@cluesmith/codev 2.0.15 → 2.0.16
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/dashboard/dist/assets/{index-BYfmVwKi.js → index-mLspyEje.js} +2 -2
- package/dashboard/dist/assets/{index-BYfmVwKi.js.map → index-mLspyEje.js.map} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/dist/agent-farm/commands/bench.d.ts +1 -1
- package/dist/agent-farm/commands/bench.js +1 -1
- package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-routes.js +8 -2
- package/dist/agent-farm/servers/tower-routes.js.map +1 -1
- package/dist/lib/github.d.ts.map +1 -1
- package/dist/lib/github.js +9 -3
- package/dist/lib/github.js.map +1 -1
- package/package.json +1 -1
|
@@ -130,5 +130,5 @@ void main() {
|
|
|
130
130
|
`),!1;if(!(l?B.metaKey:B.ctrlKey&&B.shiftKey))return!0;if(B.key==="c"||B.key==="C"){const k=a.getSelection();return k?(B.preventDefault(),navigator.clipboard.writeText(k).catch(()=>{}),!1):!0}return B.key==="v"||B.key==="V"?(B.preventDefault(),yg(a),!1):!0});const o=B=>bg(B,a);O.current.addEventListener("paste",o);const m=()=>{var V,le,ce;const B=(V=O.current)==null?void 0:V.getBoundingClientRect();if(!B||B.width===0||B.height===0)return;const D=(ce=(le=a.buffer)==null?void 0:le.active)==null?void 0:ce.baseY;if(!D){g.fit();return}const k=a.buffer.active.viewportY,Y=k==null||k>=D;g.fit(),Y?a.scrollToBottom():a.scrollToLine(k)};let x=null;const v=()=>{x&&clearTimeout(x),x=setTimeout(()=>{x=null,m()},150)};m();const w=setTimeout(v,300),C=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}${I}`,L={lastSeq:0,attempts:0,timer:null,disposed:!1,initialPhase:!0,initialBuffer:"",flushTimer:null},A=50,E=3e4,T=B=>(B=B.replace(/\x1b\[[\?>][\d;]*c/g,""),B=B.replace(/\[[\?>][\d;]*c/g,""),B),H=B=>{const D=B!==void 0?`${C}?resume=${B}`:C,k=new WebSocket(D);k.binaryType="arraybuffer",ne.current=k,L.initialPhase=!0,L.initialBuffer="",L.flushTimer&&(clearTimeout(L.flushTimer),L.flushTimer=null);const Y=()=>{if(L.initialPhase=!1,L.flushTimer=null,L.initialBuffer){const V=T(L.initialBuffer);V&&a.write(V,()=>{a.scrollToBottom()}),L.initialBuffer=""}v(),setTimeout(()=>{var V;((V=ne.current)==null?void 0:V.readyState)===WebSocket.OPEN&&da(ne.current,"resize",{cols:a.cols,rows:a.rows}),a.scrollToBottom()},350)};k.onopen=()=>{L.attempts=0,_("connected"),da(k,"resize",{cols:a.cols,rows:a.rows})},k.onmessage=V=>{var N;const le=new Uint8Array(V.data);if(le.length===0)return;const ce=le[0],q=le.subarray(1);if(ce===hf){const J=new TextDecoder().decode(q);if(L.initialPhase)L.initialBuffer+=J,L.flushTimer||(L.flushTimer=setTimeout(Y,500));else{const ee=T(J);ee&&a.write(ee)}}else if(ce===cf)try{const J=JSON.parse(new TextDecoder().decode(q));J.type==="seq"&&typeof((N=J.payload)==null?void 0:N.seq)=="number"&&(L.lastSeq=J.payload.seq)}catch{}},k.onclose=()=>{if(L.disposed)return;if(L.attempts>=A){_("disconnected"),a.write(`\r
|
|
131
131
|
\x1B[90m[Session ended — unable to reconnect]\x1B[0m\r
|
|
132
132
|
`);return}_("reconnecting"),L.attempts===0&&a.write(`\r
|
|
133
|
-
\x1B[33m[Connection lost — reconnecting...]\x1B[0m`);const V=Math.min(1e3*Math.pow(2,L.attempts),E);L.attempts++,L.timer=setTimeout(()=>{L.disposed||H(L.lastSeq||void 0)},V)},k.onerror=()=>{}},G=/Android|iPhone|iPad|iPod/i.test(navigator.userAgent);let U="",P=0;a.onData(B=>{var Y,V,le,ce,q,N;const D=ne.current;if(!D||D.readyState!==WebSocket.OPEN)return;if(G){const J=Date.now();if(B===U&&J-P<150)return;U=B,P=J}if(L.initialPhase){const J=B.replace(/\x1b\[[\?>][\d;]*c/g,"").replace(/\x1b\[\d+;\d+R/g,"").replace(/\x1b\[\?[\d;]*\$y/g,"");if(!J)return;B=J}const k=n.current;if((k.ctrl||k.cmd)&&B.length===1){const J=B.charCodeAt(0);if(k.ctrl)J>=97&&J<=122?B=String.fromCharCode(J-96):J>=65&&J<=90&&(B=String.fromCharCode(J-64)),k.ctrl=!1,k.cmd=!1,(Y=k.clearCallback)==null||Y.call(k);else if(k.cmd){const ee=B.toLowerCase();if(ee==="v"){(V=navigator.clipboard)==null||V.readText().then(_e=>{_e&&a.paste(_e)}).catch(()=>{}),k.ctrl=!1,k.cmd=!1,(le=k.clearCallback)==null||le.call(k);return}if(ee==="c"){const _e=a.getSelection();_e&&((ce=navigator.clipboard)==null||ce.writeText(_e).catch(()=>{})),k.ctrl=!1,k.cmd=!1,(q=k.clearCallback)==null||q.call(k);return}k.ctrl=!1,k.cmd=!1,(N=k.clearCallback)==null||N.call(k)}}wg(D,B)}),a.onResize(({cols:B,rows:D})=>{const k=ne.current;(k==null?void 0:k.readyState)===WebSocket.OPEN&&da(k,"resize",{cols:B,rows:D})}),H();const F=new ResizeObserver(v);F.observe(O.current);const R=()=>{document.hidden||v()};return document.addEventListener("visibilitychange",R),()=>{var B,D;L.disposed=!0,L.timer&&clearTimeout(L.timer),L.flushTimer&&clearTimeout(L.flushTimer),clearTimeout(w),x&&clearTimeout(x),h==null||h.dispose(),r==null||r.dispose(),(B=O.current)==null||B.removeEventListener("paste",o),F.disconnect(),document.removeEventListener("visibilitychange",R),(D=ne.current)==null||D.close(),a.dispose(),te.current=null,ne.current=null,j.current=null}},[I]),Q.jsxs("div",{style:{width:"100%",height:"100%",display:"flex",flexDirection:"column",position:"relative"},children:[$===!1&&Q.jsx("div",{style:{backgroundColor:"#3a2a00",color:"#ffcc00",padding:"4px 12px",fontSize:"12px",flexShrink:0},children:"Session persistence unavailable — this terminal will not survive a restart"}),Q.jsx("div",{ref:O,className:"terminal-container",style:{width:"100%",flex:1,minHeight:0,overflow:"hidden",backgroundColor:"#1a1a1a"}}),Q.jsx(Sg,{fitRef:j,wsRef:ne,xtermRef:te,connStatus:f}),u&&Q.jsx(mg,{wsRef:ne,modifierRef:n})]})}function wg(I,W){const $=new TextEncoder().encode(W),O=new Uint8Array(1+$.length);O[0]=hf,O.set($,1),I.send(O.buffer)}function da(I,W,$){const O=JSON.stringify({type:W,payload:$}),te=new TextEncoder().encode(O),ne=new Uint8Array(1+te.length);ne[0]=cf,ne.set(te,1),I.send(ne.buffer)}const xg=5e3;function Lg(){const[I,W]=ye.useState(null),[$,O]=ye.useState(null),te=ye.useRef(!1),ne=ye.useCallback(async()=>{try{const n=await jv();W(u=>u!==null&&JSON.stringify(u)===JSON.stringify(n)?u:n),O(null)}catch(n){O(n instanceof Error?n.message:"Failed to fetch overview")}},[]);ye.useEffect(()=>{if(typeof EventSource>"u")return;const n=$v(),u=new EventSource(n);return u.onmessage=f=>{try{JSON.parse(f.data).type==="overview-changed"&&!te.current&&(te.current=!0,ne().finally(()=>{te.current=!1}))}catch{}},u.onerror=()=>{},()=>u.close()},[ne]),ye.useEffect(()=>{ne();const n=setInterval(ne,xg);return()=>clearInterval(n)},[ne]);const j=ye.useCallback(async()=>{await qv(),await ne()},[ne]);return{data:I,error:$,refresh:j}}function Eg(I){if(I.blocked)return`Blocked: ${I.blocked}`;if(I.mode==="soft")return"running";if(!I.phase)return"starting";const W=I.planPhases;if(W.length===0)return I.phase;const $=W.findIndex(O=>O.id===I.phase);return $===-1?I.phase:`${I.phase} (${$+1}/${W.length})`}function Nl(I){if(I<0)return"-";const W=Math.floor(I/6e4);if(W<60)return`${W}m`;const $=Math.floor(W/60),O=W%60;return $<24?`${$}h ${O}m`:`${Math.floor($/24)}d ${$%24}h`}function Mg(I,W){if(!I)return"-";const $=Date.now()-new Date(I).getTime();if($<0)return"-";const O=Math.max(0,$-W);return W===0?Nl($):`${Nl($)} wc / ${Nl(O)} ag`}function Ag({builder:I,onOpen:W}){const $=I.issueNumber?`#${I.issueNumber}`:I.id,O=I.issueTitle||I.id,te=I.blocked!==null&&I.blocked!=="",ne=Math.min(100,Math.max(0,Math.round(I.progress??0)));return Q.jsxs("tr",{className:`builder-row${te?" builder-row--blocked":""}`,children:[Q.jsx("td",{className:"builder-col-id",children:$}),Q.jsx("td",{className:"builder-col-title",children:O}),Q.jsx("td",{className:"builder-col-state",children:Q.jsx("span",{className:te?"builder-state-blocked":"builder-state-active",children:Eg(I)})}),Q.jsxs("td",{className:"builder-col-progress",children:[Q.jsx("div",{className:"progress-bar",children:Q.jsx("div",{className:`progress-fill${te?" progress-fill--blocked":""}`,style:{width:`${ne}%`}})}),Q.jsxs("span",{className:"progress-pct",children:[ne,"%"]})]}),Q.jsx("td",{className:"builder-col-elapsed",children:Mg(I.startedAt,I.idleMs??0)}),Q.jsx("td",{className:"builder-col-actions",children:W&&Q.jsx("button",{className:"builder-row-open",onClick:()=>W(I),children:"Open"})})]})}function Rg(I){const W=Date.now()-new Date(I).getTime(),$=Math.floor(W/6e4);if($<60)return`${Math.max(1,$)}m`;const O=Math.floor($/60);return O<24?`${O}h`:`${Math.floor(O/24)}d`}function Dg(I,W){const $=[];for(const O of I)$.push({key:`pr-${O.number}`,issueOrPR:`#${O.number}`,title:O.title,kind:"PR review",kindClass:"attention-kind--pr",waitingSince:O.createdAt,url:O.url});for(const O of W){if(!O.blocked||!O.blockedSince||O.blocked==="PR review")continue;const te=O.issueNumber?`#${O.issueNumber}`:O.id;$.push({key:`gate-${O.id}`,issueOrPR:te,title:O.issueTitle||O.id,kind:O.blocked,kindClass:O.blocked==="spec review"?"attention-kind--spec":"attention-kind--plan",waitingSince:O.blockedSince})}return $.sort((O,te)=>new Date(O.waitingSince).getTime()-new Date(te.waitingSince).getTime()),$}function Tg({prs:I,builders:W}){const $=Dg(I,W);return $.length===0?Q.jsx("p",{className:"work-empty",children:"Nothing needs attention"}):Q.jsx("div",{className:"attention-rows",children:$.map(O=>{const te=Q.jsxs(Q.Fragment,{children:[Q.jsx("span",{className:"attention-row-id",children:O.issueOrPR}),Q.jsx("span",{className:"attention-row-title",children:O.title}),Q.jsx("span",{className:`attention-row-kind ${O.kindClass}`,children:O.kind}),Q.jsx("span",{className:"attention-row-age",children:Rg(O.waitingSince)})]});return O.url?Q.jsx("a",{className:"attention-row",href:O.url,target:"_blank",rel:"noopener noreferrer",children:te},O.key):Q.jsx("div",{className:"attention-row",children:te},O.key)})})}function Bg(I){const W=Date.now()-new Date(I).getTime(),$=Math.floor(W/6e4);if($<60)return`${Math.max(1,$)}m`;const O=Math.floor($/60);return O<24?`${O}h`:`${Math.floor(O/24)}d`}const Og={high:"priority-dot--high",medium:"priority-dot--med",low:"priority-dot--low"},kg={bug:"type-tag--bug",project:"type-tag--project"};function Ul({label:I,filePath:W,onRefresh:$}){return Q.jsx("button",{className:"backlog-artifact-link",onClick:async O=>{O.preventDefault(),O.stopPropagation(),await Pl(W),$==null||$()},children:I})}function Hg({items:I,onRefresh:W}){const $=I.filter(O=>!O.hasBuilder);return $.length===0?Q.jsx("p",{className:"work-empty",children:"No open issues"}):Q.jsx("div",{className:"backlog-rows",children:$.map(O=>Q.jsxs("div",{className:"backlog-row",children:[Q.jsxs("a",{className:"backlog-row-main",href:O.url,target:"_blank",rel:"noopener noreferrer",children:[Q.jsx("span",{className:`backlog-priority-dot ${Og[O.priority]??"priority-dot--low"}`}),Q.jsxs("span",{className:"backlog-row-number",children:["#",O.number]}),Q.jsx("span",{className:`backlog-type-tag ${kg[O.type]??""}`,children:O.type}),Q.jsx("span",{className:"backlog-row-title",children:O.title}),Q.jsx("span",{className:"backlog-row-age",children:Bg(O.createdAt)})]}),(O.specPath||O.planPath||O.reviewPath)&&Q.jsxs("span",{className:"backlog-artifacts",children:[O.specPath&&Q.jsx(Ul,{label:"spec",filePath:O.specPath,onRefresh:W}),O.planPath&&Q.jsx(Ul,{label:"plan",filePath:O.planPath,onRefresh:W}),O.reviewPath&&Q.jsx(Ul,{label:"review",filePath:O.reviewPath,onRefresh:W})]})]},O.number))})}function zg(I){const W=Date.now()-new Date(I).getTime(),$=Math.floor(W/6e4);if($<60)return`${Math.max(1,$)}m ago`;const O=Math.floor($/60);return O<24?`${O}h ago`:`${Math.floor(O/24)}d ago`}const Ng={bug:"type-tag--bug",project:"type-tag--project"};function Ug({items:I}){return I.length===0?null:Q.jsx("div",{className:"recently-closed-rows",children:I.map(W=>Q.jsxs("a",{className:"recently-closed-row",href:W.url,target:"_blank",rel:"noopener noreferrer",children:[Q.jsx("span",{className:"recently-closed-check",children:"✓"}),Q.jsxs("span",{className:"backlog-row-number",children:["#",W.number]}),Q.jsx("span",{className:`backlog-type-tag ${Ng[W.type]??""}`,children:W.type}),Q.jsx("span",{className:"backlog-row-title",children:W.title}),Q.jsx("span",{className:"backlog-row-age",children:zg(W.closedAt)})]},W.number))})}function Ig(I,W){const $=I.replace(/^\//,"");return W.staged.some(O=>$.endsWith(O)||O.endsWith($))?{indicator:"A",className:"git-staged"}:W.modified.some(O=>$.endsWith(O)||O.endsWith($))?{indicator:"M",className:"git-modified"}:W.untracked.some(O=>$.endsWith(O)||O.endsWith($))?{indicator:"?",className:"git-untracked"}:null}function df({entry:I,expanded:W,gitStatus:$,onToggle:O,onOpen:te,depth:ne=0}){var f;const j=I.type==="directory",n=W.has(I.path),u=j?null:Ig(I.path,$);return Q.jsxs(Q.Fragment,{children:[Q.jsxs("div",{className:`file-node ${j?"directory":"file"}`,style:{paddingLeft:`${ne*16+8}px`},onClick:()=>j?O(I.path):te(I.path),role:"treeitem","aria-expanded":j?n:void 0,tabIndex:0,onKeyDown:_=>{(_.key==="Enter"||_.key===" ")&&(_.preventDefault(),j?O(I.path):te(I.path))},children:[Q.jsx("span",{className:"file-icon",children:j?n?"📂":"📁":"📄"}),Q.jsx("span",{className:"file-name",children:I.name}),u&&Q.jsx("span",{className:`git-indicator ${u.className}`,children:u.indicator})]}),j&&n&&((f=I.children)==null?void 0:f.map(_=>Q.jsx(df,{entry:_,expanded:W,gitStatus:$,onToggle:O,onOpen:te,depth:ne+1},_.path)))]})}function ff(I,W=[]){for(const $ of I)$.type==="file"&&W.push($),$.children&&ff($.children,W);return W}function Pg({onRefresh:I}){const[W,$]=ye.useState([]),[O,te]=ye.useState(new Set),[ne,j]=ye.useState(null),[n,u]=ye.useState(!1),[f,_]=ye.useState({modified:[],staged:[],untracked:[]}),[a,g]=ye.useState([]),[y,b]=ye.useState(""),[c,r]=ye.useState(!1),h=ye.useRef(null),l=ye.useCallback(async()=>{try{const E=await Xv();$(E),j(null),u(!0)}catch(E){j(E.message)}},[]),o=ye.useCallback(async()=>{try{const E=await Yv();_(E)}catch(E){console.error("Failed to load git status:",E)}},[]),m=ye.useCallback(async()=>{try{const E=await Vv();g(E)}catch(E){console.error("Failed to load recent files:",E)}},[]);ye.useEffect(()=>{n||(l(),o(),m())},[n,l,o,m]),ye.useEffect(()=>{const E=setInterval(()=>{l(),o()},5e3);return()=>clearInterval(E)},[l,o]);const x=E=>{te(T=>{const H=new Set(T);return H.has(E)?H.delete(E):H.add(E),H})},v=async E=>{try{await Pl(E),I(),m()}catch(T){console.error("Failed to open file:",T)}},w=ye.useMemo(()=>ff(W),[W]),S=ye.useMemo(()=>{if(!y.trim())return[];const E=y.toLowerCase();return w.filter(T=>T.name.toLowerCase().includes(E)||T.path.toLowerCase().includes(E)).slice(0,10)},[w,y]),C=E=>{b(E.target.value),r(!0)},L=E=>{E.key==="Escape"?(r(!1),b("")):E.key==="Enter"&&S.length>0&&(v(S[0].path),b(""),r(!1))},A=E=>{v(E),b(""),r(!1)};return ne?Q.jsxs("div",{className:"file-tree-error",children:["Error: ",ne]}):n?Q.jsxs("div",{className:"file-tree-container",children:[Q.jsxs("div",{className:"file-search",children:[Q.jsx("input",{ref:h,type:"text",className:"file-search-input",placeholder:"Search files...",value:y,onChange:C,onKeyDown:L,onFocus:()=>r(!0),onBlur:()=>setTimeout(()=>r(!1),200)}),c&&S.length>0&&Q.jsx("div",{className:"file-search-suggestions",children:S.map(E=>Q.jsxs("div",{className:"file-search-suggestion",onMouseDown:()=>A(E.path),children:[Q.jsx("span",{className:"suggestion-name",children:E.name}),Q.jsx("span",{className:"suggestion-path",children:E.path})]},E.path))})]}),a.length>0&&Q.jsxs("div",{className:"file-tree-section",children:[Q.jsx("div",{className:"file-tree-section-header",children:"Recent"}),a.map(E=>Q.jsxs("div",{className:"file-node file recent-file",style:{paddingLeft:"8px"},onClick:()=>v(E.path),role:"treeitem",tabIndex:0,onKeyDown:T=>{(T.key==="Enter"||T.key===" ")&&(T.preventDefault(),v(E.path))},children:[Q.jsx("span",{className:"file-icon",children:"🕐"}),Q.jsx("span",{className:"file-name",children:E.name}),Q.jsx("span",{className:"file-path-hint",children:E.relativePath})]},E.id))]}),Q.jsxs("div",{className:"file-tree-section",children:[Q.jsx("div",{className:"file-tree-section-header",children:"Files"}),Q.jsx("div",{className:"file-tree",role:"tree","aria-label":"Project files",children:W.map(E=>Q.jsx(df,{entry:E,expanded:O,gitStatus:f,onToggle:x,onOpen:v},E.path))})]})]}):Q.jsx("div",{className:"file-tree-loading",children:"Loading files..."})}const er=['Use `af spawn --task "description"` for quick one-off tasks that don\'t need a spec',"Run `af status` to see all active builders and their current phase",'Use `af send architect "message"` to notify the architect when you need guidance',"Run `af cleanup --project 0042` after merging a PR to clean up the worktree","Use `af spawn --soft -p 42` for flexible, protocol-guided work without strict porch orchestration","Run `af dash start` to launch the architect dashboard","Use `af spawn 42 --resume` to resume an existing builder worktree instead of recreating it","Use `af open file.ts` to open a file in the dashboard annotation viewer","Run `af tower start` to start the Tower server — there is no `restart` command, use stop then start","Check `af-config.json` at your project root to customize builder and architect commands","Run `porch pending` to see all gates waiting for your approval across all projects","Use `porch status 42` to see detailed phase status for a specific project","Run `porch next 42` to get the next tasks for a project","Use `porch done 42` to signal that the current phase work is complete","Gates like `spec-approval` and `plan-approval` require explicit human approval before advancing","Porch tracks state in `codev/projects/<id>/status.yaml` — never edit this file directly","Use `porch approve 42 spec-approval` to approve a gate (human only)","Porch drives SPIR, TICK, and BUGFIX protocols via a state machine with automatic consultations","Use `consult -m gemini --type integration` for integration reviews with Gemini","Run `consult -m gemini --protocol spir --type spec` to get a Gemini review of your specification","Use `consult -m codex --protocol spir --type spec` for a focused specification review","Run `consult -m claude --protocol spir --type plan` to get feedback on your implementation plan","The `consult` CLI supports three models: `gemini`, `codex`, and `claude`",'Use `consult -m gemini --prompt "your question"` to ask Gemini a general question with codebase context','Say "cmap the PR" to run all three consultations in parallel in the background','Consultations are enabled by default in SPIR — say "without consultation" to skip them',"Commit specs and plans to `main` before spawning — builders branch from HEAD","Always add files explicitly with `git add file1 file2` — never use `git add .` or `git add -A`","Use SPIR for new features, TICK for amendments to existing specs, and BUGFIX for issue fixes","Each SPIR feature produces exactly three documents: spec, plan, and review","Specs define WHAT to build, plans define HOW — keep them as separate documents","Add YAML frontmatter with `approved` and `validated` fields to skip phases in porch","Run `codev doctor` to check that your environment is set up correctly","Use `--merge` (not squash) when merging PRs — individual commits document the development process","The TICK protocol modifies spec and plan in-place and creates a new review file","BUGFIX protocol uses GitHub Issues as source of truth — no spec/plan artifacts needed",'Run `tokei -e "node_modules" -e ".git" -e "dist" .` to measure codebase size',"Use `codev adopt` to set up Codev in an existing project","Click a builder card in the Work view to jump to its terminal tab","The file panel in Work view lets you browse project files without leaving the dashboard","Use the Refresh button to update builder status, PRs, and backlog data","The dashboard shows active builders, pending PRs, and backlog items in one view","Click the file panel toggle arrow to expand or collapse the file browser","The dashboard supports both desktop split-pane and mobile single-pane layouts","Tab indicators show builder status at a glance — active, waiting, or implementing","Use the `+ Shell` button to quickly open a new shell terminal tab","The SPIR protocol has four phases: Specify, Plan, Implement (IDE loop), and Review","Each implementation phase follows the IDE cycle: Implement, Defend (test), Evaluate","The EXPERIMENT protocol is for testing new approaches — use it for proof-of-concept work","The MAINTAIN protocol handles code hygiene and documentation sync","Run 3-way consultations at each SPIR checkpoint for spec, plan, and implementation reviews"];function Fg(I){const W=new Date(I.getFullYear(),0,0);return Math.floor((I.getTime()-W.getTime())/864e5)}function _f(I){const W=I.getFullYear(),$=String(I.getMonth()+1).padStart(2,"0"),O=String(I.getDate()).padStart(2,"0");return`tip-dismissed-${W}-${$}-${O}`}function jg(){try{return localStorage.getItem(_f(new Date))==="1"}catch{return!1}}function $g(){try{localStorage.setItem(_f(new Date),"1")}catch{}}function qg(I){return I.split("`").map(($,O)=>O%2===1?Q.jsx("code",{children:$},O):Q.jsx("span",{children:$},O))}function Wg(){const I=Fg(new Date)%er.length,[W,$]=ye.useState(I),[O,te]=ye.useState(jg);if(O||er.length===0)return null;const ne=()=>{$((W-1+er.length)%er.length)},j=()=>{$((W+1)%er.length)},n=()=>{$g(),te(!0)};return Q.jsxs("div",{className:"tip-banner",children:[Q.jsx("button",{className:"tip-banner-nav",onClick:ne,"aria-label":"Previous tip",children:"‹"}),Q.jsx("span",{className:"tip-banner-label",children:"Tip:"}),Q.jsx("span",{className:"tip-banner-text",children:qg(er[W])}),Q.jsx("button",{className:"tip-banner-nav",onClick:j,"aria-label":"Next tip",children:"›"}),Q.jsx("button",{className:"tip-banner-dismiss",onClick:n,"aria-label":"Dismiss tip",children:"×"})]})}function Gg({state:I,onRefresh:W,onSelectTab:$}){var _,a;const{data:O,error:te,refresh:ne}=Lg(),[j,n]=ye.useState(!1),u=ye.useCallback(async()=>{try{await Wv(),W()}catch(g){console.error("Failed to create shell:",g)}},[W]),f=ye.useCallback(g=>{var b;const y=(b=I==null?void 0:I.builders)==null?void 0:b.find(c=>{var r,h,l,o;return g.issueNumber?((r=c.name)==null?void 0:r.includes(String(g.issueNumber)))||((h=c.id)==null?void 0:h.includes(String(g.issueNumber))):((l=c.id)==null?void 0:l.includes(g.id))||((o=c.name)==null?void 0:o.includes(g.id))});y&&($==null||$(y.id))},[I==null?void 0:I.builders,$]);return I?Q.jsxs("div",{className:`work-view ${j?"file-panel-open":""}`,children:[Q.jsxs("div",{className:"work-content",children:[Q.jsxs("div",{className:"work-header",children:[Q.jsx("h2",{className:"work-title",children:"Work"}),Q.jsxs("div",{className:"work-actions",children:[Q.jsx("button",{className:"work-btn",onClick:u,children:"+ Shell"}),Q.jsx("button",{className:"work-btn work-btn-secondary",onClick:ne,children:"Refresh"})]})]}),te&&Q.jsxs("div",{className:"work-error",children:["Failed to load overview: ",te]}),Q.jsx(Wg,{}),Q.jsxs("section",{className:"work-section",children:[Q.jsx("h3",{className:"work-section-title",children:"Builders"}),O!=null&&O.builders&&O.builders.length>0?Q.jsxs("table",{className:"builder-table",children:[Q.jsx("thead",{children:Q.jsxs("tr",{children:[Q.jsx("th",{children:"Issue"}),Q.jsx("th",{children:"Title"}),Q.jsx("th",{children:"State"}),Q.jsx("th",{children:"Progress"}),Q.jsx("th",{children:"Elapsed"}),Q.jsx("th",{})]})}),Q.jsx("tbody",{children:O.builders.map(g=>Q.jsx(Ag,{builder:g,onOpen:f},g.id))})]}):Q.jsx("p",{className:"work-empty",children:"No active builders"})]}),Q.jsxs("section",{className:"work-section",children:[Q.jsx("h3",{className:"work-section-title",children:"Needs Attention"}),(_=O==null?void 0:O.errors)!=null&&_.prs?Q.jsx("p",{className:"work-unavailable",children:O.errors.prs}):Q.jsx(Tg,{prs:(O==null?void 0:O.pendingPRs)??[],builders:(O==null?void 0:O.builders)??[]})]}),Q.jsxs("section",{className:"work-section",children:[Q.jsx("h3",{className:"work-section-title",children:"Projects and Bugs"}),(a=O==null?void 0:O.errors)!=null&&a.issues?Q.jsx("p",{className:"work-unavailable",children:O.errors.issues}):Q.jsx(Hg,{items:(O==null?void 0:O.backlog)??[],onRefresh:W})]}),(O==null?void 0:O.recentlyClosed)&&O.recentlyClosed.length>0&&Q.jsxs("section",{className:"work-section",children:[Q.jsx("h3",{className:"work-section-title",children:"Recently Closed"}),Q.jsx(Ug,{items:O.recentlyClosed})]})]}),Q.jsxs("div",{className:`work-file-panel ${j?"expanded":"collapsed"}`,children:[Q.jsxs("div",{className:"work-file-panel-header",children:[Q.jsx("span",{className:"work-file-panel-toggle",onClick:()=>n(!j),children:j?"▼":"▲"}),Q.jsx("span",{className:"work-file-panel-label",onClick:()=>n(!j),children:"Files"}),!j&&Q.jsx("input",{className:"work-file-panel-search",type:"text",placeholder:"Search files...",onFocus:()=>n(!0)})]}),j&&Q.jsx("div",{className:"work-file-panel-content",children:Q.jsx(Pg,{onRefresh:W})})]})]}):Q.jsx("div",{className:"work-view",children:Q.jsx("p",{className:"work-loading",children:"Loading..."})})}function Xg({tabs:I,activeTabId:W,onSelectTab:$,onRefresh:O,children:te}){return Q.jsxs("div",{className:"mobile-layout",children:[Q.jsx(nf,{tabs:I,activeTabId:W,onSelectTab:$,onRefresh:O}),Q.jsx("div",{className:"mobile-content",children:te})]})}function Yg({tabId:I,initialLine:W}){let O=`${tf()}api/annotate/${I}/`;return W&&(O+=`?line=${W}`),Q.jsx("div",{className:"file-viewer",style:{width:"100%",height:"100%"},children:Q.jsx("iframe",{src:O,style:{width:"100%",height:"100%",border:"none"},title:"File Annotator"})})}function Vg(I,W){const $=I==null?void 0:I.trim(),O=W==null?void 0:W.trim();return $&&O&&$.toLowerCase()!==O.toLowerCase()?`${$} ${O} dashboard`:O?`${O} dashboard`:"dashboard"}function Kg(){const{state:I,refresh:W}=Kv(),{tabs:$,activeTab:O,activeTabId:te,selectTab:ne}=Zv(I),j=rf(`(max-width: ${ef}px)`),[n,u]=ye.useState(new Set),f=ye.useRef(new Map),_=ye.useCallback(async(l,o,m,x)=>{try{const v=await Pl(l,o,x);o&&o>0&&f.current.set(v.id,o),W()}catch(v){console.error("Failed to open file:",v)}},[W]),a=Vg(I==null?void 0:I.hostname,I==null?void 0:I.workspaceName);ye.useEffect(()=>{document.title=a},[a]);const[g]=ye.useState(()=>new URLSearchParams(window.location.search).get("fullscreen")==="1");ye.useEffect(()=>{if(!O)return;(O.type==="architect"||O.type==="builder"||O.type==="shell")&&u(o=>{if(o.has(O.id))return o;const m=new Set(o);return m.add(O.id),m})},[O==null?void 0:O.id,O==null?void 0:O.type]);const y=l=>{const o=Xd(l);return o?Q.jsx(Jd,{wsPath:o,onFileOpen:_,persistent:l.persistent}):Q.jsx("div",{className:"no-terminal",children:"No terminal session"})},b=l=>{if(!l.annotationId||!I)return Q.jsx("div",{className:"no-terminal",children:"No file viewer"});if(!I.annotations.find(x=>x.id===l.annotationId))return Q.jsx("div",{className:"no-terminal",children:"Annotation not found"});const m=f.current.get(l.annotationId);return m!==void 0&&f.current.delete(l.annotationId),Q.jsx(Yg,{tabId:l.annotationId,initialLine:m??l.initialLine})},c=l=>{const o=$.filter(m=>l.includes(m.type)&&n.has(m.id));return Q.jsxs(Q.Fragment,{children:[o.map(m=>{const x=Xd(m);return Q.jsx("div",{className:"terminal-tab-pane",style:{display:te===m.id?void 0:"none"},children:x?Q.jsx(Jd,{wsPath:x,onFileOpen:_,persistent:m.persistent}):Q.jsx("div",{className:"no-terminal",children:"No terminal session"})},m.id)}),Q.jsx("div",{style:{display:(O==null?void 0:O.type)==="work"?void 0:"none"},children:Q.jsx(Gg,{state:I,onRefresh:W,onSelectTab:ne})}),(O==null?void 0:O.type)==="file"&&b(O)]})};if(g)return O&&(O.type==="architect"||O.type==="builder"||O.type==="shell")?Q.jsx("div",{className:"fullscreen-terminal",children:y(O)}):Q.jsx("div",{className:"fullscreen-terminal"});if(j)return Q.jsx("div",{className:"mobile-wrapper",children:Q.jsx(Xg,{tabs:$,activeTabId:te,onSelectTab:ne,onRefresh:W,children:c(["architect","builder","shell"])})});const r=$.find(l=>l.type==="architect"),h=r?y(r):Q.jsx("div",{className:"no-architect",children:"No architect terminal"});return Q.jsxs("div",{className:"app",children:[Q.jsxs("header",{className:"app-header",children:[Q.jsx("h1",{className:"app-title",children:a}),(I==null?void 0:I.version)&&Q.jsxs("span",{className:"header-version",children:["v",I.version]})]}),Q.jsx("div",{className:"app-body",children:Q.jsx(Jv,{left:h,right:Q.jsxs("div",{className:"right-panel",children:[Q.jsx(nf,{tabs:$.filter(l=>l.type!=="architect"),activeTabId:te,onSelectTab:ne,onRefresh:W}),Q.jsx("div",{className:"tab-content",role:"tabpanel",children:c(["builder","shell"])})]})})})]})}Iv.createRoot(document.getElementById("root")).render(Q.jsx(ye.StrictMode,{children:Q.jsx(Kg,{})}));
|
|
134
|
-
//# sourceMappingURL=index-
|
|
133
|
+
\x1B[33m[Connection lost — reconnecting...]\x1B[0m`);const V=Math.min(1e3*Math.pow(2,L.attempts),E);L.attempts++,L.timer=setTimeout(()=>{L.disposed||H(L.lastSeq||void 0)},V)},k.onerror=()=>{}},G=/Android|iPhone|iPad|iPod/i.test(navigator.userAgent);let U="",P=0;a.onData(B=>{var Y,V,le,ce,q,N;const D=ne.current;if(!D||D.readyState!==WebSocket.OPEN)return;if(G){const J=Date.now();if(B===U&&J-P<150)return;U=B,P=J}if(L.initialPhase){const J=B.replace(/\x1b\[[\?>][\d;]*c/g,"").replace(/\x1b\[\d+;\d+R/g,"").replace(/\x1b\[\?[\d;]*\$y/g,"");if(!J)return;B=J}const k=n.current;if((k.ctrl||k.cmd)&&B.length===1){const J=B.charCodeAt(0);if(k.ctrl)J>=97&&J<=122?B=String.fromCharCode(J-96):J>=65&&J<=90&&(B=String.fromCharCode(J-64)),k.ctrl=!1,k.cmd=!1,(Y=k.clearCallback)==null||Y.call(k);else if(k.cmd){const ee=B.toLowerCase();if(ee==="v"){(V=navigator.clipboard)==null||V.readText().then(_e=>{_e&&a.paste(_e)}).catch(()=>{}),k.ctrl=!1,k.cmd=!1,(le=k.clearCallback)==null||le.call(k);return}if(ee==="c"){const _e=a.getSelection();_e&&((ce=navigator.clipboard)==null||ce.writeText(_e).catch(()=>{})),k.ctrl=!1,k.cmd=!1,(q=k.clearCallback)==null||q.call(k);return}k.ctrl=!1,k.cmd=!1,(N=k.clearCallback)==null||N.call(k)}}wg(D,B)}),a.onResize(({cols:B,rows:D})=>{const k=ne.current;(k==null?void 0:k.readyState)===WebSocket.OPEN&&da(k,"resize",{cols:B,rows:D})}),H();const F=new ResizeObserver(v);F.observe(O.current);const R=()=>{document.hidden||v()};return document.addEventListener("visibilitychange",R),()=>{var B,D;L.disposed=!0,L.timer&&clearTimeout(L.timer),L.flushTimer&&clearTimeout(L.flushTimer),clearTimeout(w),x&&clearTimeout(x),h==null||h.dispose(),r==null||r.dispose(),(B=O.current)==null||B.removeEventListener("paste",o),F.disconnect(),document.removeEventListener("visibilitychange",R),(D=ne.current)==null||D.close(),a.dispose(),te.current=null,ne.current=null,j.current=null}},[I]),Q.jsxs("div",{style:{width:"100%",height:"100%",display:"flex",flexDirection:"column",position:"relative"},children:[$===!1&&Q.jsx("div",{style:{backgroundColor:"#3a2a00",color:"#ffcc00",padding:"4px 12px",fontSize:"12px",flexShrink:0},children:"Session persistence unavailable — this terminal will not survive a restart"}),Q.jsx("div",{ref:O,className:"terminal-container",style:{width:"100%",flex:1,minHeight:0,overflow:"hidden",backgroundColor:"#1a1a1a"}}),Q.jsx(Sg,{fitRef:j,wsRef:ne,xtermRef:te,connStatus:f}),u&&Q.jsx(mg,{wsRef:ne,modifierRef:n})]})}function wg(I,W){const $=new TextEncoder().encode(W),O=new Uint8Array(1+$.length);O[0]=hf,O.set($,1),I.send(O.buffer)}function da(I,W,$){const O=JSON.stringify({type:W,payload:$}),te=new TextEncoder().encode(O),ne=new Uint8Array(1+te.length);ne[0]=cf,ne.set(te,1),I.send(ne.buffer)}const xg=5e3;function Lg(){const[I,W]=ye.useState(null),[$,O]=ye.useState(null),te=ye.useRef(!1),ne=ye.useCallback(async()=>{try{const n=await jv();W(u=>u!==null&&JSON.stringify(u)===JSON.stringify(n)?u:n),O(null)}catch(n){O(n instanceof Error?n.message:"Failed to fetch overview")}},[]);ye.useEffect(()=>{if(typeof EventSource>"u")return;const n=$v(),u=new EventSource(n);return u.onmessage=f=>{try{JSON.parse(f.data).type==="overview-changed"&&!te.current&&(te.current=!0,ne().finally(()=>{te.current=!1}))}catch{}},u.onerror=()=>{},()=>u.close()},[ne]),ye.useEffect(()=>{ne();const n=setInterval(ne,xg);return()=>clearInterval(n)},[ne]);const j=ye.useCallback(async()=>{await qv(),await ne()},[ne]);return{data:I,error:$,refresh:j}}function Eg(I){if(I.blocked)return`Blocked: ${I.blocked}`;if(I.mode==="soft")return"running";if(!I.phase)return"starting";const W=I.planPhases;if(W.length===0)return I.phase;const $=W.findIndex(O=>O.id===I.phase);return $===-1?I.phase:`${I.phase} (${$+1}/${W.length})`}function Nl(I){if(I<0)return"-";const W=Math.floor(I/6e4);if(W<60)return`${W}m`;const $=Math.floor(W/60),O=W%60;return $<24?`${$}h ${O}m`:`${Math.floor($/24)}d ${$%24}h`}function Mg(I,W){if(!I)return"-";const $=Date.now()-new Date(I).getTime();if($<0)return"-";const O=Math.max(0,$-W);return W===0?Nl($):`${Nl($)} wc / ${Nl(O)} ag`}function Ag({builder:I,onOpen:W}){const $=I.issueNumber?`#${I.issueNumber}`:I.id,O=I.issueTitle||I.id,te=I.blocked!==null&&I.blocked!=="",ne=Math.min(100,Math.max(0,Math.round(I.progress??0)));return Q.jsxs("tr",{className:`builder-row${te?" builder-row--blocked":""}`,children:[Q.jsx("td",{className:"builder-col-id",children:$}),Q.jsx("td",{className:"builder-col-title",children:O}),Q.jsx("td",{className:"builder-col-state",children:Q.jsx("span",{className:te?"builder-state-blocked":"builder-state-active",children:Eg(I)})}),Q.jsxs("td",{className:"builder-col-progress",children:[Q.jsx("div",{className:"progress-bar",children:Q.jsx("div",{className:`progress-fill${te?" progress-fill--blocked":""}`,style:{width:`${ne}%`}})}),Q.jsxs("span",{className:"progress-pct",children:[ne,"%"]})]}),Q.jsx("td",{className:"builder-col-elapsed",children:Mg(I.startedAt,I.idleMs??0)}),Q.jsx("td",{className:"builder-col-actions",children:W&&Q.jsx("button",{className:"builder-row-open",onClick:()=>W(I),children:"Open"})})]})}function Rg(I){const W=Date.now()-new Date(I).getTime(),$=Math.floor(W/6e4);if($<60)return`${Math.max(1,$)}m`;const O=Math.floor($/60);return O<24?`${O}h`:`${Math.floor(O/24)}d`}function Dg(I,W){const $=[];for(const O of I)$.push({key:`pr-${O.number}`,issueOrPR:`#${O.number}`,title:O.title,kind:"PR review",kindClass:"attention-kind--pr",waitingSince:O.createdAt,url:O.url});for(const O of W){if(!O.blocked||!O.blockedSince||O.blocked==="PR review")continue;const te=O.issueNumber?`#${O.issueNumber}`:O.id;$.push({key:`gate-${O.id}`,issueOrPR:te,title:O.issueTitle||O.id,kind:O.blocked,kindClass:O.blocked==="spec review"?"attention-kind--spec":"attention-kind--plan",waitingSince:O.blockedSince})}return $.sort((O,te)=>new Date(O.waitingSince).getTime()-new Date(te.waitingSince).getTime()),$}function Tg({prs:I,builders:W}){const $=Dg(I,W);return $.length===0?Q.jsx("p",{className:"work-empty",children:"Nothing needs attention"}):Q.jsx("div",{className:"attention-rows",children:$.map(O=>{const te=Q.jsxs(Q.Fragment,{children:[Q.jsx("span",{className:"attention-row-id",children:O.issueOrPR}),Q.jsx("span",{className:"attention-row-title",children:O.title}),Q.jsx("span",{className:`attention-row-kind ${O.kindClass}`,children:O.kind}),Q.jsx("span",{className:"attention-row-age",children:Rg(O.waitingSince)})]});return O.url?Q.jsx("a",{className:"attention-row",href:O.url,target:"_blank",rel:"noopener noreferrer",children:te},O.key):Q.jsx("div",{className:"attention-row",children:te},O.key)})})}function Bg(I){const W=Date.now()-new Date(I).getTime(),$=Math.floor(W/6e4);if($<60)return`${Math.max(1,$)}m`;const O=Math.floor($/60);return O<24?`${O}h`:`${Math.floor(O/24)}d`}const Og={high:"priority-dot--high",medium:"priority-dot--med",low:"priority-dot--low"},kg={bug:"type-tag--bug",project:"type-tag--project"};function Ul({label:I,filePath:W,onRefresh:$}){return Q.jsx("button",{className:"backlog-artifact-link",onClick:async O=>{O.preventDefault(),O.stopPropagation(),await Pl(W),$==null||$()},children:I})}function Hg({items:I,onRefresh:W}){const $=I.filter(O=>!O.hasBuilder);return $.length===0?Q.jsx("p",{className:"work-empty",children:"No open issues"}):Q.jsx("div",{className:"backlog-rows",children:$.map(O=>Q.jsxs("div",{className:"backlog-row",children:[Q.jsxs("a",{className:"backlog-row-main",href:O.url,target:"_blank",rel:"noopener noreferrer",children:[Q.jsx("span",{className:`backlog-priority-dot ${Og[O.priority]??"priority-dot--low"}`}),Q.jsxs("span",{className:"backlog-row-number",children:["#",O.number]}),Q.jsx("span",{className:`backlog-type-tag ${kg[O.type]??""}`,children:O.type}),Q.jsx("span",{className:"backlog-row-title",children:O.title}),Q.jsx("span",{className:"backlog-row-age",children:Bg(O.createdAt)})]}),(O.specPath||O.planPath||O.reviewPath)&&Q.jsxs("span",{className:"backlog-artifacts",children:[O.specPath&&Q.jsx(Ul,{label:"spec",filePath:O.specPath,onRefresh:W}),O.planPath&&Q.jsx(Ul,{label:"plan",filePath:O.planPath,onRefresh:W}),O.reviewPath&&Q.jsx(Ul,{label:"review",filePath:O.reviewPath,onRefresh:W})]})]},O.number))})}function zg(I){const W=Date.now()-new Date(I).getTime(),$=Math.floor(W/6e4);if($<60)return`${Math.max(1,$)}m ago`;const O=Math.floor($/60);return O<24?`${O}h ago`:`${Math.floor(O/24)}d ago`}const Ng={bug:"type-tag--bug",project:"type-tag--project"};function Ug({items:I}){return I.length===0?null:Q.jsx("div",{className:"recently-closed-rows",children:I.map(W=>Q.jsxs("a",{className:"recently-closed-row",href:W.url,target:"_blank",rel:"noopener noreferrer",children:[Q.jsx("span",{className:"recently-closed-check",children:"✓"}),Q.jsxs("span",{className:"backlog-row-number",children:["#",W.number]}),Q.jsx("span",{className:`backlog-type-tag ${Ng[W.type]??""}`,children:W.type}),Q.jsx("span",{className:"backlog-row-title",children:W.title}),Q.jsx("span",{className:"backlog-row-age",children:zg(W.closedAt)})]},W.number))})}function Ig(I,W){const $=I.replace(/^\//,"");return W.staged.some(O=>$.endsWith(O)||O.endsWith($))?{indicator:"A",className:"git-staged"}:W.modified.some(O=>$.endsWith(O)||O.endsWith($))?{indicator:"M",className:"git-modified"}:W.untracked.some(O=>$.endsWith(O)||O.endsWith($))?{indicator:"?",className:"git-untracked"}:null}function df({entry:I,expanded:W,gitStatus:$,onToggle:O,onOpen:te,depth:ne=0}){var f;const j=I.type==="directory",n=W.has(I.path),u=j?null:Ig(I.path,$);return Q.jsxs(Q.Fragment,{children:[Q.jsxs("div",{className:`file-node ${j?"directory":"file"}`,style:{paddingLeft:`${ne*16+8}px`},onClick:()=>j?O(I.path):te(I.path),role:"treeitem","aria-expanded":j?n:void 0,tabIndex:0,onKeyDown:_=>{(_.key==="Enter"||_.key===" ")&&(_.preventDefault(),j?O(I.path):te(I.path))},children:[Q.jsx("span",{className:"file-icon",children:j?n?"📂":"📁":"📄"}),Q.jsx("span",{className:"file-name",children:I.name}),u&&Q.jsx("span",{className:`git-indicator ${u.className}`,children:u.indicator})]}),j&&n&&((f=I.children)==null?void 0:f.map(_=>Q.jsx(df,{entry:_,expanded:W,gitStatus:$,onToggle:O,onOpen:te,depth:ne+1},_.path)))]})}function ff(I,W=[]){for(const $ of I)$.type==="file"&&W.push($),$.children&&ff($.children,W);return W}function Pg({onRefresh:I}){const[W,$]=ye.useState([]),[O,te]=ye.useState(new Set),[ne,j]=ye.useState(null),[n,u]=ye.useState(!1),[f,_]=ye.useState({modified:[],staged:[],untracked:[]}),[a,g]=ye.useState([]),[y,b]=ye.useState(""),[c,r]=ye.useState(!1),h=ye.useRef(null),l=ye.useCallback(async()=>{try{const E=await Xv();$(E),j(null),u(!0)}catch(E){j(E.message)}},[]),o=ye.useCallback(async()=>{try{const E=await Yv();_(E)}catch(E){console.error("Failed to load git status:",E)}},[]),m=ye.useCallback(async()=>{try{const E=await Vv();g(E)}catch(E){console.error("Failed to load recent files:",E)}},[]);ye.useEffect(()=>{n||(l(),o(),m())},[n,l,o,m]),ye.useEffect(()=>{const E=setInterval(()=>{l(),o()},5e3);return()=>clearInterval(E)},[l,o]);const x=E=>{te(T=>{const H=new Set(T);return H.has(E)?H.delete(E):H.add(E),H})},v=async E=>{try{await Pl(E),I(),m()}catch(T){console.error("Failed to open file:",T)}},w=ye.useMemo(()=>ff(W),[W]),S=ye.useMemo(()=>{if(!y.trim())return[];const E=y.toLowerCase();return w.filter(T=>T.name.toLowerCase().includes(E)||T.path.toLowerCase().includes(E)).slice(0,10)},[w,y]),C=E=>{b(E.target.value),r(!0)},L=E=>{E.key==="Escape"?(r(!1),b("")):E.key==="Enter"&&S.length>0&&(v(S[0].path),b(""),r(!1))},A=E=>{v(E),b(""),r(!1)};return ne?Q.jsxs("div",{className:"file-tree-error",children:["Error: ",ne]}):n?Q.jsxs("div",{className:"file-tree-container",children:[Q.jsxs("div",{className:"file-search",children:[Q.jsx("input",{ref:h,type:"text",className:"file-search-input",placeholder:"Search files...",value:y,onChange:C,onKeyDown:L,onFocus:()=>r(!0),onBlur:()=>setTimeout(()=>r(!1),200)}),c&&S.length>0&&Q.jsx("div",{className:"file-search-suggestions",children:S.map(E=>Q.jsxs("div",{className:"file-search-suggestion",onMouseDown:()=>A(E.path),children:[Q.jsx("span",{className:"suggestion-name",children:E.name}),Q.jsx("span",{className:"suggestion-path",children:E.path})]},E.path))})]}),a.length>0&&Q.jsxs("div",{className:"file-tree-section",children:[Q.jsx("div",{className:"file-tree-section-header",children:"Recent"}),a.map(E=>Q.jsxs("div",{className:"file-node file recent-file",style:{paddingLeft:"8px"},onClick:()=>v(E.path),role:"treeitem",tabIndex:0,onKeyDown:T=>{(T.key==="Enter"||T.key===" ")&&(T.preventDefault(),v(E.path))},children:[Q.jsx("span",{className:"file-icon",children:"🕐"}),Q.jsx("span",{className:"file-name",children:E.name}),Q.jsx("span",{className:"file-path-hint",children:E.relativePath})]},E.id))]}),Q.jsxs("div",{className:"file-tree-section",children:[Q.jsx("div",{className:"file-tree-section-header",children:"Files"}),Q.jsx("div",{className:"file-tree",role:"tree","aria-label":"Project files",children:W.map(E=>Q.jsx(df,{entry:E,expanded:O,gitStatus:f,onToggle:x,onOpen:v},E.path))})]})]}):Q.jsx("div",{className:"file-tree-loading",children:"Loading files..."})}const er=['Use `af spawn --task "description"` for quick one-off tasks that don\'t need a spec',"Run `af status` to see all active builders and their current phase",'Use `af send architect "message"` to notify the architect when you need guidance',"Run `af cleanup --project 0042` after merging a PR to clean up the worktree","Use `af spawn --soft -p 42` for flexible, protocol-guided work without strict porch orchestration","Run `af dash start` to launch the architect dashboard","Use `af spawn 42 --resume` to resume an existing builder worktree instead of recreating it","Use `af open file.ts` to open a file in the dashboard annotation viewer","Run `af tower start` to start the Tower server — there is no `restart` command, use stop then start","Check `af-config.json` at your project root to customize builder and architect commands","Run `porch pending` to see all gates waiting for your approval across all projects","Use `porch status 42` to see detailed phase status for a specific project","Run `porch next 42` to get the next tasks for a project","Use `porch done 42` to signal that the current phase work is complete","Gates like `spec-approval` and `plan-approval` require explicit human approval before advancing","Porch tracks state in `codev/projects/<id>/status.yaml` — never edit this file directly","Use `porch approve 42 spec-approval` to approve a gate (human only)","Porch drives SPIR, TICK, and BUGFIX protocols via a state machine with automatic consultations","Use `consult -m gemini --type integration` for integration reviews with Gemini","Run `consult -m gemini --protocol spir --type spec` to get a Gemini review of your specification","Use `consult -m codex --protocol spir --type spec` for a focused specification review","Run `consult -m claude --protocol spir --type plan` to get feedback on your implementation plan","The `consult` CLI supports three models: `gemini`, `codex`, and `claude`",'Use `consult -m gemini --prompt "your question"` to ask Gemini a general question with codebase context','Say "cmap the PR" to run all three consultations in parallel in the background','Consultations are enabled by default in SPIR — say "without consultation" to skip them',"Commit specs and plans to `main` before spawning — builders branch from HEAD","Always add files explicitly with `git add file1 file2` — never use `git add .` or `git add -A`","Use SPIR for new features, TICK for amendments to existing specs, and BUGFIX for issue fixes","Each SPIR feature produces exactly three documents: spec, plan, and review","Specs define WHAT to build, plans define HOW — keep them as separate documents","Add YAML frontmatter with `approved` and `validated` fields to skip phases in porch","Run `codev doctor` to check that your environment is set up correctly","Use `--merge` (not squash) when merging PRs — individual commits document the development process","The TICK protocol modifies spec and plan in-place and creates a new review file","BUGFIX protocol uses GitHub Issues as source of truth — no spec/plan artifacts needed",'Run `tokei -e "node_modules" -e ".git" -e "dist" .` to measure codebase size',"Use `codev adopt` to set up Codev in an existing project","Click a builder card in the Work view to jump to its terminal tab","The file panel in Work view lets you browse project files without leaving the dashboard","Use the Refresh button to update builder status, PRs, and backlog data","The dashboard shows active builders, pending PRs, and backlog items in one view","Click the file panel toggle arrow to expand or collapse the file browser","The dashboard supports both desktop split-pane and mobile single-pane layouts","Tab indicators show builder status at a glance — active, waiting, or implementing","Use the `+ Shell` button to quickly open a new shell terminal tab","The SPIR protocol has four phases: Specify, Plan, Implement (IDE loop), and Review","Each implementation phase follows the IDE cycle: Implement, Defend (test), Evaluate","The EXPERIMENT protocol is for testing new approaches — use it for proof-of-concept work","The MAINTAIN protocol handles code hygiene and documentation sync","Run 3-way consultations at each SPIR checkpoint for spec, plan, and implementation reviews"];function Fg(I){const W=new Date(I.getFullYear(),0,0);return Math.floor((I.getTime()-W.getTime())/864e5)}function _f(I){const W=I.getFullYear(),$=String(I.getMonth()+1).padStart(2,"0"),O=String(I.getDate()).padStart(2,"0");return`tip-dismissed-${W}-${$}-${O}`}function jg(){try{return localStorage.getItem(_f(new Date))==="1"}catch{return!1}}function $g(){try{localStorage.setItem(_f(new Date),"1")}catch{}}function qg(I){return I.split("`").map(($,O)=>O%2===1?Q.jsx("code",{children:$},O):Q.jsx("span",{children:$},O))}function Wg(){const I=Fg(new Date)%er.length,[W,$]=ye.useState(I),[O,te]=ye.useState(jg);if(O||er.length===0)return null;const ne=()=>{$((W-1+er.length)%er.length)},j=()=>{$((W+1)%er.length)},n=()=>{$g(),te(!0)};return Q.jsxs("div",{className:"tip-banner",children:[Q.jsx("button",{className:"tip-banner-nav",onClick:ne,"aria-label":"Previous tip",children:"‹"}),Q.jsx("span",{className:"tip-banner-label",children:"Tip:"}),Q.jsx("span",{className:"tip-banner-text",children:qg(er[W])}),Q.jsx("button",{className:"tip-banner-nav",onClick:j,"aria-label":"Next tip",children:"›"}),Q.jsx("button",{className:"tip-banner-dismiss",onClick:n,"aria-label":"Dismiss tip",children:"×"})]})}function Gg({state:I,onRefresh:W,onSelectTab:$}){var _,a;const{data:O,error:te,refresh:ne}=Lg(),[j,n]=ye.useState(!1),u=ye.useCallback(async()=>{try{await Wv(),W()}catch(g){console.error("Failed to create shell:",g)}},[W]),f=ye.useCallback(g=>{var b;const y=(b=I==null?void 0:I.builders)==null?void 0:b.find(c=>{var r,h,l,o;return g.issueNumber?((r=c.name)==null?void 0:r.includes(String(g.issueNumber)))||((h=c.id)==null?void 0:h.includes(String(g.issueNumber))):((l=c.id)==null?void 0:l.includes(g.id))||((o=c.name)==null?void 0:o.includes(g.id))});y&&($==null||$(y.id))},[I==null?void 0:I.builders,$]);return I?Q.jsxs("div",{className:`work-view ${j?"file-panel-open":""}`,children:[Q.jsxs("div",{className:"work-content",children:[Q.jsxs("div",{className:"work-header",children:[Q.jsx("h2",{className:"work-title",children:"Work"}),Q.jsxs("div",{className:"work-actions",children:[Q.jsx("button",{className:"work-btn",onClick:u,children:"+ Shell"}),Q.jsx("button",{className:"work-btn work-btn-secondary",onClick:ne,children:"Refresh"})]})]}),te&&Q.jsxs("div",{className:"work-error",children:["Failed to load overview: ",te]}),Q.jsx(Wg,{}),Q.jsxs("section",{className:"work-section",children:[Q.jsx("h3",{className:"work-section-title",children:"Builders"}),O!=null&&O.builders&&O.builders.length>0?Q.jsxs("table",{className:"builder-table",children:[Q.jsx("thead",{children:Q.jsxs("tr",{children:[Q.jsx("th",{children:"Issue"}),Q.jsx("th",{children:"Title"}),Q.jsx("th",{children:"State"}),Q.jsx("th",{children:"Progress"}),Q.jsx("th",{children:"Elapsed"}),Q.jsx("th",{})]})}),Q.jsx("tbody",{children:O.builders.map(g=>Q.jsx(Ag,{builder:g,onOpen:f},g.id))})]}):Q.jsx("p",{className:"work-empty",children:"No active builders"})]}),Q.jsxs("section",{className:"work-section",children:[Q.jsx("h3",{className:"work-section-title",children:"Needs Attention"}),(_=O==null?void 0:O.errors)!=null&&_.prs?Q.jsx("p",{className:"work-unavailable",children:O.errors.prs}):Q.jsx(Tg,{prs:(O==null?void 0:O.pendingPRs)??[],builders:(O==null?void 0:O.builders)??[]})]}),Q.jsxs("section",{className:"work-section",children:[Q.jsx("h3",{className:"work-section-title",children:"Projects and Bugs"}),(a=O==null?void 0:O.errors)!=null&&a.issues?Q.jsx("p",{className:"work-unavailable",children:O.errors.issues}):Q.jsx(Hg,{items:(O==null?void 0:O.backlog)??[],onRefresh:W})]}),(O==null?void 0:O.recentlyClosed)&&O.recentlyClosed.length>0&&Q.jsxs("section",{className:"work-section",children:[Q.jsx("h3",{className:"work-section-title",children:"Recently Closed"}),Q.jsx(Ug,{items:O.recentlyClosed})]})]}),Q.jsxs("div",{className:`work-file-panel ${j?"expanded":"collapsed"}`,children:[Q.jsxs("div",{className:"work-file-panel-header",children:[Q.jsx("span",{className:"work-file-panel-toggle",onClick:()=>n(!j),children:j?"▼":"▲"}),Q.jsx("span",{className:"work-file-panel-label",onClick:()=>n(!j),children:"Files"}),!j&&Q.jsx("input",{className:"work-file-panel-search",type:"text",placeholder:"Search files...",onFocus:()=>n(!0)})]}),j&&Q.jsx("div",{className:"work-file-panel-content",children:Q.jsx(Pg,{onRefresh:W})})]})]}):Q.jsx("div",{className:"work-view",children:Q.jsx("p",{className:"work-loading",children:"Loading..."})})}function Xg({tabs:I,activeTabId:W,onSelectTab:$,onRefresh:O,children:te}){return Q.jsxs("div",{className:"mobile-layout",children:[Q.jsx(nf,{tabs:I,activeTabId:W,onSelectTab:$,onRefresh:O}),Q.jsx("div",{className:"mobile-content",children:te})]})}function Yg({tabId:I,initialLine:W}){let O=`${tf()}api/annotate/${I}/`;return W&&(O+=`?line=${W}`),Q.jsx("div",{className:"file-viewer",style:{width:"100%",height:"100%"},children:Q.jsx("iframe",{src:O,style:{width:"100%",height:"100%",border:"none"},title:"File Annotator"})})}function Vg(I,W){const $=I==null?void 0:I.trim(),O=W==null?void 0:W.trim();return $&&O&&$.toLowerCase()!==O.toLowerCase()?`${O} on ${$} overview`:O?`${O} overview`:"overview"}function Kg(){const{state:I,refresh:W}=Kv(),{tabs:$,activeTab:O,activeTabId:te,selectTab:ne}=Zv(I),j=rf(`(max-width: ${ef}px)`),[n,u]=ye.useState(new Set),f=ye.useRef(new Map),_=ye.useCallback(async(l,o,m,x)=>{try{const v=await Pl(l,o,x);o&&o>0&&f.current.set(v.id,o),W()}catch(v){console.error("Failed to open file:",v)}},[W]),a=Vg(I==null?void 0:I.hostname,I==null?void 0:I.workspaceName);ye.useEffect(()=>{document.title=a},[a]);const[g]=ye.useState(()=>new URLSearchParams(window.location.search).get("fullscreen")==="1");ye.useEffect(()=>{if(!O)return;(O.type==="architect"||O.type==="builder"||O.type==="shell")&&u(o=>{if(o.has(O.id))return o;const m=new Set(o);return m.add(O.id),m})},[O==null?void 0:O.id,O==null?void 0:O.type]);const y=l=>{const o=Xd(l);return o?Q.jsx(Jd,{wsPath:o,onFileOpen:_,persistent:l.persistent}):Q.jsx("div",{className:"no-terminal",children:"No terminal session"})},b=l=>{if(!l.annotationId||!I)return Q.jsx("div",{className:"no-terminal",children:"No file viewer"});if(!I.annotations.find(x=>x.id===l.annotationId))return Q.jsx("div",{className:"no-terminal",children:"Annotation not found"});const m=f.current.get(l.annotationId);return m!==void 0&&f.current.delete(l.annotationId),Q.jsx(Yg,{tabId:l.annotationId,initialLine:m??l.initialLine})},c=l=>{const o=$.filter(m=>l.includes(m.type)&&n.has(m.id));return Q.jsxs(Q.Fragment,{children:[o.map(m=>{const x=Xd(m);return Q.jsx("div",{className:"terminal-tab-pane",style:{display:te===m.id?void 0:"none"},children:x?Q.jsx(Jd,{wsPath:x,onFileOpen:_,persistent:m.persistent}):Q.jsx("div",{className:"no-terminal",children:"No terminal session"})},m.id)}),Q.jsx("div",{style:{display:(O==null?void 0:O.type)==="work"?void 0:"none"},children:Q.jsx(Gg,{state:I,onRefresh:W,onSelectTab:ne})}),(O==null?void 0:O.type)==="file"&&b(O)]})};if(g)return O&&(O.type==="architect"||O.type==="builder"||O.type==="shell")?Q.jsx("div",{className:"fullscreen-terminal",children:y(O)}):Q.jsx("div",{className:"fullscreen-terminal"});if(j)return Q.jsx("div",{className:"mobile-wrapper",children:Q.jsx(Xg,{tabs:$,activeTabId:te,onSelectTab:ne,onRefresh:W,children:c(["architect","builder","shell"])})});const r=$.find(l=>l.type==="architect"),h=r?y(r):Q.jsx("div",{className:"no-architect",children:"No architect terminal"});return Q.jsxs("div",{className:"app",children:[Q.jsxs("header",{className:"app-header",children:[Q.jsx("h1",{className:"app-title",children:a}),(I==null?void 0:I.version)&&Q.jsxs("span",{className:"header-version",children:["v",I.version]})]}),Q.jsx("div",{className:"app-body",children:Q.jsx(Jv,{left:h,right:Q.jsxs("div",{className:"right-panel",children:[Q.jsx(nf,{tabs:$.filter(l=>l.type!=="architect"),activeTabId:te,onSelectTab:ne,onRefresh:W}),Q.jsx("div",{className:"tab-content",role:"tabpanel",children:c(["builder","shell"])})]})})})]})}Iv.createRoot(document.getElementById("root")).render(Q.jsx(ye.StrictMode,{children:Q.jsx(Kg,{})}));
|
|
134
|
+
//# sourceMappingURL=index-mLspyEje.js.map
|