@wowyuarm/dsh-agent-team 0.1.11 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +4 -4
  2. package/README.zh.md +4 -4
  3. package/package.json +3 -2
  4. package/packages/agent-team/README.md +2 -2
  5. package/packages/agent-team/README.zh.md +2 -2
  6. package/packages/agent-team/lib/context-projection.js +5 -1
  7. package/packages/agent-team/lib/index.js +11 -44
  8. package/packages/agent-team/lib/ledger.js +251 -142
  9. package/packages/agent-team/lib/member-runtime.js +47 -9
  10. package/packages/agent-team/lib/mentions.js +56 -0
  11. package/packages/agent-team/lib/spec.js +1 -0
  12. package/packages/agent-team/lib/typert.host.js +80 -31
  13. package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
  14. package/packages/agent-team/lib/typert.remote-client.js +71 -26
  15. package/packages/agent-team/lib/types/context-projection.d.ts.map +1 -1
  16. package/packages/agent-team/lib/types/index.d.ts +1 -7
  17. package/packages/agent-team/lib/types/index.d.ts.map +1 -1
  18. package/packages/agent-team/lib/types/ledger.d.ts +75 -17
  19. package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
  20. package/packages/agent-team/lib/types/member-runtime.d.ts +2 -1
  21. package/packages/agent-team/lib/types/member-runtime.d.ts.map +1 -1
  22. package/packages/agent-team/lib/types/mentions.d.ts +34 -0
  23. package/packages/agent-team/lib/types/mentions.d.ts.map +1 -0
  24. package/packages/agent-team/lib/types/spec.d.ts.map +1 -1
  25. package/packages/agent-team/lib/types/types/entities.d.ts +0 -18
  26. package/packages/agent-team/lib/types/types/entities.d.ts.map +1 -1
  27. package/packages/agent-team/lib/types/types/requests-results.d.ts +57 -15
  28. package/packages/agent-team/lib/types/types/requests-results.d.ts.map +1 -1
  29. package/packages/agent-team/preset/team-member/agent.cordis.yml +48 -8
  30. package/packages/client-agent-team/lib/client.js +1366 -909
  31. package/packages/client-agent-team/lib/client.js.map +1 -1
  32. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts.map +1 -1
  33. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +3 -3
  34. package/packages/client-agent-team/lib/types/client/TeamAvatarStack.d.ts +18 -0
  35. package/packages/client-agent-team/lib/types/client/TeamAvatarStack.d.ts.map +1 -0
  36. package/packages/client-agent-team/lib/types/client/TeamAvatarStack.js +22 -0
  37. package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts +3 -1
  38. package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts.map +1 -1
  39. package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +125 -13
  40. package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.d.ts.map +1 -1
  41. package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.js +10 -3
  42. package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts.map +1 -1
  43. package/packages/client-agent-team/lib/types/client/TeamComposer.js +11 -17
  44. package/packages/client-agent-team/lib/types/client/TeamConversation.js +1 -1
  45. package/packages/client-agent-team/lib/types/client/TeamCountBadge.d.ts +20 -0
  46. package/packages/client-agent-team/lib/types/client/TeamCountBadge.d.ts.map +1 -0
  47. package/packages/client-agent-team/lib/types/client/TeamCountBadge.js +25 -0
  48. package/packages/client-agent-team/lib/types/client/TeamInboxPage.d.ts +9 -5
  49. package/packages/client-agent-team/lib/types/client/TeamInboxPage.d.ts.map +1 -1
  50. package/packages/client-agent-team/lib/types/client/TeamInboxPage.js +82 -14
  51. package/packages/client-agent-team/lib/types/client/TeamMemberRow.d.ts +43 -0
  52. package/packages/client-agent-team/lib/types/client/TeamMemberRow.d.ts.map +1 -0
  53. package/packages/client-agent-team/lib/types/client/TeamMemberRow.js +27 -0
  54. package/packages/client-agent-team/lib/types/client/TeamMembersAction.d.ts +2 -2
  55. package/packages/client-agent-team/lib/types/client/TeamMembersAction.d.ts.map +1 -1
  56. package/packages/client-agent-team/lib/types/client/TeamMembersAction.js +2 -2
  57. package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts.map +1 -1
  58. package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +6 -2
  59. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts.map +1 -1
  60. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +28 -10
  61. package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
  62. package/packages/client-agent-team/lib/types/client/index.js +3 -4
  63. package/packages/client-agent-team/lib/types/client/locales.d.ts +36 -16
  64. package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
  65. package/packages/client-agent-team/lib/types/client/locales.js +36 -16
  66. package/packages/client-agent-team/lib/types/client/slots.d.ts +0 -1
  67. package/packages/client-agent-team/lib/types/client/slots.d.ts.map +1 -1
  68. package/packages/client-agent-team/lib/types/client/team-changes.d.ts +7 -1
  69. package/packages/client-agent-team/lib/types/client/team-changes.d.ts.map +1 -1
  70. package/packages/client-agent-team/lib/types/client/team-changes.js +62 -31
  71. package/packages/client-agent-team/lib/types/client/team-formatters.d.ts +38 -5
  72. package/packages/client-agent-team/lib/types/client/team-formatters.d.ts.map +1 -1
  73. package/packages/client-agent-team/lib/types/client/team-formatters.js +54 -7
  74. package/packages/tool-agent-team/README.md +2 -2
  75. package/packages/tool-agent-team/README.zh.md +2 -2
  76. package/packages/tool-agent-team/lib/index.js +29 -16
  77. package/packages/tool-agent-team/lib/types/index.d.ts.map +1 -1
  78. package/packages/agent-team/lib/progress-nudge.js +0 -328
  79. package/packages/agent-team/lib/types/progress-nudge.d.ts +0 -136
  80. package/packages/agent-team/lib/types/progress-nudge.d.ts.map +0 -1
  81. package/packages/client-agent-team/lib/types/client/TeamSettings.d.ts +0 -3
  82. package/packages/client-agent-team/lib/types/client/TeamSettings.d.ts.map +0 -1
  83. package/packages/client-agent-team/lib/types/client/TeamSettings.js +0 -5
