@atomic-chat/core 0.20.7 → 0.21.0

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 (216) hide show
  1. package/dist/cli/launch.d.ts +23 -3
  2. package/dist/cli/launch.js +59 -8
  3. package/dist/cli/launch.js.map +1 -1
  4. package/dist/cli/main.d.ts +1 -1
  5. package/dist/contracts/events.d.ts +8 -0
  6. package/dist/contracts/settings.d.ts +5 -0
  7. package/dist/contracts/settings.js.map +1 -1
  8. package/dist/core/atomic-core.d.ts +3 -1
  9. package/dist/core/atomic-core.js +4 -1
  10. package/dist/core/atomic-core.js.map +1 -1
  11. package/dist/core/create.js +4 -1
  12. package/dist/core/create.js.map +1 -1
  13. package/dist/core/sessions.js +1 -0
  14. package/dist/core/sessions.js.map +1 -1
  15. package/dist/integrations/catalog.d.ts +25 -8
  16. package/dist/integrations/catalog.js +105 -38
  17. package/dist/integrations/catalog.js.map +1 -1
  18. package/dist/integrations/configure/atomic-agent.d.ts +9 -1
  19. package/dist/integrations/configure/atomic-agent.js +42 -3
  20. package/dist/integrations/configure/atomic-agent.js.map +1 -1
  21. package/dist/integrations/configure/backup.d.ts +21 -0
  22. package/dist/integrations/configure/backup.js +52 -0
  23. package/dist/integrations/configure/backup.js.map +1 -0
  24. package/dist/integrations/configure/claude-code.d.ts +11 -4
  25. package/dist/integrations/configure/claude-code.js +73 -24
  26. package/dist/integrations/configure/claude-code.js.map +1 -1
  27. package/dist/integrations/configure/cline.d.ts +14 -4
  28. package/dist/integrations/configure/cline.js +78 -6
  29. package/dist/integrations/configure/cline.js.map +1 -1
  30. package/dist/integrations/configure/codex.d.ts +5 -3
  31. package/dist/integrations/configure/codex.js +12 -5
  32. package/dist/integrations/configure/codex.js.map +1 -1
  33. package/dist/integrations/configure/copilot.d.ts +28 -5
  34. package/dist/integrations/configure/copilot.js +124 -8
  35. package/dist/integrations/configure/copilot.js.map +1 -1
  36. package/dist/integrations/configure/droid.d.ts +13 -7
  37. package/dist/integrations/configure/droid.js +48 -17
  38. package/dist/integrations/configure/droid.js.map +1 -1
  39. package/dist/integrations/configure/dsh.d.ts +36 -20
  40. package/dist/integrations/configure/dsh.js +250 -48
  41. package/dist/integrations/configure/dsh.js.map +1 -1
  42. package/dist/integrations/configure/goose.d.ts +21 -7
  43. package/dist/integrations/configure/goose.js +141 -10
  44. package/dist/integrations/configure/goose.js.map +1 -1
  45. package/dist/integrations/configure/hermes.d.ts +63 -10
  46. package/dist/integrations/configure/hermes.js +360 -75
  47. package/dist/integrations/configure/hermes.js.map +1 -1
  48. package/dist/integrations/configure/json-backup.d.ts +73 -0
  49. package/dist/integrations/configure/json-backup.js +292 -0
  50. package/dist/integrations/configure/json-backup.js.map +1 -0
  51. package/dist/integrations/configure/json-key-backup.d.ts +43 -0
  52. package/dist/integrations/configure/json-key-backup.js +113 -0
  53. package/dist/integrations/configure/json-key-backup.js.map +1 -0
  54. package/dist/integrations/configure/kilo.d.ts +4 -4
  55. package/dist/integrations/configure/kilo.js +6 -9
  56. package/dist/integrations/configure/kilo.js.map +1 -1
  57. package/dist/integrations/configure/legacy-env-block.d.ts +18 -0
  58. package/dist/integrations/configure/legacy-env-block.js +47 -0
  59. package/dist/integrations/configure/legacy-env-block.js.map +1 -0
  60. package/dist/integrations/configure/mimo.d.ts +3 -2
  61. package/dist/integrations/configure/mimo.js +8 -9
  62. package/dist/integrations/configure/mimo.js.map +1 -1
  63. package/dist/integrations/configure/muse.d.ts +3 -3
  64. package/dist/integrations/configure/muse.js +5 -6
  65. package/dist/integrations/configure/muse.js.map +1 -1
  66. package/dist/integrations/configure/openclaude.d.ts +22 -7
  67. package/dist/integrations/configure/openclaude.js +132 -39
  68. package/dist/integrations/configure/openclaude.js.map +1 -1
  69. package/dist/integrations/configure/openclaw.d.ts +19 -5
  70. package/dist/integrations/configure/openclaw.js +79 -23
  71. package/dist/integrations/configure/openclaw.js.map +1 -1
  72. package/dist/integrations/configure/opencode-style.d.ts +53 -11
  73. package/dist/integrations/configure/opencode-style.js +218 -23
  74. package/dist/integrations/configure/opencode-style.js.map +1 -1
  75. package/dist/integrations/configure/opencode.d.ts +5 -4
  76. package/dist/integrations/configure/opencode.js +8 -10
  77. package/dist/integrations/configure/opencode.js.map +1 -1
  78. package/dist/integrations/configure/openhands.d.ts +5 -4
  79. package/dist/integrations/configure/openhands.js +7 -7
  80. package/dist/integrations/configure/openhands.js.map +1 -1
  81. package/dist/integrations/configure/pi.d.ts +6 -5
  82. package/dist/integrations/configure/pi.js +79 -30
  83. package/dist/integrations/configure/pi.js.map +1 -1
  84. package/dist/integrations/configure/poolside.d.ts +5 -4
  85. package/dist/integrations/configure/poolside.js +7 -7
  86. package/dist/integrations/configure/poolside.js.map +1 -1
  87. package/dist/integrations/configure/registry.d.ts +6 -0
  88. package/dist/integrations/configure/registry.js +1 -0
  89. package/dist/integrations/configure/registry.js.map +1 -1
  90. package/dist/integrations/configure/zcode.d.ts +6 -7
  91. package/dist/integrations/configure/zcode.js +26 -11
  92. package/dist/integrations/configure/zcode.js.map +1 -1
  93. package/dist/integrations/configure/zed.d.ts +16 -4
  94. package/dist/integrations/configure/zed.js +61 -13
  95. package/dist/integrations/configure/zed.js.map +1 -1
  96. package/dist/models/gguf/kv-cache.d.ts +20 -1
  97. package/dist/models/gguf/kv-cache.js +97 -7
  98. package/dist/models/gguf/kv-cache.js.map +1 -1
  99. package/dist/models/gguf/reader.d.ts +5 -3
  100. package/dist/models/gguf/reader.js +10 -6
  101. package/dist/models/gguf/reader.js.map +1 -1
  102. package/dist/runtime/llamacpp/args.d.ts +14 -0
  103. package/dist/runtime/llamacpp/args.js +48 -4
  104. package/dist/runtime/llamacpp/args.js.map +1 -1
  105. package/dist/runtime/llamacpp/ctx-ladder.d.ts +6 -3
  106. package/dist/runtime/llamacpp/ctx-ladder.js +6 -3
  107. package/dist/runtime/llamacpp/ctx-ladder.js.map +1 -1
  108. package/dist/runtime/llamacpp/fit-margin.d.ts +24 -0
  109. package/dist/runtime/llamacpp/fit-margin.js +31 -0
  110. package/dist/runtime/llamacpp/fit-margin.js.map +1 -1
  111. package/dist/runtime/llamacpp/generation-limits.d.ts +45 -0
  112. package/dist/runtime/llamacpp/generation-limits.js +61 -0
  113. package/dist/runtime/llamacpp/generation-limits.js.map +1 -0
  114. package/dist/runtime/llamacpp/load-plan.d.ts +14 -2
  115. package/dist/runtime/llamacpp/load-plan.js +64 -13
  116. package/dist/runtime/llamacpp/load-plan.js.map +1 -1
  117. package/dist/runtime/llamacpp/runtime.d.ts +1 -0
  118. package/dist/runtime/llamacpp/runtime.js +2 -0
  119. package/dist/runtime/llamacpp/runtime.js.map +1 -1
  120. package/dist/runtime/managed-engines/runtime.js +13 -2
  121. package/dist/runtime/managed-engines/runtime.js.map +1 -1
  122. package/dist/runtime/managed-engines/spec.d.ts +6 -0
  123. package/dist/runtime/managed-engines/spec.js.map +1 -1
  124. package/dist/runtime/managed-models/auto-limits.d.ts +47 -0
  125. package/dist/runtime/managed-models/auto-limits.js +60 -0
  126. package/dist/runtime/managed-models/auto-limits.js.map +1 -0
  127. package/dist/runtime/managed-models/index.d.ts +1 -0
  128. package/dist/runtime/managed-models/index.js +1 -0
  129. package/dist/runtime/managed-models/index.js.map +1 -1
  130. package/dist/runtime/mlx/config.d.ts +9 -5
  131. package/dist/runtime/mlx/config.js +12 -6
  132. package/dist/runtime/mlx/config.js.map +1 -1
  133. package/dist/runtime/mlx/model-files.d.ts +9 -0
  134. package/dist/runtime/mlx/model-files.js +26 -0
  135. package/dist/runtime/mlx/model-files.js.map +1 -1
  136. package/dist/runtime/mlx/runtime.d.ts +7 -0
  137. package/dist/runtime/mlx/runtime.js +24 -2
  138. package/dist/runtime/mlx/runtime.js.map +1 -1
  139. package/dist/runtime/sglang/adapter.d.ts +4 -0
  140. package/dist/runtime/sglang/adapter.js +9 -6
  141. package/dist/runtime/sglang/adapter.js.map +1 -1
  142. package/dist/runtime/sglang/engine.js +2 -1
  143. package/dist/runtime/sglang/engine.js.map +1 -1
  144. package/dist/runtime/sglang/memory.d.ts +11 -1
  145. package/dist/runtime/sglang/memory.js +34 -3
  146. package/dist/runtime/sglang/memory.js.map +1 -1
  147. package/dist/runtime/sglang/settings.d.ts +2 -1
  148. package/dist/runtime/sglang/settings.js +11 -7
  149. package/dist/runtime/sglang/settings.js.map +1 -1
  150. package/dist/runtime/vllm/adapter.d.ts +4 -0
  151. package/dist/runtime/vllm/adapter.js +9 -6
  152. package/dist/runtime/vllm/adapter.js.map +1 -1
  153. package/dist/runtime/vllm/engine.js +1 -0
  154. package/dist/runtime/vllm/engine.js.map +1 -1
  155. package/dist/runtime/vllm/memory.d.ts +12 -1
  156. package/dist/runtime/vllm/memory.js +44 -2
  157. package/dist/runtime/vllm/memory.js.map +1 -1
  158. package/dist/runtime/vllm/settings.d.ts +2 -1
  159. package/dist/runtime/vllm/settings.js +12 -7
  160. package/dist/runtime/vllm/settings.js.map +1 -1
  161. package/dist/server/public/context-window.d.ts +29 -0
  162. package/dist/server/public/context-window.js +77 -0
  163. package/dist/server/public/context-window.js.map +1 -0
  164. package/dist/server/public/decision-preview.js +1 -0
  165. package/dist/server/public/decision-preview.js.map +1 -1
  166. package/dist/server/public/errors.d.ts +15 -4
  167. package/dist/server/public/errors.js +53 -7
  168. package/dist/server/public/errors.js.map +1 -1
  169. package/dist/server/public/forward.js +65 -5
  170. package/dist/server/public/forward.js.map +1 -1
  171. package/dist/server/public/index.d.ts +1 -0
  172. package/dist/server/public/index.js +1 -0
  173. package/dist/server/public/index.js.map +1 -1
  174. package/dist/server/public/listing.d.ts +9 -2
  175. package/dist/server/public/listing.js +30 -9
  176. package/dist/server/public/listing.js.map +1 -1
  177. package/dist/server/public/responses.js +9 -5
  178. package/dist/server/public/responses.js.map +1 -1
  179. package/dist/server/public/system-messages.d.ts +39 -0
  180. package/dist/server/public/system-messages.js +166 -0
  181. package/dist/server/public/system-messages.js.map +1 -0
  182. package/dist/server/public/telemetry.d.ts +9 -0
  183. package/dist/server/public/telemetry.js +42 -6
  184. package/dist/server/public/telemetry.js.map +1 -1
  185. package/dist/server/public/thinking.d.ts +26 -0
  186. package/dist/server/public/thinking.js +62 -0
  187. package/dist/server/public/thinking.js.map +1 -0
  188. package/dist/server/public/trace.d.ts +8 -0
  189. package/dist/server/public/trace.js +17 -0
  190. package/dist/server/public/trace.js.map +1 -1
  191. package/dist/server/public/types.d.ts +8 -0
  192. package/dist/server/shims/index.d.ts +1 -0
  193. package/dist/server/shims/index.js +1 -0
  194. package/dist/server/shims/index.js.map +1 -1
  195. package/dist/server/shims/reminders.d.ts +8 -0
  196. package/dist/server/shims/reminders.js +14 -0
  197. package/dist/server/shims/reminders.js.map +1 -0
  198. package/dist/server/shims/responses.d.ts +33 -9
  199. package/dist/server/shims/responses.js +160 -36
  200. package/dist/server/shims/responses.js.map +1 -1
  201. package/dist/settings/default-migrations.d.ts +34 -0
  202. package/dist/settings/default-migrations.js +47 -0
  203. package/dist/settings/default-migrations.js.map +1 -0
  204. package/dist/settings/schema/atomic-prism.json +23 -9
  205. package/dist/settings/schema/llamacpp-upstream.json +23 -9
  206. package/dist/settings/schema/llamacpp.json +23 -9
  207. package/dist/settings/schema/sglang.json +8 -8
  208. package/dist/settings/schema/vllm.json +8 -8
  209. package/dist/settings/schema.js +1 -0
  210. package/dist/settings/schema.js.map +1 -1
  211. package/dist/settings/store.d.ts +6 -0
  212. package/dist/settings/store.js +18 -1
  213. package/dist/settings/store.js.map +1 -1
  214. package/dist/version.d.ts +1 -1
  215. package/dist/version.js +1 -1
  216. package/package.json +1 -1
