@wowyuarm/dsh-agent-team 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +14 -2
  2. package/README.zh.md +10 -2
  3. package/package.json +2 -2
  4. package/packages/agent-team/lib/attachments.js +157 -0
  5. package/packages/agent-team/lib/index.js +274 -5
  6. package/packages/agent-team/lib/ledger.js +65 -13
  7. package/packages/agent-team/lib/recovery.js +87 -0
  8. package/packages/agent-team/lib/spec.js +17 -1
  9. package/packages/agent-team/lib/typert.host.js +321 -21
  10. package/packages/agent-team/lib/typert.remote-client.d.ts +9 -1
  11. package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
  12. package/packages/agent-team/lib/typert.remote-client.js +249 -17
  13. package/packages/agent-team/lib/types/attachments.d.ts +69 -0
  14. package/packages/agent-team/lib/types/attachments.d.ts.map +1 -0
  15. package/packages/agent-team/lib/types/index.d.ts +66 -1
  16. package/packages/agent-team/lib/types/index.d.ts.map +1 -1
  17. package/packages/agent-team/lib/types/ledger.d.ts +17 -1
  18. package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
  19. package/packages/agent-team/lib/types/recovery.d.ts +42 -0
  20. package/packages/agent-team/lib/types/recovery.d.ts.map +1 -0
  21. package/packages/agent-team/lib/types/spec.d.ts.map +1 -1
  22. package/packages/agent-team/lib/types/types.d.ts +85 -2
  23. package/packages/agent-team/lib/types/types.d.ts.map +1 -1
  24. package/packages/client-agent-team/README.md +2 -2
  25. package/packages/client-agent-team/README.zh.md +2 -2
  26. package/packages/client-agent-team/lib/client.js +1176 -281
  27. package/packages/client-agent-team/lib/client.js.map +1 -1
  28. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts +6 -2
  29. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts.map +1 -1
  30. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +104 -58
  31. package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts +5 -1
  32. package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts.map +1 -1
  33. package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +44 -19
  34. package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.d.ts.map +1 -1
  35. package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.js +23 -18
  36. package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts +4 -1
  37. package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts.map +1 -1
  38. package/packages/client-agent-team/lib/types/client/TeamComposer.js +40 -4
  39. package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts +1 -1
  40. package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts.map +1 -1
  41. package/packages/client-agent-team/lib/types/client/TeamConversation.js +3 -3
  42. package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts +7 -2
  43. package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts.map +1 -1
  44. package/packages/client-agent-team/lib/types/client/TeamMessage.js +34 -8
  45. package/packages/client-agent-team/lib/types/client/TeamRunDivider.d.ts +10 -0
  46. package/packages/client-agent-team/lib/types/client/TeamRunDivider.d.ts.map +1 -0
  47. package/packages/client-agent-team/lib/types/client/TeamRunDivider.js +12 -0
  48. package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts +3 -0
  49. package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts.map +1 -1
  50. package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +18 -11
  51. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts +1 -1
  52. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts.map +1 -1
  53. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +6 -5
  54. package/packages/client-agent-team/lib/types/client/attachment-preview.d.ts +22 -0
  55. package/packages/client-agent-team/lib/types/client/attachment-preview.d.ts.map +1 -0
  56. package/packages/client-agent-team/lib/types/client/attachment-preview.js +35 -0
  57. package/packages/client-agent-team/lib/types/client/drafts.d.ts +41 -0
  58. package/packages/client-agent-team/lib/types/client/drafts.d.ts.map +1 -0
  59. package/packages/client-agent-team/lib/types/client/drafts.js +144 -0
  60. package/packages/client-agent-team/lib/types/client/index.d.ts +2 -0
  61. package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
  62. package/packages/client-agent-team/lib/types/client/index.js +50 -10
  63. package/packages/client-agent-team/lib/types/client/locales.d.ts +28 -0
  64. package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
  65. package/packages/client-agent-team/lib/types/client/locales.js +28 -0
  66. package/packages/client-agent-team/lib/types/client/multi-menu-field.d.ts +33 -0
  67. package/packages/client-agent-team/lib/types/client/multi-menu-field.d.ts.map +1 -0
  68. package/packages/client-agent-team/lib/types/client/multi-menu-field.js +30 -0
  69. package/packages/client-agent-team/lib/types/client/navigation.d.ts +16 -1
  70. package/packages/client-agent-team/lib/types/client/navigation.d.ts.map +1 -1
  71. package/packages/client-agent-team/lib/types/client/navigation.js +45 -8
  72. package/packages/client-agent-team/lib/types/client/slots.d.ts +18 -2
  73. package/packages/client-agent-team/lib/types/client/slots.d.ts.map +1 -1
  74. package/packages/client-agent-team/lib/types/client/team-formatters.d.ts +2 -0
  75. package/packages/client-agent-team/lib/types/client/team-formatters.d.ts.map +1 -1
  76. package/packages/client-agent-team/lib/types/client/team-formatters.js +4 -0
  77. package/packages/client-agent-team/lib/types/client/team-separators.d.ts +8 -0
  78. package/packages/client-agent-team/lib/types/client/team-separators.d.ts.map +1 -1
  79. package/packages/client-agent-team/lib/types/client/team-separators.js +14 -0
  80. package/packages/tool-agent-team/lib/index.js +6 -2
  81. package/packages/tool-agent-team/lib/types/index.d.ts.map +1 -1
@@ -4089,7 +4089,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4089
4089
  "presetId": string().readonly(),
4090
4090
  "model": object({
4091
4091
  "provider": string().readonly(),
4092
- "model": string().readonly()
4092
+ "model": string().readonly(),
4093
+ "reasoningEffort": intersection(string(), unknown()).readonly().optional()
4093
4094
  }).readonly().optional(),
4094
4095
  "channelRefs": array(intersection(string(), unknown())).readonly()
4095
4096
  });
@@ -4109,7 +4110,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4109
4110
  "presetId": string().readonly(),
4110
4111
  "model": union([_undefined(), object({
4111
4112
  "provider": string().readonly(),
4112
- "model": string().readonly()
4113
+ "model": string().readonly(),
4114
+ "reasoningEffort": intersection(string(), unknown()).readonly().optional()
4113
4115
  })]).readonly().optional(),
4114
4116
  "privateMemoryPath": string().readonly(),
4115
4117
  "state": union([
@@ -4298,6 +4300,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4298
4300
  }).readonly(),
4299
4301
  "memberIds": array(intersection(string(), unknown())).readonly()
4300
4302
  });
4303
+ const _wowyuarm_dsh_agent_team_agentTeam_getAttachment_parameter_0$schema = object({ "attachmentId": intersection(string(), unknown()).readonly() });
4304
+ const _wowyuarm_dsh_agent_team_agentTeam_getAttachment_result$schema = object({
4305
+ "name": string().readonly(),
4306
+ "mediaType": string().readonly(),
4307
+ "byteSize": number().readonly(),
4308
+ "bytesBase64": string().readonly()
4309
+ });
4301
4310
  const _wowyuarm_dsh_agent_team_agentTeam_inbox_parameter_0$schema = object({
4302
4311
  "workspaceId": intersection(string(), unknown()).readonly(),
4303
4312
  "limit": number().readonly().optional()
@@ -4366,7 +4375,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4366
4375
  "presetId": string().readonly(),
4367
4376
  "model": union([_undefined(), object({
4368
4377
  "provider": string().readonly(),
4369
- "model": string().readonly()
4378
+ "model": string().readonly(),
4379
+ "reasoningEffort": intersection(string(), unknown()).readonly().optional()
4370
4380
  })]).readonly().optional(),
4371
4381
  "state": union([
4372
4382
  literal("enabled"),
@@ -4388,6 +4398,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4388
4398
  ]).readonly(),
4389
4399
  "diagnostic": string().readonly().optional()
4390
4400
  }));
4401
+ const _wowyuarm_dsh_agent_team_agentTeam_putAttachment_parameter_0$schema = object({
4402
+ "requestId": intersection(string(), unknown()).readonly(),
4403
+ "workspaceId": intersection(string(), unknown()).readonly(),
4404
+ "name": string().readonly(),
4405
+ "mediaType": union([_undefined(), string()]).readonly().optional(),
4406
+ "bytesBase64": string().readonly()
4407
+ });
4408
+ const _wowyuarm_dsh_agent_team_agentTeam_putAttachment_result$schema = object({
4409
+ "attachmentId": intersection(string(), unknown()).readonly(),
4410
+ "path": string().readonly(),
4411
+ "name": string().readonly(),
4412
+ "byteSize": number().readonly(),
4413
+ "mediaType": string().readonly()
4414
+ });
4391
4415
  const _wowyuarm_dsh_agent_team_agentTeam_readThread_parameter_0$schema = object({
4392
4416
  "requestId": intersection(string(), unknown()).readonly(),
4393
4417
  "workspaceId": intersection(string(), unknown()).readonly(),
@@ -4441,6 +4465,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4441
4465
  "taskRef": intersection(string(), unknown()).readonly(),
4442
4466
  "sender": intersection(string(), unknown()).readonly(),
4443
4467
  "body": string().readonly(),
4468
+ "attachments": union([_undefined(), array(object({
4469
+ "attachmentId": intersection(string(), unknown()).readonly(),
4470
+ "name": string().readonly(),
4471
+ "byteSize": number().readonly(),
4472
+ "mediaType": string().readonly()
4473
+ }))]).readonly().optional(),
4444
4474
  "topLevel": boolean().readonly(),
4445
4475
  "sequence": number().readonly(),
4446
4476
  "occurredAt": string().readonly()
@@ -4457,6 +4487,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4457
4487
  "taskRef": intersection(string(), unknown()).readonly(),
4458
4488
  "sender": intersection(string(), unknown()).readonly(),
4459
4489
  "body": string().readonly(),
4490
+ "attachments": union([_undefined(), array(object({
4491
+ "attachmentId": intersection(string(), unknown()).readonly(),
4492
+ "name": string().readonly(),
4493
+ "byteSize": number().readonly(),
4494
+ "mediaType": string().readonly()
4495
+ }))]).readonly().optional(),
4460
4496
  "topLevel": boolean().readonly(),
4461
4497
  "sequence": number().readonly(),
4462
4498
  "occurredAt": string().readonly()
@@ -4521,6 +4557,45 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4521
4557
  "sequence": number().readonly()
4522
4558
  })).readonly()
4523
4559
  });
4560
+ const _wowyuarm_dsh_agent_team_agentTeam_recoverMember_parameter_0$schema = object({
4561
+ "requestId": intersection(string(), unknown()).readonly(),
4562
+ "workspaceId": intersection(string(), unknown()).readonly(),
4563
+ "memberId": intersection(string(), unknown()).readonly()
4564
+ });
4565
+ const _wowyuarm_dsh_agent_team_agentTeam_recoverMember_result$schema = object({ "status": object({
4566
+ "member": object({
4567
+ "memberId": intersection(string(), unknown()).readonly(),
4568
+ "sessionId": intersection(string(), unknown()).readonly(),
4569
+ "workspaceId": intersection(string(), unknown()).readonly(),
4570
+ "handle": string().readonly(),
4571
+ "description": string().readonly(),
4572
+ "presetId": string().readonly(),
4573
+ "model": union([_undefined(), object({
4574
+ "provider": string().readonly(),
4575
+ "model": string().readonly(),
4576
+ "reasoningEffort": intersection(string(), unknown()).readonly().optional()
4577
+ })]).readonly().optional(),
4578
+ "privateMemoryPath": string().readonly(),
4579
+ "state": union([
4580
+ literal("enabled"),
4581
+ literal("suspended"),
4582
+ literal("inactive")
4583
+ ]).readonly()
4584
+ }).readonly(),
4585
+ "availability": union([
4586
+ literal("suspended"),
4587
+ literal("inactive"),
4588
+ literal("active"),
4589
+ literal("unavailable")
4590
+ ]).readonly(),
4591
+ "presence": union([
4592
+ literal("unavailable"),
4593
+ literal("available"),
4594
+ literal("working"),
4595
+ literal("error")
4596
+ ]).readonly(),
4597
+ "diagnostic": string().readonly().optional()
4598
+ }).readonly() });
4524
4599
  const _wowyuarm_dsh_agent_team_agentTeam_removeChannelMember_parameter_0$schema = object({
4525
4600
  "requestId": intersection(string(), unknown()).readonly(),
4526
4601
  "workspaceId": intersection(string(), unknown()).readonly(),
@@ -4560,6 +4635,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4560
4635
  "body": string().readonly(),
4561
4636
  "baseRevision": number().readonly(),
4562
4637
  "recipients": array(intersection(string(), unknown())).readonly().optional(),
4638
+ "attachmentPaths": union([_undefined(), array(string())]).readonly().optional(),
4563
4639
  "confirmationToken": intersection(string(), unknown()).readonly().optional()
4564
4640
  });
4565
4641
  const _wowyuarm_dsh_agent_team_agentTeam_reply_result$schema = union([
@@ -4611,6 +4687,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4611
4687
  "taskRef": intersection(string(), unknown()).readonly(),
4612
4688
  "sender": intersection(string(), unknown()).readonly(),
4613
4689
  "body": string().readonly(),
4690
+ "attachments": union([_undefined(), array(object({
4691
+ "attachmentId": intersection(string(), unknown()).readonly(),
4692
+ "name": string().readonly(),
4693
+ "byteSize": number().readonly(),
4694
+ "mediaType": string().readonly()
4695
+ }))]).readonly().optional(),
4614
4696
  "topLevel": boolean().readonly(),
4615
4697
  "sequence": number().readonly(),
4616
4698
  "occurredAt": string().readonly()
@@ -4651,12 +4733,60 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4651
4733
  })).readonly()
4652
4734
  })
4653
4735
  ]);
4736
+ const _wowyuarm_dsh_agent_team_agentTeam_restartMember_parameter_0$schema = object({
4737
+ "requestId": intersection(string(), unknown()).readonly(),
4738
+ "workspaceId": intersection(string(), unknown()).readonly(),
4739
+ "memberId": intersection(string(), unknown()).readonly()
4740
+ });
4741
+ const _wowyuarm_dsh_agent_team_agentTeam_restartMember_result$schema = object({
4742
+ "receipt": object({
4743
+ "operationId": intersection(string(), unknown()).readonly(),
4744
+ "requestId": intersection(string(), unknown()).readonly(),
4745
+ "sequence": number().readonly()
4746
+ }).readonly(),
4747
+ "status": object({
4748
+ "member": object({
4749
+ "memberId": intersection(string(), unknown()).readonly(),
4750
+ "sessionId": intersection(string(), unknown()).readonly(),
4751
+ "workspaceId": intersection(string(), unknown()).readonly(),
4752
+ "handle": string().readonly(),
4753
+ "description": string().readonly(),
4754
+ "presetId": string().readonly(),
4755
+ "model": union([_undefined(), object({
4756
+ "provider": string().readonly(),
4757
+ "model": string().readonly(),
4758
+ "reasoningEffort": intersection(string(), unknown()).readonly().optional()
4759
+ })]).readonly().optional(),
4760
+ "privateMemoryPath": string().readonly(),
4761
+ "state": union([
4762
+ literal("enabled"),
4763
+ literal("suspended"),
4764
+ literal("inactive")
4765
+ ]).readonly()
4766
+ }).readonly(),
4767
+ "availability": union([
4768
+ literal("suspended"),
4769
+ literal("inactive"),
4770
+ literal("active"),
4771
+ literal("unavailable")
4772
+ ]).readonly(),
4773
+ "presence": union([
4774
+ literal("unavailable"),
4775
+ literal("available"),
4776
+ literal("working"),
4777
+ literal("error")
4778
+ ]).readonly(),
4779
+ "diagnostic": string().readonly().optional()
4780
+ }).readonly()
4781
+ });
4654
4782
  const _wowyuarm_dsh_agent_team_agentTeam_sendMessage_parameter_0$schema = object({
4655
4783
  "requestId": intersection(string(), unknown()).readonly(),
4656
4784
  "workspaceId": intersection(string(), unknown()).readonly(),
4657
4785
  "channelRef": intersection(string(), unknown()).readonly(),
4658
4786
  "body": string().readonly(),
4659
4787
  "recipients": array(intersection(string(), unknown())).readonly().optional(),
4788
+ "attachments": union([_undefined(), array(intersection(string(), unknown()))]).readonly().optional(),
4789
+ "attachmentPaths": union([_undefined(), array(string())]).readonly().optional(),
4660
4790
  "confirmationToken": intersection(string(), unknown()).readonly().optional()
4661
4791
  });
