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,402 @@
1
+ /**
2
+ * codex-provider-gateway.ts — the adapter-owned Remote behind the Hub's Codex
3
+ * settings panel (2026-10-03 user ruling; reworked 2026-10-04).
4
+ *
5
+ * Why a Remote and not a hub route: the provider list is ADAPTER config
6
+ * (dev-rules §12), so the adapter owns it and the hub only forwards.
7
+ * `TypertRemoteService` + `@Remote` is the whole mechanism — standard (TC39)
8
+ * method decorators recorded on the class prototype, read back at dispatch time
9
+ * by the gateway's source-claim scan. No codegen, no compiler-injected metadata,
10
+ * which is why a plain `tsc` adapter build can ship one.
11
+ *
12
+ * Wire contract (`superd-hub/src/client/runtime-settings-api.ts` builds each
13
+ * envelope; the hub carrier forwards `envelope.method` verbatim):
14
+ *
15
+ * request POST /hub/api?agent=codex
16
+ * { type:'client-request', rpcId, method:'codexProviders/<op>',
17
+ * payload: { args: { request?: … } } }
18
+ * response { type:'server-response', rpcId, result:{ ok:true, value:<view> } }
19
+ *
20
+ * There is no `select`: which provider a SESSION runs on is DSH's own
21
+ * per-session `model/selection`, chosen from the harness's model selector. This
22
+ * panel is a list editor — add, edit, remove — plus the reconcile with the
23
+ * user's `config.toml` that {@link syncFromNative} performs.
24
+ *
25
+ * The class is a delegation shell on purpose: every operation is a plain
26
+ * function over (worldHome, codexHome), so the entire contract — the key
27
+ * privacy rule, the validation, the sync, the view projection — is pinnable
28
+ * under `node --test` with no Cordis Context and no real home.
29
+ *
30
+ * @module agent-codex/codex-provider-gateway
31
+ */
32
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
33
+ var useValue = arguments.length > 2;
34
+ for (var i = 0; i < initializers.length; i++) {
35
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
36
+ }
37
+ return useValue ? value : void 0;
38
+ };
39
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
40
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
41
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
42
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
43
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
44
+ var _, done = false;
45
+ for (var i = decorators.length - 1; i >= 0; i--) {
46
+ var context = {};
47
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
48
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
49
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
50
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
51
+ if (kind === "accessor") {
52
+ if (result === void 0) continue;
53
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
54
+ if (_ = accept(result.get)) descriptor.get = _;
55
+ if (_ = accept(result.set)) descriptor.set = _;
56
+ if (_ = accept(result.init)) initializers.unshift(_);
57
+ }
58
+ else if (_ = accept(result)) {
59
+ if (kind === "field") initializers.unshift(_);
60
+ else descriptor[key] = _;
61
+ }
62
+ }
63
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
64
+ done = true;
65
+ };
66
+ import { Remote, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
67
+ import { isProviderId, isWireProtocol, providerStorePath, readProviderStore, removeProvider, syncNativeProviders, upsertProvider, writeProviderStore, } from "./codex-providers.js";
68
+ import { providerCatalogDir, readNativeProviders, readNativeSelection, } from "./codex-native-config.js";
69
+ import { readFileSync } from "node:fs";
70
+ import { join } from "node:path";
71
+ /**
72
+ * Both protocols are advertised, because the user asked for that dropdown — and
73
+ * because a user arriving from cc-switch has seen exactly these two options
74
+ * there. `chat` is rendered but not selectable: codex 0.154 refuses it at config
75
+ * load, and the hint is the binary's own sentence rather than our paraphrase.
76
+ */
77
+ export const PROTOCOL_OPTIONS = [
78
+ {
79
+ value: "responses",
80
+ label: "Responses API",
81
+ available: true,
82
+ hint: "Codex's native wire protocol — the only one 0.154 accepts.",
83
+ },
84
+ {
85
+ value: "chat",
86
+ label: "Chat Completions",
87
+ available: false,
88
+ hint: '`wire_api = "chat"` is no longer supported.\nHow to fix: set `wire_api = "responses"` in your provider config.',
89
+ },
90
+ ];
91
+ function isRecord(value) {
92
+ return value !== null && typeof value === "object" && !Array.isArray(value);
93
+ }
94
+ function nonEmpty(value) {
95
+ return typeof value === "string" && value.trim() !== "" ? value : undefined;
96
+ }
97
+ /** Whether the runtime's own auth.json already holds a key (never read out). */
98
+ function authJsonHasKey(codexHome) {
99
+ try {
100
+ const parsed = JSON.parse(readFileSync(join(codexHome, "auth.json"), "utf8"));
101
+ return isRecord(parsed) && nonEmpty(parsed["OPENAI_API_KEY"]) !== undefined;
102
+ }
103
+ catch {
104
+ return false;
105
+ }
106
+ }
107
+ /**
108
+ * Whether the runtime's own auth.json is signed in with a ChatGPT account.
109
+ *
110
+ * Measured 2026-10-03 on this machine: when `auth_mode` is `chatgpt`, codex's
111
+ * auth manager refreshes the OAuth token FIRST and never falls through to the
112
+ * `OPENAI_API_KEY` in the same file — so a `requires_openai_auth` provider is
113
+ * silently unusable behind a ChatGPT login (here the refresh is 403
114
+ * `unsupported_country_region_territory`). The `env_key` shape is unaffected
115
+ * because it never consults the auth manager at all, which is why the launch
116
+ * path now hands a stored key to the child through its own environment
117
+ * (`codex-launch.ts`). What remains exposed is only the SEEDED shape: an entry
118
+ * that holds no key because the runtime's auth.json was supposed to.
119
+ */
120
+ function chatgptAuthMode(codexHome) {
121
+ try {
122
+ const parsed = JSON.parse(readFileSync(join(codexHome, "auth.json"), "utf8"));
123
+ return isRecord(parsed) && parsed["auth_mode"] === "chatgpt";
124
+ }
125
+ catch {
126
+ return false;
127
+ }
128
+ }
129
+ /** Whether an entry's key is actually available right now. */
130
+ function keyAvailable(codexHome, entry) {
131
+ if (entry.auth.kind === "apiKey") {
132
+ return entry.auth.value !== "" || authJsonHasKey(codexHome);
133
+ }
134
+ return nonEmpty(process.env[entry.auth.name]) !== undefined;
135
+ }
136
+ function project(codexHome, entry) {
137
+ return {
138
+ id: entry.id,
139
+ label: entry.label,
140
+ baseUrl: entry.baseUrl,
141
+ protocol: entry.protocol,
142
+ models: entry.models,
143
+ authKind: entry.auth.kind,
144
+ ...(entry.auth.kind === "env" ? { envName: entry.auth.name } : {}),
145
+ hasKey: keyAvailable(codexHome, entry),
146
+ };
147
+ }
148
+ /** Turn one parsed native table into the store's import shape. */
149
+ function toImport(table) {
150
+ return {
151
+ ...(table.id === "" ? {} : { nativeId: table.id }),
152
+ baseUrl: table.baseUrl,
153
+ protocol: table.protocol,
154
+ auth: table.auth,
155
+ models: table.models,
156
+ };
157
+ }
158
+ /**
159
+ * Reconcile the canonical store against the user's `config.toml`.
160
+ *
161
+ * This is the sync the 2026-10-04 ruling asks for: the store is canonical, the
162
+ * native file is a SOURCE, and the two are joined by endpoint URL (the only
163
+ * identity a hand-written codex config reliably carries). It runs at adapter
164
+ * startup and every ten minutes thereafter, and it is idempotent and silent —
165
+ * the file is only rewritten when something actually moved.
166
+ *
167
+ * @param worldHome - the world's DSH home.
168
+ * @param codexHome - the native codex home (read only).
169
+ * @returns the effective store plus what the sync changed.
170
+ */
171
+ export function syncFromNative(worldHome, codexHome) {
172
+ const store = readProviderStore(worldHome);
173
+ const imported = readNativeProviders(codexHome).map(toImport);
174
+ const result = syncNativeProviders(store, imported);
175
+ if (result.added.length > 0 || result.updated.length > 0) {
176
+ writeProviderStore(worldHome, result.store);
177
+ }
178
+ return result;
179
+ }
180
+ /** The view for one (already loaded) store. */
181
+ function viewOf(worldHome, codexHome, store, syncedAt, note) {
182
+ const nativeSelection = readNativeSelection(codexHome);
183
+ const native = nativeSelection.providerId === undefined && nativeSelection.model === undefined
184
+ ? null
185
+ : {
186
+ ...(nativeSelection.providerId === undefined ? {} : { providerId: nativeSelection.providerId }),
187
+ ...(nativeSelection.model === undefined ? {} : { model: nativeSelection.model }),
188
+ };
189
+ // Only a SEEDED keyed entry defers to auth.json, so only it can be shadowed
190
+ // by a ChatGPT login. An entry holding its own key bypasses the auth manager
191
+ // entirely through the launch's synthetic `env_key`.
192
+ const deferred = store.providers.some((entry) => entry.auth.kind === "apiKey" && entry.auth.value === "");
193
+ const shadowed = deferred && chatgptAuthMode(codexHome)
194
+ ? 'Codex is signed in with a ChatGPT account, which takes precedence over a saved API key — a provider that relies on auth.json will not run until you sign out (`codex logout`) or give this provider its own key.'
195
+ : undefined;
196
+ const combined = [note, shadowed].filter((part) => part !== undefined).join(" ");
197
+ return {
198
+ providers: store.providers.map((entry) => project(codexHome, entry)),
199
+ native,
200
+ protocols: PROTOCOL_OPTIONS,
201
+ paths: {
202
+ store: providerStorePath(worldHome),
203
+ config: join(codexHome, "config.toml"),
204
+ auth: join(codexHome, "auth.json"),
205
+ catalogs: providerCatalogDir(worldHome),
206
+ },
207
+ ...(syncedAt === undefined ? {} : { syncedAt }),
208
+ ...(combined === "" ? {} : { note: combined }),
209
+ };
210
+ }
211
+ /**
212
+ * Read the panel state, reconciling with `config.toml` first.
213
+ *
214
+ * Reading is a write-free act for the native home now (the old build seeded the
215
+ * store from it once); the only write this can perform is to the adapter's own
216
+ * store, and only when the sync found something new.
217
+ *
218
+ * @param worldHome - the world's DSH home.
219
+ * @param codexHome - the native codex home.
220
+ * @param syncedAt - epoch ms to report as the last reconcile.
221
+ * @returns the panel's state.
222
+ */
223
+ export function readProvidersView(worldHome, codexHome, syncedAt) {
224
+ const { store, added, updated } = syncFromNative(worldHome, codexHome);
225
+ const note = added.length === 0 && updated.length === 0
226
+ ? undefined
227
+ : `Imported ${added.length} provider(s) from your Codex config.toml${updated.length === 0 ? "" : ` and refreshed ${updated.join(", ")}`}.`;
228
+ // A read IS the reconcile, so the timestamp is the read's own unless the
229
+ // caller has a better one — otherwise the panel would never have one to show.
230
+ return viewOf(worldHome, codexHome, store, syncedAt ?? Date.now(), note);
231
+ }
232
+ /**
233
+ * Validate one `codexProviders/save` request.
234
+ *
235
+ * @param request - the wire payload's `request` argument.
236
+ * @param existing - the entry this save replaces, so an edit that does not
237
+ * re-type the key keeps the stored one.
238
+ * @throws {TypeError} naming the offending field.
239
+ */
240
+ export function normalizeSaveRequest(request, existing) {
241
+ if (!isRecord(request) || !isRecord(request["provider"])) {
242
+ throw new TypeError("codexProviders/save: provider must be an object");
243
+ }
244
+ const raw = request["provider"];
245
+ const id = raw["id"];
246
+ if (!isProviderId(id)) {
247
+ throw new TypeError(`codexProviders/save: id must match /^[a-z0-9][a-z0-9-]*$/ (got ${JSON.stringify(id)})`);
248
+ }
249
+ const label = nonEmpty(raw["label"]);
250
+ if (label === undefined)
251
+ throw new TypeError("codexProviders/save: label must be a non-empty string");
252
+ const baseUrl = nonEmpty(raw["baseUrl"]);
253
+ if (baseUrl === undefined)
254
+ throw new TypeError("codexProviders/save: baseUrl must be a non-empty string");
255
+ let parsed;
256
+ try {
257
+ parsed = new URL(baseUrl);
258
+ }
259
+ catch {
260
+ throw new TypeError(`codexProviders/save: baseUrl is not a URL (got ${JSON.stringify(baseUrl)})`);
261
+ }
262
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
263
+ throw new TypeError(`codexProviders/save: baseUrl must be http(s) (got ${parsed.protocol})`);
264
+ }
265
+ const protocol = raw["protocol"];
266
+ if (!isWireProtocol(protocol)) {
267
+ throw new TypeError(`codexProviders/save: protocol must be "responses" or "chat" (got ${JSON.stringify(protocol)})`);
268
+ }
269
+ if (protocol === "chat") {
270
+ // Refused at the boundary rather than persisted and discovered by codex.
271
+ throw new TypeError('codexProviders/save: protocol "chat" is refused by codex 0.154; use "responses"');
272
+ }
273
+ const rawModels = raw["models"];
274
+ // An empty list is legal: it is the state a provider imported from a native
275
+ // config arrives in (only the provider in force has a discoverable catalog),
276
+ // and the panel must be able to save an edit without inventing models.
277
+ if (!Array.isArray(rawModels)) {
278
+ throw new TypeError("codexProviders/save: models must be an array");
279
+ }
280
+ const models = rawModels.map((value) => {
281
+ if (!isRecord(value))
282
+ throw new TypeError("codexProviders/save: every entry of models must be an object");
283
+ const modelId = nonEmpty(value["id"]);
284
+ if (modelId === undefined)
285
+ throw new TypeError("codexProviders/save: every entry of models needs a non-empty id");
286
+ const displayName = nonEmpty(value["displayName"]);
287
+ const contextWindow = value["contextWindow"];
288
+ return {
289
+ id: modelId,
290
+ ...(displayName === undefined ? {} : { displayName }),
291
+ ...(typeof contextWindow === "number" && Number.isSafeInteger(contextWindow) && contextWindow > 0
292
+ ? { contextWindow }
293
+ : {}),
294
+ };
295
+ });
296
+ const rawAuth = raw["auth"];
297
+ if (!isRecord(rawAuth))
298
+ throw new TypeError("codexProviders/save: auth must be an object");
299
+ let auth;
300
+ if (rawAuth["kind"] === "env") {
301
+ const name = nonEmpty(rawAuth["name"]);
302
+ if (name === undefined)
303
+ throw new TypeError("codexProviders/save: auth.name must be a non-empty string");
304
+ auth = { kind: "env", name };
305
+ }
306
+ else if (rawAuth["kind"] === "apiKey") {
307
+ const value = rawAuth["value"];
308
+ if (typeof value !== "string")
309
+ throw new TypeError("codexProviders/save: auth.value must be a string");
310
+ // An empty value on an edit means "keep the stored one" — the panel is
311
+ // write-only for keys, so it cannot echo the existing value back.
312
+ const kept = value === "" && existing?.auth.kind === "apiKey" ? existing.auth.value : value;
313
+ auth = { kind: "apiKey", value: kept };
314
+ }
315
+ else {
316
+ throw new TypeError(`codexProviders/save: auth.kind must be "apiKey" or "env" (got ${JSON.stringify(rawAuth["kind"])})`);
317
+ }
318
+ return { id, label, baseUrl, protocol, auth, models, origin: "user" };
319
+ }
320
+ /**
321
+ * Insert or replace one provider.
322
+ *
323
+ * Nothing native is written, and nothing is "activated": the model catalog for
324
+ * this provider is regenerated on the adapter's own tree (`codex-launch.ts`
325
+ * does it at spawn), and the next session that picks one of these models gets a
326
+ * child pinned to it.
327
+ */
328
+ export function saveProvider(worldHome, codexHome, request, syncedAt) {
329
+ const store = readProviderStore(worldHome);
330
+ const id = isRecord(request) && isRecord(request["provider"]) ? request["provider"]["id"] : undefined;
331
+ const existing = store.providers.find((entry) => entry.id === id);
332
+ const entry = normalizeSaveRequest(request, existing);
333
+ const next = upsertProvider(store, entry);
334
+ writeProviderStore(worldHome, next);
335
+ return viewOf(worldHome, codexHome, next, syncedAt);
336
+ }
337
+ /** Drop one provider. The native config is left alone — removing from this list is not unconfiguring Codex. */
338
+ export function removeProviderEntry(worldHome, codexHome, request, syncedAt) {
339
+ const id = isRecord(request) ? nonEmpty(request["id"]) : undefined;
340
+ if (id === undefined)
341
+ throw new TypeError("codexProviders/remove: id must be a non-empty string");
342
+ const store = readProviderStore(worldHome);
343
+ const next = removeProvider(store, id);
344
+ writeProviderStore(worldHome, next);
345
+ return viewOf(worldHome, codexHome, next, syncedAt);
346
+ }
347
+ /**
348
+ * The adapter's provider Remote. One instance per world context.
349
+ */
350
+ let CodexProvidersGateway = (() => {
351
+ let _classSuper = TypertRemoteService;
352
+ let _instanceExtraInitializers = [];
353
+ let _get_decorators;
354
+ let _save_decorators;
355
+ let _remove_decorators;
356
+ return class CodexProvidersGateway extends _classSuper {
357
+ static {
358
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
359
+ _get_decorators = [Remote("get")];
360
+ _save_decorators = [Remote("save")];
361
+ _remove_decorators = [Remote("remove")];
362
+ __esDecorate(this, null, _get_decorators, { kind: "method", name: "get", static: false, private: false, access: { has: obj => "get" in obj, get: obj => obj.get }, metadata: _metadata }, null, _instanceExtraInitializers);
363
+ __esDecorate(this, null, _save_decorators, { kind: "method", name: "save", static: false, private: false, access: { has: obj => "save" in obj, get: obj => obj.save }, metadata: _metadata }, null, _instanceExtraInitializers);
364
+ __esDecorate(this, null, _remove_decorators, { kind: "method", name: "remove", static: false, private: false, access: { has: obj => "remove" in obj, get: obj => obj.remove }, metadata: _metadata }, null, _instanceExtraInitializers);
365
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
366
+ }
367
+ worldHome = __runInitializers(this, _instanceExtraInitializers);
368
+ codexHome;
369
+ onChange;
370
+ /**
371
+ * @param ctx - the world context this service registers on (namespace `codexProviders`).
372
+ * @param worldHome - the world's DSH home holding adapter state (`<dshHome>/agents/codex`).
373
+ * @param codexHome - the USER's real codex home (native settings live there), resolved lazily so construction stays zero-IO.
374
+ * @param onChange - notified after any mutation, so the provider's `ctx.llm` routes can be re-registered.
375
+ */
376
+ constructor(ctx, worldHome, codexHome, onChange = () => { }) {
377
+ super(ctx, "codexProviders");
378
+ this.worldHome = worldHome;
379
+ this.codexHome = codexHome;
380
+ this.onChange = onChange;
381
+ }
382
+ /** Read the panel state, reconciling the store with `config.toml` first. Never writes the native home. */
383
+ async get() {
384
+ const view = readProvidersView(this.worldHome, this.codexHome());
385
+ this.onChange();
386
+ return view;
387
+ }
388
+ /** Add or edit one provider. */
389
+ async save(request) {
390
+ const view = saveProvider(this.worldHome, this.codexHome(), request);
391
+ this.onChange();
392
+ return view;
393
+ }
394
+ /** Drop one provider from the list. */
395
+ async remove(request) {
396
+ const view = removeProviderEntry(this.worldHome, this.codexHome(), request);
397
+ this.onChange();
398
+ return view;
399
+ }
400
+ };
401
+ })();
402
+ export { CodexProvidersGateway };