super-dsh 0.1.6 → 0.1.10-e

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 (260) hide show
  1. package/README.md +25 -3
  2. package/agent-agy/cordis.patch.yml +7 -4
  3. package/agent-agy/dist/agent.d.ts +12 -11
  4. package/agent-agy/dist/agy-auth-gateway.d.ts +124 -0
  5. package/agent-agy/dist/agy-auth-gateway.js +233 -0
  6. package/agent-agy/dist/agy-auth.d.ts +153 -0
  7. package/agent-agy/dist/agy-auth.js +179 -0
  8. package/agent-agy/dist/agy-cli-client.d.ts +39 -9
  9. package/agent-agy/dist/agy-cli-client.js +82 -18
  10. package/agent-agy/dist/agy-store.d.ts +8 -0
  11. package/agent-agy/dist/index.d.ts +46 -16
  12. package/agent-agy/dist/index.js +82 -56
  13. package/agent-agy/dist/models.d.ts +70 -0
  14. package/agent-agy/dist/models.js +102 -3
  15. package/agent-agy/package.json +7 -5
  16. package/agent-agy-sdk/cordis.patch.yml +58 -0
  17. package/agent-agy-sdk/dist/adapter.d.ts +15 -0
  18. package/agent-agy-sdk/dist/adapter.js +42 -0
  19. package/agent-agy-sdk/dist/agent-preset-agy.d.ts +27 -0
  20. package/agent-agy-sdk/dist/agent-preset-agy.js +32 -0
  21. package/agent-agy-sdk/dist/agent.d.ts +138 -0
  22. package/agent-agy-sdk/dist/agent.js +494 -0
  23. package/{agent-agy → agent-agy-sdk}/dist/agy-client.d.ts +26 -6
  24. package/{agent-agy → agent-agy-sdk}/dist/agy-client.js +43 -25
  25. package/agent-agy-sdk/dist/agy-sessions.d.ts +25 -0
  26. package/agent-agy-sdk/dist/agy-sessions.js +107 -0
  27. package/agent-agy-sdk/dist/agy-store.d.ts +39 -0
  28. package/agent-agy-sdk/dist/agy-store.js +83 -0
  29. package/agent-agy-sdk/dist/inbox.d.ts +26 -0
  30. package/agent-agy-sdk/dist/inbox.js +53 -0
  31. package/agent-agy-sdk/dist/index.d.ts +93 -0
  32. package/agent-agy-sdk/dist/index.js +476 -0
  33. package/agent-agy-sdk/dist/models.d.ts +41 -0
  34. package/agent-agy-sdk/dist/models.js +74 -0
  35. package/agent-agy-sdk/dist/sdk-venv.d.ts +76 -0
  36. package/agent-agy-sdk/dist/sdk-venv.js +173 -0
  37. package/agent-agy-sdk/dist/world-plugin.d.ts +10 -0
  38. package/agent-agy-sdk/dist/world-plugin.js +82 -0
  39. package/agent-agy-sdk/package.json +64 -0
  40. package/agent-claude/dist/adapter.js +106 -31
  41. package/agent-claude/dist/agent.js +154 -17
  42. package/agent-claude/dist/claude-client.js +84 -43
  43. package/agent-claude/dist/claude-launch.js +101 -0
  44. package/agent-claude/dist/claude-native-config.js +169 -0
  45. package/agent-claude/dist/claude-provider-gateway.js +340 -0
  46. package/agent-claude/dist/claude-providers.js +391 -0
  47. package/agent-claude/dist/claude-route.js +152 -0
  48. package/agent-claude/dist/index.js +214 -37
  49. package/agent-claude/dist/models.js +14 -0
  50. package/agent-claude/dist/sdk-runtime.js +320 -0
  51. package/agent-claude/package.json +6 -4
  52. package/agent-codex/README.md +141 -36
  53. package/agent-codex/cordis.patch.yml +14 -10
  54. package/agent-codex/dist/adapter.js +64 -28
  55. package/agent-codex/dist/agent.js +255 -81
  56. package/agent-codex/dist/app-server-approvals.js +165 -0
  57. package/agent-codex/dist/app-server-client.js +723 -0
  58. package/agent-codex/dist/app-server-events.js +432 -0
  59. package/agent-codex/dist/app-server-protocol.js +95 -0
  60. package/agent-codex/dist/app-server-wire.js +299 -0
  61. package/agent-codex/dist/codex-launch.js +78 -0
  62. package/agent-codex/dist/codex-native-config.js +392 -0
  63. package/agent-codex/dist/codex-provider-gateway.js +402 -0
  64. package/agent-codex/dist/codex-providers.js +376 -0
  65. package/agent-codex/dist/codex-route.js +86 -0
  66. package/agent-codex/dist/index.js +256 -115
  67. package/agent-codex/dist/permission.js +75 -1
  68. package/agent-codex/package.json +1 -2
  69. package/agent-codex-sdk/README.md +79 -0
  70. package/agent-codex-sdk/cordis.patch.yml +81 -0
  71. package/agent-codex-sdk/dist/adapter.js +91 -0
  72. package/agent-codex-sdk/dist/agent-preset-codex.js +32 -0
  73. package/agent-codex-sdk/dist/agent.js +1085 -0
  74. package/agent-codex-sdk/dist/codex-native-config.js +392 -0
  75. package/agent-codex-sdk/dist/codex-provider-gateway.js +402 -0
  76. package/agent-codex-sdk/dist/codex-providers.js +376 -0
  77. package/agent-codex-sdk/dist/codex-route.js +86 -0
  78. package/{agent-codex/dist/codex-client.js → agent-codex-sdk/dist/codex-sdk-client.js} +253 -32
  79. package/agent-codex-sdk/dist/codex-sdk-launch.js +92 -0
  80. package/agent-codex-sdk/dist/codex-store.js +180 -0
  81. package/agent-codex-sdk/dist/inbox.js +53 -0
  82. package/agent-codex-sdk/dist/index.js +739 -0
  83. package/agent-codex-sdk/dist/permission.js +71 -0
  84. package/agent-codex-sdk/dist/sdk-runtime.js +307 -0
  85. package/agent-codex-sdk/dist/session-map.js +167 -0
  86. package/agent-codex-sdk/dist/world-plugin.js +93 -0
  87. package/agent-codex-sdk/package.json +79 -0
  88. package/agent-codex-sdk/scripts/fetch-sdk-runtime.mjs +57 -0
  89. package/agent-omp/README.md +72 -55
  90. package/agent-omp/dist/agent.js +36 -11
  91. package/agent-omp/dist/index.js +92 -52
  92. package/agent-omp/dist/lazy-rpc.js +11 -4
  93. package/agent-omp/dist/omp-cli.js +114 -97
  94. package/agent-omp/dist/omp-store.js +12 -4
  95. package/agent-omp/dist/permission.js +70 -5
  96. package/agent-omp/dist/rpc-client.js +409 -0
  97. package/agent-omp/dist/world-plugin.js +36 -3
  98. package/agent-omp/package.json +2 -6
  99. package/agent-omp-sdk/README.md +103 -0
  100. package/agent-omp-sdk/cordis.patch.yml +108 -0
  101. package/agent-omp-sdk/dist/adapter.d.ts +21 -0
  102. package/agent-omp-sdk/dist/adapter.js +36 -0
  103. package/agent-omp-sdk/dist/agent-preset-omp.d.ts +31 -0
  104. package/agent-omp-sdk/dist/agent-preset-omp.js +32 -0
  105. package/agent-omp-sdk/dist/agent.d.ts +64 -0
  106. package/agent-omp-sdk/dist/agent.js +1178 -0
  107. package/agent-omp-sdk/dist/discovery.d.ts +57 -0
  108. package/agent-omp-sdk/dist/discovery.js +116 -0
  109. package/agent-omp-sdk/dist/inbox.d.ts +28 -0
  110. package/agent-omp-sdk/dist/inbox.js +53 -0
  111. package/agent-omp-sdk/dist/index.d.ts +60 -0
  112. package/agent-omp-sdk/dist/index.js +632 -0
  113. package/agent-omp-sdk/dist/knobs.d.ts +34 -0
  114. package/agent-omp-sdk/dist/knobs.js +50 -0
  115. package/agent-omp-sdk/dist/lazy-rpc.d.ts +98 -0
  116. package/agent-omp-sdk/dist/lazy-rpc.js +178 -0
  117. package/agent-omp-sdk/dist/mobile/zoom-guard.d.ts +187 -0
  118. package/agent-omp-sdk/dist/mobile/zoom-guard.js +294 -0
  119. package/agent-omp-sdk/dist/mobile-boot.d.ts +49 -0
  120. package/agent-omp-sdk/dist/mobile-boot.js +38 -0
  121. package/agent-omp-sdk/dist/models.d.ts +39 -0
  122. package/agent-omp-sdk/dist/models.js +299 -0
  123. package/agent-omp-sdk/dist/omp-cli.d.ts +67 -0
  124. package/agent-omp-sdk/dist/omp-cli.js +164 -0
  125. package/agent-omp-sdk/dist/omp-disk-discovery.d.ts +27 -0
  126. package/agent-omp-sdk/dist/omp-disk-discovery.js +178 -0
  127. package/agent-omp-sdk/dist/omp-executable.d.ts +2 -0
  128. package/agent-omp-sdk/dist/omp-executable.js +30 -0
  129. package/agent-omp-sdk/dist/omp-store.d.ts +134 -0
  130. package/agent-omp-sdk/dist/omp-store.js +526 -0
  131. package/agent-omp-sdk/dist/pairing.d.ts +7 -0
  132. package/agent-omp-sdk/dist/pairing.js +45 -0
  133. package/agent-omp-sdk/dist/permission.d.ts +138 -0
  134. package/agent-omp-sdk/dist/permission.js +161 -0
  135. package/agent-omp-sdk/dist/protocol.d.ts +189 -0
  136. package/agent-omp-sdk/dist/rpc-types.d.ts +77 -0
  137. package/agent-omp-sdk/dist/rpc-types.js +1 -0
  138. package/agent-omp-sdk/dist/sdk-client.d.ts +160 -0
  139. package/{agent-omp → agent-omp-sdk}/dist/sdk-client.js +108 -56
  140. package/agent-omp-sdk/dist/sdk-runtime.d.ts +211 -0
  141. package/agent-omp-sdk/dist/sdk-runtime.js +418 -0
  142. package/agent-omp-sdk/dist/sidecar-client.d.ts +87 -0
  143. package/agent-omp-sdk/dist/sidecar-client.js +197 -0
  144. package/agent-omp-sdk/dist/store/adapter.d.ts +17 -0
  145. package/agent-omp-sdk/dist/store/adapter.js +47 -0
  146. package/agent-omp-sdk/dist/store/db.d.ts +70 -0
  147. package/agent-omp-sdk/dist/store/db.js +210 -0
  148. package/agent-omp-sdk/dist/store/index.d.ts +23 -0
  149. package/agent-omp-sdk/dist/store/index.js +59 -0
  150. package/agent-omp-sdk/dist/store/reconcile.d.ts +15 -0
  151. package/agent-omp-sdk/dist/store/reconcile.js +51 -0
  152. package/agent-omp-sdk/dist/store/schema.d.ts +8 -0
  153. package/agent-omp-sdk/dist/store/schema.js +40 -0
  154. package/agent-omp-sdk/dist/transport.d.ts +49 -0
  155. package/agent-omp-sdk/dist/transport.js +35 -0
  156. package/agent-omp-sdk/dist/world-home.d.ts +4 -0
  157. package/agent-omp-sdk/dist/world-home.js +23 -0
  158. package/agent-omp-sdk/dist/world-plugin.d.ts +10 -0
  159. package/agent-omp-sdk/dist/world-plugin.js +137 -0
  160. package/agent-omp-sdk/package.json +87 -0
  161. package/client/index.js +1883 -287
  162. package/cordis.patch.yml +80 -0
  163. package/package.json +23 -9
  164. package/superd-hub/dist/a2a-delivery.d.ts +189 -0
  165. package/superd-hub/dist/a2a-delivery.js +240 -0
  166. package/superd-hub/dist/a2a-host.d.ts +76 -0
  167. package/superd-hub/dist/a2a-host.js +145 -0
  168. package/superd-hub/dist/a2a-ingest.d.ts +31 -0
  169. package/superd-hub/dist/a2a-ingest.js +636 -0
  170. package/superd-hub/dist/a2a-log.d.ts +17 -0
  171. package/superd-hub/dist/a2a-log.js +42 -0
  172. package/superd-hub/dist/a2a-row.d.ts +65 -0
  173. package/superd-hub/dist/a2a-row.js +162 -0
  174. package/superd-hub/dist/a2a-service.d.ts +357 -0
  175. package/superd-hub/dist/a2a-service.js +980 -0
  176. package/superd-hub/dist/a2a-wire.d.ts +220 -0
  177. package/superd-hub/dist/a2a-wire.js +305 -0
  178. package/superd-hub/dist/agent-ids.d.ts +10 -0
  179. package/superd-hub/dist/agent-ids.js +68 -0
  180. package/superd-hub/dist/agent-roster.d.ts +29 -18
  181. package/superd-hub/dist/agent-roster.js +54 -15
  182. package/superd-hub/dist/agent-status.d.ts +119 -0
  183. package/superd-hub/dist/agent-status.js +386 -0
  184. package/superd-hub/dist/client/agent-settings.d.ts +210 -0
  185. package/superd-hub/dist/client/agent-settings.js +300 -0
  186. package/superd-hub/dist/client/mesh-api.d.ts +134 -0
  187. package/superd-hub/dist/client/mesh-api.js +219 -0
  188. package/superd-hub/dist/client/mesh-groups.d.ts +63 -0
  189. package/superd-hub/dist/client/mesh-groups.js +66 -0
  190. package/superd-hub/dist/client/roster.d.ts +48 -0
  191. package/superd-hub/dist/client/roster.js +102 -0
  192. package/superd-hub/dist/client/runtime-settings-api.d.ts +76 -0
  193. package/superd-hub/dist/client/runtime-settings-api.js +137 -0
  194. package/superd-hub/dist/client/switch.d.ts +165 -0
  195. package/superd-hub/dist/client/switch.js +295 -0
  196. package/superd-hub/dist/exec-pty-channel.d.ts +58 -0
  197. package/superd-hub/dist/exec-pty-channel.js +162 -0
  198. package/superd-hub/dist/exec-pty-framing.d.ts +32 -0
  199. package/superd-hub/dist/exec-pty-framing.js +81 -0
  200. package/superd-hub/dist/exec-pty-rpc.d.ts +21 -0
  201. package/superd-hub/dist/exec-pty-rpc.js +128 -0
  202. package/superd-hub/dist/exec-pty-session.d.ts +76 -0
  203. package/superd-hub/dist/exec-pty-session.js +234 -0
  204. package/superd-hub/dist/exec.d.ts +56 -0
  205. package/superd-hub/dist/exec.js +225 -0
  206. package/superd-hub/dist/gateway.d.ts +39 -2
  207. package/superd-hub/dist/gateway.js +62 -3
  208. package/superd-hub/dist/hub-tool.d.ts +174 -0
  209. package/superd-hub/dist/hub-tool.js +464 -0
  210. package/superd-hub/dist/index.d.ts +15 -1
  211. package/superd-hub/dist/index.js +16 -0
  212. package/superd-hub/dist/machines.d.ts +45 -0
  213. package/superd-hub/dist/machines.js +125 -0
  214. package/superd-hub/dist/mesh-federate.d.ts +138 -0
  215. package/superd-hub/dist/mesh-federate.js +223 -0
  216. package/superd-hub/dist/mesh-gateway.d.ts +67 -0
  217. package/superd-hub/dist/mesh-gateway.js +408 -0
  218. package/superd-hub/dist/mesh-link.d.ts +274 -0
  219. package/superd-hub/dist/mesh-link.js +441 -0
  220. package/superd-hub/dist/mesh-rpc.d.ts +123 -0
  221. package/superd-hub/dist/mesh-rpc.js +250 -0
  222. package/superd-hub/dist/mux-client.d.ts +71 -0
  223. package/superd-hub/dist/mux-client.js +281 -0
  224. package/superd-hub/dist/pack-version.d.ts +2 -0
  225. package/superd-hub/dist/pack-version.js +30 -0
  226. package/superd-hub/dist/roster.d.ts +6 -0
  227. package/superd-hub/dist/rpc.d.ts +18 -2
  228. package/superd-hub/dist/rpc.js +34 -4
  229. package/superd-hub/dist/spawn-world.js +3 -1
  230. package/superd-hub/dist/switch-core.d.ts +62 -25
  231. package/superd-hub/dist/switch-core.js +53 -30
  232. package/superd-hub/dist/system-head.d.ts +22 -12
  233. package/superd-hub/dist/system-head.js +100 -84
  234. package/superd-hub/dist/wire-endpoints.d.ts +264 -0
  235. package/superd-hub/dist/wire-endpoints.js +180 -0
  236. package/superd-hub/lib/client/index.js +1883 -287
  237. package/superd-hub/package.json +11 -2
  238. package/agent-agy/dist/agent-preset-projection.d.ts +0 -31
  239. package/agent-agy/dist/agent-preset-projection.js +0 -33
  240. package/agent-claude/dist/agent-preset-projection.js +0 -30
  241. package/agent-codex/dist/agent-preset-projection.js +0 -37
  242. package/agent-codex/dist/app-home.js +0 -65
  243. package/agent-codex/dist/models.js +0 -152
  244. package/agent-codex/dist/spike.js +0 -46
  245. package/agent-hermes/dist/agent-preset-projection.js +0 -34
  246. package/agent-omp/dist/agent-preset-projection.js +0 -36
  247. package/agent-omp/dist/app-home.js +0 -86
  248. package/agent-omp/dist/sidecar-client.js +0 -195
  249. package/agent-pi/dist/agent-preset-projection.js +0 -29
  250. package/superd-hub/dist/client-shim.d.ts +0 -28
  251. package/superd-hub/dist/client-shim.js +0 -251
  252. package/superd-hub/dist/index-pass.d.ts +0 -22
  253. package/superd-hub/dist/index-pass.js +0 -47
  254. package/superd-hub/dist/labels.d.ts +0 -45
  255. package/superd-hub/dist/labels.js +0 -83
  256. /package/{agent-agy → agent-agy-sdk}/bridge/agy_bridge.py +0 -0
  257. /package/{agent-agy → agent-agy-sdk}/bridge/gemini_openai_server.mjs +0 -0
  258. /package/{agent-codex/dist/codex-events.js → agent-codex-sdk/dist/codex-sdk-events.js} +0 -0
  259. /package/{agent-omp → agent-omp-sdk}/dist/protocol.js +0 -0
  260. /package/{agent-omp → agent-omp-sdk}/sidecar/main.ts +0 -0
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@pgmi-builds/agent-codex-sdk",
3
+ "version": "0.1.0",
4
+ "description": "Codex (SDK) provider for DeepSeek Harness (dsh) — the OPT-IN in-process SDK transport for the Codex agent: it embeds Codex threads in this Node process instead of driving a `codex app-server` child (that is @pgmi-builds/agent-codex, the PRIMARY path, because it reuses the operator's own codex binary). Delivered DISABLED by default (world key `codex-sdk`, roster label \"Codex (SDK)\"); turning the composite row on IS the switch. This package declares NO SDK dependency — not a dependency, not an optionalDependency and not a peer — and ships NO postinstall: the durable SDK tree (the codex SDK package plus the pinned codex binary package) is fetched into the world home on the first real prompt (src/sdk-runtime.ts, `npm run fetch-sdk-runtime`).",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": "./dist/index.js",
8
+ "./world": "./dist/world-plugin.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "scripts",
13
+ "cordis.patch.yml",
14
+ "README.md"
15
+ ],
16
+ "dsh": {
17
+ "bundle": {
18
+ "patch": "./cordis.patch.yml"
19
+ }
20
+ },
21
+ "scripts": {
22
+ "build": "tsc -p tsconfig.json",
23
+ "test": "node --test test/*.test.mjs",
24
+ "fetch-sdk-runtime": "node scripts/fetch-sdk-runtime.mjs"
25
+ },
26
+ "dependencies": {},
27
+ "peerDependencies": {
28
+ "@deepseek-ai/cordis": "^4.0.1",
29
+ "@deepseek-ai/dsh-agent": ">=0.1.5-0 <0.3.0-0",
30
+ "@deepseek-ai/dsh-agent-presets": ">=0.1.5-0 <0.3.0-0",
31
+ "@deepseek-ai/dsh-llm": ">=0.1.5-0 <0.3.0-0",
32
+ "@deepseek-ai/dsh-scope": ">=0.1.5-0 <0.3.0-0",
33
+ "@deepseek-ai/dsh-session": ">=0.1.5-0 <0.3.0-0",
34
+ "@deepseek-ai/dsh-session-persistence": ">=0.1.5-0 <0.3.0-0",
35
+ "@deepseek-ai/dsh-typert-protocol": ">=0.1.5-0 <0.3.0-0",
36
+ "@pgmi-builds/superd-hub": "*"
37
+ },
38
+ "peerDependenciesMeta": {
39
+ "@deepseek-ai/cordis": {
40
+ "optional": true
41
+ },
42
+ "@deepseek-ai/dsh-agent": {
43
+ "optional": true
44
+ },
45
+ "@deepseek-ai/dsh-agent-presets": {
46
+ "optional": true
47
+ },
48
+ "@deepseek-ai/dsh-llm": {
49
+ "optional": true
50
+ },
51
+ "@deepseek-ai/dsh-scope": {
52
+ "optional": true
53
+ },
54
+ "@deepseek-ai/dsh-session": {
55
+ "optional": true
56
+ },
57
+ "@deepseek-ai/dsh-session-persistence": {
58
+ "optional": true
59
+ },
60
+ "@deepseek-ai/dsh-typert-protocol": {
61
+ "optional": true
62
+ },
63
+ "@pgmi-builds/superd-hub": {
64
+ "optional": true
65
+ }
66
+ },
67
+ "devDependencies": {
68
+ "@types/node": "^26.2.0",
69
+ "typescript": "^5.6.0"
70
+ },
71
+ "publishConfig": {
72
+ "access": "public"
73
+ },
74
+ "license": "MIT",
75
+ "main": "dist/index.js",
76
+ "engines": {
77
+ "node": ">=22.18"
78
+ }
79
+ }
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * fetch-sdk-runtime.mjs — eagerly warm the durable SDK runtime for a world home.
4
+ *
5
+ * The adapter fetches this runtime lazily on the first real prompt
6
+ * (src/sdk-runtime.ts); this script exists for the two cases where waiting for
7
+ * a first turn is unacceptable: pre-provisioning a machine, and recovering from
8
+ * a recorded failure (`<worldHome>/sdk-runtime.error.log`).
9
+ *
10
+ * node scripts/fetch-sdk-runtime.mjs [<home>]
11
+ *
12
+ * `<home>` is the DSH/SUPERD home (default: `$DSH_HOME`, then
13
+ * `$SUPERD_HOME_DIR`); the world home is `<home>/agents/codex-sdk`, exactly
14
+ * what the world plugin provisions (world key `codex-sdk`). There is
15
+ * deliberately NO default to `~/.dsh`: this is a dev/test tool and it refuses
16
+ * any home outside this repository's `.tests` tree — the same red line the
17
+ * launcher enforces (repo AGENTS §〇).
18
+ *
19
+ * Idempotent: a complete, matching runtime short-circuits (no network, no npm).
20
+ */
21
+ import { dirname, resolve, sep } from "node:path";
22
+ import { fileURLToPath } from "node:url";
23
+ import { createSdkRuntimeDeps, ensureSdkRuntime, sdkRuntimeLayout } from "../dist/sdk-runtime.js";
24
+
25
+ const here = dirname(fileURLToPath(import.meta.url));
26
+ const pluginDir = resolve(here, "..");
27
+ const repoRoot = resolve(pluginDir, "..", "..");
28
+ const testsRoot = resolve(repoRoot, ".tests");
29
+
30
+ const home = process.argv[2] ?? process.env.DSH_HOME ?? process.env.SUPERD_HOME_DIR;
31
+ if (home === undefined || home === "") {
32
+ console.error(
33
+ "refusing: pass a DSH home as argv[2] or set DSH_HOME / SUPERD_HOME_DIR " +
34
+ "(no default — ~/.dsh is a prod home)",
35
+ );
36
+ process.exit(2);
37
+ }
38
+ const dshHome = resolve(home);
39
+ if (dshHome !== testsRoot && !dshHome.startsWith(testsRoot + sep)) {
40
+ console.error(`refusing: DSH home ${dshHome} is outside ${testsRoot} (repo red line)`);
41
+ process.exit(1);
42
+ }
43
+ const worldHome = resolve(dshHome, "agents", "codex-sdk");
44
+
45
+ try {
46
+ // ONE implementation shared with the adapter's first-prompt fetch: the
47
+ // builder lives in the module, so this script cannot drift from it.
48
+ const record = await ensureSdkRuntime(worldHome, createSdkRuntimeDeps(pluginDir));
49
+ console.log(JSON.stringify(record, null, 2));
50
+ if (process.env.VERBOSE === "1") {
51
+ console.log(`layout: ${JSON.stringify(sdkRuntimeLayout(worldHome), null, 2)}`);
52
+ }
53
+ } catch (error) {
54
+ // ensureSdkRuntime already wrote the durable trace; add the operator-facing line.
55
+ console.error(String(error instanceof Error ? error.message : error));
56
+ process.exit(1);
57
+ }
@@ -1,77 +1,94 @@
1
- # @pgmi-builds/agent-omp(OMP adapter,SDK 线)
1
+ # @pgmi-builds/agent-omp(OMP adapter,RPC 线)
2
2
 
