@wowyuarm/dsh-agent-team 0.1.6 → 0.1.8
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 +11 -5
- package/README.zh.md +11 -5
- package/package.json +44 -42
- package/packages/agent-team/README.md +2 -0
- package/packages/agent-team/README.zh.md +2 -0
- package/packages/agent-team/core-skills/member-skill-manager/SKILL.md +2 -0
- package/packages/agent-team/lib/index.js +140 -204
- package/packages/agent-team/lib/ledger.js +436 -25
- package/packages/agent-team/lib/member-context.js +6 -2
- package/packages/agent-team/lib/member-runtime.js +229 -0
- package/packages/agent-team/lib/preset-roster.js +1 -0
- package/packages/agent-team/lib/progress-nudge.js +320 -0
- package/packages/agent-team/lib/spec.js +30 -1
- package/packages/agent-team/lib/typert.host.js +250 -70
- package/packages/agent-team/lib/typert.remote-client.d.ts +5 -1
- package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
- package/packages/agent-team/lib/typert.remote-client.js +168 -38
- package/packages/agent-team/lib/types/entities.js +1 -0
- package/packages/agent-team/lib/types/index.d.ts +28 -44
- package/packages/agent-team/lib/types/index.d.ts.map +1 -1
- package/packages/agent-team/lib/types/ledger.d.ts +60 -2
- package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
- package/packages/agent-team/lib/types/member-context.d.ts.map +1 -1
- package/packages/agent-team/lib/types/member-runtime.d.ts +108 -0
- package/packages/agent-team/lib/types/member-runtime.d.ts.map +1 -0
- package/packages/agent-team/lib/types/operations.js +1 -0
- package/packages/agent-team/lib/types/preset-roster.d.ts.map +1 -1
- package/packages/agent-team/lib/types/progress-nudge.d.ts +136 -0
- package/packages/agent-team/lib/types/progress-nudge.d.ts.map +1 -0
- package/packages/agent-team/lib/types/requests-results.js +1 -0
- package/packages/agent-team/lib/types/spec.d.ts.map +1 -1
- package/packages/agent-team/lib/types/types/entities.d.ts +357 -0
- package/packages/agent-team/lib/types/types/entities.d.ts.map +1 -0
- package/packages/agent-team/lib/types/types/operations.d.ts +303 -0
- package/packages/agent-team/lib/types/types/operations.d.ts.map +1 -0
- package/packages/agent-team/lib/types/types/requests-results.d.ts +529 -0
- package/packages/agent-team/lib/types/types/requests-results.d.ts.map +1 -0
- package/packages/agent-team/lib/types/types.d.ts +10 -1070
- package/packages/agent-team/lib/types/types.d.ts.map +1 -1
- package/packages/agent-team/preset/team-member/agent.cordis.yml +6 -4
- package/packages/client-agent-team/README.md +3 -1
- package/packages/client-agent-team/README.zh.md +3 -1
- package/packages/client-agent-team/lib/client.js +773 -733
- package/packages/client-agent-team/lib/client.js.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts +3 -2
- package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +30 -7
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts +1 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +5 -9
- package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.d.ts +2 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.js +31 -5
- package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts +3 -1
- package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamComposer.js +39 -28
- package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts +1 -1
- package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamConversation.js +2 -2
- package/packages/client-agent-team/lib/types/client/TeamMemberAvatar.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamMemberAvatar.js +3 -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 +15 -3
- package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts +2 -2
- package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamPresenceDot.js +4 -6
- package/packages/client-agent-team/lib/types/client/TeamStateDot.d.ts +14 -0
- package/packages/client-agent-team/lib/types/client/TeamStateDot.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/TeamStateDot.js +15 -0
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts +2 -1
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +41 -16
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts +1 -1
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +2 -2
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceRow.d.ts +1 -1
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceRow.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/index.d.ts +1 -1
- 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 -77
- package/packages/client-agent-team/lib/types/client/locales.d.ts +26 -0
- package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/locales.js +26 -0
- package/packages/client-agent-team/lib/types/client/navigation.d.ts +2 -1
- package/packages/client-agent-team/lib/types/client/navigation.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/sidebar-drag.d.ts +1 -2
- package/packages/client-agent-team/lib/types/client/sidebar-drag.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/sidebar-order.d.ts +1 -1
- package/packages/client-agent-team/lib/types/client/sidebar-order.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/sidebar-sections.d.ts +1 -1
- package/packages/client-agent-team/lib/types/client/sidebar-sections.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/slots.d.ts +5 -1
- package/packages/client-agent-team/lib/types/client/slots.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/task-refs.d.ts +7 -1
- package/packages/client-agent-team/lib/types/client/task-refs.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/task-refs.js +25 -3
- package/packages/client-agent-team/lib/types/client/team-formatters.d.ts +11 -10
- package/packages/client-agent-team/lib/types/client/team-formatters.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/team-formatters.js +14 -11
- package/packages/client-agent-team/lib/types/client/team-membership.d.ts +1 -1
- package/packages/client-agent-team/lib/types/client/team-membership.d.ts.map +1 -1
- package/packages/tool-agent-team/lib/index.js +9 -9
- package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.d.ts +0 -17
- package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.d.ts.map +0 -1
- package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.js +0 -135
- package/packages/client-agent-team/lib/types/client/member-session-input.d.ts +0 -22
- package/packages/client-agent-team/lib/types/client/member-session-input.d.ts.map +0 -1
- package/packages/client-agent-team/lib/types/client/member-session-input.js +0 -98
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Fragment, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
2
|
+
import { Fragment, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { MarkdownText, MessageText, Modal } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
4
4
|
import { cachedAttachmentDataUrl, formatByteSize, loadAttachmentDataUrl } from "./attachment-preview.js";
|
|
5
5
|
import { cachedResolvedTaskRef, resolveUnknownTaskRefs, useResolvedTaskRefVersion } from "./task-refs.js";
|
|
@@ -30,6 +30,13 @@ export function TeamMessage({ senderName, memberId, human, body, occurredAt, men
|
|
|
30
30
|
}, [onResolveTaskRefs, bodyTaskRefKey, refVersion]);
|
|
31
31
|
const taskLabel = useCallback((taskNumber) => t?.('taskLabel', { number: taskNumber }) ?? `Task #${taskNumber}`, [t]);
|
|
32
32
|
const refLabel = useCallback((ref) => ref.startsWith('thread:') ? (t?.('threadLabel') ?? 'Thread') : ref.startsWith('channel:') ? (t?.('channels') ?? 'Channels') : ref, [t]);
|
|
33
|
+
// Markdown chrome (code-copy buttons, footnotes heading) is locale copy the
|
|
34
|
+
// cordis-free primitive receives via props. Stable per locale revision — a
|
|
35
|
+
// fresh object per render would rebuild the component table every chunk.
|
|
36
|
+
const markdownLabels = useMemo(() => ({
|
|
37
|
+
code: { copyLabel: t?.('copyCode') ?? 'Copy', copiedLabel: t?.('copiedCode') ?? 'Copied' },
|
|
38
|
+
footnotes: t?.('markdownFootnotes') ?? 'Footnotes',
|
|
39
|
+
}), [t]);
|
|
33
40
|
// Long bodies start clamped behind the expand control. The default derives
|
|
34
41
|
// from the body alone; the toggle itself is per-mount view state nothing
|
|
35
42
|
// persists.
|
|
@@ -84,7 +91,7 @@ export function TeamMessage({ senderName, memberId, human, body, occurredAt, men
|
|
|
84
91
|
: _jsx(Fragment, { children: renderRefs(segment.text, onOpenRef, taskLabel, refLabel) }, index)) })
|
|
85
92
|
: plan.render === 'literal'
|
|
86
93
|
? _jsx("div", { className: css.messageText, children: onOpenRef === undefined ? _jsx(MessageText, { text: displayBody }) : renderRefs(displayBody, onOpenRef, taskLabel, refLabel) })
|
|
87
|
-
: _jsx("div", { ref: markdownRef, className: css.messageMarkdown, children: _jsx(MarkdownText, { text: displayBody }, `${displayBody}:${onOpenRef === undefined ? 'literal' : 'refs'}`) });
|
|
94
|
+
: _jsx("div", { ref: markdownRef, className: css.messageMarkdown, children: _jsx(MarkdownText, { text: displayBody, labels: markdownLabels }, `${displayBody}:${onOpenRef === undefined ? 'literal' : 'refs'}`) });
|
|
88
95
|
return (_jsxs("article", { className: css.messageRow, "data-human": human || undefined, "data-grouped": grouped || undefined, children: [_jsx("div", { className: css.messageIdentity, style: avatarStyle, "aria-hidden": "true", children: senderName.replace('@', '').slice(0, 1).toUpperCase() }), _jsxs("div", { className: css.messageBody, children: [(!grouped || showGroupedTime === true) && (_jsxs("div", { className: css.nameRow, children: [!grouped && _jsx("strong", { ...(senderTitle === undefined ? {} : { title: senderTitle }), children: senderName }), occurredAt !== undefined && _jsx("span", { className: css.messageTime, children: formatMessageTime(occurredAt) })] })), clampable ? _jsx("div", { className: clamped ? css.messageClamp : undefined, children: bodyNode }) : bodyNode, clampable && (_jsx("button", { type: "button", className: css.messageExpand, "data-message-expand": "true", "aria-expanded": expanded, onClick: () => { setExpanded(value => !value); }, children: expanded ? (t?.('collapseMessage') ?? 'Show less') : (t?.('expandMessage') ?? 'Show more') })), (plan.fallbackNames.length > 0 || plan.fallbackRefs.length > 0) && (_jsxs("div", { className: css.mentionsRow, children: [plan.fallbackNames.map(name => _jsxs("span", { className: css.mention, children: ["@", name] }, name)), plan.fallbackRefs.map(ref => {
|
|
89
96
|
const resolved = cachedResolvedTaskRef(ref);
|
|
90
97
|
const label = resolved !== undefined && ref.startsWith('task:') ? taskLabel(resolved.taskNumber) : ref;
|
|
@@ -211,6 +218,11 @@ function renderRefs(text, onOpenRef, taskLabel, refLabel) {
|
|
|
211
218
|
if (segment.ref === undefined)
|
|
212
219
|
return _jsx(Fragment, { children: segment.text }, index);
|
|
213
220
|
const resolved = cachedResolvedTaskRef(segment.ref);
|
|
221
|
+
// Task refs link only once the Host confirms them; abbreviated or unknown
|
|
222
|
+
// refs stay plain text so prose never misfires as a link. Channel and
|
|
223
|
+
// Thread refs have no resolver and link at the authored position.
|
|
224
|
+
if (segment.ref.startsWith('task:') && resolved === undefined)
|
|
225
|
+
return _jsx(Fragment, { children: segment.text }, index);
|
|
214
226
|
const label = resolved !== undefined && segment.ref.startsWith('task:') ? taskLabel(resolved.taskNumber) : refLabel(segment.ref);
|
|
215
227
|
return _jsx("button", { type: "button", className: css.refLink, title: segment.ref, onClick: () => { onOpenRef(segment.ref); }, children: label }, index);
|
|
216
228
|
});
|
|
@@ -218,7 +230,7 @@ function renderRefs(text, onOpenRef, taskLabel, refLabel) {
|
|
|
218
230
|
/** One message's attachment strip: image thumbnails with a large view, or name chips when bytes are gone. */
|
|
219
231
|
function TeamAttachmentStrip({ attachments, loadAttachment, t }) {
|
|
220
232
|
const [zoomed, setZoomed] = useState();
|
|
221
|
-
return _jsxs("div", { className: css.attachmentStrip, children: [attachments.map(attachment => _jsx(TeamAttachment, { attachment: attachment, ...(loadAttachment === undefined ? {} : { loadAttachment }), ...(t === undefined ? {} : { t }), onZoom: setZoomed }, attachment.attachmentId)), zoomed !== undefined && _jsx(Modal, { open: true, ...(css.attachmentModal === undefined ? {} : { className: css.attachmentModal }), title: zoomed.name, onClose: () => { setZoomed(undefined); }, children: _jsx("img", { className: css.attachmentZoom, src: cachedAttachmentDataUrl(zoomed.attachmentId) ?? undefined, alt: zoomed.name }) })] });
|
|
233
|
+
return _jsxs("div", { className: css.attachmentStrip, children: [attachments.map(attachment => _jsx(TeamAttachment, { attachment: attachment, ...(loadAttachment === undefined ? {} : { loadAttachment }), ...(t === undefined ? {} : { t }), onZoom: setZoomed }, attachment.attachmentId)), zoomed !== undefined && _jsx(Modal, { open: true, ...(css.attachmentModal === undefined ? {} : { className: css.attachmentModal }), title: zoomed.name, closeLabel: t?.('close') ?? 'Close', onClose: () => { setZoomed(undefined); }, children: _jsx("img", { className: css.attachmentZoom, src: cachedAttachmentDataUrl(zoomed.attachmentId) ?? undefined, alt: zoomed.name }) })] });
|
|
222
234
|
}
|
|
223
235
|
function TeamAttachment({ attachment, loadAttachment, t, onZoom }) {
|
|
224
236
|
const wantsPreview = loadAttachment !== undefined && attachment.mediaType.startsWith('image/');
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { StateDotState } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
2
1
|
import type { AgentTeamClientMemberStatus } from '@wowyuarm/dsh-agent-team/types';
|
|
3
2
|
import type { TeamSidebarProps } from './slots.ts';
|
|
3
|
+
import type { TeamStateDotState } from './TeamStateDot.tsx';
|
|
4
4
|
export declare function presenceLabel(status: AgentTeamClientMemberStatus, t: TeamSidebarProps['t']): string;
|
|
5
5
|
/** Shared presence → indicator mapping for dots and avatar badges. */
|
|
6
|
-
export declare function presenceDotState(presence: AgentTeamClientMemberStatus['presence']):
|
|
6
|
+
export declare function presenceDotState(presence: AgentTeamClientMemberStatus['presence']): TeamStateDotState;
|
|
7
7
|
export declare function TeamPresenceDot({ status, t }: {
|
|
8
8
|
readonly status: AgentTeamClientMemberStatus;
|
|
9
9
|
readonly t: TeamSidebarProps['t'];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TeamPresenceDot.d.ts","sourceRoot":"","sources":["../../../src/client/TeamPresenceDot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,
|
|
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,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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { Tooltip } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
3
|
+
import { TeamStateDot } from "./TeamStateDot.js";
|
|
3
4
|
import css from './presence.module.css';
|
|
4
5
|
export function presenceLabel(status, t) {
|
|
5
6
|
const label = status.presence === 'available' ? t('statusAvailable')
|
|
@@ -9,12 +10,9 @@ export function presenceLabel(status, t) {
|
|
|
9
10
|
}
|
|
10
11
|
/** Shared presence → indicator mapping for dots and avatar badges. */
|
|
11
12
|
export function presenceDotState(presence) {
|
|
12
|
-
return presence === 'available' ? 'done' : presence === 'working' ? 'ongoing' : presence === 'error' ? 'error' : '
|
|
13
|
+
return presence === 'available' ? 'done' : presence === 'working' ? 'ongoing' : presence === 'error' ? 'error' : 'quiet';
|
|
13
14
|
}
|
|
14
15
|
export function TeamPresenceDot({ status, t }) {
|
|
15
16
|
const label = presenceLabel(status, t);
|
|
16
|
-
|
|
17
|
-
return (_jsx(Tooltip, { label: label, delayMs: 300, children: _jsx("span", { className: css.target, role: "img", "aria-label": label, children: state === 'gray'
|
|
18
|
-
? _jsx("span", { className: css.unavailableDot, "aria-hidden": "true" })
|
|
19
|
-
: _jsx(StateDot, { state: state }) }) }));
|
|
17
|
+
return (_jsx(Tooltip, { label: label, delayMs: 300, children: _jsx("span", { className: css.target, role: "img", "aria-label": label, children: _jsx(TeamStateDot, { state: presenceDotState(status.presence) }) }) }));
|
|
20
18
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { StateDotState } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
2
|
+
/** The Team status dot language: the DSH four-color states plus the two quiet statuses StateDot has no slot for. */
|
|
3
|
+
export type TeamStateDotState = StateDotState | 'todo' | 'quiet';
|
|
4
|
+
/**
|
|
5
|
+
* Render the one shared Team status indicator. Native StateDot states pass
|
|
6
|
+
* through; the quiet statuses mirror StateDot geometry locally so every
|
|
7
|
+
* surface renders the same shape — todo a hollow ring (not started), quiet a
|
|
8
|
+
* solid tertiary dot with the same 10% halo (closed, unavailable).
|
|
9
|
+
*/
|
|
10
|
+
export declare function TeamStateDot({ state, size }: {
|
|
11
|
+
readonly state: TeamStateDotState;
|
|
12
|
+
readonly size?: number | undefined;
|
|
13
|
+
}): import("react").JSX.Element;
|
|
14
|
+
//# sourceMappingURL=TeamStateDot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TeamStateDot.d.ts","sourceRoot":"","sources":["../../../src/client/TeamStateDot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAA;AAG1E,oHAAoH;AACpH,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,MAAM,GAAG,OAAO,CAAA;AAEhE;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,IAAS,EAAE,EAAE;IACjD,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAA;IACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC,+BAKA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { StateDot } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
3
|
+
import css from './state-dot.module.css';
|
|
4
|
+
/**
|
|
5
|
+
* Render the one shared Team status indicator. Native StateDot states pass
|
|
6
|
+
* through; the quiet statuses mirror StateDot geometry locally so every
|
|
7
|
+
* surface renders the same shape — todo a hollow ring (not started), quiet a
|
|
8
|
+
* solid tertiary dot with the same 10% halo (closed, unavailable).
|
|
9
|
+
*/
|
|
10
|
+
export function TeamStateDot({ state, size = 10 }) {
|
|
11
|
+
if (state === 'todo' || state === 'quiet') {
|
|
12
|
+
return _jsx("span", { className: css.quiet, "data-variant": state, style: { width: size, height: size }, "aria-hidden": "true" });
|
|
13
|
+
}
|
|
14
|
+
return _jsx(StateDot, { state: state, size: size });
|
|
15
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentTeamChannelRef, AgentTeamTaskRef, AgentTeamThreadRef } from '@wowyuarm/dsh-agent-team/types';
|
|
2
|
-
import type { WorkspaceId } from '@deepseek-ai/dsh-
|
|
2
|
+
import type { WorkspaceId } from '@deepseek-ai/dsh-api-workspace-controller/client';
|
|
3
3
|
import type { TeamConversationProps } from './slots.ts';
|
|
4
4
|
import type { TeamDraftStore } from './drafts.ts';
|
|
5
5
|
interface TeamThreadPageProps {
|
|
@@ -12,6 +12,7 @@ interface TeamThreadPageProps {
|
|
|
12
12
|
readonly loadChannels: TeamConversationProps['loadChannels'];
|
|
13
13
|
readonly readThread: TeamConversationProps['readThread'];
|
|
14
14
|
readonly loadThreadHistory: TeamConversationProps['loadThreadHistory'];
|
|
15
|
+
readonly threadObservations: TeamConversationProps['threadObservations'];
|
|
15
16
|
readonly subscribeChanges: TeamConversationProps['subscribeChanges'];
|
|
16
17
|
readonly loadMembers: TeamConversationProps['loadMembers'];
|
|
17
18
|
readonly drafts: TeamDraftStore;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TeamThreadPage.d.ts","sourceRoot":"","sources":["../../../src/client/TeamThreadPage.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,mBAAmB,EAInB,gBAAgB,EAGhB,kBAAkB,EAEnB,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"TeamThreadPage.d.ts","sourceRoot":"","sources":["../../../src/client/TeamThreadPage.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,mBAAmB,EAInB,gBAAgB,EAGhB,kBAAkB,EAEnB,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kDAAkD,CAAA;AAEnF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AACvD,OAAO,KAAK,EAAgB,cAAc,EAAE,MAAM,aAAa,CAAA;AAe/D,UAAU,mBAAmB;IAC3B,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,UAAU,CAAC,EAAE,mBAAmB,CAAA;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,gBAAgB,CAAA;IACnC,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAA;IACtC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,eAAe,EAAE,qBAAqB,CAAC,iBAAiB,CAAC,CAAA;IAClE,QAAQ,CAAC,YAAY,EAAE,qBAAqB,CAAC,cAAc,CAAC,CAAA;IAC5D,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC,YAAY,CAAC,CAAA;IACxD,QAAQ,CAAC,iBAAiB,EAAE,qBAAqB,CAAC,mBAAmB,CAAC,CAAA;IACtE,QAAQ,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,oBAAoB,CAAC,CAAA;IACxE,QAAQ,CAAC,gBAAgB,EAAE,qBAAqB,CAAC,kBAAkB,CAAC,CAAA;IACpE,QAAQ,CAAC,WAAW,EAAE,qBAAqB,CAAC,aAAa,CAAC,CAAA;IAC1D,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;IAC/B,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC,eAAe,CAAC,CAAA;IAC9D,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,CAAA;IAC9C,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC,YAAY,CAAC,CAAA;IACxD,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC,eAAe,CAAC,CAAA;IAC9D,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC,eAAe,CAAC,CAAA;IAC9D,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC,eAAe,CAAC,CAAA;IAC9D,QAAQ,CAAC,YAAY,EAAE,qBAAqB,CAAC,cAAc,CAAC,CAAA;IAC5D,QAAQ,CAAC,eAAe,EAAE,qBAAqB,CAAC,iBAAiB,CAAC,CAAA;IAClE,QAAQ,CAAC,CAAC,EAAE,qBAAqB,CAAC,GAAG,CAAC,CAAA;CACvC;AA8BD,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,+BAgsBxD"}
|
|
@@ -5,7 +5,8 @@ import { TeamComposer } from "./TeamComposer.js";
|
|
|
5
5
|
import { TeamPresenceDot } from "./TeamPresenceDot.js";
|
|
6
6
|
import { TeamMessage } from "./TeamMessage.js";
|
|
7
7
|
import { TeamRunDivider } from "./TeamRunDivider.js";
|
|
8
|
-
import { formatActivity, formatClaimState, formatTaskStatus, formatTaskTitle, mentionNamesOf } from "./team-formatters.js";
|
|
8
|
+
import { formatActivity, formatClaimState, formatTaskStatus, formatTaskTitle, mentionNamesOf, taskStatusDot } from "./team-formatters.js";
|
|
9
|
+
import { TeamStateDot } from "./TeamStateDot.js";
|
|
9
10
|
import { mintRequestId } from "./requests.js";
|
|
10
11
|
import { daySeparatorLabel, isRunGap, timelineDayKey } from "./team-separators.js";
|
|
11
12
|
import { useTimelineScroll } from "./timeline-scroll.js";
|
|
@@ -33,11 +34,14 @@ function readMeta(facts) {
|
|
|
33
34
|
return new Map(facts.map(fact => [factKey(fact.fact), fact]));
|
|
34
35
|
}
|
|
35
36
|
export function TeamThreadPage(props) {
|
|
36
|
-
const { workspaceId, channelRef, taskRef, threadRef, taskNumber, backToWorkspace, selectChannel, selectThread, resolveTaskRefs, putAttachment, loadChannels, readThread, loadThreadHistory, subscribeChanges, loadMembers, drafts, getAttachment, reply, changeTask, promoteThread, t, } = props;
|
|
37
|
+
const { workspaceId, channelRef, taskRef, threadRef, taskNumber, backToWorkspace, selectChannel, selectThread, resolveTaskRefs, putAttachment, loadChannels, readThread, loadThreadHistory, threadObservations, subscribeChanges, loadMembers, drafts, getAttachment, reply, changeTask, promoteThread, t, } = props;
|
|
37
38
|
const threadRequest = { threadRef, ...(taskRef === undefined ? {} : { taskRef }) };
|
|
38
39
|
const [projection, setProjection] = useState();
|
|
39
40
|
const [channelView, setChannelView] = useState();
|
|
40
41
|
const [members, setMembers] = useState([]);
|
|
42
|
+
// Current Thread followers; the composer ranks them first because a mention
|
|
43
|
+
// to a follower delivers directly instead of entering the invite detour.
|
|
44
|
+
const [followerIds, setFollowerIds] = useState(() => new Set());
|
|
41
45
|
const [currentFacts, setCurrentFacts] = useState([]);
|
|
42
46
|
const [olderFacts, setOlderFacts] = useState([]);
|
|
43
47
|
const [readFacts, setReadFacts] = useState([]);
|
|
@@ -196,29 +200,37 @@ export function TeamThreadPage(props) {
|
|
|
196
200
|
// Every arrival while the Thread is open is acknowledged durably: the
|
|
197
201
|
// timeline renders it either way, and the Human has no manual read
|
|
198
202
|
// action anymore. The count only feeds the pure jump hint for a reader
|
|
199
|
-
// away from the
|
|
203
|
+
// away from the tail; a bottom-pinned reader already sees the arrivals.
|
|
200
204
|
if (!timeline.isPinned())
|
|
201
205
|
setNewFactsCount(current => current + additions.length);
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
// The durable acknowledgment did not happen (it failed, a newer read
|
|
206
|
-
// superseded it, or the page unmounted); the count keeps the jump hint
|
|
207
|
-
// visible unless that newer read now owns the tail.
|
|
208
|
-
if (!mountedRef.current || sequenceRef.current !== priorSequence + 1)
|
|
209
|
-
return;
|
|
210
|
-
setNewFactsCount(current => current + additions.length);
|
|
206
|
+
// The acknowledgment outcome does not change what is on screen: a
|
|
207
|
+
// failed read surfaces through the error surface, not through the count.
|
|
208
|
+
await readCurrent(true);
|
|
211
209
|
}
|
|
212
210
|
catch {
|
|
213
211
|
// A passive refresh is an invalidation convenience; the next explicit action rereads Host state.
|
|
214
212
|
}
|
|
215
213
|
};
|
|
214
|
+
// Follower ranking is an enhancement, not a page fact: a failed observation
|
|
215
|
+
// read leaves the roster order in place instead of surfacing an error.
|
|
216
|
+
const refreshFollowers = async () => {
|
|
217
|
+
try {
|
|
218
|
+
const result = await threadObservations({ workspaceId, ...threadRequest });
|
|
219
|
+
if (!mountedRef.current || !result.ok)
|
|
220
|
+
return;
|
|
221
|
+
setFollowerIds(new Set(result.value.followers));
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
// The next thread-scope wake retries; ranking falls back to roster order.
|
|
225
|
+
}
|
|
226
|
+
};
|
|
216
227
|
useEffect(() => {
|
|
217
228
|
mountedRef.current = true;
|
|
218
229
|
projectionRef.current = undefined;
|
|
219
230
|
setProjection(undefined);
|
|
220
231
|
setChannelView(undefined);
|
|
221
232
|
setMembers([]);
|
|
233
|
+
setFollowerIds(new Set());
|
|
222
234
|
setCurrentFacts([]);
|
|
223
235
|
currentFactsRef.current = [];
|
|
224
236
|
setOlderFacts([]);
|
|
@@ -235,9 +247,10 @@ export function TeamThreadPage(props) {
|
|
|
235
247
|
void (async () => {
|
|
236
248
|
// One parallel round covers the whole first paint. The durable read no
|
|
237
249
|
// longer wakes any change scope, so no second wave follows it.
|
|
238
|
-
const [read, history] = await Promise.all([
|
|
250
|
+
const [read, history, observations] = await Promise.all([
|
|
239
251
|
readThread({ requestId: readRequestIdRef.current, workspaceId, ...threadRequest }),
|
|
240
252
|
loadThreadHistory({ workspaceId, ...threadRequest, limit: 20 }).catch(() => undefined),
|
|
253
|
+
threadObservations({ workspaceId, ...threadRequest }).catch(() => undefined),
|
|
241
254
|
]);
|
|
242
255
|
if (!mountedRef.current || sequence !== sequenceRef.current)
|
|
243
256
|
return;
|
|
@@ -259,6 +272,8 @@ export function TeamThreadPage(props) {
|
|
|
259
272
|
setHistoryCursor(history.value.cursor);
|
|
260
273
|
setHistoryHasMore(history.value.hasMore);
|
|
261
274
|
}
|
|
275
|
+
if (observations !== undefined && observations.ok)
|
|
276
|
+
setFollowerIds(new Set(observations.value.followers));
|
|
262
277
|
setError(undefined);
|
|
263
278
|
setLoading(false);
|
|
264
279
|
await drainUnread();
|
|
@@ -273,6 +288,8 @@ export function TeamThreadPage(props) {
|
|
|
273
288
|
return;
|
|
274
289
|
}
|
|
275
290
|
void refreshPassiveFacts();
|
|
291
|
+
// Attention changes wake this scope too; keep the mention ranking current.
|
|
292
|
+
void refreshFollowers();
|
|
276
293
|
}),
|
|
277
294
|
subscribeChanges({ kind: 'workspace', workspaceId }, update => {
|
|
278
295
|
if (!mountedRef.current)
|
|
@@ -298,6 +315,14 @@ export function TeamThreadPage(props) {
|
|
|
298
315
|
if (newFactsCount > 0 && timeline.isPinned())
|
|
299
316
|
setNewFactsCount(0);
|
|
300
317
|
}, [newFactsCount, currentFacts, olderFacts, timeline]);
|
|
318
|
+
// The hint answers "where is the tail?"; the moment the reader is back
|
|
319
|
+
// within the follow margin — by the jump click or their own scroll — it
|
|
320
|
+
// must go away even when no render follows that position change.
|
|
321
|
+
const handleTimelineScroll = () => {
|
|
322
|
+
timeline.onScroll();
|
|
323
|
+
if (timeline.isPinned())
|
|
324
|
+
setNewFactsCount(0);
|
|
325
|
+
};
|
|
301
326
|
const loadOlder = async () => {
|
|
302
327
|
if (historyHasMore === false && historyCursor === undefined)
|
|
303
328
|
return;
|
|
@@ -614,7 +639,7 @@ export function TeamThreadPage(props) {
|
|
|
614
639
|
// Threads are always entered through a Channel page, so a Channel origin
|
|
615
640
|
// returns to its timeline; a Thread restored without one returns further.
|
|
616
641
|
const backLabel = channelRef === undefined ? t('backToWorkspace') : t('backToChannel');
|
|
617
|
-
return _jsxs("main", { className: css.surface, "data-team-thread": threadRef, children: [_jsxs("div", { className: css.surfaceHeader, children: [_jsx("div", { className: css.backRow, children: _jsx(Button, { size: "sm", icon: _jsx(IconChevronLeftOutline14, {}), onClick: backToWorkspace, children: backLabel }) }), _jsxs("header", { className: css.headerRow, children: [_jsxs("div", { className: css.headerCopy, children: [_jsxs("div", { className: threadCss.titleLine, children: [_jsx("h1", { children: task === undefined ? t('threadLabel') : t('taskLabel', { number: resolvedTaskNumber ?? '…' }) }), task !== undefined &&
|
|
642
|
+
return _jsxs("main", { className: css.surface, "data-team-thread": threadRef, children: [_jsxs("div", { className: css.surfaceHeader, children: [_jsx("div", { className: css.backRow, children: _jsx(Button, { size: "sm", icon: _jsx(IconChevronLeftOutline14, {}), onClick: backToWorkspace, children: backLabel }) }), _jsxs("header", { className: css.headerRow, children: [_jsxs("div", { className: css.headerCopy, children: [_jsxs("div", { className: threadCss.titleLine, children: [_jsx("h1", { children: task === undefined ? t('threadLabel') : t('taskLabel', { number: resolvedTaskNumber ?? '…' }) }), task !== undefined && _jsxs(Pill, { children: [_jsx(TeamStateDot, { size: 8, state: taskStatusDot(task.status) }), formatTaskStatus(task.status, t)] })] }), taskTitle !== undefined && taskTitle !== '' && _jsx("p", { className: threadCss.taskTitle, title: taskTitle, children: taskTitle })] }), task === undefined && thread !== undefined && _jsx("div", { className: css.headerActions, children: _jsx(Button, { size: "sm", variant: "primary", disabled: pending, onClick: () => { void convertToTask(); }, children: mutating === 'promote' ? t('promotingTask') : t('promoteToTask') }) }), task !== undefined && thread !== undefined && task.resolution !== 'closed' && _jsxs("div", { className: css.headerActions, children: [(() => {
|
|
618
643
|
const activeClaims = projection?.claims.filter(claim => claim.taskRef === task.taskRef && claim.state === 'active') ?? [];
|
|
619
644
|
const earlyAccept = task.resolution === 'open' && task.status === 'in_progress' && activeClaims.length > 0;
|
|
620
645
|
// todo Tasks accept directly: the work finished outside the
|
|
@@ -637,7 +662,7 @@ export function TeamThreadPage(props) {
|
|
|
637
662
|
})(), task !== undefined && thread !== undefined && _jsx("section", { className: threadCss.workSection, "aria-label": t('claims'), children: _jsx(DisclosureRow, { expandOnRowClick: true, expandable: true, open: claimsOpen, onToggle: () => { setClaimsOpen(current => !current); }, icon: _jsx(IconChecklistOutline14, { size: 14 }), title: `${t('claims')} · ${taskClaims.length}`, children: _jsxs("div", { className: threadCss.claimList, children: [taskClaims.length === 0 && _jsx("p", { className: threadCss.emptyClaims, children: t('noClaims') }), taskClaims.map(claim => {
|
|
638
663
|
const ownerStatus = members.find(status => status.member.memberId === claim.owner);
|
|
639
664
|
return _jsxs("article", { className: threadCss.claimRow, children: [ownerStatus === undefined ? _jsx("span", {}) : _jsx(TeamPresenceDot, { status: ownerStatus, t: t }), _jsx("strong", { className: threadCss.claimOwner, children: memberName(claim.owner) }), _jsx("span", { className: threadCss.claimDirection, children: claim.direction }), _jsx("small", { className: threadCss.claimState, children: formatClaimState(claim.state, t) })] }, claim.claimRef);
|
|
640
|
-
})] }) }) })] }), _jsx("section", { ref: timeline.ref, onScroll:
|
|
665
|
+
})] }) }) })] }), _jsx("section", { ref: timeline.ref, onScroll: handleTimelineScroll, className: css.timeline, "aria-label": t('timelineLabel'), children: _jsxs("div", { className: css.timelineContent, children: [loading && projection === undefined && error === undefined && _jsx("div", { className: css.emptySurface, children: _jsxs("p", { className: css.loadingState, children: [_jsx("span", { className: css.loadingMark, "aria-hidden": "true" }), t('loadingThread')] }) }), projection === undefined && error !== undefined && _jsxs("div", { className: css.errorState, role: "alert", children: [_jsx("span", { children: error }), _jsx(Button, { size: "sm", variant: "outline", onClick: () => { void readCurrent(); }, children: t('retry') })] }), olderFacts.length > 0 && _jsxs("section", { className: threadCss.historySection, "aria-label": t('olderHistory'), children: [_jsx("h2", { children: t('olderHistory') }), renderFactBlocks(olderFacts, undefined)] }), historyHasMore && _jsx("div", { className: css.timelineAction, children: _jsx(Button, { size: "sm", onClick: () => { void loadOlder(); }, children: t('loadOlder') }) }), currentFactsWithAnchor.length > 0 && _jsx("section", { className: threadCss.publicSection, children: renderFactBlocks(currentFactsWithAnchor, unreadBoundary) }), autoReadExhausted && _jsxs("div", { className: css.timelineAction, role: "alert", children: [_jsx("span", { children: t('autoReadIncomplete') }), _jsx(Button, { size: "sm", onClick: () => { setAutoReadExhausted(false); void drainUnread(); }, disabled: loading, children: t('retry') })] }), newFactsCount > 0 && _jsx("div", { className: threadCss.newUpdates, role: "status", children: _jsx("button", { type: "button", className: threadCss.newUpdatesJump, onClick: () => { setNewFactsCount(0); timeline.scrollToBottom(); }, children: t('newUpdatesJump', { count: newFactsCount }) }) })] }) }), projection !== undefined && thread !== undefined ? (task?.resolution === 'closed'
|
|
641
666
|
? _jsxs("div", { className: threadCss.closedBar, "data-team-closed": true, children: [error !== undefined && _jsx("p", { className: css.error, role: "alert", children: error }), _jsxs("div", { className: threadCss.closedNotice, children: [_jsx("span", { children: t('taskClosedNotice') }), _jsx(Button, { size: "sm", variant: "outline", disabled: pending, onClick: () => { void mutateTask('reopen'); }, children: t('reopenTask') })] })] })
|
|
642
|
-
: _jsx(TeamComposer, { members: channelMembers, recipients: recipients, draft: draft, pending: pending, ...(statusMessage === undefined ? {} : { confirmation: statusMessage }), ...(error === undefined ? {} : { error }), onDraftChange: next => { drafts.writeDraft(draftKey, next); setConfirmation(undefined); setReplyRequestId(undefined); setStatusMessage(undefined); }, onRecipientsChange: next => { drafts.writeRecipients(draftKey, next); setConfirmation(undefined); setReplyRequestId(undefined); setStatusMessage(undefined); }, onSubmit: () => { void sendReply(); }, placeholder: t('replyPlaceholder'), pendingFiles: pendingFiles, onFilesChange: setPendingFiles, t: t }, draftKey)) : _jsx("div", {})] });
|
|
667
|
+
: _jsx(TeamComposer, { members: channelMembers, followerMemberIds: followerIds, recipients: recipients, draft: draft, pending: pending, ...(statusMessage === undefined ? {} : { confirmation: statusMessage }), ...(error === undefined ? {} : { error }), onDraftChange: next => { drafts.writeDraft(draftKey, next); setConfirmation(undefined); setReplyRequestId(undefined); setStatusMessage(undefined); }, onRecipientsChange: next => { drafts.writeRecipients(draftKey, next); setConfirmation(undefined); setReplyRequestId(undefined); setStatusMessage(undefined); }, onSubmit: () => { void sendReply(); }, placeholder: t('replyPlaceholder'), pendingFiles: pendingFiles, onFilesChange: setPendingFiles, t: t }, draftKey)) : _jsx("div", {})] });
|
|
643
668
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { TeamSidebarProps } from './slots.ts';
|
|
2
|
-
export declare function TeamWorkspaceBrowser({ wide, expandSidebar, navigation, selectWorkspace, selectChannel, t, useWorkspaces, loadMembers, subscribeChanges, addMember, loadChannels, createChannel, updateChannel, updateMember, recoverMember, clearMemberContext, joinChannel, removeChannelMember, loadModels, openMemberSession }: TeamSidebarProps): import("react").JSX.Element;
|
|
2
|
+
export declare function TeamWorkspaceBrowser({ wide, expandSidebar, navigation, selectWorkspace, selectChannel, t, useWorkspaces, loadMembers, subscribeChanges, addMember, loadChannels, createChannel, updateChannel, archiveChannel, updateMember, recoverMember, clearMemberContext, archiveMember, joinChannel, removeChannelMember, loadModels, openMemberSession }: TeamSidebarProps): import("react").JSX.Element;
|
|
3
3
|
//# sourceMappingURL=TeamWorkspaceBrowser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TeamWorkspaceBrowser.d.ts","sourceRoot":"","sources":["../../../src/client/TeamWorkspaceBrowser.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAUlD,wBAAgB,oBAAoB,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,WAAW,EAAE,mBAAmB,EAAE,UAAU,EAAE,iBAAiB,EAAE,EAAE,gBAAgB,+
|
|
1
|
+
{"version":3,"file":"TeamWorkspaceBrowser.d.ts","sourceRoot":"","sources":["../../../src/client/TeamWorkspaceBrowser.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAUlD,wBAAgB,oBAAoB,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,EAAE,UAAU,EAAE,iBAAiB,EAAE,EAAE,gBAAgB,+BA8DlX"}
|
|
@@ -7,7 +7,7 @@ import { useSidebarSectionOpen, setSidebarSectionOpen } from "./sidebar-sections
|
|
|
7
7
|
import { TeamAgentsPanel } from "./TeamAgentsPanel.js";
|
|
8
8
|
import { TeamChannelsPanel } from "./TeamChannelsPanel.js";
|
|
9
9
|
import css from './sidebar.module.css';
|
|
10
|
-
export function TeamWorkspaceBrowser({ wide, expandSidebar, navigation, selectWorkspace, selectChannel, t, useWorkspaces, loadMembers, subscribeChanges, addMember, loadChannels, createChannel, updateChannel, updateMember, recoverMember, clearMemberContext, joinChannel, removeChannelMember, loadModels, openMemberSession }) {
|
|
10
|
+
export function TeamWorkspaceBrowser({ wide, expandSidebar, navigation, selectWorkspace, selectChannel, t, useWorkspaces, loadMembers, subscribeChanges, addMember, loadChannels, createChannel, updateChannel, archiveChannel, updateMember, recoverMember, clearMemberContext, archiveMember, joinChannel, removeChannelMember, loadModels, openMemberSession }) {
|
|
11
11
|
const navigationState = useSyncExternalStore(navigation.subscribe, navigation.getSnapshot, navigation.getSnapshot);
|
|
12
12
|
const workspaces = useWorkspaces(state => state.items);
|
|
13
13
|
const selected = navigationState.workspaceId;
|
|
@@ -39,5 +39,5 @@ export function TeamWorkspaceBrowser({ wide, expandSidebar, navigation, selectWo
|
|
|
39
39
|
if (!wide) {
|
|
40
40
|
return _jsxs("nav", { className: css.railWorkspace, "aria-label": t('workspaceSections'), children: [_jsx(Tooltip, { label: t('channels'), side: "right", children: _jsx("button", { type: "button", className: css.railButton, "aria-label": t('channels'), onClick: () => { setPendingSection('channels'); expandSidebar(); }, children: _jsx(IconListPenOutline16, { size: 16 }) }) }), _jsx(Tooltip, { label: t('agents'), side: "right", children: _jsx("button", { type: "button", className: css.railButton, "aria-label": t('agents'), onClick: () => { setPendingSection('agents'); expandSidebar(); }, children: _jsx(IconAgentPresetOutline16, { size: 16 }) }) })] });
|
|
41
41
|
}
|
|
42
|
-
return _jsxs("section", { className: css.workspaceBrowser, "aria-label": t('workspaces'), children: [_jsx(TeamSidebarSection, { title: t('workspaces'), open: workspacesOpen, onToggle: open => { setSidebarSectionOpen(undefined, 'workspaces', open); }, children: _jsxs("div", { className: css.workspaceList, children: [workspaces.map(workspace => _jsx(TeamWorkspaceRow, { workspaceId: workspace.workspaceId, title: workspace.title, path: workspace.path, selected: workspace.workspaceId === selectedId, current: workspace.workspaceId === selectedId && overviewIsCurrent, onSelect: selectWorkspace }, workspace.workspaceId)), workspaces.length === 0 && _jsx("p", { className: css.emptyState, children: t('empty') })] }) }), selectedId !== undefined && _jsxs("div", { className: css.workspaceSection, children: [_jsx("div", { ref: channelsRef, children: _jsx(TeamChannelsPanel, { workspaceId: selectedId, loadMembers: loadMembers, loadChannels: loadChannels, subscribeChanges: subscribeChanges, createChannel: createChannel, updateChannel: updateChannel, joinChannel: joinChannel, removeChannelMember: removeChannelMember, creatingAgents: creatingAgents.filter(request => request.workspaceId === selectedId), ...(navigationState.memberSessionId !== undefined || navigationState.channelRef === undefined ? {} : { selectedChannelRef: navigationState.channelRef }), selectChannel: selectChannel, t: t }, selectedId) }), _jsx("div", { ref: agentsRef, children: _jsx(TeamAgentsPanel, { workspaceId: selectedId, loadMembers: loadMembers, subscribeChanges: subscribeChanges, addMember: addMember, updateMember: updateMember, recoverMember: recoverMember, clearMemberContext: clearMemberContext, loadModels: loadModels, ...(navigationState.memberSessionId === undefined ? {} : { memberSessionId: navigationState.memberSessionId }), openMemberSession: openMemberSession, onCreatingChange: (request, creating) => { setCreatingAgents(current => creating ? [...current.filter(item => item.requestId !== request.requestId), request] : current.filter(item => item.requestId !== request.requestId)); }, t: t }, selectedId) })] })] });
|
|
42
|
+
return _jsxs("section", { className: css.workspaceBrowser, "aria-label": t('workspaces'), children: [_jsx(TeamSidebarSection, { title: t('workspaces'), open: workspacesOpen, onToggle: open => { setSidebarSectionOpen(undefined, 'workspaces', open); }, children: _jsxs("div", { className: css.workspaceList, children: [workspaces.map(workspace => _jsx(TeamWorkspaceRow, { workspaceId: workspace.workspaceId, title: workspace.title, path: workspace.path, selected: workspace.workspaceId === selectedId, current: workspace.workspaceId === selectedId && overviewIsCurrent, onSelect: selectWorkspace }, workspace.workspaceId)), workspaces.length === 0 && _jsx("p", { className: css.emptyState, children: t('empty') })] }) }), selectedId !== undefined && _jsxs("div", { className: css.workspaceSection, children: [_jsx("div", { ref: channelsRef, children: _jsx(TeamChannelsPanel, { workspaceId: selectedId, loadMembers: loadMembers, loadChannels: loadChannels, subscribeChanges: subscribeChanges, createChannel: createChannel, updateChannel: updateChannel, archiveChannel: archiveChannel, joinChannel: joinChannel, removeChannelMember: removeChannelMember, creatingAgents: creatingAgents.filter(request => request.workspaceId === selectedId), ...(navigationState.memberSessionId !== undefined || navigationState.channelRef === undefined ? {} : { selectedChannelRef: navigationState.channelRef }), selectChannel: selectChannel, t: t }, selectedId) }), _jsx("div", { ref: agentsRef, children: _jsx(TeamAgentsPanel, { workspaceId: selectedId, loadMembers: loadMembers, subscribeChanges: subscribeChanges, addMember: addMember, updateMember: updateMember, recoverMember: recoverMember, clearMemberContext: clearMemberContext, archiveMember: archiveMember, loadModels: loadModels, ...(navigationState.memberSessionId === undefined ? {} : { memberSessionId: navigationState.memberSessionId }), openMemberSession: openMemberSession, onCreatingChange: (request, creating) => { setCreatingAgents(current => creating ? [...current.filter(item => item.requestId !== request.requestId), request] : current.filter(item => item.requestId !== request.requestId)); }, t: t }, selectedId) })] })] });
|
|
43
43
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { WorkspaceId } from '@deepseek-ai/dsh-
|
|
1
|
+
import type { WorkspaceId } from '@deepseek-ai/dsh-api-workspace-controller/client';
|
|
2
2
|
export declare function TeamWorkspaceRow({ workspaceId, title, path, selected, current, onSelect }: {
|
|
3
3
|
workspaceId: WorkspaceId;
|
|
4
4
|
title: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TeamWorkspaceRow.d.ts","sourceRoot":"","sources":["../../../src/client/TeamWorkspaceRow.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"TeamWorkspaceRow.d.ts","sourceRoot":"","sources":["../../../src/client/TeamWorkspaceRow.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kDAAkD,CAAA;AAGnF,wBAAgB,gBAAgB,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;IAC1F,WAAW,EAAE,WAAW,CAAA;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,4EAA4E;IAC5E,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,CAAA;CAC7C,+BAgBA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ClientContext } from '@deepseek-ai/
|
|
1
|
+
import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
2
2
|
import { TeamNavigation } from './navigation.ts';
|
|
3
3
|
import { TeamDraftStore } from './drafts.ts';
|
|
4
4
|
import { type TeamKey } from './locales.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,
|
|
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;AAoCnE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAK5C,OAAO,EAAU,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAEnD,YAAY,EAAE,QAAQ,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AAC9F,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAIhD,eAAO,MAAM,MAAM,UAElB,CAAA;AAED,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,kBAAkB;QAC1B,IAAI,EAAE,OAAO,CAAA;KACd;CACF;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,cAAc,EAAE,cAAc,CAAA;QAC9B,UAAU,EAAE,cAAc,CAAA;KAC3B;CACF;AAyJD,wBAAsB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7D"}
|
|
@@ -6,13 +6,11 @@ import { TeamFooterAction } from "./TeamFooterAction.js";
|
|
|
6
6
|
import { TeamSettings } from "./TeamSettings.js";
|
|
7
7
|
import { TeamConversation } from "./TeamConversation.js";
|
|
8
8
|
import { TeamWorkspaceBrowser } from "./TeamWorkspaceBrowser.js";
|
|
9
|
-
import { TeamMemberSessionComposer } from "./TeamMemberSessionComposer.js";
|
|
10
|
-
import { admitTeamCompact, createTeamMemberSessionSources } from "./member-session-input.js";
|
|
11
9
|
import { en, zh } from "./locales.js";
|
|
12
10
|
export { TeamNavigation } from "./navigation.js";
|
|
13
11
|
const NS = 'team';
|
|
14
12
|
export const inject = [
|
|
15
|
-
'slots', 'workspaces', 'locale', 'remote', '
|
|
13
|
+
'slots', 'workspaces', 'locale', 'remote', 'remote.session', 'sessions', 'connection', 'conversation',
|
|
16
14
|
];
|
|
17
15
|
function registerModeShadow(ctx, navigation, changes, drafts, name, component, extraInject) {
|
|
18
16
|
// Stay in Team mode: the conversation shadow stands down for Member Session
|
|
@@ -37,15 +35,13 @@ function registerModeShadow(ctx, navigation, changes, drafts, name, component, e
|
|
|
37
35
|
joinChannel: (request) => ctx.remote.agentTeam.joinChannel(request),
|
|
38
36
|
removeChannelMember: (request) => ctx.remote.agentTeam.removeChannelMember(request),
|
|
39
37
|
updateChannel: (request) => ctx.remote.agentTeam.updateChannel(request),
|
|
38
|
+
archiveChannel: (request) => ctx.remote.agentTeam.archiveChannel(request),
|
|
40
39
|
updateMember: (request) => ctx.remote.agentTeam.updateMember(request),
|
|
41
40
|
recoverMember: (request) => ctx.remote.agentTeam.recoverMember(request),
|
|
42
41
|
clearMemberContext: (request) => ctx.remote.agentTeam.clearMemberContext(request),
|
|
42
|
+
archiveMember: (request) => ctx.remote.agentTeam.archiveMember(request),
|
|
43
43
|
// The Host-scoped catalog needs no live Member, so suspended ones stay editable too.
|
|
44
|
-
loadModels:
|
|
45
|
-
const connection = ctx.get('connection');
|
|
46
|
-
const response = await connection.api.llm.models({});
|
|
47
|
-
return response.result;
|
|
48
|
-
},
|
|
44
|
+
loadModels: () => ctx.remote.session.modelCatalog(),
|
|
49
45
|
openMemberSession: openMemberSessionImpl,
|
|
50
46
|
};
|
|
51
47
|
ctx.slots.inject(name, () => {
|
|
@@ -69,6 +65,7 @@ function registerModeShadow(ctx, navigation, changes, drafts, name, component, e
|
|
|
69
65
|
...(name === 'conversation' ? {
|
|
70
66
|
readThread: (request) => ctx.remote.agentTeam.readThread(request),
|
|
71
67
|
loadThreadHistory: (request) => ctx.remote.agentTeam.threadHistory(request),
|
|
68
|
+
threadObservations: (request) => ctx.remote.agentTeam.threadObservations(request),
|
|
72
69
|
sendMessage: (request) => ctx.remote.agentTeam.sendMessage(request),
|
|
73
70
|
putAttachment: (request) => ctx.remote.agentTeam.putAttachment(request),
|
|
74
71
|
getAttachment: (request) => ctx.remote.agentTeam.getAttachment(request),
|
|
@@ -98,49 +95,6 @@ function registerModeShadow(ctx, navigation, changes, drafts, name, component, e
|
|
|
98
95
|
};
|
|
99
96
|
});
|
|
100
97
|
}
|
|
101
|
-
function registerMemberSessionComposer(ctx, navigation) {
|
|
102
|
-
ctx.slots.inject('conversation.composer.bar', () => {
|
|
103
|
-
let dispose;
|
|
104
|
-
let registeredSessionId;
|
|
105
|
-
const reconcile = () => {
|
|
106
|
-
const memberSessionId = navigation.getSnapshot().memberSessionId;
|
|
107
|
-
const active = navigation.getSnapshot().mode === 'team' && memberSessionId !== undefined;
|
|
108
|
-
if (dispose !== undefined && (!active || registeredSessionId !== memberSessionId)) {
|
|
109
|
-
dispose();
|
|
110
|
-
dispose = undefined;
|
|
111
|
-
registeredSessionId = undefined;
|
|
112
|
-
}
|
|
113
|
-
if (active && dispose === undefined) {
|
|
114
|
-
registeredSessionId = memberSessionId;
|
|
115
|
-
dispose = ctx.slots.register({
|
|
116
|
-
name: 'conversation.composer.bar',
|
|
117
|
-
priority: -100,
|
|
118
|
-
// The registration may remain live during a session transition, but
|
|
119
|
-
// it elects only when the shell's current Session is the embedded
|
|
120
|
-
// Member. This avoids taking an ordinary Session if selection races.
|
|
121
|
-
select: () => ctx.sessions.list.getSnapshot().current === memberSessionId ? {} : null,
|
|
122
|
-
inject: (sessionId) => {
|
|
123
|
-
const actx = ctx.sessions.scope(sessionId);
|
|
124
|
-
if (actx === undefined)
|
|
125
|
-
throw new Error(`agent-team: Member session ${String(sessionId)} has no client scope`);
|
|
126
|
-
const sessions = ctx.sessions;
|
|
127
|
-
return {
|
|
128
|
-
controller: ctx.get('inputTriggers').sessionOf(actx),
|
|
129
|
-
stop: () => { void sessions.sessionOf(actx)?.cancel(); },
|
|
130
|
-
submitInput: (mode) => ctx.conversation.input.for(actx).submit(mode),
|
|
131
|
-
};
|
|
132
|
-
},
|
|
133
|
-
}, TeamMemberSessionComposer);
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
const offNavigation = navigation.subscribe(reconcile);
|
|
137
|
-
reconcile();
|
|
138
|
-
return () => {
|
|
139
|
-
offNavigation();
|
|
140
|
-
dispose?.();
|
|
141
|
-
};
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
98
|
function applyUi(ctx) {
|
|
145
99
|
ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'agent-team: dictionaries');
|
|
146
100
|
const navigation = new TeamNavigation();
|
|
@@ -154,37 +108,16 @@ function applyUi(ctx) {
|
|
|
154
108
|
void disposeDrafts();
|
|
155
109
|
}, 'agent-team: navigation service');
|
|
156
110
|
const changes = new TeamChangeStream((request, signal) => ctx.remote.agentTeam.changes(request, signal));
|
|
157
|
-
const triggerSources = createTeamMemberSessionSources({
|
|
158
|
-
isEmbeddedMemberSession: sessionId => {
|
|
159
|
-
const snapshot = navigation.getSnapshot();
|
|
160
|
-
return snapshot.mode === 'team' && snapshot.memberSessionId === sessionId && snapshot.workspaceId !== undefined;
|
|
161
|
-
},
|
|
162
|
-
members: async () => {
|
|
163
|
-
const workspaceId = navigation.getSnapshot().workspaceId;
|
|
164
|
-
if (workspaceId === undefined)
|
|
165
|
-
return [];
|
|
166
|
-
const result = await ctx.remote.agentTeam.members({ workspaceId });
|
|
167
|
-
return result.ok ? result.value : [];
|
|
168
|
-
},
|
|
169
|
-
executeCompact: async (sessionId) => {
|
|
170
|
-
const actx = ctx.sessions.scope(sessionId);
|
|
171
|
-
const session = actx === undefined ? undefined : ctx.sessions.sessionOf(actx);
|
|
172
|
-
return session === undefined ? { kind: 'error', text: 'current Member Session is unavailable' } : admitTeamCompact(session);
|
|
173
|
-
},
|
|
174
|
-
});
|
|
175
|
-
const inputTriggers = ctx.get('inputTriggers');
|
|
176
|
-
ctx.effect(() => {
|
|
177
|
-
const disposers = triggerSources.map(source => inputTriggers.registerSource(source));
|
|
178
|
-
return () => { for (const dispose of disposers)
|
|
179
|
-
dispose(); };
|
|
180
|
-
}, 'agent-team: Member session trigger sources');
|
|
181
111
|
const loadMemberGroups = async () => {
|
|
182
112
|
const workspaces = ctx.workspaces.list.getSnapshot().items;
|
|
183
113
|
const groups = await Promise.all(workspaces.map(async (workspace) => {
|
|
184
114
|
const result = await ctx.remote.agentTeam.members({ workspaceId: workspace.workspaceId });
|
|
185
115
|
if (!result.ok)
|
|
186
116
|
throw new Error(result.error.message);
|
|
187
|
-
|
|
117
|
+
// The members modal is a listing surface: archived Members are hidden
|
|
118
|
+
// everywhere, and removed (inactive) ones never belong in a roster.
|
|
119
|
+
const members = result.value.filter(status => status.member.state !== 'inactive' && status.member.state !== 'archived');
|
|
120
|
+
return { workspaceId: workspace.workspaceId, workspaceTitle: workspace.title, members };
|
|
188
121
|
}));
|
|
189
122
|
return groups.filter(group => group.members.length > 0);
|
|
190
123
|
};
|
|
@@ -216,7 +149,6 @@ function applyUi(ctx) {
|
|
|
216
149
|
}, TeamFooterAction));
|
|
217
150
|
registerModeShadow(ctx, navigation, changes, drafts, 'sidebar.workspaces', TeamWorkspaceBrowser);
|
|
218
151
|
registerModeShadow(ctx, navigation, changes, drafts, 'conversation', TeamConversation);
|
|
219
|
-
registerMemberSessionComposer(ctx, navigation);
|
|
220
152
|
registerModeShadow(ctx, navigation, changes, drafts, 'sidebar.settings', TeamSettings, () => ({ loadMemberGroups }));
|
|
221
153
|
}
|
|
222
154
|
export async function apply(ctx) {
|
|
@@ -12,6 +12,9 @@ export declare const zh: {
|
|
|
12
12
|
readonly addAgent: "添加 Agent";
|
|
13
13
|
readonly cancel: "取消";
|
|
14
14
|
readonly close: "关闭";
|
|
15
|
+
readonly copyCode: "复制";
|
|
16
|
+
readonly copiedCode: "已复制";
|
|
17
|
+
readonly markdownFootnotes: "脚注";
|
|
15
18
|
readonly retry: "重试";
|
|
16
19
|
readonly agentName: "名称";
|
|
17
20
|
readonly agentDescription: "说明";
|
|
@@ -45,6 +48,16 @@ export declare const zh: {
|
|
|
45
48
|
readonly clearContextNotice: "将结束 {name} 当前的会话上下文并从空白开始:旧对话会归档保留在会话记录中。{name} 的身份、私有记忆与 notes、频道和会话绑定都保持不变,后续协作从新上下文继续累积。";
|
|
46
49
|
readonly clearContextConfirm: "开始全新上下文";
|
|
47
50
|
readonly clearContextFailed: "清空上下文失败:{message}";
|
|
51
|
+
readonly archiveAgent: "归档";
|
|
52
|
+
readonly archiveAgentTitle: "归档 Agent:{name}";
|
|
53
|
+
readonly archiveAgentNotice: "将把 {name} 从所有列表收起:会话与私有记忆保留在磁盘上、活跃 Claim 会释放,但暂无恢复入口。";
|
|
54
|
+
readonly archiveAgentConfirm: "归档";
|
|
55
|
+
readonly archiveAgentFailed: "归档失败:{message}";
|
|
56
|
+
readonly archiveChannel: "归档频道";
|
|
57
|
+
readonly archiveChannelTitle: "归档频道:{name}";
|
|
58
|
+
readonly archiveChannelNotice: "将把 {name} 及其全部讨论从所有列表收起:数据保留、所有成员在此频道的活跃 Claim 会释放,但暂无恢复入口。";
|
|
59
|
+
readonly archiveChannelConfirm: "归档频道";
|
|
60
|
+
readonly archiveChannelFailed: "归档频道失败:{message}";
|
|
48
61
|
readonly optionalSuffix: "(可选)";
|
|
49
62
|
readonly agentDescriptionPlaceholder: "留空则暂无描述";
|
|
50
63
|
readonly membersPickerEmpty: "选择初始成员";
|
|
@@ -154,6 +167,9 @@ export declare const en: {
|
|
|
154
167
|
readonly addAgent: "Add Agent";
|
|
155
168
|
readonly cancel: "Cancel";
|
|
156
169
|
readonly close: "Close";
|
|
170
|
+
readonly copyCode: "Copy";
|
|
171
|
+
readonly copiedCode: "Copied";
|
|
172
|
+
readonly markdownFootnotes: "Footnotes";
|
|
157
173
|
readonly retry: "Retry";
|
|
158
174
|
readonly agentName: "Name";
|
|
159
175
|
readonly agentDescription: "Description";
|
|
@@ -187,6 +203,16 @@ export declare const en: {
|
|
|
187
203
|
readonly clearContextNotice: "This ends {name}'s current session context and starts blank: the previous conversation is archived and stays in the session history. {name}'s identity, private memory and notes, channel and session bindings are untouched, and future collaboration accumulates from the new context.";
|
|
188
204
|
readonly clearContextConfirm: "Start from new context";
|
|
189
205
|
readonly clearContextFailed: "Failed to clear context: {message}";
|
|
206
|
+
readonly archiveAgent: "Archive";
|
|
207
|
+
readonly archiveAgentTitle: "Archive Agent: {name}";
|
|
208
|
+
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.";
|
|
209
|
+
readonly archiveAgentConfirm: "Archive";
|
|
210
|
+
readonly archiveAgentFailed: "Failed to archive: {message}";
|
|
211
|
+
readonly archiveChannel: "Archive Channel";
|
|
212
|
+
readonly archiveChannelTitle: "Archive Channel: {name}";
|
|
213
|
+
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.";
|
|
214
|
+
readonly archiveChannelConfirm: "Archive Channel";
|
|
215
|
+
readonly archiveChannelFailed: "Failed to archive Channel: {message}";
|
|
190
216
|
readonly optionalSuffix: " (optional)";
|
|
191
217
|
readonly agentDescriptionPlaceholder: "Leave empty if not needed";
|
|
192
218
|
readonly membersPickerEmpty: "Choose initial members";
|
|
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0JL,CAAA;AAEV,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0JL,CAAA;AAEV,MAAM,MAAM,OAAO,GAAG,MAAM,OAAO,EAAE,CAAA"}
|