@wowyuarm/dsh-agent-team 0.1.12 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +2 -0
  2. package/README.zh.md +2 -0
  3. package/cordis.patch.yml +7 -3
  4. package/package.json +14 -2
  5. package/packages/agent-team/README.md +2 -2
  6. package/packages/agent-team/README.zh.md +2 -2
  7. package/packages/agent-team/lib/index.js +151 -69
  8. package/packages/agent-team/lib/ledger.js +249 -31
  9. package/packages/agent-team/lib/member-context.js +18 -1
  10. package/packages/agent-team/lib/member-runtime.js +5 -4
  11. package/packages/agent-team/lib/mentions.js +48 -24
  12. package/packages/agent-team/lib/spec.js +19 -0
  13. package/packages/agent-team/lib/typert.host.js +187 -41
  14. package/packages/agent-team/lib/typert.remote-client.d.ts +7 -3
  15. package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
  16. package/packages/agent-team/lib/typert.remote-client.js +132 -27
  17. package/packages/agent-team/lib/types/index.d.ts +32 -7
  18. package/packages/agent-team/lib/types/index.d.ts.map +1 -1
  19. package/packages/agent-team/lib/types/ledger.d.ts +46 -2
  20. package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
  21. package/packages/agent-team/lib/types/member-context.d.ts +6 -0
  22. package/packages/agent-team/lib/types/member-context.d.ts.map +1 -1
  23. package/packages/agent-team/lib/types/mentions.d.ts +20 -7
  24. package/packages/agent-team/lib/types/mentions.d.ts.map +1 -1
  25. package/packages/agent-team/lib/types/spec.d.ts.map +1 -1
  26. package/packages/agent-team/lib/types/types/entities.d.ts +3 -2
  27. package/packages/agent-team/lib/types/types/entities.d.ts.map +1 -1
  28. package/packages/agent-team/lib/types/types/operations.d.ts +37 -1
  29. package/packages/agent-team/lib/types/types/operations.d.ts.map +1 -1
  30. package/packages/agent-team/lib/types/types/requests-results.d.ts +50 -10
  31. package/packages/agent-team/lib/types/types/requests-results.d.ts.map +1 -1
  32. package/packages/agent-team/lib/types/vendor/storage-sqlite/index.d.ts +87 -0
  33. package/packages/agent-team/lib/types/vendor/storage-sqlite/index.d.ts.map +1 -0
  34. package/packages/agent-team/lib/types/vendor/storage-sqlite/schema.d.ts +59 -0
  35. package/packages/agent-team/lib/types/vendor/storage-sqlite/schema.d.ts.map +1 -0
  36. package/packages/agent-team/lib/types/vendor/storage-sqlite/unit.d.ts +57 -0
  37. package/packages/agent-team/lib/types/vendor/storage-sqlite/unit.d.ts.map +1 -0
  38. package/packages/agent-team/lib/vendor/storage-sqlite/index.js +139 -0
  39. package/packages/agent-team/lib/vendor/storage-sqlite/schema.js +120 -0
  40. package/packages/agent-team/lib/vendor/storage-sqlite/unit.js +132 -0
  41. package/packages/client-agent-team/README.md +1 -1
  42. package/packages/client-agent-team/README.zh.md +1 -1
  43. package/packages/client-agent-team/lib/client.js +603 -343
  44. package/packages/client-agent-team/lib/client.js.map +1 -1
  45. package/packages/client-agent-team/lib/types/client/TeamAgentImport.d.ts +12 -0
  46. package/packages/client-agent-team/lib/types/client/TeamAgentImport.d.ts.map +1 -0
  47. package/packages/client-agent-team/lib/types/client/TeamAgentImport.js +69 -0
  48. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts +3 -1
  49. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts.map +1 -1
  50. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +29 -17
  51. package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts.map +1 -1
  52. package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +19 -44
  53. package/packages/client-agent-team/lib/types/client/TeamInboxPage.d.ts +2 -2
  54. package/packages/client-agent-team/lib/types/client/TeamInboxPage.d.ts.map +1 -1
  55. package/packages/client-agent-team/lib/types/client/TeamInboxPage.js +15 -14
  56. package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts +1 -1
  57. package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts.map +1 -1
  58. package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts.map +1 -1
  59. package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +15 -29
  60. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts +1 -1
  61. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts.map +1 -1
  62. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +2 -2
  63. package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
  64. package/packages/client-agent-team/lib/types/client/index.js +8 -1
  65. package/packages/client-agent-team/lib/types/client/locales.d.ts +18 -0
  66. package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
  67. package/packages/client-agent-team/lib/types/client/locales.js +18 -0
  68. package/packages/client-agent-team/lib/types/client/slots.d.ts +3 -1
  69. package/packages/client-agent-team/lib/types/client/slots.d.ts.map +1 -1
  70. package/packages/client-agent-team/lib/types/client/team-changes.d.ts +15 -31
  71. package/packages/client-agent-team/lib/types/client/team-changes.d.ts.map +1 -1
  72. package/packages/client-agent-team/lib/types/client/team-changes.js +82 -111
  73. package/packages/client-agent-team/lib/types/client/team-formatters.d.ts +13 -11
  74. package/packages/client-agent-team/lib/types/client/team-formatters.d.ts.map +1 -1
  75. package/packages/client-agent-team/lib/types/client/team-formatters.js +29 -35
  76. package/packages/tool-agent-team/README.md +1 -1
  77. package/packages/tool-agent-team/README.zh.md +1 -1
  78. package/packages/tool-agent-team/lib/host-access.js +19 -0
  79. package/packages/tool-agent-team/lib/index.js +42 -33
  80. package/packages/tool-agent-team/lib/types/host-access.d.ts +10 -0
  81. package/packages/tool-agent-team/lib/types/host-access.d.ts.map +1 -1
  82. package/packages/tool-agent-team/lib/types/index.d.ts.map +1 -1
  83. package/packages/client-agent-team/lib/types/client/scope-coverage.d.ts +0 -41
  84. package/packages/client-agent-team/lib/types/client/scope-coverage.d.ts.map +0 -1
  85. package/packages/client-agent-team/lib/types/client/scope-coverage.js +0 -64
@@ -4,6 +4,7 @@ window.__ModuleLoader__.load({
4
4
  var module = { exports: {} };
5
5
  var exports = module.exports;
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ let _deepseek_ai_dsh_api_gateway_client = require("@deepseek-ai/dsh-api-gateway/client");
7
8
  let react = require("react");
8
9
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
9
10
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -4296,27 +4297,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4296
4297
  "readThroughSequence": number().readonly()
4297
4298
  }).readonly().optional()
4298
4299
  });
4299
- const _wowyuarm_dsh_agent_team_agentTeam_changes_parameter_0$schema = object({
4300
- "afterVersion": number().readonly(),
4301
- "scope": union([
4302
- object({
4303
- "kind": literal("workspace").readonly(),
4304
- "workspaceId": intersection(string(), unknown()).readonly()
4305
- }),
4306
- object({
4307
- "kind": literal("channel").readonly(),
4308
- "channelRef": intersection(string(), unknown()).readonly()
4309
- }),
4310
- object({
4311
- "kind": literal("thread").readonly(),
4312
- "threadRef": intersection(string(), unknown()).readonly()
4313
- }),
4314
- object({
4315
- "kind": literal("presence").readonly(),
4316
- "workspaceId": intersection(string(), unknown()).readonly()
4317
- })
4318
- ]).readonly().optional()
4319
- });
4300
+ const _wowyuarm_dsh_agent_team_agentTeam_changes_parameter_0$schema = object({ "scope": union([
4301
+ object({
4302
+ "kind": literal("workspace").readonly(),
4303
+ "workspaceId": intersection(string(), unknown()).readonly()
4304
+ }),
4305
+ object({
4306
+ "kind": literal("channel").readonly(),
4307
+ "channelRef": intersection(string(), unknown()).readonly()
4308
+ }),
4309
+ object({
4310
+ "kind": literal("thread").readonly(),
4311
+ "threadRef": intersection(string(), unknown()).readonly()
4312
+ }),
4313
+ object({
4314
+ "kind": literal("presence").readonly(),
4315
+ "workspaceId": intersection(string(), unknown()).readonly()
4316
+ })
4317
+ ]).readonly().optional() });
4320
4318
  const _wowyuarm_dsh_agent_team_agentTeam_changes_result$schema = object({ "version": number().readonly() });
4321
4319
  const _wowyuarm_dsh_agent_team_agentTeam_changeTask_parameter_0$schema = object({
4322
4320
  "requestId": intersection(string(), unknown()).readonly(),
@@ -4516,6 +4514,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4516
4514
  });
