@starlove/orbit 1.1.11 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +0 -0
- package/Dockerfile +0 -0
- package/LICENSE +0 -0
- package/README.md +0 -0
- package/SKILL-ORBIT.md +0 -0
- package/build.mjs +11 -5
- package/dist/full/apple-touch-icon.png +0 -0
- package/dist/full/cursors/live_arrow.cur +0 -0
- package/dist/full/cursors/live_link.cur +0 -0
- package/dist/full/cursors/live_move.cur +0 -0
- package/dist/full/cursors/live_select.cur +0 -0
- package/dist/full/cursors/live_unavail.cur +0 -0
- package/dist/full/favicon-32x32.png +0 -0
- package/dist/full/index.html +11 -7
- package/dist/full/js/{app.55b38e12.js → app.ccc442f7.js} +85 -77
- package/dist/full/js/app.ccc442f7.js.map +7 -0
- package/dist/full/orbits-favicon.png +0 -0
- package/dist/full/orbits-logo-bg.png +0 -0
- package/dist/full/orbits-logo.png +0 -0
- package/dist/full/styles.b7c19a07.css +1 -0
- package/dist/full/version.json +2 -2
- package/docs/AGENT_PROTOCOL.md +0 -0
- package/docs/MCP_SETUP.md +0 -0
- package/docs/ORBIT_DISPATCH.md +0 -0
- package/docs/SS-Orbit-Dark.png +0 -0
- package/docs/SS-Orbit-Light.png +0 -0
- package/docs/mcp-client.example.json +0 -0
- package/docs/setup/orbit-init-wizard.md +0 -0
- package/package.json +6 -3
- package/public/apple-touch-icon.png +0 -0
- package/public/cursors/live_arrow.cur +0 -0
- package/public/cursors/live_link.cur +0 -0
- package/public/cursors/live_move.cur +0 -0
- package/public/cursors/live_select.cur +0 -0
- package/public/cursors/live_unavail.cur +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/index.html +9 -5
- package/public/js/actor-labels.js +0 -0
- package/public/js/api.js +0 -0
- package/public/js/app.js +0 -0
- package/public/js/board-menu.js +16 -2
- package/public/js/card-actions.js +0 -0
- package/public/js/config.js +0 -0
- package/public/js/create-card.js +1 -1
- package/public/js/dom.js +0 -0
- package/public/js/drawer.js +1 -1
- package/public/js/format.js +2 -3
- package/public/js/kanban.js +10 -9
- package/public/js/local-backend.js +0 -0
- package/public/js/main.js +0 -0
- package/public/js/modal.js +0 -0
- package/public/js/motion-preference.js +0 -0
- package/public/js/router.js +0 -0
- package/public/js/search.js +1 -1
- package/public/js/settings-tabs.js +0 -0
- package/public/js/settings.js +39 -27
- package/public/js/sse.js +0 -0
- package/public/js/starscape.js +0 -0
- package/public/js/state.js +0 -0
- package/public/js/theme-preference.js +0 -0
- package/public/js/ticket-detail.js +4 -4
- package/public/js/toast.js +0 -0
- package/public/js/transport.js +0 -0
- package/public/js/unread.js +0 -0
- package/public/js/url-routes.js +0 -0
- package/public/orbits-favicon.png +0 -0
- package/public/orbits-logo-bg.png +0 -0
- package/public/orbits-logo.png +0 -0
- package/public/styles.css +498 -445
- package/src/core/agent.js +0 -0
- package/src/core/agents-md.js +0 -0
- package/src/core/attachments.js +0 -0
- package/src/core/auth.js +0 -0
- package/src/core/backups.js +0 -0
- package/src/core/board.js +0 -0
- package/src/core/boards.js +0 -0
- package/src/core/bootstrap.js +0 -0
- package/src/core/css-bundle.js +29 -0
- package/src/core/db.js +0 -0
- package/src/core/delete-board.js +0 -0
- package/src/core/dispatch.js +0 -0
- package/src/core/events.js +0 -0
- package/src/core/http.js +10 -3
- package/src/core/migrate.js +0 -0
- package/src/core/paths.js +0 -0
- package/src/core/provision-repo-board.js +0 -0
- package/src/core/queries.js +0 -0
- package/src/core/registry.js +0 -0
- package/src/core/relations.js +0 -0
- package/src/core/review-verdicts.js +0 -0
- package/src/core/router.js +0 -0
- package/src/core/search.js +0 -0
- package/src/core/seed.js +0 -0
- package/src/core/snapshots.js +0 -0
- package/src/core/states.js +0 -0
- package/src/core/system-picker.js +0 -0
- package/src/core/tickets.js +0 -0
- package/src/core/util.js +0 -0
- package/src/mcp/orbit-client.js +0 -0
- package/src/mcp-server.js +0 -0
- package/src/server.js +0 -0
- package/dist/full/js/app.55b38e12.js.map +0 -7
- package/dist/full/styles.273fc37a.css +0 -6002
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
var Nn=Object.defineProperty;var C=(e,t)=>()=>(e&&(t=e(e=0)),t);var On=(e,t)=>{for(var a in t)Nn(e,a,{get:t[a],enumerable:!0})};var y,le,V,
|
|
1
|
+
var Nn=Object.defineProperty;var C=(e,t)=>()=>(e&&(t=e(e=0)),t);var On=(e,t)=>{for(var a in t)Nn(e,a,{get:t[a],enumerable:!0})};var y,le,V,T,U,k,ye,Te,Nt,ve,st,de,Ta,Ot,ne=C(()=>{y=e=>document.querySelector(e),le=y("#boardMenuBtn"),V=y("#boardFlyout"),T=y("#kanban"),U=y("#drawer"),k=y("#drawerInner"),ye=y("#drawerBackdrop"),Te=y("#createFlyout"),Nt=y("#createFlyoutInner"),ve=y("#createFlyoutBackdrop"),st=y("#searchInput"),de=y("#searchResults"),Ta=y("#themeToggle"),Ot=y("#themeIcon")});function _e(e){try{return e??globalThis.localStorage??null}catch{return null}}function jt(e){return typeof window<"u"&&typeof window.matchMedia=="function"?window.matchMedia(e):{matches:!1}}function ct(e=_e()){let a=_e(e)?.getItem?.(_a);return a==="true"?!0:a==="false"?!1:null}function Ht(e=jt){try{return!!e("(prefers-reduced-motion: reduce)")?.matches}catch{return!1}}function Ce({storage:e=_e(),mediaMatcher:t=jt}={}){return ct(e)??Ht(t)}function Ca(e,t=_e()){let a=_e(t),n=e?"true":"false";return a?.setItem?.(_a,n),e}function ze({doc:e=globalThis.document,storage:t=_e(),mediaMatcher:a=jt}={}){let n=e?.documentElement,r=ct(t);return n&&(r===!0?n.setAttribute("data-motion","reduce"):r===!1?n.setAttribute("data-motion","full"):n.removeAttribute("data-motion")),Ce({storage:t,mediaMatcher:a})}var _a,qt=C(()=>{_a="mab_reduce_motion"});function Ie(e){try{return e??globalThis.localStorage??null}catch{return null}}function Me(e){try{return e??globalThis.document??null}catch{return null}}function Ut(e){try{return e??globalThis.window??null}catch{return null}}function jn(e){return zt.has(e)?e:"light"}function Ma(e=Ie()){let a=Ie(e)?.getItem?.(Ia);return zt.has(a)?a:null}function ue({doc:e=Me(),storage:t=Ie()}={}){let a=Me(e)?.documentElement?.getAttribute?.("data-theme");return zt.has(a)?a:Ma(t)??"light"}function Pa({doc:e=Me(),storage:t=Ie()}={}){let a=Ma(t);return a&&Me(e)?.documentElement?.setAttribute?.("data-theme",a),ue({doc:e,storage:t})}function Gt(e,{doc:t=Me(),storage:a=Ie(),eventTarget:n=Ut(),notify:r=!0}={}){let o=jn(e);return Me(t)?.documentElement?.setAttribute?.("data-theme",o),Ie(a)?.setItem?.(Ia,o),r&&Hn(o,n),o}function Aa(e={}){let t=ue(e)==="dark"?"light":"dark";return Gt(t,e)}function Hn(e,t=Ut()){let a=Ut(t);if(typeof a?.dispatchEvent=="function"){if(typeof CustomEvent=="function"){a.dispatchEvent(new CustomEvent(lt,{detail:{theme:e}}));return}a.dispatchEvent({type:lt,detail:{theme:e}})}}var Ia,lt,zt,Jt=C(()=>{Ia="mab_theme",lt="orbit:theme-change",zt=new Set(["light","dark"])});function Ge(e){return!e||!dt.has(e)?"lanes":e}var dt,ut=C(()=>{dt=new Set(["lanes","appearance","ai","notes","journal","repository","archive"])});function Da(){return Ge(c.settingsTab||localStorage.getItem("mab_settings_tab"))}function Pe(){if(!c.data)return;let e=c.data.boards||[],t=c.boardId?e.find(a=>a.id===c.boardId):null;if(!t&&c.boardSlug&&(t=e.find(a=>a.slug===c.boardSlug)||e.find(a=>a.id===c.boardSlug)),!t){let a=c.data.active_board_id;t=e.find(n=>n.id===a)||e[0]||null}c.boardId=t?.id||"",c.boardSlug=t?.slug||""}function Y(){return(c.data?.boards||[]).find(e=>e.id===c.boardId)}function Fa(){return c.boardId?(c.data?.labels||[]).filter(e=>e.board_id===c.boardId):[]}function Je(){return c.data.states.filter(e=>e.board_id===c.boardId)}function Na(e){return e?.role==="ai_ready"||e?.name==="AI Ready"}function Ae(){let e=Je();return Y()?.ai_enabled!==0?e:e.filter(t=>!Na(t))}function Oa(e=""){let t=Je();return Y()?.ai_enabled!==0?t:t.filter(a=>!Na(a)||a.id===e)}function W(){return c.data.tickets.filter(e=>e.board_id===c.boardId)}function Kn(e){return e?{id:e.id,board_id:e.board_id,board_slug:e.board_slug,number:e.number,title:e.title,type:e.type,state_name:e.state_name,state_role:e.state_role,priority:e.priority}:null}function Yn(e){if(!c.data?.tickets)return;let t=c.data.tickets.filter(r=>r.board_id===e&&!r.archived_at),a=new Map(t.map(r=>[r.id,r])),n=new Map;for(let r of t)r.parent_ticket_id&&n.set(r.parent_ticket_id,(n.get(r.parent_ticket_id)||0)+1);for(let r of t)r.parent_ticket=r.parent_ticket_id?Kn(a.get(r.parent_ticket_id)):null,r.child_count=n.get(r.id)||0}function ja(e){if(!c.data?.tickets||!e?.id)return;let t=c.data.tickets.findIndex(r=>r.id===e.id),a=t>=0?c.data.tickets[t]:{},n={...a,...e,labels:e.labels||a.labels||[],comment_count:e.comment_count??a.comment_count??0,child_count:e.child_count??a.child_count??0,parent_ticket:e.parent_ticket||a.parent_ticket||null};t>=0?c.data.tickets.splice(t,1,n):c.data.tickets.push(n),c.data.tickets.sort((r,o)=>String(o.updated_at||"").localeCompare(String(r.updated_at||""))||String(r.id).localeCompare(String(o.id))),Yn(n.board_id||c.boardId)}var c,z=C(()=>{ut();c={data:null,boardId:"",boardSlug:"",selectedTicketId:"",expandedCardIds:new Set,detailMode:"empty",settingsTab:Ge(localStorage.getItem("mab_settings_tab")),showPriority:localStorage.getItem("mab_show_priority")!=="false",eventSource:null}});function l(e){return String(e??"").replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}function Xn(e){if(!e)return e;let t=e;for(let[a,n]of Wn)t=t.split(a).join(n);return t}function ie(e){return e?Xn(String(e)).replace(/\r\n?/g,`
|
|
2
2
|
`):""}function we(e){return l(ie(e))}function Qn(e){let t=String(e||"").trim();if(!t)return"";let a=t.replace(/[\u0000-\u001f\u007f\s]+/g,"").toLowerCase();if(/^(?:javascript|data|vbscript):/.test(a))return"";let n=a.match(/^([a-z][a-z0-9+.-]*):/);return n&&!Vn.has(`${n[1]}:`)?"":t}function Yt(e){let t=l(e);return t=t.replace(/(\*\*|__)(?=\S)([\s\S]*?\S)\1/g,"<strong>$2</strong>"),t=t.replace(/(\*|_)(?=\S)([^*_]*?\S)\1/g,"<em>$2</em>"),t}function Wt(e){let t=/\[([^\]\n]+)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g,a="",n=0,r;for(;r=t.exec(e);){a+=Yt(e.slice(n,r.index));let o=Yt(r[1]),i=Qn(r[2]);a+=i?`<a href="${l(i)}" target="_blank" rel="noopener noreferrer">${o}</a>`:o,n=r.index+r[0].length}return a+=Yt(e.slice(n)),a}function pt(e){let t=String(e??""),a="",n=0;for(;n<t.length;){let r=t.indexOf("`",n);if(r===-1){a+=Wt(t.slice(n));break}let o=t.indexOf("`",r+1);if(o===-1){a+=Wt(t.slice(n));break}a+=Wt(t.slice(n,r)),a+=`<code>${l(t.slice(r+1,o))}</code>`,n=o+1}return a}function Zn(e){return`<p>${pt(e.join(`
|
|
3
3
|
`)).replaceAll(`
|
|
4
4
|
`,"<br>")}</p>`}function er(e){let t=e.match(/^\[( |x|X)\]\s+(.*)$/);if(!t)return null;let a=t[1].toLowerCase()==="x",n=pt(t[2].trim()).replaceAll(`
|
|
5
5
|
`,"<br>");return{checked:a,html:`<input type="checkbox" disabled${a?" checked":""}> ${n}`}}function Xt(e){let t=ie(e);if(!t.trim())return"";let a=[],n=t.split(`
|
|
6
6
|
`),r=[],o=null,i=null,s=()=>{r.length&&(a.push(Zn(r)),r=[])},u=()=>{if(!o)return;let p=o.taskList?' class="task-list"':"";a.push(`<${o.type}${p}>${o.items.map(f=>`<li${f.taskClass?` class="${f.taskClass}"`:""}>${f.html}</li>`).join("")}</${o.type}>`),o=null},d=()=>{i&&(a.push(`<blockquote>${Xt(i.join(`
|
|
7
|
-
`))}</blockquote>`),i=null)},m=()=>{s(),u(),d()};for(let p=0;p<n.length;p+=1){let f=n[p];if(/^\s*```/.test(f)){m();let
|
|
8
|
-
`))}</code></pre>`);continue}if(/^\s*(?:-\s*){3,}\s*$/.test(f)||/^\s*(?:\*\s*){3,}\s*$/.test(f)||/^\s*(?:_\s*){3,}\s*$/.test(f)){m(),a.push("<hr>");continue}let
|
|
9
|
-
`,"<br>")});continue}u(),r.push(f)}return m(),a.join("")}function Ke(e){return e?new Intl.DateTimeFormat(void 0,{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"}).format(new Date(e)):""}function Ha(e){return e?new Intl.DateTimeFormat(void 0,{year:"numeric",month:"short",day:"numeric",hour:"numeric",minute:"2-digit",second:"2-digit"}).format(new Date(e)):""}function Q(e){return`#${e.number}`}function Ye(e){let t=e?.state_role||e?.role||e?.state_name||e?.name||"state";return String(t).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"state"}function
|
|
7
|
+
`))}</blockquote>`),i=null)},m=()=>{s(),u(),d()};for(let p=0;p<n.length;p+=1){let f=n[p];if(/^\s*```/.test(f)){m();let A=[];for(p+=1;p<n.length&&!/^\s*```\s*$/.test(n[p]);)A.push(n[p]),p+=1;a.push(`<pre><code>${l(A.join(`
|
|
8
|
+
`))}</code></pre>`);continue}if(/^\s*(?:-\s*){3,}\s*$/.test(f)||/^\s*(?:\*\s*){3,}\s*$/.test(f)||/^\s*(?:_\s*){3,}\s*$/.test(f)){m(),a.push("<hr>");continue}let h=f.match(/^\s{0,3}(#{1,6})\s+(.+?)\s*#*\s*$/);if(h){m();let A=h[1].length;a.push(`<h${A}>${pt(h[2])}</h${A}>`);continue}let w=f.match(/^\s{0,3}>\s?(.*)$/);if(w){s(),u(),i||(i=[]),i.push(w[1]);continue}if(i&&!f.trim()){d();continue}if(d(),!f.trim()){s(),u();continue}let $=f.match(/^\s*\d+[.)]\s+(.+)$/),M=f.match(/^\s*[-*+]\s+(.+)$/);if($||M){s();let A=$?"ol":"ul",te=($||M)[1].trim(),B=null;M&&(B=er(te)),(!o||o.type!==A||!!o.taskList!=!!B)&&(u(),o={type:A,items:[],taskList:!!B}),B?o.items.push({html:B.html,taskClass:B.checked?"task-item task-item-done":"task-item"}):o.items.push({html:pt(te).replaceAll(`
|
|
9
|
+
`,"<br>")});continue}u(),r.push(f)}return m(),a.join("")}function Ke(e){return e?new Intl.DateTimeFormat(void 0,{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"}).format(new Date(e)):""}function Ha(e){return e?new Intl.DateTimeFormat(void 0,{year:"numeric",month:"short",day:"numeric",hour:"numeric",minute:"2-digit",second:"2-digit"}).format(new Date(e)):""}function Q(e){return`#${e.number}`}function Ye(e){let t=e?.state_role||e?.role||e?.state_name||e?.name||"state";return String(t).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"state"}function N(e){return e==="epic"||e==="feature"||e==="bug"||e==="task"?e:"task"}function Be(e){return{epic:"Epic",feature:"Feature",task:"Task",bug:"Bug"}[N(e)]||"Task"}function qa(e){return{epic:"Epic",feature:"Feature",task:"Task",bug:"Bug"}[N(e)]||"Task"}function Re(e){return{0:"MAYBE",1:"LOW",2:"MED",3:"HIGH",4:"URGENT"}[Number(e)]||"MED"}function De(e){let t=["maybe","low","med","high","urgent"],a=Number(e);return t[Number.isFinite(a)?Math.max(0,Math.min(4,a)):2]}function Ua(e=[]){return e.length?`
|
|
10
10
|
<div class="labels">
|
|
11
11
|
${e.map(t=>`<span class="label" style="--label-color: ${l(t.color)}">${l(t.name)}</span>`).join("")}
|
|
12
12
|
</div>
|
|
13
|
-
`:""}function za(e){let t=String(e||"").trim();if(!t)return"Not set";let a=t.match(/github\.com\/([^/\s]+)\/([^/\s]+?)(?:\.git)?$/i);if(a)return`${a[1]}/${a[2]}`;let n=t.match(/github\.com[:/]([^/\s]+)\/([^/\s]+?)(?:\.git)?$/i);return n?`${n[1]}/${n[2]}`:t}var Wn,Vn,re=C(()=>{Wn=[["\u0393\xC7\xF4","\u2013"],["\u0393\xC7\xF6","\u2014"],["\u0393\xC7\xA3",'"'],["\u0393\xC7\xA5",'"'],["\u0393\xC7\xFF","'"],["\u0393\xC7\xD6","'"],["\u0393\xC7\xAA","\u2026"],["\u0393\xC7\xF3","\u2022"],["\u0393\xC7\u2591","\u2030"],["\u0393\xC7\u2563","\u2039"],["\u0393\xC7\u2551","\u203A"],["\u0393\xF6\xC7","\u2500"],["\u0393\xF6\xE9","\u2502"],["\u0393\xF6\xEE","\u250C"],["\u0393\xF6\xC9","\u2510"],["\u0393\xF6\xF6","\u2514"],["\u0393\xF6\xFF","\u2518"],["\u0393\xF6\xA3","\u251C"],["\u0393\xF6\xF1","\u2524"],["\u0393\xF6\xBC","\u252C"],["\u0393\xF6\u2524","\u2534"],["\u0393\xF6\u255D","\u253C"],["\u0393\xF2\xC9","\u2550"],["\u0393\xF2\xE6","\u2551"],["\u0393\xF2\xC6","\u2552"],["\u0393\xF2\xF6","\u2554"],["\u0393\xF2\xA1","\u256D"],["\u0393\xF2\xAB","\u256E"],["\u0393\xF2\xBB","\u256F"],["\u0393\xF2\u2591","\u2570"],["\u0393\xFB\xE6","\u2591"],["\u0393\xFB\xC6","\u2592"],["\u0393\xFB\xF4","\u2593"],["\u0393\xFB\xC9","\u2590"],["\u0393\xFB\xEE","\u258C"],["\u0393\xFB\xC4",">"],["\u0393\xFB\xE1","\u25A0"],["\u0393\xFB\u255D","\u25BC"],["\u0393\xF9\xC5","\u25CF"],["\u0393\xF9\xEF","\u25CB"],["\u0393\xDC\xF2","\u2695"],["\u0393\xDC\xE1","\u26A0"],["\u0393\xDC\xED","\u26A1"],["\u0393\xDC\xF4","\u2693"],["\u0393\xE5\xC9","\u2190"],["\u0393\xE5\xE6","\u2191"],["\u0393\xE5\xC6","\u2192"],["\u0393\xE5\xF4","\u2193"],["\u0393\xE5\xF6","\u2194"],["\u252C\xE1"," "],["\u252C\u2310","\xA9"],["\u252C\xAB","\xAE"],["\u252C\u2591","\xB0"],["\u252C\xBA","\xA7"],["\u252C\u2556","\xB7"],["\u201C",'"'],["\u201D",'"'],["\u2018","'"],["\u2019","'"]];Vn=new Set(["http:","https:","mailto:","tel:"])});function ar(){return ke&&ke.isConnected||(ke=document.createElement("div"),ke.className="toast-container",document.body.append(ke)),ke}function h(e,t="info",a=4e3){let n=ar(),r=document.createElement("div");r.className=`toast toast-${t}`,r.setAttribute("role","status");let o=tr[t];r.innerHTML=`<span class="toast-icon">${o}</span><span class="toast-msg">${l(e)}</span><button class="toast-close" aria-label="Dismiss">×</button>`,r.querySelector(".toast-close").addEventListener("click",()=>Vt(r)),n.prepend(r),requestAnimationFrame(()=>requestAnimationFrame(()=>r.classList.add("toast-enter")));let i=setTimeout(()=>Vt(r),a);r.addEventListener("mouseenter",()=>clearTimeout(i)),r.addEventListener("mouseleave",()=>{let s=setTimeout(()=>Vt(r),1500);r.addEventListener("mouseenter",()=>clearTimeout(s),{once:!0})})}function Vt(e){e.classList.contains("toast-exit")||(e.classList.add("toast-exit"),e.addEventListener("animationend",()=>e.remove(),{once:!0}))}function Ga(e,t){let a=new Blob([JSON.stringify(t,null,2)],{type:"application/json"}),n=URL.createObjectURL(a),r=document.createElement("a");r.href=n,r.download=e,document.body.append(r),r.click(),r.remove(),URL.revokeObjectURL(n)}function mt(e,t){let a=0;return(...n)=>{clearTimeout(a),a=setTimeout(()=>e(...n),t)}}var tr,ke,pe=C(()=>{re();tr={info:'<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z" clip-rule="evenodd"/></svg>',success:'<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd"/></svg>',warning:'<svg viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z" clip-rule="evenodd"/></svg>',error:'<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z" clip-rule="evenodd"/></svg>'},ke=null;h.info=(e,t)=>h(e,"info",t);h.success=(e,t)=>h(e,"success",t);h.warning=(e,t)=>h(e,"warning",t);h.error=(e,t)=>h(e,"error",t)});async function Ja({method:e="GET",path:t,body:a,headers:n}){let r={"Content-Type":"application/json",...n||{}},o=await fetch(t,{method:e,headers:r,body:a!==void 0?JSON.stringify(a):void 0}),i=await o.text(),s=i?JSON.parse(i):{};if(!o.ok){let u=new Error(s.error||o.statusText);throw u.payload=s,u.status=o.status,u}return s}var Ka=C(()=>{});function ft(){return`/api/bootstrap${c.boardId?`?board_id=${encodeURIComponent(c.boardId)}`:c.boardSlug?`?board=${encodeURIComponent(c.boardSlug)}`:""}`}function $(e){if(!c.boardId||e.includes("board_id="))return e;let t=e.includes("?")?"&":"?";return`${e}${t}board_id=${encodeURIComponent(c.boardId)}`}async function v(e,t={}){try{return await Ja({method:t.method||"GET",path:e,body:t.body,headers:t.headers})}catch(a){throw h.error(a.payload?.error||a.message||"Request failed"),a}}var Z=C(()=>{z();pe();Ka()});function Zt(){Qt+=1,U.hidden=!1,ye.hidden=!1,requestAnimationFrame(()=>{U.classList.add("is-open"),ye.classList.add("is-visible")})}function ht(){let e=++Qt,t=U.classList.contains("is-open");U.classList.remove("is-open"),ye.classList.remove("is-visible");let a=()=>{if(Qt!==e)return;U.hidden=!0,ye.hidden=!0,w.innerHTML="";let o=document.getElementById("drawerTitleBlock"),i=document.getElementById("drawerTabs");o&&(o.innerHTML=""),i&&(i.innerHTML="",i.hidden=!0),U.classList.remove("is-wide")};if(!t){a();return}let n=!1,r=()=>{n||(n=!0,a())};U.addEventListener("transitionend",r,{once:!0}),setTimeout(r,360)}function bt({eyebrow:e,title:t,titleAttrs:a,subtitleHtml:n,tabs:r,activeTab:o,onTabSelect:i,body:s,mode:u}){U.classList.toggle("is-settings",u==="settings"),U.classList.toggle("is-wide",u==="ticket"||u==="settings");let d=document.getElementById("drawerTitleBlock"),m=document.getElementById("drawerTabs"),f=` class="drawer-title-text${a?.class?` ${a.class}`:""}"`;for(let[x,N]of Object.entries(a||{}))x!=="class"&&(f+=` ${x}="${l(String(N))}"`);let b=[];e&&b.push(`<span class="drawer-eyebrow">${l(e)}</span>`),b.push(`<h2${f}>${l(t??"")}</h2>`),n&&b.push(`<div class="drawer-subtitle">${n}</div>`),d.innerHTML=b.join(""),r&&r.length?(m.hidden=!1,m.innerHTML=r.map(x=>`<button type="button" role="tab" class="drawer-tab ${x.id===o?"is-active":""}" data-drawer-tab="${l(x.id)}" aria-selected="${x.id===o}">${l(x.label)}</button>`).join(""),typeof i=="function"&&m.querySelectorAll(".drawer-tab").forEach(x=>{x.addEventListener("click",()=>i(x.dataset.drawerTab))})):(m.hidden=!0,m.innerHTML="");let T=document.getElementById("drawerArchiveBtn");T&&(T.hidden=c.detailMode!=="ticket"),w.innerHTML=s??""}var Qt,gt=C(()=>{ne();z();re();Qt=0});function sr(e,t=Ae()){return e?[{id:"move",label:"Move to",children:t.map(a=>({id:`move:${a.id}`,label:a.name,action:"move",value:a.id,checked:a.id===e.state_id,disabled:a.id===e.state_id}))},{id:"priority",label:"Priority",children:rr.map(a=>({id:`priority:${a}`,label:Re(a),action:"priority",value:a,checked:Number(e.priority)===a,disabled:Number(e.priority)===a}))},{id:"type",label:"Type",children:nr.map(a=>({id:`type:${a}`,label:Be(a),action:"type",value:a,checked:D(e.type)===a,disabled:D(e.type)===a}))},{id:"open",label:"Open",action:"open"},{id:"archive",label:"Archive",action:"archive",danger:!0}]:[]}function cr({x:e,y:t,menuWidth:a,menuHeight:n,viewportWidth:r,viewportHeight:o,margin:i=ta}){let s=Math.max(i,r-a-i),u=Math.max(i,o-n-i),d=e+a+i>r?e-a:e,m=t+n+i>o?t-n:t;return{left:Math.min(Math.max(i,d),s),top:Math.min(Math.max(i,m),u)}}function lr({triggerRect:e,submenuWidth:t,submenuHeight:a,viewportWidth:n,viewportHeight:r,margin:o=ta,gap:i=or}){let s=Math.max(o,n-t-o),u=e.right+i,d=e.left-t-i,m=u+t+o<=n,p=d>=o,f=m||!p?u:d,b=Math.max(0,r-o*2),T=Math.min(a,b),x=Math.max(o,r-T-o),N=e.top-i;return{left:Math.min(Math.max(o,f),s),top:Math.min(Math.max(o,N),x),maxHeight:b}}function kt({apiClient:e=v,navigator:t=null,confirmer:a=globalThis.confirm}={}){async function n(r,o){await e($(`/api/tickets/${encodeURIComponent(r.id)}`),{method:"PATCH",body:o})}return{async open(r){return t?t({boardId:c.boardId,view:"ticket",ticketId:r.id}):null},async move(r,o){await n(r,{state_id:o})},async priority(r,o){await n(r,{priority:o})},async type(r,o){await n(r,{type:o})},async archive(r){return typeof a=="function"&&!a(`Archive "${r.title||"card"}"? You can restore it from Settings \u2192 Card Archive.`)?!1:(await e($(`/api/tickets/${encodeURIComponent(r.id)}/archive`),{method:"POST"}),h.error(`Archived: ${r.title||"card"}`),!0)}}}function na(e){aa=!!e}function ee({restoreFocus:e=!1}={}){se(),We&&(We.abort(),We=null);for(let t of Ve)t.isConnected&&t.remove();Ve.clear(),G&&(G.querySelectorAll(".card-action-menu-item.has-submenu").forEach(t=>{let a=$e.get(t);a?.isConnected&&a.remove(),$e.delete(t)}),G.remove(),G=null),e&&yt?.isConnected&&yt.focus({preventScroll:!0}),yt=null}function dr({ticket:e,anchor:t,x:a,y:n,handlers:r=kt(),onBeforeOpen:o=null}){if(ee(),!e||aa)return null;typeof o=="function"&&o(),yt=t||document.activeElement;let i=document.createElement("div");i.className="card-action-menu",i.setAttribute("role","menu"),i.setAttribute("aria-label",`Actions for #${e.number||""} ${e.title||"card"}`.trim()),i.dataset.ticketId=e.id,i.innerHTML=Xa(sr(e)),document.body.append(i),G=i,i.querySelectorAll(".card-action-menu-item.has-submenu").forEach(p=>{let f=p.querySelector(":scope > .card-action-submenu");f&&(f.remove(),document.body.append(f),$e.set(p,f),ea.set(f,p),mr(f,e,r))});let s=i.getBoundingClientRect(),u=cr({x:a,y:n,menuWidth:s.width,menuHeight:s.height,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight});i.style.left=`${u.left}px`,i.style.top=`${u.top}px`,pr(i,e,r),oa(i)?.focus({preventScroll:!0}),We=new AbortController;let m=We.signal;return requestAnimationFrame(()=>{document.addEventListener("pointerdown",fr,{signal:m,capture:!0})}),document.addEventListener("keydown",hr,{signal:m,capture:!0}),document.addEventListener("scroll",br,{signal:m,capture:!0,passive:!0}),window.addEventListener("resize",()=>ee(),{signal:m,passive:!0}),window.addEventListener("blur",()=>ee(),{signal:m}),i}function Wa(e,t,{handlers:a=kt(),onBeforeOpen:n=null}={}){e.addEventListener("contextmenu",r=>{let o=r.target instanceof Element?r.target.closest(".card"):null;if(!o)return;let i=t(o.dataset.ticketId);if(i){if(r.preventDefault(),r.stopPropagation(),aa){ee();return}dr({ticket:i,anchor:o,x:r.clientX,y:r.clientY,handlers:a,onBeforeOpen:n})}})}function Xa(e){return`<ul class="card-action-menu-list" role="none">${e.map(ur).join("")}</ul>`}function ur(e){let t=!!e.children?.length,a=["card-action-menu-item"];t&&a.push("has-submenu"),e.danger&&a.push("is-danger");let n=e.checked?'<span class="card-action-check" aria-hidden="true">\u2713</span>':'<span class="card-action-check" aria-hidden="true"></span>',r=t?'<span class="card-action-arrow" aria-hidden="true">\u203A</span>':"";return`
|
|
13
|
+
`:""}function za(e){let t=String(e||"").trim();if(!t)return"Not set";let a=t.match(/github\.com\/([^/\s]+)\/([^/\s]+?)(?:\.git)?$/i);if(a)return`${a[1]}/${a[2]}`;let n=t.match(/github\.com[:/]([^/\s]+)\/([^/\s]+?)(?:\.git)?$/i);return n?`${n[1]}/${n[2]}`:t}var Wn,Vn,re=C(()=>{Wn=[["\u0393\xC7\xF4","\u2013"],["\u0393\xC7\xF6","\u2014"],["\u0393\xC7\xA3",'"'],["\u0393\xC7\xA5",'"'],["\u0393\xC7\xFF","'"],["\u0393\xC7\xD6","'"],["\u0393\xC7\xAA","\u2026"],["\u0393\xC7\xF3","\u2022"],["\u0393\xC7\u2591","\u2030"],["\u0393\xC7\u2563","\u2039"],["\u0393\xC7\u2551","\u203A"],["\u0393\xF6\xC7","\u2500"],["\u0393\xF6\xE9","\u2502"],["\u0393\xF6\xEE","\u250C"],["\u0393\xF6\xC9","\u2510"],["\u0393\xF6\xF6","\u2514"],["\u0393\xF6\xFF","\u2518"],["\u0393\xF6\xA3","\u251C"],["\u0393\xF6\xF1","\u2524"],["\u0393\xF6\xBC","\u252C"],["\u0393\xF6\u2524","\u2534"],["\u0393\xF6\u255D","\u253C"],["\u0393\xF2\xC9","\u2550"],["\u0393\xF2\xE6","\u2551"],["\u0393\xF2\xC6","\u2552"],["\u0393\xF2\xF6","\u2554"],["\u0393\xF2\xA1","\u256D"],["\u0393\xF2\xAB","\u256E"],["\u0393\xF2\xBB","\u256F"],["\u0393\xF2\u2591","\u2570"],["\u0393\xFB\xE6","\u2591"],["\u0393\xFB\xC6","\u2592"],["\u0393\xFB\xF4","\u2593"],["\u0393\xFB\xC9","\u2590"],["\u0393\xFB\xEE","\u258C"],["\u0393\xFB\xC4",">"],["\u0393\xFB\xE1","\u25A0"],["\u0393\xFB\u255D","\u25BC"],["\u0393\xF9\xC5","\u25CF"],["\u0393\xF9\xEF","\u25CB"],["\u0393\xDC\xF2","\u2695"],["\u0393\xDC\xE1","\u26A0"],["\u0393\xDC\xED","\u26A1"],["\u0393\xDC\xF4","\u2693"],["\u0393\xE5\xC9","\u2190"],["\u0393\xE5\xE6","\u2191"],["\u0393\xE5\xC6","\u2192"],["\u0393\xE5\xF4","\u2193"],["\u0393\xE5\xF6","\u2194"],["\u252C\xE1"," "],["\u252C\u2310","\xA9"],["\u252C\xAB","\xAE"],["\u252C\u2591","\xB0"],["\u252C\xBA","\xA7"],["\u252C\u2556","\xB7"],["\u201C",'"'],["\u201D",'"'],["\u2018","'"],["\u2019","'"]];Vn=new Set(["http:","https:","mailto:","tel:"])});function ar(){return ke&&ke.isConnected||(ke=document.createElement("div"),ke.className="toast-container",document.body.append(ke)),ke}function b(e,t="info",a=4e3){let n=ar(),r=document.createElement("div");r.className=`toast toast-${t}`,r.setAttribute("role","status");let o=tr[t];r.innerHTML=`<span class="toast-icon">${o}</span><span class="toast-msg">${l(e)}</span><button class="toast-close" aria-label="Dismiss">×</button>`,r.querySelector(".toast-close").addEventListener("click",()=>Vt(r)),n.prepend(r),requestAnimationFrame(()=>requestAnimationFrame(()=>r.classList.add("toast-enter")));let i=setTimeout(()=>Vt(r),a);r.addEventListener("mouseenter",()=>clearTimeout(i)),r.addEventListener("mouseleave",()=>{let s=setTimeout(()=>Vt(r),1500);r.addEventListener("mouseenter",()=>clearTimeout(s),{once:!0})})}function Vt(e){e.classList.contains("toast-exit")||(e.classList.add("toast-exit"),e.addEventListener("animationend",()=>e.remove(),{once:!0}))}function Ga(e,t){let a=new Blob([JSON.stringify(t,null,2)],{type:"application/json"}),n=URL.createObjectURL(a),r=document.createElement("a");r.href=n,r.download=e,document.body.append(r),r.click(),r.remove(),URL.revokeObjectURL(n)}function mt(e,t){let a=0;return(...n)=>{clearTimeout(a),a=setTimeout(()=>e(...n),t)}}var tr,ke,pe=C(()=>{re();tr={info:'<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z" clip-rule="evenodd"/></svg>',success:'<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd"/></svg>',warning:'<svg viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z" clip-rule="evenodd"/></svg>',error:'<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z" clip-rule="evenodd"/></svg>'},ke=null;b.info=(e,t)=>b(e,"info",t);b.success=(e,t)=>b(e,"success",t);b.warning=(e,t)=>b(e,"warning",t);b.error=(e,t)=>b(e,"error",t)});async function Ja({method:e="GET",path:t,body:a,headers:n}){let r={"Content-Type":"application/json",...n||{}},o=await fetch(t,{method:e,headers:r,body:a!==void 0?JSON.stringify(a):void 0}),i=await o.text(),s=i?JSON.parse(i):{};if(!o.ok){let u=new Error(s.error||o.statusText);throw u.payload=s,u.status=o.status,u}return s}var Ka=C(()=>{});function ft(){return`/api/bootstrap${c.boardId?`?board_id=${encodeURIComponent(c.boardId)}`:c.boardSlug?`?board=${encodeURIComponent(c.boardSlug)}`:""}`}function S(e){if(!c.boardId||e.includes("board_id="))return e;let t=e.includes("?")?"&":"?";return`${e}${t}board_id=${encodeURIComponent(c.boardId)}`}async function v(e,t={}){try{return await Ja({method:t.method||"GET",path:e,body:t.body,headers:t.headers})}catch(a){throw b.error(a.payload?.error||a.message||"Request failed"),a}}var Z=C(()=>{z();pe();Ka()});function Zt(){Qt+=1,U.hidden=!1,ye.hidden=!1,requestAnimationFrame(()=>{U.classList.add("is-open"),ye.classList.add("is-visible")})}function ht(){let e=++Qt,t=U.classList.contains("is-open");U.classList.remove("is-open"),ye.classList.remove("is-visible");let a=()=>{if(Qt!==e)return;U.hidden=!0,ye.hidden=!0,k.innerHTML="";let o=document.getElementById("drawerTitleBlock"),i=document.getElementById("drawerTabs");o&&(o.innerHTML=""),i&&(i.innerHTML="",i.hidden=!0),U.classList.remove("is-wide")};if(!t){a();return}let n=!1,r=()=>{n||(n=!0,a())};U.addEventListener("transitionend",r,{once:!0}),setTimeout(r,360)}function bt({eyebrow:e,title:t,titleAttrs:a,subtitleHtml:n,tabs:r,activeTab:o,onTabSelect:i,body:s,mode:u}){U.classList.toggle("is-settings",u==="settings"),U.classList.toggle("is-wide",u==="ticket"||u==="settings");let d=document.getElementById("drawerTitleBlock"),m=document.getElementById("drawerTabs"),f=` class="drawer-title drawer-title-text${a?.class?` ${a.class}`:""}"`;for(let[$,M]of Object.entries(a||{}))$!=="class"&&(f+=` ${$}="${l(String(M))}"`);let h=[];e&&h.push(`<span class="drawer-eyebrow">${l(e)}</span>`),h.push(`<h2${f}>${l(t??"")}</h2>`),n&&h.push(`<div class="drawer-subtitle">${n}</div>`),d.innerHTML=h.join(""),r&&r.length?(m.hidden=!1,m.innerHTML=r.map($=>`<button type="button" role="tab" class="drawer-tab ${$.id===o?"is-active":""}" data-drawer-tab="${l($.id)}" aria-selected="${$.id===o}">${l($.label)}</button>`).join(""),typeof i=="function"&&m.querySelectorAll(".drawer-tab").forEach($=>{$.addEventListener("click",()=>i($.dataset.drawerTab))})):(m.hidden=!0,m.innerHTML="");let w=document.getElementById("drawerArchiveBtn");w&&(w.hidden=c.detailMode!=="ticket"),k.innerHTML=s??""}var Qt,gt=C(()=>{ne();z();re();Qt=0});function sr(e,t=Ae()){return e?[{id:"move",label:"Move to",children:t.map(a=>({id:`move:${a.id}`,label:a.name,action:"move",value:a.id,checked:a.id===e.state_id,disabled:a.id===e.state_id}))},{id:"priority",label:"Priority",children:rr.map(a=>({id:`priority:${a}`,label:Re(a),action:"priority",value:a,checked:Number(e.priority)===a,disabled:Number(e.priority)===a}))},{id:"type",label:"Type",children:nr.map(a=>({id:`type:${a}`,label:Be(a),action:"type",value:a,checked:N(e.type)===a,disabled:N(e.type)===a}))},{id:"open",label:"Open",action:"open"},{id:"archive",label:"Archive",action:"archive",danger:!0}]:[]}function cr({x:e,y:t,menuWidth:a,menuHeight:n,viewportWidth:r,viewportHeight:o,margin:i=ta}){let s=Math.max(i,r-a-i),u=Math.max(i,o-n-i),d=e+a+i>r?e-a:e,m=t+n+i>o?t-n:t;return{left:Math.min(Math.max(i,d),s),top:Math.min(Math.max(i,m),u)}}function lr({triggerRect:e,submenuWidth:t,submenuHeight:a,viewportWidth:n,viewportHeight:r,margin:o=ta,gap:i=or}){let s=Math.max(o,n-t-o),u=e.right+i,d=e.left-t-i,m=u+t+o<=n,p=d>=o,f=m||!p?u:d,h=Math.max(0,r-o*2),w=Math.min(a,h),$=Math.max(o,r-w-o),M=e.top-i;return{left:Math.min(Math.max(o,f),s),top:Math.min(Math.max(o,M),$),maxHeight:h}}function kt({apiClient:e=v,navigator:t=null,confirmer:a=globalThis.confirm}={}){async function n(r,o){await e(S(`/api/tickets/${encodeURIComponent(r.id)}`),{method:"PATCH",body:o})}return{async open(r){return t?t({boardId:c.boardId,view:"ticket",ticketId:r.id}):null},async move(r,o){await n(r,{state_id:o})},async priority(r,o){await n(r,{priority:o})},async type(r,o){await n(r,{type:o})},async archive(r){return typeof a=="function"&&!a(`Archive "${r.title||"card"}"? You can restore it from Settings \u2192 Card Archive.`)?!1:(await e(S(`/api/tickets/${encodeURIComponent(r.id)}/archive`),{method:"POST"}),b.error(`Archived: ${r.title||"card"}`),!0)}}}function na(e){aa=!!e}function ee({restoreFocus:e=!1}={}){se(),We&&(We.abort(),We=null);for(let t of Ve)t.isConnected&&t.remove();Ve.clear(),G&&(G.querySelectorAll(".card-action-menu-item.has-submenu").forEach(t=>{let a=$e.get(t);a?.isConnected&&a.remove(),$e.delete(t)}),G.remove(),G=null),e&&yt?.isConnected&&yt.focus({preventScroll:!0}),yt=null}function dr({ticket:e,anchor:t,x:a,y:n,handlers:r=kt(),onBeforeOpen:o=null}){if(ee(),!e||aa)return null;typeof o=="function"&&o(),yt=t||document.activeElement;let i=document.createElement("div");i.className="card-action-menu",i.setAttribute("role","menu"),i.setAttribute("aria-label",`Actions for #${e.number||""} ${e.title||"card"}`.trim()),i.dataset.ticketId=e.id,i.innerHTML=Xa(sr(e)),document.body.append(i),G=i,i.querySelectorAll(".card-action-menu-item.has-submenu").forEach(p=>{let f=p.querySelector(":scope > .card-action-submenu");f&&(f.remove(),document.body.append(f),$e.set(p,f),ea.set(f,p),mr(f,e,r))});let s=i.getBoundingClientRect(),u=cr({x:a,y:n,menuWidth:s.width,menuHeight:s.height,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight});i.style.left=`${u.left}px`,i.style.top=`${u.top}px`,pr(i,e,r),oa(i)?.focus({preventScroll:!0}),We=new AbortController;let m=We.signal;return requestAnimationFrame(()=>{document.addEventListener("pointerdown",fr,{signal:m,capture:!0})}),document.addEventListener("keydown",hr,{signal:m,capture:!0}),document.addEventListener("scroll",br,{signal:m,capture:!0,passive:!0}),window.addEventListener("resize",()=>ee(),{signal:m,passive:!0}),window.addEventListener("blur",()=>ee(),{signal:m}),i}function Wa(e,t,{handlers:a=kt(),onBeforeOpen:n=null}={}){e.addEventListener("contextmenu",r=>{let o=r.target instanceof Element?r.target.closest(".card"):null;if(!o)return;let i=t(o.dataset.ticketId);if(i){if(r.preventDefault(),r.stopPropagation(),aa){ee();return}dr({ticket:i,anchor:o,x:r.clientX,y:r.clientY,handlers:a,onBeforeOpen:n})}})}function Xa(e){return`<ul class="card-action-menu-list" role="none">${e.map(ur).join("")}</ul>`}function ur(e){let t=!!e.children?.length,a=["card-action-menu-item"];t&&a.push("has-submenu"),e.danger&&a.push("is-danger");let n=e.checked?'<span class="card-action-check" aria-hidden="true">\u2713</span>':'<span class="card-action-check" aria-hidden="true"></span>',r=t?'<span class="card-action-arrow" aria-hidden="true">\u203A</span>':"";return`
|
|
14
14
|
<li class="${a.join(" ")}" role="none">
|
|
15
15
|
<button type="button"
|
|
16
16
|
class="card-action-button"
|
|
@@ -25,7 +25,7 @@ var Nn=Object.defineProperty;var C=(e,t)=>()=>(e&&(t=e(e=0)),t);var On=(e,t)=>{f
|
|
|
25
25
|
</button>
|
|
26
26
|
${t?`<div class="card-action-submenu" role="menu">${Xa(e.children)}</div>`:""}
|
|
27
27
|
</li>
|
|
28
|
-
`}function pr(e,t,a){e.addEventListener("pointerover",n=>{let r=n.target instanceof Element?n.target.closest(".card-action-menu-item"):null;!r||!e.contains(r)||(r.classList.contains("has-submenu")?(se(),vt(r)):gr(e))},!0),e.addEventListener("focusin",n=>{let r=n.target instanceof Element?n.target.closest(".card-action-menu-item"):null;!r||!e.contains(r)||(r.classList.contains("has-submenu")?(se(),vt(r)):(se(),en(e)))}),e.addEventListener("click",n=>Va(n,e,t,a)),e.addEventListener("keydown",n=>Qa(n,e))}function mr(e,t,a){e.addEventListener("pointerenter",se),e.addEventListener("pointerover",n=>{n.target instanceof Element&&e.contains(n.target)&&se()},!0),e.addEventListener("click",n=>{G&&Va(n,G,t,a,e)}),e.addEventListener("keydown",n=>{G&&Qa(n,G)})}function Va(e,t,a,n,r=t){let o=e.target instanceof Element?e.target.closest("button.card-action-button"):null;if(!o||!r.contains(o)||o.disabled)return;e.preventDefault(),e.stopPropagation();let i=o.closest(".card-action-menu-item");if(i?.classList.contains("has-submenu")){se(),vt(i),oa($e.get(i))?.focus({preventScroll:!0});return}let s=o.dataset.action,u=o.dataset.value;if(ee(),s==="open")return n.open(a);if(s==="move")return n.move(a,u);if(s==="priority")return n.priority(a,Number(u));if(s==="type")return n.type(a,u);if(s==="archive")return n.archive(a)}function Qa(e,t){let a=e.target instanceof Element?e.target.closest("button.card-action-button"):null;if(!a)return;let n=a.closest(".card-action-submenu");if(!t.contains(a)&&!n)return;let o=a.closest(".card-action-menu-list"),i=a.closest(".card-action-menu-item");if(e.key==="Escape"){if(e.preventDefault(),n){let s=ea.get(n),u=s?.querySelector(":scope > .card-action-button");wt(s),u?.focus({preventScroll:!0})}else ee({restoreFocus:!0});return}if(e.key==="ArrowDown"||e.key==="ArrowUp"){e.preventDefault(),yr(o,a,e.key==="ArrowDown"?1:-1);return}if(e.key==="Home"||e.key==="End"){e.preventDefault();let s=ra(o);s[e.key==="Home"?0:s.length-1]?.focus({preventScroll:!0});return}if(e.key==="ArrowRight"&&i?.classList.contains("has-submenu")){e.preventDefault(),se(),vt(i),oa($e.get(i))?.focus({preventScroll:!0});return}if(e.key==="ArrowLeft"&&n){let s=ea.get(n),u=s?.querySelector(":scope > .card-action-button");u&&(e.preventDefault(),wt(s),u.focus({preventScroll:!0}))}}function fr(e){G&&(Za(e)||ee())}function hr(e){e.key==="Escape"&&G&&(e.preventDefault(),ee({restoreFocus:!0}))}function br(e){G&&(Za(e)||ee())}function Za(e){let t=e.target;if(!(t instanceof Node))return!1;if(G?.contains(t))return!0;for(let a of Ve)if(a.contains(t))return!0;return!1}function vt(e){let t=e.parentElement?.children||[];for(let n of t)n!==e&&n.classList?.contains("has-submenu")&&n.classList.contains("is-open")&&wt(n);let a=$e.get(e);if(a){if(e.classList.contains("is-open")){Ya(e,a);return}e.classList.add("is-open"),e.querySelector(":scope > .card-action-button")?.setAttribute("aria-expanded","true"),a.classList.add("is-open"),Ve.add(a),Ya(e,a)}}function wt(e){if(!e)return;e.classList.remove("is-open"),e.querySelector(":scope > .card-action-button")?.setAttribute("aria-expanded","false");let t=$e.get(e);t&&(t.classList.remove("is-open"),t.style.removeProperty("left"),t.style.removeProperty("top"),t.style.removeProperty("max-height"),Ve.delete(t))}function en(e){e.querySelectorAll(".card-action-menu-item.has-submenu.is-open").forEach(wt)}function gr(e){se(),Xe=setTimeout(()=>{Xe=null,G===e&&en(e)},ir)}function se(){Xe!=null&&(clearTimeout(Xe),Xe=null)}function Ya(e,t){let a=e.querySelector(":scope > .card-action-button");if(!t||!a)return;let n=Math.max(0,window.innerHeight-ta*2);t.style.maxHeight=`${n}px`,t.style.left="0px",t.style.top="0px";let r=t.getBoundingClientRect(),o=lr({triggerRect:a.getBoundingClientRect(),submenuWidth:r.width,submenuHeight:r.height,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight});t.style.left=`${o.left}px`,t.style.top=`${o.top}px`,t.style.maxHeight=`${o.maxHeight}px`}function ra(e){if(!e)return[];let t=e.classList?.contains("card-action-menu-list")?e:e.querySelector(":scope > .card-action-menu-list");return t?[...t.querySelectorAll(":scope > .card-action-menu-item > .card-action-button")].filter(a=>!a.disabled):[]}function oa(e){return ra(e)[0]||null}function yr(e,t,a){let n=ra(e);if(!n.length)return;let r=n.indexOf(t),o=r===-1?0:(r+a+n.length)%n.length;n[o].focus({preventScroll:!0})}var nr,rr,ta,or,ir,G,aa,We,yt,$e,ea,Ve,Xe,tn=C(()=>{Z();z();re();pe();nr=["epic","feature","task","bug"],rr=[0,1,2,3,4],ta=8,or=6,ir=180,G=null,aa=!1,We=null,yt=null,$e=new WeakMap,ea=new WeakMap,Ve=new Set,Xe=null});function vr(e){return e?typeof e=="string"?{readAt:e,count:0}:{readAt:e.readAt||null,count:Number(e.count)||0}:{readAt:null,count:0}}function Qe(e){if(!e)return new Map;let t=sa.get(e);if(t)return t;t=new Map;try{let a=localStorage.getItem(an(e));if(a){let n=JSON.parse(a);for(let[r,o]of Object.entries(n))t.set(r,vr(o))}}catch{}return sa.set(e,t),t}function $t(e){let t=sa.get(e);if(t)try{let a={};for(let[n,r]of t)a[n]=r;localStorage.setItem(an(e),JSON.stringify(a))}catch{}}function nn(e,t){let a=e.get(t);return a||(a={readAt:null,count:0},e.set(t,a)),a}function xt(e){let t=e?.board_id||c.boardId;if(!t||!e?.id)return 0;let n=Qe(t).get(e.id);return n?n.count:localStorage.getItem(ia(t))==="1"?1:0}function St(e,t){let a=c.boardId;if(!a||!e)return;let n=Qe(a),r=nn(n,e);r.count===0&&r.readAt&&t&&r.readAt>=t||(r.count=0,t&&(r.readAt=t),$t(a))}function rn(e){let t=c.boardId;if(!t||!e)return;let a=Qe(t),n=nn(a,e);n.count=(n.count||0)+1,$t(t)}function on(e){let t=c.boardId;if(!t||!e)return;let a=Qe(t);a.has(e)&&(a.delete(e),$t(t))}function sn(e,t){if(!e||localStorage.getItem(ia(e))==="1")return;let a=Qe(e);for(let n of t||[])!a.has(n.id)&&n.updated_at&&a.set(n.id,{readAt:n.updated_at,count:0});$t(e);try{localStorage.setItem(ia(e),"1")}catch{}}var an,ia,sa,Ze=C(()=>{z();an=e=>`mab_card_read:${e}`,ia=e=>`mab_card_read_seeded:${e}`,sa=new Map});function Fe(){let e=Ae(),t=W();la=new Map(t.map(a=>[a.id,a])),
|
|
28
|
+
`}function pr(e,t,a){e.addEventListener("pointerover",n=>{let r=n.target instanceof Element?n.target.closest(".card-action-menu-item"):null;!r||!e.contains(r)||(r.classList.contains("has-submenu")?(se(),vt(r)):gr(e))},!0),e.addEventListener("focusin",n=>{let r=n.target instanceof Element?n.target.closest(".card-action-menu-item"):null;!r||!e.contains(r)||(r.classList.contains("has-submenu")?(se(),vt(r)):(se(),en(e)))}),e.addEventListener("click",n=>Va(n,e,t,a)),e.addEventListener("keydown",n=>Qa(n,e))}function mr(e,t,a){e.addEventListener("pointerenter",se),e.addEventListener("pointerover",n=>{n.target instanceof Element&&e.contains(n.target)&&se()},!0),e.addEventListener("click",n=>{G&&Va(n,G,t,a,e)}),e.addEventListener("keydown",n=>{G&&Qa(n,G)})}function Va(e,t,a,n,r=t){let o=e.target instanceof Element?e.target.closest("button.card-action-button"):null;if(!o||!r.contains(o)||o.disabled)return;e.preventDefault(),e.stopPropagation();let i=o.closest(".card-action-menu-item");if(i?.classList.contains("has-submenu")){se(),vt(i),oa($e.get(i))?.focus({preventScroll:!0});return}let s=o.dataset.action,u=o.dataset.value;if(ee(),s==="open")return n.open(a);if(s==="move")return n.move(a,u);if(s==="priority")return n.priority(a,Number(u));if(s==="type")return n.type(a,u);if(s==="archive")return n.archive(a)}function Qa(e,t){let a=e.target instanceof Element?e.target.closest("button.card-action-button"):null;if(!a)return;let n=a.closest(".card-action-submenu");if(!t.contains(a)&&!n)return;let o=a.closest(".card-action-menu-list"),i=a.closest(".card-action-menu-item");if(e.key==="Escape"){if(e.preventDefault(),n){let s=ea.get(n),u=s?.querySelector(":scope > .card-action-button");wt(s),u?.focus({preventScroll:!0})}else ee({restoreFocus:!0});return}if(e.key==="ArrowDown"||e.key==="ArrowUp"){e.preventDefault(),yr(o,a,e.key==="ArrowDown"?1:-1);return}if(e.key==="Home"||e.key==="End"){e.preventDefault();let s=ra(o);s[e.key==="Home"?0:s.length-1]?.focus({preventScroll:!0});return}if(e.key==="ArrowRight"&&i?.classList.contains("has-submenu")){e.preventDefault(),se(),vt(i),oa($e.get(i))?.focus({preventScroll:!0});return}if(e.key==="ArrowLeft"&&n){let s=ea.get(n),u=s?.querySelector(":scope > .card-action-button");u&&(e.preventDefault(),wt(s),u.focus({preventScroll:!0}))}}function fr(e){G&&(Za(e)||ee())}function hr(e){e.key==="Escape"&&G&&(e.preventDefault(),ee({restoreFocus:!0}))}function br(e){G&&(Za(e)||ee())}function Za(e){let t=e.target;if(!(t instanceof Node))return!1;if(G?.contains(t))return!0;for(let a of Ve)if(a.contains(t))return!0;return!1}function vt(e){let t=e.parentElement?.children||[];for(let n of t)n!==e&&n.classList?.contains("has-submenu")&&n.classList.contains("is-open")&&wt(n);let a=$e.get(e);if(a){if(e.classList.contains("is-open")){Ya(e,a);return}e.classList.add("is-open"),e.querySelector(":scope > .card-action-button")?.setAttribute("aria-expanded","true"),a.classList.add("is-open"),Ve.add(a),Ya(e,a)}}function wt(e){if(!e)return;e.classList.remove("is-open"),e.querySelector(":scope > .card-action-button")?.setAttribute("aria-expanded","false");let t=$e.get(e);t&&(t.classList.remove("is-open"),t.style.removeProperty("left"),t.style.removeProperty("top"),t.style.removeProperty("max-height"),Ve.delete(t))}function en(e){e.querySelectorAll(".card-action-menu-item.has-submenu.is-open").forEach(wt)}function gr(e){se(),Xe=setTimeout(()=>{Xe=null,G===e&&en(e)},ir)}function se(){Xe!=null&&(clearTimeout(Xe),Xe=null)}function Ya(e,t){let a=e.querySelector(":scope > .card-action-button");if(!t||!a)return;let n=Math.max(0,window.innerHeight-ta*2);t.style.maxHeight=`${n}px`,t.style.left="0px",t.style.top="0px";let r=t.getBoundingClientRect(),o=lr({triggerRect:a.getBoundingClientRect(),submenuWidth:r.width,submenuHeight:r.height,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight});t.style.left=`${o.left}px`,t.style.top=`${o.top}px`,t.style.maxHeight=`${o.maxHeight}px`}function ra(e){if(!e)return[];let t=e.classList?.contains("card-action-menu-list")?e:e.querySelector(":scope > .card-action-menu-list");return t?[...t.querySelectorAll(":scope > .card-action-menu-item > .card-action-button")].filter(a=>!a.disabled):[]}function oa(e){return ra(e)[0]||null}function yr(e,t,a){let n=ra(e);if(!n.length)return;let r=n.indexOf(t),o=r===-1?0:(r+a+n.length)%n.length;n[o].focus({preventScroll:!0})}var nr,rr,ta,or,ir,G,aa,We,yt,$e,ea,Ve,Xe,tn=C(()=>{Z();z();re();pe();nr=["epic","feature","task","bug"],rr=[0,1,2,3,4],ta=8,or=6,ir=180,G=null,aa=!1,We=null,yt=null,$e=new WeakMap,ea=new WeakMap,Ve=new Set,Xe=null});function vr(e){return e?typeof e=="string"?{readAt:e,count:0}:{readAt:e.readAt||null,count:Number(e.count)||0}:{readAt:null,count:0}}function Qe(e){if(!e)return new Map;let t=sa.get(e);if(t)return t;t=new Map;try{let a=localStorage.getItem(an(e));if(a){let n=JSON.parse(a);for(let[r,o]of Object.entries(n))t.set(r,vr(o))}}catch{}return sa.set(e,t),t}function $t(e){let t=sa.get(e);if(t)try{let a={};for(let[n,r]of t)a[n]=r;localStorage.setItem(an(e),JSON.stringify(a))}catch{}}function nn(e,t){let a=e.get(t);return a||(a={readAt:null,count:0},e.set(t,a)),a}function xt(e){let t=e?.board_id||c.boardId;if(!t||!e?.id)return 0;let n=Qe(t).get(e.id);return n?n.count:localStorage.getItem(ia(t))==="1"?1:0}function St(e,t){let a=c.boardId;if(!a||!e)return;let n=Qe(a),r=nn(n,e);r.count===0&&r.readAt&&t&&r.readAt>=t||(r.count=0,t&&(r.readAt=t),$t(a))}function rn(e){let t=c.boardId;if(!t||!e)return;let a=Qe(t),n=nn(a,e);n.count=(n.count||0)+1,$t(t)}function on(e){let t=c.boardId;if(!t||!e)return;let a=Qe(t);a.has(e)&&(a.delete(e),$t(t))}function sn(e,t){if(!e||localStorage.getItem(ia(e))==="1")return;let a=Qe(e);for(let n of t||[])!a.has(n.id)&&n.updated_at&&a.set(n.id,{readAt:n.updated_at,count:0});$t(e);try{localStorage.setItem(ia(e),"1")}catch{}}var an,ia,sa,Ze=C(()=>{z();an=e=>`mab_card_read:${e}`,ia=e=>`mab_card_read_seeded:${e}`,sa=new Map});function Fe(){let e=Ae(),t=W();la=new Map(t.map(a=>[a.id,a])),T.innerHTML=e.map(a=>$r(a,t)).join("")}function wr(e){if(!e)return;let t=e.dataset.ticketId,a=!c.expandedCardIds.has(t);if(a){if(c.expandedCardIds.add(t),!e.querySelector(".card-expandable")){let r=la.get(t),o=e.querySelector(".card-meta");r&&o&&o.insertAdjacentHTML("afterend",dn(r))}}else c.expandedCardIds.delete(t);e.classList.toggle("is-expanded",a);let n=e.querySelector("button.card-expand-trigger");n&&n.setAttribute("aria-expanded",a?"true":"false")}function cn(){ca=ca||kt({navigator:P});let e=null,t=a=>{e!==a&&(e&&e.classList.remove("drag-over"),e=a,e&&e.classList.add("drag-over"))};T.addEventListener("dragstart",a=>{let n=a.target instanceof Element?a.target.closest(".card"):null;n&&(ee(),na(!0),a.dataTransfer.setData("text/plain",n.dataset.ticketId),a.dataTransfer.effectAllowed="move")}),T.addEventListener("dragover",a=>{let n=a.target instanceof Element?a.target.closest(".column"):null;n&&(a.preventDefault(),t(n))}),T.addEventListener("dragend",()=>{na(!1),t(null),Lt=!0,setTimeout(()=>{Lt=!1},0)}),T.addEventListener("drop",async a=>{let n=a.target instanceof Element?a.target.closest(".column"):null;if(!n)return;a.preventDefault(),t(null);let r=a.dataTransfer.getData("text/plain");r&&(F(),await v(S(`/api/tickets/${r}`),{method:"PATCH",body:{state_id:n.dataset.stateId}}),await _())}),T.addEventListener("click",a=>{let n=a.target instanceof Element?a.target:a.target?.parentElement;if(!n)return;let r=n.closest("[data-add-to-state]");if(r){a.stopPropagation(),Tt(r.dataset.addToState||"");return}let o=n.closest("button.card-expand-trigger");if(o){a.stopPropagation(),a.preventDefault(),wr(o.closest(".card"));return}if(n.closest("a")){a.stopPropagation();return}let i=n.closest(".epic-mini-header[data-ticket-id]");if(i){F(),P({boardId:c.boardId,view:"ticket",ticketId:i.dataset.ticketId});return}let s=n.closest(".card");if(s){if(Lt){Lt=!1,a.preventDefault(),a.stopPropagation();return}F(),P({boardId:c.boardId,view:"ticket",ticketId:s.dataset.ticketId})}}),Wa(T,a=>la.get(a),{handlers:ca,onBeforeOpen:F})}function ln(){T.querySelectorAll(".card.selected").forEach(e=>e.classList.remove("selected")),c.selectedTicketId&&T.querySelectorAll(`.card[data-ticket-id="${CSS.escape(c.selectedTicketId)}"]`).forEach(e=>e.classList.add("selected"))}function kr(e){let t=e.toLowerCase(),a={icon:'<svg class="empty-state-icon" viewBox="0 0 24 24"><path d="M18 6L6 18M6 6l12 12" opacity="0.5" /></svg>',title:"Nothing here",subtitle:"Tasks will appear when ready"};return t==="ai ready"?a={icon:`<svg class="empty-state-icon ai-sparkle" viewBox="0 0 24 24">
|
|
29
29
|
<path d="M12 3L14.5 9L21 11.5L14.5 14L12 20L9.5 14L3 11.5L9.5 9L12 3Z" fill="currentColor" opacity="0.65" />
|
|
30
30
|
<circle cx="12" cy="11.5" r="1.8" fill="#fff" />
|
|
31
31
|
</svg>`,title:"Ready for agents",subtitle:"Drop unblocked cards here \u2014 the claim-next tool picks them up"}:t.includes("progress")?a={icon:`<svg class="empty-state-icon orbit" viewBox="0 0 100 100">
|
|
@@ -52,21 +52,21 @@ var Nn=Object.defineProperty;var C=(e,t)=>()=>(e&&(t=e(e=0)),t);var On=(e,t)=>{f
|
|
|
52
52
|
<div class="empty-state-title">${l(a.title)}</div>
|
|
53
53
|
<div class="empty-state-subtitle">${l(a.subtitle)}</div>
|
|
54
54
|
</div>
|
|
55
|
-
`}function $r(e,t){let a=t.filter(
|
|
56
|
-
<section class="${o.join(" ")}" data-state-id="${e.id}" data-state-name="${l(e.name)}">
|
|
57
|
-
<div class="column-head">
|
|
58
|
-
<h2${r?' title="Agent staging \u2014 cards here are picked up by the claim-next tool when unblocked"':""}>
|
|
55
|
+
`}function $r(e,t){let a=t.filter(s=>s.state_id===e.id),n=a.length===0,r=e.name==="AI Ready",o=["column","lane"];r&&o.push("column--ai-ready");let i=r?' data-accent="ai-ready"':"";return`
|
|
56
|
+
<section class="${o.join(" ")}" data-flat${i} data-state-id="${e.id}" data-state-name="${l(e.name)}">
|
|
57
|
+
<div class="column-head lane-head">
|
|
58
|
+
<h2 class="lane-title"${r?' title="Agent staging \u2014 cards here are picked up by the claim-next tool when unblocked"':""}>
|
|
59
59
|
${r?'<span class="agent-dot" aria-hidden="true"></span>':""}${l(e.name)}
|
|
60
60
|
</h2>
|
|
61
|
-
<div class="column-head-actions">
|
|
62
|
-
<button type="button" class="column-add-btn
|
|
61
|
+
<div class="column-head-actions lane-actions">
|
|
62
|
+
<button type="button" class="column-add-btn" data-variant="plus" data-add-to-state="${l(e.id)}" title="New card">+</button>
|
|
63
63
|
<span class="count">${a.length}</span>
|
|
64
64
|
</div>
|
|
65
65
|
</div>
|
|
66
66
|
${n?kr(e.name):xr(a,t)}
|
|
67
67
|
<button type="button" class="add-card-phantom" data-add-to-state="${l(e.id)}">+ Add a card</button>
|
|
68
68
|
</section>
|
|
69
|
-
`}function xr(e,t){let a=new Map(t.filter(s=>
|
|
69
|
+
`}function xr(e,t){let a=new Map(t.filter(s=>N(s.type)==="epic").map(s=>[s.id,s])),n=new Set(e.filter(s=>N(s.type)==="epic").map(s=>s.id)),r=new Map;for(let s of e)if(s.parent_ticket_id&&a.has(s.parent_ticket_id)){let u=r.get(s.parent_ticket_id)||[];u.push(s),r.set(s.parent_ticket_id,u)}let o=new Set,i=[];for(let s of e)if(!o.has(s.id)){if(N(s.type)==="epic"){let u=r.get(s.id)||[];if(u.length){let d=u.map(m=>et(m,{asEpicChild:!0})).join("");i.push(`${et(s)}<div class="epic-children">${d}</div>`),u.forEach(m=>o.add(m.id))}else i.push(et(s));o.add(s.id);continue}if(!(s.parent_ticket_id&&n.has(s.parent_ticket_id))){if(s.parent_ticket_id&&a.has(s.parent_ticket_id)&&!n.has(s.parent_ticket_id)){let u=a.get(s.parent_ticket_id),d=r.get(s.parent_ticket_id)||[],m=d.map(p=>et(p,{asEpicChild:!0})).join("");i.push(`${Sr(u)}<div class="epic-children">${m}</div>`),d.forEach(p=>o.add(p.id));continue}i.push(et(s)),o.add(s.id)}}return i.join("")}function Sr(e){return`
|
|
70
70
|
<div class="epic-mini-header" data-ticket-id="${l(e.id)}" title="Open epic">
|
|
71
71
|
<div class="card-type-id type-pill-epic">
|
|
72
72
|
${Et("epic")}
|
|
@@ -75,11 +75,11 @@ var Nn=Object.defineProperty;var C=(e,t)=>()=>(e&&(t=e(e=0)),t);var On=(e,t)=>{f
|
|
|
75
75
|
<span class="ticket-number">${l(Q(e))}</span>
|
|
76
76
|
<span class="epic-mini-title">${l(e.title)}</span>
|
|
77
77
|
</div>
|
|
78
|
-
`}function da(e){let t=De(e),a=Re(e);return`<div class="card-priority-id priority-pill
|
|
78
|
+
`}function da(e){let t=De(e),a=Re(e);return`<div class="card-priority-id priority-pill" data-variant="${l(t)}"><span class="card-priority-label">${l(a)}</span></div>`}function Et(e){let t=N(e),a="",n="currentColor";switch(t){case"epic":n="#c084fc",a='<path d="M12 2L14.5 9.5L22 12L14.5 14.5L12 22L9.5 14.5L2 12L9.5 9.5L12 2Z" fill="currentColor" />';break;case"feature":n="#4ade80",a='<path d="M19 21l-7-5-7 5V5a2 2 0 012-2h10a2 2 0 012 2v16z" fill="currentColor" />';break;case"bug":n="#f87171",a='<circle cx="12" cy="12" r="10" /><path d="M12 8v4M12 16h.01" />';break;default:n="#60a5fa",a='<rect x="3" y="3" width="18" height="18" rx="2" /><path d="M9 12l2 2 4-4" />'}return`
|
|
79
79
|
<svg class="card-type-icon" viewBox="0 0 24 24" style="color: ${n}">
|
|
80
80
|
${a}
|
|
81
81
|
</svg>
|
|
82
|
-
`}function et(e,{asEpicChild:t=!1}={}){let a=
|
|
82
|
+
`}function et(e,{asEpicChild:t=!1}={}){let a=N(e.type),n=De(e.priority),r=Be(e.type).toUpperCase(),o=c.expandedCardIds.has(e.id),s=!!String(e.description||"").trim()||e.labels&&e.labels.length||e.parent_ticket||e.child_count,u=`
|
|
83
83
|
<span class="ticket-number">${l(Q(e))}</span>
|
|
84
84
|
<div class="card-type-id type-pill-${l(a)}">
|
|
85
85
|
${Et(e.type)}
|
|
@@ -88,12 +88,12 @@ var Nn=Object.defineProperty;var C=(e,t)=>()=>(e&&(t=e(e=0)),t);var On=(e,t)=>{f
|
|
|
88
88
|
${c.showPriority?da(e.priority):""}
|
|
89
89
|
${s?'<svg class="card-expand-chevron" viewBox="0 0 24 24" aria-hidden="true"><path d="M6 9l6 6 6-6" /></svg>':""}
|
|
90
90
|
`,d=xt(e),m=d===0?"":d===1?'<span class="card-unread-dot" role="status" aria-label="1 unread update"></span>':`<span class="card-unread-dot has-count" role="status" aria-label="${d} unread updates">${d>99?"99+":d}</span>`;return`
|
|
91
|
-
<article class="card type-${l(a)} priority-${l(n)}${o?" is-expanded":""}${t?" is-epic-child":""} ${e.id===c.selectedTicketId?"selected":""}" draggable="true" data-ticket-id="${e.id}">
|
|
91
|
+
<article class="card type-${l(a)} priority-${l(n)}${o?" is-expanded":""}${t?" is-epic-child":""} ${e.id===c.selectedTicketId?"selected":""}" data-variant="${l(a)}" draggable="true" data-ticket-id="${e.id}">
|
|
92
92
|
${m}
|
|
93
93
|
<h3>${l(e.title)}</h3>
|
|
94
94
|
|
|
95
95
|
<div class="card-meta">
|
|
96
|
-
${s?`<button type="button" class="card-expand-trigger" data-card-toggle aria-expanded="${o?"true":"false"}">${u}</button>`:`<div class="card-expand-trigger card-expand-trigger--static">${u}</div>`}
|
|
96
|
+
${s?`<button type="button" class="card-expand-trigger" data-variant="card-accordion" data-card-toggle aria-expanded="${o?"true":"false"}">${u}</button>`:`<div class="card-expand-trigger card-expand-trigger--static">${u}</div>`}
|
|
97
97
|
</div>
|
|
98
98
|
|
|
99
99
|
${s&&o?dn(e):""}
|
|
@@ -105,7 +105,7 @@ var Nn=Object.defineProperty;var C=(e,t)=>()=>(e&&(t=e(e=0)),t);var On=(e,t)=>{f
|
|
|
105
105
|
${e.parent_ticket?`<div class="parent-line">-> ${l(Q(e.parent_ticket))}</div>`:""}
|
|
106
106
|
${e.child_count?`<div class="child-count">${e.child_count} feature${e.child_count===1?"":"s"} inside</div>`:""}
|
|
107
107
|
</div>
|
|
108
|
-
`}function un(){let a=()=>Math.max(
|
|
108
|
+
`}function un(){let a=()=>Math.max(T.clientWidth,1),n=!1,r=!1,o=0,i=0,s=0,u=p=>p instanceof Element?!!(p.closest(".card")||p.closest("a, button, input, select, textarea, [draggable='true']")):!1,d=(p,f)=>f===WheelEvent.DOM_DELTA_LINE?p*16:f===WheelEvent.DOM_DELTA_PAGE?p*a():p;T.addEventListener("wheel",p=>{if(p.defaultPrevented||p.ctrlKey)return;let f=p.deltaX||(p.shiftKey?p.deltaY:0);!f||!(Math.abs(f)>=Math.abs(p.deltaY)||p.shiftKey)||T.scrollWidth<=T.clientWidth||(p.preventDefault(),T.scrollLeft+=d(f,p.deltaMode))},{passive:!1}),T.addEventListener("pointerdown",p=>{p.button===0&&(u(p.target)||(n=!0,r=!1,s=p.pointerId,o=p.clientX,i=T.scrollLeft,T.classList.add("is-grabbing")))}),T.addEventListener("pointermove",p=>{if(!n||p.pointerId!==s)return;let f=p.clientX-o;if(!r&&Math.abs(f)>4){r=!0;try{T.setPointerCapture(s)}catch{}}r&&(p.preventDefault(),T.scrollLeft=i-f)});let m=p=>{if(!(!n||p&&p.pointerId!==s)){n=!1,T.classList.remove("is-grabbing");try{T.releasePointerCapture(s)}catch{}}};T.addEventListener("pointerup",m),T.addEventListener("pointercancel",m),T.addEventListener("pointerleave",m),T.addEventListener("click",p=>{r&&(p.stopPropagation(),p.preventDefault(),r=!1)},!0)}var la,ca,Lt,tt=C(()=>{ne();z();re();Z();fe();Ne();me();tn();Ze();la=new Map,ca=null,Lt=!1});var pn,xe,H,Oe=C(()=>{pn="full";pn="full";xe=pn,H={sse:xe==="full",ai:xe==="full",multiBoard:xe==="full",tokenAuth:xe==="full",attachments:xe==="full"}});async function he(){let e=await v(`/api/boards/${c.boardId}/context?include_struck=true`),t=e.board,a=Da(),n=[{id:"lanes",label:"Lanes"},{id:"appearance",label:"Appearance"},{id:"archive",label:"Card Archive"},{id:"notes",label:"Notes"},{id:"journal",label:"Journal"},...H.ai?[{id:"ai",label:"AI"}]:[],{id:"repository",label:"Repository"}],r=a==="ai"&&!H.ai?"lanes":a;bt({eyebrow:"SETTINGS",mode:"settings",title:t.name,tabs:n,activeTab:r,onTabSelect:async o=>{P({boardId:c.boardId,view:"settings",tab:o})},body:Lr(e,r)}),Ur(e,r)}function Lr(e,t){switch(t){case"notes":return Or(e);case"lanes":return fn();case"appearance":return jr();case"ai":return H.ai?Er(e):fn();case"journal":return Hr(e);case"archive":return Rr();case"repository":default:return Dr(e)}}function Er(e){let t=e.board,a=t.ai_enabled!==0,n=a?'<div class="ai-section-divider" aria-hidden="true"></div>':"",r=a?Tr(t):"",o=a?_r(e):"";return`
|
|
109
109
|
<div class="section">
|
|
110
110
|
<label class="orbit-check" for="aiEnabledToggle">
|
|
111
111
|
<input
|
|
@@ -183,7 +183,7 @@ How any AI agent should use this board and work in this repo.`,a=e.agent_instruc
|
|
|
183
183
|
<strong data-mcp-output-title>${l(i.label)} setup</strong>
|
|
184
184
|
<p class="description" data-mcp-helper>${l(i.helper)}</p>
|
|
185
185
|
</div>
|
|
186
|
-
<button type="button"
|
|
186
|
+
<button type="button" data-variant="secondary" data-copy-mcp="config">Copy setup</button>
|
|
187
187
|
</div>
|
|
188
188
|
<div class="mcp-terminal">
|
|
189
189
|
<div class="mcp-terminal-chrome" aria-hidden="true"><span></span><span></span><span></span></div>
|
|
@@ -199,7 +199,7 @@ How any AI agent should use this board and work in this repo.`,a=e.agent_instruc
|
|
|
199
199
|
<strong>Manual run command</strong>
|
|
200
200
|
<p class="description">Use this only when an app asks you to start the MCP server yourself.</p>
|
|
201
201
|
</div>
|
|
202
|
-
<button type="button"
|
|
202
|
+
<button type="button" data-variant="secondary" data-copy-mcp="command">Copy command</button>
|
|
203
203
|
</div>
|
|
204
204
|
<div class="mcp-terminal">
|
|
205
205
|
<div class="mcp-terminal-chrome" aria-hidden="true"><span></span><span></span><span></span></div>
|
|
@@ -216,8 +216,8 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
216
216
|
<div class="section">
|
|
217
217
|
<div id="archiveList" class="archive-list">Loading\u2026</div>
|
|
218
218
|
</div>
|
|
219
|
-
`}function Dr(e){let t=e.board;return
|
|
220
|
-
${
|
|
219
|
+
`}function Dr(e){let t=e.board;return O.boardId!==t.id&&(O.boardId=t.id,O.step="idle",O.exported=!1),`
|
|
220
|
+
${H.multiBoard?`
|
|
221
221
|
<div class="detail-head project-manual-head">
|
|
222
222
|
<div class="meta-grid">
|
|
223
223
|
<div class="meta meta--repo-path">
|
|
@@ -230,12 +230,12 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
230
230
|
</div>`:`
|
|
231
231
|
<p class="description">This board lives in your browser only. Export a snapshot if you want to move it to a real Orbit install, or import one to seed this preview.</p>`}
|
|
232
232
|
|
|
233
|
-
${
|
|
233
|
+
${H.multiBoard?Fr(t):""}
|
|
234
234
|
|
|
235
235
|
<div class="section">
|
|
236
236
|
<h3>Board Snapshot</h3>
|
|
237
237
|
<p class="description">Import accepts Orbit snapshots or Trello board JSON exports. The default import creates a separate board and leaves this board untouched.</p>
|
|
238
|
-
${
|
|
238
|
+
${H.attachments?`
|
|
239
239
|
<label class="orbit-check">
|
|
240
240
|
<input type="checkbox" id="exportProjectImages" />
|
|
241
241
|
<span class="orbit-check-box" aria-hidden="true">
|
|
@@ -246,11 +246,9 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
246
246
|
<p class="description">Image exports are embedded in the .orbit.json snapshot and may be much larger.</p>
|
|
247
247
|
`:""}
|
|
248
248
|
<div class="deployment-actions">
|
|
249
|
-
<button type="button"
|
|
250
|
-
<
|
|
251
|
-
|
|
252
|
-
<span>Import as New Board</span>
|
|
253
|
-
</label>
|
|
249
|
+
<button type="button" data-variant="secondary" id="exportProject">Export</button>
|
|
250
|
+
<input type="file" id="importSnapshotAsNewFile" class="import-file-input" accept=".orbit.json,.json,application/json" />
|
|
251
|
+
<button type="button" data-variant="secondary" id="importSnapshotAsNewButton">Import as New Board</button>
|
|
254
252
|
</div>
|
|
255
253
|
</div>
|
|
256
254
|
|
|
@@ -262,14 +260,12 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
262
260
|
<input id="replaceImportConfirmInput" autocomplete="off" spellcheck="false" placeholder="${l(t.slug||"")}" />
|
|
263
261
|
</label>
|
|
264
262
|
<div class="deployment-actions">
|
|
265
|
-
<
|
|
266
|
-
|
|
267
|
-
<span>Replace Current Board</span>
|
|
268
|
-
</label>
|
|
263
|
+
<input type="file" id="replaceCurrentBoardImportFile" class="import-file-input" accept=".orbit.json,.json,application/json" disabled />
|
|
264
|
+
<button type="button" data-variant="secondary" id="replaceCurrentBoardImportButton" disabled>Replace Current Board</button>
|
|
269
265
|
</div>
|
|
270
266
|
</div>
|
|
271
267
|
|
|
272
|
-
${
|
|
268
|
+
${H.multiBoard?Nr(t):""}
|
|
273
269
|
`}function Fr(e){return`
|
|
274
270
|
<div class="section board-rename-section">
|
|
275
271
|
<h3>Board Name</h3>
|
|
@@ -279,20 +275,20 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
279
275
|
<span>Display name</span>
|
|
280
276
|
<input name="name" value="${l(e.name||"")}" maxlength="120" required />
|
|
281
277
|
</label>
|
|
282
|
-
<button type="submit">Rename Board</button>
|
|
278
|
+
<button type="submit" data-variant="secondary">Rename Board</button>
|
|
283
279
|
</form>
|
|
284
280
|
</div>
|
|
285
|
-
`}function Nr(e){let t=l(e.slug||"");if(
|
|
281
|
+
`}function Nr(e){let t=l(e.slug||"");if(O.step==="choice")return`
|
|
286
282
|
<div class="section repository-danger-zone">
|
|
287
283
|
<h3>Delete Board</h3>
|
|
288
284
|
<p class="description">Delete this board from Orbit and remove its repo-local Orbit files. Export a snapshot first if you may need this board again.</p>
|
|
289
285
|
<div class="repository-delete-actions">
|
|
290
|
-
<button type="button"
|
|
291
|
-
<button type="button"
|
|
292
|
-
<button type="button"
|
|
286
|
+
<button type="button" data-variant="secondary" id="deleteBoardExportFirst">Export first</button>
|
|
287
|
+
<button type="button" data-variant="ghost" class="danger-button" id="deleteBoardSkipExport">Delete without exporting</button>
|
|
288
|
+
<button type="button" data-variant="ghost" id="deleteBoardCancel">Cancel</button>
|
|
293
289
|
</div>
|
|
294
290
|
</div>
|
|
295
|
-
`;if(
|
|
291
|
+
`;if(O.step==="confirm"){let a=O.exported?"Snapshot exported. Type the board slug to confirm permanent deletion.":"Type the board slug to confirm permanent deletion.";return`
|
|
296
292
|
<div class="section repository-danger-zone is-confirming">
|
|
297
293
|
<h3>Delete Board</h3>
|
|
298
294
|
<p class="description">${l(a)}</p>
|
|
@@ -302,15 +298,15 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
302
298
|
<input id="deleteBoardConfirmInput" autocomplete="off" spellcheck="false" placeholder="${t}" autofocus />
|
|
303
299
|
</label>
|
|
304
300
|
<div class="repository-delete-actions">
|
|
305
|
-
<button type="button" class="danger-button" id="deleteBoardConfirm" disabled>Delete board permanently</button>
|
|
306
|
-
<button type="button"
|
|
301
|
+
<button type="button" data-variant="primary" class="danger-button" id="deleteBoardConfirm" disabled>Delete board permanently</button>
|
|
302
|
+
<button type="button" data-variant="ghost" id="deleteBoardCancel">Cancel</button>
|
|
307
303
|
</div>
|
|
308
304
|
</div>
|
|
309
305
|
`}return`
|
|
310
306
|
<div class="section repository-danger-zone">
|
|
311
307
|
<h3>Delete Board</h3>
|
|
312
308
|
<p class="description">Remove this board from Orbit and delete its repo-local Orbit files. This cannot be undone without an exported snapshot.</p>
|
|
313
|
-
<button type="button"
|
|
309
|
+
<button type="button" data-variant="ghost" class="danger-button" id="deleteBoardStart">Delete Board</button>
|
|
314
310
|
</div>
|
|
315
311
|
`}function Or(e){let t=e.board,a="Remember to mention SKILL-ORBIT.md to my AI agents if they get confused",n=t.project_notes||"",r=!!n.trim(),o=r?"":"is-placeholder",i=r?we(n):l(a);return`
|
|
316
312
|
<div class="section ai-fields">
|
|
@@ -343,7 +339,7 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
343
339
|
${Yr()}
|
|
344
340
|
<form id="laneCreateForm" class="lane-create-form">
|
|
345
341
|
<input name="name" placeholder="New lane name..." required />
|
|
346
|
-
<button type="submit">Add Lane</button>
|
|
342
|
+
<button type="submit" data-variant="primary">Add Lane</button>
|
|
347
343
|
</form>
|
|
348
344
|
</div>
|
|
349
345
|
`}function jr(){let e=ue(),t=Ce(),a=ct(),n=Ht(),r=a===null?`Using browser default (${n?"reduced motion":"motion allowed"}).`:"Using your saved preference.";return`
|
|
@@ -400,10 +396,10 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
400
396
|
</select>
|
|
401
397
|
<input name="title" placeholder="Entry title..." required />
|
|
402
398
|
<textarea name="body" placeholder="Decision rationale or lesson: do X instead of Y when working with Z." required></textarea>
|
|
403
|
-
<button type="submit">Add Entry</button>
|
|
399
|
+
<button type="submit" data-variant="primary">Add Entry</button>
|
|
404
400
|
</form>
|
|
405
401
|
</div>
|
|
406
|
-
`}function qr(e){if(String(e||"").trimStart().startsWith("<"))throw new Error("That file looks like an HTML page instead of JSON. In Trello, use Export JSON/download the board JSON, not Save Page As.");try{return JSON.parse(e)}catch(a){throw new Error(a?.message||"invalid JSON")}}function Ur(e,t){let a=e.board;if(t==="repository"){let n=async(
|
|
402
|
+
`}function qr(e){if(String(e||"").trimStart().startsWith("<"))throw new Error("That file looks like an HTML page instead of JSON. In Trello, use Export JSON/download the board JSON, not Save Page As.");try{return JSON.parse(e)}catch(a){throw new Error(a?.message||"invalid JSON")}}function Ur(e,t){let a=e.board;if(t==="repository"){let n=async(p=!!y("#exportProjectImages")?.checked)=>{let f=p?"?include_attachments=true":"",h=await v(`/api/boards/${encodeURIComponent(a.id)}/export${f}`),w=p?`${a.slug}.with-images.orbit.json`:`${a.slug}.orbit.json`;Ga(w,h)};y("#exportProject")?.addEventListener("click",async()=>{await n()}),y("#boardRenameForm")?.addEventListener("submit",async p=>{p.preventDefault();let f=new FormData(p.currentTarget),h=String(f.get("name")||"").trim();!h||h===a.name||(await v(`/api/boards/${encodeURIComponent(a.id)}`,{method:"PATCH",body:{name:h}}),await _(),c.detailMode="settings",b.success(`Renamed board to ${h}. Canonical slug unchanged: ${a.slug}`))});let r=async(p,f)=>{let h=await p.text(),w=qr(h);return v("/api/admin/import",{method:"POST",body:f(w)})},o=y("#importSnapshotAsNewFile");y("#importSnapshotAsNewButton")?.addEventListener("click",()=>{o?.click()}),o?.addEventListener("change",async p=>{let f=p.currentTarget,h=f.files?.[0];if(h)try{let w=await r(h,A=>({snapshot:A,create_new:!0,board_id:a.id}));c.boardId=w.imported_board_id,c.boardSlug=w.imported_board_slug,c.detailMode="empty",await _(),await P({boardId:w.imported_board_id,view:"board"});let $=w.imported_counts||{},M=Number.isFinite(Number($.tickets))?` (${$.tickets} cards)`:"";b.success(w.source_format==="trello-board-export"?`Trello board imported as new board${M}`:"Board imported as new board")}catch(w){b.error(`Import failed: ${w?.message||"invalid JSON"}`)}finally{f.value=""}});let i=y("#replaceImportConfirmInput"),s=y("#replaceCurrentBoardImportFile"),u=y("#replaceCurrentBoardImportButton");i?.addEventListener("input",()=>{let p=i.value.trim()!==a.slug;s&&(s.disabled=p),u&&(u.disabled=p)}),u?.addEventListener("click",()=>{u.disabled||s?.disabled||s?.click()}),s?.addEventListener("change",async p=>{let f=p.currentTarget,h=f.files?.[0];if(h){if(i.value.trim()!==a.slug){b.error("Type the board slug before replacing this board."),f.value="";return}try{let w=await r(h,A=>({snapshot:A,replace_existing:!0,board_id:a.id}));await _(),c.detailMode="settings";let $=w.imported_counts||{},M=Number.isFinite(Number($.tickets))?` (${$.tickets} cards)`:"";b.success(w.source_format==="trello-board-export"?`Trello board replaced from Trello import${M}`:"Board replaced from snapshot")}catch(w){b.error(`Import failed: ${w?.message||"invalid JSON"}`)}finally{f.value=""}}}),y("#deleteBoardStart")?.addEventListener("click",async()=>{O.step="choice",O.exported=!1,await he()}),y("#deleteBoardExportFirst")?.addEventListener("click",async()=>{await n(),O.step="confirm",O.exported=!0,await he()}),y("#deleteBoardSkipExport")?.addEventListener("click",async()=>{O.step="confirm",O.exported=!1,await he()}),y("#deleteBoardCancel")?.addEventListener("click",async()=>{O.step="idle",O.exported=!1,await he()});let d=y("#deleteBoardConfirmInput"),m=y("#deleteBoardConfirm");d?.addEventListener("input",()=>{m&&(m.disabled=d.value.trim()!==a.slug)}),m?.addEventListener("click",async()=>{await v(`/api/boards/${encodeURIComponent(a.id)}`,{method:"DELETE",body:{confirm_slug:a.slug,delete_files:!0}}),O.step="idle",O.exported=!1,await _(),b.success(`Deleted board: ${a.name}`),P({boardId:c.boardId,view:"board"},{replace:!0})})}if(t==="notes"){let n=k.querySelector('[data-edit-field="project_notes"]');if(n){let r=()=>je(n,{fieldName:"project_notes",multiline:!0,initialValue:a.project_notes||"",ariaLabel:"Edit Notes For You",rerender:async()=>{c.detailMode="settings",await he()},commit:async o=>{await v(`/api/boards/${a.id}`,{method:"PATCH",body:{project_notes:ie(o)}}),await _(),c.detailMode="settings",b.success("Saved")}});n.addEventListener("click",o=>{o.preventDefault(),r()}),n.addEventListener("keydown",o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),r())})}}if(t==="lanes"&&(k.querySelectorAll("[data-lane-action]").forEach(n=>{n.addEventListener("click",async()=>{await Wr(n)})}),k.querySelectorAll(".lane-row input, .lane-row select").forEach(n=>{n.addEventListener("change",async()=>{await yn(n.closest(".lane-row"))})}),y("#laneCreateForm")?.addEventListener("submit",async n=>{n.preventDefault();let r=new FormData(n.currentTarget);await v(`/api/boards/${a.id}/states`,{method:"POST",body:Object.fromEntries(r.entries())}),await _(),c.detailMode="settings",b.success("Lane added")}),y("#showPriorityToggle")?.addEventListener("change",n=>{c.showPriority=!!n.currentTarget.checked,localStorage.setItem("mab_show_priority",c.showPriority?"true":"false"),Fe()})),t==="appearance"&&(k.querySelectorAll("input[name='themePreference']").forEach(n=>{n.addEventListener("change",r=>{if(!r.currentTarget.checked)return;let o=Gt(r.currentTarget.value);b.success(o==="dark"?"Dark theme enabled":"Light theme enabled")})}),y("#reduceMotionToggle")?.addEventListener("change",n=>{let r=!!n.currentTarget.checked;Ca(r),ze(),window.dispatchEvent(new CustomEvent("orbit:motion-preference-change",{detail:{reduce:r}})),b.success(r?"Theme motion reduced":"Theme motion enabled")})),t==="ai"){let n=()=>{let o=y("#mcpOsSelect")?.value||_t(),i=y("#mcpClientSelect")?.value||"claude-code",s=It[i]||It.generic,u=mn(),d=ua(i,u),m=pa(o,u),p=k.querySelector("[data-mcp-os-note]");p&&(p.textContent=`Detected: ${Ct[_t()]?.label||"Linux"}`);let f=k.querySelector("[data-mcp-client-format]");f&&(f.textContent=s.format);let h=k.querySelector("[data-mcp-output-title]");h&&(h.textContent=`${s.label} setup`);let w=k.querySelector("[data-mcp-helper]");w&&(w.textContent=s.helper);let $=k.querySelector("[data-mcp-config]");$&&($.textContent=d);let M=k.querySelector("[data-mcp-command]");M&&(M.textContent=m)};y("#mcpOsSelect")?.addEventListener("change",()=>n()),y("#mcpClientSelect")?.addEventListener("change",()=>n()),["#mcpServerPathInput"].forEach(o=>{y(o)?.addEventListener("input",()=>n())}),k.querySelectorAll("[data-copy-mcp]").forEach(o=>{o.addEventListener("click",async()=>{let i=y("#mcpOsSelect")?.value||_t(),s=y("#mcpClientSelect")?.value||"claude-code",u=mn(),d=o.dataset.copyMcp==="command"?pa(i,u):ua(s,u);await zr(d),b.success(o.dataset.copyMcp==="command"?"MCP command copied":"MCP config copied")})});let r=k.querySelector('[data-edit-field="agent_instructions"]');if(r){let o=()=>je(r,{fieldName:"agent_instructions",multiline:!0,initialValue:a.agent_instructions||"",ariaLabel:"Edit Agent Instructions",rerender:async()=>{c.detailMode="settings",await he()},commit:async i=>{await v(`/api/boards/${a.id}`,{method:"PATCH",body:{agent_instructions:ie(i)}}),await _(),c.detailMode="settings",b.success("Saved")}});r.addEventListener("click",i=>{i.preventDefault(),o()}),r.addEventListener("keydown",i=>{(i.key==="Enter"||i.key===" ")&&(i.preventDefault(),o())})}y("#aiEnabledToggle")?.addEventListener("change",async o=>{let i=!!o.currentTarget.checked;await v(`/api/boards/${a.id}`,{method:"PATCH",body:{ai_enabled:i}}),await _(),c.detailMode="settings",b.success(i?"AI features enabled \u2014 agent lanes provisioned":"AI features disabled \u2014 AI Ready hidden")})}if(t==="archive"){let n=y("#archiveList");if(n){let r=async()=>{try{let i=(await v(`/api/boards/${encodeURIComponent(a.id)}/archive`)).tickets||[];if(i.length===0){n.innerHTML='<p class="description">No archived cards yet. Click the trash icon in the card detail header to archive a card.</p>';return}n.innerHTML=`<div class="detail-card-grid">${i.map(s=>at(s,{archive:{id:s.id},disableOpen:!0})).join("")}</div>`}catch(o){n.innerHTML=`<p class="description">Could not load archive: ${l(o?.message||"unknown error")}</p>`}};r(),n.addEventListener("click",async o=>{let i=o.target.closest("[data-archive-restore]"),s=o.target.closest("[data-archive-delete]");if(!i&&!s)return;o.stopPropagation();let d=(i||s).closest("article")?.querySelector("h3")?.textContent||"card";if(i){let m=i.dataset.archiveRestore;await v(S(`/api/tickets/${encodeURIComponent(m)}/restore`),{method:"POST"}),b.success(`Restored: ${d}`),await _(),await r();return}if(s){let m=s.dataset.archiveDelete;if(!confirm(`Permanently delete "${d}"? This cannot be undone.`))return;await v(S(`/api/tickets/${encodeURIComponent(m)}`),{method:"DELETE"}),b.success(`Deleted: ${d}`),await r()}})}}t==="journal"&&(k.querySelectorAll("[data-entry-action='toggle-struck']").forEach(n=>{n.addEventListener("click",async()=>{await v(S(`/api/board-entries/${n.dataset.entryId}`),{method:"PATCH",body:{struck:n.dataset.struck!=="true"}}),await _(),c.detailMode="settings",b.info(n.dataset.struck==="true"?"Project entry restored":"Project entry struck")})}),y("#projectEntryForm")?.addEventListener("submit",async n=>{n.preventDefault();let r=new FormData(n.currentTarget);await v(`/api/boards/${a.id}/entries`,{method:"POST",body:Object.fromEntries(r.entries())}),await _(),c.detailMode="settings",b.success("Project entry added")}))}async function zr(e){if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(e);return}let t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="fixed",t.style.left="-9999px",document.body.append(t),t.select(),document.execCommand("copy"),t.remove()}function Gr(e=[]){return e.length?e.map(t=>{let a=!!t.struck_at;return`
|
|
407
403
|
<div class="comment project-entry ${l(t.type)} ${a?"is-struck":""}">
|
|
408
404
|
<div class="comment-meta">
|
|
409
405
|
<div>
|
|
@@ -414,7 +410,8 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
414
410
|
<span>${l(t.created_by)} - ${Ke(t.created_at)}</span>
|
|
415
411
|
<button
|
|
416
412
|
type="button"
|
|
417
|
-
|
|
413
|
+
data-variant="ghost"
|
|
414
|
+
class="project-entry-strike"
|
|
418
415
|
data-entry-action="toggle-struck"
|
|
419
416
|
data-entry-id="${l(t.id)}"
|
|
420
417
|
data-struck="${a?"true":"false"}"
|
|
@@ -428,33 +425,33 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
428
425
|
<div class="lane-list">
|
|
429
426
|
${e.map((n,r)=>{let o=n.role==="ai_ready",i=o?"AI Ready lane name is locked \u2014 disable AI to hide this column":"";return`
|
|
430
427
|
<div class="lane-row${o?" lane-row--locked":""}" data-lane-id="${n.id}">
|
|
431
|
-
<button type="button" class="lane-icon-btn" data-lane-action="up" ${r===0?"disabled":""} title="Move lane left" aria-label="Move lane left">\u2191</button>
|
|
432
|
-
<button type="button" class="lane-icon-btn" data-lane-action="down" ${r===e.length-1?"disabled":""} title="Move lane right" aria-label="Move lane right">\u2193</button>
|
|
428
|
+
<button type="button" data-variant="ghost" class="settings-lane-icon-btn" data-lane-action="up" ${r===0?"disabled":""} title="Move lane left" aria-label="Move lane left">\u2191</button>
|
|
429
|
+
<button type="button" data-variant="ghost" class="settings-lane-icon-btn" data-lane-action="down" ${r===e.length-1?"disabled":""} title="Move lane right" aria-label="Move lane right">\u2193</button>
|
|
433
430
|
<input name="name" value="${l(n.name)}" aria-label="Lane name" ${o?`readonly title="${l(i)}"`:""} />
|
|
434
|
-
<button type="button" class="lane-new-toggle ${n.is_default?"is-on":""}" data-lane-action="toggle-default" aria-pressed="${n.is_default?"true":"false"}" title="${n.is_default?"Default lane for new cards \u2014 click another lane to move it":"Make this the default lane for new cards"}" aria-label="Default lane for new cards">
|
|
431
|
+
<button type="button" data-variant="${n.is_default?"secondary":"ghost"}" class="settings-lane-new-toggle ${n.is_default?"is-on":""}" data-lane-action="toggle-default" aria-pressed="${n.is_default?"true":"false"}" title="${n.is_default?"Default lane for new cards \u2014 click another lane to move it":"Make this the default lane for new cards"}" aria-label="Default lane for new cards">
|
|
435
432
|
<span class="lane-new-sun" aria-hidden="true"></span>
|
|
436
433
|
<span class="lane-new-label">New</span>
|
|
437
434
|
</button>
|
|
438
|
-
<button type="button" class="lane-delete-btn" data-lane-action="delete" ${Jr(n,a,t)?"disabled":""} title="${Kr(n,a,t)}" aria-label="Delete lane">\xD7</button>
|
|
435
|
+
<button type="button" data-variant="ghost" class="settings-lane-delete-btn danger-button" data-lane-action="delete" ${Jr(n,a,t)?"disabled":""} title="${Kr(n,a,t)}" aria-label="Delete lane">\xD7</button>
|
|
439
436
|
</div>
|
|
440
437
|
`}).join("")}
|
|
441
438
|
</div>
|
|
442
|
-
`}async function Wr(e){let t=e.closest(".lane-row"),a=t.dataset.laneId,n=e.dataset.laneAction;if(n==="delete"){await v(
|
|
443
|
-
`).length+1);let
|
|
439
|
+
`}async function Wr(e){let t=e.closest(".lane-row"),a=t.dataset.laneId,n=e.dataset.laneAction;if(n==="delete"){await v(S(`/api/states/${a}`),{method:"DELETE"}),await _(),c.detailMode="settings",b.success("Lane deleted");return}if(n==="toggle-default"){if(e.getAttribute("aria-pressed")==="true")return;k.querySelectorAll('[data-lane-action="toggle-default"]').forEach(u=>{u.setAttribute("aria-pressed","false"),u.setAttribute("data-variant","ghost"),u.classList.remove("is-on")}),e.setAttribute("aria-pressed","true"),e.setAttribute("data-variant","secondary"),e.classList.add("is-on"),await yn(t,{silent:!0}),b.success("Default lane updated");return}let r=Je().map(s=>s.id),o=r.indexOf(a),i=n==="up"?o-1:o+1;i<0||i>=r.length||([r[o],r[i]]=[r[i],r[o]],await v(`/api/boards/${c.boardId}/states`,{method:"PATCH",body:{state_ids:r}}),await _(),c.detailMode="settings",b.success("Lanes reordered"))}async function yn(e,{silent:t=!1}={}){let a=e.querySelector('input[name="name"]').value,r=e.querySelector('[data-lane-action="toggle-default"]')?.getAttribute("aria-pressed")==="true";await v(S(`/api/states/${e.dataset.laneId}`),{method:"PATCH",body:{name:a,is_default:r}}),await _(),c.detailMode="settings",t||b.success("Lane updated")}var O,Ct,It,gn,vn=C(()=>{z();ne();re();Z();pe();gt();fe();tt();ma();me();Oe();qt();Jt();O={boardId:"",step:"idle",exported:!1};Ct={windows:{label:"Windows",shell:"PowerShell",serverPath:"C:\\Path\\To\\StarscapeOrbit\\src\\mcp-server.js"},macos:{label:"macOS",shell:"Terminal",serverPath:"/Users/you/apps/starscape-orbit/src/mcp-server.js"},linux:{label:"Linux",shell:"Terminal",serverPath:"/home/you/apps/starscape-orbit/src/mcp-server.js"}},It={"claude-code":{label:"Claude Code",format:"CLI command",helper:"Run this command once. Claude Code records the local Orbit tool server for the project."},codex:{label:"Codex",format:"config.toml",helper:"Paste this TOML into Codex config. Project-local config may require the project to be trusted."},cursor:{label:"Cursor",format:"MCP JSON",helper:"Paste this JSON into Cursor MCP settings. Cursor starts Orbit when an agent needs the tools."},opencode:{label:"OpenCode",format:"opencode.json",helper:"Paste this into OpenCode config under the local MCP server list."},openclaw:{label:"OpenClaw",format:"MCP JSON",helper:"Paste this JSON into OpenClaw's MCP server list. OpenClaw will spawn Orbit on demand."},generic:{label:"Other MCP app",format:"MCP JSON",helper:"Most MCP clients accept this JSON shape for local stdio servers."}};gn=new Set(["in_progress","review"])});function Se(e){return String(e||"").trim()}function ha(e){let t=Se(e);return t?t.replace(/^@+/,"").replace(/[-_]+/g," ").replace(/\s+/g," ").trim().replace(/\b\w/g,a=>a.toUpperCase()):""}function kn({actor:e,actorId:t}={}){let a=Se(e),n=Se(t),r=a.toLowerCase(),o=n.toLowerCase();return a&&!fa.has(r)&&!wn.has(r)?ha(a):n&&!fa.has(o)&&!wn.has(o)?ha(n):""}function ba({actor:e,actorType:t,actorId:a}={}){let n=Se(t).toLowerCase(),r=Se(e),o=r.toLowerCase();if(n==="agent"){let i=kn({actor:r,actorId:a});return i?`Agent \xB7 ${i}`:"Agent"}return!r||fa.has(o)?"You":ha(r)}function $n(e={}){let t=Se(e.kind).toLowerCase(),a=Se(e.author);if(Xr.has(t)||t&&t!=="human_comment"){let r=kn({actor:a});return r?`Agent \xB7 ${r}`:"Agent"}return ba({actor:a,actorType:"human"})}var fa,wn,Xr,xn=C(()=>{fa=new Set(["local","local-owner","owner"]),wn=new Set(["agent","local-agent","orbit-agent"]),Xr=new Set(["agent_note","checkpoint","completion"])});async function ce(e,{renderBoardAfter:t=!1}={}){let[a,n,r]=await Promise.all([v(S(`/api/tickets/${e}/context?depth=1`)),v(S(`/api/tickets/${e}/history`)),v(S(`/api/tickets/${e}/comments`))]);a.ticket?.id===e&&(ja(a.ticket),t&&Fe(),!(c.detailMode!=="ticket"||c.selectedTicketId!==e)&&await Le({context:a,statusHistory:n,comments:r.comments||[]}))}async function be(e,t){await v(S(`/api/tickets/${e}`),{method:"PATCH",body:t}),await ce(e,{renderBoardAfter:!0})}function Vr(e,t,a){if(!e||!t||typeof t.clientX!="number"||typeof t.clientY!="number")return null;let n=null;if(document.caretPositionFromPoint){let r=document.caretPositionFromPoint(t.clientX,t.clientY);r?.offsetNode&&(r.offsetNode===e||e.contains(r.offsetNode))&&(n=document.createRange(),n.setStart(e,0),n.setEnd(r.offsetNode,r.offset))}else if(document.caretRangeFromPoint){let r=document.caretRangeFromPoint(t.clientX,t.clientY);r?.startContainer&&(r.startContainer===e||e.contains(r.startContainer))&&(n=document.createRange(),n.setStart(e,0),n.setEnd(r.startContainer,r.startOffset))}return n?Math.max(0,Math.min(a,n.toString().length)):null}function Qr(e){let t=e?.closest?.(".drawer-inner");return t?{scrollContainer:t,nodeRect:e.getBoundingClientRect(),scrollTop:t.scrollTop}:null}function Zr(e,t){if(!e?.scrollContainer||!t?.isConnected)return;let a=t.getBoundingClientRect(),n=Math.max(0,e.scrollContainer.scrollTop+(a.top-e.nodeRect.top));Number.isFinite(n)?e.scrollContainer.scrollTop=n:e.scrollContainer.scrollTop=e.scrollTop}function eo(e){try{e.focus({preventScroll:!0})}catch{e.focus()}}function je(e,t){if(!e||e.dataset.editing==="true")return;let{fieldName:a,multiline:n=!0,initialValue:r="",ariaLabel:o,emptyMessage:i,sourceEvent:s,rerender:u,commit:d}=t,m=n?Qr(e):null,p=String(r),f=n?Vr(e,s,p.length):null;e.dataset.editing="true";let h=document.createElement(n?"textarea":"input");if(h.className=n?"inline-desc-editor":"inline-title-editor",h.value=p,a&&h.setAttribute("data-editing-field",a),o&&h.setAttribute("aria-label",o),!n)h.type="text",h.maxLength=500,h.autocomplete="off",h.spellcheck=!0;else{h.rows=Math.max(3,p.split(`
|
|
440
|
+
`).length+1);let x=e.getBoundingClientRect().height;Number.isFinite(x)&&x>0&&(h.style.minHeight=`${Math.ceil(x)}px`)}if(e.replaceWith(h),eo(h),!n)h.select();else{let x=f??0;h.setSelectionRange(x,x),Zr(m,h)}let w=!1,$=()=>{document.removeEventListener("pointerdown",te,!0)},M=()=>{h.isConnected&&h.replaceWith(e),delete e.dataset.editing},A=()=>{w=!0,$(),M()};function te(x){w||x.target===h||h.contains(x.target)||h.blur()}document.addEventListener("pointerdown",te,!0);let B=async()=>{if(w)return;let x=n?h.value:h.value.trim();if(A(),String(x)===String(r)){u&&await u();return}if(i&&!x.trim()){b.warning(i),u&&await u();return}d&&await d(x)},L=async()=>{w||(A(),u&&await u())};h.addEventListener("blur",B),h.addEventListener("keydown",x=>{if(x.key==="Escape"){x.preventDefault(),L();return}x.key==="Enter"&&(n?(x.metaKey||x.ctrlKey)&&(x.preventDefault(),B()):(x.preventDefault(),B()))})}function to(e){let t=e.id,a=()=>je(n,{fieldName:"title",multiline:!1,initialValue:e.title||"",ariaLabel:"Edit ticket title",emptyMessage:"Title cannot be empty",rerender:()=>Le(),commit:d=>be(t,{title:d})}),n=U.querySelector('[data-edit-field="title"]');n&&(n.addEventListener("click",a),n.addEventListener("keydown",d=>{(d.key==="Enter"||d.key===" ")&&(d.preventDefault(),a())}));let r=k.querySelector('[data-edit-field="description"]'),o=d=>je(r,{fieldName:"description",multiline:!0,initialValue:e.description||"",ariaLabel:"Edit ticket description",sourceEvent:d,rerender:()=>Le(),commit:m=>be(t,{description:ie(m)})});r&&(r.addEventListener("click",d=>{d.preventDefault(),o(d)}),r.addEventListener("keydown",d=>{(d.key==="Enter"||d.key===" ")&&(d.preventDefault(),o())}));let i=[{key:"ai_plan",label:"AI plan"},{key:"implementation_summary",label:"Implementation summary"},{key:"implementation_updates",label:"Implementation updates / lessons"}];for(let{key:d,label:m}of i){let p=k.querySelector(`[data-edit-field="${d}"]`);if(!p)continue;let f=h=>je(p,{fieldName:d,multiline:!0,initialValue:e[d]||"",ariaLabel:`Edit ${m}`,sourceEvent:h,rerender:()=>Le(),commit:w=>be(t,{[d]:ie(w)})});p.addEventListener("click",h=>{h.preventDefault(),f(h)}),p.addEventListener("keydown",h=>{(h.key==="Enter"||h.key===" ")&&(h.preventDefault(),f())})}U.querySelectorAll(".meta-select[data-meta-field]").forEach(d=>{d.addEventListener("change",async()=>{let m=d.dataset.metaField;if(m==="type"){await be(t,{type:d.value});return}if(m==="state_id"){await be(t,{state_id:d.value});return}if(m==="parent_ticket_id"){await be(t,{parent_ticket_id:d.value||null});return}m==="priority"&&await be(t,{priority:Number(d.value)})})});let s=async d=>{await be(t,{labels:d})};k.querySelectorAll("[data-remove-label]").forEach(d=>{d.addEventListener("click",async()=>{let m=d.getAttribute("data-remove-label"),p=(e.labels||[]).map(f=>f.name).filter(f=>f!==m);await s(p)})});let u=async()=>{let d=k.querySelector("[data-label-input]");if(!d)return;let m=d.value.trim();if(!m)return;let p=(e.labels||[]).map(f=>f.name);if(p.includes(m)){d.value="";return}p.push(m),d.value="",await s(p)};k.querySelector("[data-label-add]")?.addEventListener("click",()=>{u()}),k.querySelector("[data-label-input]")?.addEventListener("keydown",d=>{d.key==="Enter"&&(d.preventDefault(),u())})}async function Le(e={}){if(c.detailMode==="settings"){await he(),Zt();return}if(!c.selectedTicketId){ht();return}let t=c.selectedTicketId,a=g=>Object.prototype.hasOwnProperty.call(e,g),[n,r,o,i]=await Promise.all([a("context")?Promise.resolve(e.context):v(S(`/api/tickets/${t}/context?depth=1`)),a("statusHistory")?Promise.resolve(e.statusHistory):v(S(`/api/tickets/${t}/history`)),a("comments")?Promise.resolve(e.comments):v(S(`/api/tickets/${t}/comments`)).then(g=>g.comments||[]),a("attachmentList")?Promise.resolve(e.attachmentList):H.attachments?v(S(`/api/tickets/${t}/attachments`)).catch(()=>({attachments:[]})):Promise.resolve({attachments:[]})]);if(c.detailMode!=="ticket"||c.selectedTicketId!==t||n.ticket?.id!==t)return;let s=n.ticket;St(s.id,s.updated_at),document.querySelector(`.card[data-ticket-id="${CSS.escape(s.id)}"] .card-unread-dot`)?.remove();let u=Oa(s.state_id),d=["epic","feature","task","bug"].map(g=>`<option value="${l(g)}" ${N(s.type)===g?"selected":""}>${l(qa(g))}</option>`).join(""),m=u.map(g=>`<option value="${l(g.id)}" ${g.id===s.state_id?"selected":""}>${l(g.name)}</option>`).join(""),p=[0,1,2,3,4].map(g=>`<option value="${g}" ${Number(s.priority)===g?"selected":""}>${l(Re(g))}</option>`).join(""),f=(s.labels||[]).map(g=>`
|
|
444
441
|
<span class="label-pill-removable" style="--label-color: ${l(g.color)}">
|
|
445
442
|
${l(g.name)}
|
|
446
443
|
<button type="button" class="label-pill-remove" data-remove-label="${l(g.name)}" title="Remove label">\xD7</button>
|
|
447
|
-
</span>`).join(""),
|
|
444
|
+
</span>`).join(""),w=Fa().map(g=>g.name).filter(g=>!s.labels?.some(I=>I.name===g)).map(g=>`<option value="${l(g)}"></option>`).join(""),$=N(s.type),M=De(s.priority),A=u.find(g=>g.id===s.state_id),te=Ye(A),B=s.description?we(s.description):l("No description yet."),L=s.description?"description preserved-text-body editable-field":"description editable-field is-placeholder",x=`
|
|
448
445
|
<span class="ticket-number">${l(Q(s))}</span>
|
|
449
446
|
<div class="detail-meta-badge-row" aria-label="Ticket metadata controls">
|
|
450
|
-
<select class="detail-meta-badge detail-state-badge
|
|
451
|
-
<select class="detail-meta-badge detail-type-badge type-pill-${l(
|
|
452
|
-
<select class="detail-meta-badge detail-priority-badge priority-pill
|
|
447
|
+
<select class="detail-meta-badge detail-state-badge meta-select" data-variant="${l(te)}" data-meta-field="state_id" aria-label="Ticket state">${m}</select>
|
|
448
|
+
<select class="detail-meta-badge detail-type-badge type-pill-${l($)} meta-select" data-meta-field="type" aria-label="Ticket type">${d}</select>
|
|
449
|
+
<select class="detail-meta-badge detail-priority-badge priority-pill meta-select" data-variant="${l(M)}" data-meta-field="priority" aria-label="Ticket priority">${p}</select>
|
|
453
450
|
</div>
|
|
454
|
-
`;bt({mode:"ticket",title:s.title,titleAttrs:{class:"editable-field","data-edit-field":"title",role:"button",tabindex:"0",title:"Click or press Enter to edit ticket title","aria-label":"Edit ticket title"},subtitleHtml:
|
|
451
|
+
`;bt({mode:"ticket",title:s.title,titleAttrs:{class:"editable-field","data-edit-field":"title",role:"button",tabindex:"0",title:"Click or press Enter to edit ticket title","aria-label":"Edit ticket title"},subtitleHtml:x,body:`
|
|
455
452
|
<div class="detail-head">
|
|
456
453
|
<p class="detail-updated" title="Last saved change">Updated ${l(Ha(s.updated_at))}</p>
|
|
457
|
-
<div class="${
|
|
454
|
+
<div class="${L}" data-edit-field="description" tabindex="0" title="Click to edit">${B}</div>
|
|
458
455
|
<dl class="ticket-meta" id="ticketMetaGrid" data-ticket-id="${l(s.id)}">
|
|
459
456
|
<div class="ticket-meta-row ticket-meta-row--stack">
|
|
460
457
|
<dt>Labels</dt>
|
|
@@ -462,7 +459,7 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
462
459
|
<div class="label-pills-row" data-other-labels>${f}</div>
|
|
463
460
|
<div class="label-add-row">
|
|
464
461
|
<input type="text" class="label-add-input meta-inline-input" data-label-input list="board-label-suggestions" placeholder="Add label\u2026" aria-label="Add label" />
|
|
465
|
-
<datalist id="board-label-suggestions">${
|
|
462
|
+
<datalist id="board-label-suggestions">${w}</datalist>
|
|
466
463
|
<button type="button" class="ghost meta-add-btn" data-label-add>Add</button>
|
|
467
464
|
</div>
|
|
468
465
|
</dd>
|
|
@@ -472,7 +469,7 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
472
469
|
|
|
473
470
|
${po(s,n)}
|
|
474
471
|
|
|
475
|
-
${
|
|
472
|
+
${H.attachments?no(s,i.attachments||[]):""}
|
|
476
473
|
|
|
477
474
|
${mo(s,n)}
|
|
478
475
|
|
|
@@ -504,7 +501,7 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
504
501
|
<button type="submit">Comment</button>
|
|
505
502
|
</form>
|
|
506
503
|
</div>
|
|
507
|
-
`}),to(s),
|
|
504
|
+
`}),to(s),H.attachments&&io(s),y("#detailCommentForm").addEventListener("submit",async g=>{g.preventDefault();let I=ie(new FormData(g.currentTarget).get("body")).trim();I&&(await v(S(`/api/tickets/${s.id}/comments`),{method:"POST",body:{body:I}}),await ce(s.id))}),k.querySelectorAll("[data-open-ticket]").forEach(g=>{g.addEventListener("click",async I=>{I.target.closest("[data-detach-child],[data-detach-parent],[data-detach-relation]")||P({boardId:c.boardId,view:"ticket",ticketId:g.dataset.openTicket})})}),k.querySelectorAll("[data-detach-child]").forEach(g=>{g.addEventListener("click",async I=>{I.stopPropagation();let D=g.dataset.detachChild;try{await v(S(`/api/tickets/${D}`),{method:"PATCH",body:{parent_ticket_id:null}})}catch(q){b.error(q.message||"Failed to remove child");return}await ce(s.id,{renderBoardAfter:!0}),b.success("Removed from epic")})}),k.querySelectorAll("[data-detach-parent]").forEach(g=>{g.addEventListener("click",async I=>{I.stopPropagation();try{await v(S(`/api/tickets/${s.id}`),{method:"PATCH",body:{parent_ticket_id:null}})}catch(D){b.error(D.message||"Failed to remove parent");return}await ce(s.id,{renderBoardAfter:!0}),b.success("Parent epic removed")})}),k.querySelectorAll("[data-detach-relation]").forEach(g=>{g.addEventListener("click",async I=>{I.stopPropagation();let D=g.dataset.detachRelation;try{await v(S(`/api/relations/${D}`),{method:"DELETE"})}catch(q){b.error(q.message||"Failed to remove relation");return}await ce(s.id),b.success("Relation removed")})});let R=k.querySelector("[data-ai-plan-toggle]");R&&R.addEventListener("toggle",()=>{let g=R.dataset.ticketId;R.open?localStorage.setItem(`mab_ai_plan_open:${g}`,"1"):localStorage.removeItem(`mab_ai_plan_open:${g}`)});let j=k.querySelector("#parentEpicForm");if(j){let g=j.querySelector("[name=target]"),I=j.querySelector("[data-parent-epic-clear]"),D=()=>{j.classList.toggle("has-value",g.value.length>0)};g.addEventListener("input",D),D(),I.addEventListener("click",()=>{g.value="",D(),g.focus()}),j.addEventListener("submit",async q=>{q.preventDefault();let X=String(new FormData(q.currentTarget).get("target")||"").trim();if(!X)return;let J=Sn(X,s.id);if(!J){b.warning("Pick an epic from the suggestions");return}let ae=W().find(K=>K.id===J);if(!ae||N(ae.type)!=="epic"){b.warning("Parent must be an epic");return}try{await v(S(`/api/tickets/${s.id}`),{method:"PATCH",body:{parent_ticket_id:J}})}catch(K){b.error(K.message||"Failed to set parent epic");return}await ce(s.id,{renderBoardAfter:!0}),b.success("Parent epic set")})}let E=k.querySelector("#relatedAddForm");if(E){let g=E.querySelector("[name=target]"),I=E.querySelector("[data-related-clear]"),D=()=>{E.classList.toggle("has-value",g.value.length>0)};g.addEventListener("input",D),D(),I.addEventListener("click",()=>{g.value="",D(),g.focus()}),E.addEventListener("submit",async q=>{q.preventDefault();let X=new FormData(q.currentTarget),J=String(X.get("target")||"").trim(),ae=String(X.get("type")||"relates_to");if(!J)return;let K=Sn(J,s.id);if(!K){b.warning("Pick a ticket from the suggestions");return}try{await v(S("/api/relations"),{method:"POST",body:{source_ticket_id:s.id,target_ticket_id:K,type:ae}})}catch(Ee){b.error(Ee.message||"Failed to add relation");return}await ce(s.id)})}Zt()}function ao(e){return localStorage.getItem(`mab_ai_plan_open:${e}`)==="1"}function no(e,t=[]){let a=t.length?`<div class="attachment-grid">${t.map(n=>ro(e,n)).join("")}</div>`:'<p class="description">No images attached yet.</p>';return`
|
|
508
505
|
<div class="section attachments-section" data-attachment-section data-ticket-id="${l(e.id)}">
|
|
509
506
|
<div class="attachment-heading-row">
|
|
510
507
|
<h3>Images</h3>
|
|
@@ -525,7 +522,7 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
525
522
|
<div class="attachment-card-meta"><strong>${a}</strong><span>${n}</span></div>
|
|
526
523
|
<button type="button" class="attachment-delete" data-delete-attachment="${l(t.id)}" aria-label="Remove missing image">\xD7</button>
|
|
527
524
|
</article>
|
|
528
|
-
`;let r
|
|
525
|
+
`;let r=S(t.content_url||`/api/tickets/${e.id}/attachments/${t.id}/content`);return`
|
|
529
526
|
<article class="attachment-card">
|
|
530
527
|
<button type="button" class="attachment-thumb-button" data-open-lightbox="${l(r)}" data-lightbox-title="${a}">
|
|
531
528
|
<img src="${l(r)}" alt="${a}" loading="lazy" />
|
|
@@ -533,7 +530,7 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
533
530
|
<div class="attachment-card-meta"><strong>${a}</strong><span>${n}</span></div>
|
|
534
531
|
<button type="button" class="attachment-delete" data-delete-attachment="${l(t.id)}" aria-label="Remove image">\xD7</button>
|
|
535
532
|
</article>
|
|
536
|
-
`}function oo(e){let t=Number(e||0);return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(1)} MB`}function Ln(e){return[...e||[]].filter(t=>t&&String(t.type||"").startsWith("image/"))}async function ga(e,t){let a=Ln(t);if(!a.length){
|
|
533
|
+
`}function oo(e){let t=Number(e||0);return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(1)} MB`}function Ln(e){return[...e||[]].filter(t=>t&&String(t.type||"").startsWith("image/"))}async function ga(e,t){let a=Ln(t);if(!a.length){b.warning("No image files found");return}for(let n of a){let r=await fetch(S(`/api/tickets/${e.id}/attachments?filename=${encodeURIComponent(n.name||"image")}`),{method:"POST",headers:{"Content-Type":n.type||"application/octet-stream","X-File-Name":n.name||"image"},body:n});if(!r.ok){let o={};try{o=await r.json()}catch{}throw new Error(o.error||`Upload failed (${r.status})`)}}await ce(e.id),b.success(a.length===1?"Image attached":`${a.length} images attached`)}function io(e){let t=k.querySelector("[data-attachment-section]");if(!t)return;let a=t.querySelector("[data-attachment-input]");a?.addEventListener("change",async()=>{try{await ga(e,a.files),a.value=""}catch(r){b.error(r.message||"Upload failed")}});let n=t.querySelector("[data-attachment-dropzone]");n?.addEventListener("dragover",r=>{r.preventDefault(),n.classList.add("is-dragover")}),n?.addEventListener("dragleave",()=>n.classList.remove("is-dragover")),n?.addEventListener("drop",async r=>{r.preventDefault(),n.classList.remove("is-dragover");try{await ga(e,r.dataTransfer?.files||[])}catch(o){b.error(o.message||"Upload failed")}}),k.onpaste=async r=>{if(r.target.closest("input, textarea, [contenteditable='true']"))return;let o=Ln(r.clipboardData?.files||[]);if(o.length){r.preventDefault();try{await ga(e,o)}catch(i){b.error(i.message||"Paste upload failed")}}},t.querySelectorAll("[data-delete-attachment]").forEach(r=>{r.addEventListener("click",async()=>{try{await v(S(`/api/tickets/${e.id}/attachments/${r.dataset.deleteAttachment}`),{method:"DELETE"}),await ce(e.id),b.success("Image removed")}catch(o){b.error(o.message||"Delete failed")}})}),t.querySelectorAll("[data-open-lightbox]").forEach(r=>{r.addEventListener("click",()=>so(r.dataset.openLightbox,r.dataset.lightboxTitle||"Image"))})}function so(e,t){document.querySelector(".attachment-lightbox")?.remove();let n=document.createElement("div");n.className="attachment-lightbox",n.innerHTML=`
|
|
537
534
|
<div class="attachment-lightbox-panel" role="dialog" aria-modal="true" aria-label="${l(t)}">
|
|
538
535
|
<button type="button" class="attachment-lightbox-close" aria-label="Close image">\xD7</button>
|
|
539
536
|
<img src="${l(e)}" alt="${l(t)}" />
|
|
@@ -578,12 +575,12 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
578
575
|
</select>
|
|
579
576
|
<button type="submit" class="ghost meta-add-btn">Add</button>
|
|
580
577
|
</form>
|
|
581
|
-
`;return i+s}function po(e,t){if(
|
|
578
|
+
`;return i+s}function po(e,t){if(N(e.type)==="epic"){let n=t.child_tickets||[];return`
|
|
582
579
|
<div class="section">
|
|
583
580
|
<h3>Features inside this Epic</h3>
|
|
584
581
|
${n.length?`<div class="detail-card-grid">${n.map(o=>at(o,{detach:{mode:"child",id:o.id}})).join("")}</div>`:'<p class="description">No child features yet. Create a feature / task card and set this epic as its parent.</p>'}
|
|
585
582
|
</div>
|
|
586
|
-
`}return""}function mo(e,t){if(
|
|
583
|
+
`}return""}function mo(e,t){if(N(e.type)==="epic")return"";let n=W().filter(o=>o.type==="epic"&&o.id!==e.id).map(o=>`<option value="#${o.number} \u2014 ${l(o.title)}"></option>`).join("");return`
|
|
587
584
|
<div class="section">
|
|
588
585
|
<h3>Epic</h3>
|
|
589
586
|
${t.parent_ticket?`<div class="detail-card-grid detail-card-grid--single">${at(t.parent_ticket,{detach:{mode:"parent"}})}</div>`:`
|
|
@@ -597,13 +594,13 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
597
594
|
</form>
|
|
598
595
|
`}
|
|
599
596
|
</div>
|
|
600
|
-
`}function at(e,t={}){let a=
|
|
597
|
+
`}function at(e,t={}){let a=N(e.type),n=De(e.priority),r=Ye(e),o=Be(e.type).toUpperCase(),i=t.eyebrow?`<span class="card-eyebrow">${l(t.eyebrow)}</span>`:"",s="";if(t.detach){let{mode:m,id:p}=t.detach,f="",h="";m==="child"?(f=`data-detach-child="${l(p)}"`,h="Remove from epic"):m==="parent"?(f='data-detach-parent="1"',h="Remove parent epic"):m==="relation"&&(f=`data-detach-relation="${l(p)}"`,h="Remove relation"),s=`<button type="button" class="card-detach-btn" ${f} aria-label="${h}" title="${h}">\xD7</button>`}else if(t.archive){let m=l(t.archive.id);s=`
|
|
601
598
|
<div class="card-archive-actions">
|
|
602
599
|
<button type="button" class="card-archive-btn card-archive-btn--restore" data-archive-restore="${m}" aria-label="Restore to board" title="Restore to board"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 12a9 9 0 1 0 3-6.7"/><path d="M3 4v5h5"/></svg></button>
|
|
603
600
|
<button type="button" class="card-archive-btn card-archive-btn--delete" data-archive-delete="${m}" aria-label="Delete permanently" title="Delete permanently"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6"/><path d="M14 11v6"/></svg></button>
|
|
604
601
|
</div>
|
|
605
602
|
`}let u=xt(e),d=u===0?"":u===1?'<span class="card-unread-dot" role="status" aria-label="1 unread update"></span>':`<span class="card-unread-dot has-count" role="status" aria-label="${u} unread updates">${u>99?"99+":u}</span>`;return`
|
|
606
|
-
<article class="card card--detail type-${l(a)} priority-${l(n)}"${t.disableOpen?"":` data-open-ticket="${l(e.id)}"`}>
|
|
603
|
+
<article class="card card--detail type-${l(a)} priority-${l(n)}" data-variant="${l(a)}"${t.disableOpen?"":` data-open-ticket="${l(e.id)}"`}>
|
|
607
604
|
${d}
|
|
608
605
|
${s}
|
|
609
606
|
${i}
|
|
@@ -615,12 +612,12 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
615
612
|
${Et(e.type)}
|
|
616
613
|
<span class="card-type-label">${l(o)}</span>
|
|
617
614
|
</div>
|
|
618
|
-
<span class="detail-card-state
|
|
615
|
+
<span class="detail-card-state" data-variant="${l(r)}">${l(e.state_name||"State")}</span>
|
|
619
616
|
${c.showPriority?da(e.priority):""}
|
|
620
617
|
</div>
|
|
621
618
|
</div>
|
|
622
619
|
</article>
|
|
623
|
-
`}function fo(e){let t=String(e.type||"").replace(/_/g," "),a=e.direction==="incoming"?"from":"to";return at(e.other_ticket,{eyebrow:`${t} ${a}`,detach:{mode:"relation",id:e.id}})}var ma=C(()=>{z();ne();re();tt();gt();fe();Z();Oe();pe();vn();Ze();xn()});function va(){He&&(clearTimeout(He),He=null),c.eventSource&&(c.eventSource.close(),c.eventSource=null);let e=new URLSearchParams;c.boardId&&e.set("board_id",c.boardId);let t=`/api/events/stream${e.toString()?`?${e}`:""}`,a=new EventSource(t);c.eventSource=a,a.addEventListener("open",()=>{Mt=1e3,Pt&&(
|
|
620
|
+
`}function fo(e){let t=String(e.type||"").replace(/_/g," "),a=e.direction==="incoming"?"from":"to";return at(e.other_ticket,{eyebrow:`${t} ${a}`,detach:{mode:"relation",id:e.id}})}var ma=C(()=>{z();ne();re();tt();gt();fe();Z();Oe();pe();vn();Ze();xn()});function va(){He&&(clearTimeout(He),He=null),c.eventSource&&(c.eventSource.close(),c.eventSource=null);let e=new URLSearchParams;c.boardId&&e.set("board_id",c.boardId);let t=`/api/events/stream${e.toString()?`?${e}`:""}`,a=new EventSource(t);c.eventSource=a,a.addEventListener("open",()=>{Mt=1e3,Pt&&(b.success("Live updates reconnected"),Pt=!1)}),a.addEventListener("board",async n=>{let r;try{r=JSON.parse(n.data)}catch{return}let o=r.type,i=()=>c.data?.tickets?.find(d=>d.id===r.ticket_id),s=c.data?.actor?.name,u=r.actor&&s&&r.actor===s;if(r.ticket_id&&(u?St(r.ticket_id,r.timestamp):o==="ticket_deleted"?on(r.ticket_id):ho.has(o)&&rn(r.ticket_id)),o==="ticket_created")b.success(`Card created: ${r.data.title||"New card"}`),ge();else if(o==="state_changed"){let d=i(),m=d?`#${d.number} ${d.title}`:"Card";b.info(`${m} \u2192 ${r.data.to}`),ge()}else if(o==="ticket_updated"){let d=i(),m=d?`#${d.number}`:"Card",p=r.data.fields?Object.keys(r.data.fields).join(", "):"";b.info(`${m} updated${p?`: ${p}`:""}`),ge()}else if(o==="comment_created"){let d=i(),m=d?`#${d.number}`:"ticket";b.info(`New comment on ${m}`),ge()}else if(o==="agent_claimed"){let d=i();b.info(`Agent claimed ${d?`#${d.number} ${d.title}`:"a ticket"}`),ge()}else if(o==="checkpoint_requested"){let d=i();b.warning(`Checkpoint on ${d?`#${d.number}`:"ticket"} \u2014 needs human input`),ge()}else if(o==="agent_completed"){let d=i();b.success(`Agent completed ${d?`#${d.number} ${d.title}`:"a ticket"}`),ge()}else(o==="ticket_deleted"||o==="states_reordered"||o==="state_created"||o==="state_deleted"||o==="board_updated"||o==="board_imported")&&ge()}),a.onerror=()=>{if(a.readyState!==EventSource.CLOSED||(Pt||(b.warning("Live updates disconnected \u2014 retrying\u2026"),Pt=!0),He))return;let n=Mt;Mt=Math.min(Mt*2,3e4),He=setTimeout(()=>{He=null,va()},n)}}var ho,Mt,He,Pt,ge,En=C(()=>{z();Z();pe();me();Ze();ho=new Set(["ticket_created","state_changed","ticket_updated","comment_created","agent_claimed","checkpoint_requested","agent_completed"]),Mt=1e3,He=null,Pt=!1;ge=mt(async()=>{let e=c.selectedTicketId,t=c.detailMode;c.data=await v(ft()),Pe(),c.selectedTicketId=e,c.detailMode=t,await At()},300)});var _n={};On(_n,{load:()=>_,render:()=>At,renderDetailOnly:()=>bo});async function _(){oe(),c.data=await v(ft()),Pe(),sn(c.boardId,c.data?.tickets||[]),await At(),H.sse&&c.boardId!==Tn&&(Tn=c.boardId,va())}async function At(){Pe(),wa(),Fe(),await Le()}async function bo(){Pe(),wa(),ln(),await Le()}var Tn,me=C(()=>{z();Z();tt();ma();nt();En();Ze();Oe();Tn=null});function $a(){return Te?.classList.contains("is-open")}function Tt(e){clearTimeout(ka),oe(),ht(),Nt.innerHTML=go(e||""),yo(),y("#createFlyoutClose")?.addEventListener("click",()=>F()),Te.hidden=!1,ve.hidden=!1,requestAnimationFrame(()=>{Te.classList.add("is-open"),ve.classList.add("is-visible")}),requestAnimationFrame(()=>{y("#createTicketTitle")?.focus()})}function F(){clearTimeout(ka),Te.classList.remove("is-open"),ve.classList.remove("is-visible"),ka=setTimeout(()=>{Te.hidden=!0,ve.hidden=!0,Nt.innerHTML=""},220)}function go(e){let t=Ae(),a=t.find(i=>i.is_default)||t[0],n=e&&t.some(i=>i.id===e)?e:a?.id||"",r=t.map(i=>`<option value="${l(i.id)}" ${i.id===n?"selected":""}>${l(i.name)}</option>`).join(""),o=W().filter(i=>i.type==="epic").map(i=>`<option value="${l(i.id)}">${l(Q(i))}</option>`).join("");return`
|
|
624
621
|
<div class="create-flyout-head">
|
|
625
622
|
<h2>New card</h2>
|
|
626
623
|
<button type="button" class="create-flyout-close ghost" id="createFlyoutClose" aria-label="Close">\xD7</button>
|
|
@@ -636,7 +633,7 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
636
633
|
<label>
|
|
637
634
|
Type
|
|
638
635
|
<select id="createTicketType" name="type" class="select-chevron-field" aria-label="Ticket type">
|
|
639
|
-
<option value="epic">Epic
|
|
636
|
+
<option value="epic">Epic</option>
|
|
640
637
|
<option value="feature">Feature</option>
|
|
641
638
|
<option value="task" selected>Task</option>
|
|
642
639
|
<option value="bug">Bug</option>
|
|
@@ -663,11 +660,11 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
663
660
|
<input id="createTicketLabels" name="labels" type="text" placeholder="Labels (comma-separated)" />
|
|
664
661
|
<button type="submit">Create card</button>
|
|
665
662
|
</form>
|
|
666
|
-
`}function yo(){let e=y("#createTicketForm");e&&e.addEventListener("submit",vo)}async function vo(e){e.preventDefault();let t=e.currentTarget,a=new FormData(t),n=String(a.get("labels")||"").split(",").map(o=>o.trim()).filter(Boolean),r=await v("/api/tickets",{method:"POST",body:{board_id:c.boardId,title:a.get("title"),description:a.get("description"),type:a.get("type"),parent_ticket_id:a.get("parent_ticket_id")||null,state_id:a.get("state"),priority:Number(a.get("priority")),labels:n}});
|
|
667
|
-
<button type="button" class="menu-flyout-item ${r.id===c.boardId?"is-current":""}" data-pick-board="${l(r.id)}" role="menuitem">
|
|
663
|
+
`}function yo(){let e=y("#createTicketForm");e&&e.addEventListener("submit",vo)}async function vo(e){e.preventDefault();let t=e.currentTarget,a=new FormData(t),n=String(a.get("labels")||"").split(",").map(o=>o.trim()).filter(Boolean),r=await v("/api/tickets",{method:"POST",body:{board_id:c.boardId,title:a.get("title"),description:a.get("description"),type:a.get("type"),parent_ticket_id:a.get("parent_ticket_id")||null,state_id:a.get("state"),priority:Number(a.get("priority")),labels:n}});F(),c.selectedTicketId=r.id,c.detailMode="ticket",await _(),qe()}var ka,Ne=C(()=>{ne();z();re();Z();fe();gt();nt();me();ka=0});function rt(){V&&(V.hidden=!0,V.innerHTML="",le?.setAttribute("aria-expanded","false"))}function oe(){rt()}function wa(){if(!c.data)return;let e=(c.data.boards||[]).find(t=>t.id===c.boardId);if(le){let t=e?.name||"Board";le.innerHTML=`${wo}<span class="topbar-chip-label">${l(t)}</span>`,le.title=e?`${e.name} \u2014 slug: ${e.slug}`:"Choose board"}}function ko(){let a=(c.data.boards||[]).map(r=>`
|
|
664
|
+
<button type="button" class="menu-flyout-item ${r.id===c.boardId?"is-current":""}" data-variant="menu-item" data-pick-board="${l(r.id)}" role="menuitem">
|
|
668
665
|
<span class="menu-flyout-item-title">${l(r.name)}</span>
|
|
669
666
|
<span class="menu-flyout-item-meta">${l(r.slug)}</span>
|
|
670
|
-
</button>`).join("")||'<p class="menu-flyout-hint menu-flyout-hint--empty">No boards yet. Create one below if you can.</p>',n=
|
|
667
|
+
</button>`).join("")||'<p class="menu-flyout-hint menu-flyout-hint--empty">No boards yet. Create one below if you can.</p>',n=H.multiBoard?`
|
|
671
668
|
<div class="menu-flyout-section">
|
|
672
669
|
<h3 class="menu-flyout-heading">New board</h3>
|
|
673
670
|
<form id="createBoardForm" class="menu-flyout-form">
|
|
@@ -686,13 +683,24 @@ enabled = true`}function Ar(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
686
683
|
<div class="menu-flyout-head">Board</div>
|
|
687
684
|
<div class="menu-flyout-list">${a}</div>
|
|
688
685
|
${n}
|
|
689
|
-
`}function
|
|
686
|
+
`}function $o(){V.querySelectorAll("[data-pick-board]").forEach(t=>{t.addEventListener("click",async a=>{a.stopPropagation();let n=t.getAttribute("data-pick-board");rt(),n!==c.boardId&&(F(),await P({boardId:n,view:"board"}))})});let e=V.querySelector("#createBoardForm");if(e){let t=e.querySelector("#pickRepoFolderBtn"),a=e.querySelector("#repoPathInput");t?.addEventListener("click",async n=>{n.preventDefault(),t.disabled=!0;try{let r=await v("/api/system/pick-folder",{method:"POST"});r.path&&(a.value=r.path,a.dispatchEvent(new Event("input",{bubbles:!0})))}catch(r){b.error(r?.message||"Folder picker unavailable")}finally{t.disabled=!1}}),e.addEventListener("submit",async n=>{n.preventDefault();let r=new FormData(e),o=String(r.get("slug")||"").trim(),i=String(r.get("default_branch")||"").trim(),s=String(r.get("repo_url")||"").trim(),u=String(r.get("repo_path")||"").trim();if(!u){a?.reportValidity();return}let d=await v("/api/boards",{method:"POST",body:{name:r.get("name"),repo_path:u,...o?{slug:o}:{},...i?{default_branch:i}:{},...s?{repo_url:s}:{}}});rt(),c.boardId=d.id,c.selectedTicketId="",c.detailMode="settings",await _(),qe(),b.success("Board created")})}}function Cn(){F(),V.innerHTML=ko(),V.hidden=!1,le?.setAttribute("aria-expanded","true"),$o()}var wo,nt=C(()=>{ne();z();re();Z();fe();Ne();pe();me();Oe();wo=`
|
|
687
|
+
<svg
|
|
688
|
+
class="topbar-icon"
|
|
689
|
+
width="16"
|
|
690
|
+
height="16"
|
|
691
|
+
viewBox="0 0 24 24"
|
|
692
|
+
fill="none"
|
|
693
|
+
aria-hidden="true"
|
|
694
|
+
>
|
|
695
|
+
<rect x="4" y="4" width="6" height="16" rx="0.75" stroke="currentColor" stroke-width="2" />
|
|
696
|
+
<rect x="14" y="4" width="6" height="16" rx="0.75" stroke="currentColor" stroke-width="2" />
|
|
697
|
+
</svg>`});function In(){return{...xo}}function Sa(e=globalThis.location){if(typeof e=="string"){let t=new URL(e,"http://orbit.local");return{pathname:t.pathname||"/",search:t.search||"",hash:t.hash||""}}return{pathname:e?.pathname||"/",search:e?.search||"",hash:e?.hash||""}}function xa(e){try{return decodeURIComponent(e)}catch{return e}}function So(e){return String(e||"").replace(/^#/,"").replace(/^\/+/,"").replace(/\/+$/,"").split("/").filter(Boolean)}function Lo(e){if(!e.length)return null;let t=In(),a=0;if(e[a]==="b"){if(!e[a+1])return null;t.boardSlug=xa(e[a+1]),a+=2}else if(e[a]!=="t"&&e[a]!=="settings")return null;if(e[a]==="t"&&e[a+1])t.view="ticket",t.ticketId=xa(e[a+1]);else if(e[a]==="settings"){t.view="settings";let n=e[a+1]?xa(e[a+1]):"";n&&dt.has(n)&&(t.tab=n)}return t}function Mn(e){let t=String(e||"");return!t||t==="#"||t==="#/"?null:Lo(So(t))}function Bt(e=globalThis.location){let t=Sa(e);return Mn(t.hash)||In()}function ot(e=globalThis.location){let t=Sa(e);return!!Mn(t.hash)}function Ue({boardSlug:e="",view:t="board",ticketId:a="",tab:n=""}={}){let r=[];return e&&r.push("b",encodeURIComponent(e)),t==="ticket"&&a?r.push("t",encodeURIComponent(a)):t==="settings"&&(r.push("settings"),n&&dt.has(n)&&r.push(n)),"#/"+r.join("/")}function Rt(e=globalThis.location,t=Bt(e)){return Sa(e).hash===Ue(t)}var xo,La=C(()=>{ut();xo=Object.freeze({boardSlug:"",view:"board",ticketId:"",tab:""})});function Pn(e){if(!e)return null;let t=c.data?.boards||[];return t.find(a=>a.slug===e)||t.find(a=>a.id===e)||null}function Eo(e={}){return e.boardSlug?e.boardSlug:e.boardId?Pn(e.boardId)?.slug||e.boardId:Y()?.slug||c.boardSlug||""}function To(e={}){return{...e,boardSlug:Eo(e)}}function _o(){let e="board";return c.detailMode==="ticket"&&c.selectedTicketId?e="ticket":c.detailMode==="settings"&&(e="settings"),{boardSlug:Y()?.slug||c.boardSlug,view:e,ticketId:c.selectedTicketId,tab:e==="settings"?Ge(c.settingsTab):""}}function An(e){Dt=e}function Ea(){return Bt(location)}async function P(e,{replace:t=!1}={}){let a=To(e),n=Ue(a);if(Rt(location,a)){Dt&&await it();return}t?history.replaceState(null,"",n):history.pushState(null,"",n),Dt&&await it()}function qe({replace:e=!1}={}){let t=_o(),a=Ue(t);Rt(location,t)||(e?history.replaceState(null,"",a):history.pushState(null,"",a))}async function it(){let{load:e,renderDetailOnly:t}=await Promise.resolve().then(()=>(me(),_n)),a=Ea(),n=ot(location),r=c.boardId,i=Pn(a.boardSlug)||(a.boardSlug?Y():null);i?(c.boardId=i.id,c.boardSlug=i.slug):a.boardSlug&&(c.boardSlug=a.boardSlug);let s=i?{...a,boardSlug:i.slug}:a;if(n&&!Rt(location,s)&&history.replaceState(null,"",Ue(s)),a.view==="ticket")c.selectedTicketId=a.ticketId||"",c.detailMode=a.ticketId?"ticket":"empty";else if(a.view==="settings"){if(c.selectedTicketId="",c.detailMode="settings",a.tab){c.settingsTab=a.tab;try{localStorage.setItem("mab_settings_tab",a.tab)}catch{}}}else c.selectedTicketId="",c.detailMode="empty";if(oe(),F(),c.boardId&&c.boardId!==r){await e();return}await t()}var Dt,fe=C(()=>{z();ut();nt();Ne();La();La();Dt=!1;window.addEventListener("popstate",()=>{Dt&&it()})});ne();qt();Jt();Pa(),ze();var qn=Un();Kt();{let e=()=>{document.body.classList.toggle("is-scrolled",window.scrollY>4)};window.addEventListener("scroll",e,{passive:!0}),e()}Ba();Ta?.addEventListener("click",()=>{Aa()});window.addEventListener(lt,()=>{Ba(),qn.sync()});function Ba(){if(!Ot)return;let e=ue()==="dark";Ot.innerHTML=e?'<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z" />':'<circle cx="12" cy="12" r="5" /><path d="M12 1v2m0 18v2M4.2 4.2l1.4 1.4m12.8 12.8l1.4 1.4M1 12h2m18 0h2M4.2 19.8l1.4-1.4M18.4 5.6l1.4-1.4" />'}function Un(){let e=document.querySelector(".grain");if(!e)return{sync:()=>{}};zn(e);let t=document.createElement("canvas");t.className="starfield-canvas",t.setAttribute("aria-hidden","true");let a=e.querySelector(".milky-way");a&&a.nextSibling?e.insertBefore(t,a.nextSibling):a?e.appendChild(t):e.insertBefore(t,e.firstChild);let n=t.getContext("2d"),r=Math.min(window.devicePixelRatio||1,2),o=0,i=0,s=[],u=0,d=!1,m={x:0,y:0,tx:0,ty:0};function p(){o=window.innerWidth,i=window.innerHeight,t.width=Math.round(o*r),t.height=Math.round(i*r),t.style.width=o+"px",t.style.height=i+"px",n.setTransform(r,0,0,r,0,0),f()}function f(){let L=o*i/1296e3,x=[{count:Math.round(320*L),depth:.12,sizes:[[1,.9],[1.4,.1]],glow:0},{count:Math.round(160*L),depth:.3,sizes:[[1,.5],[1.6,.4],[2.4,.1]],glow:1.8},{count:Math.round(44*L),depth:.58,sizes:[[1.8,.5],[2.6,.38],[3.6,.12]],glow:2.4}],R=Ra(12648430);s=[];for(let j of x)for(let E=0;E<j.count;E++){let g=Jn(R(),j.sizes);s.push({x:R()*o,y:R()*i,size:g,depth:j.depth,glow:g>=2?j.glow:0,rgb:h(R()),period:2.2+R()*5.4,phase:R()*Math.PI*2,amp:.25+R()*.5,baseAlpha:g<1.5?.45+R()*.28:.55+R()*.22})}}function h(L){return L<.8?[255,255,255]:L<.93?[255,222,186]:[195,218,255]}function w(L){!o||!i||(m.tx=L.clientX/o-.5,m.ty=L.clientY/i-.5)}function $(L){m.x+=(m.tx-m.x)*.06,m.y+=(m.ty-m.y)*.06,n.clearRect(0,0,o,i),n.globalCompositeOperation="lighter";let x=L/1e3,R=70;for(let j=0;j<s.length;j++){let E=s[j],g=.5+.5*Math.sin(x*(2*Math.PI/E.period)+E.phase),I=E.baseAlpha*(1-E.amp+E.amp*g),D=E.x-m.x*E.depth*R,q=E.y-m.y*E.depth*R,[X,J,ae]=E.rgb;if(E.glow>0){let K=E.size*E.glow,Ee=n.createRadialGradient(D,q,0,D,q,K);Ee.addColorStop(0,`rgba(${X},${J},${ae},${I*.85})`),Ee.addColorStop(.35,`rgba(${X},${J},${ae},${I*.3})`),Ee.addColorStop(1,`rgba(${X},${J},${ae},0)`),n.fillStyle=Ee,n.beginPath(),n.arc(D,q,K,0,Math.PI*2),n.fill(),n.fillStyle=`rgba(${X},${J},${ae},${I})`,n.beginPath(),n.arc(D,q,E.size/2,0,Math.PI*2),n.fill()}else{let K=E.size/2;n.fillStyle=`rgba(${X},${J},${ae},${I})`,n.fillRect(D-K,q-K,E.size,E.size)}}n.globalCompositeOperation="source-over",d&&(u=requestAnimationFrame($))}function M(){n.clearRect(0,0,o,i),n.globalCompositeOperation="lighter";for(let L of s){let[x,R,j]=L.rgb;if(n.fillStyle=`rgba(${x},${R},${j},${L.baseAlpha})`,L.glow>0)n.beginPath(),n.arc(L.x,L.y,L.size/2,0,Math.PI*2),n.fill();else{let E=L.size/2;n.fillRect(L.x-E,L.y-E,L.size,L.size)}}n.globalCompositeOperation="source-over"}function A(){d||(d=!0,u=requestAnimationFrame($))}function te(){d=!1,cancelAnimationFrame(u)}function B(){let L=ue()==="dark",x=Ce();if(!L){te(),n.clearRect(0,0,o,i);return}s.length||p(),x||document.hidden?(te(),M()):A()}return window.addEventListener("resize",()=>{p(),B()},{passive:!0}),window.addEventListener("pointermove",w,{passive:!0}),document.addEventListener("visibilitychange",B),window.matchMedia("(prefers-reduced-motion: reduce)").addEventListener("change",()=>{ze(),B()}),window.addEventListener("orbit:motion-preference-change",B),p(),B(),{sync:B}}function zn(e){e.querySelectorAll(".signature-star").forEach(n=>n.remove());let t=Ra(6070757),a=7;for(let n=0;n<a;n++){let r=document.createElement("div");r.className="signature-star",r.setAttribute("aria-hidden","true"),r.style.left=(6+t()*88).toFixed(2)+"%",r.style.top=(8+t()*78).toFixed(2)+"%",r.style.animationDelay=(-t()*4.8).toFixed(2)+"s",e.appendChild(r)}}function Kt(){let e=14e3+Math.random()*28e3;setTimeout(Gn,e)}function Gn(){let e=ue()==="dark",t=Ce(),a=document.querySelector(".grain");if(!e||t||document.hidden||!a){Kt();return}let n=window.innerWidth,r=window.innerHeight,o=Math.random()*n*.6,i=Math.random()*r*.55,s=380+Math.random()*520,u=18+Math.random()*26,d=u*Math.PI/180,m=o+Math.cos(d)*s,p=i+Math.sin(d)*s,f=document.createElement("div");f.className="meteor",f.setAttribute("aria-hidden","true"),f.style.setProperty("--from-x",o+"px"),f.style.setProperty("--from-y",i+"px"),f.style.setProperty("--to-x",m+"px"),f.style.setProperty("--to-y",p+"px"),f.style.setProperty("--angle",u+"deg"),a.appendChild(f),f.addEventListener("animationend",()=>f.remove(),{once:!0}),Kt()}function Jn(e,t){let a=0;for(let[n,r]of t)if(a+=r,e<a)return n;return t[t.length-1][0]}function Ra(e){let t=e>>>0;return function(){t=t+1831565813>>>0;let a=t;return a=Math.imul(a^a>>>15,a|1),a^=a+Math.imul(a^a>>>7,a|61),((a^a>>>14)>>>0)/4294967296}}ne();z();Z();pe();fe();nt();Ne();tt();ne();z();Z();fe();re();Ne();async function Bn(){let e=st.value.trim();if(e.length<2){Ft();return}let t=Y();if(!t)return;let a=await v(`/api/search?q=${encodeURIComponent(e)}&board=${encodeURIComponent(t.slug)}`);if(a.results.length===0){de.hidden=!1,de.innerHTML='<div class="search-hit">No results</div>';return}de.hidden=!1,de.innerHTML=a.results.map(n=>`
|
|
690
698
|
<div class="search-hit" data-ticket-id="${n.id}">
|
|
691
699
|
<span class="search-hit-main">
|
|
692
700
|
<strong>${l(Q(n))}</strong>
|
|
693
701
|
<span class="search-hit-title">${l(n.title)}</span>
|
|
694
702
|
</span>
|
|
695
|
-
<span class="search-hit-state
|
|
703
|
+
<span class="search-hit-state" data-variant="${l(Ye(n))}">${l(n.state_name||"State")}</span>
|
|
696
704
|
</div>
|
|
697
|
-
`).join(""),de.querySelectorAll("[data-ticket-id]").forEach(n=>{n.addEventListener("click",async()=>{
|
|
705
|
+
`).join(""),de.querySelectorAll("[data-ticket-id]").forEach(n=>{n.addEventListener("click",async()=>{F(),Ft(),P({boardId:c.boardId,view:"ticket",ticketId:n.dataset.ticketId})})})}function Ft(){de.hidden=!0,de.innerHTML=""}me();Oe();function Dn(e){e?.showModal()}function Rn(e){e?.open&&e.close()}function Fn(e){e&&(e.addEventListener("click",t=>{t.target===e&&Rn(e)}),e.querySelectorAll("[data-modal-close]").forEach(t=>{t.addEventListener("click",()=>Rn(e))}))}async function Co(){let e=document.getElementById("welcomeDialog");Fn(e),xe==="preview"&&Dn(e),y("#settingsBtn").addEventListener("click",async()=>{F(),oe(),P({boardId:c.boardId,view:"settings",tab:c.settingsTab||"lanes"})}),le?.addEventListener("click",a=>{if(a.stopPropagation(),!V.hidden){rt();return}Cn()}),y("#newTicketBtn").addEventListener("click",()=>{if($a()){F();return}Tt("")}),ve.addEventListener("click",()=>{F()}),y("#drawerCloseBtn").addEventListener("click",()=>{P({boardId:c.boardId,view:"board"})}),y("#drawerArchiveBtn").addEventListener("click",async()=>{let a=c.selectedTicketId;if(!a||c.detailMode!=="ticket")return;let r=c.data?.tickets?.find(o=>o.id===a)?.title||"card";await v(S(`/api/tickets/${encodeURIComponent(a)}/archive`),{method:"POST"}),b.error(`Archived: ${r}`),await _(),P({boardId:c.boardId,view:"board"})}),ye.addEventListener("click",()=>{P({boardId:c.boardId,view:"board"})}),document.addEventListener("keydown",a=>{if(a.key!=="Escape")return;if(!V.hidden){oe();return}if($a()){F();return}if(!U.classList.contains("is-open"))return;let n=document.activeElement;n?.classList?.contains("inline-title-editor")||n?.classList?.contains("inline-desc-editor")||P({boardId:c.boardId,view:"board"})}),st.addEventListener("input",mt(Bn,220)),document.addEventListener("click",a=>{a.target.closest("#topbarSearch")||Ft(),a.target.closest(".topbar-menu")||oe()}),un(),cn();let t=Ea();t.boardSlug&&(c.boardSlug=t.boardSlug),await _(),An(!0),ot()?await it():qe({replace:!0})}Co();
|
|
698
706
|
//# sourceMappingURL=app.js.map
|