@wowyuarm/dsh-agent-team 0.1.2 → 0.1.4

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.
Files changed (90) hide show
  1. package/README.md +8 -1
  2. package/README.zh.md +9 -1
  3. package/package.json +12 -3
  4. package/packages/agent-team/README.md +3 -3
  5. package/packages/agent-team/README.zh.md +3 -3
  6. package/packages/agent-team/lib/attachments.js +11 -12
  7. package/packages/agent-team/lib/auto-compaction.js +163 -0
  8. package/packages/agent-team/lib/index.js +252 -139
  9. package/packages/agent-team/lib/ledger.js +344 -170
  10. package/packages/agent-team/lib/recovery.js +30 -35
  11. package/packages/agent-team/lib/spec.js +27 -11
  12. package/packages/agent-team/lib/typert.host.js +197 -88
  13. package/packages/agent-team/lib/typert.remote-client.d.ts +3 -1
  14. package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
  15. package/packages/agent-team/lib/typert.remote-client.js +139 -59
  16. package/packages/agent-team/lib/types/attachments.d.ts +2 -2
  17. package/packages/agent-team/lib/types/attachments.d.ts.map +1 -1
  18. package/packages/agent-team/lib/types/auto-compaction.d.ts +38 -0
  19. package/packages/agent-team/lib/types/auto-compaction.d.ts.map +1 -0
  20. package/packages/agent-team/lib/types/index.d.ts +52 -19
  21. package/packages/agent-team/lib/types/index.d.ts.map +1 -1
  22. package/packages/agent-team/lib/types/ledger.d.ts +29 -2
  23. package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
  24. package/packages/agent-team/lib/types/recovery.d.ts +15 -16
  25. package/packages/agent-team/lib/types/recovery.d.ts.map +1 -1
  26. package/packages/agent-team/lib/types/spec.d.ts.map +1 -1
  27. package/packages/agent-team/lib/types/types.d.ts +69 -30
  28. package/packages/agent-team/lib/types/types.d.ts.map +1 -1
  29. package/packages/agent-team/preset/team-member/agent.cordis.yml +7 -2
  30. package/packages/client-agent-team/README.md +2 -1
  31. package/packages/client-agent-team/README.zh.md +2 -1
  32. package/packages/client-agent-team/lib/client.js +1577 -863
  33. package/packages/client-agent-team/lib/client.js.map +1 -1
  34. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts.map +1 -1
  35. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +35 -174
  36. package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts.map +1 -1
  37. package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +20 -30
  38. package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.d.ts.map +1 -1
  39. package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.js +3 -2
  40. package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts +6 -1
  41. package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts.map +1 -1
  42. package/packages/client-agent-team/lib/types/client/TeamComposer.js +4 -5
  43. package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts +1 -1
  44. package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts.map +1 -1
  45. package/packages/client-agent-team/lib/types/client/TeamConversation.js +3 -3
  46. package/packages/client-agent-team/lib/types/client/TeamMemberEditor.d.ts +34 -0
  47. package/packages/client-agent-team/lib/types/client/TeamMemberEditor.d.ts.map +1 -0
  48. package/packages/client-agent-team/lib/types/client/TeamMemberEditor.js +169 -0
  49. package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.d.ts +17 -0
  50. package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.d.ts.map +1 -0
  51. package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.js +120 -0
  52. package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts +4 -1
  53. package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts.map +1 -1
  54. package/packages/client-agent-team/lib/types/client/TeamMessage.js +94 -47
  55. package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts +2 -1
  56. package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts.map +1 -1
  57. package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +81 -39
  58. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts.map +1 -1
  59. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +2 -1
  60. package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
  61. package/packages/client-agent-team/lib/types/client/index.js +72 -1
  62. package/packages/client-agent-team/lib/types/client/locales.d.ts +24 -0
  63. package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
  64. package/packages/client-agent-team/lib/types/client/locales.js +24 -0
  65. package/packages/client-agent-team/lib/types/client/member-session-input.d.ts +22 -0
  66. package/packages/client-agent-team/lib/types/client/member-session-input.d.ts.map +1 -0
  67. package/packages/client-agent-team/lib/types/client/member-session-input.js +98 -0
  68. package/packages/client-agent-team/lib/types/client/navigation.d.ts +1 -1
  69. package/packages/client-agent-team/lib/types/client/navigation.d.ts.map +1 -1
  70. package/packages/client-agent-team/lib/types/client/navigation.js +12 -6
  71. package/packages/client-agent-team/lib/types/client/requests.d.ts +16 -0
  72. package/packages/client-agent-team/lib/types/client/requests.d.ts.map +1 -0
  73. package/packages/client-agent-team/lib/types/client/requests.js +22 -0
  74. package/packages/client-agent-team/lib/types/client/slots.d.ts +2 -1
  75. package/packages/client-agent-team/lib/types/client/slots.d.ts.map +1 -1
  76. package/packages/client-agent-team/lib/types/client/task-refs.d.ts +6 -1
  77. package/packages/client-agent-team/lib/types/client/task-refs.d.ts.map +1 -1
  78. package/packages/client-agent-team/lib/types/client/task-refs.js +19 -0
  79. package/packages/client-agent-team/lib/types/client/team-formatters.d.ts +52 -3
  80. package/packages/client-agent-team/lib/types/client/team-formatters.d.ts.map +1 -1
  81. package/packages/client-agent-team/lib/types/client/team-formatters.js +74 -4
  82. package/packages/client-agent-team/lib/types/client/team-membership.d.ts.map +1 -1
  83. package/packages/client-agent-team/lib/types/client/team-membership.js +2 -1
  84. package/packages/tool-agent-team/README.md +7 -7
  85. package/packages/tool-agent-team/README.zh.md +7 -7
  86. package/packages/tool-agent-team/lib/index.js +38 -28
  87. package/packages/tool-agent-team/lib/types/index.d.ts.map +1 -1
  88. package/packages/client-agent-team/lib/types/client/TeamInboxPanel.d.ts +0 -13
  89. package/packages/client-agent-team/lib/types/client/TeamInboxPanel.d.ts.map +0 -1
  90. package/packages/client-agent-team/lib/types/client/TeamInboxPanel.js +0 -90
@@ -4138,7 +4138,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4138
4138
  const _wowyuarm_dsh_agent_team_agentTeam_changeAttention_parameter_0$schema = object({
4139
4139
  "requestId": intersection(string(), unknown()).readonly(),
4140
4140
  "workspaceId": intersection(string(), unknown()).readonly(),
4141
- "taskRef": intersection(string(), unknown()).readonly(),
4141
+ "threadRef": intersection(string(), unknown()).readonly().optional(),
4142
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4142
4143
  "action": union([literal("follow"), literal("unfollow")]).readonly()
4143
4144
  });
4144
4145
  const _wowyuarm_dsh_agent_team_agentTeam_changeAttention_result$schema = object({
@@ -4163,10 +4164,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4163
4164
  literal("open"),
4164
4165
  literal("accepted")
4165
4166
  ]).readonly()
4166
- }).readonly(),
4167
+ }).readonly().optional(),
4167
4168
  "thread": object({
4168
4169
  "threadRef": intersection(string(), unknown()).readonly(),
4169
- "taskRef": intersection(string(), unknown()).readonly(),
4170
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4170
4171
  "revision": number().readonly()
4171
4172
  }).readonly(),
4172
4173
  "attention": object({
@@ -4217,7 +4218,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4217
4218
  "kind": union([
4218
4219
  literal("accept"),
4219
4220
  literal("close"),
4220
- literal("reopen")
4221
+ literal("reopen"),
4222
+ literal("promote")
4221
4223
  ]).readonly(),
4222
4224
  "releasedClaimRefs": union([_undefined(), array(intersection(string(), unknown()))]).readonly().optional(),
4223
4225
  "completedClaimRefs": union([_undefined(), array(intersection(string(), unknown()))]).readonly().optional(),
@@ -4246,7 +4248,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4246
4248
  }).readonly(),
4247
4249
  "thread": object({
4248
4250
  "threadRef": intersection(string(), unknown()).readonly(),
4249
- "taskRef": intersection(string(), unknown()).readonly(),
4251
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4250
4252
  "revision": number().readonly()
4251
4253
  }).readonly(),
4252
4254
  "claims": array(object({
@@ -4265,7 +4267,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4265
4267
  }),
4266
4268
  object({
4267
4269
  "kind": literal("unread_required").readonly(),
4268
- "taskRef": intersection(string(), unknown()).readonly(),
4270
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4269
4271
  "threadRef": intersection(string(), unknown()).readonly(),
4270
4272
  "revision": number().readonly(),
4271
4273
  "unreadCount": number().readonly(),
@@ -4273,7 +4275,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4273
4275
  }),
4274
4276
  object({
4275
4277
  "kind": literal("stale_revision").readonly(),
4276
- "taskRef": intersection(string(), unknown()).readonly(),
4278
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4277
4279
  "threadRef": intersection(string(), unknown()).readonly(),
4278
4280
  "expectedRevision": number().readonly(),
4279
4281
  "revision": number().readonly()
@@ -4331,10 +4333,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4331
4333
  literal("open"),
4332
4334
  literal("accepted")
4333
4335
  ]).readonly()
4334
- }).readonly(),
4336
+ }).readonly().optional(),
4335
4337
  "thread": object({
4336
4338
  "threadRef": intersection(string(), unknown()).readonly(),
4337
- "taskRef": intersection(string(), unknown()).readonly(),
4339
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4338
4340
  "revision": number().readonly()
4339
4341
  }).readonly(),
4340
4342
  "unreadCount": number().readonly(),
@@ -4399,6 +4401,74 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4399
4401
  ]).readonly(),
4400
4402
  "diagnostic": string().readonly().optional()
4401
4403
  }));
4404
+ const _wowyuarm_dsh_agent_team_agentTeam_promoteThread_parameter_0$schema = object({
4405
+ "requestId": intersection(string(), unknown()).readonly(),
4406
+ "workspaceId": intersection(string(), unknown()).readonly(),
4407
+ "threadRef": intersection(string(), unknown()).readonly(),
4408
+ "baseRevision": number().readonly()
4409
+ });
4410
+ const _wowyuarm_dsh_agent_team_agentTeam_promoteThread_result$schema = union([
4411
+ object({
4412
+ "kind": literal("unread_required").readonly(),
4413
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4414
+ "threadRef": intersection(string(), unknown()).readonly(),
4415
+ "revision": number().readonly(),
4416
+ "unreadCount": number().readonly(),
4417
+ "directCount": number().readonly()
4418
+ }),
4419
+ object({
4420
+ "kind": literal("stale_revision").readonly(),
4421
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4422
+ "threadRef": intersection(string(), unknown()).readonly(),
4423
+ "expectedRevision": number().readonly(),
4424
+ "revision": number().readonly()
4425
+ }),
4426
+ object({
4427
+ "kind": literal("committed").readonly(),
4428
+ "receipt": object({
4429
+ "operationId": intersection(string(), unknown()).readonly(),
4430
+ "requestId": intersection(string(), unknown()).readonly(),
4431
+ "sequence": number().readonly()
4432
+ }).readonly(),
4433
+ "activity": object({
4434
+ "kind": union([
4435
+ literal("accept"),
4436
+ literal("close"),
4437
+ literal("reopen"),
4438
+ literal("promote")
4439
+ ]).readonly(),
4440
+ "releasedClaimRefs": union([_undefined(), array(intersection(string(), unknown()))]).readonly().optional(),
4441
+ "completedClaimRefs": union([_undefined(), array(intersection(string(), unknown()))]).readonly().optional(),
4442
+ "activityRef": intersection(string(), unknown()).readonly(),
4443
+ "taskRef": intersection(string(), unknown()).readonly(),
4444
+ "threadRef": intersection(string(), unknown()).readonly(),
4445
+ "actor": intersection(string(), unknown()).readonly(),
4446
+ "sequence": number().readonly()
4447
+ }).readonly(),
4448
+ "task": object({
4449
+ "taskRef": intersection(string(), unknown()).readonly(),
4450
+ "channelRef": intersection(string(), unknown()).readonly(),
4451
+ "threadRef": intersection(string(), unknown()).readonly(),
4452
+ "status": union([
4453
+ literal("todo"),
4454
+ literal("in_progress"),
4455
+ literal("in_review"),
4456
+ literal("done"),
4457
+ literal("closed")
4458
+ ]).readonly(),
4459
+ "resolution": union([
4460
+ literal("closed"),
4461
+ literal("open"),
4462
+ literal("accepted")
4463
+ ]).readonly()
4464
+ }).readonly(),
4465
+ "thread": object({
4466
+ "threadRef": intersection(string(), unknown()).readonly(),
4467
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4468
+ "revision": number().readonly()
4469
+ }).readonly()
4470
+ })
4471
+ ]);
4402
4472
  const _wowyuarm_dsh_agent_team_agentTeam_putAttachment_parameter_0$schema = object({
4403
4473
  "requestId": intersection(string(), unknown()).readonly(),
4404
4474
  "workspaceId": intersection(string(), unknown()).readonly(),
@@ -4416,7 +4486,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4416
4486
  const _wowyuarm_dsh_agent_team_agentTeam_readThread_parameter_0$schema = object({
4417
4487
  "requestId": intersection(string(), unknown()).readonly(),
4418
4488
  "workspaceId": intersection(string(), unknown()).readonly(),
4419
- "taskRef": intersection(string(), unknown()).readonly()
4489
+ "threadRef": intersection(string(), unknown()).readonly().optional(),
4490
+ "taskRef": intersection(string(), unknown()).readonly().optional()
4420
4491
  });
4421
4492
  const _wowyuarm_dsh_agent_team_agentTeam_readThread_result$schema = object({
4422
4493
  "receipt": object({
@@ -4440,10 +4511,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4440
4511
  literal("open"),
4441
4512
  literal("accepted")
4442
4513
  ]).readonly()
4443
- }).readonly(),
4514
+ }).readonly().optional(),
4444
4515
  "thread": object({
4445
4516
  "threadRef": intersection(string(), unknown()).readonly(),
4446
- "taskRef": intersection(string(), unknown()).readonly(),
4517
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4447
4518
  "revision": number().readonly()
4448
4519
  }).readonly(),
4449
4520
  "claims": array(object({
@@ -4463,7 +4534,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4463
4534
  "messageRef": intersection(string(), unknown()).readonly(),
4464
4535
  "channelRef": intersection(string(), unknown()).readonly(),
4465
4536
  "threadRef": intersection(string(), unknown()).readonly(),
4466
- "taskRef": intersection(string(), unknown()).readonly(),
4537
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4467
4538
  "sender": intersection(string(), unknown()).readonly(),
4468
4539
  "body": string().readonly(),
4469
4540
  "attachments": union([_undefined(), array(object({
@@ -4485,7 +4556,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4485
4556
  "messageRef": intersection(string(), unknown()).readonly(),
4486
4557
  "channelRef": intersection(string(), unknown()).readonly(),
4487
4558
  "threadRef": intersection(string(), unknown()).readonly(),
4488
- "taskRef": intersection(string(), unknown()).readonly(),
4559
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4489
4560
  "sender": intersection(string(), unknown()).readonly(),
4490
4561
  "body": string().readonly(),
4491
4562
  "attachments": union([_undefined(), array(object({
@@ -4507,7 +4578,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4507
4578
  "kind": union([
4508
4579
  literal("accept"),
4509
4580
  literal("close"),
4510
- literal("reopen")
4581
+ literal("reopen"),
4582
+ literal("promote")
4511
4583
  ]).readonly(),
4512
4584
  "releasedClaimRefs": union([_undefined(), array(intersection(string(), unknown()))]).readonly().optional(),
4513
4585
  "completedClaimRefs": union([_undefined(), array(intersection(string(), unknown()))]).readonly().optional(),
@@ -4633,7 +4705,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4633
4705
  const _wowyuarm_dsh_agent_team_agentTeam_reply_parameter_0$schema = object({
4634
4706
  "requestId": intersection(string(), unknown()).readonly(),
4635
4707
  "workspaceId": intersection(string(), unknown()).readonly(),
4636
- "taskRef": intersection(string(), unknown()).readonly(),
4708
+ "threadRef": intersection(string(), unknown()).readonly().optional(),
4709
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4637
4710
  "body": string().readonly(),
4638
4711
  "baseRevision": number().readonly(),
4639
4712
  "recipients": array(intersection(string(), unknown())).readonly().optional(),
@@ -4644,7 +4717,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4644
4717
  const _wowyuarm_dsh_agent_team_agentTeam_reply_result$schema = union([
4645
4718
  object({
4646
4719
  "kind": literal("unread_required").readonly(),
4647
- "taskRef": intersection(string(), unknown()).readonly(),
4720
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4648
4721
  "threadRef": intersection(string(), unknown()).readonly(),
4649
4722
  "revision": number().readonly(),
4650
4723
  "unreadCount": number().readonly(),
@@ -4652,7 +4725,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4652
4725
  }),
4653
4726
  object({
4654
4727
  "kind": literal("stale_revision").readonly(),
4655
- "taskRef": intersection(string(), unknown()).readonly(),
4728
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4656
4729
  "threadRef": intersection(string(), unknown()).readonly(),
4657
4730
  "expectedRevision": number().readonly(),
4658
4731
  "revision": number().readonly()
@@ -4687,7 +4760,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4687
4760
  "messageRef": intersection(string(), unknown()).readonly(),
4688
4761
  "channelRef": intersection(string(), unknown()).readonly(),
4689
4762
  "threadRef": intersection(string(), unknown()).readonly(),
4690
- "taskRef": intersection(string(), unknown()).readonly(),
4763
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4691
4764
  "sender": intersection(string(), unknown()).readonly(),
4692
4765
  "body": string().readonly(),
4693
4766
  "attachments": union([_undefined(), array(object({
@@ -4716,10 +4789,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4716
4789
  literal("open"),
4717
4790
  literal("accepted")
4718
4791
  ]).readonly()
4719
- }).readonly(),
4792
+ }).readonly().optional(),
4720
4793
  "thread": object({
4721
4794
  "threadRef": intersection(string(), unknown()).readonly(),
4722
- "taskRef": intersection(string(), unknown()).readonly(),
4795
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4723
4796
  "revision": number().readonly()
4724
4797
  }).readonly(),
4725
4798
  "attention": array(object({
@@ -4754,7 +4827,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4754
4827
  "recipients": array(intersection(string(), unknown())).readonly().optional(),
4755
4828
  "attachments": union([_undefined(), array(intersection(string(), unknown()))]).readonly().optional(),
4756
4829
  "attachmentPaths": union([_undefined(), array(string())]).readonly().optional(),
4757
- "confirmationToken": intersection(string(), unknown()).readonly().optional()
4830
+ "confirmationToken": intersection(string(), unknown()).readonly().optional(),
4831
+ "asTask": boolean().readonly().optional()
4758
4832
  });
4759
4833
  const _wowyuarm_dsh_agent_team_agentTeam_sendMessage_result$schema = union([
4760
4834
  object({
@@ -4768,7 +4842,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4768
4842
  "messageRef": intersection(string(), unknown()).readonly(),
4769
4843
  "channelRef": intersection(string(), unknown()).readonly(),
4770
4844
  "threadRef": intersection(string(), unknown()).readonly(),
4771
- "taskRef": intersection(string(), unknown()).readonly(),
4845
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4772
4846
  "sender": intersection(string(), unknown()).readonly(),
4773
4847
  "body": string().readonly(),
4774
4848
  "attachments": union([_undefined(), array(object({
@@ -4797,10 +4871,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4797
4871
  literal("open"),
4798
4872
  literal("accepted")
4799
4873
  ]).readonly()
4800
- }).readonly(),
4874
+ }).readonly().optional(),
4801
4875
  "thread": object({
4802
4876
  "threadRef": intersection(string(), unknown()).readonly(),
4803
- "taskRef": intersection(string(), unknown()).readonly(),
4877
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4804
4878
  "revision": number().readonly()
4805
4879
  }).readonly(),
4806
4880
  "attention": array(object({
@@ -4838,7 +4912,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4838
4912
  ]);
4839
4913
  const _wowyuarm_dsh_agent_team_agentTeam_threadHistory_parameter_0$schema = object({
4840
4914
  "workspaceId": intersection(string(), unknown()).readonly(),
4841
- "taskRef": intersection(string(), unknown()).readonly(),
4915
+ "threadRef": intersection(string(), unknown()).readonly().optional(),
4916
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4842
4917
  "beforeSequence": number().readonly().optional(),
4843
4918
  "limit": number().readonly().optional()
4844
4919
  });
@@ -4859,17 +4934,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4859
4934
  literal("open"),
4860
4935
  literal("accepted")
4861
4936
  ]).readonly()
4862
- }).readonly(),
4937
+ }).readonly().optional(),
4863
4938
  "thread": object({
4864
4939
  "threadRef": intersection(string(), unknown()).readonly(),
4865
- "taskRef": intersection(string(), unknown()).readonly(),
4940
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4866
4941
  "revision": number().readonly()
4867
4942
  }).readonly(),
4868
4943
  "anchor": object({
4869
4944
  "messageRef": intersection(string(), unknown()).readonly(),
4870
4945
  "channelRef": intersection(string(), unknown()).readonly(),
4871
4946
  "threadRef": intersection(string(), unknown()).readonly(),
4872
- "taskRef": intersection(string(), unknown()).readonly(),
4947
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4873
4948
  "sender": intersection(string(), unknown()).readonly(),
4874
4949
  "body": string().readonly(),
4875
4950
  "attachments": union([_undefined(), array(object({
@@ -4903,7 +4978,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4903
4978
  "messageRef": intersection(string(), unknown()).readonly(),
4904
4979
  "channelRef": intersection(string(), unknown()).readonly(),
4905
4980
  "threadRef": intersection(string(), unknown()).readonly(),
4906
- "taskRef": intersection(string(), unknown()).readonly(),
4981
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4907
4982
  "sender": intersection(string(), unknown()).readonly(),
4908
4983
  "body": string().readonly(),
4909
4984
  "attachments": union([_undefined(), array(object({
@@ -4925,7 +5000,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4925
5000
  "kind": union([
4926
5001
  literal("accept"),
4927
5002
  literal("close"),
4928
- literal("reopen")
5003
+ literal("reopen"),
5004
+ literal("promote")
4929
5005
  ]).readonly(),
4930
5006
  "releasedClaimRefs": union([_undefined(), array(intersection(string(), unknown()))]).readonly().optional(),
4931
5007
  "completedClaimRefs": union([_undefined(), array(intersection(string(), unknown()))]).readonly().optional(),
@@ -4964,13 +5040,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4964
5040
  });
4965
5041
  const _wowyuarm_dsh_agent_team_agentTeam_threadObservations_parameter_0$schema = object({
4966
5042
  "workspaceId": intersection(string(), unknown()).readonly(),
4967
- "taskRef": intersection(string(), unknown()).readonly(),
5043
+ "threadRef": intersection(string(), unknown()).readonly().optional(),
5044
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4968
5045
  "limit": number().readonly().optional()
4969
5046
  });
4970
5047
  const _wowyuarm_dsh_agent_team_agentTeam_threadObservations_result$schema = object({ "items": array(object({
4971
5048
  "sequence": number().readonly(),
4972
5049
  "threadRef": intersection(string(), unknown()).readonly(),
4973
- "taskRef": intersection(string(), unknown()).readonly(),
5050
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
4974
5051
  "memberId": intersection(string(), unknown()).readonly(),
4975
5052
  "action": union([literal("follow"), literal("unfollow")]).readonly()
4976
5053
  })).readonly() });
@@ -5089,7 +5166,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5089
5166
  })).readonly(),
5090
5167
  "threads": array(object({
5091
5168
  "threadRef": intersection(string(), unknown()).readonly(),
5092
- "taskRef": intersection(string(), unknown()).readonly(),
5169
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
5093
5170
  "revision": number().readonly()
5094
5171
  })).readonly(),
5095
5172
  "taskNumbers": array(object({
@@ -5101,7 +5178,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5101
5178
  "messageRef": intersection(string(), unknown()).readonly(),
5102
5179
  "channelRef": intersection(string(), unknown()).readonly(),
5103
5180
  "threadRef": intersection(string(), unknown()).readonly(),
5104
- "taskRef": intersection(string(), unknown()).readonly(),
5181
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
5105
5182
  "sender": intersection(string(), unknown()).readonly(),
5106
5183
  "body": string().readonly(),
5107
5184
  "attachments": union([_undefined(), array(object({
@@ -5131,13 +5208,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5131
5208
  literal("open"),
5132
5209
  literal("accepted")
5133
5210
  ]).readonly()
5134
- }).readonly(),
5211
+ }).readonly().optional(),
5135
5212
  "thread": object({
5136
5213
  "threadRef": intersection(string(), unknown()).readonly(),
5137
- "taskRef": intersection(string(), unknown()).readonly(),
5214
+ "taskRef": intersection(string(), unknown()).readonly().optional(),
5138
5215
  "revision": number().readonly()
5139
5216
  }).readonly(),
5140
- "taskNumber": number().readonly(),
5217
+ "taskNumber": number().readonly().optional(),
5141
5218
  "messageCount": number().readonly()
5142
5219
  })).readonly(),
5143
5220
  "claims": array(object({
@@ -5158,7 +5235,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5158
5235
  "kind": union([
5159
5236
  literal("accept"),
5160
5237
  literal("close"),
5161
- literal("reopen")
5238
+ literal("reopen"),
5239
+ literal("promote")
5162
5240
  ]).readonly(),
5163
5241
  "releasedClaimRefs": union([_undefined(), array(intersection(string(), unknown()))]).readonly().optional(),
5164
5242
  "completedClaimRefs": union([_undefined(), array(intersection(string(), unknown()))]).readonly().optional(),
@@ -5220,7 +5298,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5220
5298
  },
5221
5299
  sourceLocation: {
5222
5300
  "file": "packages/agent-team/src/index.ts",
5223
- "line": 342,
5301
+ "line": 380,
5224
5302
  "column": 9
5225
5303
  }
5226
5304
  },
@@ -5247,7 +5325,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5247
5325
  },
5248
5326
  sourceLocation: {
5249
5327
  "file": "packages/agent-team/src/index.ts",
5250
- "line": 644,
5328
+ "line": 664,
5251
5329
  "column": 9
5252
5330
  }
5253
5331
  },
@@ -5275,7 +5353,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5275
5353
  },
5276
5354
  sourceLocation: {
5277
5355
  "file": "packages/agent-team/src/index.ts",
5278
- "line": 279,
5356
+ "line": 317,
5279
5357
  "column": 9
5280
5358
  }
5281
5359
  },
@@ -5302,7 +5380,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5302
5380
  },
5303
5381
  sourceLocation: {
5304
5382
  "file": "packages/agent-team/src/index.ts",
5305
- "line": 524,
5383
+ "line": 554,
5306
5384
  "column": 9
5307
5385
  }
5308
5386
  },
@@ -5329,7 +5407,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5329
5407
  },
5330
5408
  sourceLocation: {
5331
5409
  "file": "packages/agent-team/src/index.ts",
5332
- "line": 320,
5410
+ "line": 358,
5333
5411
  "column": 9
5334
5412
  }
5335
5413
  },
@@ -5356,7 +5434,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5356
5434
  },
5357
5435
  sourceLocation: {
5358
5436
  "file": "packages/agent-team/src/index.ts",
5359
- "line": 621,
5437
+ "line": 650,
5360
5438
  "column": 9
5361
5439
  }
5362
5440
  },
@@ -5383,7 +5461,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5383
5461
  },
5384
5462
  sourceLocation: {
5385
5463
  "file": "packages/agent-team/src/index.ts",
5386
- "line": 654,
5464
+ "line": 673,
5387
5465
  "column": 3
5388
5466
  }
5389
5467
  },
@@ -5410,7 +5488,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5410
5488
  },
5411
5489
  sourceLocation: {
5412
5490
  "file": "packages/agent-team/src/index.ts",
5413
- "line": 534,
5491
+ "line": 574,
5414
5492
  "column": 9
5415
5493
  }
5416
5494
  },
@@ -5438,10 +5516,37 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5438
5516
  },
5439
5517
  sourceLocation: {
5440
5518
  "file": "packages/agent-team/src/index.ts",
5441
- "line": 270,
5519
+ "line": 308,
5442
5520
  "column": 3
5443
5521
  }
5444
5522
  },
5523
+ {
5524
+ id: "@wowyuarm/dsh-agent-team#agentTeam/promoteThread",
5525
+ service: "agentTeam",
5526
+ namespace: "agentTeam",
5527
+ method: "promoteThread",
5528
+ invocation: { kind: "direct" },
5529
+ parameters: [{
5530
+ name: "request",
5531
+ wire: "request",
5532
+ source: "json",
5533
+ codec: {
5534
+ mode: "strict",
5535
+ typeSymbol: "@wowyuarm/dsh-agent-team/types#AgentTeamPromoteThreadRequest",
5536
+ schema: _wowyuarm_dsh_agent_team_agentTeam_promoteThread_parameter_0$schema
5537
+ }
5538
+ }],
5539
+ result: {
5540
+ mode: "strict",
5541
+ typeSymbol: "@wowyuarm/dsh-agent-team/types#AgentTeamPromoteThreadResult",
5542
+ schema: _wowyuarm_dsh_agent_team_agentTeam_promoteThread_result$schema
5543
+ },
5544
+ sourceLocation: {
5545
+ "file": "packages/agent-team/src/index.ts",
5546
+ "line": 564,
5547
+ "column": 9
5548
+ }
5549
+ },
5445
5550
  {
5446
5551
  id: "@wowyuarm/dsh-agent-team#agentTeam/putAttachment",
5447
5552
  service: "agentTeam",
@@ -5465,7 +5570,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5465
5570
  },
5466
5571
  sourceLocation: {
5467
5572
  "file": "packages/agent-team/src/index.ts",
5468
- "line": 608,
5573
+ "line": 637,
5469
5574
  "column": 9
5470
5575
  }
5471
5576
  },
@@ -5492,7 +5597,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5492
5597
  },
5493
5598
  sourceLocation: {
5494
5599
  "file": "packages/agent-team/src/index.ts",
5495
- "line": 661,
5600
+ "line": 680,
5496
5601
  "column": 9
5497
5602
  }
5498
5603
  },
@@ -5519,7 +5624,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5519
5624
  },
5520
5625
  sourceLocation: {
5521
5626
  "file": "packages/agent-team/src/index.ts",
5522
- "line": 400,
5627
+ "line": 433,
5523
5628
  "column": 9
5524
5629
  }
5525
5630
  },
@@ -5546,7 +5651,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5546
5651
  },
5547
5652
  sourceLocation: {
5548
5653
  "file": "packages/agent-team/src/index.ts",
5549
- "line": 546,
5654
+ "line": 585,
5550
5655
  "column": 9
5551
5656
  }
5552
5657
  },
@@ -5573,7 +5678,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5573
5678
  },
