export type V1BatchCommand = { command_id: string; capability: string; phase: 'execute' | 'validate'; input: Record; depends_on?: string[]; continue_after_failure?: boolean; }; export type V1BatchTerminalStatus = | 'succeeded' | 'failed' | 'denied' | 'rejected' | 'skipped' | 'unsupported' | 'unavailable' | 'expired'; export type V1BatchResult = { command_id: string; capability?: string; status: V1BatchTerminalStatus; data?: unknown; meta?: Record; artifacts?: unknown[]; error?: { code: string; message: string; }; }; export interface V1CommandBatchRuntimeOptions { initialResults?: Iterable; resultMeta?: () => Record | undefined; executeOne: (command: V1BatchCommand) => Promise; } type BatchItem = { command: V1BatchCommand; base: { command_id: string; capability: string; }; }; export async function runV1CommandBatch( commands: V1BatchCommand[], options: V1CommandBatchRuntimeOptions, ): Promise { const items = new Map(); const commandIndexes = new Map(); const commandIdCounts = new Map(); const initialResults = new Map(); for (const result of options.initialResults || []) { const commandId = scalarString(result.command_id); if (commandId) { initialResults.set(commandId, result); } } commands.forEach((command, index) => { const base = commandResultBase(command); items.set(index, { command, base }); commandIdCounts.set(base.command_id, (commandIdCounts.get(base.command_id) || 0) + 1); }); const duplicateCommandIds = new Set( Array.from(commandIdCounts.entries()) .filter(([, count]) => count > 1) .map(([commandId]) => commandId) ); items.forEach((item, index) => { if (!duplicateCommandIds.has(item.base.command_id)) { commandIndexes.set(item.base.command_id, index); } }); const remaining = Array.from(items.keys()); const resultsByIndex = new Map(); const resultsByCommandId = new Map(); let hasFailedCommand = false; initialResults.forEach((result, commandId) => { if (duplicateCommandIds.has(commandId)) return; resultsByCommandId.set(commandId, result); if (!commandIndexes.has(commandId) && result.status !== 'succeeded') { hasFailedCommand = true; } }); while (remaining.length > 0) { let madeProgress = false; for (let offset = 0; offset < remaining.length; offset += 1) { const index = remaining[offset]; const item = items.get(index); if (!item) continue; let result: V1BatchResult | undefined; const initialResult = initialResults.get(item.base.command_id); if (duplicateCommandIds.has(item.base.command_id)) { result = invalidCommandResult( item.base, 'command_id values must be unique within a command batch.', options.resultMeta, ); } else if (initialResult) { result = initialResult; } else if (hasPendingDependencies(item.command, commandIndexes, resultsByIndex, resultsByCommandId)) { continue; } else if (shouldSkipCommand(item.command, resultsByCommandId, hasFailedCommand)) { result = skippedCommandResult(item.base, options.resultMeta); } else { const resolved = resolveCommandReferences(item.command, resultsByCommandId); result = resolved.error ? invalidReferenceCommandResult(item.base, resolved.error, options.resultMeta) : await options.executeOne(resolved.command); } resultsByIndex.set(index, result); resultsByCommandId.set(result.command_id, result); hasFailedCommand = hasFailedCommand || result.status !== 'succeeded'; remaining.splice(offset, 1); offset -= 1; madeProgress = true; } if (!madeProgress) { for (const index of remaining) { const item = items.get(index); if (!item) continue; const result = skippedCommandResult(item.base, options.resultMeta); resultsByIndex.set(index, result); resultsByCommandId.set(result.command_id, result); } remaining.splice(0, remaining.length); } } return Array.from(resultsByIndex.entries()) .sort(([left], [right]) => left - right) .map(([, result]) => result); } function hasPendingDependencies( command: V1BatchCommand, commandIndexes: Map, resultsByIndex: Map, resultsByCommandId: Map, ): boolean { if (command.phase === 'validate') return false; for (const dependencyId of commandDependencies(command)) { if (resultsByCommandId.has(dependencyId)) continue; const dependencyIndex = commandIndexes.get(dependencyId); if (dependencyIndex !== undefined && !resultsByIndex.has(dependencyIndex)) { return true; } } return false; } function shouldSkipCommand( command: V1BatchCommand, resultsByCommandId: Map, hasFailedCommand: boolean, ): boolean { if (command.phase === 'validate') return false; for (const dependencyId of commandDependencies(command)) { const result = resultsByCommandId.get(dependencyId); if (!result || result.status !== 'succeeded') { return true; } } return hasFailedCommand && command.continue_after_failure !== true; } function commandDependencies(command: V1BatchCommand): string[] { return Array.isArray(command.depends_on) ? command.depends_on.filter( (dependencyId): dependencyId is string => typeof dependencyId === 'string' && dependencyId.length > 0 ) : []; } function resolveCommandReferences( command: V1BatchCommand, resultsByCommandId: Map, ): { command: V1BatchCommand; error?: undefined } | { command: V1BatchCommand; error: string } { if (command.phase === 'validate') { return { command }; } const resolved = resolveValueReferences(command.input, resultsByCommandId); if (resolved.error) { return { command, error: resolved.error }; } return { command: { ...command, input: resolved.value as Record, }, }; } function resolveValueReferences( value: unknown, resultsByCommandId: Map, ): { value: unknown; error?: undefined } | { value: unknown; error: string } { if (!value || typeof value !== 'object') { return { value }; } if (Array.isArray(value)) { const resolvedItems: unknown[] = []; for (const item of value) { const resolved = resolveValueReferences(item, resultsByCommandId); if (resolved.error) return { value, error: resolved.error }; resolvedItems.push(resolved.value); } return { value: resolvedItems }; } const objectValue = value as Record; if (Object.prototype.hasOwnProperty.call(objectValue, '$from')) { return resolveReferenceObject(objectValue, resultsByCommandId); } const resolvedObject: Record = {}; for (const [key, child] of Object.entries(objectValue)) { const resolved = resolveValueReferences(child, resultsByCommandId); if (resolved.error) return { value, error: resolved.error }; resolvedObject[key] = resolved.value; } return { value: resolvedObject }; } function resolveReferenceObject( reference: Record, resultsByCommandId: Map, ): { value: unknown; error?: undefined } | { value: unknown; error: string } { const keys = Object.keys(reference); const sourceId = reference.$from; const path = reference.path; if ( keys.length !== 2 || typeof sourceId !== 'string' || sourceId.length < 1 || !Array.isArray(path) || !path.every(segment => ( typeof segment === 'string' || (typeof segment === 'number' && Number.isInteger(segment)) )) ) { return { value: reference, error: 'Reference objects must contain a string $from and a string/integer path.' }; } const source = resultsByCommandId.get(sourceId); if (!source || source.status !== 'succeeded') { return { value: reference, error: 'Reference source did not complete successfully before this command.' }; } let node: unknown = source; for (const segment of path) { if (!node || typeof node !== 'object') { return { value: reference, error: 'Reference path did not resolve in the source command result.' }; } const key = typeof segment === 'number' ? segment : String(segment); if (!Object.prototype.hasOwnProperty.call(node, key)) { return { value: reference, error: 'Reference path did not resolve in the source command result.' }; } node = (node as Record)[key]; } return { value: node }; } function commandResultBase(command: V1BatchCommand): { command_id: string; capability: string } { const commandId = scalarString(command.command_id); const capability = scalarString(command.capability); return { command_id: commandId || 'cmd_missing_command_id', capability, }; } function scalarString(value: unknown): string { return ['string', 'number', 'boolean'].includes(typeof value) ? String(value) : ''; } function invalidCommandResult( base: { command_id: string; capability: string }, message: string, resultMeta?: () => Record | undefined, ): V1BatchResult { return withMeta({ command_id: base.command_id, capability: base.capability, status: 'failed', artifacts: [], error: { code: 'invalid_command', message, }, }, resultMeta); } function invalidReferenceCommandResult( base: { command_id: string; capability: string }, message: string, resultMeta?: () => Record | undefined, ): V1BatchResult { return withMeta({ command_id: base.command_id, capability: base.capability, status: 'failed', artifacts: [], error: { code: 'invalid_reference', message, }, }, resultMeta); } function skippedCommandResult( base: { command_id: string; capability: string }, resultMeta?: () => Record | undefined, ): V1BatchResult { return withMeta({ command_id: base.command_id, capability: base.capability, status: 'skipped', data: { skipped: true }, artifacts: [], }, resultMeta); } function withMeta( result: V1BatchResult, resultMeta?: () => Record | undefined, ): V1BatchResult { const meta = resultMeta?.(); return meta && Object.keys(meta).length > 0 ? { ...result, meta } : result; }