@wowyuarm/dsh-agent-team 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +7 -1
  2. package/README.zh.md +7 -1
  3. package/package.json +1 -1
  4. package/packages/agent-team/README.md +3 -3
  5. package/packages/agent-team/README.zh.md +3 -3
  6. package/packages/agent-team/lib/index.js +38 -9
  7. package/packages/agent-team/lib/ledger.js +275 -108
  8. package/packages/agent-team/lib/spec.js +27 -11
  9. package/packages/agent-team/lib/typert.host.js +185 -86
  10. package/packages/agent-team/lib/typert.remote-client.d.ts +3 -1
  11. package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
  12. package/packages/agent-team/lib/typert.remote-client.js +139 -59
  13. package/packages/agent-team/lib/types/index.d.ts +12 -7
  14. package/packages/agent-team/lib/types/index.d.ts.map +1 -1
  15. package/packages/agent-team/lib/types/ledger.d.ts +16 -2
  16. package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
  17. package/packages/agent-team/lib/types/spec.d.ts.map +1 -1
  18. package/packages/agent-team/lib/types/types.d.ts +69 -30
  19. package/packages/agent-team/lib/types/types.d.ts.map +1 -1
  20. package/packages/agent-team/preset/team-member/agent.cordis.yml +1 -1
  21. package/packages/client-agent-team/README.md +2 -1
  22. package/packages/client-agent-team/README.zh.md +2 -1
  23. package/packages/client-agent-team/lib/client.js +625 -319
  24. package/packages/client-agent-team/lib/client.js.map +1 -1
  25. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +34 -12
  26. package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts.map +1 -1
  27. package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +14 -10
  28. package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts +6 -1
  29. package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts.map +1 -1
  30. package/packages/client-agent-team/lib/types/client/TeamComposer.js +4 -4
  31. package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts +1 -1
  32. package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts.map +1 -1
  33. package/packages/client-agent-team/lib/types/client/TeamConversation.js +3 -3
  34. package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts +4 -1
  35. package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts.map +1 -1
  36. package/packages/client-agent-team/lib/types/client/TeamMessage.js +16 -9
  37. package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts +2 -1
  38. package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts.map +1 -1
  39. package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +71 -16
  40. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts.map +1 -1
  41. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +2 -1
  42. package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
  43. package/packages/client-agent-team/lib/types/client/index.js +1 -0
  44. package/packages/client-agent-team/lib/types/client/locales.d.ts +24 -0
  45. package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
  46. package/packages/client-agent-team/lib/types/client/locales.js +24 -0
  47. package/packages/client-agent-team/lib/types/client/navigation.d.ts +1 -1
  48. package/packages/client-agent-team/lib/types/client/navigation.d.ts.map +1 -1
  49. package/packages/client-agent-team/lib/types/client/navigation.js +12 -6
  50. package/packages/client-agent-team/lib/types/client/slots.d.ts +2 -1
  51. package/packages/client-agent-team/lib/types/client/slots.d.ts.map +1 -1
  52. package/packages/client-agent-team/lib/types/client/task-refs.d.ts +1 -1
  53. package/packages/client-agent-team/lib/types/client/task-refs.d.ts.map +1 -1
  54. package/packages/client-agent-team/lib/types/client/task-refs.js +1 -1
  55. package/packages/client-agent-team/lib/types/client/team-formatters.d.ts +9 -0
  56. package/packages/client-agent-team/lib/types/client/team-formatters.d.ts.map +1 -1
  57. package/packages/client-agent-team/lib/types/client/team-formatters.js +13 -0
  58. package/packages/tool-agent-team/README.md +7 -7
  59. package/packages/tool-agent-team/README.zh.md +7 -7
  60. package/packages/tool-agent-team/lib/index.js +38 -28
  61. package/packages/tool-agent-team/lib/types/index.d.ts.map +1 -1
package/README.md CHANGED
@@ -13,7 +13,13 @@ An opt-in plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-
13
13
 
14
14
  ## Preview
15
15
 
