@wowyuarm/dsh-agent-team 0.1.15 → 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 +7 -3
- package/README.zh.md +7 -3
- package/package.json +49 -47
- package/packages/agent-team/lib/context-source.js +11 -6
- package/packages/agent-team/lib/environment-check.js +102 -0
- package/packages/agent-team/lib/human-profile.js +23 -37
- package/packages/agent-team/lib/index.js +28 -2
- 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 +2 -4
- package/packages/agent-team/lib/member-time-context.js +2 -4
- package/packages/agent-team/lib/pressure-policy.js +13 -8
- package/packages/agent-team/lib/typert.host.js +121 -44
- package/packages/agent-team/lib/typert.remote-client.d.ts +3 -1
- package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
- package/packages/agent-team/lib/typert.remote-client.js +86 -38
- package/packages/agent-team/lib/types/context-source.d.ts +7 -4
- 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 +21 -27
- package/packages/agent-team/lib/types/human-profile.d.ts.map +1 -1
- package/packages/agent-team/lib/types/index.d.ts +23 -2
- 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.map +1 -1
- 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/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 +66 -0
- package/packages/agent-team/lib/types/types/requests-results.d.ts.map +1 -1
- package/packages/client-agent-team/lib/client.js +324 -75
- 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 +0 -5
- 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/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/index.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/index.js +9 -0
- 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/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
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import { type TeamEnvironmentSource } from './environment-check.ts';
|
|
3
|
+
/**
|
|
4
|
+
* The local environment check: which DSH line this installation runs against,
|
|
5
|
+
* and whether that line is inside the range the bundle declares.
|
|
6
|
+
*
|
|
7
|
+
* Three verdicts, never a fourth, and never a guess: a fact the Host could not
|
|
8
|
+
* establish is `undetermined`, not a mismatch. Every verdict is stated as text
|
|
9
|
+
* plus an icon, so the state survives a reader who cannot tell the colors
|
|
10
|
+
* apart. The support line is written in words rather than as a bare semver
|
|
11
|
+
* range, and the tested combination is printed only when the Host could derive
|
|
12
|
+
* both of its versions — the page never supplies a version of its own.
|
|
13
|
+
*/
|
|
14
|
+
export type EnvironmentCheckProps = PropsLocale<'team'> & {
|
|
15
|
+
readonly environment: TeamEnvironmentSource;
|
|
16
|
+
};
|
|
17
|
+
export declare function EnvironmentCheck({ t, environment }: EnvironmentCheckProps): import("react").JSX.Element | null;
|
|
18
|
+
//# sourceMappingURL=EnvironmentCheck.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnvironmentCheck.d.ts","sourceRoot":"","sources":["../../../src/client/EnvironmentCheck.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,EAAuB,KAAK,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAGxF;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,qBAAqB,GAC7B,WAAW,CAAC,MAAM,CAAC,GACnB;IAAE,QAAQ,CAAC,WAAW,EAAE,qBAAqB,CAAA;CAAE,CAAA;AAyBnD,wBAAgB,gBAAgB,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,EAAE,qBAAqB,sCAkDzE"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEnvironmentCheck } from "./environment-check.js";
|
|
3
|
+
import css from './environment-check.module.css';
|
|
4
|
+
/** The three glyphs, drawn at the 16px seat the settings page uses for state marks. */
|
|
5
|
+
const ICONS = {
|
|
6
|
+
ok: _jsx("path", { d: "M3 8.5 6.5 12 13 4.5" }),
|
|
7
|
+
warn: _jsxs(_Fragment, { children: [_jsx("path", { d: "M8 2.5 14.6 13.6H1.4z" }), _jsx("path", { d: "M8 6.6v3.2" }), _jsx("path", { d: "M8 11.9h.01" })] }),
|
|
8
|
+
unknown: _jsxs(_Fragment, { children: [_jsx("circle", { cx: "8", cy: "8", r: "6" }), _jsx("path", { d: "M5.6 8h4.8" })] }),
|
|
9
|
+
};
|
|
10
|
+
function EnvironmentIcon({ glyph }) {
|
|
11
|
+
return _jsx("svg", { className: css.icon, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: ICONS[glyph] });
|
|
12
|
+
}
|
|
13
|
+
/** The release notes this bundle's own repository keeps, one click from the version footnote. */
|
|
14
|
+
const RELEASE_NOTES_URL = 'https://github.com/wowyuarm/dsh-agent-team/releases';
|
|
15
|
+
export function EnvironmentCheck({ t, environment }) {
|
|
16
|
+
const { report } = useEnvironmentCheck(environment);
|
|
17
|
+
// Nothing to state before the first read settles, and nothing to state if it
|
|
18
|
+
// never lands: the block is informational and its absence is not an error.
|
|
19
|
+
if (report === undefined)
|
|
20
|
+
return null;
|
|
21
|
+
const range = report.supportRange;
|
|
22
|
+
const running = report.dshVersion;
|
|
23
|
+
// The tested combination appears only when both of its versions were derived:
|
|
24
|
+
// the installed manifest's own version, and the range's lower bound, which is
|
|
25
|
+
// the certified line. A missing one withholds the line rather than inviting a
|
|
26
|
+
// hand-written version onto the page.
|
|
27
|
+
const certified = report.certifiedDshVersion;
|
|
28
|
+
const bundleVersion = report.bundleVersion;
|
|
29
|
+
// Both sides of the line have to be derived: `'unknown'` is the data layer's
|
|
30
|
+
// word for a version that could not be read, and it never reaches the page.
|
|
31
|
+
const tested = certified !== undefined && bundleVersion !== undefined && bundleVersion !== 'unknown';
|
|
32
|
+
const title = report.verdict === 'ok'
|
|
33
|
+
? t('environmentOkTitle')
|
|
34
|
+
: report.verdict === 'out-of-range'
|
|
35
|
+
? t('environmentOutOfRangeTitle')
|
|
36
|
+
: t('environmentUndeterminedTitle');
|
|
37
|
+
const lines = [];
|
|
38
|
+
if (report.verdict === 'ok') {
|
|
39
|
+
if (running !== undefined)
|
|
40
|
+
lines.push(t('environmentOkDetail', { version: running }));
|
|
41
|
+
}
|
|
42
|
+
else if (report.verdict === 'out-of-range') {
|
|
43
|
+
if (running !== undefined)
|
|
44
|
+
lines.push(t('environmentOutOfRangeDetail', { version: running }));
|
|
45
|
+
if (range !== undefined)
|
|
46
|
+
lines.push(t('environmentRange', { lower: range.lower, upper: range.upper }));
|
|
47
|
+
if (tested && certified !== undefined && bundleVersion !== undefined) {
|
|
48
|
+
lines.push(t('environmentTested', { bundle: bundleVersion, dsh: certified }));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
lines.push(t('environmentUndeterminedDetail'));
|
|
53
|
+
}
|
|
54
|
+
// `data-environment` carries the verdict the way the rest of the Client marks
|
|
55
|
+
// a state for assertions; the block also renders nothing at all before a read
|
|
56
|
+
// lands, so a journey can wait on this attribute rather than on prose.
|
|
57
|
+
return _jsxs("div", { className: css.block, "data-environment": report.verdict, children: [_jsx(EnvironmentIcon, { glyph: report.verdict === 'ok' ? 'ok' : report.verdict === 'out-of-range' ? 'warn' : 'unknown' }), _jsxs("div", { className: css.body, children: [_jsx("p", { className: css.title, children: title }), lines.map((line, index) => _jsx("p", { className: css.detail, children: line }, index)), report.verdict !== 'ok' && _jsx("p", { className: css.action, children: _jsx("a", { className: css.link, href: RELEASE_NOTES_URL, target: "_blank", rel: "noreferrer", children: t('environmentReleaseNotes') }) })] })] });
|
|
58
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
2
|
import { type TeamHumanIdentityFace } from './human-identity.ts';
|
|
3
|
+
import type { TeamEnvironmentSource } from './environment-check.ts';
|
|
3
4
|
export interface HumanSettingsSectionInjected {
|
|
4
5
|
/** The shared Human identity projection: profile facts plus post-write refresh. */
|
|
5
6
|
identity: TeamHumanIdentityFace;
|
|
@@ -9,6 +10,8 @@ export interface HumanSettingsSectionInjected {
|
|
|
9
10
|
uploadAvatar: (file: File) => Promise<string | undefined>;
|
|
10
11
|
/** Clear the avatar; the identity falls back to the initial. */
|
|
11
12
|
removeAvatar: () => Promise<string | undefined>;
|
|
13
|
+
/** The local environment check, a read-only projection of the installation. */
|
|
14
|
+
environment: TeamEnvironmentSource;
|
|
12
15
|
}
|
|
13
16
|
export type HumanSettingsSectionProps = PropsRuntime<'settings.section'> & PropsLocale<'team'> & HumanSettingsSectionInjected;
|
|
14
17
|
export declare function HumanSettingsSection(props: HumanSettingsSectionProps): import("react").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HumanSettingsSection.d.ts","sourceRoot":"","sources":["../../../src/client/HumanSettingsSection.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAEjF,OAAO,EAAoB,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"HumanSettingsSection.d.ts","sourceRoot":"","sources":["../../../src/client/HumanSettingsSection.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAEjF,OAAO,EAAoB,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAElF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAmBnE,MAAM,WAAW,4BAA4B;IAC3C,mFAAmF;IACnF,QAAQ,EAAE,qBAAqB,CAAA;IAC/B,sFAAsF;IACtF,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACvD,gGAAgG;IAChG,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACzD,gEAAgE;IAChE,YAAY,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAC/C,+EAA+E;IAC/E,WAAW,EAAE,qBAAqB,CAAA;CACnC;AAED,MAAM,MAAM,yBAAyB,GACjC,YAAY,CAAC,kBAAkB,CAAC,GAChC,WAAW,CAAC,MAAM,CAAC,GACnB,4BAA4B,CAAA;AAsBhC,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,+BAkKpE"}
|
|
@@ -2,16 +2,19 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
2
2
|
import { useRef, useState } from 'react';
|
|
3
3
|
import { Button, Input } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
4
4
|
import { useHumanIdentity } from "./human-identity.js";
|
|
5
|
+
import { EnvironmentCheck } from "./EnvironmentCheck.js";
|
|
5
6
|
import { useAvatarImage } from "./avatar-image.js";
|
|
6
7
|
import css from './human-settings.module.css';
|
|
7
8
|
/**
|
|
8
|
-
* The Human's own settings page: display name, avatar,
|
|
9
|
-
* footnote.
|
|
9
|
+
* The Human's own settings page: display name, avatar, the local environment
|
|
10
|
+
* check, and the version footnote.
|
|
10
11
|
*
|
|
11
12
|
* The page owns no durable fact and no copy of one. Name, avatar, and version
|
|
12
13
|
* all arrive from the shared identity projection, so a save here moves the
|
|
13
14
|
* message rows and member refs at the same moment; a failed write keeps the
|
|
14
|
-
* typed name in the field and reports the Host's own reason.
|
|
15
|
+
* typed name in the field and reports the Host's own reason. The environment
|
|
16
|
+
* check is a separate projection, read only, and belongs to the installation
|
|
17
|
+
* rather than to the Human.
|
|
15
18
|
*/
|
|
16
19
|
/** Host-side avatar ceiling (`ATTACHMENT_MAX_BYTES`): the settings page refuses larger files before the round trip. */
|
|
17
20
|
const AVATAR_MAX_BYTES = 10 * 1024 * 1024;
|
|
@@ -109,7 +112,7 @@ export function HumanSettingsSection(props) {
|
|
|
109
112
|
: _jsx("img", { className: `${css.identity} ${css.identityImage}`, "data-avatar": "image", src: avatar.src, alt: "", onError: avatar.failed }), _jsx("input", { ref: filePicker, type: "file", accept: "image/*", tabIndex: -1, "aria-hidden": "true", hidden: true, onChange: (event) => {
|
|
110
113
|
void pickAvatar(event.target.files?.[0]);
|
|
111
114
|
event.target.value = '';
|
|
112
|
-
} }), _jsx(Button, { variant: "outline", disabled: uploading, onClick: () => { filePicker.current?.click(); }, children: uploading ? t('humanSettingsUploading') : hasAvatar ? t('humanSettingsReplace') : t('humanSettingsUpload') }), hasAvatar && _jsx(Button, { disabled: uploading, onClick: () => { void removeAvatar(); }, children: t('humanSettingsRemoveAvatar') })] })] })] }), _jsxs("div", { className: css.footnote, children: [_jsx("span", { children: t('humanSettingsVersion', { version: profile.version ?? '' }) }), _jsx("span", { "aria-hidden": "true", children: "\u00B7" }), _jsx("a", { className: css.link, href: profile.repoUrl ?? '', target: "_blank", rel: "noreferrer", children: "GitHub" }), profile.updateAvailable && profile.latestVersion !== undefined
|
|
115
|
+
} }), _jsx(Button, { variant: "outline", disabled: uploading, onClick: () => { filePicker.current?.click(); }, children: uploading ? t('humanSettingsUploading') : hasAvatar ? t('humanSettingsReplace') : t('humanSettingsUpload') }), hasAvatar && _jsx(Button, { disabled: uploading, onClick: () => { void removeAvatar(); }, children: t('humanSettingsRemoveAvatar') })] })] })] }), _jsx(EnvironmentCheck, { t: t, environment: props.environment }), _jsxs("div", { className: css.footnote, children: [_jsx("span", { children: t('humanSettingsVersion', { version: profile.version ?? '' }) }), _jsx("span", { "aria-hidden": "true", children: "\u00B7" }), _jsx("a", { className: css.link, href: profile.repoUrl ?? '', target: "_blank", rel: "noreferrer", children: "GitHub" }), profile.updateAvailable && profile.latestVersion !== undefined
|
|
113
116
|
? _jsx("a", { className: css.link, href: `${profile.repoUrl ?? ''}/releases`, target: "_blank", rel: "noreferrer", children: t('humanSettingsUpdateAvailable', { version: profile.latestVersion }) })
|
|
114
117
|
: null] }), emptyName && _jsx("p", { className: css.notice, children: t('humanSettingsNameEmpty') }), notice === null ? null : _jsx("p", { className: css.notice, role: "alert", children: notice })] }));
|
|
115
118
|
}
|
|
@@ -230,11 +230,6 @@ function AgentRow({ workspaceId, leaveWorkspace, status, current, updateMember,
|
|
|
230
230
|
return;
|
|
231
231
|
}
|
|
232
232
|
if (result.value.status.availability === 'unavailable') {
|
|
233
|
-
const diagnostic = result.value.status.diagnostic;
|
|
234
|
-
if (diagnostic?.class === 'session-refused' && diagnostic.remediable === false) {
|
|
235
|
-
setRowAlert(t('restartRefusedNoRestart', { detail: diagnosticText(result.value.status) }));
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
233
|
setRowAlert(t('restartStillUnavailable', { diagnostic: diagnosticText(result.value.status) || t('statusUnavailable') }));
|
|
239
234
|
return;
|
|
240
235
|
}
|
|
@@ -7,7 +7,7 @@ export declare function diagnosticText(status: Pick<AgentTeamClientMemberStatus,
|
|
|
7
7
|
/**
|
|
8
8
|
* Whether the restart action can help an unavailable Member: it heals
|
|
9
9
|
* transient and repairable failures, but not a transient rollover window
|
|
10
|
-
* (which resolves on its own)
|
|
10
|
+
* (which resolves on its own).
|
|
11
11
|
*/
|
|
12
12
|
export declare function restartOffered(status: AgentTeamClientMemberStatus): boolean;
|
|
13
13
|
/** Shared presence → indicator mapping for dots and avatar badges. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TeamPresenceDot.d.ts","sourceRoot":"","sources":["../../../src/client/TeamPresenceDot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAA;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAG3D,wBAAgB,aAAa,CAAC,MAAM,EAAE,2BAA2B,EAAE,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,MAAM,CAKnG;AAED,oHAAoH;AACpH,wBAAgB,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,2BAA2B,EAAE,YAAY,CAAC,GAAG,MAAM,CAI9F;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,2BAA2B,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"TeamPresenceDot.d.ts","sourceRoot":"","sources":["../../../src/client/TeamPresenceDot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAA;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAG3D,wBAAgB,aAAa,CAAC,MAAM,EAAE,2BAA2B,EAAE,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,MAAM,CAKnG;AAED,oHAAoH;AACpH,wBAAgB,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,2BAA2B,EAAE,YAAY,CAAC,GAAG,MAAM,CAI9F;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,2BAA2B,GAAG,OAAO,CAE3E;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,2BAA2B,CAAC,UAAU,CAAC,GAAG,iBAAiB,CAErG;AAED,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE;IAC7C,QAAQ,CAAC,MAAM,EAAE,2BAA2B,CAAA;IAC5C,QAAQ,CAAC,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAA;CAClC,+BASA"}
|
|
@@ -18,15 +18,10 @@ export function diagnosticText(status) {
|
|
|
18
18
|
/**
|
|
19
19
|
* Whether the restart action can help an unavailable Member: it heals
|
|
20
20
|
* transient and repairable failures, but not a transient rollover window
|
|
21
|
-
* (which resolves on its own)
|
|
21
|
+
* (which resolves on its own).
|
|
22
22
|
*/
|
|
23
23
|
export function restartOffered(status) {
|
|
24
|
-
|
|
25
|
-
if (diagnostic === undefined)
|
|
26
|
-
return true;
|
|
27
|
-
if (diagnostic.class === 'rollover')
|
|
28
|
-
return false;
|
|
29
|
-
return !(diagnostic.class === 'session-refused' && diagnostic.remediable === false);
|
|
24
|
+
return status.diagnostic?.class !== 'rollover';
|
|
30
25
|
}
|
|
31
26
|
/** Shared presence → indicator mapping for dots and avatar badges. */
|
|
32
27
|
export function presenceDotState(presence) {
|
|
@@ -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
|
+
}
|
|
@@ -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
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";
|
|
@@ -160,10 +161,17 @@ function applyUi(ctx) {
|
|
|
160
161
|
return `data:${result.value.mediaType};base64,${result.value.bytesBase64}`;
|
|
161
162
|
},
|
|
162
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
|
+
});
|
|
163
170
|
ctx.effect(() => () => {
|
|
164
171
|
navigation.dispose();
|
|
165
172
|
drafts.dispose();
|
|
166
173
|
humanIdentity.dispose();
|
|
174
|
+
environment.dispose();
|
|
167
175
|
void disposeNavigation();
|
|
168
176
|
void disposeDrafts();
|
|
169
177
|
}, 'agent-team: navigation service');
|
|
@@ -250,6 +258,7 @@ function applyUi(ctx) {
|
|
|
250
258
|
locale: NS,
|
|
251
259
|
inject: () => ({
|
|
252
260
|
identity: humanIdentity,
|
|
261
|
+
environment,
|
|
253
262
|
saveName: async (name) => {
|
|
254
263
|
const saved = await ctx.remote.agentTeam.setHumanProfile({ name });
|
|
255
264
|
if (!saved.ok)
|
|
@@ -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
|
};
|