@@ -1,27 +1,43 @@
1
1
  /**
2
- * OpenClaw keeps one config for the CLI and both desktop apps in `~/.openclaw/openclaw.json`
2
+ * OpenClaw keeps one config for the CLI and the macOS app in `~/.openclaw/openclaw.json`
3
3
  * (overridable with `OPENCLAW_CONFIG_PATH`); its Gateway watches the file and hot-reloads, so one
4
4
  * write covers everything with no restart.
5
5
  *
6
6
  * The merge has two tiers. Keys that express a decision the user may have made deliberately are
7
- * SEEDED only when absent — `models.mode`, `gateway.mode`, `gateway.auth.mode`,
8
- * `agents.defaults.timeoutSeconds`, and the per-model settings entry. Keys that say "run this model
9
- * now" are always OVERWRITTEN — our provider block and `agents.defaults.model.primary`.
7
+ * SEEDED only when absent — `models.mode`, `gateway.mode`, `gateway.auth.mode` (and that one only
8
+ * when the Gateway has no token or password to expect), and the per-model settings entry. Keys that
9
+ * say "run this model now" are always OVERWRITTEN — our provider block and
10
+ * `agents.defaults.model.primary`. What the keys held before is recorded in
11
+ * `openclaw.json.atomic-chat-backup.json` for the app's Disconnect.
10
12
  *
11
13
  * The one non-obvious rule is `modelPolicy.allow`. When it is non-empty it gates model selection
12
14
  * entirely, so a user restricted to a cloud provider would watch Run "succeed" and then be told our
13
15
  * model is not allowed — hence the `atomic/*` widening. But an absent key or `[]` already means
14
16
  * "allow anything", so writing into it would INTRODUCE a restriction nobody asked for. Those are
15
17
  * left exactly as they are.
18
+ *
19
+ * Mirrors `configure_openclaw_at` in the app's `core/system/commands.rs`, byte for byte.
16
20
  */
