@atomic-chat/core 0.20.6 → 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.
- package/dist/audio/jobs.js +4 -0
- package/dist/audio/jobs.js.map +1 -1
- package/dist/audio/service.d.ts +1 -1
- package/dist/audio/service.js +3 -1
- package/dist/audio/service.js.map +1 -1
- package/dist/audio/session.js +28 -16
- package/dist/audio/session.js.map +1 -1
- package/dist/audio/state.d.ts +3 -1
- package/dist/audio/state.js +3 -1
- package/dist/audio/state.js.map +1 -1
- package/dist/cli/launch.d.ts +23 -3
- package/dist/cli/launch.js +59 -8
- package/dist/cli/launch.js.map +1 -1
- package/dist/cli/main.d.ts +1 -1
- package/dist/contracts/events.d.ts +8 -0
- package/dist/contracts/settings.d.ts +5 -0
- package/dist/contracts/settings.js.map +1 -1
- package/dist/core/atomic-core.d.ts +3 -1
- package/dist/core/atomic-core.js +4 -1
- package/dist/core/atomic-core.js.map +1 -1
- package/dist/core/create.js +4 -1
- package/dist/core/create.js.map +1 -1
- package/dist/core/sessions.js +1 -0
- package/dist/core/sessions.js.map +1 -1
- package/dist/integrations/catalog.d.ts +25 -8
- package/dist/integrations/catalog.js +105 -38
- package/dist/integrations/catalog.js.map +1 -1
- package/dist/integrations/configure/atomic-agent.d.ts +9 -1
- package/dist/integrations/configure/atomic-agent.js +42 -3
- package/dist/integrations/configure/atomic-agent.js.map +1 -1
- package/dist/integrations/configure/backup.d.ts +21 -0
- package/dist/integrations/configure/backup.js +52 -0
- package/dist/integrations/configure/backup.js.map +1 -0
- package/dist/integrations/configure/claude-code.d.ts +11 -4
- package/dist/integrations/configure/claude-code.js +73 -24
- package/dist/integrations/configure/claude-code.js.map +1 -1
- package/dist/integrations/configure/cline.d.ts +14 -4
- package/dist/integrations/configure/cline.js +78 -6
- package/dist/integrations/configure/cline.js.map +1 -1
- package/dist/integrations/configure/codex.d.ts +5 -3
- package/dist/integrations/configure/codex.js +12 -5
- package/dist/integrations/configure/codex.js.map +1 -1
- package/dist/integrations/configure/copilot.d.ts +28 -5
- package/dist/integrations/configure/copilot.js +124 -8
- package/dist/integrations/configure/copilot.js.map +1 -1
- package/dist/integrations/configure/droid.d.ts +13 -7
- package/dist/integrations/configure/droid.js +48 -17
- package/dist/integrations/configure/droid.js.map +1 -1
- package/dist/integrations/configure/dsh.d.ts +36 -20
- package/dist/integrations/configure/dsh.js +250 -48
- package/dist/integrations/configure/dsh.js.map +1 -1
- package/dist/integrations/configure/goose.d.ts +21 -7
- package/dist/integrations/configure/goose.js +141 -10
- package/dist/integrations/configure/goose.js.map +1 -1
- package/dist/integrations/configure/hermes.d.ts +63 -10
- package/dist/integrations/configure/hermes.js +360 -75
- package/dist/integrations/configure/hermes.js.map +1 -1
- package/dist/integrations/configure/json-backup.d.ts +73 -0
- package/dist/integrations/configure/json-backup.js +292 -0
- package/dist/integrations/configure/json-backup.js.map +1 -0
- package/dist/integrations/configure/json-key-backup.d.ts +43 -0
- package/dist/integrations/configure/json-key-backup.js +113 -0
- package/dist/integrations/configure/json-key-backup.js.map +1 -0
- package/dist/integrations/configure/kilo.d.ts +4 -4
- package/dist/integrations/configure/kilo.js +6 -9
- package/dist/integrations/configure/kilo.js.map +1 -1
- package/dist/integrations/configure/legacy-env-block.d.ts +18 -0
- package/dist/integrations/configure/legacy-env-block.js +47 -0
- package/dist/integrations/configure/legacy-env-block.js.map +1 -0
- package/dist/integrations/configure/mimo.d.ts +3 -2
- package/dist/integrations/configure/mimo.js +8 -9
- package/dist/integrations/configure/mimo.js.map +1 -1
- package/dist/integrations/configure/muse.d.ts +3 -3
- package/dist/integrations/configure/muse.js +5 -6
- package/dist/integrations/configure/muse.js.map +1 -1
- package/dist/integrations/configure/openclaude.d.ts +22 -7
- package/dist/integrations/configure/openclaude.js +132 -39
- package/dist/integrations/configure/openclaude.js.map +1 -1
- package/dist/integrations/configure/openclaw.d.ts +19 -5
- package/dist/integrations/configure/openclaw.js +79 -23
- package/dist/integrations/configure/openclaw.js.map +1 -1
- package/dist/integrations/configure/opencode-style.d.ts +53 -11
- package/dist/integrations/configure/opencode-style.js +218 -23
- package/dist/integrations/configure/opencode-style.js.map +1 -1
- package/dist/integrations/configure/opencode.d.ts +5 -4
- package/dist/integrations/configure/opencode.js +8 -10
- package/dist/integrations/configure/opencode.js.map +1 -1
- package/dist/integrations/configure/openhands.d.ts +5 -4
- package/dist/integrations/configure/openhands.js +7 -7
- package/dist/integrations/configure/openhands.js.map +1 -1
- package/dist/integrations/configure/pi.d.ts +6 -5
- package/dist/integrations/configure/pi.js +79 -30
- package/dist/integrations/configure/pi.js.map +1 -1
- package/dist/integrations/configure/poolside.d.ts +5 -4
- package/dist/integrations/configure/poolside.js +7 -7
- package/dist/integrations/configure/poolside.js.map +1 -1
- package/dist/integrations/configure/registry.d.ts +6 -0
- package/dist/integrations/configure/registry.js +1 -0
- package/dist/integrations/configure/registry.js.map +1 -1
- package/dist/integrations/configure/zcode.d.ts +6 -7
- package/dist/integrations/configure/zcode.js +26 -11
- package/dist/integrations/configure/zcode.js.map +1 -1
- package/dist/integrations/configure/zed.d.ts +16 -4
- package/dist/integrations/configure/zed.js +61 -13
- package/dist/integrations/configure/zed.js.map +1 -1
- package/dist/models/gguf/kv-cache.d.ts +20 -1
- package/dist/models/gguf/kv-cache.js +97 -7
- package/dist/models/gguf/kv-cache.js.map +1 -1
- package/dist/models/gguf/reader.d.ts +5 -3
- package/dist/models/gguf/reader.js +10 -6
- package/dist/models/gguf/reader.js.map +1 -1
- package/dist/runtime/llamacpp/args.d.ts +14 -0
- package/dist/runtime/llamacpp/args.js +48 -4
- package/dist/runtime/llamacpp/args.js.map +1 -1
- package/dist/runtime/llamacpp/ctx-ladder.d.ts +6 -3
- package/dist/runtime/llamacpp/ctx-ladder.js +6 -3
- package/dist/runtime/llamacpp/ctx-ladder.js.map +1 -1
- package/dist/runtime/llamacpp/fit-margin.d.ts +24 -0
- package/dist/runtime/llamacpp/fit-margin.js +31 -0
- package/dist/runtime/llamacpp/fit-margin.js.map +1 -1
- package/dist/runtime/llamacpp/generation-limits.d.ts +45 -0
- package/dist/runtime/llamacpp/generation-limits.js +61 -0
- package/dist/runtime/llamacpp/generation-limits.js.map +1 -0
- package/dist/runtime/llamacpp/load-plan.d.ts +14 -2
- package/dist/runtime/llamacpp/load-plan.js +64 -13
- package/dist/runtime/llamacpp/load-plan.js.map +1 -1
- package/dist/runtime/llamacpp/runtime.d.ts +1 -0
- package/dist/runtime/llamacpp/runtime.js +2 -0
- package/dist/runtime/llamacpp/runtime.js.map +1 -1
- package/dist/runtime/managed-engines/runtime.js +13 -2
- package/dist/runtime/managed-engines/runtime.js.map +1 -1
- package/dist/runtime/managed-engines/spec.d.ts +6 -0
- package/dist/runtime/managed-engines/spec.js.map +1 -1
- package/dist/runtime/managed-models/auto-limits.d.ts +47 -0
- package/dist/runtime/managed-models/auto-limits.js +60 -0
- package/dist/runtime/managed-models/auto-limits.js.map +1 -0
- package/dist/runtime/managed-models/index.d.ts +1 -0
- package/dist/runtime/managed-models/index.js +1 -0
- package/dist/runtime/managed-models/index.js.map +1 -1
- package/dist/runtime/mlx/config.d.ts +9 -5
- package/dist/runtime/mlx/config.js +12 -6
- package/dist/runtime/mlx/config.js.map +1 -1
- package/dist/runtime/mlx/model-files.d.ts +9 -0
- package/dist/runtime/mlx/model-files.js +26 -0
- package/dist/runtime/mlx/model-files.js.map +1 -1
- package/dist/runtime/mlx/runtime.d.ts +7 -0
- package/dist/runtime/mlx/runtime.js +24 -2
- package/dist/runtime/mlx/runtime.js.map +1 -1
- package/dist/runtime/sglang/adapter.d.ts +4 -0
- package/dist/runtime/sglang/adapter.js +9 -6
- package/dist/runtime/sglang/adapter.js.map +1 -1
- package/dist/runtime/sglang/engine.js +2 -1
- package/dist/runtime/sglang/engine.js.map +1 -1
- package/dist/runtime/sglang/memory.d.ts +11 -1
- package/dist/runtime/sglang/memory.js +34 -3
- package/dist/runtime/sglang/memory.js.map +1 -1
- package/dist/runtime/sglang/settings.d.ts +2 -1
- package/dist/runtime/sglang/settings.js +11 -7
- package/dist/runtime/sglang/settings.js.map +1 -1
- package/dist/runtime/vllm/adapter.d.ts +4 -0
- package/dist/runtime/vllm/adapter.js +9 -6
- package/dist/runtime/vllm/adapter.js.map +1 -1
- package/dist/runtime/vllm/engine.js +1 -0
- package/dist/runtime/vllm/engine.js.map +1 -1
- package/dist/runtime/vllm/memory.d.ts +12 -1
- package/dist/runtime/vllm/memory.js +44 -2
- package/dist/runtime/vllm/memory.js.map +1 -1
- package/dist/runtime/vllm/settings.d.ts +2 -1
- package/dist/runtime/vllm/settings.js +12 -7
- package/dist/runtime/vllm/settings.js.map +1 -1
- package/dist/server/public/context-window.d.ts +29 -0
- package/dist/server/public/context-window.js +77 -0
- package/dist/server/public/context-window.js.map +1 -0
- package/dist/server/public/decision-preview.js +1 -0
- package/dist/server/public/decision-preview.js.map +1 -1
- package/dist/server/public/errors.d.ts +15 -4
- package/dist/server/public/errors.js +53 -7
- package/dist/server/public/errors.js.map +1 -1
- package/dist/server/public/forward.js +65 -5
- package/dist/server/public/forward.js.map +1 -1
- package/dist/server/public/index.d.ts +1 -0
- package/dist/server/public/index.js +1 -0
- package/dist/server/public/index.js.map +1 -1
- package/dist/server/public/listing.d.ts +9 -2
- package/dist/server/public/listing.js +30 -9
- package/dist/server/public/listing.js.map +1 -1
- package/dist/server/public/responses.js +9 -5
- package/dist/server/public/responses.js.map +1 -1
- package/dist/server/public/system-messages.d.ts +39 -0
- package/dist/server/public/system-messages.js +166 -0
- package/dist/server/public/system-messages.js.map +1 -0
- package/dist/server/public/telemetry.d.ts +9 -0
- package/dist/server/public/telemetry.js +42 -6
- package/dist/server/public/telemetry.js.map +1 -1
- package/dist/server/public/thinking.d.ts +26 -0
- package/dist/server/public/thinking.js +62 -0
- package/dist/server/public/thinking.js.map +1 -0
- package/dist/server/public/trace.d.ts +8 -0
- package/dist/server/public/trace.js +17 -0
- package/dist/server/public/trace.js.map +1 -1
- package/dist/server/public/types.d.ts +8 -0
- package/dist/server/shims/index.d.ts +1 -0
- package/dist/server/shims/index.js +1 -0
- package/dist/server/shims/index.js.map +1 -1
- package/dist/server/shims/reminders.d.ts +8 -0
- package/dist/server/shims/reminders.js +14 -0
- package/dist/server/shims/reminders.js.map +1 -0
- package/dist/server/shims/responses.d.ts +33 -9
- package/dist/server/shims/responses.js +160 -36
- package/dist/server/shims/responses.js.map +1 -1
- package/dist/settings/default-migrations.d.ts +34 -0
- package/dist/settings/default-migrations.js +47 -0
- package/dist/settings/default-migrations.js.map +1 -0
- package/dist/settings/schema/atomic-prism.json +23 -9
- package/dist/settings/schema/llamacpp-upstream.json +23 -9
- package/dist/settings/schema/llamacpp.json +23 -9
- package/dist/settings/schema/sglang.json +8 -8
- package/dist/settings/schema/vllm.json +8 -8
- package/dist/settings/schema.js +1 -0
- package/dist/settings/schema.js.map +1 -1
- package/dist/settings/store.d.ts +6 -0
- package/dist/settings/store.js +18 -1
- package/dist/settings/store.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The backup Claude Code's and OpenClaude's writers keep beside each config file they edit, so the
|
|
3
|
+
* desktop app's Disconnect can put the user's own values back — even after a CLI `launch` made the
|
|
4
|
+
* connection.
|
|
5
|
+
*
|
|
6
|
+
* Twin of `src-tauri/src/core/system/claude_config.rs` in the app: same sidecar name, same format,
|
|
7
|
+
* same rules. Connect records, in `<config file>.atomic-chat-backup.json`, what every key it sets
|
|
8
|
+
* held before; a reconnect first undoes the previous Connect in memory, so the sidecar keeps
|
|
9
|
+
* describing the user's own values, never an earlier Atomic Chat write. A value the user changed
|
|
10
|
+
* after Connect is theirs and is not restored. Settings an earlier release wrote without a sidecar
|
|
11
|
+
* are recognised by pointing at this server and taken out rather than recorded as the user's.
|
|
12
|
+
*
|
|
13
|
+
* A path is a list of segments: a string is an object key, `{ id: X }` the element of an array whose
|
|
14
|
+
* `id` is X — an element that is ours by that id, removed whatever it holds now. An empty path is
|
|
15
|
+
* the whole file.
|
|
16
|
+
*/
|
|
17
|
+
import type { ConfigFs, JsonValue } from '../config-io.js';
|
|
18
|
+
import type { JsonObject } from './json-tree.js';
|
|
19
|
+
export declare const BACKUP_SUFFIX = ".atomic-chat-backup.json";
|
|
20
|
+
export type PathSegment = string | {
|
|
21
|
+
id: string;
|
|
22
|
+
};
|
|
23
|
+
export type JsonPath = PathSegment[];
|
|
24
|
+
export interface BackupEntry {
|
|
25
|
+
path: JsonPath;
|
|
26
|
+
existed: boolean;
|
|
27
|
+
previous?: JsonValue;
|
|
28
|
+
written: JsonValue;
|
|
29
|
+
}
|
|
30
|
+
export interface Backup {
|
|
31
|
+
about: string;
|
|
32
|
+
version: 1;
|
|
33
|
+
fileExisted: boolean;
|
|
34
|
+
created: JsonPath[];
|
|
35
|
+
entries: BackupEntry[];
|
|
36
|
+
}
|
|
37
|
+
/** A key Connect sets. */
|
|
38
|
+
export type JsonWrite = [JsonPath, JsonValue];
|
|
39
|
+
/** The output cap written beside a known window: a quarter of it, at most 8192. */
|
|
40
|
+
export declare function outputCap(contextLength: number): number;
|
|
41
|
+
/**
|
|
42
|
+
* A config-directory variable the way the agents take it: absolute, or `~`-relative (expanded
|
|
43
|
+
* against `home`). Anything else is ignored.
|
|
44
|
+
*/
|
|
45
|
+
export declare function configDirFrom(value: string | undefined, home: string): string | undefined;
|
|
46
|
+
export interface OurServer {
|
|
47
|
+
host: string;
|
|
48
|
+
port: number;
|
|
49
|
+
}
|
|
50
|
+
/** The server a URL we are about to write points at. */
|
|
51
|
+
export declare function ourServerFromUrl(url: string): OurServer | undefined;
|
|
52
|
+
/** `url` is this server: its exact host and port, or a loopback address with its port. */
|
|
53
|
+
export declare function isOurServerUrl(server: OurServer | undefined, url: string): boolean;
|
|
54
|
+
/** Structural equality, key order ignored (the Rust side compares `serde_json::Value`s). */
|
|
55
|
+
export declare function jsonEqual(a: JsonValue | undefined, b: JsonValue | undefined): boolean;
|
|
56
|
+
export declare function getAt(root: JsonValue, path: JsonPath): JsonValue | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Apply `writes` to `root` and describe them. `carry` lists paths the previous Connect wrote that
|
|
59
|
+
* this one keeps as they are when it does not write them itself. `forgetLegacy` runs only when there
|
|
60
|
+
* is no backup.
|
|
61
|
+
*/
|
|
62
|
+
export declare function redo(root: JsonObject, previous: Backup | undefined, fileExisted: boolean, writes: JsonWrite[], carry: JsonPath[], forgetLegacy: (root: JsonObject) => void): Backup;
|
|
63
|
+
/** The whole-file backup of a file Connect replaces outright (OpenClaude's startup profile). */
|
|
64
|
+
export declare function wholeFileBackup(existed: boolean, previous: JsonValue | undefined, written: JsonValue): Backup;
|
|
65
|
+
export declare const backupPath: (config: string) => string;
|
|
66
|
+
/** The sidecar next to `config`; one that cannot be read counts as none, as on the Rust side. */
|
|
67
|
+
export declare function readBackup(fs: ConfigFs, config: string): Promise<Backup | undefined>;
|
|
68
|
+
/**
|
|
69
|
+
* Write a config the way the desktop does: through a symbolic link rather than over it, keeping an
|
|
70
|
+
* existing file's permissions and giving a new one owner-only access (these files carry keys).
|
|
71
|
+
*/
|
|
72
|
+
export declare function writeConfigFile(fs: ConfigFs, path: string, contents: string): Promise<void>;
|
|
73
|
+
export declare function writeBackup(fs: ConfigFs, config: string, backup: Backup): Promise<void>;
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The backup Claude Code's and OpenClaude's writers keep beside each config file they edit, so the
|
|
3
|
+
* desktop app's Disconnect can put the user's own values back — even after a CLI `launch` made the
|
|
4
|
+
* connection.
|
|
5
|
+
*
|
|
6
|
+
* Twin of `src-tauri/src/core/system/claude_config.rs` in the app: same sidecar name, same format,
|
|
7
|
+
* same rules. Connect records, in `<config file>.atomic-chat-backup.json`, what every key it sets
|
|
8
|
+
* held before; a reconnect first undoes the previous Connect in memory, so the sidecar keeps
|
|
9
|
+
* describing the user's own values, never an earlier Atomic Chat write. A value the user changed
|
|
10
|
+
* after Connect is theirs and is not restored. Settings an earlier release wrote without a sidecar
|
|
11
|
+
* are recognised by pointing at this server and taken out rather than recorded as the user's.
|
|
12
|
+
*
|
|
13
|
+
* A path is a list of segments: a string is an object key, `{ id: X }` the element of an array whose
|
|
14
|
+
* `id` is X — an element that is ours by that id, removed whatever it holds now. An empty path is
|
|
15
|
+
* the whole file.
|
|
16
|
+
*/
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { canonicalJson, parseJsonStrict } from '../config-io.js';
|
|
19
|
+
import { asJsonArray, asJsonObject } from './json-tree.js';
|
|
20
|
+
export const BACKUP_SUFFIX = '.atomic-chat-backup.json';
|
|
21
|
+
const BACKUP_ABOUT = 'Atomic Chat keeps the values it replaced here and puts them back when you disconnect.';
|
|
22
|
+
/** The output cap written beside a known window: a quarter of it, at most 8192. */
|
|
23
|
+
export function outputCap(contextLength) {
|
|
24
|
+
return Math.min(Math.floor(contextLength / 4), 8192);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A config-directory variable the way the agents take it: absolute, or `~`-relative (expanded
|
|
28
|
+
* against `home`). Anything else is ignored.
|
|
29
|
+
*/
|
|
30
|
+
export function configDirFrom(value, home) {
|
|
31
|
+
const trimmed = value?.trim();
|
|
32
|
+
if (!trimmed)
|
|
33
|
+
return undefined;
|
|
34
|
+
if (trimmed === '~')
|
|
35
|
+
return home;
|
|
36
|
+
if (trimmed.startsWith('~/') || trimmed.startsWith('~\\'))
|
|
37
|
+
return join(home, trimmed.slice(2));
|
|
38
|
+
return /^(?:\/|[A-Za-z]:[\\/]|\\\\)/.test(trimmed) ? trimmed : undefined;
|
|
39
|
+
}
|
|
40
|
+
function normaliseHost(host) {
|
|
41
|
+
const bare = host.trim().replace(/^\[/, '').replace(/\]$/, '').toLowerCase();
|
|
42
|
+
return bare === '0.0.0.0' || bare === '::' || bare === '' ? '127.0.0.1' : bare;
|
|
43
|
+
}
|
|
44
|
+
/** Host (lower-case, IPv6 without brackets) and port of a URL; a scheme-less `host:port` works. */
|
|
45
|
+
function hostAndPort(raw) {
|
|
46
|
+
const trimmed = raw.trim();
|
|
47
|
+
if (trimmed === '')
|
|
48
|
+
return undefined;
|
|
49
|
+
const parse = (text) => {
|
|
50
|
+
try {
|
|
51
|
+
const url = new URL(text);
|
|
52
|
+
return url.hostname === '' ? undefined : url;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const url = parse(trimmed) ?? parse(`http://${trimmed}`);
|
|
59
|
+
if (!url)
|
|
60
|
+
return undefined;
|
|
61
|
+
const defaults = { 'http:': 80, 'https:': 443, 'ws:': 80, 'wss:': 443 };
|
|
62
|
+
const port = url.port === '' ? defaults[url.protocol] : Number(url.port);
|
|
63
|
+
if (port === undefined)
|
|
64
|
+
return undefined;
|
|
65
|
+
const host = url.hostname.replace(/^\[/, '').replace(/\]$/, '').replace(/\.$/, '').toLowerCase();
|
|
66
|
+
return { host, port };
|
|
67
|
+
}
|
|
68
|
+
function isLoopbackHost(host) {
|
|
69
|
+
return (host === 'localhost' ||
|
|
70
|
+
host.endsWith('.localhost') ||
|
|
71
|
+
/^127\.\d+\.\d+\.\d+$/.test(host) ||
|
|
72
|
+
host === '::1' ||
|
|
73
|
+
host === '0.0.0.0' ||
|
|
74
|
+
host === '::');
|
|
75
|
+
}
|
|
76
|
+
/** The server a URL we are about to write points at. */
|
|
77
|
+
export function ourServerFromUrl(url) {
|
|
78
|
+
const parsed = hostAndPort(url);
|
|
79
|
+
return parsed && { host: normaliseHost(parsed.host), port: parsed.port };
|
|
80
|
+
}
|
|
81
|
+
/** `url` is this server: its exact host and port, or a loopback address with its port. */
|
|
82
|
+
export function isOurServerUrl(server, url) {
|
|
83
|
+
const parsed = server && hostAndPort(url);
|
|
84
|
+
return (parsed !== undefined &&
|
|
85
|
+
server !== undefined &&
|
|
86
|
+
parsed.port === server.port &&
|
|
87
|
+
(parsed.host === server.host || isLoopbackHost(parsed.host)));
|
|
88
|
+
}
|
|
89
|
+
// ── Paths in a JSON tree ──────────────────────────────────────────────────────────────────────
|
|
90
|
+
const idOf = (segment) => typeof segment === 'object' ? segment.id : undefined;
|
|
91
|
+
const hasId = (value, id) => asJsonObject(value)?.['id'] === id;
|
|
92
|
+
const endsInId = (path) => path.length > 0 && idOf(path[path.length - 1]) !== undefined;
|
|
93
|
+
const samePath = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
94
|
+
/** Structural equality, key order ignored (the Rust side compares `serde_json::Value`s). */
|
|
95
|
+
export function jsonEqual(a, b) {
|
|
96
|
+
if (a === b)
|
|
97
|
+
return true;
|
|
98
|
+
if (a === undefined || b === undefined || a === null || b === null)
|
|
99
|
+
return false;
|
|
100
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
101
|
+
return (Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((v, i) => jsonEqual(v, b[i])));
|
|
102
|
+
}
|
|
103
|
+
if (typeof a === 'object' && typeof b === 'object') {
|
|
104
|
+
const ka = Object.keys(a);
|
|
105
|
+
const kb = Object.keys(b);
|
|
106
|
+
return ka.length === kb.length && ka.every((k) => k in b && jsonEqual(a[k], b[k]));
|
|
107
|
+
}
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
export function getAt(root, path) {
|
|
111
|
+
let node = root;
|
|
112
|
+
for (const segment of path) {
|
|
113
|
+
const id = idOf(segment);
|
|
114
|
+
if (id !== undefined)
|
|
115
|
+
node = asJsonArray(node)?.find((e) => hasId(e, id));
|
|
116
|
+
else {
|
|
117
|
+
const object = asJsonObject(node);
|
|
118
|
+
node =
|
|
119
|
+
object && Object.prototype.hasOwnProperty.call(object, segment)
|
|
120
|
+
? object[segment]
|
|
121
|
+
: undefined;
|
|
122
|
+
}
|
|
123
|
+
if (node === undefined)
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
return node;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Set `value` at `path`, replacing missing containers on the way — or values of the wrong kind —
|
|
130
|
+
* with empty ones and recording them in `created`.
|
|
131
|
+
*/
|
|
132
|
+
function setAt(root, path, value, created) {
|
|
133
|
+
let node = root;
|
|
134
|
+
for (let i = 0; i < path.length; i++) {
|
|
135
|
+
const segment = path[i];
|
|
136
|
+
const id = idOf(segment);
|
|
137
|
+
const last = i === path.length - 1;
|
|
138
|
+
let child;
|
|
139
|
+
const store = (next) => {
|
|
140
|
+
if (id !== undefined) {
|
|
141
|
+
const items = node;
|
|
142
|
+
const index = items.findIndex((e) => hasId(e, id));
|
|
143
|
+
if (index >= 0)
|
|
144
|
+
items[index] = next;
|
|
145
|
+
else
|
|
146
|
+
items.push(next);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
;
|
|
150
|
+
node[segment] = next;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
if (last) {
|
|
154
|
+
store(value);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
child =
|
|
158
|
+
id !== undefined
|
|
159
|
+
? node.find((e) => hasId(e, id))
|
|
160
|
+
: Object.prototype.hasOwnProperty.call(node, segment)
|
|
161
|
+
? node[segment]
|
|
162
|
+
: undefined;
|
|
163
|
+
const wantsArray = idOf(path[i + 1]) !== undefined;
|
|
164
|
+
const fits = wantsArray ? Array.isArray(child) : asJsonObject(child) !== undefined;
|
|
165
|
+
if (!fits) {
|
|
166
|
+
child = wantsArray ? [] : {};
|
|
167
|
+
store(child);
|
|
168
|
+
const prefix = path.slice(0, i + 1);
|
|
169
|
+
if (!created.some((p) => samePath(p, prefix)))
|
|
170
|
+
created.push(prefix);
|
|
171
|
+
}
|
|
172
|
+
node = child;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function removeAt(root, path) {
|
|
176
|
+
if (path.length === 0)
|
|
177
|
+
return;
|
|
178
|
+
const parent = getAt(root, path.slice(0, -1));
|
|
179
|
+
const segment = path[path.length - 1];
|
|
180
|
+
const id = idOf(segment);
|
|
181
|
+
if (id !== undefined) {
|
|
182
|
+
const items = asJsonArray(parent);
|
|
183
|
+
if (!items)
|
|
184
|
+
return;
|
|
185
|
+
for (let i = items.length - 1; i >= 0; i--)
|
|
186
|
+
if (hasId(items[i], id))
|
|
187
|
+
items.splice(i, 1);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
const object = asJsonObject(parent);
|
|
191
|
+
if (object)
|
|
192
|
+
delete object[segment];
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Put back what `backup` recorded wherever the value is still the one we wrote. An element that is
|
|
197
|
+
* ours by its id goes whatever it holds now: the agent may have rewritten it.
|
|
198
|
+
*/
|
|
199
|
+
function restore(root, backup) {
|
|
200
|
+
for (const entry of [...backup.entries].reverse()) {
|
|
201
|
+
const current = getAt(root, entry.path);
|
|
202
|
+
if (current === undefined)
|
|
203
|
+
continue;
|
|
204
|
+
const byId = endsInId(entry.path);
|
|
205
|
+
if (!byId && !jsonEqual(current, entry.written))
|
|
206
|
+
continue;
|
|
207
|
+
if (entry.existed && !byId)
|
|
208
|
+
setAt(root, entry.path, entry.previous ?? null, []);
|
|
209
|
+
else
|
|
210
|
+
removeAt(root, entry.path);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Apply `writes` to `root` and describe them. `carry` lists paths the previous Connect wrote that
|
|
215
|
+
* this one keeps as they are when it does not write them itself. `forgetLegacy` runs only when there
|
|
216
|
+
* is no backup.
|
|
217
|
+
*/
|
|
218
|
+
export function redo(root, previous, fileExisted, writes, carry, forgetLegacy) {
|
|
219
|
+
let created = [];
|
|
220
|
+
let existedBefore = fileExisted;
|
|
221
|
+
const all = [...writes];
|
|
222
|
+
if (previous) {
|
|
223
|
+
const kept = [];
|
|
224
|
+
for (const path of carry) {
|
|
225
|
+
if (writes.some(([written]) => samePath(written, path)))
|
|
226
|
+
continue;
|
|
227
|
+
const entry = previous.entries.find((e) => samePath(e.path, path));
|
|
228
|
+
if (entry && jsonEqual(getAt(root, entry.path), entry.written))
|
|
229
|
+
kept.push([entry.path, entry.written]);
|
|
230
|
+
}
|
|
231
|
+
restore(root, previous);
|
|
232
|
+
all.push(...kept);
|
|
233
|
+
created = previous.created.map((p) => [...p]);
|
|
234
|
+
existedBefore = previous.fileExisted;
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
forgetLegacy(root);
|
|
238
|
+
}
|
|
239
|
+
const entries = [];
|
|
240
|
+
for (const [path, value] of all) {
|
|
241
|
+
const before = endsInId(path) ? undefined : getAt(root, path);
|
|
242
|
+
setAt(root, path, structuredClone(value), created);
|
|
243
|
+
const entry = { path, existed: before !== undefined, written: value };
|
|
244
|
+
if (before !== undefined && before !== null)
|
|
245
|
+
entry.previous = structuredClone(before);
|
|
246
|
+
entries.push(entry);
|
|
247
|
+
}
|
|
248
|
+
return { about: BACKUP_ABOUT, version: 1, fileExisted: existedBefore, created, entries };
|
|
249
|
+
}
|
|
250
|
+
/** The whole-file backup of a file Connect replaces outright (OpenClaude's startup profile). */
|
|
251
|
+
export function wholeFileBackup(existed, previous, written) {
|
|
252
|
+
const entry = { path: [], existed, written };
|
|
253
|
+
if (existed && previous !== undefined && previous !== null)
|
|
254
|
+
entry.previous = previous;
|
|
255
|
+
return { about: BACKUP_ABOUT, version: 1, fileExisted: existed, created: [], entries: [entry] };
|
|
256
|
+
}
|
|
257
|
+
// ── Files ─────────────────────────────────────────────────────────────────────────────────────
|
|
258
|
+
export const backupPath = (config) => `${config}${BACKUP_SUFFIX}`;
|
|
259
|
+
/** The sidecar next to `config`; one that cannot be read counts as none, as on the Rust side. */
|
|
260
|
+
export async function readBackup(fs, config) {
|
|
261
|
+
const text = await fs.read(backupPath(config));
|
|
262
|
+
if (text === undefined)
|
|
263
|
+
return undefined;
|
|
264
|
+
try {
|
|
265
|
+
const parsed = asJsonObject(parseJsonStrict(text, fs.absolute(backupPath(config))));
|
|
266
|
+
if (!parsed || !Array.isArray(parsed['entries']) || typeof parsed['fileExisted'] !== 'boolean')
|
|
267
|
+
return undefined;
|
|
268
|
+
return {
|
|
269
|
+
about: BACKUP_ABOUT,
|
|
270
|
+
version: 1,
|
|
271
|
+
fileExisted: parsed['fileExisted'],
|
|
272
|
+
created: (asJsonArray(parsed['created']) ?? []),
|
|
273
|
+
entries: parsed['entries'],
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
return undefined;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Write a config the way the desktop does: through a symbolic link rather than over it, keeping an
|
|
282
|
+
* existing file's permissions and giving a new one owner-only access (these files carry keys).
|
|
283
|
+
*/
|
|
284
|
+
export async function writeConfigFile(fs, path, contents) {
|
|
285
|
+
const target = await fs.linkTarget(path);
|
|
286
|
+
const mode = (await fs.permissions(target)) ?? 0o600;
|
|
287
|
+
await fs.write(target, contents, { mode });
|
|
288
|
+
}
|
|
289
|
+
export async function writeBackup(fs, config, backup) {
|
|
290
|
+
await writeConfigFile(fs, backupPath(config), canonicalJson(backup));
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=json-backup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-backup.js","sourceRoot":"","sources":["../../../src/integrations/configure/json-backup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Restorable edits to an agent's own JSON config — the TypeScript side of the app's
|
|
3
|
+
* `core/system/json_key_backup.rs`, byte for byte.
|
|
4
|
+
*
|
|
5
|
+
* Connect overwrites a handful of keys in a file the user also edits (the model an agent opens on,
|
|
6
|
+
* a gateway mode, an allow-list). Before writing, it records what each of those keys held — and the
|
|
7
|
+
* value it put there — in a sidecar `<config>.atomic-chat-backup.json` next to the file. The app's
|
|
8
|
+
* Disconnect puts a key back only while it still holds our value: a key the user changed after
|
|
9
|
+
* Connect is theirs. The CLI records the same sidecar, so a connection made from the terminal is
|
|
10
|
+
* undone by the app's Disconnect too.
|
|
11
|
+
*/
|
|
12
|
+
import type { ConfigFs, JsonValue } from '../config-io.js';
|
|
13
|
+
/** Appended to the config file's name to name its sidecar. */
|
|
14
|
+
export declare const BACKUP_SUFFIX = ".atomic-chat-backup.json";
|
|
15
|
+
/** One key Connect changed: where, what it held before (absent: it was absent) and what we wrote. */
|
|
16
|
+
export interface KeyBackup {
|
|
17
|
+
path: string[];
|
|
18
|
+
before?: JsonValue;
|
|
19
|
+
ours?: JsonValue;
|
|
20
|
+
}
|
|
21
|
+
/** A sidecar. `seeded` is agent-specific: values Connect added that are not a key of their own. */
|
|
22
|
+
export interface Backup {
|
|
23
|
+
keys: KeyBackup[];
|
|
24
|
+
seeded: JsonValue[];
|
|
25
|
+
}
|
|
26
|
+
/** The value at `path`, when every step on the way is an object. */
|
|
27
|
+
export declare function getAt(root: JsonValue | undefined, path: string[]): JsonValue | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* The backup of a Connect that turned `before` into `after`, for the keys at `paths`. A key Connect
|
|
30
|
+
* left as it found it gets no entry. A key an earlier Connect already recorded keeps that earlier
|
|
31
|
+
* `before` while it still held the earlier `ours` — otherwise the user changed it in between, and
|
|
32
|
+
* that is what Disconnect returns to. Earlier entries for keys this Connect does not touch are
|
|
33
|
+
* carried over.
|
|
34
|
+
*/
|
|
35
|
+
export declare function trackKeys(before: JsonValue, after: JsonValue, paths: string[][], previous: KeyBackup[]): KeyBackup[];
|
|
36
|
+
/** The sidecar's text, in the format every JSON writer here uses. */
|
|
37
|
+
export declare function renderBackup(backup: Backup): string;
|
|
38
|
+
/** Parse a sidecar; `undefined` for anything that is not one. */
|
|
39
|
+
export declare function parseBackup(text: string): Backup | undefined;
|
|
40
|
+
export declare function readBackupText(fs: ConfigFs, configPath: string): Promise<string | undefined>;
|
|
41
|
+
export declare function readBackup(fs: ConfigFs, configPath: string): Promise<Backup | undefined>;
|
|
42
|
+
/** Write the sidecar with the config's own permissions: it holds the same values, keys included. */
|
|
43
|
+
export declare function writeBackupText(fs: ConfigFs, configPath: string, text: string): Promise<void>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Restorable edits to an agent's own JSON config — the TypeScript side of the app's
|
|
3
|
+
* `core/system/json_key_backup.rs`, byte for byte.
|
|
4
|
+
*
|
|
5
|
+
* Connect overwrites a handful of keys in a file the user also edits (the model an agent opens on,
|
|
6
|
+
* a gateway mode, an allow-list). Before writing, it records what each of those keys held — and the
|
|
7
|
+
* value it put there — in a sidecar `<config>.atomic-chat-backup.json` next to the file. The app's
|
|
8
|
+
* Disconnect puts a key back only while it still holds our value: a key the user changed after
|
|
9
|
+
* Connect is theirs. The CLI records the same sidecar, so a connection made from the terminal is
|
|
10
|
+
* undone by the app's Disconnect too.
|
|
11
|
+
*/
|
|
12
|
+
import { canonicalJson } from '../config-io.js';
|
|
13
|
+
import { asJsonObject } from './json-tree.js';
|
|
14
|
+
/** Appended to the config file's name to name its sidecar. */
|
|
15
|
+
export const BACKUP_SUFFIX = '.atomic-chat-backup.json';
|
|
16
|
+
/** The value at `path`, when every step on the way is an object. */
|
|
17
|
+
export function getAt(root, path) {
|
|
18
|
+
let node = root;
|
|
19
|
+
for (const key of path) {
|
|
20
|
+
const obj = asJsonObject(node);
|
|
21
|
+
if (obj === undefined || !Object.prototype.hasOwnProperty.call(obj, key))
|
|
22
|
+
return undefined;
|
|
23
|
+
node = obj[key];
|
|
24
|
+
}
|
|
25
|
+
return node;
|
|
26
|
+
}
|
|
27
|
+
function same(a, b) {
|
|
28
|
+
if (a === undefined || b === undefined)
|
|
29
|
+
return a === b;
|
|
30
|
+
return canonicalJson(a) === canonicalJson(b);
|
|
31
|
+
}
|
|
32
|
+
function samePath(a, b) {
|
|
33
|
+
return a.length === b.length && a.every((part, i) => part === b[i]);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The backup of a Connect that turned `before` into `after`, for the keys at `paths`. A key Connect
|
|
37
|
+
* left as it found it gets no entry. A key an earlier Connect already recorded keeps that earlier
|
|
38
|
+
* `before` while it still held the earlier `ours` — otherwise the user changed it in between, and
|
|
39
|
+
* that is what Disconnect returns to. Earlier entries for keys this Connect does not touch are
|
|
40
|
+
* carried over.
|
|
41
|
+
*/
|
|
42
|
+
export function trackKeys(before, after, paths, previous) {
|
|
43
|
+
const out = [];
|
|
44
|
+
for (const path of paths) {
|
|
45
|
+
const now = getAt(before, path);
|
|
46
|
+
const ours = getAt(after, path);
|
|
47
|
+
const earlier = previous.find((entry) => samePath(entry.path, path));
|
|
48
|
+
const original = earlier !== undefined && same(earlier.ours, now) ? earlier.before : now;
|
|
49
|
+
if (!same(original, ours)) {
|
|
50
|
+
out.push({
|
|
51
|
+
path,
|
|
52
|
+
...(original !== undefined ? { before: original } : {}),
|
|
53
|
+
...(ours !== undefined ? { ours } : {}),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
for (const entry of previous) {
|
|
58
|
+
if (!paths.some((path) => samePath(path, entry.path)))
|
|
59
|
+
out.push(entry);
|
|
60
|
+
}
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
63
|
+
/** The sidecar's text, in the format every JSON writer here uses. */
|
|
64
|
+
export function renderBackup(backup) {
|
|
65
|
+
return canonicalJson({
|
|
66
|
+
keys: backup.keys.map((entry) => ({
|
|
67
|
+
path: entry.path,
|
|
68
|
+
...(entry.before !== undefined ? { before: entry.before } : {}),
|
|
69
|
+
...(entry.ours !== undefined ? { ours: entry.ours } : {}),
|
|
70
|
+
})),
|
|
71
|
+
...(backup.seeded.length > 0 ? { seeded: backup.seeded } : {}),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/** Parse a sidecar; `undefined` for anything that is not one. */
|
|
75
|
+
export function parseBackup(text) {
|
|
76
|
+
let root;
|
|
77
|
+
try {
|
|
78
|
+
root = JSON.parse(text);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
const keys = asJsonObject(root)?.['keys'];
|
|
84
|
+
if (!Array.isArray(keys))
|
|
85
|
+
return undefined;
|
|
86
|
+
const parsed = [];
|
|
87
|
+
for (const raw of keys) {
|
|
88
|
+
const entry = asJsonObject(raw);
|
|
89
|
+
const path = entry?.['path'];
|
|
90
|
+
if (!entry || !Array.isArray(path) || !path.every((p) => typeof p === 'string'))
|
|
91
|
+
return undefined;
|
|
92
|
+
parsed.push({
|
|
93
|
+
path: path,
|
|
94
|
+
...(entry['before'] !== undefined ? { before: entry['before'] } : {}),
|
|
95
|
+
...(entry['ours'] !== undefined ? { ours: entry['ours'] } : {}),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
const seeded = asJsonObject(root)?.['seeded'];
|
|
99
|
+
return { keys: parsed, seeded: Array.isArray(seeded) ? seeded : [] };
|
|
100
|
+
}
|
|
101
|
+
export async function readBackupText(fs, configPath) {
|
|
102
|
+
return fs.read(`${configPath}${BACKUP_SUFFIX}`);
|
|
103
|
+
}
|
|
104
|
+
export async function readBackup(fs, configPath) {
|
|
105
|
+
const text = await readBackupText(fs, configPath);
|
|
106
|
+
return text === undefined ? undefined : parseBackup(text);
|
|
107
|
+
}
|
|
108
|
+
/** Write the sidecar with the config's own permissions: it holds the same values, keys included. */
|
|
109
|
+
export async function writeBackupText(fs, configPath, text) {
|
|
110
|
+
const mode = await fs.permissions(configPath);
|
|
111
|
+
await fs.write(`${configPath}${BACKUP_SUFFIX}`, text, mode !== undefined ? { mode } : {});
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=json-key-backup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-key-backup.js","sourceRoot":"","sources":["../../../src/integrations/configure/json-key-backup.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Kilo Code — `~/.config/kilo
|
|
2
|
+
* Kilo Code — `kilo.jsonc` in `$KILO_CONFIG_DIR`, else `~/.config/kilo`.
|
|
3
3
|
*
|
|
4
|
-
* Port of `configure_kilo` in `src-tauri/src/core/system/commands.rs`.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Port of `configure_kilo` in `src-tauri/src/core/system/commands.rs`. Kilo opens on the model it
|
|
5
|
+
* last used for its agent before the one this config selects, so `launch` also starts it with
|
|
6
|
+
* `--model atomic/<id>` (`runArgsFor` in the catalog).
|
|
7
7
|
*/
|
|
8
8
|
import type { ConfigureInput } from './registry.js';
|
|
9
9
|
export declare function configureKilo(input: ConfigureInput): Promise<void>;
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Kilo Code — `~/.config/kilo
|
|
2
|
+
* Kilo Code — `kilo.jsonc` in `$KILO_CONFIG_DIR`, else `~/.config/kilo`.
|
|
3
3
|
*
|
|
4
|
-
* Port of `configure_kilo` in `src-tauri/src/core/system/commands.rs`.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Port of `configure_kilo` in `src-tauri/src/core/system/commands.rs`. Kilo opens on the model it
|
|
5
|
+
* last used for its agent before the one this config selects, so `launch` also starts it with
|
|
6
|
+
* `--model atomic/<id>` (`runArgsFor` in the catalog).
|
|
7
7
|
*/
|
|
8
8
|
import { registerWriter } from './registry.js';
|
|
9
|
-
import { writeOpencodeStyleConfig } from './opencode-style.js';
|
|
9
|
+
import { kiloTarget, writeOpencodeStyleConfig } from './opencode-style.js';
|
|
10
10
|
export function configureKilo(input) {
|
|
11
|
-
return writeOpencodeStyleConfig(input, {
|
|
12
|
-
dir: '.config/kilo',
|
|
13
|
-
file: 'kilo.jsonc',
|
|
11
|
+
return writeOpencodeStyleConfig(input, kiloTarget(input.env), {
|
|
14
12
|
schema: 'https://app.kilo.ai/config.json',
|
|
15
|
-
lenient: true,
|
|
16
13
|
});
|
|
17
14
|
}
|
|
18
15
|
registerWriter('kilo', configureKilo);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kilo.js","sourceRoot":"","sources":["../../../src/integrations/configure/kilo.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"kilo.js","sourceRoot":"","sources":["../../../src/integrations/configure/kilo.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAE1E,MAAM,UAAU,aAAa,CAAC,KAAqB;IACjD,OAAO,wBAAwB,CAAC,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;QAC5D,MAAM,EAAE,iCAAiC;KAC1C,CAAC,CAAA;AACJ,CAAC;AAED,cAAc,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenHands, Poolside and Muse Code read their endpoint from the environment only. Older releases
|
|
3
|
+
* persisted it — a marked block in the user's shell rc, `setx` on Windows — which captured every
|
|
4
|
+
* other use of the agent (a cloud key replaced by our placeholder, a dead localhost once the server
|
|
5
|
+
* stops). Now the variables are set only on the process we launch (`childEnv`, and inline in the
|
|
6
|
+
* app's terminal), and Connect removes the block an older release wrote: exactly the region between
|
|
7
|
+
* its paired marker lines, never a user's own export of the same variable. Mirrors
|
|
8
|
+
* `remove_legacy_env_agent_config` in the app's `core/system/commands.rs`; the Windows `setx`
|
|
9
|
+
* variables are removed by the app alone.
|
|
10
|
+
*/
|
|
11
|
+
import type { ConfigFs } from '../config-io.js';
|
|
12
|
+
import type { ConfigureInput } from './registry.js';
|
|
13
|
+
/** `content` without the region between (and including) the paired `marker` lines. */
|
|
14
|
+
export declare function removeMarkedEnvBlock(content: string, marker: string): string;
|
|
15
|
+
/** Remove `marker`'s block from every rc file that has one; files without it are not touched. */
|
|
16
|
+
export declare function removeLegacyEnvBlocks(fs: ConfigFs, marker: string): Promise<void>;
|
|
17
|
+
/** The writer of an agent configured through its launch environment alone. */
|
|
18
|
+
export declare function legacyEnvAgentWriter(marker: string): (input: ConfigureInput) => Promise<void>;
|