package/README.md CHANGED
@@ -21,13 +21,13 @@ An opt-in plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-
21
21
 
22
22
  ## Preview
23
23
 
24
- Agent Team is opt-in: after installation the ordinary DSH page stays as-is, and Team mode is one additional entry in the sidebar footer.
24
+ Team mode lives inside the ordinary DSH Web UI: Channels carry the discussion, the Inbox gathers what needs you, and Task Threads keep one line of progress.
25
25
 
26
- ![Ordinary DSH Web UI with the Team entry highlighted in the sidebar footer](assets/readme/dsh-entry.png)
26
+ ![Channel in the DSH Web UI: member roster, @mentions, and Task references in the message flow](assets/readme/channel.png)
27
27
 
28
- Entering Team mode shows Channels, managed Agents, and the collaboration timeline:
28
+ The Human Inbox leads with unread Threads that need you, followed by recently active ones:
29
29
 
30
- ![Team mode in the DSH Web UI: Channels and online Agent members in the sidebar, with the Main Channel showing Task references](assets/readme/team-mode.png)
30
+ ![Human Inbox in the DSH Web UI: unread Threads that need you on top, recently active Threads below](assets/readme/inbox.png)
31
31
 
32
32
  ### Task Threads
33
33
 
package/README.zh.md CHANGED
@@ -21,13 +21,13 @@
21
21
 
22
22
  ## 预览
23
23
 
24
- Agent Team 是按需启用的:安装后普通 DSH 页面保持原样,Team mode 只是侧栏底部多出的一个入口。
24
+ Team mode 就在普通 DSH Web UI 里:Channel 承载讨论,收件箱收拢需要你的事项,Task Thread 把一条工作线保留在同一条上下文里。
25
25
 
26
- ![普通 DSH Web UI,侧栏底部高亮 Team 入口](assets/readme/dsh-entry.png)
26
+ ![DSH Web UI 中的 Channel:成员名单、@提及与消息流中的 Task 引用](assets/readme/channel.png)
27
27
 
28
- 进入 Team mode 后是频道、受管 Agent 与协作时间线:
28
+ Human 收件箱把需要你的未读 Thread 置顶,其下是最近活跃:
29
29
 
30
- ![DSH Web UI 中的 Team mode:侧边栏展示频道与在线 Agent 成员;Main Channel 展示 Task 引用](assets/readme/team-mode.png)
30
+ ![DSH Web UI 中的 Human 收件箱:需要你的未读 Thread 在上,最近活跃的 Thread 在下](assets/readme/inbox.png)
31
31
 
32
32
  ### Task Thread
33
33
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wowyuarm/dsh-agent-team",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "description": "A persistent agent team for long-running collaboration in DeepSeek Harness",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,7 +25,8 @@
25
25
  "clean:build-outputs": "node scripts/clean-build-outputs.mjs",
26
26
  "check:docs": "node scripts/check-docs.mjs",
27
27
  "check:core-skills": "node scripts/check-core-skills.mjs",
