Merge pull request 'refactor(cli): auto-generate skill doc from command registry' (#74) from refactor/71-auto-gen-skill-doc into main
This commit is contained in:
@@ -21,84 +21,49 @@ import { cmdThreads } from "./cmd-threads.js";
|
|||||||
import { parseLiveArgv } from "./live-argv.js";
|
import { parseLiveArgv } from "./live-argv.js";
|
||||||
import { parseRunArgv } from "./run-argv.js";
|
import { parseRunArgv } from "./run-argv.js";
|
||||||
|
|
||||||
export function formatCliUsage(): string {
|
|
||||||
return [
|
|
||||||
"Usage:",
|
|
||||||
" uncaged-workflow workflow add <name> <file.esm.js> [--types <path>]",
|
|
||||||
" uncaged-workflow workflow list",
|
|
||||||
" uncaged-workflow workflow show <name>",
|
|
||||||
" uncaged-workflow workflow rm <name>",
|
|
||||||
" uncaged-workflow workflow history <name>",
|
|
||||||
" uncaged-workflow workflow rollback <name> [hash]",
|
|
||||||
"",
|
|
||||||
" uncaged-workflow thread run <name> [--prompt <text>] [--max-rounds N]",
|
|
||||||
" uncaged-workflow thread list [name]",
|
|
||||||
" uncaged-workflow thread show <id>",
|
|
||||||
" uncaged-workflow thread rm <id>",
|
|
||||||
" uncaged-workflow thread ps",
|
|
||||||
" uncaged-workflow thread kill <thread-id>",
|
|
||||||
" uncaged-workflow thread live <thread-id> [--debug] [--role <name>]",
|
|
||||||
" uncaged-workflow thread live --latest [--debug] [--role <name>]",
|
|
||||||
" uncaged-workflow thread pause <thread-id>",
|
|
||||||
" uncaged-workflow thread resume <thread-id>",
|
|
||||||
" uncaged-workflow thread fork <thread-id> [--from-role <role>]",
|
|
||||||
"",
|
|
||||||
" uncaged-workflow cas get <thread-id> <hash>",
|
|
||||||
" uncaged-workflow cas put <thread-id> <content>",
|
|
||||||
" uncaged-workflow cas list <thread-id>",
|
|
||||||
" uncaged-workflow cas rm <thread-id> <hash>",
|
|
||||||
" uncaged-workflow cas gc",
|
|
||||||
"",
|
|
||||||
" uncaged-workflow init workspace <name>",
|
|
||||||
" uncaged-workflow init template <name>",
|
|
||||||
"",
|
|
||||||
" uncaged-workflow run <name> [...] (shortcut for thread run)",
|
|
||||||
" uncaged-workflow live <thread-id> [...] (shortcut for thread live)",
|
|
||||||
"",
|
|
||||||
"Environment variables:",
|
|
||||||
" WORKFLOW_STORAGE_ROOT Override storage directory (default: ~/.uncaged/workflow)",
|
|
||||||
" UNCAGED_WORKFLOW_STORAGE_ROOT Internal override (takes priority over WORKFLOW_STORAGE_ROOT)",
|
|
||||||
].join("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
function printDeprecation(oldCmd: string, newCmd: string): void {
|
|
||||||
printCliWarn(`⚠ "${oldCmd}" is deprecated, use "${newCmd}" instead`);
|
|
||||||
}
|
|
||||||
|
|
||||||
type DispatchFn = (storageRoot: string, argv: string[]) => Promise<number>;
|
type DispatchFn = (storageRoot: string, argv: string[]) => Promise<number>;
|
||||||
|
|
||||||
|
type CommandEntry = {
|
||||||
|
handler: DispatchFn;
|
||||||
|
args: string;
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type CommandGroup = {
|
||||||
|
name: string;
|
||||||
|
commands: ReadonlyArray<{ name: string; args: string; description: string }>;
|
||||||
|
};
|
||||||
|
|
||||||
// ── Individual dispatch functions ──────────────────────────────────────
|
// ── Individual dispatch functions ──────────────────────────────────────
|
||||||
|
|
||||||
async function dispatchInit(_storageRoot: string, argv: string[]): Promise<number> {
|
async function dispatchInitWorkspace(_storageRoot: string, argv: string[]): Promise<number> {
|
||||||
const sub = argv[0];
|
const name = argv[0];
|
||||||
const name = argv[1];
|
if (name === undefined || argv.length > 1) {
|
||||||
if (sub === undefined || name === undefined || argv.length > 2) {
|
printCliError(`${formatCliUsage()}\n\nerror: init workspace requires <name>`);
|
||||||
printCliError(`${formatCliUsage()}\n\nerror: init requires workspace|template <name>`);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
const result = await cmdInitWorkspace(process.cwd(), name);
|
||||||
if (sub === "workspace") {
|
if (!result.ok) {
|
||||||
const result = await cmdInitWorkspace(process.cwd(), name);
|
printCliError(result.error);
|
||||||
if (!result.ok) {
|
return 1;
|
||||||
printCliError(result.error);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
printCliLine(`initialized workflow workspace at ${result.value.rootPath}`);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
printCliLine(`initialized workflow workspace at ${result.value.rootPath}`);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (sub === "template") {
|
async function dispatchInitTemplate(_storageRoot: string, argv: string[]): Promise<number> {
|
||||||
const result = await cmdInitTemplate(process.cwd(), name);
|
const name = argv[0];
|
||||||
if (!result.ok) {
|
if (name === undefined || argv.length > 1) {
|
||||||
printCliError(result.error);
|
printCliError(`${formatCliUsage()}\n\nerror: init template requires <name>`);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
printCliLine(`initialized template at ${result.value.templatePath}`);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
const result = await cmdInitTemplate(process.cwd(), name);
|
||||||
printCliError(`${formatCliUsage()}\n\nerror: unknown init subcommand: ${sub}`);
|
if (!result.ok) {
|
||||||
return 1;
|
printCliError(result.error);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printCliLine(`initialized template at ${result.value.templatePath}`);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function dispatchAdd(storageRoot: string, argv: string[]): Promise<number> {
|
async function dispatchAdd(storageRoot: string, argv: string[]): Promise<number> {
|
||||||
@@ -426,49 +391,210 @@ async function dispatchCasRm(storageRoot: string, rest: string[]): Promise<numbe
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CAS_SUBCOMMAND_TABLE: Record<string, DispatchFn> = {
|
// ── Subcommand tables with metadata ────────────────────────────────────
|
||||||
get: dispatchCasGet,
|
|
||||||
put: dispatchCasPut,
|
const WORKFLOW_SUBCOMMAND_TABLE: Record<string, CommandEntry> = {
|
||||||
list: dispatchCasList,
|
add: {
|
||||||
rm: dispatchCasRm,
|
handler: dispatchAdd,
|
||||||
gc: dispatchGc,
|
args: "<name> <file.esm.js> [--types <path>]",
|
||||||
|
description: "Register a workflow bundle in the registry",
|
||||||
|
},
|
||||||
|
list: { handler: dispatchList, args: "", description: "List all registered workflows" },
|
||||||
|
show: {
|
||||||
|
handler: dispatchShow,
|
||||||
|
args: "<name>",
|
||||||
|
description: "Show details of a registered workflow",
|
||||||
|
},
|
||||||
|
rm: {
|
||||||
|
handler: dispatchRemove,
|
||||||
|
args: "<name>",
|
||||||
|
description: "Remove a workflow from the registry",
|
||||||
|
},
|
||||||
|
history: {
|
||||||
|
handler: dispatchHistory,
|
||||||
|
args: "<name>",
|
||||||
|
description: "Show version history of a workflow",
|
||||||
|
},
|
||||||
|
rollback: {
|
||||||
|
handler: dispatchRollback,
|
||||||
|
args: "<name> [hash]",
|
||||||
|
description: "Rollback a workflow to a previous version",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
async function dispatchCas(storageRoot: string, argv: string[]): Promise<number> {
|
const THREAD_SUBCOMMAND_TABLE: Record<string, CommandEntry> = {
|
||||||
const sub = argv[0];
|
run: {
|
||||||
if (sub === undefined) {
|
handler: dispatchRun,
|
||||||
printCliError(`${formatCliUsage()}\n\nerror: unknown cas subcommand: (none)`);
|
args: "<name> [--prompt <text>] [--max-rounds N]",
|
||||||
return 1;
|
description: "Start a new thread executing a workflow",
|
||||||
}
|
},
|
||||||
const handler = CAS_SUBCOMMAND_TABLE[sub];
|
list: {
|
||||||
if (handler === undefined) {
|
handler: dispatchThreadList,
|
||||||
printCliError(`${formatCliUsage()}\n\nerror: unknown cas subcommand: ${sub}`);
|
args: "[name]",
|
||||||
return 1;
|
description: "List threads, optionally filtered by workflow name",
|
||||||
}
|
},
|
||||||
return handler(storageRoot, argv.slice(1));
|
show: { handler: dispatchThreadShow, args: "<id>", description: "Show thread details and state" },
|
||||||
|
rm: { handler: dispatchThreadRm, args: "<id>", description: "Remove a thread" },
|
||||||
|
fork: {
|
||||||
|
handler: dispatchFork,
|
||||||
|
args: "<thread-id> [--from-role <role>]",
|
||||||
|
description: "Fork a thread, optionally from a specific role",
|
||||||
|
},
|
||||||
|
ps: { handler: dispatchPs, args: "", description: "List running threads" },
|
||||||
|
kill: { handler: dispatchKill, args: "<thread-id>", description: "Kill a running thread" },
|
||||||
|
live: {
|
||||||
|
handler: dispatchLive,
|
||||||
|
args: "<thread-id> [--debug] [--role <name>]",
|
||||||
|
description: "Attach to a thread and stream output live",
|
||||||
|
},
|
||||||
|
pause: { handler: dispatchPause, args: "<thread-id>", description: "Pause a running thread" },
|
||||||
|
resume: { handler: dispatchResume, args: "<thread-id>", description: "Resume a paused thread" },
|
||||||
|
};
|
||||||
|
|
||||||
|
const CAS_SUBCOMMAND_TABLE: Record<string, CommandEntry> = {
|
||||||
|
get: {
|
||||||
|
handler: dispatchCasGet,
|
||||||
|
args: "<thread-id> <hash>",
|
||||||
|
description: "Retrieve content by hash from a thread's CAS",
|
||||||
|
},
|
||||||
|
put: {
|
||||||
|
handler: dispatchCasPut,
|
||||||
|
args: "<thread-id> <content>",
|
||||||
|
description: "Store content in a thread's CAS, returns hash",
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
handler: dispatchCasList,
|
||||||
|
args: "<thread-id>",
|
||||||
|
description: "List all CAS entries for a thread",
|
||||||
|
},
|
||||||
|
rm: { handler: dispatchCasRm, args: "<thread-id> <hash>", description: "Remove a CAS entry" },
|
||||||
|
gc: { handler: dispatchGc, args: "", description: "Garbage-collect unreferenced CAS entries" },
|
||||||
|
};
|
||||||
|
|
||||||
|
const INIT_SUBCOMMAND_TABLE: Record<string, CommandEntry> = {
|
||||||
|
workspace: {
|
||||||
|
handler: dispatchInitWorkspace,
|
||||||
|
args: "<name>",
|
||||||
|
description: "Initialize a new workflow workspace",
|
||||||
|
},
|
||||||
|
template: {
|
||||||
|
handler: dispatchInitTemplate,
|
||||||
|
args: "<name>",
|
||||||
|
description: "Initialize a new workflow template",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// ── Command registry ───────────────────────────────────────────────────
|
||||||
|
|
||||||
|
export function getCommandRegistry(): ReadonlyArray<CommandGroup> {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: "workflow",
|
||||||
|
commands: Object.entries(WORKFLOW_SUBCOMMAND_TABLE).map(([name, e]) => ({
|
||||||
|
name,
|
||||||
|
args: e.args,
|
||||||
|
description: e.description,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "thread",
|
||||||
|
commands: Object.entries(THREAD_SUBCOMMAND_TABLE).map(([name, e]) => ({
|
||||||
|
name,
|
||||||
|
args: e.args,
|
||||||
|
description: e.description,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cas",
|
||||||
|
commands: Object.entries(CAS_SUBCOMMAND_TABLE).map(([name, e]) => ({
|
||||||
|
name,
|
||||||
|
args: e.args,
|
||||||
|
description: e.description,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "init",
|
||||||
|
commands: Object.entries(INIT_SUBCOMMAND_TABLE).map(([name, e]) => ({
|
||||||
|
name,
|
||||||
|
args: e.args,
|
||||||
|
description: e.description,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Workflow subcommand table (Phase 1) ────────────────────────────────
|
// ── Auto-generated CLI usage ───────────────────────────────────────────
|
||||||
|
|
||||||
const WORKFLOW_SUBCOMMAND_TABLE: Record<string, DispatchFn> = {
|
export function formatCliUsage(): string {
|
||||||
add: dispatchAdd,
|
const groups = getCommandRegistry();
|
||||||
list: dispatchList,
|
const lines: string[] = ["Usage:"];
|
||||||
show: dispatchShow,
|
for (const group of groups) {
|
||||||
rm: dispatchRemove,
|
for (const cmd of group.commands) {
|
||||||
history: dispatchHistory,
|
const args = cmd.args ? ` ${cmd.args}` : "";
|
||||||
rollback: dispatchRollback,
|
lines.push(` uncaged-workflow ${group.name} ${cmd.name}${args}`);
|
||||||
};
|
}
|
||||||
|
lines.push("");
|
||||||
|
}
|
||||||
|
lines.push(" uncaged-workflow run <name> [...] (shortcut for thread run)");
|
||||||
|
lines.push(" uncaged-workflow live <thread-id> [...] (shortcut for thread live)");
|
||||||
|
lines.push("");
|
||||||
|
lines.push("Environment variables:");
|
||||||
|
lines.push(
|
||||||
|
" WORKFLOW_STORAGE_ROOT Override storage directory (default: ~/.uncaged/workflow)",
|
||||||
|
);
|
||||||
|
lines.push(
|
||||||
|
" UNCAGED_WORKFLOW_STORAGE_ROOT Internal override (takes priority over WORKFLOW_STORAGE_ROOT)",
|
||||||
|
);
|
||||||
|
return lines.join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
async function dispatchWorkflow(storageRoot: string, argv: string[]): Promise<number> {
|
function printDeprecation(oldCmd: string, newCmd: string): void {
|
||||||
|
printCliWarn(`⚠ "${oldCmd}" is deprecated, use "${newCmd}" instead`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Group dispatchers ──────────────────────────────────────────────────
|
||||||
|
|
||||||
|
function dispatchGroup(
|
||||||
|
tableName: string,
|
||||||
|
table: Record<string, CommandEntry>,
|
||||||
|
storageRoot: string,
|
||||||
|
argv: string[],
|
||||||
|
): Promise<number> | null {
|
||||||
const sub = argv[0];
|
const sub = argv[0];
|
||||||
if (sub === undefined) {
|
if (sub === undefined) {
|
||||||
printCliError(`${formatCliUsage()}\n\nerror: unknown workflow subcommand: (none)`);
|
printCliError(`${formatCliUsage()}\n\nerror: unknown ${tableName} subcommand: (none)`);
|
||||||
|
return Promise.resolve(1);
|
||||||
|
}
|
||||||
|
const entry = table[sub];
|
||||||
|
if (entry === undefined) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return entry.handler(storageRoot, argv.slice(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function dispatchInit(storageRoot: string, argv: string[]): Promise<number> {
|
||||||
|
const sub = argv[0];
|
||||||
|
const name = argv[1];
|
||||||
|
if (sub === undefined || name === undefined || argv.length > 2) {
|
||||||
|
printCliError(`${formatCliUsage()}\n\nerror: init requires workspace|template <name>`);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
const handler = WORKFLOW_SUBCOMMAND_TABLE[sub];
|
|
||||||
if (handler !== undefined) {
|
const entry = INIT_SUBCOMMAND_TABLE[sub];
|
||||||
return handler(storageRoot, argv.slice(1));
|
if (entry !== undefined) {
|
||||||
|
return entry.handler(storageRoot, argv.slice(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printCliError(`${formatCliUsage()}\n\nerror: unknown init subcommand: ${sub}`);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function dispatchWorkflow(storageRoot: string, argv: string[]): Promise<number> {
|
||||||
|
const result = dispatchGroup("workflow", WORKFLOW_SUBCOMMAND_TABLE, storageRoot, argv);
|
||||||
|
if (result !== null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
const sub = argv[0];
|
||||||
if (sub === "remove") {
|
if (sub === "remove") {
|
||||||
printDeprecation("workflow remove", "workflow rm");
|
printDeprecation("workflow remove", "workflow rm");
|
||||||
return dispatchRemove(storageRoot, argv.slice(1));
|
return dispatchRemove(storageRoot, argv.slice(1));
|
||||||
@@ -477,33 +603,24 @@ async function dispatchWorkflow(storageRoot: string, argv: string[]): Promise<nu
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Thread subcommand table (Phase 2) ──────────────────────────────────
|
|
||||||
|
|
||||||
const THREAD_SUBCOMMAND_TABLE: Record<string, DispatchFn> = {
|
|
||||||
run: dispatchRun,
|
|
||||||
list: dispatchThreadList,
|
|
||||||
show: dispatchThreadShow,
|
|
||||||
rm: dispatchThreadRm,
|
|
||||||
fork: dispatchFork,
|
|
||||||
ps: dispatchPs,
|
|
||||||
kill: dispatchKill,
|
|
||||||
live: dispatchLive,
|
|
||||||
pause: dispatchPause,
|
|
||||||
resume: dispatchResume,
|
|
||||||
};
|
|
||||||
|
|
||||||
async function dispatchThread(storageRoot: string, argv: string[]): Promise<number> {
|
async function dispatchThread(storageRoot: string, argv: string[]): Promise<number> {
|
||||||
|
const result = dispatchGroup("thread", THREAD_SUBCOMMAND_TABLE, storageRoot, argv);
|
||||||
|
if (result !== null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
const sub = argv[0];
|
const sub = argv[0];
|
||||||
if (sub === undefined) {
|
printCliError(`${formatCliUsage()}\n\nerror: unknown thread subcommand: ${sub}`);
|
||||||
printCliError(`${formatCliUsage()}\n\nerror: unknown thread subcommand: (none)`);
|
return 1;
|
||||||
return 1;
|
}
|
||||||
|
|
||||||
|
async function dispatchCas(storageRoot: string, argv: string[]): Promise<number> {
|
||||||
|
const result = dispatchGroup("cas", CAS_SUBCOMMAND_TABLE, storageRoot, argv);
|
||||||
|
if (result !== null) {
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
const handler = THREAD_SUBCOMMAND_TABLE[sub];
|
const sub = argv[0];
|
||||||
if (handler === undefined) {
|
printCliError(`${formatCliUsage()}\n\nerror: unknown cas subcommand: ${sub}`);
|
||||||
printCliError(`${formatCliUsage()}\n\nerror: unknown thread subcommand: ${sub}`);
|
return 1;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return handler(storageRoot, argv.slice(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Help ────────────────────────────────────────────────────────────────
|
// ── Help ────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -1,4 +1,19 @@
|
|||||||
|
import { getCommandRegistry } from "./cli-dispatch.js";
|
||||||
|
|
||||||
export function formatSkillDoc(): string {
|
export function formatSkillDoc(): string {
|
||||||
|
const groups = getCommandRegistry();
|
||||||
|
|
||||||
|
const commandSections: string[] = [];
|
||||||
|
for (const group of groups) {
|
||||||
|
const rows = group.commands.map((cmd) => {
|
||||||
|
const args = cmd.args ? `\`${cmd.args}\`` : "(none)";
|
||||||
|
return `| \`${group.name} ${cmd.name}\` | ${args} | ${cmd.description} |`;
|
||||||
|
});
|
||||||
|
commandSections.push(
|
||||||
|
`### ${group.name}\n\n| Command | Args | Description |\n|---------|------|-------------|\n${rows.join("\n")}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return `# uncaged-workflow CLI Reference
|
return `# uncaged-workflow CLI Reference
|
||||||
|
|
||||||
## Core Concepts
|
## Core Concepts
|
||||||
@@ -13,48 +28,7 @@ export function formatSkillDoc(): string {
|
|||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
### workflow
|
${commandSections.join("\n\n")}
|
||||||
|
|
||||||
| Command | Args | Description |
|
|
||||||
|---------|------|-------------|
|
|
||||||
| \`workflow add\` | \`<name> <file.esm.js> [--types <path>]\` | Register a workflow bundle in the registry |
|
|
||||||
| \`workflow list\` | (none) | List all registered workflows |
|
|
||||||
| \`workflow show\` | \`<name>\` | Show details of a registered workflow |
|
|
||||||
| \`workflow rm\` | \`<name>\` | Remove a workflow from the registry |
|
|
||||||
| \`workflow history\` | \`<name>\` | Show version history of a workflow |
|
|
||||||
| \`workflow rollback\` | \`<name> [hash]\` | Rollback a workflow to a previous version |
|
|
||||||
|
|
||||||
### thread
|
|
||||||
|
|
||||||
| Command | Args | Description |
|
|
||||||
|---------|------|-------------|
|
|
||||||
| \`thread run\` | \`<name> [--prompt <text>] [--max-rounds N]\` | Start a new thread executing a workflow |
|
|
||||||
| \`thread list\` | \`[name]\` | List threads, optionally filtered by workflow name |
|
|
||||||
| \`thread show\` | \`<id>\` | Show thread details and state |
|
|
||||||
| \`thread rm\` | \`<id>\` | Remove a thread |
|
|
||||||
| \`thread fork\` | \`<thread-id> [--from-role <role>]\` | Fork a thread, optionally from a specific role |
|
|
||||||
| \`thread ps\` | (none) | List running threads |
|
|
||||||
| \`thread kill\` | \`<thread-id>\` | Kill a running thread |
|
|
||||||
| \`thread live\` | \`<thread-id> [--debug] [--role <name>]\` or \`--latest [--debug] [--role <name>]\` | Attach to a thread and stream output live |
|
|
||||||
| \`thread pause\` | \`<thread-id>\` | Pause a running thread |
|
|
||||||
| \`thread resume\` | \`<thread-id>\` | Resume a paused thread |
|
|
||||||
|
|
||||||
### cas
|
|
||||||
|
|
||||||
| Command | Args | Description |
|
|
||||||
|---------|------|-------------|
|
|
||||||
| \`cas get\` | \`<thread-id> <hash>\` | Retrieve content by hash from a thread's CAS |
|
|
||||||
| \`cas put\` | \`<thread-id> <content>\` | Store content in a thread's CAS, returns hash |
|
|
||||||
| \`cas list\` | \`<thread-id>\` | List all CAS entries for a thread |
|
|
||||||
| \`cas rm\` | \`<thread-id> <hash>\` | Remove a CAS entry |
|
|
||||||
| \`cas gc\` | (none) | Garbage-collect unreferenced CAS entries |
|
|
||||||
|
|
||||||
### init
|
|
||||||
|
|
||||||
| Command | Args | Description |
|
|
||||||
|---------|------|-------------|
|
|
||||||
| \`init workspace\` | \`<name>\` | Initialize a new workflow workspace |
|
|
||||||
| \`init template\` | \`<name>\` | Initialize a new workflow template |
|
|
||||||
|
|
||||||
### Top-level shortcuts
|
### Top-level shortcuts
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user