17
21
  import { AtomicCoreError } from '../../contracts/index.js';
18
22
  import { canonicalJson, keyOr, parseJsonLenient } from '../config-io.js';
23
+ import { readBackup, renderBackup, trackKeys, writeBackupText } from './json-key-backup.js';
19
24
  import { asJsonArray, asJsonObject } from './json-tree.js';
20
25
  import { registerWriter } from './registry.js';
21
26
  const PROVIDER_ID = 'atomic';
22
27
  const DEFAULT_PATH = '.openclaw/openclaw.json';
23
- /** Small local models blow past OpenClaw's short default once wrapped in the agent prompt + tools. */
24
- const DEFAULT_TIMEOUT_SECONDS = 240;
28
+ /**
29
+ * Per-request budget on our provider: it covers connecting, the headers and streaming the body, and
30
+ * raises the ~120 s idle watchdog for this provider only — a long prompt on a slow machine needs
31
+ * more before the first token. Unlike `agents.defaults.timeoutSeconds`, it leaves every other model
32
+ * alone.
33
+ */
34
+ const PROVIDER_TIMEOUT_SECONDS = 600;
35
+ /** `agents.defaults.timeoutSeconds` older releases seeded, capping every model's attempt. */
36
+ const LEGACY_AGENT_TIMEOUT_SECONDS = 240;
37
+ /** The output cap written next to a known window: a quarter of it, at most 8192 tokens. */
38
+ export function outputCapFor(contextLength) {
39
+ return Math.min(8192, Math.floor(contextLength / 4));
40
+ }
25
41
  /** Read `<parent>[key]` as an object, creating it when absent; anything else is a hard error. */
26
42
  function childObject(parent, key, label) {
27
43
  if (parent[key] === undefined)
@@ -39,8 +55,34 @@ export function modelPolicyAllows(list, modelRef) {
39
55
  return entry.endsWith('*') ? modelRef.startsWith(entry.slice(0, -1)) : entry === modelRef;
40
56
  });
41
57
  }
58
+ /**
59
+ * Bring a parsed `openclaw.json` into the shape the merge works on without changing what it means:
60
+ * a plain-string `agents.defaults.model` becomes `{ primary: <it> }`, and the
61
+ * `agents.defaults.timeoutSeconds: 240` older releases seeded goes.
62
+ */
63
+ export function openclawNormalize(parsed) {
64
+ const defaults = asJsonObject(asJsonObject(asJsonObject(parsed)?.['agents'])?.['defaults']);
65
+ if (!defaults)
66
+ return;
67
+ if (defaults['timeoutSeconds'] === LEGACY_AGENT_TIMEOUT_SECONDS)
68
+ delete defaults['timeoutSeconds'];
69
+ const model = defaults['model'];
70
+ if (typeof model === 'string')
71
+ defaults['model'] = { primary: model };
72
+ }
73
+ /** The keys Connect may overwrite besides our own provider entry. */
74
+ export function openclawTrackedPaths(modelRef) {
75
+ return [
76
+ ['models', 'mode'],
77
+ ['gateway', 'mode'],
78
+ ['gateway', 'auth', 'mode'],
79
+ ['agents', 'defaults', 'model', 'primary'],
80
+ ['agents', 'defaults', 'models', modelRef],
81
+ ['agents', 'defaults', 'modelPolicy', 'allow'],
82
+ ];
83
+ }
42
84
  /** The whole merge, with no I/O, so every rule above is testable against a plain object. */