28
- "test": "npm run generate:typert && npm run check:docs && npm run check:core-skills && vitest run",
28
+ "check:boundaries": "node scripts/check-package-boundaries.mjs",
29
+ "test": "npm run generate:typert && npm run check:docs && npm run check:core-skills && npm run check:boundaries && vitest run",
29
30
  "test:browser": "npm run build && node scripts/run-browser-test.mjs",
30
31
  "preview": "node scripts/check-preview-credentials.mjs && npm run build && node scripts/run-preview.mjs",
31
32
  "preview:ui": "npm run build && node scripts/run-ui-preview.mjs",
@@ -28,11 +28,11 @@ Activation applies `tools.allow` as a scoped restriction over the composed prese
28
28
 
29
29
  Skills are Member-private: the preset has no shared skill-filesystem row, and the Host registers one provider per Member that scans exactly the plugin's bundled read-only core skills (`packages/agent-team/core-skills/` — the `member-skill-manager` meta skill that owns all skill craft guidance) plus that Member's writable `skills/` directory under its private memory path (default roots excluded). Installing is writing into the Member's own directory — directory form `skills/<name>/SKILL.md` with optional references and scripts, or a flat `.md` — and there is deliberately no upload Remote. The persona itself only states the private-space physical facts; the meta skill's description routes skill-management work to it. `skills.allow` filters the catalog through a live selection ref swapped at the same turn boundary; the filesystem watcher feeds discovery after a self-install.
30
30
 
31
- Every team-managed session records `danger-full-access`. Project cwd remains the Workspace path, while private memory lives under `$DSH_HOME/agent-team/members/<memberId>/`. An untitled Member session is named with its handle through the session-title service, so the ordinary Session list shows the Member identity; an explicit rename or any earlier title always wins. The isolated `team-member` preset also provides coding tools including model-facing web search, Workspace instruction discovery, and Team protocol guidance. The host owns the shared Web service and provider; the preset mounts only the model-facing web tool. Its lowercase `memory.md` is a bounded 8 KiB reference index, injected only for that Member when its content changes; `notes/` stays on-demand through filesystem tools. Over-budget indexes receive a maintenance warning, not silent truncation. Ordinary sessions and forks receive no Team identity or private-memory context. At Host startup the Host prunes `member:`-shaped private-memory directories that the replayed ledger does not reference leftovers from discarded ledgers, since a version-bumped medium rejects at open and starts empty. Prune failures fail startup; entries outside the `member:` shape are left untouched.
31
+ Every team-managed session records `danger-full-access`. Project cwd remains the Workspace path, while private memory lives under `$DSH_HOME/agent-team/members/<memberId>/`. An untitled Member session is named with its handle through the session-title service, so the ordinary Session list shows the Member identity; an explicit rename or any earlier title always wins. The isolated `team-member` preset also provides coding tools including model-facing web search, Workspace instruction discovery, and Team protocol guidance. The host owns the shared Web service and provider; the preset mounts only the model-facing web tool. Its lowercase `memory.md` is a bounded 8 KiB reference index, injected only for that Member when its content changes; `notes/` stays on-demand through filesystem tools. Over-budget indexes receive a maintenance warning, not silent truncation. Ordinary sessions and forks receive no Team identity or private-memory context. At Host startup every enabled Member's private memory is provisioned and an `inactive` Member's is removed with its Session archived; directories the replayed ledger does not reference are never pruned, so leftovers from a discarded ledger stay on disk for the operator. Both that removal and the activation-time migration of a pre-fix colon directory act only on paths inside the running process's own `$DSH_HOME/agent-team/members/`: a recorded path naming a different DSH home (an isolated test home, a second instance) is refused with a warning rather than renamed or deleted, because acting on it would take a Member's real private memory out of its home.
32
32
 
33
33
  Adding a Member to a Channel grants future read/send/claim authority but injects no historical Messages into the member session. Every top-level Message creates a Thread; new Client/tool starts explicitly choose taskless while released-client omission remains taskful, and a Human can later promote a taskless Thread by atomically adding its Task overlay and a structured `promote` Task activity. Thread Attention starts when a Thread is created, a Claim is created, a member follows, a top-level Message mentions them, or a Human confirms an invitation. Ordinary unread is derived from Attention; structured mentions create durable direct markers, while terminal Task changes retain sparse Activity markers for affected followers after Attention ends. `team_inbox` and Thread reads are Host projections, not Session inbox contents. A direct mention context includes its Message body and source; Task/Claim changes — including promotion — include concise transition facts; ordinary unread carries a body-free Thread-first route. Pending hints are coalesced, ignored hints do not loop, and resume/error recovery derives a new hint from durable unread state. For recoverable service failures, the Host wakes a Member after each of the first two consecutive `agent/error` occurrences, then leaves the third failure for the operator; only a clean turn resets that run.
