epiq 0.3.6 → 0.3.7
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/dist/mcp.js +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -32,7 +32,7 @@ ${o.message}`);let i=await nr({cwd:e,message:"[epiq:repair-storage-branch]"});re
|
|
|
32
32
|
${o.message}`);w.debug("[sync] set upstream to remote branch");let i=await F({args:["branch","--set-upstream-to",`${Z}/${k}`,k],cwd:e});return c(i)?s(`Failed to set remote upstream
|
|
33
33
|
${i.message}`):u("Configured remote upstream",!0)},Zo=async({worktreeRoot:e,ownEventFileName:t})=>{w.debug("[sync] stage own event file in remote worktree",t);let n=await F({args:["add",Wa(t)],cwd:e});return c(n)?s(`Failed to stage remote own event file
|
|
34
34
|
${n.message}`):u("Staged remote own event file",void 0)},ei=async({repoRoot:e,worktreeRoot:t})=>{let n=await Ga(e);return c(n)?s(n.message):(w.debug("[sync] create remote sync commit"),nr({cwd:t,message:n.data}))},cr=async e=>{w.debug("[sync] push remote worktree");let t=await rr(e);if(c(t))return s(t.message);let n=await F({args:t.data?["push"]:["push","-u",Z,k],cwd:e});return w.debug("[sync] push result",n),c(n)?s(`Failed during remote push
|
|
35
|
-
${n.message}`):u("Pushed remote",!0)},lr=async({repoRoot:e,worktreeRoot:t,ensureUpstream:n})=>{w.debug("[sync] bootstrap remote storage",{repoRoot:e,worktreeRoot:t,ensureUpstream:n});let r=!1,o=[_a(),await Ya({repoRoot:e}),await Qa({repoRoot:e,worktreeRoot:t}),await Za(t),await ed(t),n?await td(t):u("Skipped remote upstream bootstrap",!1)];for(let i of o){if(c(i))return s(i.message);r=r||!!i.data}return w.debug("[sync] bootstrap changed",r),u(n?"Bootstrapped remote storage":"Bootstrapped remote storage (readonly)",r)},ur=(e,t)=>{for(let n of[ot(e),ot(t)]){let r=dn(n);if(c(r))return s(r.message)}return u("Ensured remote layout",void 0)};var ri=async(e=process.cwd())=>{logger.debug("[sync] start readonly sync",{cwd:e});let t=await tr(e);if(c(t))return s(t.message);let n=t.data,r=sr(n);logger.debug("[sync] resolved readonly roots",{repoRoot:n,worktreeRoot:r});let o=await Ct(n);if(c(o))return s(o.message);if(o.data)return s("Cannot sync while a git operation is in progress in the current repo");let i=await ar(n);if(c(i))return s(i.message);logger.debug("[sync] readonly ensure initial commit changed",i.data);let a=await lr({repoRoot:n,worktreeRoot:r,ensureUpstream:!1});if(c(a))return s(a.message);let d=await Ct(r);if(c(d))return s(d.message);if(d.data)return s("Cannot sync while a git operation is in progress in the remote worktree");let l=ur(n,r);if(c(l))return s(l.message);logger.debug("[sync] readonly pull remote branch");let m=await on({cwd:r,remote:Z,branch:k});if(c(m))return s(m.message);logger.debug("[sync] readonly pulled remote",m.data);let g=dr({repoRoot:n,worktreeRoot:r});return c(g)?s(g.message):(logger.debug("[sync] readonly hydrated from remote",g.data),u("Synced from remote",{repoRoot:n,worktreeRoot:r}))},nd=({repoRoot:e,worktreeRoot:t,ownEventFileName:n})=>{let r=Nt({root:e,fileName:n}),o=Nt({root:t,fileName:n});return bt.existsSync(r)?(logger.debug("[sync] merge own event file to remote",{ownEventFileName:n,localFile:r,remoteFile:o}),an({sourceFile:r,targetFile:o})):(logger.debug("[sync] local own event file missing",r),u("Local own event file missing, nothing to merge",!1))},ti=async({repoRoot:e,worktreeRoot:t,ownEventFileName:n})=>{let r=nd({repoRoot:e,worktreeRoot:t,ownEventFileName:n});if(c(r))return s(r.message);let o=await zo(t);if(c(o))return s(o.message);if(!r.data&&!o.data)return u("Own event file already up to date in remote worktree",{createdCommit:!1});let i=await Zo({worktreeRoot:t,ownEventFileName:n});if(c(i))return s(i.message);let a=await ei({repoRoot:e,worktreeRoot:t});return c(a)?s(a.message):u("Merged, staged, and committed own event file",{createdCommit:!0,commitSha:a.data})},ni=({repoRoot:e,worktreeRoot:t,ownEventFileName:n})=>{let r=Nt({root:e,fileName:n}),o=Nt({root:t,fileName:n});logger.debug("[sync] own event file sizes",{local:bt.existsSync(r)?bt.statSync(r).size:0,remote:bt.existsSync(o)?bt.statSync(o).size:0})},oi=async({cwd:e=process.cwd(),ownEventFileName:t})=>{logger.debug("[sync] start write sync",{cwd:e,ownEventFileName:t});let n=await tr(e);if(c(n))return s(n.message);let r=n.data,o=sr(r);logger.debug("[sync] resolved roots",{repoRoot:r,worktreeRoot:o});let i=await
|
|
35
|
+
${n.message}`):u("Pushed remote",!0)},lr=async({repoRoot:e,worktreeRoot:t,ensureUpstream:n})=>{w.debug("[sync] bootstrap remote storage",{repoRoot:e,worktreeRoot:t,ensureUpstream:n});let r=!1,o=[_a(),await Ya({repoRoot:e}),await Qa({repoRoot:e,worktreeRoot:t}),await Za(t),await ed(t),n?await td(t):u("Skipped remote upstream bootstrap",!1)];for(let i of o){if(c(i))return s(i.message);r=r||!!i.data}return w.debug("[sync] bootstrap changed",r),u(n?"Bootstrapped remote storage":"Bootstrapped remote storage (readonly)",r)},ur=(e,t)=>{for(let n of[ot(e),ot(t)]){let r=dn(n);if(c(r))return s(r.message)}return u("Ensured remote layout",void 0)};var ri=async(e=process.cwd())=>{logger.debug("[sync] start readonly sync",{cwd:e});let t=await tr(e);if(c(t))return s(t.message);let n=t.data,r=sr(n);logger.debug("[sync] resolved readonly roots",{repoRoot:n,worktreeRoot:r});let o=await Ct(n);if(c(o))return s(o.message);if(o.data)return s("Cannot sync while a git operation is in progress in the current repo");let i=await ar(n);if(c(i))return s(i.message);logger.debug("[sync] readonly ensure initial commit changed",i.data);let a=await lr({repoRoot:n,worktreeRoot:r,ensureUpstream:!1});if(c(a))return s(a.message);let d=await Ct(r);if(c(d))return s(d.message);if(d.data)return s("Cannot sync while a git operation is in progress in the remote worktree");let l=ur(n,r);if(c(l))return s(l.message);logger.debug("[sync] readonly pull remote branch");let m=await on({cwd:r,remote:Z,branch:k});if(c(m))return s(m.message);logger.debug("[sync] readonly pulled remote",m.data);let g=dr({repoRoot:n,worktreeRoot:r});return c(g)?s(g.message):(logger.debug("[sync] readonly hydrated from remote",g.data),u("Synced from remote",{repoRoot:n,worktreeRoot:r}))},nd=({repoRoot:e,worktreeRoot:t,ownEventFileName:n})=>{let r=Nt({root:e,fileName:n}),o=Nt({root:t,fileName:n});return bt.existsSync(r)?(logger.debug("[sync] merge own event file to remote",{ownEventFileName:n,localFile:r,remoteFile:o}),an({sourceFile:r,targetFile:o})):(logger.debug("[sync] local own event file missing",r),u("Local own event file missing, nothing to merge",!1))},ti=async({repoRoot:e,worktreeRoot:t,ownEventFileName:n})=>{let r=nd({repoRoot:e,worktreeRoot:t,ownEventFileName:n});if(c(r))return s(r.message);let o=await zo(t);if(c(o))return s(o.message);if(!r.data&&!o.data)return u("Own event file already up to date in remote worktree",{createdCommit:!1});let i=await Zo({worktreeRoot:t,ownEventFileName:n});if(c(i))return s(i.message);let a=await ei({repoRoot:e,worktreeRoot:t});return c(a)?s(a.message):u("Merged, staged, and committed own event file",{createdCommit:!0,commitSha:a.data})},ni=({repoRoot:e,worktreeRoot:t,ownEventFileName:n})=>{let r=Nt({root:e,fileName:n}),o=Nt({root:t,fileName:n});logger.debug("[sync] own event file sizes",{local:bt.existsSync(r)?bt.statSync(r).size:0,remote:bt.existsSync(o)?bt.statSync(o).size:0})},oi=async({cwd:e=process.cwd(),ownEventFileName:t})=>{logger.debug("[sync] start write sync",{cwd:e,ownEventFileName:t});let n=await tr(e);if(c(n))return s(n.message);let r=n.data,o=sr(r);logger.debug("[sync] resolved roots",{repoRoot:r,worktreeRoot:o});let i=await ar(r);if(c(i))return s(`Failed to ensure initial commit: ${i.message}`);logger.debug("[sync] ensure initial commit changed",i.data);let a=await Go(r);if(c(a))return s(a.message);if(a.data)return s("Cannot run :sync while the repository is in detached HEAD state");if(t.includes("/")||t.includes("\\"))return s("Own event file must be a file name, not a path");if(!t.endsWith(".jsonl"))return s("Own event file must end with .jsonl");let d=await Ct(r);if(c(d))return s(d.message);if(d.data)return s("Cannot run :sync while a merge, rebase, cherry-pick, or revert is in progress in the current repo");let l=await lr({repoRoot:r,worktreeRoot:o,ensureUpstream:!0});if(c(l))return s(l.message);let m=await Ct(o);if(c(m))return s(m.message);if(m.data)return s("Cannot run :sync while a merge, rebase, cherry-pick, or revert is in progress in the remote worktree");let g=ur(r,o);if(c(g))return s(g.message);let y=!1,N,b=!1,I=!1,T=!1;logger.debug("[sync] pull remote branch before local copy");let S=await on({cwd:o,remote:Z,branch:k});if(c(S))return s(S.message);b=S.data,logger.debug("[sync] pulled remote",b);let R=dr({repoRoot:r,worktreeRoot:o});if(c(R))return s(R.message);T=R.data,logger.debug("[sync] hydrated from remote",T);let B=await ti({repoRoot:r,worktreeRoot:o,ownEventFileName:t});if(c(B))return s(B.message);if(y=B.data.createdCommit,N=B.data.commitSha,ni({repoRoot:r,worktreeRoot:o,ownEventFileName:t}),logger.debug("[sync] sync own file result",B.data),y||l.data){let G=await cr(o),ie=G;if(c(G)&&jo(G.message)){let Lt=await on({cwd:o,remote:Z,branch:k});if(c(Lt))return s(Lt.message);let De=await ti({repoRoot:r,worktreeRoot:o,ownEventFileName:t});if(c(De))return s(De.message);De.data.createdCommit&&(y=!0,N=De.data.commitSha),ni({repoRoot:r,worktreeRoot:o,ownEventFileName:t}),logger.debug("[sync] retry sync own file result",De.data),ie=await cr(o)}if(c(ie))return s(ie.message);I=ie.data,logger.debug("[sync] pushed remote",I)}else logger.debug("[sync] no commit created, skipped push");if(y){let G=await F({args:["rev-parse","HEAD"],cwd:o});if(c(G))return s(G.message);N=G.data.stdout.trim()}return u("Synced event logs with remote",{repoRoot:r,worktreeRoot:o,createdCommit:y,commitSha:N,pulled:b,pushed:I,hydrated:T,bootstrapped:l.data})};import{ulid as ii}from"ulid";var it=null,Ue=()=>structuredClone(it),st=e=>it=e,si=()=>{let{currentNode:e,selectedIndex:t}=v(),r=M(e.id)[t];return r?u("Resolved selected child",r):s("Target node not found")};function mr(e){let t=si();if(c(t))return t;let{currentNode:n,nodes:r}=v();if(!n.parentNodeId)return s("Missing parent node id");let o=r[n.parentNodeId];if(!o)return s("Missing parent node");let i=W(o.id),a=i.findIndex(({id:N})=>N===n.id);if(a<0)return s("Current node not found among siblings");let d=i[a+e];if(!d)return s("Missing sibling node");let l=X();if(c(l))return s("Unable to resolve user ID");let{userId:m,userName:g}=l.data;if(st({id:ii(),userId:m,userName:g,action:"move.node",payload:{id:t.data.id,parent:d.id,pos:{at:"end"}}}),!it)return s("Could not materialize move state");let y=nt(it,!0);return c(y)?y:u("Node moved successfully",y.data)}function pr(e){let t=si();if(c(t))return t;let{currentNode:n,selectedIndex:r}=v(),i=W(n.id)[r+e];if(!i)return s("Missing sibling node");let a=X();if(c(a))return s("Unable to resolve user ID");let{userId:d,userName:l}=a.data;if(st({id:ii(),userId:d,userName:l,action:"move.node",payload:{id:t.data.id,parent:n.id,pos:{at:e===1?"after":"before",sibling:i.id}}}),!it)return s("Could not materialize move state");let m=nt(it,!0);return c(m)?m:u("Node moved successfully",m.data)}import rd from"node:os";import ai from"node:path";import{z as It}from"zod";var od={userId:"",userName:"",preferredEditor:"",autoSync:!1},di=It.object({preferredEditor:It.string().optional(),userName:It.string().optional(),userId:It.string().optional(),autoSync:It.boolean().optional()}).strict(),id=".epiq",sd="config.json",ci=()=>ai.join(rd.homedir(),id),gr=()=>ai.join(ci(),sd),fr=()=>{try{return le.mkDir(ci()),u("Ensured ~/.epiq exists",null)}catch{return s("Unable to create ~/.epiq")}},ad=e=>{let t;try{t=JSON.parse(e)}catch{return s("Invalid ~/.epiq/config.json JSON")}let n=di.safeParse(t??{});return n.success?u("Parsed config",n.data):s(`Invalid ~/.epiq/config.json shape: ${n.error.issues.map(r=>r.path.join(".")||r.message).join(", ")}`)},li=()=>{let e=fr();if(c(e))return s(e.message);let t=gr(),n=le.readFile(t);return n==null||n.trim()===""?u("No config found, using empty config",{autoSync:!1,preferredEditor:"",userId:"",userName:""}):ad(n)},ui=e=>{let t=fr();if(c(t))return s(t.message);let n=di.safeParse(e);if(!n.success)return s(`Invalid config: ${n.error.issues.map(o=>o.path.join(".")||o.message).join(", ")}`);let r=gr();try{return le.writeToFile(r,JSON.stringify(n.data,null,2)+`
|
|
36
36
|
`),u("Config written",null)}catch{return s("Unable to write ~/.epiq/config.json")}},cn=e=>{let t=li();if(c(t))return s("Failed to read existing config");let n={...t.data,...e};return ui(n)},mi=()=>{let e=gr(),t=fr();if(c(t))return s("Unable to create ~/.epiq");if(!(le.readFile(e)!==null)){let l=ui(od);if(c(l))throw new Error("Unable to create ~/.epiq/config.json")}let r=li();if(c(r))throw new Error(r.message||"Unable to load settings");let{preferredEditor:o,userName:i,userId:a,autoSync:d}=r.data;return!i||!a?s("User name or ID not configured in ~/.epiq/config.json"):u("successfully loaded settings",{preferredEditor:o??"",userName:i,userId:a,autoSync:d??!1})};var pi=e=>Object.values(v().tags).find(t=>t.name===e),gi=e=>Object.values(v().contributors).find(t=>t.name===e),fi=[{systemOnly:!0,intent:L.Move,mode:f.COMMAND_LINE,action:()=>{let e=X();if(c(e))return s("Unable to resolve user ID");let{modifier:t}=re().commandMeta,n=()=>{let d=Ue();if(!d)return s("No pending move state");let l=d.payload.id;if(!v().nodes[l])return s("Moved node not found");let g=d.payload.parent,y=v().nodes[g];if(!y)return s("Move parent not found");let N=M(g).findIndex(b=>b.id===l);return N===-1?s("Moved node not found among rendered children"):(U.navigate({currentNode:y,selectedIndex:N}),u("Synchronized navigation to moved node",null))},r=d=>{if(c(d))return s(d.message);let l=n();return c(l)?s(l.message):u("Updated move preview",null)},{currentNode:o,selectedIndex:i}=v(),a=M(o.id)[i];if(!a)return A({mode:f.DEFAULT}),s("No move target");if(t==="start"){if(a.readonly)return s("Target node is read-only");if(i===-1)return s("No item selected");if(!a.parentNodeId)return s("Target has no parent");let d=M(a.parentNodeId),l=d.findIndex(({id:b})=>b===a.id);if(l===-1)return s("Target not found among siblings");let m=d[l-1],g=d[l+1],y=g!=null?{at:"before",sibling:g.id}:m!=null?{at:"after",sibling:m.id}:{at:"start"};st({id:$(),action:"move.node",payload:{id:a.id,parent:a.parentNodeId,pos:y},...e.data}),A({mode:f.MOVE});let N=n();return c(N)?s(N.message):u("Move initialized",null)}if(t==="next")return A({mode:f.MOVE}),r(pr(1));if(t==="previous")return A({mode:f.MOVE}),r(pr(-1));if(t==="to-next")return A({mode:f.MOVE}),r(mr(1));if(t==="to-previous")return A({mode:f.MOVE}),r(mr(-1));if(t==="confirm"){A({mode:f.DEFAULT});let d=Ue();if(!d)return s("No pending move to confirm");let l=Q(d);if(c(l))return l;let m=n();return c(m)?s(m.message):(st(null),u("Moved item",null))}return t==="cancel"?(st(null),A({mode:f.DEFAULT}),u("Cancelling move",null)):s("Invalid move modifier")}},{intent:L.Delete,mode:f.COMMAND_LINE,action:()=>{let e=X();if(c(e))return s("Unable to resolve user ID");let{currentNode:t,selectedIndex:n}=v(),r=M(t.id)[n];return r?Q({id:$(),action:"delete.node",payload:{id:r.id},...e.data}):s("Unable to resolve child to delete")},onSuccess:()=>A({mode:f.DEFAULT})},{intent:L.Edit,mode:f.COMMAND_LINE,action:()=>{let e=X();if(c(e))return s("Unable to resolve user ID");let t=be(v().breadCrumb,"TICKET");if(c(t))return s("Edit target must be an issue");let n=t.data;if(n.readonly)return s("Cannot edit readonly field");let{currentNode:r,selectedIndex:o}=v();if(!M(n.id)[o])return s("No selected field");let a=M(r.id)[o];if(!a)return s("No selected field");if(a.readonly)return s("Cannot edit readonly field");let d=a.props.value;if(typeof d!="string")return s("Selected field is not editable text");let l=So(d);if(c(l))return s("Failed to edit field");let m=l.data;return m===d?u("No changes made",null):a.title==="Description"?Q({id:$(),action:"edit.description",payload:{id:a.id,md:m},...e.data}):a.title==="Title"?Q({id:$(),action:"edit.title",payload:{id:a.id,name:m},...e.data}):s(`Editing not supported for "${a.title}"`)},onSuccess:()=>A({mode:f.DEFAULT})},{intent:L.Filter,mode:f.COMMAND_LINE,action:()=>{let{modifier:e,inputString:t}=re().commandMeta,n=/(!=|=)/,[r,o]=e.split(n);if(!r||!(d=>z(p.FILTER).map(l=>l.split(n)[0]).includes(d))(r))return s("Invalid filter modifier");let a={target:r,operator:"=",value:t.trim()};return de(d=>({...d,filters:e==="clear"?[]:[...d.filters,a],mode:f.DEFAULT})),u("Viewing help",null)}},{intent:L.ViewHelp,mode:f.COMMAND_LINE,action:()=>(A({mode:f.HELP}),u("Viewing help",null))},{intent:L.CloseIssue,mode:f.COMMAND_LINE,action:()=>{let e=X();if(c(e))return s("Unable to resolve user ID");let{currentNode:t,selectedIndex:n}=v(),r=M(t.id)[n];if(!r)return s("Unable to close issue, no target found");if(!r.parentNodeId)return s("No target parent found");if(!ye(r))return s("Cannot close in this context");let o=Q({id:$(),action:"close.issue",payload:{id:r.id,parent:r.parentNodeId},...e.data});return c(o)?o:u("Viewing help",null)}},{intent:L.ReopenIssue,mode:f.COMMAND_LINE,action:()=>{let e=X();if(c(e))return s("Unable to resolve user ID");let{currentNode:t,selectedIndex:n}=v(),r=M(t.id)[n];if(!r)return s("Unable to reopen issue, no target found");let o=r.context==="TICKET"?u("Resolved ticket",r):ke(r.id,"TICKET");if(c(o))return s("Cannot reopen in this context");let i=o.data,a=Q({id:$(),action:"reopen.issue",payload:{id:i.id},...e.data});return c(a)?a:u("Issue reopened",null)},onSuccess:()=>A({mode:f.DEFAULT})},{intent:L.SetUserName,mode:f.COMMAND_LINE,action:()=>{let{userId:e,preferredEditor:t,userName:n}=pe(),r=Kt()?.trim();if(!r)return s("No username provided");let o=r??n,i=e??$();if(!o||!i)return s("Unable to resolve user name or id");let a=cn({userName:o,userId:i,preferredEditor:t??""});return c(a)?a:(Ye({userName:o,userId:i}),A({mode:f.DEFAULT}),u(`Username set to "${r}"`,null))}},{intent:L.Init,mode:f.COMMAND_LINE,action:()=>{let e=xr();if(c(e))return e;let{rootNodeId:t,nodes:n}=v();return U.navigate({currentNode:n[t],selectedIndex:0}),A({mode:f.DEFAULT}),u("Project initialized",null)}},{intent:L.SetEditor,mode:f.COMMAND_LINE,action:()=>{let e=Kt()?.trim();if(!e)return s("No editor provided");let t=cn({preferredEditor:e});return c(t)?t:(Ye({preferredEditor:e}),A({mode:f.DEFAULT}),u(`Editor configuration set to "${e}"`,null))}},{intent:L.SetAutoSync,mode:f.COMMAND_LINE,action:()=>{let e=re().commandMeta.modifier;if(e!=="true"&&e!=="false")return s("Invalid response");let t=e.toLowerCase()==="true",n=cn({autoSync:t});return c(n)?n:(Ye({autoSync:t}),A({mode:f.DEFAULT}),u(`Auto synchronization set to "${t}"`,null))}},{intent:L.NewItem,mode:f.COMMAND_LINE,action:(e,t)=>{let n=X();if(c(n))return s("Unable to resolve user ID");if(!t.inputString)return s(`provide a name for your ${t.modifier}`);let{breadCrumb:r,currentNode:o,selectedIndex:i}=v(),a=d=>{let l=Q(d);if(c(l))return l;let m=C.getNode(l.data.result.id);if(!m)return s("Created node not found");if(!m.parentNodeId)return l;let g=C.getNode(m.parentNodeId);return g?(U.navigate({currentNode:g,selectedIndex:C.getSiblings(m.parentNodeId).findIndex(({id:y})=>y===m.id)}),l):s("Parent node not found")};if(t.modifier==="board"){let{rootNodeId:d}=v(),l=C.getNode(d);return l?a({id:$(),action:"add.board",payload:{id:$(),name:t.inputString,parent:l.id},...n.data}):s("Workspace not found")}if(t.modifier==="swimlane"){let d=be(r,"BOARD");return c(d)?s("Unable to add swimlane in this context"):a({id:$(),action:"add.swimlane",payload:{id:$(),name:t.inputString,parent:d.data.id},...n.data})}if(t.modifier==="issue"){let d=M(o.id)[i],l=o.context==="SWIMLANE"?o:o.context==="BOARD"&&d?.context==="SWIMLANE"?d:(()=>{let b=be(r,"SWIMLANE");return c(b)?null:b.data})();if(!l)return s("Unable to add issue in this context");let m=To({name:t.inputString,parent:l.id,user:n.data}),g=ko(m);if(g.some(b=>c(b)))return s("Issue create failed: "+g.filter(c).map(b=>b.message).filter(Boolean).join(", "));let y=g[0];if(!y||c(y))return s("Issue creation failed");let N=m[0]?.payload.id;return N?(U.navigate({currentNode:l,selectedIndex:C.getSiblings(l.id).findIndex(({id:b})=>b===N)}),u("Issue created",null)):s("Unable to determine ticket id")}return Wr()},onSuccess:()=>A({mode:f.DEFAULT})},{intent:L.SetView,mode:f.COMMAND_LINE,action:()=>{let{commandMeta:e}=re();return e.validity===Ne.Invalid?s("Invalid command "+xe):(de(t=>({...t,viewMode:e.modifier==="wide"?"wide":e.modifier==="dense"?"dense":t.viewMode})),u("View set",null))},onSuccess:()=>A({mode:f.DEFAULT})},{intent:L.Rename,mode:f.COMMAND_LINE,action:()=>{let e=X();if(c(e))return s("Unable to resolve user ID");let{currentNode:t,selectedIndex:n}=v(),r=M(t.id)[n];if(!r)return s("Missing node");if(r.readonly)return s("Cannot rename readonly node");let o=Kt();return o?Q({id:$(),action:"edit.title",payload:{id:r.id,name:o},...e.data}):s("Provide a new name")},onSuccess:()=>A({mode:f.DEFAULT})},{intent:L.UntagTicket,mode:f.COMMAND_LINE,action:()=>{let e=X();if(c(e))return s("Unable to resolve user ID");let{modifier:t,inputString:n}=re().commandMeta,r=(t||n).trim();if(!r)return s("Provide a tag");let o=pi(r);if(!o)return s(`Tag "${r}" does not exist`);let{selectedNode:i}=v();if(!i)return s("Invalid untag target");let a=ke(i.id,"TICKET");if(c(a))return s("Unable to untag issue in this context");let d=a.data,l=C.getFieldByTitle(d.id,"Tags");if(!l)return s("Unable to locate tags field");let m=M(l.id).find(g=>g.props?.value===o.id);return m?Q({id:$(),action:"untag.issue",payload:{id:m.id,target:d.id,tagId:o.id},...e.data}):s("Issue is not tagged with that tag")},onSuccess:()=>A({mode:f.DEFAULT})},{intent:L.TagTicket,mode:f.COMMAND_LINE,action:()=>{let e=X();if(c(e))return s("Unable to resolve user ID");let{modifier:t,inputString:n}=re().commandMeta,r=(t||n).trim();if(!r)return s("Provide a tag");let{selectedIndex:o,currentNode:i}=v(),a=M(i.id)[o];if(!a)return s("Invalid tag target");let d=ke(a.id,"TICKET");if(c(d))return s("Unable to tag issue in this context");let l=d.data,m=pi(r),g;if(m)g=m.id;else{let b=$(),I=Q({id:$(),action:"create.tag",payload:{id:b,name:r},userId:e.data.userId,userName:e.data.userName});if(c(I))return I;g=I.data.result.id}let y=C.getFieldByTitle(l.id,"Tags");return y?M(y.id).some(b=>b.props?.value===g)?s("Already tagged with that tag"):Q({id:$(),action:"tag.issue",payload:{id:$(),target:l.id,tagId:g},...e.data}):s("Unable to locate tags field")},onSuccess:()=>A({mode:f.DEFAULT})},{intent:L.AssignUserToTicket,mode:f.COMMAND_LINE,action:()=>{let e=X();if(c(e))return s("Unable to resolve user ID");let{modifier:t,inputString:n}=re().commandMeta,r=(t||n).trim();if(!r)return s("Provide an assignee");let{selectedIndex:o,currentNode:i}=v(),a=M(i.id)[o];if(!a)return s("Invalid assign target");let d=ke(a.id,"TICKET");if(c(d))return s("Unable to assign issue in this context");let l=d.data,m=gi(r),g;if(m)g=m.id;else{let b=$(),I=Q({id:$(),action:"create.contributor",payload:{id:b,name:r},userId:e.data.userId,userName:e.data.userName});if(c(I))return I;g=I.data.result.id}let y=C.getFieldByTitle(l.id,"Assignees");return y?M(y.id).some(b=>b.props?.value===g)?s("Assignee already assigned"):Q({id:$(),action:"assign.issue",payload:{id:$(),target:l.id,contributor:g},...e.data}):s("Unable to locate assignees field")},onSuccess:()=>A({mode:f.DEFAULT})},{intent:L.UnassignUserFromTicket,mode:f.COMMAND_LINE,action:()=>{let e=X();if(c(e))return s("Unable to resolve user ID");let{modifier:t,inputString:n}=re().commandMeta,r=(t||n).trim();if(!r)return s("Provide an assignee to remove");let o=gi(r);if(!o)return s(`Assignee "${r}" does not exist`);let{selectedNode:i}=v();if(!i)return s("Invalid unassign target");let a=ke(i.id,"TICKET");if(c(a))return s("Unable to unassign in this context");let d=a.data,l=C.getFieldByTitle(d.id,"Assignees");if(!l)return s("Unable to locate assignees field");let m=M(l.id).find(g=>g.props?.value===o.id);return m?Q({id:$(),action:"unassign.issue",payload:{id:m.id,target:d.id,contributor:o.id},...e.data}):s(`Issue is not assigned to "${r}"`)},onSuccess:()=>A({mode:f.DEFAULT})},{intent:L.Sync,mode:f.COMMAND_LINE,action:async()=>{j(()=>""),A({syncStatus:{msg:"Syncing",status:"syncing"}});let{userId:e,userName:t}=pe();if(!e)return s("Unable to resolve userId");if(!t)return s("Unable to resolve userName");let n=Ke()?xr():u("No pending default events",null);if(c(n))return s(`Unable to persist default events. ${n.message}`);let r=X();if(c(r)||!r.data)return s("Unable to resolve event log path");let o=Jn(r.data);logger.debug("[sync-command] pending defaults",Ke());let i=await oi({ownEventFileName:o});if(c(i))return A({syncStatus:{msg:i.message,status:"outOfSync"}}),s(`Unable to sync state. ${i.message}`);A({syncStatus:{msg:"Synced",status:"synced"},mode:f.DEFAULT});let a=vt();return c(a)?s("Unable to load events"):(Ve(a.data),u("Synced",!0))}},{intent:L.Peek,mode:f.COMMAND_LINE,action:async()=>{let e=be(v().breadCrumb,"BOARD");if(c(e))return e;let t=vt();if(c(t))return s(t.message);let n=t.data,{modifier:r}=re().commandMeta,o;if(r==="now"){let y=yr();if(c(y))return y;let N=Ve(n);return N.some(c)?s(N.map(b=>b.message).join(", ")):(A({mode:f.DEFAULT,readOnly:!1,timeMode:"live",unappliedEvents:[]}),u("Peeking now",!0))}if(r==="prev"){let y=v().eventLog.at(-2),N=Wn(y);if(N===null)return s("No previous event to peek");o=N}else if(r==="next"){let y=v().unappliedEvents.at(0),N=Wn(y);if(N===null)return s("No next event to peek");o=N}else{let y=Ht(r);if(!y)return s("Invalid peek date");o=y.getTime()}let i=e.data.id,{appliedEvents:a,unappliedEvents:d}=Do(n,o),l=yr();if(c(l))return l;let m=Ve(a);if(m.some(c))return s(m.map(y=>y.message).join(", "));let g=v().nodes[i];return g?(U.navigate({currentNode:g,selectedIndex:0}),A({mode:f.DEFAULT,readOnly:!0,timeMode:"peek",unappliedEvents:d}),u("Peeking ",!0)):s("Board did not exist at peek date")}}];var dd=new Set(["peek","filter","view-help"]),ue=async({isForceExecutedBySystem:e=!1}={})=>{let{commandMeta:{command:t,validity:n,modifier:r,inputString:o}}=re();if(!t)return s("No command to confirm");if(!e&&n===Ne.Invalid)return s("Invalid command");let i=Eo(t);if(go(),v().readOnly&&!dd.has(i))return yt({result:xe.Fail,message:"Command not available in readonly state",data:null});let a=fi.filter(l=>e||l.systemOnly!==!0).find(l=>l.intent===i);if(!a)return yt({result:xe.Fail,message:"Command not found",data:null});let d=await a.action(a,{command:t,inputString:o,modifier:r});return c(d)?yt(d):(fo({addToHistory:!e}),a.onSuccess?.(),yt(d))};var ln=[{intent:x.Exit,mode:f.MOVE,description:"[<Esc>] exit context / cancel",action:()=>(A({mode:f.COMMAND_LINE}),j(()=>"move cancel"),ue({isForceExecutedBySystem:!0}))},{intent:x.InitMove,mode:f.DEFAULT,description:"[m] move init/confirm",action:()=>(A({mode:f.COMMAND_LINE}),j(()=>"move start"),ue({isForceExecutedBySystem:!0}))},{intent:x.ConfirmMove,mode:f.MOVE,action:()=>(A({mode:f.COMMAND_LINE}),j(()=>"move confirm"),ue({isForceExecutedBySystem:!0}))}],un=[{intent:x.MovePreviousItem,mode:f.MOVE,action:()=>Ue()?(A({mode:f.COMMAND_LINE}),j(()=>"move previous"),ue({isForceExecutedBySystem:!0})):s("No pending move")},{intent:x.MoveNextItem,mode:f.MOVE,action:()=>Ue()?(A({mode:f.COMMAND_LINE}),j(()=>"move next"),ue({isForceExecutedBySystem:!0})):s("No pending move")}],yi=[{intent:x.MoveToNextContainer,mode:f.MOVE,action:()=>Ue()?(A({mode:f.COMMAND_LINE}),j(()=>"move to-next"),ue({isForceExecutedBySystem:!0})):s("No pending move")},{intent:x.MoveToPreviousContainer,mode:f.MOVE,action:()=>Ue()?(A({mode:f.COMMAND_LINE}),j(()=>"move to-previous"),ue({isForceExecutedBySystem:!0})):s("No pending move")}];var xi={[P.WORKSPACE]:[...ln,...un],[P.BOARD]:[...ln,...un],[P.SWIMLANE]:[...ln,...un,...yi],[P.TICKET]:[],[P.FIELD]:[],[P.FIELD_LIST]:[],[P.TEXT]:[]};var vi=[{intent:x.AddItem,mode:f.DEFAULT,description:"[n] new...",action:()=>(A({mode:f.COMMAND_LINE}),j(()=>`${p.NEW} `),u("Adding new item",null))},{intent:x.Delete,mode:f.DEFAULT,description:"[d] delete",action:()=>(A({mode:f.COMMAND_LINE}),j(()=>`${p.DELETE} `),u("Deleting item",null))},{intent:x.InitCommandLine,mode:f.DEFAULT,description:"[:] focus command line",action:()=>(A({mode:f.COMMAND_LINE}),j(()=>""),u("Entering command line mode",null))},{intent:x.Confirm,mode:f.DEFAULT,description:"[<Enter>] confirm/enter",action:()=>(U.enterChildNode(),u("Entering context",null))},{intent:x.Exit,mode:f.DEFAULT,description:"[q] exit context",action:()=>(U.enterParentNode(),u("Exiting context",null))},{intent:x.NavPreviousItem,mode:f.DEFAULT,description:"[arrows/hjkl] navigate",action:()=>(U.navigateToPreviousItem(),u("Navigating to previous item",null))},{intent:x.NavNextItem,mode:f.DEFAULT,action:()=>(U.navigateToNextItem(),u("Navigating to next item",null))},{intent:x.NavToPreviousContainer,mode:f.DEFAULT,action:()=>(U.navigateToPreviousContainer(),u("Navigating to previous container",null))},{intent:x.NavToNextContainer,mode:f.DEFAULT,action:()=>(U.navigateToNextContainer(),u("Navigating to next container",null))},{intent:x.Edit,mode:f.DEFAULT,action:()=>(A({mode:f.COMMAND_LINE}),j(()=>"edit"),ue(),u("Fired command",!0))},{intent:x.SetViewDense,mode:f.DEFAULT,description:"[v] view change (wide/dense)",action:()=>(A({viewMode:"dense"}),u("View set",null))},{intent:x.SetViewWide,mode:f.DEFAULT,action:()=>(A({viewMode:"wide"}),u("View set",null))}];var hi=[{intent:x.ViewHelp,mode:f.DEFAULT,action:()=>(A({mode:f.HELP}),u("Viewing help",null))},{intent:x.Exit,mode:f.HELP,action:()=>(A({mode:f.DEFAULT}),u("Exiting help",null))},{intent:x.Confirm,mode:f.COMMAND_LINE,action:()=>(ue(),u("Executing command",null))},{intent:x.MoveCursorLeft,mode:f.COMMAND_LINE,action:()=>(Gn(-1),u("Moving cursor left",null))},{intent:x.MoveCursorRight,mode:f.COMMAND_LINE,action:()=>(Gn(1),u("Moving cursor right",null))},{intent:x.MoveCursorLeftOfWord,mode:f.COMMAND_LINE,action:()=>(qn("left"),u("Moving cursor left of word",null))},{intent:x.MoveCursorRightOfWord,mode:f.COMMAND_LINE,action:()=>(qn("right"),u("Moving cursor right of word",null))},{intent:x.ExitCommandLine,mode:f.COMMAND_LINE,action:()=>(A({mode:f.DEFAULT}),u("Exiting command line",null))},{intent:x.AutoCompleteCommand,mode:f.COMMAND_LINE,action:()=>(j((e,{remainder:t})=>t?e+t:e),u("Auto-completing command",null))},{intent:x.CaptureInput,mode:f.COMMAND_LINE,action:(e,{sequence:t})=>(j(n=>n+t),u("Capturing input",null))},{intent:x.EraseInput,mode:f.COMMAND_LINE,action:()=>(mo(),u("Erasing input",null))},{intent:x.EraseInputWord,mode:f.COMMAND_LINE,action:()=>(po(),u("Erasing input word",null))},{intent:x.GetLastCommandFromHistory,mode:f.COMMAND_LINE,action:()=>(yo(),u("Getting last command from history",null))},{intent:x.GetNextCommandFromHistory,mode:f.COMMAND_LINE,action:()=>(xo(),u("Getting next command from history",null))}];import cd from"chalk";var mn=": for command line",Ei="q to exit",Ci=`${cd.hex(E.accent)("m")} to confirm`,vr={[P.WORKSPACE]:[mn],[P.BOARD]:[mn],[P.BOARD+f.COMMAND_LINE]:[mn],[P.SWIMLANE]:[mn],[P.TICKET+f.HELP]:[Ei],[P.SWIMLANE+f.HELP]:[Ei],[P.TICKET]:[],[P.FIELD]:[],[P.SWIMLANE+f.MOVE]:[Ci],[P.TICKET+f.MOVE]:[Ci]};var pn=e=>e.trim().toLocaleLowerCase(),ld=(e,t)=>{let n=C.getFieldByTitle(e,t);if(!n)return"";let r=n.props?.value;return typeof r=="string"?r:""},ud=e=>{let{tags:t}=v(),n=C.getFieldByTitle(e,"Tags");return n?W(n.id).map(r=>{let o=r.props?.value;return typeof o=="string"?t[o]?.name:void 0}).filter(r=>!!r):[]},md=e=>{let{contributors:t}=v(),n=C.getFieldByTitle(e,"Assignees");return n?W(n.id).map(r=>{let o=r.props?.value;return typeof o=="string"?t[o]?.name:void 0}).filter(r=>!!r):[]},Ni=(e,t)=>{let n=t.value;if(!n)return!0;switch(t.target){case"title":return pn(e.title??"").includes(n);case"description":return pn(ld(e.id,"Description")).includes(n);case"tag":return ud(e.id).map(pn).some(d=>d.includes(n));case"assignee":return md(e.id).map(pn).some(d=>d.includes(n));default:return!0}};function bi(e,t,n){let r=t[e];if(!r)return s("buildBreadCrumb(): current node not found");let o=[],i=r;for(;i&&(o.push(i),!(i.id===n||!i.parentNodeId));)i=t[i.parentNodeId];let a=o[o.length-1];return!a||a.id!==n?s("buildBreadCrumb(): node is not connected to root"):(o.reverse(),u("Breadcrumb built",o))}var Ii=e=>{let t={};for(let n of e)n.intent&&(t[n.mode]||(t[n.mode]={}),t[n.mode][n.intent]=n);return t};var gn,hr,Er=new Set,Si=()=>{for(let e of Er)e()},gd=e=>(Er.add(e),()=>Er.delete(e));function Ti(e){let{currentNodeId:t,mode:n,rootNodeId:r,nodes:o,filters:i}=e;if(!t)return s("derive(): currentNodeId is missing");if(!r)return s("derive(): rootNode is missing");if(!o[r])return s("derive(): unable to find root node");let d=o[t];if(!d)return logger.error("Unable to derive state, currentNode not found"),s("Unable to derive state, currentNode not found");let l=bi(t,o,r);if(c(l))return logger.error(l.message),l;let m=l.data,{context:g}=d,y=vr[g+n]??vr[g]??[],N=[...vi,...xi[g]??[],...hi],b=Ii(N),I=fd(o,i),T=I[t]?.[e.selectedIndex]??null;return u("Derived successfully",{...e,currentNode:d,breadCrumb:m,availableHints:y,availableActions:N,actionIndex:b,selectedNode:T,renderedChildrenIndex:I})}var v=()=>(gn||logger.error("State not initialized. Call initWorkspaceState() first.",new Error().stack),gn);function Qn(e){hr=e;let t={readOnly:!1,filters:[],tags:{},contributors:{},viewMode:"dense",mode:f.DEFAULT,nodes:{[e.id]:e},rootNodeId:e.id,currentNodeId:e.id,renderedChildrenIndex:{},selectedIndex:-1,syncStatus:{status:"synced",msg:""},eventLog:[],unappliedEvents:[],timeMode:"live"},n=Ti(t);return c(n)?n:(gn=n.data,Si(),u("State initialized",null))}function de(e){let t=v(),n=e(t),r=Ti(n);return c(r)?s(r.message??"Unable to update state"):(gn=r.data,Si(),u("State updated",null))}var A=e=>de(t=>({...t,...e}));var _=()=>pd(gd,v,v),fd=(e,t)=>{let n={};for(let r of Object.values(e))ye(r)&&t.length>0&&!t.every(o=>Ni(r,o))||!r.parentNodeId||r.isDeleted||((!r.parentNodeId||!n[r.parentNodeId])&&(n[r.parentNodeId]=[]),n[r.parentNodeId].push(r));for(let r of Object.keys(n))n[r].sort((o,i)=>{let a=e[o.id],d=e[i.id];return!a||!d?0:a.rank.localeCompare(d.rank)});return n},M=e=>v()?.renderedChildrenIndex[e]??[],yr=()=>hr?Qn(hr):s("Cannot reset state: no initial workspace found");var U={exit(){process.exit(0)},enterChildNode(){let e=v(),t=e.currentNode,n=Math.max(0,e.selectedIndex),r=M(t.id)[n];!r||t.context==="FIELD"||U.navigate({currentNode:r,selectedIndex:M(r.id).length?0:-1})},enterParentNode(){let{currentNode:e,nodes:t}=v();if(!e.parentNodeId){logger.info("Missing parent node id");return}let n=t[e.parentNodeId];if(!n){logger.error("Parent not found");return}let r=M(n.id),o=r.findIndex(({id:a})=>a===e.id),i=r.length===0?-1:o>=0?o:0;U.navigate({currentNode:n,selectedIndex:i})},navigateToNextItem:()=>Ai(1),navigateToPreviousItem:()=>Ai(-1),navigateToNextContainer:()=>wi(1),navigateToPreviousContainer:()=>wi(-1),navigate:({currentNode:e=v().currentNode,selectedIndex:t})=>{A({currentNodeId:e.id,selectedIndex:t})}},Ai=e=>{let t=v(),n=M(t.currentNode.id).length;if(n===0)return;let o=(Math.max(0,t.selectedIndex)+e+n)%n;U.navigate({selectedIndex:o})},wi=e=>{let{currentNode:t,nodes:n,selectedIndex:r}=v();if(!t.childNavigationAcrossParents)return;if(!t.parentNodeId){logger.error("Missing parent node id");return}let o=n[t.parentNodeId];if(!t||!o)return;let i=M(o.id),a=i.findIndex(N=>N.id===t.id);if(a<0)return;let d=i.at(a+e)??i.at(0);if(!d)return;let l=M(d.id),m=Math.max(0,l.length-1),g=Math.min(Math.max(0,r),m),y=l.length?g:-1;U.navigate({currentNode:d,selectedIndex:y})};var Ae="system",we="ACTOR",St=yd(),Re=null;function xd(){let e=Object.values(v().nodes).find(r=>r.context==="WORKSPACE");if(!e)throw new Error("No workspace found in event log");let[t]=M(e.id),[n]=t?M(t.id):[];if(logger.debug("Boot navigation target:",{workspace:e?.id,firstBoard:t?.id,firstSwimlane:n?.id}),n){let r=v().renderedChildrenIndex?.[n.id]??[];return{currentNode:n,selectedIndex:r.length>0?0:-1}}else return t?{currentNode:t,selectedIndex:0}:e?{currentNode:e,selectedIndex:0}:{currentNode:v().nodes[v().rootNodeId],selectedIndex:0}}function vd(){let e=xd();U.navigate(e)}function hd(){let e=St(),t=St(),n=St(),r=St(),o=St();return[{id:Te(),userId:Ae,userName:we,action:"init.workspace",payload:{id:e,name:"Workspace"}},{id:Te(),userId:Ae,userName:we,action:"add.board",payload:{id:t,name:"Default",parent:e}},{id:Te(),userId:Ae,userName:we,action:"add.swimlane",payload:{id:n,name:"Todo",parent:t}},{id:Te(),userId:Ae,userName:we,action:"add.swimlane",payload:{id:r,name:"In progress",parent:t}},{id:Te(),userId:Ae,userName:we,action:"add.swimlane",payload:{id:o,name:"Done",parent:t}},{id:Te(),userId:Ae,userName:we,action:"add.board",payload:{id:en,name:"Closed",parent:e}},{id:Te(),userId:Ae,userName:we,action:"add.swimlane",payload:{id:tt,name:"Closed",parent:en}},{id:Te(),userId:Ae,userName:we,action:"lock.node",payload:{id:en}},{id:Te(),userId:Ae,userName:we,action:"lock.node",payload:{id:tt}}]}function Ke(){return Re!==null}function xr(){if(!Re||Re.length===0)return Re=null,u("No pending default events to persist",null);let e=Re.map(t=>Jt({event:t})).filter(c);return e.length>0?s([at.bold.red("Persisting default events failed"),"",...e.map((t,n)=>`${at.dim.gray(`${n+1}.`)} ${at.dim(t.message)}`),`
|
|
37
37
|
`].join(`
|
|
38
38
|
`)):(Re=null,u("Persisted pending default events",null))}function Ri(e){let t;e.some(r=>r.action==="init.workspace")?(Re=null,t=Ve(e)):(Re=hd(),t=Ve([...Re]));let n=t.filter(c);return n.length>0?s([at.bold.red("Materializing failed"),"",...n.map((r,o)=>`${at.dim.gray(`${o+1}.`)} ${at.dim(r.message)}`),`
|
package/dist/mcp.js
CHANGED
|
@@ -32,7 +32,7 @@ ${o.message}`);let s=await Qt({cwd:e,message:"[epiq:repair-storage-branch]"});re
|
|
|
32
32
|
${o.message}`);x.debug("[sync] set upstream to remote branch");let s=await T({args:["branch","--set-upstream-to",`${K}/${L}`,L],cwd:e});return a(s)?i(`Failed to set remote upstream
|
|
33
33
|
${s.message}`):c("Configured remote upstream",!0)},Tr=async({worktreeRoot:e,ownEventFileName:t})=>{x.debug("[sync] stage own event file in remote worktree",t);let n=await T({args:["add",zi(t)],cwd:e});return a(n)?i(`Failed to stage remote own event file
|
|
34
34
|
${n.message}`):c("Staged remote own event file",void 0)},Mr=async({repoRoot:e,worktreeRoot:t})=>{let n=await es(e);return a(n)?i(n.message):(x.debug("[sync] create remote sync commit"),Qt({cwd:t,message:n.data}))},on=async e=>{x.debug("[sync] push remote worktree");let t=await en(e);if(a(t))return i(t.message);let n=await T({args:t.data?["push"]:["push","-u",K,L],cwd:e});return x.debug("[sync] push result",n),a(n)?i(`Failed during remote push
|
|
35
|
-
${n.message}`):c("Pushed remote",!0)},Lr=async({repoRoot:e,worktreeRoot:t,ensureUpstream:n})=>{x.debug("[sync] bootstrap remote storage",{repoRoot:e,worktreeRoot:t,ensureUpstream:n});let r=!1,o=[Ji(),await ns({repoRoot:e}),await is({repoRoot:e,worktreeRoot:t}),await ss(t),await as(t),n?await ds(t):c("Skipped remote upstream bootstrap",!1)];for(let s of o){if(a(s))return i(s.message);r=r||!!s.data}return x.debug("[sync] bootstrap changed",r),c(n?"Bootstrapped remote storage":"Bootstrapped remote storage (readonly)",r)},Pr=(e,t)=>{for(let n of[Te(e),Te(t)]){let r=St(n);if(a(r))return i(r.message)}return c("Ensured remote layout",void 0)};var cs=({repoRoot:e,worktreeRoot:t,ownEventFileName:n})=>{let r=ze({root:e,fileName:n}),o=ze({root:t,fileName:n});return qe.existsSync(r)?(logger.debug("[sync] merge own event file to remote",{ownEventFileName:n,localFile:r,remoteFile:o}),Rt({sourceFile:r,targetFile:o})):(logger.debug("[sync] local own event file missing",r),c("Local own event file missing, nothing to merge",!1))},Dr=async({repoRoot:e,worktreeRoot:t,ownEventFileName:n})=>{let r=cs({repoRoot:e,worktreeRoot:t,ownEventFileName:n});if(a(r))return i(r.message);let o=await Nr(t);if(a(o))return i(o.message);if(!r.data&&!o.data)return c("Own event file already up to date in remote worktree",{createdCommit:!1});let s=await Tr({worktreeRoot:t,ownEventFileName:n});if(a(s))return i(s.message);let d=await Mr({repoRoot:e,worktreeRoot:t});return a(d)?i(d.message):c("Merged, staged, and committed own event file",{createdCommit:!0,commitSha:d.data})},Fr=({repoRoot:e,worktreeRoot:t,ownEventFileName:n})=>{let r=ze({root:e,fileName:n}),o=ze({root:t,fileName:n});logger.debug("[sync] own event file sizes",{local:qe.existsSync(r)?qe.statSync(r).size:0,remote:qe.existsSync(o)?qe.statSync(o).size:0})},At=async({cwd:e=process.cwd(),ownEventFileName:t})=>{logger.debug("[sync] start write sync",{cwd:e,ownEventFileName:t});let n=await gr(e);if(a(n))return i(n.message);let r=n.data,o=Sr(r);logger.debug("[sync] resolved roots",{repoRoot:r,worktreeRoot:o});let s=await
|
|
35
|
+
${n.message}`):c("Pushed remote",!0)},Lr=async({repoRoot:e,worktreeRoot:t,ensureUpstream:n})=>{x.debug("[sync] bootstrap remote storage",{repoRoot:e,worktreeRoot:t,ensureUpstream:n});let r=!1,o=[Ji(),await ns({repoRoot:e}),await is({repoRoot:e,worktreeRoot:t}),await ss(t),await as(t),n?await ds(t):c("Skipped remote upstream bootstrap",!1)];for(let s of o){if(a(s))return i(s.message);r=r||!!s.data}return x.debug("[sync] bootstrap changed",r),c(n?"Bootstrapped remote storage":"Bootstrapped remote storage (readonly)",r)},Pr=(e,t)=>{for(let n of[Te(e),Te(t)]){let r=St(n);if(a(r))return i(r.message)}return c("Ensured remote layout",void 0)};var cs=({repoRoot:e,worktreeRoot:t,ownEventFileName:n})=>{let r=ze({root:e,fileName:n}),o=ze({root:t,fileName:n});return qe.existsSync(r)?(logger.debug("[sync] merge own event file to remote",{ownEventFileName:n,localFile:r,remoteFile:o}),Rt({sourceFile:r,targetFile:o})):(logger.debug("[sync] local own event file missing",r),c("Local own event file missing, nothing to merge",!1))},Dr=async({repoRoot:e,worktreeRoot:t,ownEventFileName:n})=>{let r=cs({repoRoot:e,worktreeRoot:t,ownEventFileName:n});if(a(r))return i(r.message);let o=await Nr(t);if(a(o))return i(o.message);if(!r.data&&!o.data)return c("Own event file already up to date in remote worktree",{createdCommit:!1});let s=await Tr({worktreeRoot:t,ownEventFileName:n});if(a(s))return i(s.message);let d=await Mr({repoRoot:e,worktreeRoot:t});return a(d)?i(d.message):c("Merged, staged, and committed own event file",{createdCommit:!0,commitSha:d.data})},Fr=({repoRoot:e,worktreeRoot:t,ownEventFileName:n})=>{let r=ze({root:e,fileName:n}),o=ze({root:t,fileName:n});logger.debug("[sync] own event file sizes",{local:qe.existsSync(r)?qe.statSync(r).size:0,remote:qe.existsSync(o)?qe.statSync(o).size:0})},At=async({cwd:e=process.cwd(),ownEventFileName:t})=>{logger.debug("[sync] start write sync",{cwd:e,ownEventFileName:t});let n=await gr(e);if(a(n))return i(n.message);let r=n.data,o=Sr(r);logger.debug("[sync] resolved roots",{repoRoot:r,worktreeRoot:o});let s=await Ar(r);if(a(s))return i(`Failed to ensure initial commit: ${s.message}`);logger.debug("[sync] ensure initial commit changed",s.data);let d=await Ir(r);if(a(d))return i(d.message);if(d.data)return i("Cannot run :sync while the repository is in detached HEAD state");if(t.includes("/")||t.includes("\\"))return i("Own event file must be a file name, not a path");if(!t.endsWith(".jsonl"))return i("Own event file must end with .jsonl");let l=await Zt(r);if(a(l))return i(l.message);if(l.data)return i("Cannot run :sync while a merge, rebase, cherry-pick, or revert is in progress in the current repo");let u=await Lr({repoRoot:r,worktreeRoot:o,ensureUpstream:!0});if(a(u))return i(u.message);let v=await Zt(o);if(a(v))return i(v.message);if(v.data)return i("Cannot run :sync while a merge, rebase, cherry-pick, or revert is in progress in the remote worktree");let f=Pr(r,o);if(a(f))return i(f.message);let N=!1,C,S=!1,M=!1,j=!1;logger.debug("[sync] pull remote branch before local copy");let kt=await tn({cwd:o,remote:K,branch:L});if(a(kt))return i(kt.message);S=kt.data,logger.debug("[sync] pulled remote",S);let Ot=wr({repoRoot:r,worktreeRoot:o});if(a(Ot))return i(Ot.message);j=Ot.data,logger.debug("[sync] hydrated from remote",j);let De=await Dr({repoRoot:r,worktreeRoot:o,ownEventFileName:t});if(a(De))return i(De.message);if(N=De.data.createdCommit,C=De.data.commitSha,Fr({repoRoot:r,worktreeRoot:o,ownEventFileName:t}),logger.debug("[sync] sync own file result",De.data),N||u.data){let ve=await on(o),Ye=ve;if(a(ve)&&Er(ve.message)){let gn=await tn({cwd:o,remote:K,branch:L});if(a(gn))return i(gn.message);let Fe=await Dr({repoRoot:r,worktreeRoot:o,ownEventFileName:t});if(a(Fe))return i(Fe.message);Fe.data.createdCommit&&(N=!0,C=Fe.data.commitSha),Fr({repoRoot:r,worktreeRoot:o,ownEventFileName:t}),logger.debug("[sync] retry sync own file result",Fe.data),Ye=await on(o)}if(a(Ye))return i(Ye.message);M=Ye.data,logger.debug("[sync] pushed remote",M)}else logger.debug("[sync] no commit created, skipped push");if(N){let ve=await T({args:["rev-parse","HEAD"],cwd:o});if(a(ve))return i(ve.message);C=ve.data.stdout.trim()}return c("Synced event logs with remote",{repoRoot:r,worktreeRoot:o,createdCommit:N,commitSha:C,pulled:S,pushed:M,hydrated:j,bootstrapped:u.data})};import{ulid as kr}from"ulid";var Me=null,ge=()=>structuredClone(Me),Le=e=>Me=e,Or=()=>{let{currentNode:e,selectedIndex:t}=y(),r=R(e.id)[t];return r?c("Resolved selected child",r):i("Target node not found")};function sn(e){let t=Or();if(a(t))return t;let{currentNode:n,nodes:r}=y();if(!n.parentNodeId)return i("Missing parent node id");let o=r[n.parentNodeId];if(!o)return i("Missing parent node");let s=H(o.id),d=s.findIndex(({id:C})=>C===n.id);if(d<0)return i("Current node not found among siblings");let l=s[d+e];if(!l)return i("Missing sibling node");let u=W();if(a(u))return i("Unable to resolve user ID");let{userId:v,userName:f}=u.data;if(Le({id:kr(),userId:v,userName:f,action:"move.node",payload:{id:t.data.id,parent:l.id,pos:{at:"end"}}}),!Me)return i("Could not materialize move state");let N=Se(Me,!0);return a(N)?N:c("Node moved successfully",N.data)}function an(e){let t=Or();if(a(t))return t;let{currentNode:n,selectedIndex:r}=y(),s=H(n.id)[r+e];if(!s)return i("Missing sibling node");let d=W();if(a(d))return i("Unable to resolve user ID");let{userId:l,userName:u}=d.data;if(Le({id:kr(),userId:l,userName:u,action:"move.node",payload:{id:t.data.id,parent:n.id,pos:{at:e===1?"after":"before",sibling:s.id}}}),!Me)return i("Could not materialize move state");let v=Se(Me,!0);return a(v)?v:c("Node moved successfully",v.data)}import ls from"node:os";import Ur from"node:path";import{z as Ge}from"zod";var us={userId:"",userName:"",preferredEditor:"",autoSync:!1},_r=Ge.object({preferredEditor:Ge.string().optional(),userName:Ge.string().optional(),userId:Ge.string().optional(),autoSync:Ge.boolean().optional()}).strict(),ms=".epiq",ps="config.json",Br=()=>Ur.join(ls.homedir(),ms),dn=()=>Ur.join(Br(),ps),cn=()=>{try{return Y.mkDir(Br()),c("Ensured ~/.epiq exists",null)}catch{return i("Unable to create ~/.epiq")}},gs=e=>{let t;try{t=JSON.parse(e)}catch{return i("Invalid ~/.epiq/config.json JSON")}let n=_r.safeParse(t??{});return n.success?c("Parsed config",n.data):i(`Invalid ~/.epiq/config.json shape: ${n.error.issues.map(r=>r.path.join(".")||r.message).join(", ")}`)},Wr=()=>{let e=cn();if(a(e))return i(e.message);let t=dn(),n=Y.readFile(t);return n==null||n.trim()===""?c("No config found, using empty config",{autoSync:!1,preferredEditor:"",userId:"",userName:""}):gs(n)},$r=e=>{let t=cn();if(a(t))return i(t.message);let n=_r.safeParse(e);if(!n.success)return i(`Invalid config: ${n.error.issues.map(o=>o.path.join(".")||o.message).join(", ")}`);let r=dn();try{return Y.writeToFile(r,JSON.stringify(n.data,null,2)+`
|
|
36
36
|
`),c("Config written",null)}catch{return i("Unable to write ~/.epiq/config.json")}},wt=e=>{let t=Wr();if(a(t))return i("Failed to read existing config");let n={...t.data,...e};return $r(n)},Hr=()=>{let e=dn(),t=cn();if(a(t))return i("Unable to create ~/.epiq");if(!(Y.readFile(e)!==null)){let u=$r(us);if(a(u))throw new Error("Unable to create ~/.epiq/config.json")}let r=Wr();if(a(r))throw new Error(r.message||"Unable to load settings");let{preferredEditor:o,userName:s,userId:d,autoSync:l}=r.data;return!s||!d?i("User name or ID not configured in ~/.epiq/config.json"):c("successfully loaded settings",{preferredEditor:o??"",userName:s,userId:d,autoSync:l??!1})};var Kr=e=>Object.values(y().tags).find(t=>t.name===e),Vr=e=>Object.values(y().contributors).find(t=>t.name===e),jr=[{systemOnly:!0,intent:b.Move,mode:p.COMMAND_LINE,action:()=>{let e=W();if(a(e))return i("Unable to resolve user ID");let{modifier:t}=J().commandMeta,n=()=>{let l=ge();if(!l)return i("No pending move state");let u=l.payload.id;if(!y().nodes[u])return i("Moved node not found");let f=l.payload.parent,N=y().nodes[f];if(!N)return i("Move parent not found");let C=R(f).findIndex(S=>S.id===u);return C===-1?i("Moved node not found among rendered children"):(U.navigate({currentNode:N,selectedIndex:C}),c("Synchronized navigation to moved node",null))},r=l=>{if(a(l))return i(l.message);let u=n();return a(u)?i(u.message):c("Updated move preview",null)},{currentNode:o,selectedIndex:s}=y(),d=R(o.id)[s];if(!d)return I({mode:p.DEFAULT}),i("No move target");if(t==="start"){if(d.readonly)return i("Target node is read-only");if(s===-1)return i("No item selected");if(!d.parentNodeId)return i("Target has no parent");let l=R(d.parentNodeId),u=l.findIndex(({id:S})=>S===d.id);if(u===-1)return i("Target not found among siblings");let v=l[u-1],f=l[u+1],N=f!=null?{at:"before",sibling:f.id}:v!=null?{at:"after",sibling:v.id}:{at:"start"};Le({id:F(),action:"move.node",payload:{id:d.id,parent:d.parentNodeId,pos:N},...e.data}),I({mode:p.MOVE});let C=n();return a(C)?i(C.message):c("Move initialized",null)}if(t==="next")return I({mode:p.MOVE}),r(an(1));if(t==="previous")return I({mode:p.MOVE}),r(an(-1));if(t==="to-next")return I({mode:p.MOVE}),r(sn(1));if(t==="to-previous")return I({mode:p.MOVE}),r(sn(-1));if(t==="confirm"){I({mode:p.DEFAULT});let l=ge();if(!l)return i("No pending move to confirm");let u=$(l);if(a(u))return u;let v=n();return a(v)?i(v.message):(Le(null),c("Moved item",null))}return t==="cancel"?(Le(null),I({mode:p.DEFAULT}),c("Cancelling move",null)):i("Invalid move modifier")}},{intent:b.Delete,mode:p.COMMAND_LINE,action:()=>{let e=W();if(a(e))return i("Unable to resolve user ID");let{currentNode:t,selectedIndex:n}=y(),r=R(t.id)[n];return r?$({id:F(),action:"delete.node",payload:{id:r.id},...e.data}):i("Unable to resolve child to delete")},onSuccess:()=>I({mode:p.DEFAULT})},{intent:b.Edit,mode:p.COMMAND_LINE,action:()=>{let e=W();if(a(e))return i("Unable to resolve user ID");let t=ye(y().breadCrumb,"TICKET");if(a(t))return i("Edit target must be an issue");let n=t.data;if(n.readonly)return i("Cannot edit readonly field");let{currentNode:r,selectedIndex:o}=y();if(!R(n.id)[o])return i("No selected field");let d=R(r.id)[o];if(!d)return i("No selected field");if(d.readonly)return i("Cannot edit readonly field");let l=d.props.value;if(typeof l!="string")return i("Selected field is not editable text");let u=Zn(l);if(a(u))return i("Failed to edit field");let v=u.data;return v===l?c("No changes made",null):d.title==="Description"?$({id:F(),action:"edit.description",payload:{id:d.id,md:v},...e.data}):d.title==="Title"?$({id:F(),action:"edit.title",payload:{id:d.id,name:v},...e.data}):i(`Editing not supported for "${d.title}"`)},onSuccess:()=>I({mode:p.DEFAULT})},{intent:b.Filter,mode:p.COMMAND_LINE,action:()=>{let{modifier:e,inputString:t}=J().commandMeta,n=/(!=|=)/,[r,o]=e.split(n);if(!r||!(l=>_(m.FILTER).map(u=>u.split(n)[0]).includes(l))(r))return i("Invalid filter modifier");let d={target:r,operator:"=",value:t.trim()};return q(l=>({...l,filters:e==="clear"?[]:[...l.filters,d],mode:p.DEFAULT})),c("Viewing help",null)}},{intent:b.ViewHelp,mode:p.COMMAND_LINE,action:()=>(I({mode:p.HELP}),c("Viewing help",null))},{intent:b.CloseIssue,mode:p.COMMAND_LINE,action:()=>{let e=W();if(a(e))return i("Unable to resolve user ID");let{currentNode:t,selectedIndex:n}=y(),r=R(t.id)[n];if(!r)return i("Unable to close issue, no target found");if(!r.parentNodeId)return i("No target parent found");if(!z(r))return i("Cannot close in this context");let o=$({id:F(),action:"close.issue",payload:{id:r.id,parent:r.parentNodeId},...e.data});return a(o)?o:c("Viewing help",null)}},{intent:b.ReopenIssue,mode:p.COMMAND_LINE,action:()=>{let e=W();if(a(e))return i("Unable to resolve user ID");let{currentNode:t,selectedIndex:n}=y(),r=R(t.id)[n];if(!r)return i("Unable to reopen issue, no target found");let o=r.context==="TICKET"?c("Resolved ticket",r):be(r.id,"TICKET");if(a(o))return i("Cannot reopen in this context");let s=o.data,d=$({id:F(),action:"reopen.issue",payload:{id:s.id},...e.data});return a(d)?d:c("Issue reopened",null)},onSuccess:()=>I({mode:p.DEFAULT})},{intent:b.SetUserName,mode:p.COMMAND_LINE,action:()=>{let{userId:e,preferredEditor:t,userName:n}=oe(),r=ut()?.trim();if(!r)return i("No username provided");let o=r??n,s=e??F();if(!o||!s)return i("Unable to resolve user name or id");let d=wt({userName:o,userId:s,preferredEditor:t??""});return a(d)?d:(it({userName:o,userId:s}),I({mode:p.DEFAULT}),c(`Username set to "${r}"`,null))}},{intent:b.Init,mode:p.COMMAND_LINE,action:()=>{let e=un();if(a(e))return e;let{rootNodeId:t,nodes:n}=y();return U.navigate({currentNode:n[t],selectedIndex:0}),I({mode:p.DEFAULT}),c("Project initialized",null)}},{intent:b.SetEditor,mode:p.COMMAND_LINE,action:()=>{let e=ut()?.trim();if(!e)return i("No editor provided");let t=wt({preferredEditor:e});return a(t)?t:(it({preferredEditor:e}),I({mode:p.DEFAULT}),c(`Editor configuration set to "${e}"`,null))}},{intent:b.SetAutoSync,mode:p.COMMAND_LINE,action:()=>{let e=J().commandMeta.modifier;if(e!=="true"&&e!=="false")return i("Invalid response");let t=e.toLowerCase()==="true",n=wt({autoSync:t});return a(n)?n:(it({autoSync:t}),I({mode:p.DEFAULT}),c(`Auto synchronization set to "${t}"`,null))}},{intent:b.NewItem,mode:p.COMMAND_LINE,action:(e,t)=>{let n=W();if(a(n))return i("Unable to resolve user ID");if(!t.inputString)return i(`provide a name for your ${t.modifier}`);let{breadCrumb:r,currentNode:o,selectedIndex:s}=y(),d=l=>{let u=$(l);if(a(u))return u;let v=E.getNode(u.data.result.id);if(!v)return i("Created node not found");if(!v.parentNodeId)return u;let f=E.getNode(v.parentNodeId);return f?(U.navigate({currentNode:f,selectedIndex:E.getSiblings(v.parentNodeId).findIndex(({id:N})=>N===v.id)}),u):i("Parent node not found")};if(t.modifier==="board"){let{rootNodeId:l}=y(),u=E.getNode(l);return u?d({id:F(),action:"add.board",payload:{id:F(),name:t.inputString,parent:u.id},...n.data}):i("Workspace not found")}if(t.modifier==="swimlane"){let l=ye(r,"BOARD");return a(l)?i("Unable to add swimlane in this context"):d({id:F(),action:"add.swimlane",payload:{id:F(),name:t.inputString,parent:l.data.id},...n.data})}if(t.modifier==="issue"){let l=R(o.id)[s],u=o.context==="SWIMLANE"?o:o.context==="BOARD"&&l?.context==="SWIMLANE"?l:(()=>{let S=ye(r,"SWIMLANE");return a(S)?null:S.data})();if(!u)return i("Unable to add issue in this context");let v=Ze({name:t.inputString,parent:u.id,user:n.data}),f=Ae(v);if(f.some(S=>a(S)))return i("Issue create failed: "+f.filter(a).map(S=>S.message).filter(Boolean).join(", "));let N=f[0];if(!N||a(N))return i("Issue creation failed");let C=v[0]?.payload.id;return C?(U.navigate({currentNode:u,selectedIndex:E.getSiblings(u.id).findIndex(({id:S})=>S===C)}),c("Issue created",null)):i("Unable to determine ticket id")}return fn()},onSuccess:()=>I({mode:p.DEFAULT})},{intent:b.SetView,mode:p.COMMAND_LINE,action:()=>{let{commandMeta:e}=J();return e.validity===re.Invalid?i("Invalid command "+ee):(q(t=>({...t,viewMode:e.modifier==="wide"?"wide":e.modifier==="dense"?"dense":t.viewMode})),c("View set",null))},onSuccess:()=>I({mode:p.DEFAULT})},{intent:b.Rename,mode:p.COMMAND_LINE,action:()=>{let e=W();if(a(e))return i("Unable to resolve user ID");let{currentNode:t,selectedIndex:n}=y(),r=R(t.id)[n];if(!r)return i("Missing node");if(r.readonly)return i("Cannot rename readonly node");let o=ut();return o?$({id:F(),action:"edit.title",payload:{id:r.id,name:o},...e.data}):i("Provide a new name")},onSuccess:()=>I({mode:p.DEFAULT})},{intent:b.UntagTicket,mode:p.COMMAND_LINE,action:()=>{let e=W();if(a(e))return i("Unable to resolve user ID");let{modifier:t,inputString:n}=J().commandMeta,r=(t||n).trim();if(!r)return i("Provide a tag");let o=Kr(r);if(!o)return i(`Tag "${r}" does not exist`);let{selectedNode:s}=y();if(!s)return i("Invalid untag target");let d=be(s.id,"TICKET");if(a(d))return i("Unable to untag issue in this context");let l=d.data,u=E.getFieldByTitle(l.id,"Tags");if(!u)return i("Unable to locate tags field");let v=R(u.id).find(f=>f.props?.value===o.id);return v?$({id:F(),action:"untag.issue",payload:{id:v.id,target:l.id,tagId:o.id},...e.data}):i("Issue is not tagged with that tag")},onSuccess:()=>I({mode:p.DEFAULT})},{intent:b.TagTicket,mode:p.COMMAND_LINE,action:()=>{let e=W();if(a(e))return i("Unable to resolve user ID");let{modifier:t,inputString:n}=J().commandMeta,r=(t||n).trim();if(!r)return i("Provide a tag");let{selectedIndex:o,currentNode:s}=y(),d=R(s.id)[o];if(!d)return i("Invalid tag target");let l=be(d.id,"TICKET");if(a(l))return i("Unable to tag issue in this context");let u=l.data,v=Kr(r),f;if(v)f=v.id;else{let S=F(),M=$({id:F(),action:"create.tag",payload:{id:S,name:r},userId:e.data.userId,userName:e.data.userName});if(a(M))return M;f=M.data.result.id}let N=E.getFieldByTitle(u.id,"Tags");return N?R(N.id).some(S=>S.props?.value===f)?i("Already tagged with that tag"):$({id:F(),action:"tag.issue",payload:{id:F(),target:u.id,tagId:f},...e.data}):i("Unable to locate tags field")},onSuccess:()=>I({mode:p.DEFAULT})},{intent:b.AssignUserToTicket,mode:p.COMMAND_LINE,action:()=>{let e=W();if(a(e))return i("Unable to resolve user ID");let{modifier:t,inputString:n}=J().commandMeta,r=(t||n).trim();if(!r)return i("Provide an assignee");let{selectedIndex:o,currentNode:s}=y(),d=R(s.id)[o];if(!d)return i("Invalid assign target");let l=be(d.id,"TICKET");if(a(l))return i("Unable to assign issue in this context");let u=l.data,v=Vr(r),f;if(v)f=v.id;else{let S=F(),M=$({id:F(),action:"create.contributor",payload:{id:S,name:r},userId:e.data.userId,userName:e.data.userName});if(a(M))return M;f=M.data.result.id}let N=E.getFieldByTitle(u.id,"Assignees");return N?R(N.id).some(S=>S.props?.value===f)?i("Assignee already assigned"):$({id:F(),action:"assign.issue",payload:{id:F(),target:u.id,contributor:f},...e.data}):i("Unable to locate assignees field")},onSuccess:()=>I({mode:p.DEFAULT})},{intent:b.UnassignUserFromTicket,mode:p.COMMAND_LINE,action:()=>{let e=W();if(a(e))return i("Unable to resolve user ID");let{modifier:t,inputString:n}=J().commandMeta,r=(t||n).trim();if(!r)return i("Provide an assignee to remove");let o=Vr(r);if(!o)return i(`Assignee "${r}" does not exist`);let{selectedNode:s}=y();if(!s)return i("Invalid unassign target");let d=be(s.id,"TICKET");if(a(d))return i("Unable to unassign in this context");let l=d.data,u=E.getFieldByTitle(l.id,"Assignees");if(!u)return i("Unable to locate assignees field");let v=R(u.id).find(f=>f.props?.value===o.id);return v?$({id:F(),action:"unassign.issue",payload:{id:v.id,target:l.id,contributor:o.id},...e.data}):i(`Issue is not assigned to "${r}"`)},onSuccess:()=>I({mode:p.DEFAULT})},{intent:b.Sync,mode:p.COMMAND_LINE,action:async()=>{O(()=>""),I({syncStatus:{msg:"Syncing",status:"syncing"}});let{userId:e,userName:t}=oe();if(!e)return i("Unable to resolve userId");if(!t)return i("Unable to resolve userName");let n=Oe()?un():c("No pending default events",null);if(a(n))return i(`Unable to persist default events. ${n.message}`);let r=W();if(a(r)||!r.data)return i("Unable to resolve event log path");let o=He(r.data);logger.debug("[sync-command] pending defaults",Oe());let s=await At({ownEventFileName:o});if(a(s))return I({syncStatus:{msg:s.message,status:"outOfSync"}}),i(`Unable to sync state. ${s.message}`);I({syncStatus:{msg:"Synced",status:"synced"},mode:p.DEFAULT});let d=Ke();return a(d)?i("Unable to load events"):(Ee(d.data),c("Synced",!0))}},{intent:b.Peek,mode:p.COMMAND_LINE,action:async()=>{let e=ye(y().breadCrumb,"BOARD");if(a(e))return e;let t=Ke();if(a(t))return i(t.message);let n=t.data,{modifier:r}=J().commandMeta,o;if(r==="now"){let N=ln();if(a(N))return N;let C=Ee(n);return C.some(a)?i(C.map(S=>S.message).join(", ")):(I({mode:p.DEFAULT,readOnly:!1,timeMode:"live",unappliedEvents:[]}),c("Peeking now",!0))}if(r==="prev"){let N=y().eventLog.at(-2),C=Bt(N);if(C===null)return i("No previous event to peek");o=C}else if(r==="next"){let N=y().unappliedEvents.at(0),C=Bt(N);if(C===null)return i("No next event to peek");o=C}else{let N=ct(r);if(!N)return i("Invalid peek date");o=N.getTime()}let s=e.data.id,{appliedEvents:d,unappliedEvents:l}=sr(n,o),u=ln();if(a(u))return u;let v=Ee(d);if(v.some(a))return i(v.map(N=>N.message).join(", "));let f=y().nodes[s];return f?(U.navigate({currentNode:f,selectedIndex:0}),I({mode:p.DEFAULT,readOnly:!0,timeMode:"peek",unappliedEvents:l}),c("Peeking ",!0)):i("Board did not exist at peek date")}}];var fs=new Set(["peek","filter","view-help"]),X=async({isForceExecutedBySystem:e=!1}={})=>{let{commandMeta:{command:t,validity:n,modifier:r,inputString:o}}=J();if(!t)return i("No command to confirm");if(!e&&n===re.Invalid)return i("Invalid command");let s=Gn(t);if(Vn(),y().readOnly&&!fs.has(s))return We({result:ee.Fail,message:"Command not available in readonly state",data:null});let d=jr.filter(u=>e||u.systemOnly!==!0).find(u=>u.intent===s);if(!d)return We({result:ee.Fail,message:"Command not found",data:null});let l=await d.action(d,{command:t,inputString:o,modifier:r});return a(l)?We(l):(jn({addToHistory:!e}),d.onSuccess?.(),We(l))};var Tt=[{intent:h.Exit,mode:p.MOVE,description:"[<Esc>] exit context / cancel",action:()=>(I({mode:p.COMMAND_LINE}),O(()=>"move cancel"),X({isForceExecutedBySystem:!0}))},{intent:h.InitMove,mode:p.DEFAULT,description:"[m] move init/confirm",action:()=>(I({mode:p.COMMAND_LINE}),O(()=>"move start"),X({isForceExecutedBySystem:!0}))},{intent:h.ConfirmMove,mode:p.MOVE,action:()=>(I({mode:p.COMMAND_LINE}),O(()=>"move confirm"),X({isForceExecutedBySystem:!0}))}],Mt=[{intent:h.MovePreviousItem,mode:p.MOVE,action:()=>ge()?(I({mode:p.COMMAND_LINE}),O(()=>"move previous"),X({isForceExecutedBySystem:!0})):i("No pending move")},{intent:h.MoveNextItem,mode:p.MOVE,action:()=>ge()?(I({mode:p.COMMAND_LINE}),O(()=>"move next"),X({isForceExecutedBySystem:!0})):i("No pending move")}],zr=[{intent:h.MoveToNextContainer,mode:p.MOVE,action:()=>ge()?(I({mode:p.COMMAND_LINE}),O(()=>"move to-next"),X({isForceExecutedBySystem:!0})):i("No pending move")},{intent:h.MoveToPreviousContainer,mode:p.MOVE,action:()=>ge()?(I({mode:p.COMMAND_LINE}),O(()=>"move to-previous"),X({isForceExecutedBySystem:!0})):i("No pending move")}];var qr={[P.WORKSPACE]:[...Tt,...Mt],[P.BOARD]:[...Tt,...Mt],[P.SWIMLANE]:[...Tt,...Mt,...zr],[P.TICKET]:[],[P.FIELD]:[],[P.FIELD_LIST]:[],[P.TEXT]:[]};var Gr=[{intent:h.AddItem,mode:p.DEFAULT,description:"[n] new...",action:()=>(I({mode:p.COMMAND_LINE}),O(()=>`${m.NEW} `),c("Adding new item",null))},{intent:h.Delete,mode:p.DEFAULT,description:"[d] delete",action:()=>(I({mode:p.COMMAND_LINE}),O(()=>`${m.DELETE} `),c("Deleting item",null))},{intent:h.InitCommandLine,mode:p.DEFAULT,description:"[:] focus command line",action:()=>(I({mode:p.COMMAND_LINE}),O(()=>""),c("Entering command line mode",null))},{intent:h.Confirm,mode:p.DEFAULT,description:"[<Enter>] confirm/enter",action:()=>(U.enterChildNode(),c("Entering context",null))},{intent:h.Exit,mode:p.DEFAULT,description:"[q] exit context",action:()=>(U.enterParentNode(),c("Exiting context",null))},{intent:h.NavPreviousItem,mode:p.DEFAULT,description:"[arrows/hjkl] navigate",action:()=>(U.navigateToPreviousItem(),c("Navigating to previous item",null))},{intent:h.NavNextItem,mode:p.DEFAULT,action:()=>(U.navigateToNextItem(),c("Navigating to next item",null))},{intent:h.NavToPreviousContainer,mode:p.DEFAULT,action:()=>(U.navigateToPreviousContainer(),c("Navigating to previous container",null))},{intent:h.NavToNextContainer,mode:p.DEFAULT,action:()=>(U.navigateToNextContainer(),c("Navigating to next container",null))},{intent:h.Edit,mode:p.DEFAULT,action:()=>(I({mode:p.COMMAND_LINE}),O(()=>"edit"),X(),c("Fired command",!0))},{intent:h.SetViewDense,mode:p.DEFAULT,description:"[v] view change (wide/dense)",action:()=>(I({viewMode:"dense"}),c("View set",null))},{intent:h.SetViewWide,mode:p.DEFAULT,action:()=>(I({viewMode:"wide"}),c("View set",null))}];var Jr=[{intent:h.ViewHelp,mode:p.DEFAULT,action:()=>(I({mode:p.HELP}),c("Viewing help",null))},{intent:h.Exit,mode:p.HELP,action:()=>(I({mode:p.DEFAULT}),c("Exiting help",null))},{intent:h.Confirm,mode:p.COMMAND_LINE,action:()=>(X(),c("Executing command",null))},{intent:h.MoveCursorLeft,mode:p.COMMAND_LINE,action:()=>(jt(-1),c("Moving cursor left",null))},{intent:h.MoveCursorRight,mode:p.COMMAND_LINE,action:()=>(jt(1),c("Moving cursor right",null))},{intent:h.MoveCursorLeftOfWord,mode:p.COMMAND_LINE,action:()=>(zt("left"),c("Moving cursor left of word",null))},{intent:h.MoveCursorRightOfWord,mode:p.COMMAND_LINE,action:()=>(zt("right"),c("Moving cursor right of word",null))},{intent:h.ExitCommandLine,mode:p.COMMAND_LINE,action:()=>(I({mode:p.DEFAULT}),c("Exiting command line",null))},{intent:h.AutoCompleteCommand,mode:p.COMMAND_LINE,action:()=>(O((e,{remainder:t})=>t?e+t:e),c("Auto-completing command",null))},{intent:h.CaptureInput,mode:p.COMMAND_LINE,action:(e,{sequence:t})=>(O(n=>n+t),c("Capturing input",null))},{intent:h.EraseInput,mode:p.COMMAND_LINE,action:()=>(Hn(),c("Erasing input",null))},{intent:h.EraseInputWord,mode:p.COMMAND_LINE,action:()=>(Kn(),c("Erasing input word",null))},{intent:h.GetLastCommandFromHistory,mode:p.COMMAND_LINE,action:()=>(zn(),c("Getting last command from history",null))},{intent:h.GetNextCommandFromHistory,mode:p.COMMAND_LINE,action:()=>(qn(),c("Getting next command from history",null))}];import vs from"chalk";var Lt=": for command line",Yr="q to exit",Xr=`${vs.hex(Sn.accent)("m")} to confirm`,mn={[P.WORKSPACE]:[Lt],[P.BOARD]:[Lt],[P.BOARD+p.COMMAND_LINE]:[Lt],[P.SWIMLANE]:[Lt],[P.TICKET+p.HELP]:[Yr],[P.SWIMLANE+p.HELP]:[Yr],[P.TICKET]:[],[P.FIELD]:[],[P.SWIMLANE+p.MOVE]:[Xr],[P.TICKET+p.MOVE]:[Xr]};var Pt=e=>e.trim().toLocaleLowerCase(),ys=(e,t)=>{let n=E.getFieldByTitle(e,t);if(!n)return"";let r=n.props?.value;return typeof r=="string"?r:""},Es=e=>{let{tags:t}=y(),n=E.getFieldByTitle(e,"Tags");return n?H(n.id).map(r=>{let o=r.props?.value;return typeof o=="string"?t[o]?.name:void 0}).filter(r=>!!r):[]},Ns=e=>{let{contributors:t}=y(),n=E.getFieldByTitle(e,"Assignees");return n?H(n.id).map(r=>{let o=r.props?.value;return typeof o=="string"?t[o]?.name:void 0}).filter(r=>!!r):[]},Qr=(e,t)=>{let n=t.value;if(!n)return!0;switch(t.target){case"title":return Pt(e.title??"").includes(n);case"description":return Pt(ys(e.id,"Description")).includes(n);case"tag":return Es(e.id).map(Pt).some(l=>l.includes(n));case"assignee":return Ns(e.id).map(Pt).some(l=>l.includes(n));default:return!0}};function Zr(e,t,n){let r=t[e];if(!r)return i("buildBreadCrumb(): current node not found");let o=[],s=r;for(;s&&(o.push(s),!(s.id===n||!s.parentNodeId));)s=t[s.parentNodeId];let d=o[o.length-1];return!d||d.id!==n?i("buildBreadCrumb(): node is not connected to root"):(o.reverse(),c("Breadcrumb built",o))}var eo=e=>{let t={};for(let n of e)n.intent&&(t[n.mode]||(t[n.mode]={}),t[n.mode][n.intent]=n);return t};var Dt,pn,Is=new Set,to=()=>{for(let e of Is)e()};function no(e){let{currentNodeId:t,mode:n,rootNodeId:r,nodes:o,filters:s}=e;if(!t)return i("derive(): currentNodeId is missing");if(!r)return i("derive(): rootNode is missing");if(!o[r])return i("derive(): unable to find root node");let l=o[t];if(!l)return logger.error("Unable to derive state, currentNode not found"),i("Unable to derive state, currentNode not found");let u=Zr(t,o,r);if(a(u))return logger.error(u.message),u;let v=u.data,{context:f}=l,N=mn[f+n]??mn[f]??[],C=[...Gr,...qr[f]??[],...Jr],S=eo(C),M=xs(o,s),j=M[t]?.[e.selectedIndex]??null;return c("Derived successfully",{...e,currentNode:l,breadCrumb:v,availableHints:N,availableActions:C,actionIndex:S,selectedNode:j,renderedChildrenIndex:M})}var y=()=>(Dt||logger.error("State not initialized. Call initWorkspaceState() first.",new Error().stack),Dt);function Jt(e){pn=e;let t={readOnly:!1,filters:[],tags:{},contributors:{},viewMode:"dense",mode:p.DEFAULT,nodes:{[e.id]:e},rootNodeId:e.id,currentNodeId:e.id,renderedChildrenIndex:{},selectedIndex:-1,syncStatus:{status:"synced",msg:""},eventLog:[],unappliedEvents:[],timeMode:"live"},n=no(t);return a(n)?n:(Dt=n.data,to(),c("State initialized",null))}function q(e){let t=y(),n=e(t),r=no(n);return a(r)?i(r.message??"Unable to update state"):(Dt=r.data,to(),c("State updated",null))}var I=e=>q(t=>({...t,...e}));var xs=(e,t)=>{let n={};for(let r of Object.values(e))z(r)&&t.length>0&&!t.every(o=>Qr(r,o))||!r.parentNodeId||r.isDeleted||((!r.parentNodeId||!n[r.parentNodeId])&&(n[r.parentNodeId]=[]),n[r.parentNodeId].push(r));for(let r of Object.keys(n))n[r].sort((o,s)=>{let d=e[o.id],l=e[s.id];return!d||!l?0:d.rank.localeCompare(l.rank)});return n},R=e=>y()?.renderedChildrenIndex[e]??[],ln=()=>pn?Jt(pn):i("Cannot reset state: no initial workspace found");var U={exit(){process.exit(0)},enterChildNode(){let e=y(),t=e.currentNode,n=Math.max(0,e.selectedIndex),r=R(t.id)[n];!r||t.context==="FIELD"||U.navigate({currentNode:r,selectedIndex:R(r.id).length?0:-1})},enterParentNode(){let{currentNode:e,nodes:t}=y();if(!e.parentNodeId){logger.info("Missing parent node id");return}let n=t[e.parentNodeId];if(!n){logger.error("Parent not found");return}let r=R(n.id),o=r.findIndex(({id:d})=>d===e.id),s=r.length===0?-1:o>=0?o:0;U.navigate({currentNode:n,selectedIndex:s})},navigateToNextItem:()=>ro(1),navigateToPreviousItem:()=>ro(-1),navigateToNextContainer:()=>oo(1),navigateToPreviousContainer:()=>oo(-1),navigate:({currentNode:e=y().currentNode,selectedIndex:t})=>{I({currentNodeId:e.id,selectedIndex:t})}},ro=e=>{let t=y(),n=R(t.currentNode.id).length;if(n===0)return;let o=(Math.max(0,t.selectedIndex)+e+n)%n;U.navigate({selectedIndex:o})},oo=e=>{let{currentNode:t,nodes:n,selectedIndex:r}=y();if(!t.childNavigationAcrossParents)return;if(!t.parentNodeId){logger.error("Missing parent node id");return}let o=n[t.parentNodeId];if(!t||!o)return;let s=R(o.id),d=s.findIndex(C=>C.id===t.id);if(d<0)return;let l=s.at(d+e)??s.at(0);if(!l)return;let u=R(l.id),v=Math.max(0,u.length-1),f=Math.min(Math.max(0,r),v),N=u.length?f:-1;U.navigate({currentNode:l,selectedIndex:N})};var ce="system",le="ACTOR",Je=bs(),ue=null;function Cs(){let e=Object.values(y().nodes).find(r=>r.context==="WORKSPACE");if(!e)throw new Error("No workspace found in event log");let[t]=R(e.id),[n]=t?R(t.id):[];if(logger.debug("Boot navigation target:",{workspace:e?.id,firstBoard:t?.id,firstSwimlane:n?.id}),n){let r=y().renderedChildrenIndex?.[n.id]??[];return{currentNode:n,selectedIndex:r.length>0?0:-1}}else return t?{currentNode:t,selectedIndex:0}:e?{currentNode:e,selectedIndex:0}:{currentNode:y().nodes[y().rootNodeId],selectedIndex:0}}function hs(){let e=Cs();U.navigate(e)}function Rs(){let e=Je(),t=Je(),n=Je(),r=Je(),o=Je();return[{id:de(),userId:ce,userName:le,action:"init.workspace",payload:{id:e,name:"Workspace"}},{id:de(),userId:ce,userName:le,action:"add.board",payload:{id:t,name:"Default",parent:e}},{id:de(),userId:ce,userName:le,action:"add.swimlane",payload:{id:n,name:"Todo",parent:t}},{id:de(),userId:ce,userName:le,action:"add.swimlane",payload:{id:r,name:"In progress",parent:t}},{id:de(),userId:ce,userName:le,action:"add.swimlane",payload:{id:o,name:"Done",parent:t}},{id:de(),userId:ce,userName:le,action:"add.board",payload:{id:It,name:"Closed",parent:e}},{id:de(),userId:ce,userName:le,action:"add.swimlane",payload:{id:Z,name:"Closed",parent:It}},{id:de(),userId:ce,userName:le,action:"lock.node",payload:{id:It}},{id:de(),userId:ce,userName:le,action:"lock.node",payload:{id:Z}}]}function Oe(){return ue!==null}function un(){if(!ue||ue.length===0)return ue=null,c("No pending default events to persist",null);let e=ue.map(t=>vt({event:t})).filter(a);return e.length>0?i([Pe.bold.red("Persisting default events failed"),"",...e.map((t,n)=>`${Pe.dim.gray(`${n+1}.`)} ${Pe.dim(t.message)}`),`
|
|
37
37
|
`].join(`
|
|
38
38
|
`)):(ue=null,c("Persisted pending default events",null))}function io(e){let t;e.some(r=>r.action==="init.workspace")?(ue=null,t=Ee(e)):(ue=Rs(),t=Ee([...ue]));let n=t.filter(a);return n.length>0?i([Pe.bold.red("Materializing failed"),"",...n.map((r,o)=>`${Pe.dim.gray(`${o+1}.`)} ${Pe.dim(r.message)}`),`
|