5574
5679
  sourceLocation: {
5575
5680
  "file": "packages/agent-team/src/index.ts",
5576
- "line": 629,
5681
+ "line": 658,
5577
5682
  "column": 9
5578
5683
  }
5579
5684
  },
@@ -5600,7 +5705,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5600
5705
  },
5601
5706
  sourceLocation: {
5602
5707
  "file": "packages/agent-team/src/index.ts",
5603
- "line": 258,
5708
+ "line": 295,
5604
5709
  "column": 3
5605
5710
  }
5606
5711
  },
@@ -5627,7 +5732,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5627
5732
  },
5628
5733
  sourceLocation: {
5629
5734
  "file": "packages/agent-team/src/index.ts",
5630
- "line": 556,
5735
+ "line": 594,
5631
5736
  "column": 9
5632
5737
  }
5633
5738
  },
@@ -5654,7 +5759,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5654
5759
  },
5655
5760
  sourceLocation: {
5656
5761
  "file": "packages/agent-team/src/index.ts",
5657
- "line": 678,
5762
+ "line": 696,
5658
5763
  "column": 3
5659
5764
  }
5660
5765
  },
@@ -5681,7 +5786,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5681
5786
  },
5682
5787
  sourceLocation: {
5683
5788
  "file": "packages/agent-team/src/index.ts",
5684
- "line": 671,
5789
+ "line": 689,
5685
5790
  "column": 3
5686
5791
  }
5687
5792
  },
@@ -5708,7 +5813,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5708
5813
  },
5709
5814
  sourceLocation: {
5710
5815
  "file": "packages/agent-team/src/index.ts",
5711
- "line": 332,
5816
+ "line": 370,
5712
5817
  "column": 9
5713
5818
  }
5714
5819
  },
@@ -5735,7 +5840,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5735
5840
  },
5736
5841
  sourceLocation: {
5737
5842
  "file": "packages/agent-team/src/index.ts",
5738
- "line": 487,
5843
+ "line": 524,
5739
5844
  "column": 9
5740
5845
  }
5741
5846
  },
@@ -5762,7 +5867,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5762
5867
  },
5763
5868
  sourceLocation: {
5764
5869
  "file": "packages/agent-team/src/index.ts",
5765
- "line": 685,
5870
+ "line": 703,
5766
5871
  "column": 3
5767
5872
  }
5768
5873
  }
@@ -5775,14 +5880,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5775
5880
  if (typeof localStorage === "undefined") return { mode: "conversation" };
5776
5881
  try {
5777
5882
  const parsed = JSON.parse(localStorage.getItem("dsh.agent-team.navigation") ?? "");
5778
- const hasThread = typeof parsed.taskRef === "string" && typeof parsed.threadRef === "string";
5883
+ const hasThread = typeof parsed.threadRef === "string";
5779
5884
  return {
5780
5885
  mode: parsed.mode === "team" ? "team" : "conversation",
5781
5886
  ...typeof parsed.workspaceId === "string" ? { workspaceId: parsed.workspaceId } : {},
5782
5887
  ...typeof parsed.channelRef === "string" ? { channelRef: parsed.channelRef } : {},
5783
5888
  ...hasThread ? {
5784
- taskRef: parsed.taskRef,
5785
5889
  threadRef: parsed.threadRef,
5890
+ ...typeof parsed.taskRef === "string" ? { taskRef: parsed.taskRef } : {},
5786
5891
  ...typeof parsed.taskNumber === "number" && Number.isInteger(parsed.taskNumber) && parsed.taskNumber > 0 ? { taskNumber: parsed.taskNumber } : {}
5787
5892
  } : {}
5788
5893
  };
@@ -5832,9 +5937,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5832
5937
  this.clearMemberSession();
5833
5938
  this.setChannel(channelRef);
5834
5939
  },
5835
- selectThread: (taskRef, threadRef, channelRef, taskNumber) => {
5940
+ selectThread: (threadRef, channelRef, taskRef, taskNumber) => {
5836
5941
  this.clearMemberSession();
5837
- this.setThread(taskRef, threadRef, channelRef, taskNumber);
5942
+ this.setThread(threadRef, channelRef, taskRef, taskNumber);
5838
5943
  },
5839
5944
  backToWorkspace: () => {
5840
5945
  this.clearMemberSession();
@@ -5905,18 +6010,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5905
6010
  this.snapshot = base;
5906
6011
  this.commit();
5907
6012
  }
5908
- setThread(taskRef, threadRef, channelRef, taskNumber) {
6013
+ setThread(threadRef, channelRef, taskRef, taskNumber) {
5909
6014
  if (this.snapshot.threadRef === threadRef && this.snapshot.taskRef === taskRef && this.snapshot.channelRef === channelRef && this.snapshot.taskNumber === taskNumber) return;
5910
- if (threadRef === void 0 || taskRef === void 0) {
6015
+ if (threadRef === void 0) {
5911
6016
  const { taskRef: _taskRef, threadRef: _threadRef, taskNumber: _taskNumber, ...base } = this.snapshot;
5912
6017
  this.snapshot = base;
5913
6018
  } else {
5914
6019
  const { channelRef: _channelRef, taskRef: _taskRef, threadRef: _threadRef, taskNumber: _taskNumber, ...base } = this.snapshot;
5915
6020
  this.snapshot = {
5916
6021
  ...base,
5917
- taskRef,
5918
6022
  threadRef,
5919
6023
  ...channelRef === void 0 ? {} : { channelRef },
6024
+ ...taskRef === void 0 ? {} : { taskRef },
5920
6025
  ...taskNumber === void 0 ? {} : { taskNumber }
5921
6026
  };
5922
6027
  }
@@ -6377,8 +6482,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6377
6482
  return `${(byteSize / (1024 * 1024)).toFixed(1)} MB`;
6378
6483
  }
6379
6484
  //#endregion
6485
+ //#region src/client/requests.ts
6486
+ /** Fresh idempotency identity for one Client-initiated durable request. */
6487
+ const mintRequestId = () => crypto.randomUUID();
6488
+ //#endregion
6380
6489
  //#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/composer.module.css.mjs
6381
- const css$5 = ".x9jGQq_root{padding:0 var(--dsh-composer-side-clearance,16px) 8px;flex-direction:column;align-items:center;display:flex}.x9jGQq_card{box-sizing:border-box;width:100%;max-width:var(--dsh-composer-card-max-width,780px);border:1px solid var(--dsw-alias-border-l2-darkmode-thin);background:var(--dsw-specific-input-major,var(--dsw-alias-bg-layer-1));box-shadow:var(--dsw-shadow-lv2);border-radius:22px;flex-direction:column;gap:6px;padding:10px 0 0;display:flex;position:relative}.x9jGQq_inputArea{min-height:28px;position:relative}.x9jGQq_inputArea textarea{box-sizing:border-box;resize:none;width:100%;min-height:28px;max-height:336px;color:var(--dsw-alias-label-primary,var(--dsw-alias-label-primary));font:inherit;white-space:pre-wrap;overflow-wrap:anywhere;background:0 0;border:0;outline:0;padding:4px 12px 0 16px;font-size:15px;line-height:24px;display:block;overflow-y:auto}.x9jGQq_inputArea textarea::placeholder{color:var(--dsw-alias-label-caption,var(--dsw-alias-label-tertiary))}.x9jGQq_inputArea textarea:disabled{cursor:not-allowed;opacity:.55}.x9jGQq_mentionMenu{z-index:10;border:1px solid var(--dsw-alias-border-inverted);background:var(--dsw-specific-menu);max-height:min(320px,40vh);box-shadow:var(--dsw-shadow-lv3);border-radius:12px;padding:4px;position:absolute;bottom:calc(100% + 12px);left:0;right:0;overflow-y:auto}.x9jGQq_mentionOption{width:100%;min-height:40px;color:var(--dsw-alias-label-primary,var(--dsw-alias-label-primary));cursor:pointer;text-align:left;background:0 0;border:0;border-radius:10px;grid-template-columns:16px minmax(0,auto) minmax(0,1fr);align-items:center;gap:8px;padding:8px 10px;font-size:14px;line-height:22px;display:grid}.x9jGQq_mentionOption:hover,.x9jGQq_mentionOption[aria-selected=true]{background:var(--dsw-alias-interactive-bg-hover)}.x9jGQq_mentionName{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.x9jGQq_mentionDescription{min-width:0;color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-tertiary));text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.x9jGQq_toolbar{justify-content:flex-end;align-items:center;gap:6px;min-height:34px;padding:2px 8px 6px;display:flex}.x9jGQq_attachButton{background:var(--dsw-specific-selector);color:var(--dsw-alias-label-primary);cursor:pointer;border:0;border-radius:999px;flex:none;place-items:center;width:28px;height:28px;margin-right:auto;display:grid}.x9jGQq_attachButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.x9jGQq_attachButton:disabled{cursor:default;opacity:.5}.x9jGQq_attachButton:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,var(--dsw-specific-selector));outline-offset:1px}.x9jGQq_fileInput{display:none}.x9jGQq_fileChips{flex-wrap:wrap;gap:4px;margin:0;padding:4px 8px 0;list-style:none;display:flex}.x9jGQq_fileChip{background:var(--dsw-alias-interactive-bg-hover);border-radius:6px;align-items:center;gap:4px;max-width:100%;padding:2px 4px 2px 8px;display:inline-flex}.x9jGQq_fileChipSize{color:var(--dsw-alias-label-tertiary);margin-left:6px}.x9jGQq_imageChip{align-items:center;display:flex}.x9jGQq_imageChipPreview{border:1px solid var(--dsw-alias-border-l2);object-fit:cover;border-radius:4px;width:56px;height:40px}.x9jGQq_fileChipName{text-overflow:ellipsis;white-space:nowrap;max-width:220px;font-size:11px;line-height:16px;overflow:hidden}.x9jGQq_fileChipRemove{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;justify-content:center;align-items:center;width:16px;height:16px;padding:0;font-size:12px;display:inline-flex}.x9jGQq_fileChipRemove:hover,.x9jGQq_fileChipRemove:focus-visible{color:var(--dsw-alias-label-primary);outline:none}.x9jGQq_sendButton{background:var(--dsw-alias-button-info-fill,var(--dsw-alias-button-primary-fill));color:#fff;cursor:pointer;border:0;border-radius:50%;justify-content:center;align-items:center;width:34px;height:34px;padding:0;transition:background-color .1s,opacity .1s;display:inline-flex}.x9jGQq_sendButton:hover:not(:disabled){background:var(--dsw-alias-button-info-hover,var(--dsw-alias-button-primary-hover))}.x9jGQq_sendButton:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.x9jGQq_sendButton:disabled{cursor:not-allowed;opacity:.4}.x9jGQq_confirmation{color:var(--dsw-alias-label-tertiary);align-self:stretch;margin:0;padding:0 16px;font-size:12px;line-height:18px}.x9jGQq_notifyRow{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-tertiary));overflow-wrap:anywhere;margin:0;padding:0 16px;font-size:12px;line-height:18px}.x9jGQq_error{color:var(--dsw-alias-state-error-primary);align-self:stretch;margin:0;padding:0 4px 2px;font-size:12px;line-height:18px}@media (width<=600px){.x9jGQq_mentionOption{grid-template-columns:16px minmax(0,1fr);min-height:36px;padding-block:6px}.x9jGQq_mentionDescription{display:none}}@media (prefers-reduced-motion:reduce){.x9jGQq_sendButton{transition:none}}";
6490
+ const css$5 = ".x9jGQq_root{padding:0 var(--dsh-composer-side-clearance,16px) 8px;flex-direction:column;align-items:center;display:flex}.x9jGQq_card{box-sizing:border-box;width:100%;max-width:var(--dsh-composer-card-max-width,780px);border:1px solid var(--dsw-alias-border-l2-darkmode-thin);background:var(--dsw-specific-input-major,var(--dsw-alias-bg-layer-1));box-shadow:var(--dsw-shadow-lv2);border-radius:22px;flex-direction:column;gap:6px;padding:10px 0 0;display:flex;position:relative}.x9jGQq_inputArea{min-height:28px;position:relative}.x9jGQq_inputArea textarea{box-sizing:border-box;resize:none;width:100%;min-height:28px;max-height:336px;color:var(--dsw-alias-label-primary,var(--dsw-alias-label-primary));font:inherit;white-space:pre-wrap;overflow-wrap:anywhere;background:0 0;border:0;outline:0;padding:4px 12px 0 16px;font-size:15px;line-height:24px;display:block;overflow-y:auto}.x9jGQq_inputArea textarea::placeholder{color:var(--dsw-alias-label-caption,var(--dsw-alias-label-tertiary))}.x9jGQq_memberSessionRoot{padding:0 var(--dsh-composer-side-clearance) 8px}.x9jGQq_memberSessionCard{font-family:var(--dsw-font-family);gap:6px;padding-top:10px;font-size:16px;line-height:24px}.x9jGQq_memberSessionInputArea textarea{min-height:28px;color:var(--dsw-alias-label-primary);caret-color:var(--dsw-alias-state-business-primary);font-family:var(--dsw-font-family);font-size:inherit;line-height:inherit;padding:4px 12px 0 16px}.x9jGQq_memberSessionStatus{width:100%;max-width:var(--dsh-composer-card-max-width);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-state-error-primary);border-radius:8px;margin:0 0 6px;padding:4px 8px;font-size:12px;line-height:18px}.x9jGQq_memberSessionToolbar{min-width:0;padding:2px 8px 6px}.x9jGQq_memberSessionPrimary{background:var(--dsw-alias-button-info-fill);border-radius:999px;place-items:center;display:grid;transform:translateY(-2px)}.x9jGQq_memberSessionPrimary:hover:not(:disabled){background:var(--dsw-alias-button-info-hover)}.x9jGQq_memberSessionPrimary:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.x9jGQq_memberSessionPrimary:disabled{cursor:default;opacity:.4}.x9jGQq_inputArea textarea:disabled{cursor:not-allowed;opacity:.55}.x9jGQq_mentionMenu{z-index:10;border:1px solid var(--dsw-alias-border-inverted);background:var(--dsw-specific-menu);max-height:min(320px,40vh);box-shadow:var(--dsw-shadow-lv3);border-radius:12px;padding:4px;position:absolute;bottom:calc(100% + 12px);left:0;right:0;overflow-y:auto}.x9jGQq_mentionOption{width:100%;min-height:40px;color:var(--dsw-alias-label-primary,var(--dsw-alias-label-primary));cursor:pointer;text-align:left;background:0 0;border:0;border-radius:10px;grid-template-columns:16px minmax(0,auto) minmax(0,1fr);align-items:center;gap:8px;padding:8px 10px;font-size:14px;line-height:22px;display:grid}.x9jGQq_mentionOption:hover,.x9jGQq_mentionOption[aria-selected=true]{background:var(--dsw-alias-interactive-bg-hover)}.x9jGQq_mentionName{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.x9jGQq_mentionDescription{min-width:0;color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-tertiary));text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.x9jGQq_toolbar{justify-content:flex-end;align-items:center;gap:6px;min-height:34px;padding:2px 8px 6px;display:flex}.x9jGQq_asTaskOn[aria-pressed=true],.x9jGQq_asTaskOn[aria-pressed=true]:hover:not(:disabled){background:var(--dsw-alias-button-primary-fill);border-color:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.x9jGQq_attachButton{background:var(--dsw-specific-selector);color:var(--dsw-alias-label-primary);cursor:pointer;border:0;border-radius:999px;flex:none;place-items:center;width:28px;height:28px;margin-right:auto;display:grid}.x9jGQq_attachButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.x9jGQq_attachButton:disabled{cursor:default;opacity:.5}.x9jGQq_attachButton:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,var(--dsw-specific-selector));outline-offset:1px}.x9jGQq_fileInput{display:none}.x9jGQq_fileChips{flex-wrap:wrap;gap:4px;margin:0;padding:4px 8px 0;list-style:none;display:flex}.x9jGQq_fileChip{background:var(--dsw-alias-interactive-bg-hover);border-radius:6px;align-items:center;gap:4px;max-width:100%;padding:2px 4px 2px 8px;display:inline-flex}.x9jGQq_fileChipSize{color:var(--dsw-alias-label-tertiary);margin-left:6px}.x9jGQq_imageChip{align-items:center;display:flex}.x9jGQq_imageChipPreview{border:1px solid var(--dsw-alias-border-l2);object-fit:cover;border-radius:4px;width:56px;height:40px}.x9jGQq_fileChipName{text-overflow:ellipsis;white-space:nowrap;max-width:220px;font-size:11px;line-height:16px;overflow:hidden}.x9jGQq_fileChipRemove{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;justify-content:center;align-items:center;width:16px;height:16px;padding:0;font-size:12px;display:inline-flex}.x9jGQq_fileChipRemove:hover,.x9jGQq_fileChipRemove:focus-visible{color:var(--dsw-alias-label-primary);outline:none}.x9jGQq_sendButton{background:var(--dsw-alias-button-info-fill,var(--dsw-alias-button-primary-fill));color:#fff;cursor:pointer;border:0;border-radius:50%;justify-content:center;align-items:center;width:34px;height:34px;padding:0;transition:background-color .1s,opacity .1s;display:inline-flex}.x9jGQq_sendButton:hover:not(:disabled){background:var(--dsw-alias-button-info-hover,var(--dsw-alias-button-primary-hover))}.x9jGQq_sendButton:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.x9jGQq_sendButton:disabled{cursor:not-allowed;opacity:.4}.x9jGQq_confirmation{color:var(--dsw-alias-label-tertiary);align-self:stretch;margin:0;padding:0 16px;font-size:12px;line-height:18px}.x9jGQq_notifyRow{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-tertiary));overflow-wrap:anywhere;margin:0;padding:0 16px;font-size:12px;line-height:18px}.x9jGQq_error{color:var(--dsw-alias-state-error-primary);align-self:stretch;margin:0;padding:0 4px 2px;font-size:12px;line-height:18px}@media (width<=600px){.x9jGQq_mentionOption{grid-template-columns:16px minmax(0,1fr);min-height:36px;padding-block:6px}.x9jGQq_mentionDescription{display:none}}@media (prefers-reduced-motion:reduce){.x9jGQq_sendButton{transition:none}}";
6382
6491
  const tagId$5 = "@wowyuarm/dsh-agent-team/composer.module.css";
6383
6492
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$5) + "]") === null) {
6384
6493
  const tag = document.createElement("style");
@@ -6388,6 +6497,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6388
6497
  document.head.appendChild(tag);
6389
6498
  }
6390
6499
  var composer_module_css_default = {
6500
+ "asTaskOn": "x9jGQq_asTaskOn",
6391
6501
  "attachButton": "x9jGQq_attachButton",
6392
6502
  "card": "x9jGQq_card",
6393
6503
  "confirmation": "x9jGQq_confirmation",
@@ -6401,6 +6511,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6401
6511
  "imageChip": "x9jGQq_imageChip",
6402
6512
  "imageChipPreview": "x9jGQq_imageChipPreview",
6403
6513
  "inputArea": "x9jGQq_inputArea",
6514
+ "memberSessionCard": "x9jGQq_memberSessionCard",
6515
+ "memberSessionInputArea": "x9jGQq_memberSessionInputArea",
6516
+ "memberSessionPrimary": "x9jGQq_memberSessionPrimary",
6517
+ "memberSessionRoot": "x9jGQq_memberSessionRoot",
6518
+ "memberSessionStatus": "x9jGQq_memberSessionStatus",
6519
+ "memberSessionToolbar": "x9jGQq_memberSessionToolbar",
6404
6520
  "mentionDescription": "x9jGQq_mentionDescription",
6405
6521
  "mentionMenu": "x9jGQq_mentionMenu",
6406
6522
  "mentionName": "x9jGQq_mentionName",
@@ -6447,7 +6563,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6447
6563
  }
6448
6564
  return url;
6449
6565
  }
6450
- function TeamComposer({ members, recipients, draft, pending, confirmation, error, onDraftChange, onRecipientsChange, onSubmit, pendingFiles, onFilesChange, t }) {
6566
+ function TeamComposer({ members, recipients, draft, pending, confirmation, error, onDraftChange, onRecipientsChange, onSubmit, placeholder, pendingFiles, onFilesChange, asTask, onAsTaskChange, t }) {
6451
6567
  const inputRef = (0, react.useRef)(null);
6452
6568
  const fileInputRef = (0, react.useRef)(null);
6453
6569
  const rootRef = (0, react.useRef)(null);
@@ -6564,7 +6680,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6564
6680
  ref: rootRef,
6565
6681
  className: composer_module_css_default.root,
6566
6682
  onSubmit: (event) => {
6567
- console.log("DBG composer submit pending=%s draft=%j", pending, draft);
6568
6683
  event.preventDefault();
6569
6684
  if (!pending && draft.trim() !== "") onSubmit();
6570
6685
  },
@@ -6624,7 +6739,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6624
6739
  "aria-expanded": menuOpen,
6625
6740
  value: draft,
6626
6741
  readOnly: pending,
6627
- placeholder: t("messagePlaceholder"),
6742
+ placeholder: placeholder ?? t("messagePlaceholder"),
6628
6743
  rows: 1,
6629
6744
  onChange,
6630
6745
  onKeyDown,
@@ -6685,39 +6800,53 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6685
6800
  }),
6686
6801
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6687
6802
  className: composer_module_css_default.toolbar,
6688
- children: [onFilesChange !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
6689
- ref: fileInputRef,
6690
- type: "file",
6691
- multiple: true,
6692
- className: composer_module_css_default.fileInput,
6693
- "aria-hidden": "true",
6694
- tabIndex: -1,
6695
- onChange: (event) => {
6696
- const chosen = [...event.target.files ?? []];
6697
- if (chosen.length > 0 && pendingFiles !== void 0) onFilesChange([...pendingFiles, ...chosen]);
6698
- event.target.value = "";
6699
- }
6700
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6701
- type: "button",
6702
- className: composer_module_css_default.attachButton,
6703
- "aria-label": t("attachFiles"),
6704
- title: t("attachFiles"),
6705
- disabled: pending,
6706
- onClick: () => {
6707
- fileInputRef.current?.click();
6708
- },
6709
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, { size: 14 })
6710
- })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6711
- type: "submit",
6712
- className: composer_module_css_default.sendButton,
6713
- "aria-label": pending ? t("sendingMessage") : t("sendMessage"),
6714
- disabled: pending || draft.trim() === "",
6715
- onMouseDown: (event) => {
6716
- event.preventDefault();
6717
- inputRef.current?.focus({ preventScroll: true });
6718
- },
6719
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSendOutline16, { size: 16 })
6720
- })]
6803
+ children: [
6804
+ onAsTaskChange !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
6805
+ size: "sm",
6806
+ variant: "outline",
6807
+ className: asTask === true ? composer_module_css_default.asTaskOn : void 0,
6808
+ "aria-pressed": asTask === true,
6809
+ disabled: pending,
6810
+ onClick: () => {
6811
+ onAsTaskChange(asTask !== true);
6812
+ },
6813
+ children: t("asTask")
6814
+ }),
6815
+ onFilesChange !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
6816
+ ref: fileInputRef,
6817
+ type: "file",
6818
+ multiple: true,
6819
+ className: composer_module_css_default.fileInput,
6820
+ "aria-hidden": "true",
6821
+ tabIndex: -1,
6822
+ onChange: (event) => {
6823
+ const chosen = [...event.target.files ?? []];
6824
+ if (chosen.length > 0 && pendingFiles !== void 0) onFilesChange([...pendingFiles, ...chosen]);
6825
+ event.target.value = "";
6826
+ }
6827
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6828
+ type: "button",
6829
+ className: composer_module_css_default.attachButton,
6830
+ "aria-label": t("attachFiles"),
6831
+ title: t("attachFiles"),
6832
+ disabled: pending,
6833
+ onClick: () => {
6834
+ fileInputRef.current?.click();
6835
+ },
6836
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, { size: 14 })
6837
+ })] }),
6838
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6839
+ type: "submit",
6840
+ className: composer_module_css_default.sendButton,
6841
+ "aria-label": pending ? t("sendingMessage") : t("sendMessage"),
6842
+ disabled: pending || draft.trim() === "",
6843
+ onMouseDown: (event) => {
6844
+ event.preventDefault();
6845
+ inputRef.current?.focus({ preventScroll: true });
6846
+ },
6847
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSendOutline16, { size: 16 })
6848
+ })
6849
+ ]
6721
6850
  })
6722
6851
  ]
6723
6852
  }), error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
@@ -6756,6 +6885,27 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6756
6885
  pending.delete(entry.taskRef);
6757
6886
  emit();
6758
6887
  };
6888
+ /** Click-path Host lookup: remember every resolved entry and hand them back for immediate navigation. */
6889
+ const hostTaskRefLookup = (resolveTaskRefs, workspaceId) => async (taskRefs) => {
6890
+ const result = await resolveTaskRefs({
6891
+ workspaceId,
6892
+ taskRefs
6893
+ });
6894
+ if (!result.ok) return [];
6895
+ for (const entry of result.value.resolved) rememberResolvedTaskRef(entry);
6896
+ return result.value.resolved;
6897
+ };
6898
+ /** Resolve one Task ref through the Host and jump to its home Channel Thread. */
6899
+ const jumpToTaskThread = (resolveTaskRefs, workspaceId, taskRef, selectThread) => {
6900
+ resolveTaskRefs({
6901
+ workspaceId,
6902
+ taskRefs: [taskRef]
6903
+ }).then((result) => {
6904
+ if (!result.ok) return;
6905
+ const hit = result.value.resolved[0];
6906
+ if (hit !== void 0) selectThread(hit.threadRef, hit.channelRef, hit.taskRef, hit.taskNumber);
6907
+ });
6908
+ };
6759
6909
  /**
6760
6910
  * Batch-resolve unknown refs through the Host lookup. Concurrent callers
6761
6911
  * deduplicate through the pending set; failures just clear the pending mark
@@ -6821,12 +6971,22 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6821
6971
  for (let index = 0; index < memberId.length; index += 1) hash = (hash * 31 + memberId.charCodeAt(index)) % 360;
6822
6972
  return hash;
6823
6973
  }
6824
- const BRANDED_REF_PATTERN = /\b(task|channel|thread):[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi;
6974
+ const BRANDED_REF_PATTERN = /\b(task|channel|thread):{1,2}[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi;
6975
+ /**
6976
+ * Canonical form of one matched ref: models occasionally double the colon or
6977
+ * uppercase the UUID when citing a ref in prose, while Host lookups and
6978
+ * navigation only accept the lowercase single-colon ref the ledger mints.
6979
+ */
6980
+ function canonicalBrandedRef(match) {
6981
+ return match.replace("::", ":").toLowerCase();
6982
+ }
6825
6983
  /**
6826
6984
  * Split a literal text run into plain and branded-ref segments. The pattern
6827
6985
  * anchors on the fixed ref prefixes plus the UUID shape, so ordinary prose
6828
- * containing a colon never linkifies. Refs render as navigation links; text
6829
- * without any ref comes back as one untouched segment.
6986
+ * containing a colon never linkifies; a doubled colon from model output is
6987
+ * tolerated. Segment refs are always canonical, so resolution and navigation
6988
+ * work regardless of how the ref was spelled; text without any ref comes
6989
+ * back as one untouched segment.
6830
6990
  */
6831
6991
  function splitBrandedRefs(text) {
6832
6992
  const segments = [];
@@ -6836,13 +6996,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6836
6996
  if (start > cursor) segments.push({ text: text.slice(cursor, start) });
6837
6997
  segments.push({
6838
6998
  text: match[0],
6839
- ref: match[0]
6999
+ ref: canonicalBrandedRef(match[0])
6840
7000
  });
6841
7001
  cursor = start + match[0].length;
6842
7002
  }
6843
7003
  if (cursor < text.length) segments.push({ text: text.slice(cursor) });