4662
4792
  const _wowyuarm_dsh_agent_team_agentTeam_sendMessage_result$schema = union([
@@ -4674,6 +4804,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4674
4804
  "taskRef": intersection(string(), unknown()).readonly(),
4675
4805
  "sender": intersection(string(), unknown()).readonly(),
4676
4806
  "body": string().readonly(),
4807
+ "attachments": union([_undefined(), array(object({
4808
+ "attachmentId": intersection(string(), unknown()).readonly(),
4809
+ "name": string().readonly(),
4810
+ "byteSize": number().readonly(),
4811
+ "mediaType": string().readonly()
4812
+ }))]).readonly().optional(),
4677
4813
  "topLevel": boolean().readonly(),
4678
4814
  "sequence": number().readonly(),
4679
4815
  "occurredAt": string().readonly()
@@ -4769,6 +4905,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4769
4905
  "taskRef": intersection(string(), unknown()).readonly(),
4770
4906
  "sender": intersection(string(), unknown()).readonly(),
4771
4907
  "body": string().readonly(),
4908
+ "attachments": union([_undefined(), array(object({
4909
+ "attachmentId": intersection(string(), unknown()).readonly(),
4910
+ "name": string().readonly(),
4911
+ "byteSize": number().readonly(),
4912
+ "mediaType": string().readonly()
4913
+ }))]).readonly().optional(),
4772
4914
  "topLevel": boolean().readonly(),
4773
4915
  "sequence": number().readonly(),
4774
4916
  "occurredAt": string().readonly()
@@ -4797,6 +4939,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4797
4939
  "taskRef": intersection(string(), unknown()).readonly(),
4798
4940
  "sender": intersection(string(), unknown()).readonly(),
4799
4941
  "body": string().readonly(),
4942
+ "attachments": union([_undefined(), array(object({
4943
+ "attachmentId": intersection(string(), unknown()).readonly(),
4944
+ "name": string().readonly(),
4945
+ "byteSize": number().readonly(),
4946
+ "mediaType": string().readonly()
4947
+ }))]).readonly().optional(),
4800
4948
  "topLevel": boolean().readonly(),
4801
4949
  "sequence": number().readonly(),
4802
4950
  "occurredAt": string().readonly()
@@ -4886,7 +5034,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4886
5034
  "description": string().readonly(),
4887
5035
  "model": object({
4888
5036
  "provider": string().readonly(),
4889
- "model": string().readonly()
5037
+ "model": string().readonly(),
5038
+ "reasoningEffort": intersection(string(), unknown()).readonly().optional()
4890
5039
  }).readonly().optional()
4891
5040
  });
4892
5041
  const _wowyuarm_dsh_agent_team_agentTeam_updateMember_result$schema = object({
@@ -4905,7 +5054,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4905
5054
  "presetId": string().readonly(),
4906
5055
  "model": union([_undefined(), object({
4907
5056
  "provider": string().readonly(),
4908
- "model": string().readonly()
5057
+ "model": string().readonly(),
5058
+ "reasoningEffort": intersection(string(), unknown()).readonly().optional()
4909
5059
  })]).readonly().optional(),
4910
5060
  "privateMemoryPath": string().readonly(),
4911
5061
  "state": union([
@@ -4986,6 +5136,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4986
5136
  "taskRef": intersection(string(), unknown()).readonly(),
4987
5137
  "sender": intersection(string(), unknown()).readonly(),
4988
5138
  "body": string().readonly(),
5139
+ "attachments": union([_undefined(), array(object({
5140
+ "attachmentId": intersection(string(), unknown()).readonly(),
5141
+ "name": string().readonly(),
5142
+ "byteSize": number().readonly(),
5143
+ "mediaType": string().readonly()
5144
+ }))]).readonly().optional(),
4989
5145
  "topLevel": boolean().readonly(),
4990
5146
  "sequence": number().readonly(),
4991
5147
  "occurredAt": string().readonly()
@@ -5095,7 +5251,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5095
5251
  },
5096
5252
  sourceLocation: {
5097
5253
  "file": "packages/agent-team/src/index.ts",
5098
- "line": 284,
5254
+ "line": 325,
5099
5255
  "column": 9
5100
5256
  }
5101
5257
  },
@@ -5122,7 +5278,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5122
5278
  },
5123
5279
  sourceLocation: {
5124
5280
  "file": "packages/agent-team/src/index.ts",
5125
- "line": 428,
5281
+ "line": 663,
5126
5282
  "column": 9
5127
5283
  }
5128
5284
  },
@@ -5150,7 +5306,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5150
5306
  },
5151
5307
  sourceLocation: {
5152
5308
  "file": "packages/agent-team/src/index.ts",
5153
- "line": 221,
5309
+ "line": 262,
5154
5310
  "column": 9
5155
5311
  }
5156
5312
  },
@@ -5177,7 +5333,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5177
5333
  },
5178
5334
  sourceLocation: {
5179
5335
  "file": "packages/agent-team/src/index.ts",
5180
- "line": 376,
5336
+ "line": 543,
5181
5337
  "column": 9
5182
5338
  }
5183
5339
  },
@@ -5204,7 +5360,34 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5204
5360
  },
5205
5361
  sourceLocation: {
5206
5362
  "file": "packages/agent-team/src/index.ts",
5207
- "line": 262,
5363
+ "line": 303,
5364
+ "column": 9
5365
+ }
5366
+ },
5367
+ {
5368
+ id: "@wowyuarm/dsh-agent-team#agentTeam/getAttachment",
5369
+ service: "agentTeam",
5370
+ namespace: "agentTeam",
5371
+ method: "getAttachment",
5372
+ invocation: { kind: "direct" },
5373
+ parameters: [{
5374
+ name: "request",
5375
+ wire: "request",
5376
+ source: "json",
5377
+ codec: {
5378
+ mode: "strict",
5379
+ typeSymbol: "@wowyuarm/dsh-agent-team/types#AgentTeamGetAttachmentRequest",
5380
+ schema: _wowyuarm_dsh_agent_team_agentTeam_getAttachment_parameter_0$schema
5381
+ }
5382
+ }],
5383
+ result: {
5384
+ mode: "strict",
5385
+ typeSymbol: "@wowyuarm/dsh-agent-team/types#AgentTeamGetAttachmentResult",
5386
+ schema: _wowyuarm_dsh_agent_team_agentTeam_getAttachment_result$schema
5387
+ },
5388
+ sourceLocation: {
5389
+ "file": "packages/agent-team/src/index.ts",
5390
+ "line": 640,
5208
5391
  "column": 9
5209
5392
  }
5210
5393
  },
@@ -5231,7 +5414,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5231
5414
  },
5232
5415
  sourceLocation: {
5233
5416
  "file": "packages/agent-team/src/index.ts",
5234
- "line": 438,
5417
+ "line": 673,
5235
5418
  "column": 3
5236
5419
  }
5237
5420
  },
@@ -5258,7 +5441,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5258
5441
  },
5259
5442
  sourceLocation: {
5260
5443
  "file": "packages/agent-team/src/index.ts",
5261
- "line": 386,
5444
+ "line": 553,
5262
5445
  "column": 9
5263
5446
  }
5264
5447
  },
@@ -5286,10 +5469,37 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5286
5469
  },
5287
5470
  sourceLocation: {
5288
5471
  "file": "packages/agent-team/src/index.ts",
5289
- "line": 212,
5472
+ "line": 253,
5290
5473
  "column": 3
5291
5474
  }
5292
5475
  },
5476
+ {
5477
+ id: "@wowyuarm/dsh-agent-team#agentTeam/putAttachment",
5478
+ service: "agentTeam",
5479
+ namespace: "agentTeam",
5480
+ method: "putAttachment",
5481
+ invocation: { kind: "direct" },
5482
+ parameters: [{
5483
+ name: "request",
5484
+ wire: "request",
5485
+ source: "json",
5486
+ codec: {
5487
+ mode: "strict",
5488
+ typeSymbol: "@wowyuarm/dsh-agent-team/types#AgentTeamPutAttachmentRequest",
5489
+ schema: _wowyuarm_dsh_agent_team_agentTeam_putAttachment_parameter_0$schema
5490
+ }
5491
+ }],
5492
+ result: {
5493
+ mode: "strict",
5494
+ typeSymbol: "@wowyuarm/dsh-agent-team/types#AgentTeamPutAttachmentResult",
5495
+ schema: _wowyuarm_dsh_agent_team_agentTeam_putAttachment_result$schema
5496
+ },
5497
+ sourceLocation: {
5498
+ "file": "packages/agent-team/src/index.ts",
5499
+ "line": 627,
5500
+ "column": 9
5501
+ }
5502
+ },
5293
5503
  {
5294
5504
  id: "@wowyuarm/dsh-agent-team#agentTeam/readThread",
5295
5505
  service: "agentTeam",
@@ -5313,7 +5523,34 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5313
5523
  },
5314
5524
  sourceLocation: {
5315
5525
  "file": "packages/agent-team/src/index.ts",
5316
- "line": 445,
5526
+ "line": 680,
5527
+ "column": 9
5528
+ }
5529
+ },
5530
+ {
5531
+ id: "@wowyuarm/dsh-agent-team#agentTeam/recoverMember",
5532
+ service: "agentTeam",
5533
+ namespace: "agentTeam",
5534
+ method: "recoverMember",
5535
+ invocation: { kind: "direct" },
5536
+ parameters: [{
5537
+ name: "request",
5538
+ wire: "request",
5539
+ source: "json",
5540
+ codec: {
5541
+ mode: "strict",
5542
+ typeSymbol: "@wowyuarm/dsh-agent-team/types#AgentTeamRecoverMemberRequest",
5543
+ schema: _wowyuarm_dsh_agent_team_agentTeam_recoverMember_parameter_0$schema
5544
+ }
5545
+ }],
5546
+ result: {
5547
+ mode: "strict",
5548
+ typeSymbol: "@wowyuarm/dsh-agent-team/types#AgentTeamRecoverMemberResult",
5549
+ schema: _wowyuarm_dsh_agent_team_agentTeam_recoverMember_result$schema
5550
+ },
5551
+ sourceLocation: {
5552
+ "file": "packages/agent-team/src/index.ts",
5553
+ "line": 382,
5317
5554
  "column": 9
5318
5555
  }
5319
5556
  },
@@ -5340,7 +5577,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5340
5577
  },
5341
5578
  sourceLocation: {
5342
5579
  "file": "packages/agent-team/src/index.ts",
5343
- "line": 398,
5580
+ "line": 565,
5344
5581
  "column": 9
5345
5582
  }
5346
5583
  },
@@ -5367,7 +5604,34 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5367
5604
  },
5368
5605
  sourceLocation: {
5369
5606
  "file": "packages/agent-team/src/index.ts",
5370
- "line": 418,
5607
+ "line": 648,
5608
+ "column": 9
5609
+ }
5610
+ },
5611
+ {
5612
+ id: "@wowyuarm/dsh-agent-team#agentTeam/restartMember",
5613
+ service: "agentTeam",
5614
+ namespace: "agentTeam",
5615
+ method: "restartMember",
5616
+ invocation: { kind: "direct" },
5617
+ parameters: [{
5618
+ name: "request",
5619
+ wire: "request",
5620
+ source: "json",
5621
+ codec: {
5622
+ mode: "strict",
5623
+ typeSymbol: "@wowyuarm/dsh-agent-team/types#AgentTeamRestartMemberRequest",
5624
+ schema: _wowyuarm_dsh_agent_team_agentTeam_restartMember_parameter_0$schema
5625
+ }
5626
+ }],
5627
+ result: {
5628
+ mode: "strict",
5629
+ typeSymbol: "@wowyuarm/dsh-agent-team/types#AgentTeamRestartMemberResult",
5630
+ schema: _wowyuarm_dsh_agent_team_agentTeam_restartMember_result$schema
5631
+ },
5632
+ sourceLocation: {
5633
+ "file": "packages/agent-team/src/index.ts",
5634
+ "line": 401,
5371
5635
  "column": 9
5372
5636
  }
5373
5637
  },
@@ -5394,7 +5658,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5394
5658
  },
5395
5659
  sourceLocation: {
5396
5660
  "file": "packages/agent-team/src/index.ts",
5397
- "line": 408,
5661
+ "line": 575,
5398
5662
  "column": 9
5399
5663
  }
5400
5664
  },
@@ -5421,7 +5685,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5421
5685
  },
5422
5686
  sourceLocation: {
5423
5687
  "file": "packages/agent-team/src/index.ts",
5424
- "line": 462,
5688
+ "line": 697,
5425
5689
  "column": 3
5426
5690
  }
5427
5691
  },
@@ -5448,7 +5712,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5448
5712
  },
5449
5713
  sourceLocation: {
5450
5714
  "file": "packages/agent-team/src/index.ts",
5451
- "line": 455,
5715
+ "line": 690,
5452
5716
  "column": 3
5453
5717
  }
5454
5718
  },
@@ -5475,7 +5739,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5475
5739
  },
5476
5740
  sourceLocation: {
5477
5741
  "file": "packages/agent-team/src/index.ts",
5478
- "line": 274,
5742
+ "line": 315,
5479
5743
  "column": 9
5480
5744
  }
5481
5745
  },
@@ -5502,7 +5766,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5502
5766
  },
5503
5767
  sourceLocation: {
5504
5768
  "file": "packages/agent-team/src/index.ts",
5505
- "line": 341,
5769
+ "line": 507,
5506
5770
  "column": 9
5507
5771
  }
5508
5772
  },
@@ -5529,7 +5793,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5529
5793
  },
5530
5794
  sourceLocation: {
5531
5795
  "file": "packages/agent-team/src/index.ts",
5532
- "line": 469,
5796
+ "line": 704,
5533
5797
  "column": 3
5534
5798
  }
5535
5799
  }
@@ -5537,14 +5801,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5537
5801
  };
5538
5802
  //#endregion
5539
5803
  //#region src/client/navigation.ts
