super-dsh 0.1.9 → 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 (178) 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 +1204 -93
  162. package/cordis.patch.yml +64 -0
  163. package/package.json +17 -8
  164. package/superd-hub/dist/client/agent-settings.d.ts +210 -0
  165. package/superd-hub/dist/client/agent-settings.js +300 -0
  166. package/superd-hub/dist/client/roster.js +6 -0
  167. package/superd-hub/dist/client/runtime-settings-api.d.ts +76 -0
  168. package/superd-hub/dist/client/runtime-settings-api.js +137 -0
  169. package/superd-hub/dist/client/switch.d.ts +165 -0
  170. package/superd-hub/dist/client/switch.js +295 -0
  171. package/superd-hub/lib/client/index.js +1204 -93
  172. package/agent-codex/dist/models.js +0 -152
  173. package/agent-omp/dist/sidecar-client.js +0 -195
  174. /package/{agent-agy → agent-agy-sdk}/bridge/agy_bridge.py +0 -0
  175. /package/{agent-agy → agent-agy-sdk}/bridge/gemini_openai_server.mjs +0 -0
  176. /package/{agent-codex/dist/codex-events.js → agent-codex-sdk/dist/codex-sdk-events.js} +0 -0
  177. /package/{agent-omp → agent-omp-sdk}/dist/protocol.js +0 -0
  178. /package/{agent-omp → agent-omp-sdk}/sidecar/main.ts +0 -0
