spexcode 0.2.8 → 0.4.0

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.
Files changed (101) hide show
  1. package/README.md +56 -44
  2. package/package.json +3 -3
  3. package/spec-cli/bin/spex.mjs +2 -2
  4. package/spec-cli/hooks/dispatch.sh +1 -1
  5. package/spec-cli/hooks/harness.sh +26 -6
  6. package/spec-cli/src/anchors.ts +300 -0
  7. package/spec-cli/src/attach.ts +2 -2
  8. package/spec-cli/src/cli.ts +691 -536
  9. package/spec-cli/src/client.ts +31 -30
  10. package/spec-cli/src/contract-filter.ts +1 -1
  11. package/spec-cli/src/doctor.ts +40 -13
  12. package/spec-cli/src/gateway.ts +11 -7
  13. package/spec-cli/src/git.ts +23 -15
  14. package/spec-cli/src/{board.ts → graph.ts} +44 -14
  15. package/spec-cli/src/{boardCache.ts → graphCache.ts} +41 -21
  16. package/spec-cli/src/{boardDelta.ts → graphDelta.ts} +1 -1
  17. package/spec-cli/src/graphStream.ts +288 -0
  18. package/spec-cli/src/guide.ts +142 -98
  19. package/spec-cli/src/harness-select.ts +2 -2
  20. package/spec-cli/src/harness.ts +30 -14
  21. package/spec-cli/src/help.ts +300 -385
  22. package/spec-cli/src/hooks.ts +1 -1
  23. package/spec-cli/src/index.ts +144 -103
  24. package/spec-cli/src/init.ts +14 -13
  25. package/spec-cli/src/issues.ts +89 -33
  26. package/spec-cli/src/layout.ts +5 -5
  27. package/spec-cli/src/lint.ts +128 -30
  28. package/spec-cli/src/localIssues.ts +61 -60
  29. package/spec-cli/src/materialize.ts +1 -1
  30. package/spec-cli/src/mentions.ts +15 -15
  31. package/spec-cli/src/migrate-table.ts +398 -0
  32. package/spec-cli/src/migrate.ts +386 -0
  33. package/spec-cli/src/ranker.ts +30 -4
  34. package/spec-cli/src/reaper.ts +117 -0
  35. package/spec-cli/src/search.bench.mjs +12 -12
  36. package/spec-cli/src/search.ts +1 -1
  37. package/spec-cli/src/sessions.ts +244 -138
  38. package/spec-cli/src/specs.ts +40 -25
  39. package/spec-cli/src/supervise.ts +2 -2
  40. package/spec-cli/src/tree.ts +5 -5
  41. package/spec-cli/src/uninstall.ts +4 -4
  42. package/spec-cli/templates/hooks/post-checkout +1 -1
  43. package/spec-cli/templates/hooks/post-merge +3 -3
  44. package/spec-cli/templates/hooks/pre-commit +9 -9
  45. package/spec-cli/templates/hooks/prepare-commit-msg +1 -1
  46. package/spec-cli/templates/spec/project/{.config → .plugins}/core/idle/idle.sh +2 -2
  47. package/spec-cli/templates/spec/project/{.config → .plugins}/core/mark-active/mark-active.sh +7 -0
  48. package/spec-cli/templates/spec/project/{.config → .plugins}/core/mark-active/spec.md +2 -0
  49. package/spec-cli/templates/spec/project/{.config → .plugins}/core/session-fail/fail.sh +1 -1
  50. package/spec-cli/templates/spec/project/{.config → .plugins}/core/spec-first/spec-first.sh +1 -1
  51. package/spec-cli/templates/spec/project/{.config → .plugins}/core/spec-of-file/spec-of-file.sh +2 -2
  52. package/spec-cli/templates/spec/project/.plugins/core/spec.md +21 -0
  53. package/spec-cli/templates/spec/project/{.config → .plugins}/core/stop-gate/stop-gate.sh +21 -21
  54. package/spec-cli/templates/spec/project/{.config → .plugins}/distill/spec.md +2 -2
  55. package/spec-cli/templates/spec/project/{.config → .plugins}/extract/spec.md +5 -5
  56. package/spec-cli/templates/spec/project/{.config → .plugins/prompts}/forge-link/spec.md +1 -1
  57. package/spec-cli/templates/spec/project/{.config → .plugins/prompts}/reproduce-before-fix/spec.md +3 -3
  58. package/spec-cli/templates/spec/project/.plugins/prompts/spec.md +20 -0
  59. package/spec-cli/templates/spec/project/{.config → .plugins}/regroup/spec.md +2 -2
  60. package/spec-cli/templates/spec/project/.plugins/spec.md +18 -0
  61. package/spec-cli/templates/spec/project/.plugins/supervisor/spec.md +8 -0
  62. package/spec-cli/templates/spec/project/{.config → .plugins}/tidy/spec.md +1 -1
  63. package/spec-cli/templates/spec/project/spec.md +1 -1
  64. package/spec-dashboard/dist/assets/{Dashboard-P0B9ukSG.js → Dashboard-CTcH2eW9.js} +9 -9
  65. package/spec-dashboard/dist/assets/EvalsPage-CJNKwHLN.js +2 -0
  66. package/spec-dashboard/dist/assets/{FoldToggle-BuQ0lokE.js → FoldToggle-CVFbBpyW.js} +1 -1
  67. package/spec-dashboard/dist/assets/{IssuesPage-H-D8aHEl.js → IssuesPage-kULjonqj.js} +1 -1
  68. package/spec-dashboard/dist/assets/{MobileApp-oZXIeCPb.js → MobileApp-B0ZJju8K.js} +1 -1
  69. package/spec-dashboard/dist/assets/{SessionInterface-Blr_MEdU.js → SessionInterface-BRKJqU2U.js} +3 -3
  70. package/spec-dashboard/dist/assets/{SessionWindow-LcCzBMU7.js → SessionWindow-CDhEL7wO.js} +7 -7
  71. package/spec-dashboard/dist/assets/{Settings-_yOye-In.js → Settings-BL6FV_8S.js} +1 -1
  72. package/spec-dashboard/dist/assets/{index-uGs9v_9o.css → index-DmQsNYKK.css} +1 -1
  73. package/spec-dashboard/dist/assets/{index-BhIslAau.js → index-DulGPk6A.js} +8 -8
  74. package/spec-dashboard/dist/index.html +2 -2
  75. package/{spec-yatsu → spec-eval}/src/cache.ts +8 -5
  76. package/{spec-yatsu → spec-eval}/src/cli.ts +212 -96
  77. package/{spec-yatsu → spec-eval}/src/evaltab.ts +35 -27
  78. package/{spec-yatsu → spec-eval}/src/filing.ts +7 -5
  79. package/{spec-yatsu → spec-eval}/src/freshness.ts +44 -22
  80. package/spec-eval/src/humanok.ts +43 -0
  81. package/{spec-yatsu → spec-eval}/src/scenariofresh.ts +22 -17
  82. package/{spec-yatsu/src/yatsu.ts → spec-eval/src/scenarios.ts} +41 -26
  83. package/{spec-yatsu/src/proof.ts → spec-eval/src/sessioneval.ts} +59 -59
  84. package/{spec-yatsu → spec-eval}/src/sidecar.ts +42 -10
  85. package/{spec-yatsu → spec-eval}/src/timeline.ts +1 -1
  86. package/spec-forge/src/__fixtures__/github-forge.json +9 -9
  87. package/spec-forge/src/cli.ts +14 -13
  88. package/spec-forge/src/{needs-yatsu-eval.ts → needs-eval.ts} +6 -6
  89. package/spec-cli/src/boardStream.ts +0 -179
  90. package/spec-cli/templates/presets/careful/.config/clarify-before-code/spec.md +0 -11
  91. package/spec-cli/templates/spec/project/.config/core/spec.md +0 -17
  92. package/spec-cli/templates/spec/project/.config/spec.md +0 -15
  93. package/spec-cli/templates/spec/project/.config/supervisor/spec.md +0 -8
  94. package/spec-dashboard/dist/assets/EvalsPage-BrvAGyc4.js +0 -2
  95. /package/spec-cli/templates/spec/project/{.config → .plugins}/core/idle/spec.md +0 -0
  96. /package/spec-cli/templates/spec/project/{.config → .plugins}/core/session-fail/spec.md +0 -0
  97. /package/spec-cli/templates/spec/project/{.config → .plugins}/core/spec-first/spec.md +0 -0
  98. /package/spec-cli/templates/spec/project/{.config → .plugins}/core/spec-of-file/spec.md +0 -0
  99. /package/spec-cli/templates/spec/project/{.config → .plugins}/core/stop-gate/spec.md +0 -0
  100. /package/spec-cli/templates/spec/project/{.config → .plugins}/distill/digest.mjs +0 -0
  101. /package/spec-cli/templates/spec/project/{.config → .plugins/prompts}/memory-hygiene/spec.md +0 -0