5540
- const STORAGE_KEY = "dsh.agent-team.navigation";
5804
+ const STORAGE_KEY$1 = "dsh.agent-team.navigation";
5541
5805
  function readSnapshot() {
5542
5806
  if (typeof localStorage === "undefined") return { mode: "conversation" };
5543
5807
  try {
5544
5808
  const parsed = JSON.parse(localStorage.getItem("dsh.agent-team.navigation") ?? "");
5809
+ const hasThread = typeof parsed.taskRef === "string" && typeof parsed.threadRef === "string";
5545
5810
  return {
5546
5811
  mode: parsed.mode === "team" ? "team" : "conversation",
5547
- ...typeof parsed.workspaceId === "string" ? { workspaceId: parsed.workspaceId } : {}
5812
+ ...typeof parsed.workspaceId === "string" ? { workspaceId: parsed.workspaceId } : {},
5813
+ ...typeof parsed.channelRef === "string" ? { channelRef: parsed.channelRef } : {},
5814
+ ...hasThread ? {
5815
+ taskRef: parsed.taskRef,
5816
+ threadRef: parsed.threadRef,
5817
+ ...typeof parsed.taskNumber === "number" && Number.isInteger(parsed.taskNumber) && parsed.taskNumber > 0 ? { taskNumber: parsed.taskNumber } : {}
5818
+ } : {}
5548
5819
  };
5549
5820
  } catch {
5550
5821
  return { mode: "conversation" };
@@ -5553,10 +5824,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5553
5824
  function persistSnapshot(snapshot) {
5554
5825
  if (typeof localStorage === "undefined") return;
5555
5826
  try {
5556
- const { mode, workspaceId } = snapshot;
5557
- localStorage.setItem(STORAGE_KEY, JSON.stringify({
5827
+ const { mode, workspaceId, channelRef, taskRef, threadRef, taskNumber } = snapshot;
5828
+ localStorage.setItem(STORAGE_KEY$1, JSON.stringify({
5558
5829
  mode,
5559
- ...workspaceId === void 0 ? {} : { workspaceId }
5830
+ ...workspaceId === void 0 ? {} : { workspaceId },
5831
+ ...channelRef === void 0 ? {} : { channelRef },
5832
+ ...taskRef === void 0 ? {} : { taskRef },
5833
+ ...threadRef === void 0 ? {} : { threadRef },
5834
+ ...taskNumber === void 0 ? {} : { taskNumber }
5560
5835
  }));
5561
5836
  } catch {}
5562
5837
  }
@@ -5574,25 +5849,37 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5574
5849
  actions() {
5575
5850
  return {
5576
5851
  enterTeam: () => {
5852
+ this.clearMemberSession();
5577
5853
  this.setMode("team");
5578
5854
  },
5579
5855
  leaveTeam: () => {
5580
5856
  this.setMode("conversation");
5581
5857
  },
5582
5858
  selectWorkspace: (workspaceId) => {
5859
+ this.clearMemberSession();
5583
5860
  this.setWorkspace(workspaceId);
5584
5861
  },
5585
5862
  selectChannel: (channelRef) => {
5863
+ this.clearMemberSession();
5586
5864
  this.setChannel(channelRef);
5587
5865
  },
5588
5866
  selectThread: (taskRef, threadRef, channelRef, taskNumber) => {
5867
+ this.clearMemberSession();
5589
5868
  this.setThread(taskRef, threadRef, channelRef, taskNumber);
5590
5869
  },
5591
5870
  backToWorkspace: () => {
5871
+ this.clearMemberSession();
5592
5872
  this.setThread(void 0);
5593
5873
  },
5594
5874
  backToChannels: () => {
5875
+ this.clearMemberSession();
5595
5876
  this.clearChannel();
5877
+ },
5878
+ enterMemberSession: (sessionId, returnToSessionId) => {
5879
+ this.setMemberSession(sessionId, returnToSessionId);
5880
+ },
5881
+ exitMemberSession: () => {
5882
+ this.clearMemberSession();
5596
5883
  }
5597
5884
  };
5598
5885
  }
@@ -5607,6 +5894,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5607
5894
  };
5608
5895
  this.commit();
5609
5896
  }
5897
+ setMemberSession(sessionId, returnToSessionId) {
5898
+ if (this.snapshot.memberSessionId === sessionId && this.snapshot.mode === "team") return;
5899
+ const { memberSessionId: _memberSessionId, ...base } = this.snapshot;
5900
+ this.snapshot = {
5901
+ ...base,
5902
+ mode: "team",
5903
+ memberSessionId: sessionId,
5904
+ ...returnToSessionId === void 0 ? {} : { returnToSessionId }
5905
+ };
5906
+ this.commit();
5907
+ }
5908
+ /** Any explicit Team navigation or the footer leave closes a Member view. */
5909
+ clearMemberSession() {
5910
+ if (this.snapshot.memberSessionId === void 0 && this.snapshot.returnToSessionId === void 0) return;
5911
+ const { memberSessionId: _memberSessionId, returnToSessionId: _returnToSessionId, ...base } = this.snapshot;
5912
+ this.snapshot = base;
5913
+ this.commit();
5914
+ }
5610
5915
  setWorkspace(workspaceId) {
5611
5916
  if (this.snapshot.workspaceId === workspaceId) return;
5612
5917
  const { channelRef: _channelRef, taskRef: _taskRef, threadRef: _threadRef, taskNumber: _taskNumber, ...base } = this.snapshot;
@@ -5730,6 +6035,136 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5730
6035
  }
5731
6036
  };
5732
6037
  //#endregion
6038
+ //#region src/client/drafts.ts
6039
+ const STORAGE_KEY = "dsh.agent-team.drafts.v1";
6040
+ /** Retention ceiling; the oldest savedAt entries fall out first. */
6041
+ const LIMIT = 50;
6042
+ const EMPTY = Object.freeze({
6043
+ draft: "",
6044
+ recipients: /* @__PURE__ */ new Set()
6045
+ });
6046
+ function isTeamDraftKey(value) {
6047
+ return value.startsWith("channel:") || value.startsWith("thread:");
6048
+ }
6049
+ function readStored() {
6050
+ if (typeof localStorage === "undefined") return /* @__PURE__ */ new Map();
6051
+ try {
6052
+ const parsed = JSON.parse(localStorage.getItem("dsh.agent-team.drafts.v1") ?? "");
6053
+ const restored = /* @__PURE__ */ new Map();
6054
+ for (const [key, value] of Object.entries(parsed)) {
6055
+ if (!isTeamDraftKey(key) || typeof value !== "object" || value === null) continue;
6056
+ const candidate = value;
6057
+ if (typeof candidate.draft !== "string" || !Array.isArray(candidate.recipientIds) || typeof candidate.savedAt !== "number") continue;
6058
+ if (!candidate.recipientIds.every((id) => typeof id === "string")) continue;
6059
+ restored.set(key, {
6060
+ draft: candidate.draft,
6061
+ recipientIds: candidate.recipientIds,
6062
+ savedAt: candidate.savedAt
6063
+ });
6064
+ }
6065
+ return restored;
6066
+ } catch {
6067
+ return /* @__PURE__ */ new Map();
6068
+ }
6069
+ }
6070
+ function persistStored(entries) {
6071
+ if (typeof localStorage === "undefined") return;
6072
+ try {
6073
+ const payload = Object.fromEntries([...entries].map(([key, entry]) => [key, entry]));
6074
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(payload));
6075
+ } catch {}
6076
+ }
6077
+ /**
6078
+ * Root-scoped draft cache, one instance per Client context (created in
6079
+ * `applyUi` and injected like the navigation service — never a module
6080
+ * singleton). Slot lifetimes subscribe per key.
6081
+ */
6082
+ var TeamDraftStore = class {
6083
+ entries = readStored();
6084
+ snapshots = /* @__PURE__ */ new Map();
6085
+ listeners = /* @__PURE__ */ new Set();
6086
+ subscribe = (listener) => {
6087
+ this.listeners.add(listener);
6088
+ return () => {
6089
+ this.listeners.delete(listener);
6090
+ };
6091
+ };
6092
+ /** Release listeners when the owning Client context disposes. */
6093
+ dispose() {
6094
+ this.listeners.clear();
6095
+ }
6096
+ /** Stable per-key snapshot identity for useSyncExternalStore. */
6097
+ getSnapshot = (key) => {
6098
+ const cached = this.snapshots.get(key);
6099
+ if (cached !== void 0) return cached;
6100
+ const entry = this.entries.get(key);
6101
+ if (entry === void 0) return EMPTY;
6102
+ const snapshot = Object.freeze({
6103
+ draft: entry.draft,
6104
+ recipients: new Set(entry.recipientIds)
6105
+ });
6106
+ this.snapshots.set(key, snapshot);
6107
+ return snapshot;
6108
+ };
6109
+ writeDraft(key, draft) {
6110
+ this.write(key, { draft });
6111
+ }
6112
+ writeRecipients(key, recipients) {
6113
+ this.write(key, { recipientIds: [...recipients] });
6114
+ }
6115
+ /** Drop one key entirely — the success path after a committed send. */
6116
+ clear(key) {
6117
+ if (!this.entries.delete(key)) return;
6118
+ this.snapshots.delete(key);
6119
+ persistStored(this.entries);
6120
+ for (const listener of this.listeners) listener();
6121
+ }
6122
+ /** Test seam: forget everything, including what localStorage still holds. */
6123
+ reset() {
6124
+ this.entries = /* @__PURE__ */ new Map();
6125
+ this.snapshots.clear();
6126
+ if (typeof localStorage !== "undefined") localStorage.removeItem(STORAGE_KEY);
6127
+ for (const listener of this.listeners) listener();
6128
+ }
6129
+ /** Re-read persisted content — what a fresh page load starts from. */
6130
+ reload() {
6131
+ this.entries = readStored();
6132
+ this.snapshots.clear();
6133
+ for (const listener of this.listeners) listener();
6134
+ }
6135
+ write(key, patch) {
6136
+ const previous = this.entries.get(key);
6137
+ const next = {
6138
+ draft: patch.draft ?? previous?.draft ?? "",
6139
+ recipientIds: patch.recipientIds ?? previous?.recipientIds ?? [],
6140
+ savedAt: Date.now()
6141
+ };
6142
+ if (previous !== void 0 && previous.draft === next.draft && previous.recipientIds.length === next.recipientIds.length && previous.recipientIds.every((id, index) => id === next.recipientIds[index])) return;
6143
+ if (next.draft === "" && next.recipientIds.length === 0) {
6144
+ this.clear(key);
6145
+ return;
6146
+ }
6147
+ this.entries.set(key, next);
6148
+ this.evict();
6149
+ this.snapshots.delete(key);
6150
+ persistStored(this.entries);
6151
+ for (const listener of this.listeners) listener();
6152
+ }
6153
+ evict() {
6154
+ while (this.entries.size > LIMIT) {
6155
+ let oldestKey;
6156
+ let oldestSavedAt = Number.POSITIVE_INFINITY;
6157
+ for (const [key, entry] of this.entries) if (entry.savedAt < oldestSavedAt) {
6158
+ oldestSavedAt = entry.savedAt;
6159
+ oldestKey = key;
6160
+ }
6161
+ if (oldestKey === void 0) return;
6162
+ this.entries.delete(oldestKey);
6163
+ this.snapshots.delete(oldestKey);
6164
+ }
6165
+ }
6166
+ };
6167
+ //#endregion
5733
6168
  //#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/team.module.css.mjs
5734
6169
  const css$8 = ".YvAbSa_footerStack{flex:none;width:100%;height:42px;margin:8px 0 0;display:flex}.YvAbSa_footerAction,.YvAbSa_settingsAction{box-sizing:border-box;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:8px;width:calc(100% + 4px);height:42px;padding:0 10px 0 8px;font-family:inherit;font-size:14px;line-height:22px;display:flex;overflow:hidden}.YvAbSa_footerAction{margin:0 -2px}.YvAbSa_settingsAction{margin:4px -2px}.YvAbSa_footerAction:hover,.YvAbSa_footerAction:focus-visible,.YvAbSa_settingsAction:hover,.YvAbSa_settingsAction:focus-visible{background:var(--dsw-alias-interactive-bg-hover);outline:none}.YvAbSa_footerAction.YvAbSa_rail,.YvAbSa_settingsAction.YvAbSa_rail{border-radius:50%;justify-content:center;width:36px;height:36px;padding:0}.YvAbSa_footerAction.YvAbSa_rail{margin:0}.YvAbSa_settingsAction.YvAbSa_rail{margin:8px 0 10px}.YvAbSa_railStack{align-items:center;width:36px;height:36px;margin:0}";
5735
6170
  const tagId$8 = "@wowyuarm/dsh-agent-team/team.module.css";
@@ -5781,7 +6216,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5781
6216
  }
5782
6217
  //#endregion
5783
6218
  //#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/presence.module.css.mjs
5784
- const css$7 = ".-\\36 lQ-q_target{flex:0 0 14px;justify-content:center;align-items:center;display:inline-flex}.-\\36 lQ-q_unavailableDot{background:var(--dsw-alias-text-disabled);border-radius:50%;width:7px;height:7px;display:inline-block}";
6219
+ const css$7 = ".-\\36 lQ-q_target{flex:0 0 14px;justify-content:center;align-items:center;display:inline-flex}.-\\36 lQ-q_unavailableDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;width:7px;height:7px;display:inline-block}";
5785
6220
  const tagId$7 = "@wowyuarm/dsh-agent-team/presence.module.css";
5786
6221
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$7) + "]") === null) {
5787
6222
  const tag = document.createElement("style");
@@ -5823,7 +6258,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5823
6258
  }
5824
6259
  //#endregion
5825
6260
  //#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/members.module.css.mjs
5826
- const css$6 = ".UkovOW_body{max-height:min(65vh,560px);overflow-y:auto}.UkovOW_content{outline:none;gap:12px;display:grid}.UkovOW_group{gap:3px;display:grid}.UkovOW_group+.UkovOW_group{border-top:1px solid var(--dsw-alias-border-subtle);padding-top:10px}.UkovOW_group h3{color:var(--dsw-alias-text-secondary);margin:0 0 3px;font-size:12px;font-weight:600;line-height:18px}.UkovOW_member{border-radius:6px;grid-template-columns:14px minmax(0,1fr);align-items:center;gap:0 8px;min-height:36px;padding:4px 6px;display:grid}.UkovOW_member:hover{background:var(--dsw-alias-interactive-bg-hover)}.UkovOW_copy{min-width:0;display:grid}.UkovOW_copy strong{color:var(--dsw-alias-text-primary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:500;line-height:18px;overflow:hidden}.UkovOW_copy small{color:var(--dsw-alias-text-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:14px;overflow:hidden}.UkovOW_state,.UkovOW_error{margin:0;padding:6px 0;font-size:12px;line-height:18px}.UkovOW_state{color:var(--dsw-alias-text-tertiary)}.UkovOW_error{color:var(--dsw-alias-state-error-primary)}@media (width<=600px){.UkovOW_body{max-height:calc(100vh - 160px)}}";
6261
+ const css$6 = ".UkovOW_body{max-height:min(65vh,560px);overflow-y:auto}.UkovOW_content{outline:none;gap:12px;display:grid}.UkovOW_group{gap:3px;display:grid}.UkovOW_group+.UkovOW_group{border-top:1px solid var(--dsw-alias-border-l2);padding-top:10px}.UkovOW_group h3{color:var(--dsw-alias-label-secondary);margin:0 0 3px;font-size:12px;font-weight:600;line-height:18px}.UkovOW_member{border-radius:6px;grid-template-columns:14px minmax(0,1fr);align-items:center;gap:0 8px;min-height:36px;padding:4px 6px;display:grid}.UkovOW_member:hover{background:var(--dsw-alias-interactive-bg-hover)}.UkovOW_copy{min-width:0;display:grid}.UkovOW_copy strong{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:500;line-height:18px;overflow:hidden}.UkovOW_copy small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:14px;overflow:hidden}.UkovOW_state,.UkovOW_error{margin:0;padding:6px 0;font-size:12px;line-height:18px}.UkovOW_state{color:var(--dsw-alias-label-tertiary)}.UkovOW_error{color:var(--dsw-alias-state-error-primary)}@media (width<=600px){.UkovOW_body{max-height:calc(100vh - 160px)}}";
5827
6262
  const tagId$6 = "@wowyuarm/dsh-agent-team/members.module.css";
5828
6263
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$6) + "]") === null) {
5829
6264
  const tag = document.createElement("style");
@@ -5941,8 +6376,40 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5941
6376
  });
5942
6377
  }
5943
6378
  //#endregion
6379
+ //#region src/client/attachment-preview.ts
6380
+ /** Base64 one file payload in chunks so large uploads stay off the call-stack limit. */
6381
+ function bytesToBase64(bytes) {
6382
+ let binary = "";
6383
+ const chunk = 32768;
6384
+ for (let start = 0; start < bytes.length; start += chunk) binary += String.fromCharCode(...bytes.subarray(start, start + chunk));
6385
+ return btoa(binary);
6386
+ }
6387
+ /**
6388
+ * Thumbnail data URLs live in one session-wide cache: message lists re-render
6389
+ * often, and each miss costs a Host round-trip plus a base64 decode. Failed
6390
+ * loads (bytes already GC'd) are cached as `null` so the chip fallback is stable.
6391
+ */
6392
+ const dataUrlCache = /* @__PURE__ */ new Map();
6393
+ function cachedAttachmentDataUrl(attachmentId) {
6394
+ return dataUrlCache.get(attachmentId);
6395
+ }
6396
+ async function loadAttachmentDataUrl(getAttachment, attachment) {
6397
+ const cached = dataUrlCache.get(attachment.attachmentId);
6398
+ if (cached !== void 0) return cached;
6399
+ const result = await getAttachment({ attachmentId: attachment.attachmentId });
6400
+ const url = result.ok && attachment.mediaType.startsWith("image/") ? `data:${attachment.mediaType};base64,${result.value.bytesBase64}` : null;
6401
+ dataUrlCache.set(attachment.attachmentId, url);
6402
+ return url;
6403
+ }
6404
+ /** Human-readable byte size for attachment chips. */
6405
+ function formatByteSize(byteSize) {
6406
+ if (byteSize < 1024) return `${byteSize} B`;
6407
+ if (byteSize < 1024 * 1024) return `${(byteSize / 1024).toFixed(0)} KB`;
6408
+ return `${(byteSize / (1024 * 1024)).toFixed(1)} MB`;
6409
+ }
6410
+ //#endregion
5944
6411
  //#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/composer.module.css.mjs
