dsh-as-mcp 0.54.0 → 0.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +81 -0
- package/CHANGELOG.zh.md +14 -0
- package/README.md +68 -7
- package/README.zh.md +60 -6
- package/cordis.patch.yml +4 -3
- package/lib/index.d.ts +275 -0
- package/lib/index.js +637 -1
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,87 @@ plugin is pre-1.0, so a minor bump is a feature and a patch is a fix or docs.
|
|
|
6
6
|
A Chinese summary of every release lives in [CHANGELOG.zh.md](./CHANGELOG.zh.md);
|
|
7
7
|
this file stays the authoritative record.
|
|
8
8
|
|
|
9
|
+
## 0.56.0
|
|
10
|
+
|
|
11
|
+
- Four new tools at the end of the `session` group — `schedule_create`, `schedule_list`,
|
|
12
|
+
`schedule_view` and `schedule_edit` — bring the surface from 38 to 42 (the group from 21 to 25).
|
|
13
|
+
They wrap the Host `ctx.schedule` service, so a task is stored and delivered by the harness itself:
|
|
14
|
+
its prompt fires at each occurrence whether or not this endpoint, or any client, is connected.
|
|
15
|
+
`schedule_create` takes exactly one timing form — `rrule` (one `DTSTART` line plus one `RRULE` line,
|
|
16
|
+
the same RFC 5545 subset the DSH Automation page writes), `afterSeconds` for a one-shot N seconds
|
|
17
|
+
from now, or `everySeconds` for a fixed interval — and a `target` of `"session"` (update an existing
|
|
18
|
+
conversation, needs `sessionId`), `"new_once"` (create one conversation on the first delivery and
|
|
19
|
+
reuse it) or `"new"` (a fresh conversation per delivery), with `cwd`/`agentPreset` on the two
|
|
20
|
+
new-conversation targets. A request that names two timing forms is refused rather than silently
|
|
21
|
+
preferring one, and a new-conversation target that also names a `sessionId` is refused as
|
|
22
|
+
self-contradicting. `schedule_list` pages tasks (active first by next occurrence, `limit` 1–200);
|
|
23
|
+
`schedule_view` answers `found: false` for a missing id instead of an error; `schedule_edit`
|
|
24
|
+
updates or deletes, pauses with `active: false` and resumes with `active: true`, and refuses change
|
|
25
|
+
fields on a delete.
|
|
26
|
+
- **The whole schedule surface is refused while `session.scope` is `"owned"`.** A scheduled task is a
|
|
27
|
+
Host record with no owning session, so an ownership filter cannot be expressed on it, and its
|
|
28
|
+
delivery target may name any conversation on the instance; the error says exactly that and points at
|
|
29
|
+
`scope: "all"`. Mutation outcomes are data rather than errors — `{ updated: true, task }`,
|
|
30
|
+
`{ deleted: true }`, `{ found: false }`, `{ conflict: true }` — so a polling caller can act without
|
|
31
|
+
parsing text, and `expectedUpdatedAt` carries the harness's own revision: a stale edit answers
|
|
32
|
+
`conflict: true` and changes nothing instead of overwriting what the user just changed in the
|
|
33
|
+
Automation page.
|
|
34
|
+
- `dsh_info.harnessServices` gained a `schedule` probe (30 probes, was 29) and `dsh_info.notes` a
|
|
35
|
+
paragraph on the Host-global nature and the owned-scope refusal. No new configuration keys: the
|
|
36
|
+
push surface, both transports, the tool groups and the settings panel are unchanged.
|
|
37
|
+
- Docs and tests: both READMEs gain four tool rows and a "Scheduled automation" section (with the
|
|
38
|
+
create → list → pause/resume → delete flow and the owned-scope warning), `docs/CAPABILITY-GAPS.md`
|
|
39
|
+
moves to 42 tools / 30 probes, and `cordis.patch.yml` restates the session group as 25 tools.
|
|
40
|
+
`tests/schedule.test.ts` pins the driver contract (one timing form, target rules, page bounds, the
|
|
41
|
+
owned-scope refusal, conflict/miss as data); `tests/mcp-endpoint.test.ts` pins argument routing;
|
|
42
|
+
`tests/availability.test.ts` covers the new required capability.
|
|
43
|
+
|
|
44
|
+
## 0.55.0
|
|
45
|
+
|
|
46
|
+
- Three new tools in the `session` group — `session_command_list`, `session_command` and
|
|
47
|
+
`session_goal` — bring the surface from 35 to 38 (the group from 18 to 21). A slash command
|
|
48
|
+
executes **without a model turn** (the registry parses the line and invokes the handler directly),
|
|
49
|
+
so `session_command` is the cheap half of "do what a human typing into the DSH composer would
|
|
50
|
+
do": compact a long session, export its log, enter plan mode or set a goal. `session_command_list`
|
|
51
|
+
reports every command the session's agent can see, with its description and input hint, and marks
|
|
52
|
+
each `permitted` instead of hiding the refused ones; `session_command` takes the line with or
|
|
53
|
+
without its leading slash and with arguments in the same string (`"compact"`, `"/export"`,
|
|
54
|
+
`"/goal <objective>"`, `"/plan off"`), and the run goes through the harness's own command
|
|
55
|
+
registry, so it is the same execution a human typing the line produces (the reply carries the
|
|
56
|
+
harness's `commandId`, `ok`, the handler's `text` and the `sourceEventSeq` it recorded). The
|
|
57
|
+
admitted set is explicit — `/compact`, `/plan`, `/goal`, `/export` — not "anything the registry
|
|
58
|
+
lists": `/permission` would change the session's permission preset (a remote caller must not
|
|
59
|
+
escalate its own session) and `/feedback` writes the user's own review records, so both are
|
|
60
|
+
refused **before** any handler runs — a refused call writes nothing to the session log — and an
|
|
61
|
+
unknown name is refused with the admitted set listed. A handler that reports an error comes back
|
|
62
|
+
as `ok: false` with its text, while a name/argument the registry did not admit is an error saying
|
|
63
|
+
nothing was logged.
|
|
64
|
+
- `session_goal` reads and mutates the session's **durable goal** — the long-running objective the
|
|
65
|
+
harness's round driver keeps advancing across turns, which is how a caller delegates multi-hour
|
|
66
|
+
work instead of holding one turn open. `action` is `get` (the goal, or `null`) or
|
|
67
|
+
`create`/`edit`/`pause`/`resume`/`complete`/`clear`; `create` needs `objective`, `edit` needs
|
|
68
|
+
`objective` and/or `maxGoalRounds`, and every other action acts on the goal that exists now, so
|
|
69
|
+
its ref comes from a read rather than from the caller. `expectedRevision` (from a previous read) is
|
|
70
|
+
the lost-update guard: a mutation whose goal changed underneath — say the user edited it in the DSH
|
|
71
|
+
UI a moment ago — is refused instead of silently applied, the same spirit as the UI's conflict
|
|
72
|
+
handling. A goal reports `id`, `revision`, `objective`, `phase` (`active`/`paused`/`blocked`/
|
|
73
|
+
`complete`), `activation` (`armed`/`disarmed`), `maxGoalRounds`, `roundsStarted`, `blockedReason`
|
|
74
|
+
when blocked and its timestamps; `clear` returns `goal: null` with `cleared: true`, and `complete`
|
|
75
|
+
returns the completed goal.
|
|
76
|
+
- `dsh_info.harnessServices` reports two more probes, `commands` and `goals` (29 in total, up from
|
|
77
|
+
27), and `toolAvailability` pre-flights the three tools against `sessionController` +
|
|
78
|
+
`sessionController.resolveAgent` plus the matching service, so an agent-scoped command or goal
|
|
79
|
+
service that a profile does not mount is reported unavailable instead of failing at call time.
|
|
80
|
+
`dsh_info.notes` gains one paragraph per surface: commands run without a model turn and only the
|
|
81
|
+
user-plane set is admitted, and goal mutations carry the harness's revision guard.
|
|
82
|
+
- No new configuration keys: push, the two transports, the tool groups and the settings panel are
|
|
83
|
+
unchanged. Both READMEs gain the three tool rows, a "Session orchestration" flow and a
|
|
84
|
+
deployment-requirements row; `docs/CAPABILITY-GAPS.md` is re-counted to 38 tools and 29 probes and
|
|
85
|
+
marks slash commands and durable goals as shipped, with `resolveAgent` named as the bridging layer.
|
|
86
|
+
`tests/orchestration.test.ts` pins the new driver surface (allow-list before the handler, slash
|
|
87
|
+
normalization, the revision guard, projection of the goal view) and `tests/mcp-endpoint.test.ts`
|
|
88
|
+
the argument passthrough; `tests/availability.test.ts` covers the new pre-flight rules.
|
|
89
|
+
|
|
9
90
|
## 0.54.0
|
|
10
91
|
|
|
11
92
|
- Server push now covers the whole run instead of one turn-ending signal. The existing
|
package/CHANGELOG.zh.md
CHANGED
|
@@ -6,6 +6,20 @@
|
|
|
6
6
|
- 两份文件的**版本标题必须完全一致**(集合与顺序),由 `tools/check-docs.mjs` 强制检查——发布时漏写中文条目会让检查失败,中文读者不会悄悄落后一个版本。
|
|
7
7
|
- 版本号遵循 SemVer;项目仍是 pre-1.0,所以 minor 是功能,patch 是修复或文档。
|
|
8
8
|
|
|
9
|
+
## 0.56.0
|
|
10
|
+
|
|
11
|
+
- 在 session 组末尾新增 4 个工具(`schedule_create`、`schedule_list`、`schedule_view`、`schedule_edit`),工具面从 38 增至 42(该组从 21 增至 25)。它们包装 Host 的 `ctx.schedule` 服务,任务由 harness 自己存储与投递:每次触发都把 prompt 送到目标会话,无论本端点或任何客户端是否在线。`schedule_create` 必须且只能给一种时间形态——`rrule`(一行 `DTSTART` 加一行 `RRULE`,与 DSH「自动化」页面写出的 RFC 5545 子集相同)、`afterSeconds`(从现在起 N 秒后一次)、或 `everySeconds`(固定间隔)——`target` 取 `"session"`(更新已有会话,需要 `sessionId`)、`"new_once"`(首次投递新建会话并复用)、`"new"`(每次投递新建会话),后两者可带 `cwd`/`agentPreset`。同时给两种时间形态会被拒绝而不是悄悄取其一;`target` 为新建会话却又给了 `sessionId` 也会因自相矛盾被拒绝。`schedule_list` 分页列出任务(活动任务按下次触发在前,`limit` 1–200);`schedule_view` 对不存在的 id 返回 `found: false` 而不是报错;`schedule_edit` 负责更新/删除,`active: false` 暂停、`true` 恢复,删除时拒绝任何改动字段。
|
|
12
|
+
- **`session.scope` 为 `"owned"` 时整个 schedule 面被拒绝。** 定时任务是 Host 记录、没有所属会话,无法在其上表达归属过滤,而它的投递目标可以指向实例上的任意会话;错误信息会说明原因并指向 `scope: "all"`。修改结果用数据表达而不是抛错——`{ updated: true, task }`、`{ deleted: true }`、`{ found: false }`、`{ conflict: true }`——轮询调用方不必解析文本;`expectedUpdatedAt` 携带 harness 自己的 revision:过期编辑返回 `conflict: true` 且不做修改,不会覆盖用户刚在「自动化」页面改过的东西。
|
|
13
|
+
- `dsh_info.harnessServices` 新增 `schedule` 探针(共 30 个,原为 29 个),`dsh_info.notes` 增加一段说明 Host 级属性与 owned 拒绝。无新增配置键:推送、两种传输、工具组与设置面板均不变。
|
|
14
|
+
- 文档与测试:两份 README 增加 4 行工具表与「定时自动化 / Scheduled automation」小节(含 create → list → 暂停/恢复 → delete 流程与 owned 警告),`docs/CAPABILITY-GAPS.md` 更新为 42 工具 / 30 探针,`cordis.patch.yml` 把 session 组注释改为 25 个工具。`tests/schedule.test.ts` 钉住驱动契约(唯一时间形态、target 规则、分页上限、owned 拒绝、冲突/未找到以数据表达);`tests/mcp-endpoint.test.ts` 钉住参数透传;`tests/availability.test.ts` 覆盖新的依赖能力。
|
|
15
|
+
|
|
16
|
+
## 0.55.0
|
|
17
|
+
|
|
18
|
+
- 新增 3 个工具(`session_command_list`、`session_command`、`session_goal`),工具面从 35 增至 38,仍全在 session 组(该组从 18 增至 21)。斜杠命令**不消耗模型轮次**(注册表解析命令行后直接调用 handler),所以 `session_command` 就是「替人在 DSH 输入框里敲命令」的便宜一半:压缩长会话、导出日志、进入 plan 模式、设置目标。`session_command_list` 报出该会话 agent 能看到的全部命令(描述与输入提示),并用 `permitted` 标出本端点会执行哪些,而不是把被拒绝的隐藏掉;`session_command` 接受带或不带前导斜杠的命令行、参数写在同一字符串里(`"compact"`、`"/export"`、`"/goal <objective>"`、`"/plan off"`),执行走 harness 自己的命令注册表,与真人敲同一行的执行完全一致(回复带 harness 的 `commandId`、`ok`、handler 的 `text`,以及它记录的 `sourceEventSeq`)。放行集是显式的 `/compact`、`/plan`、`/goal`、`/export`,而不是「注册表里有什么就运行什么」:`/permission` 会改变会话的权限 preset(远程调用方不能给自己提权),`/feedback` 会写入用户自己的评审记录,两者在**任何 handler 运行之前**就被拒绝——被拒调用不向会话日志写任何东西;未注册的名字会被拒绝并列出放行集。handler 报错时返回 `ok: false` 与文本,注册表未接收的名字/参数返回「什么都没写进日志」的错误。
|
|
19
|
+
- `session_goal` 读取和修改会话的**持久目标**——harness 的轮次驱动会在多轮之间持续推进的长期目标,调用方因此可以委派多小时的任务,而不必一直挂着一轮。`action` 取 `get`(返回目标或 `null`)或 `create`/`edit`/`pause`/`resume`/`complete`/`clear`;`create` 需要 `objective`,`edit` 需要 `objective` 和/或 `maxGoalRounds`,其余动作作用于当前存在的目标,其 ref 来自一次读取而不是调用方。`expectedRevision`(来自上一次读取)是丢失更新保护:目标在脚下被改过(比如用户刚在 DSH 界面里编辑过)就拒绝,而不是悄悄覆盖——与界面冲突处理同一思路。目标报出 `id`、`revision`、`objective`、`phase`(`active`/`paused`/`blocked`/`complete`)、`activation`(`armed`/`disarmed`)、`maxGoalRounds`、`roundsStarted`、被阻塞时的 `blockedReason` 与时间戳;`clear` 返回 `goal: null`(`cleared: true`),`complete` 返回已完成的目标。
|
|
20
|
+
- `dsh_info.harnessServices` 新增 `commands` 与 `goals` 两个探针(共 29 个,原为 27 个);`dsh_info.toolAvailability` 对三个新工具做预检,要求 `sessionController` + `sessionController.resolveAgent` 以及对应的 commands/goals 服务,缺能力的 profile 会把它们报成不可用,而不是等到调用时才失败;`dsh_info.notes` 各增一段(命令不消耗轮次且只放行用户面集合;目标修改带 harness 的 revision 保护)。
|
|
21
|
+
- 无新增配置键:推送、两种传输、工具组与设置面板均不变。两份 README 增加三行工具表、「会话编排 / Session orchestration」流程与部署要求行;`docs/CAPABILITY-GAPS.md` 的工具数/探针数更新为 38/29,并把斜杠命令与持久目标两条差距标记为已交付、点名 `resolveAgent` 是打通它们的桥。`tests/orchestration.test.ts` 钉住新驱动面(handler 之前的 allow-list、斜杠归一化、revision 保护、目标投影),`tests/mcp-endpoint.test.ts` 钉住参数透传,`tests/availability.test.ts` 覆盖新的预检规则。
|
|
22
|
+
|
|
9
23
|
## 0.54.0
|
|
10
24
|
|
|
11
25
|
- 服务端推送从「只报一轮结束」扩展到整场运行,仍走现有的 `subscriptions/listen` 流,且不新增任何工具(工具面仍是 35 个):`dsh://sessions`(会话增删、活动/状态、subagent 起止)、`dsh://session/<id>/events`(最新持久事件投影为 `{seq, type, at, turn, step, summary, error}`,每次追加都发布,单次读取至多 64 条)、`dsh://session/<id>/assistant`(实时 `start`/`text`/`reasoning`/`tool`/`finish`/`end` 帧,`seq` 每会话单调递增)、`dsh://session/<id>/status`(与 `session_status` 同负载)、`dsh://session/<id>/projections`(白名单内的 `workingDirectory`/`worktree`/`goal`/`plan`/`todos`/`agentPreset`/`title`)、`dsh://jobs` 与 `dsh://jobs/<id>`(后台 shell 任务;任务尾部读取不消费,不会抢走 `shell_output` 的字节)。0.52.86 的 `dsh://session/<id>/turn` 结算资源保留,成为整个 feed 集合中的一项。`resources/list`/`resources/templates/list` 会公布这些 feed,`dsh_info.notes` 也会点名它们。
|
package/README.md
CHANGED
|
@@ -252,6 +252,13 @@ schema-aware client can read the object directly instead of parsing JSON out of
|
|
|
252
252
|
| `session_unarchive` | Return an archived session to its recorded position in the DSH UI. Idempotent: an id that is not archived is not an error, and the log was never touched, so the session is visible and promptable again. |
|
|
253
253
|
| `session_pin` | Pin a session to the top of the DSH UI's session list (the same pin set the sidebar writes). The session must exist and must not be archived; pinning is idempotent. |
|
|
254
254
|
| `session_unpin` | Remove a session from the DSH UI's pin set. Idempotent: an id that is not pinned is not an error. |
|
|
255
|
+
| `session_command_list` | The slash commands this session's agent can run — each with a one-line description, an optional `input` hint and a `permitted` flag — so a caller can see that a command exists while this endpoint deliberately will not run it (the admitted set is `/compact`, `/plan`, `/goal`, `/export`; `/permission` and `/feedback` are refused on purpose). A command executes without a model turn — the handler is invoked directly — which makes this the cheap way to compact a long session, export its log, enter plan mode or set a goal, exactly as a human typing into the DSH composer would. Read-only; run one with `session_command`. |
|
|
256
|
+
| `session_command` | Execute one slash command against a session's agent without spending a model turn, as if the human had typed it into the DSH composer: give the `command` with or without its leading slash, with its arguments in the same string (`"compact"`, `"/export"`, `"/goal <objective>"`, `"/plan off"`). The run goes through the harness's own command registry, so it is the same execution a human typing the line produces and the session log records it; the reply carries the harness's `commandId`, `ok` (`false` when the handler itself reported an error result), the handler's `text` and the `sourceEventSeq` it recorded when it reported one. Only the user-plane commands are admitted (`/compact`, `/plan`, `/goal`, `/export`); `/permission` (which would change the session permission preset) and `/feedback` (which would write the user's own review records) are refused before any handler runs, so a refused call writes nothing to the session log, and a name that is not registered on this profile is refused with the admitted set listed. A name or argument the registry did not admit is an error saying nothing was logged. Call `session_command_list` first to see the exact names and the input hint this agent accepts. |
|
|
257
|
+
| `session_goal` | Read or mutate the session's durable goal — the long-running objective the harness's round driver keeps advancing across turns, which is how a caller delegates multi-hour work instead of holding one turn open. `action` is `get` (which returns the `goal` or `null`), or one of `create` (needs `objective`), `edit` (needs `objective` and/or `maxGoalRounds`), `pause`, `resume`, `complete`, `clear`; every action except `create` acts on the goal that exists now, so its ref comes from a read rather than from the caller. Pass `expectedRevision` (from a previous read) to refuse a mutation whose goal changed underneath you — the equivalent of the DSH UI's conflict handling. A goal reports `id`, `revision`, `objective`, `phase` (`active`/`paused`/`blocked`/`complete`), `activation` (`armed`/`disarmed`), `maxGoalRounds`, `roundsStarted`, `blockedReason` when blocked, and `createdAt`/`updatedAt`; `clear` returns `goal: null` (and `cleared: true`), while `complete` returns the completed goal. |
|
|
258
|
+
| `schedule_create` | Create a **Host** scheduled task: an instruction the harness delivers to a conversation at each occurrence, whether or not this endpoint or any client is connected. Give exactly one timing form — `rrule` (one `DTSTART` line plus one `RRULE` line, the RFC 5545 subset the DSH Automation page writes, e.g. `"DTSTART;TZID=Asia/Singapore:20260901T080000\nRRULE:FREQ=DAILY;COUNT=3"`), `afterSeconds` for a one-shot N seconds from now, or `everySeconds` for a fixed interval. `target` decides where each delivery lands: `"session"` updates an existing conversation (needs `sessionId`), `"new_once"` creates one conversation on the first delivery and reuses it, `"new"` starts a fresh conversation every time; the two new-conversation targets accept `cwd` and `agentPreset`. The default target is `"session"` when `sessionId` is given and `"new"` otherwise. The reply is the stored task with its generated id, `scheduledAt`, `status` and timing variant fields. Tasks are Host records, not session records, so this surface is refused while `session.scope` is `"owned"`. |
|
|
259
|
+
| `schedule_list` | One page of Host scheduled tasks, active ones first by next occurrence and paused/ended ones after. `active: true` keeps only active tasks, `false` only paused and ended ones; absent returns every task. `limit` is 1–200 (default 20) and `offset` skips rows. Each row carries the task `id`, `title`, `prompt`, its timing fields, `scheduledAt`, `status`, `target` and the last delivery once it has fired. Lists tasks any session created; refused while `session.scope` is `"owned"`. |
|
|
260
|
+
| `schedule_view` | One Host scheduled task by `scheduleId`, with the same fields `schedule_list` reports plus its delivery target detail. An id that no longer exists answers `{ "found": false, "id": ... }` rather than an error, so a cleanup loop stays idempotent. Refused while `session.scope` is `"owned"`. |
|
|
261
|
+
| `schedule_edit` | Change or remove one Host scheduled task. `action: "update"` needs at least one of `title`, `prompt`, a timing form (`rrule`, `afterSeconds` or `everySeconds`), a `target` (with `sessionId` for `"session"`, or `cwd`/`agentPreset` for `"new"`/`"new_once"`), or `active` — `false` pauses the task, `true` resumes it, and a resume may need a new timing when the old rule is exhausted. `action: "delete"` removes the task and its saved delivery records and accepts no change fields. `expectedUpdatedAt` is the lost-update guard: if the task changed after that read the call answers `conflict: true` and changes nothing. Outcomes are data, not errors: `{ updated: true, task }`, `{ deleted: true }`, `{ found: false }` or `{ conflict: true }`. Refused while `session.scope` is `"owned"`. |
|
|
255
262
|
| `session_usage` | Token usage per session (its subagents included by default): exact bucket counts, a per-model breakdown, optional per-turn detail, and money when a price plugin is installed. Pass `sessionIds` to tally several known sessions in one receipt, or `cwd` to total every session that ran in one workspace directory. |
|
|
256
263
|
| `file_read` | Read a UTF-8 file through DSH's filesystem service. Bounded by a byte limit; `offset`/`nextOffset` page through a larger file (both are **byte** offsets, so an offset at or past EOF is an empty complete read), `maxBytes` asks for a smaller window so reading a slice costs less, and `sha256: true` returns the whole file's hash as the compare-and-swap value for a later write/edit. |
|
|
257
264
|
| `file_read_image` | Read an image (png/jpeg/gif/webp/bmp, detected from the bytes) and return it as an MCP image block, preceded by a metadata block (path, mimeType, bytes), so you can look at a screenshot or chart instead of guessing. Capped at 8 MiB. |
|
|
@@ -311,6 +318,59 @@ refused *and* hidden from `dsh_tool_list`. The omissions that matter:
|
|
|
311
318
|
An operator can widen this deliberately with the `agentTools.allow` setting, or subtract from
|
|
312
319
|
the default with `agentTools.deny`.
|
|
313
320
|
|
|
321
|
+
### Session orchestration
|
|
322
|
+
|
|
323
|
+
Some work is not a single prompt. Compacting a long session, exporting its log, entering plan mode or
|
|
324
|
+
setting a goal are user-plane actions a human performs by typing a slash command into the DSH
|
|
325
|
+
composer; a durable goal also turns a one-turn request into an objective the harness's round driver
|
|
326
|
+
keeps advancing across turns. Neither path costs a model turn of its own. The intended flow:
|
|
327
|
+
|
|
328
|
+
```
|
|
329
|
+
session_command_list { sessionId } # what this agent accepts; permitted marks the admitted set
|
|
330
|
+
-> session_command { sessionId, command: "/compact" } # run one; no model turn
|
|
331
|
+
-> session_goal { sessionId, action: "create", objective: "Finish the migration", maxGoalRounds: 20 }
|
|
332
|
+
-> session_goal { sessionId, action: "get" } # poll phase/revision...
|
|
333
|
+
or subscribe to dsh://session/<id>/projections # ...or be told when the goal changes
|
|
334
|
+
-> session_goal { sessionId, action: "pause", expectedRevision: 3 } # then resume / complete / clear
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
`session_command_list` reports each entry's `permitted` flag instead of hiding the refused commands, so
|
|
338
|
+
a caller can see that `/permission` and `/feedback` exist on the profile and that this endpoint
|
|
339
|
+
deliberately will not run them: `/permission` would change the session's permission preset and
|
|
340
|
+
`/feedback` would write the user's own review records, and neither reaches a handler or writes anything
|
|
341
|
+
to the session log. `session_status` reports the session's turn and log state, not the goal itself; the
|
|
342
|
+
goal's phase and revision come from `session_goal { action: "get" }`, and the
|
|
343
|
+
`dsh://session/<id>/projections` feed (which includes `goal`) publishes when it changes, so following a
|
|
344
|
+
goal is a poll or a subscription rather than a prompt per turn. A mutation without `expectedRevision`
|
|
345
|
+
acts on the goal that exists at that moment; pass the revision a read returned when two supervisors
|
|
346
|
+
could race.
|
|
347
|
+
|
|
348
|
+
### Scheduled automation
|
|
349
|
+
|
|
350
|
+
A scheduled task is the one surface here that outlives the process: the harness stores it and delivers
|
|
351
|
+
its prompt at each occurrence, so it keeps working when no MCP client is connected. Tasks are **Host**
|
|
352
|
+
records rather than session records — `schedule_list` shows tasks any session created, and `target`
|
|
353
|
+
decides whether a delivery updates one conversation, reuses a conversation created on first delivery, or
|
|
354
|
+
starts a fresh one each time:
|
|
355
|
+
|
|
356
|
+
```
|
|
357
|
+
schedule_create { title: "Daily dependency check", prompt: "Run the dependency audit and report",
|
|
358
|
+
rrule: "DTSTART;TZID=Asia/Singapore:20260901T080000\nRRULE:FREQ=DAILY",
|
|
359
|
+
target: "new_once", cwd: "/repo" }
|
|
360
|
+
schedule_create { title: "Check the build in ten minutes", prompt: "Check whether the build is green",
|
|
361
|
+
afterSeconds: 600, target: "session", sessionId }
|
|
362
|
+
-> schedule_list { active: true } # id, next occurrence, status
|
|
363
|
+
-> schedule_edit { scheduleId, action: "update", active: false } # pause
|
|
364
|
+
-> schedule_edit { scheduleId, action: "update", title: "..." , everySeconds: 3600 }
|
|
365
|
+
-> schedule_edit { scheduleId, action: "delete" } # removes the task and its deliveries
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
Because a Host record has no owning session, this whole surface is **refused while `session.scope` is
|
|
369
|
+
`"owned"`**: an ownership filter cannot be expressed on it, and a task's delivery target may name any
|
|
370
|
+
conversation on the instance. The refusal says so and points at `scope: "all"`. `expectedUpdatedAt`
|
|
371
|
+
carries the harness's own revision, so a stale edit answers `conflict: true` and changes nothing instead
|
|
372
|
+
of overwriting what the user just changed in the Automation page.
|
|
373
|
+
|
|
314
374
|
## Worktrees
|
|
315
375
|
|
|
316
376
|
A session can work in its own Git checkout of the same repository. The operation is the one the
|
|
@@ -361,7 +421,7 @@ An MCP server cannot call a client on its own, so every "something changed" trav
|
|
|
361
421
|
resource notification. This endpoint publishes one change-feed surface over both standard push
|
|
362
422
|
channels, and each notification is **payload-less**: it names a synthetic resource, and the
|
|
363
423
|
client reads that resource for the JSON. No tools were added for this — the surface is still the
|
|
364
|
-
|
|
424
|
+
38 in the table above — and push has no configuration key: it is always on and costs nothing
|
|
365
425
|
while nobody subscribes.
|
|
366
426
|
|
|
367
427
|
| Client era | Handshake | Server→client channel | How push is requested |
|
|
@@ -1007,6 +1067,7 @@ but a deployment can switch the capability off.
|
|
|
1007
1067
|
| `worktree_create` / `worktree_restore` / `session_create { worktree }` | `worktrees` **and** `sessionController.resolveAgent` | the forge bundle in DSH Desktop/Web provides the service (`@deepseek-ai/dsh-experimental-forge-bundle`); a bare profile has none, `dsh_info.toolAvailability` reports the tools unavailable, and `session_create { worktree }` is refused before the session exists. Git and Node must exist in the session's execution world |
|
|
1008
1068
|
| `session_status.workingDirectory` / `session_status.worktree` / `session_list { includeWorktree }` | readable session projections (`sessionController.projections` or `sessionQuery.observeSession`) | optional: without them both replies omit those two fields and the rest is unchanged |
|
|
1009
1069
|
| `session_archive` / `session_unarchive` / `session_pin` / `session_unpin` | `workspaceRegistry.archiveSession` / `pinSession` | the same registry sets the DSH sidebar's actions write; if the methods are missing the tools are reported unavailable |
|
|
1070
|
+
| `session_command_list` / `session_command` / `session_goal` | `sessionController.resolveAgent` **and** `commands` / `goals` | both services are agent-scoped, so the session's live agent is the bridge; a profile without them reports the three tools unavailable in `dsh_info.toolAvailability`, and each call names the missing service and the bundle that provides it |
|
|
1010
1071
|
| `workspace_*` | `workspaceRegistry` | provided by the base bundle in normal profiles |
|
|
1011
1072
|
| `file_*` | `fs` | the deployment's sandbox policy still applies; `file_read_image` additionally needs a supported image format |
|
|
1012
1073
|
| `shell_*` | `shell` | `shell_run` uses `run()` when present and `execute()` otherwise; background jobs need `start()` or `execute()` |
|
|
@@ -1180,14 +1241,14 @@ build:
|
|
|
1180
1241
|
|
|
1181
1242
|
| Tool groups enabled | Tools advertised | Last result |
|
|
1182
1243
|
| --- | --- | --- |
|
|
1183
|
-
| all six |
|
|
1184
|
-
| `session`, `usage` only |
|
|
1185
|
-
| `workspace`, `session`, `agentTools`, `usage` |
|
|
1244
|
+
| all six | 38 | live-checks 195/195 with `--with-model --with-subagent` and acceptance 166/166 — one boot, search index open |
|
|
1245
|
+
| `session`, `usage` only | 23 | live-checks 95/95 with `--with-model` (file/shell/workspace sections skip) |
|
|
1246
|
+
| `workspace`, `session`, `agentTools`, `usage` | 28 | live-checks 64/64 (a disabled group's reason names its `tools.<group>` switch) |
|
|
1186
1247
|
| `files`, `shell` only | 11 | live-checks 68/68 (session/usage/queue/search sections skip) |
|
|
1187
1248
|
|
|
1188
|
-
The advertised counts are the current surface (0.
|
|
1189
|
-
last-result column records runs made against 0.52.86, before the
|
|
1190
|
-
re-measured
|
|
1249
|
+
The advertised counts are the current surface (0.55.0: 21 session-group tools and 38 overall); the
|
|
1250
|
+
last-result column records runs made against 0.52.86, before the 0.53.0 additions, and has not been
|
|
1251
|
+
re-measured since.
|
|
1191
1252
|
|
|
1192
1253
|
A fifth shape, `mountonly`, boots with `http.enabled: false` and `mountOnWebServer: true` and
|
|
1193
1254
|
checks the endpoint over DSH's own web server: 109/109, all cheap, including the assertions that
|
package/README.zh.md
CHANGED
|
@@ -237,6 +237,13 @@ scheme 可以省略:`127.0.0.1:8790/mcp` 也能识别。
|
|
|
237
237
|
| `session_unarchive` | 把归档的会话放回它在 DSH 界面里记录的位置。幂等:对未归档的 id 不算错误;日志从未被动过,因此会话重新可见、可继续 prompt。 |
|
|
238
238
|
| `session_pin` | 把会话置顶到 DSH 界面的会话列表(与侧边栏置顶写入同一个 pin 集合)。会话必须存在且未归档;置顶幂等。 |
|
|
239
239
|
| `session_unpin` | 把会话从 DSH 界面的 pin 集合里移除。幂等:对未置顶的 id 不算错误。 |
|
|
240
|
+
| `session_command_list` | 列出该会话 agent 能运行的斜杠命令——每条带一句描述、可选的 `input` 提示与 `permitted` 标记——因此调用方能看到某个命令存在、而本端点故意不运行它(放行集是 `/compact`、`/plan`、`/goal`、`/export`;`/permission` 与 `/feedback` 刻意拒绝)。命令**不消耗模型轮次**(直接调用 handler),所以这是压缩长会话、导出日志、进入 plan 模式或设置目标最便宜的办法——与人在 DSH 输入框里敲命令完全一致。只读;用 `session_command` 运行其中一条。 |
|
|
241
|
+
| `session_command` | 对会话的 agent 执行一条斜杠命令,不花模型轮次,就像人真的在 DSH 输入框里敲了它:`command` 可带可不带前导斜杠,参数写在同一字符串里(`"compact"`、`"/export"`、`"/goal <objective>"`、`"/plan off"`)。执行走 harness 自己的命令注册表,因此与真人敲同一行的执行完全一致,会话日志也会记录;回复带 harness 的 `commandId`、`ok`(handler 自己报告错误结果时为 `false`)、handler 的 `text`,以及它报告时记录的 `sourceEventSeq`。只放行用户面命令(`/compact`、`/plan`、`/goal`、`/export`);`/permission`(会改变会话的 permission preset)与 `/feedback`(会写入你自己的评审记录)在任何 handler 运行之前就被拒绝,因此被拒调用**不会向会话日志写入任何东西**;本 profile 未注册的命令名会被拒绝并列出放行集。注册表没有接收的名字或参数返回错误并说明什么都没写进日志。先调 `session_command_list` 看该 agent 接受的确切名字与输入提示。 |
|
|
242
|
+
| `session_goal` | 读取或修改会话的持久目标(durable goal)——即 harness 的轮次驱动会在多轮之间持续推进的长期目标,调用方因此可以委派多小时的任务,而不必一直挂着一轮。`action` 取 `get`(返回 `goal` 或 `null`),或 `create`(需要 `objective`)、`edit`(需要 `objective` 和/或 `maxGoalRounds`)、`pause`、`resume`、`complete`、`clear` 之一;除 `create` 外的动作都作用于当前存在的目标,其 ref 来自一次读取而不是调用方。传 `expectedRevision`(来自之前的读取)可拒绝"目标已在脚下被改过"的修改——相当于 DSH 界面的冲突处理。目标报出 `id`、`revision`、`objective`、`phase`(`active`/`paused`/`blocked`/`complete`)、`activation`(`armed`/`disarmed`)、`maxGoalRounds`、`roundsStarted`、被阻塞时的 `blockedReason` 与 `createdAt`/`updatedAt`;`clear` 返回 `goal: null`(并带 `cleared: true`),`complete` 返回已完成的目标。 |
|
|
243
|
+
| `schedule_create` | 创建一个 **Host 级** 定时任务:harness 会在每次触发时把指令投递到某个会话,无论本端点或任何客户端是否在线。时必须且只能给出一种形式——`rrule`(一行 `DTSTART` 加一行 `RRULE`,即 DSH「自动化」页面写出的 RFC 5545 子集,例如 `"DTSTART;TZID=Asia/Singapore:20260901T080000\nRRULE:FREQ=DAILY;COUNT=3"`)、`afterSeconds`(从现在起 N 秒后执行一次)、或 `everySeconds`(固定间隔)。`target` 决定投递落点:`"session"` 更新一个已有会话(需要 `sessionId`)、`"new_once"` 首次投递时新建一个会话并复用、`"new"` 每次投递都新建会话;后两种可带 `cwd` 与 `agentPreset`。给了 `sessionId` 时默认 `"session"`,否则默认 `"new"`。返回存下的任务,含生成的 id、`scheduledAt`、`status` 与具体时间形态字段。任务属于 Host 记录而不是会话记录,因此当 `session.scope` 为 `"owned"` 时整个 schedule 面会被拒绝。 |
|
|
244
|
+
| `schedule_list` | Host 定时任务的一页,活动任务按下次触发时间在前,暂停/已结束的在后。`active: true` 只留活动任务,`false` 只留暂停与已结束的;不传则返回全部。`limit` 为 1–200(默认 20),`offset` 用于跳过。每行含任务 `id`、`title`、`prompt`、时间形态字段、`scheduledAt`、`status`、`target`,以及触发过之后的最近一次投递。列出的是任何会话创建的任务;`session.scope` 为 `"owned"` 时拒绝。 |
|
|
245
|
+
| `schedule_view` | 按 `scheduleId` 读一个 Host 定时任务,字段与 `schedule_list` 相同并附投递目标细节。已不存在的 id 返回 `{ "found": false, "id": ... }` 而不是报错,清理循环因此保持幂等。`session.scope` 为 `"owned"` 时拒绝。 |
|
|
246
|
+
| `schedule_edit` | 修改或删除一个 Host 定时任务。`action: "update"` 至少需要一项改动:`title`、`prompt`、某种时间形态(`rrule`、`afterSeconds` 或 `everySeconds`)、`target`(`"session"` 需 `sessionId`,`"new"`/`"new_once"` 可带 `cwd`/`agentPreset`),或 `active`——`false` 暂停,`true` 恢复,旧规则已耗尽时恢复可能需要新的时间形态。`action: "delete"` 删除任务及其保存的投递记录,且不接受任何改动字段。`expectedUpdatedAt` 是丢失更新的守卫:若任务在该次读取后变过,调用返回 `conflict: true` 且不做任何修改。结果是数据而不是错误:`{ updated: true, task }`、`{ deleted: true }`、`{ found: false }` 或 `{ conflict: true }`。`session.scope` 为 `"owned"` 时拒绝。 |
|
|
240
247
|
| `session_usage` | 按会话统计 token 用量(默认含其 subagent):精确的四桶计数、按模型拆分、可选的按轮拆分,装了价格插件时还有钱。传 `sessionIds` 可一次结算多个已知会话,传 `cwd` 可汇总某个工作目录里跑过的所有会话。 |
|
|
241
248
|
| `file_read` | 经 DSH 文件系统服务读 UTF-8 文件。受字节上限约束;`offset`/`nextOffset` 可翻页读取更大的文件(两者都是**字节**偏移,因此 EOF 处或之后的偏移是空的完整读取),`maxBytes` 用更小的窗口降低单次开销;`sha256: true` 返回整个文件的哈希,作为后续写入/编辑的比较并交换值。 |
|
|
242
249
|
| `file_read_image` | 读取图片(png/jpeg/gif/webp/bmp,按字节嗅探)并以 MCP image block 返回,让你直接看截图或图表而不是靠猜。上限 8 MiB。 |
|
|
@@ -288,6 +295,52 @@ workspace_create { path: "/Users/me/project" }
|
|
|
288
295
|
|
|
289
296
|
运维方可以通过 `agentTools.allow` 有意放宽,或用 `agentTools.deny` 从默认集合里减去。
|
|
290
297
|
|
|
298
|
+
### 会话编排
|
|
299
|
+
|
|
300
|
+
有些活不是一次 prompt 能装下的。压缩长会话、导出日志、进入 plan 模式、设置目标,都是人在 DSH 输入框里
|
|
301
|
+
敲一条斜杠命令就能完成的用户面动作;持久目标还会把"一次请求"变成 harness 的轮次驱动会跨轮持续推进的
|
|
302
|
+
目标。这两条路本身都不消耗模型轮次。预期流程:
|
|
303
|
+
|
|
304
|
+
```
|
|
305
|
+
session_command_list { sessionId } # 该 agent 接受什么;permitted 标出放行集
|
|
306
|
+
-> session_command { sessionId, command: "/compact" } # 运行一条;不花模型轮次
|
|
307
|
+
-> session_goal { sessionId, action: "create", objective: "完成迁移", maxGoalRounds: 20 }
|
|
308
|
+
-> session_goal { sessionId, action: "get" } # 轮询 phase/revision……
|
|
309
|
+
或订阅 dsh://session/<id>/projections # ……或等它在变化时通知你
|
|
310
|
+
-> session_goal { sessionId, action: "pause", expectedRevision: 3 } # 之后 resume / complete / clear
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
`session_command_list` 报出每条命令的 `permitted` 标记而不是把被拒命令藏起来,调用方因此能看到该 profile
|
|
314
|
+
上确实有 `/permission` 与 `/feedback`、而本端点故意不运行它们:`/permission` 会改变会话的权限 preset,
|
|
315
|
+
`/feedback` 会写入用户自己的评审记录;两者都到不了 handler,也不会向会话日志写入任何东西。
|
|
316
|
+
`session_status` 报的是会话的轮次与日志状态,不含目标本身;目标的 phase 与 revision 来自
|
|
317
|
+
`session_goal { action: "get" }`,而 `dsh://session/<id>/projections` feed(其中含 `goal`)会在目标变化时
|
|
318
|
+
发布,因此跟进一个目标是轮询或订阅,而不是每轮都发 prompt。不带 `expectedRevision` 的修改作用于当时存在
|
|
319
|
+
的目标;若可能有两个监督者竞争,请传回读取时拿到的 revision。
|
|
320
|
+
|
|
321
|
+
### 定时自动化
|
|
322
|
+
|
|
323
|
+
定时任务是本插件里唯一比进程活得更久的面:harness 负责存储并在每次触发时投递 prompt,因此即使没有
|
|
324
|
+
任何 MCP 客户端在线也照常工作。任务是 **Host** 记录而不是会话记录——`schedule_list` 列出任何会话创建的
|
|
325
|
+
任务,`target` 决定投递是更新同一个会话、首次投递时新建一个会话再复用、还是每次新建一个会话:
|
|
326
|
+
|
|
327
|
+
```
|
|
328
|
+
schedule_create { title: "每日依赖检查", prompt: "跑一遍依赖审计并汇报",
|
|
329
|
+
rrule: "DTSTART;TZID=Asia/Singapore:20260901T080000\nRRULE:FREQ=DAILY",
|
|
330
|
+
target: "new_once", cwd: "/repo" }
|
|
331
|
+
schedule_create { title: "十分钟后看构建", prompt: "看看构建是否变绿",
|
|
332
|
+
afterSeconds: 600, target: "session", sessionId }
|
|
333
|
+
-> schedule_list { active: true } # id、下次触发、状态
|
|
334
|
+
-> schedule_edit { scheduleId, action: "update", active: false } # 暂停
|
|
335
|
+
-> schedule_edit { scheduleId, action: "update", title: "..." , everySeconds: 3600 }
|
|
336
|
+
-> schedule_edit { scheduleId, action: "delete" } # 连任务与投递记录一起删除
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
因为 Host 记录没有所属会话,`session.scope` 为 `"owned"` 时整个面色会被**拒绝**:这种记录上无法表达
|
|
340
|
+
归属过滤,而任务的投递目标可以指向实例上的任意会话。拒绝信息会说明原因并指向 `scope: "all"`。
|
|
341
|
+
`expectedUpdatedAt` 携带 harness 自己的 revision,因此过期编辑返回 `conflict: true` 且不做修改,而不是
|
|
342
|
+
覆盖用户刚在「自动化」页面里改过的东西。
|
|
343
|
+
|
|
291
344
|
## 工作树
|
|
292
345
|
|
|
293
346
|
一个会话可以在一份自己的、来自同一仓库的 Git 检出里工作。这正是 DSH 界面「New worktree」选项做的事:
|
|
@@ -328,7 +381,7 @@ profile 能读 session projection 时,`session_status` 会报 `workingDirector
|
|
|
328
381
|
|
|
329
382
|
MCP 服务无法主动调用客户端,所以「有什么变了」只能以资源通知的形式送出去。本端点把同一套变更 feed 发布到
|
|
330
383
|
两种标准的推送通道上,而且每条通知都**不携带负载**:它只点名一个合成资源,客户端再去读那个资源拿 JSON。
|
|
331
|
-
|
|
384
|
+
这件事没有新增任何工具——工具面是上面表格里的 42 个——推送也没有配置键:它始终开启,且在无人订阅时
|
|
332
385
|
零成本。
|
|
333
386
|
|
|
334
387
|
| 客户端时代 | 握手 | 服务端→客户端通道 | 如何请求推送 |
|
|
@@ -880,6 +933,7 @@ profile 推导同一份映射;不过配置 profile 的人应当能在一处读
|
|
|
880
933
|
| `worktree_create` / `worktree_restore` / `session_create { worktree }` | `worktrees` **且** `sessionController.resolveAgent` | 服务由 DSH Desktop/Web 的 forge bundle(`@deepseek-ai/dsh-experimental-forge-bundle`)提供;裸 profile 没有它,`dsh_info.toolAvailability` 会把这些工具报成不可用,`session_create { worktree }` 在创建会话之前就被拒绝。会话的执行环境里还需要 Git 与 Node |
|
|
881
934
|
| `session_status.workingDirectory` / `session_status.worktree` / `session_list { includeWorktree }` | 可读的 session projection(`sessionController.projections` 或 `sessionQuery.observeSession`) | 可选:没有它时两个回复都省略这两个字段,其余内容不变 |
|
|
882
935
|
| `session_archive` / `session_unarchive` / `session_pin` / `session_unpin` | `workspaceRegistry.archiveSession` / `pinSession` | 与 DSH 侧边栏动作写入同一组 registry 集合;方法缺失时这些工具被报成不可用 |
|
|
936
|
+
| `session_command_list` / `session_command` / `session_goal` | `sessionController.resolveAgent` **且** `commands` / `goals` | 两个服务都是 agent 作用域的,会话的实时 agent 就是桥;profile 没有它们时 `dsh_info.toolAvailability` 会把这三个工具报成不可用,每次调用也会点名缺少的服务与提供它的 bundle |
|
|
883
937
|
| `workspace_*` | `workspaceRegistry` | 常规 profile 由 base bundle 提供 |
|
|
884
938
|
| `file_*` | `fs` | 部署的沙箱策略照样生效;`file_read_image` 还需要受支持的图片格式 |
|
|
885
939
|
| `shell_*` | `shell` | `shell_run` 有 `run()` 用 `run()`、否则 `execute()`;后台任务需要 `start()` 或 `execute()` |
|
|
@@ -1011,13 +1065,13 @@ node scripts/exercise.mjs # 约 60 项断言:建工作区、开会话、让
|
|
|
1011
1065
|
|
|
1012
1066
|
| 启用的工具组 | 公布工具数 | 最近结果 |
|
|
1013
1067
|
| --- | --- | --- |
|
|
1014
|
-
| 全部六组 |
|
|
1015
|
-
| 仅 `session`、`usage` |
|
|
1016
|
-
| `workspace`、`session`、`agentTools`、`usage` |
|
|
1068
|
+
| 全部六组 | 38 | `--with-model --with-subagent` 下 live-checks 195/195;验收 166/166,同一轮启动、搜索索引开启 |
|
|
1069
|
+
| 仅 `session`、`usage` | 23 | `--with-model` 下 live-checks 95/95(文件/shell/工作区段落跳过) |
|
|
1070
|
+
| `workspace`、`session`、`agentTools`、`usage` | 28 | live-checks 64/64(被关闭的组会在原因里点名 `tools.<group>` 开关) |
|
|
1017
1071
|
| 仅 `files`、`shell` | 11 | live-checks 68/68(会话/用量/队列/搜索段落跳过) |
|
|
1018
1072
|
|
|
1019
|
-
"公布工具数"一列是当前工具面(0.
|
|
1020
|
-
针对 0.52.86
|
|
1073
|
+
"公布工具数"一列是当前工具面(0.55.0:session 组 21 个、总计 38 个);"最近结果"一列记录的是
|
|
1074
|
+
针对 0.52.86(尚无 0.53.0 新增工具)的实测,此后未重测。
|
|
1021
1075
|
|
|
1022
1076
|
第五个形态 `mountonly` 以 `http.enabled: false` + `mountOnWebServer: true` 启动,经 DSH 自己的
|
|
1023
1077
|
web 服务器验证端点:109/109,全部廉价,其中包含 `dsh_info` 必须报 `listening: false`、
|
package/cordis.patch.yml
CHANGED
|
@@ -50,13 +50,14 @@
|
|
|
50
50
|
# stream) and cost nothing while no client subscribes. The session-group
|
|
51
51
|
# feeds need `session`; the job feeds need `shell`.
|
|
52
52
|
#
|
|
53
|
-
# The session group:
|
|
53
|
+
# The session group: 25 tools — create/list/search/status/prompt/
|
|
54
54
|
# transcript/tool-result/queue/cancel/fork/rename/set_model, the
|
|
55
|
-
# worktree pair,
|
|
55
|
+
# worktree pair, archive/unarchive + pin/unpin, and the orchestration
|
|
56
|
+
# trio (slash commands + durable goal) and the schedule quartet. The worktree tools
|
|
56
57
|
# also need the worktrees service (the forge bundle in Desktop/Web,
|
|
57
58
|
# probed as `dsh_info.harnessServices.worktrees`); archive/pin write the
|
|
58
59
|
# same registry sets the DSH sidebar's actions write. Disabling the
|
|
59
|
-
# group removes all
|
|
60
|
+
# group removes all 25 at once; `dsh_info.toolAvailability` names the
|
|
60
61
|
# ones a profile cannot serve.
|
|
61
62
|
session: true
|
|
62
63
|
files: true
|