@khorsheed/dsh-room 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.en.md +9 -8
- package/README.i18n.yaml +2 -2
- package/README.md +9 -8
- package/lib/client.js +3422 -1481
- package/lib/index.js +88 -12
- package/lib/{journal-CuRnWk66.js → journal-BWL3-i0s.js} +27 -0
- package/lib/tool.js +63 -11
- package/lib/typert.host.js +161 -26
- package/lib/typert.remote-client.d.ts +2 -0
- package/lib/typert.remote-client.js +142 -22
- package/lib/types/adapter.d.ts +2 -2
- package/lib/types/client/RoomActivityDock.d.ts +19 -0
- package/lib/types/client/RoomActivityDock.js +105 -0
- package/lib/types/client/RoomComposer.d.ts +1 -1
- package/lib/types/client/RoomComposer.js +3 -3
- package/lib/types/client/RoomPlanTab.d.ts +15 -0
- package/lib/types/client/RoomPlanTab.js +13 -0
- package/lib/types/client/RoomPlanView.d.ts +3 -2
- package/lib/types/client/RoomPlanView.js +5 -6
- package/lib/types/client/executions.d.ts +50 -0
- package/lib/types/client/executions.js +70 -0
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/index.js +33 -1
- package/lib/types/client/locales.d.ts +50 -0
- package/lib/types/client/locales.js +50 -0
- package/lib/types/client/preset-visibility.d.ts +3 -3
- package/lib/types/client/preset-visibility.js +2 -2
- package/lib/types/client/slots.d.ts +6 -1
- package/lib/types/dispatch.js +30 -6
- package/lib/types/index.d.ts +5 -0
- package/lib/types/index.js +42 -7
- package/lib/types/journal.d.ts +1 -1
- package/lib/types/journal.js +27 -1
- package/lib/types/tool-definition.d.ts +56 -0
- package/lib/types/tool-definition.js +393 -0
- package/lib/types/tool.d.ts +37 -49
- package/lib/types/tool.js +47 -381
- package/lib/types/types.d.ts +28 -0
- package/package.json +27 -26
|
@@ -83,6 +83,8 @@ const _khorsheed_dsh_room_room_addTask_result$schema = () => (_khorsheed_dsh_roo
|
|
|
83
83
|
})]))
|
|
84
84
|
let _khorsheed_dsh_room_room_cancel_parameter_0$schema$value
|
|
85
85
|
const _khorsheed_dsh_room_room_cancel_parameter_0$schema = () => (_khorsheed_dsh_room_room_cancel_parameter_0$schema$value ??= z.object({
|
|
86
|
+
'expectedRunId': z.string().readonly().optional(),
|
|
87
|
+
'expectedStartedAt': z.number().readonly().optional(),
|
|
86
88
|
'sessionId': z.intersection(z.string(), z.unknown()).readonly(),
|
|
87
89
|
'name': z.string().readonly(),
|
|
88
90
|
}))
|
|
@@ -157,6 +159,82 @@ const _khorsheed_dsh_room_room_cancel_result$schema = () => (_khorsheed_dsh_room
|
|
|
157
159
|
'message': z.string().readonly(),
|
|
158
160
|
})]).readonly(),
|
|
159
161
|
})]))
|
|
162
|
+
let _khorsheed_dsh_room_room_cancelChild_parameter_0$schema$value
|
|
163
|
+
const _khorsheed_dsh_room_room_cancelChild_parameter_0$schema = () => (_khorsheed_dsh_room_room_cancelChild_parameter_0$schema$value ??= z.object({
|
|
164
|
+
'sessionId': z.intersection(z.string(), z.unknown()),
|
|
165
|
+
'childSessionId': z.intersection(z.string(), z.unknown()),
|
|
166
|
+
}))
|
|
167
|
+
let _khorsheed_dsh_room_room_cancelChild_result$schema$value
|
|
168
|
+
const _khorsheed_dsh_room_room_cancelChild_result$schema = () => (_khorsheed_dsh_room_room_cancelChild_result$schema$value ??= z.union([z.object({
|
|
169
|
+
'ok': z.literal(true).readonly(),
|
|
170
|
+
'value': z.object({
|
|
171
|
+
'cancelled': z.boolean().readonly(),
|
|
172
|
+
}).readonly(),
|
|
173
|
+
}), z.object({
|
|
174
|
+
'ok': z.literal(false).readonly(),
|
|
175
|
+
'error': z.union([z.object({
|
|
176
|
+
'code': z.literal("request-conflict").readonly(),
|
|
177
|
+
}), z.object({
|
|
178
|
+
'code': z.literal("member-cwd-bound").readonly(),
|
|
179
|
+
}), z.object({
|
|
180
|
+
'code': z.literal("not-coordinator").readonly(),
|
|
181
|
+
}), z.object({
|
|
182
|
+
'code': z.literal("delivery-not-uncertain").readonly(),
|
|
183
|
+
}), z.object({
|
|
184
|
+
'code': z.literal("plan-reconciliation-required").readonly(),
|
|
185
|
+
}), z.object({
|
|
186
|
+
'code': z.literal("coordinator-busy").readonly(),
|
|
187
|
+
}), z.object({
|
|
188
|
+
'code': z.literal("coordinator-not-ready").readonly(),
|
|
189
|
+
'message': z.string().readonly(),
|
|
190
|
+
}), z.object({
|
|
191
|
+
'code': z.literal("coordinator-conflict").readonly(),
|
|
192
|
+
}), z.object({
|
|
193
|
+
'code': z.literal("active-coordinator").readonly(),
|
|
194
|
+
}), z.object({
|
|
195
|
+
'code': z.literal("configuration-owned-by-core").readonly(),
|
|
196
|
+
}), z.object({
|
|
197
|
+
'code': z.literal("session-not-found").readonly(),
|
|
198
|
+
}), z.object({
|
|
199
|
+
'code': z.literal("not-a-room").readonly(),
|
|
200
|
+
}), z.object({
|
|
201
|
+
'code': z.literal("invalid-name").readonly(),
|
|
202
|
+
}), z.object({
|
|
203
|
+
'code': z.literal("duplicate-name").readonly(),
|
|
204
|
+
}), z.object({
|
|
205
|
+
'code': z.literal("empty-provider").readonly(),
|
|
206
|
+
}), z.object({
|
|
207
|
+
'code': z.literal("member-not-found").readonly(),
|
|
208
|
+
}), z.object({
|
|
209
|
+
'code': z.literal("empty-text").readonly(),
|
|
210
|
+
}), z.object({
|
|
211
|
+
'code': z.literal("nothing-to-update").readonly(),
|
|
212
|
+
}), z.object({
|
|
213
|
+
'code': z.literal("local-agent-unavailable").readonly(),
|
|
214
|
+
}), z.object({
|
|
215
|
+
'code': z.literal("unknown-provider").readonly(),
|
|
216
|
+
'provider': z.string().readonly(),
|
|
217
|
+
'available': z.array(z.string()).readonly(),
|
|
218
|
+
}), z.object({
|
|
219
|
+
'code': z.literal("unknown-targets").readonly(),
|
|
220
|
+
'names': z.array(z.string()).readonly(),
|
|
221
|
+
}), z.object({
|
|
222
|
+
'code': z.literal("no-targets").readonly(),
|
|
223
|
+
}), z.object({
|
|
224
|
+
'code': z.literal("relay-not-found").readonly(),
|
|
225
|
+
}), z.object({
|
|
226
|
+
'code': z.literal("relay-not-pending").readonly(),
|
|
227
|
+
}), z.object({
|
|
228
|
+
'code': z.literal("main-member").readonly(),
|
|
229
|
+
}), z.object({
|
|
230
|
+
'code': z.literal("task-not-found").readonly(),
|
|
231
|
+
}), z.object({
|
|
232
|
+
'code': z.literal("task-closed").readonly(),
|
|
233
|
+
}), z.object({
|
|
234
|
+
'code': z.literal("resume-failed").readonly(),
|
|
235
|
+
'message': z.string().readonly(),
|
|
236
|
+
})]).readonly(),
|
|
237
|
+
})]))
|
|
160
238
|
let _khorsheed_dsh_room_room_closeTask_parameter_0$schema$value
|
|
161
239
|
const _khorsheed_dsh_room_room_closeTask_parameter_0$schema = () => (_khorsheed_dsh_room_room_closeTask_parameter_0$schema$value ??= z.object({
|
|
162
240
|
'sessionId': z.intersection(z.string(), z.unknown()).readonly(),
|
|
@@ -394,7 +472,26 @@ let _khorsheed_dsh_room_room_getState_result$schema$value
|
|
|
394
472
|
const _khorsheed_dsh_room_room_getState_result$schema = () => (_khorsheed_dsh_room_room_getState_result$schema$value ??= z.union([z.object({
|
|
395
473
|
'ok': z.literal(true).readonly(),
|
|
396
474
|
'value': z.object({
|
|
475
|
+
'executions': z.array(z.object({
|
|
476
|
+
'id': z.string().readonly(),
|
|
477
|
+
'memberId': z.string().readonly().optional(),
|
|
478
|
+
'childSessionId': z.intersection(z.string(), z.unknown()).readonly().optional(),
|
|
479
|
+
'provider': z.string().readonly().optional(),
|
|
480
|
+
'model': z.string().readonly().optional(),
|
|
481
|
+
'effort': z.string().readonly().optional(),
|
|
482
|
+
'tokens': z.number().readonly().optional(),
|
|
483
|
+
'runId': z.string().readonly().optional(),
|
|
484
|
+
'member': z.string().readonly(),
|
|
485
|
+
'state': z.union([z.literal("running"), z.literal("done"), z.literal("cancelled"), z.literal("failed")]).readonly(),
|
|
486
|
+
'startedAt': z.number().readonly(),
|
|
487
|
+
'elapsedMs': z.number().readonly().optional(),
|
|
488
|
+
'error': z.string().readonly().optional(),
|
|
489
|
+
})).readonly().optional(),
|
|
397
490
|
'plan': z.object({
|
|
491
|
+
'stages': z.array(z.object({
|
|
492
|
+
'id': z.string(),
|
|
493
|
+
'title': z.string(),
|
|
494
|
+
})),
|
|
398
495
|
'version': z.literal(1),
|
|
399
496
|
'id': z.string(),
|
|
400
497
|
'revision': z.number(),
|
|
@@ -409,16 +506,12 @@ const _khorsheed_dsh_room_room_getState_result$schema = () => (_khorsheed_dsh_ro
|
|
|
409
506
|
}),
|
|
410
507
|
'activeMs': z.number(),
|
|
411
508
|
'resumedAt': z.number().optional(),
|
|
412
|
-
'stages': z.array(z.object({
|
|
413
|
-
'id': z.string(),
|
|
414
|
-
'title': z.string(),
|
|
415
|
-
})),
|
|
416
509
|
'tasks': z.array(z.object({
|
|
417
510
|
'id': z.string(),
|
|
418
511
|
'title': z.string(),
|
|
419
512
|
'stageId': z.string(),
|
|
420
513
|
'parentId': z.string().optional(),
|
|
421
|
-
'kind': z.union([z.literal("
|
|
514
|
+
'kind': z.union([z.literal("task"), z.literal("group")]),
|
|
422
515
|
'ownerMemberId': z.string().optional(),
|
|
423
516
|
'instruction': z.string(),
|
|
424
517
|
'criteria': z.array(z.string()),
|
|
@@ -1271,7 +1364,7 @@ export const TYPERT_REMOTE = {
|
|
|
1271
1364
|
create: _khorsheed_dsh_room_room_addTask_result$schema,
|
|
1272
1365
|
schema: _khorsheed_dsh_room_room_addTask_result$schema(),
|
|
1273
1366
|
},
|
|
1274
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1367
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":948,"column":9},
|
|
1275
1368
|
},
|
|
1276
1369
|
{
|
|
1277
1370
|
id: '@khorsheed/dsh-room#room/cancel',
|
|
@@ -1298,7 +1391,34 @@ export const TYPERT_REMOTE = {
|
|
|
1298
1391
|
create: _khorsheed_dsh_room_room_cancel_result$schema,
|
|
1299
1392
|
schema: _khorsheed_dsh_room_room_cancel_result$schema(),
|
|
1300
1393
|
},
|
|
1301
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1394
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":1053,"column":9},
|
|
1395
|
+
},
|
|
1396
|
+
{
|
|
1397
|
+
id: '@khorsheed/dsh-room#room/cancelChild',
|
|
1398
|
+
service: 'room',
|
|
1399
|
+
namespace: 'room',
|
|
1400
|
+
method: 'cancelChild',
|
|
1401
|
+
invocation: { kind: 'direct' },
|
|
1402
|
+
parameters: [
|
|
1403
|
+
{
|
|
1404
|
+
name: 'request',
|
|
1405
|
+
wire: 'request',
|
|
1406
|
+
source: 'json',
|
|
1407
|
+
codec: {
|
|
1408
|
+
mode: 'strict',
|
|
1409
|
+
typeSymbol: '@khorsheed/dsh-room#room/cancelChild:request',
|
|
1410
|
+
create: _khorsheed_dsh_room_room_cancelChild_parameter_0$schema,
|
|
1411
|
+
schema: _khorsheed_dsh_room_room_cancelChild_parameter_0$schema(),
|
|
1412
|
+
},
|
|
1413
|
+
},
|
|
1414
|
+
],
|
|
1415
|
+
result: {
|
|
1416
|
+
mode: 'strict',
|
|
1417
|
+
typeSymbol: '@khorsheed/dsh-room/types#RoomCancelResult',
|
|
1418
|
+
create: _khorsheed_dsh_room_room_cancelChild_result$schema,
|
|
1419
|
+
schema: _khorsheed_dsh_room_room_cancelChild_result$schema(),
|
|
1420
|
+
},
|
|
1421
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":1093,"column":9},
|
|
1302
1422
|
},
|
|
1303
1423
|
{
|
|
1304
1424
|
id: '@khorsheed/dsh-room#room/closeTask',
|
|
@@ -1325,7 +1445,7 @@ export const TYPERT_REMOTE = {
|
|
|
1325
1445
|
create: _khorsheed_dsh_room_room_closeTask_result$schema,
|
|
1326
1446
|
schema: _khorsheed_dsh_room_room_closeTask_result$schema(),
|
|
1327
1447
|
},
|
|
1328
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1448
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":976,"column":9},
|
|
1329
1449
|
},
|
|
1330
1450
|
{
|
|
1331
1451
|
id: '@khorsheed/dsh-room#room/confirmRelay',
|
|
@@ -1352,7 +1472,7 @@ export const TYPERT_REMOTE = {
|
|
|
1352
1472
|
create: _khorsheed_dsh_room_room_confirmRelay_result$schema,
|
|
1353
1473
|
schema: _khorsheed_dsh_room_room_confirmRelay_result$schema(),
|
|
1354
1474
|
},
|
|
1355
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1475
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":905,"column":9},
|
|
1356
1476
|
},
|
|
1357
1477
|
{
|
|
1358
1478
|
id: '@khorsheed/dsh-room#room/dismissRelay',
|
|
@@ -1379,7 +1499,7 @@ export const TYPERT_REMOTE = {
|
|
|
1379
1499
|
create: _khorsheed_dsh_room_room_dismissRelay_result$schema,
|
|
1380
1500
|
schema: _khorsheed_dsh_room_room_dismissRelay_result$schema(),
|
|
1381
1501
|
},
|
|
1382
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1502
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":928,"column":9},
|
|
1383
1503
|
},
|
|
1384
1504
|
{
|
|
1385
1505
|
id: '@khorsheed/dsh-room#room/getState',
|
|
@@ -1406,7 +1526,7 @@ export const TYPERT_REMOTE = {
|
|
|
1406
1526
|
create: _khorsheed_dsh_room_room_getState_result$schema,
|
|
1407
1527
|
schema: _khorsheed_dsh_room_room_getState_result$schema(),
|
|
1408
1528
|
},
|
|
1409
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1529
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":349,"column":9},
|
|
1410
1530
|
},
|
|
1411
1531
|
{
|
|
1412
1532
|
id: '@khorsheed/dsh-room#room/invite',
|
|
@@ -1433,7 +1553,7 @@ export const TYPERT_REMOTE = {
|
|
|
1433
1553
|
create: _khorsheed_dsh_room_room_invite_result$schema,
|
|
1434
1554
|
schema: _khorsheed_dsh_room_room_invite_result$schema(),
|
|
1435
1555
|
},
|
|
1436
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1556
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":450,"column":3},
|
|
1437
1557
|
},
|
|
1438
1558
|
{
|
|
1439
1559
|
id: '@khorsheed/dsh-room#room/isRoom',
|
|
@@ -1460,7 +1580,7 @@ export const TYPERT_REMOTE = {
|
|
|
1460
1580
|
create: _khorsheed_dsh_room_room_isRoom_result$schema,
|
|
1461
1581
|
schema: _khorsheed_dsh_room_room_isRoom_result$schema(),
|
|
1462
1582
|
},
|
|
1463
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1583
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":272,"column":9},
|
|
1464
1584
|
},
|
|
1465
1585
|
{
|
|
1466
1586
|
id: '@khorsheed/dsh-room#room/listProviders',
|
|
@@ -1487,7 +1607,7 @@ export const TYPERT_REMOTE = {
|
|
|
1487
1607
|
create: _khorsheed_dsh_room_room_listProviders_result$schema,
|
|
1488
1608
|
schema: _khorsheed_dsh_room_room_listProviders_result$schema(),
|
|
1489
1609
|
},
|
|
1490
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1610
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":321,"column":9},
|
|
1491
1611
|
},
|
|
1492
1612
|
{
|
|
1493
1613
|
id: '@khorsheed/dsh-room#room/planCommand',
|
|
@@ -1514,7 +1634,7 @@ export const TYPERT_REMOTE = {
|
|
|
1514
1634
|
create: _khorsheed_dsh_room_room_planCommand_result$schema,
|
|
1515
1635
|
schema: _khorsheed_dsh_room_room_planCommand_result$schema(),
|
|
1516
1636
|
},
|
|
1517
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1637
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":789,"column":9},
|
|
1518
1638
|
},
|
|
1519
1639
|
{
|
|
1520
1640
|
id: '@khorsheed/dsh-room#room/postMessage',
|
|
@@ -1541,7 +1661,7 @@ export const TYPERT_REMOTE = {
|
|
|
1541
1661
|
create: _khorsheed_dsh_room_room_postMessage_result$schema,
|
|
1542
1662
|
schema: _khorsheed_dsh_room_room_postMessage_result$schema(),
|
|
1543
1663
|
},
|
|
1544
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1664
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":668,"column":9},
|
|
1545
1665
|
},
|
|
1546
1666
|
{
|
|
1547
1667
|
id: '@khorsheed/dsh-room#room/prepareMember',
|
|
@@ -1568,7 +1688,7 @@ export const TYPERT_REMOTE = {
|
|
|
1568
1688
|
create: _khorsheed_dsh_room_room_prepareMember_result$schema,
|
|
1569
1689
|
schema: _khorsheed_dsh_room_room_prepareMember_result$schema(),
|
|
1570
1690
|
},
|
|
1571
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1691
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":518,"column":9},
|
|
1572
1692
|
},
|
|
1573
1693
|
{
|
|
1574
1694
|
id: '@khorsheed/dsh-room#room/reconcileDelivery',
|
|
@@ -1595,7 +1715,7 @@ export const TYPERT_REMOTE = {
|
|
|
1595
1715
|
create: _khorsheed_dsh_room_room_reconcileDelivery_result$schema,
|
|
1596
1716
|
schema: _khorsheed_dsh_room_room_reconcileDelivery_result$schema(),
|
|
1597
1717
|
},
|
|
1598
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1718
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":544,"column":9},
|
|
1599
1719
|
},
|
|
1600
1720
|
{
|
|
1601
1721
|
id: '@khorsheed/dsh-room#room/removeMember',
|
|
@@ -1622,7 +1742,7 @@ export const TYPERT_REMOTE = {
|
|
|
1622
1742
|
create: _khorsheed_dsh_room_room_removeMember_result$schema,
|
|
1623
1743
|
schema: _khorsheed_dsh_room_room_removeMember_result$schema(),
|
|
1624
1744
|
},
|
|
1625
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1745
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":631,"column":9},
|
|
1626
1746
|
},
|
|
1627
1747
|
{
|
|
1628
1748
|
id: '@khorsheed/dsh-room#room/setCoordinator',
|
|
@@ -1649,7 +1769,7 @@ export const TYPERT_REMOTE = {
|
|
|
1649
1769
|
create: _khorsheed_dsh_room_room_setCoordinator_result$schema,
|
|
1650
1770
|
schema: _khorsheed_dsh_room_room_setCoordinator_result$schema(),
|
|
1651
1771
|
},
|
|
1652
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1772
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":561,"column":9},
|
|
1653
1773
|
},
|
|
1654
1774
|
{
|
|
1655
1775
|
id: '@khorsheed/dsh-room#room/setGoal',
|
|
@@ -1676,7 +1796,7 @@ export const TYPERT_REMOTE = {
|
|
|
1676
1796
|
create: _khorsheed_dsh_room_room_setGoal_result$schema,
|
|
1677
1797
|
schema: _khorsheed_dsh_room_room_setGoal_result$schema(),
|
|
1678
1798
|
},
|
|
1679
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1799
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":1034,"column":9},
|
|
1680
1800
|
},
|
|
1681
1801
|
{
|
|
1682
1802
|
id: '@khorsheed/dsh-room#room/updateMember',
|
|
@@ -1703,7 +1823,7 @@ export const TYPERT_REMOTE = {
|
|
|
1703
1823
|
create: _khorsheed_dsh_room_room_updateMember_result$schema,
|
|
1704
1824
|
schema: _khorsheed_dsh_room_room_updateMember_result$schema(),
|
|
1705
1825
|
},
|
|
1706
|
-
sourceLocation: {"file":"packages/room/src/index.ts","line":
|
|
1826
|
+
sourceLocation: {"file":"packages/room/src/index.ts","line":473,"column":9},
|
|
1707
1827
|
},
|
|
1708
1828
|
],
|
|
1709
1829
|
}
|
package/lib/types/adapter.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The room's ONLY coupling point to the local-agent family's delegation
|
|
3
|
-
* facade (
|
|
4
|
-
* landed as `LocalAgentRegistry.start/resume/cancel`). The TYPES come from a
|
|
3
|
+
* facade (`.agents/notes/implemented/feature/2026-08-18-local-agent-delegation-facade.md`,
|
|
4
|
+
* M1 landed as `LocalAgentRegistry.start/resume/cancel`). The TYPES come from a
|
|
5
5
|
* type-only import of the family core (drift-checked at compile time); the
|
|
6
6
|
* RUNTIME stays a probe — `ctx.get('localAgent')` plus method-existence
|
|
7
7
|
* checks — so a composition without the family degrades the CLI-member
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { RoomState } from '../types.ts';
|
|
3
|
+
import type { RoomComposerProps } from './slots.ts';
|
|
4
|
+
export interface RoomActivityDockProps {
|
|
5
|
+
sessionId?: string;
|
|
6
|
+
backgroundSessions?: RoomComposerProps['backgroundSessions'];
|
|
7
|
+
activeChildren?: RoomComposerProps['activeChildren'];
|
|
8
|
+
stopChild?: RoomComposerProps['stopChild'];
|
|
9
|
+
state: RoomState;
|
|
10
|
+
openSession?: RoomComposerProps['openPlanSession'];
|
|
11
|
+
stopExecution?: RoomComposerProps['stopExecution'];
|
|
12
|
+
planCommand?: RoomComposerProps['planCommand'];
|
|
13
|
+
openPlan?: RoomComposerProps['openPlan'];
|
|
14
|
+
stopMember?: RoomComposerProps['stopMember'];
|
|
15
|
+
t: RoomComposerProps['t'];
|
|
16
|
+
}
|
|
17
|
+
/** Composer-owned capsules: panels grow above their triggers, never into the input. */
|
|
18
|
+
export declare function RoomActivityDock({ state, sessionId, backgroundSessions, activeChildren, stopChild, openSession, stopExecution, planCommand, openPlan, stopMember, t }: RoomActivityDockProps): ReactNode;
|
|
19
|
+
//# sourceMappingURL=RoomActivityDock.d.ts.map
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useId, useRef, useState, useSyncExternalStore } from 'react';
|
|
3
|
+
import { IconAgentPresetOutlineMedium, IconChecklistOutlineMedium, IconStopFillMedium } from './icons.js';
|
|
4
|
+
import { descendantRows, executionRows } from './executions.js';
|
|
5
|
+
import { formatDurationMs } from './format.js';
|
|
6
|
+
import { RoomPlanView } from './RoomPlanView.js';
|
|
7
|
+
import css from './RoomActivityDock.module.css';
|
|
8
|
+
const EMPTY_SESSIONS = { byId: {} };
|
|
9
|
+
const NO_SESSIONS = { subscribe: () => () => { }, getSnapshot: () => EMPTY_SESSIONS };
|
|
10
|
+
/** Composer-owned capsules: panels grow above their triggers, never into the input. */
|
|
11
|
+
export function RoomActivityDock({ state, sessionId, backgroundSessions = NO_SESSIONS, activeChildren, stopChild, openSession, stopExecution, planCommand, openPlan, stopMember, t }) {
|
|
12
|
+
const [expanded, setExpanded] = useState(null);
|
|
13
|
+
const [filter, setFilter] = useState('recent');
|
|
14
|
+
const [detail, setDetail] = useState(false);
|
|
15
|
+
const [pending, setPending] = useState(null);
|
|
16
|
+
const [error, setError] = useState(null);
|
|
17
|
+
const [now, setNow] = useState(Date.now);
|
|
18
|
+
const [active, setActive] = useState([]);
|
|
19
|
+
const root = useRef(null);
|
|
20
|
+
const id = useId();
|
|
21
|
+
const sessions = useSyncExternalStore(backgroundSessions.subscribe, backgroundSessions.getSnapshot);
|
|
22
|
+
const descendants = sessionId === undefined ? [] : descendantRows(sessions.byId, sessionId, state, now, active);
|
|
23
|
+
const rows = [...executionRows(state), ...descendants];
|
|
24
|
+
const hasChildren = Object.values(sessions.byId).some(child => child.parentId === sessionId && child.origin === 'subagent');
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!activeChildren || !hasChildren)
|
|
27
|
+
return;
|
|
28
|
+
let disposed = false;
|
|
29
|
+
let pending = false;
|
|
30
|
+
const refresh = async () => {
|
|
31
|
+
if (pending)
|
|
32
|
+
return;
|
|
33
|
+
pending = true;
|
|
34
|
+
try {
|
|
35
|
+
const value = await activeChildren();
|
|
36
|
+
if (!disposed && value !== undefined)
|
|
37
|
+
setActive(value);
|
|
38
|
+
}
|
|
39
|
+
catch { /* Unknown is not evidence that a delegation stopped. */ }
|
|
40
|
+
finally {
|
|
41
|
+
pending = false;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
void refresh();
|
|
45
|
+
const timer = setInterval(() => { void refresh(); }, 2000);
|
|
46
|
+
return () => { disposed = true; clearInterval(timer); };
|
|
47
|
+
}, [activeChildren, hasChildren]);
|
|
48
|
+
const running = rows.filter(row => row.status === 'running');
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (expanded === null)
|
|
51
|
+
return;
|
|
52
|
+
const close = (event) => { if (event.target instanceof Node && !root.current?.contains(event.target))
|
|
53
|
+
setExpanded(null); };
|
|
54
|
+
const escape = (event) => { if (event.key === 'Escape') {
|
|
55
|
+
setExpanded(null);
|
|
56
|
+
root.current?.querySelector('[aria-expanded="true"]')?.focus();
|
|
57
|
+
} };
|
|
58
|
+
document.addEventListener('pointerdown', close);
|
|
59
|
+
document.addEventListener('keydown', escape);
|
|
60
|
+
return () => { document.removeEventListener('pointerdown', close); document.removeEventListener('keydown', escape); };
|
|
61
|
+
}, [expanded]);
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (expanded !== 'agents' || running.length === 0)
|
|
64
|
+
return;
|
|
65
|
+
setNow(Date.now());
|
|
66
|
+
const timer = setInterval(() => setNow(Date.now()), 1000);
|
|
67
|
+
return () => clearInterval(timer);
|
|
68
|
+
}, [expanded, running.length]);
|
|
69
|
+
const stop = async (row) => {
|
|
70
|
+
if (pending !== null)
|
|
71
|
+
return;
|
|
72
|
+
setPending(row.id);
|
|
73
|
+
setError(null);
|
|
74
|
+
try {
|
|
75
|
+
const result = row.sessionTotal && row.childSessionId ? await stopChild?.(row.childSessionId) : row.execution ? await stopExecution?.(row.member, row.execution) : undefined;
|
|
76
|
+
if (!result)
|
|
77
|
+
return;
|
|
78
|
+
if (!result.ok)
|
|
79
|
+
setError(result.message);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
setError(t('composer.error.generic'));
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
setPending(null);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const leaf = state.plan?.tasks.filter(task => task.kind === 'task' && task.status !== 'cancelled') ?? [];
|
|
89
|
+
const accepted = leaf.filter(task => task.status === 'accepted').length;
|
|
90
|
+
const visible = filter === 'running' ? running : filter === 'attention'
|
|
91
|
+
? rows.filter(row => ['failed', 'uncertain', 'submitted'].includes(row.status)) : filter === 'recent' ? rows.slice(0, 6) : rows;
|
|
92
|
+
if (rows.length === 0 && state.plan === undefined)
|
|
93
|
+
return null;
|
|
94
|
+
return _jsxs("div", { ref: root, className: css.root, "data-testid": "room-activity-dock", children: [expanded === 'agents' && _jsxs("section", { className: css.panel, id: `${id}-agents`, "aria-label": t('activity.agents'), children: [_jsxs("div", { className: css.heading, children: [_jsx("strong", { children: t('activity.agents') }), _jsx("div", { className: css.filters, children: ['recent', 'running', 'attention', 'all'].map(value => _jsx("button", { type: "button", "aria-pressed": filter === value, onClick: () => setFilter(value), children: t(`activity.filter.${value}`) }, value)) })] }), error && _jsx("p", { role: "alert", children: error }), _jsx("div", { className: css.grid, children: visible.map(row => _jsxs("article", { className: css.card, children: [_jsxs("button", { type: "button", className: css.cardMain, disabled: !row.childSessionId || !openSession, onClick: () => row.childSessionId && openSession?.(row.childSessionId), "aria-label": `${t('activity.session')}: ${row.title}`, children: [_jsxs("span", { className: css.meta, children: [_jsx("span", { children: row.member }), _jsx("span", { "data-status": row.status, children: t(`activity.status.${row.status}`) })] }), _jsx("span", { className: css.title, title: row.title, children: row.title }), _jsx("span", { className: css.secondary, children: [row.provider, row.model, row.effort].filter(Boolean).join(' · ') })] }), row.error && _jsx("p", { className: css.error, children: row.error }), _jsxs("div", { className: css.footer, children: [_jsxs("span", { children: [row.sessionTotal ? `${t('activity.sessionTotal')} · ` : '', row.status === 'queued' ? t('activity.notStarted') : row.status === 'running' && row.startedAt !== undefined ? formatDurationMs(Math.max(0, now - row.startedAt)) : row.elapsedMs === undefined ? '—' : formatDurationMs(row.elapsedMs), row.tokens === undefined ? '' : ` · ${Intl.NumberFormat(undefined, { notation: 'compact', maximumFractionDigits: 1 }).format(row.tokens)} tok`] }), row.status === 'running' && ((row.execution && stopExecution) || (row.sessionTotal && stopChild)) ? _jsxs("button", { type: "button", disabled: pending !== null, onClick: () => { void stop(row); }, "aria-label": `${t('activity.stop')}: ${row.title}`, children: [_jsx(IconStopFillMedium, { size: 12 }), t('activity.stop')] })
|
|
95
|
+
: row.childSessionId && openSession && _jsx("button", { type: "button", onClick: () => openSession(row.childSessionId), children: t('activity.session') })] })] }, row.id)) }), visible.length === 0 && _jsx("p", { className: css.empty, children: t('activity.empty') })] }), expanded === 'plan' && state.plan && _jsxs("section", { className: css.panel, id: `${id}-plan`, "aria-label": t('activity.plan'), children: [_jsxs("div", { className: css.heading, children: [_jsx("strong", { children: state.plan.objective }), _jsxs("span", { className: css.secondary, children: [t(`plan.status.${state.plan.status}`), " \u00B7 ", t('plan.acceptedCount', { done: accepted, total: leaf.length })] })] }), state.plan.reason && _jsx("p", { className: css.error, children: state.plan.reason }), _jsx("div", { className: css.planList, children: leaf.map(task => {
|
|
96
|
+
const member = state.members.find(member => member.id === task.ownerMemberId);
|
|
97
|
+
return _jsxs("button", { type: "button", className: css.planRow, onClick: () => { if (openPlan)
|
|
98
|
+
openPlan();
|
|
99
|
+
else
|
|
100
|
+
setDetail(true); }, children: [_jsx("span", { className: css.taskDot, "data-status": task.status, "aria-hidden": true }), _jsx("span", { children: task.title }), _jsxs("span", { className: css.secondary, children: [member?.name, " \u00B7 ", t(`plan.status.${task.status}`)] })] }, task.id);
|
|
101
|
+
}) }), leaf.length === 0 && _jsx("p", { className: css.empty, children: t('activity.planning') }), _jsxs("div", { className: css.footer, children: [_jsx("span", {}), _jsx("button", { type: "button", onClick: () => { if (openPlan)
|
|
102
|
+
openPlan();
|
|
103
|
+
else
|
|
104
|
+
setDetail(value => !value); }, children: t('activity.planDetails') })] }), detail && !openPlan && planCommand && _jsx(RoomPlanView, { expanded: true, plan: state.plan, members: state.members, command: planCommand, openSession: openSession, stopMember: stopMember, t: t })] }), _jsxs("div", { className: css.capsules, children: [rows.length > 0 && _jsxs("button", { type: "button", className: css.capsule, "aria-expanded": expanded === 'agents', "aria-controls": `${id}-agents`, title: running.length > 0 ? t('activity.runningHint', { count: new Set(running.map(row => row.member)).size }) : t('activity.agents'), onClick: () => setExpanded(value => value === 'agents' ? null : 'agents'), children: [_jsx("span", { className: css.icon, children: running.length > 0 ? _jsx("span", { className: css.runningDot, "data-testid": "room-running-dot", "aria-hidden": true }) : _jsx(IconAgentPresetOutlineMedium, { size: 16 }) }), t('activity.agents')] }), state.plan && _jsxs("button", { type: "button", className: css.capsule, "aria-expanded": expanded === 'plan', "aria-controls": `${id}-plan`, onClick: () => setExpanded(value => value === 'plan' ? null : 'plan'), children: [_jsx(IconChecklistOutlineMedium, { size: 16 }), t('activity.plan'), " ", _jsxs("span", { className: css.secondary, children: [accepted, "/", leaf.length] })] })] })] });
|
|
105
|
+
}
|
|
@@ -17,5 +17,5 @@ import type { RoomComposerMatch, RoomComposerProps } from './slots.ts';
|
|
|
17
17
|
*/
|
|
18
18
|
export declare function selectRoomComposer(owner: ComposerChainProps, isRoomCached: (sessionId: SessionId) => boolean): RoomComposerMatch | null;
|
|
19
19
|
/** The room composer takeover component. */
|
|
20
|
-
export declare function RoomComposer({ sessionId, roomStore, submit, stop, addTask, closeTask, setGoal, planCommand, openPlanSession, reconcileDelivery, roomCwd, invite, listProviders, listNames, browseDirectory, modelSurface, renderHarnessModelPicker, roomChrome, modelDirectory, renderMemberConfiguration, renderMemberInbox, stopMember, useSession, useProjection, t, }: RoomComposerProps): ReactNode;
|
|
20
|
+
export declare function RoomComposer({ sessionId, roomStore, submit, stop, addTask, closeTask, setGoal, planCommand, openPlanSession, openPlan, stopExecution, backgroundSessions, activeChildren, stopChild, reconcileDelivery, roomCwd, invite, listProviders, listNames, browseDirectory, modelSurface, renderHarnessModelPicker, roomChrome, modelDirectory, renderMemberConfiguration, renderMemberInbox, stopMember, useSession, useProjection, t, }: RoomComposerProps): ReactNode;
|
|
21
21
|
//# sourceMappingURL=RoomComposer.d.ts.map
|
|
@@ -41,7 +41,7 @@ import { memberColor } from './member-color.js';
|
|
|
41
41
|
import { RoomStatsLine } from './RoomStatsLine.js';
|
|
42
42
|
import { RoomDockCapsules } from './RoomDockCapsules.js';
|
|
43
43
|
import { RoomTodoStrip } from './RoomTodoStrip.js';
|
|
44
|
-
import {
|
|
44
|
+
import { RoomActivityDock } from './RoomActivityDock.js';
|
|
45
45
|
import { RoomQueueStrip } from './RoomQueueStrip.js';
|
|
46
46
|
import { RoomRecoveryView } from './RoomRecoveryView.js';
|
|
47
47
|
import { RoomModelPicker } from './RoomModelPicker.js';
|
|
@@ -91,7 +91,7 @@ export function selectRoomComposer(owner, isRoomCached) {
|
|
|
91
91
|
return sessionId !== undefined && isRoomCached(sessionId) ? { room: true } : null;
|
|
92
92
|
}
|
|
93
93
|
/** The room composer takeover component. */
|
|
94
|
-
export function RoomComposer({ sessionId, roomStore, submit, stop, addTask, closeTask, setGoal, planCommand, openPlanSession, reconcileDelivery, roomCwd, invite, listProviders, listNames, browseDirectory, modelSurface, renderHarnessModelPicker, roomChrome, modelDirectory, renderMemberConfiguration, renderMemberInbox, stopMember, useSession, useProjection, t, }) {
|
|
94
|
+
export function RoomComposer({ sessionId, roomStore, submit, stop, addTask, closeTask, setGoal, planCommand, openPlanSession, openPlan, stopExecution, backgroundSessions, activeChildren, stopChild, reconcileDelivery, roomCwd, invite, listProviders, listNames, browseDirectory, modelSurface, renderHarnessModelPicker, roomChrome, modelDirectory, renderMemberConfiguration, renderMemberInbox, stopMember, useSession, useProjection, t, }) {
|
|
95
95
|
const state = useSyncExternalStore(roomStore.subscribe, () => roomStore.getCached(sessionId));
|
|
96
96
|
const [draft, setDraft] = useState('');
|
|
97
97
|
const [busy, setBusy] = useState(false);
|
|
@@ -201,7 +201,7 @@ export function RoomComposer({ sessionId, roomStore, submit, stop, addTask, clos
|
|
|
201
201
|
void send();
|
|
202
202
|
}
|
|
203
203
|
};
|
|
204
|
-
return (_jsxs("div", { className: css.root, children: [_jsxs("div", { className: css.dock, children: [!external && useProjection !== undefined && _jsx(RoomTodoStrip, { useProjection: useProjection, t: t }), _jsx(RoomDockCapsules, { sessionId: sessionId, roomStore: roomStore, addTask: addTask, closeTask: closeTask, setGoal: setGoal, formalPlans: planCommand !== undefined, roomCwd: roomCwd, invite: invite, listProviders: listProviders, listNames: listNames, browseDirectory: browseDirectory, modelSurface: modelSurface, renderHarnessModelPicker: renderHarnessModelPicker, roomChrome: roomChrome, t: t }), state !== undefined &&
|
|
204
|
+
return (_jsxs("div", { className: css.root, children: [_jsxs("div", { className: css.dock, children: [!external && useProjection !== undefined && _jsx(RoomTodoStrip, { useProjection: useProjection, t: t }), (state === undefined || (state.plan === undefined && (state.executions?.length ?? 0) === 0)) && _jsx(RoomDockCapsules, { sessionId: sessionId, roomStore: roomStore, addTask: addTask, closeTask: closeTask, setGoal: setGoal, formalPlans: planCommand !== undefined, roomCwd: roomCwd, invite: invite, listProviders: listProviders, listNames: listNames, browseDirectory: browseDirectory, modelSurface: modelSurface, renderHarnessModelPicker: renderHarnessModelPicker, roomChrome: roomChrome, t: t }), state !== undefined && reconcileDelivery !== undefined && _jsx(RoomRecoveryView, { deliveries: state.deliveries ?? [], members: state.members, reconcile: reconcileDelivery, openSession: openPlanSession, t: t }), _jsx(RoomQueueStrip, { items: [...external ? [] : queued, ...(state?.deliveries ?? []).filter(row => row.memberId === coordinator?.id && (row.status === 'queued' || row.status === 'uncertain')).map(row => ({ id: row.id, preview: row.status === 'uncertain' ? `${row.error ?? 'Outcome unknown'}: ${row.text}` : row.text }))], t: t }), state !== undefined && _jsx(RoomActivityDock, { sessionId: sessionId, state: state, backgroundSessions: backgroundSessions, activeChildren: activeChildren, stopChild: stopChild, openSession: openPlanSession, stopExecution: stopExecution, planCommand: planCommand, openPlan: openPlan, stopMember: stopMember, t: t }, sessionId)] }), error !== null && _jsx("div", { className: css.error, role: "alert", children: error }), external && coordinator.childSessionId !== undefined && renderMemberInbox?.(coordinator.childSessionId), _jsxs("div", { className: css.card, children: [_jsxs("div", { className: css.coordinator, children: [t('coordinator.label'), " \u00B7 ", coordinator?.name ?? 'dsh', external ? ` · ${coordinator.provider}` : ' · DSH'] }), mention !== null && candidates.length > 0 && (_jsx("ul", { className: css.menu, role: "listbox", "aria-label": "members", children: candidates.map((member, index) => (_jsx("li", { children: _jsxs("button", { type: "button", role: "option", "aria-selected": index === mention.index, className: index === mention.index ? css.itemActive : css.item, onMouseDown: (event) => {
|
|
205
205
|
event.preventDefault();
|
|
206
206
|
applyMention(member.name);
|
|
207
207
|
}, children: [_jsx("span", { className: css.dot, style: { background: memberColor(member.name) }, "aria-hidden": true }), _jsx("span", { children: member.name }), _jsx("span", { className: css.hint, children: member.kind === 'main-agent' ? t('member.kind.main') : member.provider ?? '' })] }) }, member.name))) })), _jsx("textarea", { ref: areaRef, className: css.input, rows: 2, value: draft, placeholder: t('composer.placeholder'), onChange: onChange, onKeyDown: onKeyDown }), _jsxs("div", { className: css.row, children: [external && coordinator.childSessionId !== undefined && renderMemberConfiguration?.(coordinator.childSessionId), !external && modelDirectory !== undefined && (_jsx(RoomModelPicker, { directory: modelDirectory, onError: setError, t: t })), running && (_jsx("button", { type: "button", className: css.primary, "aria-label": t('composer.stop'), onMouseDown: (event) => { event.preventDefault(); }, onClick: () => { if (external)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import type { RoomComposerInjected } from './slots.ts';
|
|
3
|
+
export declare const ROOM_PLAN_KIND = "room-plan";
|
|
4
|
+
export declare const ROOM_PLAN_TAB_ID = "@khorsheed/dsh-room/plan";
|
|
5
|
+
declare module '@deepseek-ai/dsh-client-ui-sidebar-right/client' {
|
|
6
|
+
interface SidebarRightTabParamsMap {
|
|
7
|
+
'room-plan': Record<string, never>;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
type Injected = Pick<RoomComposerInjected, 'roomStore' | 'planCommand' | 'openPlanSession' | 'stopMember'>;
|
|
11
|
+
type Props = PropsRuntime<'sidebar.right.pane.tab'> & InjectFace<Injected> & PropsLocale<'room'>;
|
|
12
|
+
/** Uses the host's session-scoped sidebar, with the same review commands as the dock. */
|
|
13
|
+
export declare function RoomPlanTab({ sessionId, roomStore, planCommand, openPlanSession, stopMember, t }: Props): import("react").JSX.Element | null;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=RoomPlanTab.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useSyncExternalStore } from 'react';
|
|
3
|
+
import { RoomPlanView } from './RoomPlanView.js';
|
|
4
|
+
export const ROOM_PLAN_KIND = 'room-plan';
|
|
5
|
+
export const ROOM_PLAN_TAB_ID = '@khorsheed/dsh-room/plan';
|
|
6
|
+
/** Uses the host's session-scoped sidebar, with the same review commands as the dock. */
|
|
7
|
+
export function RoomPlanTab({ sessionId, roomStore, planCommand, openPlanSession, stopMember, t }) {
|
|
8
|
+
const state = useSyncExternalStore(roomStore.subscribe, () => roomStore.getCached(sessionId));
|
|
9
|
+
useEffect(() => { void roomStore.ensure(sessionId); }, [roomStore, sessionId]);
|
|
10
|
+
if (!state || !planCommand)
|
|
11
|
+
return null;
|
|
12
|
+
return _jsx(RoomPlanView, { expanded: true, plan: state.plan, members: state.members, command: planCommand, openSession: openPlanSession, stopMember: stopMember, t: t }, sessionId);
|
|
13
|
+
}
|
|
@@ -4,14 +4,15 @@ import type { RoomMember } from '../types.ts';
|
|
|
4
4
|
import type { RoomComposerProps, RoomMutationOutcome } from './slots.ts';
|
|
5
5
|
type PlanView = Omit<RoomPlan, 'requests'>;
|
|
6
6
|
export interface RoomPlanViewProps {
|
|
7
|
+
expanded?: boolean;
|
|
7
8
|
plan?: PlanView | undefined;
|
|
8
9
|
members: readonly RoomMember[];
|
|
9
10
|
command: (json: string) => Promise<RoomMutationOutcome>;
|
|
10
11
|
openSession?: ((id: string) => void) | undefined;
|
|
11
|
-
stopMember?: ((name: string) => void) | undefined;
|
|
12
|
+
stopMember?: ((name: string, expectedRunId?: string) => void) | undefined;
|
|
12
13
|
t: RoomComposerProps['t'];
|
|
13
14
|
}
|
|
14
15
|
/** Goal review is optional room chrome; ordinary chat never opens this form. */
|
|
15
|
-
export declare function RoomPlanView({ plan, members, command, openSession, stopMember, t }: RoomPlanViewProps): ReactNode;
|
|
16
|
+
export declare function RoomPlanView({ plan, members, command, openSession, stopMember, expanded, t }: RoomPlanViewProps): ReactNode;
|
|
16
17
|
export {};
|
|
17
18
|
//# sourceMappingURL=RoomPlanView.d.ts.map
|
|
@@ -3,10 +3,9 @@ import { useEffect, useRef, useState } from 'react';
|
|
|
3
3
|
import { RoomRequestIds } from './request-ids.js';
|
|
4
4
|
import css from './RoomPlanView.module.css';
|
|
5
5
|
/** Goal review is optional room chrome; ordinary chat never opens this form. */
|
|
6
|
-
export function RoomPlanView({ plan, members, command, openSession, stopMember, t }) {
|
|
6
|
+
export function RoomPlanView({ plan, members, command, openSession, stopMember, expanded = false, t }) {
|
|
7
7
|
const [creating, setCreating] = useState(false);
|
|
8
8
|
const [objective, setObjective] = useState('');
|
|
9
|
-
const [execute, setExecute] = useState(false);
|
|
10
9
|
const [busy, setBusy] = useState(false);
|
|
11
10
|
const [error, setError] = useState(null);
|
|
12
11
|
const [reason, setReason] = useState('');
|
|
@@ -76,13 +75,13 @@ export function RoomPlanView({ plan, members, command, openSession, stopMember,
|
|
|
76
75
|
const attempt = task.attempts.at(-1);
|
|
77
76
|
const uncertain = attempt?.status === 'uncertain';
|
|
78
77
|
const reviewable = attempt?.status === 'submitted' && attempt.settledAt !== undefined;
|
|
79
|
-
return _jsxs("details", { id: `room-plan-task-${task.id}`, className: task.parentId === undefined ? css.task : css.childTask, children: [_jsxs("summary", { children: [task.title, " \u00B7 ", task.kind === 'group' ? t('plan.group') : status(task.status), owner && ` · ${owner.name}`] }), _jsx("p", { className: css.text, children: task.instruction }), task.parentId && _jsxs("p", { children: [t('plan.parent'), ": ", plan?.tasks.find(parent => parent.id === task.parentId)?.title ?? task.parentId] }), task.criteria.length > 0 && _jsxs(_Fragment, { children: [_jsx("strong", { children: t('plan.criteria') }), list(task.criteria)] }), task.inputRefs.length > 0 && _jsxs(_Fragment, { children: [_jsx("strong", { children: t('plan.inputs') }), list(task.inputRefs)] }), task.artifactPaths.length > 0 && _jsxs(_Fragment, { children: [_jsx("strong", { children: t('plan.expectedArtifacts') }), list(task.artifactPaths)] }), task.dependsOn.length > 0 && _jsxs("div", { children: [t('plan.dependencies'), ": ", task.dependsOn.map(id => _jsx("a", { className: css.dependency, href: `#room-plan-task-${id}`, children: plan?.tasks.find(task => task.id === id)?.title ?? id }, id))] }), _jsxs("div", { className: css.actions, children: [owner?.childSessionId && openSession && _jsx("button", { type: "button", onClick: () => openSession(owner.childSessionId), children: t('plan.session') }), owner && stopMember && attempt?.startedAt !== undefined && attempt.settledAt === undefined && ['running', 'submitted'].includes(attempt.status) && _jsx("button", { type: "button", onClick: () => stopMember(owner.name), children: t('composer.stop') }), (uncertain || (!closed && (reviewable || task.status === 'failed'))) && _jsx("button", { type: "button", onClick: () => { setReviewTask(task.id); setGoalControls(false); setReason(''); setReferences(''); setArtifacts(''); }, children: t(uncertain ? 'plan.reconcile' : reviewable ? 'plan.review' : 'plan.retry') })] }), reviewTask === task.id && attempt && _jsxs("div", { className: css.review, children: [evidenceFields, _jsxs("div", { className: css.actions, children: [reviewable && _jsxs(_Fragment, { children: [_jsx("button", { type: "button", disabled: busy || !hasEvidence, onClick: () => { void run({ action: 'review', taskId: task.id, attemptId: attempt.id, decision: 'accepted', reason, references: lines(references) }); }, children: t('plan.accept') }), _jsx("button", { type: "button", disabled: busy || !hasEvidence, onClick: () => { void run({ action: 'review', taskId: task.id, attemptId: attempt.id, decision: 'rework', reason, references: lines(references) }); }, children: t('plan.rework') })] }), uncertain && _jsxs(_Fragment, { children: [_jsx("button", { type: "button", disabled: busy || !hasEvidence, onClick: () => { void run({ action: 'reconcile', taskId: task.id, attemptId: attempt.id, outcome: 'submitted', evidence }); }, children: t('plan.reconcileSubmitted') }), _jsx("button", { type: "button", disabled: busy || !hasEvidence, onClick: () => { void run({ action: 'reconcile', taskId: task.id, attemptId: attempt.id, outcome: 'failed', evidence }); }, children: t('plan.reconcileFailed') })] }), !uncertain && !reviewable && task.status === 'failed' && _jsx("button", { type: "button", disabled: busy || reason.trim() === '', onClick: () => { void run({ action: 'retry', taskId: task.id, reason }); }, children: t('plan.retry') })] })] }), task.attempts.map(attemptView)] }, task.id);
|
|
78
|
+
return _jsxs("details", { id: `room-plan-task-${task.id}`, className: task.parentId === undefined ? css.task : css.childTask, children: [_jsxs("summary", { children: [task.title, " \u00B7 ", task.kind === 'group' ? t('plan.group') : status(task.status), owner && ` · ${owner.name}`] }), _jsx("p", { className: css.text, children: task.instruction }), task.parentId && _jsxs("p", { children: [t('plan.parent'), ": ", plan?.tasks.find(parent => parent.id === task.parentId)?.title ?? task.parentId] }), task.criteria.length > 0 && _jsxs(_Fragment, { children: [_jsx("strong", { children: t('plan.criteria') }), list(task.criteria)] }), task.inputRefs.length > 0 && _jsxs(_Fragment, { children: [_jsx("strong", { children: t('plan.inputs') }), list(task.inputRefs)] }), task.artifactPaths.length > 0 && _jsxs(_Fragment, { children: [_jsx("strong", { children: t('plan.expectedArtifacts') }), list(task.artifactPaths)] }), task.dependsOn.length > 0 && _jsxs("div", { children: [t('plan.dependencies'), ": ", task.dependsOn.map(id => _jsx("a", { className: css.dependency, href: `#room-plan-task-${id}`, children: plan?.tasks.find(task => task.id === id)?.title ?? id }, id))] }), _jsxs("div", { className: css.actions, children: [owner?.childSessionId && openSession && _jsx("button", { type: "button", onClick: () => openSession(owner.childSessionId), children: t('plan.session') }), owner && stopMember && attempt?.startedAt !== undefined && attempt.settledAt === undefined && ['running', 'submitted'].includes(attempt.status) && _jsx("button", { type: "button", onClick: () => stopMember(owner.name, attempt.deliveryId), children: t('composer.stop') }), (uncertain || (!closed && (reviewable || task.status === 'failed'))) && _jsx("button", { type: "button", onClick: () => { setReviewTask(task.id); setGoalControls(false); setReason(''); setReferences(''); setArtifacts(''); }, children: t(uncertain ? 'plan.reconcile' : reviewable ? 'plan.review' : 'plan.retry') })] }), reviewTask === task.id && attempt && _jsxs("div", { className: css.review, children: [evidenceFields, _jsxs("div", { className: css.actions, children: [reviewable && _jsxs(_Fragment, { children: [_jsx("button", { type: "button", disabled: busy || !hasEvidence, onClick: () => { void run({ action: 'review', taskId: task.id, attemptId: attempt.id, decision: 'accepted', reason, references: lines(references) }); }, children: t('plan.accept') }), _jsx("button", { type: "button", disabled: busy || !hasEvidence, onClick: () => { void run({ action: 'review', taskId: task.id, attemptId: attempt.id, decision: 'rework', reason, references: lines(references) }); }, children: t('plan.rework') })] }), uncertain && _jsxs(_Fragment, { children: [_jsx("button", { type: "button", disabled: busy || !hasEvidence, onClick: () => { void run({ action: 'reconcile', taskId: task.id, attemptId: attempt.id, outcome: 'submitted', evidence }); }, children: t('plan.reconcileSubmitted') }), _jsx("button", { type: "button", disabled: busy || !hasEvidence, onClick: () => { void run({ action: 'reconcile', taskId: task.id, attemptId: attempt.id, outcome: 'failed', evidence }); }, children: t('plan.reconcileFailed') })] }), !uncertain && !reviewable && task.status === 'failed' && _jsx("button", { type: "button", disabled: busy || reason.trim() === '', onClick: () => { void run({ action: 'retry', taskId: task.id, reason }); }, children: t('plan.retry') })] })] }), task.attempts.map(attemptView)] }, task.id);
|
|
80
79
|
};
|
|
81
80
|
const leaf = plan?.tasks.filter(task => task.kind === 'task' && task.status !== 'cancelled') ?? [];
|
|
82
81
|
const accepted = leaf.filter(task => task.status === 'accepted').length;
|
|
83
82
|
const closed = plan !== undefined && ['completed', 'cancelled'].includes(plan.status);
|
|
84
|
-
const createForm = _jsxs("div", { className: css.fields, children: [_jsxs("label", { children: [t('plan.objective'), _jsx("textarea", { value: objective, onChange: event => setObjective(event.target.value) })] }), _jsxs("
|
|
85
|
-
return _jsxs("details", { className: css.root, "data-testid": "room-plan", children: [_jsx("summary", { children: plan === undefined ? t('plan.create') : `${plan.objective} · ${status(plan.status)} · ${t('plan.acceptedCount', { done: accepted, total: leaf.length })}` }), error && _jsx("p", { role: "alert", children: error }), plan === undefined ? createForm : _jsxs(_Fragment, { children: [
|
|
83
|
+
const createForm = _jsxs("div", { className: css.fields, children: [_jsxs("label", { children: [t('plan.objective'), _jsx("textarea", { value: objective, onChange: event => setObjective(event.target.value) })] }), _jsxs("details", { children: [_jsx("summary", { children: t('activity.limits') }), budgetFields] }), _jsxs("div", { className: css.actions, children: [_jsx("button", { type: "button", disabled: busy || objective.trim() === '', onClick: () => { void run({ action: 'create', objective: objective.trim(), mode: 'execute', budget }); }, children: t('plan.start') }), _jsx("button", { type: "button", disabled: busy || objective.trim() === '', onClick: () => { void run({ action: 'create', objective: objective.trim(), mode: 'draft', budget }); }, children: t('plan.saveDraft') })] })] });
|
|
84
|
+
return _jsxs("details", { className: expanded ? `${css.root} ${css.expanded}` : css.root, "data-testid": "room-plan", open: expanded || undefined, children: [_jsx("summary", { children: plan === undefined ? t('plan.create') : `${plan.objective} · ${status(plan.status)} · ${t('plan.acceptedCount', { done: accepted, total: leaf.length })}` }), error && _jsx("p", { role: "alert", children: error }), plan === undefined ? createForm : _jsxs(_Fragment, { children: [plan.reason && _jsx("p", { role: "status", children: plan.reason }), !closed && _jsx("div", { className: css.actions, children: plan.status === 'running' ? _jsx("button", { type: "button", disabled: busy, onClick: () => { void run({ action: 'pause', goalId: plan.id, reason: t('plan.humanPause') }); }, children: t('plan.pause') })
|
|
86
85
|
: _jsx("button", { type: "button", disabled: busy, onClick: () => { void run({ action: 'resume' }); }, children: t('plan.resume') }) }), plan.stages.map(stage => _jsxs("details", { className: css.stage, open: true, children: [_jsx("summary", { children: stage.title }), plan.tasks.filter(task => task.stageId === stage.id).map(taskView)] }, stage.id)), plan.completion && _jsxs(_Fragment, { children: [_jsx("p", { children: plan.completion.summary }), list(plan.completion.references), list(plan.completion.artifacts)] }), !closed && _jsxs("details", { className: css.review, open: goalControls, onToggle: event => { const open = event.currentTarget.open; setGoalControls(open); if (open)
|
|
87
|
-
setReviewTask(null); }, children: [_jsx("summary", { children: t('plan.goalControls') }), goalControls && _jsxs(_Fragment, { children: [budgetFields, _jsx("button", { type: "button", disabled: busy, onClick: () => { void run({ action: 'budget', budget }); }, children: t('plan.updateBudget') }), evidenceFields, _jsxs("div", { className: css.actions, children: [_jsx("button", { type: "button", disabled: busy || !hasEvidence || leaf.length === 0 || accepted !== leaf.length, onClick: () => { void run({ action: 'complete', evidence }); }, children: t('plan.complete') }), _jsx("button", { type: "button", disabled: busy || reason.trim() === '', onClick: () => { void run({ action: 'cancel', reason }); }, children: t('plan.cancel') })] })] })] }), closed && _jsx("button", { type: "button", onClick: () => setCreating(value => !value), children: t('plan.create') }), closed && creating && createForm] })] });
|
|
86
|
+
setReviewTask(null); }, children: [_jsx("summary", { children: t('plan.goalControls') }), goalControls && _jsxs(_Fragment, { children: [_jsxs("details", { children: [_jsx("summary", { children: t('activity.limits') }), budgetFields, _jsx("button", { type: "button", disabled: busy, onClick: () => { void run({ action: 'budget', budget }); }, children: t('plan.updateBudget') })] }), evidenceFields, _jsxs("div", { className: css.actions, children: [_jsx("button", { type: "button", disabled: busy || !hasEvidence || leaf.length === 0 || accepted !== leaf.length, onClick: () => { void run({ action: 'complete', evidence }); }, children: t('plan.complete') }), _jsx("button", { type: "button", disabled: busy || reason.trim() === '', onClick: () => { void run({ action: 'cancel', reason }); }, children: t('plan.cancel') })] })] })] }), closed && _jsx("button", { type: "button", onClick: () => setCreating(value => !value), children: t('plan.create') }), closed && creating && createForm] })] });
|
|
88
87
|
}
|