5945
- 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-surface-primary));box-shadow:var(--dsw-shadow-lv2);border-radius:22px;flex-direction:column;gap:6px;padding:10px 0 0;display:flex;position:relative}.x9jGQq_card:focus-within{border-color:var(--dsw-alias-state-business-primary)}.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-text-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-text-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-text-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-text-tertiary));text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.x9jGQq_toolbar{justify-content:flex-end;align-items:center;min-height:34px;padding:2px 8px 6px;display:flex}.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-text-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-text-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}}";
6412
+ 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_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}}";
5946
6413
  const tagId$5 = "@wowyuarm/dsh-agent-team/composer.module.css";
5947
6414
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$5) + "]") === null) {
5948
6415
  const tag = document.createElement("style");
@@ -5952,9 +6419,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5952
6419
  document.head.appendChild(tag);
5953
6420
  }
5954
6421
  var composer_module_css_default = {
6422
+ "attachButton": "x9jGQq_attachButton",
5955
6423
  "card": "x9jGQq_card",
5956
6424
  "confirmation": "x9jGQq_confirmation",
5957
6425
  "error": "x9jGQq_error",
6426
+ "fileChip": "x9jGQq_fileChip",
6427
+ "fileChipName": "x9jGQq_fileChipName",
6428
+ "fileChipRemove": "x9jGQq_fileChipRemove",
6429
+ "fileChips": "x9jGQq_fileChips",
6430
+ "fileInput": "x9jGQq_fileInput",
5958
6431
  "inputArea": "x9jGQq_inputArea",
5959
6432
  "mentionDescription": "x9jGQq_mentionDescription",
5960
6433
  "mentionMenu": "x9jGQq_mentionMenu",
@@ -5991,8 +6464,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5991
6464
  const normalized = query.toLocaleLowerCase();
5992
6465
  return members.filter((status) => status.presence !== "unavailable" && status.member.state !== "inactive" && status.member.handle.toLocaleLowerCase().startsWith(normalized));
5993
6466
  }
5994
- function TeamComposer({ members, recipients, draft, pending, confirmation, error, onDraftChange, onRecipientsChange, onSubmit, t }) {
6467
+ function TeamComposer({ members, recipients, draft, pending, confirmation, error, onDraftChange, onRecipientsChange, onSubmit, pendingFiles, onFilesChange, t }) {
5995
6468
  const inputRef = (0, react.useRef)(null);
6469
+ const fileInputRef = (0, react.useRef)(null);
5996
6470
  const rootRef = (0, react.useRef)(null);
5997
6471
  const menuRef = (0, react.useRef)(null);
5998
6472
  const composingRef = (0, react.useRef)(false);
@@ -6019,6 +6493,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6019
6493
  }
6020
6494
  setHighlight((current) => Math.min(current, candidates.length - 1));
6021
6495
  }, [mention, candidates.length]);
6496
+ (0, react.useEffect)(() => {
6497
+ const active = document.activeElement;
6498
+ if (active !== document.body && active?.closest("[aria-current=\"page\"]") === null) return;
6499
+ inputRef.current?.focus({ preventScroll: true });
6500
+ }, []);
6501
+ (0, react.useEffect)(() => {
6502
+ if (confirmation === void 0 || pending) return;
6503
+ inputRef.current?.focus({ preventScroll: true });
6504
+ }, [confirmation, pending]);
6022
6505
  const pruneRecipients = (nextDraft) => {
6023
6506
  const knownMembers = new Map(members.map((status) => [status.member.memberId, status.member]));
6024
6507
  const next = new Set([...recipients].filter((memberId) => {
@@ -6027,6 +6510,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6027
6510
  }));
6028
6511
  if (next.size !== recipients.size) onRecipientsChange(next);
6029
6512
  };
6513
+ (0, react.useEffect)(() => {
6514
+ if (members.length === 0) return;
6515
+ pruneRecipients(draft);
6516
+ }, [
6517
+ draft,
6518
+ recipients,
6519
+ members
6520
+ ]);
6030
6521
  const updateMention = (nextDraft, caret) => {
6031
6522
  const match = findMention(nextDraft, caret);
6032
6523
  setMention(match);
@@ -6090,6 +6581,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6090
6581
  ref: rootRef,
6091
6582
  className: composer_module_css_default.root,
6092
6583
  onSubmit: (event) => {
6584
+ console.log("DBG composer submit pending=%s draft=%j", pending, draft);
6093
6585
  event.preventDefault();
6094
6586
  if (!pending && draft.trim() !== "") onSubmit();
6095
6587
  },
@@ -6148,7 +6640,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6148
6640
  "aria-activedescendant": menuOpen && activeCandidate !== void 0 ? `${listId}-${activeCandidate.member.memberId}` : void 0,
6149
6641
  "aria-expanded": menuOpen,
6150
6642
  value: draft,
6151
- disabled: pending,
6643
+ readOnly: pending,
6152
6644
  placeholder: t("messagePlaceholder"),
6153
6645
  rows: 1,
6154
6646
  onChange,
@@ -6171,15 +6663,62 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6171
6663
  "data-team-notify": true,
6172
6664
  children: t("composerNotify", { ids: [...recipients].sort().map((memberId) => `@${members.find((candidate) => candidate.member.memberId === memberId)?.member.handle ?? memberId}`).join(", ") })
6173
6665
  }),
6174
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6666
+ onFilesChange !== void 0 && pendingFiles !== void 0 && pendingFiles.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
6667
+ className: composer_module_css_default.fileChips,
6668
+ "aria-label": t("attachFiles"),
6669
+ children: pendingFiles.map((file, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
6670
+ className: composer_module_css_default.fileChip,
6671
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6672
+ className: composer_module_css_default.fileChipName,
6673
+ title: file.name,
6674
+ children: file.name
6675
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6676
+ type: "button",
6677
+ className: composer_module_css_default.fileChipRemove,
6678
+ "aria-label": t("removeFile", { name: file.name }),
6679
+ disabled: pending,
6680
+ onClick: () => {
6681
+ onFilesChange(pendingFiles.filter((_, candidate) => candidate !== index));
6682
+ },
6683
+ children: "×"
6684
+ })]
6685
+ }, `${file.name}-${index}`))
6686
+ }),
6687
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6175
6688
  className: composer_module_css_default.toolbar,
6176
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6689
+ children: [onFilesChange !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
6690
+ ref: fileInputRef,
6691
+ type: "file",
6692
+ multiple: true,
6693
+ className: composer_module_css_default.fileInput,
6694
+ "aria-hidden": "true",
6695
+ tabIndex: -1,
6696
+ onChange: (event) => {
6697
+ const chosen = [...event.target.files ?? []];
6698
+ if (chosen.length > 0 && pendingFiles !== void 0) onFilesChange([...pendingFiles, ...chosen]);
6699
+ event.target.value = "";
6700
+ }
6701
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6702
+ type: "button",
6703
+ className: composer_module_css_default.attachButton,
6704
+ "aria-label": t("attachFiles"),
6705
+ title: t("attachFiles"),
6706
+ disabled: pending,
6707
+ onClick: () => {
6708
+ fileInputRef.current?.click();
6709
+ },
6710
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, { size: 14 })
6711
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6177
6712
  type: "submit",
6178
6713
  className: composer_module_css_default.sendButton,
6179
6714
  "aria-label": pending ? t("sendingMessage") : t("sendMessage"),
6180
6715
  disabled: pending || draft.trim() === "",
6716
+ onMouseDown: (event) => {
6717
+ event.preventDefault();
6718
+ inputRef.current?.focus({ preventScroll: true });
6719
+ },
6181
6720
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSendOutline16, { size: 16 })
6182
- })
6721
+ })]
6183
6722
  })
6184
6723
  ]
6185
6724
  }), error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
@@ -6335,9 +6874,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6335
6874
  });
6336
6875
  throw new Error(`unknown Team Activity kind: ${activity.kind}`);
6337
6876
  }
6877
+ /** Remove the machine-facing `[attachment] <path>` prompt lines from a body before display. */
6878
+ function stripAttachmentLines(body) {
6879
+ return body.replaceAll(/^\[attachment\] .*$(\n)?/gm, "").replace(/\n+$/, "");
6880
+ }
6338
6881
  //#endregion
6339
6882
  //#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/conversation.module.css.mjs
6340
- 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-subtle);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-text-primary);overflow-wrap:anywhere;margin:0;font-size:20px;font-weight:600;line-height:28px}.omcBaG_headerCopy p{color:var(--dsw-alias-text-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-text-primary);font-size:13px;font-weight:600;line-height:20px}.omcBaG_messageTime{color:var(--dsw-alias-text-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-text-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-text-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-text-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-fill-tertiary);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-text-tertiary);text-transform:uppercase;font-size:12px;line-height:18px}.omcBaG_welcome h1{color:var(--dsw-alias-text-primary);margin:8px 0;font-size:24px;font-weight:600;line-height:32px}.omcBaG_welcome p{color:var(--dsw-alias-text-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{border:1px solid #0000;border-radius:10px;margin:2px -10px;padding:3px 10px;transition:border-color .12s}.omcBaG_messageRun:hover{border-color:var(--dsw-alias-border-default)}.omcBaG_messageRow[data-grouped]:has(.omcBaG_messageBody>button){border-top:1px solid var(--dsw-alias-border-subtle);margin-top:3px;padding-top:7px}.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}@media (width<=600px){.omcBaG_messageRun{margin:2px -6px;padding:3px 6px}}@media (prefers-reduced-motion:reduce){.omcBaG_messageRun{transition:none}}";
6883
+ 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_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}";
6341
6884
  const tagId$4 = "@wowyuarm/dsh-agent-team/conversation.module.css";
6342
6885
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
6343
6886
  const tag = document.createElement("style");
@@ -6347,6 +6890,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6347
6890
  document.head.appendChild(tag);
6348
6891
  }
6349
6892
  var conversation_module_css_default = {
6893
+ "attachmentChip": "omcBaG_attachmentChip",
6894
+ "attachmentChipName": "omcBaG_attachmentChipName",
6895
+ "attachmentChipSize": "omcBaG_attachmentChipSize",
6896
+ "attachmentModal": "omcBaG_attachmentModal",
6897
+ "attachmentStrip": "omcBaG_attachmentStrip",
6898
+ "attachmentThumb": "omcBaG_attachmentThumb",
6899
+ "attachmentZoom": "omcBaG_attachmentZoom",
6350
6900
  "backRow": "omcBaG_backRow",
6351
6901
  "emptyState": "omcBaG_emptyState",
6352
6902
  "emptySurface": "omcBaG_emptySurface",
@@ -6368,6 +6918,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6368
6918
  "messageTime": "omcBaG_messageTime",
6369
6919
  "nameRow": "omcBaG_nameRow",
6370
6920
  "pulse": "omcBaG_pulse",
6921
+ "runDivider": "omcBaG_runDivider",
6371
6922
  "surface": "omcBaG_surface",
6372
6923
  "surfaceHeader": "omcBaG_surfaceHeader",
6373
6924
  "timeline": "omcBaG_timeline",
@@ -6380,9 +6931,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6380
6931
  //#endregion
6381
6932
  //#region src/client/TeamMessage.tsx
6382
6933
  /** One chat message row with identity chrome and sender-appropriate rendering. */
6383
- function TeamMessage({ senderName, memberId, human, body, occurredAt, mentionNames, senderTitle, grouped, children }) {
6934
+ function TeamMessage({ senderName, memberId, human, body, occurredAt, mentionNames, senderTitle, grouped, attachments, loadAttachment, t, children }) {
6384
6935
  const avatarStyle = human ? void 0 : { "--team-avatar-hue": memberHue(memberId) };
6385
- const inline = (human || isPlainTextBody(body)) && mentionNames !== void 0 && mentionNames.length > 0 ? splitMentionNames(body, mentionNames) : void 0;
6936
+ const displayBody = stripAttachmentLines(body) === "" ? body : stripAttachmentLines(body);
6937
+ const inline = (human || isPlainTextBody(displayBody)) && mentionNames !== void 0 && mentionNames.length > 0 ? splitMentionNames(displayBody, mentionNames) : void 0;
6386
6938
  const fallbackNames = inline === void 0 ? mentionNames ?? [] : inline.unmatched;
6387
6939
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
6388
6940
  className: conversation_module_css_default.messageRow,
@@ -6414,10 +6966,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6414
6966
  }, index) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: segment.text }, index))
6415
6967
  }) : human ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6416
6968
  className: conversation_module_css_default.messageText,
6417
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MessageText, { text: body })
6969
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MessageText, { text: displayBody })
6418
6970
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6419
6971
  className: conversation_module_css_default.messageMarkdown,
6420
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, { text: body })
6972
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, { text: displayBody })
6421
6973
  }),
6422
6974
  fallbackNames.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6423
6975
  className: conversation_module_css_default.mentionsRow,
@@ -6426,11 +6978,103 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6426
6978
  children: ["@", name]
6427
6979
  }, name))
6428
6980
  }),
6981
+ attachments !== void 0 && attachments.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamAttachmentStrip, {
6982
+ attachments,
6983
+ ...loadAttachment === void 0 ? {} : { loadAttachment },
6984
+ ...t === void 0 ? {} : { t }
6985
+ }),
6429
6986
  children
6430
6987
  ]
6431
6988
  })]
6432
6989
  });
6433
6990
  }
6991
+ /** One message's attachment strip: image thumbnails with a large view, or name chips when bytes are gone. */
6992
+ function TeamAttachmentStrip({ attachments, loadAttachment, t }) {
6993
+ const [zoomed, setZoomed] = (0, react.useState)();
6994
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6995
+ className: conversation_module_css_default.attachmentStrip,
6996
+ children: [attachments.map((attachment) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamAttachment, {
6997
+ attachment,
6998
+ ...loadAttachment === void 0 ? {} : { loadAttachment },
6999
+ ...t === void 0 ? {} : { t },
7000
+ onZoom: setZoomed
7001
+ }, attachment.attachmentId)), zoomed !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
7002
+ open: true,
7003
+ ...conversation_module_css_default.attachmentModal === void 0 ? {} : { className: conversation_module_css_default.attachmentModal },
7004
+ title: zoomed.name,
7005
+ onClose: () => {
7006
+ setZoomed(void 0);
7007
+ },
7008
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
7009
+ className: conversation_module_css_default.attachmentZoom,
7010
+ src: cachedAttachmentDataUrl(zoomed.attachmentId) ?? void 0,
7011
+ alt: zoomed.name
7012
+ })
7013
+ })]
7014
+ });
7015
+ }
7016
+ function TeamAttachment({ attachment, loadAttachment, t, onZoom }) {
7017
+ const wantsPreview = loadAttachment !== void 0 && attachment.mediaType.startsWith("image/");
7018
+ const [dataUrl, setDataUrl] = (0, react.useState)(wantsPreview ? cachedAttachmentDataUrl(attachment.attachmentId) : null);
7019
+ (0, react.useEffect)(() => {
7020
+ if (!wantsPreview || dataUrl !== void 0) return;
7021
+ let mounted = true;
7022
+ loadAttachmentDataUrl(loadAttachment, attachment).then((url) => {
7023
+ if (mounted) setDataUrl(url);
7024
+ });
7025
+ return () => {
7026
+ mounted = false;
7027
+ };
7028
+ }, [
7029
+ wantsPreview,
7030
+ dataUrl,
7031
+ loadAttachment,
7032
+ attachment
7033
+ ]);
7034
+ const expired = t?.("attachmentExpired") ?? "File no longer cached";
7035
+ if (wantsPreview && dataUrl !== null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7036
+ type: "button",
7037
+ className: conversation_module_css_default.attachmentThumb,
7038
+ "aria-label": t?.("viewImage", { name: attachment.name }) ?? attachment.name,
7039
+ title: attachment.name,
7040
+ onClick: () => {
7041
+ onZoom(attachment);
7042
+ },
7043
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
7044
+ src: dataUrl,
7045
+ alt: attachment.name
7046
+ })
7047
+ });
7048
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7049
+ className: conversation_module_css_default.attachmentChip,
7050
+ title: wantsPreview ? expired : `${attachment.name} · ${formatByteSize(attachment.byteSize)}`,
7051
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7052
+ className: conversation_module_css_default.attachmentChipName,
7053
+ children: attachment.name
7054
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7055
+ className: conversation_module_css_default.attachmentChipSize,
7056
+ children: wantsPreview ? expired : formatByteSize(attachment.byteSize)
7057
+ })]
7058
+ });
7059
+ }
7060
+ //#endregion
7061
+ //#region src/client/TeamRunDivider.tsx
7062
+ /**
7063
+ * Explicit boundary between two same-sender Messages of one run separated by
7064
+ * a real waiting gap: the hairline restores the block boundary that grouping
7065
+ * removed, and the label below it restores the instant that the suppressed
7066
+ * identity chrome would have shown.
7067
+ */
7068
+ function TeamRunDivider({ occurredAt }) {
7069
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7070
+ className: conversation_module_css_default.runDivider,
7071
+ role: "separator",
7072
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("time", {
7073
+ dateTime: occurredAt,
7074
+ children: formatMessageTime(occurredAt)
7075
+ })
7076
+ });
7077
+ }
6434
7078
  //#endregion