4517
4515
  const _wowyuarm_dsh_agent_team_agentTeam_inbox_result$schema = object({
4518
4516
  "items": array(object({
4517
+ "workspaceId": intersection(string(), unknown()).readonly(),
4519
4518
  "channelRef": intersection(string(), unknown()).readonly(),
4520
4519
  "channelName": string().readonly().optional(),
4521
4520
  "task": object({
@@ -4562,6 +4561,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4562
4561
  }).readonly().optional()
4563
4562
  })).readonly(),
4564
4563
  "recent": array(object({
4564
+ "workspaceId": intersection(string(), unknown()).readonly(),
4565
4565
  "channelRef": intersection(string(), unknown()).readonly(),
4566
4566
  "channelName": string().readonly().optional(),
4567
4567
  "task": object({
@@ -4626,7 +4626,54 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4626
4626
  "channelRef": intersection(string(), unknown()).readonly(),
4627
4627
  "memberId": intersection(string(), unknown()).readonly()
4628
4628
  });
4629
- const _wowyuarm_dsh_agent_team_agentTeam_members_parameter_0$schema = object({ "workspaceId": intersection(string(), unknown()).readonly() });
4629
+ const _wowyuarm_dsh_agent_team_agentTeam_joinWorkspace_parameter_0$schema = object({
4630
+ "requestId": intersection(string(), unknown()).readonly(),
4631
+ "workspaceId": intersection(string(), unknown()).readonly(),
4632
+ "memberId": intersection(string(), unknown()).readonly()
4633
+ });
4634
+ const _wowyuarm_dsh_agent_team_agentTeam_joinWorkspace_result$schema = object({
4635
+ "receipt": object({
4636
+ "operationId": intersection(string(), unknown()).readonly(),
4637
+ "requestId": intersection(string(), unknown()).readonly(),
4638
+ "sequence": number().readonly(),
4639
+ "occurredAt": string().readonly()
4640
+ }).readonly(),
4641
+ "memberId": intersection(string(), unknown()).readonly(),
4642
+ "workspaceId": intersection(string(), unknown()).readonly()
4643
+ });
4644
+ const _wowyuarm_dsh_agent_team_agentTeam_leaveWorkspace_parameter_0$schema = object({
4645
+ "requestId": intersection(string(), unknown()).readonly(),
4646
+ "workspaceId": intersection(string(), unknown()).readonly(),
4647
+ "memberId": intersection(string(), unknown()).readonly()
4648
+ });
4649
+ const _wowyuarm_dsh_agent_team_agentTeam_leaveWorkspace_result$schema = object({
4650
+ "receipt": object({
4651
+ "operationId": intersection(string(), unknown()).readonly(),
4652
+ "requestId": intersection(string(), unknown()).readonly(),
4653
+ "sequence": number().readonly(),
4654
+ "occurredAt": string().readonly()
4655
+ }).readonly(),
4656
+ "memberId": intersection(string(), unknown()).readonly(),
4657
+ "workspaceId": intersection(string(), unknown()).readonly(),
4658
+ "releasedClaims": array(object({
4659
+ "claimRef": intersection(string(), unknown()).readonly(),
4660
+ "taskRef": intersection(string(), unknown()).readonly(),
4661
+ "threadRef": intersection(string(), unknown()).readonly(),
4662
+ "owner": intersection(string(), unknown()).readonly(),
4663
+ "direction": string().readonly(),
4664
+ "normalizedDirection": string().readonly(),
4665
+ "state": union([
4666
+ literal("active"),
4667
+ literal("done"),
4668
+ literal("released")
4669
+ ]).readonly()
4670
+ })).readonly(),
4671
+ "removedAttention": array(object({
4672
+ "memberId": intersection(string(), unknown()).readonly(),
4673
+ "threadRef": intersection(string(), unknown()).readonly()
4674
+ })).readonly()
4675
+ });
4676
+ const _wowyuarm_dsh_agent_team_agentTeam_members_parameter_0$schema = object({ "workspaceId": intersection(string(), unknown()).readonly().optional() });
4630
4677
  const _wowyuarm_dsh_agent_team_agentTeam_members_result$schema = array(object({
4631
4678
  "member": object({
4632
4679
  "memberId": intersection(string(), unknown()).readonly(),
@@ -4651,6 +4698,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4651
4698
  literal("archived")
4652
4699
  ]).readonly()
4653
4700
  }).readonly(),
4701
+ "workspaceIds": array(intersection(string(), unknown())).readonly(),
4654
4702
  "availability": union([
4655
4703
  literal("suspended"),
4656
4704
  literal("inactive"),
@@ -5510,6 +5558,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5510
5558
  });
5511
5559
  const _wowyuarm_dsh_agent_team_agentTeam_view_result$schema = object({
5512
5560
  "humanMemberId": intersection(string(), unknown()).readonly(),
5561
+ "workspaces": array(object({
5562
+ "workspaceId": intersection(string(), unknown()).readonly(),
5563
+ "title": union([_undefined(), string()]).readonly().optional(),
5564
+ "default": boolean().readonly()
5565
+ })).readonly(),
5513
5566
  "channels": array(object({
5514
5567
  "channelRef": intersection(string(), unknown()).readonly(),
5515
5568
  "workspaceId": intersection(string(), unknown()).readonly(),
@@ -5590,6 +5643,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5590
5643
  "revision": number().readonly()
5591
5644
  }).readonly(),
5592
5645
  "taskNumber": number().readonly().optional(),
5646
+ "claimOwners": array(object({
5647
+ "memberId": intersection(string(), unknown()).readonly(),
5648
+ "name": string().readonly()
5649
+ })).readonly(),
5593
5650
  "messageCount": number().readonly(),
5594
5651
  "lastActivityAt": string().readonly()
5595
5652
  })).readonly(),
@@ -5675,7 +5732,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5675
5732
  },
5676
5733
  sourceLocation: {
5677
5734
  "file": "packages/agent-team/src/index.ts",
5678
- "line": 699,
5735
+ "line": 727,
5679
5736
  "column": 9
5680
5737
  }
5681
5738
  },
@@ -5702,7 +5759,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5702
5759
  },
5703
5760
  sourceLocation: {
5704
5761
  "file": "packages/agent-team/src/index.ts",
5705
- "line": 689,
5762
+ "line": 717,
5706
5763
  "column": 9
5707
5764
  }
5708
5765
  },
@@ -5729,7 +5786,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5729
5786
  },
5730
5787
  sourceLocation: {
5731
5788
  "file": "packages/agent-team/src/index.ts",
5732
- "line": 1080,
5789
+ "line": 1108,
5733
5790
  "column": 9
5734
5791
  }
5735
5792
  },
@@ -5756,7 +5813,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5756
5813
  },
5757
5814
  sourceLocation: {
5758
5815
  "file": "packages/agent-team/src/index.ts",
5759
- "line": 1202,
5816
+ "line": 1248,
5760
5817
  "column": 9
5761
5818
  }
5762
5819
  },
@@ -5765,6 +5822,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5765
5822
  service: "agentTeam",
5766
5823
  namespace: "agentTeam",
5767
5824
  method: "changes",
5825
+ mode: "stream",
5768
5826
  invocation: { kind: "direct" },
5769
5827
  parameters: [{
5770
5828
  name: "request",
@@ -5784,8 +5842,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5784
5842
  },
5785
5843
  sourceLocation: {
5786
5844
  "file": "packages/agent-team/src/index.ts",
5787
- "line": 620,
5788
- "column": 9
5845
+ "line": 650,
5846
+ "column": 11
5789
5847
  }
5790
5848
  },
5791
5849
  {
@@ -5811,7 +5869,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5811
5869
  },
5812
5870
  sourceLocation: {
5813
5871
  "file": "packages/agent-team/src/index.ts",
5814
- "line": 1092,
5872
+ "line": 1120,
5815
5873
  "column": 9
5816
5874
  }
5817
5875
  },
@@ -5838,7 +5896,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5838
5896
  },
5839
5897
  sourceLocation: {
5840
5898
  "file": "packages/agent-team/src/index.ts",
5841
- "line": 814,
5899
+ "line": 842,
5842
5900
  "column": 9
5843
5901
  }
5844
5902
  },
@@ -5865,7 +5923,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5865
5923
  },
5866
5924
  sourceLocation: {
5867
5925
  "file": "packages/agent-team/src/index.ts",
5868
- "line": 662,
5926
+ "line": 690,
5869
5927
  "column": 9
5870
5928
  }
5871
5929
  },
@@ -5892,7 +5950,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5892
5950
  },
5893
5951
  sourceLocation: {
5894
5952
  "file": "packages/agent-team/src/index.ts",
5895
- "line": 1188,
5953
+ "line": 1234,
5896
5954
  "column": 9
5897
5955
  }
5898
5956
  },
@@ -5919,7 +5977,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5919
5977
  },
5920
5978
  sourceLocation: {
5921
5979
  "file": "packages/agent-team/src/index.ts",
5922
- "line": 1211,
5980
+ "line": 1257,
5923
5981
  "column": 3
5924
5982
  }
5925
5983
  },
@@ -5946,7 +6004,61 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5946
6004
  },