34
34
 
35
- Member replies require the exact current Thread revision and atomically update Message and Thread facts. `threadRef` is the primary collaboration identity; released task-only Clients may send a Host-resolved `taskRef` alias for taskful Threads, while Task/Claim operations remain Task-ref based. Unread work must be read before a mutation; stale revisions are rejected after that unread gate. A closed Task rejects replies and new Attention; reopening restores the Task without restoring prior Attention. Taskless Threads still support replies, follow, mentions, Inbox, read, and history, but have no Claims or Task-resolution path. Top-level Messages may mention Agents directly: mentioned Members start following the new Thread. In an existing Thread, a Human reply mentioning an unfollowed Agent requires a process-local, one-use confirmation token before the operation commits, while such Member replies are rejected with member_not_following. Message facts carry their structured mention refs, and the Client renders mention chips only for those Members. Claim/done/release and Task changes are ordered host-authored Activities. Active Claims exclude only the same normalized Direction; different Directions can run concurrently. Task state is derived from Claims unless Human acceptance or closure overrides it. Close releases active Claims and clears Thread Attention atomically. Member removal marks the member inactive, releases owned active Claims, clears its Attention and direct markers, and archives the session after the durable commit. Message and Activity facts share one bounded sequence cursor.
35
+ Member replies require the exact current Thread revision and atomically update Message and Thread facts. `threadRef` is the primary collaboration identity; released task-only Clients may send a Host-resolved `taskRef` alias for taskful Threads, while Task/Claim operations remain Task-ref based. Unread work must be read before a mutation; stale revisions are rejected after that unread gate. A closed Task rejects replies and new Attention; reopening restores the Task without restoring prior Attention. Taskless Threads still support replies, follow, mentions, Inbox, read, and history, but have no Claims or Task-resolution path. Top-level Messages may mention Agents directly: mentioned Members start following the new Thread. In an existing Thread, a Human reply mentioning a Member that is not currently following requires a process-local, one-use confirmation token before the operation commits, while such a Member reply commits and delivers only to Members the Thread has ever carried, reporting the rest as undelivered. Mentions are authored in the Message body as `@Handle` and resolved by the Host against the Channel's addressable names; Message facts carry the resolved refs, and the Client renders mention chips only for those Members. Claim/done/release and Task changes are ordered host-authored Activities. Active Claims exclude only the same normalized Direction; different Directions can run concurrently. Task state is derived from Claims unless Human acceptance or closure overrides it. Close releases active Claims and clears Thread Attention atomically. Member removal marks the member inactive, releases owned active Claims, clears its Attention and direct markers, and archives the session after the durable commit. Message and Activity facts share one bounded sequence cursor.
36
36
 
37
37
  `changes()` is the Client invalidation stream. Each request declares one optional `scope` — workspace, channel, or thread — plus an abortable transport signal; a committed operation wakes only waiters whose scope matches the scopes derived from that operation (member lifecycle and presence wake their Workspace; content operations wake their Channel and Thread). A Thread read derives no scope, because it advances only the reader's private watermark — and a read that finds nothing unread for its reader (no watermark to advance, no marker to consume) appends no operation at all: it answers with the same projection-derived picture and no receipt, so an already-read Thread costs neither a durable write nor a replay. After each commit the Host notifies only the Members whose Inbox projection the operation can have changed — the operation's Attention/marker delta plus current followers of the touched Threads — never every live Agent.
38
38
 
@@ -28,11 +28,11 @@ Activation 把 `tools.allow` 作为 scoped restriction 应用在已组合的 pre
28
28
 
29
29
  Skills 是 Member 私有的:preset 不带共享 skill-filesystem row,Host 为每个 Member 注册一个 provider,只扫插件内置的只读 core skills(`packages/agent-team/core-skills/`——`member-skill-manager` meta skill,全部 skill 写作/安装/credentials 引导都在它里面)加该 Member 可写的私有 `skills/` 目录(排除默认 roots)。安装就是往自己目录写——目录形态 `skills/<name>/SKILL.md` + 可选 references/scripts,或平铺 `.md`——有意不提供上传 Remote。persona 只陈述私有空间物理事实,meta skill 的 description 负责"涉及 skill 管理工作时先读我"。`skills.allow` 通过同一 turn 边界换装的 live selection ref 过滤 catalog;自装后的发现由 filesystem watcher 驱动。
30
30
 
