@idcloudhost/ai-connect 0.1.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/LICENSE +21 -0
- package/README.md +287 -0
- package/dist/adapters/aider.d.ts +11 -0
- package/dist/adapters/aider.d.ts.map +1 -0
- package/dist/adapters/aider.js +69 -0
- package/dist/adapters/aider.js.map +1 -0
- package/dist/adapters/claude-code.d.ts +17 -0
- package/dist/adapters/claude-code.d.ts.map +1 -0
- package/dist/adapters/claude-code.js +73 -0
- package/dist/adapters/claude-code.js.map +1 -0
- package/dist/adapters/codex.d.ts +11 -0
- package/dist/adapters/codex.d.ts.map +1 -0
- package/dist/adapters/codex.js +71 -0
- package/dist/adapters/codex.js.map +1 -0
- package/dist/adapters/continue.d.ts +7 -0
- package/dist/adapters/continue.d.ts.map +1 -0
- package/dist/adapters/continue.js +79 -0
- package/dist/adapters/continue.js.map +1 -0
- package/dist/adapters/crush.d.ts +4 -0
- package/dist/adapters/crush.d.ts.map +1 -0
- package/dist/adapters/crush.js +72 -0
- package/dist/adapters/crush.js.map +1 -0
- package/dist/adapters/goose.d.ts +11 -0
- package/dist/adapters/goose.d.ts.map +1 -0
- package/dist/adapters/goose.js +68 -0
- package/dist/adapters/goose.js.map +1 -0
- package/dist/adapters/helpers.d.ts +33 -0
- package/dist/adapters/helpers.d.ts.map +1 -0
- package/dist/adapters/helpers.js +117 -0
- package/dist/adapters/helpers.js.map +1 -0
- package/dist/adapters/hermes.d.ts +11 -0
- package/dist/adapters/hermes.d.ts.map +1 -0
- package/dist/adapters/hermes.js +100 -0
- package/dist/adapters/hermes.js.map +1 -0
- package/dist/adapters/index.d.ts +20 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +60 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/manual.d.ts +6 -0
- package/dist/adapters/manual.d.ts.map +1 -0
- package/dist/adapters/manual.js +87 -0
- package/dist/adapters/manual.js.map +1 -0
- package/dist/adapters/omp.d.ts +8 -0
- package/dist/adapters/omp.d.ts.map +1 -0
- package/dist/adapters/omp.js +64 -0
- package/dist/adapters/omp.js.map +1 -0
- package/dist/adapters/openclaw.d.ts +10 -0
- package/dist/adapters/openclaw.d.ts.map +1 -0
- package/dist/adapters/openclaw.js +107 -0
- package/dist/adapters/openclaw.js.map +1 -0
- package/dist/adapters/opencode.d.ts +11 -0
- package/dist/adapters/opencode.d.ts.map +1 -0
- package/dist/adapters/opencode.js +86 -0
- package/dist/adapters/opencode.js.map +1 -0
- package/dist/adapters/pi-family.d.ts +14 -0
- package/dist/adapters/pi-family.d.ts.map +1 -0
- package/dist/adapters/pi-family.js +27 -0
- package/dist/adapters/pi-family.js.map +1 -0
- package/dist/adapters/pi.d.ts +8 -0
- package/dist/adapters/pi.d.ts.map +1 -0
- package/dist/adapters/pi.js +56 -0
- package/dist/adapters/pi.js.map +1 -0
- package/dist/adapters/shell-env.d.ts +12 -0
- package/dist/adapters/shell-env.d.ts.map +1 -0
- package/dist/adapters/shell-env.js +81 -0
- package/dist/adapters/shell-env.js.map +1 -0
- package/dist/adapters/zed.d.ts +10 -0
- package/dist/adapters/zed.d.ts.map +1 -0
- package/dist/adapters/zed.js +91 -0
- package/dist/adapters/zed.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +207 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/connect.d.ts +3 -0
- package/dist/commands/connect.d.ts.map +1 -0
- package/dist/commands/connect.js +179 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/context.d.ts +21 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +4 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/doctor.d.ts +11 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +85 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/env.d.ts +7 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +37 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +39 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/login.d.ts +7 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +130 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/models.d.ts +9 -0
- package/dist/commands/models.d.ts.map +1 -0
- package/dist/commands/models.js +51 -0
- package/dist/commands/models.js.map +1 -0
- package/dist/commands/remove.d.ts +3 -0
- package/dist/commands/remove.d.ts.map +1 -0
- package/dist/commands/remove.js +43 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/snippet.d.ts +7 -0
- package/dist/commands/snippet.d.ts.map +1 -0
- package/dist/commands/snippet.js +91 -0
- package/dist/commands/snippet.js.map +1 -0
- package/dist/core/detect.d.ts +12 -0
- package/dist/core/detect.d.ts.map +1 -0
- package/dist/core/detect.js +59 -0
- package/dist/core/detect.js.map +1 -0
- package/dist/core/discovery.d.ts +46 -0
- package/dist/core/discovery.d.ts.map +1 -0
- package/dist/core/discovery.js +124 -0
- package/dist/core/discovery.js.map +1 -0
- package/dist/core/gateway.d.ts +59 -0
- package/dist/core/gateway.d.ts.map +1 -0
- package/dist/core/gateway.js +385 -0
- package/dist/core/gateway.js.map +1 -0
- package/dist/core/http.d.ts +18 -0
- package/dist/core/http.d.ts.map +1 -0
- package/dist/core/http.js +73 -0
- package/dist/core/http.js.map +1 -0
- package/dist/core/management.d.ts +47 -0
- package/dist/core/management.d.ts.map +1 -0
- package/dist/core/management.js +88 -0
- package/dist/core/management.js.map +1 -0
- package/dist/core/store.d.ts +25 -0
- package/dist/core/store.d.ts.map +1 -0
- package/dist/core/store.js +48 -0
- package/dist/core/store.js.map +1 -0
- package/dist/fsutil/edit.d.ts +18 -0
- package/dist/fsutil/edit.d.ts.map +1 -0
- package/dist/fsutil/edit.js +102 -0
- package/dist/fsutil/edit.js.map +1 -0
- package/dist/fsutil/formats.d.ts +32 -0
- package/dist/fsutil/formats.d.ts.map +1 -0
- package/dist/fsutil/formats.js +154 -0
- package/dist/fsutil/formats.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +134 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/ui.d.ts +20 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +69 -0
- package/dist/ui.js.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"management.js","sourceRoot":"","sources":["../../src/core/management.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface Profile {
|
|
2
|
+
/** Base URL the OpenAI routes hang off, e.g. https://ai.paas.id/v1 */
|
|
3
|
+
apiBase: string;
|
|
4
|
+
apiKey: string;
|
|
5
|
+
defaultModel?: string;
|
|
6
|
+
/** Dashboard API root used to discover this profile, when it came from there. */
|
|
7
|
+
dashboardUrl?: string;
|
|
8
|
+
orgId?: string;
|
|
9
|
+
savedAt: string;
|
|
10
|
+
}
|
|
11
|
+
export interface StoreShape {
|
|
12
|
+
version: 1;
|
|
13
|
+
current?: string;
|
|
14
|
+
profiles: Record<string, Profile>;
|
|
15
|
+
}
|
|
16
|
+
export declare function configDir(): string;
|
|
17
|
+
export declare function configFile(): string;
|
|
18
|
+
export declare function loadStore(): Promise<StoreShape>;
|
|
19
|
+
export declare function saveStore(store: StoreShape): Promise<string>;
|
|
20
|
+
export declare function saveProfile(name: string, profile: Profile, makeCurrent?: boolean): Promise<string>;
|
|
21
|
+
export declare function getProfile(name?: string): Promise<{
|
|
22
|
+
name: string;
|
|
23
|
+
profile: Profile;
|
|
24
|
+
} | null>;
|
|
25
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/core/store.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,OAAO;IACtB,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,wBAAgB,SAAS,IAAI,MAAM,CAIlC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC,CAQrD;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CASlE;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,UAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAKrG;AAED,wBAAsB,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAAC,CAMlG"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
export function configDir() {
|
|
5
|
+
const xdg = process.env.XDG_CONFIG_HOME;
|
|
6
|
+
if (xdg && xdg.trim())
|
|
7
|
+
return path.join(xdg, 'idch-ai');
|
|
8
|
+
return path.join(os.homedir(), '.config', 'idch-ai');
|
|
9
|
+
}
|
|
10
|
+
export function configFile() {
|
|
11
|
+
return path.join(configDir(), 'config.json');
|
|
12
|
+
}
|
|
13
|
+
export async function loadStore() {
|
|
14
|
+
try {
|
|
15
|
+
const raw = await fs.readFile(configFile(), 'utf8');
|
|
16
|
+
const parsed = JSON.parse(raw);
|
|
17
|
+
return { version: 1, current: parsed.current, profiles: parsed.profiles ?? {} };
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return { version: 1, profiles: {} };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export async function saveStore(store) {
|
|
24
|
+
const file = configFile();
|
|
25
|
+
await fs.mkdir(path.dirname(file), { recursive: true, mode: 0o700 });
|
|
26
|
+
const tmp = `${file}.tmp-${process.pid}`;
|
|
27
|
+
// The file holds a live API key, so keep it owner-readable only.
|
|
28
|
+
await fs.writeFile(tmp, JSON.stringify(store, null, 2) + '\n', { encoding: 'utf8', mode: 0o600 });
|
|
29
|
+
await fs.rename(tmp, file);
|
|
30
|
+
await fs.chmod(file, 0o600).catch(() => { });
|
|
31
|
+
return file;
|
|
32
|
+
}
|
|
33
|
+
export async function saveProfile(name, profile, makeCurrent = true) {
|
|
34
|
+
const store = await loadStore();
|
|
35
|
+
store.profiles[name] = profile;
|
|
36
|
+
if (makeCurrent)
|
|
37
|
+
store.current = name;
|
|
38
|
+
return saveStore(store);
|
|
39
|
+
}
|
|
40
|
+
export async function getProfile(name) {
|
|
41
|
+
const store = await loadStore();
|
|
42
|
+
const key = name ?? store.current;
|
|
43
|
+
if (!key)
|
|
44
|
+
return null;
|
|
45
|
+
const profile = store.profiles[key];
|
|
46
|
+
return profile ? { name: key, profile } : null;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/core/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAmB7B,MAAM,UAAU,SAAS;IACvB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACxC,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACxD,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,aAAa,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,MAAM,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAwB,CAAC;QACtD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;IAClF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACtC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAiB;IAC/C,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;IAC1B,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACrE,MAAM,GAAG,GAAG,GAAG,IAAI,QAAQ,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,iEAAiE;IACjE,MAAM,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAClG,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC3B,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC5C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,OAAgB,EAAE,WAAW,GAAG,IAAI;IAClF,MAAM,KAAK,GAAG,MAAM,SAAS,EAAE,CAAC;IAChC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;IAC/B,IAAI,WAAW;QAAE,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;IACtC,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAa;IAC5C,MAAM,KAAK,GAAG,MAAM,SAAS,EAAE,CAAC;IAChC,MAAM,GAAG,GAAG,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC;IAClC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACpC,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FileChange } from '../types.js';
|
|
2
|
+
/** Expand a leading `~` against the user's home directory. */
|
|
3
|
+
export declare function expandHome(p: string): string;
|
|
4
|
+
/** Render an absolute path back with `~` so output stays readable. */
|
|
5
|
+
export declare function shortenHome(p: string): string;
|
|
6
|
+
export declare function readIfExists(file: string): Promise<string | null>;
|
|
7
|
+
export declare function pathExists(file: string): Promise<boolean>;
|
|
8
|
+
/**
|
|
9
|
+
* Write `after` to `file`, backing up any existing content first.
|
|
10
|
+
* The write is atomic (temp file in the same directory, then rename) so a crash
|
|
11
|
+
* mid-write can never leave the user with a half-written agent config.
|
|
12
|
+
*/
|
|
13
|
+
export declare function writeFileSafely(file: string, after: string, opts: {
|
|
14
|
+
dryRun: boolean;
|
|
15
|
+
}): Promise<FileChange>;
|
|
16
|
+
/** Minimal line-level unified diff. Enough to show what `--dry-run` would do. */
|
|
17
|
+
export declare function unifiedDiff(before: string | null, after: string, file: string): string;
|
|
18
|
+
//# sourceMappingURL=edit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/fsutil/edit.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,8DAA8D;AAC9D,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAI5C;AAED,sEAAsE;AACtE,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOvE;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D;AAOD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GACxB,OAAO,CAAC,UAAU,CAAC,CAoBrB;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAgCtF"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
/** Expand a leading `~` against the user's home directory. */
|
|
5
|
+
export function expandHome(p) {
|
|
6
|
+
if (p === '~')
|
|
7
|
+
return os.homedir();
|
|
8
|
+
if (p.startsWith('~/') || p.startsWith('~\\'))
|
|
9
|
+
return path.join(os.homedir(), p.slice(2));
|
|
10
|
+
return p;
|
|
11
|
+
}
|
|
12
|
+
/** Render an absolute path back with `~` so output stays readable. */
|
|
13
|
+
export function shortenHome(p) {
|
|
14
|
+
const home = os.homedir();
|
|
15
|
+
return p.startsWith(home + path.sep) ? '~' + p.slice(home.length) : p;
|
|
16
|
+
}
|
|
17
|
+
export async function readIfExists(file) {
|
|
18
|
+
try {
|
|
19
|
+
return await fs.readFile(file, 'utf8');
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
if (err.code === 'ENOENT')
|
|
23
|
+
return null;
|
|
24
|
+
throw err;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export async function pathExists(file) {
|
|
28
|
+
try {
|
|
29
|
+
await fs.access(file);
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function backupName(file) {
|
|
37
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
38
|
+
return `${file}.idch-bak-${stamp}`;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Write `after` to `file`, backing up any existing content first.
|
|
42
|
+
* The write is atomic (temp file in the same directory, then rename) so a crash
|
|
43
|
+
* mid-write can never leave the user with a half-written agent config.
|
|
44
|
+
*/
|
|
45
|
+
export async function writeFileSafely(file, after, opts) {
|
|
46
|
+
const before = await readIfExists(file);
|
|
47
|
+
if (before === after)
|
|
48
|
+
return { path: file, before, after, unchanged: true };
|
|
49
|
+
if (opts.dryRun)
|
|
50
|
+
return { path: file, before, after, unchanged: false };
|
|
51
|
+
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
52
|
+
let backupPath;
|
|
53
|
+
if (before !== null) {
|
|
54
|
+
backupPath = backupName(file);
|
|
55
|
+
await fs.writeFile(backupPath, before, 'utf8');
|
|
56
|
+
}
|
|
57
|
+
const tmp = `${file}.idch-tmp-${process.pid}`;
|
|
58
|
+
await fs.writeFile(tmp, after, 'utf8');
|
|
59
|
+
await fs.rename(tmp, file);
|
|
60
|
+
const change = { path: file, before, after, unchanged: false };
|
|
61
|
+
if (backupPath)
|
|
62
|
+
change.backupPath = backupPath;
|
|
63
|
+
return change;
|
|
64
|
+
}
|
|
65
|
+
/** Minimal line-level unified diff. Enough to show what `--dry-run` would do. */
|
|
66
|
+
export function unifiedDiff(before, after, file) {
|
|
67
|
+
const a = (before ?? '').split('\n');
|
|
68
|
+
const b = after.split('\n');
|
|
69
|
+
const out = [`--- ${before === null ? '/dev/null' : file}`, `+++ ${file}`];
|
|
70
|
+
// Longest common subsequence over lines. Configs are small; O(n*m) is fine.
|
|
71
|
+
const n = a.length;
|
|
72
|
+
const m = b.length;
|
|
73
|
+
const lcs = Array.from({ length: n + 1 }, () => new Array(m + 1).fill(0));
|
|
74
|
+
for (let i = n - 1; i >= 0; i--) {
|
|
75
|
+
for (let j = m - 1; j >= 0; j--) {
|
|
76
|
+
lcs[i][j] = a[i] === b[j] ? lcs[i + 1][j + 1] + 1 : Math.max(lcs[i + 1][j], lcs[i][j + 1]);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
let i = 0;
|
|
80
|
+
let j = 0;
|
|
81
|
+
while (i < n && j < m) {
|
|
82
|
+
if (a[i] === b[j]) {
|
|
83
|
+
out.push(` ${a[i]}`);
|
|
84
|
+
i++;
|
|
85
|
+
j++;
|
|
86
|
+
}
|
|
87
|
+
else if (lcs[i + 1][j] >= lcs[i][j + 1]) {
|
|
88
|
+
out.push(`- ${a[i]}`);
|
|
89
|
+
i++;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
out.push(`+ ${b[j]}`);
|
|
93
|
+
j++;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
while (i < n)
|
|
97
|
+
out.push(`- ${a[i++]}`);
|
|
98
|
+
while (j < m)
|
|
99
|
+
out.push(`+ ${b[j++]}`);
|
|
100
|
+
return out.join('\n');
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/fsutil/edit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as jsonc from 'jsonc-parser';
|
|
2
|
+
import YAML from 'yaml';
|
|
3
|
+
export type Json = Record<string, unknown>;
|
|
4
|
+
export declare function parseJson(text: string | null): Json;
|
|
5
|
+
export declare function stringifyJson(value: Json, previous: string | null): string;
|
|
6
|
+
/**
|
|
7
|
+
* Edit a JSON/JSONC file in place at `pathInDoc`, preserving comments and
|
|
8
|
+
* formatting everywhere we did not touch. Pass `undefined` as value to delete.
|
|
9
|
+
* Used for files a human curates by hand, like Zed's settings.json.
|
|
10
|
+
*/
|
|
11
|
+
export declare function editJsonc(text: string | null, pathInDoc: jsonc.JSONPath, value: unknown): string;
|
|
12
|
+
export declare function parseYaml(text: string | null): Json;
|
|
13
|
+
/**
|
|
14
|
+
* Edit a YAML document while preserving the comments and ordering of everything
|
|
15
|
+
* we did not touch. Agent configs are hand-edited files; clobbering a user's
|
|
16
|
+
* comments to add a provider block would be rude.
|
|
17
|
+
*/
|
|
18
|
+
export declare function editYaml(text: string | null, mutate: (doc: YAML.Document.Parsed) => void): string;
|
|
19
|
+
/**
|
|
20
|
+
* Same as `editYaml`, but drops any mapping we just emptied and returns an empty
|
|
21
|
+
* file when nothing is left. Used on the removal path so undoing a connect does
|
|
22
|
+
* not leave `model: {}` or a lone `{}` behind.
|
|
23
|
+
*/
|
|
24
|
+
export declare function editYamlPruned(text: string | null, mutate: (doc: YAML.Document.Parsed) => void): string;
|
|
25
|
+
export declare function stringifyYaml(value: Json): string;
|
|
26
|
+
export declare function parseToml(text: string | null): Json;
|
|
27
|
+
export declare function stringifyToml(value: Json): string;
|
|
28
|
+
/** Upsert `KEY=value` lines, leaving every other line (and comments) untouched. */
|
|
29
|
+
export declare function upsertEnvFile(text: string | null, vars: Record<string, string>): string;
|
|
30
|
+
/** Remove entries from an env file by key. */
|
|
31
|
+
export declare function removeEnvKeys(text: string | null, keys: string[]): string;
|
|
32
|
+
//# sourceMappingURL=formats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formats.d.ts","sourceRoot":"","sources":["../../src/fsutil/formats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAW3C,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CASnD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAG1E;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAOhG;AAID,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAQnD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,IAAI,GAAG,MAAM,CAiBjG;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,IAAI,GAAG,MAAM,CAOvG;AAaD,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,CAEjD;AAID,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAGnD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,CAGjD;AAID,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAoBvF;AAMD,8CAA8C;AAC9C,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAWzE"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import * as jsonc from 'jsonc-parser';
|
|
2
|
+
import YAML from 'yaml';
|
|
3
|
+
import * as TOML from 'smol-toml';
|
|
4
|
+
/** Detect the indentation an existing file already uses, so we do not reformat it. */
|
|
5
|
+
function detectIndent(text, fallback = 2) {
|
|
6
|
+
const m = text.match(/^([ \t]+)\S/m);
|
|
7
|
+
if (!m)
|
|
8
|
+
return fallback;
|
|
9
|
+
return m[1].startsWith('\t') ? '\t' : m[1].length;
|
|
10
|
+
}
|
|
11
|
+
/* ------------------------------------------------------------------ JSON */
|
|
12
|
+
export function parseJson(text) {
|
|
13
|
+
if (!text || !text.trim())
|
|
14
|
+
return {};
|
|
15
|
+
const errors = [];
|
|
16
|
+
// Tolerant on purpose: several agents ship JSON files that carry comments.
|
|
17
|
+
const value = jsonc.parse(text, errors, { allowTrailingComma: true, disallowComments: false });
|
|
18
|
+
if (errors.length && (value === undefined || value === null)) {
|
|
19
|
+
throw new Error(`could not parse JSON (${jsonc.printParseErrorCode(errors[0].error)} at offset ${errors[0].offset})`);
|
|
20
|
+
}
|
|
21
|
+
return (value ?? {});
|
|
22
|
+
}
|
|
23
|
+
export function stringifyJson(value, previous) {
|
|
24
|
+
const indent = previous ? detectIndent(previous) : 2;
|
|
25
|
+
return JSON.stringify(value, null, indent) + '\n';
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Edit a JSON/JSONC file in place at `pathInDoc`, preserving comments and
|
|
29
|
+
* formatting everywhere we did not touch. Pass `undefined` as value to delete.
|
|
30
|
+
* Used for files a human curates by hand, like Zed's settings.json.
|
|
31
|
+
*/
|
|
32
|
+
export function editJsonc(text, pathInDoc, value) {
|
|
33
|
+
const source = text && text.trim() ? text : '{}\n';
|
|
34
|
+
const edits = jsonc.modify(source, pathInDoc, value, {
|
|
35
|
+
formattingOptions: { insertSpaces: true, tabSize: typeof detectIndent(source) === 'number' ? detectIndent(source) : 2 },
|
|
36
|
+
});
|
|
37
|
+
const applied = jsonc.applyEdits(source, edits);
|
|
38
|
+
return applied.endsWith('\n') ? applied : applied + '\n';
|
|
39
|
+
}
|
|
40
|
+
/* ------------------------------------------------------------------ YAML */
|
|
41
|
+
export function parseYaml(text) {
|
|
42
|
+
if (!text || !text.trim())
|
|
43
|
+
return {};
|
|
44
|
+
const value = YAML.parse(text);
|
|
45
|
+
if (value === null || value === undefined)
|
|
46
|
+
return {};
|
|
47
|
+
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
48
|
+
throw new Error('expected a YAML mapping at the document root');
|
|
49
|
+
}
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Edit a YAML document while preserving the comments and ordering of everything
|
|
54
|
+
* we did not touch. Agent configs are hand-edited files; clobbering a user's
|
|
55
|
+
* comments to add a provider block would be rude.
|
|
56
|
+
*/
|
|
57
|
+
export function editYaml(text, mutate) {
|
|
58
|
+
const doc = (text && text.trim() ? YAML.parseDocument(text) : YAML.parseDocument('\n'));
|
|
59
|
+
if (doc.contents === null || (YAML.isScalar(doc.contents) && doc.contents.value === null)) {
|
|
60
|
+
// createNode keeps the document's schema attached, which setIn() needs to
|
|
61
|
+
// auto-create intermediate maps for a deep path.
|
|
62
|
+
doc.contents = doc.createNode({});
|
|
63
|
+
}
|
|
64
|
+
mutate(doc);
|
|
65
|
+
// setIn() creates collections in flow style ({a: 1}); force block style so the
|
|
66
|
+
// file still looks like the hand-written YAML the user expects.
|
|
67
|
+
YAML.visit(doc, {
|
|
68
|
+
Map: (_key, node) => {
|
|
69
|
+
node.flow = false;
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
const out = doc.toString({ lineWidth: 0 });
|
|
73
|
+
return out.endsWith('\n') ? out : out + '\n';
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Same as `editYaml`, but drops any mapping we just emptied and returns an empty
|
|
77
|
+
* file when nothing is left. Used on the removal path so undoing a connect does
|
|
78
|
+
* not leave `model: {}` or a lone `{}` behind.
|
|
79
|
+
*/
|
|
80
|
+
export function editYamlPruned(text, mutate) {
|
|
81
|
+
const out = editYaml(text, (doc) => {
|
|
82
|
+
mutate(doc);
|
|
83
|
+
pruneEmptyMaps(doc.contents);
|
|
84
|
+
});
|
|
85
|
+
const parsed = parseYaml(out);
|
|
86
|
+
return Object.keys(parsed).length === 0 ? '' : out;
|
|
87
|
+
}
|
|
88
|
+
/** Depth-first so a map emptied by pruning its last child is pruned in turn. */
|
|
89
|
+
function pruneEmptyMaps(node) {
|
|
90
|
+
if (!YAML.isMap(node))
|
|
91
|
+
return;
|
|
92
|
+
for (const item of [...node.items]) {
|
|
93
|
+
pruneEmptyMaps(item.value);
|
|
94
|
+
if (YAML.isMap(item.value) && item.value.items.length === 0) {
|
|
95
|
+
node.items.splice(node.items.indexOf(item), 1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export function stringifyYaml(value) {
|
|
100
|
+
return YAML.stringify(value, { lineWidth: 0 });
|
|
101
|
+
}
|
|
102
|
+
/* ------------------------------------------------------------------ TOML */
|
|
103
|
+
export function parseToml(text) {
|
|
104
|
+
if (!text || !text.trim())
|
|
105
|
+
return {};
|
|
106
|
+
return TOML.parse(text);
|
|
107
|
+
}
|
|
108
|
+
export function stringifyToml(value) {
|
|
109
|
+
const out = TOML.stringify(value);
|
|
110
|
+
return out.endsWith('\n') ? out : out + '\n';
|
|
111
|
+
}
|
|
112
|
+
/* ------------------------------------------------------------- dotenv-ish */
|
|
113
|
+
/** Upsert `KEY=value` lines, leaving every other line (and comments) untouched. */
|
|
114
|
+
export function upsertEnvFile(text, vars) {
|
|
115
|
+
const lines = (text ?? '').split('\n');
|
|
116
|
+
const remaining = new Map(Object.entries(vars));
|
|
117
|
+
const next = lines.map((line) => {
|
|
118
|
+
const m = line.match(/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/);
|
|
119
|
+
if (!m)
|
|
120
|
+
return line;
|
|
121
|
+
const key = m[1];
|
|
122
|
+
if (!remaining.has(key))
|
|
123
|
+
return line;
|
|
124
|
+
const value = remaining.get(key);
|
|
125
|
+
remaining.delete(key);
|
|
126
|
+
return `${key}=${quoteEnv(value)}`;
|
|
127
|
+
});
|
|
128
|
+
if (remaining.size) {
|
|
129
|
+
if (next.length && next[next.length - 1].trim() !== '')
|
|
130
|
+
next.push('');
|
|
131
|
+
for (const [key, value] of remaining)
|
|
132
|
+
next.push(`${key}=${quoteEnv(value)}`);
|
|
133
|
+
}
|
|
134
|
+
const out = next.join('\n');
|
|
135
|
+
return out.endsWith('\n') ? out : out + '\n';
|
|
136
|
+
}
|
|
137
|
+
function quoteEnv(value) {
|
|
138
|
+
return /^[A-Za-z0-9_./:@=+-]*$/.test(value) ? value : JSON.stringify(value);
|
|
139
|
+
}
|
|
140
|
+
/** Remove entries from an env file by key. */
|
|
141
|
+
export function removeEnvKeys(text, keys) {
|
|
142
|
+
if (!text)
|
|
143
|
+
return '';
|
|
144
|
+
const drop = new Set(keys);
|
|
145
|
+
const out = text
|
|
146
|
+
.split('\n')
|
|
147
|
+
.filter((line) => {
|
|
148
|
+
const m = line.match(/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/);
|
|
149
|
+
return !(m && drop.has(m[1]));
|
|
150
|
+
})
|
|
151
|
+
.join('\n');
|
|
152
|
+
return out.endsWith('\n') ? out : out + '\n';
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=formats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formats.js","sourceRoot":"","sources":["../../src/fsutil/formats.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Programmatic API.
|
|
3
|
+
*
|
|
4
|
+
* Everything the CLI does is available here, so a customer can wire the gateway
|
|
5
|
+
* into their own installer, devcontainer bootstrap, or internal tool.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { resolveSource, buildTarget, getAdapter } from '@idcloudhost/ai-connect';
|
|
9
|
+
*
|
|
10
|
+
* const source = await resolveSource({ baseUrl: process.env.IDCH_AI_BASE_URL, apiKey: key });
|
|
11
|
+
* const target = await buildTarget(source, {});
|
|
12
|
+
* await getAdapter('opencode')!.apply({ target, dryRun: false, secretMode: 'inline', scope: 'user', cwd: process.cwd() });
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export type { Adapter, ApplyOptions, ApplyResult, CapabilityCheck, CapabilityReport, ConnectionTarget, DetectResult, FileChange, GatewayModel, SecretMode, } from './types.js';
|
|
16
|
+
export { adapters, adapterIds, getAdapter } from './adapters/index.js';
|
|
17
|
+
export { buildTarget, resolveSource, pickDefaultModel, type ResolveInput, type ResolvedSource } from './core/discovery.js';
|
|
18
|
+
export { chatModels, listModels, probeCapabilities, resolveApiBase, splitBase, testChat, normalizeUrl } from './core/gateway.js';
|
|
19
|
+
export { ManagementClient, DEFAULT_DASHBOARD_URL, explainManagementError, type AiStatus, type KeyRow } from './core/management.js';
|
|
20
|
+
export { getProfile, loadStore, saveProfile, saveStore, configFile, configDir, type Profile, type StoreShape } from './core/store.js';
|
|
21
|
+
export { HttpError } from './core/http.js';
|
|
22
|
+
export { expandHome, shortenHome, unifiedDiff, writeFileSafely, readIfExists } from './fsutil/edit.js';
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,YAAY,EACV,OAAO,EACP,YAAY,EACZ,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC3H,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjI,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnI,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACtI,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { adapters, adapterIds, getAdapter } from './adapters/index.js';
|
|
2
|
+
export { buildTarget, resolveSource, pickDefaultModel } from './core/discovery.js';
|
|
3
|
+
export { chatModels, listModels, probeCapabilities, resolveApiBase, splitBase, testChat, normalizeUrl } from './core/gateway.js';
|
|
4
|
+
export { ManagementClient, DEFAULT_DASHBOARD_URL, explainManagementError } from './core/management.js';
|
|
5
|
+
export { getProfile, loadStore, saveProfile, saveStore, configFile, configDir } from './core/store.js';
|
|
6
|
+
export { HttpError } from './core/http.js';
|
|
7
|
+
export { expandHome, shortenHome, unifiedDiff, writeFileSafely, readIfExists } from './fsutil/edit.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAA0C,MAAM,qBAAqB,CAAC;AAC3H,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjI,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,sBAAsB,EAA8B,MAAM,sBAAsB,CAAC;AACnI,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAiC,MAAM,iBAAiB,CAAC;AACtI,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/** Public types shared by the CLI and the programmatic API. */
|
|
2
|
+
/** A model as exposed by the gateway, enriched with catalog metadata when available. */
|
|
3
|
+
export interface GatewayModel {
|
|
4
|
+
/** Model id exactly as the gateway expects it in `model`. Never rewritten. */
|
|
5
|
+
id: string;
|
|
6
|
+
/** Human label. Falls back to `id`. */
|
|
7
|
+
label: string;
|
|
8
|
+
/** Upstream provider name (openai, anthropic, deepseek…), when the gateway reports it. */
|
|
9
|
+
provider?: string;
|
|
10
|
+
/** Total context window in tokens. */
|
|
11
|
+
contextWindow?: number;
|
|
12
|
+
/** Max output tokens. */
|
|
13
|
+
maxOutputTokens?: number;
|
|
14
|
+
/** USD per 1M input/output tokens. */
|
|
15
|
+
inputUsdPer1M?: number;
|
|
16
|
+
outputUsdPer1M?: number;
|
|
17
|
+
/** LiteLLM `mode`: chat, embedding, image_generation, rerank… */
|
|
18
|
+
mode?: string;
|
|
19
|
+
/** True when the catalog says the model accepts image input. */
|
|
20
|
+
supportsVision?: boolean;
|
|
21
|
+
/** True when the catalog says the model supports function/tool calling. */
|
|
22
|
+
supportsTools?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/** Everything an adapter needs to write a working config. */
|
|
25
|
+
export interface ConnectionTarget {
|
|
26
|
+
/** Base URL an OpenAI SDK gets as `baseURL` — the one `/chat/completions` hangs off. */
|
|
27
|
+
apiBase: string;
|
|
28
|
+
/** Scheme + host + port of `apiBase`, no path. Some agents want this instead. */
|
|
29
|
+
origin: string;
|
|
30
|
+
/** Path segment between origin and the OpenAI routes, e.g. "/v1" or "". */
|
|
31
|
+
basePath: string;
|
|
32
|
+
/** The virtual key. Sent as `Authorization: Bearer <apiKey>`. */
|
|
33
|
+
apiKey: string;
|
|
34
|
+
/** Provider id written into agent configs. Namespaces everything we own. */
|
|
35
|
+
providerId: string;
|
|
36
|
+
/** Display name written into agent configs. */
|
|
37
|
+
providerLabel: string;
|
|
38
|
+
/** Models to register. Empty means "register everything the gateway lists". */
|
|
39
|
+
models: GatewayModel[];
|
|
40
|
+
/** Model an agent should select by default. */
|
|
41
|
+
defaultModel?: string;
|
|
42
|
+
}
|
|
43
|
+
/** How an adapter stores credentials. */
|
|
44
|
+
export type SecretMode =
|
|
45
|
+
/** Write the key straight into the config file. */
|
|
46
|
+
'inline'
|
|
47
|
+
/** Write `$ENV_VAR` / `{env:ENV_VAR}` and tell the user to export it. */
|
|
48
|
+
| 'env';
|
|
49
|
+
export interface ApplyOptions {
|
|
50
|
+
target: ConnectionTarget;
|
|
51
|
+
/** Compute the change but do not touch the filesystem. */
|
|
52
|
+
dryRun: boolean;
|
|
53
|
+
/** inline (default) or env-var indirection. */
|
|
54
|
+
secretMode: SecretMode;
|
|
55
|
+
/** Override the config file path the adapter would pick. */
|
|
56
|
+
configPathOverride?: string;
|
|
57
|
+
/** Write into the current project instead of the user's home, when supported. */
|
|
58
|
+
scope: 'user' | 'project';
|
|
59
|
+
/** Project root used when scope === 'project'. */
|
|
60
|
+
cwd: string;
|
|
61
|
+
}
|
|
62
|
+
/** One file an adapter created or changed. */
|
|
63
|
+
export interface FileChange {
|
|
64
|
+
path: string;
|
|
65
|
+
/** File contents before, or null when the file did not exist. */
|
|
66
|
+
before: string | null;
|
|
67
|
+
after: string;
|
|
68
|
+
/** Path of the backup we wrote, when we overwrote an existing file. */
|
|
69
|
+
backupPath?: string;
|
|
70
|
+
/** True when before === after and nothing was written. */
|
|
71
|
+
unchanged: boolean;
|
|
72
|
+
}
|
|
73
|
+
export interface ApplyResult {
|
|
74
|
+
adapterId: string;
|
|
75
|
+
changes: FileChange[];
|
|
76
|
+
/** Env vars the user must export for this config to work. */
|
|
77
|
+
envVars: Record<string, string>;
|
|
78
|
+
/** Extra human steps, e.g. "restart opencode", "select the model with /models". */
|
|
79
|
+
notes: string[];
|
|
80
|
+
/** Command the user can run to try it immediately. */
|
|
81
|
+
tryCommand?: string;
|
|
82
|
+
}
|
|
83
|
+
export interface DetectResult {
|
|
84
|
+
/** The binary or config was found on this machine. */
|
|
85
|
+
installed: boolean;
|
|
86
|
+
/** How we knew: "binary: opencode", "config: ~/.pi/agent/models.json". */
|
|
87
|
+
evidence?: string;
|
|
88
|
+
/** Version string when cheaply obtainable. */
|
|
89
|
+
version?: string;
|
|
90
|
+
}
|
|
91
|
+
export interface Adapter {
|
|
92
|
+
/** Stable slug used on the CLI: `idch-ai connect --agent opencode`. */
|
|
93
|
+
id: string;
|
|
94
|
+
/** Display name. */
|
|
95
|
+
name: string;
|
|
96
|
+
/** One line describing what this agent is. */
|
|
97
|
+
summary: string;
|
|
98
|
+
/** Link to the vendor doc page for custom providers. */
|
|
99
|
+
docsUrl: string;
|
|
100
|
+
/** Executable names we look for on PATH. */
|
|
101
|
+
bins: string[];
|
|
102
|
+
/**
|
|
103
|
+
* 'auto' — we can write the config file ourselves.
|
|
104
|
+
* 'manual' — the agent stores settings somewhere we must not write
|
|
105
|
+
* (VS Code global state, a GUI keychain); we print instructions.
|
|
106
|
+
*/
|
|
107
|
+
mode: 'auto' | 'manual';
|
|
108
|
+
/** True when the adapter honours ApplyOptions.scope === 'project'. */
|
|
109
|
+
supportsProjectScope?: boolean;
|
|
110
|
+
/** Secret modes this adapter can express, most-preferred first. */
|
|
111
|
+
secretModes: SecretMode[];
|
|
112
|
+
detect(opts: {
|
|
113
|
+
cwd: string;
|
|
114
|
+
}): Promise<DetectResult>;
|
|
115
|
+
/** Absolute path of the file this adapter would write. */
|
|
116
|
+
configPath(opts: Pick<ApplyOptions, 'scope' | 'cwd' | 'configPathOverride'>): string;
|
|
117
|
+
apply(opts: ApplyOptions): Promise<ApplyResult>;
|
|
118
|
+
/** Strip our provider block back out. */
|
|
119
|
+
remove(opts: Omit<ApplyOptions, 'target' | 'secretMode'> & {
|
|
120
|
+
providerId: string;
|
|
121
|
+
}): Promise<ApplyResult>;
|
|
122
|
+
}
|
|
123
|
+
/** Result of probing what the live gateway actually supports. */
|
|
124
|
+
export interface CapabilityReport {
|
|
125
|
+
model: string;
|
|
126
|
+
checks: CapabilityCheck[];
|
|
127
|
+
}
|
|
128
|
+
export interface CapabilityCheck {
|
|
129
|
+
id: 'models' | 'auth' | 'chat' | 'streaming' | 'tools' | 'response_format_json' | 'response_format_schema' | 'vision' | 'embeddings' | 'responses_api' | 'anthropic_messages' | 'rate_limit_headers';
|
|
130
|
+
label: string;
|
|
131
|
+
status: 'pass' | 'fail' | 'skip';
|
|
132
|
+
detail?: string;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,+DAA+D"}
|