@@ -0,0 +1,169 @@
1
+ /**
2
+ * claude-native-config.ts — reading the foreign runtime's own settings, the
3
+ * read-only half of the multi-provider split (2026-10-04).
4
+ *
5
+ * Claude Code is a single-provider harness: its `settings.json` `env` block
6
+ * names exactly ONE `ANTHROPIC_BASE_URL` with at most one key variable, so the
7
+ * LIST of providers a user has configured has nowhere to live natively and
8
+ * lives in the adapter's store instead (`claude-providers.ts`). This module is
9
+ * the other half of that split — the sole authority on what the user's own
10
+ * file actually says.
11
+ *
12
+ * The direction is one-way: `settings.json` is a SOURCE. Nothing here writes
13
+ * it — this module has no write path at all — and cc-switch can still own the
14
+ * file; the sync in `claude-provider-gateway.ts` picks up whatever it leaves
15
+ * there. The `.bak-*` manual-switch layers are never folded (they are not the
16
+ * live file). Compare `agent-codex/src/codex-native-config.ts`, the structural
17
+ * port source; claude needs none of codex's per-provider catalog machinery
18
+ * because a settings env block IS its whole catalog.
19
+ *
20
+ * Two reads live here:
21
+ *
22
+ * - `readNativeProviders` — the `env` block as a provider table, 0 or 1
23
+ * entries. An env block without `ANTHROPIC_BASE_URL` declares no provider:
24
+ * the store's identity IS the endpoint URL, and with nothing to dedupe by
25
+ * there is no entry to make.
26
+ * - `readNativeModel` — `env.ANTHROPIC_MODEL`, the model the user's own CLI
27
+ * runs. Independent of the provider read: a native setup on the default
28
+ * Anthropic endpoint carries no base URL but a perfectly meaningful model.
29
+ *
30
+ * Auth is classified by the VARIABLE NAME, and an explicitly-empty variable
31
+ * reads as unset — the same env semantics the codex port applies to an empty
32
+ * `env_key` — so `ANTHROPIC_AUTH_TOKEN` (Bearer) wins only when it carries a
33
+ * value, and a base URL whose env names no usable key variable folds as the
34
+ * real "keyed outside Super D" state `{kind:"apiKey", value:""}` rather than
35
+ * being rejected.
36
+ *
37
+ * Non-string env values (a hand-edited file may carry numbers or booleans)
38
+ * are read in their string forms — everything downstream of an env block is a
39
+ * string, process-env semantics — and shapes with no string form worth
40
+ * honoring (objects, arrays, null) are skipped.
41
+ *
42
+ * Every read is fail-soft: an absent file, an unreadable file, unparsable
43
+ * JSON, or a wrong shape all degrade to "nothing declared" and never throw.
44
+ *
45
+ * @module agent-claude/claude-native-config
46
+ */
47
+ import { existsSync, readFileSync } from "node:fs";
48
+ import { join } from "node:path";
49
+ // The home resolver stays canonical in claude-home.ts (it has its own tests
50
+ // and its own callers); this re-export is the non-duplicating way to give the
51
+ // native-config consumers the one-face import the plan's Interfaces pin.
52
+ export { resolveClaudeHome } from "./claude-home.js";
53
+ const SETTINGS_FILE = "settings.json";
54
+ /** Read a file, or `undefined` when it is absent or unreadable. */
55
+ function readIfExists(path) {
56
+ if (!existsSync(path))
57
+ return undefined;
58
+ try {
59
+ return readFileSync(path, "utf8");
60
+ }
61
+ catch {
62
+ return undefined;
63
+ }
64
+ }
65
+ /**
66
+ * One env value as the process would see it. Strings pass verbatim; numbers
67
+ * and booleans coerce to their string forms; objects, arrays, null, and
68
+ * empty/whitespace strings are unusable (an empty credential is not a
69
+ * credential — see the module header).
70
+ */
71
+ function envString(value) {
72
+ if (typeof value === "string")
73
+ return value.trim() === "" ? undefined : value;
74
+ if (typeof value === "number" && Number.isFinite(value))
75
+ return String(value);
76
+ if (typeof value === "boolean")
77
+ return value ? "true" : "false";
78
+ return undefined;
79
+ }
80
+ /** The settings.json `env` block, or `undefined` when anything above it fails. */
81
+ function readEnvBlock(claudeHome) {
82
+ const text = readIfExists(join(claudeHome, SETTINGS_FILE));
83
+ if (text === undefined)
84
+ return undefined;
85
+ let parsed;
86
+ try {
87
+ parsed = JSON.parse(text);
88
+ }
89
+ catch {
90
+ return undefined;
91
+ }
92
+ if (parsed === null || Array.isArray(parsed) || typeof parsed !== "object")
93
+ return undefined;
94
+ const env = parsed["env"];
95
+ if (env === null || Array.isArray(env) || typeof env !== "object")
96
+ return undefined;
97
+ return env;
98
+ }
99
+ /**
100
+ * Parse the native settings env into the sync's source tables.
101
+ *
102
+ * The output is 0 or 1 entries, in the only order there is. `models` is the
103
+ * DEDUPLICATED sequence of the alias values (sonnet, opus, haiku) — the only
104
+ * model ids a settings env reveals; `ANTHROPIC_MODEL` deliberately does not
105
+ * become one (it is `readNativeModel`'s own view, and folding it would invent
106
+ * a catalog entry the aliases never named).
107
+ *
108
+ * @param claudeHome - the NATIVE claude home (`~/.claude`).
109
+ * @returns the declared provider table, or `[]` when the env declares none.
110
+ */
111
+ export function readNativeProviders(claudeHome) {
112
+ const env = readEnvBlock(claudeHome);
113
+ if (env === undefined)
114
+ return [];
115
+ const baseUrl = envString(env["ANTHROPIC_BASE_URL"]);
116
+ // No endpoint is not a provider: there is nothing to dedupe the entry by in
117
+ // a list whose identity IS the endpoint URL.
118
+ if (baseUrl === undefined)
119
+ return [];
120
+ // Key-variable precedence: AUTH_TOKEN (Bearer) over API_KEY (x-api-key),
121
+ // an empty variable counting as unset, and no usable variable at all
122
+ // folding as the keyed-outside-Super-D state rather than an error.
123
+ const token = envString(env["ANTHROPIC_AUTH_TOKEN"]);
124
+ const key = envString(env["ANTHROPIC_API_KEY"]);
125
+ const auth = token !== undefined
126
+ ? { kind: "authToken", value: token }
127
+ : key !== undefined
128
+ ? { kind: "apiKey", value: key }
129
+ : { kind: "apiKey", value: "" };
130
+ const sonnet = envString(env["ANTHROPIC_DEFAULT_SONNET_MODEL"]);
131
+ const opus = envString(env["ANTHROPIC_DEFAULT_OPUS_MODEL"]);
132
+ const haiku = envString(env["ANTHROPIC_DEFAULT_HAIKU_MODEL"]);
133
+ const models = [];
134
+ const seen = new Set();
135
+ for (const id of [sonnet, opus, haiku]) {
136
+ if (id === undefined || seen.has(id))
137
+ continue;
138
+ seen.add(id);
139
+ models.push({ id });
140
+ }
141
+ const table = {
142
+ baseUrl,
143
+ auth,
144
+ models,
145
+ ...(sonnet === undefined && opus === undefined && haiku === undefined ? {} : {
146
+ aliases: {
147
+ ...(sonnet === undefined ? {} : { sonnet }),
148
+ ...(opus === undefined ? {} : { opus }),
149
+ ...(haiku === undefined ? {} : { haiku }),
150
+ },
151
+ }),
152
+ };
153
+ return [table];
154
+ }
155
+ /**
156
+ * The model the user's own settings env puts in force (`env.ANTHROPIC_MODEL`).
157
+ *
158
+ * Read independently of the provider tables: it is the panel's passive "your
159
+ * own Claude runs this" line, meaningful even when no endpoint is declared.
160
+ *
161
+ * @param claudeHome - the NATIVE claude home (`~/.claude`).
162
+ * @returns the model id, or `undefined` when the env names none.
163
+ */
164
+ export function readNativeModel(claudeHome) {
165
+ const env = readEnvBlock(claudeHome);
166
+ if (env === undefined)
167
+ return undefined;
168
+ return envString(env["ANTHROPIC_MODEL"]);
169
+ }
@@ -0,0 +1,340 @@
1
+ /**
2
+ * claude-provider-gateway.ts — the adapter-owned Remote behind the Hub's Claude
3
+ * settings panel (2026-10-04 multi-provider ruling).
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=claude
16
+ * { type:'client-request', rpcId, method:'claudeProviders/<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 `settings.json` that {@link syncFromNative} performs.
24
+ *
25
+ * The class is a delegation shell on purpose: every operation is a plain
26
+ * function over (worldHome, claudeHome), 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-claude/claude-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, providerStorePath, readProviderStore, removeProvider, syncNativeProviders, upsertProvider, writeProviderStore, } from "./claude-providers.js";
68
+ import { readNativeModel, readNativeProviders, } from "./claude-native-config.js";
69
+ import { join } from "node:path";
70
+ function isRecord(value) {
71
+ return value !== null && typeof value === "object" && !Array.isArray(value);
72
+ }
73
+ function nonEmpty(value) {
74
+ return typeof value === "string" && value.trim() !== "" ? value : undefined;
75
+ }
76
+ /**
77
+ * Whether an entry's key is actually available right now.
78
+ *
79
+ * Claude has no auth-manager shadowing to work around (the codex face's
80
+ * ChatGPT-login wrinkle has no analogue here): both kinds carry the literal
81
+ * secret and reach the child through its own environment
82
+ * (`claude-launch.ts`), so the store IS the whole truth — an empty value is the
83
+ * real "keyed outside Super D" state and nothing else can supply the key.
84
+ */
85
+ function keyAvailable(entry) {
86
+ return entry.auth.value !== "";
87
+ }
88
+ function project(entry) {
89
+ return {
90
+ id: entry.id,
91
+ label: entry.label,
92
+ baseUrl: entry.baseUrl,
93
+ models: entry.models,
94
+ authKind: entry.auth.kind,
95
+ hasKey: keyAvailable(entry),
96
+ };
97
+ }
98
+ /** Turn one parsed native table into the store's import shape. */
99
+ function toImport(table) {
100
+ // The native read emits a table only when a usable endpoint exists, and it
101
+ // always classifies an auth shape by then; the optionals are the TYPE being
102
+ // honest about a hand-edited file, so the fold keeps only tables that
103
+ // actually carry the pair.
104
+ if (table.baseUrl === undefined || table.auth === undefined)
105
+ return undefined;
106
+ return {
107
+ baseUrl: table.baseUrl,
108
+ auth: table.auth,
109
+ models: table.models,
110
+ ...(table.aliases === undefined ? {} : { aliases: table.aliases }),
111
+ };
112
+ }
113
+ /**
114
+ * Reconcile the canonical store against the user's `settings.json` env.
115
+ *
116
+ * This is the sync the 2026-10-04 ruling asks for: the store is canonical, the
117
+ * native settings env is a SOURCE, and the two are joined by endpoint URL (the
118
+ * only identity a hand-written settings env reliably carries — it names no
119
+ * provider). It runs at adapter startup and every ten minutes thereafter, and
120
+ * it is idempotent and silent — the store is only rewritten when something
121
+ * actually moved.
122
+ *
123
+ * @param worldHome - the world's DSH home.
124
+ * @param claudeHome - the native claude home (read only).
125
+ * @returns the effective store plus what the sync changed.
126
+ */
127
+ export function syncFromNative(worldHome, claudeHome) {
128
+ const store = readProviderStore(worldHome);
129
+ const imported = readNativeProviders(claudeHome)
130
+ .map(toImport)
131
+ .filter((value) => value !== undefined);
132
+ const result = syncNativeProviders(store, imported);
133
+ if (result.added.length > 0 || result.updated.length > 0) {
134
+ writeProviderStore(worldHome, result.store);
135
+ }
136
+ return result;
137
+ }
138
+ /** The view for one (already loaded) store. */
139
+ function viewOf(worldHome, claudeHome, store, syncedAt, note) {
140
+ // A settings env declares at most one endpoint, so the FIRST table is the
141
+ // one in force. `readNativeModel` is read on its own because a native setup
142
+ // on the default Anthropic endpoint carries a model but no base URL.
143
+ const baseUrl = readNativeProviders(claudeHome)[0]?.baseUrl;
144
+ const model = readNativeModel(claudeHome);
145
+ const native = baseUrl === undefined && model === undefined
146
+ ? null
147
+ : {
148
+ ...(baseUrl === undefined ? {} : { baseUrl }),
149
+ ...(model === undefined ? {} : { model }),
150
+ };
151
+ return {
152
+ providers: store.providers.map(project),
153
+ native,
154
+ paths: {
155
+ store: providerStorePath(worldHome),
156
+ settings: join(claudeHome, "settings.json"),
157
+ },
158
+ ...(syncedAt === undefined ? {} : { syncedAt }),
159
+ ...(note === undefined ? {} : { note }),
160
+ };
161
+ }
162
+ /**
163
+ * Read the panel state, reconciling with the native `settings.json` env first.
164
+ *
165
+ * Reading never writes the native home; the only write this can perform is to
166
+ * the adapter's own store, and only when the sync found something new.
167
+ *
168
+ * @param worldHome - the world's DSH home.
169
+ * @param claudeHome - the native claude home.
170
+ * @param syncedAt - epoch ms to report as the last reconcile.
171
+ * @returns the panel's state.
172
+ */
173
+ export function readProvidersView(worldHome, claudeHome, syncedAt) {
174
+ const { store, added, updated } = syncFromNative(worldHome, claudeHome);
175
+ const note = added.length === 0 && updated.length === 0
176
+ ? undefined
177
+ : `Imported ${added.length} provider(s) from your Claude settings.json${updated.length === 0 ? "" : ` and refreshed ${updated.join(", ")}`}.`;
178
+ // A read IS the reconcile, so the timestamp is the read's own unless the
179
+ // caller has a better one — otherwise the panel would never have one to show.
180
+ return viewOf(worldHome, claudeHome, store, syncedAt ?? Date.now(), note);
181
+ }
182
+ /**
183
+ * Validate one `claudeProviders/save` request.
184
+ *
185
+ * @param request - the wire payload's `request` argument.
186
+ * @param existing - the entry this save replaces, so an edit that does not
187
+ * re-type the key keeps the stored one.
188
+ * @throws {TypeError} naming the offending field.
189
+ */
190
+ export function normalizeSaveRequest(request, existing) {
191
+ if (!isRecord(request) || !isRecord(request["provider"])) {
192
+ throw new TypeError("claudeProviders/save: provider must be an object");
193
+ }
194
+ const raw = request["provider"];
195
+ const id = raw["id"];
196
+ if (!isProviderId(id)) {
197
+ throw new TypeError(`claudeProviders/save: id must match /^[a-z0-9][a-z0-9-]*$/ (got ${JSON.stringify(id)})`);
198
+ }
199
+ const label = nonEmpty(raw["label"]);
200
+ if (label === undefined)
201
+ throw new TypeError("claudeProviders/save: label must be a non-empty string");
202
+ const baseUrl = nonEmpty(raw["baseUrl"]);
203
+ if (baseUrl === undefined)
204
+ throw new TypeError("claudeProviders/save: baseUrl must be a non-empty string");
205
+ let parsed;
206
+ try {
207
+ parsed = new URL(baseUrl);
208
+ }
209
+ catch {
210
+ throw new TypeError(`claudeProviders/save: baseUrl is not a URL (got ${JSON.stringify(baseUrl)})`);
211
+ }
212
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
213
+ throw new TypeError(`claudeProviders/save: baseUrl must be http(s) (got ${parsed.protocol})`);
214
+ }
215
+ const rawModels = raw["models"];
216
+ // An empty list is legal: it is the state a provider folded in from a native
217
+ // settings env that names no alias model arrives in, and the panel must be
218
+ // able to save an edit without inventing models.
219
+ if (!Array.isArray(rawModels)) {
220
+ throw new TypeError("claudeProviders/save: models must be an array");
221
+ }
222
+ const models = rawModels.map((value) => {
223
+ if (!isRecord(value))
224
+ throw new TypeError("claudeProviders/save: every entry of models must be an object");
225
+ const modelId = nonEmpty(value["id"]);
226
+ if (modelId === undefined)
227
+ throw new TypeError("claudeProviders/save: every entry of models needs a non-empty id");
228
+ const displayName = nonEmpty(value["displayName"]);
229
+ const contextWindow = value["contextWindow"];
230
+ return {
231
+ id: modelId,
232
+ ...(displayName === undefined ? {} : { displayName }),
233
+ ...(typeof contextWindow === "number" && Number.isSafeInteger(contextWindow) && contextWindow > 0
234
+ ? { contextWindow }
235
+ : {}),
236
+ };
237
+ });
238
+ // `aliases` is deliberately NOT a save field: the DEFAULT_*_MODEL mapping is
239
+ // derived by the native fold (spec §2.2), the panel never edits it, and a
240
+ // save of a folded entry drops it — the next reconcile re-derives it from
241
+ // the live settings env for as long as the endpoint still matches.
242
+ const rawAuth = raw["auth"];
243
+ if (!isRecord(rawAuth))
244
+ throw new TypeError("claudeProviders/save: auth must be an object");
245
+ const kind = rawAuth["kind"];
246
+ if (kind !== "authToken" && kind !== "apiKey") {
247
+ throw new TypeError(`claudeProviders/save: auth.kind must be "authToken" or "apiKey" (got ${JSON.stringify(kind)})`);
248
+ }
249
+ const value = rawAuth["value"];
250
+ if (typeof value !== "string")
251
+ throw new TypeError("claudeProviders/save: auth.value must be a string");
252
+ // An empty value on an edit means "keep the stored one" — the panel is
253
+ // write-only for keys, so it cannot echo the existing value back. The keep
254
+ // is per kind: a secret of the other shape is not this provider's key.
255
+ const kept = value === "" && existing?.auth.kind === kind ? existing.auth.value : value;
256
+ const auth = { kind, value: kept };
257
+ return { id, label, baseUrl, auth, models, origin: "user" };
258
+ }
259
+ /**
260
+ * Insert or replace one provider.
261
+ *
262
+ * Nothing native is written, and nothing is "activated": the entry sits in the
263
+ * list, and the next session that picks one of its models gets a child pinned
264
+ * to it — `claude-launch.ts` builds the provider's environment at spawn.
265
+ */
266
+ export function saveProvider(worldHome, claudeHome, request, syncedAt) {
267
+ const store = readProviderStore(worldHome);
268
+ const id = isRecord(request) && isRecord(request["provider"]) ? request["provider"]["id"] : undefined;
269
+ const existing = store.providers.find((entry) => entry.id === id);
270
+ const entry = normalizeSaveRequest(request, existing);
271
+ const next = upsertProvider(store, entry);
272
+ writeProviderStore(worldHome, next);
273
+ return viewOf(worldHome, claudeHome, next, syncedAt);
274
+ }
275
+ /** Drop one provider. The native settings are left alone — removing from this list is not unconfiguring Claude Code. */
276
+ export function removeProviderEntry(worldHome, claudeHome, request, syncedAt) {
277
+ const id = isRecord(request) ? nonEmpty(request["id"]) : undefined;
278
+ if (id === undefined)
279
+ throw new TypeError("claudeProviders/remove: id must be a non-empty string");
280
+ const store = readProviderStore(worldHome);
281
+ const next = removeProvider(store, id);
282
+ writeProviderStore(worldHome, next);
283
+ return viewOf(worldHome, claudeHome, next, syncedAt);
284
+ }
285
+ /**
286
+ * The adapter's provider Remote. One instance per world context.
287
+ */
288
+ let ClaudeProvidersGateway = (() => {
289
+ let _classSuper = TypertRemoteService;
290
+ let _instanceExtraInitializers = [];
291
+ let _get_decorators;
292
+ let _save_decorators;
293
+ let _remove_decorators;
294
+ return class ClaudeProvidersGateway extends _classSuper {
295
+ static {
296
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
297
+ _get_decorators = [Remote("get")];
298
+ _save_decorators = [Remote("save")];
299
+ _remove_decorators = [Remote("remove")];
300
+ __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);
301
+ __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);
302
+ __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);
303
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
304
+ }
305
+ worldHome = __runInitializers(this, _instanceExtraInitializers);
306
+ claudeHome;
307
+ onChange;
308
+ /**
309
+ * @param ctx - the world context this service registers on (namespace `claudeProviders`).
310
+ * @param worldHome - the world's DSH home holding adapter state (`<dshHome>/agents/claude`).
311
+ * @param claudeHome - the USER's real claude home (native settings live there), resolved lazily so construction stays zero-IO.
312
+ * @param onChange - notified after any mutation, so the provider's `ctx.llm` routes can be re-registered.
313
+ */
314
+ constructor(ctx, worldHome, claudeHome, onChange = () => { }) {
315
+ super(ctx, "claudeProviders");
316
+ this.worldHome = worldHome;
317
+ this.claudeHome = claudeHome;
318
+ this.onChange = onChange;
319
+ }
320
+ /** Read the panel state, reconciling the store with the native settings env first. Never writes the native home. */
321
+ async get() {
322
+ const view = readProvidersView(this.worldHome, this.claudeHome());
323
+ this.onChange();
324
+ return view;
325
+ }
326
+ /** Add or edit one provider. */
327
+ async save(request) {
328
+ const view = saveProvider(this.worldHome, this.claudeHome(), request);
329
+ this.onChange();
330
+ return view;
331
+ }
332
+ /** Drop one provider from the list. */
333
+ async remove(request) {
334
+ const view = removeProviderEntry(this.worldHome, this.claudeHome(), request);
335
+ this.onChange();
336
+ return view;
337
+ }
338
+ };
339
+ })();
340
+ export { ClaudeProvidersGateway };