16
- ![Team mode in the DSH Web UI: workspaces, channels, and agents in the sidebar; a Task thread with agent reports](assets/readme/team-mode.png)
16
+ ![Team mode in the DSH Web UI: Channels and seven online Agents in the sidebar; the Main Channel shows Task references and the composer’s task switch](assets/readme/team-mode.png)
17
+
18
+ ### Task Threads
19
+
20
+ A Task Thread keeps Claims, Agent handoffs, Human acceptance, and follow-up replies in one durable context.
21
+
22
+ ![Completed Task Thread in the DSH Web UI: a Claim, Agent handoffs, Human acceptance activity, and the reply composer](assets/readme/task-thread.png)
17
23
 
18
24
  ## Quick start
19
25
 
package/README.zh.md CHANGED
@@ -10,7 +10,13 @@
10
10
 
11
11
  ## 预览
12
12
 
13
- ![DSH Web UI 中的 Team mode:侧边栏是 Workspace、频道与 Agent;主区是一个 Task Thread,含 Agent 汇报](assets/readme/team-mode.png)
13
+ ![DSH Web UI 中的 Team mode:侧边栏展示频道与 7 位在线 Agent;Main 频道含 Task 引用和 composer 的作为任务开关](assets/readme/team-mode.png)
14
+
15
+ ### Task Thread
16
+
17
+ Task Thread 把 Claim、Agent 交接、Human 验收和后续回复保留在同一条可持续阅读的上下文中。
18
+
19
+ ![DSH Web UI 中已完成的 Task Thread:含 Claim、Agent 交接、Human 验收活动和回复 composer](assets/readme/task-thread.png)
14
20
 
15
21
  ## 快速开始
16
22
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wowyuarm/dsh-agent-team",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Help humans organize tasks and let agents collaborate - a Team plugin for DeepSeek Harness",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,9 +20,9 @@ Member creation commits one stable Member/session/Workspace/preset/private-memor
20
20
 
21
21
  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.
22
22
 
23
- Adding a Member to a Channel grants future read/send/claim authority but injects no historical Messages into the member session. Thread Attention starts when a Task 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 include concise transition facts; ordinary unread includes only a body-free Task 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.
23
+ 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.
24
24
 
25
- Member replies require the exact current Thread revision and atomically update Message and Thread facts. 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. 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.
25
+ 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.
26
26
 
27
27
  `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 commits durably but derives no scope, because it advances only the reader's private watermark. 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.
28
28
 
@@ -40,7 +40,7 @@ A team-enabled preset registers the five tools in its own agent scope and marks
40
40
 
41
41
  #### What the model sees
42
42
 
43
- An enabled Member may receive one bounded, coalesced context notification after durable unread work appears. Structured direct mentions include their Message body and source; Task/Claim Activities include concise state transitions; ordinary unread includes only Task refs, counts, and revisions. The notification is queued at the Agent's safe step boundary, so active model requests and tools are not interrupted. It routes the common path directly to `team_thread.read`; the model uses `team_inbox` only when it needs to triage remaining Threads.
43
+ An enabled Member may receive one bounded, coalesced context notification after durable unread work appears. Structured direct mentions include their Message body and source; Task/Claim Activities include concise state transitions; ordinary unread includes only a Thread-first route, counts, and revisions, with a Task overlay where present. The notification is queued at the Agent's safe step boundary, so active model requests and tools are not interrupted. It routes the common path directly to `team_thread.read`; the model uses `team_inbox` only when it needs to triage remaining Threads.
44
44
 
45
45
  #### Token effect
46
46
 
@@ -20,9 +20,9 @@ Service 使用 `ctx.storageDomain`、`ctx.workspaceRegistry`、`ctx.agents`、`c
20
20
 
