delqhi/code-devops
0
1import { mkdir, readFile, writeFile } from 'node:fs/promises';2import { dirname, join } from 'node:path';3import { homedir } from 'node:os';4 5const DEFAULT_STATE_PATH = join(homedir(), '.config', 'sin', 'sin-code-devops', 'onboarding-state.json');6 7type OnboardingState = {8 ownerEmail?: string;9 notes?: string;10 updatedAt?: string;11};12 13export type TemplateAgentAction =14 | { action: 'agent.help' }15 | { action: 'sin.code.devops.health' }16 | { action: 'sin.code.devops.onboarding.status' }17 | { action: 'sin.code.devops.onboarding.save'; ownerEmail?: string; notes?: string; confirm?: boolean };18 19export async function executeTemplateAgentAction(action: TemplateAgentAction): Promise<unknown> {20 switch (action.action) {21 case 'agent.help':22 return buildHelpPayload();23 case 'sin.code.devops.health':24 return {25 ok: true,26 agent: 'sin-code-devops',27 primaryModel: 'opencode/qwen3.6-plus-free',28 team: 'Team Coding',29 };30 case 'sin.code.devops.onboarding.status':31 return {32 ok: true,33 statePath: DEFAULT_STATE_PATH,34 state: await readState(),35 };36 case 'sin.code.devops.onboarding.save':37 if (!action.confirm) {38 throw new Error('input_required:confirm=true required');39 }40 return {41 ok: true,42 statePath: DEFAULT_STATE_PATH,43 state: await writeState({44 ownerEmail: clean(action.ownerEmail),45 notes: clean(action.notes),46 updatedAt: new Date().toISOString(),47 }),48 };49 }50}51 52function buildHelpPayload() {53 return {54 ok: true,55 agent: 'sin-code-devops',56 actions: ['sin.code.devops.health', 'sin.code.devops.onboarding.status', 'sin.code.devops.onboarding.save'],57 controlPlane: {58 projectionMode: 'control-plane-first',59 capabilityRegistry: 'control_plane.capabilities',60 consumerAuthScript: './scripts/hf_pull_script.py',61 completeInstallScript: './scripts/complete-install.sh',62 },63 };64}65 66async function readState(): Promise<OnboardingState | null> {67 try {68 return JSON.parse(await readFile(DEFAULT_STATE_PATH, 'utf8')) as OnboardingState;69 } catch {70 return null;71 }72}73 74async function writeState(state: OnboardingState) {75 await mkdir(dirname(DEFAULT_STATE_PATH), { recursive: true });76 await writeFile(DEFAULT_STATE_PATH, `${JSON.stringify(state, null, 2)}\n`, 'utf8');77 return state;78}79 80function clean(value: string | undefined) {81 const normalized = String(value || '').trim();82 return normalized || undefined;83}84 