6844
7004
  return segments;
6845
7005
  }
7006
+ /**
7007
+ * Whether one string's whole content is exactly one branded ref. A code span
7008
+ * like this is the model styling a ref as an identifier, not publishing code,
7009
+ * so the Markdown pass may linkify it; anything larger stays literal.
7010
+ */
7011
+ function isSingleBrandedRef(text) {
7012
+ const trimmed = text.trim();
7013
+ if (trimmed === "") return false;
7014
+ const matches = [...trimmed.matchAll(BRANDED_REF_PATTERN)];
7015
+ return matches.length === 1 && matches[0][0] === trimmed;
7016
+ }
6846
7017
  function escapeRegExp(value) {
6847
7018
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6848
7019
  }
@@ -6927,6 +7098,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6927
7098
  actor,
6928
7099
  count: activity.completedClaimRefs.length
6929
7100
  }) : options.t("activityAccepted", { actor });
7101
+ if (activity.kind === "promote") return options.t("activityPromoted", { actor });
6930
7102
  if (activity.kind === "close") return options.t("activityClosed", { actor });
6931
7103
  if (activity.kind === "reopen") return options.t("activityReopened", { actor });
6932
7104
  const direction = "claimRef" in activity ? options.claims.find((claim) => claim.claimRef === activity.claimRef)?.direction ?? options.t("claims") : options.t("claims");
@@ -6952,9 +7124,38 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6952
7124
  function stripAttachmentLines(body) {
6953
7125
  return body.replaceAll(/^\[attachment\] .*$(\n)?/gm, "").replace(/\n+$/, "");
6954
7126
  }
7127
+ /** Whether one displayed Message body starts clamped behind the expand control. */
7128
+ function shouldClampMessage(displayBody) {
7129
+ return displayBody.length > 600;
7130
+ }
7131
+ /**
7132
+ * Decide how one Message body renders. Human input and plain-prose Agent
7133
+ * bodies stay literal, with structured mention chips inline where possible;
7134
+ * rich Agent Markdown keeps unmatched mentions and non-Task refs in the
7135
+ * trailing fallback row while the post-render pass handles Task refs at their
7136
+ * authored position. Surfaces without ref navigation render everything
7137
+ * literally and keep the full fallback row.
7138
+ */
7139
+ function planMessageBody(body, options) {
7140
+ const stripped = stripAttachmentLines(body);
7141
+ const displayBody = stripped === "" ? body : stripped;
7142
+ const richAgentBody = !options.human && !isPlainTextBody(displayBody);
7143
+ const inline = (options.human || isPlainTextBody(displayBody)) && options.mentionNames !== void 0 && options.mentionNames.length > 0 ? splitMentionNames(displayBody, options.mentionNames) : void 0;
7144
+ const fallbackNames = inline !== void 0 ? inline.unmatched : richAgentBody && options.canOpenRefs && options.mentionNames !== void 0 ? splitMentionNames(displayBody, options.mentionNames).unmatched : options.mentionNames ?? [];
7145
+ const refs = splitBrandedRefs(displayBody).flatMap((segment) => segment.ref === void 0 ? [] : [segment.ref]);
7146
+ return {
7147
+ displayBody,
7148
+ richAgentBody,
7149
+ render: inline !== void 0 ? "inline" : options.human || options.canOpenRefs && !richAgentBody && refs.length > 0 ? "literal" : "markdown",
7150
+ ...inline === void 0 ? {} : { inline },
7151
+ fallbackNames,
7152
+ fallbackRefs: richAgentBody && options.canOpenRefs ? refs.filter((ref) => !ref.startsWith("task:")) : [],
7153
+ taskRefs: options.canOpenRefs && !richAgentBody ? refs.filter((ref) => ref.startsWith("task:")).map((ref) => ref) : []
7154
+ };
7155
+ }
6955
7156
  //#endregion
6956
7157
  //#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/conversation.module.css.mjs
6957
- const css$4 = ".omcBaG_surface{grid-template-rows:auto minmax(0,1fr) auto;min-width:0;height:100%;min-height:0;display:grid;overflow:hidden}.omcBaG_surfaceHeader{border-bottom:1px solid var(--dsw-alias-border-l2);min-width:0;padding:14px clamp(18px,3vw,36px) 12px}.omcBaG_headerRow{justify-content:space-between;align-items:flex-start;gap:16px;min-width:0;max-width:880px;margin:0 auto;display:flex}.omcBaG_headerCopy{min-width:0}.omcBaG_headerCopy h1{color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;margin:0;font-size:20px;font-weight:600;line-height:28px}.omcBaG_headerCopy p{color:var(--dsw-alias-label-secondary);margin:3px 0 0;font-size:13px;line-height:20px}.omcBaG_headerActions{flex:none;align-items:center;gap:6px;display:flex}.omcBaG_backRow{max-width:880px;margin:0 auto 8px}.omcBaG_timeline{overscroll-behavior:contain;scrollbar-gutter:stable;min-height:0;padding:12px clamp(18px,3vw,36px) 24px;overflow:hidden auto}.omcBaG_timelineContent{flex-direction:column;min-width:0;max-width:880px;min-height:100%;margin:0 auto;display:flex}.omcBaG_emptySurface{margin:auto;padding:32px 0}.omcBaG_emptySurface .omcBaG_emptyState{text-align:center;justify-items:center}.omcBaG_timelineAction{justify-content:center;padding:2px 0 8px;display:flex}.omcBaG_messageRow{gap:10px;padding:10px 0;display:flex}.omcBaG_messageRow[data-grouped]{padding-top:2px}.omcBaG_messageRow[data-grouped] .omcBaG_messageBody>:first-child{margin-top:0}.omcBaG_messageIdentity{background:hsl(var(--team-avatar-hue,212) 42% 46%);color:#fff;border-radius:50%;flex:0 0 28px;justify-content:center;align-items:center;height:28px;font-size:12px;font-weight:600;display:flex}.omcBaG_messageRow[data-human] .omcBaG_messageIdentity{background:var(--dsw-alias-state-business-primary)}.omcBaG_messageRow[data-grouped] .omcBaG_messageIdentity{visibility:hidden}.omcBaG_messageBody{min-width:0}.omcBaG_nameRow{flex-wrap:wrap;align-items:baseline;gap:8px;display:flex}.omcBaG_nameRow strong{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600;line-height:20px}.omcBaG_messageTime{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:20px}.omcBaG_messageText{white-space:pre-wrap;word-break:break-word;margin:6px 0;font-size:14px;line-height:22px}.omcBaG_messageBody .omcBaG_messageMarkdown{font-size:14px;line-height:22px}.omcBaG_messageBody>.omcBaG_messageMarkdown>div:first-child{color:var(--dsw-alias-label-primary);font:inherit}.omcBaG_messageBody .omcBaG_messageMarkdown p{margin:6px 0}.omcBaG_messageBody .omcBaG_messageMarkdown :where(ul,ol){margin:6px 0;padding-left:22px}.omcBaG_messageBody .omcBaG_messageMarkdown li+li{margin-top:2px}.omcBaG_messageBody .omcBaG_messageMarkdown strong{font-weight:600}.omcBaG_messageBody .omcBaG_messageMarkdown :where(h1,h2,h3,h4,h5,h6){margin:12px 0 4px}.omcBaG_messageBody .omcBaG_messageMarkdown :where(h1){font-size:17px;line-height:26px}.omcBaG_messageBody .omcBaG_messageMarkdown :where(h2){font-size:16px;line-height:24px}.omcBaG_messageBody .omcBaG_messageMarkdown :where(h3,h4,h5,h6){font-size:15px;line-height:22px}.omcBaG_messageBody .omcBaG_messageMarkdown pre{margin:8px 0;padding:10px 12px;font-size:13px}.omcBaG_messageBody .omcBaG_messageMarkdown blockquote{margin:6px 0}.omcBaG_messageBody .omcBaG_messageMarkdown :where(th,td){padding-block:5px}.omcBaG_emptyState,.omcBaG_loadingState{color:var(--dsw-alias-label-tertiary);margin:0;padding:14px 0;font-size:13px;line-height:20px}.omcBaG_emptyState{gap:3px;display:grid}.omcBaG_emptyState strong{color:var(--dsw-alias-label-secondary);font-weight:500}.omcBaG_emptyState span{font-size:12px}.omcBaG_loadingState{align-items:center;gap:8px;display:flex}.omcBaG_loadingMark{background:var(--dsw-alias-bg-skeleton);border-radius:50%;width:8px;height:8px;animation:1.2s ease-in-out infinite omcBaG_pulse}.omcBaG_error,.omcBaG_errorState{color:var(--dsw-alias-state-error-primary);max-width:880px;margin:0 auto;padding-top:6px;font-size:12px;line-height:18px}.omcBaG_errorState{justify-content:space-between;align-items:center;gap:8px;display:flex}.omcBaG_welcomeSurface{justify-content:center;align-items:center;min-width:0;height:100%;padding:32px;display:flex}.omcBaG_welcome{text-align:center;max-width:420px}.omcBaG_welcomeEyebrow{color:var(--dsw-alias-label-tertiary);text-transform:uppercase;font-size:12px;line-height:18px}.omcBaG_welcome h1{color:var(--dsw-alias-label-primary);margin:8px 0;font-size:24px;font-weight:600;line-height:32px}.omcBaG_welcome p{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px;line-height:20px}@keyframes omcBaG_pulse{0%,to{opacity:.35}50%{opacity:1}}@media (width<=600px){.omcBaG_surfaceHeader{padding:12px 12px 10px}.omcBaG_headerRow{flex-direction:column;align-items:stretch;gap:8px}.omcBaG_headerActions{flex-wrap:wrap}.omcBaG_backRow{margin-bottom:6px}.omcBaG_timeline{scrollbar-gutter:auto;padding:8px 12px 16px}.omcBaG_messageRow{padding:8px 0}}@media (prefers-reduced-motion:reduce){.omcBaG_loadingMark{animation:none}}.omcBaG_messageRun{margin:2px 0;padding:3px 0}.omcBaG_messageRow[data-grouped]:has(.omcBaG_messageBody>button){border-top:1px solid var(--dsw-alias-border-l2);margin-top:3px;padding-top:7px}.omcBaG_runDivider{border-top:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);margin:2px 0 0;padding:5px 0 0 38px;font-size:11px;line-height:16px}.omcBaG_runDivider+.omcBaG_messageRow[data-grouped]:has(.omcBaG_messageBody>button){border-top:0;margin-top:0}.omcBaG_mention{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 12%, transparent);color:var(--dsw-alias-state-business-primary);border-radius:5px;padding:0 4px;font-weight:500;box-shadow:0 1px 2px #00000014}.omcBaG_mentionsRow{gap:4px;width:fit-content;margin-top:3px;font-size:.85em;display:flex}.omcBaG_attachmentStrip{flex-wrap:wrap;gap:6px;margin-top:4px;display:flex}.omcBaG_attachmentThumb{cursor:zoom-in;border:0;border-radius:8px;padding:0}.omcBaG_attachmentThumb img{object-fit:cover;border-radius:8px;width:128px;height:96px;display:block}.omcBaG_attachmentThumb:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,currentColor);outline-offset:1px}.omcBaG_confirmBody{margin:0 0 8px}.omcBaG_confirmList{gap:6px;margin:0;padding-left:18px;display:grid}.omcBaG_refLink{color:var(--dsw-alias-state-business-primary);cursor:pointer;font:inherit;text-align:left;text-underline-offset:3px;background:0 0;border:none;border-radius:4px;padding:0;text-decoration:underline}.omcBaG_refLink:hover{text-decoration-thickness:2px}.omcBaG_refLink:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}.omcBaG_attachmentModal{width:min(1100px,92vw)}.omcBaG_attachmentZoom{object-fit:contain;border-radius:12px;max-width:100%;max-height:78vh;margin:0 auto;display:block}.omcBaG_attachmentChip{background:var(--dsw-alias-interactive-bg-hover);border-radius:6px;align-items:baseline;gap:6px;max-width:100%;padding:3px 8px;display:inline-flex}.omcBaG_attachmentChipName{text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:17px;overflow:hidden}.omcBaG_attachmentChipSize{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:11px;line-height:17px}";
7158
+ const css$4 = ".omcBaG_surface{grid-template-rows:auto minmax(0,1fr) auto;min-width:0;height:100%;min-height:0;display:grid;overflow:hidden}.omcBaG_surfaceHeader{border-bottom:1px solid var(--dsw-alias-border-l2);min-width:0;padding:14px clamp(18px,3vw,36px) 12px}.omcBaG_headerRow{justify-content:space-between;align-items:flex-start;gap:16px;min-width:0;max-width:880px;margin:0 auto;display:flex}.omcBaG_headerCopy{min-width:0}.omcBaG_headerCopy h1{color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;margin:0;font-size:20px;font-weight:600;line-height:28px}.omcBaG_headerCopy p{color:var(--dsw-alias-label-secondary);margin:3px 0 0;font-size:13px;line-height:20px}.omcBaG_headerActions{flex:none;align-items:center;gap:6px;display:flex}.omcBaG_backRow{max-width:880px;margin:0 auto 8px}.omcBaG_timeline{overscroll-behavior:contain;scrollbar-gutter:stable;min-height:0;padding:12px clamp(18px,3vw,36px) 24px;overflow:hidden auto}.omcBaG_timelineContent{flex-direction:column;min-width:0;max-width:880px;min-height:100%;margin:0 auto;display:flex}.omcBaG_emptySurface{margin:auto;padding:32px 0}.omcBaG_emptySurface .omcBaG_emptyState{text-align:center;justify-items:center}.omcBaG_timelineAction{justify-content:center;padding:2px 0 8px;display:flex}.omcBaG_messageRow{gap:10px;padding:10px 0;display:flex}.omcBaG_messageRow[data-grouped]{padding-top:2px}.omcBaG_messageRow[data-grouped] .omcBaG_messageBody>:first-child,.omcBaG_messageRow[data-grouped] .omcBaG_messageBody>:first-child>:first-child{margin-top:0}.omcBaG_messageIdentity{background:hsl(var(--team-avatar-hue,212) 42% 46%);color:#fff;border-radius:50%;flex:0 0 28px;justify-content:center;align-items:center;height:28px;font-size:12px;font-weight:600;display:flex}.omcBaG_messageRow[data-human] .omcBaG_messageIdentity{background:var(--dsw-alias-state-business-primary)}.omcBaG_messageRow[data-grouped] .omcBaG_messageIdentity{visibility:hidden}.omcBaG_messageBody{min-width:0}.omcBaG_nameRow{flex-wrap:wrap;align-items:baseline;gap:8px;display:flex}.omcBaG_nameRow strong{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600;line-height:20px}.omcBaG_messageTime{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:20px}.omcBaG_messageText{white-space:pre-wrap;word-break:break-word;margin:6px 0;font-size:14px;line-height:22px}.omcBaG_messageClamp{max-height:176px;overflow:hidden;-webkit-mask-image:linear-gradient(#000 72%,#0000 100%);mask-image:linear-gradient(#000 72%,#0000 100%)}.omcBaG_messageExpand{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;width:fit-content;margin-top:4px;padding:0;font-size:12px;line-height:20px;display:block}.omcBaG_messageExpand:hover,.omcBaG_messageExpand:focus-visible{color:var(--dsw-alias-label-primary);text-underline-offset:2px;outline:none;text-decoration:underline}.omcBaG_messageBody .omcBaG_messageMarkdown{font-size:14px;line-height:22px}.omcBaG_messageBody .omcBaG_messageMarkdown>div:first-child{color:var(--dsw-alias-label-primary);font:inherit}.omcBaG_messageBody .omcBaG_messageMarkdown p{margin:6px 0}.omcBaG_messageBody .omcBaG_messageMarkdown :where(ul,ol){margin:6px 0;padding-left:22px}.omcBaG_messageBody .omcBaG_messageMarkdown li+li{margin-top:2px}.omcBaG_messageBody .omcBaG_messageMarkdown strong{font-weight:600}.omcBaG_messageBody .omcBaG_messageMarkdown :where(h1,h2,h3,h4,h5,h6){margin:12px 0 4px}.omcBaG_messageBody .omcBaG_messageMarkdown :where(h1){font-size:17px;line-height:26px}.omcBaG_messageBody .omcBaG_messageMarkdown :where(h2){font-size:16px;line-height:24px}.omcBaG_messageBody .omcBaG_messageMarkdown :where(h3,h4,h5,h6){font-size:15px;line-height:22px}.omcBaG_messageBody .omcBaG_messageMarkdown pre{margin:8px 0;padding:10px 12px;font-size:13px}.omcBaG_messageBody .omcBaG_messageMarkdown blockquote{margin:6px 0}.omcBaG_messageBody .omcBaG_messageMarkdown :where(th,td){padding-block:5px}.omcBaG_emptyState,.omcBaG_loadingState{color:var(--dsw-alias-label-tertiary);margin:0;padding:14px 0;font-size:13px;line-height:20px}.omcBaG_emptyState{gap:3px;display:grid}.omcBaG_emptyState strong{color:var(--dsw-alias-label-secondary);font-weight:500}.omcBaG_emptyState span{font-size:12px}.omcBaG_loadingState{align-items:center;gap:8px;display:flex}.omcBaG_loadingMark{background:var(--dsw-alias-bg-skeleton);border-radius:50%;width:8px;height:8px;animation:1.2s ease-in-out infinite omcBaG_pulse}.omcBaG_error,.omcBaG_errorState{color:var(--dsw-alias-state-error-primary);max-width:880px;margin:0 auto;padding-top:6px;font-size:12px;line-height:18px}.omcBaG_errorState{justify-content:space-between;align-items:center;gap:8px;display:flex}.omcBaG_welcomeSurface{justify-content:center;align-items:center;min-width:0;height:100%;padding:32px;display:flex}.omcBaG_welcome{text-align:center;max-width:420px}.omcBaG_welcomeEyebrow{color:var(--dsw-alias-label-tertiary);text-transform:uppercase;font-size:12px;line-height:18px}.omcBaG_welcome h1{color:var(--dsw-alias-label-primary);margin:8px 0;font-size:24px;font-weight:600;line-height:32px}.omcBaG_welcome p{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px;line-height:20px}@keyframes omcBaG_pulse{0%,to{opacity:.35}50%{opacity:1}}@media (width<=600px){.omcBaG_surfaceHeader{padding:12px 12px 10px}.omcBaG_headerRow{flex-direction:column;align-items:stretch;gap:8px}.omcBaG_headerActions{flex-wrap:wrap}.omcBaG_backRow{margin-bottom:6px}.omcBaG_timeline{scrollbar-gutter:auto;padding:8px 12px 16px}.omcBaG_messageRow{padding:8px 0}}@media (prefers-reduced-motion:reduce){.omcBaG_loadingMark{animation:none}}.omcBaG_messageRun{margin:2px 0;padding:3px 0}.omcBaG_messageRow[data-grouped]:has(.omcBaG_messageBody>button:not([data-message-expand])){margin-top:3px;padding-top:7px;position:relative}.omcBaG_messageRow[data-grouped]:has(.omcBaG_messageBody>button:not([data-message-expand])):before{background:var(--dsw-alias-border-l2);content:\"\";height:1px;position:absolute;inset:0 0 auto 38px}.omcBaG_runDivider{border-top:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);margin:2px 0 0 38px;padding:5px 0 0;font-size:11px;line-height:16px}.omcBaG_runDivider+.omcBaG_messageRow[data-grouped]:has(.omcBaG_messageBody>button:not([data-message-expand])){margin-top:0}.omcBaG_runDivider+.omcBaG_messageRow[data-grouped]:has(.omcBaG_messageBody>button:not([data-message-expand])):before{content:none}.omcBaG_mention{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 12%, transparent);color:var(--dsw-alias-state-business-primary);border-radius:5px;padding:0 4px;font-weight:500;box-shadow:0 1px 2px #00000014}.omcBaG_mentionsRow{gap:4px;width:fit-content;margin-top:3px;font-size:.85em;display:flex}.omcBaG_attachmentStrip{flex-wrap:wrap;gap:6px;margin-top:4px;display:flex}.omcBaG_attachmentThumb{cursor:zoom-in;border:0;border-radius:8px;padding:0}.omcBaG_attachmentThumb img{object-fit:cover;border-radius:8px;width:128px;height:96px;display:block}.omcBaG_attachmentThumb:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,currentColor);outline-offset:1px}.omcBaG_confirmBody{margin:0 0 8px}.omcBaG_confirmList{gap:6px;margin:0;padding-left:18px;display:grid}.omcBaG_refLink{color:var(--dsw-alias-state-business-primary);cursor:pointer;font:inherit;text-align:left;text-underline-offset:3px;background:0 0;border:none;border-radius:4px;padding:0;text-decoration:underline}.omcBaG_refLink:hover{text-decoration-thickness:2px}.omcBaG_refLink:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}.omcBaG_attachmentModal{width:min(1100px,92vw)}.omcBaG_attachmentZoom{object-fit:contain;border-radius:12px;max-width:100%;max-height:78vh;margin:0 auto;display:block}.omcBaG_attachmentChip{background:var(--dsw-alias-interactive-bg-hover);border-radius:6px;align-items:baseline;gap:6px;max-width:100%;padding:3px 8px;display:inline-flex}.omcBaG_attachmentChipName{text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:17px;overflow:hidden}.omcBaG_attachmentChipSize{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:11px;line-height:17px}";
6958
7159
  const tagId$4 = "@wowyuarm/dsh-agent-team/conversation.module.css";
6959
7160
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
6960
7161
  const tag = document.createElement("style");
@@ -6986,6 +7187,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6986
7187
  "mention": "omcBaG_mention",
6987
7188
  "mentionsRow": "omcBaG_mentionsRow",
6988
7189
  "messageBody": "omcBaG_messageBody",
7190
+ "messageClamp": "omcBaG_messageClamp",
7191
+ "messageExpand": "omcBaG_messageExpand",
6989
7192
  "messageIdentity": "omcBaG_messageIdentity",
6990
7193
  "messageMarkdown": "omcBaG_messageMarkdown",
6991
7194
  "messageRow": "omcBaG_messageRow",
@@ -7008,15 +7211,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7008
7211
  //#endregion
7009
7212
  //#region src/client/TeamMessage.tsx
7010
7213
  /** One chat message row with identity chrome and sender-appropriate rendering. */
7011
- function TeamMessage({ senderName, memberId, human, body, occurredAt, mentionNames, senderTitle, grouped, attachments, loadAttachment, t, onOpenRef, onResolveTaskRefs, children }) {
7214
+ function TeamMessage({ senderName, memberId, human, body, occurredAt, mentionNames, senderTitle, grouped, showGroupedTime, attachments, loadAttachment, t, onOpenRef, onResolveTaskRefs, children }) {
7012
7215
  const avatarStyle = human ? void 0 : { "--team-avatar-hue": memberHue(memberId) };
7013
- const displayBody = stripAttachmentLines(body) === "" ? body : stripAttachmentLines(body);
7014
- const inline = (human || isPlainTextBody(displayBody)) && mentionNames !== void 0 && mentionNames.length > 0 ? splitMentionNames(displayBody, mentionNames) : void 0;
7015
- const fallbackNames = inline === void 0 ? mentionNames ?? [] : inline.unmatched;
7016
- const richAgentBody = !human && !isPlainTextBody(displayBody);
7017
- const fallbackRefs = richAgentBody && onOpenRef !== void 0 ? splitBrandedRefs(displayBody).filter((segment) => segment.ref !== void 0 && !segment.ref.startsWith("task:")).map((segment) => segment.ref) : [];
7216
+ const plan = planMessageBody(body, {
7217
+ human,
7218
+ ...mentionNames === void 0 ? {} : { mentionNames },
7219
+ canOpenRefs: onOpenRef !== void 0
7220
+ });
7221
+ const displayBody = plan.displayBody;
7222
+ const { richAgentBody } = plan;
7018
7223
  const refVersion = useResolvedTaskRefVersion();
7019
- const bodyTaskRefs = onOpenRef === void 0 || richAgentBody ? [] : splitBrandedRefs(displayBody).filter((segment) => segment.ref !== void 0 && segment.ref.startsWith("task:")).map((segment) => segment.ref);
7224
+ const bodyTaskRefs = plan.taskRefs;
7020
7225
  const bodyTaskRefKey = bodyTaskRefs.join(",");
7021
7226
  (0, react.useEffect)(() => {
7022
7227
  if (onResolveTaskRefs === void 0 || bodyTaskRefKey === "") return;
@@ -7027,14 +7232,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7027
7232
  refVersion
7028
7233
  ]);
7029
7234
  const taskLabel = (0, react.useCallback)((taskNumber) => t?.("taskLabel", { number: taskNumber }) ?? `Task #${taskNumber}`, [t]);
7235
+ const [expanded, setExpanded] = (0, react.useState)(false);
7236
+ const clampable = shouldClampMessage(displayBody);
7237
+ const clamped = clampable && !expanded;
7030
7238
  const markdownRef = (0, react.useRef)(null);
7031
7239
  (0, react.useLayoutEffect)(() => {
7032
7240
  const root = markdownRef.current;
7033
7241
  if (!richAgentBody || root === null || onOpenRef === void 0) return;
7034
7242
  const textNodes = markdownProseTextNodes(root);
7035
- const taskRefs = [...new Set(textNodes.flatMap((node) => splitBrandedRefs(node.data).filter((segment) => segment.ref?.startsWith("task:") === true).map((segment) => segment.ref)))];
7243
+ const styledRefCodes = markdownStyledRefCodeElements(root);
7244
+ const taskRefs = [...new Set([...textNodes.map((node) => node.data), ...styledRefCodes.map((code) => code.textContent ?? "")].flatMap((text) => splitBrandedRefs(text).filter((segment) => segment.ref?.startsWith("task:") === true).map((segment) => segment.ref)))];
7036
7245
  if (onResolveTaskRefs !== void 0 && taskRefs.length > 0) resolveUnknownTaskRefs(taskRefs, onResolveTaskRefs);
7037
- for (const node of textNodes) renderResolvedMarkdownTaskRefs(node, taskLabel);
7246
+ for (const code of styledRefCodes) renderResolvedMarkdownCodeRef(code, taskLabel);
7247
+ for (const node of textNodes) renderResolvedMarkdownText(node, mentionNames ?? [], taskLabel);
7038
7248
  for (const button of root.querySelectorAll("button[data-task-ref]")) {
7039
7249
  const taskRef = button.dataset.taskRef;
7040
7250
  const hit = taskRef === void 0 ? void 0 : cachedResolvedTaskRef(taskRef);
@@ -7045,7 +7255,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7045
7255
  onOpenRef,
7046
7256
  onResolveTaskRefs,
7047
7257
  refVersion,
7048
- taskLabel
7258
+ taskLabel,
7259
+ mentionNames
7049
7260
  ]);
7050
7261
  (0, react.useEffect)(() => {
7051
7262
  const root = markdownRef.current;
@@ -7063,6 +7274,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7063
7274
  root.removeEventListener("click", openTask);
7064
7275
  };
7065
7276
  }, [richAgentBody, onOpenRef]);
7277
+ const bodyNode = plan.render === "inline" && plan.inline !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7278
+ className: conversation_module_css_default.messageText,
7279
+ children: plan.inline.segments.map((segment, index) => segment.mention ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7280
+ className: conversation_module_css_default.mention,
7281
+ children: segment.text
7282
+ }, index) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderRefs(segment.text, onOpenRef, taskLabel) }, index))
7283
+ }) : plan.render === "literal" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7284
+ className: conversation_module_css_default.messageText,
7285
+ children: onOpenRef === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MessageText, { text: displayBody }) : renderRefs(displayBody, onOpenRef, taskLabel)
7286
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7287
+ ref: markdownRef,
7288
+ className: conversation_module_css_default.messageMarkdown,
7289
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, { text: displayBody }, `${displayBody}:${onOpenRef === void 0 ? "literal" : "refs"}`)
7290
+ });
7066
7291
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
7067
7292
  className: conversation_module_css_default.messageRow,
7068
7293
  "data-human": human || void 0,
@@ -7075,9 +7300,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7075
7300
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7076
7301
  className: conversation_module_css_default.messageBody,
7077
7302
  children: [
7078
- !grouped && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7303
+ (!grouped || showGroupedTime === true) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7079
7304
  className: conversation_module_css_default.nameRow,
7080
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
7305
+ children: [!grouped && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
7081
7306
  ...senderTitle === void 0 ? {} : { title: senderTitle },
7082
7307
  children: senderName
7083
7308
  }), occurredAt !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -7085,26 +7310,26 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7085
7310
  children: formatMessageTime(occurredAt)
7086
7311
  })]
7087
7312
  }),