5947
6005
  sourceLocation: {
5948
6006
  "file": "packages/agent-team/src/index.ts",
5949
- "line": 1112,
6007
+ "line": 1140,
6008
+ "column": 9
6009
+ }
6010
+ },
6011
+ {
6012
+ id: "@wowyuarm/dsh-agent-team#agentTeam/joinWorkspace",
6013
+ service: "agentTeam",
6014
+ namespace: "agentTeam",
6015
+ method: "joinWorkspace",
6016
+ invocation: { kind: "direct" },
6017
+ parameters: [{
6018
+ name: "request",
6019
+ wire: "request",
6020
+ source: "json",
6021
+ codec: {
6022
+ mode: "strict",
6023
+ typeSymbol: "@wowyuarm/dsh-agent-team/types#AgentTeamJoinWorkspaceRequest",
6024
+ schema: _wowyuarm_dsh_agent_team_agentTeam_joinWorkspace_parameter_0$schema
6025
+ }
6026
+ }],
6027
+ result: {
6028
+ mode: "strict",
6029
+ typeSymbol: "@wowyuarm/dsh-agent-team/types#AgentTeamJoinWorkspaceResult",
6030
+ schema: _wowyuarm_dsh_agent_team_agentTeam_joinWorkspace_result$schema
6031
+ },
6032
+ sourceLocation: {
6033
+ "file": "packages/agent-team/src/index.ts",
6034
+ "line": 1160,
6035
+ "column": 9
6036
+ }
6037
+ },
6038
+ {
6039
+ id: "@wowyuarm/dsh-agent-team#agentTeam/leaveWorkspace",
6040
+ service: "agentTeam",
6041
+ namespace: "agentTeam",
6042
+ method: "leaveWorkspace",
6043
+ invocation: { kind: "direct" },
6044
+ parameters: [{
6045
+ name: "request",
6046
+ wire: "request",
6047
+ source: "json",
6048
+ codec: {
6049
+ mode: "strict",
6050
+ typeSymbol: "@wowyuarm/dsh-agent-team/types#AgentTeamLeaveWorkspaceRequest",
6051
+ schema: _wowyuarm_dsh_agent_team_agentTeam_leaveWorkspace_parameter_0$schema
6052
+ }
6053
+ }],
6054
+ result: {
6055
+ mode: "strict",
6056
+ typeSymbol: "@wowyuarm/dsh-agent-team/types#AgentTeamLeaveWorkspaceResult",
6057
+ schema: _wowyuarm_dsh_agent_team_agentTeam_leaveWorkspace_result$schema
6058
+ },
6059
+ sourceLocation: {
6060
+ "file": "packages/agent-team/src/index.ts",
6061
+ "line": 1169,
5950
6062
  "column": 9
5951
6063
  }
5952
6064
  },
@@ -5974,7 +6086,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5974
6086
  },
5975
6087
  sourceLocation: {
5976
6088
  "file": "packages/agent-team/src/index.ts",
5977
- "line": 611,
6089
+ "line": 640,
5978
6090
  "column": 3
5979
6091
  }
5980
6092
  },
@@ -6001,7 +6113,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6001
6113
  },
6002
6114
  sourceLocation: {
6003
6115
  "file": "packages/agent-team/src/index.ts",
6004
- "line": 1102,
6116
+ "line": 1130,
6005
6117
  "column": 9
6006
6118
  }
6007
6119
  },
@@ -6028,7 +6140,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6028
6140
  },
6029
6141
  sourceLocation: {
6030
6142
  "file": "packages/agent-team/src/index.ts",
6031
- "line": 1175,
6143
+ "line": 1221,
6032
6144
  "column": 9
6033
6145
  }
6034
6146
  },
@@ -6055,7 +6167,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6055
6167
  },
6056
6168
  sourceLocation: {
6057
6169
  "file": "packages/agent-team/src/index.ts",
6058
- "line": 1218,
6170
+ "line": 1264,
6059
6171
  "column": 9
6060
6172
  }
6061
6173
  },
@@ -6082,7 +6194,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6082
6194
  },
6083
6195
  sourceLocation: {
6084
6196
  "file": "packages/agent-team/src/index.ts",
6085
- "line": 759,
6197
+ "line": 787,
6086
6198
  "column": 9
6087
6199
  }
6088
6200
  },
@@ -6109,7 +6221,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6109
6221
  },
6110
6222
  sourceLocation: {
6111
6223
  "file": "packages/agent-team/src/index.ts",
6112
- "line": 1123,
6224
+ "line": 1151,
6113
6225
  "column": 9
6114
6226
  }
6115
6227
  },
@@ -6136,7 +6248,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6136
6248
  },
6137
6249
  sourceLocation: {
6138
6250
  "file": "packages/agent-team/src/index.ts",
6139
- "line": 1196,
6251
+ "line": 1242,
6140
6252
  "column": 9
6141
6253
  }
6142
6254
  },
@@ -6163,7 +6275,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6163
6275
  },
6164
6276
  sourceLocation: {
6165
6277
  "file": "packages/agent-team/src/index.ts",
6166
- "line": 598,
6278
+ "line": 627,
6167
6279
  "column": 3
6168
6280
  }
6169
6281
  },
@@ -6190,7 +6302,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6190
6302
  },
6191
6303
  sourceLocation: {
6192
6304
  "file": "packages/agent-team/src/index.ts",
6193
- "line": 1132,
6305
+ "line": 1178,
6194
6306
  "column": 9
6195
6307
  }
6196
6308
  },
@@ -6217,7 +6329,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6217
6329
  },
6218
6330
  sourceLocation: {
6219
6331
  "file": "packages/agent-team/src/index.ts",
6220
- "line": 1236,
6332
+ "line": 1282,
6221
6333
  "column": 3
6222
6334
  }
6223
6335
  },
@@ -6244,7 +6356,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6244
6356
  },
6245
6357
  sourceLocation: {
6246
6358
  "file": "packages/agent-team/src/index.ts",
6247
- "line": 1229,
6359
+ "line": 1275,
6248
6360
  "column": 3
6249
6361
  }
6250
6362
  },
@@ -6271,7 +6383,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6271
6383
  },
6272
6384
  sourceLocation: {
6273
6385
  "file": "packages/agent-team/src/index.ts",
6274
- "line": 674,
6386
+ "line": 702,
6275
6387
  "column": 9
6276
6388
  }
6277
6389
  },
@@ -6298,7 +6410,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6298
6410
  },
6299
6411
  sourceLocation: {
6300
6412
  "file": "packages/agent-team/src/index.ts",
6301
- "line": 1020,
6413
+ "line": 1048,
6302
6414
  "column": 9
6303
6415
  }
6304
6416
  },
@@ -6325,7 +6437,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6325
6437
  },
6326
6438
  sourceLocation: {
6327
6439
  "file": "packages/agent-team/src/index.ts",
6328
- "line": 1243,
6440
+ "line": 1289,
6329
6441
  "column": 3
6330
6442
  }
6331
6443
  }
@@ -6508,123 +6620,93 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6508
6620
  };
6509
6621
  //#endregion
6510
6622
  //#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
