@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,12 @@
|
|
|
1
|
+
import type { Adapter } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The catch-all: a sourceable script exporting the standard OpenAI env vars.
|
|
4
|
+
*
|
|
5
|
+
* Anything that reads OPENAI_API_KEY / OPENAI_BASE_URL works after sourcing it —
|
|
6
|
+
* the OpenAI SDKs, LangChain, LlamaIndex, the Vercel AI SDK, Qwen Code, Cline in
|
|
7
|
+
* a terminal, one-off curl. We write a dedicated file rather than editing the
|
|
8
|
+
* user's ~/.zshrc, because appending exports to someone's shell rc is not ours
|
|
9
|
+
* to do and is painful to undo cleanly.
|
|
10
|
+
*/
|
|
11
|
+
export declare const shellEnvAdapter: Adapter;
|
|
12
|
+
//# sourceMappingURL=shell-env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-env.d.ts","sourceRoot":"","sources":["../../src/adapters/shell-env.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAA6B,MAAM,aAAa,CAAC;AAStE;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,EAAE,OAoE7B,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { readIfExists, shortenHome, writeFileSafely } from '../fsutil/edit.js';
|
|
3
|
+
import { configDir } from '../core/store.js';
|
|
4
|
+
import { result } from './helpers.js';
|
|
5
|
+
function envScript() {
|
|
6
|
+
return path.join(configDir(), 'env.sh');
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The catch-all: a sourceable script exporting the standard OpenAI env vars.
|
|
10
|
+
*
|
|
11
|
+
* Anything that reads OPENAI_API_KEY / OPENAI_BASE_URL works after sourcing it —
|
|
12
|
+
* the OpenAI SDKs, LangChain, LlamaIndex, the Vercel AI SDK, Qwen Code, Cline in
|
|
13
|
+
* a terminal, one-off curl. We write a dedicated file rather than editing the
|
|
14
|
+
* user's ~/.zshrc, because appending exports to someone's shell rc is not ours
|
|
15
|
+
* to do and is painful to undo cleanly.
|
|
16
|
+
*/
|
|
17
|
+
export const shellEnvAdapter = {
|
|
18
|
+
id: 'env',
|
|
19
|
+
name: 'Shell environment',
|
|
20
|
+
summary: 'A sourceable env.sh with the standard OpenAI variables. Works with any OpenAI-compatible client.',
|
|
21
|
+
docsUrl: 'https://platform.openai.com/docs/api-reference',
|
|
22
|
+
bins: [],
|
|
23
|
+
mode: 'auto',
|
|
24
|
+
supportsProjectScope: true,
|
|
25
|
+
secretModes: ['inline'],
|
|
26
|
+
async detect() {
|
|
27
|
+
return { installed: true, evidence: 'always available' };
|
|
28
|
+
},
|
|
29
|
+
configPath({ scope, cwd, configPathOverride }) {
|
|
30
|
+
if (configPathOverride)
|
|
31
|
+
return configPathOverride;
|
|
32
|
+
return scope === 'project' ? path.join(cwd, '.env') : envScript();
|
|
33
|
+
},
|
|
34
|
+
async apply(opts) {
|
|
35
|
+
const file = this.configPath(opts);
|
|
36
|
+
const { target } = opts;
|
|
37
|
+
const isProject = opts.scope === 'project';
|
|
38
|
+
const vars = [
|
|
39
|
+
['OPENAI_API_KEY', target.apiKey],
|
|
40
|
+
['OPENAI_BASE_URL', target.apiBase],
|
|
41
|
+
// The older SDKs and aider read this name instead.
|
|
42
|
+
['OPENAI_API_BASE', target.apiBase],
|
|
43
|
+
['IDCH_AI_API_KEY', target.apiKey],
|
|
44
|
+
['IDCH_AI_BASE_URL', target.apiBase],
|
|
45
|
+
];
|
|
46
|
+
if (target.defaultModel) {
|
|
47
|
+
vars.push(['OPENAI_MODEL', target.defaultModel], ['IDCH_AI_MODEL', target.defaultModel]);
|
|
48
|
+
}
|
|
49
|
+
const header = [
|
|
50
|
+
'# Written by @idcloudhost/ai-connect. Safe to regenerate.',
|
|
51
|
+
isProject ? '# Add this file to .gitignore — it contains a live API key.' : `# source ${shortenHome(file)}`,
|
|
52
|
+
'',
|
|
53
|
+
];
|
|
54
|
+
const body = vars.map(([k, v]) => (isProject ? `${k}=${v}` : `export ${k}=${JSON.stringify(v)}`));
|
|
55
|
+
const after = [...header, ...body, ''].join('\n');
|
|
56
|
+
const change = await writeFileSafely(file, after, { dryRun: opts.dryRun });
|
|
57
|
+
return result(this.id, [change], {
|
|
58
|
+
notes: isProject
|
|
59
|
+
? [`Wrote ${shortenHome(file)}. Add it to .gitignore — it holds a live key.`]
|
|
60
|
+
: [
|
|
61
|
+
`Load it with: source ${shortenHome(file)}`,
|
|
62
|
+
'Add that line to your shell rc yourself if you want it permanent.',
|
|
63
|
+
],
|
|
64
|
+
tryCommand: isProject ? undefined : `source ${shortenHome(file)} && idch-ai doctor`,
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
async remove(opts) {
|
|
68
|
+
const file = this.configPath(opts);
|
|
69
|
+
const before = await readIfExists(file);
|
|
70
|
+
if (before === null)
|
|
71
|
+
return result(this.id, []);
|
|
72
|
+
if (!before.includes('@idcloudhost/ai-connect')) {
|
|
73
|
+
return result(this.id, [], {
|
|
74
|
+
notes: [`Left ${shortenHome(file)} alone — it was not written by this tool.`],
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const change = await writeFileSafely(file, '', { dryRun: opts.dryRun });
|
|
78
|
+
return result(this.id, [change], { notes: [`Emptied ${shortenHome(file)}.`] });
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=shell-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-env.js","sourceRoot":"","sources":["../../src/adapters/shell-env.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,SAAS,SAAS;IAChB,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,eAAe,GAAY;IACtC,EAAE,EAAE,KAAK;IACT,IAAI,EAAE,mBAAmB;IACzB,OAAO,EAAE,kGAAkG;IAC3G,OAAO,EAAE,gDAAgD;IACzD,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,MAAM;IACZ,oBAAoB,EAAE,IAAI;IAC1B,WAAW,EAAE,CAAC,QAAQ,CAAC;IAEvB,KAAK,CAAC,MAAM;QACV,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC3D,CAAC;IAED,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,kBAAkB,EAAE;QAC3C,IAAI,kBAAkB;YAAE,OAAO,kBAAkB,CAAC;QAClD,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAkB;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC;QAE3C,MAAM,IAAI,GAA4B;YACpC,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC;YACjC,CAAC,iBAAiB,EAAE,MAAM,CAAC,OAAO,CAAC;YACnC,mDAAmD;YACnD,CAAC,iBAAiB,EAAE,MAAM,CAAC,OAAO,CAAC;YACnC,CAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC;YAClC,CAAC,kBAAkB,EAAE,MAAM,CAAC,OAAO,CAAC;SACrC,CAAC;QACF,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,eAAe,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;QAC3F,CAAC;QAED,MAAM,MAAM,GAAG;YACb,2DAA2D;YAC3D,SAAS,CAAC,CAAC,CAAC,6DAA6D,CAAC,CAAC,CAAC,YAAY,WAAW,CAAC,IAAI,CAAC,EAAE;YAC3G,EAAE;SACH,CAAC;QACF,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAClG,MAAM,KAAK,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAElD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3E,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE;YAC/B,KAAK,EAAE,SAAS;gBACd,CAAC,CAAC,CAAC,SAAS,WAAW,CAAC,IAAI,CAAC,+CAA+C,CAAC;gBAC7E,CAAC,CAAC;oBACE,wBAAwB,WAAW,CAAC,IAAI,CAAC,EAAE;oBAC3C,mEAAmE;iBACpE;YACL,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,WAAW,CAAC,IAAI,CAAC,oBAAoB;SACpF,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAI;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,CAAC;YAChD,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE;gBACzB,KAAK,EAAE,CAAC,QAAQ,WAAW,CAAC,IAAI,CAAC,2CAA2C,CAAC;aAC9E,CAAC,CAAC;QACL,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACxE,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,WAAW,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Adapter } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Zed's settings.json is a hand-curated JSONC file full of comments, so this
|
|
4
|
+
* adapter edits it surgically instead of reserialising the document.
|
|
5
|
+
*
|
|
6
|
+
* Zed explicitly tells you not to put API keys in settings.json — the key is
|
|
7
|
+
* entered once in the Agent panel, so we only write the endpoint and models.
|
|
8
|
+
*/
|
|
9
|
+
export declare const zedAdapter: Adapter;
|
|
10
|
+
//# sourceMappingURL=zed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zed.d.ts","sourceRoot":"","sources":["../../src/adapters/zed.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAA6B,MAAM,aAAa,CAAC;AAatE;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,EAAE,OAiFxB,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import { readIfExists, shortenHome, writeFileSafely } from '../fsutil/edit.js';
|
|
4
|
+
import { editJsonc, parseJson } from '../fsutil/formats.js';
|
|
5
|
+
import { detectByBinOrConfig } from '../core/detect.js';
|
|
6
|
+
import { ctx, maxOut, modelsToWrite, result, xdgConfigHome } from './helpers.js';
|
|
7
|
+
function userConfig() {
|
|
8
|
+
if (process.platform === 'win32') {
|
|
9
|
+
return path.join(process.env.APPDATA ?? path.join(os.homedir(), 'AppData', 'Roaming'), 'Zed', 'settings.json');
|
|
10
|
+
}
|
|
11
|
+
return path.join(xdgConfigHome(), 'zed', 'settings.json');
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Zed's settings.json is a hand-curated JSONC file full of comments, so this
|
|
15
|
+
* adapter edits it surgically instead of reserialising the document.
|
|
16
|
+
*
|
|
17
|
+
* Zed explicitly tells you not to put API keys in settings.json — the key is
|
|
18
|
+
* entered once in the Agent panel, so we only write the endpoint and models.
|
|
19
|
+
*/
|
|
20
|
+
export const zedAdapter = {
|
|
21
|
+
id: 'zed',
|
|
22
|
+
name: 'Zed',
|
|
23
|
+
summary: 'Zed editor agent panel. Endpoint goes in settings.json, key goes in the UI.',
|
|
24
|
+
docsUrl: 'https://zed.dev/docs/ai/use-api-access',
|
|
25
|
+
bins: ['zed'],
|
|
26
|
+
mode: 'auto',
|
|
27
|
+
secretModes: ['env'],
|
|
28
|
+
async detect() {
|
|
29
|
+
return detectByBinOrConfig(['zed'], [userConfig()]);
|
|
30
|
+
},
|
|
31
|
+
configPath({ configPathOverride }) {
|
|
32
|
+
return configPathOverride ?? userConfig();
|
|
33
|
+
},
|
|
34
|
+
async apply(opts) {
|
|
35
|
+
const file = this.configPath(opts);
|
|
36
|
+
const before = await readIfExists(file);
|
|
37
|
+
const { target } = opts;
|
|
38
|
+
const available = modelsToWrite(target).map((m) => ({
|
|
39
|
+
name: m.id,
|
|
40
|
+
display_name: m.label,
|
|
41
|
+
max_tokens: ctx(m),
|
|
42
|
+
max_output_tokens: maxOut(m),
|
|
43
|
+
capabilities: {
|
|
44
|
+
tools: m.supportsTools ?? true,
|
|
45
|
+
images: m.supportsVision ?? false,
|
|
46
|
+
parallel_tool_calls: false,
|
|
47
|
+
prompt_cache_key: false,
|
|
48
|
+
},
|
|
49
|
+
}));
|
|
50
|
+
const after = editJsonc(before, ['language_models', 'openai_compatible', target.providerLabel], {
|
|
51
|
+
api_url: target.apiBase,
|
|
52
|
+
available_models: available,
|
|
53
|
+
});
|
|
54
|
+
const change = await writeFileSafely(file, after, { dryRun: opts.dryRun });
|
|
55
|
+
return result(this.id, [change], {
|
|
56
|
+
notes: [
|
|
57
|
+
`Open the Agent panel → Settings → "${target.providerLabel}" and paste the API key there. Zed does not read keys from settings.json.`,
|
|
58
|
+
'Comments and formatting elsewhere in settings.json are preserved.',
|
|
59
|
+
],
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
async remove(opts) {
|
|
63
|
+
const file = this.configPath(opts);
|
|
64
|
+
const before = await readIfExists(file);
|
|
65
|
+
if (before === null)
|
|
66
|
+
return result(this.id, []);
|
|
67
|
+
// Find the entry by provider id or label, since the key is the display name.
|
|
68
|
+
const doc = parseJson(before);
|
|
69
|
+
const compat = (doc.language_models?.openai_compatible ?? {});
|
|
70
|
+
const keys = Object.keys(compat).filter((k) => k === opts.providerId || k.toLowerCase().includes('idcloudhost'));
|
|
71
|
+
if (!keys.length)
|
|
72
|
+
return result(this.id, []);
|
|
73
|
+
let text = before;
|
|
74
|
+
for (const key of keys)
|
|
75
|
+
text = editJsonc(text, ['language_models', 'openai_compatible', key], undefined);
|
|
76
|
+
// Prune the containers we would otherwise leave behind as empty husks, but
|
|
77
|
+
// only if nothing else lives in them.
|
|
78
|
+
const pruned = parseJson(text);
|
|
79
|
+
const compatAfter = pruned.language_models?.openai_compatible;
|
|
80
|
+
if (compatAfter && typeof compatAfter === 'object' && Object.keys(compatAfter).length === 0) {
|
|
81
|
+
text = editJsonc(text, ['language_models', 'openai_compatible'], undefined);
|
|
82
|
+
const lmAfter = parseJson(text).language_models;
|
|
83
|
+
if (lmAfter && typeof lmAfter === 'object' && Object.keys(lmAfter).length === 0) {
|
|
84
|
+
text = editJsonc(text, ['language_models'], undefined);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const change = await writeFileSafely(file, text, { dryRun: opts.dryRun });
|
|
88
|
+
return result(this.id, [change], { notes: [`Removed ${keys.join(', ')} from ${shortenHome(file)}.`] });
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
//# sourceMappingURL=zed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zed.js","sourceRoot":"","sources":["../../src/adapters/zed.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { parseArgs } from 'node:util';
|
|
3
|
+
import process from 'node:process';
|
|
4
|
+
import { connectCommand } from './commands/connect.js';
|
|
5
|
+
import { listCommand } from './commands/list.js';
|
|
6
|
+
import { modelsCommand } from './commands/models.js';
|
|
7
|
+
import { doctorCommand } from './commands/doctor.js';
|
|
8
|
+
import { removeCommand } from './commands/remove.js';
|
|
9
|
+
import { loginCommand } from './commands/login.js';
|
|
10
|
+
import { envCommand } from './commands/env.js';
|
|
11
|
+
import { snippetCommand } from './commands/snippet.js';
|
|
12
|
+
import { loadStore, saveStore, configFile } from './core/store.js';
|
|
13
|
+
import { shortenHome } from './fsutil/edit.js';
|
|
14
|
+
import { HttpError } from './core/http.js';
|
|
15
|
+
import { c, ui } from './ui.js';
|
|
16
|
+
const HELP = `
|
|
17
|
+
${c.bold('idch-ai')} — point any AI agent at the IDCloudHost OpenAI-compatible gateway
|
|
18
|
+
|
|
19
|
+
${c.bold('USAGE')}
|
|
20
|
+
idch-ai <command> [agents…] [options]
|
|
21
|
+
|
|
22
|
+
${c.bold('COMMANDS')}
|
|
23
|
+
connect [agents…] Write provider config for one, several, or all detected agents
|
|
24
|
+
list Show supported agents and which are installed here
|
|
25
|
+
models List the models this key may use
|
|
26
|
+
doctor Probe the live gateway and check every agent config
|
|
27
|
+
remove [agents…] Strip our provider block back out
|
|
28
|
+
login Save gateway URL + key to a profile (nothing else touched)
|
|
29
|
+
logout Forget a saved profile
|
|
30
|
+
env Print the gateway as environment variables
|
|
31
|
+
snippet [lang] Starter code: curl, node, python, vercel-ai, langchain
|
|
32
|
+
|
|
33
|
+
${c.bold('AGENTS')}
|
|
34
|
+
opencode pi omp hermes openclaw codex claude-code crush goose
|
|
35
|
+
aider continue zed cline cursor qwen-code env (or: all)
|
|
36
|
+
|
|
37
|
+
${c.bold('CONNECTION')}
|
|
38
|
+
--base-url <url> Gateway base URL (env: IDCH_AI_BASE_URL)
|
|
39
|
+
--api-key <key> Virtual key (env: IDCH_AI_API_KEY)
|
|
40
|
+
--profile <name> Use a saved profile (default: the current one)
|
|
41
|
+
--dashboard-url <url> Discover the gateway through the dashboard API
|
|
42
|
+
--token <jwt> Dashboard access token
|
|
43
|
+
--org <id> Organization id
|
|
44
|
+
|
|
45
|
+
${c.bold('BEHAVIOUR')}
|
|
46
|
+
--model <id> Model to make the default (repeatable via --only)
|
|
47
|
+
--only <ids> Register only these models (comma separated)
|
|
48
|
+
--provider-id <id> Key our block is written under (default: idcloudhost)
|
|
49
|
+
--secret <mode> inline | env — where the key goes (adapters may override)
|
|
50
|
+
--scope <scope> user | project (default: user)
|
|
51
|
+
--config-path <file> Override the config file, single agent only
|
|
52
|
+
--dry-run Show what would change, write nothing
|
|
53
|
+
--print Print a diff of every change
|
|
54
|
+
--no-verify Skip the live test call after writing
|
|
55
|
+
--no-save Do not save a profile
|
|
56
|
+
--json Machine-readable output
|
|
57
|
+
--yes, -y Never prompt
|
|
58
|
+
--help, -h This text
|
|
59
|
+
--version, -v Print the version
|
|
60
|
+
|
|
61
|
+
${c.bold('EXAMPLES')}
|
|
62
|
+
idch-ai login
|
|
63
|
+
idch-ai connect
|
|
64
|
+
idch-ai connect opencode pi omp
|
|
65
|
+
idch-ai connect all --model deepseek-chat
|
|
66
|
+
idch-ai connect openclaw --dry-run --print
|
|
67
|
+
idch-ai doctor
|
|
68
|
+
eval "$(idch-ai env)"
|
|
69
|
+
`;
|
|
70
|
+
async function main(argv) {
|
|
71
|
+
const { values, positionals } = parseArgs({
|
|
72
|
+
args: argv,
|
|
73
|
+
allowPositionals: true,
|
|
74
|
+
strict: true,
|
|
75
|
+
options: {
|
|
76
|
+
'base-url': { type: 'string' },
|
|
77
|
+
'api-key': { type: 'string' },
|
|
78
|
+
profile: { type: 'string' },
|
|
79
|
+
'dashboard-url': { type: 'string' },
|
|
80
|
+
token: { type: 'string' },
|
|
81
|
+
org: { type: 'string' },
|
|
82
|
+
model: { type: 'string' },
|
|
83
|
+
only: { type: 'string' },
|
|
84
|
+
'provider-id': { type: 'string' },
|
|
85
|
+
'provider-label': { type: 'string' },
|
|
86
|
+
secret: { type: 'string' },
|
|
87
|
+
scope: { type: 'string' },
|
|
88
|
+
'config-path': { type: 'string' },
|
|
89
|
+
shell: { type: 'string' },
|
|
90
|
+
'dry-run': { type: 'boolean', default: false },
|
|
91
|
+
print: { type: 'boolean', default: false },
|
|
92
|
+
// Explicit negative flags rather than parseArgs' allowNegative, which only
|
|
93
|
+
// exists on newer Node than this package supports.
|
|
94
|
+
'no-verify': { type: 'boolean', default: false },
|
|
95
|
+
'no-save': { type: 'boolean', default: false },
|
|
96
|
+
offline: { type: 'boolean', default: false },
|
|
97
|
+
json: { type: 'boolean', default: false },
|
|
98
|
+
yes: { type: 'boolean', short: 'y', default: false },
|
|
99
|
+
help: { type: 'boolean', short: 'h', default: false },
|
|
100
|
+
version: { type: 'boolean', short: 'v', default: false },
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
if (values.version) {
|
|
104
|
+
ui.plain(await version());
|
|
105
|
+
return 0;
|
|
106
|
+
}
|
|
107
|
+
const command = positionals[0];
|
|
108
|
+
if (values.help || !command || command === 'help') {
|
|
109
|
+
ui.plain(HELP.trim());
|
|
110
|
+
return command || values.help ? 0 : 1;
|
|
111
|
+
}
|
|
112
|
+
const secret = values.secret;
|
|
113
|
+
if (secret && secret !== 'inline' && secret !== 'env')
|
|
114
|
+
throw new Error('--secret must be "inline" or "env"');
|
|
115
|
+
const scope = values.scope;
|
|
116
|
+
if (scope && scope !== 'user' && scope !== 'project')
|
|
117
|
+
throw new Error('--scope must be "user" or "project"');
|
|
118
|
+
const flags = {
|
|
119
|
+
cwd: process.cwd(),
|
|
120
|
+
json: values.json,
|
|
121
|
+
yes: values.yes,
|
|
122
|
+
dryRun: values['dry-run'],
|
|
123
|
+
print: values.print,
|
|
124
|
+
verify: !values['no-verify'],
|
|
125
|
+
save: !values['no-save'],
|
|
126
|
+
offline: values.offline,
|
|
127
|
+
...(values['base-url'] ? { baseUrl: values['base-url'] } : {}),
|
|
128
|
+
...(values['api-key'] ? { apiKey: values['api-key'] } : {}),
|
|
129
|
+
...(values.profile ? { profile: values.profile, profileName: values.profile } : {}),
|
|
130
|
+
...(values['dashboard-url'] ? { dashboardUrl: values['dashboard-url'] } : {}),
|
|
131
|
+
...(values.token ? { token: values.token } : {}),
|
|
132
|
+
...(values.org ? { org: values.org } : {}),
|
|
133
|
+
...(values.model ? { defaultModel: values.model } : {}),
|
|
134
|
+
...(values.only ? { onlyModels: values.only.split(',').map((s) => s.trim()).filter(Boolean) } : {}),
|
|
135
|
+
...(values['provider-id'] ? { providerId: values['provider-id'] } : {}),
|
|
136
|
+
...(values['provider-label'] ? { providerLabel: values['provider-label'] } : {}),
|
|
137
|
+
...(secret ? { secret } : {}),
|
|
138
|
+
...(scope ? { scope } : {}),
|
|
139
|
+
...(values['config-path'] ? { configPath: values['config-path'] } : {}),
|
|
140
|
+
};
|
|
141
|
+
const rest = positionals.slice(1);
|
|
142
|
+
switch (command) {
|
|
143
|
+
case 'connect':
|
|
144
|
+
case 'setup':
|
|
145
|
+
return connectCommand(rest, flags);
|
|
146
|
+
case 'list':
|
|
147
|
+
case 'agents':
|
|
148
|
+
return listCommand(flags);
|
|
149
|
+
case 'models':
|
|
150
|
+
return modelsCommand(flags);
|
|
151
|
+
case 'doctor':
|
|
152
|
+
case 'verify':
|
|
153
|
+
return doctorCommand(flags);
|
|
154
|
+
case 'remove':
|
|
155
|
+
case 'disconnect':
|
|
156
|
+
return removeCommand(rest, flags);
|
|
157
|
+
case 'login':
|
|
158
|
+
return loginCommand(flags);
|
|
159
|
+
case 'logout':
|
|
160
|
+
return logout(flags);
|
|
161
|
+
case 'env':
|
|
162
|
+
return envCommand({ ...flags, ...(values.shell ? { shell: values.shell } : {}) });
|
|
163
|
+
case 'snippet':
|
|
164
|
+
return snippetCommand(rest[0], flags);
|
|
165
|
+
default:
|
|
166
|
+
throw new Error(`unknown command "${command}". Run \`idch-ai --help\`.`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
async function logout(flags) {
|
|
170
|
+
const store = await loadStore();
|
|
171
|
+
const name = flags.profileName ?? store.current;
|
|
172
|
+
if (!name || !store.profiles[name]) {
|
|
173
|
+
ui.info('no saved profile to remove');
|
|
174
|
+
return 0;
|
|
175
|
+
}
|
|
176
|
+
delete store.profiles[name];
|
|
177
|
+
if (store.current === name)
|
|
178
|
+
delete store.current;
|
|
179
|
+
await saveStore(store);
|
|
180
|
+
ui.ok(`Removed profile "${name}" from ${shortenHome(configFile())}`);
|
|
181
|
+
ui.info('Agent configs still hold the key. Run `idch-ai remove all` to strip those too.');
|
|
182
|
+
return 0;
|
|
183
|
+
}
|
|
184
|
+
async function version() {
|
|
185
|
+
const { readFile } = await import('node:fs/promises');
|
|
186
|
+
const url = new URL('../package.json', import.meta.url);
|
|
187
|
+
const pkg = JSON.parse(await readFile(url, 'utf8'));
|
|
188
|
+
return pkg.version ?? '0.0.0';
|
|
189
|
+
}
|
|
190
|
+
main(process.argv.slice(2))
|
|
191
|
+
.then((code) => {
|
|
192
|
+
process.exitCode = code;
|
|
193
|
+
})
|
|
194
|
+
.catch((err) => {
|
|
195
|
+
if (err instanceof HttpError) {
|
|
196
|
+
ui.fail(err.friendly);
|
|
197
|
+
if (err.status === 401)
|
|
198
|
+
ui.info('The gateway rejected the key. Check it, or generate a new one in the dashboard.');
|
|
199
|
+
if (err.status === 429)
|
|
200
|
+
ui.info('You are over a budget or rate limit. Check your usage in the dashboard.');
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
ui.fail(err instanceof Error ? err.message : String(err));
|
|
204
|
+
}
|
|
205
|
+
process.exitCode = 1;
|
|
206
|
+
});
|
|
207
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"AAQA,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAG7D,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAkG7F"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import prompts from 'prompts';
|
|
2
|
+
import { adapters, getAdapter } from '../adapters/index.js';
|
|
3
|
+
import { buildTarget, resolveSource } from '../core/discovery.js';
|
|
4
|
+
import { testChat } from '../core/gateway.js';
|
|
5
|
+
import { saveProfile } from '../core/store.js';
|
|
6
|
+
import { shortenHome, unifiedDiff } from '../fsutil/edit.js';
|
|
7
|
+
import { c, maskKey, ui } from '../ui.js';
|
|
8
|
+
import { interactive } from './context.js';
|
|
9
|
+
import { promptForCredentials } from './login.js';
|
|
10
|
+
export async function connectCommand(agentArgs, flags) {
|
|
11
|
+
// 1. Credentials. Ask only when we cannot find them and someone is watching.
|
|
12
|
+
let source;
|
|
13
|
+
try {
|
|
14
|
+
source = await resolveSource(flags);
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
if (!interactive(flags))
|
|
18
|
+
throw err;
|
|
19
|
+
ui.warn(err.message);
|
|
20
|
+
source = await promptForCredentials(flags);
|
|
21
|
+
}
|
|
22
|
+
ui.step(`Gateway ${c.bold(source.baseUrl)} ${c.dim(`(${source.from.baseUrl})`)}`);
|
|
23
|
+
ui.step(`Key ${c.bold(maskKey(source.apiKey))} ${c.dim(`(${source.from.apiKey})`)}`);
|
|
24
|
+
// 2. Probe the gateway and pull the model catalogue.
|
|
25
|
+
const target = await buildTarget(source, flags);
|
|
26
|
+
if (target.models.length) {
|
|
27
|
+
ui.ok(`${target.models.length} model(s) available to this key. Default: ${c.bold(target.defaultModel ?? 'none')}`);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
ui.warn('No models were listed. Configs will be written with whatever --model you passed.');
|
|
31
|
+
}
|
|
32
|
+
// 3. Which agents.
|
|
33
|
+
const chosen = await chooseAgents(agentArgs, flags);
|
|
34
|
+
if (!chosen.length) {
|
|
35
|
+
ui.warn('No agents selected — nothing to do.');
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
// 4. Apply.
|
|
39
|
+
const results = [];
|
|
40
|
+
const failures = [];
|
|
41
|
+
for (const adapter of chosen) {
|
|
42
|
+
const secretMode = flags.secret && adapter.secretModes.includes(flags.secret) ? flags.secret : adapter.secretModes[0];
|
|
43
|
+
const opts = {
|
|
44
|
+
target,
|
|
45
|
+
dryRun: flags.dryRun ?? false,
|
|
46
|
+
secretMode,
|
|
47
|
+
scope: flags.scope ?? 'user',
|
|
48
|
+
cwd: flags.cwd,
|
|
49
|
+
...(flags.configPath && chosen.length === 1 ? { configPathOverride: flags.configPath } : {}),
|
|
50
|
+
};
|
|
51
|
+
try {
|
|
52
|
+
results.push(await adapter.apply(opts));
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
failures.push({ adapter, error: err });
|
|
56
|
+
ui.fail(`${adapter.name}: ${err.message}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// 5. Report.
|
|
60
|
+
if (flags.json) {
|
|
61
|
+
ui.plain(JSON.stringify({
|
|
62
|
+
gateway: { apiBase: target.apiBase, defaultModel: target.defaultModel, models: target.models.map((m) => m.id) },
|
|
63
|
+
applied: results,
|
|
64
|
+
failed: failures.map((f) => ({ adapter: f.adapter.id, error: f.error.message })),
|
|
65
|
+
}, null, 2));
|
|
66
|
+
return failures.length ? 1 : 0;
|
|
67
|
+
}
|
|
68
|
+
reportResults(results, chosen, flags);
|
|
69
|
+
// 6. Prove it works, rather than claiming it does.
|
|
70
|
+
if (flags.verify !== false && !flags.dryRun && target.defaultModel) {
|
|
71
|
+
ui.title('Verifying');
|
|
72
|
+
try {
|
|
73
|
+
const reply = await testChat(target.apiBase, target.apiKey, target.defaultModel);
|
|
74
|
+
ui.ok(`${target.defaultModel} replied: ${c.dim(JSON.stringify(reply.slice(0, 60)))}`);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
ui.fail(`the gateway did not answer a test call: ${err.message}`);
|
|
78
|
+
ui.info('The config files were still written. Run `idch-ai doctor` for a fuller diagnosis.');
|
|
79
|
+
return 1;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// 7. Remember, so the next agent is a one-liner.
|
|
83
|
+
if (flags.save !== false && !flags.dryRun) {
|
|
84
|
+
const name = flags.profileName ?? 'default';
|
|
85
|
+
const file = await saveProfile(name, {
|
|
86
|
+
apiBase: target.apiBase,
|
|
87
|
+
apiKey: target.apiKey,
|
|
88
|
+
savedAt: new Date().toISOString(),
|
|
89
|
+
...(target.defaultModel ? { defaultModel: target.defaultModel } : {}),
|
|
90
|
+
...(flags.dashboardUrl ? { dashboardUrl: flags.dashboardUrl } : {}),
|
|
91
|
+
...(flags.org ? { orgId: flags.org } : {}),
|
|
92
|
+
});
|
|
93
|
+
ui.info(`Saved profile "${name}" to ${shortenHome(file)} (chmod 600).`);
|
|
94
|
+
}
|
|
95
|
+
return failures.length ? 1 : 0;
|
|
96
|
+
}
|
|
97
|
+
async function chooseAgents(agentArgs, flags) {
|
|
98
|
+
const names = agentArgs.flatMap((a) => a.split(',')).map((a) => a.trim()).filter(Boolean);
|
|
99
|
+
if (names.includes('all'))
|
|
100
|
+
return adapters.filter((a) => a.mode === 'auto');
|
|
101
|
+
if (names.length) {
|
|
102
|
+
const found = [];
|
|
103
|
+
for (const name of names) {
|
|
104
|
+
const adapter = getAdapter(name);
|
|
105
|
+
if (!adapter)
|
|
106
|
+
throw new Error(`unknown agent "${name}". Run \`idch-ai list\` to see the supported ones.`);
|
|
107
|
+
found.push(adapter);
|
|
108
|
+
}
|
|
109
|
+
return found;
|
|
110
|
+
}
|
|
111
|
+
// Nothing named: offer what is actually installed on this machine.
|
|
112
|
+
const detected = await Promise.all(adapters.map(async (a) => ({ adapter: a, detect: await a.detect({ cwd: flags.cwd }) })));
|
|
113
|
+
const installed = detected.filter((d) => d.detect.installed && d.adapter.id !== 'env');
|
|
114
|
+
if (!interactive(flags)) {
|
|
115
|
+
if (!installed.length)
|
|
116
|
+
throw new Error('no supported agents were detected. Name one explicitly, e.g. `idch-ai connect opencode`.');
|
|
117
|
+
return installed.map((d) => d.adapter);
|
|
118
|
+
}
|
|
119
|
+
if (!installed.length) {
|
|
120
|
+
ui.warn('No supported agents detected on this machine.');
|
|
121
|
+
}
|
|
122
|
+
const { picked } = (await prompts({
|
|
123
|
+
type: 'multiselect',
|
|
124
|
+
name: 'picked',
|
|
125
|
+
message: 'Which agents should point at the gateway?',
|
|
126
|
+
instructions: false,
|
|
127
|
+
choices: adapters.map((a) => {
|
|
128
|
+
const hit = detected.find((d) => d.adapter.id === a.id);
|
|
129
|
+
const badge = hit?.detect.installed ? c.green('installed') : c.dim('not found');
|
|
130
|
+
return {
|
|
131
|
+
title: `${a.name} ${badge}${a.mode === 'manual' ? c.dim(' (prints instructions)') : ''}`,
|
|
132
|
+
value: a.id,
|
|
133
|
+
selected: hit?.detect.installed === true && a.mode === 'auto',
|
|
134
|
+
};
|
|
135
|
+
}),
|
|
136
|
+
}, { onCancel: () => process.exit(130) }));
|
|
137
|
+
return (picked ?? []).map((id) => getAdapter(id)).filter(Boolean);
|
|
138
|
+
}
|
|
139
|
+
function reportResults(results, chosen, flags) {
|
|
140
|
+
const envVars = {};
|
|
141
|
+
for (const res of results) {
|
|
142
|
+
const adapter = chosen.find((a) => a.id === res.adapterId);
|
|
143
|
+
ui.title(adapter.name);
|
|
144
|
+
if (adapter.mode === 'manual') {
|
|
145
|
+
for (const note of res.notes)
|
|
146
|
+
ui.plain(` ${note}`);
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (!res.changes.length) {
|
|
150
|
+
ui.info('nothing to change');
|
|
151
|
+
}
|
|
152
|
+
for (const change of res.changes) {
|
|
153
|
+
if (change.unchanged) {
|
|
154
|
+
ui.ok(`${shortenHome(change.path)} ${c.dim('already up to date')}`);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const verb = flags.dryRun ? 'would write' : change.before === null ? 'created' : 'updated';
|
|
158
|
+
ui.ok(`${verb} ${shortenHome(change.path)}`);
|
|
159
|
+
if (change.backupPath)
|
|
160
|
+
ui.info(`backup: ${shortenHome(change.backupPath)}`);
|
|
161
|
+
if (flags.print || flags.dryRun) {
|
|
162
|
+
ui.plain(c.dim(unifiedDiff(change.before, change.after, shortenHome(change.path))));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
for (const note of res.notes)
|
|
166
|
+
ui.info(note);
|
|
167
|
+
Object.assign(envVars, res.envVars);
|
|
168
|
+
if (res.tryCommand)
|
|
169
|
+
ui.plain(` ${c.dim('try:')} ${c.bold(res.tryCommand)}`);
|
|
170
|
+
}
|
|
171
|
+
if (Object.keys(envVars).length) {
|
|
172
|
+
ui.title('Environment');
|
|
173
|
+
ui.info('These configs read the key from the environment. Export it before starting the agent:');
|
|
174
|
+
for (const [k, v] of Object.entries(envVars))
|
|
175
|
+
ui.code(`export ${k}=${JSON.stringify(v)}`);
|
|
176
|
+
ui.info('Or run `idch-ai connect env` to get a sourceable file instead.');
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=connect.js.map
|