UNPKG

@phren/cli

Version:

Knowledge layer for AI agents - CLI, MCP server, and data layer

52 lines (51 loc) • 2.36 kB
import * as fs from "node:fs"; import * as path from "node:path"; import { homedir } from "node:os"; import { hookRequest } from "../bridge/client.js"; import { AccountUsageReader } from "../bridge/usage.js"; export async function readUsage() { try { const value = await hookRequest("/v1/usage?sources=codex,claude,opencode,opencode-go,openrouter&goPlan=1", undefined, undefined, 2_000); if (Array.isArray(value.accounts)) return value.accounts; } catch { /* Same readers when the local Hook is unavailable. */ } return (await new AccountUsageReader().read()).accounts; } export function parseProviderErrors(text, now = Date.now()) { const result = []; for (const line of text.split("\n")) { if (!/(Go usage limit exceeded|Rate limit exceeded)/i.test(line)) continue; const stamp = /\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?/.exec(line)?.[0]; const at = stamp ? Date.parse(stamp) : NaN; if (!Number.isFinite(at) || at > now || now - at > 3_600_000) continue; const provider = /(?:providerID|provider)["\s:=]+([a-z0-9-]+)/i.exec(line)?.[1] ?? (/Go usage limit/i.test(line) ? "opencode-go" : undefined); if (provider) result.push({ provider, at, message: /Go usage limit exceeded/i.test(line) ? "Go usage limit exceeded" : "Rate limit exceeded" }); } return result; } export function recentProviderErrors(now = Date.now()) { const root = path.join(process.env.OPENCODE_DATA_DIR || path.join(process.env.XDG_DATA_HOME || path.join(homedir(), ".local/share"), "opencode"), "log"); try { return fs.readdirSync(root).flatMap(name => { const file = path.join(root, name), stat = fs.lstatSync(file); if (!stat.isFile() || stat.isSymbolicLink() || now - stat.mtimeMs > 3_600_000) return []; const fd = fs.openSync(file, "r"); try { const data = Buffer.alloc(Math.min(stat.size, 1_048_576)); fs.readSync(fd, data, 0, data.length, Math.max(0, stat.size - data.length)); return parseProviderErrors(data.toString("utf8"), now); } finally { fs.closeSync(fd); } }); } catch { return []; } }