@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.
- package/README.md +8 -4
- package/README.zh.md +8 -4
- package/cordis.patch.yml +187 -2
- package/package.json +52 -51
- package/packages/agent-team/README.md +1 -1
- package/packages/agent-team/README.zh.md +1 -1
- package/packages/agent-team/lib/context-continuity-host.js +2 -3
- package/packages/agent-team/lib/context-projection.js +3 -3
- package/packages/agent-team/lib/context-source.js +39 -13
- package/packages/agent-team/lib/environment-check.js +102 -0
- package/packages/agent-team/lib/human-profile.js +110 -13
- package/packages/agent-team/lib/index.js +192 -100
- package/packages/agent-team/lib/installed-manifest.js +32 -0
- package/packages/agent-team/lib/ledger.js +35 -0
- package/packages/agent-team/lib/member-context.js +3 -3
- package/packages/agent-team/lib/member-time-context.js +3 -2
- package/packages/agent-team/lib/pressure-policy.js +18 -11
- package/packages/agent-team/lib/stored-session-reader.js +1 -2
- package/packages/agent-team/lib/typert.host.js +479 -260
- package/packages/agent-team/lib/typert.remote-client.d.ts +8 -3
- package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
- package/packages/agent-team/lib/typert.remote-client.js +375 -228
- package/packages/agent-team/lib/types/context-continuity-host.d.ts.map +1 -1
- package/packages/agent-team/lib/types/context-source.d.ts +49 -13
- package/packages/agent-team/lib/types/context-source.d.ts.map +1 -1
- package/packages/agent-team/lib/types/environment-check.d.ts +66 -0
- package/packages/agent-team/lib/types/environment-check.d.ts.map +1 -0
- package/packages/agent-team/lib/types/human-profile.d.ts +87 -21
- package/packages/agent-team/lib/types/human-profile.d.ts.map +1 -1
- package/packages/agent-team/lib/types/index.d.ts +85 -26
- package/packages/agent-team/lib/types/index.d.ts.map +1 -1
- package/packages/agent-team/lib/types/installed-manifest.d.ts +16 -0
- package/packages/agent-team/lib/types/installed-manifest.d.ts.map +1 -0
- package/packages/agent-team/lib/types/ledger.d.ts +12 -0
- package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
- package/packages/agent-team/lib/types/member-context.d.ts +14 -0
- package/packages/agent-team/lib/types/member-context.d.ts.map +1 -1
- package/packages/agent-team/lib/types/member-time-context.d.ts +15 -0
- package/packages/agent-team/lib/types/member-time-context.d.ts.map +1 -1
- package/packages/agent-team/lib/types/pressure-policy.d.ts +5 -1
- package/packages/agent-team/lib/types/pressure-policy.d.ts.map +1 -1
- package/packages/agent-team/lib/types/stored-session-reader.d.ts +1 -2
- package/packages/agent-team/lib/types/stored-session-reader.d.ts.map +1 -1
- package/packages/agent-team/lib/types/types/entities.d.ts +1 -8
- package/packages/agent-team/lib/types/types/entities.d.ts.map +1 -1
- package/packages/agent-team/lib/types/types/requests-results.d.ts +84 -0
- package/packages/agent-team/lib/types/types/requests-results.d.ts.map +1 -1
- package/packages/client-agent-team/README.md +1 -1
- package/packages/client-agent-team/README.zh.md +1 -1
- package/packages/client-agent-team/lib/client.js +615 -275
- package/packages/client-agent-team/lib/client.js.map +1 -1
- package/packages/client-agent-team/lib/types/client/EnvironmentCheck.d.ts +18 -0
- package/packages/client-agent-team/lib/types/client/EnvironmentCheck.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/EnvironmentCheck.js +58 -0
- package/packages/client-agent-team/lib/types/client/HumanSettingsSection.d.ts +3 -0
- package/packages/client-agent-team/lib/types/client/HumanSettingsSection.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/HumanSettingsSection.js +7 -4
- package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +6 -11
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +3 -3
- package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.js +4 -4
- package/packages/client-agent-team/lib/types/client/TeamComposer.js +3 -3
- package/packages/client-agent-team/lib/types/client/TeamFooterAction.js +2 -2
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.js +3 -3
- package/packages/client-agent-team/lib/types/client/TeamMembersAction.js +2 -2
- package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamMessage.js +1 -1
- package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts +1 -1
- package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamPresenceDot.js +2 -7
- package/packages/client-agent-team/lib/types/client/TeamRowMenu.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamRowMenu.js +2 -2
- package/packages/client-agent-team/lib/types/client/TeamSidebarSection.js +2 -2
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +3 -3
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +3 -3
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceSelector.js +2 -2
- package/packages/client-agent-team/lib/types/client/environment-check.d.ts +65 -0
- package/packages/client-agent-team/lib/types/client/environment-check.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/environment-check.js +78 -0
- package/packages/client-agent-team/lib/types/client/human-identity.d.ts +4 -8
- package/packages/client-agent-team/lib/types/client/human-identity.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/human-identity.js +0 -21
- package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/index.js +59 -49
- package/packages/client-agent-team/lib/types/client/locales.d.ts +18 -8
- package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/locales.js +21 -8
- package/packages/client-agent-team/lib/types/client/multi-menu-field.js +2 -2
- package/packages/client-agent-team/lib/types/client/slots.d.ts +1 -1
- package/packages/tool-agent-team/README.md +1 -1
- package/packages/tool-agent-team/README.zh.md +1 -1
- package/packages/tool-agent-team/lib/context-tools.js +106 -94
- package/packages/tool-agent-team/lib/index.js +17 -2
- package/packages/tool-agent-team/lib/types/context-tools.d.ts +16 -7
- package/packages/tool-agent-team/lib/types/context-tools.d.ts.map +1 -1
- package/packages/tool-agent-team/lib/types/index.d.ts.map +1 -1
- package/packages/agent-team/lib/preset-roster.js +0 -15
- package/packages/agent-team/lib/session-remediation.js +0 -493
- package/packages/agent-team/lib/types/preset-roster.d.ts +0 -5
- package/packages/agent-team/lib/types/preset-roster.d.ts.map +0 -1
- package/packages/agent-team/lib/types/session-remediation.d.ts +0 -172
- package/packages/agent-team/lib/types/session-remediation.d.ts.map +0 -1
- 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
|
|
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
|
|
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;
|
|
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 {
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
|
159
|
-
//
|
|
160
|
-
//
|
|
161
|
-
//
|
|
162
|
-
//
|
|
163
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
229
|
-
//
|
|
230
|
-
//
|
|
231
|
-
//
|
|
232
|
-
// the
|
|
233
|
-
//
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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 {
|
|
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(
|
|
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
|
}
|