@starlove/orbit 1.3.2 → 1.3.3
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/SKILL-ORBIT.md +4 -0
- package/dist/full/index.html +1 -1
- package/dist/full/js/{app.b8296a78.js → app.fb7767dc.js} +90 -90
- package/dist/full/js/app.fb7767dc.js.map +7 -0
- package/dist/full/orbits-logo-bg-wide.png +0 -0
- package/dist/full/version.json +2 -2
- package/package.json +1 -1
- package/public/js/starscape.js +10 -0
- package/public/js/theme-preference.js +13 -6
- package/public/orbits-logo-bg-wide.png +0 -0
- package/dist/full/js/app.b8296a78.js.map +0 -7
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
var
|
|
2
|
-
`):""}function ce(e){return d(X(e))}function
|
|
1
|
+
var Qn=Object.defineProperty;var _=(e,t)=>()=>(e&&(t=e(e=0)),t);var pt=(e,t)=>{for(var a in t)Qn(e,a,{get:t[a],enumerable:!0})};var y,ue,te,T,G,k,we,Me,Yt,ke,mt,pe,Ha,Wt,ie=_(()=>{y=e=>document.querySelector(e),ue=y("#boardMenuBtn"),te=y("#boardFlyout"),T=y("#kanban"),G=y("#drawer"),k=y("#drawerInner"),we=y("#drawerBackdrop"),Me=y("#createFlyout"),Yt=y("#createFlyoutInner"),ke=y("#createFlyoutBackdrop"),mt=y("#searchInput"),pe=y("#searchResults"),Ha=y("#themeToggle"),Wt=y("#themeIcon")});function Pe(e){try{return e??globalThis.localStorage??null}catch{return null}}function Vt(e){return typeof window<"u"&&typeof window.matchMedia=="function"?window.matchMedia(e):{matches:!1}}function ft(e=Pe()){let a=Pe(e)?.getItem?.(qa);return a==="true"?!0:a==="false"?!1:null}function Xt(e=Vt){try{return!!e("(prefers-reduced-motion: reduce)")?.matches}catch{return!1}}function Ae({storage:e=Pe(),mediaMatcher:t=Vt}={}){return ft(e)??Xt(t)}function Ua(e,t=Pe()){let a=Pe(t),n=e?"true":"false";return a?.setItem?.(qa,n),e}function Ye({doc:e=globalThis.document,storage:t=Pe(),mediaMatcher:a=Vt}={}){let n=e?.documentElement,r=ft(t);return n&&(r===!0?n.setAttribute("data-motion","reduce"):r===!1?n.setAttribute("data-motion","full"):n.removeAttribute("data-motion")),Ae({storage:t,mediaMatcher:a})}var qa,Qt=_(()=>{qa="mab_reduce_motion"});function Be(e){try{return e??globalThis.localStorage??null}catch{return null}}function Fe(e){try{return e??globalThis.document??null}catch{return null}}function Zt(e){try{return e??globalThis.window??null}catch{return null}}function Zn(e){return ea.has(e)?e:"light"}function bt(e=Be()){let a=Be(e)?.getItem?.(za);return ea.has(a)?a:null}function Ga(){try{return globalThis.matchMedia?.("(prefers-color-scheme: dark)").matches?"dark":"light"}catch{return"light"}}function $e({doc:e=Fe(),storage:t=Be()}={}){let a=Fe(e)?.documentElement?.getAttribute?.("data-theme");return ea.has(a)?a:bt(t)??Ga()}function Ka({doc:e=Fe(),storage:t=Be()}={}){let a=bt(t)??Ga();return Fe(e)?.documentElement?.setAttribute?.("data-theme",a),a}function We(e,{doc:t=Fe(),storage:a=Be(),eventTarget:n=Zt(),notify:r=!0}={}){let o=Zn(e);return Fe(t)?.documentElement?.setAttribute?.("data-theme",o),Be(a)?.setItem?.(za,o),r&&er(o,n),o}function Ja(e={}){let t=$e(e)==="dark"?"light":"dark";return We(t,e)}function er(e,t=Zt()){let a=Zt(t);if(typeof a?.dispatchEvent=="function"){if(typeof CustomEvent=="function"){a.dispatchEvent(new CustomEvent(ht,{detail:{theme:e}}));return}a.dispatchEvent({type:ht,detail:{theme:e}})}}var za,ht,ea,ta=_(()=>{za="mab_theme",ht="orbit:theme-change",ea=new Set(["light","dark"])});function Ve(e){return!e||!gt.has(e)?"lanes":e}var gt,yt=_(()=>{gt=new Set(["lanes","appearance","ai","notes","journal","repository","archive"])});var Va={};pt(Va,{boardLabelCatalog:()=>ra,currentBoard:()=>q,getSettingsTab:()=>na,isAiReadyState:()=>oa,selectableStatesForProject:()=>ia,state:()=>c,statesForProject:()=>Re,syncBoardSelection:()=>xe,ticketsForProject:()=>Y,upsertTicket:()=>sa,visibleStatesForProject:()=>Ee});function na(){return Ve(c.settingsTab||localStorage.getItem("mab_settings_tab"))}function xe(){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 q(){return(c.data?.boards||[]).find(e=>e.id===c.boardId)}function ra(){return c.boardId?(c.data?.labels||[]).filter(e=>e.board_id===c.boardId):[]}function Re(){return c.data.states.filter(e=>e.board_id===c.boardId)}function oa(e){return e?.role==="ai_ready"||e?.name==="AI Ready"}function Ee(){let e=Re();return q()?.ai_enabled!==0?e:e.filter(t=>!oa(t))}function ia(e=""){let t=Re();return q()?.ai_enabled!==0?t:t.filter(a=>!oa(a)||a.id===e)}function Y(){return c.data.tickets.filter(e=>e.board_id===c.boardId)}function ir(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 sr(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?ir(a.get(r.parent_ticket_id)):null,r.child_count=n.get(r.id)||0}function sa(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))),sr(n.board_id||c.boardId)}var c,U=_(()=>{yt();c={data:null,boardId:"",boardSlug:"",selectedTicketId:"",expandedCardIds:new Set,detailMode:"empty",settingsTab:Ve(localStorage.getItem("mab_settings_tab")),showPriority:localStorage.getItem("mab_show_priority")!=="false",eventSource:null}});function d(e){return String(e??"").replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}function dr(e){if(!e)return e;let t=e;for(let[a,n]of cr)t=t.split(a).join(n);return t}function X(e){return e?dr(String(e)).replace(/\r\n?/g,`
|
|
2
|
+
`):""}function ce(e){return d(X(e))}function ur(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&&!lr.has(`${n[1]}:`)?"":t}function ca(e){let t=d(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 da(e){let t=/\[([^\]\n]+)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g,a="",n=0,r;for(;r=t.exec(e);){a+=ca(e.slice(n,r.index));let o=ca(r[1]),s=ur(r[2]);a+=s?`<a href="${d(s)}" target="_blank" rel="noopener noreferrer">${o}</a>`:o,n=r.index+r[0].length}return a+=ca(e.slice(n)),a}function vt(e){let t=String(e??""),a="",n=0;for(;n<t.length;){let r=t.indexOf("`",n);if(r===-1){a+=da(t.slice(n));break}let o=t.indexOf("`",r+1);if(o===-1){a+=da(t.slice(n));break}a+=da(t.slice(n,r)),a+=`<code>${d(t.slice(r+1,o))}</code>`,n=o+1}return a}function pr(e){return`<p>${vt(e.join(`
|
|
3
3
|
`)).replaceAll(`
|
|
4
|
-
`,"<br>")}</p>`}function
|
|
5
|
-
`,"<br>");return{checked:a,html:`<input type="checkbox" disabled${a?" checked":""}> ${n}`}}function
|
|
6
|
-
`),r=[],o=null,s=null,i=()=>{r.length&&(a.push(
|
|
4
|
+
`,"<br>")}</p>`}function mr(e){let t=e.match(/^\[( |x|X)\]\s+(.*)$/);if(!t)return null;let a=t[1].toLowerCase()==="x",n=vt(t[2].trim()).replaceAll(`
|
|
5
|
+
`,"<br>");return{checked:a,html:`<input type="checkbox" disabled${a?" checked":""}> ${n}`}}function la(e){let t=X(e);if(!t.trim())return"";let a=[],n=t.split(`
|
|
6
|
+
`),r=[],o=null,s=null,i=()=>{r.length&&(a.push(pr(r)),r=[])},l=()=>{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},u=()=>{s&&(a.push(`<blockquote>${la(s.join(`
|
|
7
7
|
`))}</blockquote>`),s=null)},m=()=>{i(),l(),u()};for(let p=0;p<n.length;p+=1){let f=n[p];if(/^\s*```/.test(f)){m();let C=[];for(p+=1;p<n.length&&!/^\s*```\s*$/.test(n[p]);)C.push(n[p]),p+=1;a.push(`<pre><code>${d(C.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 b=f.match(/^\s{0,3}(#{1,6})\s+(.+?)\s*#*\s*$/);if(b){m();let C=b[1].length;a.push(`<h${C}>${
|
|
9
|
-
`,"<br>")});continue}l(),r.push(f)}return m(),a.join("")}function
|
|
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 b=f.match(/^\s{0,3}(#{1,6})\s+(.+?)\s*#*\s*$/);if(b){m();let C=b[1].length;a.push(`<h${C}>${vt(b[2])}</h${C}>`);continue}let w=f.match(/^\s{0,3}>\s?(.*)$/);if(w){i(),l(),s||(s=[]),s.push(w[1]);continue}if(s&&!f.trim()){u();continue}if(u(),!f.trim()){i(),l();continue}let $=f.match(/^\s*\d+[.)]\s+(.+)$/),P=f.match(/^\s*[-*+]\s+(.+)$/);if($||P){i();let C=$?"ol":"ul",J=($||P)[1].trim(),B=null;P&&(B=mr(J)),(!o||o.type!==C||!!o.taskList!=!!B)&&(l(),o={type:C,items:[],taskList:!!B}),B?o.items.push({html:B.html,taskClass:B.checked?"task-item task-item-done":"task-item"}):o.items.push({html:vt(J).replaceAll(`
|
|
9
|
+
`,"<br>")});continue}l(),r.push(f)}return m(),a.join("")}function Xe(e){return e?new Intl.DateTimeFormat(void 0,{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"}).format(new Date(e)):""}function Xa(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 ae(e){return`#${e.number}`}function Qe(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 De(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 Ne(e){return{0:"MAYBE",1:"LOW",2:"MED",3:"HIGH",4:"URGENT"}[Number(e)]||"MED"}function Oe(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 Za(e=[]){return e.length?`
|
|
10
10
|
<div class="labels">
|
|
11
11
|
${e.map(t=>`<span class="label" style="--label-color: ${d(t.color)}">${d(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 sr,dr,ne=_(()=>{sr=[["\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","'"]];dr=new Set(["http:","https:","mailto:","tel:"])});function fr(){return Se&&Se.isConnected||(Se=document.createElement("div"),Se.className="toast-container",document.body.append(Se)),Se}function h(e,t="info",a=4e3){let n=fr(),r=document.createElement("div");r.className=`toast toast-${t}`,r.setAttribute("role","status");let o=mr[t];r.innerHTML=`<span class="toast-icon">${o}</span><span class="toast-msg">${d(e)}</span><button class="toast-close" aria-label="Dismiss">×</button>`,r.querySelector(".toast-close").addEventListener("click",()=>la(r)),n.prepend(r),requestAnimationFrame(()=>requestAnimationFrame(()=>r.classList.add("toast-enter")));let s=setTimeout(()=>la(r),a);r.addEventListener("mouseenter",()=>clearTimeout(s)),r.addEventListener("mouseleave",()=>{let i=setTimeout(()=>la(r),1500);r.addEventListener("mouseenter",()=>clearTimeout(i),{once:!0})})}function la(e){e.classList.contains("toast-exit")||(e.classList.add("toast-exit"),e.addEventListener("animationend",()=>e.remove(),{once:!0}))}function en(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 yt(e,t){let a=0;return(...n)=>{clearTimeout(a),a=setTimeout(()=>e(...n),t)}}var mr,Se,fe=_(()=>{ne();mr={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>'},Se=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 tn({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}),s=await o.text(),i=s?JSON.parse(s):{};if(!o.ok){let l=new Error(i.error||o.statusText);throw l.payload=i,l.status=o.status,l}return i}var an=_(()=>{});var nn={};ut(nn,{api:()=>v,bootstrapPath:()=>Qe,withBoardQuery:()=>x});function Qe(){return`/api/bootstrap${c.boardId?`?board_id=${encodeURIComponent(c.boardId)}`:c.boardSlug?`?board=${encodeURIComponent(c.boardSlug)}`:""}`}function x(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 tn({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 Q=_(()=>{U();fe();an()});function pa(){ua+=1,G.hidden=!1,ke.hidden=!1,requestAnimationFrame(()=>{G.classList.add("is-open"),ke.classList.add("is-visible")})}function vt(){let e=++ua,t=G.classList.contains("is-open");G.classList.remove("is-open"),ke.classList.remove("is-visible");let a=()=>{if(ua!==e)return;G.hidden=!0,ke.hidden=!0,k.innerHTML="";let o=document.getElementById("drawerTitleBlock"),s=document.getElementById("drawerTabs");o&&(o.innerHTML=""),s&&(s.innerHTML="",s.hidden=!0),G.classList.remove("is-wide")};if(!t){a();return}let n=!1,r=()=>{n||(n=!0,a())};G.addEventListener("transitionend",r,{once:!0}),setTimeout(r,360)}function wt({eyebrow:e,title:t,titleAttrs:a,subtitleHtml:n,tabs:r,activeTab:o,onTabSelect:s,body:i,mode:l}){G.classList.toggle("is-settings",l==="settings"),G.classList.toggle("is-wide",l==="ticket"||l==="settings");let u=document.getElementById("drawerTitleBlock"),m=document.getElementById("drawerTabs"),f=` class="drawer-title drawer-title-text${a?.class?` ${a.class}`:""}"`;for(let[$,P]of Object.entries(a||{}))$!=="class"&&(f+=` ${$}="${d(String(P))}"`);let b=[];e&&b.push(`<span class="drawer-eyebrow">${d(e)}</span>`),b.push(`<h2${f}>${d(t??"")}</h2>`),n&&b.push(`<div class="drawer-subtitle">${n}</div>`),u.innerHTML=b.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="${d($.id)}" aria-selected="${$.id===o}">${d($.label)}</button>`).join(""),typeof s=="function"&&m.querySelectorAll(".drawer-tab").forEach($=>{$.addEventListener("click",()=>s($.dataset.drawerTab))})):(m.hidden=!0,m.innerHTML="");let w=document.getElementById("drawerArchiveBtn");w&&(w.hidden=c.detailMode!=="ticket"),k.innerHTML=i??""}var ua,kt=_(()=>{ie();U();ne();ua=0});function vr(e,t=Ee()){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:br.map(a=>({id:`priority:${a}`,label:Ne(a),action:"priority",value:a,checked:Number(e.priority)===a,disabled:Number(e.priority)===a}))},{id:"type",label:"Type",children:hr.map(a=>({id:`type:${a}`,label:De(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 wr({x:e,y:t,menuWidth:a,menuHeight:n,viewportWidth:r,viewportHeight:o,margin:s=fa}){let i=Math.max(s,r-a-s),l=Math.max(s,o-n-s),u=e+a+s>r?e-a:e,m=t+n+s>o?t-n:t;return{left:Math.min(Math.max(s,u),i),top:Math.min(Math.max(s,m),l)}}function kr({triggerRect:e,submenuWidth:t,submenuHeight:a,viewportWidth:n,viewportHeight:r,margin:o=fa,gap:s=gr}){let i=Math.max(o,n-t-o),l=e.right+s,u=e.left-t-s,m=l+t+o<=n,p=u>=o,f=m||!p?l:u,b=Math.max(0,r-o*2),w=Math.min(a,b),$=Math.max(o,r-w-o),P=e.top-s;return{left:Math.min(Math.max(o,f),i),top:Math.min(Math.max(o,P),$),maxHeight:b}}function St({apiClient:e=v,navigator:t=null,confirmer:a=globalThis.confirm}={}){async function n(r,o){await e(x(`/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(x(`/api/tickets/${encodeURIComponent(r.id)}/archive`),{method:"POST"}),h.error(`Archived: ${r.title||"card"}`),!0)}}}function ba(e){ha=!!e}function re({restoreFocus:e=!1}={}){de(),Ze&&(Ze.abort(),Ze=null);for(let t of tt)t.isConnected&&t.remove();tt.clear(),K&&(K.querySelectorAll(".card-action-menu-item.has-submenu").forEach(t=>{let a=Le.get(t);a?.isConnected&&a.remove(),Le.delete(t)}),K.remove(),K=null),e&&$t?.isConnected&&$t.focus({preventScroll:!0}),$t=null}function $r({ticket:e,anchor:t,x:a,y:n,handlers:r=St(),onBeforeOpen:o=null}){if(re(),!e||ha)return null;typeof o=="function"&&o(),$t=t||document.activeElement;let s=document.createElement("div");s.className="card-action-menu",s.setAttribute("role","menu"),s.setAttribute("aria-label",`Actions for #${e.number||""} ${e.title||"card"}`.trim()),s.dataset.ticketId=e.id,s.innerHTML=sn(vr(e)),document.body.append(s),K=s,s.querySelectorAll(".card-action-menu-item.has-submenu").forEach(p=>{let f=p.querySelector(":scope > .card-action-submenu");f&&(f.remove(),document.body.append(f),Le.set(p,f),ma.set(f,p),Sr(f,e,r))});let i=s.getBoundingClientRect(),l=wr({x:a,y:n,menuWidth:i.width,menuHeight:i.height,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight});s.style.left=`${l.left}px`,s.style.top=`${l.top}px`,Er(s,e,r),ya(s)?.focus({preventScroll:!0}),Ze=new AbortController;let m=Ze.signal;return requestAnimationFrame(()=>{document.addEventListener("pointerdown",Lr,{signal:m,capture:!0})}),document.addEventListener("keydown",Tr,{signal:m,capture:!0}),document.addEventListener("scroll",Ir,{signal:m,capture:!0,passive:!0}),window.addEventListener("resize",()=>re(),{signal:m,passive:!0}),window.addEventListener("blur",()=>re(),{signal:m}),s}function on(e,t,{handlers:a=St(),onBeforeOpen:n=null}={}){e.addEventListener("contextmenu",r=>{let o=r.target instanceof Element?r.target.closest(".card"):null;if(!o)return;let s=t(o.dataset.ticketId);if(s){if(r.preventDefault(),r.stopPropagation(),ha){re();return}$r({ticket:s,anchor:o,x:r.clientX,y:r.clientY,handlers:a,onBeforeOpen:n})}})}function sn(e){return`<ul class="card-action-menu-list" role="none">${e.map(xr).join("")}</ul>`}function xr(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 en(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 cr,lr,ne=_(()=>{cr=[["\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","'"]];lr=new Set(["http:","https:","mailto:","tel:"])});function hr(){return Se&&Se.isConnected||(Se=document.createElement("div"),Se.className="toast-container",document.body.append(Se)),Se}function h(e,t="info",a=4e3){let n=hr(),r=document.createElement("div");r.className=`toast toast-${t}`,r.setAttribute("role","status");let o=fr[t];r.innerHTML=`<span class="toast-icon">${o}</span><span class="toast-msg">${d(e)}</span><button class="toast-close" aria-label="Dismiss">×</button>`,r.querySelector(".toast-close").addEventListener("click",()=>ua(r)),n.prepend(r),requestAnimationFrame(()=>requestAnimationFrame(()=>r.classList.add("toast-enter")));let s=setTimeout(()=>ua(r),a);r.addEventListener("mouseenter",()=>clearTimeout(s)),r.addEventListener("mouseleave",()=>{let i=setTimeout(()=>ua(r),1500);r.addEventListener("mouseenter",()=>clearTimeout(i),{once:!0})})}function ua(e){e.classList.contains("toast-exit")||(e.classList.add("toast-exit"),e.addEventListener("animationend",()=>e.remove(),{once:!0}))}function tn(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 wt(e,t){let a=0;return(...n)=>{clearTimeout(a),a=setTimeout(()=>e(...n),t)}}var fr,Se,me=_(()=>{ne();fr={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>'},Se=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 an({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}),s=await o.text(),i=s?JSON.parse(s):{};if(!o.ok){let l=new Error(i.error||o.statusText);throw l.payload=i,l.status=o.status,l}return i}var nn=_(()=>{});var rn={};pt(rn,{api:()=>v,bootstrapPath:()=>Ze,withBoardQuery:()=>x});function Ze(){return`/api/bootstrap${c.boardId?`?board_id=${encodeURIComponent(c.boardId)}`:c.boardSlug?`?board=${encodeURIComponent(c.boardSlug)}`:""}`}function x(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 an({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 Q=_(()=>{U();me();nn()});function ma(){pa+=1,G.hidden=!1,we.hidden=!1,requestAnimationFrame(()=>{G.classList.add("is-open"),we.classList.add("is-visible")})}function kt(){let e=++pa,t=G.classList.contains("is-open");G.classList.remove("is-open"),we.classList.remove("is-visible");let a=()=>{if(pa!==e)return;G.hidden=!0,we.hidden=!0,k.innerHTML="";let o=document.getElementById("drawerTitleBlock"),s=document.getElementById("drawerTabs");o&&(o.innerHTML=""),s&&(s.innerHTML="",s.hidden=!0),G.classList.remove("is-wide")};if(!t){a();return}let n=!1,r=()=>{n||(n=!0,a())};G.addEventListener("transitionend",r,{once:!0}),setTimeout(r,360)}function $t({eyebrow:e,title:t,titleAttrs:a,subtitleHtml:n,tabs:r,activeTab:o,onTabSelect:s,body:i,mode:l}){G.classList.toggle("is-settings",l==="settings"),G.classList.toggle("is-wide",l==="ticket"||l==="settings");let u=document.getElementById("drawerTitleBlock"),m=document.getElementById("drawerTabs"),f=` class="drawer-title drawer-title-text${a?.class?` ${a.class}`:""}"`;for(let[$,P]of Object.entries(a||{}))$!=="class"&&(f+=` ${$}="${d(String(P))}"`);let b=[];e&&b.push(`<span class="drawer-eyebrow">${d(e)}</span>`),b.push(`<h2${f}>${d(t??"")}</h2>`),n&&b.push(`<div class="drawer-subtitle">${n}</div>`),u.innerHTML=b.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="${d($.id)}" aria-selected="${$.id===o}">${d($.label)}</button>`).join(""),typeof s=="function"&&m.querySelectorAll(".drawer-tab").forEach($=>{$.addEventListener("click",()=>s($.dataset.drawerTab))})):(m.hidden=!0,m.innerHTML="");let w=document.getElementById("drawerArchiveBtn");w&&(w.hidden=c.detailMode!=="ticket"),k.innerHTML=i??""}var pa,xt=_(()=>{ie();U();ne();pa=0});function wr(e,t=Ee()){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:gr.map(a=>({id:`priority:${a}`,label:Ne(a),action:"priority",value:a,checked:Number(e.priority)===a,disabled:Number(e.priority)===a}))},{id:"type",label:"Type",children:br.map(a=>({id:`type:${a}`,label:De(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 kr({x:e,y:t,menuWidth:a,menuHeight:n,viewportWidth:r,viewportHeight:o,margin:s=ha}){let i=Math.max(s,r-a-s),l=Math.max(s,o-n-s),u=e+a+s>r?e-a:e,m=t+n+s>o?t-n:t;return{left:Math.min(Math.max(s,u),i),top:Math.min(Math.max(s,m),l)}}function $r({triggerRect:e,submenuWidth:t,submenuHeight:a,viewportWidth:n,viewportHeight:r,margin:o=ha,gap:s=yr}){let i=Math.max(o,n-t-o),l=e.right+s,u=e.left-t-s,m=l+t+o<=n,p=u>=o,f=m||!p?l:u,b=Math.max(0,r-o*2),w=Math.min(a,b),$=Math.max(o,r-w-o),P=e.top-s;return{left:Math.min(Math.max(o,f),i),top:Math.min(Math.max(o,P),$),maxHeight:b}}function Tt({apiClient:e=v,navigator:t=null,confirmer:a=globalThis.confirm}={}){async function n(r,o){await e(x(`/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(x(`/api/tickets/${encodeURIComponent(r.id)}/archive`),{method:"POST"}),h.error(`Archived: ${r.title||"card"}`),!0)}}}function ga(e){ba=!!e}function re({restoreFocus:e=!1}={}){de(),et&&(et.abort(),et=null);for(let t of at)t.isConnected&&t.remove();at.clear(),K&&(K.querySelectorAll(".card-action-menu-item.has-submenu").forEach(t=>{let a=Le.get(t);a?.isConnected&&a.remove(),Le.delete(t)}),K.remove(),K=null),e&&Et?.isConnected&&Et.focus({preventScroll:!0}),Et=null}function xr({ticket:e,anchor:t,x:a,y:n,handlers:r=Tt(),onBeforeOpen:o=null}){if(re(),!e||ba)return null;typeof o=="function"&&o(),Et=t||document.activeElement;let s=document.createElement("div");s.className="card-action-menu",s.setAttribute("role","menu"),s.setAttribute("aria-label",`Actions for #${e.number||""} ${e.title||"card"}`.trim()),s.dataset.ticketId=e.id,s.innerHTML=cn(wr(e)),document.body.append(s),K=s,s.querySelectorAll(".card-action-menu-item.has-submenu").forEach(p=>{let f=p.querySelector(":scope > .card-action-submenu");f&&(f.remove(),document.body.append(f),Le.set(p,f),fa.set(f,p),Lr(f,e,r))});let i=s.getBoundingClientRect(),l=kr({x:a,y:n,menuWidth:i.width,menuHeight:i.height,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight});s.style.left=`${l.left}px`,s.style.top=`${l.top}px`,Sr(s,e,r),va(s)?.focus({preventScroll:!0}),et=new AbortController;let m=et.signal;return requestAnimationFrame(()=>{document.addEventListener("pointerdown",Tr,{signal:m,capture:!0})}),document.addEventListener("keydown",Ir,{signal:m,capture:!0}),document.addEventListener("scroll",_r,{signal:m,capture:!0,passive:!0}),window.addEventListener("resize",()=>re(),{signal:m,passive:!0}),window.addEventListener("blur",()=>re(),{signal:m}),s}function sn(e,t,{handlers:a=Tt(),onBeforeOpen:n=null}={}){e.addEventListener("contextmenu",r=>{let o=r.target instanceof Element?r.target.closest(".card"):null;if(!o)return;let s=t(o.dataset.ticketId);if(s){if(r.preventDefault(),r.stopPropagation(),ba){re();return}xr({ticket:s,anchor:o,x:r.clientX,y:r.clientY,handlers:a,onBeforeOpen:n})}})}function cn(e){return`<ul class="card-action-menu-list" role="none">${e.map(Er).join("")}</ul>`}function Er(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"
|
|
@@ -23,9 +23,9 @@ var Xn=Object.defineProperty;var _=(e,t)=>()=>(e&&(t=e(e=0)),t);var ut=(e,t)=>{f
|
|
|
23
23
|
<span class="card-action-label">${d(e.label)}</span>
|
|
24
24
|
${r}
|
|
25
25
|
</button>
|
|
26
|
-
${t?`<div class="card-action-submenu" role="menu">${
|
|
26
|
+
${t?`<div class="card-action-submenu" role="menu">${cn(e.children)}</div>`:""}
|
|
27
27
|
</li>
|
|
28
|
-
`}function
|
|
28
|
+
`}function Sr(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")?(de(),St(r)):Cr(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")?(de(),St(r)):(de(),pn(e)))}),e.addEventListener("click",n=>dn(n,e,t,a)),e.addEventListener("keydown",n=>ln(n,e))}function Lr(e,t,a){e.addEventListener("pointerenter",de),e.addEventListener("pointerover",n=>{n.target instanceof Element&&e.contains(n.target)&&de()},!0),e.addEventListener("click",n=>{K&&dn(n,K,t,a,e)}),e.addEventListener("keydown",n=>{K&&ln(n,K)})}function dn(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 s=o.closest(".card-action-menu-item");if(s?.classList.contains("has-submenu")){de(),St(s),va(Le.get(s))?.focus({preventScroll:!0});return}let i=o.dataset.action,l=o.dataset.value;if(re(),i==="open")return n.open(a);if(i==="move")return n.move(a,l);if(i==="priority")return n.priority(a,Number(l));if(i==="type")return n.type(a,l);if(i==="archive")return n.archive(a)}function ln(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"),s=a.closest(".card-action-menu-item");if(e.key==="Escape"){if(e.preventDefault(),n){let i=fa.get(n),l=i?.querySelector(":scope > .card-action-button");Lt(i),l?.focus({preventScroll:!0})}else re({restoreFocus:!0});return}if(e.key==="ArrowDown"||e.key==="ArrowUp"){e.preventDefault(),Mr(o,a,e.key==="ArrowDown"?1:-1);return}if(e.key==="Home"||e.key==="End"){e.preventDefault();let i=ya(o);i[e.key==="Home"?0:i.length-1]?.focus({preventScroll:!0});return}if(e.key==="ArrowRight"&&s?.classList.contains("has-submenu")){e.preventDefault(),de(),St(s),va(Le.get(s))?.focus({preventScroll:!0});return}if(e.key==="ArrowLeft"&&n){let i=fa.get(n),l=i?.querySelector(":scope > .card-action-button");l&&(e.preventDefault(),Lt(i),l.focus({preventScroll:!0}))}}function Tr(e){K&&(un(e)||re())}function Ir(e){e.key==="Escape"&&K&&(e.preventDefault(),re({restoreFocus:!0}))}function _r(e){K&&(un(e)||re())}function un(e){let t=e.target;if(!(t instanceof Node))return!1;if(K?.contains(t))return!0;for(let a of at)if(a.contains(t))return!0;return!1}function St(e){let t=e.parentElement?.children||[];for(let n of t)n!==e&&n.classList?.contains("has-submenu")&&n.classList.contains("is-open")&&Lt(n);let a=Le.get(e);if(a){if(e.classList.contains("is-open")){on(e,a);return}e.classList.add("is-open"),e.querySelector(":scope > .card-action-button")?.setAttribute("aria-expanded","true"),a.classList.add("is-open"),at.add(a),on(e,a)}}function Lt(e){if(!e)return;e.classList.remove("is-open"),e.querySelector(":scope > .card-action-button")?.setAttribute("aria-expanded","false");let t=Le.get(e);t&&(t.classList.remove("is-open"),t.style.removeProperty("left"),t.style.removeProperty("top"),t.style.removeProperty("max-height"),at.delete(t))}function pn(e){e.querySelectorAll(".card-action-menu-item.has-submenu.is-open").forEach(Lt)}function Cr(e){de(),tt=setTimeout(()=>{tt=null,K===e&&pn(e)},vr)}function de(){tt!=null&&(clearTimeout(tt),tt=null)}function on(e,t){let a=e.querySelector(":scope > .card-action-button");if(!t||!a)return;let n=Math.max(0,window.innerHeight-ha*2);t.style.maxHeight=`${n}px`,t.style.left="0px",t.style.top="0px";let r=t.getBoundingClientRect(),o=$r({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 ya(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 va(e){return ya(e)[0]||null}function Mr(e,t,a){let n=ya(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 br,gr,ha,yr,vr,K,ba,et,Et,Le,fa,at,tt,mn=_(()=>{Q();U();ne();me();br=["epic","feature","task","bug"],gr=[0,1,2,3,4],ha=8,yr=6,vr=180,K=null,ba=!1,et=null,Et=null,Le=new WeakMap,fa=new WeakMap,at=new Set,tt=null});function Pr(e){return e?typeof e=="string"?{readAt:e,count:0}:{readAt:e.readAt||null,count:Number(e.count)||0}:{readAt:null,count:0}}function nt(e){if(!e)return new Map;let t=ka.get(e);if(t)return t;t=new Map;try{let a=localStorage.getItem(fn(e));if(a){let n=JSON.parse(a);for(let[r,o]of Object.entries(n))t.set(r,Pr(o))}}catch{}return ka.set(e,t),t}function It(e){let t=ka.get(e);if(t)try{let a={};for(let[n,r]of t)a[n]=r;localStorage.setItem(fn(e),JSON.stringify(a))}catch{}}function hn(e,t){let a=e.get(t);return a||(a={readAt:null,count:0},e.set(t,a)),a}function _t(e){let t=e?.board_id||c.boardId;if(!t||!e?.id)return 0;let n=nt(t).get(e.id);return n?n.count:localStorage.getItem(wa(t))==="1"?1:0}function Ct(e,t){let a=c.boardId;if(!a||!e)return;let n=nt(a),r=hn(n,e);r.count===0&&r.readAt&&t&&r.readAt>=t||(r.count=0,t&&(r.readAt=t),It(a))}function bn(e){let t=c.boardId;if(!t||!e)return;let a=nt(t),n=hn(a,e);n.count=(n.count||0)+1,It(t)}function gn(e){let t=c.boardId;if(!t||!e)return;let a=nt(t);a.has(e)&&(a.delete(e),It(t))}function yn(e,t){if(!e||localStorage.getItem(wa(e))==="1")return;let a=nt(e);for(let n of t||[])!a.has(n.id)&&n.updated_at&&a.set(n.id,{readAt:n.updated_at,count:0});It(e);try{localStorage.setItem(wa(e),"1")}catch{}}var fn,wa,ka,rt=_(()=>{U();fn=e=>`mab_card_read:${e}`,wa=e=>`mab_card_read_seeded:${e}`,ka=new Map});function je(){let e=Ee(),t=Y();xa=new Map(t.map(a=>[a.id,a])),T.innerHTML=e.map(a=>Fr(a,t)).join("")}function Ar(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=xa.get(t),o=e.querySelector(".card-meta");r&&o&&o.insertAdjacentHTML("afterend",kn(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 vn(){$a=$a||Tt({navigator:A});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&&(re(),ga(!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",()=>{ga(!1),t(null),Mt=!0,setTimeout(()=>{Mt=!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&&(D(),await v(x(`/api/tickets/${r}`),{method:"PATCH",body:{state_id:n.dataset.stateId}}),await I())}),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(),At(r.dataset.addToState||"");return}let o=n.closest("button.card-expand-trigger");if(o){a.stopPropagation(),a.preventDefault(),Ar(o.closest(".card"));return}if(n.closest("a")){a.stopPropagation();return}let s=n.closest(".epic-mini-header[data-ticket-id]");if(s){D(),A({boardId:c.boardId,view:"ticket",ticketId:s.dataset.ticketId});return}let i=n.closest(".card");if(i){if(Mt){Mt=!1,a.preventDefault(),a.stopPropagation();return}D(),A({boardId:c.boardId,view:"ticket",ticketId:i.dataset.ticketId})}}),sn(T,a=>xa.get(a),{handlers:$a,onBeforeOpen:D})}function wn(){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 Br(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,7 +52,7 @@ var Xn=Object.defineProperty;var _=(e,t)=>()=>(e&&(t=e(e=0)),t);var ut=(e,t)=>{f
|
|
|
52
52
|
<div class="empty-state-title">${d(a.title)}</div>
|
|
53
53
|
<div class="empty-state-subtitle">${d(a.subtitle)}</div>
|
|
54
54
|
</div>
|
|
55
|
-
`}function
|
|
55
|
+
`}function Fr(e,t){let a=t.filter(i=>i.state_id===e.id),n=a.length===0,r=e.name==="AI Ready",o=["column","lane"];r&&o.push("column--ai-ready");let s=r?' data-accent="ai-ready"':"";return`
|
|
56
56
|
<section class="${o.join(" ")}" data-flat${s} data-state-id="${e.id}" data-state-name="${d(e.name)}">
|
|
57
57
|
<div class="column-head lane-head">
|
|
58
58
|
<h2 class="lane-title"${r?' title="Agent staging \u2014 cards here are picked up by the claim-next tool when unblocked"':""}>
|
|
@@ -63,31 +63,31 @@ var Xn=Object.defineProperty;var _=(e,t)=>()=>(e&&(t=e(e=0)),t);var ut=(e,t)=>{f
|
|
|
63
63
|
<span class="count">${a.length}</span>
|
|
64
64
|
</div>
|
|
65
65
|
</div>
|
|
66
|
-
${n?
|
|
66
|
+
${n?Br(e.name):Rr(a,t)}
|
|
67
67
|
<button type="button" class="add-card-phantom" data-add-to-state="${d(e.id)}">+ Add a card</button>
|
|
68
68
|
</section>
|
|
69
|
-
`}function
|
|
69
|
+
`}function Rr(e,t){let a=new Map(t.filter(i=>N(i.type)==="epic").map(i=>[i.id,i])),n=new Set(e.filter(i=>N(i.type)==="epic").map(i=>i.id)),r=new Map;for(let i of e)if(i.parent_ticket_id&&a.has(i.parent_ticket_id)){let l=r.get(i.parent_ticket_id)||[];l.push(i),r.set(i.parent_ticket_id,l)}let o=new Set,s=[];for(let i of e)if(!o.has(i.id)){if(N(i.type)==="epic"){let l=r.get(i.id)||[];if(l.length){let u=l.map(m=>ot(m,{asEpicChild:!0})).join("");s.push(`${ot(i)}<div class="epic-children">${u}</div>`),l.forEach(m=>o.add(m.id))}else s.push(ot(i));o.add(i.id);continue}if(!(i.parent_ticket_id&&n.has(i.parent_ticket_id))){if(i.parent_ticket_id&&a.has(i.parent_ticket_id)&&!n.has(i.parent_ticket_id)){let l=a.get(i.parent_ticket_id),u=r.get(i.parent_ticket_id)||[],m=u.map(p=>ot(p,{asEpicChild:!0})).join("");s.push(`${Dr(l)}<div class="epic-children">${m}</div>`),u.forEach(p=>o.add(p.id));continue}s.push(ot(i)),o.add(i.id)}}return s.join("")}function Dr(e){return`
|
|
70
70
|
<div class="epic-mini-header" data-ticket-id="${d(e.id)}" title="Open epic">
|
|
71
71
|
<div class="card-type-id type-pill-epic">
|
|
72
|
-
${
|
|
72
|
+
${Pt("epic")}
|
|
73
73
|
<span class="card-type-label">EPIC</span>
|
|
74
74
|
</div>
|
|
75
75
|
<span class="ticket-number">${d(ae(e))}</span>
|
|
76
76
|
<span class="epic-mini-title">${d(e.title)}</span>
|
|
77
77
|
</div>
|
|
78
|
-
`}function
|
|
78
|
+
`}function Ea(e){let t=Oe(e),a=Ne(e);return`<div class="card-priority-id priority-pill" data-variant="${d(t)}"><span class="card-priority-label">${d(a)}</span></div>`}function Pt(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
|
|
82
|
+
`}function ot(e,{asEpicChild:t=!1}={}){let a=N(e.type),n=Oe(e.priority),r=De(e.type).toUpperCase(),o=c.expandedCardIds.has(e.id),i=!!String(e.description||"").trim()||e.labels&&e.labels.length||e.parent_ticket||e.child_count,l=`
|
|
83
83
|
<span class="ticket-number">${d(ae(e))}</span>
|
|
84
84
|
<div class="card-type-id type-pill-${d(a)}">
|
|
85
|
-
${
|
|
85
|
+
${Pt(e.type)}
|
|
86
86
|
<span class="card-type-label">${d(r)}</span>
|
|
87
87
|
</div>
|
|
88
|
-
${c.showPriority?
|
|
88
|
+
${c.showPriority?Ea(e.priority):""}
|
|
89
89
|
${i?'<svg class="card-expand-chevron" viewBox="0 0 24 24" aria-hidden="true"><path d="M6 9l6 6 6-6" /></svg>':""}
|
|
90
|
-
`,u=
|
|
90
|
+
`,u=_t(e),m=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`
|
|
91
91
|
<article class="card type-${d(a)} priority-${d(n)}${o?" is-expanded":""}${t?" is-epic-child":""} ${e.id===c.selectedTicketId?"selected":""}" data-variant="${d(a)}" draggable="true" data-ticket-id="${e.id}">
|
|
92
92
|
${m}
|
|
93
93
|
<h3>${d(e.title)}</h3>
|
|
@@ -96,16 +96,16 @@ var Xn=Object.defineProperty;var _=(e,t)=>()=>(e&&(t=e(e=0)),t);var ut=(e,t)=>{f
|
|
|
96
96
|
${i?`<button type="button" class="card-expand-trigger" data-variant="card-accordion" data-card-toggle aria-expanded="${o?"true":"false"}">${l}</button>`:`<div class="card-expand-trigger card-expand-trigger--static">${l}</div>`}
|
|
97
97
|
</div>
|
|
98
98
|
|
|
99
|
-
${i&&o?
|
|
99
|
+
${i&&o?kn(e):""}
|
|
100
100
|
</article>
|
|
101
|
-
`}function
|
|
101
|
+
`}function kn(e){return`
|
|
102
102
|
<div class="card-expandable">
|
|
103
|
-
${!!String(e.description||"").trim()?`<div class="card-description markdown-body">${
|
|
104
|
-
${
|
|
103
|
+
${!!String(e.description||"").trim()?`<div class="card-description markdown-body">${la(e.description)}</div>`:""}
|
|
104
|
+
${Za(e.labels)}
|
|
105
105
|
${e.parent_ticket?`<div class="parent-line">-> ${d(ae(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
|
|
108
|
+
`}function $n(){let a=()=>Math.max(T.clientWidth,1),n=!1,r=!1,o=0,s=0,i=0,l=p=>p instanceof Element?!!(p.closest(".card")||p.closest("a, button, input, select, textarea, [draggable='true']")):!1,u=(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+=u(f,p.deltaMode))},{passive:!1}),T.addEventListener("pointerdown",p=>{p.button===0&&(l(p.target)||(n=!0,r=!1,i=p.pointerId,o=p.clientX,s=T.scrollLeft,T.classList.add("is-grabbing")))}),T.addEventListener("pointermove",p=>{if(!n||p.pointerId!==i)return;let f=p.clientX-o;if(!r&&Math.abs(f)>4){r=!0;try{T.setPointerCapture(i)}catch{}}r&&(p.preventDefault(),T.scrollLeft=s-f)});let m=p=>{if(!(!n||p&&p.pointerId!==i)){n=!1,T.classList.remove("is-grabbing");try{T.releasePointerCapture(i)}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 xa,$a,Mt,it=_(()=>{ie();U();ne();Q();he();He();fe();mn();rt();xa=new Map,$a=null,Mt=!1});var xn,Te,O,qe=_(()=>{xn="full";xn="full";Te=xn,O={sse:Te==="full",ai:Te==="full",multiBoard:Te==="full",tokenAuth:Te==="full",attachments:Te==="full"}});async function be(){let e=await v(`/api/boards/${c.boardId}/context?include_struck=true`),t=e.board,a=na(),n=[{id:"lanes",label:"Lanes"},{id:"appearance",label:"Appearance"},{id:"archive",label:"Card Archive"},{id:"notes",label:"Notes"},{id:"journal",label:"Journal"},...O.ai?[{id:"ai",label:"AI"}]:[],{id:"repository",label:"Repository"}],r=a==="ai"&&!O.ai?"lanes":a;$t({eyebrow:"SETTINGS",mode:"settings",title:t.name,tabs:n,activeTab:r,onTabSelect:async o=>{A({boardId:c.boardId,view:"settings",tab:o})},body:Nr(e,r)}),ro(e,r)}function Nr(e,t){switch(t){case"notes":return eo(e);case"lanes":return Sn();case"appearance":return to();case"ai":return O.ai?Or(e):Sn();case"journal":return ao(e);case"archive":return Wr();case"repository":default:return Vr(e)}}function Or(e){let t=e.board,a=t.ai_enabled!==0,n=a?'<div class="separator" aria-hidden="true"></div>':"",r=a?jr(t):"",o=a&&O.multiBoard?Xr(t):"",s=a?Hr(e):"";return`
|
|
109
109
|
<div class="section">
|
|
110
110
|
<label class="orbit-check" for="aiEnabledToggle">
|
|
111
111
|
<input
|
|
@@ -125,7 +125,7 @@ var Xn=Object.defineProperty;var _=(e,t)=>()=>(e&&(t=e(e=0)),t);var ut=(e,t)=>{f
|
|
|
125
125
|
${o?`${n}${o}`:""}
|
|
126
126
|
${n}
|
|
127
127
|
${s}
|
|
128
|
-
`}function
|
|
128
|
+
`}function jr(e){let t=`This project is about\u2026
|
|
129
129
|
|
|
130
130
|
How any AI agent should use this board and work in this repo.`,a=e.agent_instructions||"",n=!!a.trim(),r=n?"":"is-placeholder",o=n?ce(a):d(t);return`
|
|
131
131
|
<div class="section ai-subsection ai-context-setup">
|
|
@@ -145,7 +145,7 @@ How any AI agent should use this board and work in this repo.`,a=e.agent_instruc
|
|
|
145
145
|
>${o}</div>
|
|
146
146
|
</div>
|
|
147
147
|
</div>
|
|
148
|
-
`}function
|
|
148
|
+
`}function Hr(e){let t=Bt(),a="claude-code",n=Ur(e,t),r=Sa(a,n),o=La(t,n),s=Rt[a];return`
|
|
149
149
|
<details class="section ai-subsection mcp-setup" data-mcp-setup>
|
|
150
150
|
<summary>
|
|
151
151
|
<div class="mcp-title-row">
|
|
@@ -159,13 +159,13 @@ How any AI agent should use this board and work in this repo.`,a=e.agent_instruc
|
|
|
159
159
|
<label>
|
|
160
160
|
<span>Operating system</span>
|
|
161
161
|
<select id="mcpOsSelect" class="select-chevron-field">
|
|
162
|
-
${Object.entries(
|
|
162
|
+
${Object.entries(Ft).map(([i,l])=>`<option value="${i}" ${i===t?"selected":""}>${d(l.label)}</option>`).join("")}
|
|
163
163
|
</select>
|
|
164
164
|
</label>
|
|
165
165
|
<label>
|
|
166
166
|
<span>Agent app</span>
|
|
167
167
|
<select id="mcpClientSelect" class="select-chevron-field">
|
|
168
|
-
${Object.entries(
|
|
168
|
+
${Object.entries(Rt).map(([i,l])=>`<option value="${i}" ${i===a?"selected":""}>${d(l.label)}</option>`).join("")}
|
|
169
169
|
</select>
|
|
170
170
|
</label>
|
|
171
171
|
</div>
|
|
@@ -209,21 +209,21 @@ How any AI agent should use this board and work in this repo.`,a=e.agent_instruc
|
|
|
209
209
|
</div>
|
|
210
210
|
</div>
|
|
211
211
|
</details>
|
|
212
|
-
`}function
|
|
212
|
+
`}function Bt(){let e=String(navigator.userAgentData?.platform||navigator.platform||navigator.userAgent||"").toLowerCase();return e.includes("win")?"windows":e.includes("mac")?"macos":"linux"}function qr(e){return{serverPath:(Ft[e]||Ft.linux).serverPath}}function Ur(e,t){let a=qr(t);return{serverPath:(e.deployment||{}).mcp_server_path||a.serverPath}}function En(){return{serverPath:y("#mcpServerPathInput")?.value||""}}function Sa(e,t){if(e==="claude-code")return Jr(t);if(e==="codex")return Kr(t);if(e==="opencode")return zr(t);if(e==="vscode")return Gr(t);let a={mcpServers:{"starscape-orbit":{command:"node",args:[t.serverPath]}}};return JSON.stringify(a,null,2)}function zr(e){return JSON.stringify({$schema:"https://opencode.ai/config.json",mcp:{"starscape-orbit":{type:"local",command:["node",e.serverPath],enabled:!0}}},null,2)}function Gr(e){return JSON.stringify({servers:{starscapeOrbit:{type:"stdio",command:"node",args:[e.serverPath]}}},null,2)}function Kr(e){return`[mcp_servers.starscape-orbit]
|
|
213
213
|
command = "node"
|
|
214
|
-
args = ["${
|
|
215
|
-
enabled = true`}function
|
|
214
|
+
args = ["${Yr(e.serverPath)}"]
|
|
215
|
+
enabled = true`}function Jr(e){return["claude mcp add starscape-orbit","--","node",Tn(e.serverPath)].join(" ")}function La(e,t){return`node ${Tn(t.serverPath)}`}function Tn(e){return`"${String(e||"").replace(/"/g,'\\"')}"`}function Yr(e){return String(e||"").replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Wr(){return`
|
|
216
216
|
<p class="description">Archived cards are hidden from the kanban, search, and agent claim-next. Restore to put a card back on the board, or delete to permanently remove it.</p>
|
|
217
217
|
<div class="section">
|
|
218
218
|
<div id="archiveList" class="archive-list">Loading\u2026</div>
|
|
219
219
|
</div>
|
|
220
|
-
`}function
|
|
220
|
+
`}function Vr(e){let t=e.board;return j.boardId!==t.id&&(j.boardId=t.id,j.step="idle",j.exported=!1),`
|
|
221
221
|
${O.multiBoard?`
|
|
222
222
|
<div class="detail-head project-manual-head">
|
|
223
223
|
<div class="meta-grid">
|
|
224
224
|
<div class="meta meta--repo-path">
|
|
225
225
|
<span>Repo</span>
|
|
226
|
-
<strong>${d(
|
|
226
|
+
<strong>${d(en(t.repo_url))}</strong>
|
|
227
227
|
<span>Path</span>
|
|
228
228
|
<strong>${d(t.system_path||e.deployment?.system_path||"Not available")}</strong>
|
|
229
229
|
</div>
|
|
@@ -231,7 +231,7 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
231
231
|
</div>`:`
|
|
232
232
|
<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>`}
|
|
233
233
|
|
|
234
|
-
${O.multiBoard?
|
|
234
|
+
${O.multiBoard?Qr(t):""}
|
|
235
235
|
|
|
236
236
|
<div class="section">
|
|
237
237
|
<h3>Board Snapshot</h3>
|
|
@@ -266,8 +266,8 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
266
266
|
</div>
|
|
267
267
|
</div>
|
|
268
268
|
|
|
269
|
-
${O.multiBoard?
|
|
270
|
-
`}function
|
|
269
|
+
${O.multiBoard?Zr(t):""}
|
|
270
|
+
`}function Xr(e){let t=!!e.system_path,a=!!e.manage_helper_files;return`
|
|
271
271
|
<div class="section ai-subsection helper-files-section">
|
|
272
272
|
<div class="ai-context-title-row">
|
|
273
273
|
<span class="section-mark" aria-hidden="true">Files</span>
|
|
@@ -286,7 +286,7 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
286
286
|
<span>Generate & maintain helper files in this folder</span>
|
|
287
287
|
</label>
|
|
288
288
|
</div>
|
|
289
|
-
`}function
|
|
289
|
+
`}function Qr(e){return`
|
|
290
290
|
<div class="section board-rename-section">
|
|
291
291
|
<h3>Board Name</h3>
|
|
292
292
|
<p class="description">Rename the board display name only. The canonical URL slug stays <strong>${d(e.slug||"")}</strong>, so existing board links keep working.</p>
|
|
@@ -298,7 +298,7 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
298
298
|
<button type="submit" data-variant="secondary">Rename Board</button>
|
|
299
299
|
</form>
|
|
300
300
|
</div>
|
|
301
|
-
`}function
|
|
301
|
+
`}function Zr(e){let t=d(e.slug||"");if(j.step==="choice")return`
|
|
302
302
|
<div class="section repository-danger-zone">
|
|
303
303
|
<h3>Delete Board</h3>
|
|
304
304
|
<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>
|
|
@@ -328,7 +328,7 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
328
328
|
<p class="description">Remove this board from Orbit and delete its repo-local Orbit files. This cannot be undone without an exported snapshot.</p>
|
|
329
329
|
<button type="button" data-variant="ghost" class="danger-button" id="deleteBoardStart">Delete Board</button>
|
|
330
330
|
</div>
|
|
331
|
-
`}function
|
|
331
|
+
`}function eo(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",s=r?ce(n):d(a);return`
|
|
332
332
|
<div class="section ai-fields">
|
|
333
333
|
<div class="inline-md-field">
|
|
334
334
|
<span class="inline-md-field-label">Notes For You</span>
|
|
@@ -342,7 +342,7 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
342
342
|
>${s}</div>
|
|
343
343
|
</div>
|
|
344
344
|
</div>
|
|
345
|
-
`}function
|
|
345
|
+
`}function Sn(){return`
|
|
346
346
|
<div class="section">
|
|
347
347
|
<label class="orbit-check" for="showPriorityToggle">
|
|
348
348
|
<input
|
|
@@ -356,19 +356,19 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
356
356
|
<span class="orbit-check-label">Show priority label on cards</span>
|
|
357
357
|
</label>
|
|
358
358
|
<p class="description lanes-description">Rename, reorder, add, or remove lanes.</p>
|
|
359
|
-
${
|
|
359
|
+
${lo()}
|
|
360
360
|
<form id="laneCreateForm" class="lane-create-form">
|
|
361
361
|
<input name="name" placeholder="New lane name..." required />
|
|
362
362
|
<button type="submit" data-variant="primary">Add Lane</button>
|
|
363
363
|
</form>
|
|
364
364
|
</div>
|
|
365
|
-
`}function
|
|
365
|
+
`}function to(){let e=$e(),t=Ae(),a=ft(),n=Xt(),r=a===null?`Using browser default (${n?"reduced motion":"motion allowed"}).`:"Using your saved preference.";return`
|
|
366
366
|
<div class="section appearance-theme-section">
|
|
367
367
|
<fieldset class="appearance-theme-field">
|
|
368
368
|
<legend>Theme</legend>
|
|
369
369
|
<div class="appearance-theme-options">
|
|
370
|
-
${
|
|
371
|
-
${
|
|
370
|
+
${Ln("light","Light",e)}
|
|
371
|
+
${Ln("dark","Dark",e)}
|
|
372
372
|
</div>
|
|
373
373
|
<p class="description">Applies the light/dark theme used by the top rail toggle.</p>
|
|
374
374
|
</fieldset>
|
|
@@ -387,7 +387,7 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
387
387
|
</label>
|
|
388
388
|
<p class="description">Turns off the animated starfield, meteors, and theme animations. ${d(r)}</p>
|
|
389
389
|
</div>
|
|
390
|
-
`}function
|
|
390
|
+
`}function Ln(e,t,a){return`
|
|
391
391
|
<label class="appearance-theme-option">
|
|
392
392
|
<input type="radio" name="themePreference" value="${e}" ${a===e?"checked":""} />
|
|
393
393
|
<span class="appearance-theme-option-mark" aria-hidden="true">
|
|
@@ -405,10 +405,10 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
405
405
|
</span>
|
|
406
406
|
<span class="appearance-theme-option-label">${t}</span>
|
|
407
407
|
</label>
|
|
408
|
-
`}function
|
|
408
|
+
`}function ao(e){return`
|
|
409
409
|
${e.board?.ai_enabled!==0?'<p class="description">Agent-facing project memory: decisions to follow and lessons to apply. Struck entries stay visible here but are excluded from agent context.</p>':""}
|
|
410
410
|
<div class="section">
|
|
411
|
-
${
|
|
411
|
+
${io(e.entries)}
|
|
412
412
|
<form id="projectEntryForm" class="comment-form project-entry-form">
|
|
413
413
|
<select name="type" class="select-chevron-field" aria-label="Entry type">
|
|
414
414
|
<option value="decision">Decision</option>
|
|
@@ -419,7 +419,7 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
419
419
|
<button type="submit" data-variant="primary">Add Entry</button>
|
|
420
420
|
</form>
|
|
421
421
|
</div>
|
|
422
|
-
`}function ao(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 no(e,t){let a=e.board;if(t==="repository"){let n=async(p=!!y("#exportProjectImages")?.checked)=>{let f=p?"?include_attachments=true":"",b=await v(`/api/boards/${encodeURIComponent(a.id)}/export${f}`),w=p?`${a.slug}.with-images.orbit.json`:`${a.slug}.orbit.json`;en(w,b)};y("#exportProject")?.addEventListener("click",async()=>{await n()}),y("#boardRenameForm")?.addEventListener("submit",async p=>{p.preventDefault();let f=new FormData(p.currentTarget),b=String(f.get("name")||"").trim();!b||b===a.name||(await v(`/api/boards/${encodeURIComponent(a.id)}`,{method:"PATCH",body:{name:b}}),await I(),c.detailMode="settings",h.success(`Renamed board to ${b}. Canonical slug unchanged: ${a.slug}`))});let r=async(p,f)=>{let b=await p.text(),w=ao(b);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,b=f.files?.[0];if(b)try{let w=await r(b,C=>({snapshot:C,create_new:!0,board_id:a.id}));c.boardId=w.imported_board_id,c.boardSlug=w.imported_board_slug,c.detailMode="empty",await I(),await A({boardId:w.imported_board_id,view:"board"});let $=w.imported_counts||{},P=Number.isFinite(Number($.tickets))?` (${$.tickets} cards)`:"";h.success(w.source_format==="trello-board-export"?`Trello board imported as new board${P}`:"Board imported as new board")}catch(w){h.error(`Import failed: ${w?.message||"invalid JSON"}`)}finally{f.value=""}});let s=y("#replaceImportConfirmInput"),i=y("#replaceCurrentBoardImportFile"),l=y("#replaceCurrentBoardImportButton");s?.addEventListener("input",()=>{let p=s.value.trim()!==a.slug;i&&(i.disabled=p),l&&(l.disabled=p)}),l?.addEventListener("click",()=>{l.disabled||i?.disabled||i?.click()}),i?.addEventListener("change",async p=>{let f=p.currentTarget,b=f.files?.[0];if(b){if(s.value.trim()!==a.slug){h.error("Type the board slug before replacing this board."),f.value="";return}try{let w=await r(b,C=>({snapshot:C,replace_existing:!0,board_id:a.id}));await I(),c.detailMode="settings";let $=w.imported_counts||{},P=Number.isFinite(Number($.tickets))?` (${$.tickets} cards)`:"";h.success(w.source_format==="trello-board-export"?`Trello board replaced from Trello import${P}`:"Board replaced from snapshot")}catch(w){h.error(`Import failed: ${w?.message||"invalid JSON"}`)}finally{f.value=""}}}),y("#deleteBoardStart")?.addEventListener("click",async()=>{j.step="choice",j.exported=!1,await ge()}),y("#deleteBoardExportFirst")?.addEventListener("click",async()=>{await n(),j.step="confirm",j.exported=!0,await ge()}),y("#deleteBoardSkipExport")?.addEventListener("click",async()=>{j.step="confirm",j.exported=!1,await ge()}),y("#deleteBoardCancel")?.addEventListener("click",async()=>{j.step="idle",j.exported=!1,await ge()});let u=y("#deleteBoardConfirmInput"),m=y("#deleteBoardConfirm");u?.addEventListener("input",()=>{m&&(m.disabled=u.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}}),j.step="idle",j.exported=!1,await I(),h.success(`Deleted board: ${a.name}`),A({boardId:c.boardId,view:"board"},{replace:!0})})}if(t==="notes"){let n=k.querySelector('[data-edit-field="project_notes"]');if(n){let r=()=>Ie(n,{fieldName:"project_notes",multiline:!0,initialValue:a.project_notes||"",ariaLabel:"Edit Notes For You",rerender:async()=>{c.detailMode="settings",await ge()},commit:async o=>{await v(`/api/boards/${a.id}`,{method:"PATCH",body:{project_notes:X(o)}}),await I(),c.detailMode="settings",h.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 lo(n)})}),k.querySelectorAll(".lane-row input, .lane-row select").forEach(n=>{n.addEventListener("change",async()=>{await In(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 I(),c.detailMode="settings",h.success("Lane added")}),y("#showPriorityToggle")?.addEventListener("change",n=>{c.showPriority=!!n.currentTarget.checked,localStorage.setItem("mab_show_priority",c.showPriority?"true":"false"),je()})),t==="appearance"&&(k.querySelectorAll("input[name='themePreference']").forEach(n=>{n.addEventListener("change",r=>{if(!r.currentTarget.checked)return;let o=Zt(r.currentTarget.value);h.success(o==="dark"?"Dark theme enabled":"Light theme enabled")})}),y("#reduceMotionToggle")?.addEventListener("change",n=>{let r=!!n.currentTarget.checked;qa(r),Ye(),window.dispatchEvent(new CustomEvent("orbit:motion-preference-change",{detail:{reduce:r}})),h.success(r?"Theme motion reduced":"Theme motion enabled")})),t==="ai"){let n=()=>{let i=y("#mcpOsSelect")?.value||Pt(),l=y("#mcpClientSelect")?.value||"claude-code",u=Bt[l]||Bt.generic,m=xn(),p=Ea(l,m),f=Sa(i,m),b=k.querySelector("[data-mcp-os-note]");b&&(b.textContent=`Detected: ${At[Pt()]?.label||"Linux"}`);let w=k.querySelector("[data-mcp-client-format]");w&&(w.textContent=u.format);let $=k.querySelector("[data-mcp-output-title]");$&&($.textContent=`${u.label} setup`);let P=k.querySelector("[data-mcp-helper]");P&&(P.textContent=u.helper);let C=k.querySelector("[data-mcp-config]");C&&(C.textContent=p);let J=k.querySelector("[data-mcp-command]");J&&(J.textContent=f)};y("#mcpOsSelect")?.addEventListener("change",()=>n()),y("#mcpClientSelect")?.addEventListener("change",()=>n()),["#mcpServerPathInput"].forEach(i=>{y(i)?.addEventListener("input",()=>n())}),k.querySelectorAll("[data-copy-mcp]").forEach(i=>{i.addEventListener("click",async()=>{let l=y("#mcpOsSelect")?.value||Pt(),u=y("#mcpClientSelect")?.value||"claude-code",m=xn(),p=i.dataset.copyMcp==="command"?Sa(l,m):Ea(u,m);await ro(p),h.success(i.dataset.copyMcp==="command"?"MCP command copied":"MCP config copied")})});let r=k.querySelector('[data-edit-field="agent_instructions"]');if(r){let i=()=>Ie(r,{fieldName:"agent_instructions",multiline:!0,initialValue:a.agent_instructions||"",ariaLabel:"Edit Agent Instructions",rerender:async()=>{c.detailMode="settings",await ge()},commit:async l=>{await v(`/api/boards/${a.id}`,{method:"PATCH",body:{agent_instructions:X(l)}}),await I(),c.detailMode="settings",h.success("Saved")}});r.addEventListener("click",l=>{l.preventDefault(),i()}),r.addEventListener("keydown",l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),i())})}y("#aiEnabledToggle")?.addEventListener("change",async i=>{let l=!!i.currentTarget.checked;await v(`/api/boards/${a.id}`,{method:"PATCH",body:{ai_enabled:l}}),await I(),c.detailMode="settings",h.success(l?"AI features enabled \u2014 agent lanes provisioned":"AI features disabled \u2014 AI Ready hidden")});let o=y("#helperPickFolderBtn");o?.addEventListener("click",async()=>{o.disabled=!0;try{let i=await v("/api/system/pick-folder",{method:"POST"});if(!i.path)return;await v(`/api/boards/${encodeURIComponent(a.id)}`,{method:"PATCH",body:{system_path:i.path}}),await I(),c.detailMode="settings",h.success("Linked coding project folder updated")}catch(i){h.error(i?.message||"Folder picker unavailable")}finally{o.disabled=!1}});let s=y("#manageHelperFilesToggle");s?.addEventListener("change",async()=>{let i=s.checked;s.disabled=!0;try{await v(`/api/boards/${encodeURIComponent(a.id)}`,{method:"PATCH",body:{manage_helper_files:i}}),await I(),c.detailMode="settings",h.success(i?"Generated SKILL-ORBIT.md and AGENTS.md \u2014 Orbit will keep them in sync":"Stopped maintaining helper files (existing files left in place)")}catch(l){s.checked=!i,s.disabled=!1,h.error(l?.message||"Could not update helper files setting")}})}if(t==="archive"){let n=y("#archiveList");if(n){let r=async()=>{try{let s=(await v(`/api/boards/${encodeURIComponent(a.id)}/archive`)).tickets||[];if(s.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">${s.map(i=>Ue(i,{archive:{id:i.id},disableOpen:!0})).join("")}</div>`}catch(o){n.innerHTML=`<p class="description">Could not load archive: ${d(o?.message||"unknown error")}</p>`}};r(),n.addEventListener("click",async o=>{let s=o.target.closest("[data-archive-restore]"),i=o.target.closest("[data-archive-delete]");if(!s&&!i)return;o.stopPropagation();let u=(s||i).closest("article")?.querySelector("h3")?.textContent||"card";if(s){let m=s.dataset.archiveRestore;await v(x(`/api/tickets/${encodeURIComponent(m)}/restore`),{method:"POST"}),h.success(`Restored: ${u}`),await I(),await r();return}if(i){let m=i.dataset.archiveDelete;if(!confirm(`Permanently delete "${u}"? This cannot be undone.`))return;await v(x(`/api/tickets/${encodeURIComponent(m)}`),{method:"DELETE"}),h.success(`Deleted: ${u}`),await r()}})}}t==="journal"&&(k.querySelectorAll("[data-entry-action='toggle-struck']").forEach(n=>{n.addEventListener("click",async()=>{await v(x(`/api/board-entries/${n.dataset.entryId}`),{method:"PATCH",body:{struck:n.dataset.struck!=="true"}}),await I(),c.detailMode="settings",h.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 I(),c.detailMode="settings",h.success("Project entry added")}))}async function ro(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 oo(e=[]){return e.length?e.map(t=>{let a=!!t.struck_at;return`
|
|
422
|
+
`}function no(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 ro(e,t){let a=e.board;if(t==="repository"){let n=async(p=!!y("#exportProjectImages")?.checked)=>{let f=p?"?include_attachments=true":"",b=await v(`/api/boards/${encodeURIComponent(a.id)}/export${f}`),w=p?`${a.slug}.with-images.orbit.json`:`${a.slug}.orbit.json`;tn(w,b)};y("#exportProject")?.addEventListener("click",async()=>{await n()}),y("#boardRenameForm")?.addEventListener("submit",async p=>{p.preventDefault();let f=new FormData(p.currentTarget),b=String(f.get("name")||"").trim();!b||b===a.name||(await v(`/api/boards/${encodeURIComponent(a.id)}`,{method:"PATCH",body:{name:b}}),await I(),c.detailMode="settings",h.success(`Renamed board to ${b}. Canonical slug unchanged: ${a.slug}`))});let r=async(p,f)=>{let b=await p.text(),w=no(b);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,b=f.files?.[0];if(b)try{let w=await r(b,C=>({snapshot:C,create_new:!0,board_id:a.id}));c.boardId=w.imported_board_id,c.boardSlug=w.imported_board_slug,c.detailMode="empty",await I(),await A({boardId:w.imported_board_id,view:"board"});let $=w.imported_counts||{},P=Number.isFinite(Number($.tickets))?` (${$.tickets} cards)`:"";h.success(w.source_format==="trello-board-export"?`Trello board imported as new board${P}`:"Board imported as new board")}catch(w){h.error(`Import failed: ${w?.message||"invalid JSON"}`)}finally{f.value=""}});let s=y("#replaceImportConfirmInput"),i=y("#replaceCurrentBoardImportFile"),l=y("#replaceCurrentBoardImportButton");s?.addEventListener("input",()=>{let p=s.value.trim()!==a.slug;i&&(i.disabled=p),l&&(l.disabled=p)}),l?.addEventListener("click",()=>{l.disabled||i?.disabled||i?.click()}),i?.addEventListener("change",async p=>{let f=p.currentTarget,b=f.files?.[0];if(b){if(s.value.trim()!==a.slug){h.error("Type the board slug before replacing this board."),f.value="";return}try{let w=await r(b,C=>({snapshot:C,replace_existing:!0,board_id:a.id}));await I(),c.detailMode="settings";let $=w.imported_counts||{},P=Number.isFinite(Number($.tickets))?` (${$.tickets} cards)`:"";h.success(w.source_format==="trello-board-export"?`Trello board replaced from Trello import${P}`:"Board replaced from snapshot")}catch(w){h.error(`Import failed: ${w?.message||"invalid JSON"}`)}finally{f.value=""}}}),y("#deleteBoardStart")?.addEventListener("click",async()=>{j.step="choice",j.exported=!1,await be()}),y("#deleteBoardExportFirst")?.addEventListener("click",async()=>{await n(),j.step="confirm",j.exported=!0,await be()}),y("#deleteBoardSkipExport")?.addEventListener("click",async()=>{j.step="confirm",j.exported=!1,await be()}),y("#deleteBoardCancel")?.addEventListener("click",async()=>{j.step="idle",j.exported=!1,await be()});let u=y("#deleteBoardConfirmInput"),m=y("#deleteBoardConfirm");u?.addEventListener("input",()=>{m&&(m.disabled=u.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}}),j.step="idle",j.exported=!1,await I(),h.success(`Deleted board: ${a.name}`),A({boardId:c.boardId,view:"board"},{replace:!0})})}if(t==="notes"){let n=k.querySelector('[data-edit-field="project_notes"]');if(n){let r=()=>Ie(n,{fieldName:"project_notes",multiline:!0,initialValue:a.project_notes||"",ariaLabel:"Edit Notes For You",rerender:async()=>{c.detailMode="settings",await be()},commit:async o=>{await v(`/api/boards/${a.id}`,{method:"PATCH",body:{project_notes:X(o)}}),await I(),c.detailMode="settings",h.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 uo(n)})}),k.querySelectorAll(".lane-row input, .lane-row select").forEach(n=>{n.addEventListener("change",async()=>{await _n(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 I(),c.detailMode="settings",h.success("Lane added")}),y("#showPriorityToggle")?.addEventListener("change",n=>{c.showPriority=!!n.currentTarget.checked,localStorage.setItem("mab_show_priority",c.showPriority?"true":"false"),je()})),t==="appearance"&&(k.querySelectorAll("input[name='themePreference']").forEach(n=>{n.addEventListener("change",r=>{if(!r.currentTarget.checked)return;let o=We(r.currentTarget.value);h.success(o==="dark"?"Dark theme enabled":"Light theme enabled")})}),y("#reduceMotionToggle")?.addEventListener("change",n=>{let r=!!n.currentTarget.checked;Ua(r),Ye(),window.dispatchEvent(new CustomEvent("orbit:motion-preference-change",{detail:{reduce:r}})),h.success(r?"Theme motion reduced":"Theme motion enabled")})),t==="ai"){let n=()=>{let i=y("#mcpOsSelect")?.value||Bt(),l=y("#mcpClientSelect")?.value||"claude-code",u=Rt[l]||Rt.generic,m=En(),p=Sa(l,m),f=La(i,m),b=k.querySelector("[data-mcp-os-note]");b&&(b.textContent=`Detected: ${Ft[Bt()]?.label||"Linux"}`);let w=k.querySelector("[data-mcp-client-format]");w&&(w.textContent=u.format);let $=k.querySelector("[data-mcp-output-title]");$&&($.textContent=`${u.label} setup`);let P=k.querySelector("[data-mcp-helper]");P&&(P.textContent=u.helper);let C=k.querySelector("[data-mcp-config]");C&&(C.textContent=p);let J=k.querySelector("[data-mcp-command]");J&&(J.textContent=f)};y("#mcpOsSelect")?.addEventListener("change",()=>n()),y("#mcpClientSelect")?.addEventListener("change",()=>n()),["#mcpServerPathInput"].forEach(i=>{y(i)?.addEventListener("input",()=>n())}),k.querySelectorAll("[data-copy-mcp]").forEach(i=>{i.addEventListener("click",async()=>{let l=y("#mcpOsSelect")?.value||Bt(),u=y("#mcpClientSelect")?.value||"claude-code",m=En(),p=i.dataset.copyMcp==="command"?La(l,m):Sa(u,m);await oo(p),h.success(i.dataset.copyMcp==="command"?"MCP command copied":"MCP config copied")})});let r=k.querySelector('[data-edit-field="agent_instructions"]');if(r){let i=()=>Ie(r,{fieldName:"agent_instructions",multiline:!0,initialValue:a.agent_instructions||"",ariaLabel:"Edit Agent Instructions",rerender:async()=>{c.detailMode="settings",await be()},commit:async l=>{await v(`/api/boards/${a.id}`,{method:"PATCH",body:{agent_instructions:X(l)}}),await I(),c.detailMode="settings",h.success("Saved")}});r.addEventListener("click",l=>{l.preventDefault(),i()}),r.addEventListener("keydown",l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),i())})}y("#aiEnabledToggle")?.addEventListener("change",async i=>{let l=!!i.currentTarget.checked;await v(`/api/boards/${a.id}`,{method:"PATCH",body:{ai_enabled:l}}),await I(),c.detailMode="settings",h.success(l?"AI features enabled \u2014 agent lanes provisioned":"AI features disabled \u2014 AI Ready hidden")});let o=y("#helperPickFolderBtn");o?.addEventListener("click",async()=>{o.disabled=!0;try{let i=await v("/api/system/pick-folder",{method:"POST"});if(!i.path)return;await v(`/api/boards/${encodeURIComponent(a.id)}`,{method:"PATCH",body:{system_path:i.path}}),await I(),c.detailMode="settings",h.success("Linked coding project folder updated")}catch(i){h.error(i?.message||"Folder picker unavailable")}finally{o.disabled=!1}});let s=y("#manageHelperFilesToggle");s?.addEventListener("change",async()=>{let i=s.checked;s.disabled=!0;try{await v(`/api/boards/${encodeURIComponent(a.id)}`,{method:"PATCH",body:{manage_helper_files:i}}),await I(),c.detailMode="settings",h.success(i?"Generated SKILL-ORBIT.md and AGENTS.md \u2014 Orbit will keep them in sync":"Stopped maintaining helper files (existing files left in place)")}catch(l){s.checked=!i,s.disabled=!1,h.error(l?.message||"Could not update helper files setting")}})}if(t==="archive"){let n=y("#archiveList");if(n){let r=async()=>{try{let s=(await v(`/api/boards/${encodeURIComponent(a.id)}/archive`)).tickets||[];if(s.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">${s.map(i=>Ue(i,{archive:{id:i.id},disableOpen:!0})).join("")}</div>`}catch(o){n.innerHTML=`<p class="description">Could not load archive: ${d(o?.message||"unknown error")}</p>`}};r(),n.addEventListener("click",async o=>{let s=o.target.closest("[data-archive-restore]"),i=o.target.closest("[data-archive-delete]");if(!s&&!i)return;o.stopPropagation();let u=(s||i).closest("article")?.querySelector("h3")?.textContent||"card";if(s){let m=s.dataset.archiveRestore;await v(x(`/api/tickets/${encodeURIComponent(m)}/restore`),{method:"POST"}),h.success(`Restored: ${u}`),await I(),await r();return}if(i){let m=i.dataset.archiveDelete;if(!confirm(`Permanently delete "${u}"? This cannot be undone.`))return;await v(x(`/api/tickets/${encodeURIComponent(m)}`),{method:"DELETE"}),h.success(`Deleted: ${u}`),await r()}})}}t==="journal"&&(k.querySelectorAll("[data-entry-action='toggle-struck']").forEach(n=>{n.addEventListener("click",async()=>{await v(x(`/api/board-entries/${n.dataset.entryId}`),{method:"PATCH",body:{struck:n.dataset.struck!=="true"}}),await I(),c.detailMode="settings",h.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 I(),c.detailMode="settings",h.success("Project entry added")}))}async function oo(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 io(e=[]){return e.length?e.map(t=>{let a=!!t.struck_at;return`
|
|
423
423
|
<div class="comment project-entry ${d(t.type)} ${a?"is-struck":""}">
|
|
424
424
|
<div class="comment-meta">
|
|
425
425
|
<div>
|
|
@@ -427,7 +427,7 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
427
427
|
${a?'<span class="project-entry-status">Excluded from agent context</span>':""}
|
|
428
428
|
</div>
|
|
429
429
|
<div class="project-entry-actions">
|
|
430
|
-
<span>${d(t.created_by)} - ${
|
|
430
|
+
<span>${d(t.created_by)} - ${Xe(t.created_at)}</span>
|
|
431
431
|
<button
|
|
432
432
|
type="button"
|
|
433
433
|
data-variant="ghost"
|
|
@@ -441,7 +441,7 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
441
441
|
</div>
|
|
442
442
|
<div class="comment-body">${d(t.body)}</div>
|
|
443
443
|
</div>
|
|
444
|
-
`}).join(""):'<p class="description">No project entries yet.</p>'}function
|
|
444
|
+
`}).join(""):'<p class="description">No project entries yet.</p>'}function so(e,t,a){return!!(t.get(e.id)||e.is_default||In.has(e.role)||a&&e.role==="ai_ready")}function co(e,t,a){let n=t.get(e.id)||0;return n>0?`Cannot delete \u2014 ${n} card${n===1?"":"s"} in this lane`:e.is_default?"Cannot delete \u2014 default lane for new cards (move it first)":In.has(e.role)?"Cannot delete \u2014 core kanban lane":a&&e.role==="ai_ready"?"Cannot delete \u2014 required by agent flow while AI is enabled":"Delete lane"}function lo(){let e=Re(),t=q()?.ai_enabled!==0,a=new Map;for(let n of Y())a.set(n.state_id,(a.get(n.state_id)||0)+1);return`
|
|
445
445
|
<div class="lane-list">
|
|
446
446
|
${e.map((n,r)=>{let o=n.role==="ai_ready",s=o?"AI Ready lane name is locked \u2014 disable AI to hide this column":"";return`
|
|
447
447
|
<div class="lane-row${o?" lane-row--locked":""}" data-lane-id="${n.id}">
|
|
@@ -452,25 +452,25 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
452
452
|
<span class="lane-new-sun" aria-hidden="true"></span>
|
|
453
453
|
<span class="lane-new-label">New</span>
|
|
454
454
|
</button>
|
|
455
|
-
<button type="button" data-variant="ghost" class="settings-lane-delete-btn danger-button" data-lane-action="delete" ${
|
|
455
|
+
<button type="button" data-variant="ghost" class="settings-lane-delete-btn danger-button" data-lane-action="delete" ${so(n,a,t)?"disabled":""} title="${co(n,a,t)}" aria-label="Delete lane">\xD7</button>
|
|
456
456
|
</div>
|
|
457
457
|
`}).join("")}
|
|
458
458
|
</div>
|
|
459
|
-
`}async function
|
|
460
|
-
`).length+1);let E=e.getBoundingClientRect().height;Number.isFinite(E)&&E>0&&(b.style.minHeight=`${Math.ceil(E)}px`)}if(e.replaceWith(b),
|
|
459
|
+
`}async function uo(e){let t=e.closest(".lane-row"),a=t.dataset.laneId,n=e.dataset.laneAction;if(n==="delete"){await v(x(`/api/states/${a}`),{method:"DELETE"}),await I(),c.detailMode="settings",h.success("Lane deleted");return}if(n==="toggle-default"){if(e.getAttribute("aria-pressed")==="true")return;k.querySelectorAll('[data-lane-action="toggle-default"]').forEach(l=>{l.setAttribute("aria-pressed","false"),l.setAttribute("data-variant","ghost"),l.classList.remove("is-on")}),e.setAttribute("aria-pressed","true"),e.setAttribute("data-variant","secondary"),e.classList.add("is-on"),await _n(t,{silent:!0}),h.success("Default lane updated");return}let r=Re().map(i=>i.id),o=r.indexOf(a),s=n==="up"?o-1:o+1;s<0||s>=r.length||([r[o],r[s]]=[r[s],r[o]],await v(`/api/boards/${c.boardId}/states`,{method:"PATCH",body:{state_ids:r}}),await I(),c.detailMode="settings",h.success("Lanes reordered"))}async function _n(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(x(`/api/states/${e.dataset.laneId}`),{method:"PATCH",body:{name:a,is_default:r}}),await I(),c.detailMode="settings",t||h.success("Lane updated")}var j,Ft,Rt,In,Cn=_(()=>{U();ie();ne();Q();me();xt();he();it();Dt();fe();qe();Qt();ta();j={boardId:"",step:"idle",exported:!1};Ft={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"}},Rt={"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."},vscode:{label:"VS Code",format:"mcp.json",helper:"Paste this JSON into VS Code's user or workspace MCP configuration."},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."}};In=new Set(["in_progress","review"])});function _e(e){return String(e||"").trim()}function Ia(e){let t=_e(e);return t?t.replace(/^@+/,"").replace(/[-_]+/g," ").replace(/\s+/g," ").trim().replace(/\b\w/g,a=>a.toUpperCase()):""}function Pn({actor:e,actorId:t}={}){let a=_e(e),n=_e(t),r=a.toLowerCase(),o=n.toLowerCase();return a&&!Ta.has(r)&&!Mn.has(r)?Ia(a):n&&!Ta.has(o)&&!Mn.has(o)?Ia(n):""}function _a({actor:e,actorType:t,actorId:a}={}){let n=_e(t).toLowerCase(),r=_e(e),o=r.toLowerCase();if(n==="agent"){let s=Pn({actor:r,actorId:a});return s?`Agent \xB7 ${s}`:"Agent"}return!r||Ta.has(o)?"You":Ia(r)}function An(e={}){let t=_e(e.kind).toLowerCase(),a=_e(e.author);if(po.has(t)||t&&t!=="human_comment"){let r=Pn({actor:a});return r?`Agent \xB7 ${r}`:"Agent"}return _a({actor:a,actorType:"human"})}var Ta,Mn,po,Bn=_(()=>{Ta=new Set(["local","local-owner","owner"]),Mn=new Set(["agent","local-agent","orbit-agent"]),po=new Set(["agent_note","checkpoint","completion"])});var Dn={};pt(Dn,{renderDetail:()=>ye,renderDetailCard:()=>Ue,renderInlinePreservedTextField:()=>Nt,startInlineEdit:()=>Ie});async function le(e,{renderBoardAfter:t=!1}={}){let[a,n,r]=await Promise.all([v(x(`/api/tickets/${e}/context?depth=1`)),v(x(`/api/tickets/${e}/history`)),v(x(`/api/tickets/${e}/comments`))]);a.ticket?.id===e&&(sa(a.ticket),t&&je(),!(c.detailMode!=="ticket"||c.selectedTicketId!==e)&&await ye({context:a,statusHistory:n,comments:r.comments||[]}))}async function ge(e,t){await v(x(`/api/tickets/${e}`),{method:"PATCH",body:t}),await le(e,{renderBoardAfter:!0})}function mo(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 fo(e){let t=e?.closest?.(".drawer-inner");return t?{scrollContainer:t,nodeRect:e.getBoundingClientRect(),scrollTop:t.scrollTop}:null}function ho(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 bo(e){try{e.focus({preventScroll:!0})}catch{e.focus()}}function Ie(e,t){if(!e||e.dataset.editing==="true")return;let{fieldName:a,multiline:n=!0,initialValue:r="",ariaLabel:o,emptyMessage:s,sourceEvent:i,rerender:l,commit:u}=t,m=n?fo(e):null,p=String(r),f=n?mo(e,i,p.length):null;e.dataset.editing="true";let b=document.createElement(n?"textarea":"input");if(b.className=n?"inline-desc-editor":"inline-title-editor",b.value=p,a&&b.setAttribute("data-editing-field",a),o&&b.setAttribute("aria-label",o),!n)b.type="text",b.maxLength=500,b.autocomplete="off",b.spellcheck=!0;else{b.rows=Math.max(3,p.split(`
|
|
460
|
+
`).length+1);let E=e.getBoundingClientRect().height;Number.isFinite(E)&&E>0&&(b.style.minHeight=`${Math.ceil(E)}px`)}if(e.replaceWith(b),bo(b),!n)b.select();else{let E=f??0;b.setSelectionRange(E,E),ho(m,b)}let w=!1,$=()=>{document.removeEventListener("pointerdown",J,!0)},P=()=>{b.isConnected&&b.replaceWith(e),delete e.dataset.editing},C=()=>{w=!0,$(),P()};function J(E){w||E.target===b||b.contains(E.target)||b.blur()}document.addEventListener("pointerdown",J,!0);let B=async()=>{if(w)return;let E=n?b.value:b.value.trim();if(C(),String(E)===String(r)){l&&await l();return}if(s&&!E.trim()){h.warning(s),l&&await l();return}u&&await u(E)},S=async()=>{w||(C(),l&&await l())};b.addEventListener("blur",B),b.addEventListener("keydown",E=>{if(E.key==="Escape"){E.preventDefault(),S();return}E.key==="Enter"&&(n?(E.metaKey||E.ctrlKey)&&(E.preventDefault(),B()):(E.preventDefault(),B()))})}function go(e){let t=e.id,a=()=>Ie(n,{fieldName:"title",multiline:!1,initialValue:e.title||"",ariaLabel:"Edit ticket title",emptyMessage:"Title cannot be empty",rerender:()=>ye(),commit:u=>ge(t,{title:u})}),n=G.querySelector('[data-edit-field="title"]');n&&(n.addEventListener("click",a),n.addEventListener("keydown",u=>{(u.key==="Enter"||u.key===" ")&&(u.preventDefault(),a())}));let r=k.querySelector('[data-edit-field="description"]'),o=u=>Ie(r,{fieldName:"description",multiline:!0,initialValue:e.description||"",ariaLabel:"Edit ticket description",sourceEvent:u,rerender:()=>ye(),commit:m=>ge(t,{description:X(m)})});r&&(r.addEventListener("click",u=>{u.preventDefault(),o(u)}),r.addEventListener("keydown",u=>{(u.key==="Enter"||u.key===" ")&&(u.preventDefault(),o())}));let s=[{key:"ai_plan",label:"AI plan"},{key:"implementation_summary",label:"Implementation summary"},{key:"implementation_updates",label:"Implementation updates / lessons"}];for(let{key:u,label:m}of s){let p=k.querySelector(`[data-edit-field="${u}"]`);if(!p)continue;let f=b=>Ie(p,{fieldName:u,multiline:!0,initialValue:e[u]||"",ariaLabel:`Edit ${m}`,sourceEvent:b,rerender:()=>ye(),commit:w=>ge(t,{[u]:X(w)})});p.addEventListener("click",b=>{b.preventDefault(),f(b)}),p.addEventListener("keydown",b=>{(b.key==="Enter"||b.key===" ")&&(b.preventDefault(),f())})}G.querySelectorAll(".meta-select[data-meta-field]").forEach(u=>{u.addEventListener("change",async()=>{let m=u.dataset.metaField;if(m==="type"){await ge(t,{type:u.value});return}if(m==="state_id"){await ge(t,{state_id:u.value});return}if(m==="parent_ticket_id"){await ge(t,{parent_ticket_id:u.value||null});return}m==="priority"&&await ge(t,{priority:Number(u.value)})})});let i=async u=>{await ge(t,{labels:u})};k.querySelectorAll("[data-remove-label]").forEach(u=>{u.addEventListener("click",async()=>{let m=u.getAttribute("data-remove-label"),p=(e.labels||[]).map(f=>f.name).filter(f=>f!==m);await i(p)})});let l=async()=>{let u=k.querySelector("[data-label-input]");if(!u)return;let m=u.value.trim();if(!m)return;let p=(e.labels||[]).map(f=>f.name);if(p.includes(m)){u.value="";return}p.push(m),u.value="",await i(p)};k.querySelector("[data-label-add]")?.addEventListener("click",()=>{l()}),k.querySelector("[data-label-input]")?.addEventListener("keydown",u=>{u.key==="Enter"&&(u.preventDefault(),l())})}async function ye(e={}){if(c.detailMode==="settings"){await be(),ma();return}if(!c.selectedTicketId){kt();return}let t=c.selectedTicketId,a=g=>Object.prototype.hasOwnProperty.call(e,g),[n,r,o,s]=await Promise.all([a("context")?Promise.resolve(e.context):v(x(`/api/tickets/${t}/context?depth=1`)),a("statusHistory")?Promise.resolve(e.statusHistory):v(x(`/api/tickets/${t}/history`)),a("comments")?Promise.resolve(e.comments):v(x(`/api/tickets/${t}/comments`)).then(g=>g.comments||[]),a("attachmentList")?Promise.resolve(e.attachmentList):O.attachments?v(x(`/api/tickets/${t}/attachments`)).catch(()=>({attachments:[]})):Promise.resolve({attachments:[]})]);if(c.detailMode!=="ticket"||c.selectedTicketId!==t||n.ticket?.id!==t)return;let i=n.ticket;Ct(i.id,i.updated_at),document.querySelector(`.card[data-ticket-id="${CSS.escape(i.id)}"] .card-unread-dot`)?.remove();let l=ia(i.state_id),u=["epic","feature","task","bug"].map(g=>`<option value="${d(g)}" ${N(i.type)===g?"selected":""}>${d(Qa(g))}</option>`).join(""),m=l.map(g=>`<option value="${d(g.id)}" ${g.id===i.state_id?"selected":""}>${d(g.name)}</option>`).join(""),p=[0,1,2,3,4].map(g=>`<option value="${g}" ${Number(i.priority)===g?"selected":""}>${d(Ne(g))}</option>`).join(""),f=(i.labels||[]).map(g=>`
|
|
461
461
|
<span class="label-pill-removable" style="--label-color: ${d(g.color)}">
|
|
462
462
|
${d(g.name)}
|
|
463
463
|
<button type="button" class="label-pill-remove" data-remove-label="${d(g.name)}" title="Remove label">\xD7</button>
|
|
464
|
-
</span>`).join(""),w=
|
|
464
|
+
</span>`).join(""),w=ra().map(g=>g.name).filter(g=>!i.labels?.some(M=>M.name===g)).map(g=>`<option value="${d(g)}"></option>`).join(""),$=N(i.type),P=Oe(i.priority),C=l.find(g=>g.id===i.state_id),J=Qe(C),B=i.description?ce(i.description):d("No description yet."),S=i.description?"description preserved-text-body editable-field":"description editable-field is-placeholder",E=`
|
|
465
465
|
<span class="ticket-number">${d(ae(i))}</span>
|
|
466
466
|
<div class="detail-meta-badge-row" aria-label="Ticket metadata controls">
|
|
467
467
|
<select class="detail-meta-badge detail-state-badge meta-select" data-variant="${d(J)}" data-meta-field="state_id" aria-label="Ticket state">${m}</select>
|
|
468
468
|
<select class="detail-meta-badge detail-type-badge type-pill-${d($)} meta-select" data-meta-field="type" aria-label="Ticket type">${u}</select>
|
|
469
469
|
<select class="detail-meta-badge detail-priority-badge priority-pill meta-select" data-variant="${d(P)}" data-meta-field="priority" aria-label="Ticket priority">${p}</select>
|
|
470
470
|
</div>
|
|
471
|
-
|
|
471
|
+
`;$t({mode:"ticket",title:i.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:E,body:`
|
|
472
472
|
<div class="detail-head">
|
|
473
|
-
<p class="detail-updated" title="Last saved change">Updated ${d(
|
|
473
|
+
<p class="detail-updated" title="Last saved change">Updated ${d(Xa(i.updated_at))}</p>
|
|
474
474
|
<div class="${S}" data-edit-field="description" tabindex="0" title="Click to edit">${B}</div>
|
|
475
475
|
<dl class="ticket-meta" id="ticketMetaGrid" data-ticket-id="${d(i.id)}">
|
|
476
476
|
<div class="ticket-meta-row ticket-meta-row--stack">
|
|
@@ -487,41 +487,41 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
487
487
|
</dl>
|
|
488
488
|
</div>
|
|
489
489
|
|
|
490
|
-
${
|
|
490
|
+
${To(i,n)}
|
|
491
491
|
|
|
492
|
-
${O.attachments?
|
|
492
|
+
${O.attachments?vo(i,s.attachments||[]):""}
|
|
493
493
|
|
|
494
|
-
${
|
|
494
|
+
${Io(i,n)}
|
|
495
495
|
|
|
496
496
|
<div class="section">
|
|
497
497
|
<h3>Related</h3>
|
|
498
|
-
${
|
|
498
|
+
${Lo(n.relations,i)}
|
|
499
499
|
</div>
|
|
500
500
|
|
|
501
501
|
${q()?.ai_enabled!==0?`
|
|
502
|
-
<details class="section ai-fields" data-ai-plan-toggle data-ticket-id="${d(i.id)}"${
|
|
502
|
+
<details class="section ai-fields" data-ai-plan-toggle data-ticket-id="${d(i.id)}"${yo(i.id)?" open":""}>
|
|
503
503
|
<summary><h3>AI Plan / Implementation Record</h3></summary>
|
|
504
504
|
<div class="ai-fields-grid">
|
|
505
|
-
${
|
|
506
|
-
${
|
|
507
|
-
${
|
|
505
|
+
${Nt({fieldName:"ai_plan",label:"AI-Written Plan",value:i.ai_plan,placeholder:"Paste or let an AI write the plan..."})}
|
|
506
|
+
${Nt({fieldName:"implementation_summary",label:"Implementation Summary",value:i.implementation_summary,placeholder:"What changed, what shipped, what remains..."})}
|
|
507
|
+
${Nt({fieldName:"implementation_updates",label:"Implementation Updates / Lessons",value:i.implementation_updates,placeholder:"Progress notes, mistakes to avoid, discoveries..."})}
|
|
508
508
|
</div>
|
|
509
509
|
</details>`:""}
|
|
510
510
|
|
|
511
511
|
<div class="section">
|
|
512
512
|
<h3>Status History</h3>
|
|
513
|
-
${
|
|
513
|
+
${Eo(r)}
|
|
514
514
|
</div>
|
|
515
515
|
|
|
516
516
|
<div class="section">
|
|
517
517
|
<h3>Comments</h3>
|
|
518
|
-
${o.map(
|
|
518
|
+
${o.map(So).join("")||'<p class="description">No comments yet.</p>'}
|
|
519
519
|
<form class="comment-form" id="detailCommentForm">
|
|
520
520
|
<textarea name="body" placeholder="Add a comment, decision, or instruction..." required></textarea>
|
|
521
521
|
<button type="submit">Comment</button>
|
|
522
522
|
</form>
|
|
523
523
|
</div>
|
|
524
|
-
`}),
|
|
524
|
+
`}),go(i),O.attachments&&$o(i),y("#detailCommentForm").addEventListener("submit",async g=>{g.preventDefault();let M=X(new FormData(g.currentTarget).get("body")).trim();M&&(await v(x(`/api/tickets/${i.id}/comments`),{method:"POST",body:{body:M}}),await le(i.id))}),k.querySelectorAll("[data-open-ticket]").forEach(g=>{g.addEventListener("click",async M=>{M.target.closest("[data-detach-child],[data-detach-parent],[data-detach-relation]")||A({boardId:c.boardId,view:"ticket",ticketId:g.dataset.openTicket})})}),k.querySelectorAll("[data-detach-child]").forEach(g=>{g.addEventListener("click",async M=>{M.stopPropagation();let R=g.dataset.detachChild;try{await v(x(`/api/tickets/${R}`),{method:"PATCH",body:{parent_ticket_id:null}})}catch(z){h.error(z.message||"Failed to remove child");return}await le(i.id,{renderBoardAfter:!0}),h.success("Removed from epic")})}),k.querySelectorAll("[data-detach-parent]").forEach(g=>{g.addEventListener("click",async M=>{M.stopPropagation();try{await v(x(`/api/tickets/${i.id}`),{method:"PATCH",body:{parent_ticket_id:null}})}catch(R){h.error(R.message||"Failed to remove parent");return}await le(i.id,{renderBoardAfter:!0}),h.success("Parent epic removed")})}),k.querySelectorAll("[data-detach-relation]").forEach(g=>{g.addEventListener("click",async M=>{M.stopPropagation();let R=g.dataset.detachRelation;try{await v(x(`/api/relations/${R}`),{method:"DELETE"})}catch(z){h.error(z.message||"Failed to remove relation");return}await le(i.id),h.success("Relation removed")})});let F=k.querySelector("[data-ai-plan-toggle]");F&&F.addEventListener("toggle",()=>{let g=F.dataset.ticketId;F.open?localStorage.setItem(`mab_ai_plan_open:${g}`,"1"):localStorage.removeItem(`mab_ai_plan_open:${g}`)});let H=k.querySelector("#parentEpicForm");if(H){let g=H.querySelector("[name=target]"),M=H.querySelector("[data-parent-epic-clear]"),R=()=>{H.classList.toggle("has-value",g.value.length>0)};g.addEventListener("input",R),R(),M.addEventListener("click",()=>{g.value="",R(),g.focus()}),H.addEventListener("submit",async z=>{z.preventDefault();let ee=String(new FormData(z.currentTarget).get("target")||"").trim();if(!ee)return;let W=Fn(ee,i.id);if(!W){h.warning("Pick an epic from the suggestions");return}let oe=Y().find(V=>V.id===W);if(!oe||N(oe.type)!=="epic"){h.warning("Parent must be an epic");return}try{await v(x(`/api/tickets/${i.id}`),{method:"PATCH",body:{parent_ticket_id:W}})}catch(V){h.error(V.message||"Failed to set parent epic");return}await le(i.id,{renderBoardAfter:!0}),h.success("Parent epic set")})}let L=k.querySelector("#relatedAddForm");if(L){let g=L.querySelector("[name=target]"),M=L.querySelector("[data-related-clear]"),R=()=>{L.classList.toggle("has-value",g.value.length>0)};g.addEventListener("input",R),R(),M.addEventListener("click",()=>{g.value="",R(),g.focus()}),L.addEventListener("submit",async z=>{z.preventDefault();let ee=new FormData(z.currentTarget),W=String(ee.get("target")||"").trim(),oe=String(ee.get("type")||"relates_to");if(!W)return;let V=Fn(W,i.id);if(!V){h.warning("Pick a ticket from the suggestions");return}try{await v(x("/api/relations"),{method:"POST",body:{source_ticket_id:i.id,target_ticket_id:V,type:oe}})}catch(Ce){h.error(Ce.message||"Failed to add relation");return}await le(i.id)})}ma()}function yo(e){return localStorage.getItem(`mab_ai_plan_open:${e}`)==="1"}function vo(e,t=[]){let a=t.length?`<div class="attachment-grid">${t.map(n=>wo(e,n)).join("")}</div>`:'<p class="description">No images attached yet.</p>';return`
|
|
525
525
|
<div class="section attachments-section" data-attachment-section data-ticket-id="${d(e.id)}">
|
|
526
526
|
<div class="attachment-heading-row">
|
|
527
527
|
<h3>Images</h3>
|
|
@@ -536,7 +536,7 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
536
536
|
</div>
|
|
537
537
|
${a}
|
|
538
538
|
</div>
|
|
539
|
-
`}function
|
|
539
|
+
`}function wo(e,t){let a=d(t.original_name||"image"),n=`${ko(t.size_bytes)} \xB7 ${d(t.mime_type||"image")}`;if(t.missing)return`
|
|
540
540
|
<article class="attachment-card is-missing">
|
|
541
541
|
<div class="attachment-missing-thumb">Missing</div>
|
|
542
542
|
<div class="attachment-card-meta"><strong>${a}</strong><span>${n}</span></div>
|
|
@@ -550,26 +550,26 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
550
550
|
<div class="attachment-card-meta"><strong>${a}</strong><span>${n}</span></div>
|
|
551
551
|
<button type="button" class="attachment-delete" data-delete-attachment="${d(t.id)}" aria-label="Remove image">\xD7</button>
|
|
552
552
|
</article>
|
|
553
|
-
`}function
|
|
553
|
+
`}function ko(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 Rn(e){return[...e||[]].filter(t=>t&&String(t.type||"").startsWith("image/"))}async function Ca(e,t){let a=Rn(t);if(!a.length){h.warning("No image files found");return}for(let n of a){let r=await fetch(x(`/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 le(e.id),h.success(a.length===1?"Image attached":`${a.length} images attached`)}function $o(e){let t=k.querySelector("[data-attachment-section]");if(!t)return;let a=t.querySelector("[data-attachment-input]");a?.addEventListener("change",async()=>{try{await Ca(e,a.files),a.value=""}catch(r){h.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 Ca(e,r.dataTransfer?.files||[])}catch(o){h.error(o.message||"Upload failed")}}),k.onpaste=async r=>{if(r.target.closest("input, textarea, [contenteditable='true']"))return;let o=Rn(r.clipboardData?.files||[]);if(o.length){r.preventDefault();try{await Ca(e,o)}catch(s){h.error(s.message||"Paste upload failed")}}},t.querySelectorAll("[data-delete-attachment]").forEach(r=>{r.addEventListener("click",async()=>{try{await v(x(`/api/tickets/${e.id}/attachments/${r.dataset.deleteAttachment}`),{method:"DELETE"}),await le(e.id),h.success("Image removed")}catch(o){h.error(o.message||"Delete failed")}})}),t.querySelectorAll("[data-open-lightbox]").forEach(r=>{r.addEventListener("click",()=>xo(r.dataset.openLightbox,r.dataset.lightboxTitle||"Image"))})}function xo(e,t){document.querySelector(".attachment-lightbox")?.remove();let n=document.createElement("div");n.className="attachment-lightbox",n.innerHTML=`
|
|
554
554
|
<div class="attachment-lightbox-panel" role="dialog" aria-modal="true" aria-label="${d(t)}">
|
|
555
555
|
<button type="button" class="attachment-lightbox-close" aria-label="Close image">\xD7</button>
|
|
556
556
|
<img src="${d(e)}" alt="${d(t)}" />
|
|
557
557
|
<p>${d(t)}</p>
|
|
558
558
|
</div>
|
|
559
|
-
`;let r=()=>{document.removeEventListener("keydown",o),n.remove()};function o(s){s.key==="Escape"&&r()}n.addEventListener("click",s=>{(s.target===n||s.target.closest(".attachment-lightbox-close"))&&r()}),document.addEventListener("keydown",o),document.body.append(n)}function
|
|
559
|
+
`;let r=()=>{document.removeEventListener("keydown",o),n.remove()};function o(s){s.key==="Escape"&&r()}n.addEventListener("click",s=>{(s.target===n||s.target.closest(".attachment-lightbox-close"))&&r()}),document.addEventListener("keydown",o),document.body.append(n)}function Fn(e,t){let a=e.trim(),n=a.match(/^#?(\d+)\b/),r=Y().filter(s=>s.id!==t);if(n){let s=Number(n[1]),i=r.find(l=>l.number===s);if(i)return i.id}let o=r.find(s=>`#${s.number} \u2014 ${s.title}`===a);return o?o.id:""}function Eo(e){return!e||e.length===0?'<p class="description">No status changes yet.</p>':e.map(t=>{let a=t.body,n=a.from?d(a.from):"?",r=d(a.to||a.state||a.next_state||"?"),o=d(_a({actor:t.actor,actorType:a.actor_type||"human",actorId:a.actor_id}));return`<div class="comment status-change">
|
|
560
560
|
<div class="comment-meta">
|
|
561
561
|
<span class="status-route">${n} \u2192 ${r}</span>
|
|
562
|
-
<span>${o} \xB7 ${
|
|
562
|
+
<span>${o} \xB7 ${Xe(t.created_at)}</span>
|
|
563
563
|
</div>
|
|
564
|
-
</div>`}).join("")}function
|
|
564
|
+
</div>`}).join("")}function So(e){return`
|
|
565
565
|
<div class="comment ${e.kind==="checkpoint"?"checkpoint":""}">
|
|
566
566
|
<div class="comment-meta">
|
|
567
|
-
<strong>${d(
|
|
568
|
-
<span>${e.kind==="human_comment"?"":`${d(e.kind)} - `}${
|
|
567
|
+
<strong>${d(An(e))}</strong>
|
|
568
|
+
<span>${e.kind==="human_comment"?"":`${d(e.kind)} - `}${Xe(e.created_at)}</span>
|
|
569
569
|
</div>
|
|
570
570
|
<div class="comment-body preserved-text-body">${ce(e.body)}</div>
|
|
571
571
|
</div>
|
|
572
|
-
`}function
|
|
572
|
+
`}function Nt({fieldName:e,label:t,value:a,placeholder:n}){let r=a||"",o=!!r.trim(),s=o?ce(r):d(n||""),i=o?"":"is-placeholder";return`
|
|
573
573
|
<div class="inline-md-field">
|
|
574
574
|
<span class="inline-md-field-label">${d(t)}</span>
|
|
575
575
|
<div
|
|
@@ -581,7 +581,7 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
581
581
|
aria-label="Edit ${d(t)}"
|
|
582
582
|
>${s}</div>
|
|
583
583
|
</div>
|
|
584
|
-
`}function
|
|
584
|
+
`}function Lo(e=[],t){let a=new Set(e.map(l=>l.other_ticket.id)),n=new Set;if(t?.parent_ticket_id&&n.add(t.parent_ticket_id),t?.id)for(let l of Y())l.parent_ticket_id===t.id&&n.add(l.id);let o=Y().filter(l=>l.id!==t?.id&&!a.has(l.id)&&!n.has(l.id)).map(l=>`<option value="#${l.number} \u2014 ${d(l.title)}"></option>`).join(""),s=e.length?`<div class="detail-card-grid">${e.map(l=>_o(l)).join("")}</div>`:"",i=`
|
|
585
585
|
<form id="relatedAddForm" class="related-add-row">
|
|
586
586
|
<div class="related-add-input-wrap">
|
|
587
587
|
<input type="text" name="target" class="related-add-input meta-inline-input" list="related-ticket-suggestions" placeholder="Add related ticket\u2026" aria-label="Add related ticket" autocomplete="off" />
|
|
@@ -595,12 +595,12 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
595
595
|
</select>
|
|
596
596
|
<button type="submit" class="ghost meta-add-btn">Add</button>
|
|
597
597
|
</form>
|
|
598
|
-
`;return s+i}function
|
|
598
|
+
`;return s+i}function To(e,t){if(N(e.type)==="epic"){let n=t.child_tickets||[];return`
|
|
599
599
|
<div class="section">
|
|
600
600
|
<h3>Features inside this Epic</h3>
|
|
601
601
|
${n.length?`<div class="detail-card-grid">${n.map(o=>Ue(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>'}
|
|
602
602
|
</div>
|
|
603
|
-
`}return""}function
|
|
603
|
+
`}return""}function Io(e,t){if(N(e.type)==="epic")return"";let n=Y().filter(o=>o.type==="epic"&&o.id!==e.id).map(o=>`<option value="#${o.number} \u2014 ${d(o.title)}"></option>`).join("");return`
|
|
604
604
|
<div class="section">
|
|
605
605
|
<h3>Epic</h3>
|
|
606
606
|
${t.parent_ticket?`<div class="detail-card-grid detail-card-grid--single">${Ue(t.parent_ticket,{detach:{mode:"parent"}})}</div>`:`
|
|
@@ -614,12 +614,12 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
614
614
|
</form>
|
|
615
615
|
`}
|
|
616
616
|
</div>
|
|
617
|
-
`}function Ue(e,t={}){let a=N(e.type),n=Oe(e.priority),r=
|
|
617
|
+
`}function Ue(e,t={}){let a=N(e.type),n=Oe(e.priority),r=Qe(e),o=De(e.type).toUpperCase(),s=t.eyebrow?`<span class="card-eyebrow">${d(t.eyebrow)}</span>`:"",i="";if(t.detach){let{mode:m,id:p}=t.detach,f="",b="";m==="child"?(f=`data-detach-child="${d(p)}"`,b="Remove from epic"):m==="parent"?(f='data-detach-parent="1"',b="Remove parent epic"):m==="relation"&&(f=`data-detach-relation="${d(p)}"`,b="Remove relation"),i=`<button type="button" class="card-detach-btn" ${f} aria-label="${b}" title="${b}">\xD7</button>`}else if(t.archive){let m=d(t.archive.id);i=`
|
|
618
618
|
<div class="card-archive-actions">
|
|
619
619
|
<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>
|
|
620
620
|
<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>
|
|
621
621
|
</div>
|
|
622
|
-
`}let l=
|
|
622
|
+
`}let l=_t(e),u=l===0?"":l===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="${l} unread updates">${l>99?"99+":l}</span>`;return`
|
|
623
623
|
<article class="card card--detail type-${d(a)} priority-${d(n)}" data-variant="${d(a)}"${t.disableOpen?"":` data-open-ticket="${d(e.id)}"`}>
|
|
624
624
|
${u}
|
|
625
625
|
${i}
|
|
@@ -629,16 +629,16 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
629
629
|
<div class="card-expand-trigger card-expand-trigger--static">
|
|
630
630
|
<span class="ticket-number">${d(ae(e))}</span>
|
|
631
631
|
<div class="card-type-id type-pill-${d(a)}">
|
|
632
|
-
${
|
|
632
|
+
${Pt(e.type)}
|
|
633
633
|
<span class="card-type-label">${d(o)}</span>
|
|
634
634
|
</div>
|
|
635
635
|
<span class="detail-card-state" data-variant="${d(r)}">${d(e.state_name||"State")}</span>
|
|
636
|
-
${c.showPriority?
|
|
636
|
+
${c.showPriority?Ea(e.priority):""}
|
|
637
637
|
</div>
|
|
638
638
|
</div>
|
|
639
639
|
</article>
|
|
640
|
-
`}function
|
|
641
|
-
`).map(t=>t.trim()).filter(Boolean).join(" ").replace(/\s+/g," ").trim()}function
|
|
640
|
+
`}function _o(e){let t=String(e.type||"").replace(/_/g," "),a=e.direction==="incoming"?"from":"to";return Ue(e.other_ticket,{eyebrow:`${t} ${a}`,detach:{mode:"relation",id:e.id}})}var Dt=_(()=>{U();ie();ne();it();xt();he();Q();qe();me();Cn();rt();Bn()});function Ma(){ze&&(clearTimeout(ze),ze=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",()=>{Ot=1e3,jt&&(h.success("Live updates reconnected"),jt=!1)}),a.addEventListener("board",async n=>{let r;try{r=JSON.parse(n.data)}catch{return}let o=r.type,s=()=>c.data?.tickets?.find(u=>u.id===r.ticket_id),i=c.data?.actor?.name,l=r.actor&&i&&r.actor===i;if(r.ticket_id&&(l?Ct(r.ticket_id,r.timestamp):o==="ticket_deleted"?gn(r.ticket_id):Co.has(o)&&bn(r.ticket_id)),o==="ticket_created")h.success(`Card created: ${r.data.title||"New card"}`),ve();else if(o==="state_changed"){let u=s(),m=u?`#${u.number} ${u.title}`:"Card";h.info(`${m} \u2192 ${r.data.to}`),ve()}else if(o==="ticket_updated"){let u=s(),m=u?`#${u.number}`:"Card",p=r.data.fields?Object.keys(r.data.fields).join(", "):"";h.info(`${m} updated${p?`: ${p}`:""}`),ve()}else if(o==="comment_created"){let u=s(),m=u?`#${u.number}`:"ticket";h.info(`New comment on ${m}`),ve()}else if(o==="agent_claimed"){let u=s();h.info(`Agent claimed ${u?`#${u.number} ${u.title}`:"a ticket"}`),ve()}else if(o==="checkpoint_requested"){let u=s();h.warning(`Checkpoint on ${u?`#${u.number}`:"ticket"} \u2014 needs human input`),ve()}else if(o==="agent_completed"){let u=s();h.success(`Agent completed ${u?`#${u.number} ${u.title}`:"a ticket"}`),ve()}else(o==="ticket_deleted"||o==="states_reordered"||o==="state_created"||o==="state_deleted"||o==="board_updated"||o==="board_imported")&&ve()}),a.onerror=()=>{if(a.readyState!==EventSource.CLOSED||(jt||(h.warning("Live updates disconnected \u2014 retrying\u2026"),jt=!0),ze))return;let n=Ot;Ot=Math.min(Ot*2,3e4),ze=setTimeout(()=>{ze=null,Ma()},n)}}var Co,Ot,ze,jt,ve,Nn=_(()=>{U();Q();me();fe();rt();Co=new Set(["ticket_created","state_changed","ticket_updated","comment_created","agent_claimed","checkpoint_requested","agent_completed"]),Ot=1e3,ze=null,jt=!1;ve=wt(async()=>{let e=c.selectedTicketId,t=c.detailMode;c.data=await v(Ze()),xe(),c.selectedTicketId=e,c.detailMode=t,await Ht()},300)});function Po(e){return X(e||"").split(`
|
|
641
|
+
`).map(t=>t.trim()).filter(Boolean).join(" ").replace(/\s+/g," ").trim()}function Ao(e={}){return Po(e.project_notes)||Pa}function Bo(e,t){if(!e?.id||!t?.data?.boards)return;let a=t.data.boards.findIndex(n=>n.id===e.id);a>=0&&t.data.boards.splice(a,1,{...t.data.boards[a],...e})}function Fo(e){let t=e?.project_notes||"",a=!!t.trim(),n=a?"":" is-placeholder",r=a?ce(t):d(Mo);return`
|
|
642
642
|
<div
|
|
643
643
|
class="inline-md-field-body preserved-text-body editable-field brand-focus-notes-edit${n}"
|
|
644
644
|
data-edit-field="project_notes"
|
|
@@ -647,7 +647,7 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
647
647
|
role="button"
|
|
648
648
|
aria-label="Edit board notes"
|
|
649
649
|
>${r}</div>
|
|
650
|
-
`}function Ge(e=Z){Z=e||{};let t=
|
|
650
|
+
`}function Ge(e=Z){Z=e||{};let t=Ao(Z),a=document.getElementById("brandNotesBtn"),n=document.getElementById("brandNotesText"),r=document.getElementById("brandFocusNotes");a&&(a.hidden=!1,a.dataset.empty=t===Pa?"true":"false",a.setAttribute("aria-label",`Show board notes: ${t}`)),n&&(n.textContent=t===Pa?"":t),r&&(r.innerHTML=Fo(Z))}function st(e){let t=[document.getElementById("brandFocusBtn"),document.getElementById("brandNotesBtn")].filter(Boolean),a=document.getElementById("brandFocusPopover");if(a){for(let n of t)n.setAttribute("aria-expanded",e?"true":"false"),n.dataset.state=e?"open":"closed";a.hidden=!e}}function On(){let e=document.getElementById("brandFocusPopover");Ge(),st(!!e?.hidden)}async function jn(e){let t=document.querySelector('#brandFocusPopover [data-edit-field="project_notes"]');if(!t||!Z?.id)return;let{startInlineEdit:a}=await Promise.resolve().then(()=>(Dt(),Dn));a(t,{fieldName:"project_notes",multiline:!0,initialValue:Z.project_notes||"",ariaLabel:"Edit board notes",sourceEvent:e,rerender:async()=>{Ge(Z),st(!0)},commit:async n=>{let[{api:r},{state:o}]=await Promise.all([Promise.resolve().then(()=>(Q(),rn)),Promise.resolve().then(()=>(U(),Va))]),s=await r(`/api/boards/${encodeURIComponent(Z.id||o.boardId)}`,{method:"PATCH",body:{project_notes:X(n)}});Z={...Z,...s},Bo(Z,o),Ge(Z),st(!0)}})}function Hn(){let e=document.getElementById("brandFocusBtn"),t=document.getElementById("brandNotesBtn"),a=document.getElementById("brandFocusPopover");!e||!t||!a||(e.addEventListener("click",n=>{n.stopPropagation(),On()}),t.addEventListener("click",n=>{n.stopPropagation(),On()}),a.addEventListener("click",n=>{n.stopPropagation(),n.target.closest('[data-edit-field="project_notes"]')&&jn(n)}),a.addEventListener("keydown",n=>{n.key!=="Enter"&&n.key!==" "||n.target.closest('[data-edit-field="project_notes"]')&&(n.preventDefault(),jn(n))}),document.addEventListener("click",n=>{n.target.closest("#brandFocusBtn")||n.target.closest("#brandNotesBtn")||n.target.closest("#brandFocusPopover")||st(!1)}),document.addEventListener("keydown",n=>{n.key==="Escape"&&st(!1)}))}var Pa,Mo,Z,Aa=_(()=>{ne();Pa="No board notes yet",Mo="Add board notes for yourself and your agents\u2026";Z={}});var Un={};pt(Un,{load:()=>I,render:()=>Ht,renderDetailOnly:()=>Ro});async function I(){se(),c.data=await v(Ze()),xe(),yn(c.boardId,c.data?.tickets||[]),await Ht(),O.sse&&c.boardId!==qn&&(qn=c.boardId,Ma())}async function Ht(){xe(),Ba(),Ge(q()),je(),await ye()}async function Ro(){xe(),Ba(),Ge(q()),wn(),await ye()}var qn,fe=_(()=>{U();Q();it();Dt();ct();Nn();rt();qe();Aa();qn=null});function Ra(){return Me?.classList.contains("is-open")}function At(e){clearTimeout(Fa),se(),kt(),Yt.innerHTML=Do(e||""),No(),y("#createFlyoutClose")?.addEventListener("click",()=>D()),Me.hidden=!1,ke.hidden=!1,requestAnimationFrame(()=>{Me.classList.add("is-open"),ke.classList.add("is-visible")}),requestAnimationFrame(()=>{y("#createTicketTitle")?.focus()})}function D(){clearTimeout(Fa),Me.classList.remove("is-open"),ke.classList.remove("is-visible"),Fa=setTimeout(()=>{Me.hidden=!0,ke.hidden=!0,Yt.innerHTML=""},220)}function Do(e){let t=Ee(),a=t.find(s=>s.is_default)||t[0],n=e&&t.some(s=>s.id===e)?e:a?.id||"",r=t.map(s=>`<option value="${d(s.id)}" ${s.id===n?"selected":""}>${d(s.name)}</option>`).join(""),o=Y().filter(s=>s.type==="epic").map(s=>`<option value="${d(s.id)}">${d(ae(s))}</option>`).join("");return`
|
|
651
651
|
<div class="create-flyout-head">
|
|
652
652
|
<h2>New card</h2>
|
|
653
653
|
<button type="button" class="create-flyout-close ghost" id="createFlyoutClose" aria-label="Close">\xD7</button>
|
|
@@ -690,7 +690,7 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
690
690
|
<input id="createTicketLabels" name="labels" type="text" placeholder="Labels (comma-separated)" />
|
|
691
691
|
<button type="submit">Create card</button>
|
|
692
692
|
</form>
|
|
693
|
-
`}function
|
|
693
|
+
`}function No(){let e=y("#createTicketForm");e&&e.addEventListener("submit",Oo)}async function Oo(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}});D(),c.selectedTicketId=r.id,c.detailMode="ticket",await I(),Ke()}var Fa,He=_(()=>{ie();U();ne();Q();he();xt();ct();fe();Fa=0});function dt(){te&&(te.hidden=!0,te.innerHTML="",ue?.setAttribute("aria-expanded","false"))}function se(){dt()}function Ba(){if(!c.data)return;let e=(c.data.boards||[]).find(t=>t.id===c.boardId);if(ue){let t=e?.name||"Board";ue.innerHTML=`${jo}<span class="topbar-chip-label">${d(t)}</span>`,ue.title=e?`${e.name} \u2014 slug: ${e.slug}`:"Choose board"}}function Ho(){let a=(c.data.boards||[]).map(r=>`
|
|
694
694
|
<button type="button" class="menu-flyout-item ${r.id===c.boardId?"is-current":""}" data-variant="menu-item" data-pick-board="${d(r.id)}" role="menuitem">
|
|
695
695
|
<span class="menu-flyout-item-title">${d(r.name)}</span>
|
|
696
696
|
<span class="menu-flyout-item-meta">${d(r.slug)}</span>
|
|
@@ -719,7 +719,7 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
719
719
|
<div class="menu-flyout-head">Board</div>
|
|
720
720
|
<div class="menu-flyout-list">${a}</div>
|
|
721
721
|
${n}
|
|
722
|
-
`}function
|
|
722
|
+
`}function qo(){te.querySelectorAll("[data-pick-board]").forEach(t=>{t.addEventListener("click",async a=>{a.stopPropagation();let n=t.getAttribute("data-pick-board");dt(),n!==c.boardId&&(D(),await A({boardId:n,view:"board"}))})});let e=te.querySelector("#createBoardForm");if(e){let t=e.querySelector("#pickRepoFolderBtn"),a=e.querySelector("#repoPathInput"),n=e.querySelector("#helperFilesReveal"),r=()=>{n&&(n.hidden=!a.value.trim())};r(),t?.addEventListener("click",async o=>{o.preventDefault(),t.disabled=!0;try{let s=await v("/api/system/pick-folder",{method:"POST"});s.path&&(a.value=s.path,a.dispatchEvent(new Event("input",{bubbles:!0})),r())}catch(s){h.error(s?.message||"Folder picker unavailable")}finally{t.disabled=!1}}),e.addEventListener("submit",async o=>{o.preventDefault();let s=new FormData(e),i=String(s.get("slug")||"").trim(),l=String(s.get("default_branch")||"").trim(),u=String(s.get("repo_url")||"").trim(),m=String(s.get("repo_path")||"").trim(),p=await v("/api/boards",{method:"POST",body:{name:s.get("name"),...m?{repo_path:m,manage_helper_files:s.get("manage_helper_files")==="on"}:{},...i?{slug:i}:{},...l?{default_branch:l}:{},...u?{repo_url:u}:{}}});dt(),c.boardId=p.id,c.selectedTicketId="",c.detailMode="settings",await I(),Ke(),h.success("Board created")})}}function zn(){D(),te.innerHTML=Ho(),te.hidden=!1,ue?.setAttribute("aria-expanded","true"),qo()}var jo,ct=_(()=>{ie();U();ne();Q();he();He();me();fe();qe();jo=`
|
|
723
723
|
<svg
|
|
724
724
|
class="topbar-icon"
|
|
725
725
|
width="16"
|
|
@@ -730,13 +730,13 @@ enabled = true`}function Kr(e){return["claude mcp add starscape-orbit","--","nod
|
|
|
730
730
|
>
|
|
731
731
|
<rect x="4" y="4" width="6" height="16" rx="0.75" stroke="currentColor" stroke-width="2" />
|
|
732
732
|
<rect x="14" y="4" width="6" height="16" rx="0.75" stroke="currentColor" stroke-width="2" />
|
|
733
|
-
</svg>`});function
|
|
733
|
+
</svg>`});function Gn(){return{...Uo}}function Na(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 Da(e){try{return decodeURIComponent(e)}catch{return e}}function zo(e){return String(e||"").replace(/^#/,"").replace(/^\/+/,"").replace(/\/+$/,"").split("/").filter(Boolean)}function Go(e){if(!e.length)return null;let t=Gn(),a=0;if(e[a]==="b"){if(!e[a+1])return null;t.boardSlug=Da(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=Da(e[a+1]);else if(e[a]==="settings"){t.view="settings";let n=e[a+1]?Da(e[a+1]):"";n&>.has(n)&&(t.tab=n)}return t}function Kn(e){let t=String(e||"");return!t||t==="#"||t==="#/"?null:Go(zo(t))}function qt(e=globalThis.location){let t=Na(e);return Kn(t.hash)||Gn()}function lt(e=globalThis.location){let t=Na(e);return!!Kn(t.hash)}function Je({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&>.has(n)&&r.push(n)),"#/"+r.join("/")}function Ut(e=globalThis.location,t=qt(e)){return Na(e).hash===Je(t)}var Uo,Oa=_(()=>{yt();Uo=Object.freeze({boardSlug:"",view:"board",ticketId:"",tab:""})});function Jn(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 Ko(e={}){return e.boardSlug?e.boardSlug:e.boardId?Jn(e.boardId)?.slug||e.boardId:q()?.slug||c.boardSlug||""}function Jo(e={}){return{...e,boardSlug:Ko(e)}}function Yo(){let e="board";return c.detailMode==="ticket"&&c.selectedTicketId?e="ticket":c.detailMode==="settings"&&(e="settings"),{boardSlug:q()?.slug||c.boardSlug,view:e,ticketId:c.selectedTicketId,tab:e==="settings"?Ve(c.settingsTab):""}}function Yn(e){zt=e}function ja(){return qt(location)}async function A(e,{replace:t=!1}={}){let a=Jo(e),n=Je(a);if(Ut(location,a)){zt&&await ut();return}t?history.replaceState(null,"",n):history.pushState(null,"",n),zt&&await ut()}function Ke({replace:e=!1}={}){let t=Yo(),a=Je(t);Ut(location,t)||(e?history.replaceState(null,"",a):history.pushState(null,"",a))}async function ut(){let{load:e,renderDetailOnly:t}=await Promise.resolve().then(()=>(fe(),Un)),a=ja(),n=lt(location),r=c.boardId,s=Jn(a.boardSlug)||(a.boardSlug?q():null);s?(c.boardId=s.id,c.boardSlug=s.slug):a.boardSlug&&(c.boardSlug=a.boardSlug);let i=s?{...a,boardSlug:s.slug}:a;if(n&&!Ut(location,i)&&history.replaceState(null,"",Je(i)),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(se(),D(),c.boardId&&c.boardId!==r){await e();return}await t()}var zt,he=_(()=>{U();yt();ct();He();Oa();Oa();zt=!1;window.addEventListener("popstate",()=>{zt&&ut()})});ie();Qt();ta();Ka(),Ye();var tr=ar();aa();{let e=()=>{document.body.classList.toggle("is-scrolled",window.scrollY>4)};window.addEventListener("scroll",e,{passive:!0}),e()}Ya();Ha?.addEventListener("click",()=>{Ja()});window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",e=>{bt()||We(e.matches?"dark":"light",{notify:!0})});window.addEventListener(ht,()=>{Ya(),tr.sync()});function Ya(){if(!Wt)return;let e=$e()==="dark";Wt.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 ar(){let e=document.querySelector(".grain");if(!e)return{sync:()=>{}};nr(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,s=0,i=[],l=0,u=!1,m={x:0,y:0,tx:0,ty:0};function p(){o=window.innerWidth,s=window.innerHeight,t.width=Math.round(o*r),t.height=Math.round(s*r),t.style.width=o+"px",t.style.height=s+"px",n.setTransform(r,0,0,r,0,0),f()}function f(){let S=o*s/1296e3,E=[{count:Math.round(320*S),depth:.12,sizes:[[1,.9],[1.4,.1]],glow:0},{count:Math.round(160*S),depth:.3,sizes:[[1,.5],[1.6,.4],[2.4,.1]],glow:1.8},{count:Math.round(44*S),depth:.58,sizes:[[1.8,.5],[2.6,.38],[3.6,.12]],glow:2.4}],F=Wa(12648430);i=[];for(let H of E)for(let L=0;L<H.count;L++){let g=or(F(),H.sizes);i.push({x:F()*o,y:F()*s,size:g,depth:H.depth,glow:g>=2?H.glow:0,rgb:b(F()),period:2.2+F()*5.4,phase:F()*Math.PI*2,amp:.25+F()*.5,baseAlpha:g<1.5?.45+F()*.28:.55+F()*.22})}}function b(S){return S<.8?[255,255,255]:S<.93?[255,222,186]:[195,218,255]}function w(S){!o||!s||(m.tx=S.clientX/o-.5,m.ty=S.clientY/s-.5)}function $(S){m.x+=(m.tx-m.x)*.06,m.y+=(m.ty-m.y)*.06,n.clearRect(0,0,o,s),n.globalCompositeOperation="lighter";let E=S/1e3,F=70;for(let H=0;H<i.length;H++){let L=i[H],g=.5+.5*Math.sin(E*(2*Math.PI/L.period)+L.phase),M=L.baseAlpha*(1-L.amp+L.amp*g),R=L.x-m.x*L.depth*F,z=L.y-m.y*L.depth*F,[ee,W,oe]=L.rgb;if(L.glow>0){let V=L.size*L.glow,Ce=n.createRadialGradient(R,z,0,R,z,V);Ce.addColorStop(0,`rgba(${ee},${W},${oe},${M*.85})`),Ce.addColorStop(.35,`rgba(${ee},${W},${oe},${M*.3})`),Ce.addColorStop(1,`rgba(${ee},${W},${oe},0)`),n.fillStyle=Ce,n.beginPath(),n.arc(R,z,V,0,Math.PI*2),n.fill(),n.fillStyle=`rgba(${ee},${W},${oe},${M})`,n.beginPath(),n.arc(R,z,L.size/2,0,Math.PI*2),n.fill()}else{let V=L.size/2;n.fillStyle=`rgba(${ee},${W},${oe},${M})`,n.fillRect(R-V,z-V,L.size,L.size)}}n.globalCompositeOperation="source-over",u&&(l=requestAnimationFrame($))}function P(){n.clearRect(0,0,o,s),n.globalCompositeOperation="lighter";for(let S of i){let[E,F,H]=S.rgb;if(n.fillStyle=`rgba(${E},${F},${H},${S.baseAlpha})`,S.glow>0)n.beginPath(),n.arc(S.x,S.y,S.size/2,0,Math.PI*2),n.fill();else{let L=S.size/2;n.fillRect(S.x-L,S.y-L,S.size,S.size)}}n.globalCompositeOperation="source-over"}function C(){u||(u=!0,l=requestAnimationFrame($))}function J(){u=!1,cancelAnimationFrame(l)}function B(){let S=$e()==="dark",E=Ae();if(!S){J(),n.clearRect(0,0,o,s);return}i.length||p(),E||document.hidden?(J(),P()):C()}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",()=>{Ye(),B()}),window.addEventListener("orbit:motion-preference-change",B),p(),B(),{sync:B}}function nr(e){e.querySelectorAll(".signature-star").forEach(n=>n.remove());let t=Wa(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 aa(){let e=14e3+Math.random()*28e3;setTimeout(rr,e)}function rr(){let e=$e()==="dark",t=Ae(),a=document.querySelector(".grain");if(!e||t||document.hidden||!a){aa();return}let n=window.innerWidth,r=window.innerHeight,o=Math.random()*n*.6,s=Math.random()*r*.55,i=380+Math.random()*520,l=18+Math.random()*26,u=l*Math.PI/180,m=o+Math.cos(u)*i,p=s+Math.sin(u)*i,f=document.createElement("div");f.className="meteor",f.setAttribute("aria-hidden","true"),f.style.setProperty("--from-x",o+"px"),f.style.setProperty("--from-y",s+"px"),f.style.setProperty("--to-x",m+"px"),f.style.setProperty("--to-y",p+"px"),f.style.setProperty("--angle",l+"deg"),a.appendChild(f),f.addEventListener("animationend",()=>f.remove(),{once:!0}),aa()}function or(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 Wa(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}}ie();U();Q();me();he();ct();He();it();ie();U();Q();he();ne();He();async function Wn(){let e=mt.value.trim();if(e.length<2){Gt();return}let t=q();if(!t)return;let a=await v(`/api/search?q=${encodeURIComponent(e)}&board=${encodeURIComponent(t.slug)}`);if(a.results.length===0){pe.hidden=!1,pe.innerHTML='<div class="search-hit">No results</div>';return}pe.hidden=!1,pe.innerHTML=a.results.map(n=>`
|
|
734
734
|
<div class="search-hit" data-ticket-id="${n.id}">
|
|
735
735
|
<span class="search-hit-main">
|
|
736
736
|
<strong>${d(ae(n))}</strong>
|
|
737
737
|
<span class="search-hit-title">${d(n.title)}</span>
|
|
738
738
|
</span>
|
|
739
|
-
<span class="search-hit-state" data-variant="${d(
|
|
739
|
+
<span class="search-hit-state" data-variant="${d(Qe(n))}">${d(n.state_name||"State")}</span>
|
|
740
740
|
</div>
|
|
741
|
-
`).join(""),pe.querySelectorAll("[data-ticket-id]").forEach(n=>{n.addEventListener("click",async()=>{D(),
|
|
741
|
+
`).join(""),pe.querySelectorAll("[data-ticket-id]").forEach(n=>{n.addEventListener("click",async()=>{D(),Gt(),A({boardId:c.boardId,view:"ticket",ticketId:n.dataset.ticketId})})})}function Gt(){pe.hidden=!0,pe.innerHTML=""}fe();qe();function Kt(e){e?.showModal()}function Vn(e){e?.open&&e.close()}function Jt(e){e&&(e.addEventListener("click",t=>{t.target===e&&Vn(e)}),e.querySelectorAll("[data-modal-close]").forEach(t=>{t.addEventListener("click",()=>Vn(e))}))}Aa();async function Wo(e){if(e)try{let t=await fetch("./version.json",{cache:"no-store"});if(!t.ok)return;let a=await t.json();a?.version&&(e.textContent=`v${a.version}`)}catch{}}function Xn(){let e=document.getElementById("helpDialog"),t=document.getElementById("helpBtn");!e||!t||(Jt(e),Wo(document.getElementById("helpDialogVersion")),t.addEventListener("click",()=>Kt(e)))}async function Vo(){let e=document.getElementById("welcomeDialog");Jt(e),Hn(),Xn(),Te==="preview"&&Kt(e),y("#settingsBtn").addEventListener("click",async()=>{D(),se(),A({boardId:c.boardId,view:"settings",tab:c.settingsTab||"lanes"})}),ue?.addEventListener("click",a=>{if(a.stopPropagation(),!te.hidden){dt();return}zn()}),y("#newTicketBtn").addEventListener("click",()=>{if(Ra()){D();return}At("")}),ke.addEventListener("click",()=>{D()}),y("#drawerCloseBtn").addEventListener("click",()=>{A({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(x(`/api/tickets/${encodeURIComponent(a)}/archive`),{method:"POST"}),h.error(`Archived: ${r}`),await I(),A({boardId:c.boardId,view:"board"})}),we.addEventListener("click",()=>{A({boardId:c.boardId,view:"board"})}),document.addEventListener("keydown",a=>{if(a.key!=="Escape")return;if(!te.hidden){se();return}if(Ra()){D();return}if(!G.classList.contains("is-open"))return;let n=document.activeElement;n?.classList?.contains("inline-title-editor")||n?.classList?.contains("inline-desc-editor")||A({boardId:c.boardId,view:"board"})}),mt.addEventListener("input",wt(Wn,220)),document.addEventListener("click",a=>{a.target.closest("#topbarSearch")||Gt(),a.target.closest(".topbar-menu")||se()}),$n(),vn();let t=ja();t.boardSlug&&(c.boardSlug=t.boardSlug),await I(),Yn(!0),lt()?await ut():Ke({replace:!0})}Vo();
|
|
742
742
|
//# sourceMappingURL=app.js.map
|