@suifei/dsh-ai-team 0.3.12 → 0.3.14
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/CHANGELOG.md +12 -0
- package/README.md +5 -3
- package/client.js +142 -12
- package/index.js +1 -1
- package/lib/host/service.js +2 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.14 — 2026-11-10
|
|
4
|
+
|
|
5
|
+
- 主对话顶部增加「团队动态」:显示正在推进的 Task、owner 和运行中的成员;
|
|
6
|
+
- 点击团队动态里的 Task 直接打开 Thread;没有 Task 时显示“成员已唤醒,正在拆解”;
|
|
7
|
+
- 解决 Human 发消息后主对话没有反馈、只能去任务看板找 Task 的问题。
|
|
8
|
+
|
|
9
|
+
## 0.3.13 — 2026-11-10
|
|
10
|
+
|
|
11
|
+
- 点击成员名字进入成员视图:该成员负责/执行的任务列表 + 直接对话 + 资料入口;
|
|
12
|
+
- 目录选择改用 `ctx.get('uiWorkspace').pickDirectory()`,修复「当前宿主不支持目录选择」;
|
|
13
|
+
- 选择目录取消不再误报为不支持;保留手填路径兜底。
|
|
14
|
+
|
|
3
15
|
## 0.3.12 — 2026-11-10
|
|
4
16
|
|
|
5
17
|
- 点击成员名字直接打开该 Agent 的 DSH 原生 Session,可与它直接对话;
|
package/README.md
CHANGED
|
@@ -84,11 +84,13 @@ dsh --profile ai-team --no-open --port 33271
|
|
|
84
84
|
└─────────────────┴────────────────────────────────────┴─────────────┘
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
- **主对话**:Human 的一句话进入 Main stream,Project owner 拆 Task
|
|
87
|
+
- **主对话**:Human 的一句话进入 Main stream,Project owner 拆 Task;顶部「团队动态」直接显示正在推进的 Task 和运行中的成员,点击 Task 可打开 Thread。
|
|
88
88
|
- **看板**:四列;进行中的卡片显示 accountable owner 与执行者;数量只统计 active Task。
|
|
89
89
|
- **态势**:四象限——需要你、团队在做、等待受阻、最近完成。点击条目打开对应 Task 的 Thread。
|
|
90
90
|
- **收件箱**:跨 Project 聚合;失败决策、需要你决定、关注 Task 的完成报告都在这里。
|
|
91
|
-
-
|
|
91
|
+
- **成员视图**:点击成员名字,切到他的任务列表与「直接对话」入口。
|
|
92
|
+
- **直接对话**:成员视图里点「直接对话」,打开该 Agent 的 DSH 原生 Session;没有 session 会先激活。
|
|
93
|
+
- **成员资料**:点「⋯」改名、职责、personality、provider/model、运行配方、notes、skills、re-distill、离队/人才库。
|
|
92
94
|
|
|
93
95
|
---
|
|
94
96
|
|
|
@@ -103,7 +105,7 @@ dsh --profile ai-team --no-open --port 33271
|
|
|
103
105
|
| 收件箱 | Human/Agent 各自拉取;跨 Project 聚合与项目内 ack |
|
|
104
106
|
| 关注 | 关注 Task;完成后收到 `followed_task_update` |
|
|
105
107
|
| 默认成员 | 新 Project 初始化墨渊 / 青岚 / 白砚;可改名、改职责、改个性、改模型 |
|
|
106
|
-
| 成员 | 持久 session
|
|
108
|
+
| 成员 | 持久 session;点击名字进入成员视图(任务 + 直接对话);「⋯」编辑资料 |
|
|
107
109
|
| 模型 | Provider / Model 下拉读取 DSH `llm` 目录;可跟随系统默认 |
|
|
108
110
|
| 进化 | `team.evolve` 只改自己的 personality;验收后 reflection wake |
|
|
109
111
|
| 人才库 | leave/rejoin;遗留 Task 可被接管(taken-over) |
|
package/client.js
CHANGED
|
@@ -183,6 +183,16 @@ window.__ModuleLoader__.load({
|
|
|
183
183
|
agentChat: '直接对话',
|
|
184
184
|
agentChatOpening: '正在打开对话…',
|
|
185
185
|
agentChatUnavailable: '宿主没有可用的 Session 打开能力。',
|
|
186
|
+
memberTasks: '他的任务',
|
|
187
|
+
memberNoTasks: '还没有属于他的 Task',
|
|
188
|
+
memberNoTasksBody: '在项目里创建或指派 Task 后,会出现在这里。',
|
|
189
|
+
taskOwner: '负责人',
|
|
190
|
+
taskAssignee: '执行',
|
|
191
|
+
teamPulseTitle: '团队动态',
|
|
192
|
+
teamPulseCount: '{n} 个 Task 正在推进',
|
|
193
|
+
teamPulseWorking: '成员已接单',
|
|
194
|
+
teamPulseStarting: '成员已唤醒,正在拆解任务…',
|
|
195
|
+
teamPulseAgents: '运行中:{names}',
|
|
186
196
|
newProject: '新建项目',
|
|
187
197
|
addAgent: '添加成员',
|
|
188
198
|
newProjectMock: 'spike:新建项目属于 S-01 流程,M1 之后接入。',
|
|
@@ -473,6 +483,16 @@ window.__ModuleLoader__.load({
|
|
|
473
483
|
agentChat: 'Direct chat',
|
|
474
484
|
agentChatOpening: 'Opening conversation…',
|
|
475
485
|
agentChatUnavailable: 'This host cannot open a Session.',
|
|
486
|
+
memberTasks: 'Their tasks',
|
|
487
|
+
memberNoTasks: 'No Task belongs to this member yet',
|
|
488
|
+
memberNoTasksBody: 'Create or assign a Task in the Project and it appears here.',
|
|
489
|
+
taskOwner: 'Owner',
|
|
490
|
+
taskAssignee: 'Assignee',
|
|
491
|
+
teamPulseTitle: 'Team activity',
|
|
492
|
+
teamPulseCount: '{n} Task(s) in motion',
|
|
493
|
+
teamPulseWorking: 'Members picked up the work',
|
|
494
|
+
teamPulseStarting: 'Members are awake and breaking the work down…',
|
|
495
|
+
teamPulseAgents: 'Running: {names}',
|
|
476
496
|
newProject: 'New project',
|
|
477
497
|
addAgent: 'Add member',
|
|
478
498
|
newProjectMock: 'spike: project creation belongs to S-01 and lands after M1.',
|
|
@@ -938,6 +958,32 @@ window.__ModuleLoader__.load({
|
|
|
938
958
|
.at-agentfail { flex: none; color: var(--dsw-alias-state-warn-primary); }
|
|
939
959
|
.at-agentmore { flex: 0 0 auto; width: 28px; height: 28px; border: 0; border-radius: var(--dsw-radius-sm); background: transparent; color: var(--dsw-alias-label-tertiary); font: inherit; font-size: 13px; cursor: pointer; }
|
|
940
960
|
.at-agentmore:hover { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-primary); }
|
|
961
|
+
.at-teampulse { width: 100%; max-width: 760px; margin: 4px auto 10px; padding: 10px 12px; border: 1px solid var(--dsw-alias-state-business-primary); border-radius: var(--dsw-radius-md); background: var(--dsw-alias-bg-module-platform); }
|
|
962
|
+
.at-teampulsehead { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
|
|
963
|
+
.at-teampulsetitle { font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-primary); }
|
|
964
|
+
.at-teampulsecount { font-size: 11px; color: var(--dsw-alias-state-business-primary); }
|
|
965
|
+
.at-teampulselist { display: flex; flex-direction: column; gap: 4px; }
|
|
966
|
+
.at-teampulsetask { display: flex; align-items: center; gap: 7px; width: 100%; padding: 4px 6px; border: 0; border-radius: var(--dsw-radius-sm); background: transparent; color: var(--dsw-alias-label-primary); font: inherit; text-align: left; cursor: pointer; }
|
|
967
|
+
.at-teampulsetask:hover { background: var(--dsw-alias-interactive-bg-hover); }
|
|
968
|
+
.at-teampulseno { flex: 0 0 auto; color: var(--dsw-alias-label-tertiary); font-size: 11px; font-variant-numeric: tabular-nums; }
|
|
969
|
+
.at-teampulsetasktitle { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
|
|
970
|
+
.at-teampulseowner { flex: 0 0 auto; color: var(--dsw-alias-label-tertiary); font-size: 11px; }
|
|
971
|
+
.at-teampulsehint { color: var(--dsw-alias-label-tertiary); font-size: 11px; line-height: 16px; }
|
|
972
|
+
.at-teampulseagents { margin-top: 6px; color: var(--dsw-alias-label-tertiary); font-size: 11px; line-height: 16px; }
|
|
973
|
+
.at-memberview { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 18px; }
|
|
974
|
+
.at-memberviewhead { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding-bottom: 12px; border-bottom: 1px solid var(--dsw-alias-border-l1); }
|
|
975
|
+
.at-memberviewid { display: flex; flex-direction: column; min-width: 0; flex: 1 1 180px; }
|
|
976
|
+
.at-memberviewid strong { font-size: 15px; line-height: 22px; }
|
|
977
|
+
.at-memberviewid span { color: var(--dsw-alias-label-tertiary); font-size: 11px; line-height: 16px; }
|
|
978
|
+
.at-memberviewactions { display: flex; gap: 6px; flex-wrap: wrap; }
|
|
979
|
+
.at-memberviewbody { max-width: 760px; margin: 0 auto; padding-top: 14px; }
|
|
980
|
+
.at-memberviewsub { color: var(--dsw-alias-label-tertiary); font-size: 12px; line-height: 18px; margin-bottom: 8px; }
|
|
981
|
+
.at-membertasklist { display: flex; flex-direction: column; gap: 6px; }
|
|
982
|
+
.at-membertask { display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 10px; border: 1px solid var(--dsw-alias-border-l1); border-radius: var(--dsw-radius-sm); background: var(--dsw-alias-bg-module-platform); color: var(--dsw-alias-label-primary); font: inherit; text-align: left; cursor: pointer; }
|
|
983
|
+
.at-membertask:hover { border-color: var(--dsw-alias-border-l2); background: var(--dsw-alias-interactive-bg-hover); }
|
|
984
|
+
.at-membertaskno { flex: 0 0 auto; color: var(--dsw-alias-label-tertiary); font-variant-numeric: tabular-nums; font-size: 11px; }
|
|
985
|
+
.at-membertasktitle { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
|
|
986
|
+
.at-membertaskmeta { flex: 0 0 auto; color: var(--dsw-alias-label-tertiary); font-size: 11px; }
|
|
941
987
|
.at-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
|
|
942
988
|
.at-chead { flex: 0 0 auto; padding: 14px 18px 0; }
|
|
943
989
|
.at-title { display: flex; align-items: baseline; gap: 8px; min-width: 0; color: var(--dsw-alias-label-primary); font-size: 16px; font-weight: 600; line-height: 22px; letter-spacing: -.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
@@ -1520,6 +1566,56 @@ window.__ModuleLoader__.load({
|
|
|
1520
1566
|
}, '⋯'));
|
|
1521
1567
|
}
|
|
1522
1568
|
|
|
1569
|
+
function TeamPulse({ t, agents, tasks, onOpen }) {
|
|
1570
|
+
const active = tasks.filter((task) => ['pending', 'in_progress', 'pending_acceptance'].includes(task.status)).slice(-5);
|
|
1571
|
+
const running = agents.filter((agent) => agent.status === 'running');
|
|
1572
|
+
if (active.length === 0 && running.length === 0) return null;
|
|
1573
|
+
return h('section', { className: 'at-teampulse', 'aria-label': t('teamPulseTitle') },
|
|
1574
|
+
h('div', { className: 'at-teampulsehead' },
|
|
1575
|
+
h('span', { className: 'at-teampulsetitle' }, t('teamPulseTitle')),
|
|
1576
|
+
h('span', { className: 'at-teampulsecount' }, active.length ? t('teamPulseCount').replace('{n}', String(active.length)) : t('teamPulseWorking'))),
|
|
1577
|
+
active.length
|
|
1578
|
+
? h('div', { className: 'at-teampulselist' }, active.map((task) => h('button', {
|
|
1579
|
+
key: task.id,
|
|
1580
|
+
className: 'at-teampulsetask',
|
|
1581
|
+
type: 'button',
|
|
1582
|
+
onClick: () => onOpen(task),
|
|
1583
|
+
},
|
|
1584
|
+
h('span', { className: 'at-teampulseno' }, '#' + taskNo(task)),
|
|
1585
|
+
h('span', { className: 'at-teampulsetasktitle' }, task.title),
|
|
1586
|
+
h(StatusPill, { t, status: task.status }),
|
|
1587
|
+
h('span', { className: 'at-teampulseowner' }, task.owner ?? ''))))
|
|
1588
|
+
: h('div', { className: 'at-teampulsehint' }, t('teamPulseStarting')),
|
|
1589
|
+
running.length ? h('div', { className: 'at-teampulseagents' }, t('teamPulseAgents').replace('{names}', running.map((agent) => agent.name).join('、'))) : null);
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
function MemberView({ t, agent, tasks, onBack, onOpenTask, onOpenChat, onOpenProfile }) {
|
|
1593
|
+
return h('div', { className: 'at-memberview' },
|
|
1594
|
+
h('div', { className: 'at-memberviewhead' },
|
|
1595
|
+
h('button', { className: 'at-btn at-btn-small', type: 'button', onClick: onBack }, '← ' + t('back')),
|
|
1596
|
+
h('span', { className: 'at-dot at-dot-' + (agent.status ?? 'idle'), 'aria-hidden': 'true' }),
|
|
1597
|
+
h('div', { className: 'at-memberviewid' },
|
|
1598
|
+
h('strong', null, agent.name),
|
|
1599
|
+
h('span', null, (agent.role ?? '') + (agent.qa ? ' · QA' : '') + ' · ' + t(AGENT_STATUS[agent.status] ?? 'agentIdle'))),
|
|
1600
|
+
h('div', { className: 'at-memberviewactions' },
|
|
1601
|
+
h('button', { className: 'at-btn at-btn-small at-btn-primary', type: 'button', onClick: () => onOpenChat(agent) }, t('agentChat')),
|
|
1602
|
+
h('button', { className: 'at-btn at-btn-small', type: 'button', onClick: () => onOpenProfile(agent) }, t('memberProfileTitle')))),
|
|
1603
|
+
h('div', { className: 'at-memberviewbody' },
|
|
1604
|
+
h('div', { className: 'at-memberviewsub' }, t('memberTasks') + ' · ' + tasks.length),
|
|
1605
|
+
tasks.length
|
|
1606
|
+
? h('div', { className: 'at-membertasklist' }, tasks.map((task) => h('button', {
|
|
1607
|
+
key: task.id,
|
|
1608
|
+
className: 'at-membertask',
|
|
1609
|
+
type: 'button',
|
|
1610
|
+
onClick: () => onOpenTask(task),
|
|
1611
|
+
},
|
|
1612
|
+
h('span', { className: 'at-membertaskno' }, '#' + taskNo(task)),
|
|
1613
|
+
h('span', { className: 'at-membertasktitle' }, task.title),
|
|
1614
|
+
h(StatusPill, { t, status: task.status }),
|
|
1615
|
+
h('span', { className: 'at-membertaskmeta' }, task.ownerId === agent.id ? t('taskOwner') : t('taskAssignee')))))
|
|
1616
|
+
: h(EmptyState, { t, title: t('memberNoTasks'), body: t('memberNoTasksBody'), compact: true })));
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1523
1619
|
function LeftPanel({ t, data, projectId, scope, tab, inboxUnread, onBack, onInbox, onBoard, onProject, onNewProject, onAgent, onAgentMore, onAddAgent, onRecruit }) {
|
|
1524
1620
|
const projects = data.projects.filter((project) => !project.archived);
|
|
1525
1621
|
const activeAgents = data.agents.filter((agent) => agent.status !== 'retired');
|
|
@@ -1994,6 +2090,7 @@ window.__ModuleLoader__.load({
|
|
|
1994
2090
|
const [workspaceDraft, setWorkspaceDraft] = React.useState('');
|
|
1995
2091
|
const [workspaceError, setWorkspaceError] = React.useState('');
|
|
1996
2092
|
const [workspaceBusy, setWorkspaceBusy] = React.useState(false);
|
|
2093
|
+
const [memberViewId, setMemberViewId] = React.useState(null);
|
|
1997
2094
|
const [nBusy, setNBusy] = React.useState(false);
|
|
1998
2095
|
const [nError, setNError] = React.useState('');
|
|
1999
2096
|
const [pSuccessor, setPSuccessor] = React.useState('');
|
|
@@ -2204,6 +2301,7 @@ window.__ModuleLoader__.load({
|
|
|
2204
2301
|
}
|
|
2205
2302
|
function goConversation() {
|
|
2206
2303
|
closeMobile();
|
|
2304
|
+
setMemberViewId(null);
|
|
2207
2305
|
setScope('project');
|
|
2208
2306
|
setTab('main');
|
|
2209
2307
|
setThreadOpen(false);
|
|
@@ -2215,6 +2313,7 @@ window.__ModuleLoader__.load({
|
|
|
2215
2313
|
}
|
|
2216
2314
|
function switchInbox() {
|
|
2217
2315
|
closeMobile();
|
|
2316
|
+
setMemberViewId(null);
|
|
2218
2317
|
setScope('inbox');
|
|
2219
2318
|
setThreadOpen(false);
|
|
2220
2319
|
setNote('');
|
|
@@ -2233,6 +2332,7 @@ window.__ModuleLoader__.load({
|
|
|
2233
2332
|
await runCommand('project.activate', { projectId: next.id });
|
|
2234
2333
|
setScope('project');
|
|
2235
2334
|
setTab('main');
|
|
2335
|
+
setMemberViewId(null);
|
|
2236
2336
|
setBoardFilter('all');
|
|
2237
2337
|
setThreadOpen(false);
|
|
2238
2338
|
setReply('');
|
|
@@ -2251,17 +2351,21 @@ window.__ModuleLoader__.load({
|
|
|
2251
2351
|
setNewOpen(true);
|
|
2252
2352
|
}
|
|
2253
2353
|
async function pickWorkspacePath() {
|
|
2354
|
+
const service = ctx?.get?.('uiWorkspace') ?? ctx?.uiWorkspace;
|
|
2355
|
+
if (service === undefined || service === null || typeof service.pickDirectory !== 'function') {
|
|
2356
|
+
return { error: 'unavailable', path: null };
|
|
2357
|
+
}
|
|
2254
2358
|
try {
|
|
2255
|
-
|
|
2256
|
-
return picked ?? null;
|
|
2359
|
+
return { path: await service.pickDirectory(), error: null };
|
|
2257
2360
|
} catch {
|
|
2258
|
-
return null;
|
|
2361
|
+
return { error: 'failed', path: null };
|
|
2259
2362
|
}
|
|
2260
2363
|
}
|
|
2261
2364
|
async function pickNewWorkspace() {
|
|
2262
2365
|
const picked = await pickWorkspacePath();
|
|
2263
|
-
if (picked) setNWorkspace(picked);
|
|
2264
|
-
else setNError(t('workspacePickUnavailable'));
|
|
2366
|
+
if (picked.path) setNWorkspace(picked.path);
|
|
2367
|
+
else if (picked.error === 'unavailable') setNError(t('workspacePickUnavailable'));
|
|
2368
|
+
else if (picked.error === 'failed') setNError(t('workspacePickFailed'));
|
|
2265
2369
|
}
|
|
2266
2370
|
function openWorkspaceEditor() {
|
|
2267
2371
|
setWorkspaceDraft(project?.workspacePath ?? '');
|
|
@@ -2270,8 +2374,9 @@ window.__ModuleLoader__.load({
|
|
|
2270
2374
|
}
|
|
2271
2375
|
async function pickProjectWorkspace() {
|
|
2272
2376
|
const picked = await pickWorkspacePath();
|
|
2273
|
-
if (picked) setWorkspaceDraft(picked);
|
|
2274
|
-
else setWorkspaceError(t('workspacePickUnavailable'));
|
|
2377
|
+
if (picked.path) setWorkspaceDraft(picked.path);
|
|
2378
|
+
else if (picked.error === 'unavailable') setWorkspaceError(t('workspacePickUnavailable'));
|
|
2379
|
+
else if (picked.error === 'failed') setWorkspaceError(t('workspacePickFailed'));
|
|
2275
2380
|
}
|
|
2276
2381
|
async function saveWorkspace() {
|
|
2277
2382
|
if (!project || workspaceBusy || !workspaceDraft.trim()) return;
|
|
@@ -2395,15 +2500,27 @@ window.__ModuleLoader__.load({
|
|
|
2395
2500
|
setMBusy(false);
|
|
2396
2501
|
}
|
|
2397
2502
|
}
|
|
2503
|
+
function openMemberView(agent) {
|
|
2504
|
+
closeMobile();
|
|
2505
|
+
setMemberViewId(agent.id);
|
|
2506
|
+
setScope('project');
|
|
2507
|
+
setTab('main');
|
|
2508
|
+
setThreadOpen(false);
|
|
2509
|
+
setNote('');
|
|
2510
|
+
}
|
|
2511
|
+
function closeMemberView() {
|
|
2512
|
+
setMemberViewId(null);
|
|
2513
|
+
}
|
|
2398
2514
|
async function openAgentChat(agent) {
|
|
2399
2515
|
closeMobile();
|
|
2400
|
-
|
|
2516
|
+
const service = ctx?.get?.('uiWorkspace') ?? ctx?.uiWorkspace;
|
|
2517
|
+
if (service?.openSession === undefined) {
|
|
2401
2518
|
say(t('agentChatUnavailable'));
|
|
2402
2519
|
openProfile(agent);
|
|
2403
2520
|
return;
|
|
2404
2521
|
}
|
|
2405
2522
|
if (agent.sessionId) {
|
|
2406
|
-
|
|
2523
|
+
service.openSession(agent.sessionId);
|
|
2407
2524
|
return;
|
|
2408
2525
|
}
|
|
2409
2526
|
try {
|
|
@@ -2413,7 +2530,7 @@ window.__ModuleLoader__.load({
|
|
|
2413
2530
|
prompt: '你正在与 Human 直接对话。先简要说明你是谁、当前负责什么;不要创建 Task,除非 Human 明确要求。',
|
|
2414
2531
|
});
|
|
2415
2532
|
await reloadData();
|
|
2416
|
-
if (activated?.sessionId)
|
|
2533
|
+
if (activated?.sessionId) service.openSession(activated.sessionId);
|
|
2417
2534
|
} catch (error) {
|
|
2418
2535
|
say(tf(t, 'sendFailed', { message: error?.message ?? String(error) }));
|
|
2419
2536
|
openProfile(agent);
|
|
@@ -2767,6 +2884,8 @@ window.__ModuleLoader__.load({
|
|
|
2767
2884
|
}
|
|
2768
2885
|
|
|
2769
2886
|
const inInbox = scope === 'inbox';
|
|
2887
|
+
const memberViewAgent = data.agents.find((agent) => agent.id === memberViewId) ?? null;
|
|
2888
|
+
const memberViewTasks = memberViewAgent === null ? [] : tasks.filter((task) => task.ownerId === memberViewAgent.id || task.assigneeId === memberViewAgent.id);
|
|
2770
2889
|
const headerTitle = inInbox ? t('inboxTitle') : project ? '# ' + project.name : t('noProject');
|
|
2771
2890
|
const headerGoal = inInbox ? t('inboxGoal') : (project?.goal ?? '');
|
|
2772
2891
|
const unread = inboxUnread > 99 ? '99+' : inboxUnread;
|
|
@@ -2783,7 +2902,7 @@ window.__ModuleLoader__.load({
|
|
|
2783
2902
|
onBoard: switchBoard,
|
|
2784
2903
|
onProject: switchProject,
|
|
2785
2904
|
onNewProject: () => { closeMobile(); openNewProject(); },
|
|
2786
|
-
onAgent: (agent) => { closeMobile();
|
|
2905
|
+
onAgent: (agent) => { closeMobile(); openMemberView(agent); },
|
|
2787
2906
|
onAgentMore: (agent) => { closeMobile(); openProfile(agent); },
|
|
2788
2907
|
onAddAgent: () => { closeMobile(); openAddAgent(); },
|
|
2789
2908
|
onRecruit: (agent) => { closeMobile(); recruit(agent); },
|
|
@@ -2818,6 +2937,16 @@ window.__ModuleLoader__.load({
|
|
|
2818
2937
|
body: t('inboxEmptyBody'),
|
|
2819
2938
|
action: { label: t('inboxEmptyAction'), onClick: switchBoard },
|
|
2820
2939
|
})))
|
|
2940
|
+
: memberViewAgent && tab === 'main'
|
|
2941
|
+
? h(MemberView, {
|
|
2942
|
+
t,
|
|
2943
|
+
agent: memberViewAgent,
|
|
2944
|
+
tasks: memberViewTasks,
|
|
2945
|
+
onBack: closeMemberView,
|
|
2946
|
+
onOpenTask: openTask,
|
|
2947
|
+
onOpenChat: (agent) => { void openAgentChat(agent); },
|
|
2948
|
+
onOpenProfile: openProfile,
|
|
2949
|
+
})
|
|
2821
2950
|
: tab === 'board'
|
|
2822
2951
|
? h(Board, {
|
|
2823
2952
|
t,
|
|
@@ -2837,6 +2966,7 @@ window.__ModuleLoader__.load({
|
|
|
2837
2966
|
? h(Situation, { t, quadrants, tasks, onItem: openQuadrantItem, onViewAll: viewQuadrant })
|
|
2838
2967
|
: h('div', { className: 'at-stream', role: 'tabpanel', id: 'at-panel-main', 'aria-labelledby': 'at-tab-main' },
|
|
2839
2968
|
h('div', { className: 'at-streaminner', role: 'log', 'aria-live': 'polite', 'aria-label': t('streamAria') },
|
|
2969
|
+
h(TeamPulse, { t, agents: data.agents, tasks, onOpen: openTask }),
|
|
2840
2970
|
data.stream.length
|
|
2841
2971
|
? data.stream.map((item) => h(StreamMessage, {
|
|
2842
2972
|
key: item.id,
|
|
@@ -2914,7 +3044,7 @@ window.__ModuleLoader__.load({
|
|
|
2914
3044
|
h('span', { className: 'at-notetext' }, note),
|
|
2915
3045
|
h('button', { className: 'at-noteclose', type: 'button', 'aria-label': t('dismiss'), title: t('dismiss'), onClick: () => setNote('') }, h(Ico, { name: 'close', size: 12 })))) : null,
|
|
2916
3046
|
body,
|
|
2917
|
-
!inInbox && tab === 'main' ? h(Composer, {
|
|
3047
|
+
!inInbox && tab === 'main' && !memberViewAgent ? h(Composer, {
|
|
2918
3048
|
t,
|
|
2919
3049
|
mode,
|
|
2920
3050
|
draft,
|
package/index.js
CHANGED
|
@@ -33,7 +33,7 @@ export const name = 'ai-team';
|
|
|
33
33
|
/** The workbench only makes sense where the Web carrier exists. */
|
|
34
34
|
export const inject = ['webServer', 'permissionPresets', 'sandboxPolicy'];
|
|
35
35
|
|
|
36
|
-
const VERSION = '0.3.
|
|
36
|
+
const VERSION = '0.3.14';
|
|
37
37
|
const PROJECT_ID = 'prj_main';
|
|
38
38
|
const HUMAN_ID = 'mem_human';
|
|
39
39
|
|
package/lib/host/service.js
CHANGED
|
@@ -101,7 +101,9 @@ export class TeamService {
|
|
|
101
101
|
title: task.title,
|
|
102
102
|
status: task.status,
|
|
103
103
|
owner: state.members?.[task.ownerId]?.name ?? task.ownerId,
|
|
104
|
+
ownerId: task.ownerId,
|
|
104
105
|
assignee: task.assigneeId === null || task.assigneeId === undefined ? null : (state.members?.[task.assigneeId]?.name ?? task.assigneeId),
|
|
106
|
+
assigneeId: task.assigneeId ?? null,
|
|
105
107
|
replies: state.threads?.[task.id]?.headSeq ?? 0,
|
|
106
108
|
following: (state.followers?.[task.id] ?? []).length > 0,
|
|
107
109
|
blockedBy: task.blockedBy ?? [],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suifei/dsh-ai-team",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "文渊阁 (Wenyuan Pavilion) — AI Team mode for DeepSeek Harness: concurrent projects, owned tasks, threads, inbox and an append-only team ledger",
|
|
6
6
|
"license": "MIT",
|