@nanmicoder/dsh-agent-teams 0.1.20 → 0.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +19 -12
  2. package/README_ZH.md +19 -12
  3. package/assets/readme/workspace.png +0 -0
  4. package/compatibility.json +14 -2
  5. package/lib/capabilities.js +3 -1
  6. package/lib/client/ActivityPanel.js +80 -51
  7. package/lib/client/AgentTeamsCard.js +14 -5
  8. package/lib/client/TeamChatEntry.js +22 -0
  9. package/lib/client/WorkspaceActivity.js +100 -0
  10. package/lib/client/activity-model.js +73 -8
  11. package/lib/client/activity-monitor.js +11 -4
  12. package/lib/client/agent-teams-card-definition.js +11 -1
  13. package/lib/client/icons.js +18 -0
  14. package/lib/client/index.js +35 -4
  15. package/lib/client/locales.js +44 -0
  16. package/lib/client/session-navigation.js +13 -1
  17. package/lib/client/workspace-state.js +43 -0
  18. package/lib/client.js +832 -210
  19. package/lib/client.js.map +1 -1
  20. package/lib/harness-compat.js +20 -3
  21. package/lib/index.js +1 -1
  22. package/lib/mailbox.js +23 -3
  23. package/lib/members.js +3 -3
  24. package/lib/quality-gates.js +54 -0
  25. package/lib/scheduler.js +8 -2
  26. package/lib/snapshot.js +1 -0
  27. package/lib/state.js +15 -3
  28. package/lib/tools.js +71 -22
  29. package/lib/types/capabilities.d.ts +0 -1
  30. package/lib/types/client/ActivityPanel.d.ts +18 -1
  31. package/lib/types/client/AgentTeamsCard.d.ts +14 -2
  32. package/lib/types/client/TeamChatEntry.d.ts +4 -0
  33. package/lib/types/client/WorkspaceActivity.d.ts +22 -0
  34. package/lib/types/client/activity-model.d.ts +37 -1
  35. package/lib/types/client/activity-monitor.d.ts +4 -0
  36. package/lib/types/client/agent-teams-card-definition.d.ts +8 -0
  37. package/lib/types/client/icons.d.ts +5 -0
  38. package/lib/types/client/locales.d.ts +44 -0
  39. package/lib/types/client/session-navigation.d.ts +13 -2
  40. package/lib/types/client/workspace-state.d.ts +19 -0
  41. package/lib/types/harness-compat.d.ts +14 -1
  42. package/lib/types/mailbox.d.ts +4 -0
  43. package/lib/types/quality-gates.d.ts +7 -1
  44. package/lib/types/scheduler.d.ts +1 -0
  45. package/lib/types/snapshot.d.ts +2 -0
  46. package/lib/types/types.d.ts +16 -0
  47. package/package.json +53 -50
  48. package/release-notes/v0.1.21-rc.1.md +14 -0
  49. package/release-notes/v0.1.21.md +23 -0
@@ -11,13 +11,25 @@
11
11
  */
12
12
  import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
13
13
  import type { SessionId } from '@deepseek-ai/dsh-session/types';
14
+ import type { AgentTeamsCardData } from './agent-teams-card-definition.ts';
14
15
  /** Window event name the floater listens for to open itself. */
15
16
  export declare const OPEN_PANEL_EVENT = "agent-teams:open-panel";
16
17
  /** Navigation action injected from the plugin's own SessionsService access. */
17
18
  export interface AgentTeamsCardInjected {
19
+ readonly workspaceBridge?: {
20
+ getSnapshot: () => unknown;
21
+ subscribe: (listener: () => void) => () => void;
22
+ };
18
23
  readonly openMember: (parentId: SessionId, childId: SessionId) => void;
19
24
  }
20
25
  /** Complete keyed Chat renderer props. */
21
26
  export type AgentTeamsCardProps = PropsRuntime<'conversation.chat.node', 'agent-teams'> & PropsLocale<'agentTeams'> & AgentTeamsCardInjected;