31
- 每个 Team 管理的 session 都会持久写入 `danger-full-access`。项目 cwd 仍是 Workspace 路径,私有记忆位于 `$DSH_HOME/agent-team/members/<memberId>/`。没有标题的 Member session 会通过 session-title service 以 handle 命名,普通 Session 列表因此直接显示 Member 身份;显式重命名或任何既有标题始终优先。隔离的 `team-member` preset 还提供 coding 工具、面向模型的 Web 搜索、Workspace instruction discovery 和 Team protocol guidance。共享的 Web service 与 provider 仍由 Host 持有;preset 只挂载面向模型的 Web tool。小写 `memory.md` 是有界的 8 KiB 参考索引,只有该 Member 的内容变化时才注入;`notes/` 只通过 filesystem tools 按需读取。超预算索引只产生维护警告,不静默截断。普通 session 和 fork 不获得 Team 身份或私有记忆上下文。Host 启动时会清理重放 ledger 不再引用的 `member:` 形态私有记忆目录——这些是 ledger 被丢弃后的遗留(版本提升的 medium open 时被拒绝并以空状态重启)。清理失败会使启动失败;非 `member:` 形态的条目保持原样。
31
+ 每个 Team 管理的 session 都会持久写入 `danger-full-access`。项目 cwd 仍是 Workspace 路径,私有记忆位于 `$DSH_HOME/agent-team/members/<memberId>/`。没有标题的 Member session 会通过 session-title service 以 handle 命名,普通 Session 列表因此直接显示 Member 身份;显式重命名或任何既有标题始终优先。隔离的 `team-member` preset 还提供 coding 工具、面向模型的 Web 搜索、Workspace instruction discovery 和 Team protocol guidance。共享的 Web service 与 provider 仍由 Host 持有;preset 只挂载面向模型的 Web tool。小写 `memory.md` 是有界的 8 KiB 参考索引,只有该 Member 的内容变化时才注入;`notes/` 只通过 filesystem tools 按需读取。超预算索引只产生维护警告,不静默截断。普通 session 和 fork 不获得 Team 身份或私有记忆上下文。Host 启动时会为每个 enabled Member 准备其私有记忆,并对 `inactive` Member 归档其 Session 后删除其私有记忆;重放 ledger 不引用的目录一律不清理,被丢弃 ledger 的遗留物留在磁盘上交给操作者处置。这项删除与 activation 时对旧式 colon 目录的迁移都只作用于当前进程自己的 `$DSH_HOME/agent-team/members/` 之内的路径:记录里指向另一个 DSH home(隔离测试 home、第二个实例)的路径会被拒绝并告警,既不改名也不删除——对它动手等于把 Member 的真实私有记忆搬出它自己的 home。
32
32
 
33
33
  把 Member 加入 Channel 只授予之后的 read/send/claim authority,不向 Member session 注入历史 Message。每条顶层 Message 都创建 Thread;新 Client/tool 显式选择 taskless,released Client 省略意图时仍保持 taskful;Human 可之后 promotion taskless Thread,原子附加 Task overlay 与结构化 `promote` Task activity。创建 Thread、创建 Claim、显式 follow、顶层消息 mention 到、或 Human 确认邀请会开始 Thread Attention。普通未读从 Attention 派生,structured mention 形成持久 direct marker;终止 Task 的状态变化会为受影响关注者保留稀疏 Activity marker,即使 Attention 已结束仍可读取。`team_inbox` 和 Thread read 是 Host projection,不是 Session inbox 内容。Direct mention context 包含消息正文和来源,Task/Claim 变化(含 promotion)包含简短状态事实,普通未读提供无正文的 Thread-first 路由。提示会合并,忽略提示不会形成循环,resume/runtime error recovery 会从持久未读状态重新判断是否提示。对于可恢复的服务错误,Host 会在连续 `agent/error` occurrence 的前两次后唤醒 Member;第 3 次错误则交给 operator,只有 clean turn 才会重置这段连续错误。
34
34
 
