@wowyuarm/dsh-agent-team 0.1.10 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -4
- package/README.zh.md +17 -4
- package/package.json +53 -47
- package/packages/agent-team/README.md +6 -4
- package/packages/agent-team/README.zh.md +6 -4
- package/packages/agent-team/lib/context-management.js +40 -50
- package/packages/agent-team/lib/context-projection.js +15 -1
- package/packages/agent-team/lib/index.js +244 -154
- package/packages/agent-team/lib/invariant.js +38 -4
- package/packages/agent-team/lib/ledger.js +775 -383
- package/packages/agent-team/lib/member-context.js +6 -2
- package/packages/agent-team/lib/member-runtime.js +47 -9
- package/packages/agent-team/lib/member-time-context.js +20 -5
- package/packages/agent-team/lib/mentions.js +56 -0
- package/packages/agent-team/lib/pressure-policy.js +33 -9
- package/packages/agent-team/lib/session-event-cursor.js +116 -0
- package/packages/agent-team/lib/session-remediation.js +38 -26
- package/packages/agent-team/lib/spec.js +47 -34
- package/packages/agent-team/lib/stored-session-reader.js +138 -0
- package/packages/agent-team/lib/typert.host.js +157 -41
- package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
- package/packages/agent-team/lib/typert.remote-client.js +129 -32
- package/packages/agent-team/lib/types/context-management.d.ts +7 -0
- package/packages/agent-team/lib/types/context-management.d.ts.map +1 -1
- package/packages/agent-team/lib/types/context-projection.d.ts +8 -0
- package/packages/agent-team/lib/types/context-projection.d.ts.map +1 -1
- package/packages/agent-team/lib/types/index.d.ts +77 -7
- package/packages/agent-team/lib/types/index.d.ts.map +1 -1
- package/packages/agent-team/lib/types/invariant.d.ts.map +1 -1
- package/packages/agent-team/lib/types/ledger.d.ts +251 -20
- package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
- package/packages/agent-team/lib/types/member-context.d.ts.map +1 -1
- package/packages/agent-team/lib/types/member-runtime.d.ts +2 -1
- package/packages/agent-team/lib/types/member-runtime.d.ts.map +1 -1
- package/packages/agent-team/lib/types/member-time-context.d.ts.map +1 -1
- package/packages/agent-team/lib/types/mentions.d.ts +34 -0
- package/packages/agent-team/lib/types/mentions.d.ts.map +1 -0
- package/packages/agent-team/lib/types/pressure-policy.d.ts +18 -0
- package/packages/agent-team/lib/types/pressure-policy.d.ts.map +1 -1
- package/packages/agent-team/lib/types/session-event-cursor.d.ts +119 -0
- package/packages/agent-team/lib/types/session-event-cursor.d.ts.map +1 -0
- package/packages/agent-team/lib/types/session-remediation.d.ts +23 -0
- package/packages/agent-team/lib/types/session-remediation.d.ts.map +1 -1
- package/packages/agent-team/lib/types/spec.d.ts.map +1 -1
- package/packages/agent-team/lib/types/stored-session-reader.d.ts +92 -0
- package/packages/agent-team/lib/types/stored-session-reader.d.ts.map +1 -0
- package/packages/agent-team/lib/types/types/entities.d.ts +28 -20
- package/packages/agent-team/lib/types/types/entities.d.ts.map +1 -1
- package/packages/agent-team/lib/types/types/operations.d.ts +45 -19
- package/packages/agent-team/lib/types/types/operations.d.ts.map +1 -1
- package/packages/agent-team/lib/types/types/requests-results.d.ts +87 -4
- package/packages/agent-team/lib/types/types/requests-results.d.ts.map +1 -1
- package/packages/agent-team/preset/team-member/agent.cordis.yml +49 -7
- package/packages/client-agent-team/README.md +1 -1
- package/packages/client-agent-team/README.zh.md +1 -1
- package/packages/client-agent-team/lib/client.js +2357 -1207
- package/packages/client-agent-team/lib/client.js.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +27 -7
- package/packages/client-agent-team/lib/types/client/TeamAvatarStack.d.ts +18 -0
- package/packages/client-agent-team/lib/types/client/TeamAvatarStack.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/TeamAvatarStack.js +22 -0
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts +3 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +167 -35
- package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.js +23 -27
- package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts +11 -5
- package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamComposer.js +26 -26
- package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts +1 -1
- package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamConversation.js +9 -2
- package/packages/client-agent-team/lib/types/client/TeamCountBadge.d.ts +20 -0
- package/packages/client-agent-team/lib/types/client/TeamCountBadge.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/TeamCountBadge.js +25 -0
- package/packages/client-agent-team/lib/types/client/TeamInboxPage.d.ts +25 -0
- package/packages/client-agent-team/lib/types/client/TeamInboxPage.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/TeamInboxPage.js +139 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.js +8 -24
- package/packages/client-agent-team/lib/types/client/TeamMemberRow.d.ts +43 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberRow.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberRow.js +27 -0
- package/packages/client-agent-team/lib/types/client/TeamMembersAction.d.ts +2 -2
- package/packages/client-agent-team/lib/types/client/TeamMembersAction.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamMembersAction.js +2 -2
- package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts +9 -2
- package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamMessage.js +11 -4
- package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts +8 -0
- package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamPresenceDot.js +21 -1
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +108 -30
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts +1 -1
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +68 -7
- package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/index.js +19 -9
- package/packages/client-agent-team/lib/types/client/locales.d.ts +40 -2
- package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/locales.js +40 -2
- package/packages/client-agent-team/lib/types/client/navigation.d.ts +10 -0
- package/packages/client-agent-team/lib/types/client/navigation.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/navigation.js +18 -7
- package/packages/client-agent-team/lib/types/client/scope-coverage.d.ts +41 -0
- package/packages/client-agent-team/lib/types/client/scope-coverage.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/scope-coverage.js +64 -0
- package/packages/client-agent-team/lib/types/client/slots.d.ts +7 -2
- package/packages/client-agent-team/lib/types/client/slots.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/team-changes.d.ts +33 -2
- package/packages/client-agent-team/lib/types/client/team-changes.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/team-changes.js +107 -25
- package/packages/client-agent-team/lib/types/client/team-dialog-save.d.ts +20 -0
- package/packages/client-agent-team/lib/types/client/team-dialog-save.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/team-dialog-save.js +36 -0
- package/packages/client-agent-team/lib/types/client/team-formatters.d.ts +43 -1
- package/packages/client-agent-team/lib/types/client/team-formatters.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/team-formatters.js +81 -6
- package/packages/tool-agent-team/README.md +2 -2
- package/packages/tool-agent-team/README.zh.md +2 -2
- package/packages/tool-agent-team/lib/context-tools.js +18 -14
- package/packages/tool-agent-team/lib/host-access.js +20 -0
- package/packages/tool-agent-team/lib/index.js +44 -32
- package/packages/tool-agent-team/lib/types/context-tools.d.ts.map +1 -1
- package/packages/tool-agent-team/lib/types/host-access.d.ts +14 -0
- package/packages/tool-agent-team/lib/types/host-access.d.ts.map +1 -0
- package/packages/tool-agent-team/lib/types/index.d.ts.map +1 -1
- package/packages/agent-team/lib/progress-nudge.js +0 -328
- package/packages/agent-team/lib/types/progress-nudge.d.ts +0 -136
- package/packages/agent-team/lib/types/progress-nudge.d.ts.map +0 -1
- package/packages/client-agent-team/lib/types/client/TeamSettings.d.ts +0 -3
- package/packages/client-agent-team/lib/types/client/TeamSettings.d.ts.map +0 -1
- package/packages/client-agent-team/lib/types/client/TeamSettings.js +0 -5
|
@@ -4143,7 +4143,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4143
4143
|
literal("working"),
|
|
4144
4144
|
literal("error")
|
|
4145
4145
|
]).readonly(),
|
|
4146
|
-
"diagnostic":
|
|
4146
|
+
"diagnostic": object({
|
|
4147
|
+
"class": union([
|
|
4148
|
+
literal("session-refused"),
|
|
4149
|
+
literal("session-unreadable"),
|
|
4150
|
+
literal("preset-composition"),
|
|
4151
|
+
literal("rollover"),
|
|
4152
|
+
literal("runtime"),
|
|
4153
|
+
literal("activation")
|
|
4154
|
+
]).readonly(),
|
|
4155
|
+
"detail": string().readonly(),
|
|
4156
|
+
"location": object({
|
|
4157
|
+
"kind": string().readonly(),
|
|
4158
|
+
"path": string().readonly()
|
|
4159
|
+
}).readonly().optional(),
|
|
4160
|
+
"sessionId": intersection(string(), unknown()).readonly().optional(),
|
|
4161
|
+
"remediable": boolean().readonly().optional()
|
|
4162
|
+
}).readonly().optional(),
|
|
4147
4163
|
"capabilityWarnings": union([_undefined(), array(object({
|
|
4148
4164
|
"name": string().readonly(),
|
|
4149
4165
|
"knownNames": array(string()).readonly()
|
|
@@ -4294,6 +4310,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4294
4310
|
object({
|
|
4295
4311
|
"kind": literal("thread").readonly(),
|
|
4296
4312
|
"threadRef": intersection(string(), unknown()).readonly()
|
|
4313
|
+
}),
|
|
4314
|
+
object({
|
|
4315
|
+
"kind": literal("presence").readonly(),
|
|
4316
|
+
"workspaceId": intersection(string(), unknown()).readonly()
|
|
4297
4317
|
})
|
|
4298
4318
|
]).readonly().optional()
|
|
4299
4319
|
});
|
|
@@ -4436,7 +4456,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4436
4456
|
literal("working"),
|
|
4437
4457
|
literal("error")
|
|
4438
4458
|
]).readonly(),
|
|
4439
|
-
"diagnostic":
|
|
4459
|
+
"diagnostic": object({
|
|
4460
|
+
"class": union([
|
|
4461
|
+
literal("session-refused"),
|
|
4462
|
+
literal("session-unreadable"),
|
|
4463
|
+
literal("preset-composition"),
|
|
4464
|
+
literal("rollover"),
|
|
4465
|
+
literal("runtime"),
|
|
4466
|
+
literal("activation")
|
|
4467
|
+
]).readonly(),
|
|
4468
|
+
"detail": string().readonly(),
|
|
4469
|
+
"location": object({
|
|
4470
|
+
"kind": string().readonly(),
|
|
4471
|
+
"path": string().readonly()
|
|
4472
|
+
}).readonly().optional(),
|
|
4473
|
+
"sessionId": intersection(string(), unknown()).readonly().optional(),
|
|
4474
|
+
"remediable": boolean().readonly().optional()
|
|
4475
|
+
}).readonly().optional(),
|
|
4440
4476
|
"capabilityWarnings": union([_undefined(), array(object({
|
|
4441
4477
|
"name": string().readonly(),
|
|
4442
4478
|
"knownNames": array(string()).readonly()
|
|
@@ -4481,6 +4517,53 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4481
4517
|
const _wowyuarm_dsh_agent_team_agentTeam_inbox_result$schema = object({
|
|
4482
4518
|
"items": array(object({
|
|
4483
4519
|
"channelRef": intersection(string(), unknown()).readonly(),
|
|
4520
|
+
"channelName": string().readonly().optional(),
|
|
4521
|
+
"task": object({
|
|
4522
|
+
"taskRef": intersection(string(), unknown()).readonly(),
|
|
4523
|
+
"channelRef": intersection(string(), unknown()).readonly(),
|
|
4524
|
+
"threadRef": intersection(string(), unknown()).readonly(),
|
|
4525
|
+
"status": union([
|
|
4526
|
+
literal("done"),
|
|
4527
|
+
literal("todo"),
|
|
4528
|
+
literal("in_progress"),
|
|
4529
|
+
literal("in_review"),
|
|
4530
|
+
literal("closed")
|
|
4531
|
+
]).readonly(),
|
|
4532
|
+
"resolution": union([
|
|
4533
|
+
literal("closed"),
|
|
4534
|
+
literal("open"),
|
|
4535
|
+
literal("accepted")
|
|
4536
|
+
]).readonly()
|
|
4537
|
+
}).readonly().optional(),
|
|
4538
|
+
"taskNumber": number().readonly().optional(),
|
|
4539
|
+
"thread": object({
|
|
4540
|
+
"threadRef": intersection(string(), unknown()).readonly(),
|
|
4541
|
+
"taskRef": intersection(string(), unknown()).readonly().optional(),
|
|
4542
|
+
"revision": number().readonly()
|
|
4543
|
+
}).readonly(),
|
|
4544
|
+
"unreadCount": number().readonly(),
|
|
4545
|
+
"directCount": number().readonly(),
|
|
4546
|
+
"previewText": string().readonly().optional(),
|
|
4547
|
+
"newestSequence": number().readonly(),
|
|
4548
|
+
"newestOccurredAt": string().readonly(),
|
|
4549
|
+
"newestActor": object({
|
|
4550
|
+
"memberId": intersection(string(), unknown()).readonly(),
|
|
4551
|
+
"name": string().readonly()
|
|
4552
|
+
}).readonly(),
|
|
4553
|
+
"claimOwners": array(object({
|
|
4554
|
+
"memberId": intersection(string(), unknown()).readonly(),
|
|
4555
|
+
"name": string().readonly()
|
|
4556
|
+
})).readonly(),
|
|
4557
|
+
"attention": object({
|
|
4558
|
+
"memberId": intersection(string(), unknown()).readonly(),
|
|
4559
|
+
"threadRef": intersection(string(), unknown()).readonly(),
|
|
4560
|
+
"startSequence": number().readonly(),
|
|
4561
|
+
"readThroughSequence": number().readonly()
|
|
4562
|
+
}).readonly().optional()
|
|
4563
|
+
})).readonly(),
|
|
4564
|
+
"recent": array(object({
|
|
4565
|
+
"channelRef": intersection(string(), unknown()).readonly(),
|
|
4566
|
+
"channelName": string().readonly().optional(),
|
|
4484
4567
|
"task": object({
|
|
4485
4568
|
"taskRef": intersection(string(), unknown()).readonly(),
|
|
4486
4569
|
"channelRef": intersection(string(), unknown()).readonly(),
|
|
@@ -4498,6 +4581,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4498
4581
|
literal("accepted")
|
|
4499
4582
|
]).readonly()
|
|
4500
4583
|
}).readonly().optional(),
|
|
4584
|
+
"taskNumber": number().readonly().optional(),
|
|
4501
4585
|
"thread": object({
|
|
4502
4586
|
"threadRef": intersection(string(), unknown()).readonly(),
|
|
4503
4587
|
"taskRef": intersection(string(), unknown()).readonly().optional(),
|
|
@@ -4505,8 +4589,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4505
4589
|
}).readonly(),
|
|
4506
4590
|
"unreadCount": number().readonly(),
|
|
4507
4591
|
"directCount": number().readonly(),
|
|
4592
|
+
"previewText": string().readonly().optional(),
|
|
4508
4593
|
"newestSequence": number().readonly(),
|
|
4509
4594
|
"newestOccurredAt": string().readonly(),
|
|
4595
|
+
"newestActor": object({
|
|
4596
|
+
"memberId": intersection(string(), unknown()).readonly(),
|
|
4597
|
+
"name": string().readonly()
|
|
4598
|
+
}).readonly(),
|
|
4599
|
+
"claimOwners": array(object({
|
|
4600
|
+
"memberId": intersection(string(), unknown()).readonly(),
|
|
4601
|
+
"name": string().readonly()
|
|
4602
|
+
})).readonly(),
|
|
4510
4603
|
"attention": object({
|
|
4511
4604
|
"memberId": intersection(string(), unknown()).readonly(),
|
|
4512
4605
|
"threadRef": intersection(string(), unknown()).readonly(),
|
|
@@ -4571,7 +4664,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4571
4664
|
literal("working"),
|
|
4572
4665
|
literal("error")
|
|
4573
4666
|
]).readonly(),
|
|
4574
|
-
"diagnostic":
|
|
4667
|
+
"diagnostic": object({
|
|
4668
|
+
"class": union([
|
|
4669
|
+
literal("session-refused"),
|
|
4670
|
+
literal("session-unreadable"),
|
|
4671
|
+
literal("preset-composition"),
|
|
4672
|
+
literal("rollover"),
|
|
4673
|
+
literal("runtime"),
|
|
4674
|
+
literal("activation")
|
|
4675
|
+
]).readonly(),
|
|
4676
|
+
"detail": string().readonly(),
|
|
4677
|
+
"location": object({
|
|
4678
|
+
"kind": string().readonly(),
|
|
4679
|
+
"path": string().readonly()
|
|
4680
|
+
}).readonly().optional(),
|
|
4681
|
+
"sessionId": intersection(string(), unknown()).readonly().optional(),
|
|
4682
|
+
"remediable": boolean().readonly().optional()
|
|
4683
|
+
}).readonly().optional(),
|
|
4575
4684
|
"capabilityWarnings": union([_undefined(), array(object({
|
|
4576
4685
|
"name": string().readonly(),
|
|
4577
4686
|
"knownNames": array(string()).readonly()
|
|
@@ -4673,7 +4782,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4673
4782
|
"requestId": intersection(string(), unknown()).readonly(),
|
|
4674
4783
|
"sequence": number().readonly(),
|
|
4675
4784
|
"occurredAt": string().readonly()
|
|
4676
|
-
}).readonly(),
|
|
4785
|
+
}).readonly().optional(),
|
|
4677
4786
|
"task": object({
|
|
4678
4787
|
"taskRef": intersection(string(), unknown()).readonly(),
|
|
4679
4788
|
"channelRef": intersection(string(), unknown()).readonly(),
|
|
@@ -4800,6 +4909,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4800
4909
|
})).readonly(),
|
|
4801
4910
|
"readThroughSequence": number().readonly(),
|
|
4802
4911
|
"remainingUnreadCount": number().readonly(),
|
|
4912
|
+
"earlierFactCount": number().readonly().optional(),
|
|
4803
4913
|
"attention": object({
|
|
4804
4914
|
"memberId": intersection(string(), unknown()).readonly(),
|
|
4805
4915
|
"threadRef": intersection(string(), unknown()).readonly(),
|
|
@@ -4819,8 +4929,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4819
4929
|
"hardLimit": union([_undefined(), number()]).readonly().optional(),
|
|
4820
4930
|
"action": union([
|
|
4821
4931
|
literal("unavailable"),
|
|
4822
|
-
literal("keep"),
|
|
4823
4932
|
literal("rollover"),
|
|
4933
|
+
literal("keep"),
|
|
4824
4934
|
literal("handoff-now")
|
|
4825
4935
|
]).readonly(),
|
|
4826
4936
|
"guidance": string().readonly()
|
|
@@ -4869,7 +4979,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4869
4979
|
literal("working"),
|
|
4870
4980
|
literal("error")
|
|
4871
4981
|
]).readonly(),
|
|
4872
|
-
"diagnostic":
|
|
4982
|
+
"diagnostic": object({
|
|
4983
|
+
"class": union([
|
|
4984
|
+
literal("session-refused"),
|
|
4985
|
+
literal("session-unreadable"),
|
|
4986
|
+
literal("preset-composition"),
|
|
4987
|
+
literal("rollover"),
|
|
4988
|
+
literal("runtime"),
|
|
4989
|
+
literal("activation")
|
|
4990
|
+
]).readonly(),
|
|
4991
|
+
"detail": string().readonly(),
|
|
4992
|
+
"location": object({
|
|
4993
|
+
"kind": string().readonly(),
|
|
4994
|
+
"path": string().readonly()
|
|
4995
|
+
}).readonly().optional(),
|
|
4996
|
+
"sessionId": intersection(string(), unknown()).readonly().optional(),
|
|
4997
|
+
"remediable": boolean().readonly().optional()
|
|
4998
|
+
}).readonly().optional(),
|
|
4873
4999
|
"capabilityWarnings": union([_undefined(), array(object({
|
|
4874
5000
|
"name": string().readonly(),
|
|
4875
5001
|
"knownNames": array(string()).readonly()
|
|
@@ -5013,7 +5139,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5013
5139
|
"threadRef": intersection(string(), unknown()).readonly(),
|
|
5014
5140
|
"messageRef": intersection(string(), unknown()).readonly(),
|
|
5015
5141
|
"sequence": number().readonly()
|
|
5016
|
-
})).readonly()
|
|
5142
|
+
})).readonly(),
|
|
5143
|
+
"undeliveredMentions": array(intersection(string(), unknown())).readonly().optional()
|
|
5017
5144
|
})
|
|
5018
5145
|
]);
|
|
5019
5146
|
const _wowyuarm_dsh_agent_team_agentTeam_resolveTaskRefs_parameter_0$schema = object({
|
|
@@ -5348,7 +5475,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5348
5475
|
literal("working"),
|
|
5349
5476
|
literal("error")
|
|
5350
5477
|
]).readonly(),
|
|
5351
|
-
"diagnostic":
|
|
5478
|
+
"diagnostic": object({
|
|
5479
|
+
"class": union([
|
|
5480
|
+
literal("session-refused"),
|
|
5481
|
+
literal("session-unreadable"),
|
|
5482
|
+
literal("preset-composition"),
|
|
5483
|
+
literal("rollover"),
|
|
5484
|
+
literal("runtime"),
|
|
5485
|
+
literal("activation")
|
|
5486
|
+
]).readonly(),
|
|
5487
|
+
"detail": string().readonly(),
|
|
5488
|
+
"location": object({
|
|
5489
|
+
"kind": string().readonly(),
|
|
5490
|
+
"path": string().readonly()
|
|
5491
|
+
}).readonly().optional(),
|
|
5492
|
+
"sessionId": intersection(string(), unknown()).readonly().optional(),
|
|
5493
|
+
"remediable": boolean().readonly().optional()
|
|
5494
|
+
}).readonly().optional(),
|
|
5352
5495
|
"capabilityWarnings": union([_undefined(), array(object({
|
|
5353
5496
|
"name": string().readonly(),
|
|
5354
5497
|
"knownNames": array(string()).readonly()
|
|
@@ -5532,7 +5675,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5532
5675
|
},
|
|
5533
5676
|
sourceLocation: {
|
|
5534
5677
|
"file": "packages/agent-team/src/index.ts",
|
|
5535
|
-
"line":
|
|
5678
|
+
"line": 699,
|
|
5536
5679
|
"column": 9
|
|
5537
5680
|
}
|
|
5538
5681
|
},
|
|
@@ -5559,7 +5702,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5559
5702
|
},
|
|
5560
5703
|
sourceLocation: {
|
|
5561
5704
|
"file": "packages/agent-team/src/index.ts",
|
|
5562
|
-
"line":
|
|
5705
|
+
"line": 689,
|
|
5563
5706
|
"column": 9
|
|
5564
5707
|
}
|
|
5565
5708
|
},
|
|
@@ -5586,7 +5729,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5586
5729
|
},
|
|
5587
5730
|
sourceLocation: {
|
|
5588
5731
|
"file": "packages/agent-team/src/index.ts",
|
|
5589
|
-
"line":
|
|
5732
|
+
"line": 1080,
|
|
5590
5733
|
"column": 9
|
|
5591
5734
|
}
|
|
5592
5735
|
},
|
|
@@ -5613,7 +5756,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5613
5756
|
},
|
|
5614
5757
|
sourceLocation: {
|
|
5615
5758
|
"file": "packages/agent-team/src/index.ts",
|
|
5616
|
-
"line":
|
|
5759
|
+
"line": 1202,
|
|
5617
5760
|
"column": 9
|
|
5618
5761
|
}
|
|
5619
5762
|
},
|
|
@@ -5641,7 +5784,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5641
5784
|
},
|
|
5642
5785
|
sourceLocation: {
|
|
5643
5786
|
"file": "packages/agent-team/src/index.ts",
|
|
5644
|
-
"line":
|
|
5787
|
+
"line": 620,
|
|
5645
5788
|
"column": 9
|
|
5646
5789
|
}
|
|
5647
5790
|
},
|
|
@@ -5668,7 +5811,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5668
5811
|
},
|
|
5669
5812
|
sourceLocation: {
|
|
5670
5813
|
"file": "packages/agent-team/src/index.ts",
|
|
5671
|
-
"line":
|
|
5814
|
+
"line": 1092,
|
|
5672
5815
|
"column": 9
|
|
5673
5816
|
}
|
|
5674
5817
|
},
|
|
@@ -5695,7 +5838,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5695
5838
|
},
|
|
5696
5839
|
sourceLocation: {
|
|
5697
5840
|
"file": "packages/agent-team/src/index.ts",
|
|
5698
|
-
"line":
|
|
5841
|
+
"line": 814,
|
|
5699
5842
|
"column": 9
|
|
5700
5843
|
}
|
|
5701
5844
|
},
|
|
@@ -5722,7 +5865,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5722
5865
|
},
|
|
5723
5866
|
sourceLocation: {
|
|
5724
5867
|
"file": "packages/agent-team/src/index.ts",
|
|
5725
|
-
"line":
|
|
5868
|
+
"line": 662,
|
|
5726
5869
|
"column": 9
|
|
5727
5870
|
}
|
|
5728
5871
|
},
|
|
@@ -5749,7 +5892,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5749
5892
|
},
|
|
5750
5893
|
sourceLocation: {
|
|
5751
5894
|
"file": "packages/agent-team/src/index.ts",
|
|
5752
|
-
"line":
|
|
5895
|
+
"line": 1188,
|
|
5753
5896
|
"column": 9
|
|
5754
5897
|
}
|
|
5755
5898
|
},
|
|
@@ -5776,7 +5919,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5776
5919
|
},
|
|
5777
5920
|
sourceLocation: {
|
|
5778
5921
|
"file": "packages/agent-team/src/index.ts",
|
|
5779
|
-
"line":
|
|
5922
|
+
"line": 1211,
|
|
5780
5923
|
"column": 3
|
|
5781
5924
|
}
|
|
5782
5925
|
},
|
|
@@ -5803,7 +5946,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5803
5946
|
},
|
|
5804
5947
|
sourceLocation: {
|
|
5805
5948
|
"file": "packages/agent-team/src/index.ts",
|
|
5806
|
-
"line":
|
|
5949
|
+
"line": 1112,
|
|
5807
5950
|
"column": 9
|
|
5808
5951
|
}
|
|
5809
5952
|
},
|
|
@@ -5831,7 +5974,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5831
5974
|
},
|
|
5832
5975
|
sourceLocation: {
|
|
5833
5976
|
"file": "packages/agent-team/src/index.ts",
|
|
5834
|
-
"line":
|
|
5977
|
+
"line": 611,
|
|
5835
5978
|
"column": 3
|
|
5836
5979
|
}
|
|
5837
5980
|
},
|
|
@@ -5858,7 +6001,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5858
6001
|
},
|
|
5859
6002
|
sourceLocation: {
|
|
5860
6003
|
"file": "packages/agent-team/src/index.ts",
|
|
5861
|
-
"line":
|
|
6004
|
+
"line": 1102,
|
|
5862
6005
|
"column": 9
|
|
5863
6006
|
}
|
|
5864
6007
|
},
|
|
@@ -5885,7 +6028,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5885
6028
|
},
|
|
5886
6029
|
sourceLocation: {
|
|
5887
6030
|
"file": "packages/agent-team/src/index.ts",
|
|
5888
|
-
"line":
|
|
6031
|
+
"line": 1175,
|
|
5889
6032
|
"column": 9
|
|
5890
6033
|
}
|
|
5891
6034
|
},
|
|
@@ -5912,7 +6055,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5912
6055
|
},
|
|
5913
6056
|
sourceLocation: {
|
|
5914
6057
|
"file": "packages/agent-team/src/index.ts",
|
|
5915
|
-
"line":
|
|
6058
|
+
"line": 1218,
|
|
5916
6059
|
"column": 9
|
|
5917
6060
|
}
|
|
5918
6061
|
},
|
|
@@ -5939,7 +6082,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5939
6082
|
},
|
|
5940
6083
|
sourceLocation: {
|
|
5941
6084
|
"file": "packages/agent-team/src/index.ts",
|
|
5942
|
-
"line":
|
|
6085
|
+
"line": 759,
|
|
5943
6086
|
"column": 9
|
|
5944
6087
|
}
|
|
5945
6088
|
},
|
|
@@ -5966,7 +6109,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5966
6109
|
},
|
|
5967
6110
|
sourceLocation: {
|
|
5968
6111
|
"file": "packages/agent-team/src/index.ts",
|
|
5969
|
-
"line":
|
|
6112
|
+
"line": 1123,
|
|
5970
6113
|
"column": 9
|
|
5971
6114
|
}
|
|
5972
6115
|
},
|
|
@@ -5993,7 +6136,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5993
6136
|
},
|
|
5994
6137
|
sourceLocation: {
|
|
5995
6138
|
"file": "packages/agent-team/src/index.ts",
|
|
5996
|
-
"line":
|
|
6139
|
+
"line": 1196,
|
|
5997
6140
|
"column": 9
|
|
5998
6141
|
}
|
|
5999
6142
|
},
|
|
@@ -6020,7 +6163,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6020
6163
|
},
|
|
6021
6164
|
sourceLocation: {
|
|
6022
6165
|
"file": "packages/agent-team/src/index.ts",
|
|
6023
|
-
"line":
|
|
6166
|
+
"line": 598,
|
|
6024
6167
|
"column": 3
|
|
6025
6168
|
}
|
|
6026
6169
|
},
|
|
@@ -6047,7 +6190,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6047
6190
|
},
|
|
6048
6191
|
sourceLocation: {
|
|
6049
6192
|
"file": "packages/agent-team/src/index.ts",
|
|
6050
|
-
"line":
|
|
6193
|
+
"line": 1132,
|
|
6051
6194
|
"column": 9
|
|
6052
6195
|
}
|
|
6053
6196
|
},
|
|
@@ -6074,7 +6217,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6074
6217
|
},
|
|
6075
6218
|
sourceLocation: {
|
|
6076
6219
|
"file": "packages/agent-team/src/index.ts",
|
|
6077
|
-
"line":
|
|
6220
|
+
"line": 1236,
|
|
6078
6221
|
"column": 3
|
|
6079
6222
|
}
|
|
6080
6223
|
},
|
|
@@ -6101,7 +6244,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6101
6244
|
},
|
|
6102
6245
|
sourceLocation: {
|
|
6103
6246
|
"file": "packages/agent-team/src/index.ts",
|
|
6104
|
-
"line":
|
|
6247
|
+
"line": 1229,
|
|
6105
6248
|
"column": 3
|
|
6106
6249
|
}
|
|
6107
6250
|
},
|
|
@@ -6128,7 +6271,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6128
6271
|
},
|
|
6129
6272
|
sourceLocation: {
|
|
6130
6273
|
"file": "packages/agent-team/src/index.ts",
|
|
6131
|
-
"line":
|
|
6274
|
+
"line": 674,
|
|
6132
6275
|
"column": 9
|
|
6133
6276
|
}
|
|
6134
6277
|
},
|
|
@@ -6155,7 +6298,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6155
6298
|
},
|
|
6156
6299
|
sourceLocation: {
|
|
6157
6300
|
"file": "packages/agent-team/src/index.ts",
|
|
6158
|
-
"line":
|
|
6301
|
+
"line": 1020,
|
|
6159
6302
|
"column": 9
|
|
6160
6303
|
}
|
|
6161
6304
|
},
|
|
@@ -6182,7 +6325,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6182
6325
|
},
|
|
6183
6326
|
sourceLocation: {
|
|
6184
6327
|
"file": "packages/agent-team/src/index.ts",
|
|
6185
|
-
"line":
|
|
6328
|
+
"line": 1243,
|
|
6186
6329
|
"column": 3
|
|
6187
6330
|
}
|
|
6188
6331
|
}
|
|
@@ -6200,6 +6343,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6200
6343
|
mode: parsed.mode === "team" ? "team" : "conversation",
|
|
6201
6344
|
...typeof parsed.workspaceId === "string" ? { workspaceId: parsed.workspaceId } : {},
|
|
6202
6345
|
...typeof parsed.channelRef === "string" ? { channelRef: parsed.channelRef } : {},
|
|
6346
|
+
...parsed.inbox === true ? { inbox: true } : {},
|
|
6203
6347
|
...hasThread ? {
|
|
6204
6348
|
threadRef: parsed.threadRef,
|
|
6205
6349
|
...typeof parsed.taskRef === "string" ? { taskRef: parsed.taskRef } : {},
|
|
@@ -6213,11 +6357,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6213
6357
|
function persistSnapshot(snapshot) {
|
|
6214
6358
|
if (typeof localStorage === "undefined") return;
|
|
6215
6359
|
try {
|
|
6216
|
-
const { mode, workspaceId, channelRef, taskRef, threadRef, taskNumber } = snapshot;
|
|
6360
|
+
const { mode, workspaceId, channelRef, taskRef, threadRef, taskNumber, inbox } = snapshot;
|
|
6217
6361
|
localStorage.setItem(STORAGE_KEY$3, JSON.stringify({
|
|
6218
6362
|
mode,
|
|
6219
6363
|
...workspaceId === void 0 ? {} : { workspaceId },
|
|
6220
6364
|
...channelRef === void 0 ? {} : { channelRef },
|
|
6365
|
+
...inbox === true ? { inbox: true } : {},
|
|
6221
6366
|
...taskRef === void 0 ? {} : { taskRef },
|
|
6222
6367
|
...threadRef === void 0 ? {} : { threadRef },
|
|
6223
6368
|
...taskNumber === void 0 ? {} : { taskNumber }
|
|
@@ -6256,6 +6401,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6256
6401
|
this.clearMemberSession();
|
|
6257
6402
|
this.setThread(threadRef, channelRef, taskRef, taskNumber);
|
|
6258
6403
|
},
|
|
6404
|
+
selectInbox: () => {
|
|
6405
|
+
this.clearMemberSession();
|
|
6406
|
+
this.setInbox();
|
|
6407
|
+
},
|
|
6259
6408
|
backToWorkspace: () => {
|
|
6260
6409
|
this.clearMemberSession();
|
|
6261
6410
|
this.setThread(void 0);
|
|
@@ -6302,8 +6451,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6302
6451
|
this.commit();
|
|
6303
6452
|
}
|
|
6304
6453
|
setWorkspace(workspaceId) {
|
|
6305
|
-
if (this.snapshot.workspaceId === workspaceId) return;
|
|
6306
|
-
const { channelRef: _channelRef, taskRef: _taskRef, threadRef: _threadRef, taskNumber: _taskNumber, ...base } = this.snapshot;
|
|
6454
|
+
if (this.snapshot.workspaceId === workspaceId && this.snapshot.inbox !== true) return;
|
|
6455
|
+
const { channelRef: _channelRef, taskRef: _taskRef, threadRef: _threadRef, taskNumber: _taskNumber, inbox: _inbox, ...base } = this.snapshot;
|
|
6307
6456
|
this.snapshot = {
|
|
6308
6457
|
...base,
|
|
6309
6458
|
workspaceId
|
|
@@ -6311,14 +6460,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6311
6460
|
this.commit();
|
|
6312
6461
|
}
|
|
6313
6462
|
setChannel(channelRef) {
|
|
6314
|
-
if (this.snapshot.channelRef === channelRef && this.snapshot.threadRef === void 0) return;
|
|
6315
|
-
const { taskRef: _taskRef, threadRef: _threadRef, taskNumber: _taskNumber, ...base } = this.snapshot;
|
|
6463
|
+
if (this.snapshot.channelRef === channelRef && this.snapshot.threadRef === void 0 && this.snapshot.inbox !== true) return;
|
|
6464
|
+
const { taskRef: _taskRef, threadRef: _threadRef, taskNumber: _taskNumber, inbox: _inbox, ...base } = this.snapshot;
|
|
6316
6465
|
this.snapshot = {
|
|
6317
6466
|
...base,
|
|
6318
6467
|
channelRef
|
|
6319
6468
|
};
|
|
6320
6469
|
this.commit();
|
|
6321
6470
|
}
|
|
6471
|
+
/** The Inbox is a face, not workspace content: selecting a Workspace leaves it. */
|
|
6472
|
+
setInbox() {
|
|
6473
|
+
if (this.snapshot.inbox === true && this.snapshot.channelRef === void 0 && this.snapshot.threadRef === void 0) return;
|
|
6474
|
+
const { channelRef: _channelRef, taskRef: _taskRef, threadRef: _threadRef, taskNumber: _taskNumber, ...base } = this.snapshot;
|
|
6475
|
+
this.snapshot = {
|
|
6476
|
+
...base,
|
|
6477
|
+
inbox: true
|
|
6478
|
+
};
|
|
6479
|
+
this.commit();
|
|
6480
|
+
}
|
|
6322
6481
|
clearChannel() {
|
|
6323
6482
|
const { channelRef: _channelRef, ...base } = this.snapshot;
|
|
6324
6483
|
if (this.snapshot.channelRef === void 0) return;
|
|
@@ -6326,12 +6485,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6326
6485
|
this.commit();
|
|
6327
6486
|
}
|
|
6328
6487
|
setThread(threadRef, channelRef, taskRef, taskNumber) {
|
|
6329
|
-
if (this.snapshot.threadRef === threadRef && this.snapshot.taskRef === taskRef && this.snapshot.channelRef === channelRef && this.snapshot.taskNumber === taskNumber) return;
|
|
6488
|
+
if (this.snapshot.threadRef === threadRef && this.snapshot.taskRef === taskRef && this.snapshot.channelRef === channelRef && this.snapshot.taskNumber === taskNumber && this.snapshot.inbox !== true) return;
|
|
6330
6489
|
if (threadRef === void 0) {
|
|
6331
6490
|
const { taskRef: _taskRef, threadRef: _threadRef, taskNumber: _taskNumber, ...base } = this.snapshot;
|
|
6332
6491
|
this.snapshot = base;
|
|
6333
6492
|
} else {
|
|
6334
|
-
const { channelRef: _channelRef, taskRef: _taskRef, threadRef: _threadRef, taskNumber: _taskNumber, ...base } = this.snapshot;
|
|
6493
|
+
const { channelRef: _channelRef, taskRef: _taskRef, threadRef: _threadRef, taskNumber: _taskNumber, inbox: _inbox, ...base } = this.snapshot;
|
|
6335
6494
|
this.snapshot = {
|
|
6336
6495
|
...base,
|
|
6337
6496
|
threadRef,
|
|
@@ -6349,17 +6508,50 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6349
6508
|
};
|
|
6350
6509
|
//#endregion
|
|
6351
6510
|
//#region src/client/team-changes.ts
|
|
6511
|
+
/** First retry delay after a failed call, doubling up to the cap. */
|
|
6512
|
+
const RETRY_BASE_MS = 1e3;
|
|
6513
|
+
const RETRY_MAX_MS = 3e4;
|
|
6514
|
+
/** Abortable delay: the poll's subscription ending must not wait out a backoff. */
|
|
6515
|
+
function sleep(ms, signal) {
|
|
6516
|
+
return new Promise((resolve) => {
|
|
6517
|
+
const done = () => {
|
|
6518
|
+
clearTimeout(timer);
|
|
6519
|
+
signal.removeEventListener("abort", done);
|
|
6520
|
+
resolve();
|
|
6521
|
+
};
|
|
6522
|
+
const timer = setTimeout(done, ms);
|
|
6523
|
+
signal.addEventListener("abort", done, { once: true });
|
|
6524
|
+
});
|
|
6525
|
+
}
|
|
6352
6526
|
function scopeKey(scope) {
|
|
6353
|
-
return scope.kind === "workspace" ? `workspace:${scope.workspaceId}` : scope.kind === "channel" ? `channel:${scope.channelRef}` : `thread:${scope.threadRef}`;
|
|
6527
|
+
return scope === void 0 ? "all" : scope.kind === "workspace" ? `workspace:${scope.workspaceId}` : scope.kind === "channel" ? `channel:${scope.channelRef}` : scope.kind === "presence" ? `presence:${scope.workspaceId}` : `thread:${scope.threadRef}`;
|
|
6354
6528
|
}
|
|
6355
6529
|
/**
|
|
6356
6530
|
* One long-poll per change scope, shared by every listening surface: panels
|
|
6357
6531
|
* and pages never open parallel `changes` requests for the same scope, and
|
|
6358
6532
|
* the poll is aborted as soon as the last subscriber leaves.
|
|
6533
|
+
*
|
|
6534
|
+
* A failed call reports the outage to every listener once and then keeps
|
|
6535
|
+
* retrying with backoff. The transport recovers on its own terms — a Host
|
|
6536
|
+
* restart, a sleep/wake, a dropped proxy — and a surface that stayed mounted
|
|
6537
|
+
* has to resume from that recovery rather than stay silent until it remounts,
|
|
6538
|
+
* so the first answered call after an outage wakes every listener once even
|
|
6539
|
+
* when the cursor did not move.
|
|
6540
|
+
*
|
|
6541
|
+
* Each poll keeps its own cursor, and a cursor only means something inside the
|
|
6542
|
+
* scope it was issued for: the Host answers a presence scope from a
|
|
6543
|
+
* process-local wake epoch and every other scope from a durable ledger
|
|
6544
|
+
* position.
|
|
6359
6545
|
*/
|
|
6360
6546
|
var TeamChangeStream = class {
|
|
6361
6547
|
changes;
|
|
6362
6548
|
polls = /* @__PURE__ */ new Map();
|
|
6549
|
+
/**
|
|
6550
|
+
* The last version each scope key answered with, kept after that scope's poll
|
|
6551
|
+
* is torn down: a commit landing while no poll exists is otherwise folded into
|
|
6552
|
+
* the replacement poll's opening sample, which reports nothing.
|
|
6553
|
+
*/
|
|
6554
|
+
observed = /* @__PURE__ */ new Map();
|
|
6363
6555
|
constructor(changes) {
|
|
6364
6556
|
this.changes = changes;
|
|
6365
6557
|
}
|
|
@@ -6369,7 +6561,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6369
6561
|
if (poll === void 0) {
|
|
6370
6562
|
poll = {
|
|
6371
6563
|
controller: new AbortController(),
|
|
6372
|
-
listeners: /* @__PURE__ */ new Set()
|
|
6564
|
+
listeners: /* @__PURE__ */ new Set(),
|
|
6565
|
+
resumeFrom: this.observed.get(key)
|
|
6373
6566
|
};
|
|
6374
6567
|
this.polls.set(key, poll);
|
|
6375
6568
|
this.run(key, scope, poll);
|
|
@@ -6386,27 +6579,46 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6386
6579
|
}
|
|
6387
6580
|
async run(key, scope, poll) {
|
|
6388
6581
|
const { signal } = poll.controller;
|
|
6389
|
-
const
|
|
6390
|
-
afterVersion
|
|
6391
|
-
scope
|
|
6392
|
-
}
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
return;
|
|
6397
|
-
}
|
|
6398
|
-
let version = probe.value.version;
|
|
6582
|
+
const request = (afterVersion) => ({
|
|
6583
|
+
afterVersion,
|
|
6584
|
+
...scope === void 0 ? {} : { scope }
|
|
6585
|
+
});
|
|
6586
|
+
let version = poll.resumeFrom;
|
|
6587
|
+
let retryDelay = RETRY_BASE_MS;
|
|
6588
|
+
let reported = false;
|
|
6399
6589
|
while (!signal.aborted) {
|
|
6400
|
-
const result = await this.changes(
|
|
6401
|
-
|
|
6402
|
-
scope
|
|
6403
|
-
}, signal);
|
|
6404
|
-
if (signal.aborted) return;
|
|
6590
|
+
const result = await this.changes(request(version ?? 0), signal);
|
|
6591
|
+
if (signal.aborted || this.polls.get(key) !== poll) return;
|
|
6405
6592
|
if (!result.ok) {
|
|
6406
|
-
|
|
6407
|
-
|
|
6593
|
+
if (!reported) {
|
|
6594
|
+
reported = true;
|
|
6595
|
+
for (const listener of poll.listeners) listener({
|
|
6596
|
+
type: "failed",
|
|
6597
|
+
message: result.error.message
|
|
6598
|
+
});
|
|
6599
|
+
}
|
|
6600
|
+
await sleep(retryDelay, signal);
|
|
6601
|
+
retryDelay = Math.min(retryDelay * 2, RETRY_MAX_MS);
|
|
6602
|
+
continue;
|
|
6603
|
+
}
|
|
6604
|
+
retryDelay = RETRY_BASE_MS;
|
|
6605
|
+
if (reported) {
|
|
6606
|
+
reported = false;
|
|
6607
|
+
version = result.value.version;
|
|
6608
|
+
this.observed.set(key, version);
|
|
6609
|
+
for (const listener of poll.listeners) listener({
|
|
6610
|
+
type: "changed",
|
|
6611
|
+
version
|
|
6612
|
+
});
|
|
6613
|
+
continue;
|
|
6614
|
+
}
|
|
6615
|
+
if (version === void 0) {
|
|
6616
|
+
version = result.value.version;
|
|
6617
|
+
this.observed.set(key, version);
|
|
6618
|
+
continue;
|
|
6408
6619
|
}
|
|
6409
|
-
|
|
6620
|
+
this.observed.set(key, result.value.version);
|
|
6621
|
+
if (result.value.version !== version) {
|
|
6410
6622
|
version = result.value.version;
|
|
6411
6623
|
for (const listener of poll.listeners) listener({
|
|
6412
6624
|
type: "changed",
|
|
@@ -6415,12 +6627,26 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6415
6627
|
}
|
|
6416
6628
|
}
|
|
6417
6629
|
}
|
|
6418
|
-
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6630
|
+
};
|
|
6631
|
+
/**
|
|
6632
|
+
* The Host's `changes` stream never wakes on a Thread read — a read advances
|
|
6633
|
+
* only the reader's private watermark, so no shared projection changes. A
|
|
6634
|
+
* durable read does consume the reader's own mention markers, so the Human's
|
|
6635
|
+
* badge and Inbox page refresh from the completed read itself instead of
|
|
6636
|
+
* waiting for the next unrelated commit.
|
|
6637
|
+
*/
|
|
6638
|
+
var TeamReadStream = class {
|
|
6639
|
+
version = 0;
|
|
6640
|
+
listeners = /* @__PURE__ */ new Set();
|
|
6641
|
+
bump() {
|
|
6642
|
+
this.version += 1;
|
|
6643
|
+
for (const listener of this.listeners) listener();
|
|
6644
|
+
}
|
|
6645
|
+
subscribe(listener) {
|
|
6646
|
+
this.listeners.add(listener);
|
|
6647
|
+
return () => {
|
|
6648
|
+
this.listeners.delete(listener);
|
|
6649
|
+
};
|
|
6424
6650
|
}
|
|
6425
6651
|
};
|
|
6426
6652
|
//#endregion
|
|
@@ -6555,13 +6781,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6555
6781
|
};
|
|
6556
6782
|
//#endregion
|
|
6557
6783
|
//#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/team.module.css.mjs
|
|
6558
|
-
const css$
|
|
6559
|
-
const tagId$
|
|
6560
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$
|
|
6784
|
+
const css$13 = ".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)}.YvAbSa_footerAction:focus-visible,.YvAbSa_settingsAction:focus-visible{outline:2px solid var(--dsw-alias-label-primary);outline-offset:-2px}.YvAbSa_footerAction.YvAbSa_rail,.YvAbSa_settingsAction.YvAbSa_rail{corner-shape:round;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}";
|
|
6785
|
+
const tagId$13 = "@wowyuarm/dsh-agent-team/team.module.css";
|
|
6786
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$13) + "]") === null) {
|
|
6561
6787
|
const tag = document.createElement("style");
|
|
6562
6788
|
tag.dataset.plugin = "@wowyuarm/dsh-agent-team";
|
|
6563
|
-
tag.dataset.pluginCss = tagId$
|
|
6564
|
-
tag.textContent = css$
|
|
6789
|
+
tag.dataset.pluginCss = tagId$13;
|
|
6790
|
+
tag.textContent = css$13;
|
|
6565
6791
|
document.head.appendChild(tag);
|
|
6566
6792
|
}
|
|
6567
6793
|
var team_module_css_default = {
|
|
@@ -6604,303 +6830,769 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6604
6830
|
}) });
|
|
6605
6831
|
}
|
|
6606
6832
|
//#endregion
|
|
6607
|
-
//#region
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6833
|
+
//#region src/client/team-formatters.ts
|
|
6834
|
+
function formatTaskStatus(status, t) {
|
|
6835
|
+
return t({
|
|
6836
|
+
todo: "taskStatusTodo",
|
|
6837
|
+
in_progress: "taskStatusInProgress",
|
|
6838
|
+
in_review: "taskStatusInReview",
|
|
6839
|
+
done: "taskStatusDone",
|
|
6840
|
+
closed: "taskStatusClosed"
|
|
6841
|
+
}[status]);
|
|
6842
|
+
}
|
|
6843
|
+
function formatClaimState(state, t) {
|
|
6844
|
+
return t({
|
|
6845
|
+
active: "claimStateActive",
|
|
6846
|
+
done: "claimStateDone",
|
|
6847
|
+
released: "claimStateReleased"
|
|
6848
|
+
}[state]);
|
|
6616
6849
|
}
|
|
6617
|
-
var state_dot_module_css_default = { "quiet": "DalNWW_quiet" };
|
|
6618
|
-
//#endregion
|
|
6619
|
-
//#region src/client/TeamStateDot.tsx
|
|
6620
6850
|
/**
|
|
6621
|
-
*
|
|
6622
|
-
*
|
|
6623
|
-
*
|
|
6624
|
-
*
|
|
6851
|
+
* Status indicator for a Task status, the dot every Task surface renders.
|
|
6852
|
+
* Active states map to StateDot variants; every status renders a dot so they
|
|
6853
|
+
* share one shape language — todo is a hollow ring (not started), closed a
|
|
6854
|
+
* quiet gray dot (archived).
|
|
6625
6855
|
*/
|
|
6626
|
-
function
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
"
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
"aria-hidden": "true"
|
|
6635
|
-
});
|
|
6636
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
|
|
6637
|
-
state,
|
|
6638
|
-
size
|
|
6639
|
-
});
|
|
6856
|
+
function taskStatusDot(status) {
|
|
6857
|
+
return {
|
|
6858
|
+
todo: "todo",
|
|
6859
|
+
in_progress: "ongoing",
|
|
6860
|
+
in_review: "warning",
|
|
6861
|
+
done: "done",
|
|
6862
|
+
closed: "quiet"
|
|
6863
|
+
}[status];
|
|
6640
6864
|
}
|
|
6641
|
-
|
|
6642
|
-
|
|
6643
|
-
|
|
6644
|
-
|
|
6645
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$7) + "]") === null) {
|
|
6646
|
-
const tag = document.createElement("style");
|
|
6647
|
-
tag.dataset.plugin = "@wowyuarm/dsh-agent-team";
|
|
6648
|
-
tag.dataset.pluginCss = tagId$7;
|
|
6649
|
-
tag.textContent = css$7;
|
|
6650
|
-
document.head.appendChild(tag);
|
|
6865
|
+
/** One-line title snippet derived from the Task's root Message body. */
|
|
6866
|
+
function formatTaskTitle(body) {
|
|
6867
|
+
const firstLine = body.split("\n", 1)[0]?.trim() ?? "";
|
|
6868
|
+
return firstLine.length > 120 ? `${firstLine.slice(0, 119)}…` : firstLine;
|
|
6651
6869
|
}
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
return status.diagnostic === void 0 ? label : `${label}: ${status.diagnostic}`;
|
|
6870
|
+
/** Deterministic avatar hue for one Member identity; stable across sessions and themes. */
|
|
6871
|
+
function memberHue(memberId) {
|
|
6872
|
+
let hash = 0;
|
|
6873
|
+
for (let index = 0; index < memberId.length; index += 1) hash = (hash * 31 + memberId.charCodeAt(index)) % 360;
|
|
6874
|
+
return hash;
|
|
6658
6875
|
}
|
|
6659
|
-
|
|
6660
|
-
|
|
6661
|
-
|
|
6876
|
+
const BRANDED_REF_PATTERN = /\b(task|channel|thread):{1,2}[0-9a-f]{6,}(?:-[0-9a-f]{1,})*\b/gi;
|
|
6877
|
+
/**
|
|
6878
|
+
* Canonical form of one matched ref: models occasionally double the colon or
|
|
6879
|
+
* uppercase the UUID when citing a ref in prose, while Host lookups and
|
|
6880
|
+
* navigation only accept the lowercase single-colon ref the ledger mints.
|
|
6881
|
+
*/
|
|
6882
|
+
function canonicalBrandedRef(match) {
|
|
6883
|
+
return match.replace("::", ":").toLowerCase();
|
|
6662
6884
|
}
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
|
|
6885
|
+
/**
|
|
6886
|
+
* Split a literal text run into plain and branded-ref segments. The pattern
|
|
6887
|
+
* anchors on the fixed ref prefixes plus a UUID shape (full or abbreviated),
|
|
6888
|
+
* so ordinary prose containing a colon never linkifies; a doubled colon from
|
|
6889
|
+
* model output is tolerated. Segment refs are always canonical, so resolution
|
|
6890
|
+
* and navigation work regardless of how the ref was spelled; text without any
|
|
6891
|
+
* ref comes back as one untouched segment.
|
|
6892
|
+
*/
|
|
6893
|
+
function splitBrandedRefs(text) {
|
|
6894
|
+
const segments = [];
|
|
6895
|
+
let cursor = 0;
|
|
6896
|
+
for (const match of text.matchAll(BRANDED_REF_PATTERN)) {
|
|
6897
|
+
const start = match.index ?? 0;
|
|
6898
|
+
if (start > cursor) segments.push({ text: text.slice(cursor, start) });
|
|
6899
|
+
segments.push({
|
|
6900
|
+
text: match[0],
|
|
6901
|
+
ref: canonicalBrandedRef(match[0])
|
|
6902
|
+
});
|
|
6903
|
+
cursor = start + match[0].length;
|
|
6904
|
+
}
|
|
6905
|
+
if (cursor < text.length) segments.push({ text: text.slice(cursor) });
|
|
6906
|
+
return segments;
|
|
6675
6907
|
}
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6908
|
+
/**
|
|
6909
|
+
* Whether one string's whole content is exactly one branded ref. A code span
|
|
6910
|
+
* like this is the model styling a ref as an identifier, not publishing code,
|
|
6911
|
+
* so the Markdown pass may linkify it; anything larger stays literal.
|
|
6912
|
+
*/
|
|
6913
|
+
function isSingleBrandedRef(text) {
|
|
6914
|
+
const trimmed = text.trim();
|
|
6915
|
+
if (trimmed === "") return false;
|
|
6916
|
+
const matches = [...trimmed.matchAll(BRANDED_REF_PATTERN)];
|
|
6917
|
+
return matches.length === 1 && matches[0][0] === trimmed;
|
|
6686
6918
|
}
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
const contentRef = (0, react.useRef)(null);
|
|
6705
|
-
(0, react.useEffect)(() => {
|
|
6706
|
-
if (!panelOpen) return;
|
|
6707
|
-
queueMicrotask(() => {
|
|
6708
|
-
contentRef.current?.focus();
|
|
6709
|
-
});
|
|
6710
|
-
}, [panelOpen]);
|
|
6711
|
-
const openMembers = () => {
|
|
6712
|
-
setPanelOpen(true);
|
|
6713
|
-
setLoading(true);
|
|
6714
|
-
setError(void 0);
|
|
6715
|
-
loadMemberGroups().then(setGroups).catch((cause) => {
|
|
6716
|
-
setError(cause instanceof Error ? cause.message : String(cause));
|
|
6717
|
-
}).finally(() => {
|
|
6718
|
-
setLoading(false);
|
|
6719
|
-
});
|
|
6919
|
+
function escapeRegExp(value) {
|
|
6920
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6921
|
+
}
|
|
6922
|
+
/**
|
|
6923
|
+
* Locate one Message's structured mention names inside its literal body. A
|
|
6924
|
+
* name matches case-insensitively with an optional leading '@' on Unicode word
|
|
6925
|
+
* boundaries, and longer names win at the same position. Mention segments
|
|
6926
|
+
* render the canonical `@Handle`; names absent from the body come back
|
|
6927
|
+
* unmatched so the consumer can append them as a fallback chip row.
|
|
6928
|
+
*/
|
|
6929
|
+
function splitMentionNames(text, names) {
|
|
6930
|
+
if (names.length === 0) return {
|
|
6931
|
+
segments: [{
|
|
6932
|
+
text,
|
|
6933
|
+
mention: false
|
|
6934
|
+
}],
|
|
6935
|
+
unmatched: []
|
|
6720
6936
|
};
|
|
6721
|
-
const
|
|
6722
|
-
|
|
6723
|
-
|
|
6724
|
-
|
|
6937
|
+
const ordered = [...names].sort((left, right) => right.length - left.length);
|
|
6938
|
+
const pattern = new RegExp(`(?<![\\p{L}\\p{N}_@])@?(?:${ordered.map((name) => `(${escapeRegExp(name)})`).join("|")})(?=$|[^\\p{L}\\p{N}_])`, "giu");
|
|
6939
|
+
const segments = [];
|
|
6940
|
+
const matched = /* @__PURE__ */ new Set();
|
|
6941
|
+
let cursor = 0;
|
|
6942
|
+
for (const match of text.matchAll(pattern)) {
|
|
6943
|
+
const groupIndex = match.findIndex((group, index) => index >= 1 && group !== void 0);
|
|
6944
|
+
if (groupIndex < 1) continue;
|
|
6945
|
+
if (match.index > cursor) segments.push({
|
|
6946
|
+
text: text.slice(cursor, match.index),
|
|
6947
|
+
mention: false
|
|
6948
|
+
});
|
|
6949
|
+
const name = ordered[groupIndex - 1];
|
|
6950
|
+
segments.push({
|
|
6951
|
+
text: `@${name}`,
|
|
6952
|
+
mention: true,
|
|
6953
|
+
name
|
|
6725
6954
|
});
|
|
6955
|
+
matched.add(name.toLowerCase());
|
|
6956
|
+
cursor = match.index + match[0].length;
|
|
6957
|
+
}
|
|
6958
|
+
if (cursor < text.length) segments.push({
|
|
6959
|
+
text: text.slice(cursor),
|
|
6960
|
+
mention: false
|
|
6961
|
+
});
|
|
6962
|
+
return {
|
|
6963
|
+
segments,
|
|
6964
|
+
unmatched: names.filter((name) => !matched.has(name.toLowerCase()))
|
|
6726
6965
|
};
|
|
6727
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
6728
|
-
label: t("members"),
|
|
6729
|
-
delayMs: 500,
|
|
6730
|
-
disabled: wide,
|
|
6731
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
6732
|
-
ref: triggerRef,
|
|
6733
|
-
type: "button",
|
|
6734
|
-
className: wide ? team_module_css_default.settingsAction : `${team_module_css_default.settingsAction} ${team_module_css_default.rail}`,
|
|
6735
|
-
"aria-label": t("members"),
|
|
6736
|
-
"aria-haspopup": "dialog",
|
|
6737
|
-
onClick: openMembers,
|
|
6738
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconUserOutline16, { size: wide ? 16 : 18 }), wide && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("members") })]
|
|
6739
|
-
})
|
|
6740
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
6741
|
-
open: panelOpen,
|
|
6742
|
-
onClose: closeMembers,
|
|
6743
|
-
title: t("members"),
|
|
6744
|
-
closeLabel: t("close"),
|
|
6745
|
-
contentClassName: members_module_css_default.body,
|
|
6746
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6747
|
-
ref: contentRef,
|
|
6748
|
-
className: members_module_css_default.content,
|
|
6749
|
-
tabIndex: -1,
|
|
6750
|
-
children: [
|
|
6751
|
-
loading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6752
|
-
className: members_module_css_default.state,
|
|
6753
|
-
role: "status",
|
|
6754
|
-
children: t("loadingAgents")
|
|
6755
|
-
}),
|
|
6756
|
-
!loading && groups.length === 0 && error === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6757
|
-
className: members_module_css_default.state,
|
|
6758
|
-
children: t("emptyAgents")
|
|
6759
|
-
}),
|
|
6760
|
-
!loading && groups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
6761
|
-
className: members_module_css_default.group,
|
|
6762
|
-
"aria-labelledby": `team-members-${group.workspaceId}`,
|
|
6763
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
6764
|
-
id: `team-members-${group.workspaceId}`,
|
|
6765
|
-
children: group.workspaceTitle
|
|
6766
|
-
}), group.members.map((status) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6767
|
-
className: members_module_css_default.member,
|
|
6768
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamPresenceDot, {
|
|
6769
|
-
status,
|
|
6770
|
-
t
|
|
6771
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
6772
|
-
className: members_module_css_default.copy,
|
|
6773
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", { children: ["@", status.member.handle] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: status.member.description })]
|
|
6774
|
-
})]
|
|
6775
|
-
}, status.member.memberId))]
|
|
6776
|
-
}, group.workspaceId)),
|
|
6777
|
-
error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6778
|
-
className: members_module_css_default.error,
|
|
6779
|
-
role: "alert",
|
|
6780
|
-
children: error
|
|
6781
|
-
})
|
|
6782
|
-
]
|
|
6783
|
-
})
|
|
6784
|
-
})] });
|
|
6785
6966
|
}
|
|
6786
|
-
|
|
6787
|
-
|
|
6788
|
-
|
|
6789
|
-
|
|
6790
|
-
|
|
6791
|
-
|
|
6792
|
-
|
|
6793
|
-
|
|
6967
|
+
/**
|
|
6968
|
+
* Whether one draft spells a handle as an authored `@mention`: a literal `@`
|
|
6969
|
+
* before the handle, case-insensitively, on Unicode word boundaries. The Host
|
|
6970
|
+
* resolves delivery from the same text with its own scanner, so this is the
|
|
6971
|
+
* Client's single answer to "did the author call this name" — the composer
|
|
6972
|
+
* prunes picked recipients with it and previews the draft's notifications with
|
|
6973
|
+
* it.
|
|
6974
|
+
*/
|
|
6975
|
+
function containsMention(body, handle) {
|
|
6976
|
+
return new RegExp(`(?:^|[^\\p{L}\\p{N}_])@${escapeRegExp(handle)}(?=$|[^\\p{L}\\p{N}_])`, "iu").test(body);
|
|
6794
6977
|
}
|
|
6795
|
-
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
function bytesToBase64(bytes) {
|
|
6799
|
-
let binary = "";
|
|
6800
|
-
const chunk = 32768;
|
|
6801
|
-
for (let start = 0; start < bytes.length; start += chunk) binary += String.fromCharCode(...bytes.subarray(start, start + chunk));
|
|
6802
|
-
return btoa(binary);
|
|
6978
|
+
/** Whether one draft carries the `@all` marker the mention menu expands. */
|
|
6979
|
+
function containsAllMention(body) {
|
|
6980
|
+
return /(?<![\p{L}\p{N}_@])@all(?=$|[^\p{L}\p{N}_])/u.test(body);
|
|
6803
6981
|
}
|
|
6804
6982
|
/**
|
|
6805
|
-
*
|
|
6806
|
-
*
|
|
6807
|
-
*
|
|
6983
|
+
* Every Member the mention menu's `@all` row stands for: the roster this
|
|
6984
|
+
* composer was handed minus Members who cannot take a Message right now — the
|
|
6985
|
+
* same filter the per-handle rows apply, so the expansion and the menu agree.
|
|
6808
6986
|
*/
|
|
6809
|
-
|
|
6810
|
-
|
|
6811
|
-
return dataUrlCache.get(attachmentId);
|
|
6987
|
+
function allMentionMembers(members) {
|
|
6988
|
+
return members.filter((status) => status.presence !== "unavailable" && status.member.state !== "inactive" && status.member.state !== "archived");
|
|
6812
6989
|
}
|
|
6813
|
-
|
|
6814
|
-
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
|
|
6818
|
-
|
|
6819
|
-
|
|
6990
|
+
/**
|
|
6991
|
+
* Member ids one draft asks to notify by text alone: the Client's preview of
|
|
6992
|
+
* the Host's own body mention resolution, so a hand-typed `@Handle` reports
|
|
6993
|
+
* exactly like a pick from the mention menu. `@all` stands for the menu's
|
|
6994
|
+
* expansion; a written handle counts whenever its Member can still take a
|
|
6995
|
+
* Message — state decides, not presence, because an offline Member is notified
|
|
6996
|
+
* and reads it later.
|
|
6997
|
+
*
|
|
6998
|
+
* The result is preview-only. Only picked recipients travel as explicit
|
|
6999
|
+
* recipients, where a name the Channel cannot reach would be a rejected target
|
|
7000
|
+
* rather than the prose the Host reads.
|
|
7001
|
+
*/
|
|
7002
|
+
function mentionedMemberIds(body, members) {
|
|
7003
|
+
if (containsAllMention(body)) return allMentionMembers(members).map((status) => status.member.memberId);
|
|
7004
|
+
return members.filter((status) => status.member.state !== "inactive" && status.member.state !== "archived").filter((status) => containsMention(body, status.member.handle)).map((status) => status.member.memberId);
|
|
6820
7005
|
}
|
|
6821
|
-
/**
|
|
6822
|
-
function
|
|
6823
|
-
|
|
6824
|
-
if (byteSize < 1024 * 1024) return `${(byteSize / 1024).toFixed(0)} KB`;
|
|
6825
|
-
return `${(byteSize / (1024 * 1024)).toFixed(1)} MB`;
|
|
7006
|
+
/** Canonical chip handles for one Message's structured mention refs. */
|
|
7007
|
+
function mentionNamesOf(mentions, handles) {
|
|
7008
|
+
return mentions.map((memberId) => memberId === "member:human" ? "human" : handles.get(memberId)).filter((name) => name !== void 0);
|
|
6826
7009
|
}
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
/**
|
|
6830
|
-
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
|
|
6838
|
-
tag.dataset.pluginCss = tagId$5;
|
|
6839
|
-
tag.textContent = css$5;
|
|
6840
|
-
document.head.appendChild(tag);
|
|
7010
|
+
const MARKDOWN_BLOCK_CONSTRUCT = /(^|\n)[ \t]{0,3}(?:#{1,6}[ \t]|>[ \t]|[-*+][ \t]|\d+[.)][ \t])|^[ \t]*\|.+\|/m;
|
|
7011
|
+
const MARKDOWN_INLINE_CONSTRUCT = /[`*_[\]!]|~~~|```/;
|
|
7012
|
+
/**
|
|
7013
|
+
* Whether an Agent body survives literal rendering unchanged: no fences,
|
|
7014
|
+
* inline code, emphasis markers, links, images, tables, or block constructs.
|
|
7015
|
+
* Only such plain-prose bodies may reuse the Human inline mention flow —
|
|
7016
|
+
* anything richer keeps the trailing chip row because the Markdown primitive
|
|
7017
|
+
* renders block-level documents that cannot interleave inline chips.
|
|
7018
|
+
*/
|
|
7019
|
+
function isPlainTextBody(text) {
|
|
7020
|
+
return !(MARKDOWN_BLOCK_CONSTRUCT.test(text) || MARKDOWN_INLINE_CONSTRUCT.test(text));
|
|
6841
7021
|
}
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
"fileChip": "x9jGQq_fileChip",
|
|
6849
|
-
"fileChipName": "x9jGQq_fileChipName",
|
|
6850
|
-
"fileChipRemove": "x9jGQq_fileChipRemove",
|
|
6851
|
-
"fileChipSize": "x9jGQq_fileChipSize",
|
|
6852
|
-
"fileChips": "x9jGQq_fileChips",
|
|
6853
|
-
"fileInput": "x9jGQq_fileInput",
|
|
6854
|
-
"imageChip": "x9jGQq_imageChip",
|
|
6855
|
-
"imageChipPreview": "x9jGQq_imageChipPreview",
|
|
6856
|
-
"inputArea": "x9jGQq_inputArea",
|
|
6857
|
-
"mentionAllDot": "x9jGQq_mentionAllDot",
|
|
6858
|
-
"mentionDescription": "x9jGQq_mentionDescription",
|
|
6859
|
-
"mentionMenu": "x9jGQq_mentionMenu",
|
|
6860
|
-
"mentionName": "x9jGQq_mentionName",
|
|
6861
|
-
"mentionOption": "x9jGQq_mentionOption",
|
|
6862
|
-
"notifyRow": "x9jGQq_notifyRow",
|
|
6863
|
-
"root": "x9jGQq_root",
|
|
6864
|
-
"sendButton": "x9jGQq_sendButton",
|
|
6865
|
-
"toolbar": "x9jGQq_toolbar"
|
|
6866
|
-
};
|
|
6867
|
-
//#endregion
|
|
6868
|
-
//#region src/client/TeamComposer.tsx
|
|
6869
|
-
function findMention(draft, caret) {
|
|
6870
|
-
const beforeCaret = draft.slice(0, caret);
|
|
6871
|
-
if (beforeCaret.length === 0 || /\s/u.test(beforeCaret.at(-1) ?? "")) return void 0;
|
|
6872
|
-
let tokenStart = beforeCaret.length;
|
|
6873
|
-
while (tokenStart > 0 && !/\s/u.test(beforeCaret[tokenStart - 1])) tokenStart -= 1;
|
|
6874
|
-
const at = beforeCaret.lastIndexOf("@");
|
|
6875
|
-
if (at < tokenStart) return void 0;
|
|
6876
|
-
if (at > 0 && /[\p{L}\p{N}_]/u.test(beforeCaret[at - 1])) return void 0;
|
|
6877
|
-
return {
|
|
6878
|
-
start: at,
|
|
6879
|
-
end: caret,
|
|
6880
|
-
query: beforeCaret.slice(at + 1)
|
|
6881
|
-
};
|
|
7022
|
+
const pad$1 = (value) => String(value).padStart(2, "0");
|
|
7023
|
+
/** Absolute local `YYYY-MM-DD HH:mm` label: the precise instant behind every shorter form. */
|
|
7024
|
+
function formatAbsoluteTime(occurredAt) {
|
|
7025
|
+
const at = new Date(occurredAt);
|
|
7026
|
+
if (Number.isNaN(at.getTime())) return "";
|
|
7027
|
+
return `${at.getFullYear()}-${pad$1(at.getMonth() + 1)}-${pad$1(at.getDate())} ${pad$1(at.getHours())}:${pad$1(at.getMinutes())}`;
|
|
6882
7028
|
}
|
|
6883
|
-
|
|
6884
|
-
|
|
7029
|
+
/**
|
|
7030
|
+
* Wall-clock label for one Message instant: time within the current day,
|
|
7031
|
+
* month-day time within the year, full date otherwise.
|
|
7032
|
+
*/
|
|
7033
|
+
function formatMessageTime(occurredAt, now = /* @__PURE__ */ new Date()) {
|
|
7034
|
+
const at = new Date(occurredAt);
|
|
7035
|
+
if (Number.isNaN(at.getTime())) return "";
|
|
7036
|
+
if (at.getFullYear() === now.getFullYear() && at.getMonth() === now.getMonth() && at.getDate() === now.getDate()) return `${pad$1(at.getHours())}:${pad$1(at.getMinutes())}`;
|
|
7037
|
+
const absolute = formatAbsoluteTime(occurredAt);
|
|
7038
|
+
return at.getFullYear() === now.getFullYear() ? absolute.slice(5) : absolute;
|
|
6885
7039
|
}
|
|
6886
|
-
|
|
6887
|
-
|
|
7040
|
+
/**
|
|
7041
|
+
* Calendar days between two instants in the viewer's own zone, so "yesterday"
|
|
7042
|
+
* means yesterday locally rather than 24 hours earlier.
|
|
7043
|
+
*/
|
|
7044
|
+
function calendarDayDelta(at, now) {
|
|
7045
|
+
const midnight = (date) => new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
|
|
7046
|
+
return Math.round((midnight(now) - midnight(at)) / 864e5);
|
|
6888
7047
|
}
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
7048
|
+
/**
|
|
7049
|
+
* Recency label for one Inbox row's newest fact, shared with the Channel feed's
|
|
7050
|
+
* entry line so the two agree about the same instant. Today is a bare clock time
|
|
7051
|
+
* — the reader is in today, and 「今天」 printed down every row spends the label's
|
|
7052
|
+
* first word on the one segment that never varies, while `HH:mm` alone still
|
|
7053
|
+
* reads as a clock because it is exactly one. The first day that is not today is
|
|
7054
|
+
* the fact the reader has to be told, so it keeps its word; everything older
|
|
7055
|
+
* keeps the Message date form, so the row and the Thread it opens agree.
|
|
7056
|
+
*/
|
|
7057
|
+
function formatInboxTime(occurredAt, t, now = /* @__PURE__ */ new Date()) {
|
|
7058
|
+
const at = new Date(occurredAt);
|
|
7059
|
+
if (Number.isNaN(at.getTime())) return "";
|
|
7060
|
+
const days = calendarDayDelta(at, now);
|
|
7061
|
+
if (days === 0) return `${pad$1(at.getHours())}:${pad$1(at.getMinutes())}`;
|
|
7062
|
+
if (days === 1) return `${t("inboxTimeYesterday")} ${pad$1(at.getHours())}:${pad$1(at.getMinutes())}`;
|
|
7063
|
+
return formatMessageTime(occurredAt, now);
|
|
6892
7064
|
}
|
|
6893
|
-
|
|
6894
|
-
|
|
6895
|
-
if (
|
|
6896
|
-
|
|
7065
|
+
function formatActivity(activity, options) {
|
|
7066
|
+
const actor = options.actorName(activity.actor);
|
|
7067
|
+
if (activity.kind === "accept") return activity.completedClaimRefs !== void 0 && activity.completedClaimRefs.length > 0 ? options.t("activityAcceptedWithClaims", {
|
|
7068
|
+
actor,
|
|
7069
|
+
count: activity.completedClaimRefs.length
|
|
7070
|
+
}) : options.t("activityAccepted", { actor });
|
|
7071
|
+
if (activity.kind === "promote") return options.t("activityPromoted", { actor });
|
|
7072
|
+
if (activity.kind === "close") return options.t("activityClosed", { actor });
|
|
7073
|
+
if (activity.kind === "reopen") return options.t("activityReopened", { actor });
|
|
7074
|
+
const direction = "claimRef" in activity ? options.claims.find((claim) => claim.claimRef === activity.claimRef)?.direction ?? options.t("claims") : options.t("claims");
|
|
7075
|
+
if (activity.kind === "claim") return options.t("activityClaimed", {
|
|
7076
|
+
actor,
|
|
7077
|
+
direction
|
|
7078
|
+
});
|
|
7079
|
+
if (activity.kind === "done") return options.t("activityClaimDone", {
|
|
7080
|
+
actor,
|
|
7081
|
+
direction
|
|
7082
|
+
});
|
|
7083
|
+
if (activity.kind === "release") return options.t("activityClaimReleased", {
|
|
7084
|
+
actor,
|
|
7085
|
+
direction
|
|
7086
|
+
});
|
|
7087
|
+
if (activity.kind === "claims_released") return options.t("activityClaimsReleased", {
|
|
7088
|
+
actor,
|
|
7089
|
+
count: activity.claimRefs.length
|
|
7090
|
+
});
|
|
7091
|
+
throw new Error(`unknown Team Activity kind: ${activity.kind}`);
|
|
6897
7092
|
}
|
|
6898
|
-
/**
|
|
6899
|
-
function
|
|
6900
|
-
return
|
|
7093
|
+
/** Remove the machine-facing `[attachment] <path>` prompt lines from a body before display. */
|
|
7094
|
+
function stripAttachmentLines(body) {
|
|
7095
|
+
return body.replaceAll(/^\[attachment\] .*$(\n)?/gm, "").replace(/\n+$/, "");
|
|
7096
|
+
}
|
|
7097
|
+
/** Whether one displayed Message body starts clamped behind the expand control. */
|
|
7098
|
+
function shouldClampMessage(displayBody) {
|
|
7099
|
+
return displayBody.length > 600;
|
|
7100
|
+
}
|
|
7101
|
+
/**
|
|
7102
|
+
* Decide how one Message body renders. Human input and plain-prose Agent
|
|
7103
|
+
* bodies stay literal, with structured mention chips inline where possible;
|
|
7104
|
+
* rich Agent Markdown keeps unmatched mentions and non-Task refs in the
|
|
7105
|
+
* trailing fallback row while the post-render pass handles Task refs at their
|
|
7106
|
+
* authored position. Surfaces without ref navigation render everything
|
|
7107
|
+
* literally and keep the full fallback row.
|
|
7108
|
+
*/
|
|
7109
|
+
function planMessageBody(body, options) {
|
|
7110
|
+
const stripped = stripAttachmentLines(body);
|
|
7111
|
+
const displayBody = stripped === "" ? body : stripped;
|
|
7112
|
+
const richAgentBody = !options.human && !isPlainTextBody(displayBody);
|
|
7113
|
+
const inline = (options.human || isPlainTextBody(displayBody)) && options.mentionNames !== void 0 && options.mentionNames.length > 0 ? splitMentionNames(displayBody, options.mentionNames) : void 0;
|
|
7114
|
+
const fallbackNames = inline !== void 0 ? inline.unmatched : richAgentBody && options.canOpenRefs && options.mentionNames !== void 0 ? splitMentionNames(displayBody, options.mentionNames).unmatched : options.mentionNames ?? [];
|
|
7115
|
+
const refs = splitBrandedRefs(displayBody).flatMap((segment) => segment.ref === void 0 ? [] : [segment.ref]);
|
|
7116
|
+
return {
|
|
7117
|
+
displayBody,
|
|
7118
|
+
richAgentBody,
|
|
7119
|
+
render: inline !== void 0 ? "inline" : options.human || options.canOpenRefs && !richAgentBody && refs.length > 0 ? "literal" : "markdown",
|
|
7120
|
+
...inline === void 0 ? {} : { inline },
|
|
7121
|
+
fallbackNames,
|
|
7122
|
+
fallbackRefs: richAgentBody && !options.canOpenRefs ? refs : [],
|
|
7123
|
+
taskRefs: options.canOpenRefs && !richAgentBody ? refs.filter((ref) => ref.startsWith("task:")).map((ref) => ref) : []
|
|
7124
|
+
};
|
|
7125
|
+
}
|
|
7126
|
+
//#endregion
|
|
7127
|
+
//#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/state-dot.module.css.mjs
|
|
7128
|
+
const css$12 = ".DalNWW_quiet{corner-shape:round;border-radius:50%;flex:none;display:inline-block;position:relative}.DalNWW_quiet[data-variant=todo]{border:1px solid var(--dsw-alias-label-tertiary)}.DalNWW_quiet[data-variant=quiet]{color:var(--dsw-alias-label-tertiary)}.DalNWW_quiet[data-variant=quiet]:before{corner-shape:round;content:\"\";opacity:.1;background:currentColor;border-radius:50%;position:absolute;inset:0}.DalNWW_quiet[data-variant=quiet]:after{corner-shape:round;content:\"\";background:currentColor;border-radius:50%;position:absolute;inset:20%}";
|
|
7129
|
+
const tagId$12 = "@wowyuarm/dsh-agent-team/state-dot.module.css";
|
|
7130
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$12) + "]") === null) {
|
|
7131
|
+
const tag = document.createElement("style");
|
|
7132
|
+
tag.dataset.plugin = "@wowyuarm/dsh-agent-team";
|
|
7133
|
+
tag.dataset.pluginCss = tagId$12;
|
|
7134
|
+
tag.textContent = css$12;
|
|
7135
|
+
document.head.appendChild(tag);
|
|
7136
|
+
}
|
|
7137
|
+
var state_dot_module_css_default = { "quiet": "DalNWW_quiet" };
|
|
7138
|
+
//#endregion
|
|
7139
|
+
//#region src/client/TeamStateDot.tsx
|
|
7140
|
+
/**
|
|
7141
|
+
* Render the one shared Team status indicator. Native StateDot states pass
|
|
7142
|
+
* through; the quiet statuses mirror StateDot geometry locally so every
|
|
7143
|
+
* surface renders the same shape — todo a hollow ring (not started), quiet a
|
|
7144
|
+
* solid tertiary dot with the same 10% halo (closed, unavailable).
|
|
7145
|
+
*/
|
|
7146
|
+
function TeamStateDot({ state, size = 10 }) {
|
|
7147
|
+
if (state === "todo" || state === "quiet") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7148
|
+
className: state_dot_module_css_default.quiet,
|
|
7149
|
+
"data-variant": state,
|
|
7150
|
+
style: {
|
|
7151
|
+
width: size,
|
|
7152
|
+
height: size
|
|
7153
|
+
},
|
|
7154
|
+
"aria-hidden": "true"
|
|
7155
|
+
});
|
|
7156
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
|
|
7157
|
+
state,
|
|
7158
|
+
size
|
|
7159
|
+
});
|
|
7160
|
+
}
|
|
7161
|
+
//#endregion
|
|
7162
|
+
//#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/presence.module.css.mjs
|
|
7163
|
+
const css$11 = ".-\\36 lQ-q_target{flex:0 0 14px;justify-content:center;align-items:center;display:inline-flex}";
|
|
7164
|
+
const tagId$11 = "@wowyuarm/dsh-agent-team/presence.module.css";
|
|
7165
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$11) + "]") === null) {
|
|
7166
|
+
const tag = document.createElement("style");
|
|
7167
|
+
tag.dataset.plugin = "@wowyuarm/dsh-agent-team";
|
|
7168
|
+
tag.dataset.pluginCss = tagId$11;
|
|
7169
|
+
tag.textContent = css$11;
|
|
7170
|
+
document.head.appendChild(tag);
|
|
7171
|
+
}
|
|
7172
|
+
var presence_module_css_default = { "target": "-6lQ-q_target" };
|
|
7173
|
+
//#endregion
|
|
7174
|
+
//#region src/client/TeamPresenceDot.tsx
|
|
7175
|
+
function presenceLabel(status, t) {
|
|
7176
|
+
const label = status.presence === "available" ? t("statusAvailable") : status.presence === "working" ? t("statusWorking") : status.presence === "error" ? t("statusError") : t("statusUnavailable");
|
|
7177
|
+
return status.diagnostic === void 0 ? label : `${label}: ${diagnosticText(status)}`;
|
|
7178
|
+
}
|
|
7179
|
+
/** One line of human-readable diagnostic text: the reason, plus the refused artifact path when one was reported. */
|
|
7180
|
+
function diagnosticText(status) {
|
|
7181
|
+
const diagnostic = status.diagnostic;
|
|
7182
|
+
if (diagnostic === void 0) return "";
|
|
7183
|
+
return diagnostic.location === void 0 ? diagnostic.detail : `${diagnostic.detail} (${diagnostic.location.path})`;
|
|
7184
|
+
}
|
|
7185
|
+
/**
|
|
7186
|
+
* Whether the restart action can help an unavailable Member: it heals
|
|
7187
|
+
* transient and repairable failures, but not a transient rollover window
|
|
7188
|
+
* (which resolves on its own) or a refusal already proven non-remediable.
|
|
7189
|
+
*/
|
|
7190
|
+
function restartOffered(status) {
|
|
7191
|
+
const diagnostic = status.diagnostic;
|
|
7192
|
+
if (diagnostic === void 0) return true;
|
|
7193
|
+
if (diagnostic.class === "rollover") return false;
|
|
7194
|
+
return !(diagnostic.class === "session-refused" && diagnostic.remediable === false);
|
|
7195
|
+
}
|
|
7196
|
+
/** Shared presence → indicator mapping for dots and avatar badges. */
|
|
7197
|
+
function presenceDotState(presence) {
|
|
7198
|
+
return presence === "available" ? "done" : presence === "working" ? "ongoing" : presence === "error" ? "error" : "quiet";
|
|
7199
|
+
}
|
|
7200
|
+
function TeamPresenceDot({ status, t }) {
|
|
7201
|
+
const label = presenceLabel(status, t);
|
|
7202
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
7203
|
+
label,
|
|
7204
|
+
delayMs: 300,
|
|
7205
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7206
|
+
className: presence_module_css_default.target,
|
|
7207
|
+
role: "img",
|
|
7208
|
+
"aria-label": label,
|
|
7209
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamStateDot, { state: presenceDotState(status.presence) })
|
|
7210
|
+
})
|
|
7211
|
+
});
|
|
7212
|
+
}
|
|
7213
|
+
//#endregion
|
|
7214
|
+
//#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/sidebar.module.css.mjs
|
|
7215
|
+
const css$10 = "html[data-agent-team-mode=team] button[class*=newSession]{display:none}.d0xfxa_workspaceBrowser{flex-direction:column;height:100%;min-height:0;padding:0 8px 8px;display:flex}.d0xfxa_railButton{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;justify-content:center;align-items:center;padding:0;display:inline-flex}.d0xfxa_railButton:hover,.d0xfxa_railButton:focus-visible{--team-mark-ring:var(--dsw-alias-interactive-bg-hover);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.d0xfxa_railButton:focus-visible{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.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)}.d0xfxa_workspaceRow:focus-visible{outline:2px solid var(--dsw-alias-label-primary);outline-offset:-2px}.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_inboxCard{color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;background:0 0;border:0;border-radius:8px;flex:none;align-items:center;gap:6px;width:100%;height:34px;margin:4px 0 2px;padding:0 8px;display:flex}.d0xfxa_inboxCard:hover,.d0xfxa_inboxCard:focus-visible,.d0xfxa_inboxCard[aria-current=page]{--team-mark-ring:var(--dsw-alias-interactive-bg-hover);background:var(--dsw-alias-interactive-bg-hover)}.d0xfxa_inboxCard:focus-visible{outline:2px solid var(--dsw-alias-label-primary);outline-offset:-2px}.d0xfxa_inboxCard .d0xfxa_inboxMark{color:var(--dsw-alias-label-tertiary)}.d0xfxa_inboxCardLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:14px;line-height:20px;overflow:hidden}.d0xfxa_inboxMark{flex:0 0 16px;display:inline-flex;position:relative}.d0xfxa_inboxDot{background:var(--dsw-alias-state-business-primary);box-shadow:0 0 0 2px var(--team-mark-ring,var(--dsw-alias-bg-base));corner-shape:round;border-radius:50%;width:8px;height:8px;position:absolute;top:-2px;left:-2px}.d0xfxa_railWorkspace{flex-direction:column;align-items:center;gap:8px;padding-top:8px;display:flex}.d0xfxa_railButton{corner-shape:round;border-radius:50%;width:36px;height:36px;position:relative}.d0xfxa_railButton[aria-current=page]{--team-mark-ring:var(--dsw-alias-interactive-bg-hover);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;border-radius:4px;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:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.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{corner-shape:round;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)}.d0xfxa_iconButton:focus-visible{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.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)}.d0xfxa_textButton:focus-visible{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.d0xfxa_textButton:disabled{cursor:not-allowed;opacity:.4}.d0xfxa_channelList,.d0xfxa_agentList{flex-direction:column;gap:1px;padding:0 4px 4px;display:flex}.d0xfxa_sidebarRowDragging{opacity:.5}.d0xfxa_sidebarRowDropBefore,.d0xfxa_sidebarRowDropAfter{position:relative}.d0xfxa_sidebarRowDropBefore:before,.d0xfxa_sidebarRowDropAfter:after{content:\"\";z-index:1;background:linear-gradient(55deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 0 / 5px 7px no-repeat, linear-gradient(125deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 5px / 5px 7px no-repeat, linear-gradient(var(--dsw-alias-state-business-primary) 0 0) 4px 5px / calc(100% - 4px) 2px no-repeat;pointer-events:none;height:12px;position:absolute;left:0;right:4px}.d0xfxa_sidebarRowDropBefore:before{top:-7px}.d0xfxa_sidebarRowDropAfter:after{bottom:-7px}.d0xfxa_channelRow{color:var(--dsw-alias-label-primary);border-radius:8px;align-items:center;min-height:30px;display:flex;position:relative}.d0xfxa_channelSelect{box-sizing:border-box;color:inherit;cursor:pointer;text-align:left;background:0 0;border:0;border-radius:8px;flex:1;align-items:center;min-width:0;min-height:30px;padding:3px 4px 3px 8px;display:flex}.d0xfxa_channelSelect:focus-visible{outline:2px solid var(--dsw-alias-label-primary);outline-offset:-2px}.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;border-radius:8px;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:2px solid var(--dsw-alias-label-primary);outline-offset:-2px}.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%);corner-shape:round;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);corner-shape:round;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;justify-content:flex-start;min-width:0;display:flex}.d0xfxa_agentCopy strong{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:500;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);corner-shape:round;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)}.d0xfxa_rowMenuButton:focus-visible{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.d0xfxa_retryError{color:var(--dsw-alias-state-error-primary);justify-content:space-between;align-items:center;gap:8px;padding:8px 12px;font-size:11px;display:flex}.d0xfxa_rowAlert{color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;padding:2px 8px 6px;font-size:11px}.d0xfxa_error{color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;margin:0;padding:4px 12px 6px;font-size:11px;line-height:16px}.d0xfxa_editDescription{color:var(--dsw-alias-label-secondary);margin:0 0 10px;font-size:12px;line-height:18px}.d0xfxa_editMemberList{gap:2px;display:grid}.d0xfxa_editChannelName{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:400;line-height:18px;overflow:hidden}.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}";
|
|
7216
|
+
const tagId$10 = "@wowyuarm/dsh-agent-team/sidebar.module.css";
|
|
7217
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$10) + "]") === null) {
|
|
7218
|
+
const tag = document.createElement("style");
|
|
7219
|
+
tag.dataset.plugin = "@wowyuarm/dsh-agent-team";
|
|
7220
|
+
tag.dataset.pluginCss = tagId$10;
|
|
7221
|
+
tag.textContent = css$10;
|
|
7222
|
+
document.head.appendChild(tag);
|
|
7223
|
+
}
|
|
7224
|
+
var sidebar_module_css_default = {
|
|
7225
|
+
"agentAvatar": "d0xfxa_agentAvatar",
|
|
7226
|
+
"agentAvatarBadge": "d0xfxa_agentAvatarBadge",
|
|
7227
|
+
"agentCopy": "d0xfxa_agentCopy",
|
|
7228
|
+
"agentList": "d0xfxa_agentList",
|
|
7229
|
+
"agentRow": "d0xfxa_agentRow",
|
|
7230
|
+
"agentSelect": "d0xfxa_agentSelect",
|
|
7231
|
+
"channelList": "d0xfxa_channelList",
|
|
7232
|
+
"channelName": "d0xfxa_channelName",
|
|
7233
|
+
"channelRow": "d0xfxa_channelRow",
|
|
7234
|
+
"channelSelect": "d0xfxa_channelSelect",
|
|
7235
|
+
"editChannelName": "d0xfxa_editChannelName",
|
|
7236
|
+
"editDescription": "d0xfxa_editDescription",
|
|
7237
|
+
"editHint": "d0xfxa_editHint",
|
|
7238
|
+
"editMemberList": "d0xfxa_editMemberList",
|
|
7239
|
+
"emptyState": "d0xfxa_emptyState",
|
|
7240
|
+
"error": "d0xfxa_error",
|
|
7241
|
+
"iconButton": "d0xfxa_iconButton",
|
|
7242
|
+
"inboxCard": "d0xfxa_inboxCard",
|
|
7243
|
+
"inboxCardLabel": "d0xfxa_inboxCardLabel",
|
|
7244
|
+
"inboxDot": "d0xfxa_inboxDot",
|
|
7245
|
+
"inboxMark": "d0xfxa_inboxMark",
|
|
7246
|
+
"menuHint": "d0xfxa_menuHint",
|
|
7247
|
+
"panel": "d0xfxa_panel",
|
|
7248
|
+
"railButton": "d0xfxa_railButton",
|
|
7249
|
+
"railWorkspace": "d0xfxa_railWorkspace",
|
|
7250
|
+
"retryError": "d0xfxa_retryError",
|
|
7251
|
+
"rowAlert": "d0xfxa_rowAlert",
|
|
7252
|
+
"rowError": "d0xfxa_rowError",
|
|
7253
|
+
"rowMenu": "d0xfxa_rowMenu",
|
|
7254
|
+
"rowMenuButton": "d0xfxa_rowMenuButton",
|
|
7255
|
+
"section": "d0xfxa_section",
|
|
7256
|
+
"sectionActions": "d0xfxa_sectionActions",
|
|
7257
|
+
"sectionChevron": "d0xfxa_sectionChevron",
|
|
7258
|
+
"sectionHeader": "d0xfxa_sectionHeader",
|
|
7259
|
+
"sectionTitle": "d0xfxa_sectionTitle",
|
|
7260
|
+
"sectionToggle": "d0xfxa_sectionToggle",
|
|
7261
|
+
"sidebarRowDragging": "d0xfxa_sidebarRowDragging",
|
|
7262
|
+
"sidebarRowDropAfter": "d0xfxa_sidebarRowDropAfter",
|
|
7263
|
+
"sidebarRowDropBefore": "d0xfxa_sidebarRowDropBefore",
|
|
7264
|
+
"textButton": "d0xfxa_textButton",
|
|
7265
|
+
"unavailableDot": "d0xfxa_unavailableDot",
|
|
7266
|
+
"workspaceBrowser": "d0xfxa_workspaceBrowser",
|
|
7267
|
+
"workspaceCopy": "d0xfxa_workspaceCopy",
|
|
7268
|
+
"workspaceIcon": "d0xfxa_workspaceIcon",
|
|
7269
|
+
"workspaceList": "d0xfxa_workspaceList",
|
|
7270
|
+
"workspaceRow": "d0xfxa_workspaceRow",
|
|
7271
|
+
"workspaceSection": "d0xfxa_workspaceSection"
|
|
7272
|
+
};
|
|
7273
|
+
//#endregion
|
|
7274
|
+
//#region src/client/TeamMemberAvatar.tsx
|
|
7275
|
+
/**
|
|
7276
|
+
* Sidebar Member avatar reusing the conversation identity language: the
|
|
7277
|
+
* deterministic member hue and handle initial, with the presence indicator
|
|
7278
|
+
* overlaid at the bottom-right so one glyph carries identity and state.
|
|
7279
|
+
*/
|
|
7280
|
+
function TeamMemberAvatar({ status, t }) {
|
|
7281
|
+
const label = presenceLabel(status, t);
|
|
7282
|
+
const state = presenceDotState(status.presence);
|
|
7283
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
7284
|
+
label,
|
|
7285
|
+
delayMs: 300,
|
|
7286
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
7287
|
+
className: sidebar_module_css_default.agentAvatar,
|
|
7288
|
+
style: { "--team-avatar-hue": memberHue(status.member.memberId) },
|
|
7289
|
+
role: "img",
|
|
7290
|
+
"aria-label": label,
|
|
7291
|
+
children: [status.member.handle.replace("@", "").slice(0, 1).toUpperCase(), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7292
|
+
className: sidebar_module_css_default.agentAvatarBadge,
|
|
7293
|
+
"aria-hidden": "true",
|
|
7294
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamStateDot, { state })
|
|
7295
|
+
})]
|
|
7296
|
+
})
|
|
7297
|
+
});
|
|
7298
|
+
}
|
|
7299
|
+
//#endregion
|
|
7300
|
+
//#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/member-row.module.css.mjs
|
|
7301
|
+
const css$9 = ".xnbzeW_row{border-radius:8px;grid-template-columns:24px minmax(0,1fr);align-items:center;gap:0 10px;min-height:40px;padding:8px 10px;display:grid}.xnbzeW_row:has(button){grid-template-columns:24px minmax(0,1fr) auto}.xnbzeW_row:hover{background:var(--dsw-alias-interactive-bg-hover)}.xnbzeW_copy{min-width:0;display:grid}.xnbzeW_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}.xnbzeW_copy small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;line-height:16px;overflow:hidden}.xnbzeW_action{justify-self:end;min-width:64px}.xnbzeW_error{color:var(--dsw-alias-state-error-primary);grid-column:2/-1;margin:2px 0 0;font-size:11px;line-height:16px}@media (width<=600px){.xnbzeW_row,.xnbzeW_row:has(button){grid-template-columns:24px minmax(0,1fr);align-items:start}.xnbzeW_action{grid-column:2;justify-self:start;margin-top:6px}}";
|
|
7302
|
+
const tagId$9 = "@wowyuarm/dsh-agent-team/member-row.module.css";
|
|
7303
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$9) + "]") === null) {
|
|
7304
|
+
const tag = document.createElement("style");
|
|
7305
|
+
tag.dataset.plugin = "@wowyuarm/dsh-agent-team";
|
|
7306
|
+
tag.dataset.pluginCss = tagId$9;
|
|
7307
|
+
tag.textContent = css$9;
|
|
7308
|
+
document.head.appendChild(tag);
|
|
7309
|
+
}
|
|
7310
|
+
var member_row_module_css_default = {
|
|
7311
|
+
"action": "xnbzeW_action",
|
|
7312
|
+
"copy": "xnbzeW_copy",
|
|
7313
|
+
"error": "xnbzeW_error",
|
|
7314
|
+
"row": "xnbzeW_row"
|
|
7315
|
+
};
|
|
7316
|
+
//#endregion
|
|
7317
|
+
//#region src/client/TeamMemberRow.tsx
|
|
7318
|
+
/**
|
|
7319
|
+
* The one place a Member's identity is drawn: the presence-bearing avatar plus
|
|
7320
|
+
* the handle over its description. Read-only rosters, the rosters with a
|
|
7321
|
+
* membership action, and the sidebar Agent list all render this, so identity,
|
|
7322
|
+
* tone and truncation cannot drift between surfaces that show the same person.
|
|
7323
|
+
*
|
|
7324
|
+
* A fragment, not a row: each surface owns its own row element, hit target and
|
|
7325
|
+
* grid, and places this identity in that grid's first two tracks. The handle
|
|
7326
|
+
* spelling is the surface's call — rosters address Members the way the
|
|
7327
|
+
* composer does (`@handle`), the sidebar names them as the directory does.
|
|
7328
|
+
*/
|
|
7329
|
+
function TeamMemberIdentity({ status, name, className, t }) {
|
|
7330
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamMemberAvatar, {
|
|
7331
|
+
status,
|
|
7332
|
+
t
|
|
7333
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
7334
|
+
className: className === void 0 ? member_row_module_css_default.copy : `${member_row_module_css_default.copy} ${className}`,
|
|
7335
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: name ?? `@${status.member.handle.replace(/^@/, "")}` }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: status.member.description })]
|
|
7336
|
+
})] });
|
|
7337
|
+
}
|
|
7338
|
+
/**
|
|
7339
|
+
* The one roster row: identity, an optional membership action, and the row's
|
|
7340
|
+
* own failure line. The action is the row's only chrome, so the eye lands on
|
|
7341
|
+
* the handle first and on the action second. A read-only roster omits it and
|
|
7342
|
+
* the trailing track collapses, handing its width back to the description.
|
|
7343
|
+
*/
|
|
7344
|
+
function TeamMemberRow({ status, action, error, className, t }) {
|
|
7345
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7346
|
+
className: className === void 0 ? member_row_module_css_default.row : `${member_row_module_css_default.row} ${className}`,
|
|
7347
|
+
"data-team-member-row": true,
|
|
7348
|
+
children: [
|
|
7349
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamMemberIdentity, {
|
|
7350
|
+
status,
|
|
7351
|
+
t
|
|
7352
|
+
}),
|
|
7353
|
+
action !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
7354
|
+
size: "sm",
|
|
7355
|
+
variant: "outline",
|
|
7356
|
+
className: member_row_module_css_default.action,
|
|
7357
|
+
disabled: action.disabled === true,
|
|
7358
|
+
onClick: action.onSelect,
|
|
7359
|
+
children: action.label
|
|
7360
|
+
}),
|
|
7361
|
+
error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
7362
|
+
className: member_row_module_css_default.error,
|
|
7363
|
+
role: "alert",
|
|
7364
|
+
children: error
|
|
7365
|
+
})
|
|
7366
|
+
]
|
|
7367
|
+
});
|
|
7368
|
+
}
|
|
7369
|
+
//#endregion
|
|
7370
|
+
//#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/members.module.css.mjs
|
|
7371
|
+
const css$8 = ".UkovOW_body{max-height:min(65vh,560px);overflow-y:auto}.UkovOW_content{outline:none;gap:12px;display:grid}.UkovOW_group{gap:2px;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{margin:0 -6px}.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)}}";
|
|
7372
|
+
const tagId$8 = "@wowyuarm/dsh-agent-team/members.module.css";
|
|
7373
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$8) + "]") === null) {
|
|
7374
|
+
const tag = document.createElement("style");
|
|
7375
|
+
tag.dataset.plugin = "@wowyuarm/dsh-agent-team";
|
|
7376
|
+
tag.dataset.pluginCss = tagId$8;
|
|
7377
|
+
tag.textContent = css$8;
|
|
7378
|
+
document.head.appendChild(tag);
|
|
6901
7379
|
}
|
|
6902
|
-
|
|
6903
|
-
|
|
7380
|
+
var members_module_css_default = {
|
|
7381
|
+
"body": "UkovOW_body",
|
|
7382
|
+
"content": "UkovOW_content",
|
|
7383
|
+
"error": "UkovOW_error",
|
|
7384
|
+
"group": "UkovOW_group",
|
|
7385
|
+
"member": "UkovOW_member",
|
|
7386
|
+
"state": "UkovOW_state"
|
|
7387
|
+
};
|
|
7388
|
+
//#endregion
|
|
7389
|
+
//#region src/client/TeamMembersAction.tsx
|
|
7390
|
+
function TeamMembersAction({ wide, loadMemberGroups, t }) {
|
|
7391
|
+
const [panelOpen, setPanelOpen] = (0, react.useState)(false);
|
|
7392
|
+
const [groups, setGroups] = (0, react.useState)([]);
|
|
7393
|
+
const [loading, setLoading] = (0, react.useState)(false);
|
|
7394
|
+
const [error, setError] = (0, react.useState)();
|
|
7395
|
+
const triggerRef = (0, react.useRef)(null);
|
|
7396
|
+
const contentRef = (0, react.useRef)(null);
|
|
7397
|
+
(0, react.useEffect)(() => {
|
|
7398
|
+
if (!panelOpen) return;
|
|
7399
|
+
queueMicrotask(() => {
|
|
7400
|
+
contentRef.current?.focus();
|
|
7401
|
+
});
|
|
7402
|
+
}, [panelOpen]);
|
|
7403
|
+
const openMembers = () => {
|
|
7404
|
+
setPanelOpen(true);
|
|
7405
|
+
setLoading(true);
|
|
7406
|
+
setError(void 0);
|
|
7407
|
+
loadMemberGroups().then(setGroups).catch((cause) => {
|
|
7408
|
+
setError(cause instanceof Error ? cause.message : String(cause));
|
|
7409
|
+
}).finally(() => {
|
|
7410
|
+
setLoading(false);
|
|
7411
|
+
});
|
|
7412
|
+
};
|
|
7413
|
+
const closeMembers = () => {
|
|
7414
|
+
setPanelOpen(false);
|
|
7415
|
+
queueMicrotask(() => {
|
|
7416
|
+
triggerRef.current?.focus();
|
|
7417
|
+
});
|
|
7418
|
+
};
|
|
7419
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
7420
|
+
label: t("members"),
|
|
7421
|
+
delayMs: 500,
|
|
7422
|
+
disabled: wide,
|
|
7423
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
7424
|
+
ref: triggerRef,
|
|
7425
|
+
type: "button",
|
|
7426
|
+
className: wide ? team_module_css_default.settingsAction : `${team_module_css_default.settingsAction} ${team_module_css_default.rail}`,
|
|
7427
|
+
"aria-label": t("members"),
|
|
7428
|
+
"aria-haspopup": "dialog",
|
|
7429
|
+
onClick: openMembers,
|
|
7430
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconUserOutline16, { size: wide ? 16 : 18 }), wide && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("members") })]
|
|
7431
|
+
})
|
|
7432
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
7433
|
+
open: panelOpen,
|
|
7434
|
+
onClose: closeMembers,
|
|
7435
|
+
title: t("members"),
|
|
7436
|
+
closeLabel: t("close"),
|
|
7437
|
+
contentClassName: members_module_css_default.body,
|
|
7438
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7439
|
+
ref: contentRef,
|
|
7440
|
+
className: members_module_css_default.content,
|
|
7441
|
+
tabIndex: -1,
|
|
7442
|
+
children: [
|
|
7443
|
+
loading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
7444
|
+
className: members_module_css_default.state,
|
|
7445
|
+
role: "status",
|
|
7446
|
+
children: t("loadingAgents")
|
|
7447
|
+
}),
|
|
7448
|
+
!loading && groups.length === 0 && error === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
7449
|
+
className: members_module_css_default.state,
|
|
7450
|
+
children: t("emptyAgents")
|
|
7451
|
+
}),
|
|
7452
|
+
!loading && groups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
7453
|
+
className: members_module_css_default.group,
|
|
7454
|
+
"aria-labelledby": `team-members-${group.workspaceId}`,
|
|
7455
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
7456
|
+
id: `team-members-${group.workspaceId}`,
|
|
7457
|
+
children: group.workspaceTitle
|
|
7458
|
+
}), group.members.map((status) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamMemberRow, {
|
|
7459
|
+
status,
|
|
7460
|
+
className: members_module_css_default.member,
|
|
7461
|
+
t
|
|
7462
|
+
}, status.member.memberId))]
|
|
7463
|
+
}, group.workspaceId)),
|
|
7464
|
+
error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
7465
|
+
className: members_module_css_default.error,
|
|
7466
|
+
role: "alert",
|
|
7467
|
+
children: error
|
|
7468
|
+
})
|
|
7469
|
+
]
|
|
7470
|
+
})
|
|
7471
|
+
})] });
|
|
7472
|
+
}
|
|
7473
|
+
//#endregion
|
|
7474
|
+
//#region src/client/attachment-preview.ts
|
|
7475
|
+
/** Base64 one file payload in chunks so large uploads stay off the call-stack limit. */
|
|
7476
|
+
function bytesToBase64(bytes) {
|
|
7477
|
+
let binary = "";
|
|
7478
|
+
const chunk = 32768;
|
|
7479
|
+
for (let start = 0; start < bytes.length; start += chunk) binary += String.fromCharCode(...bytes.subarray(start, start + chunk));
|
|
7480
|
+
return btoa(binary);
|
|
7481
|
+
}
|
|
7482
|
+
/**
|
|
7483
|
+
* Thumbnail data URLs live in one session-wide cache: message lists re-render
|
|
7484
|
+
* often, and each miss costs a Host round-trip plus a base64 decode. Failed
|
|
7485
|
+
* loads (bytes already GC'd) are cached as `null` so the chip fallback is stable.
|
|
7486
|
+
*/
|
|
7487
|
+
const dataUrlCache = /* @__PURE__ */ new Map();
|
|
7488
|
+
function cachedAttachmentDataUrl(attachmentId) {
|
|
7489
|
+
return dataUrlCache.get(attachmentId);
|
|
7490
|
+
}
|
|
7491
|
+
async function loadAttachmentDataUrl(getAttachment, attachment) {
|
|
7492
|
+
const cached = dataUrlCache.get(attachment.attachmentId);
|
|
7493
|
+
if (cached !== void 0) return cached;
|
|
7494
|
+
const result = await getAttachment({ attachmentId: attachment.attachmentId });
|
|
7495
|
+
const url = result.ok && attachment.mediaType.startsWith("image/") ? `data:${attachment.mediaType};base64,${result.value.bytesBase64}` : null;
|
|
7496
|
+
dataUrlCache.set(attachment.attachmentId, url);
|
|
7497
|
+
return url;
|
|
7498
|
+
}
|
|
7499
|
+
/** Human-readable byte size for attachment chips. */
|
|
7500
|
+
function formatByteSize(byteSize) {
|
|
7501
|
+
if (byteSize < 1024) return `${byteSize} B`;
|
|
7502
|
+
if (byteSize < 1024 * 1024) return `${(byteSize / 1024).toFixed(0)} KB`;
|
|
7503
|
+
return `${(byteSize / (1024 * 1024)).toFixed(1)} MB`;
|
|
7504
|
+
}
|
|
7505
|
+
//#endregion
|
|
7506
|
+
//#region src/client/requests.ts
|
|
7507
|
+
/** Fresh idempotency identity for one Client-initiated durable request. */
|
|
7508
|
+
const mintRequestId = () => crypto.randomUUID();
|
|
7509
|
+
/**
|
|
7510
|
+
* Upload composer files in order. One failure stops with the error text; the
|
|
7511
|
+
* caller keeps its chips so a retry uploads only the still-pending files.
|
|
7512
|
+
*/
|
|
7513
|
+
const uploadComposerFiles = async (putAttachment, workspaceId, files) => {
|
|
7514
|
+
const attachmentIds = [];
|
|
7515
|
+
for (const file of files) {
|
|
7516
|
+
const uploaded = await putAttachment({
|
|
7517
|
+
requestId: mintRequestId(),
|
|
7518
|
+
workspaceId,
|
|
7519
|
+
name: file.name,
|
|
7520
|
+
mediaType: file.type === "" ? void 0 : file.type,
|
|
7521
|
+
bytesBase64: bytesToBase64(new Uint8Array(await file.arrayBuffer()))
|
|
7522
|
+
});
|
|
7523
|
+
if (!uploaded.ok) return {
|
|
7524
|
+
ok: false,
|
|
7525
|
+
error: uploaded.error.message
|
|
7526
|
+
};
|
|
7527
|
+
attachmentIds.push(uploaded.value.attachmentId);
|
|
7528
|
+
}
|
|
7529
|
+
return {
|
|
7530
|
+
ok: true,
|
|
7531
|
+
attachmentIds
|
|
7532
|
+
};
|
|
7533
|
+
};
|
|
7534
|
+
//#endregion
|
|
7535
|
+
//#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/composer.module.css.mjs
|
|
7536
|
+
const css$7 = ".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_mentionAllDot{corner-shape:round;background:var(--dsw-alias-label-primary);border-radius:50%;justify-self:center;width:8px;height:8px}.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:12px;min-height:34px;padding:2px 8px 6px;display:flex;container-type:inline-size}.x9jGQq_asTaskPill{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:24px;flex:none;align-items:center;gap:4px;height:28px;padding:0 10px 0 8px;font-size:13px;font-weight:500;line-height:20px;display:inline-flex}.x9jGQq_asTaskPill:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.x9jGQq_asTaskPill:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}.x9jGQq_asTaskPill:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}.x9jGQq_asTaskPillOn,.x9jGQq_asTaskPillOn:hover:not(:disabled){background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.x9jGQq_asTaskLabel{white-space:nowrap}@container (width<=460px){.x9jGQq_asTaskPill .x9jGQq_asTaskLabel{display:none}}.x9jGQq_attachButton{background:var(--dsw-specific-selector);corner-shape:round;color:var(--dsw-alias-label-primary);cursor:pointer;border:0;border-radius:999px;flex:none;place-items:center;width:28px;height:28px;display:grid}.x9jGQq_attachButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.x9jGQq_attachButton:disabled{cursor:default;opacity:.5}.x9jGQq_attachButton:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,var(--dsw-specific-selector));outline-offset:1px}.x9jGQq_fileInput{display:none}.x9jGQq_fileChips{flex-wrap:wrap;gap:4px;margin:0;padding:4px 8px 0;list-style:none;display:flex}.x9jGQq_fileChip{background:var(--dsw-alias-interactive-bg-hover);border-radius:6px;align-items:center;gap:4px;max-width:100%;padding:2px 4px 2px 8px;display:inline-flex}.x9jGQq_fileChipSize{color:var(--dsw-alias-label-tertiary);margin-left:6px}.x9jGQq_imageChip{align-items:center;display:flex}.x9jGQq_imageChipPreview{border:1px solid var(--dsw-alias-border-l2);object-fit:cover;border-radius:4px;width:56px;height:40px}.x9jGQq_fileChipName{text-overflow:ellipsis;white-space:nowrap;max-width:220px;font-size:11px;line-height:16px;overflow:hidden}.x9jGQq_fileChipRemove{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;justify-content:center;align-items:center;width:16px;height:16px;padding:0;font-size:12px;display:inline-flex}.x9jGQq_fileChipRemove:hover,.x9jGQq_fileChipRemove:focus-visible{color:var(--dsw-alias-label-primary)}.x9jGQq_fileChipRemove:focus-visible{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.x9jGQq_sendButton{background:var(--dsw-alias-button-info-fill,var(--dsw-alias-button-primary-fill));corner-shape:round;color:#fff;cursor:pointer;border:0;border-radius:999px;justify-content:center;align-items:center;width:34px;height:34px;margin-left:auto;padding:0;transition:background-color .1s,opacity .1s;display:inline-flex;transform:translateY(-2px)}.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:default;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}}";
|
|
7537
|
+
const tagId$7 = "@wowyuarm/dsh-agent-team/composer.module.css";
|
|
7538
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$7) + "]") === null) {
|
|
7539
|
+
const tag = document.createElement("style");
|
|
7540
|
+
tag.dataset.plugin = "@wowyuarm/dsh-agent-team";
|
|
7541
|
+
tag.dataset.pluginCss = tagId$7;
|
|
7542
|
+
tag.textContent = css$7;
|
|
7543
|
+
document.head.appendChild(tag);
|
|
7544
|
+
}
|
|
7545
|
+
var composer_module_css_default = {
|
|
7546
|
+
"asTaskLabel": "x9jGQq_asTaskLabel",
|
|
7547
|
+
"asTaskPill": "x9jGQq_asTaskPill",
|
|
7548
|
+
"asTaskPillOn": "x9jGQq_asTaskPillOn",
|
|
7549
|
+
"attachButton": "x9jGQq_attachButton",
|
|
7550
|
+
"card": "x9jGQq_card",
|
|
7551
|
+
"confirmation": "x9jGQq_confirmation",
|
|
7552
|
+
"error": "x9jGQq_error",
|
|
7553
|
+
"fileChip": "x9jGQq_fileChip",
|
|
7554
|
+
"fileChipName": "x9jGQq_fileChipName",
|
|
7555
|
+
"fileChipRemove": "x9jGQq_fileChipRemove",
|
|
7556
|
+
"fileChipSize": "x9jGQq_fileChipSize",
|
|
7557
|
+
"fileChips": "x9jGQq_fileChips",
|
|
7558
|
+
"fileInput": "x9jGQq_fileInput",
|
|
7559
|
+
"imageChip": "x9jGQq_imageChip",
|
|
7560
|
+
"imageChipPreview": "x9jGQq_imageChipPreview",
|
|
7561
|
+
"inputArea": "x9jGQq_inputArea",
|
|
7562
|
+
"mentionAllDot": "x9jGQq_mentionAllDot",
|
|
7563
|
+
"mentionDescription": "x9jGQq_mentionDescription",
|
|
7564
|
+
"mentionMenu": "x9jGQq_mentionMenu",
|
|
7565
|
+
"mentionName": "x9jGQq_mentionName",
|
|
7566
|
+
"mentionOption": "x9jGQq_mentionOption",
|
|
7567
|
+
"notifyRow": "x9jGQq_notifyRow",
|
|
7568
|
+
"root": "x9jGQq_root",
|
|
7569
|
+
"sendButton": "x9jGQq_sendButton",
|
|
7570
|
+
"toolbar": "x9jGQq_toolbar"
|
|
7571
|
+
};
|
|
7572
|
+
//#endregion
|
|
7573
|
+
//#region src/client/TeamComposer.tsx
|
|
7574
|
+
function findMention(draft, caret) {
|
|
7575
|
+
const beforeCaret = draft.slice(0, caret);
|
|
7576
|
+
if (beforeCaret.length === 0 || /\s/u.test(beforeCaret.at(-1) ?? "")) return void 0;
|
|
7577
|
+
let tokenStart = beforeCaret.length;
|
|
7578
|
+
while (tokenStart > 0 && !/\s/u.test(beforeCaret[tokenStart - 1])) tokenStart -= 1;
|
|
7579
|
+
const at = beforeCaret.lastIndexOf("@");
|
|
7580
|
+
if (at < tokenStart) return void 0;
|
|
7581
|
+
if (at > 0 && /[\p{L}\p{N}_]/u.test(beforeCaret[at - 1])) return void 0;
|
|
7582
|
+
return {
|
|
7583
|
+
start: at,
|
|
7584
|
+
end: caret,
|
|
7585
|
+
query: beforeCaret.slice(at + 1)
|
|
7586
|
+
};
|
|
7587
|
+
}
|
|
7588
|
+
function mentionCandidates(members, query) {
|
|
7589
|
+
const normalized = query.toLocaleLowerCase();
|
|
7590
|
+
return members.filter((status) => status.presence !== "unavailable" && status.member.state !== "inactive" && status.member.state !== "archived" && status.member.handle.toLocaleLowerCase().startsWith(normalized));
|
|
7591
|
+
}
|
|
7592
|
+
/** Thread followers rank first: mentioning them delivers directly, while a non-follower enters the two-send invite flow. */
|
|
7593
|
+
function rankMentionCandidates(candidates, followers) {
|
|
7594
|
+
if (followers === void 0 || followers.size === 0) return candidates;
|
|
7595
|
+
return [...candidates].sort((left, right) => Number(followers.has(right.member.memberId)) - Number(followers.has(left.member.memberId)));
|
|
6904
7596
|
}
|
|
6905
7597
|
/** One object URL per draft file; revoked when the draft is removed. */
|
|
6906
7598
|
const draftPreviewUrls = /* @__PURE__ */ new WeakMap();
|
|
@@ -6913,13 +7605,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6913
7605
|
}
|
|
6914
7606
|
return url;
|
|
6915
7607
|
}
|
|
6916
|
-
function TeamComposer({ members, followerMemberIds,
|
|
7608
|
+
function TeamComposer({ members, followerMemberIds, drafts, draftKey, pending, confirmation, error, onEdit, onSubmit, placeholder, pendingFiles, onFilesChange, asTask, onAsTaskChange, t }) {
|
|
6917
7609
|
const inputRef = (0, react.useRef)(null);
|
|
6918
7610
|
const fileInputRef = (0, react.useRef)(null);
|
|
6919
7611
|
const rootRef = (0, react.useRef)(null);
|
|
6920
7612
|
const menuRef = (0, react.useRef)(null);
|
|
6921
7613
|
const activeOptionRef = (0, react.useRef)(null);
|
|
6922
7614
|
const composingRef = (0, react.useRef)(false);
|
|
7615
|
+
const { draft, recipients } = (0, react.useSyncExternalStore)(drafts.subscribe, () => drafts.getSnapshot(draftKey));
|
|
6923
7616
|
const [mention, setMention] = (0, react.useState)();
|
|
6924
7617
|
const [highlight, setHighlight] = (0, react.useState)(0);
|
|
6925
7618
|
const memberCandidates = mention === void 0 ? [] : rankMentionCandidates(mentionCandidates(members, mention.query), followerMemberIds);
|
|
@@ -6969,14 +7662,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6969
7662
|
if (confirmation === void 0 || pending) return;
|
|
6970
7663
|
inputRef.current?.focus({ preventScroll: true });
|
|
6971
7664
|
}, [confirmation, pending]);
|
|
7665
|
+
const memberHandles = new Map(members.map((status) => [status.member.memberId, status.member.handle]));
|
|
6972
7666
|
const pruneRecipients = (nextDraft) => {
|
|
6973
7667
|
if (containsAllMention(nextDraft)) return;
|
|
6974
|
-
const knownMembers = new Map(members.map((status) => [status.member.memberId, status.member]));
|
|
6975
7668
|
const next = new Set([...recipients].filter((memberId) => {
|
|
6976
|
-
const
|
|
6977
|
-
return
|
|
7669
|
+
const handle = memberHandles.get(memberId);
|
|
7670
|
+
return handle !== void 0 && containsMention(nextDraft, handle);
|
|
6978
7671
|
}));
|
|
6979
|
-
if (next.size !== recipients.size)
|
|
7672
|
+
if (next.size !== recipients.size) drafts.writeRecipients(draftKey, next);
|
|
6980
7673
|
};
|
|
6981
7674
|
(0, react.useEffect)(() => {
|
|
6982
7675
|
if (members.length === 0) return;
|
|
@@ -6986,6 +7679,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6986
7679
|
recipients,
|
|
6987
7680
|
members
|
|
6988
7681
|
]);
|
|
7682
|
+
const notifiedIds = [...new Set([...recipients, ...mentionedMemberIds(draft, members)])].sort();
|
|
6989
7683
|
const updateMention = (nextDraft, caret) => {
|
|
6990
7684
|
const match = findMention(nextDraft, caret);
|
|
6991
7685
|
setMention(match);
|
|
@@ -6993,13 +7687,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6993
7687
|
};
|
|
6994
7688
|
const onChange = (event) => {
|
|
6995
7689
|
const nextDraft = event.target.value;
|
|
6996
|
-
|
|
7690
|
+
drafts.writeDraft(draftKey, nextDraft);
|
|
7691
|
+
onEdit?.();
|
|
6997
7692
|
pruneRecipients(nextDraft);
|
|
6998
7693
|
updateMention(nextDraft, event.target.selectionStart ?? nextDraft.length);
|
|
6999
7694
|
};
|
|
7000
7695
|
const commitMention = (nextDraft, nextCaret, nextRecipients) => {
|
|
7001
|
-
|
|
7002
|
-
|
|
7696
|
+
drafts.writeDraft(draftKey, nextDraft);
|
|
7697
|
+
drafts.writeRecipients(draftKey, nextRecipients);
|
|
7698
|
+
onEdit?.();
|
|
7003
7699
|
setMention(void 0);
|
|
7004
7700
|
setHighlight(0);
|
|
7005
7701
|
requestAnimationFrame(() => {
|
|
@@ -7172,10 +7868,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7172
7868
|
}
|
|
7173
7869
|
})]
|
|
7174
7870
|
}),
|
|
7175
|
-
|
|
7871
|
+
notifiedIds.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
7176
7872
|
className: composer_module_css_default.notifyRow,
|
|
7177
7873
|
"data-team-notify": true,
|
|
7178
|
-
children: t("composerNotify", { ids:
|
|
7874
|
+
children: t("composerNotify", { ids: notifiedIds.map((memberId) => `@${memberHandles.get(memberId) ?? memberId}`).join(", ") })
|
|
7179
7875
|
}),
|
|
7180
7876
|
onFilesChange !== void 0 && pendingFiles !== void 0 && pendingFiles.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
7181
7877
|
className: composer_module_css_default.fileChips,
|
|
@@ -7213,21 +7909,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7213
7909
|
]
|
|
7214
7910
|
}, `${file.name}-${index}`);
|
|
7215
7911
|
})
|
|
7216
|
-
}),
|
|
7217
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7218
|
-
className: composer_module_css_default.toolbar,
|
|
7219
|
-
children: [
|
|
7220
|
-
onAsTaskChange !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
7221
|
-
size: "sm",
|
|
7222
|
-
variant: "outline",
|
|
7223
|
-
className: asTask === true ? composer_module_css_default.asTaskOn : void 0,
|
|
7224
|
-
"aria-pressed": asTask === true,
|
|
7225
|
-
disabled: pending,
|
|
7226
|
-
onClick: () => {
|
|
7227
|
-
onAsTaskChange(asTask !== true);
|
|
7228
|
-
},
|
|
7229
|
-
children: t("asTask")
|
|
7230
|
-
}),
|
|
7912
|
+
}),
|
|
7913
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7914
|
+
className: composer_module_css_default.toolbar,
|
|
7915
|
+
children: [
|
|
7231
7916
|
onFilesChange !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
7232
7917
|
ref: fileInputRef,
|
|
7233
7918
|
type: "file",
|
|
@@ -7240,365 +7925,158 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7240
7925
|
if (chosen.length > 0 && pendingFiles !== void 0) onFilesChange([...pendingFiles, ...chosen]);
|
|
7241
7926
|
event.target.value = "";
|
|
7242
7927
|
}
|
|
7243
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
|
|
7252
|
-
|
|
7928
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
7929
|
+
label: t("attachFiles"),
|
|
7930
|
+
side: "top",
|
|
7931
|
+
delayMs: 500,
|
|
7932
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7933
|
+
type: "button",
|
|
7934
|
+
className: composer_module_css_default.attachButton,
|
|
7935
|
+
"aria-label": t("attachFiles"),
|
|
7936
|
+
disabled: pending,
|
|
7937
|
+
onClick: () => {
|
|
7938
|
+
fileInputRef.current?.click();
|
|
7939
|
+
},
|
|
7940
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPaperclipOutline16, { size: 14 })
|
|
7941
|
+
})
|
|
7253
7942
|
})] }),
|
|
7254
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
7255
|
-
type: "
|
|
7256
|
-
className: composer_module_css_default.
|
|
7257
|
-
"aria-label":
|
|
7258
|
-
|
|
7259
|
-
|
|
7260
|
-
|
|
7261
|
-
|
|
7262
|
-
|
|
7263
|
-
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7268
|
-
|
|
7269
|
-
|
|
7270
|
-
|
|
7271
|
-
|
|
7272
|
-
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7277
|
-
|
|
7278
|
-
|
|
7279
|
-
|
|
7280
|
-
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
|
|
7288
|
-
listeners$2.add(listener);
|
|
7289
|
-
return () => {
|
|
7290
|
-
listeners$2.delete(listener);
|
|
7291
|
-
};
|
|
7292
|
-
};
|
|
7293
|
-
/** Stable snapshot token; the map is read directly after this changes. */
|
|
7294
|
-
const getSnapshot = () => version;
|
|
7295
|
-
/** React binding: re-renders the caller when any ref resolution lands. */
|
|
7296
|
-
const useResolvedTaskRefVersion = () => (0, react.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
7297
|
-
const cachedResolvedTaskRef = (taskRef) => resolved.get(taskRef);
|
|
7298
|
-
/** Store one resolution (click path) and wake every rendered link. */
|
|
7299
|
-
const rememberResolvedTaskRef = (entry) => {
|
|
7300
|
-
resolved.set(entry.taskRef, entry);
|
|
7301
|
-
pending.delete(entry.taskRef);
|
|
7302
|
-
emit();
|
|
7303
|
-
};
|
|
7304
|
-
/** Compare refs by branded prefix plus hyphen-stripped UUID, so abbreviated spellings line up with their full form. */
|
|
7305
|
-
function refKeyOf(ref) {
|
|
7306
|
-
return ref.toLowerCase().replaceAll("-", "");
|
|
7307
|
-
}
|
|
7308
|
-
/**
|
|
7309
|
-
* Click-path Host lookup: remember every resolved entry and hand them back
|
|
7310
|
-
* for immediate navigation. The Host keeps `resolved` in the same order as
|
|
7311
|
-
* the input `taskRefs` (one entry per resolvable input, unknowns omitted);
|
|
7312
|
-
* the pairing walk below relies on that contract, so it must be preserved
|
|
7313
|
-
* together with this implementation.
|
|
7314
|
-
*/
|
|
7315
|
-
const hostTaskRefLookup = (resolveTaskRefs, workspaceId) => async (taskRefs) => {
|
|
7316
|
-
const result = await resolveTaskRefs({
|
|
7317
|
-
workspaceId,
|
|
7318
|
-
taskRefs
|
|
7319
|
-
});
|
|
7320
|
-
if (!result.ok) return [];
|
|
7321
|
-
const entries = result.value.resolved;
|
|
7322
|
-
let entryIndex = 0;
|
|
7323
|
-
for (const requested of taskRefs) {
|
|
7324
|
-
const entry = entries[entryIndex];
|
|
7325
|
-
if (entry === void 0 || !refKeyOf(entry.taskRef).startsWith(refKeyOf(requested))) continue;
|
|
7326
|
-
if (entry.taskRef !== requested) rememberResolvedTaskRef({
|
|
7327
|
-
...entry,
|
|
7328
|
-
taskRef: requested
|
|
7329
|
-
});
|
|
7330
|
-
rememberResolvedTaskRef(entry);
|
|
7331
|
-
entryIndex += 1;
|
|
7332
|
-
}
|
|
7333
|
-
return entries;
|
|
7334
|
-
};
|
|
7335
|
-
/** Resolve one Task ref through the Host and jump to its home Channel Thread. */
|
|
7336
|
-
const jumpToTaskThread = (resolveTaskRefs, workspaceId, taskRef, selectThread) => {
|
|
7337
|
-
resolveTaskRefs({
|
|
7338
|
-
workspaceId,
|
|
7339
|
-
taskRefs: [taskRef]
|
|
7340
|
-
}).then((result) => {
|
|
7341
|
-
if (!result.ok) return;
|
|
7342
|
-
const hit = result.value.resolved[0];
|
|
7343
|
-
if (hit !== void 0) selectThread(hit.threadRef, hit.channelRef, hit.taskRef, hit.taskNumber);
|
|
7344
|
-
});
|
|
7345
|
-
};
|
|
7346
|
-
/**
|
|
7347
|
-
* Batch-resolve unknown refs through the Host lookup. Concurrent callers
|
|
7348
|
-
* deduplicate through the pending set; failures just clear the pending mark
|
|
7349
|
-
* so a later interaction can retry.
|
|
7350
|
-
*/
|
|
7351
|
-
const resolveUnknownTaskRefs = async (refs, lookup) => {
|
|
7352
|
-
const missing = refs.filter((taskRef) => !resolved.has(taskRef) && !pending.has(taskRef) && !unresolvable.has(taskRef));
|
|
7353
|
-
if (missing.length === 0) return;
|
|
7354
|
-
for (const taskRef of missing) pending.add(taskRef);
|
|
7355
|
-
try {
|
|
7356
|
-
const entries = await lookup(missing);
|
|
7357
|
-
for (const entry of entries) {
|
|
7358
|
-
resolved.set(entry.taskRef, entry);
|
|
7359
|
-
pending.delete(entry.taskRef);
|
|
7360
|
-
}
|
|
7361
|
-
for (const taskRef of missing) if (!resolved.has(taskRef)) unresolvable.add(taskRef);
|
|
7362
|
-
if (entries.length > 0) emit();
|
|
7363
|
-
} finally {
|
|
7364
|
-
for (const taskRef of missing) pending.delete(taskRef);
|
|
7365
|
-
}
|
|
7366
|
-
};
|
|
7367
|
-
//#endregion
|
|
7368
|
-
//#region src/client/team-formatters.ts
|
|
7369
|
-
function formatTaskStatus(status, t) {
|
|
7370
|
-
return t({
|
|
7371
|
-
todo: "taskStatusTodo",
|
|
7372
|
-
in_progress: "taskStatusInProgress",
|
|
7373
|
-
in_review: "taskStatusInReview",
|
|
7374
|
-
done: "taskStatusDone",
|
|
7375
|
-
closed: "taskStatusClosed"
|
|
7376
|
-
}[status]);
|
|
7377
|
-
}
|
|
7378
|
-
function formatClaimState(state, t) {
|
|
7379
|
-
return t({
|
|
7380
|
-
active: "claimStateActive",
|
|
7381
|
-
done: "claimStateDone",
|
|
7382
|
-
released: "claimStateReleased"
|
|
7383
|
-
}[state]);
|
|
7384
|
-
}
|
|
7385
|
-
/**
|
|
7386
|
-
* Status indicator for a Task status, the dot every Task surface renders.
|
|
7387
|
-
* Active states map to StateDot variants; every status renders a dot so they
|
|
7388
|
-
* share one shape language — todo is a hollow ring (not started), closed a
|
|
7389
|
-
* quiet gray dot (archived).
|
|
7390
|
-
*/
|
|
7391
|
-
function taskStatusDot(status) {
|
|
7392
|
-
return {
|
|
7393
|
-
todo: "todo",
|
|
7394
|
-
in_progress: "ongoing",
|
|
7395
|
-
in_review: "warning",
|
|
7396
|
-
done: "done",
|
|
7397
|
-
closed: "quiet"
|
|
7398
|
-
}[status];
|
|
7399
|
-
}
|
|
7400
|
-
/** One-line title snippet derived from the Task's root Message body. */
|
|
7401
|
-
function formatTaskTitle(body) {
|
|
7402
|
-
const firstLine = body.split("\n", 1)[0]?.trim() ?? "";
|
|
7403
|
-
return firstLine.length > 120 ? `${firstLine.slice(0, 119)}…` : firstLine;
|
|
7404
|
-
}
|
|
7405
|
-
/** Deterministic avatar hue for one Member identity; stable across sessions and themes. */
|
|
7406
|
-
function memberHue(memberId) {
|
|
7407
|
-
let hash = 0;
|
|
7408
|
-
for (let index = 0; index < memberId.length; index += 1) hash = (hash * 31 + memberId.charCodeAt(index)) % 360;
|
|
7409
|
-
return hash;
|
|
7410
|
-
}
|
|
7411
|
-
const BRANDED_REF_PATTERN = /\b(task|channel|thread):{1,2}[0-9a-f]{6,}(?:-[0-9a-f]{1,})*\b/gi;
|
|
7412
|
-
/**
|
|
7413
|
-
* Canonical form of one matched ref: models occasionally double the colon or
|
|
7414
|
-
* uppercase the UUID when citing a ref in prose, while Host lookups and
|
|
7415
|
-
* navigation only accept the lowercase single-colon ref the ledger mints.
|
|
7416
|
-
*/
|
|
7417
|
-
function canonicalBrandedRef(match) {
|
|
7418
|
-
return match.replace("::", ":").toLowerCase();
|
|
7419
|
-
}
|
|
7420
|
-
/**
|
|
7421
|
-
* Split a literal text run into plain and branded-ref segments. The pattern
|
|
7422
|
-
* anchors on the fixed ref prefixes plus a UUID shape (full or abbreviated),
|
|
7423
|
-
* so ordinary prose containing a colon never linkifies; a doubled colon from
|
|
7424
|
-
* model output is tolerated. Segment refs are always canonical, so resolution
|
|
7425
|
-
* and navigation work regardless of how the ref was spelled; text without any
|
|
7426
|
-
* ref comes back as one untouched segment.
|
|
7427
|
-
*/
|
|
7428
|
-
function splitBrandedRefs(text) {
|
|
7429
|
-
const segments = [];
|
|
7430
|
-
let cursor = 0;
|
|
7431
|
-
for (const match of text.matchAll(BRANDED_REF_PATTERN)) {
|
|
7432
|
-
const start = match.index ?? 0;
|
|
7433
|
-
if (start > cursor) segments.push({ text: text.slice(cursor, start) });
|
|
7434
|
-
segments.push({
|
|
7435
|
-
text: match[0],
|
|
7436
|
-
ref: canonicalBrandedRef(match[0])
|
|
7437
|
-
});
|
|
7438
|
-
cursor = start + match[0].length;
|
|
7439
|
-
}
|
|
7440
|
-
if (cursor < text.length) segments.push({ text: text.slice(cursor) });
|
|
7441
|
-
return segments;
|
|
7442
|
-
}
|
|
7443
|
-
/**
|
|
7444
|
-
* Whether one string's whole content is exactly one branded ref. A code span
|
|
7445
|
-
* like this is the model styling a ref as an identifier, not publishing code,
|
|
7446
|
-
* so the Markdown pass may linkify it; anything larger stays literal.
|
|
7447
|
-
*/
|
|
7448
|
-
function isSingleBrandedRef(text) {
|
|
7449
|
-
const trimmed = text.trim();
|
|
7450
|
-
if (trimmed === "") return false;
|
|
7451
|
-
const matches = [...trimmed.matchAll(BRANDED_REF_PATTERN)];
|
|
7452
|
-
return matches.length === 1 && matches[0][0] === trimmed;
|
|
7453
|
-
}
|
|
7454
|
-
function escapeRegExp(value) {
|
|
7455
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7456
|
-
}
|
|
7457
|
-
/**
|
|
7458
|
-
* Locate one Message's structured mention names inside its literal body. A
|
|
7459
|
-
* name matches case-insensitively with an optional leading '@' on Unicode word
|
|
7460
|
-
* boundaries, and longer names win at the same position. Mention segments
|
|
7461
|
-
* render the canonical `@Handle`; names absent from the body come back
|
|
7462
|
-
* unmatched so the consumer can append them as a fallback chip row.
|
|
7463
|
-
*/
|
|
7464
|
-
function splitMentionNames(text, names) {
|
|
7465
|
-
if (names.length === 0) return {
|
|
7466
|
-
segments: [{
|
|
7467
|
-
text,
|
|
7468
|
-
mention: false
|
|
7469
|
-
}],
|
|
7470
|
-
unmatched: []
|
|
7471
|
-
};
|
|
7472
|
-
const ordered = [...names].sort((left, right) => right.length - left.length);
|
|
7473
|
-
const pattern = new RegExp(`(?<![\\p{L}\\p{N}_@])@?(?:${ordered.map((name) => `(${escapeRegExp(name)})`).join("|")})(?=$|[^\\p{L}\\p{N}_])`, "giu");
|
|
7474
|
-
const segments = [];
|
|
7475
|
-
const matched = /* @__PURE__ */ new Set();
|
|
7476
|
-
let cursor = 0;
|
|
7477
|
-
for (const match of text.matchAll(pattern)) {
|
|
7478
|
-
const groupIndex = match.findIndex((group, index) => index >= 1 && group !== void 0);
|
|
7479
|
-
if (groupIndex < 1) continue;
|
|
7480
|
-
if (match.index > cursor) segments.push({
|
|
7481
|
-
text: text.slice(cursor, match.index),
|
|
7482
|
-
mention: false
|
|
7483
|
-
});
|
|
7484
|
-
const name = ordered[groupIndex - 1];
|
|
7485
|
-
segments.push({
|
|
7486
|
-
text: `@${name}`,
|
|
7487
|
-
mention: true,
|
|
7488
|
-
name
|
|
7489
|
-
});
|
|
7490
|
-
matched.add(name.toLowerCase());
|
|
7491
|
-
cursor = match.index + match[0].length;
|
|
7492
|
-
}
|
|
7493
|
-
if (cursor < text.length) segments.push({
|
|
7494
|
-
text: text.slice(cursor),
|
|
7495
|
-
mention: false
|
|
7943
|
+
onAsTaskChange !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
7944
|
+
type: "button",
|
|
7945
|
+
className: asTask === true ? `${composer_module_css_default.asTaskPill} ${composer_module_css_default.asTaskPillOn}` : composer_module_css_default.asTaskPill,
|
|
7946
|
+
"aria-label": t("asTask"),
|
|
7947
|
+
"aria-pressed": asTask === true,
|
|
7948
|
+
title: t("asTask"),
|
|
7949
|
+
disabled: pending,
|
|
7950
|
+
onClick: () => {
|
|
7951
|
+
onAsTaskChange(asTask !== true);
|
|
7952
|
+
},
|
|
7953
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChecklistOutline14, { size: 14 }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7954
|
+
className: composer_module_css_default.asTaskLabel,
|
|
7955
|
+
children: t("asTask")
|
|
7956
|
+
})]
|
|
7957
|
+
}),
|
|
7958
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7959
|
+
type: "submit",
|
|
7960
|
+
className: composer_module_css_default.sendButton,
|
|
7961
|
+
"aria-label": pending ? t("sendingMessage") : t("sendMessage"),
|
|
7962
|
+
disabled: pending || draft.trim() === "",
|
|
7963
|
+
onMouseDown: (event) => {
|
|
7964
|
+
event.preventDefault();
|
|
7965
|
+
inputRef.current?.focus({ preventScroll: true });
|
|
7966
|
+
},
|
|
7967
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSendOutline16, { size: 16 })
|
|
7968
|
+
})
|
|
7969
|
+
]
|
|
7970
|
+
})
|
|
7971
|
+
]
|
|
7972
|
+
}), error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
7973
|
+
className: composer_module_css_default.error,
|
|
7974
|
+
role: "alert",
|
|
7975
|
+
children: error
|
|
7976
|
+
})]
|
|
7496
7977
|
});
|
|
7497
|
-
return {
|
|
7498
|
-
segments,
|
|
7499
|
-
unmatched: names.filter((name) => !matched.has(name.toLowerCase()))
|
|
7500
|
-
};
|
|
7501
|
-
}
|
|
7502
|
-
/** Canonical chip handles for one Message's structured mention refs. */
|
|
7503
|
-
function mentionNamesOf(mentions, handles) {
|
|
7504
|
-
return mentions.map((memberId) => memberId === "member:human" ? "human" : handles.get(memberId)).filter((name) => name !== void 0);
|
|
7505
7978
|
}
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
|
|
7512
|
-
|
|
7513
|
-
|
|
7514
|
-
|
|
7515
|
-
|
|
7516
|
-
|
|
7979
|
+
//#endregion
|
|
7980
|
+
//#region src/client/task-refs.ts
|
|
7981
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
7982
|
+
const pending = /* @__PURE__ */ new Set();
|
|
7983
|
+
/** Refs the Host did not recognize; never re-queried (no retry loops). */
|
|
7984
|
+
const unresolvable = /* @__PURE__ */ new Set();
|
|
7985
|
+
const listeners$2 = /* @__PURE__ */ new Set();
|
|
7986
|
+
let version = 0;
|
|
7987
|
+
const emit = () => {
|
|
7988
|
+
version += 1;
|
|
7989
|
+
for (const listener of listeners$2) listener();
|
|
7990
|
+
};
|
|
7991
|
+
const subscribe = (listener) => {
|
|
7992
|
+
listeners$2.add(listener);
|
|
7993
|
+
return () => {
|
|
7994
|
+
listeners$2.delete(listener);
|
|
7995
|
+
};
|
|
7996
|
+
};
|
|
7997
|
+
/** Stable snapshot token; the map is read directly after this changes. */
|
|
7998
|
+
const getSnapshot = () => version;
|
|
7999
|
+
/** React binding: re-renders the caller when any ref resolution lands. */
|
|
8000
|
+
const useResolvedTaskRefVersion = () => (0, react.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
8001
|
+
const cachedResolvedTaskRef = (taskRef) => resolved.get(taskRef);
|
|
8002
|
+
/** Store one resolution (click path) and wake every rendered link. */
|
|
8003
|
+
const rememberResolvedTaskRef = (entry) => {
|
|
8004
|
+
resolved.set(entry.taskRef, entry);
|
|
8005
|
+
pending.delete(entry.taskRef);
|
|
8006
|
+
emit();
|
|
8007
|
+
};
|
|
8008
|
+
/** Compare refs by branded prefix plus hyphen-stripped UUID, so abbreviated spellings line up with their full form. */
|
|
8009
|
+
function refKeyOf(ref) {
|
|
8010
|
+
return ref.toLowerCase().replaceAll("-", "");
|
|
7517
8011
|
}
|
|
7518
|
-
const pad$1 = (value) => String(value).padStart(2, "0");
|
|
7519
8012
|
/**
|
|
7520
|
-
*
|
|
7521
|
-
*
|
|
8013
|
+
* Click-path Host lookup: remember every resolved entry and hand them back
|
|
8014
|
+
* for immediate navigation. The Host keeps `resolved` in the same order as
|
|
8015
|
+
* the input `taskRefs` (one entry per resolvable input, unknowns omitted);
|
|
8016
|
+
* the pairing walk below relies on that contract, so it must be preserved
|
|
8017
|
+
* together with this implementation.
|
|
7522
8018
|
*/
|
|
7523
|
-
|
|
7524
|
-
const
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
if (at.getFullYear() === now.getFullYear() && at.getMonth() === now.getMonth() && at.getDate() === now.getDate()) return time;
|
|
7528
|
-
const date = `${at.getFullYear()}-${pad$1(at.getMonth() + 1)}-${pad$1(at.getDate())}`;
|
|
7529
|
-
if (at.getFullYear() === now.getFullYear()) return `${date.slice(5)} ${time}`;
|
|
7530
|
-
return `${date} ${time}`;
|
|
7531
|
-
}
|
|
7532
|
-
function formatActivity(activity, options) {
|
|
7533
|
-
const actor = options.actorName(activity.actor);
|
|
7534
|
-
if (activity.kind === "accept") return activity.completedClaimRefs !== void 0 && activity.completedClaimRefs.length > 0 ? options.t("activityAcceptedWithClaims", {
|
|
7535
|
-
actor,
|
|
7536
|
-
count: activity.completedClaimRefs.length
|
|
7537
|
-
}) : options.t("activityAccepted", { actor });
|
|
7538
|
-
if (activity.kind === "promote") return options.t("activityPromoted", { actor });
|
|
7539
|
-
if (activity.kind === "close") return options.t("activityClosed", { actor });
|
|
7540
|
-
if (activity.kind === "reopen") return options.t("activityReopened", { actor });
|
|
7541
|
-
const direction = "claimRef" in activity ? options.claims.find((claim) => claim.claimRef === activity.claimRef)?.direction ?? options.t("claims") : options.t("claims");
|
|
7542
|
-
if (activity.kind === "claim") return options.t("activityClaimed", {
|
|
7543
|
-
actor,
|
|
7544
|
-
direction
|
|
7545
|
-
});
|
|
7546
|
-
if (activity.kind === "done") return options.t("activityClaimDone", {
|
|
7547
|
-
actor,
|
|
7548
|
-
direction
|
|
7549
|
-
});
|
|
7550
|
-
if (activity.kind === "release") return options.t("activityClaimReleased", {
|
|
7551
|
-
actor,
|
|
7552
|
-
direction
|
|
8019
|
+
const hostTaskRefLookup = (resolveTaskRefs, workspaceId) => async (taskRefs) => {
|
|
8020
|
+
const result = await resolveTaskRefs({
|
|
8021
|
+
workspaceId,
|
|
8022
|
+
taskRefs
|
|
7553
8023
|
});
|
|
7554
|
-
if (
|
|
7555
|
-
|
|
7556
|
-
|
|
8024
|
+
if (!result.ok) return [];
|
|
8025
|
+
const entries = result.value.resolved;
|
|
8026
|
+
let entryIndex = 0;
|
|
8027
|
+
for (const requested of taskRefs) {
|
|
8028
|
+
const entry = entries[entryIndex];
|
|
8029
|
+
if (entry === void 0 || !refKeyOf(entry.taskRef).startsWith(refKeyOf(requested))) continue;
|
|
8030
|
+
if (entry.taskRef !== requested) rememberResolvedTaskRef({
|
|
8031
|
+
...entry,
|
|
8032
|
+
taskRef: requested
|
|
8033
|
+
});
|
|
8034
|
+
rememberResolvedTaskRef(entry);
|
|
8035
|
+
entryIndex += 1;
|
|
8036
|
+
}
|
|
8037
|
+
return entries;
|
|
8038
|
+
};
|
|
8039
|
+
/** Resolve one Task ref through the Host and jump to its home Channel Thread. */
|
|
8040
|
+
const jumpToTaskThread = (resolveTaskRefs, workspaceId, taskRef, selectThread) => {
|
|
8041
|
+
resolveTaskRefs({
|
|
8042
|
+
workspaceId,
|
|
8043
|
+
taskRefs: [taskRef]
|
|
8044
|
+
}).then((result) => {
|
|
8045
|
+
if (!result.ok) return;
|
|
8046
|
+
const hit = result.value.resolved[0];
|
|
8047
|
+
if (hit !== void 0) selectThread(hit.threadRef, hit.channelRef, hit.taskRef, hit.taskNumber);
|
|
7557
8048
|
});
|
|
7558
|
-
|
|
7559
|
-
}
|
|
7560
|
-
/** Remove the machine-facing `[attachment] <path>` prompt lines from a body before display. */
|
|
7561
|
-
function stripAttachmentLines(body) {
|
|
7562
|
-
return body.replaceAll(/^\[attachment\] .*$(\n)?/gm, "").replace(/\n+$/, "");
|
|
7563
|
-
}
|
|
7564
|
-
/** Whether one displayed Message body starts clamped behind the expand control. */
|
|
7565
|
-
function shouldClampMessage(displayBody) {
|
|
7566
|
-
return displayBody.length > 600;
|
|
7567
|
-
}
|
|
8049
|
+
};
|
|
7568
8050
|
/**
|
|
7569
|
-
*
|
|
7570
|
-
*
|
|
7571
|
-
*
|
|
7572
|
-
* trailing fallback row while the post-render pass handles Task refs at their
|
|
7573
|
-
* authored position. Surfaces without ref navigation render everything
|
|
7574
|
-
* literally and keep the full fallback row.
|
|
8051
|
+
* Batch-resolve unknown refs through the Host lookup. Concurrent callers
|
|
8052
|
+
* deduplicate through the pending set; failures just clear the pending mark
|
|
8053
|
+
* so a later interaction can retry.
|
|
7575
8054
|
*/
|
|
7576
|
-
|
|
7577
|
-
const
|
|
7578
|
-
|
|
7579
|
-
const
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
7583
|
-
|
|
7584
|
-
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
}
|
|
8055
|
+
const resolveUnknownTaskRefs = async (refs, lookup) => {
|
|
8056
|
+
const missing = refs.filter((taskRef) => !resolved.has(taskRef) && !pending.has(taskRef) && !unresolvable.has(taskRef));
|
|
8057
|
+
if (missing.length === 0) return;
|
|
8058
|
+
for (const taskRef of missing) pending.add(taskRef);
|
|
8059
|
+
try {
|
|
8060
|
+
const entries = await lookup(missing);
|
|
8061
|
+
for (const entry of entries) {
|
|
8062
|
+
resolved.set(entry.taskRef, entry);
|
|
8063
|
+
pending.delete(entry.taskRef);
|
|
8064
|
+
}
|
|
8065
|
+
for (const taskRef of missing) if (!resolved.has(taskRef)) unresolvable.add(taskRef);
|
|
8066
|
+
if (entries.length > 0) emit();
|
|
8067
|
+
} finally {
|
|
8068
|
+
for (const taskRef of missing) pending.delete(taskRef);
|
|
8069
|
+
}
|
|
8070
|
+
};
|
|
7593
8071
|
//#endregion
|
|
7594
8072
|
//#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/conversation.module.css.mjs
|
|
7595
|
-
const css$
|
|
7596
|
-
const tagId$
|
|
7597
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$
|
|
8073
|
+
const css$6 = ".omcBaG_surface{grid-template-rows:auto minmax(0,1fr) auto;min-width:0;height:100%;min-height:0;display:grid;overflow:hidden}.omcBaG_surfaceHeader{border-bottom:1px solid var(--dsw-alias-border-l2);min-width:0;padding:14px clamp(18px,3vw,36px) 12px}.omcBaG_headerRow{justify-content:space-between;align-items:flex-start;gap:16px;min-width:0;max-width:880px;margin:0 auto;display:flex}.omcBaG_headerCopy{min-width:0}.omcBaG_headerCopy h1{color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;margin:0;font-size:20px;font-weight:600;line-height:28px}.omcBaG_headerCopy p{color:var(--dsw-alias-label-secondary);margin:3px 0 0;font-size:13px;line-height:20px}.omcBaG_headerActions{flex:none;align-items:center;gap:6px;display:flex}.omcBaG_backRow{max-width:880px;margin:0 auto 8px}.omcBaG_timeline{overscroll-behavior:contain;scrollbar-gutter:stable;min-height:0;padding:12px clamp(18px,3vw,36px) 24px;overflow:hidden auto}.omcBaG_timelineContent{flex-direction:column;min-width:0;max-width:880px;min-height:100%;margin:0 auto;display:flex}.omcBaG_emptySurface{margin:auto;padding:32px 0}.omcBaG_emptySurface .omcBaG_emptyState{text-align:center;justify-items:center}.omcBaG_timelineAction{justify-content:center;padding:2px 0 8px;display:flex}.omcBaG_messageRow{gap:10px;padding:10px 0;display:flex}.omcBaG_messageRow[data-grouped]{padding-top:2px}.omcBaG_messageRow[data-grouped] .omcBaG_messageBody>:first-child,.omcBaG_messageRow[data-grouped] .omcBaG_messageBody>:first-child>:first-child{margin-top:0}.omcBaG_messageIdentity{background:hsl(var(--team-avatar-hue,212) 42% 46%);corner-shape:round;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_stateCluster{flex:none;align-items:center;gap:6px;display:inline-flex}.omcBaG_statusWord{color:var(--dsw-alias-label-secondary);font-size:11px;line-height:18px}.omcBaG_entryLine{flex-wrap:wrap;align-items:center;gap:8px;max-width:100%;margin:4px 0 0;display:flex}.omcBaG_entryRow{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;align-items:center;gap:6px;padding:2px 0;font-size:12px;line-height:18px;display:inline-flex}.omcBaG_entryRow:hover,.omcBaG_entryRow:focus-visible{color:var(--dsw-alias-label-primary)}.omcBaG_entryRow:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.omcBaG_entryArrow{align-items:center;transition:transform .12s;display:inline-flex}.omcBaG_entryRow:hover .omcBaG_entryArrow,.omcBaG_entryRow:focus-visible .omcBaG_entryArrow{transform:translate(2px)}.omcBaG_messageText{white-space:pre-wrap;word-break:break-word;margin:6px 0;font-size:14px;line-height:22px}.omcBaG_messageClamp{max-height:176px;overflow:hidden;-webkit-mask-image:linear-gradient(#000 72%,#0000 100%);mask-image:linear-gradient(#000 72%,#0000 100%)}.omcBaG_messageExpand{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;width:fit-content;margin-top:4px;padding:0;font-size:12px;line-height:20px;display:block}.omcBaG_messageExpand:hover,.omcBaG_messageExpand:focus-visible{color:var(--dsw-alias-label-primary);text-underline-offset:2px;outline:none;text-decoration:underline}.omcBaG_messageBody .omcBaG_messageMarkdown{font-size:14px;line-height:22px}.omcBaG_messageBody .omcBaG_messageMarkdown>div:first-child{color:var(--dsw-alias-label-primary);font:inherit}.omcBaG_messageBody .omcBaG_messageMarkdown p{margin:6px 0}.omcBaG_messageBody .omcBaG_messageMarkdown :where(ul,ol){margin:6px 0;padding-left:22px}.omcBaG_messageBody .omcBaG_messageMarkdown li+li{margin-top:2px}.omcBaG_messageBody .omcBaG_messageMarkdown strong{font-weight:600}.omcBaG_messageBody .omcBaG_messageMarkdown :where(h1,h2,h3,h4,h5,h6){margin:12px 0 4px}.omcBaG_messageBody .omcBaG_messageMarkdown :where(h1){font-size:17px;line-height:26px}.omcBaG_messageBody .omcBaG_messageMarkdown :where(h2){font-size:16px;line-height:24px}.omcBaG_messageBody .omcBaG_messageMarkdown :where(h3,h4,h5,h6){font-size:15px;line-height:22px}.omcBaG_messageBody .omcBaG_messageMarkdown pre{margin:8px 0;padding:10px 12px;font-size:13px}.omcBaG_messageBody .omcBaG_messageMarkdown blockquote{margin:6px 0}.omcBaG_messageBody .omcBaG_messageMarkdown :where(th,td){padding-block:5px}.omcBaG_emptyState,.omcBaG_loadingState{color:var(--dsw-alias-label-tertiary);margin:0;padding:14px 0;font-size:13px;line-height:20px}.omcBaG_emptyState{gap:3px;display:grid}.omcBaG_emptyState strong{color:var(--dsw-alias-label-secondary);font-weight:500}.omcBaG_emptyState span{font-size:12px}.omcBaG_loadingState{align-items:center;gap:8px;display:flex}.omcBaG_loadingMark{background:var(--dsw-alias-bg-skeleton);corner-shape:round;border-radius:50%;width:8px;height:8px;animation:1.2s ease-in-out infinite omcBaG_pulse}.omcBaG_error{color:var(--dsw-alias-state-error-primary);max-width:880px;margin:0;padding-top:6px;font-size:12px;line-height:18px}.omcBaG_errorState{color:var(--dsw-alias-state-error-primary);justify-content:space-between;align-items:center;gap:8px;max-width:880px;margin:auto;padding:32px 0;font-size:12px;line-height:18px;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_entryArrow{transition:none}.omcBaG_entryRow:hover .omcBaG_entryArrow,.omcBaG_entryRow:focus-visible .omcBaG_entryArrow{transform:none}}.omcBaG_messageRun{margin:2px 0;padding:3px 0}.omcBaG_messageRow[data-grouped]:has([data-thread-entry]){margin-top:3px;padding-top:7px;position:relative}.omcBaG_messageRow[data-grouped]:has([data-thread-entry]):before{background:var(--dsw-alias-border-l2);content:\"\";height:1px;position:absolute;inset:0 0 auto 38px}.omcBaG_runDivider{border-top:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);margin:2px 0 0 38px;padding:5px 0 0;font-size:11px;line-height:16px}.omcBaG_runDivider+.omcBaG_messageRow[data-grouped]:has([data-thread-entry]){margin-top:0}.omcBaG_runDivider+.omcBaG_messageRow[data-grouped]:has([data-thread-entry]):before{content:none}.omcBaG_mention{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 12%, transparent);color:var(--dsw-alias-state-business-primary);border-radius:6px;padding:0 4px;font-weight:500;box-shadow:0 1px 2px #00000014}.omcBaG_mentionsRow{gap:4px;width:fit-content;margin-top:3px;font-size:.85em;display:flex}.omcBaG_attachmentStrip{flex-wrap:wrap;gap:6px;margin-top:4px;display:flex}.omcBaG_attachmentThumb{cursor:zoom-in;border:0;border-radius:8px;padding:0}.omcBaG_attachmentThumb img{object-fit:cover;border-radius:8px;width:128px;height:96px;display:block}.omcBaG_attachmentThumb:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,currentColor);outline-offset:1px}.omcBaG_confirmBody{margin:0 0 8px}.omcBaG_confirmList{gap:6px;margin:0;padding-left:18px;display:grid}.omcBaG_refLink{color:var(--dsw-alias-state-business-primary);cursor:pointer;font:inherit;text-align:left;text-underline-offset:3px;background:0 0;border:none;border-radius:4px;padding:0;text-decoration:underline}.omcBaG_refLink:hover{text-decoration-thickness:2px}.omcBaG_refLink:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}.omcBaG_attachmentModal{width:min(1100px,92vw)}.omcBaG_attachmentZoom{object-fit:contain;border-radius:12px;max-width:100%;max-height:78vh;margin:0 auto;display:block}.omcBaG_attachmentChip{background:var(--dsw-alias-interactive-bg-hover);border-radius:6px;align-items:baseline;gap:6px;max-width:100%;padding:3px 8px;display:inline-flex}.omcBaG_attachmentChipName{text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:17px;overflow:hidden}.omcBaG_attachmentChipSize{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:11px;line-height:17px}";
|
|
8074
|
+
const tagId$6 = "@wowyuarm/dsh-agent-team/conversation.module.css";
|
|
8075
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$6) + "]") === null) {
|
|
7598
8076
|
const tag = document.createElement("style");
|
|
7599
8077
|
tag.dataset.plugin = "@wowyuarm/dsh-agent-team";
|
|
7600
|
-
tag.dataset.pluginCss = tagId$
|
|
7601
|
-
tag.textContent = css$
|
|
8078
|
+
tag.dataset.pluginCss = tagId$6;
|
|
8079
|
+
tag.textContent = css$6;
|
|
7602
8080
|
document.head.appendChild(tag);
|
|
7603
8081
|
}
|
|
7604
8082
|
var conversation_module_css_default = {
|
|
@@ -7614,6 +8092,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7614
8092
|
"confirmList": "omcBaG_confirmList",
|
|
7615
8093
|
"emptyState": "omcBaG_emptyState",
|
|
7616
8094
|
"emptySurface": "omcBaG_emptySurface",
|
|
8095
|
+
"entryArrow": "omcBaG_entryArrow",
|
|
8096
|
+
"entryLine": "omcBaG_entryLine",
|
|
8097
|
+
"entryRow": "omcBaG_entryRow",
|
|
7617
8098
|
"error": "omcBaG_error",
|
|
7618
8099
|
"errorState": "omcBaG_errorState",
|
|
7619
8100
|
"headerActions": "omcBaG_headerActions",
|
|
@@ -7636,6 +8117,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7636
8117
|
"pulse": "omcBaG_pulse",
|
|
7637
8118
|
"refLink": "omcBaG_refLink",
|
|
7638
8119
|
"runDivider": "omcBaG_runDivider",
|
|
8120
|
+
"stateCluster": "omcBaG_stateCluster",
|
|
8121
|
+
"statusWord": "omcBaG_statusWord",
|
|
7639
8122
|
"surface": "omcBaG_surface",
|
|
7640
8123
|
"surfaceHeader": "omcBaG_surfaceHeader",
|
|
7641
8124
|
"timeline": "omcBaG_timeline",
|
|
@@ -7647,8 +8130,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7647
8130
|
};
|
|
7648
8131
|
//#endregion
|
|
7649
8132
|
//#region src/client/TeamMessage.tsx
|
|
7650
|
-
/**
|
|
7651
|
-
|
|
8133
|
+
/**
|
|
8134
|
+
* One chat message row with identity chrome and sender-appropriate rendering.
|
|
8135
|
+
*
|
|
8136
|
+
* Memoized because a timeline row is rendered by the page that owns the whole
|
|
8137
|
+
* Thread: the Task-ref subscription below lives inside this component, so
|
|
8138
|
+
* skipping a render here never detaches it. Callers must therefore keep the
|
|
8139
|
+
* props they derive per render (mention names, ref callbacks) identity-stable.
|
|
8140
|
+
*/
|
|
8141
|
+
const TeamMessage = (0, react.memo)(function TeamMessage({ senderName, memberId, human, body, occurredAt, mentionNames, senderTitle, grouped, showGroupedTime, attachments, loadAttachment, t, onOpenRef, onResolveTaskRefs, children }) {
|
|
7652
8142
|
const avatarStyle = human ? void 0 : { "--team-avatar-hue": memberHue(memberId) };
|
|
7653
8143
|
const plan = planMessageBody(body, {
|
|
7654
8144
|
human,
|
|
@@ -7801,7 +8291,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7801
8291
|
]
|
|
7802
8292
|
})]
|
|
7803
8293
|
});
|
|
7804
|
-
}
|
|
8294
|
+
});
|
|
7805
8295
|
/** Text nodes that Markdown rendered as prose rather than code or a link. */
|
|
7806
8296
|
function markdownProseTextNodes(root) {
|
|
7807
8297
|
const nodes = [];
|
|
@@ -7984,6 +8474,101 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7984
8474
|
});
|
|
7985
8475
|
}
|
|
7986
8476
|
//#endregion
|
|
8477
|
+
//#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/avatar-stack.module.css.mjs
|
|
8478
|
+
const css$5 = ".aACNsW_stack{flex:none;align-items:center;display:inline-flex}.aACNsW_avatar,.aACNsW_overflow{box-shadow:0 0 0 2px var(--team-mark-ring,var(--dsw-alias-bg-base));corner-shape:round;border-radius:50%;justify-content:center;align-items:center;width:18px;height:18px;font-size:9px;font-weight:600;display:inline-flex}.aACNsW_avatar{background:hsl(var(--team-avatar-hue,212) 42% 46%);color:#fff}.aACNsW_overflow{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary)}.aACNsW_avatar+.aACNsW_avatar,.aACNsW_avatar+.aACNsW_overflow{margin-left:-6px}";
|
|
8479
|
+
const tagId$5 = "@wowyuarm/dsh-agent-team/avatar-stack.module.css";
|
|
8480
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$5) + "]") === null) {
|
|
8481
|
+
const tag = document.createElement("style");
|
|
8482
|
+
tag.dataset.plugin = "@wowyuarm/dsh-agent-team";
|
|
8483
|
+
tag.dataset.pluginCss = tagId$5;
|
|
8484
|
+
tag.textContent = css$5;
|
|
8485
|
+
document.head.appendChild(tag);
|
|
8486
|
+
}
|
|
8487
|
+
var avatar_stack_module_css_default = {
|
|
8488
|
+
"avatar": "aACNsW_avatar",
|
|
8489
|
+
"overflow": "aACNsW_overflow",
|
|
8490
|
+
"stack": "aACNsW_stack"
|
|
8491
|
+
};
|
|
8492
|
+
//#endregion
|
|
8493
|
+
//#region src/client/TeamAvatarStack.tsx
|
|
8494
|
+
/** Distinct owners past this count collapse into one `+N` chip. */
|
|
8495
|
+
const MAX_VISIBLE = 3;
|
|
8496
|
+
/**
|
|
8497
|
+
* The compact "who is on this work" stack: overlapping 18px Member circles in
|
|
8498
|
+
* the shared identity language, capped at three plus a `+N` chip. The circles
|
|
8499
|
+
* are presentational, so the stack is one `role="img"` whose label carries the
|
|
8500
|
+
* whole roster — three anonymous initials would read as noise.
|
|
8501
|
+
*/
|
|
8502
|
+
function TeamAvatarStack({ owners, label }) {
|
|
8503
|
+
if (owners.length === 0) return null;
|
|
8504
|
+
const shown = owners.slice(0, MAX_VISIBLE);
|
|
8505
|
+
const overflow = owners.length - shown.length;
|
|
8506
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8507
|
+
className: avatar_stack_module_css_default.stack,
|
|
8508
|
+
role: "img",
|
|
8509
|
+
"aria-label": label,
|
|
8510
|
+
children: [shown.map((owner) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8511
|
+
className: avatar_stack_module_css_default.avatar,
|
|
8512
|
+
style: { "--team-avatar-hue": memberHue(owner.memberId) },
|
|
8513
|
+
children: initial(owner.name)
|
|
8514
|
+
}, owner.memberId)), overflow > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8515
|
+
className: avatar_stack_module_css_default.overflow,
|
|
8516
|
+
children: `+${overflow}`
|
|
8517
|
+
})]
|
|
8518
|
+
});
|
|
8519
|
+
}
|
|
8520
|
+
/** First visible character of a handle — and of a raw Member id when that is all there is. */
|
|
8521
|
+
function initial(name) {
|
|
8522
|
+
return name.replace(/^@/, "").replace(/^member:/, "").slice(0, 1).toUpperCase();
|
|
8523
|
+
}
|
|
8524
|
+
//#endregion
|
|
8525
|
+
//#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/countBadge.module.css.mjs
|
|
8526
|
+
const css$4 = ".LBWXOW_badge{background:var(--dsw-alias-state-business-primary);box-sizing:border-box;color:var(--dsw-alias-label-primary-foreground);corner-shape:round;font-variant-numeric:tabular-nums;border-radius:999px;flex:none;justify-content:center;align-items:center;min-width:18px;height:18px;padding:0 5px;font-size:11px;font-weight:600;line-height:18px;display:inline-flex}.LBWXOW_hairline{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0;padding:0 4px}";
|
|
8527
|
+
const tagId$4 = "@wowyuarm/dsh-agent-team/countBadge.module.css";
|
|
8528
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
|
|
8529
|
+
const tag = document.createElement("style");
|
|
8530
|
+
tag.dataset.plugin = "@wowyuarm/dsh-agent-team";
|
|
8531
|
+
tag.dataset.pluginCss = tagId$4;
|
|
8532
|
+
tag.textContent = css$4;
|
|
8533
|
+
document.head.appendChild(tag);
|
|
8534
|
+
}
|
|
8535
|
+
var countBadge_module_css_default = {
|
|
8536
|
+
"badge": "LBWXOW_badge",
|
|
8537
|
+
"hairline": "LBWXOW_hairline"
|
|
8538
|
+
};
|
|
8539
|
+
//#endregion
|
|
8540
|
+
//#region src/client/TeamCountBadge.tsx
|
|
8541
|
+
/** Every count the Human reads is capped at this, so one wide number never widens the capsule. */
|
|
8542
|
+
const COUNT_CAP = 99;
|
|
8543
|
+
/**
|
|
8544
|
+
* The one count capsule. The Human Inbox entry, the Channel feed's Thread
|
|
8545
|
+
* entry, and the Inbox queue row all answer the same question — how much is
|
|
8546
|
+
* waiting here — so they wear the same box rather than one hand-written copy
|
|
8547
|
+
* of the same declarations per surface. Three copies is how the feed's digit
|
|
8548
|
+
* ended up on a different line box from the other two.
|
|
8549
|
+
*
|
|
8550
|
+
* Zero is the absence of a count rather than a capsule reading zero, which is
|
|
8551
|
+
* the rule every caller wants and therefore the component's own.
|
|
8552
|
+
*/
|
|
8553
|
+
function TeamCountBadge({ count, tone = "solid", label, className }) {
|
|
8554
|
+
if (count <= 0) return null;
|
|
8555
|
+
const text = count > COUNT_CAP ? `${COUNT_CAP}+` : String(count);
|
|
8556
|
+
const classes = `${countBadge_module_css_default.badge}${tone === "hairline" ? ` ${countBadge_module_css_default.hairline}` : ""}${className === void 0 ? "" : ` ${className}`}`;
|
|
8557
|
+
return label === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8558
|
+
className: classes,
|
|
8559
|
+
"data-team-count-badge": tone,
|
|
8560
|
+
"aria-hidden": "true",
|
|
8561
|
+
children: text
|
|
8562
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8563
|
+
className: classes,
|
|
8564
|
+
"data-team-count-badge": tone,
|
|
8565
|
+
role: "img",
|
|
8566
|
+
"aria-label": label,
|
|
8567
|
+
title: label,
|
|
8568
|
+
children: text
|
|
8569
|
+
});
|
|
8570
|
+
}
|
|
8571
|
+
//#endregion
|
|
7987
8572
|
//#region src/client/TeamRunDivider.tsx
|
|
7988
8573
|
/**
|
|
7989
8574
|
* Explicit boundary between two same-sender Messages of one run separated by
|
|
@@ -8163,7 +8748,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8163
8748
|
}
|
|
8164
8749
|
//#endregion
|
|
8165
8750
|
//#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/channel.module.css.mjs
|
|
8166
|
-
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}.
|
|
8751
|
+
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_memberList{gap:2px;margin:0 -6px;display:grid}.MYaRJa_modalBody{max-height:min(65vh,520px);overflow-y:auto}";
|
|
8167
8752
|
const tagId$3 = "@wowyuarm/dsh-agent-team/channel.module.css";
|
|
8168
8753
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
8169
8754
|
const tag = document.createElement("style");
|
|
@@ -8174,22 +8759,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8174
8759
|
}
|
|
8175
8760
|
var channel_module_css_default = {
|
|
8176
8761
|
"headerMeta": "MYaRJa_headerMeta",
|
|
8177
|
-
"memberAction": "MYaRJa_memberAction",
|
|
8178
|
-
"memberCopy": "MYaRJa_memberCopy",
|
|
8179
|
-
"memberError": "MYaRJa_memberError",
|
|
8180
8762
|
"memberList": "MYaRJa_memberList",
|
|
8181
|
-
"
|
|
8182
|
-
"modalBody": "MYaRJa_modalBody",
|
|
8183
|
-
"taskArrow": "MYaRJa_taskArrow",
|
|
8184
|
-
"taskCount": "MYaRJa_taskCount",
|
|
8185
|
-
"taskDot": "MYaRJa_taskDot",
|
|
8186
|
-
"taskFooter": "MYaRJa_taskFooter",
|
|
8187
|
-
"taskNumber": "MYaRJa_taskNumber",
|
|
8188
|
-
"taskStatus": "MYaRJa_taskStatus"
|
|
8763
|
+
"modalBody": "MYaRJa_modalBody"
|
|
8189
8764
|
};
|
|
8190
8765
|
//#endregion
|
|
8191
8766
|
//#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/thread.module.css.mjs
|
|
8192
|
-
const css$2 = ".-Qiwua_titleLine{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.-Qiwua_titleLine h1{margin:0}.-Qiwua_workSection{border-top:1px solid var(--dsw-alias-border-l2);max-width:880px;margin:12px auto 0;padding-top:8px}.-Qiwua_riskSection{border-top:1px solid var(--dsw-alias-border-l2);max-width:880px;margin:12px auto 0;padding-top:10px}.-Qiwua_riskSection h2{color:var(--dsw-alias-state-error-primary);margin:0 0 5px;font-size:12px;font-weight:600;line-height:18px}.-Qiwua_riskRow{color:var(--dsw-alias-label-secondary);align-items:center;gap:8px;margin:3px 0;font-size:12px;line-height:18px;display:flex}.-Qiwua_claimList{gap:4px;padding:4px 0 2px 22px;display:grid}.-Qiwua_claimRow{border-radius:6px;grid-template-columns:14px minmax(96px,auto) minmax(0,1fr) auto auto;align-items:center;gap:4px 8px;min-height:36px;padding:4px 6px;display:grid}.-Qiwua_claimRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.-Qiwua_claimOwner{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;font-weight:500;line-height:18px;overflow:hidden}.-Qiwua_claimDirection{color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;min-width:0;font-size:12px;line-height:18px}.-Qiwua_claimState{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:11px;line-height:18px}.-Qiwua_emptyClaims{color:var(--dsw-alias-label-tertiary);margin:0;padding:5px 6px;font-size:11px;line-height:18px}.-Qiwua_activityRow{color:var(--dsw-alias-label-tertiary);text-align:center;justify-content:center;align-items:center;gap:8px;max-width:100%;margin:4px auto;padding:5px 12px;font-size:11px;line-height:18px;display:flex}.-Qiwua_activityText{overflow-wrap:anywhere;min-width:0}.-Qiwua_activityMark{background:var(--dsw-alias-border-l3);border-radius:50%;flex:0 0 5px;width:5px;height:5px}.-Qiwua_activityRow:has(+.-Qiwua_activityRow),.-Qiwua_activityRow+.-Qiwua_activityRow{text-align:left;justify-content:flex-start;padding-left:38px}.-Qiwua_historySection{border-bottom:1px solid var(--dsw-alias-border-l2);max-width:100%;margin:0 auto 12px;padding-bottom:10px}.-Qiwua_historySection h2{color:var(--dsw-alias-label-tertiary);letter-spacing:.02em;text-transform:uppercase;margin:0 0 4px;font-size:11px;font-weight:600;line-height:16px}.-Qiwua_publicSection{min-width:0}.-Qiwua_unreadBoundary{color:var(--dsw-alias-label-tertiary);align-items:center;gap:10px;margin:10px 0 6px;font-size:11px;line-height:16px;display:flex}.-Qiwua_unreadBoundary:before,.-Qiwua_unreadBoundary:after{background:var(--dsw-alias-border-l3);content:\"\";flex:1;height:1px}.-Qiwua_unreadBoundary span{flex:none}.-Qiwua_daySeparator{color:var(--dsw-alias-label-tertiary);letter-spacing:.02em;align-items:center;gap:10px;margin:12px 0 4px;font-size:11px;line-height:16px;display:flex}.-Qiwua_daySeparator:before,.-Qiwua_daySeparator:after{background:var(--dsw-alias-border-l2);content:\"\";flex:1;height:1px}.-Qiwua_daySeparator span{flex:none}.-Qiwua_newUpdates{background:var(--dsw-specific-input-major,var(--dsw-alias-bg-layer-1));border:1px solid var(--dsw-alias-border-l2-darkmode-thin);box-shadow:var(--dsw-shadow-lv2);z-index:2;border-radius:999px;justify-content:center;align-items:center;width:fit-content;margin:8px auto;padding:4px 12px;font-size:12px;line-height:18px;display:flex;position:sticky;bottom:8px}.-Qiwua_newUpdatesJump{color:var(--dsw-alias-label-secondary);cursor:pointer;font:inherit;line-height:inherit;background:0 0;border:0;padding:0}.-Qiwua_newUpdatesJump:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px;border-radius:6px}.-Qiwua_taskTitle{color:var(--dsw-alias-label-secondary);-webkit-line-clamp:2;overflow-wrap:anywhere;-webkit-box-orient:vertical;margin:2px 0 0;font-size:13px;line-height:20px;display:-webkit-box;overflow:hidden}.-Qiwua_closedBar{flex-direction:column;align-items:center;display:flex}.-Qiwua_closedNotice{color:var(--dsw-alias-label-tertiary);flex-wrap:wrap;justify-content:center;align-items:center;gap:12px;padding:10px 16px 14px;font-size:13px;line-height:20px;display:flex}@media (width<=600px){.-Qiwua_claimRow{grid-template-columns:14px minmax(0,1fr) auto;align-items:start}.-Qiwua_claimState{grid-area:1/3;justify-self:end}.-Qiwua_claimDirection{grid-column:2/-1}.-Qiwua_activityRow{padding-inline:0}.-Qiwua_newUpdates{max-width:calc(100% - 16px)}}";
|
|
8767
|
+
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);corner-shape:round;border-radius:50%;flex:0 0 5px;width:5px;height:5px}.-Qiwua_activityRow:has(+.-Qiwua_activityRow),.-Qiwua_activityRow+.-Qiwua_activityRow{text-align:left;justify-content:flex-start;padding-left:38px}.-Qiwua_historySection{border-bottom:1px solid var(--dsw-alias-border-l2);max-width:100%;margin:0 auto 12px;padding-bottom:10px}.-Qiwua_historySection h2{color:var(--dsw-alias-label-tertiary);letter-spacing:.02em;text-transform:uppercase;margin:0 0 4px;font-size:11px;font-weight:600;line-height:16px}.-Qiwua_publicSection{min-width:0}.-Qiwua_unreadBoundary{color:var(--dsw-alias-label-tertiary);align-items:center;gap:10px;margin:10px 0 6px;font-size:11px;line-height:16px;display:flex}.-Qiwua_unreadBoundary:before,.-Qiwua_unreadBoundary:after{background:var(--dsw-alias-border-l3);content:\"\";flex:1;height:1px}.-Qiwua_unreadBoundary span{flex:none}.-Qiwua_daySeparator{color:var(--dsw-alias-label-tertiary);letter-spacing:.02em;align-items:center;gap:10px;margin:12px 0 4px;font-size:11px;line-height:16px;display:flex}.-Qiwua_daySeparator:before,.-Qiwua_daySeparator:after{background:var(--dsw-alias-border-l2);content:\"\";flex:1;height:1px}.-Qiwua_daySeparator span{flex:none}.-Qiwua_newUpdates{background:var(--dsw-specific-input-major,var(--dsw-alias-bg-layer-1));border:1px solid var(--dsw-alias-border-l2-darkmode-thin);corner-shape:round;box-shadow:var(--dsw-shadow-lv2);z-index:2;border-radius:999px;justify-content:center;align-items:center;width:fit-content;margin:8px auto;padding:4px 12px;font-size:12px;line-height:18px;display:flex;position:sticky;bottom:8px}.-Qiwua_newUpdatesJump{color:var(--dsw-alias-label-secondary);cursor:pointer;font:inherit;line-height:inherit;background:0 0;border:0;padding:0}.-Qiwua_newUpdatesJump:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px;border-radius:6px}.-Qiwua_taskTitle{color:var(--dsw-alias-label-secondary);-webkit-line-clamp:2;overflow-wrap:anywhere;-webkit-box-orient:vertical;margin:2px 0 0;font-size:13px;line-height:20px;display:-webkit-box;overflow:hidden}.-Qiwua_closedBar{flex-direction:column;align-items:center;display:flex}.-Qiwua_closedNotice{color:var(--dsw-alias-label-tertiary);flex-wrap:wrap;justify-content:center;align-items:center;gap:12px;padding:10px 16px 14px;font-size:13px;line-height:20px;display:flex}@media (width<=600px){.-Qiwua_claimRow{grid-template-columns:14px minmax(0,1fr) auto;align-items:start}.-Qiwua_claimState{grid-area:1/3;justify-self:end}.-Qiwua_claimDirection{grid-column:2/-1}.-Qiwua_activityRow{padding-inline:0}.-Qiwua_newUpdates{max-width:calc(100% - 16px)}}";
|
|
8193
8768
|
const tagId$2 = "@wowyuarm/dsh-agent-team/thread.module.css";
|
|
8194
8769
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
|
|
8195
8770
|
const tag = document.createElement("style");
|
|
@@ -8225,12 +8800,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8225
8800
|
//#endregion
|
|
8226
8801
|
//#region src/client/TeamChannelPage.tsx
|
|
8227
8802
|
/**
|
|
8228
|
-
* Merge the freshest top-level window over what the reader already has
|
|
8229
|
-
*
|
|
8803
|
+
* Merge the freshest top-level window over what the reader already has. The
|
|
8804
|
+
* fresh window is authoritative for every Message it covers — a change wake
|
|
8805
|
+
* must move that row's live Task state, newest instant, and unread with it —
|
|
8806
|
+
* while older Messages loaded earlier are retained instead of discarded.
|
|
8230
8807
|
*/
|
|
8231
8808
|
function mergeChannelView(current, fresh) {
|
|
8232
|
-
const
|
|
8233
|
-
const items = [...
|
|
8809
|
+
const freshRefs = new Set(fresh.items.map((item) => item.message.messageRef));
|
|
8810
|
+
const items = [...current.items.filter((item) => !freshRefs.has(item.message.messageRef)), ...fresh.items].sort((left, right) => left.message.sequence - right.message.sequence);
|
|
8234
8811
|
return {
|
|
8235
8812
|
...fresh,
|
|
8236
8813
|
items,
|
|
@@ -8238,9 +8815,41 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8238
8815
|
hasMore: fresh.hasMore || current.cursor < fresh.cursor
|
|
8239
8816
|
};
|
|
8240
8817
|
}
|
|
8241
|
-
|
|
8818
|
+
/**
|
|
8819
|
+
* The people the Channel feed shows on one Task: owners of its live Claims, in
|
|
8820
|
+
* claim order, deduped. Claim state is a Host fact, not decoration — a released
|
|
8821
|
+
* Claim is no longer work — and only a Task still in progress or review has
|
|
8822
|
+
* any, because a done or closed Task keeps its Claims as history that the state
|
|
8823
|
+
* word already tells the reader.
|
|
8824
|
+
*/
|
|
8825
|
+
function liveOwnersByTask(items, claims) {
|
|
8826
|
+
const live = new Set(items.flatMap((item) => item.task === void 0 ? [] : [item.task]).filter((task) => task.status === "in_progress" || task.status === "in_review").map((task) => task.taskRef));
|
|
8827
|
+
const owners = /* @__PURE__ */ new Map();
|
|
8828
|
+
for (const claim of claims) {
|
|
8829
|
+
if (!live.has(claim.taskRef) || claim.state === "released") continue;
|
|
8830
|
+
const known = owners.get(claim.taskRef);
|
|
8831
|
+
if (known === void 0) owners.set(claim.taskRef, [claim.owner]);
|
|
8832
|
+
else if (!known.includes(claim.owner)) known.push(claim.owner);
|
|
8833
|
+
}
|
|
8834
|
+
return owners;
|
|
8835
|
+
}
|
|
8836
|
+
/**
|
|
8837
|
+
* The newest fact instant, or nothing when the entry's own Message is still the
|
|
8838
|
+
* newest fact on its Thread. That difference is exactly what "has follow-up
|
|
8839
|
+
* activity" means, and the Host projects both instants from the ledger.
|
|
8840
|
+
*/
|
|
8841
|
+
function followUpAt(item) {
|
|
8842
|
+
const lastActivityAt = item.lastActivityAt;
|
|
8843
|
+
return lastActivityAt === void 0 || lastActivityAt === item.message.occurredAt ? void 0 : lastActivityAt;
|
|
8844
|
+
}
|
|
8845
|
+
/** Host unread per Thread, keyed for the feed's rows: zero unread is the absence of a badge, not a row. */
|
|
8846
|
+
function unreadCounts(inbox) {
|
|
8847
|
+
return new Map(inbox.items.filter((item) => item.unreadCount > 0).map((item) => [item.thread.threadRef, item.unreadCount]));
|
|
8848
|
+
}
|
|
8849
|
+
function TeamChannelPage({ workspaceId, channelRef, loadChannels, subscribeChanges, loadMembers, loadInbox, drafts, putAttachment, getAttachment, sendMessage, joinChannel, removeChannelMember, selectThread, selectChannel, backToChannels, resolveTaskRefs, t }) {
|
|
8242
8850
|
const [view, setView] = (0, react.useState)();
|
|
8243
8851
|
const [members, setMembers] = (0, react.useState)([]);
|
|
8852
|
+
const [unreadByThread, setUnreadByThread] = (0, react.useState)(/* @__PURE__ */ new Map());
|
|
8244
8853
|
const [error, setError] = (0, react.useState)();
|
|
8245
8854
|
const [pendingFiles, setPendingFiles] = (0, react.useState)([]);
|
|
8246
8855
|
const [statusMessage, setStatusMessage] = (0, react.useState)();
|
|
@@ -8250,10 +8859,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8250
8859
|
const [loadingOlder, setLoadingOlder] = (0, react.useState)(false);
|
|
8251
8860
|
const [managingMembers, setManagingMembers] = (0, react.useState)(false);
|
|
8252
8861
|
const draftKey = `channel:${channelRef}`;
|
|
8253
|
-
const { draft, recipients } = (0, react.useSyncExternalStore)(drafts.subscribe, () => drafts.getSnapshot(draftKey));
|
|
8254
8862
|
const manageTriggerRef = (0, react.useRef)(null);
|
|
8255
8863
|
const memberListRef = (0, react.useRef)(null);
|
|
8256
8864
|
const mountedRef = (0, react.useRef)(false);
|
|
8865
|
+
const loadedRef = (0, react.useRef)(false);
|
|
8257
8866
|
const refreshSequenceRef = (0, react.useRef)(0);
|
|
8258
8867
|
const channelLastItem = view?.items[view.items.length - 1];
|
|
8259
8868
|
const openRef = (ref) => {
|
|
@@ -8298,31 +8907,46 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8298
8907
|
const channelMembers = members.filter((status) => channelMemberIds.has(status.member.memberId) && status.member.state !== "inactive" && status.member.state !== "archived");
|
|
8299
8908
|
const onlineCount = channelMembers.filter((status) => status.presence === "available" || status.presence === "working").length;
|
|
8300
8909
|
const messageSender = (item) => item.message.sender;
|
|
8301
|
-
const
|
|
8910
|
+
const handleByMember = new Map(members.map((status) => [status.member.memberId, status.member.handle.replace(/^@/, "")]));
|
|
8911
|
+
const ownersByTask = liveOwnersByTask(view?.items ?? [], view?.claims ?? []);
|
|
8302
8912
|
const refresh = async (clearError = false) => {
|
|
8303
8913
|
if (!mountedRef.current) return false;
|
|
8304
8914
|
const sequence = refreshSequenceRef.current + 1;
|
|
8305
8915
|
refreshSequenceRef.current = sequence;
|
|
8306
|
-
setLoading(true);
|
|
8916
|
+
if (!loadedRef.current) setLoading(true);
|
|
8307
8917
|
if (clearError) {
|
|
8308
8918
|
setError(void 0);
|
|
8309
8919
|
setStatusMessage(void 0);
|
|
8310
8920
|
}
|
|
8311
8921
|
try {
|
|
8312
|
-
const [loaded, loadedMembers] = await Promise.all([
|
|
8313
|
-
|
|
8314
|
-
|
|
8315
|
-
|
|
8316
|
-
|
|
8317
|
-
|
|
8318
|
-
|
|
8319
|
-
|
|
8922
|
+
const [loaded, loadedMembers, loadedInbox] = await Promise.all([
|
|
8923
|
+
loadChannels({
|
|
8924
|
+
workspaceId,
|
|
8925
|
+
channelRef,
|
|
8926
|
+
direction: "before",
|
|
8927
|
+
topLevelOnly: true,
|
|
8928
|
+
includeActivities: false,
|
|
8929
|
+
limit: 20
|
|
8930
|
+
}),
|
|
8931
|
+
loadMembers({ workspaceId }),
|
|
8932
|
+
loadInbox({
|
|
8933
|
+
workspaceId,
|
|
8934
|
+
limit: 100
|
|
8935
|
+
})
|
|
8936
|
+
]);
|
|
8320
8937
|
if (!mountedRef.current || sequence !== refreshSequenceRef.current) return false;
|
|
8321
|
-
if (loaded.ok)
|
|
8322
|
-
|
|
8938
|
+
if (loaded.ok) {
|
|
8939
|
+
setView((current) => current === void 0 ? loaded.value : mergeChannelView(current, loaded.value));
|
|
8940
|
+
loadedRef.current = true;
|
|
8941
|
+
} else setError(loaded.error.message);
|
|
8323
8942
|
if (loadedMembers.ok) setMembers(loadedMembers.value);
|
|
8324
8943
|
else setError(loadedMembers.error.message);
|
|
8325
|
-
|
|
8944
|
+
if (loadedInbox.ok) setUnreadByThread(unreadCounts(loadedInbox.value));
|
|
8945
|
+
else {
|
|
8946
|
+
setUnreadByThread(/* @__PURE__ */ new Map());
|
|
8947
|
+
setError(loadedInbox.error.message);
|
|
8948
|
+
}
|
|
8949
|
+
return loaded.ok && loadedMembers.ok && loadedInbox.ok;
|
|
8326
8950
|
} catch (cause) {
|
|
8327
8951
|
if (mountedRef.current && sequence === refreshSequenceRef.current) setError(cause instanceof Error ? cause.message : String(cause));
|
|
8328
8952
|
return false;
|
|
@@ -8343,32 +8967,47 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8343
8967
|
};
|
|
8344
8968
|
(0, react.useEffect)(() => {
|
|
8345
8969
|
mountedRef.current = true;
|
|
8970
|
+
loadedRef.current = false;
|
|
8346
8971
|
setView(void 0);
|
|
8347
8972
|
setError(void 0);
|
|
8348
8973
|
setLoading(true);
|
|
8349
8974
|
setManagingMembers(false);
|
|
8350
8975
|
refresh();
|
|
8351
|
-
const disposers = [
|
|
8352
|
-
|
|
8353
|
-
|
|
8354
|
-
|
|
8355
|
-
|
|
8356
|
-
|
|
8357
|
-
|
|
8358
|
-
|
|
8359
|
-
|
|
8360
|
-
|
|
8361
|
-
|
|
8362
|
-
|
|
8363
|
-
|
|
8364
|
-
|
|
8365
|
-
|
|
8366
|
-
|
|
8367
|
-
|
|
8368
|
-
|
|
8369
|
-
|
|
8370
|
-
|
|
8371
|
-
|
|
8976
|
+
const disposers = [
|
|
8977
|
+
subscribeChanges({
|
|
8978
|
+
kind: "channel",
|
|
8979
|
+
channelRef
|
|
8980
|
+
}, (update) => {
|
|
8981
|
+
if (!mountedRef.current) return;
|
|
8982
|
+
if (update.type === "failed") {
|
|
8983
|
+
setError(update.message);
|
|
8984
|
+
return;
|
|
8985
|
+
}
|
|
8986
|
+
refresh();
|
|
8987
|
+
}),
|
|
8988
|
+
subscribeChanges({
|
|
8989
|
+
kind: "workspace",
|
|
8990
|
+
workspaceId
|
|
8991
|
+
}, (update) => {
|
|
8992
|
+
if (!mountedRef.current) return;
|
|
8993
|
+
if (update.type === "failed") {
|
|
8994
|
+
setError(update.message);
|
|
8995
|
+
return;
|
|
8996
|
+
}
|
|
8997
|
+
refreshMembers();
|
|
8998
|
+
}),
|
|
8999
|
+
subscribeChanges({
|
|
9000
|
+
kind: "presence",
|
|
9001
|
+
workspaceId
|
|
9002
|
+
}, (update) => {
|
|
9003
|
+
if (!mountedRef.current) return;
|
|
9004
|
+
if (update.type === "failed") {
|
|
9005
|
+
setError(update.message);
|
|
9006
|
+
return;
|
|
9007
|
+
}
|
|
9008
|
+
refreshMembers();
|
|
9009
|
+
})
|
|
9010
|
+
];
|
|
8372
9011
|
return () => {
|
|
8373
9012
|
mountedRef.current = false;
|
|
8374
9013
|
refreshSequenceRef.current += 1;
|
|
@@ -8419,7 +9058,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8419
9058
|
await refresh();
|
|
8420
9059
|
});
|
|
8421
9060
|
const pendingSendId = (0, react.useRef)();
|
|
9061
|
+
const clearSendState = (0, react.useCallback)(() => {
|
|
9062
|
+
setStatusMessage((current) => current === void 0 ? current : void 0);
|
|
9063
|
+
}, []);
|
|
8422
9064
|
const send = async () => {
|
|
9065
|
+
const { draft, recipients } = drafts.getSnapshot(draftKey);
|
|
8423
9066
|
if (pending || draft.trim() === "") return;
|
|
8424
9067
|
const recipientIds = [...recipients].sort();
|
|
8425
9068
|
const requestId = pendingSendId.current ?? mintRequestId();
|
|
@@ -8428,22 +9071,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8428
9071
|
setError(void 0);
|
|
8429
9072
|
setStatusMessage(void 0);
|
|
8430
9073
|
try {
|
|
8431
|
-
const
|
|
8432
|
-
|
|
8433
|
-
|
|
8434
|
-
|
|
8435
|
-
|
|
8436
|
-
name: file.name,
|
|
8437
|
-
mediaType: file.type === "" ? void 0 : file.type,
|
|
8438
|
-
bytesBase64: bytesToBase64(new Uint8Array(await file.arrayBuffer()))
|
|
8439
|
-
});
|
|
8440
|
-
if (!uploaded.ok) {
|
|
8441
|
-
pendingSendId.current = void 0;
|
|
8442
|
-
setError(uploaded.error.message);
|
|
8443
|
-
return;
|
|
8444
|
-
}
|
|
8445
|
-
attachmentIds.push(uploaded.value.attachmentId);
|
|
9074
|
+
const upload = await uploadComposerFiles(putAttachment, workspaceId, pendingFiles);
|
|
9075
|
+
if (!upload.ok) {
|
|
9076
|
+
pendingSendId.current = void 0;
|
|
9077
|
+
setError(upload.error);
|
|
9078
|
+
return;
|
|
8446
9079
|
}
|
|
9080
|
+
const attachmentIds = upload.attachmentIds;
|
|
8447
9081
|
const result = await sendMessage({
|
|
8448
9082
|
requestId,
|
|
8449
9083
|
workspaceId,
|
|
@@ -8527,39 +9161,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8527
9161
|
children: members.filter((status) => status.member.state !== "inactive" && status.member.state !== "archived").map((status) => {
|
|
8528
9162
|
const joined = channelMemberIds.has(status.member.memberId);
|
|
8529
9163
|
const rowPending = membership.pending.has(status.member.memberId);
|
|
8530
|
-
const disabled = rowPending || !joined && status.
|
|
9164
|
+
const disabled = rowPending || !joined && status.availability !== "active";
|
|
8531
9165
|
const rowError = membership.errors.get(status.member.memberId);
|
|
8532
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.
|
|
8533
|
-
|
|
8534
|
-
|
|
8535
|
-
|
|
8536
|
-
|
|
8537
|
-
|
|
8538
|
-
|
|
8539
|
-
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
|
|
8544
|
-
|
|
8545
|
-
|
|
8546
|
-
|
|
8547
|
-
|
|
8548
|
-
membership.change({
|
|
8549
|
-
workspaceId,
|
|
8550
|
-
channelRef,
|
|
8551
|
-
memberId: status.member.memberId,
|
|
8552
|
-
joined
|
|
8553
|
-
});
|
|
8554
|
-
},
|
|
8555
|
-
children: rowPending ? t("membershipUpdating") : joined ? t("removeFromChannel") : t("addToChannel")
|
|
8556
|
-
}),
|
|
8557
|
-
rowError !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
8558
|
-
className: channel_module_css_default.memberError,
|
|
8559
|
-
role: "alert",
|
|
8560
|
-
children: rowError
|
|
8561
|
-
})
|
|
8562
|
-
]
|
|
9166
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamMemberRow, {
|
|
9167
|
+
status,
|
|
9168
|
+
action: {
|
|
9169
|
+
label: rowPending ? t("membershipUpdating") : joined ? t("removeFromChannel") : t("addToChannel"),
|
|
9170
|
+
disabled,
|
|
9171
|
+
onSelect: () => {
|
|
9172
|
+
membership.change({
|
|
9173
|
+
workspaceId,
|
|
9174
|
+
channelRef,
|
|
9175
|
+
memberId: status.member.memberId,
|
|
9176
|
+
joined
|
|
9177
|
+
});
|
|
9178
|
+
}
|
|
9179
|
+
},
|
|
9180
|
+
...rowError === void 0 ? {} : { error: rowError },
|
|
9181
|
+
t
|
|
8563
9182
|
}, status.member.memberId);
|
|
8564
9183
|
})
|
|
8565
9184
|
})
|
|
@@ -8629,7 +9248,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8629
9248
|
const human = item.message.sender === view.humanMemberId;
|
|
8630
9249
|
const sender = human ? t("human") : senderStatus?.member.handle ?? item.message.sender;
|
|
8631
9250
|
const turnGap = isRunGap(index > 0 ? block.items[index - 1].message.occurredAt : void 0, item.message.occurredAt);
|
|
8632
|
-
|
|
9251
|
+
const task = item.task;
|
|
9252
|
+
const owners = task === void 0 ? [] : ownersByTask.get(task.taskRef) ?? [];
|
|
9253
|
+
const unread = unreadByThread.get(item.thread.threadRef) ?? 0;
|
|
9254
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [turnGap && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamRunDivider, { occurredAt: item.message.occurredAt }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamMessage, {
|
|
8633
9255
|
senderName: sender,
|
|
8634
9256
|
memberId: item.message.sender,
|
|
8635
9257
|
human,
|
|
@@ -8638,68 +9260,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8638
9260
|
loadAttachment: getAttachment,
|
|
8639
9261
|
t,
|
|
8640
9262
|
occurredAt: item.message.occurredAt,
|
|
8641
|
-
mentionNames: mentionNamesOf(item.mentions,
|
|
9263
|
+
mentionNames: mentionNamesOf(item.mentions, handleByMember),
|
|
8642
9264
|
onOpenRef: openRef,
|
|
8643
9265
|
onResolveTaskRefs: lookupTaskRefs,
|
|
8644
9266
|
grouped: index > 0,
|
|
8645
9267
|
showGroupedTime: item.message.topLevel === true && !turnGap,
|
|
8646
9268
|
...senderStatus === void 0 ? {} : { senderTitle: senderStatus.member.description },
|
|
8647
|
-
children:
|
|
8648
|
-
|
|
8649
|
-
|
|
8650
|
-
|
|
8651
|
-
|
|
8652
|
-
|
|
8653
|
-
|
|
8654
|
-
|
|
8655
|
-
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
|
|
8659
|
-
state: taskStatusDot(item.task.status)
|
|
8660
|
-
})
|
|
8661
|
-
}),
|
|
8662
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8663
|
-
className: channel_module_css_default.taskNumber,
|
|
8664
|
-
children: t("taskLabel", { number: item.taskNumber })
|
|
8665
|
-
}),
|
|
8666
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8667
|
-
className: channel_module_css_default.taskStatus,
|
|
8668
|
-
children: formatTaskStatus(item.task.status, t)
|
|
8669
|
-
}),
|
|
8670
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8671
|
-
className: channel_module_css_default.taskCount,
|
|
8672
|
-
children: t("taskMessageCount", { count: item.messageCount })
|
|
8673
|
-
}),
|
|
8674
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8675
|
-
className: channel_module_css_default.taskArrow,
|
|
8676
|
-
"aria-hidden": "true",
|
|
8677
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14, { size: 12 })
|
|
8678
|
-
})
|
|
8679
|
-
]
|
|
8680
|
-
}), item.message.topLevel && item.task === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
8681
|
-
type: "button",
|
|
8682
|
-
className: channel_module_css_default.taskFooter,
|
|
8683
|
-
"aria-label": t("openThread"),
|
|
8684
|
-
onClick: () => {
|
|
8685
|
-
selectThread(item.thread.threadRef, channelRef);
|
|
8686
|
-
},
|
|
8687
|
-
children: [
|
|
8688
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8689
|
-
className: channel_module_css_default.taskNumber,
|
|
8690
|
-
children: t("threadLabel")
|
|
8691
|
-
}),
|
|
8692
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8693
|
-
className: channel_module_css_default.taskCount,
|
|
8694
|
-
children: t("taskMessageCount", { count: item.messageCount })
|
|
8695
|
-
}),
|
|
8696
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8697
|
-
className: channel_module_css_default.taskArrow,
|
|
8698
|
-
"aria-hidden": "true",
|
|
8699
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14, { size: 12 })
|
|
8700
|
-
})
|
|
8701
|
-
]
|
|
8702
|
-
})]
|
|
9269
|
+
children: item.message.topLevel && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThreadEntryRow, {
|
|
9270
|
+
item,
|
|
9271
|
+
owners: owners.map((memberId) => ({
|
|
9272
|
+
memberId,
|
|
9273
|
+
name: handleByMember.get(memberId) ?? memberId
|
|
9274
|
+
})),
|
|
9275
|
+
unread,
|
|
9276
|
+
t,
|
|
9277
|
+
onOpen: () => {
|
|
9278
|
+
selectThread(item.thread.threadRef, channelRef, task?.taskRef, item.taskNumber);
|
|
9279
|
+
}
|
|
9280
|
+
})
|
|
8703
9281
|
})] }, item.message.messageRef);
|
|
8704
9282
|
})
|
|
8705
9283
|
}, `run-${block.items[0].message.messageRef}`))
|
|
@@ -8708,19 +9286,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8708
9286
|
}),
|
|
8709
9287
|
channel !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamComposer, {
|
|
8710
9288
|
members: channelMembers,
|
|
8711
|
-
|
|
8712
|
-
|
|
9289
|
+
drafts,
|
|
9290
|
+
draftKey,
|
|
8713
9291
|
pending,
|
|
8714
9292
|
...statusMessage === void 0 ? {} : { confirmation: statusMessage },
|
|
8715
9293
|
...error === void 0 ? {} : { error },
|
|
8716
|
-
|
|
8717
|
-
drafts.writeDraft(draftKey, next);
|
|
8718
|
-
setStatusMessage(void 0);
|
|
8719
|
-
},
|
|
8720
|
-
onRecipientsChange: (next) => {
|
|
8721
|
-
drafts.writeRecipients(draftKey, next);
|
|
8722
|
-
setStatusMessage(void 0);
|
|
8723
|
-
},
|
|
9294
|
+
onEdit: clearSendState,
|
|
8724
9295
|
onSubmit: () => {
|
|
8725
9296
|
send();
|
|
8726
9297
|
},
|
|
@@ -8733,6 +9304,453 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8733
9304
|
]
|
|
8734
9305
|
});
|
|
8735
9306
|
}
|
|
9307
|
+
/**
|
|
9308
|
+
* One entry's state: who is on the work, where it stands, and how much of it
|
|
9309
|
+
* needs the reader. It leads the entry's own line rather than trailing the
|
|
9310
|
+
* identity line, so a reader meets it where they are already reading instead of
|
|
9311
|
+
* crossing the column for it — and the same placement holds whether this
|
|
9312
|
+
* Message opened its run or continued one, where an identity line would have
|
|
9313
|
+
* carried nothing else. The unread capsule is the only member a taskless
|
|
9314
|
+
* discussion can carry: it needs no Task.
|
|
9315
|
+
*/
|
|
9316
|
+
function ThreadStateCluster({ task, owners, unread, t }) {
|
|
9317
|
+
if (task === void 0 && unread === 0) return null;
|
|
9318
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
9319
|
+
className: conversation_module_css_default.stateCluster,
|
|
9320
|
+
children: [
|
|
9321
|
+
task !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamAvatarStack, {
|
|
9322
|
+
owners,
|
|
9323
|
+
label: t("claimers", { names: owners.map((owner) => `@${owner.name}`).join(", ") })
|
|
9324
|
+
}),
|
|
9325
|
+
task !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamStateDot, {
|
|
9326
|
+
size: 8,
|
|
9327
|
+
state: taskStatusDot(task.status)
|
|
9328
|
+
}),
|
|
9329
|
+
task !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9330
|
+
className: conversation_module_css_default.statusWord,
|
|
9331
|
+
children: formatTaskStatus(task.status, t)
|
|
9332
|
+
}),
|
|
9333
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamCountBadge, { count: unread })
|
|
9334
|
+
]
|
|
9335
|
+
});
|
|
9336
|
+
}
|
|
9337
|
+
/**
|
|
9338
|
+
* The gate under one top-level Message: the single row that opens its Thread,
|
|
9339
|
+
* and the one line that says what stands there. State leads it, then what the
|
|
9340
|
+
* entry is: a Task entry keeps its number so the status word never floats free
|
|
9341
|
+
* of the Task it describes, follow-up activity adds when the work last moved,
|
|
9342
|
+
* and an unanswered Thread says only 回复. The instant uses the Inbox's own
|
|
9343
|
+
* 今天/昨天 form with the precise local time on the control's title, and an
|
|
9344
|
+
* unread Thread says so in the control's label rather than only in pixels.
|
|
9345
|
+
*/
|
|
9346
|
+
function ThreadEntryRow({ item, owners, unread, t, onOpen }) {
|
|
9347
|
+
const taskNumber = item.taskNumber;
|
|
9348
|
+
const followUp = followUpAt(item);
|
|
9349
|
+
const label = taskNumber !== void 0 ? t("taskLabel", { number: taskNumber }) : followUp === void 0 ? t("replyAction") : t("threadLabel");
|
|
9350
|
+
const text = followUp === void 0 ? label : `${label} · ${t("recentActivity", { time: formatInboxTime(followUp, t) })}`;
|
|
9351
|
+
const openLabel = taskNumber === void 0 ? unread > 0 ? t("openThreadUnread", { count: unread }) : t("openThread") : unread > 0 ? t("openTaskUnread", {
|
|
9352
|
+
number: taskNumber,
|
|
9353
|
+
count: unread
|
|
9354
|
+
}) : t("openTask", { number: taskNumber });
|
|
9355
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
9356
|
+
className: conversation_module_css_default.entryLine,
|
|
9357
|
+
"data-thread-entry": "",
|
|
9358
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThreadStateCluster, {
|
|
9359
|
+
task: item.task,
|
|
9360
|
+
owners,
|
|
9361
|
+
unread,
|
|
9362
|
+
t
|
|
9363
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
9364
|
+
type: "button",
|
|
9365
|
+
className: conversation_module_css_default.entryRow,
|
|
9366
|
+
"aria-label": openLabel,
|
|
9367
|
+
...followUp === void 0 ? {} : { title: formatAbsoluteTime(followUp) },
|
|
9368
|
+
onClick: onOpen,
|
|
9369
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: text }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9370
|
+
className: conversation_module_css_default.entryArrow,
|
|
9371
|
+
"aria-hidden": "true",
|
|
9372
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14, { size: 12 })
|
|
9373
|
+
})]
|
|
9374
|
+
})]
|
|
9375
|
+
});
|
|
9376
|
+
}
|
|
9377
|
+
//#endregion
|
|
9378
|
+
//#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/inbox.module.css.mjs
|
|
9379
|
+
const css$1 = ".s2ibaa_list{flex-direction:column;gap:2px;display:flex}.s2ibaa_headerMeta{font-variant-numeric:tabular-nums;flex-wrap:wrap;align-items:baseline;gap:0 10px;display:flex;overflow:hidden}.s2ibaa_headerUnread{color:var(--dsw-alias-label-primary);font-weight:600}.s2ibaa_row{color:inherit;cursor:pointer;font:inherit;text-align:left;background:0 0;border:0;border-radius:8px;grid-template-columns:max-content minmax(0,1fr);align-items:baseline;gap:1px 8px;width:100%;padding:8px;display:grid}.s2ibaa_row:hover,.s2ibaa_row:focus-visible{--team-mark-ring:var(--dsw-alias-interactive-bg-hover);background:var(--dsw-alias-interactive-bg-hover)}.s2ibaa_row:focus-visible{outline:2px solid var(--dsw-alias-label-primary);outline-offset:-2px}.s2ibaa_rowActor{grid-area:1/1;display:flex}.s2ibaa_rowLine{grid-area:1/2;align-items:baseline;gap:2px 8px;min-width:0;display:flex}.s2ibaa_rowCrumb{text-overflow:ellipsis;white-space:nowrap;flex:auto;min-width:0;font-size:13px;line-height:20px;overflow:hidden}.s2ibaa_rowWorkspace{color:var(--dsw-alias-label-tertiary);font-size:12px}.s2ibaa_rowChannel{color:var(--dsw-alias-label-primary);font-weight:600}.s2ibaa_rowTask{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);white-space:nowrap;border-radius:6px;flex:none;margin-left:3px;padding:0 5px;font-size:11px;font-weight:600;line-height:15px}.s2ibaa_rowTime{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;flex:none;font-size:11px;line-height:18px}.s2ibaa_rowPreview{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;grid-area:2/2;min-width:0;font-size:13px;line-height:20px;overflow:hidden}.s2ibaa_section{flex-direction:column;display:flex}.s2ibaa_section+.s2ibaa_section{margin-top:20px}.s2ibaa_sectionTitle{color:var(--dsw-alias-label-tertiary);margin:0 0 4px;padding:0 8px 0 34px;font-size:12px;font-weight:600;line-height:18px}.s2ibaa_sectionCount{font-variant-numeric:tabular-nums;margin-left:6px}";
|
|
9380
|
+
const tagId$1 = "@wowyuarm/dsh-agent-team/inbox.module.css";
|
|
9381
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
9382
|
+
const tag = document.createElement("style");
|
|
9383
|
+
tag.dataset.plugin = "@wowyuarm/dsh-agent-team";
|
|
9384
|
+
tag.dataset.pluginCss = tagId$1;
|
|
9385
|
+
tag.textContent = css$1;
|
|
9386
|
+
document.head.appendChild(tag);
|
|
9387
|
+
}
|
|
9388
|
+
var inbox_module_css_default = {
|
|
9389
|
+
"headerMeta": "s2ibaa_headerMeta",
|
|
9390
|
+
"headerUnread": "s2ibaa_headerUnread",
|
|
9391
|
+
"list": "s2ibaa_list",
|
|
9392
|
+
"row": "s2ibaa_row",
|
|
9393
|
+
"rowActor": "s2ibaa_rowActor",
|
|
9394
|
+
"rowChannel": "s2ibaa_rowChannel",
|
|
9395
|
+
"rowCrumb": "s2ibaa_rowCrumb",
|
|
9396
|
+
"rowLine": "s2ibaa_rowLine",
|
|
9397
|
+
"rowPreview": "s2ibaa_rowPreview",
|
|
9398
|
+
"rowTask": "s2ibaa_rowTask",
|
|
9399
|
+
"rowTime": "s2ibaa_rowTime",
|
|
9400
|
+
"rowWorkspace": "s2ibaa_rowWorkspace",
|
|
9401
|
+
"section": "s2ibaa_section",
|
|
9402
|
+
"sectionCount": "s2ibaa_sectionCount",
|
|
9403
|
+
"sectionTitle": "s2ibaa_sectionTitle"
|
|
9404
|
+
};
|
|
9405
|
+
//#endregion
|
|
9406
|
+
//#region src/client/TeamInboxPage.tsx
|
|
9407
|
+
/**
|
|
9408
|
+
* How many 「最近活跃」 rows the merged page may show. The Host bounds each
|
|
9409
|
+
* Workspace's own slice; this is the single bound across every Workspace on
|
|
9410
|
+
* screen, so the section stays the same size no matter how many are open — and
|
|
9411
|
+
* it stays a way back into work rather than a second queue, which is why it is
|
|
9412
|
+
* shorter than the queue the reader is actually being asked to work through.
|
|
9413
|
+
*/
|
|
9414
|
+
const RECENT_ROWS_LIMIT = 5;
|
|
9415
|
+
/**
|
|
9416
|
+
* Queue order: newest unread first, one total order across Workspaces. Each
|
|
9417
|
+
* Workspace slice arrives in the Host's own order (that order is the Host's
|
|
9418
|
+
* truncation policy); the merged display order is decided here, where the
|
|
9419
|
+
* merge happens, and the ledger sequence breaks ties so the queue never
|
|
9420
|
+
* reshuffles two rows that share an instant.
|
|
9421
|
+
*/
|
|
9422
|
+
function compareInboxRows(left, right) {
|
|
9423
|
+
const leftAt = Date.parse(left.item.newestOccurredAt);
|
|
9424
|
+
const rightAt = Date.parse(right.item.newestOccurredAt);
|
|
9425
|
+
const byTime = (Number.isNaN(rightAt) ? 0 : rightAt) - (Number.isNaN(leftAt) ? 0 : leftAt);
|
|
9426
|
+
return byTime !== 0 ? byTime : right.item.newestSequence - left.item.newestSequence;
|
|
9427
|
+
}
|
|
9428
|
+
/**
|
|
9429
|
+
* The Human Inbox: one Inbox call per visible Workspace, rendering the Host's
|
|
9430
|
+
* two slices — the unread queue (「需要我」, mentions counted inside it rather
|
|
9431
|
+
* than alone) and the 「最近活跃」 tail of Threads the reader took part in.
|
|
9432
|
+
* Both merge across every Workspace into one recency-ordered list, newest
|
|
9433
|
+
* first, since a queue is read by recency rather than by Workspace.
|
|
9434
|
+
* Opening the page never acknowledges anything — only a durable Thread read
|
|
9435
|
+
* advances the watermark and consumes a mention marker, so rows and the badge
|
|
9436
|
+
* drop after the Thread is opened through the existing auto-ack path. A Thread
|
|
9437
|
+
* holding unread is only ever in the queue: the Host already excludes it from
|
|
9438
|
+
* the tail, and this page never re-derives that judgement.
|
|
9439
|
+
*/
|
|
9440
|
+
function TeamInboxPage({ useWorkspaces, loadInbox, subscribeChanges, selectWorkspace, selectThread, t }) {
|
|
9441
|
+
const workspaces = useWorkspaces((state) => state.items);
|
|
9442
|
+
const [rows, setRows] = (0, react.useState)();
|
|
9443
|
+
const [recentRows, setRecentRows] = (0, react.useState)([]);
|
|
9444
|
+
const [loading, setLoading] = (0, react.useState)(true);
|
|
9445
|
+
const [error, setError] = (0, react.useState)();
|
|
9446
|
+
const loadedRef = (0, react.useRef)(false);
|
|
9447
|
+
const refresh = (0, react.useCallback)(async () => {
|
|
9448
|
+
if (!loadedRef.current) setLoading(true);
|
|
9449
|
+
const results = await Promise.all(workspaces.map(async (workspace) => {
|
|
9450
|
+
const result = await loadInbox({
|
|
9451
|
+
workspaceId: workspace.workspaceId,
|
|
9452
|
+
limit: 100
|
|
9453
|
+
});
|
|
9454
|
+
return result.ok ? {
|
|
9455
|
+
ok: true,
|
|
9456
|
+
workspaceId: workspace.workspaceId,
|
|
9457
|
+
workspaceTitle: workspace.title,
|
|
9458
|
+
items: result.value.items,
|
|
9459
|
+
recent: result.value.recent
|
|
9460
|
+
} : {
|
|
9461
|
+
ok: false,
|
|
9462
|
+
message: result.error.message
|
|
9463
|
+
};
|
|
9464
|
+
}));
|
|
9465
|
+
const failure = results.find((result) => !result.ok);
|
|
9466
|
+
const asRows = (items, workspaceId, workspaceTitle) => items.map((item) => ({
|
|
9467
|
+
workspaceId,
|
|
9468
|
+
workspaceTitle,
|
|
9469
|
+
item
|
|
9470
|
+
}));
|
|
9471
|
+
setRows(results.flatMap((result) => result.ok ? asRows(result.items, result.workspaceId, result.workspaceTitle) : []).sort(compareInboxRows));
|
|
9472
|
+
setRecentRows(results.flatMap((result) => result.ok ? asRows(result.recent, result.workspaceId, result.workspaceTitle) : []).sort(compareInboxRows).slice(0, RECENT_ROWS_LIMIT));
|
|
9473
|
+
setError(failure?.ok === false ? failure.message : void 0);
|
|
9474
|
+
loadedRef.current = true;
|
|
9475
|
+
setLoading(false);
|
|
9476
|
+
}, [loadInbox, workspaces]);
|
|
9477
|
+
(0, react.useEffect)(() => {
|
|
9478
|
+
refresh();
|
|
9479
|
+
}, [refresh]);
|
|
9480
|
+
(0, react.useEffect)(() => subscribeChanges(void 0, (update) => {
|
|
9481
|
+
if (update.type === "failed") {
|
|
9482
|
+
setError(update.message);
|
|
9483
|
+
return;
|
|
9484
|
+
}
|
|
9485
|
+
refresh();
|
|
9486
|
+
}), [subscribeChanges, refresh]);
|
|
9487
|
+
const open = (row) => {
|
|
9488
|
+
selectWorkspace(row.workspaceId);
|
|
9489
|
+
selectThread(row.item.thread.threadRef, row.item.channelRef, row.item.task?.taskRef, row.item.taskNumber);
|
|
9490
|
+
};
|
|
9491
|
+
const totalUnread = rows?.reduce((sum, row) => sum + row.item.unreadCount, 0) ?? 0;
|
|
9492
|
+
const totalMentions = rows?.reduce((sum, row) => sum + row.item.directCount, 0) ?? 0;
|
|
9493
|
+
const shownWorkspaces = /* @__PURE__ */ new Set();
|
|
9494
|
+
for (const row of rows ?? []) shownWorkspaces.add(row.workspaceTitle);
|
|
9495
|
+
for (const row of recentRows) shownWorkspaces.add(row.workspaceTitle);
|
|
9496
|
+
const showWorkspace = shownWorkspaces.size > 1;
|
|
9497
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("main", {
|
|
9498
|
+
className: conversation_module_css_default.surface,
|
|
9499
|
+
"data-team-inbox": true,
|
|
9500
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9501
|
+
className: conversation_module_css_default.surfaceHeader,
|
|
9502
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("header", {
|
|
9503
|
+
className: conversation_module_css_default.headerRow,
|
|
9504
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9505
|
+
className: conversation_module_css_default.headerCopy,
|
|
9506
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", { children: t("inboxTitle") }), rows !== void 0 && rows.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
9507
|
+
className: inbox_module_css_default.headerMeta,
|
|
9508
|
+
children: [
|
|
9509
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("inboxHeaderThreads", { count: rows.length }) }),
|
|
9510
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9511
|
+
className: inbox_module_css_default.headerUnread,
|
|
9512
|
+
children: t("inboxHeaderUnread", { count: totalUnread })
|
|
9513
|
+
}),
|
|
9514
|
+
totalMentions > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("inboxHeaderMentions", { count: totalMentions }) })
|
|
9515
|
+
]
|
|
9516
|
+
})]
|
|
9517
|
+
})
|
|
9518
|
+
})
|
|
9519
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9520
|
+
className: conversation_module_css_default.timeline,
|
|
9521
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9522
|
+
className: conversation_module_css_default.timelineContent,
|
|
9523
|
+
children: [
|
|
9524
|
+
loading && rows === void 0 && error === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9525
|
+
className: conversation_module_css_default.emptySurface,
|
|
9526
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
9527
|
+
className: conversation_module_css_default.loadingState,
|
|
9528
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9529
|
+
className: conversation_module_css_default.loadingMark,
|
|
9530
|
+
"aria-hidden": "true"
|
|
9531
|
+
}), t("loadingInbox")]
|
|
9532
|
+
})
|
|
9533
|
+
}),
|
|
9534
|
+
!loading && rows === void 0 && error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9535
|
+
className: conversation_module_css_default.errorState,
|
|
9536
|
+
role: "alert",
|
|
9537
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: error }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
9538
|
+
size: "sm",
|
|
9539
|
+
variant: "outline",
|
|
9540
|
+
onClick: () => {
|
|
9541
|
+
refresh();
|
|
9542
|
+
},
|
|
9543
|
+
children: t("retry")
|
|
9544
|
+
})]
|
|
9545
|
+
}),
|
|
9546
|
+
rows !== void 0 && (rows.length === 0 && recentRows.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9547
|
+
className: conversation_module_css_default.emptySurface,
|
|
9548
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9549
|
+
className: conversation_module_css_default.emptyState,
|
|
9550
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("inboxEmptyTitle") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("inboxEmptyHint") })]
|
|
9551
|
+
})
|
|
9552
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [rows.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
9553
|
+
className: inbox_module_css_default.section,
|
|
9554
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("h2", {
|
|
9555
|
+
className: inbox_module_css_default.sectionTitle,
|
|
9556
|
+
children: [t("inboxSectionNeedsMe"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9557
|
+
className: inbox_module_css_default.sectionCount,
|
|
9558
|
+
children: rows.length
|
|
9559
|
+
})]
|
|
9560
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9561
|
+
className: inbox_module_css_default.list,
|
|
9562
|
+
children: rows.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InboxQueueRow, {
|
|
9563
|
+
row,
|
|
9564
|
+
t,
|
|
9565
|
+
showWorkspace,
|
|
9566
|
+
onOpen: () => {
|
|
9567
|
+
open(row);
|
|
9568
|
+
}
|
|
9569
|
+
}, `${row.workspaceId} ${row.item.thread.threadRef}`))
|
|
9570
|
+
})]
|
|
9571
|
+
}), recentRows.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
9572
|
+
className: inbox_module_css_default.section,
|
|
9573
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("h2", {
|
|
9574
|
+
className: inbox_module_css_default.sectionTitle,
|
|
9575
|
+
children: [t("inboxSectionRecent"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9576
|
+
className: inbox_module_css_default.sectionCount,
|
|
9577
|
+
children: recentRows.length
|
|
9578
|
+
})]
|
|
9579
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9580
|
+
className: inbox_module_css_default.list,
|
|
9581
|
+
children: recentRows.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InboxQueueRow, {
|
|
9582
|
+
row,
|
|
9583
|
+
t,
|
|
9584
|
+
showWorkspace,
|
|
9585
|
+
onOpen: () => {
|
|
9586
|
+
open(row);
|
|
9587
|
+
}
|
|
9588
|
+
}, `${row.workspaceId} ${row.item.thread.threadRef}`))
|
|
9589
|
+
})]
|
|
9590
|
+
})] })),
|
|
9591
|
+
rows !== void 0 && error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
9592
|
+
className: conversation_module_css_default.error,
|
|
9593
|
+
role: "alert",
|
|
9594
|
+
children: error
|
|
9595
|
+
})
|
|
9596
|
+
]
|
|
9597
|
+
})
|
|
9598
|
+
})]
|
|
9599
|
+
});
|
|
9600
|
+
}
|
|
9601
|
+
/**
|
|
9602
|
+
* One queue row, shaped like the shipped two-line result row: who is on this
|
|
9603
|
+
* Thread leads in the gutter, the identity line answers which Thread this is,
|
|
9604
|
+
* how much is waiting, and when it last moved, and the gist sits under it on the
|
|
9605
|
+
* same column as evidence for that identity rather than as the row's subject.
|
|
9606
|
+
*
|
|
9607
|
+
* The gutter carries the one thing every row has — who is on the work, or who
|
|
9608
|
+
* moved a Thread nobody has claimed — so a Thread that merely arrived and one
|
|
9609
|
+
* that named the reader open on the same edge instead of the quieter one opening
|
|
9610
|
+
* on a slot reserved for a count it does not hold. It is the grammar the Channel
|
|
9611
|
+
* feed's Thread entry row already speaks, where the people on the work lead the
|
|
9612
|
+
* row.
|
|
9613
|
+
*
|
|
9614
|
+
* Before the queue admitted every unread Thread, each row was a mention and the
|
|
9615
|
+
* rows were interchangeable; now that named and ambient unread share one list,
|
|
9616
|
+
* the row has to carry that difference itself. The count closes the identity
|
|
9617
|
+
* line and only its ink changes — the shared capsule fill for a row that names
|
|
9618
|
+
* the reader, a hairline for one that merely moved. The two numbers behind that
|
|
9619
|
+
* ink (unread, mentions) reach assistive tech through the capsule's own name,
|
|
9620
|
+
* because a second visible count beside the first would cost the row the one
|
|
9621
|
+
* thing it needs to stay scannable.
|
|
9622
|
+
*/
|
|
9623
|
+
function InboxQueueRow({ row, t, showWorkspace, onOpen }) {
|
|
9624
|
+
const { item } = row;
|
|
9625
|
+
const actor = item.newestActor;
|
|
9626
|
+
const owners = item.claimOwners;
|
|
9627
|
+
const named = item.directCount > 0;
|
|
9628
|
+
const countLabel = named ? t("inboxRowUnreadMentions", {
|
|
9629
|
+
count: item.unreadCount,
|
|
9630
|
+
mentions: item.directCount
|
|
9631
|
+
}) : t("inboxRowUnread", { count: item.unreadCount });
|
|
9632
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
9633
|
+
type: "button",
|
|
9634
|
+
className: inbox_module_css_default.row,
|
|
9635
|
+
"data-named": named || void 0,
|
|
9636
|
+
onClick: onOpen,
|
|
9637
|
+
children: [
|
|
9638
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9639
|
+
className: inbox_module_css_default.rowActor,
|
|
9640
|
+
children: owners.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamAvatarStack, {
|
|
9641
|
+
owners,
|
|
9642
|
+
label: t("claimers", { names: owners.map((owner) => `@${owner.name}`).join(", ") })
|
|
9643
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamAvatarStack, {
|
|
9644
|
+
owners: [actor],
|
|
9645
|
+
label: t("inboxRowActor", { name: `@${actor.name}` })
|
|
9646
|
+
})
|
|
9647
|
+
}),
|
|
9648
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
9649
|
+
className: inbox_module_css_default.rowLine,
|
|
9650
|
+
children: [
|
|
9651
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
9652
|
+
className: inbox_module_css_default.rowCrumb,
|
|
9653
|
+
children: [
|
|
9654
|
+
showWorkspace && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9655
|
+
className: inbox_module_css_default.rowWorkspace,
|
|
9656
|
+
children: row.workspaceTitle
|
|
9657
|
+
}),
|
|
9658
|
+
showWorkspace && " / ",
|
|
9659
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
9660
|
+
className: inbox_module_css_default.rowChannel,
|
|
9661
|
+
children: ["#", item.channelName]
|
|
9662
|
+
}),
|
|
9663
|
+
" ",
|
|
9664
|
+
item.taskNumber !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9665
|
+
className: inbox_module_css_default.rowTask,
|
|
9666
|
+
children: t("taskLabel", { number: item.taskNumber })
|
|
9667
|
+
})
|
|
9668
|
+
]
|
|
9669
|
+
}),
|
|
9670
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamCountBadge, {
|
|
9671
|
+
count: item.unreadCount,
|
|
9672
|
+
tone: named ? "solid" : "hairline",
|
|
9673
|
+
label: countLabel
|
|
9674
|
+
}),
|
|
9675
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("time", {
|
|
9676
|
+
className: inbox_module_css_default.rowTime,
|
|
9677
|
+
dateTime: item.newestOccurredAt,
|
|
9678
|
+
title: formatAbsoluteTime(item.newestOccurredAt),
|
|
9679
|
+
children: formatInboxTime(item.newestOccurredAt, t)
|
|
9680
|
+
})
|
|
9681
|
+
]
|
|
9682
|
+
}),
|
|
9683
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9684
|
+
className: inbox_module_css_default.rowPreview,
|
|
9685
|
+
children: item.previewText
|
|
9686
|
+
})
|
|
9687
|
+
]
|
|
9688
|
+
});
|
|
9689
|
+
}
|
|
9690
|
+
//#endregion
|
|
9691
|
+
//#region src/client/scope-coverage.ts
|
|
9692
|
+
/**
|
|
9693
|
+
* Per-scope coverage of the change versions one surface has already answered.
|
|
9694
|
+
*
|
|
9695
|
+
* A version is only comparable inside the scope that issued it: the Host
|
|
9696
|
+
* answers a workspace scope from the durable ledger position and a presence
|
|
9697
|
+
* scope from its process-local wake epoch, which starts low and climbs on every
|
|
9698
|
+
* Agent transition. One high-water mark shared by both would therefore let a
|
|
9699
|
+
* presence epoch swallow a later, smaller ledger sequence and park the surface
|
|
9700
|
+
* on stale data, so coverage and pending versions are kept per scope.
|
|
9701
|
+
*
|
|
9702
|
+
* One round answers one version per scope. The Host delivers one event to every
|
|
9703
|
+
* matching scope, so the first version a round sees in a scope it has not
|
|
9704
|
+
* answered yet is that event reaching a second scope, and joins the round
|
|
9705
|
+
* already fetching instead of earning a second identical read. A newer version
|
|
9706
|
+
* in a scope the round has answered arrived after the round issued its fetch,
|
|
9707
|
+
* so it owes one trailing round.
|
|
9708
|
+
*/
|
|
9709
|
+
var ScopeCoverage = class {
|
|
9710
|
+
covered = /* @__PURE__ */ new Map();
|
|
9711
|
+
pending = /* @__PURE__ */ new Map();
|
|
9712
|
+
/** The scopes the open round has an answer for. */
|
|
9713
|
+
answered = /* @__PURE__ */ new Set();
|
|
9714
|
+
fetching = false;
|
|
9715
|
+
/** Folds one wake in and answers whether it opens a round. */
|
|
9716
|
+
wake(scope, version) {
|
|
9717
|
+
if (version <= this.coveredOf(scope)) return false;
|
|
9718
|
+
if (this.fetching && this.answered.has(scope)) {
|
|
9719
|
+
this.pending.set(scope, Math.max(this.pending.get(scope) ?? 0, version));
|
|
9720
|
+
return false;
|
|
9721
|
+
}
|
|
9722
|
+
this.answered.add(scope);
|
|
9723
|
+
this.covered.set(scope, version);
|
|
9724
|
+
return !this.fetching;
|
|
9725
|
+
}
|
|
9726
|
+
/** Opens a round's fetch window; versions observed from here on are pending. */
|
|
9727
|
+
beginRound() {
|
|
9728
|
+
this.pending.clear();
|
|
9729
|
+
this.fetching = true;
|
|
9730
|
+
}
|
|
9731
|
+
/** Closes a round's fetch window and answers whether a trailing round is owed. */
|
|
9732
|
+
finishRound() {
|
|
9733
|
+
this.fetching = false;
|
|
9734
|
+
this.answered.clear();
|
|
9735
|
+
let owed = false;
|
|
9736
|
+
for (const [scope, version] of this.pending) {
|
|
9737
|
+
if (version <= this.coveredOf(scope)) continue;
|
|
9738
|
+
this.covered.set(scope, version);
|
|
9739
|
+
owed = true;
|
|
9740
|
+
}
|
|
9741
|
+
return owed;
|
|
9742
|
+
}
|
|
9743
|
+
/** Drops every observation: a new owner starts with nothing covered. */
|
|
9744
|
+
reset() {
|
|
9745
|
+
this.covered.clear();
|
|
9746
|
+
this.pending.clear();
|
|
9747
|
+
this.answered.clear();
|
|
9748
|
+
this.fetching = false;
|
|
9749
|
+
}
|
|
9750
|
+
coveredOf(scope) {
|
|
9751
|
+
return this.covered.get(scope) ?? 0;
|
|
9752
|
+
}
|
|
9753
|
+
};
|
|
8736
9754
|
//#endregion
|
|
8737
9755
|
//#region src/client/TeamThreadPage.tsx
|
|
8738
9756
|
function factKey(fact) {
|
|
@@ -8747,6 +9765,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8747
9765
|
occurredAt: message.occurredAt
|
|
8748
9766
|
};
|
|
8749
9767
|
}
|
|
9768
|
+
/**
|
|
9769
|
+
* A fact owns its mention array, so the rendered name list is cached against
|
|
9770
|
+
* that array. Every roster refresh replaces the handles map with a fresh Map of
|
|
9771
|
+
* identical content, so the cache compares the resolved names rather than the
|
|
9772
|
+
* map identity: identity stays stable while the names are unchanged, which is
|
|
9773
|
+
* what keeps a memoized row from re-rendering on every refresh.
|
|
9774
|
+
*/
|
|
9775
|
+
const mentionNamesCache = /* @__PURE__ */ new WeakMap();
|
|
9776
|
+
function stableMentionNames(mentions, handles) {
|
|
9777
|
+
const names = mentionNamesOf(mentions, handles);
|
|
9778
|
+
const cached = mentionNamesCache.get(mentions);
|
|
9779
|
+
if (cached !== void 0 && cached.length === names.length && cached.every((name, index) => name === names[index])) return cached;
|
|
9780
|
+
mentionNamesCache.set(mentions, names);
|
|
9781
|
+
return names;
|
|
9782
|
+
}
|
|
8750
9783
|
function mergeFacts(...groups) {
|
|
8751
9784
|
const byKey = /* @__PURE__ */ new Map();
|
|
8752
9785
|
for (const group of groups) for (const fact of group) byKey.set(factKey(fact), fact);
|
|
@@ -8777,7 +9810,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8777
9810
|
const [autoReadExhausted, setAutoReadExhausted] = (0, react.useState)(false);
|
|
8778
9811
|
const [newFactsCount, setNewFactsCount] = (0, react.useState)(0);
|
|
8779
9812
|
const draftKey = `thread:${threadRef}`;
|
|
8780
|
-
const { draft, recipients } = (0, react.useSyncExternalStore)(drafts.subscribe, () => drafts.getSnapshot(draftKey));
|
|
8781
9813
|
const [claimsOpen, setClaimsOpen] = (0, react.useState)(false);
|
|
8782
9814
|
const [confirmingAccept, setConfirmingAccept] = (0, react.useState)(false);
|
|
8783
9815
|
(0, react.useEffect)(() => {
|
|
@@ -8847,7 +9879,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8847
9879
|
if (mountedRef.current && sequence === sequenceRef.current) setLoading(false);
|
|
8848
9880
|
}
|
|
8849
9881
|
};
|
|
8850
|
-
|
|
9882
|
+
/** One roster + view read. Answers false once the page is gone. */
|
|
9883
|
+
const applySupplemental = async () => {
|
|
8851
9884
|
try {
|
|
8852
9885
|
const [loadedMembers, loadedView] = await Promise.all([loadMembers({ workspaceId }), loadChannels({
|
|
8853
9886
|
workspaceId,
|
|
@@ -8856,15 +9889,36 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8856
9889
|
includeActivities: false,
|
|
8857
9890
|
limit: 1
|
|
8858
9891
|
})]);
|
|
8859
|
-
if (!mountedRef.current) return;
|
|
9892
|
+
if (!mountedRef.current) return false;
|
|
8860
9893
|
if (loadedMembers.ok) setMembers(loadedMembers.value);
|
|
8861
9894
|
if (loadedView.ok) setChannelView(loadedView.value);
|
|
8862
9895
|
const failure = [loadedMembers, loadedView].find((result) => !result.ok);
|
|
8863
9896
|
if (failure !== void 0 && !failure.ok) setError(failure.error.message);
|
|
9897
|
+
return true;
|
|
8864
9898
|
} catch (cause) {
|
|
8865
9899
|
if (mountedRef.current) setError(cause instanceof Error ? cause.message : String(cause));
|
|
9900
|
+
return mountedRef.current;
|
|
8866
9901
|
}
|
|
8867
9902
|
};
|
|
9903
|
+
const supplementalRef = (0, react.useRef)();
|
|
9904
|
+
const supplementalCoverageRef = (0, react.useRef)(new ScopeCoverage());
|
|
9905
|
+
const refreshSupplemental = (wake) => {
|
|
9906
|
+
const inFlight = supplementalRef.current;
|
|
9907
|
+
if (wake === void 0) {
|
|
9908
|
+
if (inFlight !== void 0) return inFlight;
|
|
9909
|
+
} else if (!supplementalCoverageRef.current.wake(wake.scope, wake.version)) return inFlight ?? Promise.resolve();
|
|
9910
|
+
const coverage = supplementalCoverageRef.current;
|
|
9911
|
+
const round = (async () => {
|
|
9912
|
+
for (;;) {
|
|
9913
|
+
coverage.beginRound();
|
|
9914
|
+
if (!await applySupplemental() || !coverage.finishRound()) return;
|
|
9915
|
+
}
|
|
9916
|
+
})().finally(() => {
|
|
9917
|
+
if (supplementalRef.current === round) supplementalRef.current = void 0;
|
|
9918
|
+
});
|
|
9919
|
+
supplementalRef.current = round;
|
|
9920
|
+
return round;
|
|
9921
|
+
};
|
|
8868
9922
|
const refreshPassiveFacts = async () => {
|
|
8869
9923
|
try {
|
|
8870
9924
|
const result = await loadThreadHistory({
|
|
@@ -8911,6 +9965,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8911
9965
|
};
|
|
8912
9966
|
(0, react.useEffect)(() => {
|
|
8913
9967
|
mountedRef.current = true;
|
|
9968
|
+
supplementalRef.current = void 0;
|
|
9969
|
+
supplementalCoverageRef.current.reset();
|
|
8914
9970
|
projectionRef.current = void 0;
|
|
8915
9971
|
setProjection(void 0);
|
|
8916
9972
|
setChannelView(void 0);
|
|
@@ -8969,28 +10025,48 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8969
10025
|
await drainUnread();
|
|
8970
10026
|
})();
|
|
8971
10027
|
refreshSupplemental();
|
|
8972
|
-
const disposers = [
|
|
8973
|
-
|
|
8974
|
-
|
|
8975
|
-
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
|
|
8982
|
-
|
|
8983
|
-
|
|
8984
|
-
|
|
8985
|
-
|
|
8986
|
-
|
|
8987
|
-
|
|
8988
|
-
|
|
8989
|
-
|
|
8990
|
-
|
|
8991
|
-
|
|
8992
|
-
|
|
8993
|
-
|
|
10028
|
+
const disposers = [
|
|
10029
|
+
subscribeChanges({
|
|
10030
|
+
kind: "thread",
|
|
10031
|
+
threadRef
|
|
10032
|
+
}, (update) => {
|
|
10033
|
+
if (!mountedRef.current) return;
|
|
10034
|
+
if (update.type === "failed") {
|
|
10035
|
+
setError(update.message);
|
|
10036
|
+
return;
|
|
10037
|
+
}
|
|
10038
|
+
refreshPassiveFacts();
|
|
10039
|
+
refreshFollowers();
|
|
10040
|
+
}),
|
|
10041
|
+
subscribeChanges({
|
|
10042
|
+
kind: "workspace",
|
|
10043
|
+
workspaceId
|
|
10044
|
+
}, (update) => {
|
|
10045
|
+
if (!mountedRef.current) return;
|
|
10046
|
+
if (update.type === "failed") {
|
|
10047
|
+
setError(update.message);
|
|
10048
|
+
return;
|
|
10049
|
+
}
|
|
10050
|
+
refreshSupplemental({
|
|
10051
|
+
scope: "workspace",
|
|
10052
|
+
version: update.version
|
|
10053
|
+
});
|
|
10054
|
+
}),
|
|
10055
|
+
subscribeChanges({
|
|
10056
|
+
kind: "presence",
|
|
10057
|
+
workspaceId
|
|
10058
|
+
}, (update) => {
|
|
10059
|
+
if (!mountedRef.current) return;
|
|
10060
|
+
if (update.type === "failed") {
|
|
10061
|
+
setError(update.message);
|
|
10062
|
+
return;
|
|
10063
|
+
}
|
|
10064
|
+
refreshSupplemental({
|
|
10065
|
+
scope: "presence",
|
|
10066
|
+
version: update.version
|
|
10067
|
+
});
|
|
10068
|
+
})
|
|
10069
|
+
];
|
|
8994
10070
|
return () => {
|
|
8995
10071
|
mountedRef.current = false;
|
|
8996
10072
|
sequenceRef.current += 1;
|
|
@@ -9066,7 +10142,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9066
10142
|
};
|
|
9067
10143
|
const messageSender = (fact) => fact.kind === "message" ? fact.message.sender : void 0;
|
|
9068
10144
|
const [pendingFiles, setPendingFiles] = (0, react.useState)([]);
|
|
9069
|
-
const openRef = (ref) => {
|
|
10145
|
+
const openRef = (0, react.useCallback)((ref) => {
|
|
9070
10146
|
if (ref.startsWith("channel:") && ref !== channelRef) {
|
|
9071
10147
|
selectChannel(ref);
|
|
9072
10148
|
return;
|
|
@@ -9087,8 +10163,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9087
10163
|
return;
|
|
9088
10164
|
}
|
|
9089
10165
|
if (ref.startsWith("task:") && ref !== taskRef) jumpToTaskThread(resolveTaskRefs, workspaceId, ref, selectThread);
|
|
9090
|
-
}
|
|
9091
|
-
|
|
10166
|
+
}, [
|
|
10167
|
+
channelRef,
|
|
10168
|
+
threadRef,
|
|
10169
|
+
taskRef,
|
|
10170
|
+
workspaceId,
|
|
10171
|
+
selectChannel,
|
|
10172
|
+
selectThread,
|
|
10173
|
+
loadChannels,
|
|
10174
|
+
resolveTaskRefs
|
|
10175
|
+
]);
|
|
10176
|
+
const lookupTaskRefs = (0, react.useMemo)(() => hostTaskRefLookup(resolveTaskRefs, workspaceId), [resolveTaskRefs, workspaceId]);
|
|
9092
10177
|
const renderFact = (fact, grouped = false) => {
|
|
9093
10178
|
if (fact.kind === "message") {
|
|
9094
10179
|
const sender = memberName(fact.message.sender);
|
|
@@ -9102,7 +10187,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9102
10187
|
loadAttachment: getAttachment,
|
|
9103
10188
|
t,
|
|
9104
10189
|
occurredAt: fact.message.occurredAt,
|
|
9105
|
-
mentionNames:
|
|
10190
|
+
mentionNames: stableMentionNames(fact.mentions, mentionHandlesMap),
|
|
9106
10191
|
onOpenRef: openRef,
|
|
9107
10192
|
onResolveTaskRefs: lookupTaskRefs,
|
|
9108
10193
|
grouped,
|
|
@@ -9287,28 +10372,25 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9287
10372
|
setMutating(void 0);
|
|
9288
10373
|
}
|
|
9289
10374
|
};
|
|
10375
|
+
const clearSendState = (0, react.useCallback)(() => {
|
|
10376
|
+
setConfirmation((current) => current === void 0 ? current : void 0);
|
|
10377
|
+
setReplyRequestId((current) => current === void 0 ? current : void 0);
|
|
10378
|
+
setStatusMessage((current) => current === void 0 ? current : void 0);
|
|
10379
|
+
}, []);
|
|
9290
10380
|
const sendReply = async () => {
|
|
10381
|
+
const { draft, recipients } = drafts.getSnapshot(draftKey);
|
|
9291
10382
|
if (pending || thread === void 0 || draft.trim() === "") return;
|
|
9292
10383
|
const id = replyRequestId ?? mintRequestId();
|
|
9293
10384
|
setReplyRequestId(id);
|
|
9294
10385
|
setPending(true);
|
|
9295
10386
|
setError(void 0);
|
|
9296
10387
|
try {
|
|
9297
|
-
const
|
|
9298
|
-
|
|
9299
|
-
|
|
9300
|
-
|
|
9301
|
-
workspaceId,
|
|
9302
|
-
name: file.name,
|
|
9303
|
-
mediaType: file.type === "" ? void 0 : file.type,
|
|
9304
|
-
bytesBase64: bytesToBase64(new Uint8Array(await file.arrayBuffer()))
|
|
9305
|
-
});
|
|
9306
|
-
if (!uploaded.ok) {
|
|
9307
|
-
setError(uploaded.error.message);
|
|
9308
|
-
return;
|
|
9309
|
-
}
|
|
9310
|
-
attachmentIds.push(uploaded.value.attachmentId);
|
|
10388
|
+
const upload = await uploadComposerFiles(putAttachment, workspaceId, pendingFiles);
|
|
10389
|
+
if (!upload.ok) {
|
|
10390
|
+
setError(upload.error);
|
|
10391
|
+
return;
|
|
9311
10392
|
}
|
|
10393
|
+
const attachmentIds = upload.attachmentIds;
|
|
9312
10394
|
const result = await reply({
|
|
9313
10395
|
requestId: id,
|
|
9314
10396
|
workspaceId,
|
|
@@ -9326,12 +10408,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9326
10408
|
}
|
|
9327
10409
|
if (result.value.kind === "committed") {
|
|
9328
10410
|
const committed = result.value;
|
|
10411
|
+
const optimisticMentions = [...new Set([...recipients, ...mentionedMemberIds(draft, channelMembers)])].sort();
|
|
9329
10412
|
setCurrentFacts((current) => {
|
|
9330
10413
|
const merged = mergeFacts(current, [{
|
|
9331
10414
|
kind: "message",
|
|
9332
10415
|
sequence: committed.message.sequence,
|
|
9333
10416
|
message: committed.message,
|
|
9334
|
-
mentions:
|
|
10417
|
+
mentions: optimisticMentions,
|
|
9335
10418
|
occurredAt: committed.receipt.occurredAt
|
|
9336
10419
|
}]);
|
|
9337
10420
|
currentFactsRef.current = merged;
|
|
@@ -9477,7 +10560,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9477
10560
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
9478
10561
|
t("runtimeRiskDetail", {
|
|
9479
10562
|
member: status.member.handle,
|
|
9480
|
-
diagnostic: status
|
|
10563
|
+
diagnostic: diagnosticText(status) || t("statusError")
|
|
9481
10564
|
}),
|
|
9482
10565
|
" · ",
|
|
9483
10566
|
claim.direction
|
|
@@ -9667,23 +10750,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9667
10750
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamComposer, {
|
|
9668
10751
|
members: channelMembers,
|
|
9669
10752
|
followerMemberIds: followerIds,
|
|
9670
|
-
|
|
9671
|
-
|
|
10753
|
+
drafts,
|
|
10754
|
+
draftKey,
|
|
9672
10755
|
pending,
|
|
9673
10756
|
...statusMessage === void 0 ? {} : { confirmation: statusMessage },
|
|
9674
|
-
...error === void 0 ? {} : { error },
|
|
9675
|
-
|
|
9676
|
-
drafts.writeDraft(draftKey, next);
|
|
9677
|
-
setConfirmation(void 0);
|
|
9678
|
-
setReplyRequestId(void 0);
|
|
9679
|
-
setStatusMessage(void 0);
|
|
9680
|
-
},
|
|
9681
|
-
onRecipientsChange: (next) => {
|
|
9682
|
-
drafts.writeRecipients(draftKey, next);
|
|
9683
|
-
setConfirmation(void 0);
|
|
9684
|
-
setReplyRequestId(void 0);
|
|
9685
|
-
setStatusMessage(void 0);
|
|
9686
|
-
},
|
|
10757
|
+
...error === void 0 ? {} : { error },
|
|
10758
|
+
onEdit: clearSendState,
|
|
9687
10759
|
onSubmit: () => {
|
|
9688
10760
|
sendReply();
|
|
9689
10761
|
},
|
|
@@ -9697,9 +10769,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9697
10769
|
}
|
|
9698
10770
|
//#endregion
|
|
9699
10771
|
//#region src/client/TeamConversation.tsx
|
|
9700
|
-
function TeamConversation({ t, useWorkspaces, navigation, drafts, putAttachment, getAttachment, loadChannels, readThread, loadThreadHistory, threadObservations, subscribeChanges, loadMembers, sendMessage, joinChannel, removeChannelMember, reply, changeTask, promoteThread, selectThread, selectChannel, backToWorkspace, backToChannels, resolveTaskRefs }) {
|
|
10772
|
+
function TeamConversation({ t, useWorkspaces, navigation, drafts, putAttachment, getAttachment, loadChannels, readThread, loadThreadHistory, threadObservations, subscribeChanges, loadMembers, loadInbox, sendMessage, joinChannel, removeChannelMember, reply, changeTask, promoteThread, selectThread, selectChannel, selectWorkspace, backToWorkspace, backToChannels, resolveTaskRefs }) {
|
|
9701
10773
|
const navigationState = (0, react.useSyncExternalStore)(navigation.subscribe, navigation.getSnapshot, navigation.getSnapshot);
|
|
9702
10774
|
const current = useWorkspaces((state) => state.items).find((workspace) => workspace.workspaceId === navigationState.workspaceId);
|
|
10775
|
+
if (navigationState.inbox === true) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamInboxPage, {
|
|
10776
|
+
useWorkspaces,
|
|
10777
|
+
loadInbox,
|
|
10778
|
+
subscribeChanges,
|
|
10779
|
+
selectWorkspace,
|
|
10780
|
+
selectThread,
|
|
10781
|
+
t
|
|
10782
|
+
}, "inbox");
|
|
9703
10783
|
if (current !== void 0 && navigationState.threadRef !== void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamThreadPage, {
|
|
9704
10784
|
workspaceId: current.workspaceId,
|
|
9705
10785
|
putAttachment,
|
|
@@ -9733,6 +10813,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9733
10813
|
loadChannels,
|
|
9734
10814
|
subscribeChanges,
|
|
9735
10815
|
loadMembers,
|
|
10816
|
+
loadInbox,
|
|
9736
10817
|
sendMessage,
|
|
9737
10818
|
joinChannel,
|
|
9738
10819
|
removeChannelMember,
|
|
@@ -9768,64 +10849,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9768
10849
|
});
|
|
9769
10850
|
}
|
|
9770
10851
|
//#endregion
|
|
9771
|
-
//#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/sidebar.module.css.mjs
|
|
9772
|
-
const css$1 = "html[data-agent-team-mode=team] button[class*=newSession]{display:none}.d0xfxa_workspaceBrowser{flex-direction:column;height:100%;min-height:0;padding:0 8px 8px;display:flex}.d0xfxa_railButton{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;justify-content:center;align-items:center;padding:0;display:inline-flex}.d0xfxa_railButton:hover,.d0xfxa_railButton:focus-visible{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);outline:none}.d0xfxa_workspaceList{flex-direction:column;gap:2px;padding-bottom:2px;display:flex}.d0xfxa_workspaceRow{color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;background:0 0;border:0;border-radius:8px;align-items:center;gap:6px;width:100%;height:34px;padding:0 8px;display:flex}.d0xfxa_workspaceRow:hover,.d0xfxa_workspaceRow:focus-visible,.d0xfxa_workspaceRow[aria-current=page]{background:var(--dsw-alias-interactive-bg-hover);outline:none}.d0xfxa_workspaceRow:focus-visible{box-shadow:inset 0 0 0 1px var(--dsw-alias-border-l3)}.d0xfxa_workspaceIcon{color:var(--dsw-alias-label-tertiary);flex:0 0 16px;justify-content:center;align-items:center;height:20px;display:inline-flex}.d0xfxa_workspaceRow[data-selected] .d0xfxa_workspaceIcon{color:var(--dsw-alias-state-business-primary)}.d0xfxa_workspaceCopy{min-width:0;display:flex}.d0xfxa_workspaceCopy strong{text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:400;line-height:20px;overflow:hidden}.d0xfxa_emptyState{color:var(--dsw-alias-label-tertiary);margin:8px;font-size:12px;line-height:18px}.d0xfxa_railWorkspace{flex-direction:column;align-items:center;gap:8px;padding-top:8px;display:flex}.d0xfxa_railButton{border-radius:50%;width:36px;height:36px}.d0xfxa_railButton[data-active]{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.d0xfxa_workspaceSection{flex-direction:column;flex:1;gap:4px;min-height:0;margin-top:2px;display:flex;overflow-y:auto}.d0xfxa_section{flex-direction:column;display:flex}.d0xfxa_sectionHeader{align-items:center;min-height:26px;padding-right:2px;display:flex}.d0xfxa_sectionToggle{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;align-items:center;gap:4px;min-width:0;min-height:24px;padding:0 6px;font-size:12px;line-height:18px;display:inline-flex}.d0xfxa_sectionToggle:focus-visible{outline:none}.d0xfxa_sectionToggle:hover .d0xfxa_sectionChevron,.d0xfxa_sectionToggle:focus-visible .d0xfxa_sectionChevron{color:var(--dsw-alias-label-primary)}.d0xfxa_sectionChevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .12s,color .12s}.d0xfxa_sectionToggle[aria-expanded=false] .d0xfxa_sectionChevron{transform:rotate(-90deg)}.d0xfxa_sectionTitle{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.d0xfxa_sectionActions{align-items:center;margin-left:auto;display:inline-flex}.d0xfxa_panel{flex-direction:column;display:flex}.d0xfxa_iconButton{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:50%;justify-content:center;align-items:center;width:24px;height:24px;padding:0;display:inline-flex}.d0xfxa_iconButton:hover,.d0xfxa_iconButton:focus-visible{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);outline:none}.d0xfxa_textButton{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:5px;padding:2px 5px;font-size:11px;line-height:18px}.d0xfxa_textButton:hover,.d0xfxa_textButton:focus-visible{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);outline:none}.d0xfxa_textButton:disabled{cursor:not-allowed;opacity:.4}.d0xfxa_channelList,.d0xfxa_agentList{flex-direction:column;gap:1px;padding:0 4px 4px;display:flex}.d0xfxa_sidebarRowDragging{opacity:.5}.d0xfxa_sidebarRowDropBefore,.d0xfxa_sidebarRowDropAfter{position:relative}.d0xfxa_sidebarRowDropBefore:before,.d0xfxa_sidebarRowDropAfter:after{content:\"\";z-index:1;background:linear-gradient(55deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 0 / 5px 7px no-repeat, linear-gradient(125deg, transparent calc(50% - 1px), var(--dsw-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 5px / 5px 7px no-repeat, linear-gradient(var(--dsw-alias-state-business-primary) 0 0) 4px 5px / calc(100% - 4px) 2px no-repeat;pointer-events:none;height:12px;position:absolute;left:0;right:4px}.d0xfxa_sidebarRowDropBefore:before{top:-7px}.d0xfxa_sidebarRowDropAfter:after{bottom:-7px}.d0xfxa_channelRow{color:var(--dsw-alias-label-primary);border-radius:8px;align-items:center;min-height:30px;display:flex;position:relative}.d0xfxa_channelSelect{box-sizing:border-box;color:inherit;cursor:pointer;text-align:left;background:0 0;border:0;flex:1;align-items:center;min-width:0;min-height:30px;padding:3px 4px 3px 8px;display:flex}.d0xfxa_channelSelect:focus-visible{outline:none}.d0xfxa_channelName{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:400;line-height:18px;overflow:hidden}.d0xfxa_agentRow{color:var(--dsw-alias-label-primary);border-radius:8px;align-items:center;min-height:38px;display:flex;position:relative}.d0xfxa_agentSelect{box-sizing:border-box;color:inherit;cursor:pointer;text-align:left;background:0 0;border:0;flex:1;grid-template-columns:24px minmax(0,1fr);align-items:center;gap:0 8px;min-width:0;min-height:38px;padding:3px 4px 3px 8px;display:grid}.d0xfxa_agentSelect:focus-visible{outline:none}.d0xfxa_agentSelect[aria-current=page]{background:var(--dsw-alias-interactive-bg-hover);border-radius:8px}.d0xfxa_agentRow:hover .d0xfxa_agentSelect[aria-current=page],.d0xfxa_agentRow:focus-within .d0xfxa_agentSelect[aria-current=page],.d0xfxa_agentRow[data-menu-open] .d0xfxa_agentSelect[aria-current=page]{background:0 0}.d0xfxa_agentAvatar{background:hsl(var(--team-avatar-hue,212) 42% 46%);color:#fff;cursor:default;border-radius:50%;flex:0 0 24px;justify-content:center;align-items:center;width:24px;height:24px;font-size:11px;font-weight:600;display:inline-flex;position:relative}.d0xfxa_agentAvatarBadge{background:var(--dsw-specific-sidebar-fill);box-shadow:0 0 0 1px var(--dsw-specific-sidebar-fill);border-radius:50%;justify-content:center;align-items:center;width:12px;height:12px;padding:1px;line-height:0;display:inline-flex;position:absolute;bottom:-3px;right:-3px}.d0xfxa_agentCopy{flex-direction:column;min-width:0;display:flex}.d0xfxa_agentCopy strong{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:400;line-height:17px;overflow:hidden}.d0xfxa_agentCopy small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:13px;overflow:hidden}.d0xfxa_unavailableDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;width:7px;height:7px;display:inline-block}.d0xfxa_rowMenu{flex:none;align-items:center;padding-right:4px;display:none}.d0xfxa_channelRow:hover .d0xfxa_rowMenu,.d0xfxa_channelRow:focus-within .d0xfxa_rowMenu,.d0xfxa_channelRow[data-menu-open] .d0xfxa_rowMenu,.d0xfxa_agentRow:hover .d0xfxa_rowMenu,.d0xfxa_agentRow:focus-within .d0xfxa_rowMenu,.d0xfxa_agentRow[data-menu-open] .d0xfxa_rowMenu{display:inline-flex}.d0xfxa_channelRow[data-menu-open],.d0xfxa_agentRow[data-menu-open],.d0xfxa_channelRow:hover,.d0xfxa_agentRow:hover,.d0xfxa_channelRow:focus-within,.d0xfxa_agentRow:focus-within,.d0xfxa_channelRow[aria-current=page]{background:var(--dsw-alias-interactive-bg-hover)}.d0xfxa_rowMenuButton{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;justify-content:center;align-items:center;width:20px;height:20px;padding:0;display:inline-flex}.d0xfxa_rowMenuButton:hover,.d0xfxa_rowMenuButton:focus-visible{color:var(--dsw-alias-label-primary);outline:none}.d0xfxa_retryError{color:var(--dsw-alias-state-error-primary);justify-content:space-between;align-items:center;gap:8px;padding:8px;font-size:11px;display:flex}.d0xfxa_rowAlert{color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;padding:2px 8px 6px;font-size:11px}.d0xfxa_editDescription{color:var(--dsw-alias-label-secondary);margin:0 0 10px;font-size:12px;line-height:18px}.d0xfxa_editMemberList{gap:3px;display:grid}.d0xfxa_editMemberRow{border-radius:6px;grid-template-columns:14px minmax(0,1fr) auto;align-items:center;gap:0 8px;min-height:40px;padding:3px 6px;display:grid}.d0xfxa_editMemberRowChannels{grid-template-columns:minmax(0,1fr) auto}.d0xfxa_editMemberRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.d0xfxa_editMemberCopy{min-width:0;display:grid}.d0xfxa_editMemberCopy strong{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:500;line-height:18px;overflow:hidden}.d0xfxa_editMemberCopy small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:14px;overflow:hidden}.d0xfxa_editChannelName{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:400;line-height:18px;overflow:hidden}.d0xfxa_editMemberRow button{min-width:60px}.d0xfxa_editHint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:11px;line-height:16px}.d0xfxa_menuHint{color:var(--dsw-alias-label-tertiary);margin-left:4px;font-size:10px;line-height:14px}.d0xfxa_rowError{color:var(--dsw-alias-state-error-primary);grid-column:1/-1;margin:2px 0;font-size:11px;line-height:16px}";
|
|
9773
|
-
const tagId$1 = "@wowyuarm/dsh-agent-team/sidebar.module.css";
|
|
9774
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
9775
|
-
const tag = document.createElement("style");
|
|
9776
|
-
tag.dataset.plugin = "@wowyuarm/dsh-agent-team";
|
|
9777
|
-
tag.dataset.pluginCss = tagId$1;
|
|
9778
|
-
tag.textContent = css$1;
|
|
9779
|
-
document.head.appendChild(tag);
|
|
9780
|
-
}
|
|
9781
|
-
var sidebar_module_css_default = {
|
|
9782
|
-
"agentAvatar": "d0xfxa_agentAvatar",
|
|
9783
|
-
"agentAvatarBadge": "d0xfxa_agentAvatarBadge",
|
|
9784
|
-
"agentCopy": "d0xfxa_agentCopy",
|
|
9785
|
-
"agentList": "d0xfxa_agentList",
|
|
9786
|
-
"agentRow": "d0xfxa_agentRow",
|
|
9787
|
-
"agentSelect": "d0xfxa_agentSelect",
|
|
9788
|
-
"channelList": "d0xfxa_channelList",
|
|
9789
|
-
"channelName": "d0xfxa_channelName",
|
|
9790
|
-
"channelRow": "d0xfxa_channelRow",
|
|
9791
|
-
"channelSelect": "d0xfxa_channelSelect",
|
|
9792
|
-
"editChannelName": "d0xfxa_editChannelName",
|
|
9793
|
-
"editDescription": "d0xfxa_editDescription",
|
|
9794
|
-
"editHint": "d0xfxa_editHint",
|
|
9795
|
-
"editMemberCopy": "d0xfxa_editMemberCopy",
|
|
9796
|
-
"editMemberList": "d0xfxa_editMemberList",
|
|
9797
|
-
"editMemberRow": "d0xfxa_editMemberRow",
|
|
9798
|
-
"editMemberRowChannels": "d0xfxa_editMemberRowChannels",
|
|
9799
|
-
"emptyState": "d0xfxa_emptyState",
|
|
9800
|
-
"iconButton": "d0xfxa_iconButton",
|
|
9801
|
-
"menuHint": "d0xfxa_menuHint",
|
|
9802
|
-
"panel": "d0xfxa_panel",
|
|
9803
|
-
"railButton": "d0xfxa_railButton",
|
|
9804
|
-
"railWorkspace": "d0xfxa_railWorkspace",
|
|
9805
|
-
"retryError": "d0xfxa_retryError",
|
|
9806
|
-
"rowAlert": "d0xfxa_rowAlert",
|
|
9807
|
-
"rowError": "d0xfxa_rowError",
|
|
9808
|
-
"rowMenu": "d0xfxa_rowMenu",
|
|
9809
|
-
"rowMenuButton": "d0xfxa_rowMenuButton",
|
|
9810
|
-
"section": "d0xfxa_section",
|
|
9811
|
-
"sectionActions": "d0xfxa_sectionActions",
|
|
9812
|
-
"sectionChevron": "d0xfxa_sectionChevron",
|
|
9813
|
-
"sectionHeader": "d0xfxa_sectionHeader",
|
|
9814
|
-
"sectionTitle": "d0xfxa_sectionTitle",
|
|
9815
|
-
"sectionToggle": "d0xfxa_sectionToggle",
|
|
9816
|
-
"sidebarRowDragging": "d0xfxa_sidebarRowDragging",
|
|
9817
|
-
"sidebarRowDropAfter": "d0xfxa_sidebarRowDropAfter",
|
|
9818
|
-
"sidebarRowDropBefore": "d0xfxa_sidebarRowDropBefore",
|
|
9819
|
-
"textButton": "d0xfxa_textButton",
|
|
9820
|
-
"unavailableDot": "d0xfxa_unavailableDot",
|
|
9821
|
-
"workspaceBrowser": "d0xfxa_workspaceBrowser",
|
|
9822
|
-
"workspaceCopy": "d0xfxa_workspaceCopy",
|
|
9823
|
-
"workspaceIcon": "d0xfxa_workspaceIcon",
|
|
9824
|
-
"workspaceList": "d0xfxa_workspaceList",
|
|
9825
|
-
"workspaceRow": "d0xfxa_workspaceRow",
|
|
9826
|
-
"workspaceSection": "d0xfxa_workspaceSection"
|
|
9827
|
-
};
|
|
9828
|
-
//#endregion
|
|
9829
10852
|
//#region src/client/TeamWorkspaceRow.tsx
|
|
9830
10853
|
function TeamWorkspaceRow({ workspaceId, title, path, selected, current, onSelect }) {
|
|
9831
10854
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
@@ -9960,32 +10983,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9960
10983
|
for (const listener of listeners$1) listener();
|
|
9961
10984
|
}
|
|
9962
10985
|
//#endregion
|
|
9963
|
-
//#region src/client/TeamMemberAvatar.tsx
|
|
9964
|
-
/**
|
|
9965
|
-
* Sidebar Member avatar reusing the conversation identity language: the
|
|
9966
|
-
* deterministic member hue and handle initial, with the presence indicator
|
|
9967
|
-
* overlaid at the bottom-right so one glyph carries identity and state.
|
|
9968
|
-
*/
|
|
9969
|
-
function TeamMemberAvatar({ status, t }) {
|
|
9970
|
-
const label = presenceLabel(status, t);
|
|
9971
|
-
const state = presenceDotState(status.presence);
|
|
9972
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
9973
|
-
label,
|
|
9974
|
-
delayMs: 300,
|
|
9975
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
9976
|
-
className: sidebar_module_css_default.agentAvatar,
|
|
9977
|
-
style: { "--team-avatar-hue": memberHue(status.member.memberId) },
|
|
9978
|
-
role: "img",
|
|
9979
|
-
"aria-label": label,
|
|
9980
|
-
children: [status.member.handle.replace("@", "").slice(0, 1).toUpperCase(), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9981
|
-
className: sidebar_module_css_default.agentAvatarBadge,
|
|
9982
|
-
"aria-hidden": "true",
|
|
9983
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamStateDot, { state })
|
|
9984
|
-
})]
|
|
9985
|
-
})
|
|
9986
|
-
});
|
|
9987
|
-
}
|
|
9988
|
-
//#endregion
|
|
9989
10986
|
//#region src/client/sidebar-drag.tsx
|
|
9990
10987
|
/**
|
|
9991
10988
|
* Native whole-row drag for the Team sidebar lists. Unlike the Harness
|
|
@@ -10260,8 +11257,45 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
10260
11257
|
});
|
|
10261
11258
|
}
|
|
10262
11259
|
//#endregion
|
|
11260
|
+
//#region src/client/team-dialog-save.ts
|
|
11261
|
+
/**
|
|
11262
|
+
* Shared edit-dialog save lifecycle: one in-flight durable update, the dialog
|
|
11263
|
+
* held disabled while it runs, a refusal reported in place, and a close only
|
|
11264
|
+
* after the parent has re-read the committed state. Callers keep their own
|
|
11265
|
+
* payload and request reuse, and hold `pendingRequest` so that editing a field
|
|
11266
|
+
* drops a request the Host may already have committed.
|
|
11267
|
+
*/
|
|
11268
|
+
function useEditDialogSave({ save, onCommitted, onClose }) {
|
|
11269
|
+
const [saving, setSaving] = (0, react.useState)(false);
|
|
11270
|
+
const [error, setError] = (0, react.useState)();
|
|
11271
|
+
const pendingRequest = (0, react.useRef)();
|
|
11272
|
+
const submit = async (request) => {
|
|
11273
|
+
pendingRequest.current = request;
|
|
11274
|
+
setSaving(true);
|
|
11275
|
+
setError(void 0);
|
|
11276
|
+
try {
|
|
11277
|
+
const result = await save(request);
|
|
11278
|
+
if (result.ok) {
|
|
11279
|
+
pendingRequest.current = void 0;
|
|
11280
|
+
await onCommitted();
|
|
11281
|
+
onClose();
|
|
11282
|
+
} else setError(result.error.message);
|
|
11283
|
+
} catch (cause) {
|
|
11284
|
+
setError(cause instanceof Error ? cause.message : String(cause));
|
|
11285
|
+
} finally {
|
|
11286
|
+
setSaving(false);
|
|
11287
|
+
}
|
|
11288
|
+
};
|
|
11289
|
+
return {
|
|
11290
|
+
saving,
|
|
11291
|
+
error,
|
|
11292
|
+
pendingRequest,
|
|
11293
|
+
save: submit
|
|
11294
|
+
};
|
|
11295
|
+
}
|
|
11296
|
+
//#endregion
|
|
10263
11297
|
//#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/create.module.css.mjs
|
|
10264
|
-
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}}";
|
|
11298
|
+
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);corner-shape:round;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}}";
|
|
10265
11299
|
const tagId = "@wowyuarm/dsh-agent-team/create.module.css";
|
|
10266
11300
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
10267
11301
|
const tag = document.createElement("style");
|
|
@@ -10454,9 +11488,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
10454
11488
|
const [handle, setHandle] = (0, react.useState)(status.member.handle);
|
|
10455
11489
|
const [description, setDescription] = (0, react.useState)(status.member.description);
|
|
10456
11490
|
const [model, setModel] = (0, react.useState)(status.member.model);
|
|
10457
|
-
const
|
|
10458
|
-
|
|
10459
|
-
|
|
11491
|
+
const { saving, error, pendingRequest, save } = useEditDialogSave({
|
|
11492
|
+
save: updateMember,
|
|
11493
|
+
onCommitted,
|
|
11494
|
+
onClose
|
|
11495
|
+
});
|
|
10460
11496
|
const dirty = handle.trim() !== status.member.handle || description.trim() !== status.member.description || !sameModel(model, status.member.model);
|
|
10461
11497
|
const submit = async (event) => {
|
|
10462
11498
|
event.preventDefault();
|
|
@@ -10470,25 +11506,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
10470
11506
|
...model === void 0 ? {} : { model },
|
|
10471
11507
|
...status.member.capabilities === void 0 ? {} : { capabilities: status.member.capabilities }
|
|
10472
11508
|
};
|
|
10473
|
-
|
|
11509
|
+
await save(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 : {
|
|
10474
11510
|
requestId: mintRequestId(),
|
|
10475
11511
|
...payload
|
|
10476
|
-
};
|
|
10477
|
-
pendingRequest.current = request;
|
|
10478
|
-
setSaving(true);
|
|
10479
|
-
setError(void 0);
|
|
10480
|
-
try {
|
|
10481
|
-
const result = await updateMember(request);
|
|
10482
|
-
if (result.ok) {
|
|
10483
|
-
pendingRequest.current = void 0;
|
|
10484
|
-
await onCommitted();
|
|
10485
|
-
onClose();
|
|
10486
|
-
} else setError(result.error.message);
|
|
10487
|
-
} catch (cause) {
|
|
10488
|
-
setError(cause instanceof Error ? cause.message : String(cause));
|
|
10489
|
-
} finally {
|
|
10490
|
-
setSaving(false);
|
|
10491
|
-
}
|
|
11512
|
+
});
|
|
10492
11513
|
};
|
|
10493
11514
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
10494
11515
|
open: true,
|
|
@@ -10623,14 +11644,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
10623
11644
|
}
|
|
10624
11645
|
}
|
|
10625
11646
|
}, []);
|
|
11647
|
+
const loadedRef = (0, react.useRef)(false);
|
|
10626
11648
|
const refresh = (0, react.useCallback)(async () => {
|
|
10627
|
-
setLoading(true);
|
|
11649
|
+
if (!loadedRef.current) setLoading(true);
|
|
10628
11650
|
const result = await loadMembers({ workspaceId });
|
|
10629
11651
|
if (result.ok) {
|
|
10630
11652
|
const next = result.value.filter((status) => status.member.state !== "inactive" && status.member.state !== "archived");
|
|
10631
11653
|
setMembers(next);
|
|
10632
11654
|
followRollover(next);
|
|
10633
11655
|
setError(void 0);
|
|
11656
|
+
loadedRef.current = true;
|
|
10634
11657
|
} else setError(result.error.message);
|
|
10635
11658
|
setLoading(false);
|
|
10636
11659
|
}, [
|
|
@@ -10655,6 +11678,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
10655
11678
|
refresh,
|
|
10656
11679
|
workspaceId
|
|
10657
11680
|
]);
|
|
11681
|
+
(0, react.useEffect)(() => subscribeChanges({
|
|
11682
|
+
kind: "presence",
|
|
11683
|
+
workspaceId
|
|
11684
|
+
}, (update) => {
|
|
11685
|
+
if (update.type === "failed") {
|
|
11686
|
+
setError(update.message);
|
|
11687
|
+
return;
|
|
11688
|
+
}
|
|
11689
|
+
refresh();
|
|
11690
|
+
}), [
|
|
11691
|
+
subscribeChanges,
|
|
11692
|
+
refresh,
|
|
11693
|
+
workspaceId
|
|
11694
|
+
]);
|
|
10658
11695
|
const closeForm = () => {
|
|
10659
11696
|
if (creating) return;
|
|
10660
11697
|
setFormOpen(false);
|
|
@@ -10678,7 +11715,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
10678
11715
|
setDescription("");
|
|
10679
11716
|
setModel(void 0);
|
|
10680
11717
|
setFormOpen(false);
|
|
10681
|
-
if (result.value.status.presence === "unavailable") setError(result.value.status
|
|
11718
|
+
if (result.value.status.presence === "unavailable") setError(diagnosticText(result.value.status) || t("statusUnavailable"));
|
|
10682
11719
|
else setRetryRequest(void 0);
|
|
10683
11720
|
queueMicrotask(() => {
|
|
10684
11721
|
triggerRef.current?.focus();
|
|
@@ -10805,7 +11842,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
10805
11842
|
className: sidebar_module_css_default.emptyState,
|
|
10806
11843
|
children: t("loadingAgents")
|
|
10807
11844
|
}),
|
|
10808
|
-
!loading && members.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
11845
|
+
!loading && error === void 0 && members.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
10809
11846
|
className: sidebar_module_css_default.emptyState,
|
|
10810
11847
|
children: t("emptyAgents")
|
|
10811
11848
|
}),
|
|
@@ -10870,7 +11907,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
10870
11907
|
return;
|
|
10871
11908
|
}
|
|
10872
11909
|
if (result.value.status.availability === "unavailable") {
|
|
10873
|
-
|
|
11910
|
+
const diagnostic = result.value.status.diagnostic;
|
|
11911
|
+
if (diagnostic?.class === "session-refused" && diagnostic.remediable === false) {
|
|
11912
|
+
setRowAlert(t("restartRefusedNoRestart", { detail: diagnosticText(result.value.status) }));
|
|
11913
|
+
return;
|
|
11914
|
+
}
|
|
11915
|
+
setRowAlert(t("restartStillUnavailable", { diagnostic: diagnosticText(result.value.status) || t("statusUnavailable") }));
|
|
10874
11916
|
return;
|
|
10875
11917
|
}
|
|
10876
11918
|
setRowAlert(void 0);
|
|
@@ -10894,8 +11936,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
10894
11936
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
10895
11937
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
10896
11938
|
className: sidebar_module_css_default.agentRow,
|
|
11939
|
+
"data-agent-row": true,
|
|
10897
11940
|
"data-menu-open": menuOpen || void 0,
|
|
10898
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
11941
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
10899
11942
|
type: "button",
|
|
10900
11943
|
className: sidebar_module_css_default.agentSelect,
|
|
10901
11944
|
"aria-label": t("openAgentSession", { name: status.member.handle }),
|
|
@@ -10904,13 +11947,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
10904
11947
|
onClick: () => {
|
|
10905
11948
|
openMemberSession(status.member.sessionId);
|
|
10906
11949
|
},
|
|
10907
|
-
children:
|
|
11950
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamMemberIdentity, {
|
|
10908
11951
|
status,
|
|
10909
|
-
|
|
10910
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
11952
|
+
name: status.member.handle.replace(/^@/, ""),
|
|
10911
11953
|
className: sidebar_module_css_default.agentCopy,
|
|
10912
|
-
|
|
10913
|
-
})
|
|
11954
|
+
t
|
|
11955
|
+
})
|
|
10914
11956
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
10915
11957
|
className: sidebar_module_css_default.rowMenu,
|
|
10916
11958
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamRowMenu, {
|
|
@@ -10926,7 +11968,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
10926
11968
|
label: t("resumeAgent"),
|
|
10927
11969
|
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlayOutline16, {})
|
|
10928
11970
|
}] : [],
|
|
10929
|
-
...status.availability === "unavailable" ? [{
|
|
11971
|
+
...status.availability === "unavailable" && restartOffered(status) ? [{
|
|
10930
11972
|
id: "restart",
|
|
10931
11973
|
label: t("restartAgent"),
|
|
10932
11974
|
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutline16, {})
|
|
@@ -11083,8 +12125,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
11083
12125
|
onCommit: applyMove
|
|
11084
12126
|
});
|
|
11085
12127
|
const sectionOpen = useSidebarSectionOpen(workspaceId, "channels");
|
|
12128
|
+
const loadedRef = (0, react.useRef)(false);
|
|
11086
12129
|
const refresh = (0, react.useCallback)(async () => {
|
|
11087
|
-
setLoading(true);
|
|
12130
|
+
if (!loadedRef.current) setLoading(true);
|
|
11088
12131
|
const [channelResult, memberResult] = await Promise.all([loadChannels({
|
|
11089
12132
|
workspaceId,
|
|
11090
12133
|
limit: 1
|
|
@@ -11096,6 +12139,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
11096
12139
|
const selectable = new Set(visibleMembers.filter((status) => status.presence !== "unavailable").map((status) => status.member.memberId));
|
|
11097
12140
|
setSelected((current) => new Set([...current].filter((memberId) => selectable.has(memberId))));
|
|
11098
12141
|
setError(void 0);
|
|
12142
|
+
loadedRef.current = true;
|
|
11099
12143
|
} else if (!channelResult.ok) setError(channelResult.error.message);
|
|
11100
12144
|
else if (!memberResult.ok) setError(memberResult.error.message);
|
|
11101
12145
|
setLoading(false);
|
|
@@ -11299,7 +12343,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
11299
12343
|
className: sidebar_module_css_default.emptyState,
|
|
11300
12344
|
children: t("loadingChannels")
|
|
11301
12345
|
}),
|
|
11302
|
-
!loading &&
|
|
12346
|
+
!loading && error === void 0 && view !== void 0 && view.channels.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
11303
12347
|
className: sidebar_module_css_default.emptyState,
|
|
11304
12348
|
children: t("emptyChannels")
|
|
11305
12349
|
}),
|
|
@@ -11452,9 +12496,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
11452
12496
|
function ChannelEditorDialog({ channel, members, joinedIds, updateChannel, joinChannel, removeChannelMember, onCommitted, onClose, t }) {
|
|
11453
12497
|
const [name, setName] = (0, react.useState)(channel.name);
|
|
11454
12498
|
const [description, setDescription] = (0, react.useState)(channel.description);
|
|
11455
|
-
const
|
|
11456
|
-
|
|
11457
|
-
|
|
12499
|
+
const { saving, error, pendingRequest, save } = useEditDialogSave({
|
|
12500
|
+
save: updateChannel,
|
|
12501
|
+
onCommitted,
|
|
12502
|
+
onClose
|
|
12503
|
+
});
|
|
11458
12504
|
const membership = useChannelMembership({
|
|
11459
12505
|
joinChannel,
|
|
11460
12506
|
removeChannelMember
|
|
@@ -11467,28 +12513,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
11467
12513
|
const normalizedName = name.trim();
|
|
11468
12514
|
const normalizedDescription = description.trim();
|
|
11469
12515
|
if (saving || !dirty || normalizedName === "") return;
|
|
11470
|
-
|
|
12516
|
+
await save(pendingRequest.current !== void 0 && pendingRequest.current.channelRef === channel.channelRef && pendingRequest.current.name === normalizedName && pendingRequest.current.description === normalizedDescription ? pendingRequest.current : {
|
|
11471
12517
|
requestId: mintRequestId(),
|
|
11472
12518
|
workspaceId: channel.workspaceId,
|
|
11473
12519
|
channelRef: channel.channelRef,
|
|
11474
12520
|
name: normalizedName,
|
|
11475
12521
|
description: normalizedDescription
|
|
11476
|
-
};
|
|
11477
|
-
pendingRequest.current = request;
|
|
11478
|
-
setSaving(true);
|
|
11479
|
-
setError(void 0);
|
|
11480
|
-
try {
|
|
11481
|
-
const result = await updateChannel(request);
|
|
11482
|
-
if (result.ok) {
|
|
11483
|
-
pendingRequest.current = void 0;
|
|
11484
|
-
await onCommitted();
|
|
11485
|
-
onClose();
|
|
11486
|
-
} else setError(result.error.message);
|
|
11487
|
-
} catch (cause) {
|
|
11488
|
-
setError(cause instanceof Error ? cause.message : String(cause));
|
|
11489
|
-
} finally {
|
|
11490
|
-
setSaving(false);
|
|
11491
|
-
}
|
|
12522
|
+
});
|
|
11492
12523
|
};
|
|
11493
12524
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
11494
12525
|
open: true,
|
|
@@ -11548,39 +12579,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
11548
12579
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", { children: t("channelMembersSection") }), members.map((status) => {
|
|
11549
12580
|
const joined = joinedIds.has(status.member.memberId);
|
|
11550
12581
|
const rowPending = membership.pending.has(status.member.memberId);
|
|
11551
|
-
const disabled = rowPending || !joined && status.
|
|
12582
|
+
const disabled = rowPending || !joined && status.availability !== "active";
|
|
11552
12583
|
const rowError = membership.errors.get(status.member.memberId);
|
|
11553
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.
|
|
11554
|
-
|
|
11555
|
-
|
|
11556
|
-
|
|
11557
|
-
|
|
11558
|
-
|
|
11559
|
-
|
|
11560
|
-
|
|
11561
|
-
|
|
11562
|
-
|
|
11563
|
-
|
|
11564
|
-
|
|
11565
|
-
|
|
11566
|
-
|
|
11567
|
-
|
|
11568
|
-
|
|
11569
|
-
membership.change({
|
|
11570
|
-
workspaceId: channel.workspaceId,
|
|
11571
|
-
channelRef: channel.channelRef,
|
|
11572
|
-
memberId: status.member.memberId,
|
|
11573
|
-
joined
|
|
11574
|
-
});
|
|
11575
|
-
},
|
|
11576
|
-
children: rowPending ? t("membershipUpdating") : joined ? t("removeFromChannel") : t("addToChannel")
|
|
11577
|
-
}),
|
|
11578
|
-
rowError !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
11579
|
-
className: sidebar_module_css_default.rowError,
|
|
11580
|
-
role: "alert",
|
|
11581
|
-
children: rowError
|
|
11582
|
-
})
|
|
11583
|
-
]
|
|
12584
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamMemberRow, {
|
|
12585
|
+
status,
|
|
12586
|
+
action: {
|
|
12587
|
+
label: rowPending ? t("membershipUpdating") : joined ? t("removeFromChannel") : t("addToChannel"),
|
|
12588
|
+
disabled,
|
|
12589
|
+
onSelect: () => {
|
|
12590
|
+
membership.change({
|
|
12591
|
+
workspaceId: channel.workspaceId,
|
|
12592
|
+
channelRef: channel.channelRef,
|
|
12593
|
+
memberId: status.member.memberId,
|
|
12594
|
+
joined
|
|
12595
|
+
});
|
|
12596
|
+
}
|
|
12597
|
+
},
|
|
12598
|
+
...rowError === void 0 ? {} : { error: rowError },
|
|
12599
|
+
t
|
|
11584
12600
|
}, status.member.memberId);
|
|
11585
12601
|
})]
|
|
11586
12602
|
}),
|
|
@@ -11595,20 +12611,78 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
11595
12611
|
}
|
|
11596
12612
|
//#endregion
|
|
11597
12613
|
//#region src/client/TeamWorkspaceBrowser.tsx
|
|
11598
|
-
|
|
12614
|
+
/**
|
|
12615
|
+
* The Inbox entry's icon with its unread mark. The quantity left this surface
|
|
12616
|
+
* and lives in the control's accessible name: the sidebar answers whether
|
|
12617
|
+
* anything is waiting at a glance, and the number — which moves on every fact —
|
|
12618
|
+
* is what a reader asks for on purpose. The mark hangs off the icon rather than
|
|
12619
|
+
* off the control, so the wide card and the 36px rail button put the same dot
|
|
12620
|
+
* on the same corner of the same glyph.
|
|
12621
|
+
*/
|
|
12622
|
+
function InboxMark({ unread }) {
|
|
12623
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
12624
|
+
className: sidebar_module_css_default.inboxMark,
|
|
12625
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconQueueOutline14, { size: 16 }), unread > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12626
|
+
className: sidebar_module_css_default.inboxDot,
|
|
12627
|
+
"data-team-inbox-dot": true,
|
|
12628
|
+
"aria-hidden": "true"
|
|
12629
|
+
})]
|
|
12630
|
+
});
|
|
12631
|
+
}
|
|
12632
|
+
function TeamWorkspaceBrowser({ wide, expandSidebar, navigation, selectWorkspace, selectChannel, selectInbox, t, useWorkspaces, loadMembers, loadInbox, subscribeChanges, subscribeReads, addMember, loadChannels, createChannel, updateChannel, archiveChannel, updateMember, recoverMember, archiveMember, joinChannel, removeChannelMember, loadModels, openMemberSession }) {
|
|
11599
12633
|
const navigationState = (0, react.useSyncExternalStore)(navigation.subscribe, navigation.getSnapshot, navigation.getSnapshot);
|
|
11600
12634
|
const workspaces = useWorkspaces((state) => state.items);
|
|
11601
12635
|
const selected = navigationState.workspaceId;
|
|
11602
12636
|
const selectedId = selected !== void 0 && workspaces.some((workspace) => workspace.workspaceId === selected) ? selected : workspaces[0]?.workspaceId;
|
|
11603
|
-
const overviewIsCurrent = navigationState.channelRef === void 0 && navigationState.memberSessionId === void 0;
|
|
12637
|
+
const overviewIsCurrent = navigationState.channelRef === void 0 && navigationState.memberSessionId === void 0 && navigationState.inbox !== true;
|
|
12638
|
+
const inboxIsCurrent = navigationState.inbox === true && navigationState.memberSessionId === void 0;
|
|
11604
12639
|
const [creatingAgents, setCreatingAgents] = (0, react.useState)([]);
|
|
11605
12640
|
const [pendingSection, setPendingSection] = (0, react.useState)();
|
|
11606
12641
|
const channelsRef = (0, react.useRef)(null);
|
|
11607
12642
|
const agentsRef = (0, react.useRef)(null);
|
|
11608
12643
|
const workspacesOpen = useSidebarSectionOpen(void 0, "workspaces");
|
|
12644
|
+
const [inboxTotal, setInboxTotal] = (0, react.useState)(0);
|
|
12645
|
+
const inboxLabel = inboxTotal > 0 ? t("inboxTitleWithCount", { count: inboxTotal }) : t("inboxTitle");
|
|
12646
|
+
(0, react.useEffect)(() => {
|
|
12647
|
+
let disposed = false;
|
|
12648
|
+
let scheduled;
|
|
12649
|
+
const refresh = async () => {
|
|
12650
|
+
const results = await Promise.all(workspaces.map((workspace) => loadInbox({
|
|
12651
|
+
workspaceId: workspace.workspaceId,
|
|
12652
|
+
limit: 1
|
|
12653
|
+
})));
|
|
12654
|
+
if (disposed) return;
|
|
12655
|
+
setInboxTotal(results.reduce((sum, result) => result.ok ? sum + result.value.totalUnreadCount : sum, 0));
|
|
12656
|
+
};
|
|
12657
|
+
const schedule = () => {
|
|
12658
|
+
if (scheduled !== void 0) return;
|
|
12659
|
+
scheduled = setTimeout(() => {
|
|
12660
|
+
scheduled = void 0;
|
|
12661
|
+
refresh();
|
|
12662
|
+
}, 200);
|
|
12663
|
+
};
|
|
12664
|
+
refresh();
|
|
12665
|
+
const unsubscribe = subscribeChanges(void 0, (update) => {
|
|
12666
|
+
if (update.type === "changed") schedule();
|
|
12667
|
+
});
|
|
12668
|
+
const unsubscribeReads = subscribeReads(schedule);
|
|
12669
|
+
return () => {
|
|
12670
|
+
disposed = true;
|
|
12671
|
+
if (scheduled !== void 0) clearTimeout(scheduled);
|
|
12672
|
+
unsubscribe();
|
|
12673
|
+
unsubscribeReads();
|
|
12674
|
+
};
|
|
12675
|
+
}, [
|
|
12676
|
+
loadInbox,
|
|
12677
|
+
subscribeChanges,
|
|
12678
|
+
subscribeReads,
|
|
12679
|
+
workspaces
|
|
12680
|
+
]);
|
|
11609
12681
|
(0, react.useEffect)(() => {
|
|
12682
|
+
if (navigationState.inbox === true) return;
|
|
11610
12683
|
if (navigationState.mode === "team" && selectedId !== void 0 && selectedId !== selected) selectWorkspace(selectedId);
|
|
11611
12684
|
}, [
|
|
12685
|
+
navigationState.inbox,
|
|
11612
12686
|
navigationState.mode,
|
|
11613
12687
|
selected,
|
|
11614
12688
|
selectedId,
|
|
@@ -11625,96 +12699,128 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
11625
12699
|
if (!wide) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
|
|
11626
12700
|
className: sidebar_module_css_default.railWorkspace,
|
|
11627
12701
|
"aria-label": t("workspaceSections"),
|
|
11628
|
-
children: [
|
|
11629
|
-
|
|
11630
|
-
|
|
11631
|
-
|
|
11632
|
-
|
|
11633
|
-
|
|
11634
|
-
|
|
11635
|
-
|
|
11636
|
-
|
|
11637
|
-
|
|
11638
|
-
|
|
11639
|
-
|
|
11640
|
-
|
|
11641
|
-
|
|
11642
|
-
|
|
11643
|
-
|
|
11644
|
-
|
|
11645
|
-
|
|
11646
|
-
|
|
11647
|
-
|
|
11648
|
-
|
|
11649
|
-
|
|
11650
|
-
|
|
11651
|
-
|
|
11652
|
-
|
|
12702
|
+
children: [
|
|
12703
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
12704
|
+
label: inboxLabel,
|
|
12705
|
+
side: "right",
|
|
12706
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12707
|
+
type: "button",
|
|
12708
|
+
className: sidebar_module_css_default.railButton,
|
|
12709
|
+
"aria-label": inboxLabel,
|
|
12710
|
+
"aria-current": inboxIsCurrent ? "page" : void 0,
|
|
12711
|
+
onClick: () => {
|
|
12712
|
+
selectInbox();
|
|
12713
|
+
expandSidebar();
|
|
12714
|
+
},
|
|
12715
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InboxMark, { unread: inboxTotal })
|
|
12716
|
+
})
|
|
12717
|
+
}),
|
|
12718
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
12719
|
+
label: t("channels"),
|
|
12720
|
+
side: "right",
|
|
12721
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12722
|
+
type: "button",
|
|
12723
|
+
className: sidebar_module_css_default.railButton,
|
|
12724
|
+
"aria-label": t("channels"),
|
|
12725
|
+
onClick: () => {
|
|
12726
|
+
setPendingSection("channels");
|
|
12727
|
+
expandSidebar();
|
|
12728
|
+
},
|
|
12729
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconListPenOutline16, { size: 16 })
|
|
12730
|
+
})
|
|
12731
|
+
}),
|
|
12732
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
12733
|
+
label: t("agents"),
|
|
12734
|
+
side: "right",
|
|
12735
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12736
|
+
type: "button",
|
|
12737
|
+
className: sidebar_module_css_default.railButton,
|
|
12738
|
+
"aria-label": t("agents"),
|
|
12739
|
+
onClick: () => {
|
|
12740
|
+
setPendingSection("agents");
|
|
12741
|
+
expandSidebar();
|
|
12742
|
+
},
|
|
12743
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconAgentPresetOutline16, { size: 16 })
|
|
12744
|
+
})
|
|
11653
12745
|
})
|
|
11654
|
-
|
|
12746
|
+
]
|
|
11655
12747
|
});
|
|
11656
12748
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
11657
12749
|
className: sidebar_module_css_default.workspaceBrowser,
|
|
11658
12750
|
"aria-label": t("workspaces"),
|
|
11659
|
-
children: [
|
|
11660
|
-
|
|
11661
|
-
|
|
11662
|
-
|
|
11663
|
-
|
|
11664
|
-
|
|
11665
|
-
|
|
11666
|
-
|
|
11667
|
-
|
|
11668
|
-
|
|
11669
|
-
|
|
11670
|
-
|
|
11671
|
-
|
|
11672
|
-
|
|
11673
|
-
|
|
11674
|
-
|
|
11675
|
-
|
|
11676
|
-
|
|
12751
|
+
children: [
|
|
12752
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
12753
|
+
type: "button",
|
|
12754
|
+
className: sidebar_module_css_default.inboxCard,
|
|
12755
|
+
"aria-label": inboxLabel,
|
|
12756
|
+
"aria-current": inboxIsCurrent ? "page" : void 0,
|
|
12757
|
+
onClick: selectInbox,
|
|
12758
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(InboxMark, { unread: inboxTotal }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12759
|
+
className: sidebar_module_css_default.inboxCardLabel,
|
|
12760
|
+
children: t("inboxTitle")
|
|
12761
|
+
})]
|
|
12762
|
+
}),
|
|
12763
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamSidebarSection, {
|
|
12764
|
+
title: t("workspaces"),
|
|
12765
|
+
open: workspacesOpen,
|
|
12766
|
+
onToggle: (open) => {
|
|
12767
|
+
setSidebarSectionOpen(void 0, "workspaces", open);
|
|
12768
|
+
},
|
|
12769
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12770
|
+
className: sidebar_module_css_default.workspaceList,
|
|
12771
|
+
children: [workspaces.map((workspace) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamWorkspaceRow, {
|
|
12772
|
+
workspaceId: workspace.workspaceId,
|
|
12773
|
+
title: workspace.title,
|
|
12774
|
+
path: workspace.path,
|
|
12775
|
+
selected: workspace.workspaceId === selectedId,
|
|
12776
|
+
current: workspace.workspaceId === selectedId && overviewIsCurrent,
|
|
12777
|
+
onSelect: selectWorkspace
|
|
12778
|
+
}, workspace.workspaceId)), workspaces.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
12779
|
+
className: sidebar_module_css_default.emptyState,
|
|
12780
|
+
children: t("empty")
|
|
12781
|
+
})]
|
|
12782
|
+
})
|
|
12783
|
+
}),
|
|
12784
|
+
selectedId !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12785
|
+
className: sidebar_module_css_default.workspaceSection,
|
|
12786
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12787
|
+
ref: channelsRef,
|
|
12788
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamChannelsPanel, {
|
|
12789
|
+
workspaceId: selectedId,
|
|
12790
|
+
loadMembers,
|
|
12791
|
+
loadChannels,
|
|
12792
|
+
subscribeChanges,
|
|
12793
|
+
createChannel,
|
|
12794
|
+
updateChannel,
|
|
12795
|
+
archiveChannel,
|
|
12796
|
+
joinChannel,
|
|
12797
|
+
removeChannelMember,
|
|
12798
|
+
creatingAgents: creatingAgents.filter((request) => request.workspaceId === selectedId),
|
|
12799
|
+
...navigationState.memberSessionId !== void 0 || navigationState.channelRef === void 0 ? {} : { selectedChannelRef: navigationState.channelRef },
|
|
12800
|
+
selectChannel,
|
|
12801
|
+
t
|
|
12802
|
+
}, selectedId)
|
|
12803
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12804
|
+
ref: agentsRef,
|
|
12805
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamAgentsPanel, {
|
|
12806
|
+
workspaceId: selectedId,
|
|
12807
|
+
loadMembers,
|
|
12808
|
+
subscribeChanges,
|
|
12809
|
+
addMember,
|
|
12810
|
+
updateMember,
|
|
12811
|
+
recoverMember,
|
|
12812
|
+
archiveMember,
|
|
12813
|
+
loadModels,
|
|
12814
|
+
...navigationState.memberSessionId === void 0 ? {} : { memberSessionId: navigationState.memberSessionId },
|
|
12815
|
+
openMemberSession,
|
|
12816
|
+
onCreatingChange: (request, creating) => {
|
|
12817
|
+
setCreatingAgents((current) => creating ? [...current.filter((item) => item.requestId !== request.requestId), request] : current.filter((item) => item.requestId !== request.requestId));
|
|
12818
|
+
},
|
|
12819
|
+
t
|
|
12820
|
+
}, selectedId)
|
|
11677
12821
|
})]
|
|
11678
12822
|
})
|
|
11679
|
-
|
|
11680
|
-
className: sidebar_module_css_default.workspaceSection,
|
|
11681
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
11682
|
-
ref: channelsRef,
|
|
11683
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamChannelsPanel, {
|
|
11684
|
-
workspaceId: selectedId,
|
|
11685
|
-
loadMembers,
|
|
11686
|
-
loadChannels,
|
|
11687
|
-
subscribeChanges,
|
|
11688
|
-
createChannel,
|
|
11689
|
-
updateChannel,
|
|
11690
|
-
archiveChannel,
|
|
11691
|
-
joinChannel,
|
|
11692
|
-
removeChannelMember,
|
|
11693
|
-
creatingAgents: creatingAgents.filter((request) => request.workspaceId === selectedId),
|
|
11694
|
-
...navigationState.memberSessionId !== void 0 || navigationState.channelRef === void 0 ? {} : { selectedChannelRef: navigationState.channelRef },
|
|
11695
|
-
selectChannel,
|
|
11696
|
-
t
|
|
11697
|
-
}, selectedId)
|
|
11698
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
11699
|
-
ref: agentsRef,
|
|
11700
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamAgentsPanel, {
|
|
11701
|
-
workspaceId: selectedId,
|
|
11702
|
-
loadMembers,
|
|
11703
|
-
subscribeChanges,
|
|
11704
|
-
addMember,
|
|
11705
|
-
updateMember,
|
|
11706
|
-
recoverMember,
|
|
11707
|
-
archiveMember,
|
|
11708
|
-
loadModels,
|
|
11709
|
-
...navigationState.memberSessionId === void 0 ? {} : { memberSessionId: navigationState.memberSessionId },
|
|
11710
|
-
openMemberSession,
|
|
11711
|
-
onCreatingChange: (request, creating) => {
|
|
11712
|
-
setCreatingAgents((current) => creating ? [...current.filter((item) => item.requestId !== request.requestId), request] : current.filter((item) => item.requestId !== request.requestId));
|
|
11713
|
-
},
|
|
11714
|
-
t
|
|
11715
|
-
}, selectedId)
|
|
11716
|
-
})]
|
|
11717
|
-
})]
|
|
12823
|
+
]
|
|
11718
12824
|
});
|
|
11719
12825
|
}
|
|
11720
12826
|
//#endregion
|
|
@@ -11748,6 +12854,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
11748
12854
|
statusError: "错误",
|
|
11749
12855
|
statusUnavailable: "不可用",
|
|
11750
12856
|
addChannel: "新建频道",
|
|
12857
|
+
inboxTitle: "收件箱",
|
|
12858
|
+
inboxTitleWithCount: "收件箱,{count} 条未读",
|
|
12859
|
+
loadingInbox: "正在加载收件箱…",
|
|
12860
|
+
inboxEmptyTitle: "收件箱是空的",
|
|
12861
|
+
inboxEmptyHint: "你参与的 Thread 有新活动、或有人提到你时,会出现在这里",
|
|
12862
|
+
inboxTimeYesterday: "昨天",
|
|
12863
|
+
inboxHeaderThreads: "{count} 个 Thread",
|
|
12864
|
+
inboxHeaderUnread: "{count} 条未读",
|
|
12865
|
+
inboxHeaderMentions: "{count} 条提及",
|
|
12866
|
+
inboxRowUnread: "{count} 条未读",
|
|
12867
|
+
inboxRowUnreadMentions: "{count} 条未读,其中 {mentions} 条提及",
|
|
12868
|
+
inboxRowActor: "最新来自 {name}",
|
|
12869
|
+
inboxSectionNeedsMe: "需要我",
|
|
12870
|
+
inboxSectionRecent: "最近活跃",
|
|
11751
12871
|
channelName: "名称",
|
|
11752
12872
|
channelDescription: "说明",
|
|
11753
12873
|
initialMembers: "初始成员",
|
|
@@ -11761,6 +12881,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
11761
12881
|
resumeAgent: "恢复",
|
|
11762
12882
|
restartAgent: "重启",
|
|
11763
12883
|
restartStillUnavailable: "重启已执行,成员仍不可用:{diagnostic}",
|
|
12884
|
+
restartRefusedNoRestart: "会话日志被确定拒绝,修复无可用项,重启无法解决:{detail}",
|
|
11764
12885
|
restartFailed: "重启执行失败:{message}",
|
|
11765
12886
|
archiveAgent: "归档",
|
|
11766
12887
|
archiveAgentTitle: "归档 Agent:{name}",
|
|
@@ -11812,12 +12933,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
11812
12933
|
taskStatusInReview: "待验收",
|
|
11813
12934
|
taskStatusDone: "已完成",
|
|
11814
12935
|
taskStatusClosed: "已关闭",
|
|
11815
|
-
taskMessageCount: "{count} 条消息",
|
|
11816
12936
|
taskLabel: "Task #{number}",
|
|
11817
12937
|
taskPending: "Task …",
|
|
11818
12938
|
openTask: "打开 Task #{number}",
|
|
11819
12939
|
openThread: "打开讨论",
|
|
12940
|
+
openTaskUnread: "打开 Task #{number}({count} 条新动态)",
|
|
12941
|
+
openThreadUnread: "打开讨论({count} 条新动态)",
|
|
11820
12942
|
threadLabel: "讨论",
|
|
12943
|
+
recentActivity: "最近活动 {time}",
|
|
12944
|
+
replyAction: "回复",
|
|
12945
|
+
claimers: "由 {names} 处理",
|
|
11821
12946
|
asTask: "作为任务",
|
|
11822
12947
|
promoteToTask: "转为 Task",
|
|
11823
12948
|
promotingTask: "正在转为 Task…",
|
|
@@ -11896,6 +13021,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
11896
13021
|
statusError: "Error",
|
|
11897
13022
|
statusUnavailable: "Unavailable",
|
|
11898
13023
|
addChannel: "New Channel",
|
|
13024
|
+
inboxTitle: "Inbox",
|
|
13025
|
+
inboxTitleWithCount: "Inbox, {count} unread",
|
|
13026
|
+
loadingInbox: "Loading Inbox…",
|
|
13027
|
+
inboxEmptyTitle: "Your Inbox is empty",
|
|
13028
|
+
inboxEmptyHint: "Threads you take part in appear here when they have new activity or mention you",
|
|
13029
|
+
inboxTimeYesterday: "Yesterday",
|
|
13030
|
+
inboxHeaderThreads: "{count} Thread(s)",
|
|
13031
|
+
inboxHeaderUnread: "{count} unread",
|
|
13032
|
+
inboxHeaderMentions: "{count} mention(s)",
|
|
13033
|
+
inboxRowUnread: "{count} unread",
|
|
13034
|
+
inboxRowUnreadMentions: "{count} unread, {mentions} mention(s)",
|
|
13035
|
+
inboxRowActor: "Latest from {name}",
|
|
13036
|
+
inboxSectionNeedsMe: "Needs me",
|
|
13037
|
+
inboxSectionRecent: "Recently active",
|
|
11899
13038
|
channelName: "Name",
|
|
11900
13039
|
channelDescription: "Description",
|
|
11901
13040
|
initialMembers: "Initial members",
|
|
@@ -11909,6 +13048,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
11909
13048
|
resumeAgent: "Resume",
|
|
11910
13049
|
restartAgent: "Restart",
|
|
11911
13050
|
restartStillUnavailable: "Restart ran, but the Member is still unavailable: {diagnostic}",
|
|
13051
|
+
restartRefusedNoRestart: "The session log is deterministically refused with nothing repairable; restarting cannot fix it: {detail}",
|
|
11912
13052
|
restartFailed: "Restart failed: {message}",
|
|
11913
13053
|
archiveAgent: "Archive",
|
|
11914
13054
|
archiveAgentTitle: "Archive Agent: {name}",
|
|
@@ -11960,12 +13100,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
11960
13100
|
taskStatusInReview: "In review",
|
|
11961
13101
|
taskStatusDone: "Done",
|
|
11962
13102
|
taskStatusClosed: "Closed",
|
|
11963
|
-
taskMessageCount: "{count} messages",
|
|
11964
13103
|
taskLabel: "Task #{number}",
|
|
11965
13104
|
taskPending: "Task …",
|
|
11966
13105
|
openTask: "Open Task #{number}",
|
|
11967
13106
|
openThread: "Open thread",
|
|
13107
|
+
openTaskUnread: "Open Task #{number} ({count} new updates)",
|
|
13108
|
+
openThreadUnread: "Open thread ({count} new updates)",
|
|
11968
13109
|
threadLabel: "Thread",
|
|
13110
|
+
recentActivity: "Last activity {time}",
|
|
13111
|
+
replyAction: "Reply",
|
|
13112
|
+
claimers: "Handled by {names}",
|
|
11969
13113
|
asTask: "As task",
|
|
11970
13114
|
promoteToTask: "Convert to Task",
|
|
11971
13115
|
promotingTask: "Converting to Task…",
|
|
@@ -12028,7 +13172,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
12028
13172
|
"connection",
|
|
12029
13173
|
"conversation"
|
|
12030
13174
|
];
|
|
12031
|
-
function registerModeShadow(ctx, navigation, changes, drafts, name, component, extraInject, entryKey) {
|
|
13175
|
+
function registerModeShadow(ctx, navigation, changes, reads, drafts, name, component, extraInject, entryKey) {
|
|
12032
13176
|
const openMemberSessionImpl = (sessionId) => {
|
|
12033
13177
|
const sessions = ctx.sessions;
|
|
12034
13178
|
const snapshot = navigation.getSnapshot();
|
|
@@ -12039,6 +13183,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
12039
13183
|
};
|
|
12040
13184
|
const sharedRemotes = {
|
|
12041
13185
|
loadChannels: (request) => ctx.remote.agentTeam.view(request),
|
|
13186
|
+
loadInbox: (request) => ctx.remote.agentTeam.inbox(request),
|
|
13187
|
+
subscribeReads: (listener) => reads.subscribe(listener),
|
|
12042
13188
|
subscribeChanges: (scope, listener) => changes.subscribe(scope, listener),
|
|
12043
13189
|
drafts,
|
|
12044
13190
|
loadMembers: (request) => ctx.remote.agentTeam.members(request),
|
|
@@ -12069,7 +13215,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
12069
13215
|
...navigation.actions(),
|
|
12070
13216
|
...sharedRemotes,
|
|
12071
13217
|
...name === "main" ? {
|
|
12072
|
-
readThread: (request) =>
|
|
13218
|
+
readThread: async (request) => {
|
|
13219
|
+
const result = await ctx.remote.agentTeam.readThread(request);
|
|
13220
|
+
if (result.ok) reads.bump();
|
|
13221
|
+
return result;
|
|
13222
|
+
},
|
|
12073
13223
|
loadThreadHistory: (request) => ctx.remote.agentTeam.threadHistory(request),
|
|
12074
13224
|
threadObservations: (request) => ctx.remote.agentTeam.threadObservations(request),
|
|
12075
13225
|
sendMessage: (request) => ctx.remote.agentTeam.sendMessage(request),
|
|
@@ -12135,6 +13285,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
12135
13285
|
};
|
|
12136
13286
|
}, "agent-team: member session restore");
|
|
12137
13287
|
const changes = new TeamChangeStream((request, signal) => ctx.remote.agentTeam.changes(request, signal));
|
|
13288
|
+
const reads = new TeamReadStream();
|
|
12138
13289
|
const loadMemberGroups = async () => {
|
|
12139
13290
|
const workspaces = ctx.workspaces.list.getSnapshot().items;
|
|
12140
13291
|
return (await Promise.all(workspaces.map(async (workspace) => {
|
|
@@ -12159,13 +13310,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
12159
13310
|
leaveTeam: () => {
|
|
12160
13311
|
navigation.actions().exitMemberSession();
|
|
12161
13312
|
navigation.actions().leaveTeam();
|
|
12162
|
-
}
|
|
12163
|
-
loadMemberGroups
|
|
13313
|
+
}
|
|
12164
13314
|
})
|
|
12165
13315
|
}, TeamFooterAction));
|
|
12166
|
-
registerModeShadow(ctx, navigation, changes, drafts, "sidebar.workspaces", TeamWorkspaceBrowser);
|
|
12167
|
-
registerModeShadow(ctx, navigation, changes, drafts, "main", TeamConversation, void 0, "conversation");
|
|
12168
|
-
registerModeShadow(ctx, navigation, changes, drafts, "sidebar.settings",
|
|
13316
|
+
registerModeShadow(ctx, navigation, changes, reads, drafts, "sidebar.workspaces", TeamWorkspaceBrowser);
|
|
13317
|
+
registerModeShadow(ctx, navigation, changes, reads, drafts, "main", TeamConversation, void 0, "conversation");
|
|
13318
|
+
registerModeShadow(ctx, navigation, changes, reads, drafts, "sidebar.settings", TeamMembersAction, () => ({ loadMemberGroups }));
|
|
12169
13319
|
}
|
|
12170
13320
|
async function apply(ctx) {
|
|
12171
13321
|
const disposeRemote = await ctx.remote.$mount(TYPERT_REMOTE);
|