22
- /** Render one durable team as a compact conversation card. */
23
- export declare function AgentTeamsCard({ node, openMember, sessionId, t }: AgentTeamsCardProps): import("react").JSX.Element;
27
+ /** Open the matching team view, carrying this team's summary
28
+ * so the panel can show it even when the team no longer exists on disk
29
+ * (historical session review). */
30
+ export declare function openActivityPanel(data: AgentTeamsCardData): void;
31
+ export declare function AgentTeamsCard({ node, openMember, sessionId, t, workspaceBridge }: AgentTeamsCardProps): import("react").JSX.Element | null;
32
+ export declare function AgentTeamsSummary({ data, openMember, sessionId, t }: AgentTeamsCardInjected & PropsLocale<'agentTeams'> & {
33
+ data: AgentTeamsCardData;
34
+ sessionId: string;
35
+ }): import("react").JSX.Element;
@@ -0,0 +1,4 @@
1
+ import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
2
+ import { type AgentTeamsCardInjected } from './AgentTeamsCard.tsx';
3
+ export declare function TeamChatEntry({ sessionId, t }: PropsRuntime<'conversation.session.header.actions'> & PropsLocale<'agentTeams'>): import("react").JSX.Element | null;
4
+ export declare function TeamTurnCard({ sessionId, turn, useChat, t, openMember }: PropsRuntime<'conversation.chat.turnTail'> & PropsLocale<'agentTeams'> & AgentTeamsCardInjected): import("react").JSX.Element | null;
@@ -0,0 +1,22 @@
1
+ import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
2
+ import type { ISidebarRight } from '@deepseek-ai/dsh-client-ui-sidebar-right/client';
3
+ import { type ActivityPanelProps } from './ActivityPanel.tsx';
4
+ import { type WorkspaceActivityState } from './workspace-state.ts';
5
+ export declare const TEAM_TAB_KIND = "agent-teams";
6
+ export declare const TEAM_TAB_ID = "@nanmicoder/dsh-agent-teams/activity";
7
+ /** Optional host integration is observable so installing/removing it also switches the fallback. */
8
+ export declare function createWorkspaceBridge(): {
9
+ getSnapshot: () => ISidebarRight | undefined;
10
+ subscribe: (listener: () => void) => () => void;
11
+ set(value: ISidebarRight | undefined): void;
12
+ };
13
+ export declare function ActivitySurface({ bridge, state, ...props }: ActivityPanelProps & {
14
+ bridge: ReturnType<typeof createWorkspaceBridge>;
15
+ state: WorkspaceActivityState;
16
+ }): import("react").JSX.Element;
17
+ export type WorkspaceActivityProps = PropsRuntime<'sidebar.right.pane.tab'> & PropsLocale<'agentTeams'> & {
18
+ state: WorkspaceActivityState;
19
+ modelDirectories: ActivityPanelProps['modelDirectories'];
20
+ openMember: ActivityPanelProps['openMember'];
21
+ };
22
+ export declare function WorkspaceActivity({ sessionId, useTabInfo, t, state, modelDirectories, openMember }: WorkspaceActivityProps): import("react").JSX.Element;
@@ -58,6 +58,37 @@ export declare function liveCaptainTeam<T extends {
58
58
  readonly captainSessionId: string;
59
59
  readonly halted?: boolean;
60
60
  }>(teams: readonly T[], sessionId: string | undefined): T | undefined;
61
+ /** Minimal member shape needed to order the delegation list (issue #192). */
62
+ export interface MemberListEntry {
63
+ readonly name: string;
64
+ readonly activity?: string;
65
+ readonly status?: string;
66
+ }
67
+ /** Minimal task shape needed to derive a member's finish time (issue #192). */
68
+ export interface MemberFinishTask {
69
+ readonly assignee: string;
70
+ readonly status: string;
71
+ readonly updatedAt?: number;
72
+ }
73
+ /**
74
+ * Latest terminal-task `updatedAt` owned by one member.
75
+ * @param memberName - member whose owned tasks are scanned.
76
+ * @param tasks - team tasks carrying durable `updatedAt` stamps.
77
+ * @returns the newest terminal stamp, or undefined when the member owns none.
78
+ */
79
+ export declare function memberFinishedAt(memberName: string, tasks: readonly MemberFinishTask[]): number | undefined;
80
+ /**
81
+ * Order the delegation member list for issue #192.
82
+ *
83
+ * Running members keep their incoming relative order and come first; finished
84
+ * members follow sorted by finish time, newest first. Members without a
85
+ * derivable finish time keep their incoming relative order after the stamped
86
+ * ones, so an older host that omits stamps never reorders them randomly.
87
+ * @param members - delegation roster in snapshot order.
88
+ * @param tasks - team tasks carrying durable `updatedAt` stamps.
89
+ * @returns the members in display order.
90
+ */
91
+ export declare function orderDelegationMembers<TMember extends MemberListEntry>(members: readonly TMember[], tasks: readonly MemberFinishTask[]): readonly TMember[];
61
92
  /** Whether the captain chat should keep showing the in-progress banner. */