35
- Member reply 必须携带准确的当前 Thread revision,并在一个 operation 内更新 Message 和 Thread facts。`threadRef` 是协作主身份;released task-only Client 可为 taskful Thread 传入 Host-resolved `taskRef` alias,而 Task/Claim 操作仍以 Task ref 为准。未读工作必须先 read;revision 过期时拒绝写入。Closed Task 拒绝 reply 和新的 Attention;reopen 恢复 Task,但不恢复之前的 Attention。taskless Thread 仍支持 reply、follow、mention、Inbox、read 和 history,但没有 Claim 或 Task resolution path。顶层消息可以直接 mention Agent:被 mention 的 Member 会开始关注新 Thread。在既有 Thread 中,Human 的 reply 提到 unfollowed Agent 时必须先取得 process-local one-use confirmation token 才提交 operation;Member 的此类 reply 会以 member_not_following 拒绝。Message fact 携带自身的 structured mention refs,Client 只为这些 Member 渲染 mention chip。claim/done/release 和 Task change 是有序的 host-authored Activity。Active Claim 只排斥相同的 normalized Direction;不同 Direction 可以并行。Task status 从 Claims 派生,Human accept/close 是覆盖事实。Close 原子释放 active Claims 并清除 Thread Attention。Member remove 原子标记 inactive、释放 owned active Claims、清除该成员的 Attention 和 direct markers,再归档 session。Message 与 Activity facts 共用一个有界 sequence cursor。
35
+ Member reply 必须携带准确的当前 Thread revision,并在一个 operation 内更新 Message 和 Thread facts。`threadRef` 是协作主身份;released task-only Client 可为 taskful Thread 传入 Host-resolved `taskRef` alias,而 Task/Claim 操作仍以 Task ref 为准。未读工作必须先 read;revision 过期时拒绝写入。Closed Task 拒绝 reply 和新的 Attention;reopen 恢复 Task,但不恢复之前的 Attention。taskless Thread 仍支持 reply、follow、mention、Inbox、read 和 history,但没有 Claim 或 Task resolution path。顶层消息可以直接 mention Agent:被 mention 的 Member 会开始关注新 Thread。在既有 Thread 中,Human 的 reply 提到当前未 follow Member 时必须先取得 process-local one-use confirmation token 才提交 operation;Member 的此类 reply 会提交,但只送达该 Thread 曾经承载过的 Member,其余在结果里报告为未送达。mention 在 Message 正文里以 `@Handle` 撰写,由 Host 按 Channel 的可寻址名字解析;Message fact 携带解析后的 refs,Client 只为这些 Member 渲染 mention chip。claim/done/release 和 Task change 是有序的 host-authored Activity。Active Claim 只排斥相同的 normalized Direction;不同 Direction 可以并行。Task status 从 Claims 派生,Human accept/close 是覆盖事实。Close 原子释放 active Claims 并清除 Thread Attention。Member remove 原子标记 inactive、释放 owned active Claims、清除该成员的 Attention 和 direct markers,再归档 session。Message 与 Activity facts 共用一个有界 sequence cursor。
36
36
 
37
37
  `changes()` 是 Client 失效通知流。每个请求声明一个可选 `scope`(workspace、channel 或 thread)和可取消的传输 signal;一次提交的 operation 只唤醒 scope 与该 operation 派生范围匹配的 waiter(成员生命周期与 presence 唤醒其 Workspace,内容操作唤醒其 Channel 与 Thread)。Thread read 不派生任何 scope,因为它只推进读者自己的私有水位——而一次读如果对读者没有任何未读(没有水位可推进、没有 marker 可消费),就完全不追加 operation:它返回同一份由 projection 派生的画面且不带 receipt,所以已读完的 Thread 既不付一次持久写、也不付一次重放。每次提交后,Host 只通知 Inbox projection 可能被该 operation 改变的 Member——即 operation 的 Attention/marker delta 加上被触及 Thread 的当前关注者——而不是全部在线 Agent。
38
38
 
@@ -34,7 +34,11 @@ const TEAM_ATTENTION_BOUNDARY_LABEL = 'Team attention change';
34
34
  const TEAM_CLAIM_BOUNDARY_LABEL = 'Team task claim change';
35
35
  /**
36
36
  * Notice summaries that are pure reminders, never semantic Team facts: a
37
- * progress nudge or a recovery instruction must not become a return anchor.
37
+ * recovery instruction must not become a return anchor. `Progress visibility
38
+ * reminder` is a historical decoder — the progress-nudge system was removed,
39
+ * but session logs recorded before its removal still carry those notices, and
40
+ * the projection keeps recognizing them (same pattern as the legacy
41
+ * `new_context` tool name below).
38
42
  */
39
43
  const REMINDER_NOTICE_SUMMARIES = new Set(['Progress visibility reminder', 'Recovery: continue your interrupted work.']);
40
44
  /** Whether one notice summary is a pure reminder (never a semantic Team fact). */
