@nanmicoder/dsh-agent-teams 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,32 +13,53 @@ DeepSeek Harness 的 AgentTeams 插件:安装后,任何会话只需一句自
13
13
 
14
14
  ## 安装
15
15
 
16
- ### 前置要求
16
+ **前置要求**:已安装 [DeepSeek Harness](https://github.com/deepseek-ai/DeepSeek-Harness)(`dsh` 命令可用);Node.js `^22.19` 或 `>=24`;pnpm 11。
17
17
 
18
- - Node.js `^22.19` 或 `>=24`;pnpm 11
19
- - 已安装或可通过 `npx` 使用 DeepSeek Harness
18
+ 插件已发布到 npm(`@nanmicoder` scope),一条命令装好:
20
19
 
21
- ### 方式一:从 npm 安装(推荐)
20
+ ```sh
21
+ dsh plugin --profile web add @nanmicoder/dsh-agent-teams
22
+ ```
22
23
 
23
- 插件已发布到 npm(`@nanmicoder` scope),一条命令装好:
24
+ `dsh plugin` 会把插件加入 `web` profile,并根据包内的 `dsh.bundle` 声明自动启用它;工具、系统提示和 Web 客户端入口随该 profile 一起加载。
25
+
26
+ > **重启生效**:安装完成后,重启正在运行的 DeepSeek Harness Web 服务并刷新页面。
27
+
28
+ 装好后可以用 `dsh plugin --profile web list` 确认插件在列表里。升级用同一条 add 命令即可。
29
+
30
+ ### 其他安装方式
31
+
32
+ **指定版本**——`latest` 的解析可能受 registry 缓存影响(国内镜像源同步新版本通常有延迟),想钉死版本时:
24
33
 
25
34
  ```sh
26
- npx -p @deepseek-ai/dsh dsh plugin --profile web add @nanmicoder/dsh-agent-teams@0.1.0
35
+ dsh plugin --profile web add @nanmicoder/dsh-agent-teams@<version>
27
36
  ```
28
37
 
29
- 带版本号安装最稳妥:`latest` 的解析可能受 registry 缓存影响(国内镜像源同步新版本通常有几分钟到几小时延迟)。升级时把 `@0.1.0` 换成新版本号即可。
38
+ 版本号见 [npm 发布页](https://www.npmjs.com/package/@nanmicoder/dsh-agent-teams?activeTab=versions)。
39
+
40
+ **还没装 DSH,或不想全局安装**——用 `npx` 直接跑,无需预装:
30
41
 
31
- ### 方式二:从 GitHub 安装
42
+ ```sh
43
+ npx -p @deepseek-ai/dsh dsh plugin --profile web add @nanmicoder/dsh-agent-teams
44
+ ```
32
45
 
33
- 不想走 npm、或想直接装未发布的最新提交:
46
+ **从 GitHub 安装**——想用尚未发布到 npm 的最新提交:
34
47
 
35
48
  ```sh
36
- npx -p @deepseek-ai/dsh dsh plugin --profile web add github:NanmiCoder/dsh-agent-teams
49
+ dsh plugin --profile web add github:NanmiCoder/dsh-agent-teams
37
50
  ```
38
51
 
39
- 两种方式效果相同:`dsh plugin` 会把插件加入 `web` profile,并根据包内的 `dsh.bundle` 声明自动启用它;工具、系统提示和 Web 客户端入口随该 profile 一起加载。
52
+ **从源码安装**——要改插件本身,或参与开发:
40
53
 
41
- > **重启生效**:安装完成后,重启正在运行的 DeepSeek Harness Web 服务并刷新页面。
54
+ ```sh
55
+ git clone https://github.com/NanmiCoder/dsh-agent-teams.git
56
+ cd dsh-agent-teams
57
+ pnpm install
58
+ pnpm build
59
+ dsh plugin --profile web add "link:$(pwd)"
60
+ ```
61
+
62
+ `link:` 安装后,改完代码跑 `pnpm build` 即时生效,不必重装插件(客户端改动需刷新页面,host 侧改动需重启 dsh 服务)。提交前跑 `pnpm verify` 做离线校验。
42
63
 
43
64
  ## 使用
44
65
 
package/lib/client.js CHANGED
@@ -1,5 +1,5 @@
1
1
  window.__ModuleLoader__.load({
2
- id: "dsh-agent-teams",
2
+ id: "@nanmicoder/dsh-agent-teams",
3
3
  factory: (require) => {
4
4
  var module = { exports: {} };
5
5
  var exports = module.exports;
@@ -112,26 +112,26 @@ window.__ModuleLoader__.load({
112
112
  //#endregion
113
113
  //#region \0dsh-css:/Users/nanmi/workspace/myself_code/dsh-agent-teams/src/client/AgentTeamsCard.module.css.mjs
114
114
  const css$1 = "._6Ci0pW_root{box-sizing:border-box;border:1px solid var(--dsw-alias-line-normal);background:var(--dsw-alias-bg-module-platform);border-radius:10px;flex-direction:column;gap:8px;width:100%;min-width:0;padding:10px 12px;display:flex}._6Ci0pW_head{align-items:center;gap:8px;min-width:0;display:flex}._6Ci0pW_leadAvatar{border:1px solid var(--dsw-alias-line-strong);object-fit:cover;background:#0b1d33;border-radius:50%;flex:none;width:24px;height:24px}._6Ci0pW_teamName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:0 auto;font-size:13px;font-weight:600;line-height:20px;overflow:hidden}._6Ci0pW_memberCount{color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none;margin-left:auto;font-size:11px;line-height:16px}._6Ci0pW_panelButton{border:1px solid var(--dsw-alias-line-strong);background:var(--dsw-alias-bg-module);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;border-radius:999px;flex:none;padding:2px 8px;font-size:10.5px;font-weight:600;line-height:16px;transition:border-color .12s,color .12s}._6Ci0pW_panelButton:hover{border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-state-business-primary)}._6Ci0pW_panelButton:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}._6Ci0pW_members{flex-wrap:wrap;gap:6px;min-width:0;display:flex}._6Ci0pW_member{border:1px solid var(--dsw-alias-line-normal);background:var(--dsw-alias-bg-module);max-width:160px;color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;border-radius:999px;align-items:center;gap:5px;padding:3px 8px 3px 3px;font-size:11px;font-weight:500;line-height:16px;transition:border-color .12s,background-color .12s;display:inline-flex}._6Ci0pW_member:hover{border-color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-bg-fill-neutral)}._6Ci0pW_member:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}._6Ci0pW_memberArt{border:1px solid var(--dsw-alias-line-strong);object-fit:cover;background:#0b1d33;border-radius:50%;width:20px;height:20px}._6Ci0pW_memberInitial{background:var(--dsw-alias-bg-fill-business);width:20px;height:20px;color:var(--dsw-alias-label-on-fill);border-radius:50%;justify-content:center;align-items:center;font-size:10px;font-weight:600;line-height:20px;display:inline-flex}._6Ci0pW_memberName{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}";
115
- const tagId$1 = "dsh-agent-teams/AgentTeamsCard.module.css";
115
+ const tagId$1 = "@nanmicoder/dsh-agent-teams/AgentTeamsCard.module.css";
116
116
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
117
117
  const tag = document.createElement("style");
118
- tag.dataset.plugin = "dsh-agent-teams";
118
+ tag.dataset.plugin = "@nanmicoder/dsh-agent-teams";
119
119
  tag.dataset.pluginCss = tagId$1;
120
120
  tag.textContent = css$1;
121
121
  document.head.appendChild(tag);
122
122
  }
123
123
  var AgentTeamsCard_module_css_default = {
124
+ "head": "_6Ci0pW_head",
125
+ "leadAvatar": "_6Ci0pW_leadAvatar",
126
+ "member": "_6Ci0pW_member",
124
127
  "memberArt": "_6Ci0pW_memberArt",
125
128
  "memberCount": "_6Ci0pW_memberCount",
126
- "root": "_6Ci0pW_root",
127
129
  "memberInitial": "_6Ci0pW_memberInitial",
128
- "panelButton": "_6Ci0pW_panelButton",
130
+ "memberName": "_6Ci0pW_memberName",
129
131
  "members": "_6Ci0pW_members",
130
- "teamName": "_6Ci0pW_teamName",
131
- "head": "_6Ci0pW_head",
132
- "leadAvatar": "_6Ci0pW_leadAvatar",
133
- "member": "_6Ci0pW_member",
134
- "memberName": "_6Ci0pW_memberName"
132
+ "panelButton": "_6Ci0pW_panelButton",
133
+ "root": "_6Ci0pW_root",
134
+ "teamName": "_6Ci0pW_teamName"
135
135
  };
136
136
  //#endregion
137
137
  //#region lib/client/AgentTeamsCard.js
@@ -262,95 +262,95 @@ window.__ModuleLoader__.load({
262
262
  //#endregion
263
263
  //#region \0dsh-css:/Users/nanmi/workspace/myself_code/dsh-agent-teams/src/client/ActivityPanel.module.css.mjs
264
264
  const css = "html{--agent-teams-panel-width:388px;--agent-teams-panel-right:calc(18px + var(--dsh-sidebar-width,0px));--agent-teams-panel-gap:14px;--agent-teams-panel-shift:calc(var(--agent-teams-panel-width) + 18px + var(--agent-teams-panel-gap))}html[data-agent-teams-panel-open] [data-phase=active]{box-sizing:border-box;padding-right:var(--agent-teams-panel-shift)}[data-phase=active]{will-change:padding-right;transition:padding-right .36s cubic-bezier(.22,1,.36,1)}.qZToFW_badge{top:64px;right:var(--agent-teams-panel-right);z-index:2147483000;box-sizing:border-box;border:1px solid var(--dsw-alias-line-normal);background:color-mix(in srgb, var(--dsw-alias-bg-module-platform) 92%, transparent);backdrop-filter:blur(16px);height:34px;box-shadow:0 8px 28px color-mix(in srgb, var(--dsw-alias-label-primary) 14%, transparent);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;border-radius:999px;align-items:center;gap:7px;padding:0 12px;font-size:12px;font-weight:600;line-height:20px;transition:border-color .15s,transform .12s;display:inline-flex;position:fixed}.qZToFW_badge:hover{border-color:var(--dsw-alias-line-strong);transform:translateY(-1px)}.qZToFW_badge:active{transform:translateY(0)scale(.98)}.qZToFW_badge:focus-visible,.qZToFW_closeButton:focus-visible,.qZToFW_memberRow:focus-visible,.qZToFW_taskNode:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.qZToFW_badgeDot,.qZToFW_panelDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;width:7px;height:7px}.qZToFW_badgeDot[data-busy=true],.qZToFW_panelDot[data-busy=true]{background:var(--dsw-alias-state-business-primary);animation:1.25s ease-in-out infinite qZToFW_agentTeamsPulse}.qZToFW_badgeCount,.qZToFW_memberCount,.qZToFW_teamStats,.qZToFW_stageLabel,.qZToFW_taskId{font-variant-numeric:tabular-nums}.qZToFW_panel{top:64px;right:var(--agent-teams-panel-right);z-index:2147483000;width:min(var(--agent-teams-panel-width), calc(100vw - 24px));box-sizing:border-box;border:1px solid color-mix(in srgb, var(--dsw-alias-line-strong) 58%, transparent);background:color-mix(in srgb, var(--dsw-alias-bg-module-platform) 95%, transparent);backdrop-filter:blur(20px)saturate(1.08);max-height:70dvh;box-shadow:0 12px 32px color-mix(in srgb, var(--dsw-alias-label-primary) 12%, transparent), 0 32px 72px color-mix(in srgb, var(--dsw-alias-label-primary) 16%, transparent);border-radius:16px;flex-direction:column;animation:.18s ease-out qZToFW_agentTeamsPanelIn;display:flex;position:fixed;overflow:hidden}@keyframes qZToFW_agentTeamsPanelIn{0%{opacity:0;transform:translateY(-6px)scale(.99)}to{opacity:1;transform:translateY(0)scale(1)}}@keyframes qZToFW_agentTeamsPulse{0%,to{opacity:.42}50%{opacity:1}}.qZToFW_panelHead{border-bottom:1px solid var(--dsw-alias-line-normal);flex:none;justify-content:space-between;align-items:center;min-height:44px;padding:0 14px 0 16px;display:flex}.qZToFW_panelTitle{color:var(--dsw-alias-label-primary);align-items:center;gap:8px;font-size:14px;font-weight:600;line-height:20px;display:inline-flex}.qZToFW_closeButton{width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:7px;justify-content:center;align-items:center;padding:0;transition:background-color .12s,color .12s,transform .12s;display:inline-flex}.qZToFW_closeButton:hover{background:var(--dsw-alias-bg-fill-neutral);color:var(--dsw-alias-label-primary)}.qZToFW_closeButton:active{transform:scale(.94)}.qZToFW_teams{overscroll-behavior:contain;flex-direction:column;min-height:0;display:flex;overflow-y:auto}.qZToFW_team{border-bottom:1px solid var(--dsw-alias-line-normal);flex-direction:column;gap:12px;padding:12px 14px 16px;display:flex}.qZToFW_team:last-child{border-bottom:0}.qZToFW_teamHead{align-items:center;gap:10px;min-width:0;display:flex}.qZToFW_teamName{min-width:0;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:13px;font-weight:600;line-height:18px;overflow:hidden}.qZToFW_teamStats{color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none;gap:8px;font-size:10.5px;line-height:16px;display:inline-flex}.qZToFW_sectionHead{justify-content:space-between;align-items:center;gap:8px;min-width:0;display:flex}.qZToFW_sectionTitle{color:var(--dsw-alias-label-secondary);align-items:center;gap:6px;font-size:11px;font-weight:600;line-height:16px;display:inline-flex}.qZToFW_sectionHint{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:14px;overflow:hidden}.qZToFW_delegationSection{min-width:0}.qZToFW_captainNode{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--dsw-alias-state-business-primary) 32%, var(--dsw-alias-line-normal));background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 7%, var(--dsw-alias-bg-module));border-radius:10px;grid-template-columns:38px minmax(0,1fr) auto;align-items:center;gap:9px;min-height:48px;padding:8px 10px;display:grid}.qZToFW_captainAvatar,.qZToFW_memberAvatar{flex:none;justify-content:center;align-items:center;display:inline-flex;position:relative}.qZToFW_captainAvatar{width:36px;height:36px}.qZToFW_leadAvatar,.qZToFW_memberArt,.qZToFW_memberInitial{box-sizing:border-box;border:1px solid var(--dsw-alias-line-strong);object-fit:cover;background:#0b1d33;border-radius:50%;width:34px;height:34px}.qZToFW_captainInfo,.qZToFW_memberInfo{flex-direction:column;min-width:0;display:flex}.qZToFW_captainInfo{gap:2px}.qZToFW_captainLine,.qZToFW_memberLine{align-items:center;gap:6px;min-width:0;display:flex}.qZToFW_captainName,.qZToFW_memberName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:12.5px;font-weight:600;line-height:18px;overflow:hidden}.qZToFW_captainRole,.qZToFW_memberRole{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:14px;overflow:hidden}.qZToFW_captainSummary,.qZToFW_memberStatusLine{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:10.5px;line-height:15px;overflow:hidden}.qZToFW_captainState,.qZToFW_memberState{color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none;align-items:center;gap:5px;font-size:10px;font-weight:500;line-height:15px;display:inline-flex}.qZToFW_captainState[data-busy=true],.qZToFW_memberState[data-activity=working]{color:var(--dsw-alias-state-business-primary)}.qZToFW_delegationTree{flex-direction:column;gap:2px;margin-left:18px;padding:9px 0 0 20px;display:flex;position:relative}.qZToFW_delegationTree:before{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 48%, var(--dsw-alias-line-normal));content:\"\";width:1px;position:absolute;top:0;bottom:22px;left:0}.qZToFW_memberBlock{flex-direction:column;min-width:0;padding:3px 0 7px;display:flex;position:relative}.qZToFW_memberBranch{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 48%, var(--dsw-alias-line-normal));width:20px;height:1px;display:block;position:absolute;top:23px;right:100%}.qZToFW_memberBranch:before{background:var(--dsw-alias-state-business-primary);content:\"\";border-radius:50%;width:5px;height:5px;position:absolute;top:-2px;right:-1px}.qZToFW_memberRow{box-sizing:border-box;width:100%;min-width:0;min-height:44px;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:8px;grid-template-columns:38px minmax(0,1fr) auto;align-items:center;gap:8px;padding:4px 6px;transition:background-color .12s,transform .12s;display:grid}.qZToFW_memberRow:hover,.qZToFW_memberRow[data-activity=working]{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 6%, var(--dsw-alias-bg-module))}.qZToFW_memberRow:active{transform:scale(.995)}.qZToFW_memberAvatar{width:34px;height:34px}.qZToFW_memberAvatar[data-unread=true]:after{border:1px solid var(--dsw-alias-state-business-primary);content:\"\";border-radius:50%;animation:1.5s ease-out infinite qZToFW_agentTeamsRing;position:absolute;inset:-3px}@keyframes qZToFW_agentTeamsRing{0%{opacity:.82;transform:scale(.94)}75%,to{opacity:0;transform:scale(1.18)}}.qZToFW_memberInitial{color:var(--dsw-alias-label-on-fill);justify-content:center;align-items:center;font-size:14px;font-weight:600;line-height:20px;display:inline-flex}.qZToFW_stateArt{box-sizing:border-box;border:2px solid var(--dsw-alias-bg-module-platform);object-fit:cover;background:#0b1d33;border-radius:50%;width:19px;height:19px;position:absolute;bottom:-4px;right:-4px}.qZToFW_stateArt[data-activity=working]{animation:2.4s ease-in-out infinite qZToFW_agentTeamsFloat}.qZToFW_stateArt[data-activity=idle]{animation:4.2s ease-in-out infinite qZToFW_agentTeamsBreathe}.qZToFW_stateArt[data-activity=unknown]{animation:2.8s ease-in-out infinite qZToFW_agentTeamsThink}@keyframes qZToFW_agentTeamsFloat{0%,to{transform:translateY(0)rotate(-4deg)}50%{transform:translateY(-2px)rotate(4deg)}}@keyframes qZToFW_agentTeamsBreathe{0%,to{opacity:.82;transform:scale(1)}50%{opacity:1;transform:scale(1.06)}}@keyframes qZToFW_agentTeamsThink{0%,to{transform:rotate(-7deg)}50%{transform:rotate(7deg)}}.qZToFW_memberState{margin-left:auto}.qZToFW_memberCount{color:var(--dsw-alias-label-tertiary);font-size:10.5px;line-height:16px}.qZToFW_assignmentLine{align-items:center;gap:7px;min-width:0;padding:0 6px 0 52px;display:flex}.qZToFW_assignmentLabel{color:var(--dsw-alias-label-tertiary);flex:none;font-size:9.5px;line-height:14px}.qZToFW_assignmentTasks{flex-wrap:wrap;flex:1;gap:4px;min-width:0;display:flex}.qZToFW_assignmentChip{background:var(--dsw-alias-bg-fill-neutral);min-height:16px;color:var(--dsw-alias-label-secondary);border-radius:4px;align-items:center;padding:0 5px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:9px;font-weight:600;line-height:14px;display:inline-flex}.qZToFW_assignmentChip[data-state=running]{background:var(--dsw-alias-bg-fill-business);color:var(--dsw-alias-label-on-fill)}.qZToFW_assignmentChip[data-state=completed]{background:var(--dsw-alias-bg-fill-success);color:var(--dsw-alias-label-on-fill)}.qZToFW_assignmentChip[data-state=blocked]{background:var(--dsw-alias-bg-fill-warning);color:var(--dsw-alias-label-on-fill)}.qZToFW_assignmentChip[data-state=failed]{background:var(--dsw-alias-bg-fill-danger);color:var(--dsw-alias-label-on-fill)}.qZToFW_assignmentChip[data-state=cancelled]{color:var(--dsw-alias-label-tertiary);text-decoration:line-through}.qZToFW_unreadPill{color:var(--dsw-alias-state-business-primary);white-space:nowrap;flex:none;font-size:9.5px;font-weight:600;line-height:14px}.qZToFW_taskEmpty{color:var(--dsw-alias-label-tertiary);font-size:9.5px;line-height:14px}.qZToFW_dependencySection{border-top:1px solid var(--dsw-alias-line-normal);flex-direction:column;gap:7px;min-width:0;padding-top:10px;display:flex}.qZToFW_stageFlow{scrollbar-width:thin;align-items:stretch;gap:0;min-width:0;padding:1px 1px 5px;display:flex;overflow-x:auto}.qZToFW_stageGroup{flex:1 0 126px;min-width:126px;display:flex;position:relative}.qZToFW_stageConnector{width:22px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none;align-items:center;margin-top:0;display:flex}.qZToFW_stageLine{background:var(--dsw-alias-line-strong);flex:1;height:1px;display:block}.qZToFW_stageColumn{flex-direction:column;flex:1;gap:5px;min-width:0;display:flex}.qZToFW_stageLabel{color:var(--dsw-alias-label-tertiary);justify-content:space-between;align-items:center;gap:6px;padding:0 2px;font-size:9.5px;font-weight:600;line-height:14px;display:flex}.qZToFW_stageLabel span{background:var(--dsw-alias-bg-fill-neutral);border-radius:4px;justify-content:center;align-items:center;min-width:14px;height:14px;font-size:8.5px;display:inline-flex}.qZToFW_stageTasks{flex-direction:column;gap:5px;display:flex}.qZToFW_taskNode{box-sizing:border-box;border:1px solid var(--dsw-alias-line-normal);background:var(--dsw-alias-bg-module);min-width:0;min-height:72px;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;cursor:pointer;border-radius:8px;flex-direction:column;gap:4px;padding:7px 8px;transition:border-color .14s,opacity .14s,transform .12s,background-color .14s;display:flex}.qZToFW_taskNode:hover,.qZToFW_taskNode[data-focused=true]{border-color:var(--dsw-alias-state-business-primary);background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 6%, var(--dsw-alias-bg-module));transform:translateY(-1px)}.qZToFW_taskNode[data-dimmed=true]{opacity:.34}.qZToFW_taskNode[data-state=completed]{border-color:color-mix(in srgb, var(--dsw-alias-state-success) 48%, var(--dsw-alias-line-normal))}.qZToFW_taskNode[data-state=blocked]{border-color:color-mix(in srgb, var(--dsw-alias-state-warning) 52%, var(--dsw-alias-line-normal))}.qZToFW_taskNode[data-state=failed]{border-color:color-mix(in srgb, var(--dsw-alias-state-danger) 56%, var(--dsw-alias-line-normal))}.qZToFW_taskNodeHead,.qZToFW_taskRoute{justify-content:space-between;align-items:center;gap:5px;min-width:0;display:flex}.qZToFW_taskId{color:var(--dsw-alias-label-tertiary);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:9.5px;font-weight:700}.qZToFW_taskBadge{background:var(--dsw-alias-bg-fill-neutral);min-height:14px;color:var(--dsw-alias-label-secondary);border-radius:4px;flex:none;align-items:center;padding:0 4px;font-size:8.5px;font-weight:600;line-height:13px;display:inline-flex}.qZToFW_taskBadge[data-state=running]{background:var(--dsw-alias-bg-fill-business);color:var(--dsw-alias-label-on-fill)}.qZToFW_taskBadge[data-state=completed]{background:var(--dsw-alias-bg-fill-success);color:var(--dsw-alias-label-on-fill)}.qZToFW_taskBadge[data-state=blocked]{background:var(--dsw-alias-bg-fill-warning);color:var(--dsw-alias-label-on-fill)}.qZToFW_taskBadge[data-state=failed]{background:var(--dsw-alias-bg-fill-danger);color:var(--dsw-alias-label-on-fill)}.qZToFW_taskBadge[data-state=cancelled]{color:var(--dsw-alias-label-tertiary);text-decoration:line-through}.qZToFW_taskSubject{min-height:30px;color:var(--dsw-alias-label-primary);-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:10.5px;font-weight:500;line-height:15px;display:-webkit-box;overflow:hidden}.qZToFW_taskRoute{color:var(--dsw-alias-label-tertiary);margin-top:auto;font-size:8.5px;line-height:13px}.qZToFW_taskOwner,.qZToFW_taskDeps{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.qZToFW_taskOwner{max-width:48%;color:var(--dsw-alias-label-secondary);font-weight:600}.qZToFW_taskDeps{text-align:right;flex:1}.qZToFW_taskStart{color:var(--dsw-alias-label-tertiary)}.qZToFW_unclaimed,.qZToFW_inbox{border-top:1px solid var(--dsw-alias-line-normal);flex-direction:column;gap:5px;min-width:0;padding-top:10px;display:flex}.qZToFW_unclaimedTitle{color:var(--dsw-alias-label-secondary);font-size:10.5px;font-weight:600;line-height:15px}.qZToFW_inboxRow{border-radius:6px;grid-template-columns:112px minmax(0,1fr);align-items:center;gap:8px;min-width:0;min-height:24px;padding:2px 5px;display:grid}.qZToFW_inboxRow:hover{background:var(--dsw-alias-bg-module)}.qZToFW_inboxRoute{min-width:0;color:var(--dsw-alias-state-business-primary);text-overflow:ellipsis;white-space:nowrap;align-items:center;gap:3px;font-size:9.5px;font-weight:600;line-height:14px;display:inline-flex;overflow:hidden}.qZToFW_inboxContent{min-width:0;color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:14px;overflow:hidden}.qZToFW_emptyHint{color:var(--dsw-alias-label-tertiary);padding:10px 12px;font-size:11px;line-height:16px}.qZToFW_team[data-historic],.qZToFW_archivedWrap{opacity:.82}.qZToFW_historicPill{background:var(--dsw-alias-bg-fill-neutral);color:var(--dsw-alias-label-tertiary);border-radius:4px;flex:none;margin-left:auto;padding:1px 7px;font-size:9.5px;font-weight:600;line-height:15px}.qZToFW_members{flex-direction:column;gap:3px;display:flex}.qZToFW_archivedWrap:before{color:var(--dsw-alias-label-tertiary);content:\"已结束 · 历史归档\";padding:5px 14px 0;font-size:9.5px;font-weight:600;line-height:14px;display:block}@media (prefers-reduced-motion:reduce){[data-phase=active],.qZToFW_panel,.qZToFW_badge,.qZToFW_badgeDot,.qZToFW_panelDot,.qZToFW_stateArt,.qZToFW_memberAvatar[data-unread=true]:after{transition:none;animation:none}}@media (width<=960px){html{--agent-teams-main-shift:0px}html[data-agent-teams-panel-open] [data-phase=active]{padding-right:0}}@media (width<=640px){html{--agent-teams-panel-right:calc(10px + var(--dsh-sidebar-width,0px))}.qZToFW_panel{width:auto;max-height:calc(100dvh - 68px);top:56px;left:10px}.qZToFW_badge{top:56px}.qZToFW_teamStats span[data-stat=messages]{display:none}.qZToFW_captainNode{grid-template-columns:38px minmax(0,1fr)}.qZToFW_captainState{display:none}.qZToFW_delegationTree{margin-left:12px;padding-left:15px}.qZToFW_memberBranch{width:15px}.qZToFW_assignmentLine{padding-left:45px}}";
265
- const tagId = "dsh-agent-teams/ActivityPanel.module.css";
265
+ const tagId = "@nanmicoder/dsh-agent-teams/ActivityPanel.module.css";
266
266
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
267
267
  const tag = document.createElement("style");
268
- tag.dataset.plugin = "dsh-agent-teams";
268
+ tag.dataset.plugin = "@nanmicoder/dsh-agent-teams";
269
269
  tag.dataset.pluginCss = tagId;
270
270
  tag.textContent = css;
271
271
  document.head.appendChild(tag);
272
272
  }
273
273
  var ActivityPanel_module_css_default = {
274
- "inbox": "qZToFW_inbox",
275
- "unclaimedTitle": "qZToFW_unclaimedTitle",
276
- "panelHead": "qZToFW_panelHead",
277
- "panelDot": "qZToFW_panelDot",
278
274
  "agentTeamsBreathe": "qZToFW_agentTeamsBreathe",
279
- "team": "qZToFW_team",
280
- "assignmentTasks": "qZToFW_assignmentTasks",
281
- "archivedWrap": "qZToFW_archivedWrap",
282
- "stageGroup": "qZToFW_stageGroup",
283
- "memberAvatar": "qZToFW_memberAvatar",
284
- "dependencySection": "qZToFW_dependencySection",
285
- "sectionHint": "qZToFW_sectionHint",
286
- "memberState": "qZToFW_memberState",
287
- "taskNodeHead": "qZToFW_taskNodeHead",
288
- "inboxContent": "qZToFW_inboxContent",
289
- "captainRole": "qZToFW_captainRole",
290
- "taskId": "qZToFW_taskId",
291
- "captainSummary": "qZToFW_captainSummary",
292
- "badgeCount": "qZToFW_badgeCount",
293
- "taskSubject": "qZToFW_taskSubject",
294
- "captainState": "qZToFW_captainState",
295
- "teamStats": "qZToFW_teamStats",
296
- "taskRoute": "qZToFW_taskRoute",
297
- "sectionTitle": "qZToFW_sectionTitle",
298
- "taskEmpty": "qZToFW_taskEmpty",
275
+ "agentTeamsFloat": "qZToFW_agentTeamsFloat",
276
+ "agentTeamsPanelIn": "qZToFW_agentTeamsPanelIn",
277
+ "agentTeamsPulse": "qZToFW_agentTeamsPulse",
299
278
  "agentTeamsRing": "qZToFW_agentTeamsRing",
300
- "stageLine": "qZToFW_stageLine",
279
+ "agentTeamsThink": "qZToFW_agentTeamsThink",
280
+ "archivedWrap": "qZToFW_archivedWrap",
281
+ "assignmentChip": "qZToFW_assignmentChip",
282
+ "assignmentLabel": "qZToFW_assignmentLabel",
301
283
  "assignmentLine": "qZToFW_assignmentLine",
302
- "inboxRow": "qZToFW_inboxRow",
303
- "emptyHint": "qZToFW_emptyHint",
304
- "members": "qZToFW_members",
284
+ "assignmentTasks": "qZToFW_assignmentTasks",
285
+ "badge": "qZToFW_badge",
286
+ "badgeCount": "qZToFW_badgeCount",
287
+ "badgeDot": "qZToFW_badgeDot",
305
288
  "captainAvatar": "qZToFW_captainAvatar",
306
- "stateArt": "qZToFW_stateArt",
307
- "agentTeamsThink": "qZToFW_agentTeamsThink",
308
- "memberRow": "qZToFW_memberRow",
309
- "memberCount": "qZToFW_memberCount",
310
- "agentTeamsPanelIn": "qZToFW_agentTeamsPanelIn",
289
+ "captainInfo": "qZToFW_captainInfo",
290
+ "captainLine": "qZToFW_captainLine",
291
+ "captainName": "qZToFW_captainName",
311
292
  "captainNode": "qZToFW_captainNode",
293
+ "captainRole": "qZToFW_captainRole",
294
+ "captainState": "qZToFW_captainState",
295
+ "captainSummary": "qZToFW_captainSummary",
296
+ "closeButton": "qZToFW_closeButton",
297
+ "delegationSection": "qZToFW_delegationSection",
312
298
  "delegationTree": "qZToFW_delegationTree",
313
- "taskOwner": "qZToFW_taskOwner",
299
+ "dependencySection": "qZToFW_dependencySection",
300
+ "emptyHint": "qZToFW_emptyHint",
301
+ "historicPill": "qZToFW_historicPill",
302
+ "inbox": "qZToFW_inbox",
303
+ "inboxContent": "qZToFW_inboxContent",
304
+ "inboxRoute": "qZToFW_inboxRoute",
305
+ "inboxRow": "qZToFW_inboxRow",
306
+ "leadAvatar": "qZToFW_leadAvatar",
314
307
  "memberArt": "qZToFW_memberArt",
315
- "stageColumn": "qZToFW_stageColumn",
316
- "taskDeps": "qZToFW_taskDeps",
317
- "assignmentChip": "qZToFW_assignmentChip",
318
- "panelTitle": "qZToFW_panelTitle",
319
- "captainLine": "qZToFW_captainLine",
320
- "stageTasks": "qZToFW_stageTasks",
321
- "delegationSection": "qZToFW_delegationSection",
322
- "teams": "qZToFW_teams",
323
- "taskStart": "qZToFW_taskStart",
324
- "badgeDot": "qZToFW_badgeDot",
325
- "panel": "qZToFW_panel",
326
- "teamHead": "qZToFW_teamHead",
308
+ "memberAvatar": "qZToFW_memberAvatar",
327
309
  "memberBlock": "qZToFW_memberBlock",
328
- "leadAvatar": "qZToFW_leadAvatar",
329
- "agentTeamsFloat": "qZToFW_agentTeamsFloat",
310
+ "memberBranch": "qZToFW_memberBranch",
311
+ "memberCount": "qZToFW_memberCount",
330
312
  "memberInfo": "qZToFW_memberInfo",
331
- "memberStatusLine": "qZToFW_memberStatusLine",
332
- "captainName": "qZToFW_captainName",
333
- "historicPill": "qZToFW_historicPill",
313
+ "memberInitial": "qZToFW_memberInitial",
334
314
  "memberLine": "qZToFW_memberLine",
315
+ "memberName": "qZToFW_memberName",
316
+ "memberRole": "qZToFW_memberRole",
317
+ "memberRow": "qZToFW_memberRow",
318
+ "memberState": "qZToFW_memberState",
319
+ "memberStatusLine": "qZToFW_memberStatusLine",
320
+ "members": "qZToFW_members",
321
+ "panel": "qZToFW_panel",
322
+ "panelDot": "qZToFW_panelDot",
323
+ "panelHead": "qZToFW_panelHead",
324
+ "panelTitle": "qZToFW_panelTitle",
325
+ "sectionHead": "qZToFW_sectionHead",
326
+ "sectionHint": "qZToFW_sectionHint",
327
+ "sectionTitle": "qZToFW_sectionTitle",
328
+ "stageColumn": "qZToFW_stageColumn",
329
+ "stageConnector": "qZToFW_stageConnector",
335
330
  "stageFlow": "qZToFW_stageFlow",
336
- "unreadPill": "qZToFW_unreadPill",
331
+ "stageGroup": "qZToFW_stageGroup",
337
332
  "stageLabel": "qZToFW_stageLabel",
338
- "inboxRoute": "qZToFW_inboxRoute",
339
- "stageConnector": "qZToFW_stageConnector",
340
- "sectionHead": "qZToFW_sectionHead",
341
- "badge": "qZToFW_badge",
342
- "teamName": "qZToFW_teamName",
343
- "memberInitial": "qZToFW_memberInitial",
333
+ "stageLine": "qZToFW_stageLine",
334
+ "stageTasks": "qZToFW_stageTasks",
335
+ "stateArt": "qZToFW_stateArt",
336
+ "taskBadge": "qZToFW_taskBadge",
337
+ "taskDeps": "qZToFW_taskDeps",
338
+ "taskEmpty": "qZToFW_taskEmpty",
339
+ "taskId": "qZToFW_taskId",
344
340
  "taskNode": "qZToFW_taskNode",
345
- "closeButton": "qZToFW_closeButton",
341
+ "taskNodeHead": "qZToFW_taskNodeHead",
342
+ "taskOwner": "qZToFW_taskOwner",
343
+ "taskRoute": "qZToFW_taskRoute",
344
+ "taskStart": "qZToFW_taskStart",
345
+ "taskSubject": "qZToFW_taskSubject",
346
+ "team": "qZToFW_team",
347
+ "teamHead": "qZToFW_teamHead",
348
+ "teamName": "qZToFW_teamName",
349
+ "teamStats": "qZToFW_teamStats",
350
+ "teams": "qZToFW_teams",
346
351
  "unclaimed": "qZToFW_unclaimed",
347
- "memberName": "qZToFW_memberName",
348
- "captainInfo": "qZToFW_captainInfo",
349
- "taskBadge": "qZToFW_taskBadge",
350
- "assignmentLabel": "qZToFW_assignmentLabel",
351
- "agentTeamsPulse": "qZToFW_agentTeamsPulse",
352
- "memberRole": "qZToFW_memberRole",
353
- "memberBranch": "qZToFW_memberBranch"
352
+ "unclaimedTitle": "qZToFW_unclaimedTitle",
353
+ "unreadPill": "qZToFW_unreadPill"
354
354
  };
355
355
  //#endregion
356
356
  //#region lib/client/ActivityPanel.js
package/lib/state.js CHANGED
@@ -12,7 +12,7 @@
12
12
  * `fs` service offers no directory deletion.
13
13
  * @module dsh-agent-teams/state
14
14
  */
15
- import { randomUUID } from 'node:crypto';
15
+ import { createHash, randomUUID } from 'node:crypto';
16
16
  import { mkdir, readFile, readdir, rename, rm, writeFile } from 'node:fs/promises';
17
17
  import { join } from 'node:path';
18
18
  /** Mailbox key of the captain. */
@@ -38,14 +38,41 @@ export async function withTeamLock(key, fn) {
38
38
  release();
39
39
  }
40
40
  }
41
+ /** Longest key emitted before truncating and appending a digest. */
42
+ const MAX_KEY_LENGTH = 48;
43
+ /** Short stable digest, used to keep otherwise-colliding keys distinct. */
44
+ function keyDigest(name) {
45
+ return createHash('sha256').update(name).digest('hex').slice(0, 8);
46
+ }
41
47
  /**
42
48
  * Fold a free-form name into a safe path/key segment.
49
+ *
50
+ * Unicode letters and digits survive, so CJK/Cyrillic/Greek names stay
51
+ * distinct and readable; everything else — spaces, punctuation, path
52
+ * separators, control characters — folds to `-`. An ASCII-only whitelist
53
+ * mapped *every* non-Latin name onto one shared fallback, which silently
54
+ * merged their mailboxes and rejected the second such member as a duplicate.
55
+ *
56
+ * A name with no letters or digits at all (pure emoji or punctuation) cannot
57
+ * yield a readable key, so it gets a digest rather than a shared constant.
58
+ * Over-long names are truncated with a digest appended, so names sharing a
59
+ * long prefix stay distinct and the result stays within filesystem limits
60
+ * (CJK costs 3 bytes per character in UTF-8).
61
+ *
43
62
  * @param name - any user-supplied name.
44
- * @returns lowercase `[a-z0-9-]` key, never empty.
63
+ * @returns a non-empty key safe as a single path segment.
45
64
  */
46
65
  export function sanitizeKey(name) {
47
- const cleaned = name.trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
48
- return cleaned === '' ? 'team' : cleaned;
66
+ const cleaned = name.normalize('NFC').trim().toLowerCase()
67
+ .replace(/[^\p{L}\p{N}]+/gu, '-')
68
+ .replace(/^-+|-+$/g, '');
69
+ if (cleaned === '')
70
+ return `k-${keyDigest(name)}`;
71
+ const points = [...cleaned];
72
+ if (points.length > MAX_KEY_LENGTH) {
73
+ return `${points.slice(0, MAX_KEY_LENGTH).join('')}-${keyDigest(name)}`;
74
+ }
75
+ return cleaned;
49
76
  }
50
77
  /**
51
78
  * Whether `dependencies` are all satisfied (every named task exists and
@@ -24,8 +24,21 @@ export declare const CAPTAIN_KEY = "captain";
24
24
  export declare function withTeamLock<T>(key: string, fn: () => Promise<T>): Promise<T>;
25
25
  /**
26
26
  * Fold a free-form name into a safe path/key segment.
27
+ *
28
+ * Unicode letters and digits survive, so CJK/Cyrillic/Greek names stay
29
+ * distinct and readable; everything else — spaces, punctuation, path
30
+ * separators, control characters — folds to `-`. An ASCII-only whitelist
31
+ * mapped *every* non-Latin name onto one shared fallback, which silently
32
+ * merged their mailboxes and rejected the second such member as a duplicate.
33
+ *
34
+ * A name with no letters or digits at all (pure emoji or punctuation) cannot
35
+ * yield a readable key, so it gets a digest rather than a shared constant.
36
+ * Over-long names are truncated with a digest appended, so names sharing a
37
+ * long prefix stay distinct and the result stays within filesystem limits
38
+ * (CJK costs 3 bytes per character in UTF-8).
39
+ *
27
40
  * @param name - any user-supplied name.
28
- * @returns lowercase `[a-z0-9-]` key, never empty.
41
+ * @returns a non-empty key safe as a single path segment.
29
42
  */
30
43
  export declare function sanitizeKey(name: string): string;
31
44
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nanmicoder/dsh-agent-teams",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
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",
@@ -24,7 +24,11 @@
24
24
  "README.md"
25
25
  ],
26
26
  "license": "MIT",
27
- "author": "程序员阿江(Relakkes) <relakkes@gmail.com>",
27
+ "author": {
28
+ "name": "程序员阿江 (Relakkes)",
29
+ "email": "relakkes@gmail.com",
30
+ "url": "https://github.com/NanmiCoder"
31
+ },
28
32
  "homepage": "https://github.com/NanmiCoder/dsh-agent-teams#readme",
29
33
  "repository": {
30
34
  "type": "git",