@qilin-agent/experimental-client-ui-agent-team 0.0.0-stage → 3.1.4
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/LICENSE +21 -0
- package/README.i18n.yaml +46 -0
- package/README.md +112 -2
- package/README.zh.md +113 -0
- package/lib/client.js +5616 -0
- package/lib/index.js +6 -0
- package/lib/types/client/TaskCardParts.d.ts +41 -0
- package/lib/types/client/TeamAction.d.ts +13 -0
- package/lib/types/client/TeamBody.d.ts +20 -0
- package/lib/types/client/definition.d.ts +20 -0
- package/lib/types/client/index.d.ts +13 -0
- package/lib/types/client/locales.d.ts +106 -0
- package/lib/types/client/member-facts.d.ts +29 -0
- package/lib/types/client/mount.d.ts +33 -0
- package/lib/types/client/team-model.d.ts +89 -0
- package/lib/types/client/team-page-store.d.ts +42 -0
- package/lib/types/client/team-writes.d.ts +107 -0
- package/lib/types/index.d.ts +4 -0
- package/package.json +92 -3
package/lib/index.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The task-card parts the conversation action draws inline and the sidebar page
|
|
3
|
+
* draws in its board.
|
|
4
|
+
*
|
|
5
|
+
* Each surface owns its CSS module and styles these parts differently, so a
|
|
6
|
+
* part receives the class names it draws with rather than importing one
|
|
7
|
+
* surface's module into the other.
|
|
8
|
+
*/
|
|
9
|
+
import type { ReactNode } from 'react';
|
|
10
|
+
import type { TeamTaskView as TeamTask } from '@qilin-agent/experimental-agent-team/client';
|
|
11
|
+
import type { TranslateNS } from '@qilin-agent/client-ui-slots';
|
|
12
|
+
import { NS } from './locales.ts';
|
|
13
|
+
/**
|
|
14
|
+
* The class names the shared parts draw with, as their owner's CSS module spells
|
|
15
|
+
* them: `taskTitle`, `taskState`, and `warning`. A CSS module is an untyped
|
|
16
|
+
* class map, so the owner's module is passed whole rather than re-declared here.
|
|
17
|
+
*/
|
|
18
|
+
export type TaskCardStyles = Readonly<Record<string, string>>;
|
|
19
|
+
/**
|
|
20
|
+
* The card's head: the task's subject and its live state.
|
|
21
|
+
* @param props - the task being drawn, the owner's classes, and the owner's copy.
|
|
22
|
+
* @returns the title row.
|
|
23
|
+
*/
|
|
24
|
+
export declare function TaskCardHead({ task, styles, t }: {
|
|
25
|
+
task: TeamTask;
|
|
26
|
+
styles: TaskCardStyles;
|
|
27
|
+
t: TranslateNS<typeof NS>;
|
|
28
|
+
}): ReactNode;
|
|
29
|
+
/**
|
|
30
|
+
* The card's shared task facts: readiness, blockers, declared write scopes, and
|
|
31
|
+
* any scope warning, in one meta row. The identity and owner spans belong to the
|
|
32
|
+
* owner, which places them around these facts.
|
|
33
|
+
* @param props - the task being drawn, the owner's classes, and the owner's copy.
|
|
34
|
+
* @returns the fact spans.
|
|
35
|
+
*/
|
|
36
|
+
export declare function TaskFacts({ task, styles, t }: {
|
|
37
|
+
task: TeamTask;
|
|
38
|
+
styles: TaskCardStyles;
|
|
39
|
+
t: TranslateNS<typeof NS>;
|
|
40
|
+
}): ReactNode;
|
|
41
|
+
//# sourceMappingURL=TaskCardParts.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SessionId } from '@qilin-agent/session/types';
|
|
2
|
+
import type { PropsLocale, PropsRuntime } from '@qilin-agent/client-ui-slots';
|
|
3
|
+
import { NS } from './locales.ts';
|
|
4
|
+
/** Business actions injected by the browser plugin. */
|
|
5
|
+
export interface TeamActionInjected {
|
|
6
|
+
/** Open a roster Session from the current conversation. */
|
|
7
|
+
openTeammate: (sessionId: SessionId, childSessionId: SessionId) => void;
|
|
8
|
+
}
|
|
9
|
+
/** Full props of the Team conversation-header action. */
|
|
10
|
+
export type TeamActionProps = PropsRuntime<'conversation.session.header.actions'> & TeamActionInjected & PropsLocale<typeof NS>;
|
|
11
|
+
/** Render the Team roster and read-only task board. */
|
|
12
|
+
export declare function TeamAction({ sessionId, useSession, useSessions, useSessionStatus, openTeammate, t, }: TeamActionProps): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=TeamAction.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { InjectFace, PropsLocale, PropsRuntime, PropsStore } from '@qilin-agent/client-ui-slots';
|
|
3
|
+
import type { createTeamPageStore } from './team-page-store.ts';
|
|
4
|
+
import type { TeamPageInjected } from './team-writes.ts';
|
|
5
|
+
import { NS } from './locales.ts';
|
|
6
|
+
/** The body's composed props: the tab it draws, its store, its face, and its copy. */
|
|
7
|
+
export type TeamBodyProps = PropsRuntime<'sidebar.right.pane.tab'> & PropsStore<ReturnType<typeof createTeamPageStore>> & InjectFace<TeamPageInjected> & PropsLocale<typeof NS>;
|
|
8
|
+
/**
|
|
9
|
+
* The Team type's chip title: the person glyph before the type's label.
|
|
10
|
+
* @param props - the tab information hook.
|
|
11
|
+
* @returns the glyph followed by the tab's title text.
|
|
12
|
+
*/
|
|
13
|
+
export declare function TeamTitle({ useTabInfo }: PropsRuntime<'sidebar.right.pane.tab.title'>): ReactNode;
|
|
14
|
+
/**
|
|
15
|
+
* Render the Team page: notices, toolbar, roster, board, and the open form.
|
|
16
|
+
* @param props - the tab's shares, the page store, the write face, and the copy.
|
|
17
|
+
* @returns the page.
|
|
18
|
+
*/
|
|
19
|
+
export declare function TeamBody({ sessionId, useSession, useSessions, useSessionStatus, useStore, actions, openTeammate, refresh, createTask, editTask, transitionTask, reassignTask, t, }: TeamBodyProps): ReactNode;
|
|
20
|
+
//# sourceMappingURL=TeamBody.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stage one of this package's registration: what the `agent-team` tab type IS.
|
|
3
|
+
*
|
|
4
|
+
* The type is a page, not a viewer: it claims no address, so a tab of this
|
|
5
|
+
* kind is opened by kind alone — from the guide page's entry box, or from
|
|
6
|
+
* anywhere that calls `ctx.sidebarRight.openTab('agent-team')`.
|
|
7
|
+
*/
|
|
8
|
+
import type { TranslateNS } from '@qilin-agent/client-ui-slots';
|
|
9
|
+
import type { SidebarRightTabDefinition } from '@qilin-agent/client-ui-sidebar-right/client';
|
|
10
|
+
/** The tab kind this package owns; `ctx.sidebarRight.openTab` names it. */
|
|
11
|
+
export declare const TEAM_KIND = "agent-team";
|
|
12
|
+
/** This implementation's identity in the tab system, and the key its body registers under. */
|
|
13
|
+
export declare const TEAM_ID = "@qilin-agent/experimental-client-ui-agent-team";
|
|
14
|
+
/**
|
|
15
|
+
* The Team type's registry definition.
|
|
16
|
+
* @param t - namespace-bound translate, read fresh on every label call.
|
|
17
|
+
* @returns the definition to register.
|
|
18
|
+
*/
|
|
19
|
+
export declare function teamDefinition(t: TranslateNS<'agent-team'>): SidebarRightTabDefinition;
|
|
20
|
+
//# sourceMappingURL=definition.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Browser entry for the experimental Agent Teams write bridge, popover, and Team page. */
|
|
2
|
+
import type { Context as ClientContext } from '@qilin-agent/kylin';
|
|
3
|
+
export { inject } from './mount.ts';
|
|
4
|
+
export type { TeamActionInjected, TeamActionProps } from './TeamAction.tsx';
|
|
5
|
+
export type { TeamBodyProps } from './TeamBody.tsx';
|
|
6
|
+
export type { TeamKey } from './locales.ts';
|
|
7
|
+
/**
|
|
8
|
+
* Mount the experimental `agentTeams` namespace and register the Team UI.
|
|
9
|
+
* @param ctx - Client runtime.
|
|
10
|
+
* @returns complete UI and Remote disposer.
|
|
11
|
+
*/
|
|
12
|
+
export declare function apply(ctx: ClientContext): Promise<() => Promise<void>>;
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/** Agent Teams Web dictionaries. */
|
|
2
|
+
/** Locale namespace owned by the Agent Teams Web UI. */
|
|
3
|
+
export declare const NS = "agent-team";
|
|
4
|
+
/** Simplified Chinese dictionary and key source. */
|
|
5
|
+
export declare const zh: {
|
|
6
|
+
trigger: string;
|
|
7
|
+
loading: string;
|
|
8
|
+
unavailable: string;
|
|
9
|
+
failure: string;
|
|
10
|
+
empty: string;
|
|
11
|
+
roster: string;
|
|
12
|
+
tasks: string;
|
|
13
|
+
model: string;
|
|
14
|
+
open: string;
|
|
15
|
+
current: string;
|
|
16
|
+
owner: string;
|
|
17
|
+
unowned: string;
|
|
18
|
+
blockedBy: string;
|
|
19
|
+
writeScopes: string;
|
|
20
|
+
ready: string;
|
|
21
|
+
blocked: string;
|
|
22
|
+
'task.expand': string;
|
|
23
|
+
'task.collapse': string;
|
|
24
|
+
'memberStatus.running': string;
|
|
25
|
+
'memberStatus.inactive': string;
|
|
26
|
+
'memberStatus.provisioning': string;
|
|
27
|
+
'memberStatus.failed': string;
|
|
28
|
+
'status.pending': string;
|
|
29
|
+
'status.in_progress': string;
|
|
30
|
+
'status.completed': string;
|
|
31
|
+
'guide.title': string;
|
|
32
|
+
'guide.description': string;
|
|
33
|
+
create: string;
|
|
34
|
+
edit: string;
|
|
35
|
+
subject: string;
|
|
36
|
+
description: string;
|
|
37
|
+
commit: string;
|
|
38
|
+
cancel: string;
|
|
39
|
+
complete: string;
|
|
40
|
+
reopen: string;
|
|
41
|
+
delete: string;
|
|
42
|
+
deleteArmed: string;
|
|
43
|
+
conflict: string;
|
|
44
|
+
rejected: string;
|
|
45
|
+
'notice.close': string;
|
|
46
|
+
refresh: string;
|
|
47
|
+
busy: string;
|
|
48
|
+
formHint: string;
|
|
49
|
+
'placeholder.subject': string;
|
|
50
|
+
'placeholder.description': string;
|
|
51
|
+
'placeholder.blockers': string;
|
|
52
|
+
'placeholder.scopes': string;
|
|
53
|
+
};
|
|
54
|
+
/** Agent Teams locale key union. */
|
|
55
|
+
export type TeamKey = keyof typeof zh;
|
|
56
|
+
/** English dictionary checked against the Chinese key set. */
|
|
57
|
+
export declare const en: {
|
|
58
|
+
trigger: string;
|
|
59
|
+
loading: string;
|
|
60
|
+
unavailable: string;
|
|
61
|
+
failure: string;
|
|
62
|
+
empty: string;
|
|
63
|
+
roster: string;
|
|
64
|
+
tasks: string;
|
|
65
|
+
model: string;
|
|
66
|
+
open: string;
|
|
67
|
+
current: string;
|
|
68
|
+
owner: string;
|
|
69
|
+
unowned: string;
|
|
70
|
+
blockedBy: string;
|
|
71
|
+
writeScopes: string;
|
|
72
|
+
ready: string;
|
|
73
|
+
blocked: string;
|
|
74
|
+
'task.expand': string;
|
|
75
|
+
'task.collapse': string;
|
|
76
|
+
'memberStatus.running': string;
|
|
77
|
+
'memberStatus.inactive': string;
|
|
78
|
+
'memberStatus.provisioning': string;
|
|
79
|
+
'memberStatus.failed': string;
|
|
80
|
+
'status.pending': string;
|
|
81
|
+
'status.in_progress': string;
|
|
82
|
+
'status.completed': string;
|
|
83
|
+
'guide.title': string;
|
|
84
|
+
'guide.description': string;
|
|
85
|
+
create: string;
|
|
86
|
+
edit: string;
|
|
87
|
+
subject: string;
|
|
88
|
+
description: string;
|
|
89
|
+
commit: string;
|
|
90
|
+
cancel: string;
|
|
91
|
+
complete: string;
|
|
92
|
+
reopen: string;
|
|
93
|
+
delete: string;
|
|
94
|
+
deleteArmed: string;
|
|
95
|
+
conflict: string;
|
|
96
|
+
rejected: string;
|
|
97
|
+
'notice.close': string;
|
|
98
|
+
refresh: string;
|
|
99
|
+
busy: string;
|
|
100
|
+
formHint: string;
|
|
101
|
+
'placeholder.subject': string;
|
|
102
|
+
'placeholder.description': string;
|
|
103
|
+
'placeholder.blockers': string;
|
|
104
|
+
'placeholder.scopes': string;
|
|
105
|
+
};
|
|
106
|
+
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The live facts one roster member draws, read the same way by the conversation
|
|
3
|
+
* action's rows and the page's roster: the model its Session selected, its
|
|
4
|
+
* settled status, and whether it is the current Session.
|
|
5
|
+
*/
|
|
6
|
+
import type { TeamMemberProjection } from '@qilin-agent/experimental-agent-team/client';
|
|
7
|
+
import type { UseSessionStatus, UseSessions } from '@qilin-agent/client-ui-session/client';
|
|
8
|
+
import type { SessionId } from '@qilin-agent/session/types';
|
|
9
|
+
import type { MemberStatus } from './team-model.ts';
|
|
10
|
+
/** The two seats the facts come through: the Session list and one Session's status. */
|
|
11
|
+
interface MemberSeats {
|
|
12
|
+
readonly useSessions: UseSessions;
|
|
13
|
+
readonly useSessionStatus: UseSessionStatus;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Read one member's live facts. An active member with neither a status push nor
|
|
17
|
+
* a running summary is `inactive`; a member in any other phase reports that phase.
|
|
18
|
+
* @param member - the member projection being drawn.
|
|
19
|
+
* @param sessionId - the Session the surface is showing, for the current-member comparison.
|
|
20
|
+
* @param seats - the standing Session list and Session-status seats.
|
|
21
|
+
* @returns the selected model, the settled status, and whether this member is the current Session.
|
|
22
|
+
*/
|
|
23
|
+
export declare function useMemberFacts(member: TeamMemberProjection, sessionId: SessionId, seats: MemberSeats): {
|
|
24
|
+
readonly model: string | undefined;
|
|
25
|
+
readonly status: MemberStatus;
|
|
26
|
+
readonly isCurrent: boolean;
|
|
27
|
+
};
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=member-facts.d.ts.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Source-safe Agent Teams browser registration: write bridge, popover, and Team page. */
|
|
2
|
+
import type { Context as ClientContext } from '@qilin-agent/kylin';
|
|
3
|
+
import type { TypertRemoteContribution } from '@qilin-agent/typert-protocol';
|
|
4
|
+
import { type TeamKey } from './locales.ts';
|
|
5
|
+
declare module '@qilin-agent/client-ui-slots' {
|
|
6
|
+
interface LocaleNamespaceMap {
|
|
7
|
+
/** Agent Teams roster and task-board copy. */
|
|
8
|
+
'agent-team': TeamKey;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Required browser services: navigation, slots, locale, tab registry, and the
|
|
13
|
+
* Remote carrier. The `agentTeams` namespace is absent on purpose — this plugin
|
|
14
|
+
* mounts it, so declaring it here would leave the fiber PENDING forever waiting
|
|
15
|
+
* for its own output.
|
|
16
|
+
*/
|
|
17
|
+
export declare const inject: string[];
|
|
18
|
+
/**
|
|
19
|
+
* Register the Team locale dictionaries, the conversation-header action, and
|
|
20
|
+
* the right-Sidebar Team page. The page reads the Lead Session's `agentTeam`
|
|
21
|
+
* projection from the shared Session store and writes through the mounted
|
|
22
|
+
* `agentTeams` Remote namespace; the registration itself performs no call.
|
|
23
|
+
* @param ctx - Client Context carrying the injected services.
|
|
24
|
+
*/
|
|
25
|
+
export declare function registerAgentTeamUi(ctx: ClientContext): void;
|
|
26
|
+
/**
|
|
27
|
+
* Mount the experimental `agentTeams` write namespace and register the UI.
|
|
28
|
+
* @param ctx - Client runtime owning the Remote, dictionaries, slots, and Session store.
|
|
29
|
+
* @param contribution - the generated `agentTeams` Remote definitions.
|
|
30
|
+
* @returns disposer joining the UI and the Remote withdrawal.
|
|
31
|
+
*/
|
|
32
|
+
export declare function mountAgentTeamUi(ctx: ClientContext, contribution: TypertRemoteContribution): Promise<() => Promise<void>>;
|
|
33
|
+
//# sourceMappingURL=mount.d.ts.map
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure Team-page arithmetic: status→copy mapping, dot states, and the
|
|
3
|
+
* create/edit draft rules, shared by the conversation popover and the
|
|
4
|
+
* right-Sidebar page. No React, no stores, no Remote calls.
|
|
5
|
+
*/
|
|
6
|
+
import type { TeamTaskId, TeamTaskView as TeamTask } from '@qilin-agent/experimental-agent-team/client';
|
|
7
|
+
import type { StateDotState } from '@qilin-agent/client-ui-primitives';
|
|
8
|
+
import type { TeamKey } from './locales.ts';
|
|
9
|
+
/** Durable lifecycle overlaid with the member Session's live turn activity. */
|
|
10
|
+
export type MemberStatus = 'running' | 'inactive' | 'provisioning' | 'failed';
|
|
11
|
+
/**
|
|
12
|
+
* Map one task status onto its status copy key.
|
|
13
|
+
* @param status - the task's durable status.
|
|
14
|
+
* @returns the locale key naming that status.
|
|
15
|
+
*/
|
|
16
|
+
export declare function statusKey(status: TeamTask['status']): TeamKey;
|
|
17
|
+
/**
|
|
18
|
+
* Map one member status onto its status copy key.
|
|
19
|
+
* @param status - the member's overlaid lifecycle status.
|
|
20
|
+
* @returns the locale key naming that status.
|
|
21
|
+
*/
|
|
22
|
+
export declare function memberStatusKey(status: MemberStatus): TeamKey;
|
|
23
|
+
/**
|
|
24
|
+
* Map one live member status onto its roster dot state.
|
|
25
|
+
* @param status - a member status that renders as a dot rather than a glyph.
|
|
26
|
+
* @returns the shared dot state for that status.
|
|
27
|
+
*/
|
|
28
|
+
export declare function memberDotState(status: Exclude<MemberStatus, 'inactive'>): StateDotState;
|
|
29
|
+
/**
|
|
30
|
+
* Map one task onto its board dot state: blocked pending tasks warn.
|
|
31
|
+
* @param task - the task view to render.
|
|
32
|
+
* @returns the shared dot state for the task's board position.
|
|
33
|
+
*/
|
|
34
|
+
export declare function taskDotState(task: TeamTask): StateDotState;
|
|
35
|
+
/** One create or edit draft exactly as the form holds it: texts, not yet lists. */
|
|
36
|
+
export interface TeamDraft {
|
|
37
|
+
/** Task subject exactly as typed; commits require it nonempty. */
|
|
38
|
+
subject: string;
|
|
39
|
+
/** Task description exactly as typed. */
|
|
40
|
+
description: string;
|
|
41
|
+
/** Blocker task ids as one comma-separated line. */
|
|
42
|
+
blockers: string;
|
|
43
|
+
/** Write scopes as one comma-separated line. */
|
|
44
|
+
scopes: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* An empty draft for the create form.
|
|
48
|
+
* @returns a draft with every field blank.
|
|
49
|
+
*/
|
|
50
|
+
export declare function emptyTeamDraft(): TeamDraft;
|
|
51
|
+
/**
|
|
52
|
+
* A draft pre-filled from one task for the edit form.
|
|
53
|
+
* @param task - the task being edited.
|
|
54
|
+
* @returns the draft holding the task's current texts and lists.
|
|
55
|
+
*/
|
|
56
|
+
export declare function teamDraftOf(task: TeamTask): TeamDraft;
|
|
57
|
+
/**
|
|
58
|
+
* Split one comma-separated line into trimmed, de-duplicated items in first
|
|
59
|
+
* occurrence order; empty items drop.
|
|
60
|
+
* @param text - the line as typed.
|
|
61
|
+
* @returns the normalized items.
|
|
62
|
+
*/
|
|
63
|
+
export declare function teamItems(text: string): string[];
|
|
64
|
+
/**
|
|
65
|
+
* Whether one draft names a subject and a description and may commit.
|
|
66
|
+
* @param draft - the form state as typed.
|
|
67
|
+
* @returns whether the commit button may act on this draft.
|
|
68
|
+
*/
|
|
69
|
+
export declare function isTeamDraftCommittable(draft: TeamDraft): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Normalize one draft into the wire request's fields: trimmed texts, parsed lists.
|
|
72
|
+
* @param draft - the form state as typed.
|
|
73
|
+
* @returns the fields one create or edit request carries.
|
|
74
|
+
*/
|
|
75
|
+
export declare function teamFormFieldsOf(draft: TeamDraft): {
|
|
76
|
+
readonly subject: string;
|
|
77
|
+
readonly description: string;
|
|
78
|
+
readonly blockers: readonly TeamTaskId[];
|
|
79
|
+
readonly writeScopes: readonly string[];
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Whether two id-or-scope lists name the same set regardless of order; an
|
|
83
|
+
* order-only difference needs no write.
|
|
84
|
+
* @param left - one list as currently stored.
|
|
85
|
+
* @param right - the other list as committed from the form.
|
|
86
|
+
* @returns whether both lists hold the same members.
|
|
87
|
+
*/
|
|
88
|
+
export declare function sameTeamSet(left: readonly string[], right: readonly string[]): boolean;
|
|
89
|
+
//# sourceMappingURL=team-model.d.ts.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Team page's write-outcome state.
|
|
3
|
+
*
|
|
4
|
+
* The seat declares this store as exclusive on the session-scoped tab slot,
|
|
5
|
+
* so the framework mints one instance per Session: the state is exactly one
|
|
6
|
+
* page's "is a write in flight" and "what the last settled write reported".
|
|
7
|
+
* The write face performs every mutation and records each outcome here; the
|
|
8
|
+
* body only reads.
|
|
9
|
+
*/
|
|
10
|
+
import { type EngineStoreHandle } from '@qilin-agent/client-store';
|
|
11
|
+
/** What one settled write reported. */
|
|
12
|
+
export type TeamNotice = {
|
|
13
|
+
readonly kind: 'conflict';
|
|
14
|
+
} | {
|
|
15
|
+
readonly kind: 'rejected';
|
|
16
|
+
readonly message: string;
|
|
17
|
+
};
|
|
18
|
+
/** One page's write-outcome state. */
|
|
19
|
+
export interface TeamPageState {
|
|
20
|
+
/** Whether one write is in flight; the face starts no second write meanwhile. */
|
|
21
|
+
busy: boolean;
|
|
22
|
+
/** The last settled write's outcome; absent while nothing is reported. */
|
|
23
|
+
notice: TeamNotice | undefined;
|
|
24
|
+
}
|
|
25
|
+
/** The store's write set. */
|
|
26
|
+
type TeamPageActions = {
|
|
27
|
+
busy: (draft: TeamPageState) => void;
|
|
28
|
+
settled: (draft: TeamPageState) => void;
|
|
29
|
+
conflict: (draft: TeamPageState) => void;
|
|
30
|
+
rejected: (draft: TeamPageState, message: string) => void;
|
|
31
|
+
cleared: (draft: TeamPageState) => void;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Declare the Team page's store.
|
|
35
|
+
*
|
|
36
|
+
* A factory rather than a shared handle: the registration declares it as an
|
|
37
|
+
* exclusive store, so the framework mints one instance per Session.
|
|
38
|
+
* @returns the store handle to declare on the registration.
|
|
39
|
+
*/
|
|
40
|
+
export declare function createTeamPageStore(): EngineStoreHandle<TeamPageState, TeamPageActions>;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=team-page-store.d.ts.map
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Team page's asynchronous half: every `agentTeams` write, bound to the
|
|
3
|
+
* page store's actions.
|
|
4
|
+
*
|
|
5
|
+
* The component never awaits anything. It calls one of the face's entries and
|
|
6
|
+
* this face performs the mutation and writes the outcome through the store's
|
|
7
|
+
* own actions. Writes always go out under the Team Lead's identity — a
|
|
8
|
+
* teammate conversation resolves to its Lead first, because the gateway's
|
|
9
|
+
* agent lookup cannot resume a subagent-owned Session. One write flies at a
|
|
10
|
+
* time per Session (`busy`); a `stale-revision` refusal records the conflict
|
|
11
|
+
* notice and refreshes the Lead's projections so the board shows the current
|
|
12
|
+
* revisions; every other refusal records the wire failure's message.
|
|
13
|
+
*/
|
|
14
|
+
import type { ClientRemote } from '@qilin-agent/api-remotes/client';
|
|
15
|
+
import type { BoundActions } from '@qilin-agent/client-store';
|
|
16
|
+
import type { SessionTarget } from '@qilin-agent/api-session-controller/client';
|
|
17
|
+
import type { SessionId } from '@qilin-agent/session/types';
|
|
18
|
+
import type { TeamTaskId, TeamTaskView as TeamTask } from '@qilin-agent/experimental-agent-team/client';
|
|
19
|
+
import type { createTeamPageStore } from './team-page-store.ts';
|
|
20
|
+
/**
|
|
21
|
+
* The slice of the Client Remote face the page calls: the `agentTeams`
|
|
22
|
+
* namespace's two write methods, exactly as the Host's generated client
|
|
23
|
+
* declares them.
|
|
24
|
+
*/
|
|
25
|
+
export type TeamWriter = Pick<ClientRemote['agentTeams'], 'createTask' | 'updateTask'>;
|
|
26
|
+
/** One create or edit form's normalized fields, ready for the wire request. */
|
|
27
|
+
export interface TeamTaskFormFields {
|
|
28
|
+
/** Task subject, trimmed by the caller. */
|
|
29
|
+
readonly subject: string;
|
|
30
|
+
/** Task description, trimmed by the caller. */
|
|
31
|
+
readonly description: string;
|
|
32
|
+
/** Blocker task ids in first-occurrence order. */
|
|
33
|
+
readonly blockers: readonly TeamTaskId[];
|
|
34
|
+
/** Write-scope prefixes in first-occurrence order. */
|
|
35
|
+
readonly writeScopes: readonly string[];
|
|
36
|
+
}
|
|
37
|
+
/** The browser actions the Team page and popover perform. */
|
|
38
|
+
export interface TeamPageInjected {
|
|
39
|
+
/**
|
|
40
|
+
* Open a roster Session from the current conversation: the Lead in the main
|
|
41
|
+
* view, a teammate as a continuable child beside it.
|
|
42
|
+
* @param sessionId - the conversation the action runs from.
|
|
43
|
+
* @param childSessionId - the roster Session to open.
|
|
44
|
+
*/
|
|
45
|
+
readonly openTeammate: (sessionId: SessionId, childSessionId: SessionId) => void;
|
|
46
|
+
/**
|
|
47
|
+
* Re-read the Lead's projections from the Host; the board follows the push.
|
|
48
|
+
* @param sessionId - the conversation the page is attached to.
|
|
49
|
+
*/
|
|
50
|
+
readonly refresh: (sessionId: SessionId) => void;
|
|
51
|
+
/**
|
|
52
|
+
* Create one shared task on the person's behalf.
|
|
53
|
+
* @param sessionId - the conversation the page is attached to.
|
|
54
|
+
* @param fields - the create form's normalized fields.
|
|
55
|
+
*/
|
|
56
|
+
readonly createTask: (sessionId: SessionId, fields: TeamTaskFormFields) => void;
|
|
57
|
+
/**
|
|
58
|
+
* Edit one task's subject, description, and write scopes, then — when the
|
|
59
|
+
* dependency set changed — commit the new blockers as a second write. Each
|
|
60
|
+
* list field rides only when it differs from the drawn task, so clearing a
|
|
61
|
+
* list reaches the wire as an empty set instead of an omission.
|
|
62
|
+
* @param sessionId - the conversation the page is attached to.
|
|
63
|
+
* @param task - the task as the edit form drew it.
|
|
64
|
+
* @param fields - the edit form's normalized fields.
|
|
65
|
+
*/
|
|
66
|
+
readonly editTask: (sessionId: SessionId, task: TeamTask, fields: TeamTaskFormFields) => void;
|
|
67
|
+
/**
|
|
68
|
+
* Commit one button transition: complete, reopen, or delete.
|
|
69
|
+
* @param sessionId - the conversation the page is attached to.
|
|
70
|
+
* @param task - the task as the card drew it.
|
|
71
|
+
* @param action - the transition.
|
|
72
|
+
*/
|
|
73
|
+
readonly transitionTask: (sessionId: SessionId, task: TeamTask, action: 'complete' | 'reopen' | 'delete') => void;
|
|
74
|
+
/**
|
|
75
|
+
* Reassign one task, or release it to unowned with an undefined owner.
|
|
76
|
+
* @param sessionId - the conversation the page is attached to.
|
|
77
|
+
* @param task - the task as the card drew it.
|
|
78
|
+
* @param owner - the assignee's durable member name, or undefined to release.
|
|
79
|
+
*/
|
|
80
|
+
readonly reassignTask: (sessionId: SessionId, task: TeamTask, owner: string | undefined) => void;
|
|
81
|
+
}
|
|
82
|
+
/** The browser services the face performs: writes, projection refresh, and roster navigation. */
|
|
83
|
+
export interface TeamWriteDeps {
|
|
84
|
+
/** The generated `agentTeams` write namespace. */
|
|
85
|
+
readonly writer: TeamWriter;
|
|
86
|
+
/** Re-read one Session's projections from the Host. */
|
|
87
|
+
readonly refreshProjections: (sessionId: SessionId) => Promise<void>;
|
|
88
|
+
/** The conversation Session owning a viewed Session's Team. */
|
|
89
|
+
readonly leadSessionId: (sessionId: SessionId) => SessionId;
|
|
90
|
+
/** How many main views retain one conversation; zero means it may navigate. */
|
|
91
|
+
readonly mainViewCount: (sessionId: SessionId) => number;
|
|
92
|
+
/** Open one conversation as the current view. */
|
|
93
|
+
readonly openSession: (target: SessionTarget) => void;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Bind the roster-opening action shared by the page and the popover.
|
|
97
|
+
* @param deps - the navigation the action performs.
|
|
98
|
+
* @returns the open action.
|
|
99
|
+
*/
|
|
100
|
+
export declare function teamOpenTeammate(deps: Pick<TeamWriteDeps, 'leadSessionId' | 'mainViewCount' | 'openSession'>): (sessionId: SessionId, childSessionId: SessionId) => void;
|
|
101
|
+
/**
|
|
102
|
+
* Bind the page's face to one set of browser services.
|
|
103
|
+
* @param deps - the writes, refresh, and navigation the face performs.
|
|
104
|
+
* @returns the Slot `inject` factory: session and bound actions in, face out.
|
|
105
|
+
*/
|
|
106
|
+
export declare function teamWritesFace(deps: TeamWriteDeps): (sessionId: SessionId, actions: BoundActions<ReturnType<typeof createTeamPageStore>>) => TeamPageInjected;
|
|
107
|
+
//# sourceMappingURL=team-writes.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,95 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qilin-agent/experimental-client-ui-agent-team",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"description": "Web Agent Teams roster, task board, and teammate navigation",
|
|
4
|
+
"version": "3.1.4",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/kkutysllb/QiLin.git",
|
|
11
|
+
"directory": "packages/experimental/client-ui-agent-team"
|
|
12
|
+
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": "^22.19.0 || >=24.0.0"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "lib/index.js",
|
|
18
|
+
"types": "lib/types/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./lib/types/index.d.ts",
|
|
22
|
+
"default": "./lib/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./client": {
|
|
25
|
+
"types": "./lib/types/client/index.d.ts",
|
|
26
|
+
"default": "./lib/client.js"
|
|
27
|
+
},
|
|
28
|
+
"./src/*": "./src/*",
|
|
29
|
+
"./package.json": "./package.json"
|
|
30
|
+
},
|
|
31
|
+
"qilin": {
|
|
32
|
+
"client": {
|
|
33
|
+
"inject": [
|
|
34
|
+
"@qilin-agent/api-session-controller",
|
|
35
|
+
"@qilin-agent/client-locale",
|
|
36
|
+
"@qilin-agent/client-ui-conversation",
|
|
37
|
+
"@qilin-agent/client-ui-primitives",
|
|
38
|
+
"@qilin-agent/client-ui-workspace",
|
|
39
|
+
"@qilin-agent/api-remotes",
|
|
40
|
+
"@qilin-agent/client-ui-sidebar-right",
|
|
41
|
+
"@qilin-agent/experimental-agent-team"
|
|
42
|
+
],
|
|
43
|
+
"platform": "web"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"@qilin-agent/api-remotes": "3.1.4",
|
|
49
|
+
"@qilin-agent/api-session-controller": "3.1.4",
|
|
50
|
+
"@qilin-agent/client-locale": "3.1.4",
|
|
51
|
+
"@qilin-agent/client-ui-primitives": "3.1.4",
|
|
52
|
+
"@qilin-agent/client-ui-renderer": "3.1.4",
|
|
53
|
+
"@qilin-agent/client-ui-conversation": "3.1.4",
|
|
54
|
+
"@qilin-agent/client-ui-session": "3.1.4",
|
|
55
|
+
"@qilin-agent/client-ui-slots": "3.1.4",
|
|
56
|
+
"@qilin-agent/client-ui-workspace": "3.1.4",
|
|
57
|
+
"@qilin-agent/client-ui-sidebar-right": "3.1.4",
|
|
58
|
+
"@qilin-agent/kylin": "~4.0.3",
|
|
59
|
+
"@qilin-agent/session": "3.1.4",
|
|
60
|
+
"@qilin-agent/experimental-agent-team": "3.1.4",
|
|
61
|
+
"@qilin-agent/typert-protocol": "3.1.4"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@testing-library/react": "^16.1.0",
|
|
65
|
+
"@types/react": "~18.3.1",
|
|
66
|
+
"@types/react-dom": "~18.3.0",
|
|
67
|
+
"react": "^18.2.0",
|
|
68
|
+
"react-dom": "^18.2.0",
|
|
69
|
+
"@qilin-agent/api-remotes": "3.1.4",
|
|
70
|
+
"@qilin-agent/api-session-controller": "3.1.4",
|
|
71
|
+
"@qilin-agent/client-store": "3.1.4",
|
|
72
|
+
"@qilin-agent/client-test-runtime": "3.1.4",
|
|
73
|
+
"@qilin-agent/client-ui-conversation": "3.1.4",
|
|
74
|
+
"@qilin-agent/client-locale": "3.1.4",
|
|
75
|
+
"@qilin-agent/client-ui-primitives": "3.1.4",
|
|
76
|
+
"@qilin-agent/client-ui-renderer": "3.1.4",
|
|
77
|
+
"@qilin-agent/client-ui-sidebar-right": "3.1.4",
|
|
78
|
+
"@qilin-agent/client-ui-slots": "3.1.4",
|
|
79
|
+
"@qilin-agent/client-ui-workspace": "3.1.4",
|
|
80
|
+
"@qilin-agent/experimental-agent-team": "3.1.4",
|
|
81
|
+
"@qilin-agent/client-ui-session": "3.1.4",
|
|
82
|
+
"@qilin-agent/session": "3.1.4",
|
|
83
|
+
"@qilin-agent/typert-protocol": "3.1.4",
|
|
84
|
+
"@qilin-agent/kylin": "~4.0.3"
|
|
85
|
+
},
|
|
86
|
+
"files": [
|
|
87
|
+
"lib/index.js",
|
|
88
|
+
"lib/client.js",
|
|
89
|
+
"lib/types/**/*.d.ts"
|
|
90
|
+
],
|
|
91
|
+
"scripts": {
|
|
92
|
+
"bundle": "tsdown",
|
|
93
|
+
"watch": "tsdown --watch"
|
|
94
|
+
}
|
|
6
95
|
}
|