- }
6526
6623
  function scopeKey(scope) {
6527
6624
  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}`;
6528
6625
  }
6529
- /**
6530
- * One long-poll per change scope, shared by every listening surface: panels
6531
- * and pages never open parallel `changes` requests for the same scope, and
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.
6545
- */
6626
+ /** One logical stream per scope per page; Harness owns the shared transport and recovery. */
6546
6627
  var TeamChangeStream = class {
6547
- changes;
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();
6555
- constructor(changes) {
6556
- this.changes = changes;
6628
+ remote;
6629
+ subscriptions = /* @__PURE__ */ new Map();
6630
+ constructor(remote) {
6631
+ this.remote = remote;
6557
6632
  }
6558
6633
  subscribe(scope, listener) {
6559
6634
  const key = scopeKey(scope);
6560
- let poll = this.polls.get(key);
6561
- if (poll === void 0) {
6562
- poll = {
6563
- controller: new AbortController(),
6564
- listeners: /* @__PURE__ */ new Set(),
6565
- resumeFrom: this.observed.get(key)
6566
- };
6567
- this.polls.set(key, poll);
6568
- this.run(key, scope, poll);
6635
+ let subscription = this.subscriptions.get(key);
6636
+ if (subscription === void 0) {
6637
+ subscription = this.open(scope, new Set([listener]));
6638
+ this.subscriptions.set(key, subscription);
6639
+ this.run(key, subscription);
6640
+ } else {
6641
+ subscription.listeners.add(listener);
6642
+ if (subscription.failure !== void 0) listener({
6643
+ type: "failed",
6644
+ message: subscription.failure
6645
+ });
6569
6646
  }
6570
- poll.listeners.add(listener);
6647
+ const owned = subscription;
6571
6648
  return () => {
6572
- const current = this.polls.get(key);
6573
- if (current === void 0 || !current.listeners.delete(listener)) return;
6574
- if (current.listeners.size === 0) {
6575
- this.polls.delete(key);
6576
- current.controller.abort();
6577
- }
6649
+ if (!owned.listeners.delete(listener) || owned.listeners.size !== 0) return;
6650
+ if (this.subscriptions.get(key) === owned) this.subscriptions.delete(key);
6651
+ owned.stream.dispose();
6652
+ };
6653
+ }
6654
+ /**
6655
+ * Reopen every scope whose stream already ended for good. The Harness resumes a
6656
+ * live generation across reconnects, but a terminated one is gone for good: a new
6657
+ * Host generation is the moment the scope was waiting for can come back, and the
6658
+ * listeners keep their seats, so only the stream is replaced.
6659
+ */
6660
+ recover() {
6661
+ for (const [key, subscription] of this.subscriptions) {
6662
+ if (subscription.failure === void 0) continue;
6663
+ const replacement = this.open(subscription.scope, subscription.listeners);
6664
+ this.subscriptions.set(key, replacement);
6665
+ subscription.stream.dispose();
6666
+ this.run(key, replacement);
6667
+ }
6668
+ }
6669
+ open(scope, listeners) {
6670
+ const key = scopeKey(scope);
6671
+ return {
6672
+ scope,
6673
+ stream: this.remote.$stream({
6674
+ name: `Team changes ${key}`,
6675
+ open: (signal) => this.remote.agentTeam.changes(scope === void 0 ? {} : { scope }, signal),
6676
+ ended: (accepted) => accepted ? new _deepseek_ai_dsh_api_gateway_client.RemoteStreamCarrierError("Team change subscription ended without a terminal result") : /* @__PURE__ */ new Error("Team change subscription ended before its opening baseline"),
6677
+ carrierFailed: (error) => this.fail(key, error.message)
6678
+ }),
6679
+ listeners,
6680
+ failure: void 0
6578
6681
  };
6579
6682
  }
6580
- async run(key, scope, poll) {
6581
- const { signal } = poll.controller;
6582
- const request = (afterVersion) => ({
6583
- afterVersion,
6584
- ...scope === void 0 ? {} : { scope }
6683
+ async dispose() {
6684
+ const subscriptions = [...this.subscriptions.values()];
6685
+ this.subscriptions.clear();
6686
+ await Promise.all(subscriptions.map((subscription) => subscription.stream.dispose()));
6687
+ }
6688
+ fail(key, message) {
6689
+ const subscription = this.subscriptions.get(key);
6690
+ if (subscription === void 0 || subscription.failure !== void 0) return;
6691
+ subscription.failure = message;
6692
+ for (const listener of subscription.listeners) listener({
6693
+ type: "failed",
6694
+ message
6585
6695
  });
6586
- let version = poll.resumeFrom;
6587
- let retryDelay = RETRY_BASE_MS;
6588
- let reported = false;
6589
- while (!signal.aborted) {
6590
- const result = await this.changes(request(version ?? 0), signal);
6591
- if (signal.aborted || this.polls.get(key) !== poll) return;
6592
- if (!result.ok) {
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;
6619
- }
6620
- this.observed.set(key, result.value.version);
6621
- if (result.value.version !== version) {
6622
- version = result.value.version;
6623
- for (const listener of poll.listeners) listener({
6696
+ }
6697
+ async run(key, subscription) {
6698
+ try {
6699
+ for await (const item of subscription.stream) {
6700
+ if (this.subscriptions.get(key) !== subscription) return;
6701
+ item.accept();
6702
+ subscription.failure = void 0;
6703
+ for (const listener of subscription.listeners) listener({
6624
6704
  type: "changed",
6625
- version
6705
+ version: item.value.version
6626
6706
  });
6627
6707
  }
6708
+ } catch (error) {
6709
+ if (this.subscriptions.get(key) === subscription) this.fail(key, error instanceof Error ? error.message : String(error));
6628
6710
  }
6629
6711
  }
6630
6712
  };
@@ -6830,6 +6912,92 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6830
6912
  }) });
6831
6913
  }
6832
6914
  //#endregion
6915
+ //#region ../agent-team/src/mentions.ts
6916
+ function escapeRegExp(value) {
6917
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6918
+ }
6919
+ /**
6920
+ * Character ranges the scanner must not read as mentions: fenced code blocks
6921
+ * and inline code spans. Authors quote handles there to talk *about* a name
6922
+ * rather than call it, and resolving those would notify the wrong Member.
6923
+ * The alternation tries the fenced form first so a block is never mistaken for
6924
+ * a run of inline spans.
6925
+ */
6926
+ function codeRanges(body) {
6927
+ const ranges = [];
6928
+ for (const match of body.matchAll(/```[\s\S]*?```|`[^`\n]*`/g)) {
6929
+ const start = match.index ?? 0;
6930
+ ranges.push([start, start + match[0].length]);
6931
+ }
6932
+ return ranges;
6933
+ }
6934
+ const ALL_MARKER = /(?<![\p{L}\p{N}_@])@all(?=$|[^\p{L}\p{N}_])/iu;
6935
+ /** Whether one body carries the `@all` marker outside code. */
6936
+ function hasAllMarker(body) {
6937
+ const excluded = codeRanges(body);
6938
+ const marker = ALL_MARKER.exec(body);
6939
+ return marker !== null && !excluded.some(([start, end]) => marker.index >= start && marker.index < end);
6940
+ }
6941
+ /**
6942
+ * Every `@Handle` occurrence in one body that names one of `handles`:
6943
+ * case-insensitive, on Unicode word boundaries, longest handle first, outside
6944
+ * code. Writing `@` is required: bare handles are ordinary words. This is the
6945
+ * single definition of an authored mention — the Host delivery resolution and
6946
+ * the Client's chip rendering and draft preview all read through it, so a name
6947
+ * that renders as a chip is the same name that delivers a notification.
6948
+ */
6949
+ function scanBodyHandles(body, handles) {
6950
+ const seen = /* @__PURE__ */ new Set();
6951
+ const usable = [];
6952
+ for (const handle of handles) {
6953
+ const key = handle.toLowerCase();
6954
+ if (handle.trim() === "" || seen.has(key)) continue;
6955
+ seen.add(key);
6956
+ usable.push(handle);
6957
+ }
6958
+ if (usable.length === 0) return Object.freeze([]);
6959
+ const excluded = codeRanges(body);
6960
+ const ordered = [...usable].sort((left, right) => right.length - left.length);
6961
+ const pattern = new RegExp(`(?<![\\p{L}\\p{N}_@])@(?:${ordered.map((handle) => escapeRegExp(handle)).join("|")})(?=$|[^\\p{L}\\p{N}_])`, "giu");
6962
+ const matches = [];
6963
+ for (const match of body.matchAll(pattern)) {
6964
+ const start = match.index ?? 0;
6965
+ if (excluded.some(([rangeStart, rangeEnd]) => start >= rangeStart && start < rangeEnd)) continue;
6966
+ const written = match[0].slice(1).toLowerCase();
6967
+ const hit = ordered.find((handle) => handle.toLowerCase() === written);
6968
+ if (hit === void 0) continue;
6969
+ matches.push(Object.freeze({
6970
+ handle: hit,
6971
+ start,
6972
+ end: start + match[0].length
6973
+ }));
6974
+ }
6975
+ return Object.freeze(matches);
6976
+ }
6977
+ /**
6978
+ * Resolve the `@Handle` mentions authored in one Message body.
6979
+ *
6980
+ * Callers pass the candidates reachable in the Message's Channel, so a name
6981
+ * that resolves here is already an addressable target; handles the Channel
6982
+ * cannot reach simply stay prose.
6983
+ *
6984
+ * `sender` is excluded because a Message never mentions its own author, which
6985
+ * also keeps the result usable as a recipient set without further filtering.
6986
+ */
6987
+ function resolveBodyMentions(body, candidates, sender) {
6988
+ const usable = candidates.filter((candidate) => candidate.memberId !== sender && candidate.handle.trim() !== "");
6989
+ const all = hasAllMarker(body);
6990
+ if (usable.length === 0) return {
6991
+ memberIds: Object.freeze([]),
6992
+ all
6993
+ };
6994
+ const matched = new Set(scanBodyHandles(body, usable.map((candidate) => candidate.handle)).map((match) => match.handle.toLowerCase()));
6995
+ return {
6996
+ memberIds: Object.freeze(usable.filter((candidate) => matched.has(candidate.handle.toLowerCase())).map((candidate) => candidate.memberId)),
6997
+ all
6998
+ };
6999
+ }
7000
+ //#endregion
6833
7001
  //#region src/client/team-formatters.ts
6834
7002
  function formatTaskStatus(status, t) {
6835
7003
  return t({
@@ -6916,15 +7084,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6916
7084
  const matches = [...trimmed.matchAll(BRANDED_REF_PATTERN)];
6917
7085
  return matches.length === 1 && matches[0][0] === trimmed;
6918
7086
  }
6919
- function escapeRegExp(value) {
6920
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6921
- }
6922
7087
  /**
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.
7088
+ * Locate one Message's delivered mention names inside its literal body. Matching
7089
+ * is the shared Host delivery scan — an authored `@`, case-insensitive on Unicode
7090
+ * word boundaries, longest handle first, code quoted rather than called so a chip
7091
+ * never lands where delivery would not reach. Mention segments render the canonical
7092
+ * `@Handle`; names absent from the body come back unmatched so the consumer can
7093
+ * append them as a fallback chip row.
6928
7094
  */
6929
7095
  function splitMentionNames(text, names) {
6930
7096
  if (names.length === 0) return {
@@ -6934,26 +7100,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6934
7100
  }],
6935
7101
  unmatched: []
6936
7102
  };
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
7103
  const segments = [];
6940
7104
  const matched = /* @__PURE__ */ new Set();
6941
7105
  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),
