@dendelion/paper-camp 0.8.0 → 0.9.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 (53) hide show
  1. package/dist/app/assets/{index-DGXi8vpJ.js → index-C0wWs5ba.js} +2 -2
  2. package/dist/app/assets/index-C0wWs5ba.js.map +1 -0
  3. package/dist/app/assets/{index-CF8jC3IN.js → index-D-nmg_4I.js} +2 -2
  4. package/dist/app/assets/{index-CF8jC3IN.js.map → index-D-nmg_4I.js.map} +1 -1
  5. package/dist/app/assets/index-Djq8LvrZ.js +3 -0
  6. package/dist/app/assets/index-Djq8LvrZ.js.map +1 -0
  7. package/dist/app/assets/main-BA1w2y_E.css +1 -0
  8. package/dist/app/assets/main-DUy5DFoq.js +218 -0
  9. package/dist/app/assets/main-DUy5DFoq.js.map +1 -0
  10. package/dist/app/assets/{sidebar-section-C2j12TzE.js → sidebar-section-mXpllayv.js} +2 -2
  11. package/dist/app/assets/{sidebar-section-C2j12TzE.js.map → sidebar-section-mXpllayv.js.map} +1 -1
  12. package/dist/app/index.html +2 -2
  13. package/dist/chunks/{serializer.BfH7zTwv.js → serializer.DqcFa2e1.js} +75 -66
  14. package/dist/chunks/serializer.DqcFa2e1.js.map +1 -0
  15. package/dist/cli/index.js +6187 -6079
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/core/env.d.ts +0 -5
  18. package/dist/core/env.d.ts.map +1 -1
  19. package/dist/core/git-pr/branch.d.ts +2 -6
  20. package/dist/core/git-pr/branch.d.ts.map +1 -1
  21. package/dist/core/git-pr/pr-lookup.d.ts +3 -44
  22. package/dist/core/git-pr/pr-lookup.d.ts.map +1 -1
  23. package/dist/core/git-pr/pr.d.ts +0 -76
  24. package/dist/core/git-pr/pr.d.ts.map +1 -1
  25. package/dist/core/git-pr/scopes.d.ts +0 -6
  26. package/dist/core/git-pr/scopes.d.ts.map +1 -1
  27. package/dist/core/index.js +36 -35
  28. package/dist/core/parse/frontmatter-schemas.d.ts +0 -8
  29. package/dist/core/parse/frontmatter-schemas.d.ts.map +1 -1
  30. package/dist/core/parse/parser.d.ts +3 -31
  31. package/dist/core/parse/parser.d.ts.map +1 -1
  32. package/dist/core/parse/schemas.d.ts.map +1 -1
  33. package/dist/core/readers.d.ts +0 -27
  34. package/dist/core/readers.d.ts.map +1 -1
  35. package/dist/core/scaffold/scaffold.d.ts +0 -6
  36. package/dist/core/scaffold/scaffold.d.ts.map +1 -1
  37. package/dist/core/scaffold/templates.d.ts +0 -6
  38. package/dist/core/scaffold/templates.d.ts.map +1 -1
  39. package/dist/core/serialize/content-hash.d.ts +0 -6
  40. package/dist/core/serialize/content-hash.d.ts.map +1 -1
  41. package/dist/core/serialize/serializer.d.ts +0 -60
  42. package/dist/core/serialize/serializer.d.ts.map +1 -1
  43. package/dist/core/status/status.d.ts +0 -19
  44. package/dist/core/status/status.d.ts.map +1 -1
  45. package/dist/types/index.d.ts +12 -29
  46. package/dist/types/index.d.ts.map +1 -1
  47. package/dist/types/index.js.map +1 -1
  48. package/package.json +1 -1
  49. package/dist/app/assets/index-DGXi8vpJ.js.map +0 -1
  50. package/dist/app/assets/main-D66GnCKz.css +0 -1
  51. package/dist/app/assets/main-DJDNx4Xs.js +0 -218
  52. package/dist/app/assets/main-DJDNx4Xs.js.map +0 -1
  53. package/dist/chunks/serializer.BfH7zTwv.js.map +0 -1
