@suifei/dsh-ai-team 0.3.11 → 0.3.13
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 +4 -2
- package/client.js +131 -15
- 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.13 — 2026-11-10
|
|
4
|
+
|
|
5
|
+
- 点击成员名字进入成员视图:该成员负责/执行的任务列表 + 直接对话 + 资料入口;
|
|
6
|
+
- 目录选择改用 `ctx.get('uiWorkspace').pickDirectory()`,修复「当前宿主不支持目录选择」;
|
|
7
|
+
- 选择目录取消不再误报为不支持;保留手填路径兜底。
|
|
8
|
+
|
|
9
|
+
## 0.3.12 — 2026-11-10
|
|
10
|
+
|
|
11
|
+
- 点击成员名字直接打开该 Agent 的 DSH 原生 Session,可与它直接对话;
|
|
12
|
+
- 没有 session 的空闲成员会先激活再打开;
|
|
13
|
+
- 「⋯」仍打开成员资料,资料内也增加「直接对话」按钮。
|
|
14
|
+
|
|
3
15
|
## 0.3.11 — 2026-11-10
|
|
4
16
|
|
|
5
17
|
- 修复空闲默认成员不接收 Main stream:owner 无 session 时先自动激活,再记录 `wake/delivered`;
|
package/README.md
CHANGED
|
@@ -88,7 +88,9 @@ dsh --profile ai-team --no-open --port 33271
|
|
|
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
|
@@ -178,8 +178,16 @@ window.__ModuleLoader__.load({
|
|
|
178
178
|
projectSwitchMock: 'spike:项目切换只更新视图标题;按项目读取账本在 M1 接入。',
|
|
179
179
|
archivedMock: 'spike:归档项目只读;取消归档在 M3 接入。',
|
|
180
180
|
agentMock: 'spike:成员详情(打开会话 / 发消息 / 记忆与技能)在 M3 接入。',
|
|
181
|
-
agentOpen: '
|
|
181
|
+
agentOpen: '与 {name} 对话',
|
|
182
182
|
moreActions: '更多操作',
|
|
183
|
+
agentChat: '直接对话',
|
|
184
|
+
agentChatOpening: '正在打开对话…',
|
|
185
|
+
agentChatUnavailable: '宿主没有可用的 Session 打开能力。',
|
|
186
|
+
memberTasks: '他的任务',
|
|
187
|
+
memberNoTasks: '还没有属于他的 Task',
|
|
188
|
+
memberNoTasksBody: '在项目里创建或指派 Task 后,会出现在这里。',
|
|
189
|
+
taskOwner: '负责人',
|
|
190
|
+
taskAssignee: '执行',
|
|
183
191
|
newProject: '新建项目',
|
|
184
192
|
addAgent: '添加成员',
|
|
185
193
|
newProjectMock: 'spike:新建项目属于 S-01 流程,M1 之后接入。',
|
|
@@ -465,8 +473,16 @@ window.__ModuleLoader__.load({
|
|
|
465
473
|
projectSwitchMock: 'spike: switching projects only updates the header; per-project ledger reads land with M1.',
|
|
466
474
|
archivedMock: 'spike: archived projects are read-only; unarchive lands with M3.',
|
|
467
475
|
agentMock: 'spike: member detail (open session / message / memory & skills) lands with M3.',
|
|
468
|
-
agentOpen: '
|
|
476
|
+
agentOpen: 'Chat with {name}',
|
|
469
477
|
moreActions: 'More actions',
|
|
478
|
+
agentChat: 'Direct chat',
|
|
479
|
+
agentChatOpening: 'Opening conversation…',
|
|
480
|
+
agentChatUnavailable: 'This host cannot open a Session.',
|
|
481
|
+
memberTasks: 'Their tasks',
|
|
482
|
+
memberNoTasks: 'No Task belongs to this member yet',
|
|
483
|
+
memberNoTasksBody: 'Create or assign a Task in the Project and it appears here.',
|
|
484
|
+
taskOwner: 'Owner',
|
|
485
|
+
taskAssignee: 'Assignee',
|
|
470
486
|
newProject: 'New project',
|
|
471
487
|
addAgent: 'Add member',
|
|
472
488
|
newProjectMock: 'spike: project creation belongs to S-01 and lands after M1.',
|
|
@@ -932,6 +948,20 @@ window.__ModuleLoader__.load({
|
|
|
932
948
|
.at-agentfail { flex: none; color: var(--dsw-alias-state-warn-primary); }
|
|
933
949
|
.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; }
|
|
934
950
|
.at-agentmore:hover { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-primary); }
|
|
951
|
+
.at-memberview { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 18px; }
|
|
952
|
+
.at-memberviewhead { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding-bottom: 12px; border-bottom: 1px solid var(--dsw-alias-border-l1); }
|
|
953
|
+
.at-memberviewid { display: flex; flex-direction: column; min-width: 0; flex: 1 1 180px; }
|
|
954
|
+
.at-memberviewid strong { font-size: 15px; line-height: 22px; }
|
|
955
|
+
.at-memberviewid span { color: var(--dsw-alias-label-tertiary); font-size: 11px; line-height: 16px; }
|
|
956
|
+
.at-memberviewactions { display: flex; gap: 6px; flex-wrap: wrap; }
|
|
957
|
+
.at-memberviewbody { max-width: 760px; margin: 0 auto; padding-top: 14px; }
|
|
958
|
+
.at-memberviewsub { color: var(--dsw-alias-label-tertiary); font-size: 12px; line-height: 18px; margin-bottom: 8px; }
|
|
959
|
+
.at-membertasklist { display: flex; flex-direction: column; gap: 6px; }
|
|
960
|
+
.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; }
|
|
961
|
+
.at-membertask:hover { border-color: var(--dsw-alias-border-l2); background: var(--dsw-alias-interactive-bg-hover); }
|
|
962
|
+
.at-membertaskno { flex: 0 0 auto; color: var(--dsw-alias-label-tertiary); font-variant-numeric: tabular-nums; font-size: 11px; }
|
|
963
|
+
.at-membertasktitle { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
|
|
964
|
+
.at-membertaskmeta { flex: 0 0 auto; color: var(--dsw-alias-label-tertiary); font-size: 11px; }
|
|
935
965
|
.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; }
|
|
936
966
|
.at-chead { flex: 0 0 auto; padding: 14px 18px 0; }
|
|
937
967
|
.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; }
|
|
@@ -1482,7 +1512,7 @@ window.__ModuleLoader__.load({
|
|
|
1482
1512
|
h('span', { className: 'at-prowtitle' }, project.name));
|
|
1483
1513
|
}
|
|
1484
1514
|
|
|
1485
|
-
function AgentRow({ t, agent, onAgent }) {
|
|
1515
|
+
function AgentRow({ t, agent, onAgent, onAgentMore }) {
|
|
1486
1516
|
const statusText = t(AGENT_STATUS[agent.status] ?? 'agentIdle');
|
|
1487
1517
|
const config = agent.config ?? null;
|
|
1488
1518
|
const model = config?.model ? config.model : t('agentDefaultModel');
|
|
@@ -1510,11 +1540,38 @@ window.__ModuleLoader__.load({
|
|
|
1510
1540
|
type: 'button',
|
|
1511
1541
|
'aria-label': tf(t, 'agentOpen', { name: agent.name }),
|
|
1512
1542
|
title: t('moreActions'),
|
|
1513
|
-
onClick: () =>
|
|
1543
|
+
onClick: () => onAgentMore(agent),
|
|
1514
1544
|
}, '⋯'));
|
|
1515
1545
|
}
|
|
1516
1546
|
|
|
1517
|
-
function
|
|
1547
|
+
function MemberView({ t, agent, tasks, onBack, onOpenTask, onOpenChat, onOpenProfile }) {
|
|
1548
|
+
return h('div', { className: 'at-memberview' },
|
|
1549
|
+
h('div', { className: 'at-memberviewhead' },
|
|
1550
|
+
h('button', { className: 'at-btn at-btn-small', type: 'button', onClick: onBack }, '← ' + t('back')),
|
|
1551
|
+
h('span', { className: 'at-dot at-dot-' + (agent.status ?? 'idle'), 'aria-hidden': 'true' }),
|
|
1552
|
+
h('div', { className: 'at-memberviewid' },
|
|
1553
|
+
h('strong', null, agent.name),
|
|
1554
|
+
h('span', null, (agent.role ?? '') + (agent.qa ? ' · QA' : '') + ' · ' + t(AGENT_STATUS[agent.status] ?? 'agentIdle'))),
|
|
1555
|
+
h('div', { className: 'at-memberviewactions' },
|
|
1556
|
+
h('button', { className: 'at-btn at-btn-small at-btn-primary', type: 'button', onClick: () => onOpenChat(agent) }, t('agentChat')),
|
|
1557
|
+
h('button', { className: 'at-btn at-btn-small', type: 'button', onClick: () => onOpenProfile(agent) }, t('memberProfileTitle')))),
|
|
1558
|
+
h('div', { className: 'at-memberviewbody' },
|
|
1559
|
+
h('div', { className: 'at-memberviewsub' }, t('memberTasks') + ' · ' + tasks.length),
|
|
1560
|
+
tasks.length
|
|
1561
|
+
? h('div', { className: 'at-membertasklist' }, tasks.map((task) => h('button', {
|
|
1562
|
+
key: task.id,
|
|
1563
|
+
className: 'at-membertask',
|
|
1564
|
+
type: 'button',
|
|
1565
|
+
onClick: () => onOpenTask(task),
|
|
1566
|
+
},
|
|
1567
|
+
h('span', { className: 'at-membertaskno' }, '#' + taskNo(task)),
|
|
1568
|
+
h('span', { className: 'at-membertasktitle' }, task.title),
|
|
1569
|
+
h(StatusPill, { t, status: task.status }),
|
|
1570
|
+
h('span', { className: 'at-membertaskmeta' }, task.ownerId === agent.id ? t('taskOwner') : t('taskAssignee')))))
|
|
1571
|
+
: h(EmptyState, { t, title: t('memberNoTasks'), body: t('memberNoTasksBody'), compact: true })));
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
function LeftPanel({ t, data, projectId, scope, tab, inboxUnread, onBack, onInbox, onBoard, onProject, onNewProject, onAgent, onAgentMore, onAddAgent, onRecruit }) {
|
|
1518
1575
|
const projects = data.projects.filter((project) => !project.archived);
|
|
1519
1576
|
const activeAgents = data.agents.filter((agent) => agent.status !== 'retired');
|
|
1520
1577
|
const talentAgents = data.agents.filter((agent) => agent.status === 'retired');
|
|
@@ -1564,7 +1621,7 @@ window.__ModuleLoader__.load({
|
|
|
1564
1621
|
h('button', { className: 'at-mini', type: 'button', 'aria-label': t('addAgent'), title: t('addAgent'), onClick: onAddAgent }, h(Ico, { name: 'plus', size: 12 })),
|
|
1565
1622
|
),
|
|
1566
1623
|
activeAgents.length
|
|
1567
|
-
? h('div', { role: 'list', 'aria-label': t('agentsAria') }, activeAgents.map((agent) => h(AgentRow, { key: agent.id, t, agent, onAgent })))
|
|
1624
|
+
? h('div', { role: 'list', 'aria-label': t('agentsAria') }, activeAgents.map((agent) => h(AgentRow, { key: agent.id, t, agent, onAgent, onAgentMore })))
|
|
1568
1625
|
: h('div', { className: 'at-colempty' }, t('emptyColumn')),
|
|
1569
1626
|
talentAgents.length ? h('details', { className: 'at-archived' },
|
|
1570
1627
|
h('summary', null, tf(t, 'talentPoolCount', { n: talentAgents.length })),
|
|
@@ -1988,6 +2045,7 @@ window.__ModuleLoader__.load({
|
|
|
1988
2045
|
const [workspaceDraft, setWorkspaceDraft] = React.useState('');
|
|
1989
2046
|
const [workspaceError, setWorkspaceError] = React.useState('');
|
|
1990
2047
|
const [workspaceBusy, setWorkspaceBusy] = React.useState(false);
|
|
2048
|
+
const [memberViewId, setMemberViewId] = React.useState(null);
|
|
1991
2049
|
const [nBusy, setNBusy] = React.useState(false);
|
|
1992
2050
|
const [nError, setNError] = React.useState('');
|
|
1993
2051
|
const [pSuccessor, setPSuccessor] = React.useState('');
|
|
@@ -2198,6 +2256,7 @@ window.__ModuleLoader__.load({
|
|
|
2198
2256
|
}
|
|
2199
2257
|
function goConversation() {
|
|
2200
2258
|
closeMobile();
|
|
2259
|
+
setMemberViewId(null);
|
|
2201
2260
|
setScope('project');
|
|
2202
2261
|
setTab('main');
|
|
2203
2262
|
setThreadOpen(false);
|
|
@@ -2209,6 +2268,7 @@ window.__ModuleLoader__.load({
|
|
|
2209
2268
|
}
|
|
2210
2269
|
function switchInbox() {
|
|
2211
2270
|
closeMobile();
|
|
2271
|
+
setMemberViewId(null);
|
|
2212
2272
|
setScope('inbox');
|
|
2213
2273
|
setThreadOpen(false);
|
|
2214
2274
|
setNote('');
|
|
@@ -2227,6 +2287,7 @@ window.__ModuleLoader__.load({
|
|
|
2227
2287
|
await runCommand('project.activate', { projectId: next.id });
|
|
2228
2288
|
setScope('project');
|
|
2229
2289
|
setTab('main');
|
|
2290
|
+
setMemberViewId(null);
|
|
2230
2291
|
setBoardFilter('all');
|
|
2231
2292
|
setThreadOpen(false);
|
|
2232
2293
|
setReply('');
|
|
@@ -2245,17 +2306,21 @@ window.__ModuleLoader__.load({
|
|
|
2245
2306
|
setNewOpen(true);
|
|
2246
2307
|
}
|
|
2247
2308
|
async function pickWorkspacePath() {
|
|
2309
|
+
const service = ctx?.get?.('uiWorkspace') ?? ctx?.uiWorkspace;
|
|
2310
|
+
if (service === undefined || service === null || typeof service.pickDirectory !== 'function') {
|
|
2311
|
+
return { error: 'unavailable', path: null };
|
|
2312
|
+
}
|
|
2248
2313
|
try {
|
|
2249
|
-
|
|
2250
|
-
return picked ?? null;
|
|
2314
|
+
return { path: await service.pickDirectory(), error: null };
|
|
2251
2315
|
} catch {
|
|
2252
|
-
return null;
|
|
2316
|
+
return { error: 'failed', path: null };
|
|
2253
2317
|
}
|
|
2254
2318
|
}
|
|
2255
2319
|
async function pickNewWorkspace() {
|
|
2256
2320
|
const picked = await pickWorkspacePath();
|
|
2257
|
-
if (picked) setNWorkspace(picked);
|
|
2258
|
-
else setNError(t('workspacePickUnavailable'));
|
|
2321
|
+
if (picked.path) setNWorkspace(picked.path);
|
|
2322
|
+
else if (picked.error === 'unavailable') setNError(t('workspacePickUnavailable'));
|
|
2323
|
+
else if (picked.error === 'failed') setNError(t('workspacePickFailed'));
|
|
2259
2324
|
}
|
|
2260
2325
|
function openWorkspaceEditor() {
|
|
2261
2326
|
setWorkspaceDraft(project?.workspacePath ?? '');
|
|
@@ -2264,8 +2329,9 @@ window.__ModuleLoader__.load({
|
|
|
2264
2329
|
}
|
|
2265
2330
|
async function pickProjectWorkspace() {
|
|
2266
2331
|
const picked = await pickWorkspacePath();
|
|
2267
|
-
if (picked) setWorkspaceDraft(picked);
|
|
2268
|
-
else setWorkspaceError(t('workspacePickUnavailable'));
|
|
2332
|
+
if (picked.path) setWorkspaceDraft(picked.path);
|
|
2333
|
+
else if (picked.error === 'unavailable') setWorkspaceError(t('workspacePickUnavailable'));
|
|
2334
|
+
else if (picked.error === 'failed') setWorkspaceError(t('workspacePickFailed'));
|
|
2269
2335
|
}
|
|
2270
2336
|
async function saveWorkspace() {
|
|
2271
2337
|
if (!project || workspaceBusy || !workspaceDraft.trim()) return;
|
|
@@ -2389,6 +2455,42 @@ window.__ModuleLoader__.load({
|
|
|
2389
2455
|
setMBusy(false);
|
|
2390
2456
|
}
|
|
2391
2457
|
}
|
|
2458
|
+
function openMemberView(agent) {
|
|
2459
|
+
closeMobile();
|
|
2460
|
+
setMemberViewId(agent.id);
|
|
2461
|
+
setScope('project');
|
|
2462
|
+
setTab('main');
|
|
2463
|
+
setThreadOpen(false);
|
|
2464
|
+
setNote('');
|
|
2465
|
+
}
|
|
2466
|
+
function closeMemberView() {
|
|
2467
|
+
setMemberViewId(null);
|
|
2468
|
+
}
|
|
2469
|
+
async function openAgentChat(agent) {
|
|
2470
|
+
closeMobile();
|
|
2471
|
+
const service = ctx?.get?.('uiWorkspace') ?? ctx?.uiWorkspace;
|
|
2472
|
+
if (service?.openSession === undefined) {
|
|
2473
|
+
say(t('agentChatUnavailable'));
|
|
2474
|
+
openProfile(agent);
|
|
2475
|
+
return;
|
|
2476
|
+
}
|
|
2477
|
+
if (agent.sessionId) {
|
|
2478
|
+
service.openSession(agent.sessionId);
|
|
2479
|
+
return;
|
|
2480
|
+
}
|
|
2481
|
+
try {
|
|
2482
|
+
say(t('agentChatOpening'));
|
|
2483
|
+
const activated = await runCommand('member.activate', {
|
|
2484
|
+
memberId: agent.id,
|
|
2485
|
+
prompt: '你正在与 Human 直接对话。先简要说明你是谁、当前负责什么;不要创建 Task,除非 Human 明确要求。',
|
|
2486
|
+
});
|
|
2487
|
+
await reloadData();
|
|
2488
|
+
if (activated?.sessionId) service.openSession(activated.sessionId);
|
|
2489
|
+
} catch (error) {
|
|
2490
|
+
say(tf(t, 'sendFailed', { message: error?.message ?? String(error) }));
|
|
2491
|
+
openProfile(agent);
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2392
2494
|
function openProfile(agent) {
|
|
2393
2495
|
setProfileAgent(agent);
|
|
2394
2496
|
setPName(agent.name ?? '');
|
|
@@ -2737,6 +2839,8 @@ window.__ModuleLoader__.load({
|
|
|
2737
2839
|
}
|
|
2738
2840
|
|
|
2739
2841
|
const inInbox = scope === 'inbox';
|
|
2842
|
+
const memberViewAgent = data.agents.find((agent) => agent.id === memberViewId) ?? null;
|
|
2843
|
+
const memberViewTasks = memberViewAgent === null ? [] : tasks.filter((task) => task.ownerId === memberViewAgent.id || task.assigneeId === memberViewAgent.id);
|
|
2740
2844
|
const headerTitle = inInbox ? t('inboxTitle') : project ? '# ' + project.name : t('noProject');
|
|
2741
2845
|
const headerGoal = inInbox ? t('inboxGoal') : (project?.goal ?? '');
|
|
2742
2846
|
const unread = inboxUnread > 99 ? '99+' : inboxUnread;
|
|
@@ -2753,7 +2857,8 @@ window.__ModuleLoader__.load({
|
|
|
2753
2857
|
onBoard: switchBoard,
|
|
2754
2858
|
onProject: switchProject,
|
|
2755
2859
|
onNewProject: () => { closeMobile(); openNewProject(); },
|
|
2756
|
-
onAgent: (agent) => { closeMobile();
|
|
2860
|
+
onAgent: (agent) => { closeMobile(); openMemberView(agent); },
|
|
2861
|
+
onAgentMore: (agent) => { closeMobile(); openProfile(agent); },
|
|
2757
2862
|
onAddAgent: () => { closeMobile(); openAddAgent(); },
|
|
2758
2863
|
onRecruit: (agent) => { closeMobile(); recruit(agent); },
|
|
2759
2864
|
};
|
|
@@ -2787,6 +2892,16 @@ window.__ModuleLoader__.load({
|
|
|
2787
2892
|
body: t('inboxEmptyBody'),
|
|
2788
2893
|
action: { label: t('inboxEmptyAction'), onClick: switchBoard },
|
|
2789
2894
|
})))
|
|
2895
|
+
: memberViewAgent && tab === 'main'
|
|
2896
|
+
? h(MemberView, {
|
|
2897
|
+
t,
|
|
2898
|
+
agent: memberViewAgent,
|
|
2899
|
+
tasks: memberViewTasks,
|
|
2900
|
+
onBack: closeMemberView,
|
|
2901
|
+
onOpenTask: openTask,
|
|
2902
|
+
onOpenChat: (agent) => { void openAgentChat(agent); },
|
|
2903
|
+
onOpenProfile: openProfile,
|
|
2904
|
+
})
|
|
2790
2905
|
: tab === 'board'
|
|
2791
2906
|
? h(Board, {
|
|
2792
2907
|
t,
|
|
@@ -2883,7 +2998,7 @@ window.__ModuleLoader__.load({
|
|
|
2883
2998
|
h('span', { className: 'at-notetext' }, note),
|
|
2884
2999
|
h('button', { className: 'at-noteclose', type: 'button', 'aria-label': t('dismiss'), title: t('dismiss'), onClick: () => setNote('') }, h(Ico, { name: 'close', size: 12 })))) : null,
|
|
2885
3000
|
body,
|
|
2886
|
-
!inInbox && tab === 'main' ? h(Composer, {
|
|
3001
|
+
!inInbox && tab === 'main' && !memberViewAgent ? h(Composer, {
|
|
2887
3002
|
t,
|
|
2888
3003
|
mode,
|
|
2889
3004
|
draft,
|
|
@@ -3030,6 +3145,7 @@ window.__ModuleLoader__.load({
|
|
|
3030
3145
|
pError ? h('div', { className: 'at-modalerror', role: 'alert' }, pError) : null,
|
|
3031
3146
|
h('div', { className: 'at-modalactions' },
|
|
3032
3147
|
h('button', { className: 'at-btn', type: 'button', onClick: () => setProfileAgent(null), disabled: pBusy }, t('cancel')),
|
|
3148
|
+
h('button', { className: 'at-btn', type: 'button', onClick: () => { const target = profileAgent; setProfileAgent(null); void openAgentChat(target); } }, t('agentChat')),
|
|
3033
3149
|
h('button', { className: 'at-btn', type: 'button', onClick: leaveProfile, disabled: pBusy }, t('leaveTeam')),
|
|
3034
3150
|
profileAgent.status === 'failed' ? h('button', { className: 'at-btn', type: 'button', onClick: retryProfile, disabled: pBusy }, t('retry')) : null,
|
|
3035
3151
|
h('button', { className: 'at-btn', type: 'button', onClick: distillProfile, disabled: pBusy }, t('redistill')),
|
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.13';
|
|
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.13",
|
|
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",
|