@wowyuarm/dsh-agent-team 0.1.1 → 0.1.3
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 +1 -0
- package/README.zh.md +2 -0
- package/package.json +42 -25
- package/packages/agent-team/README.md +1 -1
- package/packages/agent-team/README.zh.md +1 -1
- package/packages/agent-team/lib/attachments.js +11 -12
- package/packages/agent-team/lib/auto-compaction.js +163 -0
- package/packages/agent-team/lib/index.js +262 -189
- package/packages/agent-team/lib/ledger.js +140 -109
- package/packages/agent-team/lib/recovery.js +30 -35
- package/packages/agent-team/lib/spec.js +10 -4
- package/packages/agent-team/lib/typert.host.js +68 -71
- package/packages/agent-team/lib/typert.remote-client.d.ts +3 -3
- package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
- package/packages/agent-team/lib/typert.remote-client.js +41 -56
- package/packages/agent-team/lib/types/attachments.d.ts +2 -2
- package/packages/agent-team/lib/types/attachments.d.ts.map +1 -1
- package/packages/agent-team/lib/types/auto-compaction.d.ts +38 -0
- package/packages/agent-team/lib/types/auto-compaction.d.ts.map +1 -0
- package/packages/agent-team/lib/types/index.d.ts +49 -24
- package/packages/agent-team/lib/types/index.d.ts.map +1 -1
- package/packages/agent-team/lib/types/ledger.d.ts +24 -11
- package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
- package/packages/agent-team/lib/types/recovery.d.ts +15 -16
- package/packages/agent-team/lib/types/recovery.d.ts.map +1 -1
- package/packages/agent-team/lib/types/spec.d.ts.map +1 -1
- package/packages/agent-team/lib/types/types.d.ts +20 -12
- package/packages/agent-team/lib/types/types.d.ts.map +1 -1
- package/packages/agent-team/preset/team-member/agent.cordis.yml +8 -3
- package/packages/client-agent-team/README.md +3 -2
- package/packages/client-agent-team/README.zh.md +3 -2
- package/packages/client-agent-team/lib/client.js +1507 -525
- package/packages/client-agent-team/lib/client.js.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts +1 -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 +24 -182
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts +3 -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 +27 -5
- package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.js +19 -4
- package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamComposer.js +22 -2
- 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 +3 -3
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.d.ts +34 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.js +169 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.d.ts +17 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.js +120 -0
- package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts +7 -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 +170 -18
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts +4 -0
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +70 -13
- 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/index.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/index.js +72 -2
- package/packages/client-agent-team/lib/types/client/locales.d.ts +8 -2
- package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/locales.js +8 -2
- package/packages/client-agent-team/lib/types/client/member-session-input.d.ts +22 -0
- package/packages/client-agent-team/lib/types/client/member-session-input.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/member-session-input.js +98 -0
- package/packages/client-agent-team/lib/types/client/requests.d.ts +16 -0
- package/packages/client-agent-team/lib/types/client/requests.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/requests.js +22 -0
- package/packages/client-agent-team/lib/types/client/sidebar-drag.d.ts +35 -0
- package/packages/client-agent-team/lib/types/client/sidebar-drag.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/sidebar-drag.js +70 -0
- package/packages/client-agent-team/lib/types/client/sidebar-order.d.ts +27 -0
- package/packages/client-agent-team/lib/types/client/sidebar-order.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/sidebar-order.js +170 -0
- package/packages/client-agent-team/lib/types/client/slots.d.ts +2 -2
- 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 +25 -0
- package/packages/client-agent-team/lib/types/client/task-refs.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/task-refs.js +77 -0
- package/packages/client-agent-team/lib/types/client/team-formatters.d.ts +54 -1
- 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 +83 -2
- package/packages/client-agent-team/lib/types/client/team-membership.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/team-membership.js +2 -1
- package/packages/tool-agent-team/lib/index.js +4 -4
- package/packages/client-agent-team/lib/types/client/TeamInboxPanel.d.ts +0 -13
- package/packages/client-agent-team/lib/types/client/TeamInboxPanel.d.ts.map +0 -1
- package/packages/client-agent-team/lib/types/client/TeamInboxPanel.js +0 -90
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/** Insert side of an in-flight drop relative to the hovered row. */
|
|
3
|
+
export type SidebarDropMarker = 'before' | 'after';
|
|
4
|
+
export interface SidebarRowDragHandlers<K extends string> {
|
|
5
|
+
/** Per-row native wiring plus the marker this row currently shows. */
|
|
6
|
+
readonly rowProps: (orderKey: K) => {
|
|
7
|
+
readonly draggable: true;
|
|
8
|
+
readonly className?: string | undefined;
|
|
9
|
+
readonly onDragStart: (event: React.DragEvent<HTMLElement>) => void;
|
|
10
|
+
readonly onDragEnd: () => void;
|
|
11
|
+
readonly onDragOver: (event: React.DragEvent<HTMLElement>) => void;
|
|
12
|
+
readonly onDrop: (event: React.DragEvent<HTMLElement>) => void;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* One drag gesture per panel instance. `onCommit` receives the moved ref,
|
|
17
|
+
* the drop target and the insertion side exactly once per completed gesture;
|
|
18
|
+
* releases outside the list never reach it.
|
|
19
|
+
*/
|
|
20
|
+
export declare function useSidebarRowDrag<K extends string>({ refs, onCommit }: {
|
|
21
|
+
/** Effective current order of the owning list, used for hit validation. */
|
|
22
|
+
readonly refs: readonly K[];
|
|
23
|
+
readonly onCommit: (movedRef: K, targetRef: K, marker: SidebarDropMarker) => void;
|
|
24
|
+
}): SidebarRowDragHandlers<K>;
|
|
25
|
+
/**
|
|
26
|
+
* Transparent wrapper that owns the drop-marker styling for one draggable
|
|
27
|
+
* sidebar row. It adds no layout of its own; the styled row stays inside so
|
|
28
|
+
* hover/focus descendant selectors keep working.
|
|
29
|
+
*/
|
|
30
|
+
export declare function SortableRow<K extends string>({ drag, orderKey, children }: {
|
|
31
|
+
readonly drag: SidebarRowDragHandlers<K>;
|
|
32
|
+
readonly orderKey: K;
|
|
33
|
+
readonly children: ReactNode;
|
|
34
|
+
}): import("react").JSX.Element;
|
|
35
|
+
//# sourceMappingURL=sidebar-drag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidebar-drag.d.ts","sourceRoot":"","sources":["../../../src/client/sidebar-drag.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,oEAAoE;AACpE,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,OAAO,CAAA;AAElD,MAAM,WAAW,sBAAsB,CAAC,CAAC,SAAS,MAAM;IACtD,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK;QAClC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAA;QACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QACvC,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;QACnE,QAAQ,CAAC,SAAS,EAAE,MAAM,IAAI,CAAA;QAC9B,QAAQ,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;QAClE,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;KAC/D,CAAA;CACF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;IACtE,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAA;IAC3B,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAA;CAClF,GAAG,sBAAsB,CAAC,CAAC,CAAC,CAwC5B;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;IAC1E,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,CAAA;IACxC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;IACpB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;CAC7B,+BAOA"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Native whole-row drag for the Team sidebar lists. Unlike the Harness
|
|
4
|
+
* workspace list there is no document-level acceptance here: hovering another
|
|
5
|
+
* row shows the before/after insertion marker and releasing on a row commits
|
|
6
|
+
* exactly once per gesture, while a release outside any row — including over
|
|
7
|
+
* the other sidebar list, whose panel never responds — just cancels without
|
|
8
|
+
* committing.
|
|
9
|
+
*/
|
|
10
|
+
import { useRef, useState } from 'react';
|
|
11
|
+
import css from './sidebar.module.css';
|
|
12
|
+
/**
|
|
13
|
+
* One drag gesture per panel instance. `onCommit` receives the moved ref,
|
|
14
|
+
* the drop target and the insertion side exactly once per completed gesture;
|
|
15
|
+
* releases outside the list never reach it.
|
|
16
|
+
*/
|
|
17
|
+
export function useSidebarRowDrag({ refs, onCommit }) {
|
|
18
|
+
const [state, setState] = useState(null);
|
|
19
|
+
const committed = useRef(false);
|
|
20
|
+
const half = (event) => {
|
|
21
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
22
|
+
return event.clientY - rect.top < rect.height / 2 ? 'before' : 'after';
|
|
23
|
+
};
|
|
24
|
+
return {
|
|
25
|
+
rowProps: orderKey => ({
|
|
26
|
+
draggable: true,
|
|
27
|
+
className: state === null ? undefined
|
|
28
|
+
: state.active === orderKey ? css.sidebarRowDragging
|
|
29
|
+
: state.over === orderKey ? (state.marker === 'before' ? css.sidebarRowDropBefore : css.sidebarRowDropAfter)
|
|
30
|
+
: undefined,
|
|
31
|
+
onDragStart: event => {
|
|
32
|
+
if (event.dataTransfer === null)
|
|
33
|
+
return;
|
|
34
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
35
|
+
event.dataTransfer.setData('text/plain', orderKey);
|
|
36
|
+
committed.current = false;
|
|
37
|
+
setState({ active: orderKey, over: orderKey, marker: 'after' });
|
|
38
|
+
},
|
|
39
|
+
onDragEnd: () => { setState(null); },
|
|
40
|
+
onDragOver: event => {
|
|
41
|
+
if (state === null || !refs.includes(orderKey))
|
|
42
|
+
return;
|
|
43
|
+
event.preventDefault();
|
|
44
|
+
if (event.dataTransfer !== null)
|
|
45
|
+
event.dataTransfer.dropEffect = 'move';
|
|
46
|
+
const marker = half(event);
|
|
47
|
+
if (state.over !== orderKey || state.marker !== marker)
|
|
48
|
+
setState({ ...state, over: orderKey, marker });
|
|
49
|
+
},
|
|
50
|
+
onDrop: event => {
|
|
51
|
+
if (state === null || !refs.includes(orderKey))
|
|
52
|
+
return;
|
|
53
|
+
event.preventDefault();
|
|
54
|
+
if (committed.current)
|
|
55
|
+
return;
|
|
56
|
+
committed.current = true;
|
|
57
|
+
onCommit(state.active, orderKey, half(event));
|
|
58
|
+
},
|
|
59
|
+
}),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Transparent wrapper that owns the drop-marker styling for one draggable
|
|
64
|
+
* sidebar row. It adds no layout of its own; the styled row stays inside so
|
|
65
|
+
* hover/focus descendant selectors keep working.
|
|
66
|
+
*/
|
|
67
|
+
export function SortableRow({ drag, orderKey, children }) {
|
|
68
|
+
const props = drag.rowProps(orderKey);
|
|
69
|
+
return (_jsx("div", { ...props, children: children }));
|
|
70
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { WorkspaceId } from '@deepseek-ai/dsh-client-runtime/client';
|
|
2
|
+
/** Which sidebar list an order belongs to; the two ledgers are independent. */
|
|
3
|
+
export type TeamSidebarListKind = 'channels' | 'agents';
|
|
4
|
+
/** Insert side of a drop relative to the row under the pointer. */
|
|
5
|
+
export type SidebarDropMarker = 'before' | 'after';
|
|
6
|
+
/**
|
|
7
|
+
* Merge the saved personal order into the current Remote order: kept refs
|
|
8
|
+
* stay in the user's relative order with duplicates collapsed, removed refs
|
|
9
|
+
* disappear, and new refs join in their Remote default positions after the
|
|
10
|
+
* known ones.
|
|
11
|
+
*/
|
|
12
|
+
export declare function reconcileSidebarOrder<R extends string>(saved: readonly string[], current: readonly R[]): readonly R[];
|
|
13
|
+
/**
|
|
14
|
+
* Effective row order for one sidebar list: the user's saved order folded
|
|
15
|
+
* into the given Remote default order. Identity-stable across renders while
|
|
16
|
+
* neither the data nor this browser's preference changes.
|
|
17
|
+
*/
|
|
18
|
+
export declare function useSidebarOrder<R extends string>(workspaceId: WorkspaceId | undefined, kind: TeamSidebarListKind, refs: readonly R[]): readonly R[];
|
|
19
|
+
/**
|
|
20
|
+
* The only mutation path: move `movedRef` to the given side of `targetRef`
|
|
21
|
+
* inside the list's current effective order. Returns the new order, or
|
|
22
|
+
* `undefined` when the request cannot change anything (unknown refs, dropping
|
|
23
|
+
* a row onto itself, or an adjacent marker that would put it right back).
|
|
24
|
+
* Persistence and subscriber notification happen here.
|
|
25
|
+
*/
|
|
26
|
+
export declare function moveSidebarItem<R extends string>(workspaceId: WorkspaceId | undefined, kind: TeamSidebarListKind, refs: readonly R[], movedRef: R, targetRef: R, marker: SidebarDropMarker): readonly R[] | undefined;
|
|
27
|
+
//# sourceMappingURL=sidebar-order.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidebar-order.d.ts","sourceRoot":"","sources":["../../../src/client/sidebar-order.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAA;AAEzE,+EAA+E;AAC/E,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,QAAQ,CAAA;AAEvD,mEAAmE;AACnE,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,OAAO,CAAA;AA2ElD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,GAAG,SAAS,CAAC,EAAE,CAerH;AAqCD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,SAAS,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,GAAG,SAAS,CAAC,EAAE,CAQnJ;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,EAC9C,WAAW,EAAE,WAAW,GAAG,SAAS,EACpC,IAAI,EAAE,mBAAmB,EACzB,IAAI,EAAE,SAAS,CAAC,EAAE,EAClB,QAAQ,EAAE,CAAC,EACX,SAAS,EAAE,CAAC,EACZ,MAAM,EAAE,iBAAiB,GACxB,SAAS,CAAC,EAAE,GAAG,SAAS,CAe1B"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human presentation preference for the Team sidebar: the row order of the
|
|
3
|
+
* Channels and Agents lists. The order lives in this browser only — it is UI
|
|
4
|
+
* taste, never a shared Team fact, so nothing here touches the ledger.
|
|
5
|
+
*
|
|
6
|
+
* One deep module owns the whole concern: storage, reconcile against the
|
|
7
|
+
* current Remote order (drop removed refs, keep the user's relative order,
|
|
8
|
+
* append newcomers in default order), the single `moveSidebarItem` mutation
|
|
9
|
+
* behind whole-row drag, and a small subscription hook with snapshot-stable
|
|
10
|
+
* results for `useSyncExternalStore`.
|
|
11
|
+
*/
|
|
12
|
+
import { useCallback, useSyncExternalStore } from 'react';
|
|
13
|
+
const STORAGE_KEY = 'dsh.agent-team.sidebar-order';
|
|
14
|
+
function listKey(workspaceId, kind) {
|
|
15
|
+
return workspaceId === undefined ? undefined : `${workspaceId}|${kind}`;
|
|
16
|
+
}
|
|
17
|
+
const MEMORY_ONLY = Symbol('sidebar-order.memory');
|
|
18
|
+
/**
|
|
19
|
+
* Read-through parse cache over the raw persisted payload: repeated snapshots
|
|
20
|
+
* skip re-validating an unchanged payload, while anything written outside this
|
|
21
|
+
* module — another tab, devtools, a cleared store — is picked up because the
|
|
22
|
+
* raw comparison misses.
|
|
23
|
+
*/
|
|
24
|
+
let cachedRaw;
|
|
25
|
+
let cachedOrders = {};
|
|
26
|
+
/**
|
|
27
|
+
* Parse persisted orders defensively: private mode, quota errors, and stale
|
|
28
|
+
* or corrupted payloads all degrade to "no preference" instead of breaking
|
|
29
|
+
* the sidebar.
|
|
30
|
+
*/
|
|
31
|
+
function storedOrders() {
|
|
32
|
+
let raw = null;
|
|
33
|
+
try {
|
|
34
|
+
raw = typeof localStorage === 'undefined' ? null : localStorage.getItem(STORAGE_KEY);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
raw = null;
|
|
38
|
+
}
|
|
39
|
+
if (cachedRaw !== undefined && raw !== null && raw === cachedRaw)
|
|
40
|
+
return cachedOrders;
|
|
41
|
+
if (raw === null) {
|
|
42
|
+
if (cachedRaw === MEMORY_ONLY)
|
|
43
|
+
return cachedOrders;
|
|
44
|
+
cachedRaw = raw;
|
|
45
|
+
cachedOrders = {};
|
|
46
|
+
return cachedOrders;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const parsed = JSON.parse(raw);
|
|
50
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
51
|
+
throw new Error('not an object');
|
|
52
|
+
const clean = {};
|
|
53
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
54
|
+
if (!Array.isArray(value) || !value.every(entry => typeof entry === 'string'))
|
|
55
|
+
continue;
|
|
56
|
+
clean[key] = value;
|
|
57
|
+
}
|
|
58
|
+
cachedRaw = raw;
|
|
59
|
+
cachedOrders = clean;
|
|
60
|
+
return cachedOrders;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return {};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function saveOrder(key, refs) {
|
|
67
|
+
const next = { ...structuredClone(storedOrders()), [key]: refs };
|
|
68
|
+
cachedOrders = next;
|
|
69
|
+
try {
|
|
70
|
+
if (typeof localStorage !== 'undefined') {
|
|
71
|
+
const raw = JSON.stringify(next);
|
|
72
|
+
localStorage.setItem(STORAGE_KEY, raw);
|
|
73
|
+
cachedRaw = raw;
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// Private mode and quota failures do not block reordering; the session
|
|
79
|
+
// keeps serving the in-memory order below.
|
|
80
|
+
}
|
|
81
|
+
cachedRaw = MEMORY_ONLY;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Merge the saved personal order into the current Remote order: kept refs
|
|
85
|
+
* stay in the user's relative order with duplicates collapsed, removed refs
|
|
86
|
+
* disappear, and new refs join in their Remote default positions after the
|
|
87
|
+
* known ones.
|
|
88
|
+
*/
|
|
89
|
+
export function reconcileSidebarOrder(saved, current) {
|
|
90
|
+
const present = new Set(current);
|
|
91
|
+
const seen = new Set();
|
|
92
|
+
const merged = [];
|
|
93
|
+
for (const ref of saved) {
|
|
94
|
+
if (seen.has(ref) || !present.has(ref))
|
|
95
|
+
continue;
|
|
96
|
+
seen.add(ref);
|
|
97
|
+
merged.push(ref);
|
|
98
|
+
}
|
|
99
|
+
for (const ref of current) {
|
|
100
|
+
if (seen.has(ref))
|
|
101
|
+
continue;
|
|
102
|
+
seen.add(ref);
|
|
103
|
+
merged.push(ref);
|
|
104
|
+
}
|
|
105
|
+
return merged;
|
|
106
|
+
}
|
|
107
|
+
let revision = 0;
|
|
108
|
+
const listeners = new Set();
|
|
109
|
+
const snapshots = new Map();
|
|
110
|
+
function savedFingerprint(key) {
|
|
111
|
+
const saved = storedOrders()[key];
|
|
112
|
+
return saved === undefined ? '' : `f${saved.length}:${saved.join(',')}`;
|
|
113
|
+
}
|
|
114
|
+
function emitChange() {
|
|
115
|
+
revision += 1;
|
|
116
|
+
for (const listener of listeners)
|
|
117
|
+
listener();
|
|
118
|
+
}
|
|
119
|
+
function orderedSnapshot(workspaceId, kind, refs) {
|
|
120
|
+
const key = listKey(workspaceId, kind);
|
|
121
|
+
if (key === undefined)
|
|
122
|
+
return refs;
|
|
123
|
+
const signature = refs.join('\u0000');
|
|
124
|
+
const fingerprint = savedFingerprint(key);
|
|
125
|
+
const hit = snapshots.get(key);
|
|
126
|
+
if (hit !== undefined && hit.atRevision === revision && hit.signature === signature && hit.savedFingerprint === fingerprint) {
|
|
127
|
+
return hit.result;
|
|
128
|
+
}
|
|
129
|
+
const result = reconcileSidebarOrder(storedOrders()[key] ?? [], refs);
|
|
130
|
+
snapshots.set(key, { atRevision: revision, signature, savedFingerprint: fingerprint, result });
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Effective row order for one sidebar list: the user's saved order folded
|
|
135
|
+
* into the given Remote default order. Identity-stable across renders while
|
|
136
|
+
* neither the data nor this browser's preference changes.
|
|
137
|
+
*/
|
|
138
|
+
export function useSidebarOrder(workspaceId, kind, refs) {
|
|
139
|
+
const subscribe = useCallback((listener) => {
|
|
140
|
+
listeners.add(listener);
|
|
141
|
+
return () => { listeners.delete(listener); };
|
|
142
|
+
}, []);
|
|
143
|
+
return useSyncExternalStore(subscribe, () => orderedSnapshot(workspaceId, kind, refs), () => orderedSnapshot(workspaceId, kind, refs));
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* The only mutation path: move `movedRef` to the given side of `targetRef`
|
|
147
|
+
* inside the list's current effective order. Returns the new order, or
|
|
148
|
+
* `undefined` when the request cannot change anything (unknown refs, dropping
|
|
149
|
+
* a row onto itself, or an adjacent marker that would put it right back).
|
|
150
|
+
* Persistence and subscriber notification happen here.
|
|
151
|
+
*/
|
|
152
|
+
export function moveSidebarItem(workspaceId, kind, refs, movedRef, targetRef, marker) {
|
|
153
|
+
const key = listKey(workspaceId, kind);
|
|
154
|
+
const from = refs.indexOf(movedRef);
|
|
155
|
+
const nextFromTarget = refs.indexOf(targetRef);
|
|
156
|
+
if (key === undefined || from < 0 || nextFromTarget < 0 || movedRef === targetRef)
|
|
157
|
+
return undefined;
|
|
158
|
+
const next = [...refs];
|
|
159
|
+
const [item] = next.splice(from, 1);
|
|
160
|
+
if (item === undefined)
|
|
161
|
+
return undefined;
|
|
162
|
+
const insertAt = next.indexOf(targetRef) + (marker === 'after' ? 1 : 0);
|
|
163
|
+
if (insertAt === from)
|
|
164
|
+
return undefined;
|
|
165
|
+
next.splice(insertAt, 0, item);
|
|
166
|
+
saveOrder(key, next);
|
|
167
|
+
snapshots.delete(key);
|
|
168
|
+
emitChange();
|
|
169
|
+
return next;
|
|
170
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
-
import type { AgentTeamAddMemberRequest, AgentTeamChannelRef, AgentTeamClientMemberStatus, AgentTeamCreateChannelRequest, AgentTeamCreateChannelResult, AgentTeamJoinChannelRequest, AgentTeamJoinChannelResult, AgentTeamGetAttachmentRequest, AgentTeamGetAttachmentResult, AgentTeamPutAttachmentRequest, AgentTeamPutAttachmentResult, AgentTeamMemberResult, AgentTeamRecoverMemberRequest, AgentTeamRecoverMemberResult,
|
|
2
|
+
import type { AgentTeamAddMemberRequest, AgentTeamChannelRef, AgentTeamClientMemberStatus, AgentTeamCreateChannelRequest, AgentTeamCreateChannelResult, AgentTeamJoinChannelRequest, AgentTeamJoinChannelResult, AgentTeamGetAttachmentRequest, AgentTeamGetAttachmentResult, AgentTeamPutAttachmentRequest, AgentTeamPutAttachmentResult, AgentTeamMemberResult, AgentTeamRecoverMemberRequest, AgentTeamRecoverMemberResult, AgentTeamMembersRequest, AgentTeamRemoveChannelMemberRequest, AgentTeamRemoveChannelMemberResult, AgentTeamReplyRequest, AgentTeamResolveTaskRefsRequest, AgentTeamResolveTaskRefsResult, AgentTeamReplyResult, AgentTeamConfirmationRequired, AgentTeamThreadHistory, AgentTeamThreadHistoryRequest, AgentTeamThreadReadRequest, AgentTeamThreadReadResult, AgentTeamTaskRequest, AgentTeamTaskResult, AgentTeamSendMessageRequest, AgentTeamSendMessageResult, AgentTeamUpdateChannelRequest, AgentTeamUpdateChannelResult, AgentTeamUpdateMemberRequest, AgentTeamView, AgentTeamViewRequest } from '@wowyuarm/dsh-agent-team/types';
|
|
3
3
|
import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
|
|
4
4
|
import type { TeamNavigationActions, TeamNavigationSnapshot } from './navigation.ts';
|
|
5
5
|
import type { TeamChangeListener, TeamChangeScope } from './team-changes.ts';
|
|
@@ -49,7 +49,6 @@ export type TeamSidebarProps = PropsRuntime<'sidebar.workspaces'> & PropsLocale<
|
|
|
49
49
|
updateChannel: (request: AgentTeamUpdateChannelRequest) => Promise<RemoteResult<AgentTeamUpdateChannelResult>>;
|
|
50
50
|
updateMember: (request: AgentTeamUpdateMemberRequest) => Promise<RemoteResult<AgentTeamMemberResult>>;
|
|
51
51
|
recoverMember: (request: AgentTeamRecoverMemberRequest) => Promise<RemoteResult<AgentTeamRecoverMemberResult>>;
|
|
52
|
-
restartMember: (request: AgentTeamRestartMemberRequest) => Promise<RemoteResult<AgentTeamRestartMemberResult>>;
|
|
53
52
|
joinChannel: (request: AgentTeamJoinChannelRequest) => Promise<RemoteResult<AgentTeamJoinChannelResult>>;
|
|
54
53
|
removeChannelMember: (request: AgentTeamRemoveChannelMemberRequest) => Promise<RemoteResult<AgentTeamRemoveChannelMemberResult>>;
|
|
55
54
|
/** Session-independent Host model catalog (`llm.models`); needs no live Member. */
|
|
@@ -73,6 +72,7 @@ export type TeamConversationProps = PropsRuntime<'conversation'> & PropsLocale<'
|
|
|
73
72
|
removeChannelMember: (request: AgentTeamRemoveChannelMemberRequest) => Promise<RemoteResult<AgentTeamRemoveChannelMemberResult>>;
|
|
74
73
|
reply: (request: AgentTeamReplyRequest) => Promise<RemoteResult<AgentTeamReplyResult | AgentTeamConfirmationRequired>>;
|
|
75
74
|
changeTask: (request: AgentTeamTaskRequest) => Promise<RemoteResult<AgentTeamTaskResult>>;
|
|
75
|
+
resolveTaskRefs: (request: AgentTeamResolveTaskRefsRequest) => Promise<RemoteResult<AgentTeamResolveTaskRefsResult>>;
|
|
76
76
|
loadMembers: (request: AgentTeamMembersRequest) => Promise<RemoteResult<readonly AgentTeamClientMemberStatus[]>>;
|
|
77
77
|
};
|
|
78
78
|
export type TeamSettingsProps = PropsRuntime<'sidebar.settings'> & PropsLocale<'team'> & {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slots.d.ts","sourceRoot":"","sources":["../../../src/client/slots.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACjF,OAAO,KAAK,EACV,yBAAyB,EACzB,mBAAmB,EACnB,2BAA2B,EAC3B,6BAA6B,EAC7B,4BAA4B,EAC5B,2BAA2B,EAC3B,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC5B,6BAA6B,EAC7B,4BAA4B,EAC5B,qBAAqB,EACrB,6BAA6B,EAC7B,4BAA4B,EAC5B,
|
|
1
|
+
{"version":3,"file":"slots.d.ts","sourceRoot":"","sources":["../../../src/client/slots.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
|
|
2
|
+
import type { AgentTeamChannelRef, AgentTeamResolveTaskRefsRequest, AgentTeamResolveTaskRefsResult, AgentTeamTaskRef, AgentTeamThreadRef } from '@wowyuarm/dsh-agent-team/types';
|
|
3
|
+
/** Navigation facts for one branded Task ref, resolved once per session. */
|
|
4
|
+
export interface ResolvedTaskRef {
|
|
5
|
+
readonly taskRef: AgentTeamTaskRef;
|
|
6
|
+
readonly channelRef: AgentTeamChannelRef;
|
|
7
|
+
readonly threadRef: AgentTeamThreadRef;
|
|
8
|
+
readonly taskNumber: number;
|
|
9
|
+
}
|
|
10
|
+
/** React binding: re-renders the caller when any ref resolution lands. */
|
|
11
|
+
export declare const useResolvedTaskRefVersion: () => number;
|
|
12
|
+
export declare const cachedResolvedTaskRef: (taskRef: AgentTeamTaskRef) => ResolvedTaskRef | undefined;
|
|
13
|
+
/** Store one resolution (click path) and wake every rendered link. */
|
|
14
|
+
export declare const rememberResolvedTaskRef: (entry: ResolvedTaskRef) => void;
|
|
15
|
+
/** Click-path Host lookup: remember every resolved entry and hand them back for immediate navigation. */
|
|
16
|
+
export declare const hostTaskRefLookup: (resolveTaskRefs: (request: AgentTeamResolveTaskRefsRequest) => Promise<RemoteResult<AgentTeamResolveTaskRefsResult>>, workspaceId: AgentTeamResolveTaskRefsRequest["workspaceId"]) => ((taskRefs: readonly AgentTeamTaskRef[]) => Promise<readonly ResolvedTaskRef[]>);
|
|
17
|
+
/** Resolve one Task ref through the Host and jump to its home Channel Thread. */
|
|
18
|
+
export declare const jumpToTaskThread: (resolveTaskRefs: (request: AgentTeamResolveTaskRefsRequest) => Promise<RemoteResult<AgentTeamResolveTaskRefsResult>>, workspaceId: AgentTeamResolveTaskRefsRequest["workspaceId"], taskRef: AgentTeamTaskRef, selectThread: (taskRef: AgentTeamTaskRef, threadRef: AgentTeamThreadRef, channelRef: AgentTeamChannelRef, taskNumber: number) => void) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Batch-resolve unknown refs through the Host lookup. Concurrent callers
|
|
21
|
+
* deduplicate through the pending set; failures just clear the pending mark
|
|
22
|
+
* so a later interaction can retry.
|
|
23
|
+
*/
|
|
24
|
+
export declare const resolveUnknownTaskRefs: (refs: readonly AgentTeamTaskRef[], lookup: (taskRefs: readonly AgentTeamTaskRef[]) => Promise<readonly ResolvedTaskRef[]>) => Promise<void>;
|
|
25
|
+
//# sourceMappingURL=task-refs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-refs.d.ts","sourceRoot":"","sources":["../../../src/client/task-refs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACpE,OAAO,KAAK,EACV,mBAAmB,EAAE,+BAA+B,EAAE,8BAA8B,EAAE,gBAAgB,EAAE,kBAAkB,EAC3H,MAAM,gCAAgC,CAAA;AAEvC,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAA;IAClC,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAA;IACxC,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAA;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAwBD,0EAA0E;AAC1E,eAAO,MAAM,yBAAyB,QAAO,MAAmE,CAAA;AAEhH,eAAO,MAAM,qBAAqB,GAAI,SAAS,gBAAgB,KAAG,eAAe,GAAG,SAAkC,CAAA;AAEtH,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,GAAI,OAAO,eAAe,KAAG,IAIhE,CAAA;AAED,yGAAyG;AACzG,eAAO,MAAM,iBAAiB,GAC5B,iBAAiB,CAAC,OAAO,EAAE,+BAA+B,KAAK,OAAO,CAAC,YAAY,CAAC,8BAA8B,CAAC,CAAC,EACpH,aAAa,+BAA+B,CAAC,aAAa,CAAC,KAC1D,CAAC,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,KAAK,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC,CAM/E,CAAA;AAEH,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,GAC3B,iBAAiB,CAAC,OAAO,EAAE,+BAA+B,KAAK,OAAO,CAAC,YAAY,CAAC,8BAA8B,CAAC,CAAC,EACpH,aAAa,+BAA+B,CAAC,aAAa,CAAC,EAC3D,SAAS,gBAAgB,EACzB,cAAc,CAAC,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,kBAAkB,EAAE,UAAU,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,KACpI,IAMF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GACjC,MAAM,SAAS,gBAAgB,EAAE,EACjC,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,KAAK,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC,KACrF,OAAO,CAAC,IAAI,CAmBd,CAAA"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { useSyncExternalStore } from 'react';
|
|
2
|
+
const resolved = new Map();
|
|
3
|
+
const pending = new Set();
|
|
4
|
+
/** Refs the Host did not recognize; never re-queried (no retry loops). */
|
|
5
|
+
const unresolvable = new Set();
|
|
6
|
+
const listeners = new Set();
|
|
7
|
+
let version = 0;
|
|
8
|
+
const emit = () => {
|
|
9
|
+
version += 1;
|
|
10
|
+
for (const listener of listeners)
|
|
11
|
+
listener();
|
|
12
|
+
};
|
|
13
|
+
const subscribe = (listener) => {
|
|
14
|
+
listeners.add(listener);
|
|
15
|
+
return () => { listeners.delete(listener); };
|
|
16
|
+
};
|
|
17
|
+
/** Stable snapshot token; the map is read directly after this changes. */
|
|
18
|
+
const getSnapshot = () => version;
|
|
19
|
+
/** React binding: re-renders the caller when any ref resolution lands. */
|
|
20
|
+
export const useResolvedTaskRefVersion = () => useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
21
|
+
export const cachedResolvedTaskRef = (taskRef) => resolved.get(taskRef);
|
|
22
|
+
/** Store one resolution (click path) and wake every rendered link. */
|
|
23
|
+
export const rememberResolvedTaskRef = (entry) => {
|
|
24
|
+
resolved.set(entry.taskRef, entry);
|
|
25
|
+
pending.delete(entry.taskRef);
|
|
26
|
+
emit();
|
|
27
|
+
};
|
|
28
|
+
/** Click-path Host lookup: remember every resolved entry and hand them back for immediate navigation. */
|
|
29
|
+
export const hostTaskRefLookup = (resolveTaskRefs, workspaceId) => async (taskRefs) => {
|
|
30
|
+
const result = await resolveTaskRefs({ workspaceId, taskRefs });
|
|
31
|
+
if (!result.ok)
|
|
32
|
+
return [];
|
|
33
|
+
for (const entry of result.value.resolved)
|
|
34
|
+
rememberResolvedTaskRef(entry);
|
|
35
|
+
return result.value.resolved;
|
|
36
|
+
};
|
|
37
|
+
/** Resolve one Task ref through the Host and jump to its home Channel Thread. */
|
|
38
|
+
export const jumpToTaskThread = (resolveTaskRefs, workspaceId, taskRef, selectThread) => {
|
|
39
|
+
void resolveTaskRefs({ workspaceId, taskRefs: [taskRef] }).then(result => {
|
|
40
|
+
if (!result.ok)
|
|
41
|
+
return;
|
|
42
|
+
const hit = result.value.resolved[0];
|
|
43
|
+
if (hit !== undefined)
|
|
44
|
+
selectThread(hit.taskRef, hit.threadRef, hit.channelRef, hit.taskNumber);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Batch-resolve unknown refs through the Host lookup. Concurrent callers
|
|
49
|
+
* deduplicate through the pending set; failures just clear the pending mark
|
|
50
|
+
* so a later interaction can retry.
|
|
51
|
+
*/
|
|
52
|
+
export const resolveUnknownTaskRefs = async (refs, lookup) => {
|
|
53
|
+
const missing = refs.filter(taskRef => !resolved.has(taskRef) && !pending.has(taskRef) && !unresolvable.has(taskRef));
|
|
54
|
+
if (missing.length === 0)
|
|
55
|
+
return;
|
|
56
|
+
for (const taskRef of missing)
|
|
57
|
+
pending.add(taskRef);
|
|
58
|
+
try {
|
|
59
|
+
const entries = await lookup(missing);
|
|
60
|
+
for (const entry of entries) {
|
|
61
|
+
resolved.set(entry.taskRef, entry);
|
|
62
|
+
pending.delete(entry.taskRef);
|
|
63
|
+
}
|
|
64
|
+
// Refs the Host does not know are parked for the session: re-querying
|
|
65
|
+
// them on every render would loop and hammer the Host.
|
|
66
|
+
for (const taskRef of missing) {
|
|
67
|
+
if (!resolved.has(taskRef))
|
|
68
|
+
unresolvable.add(taskRef);
|
|
69
|
+
}
|
|
70
|
+
if (entries.length > 0)
|
|
71
|
+
emit();
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
for (const taskRef of missing)
|
|
75
|
+
pending.delete(taskRef);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentTeamActivity, AgentTeamClaim, AgentTeamMemberId, AgentTeamTask } from '@wowyuarm/dsh-agent-team/types';
|
|
1
|
+
import type { AgentTeamActivity, AgentTeamClaim, AgentTeamMemberId, AgentTeamTask, AgentTeamTaskRef } from '@wowyuarm/dsh-agent-team/types';
|
|
2
2
|
import type { TeamConversationProps } from './slots.ts';
|
|
3
3
|
export declare function formatTaskStatus(status: AgentTeamTask['status'], t: TeamConversationProps['t']): string;
|
|
4
4
|
export declare function formatClaimState(state: AgentTeamClaim['state'], t: TeamConversationProps['t']): string;
|
|
@@ -13,6 +13,27 @@ export declare function taskStatusDot(status: AgentTeamTask['status']): 'ongoing
|
|
|
13
13
|
export declare function formatTaskTitle(body: string): string;
|
|
14
14
|
/** Deterministic avatar hue for one Member identity; stable across sessions and themes. */
|
|
15
15
|
export declare function memberHue(memberId: string): number;
|
|
16
|
+
/** One branded-ref occurrence inside a literal body segment. */
|
|
17
|
+
export interface RefSegment {
|
|
18
|
+
readonly text: string;
|
|
19
|
+
/** The full `task:`/`channel:`/`thread:` ref when this segment is a link. */
|
|
20
|
+
readonly ref?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Split a literal text run into plain and branded-ref segments. The pattern
|
|
24
|
+
* anchors on the fixed ref prefixes plus the UUID shape, so ordinary prose
|
|
25
|
+
* containing a colon never linkifies; a doubled colon from model output is
|
|
26
|
+
* tolerated. Segment refs are always canonical, so resolution and navigation
|
|
27
|
+
* work regardless of how the ref was spelled; text without any ref comes
|
|
28
|
+
* back as one untouched segment.
|
|
29
|
+
*/
|
|
30
|
+
export declare function splitBrandedRefs(text: string): readonly RefSegment[];
|
|
31
|
+
/**
|
|
32
|
+
* Whether one string's whole content is exactly one branded ref. A code span
|
|
33
|
+
* like this is the model styling a ref as an identifier, not publishing code,
|
|
34
|
+
* so the Markdown pass may linkify it; anything larger stays literal.
|
|
35
|
+
*/
|
|
36
|
+
export declare function isSingleBrandedRef(text: string): boolean;
|
|
16
37
|
export interface MentionSegment {
|
|
17
38
|
readonly text: string;
|
|
18
39
|
readonly mention: boolean;
|
|
@@ -52,4 +73,36 @@ export declare function formatActivity(activity: AgentTeamActivity, options: {
|
|
|
52
73
|
}): string;
|
|
53
74
|
/** Remove the machine-facing `[attachment] <path>` prompt lines from a body before display. */
|
|
54
75
|
export declare function stripAttachmentLines(body: string): string;
|
|
76
|
+
/** How one Message body renders: mention-chip segments, literal text, or Markdown. */
|
|
77
|
+
export type MessageBodyRender = 'inline' | 'literal' | 'markdown';
|
|
78
|
+
/** Rendering decision for one Message body, resolved once from its stored form. */
|
|
79
|
+
export interface PlannedMessageBody {
|
|
80
|
+
/** Stored body without machine-facing attachment prompt lines; the raw body when stripping would empty it. */
|
|
81
|
+
readonly displayBody: string;
|
|
82
|
+
/** Rich Agent Markdown: only such bodies get the post-render chipify pass. */
|
|
83
|
+
readonly richAgentBody: boolean;
|
|
84
|
+
/** Which rendering branch the body takes. */
|
|
85
|
+
readonly render: MessageBodyRender;
|
|
86
|
+
/** Mention-chip segments for literal bodies; absent on the Markdown branch. */
|
|
87
|
+
readonly inline?: ReturnType<typeof splitMentionNames>;
|
|
88
|
+
/** Mention handles that did not render as chips; the trailing row shows them. */
|
|
89
|
+
readonly fallbackNames: readonly string[];
|
|
90
|
+
/** Non-Task branded refs for the trailing fallback row; rich Agent bodies keep the legacy row. */
|
|
91
|
+
readonly fallbackRefs: readonly string[];
|
|
92
|
+
/** Task refs authored in a literal body; resolved labels replace them in place. */
|
|
93
|
+
readonly taskRefs: readonly AgentTeamTaskRef[];
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Decide how one Message body renders. Human input and plain-prose Agent
|
|
97
|
+
* bodies stay literal, with structured mention chips inline where possible;
|
|
98
|
+
* rich Agent Markdown keeps unmatched mentions and non-Task refs in the
|
|
99
|
+
* trailing fallback row while the post-render pass handles Task refs at their
|
|
100
|
+
* authored position. Surfaces without ref navigation render everything
|
|
101
|
+
* literally and keep the full fallback row.
|
|
102
|
+
*/
|
|
103
|
+
export declare function planMessageBody(body: string, options: {
|
|
104
|
+
readonly human: boolean;
|
|
105
|
+
readonly mentionNames?: readonly string[];
|
|
106
|
+
readonly canOpenRefs: boolean;
|
|
107
|
+
}): PlannedMessageBody;
|
|
55
108
|
//# sourceMappingURL=team-formatters.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-formatters.d.ts","sourceRoot":"","sources":["../../../src/client/team-formatters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;
|
|
1
|
+
{"version":3,"file":"team-formatters.d.ts","sourceRoot":"","sources":["../../../src/client/team-formatters.ts"],"names":[],"mappings":"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"}
|