@botconnector/bccli 0.4.0-beta.10 → 0.4.0-beta.11
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/README.md +11 -0
- package/dist/{args-AWLROI65.js → args-SKWUZOJD.js} +1 -1
- package/dist/{chunk-IOWDWOXS.js → chunk-6BLZELE6.js} +1 -1
- package/dist/{chunk-BJ337ABK.js → chunk-TRMRDQ43.js} +1 -1
- package/dist/cli.js +6 -6
- package/dist/{integrationCli-GEIMUL3M.js → integrationCli-4PEJ74UG.js} +240 -4
- package/dist/{login-4C262MEI.js → login-N2CJC6RU.js} +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -99,6 +99,12 @@ BCCLI dapat memasang BotConnector sebagai provider untuk agent lain:
|
|
|
99
99
|
| `bccli connect aider` | hubungkan Aider ke BotConnector |
|
|
100
100
|
| `bccli connect cline` | hubungkan Cline CLI ke BotConnector |
|
|
101
101
|
| `bccli connect deepseek-harness` / `bccli connect dsh` | hubungkan DeepSeek Harness ke BotConnector |
|
|
102
|
+
| `bccli connect codex` | buat profile Codex Responses API + launcher BotConnector |
|
|
103
|
+
| `bccli connect claude-code` | buat launcher Claude Code via Anthropic Messages compatibility |
|
|
104
|
+
| `bccli connect cursor` | buat guided setup Cursor + warning override Base URL |
|
|
105
|
+
| `bccli connect openai-cli` | buat launcher OpenAI CLI khusus BotConnector |
|
|
106
|
+
| `bccli connect openai-sdk` | buat env profile untuk OpenAI Python/Node SDK |
|
|
107
|
+
| `bccli connect openai-compatible` | buat env profile universal OpenAI-compatible |
|
|
102
108
|
| `bccli disconnect <agent>` | pulihkan config sebelum integrasi |
|
|
103
109
|
|
|
104
110
|
OpenCode memakai config global `~/.config/opencode/opencode.json`. BCCLI mengambil katalog model BotConnector saat connect,
|
|
@@ -113,6 +119,11 @@ DeepSeek Harness memakai custom provider `botconnector` di `$DSH_HOME/settings.y
|
|
|
113
119
|
`api: openai-completions` dan `apiKeyEnv: BOTCONNECTOR_API_KEY`; key diletakkan pada blok BCCLI di
|
|
114
120
|
`$DSH_HOME/.env`. Provider DSH lain tetap dipertahankan.
|
|
115
121
|
|
|
122
|
+
Codex memakai profile `$CODEX_HOME/botconnector.config.toml` dengan `wire_api = "responses"` dan launcher
|
|
123
|
+
BCCLI yang membaca key dari storage BCCLI saat dijalankan. Claude Code memakai launcher terisolasi dengan
|
|
124
|
+
`ANTHROPIC_BASE_URL=https://api.botconnector.id` dan endpoint kompatibilitas `/v1/messages` + token counting.
|
|
125
|
+
Login/config utama Codex dan Claude Code tidak ditimpa.
|
|
126
|
+
|
|
116
127
|
External agent memanggil BotConnector langsung, jadi discovery model tidak memakai identitas khusus BCCLI.
|
|
117
128
|
Akses yang memang dibatasi ke BCCLI/Web App (misalnya Luna launch access) tidak otomatis diwariskan.
|
|
118
129
|
Sebelum mengubah config eksternal, BCCLI membuat backup agar disconnect dapat memulihkannya.
|
|
@@ -36,7 +36,7 @@ function readSecret(prompt) {
|
|
|
36
36
|
}
|
|
37
37
|
async function runLogin(providerId, cwd) {
|
|
38
38
|
const { runProviderCommand } = await import("./providerCli-Q7LRM2NP.js");
|
|
39
|
-
const { parseCliArgs } = await import("./args-
|
|
39
|
+
const { parseCliArgs } = await import("./args-SKWUZOJD.js");
|
|
40
40
|
return runProviderCommand(parseCliArgs(["provider", "add", providerId]), {
|
|
41
41
|
env: process.env,
|
|
42
42
|
cwd,
|
|
@@ -22,7 +22,7 @@ Pemakaian:
|
|
|
22
22
|
bccli provider list|add <id>|remove <id> kelola provider (custom: --url <url> [--name N] [--key-env ENV])
|
|
23
23
|
bccli mcp list|add <nama>|remove <nama> kelola server MCP (katalog, atau --url <url>)
|
|
24
24
|
bccli integrations lihat status integrasi agent eksternal
|
|
25
|
-
bccli connect <agent>
|
|
25
|
+
bccli connect <agent> opencode, aider, cline, dsh, codex, claude-code, cursor, openai-cli, openai-sdk, openai-compatible
|
|
26
26
|
bccli disconnect <agent> lepas integrasi dan pulihkan config sebelumnya
|
|
27
27
|
|
|
28
28
|
Opsi:
|
package/dist/cli.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
import {
|
|
13
13
|
HELP_TEXT,
|
|
14
14
|
parseCliArgs
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-TRMRDQ43.js";
|
|
16
16
|
import {
|
|
17
17
|
Permissions
|
|
18
18
|
} from "./chunk-ELML4KVQ.js";
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
import "./chunk-CLN4Z5E3.js";
|
|
28
28
|
import {
|
|
29
29
|
runLogin
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-6BLZELE6.js";
|
|
31
31
|
import {
|
|
32
32
|
Session,
|
|
33
33
|
pruneSessions
|
|
@@ -1374,7 +1374,7 @@ function createRuntime(opts) {
|
|
|
1374
1374
|
}
|
|
1375
1375
|
|
|
1376
1376
|
// src/version.ts
|
|
1377
|
-
var VERSION = true ? "0.4.0-beta.
|
|
1377
|
+
var VERSION = true ? "0.4.0-beta.11" : "0.0.0-dev";
|
|
1378
1378
|
|
|
1379
1379
|
// src/cli.ts
|
|
1380
1380
|
async function main() {
|
|
@@ -1391,16 +1391,16 @@ async function main() {
|
|
|
1391
1391
|
if (args.command === "login") return runLogin(args.loginProvider ?? "bc-cloud", cwd);
|
|
1392
1392
|
if (args.command === "mcp") {
|
|
1393
1393
|
const { runMcpCommand } = await import("./mcpCli-DZWQPTOS.js");
|
|
1394
|
-
const { readSecret } = await import("./login-
|
|
1394
|
+
const { readSecret } = await import("./login-N2CJC6RU.js");
|
|
1395
1395
|
return runMcpCommand(args, { env: process.env, cwd, out: (s) => console.log(s), err: (s) => console.error(s), readSecret });
|
|
1396
1396
|
}
|
|
1397
1397
|
if (args.command === "provider") {
|
|
1398
1398
|
const { runProviderCommand } = await import("./providerCli-Q7LRM2NP.js");
|
|
1399
|
-
const { readSecret } = await import("./login-
|
|
1399
|
+
const { readSecret } = await import("./login-N2CJC6RU.js");
|
|
1400
1400
|
return runProviderCommand(args, { env: process.env, cwd, out: (s) => console.log(s), err: (s) => console.error(s), readSecret });
|
|
1401
1401
|
}
|
|
1402
1402
|
if (args.command === "connect" || args.command === "disconnect" || args.command === "integrations") {
|
|
1403
|
-
const { runIntegrationCommand } = await import("./integrationCli-
|
|
1403
|
+
const { runIntegrationCommand } = await import("./integrationCli-4PEJ74UG.js");
|
|
1404
1404
|
return runIntegrationCommand(args, {
|
|
1405
1405
|
env: process.env,
|
|
1406
1406
|
cwd,
|
|
@@ -23,9 +23,11 @@ function keyPath(env) {
|
|
|
23
23
|
return join(integrationHome(env), "bc-cloud.key");
|
|
24
24
|
}
|
|
25
25
|
function parseTarget(raw) {
|
|
26
|
-
if (raw === "opencode" || raw === "aider" || raw === "cline" || raw === "deepseek-harness") return raw;
|
|
26
|
+
if (raw === "opencode" || raw === "aider" || raw === "cline" || raw === "deepseek-harness" || raw === "cursor" || raw === "openai-cli" || raw === "openai-sdk" || raw === "openai-compatible" || raw === "codex" || raw === "claude-code") return raw;
|
|
27
27
|
if (raw === "dsh") return "deepseek-harness";
|
|
28
|
-
throw new ConfigError(
|
|
28
|
+
throw new ConfigError(
|
|
29
|
+
"Agent harus salah satu dari: opencode, aider, cline, deepseek-harness (dsh), cursor, openai-cli, openai-sdk, openai-compatible, codex, claude-code"
|
|
30
|
+
);
|
|
29
31
|
}
|
|
30
32
|
function homeDir(env) {
|
|
31
33
|
const value = env.HOME || env.USERPROFILE;
|
|
@@ -304,6 +306,234 @@ ${managed}
|
|
|
304
306
|
deps.out(`Config: ${settingsPath}`);
|
|
305
307
|
deps.out("Provider: botconnector (OpenAI Chat Completions)");
|
|
306
308
|
}
|
|
309
|
+
function managedProfilePath(target, env, ext = "env") {
|
|
310
|
+
return join(integrationHome(env), `${target}.${ext}`);
|
|
311
|
+
}
|
|
312
|
+
function writeOpenAiEnvProfile(target, deps) {
|
|
313
|
+
const secret = ensureSecret(deps.env);
|
|
314
|
+
const key = readFileSync(secret, "utf8").trim();
|
|
315
|
+
const path = managedProfilePath(target, deps.env);
|
|
316
|
+
const backup = safeBackup(path, deps.env);
|
|
317
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
318
|
+
writeFileSync(path, [
|
|
319
|
+
`OPENAI_BASE_URL=${BASE_URL}`,
|
|
320
|
+
`OPENAI_API_KEY=${key}`,
|
|
321
|
+
""
|
|
322
|
+
].join("\n"), { mode: 384 });
|
|
323
|
+
try {
|
|
324
|
+
chmodSync(path, 384);
|
|
325
|
+
} catch {
|
|
326
|
+
}
|
|
327
|
+
writeState(target, {
|
|
328
|
+
target,
|
|
329
|
+
files: [{ path, ...backup }],
|
|
330
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
331
|
+
}, deps.env);
|
|
332
|
+
return path;
|
|
333
|
+
}
|
|
334
|
+
async function connectOpenAiCli(deps) {
|
|
335
|
+
const secret = ensureSecret(deps.env);
|
|
336
|
+
const dir = integrationHome(deps.env);
|
|
337
|
+
const launcher = join(dir, process.platform === "win32" ? "openai-botconnector.cmd" : "openai-botconnector");
|
|
338
|
+
const backup = safeBackup(launcher, deps.env);
|
|
339
|
+
mkdirSync(dir, { recursive: true });
|
|
340
|
+
if (process.platform === "win32") {
|
|
341
|
+
const keyFile = secret.replace(/\//g, "\\");
|
|
342
|
+
writeFileSync(launcher, [
|
|
343
|
+
"@echo off",
|
|
344
|
+
`set "OPENAI_BASE_URL=${BASE_URL}"`,
|
|
345
|
+
`for /f "usebackq delims=" %%A in ("${keyFile}") do set "OPENAI_API_KEY=%%A"`,
|
|
346
|
+
"openai %*",
|
|
347
|
+
""
|
|
348
|
+
].join("\r\n"));
|
|
349
|
+
} else {
|
|
350
|
+
const keyFile = secret.replace(/'/g, "'\\''");
|
|
351
|
+
writeFileSync(launcher, [
|
|
352
|
+
"#!/bin/sh",
|
|
353
|
+
`export OPENAI_BASE_URL='${BASE_URL}'`,
|
|
354
|
+
`export OPENAI_API_KEY="$(cat '${keyFile}')"`,
|
|
355
|
+
'exec openai "$@"',
|
|
356
|
+
""
|
|
357
|
+
].join("\n"), { mode: 448 });
|
|
358
|
+
try {
|
|
359
|
+
chmodSync(launcher, 448);
|
|
360
|
+
} catch {
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
writeState("openai-cli", {
|
|
364
|
+
target: "openai-cli",
|
|
365
|
+
files: [{ path: launcher, ...backup }],
|
|
366
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
367
|
+
}, deps.env);
|
|
368
|
+
deps.out("OpenAI CLI profile BotConnector siap.");
|
|
369
|
+
deps.out(`Launcher: ${launcher}`);
|
|
370
|
+
deps.out("Launcher tidak menyimpan API key di dalam script; key dibaca dari storage BCCLI saat dijalankan.");
|
|
371
|
+
}
|
|
372
|
+
async function connectOpenAiSdk(deps) {
|
|
373
|
+
const path = writeOpenAiEnvProfile("openai-sdk", deps);
|
|
374
|
+
deps.out("OpenAI SDK profile BotConnector siap.");
|
|
375
|
+
deps.out(`Env profile: ${path}`);
|
|
376
|
+
deps.out("Python dan Node OpenAI SDK dapat membaca OPENAI_BASE_URL dan OPENAI_API_KEY dari profile ini.");
|
|
377
|
+
}
|
|
378
|
+
async function connectOpenAiCompatible(deps) {
|
|
379
|
+
const path = writeOpenAiEnvProfile("openai-compatible", deps);
|
|
380
|
+
deps.out("Profile OpenAI-compatible BotConnector siap.");
|
|
381
|
+
deps.out(`Env profile: ${path}`);
|
|
382
|
+
deps.out(`Base URL: ${BASE_URL}`);
|
|
383
|
+
}
|
|
384
|
+
async function connectCursor(deps) {
|
|
385
|
+
const secret = ensureSecret(deps.env);
|
|
386
|
+
const path = managedProfilePath("cursor", deps.env, "txt");
|
|
387
|
+
const backup = safeBackup(path, deps.env);
|
|
388
|
+
const keyFile = secret.replace(/\\/g, "/");
|
|
389
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
390
|
+
writeFileSync(path, [
|
|
391
|
+
"BotConnector -> Cursor guided setup",
|
|
392
|
+
"",
|
|
393
|
+
`Base URL: ${BASE_URL}`,
|
|
394
|
+
`API key file: ${keyFile}`,
|
|
395
|
+
"",
|
|
396
|
+
"Cursor Settings -> Models:",
|
|
397
|
+
"1. Enable/add your OpenAI API key.",
|
|
398
|
+
"2. Enable Override OpenAI Base URL.",
|
|
399
|
+
`3. Set the override URL to ${BASE_URL}.`,
|
|
400
|
+
"4. Use Chat/Agent only; Cursor Tab/autocomplete remains on Cursor infrastructure.",
|
|
401
|
+
"",
|
|
402
|
+
"Important: Cursor currently applies the OpenAI Base URL override globally to OpenAI-family model requests.",
|
|
403
|
+
"Disable the override before switching back to Cursor-managed OpenAI-family models.",
|
|
404
|
+
""
|
|
405
|
+
].join("\n"));
|
|
406
|
+
writeState("cursor", {
|
|
407
|
+
target: "cursor",
|
|
408
|
+
files: [{ path, ...backup }],
|
|
409
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
410
|
+
}, deps.env);
|
|
411
|
+
deps.out("Cursor guided setup profile dibuat.");
|
|
412
|
+
deps.out(`Panduan: ${path}`);
|
|
413
|
+
deps.out("BCCLI tidak mengedit storage internal Cursor karena format override tersebut bukan konfigurasi eksternal yang stabil.");
|
|
414
|
+
}
|
|
415
|
+
function agentToolDefaultModel(models) {
|
|
416
|
+
for (const id of ["ling-3.0-flash", "mimo-v2.5", "deepseek-v4-flash"]) {
|
|
417
|
+
if (models.includes(id)) return id;
|
|
418
|
+
}
|
|
419
|
+
const first = models[0];
|
|
420
|
+
if (!first) throw new ConfigError("Katalog BotConnector tidak memiliki model untuk coding agent eksternal.");
|
|
421
|
+
return first;
|
|
422
|
+
}
|
|
423
|
+
async function connectCodex(deps) {
|
|
424
|
+
if (readState("codex", deps.env)) disconnect("codex", deps);
|
|
425
|
+
const home = homeDir(deps.env);
|
|
426
|
+
const codexHome = deps.env.CODEX_HOME || join(home, ".codex");
|
|
427
|
+
const profilePath = join(codexHome, "botconnector.config.toml");
|
|
428
|
+
const launcher = join(integrationHome(deps.env), process.platform === "win32" ? "codex-botconnector.cmd" : "codex-botconnector");
|
|
429
|
+
if (existsSync(profilePath)) {
|
|
430
|
+
throw new ConfigError("Codex sudah memiliki botconnector.config.toml. BCCLI tidak akan menimpanya.");
|
|
431
|
+
}
|
|
432
|
+
const profileBackup = safeBackup(profilePath, deps.env);
|
|
433
|
+
const launcherBackup = safeBackup(launcher, deps.env);
|
|
434
|
+
const secret = ensureSecret(deps.env);
|
|
435
|
+
const models = await botConnectorModels(deps);
|
|
436
|
+
const model = agentToolDefaultModel(models);
|
|
437
|
+
const profile = [
|
|
438
|
+
`model = ${JSON.stringify(model)}`,
|
|
439
|
+
'model_provider = "botconnector"',
|
|
440
|
+
"",
|
|
441
|
+
"[model_providers.botconnector]",
|
|
442
|
+
'name = "BotConnector"',
|
|
443
|
+
`base_url = "${BASE_URL}"`,
|
|
444
|
+
'env_key = "BOTCONNECTOR_API_KEY"',
|
|
445
|
+
'wire_api = "responses"',
|
|
446
|
+
"requires_openai_auth = false",
|
|
447
|
+
"supports_websockets = false",
|
|
448
|
+
"supports_standalone_web_search = false",
|
|
449
|
+
""
|
|
450
|
+
].join("\n");
|
|
451
|
+
mkdirSync(codexHome, { recursive: true });
|
|
452
|
+
writeFileSync(profilePath, profile);
|
|
453
|
+
mkdirSync(dirname(launcher), { recursive: true });
|
|
454
|
+
if (process.platform === "win32") {
|
|
455
|
+
const keyFile = secret.replace(/\//g, "\\");
|
|
456
|
+
writeFileSync(launcher, [
|
|
457
|
+
"@echo off",
|
|
458
|
+
'set "BOTCONNECTOR_API_KEY="',
|
|
459
|
+
`for /f "usebackq delims=" %%A in ("${keyFile}") do set "BOTCONNECTOR_API_KEY=%%A"`,
|
|
460
|
+
"codex -p botconnector %*",
|
|
461
|
+
""
|
|
462
|
+
].join("\r\n"));
|
|
463
|
+
} else {
|
|
464
|
+
const keyFile = secret.replace(/'/g, "'\\''");
|
|
465
|
+
writeFileSync(launcher, [
|
|
466
|
+
"#!/bin/sh",
|
|
467
|
+
`export BOTCONNECTOR_API_KEY="$(cat '${keyFile}')"`,
|
|
468
|
+
'exec codex -p botconnector "$@"',
|
|
469
|
+
""
|
|
470
|
+
].join("\n"), { mode: 448 });
|
|
471
|
+
try {
|
|
472
|
+
chmodSync(launcher, 448);
|
|
473
|
+
} catch {
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
writeState("codex", {
|
|
477
|
+
target: "codex",
|
|
478
|
+
files: [{ path: profilePath, ...profileBackup }, { path: launcher, ...launcherBackup }],
|
|
479
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
480
|
+
}, deps.env);
|
|
481
|
+
deps.out("Codex CLI terhubung ke BotConnector Responses API.");
|
|
482
|
+
deps.out(`Profile: ${profilePath}`);
|
|
483
|
+
deps.out(`Launcher: ${launcher}`);
|
|
484
|
+
deps.out(`Default coding model: ${model}`);
|
|
485
|
+
}
|
|
486
|
+
async function connectClaudeCode(deps) {
|
|
487
|
+
const secret = ensureSecret(deps.env);
|
|
488
|
+
const models = await botConnectorModels(deps);
|
|
489
|
+
const model = agentToolDefaultModel(models);
|
|
490
|
+
const launcher = join(integrationHome(deps.env), process.platform === "win32" ? "claude-botconnector.cmd" : "claude-botconnector");
|
|
491
|
+
const backup = safeBackup(launcher, deps.env);
|
|
492
|
+
mkdirSync(dirname(launcher), { recursive: true });
|
|
493
|
+
if (process.platform === "win32") {
|
|
494
|
+
const keyFile = secret.replace(/\//g, "\\");
|
|
495
|
+
writeFileSync(launcher, [
|
|
496
|
+
"@echo off",
|
|
497
|
+
'set "ANTHROPIC_AUTH_TOKEN="',
|
|
498
|
+
'set "CLAUDE_CODE_OAUTH_TOKEN="',
|
|
499
|
+
'set "ANTHROPIC_API_KEY="',
|
|
500
|
+
`for /f "usebackq delims=" %%A in ("${keyFile}") do set "ANTHROPIC_API_KEY=%%A"`,
|
|
501
|
+
'set "ANTHROPIC_BASE_URL=https://api.botconnector.id"',
|
|
502
|
+
`set "ANTHROPIC_MODEL=${model}"`,
|
|
503
|
+
`set "ANTHROPIC_DEFAULT_OPUS_MODEL=${model}"`,
|
|
504
|
+
`set "ANTHROPIC_DEFAULT_SONNET_MODEL=${model}"`,
|
|
505
|
+
`set "ANTHROPIC_DEFAULT_HAIKU_MODEL=${model}"`,
|
|
506
|
+
"claude %*",
|
|
507
|
+
""
|
|
508
|
+
].join("\r\n"));
|
|
509
|
+
} else {
|
|
510
|
+
const keyFile = secret.replace(/'/g, "'\\''");
|
|
511
|
+
writeFileSync(launcher, [
|
|
512
|
+
"#!/bin/sh",
|
|
513
|
+
"unset ANTHROPIC_AUTH_TOKEN CLAUDE_CODE_OAUTH_TOKEN",
|
|
514
|
+
`export ANTHROPIC_API_KEY="$(cat '${keyFile}')"`,
|
|
515
|
+
"export ANTHROPIC_BASE_URL='https://api.botconnector.id'",
|
|
516
|
+
`export ANTHROPIC_MODEL='${model}'`,
|
|
517
|
+
`export ANTHROPIC_DEFAULT_OPUS_MODEL='${model}'`,
|
|
518
|
+
`export ANTHROPIC_DEFAULT_SONNET_MODEL='${model}'`,
|
|
519
|
+
`export ANTHROPIC_DEFAULT_HAIKU_MODEL='${model}'`,
|
|
520
|
+
'exec claude "$@"',
|
|
521
|
+
""
|
|
522
|
+
].join("\n"), { mode: 448 });
|
|
523
|
+
try {
|
|
524
|
+
chmodSync(launcher, 448);
|
|
525
|
+
} catch {
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
writeState("claude-code", {
|
|
529
|
+
target: "claude-code",
|
|
530
|
+
files: [{ path: launcher, ...backup }],
|
|
531
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
532
|
+
}, deps.env);
|
|
533
|
+
deps.out("Claude Code terhubung ke BotConnector Anthropic Messages compatibility API.");
|
|
534
|
+
deps.out(`Launcher: ${launcher}`);
|
|
535
|
+
deps.out(`Default coding model: ${model}`);
|
|
536
|
+
}
|
|
307
537
|
function disconnect(target, deps) {
|
|
308
538
|
const state = readState(target, deps.env);
|
|
309
539
|
if (!state) {
|
|
@@ -322,7 +552,7 @@ function disconnect(target, deps) {
|
|
|
322
552
|
deps.out(`${target}: integrasi BotConnector dilepas dan config dipulihkan.`);
|
|
323
553
|
}
|
|
324
554
|
function listIntegrations(deps) {
|
|
325
|
-
for (const target of ["opencode", "aider", "cline", "deepseek-harness"]) {
|
|
555
|
+
for (const target of ["opencode", "aider", "cline", "deepseek-harness", "cursor", "openai-cli", "openai-sdk", "openai-compatible", "codex", "claude-code"]) {
|
|
326
556
|
deps.out(`${target} ${readState(target, deps.env) ? "connected" : "not connected"}`);
|
|
327
557
|
}
|
|
328
558
|
}
|
|
@@ -339,7 +569,13 @@ async function runIntegrationCommand(args, deps) {
|
|
|
339
569
|
if (target === "opencode") await connectOpenCode(deps);
|
|
340
570
|
else if (target === "aider") await connectAider(deps);
|
|
341
571
|
else if (target === "cline") await connectCline(deps);
|
|
342
|
-
else await connectDeepSeekHarness(deps);
|
|
572
|
+
else if (target === "deepseek-harness") await connectDeepSeekHarness(deps);
|
|
573
|
+
else if (target === "cursor") await connectCursor(deps);
|
|
574
|
+
else if (target === "openai-cli") await connectOpenAiCli(deps);
|
|
575
|
+
else if (target === "openai-sdk") await connectOpenAiSdk(deps);
|
|
576
|
+
else if (target === "openai-compatible") await connectOpenAiCompatible(deps);
|
|
577
|
+
else if (target === "codex") await connectCodex(deps);
|
|
578
|
+
else await connectClaudeCode(deps);
|
|
343
579
|
return 0;
|
|
344
580
|
}
|
|
345
581
|
export {
|