@wowyuarm/dsh-agent-team 0.1.14 → 0.2.0

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 (102) hide show
  1. package/README.md +8 -4
  2. package/README.zh.md +8 -4
  3. package/cordis.patch.yml +187 -2
  4. package/package.json +52 -51
  5. package/packages/agent-team/README.md +1 -1
  6. package/packages/agent-team/README.zh.md +1 -1
  7. package/packages/agent-team/lib/context-continuity-host.js +2 -3
  8. package/packages/agent-team/lib/context-projection.js +3 -3
  9. package/packages/agent-team/lib/context-source.js +39 -13
  10. package/packages/agent-team/lib/environment-check.js +102 -0
  11. package/packages/agent-team/lib/human-profile.js +110 -13
  12. package/packages/agent-team/lib/index.js +192 -100
  13. package/packages/agent-team/lib/installed-manifest.js +32 -0
  14. package/packages/agent-team/lib/ledger.js +35 -0
  15. package/packages/agent-team/lib/member-context.js +3 -3
  16. package/packages/agent-team/lib/member-time-context.js +3 -2
  17. package/packages/agent-team/lib/pressure-policy.js +18 -11
  18. package/packages/agent-team/lib/stored-session-reader.js +1 -2
  19. package/packages/agent-team/lib/typert.host.js +479 -260
  20. package/packages/agent-team/lib/typert.remote-client.d.ts +8 -3
  21. package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
  22. package/packages/agent-team/lib/typert.remote-client.js +375 -228
  23. package/packages/agent-team/lib/types/context-continuity-host.d.ts.map +1 -1
  24. package/packages/agent-team/lib/types/context-source.d.ts +49 -13
  25. package/packages/agent-team/lib/types/context-source.d.ts.map +1 -1
  26. package/packages/agent-team/lib/types/environment-check.d.ts +66 -0
  27. package/packages/agent-team/lib/types/environment-check.d.ts.map +1 -0
  28. package/packages/agent-team/lib/types/human-profile.d.ts +87 -21
  29. package/packages/agent-team/lib/types/human-profile.d.ts.map +1 -1
  30. package/packages/agent-team/lib/types/index.d.ts +85 -26
  31. package/packages/agent-team/lib/types/index.d.ts.map +1 -1
  32. package/packages/agent-team/lib/types/installed-manifest.d.ts +16 -0
  33. package/packages/agent-team/lib/types/installed-manifest.d.ts.map +1 -0
  34. package/packages/agent-team/lib/types/ledger.d.ts +12 -0
  35. package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
  36. package/packages/agent-team/lib/types/member-context.d.ts +14 -0
  37. package/packages/agent-team/lib/types/member-context.d.ts.map +1 -1
  38. package/packages/agent-team/lib/types/member-time-context.d.ts +15 -0
  39. package/packages/agent-team/lib/types/member-time-context.d.ts.map +1 -1
  40. package/packages/agent-team/lib/types/pressure-policy.d.ts +5 -1
  41. package/packages/agent-team/lib/types/pressure-policy.d.ts.map +1 -1
  42. package/packages/agent-team/lib/types/stored-session-reader.d.ts +1 -2
  43. package/packages/agent-team/lib/types/stored-session-reader.d.ts.map +1 -1
  44. package/packages/agent-team/lib/types/types/entities.d.ts +1 -8
  45. package/packages/agent-team/lib/types/types/entities.d.ts.map +1 -1
  46. package/packages/agent-team/lib/types/types/requests-results.d.ts +84 -0
  47. package/packages/agent-team/lib/types/types/requests-results.d.ts.map +1 -1
  48. package/packages/client-agent-team/README.md +1 -1
  49. package/packages/client-agent-team/README.zh.md +1 -1
  50. package/packages/client-agent-team/lib/client.js +615 -275
  51. package/packages/client-agent-team/lib/client.js.map +1 -1
  52. package/packages/client-agent-team/lib/types/client/EnvironmentCheck.d.ts +18 -0
  53. package/packages/client-agent-team/lib/types/client/EnvironmentCheck.d.ts.map +1 -0
  54. package/packages/client-agent-team/lib/types/client/EnvironmentCheck.js +58 -0
  55. package/packages/client-agent-team/lib/types/client/HumanSettingsSection.d.ts +3 -0
  56. package/packages/client-agent-team/lib/types/client/HumanSettingsSection.d.ts.map +1 -1
  57. package/packages/client-agent-team/lib/types/client/HumanSettingsSection.js +7 -4
  58. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +6 -11
  59. package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +3 -3
  60. package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.js +4 -4
  61. package/packages/client-agent-team/lib/types/client/TeamComposer.js +3 -3
  62. package/packages/client-agent-team/lib/types/client/TeamFooterAction.js +2 -2
  63. package/packages/client-agent-team/lib/types/client/TeamMemberEditor.js +3 -3
  64. package/packages/client-agent-team/lib/types/client/TeamMembersAction.js +2 -2
  65. package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts.map +1 -1
  66. package/packages/client-agent-team/lib/types/client/TeamMessage.js +1 -1
  67. package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts +1 -1
  68. package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts.map +1 -1
  69. package/packages/client-agent-team/lib/types/client/TeamPresenceDot.js +2 -7
  70. package/packages/client-agent-team/lib/types/client/TeamRowMenu.d.ts.map +1 -1
  71. package/packages/client-agent-team/lib/types/client/TeamRowMenu.js +2 -2
  72. package/packages/client-agent-team/lib/types/client/TeamSidebarSection.js +2 -2
  73. package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +3 -3
  74. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +3 -3
  75. package/packages/client-agent-team/lib/types/client/TeamWorkspaceSelector.js +2 -2
  76. package/packages/client-agent-team/lib/types/client/environment-check.d.ts +65 -0
  77. package/packages/client-agent-team/lib/types/client/environment-check.d.ts.map +1 -0
  78. package/packages/client-agent-team/lib/types/client/environment-check.js +78 -0
  79. package/packages/client-agent-team/lib/types/client/human-identity.d.ts +4 -8
  80. package/packages/client-agent-team/lib/types/client/human-identity.d.ts.map +1 -1
  81. package/packages/client-agent-team/lib/types/client/human-identity.js +0 -21
  82. package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
  83. package/packages/client-agent-team/lib/types/client/index.js +59 -49
  84. package/packages/client-agent-team/lib/types/client/locales.d.ts +18 -8
  85. package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
  86. package/packages/client-agent-team/lib/types/client/locales.js +21 -8
  87. package/packages/client-agent-team/lib/types/client/multi-menu-field.js +2 -2
  88. package/packages/client-agent-team/lib/types/client/slots.d.ts +1 -1
  89. package/packages/tool-agent-team/README.md +1 -1
  90. package/packages/tool-agent-team/README.zh.md +1 -1
  91. package/packages/tool-agent-team/lib/context-tools.js +106 -94
  92. package/packages/tool-agent-team/lib/index.js +17 -2
  93. package/packages/tool-agent-team/lib/types/context-tools.d.ts +16 -7
  94. package/packages/tool-agent-team/lib/types/context-tools.d.ts.map +1 -1
  95. package/packages/tool-agent-team/lib/types/index.d.ts.map +1 -1
  96. package/packages/agent-team/lib/preset-roster.js +0 -15
  97. package/packages/agent-team/lib/session-remediation.js +0 -493
  98. package/packages/agent-team/lib/types/preset-roster.d.ts +0 -5
  99. package/packages/agent-team/lib/types/preset-roster.d.ts.map +0 -1
  100. package/packages/agent-team/lib/types/session-remediation.d.ts +0 -172
  101. package/packages/agent-team/lib/types/session-remediation.d.ts.map +0 -1
  102. package/packages/agent-team/preset/team-member/agent.cordis.yml +0 -166
