@ainyc/canonry 1.46.0 → 1.46.1
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 +73 -436
- package/assets/agent-workspace/skills/aero/SKILL.md +42 -0
- package/assets/agent-workspace/skills/aero/references/memory-patterns.md +37 -0
- package/assets/agent-workspace/skills/aero/references/orchestration.md +52 -0
- package/assets/agent-workspace/skills/aero/references/regression-playbook.md +34 -0
- package/assets/agent-workspace/skills/aero/references/reporting.md +67 -0
- package/assets/agent-workspace/skills/canonry-setup/SKILL.md +274 -0
- package/assets/agent-workspace/skills/canonry-setup/references/aeo-analysis.md +130 -0
- package/assets/agent-workspace/skills/canonry-setup/references/canonry-cli.md +339 -0
- package/assets/agent-workspace/skills/canonry-setup/references/indexing.md +155 -0
- package/assets/agent-workspace/skills/canonry-setup/references/wordpress-integration.md +57 -0
- package/dist/{chunk-22RIKNII.js → chunk-RMLIF47M.js} +3 -3
- package/dist/cli.js +753 -25
- package/dist/index.d.ts +11 -0
- package/dist/index.js +1 -1
- package/package.json +9 -9
package/dist/cli.js
CHANGED
|
@@ -28,11 +28,12 @@ import {
|
|
|
28
28
|
setGoogleAuthConfig,
|
|
29
29
|
showFirstRunNotice,
|
|
30
30
|
trackEvent
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-RMLIF47M.js";
|
|
32
32
|
import {
|
|
33
33
|
apiKeys,
|
|
34
34
|
competitors,
|
|
35
35
|
createClient,
|
|
36
|
+
createLogger,
|
|
36
37
|
migrate,
|
|
37
38
|
parseJsonColumn,
|
|
38
39
|
projects,
|
|
@@ -118,9 +119,9 @@ import { parseArgs } from "util";
|
|
|
118
119
|
function commandId(spec) {
|
|
119
120
|
return spec.path.join(".");
|
|
120
121
|
}
|
|
121
|
-
function matchesPath(args,
|
|
122
|
-
if (args.length <
|
|
123
|
-
return
|
|
122
|
+
function matchesPath(args, path9) {
|
|
123
|
+
if (args.length < path9.length) return false;
|
|
124
|
+
return path9.every((segment, index) => args[index] === segment);
|
|
124
125
|
}
|
|
125
126
|
function withFormatOption(options) {
|
|
126
127
|
if (!options) {
|
|
@@ -613,9 +614,9 @@ var ApiClient = class {
|
|
|
613
614
|
}
|
|
614
615
|
return this.probePromise;
|
|
615
616
|
}
|
|
616
|
-
async request(method,
|
|
617
|
+
async request(method, path9, body) {
|
|
617
618
|
await this.probeBasePath();
|
|
618
|
-
const url = `${this.baseUrl}${
|
|
619
|
+
const url = `${this.baseUrl}${path9}`;
|
|
619
620
|
const serializedBody = body != null ? JSON.stringify(body) : void 0;
|
|
620
621
|
const headers = {
|
|
621
622
|
"Authorization": `Bearer ${this.apiKey}`,
|
|
@@ -1694,9 +1695,9 @@ async function gaConnect(project, opts) {
|
|
|
1694
1695
|
propertyId: opts.propertyId
|
|
1695
1696
|
};
|
|
1696
1697
|
if (opts.keyFile) {
|
|
1697
|
-
const
|
|
1698
|
+
const fs10 = await import("fs");
|
|
1698
1699
|
try {
|
|
1699
|
-
const content =
|
|
1700
|
+
const content = fs10.readFileSync(opts.keyFile, "utf-8");
|
|
1700
1701
|
JSON.parse(content);
|
|
1701
1702
|
body.keyJson = content;
|
|
1702
1703
|
} catch (e) {
|
|
@@ -2454,10 +2455,10 @@ Open this URL in your browser to authorize Google ${opts.type.toUpperCase()} acc
|
|
|
2454
2455
|
console.log("(Ensure this URI is listed in your Google Cloud Console OAuth client's authorized redirect URIs)\n");
|
|
2455
2456
|
}
|
|
2456
2457
|
try {
|
|
2457
|
-
const { spawn:
|
|
2458
|
+
const { spawn: spawn3 } = await import("child_process");
|
|
2458
2459
|
const platform = process.platform;
|
|
2459
2460
|
const [cmd, ...extraArgs] = platform === "darwin" ? ["open", authUrl] : platform === "win32" ? ["cmd", "/c", "start", "", authUrl] : ["xdg-open", authUrl];
|
|
2460
|
-
|
|
2461
|
+
spawn3(cmd, [...extraArgs], { detached: true, stdio: "ignore" }).unref();
|
|
2461
2462
|
console.log("(Browser opened automatically)");
|
|
2462
2463
|
} catch {
|
|
2463
2464
|
console.log("(Could not open browser automatically \u2014 please copy the URL above)");
|
|
@@ -6142,6 +6143,15 @@ var DEFAULT_QUOTA = {
|
|
|
6142
6143
|
maxRequestsPerMinute: 10,
|
|
6143
6144
|
maxRequestsPerDay: 500
|
|
6144
6145
|
};
|
|
6146
|
+
var DEFAULT_AGENT_MODELS = {
|
|
6147
|
+
anthropic: "anthropic/claude-sonnet-4-6",
|
|
6148
|
+
openai: "openai/gpt-4o",
|
|
6149
|
+
openrouter: "openrouter/anthropic/claude-sonnet-4-6",
|
|
6150
|
+
groq: "groq/llama-4-scout-17b",
|
|
6151
|
+
google: "google/gemini-2.5-flash",
|
|
6152
|
+
mistral: "mistral/mistral-large-latest",
|
|
6153
|
+
xai: "xai/grok-2"
|
|
6154
|
+
};
|
|
6145
6155
|
async function initCommand(opts) {
|
|
6146
6156
|
const format = opts?.format ?? "text";
|
|
6147
6157
|
if (format !== "json") {
|
|
@@ -6154,11 +6164,11 @@ async function initCommand(opts) {
|
|
|
6154
6164
|
reason: "config_exists",
|
|
6155
6165
|
configPath: getConfigPath()
|
|
6156
6166
|
}, null, 2));
|
|
6157
|
-
return;
|
|
6167
|
+
return void 0;
|
|
6158
6168
|
}
|
|
6159
6169
|
console.log(`Config already exists at ${getConfigPath()}`);
|
|
6160
6170
|
console.log('To reinitialize, run "canonry init --force".');
|
|
6161
|
-
return;
|
|
6171
|
+
return void 0;
|
|
6162
6172
|
}
|
|
6163
6173
|
const configDir = getConfigDir();
|
|
6164
6174
|
if (!fs6.existsSync(configDir)) {
|
|
@@ -6313,6 +6323,29 @@ Config saved to ${getConfigPath()}`);
|
|
|
6313
6323
|
console.log(`API key: ${rawApiKey}`);
|
|
6314
6324
|
console.log(`Providers: ${providerNames.join(", ")}`);
|
|
6315
6325
|
}
|
|
6326
|
+
let agentLLM;
|
|
6327
|
+
const agentProvider = opts?.agentProvider;
|
|
6328
|
+
const agentKey = opts?.agentKey;
|
|
6329
|
+
const agentModel = opts?.agentModel;
|
|
6330
|
+
if (agentProvider || agentKey || agentModel) {
|
|
6331
|
+
const provider = agentProvider ?? "anthropic";
|
|
6332
|
+
agentLLM = {
|
|
6333
|
+
provider,
|
|
6334
|
+
key: agentKey,
|
|
6335
|
+
model: agentModel ?? DEFAULT_AGENT_MODELS[provider]
|
|
6336
|
+
};
|
|
6337
|
+
} else if (!nonInteractive) {
|
|
6338
|
+
console.log("\nConfigure agent LLM (the model that powers the agent):");
|
|
6339
|
+
console.log("Supported providers: anthropic, openai, openrouter, groq, mistral, xai, google, cerebras\n");
|
|
6340
|
+
const provider = await prompt("Provider [anthropic]: ") || "anthropic";
|
|
6341
|
+
const key = await prompt("API key (press Enter to skip): ");
|
|
6342
|
+
if (key) {
|
|
6343
|
+
const defaultModel = DEFAULT_AGENT_MODELS[provider];
|
|
6344
|
+
const modelText = defaultModel ? `Model [${defaultModel}]: ` : "Model: ";
|
|
6345
|
+
const model = await prompt(modelText) || defaultModel;
|
|
6346
|
+
agentLLM = { provider, key, model };
|
|
6347
|
+
}
|
|
6348
|
+
}
|
|
6316
6349
|
if (format !== "json") {
|
|
6317
6350
|
showFirstRunNotice();
|
|
6318
6351
|
console.log('Run "canonry serve" to start the server.');
|
|
@@ -6321,6 +6354,7 @@ Config saved to ${getConfigPath()}`);
|
|
|
6321
6354
|
providerCount: providerNames.length,
|
|
6322
6355
|
providers: providerNames
|
|
6323
6356
|
});
|
|
6357
|
+
return agentLLM;
|
|
6324
6358
|
}
|
|
6325
6359
|
|
|
6326
6360
|
// src/commands/serve.ts
|
|
@@ -6883,12 +6917,12 @@ async function wordpressSetMeta(project, body) {
|
|
|
6883
6917
|
printPageDetail(result);
|
|
6884
6918
|
}
|
|
6885
6919
|
async function wordpressBulkSetMeta(project, opts) {
|
|
6886
|
-
const
|
|
6887
|
-
const
|
|
6888
|
-
const filePath =
|
|
6920
|
+
const fs10 = await import("fs/promises");
|
|
6921
|
+
const path9 = await import("path");
|
|
6922
|
+
const filePath = path9.resolve(opts.from);
|
|
6889
6923
|
let raw;
|
|
6890
6924
|
try {
|
|
6891
|
-
raw = await
|
|
6925
|
+
raw = await fs10.readFile(filePath, "utf8");
|
|
6892
6926
|
} catch {
|
|
6893
6927
|
throw new CliError({
|
|
6894
6928
|
code: "FILE_READ_ERROR",
|
|
@@ -6985,13 +7019,13 @@ async function wordpressSetSchema(project, body) {
|
|
|
6985
7019
|
printManualAssist(`Schema update for "${body.slug}"`, result);
|
|
6986
7020
|
}
|
|
6987
7021
|
async function wordpressSchemaDeploy(project, opts) {
|
|
6988
|
-
const
|
|
6989
|
-
const
|
|
7022
|
+
const fs10 = await import("fs/promises");
|
|
7023
|
+
const path9 = await import("path");
|
|
6990
7024
|
const yaml = await import("yaml").catch(() => null);
|
|
6991
|
-
const filePath =
|
|
7025
|
+
const filePath = path9.resolve(opts.profile);
|
|
6992
7026
|
let raw;
|
|
6993
7027
|
try {
|
|
6994
|
-
raw = await
|
|
7028
|
+
raw = await fs10.readFile(filePath, "utf8");
|
|
6995
7029
|
} catch {
|
|
6996
7030
|
throw new CliError({
|
|
6997
7031
|
code: "FILE_READ_ERROR",
|
|
@@ -7096,13 +7130,13 @@ async function wordpressOnboard(project, opts) {
|
|
|
7096
7130
|
}
|
|
7097
7131
|
let profileData;
|
|
7098
7132
|
if (opts.profile) {
|
|
7099
|
-
const
|
|
7100
|
-
const
|
|
7133
|
+
const fs10 = await import("fs/promises");
|
|
7134
|
+
const path9 = await import("path");
|
|
7101
7135
|
const yaml = await import("yaml").catch(() => null);
|
|
7102
|
-
const filePath =
|
|
7136
|
+
const filePath = path9.resolve(opts.profile);
|
|
7103
7137
|
let raw;
|
|
7104
7138
|
try {
|
|
7105
|
-
raw = await
|
|
7139
|
+
raw = await fs10.readFile(filePath, "utf8");
|
|
7106
7140
|
} catch {
|
|
7107
7141
|
throw new CliError({
|
|
7108
7142
|
code: "FILE_READ_ERROR",
|
|
@@ -7683,6 +7717,699 @@ var WORDPRESS_CLI_COMMANDS = [
|
|
|
7683
7717
|
}
|
|
7684
7718
|
];
|
|
7685
7719
|
|
|
7720
|
+
// src/commands/agent.ts
|
|
7721
|
+
import path8 from "path";
|
|
7722
|
+
|
|
7723
|
+
// src/agent-manager.ts
|
|
7724
|
+
import { execFileSync, spawn as spawn2 } from "child_process";
|
|
7725
|
+
import fs8 from "fs";
|
|
7726
|
+
import path6 from "path";
|
|
7727
|
+
var log = createLogger("AgentManager");
|
|
7728
|
+
var PROCESS_MARKER = "canonry-openclaw-gateway";
|
|
7729
|
+
var AgentManager = class {
|
|
7730
|
+
constructor(config, stateDir) {
|
|
7731
|
+
this.config = config;
|
|
7732
|
+
this.stateDir = stateDir;
|
|
7733
|
+
this.processJsonPath = path6.join(stateDir, "process.json");
|
|
7734
|
+
}
|
|
7735
|
+
processJsonPath;
|
|
7736
|
+
/**
|
|
7737
|
+
* Check if the gateway process is running.
|
|
7738
|
+
* Cleans up stale process.json if the process is dead or belongs to a
|
|
7739
|
+
* different process (PID reuse).
|
|
7740
|
+
*/
|
|
7741
|
+
status() {
|
|
7742
|
+
const info = this.readProcessInfo();
|
|
7743
|
+
if (!info) {
|
|
7744
|
+
return { state: "stopped" };
|
|
7745
|
+
}
|
|
7746
|
+
if (info.marker !== PROCESS_MARKER) {
|
|
7747
|
+
this.removeProcessJson();
|
|
7748
|
+
return { state: "stopped" };
|
|
7749
|
+
}
|
|
7750
|
+
if (isProcessAlive2(info.pid) && this.verifyProcessIdentity(info.pid)) {
|
|
7751
|
+
return {
|
|
7752
|
+
state: "running",
|
|
7753
|
+
pid: info.pid,
|
|
7754
|
+
port: info.gatewayPort,
|
|
7755
|
+
startedAt: info.startedAt
|
|
7756
|
+
};
|
|
7757
|
+
}
|
|
7758
|
+
this.removeProcessJson();
|
|
7759
|
+
return { state: "stopped" };
|
|
7760
|
+
}
|
|
7761
|
+
/**
|
|
7762
|
+
* Start the OpenClaw gateway as a detached background process.
|
|
7763
|
+
* Idempotent — no-op if already running.
|
|
7764
|
+
* Waits briefly for the process to confirm it hasn't crashed on startup.
|
|
7765
|
+
*/
|
|
7766
|
+
async start() {
|
|
7767
|
+
const currentStatus = this.status();
|
|
7768
|
+
if (currentStatus.state === "running") {
|
|
7769
|
+
log.info("already.running", { pid: currentStatus.pid });
|
|
7770
|
+
return;
|
|
7771
|
+
}
|
|
7772
|
+
const binary = this.config.binary ?? "openclaw";
|
|
7773
|
+
const profile = this.config.profile ?? "aero";
|
|
7774
|
+
const port = this.config.gatewayPort ?? 3579;
|
|
7775
|
+
if (!fs8.existsSync(this.stateDir)) {
|
|
7776
|
+
fs8.mkdirSync(this.stateDir, { recursive: true });
|
|
7777
|
+
}
|
|
7778
|
+
const logFile = path6.join(this.stateDir, "gateway.log");
|
|
7779
|
+
const logFd = fs8.openSync(logFile, "a");
|
|
7780
|
+
const dotEnv = this.loadDotEnv();
|
|
7781
|
+
const child = spawn2(binary, ["--profile", profile, "gateway"], {
|
|
7782
|
+
detached: true,
|
|
7783
|
+
stdio: ["ignore", logFd, logFd],
|
|
7784
|
+
env: {
|
|
7785
|
+
...process.env,
|
|
7786
|
+
...dotEnv,
|
|
7787
|
+
OPENCLAW_PROFILE: profile,
|
|
7788
|
+
OPENCLAW_GATEWAY_PORT: String(port),
|
|
7789
|
+
OPENCLAW_STATE_DIR: this.stateDir
|
|
7790
|
+
}
|
|
7791
|
+
});
|
|
7792
|
+
const startupResult = await new Promise((resolve) => {
|
|
7793
|
+
let settled = false;
|
|
7794
|
+
const settle = (r) => {
|
|
7795
|
+
if (settled) return;
|
|
7796
|
+
settled = true;
|
|
7797
|
+
resolve(r);
|
|
7798
|
+
};
|
|
7799
|
+
child.on("error", (err) => settle({ error: err }));
|
|
7800
|
+
child.on("exit", (code) => settle({ exitCode: code }));
|
|
7801
|
+
setTimeout(() => settle({}), 500);
|
|
7802
|
+
});
|
|
7803
|
+
child.unref();
|
|
7804
|
+
fs8.closeSync(logFd);
|
|
7805
|
+
if (startupResult.error) {
|
|
7806
|
+
throw new Error(`Failed to start OpenClaw gateway: ${startupResult.error.message}`);
|
|
7807
|
+
}
|
|
7808
|
+
if (startupResult.exitCode != null) {
|
|
7809
|
+
throw new Error(`OpenClaw gateway exited immediately (code ${startupResult.exitCode}). Check ${path6.join(this.stateDir, "gateway.log")} for details.`);
|
|
7810
|
+
}
|
|
7811
|
+
if (child.pid == null) {
|
|
7812
|
+
throw new Error("Failed to start OpenClaw gateway: no PID returned by spawn");
|
|
7813
|
+
}
|
|
7814
|
+
if (!isProcessAlive2(child.pid)) {
|
|
7815
|
+
throw new Error(`OpenClaw gateway exited immediately after spawn. Check ${path6.join(this.stateDir, "gateway.log")} for details.`);
|
|
7816
|
+
}
|
|
7817
|
+
const processInfo = {
|
|
7818
|
+
pid: child.pid,
|
|
7819
|
+
gatewayPort: port,
|
|
7820
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7821
|
+
marker: PROCESS_MARKER
|
|
7822
|
+
};
|
|
7823
|
+
fs8.writeFileSync(this.processJsonPath, JSON.stringify(processInfo, null, 2), "utf-8");
|
|
7824
|
+
log.info("started", { pid: child.pid, port });
|
|
7825
|
+
}
|
|
7826
|
+
/**
|
|
7827
|
+
* Stop the gateway process.
|
|
7828
|
+
* Uses DenchClaw escalation: SIGTERM → 800ms poll → SIGKILL.
|
|
7829
|
+
* Idempotent — no-op if already stopped.
|
|
7830
|
+
*/
|
|
7831
|
+
async stop() {
|
|
7832
|
+
const info = this.readProcessInfo();
|
|
7833
|
+
if (!info) return;
|
|
7834
|
+
if (isProcessAlive2(info.pid) && info.marker === PROCESS_MARKER && this.verifyProcessIdentity(info.pid)) {
|
|
7835
|
+
await terminateWithEscalation(info.pid);
|
|
7836
|
+
}
|
|
7837
|
+
this.removeProcessJson();
|
|
7838
|
+
log.info("stopped", { pid: info.pid });
|
|
7839
|
+
}
|
|
7840
|
+
/**
|
|
7841
|
+
* Stop the gateway, wipe the workspace directory, and prepare for re-seeding.
|
|
7842
|
+
*/
|
|
7843
|
+
async reset() {
|
|
7844
|
+
await this.stop();
|
|
7845
|
+
const workspaceDir = path6.join(this.stateDir, "workspace");
|
|
7846
|
+
if (fs8.existsSync(workspaceDir)) {
|
|
7847
|
+
fs8.rmSync(workspaceDir, { recursive: true, force: true });
|
|
7848
|
+
log.info("workspace.wiped", { dir: workspaceDir });
|
|
7849
|
+
}
|
|
7850
|
+
}
|
|
7851
|
+
/**
|
|
7852
|
+
* Verify that the PID actually belongs to an openclaw process by checking
|
|
7853
|
+
* the full command line. Requires "openclaw" in the args to avoid matching
|
|
7854
|
+
* unrelated Node processes after PID reuse.
|
|
7855
|
+
*/
|
|
7856
|
+
verifyProcessIdentity(pid) {
|
|
7857
|
+
try {
|
|
7858
|
+
if (process.platform === "darwin") {
|
|
7859
|
+
const out = execFileSync("ps", ["-p", String(pid), "-o", "args="], {
|
|
7860
|
+
encoding: "utf-8",
|
|
7861
|
+
timeout: 2e3
|
|
7862
|
+
}).trim();
|
|
7863
|
+
return out.includes("openclaw");
|
|
7864
|
+
}
|
|
7865
|
+
if (process.platform === "linux") {
|
|
7866
|
+
const cmdline = fs8.readFileSync(`/proc/${pid}/cmdline`, "utf-8");
|
|
7867
|
+
return cmdline.includes("openclaw");
|
|
7868
|
+
}
|
|
7869
|
+
return true;
|
|
7870
|
+
} catch {
|
|
7871
|
+
return false;
|
|
7872
|
+
}
|
|
7873
|
+
}
|
|
7874
|
+
readProcessInfo() {
|
|
7875
|
+
if (!fs8.existsSync(this.processJsonPath)) return null;
|
|
7876
|
+
try {
|
|
7877
|
+
return JSON.parse(fs8.readFileSync(this.processJsonPath, "utf-8"));
|
|
7878
|
+
} catch {
|
|
7879
|
+
return null;
|
|
7880
|
+
}
|
|
7881
|
+
}
|
|
7882
|
+
removeProcessJson() {
|
|
7883
|
+
try {
|
|
7884
|
+
fs8.unlinkSync(this.processJsonPath);
|
|
7885
|
+
} catch {
|
|
7886
|
+
}
|
|
7887
|
+
}
|
|
7888
|
+
/** Parse a simple KEY=value dotenv file from the state dir. */
|
|
7889
|
+
loadDotEnv() {
|
|
7890
|
+
const envFile = path6.join(this.stateDir, ".env");
|
|
7891
|
+
if (!fs8.existsSync(envFile)) return {};
|
|
7892
|
+
const result = {};
|
|
7893
|
+
for (const line of fs8.readFileSync(envFile, "utf-8").split("\n")) {
|
|
7894
|
+
const trimmed = line.trim();
|
|
7895
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
7896
|
+
const eq3 = trimmed.indexOf("=");
|
|
7897
|
+
if (eq3 < 1) continue;
|
|
7898
|
+
result[trimmed.slice(0, eq3)] = trimmed.slice(eq3 + 1);
|
|
7899
|
+
}
|
|
7900
|
+
return result;
|
|
7901
|
+
}
|
|
7902
|
+
};
|
|
7903
|
+
function isProcessAlive2(pid) {
|
|
7904
|
+
try {
|
|
7905
|
+
process.kill(pid, 0);
|
|
7906
|
+
return true;
|
|
7907
|
+
} catch {
|
|
7908
|
+
return false;
|
|
7909
|
+
}
|
|
7910
|
+
}
|
|
7911
|
+
async function terminateWithEscalation(pid) {
|
|
7912
|
+
try {
|
|
7913
|
+
process.kill(pid, "SIGTERM");
|
|
7914
|
+
} catch {
|
|
7915
|
+
return;
|
|
7916
|
+
}
|
|
7917
|
+
const deadline = Date.now() + 800;
|
|
7918
|
+
while (Date.now() < deadline) {
|
|
7919
|
+
if (!isProcessAlive2(pid)) return;
|
|
7920
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
7921
|
+
}
|
|
7922
|
+
try {
|
|
7923
|
+
process.kill(pid, "SIGKILL");
|
|
7924
|
+
} catch {
|
|
7925
|
+
}
|
|
7926
|
+
}
|
|
7927
|
+
|
|
7928
|
+
// src/agent-bootstrap.ts
|
|
7929
|
+
import { execFileSync as execFileSync2, execSync } from "child_process";
|
|
7930
|
+
import fs9 from "fs";
|
|
7931
|
+
import os from "os";
|
|
7932
|
+
import path7 from "path";
|
|
7933
|
+
import { fileURLToPath } from "url";
|
|
7934
|
+
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
7935
|
+
var cachedResult = null;
|
|
7936
|
+
var cachedAt = 0;
|
|
7937
|
+
function getAeroStateDir(profile = "aero") {
|
|
7938
|
+
return path7.join(os.homedir(), `.openclaw-${profile}`);
|
|
7939
|
+
}
|
|
7940
|
+
async function detectOpenClaw(config) {
|
|
7941
|
+
if (cachedResult && Date.now() - cachedAt < CACHE_TTL_MS) {
|
|
7942
|
+
return cachedResult;
|
|
7943
|
+
}
|
|
7944
|
+
let result;
|
|
7945
|
+
if (config?.binary) {
|
|
7946
|
+
const version = probeVersion(config.binary);
|
|
7947
|
+
if (version) {
|
|
7948
|
+
result = { found: true, path: config.binary, version };
|
|
7949
|
+
cachedResult = result;
|
|
7950
|
+
cachedAt = Date.now();
|
|
7951
|
+
return result;
|
|
7952
|
+
}
|
|
7953
|
+
}
|
|
7954
|
+
const binaryPath = findInPath();
|
|
7955
|
+
if (binaryPath) {
|
|
7956
|
+
const version = probeVersion(binaryPath);
|
|
7957
|
+
if (version) {
|
|
7958
|
+
result = { found: true, path: binaryPath, version };
|
|
7959
|
+
cachedResult = result;
|
|
7960
|
+
cachedAt = Date.now();
|
|
7961
|
+
return result;
|
|
7962
|
+
}
|
|
7963
|
+
}
|
|
7964
|
+
result = { found: false };
|
|
7965
|
+
cachedResult = result;
|
|
7966
|
+
cachedAt = Date.now();
|
|
7967
|
+
return result;
|
|
7968
|
+
}
|
|
7969
|
+
detectOpenClaw.resetCache = () => {
|
|
7970
|
+
cachedResult = null;
|
|
7971
|
+
cachedAt = 0;
|
|
7972
|
+
};
|
|
7973
|
+
function probeVersion(binaryPath) {
|
|
7974
|
+
try {
|
|
7975
|
+
const output = execFileSync2(binaryPath, ["--version"], {
|
|
7976
|
+
timeout: 5e3,
|
|
7977
|
+
encoding: "utf-8"
|
|
7978
|
+
});
|
|
7979
|
+
const match = output.toString().trim().match(/(\d+\.\d+\.\d+)/);
|
|
7980
|
+
return match ? match[1] : output.toString().trim();
|
|
7981
|
+
} catch {
|
|
7982
|
+
return null;
|
|
7983
|
+
}
|
|
7984
|
+
}
|
|
7985
|
+
function findInPath() {
|
|
7986
|
+
const cmd = process.platform === "win32" ? "where" : "which";
|
|
7987
|
+
try {
|
|
7988
|
+
const output = execFileSync2(cmd, ["openclaw"], {
|
|
7989
|
+
timeout: 5e3,
|
|
7990
|
+
encoding: "utf-8"
|
|
7991
|
+
});
|
|
7992
|
+
return output.toString().trim().split("\n")[0] || null;
|
|
7993
|
+
} catch {
|
|
7994
|
+
return null;
|
|
7995
|
+
}
|
|
7996
|
+
}
|
|
7997
|
+
async function installOpenClaw(opts) {
|
|
7998
|
+
try {
|
|
7999
|
+
execSync("npm install -g openclaw", {
|
|
8000
|
+
timeout: 12e4,
|
|
8001
|
+
stdio: opts?.silent ? "pipe" : "inherit"
|
|
8002
|
+
});
|
|
8003
|
+
} catch (err) {
|
|
8004
|
+
return {
|
|
8005
|
+
success: false,
|
|
8006
|
+
error: err instanceof Error ? err.message : String(err)
|
|
8007
|
+
};
|
|
8008
|
+
}
|
|
8009
|
+
detectOpenClaw.resetCache();
|
|
8010
|
+
const detection = await detectOpenClaw();
|
|
8011
|
+
if (!detection.found) {
|
|
8012
|
+
return {
|
|
8013
|
+
success: false,
|
|
8014
|
+
error: "npm install succeeded but openclaw binary was not found in PATH"
|
|
8015
|
+
};
|
|
8016
|
+
}
|
|
8017
|
+
return { success: true, detection };
|
|
8018
|
+
}
|
|
8019
|
+
function seedWorkspace(stateDir) {
|
|
8020
|
+
const workspaceDir = path7.join(stateDir, "workspace");
|
|
8021
|
+
fs9.mkdirSync(workspaceDir, { recursive: true });
|
|
8022
|
+
const __dirname = path7.dirname(fileURLToPath(import.meta.url));
|
|
8023
|
+
const assetsDir = path7.join(__dirname, "..", "assets", "agent-workspace");
|
|
8024
|
+
if (!fs9.existsSync(assetsDir)) {
|
|
8025
|
+
return;
|
|
8026
|
+
}
|
|
8027
|
+
copyDirRecursive(assetsDir, workspaceDir);
|
|
8028
|
+
}
|
|
8029
|
+
function initializeOpenClawProfile(binary, profile, workspaceDir) {
|
|
8030
|
+
try {
|
|
8031
|
+
execFileSync2(binary, [
|
|
8032
|
+
"--profile",
|
|
8033
|
+
profile,
|
|
8034
|
+
"onboard",
|
|
8035
|
+
"--non-interactive",
|
|
8036
|
+
"--accept-risk",
|
|
8037
|
+
"--mode",
|
|
8038
|
+
"local",
|
|
8039
|
+
"--workspace",
|
|
8040
|
+
workspaceDir,
|
|
8041
|
+
"--skip-channels",
|
|
8042
|
+
"--skip-skills",
|
|
8043
|
+
"--skip-health",
|
|
8044
|
+
"--no-install-daemon"
|
|
8045
|
+
], { timeout: 3e4, stdio: "pipe" });
|
|
8046
|
+
} catch (err) {
|
|
8047
|
+
const stderr = err instanceof Error && "stderr" in err ? String(err.stderr) : "";
|
|
8048
|
+
if (stderr.toLowerCase().includes("already")) return;
|
|
8049
|
+
throw new CliError({
|
|
8050
|
+
code: "AGENT_PROFILE_INIT_FAILED",
|
|
8051
|
+
message: `Failed to initialize OpenClaw profile: ${stderr || (err instanceof Error ? err.message : String(err))}`,
|
|
8052
|
+
displayMessage: `Failed to initialize OpenClaw profile "${profile}".`
|
|
8053
|
+
});
|
|
8054
|
+
}
|
|
8055
|
+
}
|
|
8056
|
+
function configureOpenClawGateway(binary, profile, gatewayPort) {
|
|
8057
|
+
const entries = [
|
|
8058
|
+
["gateway.mode", "local", false],
|
|
8059
|
+
["gateway.port", String(gatewayPort), true]
|
|
8060
|
+
];
|
|
8061
|
+
for (const [key, value, strict] of entries) {
|
|
8062
|
+
try {
|
|
8063
|
+
const args = ["--profile", profile, "config", "set", key, value];
|
|
8064
|
+
if (strict) args.push("--strict-json");
|
|
8065
|
+
execFileSync2(binary, args, { timeout: 1e4, stdio: "pipe" });
|
|
8066
|
+
} catch (err) {
|
|
8067
|
+
throw new CliError({
|
|
8068
|
+
code: "AGENT_GATEWAY_CONFIG_FAILED",
|
|
8069
|
+
message: `Failed to set ${key}=${value}: ${err instanceof Error ? err.message : String(err)}`,
|
|
8070
|
+
displayMessage: `Failed to configure OpenClaw gateway (${key}).`
|
|
8071
|
+
});
|
|
8072
|
+
}
|
|
8073
|
+
}
|
|
8074
|
+
}
|
|
8075
|
+
function setOpenClawModel(binary, profile, model) {
|
|
8076
|
+
try {
|
|
8077
|
+
execFileSync2(binary, [
|
|
8078
|
+
"--profile",
|
|
8079
|
+
profile,
|
|
8080
|
+
"models",
|
|
8081
|
+
"set",
|
|
8082
|
+
model
|
|
8083
|
+
], { timeout: 1e4, stdio: "pipe" });
|
|
8084
|
+
} catch (err) {
|
|
8085
|
+
throw new CliError({
|
|
8086
|
+
code: "AGENT_MODEL_SET_FAILED",
|
|
8087
|
+
message: `Failed to set agent model to ${model}: ${err instanceof Error ? err.message : String(err)}`,
|
|
8088
|
+
displayMessage: `Failed to set agent model to "${model}".`
|
|
8089
|
+
});
|
|
8090
|
+
}
|
|
8091
|
+
}
|
|
8092
|
+
function providerEnvVar(provider) {
|
|
8093
|
+
const map = {
|
|
8094
|
+
anthropic: "ANTHROPIC_API_KEY",
|
|
8095
|
+
openai: "OPENAI_API_KEY",
|
|
8096
|
+
google: "GOOGLE_API_KEY",
|
|
8097
|
+
"google-vertex": "GOOGLE_API_KEY",
|
|
8098
|
+
groq: "GROQ_API_KEY",
|
|
8099
|
+
mistral: "MISTRAL_API_KEY",
|
|
8100
|
+
xai: "XAI_API_KEY",
|
|
8101
|
+
openrouter: "OPENROUTER_API_KEY",
|
|
8102
|
+
cerebras: "CEREBRAS_API_KEY"
|
|
8103
|
+
};
|
|
8104
|
+
return map[provider] ?? `${provider.toUpperCase().replace(/-/g, "_")}_API_KEY`;
|
|
8105
|
+
}
|
|
8106
|
+
function writeAgentEnv(stateDir, key, value) {
|
|
8107
|
+
const envFile = path7.join(stateDir, ".env");
|
|
8108
|
+
let lines = [];
|
|
8109
|
+
if (fs9.existsSync(envFile)) {
|
|
8110
|
+
lines = fs9.readFileSync(envFile, "utf-8").split("\n");
|
|
8111
|
+
}
|
|
8112
|
+
const prefix = `${key}=`;
|
|
8113
|
+
const idx = lines.findIndex((l) => l.startsWith(prefix));
|
|
8114
|
+
const entry = `${key}=${value}`;
|
|
8115
|
+
if (idx >= 0) {
|
|
8116
|
+
lines[idx] = entry;
|
|
8117
|
+
} else {
|
|
8118
|
+
lines.push(entry);
|
|
8119
|
+
}
|
|
8120
|
+
while (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
|
|
8121
|
+
fs9.writeFileSync(envFile, lines.join("\n") + "\n", "utf-8");
|
|
8122
|
+
}
|
|
8123
|
+
function resolveAgentCredentials(opts) {
|
|
8124
|
+
const provider = opts.agentProvider ?? "anthropic";
|
|
8125
|
+
if (opts.agentKey) {
|
|
8126
|
+
return { provider, key: opts.agentKey, model: opts.agentModel };
|
|
8127
|
+
}
|
|
8128
|
+
const envVar = providerEnvVar(provider);
|
|
8129
|
+
const envKey = process.env[envVar];
|
|
8130
|
+
if (envKey) {
|
|
8131
|
+
return { provider, key: envKey, model: opts.agentModel };
|
|
8132
|
+
}
|
|
8133
|
+
const genericKey = process.env.CANONRY_AGENT_KEY;
|
|
8134
|
+
if (genericKey) {
|
|
8135
|
+
return { provider, key: genericKey, model: opts.agentModel };
|
|
8136
|
+
}
|
|
8137
|
+
const envFile = path7.join(opts.stateDir, ".env");
|
|
8138
|
+
if (fs9.existsSync(envFile)) {
|
|
8139
|
+
const hasKey = fs9.readFileSync(envFile, "utf-8").split("\n").some((l) => l.includes("_API_KEY="));
|
|
8140
|
+
if (hasKey) {
|
|
8141
|
+
return { provider, key: void 0, model: opts.agentModel };
|
|
8142
|
+
}
|
|
8143
|
+
}
|
|
8144
|
+
return { provider, key: void 0, model: opts.agentModel };
|
|
8145
|
+
}
|
|
8146
|
+
function copyDirRecursive(src, dest) {
|
|
8147
|
+
fs9.mkdirSync(dest, { recursive: true });
|
|
8148
|
+
for (const entry of fs9.readdirSync(src, { withFileTypes: true })) {
|
|
8149
|
+
const srcPath = path7.join(src, entry.name);
|
|
8150
|
+
const destPath = path7.join(dest, entry.name);
|
|
8151
|
+
if (entry.isDirectory()) {
|
|
8152
|
+
copyDirRecursive(srcPath, destPath);
|
|
8153
|
+
} else {
|
|
8154
|
+
fs9.copyFileSync(srcPath, destPath);
|
|
8155
|
+
}
|
|
8156
|
+
}
|
|
8157
|
+
}
|
|
8158
|
+
|
|
8159
|
+
// src/commands/agent.ts
|
|
8160
|
+
function resolveStateDir(opts) {
|
|
8161
|
+
if (opts?.stateDir) return opts.stateDir;
|
|
8162
|
+
try {
|
|
8163
|
+
const config = loadConfig();
|
|
8164
|
+
const profile = config.agent?.profile ?? "aero";
|
|
8165
|
+
return getAeroStateDir(profile);
|
|
8166
|
+
} catch {
|
|
8167
|
+
return getAeroStateDir();
|
|
8168
|
+
}
|
|
8169
|
+
}
|
|
8170
|
+
function resolveConfig() {
|
|
8171
|
+
try {
|
|
8172
|
+
return loadConfig().agent ?? {};
|
|
8173
|
+
} catch {
|
|
8174
|
+
return {};
|
|
8175
|
+
}
|
|
8176
|
+
}
|
|
8177
|
+
async function agentStatus(opts) {
|
|
8178
|
+
const stateDir = resolveStateDir(opts);
|
|
8179
|
+
const config = resolveConfig();
|
|
8180
|
+
const mgr = new AgentManager(config, stateDir);
|
|
8181
|
+
const status = mgr.status();
|
|
8182
|
+
if (opts?.format === "json") {
|
|
8183
|
+
console.log(JSON.stringify(status, null, 2));
|
|
8184
|
+
return;
|
|
8185
|
+
}
|
|
8186
|
+
if (status.state === "running") {
|
|
8187
|
+
console.log(`Agent: running (PID ${status.pid}, port ${status.port})`);
|
|
8188
|
+
if (status.startedAt) {
|
|
8189
|
+
console.log(`Started: ${status.startedAt}`);
|
|
8190
|
+
}
|
|
8191
|
+
} else {
|
|
8192
|
+
console.log("Agent: stopped");
|
|
8193
|
+
}
|
|
8194
|
+
}
|
|
8195
|
+
async function agentStart(opts) {
|
|
8196
|
+
const stateDir = resolveStateDir(opts);
|
|
8197
|
+
const config = resolveConfig();
|
|
8198
|
+
const mgr = new AgentManager(config, stateDir);
|
|
8199
|
+
await mgr.start();
|
|
8200
|
+
const status = mgr.status();
|
|
8201
|
+
if (opts?.format === "json") {
|
|
8202
|
+
console.log(JSON.stringify(status, null, 2));
|
|
8203
|
+
} else {
|
|
8204
|
+
console.log(`Agent started (PID ${status.pid}, port ${status.port})`);
|
|
8205
|
+
}
|
|
8206
|
+
}
|
|
8207
|
+
async function agentStop(opts) {
|
|
8208
|
+
const stateDir = resolveStateDir(opts);
|
|
8209
|
+
const config = resolveConfig();
|
|
8210
|
+
const mgr = new AgentManager(config, stateDir);
|
|
8211
|
+
await mgr.stop();
|
|
8212
|
+
if (opts?.format === "json") {
|
|
8213
|
+
console.log(JSON.stringify({ state: "stopped" }, null, 2));
|
|
8214
|
+
} else {
|
|
8215
|
+
console.log("Agent stopped");
|
|
8216
|
+
}
|
|
8217
|
+
}
|
|
8218
|
+
async function agentReset(opts) {
|
|
8219
|
+
const stateDir = resolveStateDir(opts);
|
|
8220
|
+
const config = resolveConfig();
|
|
8221
|
+
const mgr = new AgentManager(config, stateDir);
|
|
8222
|
+
await mgr.reset();
|
|
8223
|
+
if (opts?.format === "json") {
|
|
8224
|
+
console.log(JSON.stringify({ state: "reset" }, null, 2));
|
|
8225
|
+
} else {
|
|
8226
|
+
console.log('Agent reset \u2014 workspace wiped. Run "canonry agent setup" to re-initialize.');
|
|
8227
|
+
}
|
|
8228
|
+
}
|
|
8229
|
+
async function agentSetup(opts) {
|
|
8230
|
+
const isJson = opts?.format === "json";
|
|
8231
|
+
let agentLLM;
|
|
8232
|
+
if (!configExists()) {
|
|
8233
|
+
const initOpts = {
|
|
8234
|
+
geminiKey: opts?.geminiKey,
|
|
8235
|
+
openaiKey: opts?.openaiKey,
|
|
8236
|
+
claudeKey: opts?.claudeKey,
|
|
8237
|
+
perplexityKey: opts?.perplexityKey,
|
|
8238
|
+
localUrl: opts?.localUrl,
|
|
8239
|
+
localModel: opts?.localModel,
|
|
8240
|
+
localKey: opts?.localKey,
|
|
8241
|
+
googleClientId: opts?.googleClientId,
|
|
8242
|
+
googleClientSecret: opts?.googleClientSecret,
|
|
8243
|
+
agentProvider: opts?.agentProvider,
|
|
8244
|
+
agentKey: opts?.agentKey,
|
|
8245
|
+
agentModel: opts?.agentModel
|
|
8246
|
+
};
|
|
8247
|
+
if (isJson) {
|
|
8248
|
+
agentLLM = await suppressStdout(() => initCommand(initOpts)) ?? void 0;
|
|
8249
|
+
} else {
|
|
8250
|
+
agentLLM = await initCommand(initOpts) ?? void 0;
|
|
8251
|
+
}
|
|
8252
|
+
}
|
|
8253
|
+
const existingConfig = resolveConfig();
|
|
8254
|
+
let detection = await detectOpenClaw(existingConfig);
|
|
8255
|
+
if (!detection.found) {
|
|
8256
|
+
detection = await autoInstallOrFail(opts?.format);
|
|
8257
|
+
}
|
|
8258
|
+
const profile = existingConfig.profile ?? "aero";
|
|
8259
|
+
const gatewayPort = opts?.gatewayPort ?? existingConfig.gatewayPort ?? 3579;
|
|
8260
|
+
const stateDir = opts?.stateDir ?? getAeroStateDir(profile);
|
|
8261
|
+
saveConfigPatch({
|
|
8262
|
+
agent: {
|
|
8263
|
+
binary: detection.path,
|
|
8264
|
+
profile,
|
|
8265
|
+
gatewayPort,
|
|
8266
|
+
autoStart: existingConfig.autoStart
|
|
8267
|
+
}
|
|
8268
|
+
});
|
|
8269
|
+
initializeOpenClawProfile(detection.path, profile, path8.join(stateDir, "workspace"));
|
|
8270
|
+
configureOpenClawGateway(detection.path, profile, gatewayPort);
|
|
8271
|
+
const creds = agentLLM ?? resolveAgentCredentials({
|
|
8272
|
+
agentProvider: opts?.agentProvider,
|
|
8273
|
+
agentKey: opts?.agentKey,
|
|
8274
|
+
agentModel: opts?.agentModel,
|
|
8275
|
+
stateDir
|
|
8276
|
+
});
|
|
8277
|
+
if (creds.key) {
|
|
8278
|
+
writeAgentEnv(stateDir, providerEnvVar(creds.provider), creds.key);
|
|
8279
|
+
if (opts?.format !== "json") {
|
|
8280
|
+
console.log(`Agent LLM: ${creds.provider} credentials configured`);
|
|
8281
|
+
}
|
|
8282
|
+
}
|
|
8283
|
+
if (creds.model) {
|
|
8284
|
+
setOpenClawModel(detection.path, profile, creds.model);
|
|
8285
|
+
if (opts?.format !== "json") {
|
|
8286
|
+
console.log(`Agent model: ${creds.model}`);
|
|
8287
|
+
}
|
|
8288
|
+
}
|
|
8289
|
+
seedWorkspace(stateDir);
|
|
8290
|
+
if (opts?.format === "json") {
|
|
8291
|
+
console.log(JSON.stringify({
|
|
8292
|
+
state: "configured",
|
|
8293
|
+
binary: detection.path,
|
|
8294
|
+
version: detection.version,
|
|
8295
|
+
profile,
|
|
8296
|
+
gatewayPort,
|
|
8297
|
+
stateDir
|
|
8298
|
+
}, null, 2));
|
|
8299
|
+
} else {
|
|
8300
|
+
console.log(`OpenClaw: ${detection.path} (${detection.version})`);
|
|
8301
|
+
console.log(`Profile: ${profile}`);
|
|
8302
|
+
console.log(`Gateway port: ${gatewayPort}`);
|
|
8303
|
+
console.log(`State dir: ${stateDir}`);
|
|
8304
|
+
console.log("Agent setup complete.");
|
|
8305
|
+
}
|
|
8306
|
+
}
|
|
8307
|
+
async function autoInstallOrFail(format) {
|
|
8308
|
+
if (format !== "json") {
|
|
8309
|
+
console.log("OpenClaw not found, installing via npm...");
|
|
8310
|
+
}
|
|
8311
|
+
const install = await installOpenClaw({ silent: format === "json" });
|
|
8312
|
+
if (!install.success) {
|
|
8313
|
+
const msg = `Failed to install OpenClaw: ${install.error}`;
|
|
8314
|
+
if (format === "json") {
|
|
8315
|
+
console.error(JSON.stringify({ error: { code: "AGENT_INSTALL_FAILED", message: msg } }));
|
|
8316
|
+
} else {
|
|
8317
|
+
console.error(msg);
|
|
8318
|
+
}
|
|
8319
|
+
process.exitCode = 1;
|
|
8320
|
+
throw new Error(msg);
|
|
8321
|
+
}
|
|
8322
|
+
if (format !== "json") {
|
|
8323
|
+
console.log(`Installed OpenClaw ${install.detection.version}`);
|
|
8324
|
+
}
|
|
8325
|
+
return install.detection;
|
|
8326
|
+
}
|
|
8327
|
+
async function suppressStdout(fn) {
|
|
8328
|
+
const original = console.log;
|
|
8329
|
+
console.log = () => {
|
|
8330
|
+
};
|
|
8331
|
+
try {
|
|
8332
|
+
return await fn();
|
|
8333
|
+
} finally {
|
|
8334
|
+
console.log = original;
|
|
8335
|
+
}
|
|
8336
|
+
}
|
|
8337
|
+
|
|
8338
|
+
// src/cli-commands/agent.ts
|
|
8339
|
+
var AGENT_CLI_COMMANDS = [
|
|
8340
|
+
{
|
|
8341
|
+
path: ["agent", "status"],
|
|
8342
|
+
usage: "canonry agent status [--format json]",
|
|
8343
|
+
options: {},
|
|
8344
|
+
run: async (input) => {
|
|
8345
|
+
await agentStatus({ format: input.format });
|
|
8346
|
+
}
|
|
8347
|
+
},
|
|
8348
|
+
{
|
|
8349
|
+
path: ["agent", "start"],
|
|
8350
|
+
usage: "canonry agent start [--format json]",
|
|
8351
|
+
options: {},
|
|
8352
|
+
run: async (input) => {
|
|
8353
|
+
await agentStart({ format: input.format });
|
|
8354
|
+
}
|
|
8355
|
+
},
|
|
8356
|
+
{
|
|
8357
|
+
path: ["agent", "stop"],
|
|
8358
|
+
usage: "canonry agent stop [--format json]",
|
|
8359
|
+
options: {},
|
|
8360
|
+
run: async (input) => {
|
|
8361
|
+
await agentStop({ format: input.format });
|
|
8362
|
+
}
|
|
8363
|
+
},
|
|
8364
|
+
{
|
|
8365
|
+
path: ["agent", "reset"],
|
|
8366
|
+
usage: "canonry agent reset [--format json]",
|
|
8367
|
+
options: {},
|
|
8368
|
+
run: async (input) => {
|
|
8369
|
+
await agentReset({ format: input.format });
|
|
8370
|
+
}
|
|
8371
|
+
},
|
|
8372
|
+
{
|
|
8373
|
+
path: ["agent", "setup"],
|
|
8374
|
+
usage: "canonry agent setup [--agent-provider <id>] [--agent-key <key>] [--agent-model <model>] [--gateway-port <port>] [--gemini-key <key>] [--openai-key <key>] [--claude-key <key>] [--perplexity-key <key>] [--format json]",
|
|
8375
|
+
options: {
|
|
8376
|
+
"agent-provider": stringOption(),
|
|
8377
|
+
"agent-key": stringOption(),
|
|
8378
|
+
"agent-model": stringOption(),
|
|
8379
|
+
"gateway-port": { type: "string" },
|
|
8380
|
+
"gemini-key": stringOption(),
|
|
8381
|
+
"openai-key": stringOption(),
|
|
8382
|
+
"claude-key": stringOption(),
|
|
8383
|
+
"perplexity-key": stringOption(),
|
|
8384
|
+
"local-url": stringOption(),
|
|
8385
|
+
"local-model": stringOption(),
|
|
8386
|
+
"local-key": stringOption(),
|
|
8387
|
+
"google-client-id": stringOption(),
|
|
8388
|
+
"google-client-secret": stringOption()
|
|
8389
|
+
},
|
|
8390
|
+
run: async (input) => {
|
|
8391
|
+
const portStr = input.values["gateway-port"];
|
|
8392
|
+
const gatewayPort = typeof portStr === "string" ? Number.parseInt(portStr, 10) : void 0;
|
|
8393
|
+
await agentSetup({
|
|
8394
|
+
agentProvider: getString(input.values, "agent-provider"),
|
|
8395
|
+
agentKey: getString(input.values, "agent-key"),
|
|
8396
|
+
agentModel: getString(input.values, "agent-model"),
|
|
8397
|
+
gatewayPort,
|
|
8398
|
+
format: input.format,
|
|
8399
|
+
geminiKey: getString(input.values, "gemini-key"),
|
|
8400
|
+
openaiKey: getString(input.values, "openai-key"),
|
|
8401
|
+
claudeKey: getString(input.values, "claude-key"),
|
|
8402
|
+
perplexityKey: getString(input.values, "perplexity-key"),
|
|
8403
|
+
localUrl: getString(input.values, "local-url"),
|
|
8404
|
+
localModel: getString(input.values, "local-model"),
|
|
8405
|
+
localKey: getString(input.values, "local-key"),
|
|
8406
|
+
googleClientId: getString(input.values, "google-client-id"),
|
|
8407
|
+
googleClientSecret: getString(input.values, "google-client-secret")
|
|
8408
|
+
});
|
|
8409
|
+
}
|
|
8410
|
+
}
|
|
8411
|
+
];
|
|
8412
|
+
|
|
7686
8413
|
// src/cli-commands.ts
|
|
7687
8414
|
var REGISTERED_CLI_COMMANDS = [
|
|
7688
8415
|
...BACKFILL_CLI_COMMANDS,
|
|
@@ -7701,7 +8428,8 @@ var REGISTERED_CLI_COMMANDS = [
|
|
|
7701
8428
|
...WORDPRESS_CLI_COMMANDS,
|
|
7702
8429
|
...CDP_CLI_COMMANDS,
|
|
7703
8430
|
...GA_CLI_COMMANDS,
|
|
7704
|
-
...INTELLIGENCE_CLI_COMMANDS
|
|
8431
|
+
...INTELLIGENCE_CLI_COMMANDS,
|
|
8432
|
+
...AGENT_CLI_COMMANDS
|
|
7705
8433
|
];
|
|
7706
8434
|
|
|
7707
8435
|
// src/cli.ts
|