@@ -1,2 +1,2 @@
1
- import{u as T,j as e,P as Z,r as p,m as q,e as X,s as d,n as M,p as W,X as D,O as Q,c as ee,q as F,Z as z,t as I,f as b,$,b as N,v as te,w as se,x as ne,y as ae,A as P,Y as O,z as ie,B as le,o as _}from"./main-DJDNx4Xs.js";import{S as R}from"./sidebar-section-C2j12TzE.js";const oe=async()=>{try{const n=await fetch("/api/config");return n.ok?n.json():null}catch{return null}},U=async n=>{try{return(await fetch("/api/config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)})).ok}catch{return!1}},re=async()=>{try{const n=await fetch("/api/configs");return n.ok?(await n.json()).files:[]}catch{return[]}},ce=async n=>{try{const t=await fetch(`/api/configs?name=${encodeURIComponent(n)}`);return t.ok?(await t.json()).content:null}catch{return null}},H=async()=>{try{const n=await fetch("/api/env");return n.ok?await n.json():{exists:!1,exampleExists:!1,entries:[],missingKeys:[]}}catch{return{exists:!1,exampleExists:!1,entries:[],missingKeys:[]}}},de=async n=>{try{return(await fetch("/api/env",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({entries:n})})).ok}catch{return!1}},K=["phase","planDraft","ideaExtend","commitSuggest"],pe={phase:"Phase run",planDraft:"Plan draft",ideaExtend:"Idea extend",commitSuggest:"Commit suggest"},Y=110,J=140,B=160,V=110,he=()=>e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:d[3],paddingBottom:d[1]},children:[e.jsx("span",{style:{width:Y,flexShrink:0,fontSize:b.sm,opacity:.45},children:"Task"}),e.jsx("span",{style:{width:J,flexShrink:0,fontSize:b.sm,opacity:.45},children:"Agent"}),e.jsx("span",{style:{width:B,flexShrink:0,fontSize:b.sm,opacity:.45},children:"Model"}),e.jsx("span",{style:{width:V,flexShrink:0,fontSize:b.sm,opacity:.45},children:"Effort"})]}),ue=({taskKey:n,agentConfig:t,isLast:u,onSave:h})=>{const m=P[t.agent]??P["claude-code"],g=m.model,l=m.effort,[x,y]=p.useState(t.model??"");p.useEffect(()=>{y(t.model??"")},[t.model]);const v=c=>{var C;const f=c,k=P[f],w={agent:f};t.model&&(k.model===null||(C=k.model)!=null&&C.includes(t.model))&&(w.model=t.model),t.effort&&Array.isArray(k.effort)&&(w.effort=t.effort),h(n,w)},A=c=>{h(n,{...t,model:c||void 0})},j=()=>{h(n,{...t,model:x||void 0})},S=c=>{h(n,{...t,effort:c||void 0})};return e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:d[3],paddingBottom:d[2],paddingTop:d[2]},children:[e.jsx("span",{style:{width:Y,flexShrink:0,fontSize:b.sm,opacity:.65},children:pe[n]}),e.jsx(O,{size:"small",width:J,value:t.agent,onChange:v,options:ie.map(c=>({value:c,label:le[c]}))}),Array.isArray(g)?e.jsx(O,{size:"small",width:B,value:t.model??"",onChange:A,options:[{value:"",label:"Default"},...g.map(c=>({value:c,label:c}))]}):g===null?e.jsx(D,{size:"small",style:{width:B},value:x,placeholder:"Default model",onChange:c=>y(c.target.value),onBlur:j}):null,e.jsx("div",{style:{visibility:Array.isArray(l)?"visible":"hidden"},children:e.jsx(O,{size:"small",width:V,value:t.effort??"",onChange:S,options:[{value:"",label:"Default"},...(Array.isArray(l)?l:[]).map(c=>({value:c,label:c}))]})})]}),!u&&e.jsx(F,{})]})},fe=()=>{const n=p.useRef(null),[t,u]=p.useState(void 0),{iconDataUri:h,loading:m}=q(),[g,l]=p.useState(null),x=g??h,[y,v]=p.useState(!1),[A,j]=p.useState(""),[S,c]=p.useState(""),{toast:f}=X();p.useEffect(()=>{oe().then(i=>{u(i),(i==null?void 0:i.port)!==void 0&&j(String(i.port)),(i==null?void 0:i.projectName)!==void 0&&c(i.projectName)})},[]);const k=async(i,a)=>{const s=t==null?void 0:t.defaultAgents,o={phase:(s==null?void 0:s.phase)??I.phase,planDraft:(s==null?void 0:s.planDraft)??I.planDraft,ideaExtend:(s==null?void 0:s.ideaExtend)??I.ideaExtend,commitSuggest:(s==null?void 0:s.commitSuggest)??I.commitSuggest,[i]:a};await U({defaultAgents:o})?(u(E=>E&&{...E,defaultAgents:o}),f({title:"Saved",variant:"success"})):f({title:"Failed to save",variant:"error"})},w=async()=>{const i=Number(A);if(!t||!Number.isInteger(i)||i<=0||i===t.port)return;await U({port:i})?(u(s=>s&&{...s,port:i}),f({title:"Saved",variant:"success"})):f({title:"Failed to save",variant:"error"})},C=async()=>{const i=S.trim();if(!t||!i||i===t.projectName)return;await U({projectName:i})?(u(s=>s&&{...s,projectName:i}),c(i),f({title:"Saved",variant:"success"})):f({title:"Failed to save",variant:"error"})},L=async i=>{var o;const a=(o=i.target.files)==null?void 0:o[0];if(!a)return;v(!0);const s=new FileReader;s.onloadend=async()=>{const r=s.result,E=await ae(r);v(!1),E?(l(r),f({title:"Saved",variant:"success"})):f({title:"Failed to save",variant:"error"})},s.readAsDataURL(a)};return e.jsxs("div",{children:[e.jsx("div",{style:{marginBottom:d[6]},children:e.jsx("h2",{style:{margin:0},children:"Project Info"})}),t===void 0&&e.jsx("p",{children:"Loading…"}),t===null&&e.jsxs(M,{variant:"warning",children:["No papercamp/config.json found — run ",e.jsx("code",{children:"paper-camp init"})," in this directory first."]}),t&&e.jsxs(W,{size:"small",children:[e.jsxs("div",{style:{display:"flex",alignItems:"flex-end",gap:d[3],paddingBottom:d[3]},children:[e.jsx(D,{value:S,onChange:i=>c(i.target.value),onBlur:C,label:"Project Name"}),e.jsxs(Q,{size:"small",fillColor:"rgba(143, 185, 150, 0.25)",textColor:ee.accentGreenDark,children:["v",t.version]})]}),e.jsx(F,{}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:d[3],paddingBottom:d[3],paddingTop:d[3]},children:[x&&e.jsx("img",{src:x,alt:"Project icon",style:{width:40,height:40,objectFit:"contain",flexShrink:0,borderRadius:4}}),e.jsxs("div",{children:[e.jsx("input",{ref:n,type:"file",accept:".svg,.png,.jpg,.jpeg,.gif,.webp",onChange:L,style:{display:"none"}}),e.jsx(z,{variant:"secondary",size:"small",onClick:()=>{var i;return(i=n.current)==null?void 0:i.click()},disabled:y,children:y?"Uploading…":"Choose File"}),m&&e.jsx("p",{className:"text-sm",style:{opacity:.5,margin:`${d[1]} 0 0`},children:"Loading…"}),!m&&!x&&!y&&e.jsx("p",{className:"text-sm",style:{opacity:.45,margin:`${d[1]} 0 0`},children:"No icon set."})]})]}),e.jsx(F,{}),e.jsx("div",{style:{display:"flex",alignItems:"flex-end",gap:d[3],paddingBottom:d[3],paddingTop:d[3]},children:e.jsx(D,{type:"number",value:A,onChange:i=>j(i.target.value),onBlur:w,label:"Port",helperText:"Default for `paper-camp dev`. Does not affect the running server."})}),e.jsx(F,{}),e.jsx(he,{}),K.map((i,a)=>{var s;return e.jsx(ue,{taskKey:i,agentConfig:((s=t.defaultAgents)==null?void 0:s[i])??I[i],isLast:a===K.length-1,onSave:k},i)})]}),e.jsxs("p",{style:{opacity:.45,fontSize:b.sm,marginTop:d[4]},children:[e.jsx("strong",{children:"Initialized:"})," ",t?new Date(t.initializedAt).toLocaleString():"—"]})]})},me=n=>{try{const t=JSON.parse(n);return!t.scripts||typeof t.scripts!="object"?null:Object.entries(t.scripts).map(([u,h])=>({name:u,command:h}))}catch{return null}},ge=({fileName:n})=>{const[t,u]=p.useState(null),[h,m]=p.useState(!0);if(p.useEffect(()=>{m(!0),ce(n).then(l=>{u(l),m(!1)})},[n]),h)return e.jsx("p",{children:"Loading…"});if(t===null)return e.jsxs(M,{variant:"warning",children:["Could not load file — ",n," not found."]});const g=n==="package.json"?me(t):null;return e.jsxs("div",{children:[e.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:d[4]},children:e.jsx("h2",{style:{margin:0},children:n})}),g?e.jsx($,{data:g,columns:[{key:"name",header:"Script",cell:l=>e.jsx("span",{style:{fontFamily:N.mono},children:l.name}),width:4},{key:"command",header:"Command",cell:l=>e.jsx("span",{style:{fontFamily:N.mono},children:l.command})}]}):e.jsx(ne,{code:t,filename:n})]})},G=n=>/key|secret|token|password/i.test(n),xe=()=>{const[n,t]=p.useState(!0),[u,h]=p.useState([]),[m,g]=p.useState([]),[l,x]=p.useState(new Set),[y,v]=p.useState(!1),[A,j]=p.useState(!1),[S,c]=p.useState(null);p.useEffect(()=>{H().then(a=>{h(a.entries),g(a.missingKeys),t(!1)})},[]);const f=(a,s)=>{h(o=>o.map((r,E)=>E===a?{...r,...s}:r))},k=()=>h(a=>[...a,{key:"",value:""}]),w=a=>{h(s=>[...s,{key:a,value:""}]),g(s=>s.filter(o=>o!==a))},C=a=>{h(s=>s.filter((o,r)=>r!==a)),x(s=>{const o=new Set(s);return o.delete(a),o})},L=a=>x(s=>{const o=new Set(s);return o.has(a)?o.delete(a):o.add(a),o}),i=async()=>{const a=u.map(r=>({key:r.key.trim(),value:r.value,isSet:r.isSet})).filter(r=>r.key.length>0);if(new Set(a.map(r=>r.key)).size!==a.length){c("Duplicate keys are not allowed");return}c(null),v(!0);const o=await de(a.map(r=>({key:r.key,value:r.value,keep:!!r.isSet&&r.value===""})));v(!1),o?(h(a.map(r=>({key:r.key,value:"",isSet:!0}))),j(!0),setTimeout(()=>j(!1),2e3)):c("Failed to save .env")};return n?e.jsx("p",{children:"Loading…"}):e.jsxs("div",{children:[e.jsx("h2",{style:{margin:0,marginBottom:d[4]},children:"Environment Variables"}),S&&e.jsxs(M,{variant:"warning",children:["Could not save — ",S]}),m.length>0&&e.jsxs(W,{size:"small",accent:!0,accentColor:"amber",children:[e.jsx("p",{style:{margin:0,fontWeight:600},children:"Missing from .env"}),e.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:d[2],alignItems:"center"},children:[e.jsx("span",{children:"Present in .env.example but not set:"}),m.map(a=>e.jsxs(z,{variant:"secondary",size:"small",onClick:()=>w(a),children:["+ ",a]},a))]})]}),e.jsx($,{data:u,columns:[{key:"key",header:"Key",cell:(a,s)=>e.jsx(D,{value:a.key,placeholder:"KEY",style:{fontFamily:N.mono},onChange:o=>f(s,{key:o.target.value})}),width:6},{key:"value",header:"Value",cell:(a,s)=>{const o=G(a.key)&&!l.has(s);return e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:d[2]},children:[e.jsx(D,{type:o?"password":"text",value:a.value,placeholder:a.isSet?"•••••• set — leave blank to keep":"value",style:{fontFamily:N.mono,flex:1},onChange:r=>f(s,{value:r.target.value})}),G(a.key)&&e.jsx(z,{variant:"ghost",size:"small",onClick:()=>L(s),children:o?"Show":"Hide"})]})}},{key:"actions",header:"",width:2,cell:(a,s)=>e.jsx(te,{icon:e.jsx(se,{}),variant:"ghost",size:"small",label:"Remove variable",onClick:()=>C(s)})}]}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:d[3],marginTop:d[4]},children:[e.jsx(z,{variant:"secondary",size:"small",onClick:k,children:"+ Add variable"}),e.jsx(z,{variant:"primary",size:"small",onClick:i,disabled:y,children:y?"Saving…":"Save"}),A&&e.jsx("span",{className:"text-sm",style:{opacity:.6},children:"Saved"})]})]})},je=()=>{const n=T(t=>t.activeSettingsSection);return e.jsxs("div",{children:[e.jsx(Z,{children:"Settings"}),n==="general"&&e.jsx(fe,{}),n==="env"&&e.jsx(xe,{}),n.startsWith("config:")&&e.jsx(ge,{fileName:n.slice(7)})]})},Se=()=>{const n=T(l=>l.activeSettingsSection),t=T(l=>l.setActiveSettingsSection),u=T(l=>l.settingsConfigFiles),h=T(l=>l.setSettingsConfigFiles),[m,g]=p.useState(!1);return p.useEffect(()=>{re().then(h),H().then(l=>g(l.exists||l.exampleExists))},[h]),e.jsxs(e.Fragment,{children:[e.jsx(R,{label:"General",children:e.jsx(_,{size:"small",active:n==="general",onClick:()=>t("general"),children:"Project Info"})}),m&&e.jsx(R,{label:"Environment",children:e.jsx(_,{size:"small",active:n==="env",onClick:()=>t("env"),children:"Env Vars"})}),u.length>0&&e.jsx(R,{label:"Config Files",children:u.map(l=>e.jsx(_,{size:"small",active:n===`config:${l}`,onClick:()=>t(`config:${l}`),children:l},l))})]})};export{je as SettingsPage,Se as SettingsSidebar};
2
- //# sourceMappingURL=index-DGXi8vpJ.js.map
1
+ import{u as T,j as e,P as Z,r as p,m as q,e as X,s as d,n as M,p as W,X as D,O as Q,c as ee,q as F,Z as z,t as I,f as b,$,b as N,v as te,w as se,x as ne,y as ae,A as P,Y as O,z as ie,B as le,o as _}from"./main-DUy5DFoq.js";import{S as R}from"./sidebar-section-mXpllayv.js";const oe=async()=>{try{const n=await fetch("/api/config");return n.ok?n.json():null}catch{return null}},U=async n=>{try{return(await fetch("/api/config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)})).ok}catch{return!1}},re=async()=>{try{const n=await fetch("/api/configs");return n.ok?(await n.json()).files:[]}catch{return[]}},ce=async n=>{try{const t=await fetch(`/api/configs?name=${encodeURIComponent(n)}`);return t.ok?(await t.json()).content:null}catch{return null}},H=async()=>{try{const n=await fetch("/api/env");return n.ok?await n.json():{exists:!1,exampleExists:!1,entries:[],missingKeys:[]}}catch{return{exists:!1,exampleExists:!1,entries:[],missingKeys:[]}}},de=async n=>{try{return(await fetch("/api/env",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({entries:n})})).ok}catch{return!1}},K=["phase","planDraft","ideaExtend","commitSuggest"],pe={phase:"Phase run",planDraft:"Plan draft",ideaExtend:"Idea extend",commitSuggest:"Commit suggest"},Y=110,J=140,B=160,V=110,he=()=>e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:d[3],paddingBottom:d[1]},children:[e.jsx("span",{style:{width:Y,flexShrink:0,fontSize:b.sm,opacity:.45},children:"Task"}),e.jsx("span",{style:{width:J,flexShrink:0,fontSize:b.sm,opacity:.45},children:"Agent"}),e.jsx("span",{style:{width:B,flexShrink:0,fontSize:b.sm,opacity:.45},children:"Model"}),e.jsx("span",{style:{width:V,flexShrink:0,fontSize:b.sm,opacity:.45},children:"Effort"})]}),ue=({taskKey:n,agentConfig:t,isLast:u,onSave:h})=>{const m=P[t.agent]??P["claude-code"],g=m.model,l=m.effort,[x,y]=p.useState(t.model??"");p.useEffect(()=>{y(t.model??"")},[t.model]);const v=c=>{var C;const f=c,k=P[f],w={agent:f};t.model&&(k.model===null||(C=k.model)!=null&&C.includes(t.model))&&(w.model=t.model),t.effort&&Array.isArray(k.effort)&&(w.effort=t.effort),h(n,w)},A=c=>{h(n,{...t,model:c||void 0})},j=()=>{h(n,{...t,model:x||void 0})},S=c=>{h(n,{...t,effort:c||void 0})};return e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:d[3],paddingBottom:d[2],paddingTop:d[2]},children:[e.jsx("span",{style:{width:Y,flexShrink:0,fontSize:b.sm,opacity:.65},children:pe[n]}),e.jsx(O,{size:"small",width:J,value:t.agent,onChange:v,options:ie.map(c=>({value:c,label:le[c]}))}),Array.isArray(g)?e.jsx(O,{size:"small",width:B,value:t.model??"",onChange:A,options:[{value:"",label:"Default"},...g.map(c=>({value:c,label:c}))]}):g===null?e.jsx(D,{size:"small",style:{width:B},value:x,placeholder:"Default model",onChange:c=>y(c.target.value),onBlur:j}):null,e.jsx("div",{style:{visibility:Array.isArray(l)?"visible":"hidden"},children:e.jsx(O,{size:"small",width:V,value:t.effort??"",onChange:S,options:[{value:"",label:"Default"},...(Array.isArray(l)?l:[]).map(c=>({value:c,label:c}))]})})]}),!u&&e.jsx(F,{})]})},fe=()=>{const n=p.useRef(null),[t,u]=p.useState(void 0),{iconDataUri:h,loading:m}=q(),[g,l]=p.useState(null),x=g??h,[y,v]=p.useState(!1),[A,j]=p.useState(""),[S,c]=p.useState(""),{toast:f}=X();p.useEffect(()=>{oe().then(i=>{u(i),(i==null?void 0:i.port)!==void 0&&j(String(i.port)),(i==null?void 0:i.projectName)!==void 0&&c(i.projectName)})},[]);const k=async(i,a)=>{const s=t==null?void 0:t.defaultAgents,o={phase:(s==null?void 0:s.phase)??I.phase,planDraft:(s==null?void 0:s.planDraft)??I.planDraft,ideaExtend:(s==null?void 0:s.ideaExtend)??I.ideaExtend,commitSuggest:(s==null?void 0:s.commitSuggest)??I.commitSuggest,[i]:a};await U({defaultAgents:o})?(u(E=>E&&{...E,defaultAgents:o}),f({title:"Saved",variant:"success"})):f({title:"Failed to save",variant:"error"})},w=async()=>{const i=Number(A);if(!t||!Number.isInteger(i)||i<=0||i===t.port)return;await U({port:i})?(u(s=>s&&{...s,port:i}),f({title:"Saved",variant:"success"})):f({title:"Failed to save",variant:"error"})},C=async()=>{const i=S.trim();if(!t||!i||i===t.projectName)return;await U({projectName:i})?(u(s=>s&&{...s,projectName:i}),c(i),f({title:"Saved",variant:"success"})):f({title:"Failed to save",variant:"error"})},L=async i=>{var o;const a=(o=i.target.files)==null?void 0:o[0];if(!a)return;v(!0);const s=new FileReader;s.onloadend=async()=>{const r=s.result,E=await ae(r);v(!1),E?(l(r),f({title:"Saved",variant:"success"})):f({title:"Failed to save",variant:"error"})},s.readAsDataURL(a)};return e.jsxs("div",{children:[e.jsx("div",{style:{marginBottom:d[6]},children:e.jsx("h2",{style:{margin:0},children:"Project Info"})}),t===void 0&&e.jsx("p",{children:"Loading…"}),t===null&&e.jsxs(M,{variant:"warning",children:["No papercamp/config.json found — run ",e.jsx("code",{children:"paper-camp init"})," in this directory first."]}),t&&e.jsxs(W,{size:"small",children:[e.jsxs("div",{style:{display:"flex",alignItems:"flex-end",gap:d[3],paddingBottom:d[3]},children:[e.jsx(D,{value:S,onChange:i=>c(i.target.value),onBlur:C,label:"Project Name"}),e.jsxs(Q,{size:"small",fillColor:"rgba(143, 185, 150, 0.25)",textColor:ee.accentGreenDark,children:["v",t.version]})]}),e.jsx(F,{}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:d[3],paddingBottom:d[3],paddingTop:d[3]},children:[x&&e.jsx("img",{src:x,alt:"Project icon",style:{width:40,height:40,objectFit:"contain",flexShrink:0,borderRadius:4}}),e.jsxs("div",{children:[e.jsx("input",{ref:n,type:"file",accept:".svg,.png,.jpg,.jpeg,.gif,.webp",onChange:L,style:{display:"none"}}),e.jsx(z,{variant:"secondary",size:"small",onClick:()=>{var i;return(i=n.current)==null?void 0:i.click()},disabled:y,children:y?"Uploading…":"Choose File"}),m&&e.jsx("p",{className:"text-sm",style:{opacity:.5,margin:`${d[1]} 0 0`},children:"Loading…"}),!m&&!x&&!y&&e.jsx("p",{className:"text-sm",style:{opacity:.45,margin:`${d[1]} 0 0`},children:"No icon set."})]})]}),e.jsx(F,{}),e.jsx("div",{style:{display:"flex",alignItems:"flex-end",gap:d[3],paddingBottom:d[3],paddingTop:d[3]},children:e.jsx(D,{type:"number",value:A,onChange:i=>j(i.target.value),onBlur:w,label:"Port",helperText:"Default for `paper-camp dev`. Does not affect the running server."})}),e.jsx(F,{}),e.jsx(he,{}),K.map((i,a)=>{var s;return e.jsx(ue,{taskKey:i,agentConfig:((s=t.defaultAgents)==null?void 0:s[i])??I[i],isLast:a===K.length-1,onSave:k},i)})]}),e.jsxs("p",{style:{opacity:.45,fontSize:b.sm,marginTop:d[4]},children:[e.jsx("strong",{children:"Initialized:"})," ",t?new Date(t.initializedAt).toLocaleString():"—"]})]})},me=n=>{try{const t=JSON.parse(n);return!t.scripts||typeof t.scripts!="object"?null:Object.entries(t.scripts).map(([u,h])=>({name:u,command:h}))}catch{return null}},ge=({fileName:n})=>{const[t,u]=p.useState(null),[h,m]=p.useState(!0);if(p.useEffect(()=>{m(!0),ce(n).then(l=>{u(l),m(!1)})},[n]),h)return e.jsx("p",{children:"Loading…"});if(t===null)return e.jsxs(M,{variant:"warning",children:["Could not load file — ",n," not found."]});const g=n==="package.json"?me(t):null;return e.jsxs("div",{children:[e.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:d[4]},children:e.jsx("h2",{style:{margin:0},children:n})}),g?e.jsx($,{data:g,columns:[{key:"name",header:"Script",cell:l=>e.jsx("span",{style:{fontFamily:N.mono},children:l.name}),width:4},{key:"command",header:"Command",cell:l=>e.jsx("span",{style:{fontFamily:N.mono},children:l.command})}]}):e.jsx(ne,{code:t,filename:n})]})},G=n=>/key|secret|token|password/i.test(n),xe=()=>{const[n,t]=p.useState(!0),[u,h]=p.useState([]),[m,g]=p.useState([]),[l,x]=p.useState(new Set),[y,v]=p.useState(!1),[A,j]=p.useState(!1),[S,c]=p.useState(null);p.useEffect(()=>{H().then(a=>{h(a.entries),g(a.missingKeys),t(!1)})},[]);const f=(a,s)=>{h(o=>o.map((r,E)=>E===a?{...r,...s}:r))},k=()=>h(a=>[...a,{key:"",value:""}]),w=a=>{h(s=>[...s,{key:a,value:""}]),g(s=>s.filter(o=>o!==a))},C=a=>{h(s=>s.filter((o,r)=>r!==a)),x(s=>{const o=new Set(s);return o.delete(a),o})},L=a=>x(s=>{const o=new Set(s);return o.has(a)?o.delete(a):o.add(a),o}),i=async()=>{const a=u.map(r=>({key:r.key.trim(),value:r.value,isSet:r.isSet})).filter(r=>r.key.length>0);if(new Set(a.map(r=>r.key)).size!==a.length){c("Duplicate keys are not allowed");return}c(null),v(!0);const o=await de(a.map(r=>({key:r.key,value:r.value,keep:!!r.isSet&&r.value===""})));v(!1),o?(h(a.map(r=>({key:r.key,value:"",isSet:!0}))),j(!0),setTimeout(()=>j(!1),2e3)):c("Failed to save .env")};return n?e.jsx("p",{children:"Loading…"}):e.jsxs("div",{children:[e.jsx("h2",{style:{margin:0,marginBottom:d[4]},children:"Environment Variables"}),S&&e.jsxs(M,{variant:"warning",children:["Could not save — ",S]}),m.length>0&&e.jsxs(W,{size:"small",accent:!0,accentColor:"amber",children:[e.jsx("p",{style:{margin:0,fontWeight:600},children:"Missing from .env"}),e.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:d[2],alignItems:"center"},children:[e.jsx("span",{children:"Present in .env.example but not set:"}),m.map(a=>e.jsxs(z,{variant:"secondary",size:"small",onClick:()=>w(a),children:["+ ",a]},a))]})]}),e.jsx($,{data:u,columns:[{key:"key",header:"Key",cell:(a,s)=>e.jsx(D,{value:a.key,placeholder:"KEY",style:{fontFamily:N.mono},onChange:o=>f(s,{key:o.target.value})}),width:6},{key:"value",header:"Value",cell:(a,s)=>{const o=G(a.key)&&!l.has(s);return e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:d[2]},children:[e.jsx(D,{type:o?"password":"text",value:a.value,placeholder:a.isSet?"•••••• set — leave blank to keep":"value",style:{fontFamily:N.mono,flex:1},onChange:r=>f(s,{value:r.target.value})}),G(a.key)&&e.jsx(z,{variant:"ghost",size:"small",onClick:()=>L(s),children:o?"Show":"Hide"})]})}},{key:"actions",header:"",width:2,cell:(a,s)=>e.jsx(te,{icon:e.jsx(se,{}),variant:"ghost",size:"small",label:"Remove variable",onClick:()=>C(s)})}]}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:d[3],marginTop:d[4]},children:[e.jsx(z,{variant:"secondary",size:"small",onClick:k,children:"+ Add variable"}),e.jsx(z,{variant:"primary",size:"small",onClick:i,disabled:y,children:y?"Saving…":"Save"}),A&&e.jsx("span",{className:"text-sm",style:{opacity:.6},children:"Saved"})]})]})},je=()=>{const n=T(t=>t.activeSettingsSection);return e.jsxs("div",{children:[e.jsx(Z,{children:"Settings"}),n==="general"&&e.jsx(fe,{}),n==="env"&&e.jsx(xe,{}),n.startsWith("config:")&&e.jsx(ge,{fileName:n.slice(7)})]})},Se=()=>{const n=T(l=>l.activeSettingsSection),t=T(l=>l.setActiveSettingsSection),u=T(l=>l.settingsConfigFiles),h=T(l=>l.setSettingsConfigFiles),[m,g]=p.useState(!1);return p.useEffect(()=>{re().then(h),H().then(l=>g(l.exists||l.exampleExists))},[h]),e.jsxs(e.Fragment,{children:[e.jsx(R,{label:"General",children:e.jsx(_,{size:"small",active:n==="general",onClick:()=>t("general"),children:"Project Info"})}),m&&e.jsx(R,{label:"Environment",children:e.jsx(_,{size:"small",active:n==="env",onClick:()=>t("env"),children:"Env Vars"})}),u.length>0&&e.jsx(R,{label:"Config Files",children:u.map(l=>e.jsx(_,{size:"small",active:n===`config:${l}`,onClick:()=>t(`config:${l}`),children:l},l))})]})};export{je as SettingsPage,Se as SettingsSidebar};
2
+ //# sourceMappingURL=index-C0wWs5ba.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-C0wWs5ba.js","sources":["../../../src/app/services/system/config-api.ts","../../../src/app/services/system/config-files-api.ts","../../../src/app/services/system/env-api.ts","../../../src/app/features/settings/settings-page.tsx","../../../src/app/features/settings/components/settings-sidebar.tsx"],"sourcesContent":["import type { AgentId, DefaultAgentsMap, PaperCampConfig } from '@/types/index';\n\nexport const fetchConfig = async (): Promise<PaperCampConfig | null> => {\n try {\n const response = await fetch('/api/config');\n if (!response.ok) return null;\n return response.json();\n } catch {\n return null;\n }\n};\n\nexport const saveConfig = async (updates: {\n port?: number;\n projectName?: string;\n defaultAgent?: AgentId;\n defaultAgents?: DefaultAgentsMap;\n}): Promise<boolean> => {\n try {\n const response = await fetch('/api/config', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(updates),\n });\n return response.ok;\n } catch {\n return false;\n }\n};\n","export const fetchConfigs = async (): Promise<string[]> => {\n try {\n const response = await fetch('/api/configs');\n if (!response.ok) return [];\n const data = (await response.json()) as { files: string[] };\n return data.files;\n } catch {\n return [];\n }\n};\n\nexport const fetchConfigFile = async (name: string): Promise<string | null> => {\n try {\n const response = await fetch(`/api/configs?name=${encodeURIComponent(name)}`);\n if (!response.ok) return null;\n const data = (await response.json()) as { name: string; content: string };\n return data.content;\n } catch {\n return null;\n }\n};\n","import type { EnvEntry } from '@/types/index';\n\nexport interface EnvFile {\n exists: boolean;\n exampleExists: boolean;\n entries: EnvEntry[];\n missingKeys: string[];\n}\n\nexport const fetchEnv = async (): Promise<EnvFile> => {\n try {\n const response = await fetch('/api/env');\n if (!response.ok) return { exists: false, exampleExists: false, entries: [], missingKeys: [] };\n return await response.json();\n } catch {\n return { exists: false, exampleExists: false, entries: [], missingKeys: [] };\n }\n};\n\n/** `keep` preserves a set key's existing value server-side (the client never has\n * it, since GET withholds secret values). */\nexport type EnvEntryInput = { key: string; value: string; keep?: boolean };\n\nexport const saveEnv = async (entries: EnvEntryInput[]): Promise<boolean> => {\n try {\n const response = await fetch('/api/env', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ entries }),\n });\n return response.ok;\n } catch {\n return false;\n }\n};\n","import { PageTitle } from '@/app/components/page-title';\nimport { useProjectIdentity } from '@/app/hooks';\nimport {\n fetchConfig,\n fetchConfigFile,\n fetchEnv,\n saveConfig,\n saveEnv,\n uploadIcon,\n} from '@/app/services/system';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { color, fontFamily, fontSize, space } from '@/app/styles/tokens';\nimport {\n AGENT_IDS,\n AGENT_LABELS,\n AGENT_OPTIONS,\n type AgentConfig,\n type AgentId,\n DEFAULT_AGENTS,\n type DefaultAgentsMap,\n type EnvEntry,\n type PaperCampConfig,\n} from '@/types/index';\nimport {\n Alert,\n Button,\n Card,\n CloseIcon,\n CodeBlock,\n Divider,\n IconButton,\n Input,\n Select,\n Stamp,\n Table,\n useToast,\n} from '@dendelion/paper-ui';\nimport { useEffect, useRef, useState } from 'react';\n\nconst TASK_TYPE_KEYS = ['phase', 'planDraft', 'ideaExtend', 'commitSuggest'] as const;\ntype TaskTypeKey = (typeof TASK_TYPE_KEYS)[number];\n\nconst TASK_TYPE_LABELS: Record<TaskTypeKey, string> = {\n phase: 'Phase run',\n planDraft: 'Plan draft',\n ideaExtend: 'Idea extend',\n commitSuggest: 'Commit suggest',\n};\n\ninterface AgentTaskRowProps {\n taskKey: TaskTypeKey;\n agentConfig: AgentConfig;\n isLast: boolean;\n onSave: (key: TaskTypeKey, config: AgentConfig) => Promise<void>;\n}\n\nconst TASK_COLUMN_WIDTH = 110;\nconst AGENT_COLUMN_WIDTH = 140;\nconst MODEL_COLUMN_WIDTH = 160;\nconst EFFORT_COLUMN_WIDTH = 110;\n\nconst AgentTaskRowHeader = () => (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: space[3],\n paddingBottom: space[1],\n }}\n >\n <span style={{ width: TASK_COLUMN_WIDTH, flexShrink: 0, fontSize: fontSize.sm, opacity: 0.45 }}>\n Task\n </span>\n <span\n style={{ width: AGENT_COLUMN_WIDTH, flexShrink: 0, fontSize: fontSize.sm, opacity: 0.45 }}\n >\n Agent\n </span>\n <span\n style={{ width: MODEL_COLUMN_WIDTH, flexShrink: 0, fontSize: fontSize.sm, opacity: 0.45 }}\n >\n Model\n </span>\n <span\n style={{ width: EFFORT_COLUMN_WIDTH, flexShrink: 0, fontSize: fontSize.sm, opacity: 0.45 }}\n >\n Effort\n </span>\n </div>\n);\n\nconst AgentTaskRow = ({ taskKey, agentConfig, isLast, onSave }: AgentTaskRowProps) => {\n // Fall back if the config carries an unknown agent id — never white-screen the page.\n const opts = AGENT_OPTIONS[agentConfig.agent] ?? AGENT_OPTIONS['claude-code'];\n const modelOpts = opts.model;\n const effortOpts = opts.effort;\n const [localModel, setLocalModel] = useState(agentConfig.model ?? '');\n\n useEffect(() => {\n setLocalModel(agentConfig.model ?? '');\n }, [agentConfig.model]);\n\n const handleAgentChange = (v: string) => {\n const newId = v as AgentId;\n const newOpts = AGENT_OPTIONS[newId];\n const newConfig: AgentConfig = { agent: newId };\n // Only carry the model over if the new agent accepts it — otherwise a claude\n // model like 'opus' would leak into opencode and fail at launch.\n if (\n agentConfig.model &&\n (newOpts.model === null || newOpts.model?.includes(agentConfig.model))\n ) {\n newConfig.model = agentConfig.model;\n }\n if (agentConfig.effort && Array.isArray(newOpts.effort)) newConfig.effort = agentConfig.effort;\n onSave(taskKey, newConfig);\n };\n\n const handleModelSelectChange = (v: string) => {\n onSave(taskKey, { ...agentConfig, model: v || undefined });\n };\n\n const handleModelInputBlur = () => {\n onSave(taskKey, { ...agentConfig, model: localModel || undefined });\n };\n\n const handleEffortChange = (v: string) => {\n onSave(taskKey, { ...agentConfig, effort: v || undefined });\n };\n\n return (\n <>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: space[3],\n paddingBottom: space[2],\n paddingTop: space[2],\n }}\n >\n <span\n style={{ width: TASK_COLUMN_WIDTH, flexShrink: 0, fontSize: fontSize.sm, opacity: 0.65 }}\n >\n {TASK_TYPE_LABELS[taskKey]}\n </span>\n <Select\n size=\"small\"\n width={AGENT_COLUMN_WIDTH}\n value={agentConfig.agent}\n onChange={handleAgentChange}\n options={AGENT_IDS.map((id) => ({ value: id, label: AGENT_LABELS[id] }))}\n />\n {Array.isArray(modelOpts) ? (\n <Select\n size=\"small\"\n width={MODEL_COLUMN_WIDTH}\n value={agentConfig.model ?? ''}\n onChange={handleModelSelectChange}\n options={[\n { value: '', label: 'Default' },\n ...modelOpts.map((m) => ({ value: m, label: m })),\n ]}\n />\n ) : modelOpts === null ? (\n <Input\n size=\"small\"\n style={{ width: MODEL_COLUMN_WIDTH }}\n value={localModel}\n placeholder=\"Default model\"\n onChange={(e) => setLocalModel(e.target.value)}\n onBlur={handleModelInputBlur}\n />\n ) : null}\n {/* Reserve the effort slot even when the agent has no effort options, so\n switching agents doesn't change the control count and shift the row. */}\n <div style={{ visibility: Array.isArray(effortOpts) ? 'visible' : 'hidden' }}>\n <Select\n size=\"small\"\n width={EFFORT_COLUMN_WIDTH}\n value={agentConfig.effort ?? ''}\n onChange={handleEffortChange}\n options={[\n { value: '', label: 'Default' },\n ...(Array.isArray(effortOpts) ? effortOpts : []).map((e) => ({ value: e, label: e })),\n ]}\n />\n </div>\n </div>\n {!isLast && <Divider />}\n </>\n );\n};\n\nconst GeneralSection = () => {\n const fileRef = useRef<HTMLInputElement>(null);\n const [config, setConfig] = useState<PaperCampConfig | null | undefined>(undefined);\n const { iconDataUri: fetchedIconDataUri, loading: identityLoading } = useProjectIdentity();\n const [uploadedIconDataUri, setUploadedIconDataUri] = useState<string | null>(null);\n const iconDataUri = uploadedIconDataUri ?? fetchedIconDataUri;\n const [uploading, setUploading] = useState(false);\n const [portInput, setPortInput] = useState('');\n const [nameInput, setNameInput] = useState('');\n const { toast } = useToast();\n\n useEffect(() => {\n fetchConfig().then((c) => {\n setConfig(c);\n if (c?.port !== undefined) setPortInput(String(c.port));\n if (c?.projectName !== undefined) setNameInput(c.projectName);\n });\n }, []);\n\n const handleSaveAgentConfig = async (key: TaskTypeKey, newEntry: AgentConfig) => {\n const current = config?.defaultAgents;\n const updated: DefaultAgentsMap = {\n phase: current?.phase ?? DEFAULT_AGENTS.phase,\n planDraft: current?.planDraft ?? DEFAULT_AGENTS.planDraft,\n ideaExtend: current?.ideaExtend ?? DEFAULT_AGENTS.ideaExtend,\n commitSuggest: current?.commitSuggest ?? DEFAULT_AGENTS.commitSuggest,\n [key]: newEntry,\n };\n const ok = await saveConfig({ defaultAgents: updated });\n if (ok) {\n setConfig((prev) => (prev ? { ...prev, defaultAgents: updated } : prev));\n toast({ title: 'Saved', variant: 'success' });\n } else {\n toast({ title: 'Failed to save', variant: 'error' });\n }\n };\n\n const handleSavePort = async () => {\n const port = Number(portInput);\n if (!config || !Number.isInteger(port) || port <= 0 || port === config.port) return;\n const ok = await saveConfig({ port });\n if (ok) {\n setConfig((prev) => (prev ? { ...prev, port } : prev));\n toast({ title: 'Saved', variant: 'success' });\n } else {\n toast({ title: 'Failed to save', variant: 'error' });\n }\n };\n\n const handleSaveName = async () => {\n const projectName = nameInput.trim();\n if (!config || !projectName || projectName === config.projectName) return;\n const ok = await saveConfig({ projectName });\n if (ok) {\n setConfig((prev) => (prev ? { ...prev, projectName } : prev));\n setNameInput(projectName);\n toast({ title: 'Saved', variant: 'success' });\n } else {\n toast({ title: 'Failed to save', variant: 'error' });\n }\n };\n\n const handleFile = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n setUploading(true);\n const reader = new FileReader();\n reader.onloadend = async () => {\n const dataUri = reader.result as string;\n const ok = await uploadIcon(dataUri);\n setUploading(false);\n if (ok) {\n setUploadedIconDataUri(dataUri);\n toast({ title: 'Saved', variant: 'success' });\n } else {\n toast({ title: 'Failed to save', variant: 'error' });\n }\n };\n reader.readAsDataURL(file);\n };\n\n return (\n <div>\n <div style={{ marginBottom: space[6] }}>\n <h2 style={{ margin: 0 }}>Project Info</h2>\n </div>\n {config === undefined && <p>Loading…</p>}\n {config === null && (\n <Alert variant=\"warning\">\n No papercamp/config.json found — run <code>paper-camp init</code> in this directory first.\n </Alert>\n )}\n {config && (\n <Card size=\"small\">\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-end',\n gap: space[3],\n paddingBottom: space[3],\n }}\n >\n <Input\n value={nameInput}\n onChange={(e) => setNameInput(e.target.value)}\n onBlur={handleSaveName}\n label=\"Project Name\"\n />\n <Stamp\n size=\"small\"\n fillColor=\"rgba(143, 185, 150, 0.25)\"\n textColor={color.accentGreenDark}\n >\n v{config.version}\n </Stamp>\n </div>\n <Divider />\n\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: space[3],\n paddingBottom: space[3],\n paddingTop: space[3],\n }}\n >\n {iconDataUri && (\n <img\n src={iconDataUri}\n alt=\"Project icon\"\n style={{\n width: 40,\n height: 40,\n objectFit: 'contain',\n flexShrink: 0,\n borderRadius: 4,\n }}\n />\n )}\n <div>\n {/* paper-ui has no file-input component, so this raw input is intentional */}\n <input\n ref={fileRef}\n type=\"file\"\n accept=\".svg,.png,.jpg,.jpeg,.gif,.webp\"\n onChange={handleFile}\n style={{ display: 'none' }}\n />\n <Button\n variant=\"secondary\"\n size=\"small\"\n onClick={() => fileRef.current?.click()}\n disabled={uploading}\n >\n {uploading ? 'Uploading…' : 'Choose File'}\n </Button>\n {identityLoading && (\n <p className=\"text-sm\" style={{ opacity: 0.5, margin: `${space[1]} 0 0` }}>\n Loading…\n </p>\n )}\n {!identityLoading && !iconDataUri && !uploading && (\n <p className=\"text-sm\" style={{ opacity: 0.45, margin: `${space[1]} 0 0` }}>\n No icon set.\n </p>\n )}\n </div>\n </div>\n <Divider />\n\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-end',\n gap: space[3],\n paddingBottom: space[3],\n paddingTop: space[3],\n }}\n >\n <Input\n type=\"number\"\n value={portInput}\n onChange={(e) => setPortInput(e.target.value)}\n onBlur={handleSavePort}\n label=\"Port\"\n helperText=\"Default for `paper-camp dev`. Does not affect the running server.\"\n />\n </div>\n <Divider />\n\n <AgentTaskRowHeader />\n {TASK_TYPE_KEYS.map((key, idx) => (\n <AgentTaskRow\n key={key}\n taskKey={key}\n agentConfig={config.defaultAgents?.[key] ?? DEFAULT_AGENTS[key]}\n isLast={idx === TASK_TYPE_KEYS.length - 1}\n onSave={handleSaveAgentConfig}\n />\n ))}\n </Card>\n )}\n\n <p style={{ opacity: 0.45, fontSize: fontSize.sm, marginTop: space[4] }}>\n <strong>Initialized:</strong>{' '}\n {config ? new Date(config.initializedAt).toLocaleString() : '—'}\n </p>\n </div>\n );\n};\n\ninterface ScriptRow {\n name: string;\n command: string;\n}\n\nconst parsePackageScripts = (content: string): ScriptRow[] | null => {\n try {\n const parsed = JSON.parse(content) as { scripts?: Record<string, string> };\n if (!parsed.scripts || typeof parsed.scripts !== 'object') return null;\n return Object.entries(parsed.scripts).map(([name, command]) => ({ name, command }));\n } catch {\n return null;\n }\n};\n\nconst ConfigEditorSection = ({ fileName }: { fileName: string }) => {\n const [content, setContent] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n setLoading(true);\n fetchConfigFile(fileName).then((c) => {\n setContent(c);\n setLoading(false);\n });\n }, [fileName]);\n\n if (loading) return <p>Loading…</p>;\n if (content === null) {\n return <Alert variant=\"warning\">Could not load file — {fileName} not found.</Alert>;\n }\n\n const scripts = fileName === 'package.json' ? parsePackageScripts(content) : null;\n\n return (\n <div>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: space[4],\n }}\n >\n <h2 style={{ margin: 0 }}>{fileName}</h2>\n </div>\n {scripts ? (\n <Table\n data={scripts}\n columns={[\n {\n key: 'name',\n header: 'Script',\n cell: (row: ScriptRow) => (\n <span style={{ fontFamily: fontFamily.mono }}>{row.name}</span>\n ),\n width: 4,\n },\n {\n key: 'command',\n header: 'Command',\n cell: (row: ScriptRow) => (\n <span style={{ fontFamily: fontFamily.mono }}>{row.command}</span>\n ),\n },\n ]}\n />\n ) : (\n <CodeBlock code={content} filename={fileName} />\n )}\n </div>\n );\n};\n\nconst isSecretKey = (key: string) => /key|secret|token|password/i.test(key);\n\nconst EnvSection = () => {\n const [loading, setLoading] = useState(true);\n const [rows, setRows] = useState<EnvEntry[]>([]);\n const [missingKeys, setMissingKeys] = useState<string[]>([]);\n const [revealed, setRevealed] = useState<Set<number>>(new Set());\n const [saving, setSaving] = useState(false);\n const [saved, setSaved] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n fetchEnv().then((env) => {\n setRows(env.entries);\n setMissingKeys(env.missingKeys);\n setLoading(false);\n });\n }, []);\n\n const updateRow = (index: number, patch: Partial<EnvEntry>) => {\n setRows((prev) => prev.map((row, i) => (i === index ? { ...row, ...patch } : row)));\n };\n\n const handleAddRow = () => setRows((prev) => [...prev, { key: '', value: '' }]);\n\n const handleAddMissingKey = (key: string) => {\n setRows((prev) => [...prev, { key, value: '' }]);\n setMissingKeys((prev) => prev.filter((k) => k !== key));\n };\n\n const handleDeleteRow = (index: number) => {\n setRows((prev) => prev.filter((_, i) => i !== index));\n setRevealed((prev) => {\n const next = new Set(prev);\n next.delete(index);\n return next;\n });\n };\n\n const toggleReveal = (index: number) =>\n setRevealed((prev) => {\n const next = new Set(prev);\n if (next.has(index)) next.delete(index);\n else next.add(index);\n return next;\n });\n\n const handleSave = async () => {\n const trimmed = rows\n .map((row) => ({ key: row.key.trim(), value: row.value, isSet: row.isSet }))\n .filter((row) => row.key.length > 0);\n const keys = new Set(trimmed.map((row) => row.key));\n if (keys.size !== trimmed.length) {\n setError('Duplicate keys are not allowed');\n return;\n }\n setError(null);\n setSaving(true);\n // A set key left blank keeps its existing (withheld) value; a typed value\n // replaces it. The server never received the old secret, so it backfills.\n const ok = await saveEnv(\n trimmed.map((row) => ({\n key: row.key,\n value: row.value,\n keep: !!row.isSet && row.value === '',\n })),\n );\n setSaving(false);\n if (ok) {\n // Everything just saved now exists with a withheld value — reflect that.\n setRows(trimmed.map((row) => ({ key: row.key, value: '', isSet: true })));\n setSaved(true);\n setTimeout(() => setSaved(false), 2000);\n } else {\n setError('Failed to save .env');\n }\n };\n\n if (loading) return <p>Loading…</p>;\n\n return (\n <div>\n <h2 style={{ margin: 0, marginBottom: space[4] }}>Environment Variables</h2>\n {error && <Alert variant=\"warning\">Could not save — {error}</Alert>}\n {missingKeys.length > 0 && (\n <Card size=\"small\" accent accentColor=\"amber\">\n <p style={{ margin: 0, fontWeight: 600 }}>Missing from .env</p>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: space[2], alignItems: 'center' }}>\n <span>Present in .env.example but not set:</span>\n {missingKeys.map((key) => (\n <Button\n key={key}\n variant=\"secondary\"\n size=\"small\"\n onClick={() => handleAddMissingKey(key)}\n >\n + {key}\n </Button>\n ))}\n </div>\n </Card>\n )}\n <Table\n data={rows}\n columns={[\n {\n key: 'key',\n header: 'Key',\n cell: (row: EnvEntry, index: number) => (\n <Input\n value={row.key}\n placeholder=\"KEY\"\n style={{ fontFamily: fontFamily.mono }}\n onChange={(e) => updateRow(index, { key: e.target.value })}\n />\n ),\n width: 6,\n },\n {\n key: 'value',\n header: 'Value',\n cell: (row: EnvEntry, index: number) => {\n const masked = isSecretKey(row.key) && !revealed.has(index);\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: space[2] }}>\n <Input\n type={masked ? 'password' : 'text'}\n value={row.value}\n placeholder={row.isSet ? '•••••• set — leave blank to keep' : 'value'}\n style={{ fontFamily: fontFamily.mono, flex: 1 }}\n onChange={(e) => updateRow(index, { value: e.target.value })}\n />\n {isSecretKey(row.key) && (\n <Button variant=\"ghost\" size=\"small\" onClick={() => toggleReveal(index)}>\n {masked ? 'Show' : 'Hide'}\n </Button>\n )}\n </div>\n );\n },\n },\n {\n key: 'actions',\n header: '',\n width: 2,\n cell: (_row: EnvEntry, index: number) => (\n <IconButton\n icon={<CloseIcon />}\n variant=\"ghost\"\n size=\"small\"\n label=\"Remove variable\"\n onClick={() => handleDeleteRow(index)}\n />\n ),\n },\n ]}\n />\n <div style={{ display: 'flex', alignItems: 'center', gap: space[3], marginTop: space[4] }}>\n <Button variant=\"secondary\" size=\"small\" onClick={handleAddRow}>\n + Add variable\n </Button>\n <Button variant=\"primary\" size=\"small\" onClick={handleSave} disabled={saving}>\n {saving ? 'Saving…' : 'Save'}\n </Button>\n {saved && (\n <span className=\"text-sm\" style={{ opacity: 0.6 }}>\n Saved\n </span>\n )}\n </div>\n </div>\n );\n};\n\nexport const SettingsPage = () => {\n const activeSection = useAppStore((s) => s.activeSettingsSection);\n\n return (\n <div>\n <PageTitle>Settings</PageTitle>\n {activeSection === 'general' && <GeneralSection />}\n {activeSection === 'env' && <EnvSection />}\n {activeSection.startsWith('config:') && (\n <ConfigEditorSection fileName={activeSection.slice('config:'.length)} />\n )}\n </div>\n );\n};\n","import { fetchConfigs, fetchEnv } from '@/app/services/system';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { ListItem } from '@dendelion/paper-ui';\nimport { useEffect, useState } from 'react';\nimport { SidebarSection } from '../../plans/components/sidebar-section';\n\nexport const SettingsSidebar = () => {\n const activeSection = useAppStore((s) => s.activeSettingsSection);\n const setActiveSection = useAppStore((s) => s.setActiveSettingsSection);\n const configFiles = useAppStore((s) => s.settingsConfigFiles);\n const setConfigFiles = useAppStore((s) => s.setSettingsConfigFiles);\n const [showEnv, setShowEnv] = useState(false);\n\n useEffect(() => {\n fetchConfigs().then(setConfigFiles);\n fetchEnv().then((env) => setShowEnv(env.exists || env.exampleExists));\n }, [setConfigFiles]);\n\n return (\n <>\n <SidebarSection label=\"General\">\n <ListItem\n size=\"small\"\n active={activeSection === 'general'}\n onClick={() => setActiveSection('general')}\n >\n Project Info\n </ListItem>\n </SidebarSection>\n\n {showEnv && (\n <SidebarSection label=\"Environment\">\n <ListItem\n size=\"small\"\n active={activeSection === 'env'}\n onClick={() => setActiveSection('env')}\n >\n Env Vars\n </ListItem>\n </SidebarSection>\n )}\n\n {configFiles.length > 0 && (\n <SidebarSection label=\"Config Files\">\n {configFiles.map((name) => (\n <ListItem\n key={name}\n size=\"small\"\n active={activeSection === `config:${name}`}\n onClick={() => setActiveSection(`config:${name}`)}\n >\n {name}\n </ListItem>\n ))}\n </SidebarSection>\n )}\n </>\n );\n};\n"],"names":["fetchConfig","response","saveConfig","updates","fetchConfigs","fetchConfigFile","name","fetchEnv","saveEnv","entries","TASK_TYPE_KEYS","TASK_TYPE_LABELS","TASK_COLUMN_WIDTH","AGENT_COLUMN_WIDTH","MODEL_COLUMN_WIDTH","EFFORT_COLUMN_WIDTH","AgentTaskRowHeader","jsxs","space","jsx","fontSize","AgentTaskRow","taskKey","agentConfig","isLast","onSave","opts","AGENT_OPTIONS","modelOpts","effortOpts","localModel","setLocalModel","useState","useEffect","handleAgentChange","v","newId","newOpts","newConfig","_a","handleModelSelectChange","handleModelInputBlur","handleEffortChange","Fragment","Select","AGENT_IDS","id","AGENT_LABELS","m","Input","e","Divider","GeneralSection","fileRef","useRef","config","setConfig","fetchedIconDataUri","identityLoading","useProjectIdentity","uploadedIconDataUri","setUploadedIconDataUri","iconDataUri","uploading","setUploading","portInput","setPortInput","nameInput","setNameInput","toast","useToast","c","handleSaveAgentConfig","key","newEntry","current","updated","DEFAULT_AGENTS","prev","handleSavePort","port","handleSaveName","projectName","handleFile","file","reader","dataUri","ok","uploadIcon","Alert","Card","Stamp","color","Button","idx","parsePackageScripts","content","parsed","command","ConfigEditorSection","fileName","setContent","loading","setLoading","scripts","Table","row","fontFamily","CodeBlock","isSecretKey","EnvSection","rows","setRows","missingKeys","setMissingKeys","revealed","setRevealed","saving","setSaving","saved","setSaved","error","setError","env","updateRow","index","patch","i","handleAddRow","handleAddMissingKey","k","handleDeleteRow","_","next","toggleReveal","handleSave","trimmed","masked","_row","IconButton","CloseIcon","SettingsPage","activeSection","useAppStore","s","PageTitle","SettingsSidebar","setActiveSection","configFiles","setConfigFiles","showEnv","setShowEnv","SidebarSection","ListItem"],"mappings":"iRAEO,MAAMA,GAAc,SAA6C,CACtE,GAAI,CACF,MAAMC,EAAW,MAAM,MAAM,aAAa,EAC1C,OAAKA,EAAS,GACPA,EAAS,KAAA,EADS,IAE3B,MAAQ,CACN,OAAO,IACT,CACF,EAEaC,EAAa,MAAOC,GAKT,CACtB,GAAI,CAMF,OALiB,MAAM,MAAM,cAAe,CAC1C,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAA,EAC3B,KAAM,KAAK,UAAUA,CAAO,CAAA,CAC7B,GACe,EAClB,MAAQ,CACN,MAAO,EACT,CACF,EC5BaC,GAAe,SAA+B,CACzD,GAAI,CACF,MAAMH,EAAW,MAAM,MAAM,cAAc,EAC3C,OAAKA,EAAS,IACA,MAAMA,EAAS,KAAA,GACjB,MAFa,CAAA,CAG3B,MAAQ,CACN,MAAO,CAAA,CACT,CACF,EAEaI,GAAkB,MAAOC,GAAyC,CAC7E,GAAI,CACF,MAAML,EAAW,MAAM,MAAM,qBAAqB,mBAAmBK,CAAI,CAAC,EAAE,EAC5E,OAAKL,EAAS,IACA,MAAMA,EAAS,KAAA,GACjB,QAFa,IAG3B,MAAQ,CACN,OAAO,IACT,CACF,ECXaM,EAAW,SAA8B,CACpD,GAAI,CACF,MAAMN,EAAW,MAAM,MAAM,UAAU,EACvC,OAAKA,EAAS,GACP,MAAMA,EAAS,KAAA,EADG,CAAE,OAAQ,GAAO,cAAe,GAAO,QAAS,GAAI,YAAa,CAAA,CAAC,CAE7F,MAAQ,CACN,MAAO,CAAE,OAAQ,GAAO,cAAe,GAAO,QAAS,CAAA,EAAI,YAAa,EAAC,CAC3E,CACF,EAMaO,GAAU,MAAOC,GAA+C,CAC3E,GAAI,CAMF,OALiB,MAAM,MAAM,WAAY,CACvC,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAA,EAC3B,KAAM,KAAK,UAAU,CAAE,QAAAA,EAAS,CAAA,CACjC,GACe,EAClB,MAAQ,CACN,MAAO,EACT,CACF,ECKMC,EAAiB,CAAC,QAAS,YAAa,aAAc,eAAe,EAGrEC,GAAgD,CACpD,MAAO,YACP,UAAW,aACX,WAAY,cACZ,cAAe,gBACjB,EASMC,EAAoB,IACpBC,EAAqB,IACrBC,EAAqB,IACrBC,EAAsB,IAEtBC,GAAqB,IACzBC,EAAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,IAAKC,EAAM,CAAC,EACZ,cAAeA,EAAM,CAAC,CAAA,EAGxB,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,MAAOP,EAAmB,WAAY,EAAG,SAAUQ,EAAS,GAAI,QAAS,GAAA,EAAQ,SAAA,OAEhG,EACAD,EAAAA,IAAC,OAAA,CACC,MAAO,CAAE,MAAON,EAAoB,WAAY,EAAG,SAAUO,EAAS,GAAI,QAAS,GAAA,EACpF,SAAA,OAAA,CAAA,EAGDD,EAAAA,IAAC,OAAA,CACC,MAAO,CAAE,MAAOL,EAAoB,WAAY,EAAG,SAAUM,EAAS,GAAI,QAAS,GAAA,EACpF,SAAA,OAAA,CAAA,EAGDD,EAAAA,IAAC,OAAA,CACC,MAAO,CAAE,MAAOJ,EAAqB,WAAY,EAAG,SAAUK,EAAS,GAAI,QAAS,GAAA,EACrF,SAAA,QAAA,CAAA,CAED,CAAA,CACF,EAGIC,GAAe,CAAC,CAAE,QAAAC,EAAS,YAAAC,EAAa,OAAAC,EAAQ,OAAAC,KAAgC,CAEpF,MAAMC,EAAOC,EAAcJ,EAAY,KAAK,GAAKI,EAAc,aAAa,EACtEC,EAAYF,EAAK,MACjBG,EAAaH,EAAK,OAClB,CAACI,EAAYC,CAAa,EAAIC,EAAAA,SAAST,EAAY,OAAS,EAAE,EAEpEU,EAAAA,UAAU,IAAM,CACdF,EAAcR,EAAY,OAAS,EAAE,CACvC,EAAG,CAACA,EAAY,KAAK,CAAC,EAEtB,MAAMW,EAAqBC,GAAc,OACvC,MAAMC,EAAQD,EACRE,EAAUV,EAAcS,CAAK,EAC7BE,EAAyB,CAAE,MAAOF,CAAA,EAItCb,EAAY,QACXc,EAAQ,QAAU,OAAQE,EAAAF,EAAQ,QAAR,MAAAE,EAAe,SAAShB,EAAY,UAE/De,EAAU,MAAQf,EAAY,OAE5BA,EAAY,QAAU,MAAM,QAAQc,EAAQ,MAAM,IAAGC,EAAU,OAASf,EAAY,QACxFE,EAAOH,EAASgB,CAAS,CAC3B,EAEME,EAA2BL,GAAc,CAC7CV,EAAOH,EAAS,CAAE,GAAGC,EAAa,MAAOY,GAAK,OAAW,CAC3D,EAEMM,EAAuB,IAAM,CACjChB,EAAOH,EAAS,CAAE,GAAGC,EAAa,MAAOO,GAAc,OAAW,CACpE,EAEMY,EAAsBP,GAAc,CACxCV,EAAOH,EAAS,CAAE,GAAGC,EAAa,OAAQY,GAAK,OAAW,CAC5D,EAEA,OACElB,EAAAA,KAAA0B,WAAA,CACE,SAAA,CAAA1B,EAAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,IAAKC,EAAM,CAAC,EACZ,cAAeA,EAAM,CAAC,EACtB,WAAYA,EAAM,CAAC,CAAA,EAGrB,SAAA,CAAAC,EAAAA,IAAC,OAAA,CACC,MAAO,CAAE,MAAOP,EAAmB,WAAY,EAAG,SAAUQ,EAAS,GAAI,QAAS,GAAA,EAEjF,YAAiBE,CAAO,CAAA,CAAA,EAE3BH,EAAAA,IAACyB,EAAA,CACC,KAAK,QACL,MAAO/B,EACP,MAAOU,EAAY,MACnB,SAAUW,EACV,QAASW,GAAU,IAAKC,IAAQ,CAAE,MAAOA,EAAI,MAAOC,GAAaD,CAAE,CAAA,EAAI,CAAA,CAAA,EAExE,MAAM,QAAQlB,CAAS,EACtBT,EAAAA,IAACyB,EAAA,CACC,KAAK,QACL,MAAO9B,EACP,MAAOS,EAAY,OAAS,GAC5B,SAAUiB,EACV,QAAS,CACP,CAAE,MAAO,GAAI,MAAO,SAAA,EACpB,GAAGZ,EAAU,IAAKoB,IAAO,CAAE,MAAOA,EAAG,MAAOA,GAAI,CAAA,CAClD,CAAA,EAEApB,IAAc,KAChBT,EAAAA,IAAC8B,EAAA,CACC,KAAK,QACL,MAAO,CAAE,MAAOnC,CAAA,EAChB,MAAOgB,EACP,YAAY,gBACZ,SAAWoB,GAAMnB,EAAcmB,EAAE,OAAO,KAAK,EAC7C,OAAQT,CAAA,CAAA,EAER,KAGJtB,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,WAAY,MAAM,QAAQU,CAAU,EAAI,UAAY,QAAA,EAChE,SAAAV,EAAAA,IAACyB,EAAA,CACC,KAAK,QACL,MAAO7B,EACP,MAAOQ,EAAY,QAAU,GAC7B,SAAUmB,EACV,QAAS,CACP,CAAE,MAAO,GAAI,MAAO,SAAA,EACpB,IAAI,MAAM,QAAQb,CAAU,EAAIA,EAAa,CAAA,GAAI,IAAKqB,IAAO,CAAE,MAAOA,EAAG,MAAOA,GAAI,CAAA,CACtF,CAAA,CACF,CACF,CAAA,CAAA,CAAA,EAED,CAAC1B,GAAUL,MAACgC,EAAA,CAAA,CAAQ,CAAA,EACvB,CAEJ,EAEMC,GAAiB,IAAM,CAC3B,MAAMC,EAAUC,EAAAA,OAAyB,IAAI,EACvC,CAACC,EAAQC,CAAS,EAAIxB,EAAAA,SAA6C,MAAS,EAC5E,CAAE,YAAayB,EAAoB,QAASC,CAAA,EAAoBC,EAAA,EAChE,CAACC,EAAqBC,CAAsB,EAAI7B,EAAAA,SAAwB,IAAI,EAC5E8B,EAAcF,GAAuBH,EACrC,CAACM,EAAWC,CAAY,EAAIhC,EAAAA,SAAS,EAAK,EAC1C,CAACiC,EAAWC,CAAY,EAAIlC,EAAAA,SAAS,EAAE,EACvC,CAACmC,EAAWC,CAAY,EAAIpC,EAAAA,SAAS,EAAE,EACvC,CAAE,MAAAqC,CAAA,EAAUC,EAAA,EAElBrC,EAAAA,UAAU,IAAM,CACdjC,GAAA,EAAc,KAAMuE,GAAM,CACxBf,EAAUe,CAAC,GACPA,GAAA,YAAAA,EAAG,QAAS,UAAwB,OAAOA,EAAE,IAAI,CAAC,GAClDA,GAAA,YAAAA,EAAG,eAAgB,QAAWH,EAAaG,EAAE,WAAW,CAC9D,CAAC,CACH,EAAG,CAAA,CAAE,EAEL,MAAMC,EAAwB,MAAOC,EAAkBC,IAA0B,CAC/E,MAAMC,EAAUpB,GAAA,YAAAA,EAAQ,cAClBqB,EAA4B,CAChC,OAAOD,GAAA,YAAAA,EAAS,QAASE,EAAe,MACxC,WAAWF,GAAA,YAAAA,EAAS,YAAaE,EAAe,UAChD,YAAYF,GAAA,YAAAA,EAAS,aAAcE,EAAe,WAClD,eAAeF,GAAA,YAAAA,EAAS,gBAAiBE,EAAe,cACxD,CAACJ,CAAG,EAAGC,CAAA,EAEE,MAAMxE,EAAW,CAAE,cAAe0E,EAAS,GAEpDpB,EAAWsB,GAAUA,GAAO,CAAE,GAAGA,EAAM,cAAeF,CAAA,CAAiB,EACvEP,EAAM,CAAE,MAAO,QAAS,QAAS,UAAW,GAE5CA,EAAM,CAAE,MAAO,iBAAkB,QAAS,QAAS,CAEvD,EAEMU,EAAiB,SAAY,CACjC,MAAMC,EAAO,OAAOf,CAAS,EAC7B,GAAI,CAACV,GAAU,CAAC,OAAO,UAAUyB,CAAI,GAAKA,GAAQ,GAAKA,IAASzB,EAAO,KAAM,OAClE,MAAMrD,EAAW,CAAE,KAAA8E,EAAM,GAElCxB,EAAWsB,GAAUA,GAAO,CAAE,GAAGA,EAAM,KAAAE,CAAA,CAAc,EACrDX,EAAM,CAAE,MAAO,QAAS,QAAS,UAAW,GAE5CA,EAAM,CAAE,MAAO,iBAAkB,QAAS,QAAS,CAEvD,EAEMY,EAAiB,SAAY,CACjC,MAAMC,EAAcf,EAAU,KAAA,EAC9B,GAAI,CAACZ,GAAU,CAAC2B,GAAeA,IAAgB3B,EAAO,YAAa,OACxD,MAAMrD,EAAW,CAAE,YAAAgF,EAAa,GAEzC1B,EAAWsB,GAAUA,GAAO,CAAE,GAAGA,EAAM,YAAAI,CAAA,CAAqB,EAC5Dd,EAAac,CAAW,EACxBb,EAAM,CAAE,MAAO,QAAS,QAAS,UAAW,GAE5CA,EAAM,CAAE,MAAO,iBAAkB,QAAS,QAAS,CAEvD,EAEMc,EAAa,MAAOjC,GAA2C,OACnE,MAAMkC,GAAO7C,EAAAW,EAAE,OAAO,QAAT,YAAAX,EAAiB,GAC9B,GAAI,CAAC6C,EAAM,OACXpB,EAAa,EAAI,EACjB,MAAMqB,EAAS,IAAI,WACnBA,EAAO,UAAY,SAAY,CAC7B,MAAMC,EAAUD,EAAO,OACjBE,EAAK,MAAMC,GAAWF,CAAO,EACnCtB,EAAa,EAAK,EACduB,GACF1B,EAAuByB,CAAO,EAC9BjB,EAAM,CAAE,MAAO,QAAS,QAAS,UAAW,GAE5CA,EAAM,CAAE,MAAO,iBAAkB,QAAS,QAAS,CAEvD,EACAgB,EAAO,cAAcD,CAAI,CAC3B,EAEA,cACG,MAAA,CACC,SAAA,CAAAjE,MAAC,OAAI,MAAO,CAAE,aAAcD,EAAM,CAAC,CAAA,EACjC,SAAAC,EAAAA,IAAC,KAAA,CAAG,MAAO,CAAE,OAAQ,CAAA,EAAK,wBAAY,EACxC,EACCoC,IAAW,QAAapC,EAAAA,IAAC,IAAA,CAAE,SAAA,WAAQ,EACnCoC,IAAW,MACVtC,OAACwE,EAAA,CAAM,QAAQ,UAAU,SAAA,CAAA,wCACctE,EAAAA,IAAC,QAAK,SAAA,iBAAA,CAAe,EAAO,2BAAA,EACnE,EAEDoC,GACCtC,EAAAA,KAACyE,EAAA,CAAK,KAAK,QACT,SAAA,CAAAzE,EAAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,WACZ,IAAKC,EAAM,CAAC,EACZ,cAAeA,EAAM,CAAC,CAAA,EAGxB,SAAA,CAAAC,EAAAA,IAAC8B,EAAA,CACC,MAAOkB,EACP,SAAWjB,GAAMkB,EAAalB,EAAE,OAAO,KAAK,EAC5C,OAAQ+B,EACR,MAAM,cAAA,CAAA,EAERhE,EAAAA,KAAC0E,EAAA,CACC,KAAK,QACL,UAAU,4BACV,UAAWC,GAAM,gBAClB,SAAA,CAAA,IACGrC,EAAO,OAAA,CAAA,CAAA,CACX,CAAA,CAAA,QAEDJ,EAAA,EAAQ,EAETlC,EAAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,IAAKC,EAAM,CAAC,EACZ,cAAeA,EAAM,CAAC,EACtB,WAAYA,EAAM,CAAC,CAAA,EAGpB,SAAA,CAAA4C,GACC3C,EAAAA,IAAC,MAAA,CACC,IAAK2C,EACL,IAAI,eACJ,MAAO,CACL,MAAO,GACP,OAAQ,GACR,UAAW,UACX,WAAY,EACZ,aAAc,CAAA,CAChB,CAAA,SAGH,MAAA,CAEC,SAAA,CAAA3C,EAAAA,IAAC,QAAA,CACC,IAAKkC,EACL,KAAK,OACL,OAAO,kCACP,SAAU8B,EACV,MAAO,CAAE,QAAS,MAAA,CAAO,CAAA,EAE3BhE,EAAAA,IAAC0E,EAAA,CACC,QAAQ,YACR,KAAK,QACL,QAAS,IAAA,OAAM,OAAAtD,EAAAc,EAAQ,UAAR,YAAAd,EAAiB,SAChC,SAAUwB,EAET,WAAY,aAAe,aAAA,CAAA,EAE7BL,GACCvC,EAAAA,IAAC,IAAA,CAAE,UAAU,UAAU,MAAO,CAAE,QAAS,GAAK,OAAQ,GAAGD,EAAM,CAAC,CAAC,QAAU,SAAA,WAE3E,EAED,CAACwC,GAAmB,CAACI,GAAe,CAACC,GACpC5C,EAAAA,IAAC,KAAE,UAAU,UAAU,MAAO,CAAE,QAAS,IAAM,OAAQ,GAAGD,EAAM,CAAC,CAAC,MAAA,EAAU,SAAA,cAAA,CAE5E,CAAA,CAAA,CAEJ,CAAA,CAAA,CAAA,QAEDiC,EAAA,EAAQ,EAEThC,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,WACZ,IAAKD,EAAM,CAAC,EACZ,cAAeA,EAAM,CAAC,EACtB,WAAYA,EAAM,CAAC,CAAA,EAGrB,SAAAC,EAAAA,IAAC8B,EAAA,CACC,KAAK,SACL,MAAOgB,EACP,SAAWf,GAAMgB,EAAahB,EAAE,OAAO,KAAK,EAC5C,OAAQ6B,EACR,MAAM,OACN,WAAW,mEAAA,CAAA,CACb,CAAA,QAED5B,EAAA,EAAQ,QAERnC,GAAA,EAAmB,EACnBN,EAAe,IAAI,CAAC+D,EAAKqB,IAAA,OACxB3E,OAAAA,EAAAA,IAACE,GAAA,CAEC,QAASoD,EACT,cAAalC,EAAAgB,EAAO,gBAAP,YAAAhB,EAAuBkC,KAAQI,EAAeJ,CAAG,EAC9D,OAAQqB,IAAQpF,EAAe,OAAS,EACxC,OAAQ8D,CAAA,EAJHC,CAAA,EAMR,CAAA,EACH,EAGFxD,EAAAA,KAAC,IAAA,CAAE,MAAO,CAAE,QAAS,IAAM,SAAUG,EAAS,GAAI,UAAWF,EAAM,CAAC,GAClE,SAAA,CAAAC,EAAAA,IAAC,UAAO,SAAA,cAAA,CAAY,EAAU,IAC7BoC,EAAS,IAAI,KAAKA,EAAO,aAAa,EAAE,iBAAmB,GAAA,CAAA,CAC9D,CAAA,EACF,CAEJ,EAOMwC,GAAuBC,GAAwC,CACnE,GAAI,CACF,MAAMC,EAAS,KAAK,MAAMD,CAAO,EACjC,MAAI,CAACC,EAAO,SAAW,OAAOA,EAAO,SAAY,SAAiB,KAC3D,OAAO,QAAQA,EAAO,OAAO,EAAE,IAAI,CAAC,CAAC3F,EAAM4F,CAAO,KAAO,CAAE,KAAA5F,EAAM,QAAA4F,GAAU,CACpF,MAAQ,CACN,OAAO,IACT,CACF,EAEMC,GAAsB,CAAC,CAAE,SAAAC,KAAqC,CAClE,KAAM,CAACJ,EAASK,CAAU,EAAIrE,EAAAA,SAAwB,IAAI,EACpD,CAACsE,EAASC,CAAU,EAAIvE,EAAAA,SAAS,EAAI,EAU3C,GARAC,EAAAA,UAAU,IAAM,CACdsE,EAAW,EAAI,EACflG,GAAgB+F,CAAQ,EAAE,KAAM7B,GAAM,CACpC8B,EAAW9B,CAAC,EACZgC,EAAW,EAAK,CAClB,CAAC,CACH,EAAG,CAACH,CAAQ,CAAC,EAETE,EAAS,OAAOnF,EAAAA,IAAC,IAAA,CAAE,SAAA,WAAQ,EAC/B,GAAI6E,IAAY,KACd,OAAO/E,EAAAA,KAACwE,EAAA,CAAM,QAAQ,UAAU,SAAA,CAAA,yBAAuBW,EAAS,aAAA,EAAW,EAG7E,MAAMI,EAAUJ,IAAa,eAAiBL,GAAoBC,CAAO,EAAI,KAE7E,cACG,MAAA,CACC,SAAA,CAAA7E,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,eAAgB,gBAChB,aAAcD,EAAM,CAAC,CAAA,EAGvB,eAAC,KAAA,CAAG,MAAO,CAAE,OAAQ,CAAA,EAAM,SAAAkF,CAAA,CAAS,CAAA,CAAA,EAErCI,EACCrF,EAAAA,IAACsF,EAAA,CACC,KAAMD,EACN,QAAS,CACP,CACE,IAAK,OACL,OAAQ,SACR,KAAOE,GACLvF,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,WAAYwF,EAAW,IAAA,EAAS,SAAAD,EAAI,IAAA,CAAK,EAE1D,MAAO,CAAA,EAET,CACE,IAAK,UACL,OAAQ,UACR,KAAOA,GACLvF,MAAC,OAAA,CAAK,MAAO,CAAE,WAAYwF,EAAW,IAAA,EAAS,SAAAD,EAAI,OAAA,CAAQ,CAAA,CAE/D,CACF,CAAA,EAGFvF,EAAAA,IAACyF,GAAA,CAAU,KAAMZ,EAAS,SAAUI,CAAA,CAAU,CAAA,EAElD,CAEJ,EAEMS,EAAepC,GAAgB,6BAA6B,KAAKA,CAAG,EAEpEqC,GAAa,IAAM,CACvB,KAAM,CAACR,EAASC,CAAU,EAAIvE,EAAAA,SAAS,EAAI,EACrC,CAAC+E,EAAMC,CAAO,EAAIhF,EAAAA,SAAqB,CAAA,CAAE,EACzC,CAACiF,EAAaC,CAAc,EAAIlF,EAAAA,SAAmB,CAAA,CAAE,EACrD,CAACmF,EAAUC,CAAW,EAAIpF,EAAAA,SAAsB,IAAI,GAAK,EACzD,CAACqF,EAAQC,CAAS,EAAItF,EAAAA,SAAS,EAAK,EACpC,CAACuF,EAAOC,CAAQ,EAAIxF,EAAAA,SAAS,EAAK,EAClC,CAACyF,EAAOC,CAAQ,EAAI1F,EAAAA,SAAwB,IAAI,EAEtDC,EAAAA,UAAU,IAAM,CACd1B,EAAA,EAAW,KAAMoH,GAAQ,CACvBX,EAAQW,EAAI,OAAO,EACnBT,EAAeS,EAAI,WAAW,EAC9BpB,EAAW,EAAK,CAClB,CAAC,CACH,EAAG,CAAA,CAAE,EAEL,MAAMqB,EAAY,CAACC,EAAeC,IAA6B,CAC7Dd,EAASlC,GAASA,EAAK,IAAI,CAAC4B,EAAKqB,IAAOA,IAAMF,EAAQ,CAAE,GAAGnB,EAAK,GAAGoB,CAAA,EAAUpB,CAAI,CAAC,CACpF,EAEMsB,EAAe,IAAMhB,EAASlC,GAAS,CAAC,GAAGA,EAAM,CAAE,IAAK,GAAI,MAAO,EAAA,CAAI,CAAC,EAExEmD,EAAuBxD,GAAgB,CAC3CuC,EAASlC,GAAS,CAAC,GAAGA,EAAM,CAAE,IAAAL,EAAK,MAAO,EAAA,CAAI,CAAC,EAC/CyC,EAAgBpC,GAASA,EAAK,OAAQoD,GAAMA,IAAMzD,CAAG,CAAC,CACxD,EAEM0D,EAAmBN,GAAkB,CACzCb,EAASlC,GAASA,EAAK,OAAO,CAACsD,EAAGL,IAAMA,IAAMF,CAAK,CAAC,EACpDT,EAAatC,GAAS,CACpB,MAAMuD,EAAO,IAAI,IAAIvD,CAAI,EACzB,OAAAuD,EAAK,OAAOR,CAAK,EACVQ,CACT,CAAC,CACH,EAEMC,EAAgBT,GACpBT,EAAatC,GAAS,CACpB,MAAMuD,EAAO,IAAI,IAAIvD,CAAI,EACzB,OAAIuD,EAAK,IAAIR,CAAK,EAAGQ,EAAK,OAAOR,CAAK,EACjCQ,EAAK,IAAIR,CAAK,EACZQ,CACT,CAAC,EAEGE,EAAa,SAAY,CAC7B,MAAMC,EAAUzB,EACb,IAAKL,IAAS,CAAE,IAAKA,EAAI,IAAI,KAAA,EAAQ,MAAOA,EAAI,MAAO,MAAOA,EAAI,KAAA,EAAQ,EAC1E,OAAQA,GAAQA,EAAI,IAAI,OAAS,CAAC,EAErC,GADa,IAAI,IAAI8B,EAAQ,IAAK9B,GAAQA,EAAI,GAAG,CAAC,EACzC,OAAS8B,EAAQ,OAAQ,CAChCd,EAAS,gCAAgC,EACzC,MACF,CACAA,EAAS,IAAI,EACbJ,EAAU,EAAI,EAGd,MAAM/B,EAAK,MAAM/E,GACfgI,EAAQ,IAAK9B,IAAS,CACpB,IAAKA,EAAI,IACT,MAAOA,EAAI,MACX,KAAM,CAAC,CAACA,EAAI,OAASA,EAAI,QAAU,EAAA,EACnC,CAAA,EAEJY,EAAU,EAAK,EACX/B,GAEFyB,EAAQwB,EAAQ,IAAK9B,IAAS,CAAE,IAAKA,EAAI,IAAK,MAAO,GAAI,MAAO,EAAA,EAAO,CAAC,EACxEc,EAAS,EAAI,EACb,WAAW,IAAMA,EAAS,EAAK,EAAG,GAAI,GAEtCE,EAAS,qBAAqB,CAElC,EAEA,OAAIpB,EAAgBnF,EAAAA,IAAC,IAAA,CAAE,SAAA,WAAQ,SAG5B,MAAA,CACC,SAAA,CAAAA,EAAAA,IAAC,KAAA,CAAG,MAAO,CAAE,OAAQ,EAAG,aAAcD,EAAM,CAAC,CAAA,EAAK,SAAA,uBAAA,CAAqB,EACtEuG,GAASxG,EAAAA,KAACwE,EAAA,CAAM,QAAQ,UAAU,SAAA,CAAA,oBAAkBgC,CAAA,EAAM,EAC1DR,EAAY,OAAS,GACpBhG,EAAAA,KAACyE,EAAA,CAAK,KAAK,QAAQ,OAAM,GAAC,YAAY,QACpC,SAAA,CAAAvE,EAAAA,IAAC,IAAA,CAAE,MAAO,CAAE,OAAQ,EAAG,WAAY,GAAA,EAAO,SAAA,mBAAA,CAAiB,EAC3DF,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,SAAU,OAAQ,IAAKC,EAAM,CAAC,EAAG,WAAY,UAC1E,SAAA,CAAAC,EAAAA,IAAC,QAAK,SAAA,sCAAA,CAAoC,EACzC8F,EAAY,IAAKxC,GAChBxD,EAAAA,KAAC4E,EAAA,CAEC,QAAQ,YACR,KAAK,QACL,QAAS,IAAMoC,EAAoBxD,CAAG,EACvC,SAAA,CAAA,KACIA,CAAA,CAAA,EALEA,CAAA,CAOR,CAAA,CAAA,CACH,CAAA,EACF,EAEFtD,EAAAA,IAACsF,EAAA,CACC,KAAMM,EACN,QAAS,CACP,CACE,IAAK,MACL,OAAQ,MACR,KAAM,CAACL,EAAemB,IACpB1G,EAAAA,IAAC8B,EAAA,CACC,MAAOyD,EAAI,IACX,YAAY,MACZ,MAAO,CAAE,WAAYC,EAAW,IAAA,EAChC,SAAWzD,GAAM0E,EAAUC,EAAO,CAAE,IAAK3E,EAAE,OAAO,KAAA,CAAO,CAAA,CAAA,EAG7D,MAAO,CAAA,EAET,CACE,IAAK,QACL,OAAQ,QACR,KAAM,CAACwD,EAAemB,IAAkB,CACtC,MAAMY,EAAS5B,EAAYH,EAAI,GAAG,GAAK,CAACS,EAAS,IAAIU,CAAK,EAC1D,OACE5G,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAKC,EAAM,CAAC,CAAA,EAC/D,SAAA,CAAAC,EAAAA,IAAC8B,EAAA,CACC,KAAMwF,EAAS,WAAa,OAC5B,MAAO/B,EAAI,MACX,YAAaA,EAAI,MAAQ,mCAAqC,QAC9D,MAAO,CAAE,WAAYC,EAAW,KAAM,KAAM,CAAA,EAC5C,SAAWzD,GAAM0E,EAAUC,EAAO,CAAE,MAAO3E,EAAE,OAAO,KAAA,CAAO,CAAA,CAAA,EAE5D2D,EAAYH,EAAI,GAAG,GAClBvF,EAAAA,IAAC0E,GAAO,QAAQ,QAAQ,KAAK,QAAQ,QAAS,IAAMyC,EAAaT,CAAK,EACnE,SAAAY,EAAS,OAAS,MAAA,CACrB,CAAA,EAEJ,CAEJ,CAAA,EAEF,CACE,IAAK,UACL,OAAQ,GACR,MAAO,EACP,KAAM,CAACC,EAAgBb,IACrB1G,EAAAA,IAACwH,GAAA,CACC,WAAOC,GAAA,EAAU,EACjB,QAAQ,QACR,KAAK,QACL,MAAM,kBACN,QAAS,IAAMT,EAAgBN,CAAK,CAAA,CAAA,CACtC,CAEJ,CACF,CAAA,SAED,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK3G,EAAM,CAAC,EAAG,UAAWA,EAAM,CAAC,GACpF,SAAA,CAAAC,EAAAA,IAAC0E,GAAO,QAAQ,YAAY,KAAK,QAAQ,QAASmC,EAAc,SAAA,gBAAA,CAEhE,EACA7G,EAAAA,IAAC0E,EAAA,CAAO,QAAQ,UAAU,KAAK,QAAQ,QAAS0C,EAAY,SAAUlB,EACnE,SAAAA,EAAS,UAAY,OACxB,EACCE,GACCpG,EAAAA,IAAC,OAAA,CAAK,UAAU,UAAU,MAAO,CAAE,QAAS,IAAO,SAAA,OAAA,CAEnD,CAAA,CAAA,CAEJ,CAAA,EACF,CAEJ,EAEa0H,GAAe,IAAM,CAChC,MAAMC,EAAgBC,EAAaC,GAAMA,EAAE,qBAAqB,EAEhE,cACG,MAAA,CACC,SAAA,CAAA7H,EAAAA,IAAC8H,GAAU,SAAA,UAAA,CAAQ,EAClBH,IAAkB,WAAa3H,MAACiC,GAAA,CAAA,CAAe,EAC/C0F,IAAkB,OAAS3H,MAAC2F,GAAA,CAAA,CAAW,EACvCgC,EAAc,WAAW,SAAS,GACjC3H,EAAAA,IAACgF,GAAA,CAAoB,SAAU2C,EAAc,MAAM,CAAgB,CAAA,CAAG,CAAA,EAE1E,CAEJ,ECrpBaI,GAAkB,IAAM,CACnC,MAAMJ,EAAgBC,EAAaC,GAAMA,EAAE,qBAAqB,EAC1DG,EAAmBJ,EAAaC,GAAMA,EAAE,wBAAwB,EAChEI,EAAcL,EAAaC,GAAMA,EAAE,mBAAmB,EACtDK,EAAiBN,EAAaC,GAAMA,EAAE,sBAAsB,EAC5D,CAACM,EAASC,CAAU,EAAIvH,EAAAA,SAAS,EAAK,EAE5CC,OAAAA,EAAAA,UAAU,IAAM,CACd7B,GAAA,EAAe,KAAKiJ,CAAc,EAClC9I,EAAA,EAAW,KAAMoH,GAAQ4B,EAAW5B,EAAI,QAAUA,EAAI,aAAa,CAAC,CACtE,EAAG,CAAC0B,CAAc,CAAC,EAGjBpI,EAAAA,KAAA0B,WAAA,CACE,SAAA,CAAAxB,EAAAA,IAACqI,EAAA,CAAe,MAAM,UACpB,SAAArI,EAAAA,IAACsI,EAAA,CACC,KAAK,QACL,OAAQX,IAAkB,UAC1B,QAAS,IAAMK,EAAiB,SAAS,EAC1C,SAAA,cAAA,CAAA,EAGH,EAECG,GACCnI,EAAAA,IAACqI,EAAA,CAAe,MAAM,cACpB,SAAArI,EAAAA,IAACsI,EAAA,CACC,KAAK,QACL,OAAQX,IAAkB,MAC1B,QAAS,IAAMK,EAAiB,KAAK,EACtC,SAAA,UAAA,CAAA,EAGH,EAGDC,EAAY,OAAS,GACpBjI,EAAAA,IAACqI,EAAA,CAAe,MAAM,eACnB,SAAAJ,EAAY,IAAK9I,GAChBa,EAAAA,IAACsI,EAAA,CAEC,KAAK,QACL,OAAQX,IAAkB,UAAUxI,CAAI,GACxC,QAAS,IAAM6I,EAAiB,UAAU7I,CAAI,EAAE,EAE/C,SAAAA,CAAA,EALIA,CAAA,CAOR,CAAA,CACH,CAAA,EAEJ,CAEJ"}
@@ -1,2 +1,2 @@
1
- import{j as e,c as B,u as i,a as $,s as r,d as M,O as W,D as H,l as L,f as T,b,M as F,Z as w,e as J,r as k,Q as E,J as Z,X as U,g as G,h as K,i as _,P as R,k as V,o as N}from"./main-DJDNx4Xs.js";import{S as z}from"./sidebar-section-C2j12TzE.js";const I=({children:t,onClick:l})=>e.jsx("button",{type:"button",onClick:l,style:{background:"none",border:"none",padding:0,color:B.accentAmberDark,cursor:"pointer",textDecoration:"underline",font:"inherit"},children:t}),Y=()=>{const t=i(p=>p.decisions),l=i(p=>p.openQuestions),d=i(p=>p.activeDocTitle),a=i(p=>p.setActiveDocTitle),n=$(),c=t.find(p=>p.title===d);if(!c)return null;const h=l.filter(p=>p.resolvedBy===c.title);return e.jsxs("div",{children:[e.jsx("h2",{style:{...M,margin:`0 0 ${r[3]}`},children:c.title}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:r[2],marginBottom:r[5]},children:[e.jsx("span",{className:"text-sm",style:{opacity:.5},children:c.date}),e.jsx(W,{size:"small",fillColor:H[c.status].fill,textColor:H[c.status].text,children:c.status}),c.supersededBy&&e.jsxs("span",{className:"text-sm",style:{opacity:.5},children:["Superseded by"," ",e.jsx(I,{onClick:()=>a(c.supersededBy),children:c.supersededBy})]}),h.length>0&&e.jsxs("span",{className:"text-sm",style:{opacity:.5},children:[h.length===1?"Resolves":"Resolves all of"," ",h.map((p,x)=>e.jsxs("span",{children:[x>0&&", ",e.jsx(I,{onClick:()=>{n({to:"/docs/$section",params:{section:"questions"}}),a(p.title)},children:p.title})]},p.title))]})]}),e.jsx("div",{style:{fontFamily:b.body,fontSize:T.base,lineHeight:L.relaxed,color:B.textProse},children:e.jsx(F,{children:c.body})})]})},D=(t,l)=>t.toLowerCase().includes(l.toLowerCase()),P=(t,l,d=120)=>{const a=t.toLowerCase().indexOf(l.toLowerCase());if(a===-1)return t.slice(0,d);const n=Math.max(0,a-40),c=Math.min(t.length,a+l.length+40);let h=t.slice(n,c);return n>0&&(h=`…${h}`),c<t.length&&(h=`${h}…`),h},q=({query:t})=>{const l=i(o=>o.decisions),d=i(o=>o.openQuestions),a=i(o=>o.progress),n=i(o=>o.repoDocs),c=i(o=>o.setActiveDocTitle),h=i(o=>o.setDocSearchQuery),p=$(),x=[];for(const o of l)(D(o.title,t)||D(o.body,t))&&x.push({section:"decisions",sectionLabel:"Decisions",title:o.title,snippet:P(o.body||o.title,t)});for(const o of d)(D(o.title,t)||D(o.body,t))&&x.push({section:"questions",sectionLabel:"Open Questions",title:o.title,snippet:P(o.body||o.title,t)});for(const o of a)for(const u of o.items)if(D(u,t)){x.push({section:"progress",sectionLabel:"Progress",title:o.date,snippet:P(u,t)});break}for(const o of n)(D(o.name,t)||D(o.content,t))&&x.push({section:"repo-docs",sectionLabel:"Repo Docs",title:o.name,snippet:P(o.content,t)});const j={};for(const o of x)j[o.section]||(j[o.section]=[]),j[o.section].push(o);const v=(o,u)=>{p({to:"/docs/$section",params:{section:o}}),c(u),h("")};return x.length===0?e.jsxs("p",{style:{opacity:.5},children:['No results found for "',t,'".']}):e.jsxs("div",{children:[e.jsxs("p",{className:"text-sm",style:{opacity:.5,marginBottom:r[3]},children:[x.length," result",x.length===1?"":"s",' for "',t,'"']}),Object.entries(j).map(([o,u])=>e.jsxs("div",{style:{marginBottom:r[6]},children:[e.jsx("h3",{className:"text-xs",style:{fontWeight:600,letterSpacing:"0.1em",textTransform:"uppercase",opacity:.4,margin:`0 0 ${r[2]}`},children:u[0].sectionLabel}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:r[1]},children:u.map(m=>e.jsx(w,{variant:"ghost",size:"small",fullWidth:!0,onClick:()=>v(m.section,m.title),style:{justifyContent:"flex-start",padding:`${r[2]} ${r[3]}`},children:e.jsxs("span",{style:{textAlign:"left"},children:[e.jsx("span",{style:{fontFamily:b.serif,fontWeight:600,fontSize:"0.95rem",display:"block",marginBottom:"0.2rem"},children:m.title}),e.jsx("span",{className:"text-sm",style:{opacity:.6},children:m.snippet})]})},`${m.section}-${m.title}`))})]},o))]})},ee=()=>{const t=i(g=>g.openQuestions),l=i(g=>g.activeDocTitle),d=i(g=>g.setActiveDocTitle),a=i(g=>g.loadDecisions),n=i(g=>g.loadOpenQuestions),c=$(),{toast:h}=J(),[p,x]=k.useState(!1),[j,v]=k.useState(""),[o,u]=k.useState(""),[m,Q]=k.useState(!1),f=t.find(g=>g.title===l);if(!f)return null;const S=()=>{f.resolvedBy&&(c({to:"/docs/$section",params:{section:"decisions"}}),d(f.resolvedBy))},C=()=>{v(""),u(""),Q(!1),x(!0)},O=()=>{x(!1)},s=async g=>{if(g.preventDefault(),!(!j.trim()||m)){Q(!0);try{await K(f.title,j.trim(),o.trim()||void 0),x(!1),await Promise.all([a(),n()])}catch(X){Q(!1),h({title:"Resolve failed",description:X.message,variant:"error"})}}};return e.jsxs("div",{children:[e.jsx("h2",{style:{...M,margin:`0 0 ${r[3]}`},children:f.title}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:r[2],marginBottom:r[5]},children:[e.jsx("span",{className:"text-sm",style:{opacity:.5},children:f.raised}),e.jsx(W,{size:"small",fillColor:E[f.status].fill,textColor:E[f.status].text,children:f.status}),f.resolvedBy&&e.jsxs("span",{className:"text-sm",style:{opacity:.5},children:["Resolved by"," ",e.jsx(I,{onClick:S,children:f.resolvedBy})]}),f.status==="open"&&e.jsx(w,{surface:"chalkboard",onClick:C,children:"Resolve"})]}),e.jsx("div",{style:{fontFamily:b.body,fontSize:T.base,lineHeight:L.relaxed,color:B.textProse},children:e.jsx(F,{children:f.body})}),e.jsx(Z,{open:p,onClose:O,title:"Resolve question",size:"small",children:e.jsxs("form",{onSubmit:s,style:{display:"flex",flexDirection:"column",gap:r[4]},children:[e.jsx(U,{label:"Decision",value:j,onChange:g=>v(g.target.value),placeholder:"What was decided?",disabled:m,autoFocus:!0,required:!0}),e.jsx(G,{label:"Rationale",value:o,onChange:g=>u(g.target.value),placeholder:"Optional reasoning…",disabled:m,rows:4}),e.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:r[2]},children:[e.jsx(w,{type:"button",variant:"ghost",onClick:O,disabled:m,children:"Cancel"}),e.jsx(w,{type:"submit",variant:"primary",disabled:!j.trim()||m,children:"Resolve"})]})]})})]})},se=()=>{const t=i(n=>n.progress),l=i(n=>n.activeDocTitle),a=[...l?t.filter(n=>n.date===l):t].sort((n,c)=>c.date.localeCompare(n.date));return a.length===0?e.jsx("p",{style:{opacity:.5},children:"No progress entries found."}):e.jsx("div",{children:a.map(n=>e.jsxs("div",{style:{marginBottom:r[8]},children:[e.jsx("h3",{style:{fontFamily:b.serif,fontWeight:600,fontSize:T.md,margin:`0 0 ${r[3]}`,lineHeight:L.tight,opacity:.8},children:n.date}),e.jsx("ul",{style:{listStyle:"none",padding:0,margin:0,display:"flex",flexDirection:"column",gap:r[2]},children:n.items.map((c,h)=>e.jsx("li",{style:{fontFamily:b.body,fontSize:T.sm,lineHeight:1.55,color:B.textProse,paddingLeft:r[4],borderLeft:"2px solid rgba(0,0,0,0.08)"},children:e.jsx(F,{children:c})},`${n.date}-${h}`))})]},n.date))})},te=()=>{const t=i(n=>n.repoDocs),l=i(n=>n.activeDocTitle),d=t.find(n=>n.name===l);if(!d)return null;const a=d.name.endsWith(".md");return e.jsxs("div",{children:[e.jsx("h2",{style:{...M,margin:`0 0 ${r[4]}`},children:d.name}),a?e.jsx("div",{style:{fontFamily:b.body,fontSize:T.base,lineHeight:L.relaxed,color:B.textProse},children:e.jsx(F,{children:d.content})}):e.jsx("pre",{style:{fontFamily:b.mono,fontSize:T.xs,background:"rgba(0,0,0,0.04)",borderRadius:6,padding:r[4],overflowX:"auto",lineHeight:L.normal,whiteSpace:"pre-wrap"},children:d.content})]})},A=({itemId:t,label:l,onBack:d})=>e.jsx("div",{style:{marginBottom:r[4]},children:e.jsx(V,{items:[{id:"docs",label:"Docs",onClick:d},{id:t,label:l}]})}),le=()=>{const t=i(c=>c.docSearchQuery),l=i(c=>c.activeDocTitle),d=$(),a=_(),n=()=>d({to:"/docs"});return t.trim()?e.jsx("div",{children:e.jsx(q,{query:t})}):a==="decisions"&&l?e.jsxs("div",{children:[e.jsx(A,{itemId:"decision",label:l,onBack:n}),e.jsx(R,{children:"Decisions"}),e.jsx(Y,{})]}):a==="questions"&&l?e.jsxs("div",{children:[e.jsx(A,{itemId:"question",label:l,onBack:n}),e.jsx(R,{children:"Open Questions"}),e.jsx(ee,{})]}):a==="progress"?e.jsxs("div",{children:[e.jsx(A,{itemId:"progress",label:l??"Progress",onBack:n}),e.jsx(R,{children:"Progress"}),e.jsx(se,{})]}):a==="repo-docs"&&l?e.jsxs("div",{children:[e.jsx(A,{itemId:"repo-doc",label:l,onBack:n}),e.jsx(te,{})]}):e.jsxs("div",{children:[e.jsx(R,{children:"Docs"}),e.jsx("p",{style:{opacity:.5},children:"Select a section from the sidebar."})]})},oe=t=>t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),y=({children:t})=>e.jsx("span",{className:"text-sm",style:{display:"block",padding:`${r[1]} ${r[3]}`,opacity:.35,fontStyle:"italic"},children:t}),ce=()=>{const t=i(s=>s.decisions),l=i(s=>s.openQuestions),d=i(s=>s.progress),a=i(s=>s.repoDocs),n=i(s=>s.decisionsLoading),c=i(s=>s.openQuestionsLoading),h=i(s=>s.progressLoading),p=i(s=>s.repoDocsLoading),x=i(s=>s.loadDecisions),j=i(s=>s.loadOpenQuestions),v=i(s=>s.loadProgress),o=i(s=>s.loadRepoDocs),u=i(s=>s.activeDocTitle),m=i(s=>s.setActiveDocTitle),Q=i(s=>s.docSearchQuery),f=i(s=>s.setDocSearchQuery),S=_(),C=$();k.useEffect(()=>{x(),j(),v(),o()},[x,j,v,o]);const O=s=>{C({to:"/docs/$section",params:{section:"decisions"}}),m(s)};return e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{marginBottom:r[4]},children:e.jsx(U,{size:"small","aria-label":"Search docs",placeholder:"Search docs…",value:Q,onChange:s=>f(s.target.value)})}),e.jsx(z,{label:"Repo Docs",children:p&&a.length===0?e.jsx(y,{children:"Loading…"}):a.length>0?a.map(s=>e.jsx(N,{size:"small",active:S==="repo-docs"&&u===s.name,onClick:()=>{C({to:"/docs/$section",params:{section:"repo-docs"}}),m(s.name)},children:oe(s.name)},s.name)):e.jsx(y,{children:"No repo docs found"})}),e.jsx(z,{label:"Decisions",children:n&&t.length===0?e.jsx(y,{children:"Loading…"}):t.length>0?t.map(s=>e.jsx(N,{size:"small",active:S==="decisions"&&u===s.title,onClick:()=>O(s.title),children:s.title},s.title)):e.jsx(y,{children:"No decisions yet"})}),e.jsx(z,{label:"Open Questions",children:c&&l.length===0?e.jsx(y,{children:"Loading…"}):l.length>0?l.map(s=>e.jsx(N,{size:"small",active:S==="questions"&&u===s.title,onClick:()=>{C({to:"/docs/$section",params:{section:"questions"}}),m(s.title)},children:s.title},s.title)):e.jsx(y,{children:"No open questions"})}),e.jsx(z,{label:"Progress",children:h&&d.length===0?e.jsx(y,{children:"Loading…"}):d.length>0?d.map(s=>e.jsx(N,{size:"small",active:S==="progress"&&u===s.date,onClick:()=>{C({to:"/docs/$section",params:{section:"progress"}}),m(s.date)},children:s.date},s.date)):e.jsx(y,{children:"No progress entries"})})]})};export{le as DocsPage,ce as DocsSidebar};
2
- //# sourceMappingURL=index-CF8jC3IN.js.map
1
+ import{j as e,c as B,u as i,a as $,s as r,d as M,O as W,D as H,l as L,f as T,b,M as F,Z as w,e as J,r as k,Q as E,J as Z,X as U,g as G,h as K,i as _,P as R,k as V,o as N}from"./main-DUy5DFoq.js";import{S as z}from"./sidebar-section-mXpllayv.js";const I=({children:t,onClick:l})=>e.jsx("button",{type:"button",onClick:l,style:{background:"none",border:"none",padding:0,color:B.accentAmberDark,cursor:"pointer",textDecoration:"underline",font:"inherit"},children:t}),Y=()=>{const t=i(p=>p.decisions),l=i(p=>p.openQuestions),d=i(p=>p.activeDocTitle),a=i(p=>p.setActiveDocTitle),n=$(),c=t.find(p=>p.title===d);if(!c)return null;const h=l.filter(p=>p.resolvedBy===c.title);return e.jsxs("div",{children:[e.jsx("h2",{style:{...M,margin:`0 0 ${r[3]}`},children:c.title}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:r[2],marginBottom:r[5]},children:[e.jsx("span",{className:"text-sm",style:{opacity:.5},children:c.date}),e.jsx(W,{size:"small",fillColor:H[c.status].fill,textColor:H[c.status].text,children:c.status}),c.supersededBy&&e.jsxs("span",{className:"text-sm",style:{opacity:.5},children:["Superseded by"," ",e.jsx(I,{onClick:()=>a(c.supersededBy),children:c.supersededBy})]}),h.length>0&&e.jsxs("span",{className:"text-sm",style:{opacity:.5},children:[h.length===1?"Resolves":"Resolves all of"," ",h.map((p,x)=>e.jsxs("span",{children:[x>0&&", ",e.jsx(I,{onClick:()=>{n({to:"/docs/$section",params:{section:"questions"}}),a(p.title)},children:p.title})]},p.title))]})]}),e.jsx("div",{style:{fontFamily:b.body,fontSize:T.base,lineHeight:L.relaxed,color:B.textProse},children:e.jsx(F,{children:c.body})})]})},D=(t,l)=>t.toLowerCase().includes(l.toLowerCase()),P=(t,l,d=120)=>{const a=t.toLowerCase().indexOf(l.toLowerCase());if(a===-1)return t.slice(0,d);const n=Math.max(0,a-40),c=Math.min(t.length,a+l.length+40);let h=t.slice(n,c);return n>0&&(h=`…${h}`),c<t.length&&(h=`${h}…`),h},q=({query:t})=>{const l=i(o=>o.decisions),d=i(o=>o.openQuestions),a=i(o=>o.progress),n=i(o=>o.repoDocs),c=i(o=>o.setActiveDocTitle),h=i(o=>o.setDocSearchQuery),p=$(),x=[];for(const o of l)(D(o.title,t)||D(o.body,t))&&x.push({section:"decisions",sectionLabel:"Decisions",title:o.title,snippet:P(o.body||o.title,t)});for(const o of d)(D(o.title,t)||D(o.body,t))&&x.push({section:"questions",sectionLabel:"Open Questions",title:o.title,snippet:P(o.body||o.title,t)});for(const o of a)for(const u of o.items)if(D(u,t)){x.push({section:"progress",sectionLabel:"Progress",title:o.date,snippet:P(u,t)});break}for(const o of n)(D(o.name,t)||D(o.content,t))&&x.push({section:"repo-docs",sectionLabel:"Repo Docs",title:o.name,snippet:P(o.content,t)});const j={};for(const o of x)j[o.section]||(j[o.section]=[]),j[o.section].push(o);const v=(o,u)=>{p({to:"/docs/$section",params:{section:o}}),c(u),h("")};return x.length===0?e.jsxs("p",{style:{opacity:.5},children:['No results found for "',t,'".']}):e.jsxs("div",{children:[e.jsxs("p",{className:"text-sm",style:{opacity:.5,marginBottom:r[3]},children:[x.length," result",x.length===1?"":"s",' for "',t,'"']}),Object.entries(j).map(([o,u])=>e.jsxs("div",{style:{marginBottom:r[6]},children:[e.jsx("h3",{className:"text-xs",style:{fontWeight:600,letterSpacing:"0.1em",textTransform:"uppercase",opacity:.4,margin:`0 0 ${r[2]}`},children:u[0].sectionLabel}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:r[1]},children:u.map(m=>e.jsx(w,{variant:"ghost",size:"small",fullWidth:!0,onClick:()=>v(m.section,m.title),style:{justifyContent:"flex-start",padding:`${r[2]} ${r[3]}`},children:e.jsxs("span",{style:{textAlign:"left"},children:[e.jsx("span",{style:{fontFamily:b.serif,fontWeight:600,fontSize:"0.95rem",display:"block",marginBottom:"0.2rem"},children:m.title}),e.jsx("span",{className:"text-sm",style:{opacity:.6},children:m.snippet})]})},`${m.section}-${m.title}`))})]},o))]})},ee=()=>{const t=i(g=>g.openQuestions),l=i(g=>g.activeDocTitle),d=i(g=>g.setActiveDocTitle),a=i(g=>g.loadDecisions),n=i(g=>g.loadOpenQuestions),c=$(),{toast:h}=J(),[p,x]=k.useState(!1),[j,v]=k.useState(""),[o,u]=k.useState(""),[m,Q]=k.useState(!1),f=t.find(g=>g.title===l);if(!f)return null;const S=()=>{f.resolvedBy&&(c({to:"/docs/$section",params:{section:"decisions"}}),d(f.resolvedBy))},C=()=>{v(""),u(""),Q(!1),x(!0)},O=()=>{x(!1)},s=async g=>{if(g.preventDefault(),!(!j.trim()||m)){Q(!0);try{await K(f.title,j.trim(),o.trim()||void 0),x(!1),await Promise.all([a(),n()])}catch(X){Q(!1),h({title:"Resolve failed",description:X.message,variant:"error"})}}};return e.jsxs("div",{children:[e.jsx("h2",{style:{...M,margin:`0 0 ${r[3]}`},children:f.title}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:r[2],marginBottom:r[5]},children:[e.jsx("span",{className:"text-sm",style:{opacity:.5},children:f.raised}),e.jsx(W,{size:"small",fillColor:E[f.status].fill,textColor:E[f.status].text,children:f.status}),f.resolvedBy&&e.jsxs("span",{className:"text-sm",style:{opacity:.5},children:["Resolved by"," ",e.jsx(I,{onClick:S,children:f.resolvedBy})]}),f.status==="open"&&e.jsx(w,{surface:"chalkboard",onClick:C,children:"Resolve"})]}),e.jsx("div",{style:{fontFamily:b.body,fontSize:T.base,lineHeight:L.relaxed,color:B.textProse},children:e.jsx(F,{children:f.body})}),e.jsx(Z,{open:p,onClose:O,title:"Resolve question",size:"small",children:e.jsxs("form",{onSubmit:s,style:{display:"flex",flexDirection:"column",gap:r[4]},children:[e.jsx(U,{label:"Decision",value:j,onChange:g=>v(g.target.value),placeholder:"What was decided?",disabled:m,autoFocus:!0,required:!0}),e.jsx(G,{label:"Rationale",value:o,onChange:g=>u(g.target.value),placeholder:"Optional reasoning…",disabled:m,rows:4}),e.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:r[2]},children:[e.jsx(w,{type:"button",variant:"ghost",onClick:O,disabled:m,children:"Cancel"}),e.jsx(w,{type:"submit",variant:"primary",disabled:!j.trim()||m,children:"Resolve"})]})]})})]})},se=()=>{const t=i(n=>n.progress),l=i(n=>n.activeDocTitle),a=[...l?t.filter(n=>n.date===l):t].sort((n,c)=>c.date.localeCompare(n.date));return a.length===0?e.jsx("p",{style:{opacity:.5},children:"No progress entries found."}):e.jsx("div",{children:a.map(n=>e.jsxs("div",{style:{marginBottom:r[8]},children:[e.jsx("h3",{style:{fontFamily:b.serif,fontWeight:600,fontSize:T.md,margin:`0 0 ${r[3]}`,lineHeight:L.tight,opacity:.8},children:n.date}),e.jsx("ul",{style:{listStyle:"none",padding:0,margin:0,display:"flex",flexDirection:"column",gap:r[2]},children:n.items.map((c,h)=>e.jsx("li",{style:{fontFamily:b.body,fontSize:T.sm,lineHeight:1.55,color:B.textProse,paddingLeft:r[4],borderLeft:"2px solid rgba(0,0,0,0.08)"},children:e.jsx(F,{children:c})},`${n.date}-${h}`))})]},n.date))})},te=()=>{const t=i(n=>n.repoDocs),l=i(n=>n.activeDocTitle),d=t.find(n=>n.name===l);if(!d)return null;const a=d.name.endsWith(".md");return e.jsxs("div",{children:[e.jsx("h2",{style:{...M,margin:`0 0 ${r[4]}`},children:d.name}),a?e.jsx("div",{style:{fontFamily:b.body,fontSize:T.base,lineHeight:L.relaxed,color:B.textProse},children:e.jsx(F,{children:d.content})}):e.jsx("pre",{style:{fontFamily:b.mono,fontSize:T.xs,background:"rgba(0,0,0,0.04)",borderRadius:6,padding:r[4],overflowX:"auto",lineHeight:L.normal,whiteSpace:"pre-wrap"},children:d.content})]})},A=({itemId:t,label:l,onBack:d})=>e.jsx("div",{style:{marginBottom:r[4]},children:e.jsx(V,{items:[{id:"docs",label:"Docs",onClick:d},{id:t,label:l}]})}),le=()=>{const t=i(c=>c.docSearchQuery),l=i(c=>c.activeDocTitle),d=$(),a=_(),n=()=>d({to:"/docs"});return t.trim()?e.jsx("div",{children:e.jsx(q,{query:t})}):a==="decisions"&&l?e.jsxs("div",{children:[e.jsx(A,{itemId:"decision",label:l,onBack:n}),e.jsx(R,{children:"Decisions"}),e.jsx(Y,{})]}):a==="questions"&&l?e.jsxs("div",{children:[e.jsx(A,{itemId:"question",label:l,onBack:n}),e.jsx(R,{children:"Open Questions"}),e.jsx(ee,{})]}):a==="progress"?e.jsxs("div",{children:[e.jsx(A,{itemId:"progress",label:l??"Progress",onBack:n}),e.jsx(R,{children:"Progress"}),e.jsx(se,{})]}):a==="repo-docs"&&l?e.jsxs("div",{children:[e.jsx(A,{itemId:"repo-doc",label:l,onBack:n}),e.jsx(te,{})]}):e.jsxs("div",{children:[e.jsx(R,{children:"Docs"}),e.jsx("p",{style:{opacity:.5},children:"Select a section from the sidebar."})]})},oe=t=>t.charAt(0).toUpperCase()+t.slice(1).toLowerCase(),y=({children:t})=>e.jsx("span",{className:"text-sm",style:{display:"block",padding:`${r[1]} ${r[3]}`,opacity:.35,fontStyle:"italic"},children:t}),ce=()=>{const t=i(s=>s.decisions),l=i(s=>s.openQuestions),d=i(s=>s.progress),a=i(s=>s.repoDocs),n=i(s=>s.decisionsLoading),c=i(s=>s.openQuestionsLoading),h=i(s=>s.progressLoading),p=i(s=>s.repoDocsLoading),x=i(s=>s.loadDecisions),j=i(s=>s.loadOpenQuestions),v=i(s=>s.loadProgress),o=i(s=>s.loadRepoDocs),u=i(s=>s.activeDocTitle),m=i(s=>s.setActiveDocTitle),Q=i(s=>s.docSearchQuery),f=i(s=>s.setDocSearchQuery),S=_(),C=$();k.useEffect(()=>{x(),j(),v(),o()},[x,j,v,o]);const O=s=>{C({to:"/docs/$section",params:{section:"decisions"}}),m(s)};return e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{marginBottom:r[4]},children:e.jsx(U,{size:"small","aria-label":"Search docs",placeholder:"Search docs…",value:Q,onChange:s=>f(s.target.value)})}),e.jsx(z,{label:"Repo Docs",children:p&&a.length===0?e.jsx(y,{children:"Loading…"}):a.length>0?a.map(s=>e.jsx(N,{size:"small",active:S==="repo-docs"&&u===s.name,onClick:()=>{C({to:"/docs/$section",params:{section:"repo-docs"}}),m(s.name)},children:oe(s.name)},s.name)):e.jsx(y,{children:"No repo docs found"})}),e.jsx(z,{label:"Decisions",children:n&&t.length===0?e.jsx(y,{children:"Loading…"}):t.length>0?t.map(s=>e.jsx(N,{size:"small",active:S==="decisions"&&u===s.title,onClick:()=>O(s.title),children:s.title},s.title)):e.jsx(y,{children:"No decisions yet"})}),e.jsx(z,{label:"Open Questions",children:c&&l.length===0?e.jsx(y,{children:"Loading…"}):l.length>0?l.map(s=>e.jsx(N,{size:"small",active:S==="questions"&&u===s.title,onClick:()=>{C({to:"/docs/$section",params:{section:"questions"}}),m(s.title)},children:s.title},s.title)):e.jsx(y,{children:"No open questions"})}),e.jsx(z,{label:"Progress",children:h&&d.length===0?e.jsx(y,{children:"Loading…"}):d.length>0?d.map(s=>e.jsx(N,{size:"small",active:S==="progress"&&u===s.date,onClick:()=>{C({to:"/docs/$section",params:{section:"progress"}}),m(s.date)},children:s.date},s.date)):e.jsx(y,{children:"No progress entries"})})]})};export{le as DocsPage,ce as DocsSidebar};
2
+ //# sourceMappingURL=index-D-nmg_4I.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-CF8jC3IN.js","sources":["../../../src/app/components/link-button.tsx","../../../src/app/features/docs/components/decision-detail.tsx","../../../src/app/features/docs/components/docs-search.tsx","../../../src/app/features/docs/components/open-question-detail.tsx","../../../src/app/features/docs/components/progress-timeline.tsx","../../../src/app/features/docs/components/repo-doc-detail.tsx","../../../src/app/features/docs/docs-page.tsx","../../../src/app/features/docs/components/docs-sidebar.tsx"],"sourcesContent":["import { color } from '@/app/styles/tokens';\n\ninterface LinkButtonProps {\n children: React.ReactNode;\n onClick: () => void;\n}\n\nexport const LinkButton = ({ children, onClick }: LinkButtonProps) => (\n <button\n type=\"button\"\n onClick={onClick}\n style={{\n background: 'none',\n border: 'none',\n padding: 0,\n color: color.accentAmberDark,\n cursor: 'pointer',\n textDecoration: 'underline',\n font: 'inherit',\n }}\n >\n {children}\n </button>\n);\n","import { LinkButton, Markdown } from '@/app/components';\nimport { detailHeadingStyle } from '@/app/components/detail-heading-style';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { color, fontFamily, fontSize, lineHeight, space } from '@/app/styles/tokens';\nimport { Stamp } from '@dendelion/paper-ui';\nimport { useNavigate } from '@tanstack/react-router';\nimport { DECISION_STATUS_STAMP } from '../../plans/constants';\n\nexport const DecisionDetail = () => {\n const decisions = useAppStore((s) => s.decisions);\n const openQuestions = useAppStore((s) => s.openQuestions);\n const activeDocTitle = useAppStore((s) => s.activeDocTitle);\n const setActiveDocTitle = useAppStore((s) => s.setActiveDocTitle);\n const navigate = useNavigate();\n\n const decision = decisions.find((d) => d.title === activeDocTitle);\n if (!decision) return null;\n\n const resolvedQuestions = openQuestions.filter((q) => q.resolvedBy === decision.title);\n\n return (\n <div>\n <h2 style={{ ...detailHeadingStyle, margin: `0 0 ${space[3]}` }}>{decision.title}</h2>\n\n <div style={{ display: 'flex', alignItems: 'center', gap: space[2], marginBottom: space[5] }}>\n <span className=\"text-sm\" style={{ opacity: 0.5 }}>\n {decision.date}\n </span>\n <Stamp\n size=\"small\"\n fillColor={DECISION_STATUS_STAMP[decision.status].fill}\n textColor={DECISION_STATUS_STAMP[decision.status].text}\n >\n {decision.status}\n </Stamp>\n {decision.supersededBy && (\n <span className=\"text-sm\" style={{ opacity: 0.5 }}>\n Superseded by{' '}\n <LinkButton onClick={() => setActiveDocTitle(decision.supersededBy!)}>\n {decision.supersededBy}\n </LinkButton>\n </span>\n )}\n {resolvedQuestions.length > 0 && (\n <span className=\"text-sm\" style={{ opacity: 0.5 }}>\n {resolvedQuestions.length === 1 ? 'Resolves' : 'Resolves all of'}{' '}\n {resolvedQuestions.map((q, i) => (\n <span key={q.title}>\n {i > 0 && ', '}\n <LinkButton\n onClick={() => {\n navigate({ to: '/docs/$section', params: { section: 'questions' } });\n setActiveDocTitle(q.title);\n }}\n >\n {q.title}\n </LinkButton>\n </span>\n ))}\n </span>\n )}\n </div>\n\n <div\n style={{\n fontFamily: fontFamily.body,\n fontSize: fontSize.base,\n lineHeight: lineHeight.relaxed,\n color: color.textProse,\n }}\n >\n <Markdown>{decision.body}</Markdown>\n </div>\n </div>\n );\n};\n","import { useAppStore } from '@/app/stores/app-store';\nimport { fontFamily, space } from '@/app/styles/tokens';\nimport { Button } from '@dendelion/paper-ui';\nimport { useNavigate } from '@tanstack/react-router';\n\ninterface SearchMatch {\n section: 'decisions' | 'questions' | 'progress' | 'repo-docs';\n sectionLabel: string;\n title: string;\n snippet: string;\n}\n\ninterface DocsSearchProps {\n query: string;\n}\n\nconst searchIn = (text: string, query: string): boolean =>\n text.toLowerCase().includes(query.toLowerCase());\n\nconst snippet = (text: string, query: string, maxLen = 120): string => {\n const idx = text.toLowerCase().indexOf(query.toLowerCase());\n if (idx === -1) return text.slice(0, maxLen);\n const start = Math.max(0, idx - 40);\n const end = Math.min(text.length, idx + query.length + 40);\n let s = text.slice(start, end);\n if (start > 0) s = `…${s}`;\n if (end < text.length) s = `${s}…`;\n return s;\n};\n\nexport const DocsSearch = ({ query }: DocsSearchProps) => {\n const decisions = useAppStore((s) => s.decisions);\n const openQuestions = useAppStore((s) => s.openQuestions);\n const progress = useAppStore((s) => s.progress);\n const repoDocs = useAppStore((s) => s.repoDocs);\n const setActiveDocTitle = useAppStore((s) => s.setActiveDocTitle);\n const setDocSearchQuery = useAppStore((s) => s.setDocSearchQuery);\n const navigate = useNavigate();\n\n const results: SearchMatch[] = [];\n\n for (const d of decisions) {\n if (searchIn(d.title, query) || searchIn(d.body, query)) {\n results.push({\n section: 'decisions',\n sectionLabel: 'Decisions',\n title: d.title,\n snippet: snippet(d.body || d.title, query),\n });\n }\n }\n\n for (const q of openQuestions) {\n if (searchIn(q.title, query) || searchIn(q.body, query)) {\n results.push({\n section: 'questions',\n sectionLabel: 'Open Questions',\n title: q.title,\n snippet: snippet(q.body || q.title, query),\n });\n }\n }\n\n for (const p of progress) {\n for (const item of p.items) {\n if (searchIn(item, query)) {\n results.push({\n section: 'progress',\n sectionLabel: 'Progress',\n title: p.date,\n snippet: snippet(item, query),\n });\n break;\n }\n }\n }\n\n for (const f of repoDocs) {\n if (searchIn(f.name, query) || searchIn(f.content, query)) {\n results.push({\n section: 'repo-docs',\n sectionLabel: 'Repo Docs',\n title: f.name,\n snippet: snippet(f.content, query),\n });\n }\n }\n\n const grouped: Record<string, SearchMatch[]> = {};\n for (const r of results) {\n if (!grouped[r.section]) grouped[r.section] = [];\n grouped[r.section].push(r);\n }\n\n const handleSelect = (section: SearchMatch['section'], title: string) => {\n navigate({ to: '/docs/$section', params: { section } });\n setActiveDocTitle(title);\n setDocSearchQuery('');\n };\n\n if (results.length === 0) {\n return <p style={{ opacity: 0.5 }}>No results found for \"{query}\".</p>;\n }\n\n return (\n <div>\n <p className=\"text-sm\" style={{ opacity: 0.5, marginBottom: space[3] }}>\n {results.length} result{results.length === 1 ? '' : 's'} for \"{query}\"\n </p>\n {Object.entries(grouped).map(([section, matches]) => (\n <div key={section} style={{ marginBottom: space[6] }}>\n <h3\n className=\"text-xs\"\n style={{\n fontWeight: 600,\n letterSpacing: '0.1em',\n textTransform: 'uppercase',\n opacity: 0.4,\n margin: `0 0 ${space[2]}`,\n }}\n >\n {matches[0].sectionLabel}\n </h3>\n <div style={{ display: 'flex', flexDirection: 'column', gap: space[1] }}>\n {matches.map((m) => (\n <Button\n key={`${m.section}-${m.title}`}\n variant=\"ghost\"\n size=\"small\"\n fullWidth\n onClick={() => handleSelect(m.section, m.title)}\n style={{ justifyContent: 'flex-start', padding: `${space[2]} ${space[3]}` }}\n >\n <span style={{ textAlign: 'left' }}>\n <span\n style={{\n fontFamily: fontFamily.serif,\n fontWeight: 600,\n fontSize: '0.95rem',\n display: 'block',\n marginBottom: '0.2rem',\n }}\n >\n {m.title}\n </span>\n <span className=\"text-sm\" style={{ opacity: 0.6 }}>\n {m.snippet}\n </span>\n </span>\n </Button>\n ))}\n </div>\n </div>\n ))}\n </div>\n );\n};\n","import { LinkButton, Markdown } from '@/app/components';\nimport { detailHeadingStyle } from '@/app/components/detail-heading-style';\nimport { resolveOpenQuestion } from '@/app/services/content';\nimport { useAppStore } from '@/app/stores';\nimport { color, fontFamily, fontSize, lineHeight, space } from '@/app/styles/tokens';\nimport { Button, Input, Modal, Stamp, Textarea, useToast } from '@dendelion/paper-ui';\nimport { useNavigate } from '@tanstack/react-router';\nimport { useState } from 'react';\nimport { QUESTION_STATUS_STAMP } from '../../plans/constants';\n\nexport const OpenQuestionDetail = () => {\n const openQuestions = useAppStore((s) => s.openQuestions);\n const activeDocTitle = useAppStore((s) => s.activeDocTitle);\n const setActiveDocTitle = useAppStore((s) => s.setActiveDocTitle);\n const loadDecisions = useAppStore((s) => s.loadDecisions);\n const loadOpenQuestions = useAppStore((s) => s.loadOpenQuestions);\n const navigate = useNavigate();\n const { toast } = useToast();\n\n const [modalOpen, setModalOpen] = useState(false);\n const [decision, setDecision] = useState('');\n const [rationale, setRationale] = useState('');\n const [loading, setLoading] = useState(false);\n\n const question = openQuestions.find((q) => q.title === activeDocTitle);\n if (!question) return null;\n\n const handleResolvedByClick = () => {\n if (question.resolvedBy) {\n navigate({ to: '/docs/$section', params: { section: 'decisions' } });\n setActiveDocTitle(question.resolvedBy);\n }\n };\n\n const handleOpenModal = () => {\n setDecision('');\n setRationale('');\n setLoading(false);\n setModalOpen(true);\n };\n\n const handleClose = () => {\n setModalOpen(false);\n };\n\n const handleResolve = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!decision.trim() || loading) return;\n setLoading(true);\n try {\n await resolveOpenQuestion(question.title, decision.trim(), rationale.trim() || undefined);\n setModalOpen(false);\n await Promise.all([loadDecisions(), loadOpenQuestions()]);\n } catch (err) {\n setLoading(false);\n toast({\n title: 'Resolve failed',\n description: (err as Error).message,\n variant: 'error',\n });\n }\n };\n\n return (\n <div>\n <h2 style={{ ...detailHeadingStyle, margin: `0 0 ${space[3]}` }}>{question.title}</h2>\n\n <div style={{ display: 'flex', alignItems: 'center', gap: space[2], marginBottom: space[5] }}>\n <span className=\"text-sm\" style={{ opacity: 0.5 }}>\n {question.raised}\n </span>\n <Stamp\n size=\"small\"\n fillColor={QUESTION_STATUS_STAMP[question.status].fill}\n textColor={QUESTION_STATUS_STAMP[question.status].text}\n >\n {question.status}\n </Stamp>\n {question.resolvedBy && (\n <span className=\"text-sm\" style={{ opacity: 0.5 }}>\n Resolved by{' '}\n <LinkButton onClick={handleResolvedByClick}>{question.resolvedBy}</LinkButton>\n </span>\n )}\n {question.status === 'open' && (\n <Button surface=\"chalkboard\" onClick={handleOpenModal}>\n Resolve\n </Button>\n )}\n </div>\n\n <div\n style={{\n fontFamily: fontFamily.body,\n fontSize: fontSize.base,\n lineHeight: lineHeight.relaxed,\n color: color.textProse,\n }}\n >\n <Markdown>{question.body}</Markdown>\n </div>\n\n <Modal open={modalOpen} onClose={handleClose} title=\"Resolve question\" size=\"small\">\n <form\n onSubmit={handleResolve}\n style={{ display: 'flex', flexDirection: 'column', gap: space[4] }}\n >\n <Input\n label=\"Decision\"\n value={decision}\n onChange={(e) => setDecision(e.target.value)}\n placeholder=\"What was decided?\"\n disabled={loading}\n autoFocus\n required\n />\n <Textarea\n label=\"Rationale\"\n value={rationale}\n onChange={(e) => setRationale(e.target.value)}\n placeholder=\"Optional reasoning…\"\n disabled={loading}\n rows={4}\n />\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: space[2] }}>\n <Button type=\"button\" variant=\"ghost\" onClick={handleClose} disabled={loading}>\n Cancel\n </Button>\n <Button type=\"submit\" variant=\"primary\" disabled={!decision.trim() || loading}>\n Resolve\n </Button>\n </div>\n </form>\n </Modal>\n </div>\n );\n};\n","import { Markdown } from '@/app/components/markdown';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { color, fontFamily, fontSize, lineHeight, space } from '@/app/styles/tokens';\n\nexport const ProgressTimeline = () => {\n const progress = useAppStore((s) => s.progress);\n const activeDocTitle = useAppStore((s) => s.activeDocTitle);\n\n const entries = activeDocTitle ? progress.filter((p) => p.date === activeDocTitle) : progress;\n\n const sorted = [...entries].sort((a, b) => b.date.localeCompare(a.date));\n\n if (sorted.length === 0) {\n return <p style={{ opacity: 0.5 }}>No progress entries found.</p>;\n }\n\n return (\n <div>\n {sorted.map((entry) => (\n <div key={entry.date} style={{ marginBottom: space[8] }}>\n <h3\n style={{\n fontFamily: fontFamily.serif,\n fontWeight: 600,\n fontSize: fontSize.md,\n margin: `0 0 ${space[3]}`,\n lineHeight: lineHeight.tight,\n opacity: 0.8,\n }}\n >\n {entry.date}\n </h3>\n <ul\n style={{\n listStyle: 'none',\n padding: 0,\n margin: 0,\n display: 'flex',\n flexDirection: 'column',\n gap: space[2],\n }}\n >\n {entry.items.map((item, i) => (\n <li\n key={`${entry.date}-${i}`}\n style={{\n fontFamily: fontFamily.body,\n fontSize: fontSize.sm,\n lineHeight: 1.55,\n color: color.textProse,\n paddingLeft: space[4],\n borderLeft: '2px solid rgba(0,0,0,0.08)',\n }}\n >\n <Markdown>{item}</Markdown>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n );\n};\n","import { detailHeadingStyle } from '@/app/components/detail-heading-style';\nimport { Markdown } from '@/app/components/markdown';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { color, fontFamily, fontSize, lineHeight, space } from '@/app/styles/tokens';\n\nexport const RepoDocDetail = () => {\n const repoDocs = useAppStore((s) => s.repoDocs);\n const activeDocTitle = useAppStore((s) => s.activeDocTitle);\n\n const file = repoDocs.find((f) => f.name === activeDocTitle);\n if (!file) return null;\n\n const isMarkdown = file.name.endsWith('.md');\n\n return (\n <div>\n <h2 style={{ ...detailHeadingStyle, margin: `0 0 ${space[4]}` }}>{file.name}</h2>\n\n {isMarkdown ? (\n <div\n style={{\n fontFamily: fontFamily.body,\n fontSize: fontSize.base,\n lineHeight: lineHeight.relaxed,\n color: color.textProse,\n }}\n >\n <Markdown>{file.content}</Markdown>\n </div>\n ) : (\n <pre\n style={{\n fontFamily: fontFamily.mono,\n fontSize: fontSize.xs,\n background: 'rgba(0,0,0,0.04)',\n borderRadius: 6,\n padding: space[4],\n overflowX: 'auto',\n lineHeight: lineHeight.normal,\n whiteSpace: 'pre-wrap',\n }}\n >\n {file.content}\n </pre>\n )}\n </div>\n );\n};\n","import { PageTitle } from '@/app/components/page-title';\nimport { useResolvedDocSection } from '@/app/hooks';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { space } from '@/app/styles/tokens';\nimport { Breadcrumb } from '@dendelion/paper-ui';\nimport { useNavigate } from '@tanstack/react-router';\nimport { DecisionDetail } from './components/decision-detail';\nimport { DocsSearch } from './components/docs-search';\nimport { OpenQuestionDetail } from './components/open-question-detail';\nimport { ProgressTimeline } from './components/progress-timeline';\nimport { RepoDocDetail } from './components/repo-doc-detail';\n\n/** Docs / <item> breadcrumb above a doc detail view — the \"Docs\" crumb navigates back. */\nconst DocsBreadcrumb = ({\n itemId,\n label,\n onBack,\n}: {\n itemId: string;\n label: string;\n onBack: () => void;\n}) => (\n <div style={{ marginBottom: space[4] }}>\n <Breadcrumb\n items={[\n { id: 'docs', label: 'Docs', onClick: onBack },\n { id: itemId, label },\n ]}\n />\n </div>\n);\n\nexport const DocsPage = () => {\n const docSearchQuery = useAppStore((s) => s.docSearchQuery);\n const activeDocTitle = useAppStore((s) => s.activeDocTitle);\n const navigate = useNavigate();\n const activeDocSection = useResolvedDocSection();\n\n const handleBackToDocs = () => navigate({ to: '/docs' });\n\n if (docSearchQuery.trim()) {\n return (\n <div>\n <DocsSearch query={docSearchQuery} />\n </div>\n );\n }\n\n if (activeDocSection === 'decisions' && activeDocTitle) {\n return (\n <div>\n <DocsBreadcrumb itemId=\"decision\" label={activeDocTitle} onBack={handleBackToDocs} />\n <PageTitle>Decisions</PageTitle>\n <DecisionDetail />\n </div>\n );\n }\n\n if (activeDocSection === 'questions' && activeDocTitle) {\n return (\n <div>\n <DocsBreadcrumb itemId=\"question\" label={activeDocTitle} onBack={handleBackToDocs} />\n <PageTitle>Open Questions</PageTitle>\n <OpenQuestionDetail />\n </div>\n );\n }\n\n if (activeDocSection === 'progress') {\n return (\n <div>\n <DocsBreadcrumb\n itemId=\"progress\"\n label={activeDocTitle ?? 'Progress'}\n onBack={handleBackToDocs}\n />\n <PageTitle>Progress</PageTitle>\n <ProgressTimeline />\n </div>\n );\n }\n\n if (activeDocSection === 'repo-docs' && activeDocTitle) {\n return (\n <div>\n <DocsBreadcrumb itemId=\"repo-doc\" label={activeDocTitle} onBack={handleBackToDocs} />\n <RepoDocDetail />\n </div>\n );\n }\n\n return (\n <div>\n <PageTitle>Docs</PageTitle>\n <p style={{ opacity: 0.5 }}>Select a section from the sidebar.</p>\n </div>\n );\n};\n","import { useResolvedDocSection } from '@/app/hooks';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { space } from '@/app/styles/tokens';\nimport { Input, ListItem } from '@dendelion/paper-ui';\nimport { useNavigate } from '@tanstack/react-router';\nimport { useEffect } from 'react';\nimport { SidebarSection } from '../../plans/components/sidebar-section';\n\nconst simplecaseLabel = (name: string) =>\n name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();\n\nconst EmptyState = ({ children }: { children: React.ReactNode }) => (\n <span\n className=\"text-sm\"\n style={{\n display: 'block',\n padding: `${space[1]} ${space[3]}`,\n opacity: 0.35,\n fontStyle: 'italic',\n }}\n >\n {children}\n </span>\n);\n\nexport const DocsSidebar = () => {\n const decisions = useAppStore((s) => s.decisions);\n const openQuestions = useAppStore((s) => s.openQuestions);\n const progress = useAppStore((s) => s.progress);\n const repoDocs = useAppStore((s) => s.repoDocs);\n const decisionsLoading = useAppStore((s) => s.decisionsLoading);\n const openQuestionsLoading = useAppStore((s) => s.openQuestionsLoading);\n const progressLoading = useAppStore((s) => s.progressLoading);\n const repoDocsLoading = useAppStore((s) => s.repoDocsLoading);\n const loadDecisions = useAppStore((s) => s.loadDecisions);\n const loadOpenQuestions = useAppStore((s) => s.loadOpenQuestions);\n const loadProgress = useAppStore((s) => s.loadProgress);\n const loadRepoDocs = useAppStore((s) => s.loadRepoDocs);\n const activeDocTitle = useAppStore((s) => s.activeDocTitle);\n const setActiveDocTitle = useAppStore((s) => s.setActiveDocTitle);\n const docSearchQuery = useAppStore((s) => s.docSearchQuery);\n const setDocSearchQuery = useAppStore((s) => s.setDocSearchQuery);\n const activeDocSection = useResolvedDocSection();\n const navigate = useNavigate();\n\n useEffect(() => {\n loadDecisions();\n loadOpenQuestions();\n loadProgress();\n loadRepoDocs();\n }, [loadDecisions, loadOpenQuestions, loadProgress, loadRepoDocs]);\n\n const handleSelectDecision = (title: string) => {\n navigate({ to: '/docs/$section', params: { section: 'decisions' } });\n setActiveDocTitle(title);\n };\n\n return (\n <>\n <div style={{ marginBottom: space[4] }}>\n <Input\n size=\"small\"\n aria-label=\"Search docs\"\n placeholder=\"Search docs…\"\n value={docSearchQuery}\n onChange={(e) => setDocSearchQuery(e.target.value)}\n />\n </div>\n\n <SidebarSection label=\"Repo Docs\">\n {repoDocsLoading && repoDocs.length === 0 ? (\n <EmptyState>Loading…</EmptyState>\n ) : repoDocs.length > 0 ? (\n repoDocs.map((f) => (\n <ListItem\n key={f.name}\n size=\"small\"\n active={activeDocSection === 'repo-docs' && activeDocTitle === f.name}\n onClick={() => {\n navigate({ to: '/docs/$section', params: { section: 'repo-docs' } });\n setActiveDocTitle(f.name);\n }}\n >\n {simplecaseLabel(f.name)}\n </ListItem>\n ))\n ) : (\n <EmptyState>No repo docs found</EmptyState>\n )}\n </SidebarSection>\n\n <SidebarSection label=\"Decisions\">\n {decisionsLoading && decisions.length === 0 ? (\n <EmptyState>Loading…</EmptyState>\n ) : decisions.length > 0 ? (\n decisions.map((d) => (\n <ListItem\n key={d.title}\n size=\"small\"\n active={activeDocSection === 'decisions' && activeDocTitle === d.title}\n onClick={() => handleSelectDecision(d.title)}\n >\n {d.title}\n </ListItem>\n ))\n ) : (\n <EmptyState>No decisions yet</EmptyState>\n )}\n </SidebarSection>\n\n <SidebarSection label=\"Open Questions\">\n {openQuestionsLoading && openQuestions.length === 0 ? (\n <EmptyState>Loading…</EmptyState>\n ) : openQuestions.length > 0 ? (\n openQuestions.map((q) => (\n <ListItem\n key={q.title}\n size=\"small\"\n active={activeDocSection === 'questions' && activeDocTitle === q.title}\n onClick={() => {\n navigate({ to: '/docs/$section', params: { section: 'questions' } });\n setActiveDocTitle(q.title);\n }}\n >\n {q.title}\n </ListItem>\n ))\n ) : (\n <EmptyState>No open questions</EmptyState>\n )}\n </SidebarSection>\n\n <SidebarSection label=\"Progress\">\n {progressLoading && progress.length === 0 ? (\n <EmptyState>Loading…</EmptyState>\n ) : progress.length > 0 ? (\n progress.map((p) => (\n <ListItem\n key={p.date}\n size=\"small\"\n active={activeDocSection === 'progress' && activeDocTitle === p.date}\n onClick={() => {\n navigate({ to: '/docs/$section', params: { section: 'progress' } });\n setActiveDocTitle(p.date);\n }}\n >\n {p.date}\n </ListItem>\n ))\n ) : (\n <EmptyState>No progress entries</EmptyState>\n )}\n </SidebarSection>\n </>\n );\n};\n"],"names":["LinkButton","children","onClick","jsx","color","DecisionDetail","decisions","useAppStore","s","openQuestions","activeDocTitle","setActiveDocTitle","navigate","useNavigate","decision","d","resolvedQuestions","q","detailHeadingStyle","space","Stamp","DECISION_STATUS_STAMP","jsxs","i","fontFamily","fontSize","lineHeight","Markdown","searchIn","text","query","snippet","maxLen","idx","start","end","DocsSearch","progress","repoDocs","setDocSearchQuery","results","p","item","f","grouped","r","handleSelect","section","title","matches","Button","OpenQuestionDetail","loadDecisions","loadOpenQuestions","toast","useToast","modalOpen","setModalOpen","useState","setDecision","rationale","setRationale","loading","setLoading","question","handleResolvedByClick","handleOpenModal","handleClose","handleResolve","e","resolveOpenQuestion","err","QUESTION_STATUS_STAMP","Modal","Input","Textarea","ProgressTimeline","sorted","a","b","entry","RepoDocDetail","file","isMarkdown","DocsBreadcrumb","itemId","label","onBack","Breadcrumb","DocsPage","docSearchQuery","activeDocSection","useResolvedDocSection","handleBackToDocs","PageTitle","simplecaseLabel","name","EmptyState","DocsSidebar","decisionsLoading","openQuestionsLoading","progressLoading","repoDocsLoading","loadProgress","loadRepoDocs","useEffect","handleSelectDecision","Fragment","SidebarSection","ListItem"],"mappings":"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"}
1
+ {"version":3,"file":"index-D-nmg_4I.js","sources":["../../../src/app/components/link-button.tsx","../../../src/app/features/docs/components/decision-detail.tsx","../../../src/app/features/docs/components/docs-search.tsx","../../../src/app/features/docs/components/open-question-detail.tsx","../../../src/app/features/docs/components/progress-timeline.tsx","../../../src/app/features/docs/components/repo-doc-detail.tsx","../../../src/app/features/docs/docs-page.tsx","../../../src/app/features/docs/components/docs-sidebar.tsx"],"sourcesContent":["import { color } from '@/app/styles/tokens';\n\ninterface LinkButtonProps {\n children: React.ReactNode;\n onClick: () => void;\n}\n\nexport const LinkButton = ({ children, onClick }: LinkButtonProps) => (\n <button\n type=\"button\"\n onClick={onClick}\n style={{\n background: 'none',\n border: 'none',\n padding: 0,\n color: color.accentAmberDark,\n cursor: 'pointer',\n textDecoration: 'underline',\n font: 'inherit',\n }}\n >\n {children}\n </button>\n);\n","import { LinkButton, Markdown } from '@/app/components';\nimport { detailHeadingStyle } from '@/app/components/detail-heading-style';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { color, fontFamily, fontSize, lineHeight, space } from '@/app/styles/tokens';\nimport { Stamp } from '@dendelion/paper-ui';\nimport { useNavigate } from '@tanstack/react-router';\nimport { DECISION_STATUS_STAMP } from '../../plans/constants';\n\nexport const DecisionDetail = () => {\n const decisions = useAppStore((s) => s.decisions);\n const openQuestions = useAppStore((s) => s.openQuestions);\n const activeDocTitle = useAppStore((s) => s.activeDocTitle);\n const setActiveDocTitle = useAppStore((s) => s.setActiveDocTitle);\n const navigate = useNavigate();\n\n const decision = decisions.find((d) => d.title === activeDocTitle);\n if (!decision) return null;\n\n const resolvedQuestions = openQuestions.filter((q) => q.resolvedBy === decision.title);\n\n return (\n <div>\n <h2 style={{ ...detailHeadingStyle, margin: `0 0 ${space[3]}` }}>{decision.title}</h2>\n\n <div style={{ display: 'flex', alignItems: 'center', gap: space[2], marginBottom: space[5] }}>\n <span className=\"text-sm\" style={{ opacity: 0.5 }}>\n {decision.date}\n </span>\n <Stamp\n size=\"small\"\n fillColor={DECISION_STATUS_STAMP[decision.status].fill}\n textColor={DECISION_STATUS_STAMP[decision.status].text}\n >\n {decision.status}\n </Stamp>\n {decision.supersededBy && (\n <span className=\"text-sm\" style={{ opacity: 0.5 }}>\n Superseded by{' '}\n <LinkButton onClick={() => setActiveDocTitle(decision.supersededBy!)}>\n {decision.supersededBy}\n </LinkButton>\n </span>\n )}\n {resolvedQuestions.length > 0 && (\n <span className=\"text-sm\" style={{ opacity: 0.5 }}>\n {resolvedQuestions.length === 1 ? 'Resolves' : 'Resolves all of'}{' '}\n {resolvedQuestions.map((q, i) => (\n <span key={q.title}>\n {i > 0 && ', '}\n <LinkButton\n onClick={() => {\n navigate({ to: '/docs/$section', params: { section: 'questions' } });\n setActiveDocTitle(q.title);\n }}\n >\n {q.title}\n </LinkButton>\n </span>\n ))}\n </span>\n )}\n </div>\n\n <div\n style={{\n fontFamily: fontFamily.body,\n fontSize: fontSize.base,\n lineHeight: lineHeight.relaxed,\n color: color.textProse,\n }}\n >\n <Markdown>{decision.body}</Markdown>\n </div>\n </div>\n );\n};\n","import { useAppStore } from '@/app/stores/app-store';\nimport { fontFamily, space } from '@/app/styles/tokens';\nimport { Button } from '@dendelion/paper-ui';\nimport { useNavigate } from '@tanstack/react-router';\n\ninterface SearchMatch {\n section: 'decisions' | 'questions' | 'progress' | 'repo-docs';\n sectionLabel: string;\n title: string;\n snippet: string;\n}\n\ninterface DocsSearchProps {\n query: string;\n}\n\nconst searchIn = (text: string, query: string): boolean =>\n text.toLowerCase().includes(query.toLowerCase());\n\nconst snippet = (text: string, query: string, maxLen = 120): string => {\n const idx = text.toLowerCase().indexOf(query.toLowerCase());\n if (idx === -1) return text.slice(0, maxLen);\n const start = Math.max(0, idx - 40);\n const end = Math.min(text.length, idx + query.length + 40);\n let s = text.slice(start, end);\n if (start > 0) s = `…${s}`;\n if (end < text.length) s = `${s}…`;\n return s;\n};\n\nexport const DocsSearch = ({ query }: DocsSearchProps) => {\n const decisions = useAppStore((s) => s.decisions);\n const openQuestions = useAppStore((s) => s.openQuestions);\n const progress = useAppStore((s) => s.progress);\n const repoDocs = useAppStore((s) => s.repoDocs);\n const setActiveDocTitle = useAppStore((s) => s.setActiveDocTitle);\n const setDocSearchQuery = useAppStore((s) => s.setDocSearchQuery);\n const navigate = useNavigate();\n\n const results: SearchMatch[] = [];\n\n for (const d of decisions) {\n if (searchIn(d.title, query) || searchIn(d.body, query)) {\n results.push({\n section: 'decisions',\n sectionLabel: 'Decisions',\n title: d.title,\n snippet: snippet(d.body || d.title, query),\n });\n }\n }\n\n for (const q of openQuestions) {\n if (searchIn(q.title, query) || searchIn(q.body, query)) {\n results.push({\n section: 'questions',\n sectionLabel: 'Open Questions',\n title: q.title,\n snippet: snippet(q.body || q.title, query),\n });\n }\n }\n\n for (const p of progress) {\n for (const item of p.items) {\n if (searchIn(item, query)) {\n results.push({\n section: 'progress',\n sectionLabel: 'Progress',\n title: p.date,\n snippet: snippet(item, query),\n });\n break;\n }\n }\n }\n\n for (const f of repoDocs) {\n if (searchIn(f.name, query) || searchIn(f.content, query)) {\n results.push({\n section: 'repo-docs',\n sectionLabel: 'Repo Docs',\n title: f.name,\n snippet: snippet(f.content, query),\n });\n }\n }\n\n const grouped: Record<string, SearchMatch[]> = {};\n for (const r of results) {\n if (!grouped[r.section]) grouped[r.section] = [];\n grouped[r.section].push(r);\n }\n\n const handleSelect = (section: SearchMatch['section'], title: string) => {\n navigate({ to: '/docs/$section', params: { section } });\n setActiveDocTitle(title);\n setDocSearchQuery('');\n };\n\n if (results.length === 0) {\n return <p style={{ opacity: 0.5 }}>No results found for \"{query}\".</p>;\n }\n\n return (\n <div>\n <p className=\"text-sm\" style={{ opacity: 0.5, marginBottom: space[3] }}>\n {results.length} result{results.length === 1 ? '' : 's'} for \"{query}\"\n </p>\n {Object.entries(grouped).map(([section, matches]) => (\n <div key={section} style={{ marginBottom: space[6] }}>\n <h3\n className=\"text-xs\"\n style={{\n fontWeight: 600,\n letterSpacing: '0.1em',\n textTransform: 'uppercase',\n opacity: 0.4,\n margin: `0 0 ${space[2]}`,\n }}\n >\n {matches[0].sectionLabel}\n </h3>\n <div style={{ display: 'flex', flexDirection: 'column', gap: space[1] }}>\n {matches.map((m) => (\n <Button\n key={`${m.section}-${m.title}`}\n variant=\"ghost\"\n size=\"small\"\n fullWidth\n onClick={() => handleSelect(m.section, m.title)}\n style={{ justifyContent: 'flex-start', padding: `${space[2]} ${space[3]}` }}\n >\n <span style={{ textAlign: 'left' }}>\n <span\n style={{\n fontFamily: fontFamily.serif,\n fontWeight: 600,\n fontSize: '0.95rem',\n display: 'block',\n marginBottom: '0.2rem',\n }}\n >\n {m.title}\n </span>\n <span className=\"text-sm\" style={{ opacity: 0.6 }}>\n {m.snippet}\n </span>\n </span>\n </Button>\n ))}\n </div>\n </div>\n ))}\n </div>\n );\n};\n","import { LinkButton, Markdown } from '@/app/components';\nimport { detailHeadingStyle } from '@/app/components/detail-heading-style';\nimport { resolveOpenQuestion } from '@/app/services/content';\nimport { useAppStore } from '@/app/stores';\nimport { color, fontFamily, fontSize, lineHeight, space } from '@/app/styles/tokens';\nimport { Button, Input, Modal, Stamp, Textarea, useToast } from '@dendelion/paper-ui';\nimport { useNavigate } from '@tanstack/react-router';\nimport { useState } from 'react';\nimport { QUESTION_STATUS_STAMP } from '../../plans/constants';\n\nexport const OpenQuestionDetail = () => {\n const openQuestions = useAppStore((s) => s.openQuestions);\n const activeDocTitle = useAppStore((s) => s.activeDocTitle);\n const setActiveDocTitle = useAppStore((s) => s.setActiveDocTitle);\n const loadDecisions = useAppStore((s) => s.loadDecisions);\n const loadOpenQuestions = useAppStore((s) => s.loadOpenQuestions);\n const navigate = useNavigate();\n const { toast } = useToast();\n\n const [modalOpen, setModalOpen] = useState(false);\n const [decision, setDecision] = useState('');\n const [rationale, setRationale] = useState('');\n const [loading, setLoading] = useState(false);\n\n const question = openQuestions.find((q) => q.title === activeDocTitle);\n if (!question) return null;\n\n const handleResolvedByClick = () => {\n if (question.resolvedBy) {\n navigate({ to: '/docs/$section', params: { section: 'decisions' } });\n setActiveDocTitle(question.resolvedBy);\n }\n };\n\n const handleOpenModal = () => {\n setDecision('');\n setRationale('');\n setLoading(false);\n setModalOpen(true);\n };\n\n const handleClose = () => {\n setModalOpen(false);\n };\n\n const handleResolve = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!decision.trim() || loading) return;\n setLoading(true);\n try {\n await resolveOpenQuestion(question.title, decision.trim(), rationale.trim() || undefined);\n setModalOpen(false);\n await Promise.all([loadDecisions(), loadOpenQuestions()]);\n } catch (err) {\n setLoading(false);\n toast({\n title: 'Resolve failed',\n description: (err as Error).message,\n variant: 'error',\n });\n }\n };\n\n return (\n <div>\n <h2 style={{ ...detailHeadingStyle, margin: `0 0 ${space[3]}` }}>{question.title}</h2>\n\n <div style={{ display: 'flex', alignItems: 'center', gap: space[2], marginBottom: space[5] }}>\n <span className=\"text-sm\" style={{ opacity: 0.5 }}>\n {question.raised}\n </span>\n <Stamp\n size=\"small\"\n fillColor={QUESTION_STATUS_STAMP[question.status].fill}\n textColor={QUESTION_STATUS_STAMP[question.status].text}\n >\n {question.status}\n </Stamp>\n {question.resolvedBy && (\n <span className=\"text-sm\" style={{ opacity: 0.5 }}>\n Resolved by{' '}\n <LinkButton onClick={handleResolvedByClick}>{question.resolvedBy}</LinkButton>\n </span>\n )}\n {question.status === 'open' && (\n <Button surface=\"chalkboard\" onClick={handleOpenModal}>\n Resolve\n </Button>\n )}\n </div>\n\n <div\n style={{\n fontFamily: fontFamily.body,\n fontSize: fontSize.base,\n lineHeight: lineHeight.relaxed,\n color: color.textProse,\n }}\n >\n <Markdown>{question.body}</Markdown>\n </div>\n\n <Modal open={modalOpen} onClose={handleClose} title=\"Resolve question\" size=\"small\">\n <form\n onSubmit={handleResolve}\n style={{ display: 'flex', flexDirection: 'column', gap: space[4] }}\n >\n <Input\n label=\"Decision\"\n value={decision}\n onChange={(e) => setDecision(e.target.value)}\n placeholder=\"What was decided?\"\n disabled={loading}\n autoFocus\n required\n />\n <Textarea\n label=\"Rationale\"\n value={rationale}\n onChange={(e) => setRationale(e.target.value)}\n placeholder=\"Optional reasoning…\"\n disabled={loading}\n rows={4}\n />\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: space[2] }}>\n <Button type=\"button\" variant=\"ghost\" onClick={handleClose} disabled={loading}>\n Cancel\n </Button>\n <Button type=\"submit\" variant=\"primary\" disabled={!decision.trim() || loading}>\n Resolve\n </Button>\n </div>\n </form>\n </Modal>\n </div>\n );\n};\n","import { Markdown } from '@/app/components/markdown';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { color, fontFamily, fontSize, lineHeight, space } from '@/app/styles/tokens';\n\nexport const ProgressTimeline = () => {\n const progress = useAppStore((s) => s.progress);\n const activeDocTitle = useAppStore((s) => s.activeDocTitle);\n\n const entries = activeDocTitle ? progress.filter((p) => p.date === activeDocTitle) : progress;\n\n const sorted = [...entries].sort((a, b) => b.date.localeCompare(a.date));\n\n if (sorted.length === 0) {\n return <p style={{ opacity: 0.5 }}>No progress entries found.</p>;\n }\n\n return (\n <div>\n {sorted.map((entry) => (\n <div key={entry.date} style={{ marginBottom: space[8] }}>\n <h3\n style={{\n fontFamily: fontFamily.serif,\n fontWeight: 600,\n fontSize: fontSize.md,\n margin: `0 0 ${space[3]}`,\n lineHeight: lineHeight.tight,\n opacity: 0.8,\n }}\n >\n {entry.date}\n </h3>\n <ul\n style={{\n listStyle: 'none',\n padding: 0,\n margin: 0,\n display: 'flex',\n flexDirection: 'column',\n gap: space[2],\n }}\n >\n {entry.items.map((item, i) => (\n <li\n key={`${entry.date}-${i}`}\n style={{\n fontFamily: fontFamily.body,\n fontSize: fontSize.sm,\n lineHeight: 1.55,\n color: color.textProse,\n paddingLeft: space[4],\n borderLeft: '2px solid rgba(0,0,0,0.08)',\n }}\n >\n <Markdown>{item}</Markdown>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n );\n};\n","import { detailHeadingStyle } from '@/app/components/detail-heading-style';\nimport { Markdown } from '@/app/components/markdown';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { color, fontFamily, fontSize, lineHeight, space } from '@/app/styles/tokens';\n\nexport const RepoDocDetail = () => {\n const repoDocs = useAppStore((s) => s.repoDocs);\n const activeDocTitle = useAppStore((s) => s.activeDocTitle);\n\n const file = repoDocs.find((f) => f.name === activeDocTitle);\n if (!file) return null;\n\n const isMarkdown = file.name.endsWith('.md');\n\n return (\n <div>\n <h2 style={{ ...detailHeadingStyle, margin: `0 0 ${space[4]}` }}>{file.name}</h2>\n\n {isMarkdown ? (\n <div\n style={{\n fontFamily: fontFamily.body,\n fontSize: fontSize.base,\n lineHeight: lineHeight.relaxed,\n color: color.textProse,\n }}\n >\n <Markdown>{file.content}</Markdown>\n </div>\n ) : (\n <pre\n style={{\n fontFamily: fontFamily.mono,\n fontSize: fontSize.xs,\n background: 'rgba(0,0,0,0.04)',\n borderRadius: 6,\n padding: space[4],\n overflowX: 'auto',\n lineHeight: lineHeight.normal,\n whiteSpace: 'pre-wrap',\n }}\n >\n {file.content}\n </pre>\n )}\n </div>\n );\n};\n","import { PageTitle } from '@/app/components/page-title';\nimport { useResolvedDocSection } from '@/app/hooks';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { space } from '@/app/styles/tokens';\nimport { Breadcrumb } from '@dendelion/paper-ui';\nimport { useNavigate } from '@tanstack/react-router';\nimport { DecisionDetail } from './components/decision-detail';\nimport { DocsSearch } from './components/docs-search';\nimport { OpenQuestionDetail } from './components/open-question-detail';\nimport { ProgressTimeline } from './components/progress-timeline';\nimport { RepoDocDetail } from './components/repo-doc-detail';\n\n/** Docs / <item> breadcrumb above a doc detail view — the \"Docs\" crumb navigates back. */\nconst DocsBreadcrumb = ({\n itemId,\n label,\n onBack,\n}: {\n itemId: string;\n label: string;\n onBack: () => void;\n}) => (\n <div style={{ marginBottom: space[4] }}>\n <Breadcrumb\n items={[\n { id: 'docs', label: 'Docs', onClick: onBack },\n { id: itemId, label },\n ]}\n />\n </div>\n);\n\nexport const DocsPage = () => {\n const docSearchQuery = useAppStore((s) => s.docSearchQuery);\n const activeDocTitle = useAppStore((s) => s.activeDocTitle);\n const navigate = useNavigate();\n const activeDocSection = useResolvedDocSection();\n\n const handleBackToDocs = () => navigate({ to: '/docs' });\n\n if (docSearchQuery.trim()) {\n return (\n <div>\n <DocsSearch query={docSearchQuery} />\n </div>\n );\n }\n\n if (activeDocSection === 'decisions' && activeDocTitle) {\n return (\n <div>\n <DocsBreadcrumb itemId=\"decision\" label={activeDocTitle} onBack={handleBackToDocs} />\n <PageTitle>Decisions</PageTitle>\n <DecisionDetail />\n </div>\n );\n }\n\n if (activeDocSection === 'questions' && activeDocTitle) {\n return (\n <div>\n <DocsBreadcrumb itemId=\"question\" label={activeDocTitle} onBack={handleBackToDocs} />\n <PageTitle>Open Questions</PageTitle>\n <OpenQuestionDetail />\n </div>\n );\n }\n\n if (activeDocSection === 'progress') {\n return (\n <div>\n <DocsBreadcrumb\n itemId=\"progress\"\n label={activeDocTitle ?? 'Progress'}\n onBack={handleBackToDocs}\n />\n <PageTitle>Progress</PageTitle>\n <ProgressTimeline />\n </div>\n );\n }\n\n if (activeDocSection === 'repo-docs' && activeDocTitle) {\n return (\n <div>\n <DocsBreadcrumb itemId=\"repo-doc\" label={activeDocTitle} onBack={handleBackToDocs} />\n <RepoDocDetail />\n </div>\n );\n }\n\n return (\n <div>\n <PageTitle>Docs</PageTitle>\n <p style={{ opacity: 0.5 }}>Select a section from the sidebar.</p>\n </div>\n );\n};\n","import { useResolvedDocSection } from '@/app/hooks';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { space } from '@/app/styles/tokens';\nimport { Input, ListItem } from '@dendelion/paper-ui';\nimport { useNavigate } from '@tanstack/react-router';\nimport { useEffect } from 'react';\nimport { SidebarSection } from '../../plans/components/sidebar-section';\n\nconst simplecaseLabel = (name: string) =>\n name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();\n\nconst EmptyState = ({ children }: { children: React.ReactNode }) => (\n <span\n className=\"text-sm\"\n style={{\n display: 'block',\n padding: `${space[1]} ${space[3]}`,\n opacity: 0.35,\n fontStyle: 'italic',\n }}\n >\n {children}\n </span>\n);\n\nexport const DocsSidebar = () => {\n const decisions = useAppStore((s) => s.decisions);\n const openQuestions = useAppStore((s) => s.openQuestions);\n const progress = useAppStore((s) => s.progress);\n const repoDocs = useAppStore((s) => s.repoDocs);\n const decisionsLoading = useAppStore((s) => s.decisionsLoading);\n const openQuestionsLoading = useAppStore((s) => s.openQuestionsLoading);\n const progressLoading = useAppStore((s) => s.progressLoading);\n const repoDocsLoading = useAppStore((s) => s.repoDocsLoading);\n const loadDecisions = useAppStore((s) => s.loadDecisions);\n const loadOpenQuestions = useAppStore((s) => s.loadOpenQuestions);\n const loadProgress = useAppStore((s) => s.loadProgress);\n const loadRepoDocs = useAppStore((s) => s.loadRepoDocs);\n const activeDocTitle = useAppStore((s) => s.activeDocTitle);\n const setActiveDocTitle = useAppStore((s) => s.setActiveDocTitle);\n const docSearchQuery = useAppStore((s) => s.docSearchQuery);\n const setDocSearchQuery = useAppStore((s) => s.setDocSearchQuery);\n const activeDocSection = useResolvedDocSection();\n const navigate = useNavigate();\n\n useEffect(() => {\n loadDecisions();\n loadOpenQuestions();\n loadProgress();\n loadRepoDocs();\n }, [loadDecisions, loadOpenQuestions, loadProgress, loadRepoDocs]);\n\n const handleSelectDecision = (title: string) => {\n navigate({ to: '/docs/$section', params: { section: 'decisions' } });\n setActiveDocTitle(title);\n };\n\n return (\n <>\n <div style={{ marginBottom: space[4] }}>\n <Input\n size=\"small\"\n aria-label=\"Search docs\"\n placeholder=\"Search docs…\"\n value={docSearchQuery}\n onChange={(e) => setDocSearchQuery(e.target.value)}\n />\n </div>\n\n <SidebarSection label=\"Repo Docs\">\n {repoDocsLoading && repoDocs.length === 0 ? (\n <EmptyState>Loading…</EmptyState>\n ) : repoDocs.length > 0 ? (\n repoDocs.map((f) => (\n <ListItem\n key={f.name}\n size=\"small\"\n active={activeDocSection === 'repo-docs' && activeDocTitle === f.name}\n onClick={() => {\n navigate({ to: '/docs/$section', params: { section: 'repo-docs' } });\n setActiveDocTitle(f.name);\n }}\n >\n {simplecaseLabel(f.name)}\n </ListItem>\n ))\n ) : (\n <EmptyState>No repo docs found</EmptyState>\n )}\n </SidebarSection>\n\n <SidebarSection label=\"Decisions\">\n {decisionsLoading && decisions.length === 0 ? (\n <EmptyState>Loading…</EmptyState>\n ) : decisions.length > 0 ? (\n decisions.map((d) => (\n <ListItem\n key={d.title}\n size=\"small\"\n active={activeDocSection === 'decisions' && activeDocTitle === d.title}\n onClick={() => handleSelectDecision(d.title)}\n >\n {d.title}\n </ListItem>\n ))\n ) : (\n <EmptyState>No decisions yet</EmptyState>\n )}\n </SidebarSection>\n\n <SidebarSection label=\"Open Questions\">\n {openQuestionsLoading && openQuestions.length === 0 ? (\n <EmptyState>Loading…</EmptyState>\n ) : openQuestions.length > 0 ? (\n openQuestions.map((q) => (\n <ListItem\n key={q.title}\n size=\"small\"\n active={activeDocSection === 'questions' && activeDocTitle === q.title}\n onClick={() => {\n navigate({ to: '/docs/$section', params: { section: 'questions' } });\n setActiveDocTitle(q.title);\n }}\n >\n {q.title}\n </ListItem>\n ))\n ) : (\n <EmptyState>No open questions</EmptyState>\n )}\n </SidebarSection>\n\n <SidebarSection label=\"Progress\">\n {progressLoading && progress.length === 0 ? (\n <EmptyState>Loading…</EmptyState>\n ) : progress.length > 0 ? (\n progress.map((p) => (\n <ListItem\n key={p.date}\n size=\"small\"\n active={activeDocSection === 'progress' && activeDocTitle === p.date}\n onClick={() => {\n navigate({ to: '/docs/$section', params: { section: 'progress' } });\n setActiveDocTitle(p.date);\n }}\n >\n {p.date}\n </ListItem>\n ))\n ) : (\n <EmptyState>No progress entries</EmptyState>\n )}\n </SidebarSection>\n </>\n );\n};\n"],"names":["LinkButton","children","onClick","jsx","color","DecisionDetail","decisions","useAppStore","s","openQuestions","activeDocTitle","setActiveDocTitle","navigate","useNavigate","decision","d","resolvedQuestions","q","detailHeadingStyle","space","Stamp","DECISION_STATUS_STAMP","jsxs","i","fontFamily","fontSize","lineHeight","Markdown","searchIn","text","query","snippet","maxLen","idx","start","end","DocsSearch","progress","repoDocs","setDocSearchQuery","results","p","item","f","grouped","r","handleSelect","section","title","matches","Button","OpenQuestionDetail","loadDecisions","loadOpenQuestions","toast","useToast","modalOpen","setModalOpen","useState","setDecision","rationale","setRationale","loading","setLoading","question","handleResolvedByClick","handleOpenModal","handleClose","handleResolve","e","resolveOpenQuestion","err","QUESTION_STATUS_STAMP","Modal","Input","Textarea","ProgressTimeline","sorted","a","b","entry","RepoDocDetail","file","isMarkdown","DocsBreadcrumb","itemId","label","onBack","Breadcrumb","DocsPage","docSearchQuery","activeDocSection","useResolvedDocSection","handleBackToDocs","PageTitle","simplecaseLabel","name","EmptyState","DocsSidebar","decisionsLoading","openQuestionsLoading","progressLoading","repoDocsLoading","loadProgress","loadRepoDocs","useEffect","handleSelectDecision","Fragment","SidebarSection","ListItem"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import{u as h,C as j,r as i,j as e,P as k,s as f,p as x,f as p,B as w,b as u,O as y,c as m,E as S}from"./main-DUy5DFoq.js";const v={phase:"Phase run",audit:"Audit","batch-reconcile":"Batch reconcile","run-all":"Run all phases",draft:"Draft",extend:"Extend",suggest:"Suggest ideas","commit-suggest":"Commit suggest","overlap-check":"Overlap check",sync:"Sync",reconcile:"Reconcile","fix-review":"Fix review"},g=s=>{const t=new Date(s),a=o=>String(o).padStart(2,"0");return`${a(t.getDate())}/${a(t.getMonth()+1)} ${a(t.getHours())}:${a(t.getMinutes())}:${a(t.getSeconds())}`},r={fontSize:p.sm,fontWeight:600,opacity:.6,whiteSpace:"nowrap",overflow:"hidden"},L=({id:s})=>{const[t,a]=i.useState(null);return i.useEffect(()=>{a(null),S(s).then(o=>a(o.lines)).catch(()=>a([]))},[s]),t===null?e.jsx("p",{style:{opacity:.5,margin:0},children:"Loading…"}):t.length===0?e.jsx("p",{style:{opacity:.5,margin:0},children:"No output recorded."}):e.jsx("pre",{style:{fontFamily:u.mono,fontSize:p.xs,margin:0,maxHeight:320,overflowY:"auto",whiteSpace:"pre-wrap"},children:t.join(`
2
+ `)})},N=({size:s=14})=>e.jsx("svg",{width:s,height:s,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:e.jsx("polyline",{points:"9 18 15 12 9 6"})}),E=({entry:s,highlighted:t})=>{const[a,o]=i.useState(t);i.useEffect(()=>{t&&o(!0)},[t]);const c=()=>o(l=>!l);return e.jsxs("div",{className:t?"task-row-highlighted":void 0,style:{display:"flex",flexDirection:"column",gap:f[1],borderRadius:10},children:[e.jsx("div",{role:"button",tabIndex:0,onClick:c,onKeyDown:l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),c())},style:{cursor:"pointer",borderRadius:10},children:e.jsx(x,{size:"small",texture:"canvas",className:"plan-row-card",children:e.jsxs("div",{className:"task-rows-grid",children:[e.jsx("span",{className:"task-rows-chevron","aria-expanded":a,style:{display:"inline-flex",alignItems:"center",opacity:.5},children:e.jsx(N,{})}),e.jsx("span",{style:{fontWeight:600,whiteSpace:"nowrap",overflow:"hidden"},children:v[s.taskKind]}),e.jsx("span",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",opacity:.7},children:s.planTitle}),e.jsx("span",{className:"text-sm",style:{opacity:.5,whiteSpace:"nowrap"},children:w[s.agentId]}),e.jsx("span",{className:"task-rows-cell-time",style:{fontFamily:u.mono,fontSize:p.xs,opacity:.55,whiteSpace:"nowrap"},children:g(s.startedAt)}),e.jsx("span",{className:"task-rows-cell-time",style:{fontFamily:u.mono,fontSize:p.xs,opacity:.55,whiteSpace:"nowrap"},children:g(s.endedAt)}),e.jsx("div",{style:{display:"flex",alignItems:"center"},children:e.jsx(y,{size:"small",fillColor:s.outcome==="done"?"rgba(143, 185, 150, 0.25)":"rgba(201, 139, 139, 0.25)",textColor:s.outcome==="done"?m.accentGreenDark:m.accentRoseDark,children:s.outcome})})]})})}),a&&e.jsx(x,{size:"small",texture:"kraft",className:"plan-row-card",children:e.jsx(L,{id:s.id})})]})},b=()=>{const s=h(n=>n.taskLog),t=h(n=>n.taskLogLoading),a=h(n=>n.loadTaskLog),{taskId:o}=j({from:"/tasks"}),c=i.useRef(null);i.useEffect(()=>{a()},[a]),i.useEffect(()=>{var d;if(!o)return;const n=(d=c.current)==null?void 0:d.querySelector(".task-row-highlighted");n==null||n.scrollIntoView({behavior:"smooth",block:"center"})},[o]);const l=[...s].sort((n,d)=>d.endedAt.localeCompare(n.endedAt));return e.jsxs("div",{ref:c,children:[e.jsx(k,{children:"Tasks"}),t&&e.jsx("p",{style:{opacity:.5},children:"Loading…"}),!t&&l.length===0&&e.jsx("p",{style:{opacity:.5},children:"No tasks have run yet."}),!t&&l.length>0&&e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:f[1]},children:[e.jsx(x,{size:"small",texture:"kraft",className:"plan-row-card",children:e.jsxs("div",{className:"task-rows-grid",children:[e.jsx("span",{}),e.jsx("span",{style:r,children:"Task"}),e.jsx("span",{style:r,children:"Plan"}),e.jsx("span",{style:r,children:"Agent"}),e.jsx("span",{className:"task-rows-cell-time",style:r,children:"Started"}),e.jsx("span",{className:"task-rows-cell-time",style:r,children:"Ended"}),e.jsx("span",{style:r,children:"Outcome"})]})}),l.map(n=>e.jsx(E,{entry:n,highlighted:n.id===o},n.id))]})]})};export{b as TasksPage};
3
+ //# sourceMappingURL=index-Djq8LvrZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-Djq8LvrZ.js","sources":["../../../src/app/features/tasks/tasks-page.tsx"],"sourcesContent":["import { PageTitle } from '@/app/components/page-title';\nimport { fetchTaskLogLines } from '@/app/services/content/docs-api';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { color, fontFamily, fontSize, space } from '@/app/styles/tokens';\nimport { AGENT_LABELS, type TaskKind, type TaskLogEntry } from '@/types/index';\nimport { Card, Stamp } from '@dendelion/paper-ui';\nimport { useSearch } from '@tanstack/react-router';\nimport { useEffect, useRef, useState } from 'react';\n\nconst TASK_KIND_LABELS: Record<TaskKind, string> = {\n phase: 'Phase run',\n audit: 'Audit',\n 'batch-reconcile': 'Batch reconcile',\n 'run-all': 'Run all phases',\n draft: 'Draft',\n extend: 'Extend',\n suggest: 'Suggest ideas',\n 'commit-suggest': 'Commit suggest',\n 'overlap-check': 'Overlap check',\n sync: 'Sync',\n reconcile: 'Reconcile',\n 'fix-review': 'Fix review',\n};\n\nconst formatTimestamp = (iso: string) => {\n const d = new Date(iso);\n const pad = (n: number) => String(n).padStart(2, '0');\n return `${pad(d.getDate())}/${pad(d.getMonth() + 1)} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;\n};\n\nconst headerLabelStyle: React.CSSProperties = {\n fontSize: fontSize.sm,\n fontWeight: 600,\n opacity: 0.6,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n};\n\nconst TaskLogLines = ({ id }: { id: string }) => {\n const [lines, setLines] = useState<string[] | null>(null);\n\n useEffect(() => {\n setLines(null);\n fetchTaskLogLines(id)\n .then((data) => setLines(data.lines))\n .catch(() => setLines([]));\n }, [id]);\n\n if (lines === null) return <p style={{ opacity: 0.5, margin: 0 }}>Loading…</p>;\n if (lines.length === 0) return <p style={{ opacity: 0.5, margin: 0 }}>No output recorded.</p>;\n return (\n <pre\n style={{\n fontFamily: fontFamily.mono,\n fontSize: fontSize.xs,\n margin: 0,\n maxHeight: 320,\n overflowY: 'auto',\n whiteSpace: 'pre-wrap',\n }}\n >\n {lines.join('\\n')}\n </pre>\n );\n};\n\nconst ChevronRightIcon = ({ size = 14 }: { size?: number }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n);\n\nconst TaskRow = ({ entry, highlighted }: { entry: TaskLogEntry; highlighted: boolean }) => {\n const [expanded, setExpanded] = useState(highlighted);\n useEffect(() => {\n if (highlighted) setExpanded(true);\n }, [highlighted]);\n const toggle = () => setExpanded((v) => !v);\n\n return (\n <div\n className={highlighted ? 'task-row-highlighted' : undefined}\n style={{ display: 'flex', flexDirection: 'column', gap: space[1], borderRadius: 10 }}\n >\n {/* biome-ignore lint/a11y/useSemanticElements: the clickable row wraps a Card whose block layout a native <button> would break; keyboard toggling is wired on the div. */}\n <div\n role=\"button\"\n tabIndex={0}\n onClick={toggle}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n toggle();\n }\n }}\n style={{ cursor: 'pointer', borderRadius: 10 }}\n >\n <Card size=\"small\" texture=\"canvas\" className=\"plan-row-card\">\n <div className=\"task-rows-grid\">\n <span\n className=\"task-rows-chevron\"\n aria-expanded={expanded}\n style={{ display: 'inline-flex', alignItems: 'center', opacity: 0.5 }}\n >\n <ChevronRightIcon />\n </span>\n <span style={{ fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden' }}>\n {TASK_KIND_LABELS[entry.taskKind]}\n </span>\n <span\n style={{\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n opacity: 0.7,\n }}\n >\n {entry.planTitle}\n </span>\n <span className=\"text-sm\" style={{ opacity: 0.5, whiteSpace: 'nowrap' }}>\n {AGENT_LABELS[entry.agentId]}\n </span>\n <span\n className=\"task-rows-cell-time\"\n style={{\n fontFamily: fontFamily.mono,\n fontSize: fontSize.xs,\n opacity: 0.55,\n whiteSpace: 'nowrap',\n }}\n >\n {formatTimestamp(entry.startedAt)}\n </span>\n <span\n className=\"task-rows-cell-time\"\n style={{\n fontFamily: fontFamily.mono,\n fontSize: fontSize.xs,\n opacity: 0.55,\n whiteSpace: 'nowrap',\n }}\n >\n {formatTimestamp(entry.endedAt)}\n </span>\n <div style={{ display: 'flex', alignItems: 'center' }}>\n <Stamp\n size=\"small\"\n fillColor={\n entry.outcome === 'done'\n ? 'rgba(143, 185, 150, 0.25)'\n : 'rgba(201, 139, 139, 0.25)'\n }\n textColor={entry.outcome === 'done' ? color.accentGreenDark : color.accentRoseDark}\n >\n {entry.outcome}\n </Stamp>\n </div>\n </div>\n </Card>\n </div>\n {expanded && (\n <Card size=\"small\" texture=\"kraft\" className=\"plan-row-card\">\n <TaskLogLines id={entry.id} />\n </Card>\n )}\n </div>\n );\n};\n\nexport const TasksPage = () => {\n const taskLog = useAppStore((s) => s.taskLog);\n const taskLogLoading = useAppStore((s) => s.taskLogLoading);\n const loadTaskLog = useAppStore((s) => s.loadTaskLog);\n const { taskId } = useSearch({ from: '/tasks' });\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n loadTaskLog();\n }, [loadTaskLog]);\n\n useEffect(() => {\n if (!taskId) return;\n const row = containerRef.current?.querySelector('.task-row-highlighted');\n row?.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }, [taskId]);\n\n const sorted = [...taskLog].sort((a, b) => b.endedAt.localeCompare(a.endedAt));\n\n return (\n <div ref={containerRef}>\n <PageTitle>Tasks</PageTitle>\n {taskLogLoading && <p style={{ opacity: 0.5 }}>Loading…</p>}\n {!taskLogLoading && sorted.length === 0 && (\n <p style={{ opacity: 0.5 }}>No tasks have run yet.</p>\n )}\n {!taskLogLoading && sorted.length > 0 && (\n <div style={{ display: 'flex', flexDirection: 'column', gap: space[1] }}>\n <Card size=\"small\" texture=\"kraft\" className=\"plan-row-card\">\n <div className=\"task-rows-grid\">\n <span />\n <span style={headerLabelStyle}>Task</span>\n <span style={headerLabelStyle}>Plan</span>\n <span style={headerLabelStyle}>Agent</span>\n <span className=\"task-rows-cell-time\" style={headerLabelStyle}>\n Started\n </span>\n <span className=\"task-rows-cell-time\" style={headerLabelStyle}>\n Ended\n </span>\n <span style={headerLabelStyle}>Outcome</span>\n </div>\n </Card>\n {sorted.map((entry) => (\n <TaskRow key={entry.id} entry={entry} highlighted={entry.id === taskId} />\n ))}\n </div>\n )}\n </div>\n );\n};\n"],"names":["TASK_KIND_LABELS","formatTimestamp","iso","d","pad","n","headerLabelStyle","fontSize","TaskLogLines","id","lines","setLines","useState","useEffect","fetchTaskLogLines","data","jsx","fontFamily","ChevronRightIcon","size","TaskRow","entry","highlighted","expanded","setExpanded","toggle","v","jsxs","space","e","Card","AGENT_LABELS","Stamp","color","TasksPage","taskLog","useAppStore","s","taskLogLoading","loadTaskLog","taskId","useSearch","containerRef","useRef","row","_a","sorted","a","b","PageTitle"],"mappings":"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"}