7106
+ for (const match of scanBodyHandles(text, names)) {
7107
+ if (match.start > cursor) segments.push({
7108
+ text: text.slice(cursor, match.start),
6947
7109
  mention: false
6948
7110
  });
6949
- const name = ordered[groupIndex - 1];
6950
7111
  segments.push({
6951
- text: `@${name}`,
7112
+ text: `@${match.handle}`,
6952
7113
  mention: true,
6953
- name
7114
+ name: match.handle
6954
7115
  });
6955
- matched.add(name.toLowerCase());
6956
- cursor = match.index + match[0].length;
7116
+ matched.add(match.handle.toLowerCase());
7117
+ cursor = match.end;
6957
7118
  }
6958
7119
  if (cursor < text.length) segments.push({
6959
7120
  text: text.slice(cursor),
@@ -6965,19 +7126,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6965
7126
  };
6966
7127
  }
6967
7128
  /**
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.
7129
+ * Whether one draft spells a handle as an authored `@mention`: the shared
7130
+ * delivery scan, so the composer's recipient prune and will-notify preview agree
7131
+ * with the Host on what the draft actually calls.
6974
7132
  */
6975
7133
  function containsMention(body, handle) {
6976
- return new RegExp(`(?:^|[^\\p{L}\\p{N}_])@${escapeRegExp(handle)}(?=$|[^\\p{L}\\p{N}_])`, "iu").test(body);
7134
+ return scanBodyHandles(body, [handle]).length > 0;
6977
7135
  }
6978
7136
  /** Whether one draft carries the `@all` marker the mention menu expands. */
6979
7137
  function containsAllMention(body) {
6980
- return /(?<![\p{L}\p{N}_@])@all(?=$|[^\p{L}\p{N}_])/u.test(body);
7138
+ return hasAllMarker(body);
6981
7139
  }
6982
7140
  /**
6983
7141
  * Every Member the mention menu's `@all` row stands for: the roster this
@@ -7000,13 +7158,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7000
7158
  * rather than the prose the Host reads.
7001
7159
  */
7002
7160
  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);
7161
+ if (hasAllMarker(body)) return allMentionMembers(members).map((status) => status.member.memberId);
7162
+ return resolveBodyMentions(body, members.filter((status) => status.member.state !== "inactive" && status.member.state !== "archived").map((status) => ({
7163
+ memberId: status.member.memberId,
7164
+ handle: status.member.handle
7165
+ })), "member:human").memberIds;
7005
7166
  }
7006
7167
  /** Canonical chip handles for one Message's structured mention refs. */
7007
7168
  function mentionNamesOf(mentions, handles) {
7008
7169
  return mentions.map((memberId) => memberId === "member:human" ? "human" : handles.get(memberId)).filter((name) => name !== void 0);
7009
7170
  }
7171
+ /** Accessible label for one "who is on this work" stack: its owners' handles, comma-separated. */
7172
+ function claimersLabel(owners, t) {
7173
+ return t("claimers", { names: owners.map((owner) => `@${owner.name}`).join(", ") });
7174
+ }
7010
7175
  const MARKDOWN_BLOCK_CONSTRUCT = /(^|\n)[ \t]{0,3}(?:#{1,6}[ \t]|>[ \t]|[-*+][ \t]|\d+[.)][ \t])|^[ \t]*\|.+\|/m;
7011
7176
  const MARKDOWN_INLINE_CONSTRUCT = /[`*_[\]!]|~~~|```/;
7012
7177
  /**
@@ -8816,24 +8981,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8816
8981
  };
8817
8982
  }
8818
8983
  /**
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
8984
  * The newest fact instant, or nothing when the entry's own Message is still the
8838
8985
  * newest fact on its Thread. That difference is exactly what "has follow-up
8839
8986
  * activity" means, and the Host projects both instants from the ledger.
@@ -8850,7 +8997,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8850
8997
  const [view, setView] = (0, react.useState)();
8851
8998
  const [members, setMembers] = (0, react.useState)([]);
8852
8999
  const [unreadByThread, setUnreadByThread] = (0, react.useState)(/* @__PURE__ */ new Map());
8853
- const [error, setError] = (0, react.useState)();
9000
+ const [actionError, setError] = (0, react.useState)();
9001
+ const [loadError, setLoadError] = (0, react.useState)();
9002
+ const error = actionError ?? loadError;
8854
9003
  const [pendingFiles, setPendingFiles] = (0, react.useState)([]);
8855
9004
  const [statusMessage, setStatusMessage] = (0, react.useState)();
8856
9005
  const [loading, setLoading] = (0, react.useState)(true);
@@ -8908,14 +9057,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8908
9057
  const onlineCount = channelMembers.filter((status) => status.presence === "available" || status.presence === "working").length;
8909
9058
  const messageSender = (item) => item.message.sender;
8910
9059
  const handleByMember = new Map(members.map((status) => [status.member.memberId, status.member.handle.replace(/^@/, "")]));
8911
- const ownersByTask = liveOwnersByTask(view?.items ?? [], view?.claims ?? []);
8912
9060
  const refresh = async (clearError = false) => {
8913
9061
  if (!mountedRef.current) return false;
8914
9062
  const sequence = refreshSequenceRef.current + 1;
8915
9063
  refreshSequenceRef.current = sequence;
8916
9064
  if (!loadedRef.current) setLoading(true);
8917
9065
  if (clearError) {
8918
- setError(void 0);
9066
+ setLoadError(void 0);
8919
9067
  setStatusMessage(void 0);
8920
9068
  }
8921
9069
  try {
@@ -8938,17 +9086,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8938
9086
  if (loaded.ok) {
8939
9087
  setView((current) => current === void 0 ? loaded.value : mergeChannelView(current, loaded.value));
8940
9088
  loadedRef.current = true;
8941
- } else setError(loaded.error.message);
9089
+ } else setLoadError(loaded.error.message);
8942
9090
  if (loadedMembers.ok) setMembers(loadedMembers.value);
8943
- else setError(loadedMembers.error.message);
9091
+ else setLoadError(loadedMembers.error.message);
8944
9092
  if (loadedInbox.ok) setUnreadByThread(unreadCounts(loadedInbox.value));
8945
9093
  else {
8946
9094
  setUnreadByThread(/* @__PURE__ */ new Map());
8947
- setError(loadedInbox.error.message);
9095
+ setLoadError(loadedInbox.error.message);
8948
9096
  }
9097
+ if (loaded.ok && loadedMembers.ok && loadedInbox.ok) setLoadError(void 0);
8949
9098
  return loaded.ok && loadedMembers.ok && loadedInbox.ok;
8950
9099
  } catch (cause) {
8951
- if (mountedRef.current && sequence === refreshSequenceRef.current) setError(cause instanceof Error ? cause.message : String(cause));
9100
+ if (mountedRef.current && sequence === refreshSequenceRef.current) setLoadError(cause instanceof Error ? cause.message : String(cause));
8952
9101
  return false;
8953
9102
  } finally {
8954
9103
  if (mountedRef.current && sequence === refreshSequenceRef.current) setLoading(false);
@@ -8960,16 +9109,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8960
9109
  const loaded = await loadMembers({ workspaceId });
8961
9110
  if (!mountedRef.current) return;
8962
9111
  if (loaded.ok) setMembers(loaded.value);
8963
- else setError(loaded.error.message);
9112
+ else setLoadError(loaded.error.message);
8964
9113
  } catch (cause) {
8965
- if (mountedRef.current) setError(cause instanceof Error ? cause.message : String(cause));
9114
+ if (mountedRef.current) setLoadError(cause instanceof Error ? cause.message : String(cause));
8966
9115
  }
8967
9116
  };
