@atomic-chat/core 0.19.1 → 0.20.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-daemon.js +5 -0
- package/dist/app-daemon.js.map +1 -1
- package/dist/audio/args.d.ts +19 -0
- package/dist/audio/args.js +39 -0
- package/dist/audio/args.js.map +1 -0
- package/dist/audio/capabilities.d.ts +24 -0
- package/dist/audio/capabilities.js +96 -0
- package/dist/audio/capabilities.js.map +1 -0
- package/dist/audio/config.d.ts +40 -0
- package/dist/audio/config.js +57 -0
- package/dist/audio/config.js.map +1 -0
- package/dist/audio/errors.d.ts +23 -0
- package/dist/audio/errors.js +52 -0
- package/dist/audio/errors.js.map +1 -0
- package/dist/audio/gallery.d.ts +30 -0
- package/dist/audio/gallery.js +152 -0
- package/dist/audio/gallery.js.map +1 -0
- package/dist/audio/http.d.ts +26 -0
- package/dist/audio/http.js +56 -0
- package/dist/audio/http.js.map +1 -0
- package/dist/audio/idle.d.ts +22 -0
- package/dist/audio/idle.js +44 -0
- package/dist/audio/idle.js.map +1 -0
- package/dist/audio/index.d.ts +26 -0
- package/dist/audio/index.js +27 -0
- package/dist/audio/index.js.map +1 -0
- package/dist/audio/install.d.ts +57 -0
- package/dist/audio/install.js +196 -0
- package/dist/audio/install.js.map +1 -0
- package/dist/audio/jobs.d.ts +77 -0
- package/dist/audio/jobs.js +340 -0
- package/dist/audio/jobs.js.map +1 -0
- package/dist/audio/model-files.d.ts +12 -0
- package/dist/audio/model-files.js +42 -0
- package/dist/audio/model-files.js.map +1 -0
- package/dist/audio/output.d.ts +32 -0
- package/dist/audio/output.js +93 -0
- package/dist/audio/output.js.map +1 -0
- package/dist/audio/parse.d.ts +15 -0
- package/dist/audio/parse.js +149 -0
- package/dist/audio/parse.js.map +1 -0
- package/dist/audio/recipe.d.ts +22 -0
- package/dist/audio/recipe.js +92 -0
- package/dist/audio/recipe.js.map +1 -0
- package/dist/audio/request.d.ts +24 -0
- package/dist/audio/request.js +86 -0
- package/dist/audio/request.js.map +1 -0
- package/dist/audio/server-process.d.ts +51 -0
- package/dist/audio/server-process.js +202 -0
- package/dist/audio/server-process.js.map +1 -0
- package/dist/audio/service.d.ts +107 -0
- package/dist/audio/service.js +402 -0
- package/dist/audio/service.js.map +1 -0
- package/dist/audio/session.d.ts +73 -0
- package/dist/audio/session.js +216 -0
- package/dist/audio/session.js.map +1 -0
- package/dist/audio/state.d.ts +68 -0
- package/dist/audio/state.js +88 -0
- package/dist/audio/state.js.map +1 -0
- package/dist/audio/types.d.ts +52 -0
- package/dist/audio/types.js +8 -0
- package/dist/audio/types.js.map +1 -0
- package/dist/audio/wav.d.ts +22 -0
- package/dist/audio/wav.js +56 -0
- package/dist/audio/wav.js.map +1 -0
- package/dist/audio/wiring.d.ts +31 -0
- package/dist/audio/wiring.js +41 -0
- package/dist/audio/wiring.js.map +1 -0
- package/dist/backend/install/service.js +4 -2
- package/dist/backend/install/service.js.map +1 -1
- package/dist/cli/launch.js +2 -0
- package/dist/cli/launch.js.map +1 -1
- package/dist/cli/main.d.ts +1 -1
- package/dist/cli/main.js +5 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/client/control-client.d.ts +21 -1
- package/dist/client/control-client.js +50 -0
- package/dist/client/control-client.js.map +1 -1
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.js +1 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/model-catalog.d.ts +40 -0
- package/dist/client/model-catalog.js +149 -0
- package/dist/client/model-catalog.js.map +1 -0
- package/dist/cloud/registry.js +1 -0
- package/dist/cloud/registry.js.map +1 -1
- package/dist/config/paths.d.ts +22 -1
- package/dist/config/paths.js +24 -0
- package/dist/config/paths.js.map +1 -1
- package/dist/contracts/audio.d.ts +290 -0
- package/dist/contracts/audio.js +24 -0
- package/dist/contracts/audio.js.map +1 -0
- package/dist/contracts/embedding.js +1 -0
- package/dist/contracts/embedding.js.map +1 -1
- package/dist/contracts/engine-builds.d.ts +10 -4
- package/dist/contracts/engine-builds.js +10 -2
- package/dist/contracts/engine-builds.js.map +1 -1
- package/dist/contracts/engines.d.ts +1 -1
- package/dist/contracts/engines.js +4 -0
- package/dist/contracts/engines.js.map +1 -1
- package/dist/contracts/errors.d.ts +14 -2
- package/dist/contracts/errors.js +29 -0
- package/dist/contracts/errors.js.map +1 -1
- package/dist/contracts/events.d.ts +10 -0
- package/dist/contracts/geniex.d.ts +98 -0
- package/dist/contracts/geniex.js +15 -0
- package/dist/contracts/geniex.js.map +1 -0
- package/dist/contracts/index.d.ts +2 -0
- package/dist/contracts/index.js +2 -0
- package/dist/contracts/index.js.map +1 -1
- package/dist/contracts/model-yml.d.ts +40 -0
- package/dist/contracts/model-yml.js +7 -0
- package/dist/contracts/model-yml.js.map +1 -1
- package/dist/contracts/session.d.ts +6 -1
- package/dist/contracts/session.js.map +1 -1
- package/dist/contracts/settings.d.ts +12 -1
- package/dist/contracts/settings.js.map +1 -1
- package/dist/core/atomic-core.d.ts +6 -1
- package/dist/core/atomic-core.js +7 -1
- package/dist/core/atomic-core.js.map +1 -1
- package/dist/core/create.js +105 -6
- package/dist/core/create.js.map +1 -1
- package/dist/core/gpu-residency.d.ts +8 -2
- package/dist/core/gpu-residency.js +9 -1
- package/dist/core/gpu-residency.js.map +1 -1
- package/dist/core/types.d.ts +3 -0
- package/dist/core/types.js.map +1 -1
- package/dist/diffusion/install.d.ts +6 -3
- package/dist/diffusion/install.js +5 -4
- package/dist/diffusion/install.js.map +1 -1
- package/dist/embedding/index.js +1 -0
- package/dist/embedding/index.js.map +1 -1
- package/dist/engine-builds/engines.d.ts +31 -8
- package/dist/engine-builds/engines.js +118 -14
- package/dist/engine-builds/engines.js.map +1 -1
- package/dist/engine-builds/geniex.d.ts +35 -0
- package/dist/engine-builds/geniex.js +111 -0
- package/dist/engine-builds/geniex.js.map +1 -0
- package/dist/engine-builds/index.d.ts +3 -2
- package/dist/engine-builds/index.js +3 -2
- package/dist/engine-builds/index.js.map +1 -1
- package/dist/engine-builds/manifest.d.ts +95 -5
- package/dist/engine-builds/manifest.js +152 -9
- package/dist/engine-builds/manifest.js.map +1 -1
- package/dist/engine-builds/order.d.ts +7 -1
- package/dist/engine-builds/order.js +13 -0
- package/dist/engine-builds/order.js.map +1 -1
- package/dist/engine-builds/select.d.ts +43 -11
- package/dist/engine-builds/select.js +64 -16
- package/dist/engine-builds/select.js.map +1 -1
- package/dist/engine-builds/service.d.ts +19 -11
- package/dist/engine-builds/service.js +31 -9
- package/dist/engine-builds/service.js.map +1 -1
- package/dist/engines/service.d.ts +4 -3
- package/dist/engines/service.js +5 -3
- package/dist/engines/service.js.map +1 -1
- package/dist/engines/versions.js +3 -0
- package/dist/engines/versions.js.map +1 -1
- package/dist/integrations/catalog.d.ts +3 -1
- package/dist/integrations/catalog.js +8 -2
- package/dist/integrations/catalog.js.map +1 -1
- package/dist/integrations/config-io.d.ts +45 -4
- package/dist/integrations/config-io.js +91 -6
- package/dist/integrations/config-io.js.map +1 -1
- package/dist/integrations/configure/codex-repair.d.ts +75 -0
- package/dist/integrations/configure/codex-repair.js +254 -0
- package/dist/integrations/configure/codex-repair.js.map +1 -0
- package/dist/integrations/configure/codex.d.ts +48 -10
- package/dist/integrations/configure/codex.js +126 -32
- package/dist/integrations/configure/codex.js.map +1 -1
- package/dist/integrations/configure/registry.d.ts +4 -1
- package/dist/integrations/configure/registry.js +1 -0
- package/dist/integrations/configure/registry.js.map +1 -1
- package/dist/lock/process-journal.d.ts +3 -3
- package/dist/models/compatibility/rules-baseline.js +1 -0
- package/dist/models/compatibility/rules-baseline.js.map +1 -1
- package/dist/models/compatibility/rules.js +1 -0
- package/dist/models/compatibility/rules.js.map +1 -1
- package/dist/models/gguf/kv-cache.d.ts +5 -0
- package/dist/models/gguf/kv-cache.js +35 -2
- package/dist/models/gguf/kv-cache.js.map +1 -1
- package/dist/models/gguf/reader.d.ts +5 -0
- package/dist/models/gguf/reader.js +15 -3
- package/dist/models/gguf/reader.js.map +1 -1
- package/dist/models/hf.d.ts +3 -0
- package/dist/models/hf.js +11 -4
- package/dist/models/hf.js.map +1 -1
- package/dist/router/resolve.d.ts +3 -2
- package/dist/router/resolve.js +3 -1
- package/dist/router/resolve.js.map +1 -1
- package/dist/runtime/geniex/accelerators.d.ts +20 -0
- package/dist/runtime/geniex/accelerators.js +53 -0
- package/dist/runtime/geniex/accelerators.js.map +1 -0
- package/dist/runtime/geniex/check.d.ts +34 -0
- package/dist/runtime/geniex/check.js +117 -0
- package/dist/runtime/geniex/check.js.map +1 -0
- package/dist/runtime/geniex/chip.d.ts +29 -0
- package/dist/runtime/geniex/chip.js +35 -0
- package/dist/runtime/geniex/chip.js.map +1 -0
- package/dist/runtime/geniex/devices.d.ts +13 -0
- package/dist/runtime/geniex/devices.js +32 -0
- package/dist/runtime/geniex/devices.js.map +1 -0
- package/dist/runtime/geniex/geniex-host.d.ts +17 -0
- package/dist/runtime/geniex/geniex-host.js +26 -0
- package/dist/runtime/geniex/geniex-host.js.map +1 -0
- package/dist/runtime/geniex/host/args.d.ts +56 -0
- package/dist/runtime/geniex/host/args.js +115 -0
- package/dist/runtime/geniex/host/args.js.map +1 -0
- package/dist/runtime/geniex/host/engine.d.ts +76 -0
- package/dist/runtime/geniex/host/engine.js +122 -0
- package/dist/runtime/geniex/host/engine.js.map +1 -0
- package/dist/runtime/geniex/host/ffi-bun.d.ts +15 -0
- package/dist/runtime/geniex/host/ffi-bun.js +415 -0
- package/dist/runtime/geniex/host/ffi-bun.js.map +1 -0
- package/dist/runtime/geniex/host/grammar.d.ts +11 -0
- package/dist/runtime/geniex/host/grammar.js +223 -0
- package/dist/runtime/geniex/host/grammar.js.map +1 -0
- package/dist/runtime/geniex/host/inspect.d.ts +25 -0
- package/dist/runtime/geniex/host/inspect.js +177 -0
- package/dist/runtime/geniex/host/inspect.js.map +1 -0
- package/dist/runtime/geniex/host/library.d.ts +117 -0
- package/dist/runtime/geniex/host/library.js +38 -0
- package/dist/runtime/geniex/host/library.js.map +1 -0
- package/dist/runtime/geniex/host/openai.d.ts +62 -0
- package/dist/runtime/geniex/host/openai.js +458 -0
- package/dist/runtime/geniex/host/openai.js.map +1 -0
- package/dist/runtime/geniex/host/run.d.ts +48 -0
- package/dist/runtime/geniex/host/run.js +208 -0
- package/dist/runtime/geniex/host/run.js.map +1 -0
- package/dist/runtime/geniex/host/server.d.ts +39 -0
- package/dist/runtime/geniex/host/server.js +232 -0
- package/dist/runtime/geniex/host/server.js.map +1 -0
- package/dist/runtime/geniex/host/worker-protocol.d.ts +76 -0
- package/dist/runtime/geniex/host/worker-protocol.js +116 -0
- package/dist/runtime/geniex/host/worker-protocol.js.map +1 -0
- package/dist/runtime/geniex/host/worker-source.generated.d.ts +1 -0
- package/dist/runtime/geniex/host/worker-source.generated.js +4 -0
- package/dist/runtime/geniex/host/worker-source.generated.js.map +1 -0
- package/dist/runtime/geniex/host/worker.d.ts +7 -0
- package/dist/runtime/geniex/host/worker.js +19 -0
- package/dist/runtime/geniex/host/worker.js.map +1 -0
- package/dist/runtime/geniex/host-process.d.ts +48 -0
- package/dist/runtime/geniex/host-process.js +104 -0
- package/dist/runtime/geniex/host-process.js.map +1 -0
- package/dist/runtime/geniex/index.d.ts +11 -0
- package/dist/runtime/geniex/index.js +12 -0
- package/dist/runtime/geniex/index.js.map +1 -0
- package/dist/runtime/geniex/model-yml.d.ts +8 -0
- package/dist/runtime/geniex/model-yml.js +98 -0
- package/dist/runtime/geniex/model-yml.js.map +1 -0
- package/dist/runtime/geniex/runtime.d.ts +94 -0
- package/dist/runtime/geniex/runtime.js +366 -0
- package/dist/runtime/geniex/runtime.js.map +1 -0
- package/dist/runtime/litert-lm/host/openai.d.ts +4 -37
- package/dist/runtime/litert-lm/host/openai.js +11 -96
- package/dist/runtime/litert-lm/host/openai.js.map +1 -1
- package/dist/runtime/litert-lm/host/pool.d.ts +1 -7
- package/dist/runtime/litert-lm/host/pool.js +1 -17
- package/dist/runtime/litert-lm/host/pool.js.map +1 -1
- package/dist/runtime/litert-lm/host/server.js +11 -53
- package/dist/runtime/litert-lm/host/server.js.map +1 -1
- package/dist/runtime/llamacpp/args.d.ts +5 -0
- package/dist/runtime/llamacpp/args.js +2 -0
- package/dist/runtime/llamacpp/args.js.map +1 -1
- package/dist/runtime/llamacpp/fit-margin.d.ts +44 -0
- package/dist/runtime/llamacpp/fit-margin.js +50 -0
- package/dist/runtime/llamacpp/fit-margin.js.map +1 -1
- package/dist/runtime/llamacpp/load-plan.d.ts +5 -0
- package/dist/runtime/llamacpp/load-plan.js +57 -22
- package/dist/runtime/llamacpp/load-plan.js.map +1 -1
- package/dist/runtime/llamacpp/runtime.d.ts +2 -1
- package/dist/runtime/llamacpp/runtime.js +3 -1
- package/dist/runtime/llamacpp/runtime.js.map +1 -1
- package/dist/runtime/shared/external-sessions.js +1 -0
- package/dist/runtime/shared/external-sessions.js.map +1 -1
- package/dist/runtime/shared/fifo-lock.d.ts +10 -0
- package/dist/runtime/shared/fifo-lock.js +21 -0
- package/dist/runtime/shared/fifo-lock.js.map +1 -0
- package/dist/runtime/shared/index.d.ts +2 -0
- package/dist/runtime/shared/index.js +2 -0
- package/dist/runtime/shared/index.js.map +1 -1
- package/dist/runtime/shared/openai-sse.d.ts +112 -0
- package/dist/runtime/shared/openai-sse.js +178 -0
- package/dist/runtime/shared/openai-sse.js.map +1 -0
- package/dist/server/control/index.d.ts +1 -1
- package/dist/server/control/router.js +4 -0
- package/dist/server/control/router.js.map +1 -1
- package/dist/server/control/routes/audio.d.ts +15 -0
- package/dist/server/control/routes/audio.js +59 -0
- package/dist/server/control/routes/audio.js.map +1 -0
- package/dist/server/control/routes/geniex.d.ts +7 -0
- package/dist/server/control/routes/geniex.js +22 -0
- package/dist/server/control/routes/geniex.js.map +1 -0
- package/dist/server/control/types.d.ts +36 -2
- package/dist/server/control/types.js.map +1 -1
- package/dist/server/http.js +4 -0
- package/dist/server/http.js.map +1 -1
- package/dist/server/public/audio-speech-params.d.ts +47 -0
- package/dist/server/public/audio-speech-params.js +177 -0
- package/dist/server/public/audio-speech-params.js.map +1 -0
- package/dist/server/public/audio-speech.d.ts +14 -0
- package/dist/server/public/audio-speech.js +118 -0
- package/dist/server/public/audio-speech.js.map +1 -0
- package/dist/server/public/embedding.d.ts +8 -7
- package/dist/server/public/embedding.js +15 -7
- package/dist/server/public/embedding.js.map +1 -1
- package/dist/server/public/forward.js +15 -1
- package/dist/server/public/forward.js.map +1 -1
- package/dist/server/public/index.d.ts +1 -1
- package/dist/server/public/index.js +7 -0
- package/dist/server/public/index.js.map +1 -1
- package/dist/server/public/listing.js +1 -0
- package/dist/server/public/listing.js.map +1 -1
- package/dist/server/public/responses.js +9 -0
- package/dist/server/public/responses.js.map +1 -1
- package/dist/server/public/trace.js +2 -0
- package/dist/server/public/trace.js.map +1 -1
- package/dist/server/public/types.d.ts +29 -1
- package/dist/server/public/validate.d.ts +32 -0
- package/dist/server/public/validate.js +146 -0
- package/dist/server/public/validate.js.map +1 -0
- package/dist/settings/schema/geniex.json +63 -0
- package/dist/settings/schema/mlx.json +1 -1
- package/dist/settings/schema.js +11 -0
- package/dist/settings/schema.js.map +1 -1
- package/dist/telemetry/reports.d.ts +12 -0
- package/dist/telemetry/reports.js +38 -0
- package/dist/telemetry/reports.js.map +1 -1
- package/dist/telemetry/subscribe.d.ts +3 -3
- package/dist/telemetry/subscribe.js +8 -3
- package/dist/telemetry/subscribe.js.map +1 -1
- package/dist/telemetry/types.d.ts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +11 -2
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Undo what earlier Atomic Chat versions wrote into Codex's shared `config.toml`.
|
|
3
|
+
*
|
|
4
|
+
* Until the profile file (`codex.ts`), the Codex writer edited `<codex_home>/config.toml` itself,
|
|
5
|
+
* inside `# >>> Atomic Chat (managed) >>>` … `# <<< Atomic Chat (managed) <<<` regions. V1 (the first
|
|
6
|
+
* Launch page) appended one region: `[model_providers.atomic]` and `[profiles.atomic]`. V2 kept two:
|
|
7
|
+
* root `model` + `model_provider = "atomic"` at the very top, `[model_providers.atomic]` at the end.
|
|
8
|
+
* V2 is the incident: a user with a root `model` of their own got a duplicate key, and Codex — the CLI
|
|
9
|
+
* and the ChatGPT desktop app, which share the file — refused to start until it was fixed by hand.
|
|
10
|
+
*
|
|
11
|
+
* Deleting text from a file that is not ours is safe only for text we can prove is ours, so this is
|
|
12
|
+
* strict where it could be clever. A marker counts only as a whole line; the regions must pair up;
|
|
13
|
+
* each must parse on its own and hold nothing but keys some version wrote, with the values it wrote;
|
|
14
|
+
* the file without them must still parse; and it must not have changed since it was read. Anything
|
|
15
|
+
* else is a conflict: the file stays byte for byte as it was, and the message names it and says which
|
|
16
|
+
* lines to remove by hand. A repair keeps a backup of the original (never over an earlier one) and
|
|
17
|
+
* writes atomically with the file's own permission bits. A `config.toml` that is a symbolic link (a
|
|
18
|
+
* dotfile manager's) is written through: the temp file and the rename happen beside the real file,
|
|
19
|
+
* which gets the new text while the link stays a link; the backup still goes next to the link.
|
|
20
|
+
*
|
|
21
|
+
* The algorithm is shared with the desktop app, which runs it at startup and on disconnect; both
|
|
22
|
+
* sides must reach the same decision on the same bytes
|
|
23
|
+
* (ADR 2026-10-27-codex-runs-on-a-profile-of-its-own).
|
|
24
|
+
*/
|
|
25
|
+
import { join } from 'node:path';
|
|
26
|
+
import { parse as parseToml } from 'smol-toml';
|
|
27
|
+
import { AtomicCoreError } from '../../contracts/index.js';
|
|
28
|
+
import { ATOMIC_MANAGED_BEGIN, ATOMIC_MANAGED_END } from '../config-io.js';
|
|
29
|
+
const ROOT_KEYS = new Set(['model', 'model_provider', 'model_providers', 'profiles']);
|
|
30
|
+
const PROVIDER_KEYS = new Set(['name', 'base_url', 'env_key']);
|
|
31
|
+
const PROFILE_KEYS = new Set(['model', 'model_provider']);
|
|
32
|
+
/** A user's own big integers are valid TOML, not a reason to call their file broken. */
|
|
33
|
+
const parseTomlDocument = (text) => parseToml(text, { integersAsBigInt: 'asNeeded' });
|
|
34
|
+
function splitLines(content) {
|
|
35
|
+
const lines = [];
|
|
36
|
+
for (let start = 0; start < content.length;) {
|
|
37
|
+
const newline = content.indexOf('\n', start);
|
|
38
|
+
const end = newline < 0 ? content.length : newline + 1;
|
|
39
|
+
const raw = content.slice(start, end);
|
|
40
|
+
lines.push({ raw, text: raw.replace(/\n$/, '').replace(/\r$/, '') });
|
|
41
|
+
start = end;
|
|
42
|
+
}
|
|
43
|
+
return lines;
|
|
44
|
+
}
|
|
45
|
+
const conflict = (path, problem) => ({
|
|
46
|
+
kind: 'conflict',
|
|
47
|
+
reason: `Atomic Chat cannot remove its old settings from ${path}: ${problem}. ` +
|
|
48
|
+
`Remove the lines between "${ATOMIC_MANAGED_BEGIN}" and "${ATOMIC_MANAGED_END}" by hand, ` +
|
|
49
|
+
'markers included, then connect Codex again.',
|
|
50
|
+
});
|
|
51
|
+
/** The first line of a parser error, which is the message; the rest is a code frame. */
|
|
52
|
+
const parserMessage = (e) => String(e.message).split('\n')[0];
|
|
53
|
+
const isTable = (value) => typeof value === 'object' && value !== null && !Array.isArray(value) && !(value instanceof Date);
|
|
54
|
+
const only = (table, allowed) => Object.keys(table).every((key) => allowed.has(key));
|
|
55
|
+
/** `{ atomic = { … } }` and nothing else beside it. */
|
|
56
|
+
function soleAtomicTable(value) {
|
|
57
|
+
if (!isTable(value) || Object.keys(value).join() !== 'atomic')
|
|
58
|
+
return undefined;
|
|
59
|
+
const atomic = value['atomic'];
|
|
60
|
+
return isTable(atomic) ? atomic : undefined;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The settings in one region when it holds exactly what some Atomic Chat version wrote, else
|
|
64
|
+
* `undefined`. Inline tables and dotted keys mean the same to Codex, so they are accepted too.
|
|
65
|
+
*/
|
|
66
|
+
export function recogniseLegacyRegion(doc) {
|
|
67
|
+
if (Object.keys(doc).length === 0 || !only(doc, ROOT_KEYS))
|
|
68
|
+
return undefined;
|
|
69
|
+
const found = { keyed: false };
|
|
70
|
+
const has = (key) => Object.hasOwn(doc, key);
|
|
71
|
+
if (has('model')) {
|
|
72
|
+
const model = doc['model'];
|
|
73
|
+
if (typeof model !== 'string')
|
|
74
|
+
return undefined;
|
|
75
|
+
found.model = model;
|
|
76
|
+
}
|
|
77
|
+
if (has('model_provider') && doc['model_provider'] !== 'atomic')
|
|
78
|
+
return undefined;
|
|
79
|
+
if (has('model_providers')) {
|
|
80
|
+
const provider = soleAtomicTable(doc['model_providers']);
|
|
81
|
+
if (!provider || !only(provider, PROVIDER_KEYS))
|
|
82
|
+
return undefined;
|
|
83
|
+
const baseUrl = provider['base_url'];
|
|
84
|
+
if (provider['name'] !== 'Atomic Chat' || typeof baseUrl !== 'string')
|
|
85
|
+
return undefined;
|
|
86
|
+
const keyed = Object.hasOwn(provider, 'env_key');
|
|
87
|
+
if (keyed && provider['env_key'] !== 'ATOMIC_CHAT_API_KEY')
|
|
88
|
+
return undefined;
|
|
89
|
+
found.baseUrl = baseUrl;
|
|
90
|
+
found.keyed = keyed;
|
|
91
|
+
}
|
|
92
|
+
if (has('profiles')) {
|
|
93
|
+
const profile = soleAtomicTable(doc['profiles']);
|
|
94
|
+
if (!profile || !only(profile, PROFILE_KEYS))
|
|
95
|
+
return undefined;
|
|
96
|
+
const model = profile['model'];
|
|
97
|
+
if (typeof model !== 'string' || profile['model_provider'] !== 'atomic')
|
|
98
|
+
return undefined;
|
|
99
|
+
found.model ??= model;
|
|
100
|
+
}
|
|
101
|
+
return found;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Steps 2–6 of the repair on a file's text: find and pair the marker lines, recognise every region,
|
|
105
|
+
* remove them, and check what is left. Pure, so every rule is testable on a string.
|
|
106
|
+
*/
|
|
107
|
+
export function planCodexConfigRepair(original, path) {
|
|
108
|
+
const lines = splitLines(original);
|
|
109
|
+
const markers = [];
|
|
110
|
+
for (const [index, { text }] of lines.entries()) {
|
|
111
|
+
if (text === ATOMIC_MANAGED_BEGIN || text === ATOMIC_MANAGED_END) {
|
|
112
|
+
markers.push({ index, begin: text === ATOMIC_MANAGED_BEGIN });
|
|
113
|
+
}
|
|
114
|
+
else if (text.includes(ATOMIC_MANAGED_BEGIN) || text.includes(ATOMIC_MANAGED_END)) {
|
|
115
|
+
return conflict(path, `line ${index + 1} has an Atomic Chat marker inside other text`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (markers.length === 0)
|
|
119
|
+
return { kind: 'clean' };
|
|
120
|
+
const regions = [];
|
|
121
|
+
let open;
|
|
122
|
+
for (const { index, begin } of markers) {
|
|
123
|
+
if (begin && open !== undefined)
|
|
124
|
+
return conflict(path, `line ${index + 1} opens a block inside the one opened on line ${open + 1}`);
|
|
125
|
+
if (!begin && open === undefined)
|
|
126
|
+
return conflict(path, `line ${index + 1} closes a block that was never opened`);
|
|
127
|
+
if (begin)
|
|
128
|
+
open = index;
|
|
129
|
+
else {
|
|
130
|
+
regions.push({ begin: open, end: index });
|
|
131
|
+
open = undefined;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (open !== undefined)
|
|
135
|
+
return conflict(path, `the block opened on line ${open + 1} is never closed`);
|
|
136
|
+
const found = [];
|
|
137
|
+
for (const [n, { begin, end }] of regions.entries()) {
|
|
138
|
+
const where = `block ${n + 1} (lines ${begin + 1}–${end + 1})`;
|
|
139
|
+
let doc;
|
|
140
|
+
try {
|
|
141
|
+
doc = parseTomlDocument(lines
|
|
142
|
+
.slice(begin + 1, end)
|
|
143
|
+
.map((line) => line.raw)
|
|
144
|
+
.join(''));
|
|
145
|
+
}
|
|
146
|
+
catch (e) {
|
|
147
|
+
return conflict(path, `${where} is not valid TOML (${parserMessage(e)})`);
|
|
148
|
+
}
|
|
149
|
+
const settings = recogniseLegacyRegion(doc);
|
|
150
|
+
if (!settings)
|
|
151
|
+
return conflict(path, `${where} has settings Atomic Chat never writes`);
|
|
152
|
+
found.push(settings);
|
|
153
|
+
}
|
|
154
|
+
// V2 split one setup over two regions: the model in the head, the endpoint in the tail.
|
|
155
|
+
const model = found.find((s) => s.model !== undefined)?.model;
|
|
156
|
+
const baseUrl = found.find((s) => s.baseUrl !== undefined)?.baseUrl;
|
|
157
|
+
const legacy = {
|
|
158
|
+
...(model === undefined ? {} : { model }),
|
|
159
|
+
...(baseUrl === undefined ? {} : { baseUrl }),
|
|
160
|
+
keyed: found.some((s) => s.keyed),
|
|
161
|
+
};
|
|
162
|
+
const removed = new Set();
|
|
163
|
+
for (const { begin, end } of regions)
|
|
164
|
+
for (let index = begin; index <= end; index++)
|
|
165
|
+
removed.add(index);
|
|
166
|
+
let kept = [...lines.keys()].filter((index) => !removed.has(index));
|
|
167
|
+
// The V2 head was followed by a blank line (or, after reruns, several); at the top of the file
|
|
168
|
+
// they are ours too. A file that did not start with a region keeps its leading lines as they are.
|
|
169
|
+
if (removed.has(0)) {
|
|
170
|
+
const first = kept.findIndex((index) => lines[index].text.trim() !== '');
|
|
171
|
+
kept = first < 0 ? [] : kept.slice(first);
|
|
172
|
+
}
|
|
173
|
+
const body = kept
|
|
174
|
+
.map((index) => lines[index].raw)
|
|
175
|
+
.join('')
|
|
176
|
+
.trimEnd();
|
|
177
|
+
const text = body === '' ? '' : `${body}\n`;
|
|
178
|
+
try {
|
|
179
|
+
parseTomlDocument(text);
|
|
180
|
+
}
|
|
181
|
+
catch (e) {
|
|
182
|
+
// Report the line as the user sees it in the file now, not in the text we were about to write.
|
|
183
|
+
// `TomlError.line` is 1-based; a message without one (or past the end) names no line.
|
|
184
|
+
const original = kept[e.line - 1];
|
|
185
|
+
const at = original === undefined ? '' : ` (line ${original + 1})`;
|
|
186
|
+
return {
|
|
187
|
+
kind: 'conflict',
|
|
188
|
+
reason: `${path} would still not be valid TOML after removing Atomic Chat's settings: ` +
|
|
189
|
+
`${parserMessage(e)}${at}. Fix the file, or remove the lines between "${ATOMIC_MANAGED_BEGIN}" ` +
|
|
190
|
+
`and "${ATOMIC_MANAGED_END}" by hand, markers included, then connect Codex again.`,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
return { kind: 'repair', text, legacy };
|
|
194
|
+
}
|
|
195
|
+
/** The first free backup name: `config.toml.atomic-chat-backup`, then `-2`, `-3`, … */
|
|
196
|
+
export function codexBackupPath(path, attempt) {
|
|
197
|
+
return attempt === 1 ? `${path}.atomic-chat-backup` : `${path}.atomic-chat-backup-${attempt}`;
|
|
198
|
+
}
|
|
199
|
+
const readFailure = (path, e) => new AtomicCoreError('IO_ERROR', `Failed to read ${path}`, e.message);
|
|
200
|
+
async function readOrFail(fs, path) {
|
|
201
|
+
try {
|
|
202
|
+
return await fs.readStrict(path);
|
|
203
|
+
}
|
|
204
|
+
catch (e) {
|
|
205
|
+
throw readFailure(path, e);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Remove every legacy Atomic Chat region from `<dir>/config.toml`. Returns a conflict rather than
|
|
210
|
+
* throwing for a file it will not touch; throws only when the file could not be read, backed up or
|
|
211
|
+
* written. Either way a file that was not repaired is exactly as it was.
|
|
212
|
+
*/
|
|
213
|
+
export async function repairLegacyCodexConfig(fs, dir, platform) {
|
|
214
|
+
const path = join(dir, 'config.toml');
|
|
215
|
+
const original = await readOrFail(fs, path);
|
|
216
|
+
if (original === undefined)
|
|
217
|
+
return { kind: 'clean' };
|
|
218
|
+
const plan = planCodexConfigRepair(original, path);
|
|
219
|
+
if (plan.kind !== 'repair')
|
|
220
|
+
return plan;
|
|
221
|
+
let target;
|
|
222
|
+
let mode;
|
|
223
|
+
try {
|
|
224
|
+
target = await fs.linkTarget(path);
|
|
225
|
+
mode = platform === 'win32' ? undefined : await fs.permissions(target);
|
|
226
|
+
}
|
|
227
|
+
catch (e) {
|
|
228
|
+
throw readFailure(path, e);
|
|
229
|
+
}
|
|
230
|
+
// Another program (Codex itself, an editor) may have saved the file while we were deciding.
|
|
231
|
+
if ((await readOrFail(fs, path)) !== original) {
|
|
232
|
+
return conflict(path, 'it changed while Atomic Chat was reading it');
|
|
233
|
+
}
|
|
234
|
+
const options = mode === undefined ? {} : { mode };
|
|
235
|
+
let backupPath;
|
|
236
|
+
try {
|
|
237
|
+
for (let attempt = 1; backupPath === undefined; attempt++) {
|
|
238
|
+
const candidate = codexBackupPath(path, attempt);
|
|
239
|
+
if (await fs.createNew(candidate, original, options))
|
|
240
|
+
backupPath = candidate;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
catch (e) {
|
|
244
|
+
throw new AtomicCoreError('IO_ERROR', `Could not back up ${path} before removing Atomic Chat's old settings from it, so it was left as it was.`, e.message);
|
|
245
|
+
}
|
|
246
|
+
try {
|
|
247
|
+
await fs.write(target, plan.text, options);
|
|
248
|
+
}
|
|
249
|
+
catch (e) {
|
|
250
|
+
throw new AtomicCoreError('IO_ERROR', `Failed to write ${target}`, e.message);
|
|
251
|
+
}
|
|
252
|
+
return { kind: 'repaired', backupPath, legacy: plan.legacy };
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=codex-repair.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-repair.js","sourceRoot":"","sources":["../../../src/integrations/configure/codex-repair.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,55 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Codex CLI —
|
|
2
|
+
* Codex CLI — a profile file of our own, `<codex_home>/atomic-chat.config.toml`.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Codex 0.134+ layers `$CODEX_HOME/<name>.config.toml` over the base `config.toml` when it is run
|
|
5
|
+
* with `--profile <name>`, so `launch` runs `codex --profile atomic-chat` (catalog `runArgs`) and the
|
|
6
|
+
* model, the provider and its endpoint live in a file nothing else writes. The provider id is
|
|
7
|
+
* `atomic-chat`, not `atomic`, so it never merges into a `[model_providers.atomic]` the user has.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
* root
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* The shared `config.toml` is no longer ours to write. Earlier versions edited it (two managed
|
|
10
|
+
* regions: bare root `model` / `model_provider` at the top, `[model_providers.atomic]` at the end),
|
|
11
|
+
* and a user who already had a root `model` got a duplicate key that stopped Codex — and the ChatGPT
|
|
12
|
+
* desktop app, which reads the same file — from starting. The only thing done to it now is removing
|
|
13
|
+
* those regions, through the strict repair in `codex-repair.ts`, before the profile is written.
|
|
12
14
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
+
* Order: version gate, repair, profile. Below 0.134 `--profile` meant the old `[profiles.x]` tables,
|
|
16
|
+
* so an old Codex is refused before anything is touched; a version that cannot be read is let through.
|
|
17
|
+
* The profile is rewritten only while its first line says Atomic Chat wrote it: a file of the same
|
|
18
|
+
* name that someone else made is refused, never replaced. A profile that is a symbolic link is
|
|
19
|
+
* written through, so the link survives; one that points at nothing is refused rather than replaced.
|
|
20
|
+
* The bytes are a contract with the desktop writer (ADR 2026-10-27-codex-runs-on-a-profile-of-its-own),
|
|
21
|
+
* so either side can rewrite the other's.
|
|
15
22
|
*/
|
|
23
|
+
import type { ConfigFs } from '../config-io.js';
|
|
16
24
|
import type { ConfigureInput } from './registry.js';
|
|
25
|
+
/** The profile name `--profile` takes, and the stem of its file. */
|
|
26
|
+
export declare const CODEX_PROFILE = "atomic-chat";
|
|
27
|
+
/** A profile file is ours iff it starts with this. */
|
|
28
|
+
export declare const CODEX_PROFILE_OWNER_PREFIX = "# Managed by Atomic Chat";
|
|
29
|
+
/**
|
|
30
|
+
* The first release where `--profile <name>` reads `<name>.config.toml`; 0.131–0.133 called that
|
|
31
|
+
* `--profile-v2` and meant the old `[profiles.x]` tables by `--profile`.
|
|
32
|
+
*/
|
|
33
|
+
export declare const CODEX_MIN_VERSION: readonly [0, 134, 0];
|
|
34
|
+
export type CodexVersion = readonly [number, number, number];
|
|
35
|
+
/**
|
|
36
|
+
* Codex's own home: `$CODEX_HOME` when set and non-empty, else `<home>/.codex`. Codex resolves a
|
|
37
|
+
* relative `$CODEX_HOME` against its working directory, which `launch` shares with it. A leading `~`
|
|
38
|
+
* is expanded against the home directory: a quoted `CODEX_HOME="~/x"` reaches us unexpanded.
|
|
39
|
+
*/
|
|
40
|
+
export declare function codexHome(env: NodeJS.ProcessEnv, home: string): string;
|
|
41
|
+
export declare function codexProfilePath(dir: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* The profile's exact bytes. Codex reads the key from the variable `env_key` names, never inline, so
|
|
44
|
+
* a keyless server gets no `env_key` line at all and `launch` sets the variable on the child.
|
|
45
|
+
*/
|
|
46
|
+
export declare function renderCodexProfile(apiUrl: string, model: string, apiKey: string): string;
|
|
47
|
+
/** `codex --version` prints `codex-cli 0.146.0`: the first `x.y.z` in the output. */
|
|
48
|
+
export declare function parseCodexVersion(output: string): CodexVersion | undefined;
|
|
49
|
+
export declare function isCodexTooOld([major, minor, patch]: CodexVersion): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Write the profile, refusing to replace a file of that name Atomic Chat did not write. Returns its
|
|
52
|
+
* path. A profile that cannot be read is an error, never "absent"; a symbolic link is written through.
|
|
53
|
+
*/
|
|
54
|
+
export declare function writeCodexProfile(fs: ConfigFs, dir: string, apiUrl: string, model: string, apiKey: string): Promise<string>;
|
|
17
55
|
export declare function configureCodex(input: ConfigureInput): Promise<void>;
|
|
@@ -1,43 +1,137 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Codex CLI —
|
|
2
|
+
* Codex CLI — a profile file of our own, `<codex_home>/atomic-chat.config.toml`.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Codex 0.134+ layers `$CODEX_HOME/<name>.config.toml` over the base `config.toml` when it is run
|
|
5
|
+
* with `--profile <name>`, so `launch` runs `codex --profile atomic-chat` (catalog `runArgs`) and the
|
|
6
|
+
* model, the provider and its endpoint live in a file nothing else writes. The provider id is
|
|
7
|
+
* `atomic-chat`, not `atomic`, so it never merges into a `[model_providers.atomic]` the user has.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
* root
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* The shared `config.toml` is no longer ours to write. Earlier versions edited it (two managed
|
|
10
|
+
* regions: bare root `model` / `model_provider` at the top, `[model_providers.atomic]` at the end),
|
|
11
|
+
* and a user who already had a root `model` got a duplicate key that stopped Codex — and the ChatGPT
|
|
12
|
+
* desktop app, which reads the same file — from starting. The only thing done to it now is removing
|
|
13
|
+
* those regions, through the strict repair in `codex-repair.ts`, before the profile is written.
|
|
12
14
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
+
* Order: version gate, repair, profile. Below 0.134 `--profile` meant the old `[profiles.x]` tables,
|
|
16
|
+
* so an old Codex is refused before anything is touched; a version that cannot be read is let through.
|
|
17
|
+
* The profile is rewritten only while its first line says Atomic Chat wrote it: a file of the same
|
|
18
|
+
* name that someone else made is refused, never replaced. A profile that is a symbolic link is
|
|
19
|
+
* written through, so the link survives; one that points at nothing is refused rather than replaced.
|
|
20
|
+
* The bytes are a contract with the desktop writer (ADR 2026-10-27-codex-runs-on-a-profile-of-its-own),
|
|
21
|
+
* so either side can rewrite the other's.
|
|
15
22
|
*/
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
23
|
+
import { join, resolve } from 'node:path';
|
|
24
|
+
import { parse as parseToml } from 'smol-toml';
|
|
25
|
+
import { AtomicCoreError } from '../../contracts/index.js';
|
|
26
|
+
import { expandTilde, tomlBasicStringEscape } from '../config-io.js';
|
|
27
|
+
import { repairLegacyCodexConfig } from './codex-repair.js';
|
|
18
28
|
import { registerWriter } from './registry.js';
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
/** The profile name `--profile` takes, and the stem of its file. */
|
|
30
|
+
export const CODEX_PROFILE = 'atomic-chat';
|
|
31
|
+
/** A profile file is ours iff it starts with this. */
|
|
32
|
+
export const CODEX_PROFILE_OWNER_PREFIX = '# Managed by Atomic Chat';
|
|
33
|
+
/**
|
|
34
|
+
* The first release where `--profile <name>` reads `<name>.config.toml`; 0.131–0.133 called that
|
|
35
|
+
* `--profile-v2` and meant the old `[profiles.x]` tables by `--profile`.
|
|
36
|
+
*/
|
|
37
|
+
export const CODEX_MIN_VERSION = [0, 134, 0];
|
|
38
|
+
/**
|
|
39
|
+
* Codex's own home: `$CODEX_HOME` when set and non-empty, else `<home>/.codex`. Codex resolves a
|
|
40
|
+
* relative `$CODEX_HOME` against its working directory, which `launch` shares with it. A leading `~`
|
|
41
|
+
* is expanded against the home directory: a quoted `CODEX_HOME="~/x"` reaches us unexpanded.
|
|
42
|
+
*/
|
|
43
|
+
export function codexHome(env, home) {
|
|
44
|
+
const raw = env['CODEX_HOME'];
|
|
45
|
+
return raw === undefined || raw === '' ? join(home, '.codex') : resolve(expandTilde(raw, home));
|
|
46
|
+
}
|
|
47
|
+
export function codexProfilePath(dir) {
|
|
48
|
+
return join(dir, `${CODEX_PROFILE}.config.toml`);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The profile's exact bytes. Codex reads the key from the variable `env_key` names, never inline, so
|
|
52
|
+
* a keyless server gets no `env_key` line at all and `launch` sets the variable on the child.
|
|
53
|
+
*/
|
|
54
|
+
export function renderCodexProfile(apiUrl, model, apiKey) {
|
|
55
|
+
return (`${CODEX_PROFILE_OWNER_PREFIX}: \`codex --profile ${CODEX_PROFILE}\` runs Codex on your local models.\n` +
|
|
56
|
+
'# Atomic Chat rewrites this file when Codex is connected again and deletes it on disconnect.\n' +
|
|
27
57
|
`model = "${tomlBasicStringEscape(model)}"\n` +
|
|
28
|
-
`model_provider = "
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const envKeyLine = apiKey === '' ? '' : `env_key = "ATOMIC_CHAT_API_KEY"\n`;
|
|
33
|
-
const block = `${ATOMIC_MANAGED_BEGIN}\n` +
|
|
34
|
-
`[model_providers.atomic]\n` +
|
|
35
|
-
`name = "Atomic Chat"\n` +
|
|
58
|
+
`model_provider = "${CODEX_PROFILE}"\n` +
|
|
59
|
+
'\n' +
|
|
60
|
+
`[model_providers.${CODEX_PROFILE}]\n` +
|
|
61
|
+
'name = "Atomic Chat"\n' +
|
|
36
62
|
`base_url = "${tomlBasicStringEscape(apiUrl)}"\n` +
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
63
|
+
(apiKey === '' ? '' : 'env_key = "ATOMIC_CHAT_API_KEY"\n'));
|
|
64
|
+
}
|
|
65
|
+
/** `codex --version` prints `codex-cli 0.146.0`: the first `x.y.z` in the output. */
|
|
66
|
+
export function parseCodexVersion(output) {
|
|
67
|
+
const match = /(\d+)\.(\d+)\.(\d+)/.exec(output);
|
|
68
|
+
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : undefined;
|
|
69
|
+
}
|
|
70
|
+
export function isCodexTooOld([major, minor, patch]) {
|
|
71
|
+
const [minMajor, minMinor, minPatch] = CODEX_MIN_VERSION;
|
|
72
|
+
if (major !== minMajor)
|
|
73
|
+
return major < minMajor;
|
|
74
|
+
if (minor !== minMinor)
|
|
75
|
+
return minor < minMinor;
|
|
76
|
+
return patch < minPatch;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Write the profile, refusing to replace a file of that name Atomic Chat did not write. Returns its
|
|
80
|
+
* path. A profile that cannot be read is an error, never "absent"; a symbolic link is written through.
|
|
81
|
+
*/
|
|
82
|
+
export async function writeCodexProfile(fs, dir, apiUrl, model, apiKey) {
|
|
83
|
+
const path = codexProfilePath(dir);
|
|
84
|
+
const contents = renderCodexProfile(apiUrl, model, apiKey);
|
|
85
|
+
// Cannot fail with the escaping above; it keeps a future edit of the template from shipping a file
|
|
86
|
+
// Codex would reject.
|
|
87
|
+
parseToml(contents);
|
|
88
|
+
let target;
|
|
89
|
+
let existing;
|
|
90
|
+
try {
|
|
91
|
+
target = await fs.linkTarget(path);
|
|
92
|
+
existing = await fs.readStrict(target);
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
// Only a link to nothing makes `linkTarget` report "not found"; writing would replace the link.
|
|
96
|
+
const dangling = e.code === 'ENOENT';
|
|
97
|
+
throw new AtomicCoreError('IO_ERROR', dangling
|
|
98
|
+
? `${path} is a symbolic link to a file that does not exist. Remove the link or create the file it points to, then connect Codex again.`
|
|
99
|
+
: `Failed to read ${path}`, e.message);
|
|
100
|
+
}
|
|
101
|
+
if (existing !== undefined && !existing.startsWith(CODEX_PROFILE_OWNER_PREFIX)) {
|
|
102
|
+
throw new AtomicCoreError('IO_ERROR', `${path} already exists and was not written by Atomic Chat. Rename or remove it, then connect Codex again.`);
|
|
103
|
+
}
|
|
104
|
+
await fs.write(target, contents);
|
|
105
|
+
return path;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* The installed Codex's version, or `undefined` when it cannot be told: no runner, a launcher that
|
|
109
|
+
* does not start or fails, output without a version. On Windows the npm launcher is `codex.cmd`,
|
|
110
|
+
* which only `cmd` can run (as for Cline).
|
|
111
|
+
*/
|
|
112
|
+
async function installedCodexVersion(input) {
|
|
113
|
+
if (!input.spawn)
|
|
114
|
+
return undefined;
|
|
115
|
+
const program = input.program ?? 'codex';
|
|
116
|
+
const windows = input.platform === 'win32';
|
|
117
|
+
try {
|
|
118
|
+
const result = await input.spawn(windows ? 'cmd' : program, windows ? ['/C', program, '--version'] : ['--version']);
|
|
119
|
+
return result.code === 0 ? parseCodexVersion(result.stdout) : undefined;
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
export async function configureCodex(input) {
|
|
126
|
+
const version = await installedCodexVersion(input);
|
|
127
|
+
if (version && isCodexTooOld(version)) {
|
|
128
|
+
throw new AtomicCoreError('IO_ERROR', `Codex CLI ${version.join('.')} is too old for Atomic Chat. Update it to 0.134 or newer and connect again.`);
|
|
129
|
+
}
|
|
130
|
+
const dir = codexHome(input.env, input.fs.home);
|
|
131
|
+
const repair = await repairLegacyCodexConfig(input.fs, dir, input.platform);
|
|
132
|
+
if (repair.kind === 'conflict')
|
|
133
|
+
throw new AtomicCoreError('IO_ERROR', repair.reason);
|
|
134
|
+
await writeCodexProfile(input.fs, dir, input.apiUrl, input.model, input.apiKey);
|
|
41
135
|
}
|
|
42
136
|
registerWriter('codex', configureCodex);
|
|
43
137
|
//# sourceMappingURL=codex.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../src/integrations/configure/codex.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../src/integrations/configure/codex.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,12 +14,14 @@ export interface ConfigureInput {
|
|
|
14
14
|
/** `$SHELL`; decides which rc file the env-var agents write to. */
|
|
15
15
|
shell: string | undefined;
|
|
16
16
|
env: NodeJS.ProcessEnv;
|
|
17
|
-
/** Run a command (
|
|
17
|
+
/** Run a command (Cline's `cline auth`, Codex's `--version`). Resolves with its exit status and output. */
|
|
18
18
|
spawn?: (program: string, args: string[]) => Promise<{
|
|
19
19
|
code: number;
|
|
20
20
|
stdout: string;
|
|
21
21
|
stderr: string;
|
|
22
22
|
}>;
|
|
23
|
+
/** The agent's launcher as detection found it (bare name or absolute path); Codex asks it its version. */
|
|
24
|
+
program?: string;
|
|
23
25
|
}
|
|
24
26
|
export type ConfigureWriter = (input: ConfigureInput) => Promise<void>;
|
|
25
27
|
/** Register a writer for an agent id. Called once per module at import time. */
|
|
@@ -33,6 +35,7 @@ export interface ConfigureOptions {
|
|
|
33
35
|
shell?: string | undefined;
|
|
34
36
|
env?: NodeJS.ProcessEnv;
|
|
35
37
|
spawn?: ConfigureInput['spawn'];
|
|
38
|
+
program?: string;
|
|
36
39
|
}
|
|
37
40
|
/**
|
|
38
41
|
* Point an agent at a local endpoint. `model` may be empty only for the agents whose Rust
|
|
@@ -45,6 +45,7 @@ export async function configureAgent(agent, apiUrl, model, apiKey, options = {})
|
|
|
45
45
|
shell: options.shell ?? env['SHELL'],
|
|
46
46
|
env,
|
|
47
47
|
...(options.spawn ? { spawn: options.spawn } : {}),
|
|
48
|
+
...(options.program ? { program: options.program } : {}),
|
|
48
49
|
});
|
|
49
50
|
}
|
|
50
51
|
//# sourceMappingURL=registry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/integrations/configure/registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE1D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/integrations/configure/registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE1D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAmB9C,MAAM,OAAO,GAAG,IAAI,GAAG,EAA2B,CAAA;AAElD,gFAAgF;AAChF,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,MAAuB;IACrE,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;AAC9B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;AAC7B,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;AACnC,CAAC;AAYD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,KAAqB,EACrB,MAAc,EACd,KAAa,EACb,MAAc,EACd,UAA4B,EAAE;IAE9B,MAAM,QAAQ,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IACrE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,eAAe,CAAC,kBAAkB,EAAE,kBAAkB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IAClF,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IACvC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,eAAe,CACvB,gBAAgB,EAChB,eAAe,QAAQ,CAAC,IAAI,oCAAoC,EAChE,6BAA6B,QAAQ,CAAC,EAAE,GAAG,CAC5C,CAAA;IACH,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAA;IACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAA;IACrD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IACtF,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACzB,MAAM,IAAI,eAAe,CAAC,UAAU,EAAE,+DAA+D,CAAC,CAAA;IACxG,CAAC;IACD,MAAM,MAAM,CAAC;QACX,MAAM;QACN,KAAK;QACL,MAAM;QACN,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,YAAY,CAAC,IAAc,CAAC;QAC9C,QAAQ;QACR,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC;QACpC,GAAG;QACH,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACzD,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -17,10 +17,10 @@ export interface ChildProcessRecord {
|
|
|
17
17
|
process_start_id: string | null;
|
|
18
18
|
exe: string;
|
|
19
19
|
/**
|
|
20
|
-
* `diffusion` for the image engine, `decision` and `embedding` for those
|
|
21
|
-
* (their processes are reaped all the same).
|
|
20
|
+
* `diffusion` for the image engine, `audio` for the audio engine, `decision` and `embedding` for those
|
|
21
|
+
* models, which are not providers (their processes are reaped all the same).
|
|
22
22
|
*/
|
|
23
|
-
provider: LocalProviderId | 'diffusion' | 'decision' | 'embedding';
|
|
23
|
+
provider: LocalProviderId | 'diffusion' | 'audio' | 'decision' | 'embedding';
|
|
24
24
|
model_id: string;
|
|
25
25
|
port: number;
|
|
26
26
|
started_at: string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// models/atomic-prism-models.json is a deprecated editable catalog, generated from catalog.json. Its compatibility-export contract remains a supported core input.
|
|
1
2
|
// Offline snapshot of atomic-chat-conf/models/atomic-prism-models.json (without `$schema`): what the
|
|
2
3
|
// core decides with when neither the live rules nor their disk cache are available. Re-copy it from
|
|
3
4
|
// conf when the rules change there; a live document always wins.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules-baseline.js","sourceRoot":"","sources":["../../../src/models/compatibility/rules-baseline.ts"],"names":[],"mappings":"AAAA,qGAAqG;AACrG,oGAAoG;AACpG,iEAAiE;AACjE,OAAO,GAAG,MAAM,uBAAuB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAGjD,MAAM,MAAM,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAA;AACxC,IAAI,CAAC,MAAM;IAAE,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAA;AAE/F,MAAM,CAAC,MAAM,0BAA0B,GAAoB,MAAM,CAAA"}
|
|
1
|
+
{"version":3,"file":"rules-baseline.js","sourceRoot":"","sources":["../../../src/models/compatibility/rules-baseline.ts"],"names":[],"mappings":"AAAA,mKAAmK;AACnK,qGAAqG;AACrG,oGAAoG;AACpG,iEAAiE;AACjE,OAAO,GAAG,MAAM,uBAAuB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAGjD,MAAM,MAAM,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAA;AACxC,IAAI,CAAC,MAAM;IAAE,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAA;AAE/F,MAAM,CAAC,MAAM,0BAA0B,GAAoB,MAAM,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// models/atomic-prism-models.json is a deprecated editable catalog, generated from catalog.json. Its compatibility-export contract remains a supported core input.
|
|
1
2
|
/**
|
|
2
3
|
* PrismML model compatibility rules, pure half: `atomic-chat-conf/models/atomic-prism-models.json`
|
|
3
4
|
* (schema `schema.atomic-prism-models.json` next to it). Which Bonsai files need `atomic-prism`,
|