文件预览

cli.js

查看 FTTR Operator Copilot 技能包中的文件内容。

文件内容

src/cli.js

#!/usr/bin/env node

import { loadConfig } from "./config.js";
import { ConnectClient } from "./connect.js";
import { fail, ok, printJson } from "./output.js";
import {
  calculateAlertNumber,
  getAlertDetail,
  listDeviceAlerts,
  markAlertsAsRead,
} from "./tools/alerts.js";
import {
  getAgentVersion,
  getMasterGatewayInfo,
  getSlaveGatewayInfo,
} from "./tools/commands.js";
import {
  getDeviceDetail,
  getDeviceOnlineStatus,
  listDevices,
} from "./tools/devices.js";
import {
  diagnoseDeviceOffline,
  diagnoseNetworkSlow,
  explainFttraiCopilotUsage,
} from "./tools/diagnostics.js";
import {
  getNetworkExperience,
  getNetworkTopology,
  getStationExperience,
  getStationStats,
} from "./tools/network.js";
import {
  getDeviceLoad,
  getDeviceStats,
  getFaultCounter,
} from "./tools/stats.js";

const tools = {
  list_devices: async (client, args) => ok(await listDevices(client, args)),
  get_device_detail: async (client, args) => ok(await getDeviceDetail(client, args)),
  get_device_online_status: async (client, args) => ok(await getDeviceOnlineStatus(client, args)),
  list_device_alerts: async (client, args) => ok(await listDeviceAlerts(client, args)),
  get_alert_detail: async (client, args) => ok(await getAlertDetail(client, args)),
  calculate_alert_number: async (client, args) => ok(await calculateAlertNumber(client, args)),
  mark_alerts_as_read: async (client, args) => ok(await markAlertsAsRead(client, args)),
  get_network_topology: async (client, args) => ok(await getNetworkTopology(client, args)),
  get_station_stats: async (client, args) => ok(await getStationStats(client, args)),
  get_station_metrics: async (client, args) => ok(await getStationStats(client, args)),
  get_network_experience: async (client, args) => ok(await getNetworkExperience(client, args)),
  get_station_experience: async (client, args) => ok(await getStationExperience(client, args)),
  get_device_stats: async (client, args) => ok(await getDeviceStats(client, args)),
  get_device_load: async (client, args) => ok(await getDeviceLoad(client, args)),
  get_fault_counter: async (client, args) => ok(await getFaultCounter(client, args)),
  get_master_gateway_info: async (client, args) => ok(await getMasterGatewayInfo(client, args)),
  get_slave_gateway_info: async (client, args) => ok(await getSlaveGatewayInfo(client, args)),
  get_agent_version: async (client, args) => ok(await getAgentVersion(client, args)),
  diagnose_device_offline: async (client, args) => ok(await diagnoseDeviceOffline(client, args)),
  diagnose_network_slow: async (client, args) => ok(await diagnoseNetworkSlow(client, args)),
  explain_fttrai_copilot_usage: async (client, args) => ok(await explainFttraiCopilotUsage(client, args)),
};

async function main(argv) {
  const [toolName, rawArgs] = argv;

  if (!toolName || toolName === "--help" || toolName === "-h") {
    printHelp();
    return 0;
  }

  if (!Object.hasOwn(tools, toolName)) {
    const err = new Error(`未知工具: ${toolName}`);
    err.code = "unknown_tool";
    printJson(fail(err));
    return 2;
  }

  try {
    const args = parseArguments(rawArgs);
    const config = loadConfig();
    const client = new ConnectClient(config);
    const result = await tools[toolName](client, args);
    printJson(result);
    return 0;
  } catch (error) {
    printJson(fail(error));
    return 1;
  }
}

function parseArguments(rawArgs) {
  if (rawArgs === undefined || rawArgs.trim() === "") return {};
  try {
    return JSON.parse(rawArgs);
  } catch {
    const err = new Error("参数必须是 JSON 字符串");
    err.code = "invalid_argument";
    throw err;
  }
}

function printHelp() {
  process.stdout.write(`FTTR Operator Copilot OpenClaw skill CLI

Usage:
  node src/cli.js <tool> [json-arguments]

Available tools:
  list_devices '{"region_code":"<optional>","online_status":"ONLINE|OFFLINE","limit":20}'
  get_device_detail '{"device_identifier":"<device-id|mac|sn>"}'
  get_device_online_status '{"device_identifier":"<device-id|mac|sn>"}'
  list_device_alerts '{"device_identifier":"<optional>","region_code":"<optional>","event_type":"ALARM","limit":20}'
  get_alert_detail '{"alert_id":"<alert-id>"}'
  calculate_alert_number '{"device_identifiers":["<device-id|mac|sn>"]}'
  mark_alerts_as_read '{"alert_ids":["<alert-id>"]}'
  get_network_topology '{"device_identifier":"<device-id|mac|sn>"}'
  get_station_stats '{"device_identifier":"<device-id|mac|sn>","sta_mac":"<optional>"}'
  get_station_metrics '{"device_identifier":"<device-id|mac|sn>","sta_mac":"<optional>"}'
  get_network_experience '{"device_identifier":"<device-id|mac|sn>"}'
  get_station_experience '{"device_identifier":"<device-id|mac|sn>","sta_mac":"<sta-mac>"}'
  get_device_stats '{"region_code":"<optional>"}'
  get_device_load '{"device_identifier":"<device-id|mac|sn>","load_type":"basic"}'
  get_fault_counter '{"region_code":"<optional>"}'
  get_master_gateway_info '{"device_identifier":"<device-id|mac|sn>"}'
  get_slave_gateway_info '{"device_identifier":"<device-id|mac|sn>"}'
  get_agent_version '{"device_identifier":"<device-id|mac|sn>"}'
  diagnose_device_offline '{"device_identifier":"<device-id|mac|sn>"}'
  diagnose_network_slow '{"device_identifier":"<device-id|mac|sn>","symptom":"<optional>"}'
  explain_fttrai_copilot_usage '{"user_goal":"<optional>"}'

Required environment:
  FTTRAI_OPERATOR_AUTH_TOKEN

Optional environment:
  FTTRAI_RPC_URL (default: https://fms-main.fttrai.com/api/)

`);
}

main(process.argv.slice(2)).then((code) => {
  process.exitCode = code;
});