7088
- inline !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7089
- className: conversation_module_css_default.messageText,
7090
- children: inline.segments.map((segment, index) => segment.mention ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7091
- className: conversation_module_css_default.mention,
7092
- children: segment.text
7093
- }, index) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderRefs(segment.text, onOpenRef, taskLabel) }, index))
7094
- }) : human || onOpenRef !== void 0 && isPlainTextBody(displayBody) && splitBrandedRefs(displayBody).some((segment) => segment.ref !== void 0) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7095
- className: conversation_module_css_default.messageText,
7096
- children: onOpenRef === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MessageText, { text: displayBody }) : renderRefs(displayBody, onOpenRef, taskLabel)
7097
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7098
- ref: markdownRef,
7099
- className: conversation_module_css_default.messageMarkdown,
7100
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, { text: displayBody }, `${displayBody}:${onOpenRef === void 0 ? "literal" : "refs"}`)
7313
+ clampable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7314
+ className: clamped ? conversation_module_css_default.messageClamp : void 0,
7315
+ children: bodyNode
7316
+ }) : bodyNode,
7317
+ clampable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7318
+ type: "button",
7319
+ className: conversation_module_css_default.messageExpand,
7320
+ "data-message-expand": "true",
7321
+ "aria-expanded": expanded,
7322
+ onClick: () => {
7323
+ setExpanded((value) => !value);
7324
+ },
7325
+ children: expanded ? t?.("collapseMessage") ?? "Show less" : t?.("expandMessage") ?? "Show more"
7101
7326
  }),
7102
- (fallbackNames.length > 0 || fallbackRefs.length > 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7327
+ (plan.fallbackNames.length > 0 || plan.fallbackRefs.length > 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7103
7328
  className: conversation_module_css_default.mentionsRow,
7104
- children: [fallbackNames.map((name) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7329
+ children: [plan.fallbackNames.map((name) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7105
7330
  className: conversation_module_css_default.mention,
7106
7331
  children: ["@", name]
7107
- }, name)), fallbackRefs.map((ref) => {
7332
+ }, name)), plan.fallbackRefs.map((ref) => {
7108
7333
  const resolved = cachedResolvedTaskRef(ref);
7109
7334
  const label = resolved !== void 0 && ref.startsWith("task:") ? taskLabel(resolved.taskNumber) : ref;
7110
7335
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
@@ -7134,35 +7359,71 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7134
7359
  const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
7135
7360
  for (let node = walker.nextNode(); node !== null; node = walker.nextNode()) {
7136
7361
  const parent = node.parentElement;
7137
- if (parent !== null && parent.closest("code, pre, a, button") === null) nodes.push(node);
7362
+ if (parent === null) continue;
7363
+ if (parent.closest("code, pre, a, button") !== null) continue;
7364
+ if (conversation_module_css_default.mention !== void 0 && parent.closest(`[class~="${conversation_module_css_default.mention}"]`) !== null) continue;
7365
+ nodes.push(node);
7138
7366
  }
7139
7367
  return nodes;
7140
7368
  }
7141
- /** Replace resolved refs in one prose text node without changing Markdown structure. */
7142
- function renderResolvedMarkdownTaskRefs(node, taskLabel) {
7143
- const segments = splitBrandedRefs(node.data);
7144
- if (!segments.some((segment) => segment.ref?.startsWith("task:") === true && cachedResolvedTaskRef(segment.ref) !== void 0)) return;
7369
+ /** Code spans whose entire content is one branded ref: model styling around a ref, not code. */
7370
+ function markdownStyledRefCodeElements(root) {
7371
+ const elements = [];
7372
+ for (const code of root.querySelectorAll("code")) {
7373
+ if (code.closest("pre, a, button") !== null) continue;
7374
+ if (!isSingleBrandedRef(code.textContent ?? "")) continue;
7375
+ elements.push(code);
7376
+ }
7377
+ return elements;
7378
+ }
7379
+ /** One resolved Task-ref chip built outside React, matching the styled ref link. */
7380
+ function resolvedTaskRefButton(taskRef, label) {
7381
+ const button = document.createElement("button");
7382
+ button.type = "button";
7383
+ if (conversation_module_css_default.refLink !== void 0) button.className = conversation_module_css_default.refLink;
7384
+ button.dataset.taskRef = taskRef;
7385
+ button.title = taskRef;
7386
+ button.textContent = label;
7387
+ return button;
7388
+ }
7389
+ /** Replace a whole-ref code span with its resolved Task chip once known. */
7390
+ function renderResolvedMarkdownCodeRef(code, taskLabel) {
7391
+ const segments = splitBrandedRefs((code.textContent ?? "").trim());
7392
+ const segment = segments.length === 1 ? segments[0] : void 0;
7393
+ const taskRef = segment?.ref?.startsWith("task:") === true ? segment.ref : void 0;
7394
+ const resolved = taskRef === void 0 ? void 0 : cachedResolvedTaskRef(taskRef);
7395
+ if (taskRef === void 0 || resolved === void 0) return;
7396
+ code.replaceWith(resolvedTaskRefButton(taskRef, taskLabel(resolved.taskNumber)));
7397
+ }
7398
+ /** Replace resolved Task refs and structured mention handles in one prose text node without changing Markdown structure. */
7399
+ function renderResolvedMarkdownText(node, mentionNames, taskLabel) {
7400
+ let changed = false;
7145
7401
  const fragment = document.createDocumentFragment();
7146
- for (const segment of segments) {
7147
- const taskRef = segment.ref?.startsWith("task:") === true ? segment.ref : void 0;
7148
- if (taskRef === void 0) {
7149
- fragment.append(segment.text);
7402
+ for (const refSegment of splitBrandedRefs(node.data)) {
7403
+ if (refSegment.ref === void 0) {
7404
+ for (const mentionSegment of splitMentionNames(refSegment.text, mentionNames).segments) {
7405
+ if (!mentionSegment.mention) {
7406
+ fragment.append(mentionSegment.text);
7407
+ continue;
7408
+ }
7409
+ changed = true;
7410
+ const chip = document.createElement("span");
7411
+ if (conversation_module_css_default.mention !== void 0) chip.className = conversation_module_css_default.mention;
7412
+ chip.textContent = mentionSegment.text;
7413
+ fragment.append(chip);
7414
+ }
7150
7415
  continue;
7151
7416
  }
7152
- const resolved = cachedResolvedTaskRef(taskRef);
7417
+ const taskRef = refSegment.ref.startsWith("task:") === true ? refSegment.ref : void 0;
7418
+ const resolved = taskRef === void 0 ? void 0 : cachedResolvedTaskRef(taskRef);
7153
7419
  if (resolved === void 0) {
7154
- fragment.append(segment.text);
7420
+ fragment.append(refSegment.text);
7155
7421
  continue;
7156
7422
  }
7157
- const button = document.createElement("button");
7158
- button.type = "button";
7159
- if (conversation_module_css_default.refLink !== void 0) button.className = conversation_module_css_default.refLink;
7160
- button.dataset.taskRef = taskRef;
7161
- button.title = taskRef;
7162
- button.textContent = taskLabel(resolved.taskNumber);
7163
- fragment.append(button);
7423
+ changed = true;
7424
+ fragment.append(resolvedTaskRefButton(taskRef, taskLabel(resolved.taskNumber)));
7164
7425
  }
7165
- node.replaceWith(fragment);
7426
+ if (changed) node.replaceWith(fragment);
7166
7427
  }
7167
7428
  /** Render one literal text run, linkifying branded refs when navigation is available. */
7168
7429
  function renderRefs(text, onOpenRef, taskLabel) {
@@ -7290,7 +7551,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7290
7551
  return next;
7291
7552
  });
7292
7553
  const key = `${membership.joined ? "remove" : "join"}:${membership.memberId}:${membership.channelRef}`;
7293
- const requestId = requestIds.current.get(key) ?? crypto.randomUUID();
7554
+ const requestId = requestIds.current.get(key) ?? mintRequestId();
7294
7555
  requestIds.current.set(key, requestId);
7295
7556
  const request = {
7296
7557
  requestId,
@@ -7446,7 +7707,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7446
7707
  }
7447
7708
  //#endregion
7448
7709
  //#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/channel.module.css.mjs
7449
- const css$3 = ".MYaRJa_headerMeta{color:var(--dsw-alias-label-tertiary);flex-wrap:wrap;align-items:center;gap:6px;margin-top:7px;font-size:12px;line-height:18px;display:flex}.MYaRJa_headerMeta span+span:before{content:\"·\";margin-right:6px}.MYaRJa_taskFooter{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);cursor:pointer;text-align:left;background:0 0;border-radius:999px;align-items:center;gap:6px;max-width:100%;margin:6px 0 0;padding:2px 10px;transition:background-color .12s,border-color .12s,color .12s;display:inline-flex}.MYaRJa_taskFooter:hover,.MYaRJa_taskFooter:focus-visible{background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-l3);color:var(--dsw-alias-label-primary)}.MYaRJa_taskFooter:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.MYaRJa_taskNumber{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:600;line-height:18px}.MYaRJa_taskStatus,.MYaRJa_taskCount{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:18px}.MYaRJa_taskDot{flex:none;align-items:center;width:8px;display:inline-flex}.MYaRJa_taskDotQuiet{border-radius:50%;flex:none;width:8px;height:8px;position:relative}.MYaRJa_taskDotQuiet[data-variant=todo]{border:1px solid var(--dsw-alias-label-tertiary)}.MYaRJa_taskDotQuiet[data-variant=closed]{color:var(--dsw-alias-label-tertiary)}.MYaRJa_taskDotQuiet[data-variant=closed]:before{content:\"\";opacity:.1;background:currentColor;border-radius:50%;position:absolute;inset:0}.MYaRJa_taskDotQuiet[data-variant=closed]:after{content:\"\";background:currentColor;border-radius:50%;position:absolute;inset:20%}.MYaRJa_taskArrow{color:var(--dsw-alias-label-tertiary);align-items:center;transition:transform .12s;display:inline-flex}.MYaRJa_taskFooter:hover .MYaRJa_taskArrow,.MYaRJa_taskFooter:focus-visible .MYaRJa_taskArrow{transform:translate(2px)}.MYaRJa_memberList{gap:3px;display:grid}.MYaRJa_memberRow{border-radius:6px;grid-template-columns:14px minmax(0,1fr) auto;align-items:center;gap:0 8px;min-height:40px;padding:4px 6px;display:grid}.MYaRJa_memberRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.MYaRJa_memberCopy{min-width:0;display:grid}.MYaRJa_memberCopy strong{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:500;line-height:18px;overflow:hidden}.MYaRJa_memberCopy small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:14px;overflow:hidden}.MYaRJa_memberAction{min-width:60px}.MYaRJa_memberError{color:var(--dsw-alias-state-error-primary);grid-column:2/-1;margin:2px 0;font-size:11px;line-height:16px}.MYaRJa_modalBody{max-height:min(65vh,520px);overflow-y:auto}@media (width<=600px){.MYaRJa_headerMeta span+span:before{display:none}.MYaRJa_memberRow{grid-template-columns:14px minmax(0,1fr)}.MYaRJa_memberAction{grid-column:2;justify-self:start;margin-top:3px}}@media (prefers-reduced-motion:reduce){.MYaRJa_taskFooter,.MYaRJa_taskArrow{transition:none}.MYaRJa_taskFooter:hover .MYaRJa_taskArrow,.MYaRJa_taskFooter:focus-visible .MYaRJa_taskArrow{transform:none}}";
7710
+ const css$3 = ".MYaRJa_headerMeta{color:var(--dsw-alias-label-tertiary);flex-wrap:wrap;align-items:center;gap:6px;margin-top:7px;font-size:12px;line-height:18px;display:flex}.MYaRJa_headerMeta span+span:before{content:\"·\";margin-right:6px}.MYaRJa_taskFooter{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);cursor:pointer;text-align:left;background:0 0;border-radius:999px;align-items:center;gap:6px;max-width:100%;margin:6px 0 0;padding:2px 10px;transition:background-color .12s,border-color .12s,color .12s;display:inline-flex}.MYaRJa_taskFooter:hover,.MYaRJa_taskFooter:focus-visible{background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-l3);color:var(--dsw-alias-label-primary)}.MYaRJa_taskFooter:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.MYaRJa_taskNumber{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:600;line-height:18px}.MYaRJa_taskStatus,.MYaRJa_taskCount{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:18px}.MYaRJa_taskDot{flex:none;align-items:center;width:8px;display:inline-flex}.MYaRJa_taskDotQuiet{border-radius:50%;flex:none;width:8px;height:8px;position:relative}.MYaRJa_taskDotQuiet[data-variant=todo]{border:1px solid var(--dsw-alias-label-tertiary)}.MYaRJa_taskDotQuiet[data-variant=closed]{color:var(--dsw-alias-label-tertiary)}.MYaRJa_taskDotQuiet[data-variant=closed]:before{content:\"\";opacity:.1;background:currentColor;border-radius:50%;position:absolute;inset:0}.MYaRJa_taskDotQuiet[data-variant=closed]:after{content:\"\";background:currentColor;border-radius:50%;position:absolute;inset:20%}.MYaRJa_taskArrow{color:var(--dsw-alias-label-tertiary);align-items:center;transition:transform .12s;display:inline-flex}.MYaRJa_taskFooter:hover .MYaRJa_taskArrow,.MYaRJa_taskFooter:focus-visible .MYaRJa_taskArrow{transform:translate(2px)}.MYaRJa_memberList{gap:3px;display:grid}.MYaRJa_memberRow{border-radius:6px;grid-template-columns:14px minmax(0,1fr) auto;align-items:center;gap:0 8px;min-height:40px;padding:4px 6px;display:grid}.MYaRJa_memberRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.MYaRJa_memberCopy{min-width:0;display:grid}.MYaRJa_memberCopy strong{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:500;line-height:18px;overflow:hidden}.MYaRJa_memberCopy small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:14px;overflow:hidden}.MYaRJa_memberAction{min-width:60px}.MYaRJa_memberError{color:var(--dsw-alias-state-error-primary);grid-column:2/-1;margin:2px 0;font-size:11px;line-height:16px}.MYaRJa_modalBody{max-height:min(65vh,520px);overflow-y:auto}@media (width<=600px){.MYaRJa_memberRow{grid-template-columns:14px minmax(0,1fr)}.MYaRJa_memberAction{grid-column:2;justify-self:start;margin-top:3px}}@media (prefers-reduced-motion:reduce){.MYaRJa_taskFooter,.MYaRJa_taskArrow{transition:none}.MYaRJa_taskFooter:hover .MYaRJa_taskArrow,.MYaRJa_taskFooter:focus-visible .MYaRJa_taskArrow{transform:none}}";
7450
7711
  const tagId$3 = "@wowyuarm/dsh-agent-team/channel.module.css";
7451
7712
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
7452
7713
  const tag = document.createElement("style");
@@ -7473,7 +7734,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7473
7734
  };
7474
7735
  //#endregion
7475
7736
  //#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/thread.module.css.mjs
7476
- const css$2 = ".-Qiwua_titleLine{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.-Qiwua_titleLine h1{margin:0}.-Qiwua_workSection{border-top:1px solid var(--dsw-alias-border-l2);max-width:880px;margin:12px auto 0;padding-top:8px}.-Qiwua_riskSection{border-top:1px solid var(--dsw-alias-border-l2);max-width:880px;margin:12px auto 0;padding-top:10px}.-Qiwua_riskSection h2{color:var(--dsw-alias-state-error-primary);margin:0 0 5px;font-size:12px;font-weight:600;line-height:18px}.-Qiwua_riskRow{color:var(--dsw-alias-label-secondary);align-items:center;gap:8px;margin:3px 0;font-size:12px;line-height:18px;display:flex}.-Qiwua_claimList{gap:4px;padding:4px 0 2px 22px;display:grid}.-Qiwua_claimRow{border-radius:6px;grid-template-columns:14px minmax(96px,auto) minmax(0,1fr) auto auto;align-items:center;gap:4px 8px;min-height:36px;padding:4px 6px;display:grid}.-Qiwua_claimRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.-Qiwua_claimOwner{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;font-weight:500;line-height:18px;overflow:hidden}.-Qiwua_claimDirection{color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;min-width:0;font-size:12px;line-height:18px}.-Qiwua_claimState{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:11px;line-height:18px}.-Qiwua_emptyClaims{color:var(--dsw-alias-label-tertiary);margin:0;padding:5px 6px;font-size:11px;line-height:18px}.-Qiwua_activityRow{color:var(--dsw-alias-label-tertiary);text-align:center;justify-content:center;align-items:center;gap:8px;max-width:100%;margin:4px auto;padding:5px 12px;font-size:11px;line-height:18px;display:flex}.-Qiwua_activityText{overflow-wrap:anywhere;min-width:0}.-Qiwua_activityMark{background:var(--dsw-alias-border-l3);border-radius:50%;flex:0 0 5px;width:5px;height:5px}.-Qiwua_historySection{border-bottom:1px solid var(--dsw-alias-border-l2);max-width:100%;margin:0 auto 12px;padding-bottom:10px}.-Qiwua_historySection h2{color:var(--dsw-alias-label-tertiary);letter-spacing:.02em;text-transform:uppercase;margin:0 0 4px;font-size:11px;font-weight:600;line-height:16px}.-Qiwua_publicSection{min-width:0}.-Qiwua_unreadBoundary{color:var(--dsw-alias-label-tertiary);align-items:center;gap:10px;margin:10px 0 6px;font-size:11px;line-height:16px;display:flex}.-Qiwua_unreadBoundary:before,.-Qiwua_unreadBoundary:after{background:var(--dsw-alias-border-l3);content:\"\";flex:1;height:1px}.-Qiwua_unreadBoundary span{flex:none}.-Qiwua_daySeparator{color:var(--dsw-alias-label-tertiary);letter-spacing:.02em;align-items:center;gap:10px;margin:12px 0 4px;font-size:11px;line-height:16px;display:flex}.-Qiwua_daySeparator:before,.-Qiwua_daySeparator:after{background:var(--dsw-alias-border-l2);content:\"\";flex:1;height:1px}.-Qiwua_daySeparator span{flex:none}.-Qiwua_newUpdates{background:var(--dsw-specific-input-major,var(--dsw-alias-bg-layer-1));border:1px solid var(--dsw-alias-border-l2-darkmode-thin);box-shadow:var(--dsw-shadow-lv2);color:var(--dsw-alias-label-secondary);z-index:2;border-radius:999px;justify-content:center;align-items:center;gap:8px;width:fit-content;margin:8px auto;padding:4px 6px 4px 12px;font-size:12px;line-height:18px;display:flex;position:sticky;bottom:8px}.-Qiwua_taskTitle{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;margin:2px 0 0;font-size:13px;line-height:20px;overflow:hidden}.-Qiwua_closedBar{flex-direction:column;align-items:center;display:flex}.-Qiwua_closedNotice{color:var(--dsw-alias-label-tertiary);flex-wrap:wrap;justify-content:center;align-items:center;gap:12px;padding:10px 16px 14px;font-size:13px;line-height:20px;display:flex}@media (width<=600px){.-Qiwua_claimRow{grid-template-columns:14px minmax(0,1fr) auto;align-items:start}.-Qiwua_claimDirection{grid-column:2/-1}.-Qiwua_activityRow{padding-inline:0}.-Qiwua_newUpdates{max-width:calc(100% - 16px)}}";
7737
+ const css$2 = ".-Qiwua_titleLine{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.-Qiwua_titleLine h1{margin:0}.-Qiwua_workSection{border-top:1px solid var(--dsw-alias-border-l2);max-width:880px;margin:12px auto 0;padding-top:8px}.-Qiwua_riskSection{border-top:1px solid var(--dsw-alias-border-l2);max-width:880px;margin:12px auto 0;padding-top:10px}.-Qiwua_riskSection h2{color:var(--dsw-alias-state-error-primary);margin:0 0 5px;font-size:12px;font-weight:600;line-height:18px}.-Qiwua_riskRow{color:var(--dsw-alias-label-secondary);align-items:center;gap:8px;margin:3px 0;font-size:12px;line-height:18px;display:flex}.-Qiwua_claimList{gap:4px;padding:4px 0 2px 22px;display:grid}.-Qiwua_claimRow{border-radius:6px;grid-template-columns:14px minmax(96px,auto) minmax(0,1fr) auto auto;align-items:center;gap:4px 8px;min-height:36px;padding:4px 6px;display:grid}.-Qiwua_claimRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.-Qiwua_claimOwner{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;font-weight:500;line-height:18px;overflow:hidden}.-Qiwua_claimDirection{color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;min-width:0;font-size:12px;line-height:18px}.-Qiwua_claimState{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:11px;line-height:18px}.-Qiwua_emptyClaims{color:var(--dsw-alias-label-tertiary);margin:0;padding:5px 6px;font-size:11px;line-height:18px}.-Qiwua_activityRow{color:var(--dsw-alias-label-tertiary);text-align:center;justify-content:center;align-items:center;gap:8px;max-width:100%;margin:4px auto;padding:5px 12px;font-size:11px;line-height:18px;display:flex}.-Qiwua_activityText{overflow-wrap:anywhere;min-width:0}.-Qiwua_activityMark{background:var(--dsw-alias-border-l3);border-radius:50%;flex:0 0 5px;width:5px;height:5px}.-Qiwua_activityRow:has(+.-Qiwua_activityRow),.-Qiwua_activityRow+.-Qiwua_activityRow{text-align:left;justify-content:flex-start;padding-left:38px}.-Qiwua_historySection{border-bottom:1px solid var(--dsw-alias-border-l2);max-width:100%;margin:0 auto 12px;padding-bottom:10px}.-Qiwua_historySection h2{color:var(--dsw-alias-label-tertiary);letter-spacing:.02em;text-transform:uppercase;margin:0 0 4px;font-size:11px;font-weight:600;line-height:16px}.-Qiwua_publicSection{min-width:0}.-Qiwua_unreadBoundary{color:var(--dsw-alias-label-tertiary);align-items:center;gap:10px;margin:10px 0 6px;font-size:11px;line-height:16px;display:flex}.-Qiwua_unreadBoundary:before,.-Qiwua_unreadBoundary:after{background:var(--dsw-alias-border-l3);content:\"\";flex:1;height:1px}.-Qiwua_unreadBoundary span{flex:none}.-Qiwua_daySeparator{color:var(--dsw-alias-label-tertiary);letter-spacing:.02em;align-items:center;gap:10px;margin:12px 0 4px;font-size:11px;line-height:16px;display:flex}.-Qiwua_daySeparator:before,.-Qiwua_daySeparator:after{background:var(--dsw-alias-border-l2);content:\"\";flex:1;height:1px}.-Qiwua_daySeparator span{flex:none}.-Qiwua_newUpdates{background:var(--dsw-specific-input-major,var(--dsw-alias-bg-layer-1));border:1px solid var(--dsw-alias-border-l2-darkmode-thin);box-shadow:var(--dsw-shadow-lv2);color:var(--dsw-alias-label-secondary);z-index:2;border-radius:999px;justify-content:center;align-items:center;gap:8px;width:fit-content;margin:8px auto;padding:4px 6px 4px 12px;font-size:12px;line-height:18px;display:flex;position:sticky;bottom:8px}.-Qiwua_taskTitle{color:var(--dsw-alias-label-secondary);-webkit-line-clamp:2;overflow-wrap:anywhere;-webkit-box-orient:vertical;margin:2px 0 0;font-size:13px;line-height:20px;display:-webkit-box;overflow:hidden}.-Qiwua_closedBar{flex-direction:column;align-items:center;display:flex}.-Qiwua_closedNotice{color:var(--dsw-alias-label-tertiary);flex-wrap:wrap;justify-content:center;align-items:center;gap:12px;padding:10px 16px 14px;font-size:13px;line-height:20px;display:flex}@media (width<=600px){.-Qiwua_claimRow{grid-template-columns:14px minmax(0,1fr) auto;align-items:start}.-Qiwua_claimState{grid-area:1/3;justify-self:end}.-Qiwua_claimDirection{grid-column:2/-1}.-Qiwua_activityRow{padding-inline:0}.-Qiwua_newUpdates{max-width:calc(100% - 16px)}}";
7477
7738
  const tagId$2 = "@wowyuarm/dsh-agent-team/thread.module.css";
7478
7739
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
7479
7740
  const tag = document.createElement("style");
@@ -7529,6 +7790,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7529
7790
  const [statusMessage, setStatusMessage] = (0, react.useState)();
7530
7791
  const [loading, setLoading] = (0, react.useState)(true);
7531
7792
  const [pending, setPending] = (0, react.useState)(false);
7793
+ const [asTask, setAsTask] = (0, react.useState)(false);
7532
7794
  const [loadingOlder, setLoadingOlder] = (0, react.useState)(false);
7533
7795
  const [managingMembers, setManagingMembers] = (0, react.useState)(false);
7534
7796
  const draftKey = `channel:${channelRef}`;
@@ -7544,29 +7806,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7544
7806
  return;
7545
7807
  }
7546
7808
  if (ref.startsWith("task:")) {
7547
- const match = view?.items.find((item) => item.task.taskRef === ref);
7809
+ const match = view?.items.find((item) => item.task?.taskRef === ref);
7548
7810
  if (match !== void 0) {
7549
- selectThread(match.task.taskRef, match.thread.threadRef, channelRef, match.taskNumber);
7811
+ selectThread(match.thread.threadRef, channelRef, match.task?.taskRef, match.taskNumber);
7550
7812
  return;
7551
7813
  }
7552
- resolveTaskRefs({
7553
- workspaceId,
7554
- taskRefs: [ref]
7555
- }).then((result) => {
7556
- if (!result.ok) return;
7557
- const hit = result.value.resolved[0];
7558
- if (hit !== void 0) selectThread(hit.taskRef, hit.threadRef, hit.channelRef, hit.taskNumber);
7559
- });
7814
+ jumpToTaskThread(resolveTaskRefs, workspaceId, ref, selectThread);
7560
7815
  }
7561
7816
  };
7562
- const lookupTaskRefs = (taskRefs) => resolveTaskRefs({
7563
- workspaceId,
7564
- taskRefs
7565
- }).then((result) => {
7566
- if (!result.ok) return [];
7567
- for (const entry of result.value.resolved) rememberResolvedTaskRef(entry);
7568
- return result.value.resolved;
7569
- });
7817
+ const lookupTaskRefs = hostTaskRefLookup(resolveTaskRefs, workspaceId);
7570
7818
  const timeline = useTimelineScroll(`${view?.items.length ?? 0}:${channelLastItem?.message.messageRef ?? ""}`);
7571
7819
  const channel = view?.channels.find((item) => item.channelRef === channelRef);
7572
7820
  const channelMemberIds = new Set(view?.members.filter((item) => item.channelRef === channelRef).map((item) => item.memberId) ?? []);
@@ -7695,10 +7943,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7695
7943
  });
7696
7944
  const pendingSendId = (0, react.useRef)();
7697
7945
  const send = async () => {
7698
- console.log("DBG send entry pending=%s draft=%j files=%d", pending, draft, pendingFiles.length);
7699
7946
  if (pending || draft.trim() === "") return;
7700
7947
  const recipientIds = [...recipients].sort();
7701
- const requestId = pendingSendId.current ?? crypto.randomUUID();
7948
+ const requestId = pendingSendId.current ?? mintRequestId();
7702
7949
  pendingSendId.current = requestId;
7703
7950
  setPending(true);
7704
7951
  setError(void 0);
@@ -7707,7 +7954,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7707
7954
  const attachmentIds = [];
7708
7955
  for (const file of pendingFiles) {
7709
7956
  const uploaded = await putAttachment({
7710
- requestId: crypto.randomUUID(),
7957
+ requestId: mintRequestId(),
7711
7958
  workspaceId,
7712
7959
  name: file.name,
7713
7960
  mediaType: file.type === "" ? void 0 : file.type,
@@ -7726,6 +7973,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7726
7973
  channelRef,
7727
7974
  body: draft.trim(),
7728
7975
  recipients: recipientIds,
7976
+ asTask,
7729
7977
  ...attachmentIds.length === 0 ? {} : { attachments: attachmentIds }
7730
7978
  });
7731
7979
  if (!result.ok) {
@@ -7733,6 +7981,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7733
7981
  setError(result.error.message);
7734
7982
  } else if (result.value.kind === "committed") {
7735
7983
  pendingSendId.current = void 0;
7984
+ setAsTask(false);
7736
7985
  await refresh();
7737
7986
  drafts.clear(draftKey);
7738
7987
  setPendingFiles([]);
@@ -7902,7 +8151,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7902
8151
  const senderStatus = members.find((member) => member.member.memberId === item.message.sender);
7903
8152
  const human = item.message.sender === view.humanMemberId;
7904
8153
  const sender = human ? t("human") : senderStatus?.member.handle ?? item.message.sender;
7905
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [isRunGap(index > 0 ? block.items[index - 1].message.occurredAt : void 0, item.message.occurredAt) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamRunDivider, { occurredAt: item.message.occurredAt }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamMessage, {
8154
+ const turnGap = isRunGap(index > 0 ? block.items[index - 1].message.occurredAt : void 0, item.message.occurredAt);
8155
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [turnGap && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamRunDivider, { occurredAt: item.message.occurredAt }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(TeamMessage, {
7906
8156
  senderName: sender,
7907
8157
  memberId: item.message.sender,
7908
8158
  human,
@@ -7915,13 +8165,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7915
8165
  onOpenRef: openRef,
7916
8166
  onResolveTaskRefs: lookupTaskRefs,
7917
8167
  grouped: index > 0,
8168
+ showGroupedTime: item.message.topLevel === true && !turnGap,
7918
8169
  ...senderStatus === void 0 ? {} : { senderTitle: senderStatus.member.description },
7919
- children: item.message.topLevel && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
8170
+ children: [item.message.topLevel && item.task !== void 0 && item.taskNumber !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
7920
8171
  type: "button",
7921
8172
  className: channel_module_css_default.taskFooter,
7922
8173
  "aria-label": t("openTask", { number: item.taskNumber }),
7923
8174
  onClick: () => {
7924
- selectThread(item.task.taskRef, item.thread.threadRef, channelRef, item.taskNumber);
8175
+ selectThread(item.thread.threadRef, channelRef, item.task?.taskRef, item.taskNumber);
7925
8176
  },
7926
8177
  children: [
7927
8178
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -7955,7 +8206,29 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7955
8206
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14, { size: 12 })
7956
8207
  })
7957
8208
  ]
7958
- })
8209
+ }), item.message.topLevel && item.task === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
8210
+ type: "button",
8211
+ className: channel_module_css_default.taskFooter,
8212
+ "aria-label": t("openThread"),
8213
+ onClick: () => {
8214
+ selectThread(item.thread.threadRef, channelRef);
8215
+ },
8216
+ children: [
8217
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8218
+ className: channel_module_css_default.taskNumber,
8219
+ children: t("threadLabel")
8220
+ }),
8221
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8222
+ className: channel_module_css_default.taskCount,
8223
+ children: t("taskMessageCount", { count: item.messageCount })
8224
+ }),
8225
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8226
+ className: channel_module_css_default.taskArrow,
8227
+ "aria-hidden": "true",
8228
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14, { size: 12 })
8229
+ })
8230
+ ]
8231
+ })]
7959
8232
  })] }, item.message.messageRef);
