@vidge/dsh-agent-hub 0.1.0-rc1

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 (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +133 -0
  3. package/README.zh.md +115 -0
  4. package/cordis.patch.yml +22 -0
  5. package/lib/client.js +1494 -0
  6. package/lib/index.js +5045 -0
  7. package/lib/invariant.js +96 -0
  8. package/lib/types/client/LoopEngineComposerSelect.d.ts +73 -0
  9. package/lib/types/client/LoopEngineSection.d.ts +43 -0
  10. package/lib/types/client/engine-rpc.d.ts +74 -0
  11. package/lib/types/client/index.d.ts +28 -0
  12. package/lib/types/client/locales.d.ts +44 -0
  13. package/lib/types/client/session-location.d.ts +63 -0
  14. package/lib/types/client/store.d.ts +58 -0
  15. package/lib/types/commands.d.ts +69 -0
  16. package/lib/types/driver-core/context-files.d.ts +62 -0
  17. package/lib/types/driver-core/ownership.d.ts +40 -0
  18. package/lib/types/driver-core/permission-knobs.d.ts +26 -0
  19. package/lib/types/driver-core/prompt.d.ts +23 -0
  20. package/lib/types/driver-core/skill-inject.d.ts +59 -0
  21. package/lib/types/engine-claude/agent.d.ts +116 -0
  22. package/lib/types/engine-claude/loop.d.ts +99 -0
  23. package/lib/types/engine-claude/mapping.d.ts +84 -0
  24. package/lib/types/engine-claude/permission.d.ts +41 -0
  25. package/lib/types/engine-claude/process.d.ts +59 -0
  26. package/lib/types/engine-claude/provider-env.d.ts +50 -0
  27. package/lib/types/engine-claude/sdk.d.ts +101 -0
  28. package/lib/types/engine-claude/types.d.ts +28 -0
  29. package/lib/types/engine-codex/agent.d.ts +109 -0
  30. package/lib/types/engine-codex/appserver/client.d.ts +49 -0
  31. package/lib/types/engine-codex/appserver/mapping.d.ts +67 -0
  32. package/lib/types/engine-codex/appserver/thread.d.ts +66 -0
  33. package/lib/types/engine-codex/appserver/types.d.ts +215 -0
  34. package/lib/types/engine-codex/loop.d.ts +92 -0
  35. package/lib/types/engine-codex/permission.d.ts +32 -0
  36. package/lib/types/engine-codex/skills.d.ts +29 -0
  37. package/lib/types/engine-codex/types.d.ts +19 -0
  38. package/lib/types/engine-pi/agent.d.ts +125 -0
  39. package/lib/types/engine-pi/loop.d.ts +96 -0
  40. package/lib/types/engine-pi/permission.d.ts +43 -0
  41. package/lib/types/engine-pi/rpc/client.d.ts +105 -0
  42. package/lib/types/engine-pi/rpc/mapping.d.ts +37 -0
  43. package/lib/types/engine-pi/rpc/types.d.ts +235 -0
  44. package/lib/types/engine-pi/skills.d.ts +55 -0
  45. package/lib/types/engine-pi/types.d.ts +27 -0
  46. package/lib/types/engine-record.d.ts +124 -0
  47. package/lib/types/index.d.ts +138 -0
  48. package/lib/types/invariant.d.ts +23 -0
  49. package/lib/types/llm-compat.d.ts +32 -0
  50. package/lib/types/namespace.d.ts +19 -0
  51. package/lib/types/patch-manager.d.ts +78 -0
  52. package/lib/types/router.d.ts +189 -0
  53. package/lib/types/rpc.d.ts +113 -0
  54. package/lib/types/settings.d.ts +29 -0
  55. package/lib/types/skills.d.ts +93 -0
  56. package/package.json +107 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 vidge
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # dsh-agent-hub
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@vidge/dsh-agent-hub?color=cb3837)](https://www.npmjs.com/package/@vidge/dsh-agent-hub)
4
+
5
+ Run any agent loop engine on **dsh** — the built-in in-process loop, Claude
6
+ Code, Codex, or Pi — **chosen per session**, all sharing dsh's own session
7
+ store, message format, model routing, and tracing.
8
+
9
+ Pick an engine the way you pick a model: in the composer, when you start a
10
+ session. The session you are in keeps running on the engine it was created
11
+ with. No restart, no global switch, no interrupted work.
12
+
13
+ ## Why a hub
14
+
15
+ dsh admits exactly one `AgentFactory` for the whole process. That single slot
16
+ is what forced every earlier approach to be a *global* choice: to run Claude
17
+ Code you had to disable the base loop, and every session in the profile moved
18
+ with you.
19
+
20
+ This plugin takes that slot and turns it into a router. It holds one factory
21
+ per engine — including dsh's own in-process loop, mounted as a first-class
22
+ engine rather than replaced — and dispatches each `createAgent` / `resume` call
23
+ to the engine that session belongs to.
24
+
25
+ ```
26
+ dsh harness (session · llm · tracing · model routing)
27
+
28
+ │ the one AgentFactory slot
29
+
30
+ LoopEngineRouter
31
+ ├── in-process → @deepseek-ai/dsh-agent-loop (hosted, not replaced)
32
+ ├── claude-code → Claude Agent SDK
33
+ ├── codex → codex app-server
34
+ └── pi → pi --mode rpc
35
+ ```
36
+
37
+ Everything above the router stays dsh's. Each engine's native output is
38
+ translated into dsh's `Message` / `ContentBlock` / `StreamChunk` types, so
39
+ sessions from different engines are stored, streamed, resumed, and traced
40
+ identically.
41
+
42
+ ### Engine affinity is durable
43
+
44
+ A session's engine is recorded when it is created and travels with it. Resuming
45
+ a session restores it to the engine that produced its history — not to whatever
46
+ is currently selected. This matters because engine session logs carry different
47
+ provenance (a Codex-driven session records `provider = 'codex'`), and replaying
48
+ that history under another engine would hand the model a transcript it cannot
49
+ act on.
50
+
51
+ Forked sessions and subagents inherit the parent's engine.
52
+
53
+ ## Install
54
+
55
+ ```sh
56
+ dsh plugin --profile web add @vidge/dsh-agent-hub
57
+ ```
58
+
59
+ Restart `dsh web` once after installing. After that, engine selection is
60
+ runtime state — switching never requires a restart again.
61
+
62
+ > Installing writes a small managed block into the profile's
63
+ > `cordis.patch.yml`, disabling the bundle's own `agent-loop` row so the router
64
+ > can take the factory slot and re-mount that loop itself. Everything else in
65
+ > that file is preserved byte for byte.
66
+
67
+ ### Requirements
68
+
69
+ Only for the engines you actually use:
70
+
71
+ - **Claude Code** — the Claude Code CLI installed on the host. Credentials are
72
+ derived from dsh's own LLM provider configuration (see below); a CLI login is
73
+ a fallback, not a requirement.
74
+ - **Codex** — authenticated via `codex login`, or a `CODEX_API_KEY` entry.
75
+ - **Pi** — authenticated the way `pi` expects: its own `~/.pi/agent/auth.json`,
76
+ or the provider's API-key environment variable.
77
+
78
+ The in-process engine needs nothing beyond dsh itself.
79
+
80
+ ## Usage
81
+
82
+ Choose an engine in the composer when starting a session. To change engines,
83
+ start a new session — the current one keeps its engine, and anything still
84
+ running on it is undisturbed.
85
+
86
+ **Settings → Loop engine** sets the default for new sessions and controls
87
+ whether the composer picker is shown.
88
+
89
+ To remove the plugin:
90
+
91
+ ```sh
92
+ dsh plugin --profile web remove @vidge/dsh-agent-hub
93
+ ```
94
+
95
+ Then restart `dsh web`.
96
+
97
+ ## Model and credential routing
98
+
99
+ For the Claude Code engine, the child process's provider environment is derived
100
+ from dsh's own LLM configuration rather than inherited from the shell that
101
+ launched the host. The selected model names a provider route; the plugin reads
102
+ that route's endpoint from `llm-pi-ai` settings, resolves its key through dsh's
103
+ `credentials` service, and states the result as the environment variables the
104
+ Agent SDK understands — Bedrock (including behind a corporate gateway) and
105
+ native Anthropic endpoints.
106
+
107
+ This is why a dsh started from a desktop launcher works: it inherits no
108
+ provider variables, but it does not need to. dsh already knows the answer.
109
+
110
+ When a route cannot be derived — an OpenAI-protocol provider with no Claude
111
+ Code equivalent, an unset credential — the plugin falls back to inherited
112
+ environment and reports what the child was actually pointed at.
113
+
114
+ ## Engine notes
115
+
116
+ - **Claude Code** runs one SDK query per dsh step. Its slash commands are
117
+ bridged into the web menu (built-ins plus user-level `~/.claude/commands/`)
118
+ and forwarded to the engine, which expands them natively. Project-level
119
+ `.claude/commands/` files stay engine-side and work when typed directly.
120
+ - **Codex** runs `codex app-server` and has no interactive tool approval —
121
+ permissions come from the session's `sandboxMode` + `approvalPolicy`. Its
122
+ `AGENTS.md` files are surfaced through the dsh skill-injection seam across
123
+ every directory from the session cwd up to the git root, plus
124
+ `~/.codex/AGENTS.md`.
125
+ - **Pi** runs `pi --mode rpc`. Pi has no permission system, so the whole child
126
+ is sandboxed through the dsh subprocess service (default `read-only`). Its
127
+ context files (`AGENTS.md` / `CLAUDE.md`, with `AGENTS.override.md`
128
+ preferred, plus the user-level file under the pi config dir) and its
129
+ `skills/` catalogs are surfaced through the same seam.
130
+
131
+ ## License
132
+
133
+ MIT
package/README.zh.md ADDED
@@ -0,0 +1,115 @@
1
+ # dsh-agent-hub
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@vidge/dsh-agent-hub?color=cb3837)](https://www.npmjs.com/package/@vidge/dsh-agent-hub)
4
+
5
+ 在 **dsh** 上运行任意 agent loop 引擎——内置的 in-process loop、Claude Code、
6
+ Codex、Pi——**按会话选择**,并且全部共用 dsh 自己的会话存储、消息格式、模型调度
7
+ 与链路追踪。
8
+
9
+ 像选模型一样选引擎:在 composer 里选,开一个新会话。当前会话仍跑在它创建时的引擎
10
+ 上。不用重启,不是全局切换,不会打断正在进行的工作。
11
+
12
+ ## 为什么是 hub
13
+
14
+ dsh 整个进程只允许一个 `AgentFactory`。正是这个唯一槽位,使得以往所有做法都只能是
15
+ **全局**选择:要跑 Claude Code 就得禁掉 base loop,profile 里的每个会话都被一起
16
+ 带走。
17
+
18
+ 本插件占住那个槽位,并把它变成一个路由器。它为每个引擎持有一个 factory——**包括
19
+ dsh 自己的 in-process loop,它是被托管为一等引擎,而不是被替换**——并把每次
20
+ `createAgent` / `resume` 调用分发给该会话所属的引擎。
21
+
22
+ ```
23
+ dsh harness (会话 · llm · 追踪 · 模型调度)
24
+
25
+ │ 唯一的 AgentFactory 槽位
26
+
27
+ LoopEngineRouter
28
+ ├── in-process → @deepseek-ai/dsh-agent-loop (托管,非替换)
29
+ ├── claude-code → Claude Agent SDK
30
+ ├── codex → codex app-server
31
+ └── pi → pi --mode rpc
32
+ ```
33
+
34
+ 路由器之上的一切仍然是 dsh 的。各引擎的原生输出会被翻译成 dsh 的 `Message` /
35
+ `ContentBlock` / `StreamChunk` 类型,因此不同引擎产生的会话在存储、流式推送、恢复
36
+ 和追踪上表现完全一致。
37
+
38
+ ### 引擎归属是持久的
39
+
40
+ 会话的引擎在创建时被记录,并随会话一起流转。恢复会话时会回到产生这段历史的引擎,
41
+ 而不是当前选中的引擎。这一点很重要:各引擎的会话日志 provenance 不同(Codex 驱动
42
+ 的会话记录 `provider = 'codex'`),跨引擎重放会把一段模型无法据以行动的历史交给它。
43
+
44
+ fork 出的会话与 subagent 会继承父会话的引擎。
45
+
46
+ ## 安装
47
+
48
+ ```sh
49
+ dsh plugin --profile web add @vidge/dsh-agent-hub
50
+ ```
51
+
52
+ 安装后重启一次 `dsh web`。此后引擎选择即为运行时状态——再也不需要因切换而重启。
53
+
54
+ > 安装会在 profile 的 `cordis.patch.yml` 中写入一小段托管块,禁用 bundle 自带的
55
+ > `agent-loop` 行,以便路由器接管 factory 槽位并由它自己重新挂载该 loop。文件中
56
+ > 其余内容逐字节保留。
57
+
58
+ ### 依赖要求
59
+
60
+ 仅针对你实际使用的引擎:
61
+
62
+ - **Claude Code** —— 宿主机安装 Claude Code CLI。凭证由 dsh 自身的 LLM provider
63
+ 配置派生(见下文);CLI 登录只是兜底,不是必需。
64
+ - **Codex** —— 通过 `codex login` 认证,或提供 `CODEX_API_KEY`。
65
+ - **Pi** —— 按 pi 自己的方式认证:`~/.pi/agent/auth.json`,或对应 provider 的
66
+ API-key 环境变量。
67
+
68
+ in-process 引擎除 dsh 本身外无任何额外要求。
69
+
70
+ ## 使用
71
+
72
+ 在 composer 中开始会话时选择引擎。要换引擎,开一个新会话——当前会话保持它的引擎,
73
+ 仍在其上运行的任务不受影响。
74
+
75
+ **设置 → Loop engine** 用于设定新会话的默认引擎,以及控制是否显示 composer 选择器。
76
+
77
+ 卸载插件:
78
+
79
+ ```sh
80
+ dsh plugin --profile web remove @vidge/dsh-agent-hub
81
+ ```
82
+
83
+ 然后重启 `dsh web`。
84
+
85
+ ## 模型与凭证路由
86
+
87
+ 对 Claude Code 引擎,子进程的 provider 环境变量由 **dsh 自身的 LLM 配置派生**,
88
+ 而不是从启动宿主的 shell 继承。选中的模型指明一条 provider 路由,插件从
89
+ `llm-pi-ai` 设置中读取该路由的 endpoint,通过 dsh 的 `credentials` 服务解析其密钥,
90
+ 再把结果表述为 Agent SDK 能理解的环境变量——支持 Bedrock(含企业网关场景)与原生
91
+ Anthropic endpoint。
92
+
93
+ 这正是从桌面启动器启动的 dsh 也能工作的原因:它没有继承任何 provider 变量,但它
94
+ 不需要。dsh 自己就知道答案。
95
+
96
+ 当路由无法派生时——例如没有 Claude Code 对应实现的 OpenAI 协议 provider、或凭证
97
+ 未配置——插件会回退到继承环境,并报告子进程实际被指向了哪里。
98
+
99
+ ## 各引擎说明
100
+
101
+ - **Claude Code** 每个 dsh step 运行一次 SDK query。其斜杠命令被桥接进 web 菜单
102
+ (内置命令加上用户级 `~/.claude/commands/`)并转发给引擎原生展开。项目级
103
+ `.claude/commands/` 文件保留在引擎侧,直接输入即可使用。
104
+ - **Codex** 运行 `codex app-server`,没有交互式工具审批——权限来自会话的
105
+ `sandboxMode` + `approvalPolicy`。其 `AGENTS.md` 指令文件通过 dsh 的
106
+ skill-injection 接缝暴露,覆盖从会话 cwd 到 git 根目录的每一层,外加
107
+ `~/.codex/AGENTS.md`。
108
+ - **Pi** 运行 `pi --mode rpc`。Pi 没有权限系统,因此整个子进程通过 dsh subprocess
109
+ 服务沙箱化(默认 `read-only`)。其上下文文件(`AGENTS.md` / `CLAUDE.md`,
110
+ 优先 `AGENTS.override.md`,加上 pi 配置目录下的用户级文件)与 `skills/` 目录
111
+ 通过同一接缝暴露。
112
+
113
+ ## 许可
114
+
115
+ MIT
@@ -0,0 +1,22 @@
1
+ # Bundle patch layer of @vidge/dsh-agent-hub, applied when the loader expands
2
+ # this bundle — before any plugin's apply() runs. Both rows must live here.
3
+ #
4
+ # Disabling `agent-loop` is a BOOT-TIME fact, not something this plugin can do
5
+ # at runtime. The harness admits exactly one AgentFactory, and the base loop's
6
+ # constructor claims it via `ctx.agents.setFactory(this)` while the loader is
7
+ # still expanding entries — strictly before `loop-engine` applies. A profile
8
+ # that leaves the row enabled therefore fails the whole plugin tree with
9
+ # "an agent factory is already registered" and never reaches the router. The
10
+ # managed block this plugin writes into the profile's own cordis.patch.yml
11
+ # cannot substitute: that layer is applied after the bundle, and the write
12
+ # itself happens in apply(), by which point AgentLoop has already registered.
13
+ #
14
+ # The base loop is not lost by being disabled here — `mountBaseLoop` hosts it
15
+ # behind the router as the `in-process` engine, through a context that
16
+ # redirects its setFactory into router registration.
17
+ - id: agent-loop
18
+ disabled: true
19
+
20
+ - insert:
21
+ - id: loop-engine
22
+ name: '@vidge/dsh-agent-hub'