agent-phonon 0.2.4 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -4690,6 +4690,8 @@ var CodexSession = class {
4690
4690
  this.env = env;
4691
4691
  }
4692
4692
  providerArgs() {
4693
+ if (!this.env.baseUrl || !this.env.apiKey)
4694
+ return [];
4693
4695
  const id = this.env.providerId ?? "phonon_gateway";
4694
4696
  const name = this.env.providerName ?? "phonon-gateway";
4695
4697
  return [
@@ -4717,14 +4719,14 @@ var CodexSession = class {
4717
4719
 
4718
4720
  ${prompt}`;
4719
4721
  }
4720
- const args2 = this.threadId ? ["exec", "resume", this.threadId, "-", "--json", ...this.providerArgs(), "--model", this.model, "--dangerously-bypass-approvals-and-sandbox"] : ["exec", "-", "--json", ...this.providerArgs(), "--model", this.model, "--dangerously-bypass-approvals-and-sandbox"];
4722
+ const args2 = this.threadId ? ["exec", "resume", this.threadId, "-", "--json", ...this.providerArgs(), ...this.model !== "default" ? ["--model", this.model] : [], "--dangerously-bypass-approvals-and-sandbox"] : ["exec", "-", "--json", ...this.providerArgs(), ...this.model !== "default" ? ["--model", this.model] : [], "--dangerously-bypass-approvals-and-sandbox"];
4721
4723
  await this.run(args2, prompt, turnId, emit, opts);
4722
4724
  }
4723
4725
  run(args2, stdin, turnId, emit, opts) {
4724
4726
  return new Promise((resolve5) => {
4725
4727
  const child = spawn3("codex", args2, {
4726
4728
  cwd: this.cwd,
4727
- env: { ...process.env, ...opts.environment ?? {}, OPENAI_API_KEY: this.env.apiKey }
4729
+ env: { ...process.env, ...opts.environment ?? {}, ...this.env.apiKey ? { OPENAI_API_KEY: this.env.apiKey } : {} }
4728
4730
  });
4729
4731
  this.current = child;
4730
4732
  let buf = "";
@@ -5489,16 +5491,20 @@ var CAPABILITIES5 = {
5489
5491
  limits: { maxConcurrentSessions: 4 }
5490
5492
  };
5491
5493
  function writeSettingsFile(env, model) {
5494
+ if (!env.baseUrl || !env.authToken)
5495
+ return void 0;
5492
5496
  const dir = mkdtempSync(join10(tmpdir2(), "phonon-cc-"));
5493
5497
  const file = join10(dir, "settings.json");
5494
5498
  const content = JSON.stringify({
5495
5499
  env: {
5496
5500
  ANTHROPIC_BASE_URL: env.baseUrl,
5497
5501
  ANTHROPIC_AUTH_TOKEN: env.authToken,
5498
- ANTHROPIC_MODEL: model,
5499
- ANTHROPIC_DEFAULT_OPUS_MODEL: model,
5500
- ANTHROPIC_DEFAULT_SONNET_MODEL: model,
5501
- ANTHROPIC_DEFAULT_HAIKU_MODEL: model,
5502
+ ...model !== "default" ? {
5503
+ ANTHROPIC_MODEL: model,
5504
+ ANTHROPIC_DEFAULT_OPUS_MODEL: model,
5505
+ ANTHROPIC_DEFAULT_SONNET_MODEL: model,
5506
+ ANTHROPIC_DEFAULT_HAIKU_MODEL: model
5507
+ } : {},
5502
5508
  CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1"
5503
5509
  }
5504
5510
  });
@@ -5551,12 +5557,13 @@ ${prompt}`;
5551
5557
  // 最高权限:bypassPermissions 跳过所有权限确认;不限定 allowedTools = 所有工具可用
5552
5558
  // (phonon 定位:全自动执行,牺牲安全换自动化)
5553
5559
  "--permission-mode",
5554
- "bypassPermissions",
5555
- "--settings",
5556
- this.settingsFile(),
5557
- "--model",
5558
- this.model
5560
+ "bypassPermissions"
5559
5561
  ];
5562
+ const settings = this.settingsFile();
5563
+ if (settings)
5564
+ args2.push("--settings", settings);
5565
+ if (this.model !== "default")
5566
+ args2.push("--model", this.model);
5560
5567
  if (this.started)
5561
5568
  args2.push("--resume", this.uuid);
5562
5569
  else
@@ -6127,6 +6134,166 @@ function readOpenClawGatewayToken() {
6127
6134
  }
6128
6135
  }
6129
6136
 
6137
+ // src/commands.ts
6138
+ import { spawnSync } from "node:child_process";
6139
+ import { existsSync as existsSync12, cpSync, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync4, readFileSync as readFileSync5 } from "node:fs";
6140
+ import { homedir as homedir10 } from "node:os";
6141
+ import { join as join12, dirname as dirname5 } from "node:path";
6142
+ import { fileURLToPath } from "node:url";
6143
+ function probe(bin, args2 = ["--version"]) {
6144
+ const r = spawnSync(bin, args2, { timeout: 8e3 });
6145
+ return { ok: r.status === 0, out: (r.stdout?.toString() ?? "").trim().split("\n")[0] ?? "" };
6146
+ }
6147
+ function gatewayReachable(url) {
6148
+ try {
6149
+ const u = new URL(url.replace(/^ws/, "http"));
6150
+ const r = spawnSync("bash", ["-c", `exec 3<>/dev/tcp/${u.hostname}/${u.port || 80} && echo ok`], { timeout: 3e3 });
6151
+ return r.status === 0;
6152
+ } catch {
6153
+ return false;
6154
+ }
6155
+ }
6156
+ function openCodeBin() {
6157
+ const bundled = join12(homedir10(), ".opencode", "bin", "opencode");
6158
+ return existsSync12(bundled) ? bundled : "opencode";
6159
+ }
6160
+ function autoDetectAdapters(adapters) {
6161
+ const out = [...adapters];
6162
+ const has = (type2) => out.some((a) => a.type === type2);
6163
+ if (!has("hermes") && probe("hermes").ok) out.push({ type: "hermes" });
6164
+ const ocBin = openCodeBin();
6165
+ if (!has("opencode") && probe(ocBin).ok) out.push({ type: "opencode", opencodeBinPath: ocBin === "opencode" ? void 0 : ocBin });
6166
+ if (!has("claude-code") && probe("claude").ok) out.push({ type: "claude-code", claudeDefaultModel: "default" });
6167
+ if (!has("codex") && probe("codex").ok) out.push({ type: "codex", codexDefaultModel: "default" });
6168
+ return out;
6169
+ }
6170
+ function cmdDoctor() {
6171
+ console.log("agent-phonon doctor\n");
6172
+ const gwToken = readOpenClawGatewayToken();
6173
+ const gwUrl = "ws://127.0.0.1:18789";
6174
+ const gwOk = gatewayReachable(gwUrl);
6175
+ console.log(`OpenClaw Gateway (${gwUrl}): ${gwOk ? "\u2713 reachable" : "\u2717 unreachable"}${gwToken ? " (token found)" : " (no token in ~/.openclaw/openclaw.json)"}`);
6176
+ const pluginDir = join12(homedir10(), ".openclaw", "extensions", "agent-phonon-hitl");
6177
+ console.log(`OpenClaw HITL plugin: ${existsSync12(pluginDir) ? "\u2713 installed" : "\u2717 not installed (run: agent-phonon plugin install openclaw)"}`);
6178
+ console.log("\nCLI agents:");
6179
+ for (const [name, bin] of [["Claude Code", "claude"], ["Codex", "codex"], ["Hermes", "hermes"]]) {
6180
+ const p = probe(bin);
6181
+ console.log(` ${name} (${bin}): ${p.ok ? "\u2713 " + p.out : "\u2717 not found"}`);
6182
+ }
6183
+ const ocBin = openCodeBin();
6184
+ const oc = probe(ocBin);
6185
+ console.log(` OpenCode (${ocBin}): ${oc.ok ? "\u2713 " + oc.out : "\u2717 not found"}`);
6186
+ console.log("");
6187
+ try {
6188
+ const cfg = loadConfig();
6189
+ const effective = autoDetectAdapters(cfg.adapters);
6190
+ console.log(`config: ${cfg.adapters.length} configured adapter(s), ${effective.length} effective adapter(s), ${cfg.servers.length} server(s)`);
6191
+ } catch {
6192
+ console.log("config: not initialized (run: agent-phonon init)");
6193
+ }
6194
+ }
6195
+ async function cmdDiscover() {
6196
+ let cfg;
6197
+ try {
6198
+ cfg = loadConfig();
6199
+ } catch {
6200
+ console.error("config not initialized \u2014 run 'agent-phonon init' first");
6201
+ process.exit(1);
6202
+ return;
6203
+ }
6204
+ const reg = buildRegistry(cfg.adapters);
6205
+ const nested = await Promise.all(reg.all().map((a) => a.discoverAgents()));
6206
+ const agents = nested.flat();
6207
+ console.log(`discovered ${agents.length} agent(s):
6208
+ `);
6209
+ for (const a of agents) {
6210
+ console.log(` ${a.available ? "\u2713" : "\u2717"} ${a.agentId} (${a.displayName})${a.available ? "" : " \u2014 " + (a.unavailableReason ?? "unavailable")}`);
6211
+ if (a.models.length) console.log(` models: ${a.models.map((m) => m.id).join(", ")}`);
6212
+ }
6213
+ }
6214
+ function buildRegistry(adapters) {
6215
+ const reg = new AdapterRegistry();
6216
+ for (const a of autoDetectAdapters(adapters)) {
6217
+ if (a.type === "openclaw-gateway") {
6218
+ const token = a.gatewayToken ?? readOpenClawGatewayToken();
6219
+ if (token) reg.register(new OpenClawGatewayAdapter({ gateway: { baseUrl: a.gatewayUrl ?? "ws://127.0.0.1:18789", token }, defaultAgent: a.defaultAgent ?? "main" }));
6220
+ } else if (a.type === "claude-code") {
6221
+ reg.register(new ClaudeCodeAdapter({ env: { baseUrl: a.claudeBaseUrl, authToken: a.claudeAuthToken, defaultModel: a.claudeDefaultModel ?? "default", models: a.claudeModels } }));
6222
+ } else if (a.type === "codex") {
6223
+ reg.register(new CodexAdapter({ env: { baseUrl: a.codexBaseUrl, apiKey: a.codexApiKey, defaultModel: a.codexDefaultModel ?? "default", models: a.codexModels, wireApi: a.codexWireApi ?? "responses" } }));
6224
+ } else if (a.type === "hermes") {
6225
+ reg.register(new HermesAdapter({ env: { defaultModel: a.hermesModel, provider: a.hermesProvider } }));
6226
+ } else if (a.type === "opencode") {
6227
+ reg.register(new OpenCodeAdapter({ env: { binPath: a.opencodeBinPath, defaultModel: a.opencodeModel } }));
6228
+ }
6229
+ }
6230
+ return reg;
6231
+ }
6232
+ function cmdAdapterAdd(type2, opts) {
6233
+ const cfg = loadConfig();
6234
+ let a;
6235
+ switch (type2) {
6236
+ case "openclaw":
6237
+ case "openclaw-gateway":
6238
+ a = { type: "openclaw-gateway", gatewayUrl: opts.gatewayUrl ?? "ws://127.0.0.1:18789", gatewayToken: opts.token, defaultAgent: opts.defaultAgent ?? "main" };
6239
+ break;
6240
+ case "claude-code":
6241
+ a = { type: "claude-code", claudeBaseUrl: opts.baseUrl, claudeAuthToken: opts.token, claudeDefaultModel: opts.model ?? "default" };
6242
+ break;
6243
+ case "codex":
6244
+ a = { type: "codex", codexBaseUrl: opts.baseUrl, codexApiKey: opts.apiKey, codexDefaultModel: opts.model ?? "default", codexWireApi: opts.wireApi ?? "responses" };
6245
+ break;
6246
+ case "hermes":
6247
+ a = { type: "hermes", hermesModel: opts.model, hermesProvider: opts.provider };
6248
+ break;
6249
+ case "opencode":
6250
+ a = { type: "opencode", opencodeBinPath: opts.bin, opencodeModel: opts.model };
6251
+ break;
6252
+ default:
6253
+ return fail(`unknown adapter type: ${type2} (openclaw|claude-code|codex|hermes|opencode)`);
6254
+ }
6255
+ cfg.adapters = cfg.adapters.filter((x) => x.type !== a.type);
6256
+ cfg.adapters.push(a);
6257
+ writeConfig(cfg);
6258
+ console.log(`added ${a.type} adapter (${cfg.adapters.length} total)`);
6259
+ }
6260
+ function cmdAdapterList() {
6261
+ const cfg = loadConfig();
6262
+ const effective = autoDetectAdapters(cfg.adapters);
6263
+ if (effective.length === 0) {
6264
+ console.log("(no adapters available)");
6265
+ return;
6266
+ }
6267
+ for (const a of effective) {
6268
+ const auto = cfg.adapters.some((x) => x.type === a.type) ? "" : " [auto]";
6269
+ console.log(`- ${a.type}${a.defaultAgent ? ` (agent: ${a.defaultAgent})` : ""}${auto}`);
6270
+ }
6271
+ }
6272
+ function cmdPluginInstall(which) {
6273
+ if (which !== "openclaw") return fail(`plugin install supports: openclaw (got: ${which})`);
6274
+ const here = dirname5(fileURLToPath(import.meta.url));
6275
+ const pluginSrc = join12(here, "..", "..", "openclaw-plugin");
6276
+ if (!existsSync12(join12(pluginSrc, "dist", "index.js"))) {
6277
+ return fail(`plugin not built. Run: cd ${pluginSrc} && pnpm build`);
6278
+ }
6279
+ const dist = join12(homedir10(), ".agent-phonon", "openclaw-plugin-dist");
6280
+ rmSync3(dist, { recursive: true, force: true });
6281
+ mkdirSync4(dist, { recursive: true });
6282
+ cpSync(join12(pluginSrc, "dist"), join12(dist, "dist"), { recursive: true });
6283
+ cpSync(join12(pluginSrc, "openclaw.plugin.json"), join12(dist, "openclaw.plugin.json"));
6284
+ const pkg = JSON.parse(readFileSync5(join12(pluginSrc, "package.json"), "utf8"));
6285
+ delete pkg.devDependencies;
6286
+ writeFileSync4(join12(dist, "package.json"), JSON.stringify(pkg, null, 2));
6287
+ console.log(`exported clean plugin \u2192 ${dist}`);
6288
+ const r = spawnSync("openclaw", ["plugins", "install", "--force", dist], { stdio: "inherit" });
6289
+ if (r.status === 0) console.log("\n\u2713 installed. Restart OpenClaw Gateway to load: systemctl --user restart openclaw-gateway.service");
6290
+ else fail("openclaw plugins install failed");
6291
+ }
6292
+ function fail(msg) {
6293
+ console.error("error:", msg);
6294
+ process.exit(1);
6295
+ }
6296
+
6130
6297
  // src/obs-server.ts
6131
6298
  import { createServer as createServer2 } from "node:http";
6132
6299
  var ObsServer = class {
@@ -6254,7 +6421,7 @@ var PhononDaemon = class {
6254
6421
  this.registerAdapters();
6255
6422
  }
6256
6423
  registerAdapters() {
6257
- for (const a of this.cfg.adapters) {
6424
+ for (const a of autoDetectAdapters(this.cfg.adapters)) {
6258
6425
  if (a.type === "openclaw-gateway") {
6259
6426
  const token = a.gatewayToken ?? readOpenClawGatewayToken();
6260
6427
  if (!token) {
@@ -6268,17 +6435,9 @@ var PhononDaemon = class {
6268
6435
  this.gatewayAdapters.push(ad);
6269
6436
  this.registry.register(ad);
6270
6437
  } else if (a.type === "claude-code") {
6271
- if (a.claudeBaseUrl && a.claudeAuthToken) {
6272
- this.registry.register(new ClaudeCodeAdapter({ env: { baseUrl: a.claudeBaseUrl, authToken: a.claudeAuthToken, defaultModel: a.claudeDefaultModel ?? "claude-opus-4.6" } }));
6273
- } else {
6274
- console.warn("[daemon] claude-code adapter skipped: need claudeBaseUrl + claudeAuthToken");
6275
- }
6438
+ this.registry.register(new ClaudeCodeAdapter({ env: { baseUrl: a.claudeBaseUrl, authToken: a.claudeAuthToken, defaultModel: a.claudeDefaultModel ?? "default", models: a.claudeModels } }));
6276
6439
  } else if (a.type === "codex") {
6277
- if (a.codexBaseUrl && a.codexApiKey) {
6278
- this.registry.register(new CodexAdapter({ env: { baseUrl: a.codexBaseUrl, apiKey: a.codexApiKey, defaultModel: a.codexDefaultModel ?? "gpt-5.5", wireApi: a.codexWireApi ?? "responses" } }));
6279
- } else {
6280
- console.warn("[daemon] codex adapter skipped: need codexBaseUrl + codexApiKey");
6281
- }
6440
+ this.registry.register(new CodexAdapter({ env: { baseUrl: a.codexBaseUrl, apiKey: a.codexApiKey, defaultModel: a.codexDefaultModel ?? "default", models: a.codexModels, wireApi: a.codexWireApi ?? "responses" } }));
6282
6441
  } else if (a.type === "hermes") {
6283
6442
  this.registry.register(new HermesAdapter({ env: { defaultModel: a.hermesModel, provider: a.hermesProvider } }));
6284
6443
  } else if (a.type === "opencode") {
@@ -6383,215 +6542,6 @@ var PhononDaemon = class {
6383
6542
 
6384
6543
  // src/cli.ts
6385
6544
  import { existsSync as existsSync13 } from "node:fs";
6386
-
6387
- // src/commands.ts
6388
- import { spawnSync } from "node:child_process";
6389
- import { existsSync as existsSync12, cpSync, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync4, readFileSync as readFileSync5 } from "node:fs";
6390
- import { homedir as homedir10 } from "node:os";
6391
- import { join as join12, dirname as dirname5 } from "node:path";
6392
- import { fileURLToPath } from "node:url";
6393
- function probe(bin, args2 = ["--version"]) {
6394
- const r = spawnSync(bin, args2, { timeout: 8e3 });
6395
- return { ok: r.status === 0, out: (r.stdout?.toString() ?? "").trim().split("\n")[0] ?? "" };
6396
- }
6397
- function gatewayReachable(url) {
6398
- try {
6399
- const u = new URL(url.replace(/^ws/, "http"));
6400
- const r = spawnSync("bash", ["-c", `exec 3<>/dev/tcp/${u.hostname}/${u.port || 80} && echo ok`], { timeout: 3e3 });
6401
- return r.status === 0;
6402
- } catch {
6403
- return false;
6404
- }
6405
- }
6406
- function openCodeBin() {
6407
- const bundled = join12(homedir10(), ".opencode", "bin", "opencode");
6408
- return existsSync12(bundled) ? bundled : "opencode";
6409
- }
6410
- function modelInfosFromProvider(provider) {
6411
- const raw = Array.isArray(provider.models) ? provider.models : [];
6412
- const out = [];
6413
- const seen = /* @__PURE__ */ new Set();
6414
- for (const m of raw) {
6415
- const row = m;
6416
- const id = typeof row.id === "string" ? row.id : typeof row.key === "string" ? row.key : void 0;
6417
- if (!id || seen.has(id)) continue;
6418
- seen.add(id);
6419
- const contextWindow = typeof row.contextWindow === "number" ? row.contextWindow : typeof row.contextTokens === "number" ? row.contextTokens : void 0;
6420
- out.push({
6421
- id,
6422
- ...typeof row.name === "string" ? { displayName: row.name } : {},
6423
- ...contextWindow && contextWindow > 0 ? { contextWindow } : {},
6424
- available: true
6425
- });
6426
- }
6427
- return out;
6428
- }
6429
- function readDefaultLlmGateway() {
6430
- try {
6431
- const p = join12(homedir10(), ".openclaw", "openclaw.json");
6432
- const j = JSON.parse(readFileSync5(p, "utf8"));
6433
- const provider = j.models?.providers?.["phgeek-gw"];
6434
- if (provider?.baseUrl && provider?.apiKey) {
6435
- const models = modelInfosFromProvider(provider);
6436
- return { baseUrl: provider.baseUrl.replace(/\/$/, ""), apiKey: provider.apiKey, models, claudeModels: models.filter((m) => m.id.toLowerCase().includes("claude")) };
6437
- }
6438
- } catch {
6439
- }
6440
- const baseUrl = process.env.PHONON_LLM_BASE_URL;
6441
- const apiKey = process.env.PHONON_LLM_API_KEY;
6442
- return baseUrl && apiKey ? { baseUrl: baseUrl.replace(/\/$/, ""), apiKey, models: [], claudeModels: [] } : void 0;
6443
- }
6444
- function autoDetectAdapters(adapters) {
6445
- const out = [...adapters];
6446
- const has = (type2) => out.some((a) => a.type === type2);
6447
- if (!has("hermes") && probe("hermes").ok) out.push({ type: "hermes" });
6448
- const ocBin = openCodeBin();
6449
- if (!has("opencode") && probe(ocBin).ok) out.push({ type: "opencode", opencodeBinPath: ocBin === "opencode" ? void 0 : ocBin });
6450
- const gw = readDefaultLlmGateway();
6451
- if (gw) {
6452
- for (const a of out) {
6453
- if (a.type === "claude-code" && !a.claudeModels?.length) a.claudeModels = gw.claudeModels;
6454
- if (a.type === "codex" && !a.codexModels?.length) a.codexModels = gw.models;
6455
- }
6456
- if (!has("claude-code") && probe("claude").ok) {
6457
- out.push({ type: "claude-code", claudeBaseUrl: gw.baseUrl, claudeAuthToken: gw.apiKey, claudeDefaultModel: "claude-opus-4.8", claudeModels: gw.claudeModels });
6458
- }
6459
- if (!has("codex") && probe("codex").ok) {
6460
- out.push({ type: "codex", codexBaseUrl: `${gw.baseUrl}/v1`, codexApiKey: gw.apiKey, codexDefaultModel: "gpt-5.5", codexWireApi: "responses", codexModels: gw.models });
6461
- }
6462
- }
6463
- return out;
6464
- }
6465
- function cmdDoctor() {
6466
- console.log("agent-phonon doctor\n");
6467
- const gwToken = readOpenClawGatewayToken();
6468
- const gwUrl = "ws://127.0.0.1:18789";
6469
- const gwOk = gatewayReachable(gwUrl);
6470
- console.log(`OpenClaw Gateway (${gwUrl}): ${gwOk ? "\u2713 reachable" : "\u2717 unreachable"}${gwToken ? " (token found)" : " (no token in ~/.openclaw/openclaw.json)"}`);
6471
- const pluginDir = join12(homedir10(), ".openclaw", "extensions", "agent-phonon-hitl");
6472
- console.log(`OpenClaw HITL plugin: ${existsSync12(pluginDir) ? "\u2713 installed" : "\u2717 not installed (run: agent-phonon plugin install openclaw)"}`);
6473
- console.log("\nCLI agents:");
6474
- for (const [name, bin] of [["Claude Code", "claude"], ["Codex", "codex"], ["Hermes", "hermes"]]) {
6475
- const p = probe(bin);
6476
- console.log(` ${name} (${bin}): ${p.ok ? "\u2713 " + p.out : "\u2717 not found"}`);
6477
- }
6478
- const ocBin = openCodeBin();
6479
- const oc = probe(ocBin);
6480
- console.log(` OpenCode (${ocBin}): ${oc.ok ? "\u2713 " + oc.out : "\u2717 not found"}`);
6481
- console.log("");
6482
- try {
6483
- const cfg = loadConfig();
6484
- const effective = autoDetectAdapters(cfg.adapters);
6485
- console.log(`config: ${cfg.adapters.length} configured adapter(s), ${effective.length} effective adapter(s), ${cfg.servers.length} server(s)`);
6486
- } catch {
6487
- console.log("config: not initialized (run: agent-phonon init)");
6488
- }
6489
- }
6490
- async function cmdDiscover() {
6491
- let cfg;
6492
- try {
6493
- cfg = loadConfig();
6494
- } catch {
6495
- console.error("config not initialized \u2014 run 'agent-phonon init' first");
6496
- process.exit(1);
6497
- return;
6498
- }
6499
- const reg = buildRegistry(cfg.adapters);
6500
- const nested = await Promise.all(reg.all().map((a) => a.discoverAgents()));
6501
- const agents = nested.flat();
6502
- console.log(`discovered ${agents.length} agent(s):
6503
- `);
6504
- for (const a of agents) {
6505
- console.log(` ${a.available ? "\u2713" : "\u2717"} ${a.agentId} (${a.displayName})${a.available ? "" : " \u2014 " + (a.unavailableReason ?? "unavailable")}`);
6506
- if (a.models.length) console.log(` models: ${a.models.map((m) => m.id).join(", ")}`);
6507
- }
6508
- }
6509
- function buildRegistry(adapters) {
6510
- const reg = new AdapterRegistry();
6511
- for (const a of autoDetectAdapters(adapters)) {
6512
- if (a.type === "openclaw-gateway") {
6513
- const token = a.gatewayToken ?? readOpenClawGatewayToken();
6514
- if (token) reg.register(new OpenClawGatewayAdapter({ gateway: { baseUrl: a.gatewayUrl ?? "ws://127.0.0.1:18789", token }, defaultAgent: a.defaultAgent ?? "main" }));
6515
- } else if (a.type === "claude-code" && a.claudeBaseUrl && a.claudeAuthToken) {
6516
- reg.register(new ClaudeCodeAdapter({ env: { baseUrl: a.claudeBaseUrl, authToken: a.claudeAuthToken, defaultModel: a.claudeDefaultModel ?? "claude-opus-4.6", models: a.claudeModels } }));
6517
- } else if (a.type === "codex" && a.codexBaseUrl && a.codexApiKey) {
6518
- reg.register(new CodexAdapter({ env: { baseUrl: a.codexBaseUrl, apiKey: a.codexApiKey, defaultModel: a.codexDefaultModel ?? "gpt-5.5", models: a.codexModels, wireApi: a.codexWireApi ?? "responses" } }));
6519
- } else if (a.type === "hermes") {
6520
- reg.register(new HermesAdapter({ env: { defaultModel: a.hermesModel, provider: a.hermesProvider } }));
6521
- } else if (a.type === "opencode") {
6522
- reg.register(new OpenCodeAdapter({ env: { binPath: a.opencodeBinPath, defaultModel: a.opencodeModel } }));
6523
- }
6524
- }
6525
- return reg;
6526
- }
6527
- function cmdAdapterAdd(type2, opts) {
6528
- const cfg = loadConfig();
6529
- let a;
6530
- switch (type2) {
6531
- case "openclaw":
6532
- case "openclaw-gateway":
6533
- a = { type: "openclaw-gateway", gatewayUrl: opts.gatewayUrl ?? "ws://127.0.0.1:18789", gatewayToken: opts.token, defaultAgent: opts.defaultAgent ?? "main" };
6534
- break;
6535
- case "claude-code":
6536
- if (!opts.baseUrl || !opts.token) return fail("claude-code needs --base-url and --token");
6537
- a = { type: "claude-code", claudeBaseUrl: opts.baseUrl, claudeAuthToken: opts.token, claudeDefaultModel: opts.model ?? "claude-opus-4.6" };
6538
- break;
6539
- case "codex":
6540
- if (!opts.baseUrl || !opts.apiKey) return fail("codex needs --base-url and --api-key");
6541
- a = { type: "codex", codexBaseUrl: opts.baseUrl, codexApiKey: opts.apiKey, codexDefaultModel: opts.model ?? "gpt-5.5", codexWireApi: opts.wireApi ?? "responses" };
6542
- break;
6543
- case "hermes":
6544
- a = { type: "hermes", hermesModel: opts.model, hermesProvider: opts.provider };
6545
- break;
6546
- case "opencode":
6547
- a = { type: "opencode", opencodeBinPath: opts.bin, opencodeModel: opts.model };
6548
- break;
6549
- default:
6550
- return fail(`unknown adapter type: ${type2} (openclaw|claude-code|codex|hermes|opencode)`);
6551
- }
6552
- cfg.adapters = cfg.adapters.filter((x) => x.type !== a.type);
6553
- cfg.adapters.push(a);
6554
- writeConfig(cfg);
6555
- console.log(`added ${a.type} adapter (${cfg.adapters.length} total)`);
6556
- }
6557
- function cmdAdapterList() {
6558
- const cfg = loadConfig();
6559
- const effective = autoDetectAdapters(cfg.adapters);
6560
- if (effective.length === 0) {
6561
- console.log("(no adapters available)");
6562
- return;
6563
- }
6564
- for (const a of effective) {
6565
- const auto = cfg.adapters.some((x) => x.type === a.type) ? "" : " [auto]";
6566
- console.log(`- ${a.type}${a.defaultAgent ? ` (agent: ${a.defaultAgent})` : ""}${auto}`);
6567
- }
6568
- }
6569
- function cmdPluginInstall(which) {
6570
- if (which !== "openclaw") return fail(`plugin install supports: openclaw (got: ${which})`);
6571
- const here = dirname5(fileURLToPath(import.meta.url));
6572
- const pluginSrc = join12(here, "..", "..", "openclaw-plugin");
6573
- if (!existsSync12(join12(pluginSrc, "dist", "index.js"))) {
6574
- return fail(`plugin not built. Run: cd ${pluginSrc} && pnpm build`);
6575
- }
6576
- const dist = join12(homedir10(), ".agent-phonon", "openclaw-plugin-dist");
6577
- rmSync3(dist, { recursive: true, force: true });
6578
- mkdirSync4(dist, { recursive: true });
6579
- cpSync(join12(pluginSrc, "dist"), join12(dist, "dist"), { recursive: true });
6580
- cpSync(join12(pluginSrc, "openclaw.plugin.json"), join12(dist, "openclaw.plugin.json"));
6581
- const pkg = JSON.parse(readFileSync5(join12(pluginSrc, "package.json"), "utf8"));
6582
- delete pkg.devDependencies;
6583
- writeFileSync4(join12(dist, "package.json"), JSON.stringify(pkg, null, 2));
6584
- console.log(`exported clean plugin \u2192 ${dist}`);
6585
- const r = spawnSync("openclaw", ["plugins", "install", "--force", dist], { stdio: "inherit" });
6586
- if (r.status === 0) console.log("\n\u2713 installed. Restart OpenClaw Gateway to load: systemctl --user restart openclaw-gateway.service");
6587
- else fail("openclaw plugins install failed");
6588
- }
6589
- function fail(msg) {
6590
- console.error("error:", msg);
6591
- process.exit(1);
6592
- }
6593
-
6594
- // src/cli.ts
6595
6545
  var [cmd, ...args] = process.argv.slice(2);
6596
6546
  function flag(name) {
6597
6547
  return args.includes(`--${name}`);