@@ -57,14 +57,13 @@ import { carriedInputOf, checkpointByRef, checkpointRefFor, contextProjectionFol
57
57
  import { advanceOwnedSessionEventCursor } from "./session-event-cursor.js";
58
58
  import { AGENT_TEAM_HUMAN_MEMBER_ID, AgentTeamLedger, agentTeamHumanActor } from "./ledger.js";
59
59
  import { AGENT_TEAM_TOOL_NAMES, deepCopyCapabilities, memberMemoryDirectoryName, MemberRuntime } from "./member-runtime.js";
60
- import { ProgressNudgeCoordinator } from "./progress-nudge.js";
61
60
  import { classifyRecoverableError, RecoveryCoordinator, RECOVERY_MAX_CONSECUTIVE_ERRORS } from "./recovery.js";
62
61
  import { SessionRemediation, handoffAlreadyInLog } from "./session-remediation.js";
63
62
  import { StoredSessionReadError, StoredSessionReader, sessionFailureOf } from "./stored-session-reader.js";
64
63
  import { agentTeamDomainSpec } from "./spec.js";
65
64
  import { formatTeamTimestamp } from "./time-format.js";
66
65
  export { agentTeamDomainSpec, agentTeamOperationSchema } from "./spec.js";
67
- export { AGENT_TEAM_HUMAN_MEMBER_ID, AGENT_TEAM_INITIALIZE_REQUEST_ID } from "./ledger.js";
66
+ export { AGENT_TEAM_HUMAN_HANDLE, AGENT_TEAM_HUMAN_MEMBER_ID, AGENT_TEAM_INITIALIZE_REQUEST_ID } from "./ledger.js";
68
67
  export { AGENT_TEAM_TOOL_NAMES } from "./member-runtime.js";
69
68
  /** Process-stable marker carried by the final Team message tool definition. */
70
69
  export const AGENT_TEAM_PRESET_MARKER = Symbol.for('@wowyuarm/dsh-agent-team.preset');
@@ -302,22 +301,6 @@ let AgentTeam = (() => {
302
301
  this.ctx.logger.warn(`agent-team: member '${this.memberLabel(memberId)}' reached ${consecutiveFailures}/${RECOVERY_MAX_CONSECUTIVE_ERRORS} consecutive recoverable failures; leaving it in error for the operator`);
303
302
  },
304
303
  });
305
- /**
306
- * Advisory progress-visibility nudges. Purely in-process: the ledger owns
307
- * eligibility, this coordinator owns counting and notices, and neither ever
308
- * writes Team facts. See docs/team-collaboration.md for the regimes.
309
- */
310
- progressNudge = new ProgressNudgeCoordinator({
311
- agentForMember: memberId => this.handles.get(memberId)?.agent,
312
- targetsForMember: memberId => this.requireLedger().progressNudgeTargets(memberId),
313
- sessionLogForMember: (memberId, sessionId) => {
314
- const handle = this.handles.get(memberId);
315
- if (handle === undefined || handle.agent.session.id !== sessionId)
316
- return undefined;
317
- return { events: handle.agent.session.ownEvents() };
318
- },
319
- log: message => { this.ctx.logger.warn(message); },
320
- });
321
304
  /**
322
305
  * Incremental fold state for {@link contextManagement}'s projection lookup:
323
306
  * one entry per Member, replaced when that Member's Session changes. Keying
@@ -431,14 +414,13 @@ let AgentTeam = (() => {
431
414
  this.emitPresenceChanged(member.workspaceId);
432
415
  }
433
416
  });
434
- // Progress nudges count every `tool/call` of each Member Session. The
435
- // store's dispatch carrier is untagged, so a scope-tagged listener inside
436
- // the Agent setup would receive nothing; one root listener that maps the
437
- // session id back to its Member is the seam that works (same shape as the
438
- // `agent/status` listener above). The first turn of a freshly published
439
- // Member cannot race this: `handles.set()` precedes the same activation
440
- // continuation that publishes the Agent, so by the time any tool call
441
- // streams, the map lookup succeeds.
417
+ // The store's dispatch carrier is untagged, so a scope-tagged listener
418
+ // inside the Agent setup would receive nothing; one root listener that
419
+ // maps the session id back to its Member is the seam that works (same
420
+ // shape as the `agent/status` listener above). The first turn of a
421
+ // freshly published Member cannot race this: `handles.set()` precedes the
422
+ // same activation continuation that publishes the Agent, so by the time
423
+ // any tool call streams, the map lookup succeeds.
442
424
  this.ctx.on('session/event', (session, event) => {
443
425
  const memberId = this.memberBySessionId.get(session.id);
444
426
  if (memberId === undefined)
@@ -446,7 +428,6 @@ let AgentTeam = (() => {
446
428
  const handle = this.handles.get(memberId);
447
429
  if (handle === undefined || handle.agent.session.id !== session.id)
448
430
  return;
449
- this.progressNudge.onSessionEvent(memberId, session.id, handle.agent, event);
450
431
  // A successful assistant response ends any open provider-overflow
451
432
  // recovery sequence for this Member.
452
433
  if (event.type === 'assistant/message')
@@ -460,7 +441,6 @@ let AgentTeam = (() => {
460
441
  this.accepting = false;
461
442
  this.remediation = undefined;
462
443
  this.recovery.dispose();
463
- this.progressNudge.dispose();
464
444
  this.contextManagement.dispose();
465
445
  this.pressurePolicy.dispose();
466
446
  if (this.attachmentGcTimer !== undefined)
@@ -794,9 +774,6 @@ let AgentTeam = (() => {
794
774
  // Drop the old handle's transient state: pending recovery episodes and
795
775
  // error markers belong to the disposed agent, not to the Member.
796
776
  this.recovery.stopTracking(memberId);
797
- // The fresh Session may re-earn one Claim suggestion per Thread; the
798
- // old Session's one-shot records must not leak into it.
799
- this.progressNudge.stopTracking(memberId);
800
777
  // The context admission gate stays armed through disposal: input racing
801
778
  // the retire window must still be captured for the new generation, and
802
779
  // the coordinator drops its own bookkeeping only after the swap settles.
@@ -947,9 +924,6 @@ let AgentTeam = (() => {
947
924
  if (this.isInboxNotice(pending))
948
925
  handle.agent.inbox.remove(pending.id);
949
926
  }
950
- // Recovery carries the concrete interrupted work; a queued progress nudge
951
- // is stale next to it and must not survive as a second reminder.
952
- this.progressNudge.revokePendingNotice(member.memberId);
953
927
  handle.agent.steer(hint);
954
928
  }
955
929
  /** Automatic-recovery wakeup; throwing tells the coordinator the target is gone. */
