Add CLI setup and QQ webhook integration
This commit is contained in:
+145
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env node
|
||||
import process from "node:process";
|
||||
import { discoverAgents } from "./agents/discovery.js";
|
||||
import { loadConfigFile } from "./cli/config-file.js";
|
||||
import { runDoctor } from "./cli/doctor.js";
|
||||
import { printFeishu } from "./cli/print.js";
|
||||
import { runSetup } from "./cli/setup.js";
|
||||
import { localBaseUrl } from "./cli/net.js";
|
||||
import { startServer } from "./server.js";
|
||||
|
||||
interface ParsedArgs {
|
||||
command?: string;
|
||||
rest: string[];
|
||||
configPath?: string;
|
||||
json: boolean;
|
||||
help: boolean;
|
||||
}
|
||||
|
||||
async function main(argv: string[]): Promise<number> {
|
||||
const parsed = parseArgs(argv);
|
||||
if (parsed.help || !parsed.command) {
|
||||
printHelp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (parsed.command === "setup") {
|
||||
await runSetup(parsed.configPath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (parsed.command === "discover-agents") {
|
||||
const agents = await discoverAgents();
|
||||
if (parsed.json) {
|
||||
console.log(JSON.stringify(agents, null, 2));
|
||||
} else {
|
||||
for (const agent of agents) {
|
||||
const version = agent.version ? ` (${agent.version})` : "";
|
||||
const reason = agent.reason ? ` - ${agent.reason}` : "";
|
||||
console.log(`${agent.name}\t${agent.status}\t${agent.command} ${agent.args.join(" ")}${version}${reason}`.trim());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (parsed.command === "start") {
|
||||
const loaded = loadConfigFile(parsed.configPath);
|
||||
startServer(loaded.config);
|
||||
return await new Promise(() => undefined);
|
||||
}
|
||||
|
||||
if (parsed.command === "status") {
|
||||
await printStatus(parsed.configPath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (parsed.command === "doctor") {
|
||||
const loaded = loadConfigFile(parsed.configPath);
|
||||
return runDoctor(loaded.config, loaded.path);
|
||||
}
|
||||
|
||||
if (parsed.command === "print") {
|
||||
const topic = parsed.rest[0];
|
||||
const loaded = loadConfigFile(parsed.configPath);
|
||||
if (topic === "feishu") {
|
||||
await printFeishu(loaded.config);
|
||||
return 0;
|
||||
}
|
||||
console.error(`Unknown print topic: ${topic || "(missing)"}`);
|
||||
console.error("Available: feishu");
|
||||
return 1;
|
||||
}
|
||||
|
||||
console.error(`Unknown command: ${parsed.command}`);
|
||||
printHelp();
|
||||
return 1;
|
||||
}
|
||||
|
||||
function parseArgs(argv: string[]): ParsedArgs {
|
||||
const rest: string[] = [];
|
||||
let command: string | undefined;
|
||||
let configPath: string | undefined;
|
||||
let json = false;
|
||||
let help = false;
|
||||
|
||||
for (let index = 0; index < argv.length; index++) {
|
||||
const arg = argv[index];
|
||||
if (arg === "--help" || arg === "-h") {
|
||||
help = true;
|
||||
} else if (arg === "--json") {
|
||||
json = true;
|
||||
} else if (arg === "--config") {
|
||||
configPath = argv[++index];
|
||||
if (!configPath) throw new Error("--config requires a path");
|
||||
} else if (!command) {
|
||||
command = arg;
|
||||
} else {
|
||||
rest.push(arg);
|
||||
}
|
||||
}
|
||||
|
||||
return { command, rest, configPath, json, help };
|
||||
}
|
||||
|
||||
async function printStatus(configPath?: string): Promise<void> {
|
||||
const loaded = loadConfigFile(configPath);
|
||||
const baseUrl = localBaseUrl(loaded.config);
|
||||
console.log(`Config: ${loaded.path}${loaded.exists ? "" : " (seeded from config.example.json)"}`);
|
||||
console.log(`Server: ${loaded.config.server.host}:${loaded.config.server.port}`);
|
||||
console.log(`Default agent: ${loaded.config.defaultAgent}`);
|
||||
console.log(`Agents: ${loaded.config.agents.map((agent) => agent.name).join(", ")}`);
|
||||
console.log(`Enabled platforms: ${Object.entries(loaded.config.platforms).filter(([, value]) => value.enabled).map(([name]) => name).join(", ") || "none"}`);
|
||||
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timer = setTimeout(() => controller.abort(), 1_000);
|
||||
const response = await fetch(`${baseUrl}/health`, { signal: controller.signal });
|
||||
clearTimeout(timer);
|
||||
console.log(`Health probe: HTTP ${response.status}`);
|
||||
} catch {
|
||||
console.log("Health probe: not reachable on local URL");
|
||||
}
|
||||
}
|
||||
|
||||
function printHelp(): void {
|
||||
console.log(`gori-agent - local CLI-agent gateway setup and operations
|
||||
|
||||
Usage:
|
||||
gori-agent setup [--config path]
|
||||
gori-agent discover-agents [--json]
|
||||
gori-agent start [--config path]
|
||||
gori-agent status [--config path]
|
||||
gori-agent doctor [--config path]
|
||||
gori-agent print feishu [--config path]
|
||||
gori-agent --help
|
||||
|
||||
No-link fallback:
|
||||
npm run gori-agent -- setup`);
|
||||
}
|
||||
|
||||
main(process.argv.slice(2)).then((code) => {
|
||||
if (Number.isInteger(code)) process.exitCode = code;
|
||||
}).catch((error) => {
|
||||
console.error(error instanceof Error ? error.message : String(error));
|
||||
process.exitCode = 1;
|
||||
});
|
||||
Reference in New Issue
Block a user