7960
8233
  })
7961
8234
  }, `run-${block.items[0].message.messageRef}`))
@@ -7982,6 +8255,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7982
8255
  },
7983
8256
  pendingFiles,
7984
8257
  onFilesChange: setPendingFiles,
8258
+ asTask,
8259
+ onAsTaskChange: setAsTask,
7985
8260
  t
7986
8261
  }, draftKey) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {})
7987
8262
  ]
@@ -8012,7 +8287,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8012
8287
  return new Map(facts.map((fact) => [factKey(fact.fact), fact]));
8013
8288
  }
8014
8289
  function TeamThreadPage(props) {
8015
- const { workspaceId, channelRef, taskRef, threadRef, taskNumber, backToWorkspace, selectChannel, selectThread, resolveTaskRefs, putAttachment, loadChannels, readThread, loadThreadHistory, subscribeChanges, loadMembers, drafts, getAttachment, reply, changeTask, t } = props;
8290
+ const { workspaceId, channelRef, taskRef, threadRef, taskNumber, backToWorkspace, selectChannel, selectThread, resolveTaskRefs, putAttachment, loadChannels, readThread, loadThreadHistory, subscribeChanges, loadMembers, drafts, getAttachment, reply, changeTask, promoteThread, t } = props;
8291
+ const threadRequest = {
8292
+ threadRef,
8293
+ ...taskRef === void 0 ? {} : { taskRef }
8294
+ };
8016
8295
  const [projection, setProjection] = (0, react.useState)();
8017
8296
  const [channelView, setChannelView] = (0, react.useState)();
8018
8297
  const [members, setMembers] = (0, react.useState)([]);
@@ -8028,18 +8307,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8028
8307
  const [claimsOpen, setClaimsOpen] = (0, react.useState)(false);
8029
8308
  const [confirmingAccept, setConfirmingAccept] = (0, react.useState)(false);
8030
8309
  (0, react.useEffect)(() => {
8031
- if (confirmingAccept && projection?.task.resolution === "accepted") setConfirmingAccept(false);
8032
- }, [confirmingAccept, projection?.task.resolution]);
8310
+ if (confirmingAccept && projection?.task?.resolution === "accepted") setConfirmingAccept(false);
8311
+ }, [confirmingAccept, projection?.task?.resolution]);
8033
8312
  const [replyRequestId, setReplyRequestId] = (0, react.useState)();
8034
8313
  const [confirmation, setConfirmation] = (0, react.useState)();
8035
8314
  const [statusMessage, setStatusMessage] = (0, react.useState)();
8036
8315
  const [pending, setPending] = (0, react.useState)(false);
8316
+ const [mutating, setMutating] = (0, react.useState)();
8037
8317
  const [loading, setLoading] = (0, react.useState)(true);
8038
8318
  const [error, setError] = (0, react.useState)();
8039
8319
  const mountedRef = (0, react.useRef)(false);
8040
8320
  const currentFactsRef = (0, react.useRef)([]);
8041
8321
  const sequenceRef = (0, react.useRef)(0);
8042
- const readRequestIdRef = (0, react.useRef)(crypto.randomUUID());
8322
+ const readRequestIdRef = (0, react.useRef)(mintRequestId());
8043
8323
  const mutationRequests = (0, react.useRef)(/* @__PURE__ */ new Map());
8044
8324
  const threadLastFact = currentFacts[currentFacts.length - 1];
8045
8325
  const timeline = useTimelineScroll(`${currentFacts.length}:${olderFacts.length}:${threadLastFact === void 0 ? "" : factKey(threadLastFact)}`);
@@ -8057,7 +8337,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8057
8337
  };
8058
8338
  const readCurrent = async (newRequest = false) => {
8059
8339
  if (!mountedRef.current) return false;
8060
- if (newRequest) readRequestIdRef.current = crypto.randomUUID();
8340
+ if (newRequest) readRequestIdRef.current = mintRequestId();
8061
8341
  const sequence = sequenceRef.current + 1;
8062
8342
  sequenceRef.current = sequence;
8063
8343
  setLoading(true);
@@ -8065,7 +8345,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8065
8345
  const result = await readThread({
8066
8346
  requestId: readRequestIdRef.current,
8067
8347
  workspaceId,
8068
- taskRef
8348
+ ...threadRequest
8069
8349
  });
8070
8350
  if (!mountedRef.current || sequence !== sequenceRef.current) return false;
8071
8351
  if (!result.ok) {
@@ -8104,7 +8384,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8104
8384
  try {
8105
8385
  const result = await loadThreadHistory({
8106
8386
  workspaceId,
8107
- taskRef,
8387
+ ...threadRequest,
8108
8388
  limit: 100
8109
8389
  });
8110
8390
  if (!mountedRef.current || !result.ok) return;
@@ -8121,7 +8401,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8121
8401
  });
8122
8402
  setProjection((current) => current === void 0 ? current : {
8123
8403
  ...current,
8124
- task: result.value.task,
8404
+ ...result.value.task === void 0 ? {} : { task: result.value.task },
8125
8405
  thread: result.value.thread,
8126
8406
  claims: result.value.claims
8127
8407
  });
@@ -8158,10 +8438,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8158
8438
  const [read, history] = await Promise.all([readThread({
8159
8439
  requestId: readRequestIdRef.current,
8160
8440
  workspaceId,
8161
- taskRef
8441
+ ...threadRequest
8162
8442
  }), loadThreadHistory({
8163
8443
  workspaceId,
8164
- taskRef,
8444
+ ...threadRequest,
8165
8445
  limit: 20
8166
8446
  }).catch(() => void 0)]);
8167
8447
  if (!mountedRef.current || sequence !== sequenceRef.current) return;
@@ -8224,7 +8504,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8224
8504
  try {
8225
8505
  const result = await loadThreadHistory({
8226
8506
  workspaceId,
8227
- taskRef,
8507
+ ...threadRequest,
8228
8508
  beforeSequence,
8229
8509
  limit: 20
8230
8510
  });
@@ -8246,6 +8526,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8246
8526
  const activeProjection = projection;
8247
8527
  const task = activeProjection?.task;
8248
8528
  const thread = activeProjection?.thread;
8529
+ const resolvedTaskNumber = taskNumber ?? channelView?.taskNumbers.find((entry) => entry.taskRef === task?.taskRef)?.taskNumber;
8249
8530
  const taskTitle = activeProjection === void 0 ? void 0 : formatTaskTitle(activeProjection.anchor.body);
8250
8531
  const taskClaims = activeProjection?.claims ?? [];
8251
8532
  const effectiveChannelRef = task?.channelRef ?? channelRef;
@@ -8254,14 +8535,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8254
8535
  const mentionHandlesMap = (0, react.useMemo)(() => new Map(members.map((status) => [status.member.memberId, status.member.handle.replace(/^@/, "")])), [members]);
8255
8536
  const metadata = (0, react.useMemo)(() => readMeta(readFacts), [readFacts]);
8256
8537
  const unreadIndex = (0, react.useMemo)(() => {
8257
- return mergeFacts([
8258
- messageFact(activeProjection?.anchor ?? {
8259
- messageRef: "missing",
8260
- sequence: 0
8261
- }, activeProjection?.anchorMentions),
8262
- ...readFacts.map((fact) => fact.fact),
8263
- ...currentFacts
8264
- ]).findIndex((fact) => metadata.get(factKey(fact))?.unread === true);
8538
+ return mergeFacts(...activeProjection === void 0 ? [] : [[messageFact(activeProjection.anchor, activeProjection.anchorMentions)]], readFacts.map((fact) => fact.fact), currentFacts).findIndex((fact) => metadata.get(factKey(fact))?.unread === true);
8265
8539
  }, [
8266
8540
  activeProjection?.anchor,
8267
8541
  readFacts,
@@ -8277,23 +8551,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8277
8551
  const [pendingFiles, setPendingFiles] = (0, react.useState)([]);
8278
8552
  const openRef = (ref) => {
8279
8553
  if (ref.startsWith("channel:") && ref !== channelRef) selectChannel(ref);
8280
- if (ref.startsWith("task:") && ref !== taskRef) resolveTaskRefs({
8281
- workspaceId,
8282
- taskRefs: [ref]
8283
- }).then((result) => {
8284
- if (!result.ok) return;
8285
- const hit = result.value.resolved[0];
8286
- if (hit !== void 0) selectThread(hit.taskRef, hit.threadRef, hit.channelRef, hit.taskNumber);
8287
- });
8554
+ if (ref.startsWith("task:") && ref !== taskRef) jumpToTaskThread(resolveTaskRefs, workspaceId, ref, selectThread);
8288
8555
  };
8289
- const lookupTaskRefs = (refs) => resolveTaskRefs({
8290
- workspaceId,
8291
- taskRefs: refs
8292
- }).then((result) => {
8293
- if (!result.ok) return [];
8294
- for (const entry of result.value.resolved) rememberResolvedTaskRef(entry);
8295
- return result.value.resolved;
8296
- });
8556
+ const lookupTaskRefs = hostTaskRefLookup(resolveTaskRefs, workspaceId);
8297
8557
  const renderFact = (fact, grouped = false) => {
8298
8558
  if (fact.kind === "message") {
8299
8559
  const sender = memberName(fact.message.sender);
@@ -8380,19 +8640,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8380
8640
  await readCurrent(true);
8381
8641
  await refreshSupplemental();
8382
8642
  };
8383
- const mutateTask = async (action) => {
8384
- if (pending || task === void 0 || thread === void 0) return;
8643
+ const convertToTask = async () => {
8644
+ if (pending || thread === void 0 || task !== void 0) return;
8385
8645
  setPending(true);
8646
+ setMutating("promote");
8386
8647
  setError(void 0);
8387
- const key = `task:${action}`;
8388
- const requestId = mutationRequests.current.get(key) ?? crypto.randomUUID();
8648
+ const key = "promote";
8649
+ const requestId = mutationRequests.current.get(key) ?? mintRequestId();
8389
8650
  mutationRequests.current.set(key, requestId);
8390
8651
  try {
8391
- const result = await changeTask({
8652
+ const result = await promoteThread({
8392
8653
  requestId,
8393
8654
  workspaceId,
8394
- taskRef: task.taskRef,
8395
- action,
8655
+ threadRef,
8396
8656
  baseRevision: thread.revision
8397
8657
  });
8398
8658
  if (!result.ok) {
@@ -8405,8 +8665,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8405
8665
  setProjection((current) => current === void 0 ? current : {
8406
8666
  ...current,
8407
8667
  task: committed.task,
8408
- thread: committed.thread,
8409
- claims: committed.claims
8668
+ thread: committed.thread
8410
8669
  });
8411
8670
  setCurrentFacts((current) => {
8412
8671
  const merged = mergeFacts(current, [{
@@ -8432,36 +8691,94 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8432
8691
  setError(cause instanceof Error ? cause.message : String(cause));
8433
8692
  } finally {
8434
8693
  setPending(false);
8694
+ setMutating(void 0);
8435
8695
  }
8436
8696
  };
8437
- const sendReply = async () => {
8438
- if (pending || task === void 0 || thread === void 0 || draft.trim() === "") return;
8439
- const id = replyRequestId ?? crypto.randomUUID();
8440
- setReplyRequestId(id);
8697
+ const mutateTask = async (action) => {
8698
+ if (pending || task === void 0 || thread === void 0) return;
8441
8699
  setPending(true);
8700
+ if (action === "accept") setMutating("accept");
8442
8701
  setError(void 0);
8702
+ const key = `task:${action}`;
8703
+ const requestId = mutationRequests.current.get(key) ?? mintRequestId();
8704
+ mutationRequests.current.set(key, requestId);
8443
8705
  try {
8444
- const attachmentIds = [];
8445
- for (const file of pendingFiles) {
8446
- const uploaded = await putAttachment({
8447
- requestId: crypto.randomUUID(),
8448
- workspaceId,
8449
- name: file.name,
8450
- mediaType: file.type === "" ? void 0 : file.type,
8451
- bytesBase64: bytesToBase64(new Uint8Array(await file.arrayBuffer()))
8452
- });
8453
- if (!uploaded.ok) {
8454
- setError(uploaded.error.message);
8455
- return;
8456
- }
8457
- attachmentIds.push(uploaded.value.attachmentId);
8458
- }
8459
- const result = await reply({
8460
- requestId: id,
8706
+ const result = await changeTask({
8707
+ requestId,
8461
8708
  workspaceId,
8462
8709
  taskRef: task.taskRef,
8463
- body: draft.trim(),
8464
- baseRevision: thread.revision,
8710
+ action,
8711
+ baseRevision: thread.revision
8712
+ });
8713
+ if (!result.ok) {
8714
+ setError(result.error.message);
8715
+ return;
8716
+ }
8717
+ if (result.value.kind === "committed") {
8718
+ mutationRequests.current.delete(key);
8719
+ const committed = result.value;
8720
+ setProjection((current) => current === void 0 ? current : {
8721
+ ...current,
8722
+ task: committed.task,
8723
+ thread: committed.thread,
8724
+ claims: committed.claims
8725
+ });
8726
+ setCurrentFacts((current) => {
8727
+ const merged = mergeFacts(current, [{
8728
+ kind: "activity",
8729
+ sequence: committed.activity.sequence,
8730
+ activity: committed.activity
8731
+ }]);
8732
+ currentFactsRef.current = merged;
8733
+ return merged;
8734
+ });
8735
+ await readCurrent(true);
8736
+ await refreshSupplemental();
8737
+ } else if (result.value.kind === "unread_required") {
8738
+ setError(t("unreadRequired", { count: result.value.unreadCount }));
8739
+ mutationRequests.current.delete(key);
8740
+ await refreshAfterFence();
8741
+ } else {
8742
+ setError(t("staleRevision"));
8743
+ mutationRequests.current.delete(key);
8744
+ await refreshPassiveFacts();
8745
+ }
8746
+ } catch (cause) {
8747
+ setError(cause instanceof Error ? cause.message : String(cause));
8748
+ } finally {
8749
+ setPending(false);
8750
+ setMutating(void 0);
8751
+ }
8752
+ };
8753
+ const sendReply = async () => {
8754
+ if (pending || thread === void 0 || draft.trim() === "") return;
8755
+ const id = replyRequestId ?? mintRequestId();
8756
+ setReplyRequestId(id);
8757
+ setPending(true);
8758
+ setError(void 0);
8759
+ try {
8760
+ const attachmentIds = [];
8761
+ for (const file of pendingFiles) {
8762
+ const uploaded = await putAttachment({
8763
+ requestId: mintRequestId(),
8764
+ workspaceId,
8765
+ name: file.name,
8766
+ mediaType: file.type === "" ? void 0 : file.type,
8767
+ bytesBase64: bytesToBase64(new Uint8Array(await file.arrayBuffer()))
8768
+ });
8769
+ if (!uploaded.ok) {
8770
+ setError(uploaded.error.message);
8771
+ return;
8772
+ }
8773
+ attachmentIds.push(uploaded.value.attachmentId);
8774
+ }
8775
+ const result = await reply({
8776
+ requestId: id,
8777
+ workspaceId,
8778
+ threadRef,
8779
+ ...task === void 0 ? {} : { taskRef: task.taskRef },
8780
+ body: draft.trim(),
8781
+ baseRevision: thread.revision,
8465
8782
  recipients: [...recipients].sort(),
8466
8783
  ...attachmentIds.length === 0 ? {} : { attachments: attachmentIds },
8467
8784
  ...confirmation === void 0 ? {} : { confirmationToken: confirmation }
@@ -8484,7 +8801,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8484
8801
  });
8485
8802
  setProjection((current) => current === void 0 ? current : {
8486
8803
  ...current,
8487
- task: committed.task,
8804
+ ...committed.task === void 0 ? {} : { task: committed.task },
8488
8805
  thread: committed.thread
8489
8806
  });
8490
8807
  drafts.clear(draftKey);
@@ -8548,49 +8865,65 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8548
8865
  }),
8549
8866
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
8550
8867
  className: conversation_module_css_default.headerRow,
8551
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8552
- className: conversation_module_css_default.headerCopy,
8553
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8554
- className: thread_module_css_default.titleLine,
8555
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", { children: task === void 0 ? t("taskPending") : t("taskLabel", { number: taskNumber ?? "…" }) }), task !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Pill, { children: formatTaskStatus(task.status, t) })]
8556
- }), taskTitle !== void 0 && taskTitle !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8557
- className: thread_module_css_default.taskTitle,
8558
- children: taskTitle
8559
- })]
8560
- }), task !== void 0 && thread !== void 0 && task.resolution !== "closed" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8561
- className: conversation_module_css_default.headerActions,
8562
- children: [(() => {
8563
- const activeClaims = projection?.claims.filter((claim) => claim.taskRef === task.taskRef && claim.state === "active") ?? [];
8564
- const earlyAccept = task.resolution === "open" && task.status === "in_progress" && activeClaims.length > 0;
8565
- if (!(task.status === "in_review" || earlyAccept) || task.resolution !== "open") return null;
8566
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8868
+ children: [
8869
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8870
+ className: conversation_module_css_default.headerCopy,
8871
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8872
+ className: thread_module_css_default.titleLine,
8873
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", { children: task === void 0 ? t("threadLabel") : t("taskLabel", { number: resolvedTaskNumber ?? "…" }) }), task !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Pill, { children: formatTaskStatus(task.status, t) })]
8874
+ }), taskTitle !== void 0 && taskTitle !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8875
+ className: thread_module_css_default.taskTitle,
8876
+ title: taskTitle,
8877
+ children: taskTitle
8878
+ })]
8879
+ }),
8880
+ task === void 0 && thread !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8881
+ className: conversation_module_css_default.headerActions,
8882
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8567
8883
  size: "sm",
8568
8884
  variant: "primary",
8569
8885
  disabled: pending,
8570
8886
  onClick: () => {
8571
- if (earlyAccept) setConfirmingAccept(true);
8572
- else mutateTask("accept");
8887
+ convertToTask();
8573
8888
  },
8574
- children: t("acceptTask")
8575
- });
8576
- })(), task.resolution === "open" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8577
- size: "sm",
8578
- variant: "outline",
8579
- disabled: pending,
8580
- onClick: () => {
8581
- mutateTask("close");
8582
- },
8583
- children: t("closeTask")
8584
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8585
- size: "sm",
8586
- variant: "primary",
8587
- disabled: pending,
8588
- onClick: () => {
8589
- mutateTask("reopen");
8590
- },
8591
- children: t("reopenTask")
8592
- })]
8593
- })]
8889
+ children: mutating === "promote" ? t("promotingTask") : t("promoteToTask")
8890
+ })
8891
+ }),
8892
+ task !== void 0 && thread !== void 0 && task.resolution !== "closed" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8893
+ className: conversation_module_css_default.headerActions,
8894
+ children: [(() => {
8895
+ const activeClaims = projection?.claims.filter((claim) => claim.taskRef === task.taskRef && claim.state === "active") ?? [];
8896
+ const earlyAccept = task.resolution === "open" && task.status === "in_progress" && activeClaims.length > 0;
8897
+ if (!(task.status === "in_review" || earlyAccept) || task.resolution !== "open") return null;
8898
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8899
+ size: "sm",
8900
+ variant: "primary",
8901
+ disabled: pending,
8902
+ onClick: () => {
8903
+ if (earlyAccept) setConfirmingAccept(true);
8904
+ else mutateTask("accept");
8905
+ },
8906
+ children: t("acceptTask")
8907
+ });
8908
+ })(), task.resolution === "open" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8909
+ size: "sm",
8910
+ variant: "outline",
8911
+ disabled: pending,
8912
+ onClick: () => {
8913
+ mutateTask("close");
8914
+ },
8915
+ children: t("closeTask")
8916
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
8917
+ size: "sm",
8918
+ variant: "primary",
8919
+ disabled: pending,
8920
+ onClick: () => {
8921
+ mutateTask("reopen");
8922
+ },
8923
+ children: t("reopenTask")
8924
+ })]
8925
+ })
8926
+ ]
8594
8927
  }),
8595
8928
  risks.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
8596
8929
  className: thread_module_css_default.riskSection,
@@ -8632,7 +8965,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8632
8965
  onClick: () => {
8633
8966
  mutateTask("accept");
8634
8967
  },
8635
- children: pending ? t("acceptingTask") : t("acceptTask")
8968
+ children: mutating === "accept" ? t("acceptingTask") : t("acceptTask")
8636
8969
  })] }),
8637
8970
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8638
8971
  className: conversation_module_css_default.confirmBody,
@@ -8772,7 +9105,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8772
9105
  ]
8773
9106
  })
8774
9107
  }),
8775
- projection !== void 0 && task !== void 0 && thread !== void 0 ? task.resolution === "closed" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9108
+ projection !== void 0 && thread !== void 0 ? task?.resolution === "closed" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8776
9109
  className: thread_module_css_default.closedBar,
8777
9110
  "data-team-closed": true,
8778
9111
  children: [error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
@@ -8813,6 +9146,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8813
9146
  onSubmit: () => {
8814
9147
  sendReply();
8815
9148
  },
9149
+ placeholder: t("replyPlaceholder"),
8816
9150
  pendingFiles,
8817
9151
  onFilesChange: setPendingFiles,
8818
9152
  t
@@ -8822,19 +9156,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8822
9156
  }
8823
9157
  //#endregion
8824
9158
  //#region src/client/TeamConversation.tsx