@@ -1870,8 +1844,9 @@ let AgentTeam = (() => {
1870
1844
  const source = event.data.source;
1871
1845
  if (source?.kind !== 'plugin')
1872
1846
  continue;
1873
- // Reminder notices never enter attribution — a progress nudge or a
1874
- // recovery instruction is not a Team fact.
1847
+ // Reminder notices never enter attribution — a recovery instruction
1848
+ // (or a historical progress-nudge notice, kept decodable in session
1849
+ // logs recorded before that system was removed) is not a Team fact.
1875
1850
  if (source.form === 'notice' && source.summary !== undefined && isReminderNoticeSummary(source.summary))
1876
1851
  continue;
1877
1852
  const text = event.data.content.filter(block => block.type === 'text').map(block => block.text ?? '').join('\n');
@@ -2511,10 +2486,6 @@ let AgentTeam = (() => {
2511
2486
  }
2512
2487
  const ledger = this.requireLedger();
2513
2488
  this.emitChanged(ledger.changeScopesOf(operation));
2514
- // Nudge reconciliation precedes notifyMember: a committed reply both
2515
- // resets the author's silence and cancels any of its queued nudge before
2516
- // the Inbox notice (higher priority) is considered.
2517
- this.progressNudge.onCommitted(operation);
2518
2489
  for (const memberId of ledger.affectedMembersOf(operation)) {
2519
2490
  const handle = this.handles.get(memberId);
2520
2491
  if (handle !== undefined)
@@ -2594,9 +2565,6 @@ let AgentTeam = (() => {
2594
2565
  const existingInboxHint = pending.find(message => this.isInboxNotice(message));
2595
2566
  if (existingInboxHint !== undefined)
2596
2567
  agent.inbox.remove(existingInboxHint.id);
2597
- // A durable Inbox notice outranks a queued progress nudge; revoke it so
2598
- // the model reads concrete unread work instead of a generic reminder.
2599
- this.progressNudge.revokePendingNotice(member.memberId);
2600
2568
  const hint = createUserMessage({
2601
2569
  content: [{ type: 'text', text: this.notificationText(notifications, member.memberId) }],
2602
2570
  source: { kind: 'plugin', plugin: AGENT_TEAM_PLUGIN_ID, form: 'notice', summary: INBOX_NOTICE_SUMMARY },
@@ -2734,7 +2702,6 @@ let AgentTeam = (() => {
2734
2702
  }
2735
2703
  clearMemberRecoveryState(member) {
2736
2704
  this.recovery.stopTracking(member.memberId);
2737
- this.progressNudge.stopTracking(member.memberId);
2738
2705
  this.clearMemberFailure(member.memberId, 'runtime');
2739
2706
  this.clearMemberNotificationState(member.memberId);
2740
2707
  }