8968
9117
  (0, react.useEffect)(() => {
8969
9118
  mountedRef.current = true;
8970
9119
  loadedRef.current = false;
8971
9120
  setView(void 0);
8972
- setError(void 0);
9121
+ setLoadError(void 0);
8973
9122
  setLoading(true);
8974
9123
  setManagingMembers(false);
8975
9124
  refresh();
@@ -8980,7 +9129,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8980
9129
  }, (update) => {
8981
9130
  if (!mountedRef.current) return;
8982
9131
  if (update.type === "failed") {
8983
- setError(update.message);
9132
+ setLoadError(update.message);
8984
9133
  return;
8985
9134
  }
8986
9135
  refresh();
@@ -8991,7 +9140,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8991
9140
  }, (update) => {
8992
9141
  if (!mountedRef.current) return;
8993
9142
  if (update.type === "failed") {
8994
- setError(update.message);
9143
+ setLoadError(update.message);
8995
9144
  return;
8996
9145
  }
8997
9146
  refreshMembers();
@@ -9002,7 +9151,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9002
9151
  }, (update) => {
9003
9152
  if (!mountedRef.current) return;
9004
9153
  if (update.type === "failed") {
9005
- setError(update.message);
9154
+ setLoadError(update.message);
9006
9155
  return;
9007
9156
  }
9008
9157
  refreshMembers();
@@ -9249,7 +9398,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9249
9398
  const sender = human ? t("human") : senderStatus?.member.handle ?? item.message.sender;
9250
9399
  const turnGap = isRunGap(index > 0 ? block.items[index - 1].message.occurredAt : void 0, item.message.occurredAt);
9251
9400
  const task = item.task;
9252
- const owners = task === void 0 ? [] : ownersByTask.get(task.taskRef) ?? [];
9253
9401
  const unread = unreadByThread.get(item.thread.threadRef) ?? 0;
9254
9402
  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, {
9255
9403
  senderName: sender,
@@ -9268,10 +9416,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9268
9416
  ...senderStatus === void 0 ? {} : { senderTitle: senderStatus.member.description },
9269
9417
  children: item.message.topLevel && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThreadEntryRow, {
9270
9418
  item,
9271
- owners: owners.map((memberId) => ({
9272
- memberId,
9273
- name: handleByMember.get(memberId) ?? memberId
9274
- })),
9419
+ owners: item.claimOwners,
9275
9420
  unread,
9276
9421
  t,
9277
9422
  onOpen: () => {
@@ -9320,7 +9465,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9320
9465
  children: [
9321
9466
  task !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamAvatarStack, {
9322
9467
  owners,
9323
- label: t("claimers", { names: owners.map((owner) => `@${owner.name}`).join(", ") })
9468
+ label: claimersLabel(owners, t)
9324
9469
  }),
9325
9470
  task !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamStateDot, {
9326
9471
  size: 8,
@@ -9413,24 +9558,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9413
9558
  */
9414
9559
  const RECENT_ROWS_LIMIT = 5;
9415
9560
  /**
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.
9561
+ * Queue order, one total order across Workspaces: the Host's own keys —
9562
+ * mentions first, then the ledger sequence, then the Thread ref. Each Workspace
9563
+ * slice already arrives in this order, and it is also the Host's truncation
9564
+ * policy, so the merge re-applies it instead of inventing a second one: a row
9565
+ * that survived the cut on mentions must not sink below a merely newer row
9566
+ * after the merge. `newestSequence` is a global ledger position, so it stays
9567
+ * comparable across Workspaces.
9421
9568
  */
9422
9569
  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;
9570
+ return right.item.directCount - left.item.directCount || right.item.newestSequence - left.item.newestSequence || left.item.thread.threadRef.localeCompare(right.item.thread.threadRef);
9427
9571
  }
9428
9572
  /**
9429
9573
  * The Human Inbox: one Inbox call per visible Workspace, rendering the Host's
9430
9574
  * two slices — the unread queue (「需要我」, mentions counted inside it rather
9431
9575
  * 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.
9576
+ * Both merge across every Workspace into one list in the Host's own order,
9577
+ * mentions first and then newest, rather than by Workspace.
9434
9578
  * Opening the page never acknowledges anything — only a durable Thread read
9435
9579
  * advances the watermark and consumes a mention marker, so rows and the badge
9436
9580
  * drop after the Thread is opened through the existing auto-ack path. A Thread
@@ -9639,7 +9783,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9639
9783
  className: inbox_module_css_default.rowActor,
9640
9784
  children: owners.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamAvatarStack, {
9641
9785
  owners,
9642
- label: t("claimers", { names: owners.map((owner) => `@${owner.name}`).join(", ") })
9786
+ label: claimersLabel(owners, t)
9643
9787
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamAvatarStack, {
9644
9788
  owners: [actor],
9645
9789
  label: t("inboxRowActor", { name: `@${actor.name}` })
@@ -9688,70 +9832,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9688
9832
  });
9689
9833
  }
9690
9834
  //#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
- };
9754
- //#endregion
9755
9835
  //#region src/client/TeamThreadPage.tsx
9756
9836
  function factKey(fact) {
9757
9837
  return fact.kind === "message" ? `message:${fact.message.messageRef}` : `activity:${fact.activity.activityRef}`;
@@ -9901,17 +9981,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9901
9981
  }
9902
9982
  };
9903
9983
  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;
9984
+ const supplementalPendingRef = (0, react.useRef)(false);
9985
+ const refreshSupplemental = () => {
9986
+ supplementalPendingRef.current = true;
9987
+ if (supplementalRef.current !== void 0) return supplementalRef.current;
9911
9988
  const round = (async () => {
9912
- for (;;) {
9913
- coverage.beginRound();
9914
- if (!await applySupplemental() || !coverage.finishRound()) return;
9989
+ await Promise.resolve();
9990
+ while (mountedRef.current && supplementalPendingRef.current) {
9991
+ supplementalPendingRef.current = false;
9992
+ if (!await applySupplemental()) return;
9915
9993
  }
9916
9994
  })().finally(() => {
9917
9995
  if (supplementalRef.current === round) supplementalRef.current = void 0;
@@ -9966,7 +10044,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9966
10044
  (0, react.useEffect)(() => {
9967
10045
  mountedRef.current = true;
9968
10046
  supplementalRef.current = void 0;
9969
- supplementalCoverageRef.current.reset();
10047
+ supplementalPendingRef.current = false;
9970
10048
  projectionRef.current = void 0;
9971
10049
  setProjection(void 0);
9972
10050
  setChannelView(void 0);
@@ -10047,10 +10125,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10047
10125
  setError(update.message);
10048
10126
  return;
10049
10127
  }
10050
- refreshSupplemental({
10051
- scope: "workspace",
10052
- version: update.version
10053
- });
10128
+ refreshSupplemental();
10054
10129
  }),
10055
10130
  subscribeChanges({
10056
10131
  kind: "presence",
@@ -10061,10 +10136,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10061
10136
  setError(update.message);
10062
10137
  return;
10063
10138
  }
10064
- refreshSupplemental({
10065
- scope: "presence",
10066
- version: update.version
10067
- });
10139
+ refreshSupplemental();
10068
10140
  })
10069
10141
  ];
10070
10142
  return () => {
@@ -11295,7 +11367,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11295
11367
  }
11296
11368
  //#endregion
11297
11369
  //#region \0dsh-css:/home/yu/projects/dsh-agent-team/packages/client-agent-team/src/client/create.module.css.mjs
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}}";
11370
+ const css = "._1henIG_form{gap:16px;display:grid}._1henIG_modeSwitch{margin-bottom:16px}._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_notice{color:var(--dsw-alias-label-secondary);margin:0;font-size:12px;line-height:18px}._1henIG_state{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}._1henIG_roster{gap:2px;display:grid}._1henIG_failure{justify-items:start;gap:8px;display:grid}._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}}";
11299
11371
  const tagId = "@wowyuarm/dsh-agent-team/create.module.css";
11300
11372
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
11301
11373
  const tag = document.createElement("style");
@@ -11309,14 +11381,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11309
11381
  "chevronOpen": "_1henIG_chevronOpen",
11310
11382
  "dialogContent": "_1henIG_dialogContent",
11311
11383
  "error": "_1henIG_error",
11384
+ "failure": "_1henIG_failure",
11312
11385
  "field": "_1henIG_field",
11313
11386
  "form": "_1henIG_form",
11314
11387
  "input": "_1henIG_input",
11315
11388
  "memberOption": "_1henIG_memberOption",
11316
11389
  "memberPicker": "_1henIG_memberPicker",
11317
11390
  "menuCap": "_1henIG_menuCap",
11391
+ "modeSwitch": "_1henIG_modeSwitch",
11392
+ "notice": "_1henIG_notice",
11393
+ "roster": "_1henIG_roster",
11318
11394
  "selectTrigger": "_1henIG_selectTrigger",
11319
11395
  "selectValue": "_1henIG_selectValue",
11396
+ "state": "_1henIG_state",
11320
11397
  "unavailableDot": "_1henIG_unavailableDot"
11321
11398
  };
11322
11399
  //#endregion
@@ -11588,12 +11665,117 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11588
11665
  return left.provider === right.provider && left.model === right.model && left.reasoningEffort === right.reasoningEffort;
11589
11666
  }
11590
11667
  //#endregion
11668
+ //#region src/client/TeamAgentImport.tsx
11669
+ /** Selection is a Host join, not a new Agent or a copied Session. */
11670
+ function TeamAgentImport({ workspaceId, loadMembers, joinWorkspace, onJoined, onPending, t }) {
11671
+ const [members, setMembers] = (0, react.useState)([]);
11672
+ const [loading, setLoading] = (0, react.useState)(true);
11673
+ const [error, setError] = (0, react.useState)();
11674
+ const [pending, setPending] = (0, react.useState)();
11675
+ const retry = (0, react.useRef)();
11676
+ const busy = (0, react.useRef)(false);
11677
+ const generation = (0, react.useRef)(0);
11678
+ const load = (0, react.useCallback)(async () => {
11679
+ const current = ++generation.current;
11680
+ setLoading(true);
11681
+ setError(void 0);
11682
+ try {
11683
+ const result = await loadMembers({});
11684
+ if (current !== generation.current) return;
11685
+ if (!result.ok) throw new Error(result.error.message);
11686
+ setMembers(result.value.filter((status) => (status.member.state === "enabled" || status.member.state === "suspended") && !status.workspaceIds.includes(workspaceId)));
11687
+ } catch (cause) {
11688
+ if (current === generation.current) setError(cause instanceof Error ? cause.message : String(cause));
11689
+ } finally {
11690
+ if (current === generation.current) setLoading(false);
11691
+ }
11692
+ }, [loadMembers, workspaceId]);
11693
+ (0, react.useEffect)(() => {
11694
+ load();
11695
+ return () => {
11696
+ generation.current++;
11697
+ };
11698
+ }, [load]);
11699
+ const join = async (status) => {
11700
+ if (busy.current) return;
11701
+ busy.current = true;
11702
+ setPending(status.member.memberId);
11703
+ onPending(true);
11704
+ setError(void 0);
11705
+ const request = retry.current?.memberId === status.member.memberId ? retry.current : {
11706
+ requestId: mintRequestId(),
11707
+ workspaceId,
11708
+ memberId: status.member.memberId
11709
+ };
11710
+ retry.current = request;
11711
+ try {
11712
+ const result = await joinWorkspace(request);
11713
+ if (!result.ok) throw new Error(result.error.message);
11714
+ await onJoined();
11715
+ } catch (cause) {
11716
+ setError(cause instanceof Error ? cause.message : String(cause));
11717
+ } finally {
11718
+ busy.current = false;
11719
+ setPending(void 0);
11720
+ onPending(false);
11721
+ }
11722
+ };
11723
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11724
+ className: create_module_css_default.form,
11725
+ children: [
11726
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
11727
+ className: create_module_css_default.notice,
11728
+ children: t("importAgentNotice")
11729
+ }),
11730
+ loading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
11731
+ className: create_module_css_default.state,
11732
+ role: "status",
11733
+ children: t("loadingAgents")
11734
+ }),
11735
+ !loading && error === void 0 && members.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
11736
+ className: create_module_css_default.state,
11737
+ children: t("emptyImportAgents")
11738
+ }),
11739
+ !loading && members.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11740
+ className: create_module_css_default.roster,
11741
+ children: members.map((status) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamMemberRow, {
11742
+ status,
11743
+ t,
11744
+ action: {
11745
+ label: pending === status.member.memberId ? t("importingAgent") : t("importAgent"),
11746
+ disabled: pending !== void 0,
11747
+ onSelect: () => {
11748
+ join(status);
11749
+ }
11750
+ }
11751
+ }, status.member.memberId))
11752
+ }),
11753
+ error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11754
+ className: create_module_css_default.failure,
11755
+ role: "alert",
11756
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
11757
+ className: create_module_css_default.error,
11758
+ children: error
11759
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
11760
+ disabled: pending !== void 0,
11761
+ variant: "outline",
11762
+ onClick: () => {
11763
+ load();
11764
+ },
11765
+ children: t("retry")
11766
+ })]
11767
+ })
11768
+ ]
11769
+ });
11770
+ }
11771
+ //#endregion
11591
11772
  //#region src/client/TeamAgentsPanel.tsx