62
93
  export declare function teamIsActive(team: {
63
94
  readonly phase?: string;
@@ -129,7 +160,12 @@ export declare function taskStages<T extends RelationshipTask>(tasks: readonly T
129
160
  * each stage. Edges use cubic curves so fan-in remains readable without
130
161
  * turning every task into a large card.
131
162
  */
132
- export declare function compactDagLayout<T extends RelationshipTask>(tasks: readonly T[]): CompactDagLayout<T>;
163
+ export declare function compactDagLayout<T extends RelationshipTask>(tasks: readonly T[], dimensions?: {
164
+ readonly nodeWidth: number;
165
+ readonly nodeHeight: number;
166
+ readonly columnGap: number;
167
+ readonly rowGap: number;
168
+ }): CompactDagLayout<T>;
133
169
  /**
134
170
  * Return the complete upstream/downstream chain around one task.
135
171
  *
@@ -30,6 +30,8 @@ export interface ActivityTask {
30
30
  readonly kind?: string;
31
31
  readonly round?: number;
32
32
  readonly verdict?: string;
33
+ /** Durable last-write stamp; drives the finished-member ordering (issue #192). */
34
+ readonly updatedAt?: number;
33
35
  }
34
36
  /** One captain-inbox preview row. */
35
37
  export interface ActivityMessage {
@@ -99,6 +101,8 @@ interface ActivityFetchResponse {
99
101
  }
100
102
  /** Injectable browser primitives used by the poll controller and its tests. */
101
103
  export interface ActivityPollingRuntime {
104
+ /** Connection health for views; never clears the last successful snapshot. */
105
+ readonly onStatus?: (status: 'ready' | 'error') => void;
102
106
  /**
103
107
  * Current captain session to discover after a cold client/host restart.
104
108
  * This one-time scope restores teams whose older conversation log has no
@@ -11,6 +11,7 @@
11
11
  * @module dsh-agent-teams/client/card
12
12
  */
13
13
  import type { ConversationNodeDefinition } from '@deepseek-ai/dsh-client-ui-conversation/client';
14
+ import type { ChatConversationViewNode } from '@deepseek-ai/dsh-client-ui-chat/client';
14
15
  /** Final keyed Chat payload for the team summary card. */
15
16
  export interface AgentTeamsCardData {
16
17
  readonly teamId: string;
@@ -42,3 +43,10 @@ export declare function parseAgentTeamsCreateArgs(value: string): {
42
43
  } | undefined;
43
44
  /** Durable first-party tool events folded into one keyed Chat node. */
44
45
  export declare const agentTeamsCardDefinition: ConversationNodeDefinition<AgentTeamsNodeState>;
46
+ /** V4 tool-role results carry isError directly; older logs nest tool-result blocks. */
47
+ export declare function toolResultFailed(message: {
48
+ readonly content: readonly unknown[];
49
+ readonly isError?: boolean;
50
+ }): boolean;
51
+ /** Keep summaries tied to the create turn, including multiple teams in one turn. */
52
+ export declare function teamCardsForTurn(nodes: Iterable<ChatConversationViewNode>, turn: number): ChatConversationViewNode[];
@@ -0,0 +1,5 @@
1
+ export declare function IconBranchOutline16(): import("react").JSX.Element;
2
+ export declare function IconChevronDownOutline14(): import("react").JSX.Element;
3
+ export declare function IconPanelLeftOutline16(): import("react").JSX.Element;
4
+ export declare function IconStopFill16(): import("react").JSX.Element;
5
+ export declare function IconWarningOutline16(): import("react").JSX.Element;
@@ -3,6 +3,25 @@
3
3
  export declare const AGENT_TEAMS_LOCALE_NAMESPACE = "agentTeams";
4
4
  /** Simplified Chinese dictionary (the key-set source of truth). */
5
5
  export declare const zh: {
6
+ 'workspace.dependencies': string;
7
+ 'workspace.title': string;
8
+ 'workspace.guide': string;
9
+ 'workspace.eyebrow': string;
10
+ 'workspace.description': string;
11
+ 'workspace.relationships': string;
12
+ 'workspace.emptyTitle': string;
13
+ 'workspace.emptyBody': string;
14
+ 'workspace.loading': string;
15
+ 'workspace.error': string;
16
+ 'workspace.retry': string;
17
+ 'workspace.current': string;
18
+ 'workspace.history': string;
19
+ 'workspace.back': string;
20
+ 'workspace.tasks': string;
21
+ 'workspace.members': string;
22
+ 'workspace.completed': string;
23
+ 'workspace.focus': string;
24
+ 'workspace.noTasks': string;
6
25
  'card.memberCount': string;
7
26
  'action.openActivityPanel': string;
8
27
  'activity.panelButton': string;
@@ -81,6 +100,8 @@ export declare const zh: {
81
100
  'dependency.hint.pinned': string;
82
101
  'task.runningAria': string;
83
102
  'task.model': string;
103
+ 'task.detail.cancelled': string;
104
+ 'task.detail.failed': string;
84
105
  'task.detail.completed': string;
85
106
  'task.detail.noPrerequisite': string;
86
107
  'task.detail.ready': string;
@@ -184,6 +205,7 @@ export declare const zh: {
184
205
  'members.toggle': string;
185
206
  'members.collapse': string;
186
207
  'members.expand': string;
208
+ 'members.expandFinished': string;
187
209
  'members.empty': string;
188
210
  'assignment.label': string;
189
211
  'assignment.staged': string;
@@ -196,6 +218,25 @@ export declare const zh: {
196
218
  export type AgentTeamsLocaleKey = keyof typeof zh;
197
219
  /** English dictionary, checked complete against the Chinese source key set. */
198
220
  export declare const en: {
221
+ 'workspace.dependencies': string;
222
+ 'workspace.title': string;
223
+ 'workspace.guide': string;
224
+ 'workspace.eyebrow': string;
225
+ 'workspace.description': string;
226
+ 'workspace.relationships': string;
227
+ 'workspace.emptyTitle': string;
228
+ 'workspace.emptyBody': string;
229
+ 'workspace.loading': string;
230
+ 'workspace.error': string;
231
+ 'workspace.retry': string;
232
+ 'workspace.current': string;
233
+ 'workspace.history': string;
234
+ 'workspace.back': string;
235
+ 'workspace.tasks': string;
236
+ 'workspace.members': string;
237
+ 'workspace.completed': string;
238
+ 'workspace.focus': string;
239
+ 'workspace.noTasks': string;
199
240
  'card.memberCount': string;
200
241
  'action.openActivityPanel': string;
201
242
  'activity.panelButton': string;
@@ -274,6 +315,8 @@ export declare const en: {
274
315
  'dependency.hint.pinned': string;
275
316
  'task.runningAria': string;
276
317
  'task.model': string;
318
+ 'task.detail.cancelled': string;
319
+ 'task.detail.failed': string;
277
320
  'task.detail.completed': string;
278
321
  'task.detail.noPrerequisite': string;
279
322
  'task.detail.ready': string;
@@ -377,6 +420,7 @@ export declare const en: {
377
420
  'members.toggle': string;
378
421
  'members.collapse': string;
379
422
  'members.expand': string;
423
+ 'members.expandFinished': string;
380
424
  'members.empty': string;
381
425
  'assignment.label': string;
382
426
  'assignment.staged': string;
@@ -4,7 +4,7 @@ import type { SubagentAddress } from '@deepseek-ai/dsh-subagent/client';
4
4
  /** Narrow sessions-service face used by the activity panel and team card. */
5
5
  export interface AgentTeamsSessionNavigator {
6
6
  /** Legacy/ordinary session navigation. */
7
- open(id: SessionId): void;
7
+ open?(id: SessionId): void;
8
8
  /** rc.8 addressed subagent navigation. */
9
9
  openSubagent?(address: SubagentAddress): void;
10
10
  /** Refresh the exact parent's durable direct-child catalog. */
@@ -12,6 +12,17 @@ export interface AgentTeamsSessionNavigator {
12
12
  /** Reuse an address already retained by the client runtime when available. */
13
13
  subagentAddress?(id: SessionId): SubagentAddress | undefined;
14
14
  }
15
+ /** Newer sessions retain view ownership instead of publishing list.current. */
16
+ export declare function currentSessionId(state: {
17
+ readonly current?: SessionId;
18
+ readonly byId: Readonly<Record<string, {
19
+ readonly id: SessionId;
20
+ readonly retainedBy?: Readonly<Record<string, number>>;
21
+ }>>;
22
+ }): SessionId | undefined;
23
+ export interface AgentTeamsWorkspaceNavigator {
24
+ openSession(target: SessionId | SubagentAddress): void;
25
+ }
15
26
  /** Main-panel navigation added in Harness 0.1.5; older layouts omit these actions. */
16
27
  export interface AgentTeamsLayoutNavigator {
17
28
  selectPanel?(panelId: null): void;
@@ -26,4 +37,4 @@ export interface AgentTeamsLayoutNavigator {
26
37
  * the fallback preserves ordinary-session navigation. New layouts also select
27
38
  * the Conversation panel and cancel catalog refreshes superseded by navigation.
28
39
  */
29
- export declare function openAgentTeamMember(sessions: AgentTeamsSessionNavigator, parentSessionId: SessionId, childSessionId: SessionId, layout?: AgentTeamsLayoutNavigator): Promise<'subagent' | 'session' | 'cancelled'>;
40
+ export declare function openAgentTeamMember(sessions: AgentTeamsSessionNavigator, parentSessionId: SessionId, childSessionId: SessionId, layout?: AgentTeamsLayoutNavigator, workspace?: AgentTeamsWorkspaceNavigator): Promise<'subagent' | 'session' | 'cancelled'>;
@@ -0,0 +1,19 @@
1
+ /** Plugin-instance state shared by the monitor and any number of native tabs. */
2
+ import type { AgentTeamsCardData } from './agent-teams-card-definition.ts';
3
+ import type { ActivityTeam } from './activity-monitor.ts';
4
+ export type ConnectionStatus = 'loading' | 'ready' | 'error';
5
+ export interface WorkspaceSnapshot {
6
+ readonly statuses: ReadonlyMap<string, ConnectionStatus>;
7
+ readonly history: ReadonlyMap<string, AgentTeamsCardData>;
8
+ readonly selected: ReadonlyMap<string, string>;
9
+ }
10
+ export declare function createWorkspaceState(): {
11
+ getSnapshot: () => WorkspaceSnapshot;
12
+ subscribe: (listener: () => void) => () => void;
13
+ status(session: string, status: ConnectionStatus): void;
14
+ select(session: string, team: string): void;
15
+ remember(session: string, data: AgentTeamsCardData): void;
16
+ };
17
+ export type WorkspaceActivityState = ReturnType<typeof createWorkspaceState>;
18
+ /** Records restored at mount never reopen a closed tab; new teams are announced once. */
19
+ export declare function createTeamDiscovery(): (teams: readonly ActivityTeam[]) => string | undefined;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The audited Harness 0.1.2 / 0.1.5 subagent boundary. Keep version-specific shapes
2
+ * The audited Harness 0.1.2 / 0.1.5 / 0.1.7 subagent boundary. Keep version-specific shapes
3
3
  * here: API presence alone is not a promise of support for future versions.
4
4
  *
5
5
  * Alpha.2 owns followup/registerContinuableSetup; Alpha.5 and rc.1 own a
@@ -12,6 +12,19 @@ import type { Agent } from '@deepseek-ai/dsh-agent';
12
12
  import type { ContentBlock, MessageId } from '@deepseek-ai/dsh-llm';
13
13
  import type { Session, SessionEvent, SessionId } from '@deepseek-ai/dsh-session';
14
14
  type Setup = (childCtx: Context, child: Agent) => () => void;
15
+ declare module '@deepseek-ai/dsh-llm' {
16
+ interface MessageSourceMap {
17
+ 'agent-teams': {
18
+ readonly kind: 'agent-teams';
19
+ };
20
+ }
21
+ }
22
+ /**
23
+ * 0.1.6 moved startup admission to serial agent/created. Older created events
24
+ * have no source and precede session-start; ignore those until the old hook.
25
+ * Keep the removed event's type confined to this audited compatibility seam.
26
+ */
27
+ export declare function onAgentReady(ctx: Context, listener: (agent: Agent, vetoable: boolean) => void): () => void;
15
28
  /** Read child-owned history, excluding any descriptor inherited from a parent. */
16
29
  export declare function sessionOwnEvents(session: Session): readonly SessionEvent[];
17
30
  /** Install before the first request, including cold resume, with HMR cleanup. */
@@ -2,6 +2,10 @@
2
2
  import type { Context } from '@deepseek-ai/cordis';
3
3
  import type { TeamMessage, TeamState } from './types.ts';
4
4
  export declare function isCurrentMail(team: TeamState, message: TeamMessage): boolean;
5
+ /** Include structured provenance even in the status-tool fallback presentation. */
6
+ export declare function mailboxContent(message: TeamMessage): string;
7
+ /** Fallback reads must enforce the same current-generation rule as live admission. */
8
+ export declare function readCurrentMailbox(root: string, teamId: string, recipient: string, onMalformed?: (line: number) => void): Promise<TeamMessage[]>;
5
9
  export declare function mailboxPrompt(teamId: string, recipient: string, messages: readonly TeamMessage[]): string;
6
10
  /** Only messages actually admitted to this recipient's step become read. */
7
11
  export declare function installMailboxAdmission(ctx: Context, stateDir: string): void;
@@ -3,7 +3,7 @@
3
3
  * coverage, and resume. Tools and persistence call these; they do not I/O.
4
4
  * @module dsh-agent-teams/quality-gates
5
5
  */
6
- import { type AcceptanceResult, type CommandResult, type FindingSeverity, type ReviewFinding, type ReviewPolicy, type ReviewVerdict, type TaskKind, type TaskRevision, type TaskStatus, type TeamState, type TeamTask } from './types.ts';
6
+ import { type AcceptanceResult, type CommandResult, type FindingSeverity, type ReviewFinding, type ReviewPolicy, type ReviewVerdict, type TaskKind, type TaskEvidence, type TaskRevision, type TaskStatus, type TeamState, type TeamTask } from './types.ts';
7
7
  declare const QUALITY_KINDS: readonly TaskKind[];
8
8
  declare const WRITE_KINDS: readonly TaskKind[];
9
9
  declare const DEFAULT_REVIEW_POLICY: Required<Pick<ReviewPolicy, 'requirementsMinRounds' | 'requirementsMaxRounds' | 'codeMaxRounds' | 'maxRepairAttempts'>>;
@@ -204,3 +204,9 @@ export declare function defaultQualityDeliveryGraph(input: {
204
204
  export declare function qualityPlanningPrompt(): string;
205
205
  export declare function describeQualityLoop(team: TeamState): QualityLoopSnapshot;
206
206
  export { QUALITY_KINDS, WRITE_KINDS };
207
+ /** Persisted evidence must remain loadable after process restart. */
208
+ export declare function isTaskEvidence(value: unknown): value is TaskEvidence;
209
+ /** Append observations without mutating the original result or its completion time. */
210
+ export declare function appendTaskEvidence(task: TeamTask, input: QualityCompletionUpdate & {
211
+ evidence_note?: string;
212
+ }, by: string): boolean;
@@ -49,6 +49,7 @@ export interface DispatchTicket {
49
49
  readonly previousStatus?: 'claimed' | 'in_progress';
50
50
  readonly previousAttempt?: number;
51
51
  readonly previousAttemptId?: string;
52
+ readonly previousResult?: Pick<TeamTask, 'output' | 'verdict' | 'findings' | 'changedPaths' | 'acceptanceResults' | 'commandsRun'>;
52
53
  readonly subject: string;
53
54
  readonly description?: string;
54
55
  readonly teamDescription?: string;
@@ -42,6 +42,8 @@ export interface TeamActivityTask {
42
42
  readonly kind?: string;
43
43
  readonly round?: number;
44
44
  readonly verdict?: string;
45
+ /** Durable last-write stamp; drives the finished-member ordering (issue #192). */
46
+ readonly updatedAt: number;
45
47
  }
46
48
  /** One captain-inbox preview row. */
47
49
  export interface TeamActivityMessage {
@@ -65,6 +65,16 @@ export interface TaskRevision {
65
65
  /** Previous values of the amended fields; fields absent before are omitted. */
66
66
  previous: Record<string, unknown>;
67
67
  }
68
+ /** Append-only observations; never replace the terminal verdict or unlock a gate. */
69
+ export interface TaskEvidence {
70
+ at: number;
71
+ by: string;
72
+ attempt: number;
73
+ attemptId?: string;
74
+ note?: string;
75
+ acceptanceResults?: AcceptanceResult[];
76
+ commandsRun?: CommandResult[];
77
+ }
68
78
  /** One task of a team's task list. */
69
79
  export interface TeamTask {
70
80
  /** Stable task id from the profile template; absent for ad-hoc tasks. */
@@ -108,6 +118,8 @@ export interface TeamTask {
108
118
  changedPaths?: string[];
109
119
  acceptanceResults?: AcceptanceResult[];
110
120
  commandsRun?: CommandResult[];
121
+ /** Supplemental observations, attributed to their original execution generation. */
122
+ supplementalEvidence?: TaskEvidence[];
111
123
  reviewedTaskId?: string;
112
124
  reviewedAttempt?: number;
113
125
  /** Repair source: the implementation / previous successful artifact. */
@@ -174,6 +186,10 @@ export interface TeamMessage {
174
186
  /** Guidance is scoped to the recipient's execution generation, when present. */
175
187
  taskId?: string;
176
188
  attemptId?: string;
189
+ /** Source execution generation, independent of the recipient guidance generation. */
190
+ sourceTaskId?: string;
191
+ sourceAttemptId?: string;
192
+ sourceTaskStatus?: TaskStatus;
177
193
  /** Cancelled delivery is retained for audit but must not wake the recipient. */
178
194
  discardedAt?: number;
179
195
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nanmicoder/dsh-agent-teams",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "AgentTeams for DeepSeek Harness: multi-agent team collaboration (captain, members, tasks with dependencies, messaging) driven by natural language, with a tree monitor in the web GUI",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -71,6 +71,7 @@
71
71
  "@deepseek-ai/dsh-client-locale",
72
72
  "@deepseek-ai/dsh-client-ui-conversation",
73
73
  "@deepseek-ai/dsh-client-ui-layout",
74
+ "@deepseek-ai/dsh-client-ui-sidebar-right",
74
75
  "@deepseek-ai/dsh-client-ui-model-selection",
75
76
  "@deepseek-ai/dsh-api-session-controller",
76
77
  "@deepseek-ai/dsh-client-ui-session",
@@ -81,27 +82,27 @@
81
82
  },
82
83
  "peerDependencies": {
83
84
  "@deepseek-ai/cordis": "^4.0.2",
84
- "@deepseek-ai/dsh-agent": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
85
- "@deepseek-ai/dsh-api-session-controller": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
86
- "@deepseek-ai/dsh-client-connection": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
87
- "@deepseek-ai/dsh-client-locale": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
88
- "@deepseek-ai/dsh-client-store": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
89
- "@deepseek-ai/dsh-client-ui-chat": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
90
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
91
- "@deepseek-ai/dsh-client-ui-layout": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
92
- "@deepseek-ai/dsh-client-ui-model-selection": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
93
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
94
- "@deepseek-ai/dsh-client-ui-renderer": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
95
- "@deepseek-ai/dsh-client-ui-session": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
96
- "@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
97
- "@deepseek-ai/dsh-commands": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
98
- "@deepseek-ai/dsh-llm": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
99
- "@deepseek-ai/dsh-session": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
100
- "@deepseek-ai/dsh-session-projection": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
101
- "@deepseek-ai/dsh-subagent": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
102
- "@deepseek-ai/dsh-system-prompt": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
103
- "@deepseek-ai/dsh-tools": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
104
- "@deepseek-ai/dsh-util-values": "0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
85
+ "@deepseek-ai/dsh-agent": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
86
+ "@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
87
+ "@deepseek-ai/dsh-client-connection": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
88
+ "@deepseek-ai/dsh-client-locale": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
89
+ "@deepseek-ai/dsh-client-store": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
90
+ "@deepseek-ai/dsh-client-ui-chat": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
91
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
92
+ "@deepseek-ai/dsh-client-ui-layout": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
93
+ "@deepseek-ai/dsh-client-ui-model-selection": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
94
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
95
+ "@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
96
+ "@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
97
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
98
+ "@deepseek-ai/dsh-commands": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
99
+ "@deepseek-ai/dsh-llm": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
100
+ "@deepseek-ai/dsh-session": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
101
+ "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
102
+ "@deepseek-ai/dsh-subagent": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
103
+ "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
104
+ "@deepseek-ai/dsh-tools": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
105
+ "@deepseek-ai/dsh-util-values": "0.1.7-rc.2 || 0.1.5-rc.3 || 0.1.5-rc.2 || 0.1.5-rc.1 || 0.1.2-rc.1 || 0.1.2-alpha.5 || 0.1.2-alpha.2",
105
106
  "@deepseek-ai/schemastery": "^3.18.2",
106
107
  "react": "^18.2.0"
107
108
  },
@@ -180,32 +181,33 @@
180
181
  }
181
182
  },
182
183
  "devDependencies": {
183
- "@deepseek-ai/cordis": "^4.0.2",
184
- "@deepseek-ai/dsh": "0.1.5-rc.1",
185
- "@deepseek-ai/dsh-agent": "0.1.5-rc.1",
186
- "@deepseek-ai/dsh-api-session-controller": "0.1.5-rc.1",
187
- "@deepseek-ai/dsh-client-connection": "0.1.5-rc.1",
188
- "@deepseek-ai/dsh-client-locale": "0.1.5-rc.1",
189
- "@deepseek-ai/dsh-client-store": "0.1.5-rc.1",
190
- "@deepseek-ai/dsh-client-ui-chat": "0.1.5-rc.1",
191
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.5-rc.1",
192
- "@deepseek-ai/dsh-client-ui-layout": "0.1.5-rc.1",
193
- "@deepseek-ai/dsh-client-ui-model-selection": "0.1.5-rc.1",
194
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.1",
195
- "@deepseek-ai/dsh-client-ui-renderer": "0.1.5-rc.1",
196
- "@deepseek-ai/dsh-client-ui-session": "0.1.5-rc.1",
197
- "@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.1",
198
- "@deepseek-ai/dsh-commands": "0.1.5-rc.1",
199
- "@deepseek-ai/dsh-llm": "0.1.5-rc.1",
200
- "@deepseek-ai/dsh-llm-retry": "0.1.5-rc.1",
201
- "@deepseek-ai/dsh-session": "0.1.5-rc.1",
202
- "@deepseek-ai/dsh-session-projection": "0.1.5-rc.1",
203
- "@deepseek-ai/dsh-subagent": "0.1.5-rc.1",
204
- "@deepseek-ai/dsh-system-prompt": "0.1.5-rc.1",
205
- "@deepseek-ai/dsh-tools": "0.1.5-rc.1",
206
- "@deepseek-ai/dsh-util-values": "0.1.5-rc.1",
207
- "@deepseek-ai/dsh-workspace": "0.1.5-rc.1",
208
- "@deepseek-ai/schemastery": "^3.18.2",
184
+ "@deepseek-ai/cordis": "4.0.4",
185
+ "@deepseek-ai/dsh": "0.1.7-rc.2",
186
+ "@deepseek-ai/dsh-agent": "0.1.7-rc.2",
187
+ "@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.2",
188
+ "@deepseek-ai/dsh-client-connection": "0.1.7-rc.2",
189
+ "@deepseek-ai/dsh-client-locale": "0.1.7-rc.2",
190
+ "@deepseek-ai/dsh-client-store": "0.1.7-rc.2",
191
+ "@deepseek-ai/dsh-client-ui-chat": "0.1.7-rc.2",
192
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.2",
193
+ "@deepseek-ai/dsh-client-ui-layout": "0.1.7-rc.2",
194
+ "@deepseek-ai/dsh-client-ui-model-selection": "0.1.7-rc.2",
195
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.2",
196
+ "@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.2",
197
+ "@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.2",
198
+ "@deepseek-ai/dsh-client-ui-sidebar-right": "0.1.7-rc.2",
199
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.2",
200
+ "@deepseek-ai/dsh-commands": "0.1.7-rc.2",
201
+ "@deepseek-ai/dsh-llm": "0.1.7-rc.2",
202
+ "@deepseek-ai/dsh-llm-retry": "0.1.7-rc.2",
203
+ "@deepseek-ai/dsh-session": "0.1.7-rc.2",
204
+ "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2",
205
+ "@deepseek-ai/dsh-subagent": "0.1.7-rc.2",
206
+ "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2",
207
+ "@deepseek-ai/dsh-tools": "0.1.7-rc.2",
208
+ "@deepseek-ai/dsh-util-values": "0.1.7-rc.2",
209
+ "@deepseek-ai/dsh-workspace": "0.1.7-rc.2",
210
+ "@deepseek-ai/schemastery": "3.18.4",
209
211
  "@types/node": "^24.13.3",
210
212
  "@types/react": "~18.3.1",
211
213
  "@types/react-dom": "^18.3.7",
@@ -225,11 +227,12 @@
225
227
  "update:skills": "node scripts/update-skills.mjs",
226
228
  "test:skills-updater": "node --test scripts/update-skills.test.mjs",
227
229
  "verify:skill": "node scripts/sync-skill.mjs --check",
228
- "verify": "node scripts/verify.mjs && node scripts/fallback-tdd.mjs && node scripts/member-failure-tdd.mjs && pnpm verify:quality-gates && node scripts/lifecycle-verify.mjs && node scripts/stress-verify.mjs && pnpm verify:web-routes && pnpm verify:release && pnpm verify:skill && pnpm verify:harness-contract && pnpm verify:http-body && pnpm verify:compatibility && pnpm verify:capabilities && pnpm verify:member-spawn-recovery",
230
+ "verify": "node scripts/verify.mjs && node scripts/fallback-tdd.mjs && node scripts/member-failure-tdd.mjs && pnpm verify:quality-gates && node scripts/lifecycle-verify.mjs && node scripts/stress-verify.mjs && node --test scripts/issue-159.test.mjs && pnpm verify:web-routes && pnpm verify:release && pnpm verify:readme && pnpm verify:skill && pnpm verify:harness-contract && pnpm verify:http-body && pnpm verify:compatibility && pnpm verify:capabilities && pnpm verify:member-spawn-recovery",
229
231
  "verify:quality-gates": "node scripts/quality-gates-tdd.mjs && node --test scripts/quality-gates-repair-scope.test.mjs scripts/quality-gates-amend.test.mjs",
230
232
  "verify:web-routes": "node scripts/web-routes-verify.mjs",
231
233
  "verify:release": "node --test scripts/release-metadata.test.mjs",
232
- "verify:harness-contract": "node scripts/harness-compat-tdd.mjs && node scripts/stability-tdd.mjs && node scripts/lifecycle-verify.mjs --modern-harness && node scripts/member-failure-tdd.mjs --modern-harness && node scripts/lifecycle-verify.mjs --delivery-harness && node scripts/member-failure-tdd.mjs --delivery-harness",
234
+ "verify:readme": "node scripts/readme-version.mjs && node --test scripts/readme-version.test.mjs",
235
+ "verify:harness-contract": "node scripts/harness-compat-tdd.mjs && node scripts/stability-tdd.mjs && node scripts/lifecycle-verify.mjs --modern-harness && node scripts/member-failure-tdd.mjs --modern-harness && node scripts/lifecycle-verify.mjs --delivery-harness && node scripts/member-failure-tdd.mjs --delivery-harness && node --test scripts/client-harness-migration.test.mjs scripts/workspace-activity.test.mjs",
233
236
  "verify:compatibility": "node scripts/compatibility.mjs && node --test scripts/compatibility.test.mjs && node scripts/doctor.mjs",
234
237
  "verify:http-body": "node --test scripts/http-body.test.mjs",
235
238
  "doctor": "node scripts/doctor.mjs",
@@ -0,0 +1,14 @@
1
+ # AgentTeams v0.1.21-rc.1
2
+
3
+ Local compatibility candidate; not published. Intended first publication channel: `next`.
4
+
5
+ - Adapt member initialization to the awaited `agent/created` lifecycle while retaining the older `agent/session-start` boundary. Initialization failures veto modern startup.
6
+ - Follow retained `mainView` sessions and the workspace navigation API so the activity panel and member transcript links work on current Harness.
7
+ - Own the five small panel icons rather than importing renamed host artwork exports.
8
+ - Declare the AgentTeams message producer and recognize both nested legacy and V4 tool-result errors.
9
+ - Align the development cohort to Harness `0.1.7-rc.2`, Cordis `4.0.4`, and Schemastery `3.18.4`; extend the exact host matrix with `0.1.5-rc.2/rc.3`.
10
+ - Retain main’s #159 fixes: reject stale task reports, deduplicate repeated reports, append terminal evidence without reopening work, and expose automatic repair/review follow-ups.
11
+ - Retain #193: collapse finished members and order them by completion time.
12
+ - Sync upstream maintenance skills to commit `eeff1cdcffe4013e094d94c8d9b8651a65fbc79a` without local changes to vendored files.
13
+
14
+ See the [compatibility audit](../docs/harness-0.1.7-rc.2-audit-2026-09-25/README.md) for evidence, verification scope, and remaining release gates. An exact support entry is not a promise for later releases. Harness V4 session migration is not reversible simply by reinstalling an older CLI.
@@ -0,0 +1,23 @@
1
+ # AgentTeams v0.1.21
2
+
3
+ Stable plugin release on npm `latest`. Recommended host: DeepSeek Harness `0.1.7-rc.2`, currently on its separate `next` channel. Installing AgentTeams does not upgrade the host.
4
+
5
+ - Open Team collaboration as a native workspace tab from the owning chat header or reply card. Keep member icons and conversation navigation; remove the unrelated entry from the workspace start page.
6
+ - Show task dependencies, member assignments and progress with a compact header. Fix intermediate-width column placement and use a single column in narrow panes.
7
+ - Keep team monitoring alive when its tab closes, retain completed archives, and avoid replacing file or terminal tabs. Older supported hosts retain the activity panel.
8
+ - Adapt awaited member initialization, session navigation, message producers and V4 tool-result errors to Harness `0.1.7-rc.2`. Align the development cohort and add exact `0.1.5-rc.2/rc.3` support.
9
+ - Preserve stale-report protection, report deduplication and terminal evidence without reopening work (#159), plus completion ordering and folding (#193).
10
+
11
+ ## Upgrade
12
+
13
+ ```sh
14
+ dsh plugin --profile web add --save-exact @nanmicoder/dsh-agent-teams@0.1.21
15
+ ```
16
+
17
+ Use your active profile, restart its Harness process, and refresh the browser. Source installations must rebuild after pulling.
18
+
19
+ ## Verification
20
+
21
+ Real DeepSeek model runs in isolated `/tmp` projects covered normal completion, dependency scheduling, stopping and deliberate failure. Browser checks covered chat entry points, closing/reopening, staged plans and responsive widths from 360 to 1440 pixels. See the [workspace evidence](../docs/workspace-181-verification/README.md) and [host compatibility audit](../docs/harness-0.1.7-rc.2-audit-2026-09-25/README.md) for exact scope and artifact versions.
22
+
23
+ GitHub Actions runs the complete verification suite and seven-host compatibility matrix before publishing its verified tarball. The exact supported versions are recorded in [compatibility.json](../compatibility.json); later host releases are not implicitly supported.