@akira-tl/forgerelay 0.6.1 → 0.7.1
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 +43 -0
- package/README.md +38 -0
- package/capabilities/subagents/GUIDE.md +100 -40
- package/dist/activity/lifecycle.js +1 -1
- package/dist/activity/mcp-query-tools.js +1 -0
- package/dist/activity/query-service.js +1 -0
- package/dist/capabilities.js +1 -1
- package/dist/capability-registry.js +34 -0
- package/dist/cli.js +80 -165
- package/dist/composite-activity.js +155 -0
- package/dist/composite-workspaces.js +197 -0
- package/dist/db/migrations.js +14 -0
- package/dist/db/schema.js +6 -0
- package/dist/remote-workspace-relay.js +16 -0
- package/dist/server.js +698 -172
- package/dist/{local-agent-targets.js → subagents/cli-target.js} +6 -6
- package/dist/{local-agent-profiles.js → subagents/profiles.js} +13 -5
- package/dist/subagents/providers/adapters/acp.js +148 -0
- package/dist/subagents/providers/adapters/claude.js +75 -0
- package/dist/{local-agent-runtime.js → subagents/providers/adapters/codex.js} +10 -4
- package/dist/subagents/providers/adapters/opencode.js +137 -0
- package/dist/subagents/providers/adapters/pi.js +232 -0
- package/dist/{local-agent-availability.js → subagents/providers/availability.js} +24 -10
- package/dist/subagents/providers/continuation.js +11 -0
- package/dist/subagents/providers/contract.js +1 -0
- package/dist/subagents/providers/registry.js +26 -0
- package/dist/subagents/providers/shared.js +40 -0
- package/dist/subagents/sessions/capability.js +214 -0
- package/dist/subagents/sessions/delivery-mailbox.js +115 -0
- package/dist/subagents/sessions/execution.js +171 -0
- package/dist/subagents/sessions/manager.js +107 -0
- package/dist/subagents/sessions/mcp/audit.js +85 -0
- package/dist/subagents/sessions/mcp/runtime.js +19 -0
- package/dist/{local-agent-store.js → subagents/sessions/store.js} +75 -39
- package/dist/ui/.vite/manifest.json +33 -33
- package/dist/ui/activity-panel-app.html +3 -3
- package/dist/ui/assets/{activity-panel-app-CjZVvVNc.js → activity-panel-app-E1ju2dqI.js} +1 -1
- package/dist/ui/assets/{heavy-payload-vGgBRvNX.js → heavy-payload-CeW-n9w5.js} +1 -1
- package/dist/ui/assets/{review-payload-4erWKckt.js → review-payload-B9CO298v.js} +1 -1
- package/dist/ui/assets/{scrollbar-CaOPzUJd.js → scrollbar-C2twAENW.js} +1 -1
- package/dist/ui/assets/workspace-app-BztEvZIC.js +5 -0
- package/dist/ui/assets/{workspace-app-DkAiSl_0.js → workspace-app-CwbJnb_w.js} +1 -1
- package/dist/ui/assets/workspace-app-YnUST8IP.css +1 -0
- package/dist/ui/assets/workspace-app-rKuhdae8.js +1 -0
- package/dist/ui/assets/workspace-lifecycle-app-CEfMdudP.js +1 -0
- package/dist/ui/workspace-app.html +4 -4
- package/dist/ui/workspace-lifecycle-app.html +4 -4
- package/dist/workspaces.js +3 -3
- package/docs/chatgpt-coding-workflow.md +2 -9
- package/docs/configuration.md +23 -0
- package/docs/debugging.md +7 -0
- package/docs/roadmap.md +42 -7
- package/package.json +2 -2
- package/scripts/debug/runtime.mjs +23 -1
- package/scripts/debug/runtime.test.mjs +14 -2
- package/scripts/debug/serve.mjs +4 -4
- package/scripts/release/release-gate.test.mjs +2 -2
- package/dist/local-agent-adapters.js +0 -653
- package/dist/ui/assets/workspace-app-CcrHAUIn.css +0 -1
- package/dist/ui/assets/workspace-app-DJmkPYJC.js +0 -1
- package/dist/ui/assets/workspace-app-QyauBrJX.js +0 -5
- package/dist/ui/assets/workspace-lifecycle-app-BIXEo53I.js +0 -1
- /package/dist/{local-agent-path.js → subagents/providers/path.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,49 @@ All notable ForgeRelay changes are documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.7.1] - 2026-08-30
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `subagent.session resume` 现在基于 provider-native continuation 继续已有 Session;Codex、Claude、OpenCode、Pi 支持真实 continuation,Cursor/Copilot 明确保持 start-only。
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- Session 固定创建时的 provider/profile/model/thinking,并严格限制在所属 Execution Workspace;busy resume、跨 Workspace 访问和不受支持的 continuation 都返回明确错误。
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Windows restart mailbox 测试在清理临时 SQLite state 前显式关闭 restored server,避免 `EBUSY`。
|
|
20
|
+
|
|
21
|
+
## [0.7.0] - 2026-08-30
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- 新增 first-class `subagent.session` Capability tracer:Host 可通过现有 Capability Gateway 发现并启动 provider-backed Subagent Session、查询 `status`、列出当前 Execution Workspace 拥有的 Session,并通过有界单次 delivery mailbox 接收后台 Run 的最终结果;canonical Core MCP tool 仍保持九个。
|
|
26
|
+
- 为 ForgeRelay Subagent 引入稳定的 Session / Run identity 和 workspace-scoped coordination,使每次 delegated execution 都有明确的 Run 生命周期、Activity 关联和 provider continuation 映射,而无需经由 `bash -> forgerelay agents ...` CLI 间接执行。
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- 将 Claude Code、Codex、OpenCode、Pi 等 provider 的原生 session store 作为 conversation history 真源;ForgeRelay SQLite 停止写入 delegated prompt、profile body、final response、Hook report history 和 provider event/items,仅保留轻量 ownership、provider/profile/model/thinking 与 active/latest Run 协调元数据。
|
|
31
|
+
- Provider adapter contract 收敛为 continuation identity、final response 与必要执行元数据,provider streaming/messages/events 只瞬时消费;profile body 仅在 Session 首次启动时交给 provider,ForgeRelay 不保存正文副本。
|
|
32
|
+
|
|
33
|
+
## [0.6.2] - 2026-08-29
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- Added Composite Workspace as a first-class Workspace kind on the existing `open_workspace` surface. A Composite Workspace has its own persistent `cws_...` identity, may start with zero members, and can mount named local, managed-worktree, or relayed Workspaces with Agent-facing purpose descriptions.
|
|
38
|
+
- Added explicit member routing across filesystem, capability, Bash/process, and Codex-compatible `apply_patch` / `exec_command` / `write_stdin` surfaces. The Composite Workspace ID remains Host-facing while each operation must name its execution member; ForgeRelay never selects or falls back to another member automatically.
|
|
39
|
+
- Added one Composite Host Turn / Activity presentation that aggregates local and remote member activity with member labels while keeping audit, process, filesystem, and remote execution facts owned by the actual member Workspace/Execution ForgeRelay.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- `close_workspace` now dissolves a Composite Workspace without closing member Workspaces, finalizing managed worktrees, interrupting member processes, deleting files, or removing Workspace Relay routes.
|
|
44
|
+
- Interactive debug launchers now derive their displayed local endpoints from the selected `FORGERELAY_DEBUG_CONFIG_DIR/config.json`, allowing multiple isolated debug instances to use separate config/state/worktree directories and different ports such as 7677 and 6768.
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
|
|
48
|
+
- Routed Codex-compatible process and patch tools through the same Workspace Relay and Composite member resolution path as the canonical tool surface, including explicit no-fallback behavior for remote members.
|
|
49
|
+
|
|
7
50
|
## [0.6.1] - 2026-08-28
|
|
8
51
|
|
|
9
52
|
### Added
|
package/README.md
CHANGED
|
@@ -101,6 +101,44 @@ Once a workspace is open, the host can:
|
|
|
101
101
|
Normal work happens in your existing checkout. ForgeRelay does not silently move
|
|
102
102
|
every task into a worktree.
|
|
103
103
|
|
|
104
|
+
## Composite workspaces across multiple devices
|
|
105
|
+
|
|
106
|
+
When one task needs more than one execution environment, a Composite Workspace keeps
|
|
107
|
+
one Host-facing working context while preserving each member Workspace as a separate
|
|
108
|
+
execution boundary. For example, `code` can point at a local checkout while
|
|
109
|
+
`compute` points through Workspace Relay at a GPU machine.
|
|
110
|
+
|
|
111
|
+
Composite Workspaces use the same lifecycle entry points as ordinary Workspaces:
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
open_workspace({ kind: "composite", name: "research-project" })
|
|
115
|
+
open_workspace({
|
|
116
|
+
action: "member",
|
|
117
|
+
workspaceId: "cws_...",
|
|
118
|
+
memberAction: "add",
|
|
119
|
+
member: {
|
|
120
|
+
name: "compute",
|
|
121
|
+
purpose: "GPU and high-performance computation",
|
|
122
|
+
path: "/srv/research",
|
|
123
|
+
relay: "gpu-server"
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Work still names the member explicitly:
|
|
129
|
+
|
|
130
|
+
```text
|
|
131
|
+
read({ workspaceId: "cws_...", member: "code", path: "src/model.py" })
|
|
132
|
+
bash({ workspaceId: "cws_...", member: "compute", command: "python train.py" })
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
ForgeRelay does not merge member filesystems, Git state, Hooks, Skills, processes,
|
|
136
|
+
or audit facts, and it never infers a member from the tool type or purpose text.
|
|
137
|
+
The Composite Activity Panel presents member operations in one Host Turn while the
|
|
138
|
+
actual facts remain owned by the member Workspace. `close_workspace` on a Composite
|
|
139
|
+
Workspace means **dissolve**: the Composite identity and membership are removed, but
|
|
140
|
+
member Workspaces, worktrees, running jobs, files, and relay routes are preserved.
|
|
141
|
+
|
|
104
142
|
### Progressive MCP context
|
|
105
143
|
|
|
106
144
|
ForgeRelay keeps the callable MCP surface and its low-frequency operating manuals
|
|
@@ -1,69 +1,129 @@
|
|
|
1
|
-
# ForgeRelay
|
|
1
|
+
# ForgeRelay Subagent
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
当任务需要委派给另一个本地 coding agent、获取第二意见、并行调查,或用户明确点名 Subagent/provider 时读取本指南。
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 当前接口
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
启用 Subagent 后,`open_workspace` 会在 `capabilityCatalog` 中公开 `subagent.session`,同时返回紧凑的 provider/profile 元数据。不要为 Subagent 寻找或假设额外的 Core MCP tool;长期可见 Core tool surface 保持不变。
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
通过统一 `capability` gateway 调用:
|
|
10
10
|
|
|
11
|
-
```
|
|
12
|
-
|
|
11
|
+
```text
|
|
12
|
+
name = subagent.session
|
|
13
|
+
action = run
|
|
13
14
|
```
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
当前支持四个 operation:
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
- `start`:创建 Subagent Session,并立即启动第一个 Subagent Run;
|
|
19
|
+
- `resume`:在支持真实 continuation 的 provider 上继续现有 Session;
|
|
20
|
+
- `status`:读取当前 Workspace 中一个 Session 的协调状态;
|
|
21
|
+
- `list`:列出当前 Workspace 拥有的 Session 摘要。
|
|
22
|
+
|
|
23
|
+
`subagent.session` 不支持 `batch.execute`。
|
|
24
|
+
|
|
25
|
+
## start
|
|
26
|
+
|
|
27
|
+
使用 profile:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"operation": "start",
|
|
32
|
+
"target": "reviewer",
|
|
33
|
+
"prompt": "检查当前改动的并发与错误处理。"
|
|
34
|
+
}
|
|
20
35
|
```
|
|
21
36
|
|
|
22
|
-
|
|
37
|
+
也可以把 ForgeRelay 支持的 provider 名直接作为 `target`。创建新 Session 时可以显式给出 `model` / `thinking`;profile 已有默认值时通常无需重复覆盖。
|
|
23
38
|
|
|
24
|
-
|
|
39
|
+
返回值包含:
|
|
25
40
|
|
|
26
|
-
|
|
41
|
+
- `session.id`:ForgeRelay 的 Subagent Session identity;
|
|
42
|
+
- `session.status`:`running` 或 `idle`;
|
|
43
|
+
- `run.id`:本次 delegated execution 的 Subagent Run identity;
|
|
44
|
+
- provider/profile/model 等紧凑协调元数据。
|
|
27
45
|
|
|
28
|
-
|
|
46
|
+
首次 `start` 使用当时有效的 profile body 作为 provider-native conversation 的初始 instructions。ForgeRelay 不把 profile body 复制进自己的 Session SQLite。
|
|
29
47
|
|
|
30
|
-
##
|
|
48
|
+
## resume
|
|
31
49
|
|
|
32
|
-
|
|
50
|
+
已有 Session 完成一次 Run 后,可发送新的 delegated prompt:
|
|
33
51
|
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"operation": "resume",
|
|
55
|
+
"sessionId": "agt_...",
|
|
56
|
+
"prompt": "继续检查测试覆盖。"
|
|
57
|
+
}
|
|
38
58
|
```
|
|
39
59
|
|
|
40
|
-
|
|
60
|
+
`resume` 只接受 `sessionId + prompt`,不能改变 model/thinking。Session 创建时确定的 provider/profile/model/thinking 在整个 Session 生命周期中保持固定;resume 不重新读取或注入当前 profile body,而是使用 provider-native continuation history。
|
|
41
61
|
|
|
42
|
-
- `
|
|
43
|
-
- `run <provider>`:没有合适 profile 时直接启动 ForgeRelay 内建 provider;
|
|
44
|
-
- `run <id>`:向现有 agent session 发送 follow-up;
|
|
45
|
-
- `show <id>`:查看状态和最新响应;仍在运行时可稍后再次调用;
|
|
46
|
-
- shell workspace 环境会把 CLI 操作自动限定到当前 ForgeRelay workspace。
|
|
62
|
+
同一个 Session 最多只有一个 active Run;Session 正在执行时再次 resume 会返回 `subagent.busy`,不会排队或并发执行。Codex、Claude、OpenCode、Pi 支持真实 continuation;Cursor/Copilot 当前明确标记为 start-only,resume 返回 `subagent.continuation_unsupported`,不会伪装成新 provider session。
|
|
47
63
|
|
|
48
|
-
|
|
64
|
+
## status / list
|
|
49
65
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
66
|
+
查询一个 Session:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"operation": "status",
|
|
71
|
+
"sessionId": "agt_..."
|
|
72
|
+
}
|
|
53
73
|
```
|
|
54
74
|
|
|
55
|
-
|
|
75
|
+
列出当前 Workspace 的 Session:
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"operation": "list"
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Session 受实际 Execution Workspace 所有权约束;Session ID 不是跨 Workspace 的访问凭证。`status` / `resume` 都只能访问当前实际 Execution Workspace 拥有的 Session,`list` 也只返回当前 Workspace 的紧凑摘要。
|
|
84
|
+
|
|
85
|
+
Session 返回中会给出 `continuationSupported` 与 `resumable`;`open_workspace` 的 provider metadata 也会明确给出 `continuationSupported`。当前尚未通过 first-class Capability 开放 `stop` 或 `delete`,不要伪造这些 operation,也不要用新的 Core MCP tool 绕过 Capability Gateway。
|
|
86
|
+
|
|
87
|
+
## 后台完成与结果交付
|
|
88
|
+
|
|
89
|
+
`start` 接受执行后会尽快把 Session/Run identity 返回给 Host,Subagent Run 在后台继续执行。
|
|
90
|
+
|
|
91
|
+
Run 完成后:
|
|
92
|
+
|
|
93
|
+
- ForgeRelay 创建一个 linked `subagent_result` Activity,只记录 Session/Run/provider/status 等有界元数据;
|
|
94
|
+
- final response 放入有界 delivery mailbox,等待同一 Workspace 的后续 ForgeRelay 调用领取;
|
|
95
|
+
- 成功领取后 mailbox 条目立即删除,同一个 completion 不重复交付;
|
|
96
|
+
- 未领取 completion 可以跨正常 ForgeRelay 进程重启保留。
|
|
97
|
+
|
|
98
|
+
如果需要等待结果,使用 `status` 进行有节制的后续查询;不要高频短轮询。
|
|
99
|
+
|
|
100
|
+
## 数据所有权
|
|
101
|
+
|
|
102
|
+
Claude Code、Codex、OpenCode、Pi 等 provider 自己的 session store 是 conversation history 的真源。ForgeRelay 只保存恢复、Workspace ownership 和执行协调所需的小型元数据。
|
|
103
|
+
|
|
104
|
+
ForgeRelay 不把以下内容保存进 Subagent Session SQLite 或 Activity Audit:
|
|
105
|
+
|
|
106
|
+
- delegated prompt;
|
|
107
|
+
- profile body;
|
|
108
|
+
- provider transcript/messages/events/items;
|
|
109
|
+
- final response 正文;
|
|
110
|
+
- 完整 Hook report 历史;
|
|
111
|
+
- 完整 Subagent Run 历史。
|
|
112
|
+
|
|
113
|
+
Activity 只保留操作摘要;delivery mailbox 只用于尚未交付的 bounded completion,不是 conversation/history store。
|
|
114
|
+
|
|
115
|
+
## Hooks
|
|
56
116
|
|
|
57
|
-
|
|
117
|
+
`SubagentStart` / `SubagentStop` 在每一次 Subagent Run 生命周期中触发。Hook payload 使用 Session/Run/profile/provider/model/thinking/status 等协调元数据,不包含 delegated prompt 或 final response。
|
|
58
118
|
|
|
59
|
-
##
|
|
119
|
+
## CLI 兼容
|
|
60
120
|
|
|
61
|
-
|
|
121
|
+
`forgerelay agents` 仍可用于本地诊断和兼容性操作,但 Host 正常委派优先使用 `subagent.session` Capability,不要通过 `bash -> forgerelay agents ...` 实现 first-class Subagent。
|
|
62
122
|
|
|
63
|
-
|
|
123
|
+
## 验证责任
|
|
64
124
|
|
|
65
|
-
|
|
66
|
-
- 只读调查:核对关键结论是否有仓库证据;
|
|
67
|
-
- 向用户说明使用了哪个 profile/provider、它给出的结论、你做了哪些验证,以及剩余风险。
|
|
125
|
+
Subagent 返回不是自动验证过的最终结论。收到结果后仍应按照任务类型验证:
|
|
68
126
|
|
|
69
|
-
|
|
127
|
+
- 写入型任务检查真实 diff,并运行相关测试;
|
|
128
|
+
- 只读调查核对关键结论对应的仓库事实;
|
|
129
|
+
- 向用户说明使用的 profile/provider、核心结论、已做验证与剩余风险。
|
|
@@ -32,7 +32,7 @@ export class ActivityLifecycle {
|
|
|
32
32
|
const activityId = executionContext.activityId;
|
|
33
33
|
try {
|
|
34
34
|
const result = await options.operation(executionContext);
|
|
35
|
-
this.finish(activityId, result, options.outcome?.(result) ?? { type: "succeeded" });
|
|
35
|
+
this.finish(activityId, options.auditResult?.(result) ?? result, options.outcome?.(result) ?? { type: "succeeded" });
|
|
36
36
|
return result;
|
|
37
37
|
}
|
|
38
38
|
catch (error) {
|
|
@@ -20,6 +20,7 @@ const activitySummarySchema = z.object({
|
|
|
20
20
|
target: z.string(),
|
|
21
21
|
detailAvailable: z.boolean(),
|
|
22
22
|
workspaceId: z.string().optional(),
|
|
23
|
+
member: z.string().optional(),
|
|
23
24
|
processId: z.number().int().positive().optional(),
|
|
24
25
|
outputId: z.string().optional(),
|
|
25
26
|
commandLength: z.number().int().nonnegative().optional(),
|
|
@@ -126,6 +126,7 @@ function toSummary(record) {
|
|
|
126
126
|
target: activityTarget(record, request, result, structured),
|
|
127
127
|
detailAvailable: !bulkGroup && record.tool !== "rename" && record.tool !== "delete" && record.tool !== "batch",
|
|
128
128
|
...(record.workspace.id ? { workspaceId: record.workspace.id } : {}),
|
|
129
|
+
...(stringField(request, "member") ? { member: stringField(request, "member") } : {}),
|
|
129
130
|
...(processId !== undefined ? { processId } : {}),
|
|
130
131
|
...(outputId !== undefined ? { outputId } : {}),
|
|
131
132
|
...(bashLike && command !== undefined ? { commandLength: command.length } : {}),
|
package/dist/capabilities.js
CHANGED
|
@@ -92,7 +92,7 @@ export function buildCapabilityFingerprint(config, version, context = {}) {
|
|
|
92
92
|
capabilities.push("batch.execute");
|
|
93
93
|
}
|
|
94
94
|
if (config.subagents) {
|
|
95
|
-
capabilities.push("subagent.
|
|
95
|
+
capabilities.push("subagent.session");
|
|
96
96
|
}
|
|
97
97
|
if (config.artifactsEnabled && context.artifactDownloadSupported) {
|
|
98
98
|
capabilities.push("artifact.native-download");
|
|
@@ -130,6 +130,25 @@ export function createCapabilityRegistry(dependencies) {
|
|
|
130
130
|
line: z.number().int(),
|
|
131
131
|
column: z.number().int(),
|
|
132
132
|
};
|
|
133
|
+
const subagentSessionInput = z.discriminatedUnion("operation", [
|
|
134
|
+
z.object({
|
|
135
|
+
operation: z.literal("start"),
|
|
136
|
+
target: z.string().min(1),
|
|
137
|
+
prompt: z.string().min(1),
|
|
138
|
+
model: z.string().min(1).optional(),
|
|
139
|
+
thinking: z.string().min(1).optional(),
|
|
140
|
+
}).strict(),
|
|
141
|
+
z.object({
|
|
142
|
+
operation: z.literal("resume"),
|
|
143
|
+
sessionId: z.string().min(1),
|
|
144
|
+
prompt: z.string().min(1),
|
|
145
|
+
}).strict(),
|
|
146
|
+
z.object({
|
|
147
|
+
operation: z.literal("status"),
|
|
148
|
+
sessionId: z.string().min(1),
|
|
149
|
+
}).strict(),
|
|
150
|
+
z.object({ operation: z.literal("list") }).strict(),
|
|
151
|
+
]);
|
|
133
152
|
const codeIntelligenceInput = z.discriminatedUnion("operation", [
|
|
134
153
|
z.object({ operation: z.literal("definition"), ...positionInput }).strict(),
|
|
135
154
|
z.object({ operation: z.literal("hover"), ...positionInput }).strict(),
|
|
@@ -201,6 +220,21 @@ export function createCapabilityRegistry(dependencies) {
|
|
|
201
220
|
run: async (input, context, options) => dependencies.codeIntelligence.run(input, context, options),
|
|
202
221
|
}]
|
|
203
222
|
: []),
|
|
223
|
+
...(dependencies.subagentSession
|
|
224
|
+
? [{
|
|
225
|
+
name: "subagent.session",
|
|
226
|
+
description: "Coordinate provider-backed Subagent Sessions in the current Execution Workspace.",
|
|
227
|
+
guideName: "subagents",
|
|
228
|
+
readGuideBeforeFirstUse: true,
|
|
229
|
+
batchPolicy: "unsupported",
|
|
230
|
+
inputSchema: subagentSessionInput,
|
|
231
|
+
availability: () => ({
|
|
232
|
+
available: dependencies.subagentSession?.available ?? false,
|
|
233
|
+
reason: dependencies.subagentSession?.unavailableReason,
|
|
234
|
+
}),
|
|
235
|
+
run: async (input, context, options) => dependencies.subagentSession.run(input, context, options),
|
|
236
|
+
}]
|
|
237
|
+
: []),
|
|
204
238
|
...(dependencies.batchExecute
|
|
205
239
|
? [{
|
|
206
240
|
name: "batch.execute",
|