@@ -0,0 +1,2 @@
1
+ import{u as xe,r as a,s as Ze,e as Je,j as n,f as Ve,h as Qe}from"./index-DulGPk6A.js";import{V as We,W as et,X as tt,Y as nt,Z as st,g as he,n as at,_ as ee,$ as lt,a0 as Pe,a1 as ot,a2 as it,u as rt,z as me,a3 as ct,o as ut,a4 as dt}from"./SessionWindow-CDhEL7wO.js";import{F as ve}from"./FoldToggle-CVFbBpyW.js";const Oe=(l,d)=>{let c=null;for(const v of l)if(v.at<=d)c=v;else break;return c},ft=l=>{if(!l||!Array.isArray(l.events))return null;const d=l.v===1?"time":typeof l.axis=="string"?l.axis:"time",c=l.v===1?v=>v.tMs:v=>v.at;return{axis:d,events:l.events.map(v=>({at:c(v),step:v.step,...v.node?{node:v.node}:{}}))}},ht=(l,d,c)=>l==="time"?ee(d):l==="frame"?`#${d}`:l==="line"?`L${d}`:l==="index"?c?`${d}/${c}`:`${d}`:String(d);function Fe({events:l,axis:d,extent:c,activeStepIdx:v,onSeek:S}){return n.jsx("div",{className:"an-ruler",children:l.map((i,h)=>n.jsxs("button",{className:`an-step ${v===h?"on":""}`,onClick:()=>S(i.at),"data-tip":i.node?`→ ${i.node}`:void 0,children:[ht(d,i.at,c)," ",i.step]},h))})}const pe=l=>{var d,c;return((d=l.verdict)==null?void 0:d.status)==="pass"?"✓":((c=l.verdict)==null?void 0:c.status)==="fail"?"✗":"·"},Ke=l=>{var d,c;return((d=l.verdict)==null?void 0:d.status)==="pass"?"pass":((c=l.verdict)==null?void 0:c.status)==="fail"?"fail":"legacy"};function mt({entry:l,specs:d=[],sessions:c=[],onWrite:v,onOpenSession:S}){var Le,Te,Ce,De,Ae,Ie;const i=xe(),h=a.useRef(null),x=a.useRef(null),w=a.useRef(null),j=a.useRef(null),g=a.useRef(0),[f,M]=a.useState([]),[b,k]=a.useState("time"),[r,y]=a.useState(null),[$,D]=a.useState(""),[A,U]=a.useState(!1),[te,K]=a.useState(null),P=a.useRef(null),I=a.useRef(null),u=a.useRef(null),L=a.useRef(0),[ne,ge]=a.useState(0),[se,ke]=a.useState(-1),[ye,be]=a.useState(null),[_,ae]=a.useState(!1),[we,le]=a.useState(!1),[oe,ie]=a.useState(null),[q,re]=a.useState(null),[N,je]=a.useState(null),[T,Y]=a.useState(0),p=N&&N[T]||l;a.useEffect(()=>{y(null),D(""),M([]),K(null),Y(0),je(null);let e=!0;return fetch(Ze(l.node,"evals")).then(t=>t.ok?t.json():null).then(t=>{e&&Array.isArray(t==null?void 0:t.readings)&&je(t.readings.filter(s=>s.scenario===l.scenario))}).catch(()=>{}),()=>{e=!1}},[l.node,l.scenario,l.ts,l.blob,(Le=l.humanOk)==null?void 0:Le.ts]),a.useEffect(()=>{y(null),K(null)},[T]);const B=We(p),O=B.find(e=>e.kind==="video"&&e.state==="present"),ce=B.filter(e=>e.kind==="image"),ze=B.filter(e=>e.kind!=="video"&&e.kind!=="image"),V=!!O,X=l.thread??null,ue=a.useMemo(()=>X?[{by:X.by,at:X.created,body:X.body},...X.replies||[]]:[],[X]),Ue=N&&((Te=N[0])==null?void 0:Te.by)||l.by||null,R=a.useMemo(()=>ue.map((e,t)=>{const s=et(tt(e.body),f);return s&&s.seekable?{i:t,tMs:s.tMs,step:s.step,label:s.label}:null}).filter(Boolean).sort((e,t)=>e.tMs-t.tMs),[ue,f]),Me=a.useRef(f);Me.current=f;const Ne=a.useRef(R);Ne.current=R;const G=a.useCallback(()=>{const e=L.current,t=Me.current;let s=-1;for(let m=0;m<t.length&&t[m].at<=e;m++)s=m;ke(m=>m===s?m:s);let o=null;for(const m of Ne.current)if(m.tMs<=e)o=m.i;else break;be(m=>m===o?m:o)},[]);a.useEffect(()=>{G()},[R,f,G]),a.useEffect(()=>{L.current=0,P.current&&(P.current.style.width="0%"),I.current&&(I.current.style.left="0%"),u.current&&(u.current.textContent=""),ke(-1),be(null),ge(0),ae(!1),le(!1),ie(null),re(null)},[l.blob,l.scenario,l.node]),a.useEffect(()=>{if(M([]),k("time"),!p.timelineBlob)return;let e=!0;return fetch(`/api/evidence/${p.timelineBlob}`).then(t=>t.ok?t.json():null).then(t=>{const s=e&&ft(t);s&&(M(s.events),k(s.axis))}).catch(()=>{}),()=>{e=!1}},[p.timelineBlob]),a.useEffect(()=>{const e=h.current;if(!e)return;const t=()=>{const E=Math.round((e.currentTime||0)*1e3),C=Math.round((e.duration||0)*1e3);L.current=E;const W=C?E/C*100:0;P.current&&(P.current.style.width=`${W}%`),I.current&&(I.current.style.left=`${W}%`),u.current&&(u.current.textContent=`${ee(E)} / ${ee(C)}`),G()},s=()=>{ge(e.duration||0),t()},o=()=>ae(!0),m=()=>ae(!1);return e.addEventListener("timeupdate",t),e.addEventListener("seeked",t),e.addEventListener("loadedmetadata",s),e.addEventListener("durationchange",s),e.addEventListener("play",o),e.addEventListener("pause",m),s(),()=>{e.removeEventListener("timeupdate",t),e.removeEventListener("seeked",t),e.removeEventListener("loadedmetadata",s),e.removeEventListener("durationchange",s),e.removeEventListener("play",o),e.removeEventListener("pause",m)}},[O==null?void 0:O.hash,l.node,l.scenario,T,G]);const F=Math.round(ne*1e3),Z=f[se]||null,Ee=b==="time"?F:b==="frame"?ce.length:b==="index"?f.length:0,z=a.useCallback(e=>{const t=h.current;t&&(t.currentTime=e/1e3)},[]),J=a.useCallback(()=>{const e=h.current;e&&(e.paused?e.play():e.pause())},[]),Se=(e,t)=>{re(e),t!=null&&z(t)},Q=a.useCallback(async e=>{const t=h.current;if(!(t!=null&&t.videoWidth))return null;U(!0),D(i("annotator.capturing"));try{t.seeking&&await new Promise(C=>t.addEventListener("seeked",C,{once:!0}));const s=document.createElement("canvas");s.width=t.videoWidth,s.height=t.videoHeight;const o=s.getContext("2d");o.drawImage(t,0,0,s.width,s.height),e&&(o.strokeStyle="#ff9a3c",o.lineWidth=Math.max(2,s.width/300),o.strokeRect(e.x/100*s.width,e.y/100*s.height,e.w/100*s.width,e.h/100*s.height));const m=await new Promise(C=>s.toBlob(C,"image/png")),{hash:E}=await Je(m);if(!E)throw new Error("no hash");return D(""),E}catch{return D(i("annotator.failed")),null}finally{U(!1)}},[i]),Be=a.useCallback(async()=>{var s;const e=h.current;if(!e)return null;e.pause();const t=Math.round((e.currentTime??0)*1e3);return{tMs:t,step:((s=Oe(f,t))==null?void 0:s.step)??null,frame:await Q(null)}},[f,Q]),de=a.useCallback(async e=>{const t=h.current;if(!t)return;t.pause();const s=Math.round((t.currentTime||0)*1e3),o=Oe(f,s),m=await Q(e),E=[nt(s,o==null?void 0:o.step)];m&&E.push(`![frame](/api/evidence/${m})`),o!=null&&o.node&&o.node!==l.node&&E.push(`re: [[${o.node}]]`),E.push(""),K({seq:++g.current,body:E.join(`
2
+ `)})},[f,l.node,Q]),fe=a.useCallback(e=>{var o;if(!R.length)return;let t=R.findIndex(m=>m.i===q);if(t<0){const m=Math.round((((o=h.current)==null?void 0:o.currentTime)||0)*1e3);t=R.reduce((E,C,W)=>C.tMs<=m?W:E,-1)}t=Math.min(R.length-1,Math.max(0,t+e));const s=R[t];re(s.i),z(s.tMs)},[R,q,z]);a.useEffect(()=>{if(!V)return;const e=t=>{const s=document.activeElement;if(s&&(s.tagName==="INPUT"||s.tagName==="TEXTAREA"||s.tagName==="SELECT"||s.isContentEditable))return;const o=h.current;o&&(t.key===" "?(t.preventDefault(),J()):t.key==="ArrowRight"?(t.preventDefault(),o.currentTime=Math.min(o.duration||o.currentTime,o.currentTime+(t.shiftKey?1:5))):t.key==="ArrowLeft"?(t.preventDefault(),o.currentTime=Math.max(0,o.currentTime-(t.shiftKey?1:5))):t.key===","?(t.preventDefault(),o.currentTime=Math.max(0,o.currentTime-1/30)):t.key==="."?(t.preventDefault(),o.duration&&(o.currentTime=Math.min(o.duration,o.currentTime+1/30))):t.key==="ArrowDown"?(t.preventDefault(),fe(1)):t.key==="ArrowUp"?(t.preventDefault(),fe(-1)):(t.key==="a"||t.key==="A")&&(t.preventDefault(),de(null)))};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[V,J,fe,de]);const $e=e=>{var o;const t=(o=w.current)==null?void 0:o.getBoundingClientRect(),s=h.current;!t||!t.width||!s||!s.duration||(s.currentTime=Math.min(1,Math.max(0,(e-t.left)/t.width))*s.duration)},He=e=>{e.preventDefault(),le(!0),$e(e.clientX)},_e=e=>{var s;const t=(s=w.current)==null?void 0:s.getBoundingClientRect();t!=null&&t.width&&ie(Math.min(100,Math.max(0,(e.clientX-t.left)/t.width*100)))};a.useEffect(()=>{if(!we)return;const e=s=>$e(s.clientX),t=()=>le(!1);return window.addEventListener("mousemove",e),window.addEventListener("mouseup",t),()=>{window.removeEventListener("mousemove",e),window.removeEventListener("mouseup",t)}},[we]);const Re=e=>{const t=x.current.getBoundingClientRect();return{x:(e.clientX-t.left)/t.width*100,y:(e.clientY-t.top)/t.height*100}},qe=e=>{if(e.button!==0||A)return;const t=Re(e);y({x0:t.x,y0:t.y,x:t.x,y:t.y})},Ye=e=>{var s,o;if(!r)return;const t=Re(e);!((s=h.current)!=null&&s.paused)&&(Math.abs(t.x-r.x0)>1||Math.abs(t.y-r.y0)>1)&&((o=h.current)==null||o.pause()),y({...r,x:t.x,y:t.y})},Ge=()=>{if(!r)return;const e={x:Math.min(r.x0,r.x),y:Math.min(r.y0,r.y),w:Math.abs(r.x-r.x0),h:Math.abs(r.y-r.y0)};if(y(null),e.w<1&&e.h<1){J();return}de(e)},H=r&&{x:Math.min(r.x0,r.x),y:Math.min(r.y0,r.y),w:Math.abs(r.x-r.x0),h:Math.abs(r.y-r.y0)};return n.jsxs("div",{className:"an-detail",children:[n.jsxs("header",{className:"an-head",children:[n.jsx("span",{className:"an-title",children:l.scenario}),n.jsx("span",{className:"an-node",children:l.node}),n.jsx("span",{className:`an-verdict-badge ${Ke(p)}`,children:pe(p)}),p.evaluator&&n.jsx("span",{className:"an-meta",children:p.evaluator}),n.jsx("span",{className:"an-meta",children:new Date(p.ts).toLocaleString()}),n.jsx(st,{originator:Ue,sessions:c,kind:"eval",onOpenSession:S}),p.humanOk?n.jsxs("span",{className:"an-okd","data-tip":i("annotator.okBy",{by:p.humanOk.by,at:new Date(p.humanOk.ts).toLocaleString()}),children:["☑ ",i("annotator.okd")]}):(!N||T===0)&&n.jsxs("button",{type:"button",className:"an-okbtn","data-tip":i("annotator.okTitle"),onClick:async()=>{const e=await Ve(l.node,l.scenario).catch(t=>({error:String(t)}));v==null||v((e==null?void 0:e.error)||"")},children:["☑ ",i("annotator.ok")]}),N&&N.length>1&&n.jsxs("div",{className:"an-ab",children:[n.jsx(he,{icon:"chevron-left",size:13,className:"an-ab-nav",disabled:T>=N.length-1,onClick:()=>Y(e=>Math.min(N.length-1,e+1)),label:i("annotator.abOlder")}),n.jsx("div",{className:"an-ab-track",children:N.slice().reverse().map((e,t)=>{const s=N.length-1-t;return n.jsx("button",{type:"button",className:`an-ab-pip ${Ke(e)} ${s===T?"on":""}`,onClick:()=>Y(s),"data-tip":`${pe(e)} ${new Date(e.ts).toLocaleString()}`,children:pe(e)},`${e.ts}-${s}`)})}),n.jsx(he,{icon:"chevron-right",size:13,className:"an-ab-nav",disabled:T<=0,onClick:()=>Y(e=>Math.max(0,e-1)),label:i("annotator.abNewer")}),n.jsx("span",{className:"an-ab-pos",children:T===0?i("annotator.abLatest"):i("annotator.abPos",{i:N.length-T,n:N.length})})]})]}),n.jsxs("div",{className:"an-work",children:[n.jsxs("div",{className:"an-stage-col",children:[p.expected&&n.jsxs("div",{className:"an-expected",children:[n.jsx("b",{children:i("nodeView.eval.expected")})," ",p.expected]}),B.length>0&&((Ce=p.verdict)==null?void 0:Ce.note)&&n.jsxs("div",{className:"an-expected an-prior-note",children:[n.jsx("b",{children:i("nodeView.eval.noteLabel")})," ",p.verdict.note]}),!p.fresh&&(((De=p.staleAxes)==null?void 0:De.length)??0)>0&&n.jsxs("div",{className:"an-expected an-stale","data-tip":i("nodeView.eval.staleReadoutTitle"),children:[n.jsx("b",{children:i("nodeView.eval.staleLabel")})," ",p.staleAxes.join(" · "),(((Ae=p.codeDrift)==null?void 0:Ae.length)??0)>0&&n.jsxs("span",{className:"an-stale-files",children:[" — ",p.codeDrift.map(e=>`${e.file.split("/").pop()} +${e.behind}`).join(", ")]})]}),O&&n.jsxs(n.Fragment,{children:[n.jsxs("div",{className:"an-player",ref:j,children:[n.jsxs("div",{className:`an-stage ${_?"playing":"paused"}`,ref:x,onMouseDown:qe,onMouseMove:Ye,onMouseUp:Ge,children:[n.jsx("video",{className:"an-video",ref:h,src:`/api/evidence/${O.hash}`,preload:"metadata",playsInline:!0}),H&&n.jsx("div",{className:"an-rect live",style:{left:`${H.x}%`,top:`${H.y}%`,width:`${H.w}%`,height:`${H.h}%`}}),!_&&!r&&n.jsx("div",{className:"an-bigplay","aria-hidden":!0,children:n.jsx(at,{name:"play",size:22})})]}),n.jsxs("div",{className:"an-bar",children:[n.jsx(he,{icon:_?"pause":"play",size:14,className:"an-play",label:i(_?"annotator.pause":"annotator.play"),onClick:J}),n.jsxs("div",{className:"an-seek",ref:w,onMouseDown:He,onMouseMove:_e,onMouseLeave:()=>ie(null),children:[n.jsx("div",{className:"an-seek-trk"}),F>0&&b==="time"&&f.map((e,t)=>n.jsx("div",{className:"an-band",style:{left:`${e.at/F*100}%`},"data-tip":e.step},`band-${t}`)),n.jsx("div",{className:"an-seek-play",ref:P}),F>0&&R.map(e=>n.jsx("button",{type:"button",className:`an-mk ${q===e.i?"on":""} ${ye===e.i?"active":""}`,style:{left:`${e.tMs/F*100}%`},"data-tip":e.label,onMouseDown:t=>t.stopPropagation(),onClick:t=>{t.stopPropagation(),Se(e.i,e.tMs)}},`mk-${e.i}`)),n.jsx("div",{className:"an-knob",ref:I}),oe!=null&&F>0&&n.jsx("div",{className:"an-seek-hov",style:{left:`${oe}%`},children:ee(oe/100*F)})]}),n.jsx("span",{className:"an-time",ref:u}),Z&&n.jsx("span",{className:"an-curstep","data-tip":Z.node?`→ ${Z.node}`:void 0,children:Z.step}),n.jsx(lt,{target:j})]})]}),f.length>0&&n.jsx(Fe,{events:f,axis:b,extent:Ee,activeStepIdx:se,onSeek:z}),n.jsx("div",{className:"an-hint",children:i("annotator.hint")}),n.jsx("div",{className:"an-keys",children:i("annotator.keys")}),$&&n.jsx("div",{className:"an-flash",children:$})]}),!O&&f.length>0&&n.jsx(Fe,{events:f,axis:b,extent:Ee,activeStepIdx:se,onSeek:z}),ce.length>0&&n.jsx("div",{className:"an-gallery",children:ce.map((e,t)=>n.jsx(Pe,{e,alt:l.scenario},`${e.hash}-${t}`))}),ze.map((e,t)=>n.jsx(Pe,{e,alt:l.scenario},`${e.hash}-${t}`)),B.length===0&&((Ie=p.verdict)!=null&&Ie.note?n.jsx("pre",{className:"eval-transcript",children:p.verdict.note}):n.jsx("div",{className:"an-hint",children:i("nodeView.eval.noImage")}))]}),n.jsx(vt,{entry:l,comments:ue,specs:d,sessions:c,onWrite:v,codeSha:p.codeSha,seekMs:V?z:null,anchorNow:V?Be:null,draft:te,selIdx:q,activeIdx:ye,onSelect:V?Se:null,events:V?f:null})]})]})}function vt({entry:l,comments:d,codeSha:c,specs:v,sessions:S,onWrite:i,seekMs:h,anchorNow:x,draft:w,selIdx:j,activeIdx:g,onSelect:f,events:M}){var r;const b=xe(),k=(y,$)=>Qe({node:l.node,scenario:l.scenario,body:y,codeSha:c,evidence:$});return n.jsxs("aside",{className:"an-rail",children:[n.jsx("div",{className:"an-comments-head",children:b("annotator.comments",{n:d.length})}),n.jsx("div",{className:"an-rail-list",children:n.jsx(ot,{replies:d,onSeek:h,selIdx:j,activeIdx:g,onSelect:f,events:M,threadId:((r=l.thread)==null?void 0:r.id)??null,onRemarkChange:()=>i==null?void 0:i("")})}),n.jsx("div",{className:"an-rail-compose",children:n.jsx(it,{onSend:k,specs:v,sessions:S,focusId:l.node,onDone:i,anchorNow:x,draft:w},`${l.node}·${l.scenario}`)})]})}function Xe({rowKeys:l,sel:d,onSel:c,detail:v,children:S}){const[i,h]=a.useState(!1),x=a.useRef({});x.current={rowKeys:l,sel:d},a.useEffect(()=>{const j=g=>{var y;const f=(y=g.target)==null?void 0:y.tagName;if(f==="INPUT"||f==="TEXTAREA"||g.metaKey||g.ctrlKey||g.altKey||g.key!=="j"&&g.key!=="k")return;g.preventDefault(),g.stopPropagation();const{rowKeys:M,sel:b}=x.current;if(!M.length)return;const k=M.indexOf(b),r=k<0?g.key==="j"?0:M.length-1:Math.max(0,Math.min(M.length-1,k+(g.key==="j"?1:-1)));c(M[r])};return window.addEventListener("keydown",j,!0),()=>window.removeEventListener("keydown",j,!0)},[c]),a.useEffect(()=>{var j;(j=document.querySelector(".fv-list-col .sel"))==null||j.scrollIntoView({block:"nearest"})},[d]);const w=n.jsx(ve,{className:"fv-fold-inline",onToggle:()=>h(!0)});return n.jsxs("div",{className:`fv-master ${i?"folded":""}`,children:[i&&n.jsx(ve,{className:"fv-unfold",folded:!0,onToggle:()=>h(!1)}),n.jsx("div",{className:"fv-list-col",style:i?{display:"none"}:void 0,children:typeof S=="function"?S(w):n.jsxs(n.Fragment,{children:[n.jsx(ve,{className:"fv-fold",onToggle:()=>h(!0)}),S]})}),n.jsx("div",{className:"fv-detail",children:v})]})}function pt({specs:l=[],sessions:d=[],reloadBoard:c,onOpenSession:v}){const S=xe(),{page:i,param:h}=rt(),[x,w]=a.useState(null),[j,g]=a.useState(""),[f,M]=a.useState([]),b=a.useRef([]),k=a.useMemo(()=>new Map(f.map(u=>[me(u),u])),[f]);b.current=f.map(me);const r=x&&k.has(x)?x:b.current[0]??null,y=a.useMemo(()=>{if(!h)return null;const u=h.indexOf("/");return u>0?`eval:${h.slice(0,u)}·${h.slice(u+1)}`:null},[h]),[$,D]=a.useState(null);a.useEffect(()=>{i==="evals"&&y&&(w(y),D(y))},[i,y]),a.useEffect(()=>{$&&k.has($)&&D(null)},[$,k]);const A=x&&!k.has(x),U=a.useMemo(()=>!A||ct(l).some(u=>me(u)===x),[A,l,x]);a.useEffect(()=>{A&&!U&&(w(null),D(null))},[A,U]),a.useEffect(()=>{x&&!$&&f.length&&!k.has(x)&&w(null)},[x,$,f,k]),a.useEffect(()=>{if(i!=="evals"||!r||A)return;const u=/^eval:([^·]+)·(.+)$/.exec(r);u&&ut("evals",`${u[1]}/${u[2]}`,{replace:!0})},[i,r,A]);const te=a.useCallback(u=>M(u),[]),K=u=>{u&&(g(u),setTimeout(()=>g(""),6e3))},P=a.useCallback(async u=>{const L=await Ve(u.node,u.scenario).catch(ne=>({error:String(ne)}));K((L==null?void 0:L.error)||""),await(c==null?void 0:c())},[c]),I=r?k.get(r):null;return n.jsx(Xe,{rowKeys:b.current,sel:r,onSel:w,detail:I?n.jsx(mt,{entry:I,specs:l,sessions:d,onOpenSession:v,onWrite:async u=>{K(u),await(c==null?void 0:c())}}):n.jsx("div",{className:"fv-note",children:S("evalsFeed.empty")}),children:u=>n.jsxs(n.Fragment,{children:[j&&n.jsx("div",{className:"fv-notice",children:j}),n.jsx(dt,{nodes:l,sessions:d,sel:r,onSel:L=>w(L),onRows:te,onOk:P,mustShow:$,lead:u})]})})}const yt=Object.freeze(Object.defineProperty({__proto__:null,EvalMasterDetail:Xe,default:pt},Symbol.toStringTag,{value:"Module"}));export{mt as E,Xe as a,yt as b};
@@ -1 +1 @@
1
- import{u as l,j as t}from"./index-BhIslAau.js";import{n as a}from"./SessionWindow-LcCzBMU7.js";function r(){return t.jsx(a,{name:"panel-left",className:"fold-toggle-icon"})}function m({className:n,folded:e,onToggle:s}){const o=l()(e?"masterList.unfold":"masterList.fold");return t.jsx("button",{type:"button",className:n,"data-tip":o,"aria-label":o,onClick:s,children:t.jsx(r,{})})}export{m as F};
1
+ import{u as l,j as t}from"./index-DulGPk6A.js";import{n as a}from"./SessionWindow-CDhEL7wO.js";function r(){return t.jsx(a,{name:"panel-left",className:"fold-toggle-icon"})}function m({className:n,folded:e,onToggle:s}){const o=l()(e?"masterList.unfold":"masterList.fold");return t.jsx("button",{type:"button",className:n,"data-tip":o,"aria-label":o,onClick:s,children:t.jsx(r,{})})}export{m as F};
@@ -1 +1 @@
1
- import{u as D,r as a,j as s,h as Y,i as W,k as ss,m as es}from"./index-BhIslAau.js";import{a5 as Z,a6 as ts,g as ns,Z as ls,a7 as as,a1 as os,a2 as is,a8 as cs}from"./SessionWindow-LcCzBMU7.js";import{F as _}from"./FoldToggle-BuQ0lokE.js";import{u as rs,M as ds}from"./Dashboard-P0B9ukSG.js";function js({onFocusNode:t,onOpenSession:k,specs:v=[],sessions:x=[],issuesData:w=null,reloadIssues:o,issueId:d=null}){const i=D(),c=w,[h,p]=a.useState(!1),[j,m]=a.useState(!1),[b,S]=a.useState(!1),[g,N]=a.useState(!1),[l,y]=a.useState("all"),[f,n]=a.useState(""),[u,L]=a.useState(null),T=a.useRef([]),G=a.useCallback(()=>o==null?void 0:o(!0),[o]),V=e=>{e&&(n(e),setTimeout(()=>n(""),6e3))},C=Array.isArray(c==null?void 0:c.issues)?c.issues:[],P=e=>e.status!=="open",B=[...new Set(C.map(e=>e.store).filter(Boolean))],J=Array.isArray(c==null?void 0:c.stores)&&c.stores.length?c.stores:[{id:"local",label:"local",kind:"local"}];a.useEffect(()=>{if(!d||!C.length)return;const e=C.find(r=>r.id===d);e&&(l!=="all"&&e.store!==l&&y("all"),P(e)&&S(!0),M(e)||N(!1),L(`issue:${e.id}`))},[d,C,l]);const K=l==="all"?C:C.filter(e=>e.store===l),M=e=>!!Z(x,e.by)||Array.isArray(e.replies)&&e.replies.some(r=>Z(x,r.by)),I=b?K:K.filter(e=>!P(e)),E=g?I.filter(M):I,F=I.filter(M).length,O=K.filter(P).length,H=a.useMemo(()=>new Map(E.map(e=>[`issue:${e.id}`,e])),[E]);T.current=E.map(e=>`issue:${e.id}`);const A=u&&H.has(u)?u:T.current[0]??null,U=a.useRef({});if(U.current={effSel:A},rs(h,()=>p(!1)),a.useEffect(()=>{const e=r=>{var X;const R=(X=r.target)==null?void 0:X.tagName;if(R==="INPUT"||R==="TEXTAREA"||r.metaKey||r.ctrlKey||r.altKey||r.key!=="j"&&r.key!=="k")return;r.preventDefault(),r.stopPropagation();const $=T.current;if(!$.length)return;const z=$.indexOf(U.current.effSel),Q=z<0?r.key==="j"?0:$.length-1:Math.max(0,Math.min($.length-1,z+(r.key==="j"?1:-1)));L($[Q])};return window.addEventListener("keydown",e,!0),()=>window.removeEventListener("keydown",e,!0)},[]),a.useEffect(()=>{var e;(e=document.querySelector(".fv-list-col .sel"))==null||e.scrollIntoView({block:"nearest"})},[A]),c==null)return s.jsx("div",{className:"fv-note",children:i("session.issuesLoading")});if(!c.enabled)return s.jsx("div",{className:"fv-note",children:i("session.issuesOff")});const q=A?H.get(A):null;return s.jsxs("div",{className:`fv-master ${j?"folded":""}`,children:[j&&s.jsx(_,{className:"fv-unfold",folded:!0,onToggle:()=>m(!1)}),s.jsxs("div",{className:"fv-list-col",style:j?{display:"none"}:void 0,children:[f&&s.jsx("div",{className:"fv-notice",children:f}),s.jsxs("section",{className:"fv-group",children:[s.jsxs("header",{className:"fv-group-head",children:[s.jsxs("span",{className:"fv-head-row",children:[s.jsx(_,{className:"fv-fold-inline",onToggle:()=>m(!0)}),B.length>1&&s.jsx(ts,{value:l,onChange:y,options:[{value:"all",label:i("session.issuesStoreAll")},...B.map(e=>({value:e,label:e}))]}),s.jsx(ns,{icon:"plus",size:12,className:"fv-new-btn",label:i("session.issuesNew"),onClick:()=>p(!0)})]}),(g||F>0||O>0)&&s.jsxs("span",{className:"ef-chipbar",children:[(g||F>0)&&s.jsx("button",{type:"button",className:`ef-chip fv-live ${g?"on":""}`,onClick:()=>N(e=>!e),"data-tip":i("masterList.liveChipTitle"),children:i("masterList.liveChip",{n:F})}),O>0&&s.jsx("button",{type:"button",className:`ef-chip fv-concluded ${b?"on":""}`,onClick:()=>S(e=>!e),children:i("nodeView.closedIssues",{n:O})})]})]}),!E.length&&s.jsx("div",{className:"fv-note",children:i("session.issuesEmpty")}),E.map(e=>{var R;const r=`issue:${e.id}`;return s.jsxs("button",{className:`fv-row ${A===r?"sel":""}`,onClick:()=>L(r),children:[s.jsx("span",{className:`fv-dot st-${e.status||"open"}`,"data-tip":e.status}),s.jsx("span",{className:"fv-concern","data-tip":e.concern,children:e.concern}),(((R=e.replies)==null?void 0:R.length)??0)>0&&s.jsx("span",{className:"fv-replies","data-tip":i("session.issuesReplies",{n:e.replies.length}),children:e.replies.length}),B.length>1&&s.jsx("span",{className:`fv-store fv-store-${e.store==="local"?"local":"forge"}`,children:e.store})]},e.id)})]})]}),s.jsx("div",{className:"fv-detail",children:q?s.jsx(us,{issue:q,specs:v,sessions:x,onFocusNode:t,onOpenSession:k,onWrite:async e=>{V(e),await G()}}):s.jsx("div",{className:"fv-note",children:i("session.issuesEmpty")})}),h&&s.jsx(ds,{title:i("session.issuesNew"),closeLabel:i("common.close"),onClose:()=>p(!1),className:"fv-new-modal",children:s.jsx(ms,{specs:v,sessions:x,stores:J,onCancel:()=>p(!1),onDone:async e=>{p(!1),V(e),await G()}})})]})}function us({issue:t,specs:k,sessions:v,onFocusNode:x,onOpenSession:w,onWrite:o}){const d=D(),i=t.store==="local",c=t.status!=="open",[h,p]=a.useState(""),[j,m]=a.useState(""),b=Array.isArray(t.nodes)?t.nodes:[],S=Array.isArray(t.replies)?t.replies:[],g=(l,y)=>async()=>{if(!h){p(l);try{const f=await y();f!=null&&f.ok?(m(""),await(o==null?void 0:o(""))):m((f==null?void 0:f.error)||`${l} failed`)}finally{p("")}}},N=(l,y,f,n)=>s.jsx("button",{type:"button",className:`fv-close-issue fv-life-${l}`,disabled:!!h,"data-tip":n,onMouseDown:u=>u.preventDefault(),onClick:g(l,f),children:h===l?d("session.issuesActing"):y});return s.jsxs("div",{className:"fvd",children:[s.jsxs("div",{className:"fvd-scroll",children:[s.jsx("header",{className:"fvd-head",children:s.jsx("span",{className:"fvd-concern",children:t.concern})}),s.jsxs("div",{className:"fvd-meta",children:[t.status&&s.jsx("span",{className:`fv-status fv-st-${t.status}`,children:t.status}),s.jsx("span",{className:`fv-store fv-store-${i?"local":"forge"}`,children:t.store}),i?s.jsx(ls,{originator:t.by,sessions:v,kind:"issue",onOpenSession:w}):t.by&&s.jsx("span",{className:"fv-by",children:t.by}),b.map(l=>s.jsx("button",{type:"button",className:"fv-chip",onClick:()=>x==null?void 0:x(l),"data-tip":d("session.issuesFocusNode"),children:l},l)),t.url&&s.jsx("a",{className:"fv-link",href:t.url,target:"_blank",rel:"noreferrer",children:d("session.issuesOpenOnForge")})]}),t.body&&s.jsx("div",{className:"fvd-body",children:s.jsx(as,{body:t.body})}),s.jsx(os,{replies:S,threadId:i?t.id:null,onRemarkChange:()=>o==null?void 0:o("")})]}),s.jsx("div",{className:"fvd-compose",children:s.jsx(is,{onSend:(l,y)=>ss(t.id,l,y),specs:k,sessions:v,focusId:b[0]||null,onDone:o,actionsEnd:!c&&s.jsxs(s.Fragment,{children:[j&&s.jsx("span",{className:"fv-error",children:j}),i&&N("promote",d("session.issuesPromote"),()=>Y(t.id),d("session.issuesPromoteTitle")),N("close",d("session.issuesCloseIssue"),()=>W(t.id),d("session.issuesCloseIssueTitle"))]})},t.id)})]})}const fs=t=>t.id==="local"?"L":t.id==="github"?"GH":t.id==="gitlab"?"GL":(t.id||"?").slice(0,2).toUpperCase();function ms({specs:t,sessions:k,stores:v,onCancel:x,onDone:w}){var f;const o=D(),[d,i]=a.useState(((f=v[0])==null?void 0:f.id)||"local"),[c,h]=a.useState(""),[p,j]=a.useState(""),[m,b]=a.useState(!1),[S,g]=a.useState(""),N=a.useRef(null),l=cs({inputRef:N,value:p,setValue:j,specs:t,sessions:k,up:!0,fixedAbove:".fv-new-modal"});a.useEffect(()=>{var n;v.some(u=>u.id===d)||i(((n=v[0])==null?void 0:n.id)||"local")},[v,d]);const y=async()=>{const n=c.trim();if(!(!n||m)){b(!0),g("");try{const u=await es({concern:n,body:p.trim()||void 0,store:d});u!=null&&u.ok?(h(""),j(""),await(w==null?void 0:w(u.outcomes||""))):g((u==null?void 0:u.error)||o("session.issuesPostFailed"))}finally{b(!1)}}};return s.jsxs("div",{className:"fv-new-form",children:[s.jsxs("label",{className:"fv-store-pick",children:[s.jsx("span",{children:o("session.issuesStoreLabel")}),s.jsx("select",{value:d,disabled:m,onChange:n=>i(n.target.value),children:v.map(n=>s.jsxs("option",{value:n.id,children:[fs(n)," · ",n.label||n.id]},n.id))})]}),s.jsx("input",{className:"fv-input",value:c,placeholder:o("session.issuesConcernPlaceholder"),disabled:m,onChange:n=>h(n.target.value)}),s.jsxs("div",{className:"fv-tawrap",children:[s.jsx("textarea",{ref:N,className:"fv-textarea",rows:3,value:p,placeholder:o("session.issuesBodyPlaceholder"),disabled:m,onChange:n=>{j(n.target.value),l.sync(n.target)},onSelect:n=>l.sync(n.target),onBlur:l.close,onKeyDown:n=>{l.onKeyDown(n)||n.key==="Enter"&&(n.metaKey||n.ctrlKey)&&(n.preventDefault(),y())}}),l.menuEl]}),s.jsxs("div",{className:"fv-actions",children:[s.jsx("span",{className:S?"fv-error":"fv-hint",children:S||o("session.issuesMentionHint")}),s.jsx("button",{type:"button",className:"fv-cancel",disabled:m,onClick:x,children:o("common.cancel")}),s.jsx("button",{type:"button",className:"fv-send",disabled:m||!c.trim(),onClick:y,children:o(m?"session.issuesSending":"session.issuesPost")})]})]})}export{js as default};
1
+ import{u as D,r as a,j as s,i as Y,k as W,m as ss,n as es}from"./index-DulGPk6A.js";import{a5 as Z,a6 as ts,g as ns,Z as ls,a7 as as,a1 as os,a2 as is,a8 as cs}from"./SessionWindow-CDhEL7wO.js";import{F as _}from"./FoldToggle-CVFbBpyW.js";import{u as rs,M as ds}from"./Dashboard-CTcH2eW9.js";function js({onFocusNode:t,onOpenSession:k,specs:v=[],sessions:x=[],issuesData:w=null,reloadIssues:o,issueId:d=null}){const i=D(),c=w,[h,p]=a.useState(!1),[j,m]=a.useState(!1),[b,S]=a.useState(!1),[g,N]=a.useState(!1),[l,y]=a.useState("all"),[f,n]=a.useState(""),[u,L]=a.useState(null),T=a.useRef([]),G=a.useCallback(()=>o==null?void 0:o(!0),[o]),V=e=>{e&&(n(e),setTimeout(()=>n(""),6e3))},C=Array.isArray(c==null?void 0:c.issues)?c.issues:[],P=e=>e.status!=="open",B=[...new Set(C.map(e=>e.store).filter(Boolean))],J=Array.isArray(c==null?void 0:c.stores)&&c.stores.length?c.stores:[{id:"local",label:"local",kind:"local"}];a.useEffect(()=>{if(!d||!C.length)return;const e=C.find(r=>r.id===d);e&&(l!=="all"&&e.store!==l&&y("all"),P(e)&&S(!0),M(e)||N(!1),L(`issue:${e.id}`))},[d,C,l]);const K=l==="all"?C:C.filter(e=>e.store===l),M=e=>!!Z(x,e.by)||Array.isArray(e.replies)&&e.replies.some(r=>Z(x,r.by)),I=b?K:K.filter(e=>!P(e)),E=g?I.filter(M):I,F=I.filter(M).length,O=K.filter(P).length,H=a.useMemo(()=>new Map(E.map(e=>[`issue:${e.id}`,e])),[E]);T.current=E.map(e=>`issue:${e.id}`);const A=u&&H.has(u)?u:T.current[0]??null,U=a.useRef({});if(U.current={effSel:A},rs(h,()=>p(!1)),a.useEffect(()=>{const e=r=>{var X;const R=(X=r.target)==null?void 0:X.tagName;if(R==="INPUT"||R==="TEXTAREA"||r.metaKey||r.ctrlKey||r.altKey||r.key!=="j"&&r.key!=="k")return;r.preventDefault(),r.stopPropagation();const $=T.current;if(!$.length)return;const z=$.indexOf(U.current.effSel),Q=z<0?r.key==="j"?0:$.length-1:Math.max(0,Math.min($.length-1,z+(r.key==="j"?1:-1)));L($[Q])};return window.addEventListener("keydown",e,!0),()=>window.removeEventListener("keydown",e,!0)},[]),a.useEffect(()=>{var e;(e=document.querySelector(".fv-list-col .sel"))==null||e.scrollIntoView({block:"nearest"})},[A]),c==null)return s.jsx("div",{className:"fv-note",children:i("session.issuesLoading")});if(!c.enabled)return s.jsx("div",{className:"fv-note",children:i("session.issuesOff")});const q=A?H.get(A):null;return s.jsxs("div",{className:`fv-master ${j?"folded":""}`,children:[j&&s.jsx(_,{className:"fv-unfold",folded:!0,onToggle:()=>m(!1)}),s.jsxs("div",{className:"fv-list-col",style:j?{display:"none"}:void 0,children:[f&&s.jsx("div",{className:"fv-notice",children:f}),s.jsxs("section",{className:"fv-group",children:[s.jsxs("header",{className:"fv-group-head",children:[s.jsxs("span",{className:"fv-head-row",children:[s.jsx(_,{className:"fv-fold-inline",onToggle:()=>m(!0)}),B.length>1&&s.jsx(ts,{value:l,onChange:y,options:[{value:"all",label:i("session.issuesStoreAll")},...B.map(e=>({value:e,label:e}))]}),s.jsx(ns,{icon:"plus",size:12,className:"fv-new-btn",label:i("session.issuesNew"),onClick:()=>p(!0)})]}),(g||F>0||O>0)&&s.jsxs("span",{className:"ef-chipbar",children:[(g||F>0)&&s.jsx("button",{type:"button",className:`ef-chip fv-live ${g?"on":""}`,onClick:()=>N(e=>!e),"data-tip":i("masterList.liveChipTitle"),children:i("masterList.liveChip",{n:F})}),O>0&&s.jsx("button",{type:"button",className:`ef-chip fv-concluded ${b?"on":""}`,onClick:()=>S(e=>!e),children:i("nodeView.closedIssues",{n:O})})]})]}),!E.length&&s.jsx("div",{className:"fv-note",children:i("session.issuesEmpty")}),E.map(e=>{var R;const r=`issue:${e.id}`;return s.jsxs("button",{className:`fv-row ${A===r?"sel":""}`,onClick:()=>L(r),children:[s.jsx("span",{className:`fv-dot st-${e.status||"open"}`,"data-tip":e.status}),s.jsx("span",{className:"fv-concern","data-tip":e.concern,children:e.concern}),(((R=e.replies)==null?void 0:R.length)??0)>0&&s.jsx("span",{className:"fv-replies","data-tip":i("session.issuesReplies",{n:e.replies.length}),children:e.replies.length}),B.length>1&&s.jsx("span",{className:`fv-store fv-store-${e.store==="local"?"local":"forge"}`,children:e.store})]},e.id)})]})]}),s.jsx("div",{className:"fv-detail",children:q?s.jsx(us,{issue:q,specs:v,sessions:x,onFocusNode:t,onOpenSession:k,onWrite:async e=>{V(e),await G()}}):s.jsx("div",{className:"fv-note",children:i("session.issuesEmpty")})}),h&&s.jsx(ds,{title:i("session.issuesNew"),closeLabel:i("common.close"),onClose:()=>p(!1),className:"fv-new-modal",children:s.jsx(ms,{specs:v,sessions:x,stores:J,onCancel:()=>p(!1),onDone:async e=>{p(!1),V(e),await G()}})})]})}function us({issue:t,specs:k,sessions:v,onFocusNode:x,onOpenSession:w,onWrite:o}){const d=D(),i=t.store==="local",c=t.status!=="open",[h,p]=a.useState(""),[j,m]=a.useState(""),b=Array.isArray(t.nodes)?t.nodes:[],S=Array.isArray(t.replies)?t.replies:[],g=(l,y)=>async()=>{if(!h){p(l);try{const f=await y();f!=null&&f.ok?(m(""),await(o==null?void 0:o(""))):m((f==null?void 0:f.error)||`${l} failed`)}finally{p("")}}},N=(l,y,f,n)=>s.jsx("button",{type:"button",className:`fv-close-issue fv-life-${l}`,disabled:!!h,"data-tip":n,onMouseDown:u=>u.preventDefault(),onClick:g(l,f),children:h===l?d("session.issuesActing"):y});return s.jsxs("div",{className:"fvd",children:[s.jsxs("div",{className:"fvd-scroll",children:[s.jsx("header",{className:"fvd-head",children:s.jsx("span",{className:"fvd-concern",children:t.concern})}),s.jsxs("div",{className:"fvd-meta",children:[t.status&&s.jsx("span",{className:`fv-status fv-st-${t.status}`,children:t.status}),s.jsx("span",{className:`fv-store fv-store-${i?"local":"forge"}`,children:t.store}),i?s.jsx(ls,{originator:t.by,sessions:v,kind:"issue",onOpenSession:w}):t.by&&s.jsx("span",{className:"fv-by",children:t.by}),b.map(l=>s.jsx("button",{type:"button",className:"fv-chip",onClick:()=>x==null?void 0:x(l),"data-tip":d("session.issuesFocusNode"),children:l},l)),t.url&&s.jsx("a",{className:"fv-link",href:t.url,target:"_blank",rel:"noreferrer",children:d("session.issuesOpenOnForge")})]}),t.body&&s.jsx("div",{className:"fvd-body",children:s.jsx(as,{body:t.body})}),s.jsx(os,{replies:S,threadId:i?t.id:null,onRemarkChange:()=>o==null?void 0:o("")})]}),s.jsx("div",{className:"fvd-compose",children:s.jsx(is,{onSend:(l,y)=>ss(t.id,l,y),specs:k,sessions:v,focusId:b[0]||null,onDone:o,actionsEnd:!c&&s.jsxs(s.Fragment,{children:[j&&s.jsx("span",{className:"fv-error",children:j}),i&&N("promote",d("session.issuesPromote"),()=>Y(t.id),d("session.issuesPromoteTitle")),N("close",d("session.issuesCloseIssue"),()=>W(t.id),d("session.issuesCloseIssueTitle"))]})},t.id)})]})}const fs=t=>t.id==="local"?"L":t.id==="github"?"GH":t.id==="gitlab"?"GL":(t.id||"?").slice(0,2).toUpperCase();function ms({specs:t,sessions:k,stores:v,onCancel:x,onDone:w}){var f;const o=D(),[d,i]=a.useState(((f=v[0])==null?void 0:f.id)||"local"),[c,h]=a.useState(""),[p,j]=a.useState(""),[m,b]=a.useState(!1),[S,g]=a.useState(""),N=a.useRef(null),l=cs({inputRef:N,value:p,setValue:j,specs:t,sessions:k,up:!0,fixedAbove:".fv-new-modal"});a.useEffect(()=>{var n;v.some(u=>u.id===d)||i(((n=v[0])==null?void 0:n.id)||"local")},[v,d]);const y=async()=>{const n=c.trim();if(!(!n||m)){b(!0),g("");try{const u=await es({concern:n,body:p.trim()||void 0,store:d});u!=null&&u.ok?(h(""),j(""),await(w==null?void 0:w(u.outcomes||""))):g((u==null?void 0:u.error)||o("session.issuesPostFailed"))}finally{b(!1)}}};return s.jsxs("div",{className:"fv-new-form",children:[s.jsxs("label",{className:"fv-store-pick",children:[s.jsx("span",{children:o("session.issuesStoreLabel")}),s.jsx("select",{value:d,disabled:m,onChange:n=>i(n.target.value),children:v.map(n=>s.jsxs("option",{value:n.id,children:[fs(n)," · ",n.label||n.id]},n.id))})]}),s.jsx("input",{className:"fv-input",value:c,placeholder:o("session.issuesConcernPlaceholder"),disabled:m,onChange:n=>h(n.target.value)}),s.jsxs("div",{className:"fv-tawrap",children:[s.jsx("textarea",{ref:N,className:"fv-textarea",rows:3,value:p,placeholder:o("session.issuesBodyPlaceholder"),disabled:m,onChange:n=>{j(n.target.value),l.sync(n.target)},onSelect:n=>l.sync(n.target),onBlur:l.close,onKeyDown:n=>{l.onKeyDown(n)||n.key==="Enter"&&(n.metaKey||n.ctrlKey)&&(n.preventDefault(),y())}}),l.menuEl]}),s.jsxs("div",{className:"fv-actions",children:[s.jsx("span",{className:S?"fv-error":"fv-hint",children:S||o("session.issuesMentionHint")}),s.jsx("button",{type:"button",className:"fv-cancel",disabled:m,onClick:x,children:o("common.cancel")}),s.jsx("button",{type:"button",className:"fv-send",disabled:m||!c.trim(),onClick:y,children:o(m?"session.issuesSending":"session.issuesPost")})]})]})}export{js as default};
@@ -1 +1 @@
1
- import{u as k,r as b,j as s}from"./index-BhIslAau.js";import{q as M,t as A,A as y,j as g,v as H,H as V,w as R,E as _,c as $,G as B,x as G,S}from"./SessionWindow-LcCzBMU7.js";const L={spec:"nodeView.paneSpec",history:"nodeView.paneHistory",issues:"nodeView.paneIssues",eval:"nodeView.paneEval",edit:"nodeView.paneEdit"},C=(e,l)=>l.filter(u=>{var h;return(h=u.ops)==null?void 0:h.some(n=>n.nodeId===e.id)});function T({status:e}){const l=S[e]||S.pending;return s.jsx("span",{className:"m-dot",style:{background:l.color}})}function U({node:e,kids:l,editors:u,onTap:h}){return s.jsxs("button",{className:"m-row",onClick:h,children:[s.jsx(T,{status:e.status}),s.jsx("span",{className:"m-row-title",children:e.title}),u.length>0&&s.jsx("span",{className:"m-row-faces",children:u.slice(0,3).map(n=>s.jsx(y,{seed:n.id,status:n.status,title:g(n)},n.id))}),e.version?s.jsxs("span",{className:"m-row-ver",children:["v",e.version]}):null,l>0&&s.jsxs("span",{className:"m-row-kids",children:["▸",l]}),s.jsx("span",{className:"m-row-chev",children:"›"})]})}function q({node:e,childrenOf:l,sessions:u,onOpenChild:h}){const n=k(),m=l(e.id),d=M(e),i=[...m.length?[{key:"children",label:n("mobile.childrenTab",{n:m.length})}]:[],...d.map(a=>({key:a.key,label:n(L[a.key])}))],[r,x]=b.useState(null);b.useEffect(()=>{x(null)},[e.id]);const c=r&&i.some(a=>a.key===r)?r:i[0].key,j=A(e.id,c==="history"),N=C(e,u);return s.jsxs("div",{className:"m-node",children:[s.jsxs("div",{className:"m-node-head",children:[s.jsx(T,{status:e.status}),s.jsx("span",{className:"m-node-title",children:e.title}),e.version?s.jsxs("span",{className:"m-node-ver",children:["v",e.version]}):null,s.jsx("span",{className:"m-node-status",children:n(`status.${e.status}`)}),N.length>0&&s.jsx("span",{className:"m-node-faces",title:n("mobile.liveEditors",{n:N.length}),children:N.map(a=>s.jsx(y,{seed:a.id,status:a.status,title:g(a)},a.id))})]}),e.desc&&s.jsx("div",{className:"m-node-desc",children:e.desc}),s.jsx("div",{className:"m-tabs",children:i.map(a=>s.jsx("button",{className:a.key===c?"m-tab on":"m-tab",onClick:()=>x(a.key),children:a.label},a.key))}),s.jsxs("div",{className:c==="history"?"m-pane-host fixed":"m-pane-host",children:[c==="children"&&s.jsx("div",{className:"m-children",children:m.map(a=>s.jsx(U,{node:a,kids:l(a.id).length,editors:C(a,u),onTap:()=>h(a.id)},a.id))}),c==="spec"&&s.jsx(H,{node:e}),c==="history"&&s.jsx(V,{node:e,rows:j}),c==="issues"&&s.jsx(R,{node:e}),c==="edit"&&s.jsx(_,{node:e})]})]})}function D({sessions:e,openId:l,setOpenId:u,byId:h,goToNode:n}){const m=k(),d=l?e.find(i=>i.id===l):null;if(d){const i=d.ops||[];return s.jsxs("div",{className:"m-sessdetail",children:[s.jsxs("div",{className:"m-sess-card",children:[s.jsx(y,{seed:d.id,status:d.status}),s.jsxs("div",{className:"m-sess-meta",children:[s.jsx("span",{className:"m-sess-name",children:g(d)}),s.jsx("span",{className:"m-sess-status",style:{color:$[d.status]},children:m(`status.${d.status}`)})]})]}),d.activity&&s.jsx("div",{className:"m-sess-activity",children:d.activity}),s.jsx("div",{className:"m-sess-section",children:m("mobile.changing",{n:i.length})}),i.length===0?s.jsx("div",{className:"m-empty",children:m("mobile.noChanges")}):i.map((r,x)=>{const c=h[r.nodeId];return s.jsxs("button",{className:"m-row",disabled:!c,onClick:()=>c&&n(r.nodeId),children:[s.jsx("span",{className:`ov-mark ov-${r.op}`,children:B[r.op]||"•"}),s.jsx("span",{className:"m-row-title",children:c?c.title:r.nodeId}),c&&s.jsx("span",{className:"m-row-chev",children:"›"})]},x)})]})}return e.length?s.jsx("div",{className:"m-sesslist",children:e.map(i=>s.jsx("button",{className:"m-sess-row",onClick:()=>u(i.id),children:s.jsx(G,{s:i,locked:!1})},i.id))}):s.jsx("div",{className:"m-empty big",children:m("mobile.noSessions")})}function z({specs:e,sessions:l,project:u}){const h=k(),n=b.useMemo(()=>Object.fromEntries(e.map(t=>[t.id,t])),[e]),m=b.useMemo(()=>e.find(t=>!t.parent)||e[0],[e]),d=b.useMemo(()=>{const t={};return e.forEach(o=>{var p;o.parent&&(t[p=o.parent]??(t[p]=[])).push(o)}),o=>t[o]||[]},[e]),i=b.useMemo(()=>t=>{const o=[];for(let p=n[t];p;p=p.parent?n[p.parent]:null)o.unshift(p.id);return o},[n]),[r,x]=b.useState("specs"),[c,j]=b.useState(()=>m?[m.id]:[]),[N,a]=b.useState(null),v=c.filter(t=>n[t]),w=v[v.length-1]||(m==null?void 0:m.id),f=w?n[w]:null,E=t=>j(o=>[...o.filter(p=>n[p]),t]),I=t=>{j(i(t)),a(null),x("specs")},P=r==="specs"?v.length>1:!!N,O=()=>{r==="specs"?j(t=>t.slice(0,-1)):a(null)};return s.jsxs("div",{className:"m-app",children:[s.jsxs("header",{className:"m-topbar",children:[P?s.jsx("button",{className:"m-back",onClick:O,"aria-label":h("mobile.back"),children:"‹"}):s.jsx("span",{className:"m-back ghost","aria-hidden":"true"}),s.jsx("span",{className:"m-brand",children:u||"SpexCode"})]}),s.jsx("main",{className:"m-main",children:r==="specs"?s.jsxs("div",{className:"m-specs",children:[s.jsx("nav",{className:"m-crumbs",children:v.map((t,o)=>s.jsxs("span",{className:"m-crumb",children:[o>0&&s.jsx("span",{className:"m-crumb-sep",children:"›"}),s.jsx("button",{className:o===v.length-1?"m-crumb-btn cur":"m-crumb-btn",onClick:()=>j(v.slice(0,o+1)),children:n[t].title})]},t))}),f&&s.jsx(q,{node:f,childrenOf:d,sessions:l,onOpenChild:E},f.id)]}):s.jsx(D,{sessions:l,openId:N,setOpenId:a,byId:n,goToNode:I})}),s.jsxs("nav",{className:"m-tabbar",children:[s.jsxs("button",{className:r==="specs"?"m-tabbar-btn on":"m-tabbar-btn",onClick:()=>x("specs"),children:[s.jsx("span",{className:"m-tabbar-ico",children:"❯_"}),h("mobile.specsTab")]}),s.jsxs("button",{className:r==="sessions"?"m-tabbar-btn on":"m-tabbar-btn",onClick:()=>x("sessions"),children:[s.jsx("span",{className:"m-tabbar-ico",children:"◐"}),h("mobile.sessionsTab"),l.length>0&&s.jsx("span",{className:"m-tabbar-badge",children:l.length})]})]})]})}export{z as default};
1
+ import{u as k,r as b,j as s}from"./index-DulGPk6A.js";import{q as M,t as A,A as y,j as g,v as H,H as V,w as R,E as _,c as $,G as B,x as G,S}from"./SessionWindow-CDhEL7wO.js";const L={spec:"nodeView.paneSpec",history:"nodeView.paneHistory",issues:"nodeView.paneIssues",eval:"nodeView.paneEval",edit:"nodeView.paneEdit"},C=(e,l)=>l.filter(u=>{var h;return(h=u.ops)==null?void 0:h.some(n=>n.nodeId===e.id)});function T({status:e}){const l=S[e]||S.pending;return s.jsx("span",{className:"m-dot",style:{background:l.color}})}function U({node:e,kids:l,editors:u,onTap:h}){return s.jsxs("button",{className:"m-row",onClick:h,children:[s.jsx(T,{status:e.status}),s.jsx("span",{className:"m-row-title",children:e.title}),u.length>0&&s.jsx("span",{className:"m-row-faces",children:u.slice(0,3).map(n=>s.jsx(y,{seed:n.id,status:n.status,title:g(n)},n.id))}),e.version?s.jsxs("span",{className:"m-row-ver",children:["v",e.version]}):null,l>0&&s.jsxs("span",{className:"m-row-kids",children:["▸",l]}),s.jsx("span",{className:"m-row-chev",children:"›"})]})}function q({node:e,childrenOf:l,sessions:u,onOpenChild:h}){const n=k(),m=l(e.id),d=M(e),i=[...m.length?[{key:"children",label:n("mobile.childrenTab",{n:m.length})}]:[],...d.map(a=>({key:a.key,label:n(L[a.key])}))],[r,x]=b.useState(null);b.useEffect(()=>{x(null)},[e.id]);const c=r&&i.some(a=>a.key===r)?r:i[0].key,j=A(e.id,c==="history"),N=C(e,u);return s.jsxs("div",{className:"m-node",children:[s.jsxs("div",{className:"m-node-head",children:[s.jsx(T,{status:e.status}),s.jsx("span",{className:"m-node-title",children:e.title}),e.version?s.jsxs("span",{className:"m-node-ver",children:["v",e.version]}):null,s.jsx("span",{className:"m-node-status",children:n(`status.${e.status}`)}),N.length>0&&s.jsx("span",{className:"m-node-faces",title:n("mobile.liveEditors",{n:N.length}),children:N.map(a=>s.jsx(y,{seed:a.id,status:a.status,title:g(a)},a.id))})]}),e.desc&&s.jsx("div",{className:"m-node-desc",children:e.desc}),s.jsx("div",{className:"m-tabs",children:i.map(a=>s.jsx("button",{className:a.key===c?"m-tab on":"m-tab",onClick:()=>x(a.key),children:a.label},a.key))}),s.jsxs("div",{className:c==="history"?"m-pane-host fixed":"m-pane-host",children:[c==="children"&&s.jsx("div",{className:"m-children",children:m.map(a=>s.jsx(U,{node:a,kids:l(a.id).length,editors:C(a,u),onTap:()=>h(a.id)},a.id))}),c==="spec"&&s.jsx(H,{node:e}),c==="history"&&s.jsx(V,{node:e,rows:j}),c==="issues"&&s.jsx(R,{node:e}),c==="edit"&&s.jsx(_,{node:e})]})]})}function D({sessions:e,openId:l,setOpenId:u,byId:h,goToNode:n}){const m=k(),d=l?e.find(i=>i.id===l):null;if(d){const i=d.ops||[];return s.jsxs("div",{className:"m-sessdetail",children:[s.jsxs("div",{className:"m-sess-card",children:[s.jsx(y,{seed:d.id,status:d.status}),s.jsxs("div",{className:"m-sess-meta",children:[s.jsx("span",{className:"m-sess-name",children:g(d)}),s.jsx("span",{className:"m-sess-status",style:{color:$[d.status]},children:m(`status.${d.status}`)})]})]}),d.activity&&s.jsx("div",{className:"m-sess-activity",children:d.activity}),s.jsx("div",{className:"m-sess-section",children:m("mobile.changing",{n:i.length})}),i.length===0?s.jsx("div",{className:"m-empty",children:m("mobile.noChanges")}):i.map((r,x)=>{const c=h[r.nodeId];return s.jsxs("button",{className:"m-row",disabled:!c,onClick:()=>c&&n(r.nodeId),children:[s.jsx("span",{className:`ov-mark ov-${r.op}`,children:B[r.op]||"•"}),s.jsx("span",{className:"m-row-title",children:c?c.title:r.nodeId}),c&&s.jsx("span",{className:"m-row-chev",children:"›"})]},x)})]})}return e.length?s.jsx("div",{className:"m-sesslist",children:e.map(i=>s.jsx("button",{className:"m-sess-row",onClick:()=>u(i.id),children:s.jsx(G,{s:i,locked:!1})},i.id))}):s.jsx("div",{className:"m-empty big",children:m("mobile.noSessions")})}function z({specs:e,sessions:l,project:u}){const h=k(),n=b.useMemo(()=>Object.fromEntries(e.map(t=>[t.id,t])),[e]),m=b.useMemo(()=>e.find(t=>!t.parent)||e[0],[e]),d=b.useMemo(()=>{const t={};return e.forEach(o=>{var p;o.parent&&(t[p=o.parent]??(t[p]=[])).push(o)}),o=>t[o]||[]},[e]),i=b.useMemo(()=>t=>{const o=[];for(let p=n[t];p;p=p.parent?n[p.parent]:null)o.unshift(p.id);return o},[n]),[r,x]=b.useState("specs"),[c,j]=b.useState(()=>m?[m.id]:[]),[N,a]=b.useState(null),v=c.filter(t=>n[t]),w=v[v.length-1]||(m==null?void 0:m.id),f=w?n[w]:null,E=t=>j(o=>[...o.filter(p=>n[p]),t]),I=t=>{j(i(t)),a(null),x("specs")},P=r==="specs"?v.length>1:!!N,O=()=>{r==="specs"?j(t=>t.slice(0,-1)):a(null)};return s.jsxs("div",{className:"m-app",children:[s.jsxs("header",{className:"m-topbar",children:[P?s.jsx("button",{className:"m-back",onClick:O,"aria-label":h("mobile.back"),children:"‹"}):s.jsx("span",{className:"m-back ghost","aria-hidden":"true"}),s.jsx("span",{className:"m-brand",children:u||"SpexCode"})]}),s.jsx("main",{className:"m-main",children:r==="specs"?s.jsxs("div",{className:"m-specs",children:[s.jsx("nav",{className:"m-crumbs",children:v.map((t,o)=>s.jsxs("span",{className:"m-crumb",children:[o>0&&s.jsx("span",{className:"m-crumb-sep",children:"›"}),s.jsx("button",{className:o===v.length-1?"m-crumb-btn cur":"m-crumb-btn",onClick:()=>j(v.slice(0,o+1)),children:n[t].title})]},t))}),f&&s.jsx(q,{node:f,childrenOf:d,sessions:l,onOpenChild:E},f.id)]}):s.jsx(D,{sessions:l,openId:N,setOpenId:a,byId:n,goToNode:I})}),s.jsxs("nav",{className:"m-tabbar",children:[s.jsxs("button",{className:r==="specs"?"m-tabbar-btn on":"m-tabbar-btn",onClick:()=>x("specs"),children:[s.jsx("span",{className:"m-tabbar-ico",children:"❯_"}),h("mobile.specsTab")]}),s.jsxs("button",{className:r==="sessions"?"m-tabbar-btn on":"m-tabbar-btn",onClick:()=>x("sessions"),children:[s.jsx("span",{className:"m-tabbar-ico",children:"◐"}),h("mobile.sessionsTab"),l.length>0&&s.jsx("span",{className:"m-tabbar-badge",children:l.length})]})]})]})}export{z as default};