@agentled/cli
Version:
CLI for Agentled — manage workflows, apps, and knowledge from the command line. Zero context-window cost for AI agents.
251 lines • 10.3 kB
JavaScript
import { readFileSync } from 'node:fs';
import { AgentledClient } from '../client.js';
import { printError, printOutput } from '../utils/output.js';
function readJsonOption(value, fallback) {
if (!value)
return fallback;
return JSON.parse(value);
}
function readJsonFileOption(path, fallback) {
if (!path)
return fallback;
return JSON.parse(readFileSync(path, 'utf8'));
}
function parseCsv(value) {
if (!value)
return undefined;
return value.split(',').map((item) => item.trim()).filter(Boolean);
}
function printCliError(error) {
printError(error instanceof Error ? error.message : String(error));
}
export function registerBuilderWorkItemCommands(program) {
const builders = program
.command('builders')
.description('Manage external AI builder profiles and work item handoffs');
const profile = builders.command('profile').description('Manage this API key\'s AI builder profile');
profile
.command('upsert')
.description('Create or update this API key\'s AI builder profile')
.requiredOption('--provider <provider>', 'Builder provider: codex, claude, openclaw, herms, or custom')
.requiredOption('--name <name>', 'Builder display name')
.option('--metadata <json>', 'JSON metadata object')
.option('--metadata-file <path>', 'Path to JSON metadata object')
.option('--format <fmt>', 'Output format', 'json')
.action(async (opts) => {
try {
const metadata = opts.metadataFile
? readJsonFileOption(opts.metadataFile, {})
: readJsonOption(opts.metadata, {});
const result = await new AgentledClient().upsertAiBuilderProfile({
provider: opts.provider,
name: opts.name,
metadata,
});
printOutput(result, opts.format);
}
catch (error) {
printCliError(error);
}
});
const workItems = builders.command('work-items').description('Manage builder work item handoffs');
workItems
.command('list')
.description('List work items eligible for this authenticated builder')
.option('--status <csv>', 'Comma-separated statuses')
.option('--source-agent-entity-id <id>', 'Optional source business-agent ID filter')
.option('--type <type>', 'Optional work item type filter')
.option('--limit <n>', 'Maximum items to return')
.option('--format <fmt>', 'Output format', 'json')
.action(async (opts) => {
try {
const result = await new AgentledClient().listBuilderWorkItems({
status: parseCsv(opts.status),
sourceAgentEntityId: opts.sourceAgentEntityId,
type: opts.type,
limit: opts.limit ? Number(opts.limit) : undefined,
});
printOutput(result, opts.format);
}
catch (error) {
printCliError(error);
}
});
workItems
.command('list-for-agent <sourceAgentEntityId>')
.description('List builder work items for a business agent')
.option('--status <csv>', 'Comma-separated statuses')
.option('--type <type>', 'Optional work item type filter')
.option('--limit <n>', 'Maximum items to return')
.option('--format <fmt>', 'Output format', 'json')
.action(async (sourceAgentEntityId, opts) => {
try {
const result = await new AgentledClient().listBuilderWorkItemsForAgent({
sourceAgentEntityId,
status: parseCsv(opts.status),
type: opts.type,
limit: opts.limit ? Number(opts.limit) : undefined,
});
printOutput(result, opts.format);
}
catch (error) {
printCliError(error);
}
});
workItems
.command('create')
.description('Create a business-agent handoff for an external AI builder')
.requiredOption('--source-agent-entity-id <id>', 'Source business-agent ID')
.requiredOption('--title <title>', 'Work item title')
.requiredOption('--brief <brief>', 'Work item brief')
.option('--type <type>', 'Work item type')
.option('--builder-id <id>', 'Optional target builder ID')
.option('--context-refs <json>', 'JSON array of context refs')
.option('--context-refs-file <path>', 'Path to JSON array of context refs')
.option('--metadata <json>', 'JSON metadata object')
.option('--metadata-file <path>', 'Path to JSON metadata object')
.option('--format <fmt>', 'Output format', 'json')
.action(async (opts) => {
try {
const contextRefs = opts.contextRefsFile
? readJsonFileOption(opts.contextRefsFile, [])
: readJsonOption(opts.contextRefs, []);
const metadata = opts.metadataFile
? readJsonFileOption(opts.metadataFile, {})
: readJsonOption(opts.metadata, {});
const result = await new AgentledClient().createBuilderWorkItem({
sourceAgentEntityId: opts.sourceAgentEntityId,
title: opts.title,
brief: opts.brief,
type: opts.type,
builderId: opts.builderId,
contextRefs,
metadata,
});
printOutput(result, opts.format);
}
catch (error) {
printCliError(error);
}
});
workItems
.command('get <id>')
.description('Get a builder work item')
.option('--format <fmt>', 'Output format', 'json')
.action(async (id, opts) => {
try {
const result = await new AgentledClient().getBuilderWorkItem(id);
printOutput(result, opts.format);
}
catch (error) {
printCliError(error);
}
});
workItems
.command('claim <id>')
.description('Claim a builder work item as this registered builder')
.option('--status <status>', 'claimed or in_progress')
.option('--note <note>', 'Optional claim note')
.option('--format <fmt>', 'Output format', 'json')
.action(async (id, opts) => {
try {
const result = await new AgentledClient().claimBuilderWorkItem(id, {
status: opts.status,
note: opts.note,
});
printOutput(result, opts.format);
}
catch (error) {
printCliError(error);
}
});
workItems
.command('activity <id>')
.description('Append builder progress activity')
.requiredOption('--note <note>', 'Progress note')
.option('--activity-action <action>', 'Activity action label')
.option('--refs <json>', 'JSON array of refs')
.option('--format <fmt>', 'Output format', 'json')
.action(async (id, opts) => {
try {
const result = await new AgentledClient().appendBuilderWorkActivity(id, {
note: opts.note,
activityAction: opts.activityAction,
refs: readJsonOption(opts.refs, []),
});
printOutput(result, opts.format);
}
catch (error) {
printCliError(error);
}
});
workItems
.command('submit <id>')
.description('Submit completed builder work')
.requiredOption('--summary <summary>', 'Completion summary')
.option('--output-refs <json>', 'JSON array of output refs')
.option('--metadata <json>', 'JSON metadata object')
.option('--note <note>', 'Optional submit note')
.option('--format <fmt>', 'Output format', 'json')
.action(async (id, opts) => {
try {
const result = await new AgentledClient().submitBuilderWorkItem(id, {
summary: opts.summary,
outputRefs: readJsonOption(opts.outputRefs, []),
metadata: readJsonOption(opts.metadata, {}),
note: opts.note,
});
printOutput(result, opts.format);
}
catch (error) {
printCliError(error);
}
});
workItems
.command('review <id>')
.description('Review a submitted builder work item as a business agent')
.requiredOption('--verdict <verdict>', 'accepted, needs_changes, or closed')
.requiredOption('--note <note>', 'Review note')
.option('--source-agent-entity-id <id>', 'Source business-agent ID')
.option('--business-agent-rating <rating>', 'thumbs_up, thumbs_down, or neutral')
.option('--metadata <json>', 'JSON metadata object')
.option('--format <fmt>', 'Output format', 'json')
.action(async (id, opts) => {
try {
const result = await new AgentledClient().reviewBuilderWorkItem(id, {
verdict: opts.verdict,
note: opts.note,
sourceAgentEntityId: opts.sourceAgentEntityId,
businessAgentRating: opts.businessAgentRating,
metadata: readJsonOption(opts.metadata, {}),
});
printOutput(result, opts.format);
}
catch (error) {
printCliError(error);
}
});
workItems
.command('agent-activity <id>')
.description('Append business-agent activity to a builder work item')
.requiredOption('--note <note>', 'Activity note')
.option('--actor-id <id>', 'Business-agent actor ID')
.option('--activity-action <action>', 'Activity action label')
.option('--refs <json>', 'JSON array of refs')
.option('--format <fmt>', 'Output format', 'json')
.action(async (id, opts) => {
try {
const result = await new AgentledClient().appendBuilderWorkItemActivity(id, {
note: opts.note,
actorId: opts.actorId,
activityAction: opts.activityAction,
refs: readJsonOption(opts.refs, []),
});
printOutput(result, opts.format);
}
catch (error) {
printCliError(error);
}
});
}
//# sourceMappingURL=builder-work-items.js.map