6435
7079
  //#region src/client/team-membership.ts
6436
7080
  /**
@@ -6538,8 +7182,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6538
7182
  jumpToLatest
6539
7183
  };
6540
7184
  }
6541
- //#endregion
6542
- //#region src/client/team-separators.ts
7185
+ /**
7186
+ * Whether two adjacent same-sender run items are separated by a real waiting
7187
+ * gap: only such gaps earn an explicit time divider, while rapid bursts stay
7188
+ * merged into one seamless run.
7189
+ */
7190
+ function isRunGap(previousOccurredAt, occurredAt) {
7191
+ if (previousOccurredAt === void 0 || occurredAt === void 0) return false;
7192
+ const previous = Date.parse(previousOccurredAt);
7193
+ const at = Date.parse(occurredAt);
7194
+ return !Number.isNaN(previous) && !Number.isNaN(at) && at - previous >= 5 * 6e4;
7195
+ }
6543
7196
  const pad = (value) => String(value).padStart(2, "0");
6544
7197
  /** Local-calendar day key for one wall-clock instant; shared by bespoke loops. */
6545
7198
  function timelineDayKey(occurredAt) {
@@ -6599,7 +7252,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6599
7252
  }
6600
7253
  //#endregion
6601
7254
  //#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/channel.module.css.mjs
6602
- const css$3 = ".MYaRJa_headerMeta{color:var(--dsw-alias-text-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-subtle);color:var(--dsw-alias-text-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-default);color:var(--dsw-alias-text-primary)}.MYaRJa_taskFooter:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.MYaRJa_taskNumber{color:var(--dsw-alias-text-primary);font-size:12px;font-weight:600;line-height:18px}.MYaRJa_taskStatus,.MYaRJa_taskCount{color:var(--dsw-alias-text-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-text-tertiary)}.MYaRJa_taskDotQuiet[data-variant=closed]{color:var(--dsw-alias-text-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-text-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-text-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-text-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}}";
7255
+ 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}}";
6603
7256
  const tagId$3 = "@wowyuarm/dsh-agent-team/channel.module.css";
6604
7257
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
6605
7258
  const tag = document.createElement("style");
@@ -6626,7 +7279,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6626
7279
  };
6627
7280
  //#endregion
6628
7281
  //#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/thread.module.css.mjs
6629
- 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-subtle);max-width:880px;margin:12px auto 0;padding-top:8px}.-Qiwua_riskSection{border-top:1px solid var(--dsw-alias-border-subtle);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-text-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-text-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;font-weight:500;line-height:18px;overflow:hidden}.-Qiwua_claimDirection{color:var(--dsw-alias-text-primary);overflow-wrap:anywhere;min-width:0;font-size:12px;line-height:18px}.-Qiwua_claimState{color:var(--dsw-alias-text-tertiary);white-space:nowrap;font-size:11px;line-height:18px}.-Qiwua_emptyClaims{color:var(--dsw-alias-text-tertiary);margin:0;padding:5px 6px;font-size:11px;line-height:18px}.-Qiwua_activityRow{color:var(--dsw-alias-text-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-default);border-radius:50%;flex:0 0 5px;width:5px;height:5px}.-Qiwua_historySection{border-bottom:1px solid var(--dsw-alias-border-subtle);max-width:100%;margin:0 auto 12px;padding-bottom:10px}.-Qiwua_historySection h2{color:var(--dsw-alias-text-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-text-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-default);content:\"\";flex:1;height:1px}.-Qiwua_unreadBoundary span{flex:none}.-Qiwua_daySeparator{color:var(--dsw-alias-text-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-subtle);content:\"\";flex:1;height:1px}.-Qiwua_daySeparator span{flex:none}.-Qiwua_newUpdates{background:var(--dsw-specific-input-major,var(--dsw-alias-surface-primary));border:1px solid var(--dsw-alias-border-l2-darkmode-thin);box-shadow:var(--dsw-shadow-lv2);color:var(--dsw-alias-text-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-text-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-text-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)}}";
7282
+ 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)}}";
6630
7283
  const tagId$2 = "@wowyuarm/dsh-agent-team/thread.module.css";
6631
7284
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
6632
7285
  const tag = document.createElement("style");
@@ -6674,17 +7327,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6674
7327
  hasMore: fresh.hasMore || current.cursor < fresh.cursor
6675
7328
  };
6676
7329
  }
6677
- function TeamChannelPage({ workspaceId, channelRef, loadChannels, subscribeChanges, loadMembers, sendMessage, joinChannel, removeChannelMember, selectThread, backToChannels, t }) {
7330
+ function TeamChannelPage({ workspaceId, channelRef, loadChannels, subscribeChanges, loadMembers, drafts, putAttachment, getAttachment, sendMessage, joinChannel, removeChannelMember, selectThread, backToChannels, t }) {
6678
7331
  const [view, setView] = (0, react.useState)();
6679
7332
  const [members, setMembers] = (0, react.useState)([]);
6680
- const [draft, setDraft] = (0, react.useState)("");
6681
7333
  const [error, setError] = (0, react.useState)();
7334
+ const [pendingFiles, setPendingFiles] = (0, react.useState)([]);
6682
7335
  const [statusMessage, setStatusMessage] = (0, react.useState)();
6683
7336
  const [loading, setLoading] = (0, react.useState)(true);
6684
7337
  const [pending, setPending] = (0, react.useState)(false);
6685
7338
  const [loadingOlder, setLoadingOlder] = (0, react.useState)(false);
6686
- const [recipients, setRecipients] = (0, react.useState)(/* @__PURE__ */ new Set());
6687
7339
  const [managingMembers, setManagingMembers] = (0, react.useState)(false);
7340
+ const draftKey = `channel:${channelRef}`;
7341
+ const { draft, recipients } = (0, react.useSyncExternalStore)(drafts.subscribe, () => drafts.getSnapshot(draftKey));
6688
7342
  const manageTriggerRef = (0, react.useRef)(null);
6689
7343
  const memberListRef = (0, react.useRef)(null);
6690
7344
  const mountedRef = (0, react.useRef)(false);
@@ -6744,7 +7398,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6744
7398
  setView(void 0);
6745
7399
  setError(void 0);
6746
7400
  setLoading(true);
6747
- setRecipients(/* @__PURE__ */ new Set());
6748
7401
  setManagingMembers(false);
6749
7402
  refresh();
6750
7403
  const disposers = [subscribeChanges({
@@ -6819,30 +7472,47 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6819
7472
  });
6820
7473
  const pendingSendId = (0, react.useRef)();
6821
7474
  const send = async () => {
7475
+ console.log("DBG send entry pending=%s draft=%j files=%d", pending, draft, pendingFiles.length);
6822
7476
  if (pending || draft.trim() === "") return;
6823
7477
  const recipientIds = [...recipients].sort();
6824
7478
  const requestId = pendingSendId.current ?? crypto.randomUUID();
6825
7479
  pendingSendId.current = requestId;
6826
- const request = {
6827
- requestId,
6828
- workspaceId,
6829
- channelRef,
6830
- body: draft.trim(),
6831
- recipients: recipientIds
6832
- };
6833
7480
  setPending(true);
6834
7481
  setError(void 0);
6835
7482
  setStatusMessage(void 0);
6836
7483
  try {
6837
- const result = await sendMessage(request);
7484
+ const attachmentIds = [];
7485
+ for (const file of pendingFiles) {
7486
+ const uploaded = await putAttachment({
7487
+ requestId: crypto.randomUUID(),
7488
+ workspaceId,
7489
+ name: file.name,
7490
+ mediaType: file.type === "" ? void 0 : file.type,
7491
+ bytesBase64: bytesToBase64(new Uint8Array(await file.arrayBuffer()))
7492
+ });
7493
+ if (!uploaded.ok) {
7494
+ pendingSendId.current = void 0;
7495
+ setError(uploaded.error.message);
7496
+ return;
7497
+ }
7498
+ attachmentIds.push(uploaded.value.attachmentId);
7499
+ }
7500
+ const result = await sendMessage({
7501
+ requestId,
7502
+ workspaceId,
7503
+ channelRef,
7504
+ body: draft.trim(),
7505
+ recipients: recipientIds,
7506
+ ...attachmentIds.length === 0 ? {} : { attachments: attachmentIds }
7507
+ });
6838
7508
  if (!result.ok) {
6839
7509
  pendingSendId.current = void 0;
6840
7510
  setError(result.error.message);
6841
7511
  } else if (result.value.kind === "committed") {
6842
7512
  pendingSendId.current = void 0;
6843
7513
  await refresh();
6844
- setDraft("");
6845
- setRecipients(/* @__PURE__ */ new Set());
7514
+ drafts.clear(draftKey);
7515
+ setPendingFiles([]);
6846
7516
  setStatusMessage(void 0);
6847
7517
  } else if (result.value.kind === "confirmation_required") setStatusMessage(t("mentionConfirmation"));
6848
7518
  else {
@@ -7008,11 +7678,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7008
7678
  children: block.items.map((item, index) => {
7009
7679
  const senderStatus = members.find((member) => member.member.memberId === item.message.sender);
7010
7680
  const human = item.message.sender === view.humanMemberId;
7011
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamMessage, {
7012
- senderName: human ? t("human") : senderStatus?.member.handle ?? item.message.sender,
7681
+ const sender = human ? t("human") : senderStatus?.member.handle ?? item.message.sender;
7682
+ 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, {
7683
+ senderName: sender,
7013
7684
  memberId: item.message.sender,
7014
7685
  human,
7015
7686
  body: item.message.body,
7687
+ attachments: item.message.attachments,
7688
+ loadAttachment: getAttachment,
7689
+ t,
7016
7690
  occurredAt: item.message.occurredAt,
7017
7691
  mentionNames: mentionNamesOf(item.mentions, mentionHandlesMap),
7018
7692
  grouped: index > 0,
@@ -7057,7 +7731,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7057
7731
  })
7058
7732
  ]
7059
7733
  })
7060
- }, item.message.messageRef);
7734
+ })] }, item.message.messageRef);
7061
7735
  })
7062
7736
  }, `run-${block.items[0].message.messageRef}`))
7063
7737
  ]
@@ -7071,18 +7745,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7071
7745
  ...statusMessage === void 0 ? {} : { confirmation: statusMessage },
7072
7746
  ...error === void 0 ? {} : { error },
7073
7747
  onDraftChange: (next) => {
7074
- setDraft(next);
7748
+ drafts.writeDraft(draftKey, next);
7075
7749
  setStatusMessage(void 0);
7076
7750
  },
7077
7751
  onRecipientsChange: (next) => {
7078
- setRecipients(next);
7752
+ drafts.writeRecipients(draftKey, next);
7079
7753
  setStatusMessage(void 0);
7080
7754
  },
7081
7755
  onSubmit: () => {
7082
7756
  send();
7083
7757
  },
7758
+ pendingFiles,
7759
+ onFilesChange: setPendingFiles,
7084
7760
  t
7085
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {})
7761
+ }, draftKey) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {})
7086
7762
  ]
7087
7763
  });
7088
7764
  }
@@ -7111,7 +7787,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7111
7787
  return new Map(facts.map((fact) => [factKey(fact.fact), fact]));
7112
7788
  }
7113
7789
  function TeamThreadPage(props) {
7114
- const { workspaceId, channelRef, taskRef, threadRef, taskNumber, backToWorkspace, loadChannels, readThread, loadThreadHistory, subscribeChanges, loadMembers, reply, changeTask, t } = props;
7790
+ const { workspaceId, channelRef, taskRef, threadRef, taskNumber, backToWorkspace, loadChannels, readThread, loadThreadHistory, subscribeChanges, loadMembers, drafts, getAttachment, reply, changeTask, t } = props;
7115
7791
  const [projection, setProjection] = (0, react.useState)();
7116
7792
  const [channelView, setChannelView] = (0, react.useState)();
7117
7793
  const [members, setMembers] = (0, react.useState)([]);
@@ -7122,8 +7798,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7122
7798
  const [historyHasMore, setHistoryHasMore] = (0, react.useState)(false);
7123
7799
  const [remainingUnreadCount, setRemainingUnreadCount] = (0, react.useState)(0);
7124
7800
  const [newFactsCount, setNewFactsCount] = (0, react.useState)(0);
7125
- const [draft, setDraft] = (0, react.useState)("");
7126
- const [recipients, setRecipients] = (0, react.useState)(/* @__PURE__ */ new Set());
7801
+ const draftKey = `thread:${threadRef}`;
7802
+ const { draft, recipients } = (0, react.useSyncExternalStore)(drafts.subscribe, () => drafts.getSnapshot(draftKey));
7127
7803
  const [claimsOpen, setClaimsOpen] = (0, react.useState)(false);
7128
7804
  const [replyRequestId, setReplyRequestId] = (0, react.useState)();
7129
7805
  const [confirmation, setConfirmation] = (0, react.useState)();
@@ -7378,6 +8054,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7378
8054
  memberId: fact.message.sender,
7379
8055
  human: fact.message.sender === channelView?.humanMemberId,
7380
8056
  body: fact.message.body,
8057
+ attachments: fact.message.attachments,
8058
+ loadAttachment: getAttachment,
8059
+ t,
7381
8060
  occurredAt: fact.message.occurredAt,
7382
8061
  mentionNames: mentionNamesOf(fact.mentions, mentionHandlesMap),
7383
8062
  grouped,
@@ -7407,7 +8086,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7407
8086
  const flushRun = () => {
7408
8087
  if (run.length > 0) nodes.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7409
8088
  className: conversation_module_css_default.messageRun,
7410
- children: run.map((entry, entryIndex) => renderFact(entry, entryIndex > 0))
8089
+ children: run.map((entry, entryIndex) => {
8090
+ const previous = entryIndex > 0 ? run[entryIndex - 1] : void 0;
8091
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [entry.kind === "message" && isRunGap(previous?.kind === "message" ? previous.message.occurredAt : void 0, entry.message.occurredAt) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamRunDivider, { occurredAt: entry.message.occurredAt }), renderFact(entry, entryIndex > 0)] }, factKey(entry));
8092
+ })
7411
8093
  }, `run-${factKey(run[0])}`));
7412
8094
  run = [];
7413
8095
  };
@@ -7538,8 +8220,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7538
8220
  task: committed.task,
7539
8221
  thread: committed.thread