21
21
  每个 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:` 形态的条目保持原样。
22
22
 
23
- 把 Member 加入 Channel 只授予之后的 read/send/claim authority,不向 Member session 注入历史 Message。创建 Task、创建 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 变化包含简短状态事实,普通未读只包含无正文的 Task 路由;提示会合并,忽略提示不会形成循环,resume/runtime error recovery 会从持久未读状态重新判断是否提示。对于可恢复的服务错误,Host 会在连续 `agent/error` occurrence 的前两次后唤醒 Member;第 3 次错误则交给 operator,只有 clean turn 才会重置这段连续错误。
23
+ 把 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 才会重置这段连续错误。
24
24
 
25
- Member reply 必须携带准确的当前 Thread revision,并在一个 operation 内更新 Message 和 Thread facts。未读工作必须先 read;revision 过期时拒绝写入。Closed Task 拒绝 reply 和新的 Attention;reopen 恢复 Task,但不恢复之前的 Attention。顶层消息可以直接 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。
25
+ 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。
26
26
 
27
27
  `changes()` 是 Client 失效通知流。每个请求声明一个可选 `scope`(workspace、channel 或 thread)和可取消的传输 signal;一次提交的 operation 只唤醒 scope 与该 operation 派生范围匹配的 waiter(成员生命周期与 presence 唤醒其 Workspace,内容操作唤醒其 Channel 与 Thread)。Thread read 会持久化提交但不派生任何 scope,因为它只推进读者自己的私有水位。每次提交后,Host 只通知 Inbox projection 可能被该 operation 改变的 Member——即 operation 的 Attention/marker delta 加上被触及 Thread 的当前关注者——而不是全部在线 Agent。
28
28
 
@@ -40,7 +40,7 @@ Team-enabled preset 在自身 Agent scope 注册五个工具,并用 `markAgent
40
40
 
41
41
  #### What the model sees
42
42
 
43
- 启用的 Member 在持久未读工作出现后,可能收到一次有界、合并的 context 通知。Structured direct mention 包含消息正文和来源;Task/Claim Activity 包含简短状态变化;普通未读只包含 Task ref、数量和 revision。通知通过 Agent 的安全 step 边界排队,正在执行的模型请求和工具不会被中断。常见路径可以直接调用 `team_thread.read`;只有需要跨 Thread 分流时才调用 `team_inbox`。
43
+ 启用的 Member 在持久未读工作出现后,可能收到一次有界、合并的 context 通知。Structured direct mention 包含消息正文和来源;Task/Claim Activity 包含简短状态变化;普通未读只包含 Thread-first 路由、数量和 revision,存在时附带 Task overlay。通知通过 Agent 的安全 step 边界排队,正在执行的模型请求和工具不会被中断。常见路径可以直接调用 `team_thread.read`;只有需要跨 Thread 分流时才调用 `team_inbox`。
44
44
 
45
45
  #### Token effect
46
46
 