@@ -0,0 +1,65 @@
1
+ import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
2
+ import type { AgentTeamEnvironmentResult } from '@wowyuarm/dsh-agent-team/types';
3
+ /**
4
+ * The Client's one projection of the local environment check.
5
+ *
6
+ * Deliberately separate from the Human identity projection: this is a fact
7
+ * about the installation, not about the Human, it is read once and never
8
+ * written back, and the settings page is the only surface that renders it.
9
+ * Folding it into the identity store would make every seat that names the
10
+ * Human depend on a version comparison it has no use for.
11
+ *
12
+ * Reads are demand-driven off the first subscriber, so an ordinary conversation
13
+ * never calls the Remote. There is no retry: `undetermined` is a settled
14
+ * verdict about facts the Host could not establish, not a failed request, so a
15
+ * reader has nothing to retry.
16
+ */
17
+ /** One read of the environment check, replaced wholesale on every change. */
18
+ export interface TeamEnvironmentSnapshot {
19
+ /** `loading` until the first read settles, `ready` once it has. */
20
+ readonly status: 'loading' | 'ready';
21
+ /** The report to render; undefined until the first read settles. */
22
+ readonly report?: AgentTeamEnvironmentResult | undefined;
23
+ }
24
+ /** Read-side face the settings page binds. */
25
+ export interface TeamEnvironmentSource {
26
+ getSnapshot(): TeamEnvironmentSnapshot;
27
+ subscribe(listener: () => void): () => void;
28
+ }
29
+ /** Host call the store reads through; one loader per Client context. */
30
+ export interface TeamEnvironmentLoader {
31
+ loadEnvironment: () => Promise<RemoteResult<AgentTeamEnvironmentResult>>;
32
+ }
33
+ export declare class TeamEnvironmentCheck implements TeamEnvironmentSource {
34
+ private snapshot;
35
+ private readonly listeners;
36
+ private reading;
37
+ private readonly loader;
38
+ constructor(loader: TeamEnvironmentLoader);
39
+ readonly getSnapshot: () => TeamEnvironmentSnapshot;
40
+ /**
41
+ * Observe the check, starting the first read when nobody has read yet.
42
+ * @param listener - invoked after every snapshot replacement.
43
+ * @returns the disposer removing this listener.
44
+ */
45
+ readonly subscribe: (listener: () => void) => (() => void);
46
+ /**
47
+ * Read the Host projection. Concurrent callers share one round trip, and a
48
+ * failed read keeps the last accepted report — the block never blanks out
49
+ * over a background read.
50
+ * @returns settlement of this read (or of the read already in flight).
51
+ */
52
+ refresh(): Promise<void>;
53
+ dispose(): void;
54
+ private read;
55
+ /**
56
+ * Settle a read that produced no report, so a reader stops waiting on a
57
+ * `loading` that will never finish. A report that already stands is left
58
+ * untouched: a failed background read never blanks the block.
59
+ */
60
+ private fail;
61
+ private commit;
62
+ }
63
+ /** Subscribe one rendered block to the environment check. */
64
+ export declare function useEnvironmentCheck(environment: TeamEnvironmentSource): TeamEnvironmentSnapshot;
65
+ //# sourceMappingURL=environment-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment-check.d.ts","sourceRoot":"","sources":["../../../src/client/environment-check.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACpE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAA;AAEhF;;;;;;;;;;;;;GAaG;AAEH,6EAA6E;AAC7E,MAAM,WAAW,uBAAuB;IACtC,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAA;IACpC,oEAAoE;IACpE,QAAQ,CAAC,MAAM,CAAC,EAAE,0BAA0B,GAAG,SAAS,CAAA;CACzD;AAED,8CAA8C;AAC9C,MAAM,WAAW,qBAAqB;IACpC,WAAW,IAAI,uBAAuB,CAAA;IACtC,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;CAC5C;AAED,wEAAwE;AACxE,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAAC,CAAA;CACzE;AAID,qBAAa,oBAAqB,YAAW,qBAAqB;IAChE,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAClD,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;gBAElC,MAAM,EAAE,qBAAqB;IAIzC,QAAQ,CAAC,WAAW,QAAO,uBAAuB,CAAiB;IAEnE;;;;OAIG;IACH,QAAQ,CAAC,SAAS,GAAI,UAAU,MAAM,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC,CAIxD;IAED;;;;;OAKG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IASxB,OAAO,IAAI,IAAI;YAID,IAAI;IAkBlB;;;;OAIG;IACH,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,MAAM;CAIf;AAED,6DAA6D;AAC7D,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,qBAAqB,GAAG,uBAAuB,CAE/F"}
@@ -0,0 +1,78 @@
1
+ import { useSyncExternalStore } from 'react';
2
+ const INITIAL = { status: 'loading' };
3
+ export class TeamEnvironmentCheck {
4
+ snapshot = INITIAL;
5
+ listeners = new Set();
6
+ reading;
7
+ loader;
8
+ constructor(loader) {
9
+ this.loader = loader;
10
+ }
11
+ getSnapshot = () => this.snapshot;
12
+ /**
13
+ * Observe the check, starting the first read when nobody has read yet.
14
+ * @param listener - invoked after every snapshot replacement.
15
+ * @returns the disposer removing this listener.
16
+ */
17
+ subscribe = (listener) => {
18
+ this.listeners.add(listener);
19
+ if (this.snapshot.status === 'loading' && this.reading === undefined)
20
+ void this.refresh();
21
+ return () => { this.listeners.delete(listener); };
22
+ };
23
+ /**
24
+ * Read the Host projection. Concurrent callers share one round trip, and a
25
+ * failed read keeps the last accepted report — the block never blanks out
26
+ * over a background read.
27
+ * @returns settlement of this read (or of the read already in flight).
28
+ */
29
+ refresh() {
30
+ if (this.reading !== undefined)
31
+ return this.reading;
32
+ const reading = this.read().finally(() => {
33
+ if (this.reading === reading)
34
+ this.reading = undefined;
35
+ });
36
+ this.reading = reading;
37
+ return reading;
38
+ }
39
+ dispose() {
40
+ this.listeners.clear();
41
+ }
42
+ async read() {
43
+ let report;
44
+ try {
45
+ const result = await this.loader.loadEnvironment();
46
+ if (!result.ok) {
47
+ this.fail();
48
+ return;
49
+ }
50
+ report = result.value;
51
+ }
52
+ catch {
53
+ // A dropped connection surfaces as a thrown carrier error, not a result:
54
+ // both are read failures and both keep whatever report already stands.
55
+ this.fail();
56
+ return;
57
+ }
58
+ this.commit({ status: 'ready', report });
59
+ }
60
+ /**
61
+ * Settle a read that produced no report, so a reader stops waiting on a
62
+ * `loading` that will never finish. A report that already stands is left
63
+ * untouched: a failed background read never blanks the block.
64
+ */
65
+ fail() {
66
+ if (this.snapshot.report === undefined)
67
+ this.commit({ status: 'ready' });
68
+ }
69
+ commit(snapshot) {
70
+ this.snapshot = snapshot;
71
+ for (const listener of this.listeners)
72
+ listener();
73
+ }
74
+ }
75
+ /** Subscribe one rendered block to the environment check. */
76
+ export function useEnvironmentCheck(environment) {
77
+ return useSyncExternalStore(environment.subscribe, environment.getSnapshot, environment.getSnapshot);
78
+ }
@@ -4,23 +4,19 @@ import type { AgentTeamHumanProfileResult } from '@wowyuarm/dsh-agent-team/types
4
4
  * The Client's one projection of the Human identity.
