hubify 1.5.0 → 2.0.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 +50 -263
- package/dist/index.js +1872 -31483
- package/dist/index.js.map +1 -0
- package/package.json +37 -46
- package/scripts/postinstall.mjs +72 -0
- package/skill/SKILL.md +184 -0
- package/dist/chunk-FW7BS3MW.js +0 -40
- package/dist/convex-MXZDQPMB.js +0 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/convex-client.ts","../src/tui.tsx","../src/index.ts","../src/format.ts"],"sourcesContent":["/**\n * Convex client setup for CLI commands.\n *\n * Authentication: `hubify auth login` runs a device flow that issues an API\n * key (hk_live_...) stored in ~/.hubify-labs/config. All commands that write\n * data or access user-scoped data pass this key as an argument to Convex\n * mutations, which validate it server-side.\n *\n * The CONVEX_URL is baked in — it is not secret. Security comes from the\n * per-user API key, not from hiding the endpoint.\n */\n\nimport { ConvexHttpClient } from \"convex/browser\";\nimport dotenv from \"dotenv\";\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\n// ── Convex URL ────────────────────────────────────────────────\n// Hardcoded production URL — safe to ship in the npm package.\n// Override via CONVEX_URL env var or ~/.hubify-labs/config for dev.\n\nconst PRODUCTION_CONVEX_URL = \"https://scintillating-cow-269.convex.cloud\";\n\nfunction resolveConvexUrl(): string {\n if (process.env.CONVEX_URL) return process.env.CONVEX_URL;\n\n // Dev override: .env.local in hubify project root (one level up from cli/)\n const projectEnvPath = join(import.meta.dirname ?? __dirname, \"..\", \"..\", \".env.local\");\n if (existsSync(projectEnvPath)) {\n const parsed = dotenv.parse(readFileSync(projectEnvPath, \"utf-8\"));\n if (parsed.NEXT_PUBLIC_CONVEX_URL) return parsed.NEXT_PUBLIC_CONVEX_URL;\n if (parsed.CONVEX_URL) return parsed.CONVEX_URL;\n }\n\n // Config file override\n const configPath = join(homedir(), \".hubify-labs\", \"config\");\n if (existsSync(configPath)) {\n const raw = readFileSync(configPath, \"utf-8\");\n const match = raw.match(/^CONVEX_URL\\s*=\\s*(.+)/m);\n if (match) return match[1].trim();\n }\n\n return PRODUCTION_CONVEX_URL;\n}\n\n// ── API Token ─────────────────────────────────────────────────\n\nexport function getStoredToken(): string | null {\n // 1. Environment variable\n if (process.env.HUBIFY_TOKEN) return process.env.HUBIFY_TOKEN;\n\n // 2. ~/.hubify-labs/config\n const configPath = join(homedir(), \".hubify-labs\", \"config\");\n if (existsSync(configPath)) {\n const raw = readFileSync(configPath, \"utf-8\");\n const match = raw.match(/^HUBIFY_TOKEN\\s*=\\s*(.+)/m);\n if (match) return match[1].trim();\n }\n\n return null;\n}\n\nexport function saveToken(token: string): void {\n const { mkdirSync, writeFileSync } = require(\"node:fs\");\n const { join: pathJoin } = require(\"node:path\");\n const { homedir: getHomedir } = require(\"node:os\");\n\n const configDir = pathJoin(getHomedir(), \".hubify-labs\");\n mkdirSync(configDir, { recursive: true });\n const configPath = pathJoin(configDir, \"config\");\n\n let content = \"\";\n try { content = readFileSync(configPath, \"utf-8\"); } catch { /* new file */ }\n\n // Replace or append HUBIFY_TOKEN and CONVEX_URL\n const lines = content.split(\"\\n\").filter((l: string) =>\n !l.startsWith(\"HUBIFY_TOKEN=\") && !l.startsWith(\"CONVEX_URL=\")\n );\n lines.push(`HUBIFY_TOKEN=${token}`);\n lines.push(`CONVEX_URL=${resolveConvexUrl()}`);\n\n writeFileSync(configPath, lines.filter(Boolean).join(\"\\n\") + \"\\n\");\n}\n\nexport function clearToken(): void {\n const { writeFileSync } = require(\"node:fs\");\n const { join: pathJoin } = require(\"node:path\");\n const { homedir: getHomedir } = require(\"node:os\");\n\n const configPath = pathJoin(getHomedir(), \".hubify-labs\", \"config\");\n if (!existsSync(configPath)) return;\n\n const content = readFileSync(configPath, \"utf-8\");\n const cleaned = content.split(\"\\n\")\n .filter((l: string) => !l.startsWith(\"HUBIFY_TOKEN=\"))\n .join(\"\\n\");\n writeFileSync(configPath, cleaned);\n}\n\n// ── Singleton Client ──────────────────────────────────────────\n\nlet _client: ConvexHttpClient | null = null;\n\nexport function getClient(): ConvexHttpClient {\n if (!_client) {\n _client = new ConvexHttpClient(resolveConvexUrl());\n }\n return _client;\n}\n\n// ── Typed Query/Mutation Helpers ──────────────────────────────\n\nexport async function queryConvex(functionPath: string, args: Record<string, unknown> = {}): Promise<unknown> {\n const client = getClient();\n return await (client as unknown as Record<string, (...a: unknown[]) => Promise<unknown>>).query(functionPath, args);\n}\n\nexport async function mutateConvex(functionPath: string, args: Record<string, unknown> = {}): Promise<unknown> {\n const client = getClient();\n return await (client as unknown as Record<string, (...a: unknown[]) => Promise<unknown>>).mutation(functionPath, args);\n}\n\nexport async function actionConvex(functionPath: string, args: Record<string, unknown> = {}): Promise<unknown> {\n const client = getClient();\n return await (client as unknown as Record<string, (...a: unknown[]) => Promise<unknown>>).action(functionPath, args);\n}\n\n// ── Lab Resolution ────────────────────────────────────────────\n\nexport async function resolveLabId(): Promise<string> {\n if (process.env.HUBIFY_LAB_ID) return process.env.HUBIFY_LAB_ID;\n\n const configPath = join(homedir(), \".hubify-labs\", \"config\");\n if (existsSync(configPath)) {\n const raw = readFileSync(configPath, \"utf-8\");\n const match = raw.match(/^LAB_ID\\s*=\\s*(.+)/m);\n if (match) return match[1].trim();\n }\n\n // Try authenticated path first\n const token = getStoredToken();\n if (token) {\n const labs = (await mutateConvex(\"functions/cliAuth:listMyLabs\", { apiKey: token })) as Array<{ _id: string }>;\n if (labs && labs.length > 0) return labs[0]._id;\n }\n\n // Fallback: unauthenticated (dev/owner use)\n const labs = (await queryConvex(\"functions/labs:list\", {})) as Array<{ _id: string }>;\n if (!labs || labs.length === 0) {\n throw new Error(\"No labs found. Create a lab first via the web UI at hubify.com\");\n }\n return labs[0]._id;\n}\n","/**\n * hubify tui — interactive 4-panel terminal UI.\n *\n * Layout:\n * ┌─────────────────┬──────────────────┐\n * │ Chat │ Lab Overview │\n * │ (input + msgs) │ (stats + exps) │\n * ├─────────────────┼──────────────────┤\n * │ Tasks │ Alerts │\n * │ (recent tasks) │ (notifications) │\n * └─────────────────┴──────────────────┘\n *\n * Keyboard:\n * Tab — cycle panels\n * Ctrl+C — exit\n * Enter — send chat (when chat focused)\n * q — quit (when not in chat input)\n */\n\nimport React, { useState, useEffect, useCallback } from \"react\";\nimport { render, Box, Text, useInput, useApp } from \"ink\";\nimport TextInput from \"ink-text-input\";\nimport { queryConvex, resolveLabId, actionConvex } from \"./convex-client.js\";\n\n// ── Types ────────────────────────────────────────────\n\ntype Panel = \"chat\" | \"lab\" | \"tasks\" | \"alerts\";\nconst PANELS: Panel[] = [\"chat\", \"lab\", \"tasks\", \"alerts\"];\n\ninterface LabStats {\n experiments: number;\n papers: number;\n agents: number;\n pods: number;\n anomalies: string;\n}\n\ninterface Experiment {\n name: string;\n status: string;\n}\n\ninterface Task {\n title: string;\n status: string;\n priority: string;\n}\n\ninterface Notification {\n title: string;\n severity: string;\n createdAt: number;\n}\n\ninterface ChatMsg {\n role: \"user\" | \"assistant\" | \"system\";\n content: string;\n}\n\n// ── Border Box ───────────────────────────────────────\n\nfunction BorderBox({\n title,\n active,\n children,\n width,\n height,\n}: {\n title: string;\n active: boolean;\n children: React.ReactNode;\n width?: string | number;\n height?: string | number;\n}) {\n return (\n <Box\n flexDirection=\"column\"\n width={width}\n height={height}\n borderStyle=\"round\"\n borderColor={active ? \"green\" : \"gray\"}\n paddingX={1}\n >\n <Text bold color={active ? \"green\" : \"white\"}>\n {active ? \"▸ \" : \" \"}\n {title}\n </Text>\n <Box flexDirection=\"column\" flexGrow={1} overflowY=\"hidden\">\n {children}\n </Box>\n </Box>\n );\n}\n\n// ── Chat Panel ───────────────────────────────────────\n\nfunction ChatPanel({\n active,\n messages,\n input,\n onInputChange,\n onSubmit,\n sending,\n}: {\n active: boolean;\n messages: ChatMsg[];\n input: string;\n onInputChange: (v: string) => void;\n onSubmit: () => void;\n sending: boolean;\n}) {\n const visibleMsgs = messages.slice(-8);\n return (\n <BorderBox title=\"Chat\" active={active} width=\"50%\" height=\"60%\">\n <Box flexDirection=\"column\" flexGrow={1}>\n {visibleMsgs.map((m, i) => (\n <Box key={i} marginBottom={0}>\n <Text\n color={m.role === \"user\" ? \"cyan\" : m.role === \"system\" ? \"yellow\" : \"white\"}\n wrap=\"truncate-end\"\n >\n {m.role === \"user\" ? \"you\" : m.role === \"system\" ? \"sys\" : \"ai\"}:{\" \"}\n {m.content.slice(0, 120)}\n </Text>\n </Box>\n ))}\n </Box>\n <Box marginTop={1}>\n {active ? (\n <Box>\n <Text color=\"green\">> </Text>\n {sending ? (\n <Text color=\"gray\">thinking...</Text>\n ) : (\n <TextInput\n value={input}\n onChange={onInputChange}\n onSubmit={onSubmit}\n placeholder=\"Type a message...\"\n />\n )}\n </Box>\n ) : (\n <Text color=\"gray\">Tab to focus chat</Text>\n )}\n </Box>\n </BorderBox>\n );\n}\n\n// ── Lab Panel ────────────────────────────────────────\n\nfunction LabPanel({\n active,\n stats,\n experiments,\n}: {\n active: boolean;\n stats: LabStats | null;\n experiments: Experiment[];\n}) {\n return (\n <BorderBox title=\"Lab Overview\" active={active} width=\"50%\" height=\"60%\">\n {stats ? (\n <Box flexDirection=\"column\">\n <Text>\n Experiments: <Text color=\"cyan\">{stats.experiments}</Text>\n {\" \"}Papers: <Text color=\"cyan\">{stats.papers}</Text>\n {\" \"}Agents: <Text color=\"cyan\">{stats.agents}</Text>\n </Text>\n <Text>\n Pods: <Text color=\"cyan\">{stats.pods}</Text>\n {\" \"}Anomalies: <Text color=\"cyan\">{stats.anomalies}</Text>\n </Text>\n <Text color=\"gray\">─────────────────────────</Text>\n {experiments.slice(0, 8).map((e, i) => (\n <Text key={i} wrap=\"truncate-end\">\n <Text color={e.status === \"running\" ? \"green\" : e.status === \"completed\" ? \"cyan\" : \"yellow\"}>\n {e.status === \"running\" ? \"●\" : e.status === \"completed\" ? \"✓\" : \"○\"}\n </Text>{\" \"}\n {e.name.slice(0, 40)}\n </Text>\n ))}\n </Box>\n ) : (\n <Text color=\"gray\">Loading...</Text>\n )}\n </BorderBox>\n );\n}\n\n// ── Tasks Panel ──────────────────────────────────────\n\nfunction TasksPanel({\n active,\n tasks,\n}: {\n active: boolean;\n tasks: Task[];\n}) {\n return (\n <BorderBox title=\"Tasks\" active={active} width=\"50%\" height=\"40%\">\n {tasks.length === 0 ? (\n <Text color=\"gray\">No tasks</Text>\n ) : (\n tasks.slice(0, 6).map((t, i) => (\n <Text key={i} wrap=\"truncate-end\">\n <Text\n color={\n t.status === \"done\"\n ? \"green\"\n : t.status === \"in_progress\"\n ? \"cyan\"\n : \"gray\"\n }\n >\n {t.status === \"done\" ? \"✓\" : t.status === \"in_progress\" ? \"●\" : \"○\"}\n </Text>{\" \"}\n <Text color={t.priority === \"critical\" ? \"red\" : t.priority === \"high\" ? \"yellow\" : \"white\"}>\n {t.title.slice(0, 45)}\n </Text>\n </Text>\n ))\n )}\n </BorderBox>\n );\n}\n\n// ── Alerts Panel ─────────────────────────────────────\n\nfunction AlertsPanel({\n active,\n notifications,\n}: {\n active: boolean;\n notifications: Notification[];\n}) {\n return (\n <BorderBox title=\"Alerts\" active={active} width=\"50%\" height=\"40%\">\n {notifications.length === 0 ? (\n <Text color=\"gray\">No notifications</Text>\n ) : (\n notifications.slice(0, 6).map((n, i) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const age = Math.floor((Date.now() - n.createdAt) / 60000);\n const timeStr = age < 60 ? `${age}m` : `${Math.floor(age / 60)}h`;\n return (\n <Text key={i} wrap=\"truncate-end\">\n <Text\n color={\n n.severity === \"error\"\n ? \"red\"\n : n.severity === \"warning\"\n ? \"yellow\"\n : \"green\"\n }\n >\n {n.severity === \"error\" ? \"!\" : n.severity === \"warning\" ? \"▲\" : \"●\"}\n </Text>{\" \"}\n {n.title.slice(0, 40)}{\" \"}\n <Text color=\"gray\">{timeStr}</Text>\n </Text>\n );\n })\n )}\n </BorderBox>\n );\n}\n\n// ── Main TUI App ─────────────────────────────────────\n\nfunction TuiApp() {\n const { exit } = useApp();\n const [activePanel, setActivePanel] = useState<Panel>(\"chat\");\n const [chatInput, setChatInput] = useState(\"\");\n const [messages, setMessages] = useState<ChatMsg[]>([\n { role: \"system\", content: \"Welcome to Hubify TUI. Type a message to chat with your lab.\" },\n ]);\n const [sending, setSending] = useState(false);\n const [stats, setStats] = useState<LabStats | null>(null);\n const [experiments, setExperiments] = useState<Experiment[]>([]);\n const [tasks, setTasks] = useState<Task[]>([]);\n const [notifications, setNotifications] = useState<Notification[]>([]);\n const [labId, setLabId] = useState<string | null>(null);\n const [labName, setLabName] = useState<string | null>(null);\n\n // Resolve lab and fetch data\n useEffect(() => {\n let cancelled = false;\n async function load() {\n try {\n const id = await resolveLabId();\n if (cancelled) return;\n setLabId(id);\n // Fetch lab name\n const lab = await queryConvex(\"functions/labs:getById\", { id }) as { name?: string; slug?: string } | null;\n if (!cancelled && lab) {\n setLabName(lab.name ?? lab.slug ?? null);\n }\n await refresh(id);\n } catch {\n setMessages((m) => [...m, { role: \"system\", content: \"Failed to connect to Convex.\" }]);\n }\n }\n load();\n return () => { cancelled = true; };\n }, []);\n\n // Periodic refresh every 30s\n useEffect(() => {\n if (!labId) return;\n const interval = setInterval(() => refresh(labId), 30000);\n return () => clearInterval(interval);\n }, [labId]);\n\n const refresh = useCallback(async (id: string) => {\n try {\n const [statsData, expsData, tasksData, notifsData] = await Promise.all([\n queryConvex(\"functions/stats:labStats\", { labId: id }),\n queryConvex(\"functions/experiments:listByLab\", { labId: id }),\n queryConvex(\"functions/tasks:listByLab\", { labId: id, excludeProtocol: true }),\n queryConvex(\"functions/notifications:listByLab\", { labId: id }),\n ]);\n\n const s = statsData as any;\n if (s) {\n setStats({\n experiments: s.experimentCount ?? 0,\n papers: s.paperCount ?? 0,\n agents: s.agentCount ?? 0,\n pods: s.activePodCount ?? s.podCount ?? 0,\n anomalies: String(s.runningExperiments ?? 0) + \" running\",\n });\n }\n\n if (Array.isArray(expsData)) {\n setExperiments(\n (expsData as any[]).map((e) => ({\n name: e.title || e.name || \"Untitled\",\n status: e.status || \"queued\",\n }))\n );\n }\n\n if (Array.isArray(tasksData)) {\n setTasks(\n (tasksData as any[]).slice(0, 10).map((t) => ({\n title: t.title || \"Untitled\",\n status: t.status || \"open\",\n priority: t.priority || \"medium\",\n }))\n );\n }\n\n if (Array.isArray(notifsData)) {\n setNotifications(\n (notifsData as any[]).slice(0, 10).map((n) => ({\n title: n.title || n.message || \"Notification\",\n severity: n.severity || \"info\",\n createdAt: n.createdAt || Date.now(),\n }))\n );\n }\n } catch {\n // Silently fail on refresh\n }\n }, []);\n\n // Keyboard input\n useInput((input, key) => {\n if (key.tab) {\n const idx = PANELS.indexOf(activePanel);\n setActivePanel(PANELS[(idx + 1) % PANELS.length]);\n return;\n }\n if (input === \"q\" && activePanel !== \"chat\") {\n exit();\n return;\n }\n if (key.ctrl && input === \"c\") {\n exit();\n return;\n }\n });\n\n // Chat submit\n const handleChatSubmit = useCallback(async () => {\n const text = chatInput.trim();\n if (!text || sending || !labId) return;\n\n setChatInput(\"\");\n setMessages((m) => [...m, { role: \"user\", content: text }]);\n setSending(true);\n\n try {\n const result = await actionConvex(\"functions/chat:sendMessage\", {\n labId,\n message: text,\n model: \"claude\",\n context: \"research\",\n });\n const reply = (result as any)?.content || (result as any)?.message || \"No response\";\n setMessages((m) => [...m, { role: \"assistant\", content: reply }]);\n } catch (err) {\n setMessages((m) => [\n ...m,\n { role: \"system\", content: `Error: ${err instanceof Error ? err.message : \"Unknown\"}` },\n ]);\n } finally {\n setSending(false);\n }\n }, [chatInput, sending, labId]);\n\n return (\n <Box flexDirection=\"column\" width=\"100%\" height=\"100%\">\n {/* Header */}\n <Box justifyContent=\"space-between\" paddingX={1}>\n <Text bold color=\"green\">\n hubify tui\n </Text>\n <Text color=\"gray\">Tab: switch panels | q: quit | Enter: send</Text>\n </Box>\n\n {/* Top row: Chat + Lab */}\n <Box flexGrow={1}>\n <ChatPanel\n active={activePanel === \"chat\"}\n messages={messages}\n input={chatInput}\n onInputChange={setChatInput}\n onSubmit={handleChatSubmit}\n sending={sending}\n />\n <LabPanel active={activePanel === \"lab\"} stats={stats} experiments={experiments} />\n </Box>\n\n {/* Bottom row: Tasks + Alerts */}\n <Box>\n <TasksPanel active={activePanel === \"tasks\"} tasks={tasks} />\n <AlertsPanel active={activePanel === \"alerts\"} notifications={notifications} />\n </Box>\n\n {/* Status bar */}\n <Box paddingX={1}>\n <Text color=\"gray\">\n {labId ? `Lab: ${labName ?? labId.slice(0, 8) + \"...\"}` : \"Connecting...\"} | Refresh: 30s |{\" \"}\n {stats\n ? `${stats.experiments} exp · ${stats.papers} papers · ${stats.pods} pods`\n : \"Loading...\"}\n </Text>\n </Box>\n </Box>\n );\n}\n\n// ── Entry Point ──────────────────────────────────────\n\nexport function launchTui() {\n render(<TuiApp />);\n}\n","/**\n * hubify-labs CLI — drive your research lab from the terminal.\n *\n * Commands:\n * hubify-labs status — Lab overview (experiments, papers, agents, pods)\n * hubify-labs experiments — List experiments with status badges\n * hubify-labs experiments create <name> — Create a new experiment\n * hubify-labs papers — List papers with readiness %\n * hubify-labs agents — List agents with status\n * hubify-labs pods — Show pod status\n * hubify-labs pods sync — Sync pods from RunPod\n * hubify-labs queue — Show experiment queue\n * hubify-labs search <query> — Global search across all tables\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport {\n queryConvex,\n mutateConvex,\n actionConvex,\n resolveLabId,\n getStoredToken,\n saveToken,\n clearToken,\n} from \"./convex-client.js\";\nimport {\n welcomeBanner,\n sectionHeader,\n kvLine,\n experimentBadge,\n agentBadge,\n paperBadge,\n podBadge,\n readinessBar,\n formatTable,\n formatError,\n formatSuccess,\n relativeTime,\n formatCsv,\n} from \"./format.js\";\n\n// ── Types ─────────────────────────────────────────────────────\n\ninterface Experiment {\n _id: string;\n experimentId: string;\n title: string;\n status: string;\n result?: string;\n computeMode?: string;\n runTimeSeconds?: number;\n createdAt: number;\n completedAt?: number;\n}\n\ninterface Paper {\n _id: string;\n title: string;\n abstract?: string;\n target?: string;\n readinessPercent: number;\n status: string;\n pdfUrl?: string;\n lastCompiledAt?: number;\n pageCount?: number;\n wordCount?: number;\n createdAt: number;\n}\n\ninterface Agent {\n _id: string;\n name: string;\n role: string;\n model: string;\n status: string;\n totalTasks: number;\n totalTokens: number;\n createdAt: number;\n}\n\ninterface Pod {\n _id: string;\n podId: string;\n gpuType: string;\n status: string;\n sshHost?: string;\n sshPort?: number;\n costPerHour?: number;\n createdAt: number;\n}\n\ninterface LabStats {\n experimentCount: number;\n anomalyCount: number;\n paperCount: number;\n surveyCount: number;\n}\n\ninterface SearchResults {\n experiments: Experiment[];\n papers: Paper[];\n agents: Agent[];\n knowledge: Array<{ _id: string; name: string; entityType: string; description?: string }>;\n surveys: Array<{ _id: string; name: string; sourceCount?: number; anomalyCount?: number }>;\n}\n\n// ── Program Setup ─────────────────────────────────────────────\n\nconst program = new Command();\n\nprogram\n .name(\"hubify-labs\")\n .description(\"Hubify Labs CLI — Scientific Discovery Platform\")\n .version(\"0.1.0\")\n .option(\"--json\", \"Output machine-readable JSON instead of human-readable text\")\n .option(\"--format <format>\", \"Output format: table (default), json, csv\")\n .option(\"--lab <slugOrId>\", \"Target lab by slug (e.g. bigbounce, pta-gw, chirality) or ID\")\n .action(() => {\n console.log(welcomeBanner());\n });\n\n/** Check if --json flag is set globally */\nfunction isJsonOutput(): boolean {\n return program.opts().json === true || program.opts().format === \"json\";\n}\n\n/** Check if --format csv is set */\nfunction isCsvOutput(): boolean {\n return program.opts().format === \"csv\";\n}\n\n/**\n * Resolve lab ID from --lab flag (slug or ID). Sets HUBIFY_LAB_ID env so\n * resolveLabId() in convex-client.ts picks it up without further changes.\n */\nasync function applyLabFlag(): Promise<void> {\n const labArg = program.opts().lab as string | undefined;\n if (!labArg) return;\n\n // If it looks like a Convex ID (long alphanumeric with digits), use directly\n if (/^[a-z0-9]{20,}$/.test(labArg)) {\n process.env.HUBIFY_LAB_ID = labArg;\n return;\n }\n\n // Otherwise look up by slug\n const labs = (await queryConvex(\"functions/labs:list\", {})) as Array<{ _id: string; slug: string; name: string }>;\n const match = labs.find((l) => l.slug === labArg || l.slug.includes(labArg) || l.name.toLowerCase() === labArg.toLowerCase());\n if (!match) {\n const slugs = labs.map((l) => l.slug).join(\", \");\n throw new Error(`Lab \"${labArg}\" not found. Available slugs: ${slugs}`);\n }\n process.env.HUBIFY_LAB_ID = match._id;\n}\n\n/** Output data in the requested format */\nfunction outputFormatted(data: Record<string, unknown>[], humanFn: () => void): void {\n if (isJsonOutput()) {\n console.log(JSON.stringify(data, null, 2));\n } else if (isCsvOutput()) {\n console.log(formatCsv(data));\n } else {\n humanFn();\n }\n}\n\n// Apply --lab flag before any subcommand runs\nprogram.hook(\"preAction\", async () => {\n try {\n await applyLabFlag();\n } catch (err) {\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n});\n\n// ── status ────────────────────────────────────────────────────\n\nprogram\n .command(\"status\")\n .description(\"Show lab overview: experiments, papers, agents, pods\")\n .action(async () => {\n const spinner = ora(\"Connecting to Hubify Labs...\").start();\n try {\n const labId = await resolveLabId();\n spinner.text = \"Fetching lab stats...\";\n\n const [stats, experiments, papers, agents, pods] = await Promise.all([\n queryConvex(\"functions/stats:labStats\", { labId }) as Promise<LabStats>,\n queryConvex(\"functions/experiments:listByLab\", { labId }) as Promise<Experiment[]>,\n queryConvex(\"functions/papers:listByLab\", { labId }) as Promise<Paper[]>,\n queryConvex(\"functions/agents:listByLab\", { labId }) as Promise<Agent[]>,\n queryConvex(\"functions/pods:listByLab\", { labId }) as Promise<Pod[]>,\n ]);\n\n spinner.stop();\n\n // Compute counts\n const running = experiments.filter((e) => e.status === \"running\").length;\n const queued = experiments.filter((e) => e.status === \"queued\").length;\n const passed = experiments.filter((e) => e.status === \"pass\").length;\n const failed = experiments.filter((e) => e.status === \"fail\").length;\n const activeAgents = agents.filter((a) => a.status === \"active\" || a.status === \"busy\").length;\n const activePods = pods.filter((p) => p.status === \"running\").length;\n\n if (isJsonOutput()) {\n console.log(JSON.stringify({\n stats,\n experiments: { total: experiments.length, running, queued, passed, failed },\n papers: papers.map((p) => ({ id: p._id, title: p.title, readiness: p.readinessPercent, status: p.status })),\n agents: { total: agents.length, active: activeAgents },\n pods: { total: pods.length, active: activePods, list: pods.map((p) => ({ id: p.podId, gpu: p.gpuType, status: p.status })) },\n }, null, 2));\n return;\n }\n\n console.log(sectionHeader(\"Lab Status\"));\n console.log(kvLine(\"Experiments\", `${stats.experimentCount} total`));\n console.log(\n kvLine(\n \" Breakdown\",\n `${chalk.cyan(running + \" running\")} / ${chalk.yellow(queued + \" queued\")} / ${chalk.green(passed + \" pass\")} / ${chalk.red(failed + \" fail\")}`\n )\n );\n console.log(kvLine(\"Papers\", `${stats.paperCount} total`));\n console.log(kvLine(\"Surveys\", `${stats.surveyCount} total`));\n console.log(kvLine(\"Anomalies\", `${stats.anomalyCount.toLocaleString()}`));\n console.log(kvLine(\"Agents\", `${agents.length} total (${activeAgents} active)`));\n console.log(kvLine(\"Pods\", `${pods.length} total (${activePods} running)`));\n\n // Show top papers by readiness\n if (papers.length > 0) {\n console.log(sectionHeader(\"Papers\"));\n for (const paper of papers.slice(0, 5)) {\n console.log(` ${paperBadge(paper.status)} ${paper.title}`);\n console.log(` ${readinessBar(paper.readinessPercent)}`);\n }\n }\n\n // Show running experiments\n const runningExps = experiments.filter((e) => e.status === \"running\");\n if (runningExps.length > 0) {\n console.log(sectionHeader(\"Running Experiments\"));\n for (const exp of runningExps.slice(0, 5)) {\n console.log(` ${experimentBadge(exp.status)} ${exp.experimentId}: ${exp.title}`);\n }\n }\n\n // Show active pods\n const activePodList = pods.filter((p) => p.status === \"running\");\n if (activePodList.length > 0) {\n console.log(sectionHeader(\"Active Pods\"));\n for (const pod of activePodList) {\n const cost = pod.costPerHour ? `$${pod.costPerHour.toFixed(2)}/hr` : \"\";\n console.log(` ${podBadge(pod.status)} ${pod.podId} (${pod.gpuType}) ${chalk.gray(cost)}`);\n }\n }\n\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── experiments ───────────────────────────────────────────────\n\nconst experimentsCmd = program\n .command(\"experiments\")\n .description(\"List experiments with status badges\")\n .option(\"-s, --status <status>\", \"Filter by status (queued, running, pass, fail, blocked)\")\n .option(\"-n, --limit <count>\", \"Limit number of results shown\", \"50\")\n .action(async (opts) => {\n const spinner = ora(\"Fetching experiments...\").start();\n try {\n let experiments: Experiment[];\n\n if (opts.status) {\n experiments = (await queryConvex(\"functions/experiments:listByStatus\", {\n status: opts.status,\n })) as Experiment[];\n } else {\n const labId = await resolveLabId();\n experiments = (await queryConvex(\"functions/experiments:listByLab\", {\n labId,\n })) as Experiment[];\n }\n const limit = parseInt(opts.limit, 10);\n if (!isNaN(limit) && limit > 0) {\n experiments = experiments.slice(0, limit);\n }\n\n spinner.stop();\n\n if (experiments.length === 0 && !isJsonOutput() && !isCsvOutput()) {\n console.log(chalk.gray(\" No experiments found.\"));\n return;\n }\n\n const csvRows = experiments.map((e) => ({\n id: e.experimentId,\n status: e.status,\n title: e.title,\n runtime_s: e.runTimeSeconds ?? \"\",\n created: e.createdAt ? new Date(e.createdAt).toISOString() : \"\",\n }));\n\n outputFormatted(csvRows, () => {\n console.log(sectionHeader(`Experiments (${experiments.length})`));\n console.log(\n formatTable(experiments as unknown as Record<string, unknown>[], [\n { header: \"ID\", key: \"experimentId\", width: 10 },\n {\n header: \"Status\",\n key: \"status\",\n width: 14,\n format: (v) => experimentBadge(String(v)),\n },\n { header: \"Title\", key: \"title\", width: 45 },\n {\n header: \"Runtime\",\n key: \"runTimeSeconds\",\n width: 10,\n align: \"right\",\n format: (v) => {\n if (!v) return chalk.gray(\"-\");\n const s = Number(v);\n if (s < 60) return `${s}s`;\n if (s < 3600) return `${Math.floor(s / 60)}m`;\n return `${(s / 3600).toFixed(1)}h`;\n },\n },\n {\n header: \"Created\",\n key: \"createdAt\",\n width: 10,\n format: (v) => (v ? relativeTime(Number(v)) : \"-\"),\n },\n ])\n );\n console.log(\"\");\n });\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\nexperimentsCmd\n .command(\"create <name>\")\n .description(\"Create a new experiment\")\n .option(\"--gpu <type>\", \"GPU type (H200, H100, A100)\", \"H200\")\n .option(\"--result <result>\", \"Initial result description\")\n .action(async (name: string, opts) => {\n const spinner = ora(\"Creating experiment...\").start();\n try {\n const labId = await resolveLabId();\n\n // Generate an experiment ID\n const existing = (await queryConvex(\"functions/experiments:listByLab\", {\n labId,\n })) as Experiment[];\n const nextNum = existing.length + 1;\n const experimentId = `EXP-${String(nextNum).padStart(3, \"0\")}`;\n\n await mutateConvex(\"functions/experiments:create\", {\n labId,\n experimentId,\n title: name,\n status: \"queued\",\n computeMode: opts.gpu,\n result: opts.result,\n });\n\n spinner.stop();\n console.log(formatSuccess(`Experiment created: ${experimentId} — ${name}`));\n console.log(kvLine(\"Status\", \"queued\"));\n console.log(kvLine(\"Compute\", opts.gpu));\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\nexperimentsCmd\n .command(\"run <id>\")\n .description(\"Dispatch experiment to a pod for execution\")\n .option(\"--gpu <type>\", \"GPU type (H200, H100, A100)\", \"H200\")\n .action(async (id: string, opts) => {\n const spinner = ora(`Dispatching experiment ${id}...`).start();\n try {\n const labId = await resolveLabId();\n await mutateConvex(\"functions/experiments:updateStatus\", {\n labId,\n experimentId: id,\n status: \"running\",\n computeMode: opts.gpu,\n });\n spinner.stop();\n console.log(formatSuccess(`Experiment ${id} dispatched to ${opts.gpu} pod.`));\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── papers ────────────────────────────────────────────────────\n\nconst papersCmd = program\n .command(\"papers\")\n .description(\"List papers with readiness percentages\")\n .option(\"-a, --abstract\", \"Show full abstract for each paper\")\n .option(\"--pdf\", \"Show PDF URL and compile metadata\")\n .action(async (opts) => {\n const spinner = ora(\"Fetching papers...\").start();\n try {\n const labId = await resolveLabId();\n const papers = (await queryConvex(\"functions/papers:listByLab\", {\n labId,\n })) as Paper[];\n\n spinner.stop();\n\n if (papers.length === 0 && !isJsonOutput() && !isCsvOutput()) {\n console.log(chalk.gray(\" No papers found.\"));\n return;\n }\n\n const csvRows = papers.map((p) => ({\n title: p.title,\n status: p.status,\n readiness: p.readinessPercent,\n target: p.target ?? \"\",\n abstract: p.abstract ?? \"\",\n pdf_url: p.pdfUrl ?? \"\",\n pages: p.pageCount ?? \"\",\n word_count: p.wordCount ?? \"\",\n last_compiled: p.lastCompiledAt ? new Date(p.lastCompiledAt).toISOString() : \"\",\n created: p.createdAt ? new Date(p.createdAt).toISOString() : \"\",\n }));\n\n outputFormatted(csvRows, () => {\n console.log(sectionHeader(`Papers (${papers.length})`));\n for (const paper of papers) {\n console.log(` ${paperBadge(paper.status)} ${paper.title}`);\n console.log(` ${readinessBar(paper.readinessPercent)}`);\n if (paper.target) {\n console.log(` ${chalk.gray(\"Target:\")} ${paper.target}`);\n }\n if (opts.abstract && paper.abstract) {\n const lines = paper.abstract.match(/.{1,90}/g) ?? [];\n console.log(` ${chalk.dim(\"Abstract:\")}`);\n lines.slice(0, 4).forEach((l) => console.log(` ${chalk.dim(l)}`));\n if (lines.length > 4) console.log(` ${chalk.dim(\"...\")}`);\n }\n if (opts.pdf) {\n if (paper.pdfUrl) console.log(` ${chalk.gray(\"PDF:\")} ${paper.pdfUrl}`);\n if (paper.lastCompiledAt) {\n console.log(` ${chalk.gray(\"Compiled:\")} ${new Date(paper.lastCompiledAt).toLocaleDateString()}`);\n }\n if (paper.pageCount) console.log(` ${chalk.gray(\"Pages:\")} ${paper.pageCount}`);\n if (paper.wordCount) console.log(` ${chalk.gray(\"Words:\")} ~${Math.round(paper.wordCount / 100) * 100}`);\n }\n console.log(\"\");\n }\n });\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\npapersCmd\n .command(\"review <id>\")\n .description(\"Trigger cross-model peer review on a paper\")\n .action(async (id: string) => {\n const spinner = ora(`Starting peer review for paper ${id}...`).start();\n try {\n const labId = await resolveLabId();\n await actionConvex(\"functions/chat:sendMessage\", {\n labId,\n message: `/review paper ${id}`,\n context: \"CLI paper review trigger\",\n model: \"claude\",\n mode: \"review\",\n });\n spinner.stop();\n console.log(formatSuccess(`Peer review initiated for paper ${id}.`));\n console.log(chalk.gray(\" Cross-model review will run in the background.\"));\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── knowledge ─────────────────────────────────────────────────\n\nprogram\n .command(\"knowledge\")\n .description(\"List lab knowledge wiki entries\")\n .option(\"-n <count>\", \"Number to show\", \"20\")\n .option(\"--type <type>\", \"Filter by entity type: concept, entity, source, method, result, dataset\")\n .action(async (opts) => {\n const spinner = ora(\"Fetching knowledge...\").start();\n try {\n const labId = await resolveLabId();\n let entries = (await queryConvex(\"functions/knowledge:listByLab\", { labId })) as any[];\n if (opts.type) entries = entries.filter((k: any) => k.entityType === opts.type);\n entries = entries.slice(0, parseInt(opts.n));\n spinner.stop();\n\n if (isJsonOutput()) {\n console.log(JSON.stringify({ knowledge: entries }, null, 2));\n return;\n }\n\n if (!entries.length) {\n console.log(chalk.gray(\" No knowledge entries yet. Add them from the app or with `mcp knowledge_add`.\"));\n return;\n }\n\n console.log(sectionHeader(`Knowledge Wiki (${entries.length})`));\n entries.forEach((k: any) => {\n const typeColor = k.entityType === \"concept\" ? chalk.cyan :\n k.entityType === \"method\" ? chalk.magenta :\n k.entityType === \"result\" ? chalk.green :\n k.entityType === \"dataset\" ? chalk.yellow : chalk.dim;\n console.log(` ${typeColor(k.entityType ?? \"?\")} ${chalk.bold(k.name)}`);\n if (k.description) console.log(` ${chalk.dim(k.description.slice(0, 120))}`);\n });\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── reviews ───────────────────────────────────────────────────\n\nprogram\n .command(\"reviews\")\n .description(\"List peer reviews for papers in the lab\")\n .option(\"-n <count>\", \"Number to show\", \"20\")\n .option(\"--verdict <verdict>\", \"Filter by verdict: approve, concern, reject\")\n .action(async (opts) => {\n const spinner = ora(\"Fetching reviews...\").start();\n try {\n const labId = await resolveLabId();\n let reviews = (await queryConvex(\"functions/paperReviews:listByLab\", { labId })) as any[];\n if (opts.verdict) reviews = reviews.filter((r: any) => r.verdict === opts.verdict);\n reviews = reviews.slice(0, parseInt(opts.n));\n spinner.stop();\n\n if (isJsonOutput()) {\n console.log(JSON.stringify({ reviews }, null, 2));\n return;\n }\n\n if (!reviews.length) {\n console.log(chalk.gray(\" No reviews yet. Run `hubify-labs papers review <id>` to trigger.\"));\n return;\n }\n\n const verdictColor = (v: string) =>\n v === \"approve\" ? chalk.green(v.toUpperCase()) :\n v === \"reject\" ? chalk.red(v.toUpperCase()) :\n chalk.yellow(v.toUpperCase());\n\n const counts = { approve: 0, concern: 0, reject: 0 } as Record<string, number>;\n reviews.forEach((r: any) => { if (r.verdict) counts[r.verdict] = (counts[r.verdict] ?? 0) + 1; });\n\n console.log(sectionHeader(`Paper Reviews (${reviews.length})`));\n console.log(` ${chalk.green(`${counts.approve} approve`)} ${chalk.yellow(`${counts.concern} concern`)} ${chalk.red(`${counts.reject} reject`)}\\n`);\n console.log(\n formatTable(reviews, [\n { header: \"Model\", key: \"reviewerModel\", width: 18, format: (v) => String(v ?? \"\").replace(\"claude-sonnet-4-6\", \"claude\").replace(\"gemini-2.5-pro\", \"gemini\").slice(0, 18) },\n { header: \"Verdict\", key: \"verdict\", width: 10, format: (v) => verdictColor(String(v ?? \"\")) },\n { header: \"Confidence\", key: \"confidence\", width: 11, align: \"right\", format: (v) => v != null ? `${Math.round(Number(v) * 100)}%` : \"—\" },\n { header: \"Summary\", key: \"summary\", width: 45, format: (v) => chalk.dim(String(v ?? \"\").slice(0, 45)) },\n ])\n );\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── agents ────────────────────────────────────────────────────\n\nprogram\n .command(\"agents\")\n .description(\"List agents with status and role\")\n .action(async () => {\n const spinner = ora(\"Fetching agents...\").start();\n try {\n const labId = await resolveLabId();\n const agents = (await queryConvex(\"functions/agents:listByLab\", {\n labId,\n })) as Agent[];\n\n spinner.stop();\n\n if (agents.length === 0 && !isJsonOutput() && !isCsvOutput()) {\n console.log(chalk.gray(\" No agents found.\"));\n return;\n }\n\n const csvRows = agents.map((a) => ({\n name: a.name,\n status: a.status,\n role: a.role,\n model: a.model,\n tasks: a.totalTasks,\n tokens: a.totalTokens,\n }));\n\n outputFormatted(csvRows, () => {\n console.log(sectionHeader(`Agents (${agents.length})`));\n console.log(\n formatTable(agents as unknown as Record<string, unknown>[], [\n { header: \"Name\", key: \"name\", width: 22 },\n {\n header: \"Status\",\n key: \"status\",\n width: 14,\n format: (v) => agentBadge(String(v)),\n },\n {\n header: \"Role\",\n key: \"role\",\n width: 14,\n format: (v) => {\n const role = String(v);\n if (role === \"orchestrator\") return chalk.magenta(role);\n if (role === \"lead\") return chalk.blue(role);\n return chalk.gray(role);\n },\n },\n { header: \"Model\", key: \"model\", width: 20 },\n {\n header: \"Tasks\",\n key: \"totalTasks\",\n width: 8,\n align: \"right\",\n format: (v) => String(v ?? 0),\n },\n {\n header: \"Tokens\",\n key: \"totalTokens\",\n width: 10,\n align: \"right\",\n format: (v) => {\n const n = Number(v ?? 0);\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;\n return String(n);\n },\n },\n ])\n );\n });\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── figures ───────────────────────────────────────────────────\n\nprogram\n .command(\"figures\")\n .description(\"List figures generated in the lab\")\n .option(\"-n, --limit <n>\", \"Max figures to show\", \"20\")\n .option(\"--experiment <id>\", \"Filter by experiment Convex ID\")\n .action(async (opts) => {\n const spinner = ora(\"Fetching figures...\").start();\n try {\n const labId = await resolveLabId();\n let figures: any[];\n if (opts.experiment) {\n figures = (await queryConvex(\"functions/figures:listByExperiment\", { experimentId: opts.experiment })) as any[];\n } else {\n figures = (await queryConvex(\"functions/figures:listByLab\", { labId })) as any[];\n }\n figures = figures.slice(0, parseInt(opts.limit, 10));\n spinner.stop();\n\n if (figures.length === 0) {\n console.log(chalk.gray(\" No figures found.\"));\n return;\n }\n\n const csvRows = figures.map((f: any) => ({\n title: f.title,\n type: f.type ?? \"figure\",\n caption: f.caption?.slice(0, 60) ?? \"\",\n url: f.resolvedImageUrl ?? f.imageUrl ?? \"\",\n created: new Date(f.createdAt).toLocaleDateString(\"en-CA\"),\n }));\n\n outputFormatted(csvRows, () => {\n console.log(sectionHeader(`Figures (${figures.length})`));\n console.log(\n formatTable(figures, [\n { header: \"Title\", key: \"title\", width: 30 },\n { header: \"Type\", key: \"type\", width: 14, format: (v) => chalk.cyan(String(v ?? \"figure\")) },\n { header: \"Caption\", key: \"caption\", width: 40, format: (v) => chalk.gray(String(v ?? \"\").slice(0, 40)) },\n { header: \"Created\", key: \"createdAt\", width: 12, format: (v) => new Date(Number(v)).toLocaleDateString(\"en-CA\") },\n ])\n );\n });\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── pods ──────────────────────────────────────────────────────\n\nconst podsCmd = program\n .command(\"pods\")\n .description(\"Show pod status\")\n .action(async () => {\n const spinner = ora(\"Fetching pods...\").start();\n try {\n const labId = await resolveLabId();\n const pods = (await queryConvex(\"functions/pods:listByLab\", {\n labId,\n })) as Pod[];\n\n spinner.stop();\n\n if (isJsonOutput()) {\n console.log(JSON.stringify(pods, null, 2));\n return;\n }\n\n if (pods.length === 0) {\n console.log(chalk.gray(\" No pods found. Run `hubify-labs pods sync` to import from RunPod.\"));\n return;\n }\n\n console.log(sectionHeader(`Pods (${pods.length})`));\n console.log(\n formatTable(pods as unknown as Record<string, unknown>[], [\n { header: \"Pod ID\", key: \"podId\", width: 16 },\n {\n header: \"Status\",\n key: \"status\",\n width: 14,\n format: (v) => podBadge(String(v)),\n },\n { header: \"GPU\", key: \"gpuType\", width: 14 },\n {\n header: \"Cost/hr\",\n key: \"costPerHour\",\n width: 10,\n align: \"right\",\n format: (v) => (v ? `$${Number(v).toFixed(2)}` : chalk.gray(\"-\")),\n },\n {\n header: \"SSH\",\n key: \"sshHost\",\n width: 24,\n format: (v, ...args) => {\n // We can't access other fields from here, just show host\n return v ? String(v) : chalk.gray(\"n/a\");\n },\n },\n {\n header: \"Created\",\n key: \"createdAt\",\n width: 10,\n format: (v) => (v ? relativeTime(Number(v)) : \"-\"),\n },\n ])\n );\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\npodsCmd\n .command(\"sync\")\n .description(\"Sync pods from RunPod API into Convex\")\n .action(async () => {\n const spinner = ora(\"Syncing pods from RunPod...\").start();\n try {\n const labId = await resolveLabId();\n const result = (await actionConvex(\"functions/runpod:syncPods\", {\n labId,\n })) as { synced: number };\n\n spinner.stop();\n console.log(formatSuccess(`Synced ${result.synced} pod(s) from RunPod.`));\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\npodsCmd\n .command(\"ssh <podId>\")\n .description(\"SSH into a running pod\")\n .action(async (podId: string) => {\n const spinner = ora(\"Looking up pod...\").start();\n try {\n const labId = await resolveLabId();\n const pods = (await queryConvex(\"functions/pods:listByLab\", { labId })) as Pod[];\n const pod = pods.find((p) => p.podId === podId || p._id === podId);\n\n spinner.stop();\n\n if (!pod) {\n console.error(formatError(`Pod \"${podId}\" not found.`));\n process.exit(1);\n }\n\n if (!pod.sshHost || !pod.sshPort) {\n console.error(formatError(`Pod \"${podId}\" has no SSH access configured.`));\n process.exit(1);\n }\n\n console.log(chalk.gray(`\\n Connecting to ${pod.sshHost}:${pod.sshPort}...\\n`));\n\n const { execSync } = await import(\"child_process\");\n try {\n execSync(`ssh -o StrictHostKeyChecking=no -p ${pod.sshPort} root@${pod.sshHost}`, {\n stdio: \"inherit\",\n });\n } catch {\n // SSH exits with non-zero when session ends normally\n }\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\npodsCmd\n .command(\"create\")\n .description(\"Create a new pod via RunPod API\")\n .option(\"--gpu <type>\", \"GPU type\", \"H200\")\n .option(\"--name <name>\", \"Pod name\", \"hubify-lab\")\n .action(async (opts) => {\n const spinner = ora(`Creating ${opts.gpu} pod...`).start();\n try {\n const labId = await resolveLabId();\n const result = (await actionConvex(\"functions/runpod:createPod\", {\n labId,\n gpuType: opts.gpu,\n name: opts.name,\n })) as { podId: string };\n\n spinner.stop();\n console.log(formatSuccess(`Pod created: ${result.podId} (${opts.gpu})`));\n console.log(chalk.gray(\" Pod is starting up. Run `hubify pods` to check status.\"));\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── queue ─────────────────────────────────────────────────────\n\nprogram\n .command(\"queue\")\n .description(\"Show experiment queue (queued + running)\")\n .action(async () => {\n const spinner = ora(\"Fetching queue...\").start();\n try {\n const labId = await resolveLabId();\n const experiments = (await queryConvex(\"functions/experiments:listByLab\", {\n labId,\n })) as Experiment[];\n\n spinner.stop();\n\n const queued = experiments.filter((e) => e.status === \"queued\");\n const running = experiments.filter((e) => e.status === \"running\");\n const blocked = experiments.filter((e) => e.status === \"blocked\");\n\n if (running.length > 0) {\n console.log(sectionHeader(`Running (${running.length})`));\n for (const exp of running) {\n console.log(` ${experimentBadge(exp.status)} ${exp.experimentId}: ${exp.title}`);\n if (exp.computeMode) {\n console.log(` ${chalk.gray(\"Compute:\")} ${exp.computeMode}`);\n }\n }\n }\n\n if (queued.length > 0) {\n console.log(sectionHeader(`Queued (${queued.length})`));\n for (const exp of queued) {\n console.log(` ${experimentBadge(exp.status)} ${exp.experimentId}: ${exp.title}`);\n }\n }\n\n if (blocked.length > 0) {\n console.log(sectionHeader(`Blocked (${blocked.length})`));\n for (const exp of blocked) {\n console.log(` ${experimentBadge(exp.status)} ${exp.experimentId}: ${exp.title}`);\n }\n }\n\n if (running.length === 0 && queued.length === 0 && blocked.length === 0) {\n console.log(chalk.gray(\"\\n Queue is empty. All experiments complete.\"));\n }\n\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── search ────────────────────────────────────────────────────\n\nprogram\n .command(\"search <query>\")\n .description(\"Global search across experiments, papers, agents, knowledge, surveys\")\n .action(async (queryStr: string) => {\n const spinner = ora(`Searching for \"${queryStr}\"...`).start();\n try {\n const labId = await resolveLabId();\n const results = (await queryConvex(\"functions/search:globalSearch\", {\n labId,\n query: queryStr,\n })) as SearchResults;\n\n spinner.stop();\n\n const totalHits =\n results.experiments.length +\n results.papers.length +\n results.agents.length +\n results.knowledge.length +\n results.surveys.length;\n\n if (totalHits === 0) {\n console.log(chalk.gray(`\\n No results for \"${queryStr}\".`));\n return;\n }\n\n console.log(sectionHeader(`Search Results (${totalHits} hits)`));\n\n if (results.experiments.length > 0) {\n console.log(chalk.bold(` Experiments (${results.experiments.length}):`));\n for (const exp of results.experiments) {\n console.log(` ${experimentBadge(exp.status)} ${exp.experimentId}: ${exp.title}`);\n }\n console.log(\"\");\n }\n\n if (results.papers.length > 0) {\n console.log(chalk.bold(` Papers (${results.papers.length}):`));\n for (const paper of results.papers) {\n console.log(` ${paperBadge(paper.status)} ${paper.title}`);\n }\n console.log(\"\");\n }\n\n if (results.agents.length > 0) {\n console.log(chalk.bold(` Agents (${results.agents.length}):`));\n for (const agent of results.agents) {\n console.log(` ${agentBadge(agent.status)} ${agent.name} (${agent.role})`);\n }\n console.log(\"\");\n }\n\n if (results.knowledge.length > 0) {\n console.log(chalk.bold(` Knowledge (${results.knowledge.length}):`));\n for (const entry of results.knowledge) {\n console.log(` ${chalk.cyan(entry.entityType)} ${entry.name}`);\n }\n console.log(\"\");\n }\n\n if (results.surveys.length > 0) {\n console.log(chalk.bold(` Surveys (${results.surveys.length}):`));\n for (const survey of results.surveys) {\n const anomalies = survey.anomalyCount ? chalk.yellow(`${survey.anomalyCount.toLocaleString()} anomalies`) : \"\";\n console.log(` ${survey.name} ${anomalies}`);\n }\n console.log(\"\");\n }\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── lab ──────────────────────────────────────────────────────\n\nconst labCmd = program\n .command(\"lab\")\n .description(\"Manage the current lab\")\n .argument(\"[action]\", \"create | switch | info (default: info)\")\n .action(async (action?: string) => {\n if (!action || action === \"info\") {\n const spinner = ora(\"Fetching lab info...\").start();\n try {\n const labId = await resolveLabId();\n const [stats, experiments, papers, agents] = await Promise.all([\n queryConvex(\"functions/stats:labStats\", { labId }) as Promise<LabStats>,\n queryConvex(\"functions/experiments:listByLab\", { labId }) as Promise<Experiment[]>,\n queryConvex(\"functions/papers:listByLab\", { labId }) as Promise<Paper[]>,\n queryConvex(\"functions/agents:listByLab\", { labId }) as Promise<Agent[]>,\n ]);\n spinner.stop();\n console.log(sectionHeader(\"Current Lab\"));\n console.log(kvLine(\"Lab ID\", labId));\n console.log(kvLine(\"Experiments\", String(stats.experimentCount)));\n console.log(kvLine(\"Papers\", String(stats.paperCount)));\n console.log(kvLine(\"Surveys\", String(stats.surveyCount)));\n console.log(kvLine(\"Agents\", String(agents.length)));\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n } else if (action === \"create\") {\n const readline = await import(\"readline\");\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n const ask = (q: string): Promise<string> => new Promise((resolve) => rl.question(q, resolve));\n\n console.log(chalk.bold(\"\\n Create a new lab\\n\"));\n const name = await ask(chalk.gray(\" Lab name: \"));\n const description = await ask(chalk.gray(\" Description (optional): \"));\n rl.close();\n\n if (!name.trim()) {\n console.error(chalk.red(\" Lab name is required.\\n\"));\n process.exit(1);\n }\n\n const createSpinner = ora(\"Creating lab...\").start();\n try {\n const slug = name.trim().toLowerCase().replace(/[^a-z0-9]+/g, \"-\").replace(/^-|-$/g, \"\");\n await mutateConvex(\"functions/labs:create\", {\n name: name.trim(),\n slug,\n description: description.trim() || undefined,\n });\n createSpinner.stop();\n console.log(formatSuccess(`Lab \"${name.trim()}\" created (slug: ${slug})`));\n console.log(chalk.gray(` Open at: https://hubify.com/lab/${slug}\\n`));\n } catch (err) {\n createSpinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n } else if (action === \"switch\") {\n // List labs and let user pick\n const switchSpinner = ora(\"Fetching labs...\").start();\n try {\n const labs = await queryConvex(\"functions/labs:list\", {}) as { _id: string; name: string; slug: string }[];\n switchSpinner.stop();\n if (labs.length === 0) {\n console.log(chalk.yellow(\"\\n No labs found. Create one with `hubify lab create`.\\n\"));\n return;\n }\n console.log(sectionHeader(\"Your Labs\"));\n labs.forEach((l, i) => console.log(` ${chalk.bold(String(i + 1))}. ${l.name} ${chalk.gray(`(${l.slug})`)}`));\n console.log(\"\");\n\n const readline = await import(\"readline\");\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n const choice = await new Promise<string>((resolve) => rl.question(chalk.gray(\" Select lab number: \"), resolve));\n rl.close();\n\n const idx = parseInt(choice, 10) - 1;\n if (isNaN(idx) || idx < 0 || idx >= labs.length) {\n console.log(chalk.red(\" Invalid selection.\\n\"));\n return;\n }\n\n // Save to config\n const fs = await import(\"fs\");\n const path = await import(\"path\");\n const os = await import(\"os\");\n const configDir = path.join(os.homedir(), \".hubify-labs\");\n if (!fs.existsSync(configDir)) fs.mkdirSync(configDir, { recursive: true });\n const configFile = path.join(configDir, \"config\");\n let configContent = \"\";\n try { configContent = fs.readFileSync(configFile, \"utf-8\"); } catch { /* new file */ }\n const lines = configContent.split(\"\\n\").filter((l: string) => !l.startsWith(\"HUBIFY_LAB_ID=\"));\n lines.push(`HUBIFY_LAB_ID=${labs[idx]._id}`);\n fs.writeFileSync(configFile, lines.join(\"\\n\") + \"\\n\");\n\n console.log(formatSuccess(`Switched to lab: ${labs[idx].name} (${labs[idx].slug})`));\n } catch (err) {\n switchSpinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n } else {\n console.log(chalk.red(` Unknown action: ${action}. Use info, create, or switch.`));\n }\n });\n\n// ── labs ─────────────────────────────────────────────────────\n\nprogram\n .command(\"labs\")\n .description(\"List your labs\")\n .action(async () => {\n const spinner = ora(\"Fetching labs...\").start();\n try {\n const token = getStoredToken();\n const [labs, activeLab] = await Promise.all([\n (token\n ? mutateConvex(\"functions/cliAuth:listMyLabs\", { apiKey: token })\n : queryConvex(\"functions/labs:list\", {})\n ) as Promise<Array<{\n _id: string;\n name: string;\n slug?: string;\n createdAt: number;\n experimentCount?: number;\n surveyCount?: number;\n }>>,\n resolveLabId().catch(() => \"\"),\n ]);\n\n spinner.stop();\n\n if (labs.length === 0) {\n console.log(chalk.gray(\"\\n No labs found. Run `hubify lab create` or visit hubify.com/app to get started.\\n\"));\n return;\n }\n\n console.log(sectionHeader(`Your Labs (${labs.length})`));\n for (const lab of labs) {\n const isActive = lab._id === activeLab;\n const marker = isActive ? chalk.green(\"●\") : chalk.dim(\"○\");\n const name = isActive ? chalk.bold(lab.name) : chalk.cyan(lab.name);\n const slug = lab.slug ? chalk.dim(`[${lab.slug}]`) : \"\";\n const active = isActive ? chalk.green(\" ← active\") : \"\";\n console.log(` ${marker} ${name} ${slug}${active}`);\n console.log(` ${chalk.gray(\"Use:\")} hubify-labs --lab ${lab.slug ?? lab._id} <command>`);\n }\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── chat ─────────────────────────────────────────────────────\n\nprogram\n .command(\"chat\")\n .description(\"Open AI chat in terminal\")\n .option(\"-m, --model <model>\", \"Model to use\", \"claude\")\n .argument(\"[message...]\", \"Message to send (or omit for interactive mode)\")\n .action(async (messageParts: string[], opts) => {\n const labId = await resolveLabId();\n const message = messageParts.join(\" \").trim();\n\n if (!message) {\n // Interactive mode — read from stdin\n console.log(chalk.bold(\"\\n Hubify Labs Chat\") + chalk.gray(` (${opts.model})`));\n console.log(chalk.gray(\" Type your message and press Enter. Ctrl+C to exit.\\n\"));\n\n const readline = await import(\"readline\");\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n\n const askQuestion = () => {\n rl.question(chalk.green(\" > \"), async (line: string) => {\n if (!line.trim()) { askQuestion(); return; }\n const spinner = ora(\"Thinking...\").start();\n try {\n const result = await actionConvex(\"functions/chat:sendMessage\", {\n labId,\n message: line.trim(),\n context: \"CLI terminal chat\",\n model: opts.model,\n mode: \"general\",\n });\n spinner.stop();\n const reply = typeof result === \"string\" ? result : (result as { content?: string })?.content ?? \"Done.\";\n console.log(chalk.cyan(\"\\n \" + reply.split(\"\\n\").join(\"\\n \")) + \"\\n\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n }\n askQuestion();\n });\n };\n askQuestion();\n return; // Keep process alive for interactive mode\n }\n\n // One-shot mode — send single message\n const spinner = ora(\"Sending to orchestrator...\").start();\n try {\n const result = await actionConvex(\"functions/chat:sendMessage\", {\n labId,\n message,\n context: \"CLI one-shot\",\n model: opts.model,\n mode: \"general\",\n });\n spinner.stop();\n const reply = typeof result === \"string\" ? result : (result as { content?: string })?.content ?? \"Message sent.\";\n console.log(chalk.cyan(\"\\n \" + reply.split(\"\\n\").join(\"\\n \")) + \"\\n\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── auth ─────────────────────────────────────────────────────\n\nconst BASE_URL = process.env.HUBIFY_API_URL ?? \"https://hubify.com\";\nconst POLL_INTERVAL_MS = 2000;\nconst MAX_POLL_ATTEMPTS = 150; // 5 minutes\n\nprogram\n .command(\"auth\")\n .description(\"Authentication\")\n .argument(\"<action>\", \"login | logout | status\")\n .action(async (action: string) => {\n if (action === \"login\") {\n // ── Device Authorization Flow ─────────────────────────\n const spinner = ora(\"Starting authentication...\").start();\n\n let deviceCode: string;\n let userCode: string;\n let verificationUri: string;\n\n try {\n const res = await fetch(`${BASE_URL}/api/cli/auth/start`, { method: \"POST\" });\n if (!res.ok) {\n const body = await res.json().catch(() => ({}));\n throw new Error((body as { error?: string }).error ?? `HTTP ${res.status}`);\n }\n const data = await res.json() as {\n device_code: string;\n user_code: string;\n verification_uri: string;\n expires_in: number;\n interval: number;\n };\n deviceCode = data.device_code;\n userCode = data.user_code;\n verificationUri = data.verification_uri;\n } catch (err) {\n spinner.stop();\n console.error(formatError(`Failed to start auth: ${err instanceof Error ? err.message : String(err)}`));\n process.exit(1);\n }\n\n spinner.stop();\n\n console.log(chalk.bold(\"\\n Authorize Hubify CLI\\n\"));\n console.log(` ${chalk.gray(\"1.\")} Open this URL in your browser:\\n`);\n console.log(` ${chalk.cyan(verificationUri)}\\n`);\n console.log(` ${chalk.gray(\"2.\")} Enter this code when prompted:\\n`);\n console.log(` ${chalk.bold.white(userCode)}\\n`);\n\n // Open browser automatically\n const { exec } = await import(\"child_process\");\n if (process.platform === \"darwin\") exec(`open \"${verificationUri}\"`);\n else if (process.platform === \"linux\") exec(`xdg-open \"${verificationUri}\"`);\n else exec(`start \"${verificationUri}\"`);\n\n // ── Poll for token ────────────────────────────────────\n const pollSpinner = ora(\"Waiting for authorization in browser...\").start();\n let attempts = 0;\n\n while (attempts < MAX_POLL_ATTEMPTS) {\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));\n attempts++;\n\n try {\n const pollRes = await fetch(\n `${BASE_URL}/api/cli/auth/poll?device_code=${encodeURIComponent(deviceCode)}`,\n );\n const pollData = await pollRes.json() as {\n status: \"pending\" | \"authorized\" | \"expired\";\n token?: string;\n };\n\n if (pollData.status === \"authorized\" && pollData.token) {\n pollSpinner.stop();\n saveToken(pollData.token);\n console.log(formatSuccess(\"Authenticated! Your CLI is connected to Hubify Labs.\"));\n console.log(chalk.gray(` Token saved to ~/.hubify-labs/config\\n`));\n\n // Verify by listing labs\n try {\n const labs = (await mutateConvex(\"functions/cliAuth:listMyLabs\", {\n apiKey: pollData.token,\n })) as Array<{ name: string; slug: string }>;\n if (labs.length > 0) {\n console.log(chalk.gray(` Labs: ${labs.map((l) => l.name).join(\", \")}\\n`));\n }\n } catch { /* non-fatal */ }\n\n return;\n }\n\n if (pollData.status === \"expired\") {\n pollSpinner.stop();\n console.error(formatError(\"Authorization code expired. Run `hubify auth login` again.\"));\n process.exit(1);\n }\n\n // Still pending — update spinner\n const elapsed = Math.floor((attempts * POLL_INTERVAL_MS) / 1000);\n pollSpinner.text = `Waiting for browser authorization... (${elapsed}s)`;\n } catch {\n // Network blip — keep polling\n }\n }\n\n pollSpinner.stop();\n console.error(formatError(\"Timed out waiting for authorization. Run `hubify auth login` again.\"));\n process.exit(1);\n\n } else if (action === \"logout\") {\n clearToken();\n console.log(chalk.gray(\"\\n Logged out. Token removed from ~/.hubify-labs/config\\n\"));\n\n } else if (action === \"status\") {\n const token = getStoredToken();\n if (!token) {\n console.log(chalk.yellow(\"\\n Not authenticated. Run `hubify auth login`.\\n\"));\n return;\n }\n\n const spinner = ora(\"Verifying token...\").start();\n try {\n const labs = (await mutateConvex(\"functions/cliAuth:listMyLabs\", { apiKey: token })) as Array<{\n name: string;\n slug: string;\n }>;\n spinner.stop();\n console.log(chalk.green(\"\\n Authenticated.\"));\n if (labs.length > 0) {\n console.log(chalk.gray(` Labs: ${labs.map((l) => l.name).join(\", \")}`));\n }\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes(\"Invalid\") || message.includes(\"expired\")) {\n console.log(chalk.red(\"\\n Token invalid or expired. Run `hubify auth login` again.\\n\"));\n } else {\n console.log(chalk.yellow(`\\n Could not verify token: ${message}\\n`));\n }\n }\n\n } else {\n console.log(chalk.red(`\\n Unknown action: ${action}. Use login, logout, or status.\\n`));\n }\n });\n\n// ── Parse & Run ───────────────────────────────────────────────\n\n// ── tui ──────────────────────────────────────────────────────\n\nprogram\n .command(\"tui\")\n .description(\"Launch interactive 4-panel terminal UI\")\n .action(async () => {\n const { launchTui } = await import(\"./tui.js\");\n launchTui();\n });\n\n// ── site ──────────────────────────────────────────────────────\n\nconst siteCmd = program\n .command(\"site\")\n .description(\"Lab site management\");\n\nsiteCmd\n .command(\"status\")\n .description(\"Show lab site status and deploy info\")\n .action(async () => {\n const spinner = ora(\"Fetching site config...\").start();\n try {\n const labId = await resolveLabId();\n const config = await queryConvex(\"functions/siteConfig:getOrCreate\", { labId }) as any;\n spinner.stop();\n\n if (!config) {\n console.log(formatError(\"No site configured. Run `hubify-labs site deploy` to set up.\"));\n return;\n }\n\n if (isJsonOutput()) {\n console.log(JSON.stringify(config, null, 2));\n return;\n }\n\n console.log(sectionHeader(\"Lab Site\"));\n console.log(kvLine(\"Template\", config.template ?? \"none\"));\n console.log(kvLine(\"Pages\", (config.pages ?? []).join(\", \") || \"none\"));\n console.log(kvLine(\"Custom domain\", config.customDomain ?? \"none\"));\n console.log(kvLine(\"Last deployed\", config.deployedAt ? relativeTime(config.deployedAt) : \"never\"));\n if (config.heroTitle) console.log(kvLine(\"Hero title\", config.heroTitle));\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : \"Failed to fetch site config\"));\n }\n });\n\nsiteCmd\n .command(\"deploy\")\n .description(\"Deploy lab site to <slug>.hubify.app\")\n .action(async () => {\n const spinner = ora(\"Deploying lab site...\").start();\n try {\n const labId = await resolveLabId();\n await mutateConvex(\"functions/siteConfig:deploy\", { labId });\n spinner.stop();\n console.log(formatSuccess(\"Site deployed successfully.\"));\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : \"Deploy failed\"));\n }\n });\n\nsiteCmd\n .command(\"pages\")\n .description(\"List enabled site pages\")\n .action(async () => {\n const spinner = ora(\"Fetching pages...\").start();\n try {\n const labId = await resolveLabId();\n const config = await queryConvex(\"functions/siteConfig:getOrCreate\", { labId }) as any;\n spinner.stop();\n\n if (!config || !config.pages?.length) {\n console.log(\"No pages configured.\");\n return;\n }\n\n if (isJsonOutput()) {\n console.log(JSON.stringify({ pages: config.pages }, null, 2));\n return;\n }\n\n console.log(sectionHeader(\"Site Pages\"));\n (config.pages as string[]).forEach((page: string, i: number) => {\n console.log(` ${chalk.dim(`${i + 1}.`)} ${page}`);\n });\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : \"Failed\"));\n }\n });\n\n// ── backup ────────────────────────────────────────────────────\n\nprogram\n .command(\"backup\")\n .description(\"Trigger a lab backup\")\n .option(\"--type <type>\", \"Backup type: checkpoint | full | incremental\", \"checkpoint\")\n .action(async (opts) => {\n const spinner = ora(\"Starting backup...\").start();\n try {\n const labId = await resolveLabId();\n const id = await mutateConvex(\"functions/backups:create\", {\n labId,\n type: opts.type,\n description: `CLI backup (${opts.type})`,\n });\n spinner.stop();\n\n if (isJsonOutput()) {\n console.log(JSON.stringify({ id, type: opts.type, status: \"pending\" }, null, 2));\n return;\n }\n\n console.log(formatSuccess(`Backup started (${opts.type}). ID: ${id}`));\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : \"Backup failed\"));\n }\n });\n\n// ── learnings ─────────────────────────────────────────────────\n\nprogram\n .command(\"learnings\")\n .description(\"View agent learnings (operational and domain insights)\")\n .option(\"-n <count>\", \"Number of learnings to show\", \"20\")\n .option(\"--type <type>\", \"Filter by type: operational, domain, lab_state\")\n .option(\"--verified\", \"Show only verified learnings\")\n .action(async (opts) => {\n const spinner = ora(\"Fetching learnings...\").start();\n try {\n const labId = await resolveLabId();\n let learnings = await queryConvex(\"functions/agentLearnings:listByLab\", { labId }) as any[];\n\n if (opts.type) learnings = learnings.filter((l: any) => l.type === opts.type);\n if (opts.verified) learnings = learnings.filter((l: any) => l.verified);\n\n learnings = learnings.slice(0, parseInt(opts.n));\n spinner.stop();\n\n if (isJsonOutput()) {\n console.log(JSON.stringify({ learnings }, null, 2));\n return;\n }\n\n if (!learnings.length) {\n console.log(chalk.gray(\" No agent learnings yet. They accumulate as agents run experiments.\"));\n return;\n }\n\n console.log(sectionHeader(`Agent Learnings (${learnings.length})`));\n learnings.forEach((l: any) => {\n const typeColor = l.type === \"operational\" ? chalk.blue : l.type === \"domain\" ? chalk.green : chalk.yellow;\n const verified = l.verified ? chalk.green(\" ✓\") : \"\";\n console.log(` ${typeColor(l.type ?? \"??\")} ${chalk.bold(l.key)}${verified}`);\n console.log(` ${chalk.dim(l.insight?.slice(0, 120) ?? \"\")}`);\n console.log(` ${chalk.dim(`confidence: ${Math.round((l.confidence ?? 0) * 100)}% · used ${l.useCount ?? 0}x`)}`);\n });\n if (learnings.length === parseInt(opts.n)) {\n console.log(chalk.dim(` (showing ${opts.n}, may be more)`));\n }\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : \"Failed\"));\n }\n });\n\n// ── memory ────────────────────────────────────────────────────\n\nprogram\n .command(\"memory\")\n .description(\"View the 4-layer memory system: user, agent, lab, decisions\")\n .option(\"--layer <layer>\", \"Layer: user, agent, lab, decisions (default: all)\")\n .option(\"-n <count>\", \"Max items per layer\", \"10\")\n .action(async (opts) => {\n const spinner = ora(\"Fetching memory...\").start();\n try {\n const labId = await resolveLabId();\n const limit = parseInt(opts.n);\n const layer = opts.layer ?? \"all\";\n\n const [messages, prefs, learnings, knowledge, decisions] = await Promise.all([\n layer === \"all\" || layer === \"user\" ? queryConvex(\"functions/userMemory:listMessages\", { labId, limit }) as Promise<any[]> : Promise.resolve([]),\n layer === \"all\" || layer === \"user\" ? queryConvex(\"functions/userMemory:getPreferences\", { labId }) as Promise<any[]> : Promise.resolve([]),\n layer === \"all\" || layer === \"agent\" ? queryConvex(\"functions/agentLearnings:listByLab\", { labId }) as Promise<any[]> : Promise.resolve([]),\n layer === \"all\" || layer === \"lab\" ? queryConvex(\"functions/knowledge:listByLab\", { labId }) as Promise<any[]> : Promise.resolve([]),\n layer === \"all\" || layer === \"decisions\" ? queryConvex(\"functions/labDecisions:listByLab\", { labId }) as Promise<any[]> : Promise.resolve([]),\n ]);\n\n spinner.stop();\n\n if (isJsonOutput()) {\n console.log(JSON.stringify({ messages, prefs, learnings, knowledge, decisions }, null, 2));\n return;\n }\n\n if (layer === \"all\" || layer === \"user\") {\n console.log(sectionHeader(`User Memory — Preferences (${prefs.length})`));\n prefs.slice(0, limit).forEach((p: any) => {\n console.log(` ${chalk.cyan(p.key)} = ${p.value}`);\n });\n console.log(sectionHeader(`User Memory — Messages (${messages.length})`));\n messages.slice(0, limit).forEach((m: any) => {\n console.log(` ${chalk.dim(new Date(m.createdAt).toLocaleDateString())} ${m.content.slice(0, 100)}`);\n });\n }\n\n if (layer === \"all\" || layer === \"agent\") {\n console.log(sectionHeader(`Agent Learnings (${learnings.length})`));\n learnings.slice(0, limit).forEach((l: any) => {\n const verified = l.verified ? chalk.green(\" ✓\") : \"\";\n console.log(` ${chalk.blue(l.type ?? \"?\")} ${chalk.bold(l.key)}${verified} — ${chalk.dim(l.insight?.slice(0, 80) ?? \"\")}`);\n });\n }\n\n if (layer === \"all\" || layer === \"lab\") {\n console.log(sectionHeader(`Lab Knowledge (${knowledge.length})`));\n knowledge.slice(0, limit).forEach((k: any) => {\n console.log(` ${chalk.yellow(k.entityType ?? \"concept\")} ${chalk.bold(k.name)}`);\n if (k.description) console.log(` ${chalk.dim(k.description.slice(0, 80))}`);\n });\n }\n\n if (layer === \"all\" || layer === \"decisions\") {\n console.log(sectionHeader(`Decisions (${decisions.length})`));\n decisions.slice(0, limit).forEach((d: any) => {\n const reversed = d.reversedAt ? chalk.red(\" [REVERSED]\") : \"\";\n console.log(` ${chalk.bold(d.title)}${reversed}`);\n console.log(` ${chalk.dim(d.decision?.slice(0, 80) ?? \"\")}`);\n });\n }\n\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── activity ──────────────────────────────────────────────────\n\nprogram\n .command(\"activity\")\n .description(\"Show recent lab activity feed\")\n .option(\"-n <count>\", \"Number of entries\", \"15\")\n .action(async (opts) => {\n const spinner = ora(\"Fetching activity...\").start();\n try {\n const labId = await resolveLabId();\n const activity = await queryConvex(\"functions/activity:listByLab\", { labId }) as any[];\n spinner.stop();\n\n if (isJsonOutput()) {\n console.log(JSON.stringify({ activity: activity.slice(0, parseInt(opts.n)) }, null, 2));\n return;\n }\n\n if (!activity.length) {\n console.log(\"No activity yet.\");\n return;\n }\n\n console.log(sectionHeader(\"Recent Activity\"));\n activity.slice(0, parseInt(opts.n)).forEach((a: any) => {\n const severity = a.severity === \"error\" ? chalk.red(\"!\") :\n a.severity === \"warn\" ? chalk.yellow(\"!\") :\n a.severity === \"success\" ? chalk.green(\"✓\") : chalk.dim(\"·\");\n console.log(` ${severity} ${chalk.dim(relativeTime(a.createdAt))} ${a.title}`);\n if (a.description) console.log(` ${chalk.dim(a.description.slice(0, 100))}`);\n });\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : \"Failed\"));\n }\n });\n\n// ── costs ─────────────────────────────────────────────────────\n\nprogram\n .command(\"costs\")\n .description(\"Show lab cost summary and per-experiment breakdown\")\n .option(\"--top <n>\", \"Show top N most expensive experiments\", \"10\")\n .action(async (opts) => {\n const spinner = ora(\"Fetching cost data...\").start();\n try {\n const labId = await resolveLabId();\n const [costs, summary] = await Promise.all([\n queryConvex(\"functions/experimentCosts:listByLab\", { labId }) as Promise<Array<{\n _id: string;\n experimentId?: string;\n costUsd: number;\n computeMode?: string;\n gpuType?: string;\n durationSeconds?: number;\n createdAt: number;\n }>>,\n queryConvex(\"functions/experimentCosts:labSummary\", { labId }) as Promise<{\n totalCostUsd: number;\n byMode?: Record<string, number>;\n byGpu?: Record<string, number>;\n } | null>,\n ]);\n\n spinner.stop();\n\n if (isJsonOutput()) {\n console.log(JSON.stringify({ summary, costs }, null, 2));\n return;\n }\n\n const total = summary?.totalCostUsd ?? 0;\n console.log(sectionHeader(\"Lab Costs\"));\n console.log(kvLine(\"Total spend\", `$${total.toFixed(2)}`));\n\n if (summary?.byMode && Object.keys(summary.byMode).length > 0) {\n console.log(sectionHeader(\"By Compute Mode\"));\n for (const [mode, cost] of Object.entries(summary.byMode)) {\n console.log(kvLine(` ${mode}`, `$${(cost as number).toFixed(2)}`));\n }\n }\n\n if (summary?.byGpu && Object.keys(summary.byGpu).length > 0) {\n console.log(sectionHeader(\"By GPU Type\"));\n for (const [gpu, cost] of Object.entries(summary.byGpu)) {\n console.log(kvLine(` ${gpu}`, `$${(cost as number).toFixed(2)}`));\n }\n }\n\n const topN = parseInt(opts.top);\n const topCosts = costs.slice(0, topN);\n if (topCosts.length > 0) {\n console.log(sectionHeader(`Top ${topN} Most Expensive`));\n console.log(\n formatTable(topCosts as unknown as Record<string, unknown>[], [\n { header: \"Experiment\", key: \"experimentId\", width: 16, format: (v) => v ? String(v) : chalk.gray(\"—\") },\n { header: \"Cost\", key: \"costUsd\", width: 10, align: \"right\", format: (v) => `$${Number(v).toFixed(2)}` },\n { header: \"GPU\", key: \"gpuType\", width: 10, format: (v) => v ? String(v) : chalk.gray(\"—\") },\n {\n header: \"Duration\",\n key: \"durationSeconds\",\n width: 10,\n align: \"right\",\n format: (v) => {\n if (!v) return chalk.gray(\"-\");\n const s = Number(v);\n if (s < 60) return `${s}s`;\n if (s < 3600) return `${Math.floor(s / 60)}m`;\n return `${(s / 3600).toFixed(1)}h`;\n },\n },\n ])\n );\n }\n\n if (costs.length === 0) {\n console.log(chalk.gray(\" No cost data yet. Costs are logged when experiments complete.\"));\n }\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── notifications ─────────────────────────────────────────────\n\nprogram\n .command(\"notifications\")\n .description(\"Show recent lab notifications\")\n .option(\"-n <count>\", \"Number of notifications to show\", \"20\")\n .option(\"--unread\", \"Show only unread notifications\")\n .action(async (opts) => {\n const spinner = ora(\"Fetching notifications...\").start();\n try {\n const labId = await resolveLabId();\n const notifications = (await queryConvex(\"functions/notifications:listByLab\", { labId })) as Array<{\n _id: string;\n type: string;\n title: string;\n description?: string;\n severity: string;\n read: boolean;\n createdAt: number;\n }>;\n\n spinner.stop();\n\n let filtered = notifications;\n if (opts.unread) {\n filtered = notifications.filter((n) => !n.read);\n }\n\n if (isJsonOutput()) {\n console.log(JSON.stringify({ notifications: filtered.slice(0, parseInt(opts.n)) }, null, 2));\n return;\n }\n\n if (filtered.length === 0) {\n console.log(chalk.gray(opts.unread ? \" No unread notifications.\" : \" No notifications.\"));\n return;\n }\n\n const unreadCount = notifications.filter((n) => !n.read).length;\n console.log(sectionHeader(`Notifications (${filtered.length}${unreadCount > 0 ? `, ${unreadCount} unread` : \"\"})`));\n filtered.slice(0, parseInt(opts.n)).forEach((n) => {\n const icon = n.severity === \"error\" ? chalk.red(\"✗\") :\n n.severity === \"warn\" ? chalk.yellow(\"!\") :\n n.severity === \"success\" ? chalk.green(\"✓\") : chalk.dim(\"·\");\n const readMark = n.read ? chalk.dim(\" \") : chalk.cyan(\"●\");\n console.log(` ${readMark} ${icon} ${chalk.dim(relativeTime(n.createdAt))} ${n.title}`);\n if (n.description) console.log(` ${chalk.dim(n.description.slice(0, 100))}`);\n });\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── contributions ─────────────────────────────────────────────\n\nprogram\n .command(\"contributions\")\n .description(\"List scientific contributions with novelty scores\")\n .option(\"-n <count>\", \"Number to show\", \"20\")\n .action(async (opts) => {\n const spinner = ora(\"Fetching contributions...\").start();\n try {\n const labId = await resolveLabId();\n const contributions = (await queryConvex(\"functions/contributions:listByLab\", { labId })) as Array<{\n _id: string;\n title: string;\n type: string;\n noveltyScore?: number;\n summary?: string;\n paperId?: string;\n createdAt: number;\n }>;\n\n spinner.stop();\n\n if (isJsonOutput()) {\n console.log(JSON.stringify({ contributions: contributions.slice(0, parseInt(opts.n)) }, null, 2));\n return;\n }\n\n if (!contributions.length) {\n console.log(chalk.gray(\" No contributions yet. Add from the Papers view.\"));\n return;\n }\n\n const sorted = [...contributions].sort((a, b) => (b.noveltyScore ?? 0) - (a.noveltyScore ?? 0));\n\n console.log(sectionHeader(`Contributions (${sorted.length})`));\n sorted.slice(0, parseInt(opts.n)).forEach((c) => {\n // noveltyScore is 0-100; display as X.X/10\n const scoreNum = c.noveltyScore != null ? (c.noveltyScore / 10).toFixed(1) : null;\n const score = scoreNum != null ? chalk.green(`[${scoreNum}/10]`) : chalk.dim(\"[?/10]\");\n const type = chalk.dim(`(${c.type})`);\n console.log(` ${score} ${c.title} ${type}`);\n if (c.summary) console.log(` ${chalk.dim(c.summary.slice(0, 100))}`);\n });\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── surveys ──────────────────────────────────────────────────\n\nprogram\n .command(\"surveys\")\n .description(\"List surveys with source and anomaly counts\")\n .option(\"-n <count>\", \"Number to show\", \"20\")\n .option(\"--qc <status>\", \"Filter by QC status: pass, warn, fail\")\n .action(async (opts) => {\n const spinner = ora(\"Fetching surveys...\").start();\n try {\n const labId = await resolveLabId();\n const surveys = (await queryConvex(\"functions/surveys:listByLab\", { labId })) as Array<{\n _id: string;\n name: string;\n type?: string;\n sourceCount: number;\n anomalyCount: number;\n qcStatus?: string;\n qcExplanation?: string;\n result?: string;\n }>;\n\n spinner.stop();\n\n if (isJsonOutput()) {\n console.log(JSON.stringify({ surveys: surveys.slice(0, parseInt(opts.n)) }, null, 2));\n return;\n }\n\n if (!surveys.length) {\n console.log(chalk.gray(\" No surveys yet.\"));\n return;\n }\n\n let filtered = surveys;\n if (opts.qc) {\n filtered = surveys.filter((s) => s.qcStatus === opts.qc);\n }\n\n const qcColor = (qc: string | undefined) => {\n if (!qc) return chalk.dim(\"N/A\");\n if (qc === \"pass\") return chalk.green(qc.toUpperCase());\n if (qc === \"warn\") return chalk.yellow(qc.toUpperCase());\n return chalk.red(qc.toUpperCase());\n };\n\n console.log(sectionHeader(`Surveys (${filtered.length})`));\n filtered.slice(0, parseInt(opts.n)).forEach((s) => {\n const sources = chalk.cyan((s.sourceCount ?? 0).toLocaleString());\n const anomalies = chalk.yellow((s.anomalyCount ?? 0).toLocaleString());\n const rate = (s.sourceCount ?? 0) > 0 ? (((s.anomalyCount ?? 0) / s.sourceCount) * 100).toFixed(2) + \"%\" : \"—\";\n console.log(\n ` [${qcColor(s.qcStatus)}] ${s.name} — ${sources} sources · ${anomalies} anomalies (${chalk.dim(rate)})`,\n );\n if (s.result) console.log(` ${chalk.dim(s.result.slice(0, 100))}`);\n });\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── tasks ─────────────────────────────────────────────────────\n\nprogram\n .command(\"tasks\")\n .description(\"List tasks by status and priority\")\n .option(\"-n <count>\", \"Number to show\", \"30\")\n .option(\"--status <status>\", \"Filter by status: backlog, todo, in_progress, review, done\")\n .option(\"--priority <priority>\", \"Filter by priority: urgent, high, medium, low\")\n .option(\"--assignee <name>\", \"Filter by assignee name\")\n .action(async (opts) => {\n const spinner = ora(\"Fetching tasks...\").start();\n try {\n const labId = await resolveLabId();\n const tasks = (await queryConvex(\"functions/tasks:listByLab\", { labId })) as Array<{\n _id: string;\n title: string;\n status: string;\n priority: string;\n assignedTo?: string;\n dueDate?: number;\n description?: string;\n createdAt: number;\n }>;\n\n spinner.stop();\n\n if (isJsonOutput()) {\n console.log(JSON.stringify({ tasks: tasks.slice(0, parseInt(opts.n)) }, null, 2));\n return;\n }\n\n if (!tasks.length) {\n console.log(chalk.gray(\" No tasks yet.\"));\n return;\n }\n\n let filtered = tasks;\n if (opts.status) filtered = filtered.filter((t) => t.status === opts.status);\n if (opts.priority) filtered = filtered.filter((t) => t.priority === opts.priority);\n if (opts.assignee) {\n const q = opts.assignee.toLowerCase();\n filtered = filtered.filter((t) => t.assignedTo?.toLowerCase().includes(q));\n }\n\n const priorityColor = (p: string) => {\n if (p === \"urgent\") return chalk.red(p.toUpperCase());\n if (p === \"high\") return chalk.yellow(p.toUpperCase());\n if (p === \"medium\") return chalk.cyan(p.toUpperCase());\n return chalk.dim(p.toUpperCase());\n };\n\n const statusColor = (s: string) => {\n if (s === \"done\") return chalk.green(s);\n if (s === \"in_progress\") return chalk.cyan(s);\n if (s === \"review\") return chalk.yellow(s);\n if (s === \"todo\") return chalk.white(s);\n return chalk.dim(s);\n };\n\n const statusOrder: Record<string, number> = { in_progress: 0, review: 1, todo: 2, backlog: 3, done: 4 };\n const priorityOrder: Record<string, number> = { urgent: 0, high: 1, medium: 2, low: 3 };\n filtered.sort((a, b) => {\n const so = (statusOrder[a.status] ?? 5) - (statusOrder[b.status] ?? 5);\n if (so !== 0) return so;\n return (priorityOrder[a.priority] ?? 5) - (priorityOrder[b.priority] ?? 5);\n });\n\n const counts = { in_progress: 0, review: 0, todo: 0, backlog: 0, done: 0 } as Record<string, number>;\n for (const t of filtered) counts[t.status] = (counts[t.status] ?? 0) + 1;\n const summary = Object.entries(counts)\n .filter(([, v]) => v > 0)\n .map(([k, v]) => `${v} ${k.replace(\"_\", \" \")}`)\n .join(\" · \");\n\n console.log(sectionHeader(`Tasks (${filtered.length}) — ${summary}`));\n filtered.slice(0, parseInt(opts.n)).forEach((t) => {\n const due = t.dueDate ? chalk.dim(` due ${relativeTime(t.dueDate)}`) : \"\";\n const assignee = t.assignedTo ? chalk.dim(` @${t.assignedTo}`) : \"\";\n console.log(\n ` [${priorityColor(t.priority)}] [${statusColor(t.status)}] ${t.title}${assignee}${due}`,\n );\n });\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\n// ── datasets ───────────────────────────────────────────────────\n\nprogram\n .command(\"datasets\")\n .description(\"List scientific datasets in the lab\")\n .option(\"-n <count>\", \"Number to show\", \"30\")\n .option(\"--type <type>\", \"Filter by type: public, internal, generated, external\")\n .option(\"--source <source>\", \"Filter by source (partial match)\")\n .action(async (opts) => {\n const spinner = ora(\"Fetching datasets...\").start();\n try {\n const labId = await resolveLabId();\n const datasets = (await queryConvex(\"functions/datasets:listByLab\", { labId })) as Array<{\n _id: string;\n name: string;\n type?: string;\n source?: string;\n description?: string;\n sizeBytes?: number;\n recordCount?: number;\n format?: string;\n tags?: string[];\n createdAt?: number;\n }>;\n\n spinner.stop();\n\n if (isJsonOutput()) {\n console.log(JSON.stringify({ datasets: datasets.slice(0, parseInt(opts.n)) }, null, 2));\n return;\n }\n\n if (!datasets.length) {\n console.log(chalk.gray(\" No datasets yet.\"));\n return;\n }\n\n let filtered = datasets;\n if (opts.type) filtered = filtered.filter((d) => d.type === opts.type);\n if (opts.source) {\n const q = opts.source.toLowerCase();\n filtered = filtered.filter((d) => d.source?.toLowerCase().includes(q) || d.name.toLowerCase().includes(q));\n }\n\n const formatBytes = (b: number | undefined) => {\n if (!b) return \"—\";\n if (b >= 1e12) return `${(b / 1e12).toFixed(1)}TB`;\n if (b >= 1e9) return `${(b / 1e9).toFixed(1)}GB`;\n if (b >= 1e6) return `${(b / 1e6).toFixed(1)}MB`;\n return `${(b / 1e3).toFixed(0)}KB`;\n };\n\n console.log(sectionHeader(`Datasets (${filtered.length})`));\n filtered.slice(0, parseInt(opts.n)).forEach((d) => {\n const size = formatBytes(d.sizeBytes);\n const records = d.recordCount ? chalk.cyan(`${d.recordCount.toLocaleString()} records`) : \"\";\n const source = d.source ? chalk.dim(` · ${d.source}`) : \"\";\n const typeTag = d.type ? chalk.dim(`[${d.type}] `) : \"\";\n console.log(` ${typeTag}${d.name}${source}`);\n if (records || size !== \"—\") {\n console.log(` ${records}${records && size !== \"—\" ? \" · \" : \"\"}${size !== \"—\" ? chalk.dim(size) : \"\"}`);\n }\n if (d.description) {\n console.log(` ${chalk.dim(d.description.slice(0, 100))}`);\n }\n });\n console.log(\"\");\n } catch (err) {\n spinner.stop();\n console.error(formatError(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n }\n });\n\nprogram.parse();\n","/**\n * Output formatting utilities for the CLI.\n * Colored status badges, tables, and progress bars.\n */\n\nimport chalk from \"chalk\";\n\n// ── Status Badges ─────────────────────────────────────────────\n\nconst experimentStatusColors: Record<string, (text: string) => string> = {\n queued: chalk.yellow,\n running: chalk.cyan,\n pass: chalk.green,\n fail: chalk.red,\n blocked: chalk.gray,\n};\n\nconst agentStatusColors: Record<string, (text: string) => string> = {\n active: chalk.green,\n idle: chalk.yellow,\n busy: chalk.cyan,\n retired: chalk.gray,\n};\n\nconst paperStatusColors: Record<string, (text: string) => string> = {\n draft: chalk.yellow,\n review: chalk.cyan,\n submitted: chalk.blue,\n published: chalk.green,\n};\n\nconst podStatusColors: Record<string, (text: string) => string> = {\n creating: chalk.yellow,\n running: chalk.green,\n stopped: chalk.gray,\n terminated: chalk.red,\n};\n\nexport function experimentBadge(status: string): string {\n const colorFn = experimentStatusColors[status] ?? chalk.white;\n const icon = status === \"pass\" ? \"+\" : status === \"fail\" ? \"x\" : status === \"running\" ? \">\" : status === \"queued\" ? \"~\" : \"-\";\n return colorFn(`[${icon} ${status.toUpperCase()}]`);\n}\n\nexport function agentBadge(status: string): string {\n const colorFn = agentStatusColors[status] ?? chalk.white;\n const icon = status === \"active\" ? \"*\" : status === \"busy\" ? \">\" : status === \"idle\" ? \"~\" : \"-\";\n return colorFn(`[${icon} ${status.toUpperCase()}]`);\n}\n\nexport function paperBadge(status: string): string {\n const colorFn = paperStatusColors[status] ?? chalk.white;\n return colorFn(`[${status.toUpperCase()}]`);\n}\n\nexport function podBadge(status: string): string {\n const colorFn = podStatusColors[status] ?? chalk.white;\n return colorFn(`[${status.toUpperCase()}]`);\n}\n\n// ── Readiness Progress Bar ────────────────────────────────────\n\nexport function readinessBar(percent: number, width: number = 20): string {\n const filled = Math.round((percent / 100) * width);\n const empty = width - filled;\n const bar = chalk.green(\"=\".repeat(filled)) + chalk.gray(\"-\".repeat(empty));\n const pctStr =\n percent >= 95\n ? chalk.green.bold(`${percent}%`)\n : percent >= 70\n ? chalk.yellow(`${percent}%`)\n : chalk.red(`${percent}%`);\n return `[${bar}] ${pctStr}`;\n}\n\n// ── Table Formatting ──────────────────────────────────────────\n\ninterface Column {\n header: string;\n key: string;\n width?: number;\n align?: \"left\" | \"right\";\n format?: (value: unknown) => string;\n}\n\nexport function formatTable(rows: Record<string, unknown>[], columns: Column[]): string {\n if (rows.length === 0) return chalk.gray(\" (no results)\");\n\n // Calculate column widths\n const widths = columns.map((col) => {\n const headerLen = col.header.length;\n const maxDataLen = rows.reduce((max, row) => {\n const val = col.format ? col.format(row[col.key]) : String(row[col.key] ?? \"\");\n // Strip ANSI codes for width calculation\n const clean = val.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n return Math.max(max, clean.length);\n }, 0);\n return col.width ?? Math.max(headerLen, Math.min(maxDataLen, 50));\n });\n\n // Header\n const headerLine = columns\n .map((col, i) => chalk.bold(col.header.padEnd(widths[i])))\n .join(\" \");\n const separator = columns\n .map((_col, i) => chalk.gray(\"-\".repeat(widths[i])))\n .join(\" \");\n\n // Rows\n const dataLines = rows.map((row) =>\n columns\n .map((col, i) => {\n const val = col.format ? col.format(row[col.key]) : String(row[col.key] ?? \"\");\n const clean = val.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n const padding = Math.max(0, widths[i] - clean.length);\n if (col.align === \"right\") {\n return \" \".repeat(padding) + val;\n }\n return val + \" \".repeat(padding);\n })\n .join(\" \")\n );\n\n return [headerLine, separator, ...dataLines].join(\"\\n\");\n}\n\n// ── Section Headers ───────────────────────────────────────────\n\nexport function sectionHeader(title: string): string {\n return `\\n${chalk.bold.underline(title)}\\n`;\n}\n\nexport function subHeader(title: string): string {\n return chalk.bold(title);\n}\n\n// ── Key-Value Display ─────────────────────────────────────────\n\nexport function kvLine(key: string, value: string | number, keyWidth: number = 16): string {\n return ` ${chalk.gray(key.padEnd(keyWidth))} ${value}`;\n}\n\n// ── Relative Time ─────────────────────────────────────────────\n\nexport function relativeTime(timestamp: number): string {\n const diff = Date.now() - timestamp;\n const seconds = Math.floor(diff / 1000);\n if (seconds < 60) return \"just now\";\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\n// ── Welcome Banner ────────────────────────────────────────────\n\nexport function welcomeBanner(): string {\n return [\n \"\",\n chalk.bold(\" Hubify Labs CLI\"),\n chalk.gray(\" Scientific Discovery Platform\"),\n \"\",\n chalk.gray(\" Run \") + chalk.cyan(\"hubify-labs --help\") + chalk.gray(\" for all commands.\"),\n chalk.gray(\" Run \") + chalk.cyan(\"hubify-labs status\") + chalk.gray(\" to see your lab.\"),\n \"\",\n ].join(\"\\n\");\n}\n\n// ── Error Display ─────────────────────────────────────────────\n\nexport function formatError(message: string): string {\n return chalk.red(` Error: ${message}`);\n}\n\nexport function formatSuccess(message: string): string {\n return chalk.green(` ${message}`);\n}\n\n// ── CSV Formatter ──────────────────────────────────────────────\n\n/**\n * Convert an array of objects to CSV string.\n * Uses the keys of the first object as headers.\n */\nexport function formatCsv(rows: Record<string, unknown>[]): string {\n if (rows.length === 0) return \"\";\n const headers = Object.keys(rows[0]);\n const escape = (val: unknown): string => {\n const s = String(val ?? \"\");\n return s.includes(\",\") || s.includes('\"') || s.includes(\"\\n\")\n ? `\"${s.replace(/\"/g, '\"\"')}\"`\n : s;\n };\n const lines = [\n headers.join(\",\"),\n ...rows.map((row) => headers.map((h) => escape(row[h])).join(\",\")),\n ];\n return lines.join(\"\\n\");\n}\n"],"mappings":"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","names":["labs","chalk","chalk","spinner","launchTui"]}
|
package/package.json
CHANGED
|
@@ -1,67 +1,58 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hubify",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "Hubify Labs CLI — drive your research lab from the terminal (36 commands)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"hubify": "dist/index.js"
|
|
7
|
+
"hubify": "./dist/index.js",
|
|
8
|
+
"hubify-labs": "./dist/index.js"
|
|
8
9
|
},
|
|
9
|
-
"main": "./dist/index.js",
|
|
10
|
-
"exports": {
|
|
11
|
-
".": "./dist/index.js"
|
|
12
|
-
},
|
|
13
|
-
"files": [
|
|
14
|
-
"dist/",
|
|
15
|
-
"README.md",
|
|
16
|
-
"LICENSE"
|
|
17
|
-
],
|
|
18
10
|
"scripts": {
|
|
19
11
|
"build": "tsup",
|
|
20
12
|
"dev": "tsup --watch",
|
|
21
13
|
"typecheck": "tsc --noEmit",
|
|
22
|
-
"
|
|
23
|
-
"prepublishOnly": "npx tsup"
|
|
24
|
-
},
|
|
25
|
-
"dependencies": {
|
|
26
|
-
"@anthropic-ai/sdk": "^0.72.1",
|
|
27
|
-
"chalk": "^5.3.0",
|
|
28
|
-
"commander": "^12.1.0",
|
|
29
|
-
"convex": "^1.17.4",
|
|
30
|
-
"dotenv": "^16.4.7",
|
|
31
|
-
"e2b": "^1.0.0",
|
|
32
|
-
"fflate": "^0.8.2",
|
|
33
|
-
"ora": "^8.1.1",
|
|
34
|
-
"yaml": "^2.6.1"
|
|
35
|
-
},
|
|
36
|
-
"devDependencies": {
|
|
37
|
-
"@hubify/shared": "workspace:*",
|
|
38
|
-
"@types/node": "^22.10.5",
|
|
39
|
-
"tsup": "^8.3.5",
|
|
40
|
-
"tsx": "^4.19.2",
|
|
41
|
-
"typescript": "^5.7.2"
|
|
14
|
+
"postinstall": "node ./scripts/postinstall.mjs 2>/dev/null || true"
|
|
42
15
|
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"skill",
|
|
19
|
+
"scripts",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
43
22
|
"keywords": [
|
|
44
23
|
"hubify",
|
|
24
|
+
"research",
|
|
25
|
+
"science",
|
|
45
26
|
"ai",
|
|
46
27
|
"agents",
|
|
47
|
-
"
|
|
48
|
-
"collective-intelligence",
|
|
28
|
+
"experiments",
|
|
49
29
|
"cli",
|
|
50
|
-
"
|
|
51
|
-
"singularity"
|
|
30
|
+
"lab"
|
|
52
31
|
],
|
|
53
|
-
"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@types/react": "^19.2.14",
|
|
34
|
+
"chalk": "^5.4.1",
|
|
35
|
+
"commander": "^13.1.0",
|
|
36
|
+
"convex": "^1.35.1",
|
|
37
|
+
"dotenv": "^16.5.0",
|
|
38
|
+
"ink": "^7.0.0",
|
|
39
|
+
"ink-text-input": "^6.0.0",
|
|
40
|
+
"ora": "^8.2.0",
|
|
41
|
+
"react": "^19.2.5"
|
|
59
42
|
},
|
|
60
|
-
"
|
|
61
|
-
|
|
62
|
-
"
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^22.15.3",
|
|
45
|
+
"tsup": "^8.4.0",
|
|
46
|
+
"typescript": "^5.8.3"
|
|
63
47
|
},
|
|
64
48
|
"engines": {
|
|
65
|
-
"node": ">=
|
|
49
|
+
"node": ">=18"
|
|
50
|
+
},
|
|
51
|
+
"author": "Houston Golden <houston@hubify.com>",
|
|
52
|
+
"license": "MIT",
|
|
53
|
+
"homepage": "https://hubify.com",
|
|
54
|
+
"repository": {
|
|
55
|
+
"type": "git",
|
|
56
|
+
"url": "https://github.com/houstongolden/hubify"
|
|
66
57
|
}
|
|
67
58
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Hubify postinstall — deploys the Claude Code skill to ~/.claude/skills/hubify/
|
|
4
|
+
* Runs automatically after: npm install -g hubify-labs
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync } from "fs";
|
|
7
|
+
import { join } from "path";
|
|
8
|
+
import { homedir } from "os";
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
10
|
+
import { dirname } from "path";
|
|
11
|
+
|
|
12
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const HOME = homedir();
|
|
14
|
+
|
|
15
|
+
// Skill destination: ~/.claude/skills/hubify/
|
|
16
|
+
const skillDir = join(HOME, ".claude", "skills", "hubify");
|
|
17
|
+
const skillDest = join(skillDir, "SKILL.md");
|
|
18
|
+
const skillSrc = join(__dirname, "..", "skill", "SKILL.md");
|
|
19
|
+
|
|
20
|
+
// Only run in global install context
|
|
21
|
+
const isGlobal = process.env.npm_config_global === "true";
|
|
22
|
+
|
|
23
|
+
function installSkill() {
|
|
24
|
+
try {
|
|
25
|
+
if (!existsSync(skillSrc)) {
|
|
26
|
+
console.log("hubify: skill file not found, skipping skill install");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
mkdirSync(skillDir, { recursive: true });
|
|
31
|
+
copyFileSync(skillSrc, skillDest);
|
|
32
|
+
|
|
33
|
+
console.log("\n✓ Hubify CLI skill installed to ~/.claude/skills/hubify/SKILL.md");
|
|
34
|
+
console.log(" Claude Code and Cursor will now automatically know your hubify commands.");
|
|
35
|
+
console.log("\n To activate in your project, add to CLAUDE.md:");
|
|
36
|
+
console.log(" ## Hubify CLI");
|
|
37
|
+
console.log(" The hubify CLI is installed. Use hubify commands for all lab data.\n");
|
|
38
|
+
} catch (err) {
|
|
39
|
+
// Non-fatal: skill install is optional
|
|
40
|
+
console.log("hubify: could not install skill (optional):", err.message);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function updateUserClaude() {
|
|
45
|
+
// Also append to ~/.claude/CLAUDE.md if it exists
|
|
46
|
+
const userClaudeMd = join(HOME, ".claude", "CLAUDE.md");
|
|
47
|
+
if (!existsSync(userClaudeMd)) return;
|
|
48
|
+
|
|
49
|
+
const content = readFileSync(userClaudeMd, "utf8");
|
|
50
|
+
if (content.includes("hubify CLI")) return; // already added
|
|
51
|
+
|
|
52
|
+
const snippet = `
|
|
53
|
+
## Hubify CLI
|
|
54
|
+
|
|
55
|
+
The hubify CLI is installed globally. When the user asks about experiments, papers,
|
|
56
|
+
agents, compute, costs, knowledge, or lab status — use hubify commands to get real
|
|
57
|
+
data before answering. Do not guess — run the command.
|
|
58
|
+
|
|
59
|
+
Available commands: hubify status | experiments | papers | reviews | agents | activity |
|
|
60
|
+
pods | costs | knowledge | memory | learnings | contributions | surveys | datasets |
|
|
61
|
+
figures | tasks | notifications | lab | labs | site | backup | chat | queue |
|
|
62
|
+
standups | search | auth | tui
|
|
63
|
+
|
|
64
|
+
Skill reference: ~/.claude/skills/hubify/SKILL.md
|
|
65
|
+
`;
|
|
66
|
+
|
|
67
|
+
writeFileSync(userClaudeMd, content + snippet);
|
|
68
|
+
console.log(" ✓ Also added hubify reference to ~/.claude/CLAUDE.md");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
installSkill();
|
|
72
|
+
updateUserClaude();
|