mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-08-13 14:37:26 +00:00
feat: add c0mpute plugin and hire-us request flow
This commit is contained in:
parent
1a87c2f26d
commit
b1d8fe475a
20 changed files with 1271 additions and 59 deletions
|
|
@ -13,6 +13,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@logicsrc/plugin-core": "file:../../packages/plugin-core",
|
||||
"@logicsrc/plugin-c0mpute": "file:../../plugins/c0mpute",
|
||||
"@logicsrc/plugin-coinpay": "file:../../plugins/coinpay",
|
||||
"@logicsrc/plugin-sh1pt": "file:../../plugins/sh1pt",
|
||||
"@logicsrc/plugin-ugig": "file:../../plugins/ugig",
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ describe("CommandBoard API contracts", () => {
|
|||
expect(body).toEqual({ ok: true, service: "commandboard-api" });
|
||||
});
|
||||
|
||||
it("exposes default plugin contract including sh1pt", async () => {
|
||||
it("exposes default plugin contract including product plugins", async () => {
|
||||
const response = await fetch(`${baseUrl}/api/plugins`);
|
||||
const body = await response.json() as {
|
||||
plugins: Array<{ id: string; enabled: boolean; capabilities: string[] }>;
|
||||
|
|
@ -47,12 +47,17 @@ describe("CommandBoard API contracts", () => {
|
|||
};
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(body.plugins.map((plugin) => plugin.id)).toEqual(["coinpay", "ugig", "sh1pt"]);
|
||||
expect(body.plugins.map((plugin) => plugin.id)).toEqual(["coinpay", "ugig", "sh1pt", "c0mpute"]);
|
||||
expect(body.plugins.find((plugin) => plugin.id === "sh1pt")).toMatchObject({
|
||||
enabled: true,
|
||||
capabilities: expect.arrayContaining(["projects.sync", "actions.publish", "deployments.status"])
|
||||
});
|
||||
expect(body.plugins.find((plugin) => plugin.id === "c0mpute")).toMatchObject({
|
||||
enabled: true,
|
||||
capabilities: expect.arrayContaining(["compute.jobs.sync", "compute.jobs.dispatch", "compute.workers.sync"])
|
||||
});
|
||||
expect(body.capabilities["actions.publish"]).toEqual(["sh1pt"]);
|
||||
expect(body.capabilities["compute.jobs.dispatch"]).toEqual(["c0mpute"]);
|
||||
});
|
||||
|
||||
it("exposes sh1pt project and action contracts", async () => {
|
||||
|
|
@ -83,6 +88,48 @@ describe("CommandBoard API contracts", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("exposes work-in-progress c0mpute jobs and worker contracts", async () => {
|
||||
const jobsResponse = await fetch(`${baseUrl}/api/plugins/c0mpute/jobs`);
|
||||
const jobsBody = await jobsResponse.json() as { jobs: Array<{ id: string; board: string; status: string; provider: string }> };
|
||||
const workersResponse = await fetch(`${baseUrl}/api/plugins/c0mpute/workers`);
|
||||
const workersBody = await workersResponse.json() as { workers: Array<{ id: string; status: string; capacity: string }> };
|
||||
|
||||
expect(jobsResponse.status).toBe(200);
|
||||
expect(jobsBody.jobs[0]).toMatchObject({ id: "compute_job_1", board: "/projects/c0mpute", status: "draft", provider: "c0mpute.com" });
|
||||
expect(workersResponse.status).toBe(200);
|
||||
expect(workersBody.workers[0]).toMatchObject({ id: "worker_pool_1", status: "preview", capacity: "wip" });
|
||||
});
|
||||
|
||||
it("accepts work-in-progress c0mpute dispatch and quote requests", async () => {
|
||||
const dispatchResponse = await fetch(`${baseUrl}/api/plugins/c0mpute/jobs/dispatch`, {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/json" },
|
||||
body: JSON.stringify({ job_id: "compute_job_1" })
|
||||
});
|
||||
const dispatchBody = await dispatchResponse.json() as { accepted: boolean; job_id: string; status: string; board: string };
|
||||
const quoteResponse = await fetch(`${baseUrl}/api/plugins/c0mpute/quotes`, {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/json" },
|
||||
body: JSON.stringify({ workload: "agent-run-smoke-test" })
|
||||
});
|
||||
const quoteBody = await quoteResponse.json() as { accepted: boolean; workload: string; provider: string; status: string };
|
||||
|
||||
expect(dispatchResponse.status).toBe(202);
|
||||
expect(dispatchBody).toEqual({
|
||||
accepted: true,
|
||||
job_id: "compute_job_1",
|
||||
status: "queued",
|
||||
board: "/projects/c0mpute"
|
||||
});
|
||||
expect(quoteResponse.status).toBe(202);
|
||||
expect(quoteBody).toMatchObject({
|
||||
accepted: true,
|
||||
workload: "agent-run-smoke-test",
|
||||
provider: "c0mpute.com",
|
||||
status: "draft"
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects invalid LogicSRC task payloads", async () => {
|
||||
const response = await fetch(`${baseUrl}/api/tasks`, {
|
||||
method: "POST",
|
||||
|
|
|
|||
|
|
@ -1,18 +1,20 @@
|
|||
import { createServer, type IncomingMessage, type ServerResponse } from "node:http";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { createPluginRegistry } from "@logicsrc/plugin-core";
|
||||
import { c0mputePlugin } from "@logicsrc/plugin-c0mpute";
|
||||
import { coinPayPlugin } from "@logicsrc/plugin-coinpay";
|
||||
import { sh1ptPlugin } from "@logicsrc/plugin-sh1pt";
|
||||
import { uGigPlugin } from "@logicsrc/plugin-ugig";
|
||||
import { schemas, validate } from "@logicsrc/validators";
|
||||
|
||||
const registry = createPluginRegistry([coinPayPlugin, uGigPlugin, sh1ptPlugin]);
|
||||
const registry = createPluginRegistry([coinPayPlugin, uGigPlugin, sh1ptPlugin, c0mputePlugin]);
|
||||
|
||||
const boards = [
|
||||
{ path: "/general", title: "General", description: "CommandBoard.run general discussion." },
|
||||
{ path: "/gigs", title: "Gigs", description: "Paid work, uGig imports, and LogicSRC tasks." },
|
||||
{ path: "/agents", title: "Agents", description: "Agent registration, runs, and capabilities." },
|
||||
{ path: "/projects/sh1pt", title: "sh1pt", description: "Project actions, releases, artifacts, and delivery status." }
|
||||
{ path: "/projects/sh1pt", title: "sh1pt", description: "Project actions, releases, artifacts, and delivery status." },
|
||||
{ path: "/projects/c0mpute", title: "c0mpute", description: "Compute jobs, worker pools, usage, and settlement status." }
|
||||
];
|
||||
|
||||
const tasks = [
|
||||
|
|
@ -41,6 +43,15 @@ const sh1ptActions = [
|
|||
{ id: "action_deploy_preview", title: "Deploy preview", publishable: true }
|
||||
];
|
||||
|
||||
const c0mputeJobs = [
|
||||
{ id: "compute_job_1", board: "/projects/c0mpute", status: "draft", workload: "agent-run-smoke-test", provider: "c0mpute.com" },
|
||||
{ id: "compute_job_2", board: "/projects/c0mpute", status: "queued", workload: "openspec-index-build", provider: "c0mpute.com" }
|
||||
];
|
||||
|
||||
const c0mputeWorkers = [
|
||||
{ id: "worker_pool_1", region: "us-west", status: "preview", capacity: "wip" }
|
||||
];
|
||||
|
||||
export function createCommandBoardServer() {
|
||||
return createServer(async (request, response) => {
|
||||
try {
|
||||
|
|
@ -127,6 +138,49 @@ async function route(request: IncomingMessage, response: ServerResponse) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (request.method === "GET" && url.pathname === "/api/plugins/c0mpute/jobs") {
|
||||
json(response, 200, { jobs: c0mputeJobs });
|
||||
return;
|
||||
}
|
||||
|
||||
if (request.method === "GET" && url.pathname === "/api/plugins/c0mpute/workers") {
|
||||
json(response, 200, { workers: c0mputeWorkers });
|
||||
return;
|
||||
}
|
||||
|
||||
if (request.method === "POST" && url.pathname === "/api/plugins/c0mpute/jobs/dispatch") {
|
||||
const body = await readJson(request);
|
||||
if (!isRecord(body) || typeof body.job_id !== "string") {
|
||||
json(response, 422, { error: "Expected job_id" });
|
||||
return;
|
||||
}
|
||||
|
||||
json(response, 202, {
|
||||
accepted: true,
|
||||
job_id: body.job_id,
|
||||
status: "queued",
|
||||
board: typeof body.board === "string" ? body.board : "/projects/c0mpute"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (request.method === "POST" && url.pathname === "/api/plugins/c0mpute/quotes") {
|
||||
const body = await readJson(request);
|
||||
if (!isRecord(body) || typeof body.workload !== "string") {
|
||||
json(response, 422, { error: "Expected workload" });
|
||||
return;
|
||||
}
|
||||
|
||||
json(response, 202, {
|
||||
accepted: true,
|
||||
quote_id: `quote_${Date.now()}`,
|
||||
workload: body.workload,
|
||||
provider: "c0mpute.com",
|
||||
status: "draft"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (request.method === "GET" && url.pathname === "/api/schemas") {
|
||||
json(response, 200, { schemas: Object.keys(schemas) });
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue