craig-cli 0.19.4 → 0.19.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
var ak=Object.defineProperty;var Ws=(e,t)=>{for(var n in t)ak(e,n,{get:t[n],enumerable:!0})};import{realpath as N0}from"node:fs/promises";import Te from"node:path";function Oe(e){let t=Te.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:Te.join(t,"index.json"),reposDir:Te.join(t,"repos"),workspacesDir:Te.join(t,"workspaces"),runtimeDir:Te.join(t,"runtime"),uiStateFile:Te.join(t,"runtime","ui-state.json"),tasksDir:Te.join(t,"tasks"),jobsDir:Te.join(t,"jobs"),commandsDir:Te.join(t,"commands"),eventsDir:Te.join(t,"events"),orchestrationDir:Te.join(t,"orchestration"),logsDir:Te.join(t,"logs"),logFile:Te.join(t,"logs","craig.jsonl"),artifactsDir:Te.join(t,"artifacts"),worktreesDir:Te.join(t,"worktrees"),configFile:Te.join(t,"config.json")}}import bd from"node:path";import{readFile as Sv}from"node:fs/promises";import{readFile as hk}from"node:fs/promises";import{randomUUID as lk}from"node:crypto";import{chmod as ck,open as dk,readFile as uk,rename as pk,rm as fk}from"node:fs/promises";import ka from"node:path";async function U(e,t,n={}){let r=ka.dirname(e),s=ka.join(r,`.${ka.basename(e)}.${process.pid}.${Date.now()}.${lk()}.tmp`),i=await dk(s,"w",n.mode);try{let o=`${JSON.stringify(t,null,2)}
|
|
3
3
|
`;await i.writeFile(o,"utf8"),await i.sync(),await i.close(),await pk(s,e),n.mode!==void 0&&await ck(e,n.mode)}catch(o){throw await i.close().catch(()=>{}),await fk(s,{force:!0}).catch(()=>{}),o}}async function Vs(e){try{let t=await uk(e,"utf8");return JSON.parse(t)}catch(t){if(mk(t))return null;throw t}}function mk(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}async function Un(e){try{let t=await hk(e.uiStateFile,"utf8"),n=JSON.parse(t);return gk(n,e.uiStateFile)}catch(t){if(yk(t))return null;throw t}}async function gt(e,t){await U(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function Gs(){return{version:1,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null,selectedPtyTabId:null,inputMode:"control",focusedRegion:"tasks",activeTab:"agent",inspectorSection:"task",inspectionMode:"files",openInspectionKind:null,selectedFileTreePath:null,selectedFilePath:null,selectedDiffPath:null,collapsedFileTreePaths:[],selectedActionId:"commit",updatedAt:new Date().toISOString()}}function gk(e,t){if(typeof e!="object"||e===null||e.version!==1||!(e.selectedRepoId===null||typeof e.selectedRepoId=="string")||!(e.selectedWorkspaceId===null||typeof e.selectedWorkspaceId=="string")||!(e.selectedTaskId===null||typeof e.selectedTaskId=="string")||!(e.selectedPtyTabId===void 0||e.selectedPtyTabId===null||typeof e.selectedPtyTabId=="string")||!wn(e,"inputMode")||!wn(e,"focusedRegion")||!wn(e,"activeTab")||!wn(e,"inspectorSection")||!wn(e,"inspectionMode")||!Ks(e,"openInspectionKind")||!Ks(e,"selectedFileTreePath")||!Ks(e,"selectedFilePath")||!Ks(e,"selectedDiffPath")||!$u(e,"collapsedFileTreePaths")||!wn(e,"ignoredUpdateVersion")||!$u(e,"seenPreviewIds")||!wn(e,"selectedActionId")||!wk(e,"readAgentActivityAt")||typeof e.updatedAt!="string")throw new Error(`Craig UI state at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return e}function wn(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function Ks(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function $u(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(n=>typeof n=="string"))}function yk(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}function wk(e,t){if(!(t in e))return!0;let n=e[t];return typeof n=="object"&&n!==null&&!Array.isArray(n)&&Object.values(n).every(r=>typeof r=="number"&&Number.isFinite(r)&&r>=0)}var Ta={};Ws(Ta,{RUNNER_IDS:()=>me,STABLE_RUNNER_IDS:()=>yt,assertEnabled:()=>_u,buildCommand:()=>Lu,getConfiguredProfile:()=>Hs,getDefault:()=>Du,getDisplayName:()=>Fu,getEnabled:()=>Ys,getProfile:()=>Bn,isRunnerType:()=>zs,parse:()=>xu,setRunnerEnabled:()=>Mu,setRunnerPath:()=>ju});var yt=["codex","cursor","claude"],me=[...yt,"pi"];var Nu={codex:{id:"codex",displayName:"Codex",executable:"codex",defaultAgentTitle:"Codex"},cursor:{id:"cursor",displayName:"Cursor",executable:"cursor-agent",defaultAgentTitle:"Cursor"},claude:{id:"claude",displayName:"Claude",executable:"claude",defaultAgentTitle:"Claude"},pi:{id:"pi",displayName:"Pi",executable:"pi",defaultAgentTitle:"Pi"}};var Bn=e=>Nu[e];var Hs=(e,t={})=>{let n=Bn(e),r=t.runners?.[e]?.path?.trim();return{...n,executable:r&&r.length>0?r:n.executable}};var Ys=(e={})=>me.filter(t=>t!=="pi"||e.previews?.piRunner===!0).filter(t=>e.runners?.[t]?.enabled!==!1);var Du=(e={})=>{let t=Ys(e);if(t.length===0)throw new Error("No runners are enabled. Enable at least one runner in .craig/config.json.");return t.includes("codex")?"codex":t[0]};var _u=(e,t={})=>{if(e==="pi"&&t.previews?.piRunner!==!0)throw new Error('Runner "pi" is experimental. Enable the piRunner feature preview in .craig/config.json.');if(t.runners?.[e]?.enabled===!1)throw new Error(`Runner "${e}" is disabled in .craig/config.json.`)};var zs=e=>me.includes(e);var xu=e=>{if(!e||e.length===0)return"codex";if(!zs(e))throw new Error(`Unsupported runner "${e}". Expected one of: ${me.join(", ")}.`);return e};var Fu=e=>Bn(e).displayName;var Lu=(e,t,n={})=>{let r=[Hs(e,n).executable];return t&&t.length>0&&r.push(t),r};var Mu=(e,t,n)=>({...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:n}}});var ju=(e,t,n)=>{let r=e.runners?.[t]??{},{path:s,...i}=r;return{...e,runners:{...e.runners??{},[t]:n!=null?{...r,path:n}:i}}};var ba={};Ws(ba,{PREVIEW_FEATURE_IDS:()=>wt,isEnabled:()=>qu,setEnabled:()=>Uu});var wt=["agentOrchestration","piRunner","fileOpen","panelPolish"];function qu(e,t){return e.previews?.[t]===!0}function Uu(e,t,n){return{...e,previews:{...e.previews,[t]:n}}}import{mkdir as kk,readFile as Tk,writeFile as bk}from"node:fs/promises";import Rk from"node:path";var Pk=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",Bu=async e=>{try{return await Tk(e,"utf8")}catch(t){if(Pk(t))return null;throw t}},Wu=async(e,t)=>{await kk(Rk.dirname(e),{recursive:!0}),await bk(e,t,"utf8")};var Js=(e,t)=>{if(typeof e!="object"||e===null)throw new Error(`Craig config at ${t} is invalid. Expected a JSON object.`);let n=e;if(n.runners!==void 0){if(typeof n.runners!="object"||n.runners===null||Array.isArray(n.runners))throw new Error(`Craig config at ${t} is invalid. "runners" must be an object.`);for(let[r,s]of Object.entries(n.runners)){if(!me.includes(r))throw new Error(`Craig config at ${t} is invalid. "runners.${r}" is not supported. Expected one of: ${me.join(", ")}.`);if(typeof s!="object"||s===null||Array.isArray(s))throw new Error(`Craig config at ${t} is invalid. "runners.${r}" must be an object.`);let i=s;if(i.enabled!==void 0&&typeof i.enabled!="boolean")throw new Error(`Craig config at ${t} is invalid. "runners.${r}.enabled" must be a boolean.`);if(i.path!==void 0&&(typeof i.path!="string"||i.path.trim().length===0))throw new Error(`Craig config at ${t} is invalid. "runners.${r}.path" must be a non-empty string.`)}}if(n.checks!==void 0&&(typeof n.checks!="object"||n.checks===null||!Array.isArray(n.checks.commands)||!n.checks.commands.every(r=>typeof r=="string")))throw new Error(`Craig config at ${t} is invalid. "checks.commands" must be an array of strings.`);if(n.open!==void 0&&(typeof n.open!="object"||n.open===null||!Array.isArray(n.open.command)||!n.open.command.every(r=>typeof r=="string")))throw new Error(`Craig config at ${t} is invalid. "open.command" must be an array of strings.`);if(n.github!==void 0){if(typeof n.github!="object"||n.github===null)throw new Error(`Craig config at ${t} is invalid. "github" must be an object.`);if(n.github.mergeMethod!==void 0&&n.github.mergeMethod!=="merge"&&n.github.mergeMethod!=="rebase"&&n.github.mergeMethod!=="squash")throw new Error(`Craig config at ${t} is invalid. "github.mergeMethod" must be "merge", "rebase", or "squash".`);if(n.github.watchIntervalSeconds!==void 0&&(!Number.isInteger(n.github.watchIntervalSeconds)||n.github.watchIntervalSeconds<=0))throw new Error(`Craig config at ${t} is invalid. "github.watchIntervalSeconds" must be a positive integer.`)}if(n.previews!==void 0){if(typeof n.previews!="object"||n.previews===null||Array.isArray(n.previews))throw new Error(`Craig config at ${t} is invalid. "previews" must be an object.`);for(let[r,s]of Object.entries(n.previews))if(typeof s!="boolean")throw new Error(`Craig config at ${t} is invalid. "previews.${r}" must be a boolean.`)}return n};var Ra=async(e,t={readConfigFile:Bu})=>{let n=await t.readConfigFile(e.configFile);if(!n)return{};if(n.trimStart()[0]!=="{")throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`);let r;try{r=JSON.parse(n)}catch{throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`)}return Js(r,e.configFile)};var Pa=async(e,t,n={writeConfigFile:Wu})=>{Js(t,e.configFile),await n.writeConfigFile(e.configFile,`${JSON.stringify(t,null,2)}
|
|
4
|
-
`)};var Ia={};Ws(Ia,{checkForUpdate:()=>Ku,getCurrent:()=>Xs,isNewer:()=>Sa});var Xs=()=>{try{return"0.19.
|
|
4
|
+
`)};var Ia={};Ws(Ia,{checkForUpdate:()=>Ku,getCurrent:()=>Xs,isNewer:()=>Sa});var Xs=()=>{try{return"0.19.5"}catch{return"unknown"}};var Sk="https://registry.npmjs.org/craig-cli/latest",Ik=3600*1e3,vk={value:null},Vu=/^\d+\.\d+\.\d+$/,Sa=(e,t)=>{if(!Vu.test(e)||!Vu.test(t))return!1;let n=c=>c.split(".").map(Number),[r=0,s=0,i=0]=n(e),[o=0,a=0,l=0]=n(t);return r!==o?r>o:s!==a?s>a:i>l},Ku=async(e={fetch:globalThis.fetch,getCurrent:Xs,cache:vk})=>{let t=e.getCurrent(),n=Date.now();if(e.cache.value&&n-e.cache.value.cachedAt<Ik)return e.cache.value.result;let r=null;try{let i=await e.fetch(Sk,{signal:AbortSignal.timeout(5e3)});i.ok&&(r=(await i.json()).version??null)}catch{}let s={current:t,latest:r,updateAvailable:r!==null&&r!==t&&Sa(r,t)};return e.cache.value={result:s,cachedAt:n},s};var k={load:Ra,save:Pa,previews:ba,runners:Ta,version:Ia};var Gu={CLI_USAGE:2,INPUT_REQUIRED:2,WORKSPACE_CONTEXT_NOT_FOUND:3,WORKSPACE_CONTEXT_INVALID:4,WORKSPACE_NOT_FOUND:3,WORKSPACE_RECORD_INVALID:2,TASK_CONTEXT_NOT_FOUND:3,TASK_CONTEXT_AMBIGUOUS:4,TASK_CONTEXT_CONFLICT:4,TASK_NOT_FOUND:3,TASK_RECORD_INVALID:2,REPO_NOT_FOUND:3,REPO_RECORD_INVALID:2,PR_REPOSITORY_MISMATCH:4,PR_BRANCH_MISMATCH:4,EXTERNAL_DEPENDENCY_FAILED:5,OPERATION_TIMEOUT:6,OPERATION_CANCELLED:6,EVENT_CURSOR_INVALID:2,EVENT_CURSOR_EXPIRED:4,EVENT_JOURNAL_CORRUPT:2,COMMAND_NOT_FOUND:3,COMMAND_RECORD_INVALID:2,COMMAND_STATE_CONFLICT:4,CAPABILITY_NOT_FOUND:3,CAPABILITY_RECORD_INVALID:2,CAPABILITY_DENIED:4,DELEGATION_LIMIT_EXCEEDED:4,FURY_DEFINITION_INVALID:2,FURY_INPUT_INVALID:2,FURY_PLAN_NOT_FOUND:3,FURY_APPROVAL_REQUIRED:4,FURY_RUN_NOT_FOUND:3,FURY_REVIEW_NOT_FOUND:3,FURY_RECORD_INVALID:2,FURY_STATE_CONFLICT:4,FURY_OUTPUT_INVALID:4,PARTIAL_RESULT:7,INTERNAL_ERROR:1},g=class extends Error{code;exitCode;retryable;details;constructor(t,n,r){super(n,r.cause===void 0?void 0:{cause:r.cause}),this.name="CraigError",this.code=t,this.exitCode=Gu[t],this.retryable=r.retryable??!1,this.details=r.details??{}}};function va(e){return e instanceof g?e:new g("INTERNAL_ERROR",e instanceof Error?e.message:"Unknown Craig error",{cause:e})}import{appendFile as Ck,mkdir as Ak,readFile as Ek}from"node:fs/promises";import Ok from"node:path";var Hu=80,Qs=async(e,t)=>{await Ak(Ok.dirname(e.logFile),{recursive:!0});let n={timestamp:new Date().toISOString(),...t};await Ck(e.logFile,`${JSON.stringify(n)}
|
|
5
5
|
`,"utf8")},Yu=async(e,t)=>{try{await Qs(e,t)}catch{}},Zs=async(e,t=Hu)=>{try{let s=(await Ek(e.logFile,"utf8")).trimEnd().split(`
|
|
6
6
|
`).filter(i=>i.length>0).map($k);return{path:e.logFile,lines:s.slice(Math.max(0,s.length-t)),empty:s.length===0}}catch(n){if(Dk(n))return{path:e.logFile,lines:[],empty:!0};throw n}},Ca=async(e,t)=>Qs(e,{level:"error",component:"application",event:Nk(t.context),message:t.message,...t.details?{details:t.details}:{}}),zu=async(e,t)=>{try{await Ca(e,t)}catch{}},Ju=Zs,Xu=async(e,t=Hu)=>Zs(e,t);function $k(e){try{let t=JSON.parse(e);if(!t.timestamp||!t.level||!t.component||!t.event||!t.message)return e;let n=[t.taskId,t.tabId].filter(Boolean).join("/");return`[${t.timestamp}] ${t.level.toUpperCase().padEnd(5)} ${t.component}.${t.event}${n?` ${n}`:""} \u2014 ${t.message}`}catch{return e}}function Nk(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,".").replace(/^\.+|\.+$/g,"")||"error"}function Dk(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var ue={appendErrorLog:Ca,appendErrorLogBestEffort:zu,appendLog:Qs,appendLogBestEffort:Yu,readLog:Zs,readErrorLog:Ju,readRecentErrorLines:Xu};function tp(e){let{commandTokens:t,options:n,help:r}=xk(e);if(r)return Zu({kind:"help"},n);if(t.length===0)return{mode:"interactive",options:n};let[s,i,...o]=t,a;switch(`${s??""}:${i??""}`){case"context:show":Dr(o,"context show"),a={kind:"showContext"};break;case"repo:add":a={kind:"addRepo",path:Aa(o,"Repo path")};break;case"repo:list":Dr(o,"repo list"),a={kind:"listRepos"};break;case"repo:remove":a={kind:"removeRepo",repoId:re(o,"Repo id")};break;case"workspace:add":a={kind:"addWorkspace",path:Aa(o,"Workspace path")};break;case"workspace:list":a=Fk(o);break;case"workspace:archive":a={kind:"archiveWorkspace",workspaceId:re(o,"Workspace id")};break;case"workspace:restore":a={kind:"restoreWorkspace",workspaceId:re(o,"Workspace id")};break;case"workspace:remove":a={kind:"removeWorkspace",workspaceId:re(o,"Workspace id")};break;case"file:open":a={kind:"openFile",path:re(o,"File path")};break;case"task:new":a=Mk(o);break;case"task:create-child":a=jk(o);break;case"task:children":a={kind:"listTaskChildren",...o.length===0?{}:{taskId:re(o,"Task id")}};break;case"task:cancel-tree":a={kind:"cancelTaskTree",...o.length===0?{}:{taskId:re(o,"Task id")}};break;case"task:list":a=Lk(o);break;case"task:current":Dr(o,"task current"),a={kind:"currentTask"};break;case"task:rename":a={kind:"renameTask",title:Aa(o,"Task title")};break;case"task:show":a=o.length===0?{kind:"showCurrentTask"}:{kind:"showTask",taskId:re(o,"Task id")};break;case"task:pr":a=qk(o);break;case"task:repo":if(o[0]!=="add")throw I(`Unsupported task repo command: ${o.join(" ")}`);ti(o,3,"task repo add"),a={kind:"addTaskRepoTarget",taskId:ei(o,1,"Task id"),repoId:ei(o,2,"Repo id")};break;case"task:wait":a=Hk(o);break;case"agent:list":Dr(o,"agent list"),a={kind:"listAgents"};break;case"agent:status":a=Wk(o);break;case"agent:send":a=Vk(o);break;case"command:show":a={kind:"showPromptCommand",commandId:re(o,"Command id")};break;case"command:list":Dr(o,"command list"),a={kind:"listPromptCommands"};break;case"command:cancel":a={kind:"cancelPromptCommand",commandId:re(o,"Command id")};break;case"command:wait":a=Kk(o);break;case"events:list":a=Qu(o,!1);break;case"events:watch":a=Qu(o,!0);break;case"fury:validate":a={kind:"validateFury",file:re(o,"Fury file")};break;case"fury:plan":a=Yk(o);break;case"fury:approve":a={kind:"approveFury",planId:re(o,"Fury plan id")};break;case"fury:run":a={kind:"runFury",planId:re(o,"Fury plan id")};break;case"fury:status":a={kind:"showFury",runId:re(o,"Fury run id")};break;case"fury:watch":a=zk(o);break;case"fury:cancel":a={kind:"cancelFury",runId:re(o,"Fury run id")};break;case"fury:resume":a={kind:"resumeFury",runId:re(o,"Fury run id")};break;case"fury:step":a=Jk(o);break;case"fury:reviews":a=Xk(o);break;case"fury:review":a=Qk(o);break;case"task:logs":a={kind:"streamTaskLogs",taskId:re(o,"Task id")};break;case"task:diff":a={kind:"showTaskDiff",taskId:re(o,"Task id")};break;case"task:open":a={kind:"openTask",taskId:re(o,"Task id")};break;case"task:check":a={kind:"runChecks",taskId:re(o,"Task id")};break;case"task:commit":a={kind:"commitTask",taskId:re(o,"Task id")};break;case"link:add":a={kind:"addTaskLink",taskId:ei(o,0,"Task id"),repoId:ei(o,1,"Repo id")},ti(o,2,"link add");break;case"link:list":a={kind:"listTaskLinks",taskId:re(o,"Task id")};break;default:if(t.length===1&&(s==="help"||s==="--help"||s==="-h")){a={kind:"help"};break}throw I(`Unsupported command: ${t.join(" ")}`)}return Zu(a,n)}function np(e){let t=e[0]==="--"?e.slice(1):e,n=!0;for(let r of t){if(r==="--"){n=!1;continue}if(n&&r==="--json")return!0}return!1}function _k(e){return e.kind==="actFuryReview"?`fury.review.${e.action==="request_changes"?"request-changes":e.action}`:{addWorkspace:"workspace.add",addRepo:"repo.add",listRepos:"repo.list",removeRepo:"repo.remove",listWorkspaces:"workspace.list",archiveWorkspace:"workspace.archive",restoreWorkspace:"workspace.restore",removeWorkspace:"workspace.remove",createTask:"task.new",createChildTask:"task.create-child",listTaskChildren:"task.children",cancelTaskTree:"task.cancel-tree",validateFury:"fury.validate",planFury:"fury.plan",approveFury:"fury.approve",runFury:"fury.run",showFury:"fury.status",watchFury:"fury.watch",cancelFury:"fury.cancel",resumeFury:"fury.resume",completeFuryStep:"fury.step.complete",failFuryStep:"fury.step.fail",listFuryReviews:"fury.reviews.list",showFuryReview:"fury.review.show",actFuryReview:"fury.review.action",listTasks:"task.list",currentTask:"task.current",renameTask:"task.rename",showTask:"task.show",showCurrentTask:"task.show",showTaskPr:"task.pr.show",discoverTaskPr:"task.pr.discover",linkTaskPr:"task.pr.link",refreshTaskPr:"task.pr.refresh",unlinkTaskPr:"task.pr.unlink",listAgents:"agent.list",showAgentStatus:"agent.status",sendAgentPrompt:"agent.send",showPromptCommand:"command.show",listPromptCommands:"command.list",cancelPromptCommand:"command.cancel",waitPromptCommand:"command.wait",waitTask:"task.wait",listEvents:"events.list",watchEvents:"events.watch",addTaskLink:"link.add",addTaskRepoTarget:"task.repo.add",listTaskLinks:"link.list",openFile:"file.open",refreshInteractiveState:"interactive.refresh",showSelectedTask:"task.show",streamTaskLogs:"task.logs",streamSelectedTaskLogs:"task.logs",showTaskDiff:"task.diff",showSelectedTaskDiff:"task.diff",openTask:"task.open",openSelectedTask:"task.open",runChecks:"task.check",runSelectedTaskChecks:"task.check",commitTask:"task.commit",commitSelectedTask:"task.commit",showContext:"context.show",help:"help",exit:"exit"}[e.kind]}function Ea(){return["Craig commands:"," craig [--workspace-root <path>] [--task <id>] [--json] [--no-input] <command>"," craig context show Show resolved workspace, task, and agent-tab context"," craig repo add <path> Register a repo in the current Craig workspace"," craig workspace add <path> Register a repo or parent-directory workspace"," craig repo list List registered repos"," craig repo remove <id> Remove a registered repo"," craig workspace list [--archived] List workspaces"," craig workspace archive <id> Archive a workspace"," craig workspace restore <id> Restore an archived workspace"," craig workspace remove <id> Remove an archived workspace"," craig file open <path> Open a readable file in the active Craig TUI (preview)"," craig task new --repo <repo-id> [--runner codex|cursor|claude|pi] <prompt>"," craig task new --workspace <workspace-id> [--runner codex|cursor|claude|pi] <prompt>"," craig task create-child [--parent <task-id>] [--repo <repo-id> | --workspace <workspace-id>] [--runner codex|cursor|claude|pi] [--idempotency-key <key>] <prompt>"," craig task children [<task-id>] List direct child tasks"," craig task cancel-tree [<task-id>] Cancel a task and all descendants"," craig task list [--repo <repo-id>] List known Craig tasks"," craig task current Show the task resolved from flags, environment, or cwd"," craig task rename <name> Rename the resolved task without changing its ID or worktree"," craig task show [<id>] Show task details; omit id to use resolved context"," craig task repo add <task-id> <repo-id> Provision a repo target in an existing project task"," craig task pr show [<id>] [--repo <repo-id>]"," craig task pr discover [<id>] [--repo <repo-id>]"," craig task pr link [<id>] --pr <url|number> [--repo <repo-id>]"," craig task pr refresh [<id>] [--repo <repo-id>]"," craig task pr unlink [<id>] --pr <url|number> [--repo <repo-id>]"," craig agent list [--task <task-id>] List agent-tab and task roll-up states"," craig agent status [--task <task-id>] [--tab <tab-id>] Show agent state details"," craig agent send --task <task-id> [--tab <tab-id>] (--prompt <text> | --prompt-file <path> | --stdin)"," [--delivery when-ready|immediate] [--timeout <duration>] [--idempotency-key <key>]"," craig command show <command-id> Show a durable prompt command"," craig command list [--task <task-id>] List durable prompt commands"," craig command cancel <command-id> Cancel a queued prompt command"," craig command wait <command-id> [--state <states>] [--timeout <duration>]"," craig task wait [<id>] --state <states> [--tab <tab-id>] [--timeout <duration>]"," craig events list [--task <task-id>] [--type <glob>] [--after <cursor>] --json"," craig events watch [--task <task-id>] [--type <glob>] [--after <cursor>] [--format jsonl]"," craig fury validate <file> Validate a versioned fury YAML definition"," craig fury plan <file> [--root-task <id>] [--input key=value] Create an immutable approval plan"," craig fury approve <plan-id> Approve an exact validated plan (human only)"," craig fury run <plan-id> Start the single run authorized by an approved plan"," craig fury status|watch|cancel|resume <run-id> Inspect or control a durable run"," craig fury step complete|fail --run <run-id> --step <step-id> Explicitly finish agent work"," craig fury reviews list [--run <run-id>] [--state <state>] List human checkpoints"," craig fury review show|approve|reject|request-changes|resubmit <review-id>"," craig task logs <id> Stream Craig-managed logs for a task"," craig task diff <id> Show the current worktree diff for a task"," craig task open <id> Open the task worktree or print its path"," craig task check <id> Run configured checks for a task"," craig task commit <id> Commit all task worktree changes"," craig link add <task-id> <repo-id> Add contextual repo linkage only (does not provision a target)"," craig link list <task-id> List linked repos for a task"].join(`
|
|
7
7
|
`)}function xk(e){let t=[...e];t[0]==="--"&&t.shift();let n=[],r={json:!1,noInput:!1},s=new Set,i=!1,o=!0;for(let a=0;a<t.length;a+=1){let l=t[a];if(l==="--"){o=!1,n.push(l);continue}if(!o||!ep(l)){n.push(l);continue}if(s.has(l))throw I(`Global option ${l} may only be provided once.`);if(s.add(l),l==="--json"){r.json=!0;continue}if(l==="--no-input"){r.noInput=!0;continue}if(l==="--help"||l==="-h"){i=!0;continue}let c=t[a+1];if(c===void 0||c==="--"||ep(c))throw I(`Global option ${l} requires a value.`);a+=1,l==="--workspace-root"?r.workspaceRoot=M(c,"Workspace root"):r.taskId=M(c,"Task id")}return{commandTokens:n,options:r,help:i}}function Fk(e){if(e.length===0)return{kind:"listWorkspaces",archived:!1};if(e.length===1&&e[0]==="--archived")return{kind:"listWorkspaces",archived:!0};throw I(`Unsupported command: workspace list ${e.join(" ")}`)}function Lk(e){if(e.length===0)return{kind:"listTasks"};if(e.length===2&&e[0]==="--repo")return{kind:"listTasks",repoId:M(e[1],"Repo id")};throw I(`Unsupported command: task list ${e.join(" ")}`)}function Mk(e){let t,n,r,s=[],i=!0;for(let a=0;a<e.length;a+=1){let l=e[a];if(l==="--"){i=!1;continue}if(!i||!["--repo","--workspace","--runner"].includes(l)){if(i&&l.startsWith("--"))throw I(`Unsupported task new option: ${l}`);s.push(l);continue}let c=e[a+1];if(c===void 0||c==="--")throw I(`Task option ${l} requires a value.`);if(a+=1,l==="--repo"){if(t!==void 0)throw I("Task option --repo may only be provided once.");t=M(c,"Repo id")}else if(l==="--workspace"){if(n!==void 0)throw I("Task option --workspace may only be provided once.");n=M(c,"Workspace id")}else{if(r!==void 0)throw I("Task option --runner may only be provided once.");try{r=k.runners.parse(c)}catch(u){throw I(u instanceof Error?u.message:"Unsupported runner.")}}}if(!t&&!n)throw I("Task creation requires '--repo <repo-id>' or '--workspace <workspace-id>'.");if(t&&n)throw I("Task creation accepts either '--repo' or '--workspace', not both.");let o=M(s.join(" "),"Task prompt");return{kind:"createTask",...t?{repoId:t}:{},...n?{workspaceId:n}:{},...r?{runner:r}:{},prompt:o}}function jk(e){let t,n,r,s,i,o=[],a=!0;for(let l=0;l<e.length;l+=1){let c=e[l];if(c==="--"){a=!1;continue}if(!a||!["--parent","--repo","--workspace","--runner","--idempotency-key"].includes(c)){if(a&&c.startsWith("--"))throw I(`Unsupported task create-child option: ${c}`);o.push(c);continue}let u=e[l+1];if(u===void 0||u==="--")throw I(`Task option ${c} requires a value.`);if(l+=1,c==="--parent"){if(t)throw I("Task option --parent may only be provided once.");t=M(u,"Parent task id")}else if(c==="--repo"){if(n)throw I("Task option --repo may only be provided once.");n=M(u,"Repo id")}else if(c==="--workspace"){if(r)throw I("Task option --workspace may only be provided once.");r=M(u,"Workspace id")}else if(c==="--runner"){if(s)throw I("Task option --runner may only be provided once.");try{s=k.runners.parse(u)}catch(d){throw I(d instanceof Error?d.message:"Unsupported runner.")}}else{if(i)throw I("Task option --idempotency-key may only be provided once.");i=M(u,"Idempotency key")}}if(n&&r)throw I("Child task creation accepts only one of --repo or --workspace.");return{kind:"createChildTask",...t?{parentTaskId:t}:{},...n?{repoId:n}:{},...r?{workspaceId:r}:{},prompt:M(o.join(" "),"Child task prompt"),...s?{runner:s}:{},...i?{idempotencyKey:i}:{}}}function qk(e){let[t,...n]=e;if(!["show","discover","link","refresh","unlink"].includes(t??""))throw I(`Unsupported command: task pr ${e.join(" ")}`);let r,s,i;for(let a=0;a<n.length;a+=1){let l=n[a];if(l!=="--repo"&&l!=="--pr"){if(l.startsWith("--"))throw I(`Unsupported task pr ${t} option: ${l}`);if(r!==void 0)throw I(`task pr ${t} accepts at most one task id.`);r=M(l,"Task id");continue}let c=n[a+1];if(c===void 0||c==="--")throw I(`Task PR option ${l} requires a value.`);if(a+=1,l==="--repo"){if(s!==void 0)throw I("Task PR option --repo may only be provided once.");s=M(c,"Repo id")}else{if(i!==void 0)throw I("Task PR option --pr may only be provided once.");i=M(c,"Pull request selector")}}if((t==="link"||t==="unlink")&&i===void 0)throw I(`task pr ${t} requires --pr <url|number>.`);if(t!=="link"&&t!=="unlink"&&i!==void 0)throw I(`task pr ${t} does not accept --pr.`);let o={...r?{taskId:r}:{},...s?{repoId:s}:{}};switch(t){case"show":return{kind:"showTaskPr",...o};case"discover":return{kind:"discoverTaskPr",...o};case"link":return{kind:"linkTaskPr",...o,pullRequest:i};case"refresh":return{kind:"refreshTaskPr",...o};case"unlink":return{kind:"unlinkTaskPr",...o,pullRequest:i};default:throw I(`Unsupported command: task pr ${e.join(" ")}`)}}var Oa=300*1e3,Uk=new Set(["idle","working","ready","error"]),Bk=new Set(["queued","delivering","delivered","failed","cancelled"]);function Wk(e){if(e.length===0)return{kind:"showAgentStatus"};if(e.length===2&&e[0]==="--tab")return{kind:"showAgentStatus",tabId:M(e[1],"Agent tab id")};throw I(`Unsupported command: agent status ${e.join(" ")}`)}function Vk(e){let t,n,r="when-ready",s=Oa,i,o=new Set;for(let a=0;a<e.length;a+=1){let l=e[a];if(!["--prompt","--prompt-file","--stdin","--tab","--delivery","--timeout","--idempotency-key"].includes(l))throw I(`Unsupported agent send option: ${l}`);if(o.has(l))throw I(`Agent send option ${l} may only be provided once.`);if(o.add(l),l==="--stdin"){if(t)throw I("Agent send accepts exactly one prompt source.");t={source:"stdin"};continue}let c=e[a+1];if(c===void 0||c.startsWith("--"))throw I(`Agent send option ${l} requires a value.`);if(a+=1,l==="--prompt"||l==="--prompt-file"){if(t)throw I("Agent send accepts exactly one prompt source.");t=l==="--prompt"?{source:"inline",text:M(c,"Prompt")}:{source:"file",path:M(c,"Prompt file")}}else if(l==="--tab")n=M(c,"Agent tab id");else if(l==="--delivery"){if(c!=="when-ready"&&c!=="immediate")throw I('Agent send delivery must be "when-ready" or "immediate".');r=c}else l==="--timeout"?s=Na(c):i=M(c,"Idempotency key")}if(!t)throw I("Agent send requires --prompt, --prompt-file, or --stdin.");return{kind:"sendAgentPrompt",prompt:t,delivery:r,timeoutMs:s,...n?{tabId:n}:{},...i?{idempotencyKey:i}:{}}}function Kk(e){let t=M(e[0]??"","Command id"),n,r=Oa,s=new Set;for(let i=1;i<e.length;i+=1){let o=e[i];if(o!=="--state"&&o!=="--timeout")throw I(`Unsupported command wait option: ${o}`);if(s.has(o))throw I(`Command wait option ${o} may only be provided once.`);s.add(o);let a=e[i+1];if(a===void 0||a.startsWith("--"))throw I(`Command wait option ${o} requires a value.`);i+=1,o==="--state"?n=Gk(a):r=Na(a)}return{kind:"waitPromptCommand",commandId:t,...n?{states:n}:{},timeoutMs:r}}function Gk(e){let t=e.split(",").map(n=>n.trim()).filter(Boolean);if(t.length===0||t.some(n=>!Bk.has(n)))throw I(`Invalid command state list "${e}". Use queued, delivering, delivered, failed, or cancelled.`);return[...new Set(t)]}function Qu(e,t){let n,r,s="human",i=new Set;for(let a=0;a<e.length;a+=1){let l=e[a];if(!["--type","--after","--format"].includes(l))throw I(`Unsupported events ${t?"watch":"list"} option: ${l}`);if(!t&&l==="--format")throw I("--format is supported only by events watch.");if(i.has(l))throw I(`Events option ${l} may only be provided once.`);i.add(l);let c=e[a+1];if(c===void 0||c.startsWith("--"))throw I(`Events option ${l} requires a value.`);if(a+=1,l==="--type")n=M(c,"Event type glob");else if(l==="--after")r=M(c,"Event cursor");else if(c==="jsonl")s="jsonl";else throw I('Events watch format must be "jsonl".')}let o={...n?{typeGlob:n}:{},...r?{after:r}:{}};return t?{kind:"watchEvents",...o,format:s}:{kind:"listEvents",...o}}function Hk(e){let t,n,r,s=Oa,i=new Set;for(let o=0;o<e.length;o+=1){let a=e[o];if(!["--state","--tab","--timeout"].includes(a)){if(a.startsWith("--"))throw I(`Unsupported task wait option: ${a}`);if(t!==void 0)throw I("task wait accepts at most one task id.");t=M(a,"Task id");continue}if(i.has(a))throw I(`Task wait option ${a} may only be provided once.`);i.add(a);let l=e[o+1];if(l===void 0||l.startsWith("--"))throw I(`Task wait option ${a} requires a value.`);o+=1,a==="--state"?n=Zk(l):a==="--tab"?r=M(l,"Agent tab id"):s=Na(l)}if(!n)throw I("task wait requires --state <idle|working|ready|error>[,...].");return{kind:"waitTask",...t?{taskId:t}:{},states:n,...r?{tabId:r}:{},timeoutMs:s}}function Yk(e){let t,n,r={};for(let s=0;s<e.length;s+=1){let i=e[s];if(i!=="--input"&&i!=="--root-task"){if(i.startsWith("--"))throw I(`Unsupported fury plan option: ${i}`);if(t!==void 0)throw I("fury plan accepts exactly one definition file.");t=M(i,"Fury file");continue}let o=e[s+1];if(o===void 0||o.startsWith("--"))throw I(`Fury plan option ${i} requires a value.`);if(s+=1,i==="--root-task"){if(n)throw I("Fury plan option --root-task may only be provided once.");n=M(o,"Root task id");continue}let a=o.indexOf("=");if(a<1)throw I(`Invalid fury input "${o}". Use key=value.`);let l=M(o.slice(0,a),"Fury input name");if(Object.hasOwn(r,l))throw I(`Fury input "${l}" may only be provided once.`);r[l]=o.slice(a+1)}if(!t)throw I("fury plan requires a definition file.");return{kind:"planFury",file:t,inputs:r,...n?{rootTaskId:n}:{}}}function zk(e){let t=M(e[0]??"","Fury run id"),n,r="human";for(let s=1;s<e.length;s+=2){let i=e[s],o=e[s+1];if(!o||!["--after","--format"].includes(i??""))throw I("fury watch supports --after and --format jsonl.");if(i==="--after")n=M(o,"Event cursor");else if(o==="jsonl")r=o;else throw I("fury watch format must be jsonl.")}return{kind:"watchFury",runId:t,...n?{after:n}:{},format:r}}function Jk(e){let t=e[0];if(t!=="complete"&&t!=="fail")throw I("fury step requires complete or fail.");let n=$a(e.slice(1),["--run","--step","--output","--output-file","--stdin","--reason"]),r=M(n.get("--run")??"","Fury run id"),s=M(n.get("--step")??"","Fury step id");if(t==="fail"){if(["--output","--output-file","--stdin"].some(a=>n.has(a)))throw I("fury step fail accepts only --reason.");return{kind:"failFuryStep",runId:r,stepId:s,reason:M(n.get("--reason")??"","Failure reason")}}if(n.has("--reason"))throw I("fury step complete does not accept --reason.");let i=["--output","--output-file","--stdin"].filter(a=>n.has(a));if(i.length>1)throw I("fury step complete accepts only one output source.");let o=i[0];return{kind:"completeFuryStep",runId:r,stepId:s,...o==="--output"?{output:{source:"inline",text:n.get(o)}}:o==="--output-file"?{output:{source:"file",path:n.get(o)}}:o==="--stdin"?{output:{source:"stdin"}}:{}}}function Xk(e){if(e[0]!=="list")throw I("fury reviews requires list.");let t=$a(e.slice(1),["--run","--state"]),n=t.get("--run"),r=t.get("--state");if(r&&!["waiting_for_review","changes_requested","approved","rejected","timed_out","cancelled"].includes(r))throw I(`Unsupported fury review state: ${r}`);return{kind:"listFuryReviews",...n?{runId:n}:{},...r?{state:r}:{}}}function Qk(e){let t=e[0],n=M(e[1]??"","Fury review id");if(t==="show")return ti(e,2,"fury review show"),{kind:"showFuryReview",reviewId:n};if(!t||!["approve","reject","request-changes","resubmit"].includes(t))throw I("Unsupported fury review action.");let r=$a(e.slice(2),["--note","--reason","--summary"]),s=t==="request-changes"?"request_changes":t,i=r.get("--note")??r.get("--reason")??r.get("--summary"),o=t==="approve"?"--note":t==="resubmit"?"--summary":"--reason";if([...r.keys()].some(a=>a!==o))throw I(`fury review ${t} accepts only ${o}.`);return{kind:"actFuryReview",reviewId:n,action:s,...i?{message:i}:{}}}function $a(e,t){let n=new Map;for(let r=0;r<e.length;r+=1){let s=e[r];if(!t.includes(s)||n.has(s))throw I(`Unsupported or duplicate option: ${s}`);if(s==="--stdin"){n.set(s,"true");continue}let i=e[++r];if(i===void 0||i.startsWith("--"))throw I(`Option ${s} requires a value.`);n.set(s,M(i,s))}return n}function Zk(e){let t=e.split(",").map(n=>n.trim()).filter(Boolean);if(t.length===0||t.some(n=>!Uk.has(n)))throw I(`Invalid agent state list "${e}". Use idle, working, ready, or error.`);return[...new Set(t)]}function Na(e){let t=/^(\d+)(ms|s|m|h)$/.exec(e.trim());if(!t)throw I(`Invalid duration "${e}". Use values such as 500ms, 30s, 5m, or 1h.`);let n=Number(t[1]),r={ms:1,s:1e3,m:6e4,h:36e5}[t[2]],s=n*r;if(!Number.isSafeInteger(s))throw I(`Duration "${e}" is too large.`);return s}function Zu(e,t){return{mode:"command",command:e,commandName:_k(e),options:t}}function ep(e){return["--json","--no-input","--workspace-root","--task","--help","-h"].includes(e)}function Dr(e,t){ti(e,0,t)}function ti(e,t,n){if(e.length!==t)throw I(`Command ${n} received an unexpected number of arguments.`)}function re(e,t){if(e.length!==1)throw I(`${t} is required and must be provided once.`);return M(e[0],t)}function Aa(e,t){return M(e.join(" "),t)}function ei(e,t,n){return M(e[t]??"",n)}function M(e,t){let n=e.trim();if(n.length===0)throw I(`${t} cannot be empty.`);return n}function I(e){return new g("CLI_USAGE",`${e}
|