7540
8222
  });
7541
- setDraft("");
7542
- setRecipients(/* @__PURE__ */ new Set());
8223
+ drafts.clear(draftKey);
7543
8224
  setReplyRequestId(void 0);
7544
8225
  setConfirmation(void 0);
7545
8226
  setStatusMessage(void 0);
@@ -7807,13 +8488,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7807
8488
  ...statusMessage === void 0 ? {} : { confirmation: statusMessage },
7808
8489
  ...error === void 0 ? {} : { error },
7809
8490
  onDraftChange: (next) => {
7810
- setDraft(next);
8491
+ drafts.writeDraft(draftKey, next);
7811
8492
  setConfirmation(void 0);
7812
8493
  setReplyRequestId(void 0);
7813
8494
  setStatusMessage(void 0);
7814
8495
  },
7815
8496
  onRecipientsChange: (next) => {
7816
- setRecipients(next);
8497
+ drafts.writeRecipients(draftKey, next);
7817
8498
  setConfirmation(void 0);
7818
8499
  setReplyRequestId(void 0);
7819
8500
  setStatusMessage(void 0);
@@ -7822,13 +8503,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7822
8503
  sendReply();
7823
8504
  },
7824
8505
  t
7825
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {})
8506
+ }, draftKey) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {})
7826
8507
  ]
7827
8508
  });
7828
8509
  }
7829
8510
  //#endregion
7830
8511
  //#region src/client/TeamConversation.tsx
7831
- function TeamConversation({ t, useWorkspaces, navigation, loadChannels, readThread, loadThreadHistory, subscribeChanges, loadMembers, sendMessage, joinChannel, removeChannelMember, reply, changeTask, selectThread, backToWorkspace, backToChannels }) {
8512
+ function TeamConversation({ t, useWorkspaces, navigation, drafts, putAttachment, getAttachment, loadChannels, readThread, loadThreadHistory, subscribeChanges, loadMembers, sendMessage, joinChannel, removeChannelMember, reply, changeTask, selectThread, backToWorkspace, backToChannels }) {
7832
8513
  const navigationState = (0, react.useSyncExternalStore)(navigation.subscribe, navigation.getSnapshot, navigation.getSnapshot);
7833
8514
  const current = useWorkspaces((state) => state.items).find((workspace) => workspace.workspaceId === navigationState.workspaceId);
7834
8515
  if (current !== void 0 && navigationState.taskRef !== void 0 && navigationState.threadRef !== void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamThreadPage, {
@@ -7838,6 +8519,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7838
8519
  backToWorkspace,
7839
8520
  ...navigationState.channelRef === void 0 ? {} : { channelRef: navigationState.channelRef },
7840
8521
  ...navigationState.taskNumber === void 0 ? {} : { taskNumber: navigationState.taskNumber },
8522
+ drafts,
8523
+ getAttachment,
7841
8524
  readThread,
7842
8525
  loadChannels,
7843
8526
  loadThreadHistory,
@@ -7850,6 +8533,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7850
8533
  if (current !== void 0 && navigationState.channelRef !== void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamChannelPage, {
7851
8534
  workspaceId: current.workspaceId,
7852
8535
  channelRef: navigationState.channelRef,
8536
+ drafts,
8537
+ putAttachment,
8538
+ getAttachment,
7853
8539
  loadChannels,
7854
8540
  subscribeChanges,
7855
8541
  loadMembers,
@@ -7887,7 +8573,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7887
8573
  }
7888
8574
  //#endregion
7889
8575
  //#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/sidebar.module.css.mjs
7890
- 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-default)}.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_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_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-text-disabled);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-text-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-text-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_rowError{color:var(--dsw-alias-state-error-primary);grid-column:1/-1;margin:2px 0;font-size:11px;line-height:16px}";
8576
+ 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_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}";
7891
8577
  const tagId$1 = "@wowyuarm/dsh-agent-team/sidebar.module.css";
7892
8578
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
7893
8579
  const tag = document.createElement("style");
@@ -7916,6 +8602,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7916
8602
  "editMemberRowChannels": "d0xfxa_editMemberRowChannels",
7917
8603
  "emptyState": "d0xfxa_emptyState",
7918
8604
  "iconButton": "d0xfxa_iconButton",
8605
+ "menuHint": "d0xfxa_menuHint",
7919
8606
  "panel": "d0xfxa_panel",
7920
8607
  "railButton": "d0xfxa_railButton",
7921
8608
  "railWorkspace": "d0xfxa_railWorkspace",
@@ -8062,7 +8749,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8062
8749
  }
8063
8750
  //#endregion
8064
8751
  //#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/create.module.css.mjs
8065
- 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{width:100%}._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-text-disabled);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}}";
8752
+ 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}}";
8066
8753
  const tagId = "@wowyuarm/dsh-agent-team/create.module.css";
8067
8754
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
8068
8755
  const tag = document.createElement("style");
@@ -8081,13 +8768,77 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8081
8768
  "input": "_1henIG_input",
8082
8769
  "memberOption": "_1henIG_memberOption",
8083
8770
  "memberPicker": "_1henIG_memberPicker",
8771
+ "menuCap": "_1henIG_menuCap",
8084
8772
  "selectTrigger": "_1henIG_selectTrigger",
8085
8773
  "selectValue": "_1henIG_selectValue",
8086
8774
  "unavailableDot": "_1henIG_unavailableDot"
8087
8775
  };
8088
8776
  //#endregion
8777
+ //#region src/client/multi-menu-field.tsx
8778
+ /**
8779
+ * Render the labeled multi-select Menu field.
8780
+ * @param props.label - field caption; doubles as the trigger's accessible name.
8781
+ * @param props.options - selectable entries in display order.
8782
+ * @param props.selected - currently checked ids.
8783
+ * @param props.onToggle - invoked with an id when its row is clicked.
8784
+ * @param props.disabled - disables the trigger while a mutation is in flight.
8785
+ * @param props.emptyText - shown instead of the picker when there is nothing to pick.
8786
+ * @param props.triggerEmptyLabel - trigger caption when nothing is selected.
8787
+ * @param props.formatCount - builds the trigger caption for N selections.
8788
+ */
8789
+ function MultiMenuField({ label, options, selected, onToggle, disabled = false, emptyText, triggerEmptyLabel, formatCount }) {
8790
+ const [open, setOpen] = (0, react.useState)(false);
8791
+ const items = options.map((option) => ({
8792
+ id: option.id,
8793
+ label: option.hint === void 0 ? option.label : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [option.label, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
8794
+ className: sidebar_module_css_default.menuHint,
8795
+ children: ` ${option.hint}`
8796
+ })] }),
8797
+ ...option.disabled === true ? { disabled: true } : {},
8798
+ ...option.icon === void 0 ? {} : { icon: option.icon }
8799
+ }));
8800
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8801
+ className: create_module_css_default.field,
8802
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label }), options.length === 0 && emptyText !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
8803
+ className: sidebar_module_css_default.editHint,
8804
+ children: emptyText
8805
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
8806
+ open,
8807
+ portal: true,
8808
+ className: create_module_css_default.menuCap,
8809
+ items,
8810
+ selectedIds: selected,
8811
+ onSelect: (id) => {
8812
+ onToggle(id);
8813
+ },
8814
+ onClose: () => {
8815
+ setOpen(false);
8816
+ },
8817
+ anchor: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
8818
+ type: "button",
8819
+ className: create_module_css_default.selectTrigger,
8820
+ "aria-label": label,
8821
+ "aria-haspopup": "listbox",
8822
+ "aria-expanded": open,
8823
+ disabled,
8824
+ onClick: () => {
8825
+ setOpen((value) => !value);
8826
+ },
8827
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8828
+ className: create_module_css_default.selectValue,
8829
+ children: selected.length === 0 ? triggerEmptyLabel : formatCount(selected.length)
8830
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8831
+ className: `${create_module_css_default.chevron} ${open ? create_module_css_default.chevronOpen : ""}`,
8832
+ "aria-hidden": true,
8833
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, {})
8834
+ })]
8835
+ })
8836
+ })]
8837
+ });
8838
+ }
8839
+ //#endregion
8089
8840
  //#region src/client/TeamAgentsPanel.tsx
8090
- function TeamAgentsPanel({ workspaceId, loadMembers, subscribeChanges, loadChannels, addMember, updateMember, joinChannel, removeChannelMember, loadModels, openMemberSession, onCreatingChange, t }) {
8841
+ function TeamAgentsPanel({ workspaceId, loadMembers, subscribeChanges, loadChannels, addMember, updateMember, recoverMember, restartMember, joinChannel, removeChannelMember, loadModels, memberSessionId, openMemberSession, onCreatingChange, t }) {
8091
8842
  const [members, setMembers] = (0, react.useState)([]);
8092
8843
  const [channels, setChannels] = (0, react.useState)([]);
8093
8844
  const [channelRefs, setChannelRefs] = (0, react.useState)([]);
@@ -8096,6 +8847,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8096
8847
  const [formOpen, setFormOpen] = (0, react.useState)(false);
8097
8848
  const [handle, setHandle] = (0, react.useState)("");
8098
8849
  const [description, setDescription] = (0, react.useState)("");
8850
+ const [model, setModel] = (0, react.useState)(void 0);
8099
8851
  const [creating, setCreating] = (0, react.useState)(false);
8100
8852
  const [retryRequest, setRetryRequest] = (0, react.useState)();
8101
8853
  const triggerRef = (0, react.useRef)(null);
@@ -8159,6 +8911,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8159
8911
  });
8160
8912
  setHandle("");
8161
8913
  setDescription("");
8914
+ setModel(void 0);
8162
8915
  setChannelRefs([]);
8163
8916
  setFormOpen(false);
8164
8917
  if (result.value.status.presence === "unavailable") setError(result.value.status.diagnostic ?? t("statusUnavailable"));
@@ -8181,15 +8934,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8181
8934
  event.preventDefault();
8182
8935
  const normalizedHandle = handle.trim();
8183
8936
  const normalizedDescription = description.trim();
8184
- if (normalizedHandle.length === 0 || normalizedDescription.length === 0 || creating) return;
8185
- if (channelRefs.length === 0) return;
8186
- provision(retryRequest !== void 0 && retryRequest.workspaceId === workspaceId && retryRequest.handle === normalizedHandle && retryRequest.description === normalizedDescription && retryRequest.channelRefs.length === channelRefs.length && retryRequest.channelRefs.every((ref) => channelRefs.includes(ref)) ? retryRequest : {
8937
+ if (normalizedHandle.length === 0 || creating) return;
8938
+ 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 : {
8187
8939
  requestId: crypto.randomUUID(),
8188
8940
  workspaceId,
8189
8941
  handle: normalizedHandle,
8190
8942
  description: normalizedDescription,
8191
8943
  presetId: "team-member",
8192
- channelRefs
8944
+ channelRefs,
8945
+ ...model === void 0 ? {} : { model }
8193
8946
  });
8194
8947
  };
8195
8948
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -8210,7 +8963,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8210
8963
  type: "submit",
8211
8964
  form: "team-agent-create-form",
8212
8965
  variant: "primary",
8213
- disabled: creating || handle.trim().length === 0 || description.trim().length === 0 || channelRefs.length === 0,
8966
+ disabled: creating || handle.trim().length === 0,
8214
8967
  children: creating ? t("creatingAgent") : t("createAgent")
8215
8968
  })] }),
8216
8969
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
@@ -8233,9 +8986,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8233
8986
  }),
8234
8987
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
8235
8988
  className: create_module_css_default.field,
8236
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("agentDescription") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
8989
+ 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, {
8237
8990
  className: create_module_css_default.input,
8238
8991
  value: description,
8992
+ placeholder: t("agentDescriptionPlaceholder"),
8239
8993
  onChange: (event) => {
8240
8994
  setDescription(event.target.value);
8241
8995
  setRetryRequest(void 0);
@@ -8243,21 +8997,31 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8243
8997
  disabled: creating
8244
8998
  })]
8245
8999
  }),
8246
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
8247
- className: create_module_css_default.field,
8248
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", { children: t("initialChannels") }), channels.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("noChannelsForAgent") }) : channels.map((channel) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [
8249
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
8250
- type: "checkbox",
8251
- checked: channelRefs.includes(channel.channelRef),
8252
- disabled: creating,
8253
- onChange: (event) => {
8254
- setChannelRefs((current) => event.target.checked ? [...current, channel.channelRef] : current.filter((ref) => ref !== channel.channelRef));
8255
- setRetryRequest(void 0);
8256
- }
8257
- }),
8258
- " ",
8259
- channel.name
8260
- ] }, channel.channelRef))]
9000
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelPickerField, {
9001
+ model,
9002
+ onModelChange: (choice) => {
9003
+ setModel(choice);
9004
+ setRetryRequest(void 0);
9005
+ },
9006
+ loadModels,
9007
+ disabled: creating,
9008
+ t
9009
+ }),
9010
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MultiMenuField, {
9011
+ label: `${t("initialChannels")}${t("optionalSuffix")}`,
9012
+ disabled: creating,
9013
+ options: channels.map((channel) => ({
9014
+ id: channel.channelRef,
9015
+ label: channel.name
9016
+ })),
9017
+ selected: channelRefs,
9018
+ onToggle: (ref) => {
9019
+ setChannelRefs((current) => current.includes(ref) ? current.filter((item) => item !== ref) : [...current, ref]);
9020
+ setRetryRequest(void 0);
9021
+ },
9022
+ emptyText: t("noChannelsForAgent"),
9023
+ triggerEmptyLabel: t("channelsPickerEmpty"),
9024
+ formatCount: (count) => t("channelsPickerCount", { count })
8261
9025
  }),
8262
9026
  formOpen && error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8263
9027
  className: create_module_css_default.error,
@@ -8297,9 +9061,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8297
9061
  className: sidebar_module_css_default.agentList,
8298
9062
  children: members.map((status) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AgentRow, {
8299
9063
  status,
9064
+ ...memberSessionId === void 0 ? {} : { current: status.member.sessionId === memberSessionId },
8300
9065
  channels,
8301
9066
  loadChannels,
8302
9067
  updateMember,
9068
+ recoverMember,
9069
+ restartMember,
8303
9070
  joinChannel,
8304
9071
  removeChannelMember,
8305
9072
  loadModels,
@@ -8333,9 +9100,25 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8333
9100
  * conversation page, the avatar carries identity plus the presence badge, and
8334
9101
  * the row menu opens the editor.
8335
9102
  */
8336
- function AgentRow({ status, channels, loadChannels, updateMember, joinChannel, removeChannelMember, loadModels, openMemberSession, onUpdated, t }) {
9103
+ function AgentRow({ status, current, channels, loadChannels, updateMember, recoverMember, restartMember, joinChannel, removeChannelMember, loadModels, openMemberSession, onUpdated, t }) {
8337
9104
  const [menuOpen, setMenuOpen] = (0, react.useState)(false);
8338
9105
  const [editing, setEditing] = (0, react.useState)(false);
9106
+ const resume = async () => {
9107
+ await recoverMember({
9108
+ requestId: crypto.randomUUID(),
9109
+ workspaceId: status.member.workspaceId,
9110
+ memberId: status.member.memberId
9111
+ });
9112
+ await onUpdated();
9113
+ };
9114
+ const restart = async () => {
9115
+ await restartMember({
9116
+ requestId: crypto.randomUUID(),
9117
+ workspaceId: status.member.workspaceId,
9118
+ memberId: status.member.memberId
9119
+ });
9120
+ await onUpdated();
9121
+ };
8339
9122
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8340
9123
  className: sidebar_module_css_default.agentRow,
8341
9124
  "data-menu-open": menuOpen || void 0,
@@ -8343,6 +9126,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8343
9126
  type: "button",
8344
9127
  className: sidebar_module_css_default.agentSelect,
8345
9128
  "aria-label": t("openAgentSession", { name: status.member.handle }),
9129
+ "aria-current": current ? "page" : void 0,
8346
9130
  onClick: () => {
8347
9131
  openMemberSession(status.member.sessionId);
8348
9132
  },
@@ -8357,13 +9141,27 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8357
9141
  className: sidebar_module_css_default.rowMenu,
8358
9142
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamRowMenu, {
8359
9143
  label: t("actionsAgent", { name: status.member.handle }),
8360
- items: [{
8361
- id: "edit",
8362
- label: t("editAgent"),
8363
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, {})
8364
- }],
8365
- onSelect: () => {
8366
- setEditing(true);
9144
+ items: [
9145
+ {
9146
+ id: "edit",
9147
+ label: t("editAgent"),
9148
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, {})
9149
+ },
9150
+ ...status.presence === "error" ? [{
9151
+ id: "resume",
9152
+ label: t("resumeAgent"),
9153
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlayOutline16, {})
9154
+ }] : [],
9155
+ {
9156
+ id: "restart",
9157
+ label: t("restartAgent"),
9158
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutline14, {})
9159
+ }
9160
+ ],
9161
+ onSelect: (id) => {
9162
+ if (id === "resume") resume();
9163
+ else if (id === "restart") restart();
9164
+ else setEditing(true);
8367
9165
  },
8368
9166
  onOpenChange: setMenuOpen
8369
9167
  })
