@khorsheed/dsh-local-agent-codex 0.1.0-rc.8 → 0.2.0-rc.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 CHANGED
@@ -1,5 +1,9 @@
1
1
  # 变更记录
2
2
 
3
+ ## 0.2.0-rc.1(2026-09-30)
4
+
5
+ - **家族折叠:委派工具收进本包**。新增 `./tool` 组合入口(`src/tool.ts`)——`subagent_codex` 委派工具由 agent 预设点名 `name: '@khorsheed/dsh-local-agent-codex/tool'` 按会话授予,Config 两字段(`provider` / `toolName`)全部可选、默认即本包取值,预设行无需配置;行 id `tool-subagent-codex-local` 不变。bundle patch 不再插 profile 根工具行(官方 `tool-subagent-codex` 行的停用覆盖保留),本包自挂载恰好一行(provider 行)。实现共享自家族核 `@khorsheed/dsh-local-agent` 的 `./tool-factory` 导出;对 `@khorsheed/dsh-local-agent-tool-subagent` 的依赖移除(该包退役)。
6
+
3
7
  ## 0.1.0-rc.8(2026-09-30)
4
8
 
5
9
  家族同版联动:加宽 `@deepseek-ai/dsh-*` peer 区间以覆盖宿主 0.2.0(0.2.0 的兼容闸会禁用 peer 区间不覆盖宿主版本的已装插件)。无功能变更。
package/README.en.md CHANGED
@@ -10,7 +10,7 @@ dsh agents already get work done, but some tasks you simply want to give to your
10
10
 
11
11
  ## Features
12
12
 
13
- - **Delegate from any preset** — the `subagent_codex` tool mounts at the profile root; no per-preset setup.
13
+ - **Per-session delegation grant** — the `subagent_codex` tool is this package's `./tool` composition entry, granted to the sessions of an agent preset that names it (e.g. dev mode); no per-preset setup.
14
14
  - **Scoped-home isolation** — all Codex state (config, credentials, rollout session records) lives in `$DSH_HOME/local-agent/codex`, separate from your `~/.codex`.
15
15
  - **In-session login** — `/codex login` runs `codex login` on a pseudo-terminal and the authorization page opens in your browser by itself; when the page hands you a code, paste it back with `/codex code <code>`. The settings card shows auth status and offers sign-out.
16
16
  - **Resident mode (live)** — one resident `codex app-server` process per member, one turn per round: output streams into the child session in real time, cancel does not kill the process, and a crash resumes the same thread; off — or a channel that cannot come up — means the one-shot `codex exec` path, hot-switched without a reload.
@@ -114,7 +114,7 @@ The last line selects the provider for delegations; keep the rest of the file in
114
114
 
115
115
  **Named scopes.** `/codex login --scope <name>` opens a second scoped home at `<homesRoot>/codex@<name>`: the directory is provisioned with the same `config.toml` that pins credential storage to a file rather than the macOS keychain, so that scope's login lands in its own `auth.json`. A scoped delegation runs `codex exec` there, writes its rollout there and reads it back from there — exec-only, because the resident app-server is bound to the default scoped home.
116
116
 
117
- **Bundle composition.** The patch registers the `codex` harness (scoped `CODEX_HOME`, PTY login, rollout-file session records) and mounts the `subagent_codex` tool at the profile root — the official preset row of that name already ships `disabled: true`, and the patch disables it once more, so a community install can never register two `subagent_codex` tools; a user who deliberately re-enables the official row in their own preset layer gets a loud duplicate-name conflict and must choose one, by design. The `codex-local` provider spawns `codex exec` under that home (the one-shot drive when live is off). The browser half ships with this package's `./client`: the Codex settings card composes the family core's shared `ProviderAuthBlock`, landing on the Plugins page's per-package detail view (`plugins.bundle.config`, keyed by package name) for a standalone install, on the bundle detail view's row-level configure entry (`plugins.row.config`) when installed as a family-bundle member, and — on 0.1.5 — on the Settings → Plugins → 插件配置 tab (`settings.plugin.item`, keyed by the settings namespace); card writes ride the bound settingsScope and hot-apply without a reload. The core itself comes from `@khorsheed/dsh-local-agent`, declared as a dependency.
117
+ **Bundle composition.** The patch registers the `codex` harness (scoped `CODEX_HOME`, PTY login, rollout-file session records) — exactly one provider row; since the family fold the `subagent_codex` tool is this package's `./tool` composition entry, granted per session by an agent preset that names it (the dev preset's `tool-subagent-codex-local` row), no longer mounted at the profile root. The family keeps the official model-facing name `subagent_codex`: the official preset row of that name already ships `disabled: true`, and the patch disables the profile-root row once more, so a community install can never register two `subagent_codex` tools; a user who deliberately re-enables the official row in their own preset layer gets a loud duplicate-name conflict and must choose one, by design. The `codex-local` provider spawns `codex exec` under that home (the one-shot drive when live is off). The browser half ships with this package's `./client`: the Codex settings card composes the family core's shared `ProviderAuthBlock`, landing on the Plugins page's per-package detail view (`plugins.bundle.config`, keyed by package name) for a standalone install, on the bundle detail view's row-level configure entry (`plugins.row.config`) when installed as a family-bundle member, and — on 0.1.5 — on the Settings → Plugins → 插件配置 tab (`settings.plugin.item`, keyed by the settings namespace); card writes ride the bound settingsScope and hot-apply without a reload. The core itself comes from `@khorsheed/dsh-local-agent`, declared as a dependency.
118
118
 
