clawdie-ai/scripts/agent-task.ts
Clawdie AI af659e7c56 feat(phase4): just front door — 55 recipes + 10 CLI helper scripts
Adds justfile with 8 grouped recipe sections covering build, jail
management, skill catalog, agent ops, and system admin. Adds scripts for
skill-list/add/sync, jail-status, system-health, agent-task/status/logs,
harness-check, and hostd-cli. Fixes project root derivation to use
import.meta.url instead of process.cwd() so scripts work regardless of
invocation directory.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---
Build: pass | Tests: FAIL — Tests  40 failed | 766 passed (806)
2026-04-13 23:26:22 +00:00

82 lines
2.2 KiB
TypeScript

#!/usr/bin/env npx tsx
/**
* scripts/agent-task.ts — Create a controlplane task via natural language.
* Usage: just agent-task "Restart the cms jail nginx service"
*/
import http from 'http';
const PORT = parseInt(process.env.CONTROLPLANE_PORT ?? '3100', 10);
const HOST = process.env.CONTROLPLANE_BIND_HOST ?? '127.0.0.1';
const description = process.argv[2];
if (!description) {
console.error('Usage: just agent-task "<description>"');
process.exit(1);
}
function post<T>(path: string, body: unknown): Promise<T> {
return new Promise((resolve, reject) => {
const payload = JSON.stringify(body);
const req = http.request(
{
hostname: HOST,
port: PORT,
path,
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) },
},
(res) => {
let buf = '';
res.on('data', (c: Buffer) => { buf += c.toString(); });
res.on('end', () => {
try { resolve(JSON.parse(buf) as T); }
catch { reject(new Error(`Non-JSON response (HTTP ${res.statusCode}): ${buf.slice(0, 100)}`)); }
});
},
);
req.on('error', reject);
req.write(payload);
req.end();
});
}
interface TaskResponse {
task?: { id: string; title: string; status: string };
error?: string;
}
async function main(): Promise<void> {
let resp: TaskResponse;
try {
resp = await post<TaskResponse>('/api/controlplane/tasks', {
title: description.slice(0, 100),
description,
priority: 'medium',
});
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
if (msg.includes('ECONNREFUSED')) {
console.error(`Controlplane not reachable at http://${HOST}:${PORT}`);
} else {
console.error(`Error: ${msg}`);
}
process.exit(1);
}
if (!resp.task) {
console.error(`Failed: ${resp.error ?? JSON.stringify(resp)}`);
process.exit(1);
}
console.log(`\nTask created:`);
console.log(` ID: ${resp.task.id}`);
console.log(` Title: ${resp.task.title}`);
console.log(` Status: ${resp.task.status}`);
console.log('');
}
main().catch((err: Error) => {
console.error(err.message);
process.exit(1);
});