This commit is contained in:
2026-09-03 11:28:30 +07:00 Unverified
parent 26c2d0f015
commit 82d0fe3e0d
93 changed files with 19237 additions and 1285 deletions
+97
View File
@@ -0,0 +1,97 @@
import { defineCommand } from "citty";
import { apiRequest, type ApiRequestInit } from "../lib/api";
import { toTable } from "../lib/format";
export type OperationsApiRequest = <T>(
path: string,
init?: ApiRequestInit,
) => Promise<T>;
type Operation = {
metadata: { name: string; creationTimestamp: string };
spec: { workspaceId: string; action: string };
status: {
state: string;
startedAt?: string;
finishedAt?: string;
result?: unknown;
error?: { code: string; message: string };
};
};
function operationPath(workspace?: string): string {
return workspace
? `/operations?${new URLSearchParams({ workspaceId: workspace })}`
: "/operations";
}
function renderOperations(items: Operation[]): string {
if (items.length === 0) return "No operations";
return toTable(
items.map((operation) => ({
id: operation.metadata.name,
workspace: operation.spec.workspaceId,
action: operation.spec.action,
state: operation.status.state,
created: operation.metadata.creationTimestamp,
finished: operation.status.finishedAt,
})),
);
}
export async function listOperations(
workspace?: string,
request: OperationsApiRequest = apiRequest,
): Promise<string> {
const response = await request<{ items: Operation[] }>(
operationPath(workspace),
);
return renderOperations(response.items);
}
export async function getOperation(
id: string,
request: OperationsApiRequest = apiRequest,
): Promise<string> {
const operation = await request<Operation>(
`/operations/${encodeURIComponent(id)}`,
);
const output = [renderOperations([operation])];
if (operation.status.error) {
output.push(
`Error: ${operation.status.error.code}: ${operation.status.error.message}`,
);
}
if (operation.status.result !== undefined) {
output.push(`Result: ${JSON.stringify(operation.status.result)}`);
}
return output.join("\n");
}
const list = defineCommand({
meta: { name: "ls", description: "List operations" },
args: {
workspace: {
type: "string",
alias: "w",
description: "Filter by workspace",
},
},
async run({ args }) {
console.log(await listOperations(args.workspace ?? args._[0]));
},
});
const get = defineCommand({
meta: { name: "get", description: "Get an operation" },
async run({ args }) {
const id = String(args._[0] ?? "").trim();
if (!id) throw new Error("Operation ID is required");
console.log(await getOperation(id));
},
});
export const operations = defineCommand({
meta: { name: "operations", description: "Inspect server operations" },
subCommands: { get, ls: list },
});