@@ -98,6 +98,7 @@ let AgentTeam = (() => {
98
98
  let _recoverMember_decorators;
99
99
  let _updateMember_decorators;
100
100
  let _changeTask_decorators;
101
+ let _promoteThread_decorators;
101
102
  let _joinChannel_decorators;
102
103
  let _removeChannelMember_decorators;
103
104
  let _sendMessage_decorators;
@@ -122,6 +123,7 @@ let AgentTeam = (() => {
122
123
  _recoverMember_decorators = [Remote('recoverMember')];
123
124
  _updateMember_decorators = [Remote('updateMember')];
124
125
  _changeTask_decorators = [Remote('changeTask')];
126
+ _promoteThread_decorators = [Remote('promoteThread')];
125
127
  _joinChannel_decorators = [Remote('joinChannel')];
126
128
  _removeChannelMember_decorators = [Remote('removeChannelMember')];
127
129
  _sendMessage_decorators = [Remote('sendMessage')];
@@ -143,6 +145,7 @@ let AgentTeam = (() => {
143
145
  __esDecorate(this, null, _recoverMember_decorators, { kind: "method", name: "recoverMember", static: false, private: false, access: { has: obj => "recoverMember" in obj, get: obj => obj.recoverMember }, metadata: _metadata }, null, _instanceExtraInitializers);
144
146
  __esDecorate(this, null, _updateMember_decorators, { kind: "method", name: "updateMember", static: false, private: false, access: { has: obj => "updateMember" in obj, get: obj => obj.updateMember }, metadata: _metadata }, null, _instanceExtraInitializers);
145
147
  __esDecorate(this, null, _changeTask_decorators, { kind: "method", name: "changeTask", static: false, private: false, access: { has: obj => "changeTask" in obj, get: obj => obj.changeTask }, metadata: _metadata }, null, _instanceExtraInitializers);
148
+ __esDecorate(this, null, _promoteThread_decorators, { kind: "method", name: "promoteThread", static: false, private: false, access: { has: obj => "promoteThread" in obj, get: obj => obj.promoteThread }, metadata: _metadata }, null, _instanceExtraInitializers);
146
149
  __esDecorate(this, null, _joinChannel_decorators, { kind: "method", name: "joinChannel", static: false, private: false, access: { has: obj => "joinChannel" in obj, get: obj => obj.joinChannel }, metadata: _metadata }, null, _instanceExtraInitializers);
147
150
  __esDecorate(this, null, _removeChannelMember_decorators, { kind: "method", name: "removeChannelMember", static: false, private: false, access: { has: obj => "removeChannelMember" in obj, get: obj => obj.removeChannelMember }, metadata: _metadata }, null, _instanceExtraInitializers);
148
151
  __esDecorate(this, null, _sendMessage_decorators, { kind: "method", name: "sendMessage", static: false, private: false, access: { has: obj => "sendMessage" in obj, get: obj => obj.sendMessage }, metadata: _metadata }, null, _instanceExtraInitializers);
@@ -426,9 +429,11 @@ let AgentTeam = (() => {
426
429
  });
427
430
  }
428
431
  /**
429
- * Operator nudge for an error-stopped Member: steer a continuation prompt
430
- * into its live session. Runtime-only no ledger operation, no suspend.
431
- * Taking over manually also cancels any pending automatic recovery episode.
432
+ * Operator nudge for a Member that stopped making progress: steer a
433
+ * continuation prompt into its live session, rebuild it after an orphaned
434
+ * preset composition, or re-run activation when no live session exists.
435
+ * Runtime-only — no ledger operation, no suspend. Taking over manually also
436
+ * cancels any pending automatic recovery episode.
432
437
  */
433
438
  async recoverMember(request) {
434
439
  this.requireAccepting();
@@ -444,6 +449,16 @@ let AgentTeam = (() => {
444
449
  await this.reactivateMember(request.memberId);
445
450
  return Object.freeze({ status: this.memberStatus(member) });
446
451
  }
452
+ // A failed activation also leaves nothing to steer; re-running it is the
453
+ // only way back. A renewed failure stays non-throwing: the refreshed
454
+ // status carries the activation diagnostic for the sidebar.
455
+ if (handle === undefined) {
456
+ if (member.state !== 'enabled')
457
+ throw new Error(`Agent Member '${member.handle}' is ${member.state}; only enabled Members can be restarted`);
458
+ this.ctx.logger.info(`agent-team: restarting member '${member.handle}' after a failed activation`);
459
+ await this.reactivateMember(request.memberId);
460
+ return Object.freeze({ status: this.memberStatus(member) });
461
+ }
447
462
  this.ctx.logger.info(`agent-team: operator asked member '${member.handle}' to resume`);
448
463
  this.steerResume(member, this.manualResumeText());
449
464
  return Object.freeze({ status: this.memberStatus(member) });
@@ -545,6 +560,14 @@ let AgentTeam = (() => {
545
560
  this.emitCommittedOutcome(result);
546
561
  return result.value;
547
562
  }
563
+ /** Human-only promotion of a taskless Thread into a real Task plus public Message. */
564
+ async promoteThread(request) {
565
+ this.requireAccepting();
566
+ this.requireWorkspace(request.workspaceId);
567
+ const result = await this.requireLedger().promoteThread({ ...request, actor: agentTeamHumanActor() });
568
+ this.emitCommittedOutcome(result);
569
+ return result.value;
570
+ }
548
571
  /** Human-only Channel membership grant; it never injects historical Thread bodies. */
549
572
  async joinChannel(request) {
550
573
  const actor = this.humanCall(request.workspaceId);
@@ -564,7 +587,7 @@ let AgentTeam = (() => {
564
587
  this.emitCommitted(result.value.receipt);
565
588
  return result.value;
566
589
  }
567
- /** Human top-level Task creation; unfollowed Agent mentions use the two-send result. */
590
+ /** Human top-level Thread start; asTask attaches an optional Task overlay. */
568
591
  async sendMessage(request) {
569
592
  return this.sendMessageAs(this.humanCall(request.workspaceId), request);
570
593
  }
@@ -667,7 +690,7 @@ let AgentTeam = (() => {
667
690
  this.requireWorkspace(request.workspaceId);
668
691
  return this.requireLedger().view(request);
669
692
  }
670
- /** Agent-only top-level Task creation. Workspace identity is verified against the live binding. */
693
+ /** Agent-only top-level Thread start. Workspace identity is verified against the live binding. */
671
694
  async sendMessageForAgent(agent, request) {
672
695
  return this.sendMessageAs(this.memberCall(agent, request.workspaceId), request);
673
696
  }
@@ -1086,7 +1109,8 @@ let AgentTeam = (() => {
1086
1109
  const sender = fact.message.sender === AGENT_TEAM_HUMAN_MEMBER_ID
1087
1110
  ? 'human' : this.requireLedger().getMember(fact.message.sender)?.handle ?? fact.message.sender;
1088
1111
  const detail = ['Direct Team mention', `From: ${sender}`, `Channel: ${item.channelRef}`,
1089
- `Task: ${item.task.taskRef}`, `Thread: ${item.thread.threadRef}`, `Message ref: ${fact.message.messageRef}`,
1112
+ ...(item.task === undefined ? [] : [`Task: ${item.task.taskRef}`]),
1113
+ `Thread: ${item.thread.threadRef}`, `Message ref: ${fact.message.messageRef}`,
1090
1114
  `Message: ${this.boundedNotificationBody(fact.message.body)}`].join('\n');
1091
1115
  if (append(detail))
1092
1116
  detailedFactCount += 1;
@@ -1098,12 +1122,14 @@ let AgentTeam = (() => {
1098
1122
  }
1099
1123
  }
1100
1124
  const ordinaryCount = facts.filter(entry => entry.fact.kind === 'message' && !entry.direct).length;
1101
- if (ordinaryCount > 0)
1102
- append(`Task ${item.task.taskRef}: ${ordinaryCount} unread update${ordinaryCount === 1 ? '' : 's'}.`);
1125
+ if (ordinaryCount > 0) {
1126
+ const route = item.task === undefined ? `Thread ${item.thread.threadRef}` : `Task ${item.task.taskRef}`;
1127
+ append(`${route}: ${ordinaryCount} unread update${ordinaryCount === 1 ? '' : 's'}.`);
1128
+ }
1103
1129
  }
1104
1130
  if (omitted)
1105
1131
  sections.push('More unread work remains in team_inbox; the automatic context is bounded.');
1106
- sections.push('Use team_thread read with the relevant taskRef before acting or replying. Use team_inbox only when you need to triage the remaining Threads.');
1132
+ sections.push('Use team_thread read with the relevant threadRef before acting or replying. Use team_inbox only when you need to triage the remaining Threads.');
1107
1133
  return sections.join('\n\n');
1108
1134
  }
1109
1135
  boundedNotificationBody(body) {
@@ -1125,6 +1151,9 @@ let AgentTeam = (() => {
1125
1151
  if (activity.kind === 'claims_released') {
1126
1152
  return `Team Task update\n${actor}'s Claims ${activity.claimRefs.join(', ')} were released on Task ${activity.taskRef}.`;
1127
1153
  }
1154
+ if (activity.kind === 'promote') {
1155
+ return `Team Task update\n${actor} created Task ${activity.taskRef} from Thread ${activity.threadRef}; it is open for claims.`;
1156
+ }
1128
1157
  const released = 'releasedClaimRefs' in activity && activity.releasedClaimRefs !== undefined && activity.releasedClaimRefs.length > 0
1129
1158
  ? ` Released Claims: ${activity.releasedClaimRefs.join(', ')}.` : '';
1130
1159
  return `Team Task update\n${actor} ${activity.kind} Task ${activity.taskRef}.${released}`;