8825
- function TeamConversation({ t, useWorkspaces, navigation, drafts, putAttachment, getAttachment, loadChannels, readThread, loadThreadHistory, subscribeChanges, loadMembers, sendMessage, joinChannel, removeChannelMember, reply, changeTask, selectThread, selectChannel, backToWorkspace, backToChannels, resolveTaskRefs }) {
9159
+ function TeamConversation({ t, useWorkspaces, navigation, drafts, putAttachment, getAttachment, loadChannels, readThread, loadThreadHistory, subscribeChanges, loadMembers, sendMessage, joinChannel, removeChannelMember, reply, changeTask, promoteThread, selectThread, selectChannel, backToWorkspace, backToChannels, resolveTaskRefs }) {
8826
9160
  const navigationState = (0, react.useSyncExternalStore)(navigation.subscribe, navigation.getSnapshot, navigation.getSnapshot);
8827
9161
  const current = useWorkspaces((state) => state.items).find((workspace) => workspace.workspaceId === navigationState.workspaceId);
8828
- if (current !== void 0 && navigationState.taskRef !== void 0 && navigationState.threadRef !== void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamThreadPage, {
9162
+ if (current !== void 0 && navigationState.threadRef !== void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamThreadPage, {
8829
9163
  workspaceId: current.workspaceId,
8830
9164
  putAttachment,
8831
- taskRef: navigationState.taskRef,
8832
9165
  threadRef: navigationState.threadRef,
8833
9166
  backToWorkspace,
8834
9167
  selectChannel,
8835
9168
  selectThread,
8836
9169
  resolveTaskRefs,
8837
9170
  ...navigationState.channelRef === void 0 ? {} : { channelRef: navigationState.channelRef },
9171
+ ...navigationState.taskRef === void 0 ? {} : { taskRef: navigationState.taskRef },
8838
9172
  ...navigationState.taskNumber === void 0 ? {} : { taskNumber: navigationState.taskNumber },
8839
9173
  drafts,
8840
9174
  getAttachment,
@@ -8845,6 +9179,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8845
9179
  loadMembers,
8846
9180
  reply,
8847
9181
  changeTask,
9182
+ promoteThread,
8848
9183
  t
8849
9184
  }, navigationState.threadRef);
8850
9185
  if (current !== void 0 && navigationState.channelRef !== void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamChannelPage, {
@@ -8892,7 +9227,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8892
9227
  }
8893
9228
  //#endregion
8894
9229
  //#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/sidebar.module.css.mjs
8895
- const css$1 = "html[data-agent-team-mode=team] button[class*=newSession]{display:none}.d0xfxa_workspaceBrowser{flex-direction:column;height:100%;min-height:0;padding:0 8px 8px;display:flex}.d0xfxa_workspaceHeader{color:var(--dsw-alias-label-tertiary);justify-content:space-between;align-items:center;min-height:28px;padding:0 4px 0 8px;font-size:13px;font-weight:600;line-height:20px;display:flex}.d0xfxa_railButton{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;justify-content:center;align-items:center;padding:0;display:inline-flex}.d0xfxa_railButton:hover,.d0xfxa_railButton:focus-visible{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);outline:none}.d0xfxa_workspaceList{flex-direction:column;gap:2px;padding-bottom:2px;display:flex}.d0xfxa_workspaceRow{color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;background:0 0;border:0;border-radius:8px;align-items:center;gap:6px;width:100%;height:34px;padding:0 8px;display:flex}.d0xfxa_workspaceRow:hover,.d0xfxa_workspaceRow:focus-visible,.d0xfxa_workspaceRow[aria-current=page]{background:var(--dsw-alias-interactive-bg-hover);outline:none}.d0xfxa_workspaceRow:focus-visible{box-shadow:inset 0 0 0 1px var(--dsw-alias-border-l3)}.d0xfxa_workspaceIcon{color:var(--dsw-alias-label-tertiary);flex:0 0 16px;justify-content:center;align-items:center;height:20px;display:inline-flex}.d0xfxa_workspaceRow[data-selected] .d0xfxa_workspaceIcon{color:var(--dsw-alias-state-business-primary)}.d0xfxa_workspaceCopy{min-width:0;display:flex}.d0xfxa_workspaceCopy strong{text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:400;line-height:20px;overflow:hidden}.d0xfxa_emptyState{color:var(--dsw-alias-label-tertiary);margin:8px;font-size:12px;line-height:18px}.d0xfxa_railWorkspace{flex-direction:column;align-items:center;gap:8px;padding-top:8px;display:flex}.d0xfxa_railButton{border-radius:50%;width:36px;height:36px}.d0xfxa_railButton[data-active]{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.d0xfxa_workspaceSection{flex-direction:column;flex:1;gap:4px;min-height:0;margin-top:2px;display:flex;overflow-y:auto}.d0xfxa_section{flex-direction:column;display:flex}.d0xfxa_sectionHeader{align-items:center;min-height:26px;padding-right:2px;display:flex}.d0xfxa_sectionToggle{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;align-items:center;gap:4px;min-width:0;min-height:24px;padding:0 6px;font-size:12px;line-height:18px;display:inline-flex}.d0xfxa_sectionToggle:focus-visible{outline:none}.d0xfxa_sectionToggle:hover .d0xfxa_sectionChevron,.d0xfxa_sectionToggle:focus-visible .d0xfxa_sectionChevron{color:var(--dsw-alias-label-primary)}.d0xfxa_sectionChevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .12s,color .12s}.d0xfxa_sectionToggle[aria-expanded=false] .d0xfxa_sectionChevron{transform:rotate(-90deg)}.d0xfxa_sectionTitle{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.d0xfxa_sectionActions{align-items:center;margin-left:auto;display:inline-flex}.d0xfxa_panel{flex-direction:column;display:flex}.d0xfxa_iconButton{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:50%;justify-content:center;align-items:center;width:24px;height:24px;padding:0;display:inline-flex}.d0xfxa_iconButton:hover,.d0xfxa_iconButton:focus-visible{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);outline:none}.d0xfxa_textButton{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:5px;padding:2px 5px;font-size:11px;line-height:18px}.d0xfxa_textButton:hover,.d0xfxa_textButton:focus-visible{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);outline:none}.d0xfxa_textButton:disabled{cursor:not-allowed;opacity:.4}.d0xfxa_channelList,.d0xfxa_agentList{flex-direction:column;gap:1px;padding:0 4px 4px;display:flex}.d0xfxa_sidebarRowDragging{opacity:.5}.d0xfxa_sidebarRowDropBefore,.d0xfxa_sidebarRowDropAfter{position:relative}.d0xfxa_sidebarRowDropBefore:before,.d0xfxa_sidebarRowDropAfter:after{content:\"\";z-index:1;background:linear-gradient(55deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 0 / 5px 7px no-repeat, linear-gradient(125deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 5px / 5px 7px no-repeat, linear-gradient(var(--dsw-alias-state-business-primary) 0 0) 4px 5px / calc(100% - 4px) 2px no-repeat;pointer-events:none;height:12px;position:absolute;left:0;right:4px}.d0xfxa_sidebarRowDropBefore:before{top:-7px}.d0xfxa_sidebarRowDropAfter:after{bottom:-7px}.d0xfxa_channelRow{color:var(--dsw-alias-label-primary);border-radius:8px;align-items:center;min-height:30px;display:flex;position:relative}.d0xfxa_channelSelect{box-sizing:border-box;color:inherit;cursor:pointer;text-align:left;background:0 0;border:0;flex:1;align-items:center;min-width:0;min-height:30px;padding:3px 4px 3px 8px;display:flex}.d0xfxa_channelSelect:focus-visible{outline:none}.d0xfxa_channelName{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:400;line-height:18px;overflow:hidden}.d0xfxa_agentRow{color:var(--dsw-alias-label-primary);border-radius:8px;align-items:center;min-height:38px;display:flex;position:relative}.d0xfxa_agentSelect{box-sizing:border-box;color:inherit;cursor:pointer;text-align:left;background:0 0;border:0;flex:1;grid-template-columns:24px minmax(0,1fr);align-items:center;gap:0 8px;min-width:0;min-height:38px;padding:3px 4px 3px 8px;display:grid}.d0xfxa_agentSelect:focus-visible{outline:none}.d0xfxa_agentSelect[aria-current=page]{background:var(--dsw-alias-interactive-bg-hover);border-radius:8px}.d0xfxa_agentRow:hover .d0xfxa_agentSelect[aria-current=page],.d0xfxa_agentRow:focus-within .d0xfxa_agentSelect[aria-current=page],.d0xfxa_agentRow[data-menu-open] .d0xfxa_agentSelect[aria-current=page]{background:0 0}.d0xfxa_agentAvatar{background:hsl(var(--team-avatar-hue,212) 42% 46%);color:#fff;cursor:default;border-radius:50%;flex:0 0 24px;justify-content:center;align-items:center;width:24px;height:24px;font-size:11px;font-weight:600;display:inline-flex;position:relative}.d0xfxa_agentAvatarBadge{background:var(--dsw-specific-sidebar-fill);box-shadow:0 0 0 1px var(--dsw-specific-sidebar-fill);border-radius:50%;justify-content:center;align-items:center;width:12px;height:12px;padding:1px;line-height:0;display:inline-flex;position:absolute;bottom:-3px;right:-3px}.d0xfxa_agentCopy{flex-direction:column;min-width:0;display:flex}.d0xfxa_agentCopy strong{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:400;line-height:17px;overflow:hidden}.d0xfxa_agentCopy small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:13px;overflow:hidden}.d0xfxa_unavailableDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;width:7px;height:7px;display:inline-block}.d0xfxa_rowMenu{flex:none;align-items:center;padding-right:4px;display:none}.d0xfxa_channelRow:hover .d0xfxa_rowMenu,.d0xfxa_channelRow:focus-within .d0xfxa_rowMenu,.d0xfxa_channelRow[data-menu-open] .d0xfxa_rowMenu,.d0xfxa_agentRow:hover .d0xfxa_rowMenu,.d0xfxa_agentRow:focus-within .d0xfxa_rowMenu,.d0xfxa_agentRow[data-menu-open] .d0xfxa_rowMenu{display:inline-flex}.d0xfxa_channelRow[data-menu-open],.d0xfxa_agentRow[data-menu-open],.d0xfxa_channelRow:hover,.d0xfxa_agentRow:hover,.d0xfxa_channelRow:focus-within,.d0xfxa_agentRow:focus-within,.d0xfxa_channelRow[aria-current=page]{background:var(--dsw-alias-interactive-bg-hover)}.d0xfxa_rowMenuButton{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;justify-content:center;align-items:center;width:20px;height:20px;padding:0;display:inline-flex}.d0xfxa_rowMenuButton:hover,.d0xfxa_rowMenuButton:focus-visible{color:var(--dsw-alias-label-primary);outline:none}.d0xfxa_retryError{color:var(--dsw-alias-state-error-primary);justify-content:space-between;align-items:center;gap:8px;padding:8px;font-size:11px;display:flex}.d0xfxa_editDescription{color:var(--dsw-alias-label-secondary);margin:0 0 10px;font-size:12px;line-height:18px}.d0xfxa_editMemberList{gap:3px;display:grid}.d0xfxa_editMemberRow{border-radius:6px;grid-template-columns:14px minmax(0,1fr) auto;align-items:center;gap:0 8px;min-height:40px;padding:3px 6px;display:grid}.d0xfxa_editMemberRowChannels{grid-template-columns:minmax(0,1fr) auto}.d0xfxa_editMemberRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.d0xfxa_editMemberCopy{min-width:0;display:grid}.d0xfxa_editMemberCopy strong{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:500;line-height:18px;overflow:hidden}.d0xfxa_editMemberCopy small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:14px;overflow:hidden}.d0xfxa_editChannelName{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:400;line-height:18px;overflow:hidden}.d0xfxa_editMemberRow button{min-width:60px}.d0xfxa_editHint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:11px;line-height:16px}.d0xfxa_menuHint{color:var(--dsw-alias-label-tertiary);margin-left:4px;font-size:10px;line-height:14px}.d0xfxa_rowError{color:var(--dsw-alias-state-error-primary);grid-column:1/-1;margin:2px 0;font-size:11px;line-height:16px}";
9230
+ const css$1 = "html[data-agent-team-mode=team] button[class*=newSession]{display:none}.d0xfxa_workspaceBrowser{flex-direction:column;height:100%;min-height:0;padding:0 8px 8px;display:flex}.d0xfxa_railButton{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;justify-content:center;align-items:center;padding:0;display:inline-flex}.d0xfxa_railButton:hover,.d0xfxa_railButton:focus-visible{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);outline:none}.d0xfxa_workspaceList{flex-direction:column;gap:2px;padding-bottom:2px;display:flex}.d0xfxa_workspaceRow{color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;background:0 0;border:0;border-radius:8px;align-items:center;gap:6px;width:100%;height:34px;padding:0 8px;display:flex}.d0xfxa_workspaceRow:hover,.d0xfxa_workspaceRow:focus-visible,.d0xfxa_workspaceRow[aria-current=page]{background:var(--dsw-alias-interactive-bg-hover);outline:none}.d0xfxa_workspaceRow:focus-visible{box-shadow:inset 0 0 0 1px var(--dsw-alias-border-l3)}.d0xfxa_workspaceIcon{color:var(--dsw-alias-label-tertiary);flex:0 0 16px;justify-content:center;align-items:center;height:20px;display:inline-flex}.d0xfxa_workspaceRow[data-selected] .d0xfxa_workspaceIcon{color:var(--dsw-alias-state-business-primary)}.d0xfxa_workspaceCopy{min-width:0;display:flex}.d0xfxa_workspaceCopy strong{text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:400;line-height:20px;overflow:hidden}.d0xfxa_emptyState{color:var(--dsw-alias-label-tertiary);margin:8px;font-size:12px;line-height:18px}.d0xfxa_railWorkspace{flex-direction:column;align-items:center;gap:8px;padding-top:8px;display:flex}.d0xfxa_railButton{border-radius:50%;width:36px;height:36px}.d0xfxa_railButton[data-active]{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.d0xfxa_workspaceSection{flex-direction:column;flex:1;gap:4px;min-height:0;margin-top:2px;display:flex;overflow-y:auto}.d0xfxa_section{flex-direction:column;display:flex}.d0xfxa_sectionHeader{align-items:center;min-height:26px;padding-right:2px;display:flex}.d0xfxa_sectionToggle{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;align-items:center;gap:4px;min-width:0;min-height:24px;padding:0 6px;font-size:12px;line-height:18px;display:inline-flex}.d0xfxa_sectionToggle:focus-visible{outline:none}.d0xfxa_sectionToggle:hover .d0xfxa_sectionChevron,.d0xfxa_sectionToggle:focus-visible .d0xfxa_sectionChevron{color:var(--dsw-alias-label-primary)}.d0xfxa_sectionChevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .12s,color .12s}.d0xfxa_sectionToggle[aria-expanded=false] .d0xfxa_sectionChevron{transform:rotate(-90deg)}.d0xfxa_sectionTitle{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.d0xfxa_sectionActions{align-items:center;margin-left:auto;display:inline-flex}.d0xfxa_panel{flex-direction:column;display:flex}.d0xfxa_iconButton{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:50%;justify-content:center;align-items:center;width:24px;height:24px;padding:0;display:inline-flex}.d0xfxa_iconButton:hover,.d0xfxa_iconButton:focus-visible{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);outline:none}.d0xfxa_textButton{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:5px;padding:2px 5px;font-size:11px;line-height:18px}.d0xfxa_textButton:hover,.d0xfxa_textButton:focus-visible{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);outline:none}.d0xfxa_textButton:disabled{cursor:not-allowed;opacity:.4}.d0xfxa_channelList,.d0xfxa_agentList{flex-direction:column;gap:1px;padding:0 4px 4px;display:flex}.d0xfxa_sidebarRowDragging{opacity:.5}.d0xfxa_sidebarRowDropBefore,.d0xfxa_sidebarRowDropAfter{position:relative}.d0xfxa_sidebarRowDropBefore:before,.d0xfxa_sidebarRowDropAfter:after{content:\"\";z-index:1;background:linear-gradient(55deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 0 / 5px 7px no-repeat, linear-gradient(125deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 5px / 5px 7px no-repeat, linear-gradient(var(--dsw-alias-state-business-primary) 0 0) 4px 5px / calc(100% - 4px) 2px no-repeat;pointer-events:none;height:12px;position:absolute;left:0;right:4px}.d0xfxa_sidebarRowDropBefore:before{top:-7px}.d0xfxa_sidebarRowDropAfter:after{bottom:-7px}.d0xfxa_channelRow{color:var(--dsw-alias-label-primary);border-radius:8px;align-items:center;min-height:30px;display:flex;position:relative}.d0xfxa_channelSelect{box-sizing:border-box;color:inherit;cursor:pointer;text-align:left;background:0 0;border:0;flex:1;align-items:center;min-width:0;min-height:30px;padding:3px 4px 3px 8px;display:flex}.d0xfxa_channelSelect:focus-visible{outline:none}.d0xfxa_channelName{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:400;line-height:18px;overflow:hidden}.d0xfxa_agentRow{color:var(--dsw-alias-label-primary);border-radius:8px;align-items:center;min-height:38px;display:flex;position:relative}.d0xfxa_agentSelect{box-sizing:border-box;color:inherit;cursor:pointer;text-align:left;background:0 0;border:0;flex:1;grid-template-columns:24px minmax(0,1fr);align-items:center;gap:0 8px;min-width:0;min-height:38px;padding:3px 4px 3px 8px;display:grid}.d0xfxa_agentSelect:focus-visible{outline:none}.d0xfxa_agentSelect[aria-current=page]{background:var(--dsw-alias-interactive-bg-hover);border-radius:8px}.d0xfxa_agentRow:hover .d0xfxa_agentSelect[aria-current=page],.d0xfxa_agentRow:focus-within .d0xfxa_agentSelect[aria-current=page],.d0xfxa_agentRow[data-menu-open] .d0xfxa_agentSelect[aria-current=page]{background:0 0}.d0xfxa_agentAvatar{background:hsl(var(--team-avatar-hue,212) 42% 46%);color:#fff;cursor:default;border-radius:50%;flex:0 0 24px;justify-content:center;align-items:center;width:24px;height:24px;font-size:11px;font-weight:600;display:inline-flex;position:relative}.d0xfxa_agentAvatarBadge{background:var(--dsw-specific-sidebar-fill);box-shadow:0 0 0 1px var(--dsw-specific-sidebar-fill);border-radius:50%;justify-content:center;align-items:center;width:12px;height:12px;padding:1px;line-height:0;display:inline-flex;position:absolute;bottom:-3px;right:-3px}.d0xfxa_agentCopy{flex-direction:column;min-width:0;display:flex}.d0xfxa_agentCopy strong{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:400;line-height:17px;overflow:hidden}.d0xfxa_agentCopy small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:13px;overflow:hidden}.d0xfxa_unavailableDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;width:7px;height:7px;display:inline-block}.d0xfxa_rowMenu{flex:none;align-items:center;padding-right:4px;display:none}.d0xfxa_channelRow:hover .d0xfxa_rowMenu,.d0xfxa_channelRow:focus-within .d0xfxa_rowMenu,.d0xfxa_channelRow[data-menu-open] .d0xfxa_rowMenu,.d0xfxa_agentRow:hover .d0xfxa_rowMenu,.d0xfxa_agentRow:focus-within .d0xfxa_rowMenu,.d0xfxa_agentRow[data-menu-open] .d0xfxa_rowMenu{display:inline-flex}.d0xfxa_channelRow[data-menu-open],.d0xfxa_agentRow[data-menu-open],.d0xfxa_channelRow:hover,.d0xfxa_agentRow:hover,.d0xfxa_channelRow:focus-within,.d0xfxa_agentRow:focus-within,.d0xfxa_channelRow[aria-current=page]{background:var(--dsw-alias-interactive-bg-hover)}.d0xfxa_rowMenuButton{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;justify-content:center;align-items:center;width:20px;height:20px;padding:0;display:inline-flex}.d0xfxa_rowMenuButton:hover,.d0xfxa_rowMenuButton:focus-visible{color:var(--dsw-alias-label-primary);outline:none}.d0xfxa_retryError{color:var(--dsw-alias-state-error-primary);justify-content:space-between;align-items:center;gap:8px;padding:8px;font-size:11px;display:flex}.d0xfxa_rowAlert{color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;padding:2px 8px 6px;font-size:11px}.d0xfxa_editDescription{color:var(--dsw-alias-label-secondary);margin:0 0 10px;font-size:12px;line-height:18px}.d0xfxa_editMemberList{gap:3px;display:grid}.d0xfxa_editMemberRow{border-radius:6px;grid-template-columns:14px minmax(0,1fr) auto;align-items:center;gap:0 8px;min-height:40px;padding:3px 6px;display:grid}.d0xfxa_editMemberRowChannels{grid-template-columns:minmax(0,1fr) auto}.d0xfxa_editMemberRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.d0xfxa_editMemberCopy{min-width:0;display:grid}.d0xfxa_editMemberCopy strong{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:500;line-height:18px;overflow:hidden}.d0xfxa_editMemberCopy small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:14px;overflow:hidden}.d0xfxa_editChannelName{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:400;line-height:18px;overflow:hidden}.d0xfxa_editMemberRow button{min-width:60px}.d0xfxa_editHint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:11px;line-height:16px}.d0xfxa_menuHint{color:var(--dsw-alias-label-tertiary);margin-left:4px;font-size:10px;line-height:14px}.d0xfxa_rowError{color:var(--dsw-alias-state-error-primary);grid-column:1/-1;margin:2px 0;font-size:11px;line-height:16px}";
8896
9231
  const tagId$1 = "@wowyuarm/dsh-agent-team/sidebar.module.css";
8897
9232
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
8898
9233
  const tag = document.createElement("style");
@@ -8926,6 +9261,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8926
9261
  "railButton": "d0xfxa_railButton",
8927
9262
  "railWorkspace": "d0xfxa_railWorkspace",
8928
9263
  "retryError": "d0xfxa_retryError",
9264
+ "rowAlert": "d0xfxa_rowAlert",
8929
9265
  "rowError": "d0xfxa_rowError",
8930
9266
  "rowMenu": "d0xfxa_rowMenu",
8931
9267
  "rowMenuButton": "d0xfxa_rowMenuButton",
@@ -8942,7 +9278,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8942
9278
  "unavailableDot": "d0xfxa_unavailableDot",
8943
9279
  "workspaceBrowser": "d0xfxa_workspaceBrowser",
8944
9280
  "workspaceCopy": "d0xfxa_workspaceCopy",
8945
- "workspaceHeader": "d0xfxa_workspaceHeader",
8946
9281
  "workspaceIcon": "d0xfxa_workspaceIcon",
8947
9282
  "workspaceList": "d0xfxa_workspaceList",
8948
9283
  "workspaceRow": "d0xfxa_workspaceRow",
@@ -8971,6 +9306,33 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8971
9306
  });
8972
9307
  }
8973
9308
  //#endregion
9309
+ //#region src/client/TeamSidebarSection.tsx
9310
+ /** Collapsible sidebar section header: disclosure toggle plus trailing actions. */
9311
+ function TeamSidebarSection({ title, actions, children }) {
9312
+ const [open, setOpen] = (0, react.useState)(true);
9313
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
9314
+ className: sidebar_module_css_default.section,
9315
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9316
+ className: sidebar_module_css_default.sectionHeader,
9317
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
9318
+ type: "button",
9319
+ className: sidebar_module_css_default.sectionToggle,
9320
+ "aria-expanded": open,
9321
+ onClick: () => {
9322
+ setOpen((value) => !value);
9323
+ },
9324
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: sidebar_module_css_default.sectionChevron }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9325
+ className: sidebar_module_css_default.sectionTitle,
9326
+ children: title
9327
+ })]
9328
+ }), actions !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9329
+ className: sidebar_module_css_default.sectionActions,
9330
+ children: actions
9331
+ })]
9332
+ }), open && children]
9333
+ });
9334
+ }
9335
+ //#endregion
8974
9336
  //#region src/client/TeamMemberAvatar.tsx
8975
9337
  /**
8976
9338
  * Sidebar Member avatar reusing the conversation identity language: the
@@ -9274,33 +9636,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9274
9636
  });
9275
9637
  }
9276
9638
  //#endregion
9277
- //#region src/client/TeamSidebarSection.tsx
9278
- /** Collapsible sidebar section header: disclosure toggle plus trailing actions. */
9279
- function TeamSidebarSection({ title, actions, children }) {
9280
- const [open, setOpen] = (0, react.useState)(true);
9281
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
9282
- className: sidebar_module_css_default.section,
9283
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9284
- className: sidebar_module_css_default.sectionHeader,
9285
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
9286
- type: "button",
9287
- className: sidebar_module_css_default.sectionToggle,
9288
- "aria-expanded": open,
9289
- onClick: () => {
9290
- setOpen((value) => !value);
9291
- },
9292
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: sidebar_module_css_default.sectionChevron }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9293
- className: sidebar_module_css_default.sectionTitle,
9294
- children: title
9295
- })]
9296
- }), actions !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9297
- className: sidebar_module_css_default.sectionActions,
9298
- children: actions
9299
- })]
9300
- }), open && children]
9301
- });
9302
- }
9303
- //#endregion
9304
9639
  //#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/create.module.css.mjs
9305
9640
  const css = "._1henIG_form{gap:16px;display:grid}._1henIG_field{color:var(--dsw-alias-label-secondary);gap:6px;font-size:12px;line-height:18px;display:grid}._1henIG_input{box-sizing:border-box;width:100%}._1henIG_menuCap{max-height:min(320px,56vh)}._1henIG_selectTrigger{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);box-sizing:border-box;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;border-radius:8px;justify-content:space-between;align-items:center;gap:8px;min-height:32px;padding:4px 10px;font-size:14px;line-height:22px;display:flex}._1henIG_selectTrigger:disabled{cursor:default;opacity:.6}._1henIG_selectTrigger:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}._1henIG_selectValue{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}._1henIG_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .12s;display:inline-flex}._1henIG_chevronOpen{transform:rotate(180deg)}._1henIG_memberPicker{border:0;gap:4px;max-height:220px;margin:0;padding:0;display:grid;overflow-y:auto}._1henIG_memberPicker legend{color:var(--dsw-alias-label-secondary);padding:0 0 6px;font-size:12px;line-height:18px}._1henIG_memberOption{color:var(--dsw-alias-label-primary);border-radius:6px;grid-template-columns:auto 14px minmax(0,1fr);align-items:center;gap:0 7px;min-height:32px;padding:3px 6px;display:grid}._1henIG_memberOption:hover{background:var(--dsw-alias-interactive-bg-hover)}._1henIG_memberOption input{margin:0}._1henIG_memberOption small{color:var(--dsw-alias-label-tertiary);grid-column:3;font-size:10px;line-height:14px}._1henIG_unavailableDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;justify-self:center;width:7px;height:7px;display:inline-block}._1henIG_error{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:18px}._1henIG_dialogContent{max-height:min(70vh,560px);overflow-y:auto}@media (width<=600px){._1henIG_dialogContent{max-height:calc(100vh - 180px)}._1henIG_memberPicker{max-height:180px}}";
9306
9641
  const tagId = "@wowyuarm/dsh-agent-team/create.module.css";
@@ -9390,368 +9725,26 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9390
9725
  });
9391
9726
  }
9392
9727
  //#endregion