5
5
  *
6
6
  * The durable facts live in the Host: the display name and the avatar
7
- * reference in the `agent-team-human` settings section, the avatar bytes in the
7
+ * reference in the Team Host row's own Config, the avatar bytes in the
8
8
  * persistent avatar store. This store is the only place the Team Client reads
9
9
  * them, so every seat that names or draws the Human — message rows, member
10
10
  * refs, mention chips, the settings page — shows one rename and one face, and a
11
- * single refresh after a write moves all of them together.
11
+ * single refresh after a write moves all of them together. Writes go back
12
+ * through the Host's `setHumanProfile` Remote, which owns the profile entry the
13
+ * Client would otherwise have to name.
12
14
  *
13
15
  * Seats render before the first read settles; `name` stays undefined until then
14
16
  * and every caller falls back to its own localized name for the Human. Reads
15
17
  * are demand-driven: the first subscriber starts the read, so a Client that
16
18
  * never opens Team mode or the profile page never calls the Remote.
17
19
  */
18
- /**
19
- * Host settings namespace that holds the Human profile. The Host declares the
20
- * same string (`HUMAN_PROFILE_SETTINGS_NAMESPACE`) on its own side of the
21
- * bundle boundary, and a test pins the two together.
22
- */
23
- export declare const HUMAN_PROFILE_NAMESPACE = "agent-team-human";
24
20
  /** One read of the Human identity, replaced wholesale on every change. */