43
- export function openclawPatchConfig(parsed, apiUrl, model, apiKey) {
85
+ export function openclawPatchConfig(parsed, apiUrl, model, apiKey, contextLength, gatewaySecretInEnv = false) {
44
86
  const root = asJsonObject(parsed);
45
87
  if (!root)
46
88
  throw new AtomicCoreError('IO_ERROR', 'openclaw.json is not a JSON object');
@@ -50,31 +92,39 @@ export function openclawPatchConfig(parsed, apiUrl, model, apiKey) {
50
92
  models['mode'] = 'merge';
51
93
  const providers = childObject(models, 'providers', 'models.providers');
52
94
  // The catalog entry's `id` is the bare model id our /v1 server reports; OpenClaw builds the ref as
53
- // `<providerId>/<id>`, so prefixing here would double it to `atomic/atomic/…` and break lookup.
95
+ // `<providerId>/<id>`, so prefixing here would double it to `atomic/atomic/…` and break lookup. A
96
+ // known window lets OpenClaw compact before the server refuses; an unknown one is not invented.
97
+ const modelEntry = { id: model, name: model };
98
+ if (contextLength !== undefined) {
99
+ modelEntry['contextWindow'] = contextLength;
100
+ modelEntry['maxTokens'] = outputCapFor(contextLength);
101
+ }
54
102
  providers[PROVIDER_ID] = {
55
103
  baseUrl: apiUrl,
56
104
  apiKey: keyOr(apiKey, 'atomic'),
57
105
  api: 'openai-completions',
58
- models: [{ id: model, name: model }],
106
+ timeoutSeconds: PROVIDER_TIMEOUT_SECONDS,
107
+ models: [modelEntry],
59
108
  };
60
- // The local gateway refuses to open its websocket without connection auth; for a loopback-only
61
- // setup "none" (private-ingress open auth) is what makes the agent reachable with no token.
62
109
  const gateway = childObject(root, 'gateway', 'gateway');
63
110
  if (gateway['mode'] === undefined)
64
111
  gateway['mode'] = 'local';
65
- const auth = childObject(gateway, 'auth', 'gateway.auth');
66
- if (auth['mode'] === undefined)
67
- auth['mode'] = 'none';
112
+ // The local Gateway refuses its websocket without connection auth and, with no mode set, expects a
113
+ // token. With no token or password to expect, "none" (private-ingress open auth) makes it
114
+ // reachable; with one, "none" would switch token auth off.
115
+ const auth = asJsonObject(gateway['auth']);
116
+ const authIsSet = ['mode', 'token', 'password'].some((key) => {
117
+ const value = auth?.[key];
118
+ return value !== undefined && value !== null && value !== '';
119
+ });
120
+ if (!authIsSet && !gatewaySecretInEnv)
121
+ childObject(gateway, 'auth', 'gateway.auth')['mode'] = 'none';
68
122
  const agents = childObject(root, 'agents', 'agents');
69
123
  const defaults = childObject(agents, 'defaults', 'agents.defaults');
70
- if (defaults['timeoutSeconds'] === undefined)
71
- defaults['timeoutSeconds'] = DEFAULT_TIMEOUT_SECONDS;
72
- // Both a plain string and an object are accepted here, but only the object form has room for the
73
- // fallbacks OpenClaw writes itself, so a string is normalised rather than extended.
74
124
  if (asJsonObject(defaults['model']) === undefined)
75
125
  defaults['model'] = {};
76
- const modelEntry = asJsonObject(defaults['model']);
77
- modelEntry['primary'] = modelRef;
126
+ const primary = asJsonObject(defaults['model']);
127
+ primary['primary'] = modelRef;
78
128
  // `agents.defaults.models` holds aliases and per-model settings. Pre-migration builds also read it
79
129
  // as an allowlist, so the entry is still seeded; on current builds it restricts nothing.
80
130
  const settings = childObject(defaults, 'models', 'agents.defaults.models');
@@ -86,14 +136,20 @@ export function openclawPatchConfig(parsed, apiUrl, model, apiKey) {
86
136
  }
87
137
  return root;
88
138
  }
89
- export const configureOpenclaw = async ({ apiUrl, model, apiKey, fs, env, }) => {
139
+ export const configureOpenclaw = async ({ apiUrl, model, apiKey, fs, env, contextLength, }) => {
90
140
  const override = env['OPENCLAW_CONFIG_PATH'];
91
141
  const path = override && override.length > 0 ? override : DEFAULT_PATH;
142
+ const gatewaySecretInEnv = ['OPENCLAW_GATEWAY_TOKEN', 'OPENCLAW_GATEWAY_PASSWORD'].some((name) => (env[name] ?? '').trim() !== '');
92
143
  // OpenClaw reads this file as JSON5, so we must parse with the same leniency or we reject configs
93
144
  // it happily accepts. Comments are dropped on write; every setting is preserved.
94
145
  const text = await fs.read(path);
95
- const parsed = text === undefined ? {} : parseJsonLenient(text, fs.absolute(path));
96
- await fs.write(path, canonicalJson(openclawPatchConfig(parsed, apiUrl, model, apiKey)));
146
+ const base = text === undefined ? {} : parseJsonLenient(text, fs.absolute(path));
147
+ openclawNormalize(base);
148
+ const patched = openclawPatchConfig(JSON.parse(JSON.stringify(base)), apiUrl, model, apiKey, contextLength, gatewaySecretInEnv);
149
+ const previous = await readBackup(fs, path);
150
+ const keys = trackKeys(base, patched, openclawTrackedPaths(`${PROVIDER_ID}/${model}`), previous?.keys ?? []);
151
+ await fs.write(path, canonicalJson(patched));
152
+ await writeBackupText(fs, path, renderBackup({ keys, seeded: [] }));
97
153
  };
98
154
  registerWriter('openclaw', configureOpenclaw);
99
155
  //# sourceMappingURL=openclaw.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"openclaw.js","sourceRoot":"","sources":["../../../src/integrations/configure/openclaw.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openclaw.js","sourceRoot":"","sources":["../../../src/integrations/configure/openclaw.ts"],"names":[],"mappings":"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"}
@@ -3,23 +3,65 @@
3
3
  *
4
4
  * All three keep one JSON file whose `provider.<id>` map names an `@ai-sdk/openai-compatible`
5
5
  * endpoint, and all three are configured by upserting a single `atomic` entry into it and then
6
- * selecting `"<providerId>/<modelId>"` as the active model. The Rust side has this logic written
7
- * out three times (`configure_opencode`, `configure_mimo`, `configure_kilo`); only four things
8
- * differ, so here it is once with those four as parameters.
6
+ * selecting `"<providerId>/<modelId>"` as the active model. Port of `opencode_family.rs` in the app,
7
+ * byte for byte.
9
8
  *
10
9
  * Everything the user already had is preserved: other providers, unrelated top-level keys, and an
11
10
  * existing `$schema`. The active model is overwritten on purpose — pressing Run is an explicit
12
- * "use this one".
11
+ * "use this one" — but what it replaces is kept in `<config file>.atomic-chat-backup.json` beside
12
+ * the file, for the app's Disconnect to put back. A value that is already ours is not kept: a
13
+ * reconnect keeps the one saved the first time.
14
+ *
15
+ * The files are read as JSON5 (comments, trailing commas), as the agents read them, and written
16
+ * back as strict JSON, which drops the comments.
13
17
  */
18
+ import type { ConfigFs, JsonValue } from '../config-io.js';
19
+ import type { JsonObject } from './json-tree.js';
14
20
  import type { ConfigureInput } from './registry.js';
15
- export interface OpencodeStyleSpec {
16
- /** Config directory relative to the home, e.g. `.config/opencode`. */
17
- dir: string;
18
- /** File name inside `dir`. Doubles as the name used in the "not a JSON object" error. */
21
+ export declare const PROVIDER_ID = "atomic";
22
+ /** The display name of our provider entry, which is also how an entry is recognised as ours. */
23
+ export declare const PROVIDER_NAME = "Atomic Chat";
24
+ /** The output cap for a window of `contextLength` tokens. */
25
+ export declare function outputCap(contextLength: number): number;
26
+ /** A known window, or `undefined` for none. */
27
+ export declare function knownWindow(contextLength: number | undefined): number | undefined;
28
+ /** One agent's config file, and the files beside it an earlier release may have written. */
29
+ export interface ConfigTarget {
30
+ /** The file Connect writes (relative to the home, or absolute). */
19
31
  file: string;
32
+ /** Read before `file`: whatever of ours is left there is removed. */
33
+ others: string[];
34
+ }
35
+ /** Kilo: `$KILO_CONFIG_DIR` (read after the global directory), else `<xdg>/kilo`; always `kilo.jsonc`. */
36
+ export declare function kiloTarget(env: NodeJS.ProcessEnv): ConfigTarget;
37
+ /** OpenCode: `$OPENCODE_CONFIG_DIR` is read last, an `$OPENCODE_CONFIG` file after the global one. */
38
+ export declare function opencodeTarget(fs: ConfigFs, env: NodeJS.ProcessEnv): Promise<ConfigTarget>;
39
+ /** MiMo: an absolute `$MIMOCODE_HOME` holds `config/` (MiMo refuses a relative one). */
40
+ export declare function mimoTarget(fs: ConfigFs, env: NodeJS.ProcessEnv): Promise<ConfigTarget>;
41
+ /** pi's agent directory: `$PI_CODING_AGENT_DIR` (a leading `~` expanded), else `.pi/agent`. */
42
+ export declare function piDir(fs: ConfigFs, env: NodeJS.ProcessEnv): string;
43
+ /** The file as a JSON object (blank or missing is `{}`); anything else is refused. */
44
+ export declare function readRoot(fs: ConfigFs, path: string, lenient: boolean): Promise<JsonObject>;
45
+ /** Set `keys` to `value`, making objects of whatever is missing or not an object on the way. */
46
+ export declare function setAt(root: JsonObject, keys: readonly string[], value: JsonValue): void;
47
+ /** A key Connect overwrites, and how to tell (from the whole root) that what it holds is ours. */
48
+ export interface Managed {
49
+ keys: readonly string[];
50
+ ours: (root: JsonObject) => boolean;
51
+ }
52
+ export declare function backupPath(config: string): string;
53
+ /**
54
+ * Before Connect writes `managed` into `root` (the file at `config` as it is now), save what they hold
55
+ * that is not ours. Nothing to save removes an earlier backup.
56
+ */
57
+ export declare function saveReplaced(fs: ConfigFs, root: JsonObject, config: string, managed: readonly Managed[]): Promise<void>;
58
+ /** Put back what Connect replaced, for each key that is still ours. Whether anything changed. */
59
+ export declare function restoreReplaced(fs: ConfigFs, root: JsonObject, config: string, managed: readonly Managed[]): Promise<boolean>;
60
+ export interface OpencodeStyleSpec {
20
61
  /** `$schema` seeded into a config that does not carry one yet. */
21
62
  schema: string;
22
- /** `.jsonc` files are read with the json5 tolerance; strict JSON files are not. */
23
- lenient: boolean;
63
+ /** A `$schema` an earlier release wrote by mistake; replaced by `schema`. */
64
+ staleSchema?: string;
24
65
  }
25
- export declare function writeOpencodeStyleConfig(input: ConfigureInput, spec: OpencodeStyleSpec): Promise<void>;
66
+ export declare function opencodeProviderEntry(input: ConfigureInput): JsonObject;
67
+ export declare function writeOpencodeStyleConfig(input: ConfigureInput, target: ConfigTarget, spec: OpencodeStyleSpec): Promise<void>;
@@ -3,41 +3,236 @@
3
3
  *
4
4
  * All three keep one JSON file whose `provider.<id>` map names an `@ai-sdk/openai-compatible`
5
5
  * endpoint, and all three are configured by upserting a single `atomic` entry into it and then
6
- * selecting `"<providerId>/<modelId>"` as the active model. The Rust side has this logic written
7
- * out three times (`configure_opencode`, `configure_mimo`, `configure_kilo`); only four things
8
- * differ, so here it is once with those four as parameters.
6
+ * selecting `"<providerId>/<modelId>"` as the active model. Port of `opencode_family.rs` in the app,
7
+ * byte for byte.
9
8
  *
10
9
  * Everything the user already had is preserved: other providers, unrelated top-level keys, and an
11
10
  * existing `$schema`. The active model is overwritten on purpose — pressing Run is an explicit
12
- * "use this one".
11
+ * "use this one" — but what it replaces is kept in `<config file>.atomic-chat-backup.json` beside
12
+ * the file, for the app's Disconnect to put back. A value that is already ours is not kept: a
13
+ * reconnect keeps the one saved the first time.
14
+ *
15
+ * The files are read as JSON5 (comments, trailing commas), as the agents read them, and written
16
+ * back as strict JSON, which drops the comments.
13
17
  */
18
+ import { basename, isAbsolute } from 'node:path';
14
19
  import { AtomicCoreError } from '../../contracts/index.js';
15
- import { canonicalJson, keyOr, parseJsonLenient, parseJsonStrict } from '../config-io.js';
20
+ import { canonicalJson, expandTilde, keyOr, parseJsonLenient, parseJsonStrict } from '../config-io.js';
16
21
  import { asJsonObject } from './json-tree.js';
17
- export async function writeOpencodeStyleConfig(input, spec) {
18
- const { fs, apiUrl, model, apiKey } = input;
19
- const path = `${spec.dir}/${spec.file}`;
20
- // The directory is created before the file is read, so a parse failure below still leaves it —
21
- // matching `create_dir_all` sitting above the read in the Rust writers.
22
- await fs.mkdirp(spec.dir);
22
+ export const PROVIDER_ID = 'atomic';
23
+ /** The display name of our provider entry, which is also how an entry is recognised as ours. */
24
+ export const PROVIDER_NAME = 'Atomic Chat';
25
+ const BACKUP_SUFFIX = '.atomic-chat-backup.json';
26
+ const BACKUP_ABOUT = 'Atomic Chat keeps the settings its connection replaced here and puts them back on Disconnect.';
27
+ /** The longest reply an agent asks for: a quarter of the window, at most this. */
28
+ const OUTPUT_CAP = 8192;
29
+ /** The output cap for a window of `contextLength` tokens. */
30
+ export function outputCap(contextLength) {
31
+ return Math.min(OUTPUT_CAP, Math.floor(contextLength / 4));
32
+ }
33
+ /** A known window, or `undefined` for none. */
34
+ export function knownWindow(contextLength) {
35
+ return contextLength !== undefined && contextLength > 0 ? Math.floor(contextLength) : undefined;
36
+ }
37
+ // ── where the configs live ──────────────────────────────────────────────────────────────────────
38
+ function envValue(env, name) {
39
+ const value = env[name];
40
+ return value !== undefined && value.trim() !== '' ? value : undefined;
41
+ }
42
+ /** `$XDG_CONFIG_HOME`, else `.config` under the home — on every OS, as `xdg-basedir` resolves it. */
43
+ function xdgConfigHome(env) {
44
+ return envValue(env, 'XDG_CONFIG_HOME') ?? '.config';
45
+ }
46
+ /** `<stem>.jsonc` when it exists — read after `<stem>.json`, so it wins — else `<stem>.json`. */
47
+ async function dirTarget(fs, dir, stem) {
48
+ const json = `${dir}/${stem}.json`;
49
+ const jsonc = `${dir}/${stem}.jsonc`;
50
+ return (await fs.exists(jsonc)) ? { file: jsonc, others: [json] } : { file: json, others: [] };
51
+ }
52
+ /** Kilo: `$KILO_CONFIG_DIR` (read after the global directory), else `<xdg>/kilo`; always `kilo.jsonc`. */
53
+ export function kiloTarget(env) {
54
+ const dir = envValue(env, 'KILO_CONFIG_DIR') ?? `${xdgConfigHome(env)}/kilo`;
55
+ return { file: `${dir}/kilo.jsonc`, others: [] };
56
+ }
57
+ /** OpenCode: `$OPENCODE_CONFIG_DIR` is read last, an `$OPENCODE_CONFIG` file after the global one. */
58
+ export async function opencodeTarget(fs, env) {
59
+ const dir = envValue(env, 'OPENCODE_CONFIG_DIR');
60
+ if (dir)
61
+ return dirTarget(fs, dir, 'opencode');
62
+ const file = envValue(env, 'OPENCODE_CONFIG');
63
+ if (file)
64
+ return { file, others: [] };
65
+ return dirTarget(fs, `${xdgConfigHome(env)}/opencode`, 'opencode');
66
+ }
67
+ /** MiMo: an absolute `$MIMOCODE_HOME` holds `config/` (MiMo refuses a relative one). */
68
+ export async function mimoTarget(fs, env) {
69
+ const home = envValue(env, 'MIMOCODE_HOME');
70
+ return dirTarget(fs, home !== undefined && isAbsolute(home) ? `${home}/config` : `${xdgConfigHome(env)}/mimocode`, 'mimocode');
71
+ }
72
+ /** pi's agent directory: `$PI_CODING_AGENT_DIR` (a leading `~` expanded), else `.pi/agent`. */
73
+ export function piDir(fs, env) {
74
+ const dir = envValue(env, 'PI_CODING_AGENT_DIR');
75
+ return dir ? expandTilde(dir, fs.home) : '.pi/agent';
76
+ }
77
+ // ── JSON in place ───────────────────────────────────────────────────────────────────────────────
78
+ /** The file as a JSON object (blank or missing is `{}`); anything else is refused. */
79
+ export async function readRoot(fs, path, lenient) {
23
80
  const text = await fs.read(path);
24
- const parse = spec.lenient ? parseJsonLenient : parseJsonStrict;
81
+ const parse = lenient ? parseJsonLenient : parseJsonStrict;
25
82
  const parsed = text === undefined ? {} : parse(text, fs.absolute(path));
26
83
  const root = asJsonObject(parsed);
27
84
  if (!root)
28
- throw new AtomicCoreError('IO_ERROR', `${spec.file} is not a JSON object`);
29
- // `entry(..).or_insert_with(..)`: an existing `$schema` wins, even an explicit `null`.
30
- if (!('$schema' in root))
31
- root['$schema'] = spec.schema;
32
- const provider = asJsonObject(root['provider']) ?? {};
33
- root['provider'] = provider;
34
- provider['atomic'] = {
35
- name: 'Atomic Chat',
85
+ throw new AtomicCoreError('IO_ERROR', `${basename(path)} is not a JSON object`);
86
+ return root;
87
+ }
88
+ function at(root, keys) {
89
+ let node = root;
90
+ for (const key of keys) {
91
+ const obj = asJsonObject(node);
92
+ if (!obj || !(key in obj))
93
+ return undefined;
94
+ node = obj[key];
95
+ }
96
+ return node;
97
+ }
98
+ /** Set `keys` to `value`, making objects of whatever is missing or not an object on the way. */
99
+ export function setAt(root, keys, value) {
100
+ let node = root;
101
+ for (const key of keys.slice(0, -1)) {
102
+ let next = asJsonObject(node[key]);
103
+ if (!next) {
104
+ next = {};
105
+ node[key] = next;
106
+ }
107
+ node = next;
108
+ }
109
+ node[keys[keys.length - 1]] = value;
110
+ }
111
+ function removeAt(root, keys) {
112
+ const parent = asJsonObject(at(root, keys.slice(0, -1)));
113
+ if (parent)
114
+ delete parent[keys[keys.length - 1]];
115
+ }
116
+ export function backupPath(config) {
117
+ return `${config}${BACKUP_SUFFIX}`;
118
+ }
119
+ async function savedValues(fs, config) {
120
+ const text = await fs.read(backupPath(config));
121
+ if (text === undefined)
122
+ return {};
123
+ try {
124
+ return asJsonObject(asJsonObject(JSON.parse(text))?.['previous']) ?? {};
125
+ }
126
+ catch {
127
+ return {};
128
+ }
129
+ }
130
+ /**
131
+ * Before Connect writes `managed` into `root` (the file at `config` as it is now), save what they hold
132
+ * that is not ours. Nothing to save removes an earlier backup.
133
+ */
134
+ export async function saveReplaced(fs, root, config, managed) {
135
+ const saved = await savedValues(fs, config);
136
+ const previous = {};
137
+ for (const m of managed) {
138
+ const current = at(root, m.keys);
139
+ if (current === undefined)
140
+ continue;
141
+ // Ours from an earlier Connect: what that one saved still stands.
142
+ const kept = m.ours(root) ? at(saved, m.keys) : current;
143
+ if (kept !== undefined)
144
+ setAt(previous, m.keys, kept);
145
+ }
146
+ if (Object.keys(previous).length === 0) {
147
+ await fs.remove(backupPath(config));
148
+ return;
149
+ }
150
+ await fs.write(backupPath(config), canonicalJson({ about: BACKUP_ABOUT, previous }));
151
+ }
152
+ /** Put back what Connect replaced, for each key that is still ours. Whether anything changed. */
153
+ export async function restoreReplaced(fs, root, config, managed) {
154
+ const saved = await savedValues(fs, config);
155
+ // Judge every key before touching any: a pair is judged together.
156
+ const ours = managed.map((m) => at(root, m.keys) !== undefined && m.ours(root));
157
+ let changed = false;
158
+ managed.forEach((m, i) => {
159
+ if (!ours[i])
160
+ return;
161
+ const previous = at(saved, m.keys);
162
+ if (previous !== undefined)
163
+ setAt(root, m.keys, previous);
164
+ else
165
+ removeAt(root, m.keys);
166
+ changed = true;
167
+ });
168
+ return changed;
169
+ }
170
+ const OPENCODE_MANAGED = [
171
+ {
172
+ keys: ['model'],
173
+ ours: (root) => typeof root['model'] === 'string' && root['model'].startsWith(`${PROVIDER_ID}/`),
174
+ },
175
+ {
176
+ keys: ['provider', PROVIDER_ID],
177
+ ours: (root) => at(root, ['provider', PROVIDER_ID, 'name']) === PROVIDER_NAME,
178
+ },
179
+ ];
180
+ /**
181
+ * The `models.<id>` entry: thinking models answer in `reasoning_content`, which the agent then shows
182
+ * as thoughts and sends back within a tool loop (a model that does not think sends an empty one,
183
+ * which servers drop); the window and output cap when known, without which the agent never compacts
184
+ * and asks for 32K tokens per reply.
185
+ */
186
+ function modelEntry(model, contextLength) {
187
+ const entry = { name: model, reasoning: true, interleaved: { field: 'reasoning_content' } };
188
+ const ctx = knownWindow(contextLength);
189
+ if (ctx !== undefined)
190
+ entry['limit'] = { context: ctx, output: outputCap(ctx) };
191
+ return entry;
192
+ }
193
+ export function opencodeProviderEntry(input) {
194
+ const { apiUrl, model, apiKey, contextLength } = input;
195
+ return {
196
+ name: PROVIDER_NAME,
36
197
  npm: '@ai-sdk/openai-compatible',
37
- options: { baseURL: apiUrl, apiKey: keyOr(apiKey, 'atomic') },
38
- models: { [model]: { name: model } },
198
+ // A local model can read a long prompt for longer than the 5 minutes these agents wait for the
199
+ // first byte, and then they give up.
200
+ options: { baseURL: apiUrl, apiKey: keyOr(apiKey, 'atomic'), timeout: false, headerTimeout: false },
201
+ models: { [model]: modelEntry(model, contextLength) },
39
202
  };
40
- root['model'] = `atomic/${model}`;
203
+ }
204
+ export async function writeOpencodeStyleConfig(input, target, spec) {
205
+ const { fs, model } = input;
206
+ const path = target.file;
207
+ // The directory is created before the file is read, so a parse failure below still leaves it —
208
+ // matching `create_dir_all` sitting above the read in the Rust writer.
209
+ const slash = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
210
+ if (slash > 0)
211
+ await fs.mkdirp(path.slice(0, slash));
212
+ const root = await readRoot(fs, path, true);
213
+ await saveReplaced(fs, root, path, OPENCODE_MANAGED);
214
+ const schema = root['$schema'];
215
+ if (!('$schema' in root) || (spec.staleSchema !== undefined && schema === spec.staleSchema)) {
216
+ root['$schema'] = spec.schema;
217
+ }
218
+ setAt(root, ['provider', PROVIDER_ID], opencodeProviderEntry(input));
219
+ root['model'] = `${PROVIDER_ID}/${model}`;
41
220
  await fs.write(path, canonicalJson(root));
221
+ for (const other of target.others)
222
+ await removeOurs(fs, other);
223
+ }
224
+ /** Take our entries out of a file Connect does not write; one it cannot read is left as it is. */
225
+ async function removeOurs(fs, path) {
226
+ if ((await fs.read(path)) === undefined)
227
+ return;
228
+ let root;
229
+ try {
230
+ root = await readRoot(fs, path, true);
231
+ }
232
+ catch {
233
+ return;
234
+ }
235
+ if (await restoreReplaced(fs, root, path, OPENCODE_MANAGED))
236
+ await fs.write(path, canonicalJson(root));
42
237
  }
43
238
  //# sourceMappingURL=opencode-style.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-style.js","sourceRoot":"","sources":["../../../src/integrations/configure/opencode-style.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACzF,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAc7C,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,KAAqB,EACrB,IAAuB;IAEvB,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;IAC3C,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAA;IACvC,+FAA+F;IAC/F,wEAAwE;IACxE,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAEzB,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAChC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,eAAe,CAAA;IAC/D,MAAM,MAAM,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;IACvE,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;IACjC,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,eAAe,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,IAAI,uBAAuB,CAAC,CAAA;IAErF,uFAAuF;IACvF,IAAI,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC;QAAE,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,CAAA;IAEvD,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAA;IACrD,IAAI,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAA;IAC3B,QAAQ,CAAC,QAAQ,CAAC,GAAG;QACnB,IAAI,EAAE,aAAa;QACnB,GAAG,EAAE,2BAA2B;QAChC,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;QAC7D,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;KACrC,CAAA;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,UAAU,KAAK,EAAE,CAAA;IAEjC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC,CAAA;AAC3C,CAAC"}
1
+ {"version":3,"file":"opencode-style.js","sourceRoot":"","sources":["../../../src/integrations/configure/opencode-style.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,10 @@
1
1
  /**
2
- * OpenCode — `~/.config/opencode/opencode.json`.
2
+ * OpenCode — `opencode.jsonc` when there is one, else `opencode.json`, in `$OPENCODE_CONFIG_DIR`,
3
+ * else the `$OPENCODE_CONFIG` file, else `~/.config/opencode`.
3
4
  *
4
- * Port of `configure_opencode` in `src-tauri/src/core/system/commands.rs`. Strict JSON: a file the
5
- * parser rejects is a hard error and nothing is written, so a typo in the user's config is
6
- * reported instead of being overwritten.
5
+ * Port of `configure_opencode` in `src-tauri/src/core/system/commands.rs`. A file the parser rejects
6
+ * is a hard error and nothing is written, so a typo in the user's config is reported instead of
7
+ * being overwritten.
7
8
  */
8
9
  import type { ConfigureInput } from './registry.js';
9
10
  export declare function configureOpencode(input: ConfigureInput): Promise<void>;
@@ -1,18 +1,16 @@
1
1
  /**
2
- * OpenCode — `~/.config/opencode/opencode.json`.
2
+ * OpenCode — `opencode.jsonc` when there is one, else `opencode.json`, in `$OPENCODE_CONFIG_DIR`,
3
+ * else the `$OPENCODE_CONFIG` file, else `~/.config/opencode`.
3
4
  *
4
- * Port of `configure_opencode` in `src-tauri/src/core/system/commands.rs`. Strict JSON: a file the
5
- * parser rejects is a hard error and nothing is written, so a typo in the user's config is
6
- * reported instead of being overwritten.
5
+ * Port of `configure_opencode` in `src-tauri/src/core/system/commands.rs`. A file the parser rejects
6
+ * is a hard error and nothing is written, so a typo in the user's config is reported instead of
7
+ * being overwritten.
7
8
  */
8
9
  import { registerWriter } from './registry.js';
9
- import { writeOpencodeStyleConfig } from './opencode-style.js';
10
- export function configureOpencode(input) {
11
- return writeOpencodeStyleConfig(input, {
12
- dir: '.config/opencode',
13
- file: 'opencode.json',
10
+ import { opencodeTarget, writeOpencodeStyleConfig } from './opencode-style.js';
11
+ export async function configureOpencode(input) {
12
+ return writeOpencodeStyleConfig(input, await opencodeTarget(input.fs, input.env), {
14
13
  schema: 'https://opencode.ai/config.json',
15
- lenient: false,
16
14
  });
17
15
  }
18
16
  registerWriter('opencode', configureOpencode);
@@ -1 +1 @@
1
- {"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../../src/integrations/configure/opencode.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAE9D,MAAM,UAAU,iBAAiB,CAAC,KAAqB;IACrD,OAAO,wBAAwB,CAAC,KAAK,EAAE;QACrC,GAAG,EAAE,kBAAkB;QACvB,IAAI,EAAE,eAAe;QACrB,MAAM,EAAE,iCAAiC;QACzC,OAAO,EAAE,KAAK;KACf,CAAC,CAAA;AACJ,CAAC;AAED,cAAc,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAA"}
1
+ {"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../../src/integrations/configure/opencode.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAE9E,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,KAAqB;IAC3D,OAAO,wBAAwB,CAAC,KAAK,EAAE,MAAM,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE;QAChF,MAAM,EAAE,iCAAiC;KAC1C,CAAC,CAAA;AACJ,CAAC;AAED,cAAc,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAA"}
@@ -1,8 +1,9 @@
1
1
  /**
2
- * OpenHands reads env overrides only when launched with `--override-with-envs`, using
3
- * `LLM_API_KEY` / `LLM_BASE_URL` / `LLM_MODEL`. The litellm `openai/` prefix on the model id is
4
- * required for a custom OpenAI-compatible base URL — without it litellm resolves the id against its
5
- * own model registry and fails before the request leaves the process.
2
+ * OpenHands reads `LLM_API_KEY` / `LLM_BASE_URL` / `LLM_MODEL` only when launched with
3
+ * `--override-with-envs`, and `launch` sets them on the child (`childEnv`). The litellm `openai/`
4
+ * prefix on the model id is required for a custom OpenAI-compatible base URL — without it litellm
5
+ * resolves the id against its own model registry and fails before the request leaves the process.
6
+ * Nothing is persisted; Connect only removes what an older release did (`legacy-env-block.ts`).
6
7
  */
7
8
  import type { ConfigureWriter } from './registry.js';
8
9
  export declare const configureOpenhands: ConfigureWriter;