import { existsSync, readFileSync } from "node:fs"; import { join } from "node:path"; import { spawnSafe } from "@uncaged/nerve-workflow-utils"; import { buildSenseGenerator } from "./build.js"; // --- Environment --- const HOME = process.env.HOME ?? "/home/azureuser"; const NERVE_ROOT = join(HOME, ".uncaged-nerve"); const SENSES_DIR = join(NERVE_ROOT, "senses"); // --- Resolve provider --- async function cfgGet(key: string): Promise { const result = await spawnSafe("cfg", ["get", key], { cwd: NERVE_ROOT, env: null, timeoutMs: 10_000, }); if (!result.ok) return null; return result.value.stdout.trim() || null; } const apiKey = process.env.DASHSCOPE_API_KEY ?? (await cfgGet("DASHSCOPE_API_KEY")); const baseUrl = process.env.DASHSCOPE_BASE_URL ?? (await cfgGet("DASHSCOPE_BASE_URL")); const model = process.env.DASHSCOPE_MODEL ?? (await cfgGet("DASHSCOPE_MODEL")) ?? "qwen-plus"; if (!apiKey || !baseUrl) { throw new Error("Set DASHSCOPE_API_KEY and DASHSCOPE_BASE_URL"); } // --- Build context --- function getNerveYaml(): string { try { return readFileSync(join(NERVE_ROOT, "nerve.yaml"), "utf-8"); } catch { return "# nerve.yaml unavailable"; } } function buildSenseExamples(): string { const examples: string[] = []; for (const name of ["cpu-usage", "linux-system-health"]) { const dir = join(SENSES_DIR, name); if (!existsSync(dir)) continue; const indexFile = existsSync(join(dir, "index.js")) ? readFileSync(join(dir, "index.js"), "utf-8") : ""; const schema = existsSync(join(dir, "schema.ts")) ? readFileSync(join(dir, "schema.ts"), "utf-8") : ""; const migrationDir = join(dir, "migrations"); let migration = ""; if (existsSync(join(migrationDir, "0001_init.sql"))) { migration = readFileSync(join(migrationDir, "0001_init.sql"), "utf-8"); } examples.push( `### Example sense: ${name}\n\n` + `**index.js:**\n\`\`\`js\n${indexFile}\n\`\`\`\n\n` + `**schema.ts:**\n\`\`\`ts\n${schema}\n\`\`\`\n\n` + `**migrations/0001_init.sql:**\n\`\`\`sql\n${migration}\n\`\`\``, ); } return examples.join("\n\n---\n\n"); } // --- Wire up --- const workflow = buildSenseGenerator({ provider: { apiKey, baseUrl, model }, nerveRoot: NERVE_ROOT, sensesDir: SENSES_DIR, senseExamples: buildSenseExamples(), nerveYaml: getNerveYaml(), }); export default workflow;