25
21
  export interface TeamHumanIdentitySnapshot {
26
22
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"human-identity.d.ts","sourceRoot":"","sources":["../../../src/client/human-identity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACpE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAA;AAEjF;;;;;;;;;;;;;;GAcG;AAEH;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,qBAAqB,CAAA;AAEzD,0EAA0E;AAC1E,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,aAAa,CAAA;IACpD,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,wFAAwF;IACxF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,gDAAgD;IAChD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,6CAA6C;IAC7C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;IACjC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3C,iFAAiF;IACjF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC;AAED,wFAAwF;AACxF,MAAM,WAAW,uBAAuB;IACtC,WAAW,IAAI,yBAAyB,CAAA;IACxC,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;CAC5C;AAED,iFAAiF;AACjF,MAAM,WAAW,qBAAsB,SAAQ,uBAAuB;IACpE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACzB;AAED,yEAAyE;AACzE,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,2BAA2B,CAAC,CAAC,CAAA;IACrE,yFAAyF;IACzF,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;CAC7D;AAID,qBAAa,iBAAkB,YAAW,qBAAqB;IAC7D,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAClD,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;gBAEpC,MAAM,EAAE,uBAAuB;IAI3C,QAAQ,CAAC,WAAW,QAAO,yBAAyB,CAAiB;IAErE;;;;OAIG;IACH,QAAQ,CAAC,SAAS,GAAI,UAAU,MAAM,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC,CAIxD;IAED;;;;;OAKG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IASxB,OAAO,IAAI,IAAI;YAID,IAAI;IAkClB;;;;OAIG;IACH,OAAO,CAAC,IAAI;IAOZ,OAAO,CAAC,MAAM;CAIf;AAED,mDAAmD;AACnD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,uBAAuB,GAAG,yBAAyB,CAE7F"}
1
+ {"version":3,"file":"human-identity.d.ts","sourceRoot":"","sources":["../../../src/client/human-identity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACpE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAA;AAEjF;;;;;;;;;;;;;;;;GAgBG;AAEH,0EAA0E;AAC1E,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,aAAa,CAAA;IACpD,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,wFAAwF;IACxF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,gDAAgD;IAChD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,6CAA6C;IAC7C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;IACjC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3C,iFAAiF;IACjF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC;AAED,wFAAwF;AACxF,MAAM,WAAW,uBAAuB;IACtC,WAAW,IAAI,yBAAyB,CAAA;IACxC,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;CAC5C;AAED,iFAAiF;AACjF,MAAM,WAAW,qBAAsB,SAAQ,uBAAuB;IACpE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACzB;AAED,yEAAyE;AACzE,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,2BAA2B,CAAC,CAAC,CAAA;IACrE,yFAAyF;IACzF,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;CAC7D;AAID,qBAAa,iBAAkB,YAAW,qBAAqB;IAC7D,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAClD,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;gBAEpC,MAAM,EAAE,uBAAuB;IAI3C,QAAQ,CAAC,WAAW,QAAO,yBAAyB,CAAiB;IAErE;;;;OAIG;IACH,QAAQ,CAAC,SAAS,GAAI,UAAU,MAAM,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC,CAIxD;IAED;;;;;OAKG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IASxB,OAAO,IAAI,IAAI;YAID,IAAI;IAkClB;;;;OAIG;IACH,OAAO,CAAC,IAAI;IAOZ,OAAO,CAAC,MAAM;CAIf;AAED,mDAAmD;AACnD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,uBAAuB,GAAG,yBAAyB,CAE7F"}
@@ -1,25 +1,4 @@
1
1
  import { useSyncExternalStore } from 'react';
2
- /**
3
- * The Client's one projection of the Human identity.
4
- *
5
- * The durable facts live in the Host: the display name and the avatar
6
- * reference in the `agent-team-human` settings section, the avatar bytes in the
7
- * persistent avatar store. This store is the only place the Team Client reads
8
- * them, so every seat that names or draws the Human — message rows, member
9
- * refs, mention chips, the settings page — shows one rename and one face, and a
10
- * single refresh after a write moves all of them together.
11
- *
12
- * Seats render before the first read settles; `name` stays undefined until then
13
- * and every caller falls back to its own localized name for the Human. Reads
14
- * are demand-driven: the first subscriber starts the read, so a Client that
15
- * never opens Team mode or the profile page never calls the Remote.
16
- */
17
- /**
18
- * Host settings namespace that holds the Human profile. The Host declares the
19
- * same string (`HUMAN_PROFILE_SETTINGS_NAMESPACE`) on its own side of the
20
- * bundle boundary, and a test pins the two together.
21
- */
22
- export const HUMAN_PROFILE_NAMESPACE = 'agent-team-human';
23
2
  const INITIAL = { status: 'loading', updateAvailable: false };
24
3
  export class TeamHumanIdentity {
25
4
  snapshot = INITIAL;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAA;AA6CnE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAK5C,OAAO,EAAU,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAEnD,YAAY,EAAE,QAAQ,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AAC9F,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAIhD,eAAO,MAAM,MAAM,UAElB,CAAA;AAED,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,kBAAkB;QAC1B,IAAI,EAAE,OAAO,CAAA;KACd;CACF;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,cAAc,EAAE,cAAc,CAAA;QAC9B,UAAU,EAAE,cAAc,CAAA;KAC3B;CACF;AAqRD,wBAAsB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAA;AA8CnE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAK5C,OAAO,EAAU,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAEnD,YAAY,EAAE,QAAQ,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AAC9F,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAIhD,eAAO,MAAM,MAAM,UAElB,CAAA;AAuBD,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,kBAAkB;QAC1B,IAAI,EAAE,OAAO,CAAA;KACd;CACF;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,cAAc,EAAE,cAAc,CAAA;QAC9B,UAAU,EAAE,cAAc,CAAA;KAC3B;CACF;AA8QD,wBAAsB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7D"}
@@ -1,6 +1,7 @@
1
1
  import agentTeamRemote from '@wowyuarm/dsh-agent-team/remote';
2
2
  import { HumanSettingsSection } from "./HumanSettingsSection.js";
3
- import { HUMAN_PROFILE_NAMESPACE, TeamHumanIdentity } from "./human-identity.js";
3
+ import { TeamHumanIdentity } from "./human-identity.js";
4
+ import { TeamEnvironmentCheck } from "./environment-check.js";
4
5
  import { bytesToBase64 } from "./attachment-preview.js";
5
6
  import { TeamNavigation } from "./navigation.js";
6
7
  import { TeamChangeStream, TeamReadStream } from "./team-changes.js";
@@ -13,8 +14,27 @@ import { en, zh } from "./locales.js";
13
14
  export { TeamNavigation } from "./navigation.js";
14
15
  const NS = 'team';
15
16
  export const inject = [
16
- 'slots', 'workspaces', 'locale', 'remote', 'remote.session', 'sessions', 'connection', 'conversation',
17
+ 'slots', 'workspaces', 'locale', 'remote', 'remote.session', 'sessions', 'connection', 'conversation', 'uiWorkspace',
17
18
  ];
19
+ /**
20
+ * 0.1.7 moved the conversation selection into the workspace service: the
21
+ * rendered session is the one holding its `mainView` reference (the shipped
22
+ * consumers read the same projection), so the Team client reads the selection
23
+ * through retention instead of a service-owned `current`.
24
+ */
25
+ function currentMainSessionId(ctx) {
26
+ const sessions = ctx.sessions;
27
+ return Object.values(sessions.list.getSnapshot().byId)
28
+ .find(session => (session.retainedBy.mainView ?? 0) > 0)?.id;
29
+ }
30
+ /**
31
+ * Session ids this client opened as Member views, per client instance. The
32
+ * 0.1.7 workspace service exposes no clear, so a dead return target leaves
33
+ * the departed Member selection in place; excluding Member sessions from the
34
+ * next capture keeps that stale selection from becoming a false return
35
+ * target.
36
+ */
37
+ const openedMemberSessions = new WeakMap();
18
38
  function registerModeShadow(ctx, navigation, changes, reads, drafts, humanIdentity, name, component, extraInject,
19
39
  // Keyed seats (`main`) address one panel by key; the reserved 'conversation'
20
40
  // key is where the shipped Conversation registers, so the Team seat shadows
@@ -24,14 +44,16 @@ entryKey) {
24
44
  // views (see registerModeShadow), so the shipped conversation root renders
25
45
  // the selected Member Session inside the Team shell.
26
46
  const openMemberSessionImpl = (sessionId) => {
27
- const sessions = ctx.sessions;
28
47
  const snapshot = navigation.getSnapshot();
29
- const current = sessions.list.getSnapshot().current;
48
+ const current = currentMainSessionId(ctx);
30
49
  // The return target is captured on first entry only — switching between
31
50
  // Member Sessions must keep pointing at the Human's original session.
32
- const returnTo = snapshot.memberSessionId === undefined && current !== undefined && current !== sessionId ? current : undefined;
51
+ const memberSessions = openedMemberSessions.get(ctx) ?? new Set();
52
+ openedMemberSessions.set(ctx, memberSessions);
53
+ memberSessions.add(sessionId);
54
+ const returnTo = snapshot.memberSessionId === undefined && current !== undefined && current !== sessionId && !memberSessions.has(current) ? current : undefined;
33
55
  navigation.actions().enterMemberSession(sessionId, returnTo);
34
- sessions.open(sessionId);
56
+ ctx.uiWorkspace.openSession(sessionId);
35
57
  };
36
58
  // Remote bindings shared by every Team slot; surface-specific entries extend it below.
37
59
  const sharedRemotes = {
@@ -126,16 +148,8 @@ function applyUi(ctx) {
126
148
  // The Human's own identity: one projection every seat reads, refreshed once
127
149
  // after a profile write so a rename reaches the timeline and the member refs
128
150
  // without a reload. Reads are demand-driven — the first seat that subscribes
129
- // starts the read.
130
- // The profile page writes through the settings transport. It arrives from the
131
- // settings plugin, and Cordis refuses a `remote.<namespace>` read that was
132
- // never injected, so the binding is an optional injection rather than either
133
- // a hard activation dependency (a settings-less host would lose Team mode
134
- // entirely) or an undeclared read (which throws at the first write).
135
- let settingsTransport;
136
- ctx.inject(['remote.settings'], (scope) => {
137
- settingsTransport = scope.remote.settings;
138
- });
151
+ // starts the read. The profile page writes back through the Team Remote, so
152
+ // the Client never names the Host's own profile entry.
139
153
  const humanIdentity = new TeamHumanIdentity({
140
154
  loadProfile: () => ctx.remote.agentTeam.humanProfile({}),
141
155
  loadAvatarUrl: async (avatarRef) => {
@@ -147,20 +161,28 @@ function applyUi(ctx) {
147
161
  return `data:${result.value.mediaType};base64,${result.value.bytesBase64}`;
148
162
  },
149
163
  });
164
+ // The local environment check: a fact about this installation rather than
165
+ // about the Human, so it is its own projection and never a field of the
166
+ // identity above. Read once, on the first subscriber, and never written back.
167
+ const environment = new TeamEnvironmentCheck({
168
+ loadEnvironment: () => ctx.remote.agentTeam.environment({}),
169
+ });
150
170
  ctx.effect(() => () => {
151
171
  navigation.dispose();
152
172
  drafts.dispose();
153
173
  humanIdentity.dispose();
174
+ environment.dispose();
154
175
  void disposeNavigation();
155
176
  void disposeDrafts();
156
177
  }, 'agent-team: navigation service');
157
178
  // The one restore owner: leaving an embedded Member Session view must
158
- // rebind the underlying current session, or the stale Member current later
159
- // masks to undefined when the Host disposes that session (rollover) and
160
- // the conversation seat remounts. Takeover is conditional — only when the
161
- // current still IS the departed Member session — so a selection someone
162
- // else made in the meantime survives. A dead return target clears instead
163
- // of opening an unknown id.
179
+ // rebind the underlying selection, or the departed Member session stays the
180
+ // workspace service's `mainView` retention into the next Member entry's
181
+ // return-target capture. Takeover is conditional — only when the selection
182
+ // still IS the departed Member session — so a selection someone else made
183
+ // in the meantime survives. A dead return target keeps the departed
184
+ // selection: 0.1.7 exposes no public clear, and the retention is inert
185
+ // behind the Team seat until the next open.
164
186
  ctx.effect(() => {
165
187
  let previous = navigation.getSnapshot();
166
188
  const restore = () => {
@@ -170,13 +192,10 @@ function applyUi(ctx) {
170
192
  previous = snapshot;
171
193
  if (departed === undefined || snapshot.memberSessionId !== undefined)
172
194
  return;
173
- const sessions = ctx.sessions;
174
- if (sessions.list.getSnapshot().current !== departed)
195
+ if (currentMainSessionId(ctx) !== departed)
175
196
  return;
176
- if (returnTo !== undefined && sessions.list.getSnapshot().byId[returnTo] !== undefined)
177
- sessions.open(returnTo);
178
- else
179
- sessions.clear();
197
+ if (returnTo !== undefined && ctx.sessions.list.getSnapshot().byId[returnTo] !== undefined)
198
+ ctx.uiWorkspace.openSession(returnTo);
180
199
  };
181
200
  const unsubscribe = navigation.subscribe(restore);
182
201
  return () => {
@@ -213,7 +232,7 @@ function applyUi(ctx) {
213
232
  navigation,
214
233
  ...navigation.actions(),
215
234
  // The footer is the only surface that leaves Team mode; closing the
216
- // embedded Member Session view rebinds the underlying current through
235
+ // embedded Member Session view rebinds the underlying selection through
217
236
  // the same root-scope restore owner, so there is exactly one restore
218
237
  // path and no double open.
219
238
  leaveTeam: () => {
@@ -225,12 +244,12 @@ function applyUi(ctx) {
225
244
  registerModeShadow(ctx, navigation, changes, reads, drafts, humanIdentity, 'sidebar.workspaces', TeamWorkspaceBrowser);
226
245
  registerModeShadow(ctx, navigation, changes, reads, drafts, humanIdentity, 'main', TeamConversation, undefined, 'conversation');
227
246
  registerModeShadow(ctx, navigation, changes, reads, drafts, humanIdentity, 'sidebar.settings', TeamMembersAction, () => ({ loadMemberGroups }));
228
- // The Human profile page: one settings section over the `agent-team-human`
229
- // namespace, ordered between General (0) and Models (10) so identity sits
230
- // near the top. Writes go through the settings controller, which answers
231
- // with the Host's own rejection reason (a name collides, an empty one), and
232
- // the shared identity re-reads afterwards, so a rename lands in the timeline
233
- // and the member refs at the same moment the page shows it.
247
+ // The Human profile page: one settings section, ordered between General (0)
248
+ // and Models (10) so identity sits near the top. Writes go through the Team
249
+ // Remote, which answers with the Host's own rejection reason (a name
250
+ // collides, an empty one), and the shared identity re-reads afterwards, so a
251
+ // rename lands in the timeline and the member refs at the same moment the
252
+ // page shows it.
234
253
  ctx.slots.inject('settings.section', () => ctx.slots.register({
235
254
  name: 'settings.section',
236
255
  id: 'team-human',
@@ -239,11 +258,9 @@ function applyUi(ctx) {
239
258
  locale: NS,
240
259
  inject: () => ({
241
260
  identity: humanIdentity,
261
+ environment,
242
262
  saveName: async (name) => {
243
- const settings = settingsTransport;
244
- if (settings === undefined)
245
- return 'the settings service is unavailable';
246
- const saved = await settings.update(HUMAN_PROFILE_NAMESPACE, { name }, undefined);
263
+ const saved = await ctx.remote.agentTeam.setHumanProfile({ name });
247
264
  if (!saved.ok)
248
265
  return saved.error.message;
249
266
  await humanIdentity.refresh();
@@ -257,10 +274,7 @@ function applyUi(ctx) {
257
274
  });
258
275
  if (!put.ok)
259
276
  return put.error.message;
260
- const settings = settingsTransport;
261
- if (settings === undefined)
262
- return 'the settings service is unavailable';
263
- const saved = await settings.update(HUMAN_PROFILE_NAMESPACE, { avatarRef: put.value.avatarRef }, undefined);
277
+ const saved = await ctx.remote.agentTeam.setHumanProfile({ avatarRef: put.value.avatarRef });
264
278
  if (!saved.ok)
265
279
  return saved.error.message;
266
280
  await humanIdentity.refresh();
@@ -270,14 +284,10 @@ function applyUi(ctx) {
270
284
  const { avatarRef } = humanIdentity.getSnapshot();
271
285
  if (avatarRef === undefined)
272
286
  return undefined;
273
- const settings = settingsTransport;
274
- if (settings === undefined)
275
- return 'the settings service is unavailable';
276
287
  // Bytes first, then the reference: a failed clear leaves a readable
277
- // avatar instead of a reference to bytes nobody can load. Clearing one
278
- // field is a path op — a merge patch cannot express removal.
288
+ // avatar instead of a reference to bytes nobody can load.
279
289
  await ctx.remote.agentTeam.removeHumanAvatar({ avatarRef });
280
- const cleared = await settings.mutate(HUMAN_PROFILE_NAMESPACE, [{ op: 'unset', path: ['avatarRef'] }], undefined);
290
+ const cleared = await ctx.remote.agentTeam.setHumanProfile({ avatarRef: null });
281
291
  if (!cleared.ok)
282
292
  return cleared.error.message;
283
293
  await humanIdentity.refresh();
@@ -64,13 +64,11 @@ export declare const zh: {
64
64
  readonly resumeAgent: "恢复";
65
65
  readonly restartAgent: "重启";
66
66
  readonly restartStillUnavailable: "重启已执行,成员仍不可用:{diagnostic}";
67
- readonly restartRefusedNoRestart: "会话日志被确定拒绝,修复无可用项,重启无法解决:{detail}";
68
67
  readonly restartFailed: "重启执行失败:{message}";
69
68
  readonly archiveAgent: "归档";
70
69
  readonly archiveAgentTitle: "归档 Agent:{name}";
71
70
  readonly archiveAgentNotice: "将把 {name} 从所有列表收起:会话与私有记忆保留在磁盘上、活跃 Claim 会释放,但暂无恢复入口。";
72
71
  readonly archiveAgentConfirm: "归档";
73
- readonly archiveAgentFailed: "归档失败:{message}";
74
72
  readonly archiveChannel: "归档频道";
75
73
  readonly archiveChannelTitle: "归档频道:{name}";
76
74
  readonly archiveChannelNotice: "将把 {name} 及其全部讨论从所有列表收起:数据保留、所有成员在此频道的活跃 Claim 会释放,但暂无恢复入口。";
@@ -133,13 +131,21 @@ export declare const zh: {
133
131
  readonly humanSettingsUnavailable: "资料读不出来:{message}";
134
132
  readonly humanSettingsVersion: "版本 {version}";
135
133
  readonly humanSettingsUpdateAvailable: "有新版本 {version},去查看发布说明";
134
+ readonly environmentOkTitle: "在支持范围内";
135
+ readonly environmentOkDetail: "正在运行的 DSH {version} 在我们声明的支持范围内。";
136
+ readonly environmentOutOfRangeTitle: "不在支持范围内";
137
+ readonly environmentOutOfRangeDetail: "正在运行的 DSH {version} 不在我们声明的支持范围内——这套组合未经我们认证,可能出问题。";
138
+ readonly environmentRange: "支持范围:{lower} 起、{upper} 之前。";
139
+ readonly environmentTested: "我们实测认证的组合:Agent Team {bundle} × DSH {dsh}。";
140
+ readonly environmentUndeterminedTitle: "无法判定运行环境";
141
+ readonly environmentUndeterminedDetail: "读不到正在运行的 DSH 版本,或无法确定我们的支持范围,因此不做判断。";
142
+ readonly environmentReleaseNotes: "查看发布说明";
136
143
  readonly taskStatusTodo: "待处理";
137
144
  readonly taskStatusInProgress: "进行中";
138
145
  readonly taskStatusInReview: "待验收";
139
146
  readonly taskStatusDone: "已完成";
140
147
  readonly taskStatusClosed: "已关闭";
141
148
  readonly taskLabel: "Task #{number}";
142
- readonly taskPending: "Task …";
143
149
  readonly openTask: "打开 Task #{number}";
144
150
  readonly openThread: "打开讨论";
145
151
  readonly openTaskUnread: "打开 Task #{number}({count} 条新动态)";
@@ -206,7 +212,6 @@ export declare const zh: {
206
212
  readonly activityReopened: "{actor} 重新打开了此 Task";
207
213
  readonly mentionConfirmation: "提及未关注成员需要确认,再次发送以继续";
208
214
  readonly memberNotFollowing: "这些成员还未关注此 Thread:{ids}";
209
- readonly sendFailedKind: "无法发送消息({kind})";
210
215
  readonly unreadRequired: "请先读取 {count} 条未读更新,再继续修改。";
211
216
  readonly staleRevision: "Thread 已发生变化,请按最新状态重试。";
212
217
  };
@@ -276,13 +281,11 @@ export declare const en: {
276
281
  readonly resumeAgent: "Resume";
277
282
  readonly restartAgent: "Restart";
278
283
  readonly restartStillUnavailable: "Restart ran, but the Member is still unavailable: {diagnostic}";
279
- readonly restartRefusedNoRestart: "The session log is deterministically refused with nothing repairable; restarting cannot fix it: {detail}";
280
284
  readonly restartFailed: "Restart failed: {message}";
281
285
  readonly archiveAgent: "Archive";
282
286
  readonly archiveAgentTitle: "Archive Agent: {name}";
283
287
  readonly archiveAgentNotice: "This hides {name} from every list: the session log and private memory stay on disk and active Claims release, but there is no restore entry point yet.";
284
288
  readonly archiveAgentConfirm: "Archive";
285
- readonly archiveAgentFailed: "Failed to archive: {message}";
286
289
  readonly archiveChannel: "Archive Channel";
287
290
  readonly archiveChannelTitle: "Archive Channel: {name}";
288
291
  readonly archiveChannelNotice: "This hides {name} and all of its discussions from every list: the data stays, every Member's active Claims in this Channel release, but there is no restore entry point yet.";
@@ -345,13 +348,21 @@ export declare const en: {
345
348
  readonly humanSettingsUnavailable: "The profile could not be read: {message}";
346
349
  readonly humanSettingsVersion: "Version {version}";
347
350
  readonly humanSettingsUpdateAvailable: "New version {version} available — see the release notes";
351
+ readonly environmentOkTitle: "Within the supported range";
352
+ readonly environmentOkDetail: "The running DSH {version} is within the range we declare support for.";
353
+ readonly environmentOutOfRangeTitle: "Outside the supported range";
354
+ readonly environmentOutOfRangeDetail: "The running DSH {version} is outside the range we declare support for — we have not certified this combination and it may misbehave.";
355
+ readonly environmentRange: "Support range: from {lower} up to, but not including, {upper}.";
356
+ readonly environmentTested: "Certified combination: Agent Team {bundle} × DSH {dsh}.";
357
+ readonly environmentUndeterminedTitle: "Environment cannot be determined";
358
+ readonly environmentUndeterminedDetail: "The running DSH version could not be read, or our support range could not be established, so no judgement is made.";
359
+ readonly environmentReleaseNotes: "See the release notes";
348
360
  readonly taskStatusTodo: "To do";
349
361
  readonly taskStatusInProgress: "In progress";
350
362
  readonly taskStatusInReview: "In review";
351
363
  readonly taskStatusDone: "Done";
352
364
  readonly taskStatusClosed: "Closed";
353
365
  readonly taskLabel: "Task #{number}";
354
- readonly taskPending: "Task …";
355
366
  readonly openTask: "Open Task #{number}";
356
367
  readonly openThread: "Open thread";
357
368
  readonly openTaskUnread: "Open Task #{number} ({count} new updates)";
@@ -418,7 +429,6 @@ export declare const en: {
418
429
  readonly activityReopened: "{actor} reopened this Task";
419
430
  readonly mentionConfirmation: "Mentioning an unfollowed member requires confirmation; send again to continue";
420
431
  readonly memberNotFollowing: "These Members do not follow this Thread yet: {ids}";
421
- readonly sendFailedKind: "Unable to send message ({kind})";
422
432
  readonly unreadRequired: "Read {count} unread update(s) before changing this Thread.";
423
433
  readonly staleRevision: "This Thread changed; retry using the current state.";
424
434
  };
@@ -1 +1 @@
1
- {"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuNL,CAAA;AAEV,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqNL,CAAA;AAEV,MAAM,MAAM,OAAO,GAAG,MAAM,OAAO,EAAE,CAAA"}
1
+ {"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+NL,CAAA;AAEV,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0NL,CAAA;AAEV,MAAM,MAAM,OAAO,GAAG,MAAM,OAAO,EAAE,CAAA"}
@@ -64,13 +64,11 @@ export const zh = {
64
64
  resumeAgent: '恢复',
65
65
  restartAgent: '重启',
66
66
  restartStillUnavailable: '重启已执行,成员仍不可用:{diagnostic}',
67
- restartRefusedNoRestart: '会话日志被确定拒绝,修复无可用项,重启无法解决:{detail}',
68
67
  restartFailed: '重启执行失败:{message}',
69
68
  archiveAgent: '归档',
70
69
  archiveAgentTitle: '归档 Agent:{name}',
71
70
  archiveAgentNotice: '将把 {name} 从所有列表收起:会话与私有记忆保留在磁盘上、活跃 Claim 会释放,但暂无恢复入口。',
72
71
  archiveAgentConfirm: '归档',
73
- archiveAgentFailed: '归档失败:{message}',
74
72
  archiveChannel: '归档频道',
75
73
  archiveChannelTitle: '归档频道:{name}',
76
74
  archiveChannelNotice: '将把 {name} 及其全部讨论从所有列表收起:数据保留、所有成员在此频道的活跃 Claim 会释放,但暂无恢复入口。',
@@ -133,13 +131,24 @@ export const zh = {
133
131
  humanSettingsUnavailable: '资料读不出来:{message}',
134
132
  humanSettingsVersion: '版本 {version}',
135
133
  humanSettingsUpdateAvailable: '有新版本 {version},去查看发布说明',
134
+ // The environment check. The support line is stated in words, never as a bare
135
+ // semver range, and the tested-combination line prints only versions the Host
136
+ // could derive — the page adds no version of its own.
137
+ environmentOkTitle: '在支持范围内',
138
+ environmentOkDetail: '正在运行的 DSH {version} 在我们声明的支持范围内。',
139
+ environmentOutOfRangeTitle: '不在支持范围内',
140
+ environmentOutOfRangeDetail: '正在运行的 DSH {version} 不在我们声明的支持范围内——这套组合未经我们认证,可能出问题。',
141
+ environmentRange: '支持范围:{lower} 起、{upper} 之前。',
142
+ environmentTested: '我们实测认证的组合:Agent Team {bundle} × DSH {dsh}。',
143
+ environmentUndeterminedTitle: '无法判定运行环境',
144
+ environmentUndeterminedDetail: '读不到正在运行的 DSH 版本,或无法确定我们的支持范围,因此不做判断。',
145
+ environmentReleaseNotes: '查看发布说明',
136
146
  taskStatusTodo: '待处理',
137
147
  taskStatusInProgress: '进行中',
138
148
  taskStatusInReview: '待验收',
139
149
  taskStatusDone: '已完成',
140
150
  taskStatusClosed: '已关闭',
141
151
  taskLabel: 'Task #{number}',
142
- taskPending: 'Task …',
143
152
  openTask: '打开 Task #{number}',
144
153
  openThread: '打开讨论',
145
154
  openTaskUnread: '打开 Task #{number}({count} 条新动态)',
@@ -210,7 +219,6 @@ export const zh = {
210
219
  activityReopened: '{actor} 重新打开了此 Task',
211
220
  mentionConfirmation: '提及未关注成员需要确认,再次发送以继续',
212
221
  memberNotFollowing: '这些成员还未关注此 Thread:{ids}',
213
- sendFailedKind: '无法发送消息({kind})',
214
222
  unreadRequired: '请先读取 {count} 条未读更新,再继续修改。',
215
223
  staleRevision: 'Thread 已发生变化,请按最新状态重试。',
216
224
  };
@@ -280,13 +288,11 @@ export const en = {
280
288
  resumeAgent: 'Resume',
281
289
  restartAgent: 'Restart',
282
290
  restartStillUnavailable: 'Restart ran, but the Member is still unavailable: {diagnostic}',
283
- restartRefusedNoRestart: 'The session log is deterministically refused with nothing repairable; restarting cannot fix it: {detail}',
284
291
  restartFailed: 'Restart failed: {message}',
285
292
  archiveAgent: 'Archive',
286
293
  archiveAgentTitle: 'Archive Agent: {name}',
287
294
  archiveAgentNotice: 'This hides {name} from every list: the session log and private memory stay on disk and active Claims release, but there is no restore entry point yet.',
288
295
  archiveAgentConfirm: 'Archive',
289
- archiveAgentFailed: 'Failed to archive: {message}',
290
296
  archiveChannel: 'Archive Channel',
291
297
  archiveChannelTitle: 'Archive Channel: {name}',
292
298
  archiveChannelNotice: 'This hides {name} and all of its discussions from every list: the data stays, every Member\'s active Claims in this Channel release, but there is no restore entry point yet.',
@@ -349,13 +355,21 @@ export const en = {
349
355
  humanSettingsUnavailable: 'The profile could not be read: {message}',
350
356
  humanSettingsVersion: 'Version {version}',
351
357
  humanSettingsUpdateAvailable: 'New version {version} available — see the release notes',
358
+ environmentOkTitle: 'Within the supported range',
359
+ environmentOkDetail: 'The running DSH {version} is within the range we declare support for.',
360
+ environmentOutOfRangeTitle: 'Outside the supported range',
361
+ environmentOutOfRangeDetail: 'The running DSH {version} is outside the range we declare support for — we have not certified this combination and it may misbehave.',
362
+ environmentRange: 'Support range: from {lower} up to, but not including, {upper}.',
363
+ environmentTested: 'Certified combination: Agent Team {bundle} × DSH {dsh}.',
364
+ environmentUndeterminedTitle: 'Environment cannot be determined',
365
+ environmentUndeterminedDetail: 'The running DSH version could not be read, or our support range could not be established, so no judgement is made.',
366
+ environmentReleaseNotes: 'See the release notes',
352
367
  taskStatusTodo: 'To do',
353
368
  taskStatusInProgress: 'In progress',
354
369
  taskStatusInReview: 'In review',
355
370
  taskStatusDone: 'Done',
356
371
  taskStatusClosed: 'Closed',
357
372
  taskLabel: 'Task #{number}',
358
- taskPending: 'Task …',
359
373
  openTask: 'Open Task #{number}',
360
374
  openThread: 'Open thread',
361
375
  openTaskUnread: 'Open Task #{number} ({count} new updates)',
@@ -424,7 +438,6 @@ export const en = {
424
438
  activityReopened: '{actor} reopened this Task',
425
439
  mentionConfirmation: 'Mentioning an unfollowed member requires confirmation; send again to continue',
426
440
  memberNotFollowing: 'These Members do not follow this Thread yet: {ids}',
427
- sendFailedKind: 'Unable to send message ({kind})',
428
441
  unreadRequired: 'Read {count} unread update(s) before changing this Thread.',
429
442
  staleRevision: 'This Thread changed; retry using the current state.',
430
443
  };
@@ -4,7 +4,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
4
4
  // without closing the list so several entries can be picked in one pass; the
5
5
  // capped card scrolls internally through long catalogs.
6
6
  import { useState } from 'react';
7
- import { IconChevronDownOutline14, Menu } from '@deepseek-ai/dsh-client-ui-primitives';
7
+ import { IconChevronDownOutlineRegular, Menu } from '@deepseek-ai/dsh-client-ui-primitives';
8
8
  import createCss from './create.module.css';
9
9
  import css from './sidebar.module.css';
10
10
  /**
@@ -26,5 +26,5 @@ export function MultiMenuField({ label, options, selected, onToggle, disabled =
26
26
  ...(option.disabled === true ? { disabled: true } : {}),
27
27
  ...(option.icon === undefined ? {} : { icon: option.icon }),
28
28
  }));
29
- return (_jsxs("div", { className: createCss.field, children: [_jsx("span", { children: label }), options.length === 0 && emptyText !== undefined ? _jsx("small", { className: css.editHint, children: emptyText }) : (_jsx(Menu, { open: open, portal: true, className: createCss.menuCap, items: items, selectedIds: selected, onSelect: id => { onToggle(id); }, onClose: () => { setOpen(false); }, anchor: _jsxs("button", { type: "button", className: createCss.selectTrigger, "aria-label": label, "aria-haspopup": "menu", "aria-expanded": open, disabled: disabled, onClick: () => { setOpen(value => !value); }, children: [_jsx("span", { className: createCss.selectValue, children: selected.length === 0 ? triggerEmptyLabel : formatCount(selected.length) }), _jsx("span", { className: `${createCss.chevron} ${open ? createCss.chevronOpen : ''}`, "aria-hidden": true, children: _jsx(IconChevronDownOutline14, {}) })] }) }))] }));
29
+ return (_jsxs("div", { className: createCss.field, children: [_jsx("span", { children: label }), options.length === 0 && emptyText !== undefined ? _jsx("small", { className: css.editHint, children: emptyText }) : (_jsx(Menu, { open: open, portal: true, className: createCss.menuCap, items: items, selectedIds: selected, onSelect: id => { onToggle(id); }, onClose: () => { setOpen(false); }, anchor: _jsxs("button", { type: "button", className: createCss.selectTrigger, "aria-label": label, "aria-haspopup": "menu", "aria-expanded": open, disabled: disabled, onClick: () => { setOpen(value => !value); }, children: [_jsx("span", { className: createCss.selectValue, children: selected.length === 0 ? triggerEmptyLabel : formatCount(selected.length) }), _jsx("span", { className: `${createCss.chevron} ${open ? createCss.chevronOpen : ''}`, "aria-hidden": true, children: _jsx(IconChevronDownOutlineRegular, {}) })] }) }))] }));
30
30
  }