119
119
  **Login and credentials.** `/codex login` runs `codex login` on a pseudo-terminal through the host's subprocess seam — the CLI starts its own localhost callback server and opens the browser itself, the first-class flow; the command reply carries the authorization URL captured from the output as a fallback link, and when the CLI asks for a code the user pastes it with `/codex code <code>` (written to the child's stdin). Completion is decided by a credential watch on the scoped home: `auth.json` present with a stamp newer than the watch start — a leftover credential is never mistaken for a fresh login. A browserless remote terminal can still run `codex login --device-auth` by hand with `CODEX_HOME` pointed at the scoped home, landing in the same `auth.json`. First start writes a minimal `config.toml` pinning `cli_auth_credentials_store = "file"` — Codex's default `auto` would resolve to the macOS keychain, leaking credentials outside the scoped home and defeating this package's `auth.json` presence check; an existing config is left untouched. `/codex logout` deletes the scoped `auth.json`, so a later login authorizes a fresh account.
120
120
 
@@ -128,7 +128,7 @@ Both the locate and the scan are calibrated for concurrency. codex writes `turn_
128
128
 
129
129
  **Container delegation.** An orchestrator may run the round inside an **already-acquired container** through the facade's `DelegationCallOptions.exec` (`{ container, workdir, env? }`): the argv becomes `docker exec -w <workdir> [-e NAME…] <container> codex exec …` and everything else (stream parse, settle, rollout readback, recording) is byte-for-byte unchanged. `env` must name the in-container `CODEX_HOME`, and it should be the read-write bind mount of the host scoped home — the rollout readback reads the host copy. A container round always takes the exec one-shot (the resident app-server is a host process) and declares no member bridge (a host unix socket cannot reach into the container). Measured: one "answer 2+2" round in an `eval-env:pinned` unit settles `completed` with output `4`, and `observedModel` reads back as `gpt-5.6-sol` from the rollout the container wrote into the host scoped home.
130
130
 
131
- **Resume.** The family tool (`@khorsheed/dsh-local-agent-tool-subagent`) adds an optional `resume` parameter to the official `description`/`prompt` subset. A fresh delegation's result self-describes its handle (`追问请带 resume="<childSessionId>"`); passing it back continues the same codex thread (`codex exec --json resume <thread_id>`) in the same dsh child session, with per-round accounting. The handle is read only from the `resume` parameter and resolved by the `localAgent` registry only for the recording parent session and provider — a forged handle is rejected before any CLI process starts.
131
+ **Resume.** The family tool (this package's `./tool` composition entry, sharing the family core's `./tool-factory` implementation) adds an optional `resume` parameter to the official `description`/`prompt` subset. A fresh delegation's result self-describes its handle (`追问请带 resume="<childSessionId>"`); passing it back continues the same codex thread (`codex exec --json resume <thread_id>`) in the same dsh child session, with per-round accounting. The handle is read only from the `resume` parameter and resolved by the `localAgent` registry only for the recording parent session and provider — a forged handle is rejected before any CLI process starts.
132
132
 
133
133
  **Event-stream mirror.** The subagent session mirrors the `codex exec --json` stream in order: `reasoning` → reasoning blocks, `agent_message` → reply text, `command_execution`/`web_search_call`/`function_call_output` → tool lines (`[工具 Bash] <command> → output`), `file_change` → an `ApplyPatch` card (kind and path per change), `function_call` (e.g. the multi-agent `wait`) → a card under its own name with the `function_call_output` merged in; the final `agent_message` is the run output and the round's usage rides the last mirrored assistant message. Resumed rounds append their own turn without duplication. Aborting settles the tool result immediately while keeping the events and usage already received.
134
134
 
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # last confirmed-consistent state. Both languages carry equal authority; after
3
3
  # editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/local-agent-codex/README.en.md
5
- packages/local-agent-codex/README.en.md: cc127472d85b28dfbb599b9a6c545682be5f6a4b
6
- packages/local-agent-codex/README.md: fbc7461e9bd406f05b9988e9a6ad1ed2fe3fab78
5
+ packages/local-agent-codex/README.en.md: db346c4441e59ca802de149ec93b253a250e9cdd
6
+ packages/local-agent-codex/README.md: 10d69741bf5034c13705231065546981d5596aaf
package/README.md CHANGED
@@ -10,7 +10,7 @@ dsh 的 agent 已经能干活,但有些任务你就是想交给本机的 Codex C
10
10
 
11
11
  ## 特性
12
12
 
13
- - **任意 preset 皆可委派**——`subagent_codex` 工具挂在 profile 根,无需逐 preset 配置。
13
+ - **按会话授予的委派**——`subagent_codex` 工具是本包的 `./tool` 组合入口,由点名它的 agent 预设(如开发模式)授予该预设的会话,无需逐 preset 配置。
14
14
  - **作用域目录隔离**——Codex 的全部状态(config、凭据、rollout 会话记录)留在 `$DSH_HOME/local-agent/codex`,与你的 `~/.codex` 互不干扰。
15
15
  - **会话内登录**——`/codex login` 在伪终端里跑 `codex login`,授权页自动在浏览器打开;页面给出 code 时用 `/codex code <code>` 粘贴回来。设置卡片显示认证状态并提供退出登录。
16
16
  - **常驻模式(live)**——每成员常驻一个 `codex app-server` 进程,按轮发 turn:输出实时流入子会话、取消不杀进程、崩溃后自动续上原线程;关闭或通道起不来即回一次性 `codex exec`,热切换无需重载。
@@ -114,7 +114,7 @@ model_provider = "dsh-router"
114
114
 
115
115
  **命名 scope。** `/codex login --scope <名>` 会在 `<homesRoot>/codex@<名>` 里另开一份作用域目录:目录建立时自动跑同一份 `config.toml` provision(把凭据存储钉在文件而非 macOS keychain),因此该 scope 的登录落在它自己的 `auth.json` 里。带 scope 的委派用它跑 `codex exec`、把 rollout 写进它、从它回读;只走 exec——常驻 app-server 绑的是缺省作用域目录。
116
116
 
117
- **bundle 组成。** patch 注册 `codex` harness(`CODEX_HOME` 作用域目录、PTY 登录、rollout 文件会话记录),并把 `subagent_codex` 工具挂到 profile 根——官方 preset 的同名行本就 `disabled: true`,patch 再禁一次,社区安装永远不会注册出两个 `subagent_codex`;刻意在自有 preset 层重新启用官方行的用户会得到响亮的重名冲突,按设计必须二选一。`codex-local` provider 在该作用域目录下 spawn `codex exec`(live 未启用时的一次性驱动)。浏览器半部分随本包 `./client` 提供:Codex 设置卡组合家族 core 的共享 `ProviderAuthBlock`,独立安装落在 Plugins 页的包详情视图(`plugins.bundle.config`,按包名派发),作为家族 bundle 成员安装落在 bundle 详情页的行级配置入口(`plugins.row.config`),0.1.5 落在 设置 → 插件 → 插件配置(`settings.plugin.item`,按设置命名空间派发);卡片写入经绑定的 settingsScope 热生效,不用重载。core 本身来自声明为依赖的 `@khorsheed/dsh-local-agent`。
117
+ **bundle 组成。** patch 注册 `codex` harness(`CODEX_HOME` 作用域目录、PTY 登录、rollout 文件会话记录)——恰好一行 provider 行;`subagent_codex` 工具自家族折叠起是本包的 `./tool` 组合入口,由点名它的 agent 预设按会话授予(dev 预设的 `tool-subagent-codex-local` 行),不再挂 profile 根。家族沿用官方模型名 `subagent_codex`:官方 preset 的同名行本就 `disabled: true`,patch 对 profile 根的同名行再禁一次,社区安装永远不会注册出两个 `subagent_codex`;刻意在自有 preset 层重新启用官方行的用户会得到响亮的重名冲突,按设计必须二选一。`codex-local` provider 在该作用域目录下 spawn `codex exec`(live 未启用时的一次性驱动)。浏览器半部分随本包 `./client` 提供:Codex 设置卡组合家族 core 的共享 `ProviderAuthBlock`,独立安装落在 Plugins 页的包详情视图(`plugins.bundle.config`,按包名派发),作为家族 bundle 成员安装落在 bundle 详情页的行级配置入口(`plugins.row.config`),0.1.5 落在 设置 → 插件 → 插件配置(`settings.plugin.item`,按设置命名空间派发);卡片写入经绑定的 settingsScope 热生效,不用重载。core 本身来自声明为依赖的 `@khorsheed/dsh-local-agent`。
118
118
 
119
119
  **登录与凭据。** `/codex login` 经宿主 subprocess seam 在伪终端里跑 `codex login`——CLI 自己起 localhost 回调服务并打开浏览器,这是第一类流程;命令回复附带从输出里抓取的授权 URL 作兜底链接,CLI 追问 code 时用户以 `/codex code <code>` 粘贴(写入子进程 stdin)。完成由监听作用域目录的凭证 watch 判定:`auth.json` 出现且时间戳新于 watch 起点——残留的旧凭证不会被误认成新登录。无浏览器的远程终端可以手动以 `CODEX_HOME` 指向作用域目录跑 `codex login --device-auth`,凭据落在同一份 `auth.json`。首次启动写入一份最小 `config.toml`,固定 `cli_auth_credentials_store = "file"`——Codex 默认的 `auto` 会解析到 macOS keychain,把凭据泄漏到作用域目录之外并使本包的 `auth.json` 存在性检查失效;已存在的 config 保持不动。`/codex logout` 删除作用域 `auth.json`,之后重新登录即可换账号。
120
120
 
@@ -128,7 +128,7 @@ model_provider = "dsh-router"
128
128
 
129
129
  **容器内委派。** 编排器可以经门面 `DelegationCallOptions.exec`(`{ container, workdir, env? }`)让本轮跑在一个**已取得的容器**里:argv 变成 `docker exec -w <workdir> [-e NAME…] <container> codex exec …`,其余(流解析、settle、rollout 回读、记录)逐字节不变。`env` 必须给出容器内的 `CODEX_HOME`,且它应当是宿主作用域目录的 rw bind 挂载点——rollout 回读读的是宿主那份文件。容器轮固定走 exec 一次性驱动(长驻 app-server 是宿主进程),且不声明成员桥(宿主 unix socket 进不去容器)。实测:`eval-env:pinned` 单元里一次「回答 2+2」settle 为 `completed`,输出 `4`,`observedModel` 从容器写进宿主作用域目录的 rollout 里回读为 `gpt-5.6-sol`。
130
130
 
131
- **续聊(resume)。** 家族工具(`@khorsheed/dsh-local-agent-tool-subagent`)在官方 `description`/`prompt` 子集上增加可选 `resume` 参数。首次委派的结果文本自述句柄(`追问请带 resume="<childSessionId>"`);后续轮次传回它即在**同一个** dsh 子会话里继续**同一个** codex 线程(`codex exec --json resume <thread_id>`),按轮记账。句柄只从 `resume` 参数读取,localAgent registry 仅对记录该委派的同一 parent 会话与 provider 解析——伪造句柄在任何 CLI 进程启动前就被拒绝。
131
+ **续聊(resume)。** 家族工具(本包的 `./tool` 组合入口,实现共享自家族 core 的 `./tool-factory`)在官方 `description`/`prompt` 子集上增加可选 `resume` 参数。首次委派的结果文本自述句柄(`追问请带 resume="<childSessionId>"`);后续轮次传回它即在**同一个** dsh 子会话里继续**同一个** codex 线程(`codex exec --json resume <thread_id>`),按轮记账。句柄只从 `resume` 参数读取,localAgent registry 仅对记录该委派的同一 parent 会话与 provider 解析——伪造句柄在任何 CLI 进程启动前就被拒绝。
132
132
 
133
133
  **事件流镜像。** 子代理会话按顺序镜像 `codex exec --json` 事件流:`reasoning` → 推理块、`agent_message` → 回复文本、`command_execution`/`web_search_call`/`function_call_output` → 工具行(`[工具 Bash] <command> → output`),`file_change` → `ApplyPatch` 卡(逐 change 列出 kind 与路径),`function_call`(如 multi-agent 的 `wait`)→ 同名工具卡、结果由 `function_call_output` 并入;最终 `agent_message` 作为运行输出,当轮用量挂在最后一条镜像的 assistant 消息上。续聊轮各自追加自己的 turn,不会重复。中止会让工具结果立即 settle,并保留已收到的事件与用量。
134
134
 
package/cordis.patch.yml CHANGED
@@ -8,25 +8,23 @@
8
8
  # alongside this bundle, or this provider stays pending. No other patch inserts
9
9
  # the core row id.
10
10
  #
11
- # Two rows are inserted:
12
- # - local-agent-codex: this bundle's plugin registers the `codex` harness
13
- # (CODEX_HOME scoped home, `codex login --device-auth`, rollout-file
14
- # session records).
15
- # - tool-subagent-codex-local: the family-owned delegation tool (schema
16
- # description/prompt plus optional resume) over the `codex-local`
17
- # provider. The toolName is `subagent_codex` — the family takes the
18
- # model-facing name: the official preset row of that name ships
19
- # `disabled: true`, and this patch disables it too (below) so a community
20
- # install can never register two `subagent_codex` tools. A user who
21
- # deliberately re-enables the official row in their own preset layer gets
22
- # a loud duplicate-name conflict — by design, they must choose one. The
23
- # family tool adds continuation: a later round may pass the dsh child
24
- # session id returned by the first delegation to continue the same codex
25
- # thread.
11
+ # Exactly ONE row is inserted: the provider (this bundle's plugin registers the
12
+ # `codex` harness — CODEX_HOME scoped home, `codex login --device-auth`,
13
+ # rollout-file session records). The `subagent_codex` delegation tool is no
14
+ # longer a profile-root row: since the family fold it ships as this package's
15
+ # `./tool` composition entry (`name: '@khorsheed/dsh-local-agent-codex/tool'`
16
+ # in an agent preset), granted per session — the dev preset's
17
+ # `tool-subagent-codex-local` row is the grant point. The family keeps the
18
+ # official model-facing name `subagent_codex`: the official preset row of that
19
+ # name ships `disabled: true`, and this patch disables the profile-root row
20
+ # too (below) so a community install can never register two `subagent_codex`
21
+ # tools. A user who deliberately re-enables the official row in their own
22
+ # preset layer gets a loud duplicate-name conflict — by design, they must
23
+ # choose one. The family tool keeps its continuation parameter: a later round
24
+ # may pass the dsh child session id returned by the first delegation to
25
+ # continue the same codex thread.
26
26
  #
27
- # The tool mounts at the profile root, so every agent preset can delegate
28
- # without per-preset variants. The provider starts no codex process until a
29
- # tool call or /codex login.
27
+ # The provider starts no codex process until a tool call or /codex login.
30
28
 
31
29
  - id: tool-subagent-codex
32
30
  disabled: true
@@ -34,9 +32,3 @@
34
32
  - insert:
35
33
  - id: local-agent-codex
36
34
  name: '@khorsheed/dsh-local-agent-codex'
37
-
38
- - id: tool-subagent-codex-local
39
- name: '@khorsheed/dsh-local-agent-tool-subagent'
40
- config:
41
- provider: codex-local
42
- toolName: subagent_codex
package/lib/client.js CHANGED
@@ -243,30 +243,30 @@ window.__ModuleLoader__.load({
243
243
  document.head.appendChild(tag);
244
244
  }
245
245
  var ProviderAuthBlock_module_css_default = {
246
- "loginButton": "On5p7W_loginButton",
247
- "title": "On5p7W_title",
248
- "promptText": "On5p7W_promptText",
246
+ "rowHead": "On5p7W_rowHead",
247
+ "rowTag": "On5p7W_rowTag",
248
+ "credentialDot": "On5p7W_credentialDot",
249
+ "retryButton": "On5p7W_retryButton",
250
+ "rows": "On5p7W_rows",
249
251
  "rowIdentity": "On5p7W_rowIdentity",
252
+ "loginPrompt": "On5p7W_loginPrompt",
253
+ "openPage": "On5p7W_openPage",
250
254
  "intro": "On5p7W_intro",
251
- "credentialDot": "On5p7W_credentialDot",
255
+ "title": "On5p7W_title",
256
+ "rosterError": "On5p7W_rosterError",
257
+ "rowCard": "On5p7W_rowCard",
258
+ "loginButton": "On5p7W_loginButton",
259
+ "dotOff": "On5p7W_dotOff",
260
+ "promptText": "On5p7W_promptText",
261
+ "codeInput": "On5p7W_codeInput",
252
262
  "dotPending": "On5p7W_dotPending",
253
- "rowName": "On5p7W_rowName",
254
- "dotOn": "On5p7W_dotOn",
255
- "rows": "On5p7W_rows",
256
- "rowActions": "On5p7W_rowActions",
263
+ "logoutButton": "On5p7W_logoutButton",
257
264
  "section": "On5p7W_section",
258
- "rowCard": "On5p7W_rowCard",
259
- "loginPrompt": "On5p7W_loginPrompt",
260
265
  "status": "On5p7W_status",
261
- "codeInput": "On5p7W_codeInput",
266
+ "dotOn": "On5p7W_dotOn",
262
267
  "rowPending": "On5p7W_rowPending",
263
- "rowTag": "On5p7W_rowTag",
264
- "logoutButton": "On5p7W_logoutButton",
265
- "dotOff": "On5p7W_dotOff",
266
- "rowHead": "On5p7W_rowHead",
267
- "rosterError": "On5p7W_rosterError",
268
- "retryButton": "On5p7W_retryButton",
269
- "openPage": "On5p7W_openPage"
268
+ "rowActions": "On5p7W_rowActions",
269
+ "rowName": "On5p7W_rowName"
270
270
  };
271
271
  //#endregion
272
272
  //#region ../local-agent/src/client/ProviderAuthBlock.tsx
@@ -539,10 +539,10 @@ window.__ModuleLoader__.load({
539
539
  document.head.appendChild(tag);
540
540
  }
541
541
  var AuthStatusDot_module_css_default = {
542
- "credentialDot": "OFjNUG_credentialDot",
542
+ "dotPending": "OFjNUG_dotPending",
543
543
  "dotOn": "OFjNUG_dotOn",
544
544
  "dotOff": "OFjNUG_dotOff",
545
- "dotPending": "OFjNUG_dotPending"
545
+ "credentialDot": "OFjNUG_credentialDot"
546
546
  };
547
547
  //#endregion
548
548
  //#region ../local-agent/src/client/AuthStatusDot.tsx
@@ -568,40 +568,40 @@ window.__ModuleLoader__.load({
568
568
  document.head.appendChild(tag);
569
569
  }
570
570
  var SettingsCard_module_css_default = {
571
- "rowLabel": "oWITGW_rowLabel",
572
- "modelField": "oWITGW_modelField",
573
- "modelMenuChevron": "oWITGW_modelMenuChevron",
574
- "saved": "oWITGW_saved",
575
- "modelItemCheck": "oWITGW_modelItemCheck",
576
- "modelItemCurrent": "oWITGW_modelItemCurrent",
577
- "info": "oWITGW_info",
571
+ "modelMenuUp": "oWITGW_modelMenuUp",
572
+ "headText": "oWITGW_headText",
573
+ "card": "oWITGW_card",
578
574
  "cardOpen": "oWITGW_cardOpen",
575
+ "hint": "oWITGW_hint",
576
+ "name": "oWITGW_name",
577
+ "modelItem": "oWITGW_modelItem",
578
+ "chevron": "oWITGW_chevron",
579
+ "errorText": "oWITGW_errorText",
579
580
  "body": "oWITGW_body",
580
- "description": "oWITGW_description",
581
581
  "chevronOpen": "oWITGW_chevronOpen",
582
- "modelMenuUp": "oWITGW_modelMenuUp",
582
+ "modelField": "oWITGW_modelField",
583
+ "modelMenuChevron": "oWITGW_modelMenuChevron",
584
+ "description": "oWITGW_description",
583
585
  "modelItemLabel": "oWITGW_modelItemLabel",
584
- "hint": "oWITGW_hint",
585
- "nameRow": "oWITGW_nameRow",
586
- "header": "oWITGW_header",
587
- "errorText": "oWITGW_errorText",
588
- "switch": "oWITGW_switch",
589
- "modelItem": "oWITGW_modelItem",
590
- "modelMenuButton": "oWITGW_modelMenuButton",
586
+ "saved": "oWITGW_saved",
587
+ "info": "oWITGW_info",
591
588
  "modelMenu": "oWITGW_modelMenu",
592
589
  "block": "oWITGW_block",
593
- "headText": "oWITGW_headText",
594
- "name": "oWITGW_name",
595
- "chevron": "oWITGW_chevron",
590
+ "modelSave": "oWITGW_modelSave",
591
+ "nameRow": "oWITGW_nameRow",
592
+ "switchOn": "oWITGW_switchOn",
593
+ "modelItemCurrent": "oWITGW_modelItemCurrent",
596
594
  "blockTitle": "oWITGW_blockTitle",
595
+ "rowLabel": "oWITGW_rowLabel",
596
+ "modelItemCheck": "oWITGW_modelItemCheck",
597
+ "modelItemDefault": "oWITGW_modelItemDefault",
597
598
  "knob": "oWITGW_knob",
599
+ "header": "oWITGW_header",
600
+ "switch": "oWITGW_switch",
598
601
  "modelInput": "oWITGW_modelInput",
599
- "modelSave": "oWITGW_modelSave",
600
- "modelItemDefault": "oWITGW_modelItemDefault",
601
602
  "modelMenuChevronOpen": "oWITGW_modelMenuChevronOpen",
602
603
  "row": "oWITGW_row",
603
- "card": "oWITGW_card",
604
- "switchOn": "oWITGW_switchOn"
604
+ "modelMenuButton": "oWITGW_modelMenuButton"
605
605
  };
606
606
  //#endregion
607
607
  //#region src/client/SettingsCard.tsx
package/lib/tool.js ADDED
@@ -0,0 +1,40 @@
1
+ import { mountSubagentDelegationTool, subagentToolConfigSchema } from "@khorsheed/dsh-local-agent/tool-factory";
2
+ //#region lib/types/tool.js
3
+ const PACKAGE_NAME = "@khorsheed/dsh-local-agent-codex";
4
+ /** This entry's own defaults: a preset row needs no config. */
5
+ const DEFAULT_PROVIDER = "codex-local";
6
+ const DEFAULT_TOOL_NAME = "subagent_codex";
7
+ /** Cordis plugin name used by loader diagnostics. */
8
+ const name = "local-agent-codex-tool";
9
+ /**
10
+ * The family core's `localAgent` service is a declared inject (the
11
+ * owning-family companion exception to the community-service probe rule): a
12
+ * preset's standing scope mounts at registry-activation time, BEFORE the
13
+ * profile's later bundle rows provide the core, so a one-shot ctx.get probe
14
+ * at apply saw ABSENT there and nothing re-ran the row (rc.1 boot order; the
15
+ * worktrees `./tool` entry documents the incident). The declared inject pends
16
+ * the row until the core provides, then the body applies.
17
+ */
18
+ const inject = [
19
+ "tools",
20
+ "subagents",
21
+ "localAgent"
22
+ ];
23
+ const Config = subagentToolConfigSchema(DEFAULT_PROVIDER, DEFAULT_TOOL_NAME);
24
+ /**
25
+ * Plugin body: mount the delegation tool through the family factory, stamped
26
+ * with THIS package as the tool-origin owner (AGENTS.md § Tool origin
27
+ * tagging — the shared factory never hardcodes an owner).
28
+ * @param ctx - Cordis context (the preset's agent-plane mount).
29
+ * @param config - row config (schema defaults already applied; the `??`
30
+ * fallbacks cover a direct ctx.plugin caller that bypassed validation).
31
+ */
32
+ function apply(ctx, config) {
33
+ const resolved = {
34
+ provider: config.provider ?? DEFAULT_PROVIDER,
35
+ toolName: config.toolName ?? DEFAULT_TOOL_NAME
36
+ };
37
+ mountSubagentDelegationTool(ctx, resolved, PACKAGE_NAME);
38
+ }
39
+ //#endregion
40
+ export { Config, apply, inject, name };
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The session-granted `subagent_codex` delegation tool — this package's
3
+ * `./tool` composition entry (the worktrees 0.3.0 / room 0.2.0 fold pattern)
4
+ * for agent-preset compositions. The row provides NO service (the
5
+ * preset-mount isolate-realm rule forbids service rows); it registers the
6
+ * model-facing tool into the host tools registry through the family factory
7
+ * (`@khorsheed/dsh-local-agent/tool-factory`), delegating to the `codex-local`
8
+ * provider this package's main row registers at the profile root — the
9
+ * official tool-row shape (the shipped `tool-bash` rows work the same way).
10
+ * Granting is therefore per-session: a preset names the row
11
+ * (`- id: tool-subagent-codex-local / name: '@khorsheed/dsh-local-agent-codex/tool'`),
12
+ * its sessions get the tool; every other preset's sessions do not.
13
+ *
14
+ * This row used to mount at the profile ROOT from this package's own bundle
15
+ * patch, pointing at the shared `@khorsheed/dsh-local-agent-tool-subagent`
16
+ * companion package; the family fold retired that package (the factory moved
17
+ * into the family core) and moved the row here. The package's bundle patch
18
+ * now mounts ONLY the provider row — a profile-root tool row would grant
19
+ * every session, exactly what the fold removed.
20
+ *
21
+ * @module @khorsheed/dsh-local-agent-codex/tool
22
+ */
23
+ import type { Context } from '@deepseek-ai/cordis';
24
+ import type z from '@deepseek-ai/schemastery';
25
+ /** Cordis plugin name used by loader diagnostics. */
26
+ export declare const name = "local-agent-codex-tool";
27
+ /**
28
+ * The family core's `localAgent` service is a declared inject (the
29
+ * owning-family companion exception to the community-service probe rule): a
30
+ * preset's standing scope mounts at registry-activation time, BEFORE the
31
+ * profile's later bundle rows provide the core, so a one-shot ctx.get probe
32
+ * at apply saw ABSENT there and nothing re-ran the row (rc.1 boot order; the
33
+ * worktrees `./tool` entry documents the incident). The declared inject pends
34
+ * the row until the core provides, then the body applies.
35
+ */
36
+ export declare const inject: string[];
37
+ /** Config: every field optional, defaulting to THIS provider's own values. */
38
+ export interface Config {
39
+ /** The `ctx.subagents` provider name to delegate to (default `codex-local`). */
40
+ provider?: string;
41
+ /** Model-facing tool name (default `subagent_codex`). */
42
+ toolName?: string;
43
+ }
44
+ export declare const Config: z;
45
+ /**
46
+ * Plugin body: mount the delegation tool through the family factory, stamped
47
+ * with THIS package as the tool-origin owner (AGENTS.md § Tool origin
48
+ * tagging — the shared factory never hardcodes an owner).
49
+ * @param ctx - Cordis context (the preset's agent-plane mount).
50
+ * @param config - row config (schema defaults already applied; the `??`
51
+ * fallbacks cover a direct ctx.plugin caller that bypassed validation).
52
+ */
53
+ export declare function apply(ctx: Context, config: Config): void;
54
+ //# sourceMappingURL=tool.d.ts.map
@@ -0,0 +1,34 @@
1
+ import { mountSubagentDelegationTool, subagentToolConfigSchema } from '@khorsheed/dsh-local-agent/tool-factory';
2
+ const PACKAGE_NAME = '@khorsheed/dsh-local-agent-codex';
3
+ /** This entry's own defaults: a preset row needs no config. */
4
+ const DEFAULT_PROVIDER = 'codex-local';
5
+ const DEFAULT_TOOL_NAME = 'subagent_codex';
6
+ /** Cordis plugin name used by loader diagnostics. */
7
+ export const name = 'local-agent-codex-tool';
8
+ /**
9
+ * The family core's `localAgent` service is a declared inject (the
10
+ * owning-family companion exception to the community-service probe rule): a
11
+ * preset's standing scope mounts at registry-activation time, BEFORE the
12
+ * profile's later bundle rows provide the core, so a one-shot ctx.get probe
13
+ * at apply saw ABSENT there and nothing re-ran the row (rc.1 boot order; the
14
+ * worktrees `./tool` entry documents the incident). The declared inject pends
15
+ * the row until the core provides, then the body applies.
16
+ */
17
+ export const inject = ['tools', 'subagents', 'localAgent'];
18
+ // Bare `z` annotation per the shared helper's variance note.
19
+ export const Config = subagentToolConfigSchema(DEFAULT_PROVIDER, DEFAULT_TOOL_NAME);
20
+ /**
21
+ * Plugin body: mount the delegation tool through the family factory, stamped
22
+ * with THIS package as the tool-origin owner (AGENTS.md § Tool origin
23
+ * tagging — the shared factory never hardcodes an owner).
24
+ * @param ctx - Cordis context (the preset's agent-plane mount).
25
+ * @param config - row config (schema defaults already applied; the `??`
26
+ * fallbacks cover a direct ctx.plugin caller that bypassed validation).
27
+ */
28
+ export function apply(ctx, config) {
29
+ const resolved = {
30
+ provider: config.provider ?? DEFAULT_PROVIDER,
31
+ toolName: config.toolName ?? DEFAULT_TOOL_NAME,
32
+ };
33
+ mountSubagentDelegationTool(ctx, resolved, PACKAGE_NAME);
34
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khorsheed/dsh-local-agent-codex",
3
- "description": "Codex harness for dsh-local-agent: scoped CODEX_HOME, one-shot codex exec delegation visible in the 子代理 surface, rollout-file session records",
3
+ "description": "Codex harness for dsh-local-agent: scoped CODEX_HOME, one-shot codex exec delegation visible in the 子代理 surface, rollout-file session records; the session-granted `subagent_codex` delegation tool ships as the package's `./tool` composition entry",
4
4
  "keywords": [
5
5
  "dsh",
6
6
  "dsh-plugin",
@@ -8,7 +8,7 @@
8
8
  "local-agent",
9
9
  "codex"
10
10
  ],
11
- "version": "0.1.0-rc.8",
11
+ "version": "0.2.0-rc.1",
12
12
  "type": "module",
13
13
  "main": "lib/index.js",
14
14
  "types": "lib/types/index.d.ts",
@@ -25,6 +25,10 @@
25
25
  "types": "./lib/types/records.d.ts",
26
26
  "default": "./lib/records.js"
27
27
  },
28
+ "./tool": {
29
+ "types": "./lib/types/tool.d.ts",
30
+ "default": "./lib/tool.js"
31
+ },
28
32
  "./client": {
29
33
  "types": "./lib/types/client/index.d.ts",
30
34
  "default": "./lib/client.js"
@@ -65,8 +69,7 @@
65
69
  ],
66
70
  "license": "MIT",
67
71
  "dependencies": {
68
- "@khorsheed/dsh-local-agent": "^0.1.0-rc.8",
69
- "@khorsheed/dsh-local-agent-tool-subagent": "^0.1.0-rc.8"
72
+ "@khorsheed/dsh-local-agent": "^0.2.0-rc.1"
70
73
  },
71
74
  "peerDependencies": {
72
75
  "@deepseek-ai/cordis": "^4.0.1",