11592
- function TeamAgentsPanel({ workspaceId, loadMembers, subscribeChanges, addMember, updateMember, recoverMember, archiveMember, loadModels, memberSessionId, openMemberSession, onCreatingChange, t }) {
11773
+ function TeamAgentsPanel({ workspaceId, loadMembers, subscribeChanges, addMember, updateMember, recoverMember, archiveMember, joinWorkspace, leaveWorkspace, loadModels, memberSessionId, openMemberSession, onCreatingChange, t }) {
11593
11774
  const [members, setMembers] = (0, react.useState)([]);
11594
11775
  const [loading, setLoading] = (0, react.useState)(true);
11595
11776
  const [error, setError] = (0, react.useState)();
11596
11777
  const [formOpen, setFormOpen] = (0, react.useState)(false);
11778
+ const [importing, setImporting] = (0, react.useState)(false);
11597
11779
  const [handle, setHandle] = (0, react.useState)("");
11598
11780
  const [description, setDescription] = (0, react.useState)("");
11599
11781
  const [model, setModel] = (0, react.useState)(void 0);
@@ -11707,9 +11889,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11707
11889
  try {
11708
11890
  const result = await addMember(request);
11709
11891
  if (result.ok) {
11892
+ const committed = {
11893
+ ...result.value.status,
11894
+ workspaceIds: [result.value.status.member.workspaceId]
11895
+ };
11710
11896
  setMembers((current) => {
11711
- const retained = current.filter((status) => status.member.memberId !== result.value.status.member.memberId);
11712
- return result.value.status.member.state === "inactive" || result.value.status.member.state === "archived" ? retained : [...retained, result.value.status];
11897
+ const retained = current.filter((status) => status.member.memberId !== committed.member.memberId);
11898
+ return committed.member.state === "inactive" || committed.member.state === "archived" ? retained : [...retained, committed];
11713
11899
  });
11714
11900
  setHandle("");
11715
11901
  setDescription("");
@@ -11749,7 +11935,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11749
11935
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11750
11936
  className: sidebar_module_css_default.panel,
11751
11937
  children: [
11752
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
11938
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
11753
11939
  open: formOpen,
11754
11940
  onClose: closeForm,
11755
11941
  title: t("addAgent"),
@@ -11760,14 +11946,37 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11760
11946
  disabled: creating,
11761
11947
  onClick: closeForm,
11762
11948
  children: t("cancel")
11763
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
11949
+ }), !importing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
11764
11950
  type: "submit",
11765
11951
  form: "team-agent-create-form",
11766
11952
  variant: "primary",
11767
11953
  disabled: creating || handle.trim().length === 0,
11768
11954
  children: creating ? t("creatingAgent") : t("createAgent")
11769
11955
  })] }),
11770
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
11956
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
11957
+ className: create_module_css_default.modeSwitch,
11958
+ variant: "outline",
11959
+ disabled: creating,
11960
+ "aria-expanded": importing,
11961
+ onClick: () => {
11962
+ setImporting((value) => !value);
11963
+ setError(void 0);
11964
+ },
11965
+ children: importing ? t("createAgent") : t("importAgentTitle")
11966
+ }), formOpen && importing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TeamAgentImport, {
11967
+ workspaceId,
11968
+ loadMembers,
11969
+ joinWorkspace,
11970
+ onPending: setCreating,
11971
+ onJoined: async () => {
11972
+ await refresh();
11973
+ setFormOpen(false);
11974
+ queueMicrotask(() => {
11975
+ triggerRef.current?.focus();
11976
+ });
11977
+ },
11978
+ t
11979
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
11771
11980
  id: "team-agent-create-form",
11772
11981
  className: create_module_css_default.form,
11773
11982
  onSubmit: submit,
@@ -11814,7 +12023,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11814
12023
  children: error
11815
12024
  })
11816
12025
  ]
11817
- })
12026
+ })]
11818
12027
  }),
11819
12028
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(TeamSidebarSection, {
11820
12029
  title: t("agents"),
@@ -11832,6 +12041,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11832
12041
  "aria-label": t("addAgent"),
11833
12042
  onClick: () => {
11834
12043
  setError(void 0);
12044
+ setImporting(false);
11835
12045
  setFormOpen(true);
11836
12046
  },
11837
12047
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, { size: 14 })
@@ -11852,6 +12062,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11852
12062
  drag,
11853
12063
  orderKey: status.member.memberId,
11854
12064
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AgentRow, {
12065
+ workspaceId,
12066
+ leaveWorkspace,
11855
12067
  status,
11856
12068
  ...memberSessionId === void 0 ? {} : { current: status.member.sessionId === memberSessionId },
11857
12069
  updateMember,
@@ -11859,9 +12071,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11859
12071
  archiveMember,
11860
12072
  loadModels,
11861
12073
  openMemberSession,
11862
- onUpdated: () => {
11863
- refresh();
11864
- },
12074
+ onUpdated: refresh,
11865
12075
  t
11866
12076
  })
11867
12077
  }, status.member.memberId))
@@ -11889,11 +12099,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11889
12099
  * conversation page, the avatar carries identity plus the presence badge, and
11890
12100
  * the row menu opens the editor.
11891
12101
  */