@@ -8388,23 +9186,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8388
9186
  return `${provider}\u0000${model}`;
8389
9187
  }
8390
9188
  /**
8391
- * Agent editor: handle, description, and per-Member model selection commit
8392
- * through one durable update; Channel membership below keeps its own
8393
- * immediate add/remove flow.
9189
+ * Shared provider/model dropdown for the create and edit forms. The option
9190
+ * list rides the shared Menu primitive (one leading "follow Host default"
9191
+ * row, then non-selectable provider headings) with a capped, internally
9192
+ * scrolling card so growing model catalogs cannot stretch the dialog.
8394
9193
  */
8395
- function AgentEditorDialog({ status, channels, loadChannels, updateMember, joinChannel, removeChannelMember, loadModels, onCommitted, onClose, t }) {
8396
- const memberId = status.member.memberId;
8397
- const [handle, setHandle] = (0, react.useState)(status.member.handle);
8398
- const [description, setDescription] = (0, react.useState)(status.member.description);
8399
- const [model, setModel] = (0, react.useState)(status.member.model === void 0 ? void 0 : [status.member.model.provider, status.member.model.model]);
9194
+ function ModelPickerField({ model, onModelChange, loadModels, disabled, t }) {
8400
9195
  const [groups, setGroups] = (0, react.useState)();
8401
9196
  const [modelsError, setModelsError] = (0, react.useState)();
8402
- const [modelOpen, setModelOpen] = (0, react.useState)(false);
8403
- const [saving, setSaving] = (0, react.useState)(false);
8404
- const [error, setError] = (0, react.useState)();
8405
- const pendingRequest = (0, react.useRef)();
8406
- const [memberships, setMemberships] = (0, react.useState)();
8407
- const [loadError, setLoadError] = (0, react.useState)();
9197
+ const [open, setModelOpen] = (0, react.useState)(false);
9198
+ const [effortOpen, setEffortOpen] = (0, react.useState)(false);
8408
9199
  (0, react.useEffect)(() => {
8409
9200
  let mounted = true;
8410
9201
  loadModels().then((result) => {
@@ -8418,6 +9209,150 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8418
9209
  mounted = false;
8419
9210
  };
8420
9211
  }, [loadModels]);
9212
+ const items = [{
9213
+ id: "",
9214
+ label: t("modelFollowDefault")
9215
+ }];
9216
+ const byKey = /* @__PURE__ */ new Map();
9217
+ for (const group of groups ?? []) {
9218
+ items.push({
9219
+ type: "label",
9220
+ id: `model-group:${group.id}`,
9221
+ text: group.name
9222
+ });
9223
+ for (const entry of group.models) {
9224
+ const key = modelKey(group.id, entry.id);
9225
+ byKey.set(key, {
9226
+ provider: group.id,
9227
+ id: entry.id,
9228
+ name: entry.name,
9229
+ efforts: entry.reasoning?.efforts ?? []
9230
+ });
9231
+ items.push({
9232
+ id: key,
9233
+ label: entry.name
9234
+ });
9235
+ }
9236
+ }
9237
+ const selectedModelKey = model === void 0 ? "" : modelKey(model.provider, model.model);
9238
+ const triggerLabel = model === void 0 ? t("modelFollowDefault") : byKey.get(selectedModelKey)?.name ?? `${model.provider} / ${model.model}`;
9239
+ const efforts = model === void 0 ? [] : byKey.get(selectedModelKey)?.efforts ?? [];
9240
+ const effortItems = [{
9241
+ id: "",
9242
+ label: t("effortFollowDefault")
9243
+ }, ...efforts.map((effort) => ({
9244
+ id: effort.id,
9245
+ label: effort.name
9246
+ }))];
9247
+ const selectedEffort = model?.reasoningEffort ?? "";
9248
+ const effortTriggerLabel = model === void 0 || selectedEffort === "" ? t("effortFollowDefault") : efforts.find((effort) => effort.id === selectedEffort)?.name ?? selectedEffort;
9249
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9250
+ className: create_module_css_default.field,
9251
+ children: [
9252
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("memberModel") }),
9253
+ groups === void 0 && modelsError === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
9254
+ className: sidebar_module_css_default.editHint,
9255
+ children: t("modelsLoading")
9256
+ }),
9257
+ modelsError !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
9258
+ className: sidebar_module_css_default.editHint,
9259
+ children: t("modelsLoadFailed", { message: modelsError })
9260
+ }),
9261
+ groups !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
9262
+ open,
9263
+ portal: true,
9264
+ className: create_module_css_default.menuCap,
9265
+ items,
9266
+ selectedId: selectedModelKey,
9267
+ onSelect: (key) => {
9268
+ setModelOpen(false);
9269
+ const choice = byKey.get(key);
9270
+ onModelChange(choice === void 0 ? void 0 : {
9271
+ provider: choice.provider,
9272
+ model: choice.id
9273
+ });
9274
+ },
9275
+ onClose: () => {
9276
+ setModelOpen(false);
9277
+ },
9278
+ anchor: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
9279
+ type: "button",
9280
+ className: create_module_css_default.selectTrigger,
9281
+ "aria-label": t("memberModel"),
9282
+ "aria-haspopup": "listbox",
9283
+ "aria-expanded": open,
9284
+ disabled,
9285
+ onClick: () => {
9286
+ setModelOpen((value) => !value);
9287
+ },
9288
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9289
+ className: create_module_css_default.selectValue,
9290
+ children: triggerLabel
9291
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9292
+ className: `${create_module_css_default.chevron} ${open ? create_module_css_default.chevronOpen : ""}`,
9293
+ "aria-hidden": true,
9294
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, {})
9295
+ })]
9296
+ })
9297
+ }),
9298
+ model !== void 0 && efforts.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
9299
+ open: effortOpen,
9300
+ portal: true,
9301
+ className: create_module_css_default.menuCap,
9302
+ items: effortItems,
9303
+ selectedId: selectedEffort,
9304
+ onSelect: (key) => {
9305
+ setEffortOpen(false);
9306
+ onModelChange(key === "" ? {
9307
+ provider: model.provider,
9308
+ model: model.model
9309
+ } : {
9310
+ provider: model.provider,
9311
+ model: model.model,
9312
+ reasoningEffort: key
9313
+ });
9314
+ },
9315
+ onClose: () => {
9316
+ setEffortOpen(false);
9317
+ },
9318
+ anchor: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
9319
+ type: "button",
9320
+ className: create_module_css_default.selectTrigger,
9321
+ "aria-label": t("reasoningEffort"),
9322
+ "aria-haspopup": "listbox",
9323
+ "aria-expanded": effortOpen,
9324
+ disabled,
9325
+ onClick: () => {
9326
+ setEffortOpen((value) => !value);
9327
+ },
9328
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9329
+ className: create_module_css_default.selectValue,
9330
+ children: `${t("reasoningEffort")} · ${effortTriggerLabel}`
9331
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9332
+ className: `${create_module_css_default.chevron} ${effortOpen ? create_module_css_default.chevronOpen : ""}`,
9333
+ "aria-hidden": true,
9334
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, {})
9335
+ })]
9336
+ })
9337
+ })
9338
+ ]
9339
+ });
9340
+ }
9341
+ /**
9342
+ * Agent editor: handle, description, and per-Member model selection commit
9343
+ * through one durable update; Channel membership below keeps its own
9344
+ * immediate add/remove flow.
9345
+ */
9346
+ function AgentEditorDialog({ status, channels, loadChannels, updateMember, joinChannel, removeChannelMember, loadModels, onCommitted, onClose, t }) {
9347
+ const memberId = status.member.memberId;
9348
+ const [handle, setHandle] = (0, react.useState)(status.member.handle);
9349
+ const [description, setDescription] = (0, react.useState)(status.member.description);
9350
+ const [model, setModel] = (0, react.useState)(status.member.model);
9351
+ const [saving, setSaving] = (0, react.useState)(false);
9352
+ const [error, setError] = (0, react.useState)();
9353
+ const pendingRequest = (0, react.useRef)();
9354
+ const [memberships, setMemberships] = (0, react.useState)();
9355
+ const [loadError, setLoadError] = (0, react.useState)();
8421
9356
  (0, react.useEffect)(() => {
8422
9357
  let mounted = true;
8423
9358
  loadChannels({
@@ -8449,54 +9384,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8449
9384
  });
8450
9385
  });
8451
9386
  const joinedChannels = new Set((memberships ?? []).filter((item) => item.memberId === memberId).map((item) => item.channelRef));
8452
- const modelChoices = (() => {
8453
- const items = [{
8454
- id: "",
8455
- label: t("modelFollowDefault")
8456
- }];
8457
- const byKey = /* @__PURE__ */ new Map();
8458
- for (const group of groups ?? []) {
8459
- items.push({
8460
- type: "label",
8461
- id: `model-group:${group.id}`,
8462
- text: group.name
8463
- });
8464
- for (const entry of group.models) {
8465
- const key = modelKey(group.id, entry.id);
8466
- byKey.set(key, {
8467
- provider: group.id,
8468
- id: entry.id,
8469
- name: entry.name
8470
- });
8471
- items.push({
8472
- id: key,
8473
- label: entry.name
8474
- });
8475
- }
8476
- }
8477
- return {
8478
- items,
8479
- byKey
8480
- };
8481
- })();
8482
- const selectedModelKey = model === void 0 ? "" : modelKey(model[0], model[1]);
8483
- const modelTriggerLabel = model === void 0 ? t("modelFollowDefault") : modelChoices.byKey.get(selectedModelKey)?.name ?? `${model[0]} / ${model[1]}`;
8484
- const dirty = handle.trim() !== status.member.handle || description.trim() !== status.member.description || !sameModel(model, status.member.model === void 0 ? void 0 : [status.member.model.provider, status.member.model.model]);
9387
+ const dirty = handle.trim() !== status.member.handle || description.trim() !== status.member.description || !sameModel(model, status.member.model);
8485
9388
  const submit = async (event) => {
8486
9389
  event.preventDefault();
8487
9390
  const normalizedHandle = handle.trim();
8488
9391
  const normalizedDescription = description.trim();
8489
- if (saving || !dirty || normalizedHandle.length === 0 || normalizedDescription.length === 0) return;
9392
+ if (saving || !dirty || normalizedHandle.length === 0) return;
8490
9393
  const payload = {
8491
9394
  memberId,
8492
9395
  handle: normalizedHandle,
8493
9396
  description: normalizedDescription,
8494
- ...model === void 0 ? {} : { model: {
8495
- provider: model[0],
8496
- model: model[1]
8497
- } }
9397
+ ...model === void 0 ? {} : { model }
8498
9398
  };
8499
- 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 === void 0 ? void 0 : [pendingRequest.current.model.provider, pendingRequest.current.model.model], model) ? pendingRequest.current : {
9399
+ 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 : {
8500
9400
  requestId: crypto.randomUUID(),
8501
9401
  ...payload
8502
9402
  };
@@ -8532,7 +9432,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8532
9432
  type: "submit",
8533
9433
  form: "team-agent-edit-form",
8534
9434
  variant: "primary",
8535
- disabled: saving || !dirty || handle.trim().length === 0 || description.trim().length === 0,
9435
+ disabled: saving || !dirty || handle.trim().length === 0,
8536
9436
  children: saving ? t("editSaving") : t("editSave")
8537
9437
  })] }),
8538
9438
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
@@ -8557,9 +9457,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8557
9457
  }),
8558
9458
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
8559
9459
  className: create_module_css_default.field,
8560
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("agentDescription") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
9460
+ 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, {
8561
9461
  className: create_module_css_default.input,
8562
9462
  value: description,
9463
+ placeholder: t("agentDescriptionPlaceholder"),
8563
9464
  onChange: (event) => {
8564
9465
  setDescription(event.target.value);
8565
9466
  pendingRequest.current = void 0;
@@ -8567,53 +9468,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8567
9468
  disabled: saving
8568
9469
  })]
8569
9470
  }),
8570
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8571
- className: create_module_css_default.field,
8572
- children: [
8573
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("memberModel") }),
8574
- groups === void 0 && modelsError === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
8575
- className: sidebar_module_css_default.editHint,
8576
- children: t("modelsLoading")
8577
- }),
8578
- modelsError !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
8579
- className: sidebar_module_css_default.editHint,
8580
- children: t("modelsLoadFailed", { message: modelsError })
8581
- }),
8582
- groups !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
8583
- open: modelOpen,
8584
- portal: true,
8585
- items: modelChoices.items,
8586
- selectedId: selectedModelKey,
8587
- onSelect: (key) => {
8588
- setModelOpen(false);
8589
- pendingRequest.current = void 0;
8590
- const choice = modelChoices.byKey.get(key);
8591
- setModel(choice === void 0 ? void 0 : [choice.provider, choice.id]);
8592
- },
8593
- onClose: () => {
8594
- setModelOpen(false);
8595
- },
8596
- anchor: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
8597
- type: "button",
8598
- className: create_module_css_default.selectTrigger,
8599
- "aria-label": t("memberModel"),
8600
- "aria-haspopup": "listbox",
8601
- "aria-expanded": modelOpen,
8602
- disabled: saving,
8603
- onClick: () => {
8604
- setModelOpen((value) => !value);
8605
- },
8606
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8607
- className: create_module_css_default.selectValue,
8608
- children: modelTriggerLabel
8609
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8610
- className: `${create_module_css_default.chevron} ${modelOpen ? create_module_css_default.chevronOpen : ""}`,
8611
- "aria-hidden": true,
8612
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, {})
8613
- })]
8614
- })
8615
- })
8616
- ]
9471
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelPickerField, {
9472
+ model,
9473
+ onModelChange: (choice) => {
9474
+ pendingRequest.current = void 0;
9475
+ setModel(choice);
9476
+ },
9477
+ loadModels,
9478
+ disabled: saving,
9479
+ t
8617
9480
  }),
8618
9481
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
8619
9482
  className: create_module_css_default.memberPicker,
@@ -8674,7 +9537,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8674
9537
  function sameModel(left, right) {
8675
9538
  if (left === void 0 && right === void 0) return true;
8676
9539
  if (left === void 0 || right === void 0) return false;
8677
- return left[0] === right[0] && left[1] === right[1];
9540
+ return left.provider === right.provider && left.model === right.model && left.reasoningEffort === right.reasoningEffort;
8678
9541
  }
8679
9542
  //#endregion
8680
9543
  //#region src/client/TeamChannelsPanel.tsx
@@ -8754,7 +9617,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8754
9617
  };
8755
9618
  const submit = async (event) => {
8756
9619
  event.preventDefault();
8757
- if (mutating || name.trim() === "" || description.trim() === "") return;
9620
+ if (mutating || name.trim() === "") return;
8758
9621
  const payload = {
8759
9622
  workspaceId,
8760
9623
  name: name.trim(),
@@ -8805,7 +9668,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8805
9668
  type: "submit",
8806
9669
  form: "team-channel-create-form",
8807
9670
  variant: "primary",
8808
- disabled: mutating || name.trim() === "" || description.trim() === "",
9671
+ disabled: mutating || name.trim() === "",
8809
9672
  children: mutating ? t("creatingChannel") : t("createChannel")
8810
9673
  })] }),