9393
- //#region src/client/TeamAgentsPanel.tsx
9394
- function TeamAgentsPanel({ workspaceId, loadMembers, subscribeChanges, loadChannels, addMember, updateMember, recoverMember, joinChannel, removeChannelMember, loadModels, memberSessionId, openMemberSession, onCreatingChange, t }) {
9395
- const [members, setMembers] = (0, react.useState)([]);
9396
- const [channels, setChannels] = (0, react.useState)([]);
9397
- const [channelRefs, setChannelRefs] = (0, react.useState)([]);
9398
- const [loading, setLoading] = (0, react.useState)(true);
9399
- const [error, setError] = (0, react.useState)();
9400
- const [formOpen, setFormOpen] = (0, react.useState)(false);
9401
- const [handle, setHandle] = (0, react.useState)("");
9402
- const [description, setDescription] = (0, react.useState)("");
9403
- const [model, setModel] = (0, react.useState)(void 0);
9404
- const [creating, setCreating] = (0, react.useState)(false);
9405
- const [retryRequest, setRetryRequest] = (0, react.useState)();
9406
- const triggerRef = (0, react.useRef)(null);
9407
- const orderedAgentRefs = useSidebarOrder(workspaceId, "agents", (0, react.useMemo)(() => members.map((status) => status.member.memberId), [members]));
9408
- const orderedMembers = (0, react.useMemo)(() => {
9409
- const byId = new Map(members.map((status) => [status.member.memberId, status]));
9410
- return orderedAgentRefs.map((memberId) => byId.get(memberId)).filter((status) => status !== void 0);
9411
- }, [orderedAgentRefs, members]);
9412
- const applyMove = (movedRef, targetRef, marker) => {
9413
- moveSidebarItem(workspaceId, "agents", orderedAgentRefs, movedRef, targetRef, marker);
9414
- };
9415
- const drag = useSidebarRowDrag({
9416
- refs: orderedAgentRefs,
9417
- onCommit: applyMove
9418
- });
9419
- const refresh = (0, react.useCallback)(async () => {
9420
- setLoading(true);
9421
- const result = await loadMembers({ workspaceId });
9422
- if (result.ok) {
9423
- setMembers(result.value);
9424
- setError(void 0);
9425
- } else setError(result.error.message);
9426
- setLoading(false);
9427
- }, [loadMembers, workspaceId]);
9428
- (0, react.useEffect)(() => {
9429
- refresh();
9430
- }, [refresh]);
9431
- const loadWorkspaceChannels = (0, react.useCallback)(async () => {
9432
- const result = await loadChannels({
9433
- workspaceId,
9434
- topLevelOnly: true,
9435
- includeActivities: false,
9436
- limit: 1
9437
- });
9438
- if (result.ok) setChannels(result.value.channels);
9439
- }, [loadChannels, workspaceId]);
9728
+ //#region src/client/TeamMemberEditor.tsx
9729
+ /** Model option key inside one editor; opaque and resolved against the loaded groups. */
9730
+ function modelKey(provider, model) {
9731
+ return `${provider}\u0000${model}`;
9732
+ }
9733
+ /**
9734
+ * Shared provider/model dropdown for the create and edit forms. The option
9735
+ * list rides the shared Menu primitive (one leading "follow Host default"
9736
+ * row, then non-selectable provider headings) with a capped, internally
9737
+ * scrolling card so growing model catalogs cannot stretch the dialog.
9738
+ */
9739
+ function ModelPickerField({ model, onModelChange, loadModels, disabled, t }) {
9740
+ const [groups, setGroups] = (0, react.useState)();
9741
+ const [modelsError, setModelsError] = (0, react.useState)();
9742
+ const [open, setModelOpen] = (0, react.useState)(false);
9743
+ const [effortOpen, setEffortOpen] = (0, react.useState)(false);
9440
9744
  (0, react.useEffect)(() => {
9441
- loadWorkspaceChannels();
9442
- }, [loadWorkspaceChannels]);
9443
- (0, react.useEffect)(() => subscribeChanges({
9444
- kind: "workspace",
9445
- workspaceId
9446
- }, (update) => {
9447
- if (update.type === "failed") {
9448
- setError(update.message);
9449
- return;
9450
- }
9451
- refresh();
9452
- loadWorkspaceChannels();
9453
- }), [
9454
- subscribeChanges,
9455
- refresh,
9456
- loadWorkspaceChannels,
9457
- workspaceId
9458
- ]);
9459
- const closeForm = () => {
9460
- if (creating) return;
9461
- setFormOpen(false);
9462
- queueMicrotask(() => {
9463
- triggerRef.current?.focus();
9464
- });
9465
- };
9466
- const provision = async (request) => {
9467
- setCreating(true);
9468
- onCreatingChange(request, true);
9469
- setError(void 0);
9470
- setRetryRequest(request);
9471
- try {
9472
- const result = await addMember(request);
9473
- if (result.ok) {
9474
- setMembers((current) => {
9475
- return [...current.filter((status) => status.member.memberId !== result.value.status.member.memberId), result.value.status];
9476
- });
9477
- setHandle("");
9478
- setDescription("");
9479
- setModel(void 0);
9480
- setChannelRefs([]);
9481
- setFormOpen(false);
9482
- if (result.value.status.presence === "unavailable") setError(result.value.status.diagnostic ?? t("statusUnavailable"));
9483
- else setRetryRequest(void 0);
9484
- queueMicrotask(() => {
9485
- triggerRef.current?.focus();
9486
- });
9487
- } else {
9488
- await refresh();
9489
- setError(result.error.message);
9490
- }
9491
- } catch (cause) {
9492
- setError(cause instanceof Error ? cause.message : String(cause));
9493
- } finally {
9494
- setCreating(false);
9495
- onCreatingChange(request, false);
9496
- }
9497
- };
9498
- const submit = (event) => {
9499
- event.preventDefault();
9500
- const normalizedHandle = handle.trim();
9501
- const normalizedDescription = description.trim();
9502
- if (normalizedHandle.length === 0 || creating) return;
9503
- provision(retryRequest !== void 0 && retryRequest.workspaceId === workspaceId && retryRequest.handle === normalizedHandle && retryRequest.description === normalizedDescription && sameModel(retryRequest.model, model) && retryRequest.channelRefs.length === channelRefs.length && retryRequest.channelRefs.every((ref) => channelRefs.includes(ref)) ? retryRequest : {
9504
- requestId: crypto.randomUUID(),
9505
- workspaceId,
9506
- handle: normalizedHandle,
9507
- description: normalizedDescription,
9508
- presetId: "team-member",
9509
- channelRefs,
9510
- ...model === void 0 ? {} : { model }
9511
- });
9512
- };
9513
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9514
- className: sidebar_module_css_default.panel,
9515
- children: [
9516
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
9517
- open: formOpen,
9518
- onClose: closeForm,
9519
- title: t("addAgent"),
9520
- closeLabel: t("close"),
9521
- contentClassName: create_module_css_default.dialogContent,
9522
- footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9523
- variant: "outline",
9524
- disabled: creating,
9525
- onClick: closeForm,
9526
- children: t("cancel")
9527
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9528
- type: "submit",
9529
- form: "team-agent-create-form",
9530
- variant: "primary",
9531
- disabled: creating || handle.trim().length === 0,
9532
- children: creating ? t("creatingAgent") : t("createAgent")
9533
- })] }),
9534
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
9535
- id: "team-agent-create-form",
9536
- className: create_module_css_default.form,
9537
- onSubmit: submit,
9538
- children: [
9539
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
9540
- className: create_module_css_default.field,
9541
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("agentName") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
9542
- className: create_module_css_default.input,
9543
- value: handle,
9544
- onChange: (event) => {
9545
- setHandle(event.target.value);
9546
- setRetryRequest(void 0);
9547
- },
9548
- disabled: creating,
9549
- autoFocus: true
9550
- })]
9551
- }),
9552
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
9553
- className: create_module_css_default.field,
9554
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [t("agentDescription"), t("optionalSuffix")] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
9555
- className: create_module_css_default.input,
9556
- value: description,
9557
- placeholder: t("agentDescriptionPlaceholder"),
9558
- onChange: (event) => {
9559
- setDescription(event.target.value);
9560
- setRetryRequest(void 0);
9561
- },
9562
- disabled: creating
9563
- })]
9564
- }),
9565
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelPickerField, {
9566
- model,
9567
- onModelChange: (choice) => {
9568
- setModel(choice);
9569
- setRetryRequest(void 0);
9570
- },
9571
- loadModels,
9572
- disabled: creating,
9573
- t
9574
- }),
9575
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MultiMenuField, {
9576
- label: `${t("initialChannels")}${t("optionalSuffix")}`,
9577
- disabled: creating,
9578
- options: channels.map((channel) => ({
9579
- id: channel.channelRef,
9580
- label: channel.name
9581
- })),
9582
- selected: channelRefs,
9583
- onToggle: (ref) => {
9584
- setChannelRefs((current) => current.includes(ref) ? current.filter((item) => item !== ref) : [...current, ref]);
9585
- setRetryRequest(void 0);
9586
- },
9587
- emptyText: t("noChannelsForAgent"),
9588
- triggerEmptyLabel: t("channelsPickerEmpty"),
9589
- formatCount: (count) => t("channelsPickerCount", { count })
9590
- }),
9591
- formOpen && error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
9592
- className: create_module_css_default.error,
9593
- role: "alert",
9594
- children: error
9595
- })
9596
- ]
9597
- })
9598
- }),
9599
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(TeamSidebarSection, {
9600
- title: t("agents"),
9601
- actions: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
9602
- label: t("addAgent"),
9603
- delayMs: 500,
9604
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
9605
- ref: triggerRef,
9606
- type: "button",
9607
- className: sidebar_module_css_default.iconButton,
9608
- "aria-label": t("addAgent"),
9609
- onClick: () => {
9610
- setError(void 0);
9611
- setFormOpen(true);
9612
- },
9613
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, { size: 14 })
9614
- })
9615
- }),
9616
- children: [
9617
- loading && members.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
9618
- className: sidebar_module_css_default.emptyState,
9619
- children: t("loadingAgents")
9620
- }),
9621
- !loading && members.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
9622
- className: sidebar_module_css_default.emptyState,
9623
- children: t("emptyAgents")
9624
- }),
9625
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9626
- className: sidebar_module_css_default.agentList,
9627
- children: orderedMembers.map((status) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortableRow, {
9628
- drag,
9629
- orderKey: status.member.memberId,
9630
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AgentRow, {
9631
- status,
9632
- ...memberSessionId === void 0 ? {} : { current: status.member.sessionId === memberSessionId },
9633
- channels,
9634
- loadChannels,
9635
- updateMember,
9636
- recoverMember,
9637
- joinChannel,
9638
- removeChannelMember,
9639
- loadModels,
9640
- openMemberSession,
9641
- onUpdated: () => {
9642
- refresh();
9643
- },
9644
- t
9645
- })
9646
- }, status.member.memberId))
9647
- })
9648
- ]
9649
- }),
9650
- !formOpen && error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9651
- className: sidebar_module_css_default.retryError,
9652
- role: "alert",
9653
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: error }), retryRequest !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
9654
- type: "button",
9655
- className: sidebar_module_css_default.textButton,
9656
- disabled: creating,
9657
- onClick: () => {
9658
- setFormOpen(true);
9659
- },
9660
- children: t("retry")
9661
- })]
9662
- })
9663
- ]
9664
- });
9665
- }
9666
- /**
9667
- * One sidebar Agent row: the select button opens the Member's own Session
9668
- * conversation page, the avatar carries identity plus the presence badge, and
9669
- * the row menu opens the editor.
9670
- */
9671
- function AgentRow({ status, current, channels, loadChannels, updateMember, recoverMember, joinChannel, removeChannelMember, loadModels, openMemberSession, onUpdated, t }) {
9672
- const [menuOpen, setMenuOpen] = (0, react.useState)(false);
9673
- const [editing, setEditing] = (0, react.useState)(false);
9674
- const resume = async () => {
9675
- await recoverMember({
9676
- requestId: crypto.randomUUID(),
9677
- workspaceId: status.member.workspaceId,
9678
- memberId: status.member.memberId
9679
- });
9680
- await onUpdated();
9681
- };
9682
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9683
- className: sidebar_module_css_default.agentRow,
9684
- "data-menu-open": menuOpen || void 0,
9685
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
9686
- type: "button",
9687
- className: sidebar_module_css_default.agentSelect,
9688
- "aria-label": t("openAgentSession", { name: status.member.handle }),
9689
- "aria-current": current ? "page" : void 0,
9690
- disabled: status.availability !== "active",
9691
- onClick: () => {
9692
- openMemberSession(status.member.sessionId);
9693
- },
9694
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamMemberAvatar, {
9695
- status,
9696
- t
9697
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
9698
- className: sidebar_module_css_default.agentCopy,
9699
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: status.member.handle }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: status.member.description })]
9700
- })]
9701
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9702
- className: sidebar_module_css_default.rowMenu,
9703
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamRowMenu, {
9704
- label: t("actionsAgent", { name: status.member.handle }),
9705
- items: [{
9706
- id: "edit",
9707
- label: t("editAgent"),
9708
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, {})
9709
- }, ...status.presence === "error" ? [{
9710
- id: "resume",
9711
- label: t("resumeAgent"),
9712
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlayOutline16, {})
9713
- }] : []],
9714
- onSelect: (id) => {
9715
- if (id === "resume") resume();
9716
- else setEditing(true);
9717
- },
9718
- onOpenChange: setMenuOpen
9719
- })
9720
- })]
9721
- }), editing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AgentEditorDialog, {
9722
- status,
9723
- channels,
9724
- loadChannels,
9725
- updateMember,
9726
- joinChannel,
9727
- removeChannelMember,
9728
- loadModels,
9729
- onCommitted: onUpdated,
9730
- onClose: () => {
9731
- setEditing(false);
9732
- },
9733
- t
9734
- })] });
9735
- }
9736
- /** Model option key inside one editor; opaque and resolved against the loaded groups. */
9737
- function modelKey(provider, model) {
9738
- return `${provider}\u0000${model}`;
9739
- }
9740
- /**
9741
- * Shared provider/model dropdown for the create and edit forms. The option
9742
- * list rides the shared Menu primitive (one leading "follow Host default"
9743
- * row, then non-selectable provider headings) with a capped, internally
9744
- * scrolling card so growing model catalogs cannot stretch the dialog.
9745
- */
9746
- function ModelPickerField({ model, onModelChange, loadModels, disabled, t }) {
9747
- const [groups, setGroups] = (0, react.useState)();
9748
- const [modelsError, setModelsError] = (0, react.useState)();
9749
- const [open, setModelOpen] = (0, react.useState)(false);
9750
- const [effortOpen, setEffortOpen] = (0, react.useState)(false);
9751
- (0, react.useEffect)(() => {
9752
- let mounted = true;
9753
- loadModels().then((result) => {
9754
- if (!mounted) return;
9745
+ let mounted = true;
9746
+ loadModels().then((result) => {
9747
+ if (!mounted) return;
9755
9748
  if (result.ok) {
9756
9749
  setGroups(result.value.groups);
9757
9750
  setModelsError(void 0);
@@ -9949,147 +9942,522 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9949
9942
  ...model === void 0 ? {} : { model }
9950
9943
  };
9951
9944
  const request = pendingRequest.current !== void 0 && pendingRequest.current.memberId === payload.memberId && pendingRequest.current.handle === payload.handle && pendingRequest.current.description === payload.description && sameModel(pendingRequest.current.model, model) ? pendingRequest.current : {
9952
- requestId: crypto.randomUUID(),
9945
+ requestId: mintRequestId(),
9953
9946
  ...payload
9954
9947
  };
9955
9948
  pendingRequest.current = request;
9956
9949
  setSaving(true);
9957
9950
  setError(void 0);
9958
9951
  try {
9959
- const result = await updateMember(request);
9960
- if (result.ok) {
9961
- pendingRequest.current = void 0;
9962
- await onCommitted();
9963
- onClose();
9964
- } else setError(result.error.message);
9952
+ const result = await updateMember(request);
9953
+ if (result.ok) {
9954
+ pendingRequest.current = void 0;
9955
+ await onCommitted();
9956
+ onClose();
9957
+ } else setError(result.error.message);
9958
+ } catch (cause) {
9959
+ setError(cause instanceof Error ? cause.message : String(cause));
9960
+ } finally {
9961
+ setSaving(false);
9962
+ }
9963
+ };
9964
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
9965
+ open: true,
9966
+ onClose,
9967
+ title: t("editAgent"),
9968
+ description: `@${status.member.handle}`,
9969
+ closeLabel: t("close"),
9970
+ contentClassName: create_module_css_default.dialogContent,
9971
+ footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9972
+ variant: "outline",
9973
+ disabled: saving,
9974
+ onClick: onClose,
9975
+ children: t("cancel")
9976
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9977
+ type: "submit",
9978
+ form: "team-agent-edit-form",
9979
+ variant: "primary",
9980
+ disabled: saving || !dirty || handle.trim().length === 0,
9981
+ children: saving ? t("editSaving") : t("editSave")
9982
+ })] }),
9983
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
9984
+ id: "team-agent-edit-form",
9985
+ className: create_module_css_default.form,
9986
+ onSubmit: (event) => {
9987
+ submit(event);
9988
+ },
9989
+ children: [
9990
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
9991
+ className: create_module_css_default.field,
9992
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("agentName") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
9993
+ className: create_module_css_default.input,
9994
+ value: handle,
9995
+ onChange: (event) => {
9996
+ setHandle(event.target.value);
9997
+ pendingRequest.current = void 0;
9998
+ },
9999
+ disabled: saving,
10000
+ autoFocus: true
10001
+ })]
10002
+ }),
10003
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
10004
+ className: create_module_css_default.field,
10005
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [t("agentDescription"), t("optionalSuffix")] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
10006
+ className: create_module_css_default.input,
10007
+ value: description,
10008
+ placeholder: t("agentDescriptionPlaceholder"),
10009
+ onChange: (event) => {
10010
+ setDescription(event.target.value);
10011
+ pendingRequest.current = void 0;
10012
+ },
10013
+ disabled: saving
10014
+ })]
10015
+ }),
10016
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelPickerField, {
10017
+ model,
10018
+ onModelChange: (choice) => {
10019
+ pendingRequest.current = void 0;
10020
+ setModel(choice);
10021
+ },
10022
+ loadModels,
10023
+ disabled: saving,
10024
+ t
10025
+ }),
10026
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
10027
+ className: create_module_css_default.memberPicker,
10028
+ disabled: saving,
10029
+ children: [
10030
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", { children: t("channelMembersSection") }),
10031
+ channels.map((channel) => {
10032
+ const joined = joinedChannels.has(channel.channelRef);
10033
+ const rowPending = membership.pending.has(channel.channelRef);
10034
+ const disabled = rowPending || !joined && status.presence === "unavailable";
10035
+ const rowError = membership.errors.get(channel.channelRef);
10036
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10037
+ className: `${sidebar_module_css_default.editMemberRow} ${sidebar_module_css_default.editMemberRowChannels}`,
10038
+ children: [
10039
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", {
10040
+ className: sidebar_module_css_default.editChannelName,
10041
+ children: ["# ", channel.name]
10042
+ }),
10043
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
10044
+ size: "sm",
10045
+ variant: "outline",
10046
+ disabled,
10047
+ onClick: () => {
10048
+ membership.change({
10049
+ workspaceId: status.member.workspaceId,
10050
+ channelRef: channel.channelRef,
10051
+ memberId,
10052
+ joined
10053
+ });
10054
+ },
10055
+ children: rowPending ? t("membershipUpdating") : joined ? t("removeFromChannel") : t("addToChannel")
10056
+ }),
10057
+ rowError !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
10058
+ className: sidebar_module_css_default.rowError,
10059
+ role: "alert",
10060
+ children: rowError
10061
+ })
10062
+ ]
10063
+ }, channel.channelRef);
10064
+ }),
10065
+ channels.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("noChannelsForAgent") }),
10066
+ loadError !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
10067
+ className: sidebar_module_css_default.rowError,
10068
+ role: "alert",
10069
+ children: loadError
10070
+ })
10071
+ ]
10072
+ }),
10073
+ error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
10074
+ className: create_module_css_default.error,
10075
+ role: "alert",
10076
+ children: error
10077
+ })
10078
+ ]
10079
+ })
10080
+ });
10081
+ }
10082
+ function sameModel(left, right) {
10083
+ if (left === void 0 && right === void 0) return true;
10084
+ if (left === void 0 || right === void 0) return false;
10085
+ return left.provider === right.provider && left.model === right.model && left.reasoningEffort === right.reasoningEffort;
10086
+ }
10087
+ //#endregion
10088
+ //#region src/client/TeamAgentsPanel.tsx
10089
+ function TeamAgentsPanel({ workspaceId, loadMembers, subscribeChanges, loadChannels, addMember, updateMember, recoverMember, joinChannel, removeChannelMember, loadModels, memberSessionId, openMemberSession, onCreatingChange, t }) {
10090
+ const [members, setMembers] = (0, react.useState)([]);
10091
+ const [channels, setChannels] = (0, react.useState)([]);
10092
+ const [channelRefs, setChannelRefs] = (0, react.useState)([]);
10093
+ const [loading, setLoading] = (0, react.useState)(true);
10094
+ const [error, setError] = (0, react.useState)();
10095
+ const [formOpen, setFormOpen] = (0, react.useState)(false);
10096
+ const [handle, setHandle] = (0, react.useState)("");
10097
+ const [description, setDescription] = (0, react.useState)("");
10098
+ const [model, setModel] = (0, react.useState)(void 0);
10099
+ const [creating, setCreating] = (0, react.useState)(false);
10100
+ const [retryRequest, setRetryRequest] = (0, react.useState)();
10101
+ const triggerRef = (0, react.useRef)(null);
10102
+ const orderedAgentRefs = useSidebarOrder(workspaceId, "agents", (0, react.useMemo)(() => members.map((status) => status.member.memberId), [members]));
10103
+ const orderedMembers = (0, react.useMemo)(() => {
10104
+ const byId = new Map(members.map((status) => [status.member.memberId, status]));
10105
+ return orderedAgentRefs.map((memberId) => byId.get(memberId)).filter((status) => status !== void 0);
10106
+ }, [orderedAgentRefs, members]);
10107
+ const applyMove = (movedRef, targetRef, marker) => {
10108
+ moveSidebarItem(workspaceId, "agents", orderedAgentRefs, movedRef, targetRef, marker);
10109
+ };
10110
+ const drag = useSidebarRowDrag({
10111
+ refs: orderedAgentRefs,
10112
+ onCommit: applyMove
10113
+ });
10114
+ const refresh = (0, react.useCallback)(async () => {
10115
+ setLoading(true);
10116
+ const result = await loadMembers({ workspaceId });
10117
+ if (result.ok) {
10118
+ setMembers(result.value);
10119
+ setError(void 0);
10120
+ } else setError(result.error.message);
10121
+ setLoading(false);
10122
+ }, [loadMembers, workspaceId]);
10123
+ (0, react.useEffect)(() => {
10124
+ refresh();
10125
+ }, [refresh]);
10126
+ const loadWorkspaceChannels = (0, react.useCallback)(async () => {
10127
+ const result = await loadChannels({
10128
+ workspaceId,
10129
+ topLevelOnly: true,
10130
+ includeActivities: false,
10131
+ limit: 1
10132
+ });
10133
+ if (result.ok) setChannels(result.value.channels);
10134
+ }, [loadChannels, workspaceId]);
10135
+ (0, react.useEffect)(() => {
10136
+ loadWorkspaceChannels();
10137
+ }, [loadWorkspaceChannels]);
10138
+ (0, react.useEffect)(() => subscribeChanges({
10139
+ kind: "workspace",
10140
+ workspaceId
10141
+ }, (update) => {
10142
+ if (update.type === "failed") {
10143
+ setError(update.message);
10144
+ return;
10145
+ }
10146
+ refresh();
10147
+ loadWorkspaceChannels();
10148
+ }), [
10149
+ subscribeChanges,
10150
+ refresh,
10151
+ loadWorkspaceChannels,
10152
+ workspaceId
10153
+ ]);
10154
+ const closeForm = () => {
10155
+ if (creating) return;
10156
+ setFormOpen(false);
10157
+ queueMicrotask(() => {
10158
+ triggerRef.current?.focus();
10159
+ });
10160
+ };
10161
+ const provision = async (request) => {
10162
+ setCreating(true);
10163
+ onCreatingChange(request, true);
10164
+ setError(void 0);
10165
+ setRetryRequest(request);
10166
+ try {
10167
+ const result = await addMember(request);
10168
+ if (result.ok) {
10169
+ setMembers((current) => {
10170
+ return [...current.filter((status) => status.member.memberId !== result.value.status.member.memberId), result.value.status];
10171
+ });
10172
+ setHandle("");
10173
+ setDescription("");
10174
+ setModel(void 0);
10175
+ setChannelRefs([]);
10176
+ setFormOpen(false);
10177
+ if (result.value.status.presence === "unavailable") setError(result.value.status.diagnostic ?? t("statusUnavailable"));
10178
+ else setRetryRequest(void 0);
10179
+ queueMicrotask(() => {
10180
+ triggerRef.current?.focus();
10181
+ });
10182
+ } else {
10183
+ await refresh();
10184
+ setError(result.error.message);
10185
+ }
10186
+ } catch (cause) {
10187
+ setError(cause instanceof Error ? cause.message : String(cause));
10188
+ } finally {
10189
+ setCreating(false);
10190
+ onCreatingChange(request, false);
10191
+ }
10192
+ };
10193
+ const submit = (event) => {
10194
+ event.preventDefault();
10195
+ const normalizedHandle = handle.trim();
10196
+ const normalizedDescription = description.trim();
10197
+ if (normalizedHandle.length === 0 || creating) return;
10198
+ provision(retryRequest !== void 0 && retryRequest.workspaceId === workspaceId && retryRequest.handle === normalizedHandle && retryRequest.description === normalizedDescription && sameModel(retryRequest.model, model) && retryRequest.channelRefs.length === channelRefs.length && retryRequest.channelRefs.every((ref) => channelRefs.includes(ref)) ? retryRequest : {
10199
+ requestId: mintRequestId(),
10200
+ workspaceId,
10201
+ handle: normalizedHandle,
10202
+ description: normalizedDescription,
10203
+ presetId: "team-member",
10204
+ channelRefs,
10205
+ ...model === void 0 ? {} : { model }
10206
+ });
10207
+ };
10208
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10209
+ className: sidebar_module_css_default.panel,
10210
+ children: [
10211
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
10212
+ open: formOpen,
10213
+ onClose: closeForm,
10214
+ title: t("addAgent"),
10215
+ closeLabel: t("close"),
10216
+ contentClassName: create_module_css_default.dialogContent,
10217
+ footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
10218
+ variant: "outline",
10219
+ disabled: creating,
10220
+ onClick: closeForm,
10221
+ children: t("cancel")
10222
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
10223
+ type: "submit",
10224
+ form: "team-agent-create-form",
10225
+ variant: "primary",
10226
+ disabled: creating || handle.trim().length === 0,
10227
+ children: creating ? t("creatingAgent") : t("createAgent")
10228
+ })] }),
10229
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
10230
+ id: "team-agent-create-form",
10231
+ className: create_module_css_default.form,
10232
+ onSubmit: submit,
10233
+ children: [
10234
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
10235
+ className: create_module_css_default.field,
10236
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("agentName") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
10237
+ className: create_module_css_default.input,
10238
+ value: handle,
10239
+ onChange: (event) => {
10240
+ setHandle(event.target.value);
10241
+ setRetryRequest(void 0);
10242
+ },
10243
+ disabled: creating,
10244
+ autoFocus: true
10245
+ })]
10246
+ }),
10247
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
10248
+ className: create_module_css_default.field,
10249
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [t("agentDescription"), t("optionalSuffix")] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
10250
+ className: create_module_css_default.input,
10251
+ value: description,
10252
+ placeholder: t("agentDescriptionPlaceholder"),
10253
+ onChange: (event) => {
10254
+ setDescription(event.target.value);
10255
+ setRetryRequest(void 0);
10256
+ },
10257
+ disabled: creating
10258
+ })]
10259
+ }),
10260
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelPickerField, {
10261
+ model,
10262
+ onModelChange: (choice) => {
10263
+ setModel(choice);
10264
+ setRetryRequest(void 0);
10265
+ },
10266
+ loadModels,
10267
+ disabled: creating,
10268
+ t
10269
+ }),
10270
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MultiMenuField, {
10271
+ label: `${t("initialChannels")}${t("optionalSuffix")}`,
10272
+ disabled: creating,
10273
+ options: channels.map((channel) => ({
10274
+ id: channel.channelRef,
10275
+ label: channel.name
10276
+ })),
10277
+ selected: channelRefs,
10278
+ onToggle: (ref) => {
10279
+ setChannelRefs((current) => current.includes(ref) ? current.filter((item) => item !== ref) : [...current, ref]);
10280
+ setRetryRequest(void 0);
10281
+ },
10282
+ emptyText: t("noChannelsForAgent"),
10283
+ triggerEmptyLabel: t("channelsPickerEmpty"),
10284
+ formatCount: (count) => t("channelsPickerCount", { count })
10285
+ }),
10286
+ formOpen && error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
10287
+ className: create_module_css_default.error,
10288
+ role: "alert",
10289
+ children: error
10290
+ })
10291
+ ]
10292
+ })
10293
+ }),
10294
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(TeamSidebarSection, {
10295
+ title: t("agents"),
10296
+ actions: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
10297
+ label: t("addAgent"),
10298
+ delayMs: 500,
10299
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
10300
+ ref: triggerRef,
10301
+ type: "button",
10302
+ className: sidebar_module_css_default.iconButton,
10303
+ "aria-label": t("addAgent"),
10304
+ onClick: () => {
10305
+ setError(void 0);
10306
+ setFormOpen(true);
10307
+ },
10308
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, { size: 14 })
10309
+ })
10310
+ }),
10311
+ children: [
10312
+ loading && members.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
10313
+ className: sidebar_module_css_default.emptyState,
10314
+ children: t("loadingAgents")
10315
+ }),
10316
+ !loading && members.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
10317
+ className: sidebar_module_css_default.emptyState,
10318
+ children: t("emptyAgents")
10319
+ }),
10320
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10321
+ className: sidebar_module_css_default.agentList,
10322
+ children: orderedMembers.map((status) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortableRow, {
10323
+ drag,
10324
+ orderKey: status.member.memberId,
10325
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AgentRow, {
10326
+ status,
10327
+ ...memberSessionId === void 0 ? {} : { current: status.member.sessionId === memberSessionId },
10328
+ channels,
10329
+ loadChannels,
10330
+ updateMember,
10331
+ recoverMember,
10332
+ joinChannel,
10333
+ removeChannelMember,
10334
+ loadModels,
10335
+ openMemberSession,
10336
+ onUpdated: () => {
10337
+ refresh();
10338
+ },
10339
+ t
10340
+ })
10341
+ }, status.member.memberId))
10342
+ })
10343
+ ]
10344
+ }),
10345
+ !formOpen && error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10346
+ className: sidebar_module_css_default.retryError,
10347
+ role: "alert",
10348
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: error }), retryRequest !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
10349
+ type: "button",
10350
+ className: sidebar_module_css_default.textButton,
10351
+ disabled: creating,
10352
+ onClick: () => {
10353
+ setFormOpen(true);
10354
+ },
10355
+ children: t("retry")
10356
+ })]
10357
+ })
10358
+ ]
10359
+ });
10360
+ }
10361
+ /**
10362
+ * One sidebar Agent row: the select button opens the Member's own Session
10363
+ * conversation page, the avatar carries identity plus the presence badge, and
10364
+ * the row menu opens the editor.
10365
+ */
10366
+ function AgentRow({ status, current, channels, loadChannels, updateMember, recoverMember, joinChannel, removeChannelMember, loadModels, openMemberSession, onUpdated, t }) {
10367
+ const [menuOpen, setMenuOpen] = (0, react.useState)(false);
10368
+ const [editing, setEditing] = (0, react.useState)(false);
10369
+ const [rowAlert, setRowAlert] = (0, react.useState)();
10370
+ const recover = async () => {
10371
+ try {
10372
+ const result = await recoverMember({
10373
+ requestId: mintRequestId(),
10374
+ workspaceId: status.member.workspaceId,
10375
+ memberId: status.member.memberId
10376
+ });
10377
+ await onUpdated();
10378
+ if (!result.ok) {
10379
+ setRowAlert(t("restartFailed", { message: result.error.message }));
10380
+ return;
10381
+ }
10382
+ if (result.value.status.availability === "unavailable") {
10383
+ setRowAlert(t("restartStillUnavailable", { diagnostic: result.value.status.diagnostic ?? t("statusUnavailable") }));
10384
+ return;
10385
+ }
10386
+ setRowAlert(void 0);
10387
+ if (current === true) openMemberSession(status.member.sessionId);
9965
10388
  } catch (cause) {
9966
- setError(cause instanceof Error ? cause.message : String(cause));
9967
- } finally {
9968
- setSaving(false);
10389
+ setRowAlert(t("restartFailed", { message: cause instanceof Error ? cause.message : String(cause) }));
9969
10390
  }
9970
10391
  };
9971
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
9972
- open: true,
9973
- onClose,
9974
- title: t("editAgent"),
9975
- description: `@${status.member.handle}`,
9976
- closeLabel: t("close"),
9977
- contentClassName: create_module_css_default.dialogContent,
9978
- footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9979
- variant: "outline",
9980
- disabled: saving,
9981
- onClick: onClose,
9982
- children: t("cancel")
9983
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
9984
- type: "submit",
9985
- form: "team-agent-edit-form",
9986
- variant: "primary",
9987
- disabled: saving || !dirty || handle.trim().length === 0,
9988
- children: saving ? t("editSaving") : t("editSave")
9989
- })] }),
9990
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
9991
- id: "team-agent-edit-form",
9992
- className: create_module_css_default.form,
9993
- onSubmit: (event) => {
9994
- submit(event);
9995
- },
9996
- children: [
9997
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
9998
- className: create_module_css_default.field,
9999
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("agentName") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
10000
- className: create_module_css_default.input,
10001
- value: handle,
10002
- onChange: (event) => {
10003
- setHandle(event.target.value);
10004
- pendingRequest.current = void 0;
10005
- },
10006
- disabled: saving,
10007
- autoFocus: true
10008
- })]
10009
- }),
10010
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
10011
- className: create_module_css_default.field,
10012
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [t("agentDescription"), t("optionalSuffix")] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
10013
- className: create_module_css_default.input,
10014
- value: description,
10015
- placeholder: t("agentDescriptionPlaceholder"),
10016
- onChange: (event) => {
10017
- setDescription(event.target.value);
10018
- pendingRequest.current = void 0;
10392
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
10393
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10394
+ className: sidebar_module_css_default.agentRow,
10395
+ "data-menu-open": menuOpen || void 0,
10396
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
10397
+ type: "button",
10398
+ className: sidebar_module_css_default.agentSelect,
10399
+ "aria-label": t("openAgentSession", { name: status.member.handle }),
10400
+ "aria-current": current ? "page" : void 0,
10401
+ disabled: status.availability !== "active",
10402
+ onClick: () => {
10403
+ openMemberSession(status.member.sessionId);
10404
+ },
10405
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamMemberAvatar, {
10406
+ status,
10407
+ t
10408
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
10409
+ className: sidebar_module_css_default.agentCopy,
10410
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: status.member.handle }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: status.member.description })]
10411
+ })]
10412
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10413
+ className: sidebar_module_css_default.rowMenu,
10414
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamRowMenu, {
10415
+ label: t("actionsAgent", { name: status.member.handle }),
10416
+ items: [
10417
+ {
10418
+ id: "edit",
10419
+ label: t("editAgent"),
10420
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, {})
10019
10421
  },
10020
- disabled: saving
10021
- })]
10022
- }),
10023
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelPickerField, {
10024
- model,
10025
- onModelChange: (choice) => {
10026
- pendingRequest.current = void 0;
10027
- setModel(choice);
10422
+ ...status.presence === "error" ? [{
10423
+ id: "resume",
10424
+ label: t("resumeAgent"),
10425
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlayOutline16, {})
10426
+ }] : [],
10427
+ ...status.availability === "unavailable" ? [{
10428
+ id: "restart",
10429
+ label: t("restartAgent"),
10430
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutline16, {})
10431
+ }] : []
10432
+ ],
10433
+ onSelect: (id) => {
10434
+ if (id === "edit") setEditing(true);
10435
+ else recover();
10028
10436
  },
10029
- loadModels,
10030
- disabled: saving,
10031
- t
10032
- }),
10033
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
10034
- className: create_module_css_default.memberPicker,
10035
- disabled: saving,
10036
- children: [
10037
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", { children: t("channelMembersSection") }),
10038
- channels.map((channel) => {
10039
- const joined = joinedChannels.has(channel.channelRef);
10040
- const rowPending = membership.pending.has(channel.channelRef);
10041
- const disabled = rowPending || !joined && status.presence === "unavailable";
10042
- const rowError = membership.errors.get(channel.channelRef);
10043
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10044
- className: `${sidebar_module_css_default.editMemberRow} ${sidebar_module_css_default.editMemberRowChannels}`,
10045
- children: [
10046
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", {
10047
- className: sidebar_module_css_default.editChannelName,
10048
- children: ["# ", channel.name]
10049
- }),
10050
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
10051
- size: "sm",
10052
- variant: "outline",
10053
- disabled,
10054
- onClick: () => {
10055
- membership.change({
10056
- workspaceId: status.member.workspaceId,
10057
- channelRef: channel.channelRef,
10058
- memberId,
10059
- joined
10060
- });
10061
- },
10062
- children: rowPending ? t("membershipUpdating") : joined ? t("removeFromChannel") : t("addToChannel")
10063
- }),
10064
- rowError !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
10065
- className: sidebar_module_css_default.rowError,
10066
- role: "alert",
10067
- children: rowError
10068
- })
10069
- ]
10070
- }, channel.channelRef);
10071
- }),
10072
- channels.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("noChannelsForAgent") }),
10073
- loadError !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
10074
- className: sidebar_module_css_default.rowError,
10075
- role: "alert",
10076
- children: loadError
10077
- })
10078
- ]
10079
- }),
10080
- error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
10081
- className: create_module_css_default.error,
10082
- role: "alert",
10083
- children: error
10437
+ onOpenChange: setMenuOpen
10084
10438
  })