11892
- function AgentRow({ status, current, updateMember, recoverMember, archiveMember, loadModels, openMemberSession, onUpdated, t }) {
12102
+ function AgentRow({ workspaceId, leaveWorkspace, status, current, updateMember, recoverMember, archiveMember, loadModels, openMemberSession, onUpdated, t }) {
11893
12103
  const [menuOpen, setMenuOpen] = (0, react.useState)(false);
11894
12104
  const [editing, setEditing] = (0, react.useState)(false);
11895
12105
  const [archiving, setArchiving] = (0, react.useState)(false);
11896
12106
  const [rowAlert, setRowAlert] = (0, react.useState)();
12107
+ const [archivePending, setArchivePending] = (0, react.useState)(false);
12108
+ const archiveRequest = (0, react.useRef)();
12109
+ const withdrawing = workspaceId !== status.member.workspaceId;
11897
12110
  const recover = async () => {
11898
12111
  try {
11899
12112
  const result = await recoverMember({
@@ -11922,15 +12135,27 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11922
12135
  }
11923
12136
  };
11924
12137
  const archive = async () => {
12138
+ if (archivePending) return;
12139
+ setArchivePending(true);
12140
+ setRowAlert(void 0);
12141
+ archiveRequest.current ??= mintRequestId();
12142
+ const request = {
12143
+ requestId: archiveRequest.current,
12144
+ memberId: status.member.memberId
12145
+ };
11925
12146
  try {
11926
- const result = await archiveMember({
11927
- requestId: mintRequestId(),
11928
- memberId: status.member.memberId
11929
- });
12147
+ const result = withdrawing ? await leaveWorkspace({
12148
+ ...request,
12149
+ workspaceId
12150
+ }) : await archiveMember(request);
12151
+ if (!result.ok) throw new Error(result.error.message);
12152
+ setArchiving(false);
12153
+ archiveRequest.current = void 0;
11930
12154
  await onUpdated();
11931
- if (!result.ok) setRowAlert(t("archiveAgentFailed", { message: result.error.message }));
11932
12155
  } catch (cause) {
11933
- setRowAlert(t("archiveAgentFailed", { message: cause instanceof Error ? cause.message : String(cause) }));
12156
+ setRowAlert(cause instanceof Error ? cause.message : String(cause));
12157
+ } finally {
12158
+ setArchivePending(false);
11934
12159
  }
11935
12160
  };
11936
12161
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
@@ -11975,7 +12200,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11975
12200
  }] : [],
11976
12201
  {
11977
12202
  id: "archive",
11978
- label: t("archiveAgent"),
12203
+ label: t(withdrawing ? "withdrawAgent" : "archiveAgent"),
11979
12204
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconArchiveOutline20, { size: 16 }),
11980
12205
  danger: true
11981
12206
  }
@@ -11989,37 +12214,46 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11989
12214
  })
11990
12215
  })]
11991
12216
  }),
11992
- rowAlert !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
12217
+ !archiving && rowAlert !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11993
12218
  className: sidebar_module_css_default.rowAlert,
11994
12219
  role: "alert",
11995
12220
  children: rowAlert
11996
12221
  }),
11997
- archiving && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
12222
+ archiving && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
11998
12223
  open: true,
11999
12224
  onClose: () => {
12000
- setArchiving(false);
12225
+ if (!archivePending) setArchiving(false);
12001
12226
  },
12002
- title: t("archiveAgentTitle", { name: status.member.handle }),
12227
+ title: t(withdrawing ? "withdrawAgentTitle" : "archiveAgentTitle", { name: status.member.handle }),
12003
12228
  closeLabel: t("close"),
12004
12229
  contentClassName: create_module_css_default.dialogContent,
12005
12230
  footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
12006
12231
  variant: "outline",
12232
+ disabled: archivePending,
12007
12233
  onClick: () => {
12008
12234
  setArchiving(false);
12009
12235
  },
12010
12236
  children: t("cancel")
12011
12237
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
12012
12238
  variant: "primary",
12239
+ disabled: archivePending,
12013
12240
  onClick: () => {
12014
- setArchiving(false);
12015
12241
  archive();
12016
12242
  },
12017
- children: t("archiveAgentConfirm")
12243
+ children: t(withdrawing ? "withdrawAgent" : "archiveAgentConfirm")
12018
12244
  })] }),
12019
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
12020
- className: create_module_css_default.error,
12021
- children: t("archiveAgentNotice", { name: status.member.handle })
12022
- })
12245
+ children: [
12246
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
12247
+ className: create_module_css_default.error,
12248
+ children: t(withdrawing ? "withdrawAgentNotice" : "archiveAgentNotice", { name: status.member.handle })
12249
+ }),
12250
+ !withdrawing && status.workspaceIds.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("archiveOtherWorkspaces", { count: status.workspaceIds.length - 1 }) }),
12251
+ rowAlert !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
12252
+ className: create_module_css_default.error,
12253
+ role: "alert",
12254
+ children: rowAlert
12255
+ })
12256
+ ]
12023
12257
  }),
12024
12258
  editing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AgentEditorDialog, {
12025
12259
  status,
@@ -12629,7 +12863,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12629
12863
  })]
12630
12864
  });
12631
12865
  }
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 }) {
12866
+ function TeamWorkspaceBrowser({ wide, expandSidebar, navigation, selectWorkspace, selectChannel, selectInbox, t, useWorkspaces, loadMembers, loadInbox, subscribeChanges, subscribeReads, addMember, loadChannels, createChannel, updateChannel, archiveChannel, updateMember, recoverMember, archiveMember, joinWorkspace, leaveWorkspace, joinChannel, removeChannelMember, loadModels, openMemberSession }) {
12633
12867
  const navigationState = (0, react.useSyncExternalStore)(navigation.subscribe, navigation.getSnapshot, navigation.getSnapshot);
12634
12868
  const workspaces = useWorkspaces((state) => state.items);
12635
12869
  const selected = navigationState.workspaceId;
@@ -12810,6 +13044,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12810
13044
  updateMember,
12811
13045
  recoverMember,
12812
13046
  archiveMember,
13047
+ joinWorkspace,
13048
+ leaveWorkspace,
12813
13049
  loadModels,
12814
13050
  ...navigationState.memberSessionId === void 0 ? {} : { memberSessionId: navigationState.memberSessionId },
12815
13051
  openMemberSession,
@@ -12837,6 +13073,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12837
13073
  teamMode: "团队模式",
12838
13074
  workspaceSections: "工作区内容",
12839
13075
  addAgent: "添加 Agent",
13076
+ importAgentTitle: "从其他 Workspace 引入",
13077
+ importAgent: "引入",
13078
+ importingAgent: "引入中…",
13079
+ importAgentNotice: "选择已有 Agent 加入当前 Workspace。身份、记忆与会话保持不变;Channel 仍需另行加入。",
13080
+ emptyImportAgents: "没有可引入的 Agent。",
13081
+ withdrawAgent: "从此 Workspace 撤回",
13082
+ withdrawAgentTitle: "撤回 {name}?",
13083
+ withdrawAgentNotice: "仅撤出当前 Workspace:退出此处所有 Channel、释放活跃 Claim 并清除 Attention。其他 Workspace 的工作、会话和私有记忆不受影响。",
13084
+ archiveOtherWorkspaces: "同时从其他 {count} 个 Workspace 收起。",
12840
13085
  cancel: "取消",
12841
13086
  close: "关闭",
12842
13087
  copyCode: "复制",
@@ -13004,6 +13249,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
13004
13249
  teamMode: "Team mode",
13005
13250
  workspaceSections: "Workspace sections",
13006
13251
  addAgent: "Add Agent",
13252
+ importAgentTitle: "Bring in from another Workspace",
13253
+ importAgent: "Bring in",
13254
+ importingAgent: "Joining…",
13255
+ importAgentNotice: "Choose an existing Agent to join this Workspace. Identity, memory, and session stay unchanged; join Channels separately.",
13256
+ emptyImportAgents: "No Agents available to bring in.",
13257
+ withdrawAgent: "Withdraw from this Workspace",
13258
+ withdrawAgentTitle: "Withdraw {name}?",
13259
+ withdrawAgentNotice: "Leave only this Workspace: exit its Channels, release active Claims, and clear Attention. Work elsewhere, the session, and private memory stay unchanged.",
13260
+ archiveOtherWorkspaces: "Also hides this Agent in {count} other Workspace(s).",
13007
13261
  cancel: "Cancel",
13008
13262
  close: "Close",
13009
13263
  copyCode: "Copy",
@@ -13196,6 +13450,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
13196
13450
  recoverMember: (request) => ctx.remote.agentTeam.recoverMember(request),
13197
13451
  clearMemberContext: (request) => ctx.remote.agentTeam.clearMemberContext(request),
13198
13452
  archiveMember: (request) => ctx.remote.agentTeam.archiveMember(request),
13453
+ joinWorkspace: (request) => ctx.remote.agentTeam.joinWorkspace(request),
13454
+ leaveWorkspace: (request) => ctx.remote.agentTeam.leaveWorkspace(request),
13199
13455
  loadModels: () => ctx.remote.session.modelCatalog(),
13200
13456
  openMemberSession: openMemberSessionImpl
13201
13457
  };
@@ -13284,7 +13540,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
13284
13540
  restore();
13285
13541
  };
13286
13542
  }, "agent-team: member session restore");
13287
- const changes = new TeamChangeStream((request, signal) => ctx.remote.agentTeam.changes(request, signal));
13543
+ const changes = new TeamChangeStream(ctx.remote);
13544
+ ctx.effect(() => () => changes.dispose(), "agent-team: change subscriptions");
13545
+ ctx.on("connection/reset", () => {
13546
+ changes.recover();
13547
+ });
13288
13548
  const reads = new TeamReadStream();
13289
13549
  const loadMemberGroups = async () => {
13290
13550
  const workspaces = ctx.workspaces.list.getSnapshot().items;