3
- OMP Web 的 SDK 线:**衔接层(DSH 契约/术语/类形状)沿用 `apps/omp-web` 现行源码,内核从 `omp --mode rpc` 子进程换成 `@oh-my-pi/pi-coding-agent` SDK**。数据面目标 = `docs/plans/sdk-data-surface-assessment.md` 的 A1–A8 / S1–S10。
3
+ OMP provider for DeepSeek Harness([dsh](https://www.npmjs.com/package/@deepseek-ai/dsh))。
4
4
 
5
- ## 集成形态(承 sdk-direction §3 裁决 (a))
5
+ **不内嵌任何 OMP 代码副本**:适配器用操作员本机已在用的 `omp` binary,以 `omp --mode rpc` 子进程形态驱动,
6
+ stdio 上跑 OMP 的 NDJSON 协议(v1),把 OMP 的 RPC 面(prompt / follow_up / steer / abort / get_state /
7
+ get_messages / set_model / resume / compact)桥接进 Dash 的 Agent/Session 契约,标准 DSH Web UI 即可驱动 OMP 会话。
8
+ 模型选择由 OMP 数据面的 `LlmAdapter` 承接(`config.yml` 的 `modelRoles`)。
9
+
10
+ ## 集成形态
6
11
 
7
12
  ```
8
- dsh 宿主 (Node 22, 本包 dist/) Bun sidecar (本包 sidecar/)
9
- omp-web 衔接层(agent/adapter/ ←→ createAgentSession / ModelRegistry /
10
- replay/store/supervisor 移植) Settings / SessionManager / discover*
13
+ dsh 宿主 (Node 22, 本包 dist/) 操作员本机的 omp binary
14
+ omp-web 衔接层(agent/adapter/ ←→ `omp --mode rpc`(NDJSON v1 over stdio)
15
+ replay/store/supervisor) ~/.omp 是其唯一的 app home
11
16
  ```
12
17
 
13
- - dsh 进程树保持纯 Node;SDK 只活在 sidecar 进程(bun run)。
14
- - 协议不再是 omp 的 rpc 面,而是**自有 sidecar 协议**:在数据流等价(prompt/steer/followUp/abort/事件流)之上,新增 app 层命令(settings 读写、auth/provider 状态、模型注册表、session list/open/fork、system prompt、custom message / messages 手术、compact)——即把 A/S 清单映射成方法表。
18
+ - **没有 sidecar,没有 Bun,没有 SDK 依赖**:一会话一 `omp --mode rpc` 子进程,进程生命周期跟随会话。
19
+ - **binary 解析**(`src/rpc-client.ts` 的 `resolveOmpExecutable()`):
20
+ `$OMP_EXECUTABLE` → `PATH` 上的 `omp` → `~/.local/bin/omp` / `/usr/local/bin/omp` → 裸 `"omp"`(让 spawn 报 ENOENT)。
21
+ - **进程组隔离**:子进程 `detached` 自成进程组,teardown 走 SIGTERM + 2s 宽限后 SIGKILL,保证 `omp` 及其工具子进程不残留。
22
+
23
+ ## 安装与启用
15
24
 
16
- ## Spike 实测记录(2026-09-09,SDK 18.1.14 + bun 1.4.2)
25
+ 本包是 `super-dsh` 单一交付包内的兄弟目录,**不单独安装**(`dsh plugin --profile <name> add super-dsh`),
26
+ 也不需要预装任何 OMP SDK。唯一的外部前置条件 = **操作员机器上有 `omp`**:
17
27
 
18
- - 安装:`npm i @oh-my-pi/pi-coding-agent`(main 直指 `./src/index.ts`,无需构建步骤)+ devDep `bun`(node_modules 内二进制,不装全局)。
19
- - 根 exports 619 个。桥关心的全部在位:`createAgentSession` `AgentSession` `SessionManager(.create/.open/.continueRecent/.inMemory/.list/.listAll/.forkFrom)` `Settings(.init/.isolated/.loadReadOnly)` `ModelRegistry` `AuthStorage` `discoverAuthStorage` `AgentRegistry` `createSessionManager` `listSessions` `listAllSessions` `loadSessionMessagesReadOnly` `discoverSkills/SlashCommands/Extensions/ContextFiles/PromptTemplates` `buildSystemPrompt` `createCustomMessage` `wrapSteeringForModel` `expandPromptTemplate`。
20
- - **pi 文档 vs omp 实现**:`createAgentSessionRuntime`/`ModelRuntime`/`DefaultResourceLoader`/`SettingsManager`/`defineTool`/`createEventBus` 不在 omp 根 exports——对应能力由 `AgentSession` 实例面与 `Settings`/`discover*` 家族承担。评估文档中标 [pi] 的条目按此折算。
21
- - **`AgentSession` 实例面远超 pi 文档**:`state{systemPrompt,model,thinkingLevel,tools,messages,isStreaming,streamMessage,pendingToolCalls,error}`、`messages`、`systemPrompt`、`prompt`/`promptCustomMessage`/`sendCustomMessage`/`sendUserMessage`、`steer`/`followUp`、`setModel`/`cycleModel`/`applyRoleModel`、`compact`/`abortCompaction`、`switchSession`/`branch`/`navigateTree`/`fork`/`handoff`、`newSession`/`moveSession`、`abort`、`beginDispose`/`dispose`。S1/S2/S3/S6/S7/S8/S10 均有一等 API;S5(messages 手术)通道结构性在位(`state` 暴露 messages/tools 键),赋值语义待 TS 类型面确认。
22
- - **真机冒烟**:`OMP_HOME=~/.omp` 下 `discoverAuthStorage`+`ModelRegistry.refresh()` 得 50 模型 / 5 provider(deepseek,xai,bailian,kimi-plan,zai-plan)——与 `omp models --json` 完全一致;`SessionManager.inMemory()` 建会话成功、dispose 干净、零 LLM 调用。
23
- - **沙箱注意**:SDK 以读写模式打开 `~/.omp/agent/agent.db`;agent 沙箱内跑 sidecar/spike 需要对该库的写权限(本轮以 danger-full-access 实测通过)。
28
+ - 缺失时不静默回落:adapter 在 `apply()` 做一次二进制可解析性探测并打显式诊断,首轮 prompt 以 spawn 错误 fail loud 冒到会话。
29
+ - 启用由包内 `cordis.patch.yml` 承担(挂 OMP provider + 禁用原生 agent-loop / llm 路由),profile 无需手改。
24
30
 
25
- ## 下一步(M2 → M3 收敛)
31
+ ## Home 布局(两个 home,别混)
26
32
 
27
- 1. sidecar 骨架:bun 入口 + 方法表协议(JSON lines over stdio)+ 生命周期(spawn/健康检查/退出)。
28
- 2. 移植衔接层:从 `apps/omp-web/src` 拷 `agent.ts`/`adapter.ts`/`replay.ts`/`session-persistence-omp.ts`/`store/`,把 `rpc.ts` 调用点逐个改打 sidecar 协议;`omp-cli.ts` 的 models/config 面改走 SDK(A1/A3)。
29
- 3. S5 spike:`state.messages` 注入 toolResult + 真 turn 验证 journal 落盘。
30
- 4. 会话所有权对齐:SDK 写 OMP session store 后与 bridge-store/supervisor/TUI 的三方避让(dev_0.0.3 §9 过一遍)。
33
+ | 名字 | 是什么 | 定义(`src/knobs.ts`) | 默认 |
34
+ |---|---|---|---|
35
+ | **`OMP_HOME`** | OMP runtime app home(`agent.db`/`models.db`/`sessions/` 的写入目标,也是数据面子进程的 cwd) | `$OMP_HOME ?? resolveOmpNativeHome()` | **原生 `~/.omp`**(`$OMP_HOME` 只作测试 / 适配器级隔离 knob) |
36
+ | **`OMP_NATIVE_HOME`** | 操作员的原生 OMP 安装(TUI/CLI)读面:`agent/config.yml`、`agent/models.yml`、原生 session store | `$OMP_NATIVE_HOME ?? join(homedir(), ".omp")` | `~/.omp` |
37
+ | `<DSH_HOME>/agents/omp/` | 该 world 的 **DSH** home(DSH 会话日志、storages、settings) | dsh 宿主解析 | 非 app home |
31
38
 
32
- ## As-built:sidecar 骨架(2026-09-09,已完成 ✅)
39
+ - spawn **零重定向**:不把 `OMP_HOME` 喂给子进程;`~/.omp` 是唯一 OMP app home。
40
+ - 绝不要把 `OMP_NATIVE_HOME` 指到空目录 / 测试 home——它是 models.yml 的读取来源,读空 ⇒ 适配器零 provider ⇒ `session/prompt` 报 `model-unavailable`。
33
41
 
34
- - `sidecar/main.ts`(bun 入口):ready 握手 + JSON-lines 请求/响应/事件三帧协议;app 级共享单例 `authStorage`/`modelRegistry`;session 池(create/dispose/事件转发)。
35
- - `src/protocol.ts`:协议与方法表类型(sys.ping / models.list / settings.get / session.create|info|prompt|steer|followUp|abort|dispose / sessions.list)。
36
- - `src/sidecar-client.ts`:Node 侧 spawn/关联/事件分发/优雅关停;`src/index.ts` 暂导出 client。
37
- - ~~冒烟 `test/sidecar-smoke.test.mjs`~~(2026-09-24 场景退役删除;整包验证走 superd 的 4999 pack 线 + dev3)。
38
- - 坑已修:`ModelRegistry.refreshInBackground()` 此版本返回 void(非 Promise),可选链后接 `.catch` 会炸;ready-timeout 定时器必须 clear 否则 Node 进程挂 60s。
42
+ ## 数据面(`omp` 子进程)
39
43
 
40
- ## As-built:衔接层移植(2026-09-09,已完成 ✅)
44
+ `src/omp-cli.ts` 把操作员 binary 作为模型目录与 `modelRoles` 的**第一源**(不吃 RPC 帧);原生 `~/.omp` 的文件只作失败回落与排序读面:
41
45
 
42
- - `src/rpc-types.ts`:从 omp-web `rpc.ts` 提取的 OMP wire 类型(verbatim),两条线共用同一载荷形状。
43
- - `src/sdk-client.ts`:**`OmpSdkClient`——与 `OmpRpcClient` 同公共面**(on/onFailure/sendRaw/send/getState/getMessages/getSessionStats/getSubagents/prompt/followUp/steer/setModel/abort/newSession/close),底层复用单个共享 sidecar(模块级单例 + 引用计数,refcount 归零自动关停)。spawn args 解析 `--approval-mode`(yolo→autoApprove)与 `--resume`;未知 flag fail-loud。
44
- - 衔接层整体移植(与 omp-web 逐字节同源,仅换接缝):`agent.ts` `adapter.ts` `index.ts` `models.ts` `knobs.ts` `pairing.ts` `permission.ts` `replay.ts` `session-persistence-omp.ts` `supervisor.ts` `omp-store.ts` `agent-preset-omp.ts` `omp-cli.ts` `store/`。
45
- - sidecar 升级:session handle 化(`newSession` 换 OMP session id 但 handle 稳定);补齐 `session.state/messages/stats/subagents/setModel/new`;`getSessionStats` 实测返回 contextUsage(contextWindow 1000000)。
46
- - 测试:omp-web 单测四件(content-detection/omp-store/replay/store)+ sidecar 冒烟 + sdk-client 集成 = **20/20 绿,3.6s**;tsc 0 错。
47
- - 本地 dev fixture:`node_modules/@deepseek-ai/*` symlink 至真实 dsh 安装(照 omp-web 惯例,node_modules 不入库)。
46
+ - `omp models --json` → 凭证解析后的可用模型目录(含 agent.db 里的 OAuth/login key 等配置面看不见的凭证);子进程失败才回落磁盘 `models.db` ∪ `models.yml`(并打 stderr 提示)。
47
+ - `omp config get modelRoles --json` → role → `"provider/model[:effort]"` 映射(含持久化的 `default` 选择),每次现读。
48
+ - `omp config set modelRoles --json <obj>` → 整对象回写(拒绝点号 key),OMP 自己持久化 `modelRoles.default`。
49
+ - provider 排序与 boot 期默认模型仍首选 `agent/config.yml` 磁盘读(`omp-store.ts` 的 mini-YAML 扫描),`ompModelRolesSync` 兜底。
50
+ - 每次调用都按 `resolveOmpExecutable()` 现解析、`cwd = OMP_HOME`;**fail-soft**:binary 缺失/损坏/无响应 → 读 `undefined`、写 `false`,provider 永因 CLI 挂掉而 boot 失败。
48
51
 
49
- ### 已知差异(SDK 线 vs RPC 线,待办)
52
+ ## 实现要点
50
53
 
51
- - `extension_ui_response`(审批卡应答)在 SDK 线暂为 no-op:SDK 侧审批走 `autoApprove`/approval 事件,卡片化审批的等价通道待接。
52
- - `getSubagents` 暂返回 `[]`(SDK 的 subagent registry 暴露面待查)。
53
- - 未跑 4999 全链路(dsh 宿主内 provider 挂载)——下一步。
54
+ - **传输**:`src/rpc-client.ts` 的 `OmpRpcClient` —— NDJSON 读取(按 `\n` 切帧)、`ready` 握手(默认 120s 上限,`OMP_READY_TIMEOUT_MS`)、
55
+ per-command 响应 deadline(默认 30s,`OMP_COMMAND_TIMEOUT_MS`)、`on`/`onTitle`/`onFailure` 事件分发。
56
+ - **不协商协议**:不发 `negotiate_protocol`,停在 v1 = 纯 NDJSON(旧读取器即正确)。协商到 v2 会切换到 >1MiB 分帧,需要重组器——列为已知 gap。
57
+ - **lazy 铁律**:`src/lazy-rpc.ts` 的 `LazyOmpRpc` 是唯一 spawn 点,构造零 spawn;`prompt`/`followUp`/`steer`/`ensureStarted` 才拉起子进程,
58
+ 被动查询(`getState`/`getSubagents`/`getSessionStats`/`getSystemPrompt`/`abort`/`sendRaw`)合成应答、绝不 spawn。
59
+ `createAgent` 与 `resume` 两条路径都走它(resume 有映射时加 `--resume <ompFile>`),生成参数 `--approval-mode <mode>`。
60
+ - **两平面**:dsh 原生 session log 是 WebUI 唯一读面(插件当 producer:OMP RPC 事件 → SessionEvent → `ctx.sessionPersistence`);
61
+ OMP 原生会话文件是 runtime 权威(插件当 bridge:`bridge-store.sqlite` 只存 dsh↔omp 映射)。双份存储显式接受,单向阀 = 不回读。
62
+ - **已删除面**(本 RPC 轮,2026-10-03):`src/sdk-client.ts`、`src/sidecar-client.ts`、`src/protocol.ts`、`sidecar/`,以及 SDK/Bun 依赖与 `test/sidecar-*.test.mjs`;`scripts/build-client.ts` 与 `src/client/`、`src/mobile/` 保留(client 半边与 sidecar 无关)。
54
63
 
55
- ## As-built:4999 全链路冒烟(2026-09-09,PASS ✅)
64
+ ## 协议与实测记录(2026-10-03)
56
65
 
57
- - test profile `omp-web-test` 切换 dep 至 `link:…/apps/omp-web`(bundle 位同步换 `@pgmi-builds/omp-web`,patch 语义同 omp-web:mount omp-provider + 禁 agent-loop/llm 路由/agent-presets)。
58
- - systemd-run `omp-web-4999-test`(DSH_HOME=~/.omp/omp-web、OMP_HOME=~/.omp、port 4999)拉起全局 dsh 0.1.3-alpha.2,unit active。
59
- - 验证链:auth 200 → `session/create` ok → **dsh 进程树内 1 个共享 bun sidecar** → `session/prompt`(mode:queue + requestId,typert request 形状)accepted → `session/page`(`records[].event`,`throughSeq ≤ cursor`)回读:turn/start、user/message、2×step(reasoning + `think` 工具调用 + tool/result)、assistant/message(text "sdk-line-alive",xai/grok-4.6,含 stream chunks)、turn/end。
60
- - wire 备忘:`session/prompt` 必填 `requestId`/`mode`/`content`;`session/page` 用 `args.request`(非 `_request`),`address:{kind:"session",sessionId}` + `throughSeq` 超 cursor 直接报错并回吐当前 cursor。
66
+ `ready` 帧实测:
67
+
68
+ ```json
69
+ {"type":"ready","protocolVersion":1,"supportedProtocolVersions":[1,2],
70
+ "maxFrameBytes":1048576,"maxReassembledFrameBytes":67108864}
71
+ ```
61
72
 
62
- ## As-built:四阶段增强(2026-09-09,全部 doer(v4-pro)+verify 双签 PASS ✅)
73
+ - 只要求 `type === "ready"`;`protocolVersion` / `supportedProtocolVersions` / `maxFrameBytes` / `maxReassembledFrameBytes` 记录不校验。
74
+ - 不协商的路径实测停在 v1;`get_state` / `get_available_models` 未协商也照常应答;事件词表
75
+ (`agent_start` / `turn_start` / `message_start` / `message_update` / `message_end` / `tool_execution_start` / `tool_execution_end` / `turn_end` / `agent_end`)与 `agent.ts` 的 switch 对齐。
76
+ - 已知 gap:v2 分帧未实现(单帧 >1MiB 靠大行承载);对 `omp` 版本门仅实测 v18.4.9。
77
+
78
+ ## 测试
79
+
80
+ ```bash
81
+ npm run build # tsc -p tsconfig.json && tsc -p tsconfig.client.json
82
+ node --test test/*.test.mjs # 全 fakes / 源级断言,零真 runtime、零真 omp spawn
83
+ ```
63
84
 
64
- - **P1 `7e44412`** preset 槽位:桥自供 `agentPresets` typert remote(服务 key==wire namespace==ctx.remote.agentPresets),roster 恰一条 `omp`/`OMP`/isDefault;copy/delete 报 `agent-preset/read-only`,未知 id 报 `not-found`。关键:注册必须挂顶层 fiber(嵌套 ctx.plugin 会 404)。4999 wire 实测单条 OMP 行。
65
- - **P2 `fee6406`** system prompt → UI:`request/header.data.header.system`(EpochHeader.system)即 UI System-prompt 行的数据源。sidecar 加 `session.systemPrompt`(live,refreshBaseSystemPrompt 后 38807 字符)与 `session.systemPrompt.forFile`(冷会话 throwaway 渲染,dispose 前 releaseRetainedEntries 抑制 session_exit 落盘,实测只读)。replay/cold-shadow/open 注入;live turn 不合成 header(无 per-turn 成本)。已知 gap:live 会话要到 replay 路径才显示 System prompt 行。
66
- - **P3 `8e9f21d`** settings/models 切 sidecar:`settings.modelRoles.get/set`(set 带 flush→loadReadOnly→deepEquals 读回校验,shadow-key 只在真实落盘后推进;echo roundtrip 实测 config.yml SHA 不变)+ 富化 `models.list`(12 键与 normalizeModel 逐一对照)。omp-cli 四导出改缓存+异步暖缓存语义,Sync 变体冷启动 undefined→on-disk 回退。4999 实测 modelCatalog 5 provider 全量。
67
- - **P3.1 `e4db900`** EPIPE 加固(verify 发现的历史崩溃):child stdin 永久 no-op error sink + `#writeSafe` per-write 降级——sidecar 死亡从崩宿主变为拒绝当次调用。
68
- - **P4 `97cbc7b`** JSONL 解析切 SDK:`sessions.listAll` 一次全库索引(147 会话 26ms;id/cwd/size 0 diff,20 处 title 差异经实证为 SDK 当前 title slot 更正确)+ `sessions.messagesReadOnly` 按需 transcript(compaction 折叠语义);自研解析保留为 fail-soft fallback;顺带修了 `sessions.list {all:true}` 恒 0 的旧 bug。supervisor 热路径保留 naive 防游标错位。
69
- - 总验收:29/29 测试、4999 wire 三连(roster 单条 OMP / session list 147 / modelCatalog)、实例留 4999 供手动验收。
70
- - 遗留(低):forFile 对个别大文件 "Agent Main was replaced"(~1/tick,fail-soft);SDK 元数据快照滞后一个 tick;`sessions.messagesReadOnly` 大文件双读。
85
+ - `test/no-sidecar.test.mjs` = RPC 轮的删除面 + tick 门双重把守(源级断言:`src/` 不得再出现 SDK/sidecar client;
86
+ `index.ts` 只能 `new LazyOmpRpc(`;tick 的目录刷新必须挂在 `liveOmpSessionExists` 上,并对编译后的 `dist/index.js` 跑行为真值表)。
87
+ - `rpc-client` / `lazy-rpc` / `omp-cli-rpc` / `resolve-executable` / `package-contract` 覆盖传输、lazy 不变量、数据面与交付清单。
88
+ - **场景级验证只走整包**:`super-dsh` 的 4999 pack 线(`test/start-4999.sh`)+ dev3 目标机实装;本目录不再有 per-agent 场景 rig。
71
89
 
72
- ## As-built:P1.1 修复 + P5 mobile 包(2026-09-09)
90
+ ## 历史
73
91
 
74
- - **P1.1 `434f046`**("no omp mode" 根因修复):P1 的 roster 服务 200 但 chip 仍不显示——UI 的 preset chip 门控在 `session.projectionValues.agentPreset` 上,该投影原本由(被我们禁用的)dsh-agent-presets 宿主半驱动。桥现在自己注册同一 fold(`ctx.inject(['sessionProjections'])` + `agent-preset/selected` 事件推进),headless 截图确认 hero 行渲染 `OMP ˅` chip。配套 vendored `dsh-session-projection` 类型(父 repo)。
75
- - **P5 `29b043b`**(dashr mobile 包移植,本插件首个 client 半):`src/mobile/`(gesture/zoom-guard/client)+ `src/client/index.ts` 入口 + `scripts/build-client.ts`(tsdown 闭包工厂 → `lib/client/index.js`,id=包名)+ host 半 `src/mobile-boot.ts`(`window.__OMP_WEB_MOBILE__` + iOS zoom-guard 经 webserver/index-inject)。`dsh.client` manifest inject 只挂 ui-layout。测试 41/41。
76
- - **P5 视觉验证**(5199 实测,4999 当时被 superd 的 ui-preact 实例占用):桌面回归 OK(OMP chip 在);390x844 断点折叠(rail→0px、无横向滚动);全局注入 OK;边缘滑动手势开关侧栏实测通过;截图证据 `.scratch/p5-verify/`。
77
- - 遗留:移动端侧栏为 push-drawer 语义(打开时内容窗格被压窄,与 dashr 原行为一致);`npm install` 会剪掉 `node_modules/@deepseek-ai` symlink(需重挂);4999 端口与 superd 测试线冲突时用 `--patch` overlay 换端口。
92
+ 本包在 2026-10-03 前是内嵌 SDK + Bun 子进程(sidecar)线(SDK 事件 → SessionEvent,单进程多路复用);该线连同
93
+ 762M SDK 树 + 76M bun 二进制一起从交付面删除,改用操作员本机 binary 的 RPC 传输(设计正本:
94
+ `docs/specs/omp-rpc-transport/spec.md`)。
@@ -2,6 +2,7 @@ import { agentEvents } from "@deepseek-ai/dsh-agent";
2
2
  import { Inbox } from "./inbox.js";
3
3
  import { LlmAttemptId, ToolCallId, QUOTA_EXCEEDED_CODE, createAssistantMessage, createSystemMessage, createToolResultMessage, createUserMessage } from "@deepseek-ai/dsh-llm";
4
4
  import { createScope } from "@deepseek-ai/dsh-scope";
5
+ import { ompPermissionCommand } from "./permission.js";
5
6
  import { getBridgeStore } from "./store/index.js";
6
7
  import { withSystemHead } from "../../superd-hub/dist/index.js";
7
8
  /**
@@ -312,20 +313,20 @@ export class OmpAgent {
312
313
  // so a freshly created session announces completely blank, exactly like
313
314
  // the native agent-loop factory's: the backend takes zero part in the
314
315
  // UI's browser-local new-session draft.
315
- // `/permission` cannot work here: OMP pins `--approval-mode` at launch and
316
- // no RPC changes it mid-session. Registering the SAME name on this agent's
317
- // own scope (a command-injected child of `agent.ctx`) SHADOWS the global
318
- // permission command for this agent only — the switch then fails cleanly
319
- // instead of appending approval/policy events OMP cannot honor. (The
320
- // `inject` narration drop below stays as the backstop.)
316
+ // `/permission` — a launch fact, so the shadow routes it by child state:
317
+ // OMP pins `--approval-mode` at spawn and no RPC moves it mid-session, so
318
+ // an accepted switch only exists while this session's child does NOT. This
319
+ // agent-scoped registration (a child of `agent.ctx`) shadows the global
320
+ // command; before the first prompt it writes the same durable preset the
321
+ // global handler would (`permissionPresets.set`, no live-agent narration),
322
+ // and afterwards it refuses instead of appending a preset the running
323
+ // `omp` cannot honor. The spawn reads exactly those events
324
+ // (`resolveSpawnPermission`), so the pick reaches the child's argv.
321
325
  this.ctx.inject(["commands"], (cmdCtx) => cmdCtx.commands.register({
322
326
  name: "permission",
323
- description: "Unavailable for OMP sessions (approval policy is fixed at OMP launch)",
327
+ description: "Switch the permission preset (takes effect at the OMP child's launch)",
324
328
  input: { hint: "<preset>" },
325
- handler: () => ({
326
- kind: "error",
327
- text: "Approval policy is fixed at OMP launch; runtime switching is not supported for OMP sessions.",
328
- }),
329
+ handler: (invocation) => this.#handlePermissionCommand(invocation.rawInput),
329
330
  }));
330
331
  // `/compact` parity (route 1): OMP owns context compaction — the Dash log
331
332
  // is only the UI's scrollback projection, so no compaction/* events are
@@ -522,6 +523,30 @@ export class OmpAgent {
522
523
  }
523
524
  }
524
525
  }
526
+ /**
527
+ * `/permission` handler: mirror the global command's write for a session whose
528
+ * `omp` child does not exist yet (the pick then lands in the launch flag via
529
+ * {@link resolveSpawnPermission}), and refuse it once the child does — the
530
+ * policy is a launch flag, so accepting later would desync UI from runtime.
531
+ * Uses `permissionPresets.set` (log-only preset + knob events) rather than the
532
+ * global handler's `approval.setPolicy`, which would inject a narration user
533
+ * message into the OMP session for a change OMP never sees.
534
+ */
535
+ #handlePermissionCommand(rawInput) {
536
+ const presets = this.#loopCtx.get("permissionPresets");
537
+ if (presets === undefined) {
538
+ return { kind: "error", text: "permission presets are not available on this host" };
539
+ }
540
+ const decision = ompPermissionCommand({
541
+ rawInput,
542
+ spawned: this.#rpc.spawned,
543
+ names: presets.names,
544
+ current: presets.current(this.session),
545
+ });
546
+ if (decision.action === "apply")
547
+ presets.set(this.session, decision.preset);
548
+ return decision.result;
549
+ }
525
550
  /**
526
551
  * /compact handler (route 1): run OMP's own compaction on the live child
527
552
  * and report its real metering as the command outcome. No compaction/*