10085
- ]
10439
+ })]
10440
+ }),
10441
+ rowAlert !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10442
+ className: sidebar_module_css_default.rowAlert,
10443
+ role: "alert",
10444
+ children: rowAlert
10445
+ }),
10446
+ editing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AgentEditorDialog, {
10447
+ status,
10448
+ channels,
10449
+ loadChannels,
10450
+ updateMember,
10451
+ joinChannel,
10452
+ removeChannelMember,
10453
+ loadModels,
10454
+ onCommitted: onUpdated,
10455
+ onClose: () => {
10456
+ setEditing(false);
10457
+ },
10458
+ t
10086
10459
  })
10087
- });
10088
- }
10089
- function sameModel(left, right) {
10090
- if (left === void 0 && right === void 0) return true;
10091
- if (left === void 0 || right === void 0) return false;
10092
- return left.provider === right.provider && left.model === right.model && left.reasoningEffort === right.reasoningEffort;
10460
+ ] });
10093
10461
  }
10094
10462
  //#endregion
10095
10463
  //#region src/client/TeamChannelsPanel.tsx
@@ -10189,7 +10557,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10189
10557
  memberIds: [...selected]
10190
10558
  };
10191
10559
  const request = pendingCreate !== void 0 && pendingCreate.workspaceId === payload.workspaceId && pendingCreate.name === payload.name && pendingCreate.description === payload.description && JSON.stringify(pendingCreate.memberIds) === JSON.stringify(payload.memberIds) ? pendingCreate : {
10192
- requestId: crypto.randomUUID(),
10560
+ requestId: mintRequestId(),
10193
10561
  ...payload
10194
10562
  };
10195
10563
  setPendingCreate(request);
@@ -10443,7 +10811,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10443
10811
  const normalizedDescription = description.trim();
10444
10812
  if (saving || !dirty || normalizedName === "") return;
10445
10813
  const request = pendingRequest.current !== void 0 && pendingRequest.current.channelRef === channel.channelRef && pendingRequest.current.name === normalizedName && pendingRequest.current.description === normalizedDescription ? pendingRequest.current : {
10446
- requestId: crypto.randomUUID(),
10814
+ requestId: mintRequestId(),
10447
10815
  workspaceId: channel.workspaceId,
10448
10816
  channelRef: channel.channelRef,
10449
10817
  name: normalizedName,
@@ -10630,12 +10998,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10630
10998
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
10631
10999
  className: sidebar_module_css_default.workspaceBrowser,
10632
11000
  "aria-label": t("workspaces"),
10633
- children: [
10634
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10635
- className: sidebar_module_css_default.workspaceHeader,
10636
- children: t("workspaces")
10637
- }),
10638
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11001
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamSidebarSection, {
11002
+ title: t("workspaces"),
11003
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10639
11004
  className: sidebar_module_css_default.workspaceList,
10640
11005
  children: [workspaces.map((workspace) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamWorkspaceRow, {
10641
11006
  workspaceId: workspace.workspaceId,
@@ -10648,50 +11013,303 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10648
11013
  className: sidebar_module_css_default.emptyState,
10649
11014
  children: t("empty")
10650
11015
  })]
10651
- }),
10652
- selectedId !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10653
- className: sidebar_module_css_default.workspaceSection,
10654
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10655
- ref: channelsRef,
10656
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamChannelsPanel, {
10657
- workspaceId: selectedId,
10658
- loadMembers,
10659
- loadChannels,
10660
- subscribeChanges,
10661
- createChannel,
10662
- updateChannel,
10663
- joinChannel,
10664
- removeChannelMember,
10665
- creatingAgents: creatingAgents.filter((request) => request.workspaceId === selectedId),
10666
- ...navigationState.memberSessionId !== void 0 || navigationState.channelRef === void 0 ? {} : { selectedChannelRef: navigationState.channelRef },
10667
- selectChannel,
10668
- t
10669
- }, selectedId)
10670
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10671
- ref: agentsRef,
10672
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamAgentsPanel, {
10673
- workspaceId: selectedId,
10674
- loadMembers,
10675
- subscribeChanges,
10676
- loadChannels,
10677
- addMember,
10678
- updateMember,
10679
- recoverMember,
10680
- joinChannel,
10681
- removeChannelMember,
10682
- loadModels,
10683
- ...navigationState.memberSessionId === void 0 ? {} : { memberSessionId: navigationState.memberSessionId },
10684
- openMemberSession,
10685
- onCreatingChange: (request, creating) => {
10686
- setCreatingAgents((current) => creating ? [...current.filter((item) => item.requestId !== request.requestId), request] : current.filter((item) => item.requestId !== request.requestId));
10687
- },
10688
- t
10689
- }, selectedId)
10690
- })]
10691
11016
  })
10692
- ]
11017
+ }), selectedId !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11018
+ className: sidebar_module_css_default.workspaceSection,
11019
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11020
+ ref: channelsRef,
11021
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamChannelsPanel, {
11022
+ workspaceId: selectedId,
11023
+ loadMembers,
11024
+ loadChannels,
11025
+ subscribeChanges,
11026
+ createChannel,
11027
+ updateChannel,
11028
+ joinChannel,
11029
+ removeChannelMember,
11030
+ creatingAgents: creatingAgents.filter((request) => request.workspaceId === selectedId),
11031
+ ...navigationState.memberSessionId !== void 0 || navigationState.channelRef === void 0 ? {} : { selectedChannelRef: navigationState.channelRef },
11032
+ selectChannel,
11033
+ t
11034
+ }, selectedId)
11035
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11036
+ ref: agentsRef,
11037
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamAgentsPanel, {
11038
+ workspaceId: selectedId,
11039
+ loadMembers,
11040
+ subscribeChanges,
11041
+ loadChannels,
11042
+ addMember,
11043
+ updateMember,
11044
+ recoverMember,
11045
+ joinChannel,
11046
+ removeChannelMember,
11047
+ loadModels,
11048
+ ...navigationState.memberSessionId === void 0 ? {} : { memberSessionId: navigationState.memberSessionId },
11049
+ openMemberSession,
11050
+ onCreatingChange: (request, creating) => {
11051
+ setCreatingAgents((current) => creating ? [...current.filter((item) => item.requestId !== request.requestId), request] : current.filter((item) => item.requestId !== request.requestId));
11052
+ },
11053
+ t
11054
+ }, selectedId)
11055
+ })]
11056
+ })]
11057
+ });
11058
+ }
11059
+ //#endregion
11060
+ //#region src/client/member-session-input.ts
11061
+ const TEAM_COMMAND_SOURCE = "agent-team-command";
11062
+ const TEAM_MEMBER_SOURCE = "agent-team-member";
11063
+ /** Preserve the public Session command admission contract, not handler outcome. */
11064
+ async function admitTeamCompact(session) {
11065
+ const result = await session.command("/compact");
11066
+ if (!result.ok) throw new Error(`session.command failed: ${result.error.message}`);
11067
+ return result.value.matched ? { kind: "success" } : {
11068
+ kind: "error",
11069
+ text: "unknown command: /compact"
11070
+ };
11071
+ }
11072
+ /**
11073
+ * The two Team-only sources live in the shared public registry, but their
11074
+ * candidate plane is inert for every ordinary Session. The member source owns
11075
+ * its stable ref→label cache so serialization never falls back to guessing a
11076
+ * handle from plain text.
11077
+ */
11078
+ function createTeamMemberSessionSources(options) {
11079
+ const labels = /* @__PURE__ */ new Map();
11080
+ return [{
11081
+ trigger: "/",
11082
+ name: TEAM_COMMAND_SOURCE,
11083
+ showGroupTitle: false,
11084
+ async candidates(session, { query }) {
11085
+ if (!options.isEmbeddedMemberSession(session.sessionId) || !"compact".startsWith(query.toLocaleLowerCase())) return [];
11086
+ return [{
11087
+ name: "/compact",
11088
+ description: "压缩当前 Session 上下文",
11089
+ value: "compact"
11090
+ }];
11091
+ },
11092
+ onPick({ candidate, session }) {
11093
+ if (candidate.value !== "compact" || !options.isEmbeddedMemberSession(session.sessionId)) return void 0;
11094
+ return { claim: {
11095
+ token: "/compact",
11096
+ submit: async () => options.executeCompact(session.sessionId)
11097
+ } };
11098
+ }
11099
+ }, {
11100
+ trigger: "@",
11101
+ name: TEAM_MEMBER_SOURCE,
11102
+ showGroupTitle: false,
11103
+ async candidates(session, { query, signal }) {
11104
+ if (!options.isEmbeddedMemberSession(session.sessionId)) return [];
11105
+ const normalized = query.toLocaleLowerCase();
11106
+ const members = await options.members();
11107
+ if (signal.aborted) return [];
11108
+ return members.filter((status) => status.member.sessionId !== session.sessionId && status.member.state !== "inactive").filter((status) => status.member.handle.toLocaleLowerCase().startsWith(normalized)).map((status) => {
11109
+ labels.set(status.member.memberId, `@${status.member.handle}`);
11110
+ return {
11111
+ name: `@${status.member.handle}`,
11112
+ description: "引用成员 · 不会通知",
11113
+ value: String(status.member.memberId)
11114
+ };
11115
+ });
11116
+ },
11117
+ onPick({ candidate, session }) {
11118
+ if (!options.isEmbeddedMemberSession(session.sessionId) || candidate.value === void 0) return void 0;
11119
+ const ref = candidate.value;
11120
+ const label = labels.get(ref);
11121
+ if (label === void 0) return void 0;
11122
+ return { insert: {
11123
+ source: TEAM_MEMBER_SOURCE,
11124
+ label: label.slice(1),
11125
+ ref,
11126
+ clipboardText: label
11127
+ } };
11128
+ },
11129
+ codec: {
11130
+ clipboardText: (ref) => labels.get(ref) ?? `@${String(ref)}`,
11131
+ serialize: async (ref) => {
11132
+ const stable = String(ref);
11133
+ const label = labels.get(ref) ?? "";
11134
+ return `<team-member ref="${escapeAttribute(stable)}">${escapeText(label)}</team-member>`;
11135
+ }
11136
+ }
11137
+ }];
11138
+ }
11139
+ /** Unknown leading slash must never fall into the shipped global palette. */
11140
+ function allowsMemberSessionSubmit(draft, claimToken) {
11141
+ return !draft.trimStart().startsWith("/") || claimToken === "/compact";
11142
+ }
11143
+ function escapeText(value) {
11144
+ return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
11145
+ }
11146
+ function escapeAttribute(value) {
11147
+ return escapeText(value).replaceAll("\"", "&quot;").replaceAll("'", "&#39;");
11148
+ }
11149
+ //#endregion
11150
+ //#region src/client/TeamMemberSessionComposer.tsx
11151
+ /**
11152
+ * Narrow, Team-owned member-session composer. It deliberately uses the public
11153
+ * input state/actions and trigger controller rather than the shipped InputBar;
11154
+ * owner-provided overlay remains inside the card so the shared menu renders.
11155
+ */
11156
+ function TeamMemberSessionComposer({ controller, inputActions, overlay, placeholder, disabled, blocked, stop, submitInput, useInput, useSession }) {
11157
+ const input = useInput((state) => state);
11158
+ const session = useSession((state) => state);
11159
+ const textarea = (0, react.useRef)(null);
11160
+ const editedByHuman = (0, react.useRef)(void 0);
11161
+ const compactWasSubmitting = (0, react.useRef)(false);
11162
+ const composing = (0, react.useRef)(false);
11163
+ const [submissionNotice, setSubmissionNotice] = (0, react.useState)();
11164
+ const draft = input?.draft ?? "";
11165
+ const isLocked = disabled === true || blocked !== void 0 || inputActions === void 0 || input === void 0;
11166
+ (0, react.useEffect)(() => {
11167
+ if (isLocked) return;
11168
+ const active = document.activeElement;
11169
+ if (active !== document.body && active?.closest("[aria-current=\"page\"]") === null) return;
11170
+ textarea.current?.focus({ preventScroll: true });
11171
+ }, [isLocked]);
11172
+ (0, react.useLayoutEffect)(() => {
11173
+ const element = textarea.current;
11174
+ if (element === null) return;
11175
+ element.style.height = "auto";
11176
+ element.style.height = `${Math.min(element.scrollHeight, 336)}px`;
11177
+ }, [draft]);
11178
+ (0, react.useEffect)(() => {
11179
+ if (input === void 0) return;
11180
+ if (input.phase === "submitting" && input.claim?.token === "/compact") {
11181
+ compactWasSubmitting.current = true;
11182
+ return;
11183
+ }
11184
+ if (input.phase === "claimed" && input.claim?.token === "/compact" && compactWasSubmitting.current) {
11185
+ compactWasSubmitting.current = false;
11186
+ setSubmissionNotice("Compact 未执行,请重试。");
11187
+ return;
11188
+ }
11189
+ if (input.phase === "plain") compactWasSubmitting.current = false;
11190
+ }, [input?.claim?.token, input?.phase]);
11191
+ (0, react.useEffect)(() => {
11192
+ if (input === void 0) return;
11193
+ const edit = editedByHuman.current;
11194
+ if (edit === void 0 || edit.draft !== input.draft) return;
11195
+ editedByHuman.current = void 0;
11196
+ const hit = triggerHit(input.draft, edit.caret, input.draftRev);
11197
+ controller.dismiss();
11198
+ if (hit !== void 0) controller.toggleSource(hit.trigger === "/" ? TEAM_COMMAND_SOURCE : TEAM_MEMBER_SOURCE, hit);
11199
+ }, [
11200
+ controller,
11201
+ input?.draft,
11202
+ input?.draftRev
11203
+ ]);
11204
+ const onChange = (event) => {
11205
+ const caret = event.currentTarget.selectionStart;
11206
+ editedByHuman.current = {
11207
+ draft: event.currentTarget.value,
11208
+ caret
11209
+ };
11210
+ setSubmissionNotice(void 0);
11211
+ inputActions?.setDraft(event.currentTarget.value);
11212
+ };
11213
+ const submit = () => {
11214
+ if (input === void 0 || inputActions === void 0) return;
11215
+ if (!allowsMemberSessionSubmit(input.draft, input.claim?.token)) {
11216
+ setSubmissionNotice("此 Member Session 仅支持 /compact 命令。");
11217
+ return;
11218
+ }
11219
+ setSubmissionNotice(void 0);
11220
+ submitInput(running ? "steer" : "queue");
11221
+ };
11222
+ const onKeyDown = (event) => {
11223
+ if (event.key === "Enter" && event.shiftKey) return;
11224
+ if (event.repeat || composing.current || event.nativeEvent.isComposing || event.nativeEvent.keyCode === 229) return;
11225
+ const key = event.key === "ArrowUp" ? "up" : event.key === "ArrowDown" ? "down" : event.key === "Escape" ? "escape" : event.key === "Enter" ? "enter" : void 0;
11226
+ if (key !== void 0) {
11227
+ if (controller.arbitrate(key, false) !== "pass") {
11228
+ event.preventDefault();
11229
+ return;
11230
+ }
11231
+ }
11232
+ if (event.key === "Enter") {
11233
+ event.preventDefault();
11234
+ submit();
11235
+ }
11236
+ };
11237
+ const running = session?.running ?? false;
11238
+ const promptError = session?.promptError;
11239
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11240
+ className: `${composer_module_css_default.root} ${composer_module_css_default.memberSessionRoot}`,
11241
+ "data-team-member-composer": "true",
11242
+ children: [(submissionNotice !== void 0 || promptError !== null && promptError !== void 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
11243
+ className: composer_module_css_default.memberSessionStatus,
11244
+ role: "alert",
11245
+ children: submissionNotice ?? promptError?.error.message
11246
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11247
+ className: `${composer_module_css_default.card} ${composer_module_css_default.memberSessionCard}`,
11248
+ "data-composer-card": "true",
11249
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11250
+ className: `${composer_module_css_default.inputArea} ${composer_module_css_default.memberSessionInputArea}`,
11251
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
11252
+ ref: textarea,
11253
+ value: draft,
11254
+ disabled: isLocked,
11255
+ placeholder: blocked?.reason ?? placeholder ?? "给成员发送直接消息",
11256
+ onChange,
11257
+ onKeyDown,
11258
+ onCompositionStart: () => {
11259
+ composing.current = true;
11260
+ },
11261
+ onCompositionEnd: () => {
11262
+ composing.current = false;
11263
+ }
11264
+ }), overlay]
11265
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11266
+ className: `${composer_module_css_default.toolbar} ${composer_module_css_default.memberSessionToolbar}`,
11267
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
11268
+ className: `${composer_module_css_default.sendButton} ${composer_module_css_default.memberSessionPrimary}`,
11269
+ type: "button",
11270
+ "aria-label": running ? "停止生成" : "发送消息",
11271
+ disabled: isLocked || !running && draft.trim() === "",
11272
+ onClick: () => {
11273
+ if (running) stop?.();
11274
+ else submit();
11275
+ },
11276
+ children: running ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconStopFill16, { size: 16 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSendOutline16, { size: 16 })
11277
+ })
11278
+ })]
11279
+ })]
10693
11280
  });
10694
11281
  }
11282
+ function triggerHit(draft, caret, draftRev) {
11283
+ const before = draft.slice(0, caret);
11284
+ const leading = before.match(/^\s*\/([^\s]*)$/u);
11285
+ if (leading !== null) {
11286
+ const start = before.indexOf("/");
11287
+ return {
11288
+ trigger: "/",
11289
+ query: leading[1],
11290
+ quoted: false,
11291
+ position: "leading",
11292
+ span: {
11293
+ start,
11294
+ end: caret,
11295
+ draftRev
11296
+ }
11297
+ };
11298
+ }
11299
+ const at = before.lastIndexOf("@");
11300
+ if (at < 0 || /[\p{L}\p{N}_]/u.test(before[at - 1] ?? "") || /\s/u.test(before.slice(at + 1))) return void 0;
11301
+ return {
11302
+ trigger: "@",
11303
+ query: before.slice(at + 1),
11304
+ quoted: false,
11305
+ position: "inline",
11306
+ span: {
11307
+ start: at,
11308
+ end: caret,
11309
+ draftRev
11310
+ }
11311
+ };
11312
+ }
10695
11313
  //#endregion
10696
11314
  //#region src/client/locales.ts
10697
11315
  const zh = {
@@ -10733,6 +11351,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10733
11351
  editChannel: "编辑频道",
10734
11352
  editAgent: "编辑 Agent",
10735
11353
  resumeAgent: "恢复",
11354
+ restartAgent: "重启",
11355
+ restartStillUnavailable: "重启已执行,成员仍不可用:{diagnostic}",
11356
+ restartFailed: "重启执行失败:{message}",
10736
11357
  optionalSuffix: "(可选)",
10737
11358
  agentDescriptionPlaceholder: "留空则暂无描述",
10738
11359
  channelsPickerEmpty: "选择初始频道",
@@ -10745,6 +11366,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10745
11366
  removeFile: "移除 {name}",
10746
11367
  attachmentExpired: "文件已过期清理",
10747
11368
  viewImage: "查看大图 {name}",
11369
+ expandMessage: "展开全文",
11370
+ collapseMessage: "收起",
10748
11371
  actionsChannel: "{name} 的操作",
10749
11372
  actionsAgent: "{name} 的操作",
10750
11373
  editSave: "保存",
@@ -10777,10 +11400,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10777
11400
  taskLabel: "Task #{number}",
10778
11401
  taskPending: "Task …",
10779
11402
  openTask: "打开 Task #{number}",
11403
+ openThread: "打开讨论",
11404
+ threadLabel: "讨论",
11405
+ asTask: "作为任务",
11406
+ promoteToTask: "转为 Task",
11407
+ promotingTask: "正在转为 Task…",
10780
11408
  mentionSuggestions: "提及成员建议",
10781
11409
  messageDraft: "消息内容",
10782
11410
  composerNotify: "将通知:{ids}",
10783
11411
  messagePlaceholder: "写一条消息…",
11412
+ replyPlaceholder: "回复此 Thread…",
10784
11413
  sendMessage: "发送",
10785
11414
  sendingMessage: "发送中…",
10786
11415
  loadOlder: "加载更早消息",
@@ -10811,6 +11440,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10811
11440
  activityClaimsReleased: "{actor} 因成员权限变化释放了 {count} 个 Claim",
10812
11441
  activityAccepted: "{actor} 验收了此 Task",
10813
11442
  activityAcceptedWithClaims: "{actor} 验收了此 Task,并一并完成了 {count} 个未完成 Claim",
11443
+ activityPromoted: "{actor} 为此讨论创建了 Task",
10814
11444
  acceptEarlyTitle: "提前验收任务",
10815
11445
  acceptEarlyBody: "将验收本 Task,并把以下 {count} 个未完成的 Claim 一并标记为完成:",
10816
11446
  acceptingTask: "验收中…",
@@ -10861,6 +11491,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10861
11491
  editChannel: "Edit Channel",
10862
11492
  editAgent: "Edit Agent",
10863
11493
  resumeAgent: "Resume",
11494
+ restartAgent: "Restart",
11495
+ restartStillUnavailable: "Restart ran, but the Member is still unavailable: {diagnostic}",
11496
+ restartFailed: "Restart failed: {message}",
10864
11497
  optionalSuffix: " (optional)",
10865
11498
  agentDescriptionPlaceholder: "Leave empty if not needed",
10866
11499
  channelsPickerEmpty: "Choose initial channels",
@@ -10873,6 +11506,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10873
11506
  removeFile: "Remove {name}",
10874
11507
  attachmentExpired: "File expired and cleaned up",
10875
11508
  viewImage: "View image {name}",
11509
+ expandMessage: "Show more",
11510
+ collapseMessage: "Show less",
10876
11511
  actionsChannel: "{name} actions",
10877
11512
  actionsAgent: "{name} actions",
10878
11513
  editSave: "Save",
@@ -10905,10 +11540,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10905
11540
  taskLabel: "Task #{number}",
10906
11541
  taskPending: "Task …",
10907
11542
  openTask: "Open Task #{number}",
11543
+ openThread: "Open thread",
11544
+ threadLabel: "Thread",
11545
+ asTask: "As task",
11546
+ promoteToTask: "Convert to Task",
11547
+ promotingTask: "Converting to Task…",
10908
11548
  mentionSuggestions: "Mention suggestions",
10909
11549
  messageDraft: "Message",
10910
11550
  composerNotify: "Will notify: {ids}",
10911
11551
  messagePlaceholder: "Write a message…",
11552
+ replyPlaceholder: "Reply on this Thread…",
10912
11553
  sendMessage: "Send",
10913
11554
  sendingMessage: "Sending…",
10914
11555
  loadOlder: "Load older messages",
@@ -10939,6 +11580,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10939
11580
  activityClaimsReleased: "{actor} released {count} Claim(s) after a membership change",
10940
11581
  activityAccepted: "{actor} accepted this Task",
10941
11582
  activityAcceptedWithClaims: "{actor} accepted this Task and completed {count} unfinished Claims with it",
11583
+ activityPromoted: "{actor} created a Task for this Thread",
10942
11584
  acceptEarlyTitle: "Accept Task early",
10943
11585
  acceptEarlyBody: "This accepts the Task and marks the following {count} unfinished Claims as done:",
10944
11586
  acceptingTask: "Accepting…",
@@ -10959,7 +11601,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10959
11601
  "locale",
10960
11602
  "remote",
10961
11603
  "sessions",
10962
- "connection"
11604
+ "connection",
11605
+ "conversation",
11606
+ "inputTriggers"
10963
11607
  ];
10964
11608
  function registerModeShadow(ctx, navigation, changes, drafts, name, component, extraInject) {
10965
11609
  const sharedRemotes = {
@@ -11006,6 +11650,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11006
11650
  getAttachment: (request) => ctx.remote.agentTeam.getAttachment(request),
11007
11651
  reply: (request) => ctx.remote.agentTeam.reply(request),
11008
11652
  changeTask: (request) => ctx.remote.agentTeam.changeTask(request),
11653
+ promoteThread: (request) => ctx.remote.agentTeam.promoteThread(request),
11009
11654
  resolveTaskRefs: (request) => ctx.remote.agentTeam.resolveTaskRefs(request)
11010
11655
  } : {},
11011
11656
  ...name === "sidebar.workspaces" ? {
@@ -11028,6 +11673,47 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11028
11673
  };
11029
11674
  });
11030
11675
  }
11676
+ function registerMemberSessionComposer(ctx, navigation) {
11677
+ ctx.slots.inject("conversation.composer.bar", () => {
11678
+ let dispose;
11679
+ let registeredSessionId;
11680
+ const reconcile = () => {
11681
+ const memberSessionId = navigation.getSnapshot().memberSessionId;
11682
+ const active = navigation.getSnapshot().mode === "team" && memberSessionId !== void 0;
11683
+ if (dispose !== void 0 && (!active || registeredSessionId !== memberSessionId)) {
11684
+ dispose();
11685
+ dispose = void 0;
11686
+ registeredSessionId = void 0;
11687
+ }
11688
+ if (active && dispose === void 0) {
11689
+ registeredSessionId = memberSessionId;
11690
+ dispose = ctx.slots.register({
11691
+ name: "conversation.composer.bar",
11692
+ priority: -100,
11693
+ select: () => ctx.sessions.list.getSnapshot().current === memberSessionId ? {} : null,
11694
+ inject: (sessionId) => {
11695
+ const actx = ctx.sessions.scope(sessionId);
11696
+ if (actx === void 0) throw new Error(`agent-team: Member session ${String(sessionId)} has no client scope`);
11697
+ const sessions = ctx.sessions;
11698
+ return {
11699
+ controller: ctx.get("inputTriggers").sessionOf(actx),
11700
+ stop: () => {
11701
+ sessions.sessionOf(actx)?.cancel();
11702
+ },
11703
+ submitInput: (mode) => ctx.conversation.input.for(actx).submit(mode)
11704
+ };
11705
+ }
11706
+ }, TeamMemberSessionComposer);
11707
+ }
11708
+ };
11709
+ const offNavigation = navigation.subscribe(reconcile);
11710
+ reconcile();
11711
+ return () => {
11712
+ offNavigation();
11713
+ dispose?.();
11714
+ };
11715
+ });
11716
+ }
11031
11717
  function applyUi(ctx) {
11032
11718
  ctx.effect(() => ctx.locale.register(NS, {
11033
11719
  zh,
@@ -11044,6 +11730,33 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11044
11730
  disposeDrafts();
11045
11731
  }, "agent-team: navigation service");
11046
11732
  const changes = new TeamChangeStream((request, signal) => ctx.remote.agentTeam.changes(request, signal));
11733
+ const triggerSources = createTeamMemberSessionSources({
11734
+ isEmbeddedMemberSession: (sessionId) => {
11735
+ const snapshot = navigation.getSnapshot();
11736
+ return snapshot.mode === "team" && snapshot.memberSessionId === sessionId && snapshot.workspaceId !== void 0;
11737
+ },
11738
+ members: async () => {
11739
+ const workspaceId = navigation.getSnapshot().workspaceId;
11740
+ if (workspaceId === void 0) return [];
11741
+ const result = await ctx.remote.agentTeam.members({ workspaceId });
11742
+ return result.ok ? result.value : [];
11743
+ },
11744
+ executeCompact: async (sessionId) => {
11745
+ const actx = ctx.sessions.scope(sessionId);
11746
+ const session = actx === void 0 ? void 0 : ctx.sessions.sessionOf(actx);
11747
+ return session === void 0 ? {
11748
+ kind: "error",
11749
+ text: "current Member Session is unavailable"
11750
+ } : admitTeamCompact(session);
11751
+ }
11752
+ });
11753
+ const inputTriggers = ctx.get("inputTriggers");
11754
+ ctx.effect(() => {
11755
+ const disposers = triggerSources.map((source) => inputTriggers.registerSource(source));
11756
+ return () => {
11757
+ for (const dispose of disposers) dispose();
11758
+ };
11759
+ }, "agent-team: Member session trigger sources");
11047
11760
  const loadMemberGroups = async () => {
11048
11761
  const workspaces = ctx.workspaces.list.getSnapshot().items;
11049
11762
  return (await Promise.all(workspaces.map(async (workspace) => {
@@ -11080,6 +11793,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11080
11793
  }, TeamFooterAction));
11081
11794
  registerModeShadow(ctx, navigation, changes, drafts, "sidebar.workspaces", TeamWorkspaceBrowser);
11082
11795
  registerModeShadow(ctx, navigation, changes, drafts, "conversation", TeamConversation);
11796
+ registerMemberSessionComposer(ctx, navigation);
11083
11797
  registerModeShadow(ctx, navigation, changes, drafts, "sidebar.settings", TeamSettings, () => ({ loadMemberGroups }));
11084
11798
  }
11085
11799
  async function apply(ctx) {