8811
9674
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
@@ -8830,9 +9693,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8830
9693
  }),
8831
9694
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
8832
9695
  className: create_module_css_default.field,
8833
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("channelDescription") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
9696
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [t("channelDescription"), t("optionalSuffix")] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
8834
9697
  className: create_module_css_default.input,
8835
9698
  value: description,
9699
+ placeholder: t("agentDescriptionPlaceholder"),
8836
9700
  disabled: mutating,
8837
9701
  onChange: (event) => {
8838
9702
  setDescription(event.target.value);
@@ -8840,64 +9704,38 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8840
9704
  }
8841
9705
  })]
8842
9706
  }),
8843
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
8844
- className: create_module_css_default.memberPicker,
9707
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MultiMenuField, {
9708
+ label: t("initialMembers"),
8845
9709
  disabled: mutating,
8846
- children: [
8847
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", { children: t("initialMembers") }),
8848
- creatingAgents.map((request) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
8849
- className: create_module_css_default.memberOption,
8850
- children: [
8851
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
8852
- type: "checkbox",
8853
- disabled: true,
8854
- "aria-describedby": `creating-member-reason-${request.requestId}`
8855
- }),
8856
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8857
- className: create_module_css_default.unavailableDot,
8858
- "aria-hidden": "true"
8859
- }),
8860
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: request.handle }),
8861
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
8862
- id: `creating-member-reason-${request.requestId}`,
8863
- children: t("memberCreatingReason")
8864
- })
8865
- ]
8866
- }, request.requestId)),
8867
- members.map((status) => {
8868
- const disabled = status.presence === "unavailable";
8869
- const reasonId = `initial-member-reason-${status.member.memberId}`;
8870
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
8871
- className: create_module_css_default.memberOption,
8872
- children: [
8873
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
8874
- type: "checkbox",
8875
- disabled,
8876
- "aria-describedby": disabled ? reasonId : void 0,
8877
- checked: selected.has(status.member.memberId),
8878
- onChange: (event) => {
8879
- setSelected((current) => {
8880
- const next = new Set(current);
8881
- if (event.target.checked) next.add(status.member.memberId);
8882
- else next.delete(status.member.memberId);
8883
- return next;
8884
- });
8885
- setPendingCreate(void 0);
8886
- }
8887
- }),
8888
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamPresenceDot, {
8889
- status,
8890
- t
8891
- }),
8892
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: status.member.handle }),
8893
- disabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
8894
- id: reasonId,
8895
- children: t("memberUnavailableReason")
8896
- })
8897
- ]
8898
- }, status.member.memberId);
9710
+ options: [...creatingAgents.map((request) => ({
9711
+ id: request.requestId,
9712
+ label: request.handle,
9713
+ disabled: true,
9714
+ hint: t("memberCreatingReason")
9715
+ })), ...members.map((status) => ({
9716
+ id: status.member.memberId,
9717
+ label: status.member.handle,
9718
+ ...status.presence === "unavailable" ? {
9719
+ disabled: true,
9720
+ hint: t("memberUnavailableReason")
9721
+ } : {},
9722
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamPresenceDot, {
9723
+ status,
9724
+ t
8899
9725
  })
8900
- ]
9726
+ }))],
9727
+ selected: [...selected],
9728
+ onToggle: (id) => {
9729
+ setSelected((current) => {
9730
+ const next = new Set(current);
9731
+ if (next.has(id)) next.delete(id);
9732
+ else next.add(id);
9733
+ return next;
9734
+ });
9735
+ setPendingCreate(void 0);
9736
+ },
9737
+ triggerEmptyLabel: t("membersPickerEmpty"),
9738
+ formatCount: (count) => t("membersPickerCount", { count })
8901
9739
  }),
8902
9740
  error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8903
9741
  className: create_module_css_default.error,
@@ -9034,7 +9872,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9034
9872
  event.preventDefault();
9035
9873
  const normalizedName = name.trim();
9036
9874
  const normalizedDescription = description.trim();
9037
- if (saving || !dirty || normalizedName === "" || normalizedDescription === "") return;
9875
+ if (saving || !dirty || normalizedName === "") return;
9038
9876
  const request = pendingRequest.current !== void 0 && pendingRequest.current.channelRef === channel.channelRef && pendingRequest.current.name === normalizedName && pendingRequest.current.description === normalizedDescription ? pendingRequest.current : {
9039
9877
  requestId: crypto.randomUUID(),
9040
9878
  workspaceId: channel.workspaceId,
@@ -9074,7 +9912,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9074
9912
  type: "submit",
9075
9913
  form: "team-channel-edit-form",
9076
9914
  variant: "primary",
9077
- disabled: saving || !dirty || name.trim() === "" || description.trim() === "",
9915
+ disabled: saving || !dirty || name.trim() === "",
9078
9916
  children: saving ? t("editSaving") : t("editSave")
9079
9917
  })] }),
9080
9918
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
@@ -9099,9 +9937,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9099
9937
  }),
9100
9938
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
9101
9939
  className: create_module_css_default.field,
9102
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("channelDescription") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
9940
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [t("channelDescription"), t("optionalSuffix")] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
9103
9941
  className: create_module_css_default.input,
9104
9942
  value: description,
9943
+ placeholder: t("agentDescriptionPlaceholder"),
9105
9944
  onChange: (event) => {
9106
9945
  setDescription(event.target.value);
9107
9946
  pendingRequest.current = void 0;
@@ -9162,12 +10001,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9162
10001
  }
9163
10002
  //#endregion
9164
10003
  //#region src/client/TeamWorkspaceBrowser.tsx
9165
- function TeamWorkspaceBrowser({ wide, expandSidebar, navigation, selectWorkspace, selectChannel, t, useWorkspaces, loadMembers, subscribeChanges, addMember, loadChannels, createChannel, updateChannel, updateMember, joinChannel, removeChannelMember, loadModels, openMemberSession }) {
10004
+ function TeamWorkspaceBrowser({ wide, expandSidebar, navigation, selectWorkspace, selectChannel, t, useWorkspaces, loadMembers, subscribeChanges, addMember, loadChannels, createChannel, updateChannel, updateMember, recoverMember, restartMember, joinChannel, removeChannelMember, loadModels, openMemberSession }) {
9166
10005
  const navigationState = (0, react.useSyncExternalStore)(navigation.subscribe, navigation.getSnapshot, navigation.getSnapshot);
9167
10006
  const workspaces = useWorkspaces((state) => state.items);
9168
10007
  const selected = navigationState.workspaceId;
9169
10008
  const selectedId = selected !== void 0 && workspaces.some((workspace) => workspace.workspaceId === selected) ? selected : workspaces[0]?.workspaceId;
9170
- const overviewIsCurrent = navigationState.channelRef === void 0;
10009
+ const overviewIsCurrent = navigationState.channelRef === void 0 && navigationState.memberSessionId === void 0;
9171
10010
  const [creatingAgents, setCreatingAgents] = (0, react.useState)([]);
9172
10011
  const [pendingSection, setPendingSection] = (0, react.useState)();
9173
10012
  const channelsRef = (0, react.useRef)(null);
@@ -9255,7 +10094,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9255
10094
  joinChannel,
9256
10095
  removeChannelMember,
9257
10096
  creatingAgents: creatingAgents.filter((request) => request.workspaceId === selectedId),
9258
- ...navigationState.channelRef === void 0 ? {} : { selectedChannelRef: navigationState.channelRef },
10097
+ ...navigationState.memberSessionId !== void 0 || navigationState.channelRef === void 0 ? {} : { selectedChannelRef: navigationState.channelRef },
9259
10098
  selectChannel,
9260
10099
  t
9261
10100
  }, selectedId)
@@ -9268,9 +10107,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9268
10107
  loadChannels,
9269
10108
  addMember,
9270
10109
  updateMember,
10110
+ recoverMember,
10111
+ restartMember,
9271
10112
  joinChannel,
9272
10113
  removeChannelMember,
9273
10114
  loadModels,
10115
+ ...navigationState.memberSessionId === void 0 ? {} : { memberSessionId: navigationState.memberSessionId },
9274
10116
  openMemberSession,
9275
10117
  onCreatingChange: (request, creating) => {
9276
10118
  setCreatingAgents((current) => creating ? [...current.filter((item) => item.requestId !== request.requestId), request] : current.filter((item) => item.requestId !== request.requestId));
@@ -9322,6 +10164,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9322
10164
  manageMembers: "管理成员",
9323
10165
  editChannel: "编辑频道",
9324
10166
  editAgent: "编辑 Agent",
10167
+ resumeAgent: "恢复",
10168
+ restartAgent: "重启会话",
10169
+ optionalSuffix: "(可选)",
10170
+ agentDescriptionPlaceholder: "留空则暂无描述",
10171
+ channelsPickerEmpty: "选择初始频道",
10172
+ channelsPickerCount: "已选 {count} 个频道",
10173
+ membersPickerEmpty: "选择初始成员",
10174
+ membersPickerCount: "已选 {count} 个成员",
10175
+ reasoningEffort: "推理强度",
10176
+ effortFollowDefault: "跟随模型默认",
10177
+ attachFiles: "添加附件",
10178
+ removeFile: "移除 {name}",
10179
+ attachmentExpired: "文件已过期清理",
10180
+ viewImage: "查看大图 {name}",
9325
10181
  actionsChannel: "{name} 的操作",
9326
10182
  actionsAgent: "{name} 的操作",
9327
10183
  editSave: "保存",
@@ -9433,6 +10289,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9433
10289
  manageMembers: "Manage members",
9434
10290
  editChannel: "Edit Channel",
9435
10291
  editAgent: "Edit Agent",
10292
+ resumeAgent: "Resume",
10293
+ restartAgent: "Restart session",
10294
+ optionalSuffix: " (optional)",
10295
+ agentDescriptionPlaceholder: "Leave empty if not needed",
10296
+ channelsPickerEmpty: "Choose initial channels",
10297
+ channelsPickerCount: "{count} selected",
10298
+ membersPickerEmpty: "Choose initial members",
10299
+ membersPickerCount: "{count} selected",
10300
+ reasoningEffort: "Reasoning effort",
10301
+ effortFollowDefault: "Follow model default",
10302
+ attachFiles: "Add attachments",
10303
+ removeFile: "Remove {name}",
10304
+ attachmentExpired: "File expired and cleaned up",
10305
+ viewImage: "View image {name}",
9436
10306
  actionsChannel: "{name} actions",
9437
10307
  actionsAgent: "{name} actions",
9438
10308
  editSave: "Save",
@@ -9517,27 +10387,35 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9517
10387
  "sessions",
9518
10388
  "connection"
9519
10389
  ];
9520
- function registerModeShadow(ctx, navigation, changes, name, component, extraInject) {
10390
+ function registerModeShadow(ctx, navigation, changes, drafts, name, component, extraInject) {
9521
10391
  const sharedRemotes = {
9522
10392
  loadChannels: (request) => ctx.remote.agentTeam.view(request),
9523
10393
  subscribeChanges: (scope, listener) => changes.subscribe(scope, listener),
10394
+ drafts,
9524
10395
  loadMembers: (request) => ctx.remote.agentTeam.members(request),
9525
10396
  joinChannel: (request) => ctx.remote.agentTeam.joinChannel(request),
9526
10397
  removeChannelMember: (request) => ctx.remote.agentTeam.removeChannelMember(request),
9527
10398
  updateChannel: (request) => ctx.remote.agentTeam.updateChannel(request),
9528
10399
  updateMember: (request) => ctx.remote.agentTeam.updateMember(request),
10400
+ recoverMember: (request) => ctx.remote.agentTeam.recoverMember(request),
10401
+ restartMember: (request) => ctx.remote.agentTeam.restartMember(request),
9529
10402
  loadModels: async () => {
9530
10403
  return (await ctx.get("connection").api.llm.models({})).result;
9531
10404
  },
9532
10405
  openMemberSession: (sessionId) => {
9533
- navigation.actions().leaveTeam();
9534
- ctx.sessions.open(sessionId);
10406
+ const sessions = ctx.sessions;
10407
+ const snapshot = navigation.getSnapshot();
10408
+ const current = sessions.list.getSnapshot().current;
10409
+ const returnTo = snapshot.memberSessionId === void 0 && current !== void 0 && current !== sessionId ? current : void 0;
10410
+ navigation.actions().enterMemberSession(sessionId, returnTo);
10411
+ sessions.open(sessionId);
9535
10412
  }
9536
10413
  };
9537
10414
  ctx.slots.inject(name, () => {
9538
10415
  let dispose;
9539
10416
  const reconcile = () => {
9540
- const active = navigation.getSnapshot().mode === "team";
10417
+ const snapshot = navigation.getSnapshot();
10418
+ const active = snapshot.mode === "team" && !(name === "conversation" && snapshot.memberSessionId !== void 0);
9541
10419
  if (active && dispose === void 0) dispose = ctx.slots.register({
9542
10420
  name,
9543
10421
  priority: -100,
@@ -9551,6 +10429,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9551
10429
  readThread: (request) => ctx.remote.agentTeam.readThread(request),
9552
10430
  loadThreadHistory: (request) => ctx.remote.agentTeam.threadHistory(request),
9553
10431
  sendMessage: (request) => ctx.remote.agentTeam.sendMessage(request),
10432
+ putAttachment: (request) => ctx.remote.agentTeam.putAttachment(request),
10433
+ getAttachment: (request) => ctx.remote.agentTeam.getAttachment(request),
9554
10434
  reply: (request) => ctx.remote.agentTeam.reply(request),
9555
10435
  changeTask: (request) => ctx.remote.agentTeam.changeTask(request)
9556
10436
  } : {},
@@ -9581,9 +10461,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9581
10461
  }), "agent-team: dictionaries");
9582
10462
  const navigation = new TeamNavigation();
9583
10463
  const disposeNavigation = ctx.reflect.provide("teamNavigation", navigation);
10464
+ const drafts = new TeamDraftStore();
10465
+ const disposeDrafts = ctx.reflect.provide("teamDrafts", drafts);
9584
10466
  ctx.effect(() => () => {
9585
10467
  navigation.dispose();
10468
+ drafts.dispose();
9586
10469
  disposeNavigation();
10470
+ disposeDrafts();
9587
10471
  }, "agent-team: navigation service");
9588
10472
  const changes = new TeamChangeStream((request, signal) => ctx.remote.agentTeam.changes(request, signal));
9589
10473
  const loadMemberGroups = async () => {
@@ -9606,12 +10490,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9606
10490
  inject: () => ({
9607
10491
  navigation,
9608
10492
  ...navigation.actions(),
10493
+ leaveTeam: () => {
10494
+ const snapshot = navigation.getSnapshot();
10495
+ if (snapshot.memberSessionId === void 0) {
10496
+ navigation.actions().leaveTeam();
10497
+ return;
10498
+ }
10499
+ const returnTo = snapshot.returnToSessionId;
10500
+ navigation.actions().exitMemberSession();
10501
+ if (returnTo !== void 0) ctx.sessions.open(returnTo);
10502
+ navigation.actions().leaveTeam();
10503
+ },
9609
10504
  loadMemberGroups
9610
10505
  })
9611
10506
  }, TeamFooterAction));
9612
- registerModeShadow(ctx, navigation, changes, "sidebar.workspaces", TeamWorkspaceBrowser);
9613
- registerModeShadow(ctx, navigation, changes, "conversation", TeamConversation);
9614
- registerModeShadow(ctx, navigation, changes, "sidebar.settings", TeamSettings, () => ({ loadMemberGroups }));
10507
+ registerModeShadow(ctx, navigation, changes, drafts, "sidebar.workspaces", TeamWorkspaceBrowser);
10508
+ registerModeShadow(ctx, navigation, changes, drafts, "conversation", TeamConversation);
10509
+ registerModeShadow(ctx, navigation, changes, drafts, "sidebar.settings", TeamSettings, () => ({ loadMemberGroups }));
9615
10510
  }
9616
10511
  async function apply(ctx) {
9617
10512
  const disposeRemote = await ctx.remote.$mount(TYPERT_REMOTE);