hotsheet 0.1.1 → 0.1.2

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/dist/cli.js CHANGED
@@ -1150,12 +1150,14 @@ var CATEGORY_DESCRIPTIONS = {
1150
1150
 
1151
1151
  // src/sync/markdown.ts
1152
1152
  var dataDir;
1153
+ var port;
1153
1154
  var worklistTimeout = null;
1154
1155
  var openTicketsTimeout = null;
1155
1156
  var WORKLIST_DEBOUNCE = 500;
1156
1157
  var OPEN_TICKETS_DEBOUNCE = 5e3;
1157
- function initMarkdownSync(dir) {
1158
+ function initMarkdownSync(dir, serverPort) {
1158
1159
  dataDir = dir;
1160
+ port = serverPort;
1159
1161
  }
1160
1162
  function scheduleWorklistSync() {
1161
1163
  if (worklistTimeout) clearTimeout(worklistTimeout);
@@ -1233,13 +1235,13 @@ async function syncWorklist() {
1233
1235
  sections.push("");
1234
1236
  sections.push("## Workflow");
1235
1237
  sections.push("");
1236
- sections.push("The Hot Sheet API is available at http://localhost:4174/api. Use it to update ticket status as you work:");
1238
+ sections.push(`The Hot Sheet API is available at http://localhost:${port}/api. Use it to update ticket status as you work:`);
1237
1239
  sections.push("");
1238
1240
  sections.push('- **When you start working on a ticket**, set its status to "started":');
1239
- sections.push(' `curl -X PATCH http://localhost:4174/api/tickets/{id} -H "Content-Type: application/json" -d \'{"status": "started"}\'`');
1241
+ sections.push(` \`curl -X PATCH http://localhost:${port}/api/tickets/{id} -H "Content-Type: application/json" -d '{"status": "started"}'\``);
1240
1242
  sections.push("");
1241
1243
  sections.push('- **When you finish working on a ticket**, set its status to "completed" and add notes describing what was done:');
1242
- sections.push(' `curl -X PATCH http://localhost:4174/api/tickets/{id} -H "Content-Type: application/json" -d \'{"status": "completed", "notes": "Description of work completed"}\'`');
1244
+ sections.push(` \`curl -X PATCH http://localhost:${port}/api/tickets/{id} -H "Content-Type: application/json" -d '{"status": "completed", "notes": "Description of work completed"}'\``);
1243
1245
  sections.push("");
1244
1246
  sections.push('Do NOT set tickets to "verified" \u2014 that status is reserved for human review.');
1245
1247
  sections.push("");
@@ -1903,18 +1905,18 @@ pageRoutes.get("/", (c) => {
1903
1905
  });
1904
1906
 
1905
1907
  // src/server.ts
1906
- function tryServe(fetch, port) {
1908
+ function tryServe(fetch, port2) {
1907
1909
  return new Promise((resolve2, reject) => {
1908
- const server = serve({ fetch, port });
1910
+ const server = serve({ fetch, port: port2 });
1909
1911
  server.on("listening", () => {
1910
- resolve2(port);
1912
+ resolve2(port2);
1911
1913
  });
1912
1914
  server.on("error", (err) => {
1913
1915
  reject(err);
1914
1916
  });
1915
1917
  });
1916
1918
  }
1917
- async function startServer(port, dataDir2) {
1919
+ async function startServer(port2, dataDir2) {
1918
1920
  const app = new Hono3();
1919
1921
  app.use("*", async (c, next) => {
1920
1922
  c.set("dataDir", dataDir2);
@@ -1932,10 +1934,10 @@ async function startServer(port, dataDir2) {
1932
1934
  });
1933
1935
  app.route("/api", apiRoutes);
1934
1936
  app.route("/", pageRoutes);
1935
- let actualPort = port;
1937
+ let actualPort = port2;
1936
1938
  for (let attempt = 0; attempt < 20; attempt++) {
1937
1939
  try {
1938
- actualPort = await tryServe(app.fetch, port + attempt);
1940
+ actualPort = await tryServe(app.fetch, port2 + attempt);
1939
1941
  break;
1940
1942
  } catch (err) {
1941
1943
  if (err instanceof Error && err.code === "EADDRINUSE" && attempt < 19) {
@@ -1944,8 +1946,8 @@ async function startServer(port, dataDir2) {
1944
1946
  throw err;
1945
1947
  }
1946
1948
  }
1947
- if (actualPort !== port) {
1948
- console.log(` Port ${port} in use, using ${actualPort} instead.`);
1949
+ if (actualPort !== port2) {
1950
+ console.log(` Port ${port2} in use, using ${actualPort} instead.`);
1949
1951
  }
1950
1952
  const url = `http://localhost:${actualPort}`;
1951
1953
  console.log(`
@@ -2088,7 +2090,7 @@ Examples:
2088
2090
  }
2089
2091
  function parseArgs(argv) {
2090
2092
  const args = argv.slice(2);
2091
- let port = 4174;
2093
+ let port2 = 4174;
2092
2094
  let dataDir2 = join7(process.cwd(), ".hotsheet");
2093
2095
  let demo = null;
2094
2096
  let forceUpdateCheck = false;
@@ -2109,8 +2111,8 @@ function parseArgs(argv) {
2109
2111
  process.exit(0);
2110
2112
  break;
2111
2113
  case "--port":
2112
- port = parseInt(args[++i], 10);
2113
- if (isNaN(port)) {
2114
+ port2 = parseInt(args[++i], 10);
2115
+ if (isNaN(port2)) {
2114
2116
  console.error("Invalid port number");
2115
2117
  process.exit(1);
2116
2118
  }
@@ -2127,7 +2129,7 @@ function parseArgs(argv) {
2127
2129
  process.exit(1);
2128
2130
  }
2129
2131
  }
2130
- return { port, dataDir: dataDir2, demo, forceUpdateCheck };
2132
+ return { port: port2, dataDir: dataDir2, demo, forceUpdateCheck };
2131
2133
  }
2132
2134
  async function main() {
2133
2135
  const parsed = parseArgs(process.argv);
@@ -2135,7 +2137,7 @@ async function main() {
2135
2137
  printUsage();
2136
2138
  process.exit(1);
2137
2139
  }
2138
- const { port, demo, forceUpdateCheck } = parsed;
2140
+ const { port: port2, demo, forceUpdateCheck } = parsed;
2139
2141
  let { dataDir: dataDir2 } = parsed;
2140
2142
  await checkForUpdates(forceUpdateCheck);
2141
2143
  if (demo !== null) {
@@ -2162,13 +2164,13 @@ async function main() {
2162
2164
  if (demo !== null) {
2163
2165
  await seedDemoData(demo);
2164
2166
  }
2165
- initMarkdownSync(dataDir2);
2167
+ initMarkdownSync(dataDir2, port2);
2166
2168
  scheduleAllSync();
2167
2169
  if (demo === null) {
2168
2170
  await cleanupAttachments();
2169
2171
  }
2170
2172
  console.log(` Data directory: ${dataDir2}`);
2171
- await startServer(port, dataDir2);
2173
+ await startServer(port2, dataDir2);
2172
2174
  }
2173
2175
  main().catch((err) => {
2174
2176
  console.error(err);
@@ -1 +1,4 @@
1
- "use strict";(()=>{var re=Object.defineProperty;var le=(e,t,i)=>t in e?re(e,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[t]=i;var z=(e,t,i)=>le(e,typeof t!="symbol"?t+"":t,i);function F(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function j(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var h=class{constructor(t){z(this,"__html");this.__html=t}toString(){return this.__html}};function b(e){return new h(e)}var de=new Set(["area","base","br","col","embed","hr","img","input","link","meta","source","track","wbr"]);function D(e){return e==null||typeof e=="boolean"?"":e instanceof h?e.__html:typeof e=="string"?F(e):typeof e=="number"?String(e):Array.isArray(e)?e.map(D).join(""):""}function ce(e,t){if(t==null||t===!1)return"";if(t===!0)return` ${e}`;let i=e==="className"?"class":e==="htmlFor"?"for":e,s;return t instanceof h?s=t.__html:typeof t=="number"?s=String(t):typeof t=="string"?s=j(t):s="",` ${i}="${s}"`}function l(e,t){if(typeof e=="function")return e(t);let{children:i,...s}=t,a=Object.entries(s).map(([d,r])=>ce(d,r)).join("");if(de.has(e))return new h(`<${e}${a}>`);let o=i!=null?D(i):"";return new h(`<${e}${a}>${o}</${e}>`)}function L({children:e}){return new h(e!=null?D(e):"")}function f(e){let t=document.createElement("template");return t.innerHTML=e.toString(),t.content.firstElementChild}function V(e){document.getElementById("network-error-popup")?.remove();let t=f(l("div",{id:"network-error-popup",className:"error-popup",children:l("div",{className:"error-popup-content",children:[l("strong",{children:"Connection Error"}),l("p",{children:e}),l("button",{children:b("Dismiss")})]})}));t.querySelector("button").addEventListener("click",()=>t.remove()),document.body.appendChild(t)}async function c(e,t={}){try{return(await fetch("/api"+e,{headers:t.body!==void 0?{"Content-Type":"application/json"}:{},method:t.method,body:t.body!==void 0?JSON.stringify(t.body):void 0})).json()}catch(i){throw V("Unable to reach the server. It may have been stopped."),i}}async function W(e,t){try{let i=new FormData;return i.append("file",t),(await fetch("/api"+e,{method:"POST",body:i})).json()}catch(i){throw V("Unable to reach the server. It may have been stopped."),i}}var ue={detail_position:"side",detail_width:360,detail_height:300,trash_cleanup_days:3,verified_cleanup_days:30},n={tickets:[],selectedIds:new Set,lastClickedId:null,activeTicketId:null,view:"all",sortBy:"created",sortDir:"desc",search:"",settings:{...ue}},me={issue:"#6b7280",bug:"#ef4444",feature:"#22c55e",requirement_change:"#f97316",task:"#3b82f6",investigation:"#8b5cf6"},pe={issue:"ISS",bug:"BUG",feature:"FEA",requirement_change:"REQ",task:"TSK",investigation:"INV"},ye={highest:"\u2B06\u2B06",high:"\u2B06",default:"\u2014",low:"\u2B07",lowest:"\u2B07\u2B07"},fe={highest:"#ef4444",high:"#f97316",default:"#6b7280",low:"#3b82f6",lowest:"#94a3b8"},ge={not_started:"\u25CB",started:"\u25D4",completed:"\u2713",verified:"svg"},G='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 7 17l-5-5"/><path d="m22 10-9.5 9.5-2-2"/></svg>';function k(e){return me[e]||"#6b7280"}function S(e){return pe[e]||"ISS"}function Y(e){return ye[e]||"\u2014"}function A(e){return fe[e]||"#6b7280"}function J(e){return ge[e]||"\u25CB"}function x(e){n.activeTicketId=e,Z(e)}function X(){n.selectedIds.clear(),n.activeTicketId=null;let e=new CustomEvent("hotsheet:render");document.dispatchEvent(e)}function Q(){let e=n.view==="trash",t=document.getElementById("detail-panel"),i=document.getElementById("detail-resize-handle");if(n.selectedIds.size===1&&!e){let s=Array.from(n.selectedIds)[0];t.style.display="flex",i&&(i.style.display=""),n.activeTicketId!==s&&(n.activeTicketId=s,Z(s))}else n.activeTicketId!=null&&(n.activeTicketId=null),t.style.display="none",i&&(i.style.display="none")}async function Z(e){let t=await c(`/tickets/${e}`);if(n.activeTicketId!==e)return;document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,document.getElementById("detail-category").value=t.category,document.getElementById("detail-priority").value=t.priority,document.getElementById("detail-status").value=t.status,document.getElementById("detail-upnext").checked=t.up_next,document.getElementById("detail-details").value=t.details;let i=document.getElementById("detail-attachments");t.attachments.length>0?i.innerHTML=l(L,{children:t.attachments.map(r=>l("div",{className:"attachment-item",children:[l("span",{className:"attachment-name",children:r.original_filename}),l("button",{className:"attachment-delete","data-att-id":String(r.id),title:"Remove",children:b("&times;")})]}))}).toString():i.innerHTML="";let s=document.getElementById("detail-notes-section"),a=document.getElementById("detail-notes"),o=he(t.notes);o.length>0?(s.style.display="",a.innerHTML=l(L,{children:o.map(r=>l("div",{className:"note-entry",children:[r.created_at?l("div",{className:"note-timestamp",children:new Date(r.created_at).toLocaleString()}):null,l("div",{className:"note-text",children:r.text})]}))}).toString()):(s.style.display="none",a.innerHTML="");let d=document.getElementById("detail-meta");d.innerHTML=l(L,{children:[l("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),l("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?l("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?l("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function he(e){if(!e||e==="")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return e.trim()?[{text:e,created_at:""}]:[]}async function ee(){try{let e=await c("/stats"),t=document.getElementById("status-bar");t&&(t.textContent=`${e.total} tickets \xB7 ${e.open} open \xB7 ${e.up_next} up next`)}catch{}}function P(e){let t=document.getElementById("content-area");t.classList.remove("detail-side","detail-bottom"),t.classList.add(e==="bottom"?"detail-bottom":"detail-side")}function N(){let e=document.getElementById("detail-panel");n.settings.detail_position==="bottom"?(e.style.width="",e.style.height=`${n.settings.detail_height}px`):(e.style.height="",e.style.width=`${n.settings.detail_width}px`)}function te(){let e=document.getElementById("detail-resize-handle"),t=document.getElementById("detail-panel"),i=document.getElementById("content-area"),s=!1;e.addEventListener("mousedown",a=>{a.preventDefault(),s=!0,document.body.style.cursor=n.settings.detail_position==="bottom"?"row-resize":"col-resize",document.body.style.userSelect="none"}),document.addEventListener("mousemove",a=>{if(!s)return;let o=i.getBoundingClientRect();if(n.settings.detail_position==="bottom"){let d=Math.max(150,Math.min(500,o.bottom-a.clientY));n.settings.detail_height=d,t.style.height=`${d}px`}else{let d=Math.max(250,Math.min(600,o.right-a.clientX));n.settings.detail_width=d,t.style.width=`${d}px`}}),document.addEventListener("mouseup",()=>{s&&(s=!1,document.body.style.cursor="",document.body.style.userSelect="",n.settings.detail_position==="bottom"?c("/settings",{method:"PATCH",body:{detail_height:String(n.settings.detail_height)}}):c("/settings",{method:"PATCH",body:{detail_width:String(n.settings.detail_width)}}))})}function _(e,t){let i=t.getBoundingClientRect(),s=e.getBoundingClientRect(),a=window.innerWidth,o=window.innerHeight,d=i.left;d+s.width>a-8&&(d=i.right-s.width),d<8&&(d=8);let r=i.bottom+4;r+s.height>o-8&&(r=i.top-s.height-4),r<8&&(r=8),e.style.left=`${d}px`,e.style.top=`${r}px`}function H(e,t){let i=f(l("div",{className:"dropdown-menu",style:"visibility:hidden;top:0;left:0",children:t.map(r=>l("button",{className:`dropdown-item${r.active?" active":""}`,"data-key":r.key,children:[r.color?l("span",{className:"dropdown-dot",style:`background-color:${r.color}`}):null,l("span",{className:"dropdown-label",children:r.label}),r.shortcut?l("kbd",{className:"dropdown-kbd",children:r.shortcut}):null]}))}));i.querySelectorAll(".dropdown-item").forEach((r,u)=>{r.addEventListener("click",()=>{t[u].action(),i.remove()})});function a(r){let u=t.find(m=>r.key.toLowerCase()===m.key.toLowerCase());u?(r.preventDefault(),r.stopPropagation(),u.action(),o()):r.key==="Escape"&&(r.preventDefault(),o())}function o(){i.remove(),document.removeEventListener("keydown",a,!0),document.removeEventListener("click",d)}function d(){o()}return document.addEventListener("keydown",a,!0),setTimeout(()=>{document.addEventListener("click",d)},0),i}function C(){document.querySelectorAll(".dropdown-menu").forEach(e=>{e.remove()})}var $=null,I=!1,T=null,M=[{key:"i",value:"issue",label:"Issue"},{key:"b",value:"bug",label:"Bug"},{key:"f",value:"feature",label:"Feature"},{key:"r",value:"requirement_change",label:"Req Change"},{key:"k",value:"task",label:"Task"},{key:"g",value:"investigation",label:"Investigation"}],R=[{key:"1",value:"highest",label:"Highest"},{key:"2",value:"high",label:"High"},{key:"3",value:"default",label:"Default"},{key:"4",value:"low",label:"Low"},{key:"5",value:"lowest",label:"Lowest"}];function ve(){let e=document.activeElement;if(!e||!(e instanceof HTMLElement))return null;let t=e.closest(".ticket-row");if(!t)return null;if(t.classList.contains("draft-row"))return"draft";let i=t.dataset.id;return i!==void 0&&i!==""?parseInt(i,10):null}function be(e){e!=null&&(I=!0,e==="draft"?g():document.querySelector(`.ticket-row[data-id="${e}"] .ticket-title-input`)?.focus(),I=!1)}function y(){let e=n.view==="trash",t=ve(),i=document.getElementById("ticket-list");i.innerHTML="",e||i.appendChild(ke()),e&&n.tickets.length===0&&i.appendChild(f(l("div",{className:"ticket-list-empty",children:"Trash is empty"})));for(let s of n.tickets)i.appendChild(e?we(s):Ie(s));be(t),B(),ee()}function ke(){let e=se(),t=n.view.startsWith("category:"),i=f(l("div",{className:"ticket-row draft-row",children:[l("span",{className:"ticket-checkbox-spacer"}),l("span",{className:"ticket-status-btn draft-placeholder",children:"\u25CB"}),l("span",{className:"ticket-category-badge draft-badge",style:`background-color:${k(e)}${t?"":";cursor:pointer;opacity:1"}`,children:S(e)}),l("span",{className:"ticket-number draft-number"}),l("input",{type:"text",className:"ticket-title-input draft-input",placeholder:"New ticket..."}),l("span",{className:"ticket-priority-indicator draft-placeholder"}),l("span",{className:"ticket-star draft-placeholder"})]}));if(!t){let a=i.querySelector(".ticket-category-badge");a.addEventListener("click",o=>{o.stopPropagation(),Ee(a)})}let s=i.querySelector(".draft-input");return s.addEventListener("keydown",async a=>{if(a.key==="Enter"&&s.value.trim()){a.preventDefault();let o=s.value.trim();s.value="";let d=Te();T&&!n.view.startsWith("category:")&&(d.category=T),await c("/tickets",{method:"POST",body:{title:o,defaults:d}}),T=null,await p(),g()}else a.key==="ArrowDown"&&(a.preventDefault(),n.tickets.length>0&&document.querySelector(`.ticket-row[data-id="${n.tickets[0].id}"] .ticket-title-input`)?.focus())}),i}function g(){document.querySelector(".draft-row .draft-input")?.focus()}function Te(){let e=n.view;return e==="up-next"?{up_next:!0}:e==="open"?{}:e==="completed"?{status:"completed"}:e.startsWith("category:")?{category:e.split(":")[1]}:e.startsWith("priority:")?{priority:e.split(":")[1]}:{}}function se(){if(T)return T;let e=n.view;return e.startsWith("category:")?e.split(":")[1]:"issue"}function Ee(e){C();let i=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",s=se(),a=H(e,M.map(o=>({label:o.label,key:o.key,shortcut:`${i}${o.key.toUpperCase()}`,color:k(o.value),active:s===o.value,action:()=>{T=o.value,y(),g()}})));document.body.appendChild(a),_(a,e),a.style.visibility=""}function Ie(e){let t=n.selectedIds.has(e.id),i=e.status==="completed"||e.status==="verified",s=e.status==="verified",a=f(l("div",{className:`ticket-row${t?" selected":""}${i?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[l("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),l("button",{className:`ticket-status-btn${s?" verified":""}`,title:e.status.replace("_"," "),children:s?b(G):J(e.status)}),l("span",{className:"ticket-category-badge",style:`background-color:${k(e.category)}`,title:e.category,children:S(e.category)}),l("span",{className:"ticket-number",children:e.ticket_number}),l("input",{type:"text",className:"ticket-title-input",value:e.title}),l("span",{className:"ticket-priority-indicator",style:`color:${A(e.priority)}`,title:e.priority,children:Y(e.priority)}),l("button",{className:`ticket-star${e.up_next?" active":""}`,title:e.up_next?"Remove from Up Next":"Add to Up Next",children:e.up_next?"\u2605":"\u2606"})]}));a.addEventListener("mousedown",m=>{(m.metaKey||m.ctrlKey||m.shiftKey)&&(m.preventDefault(),ae(m,e)&&m.stopPropagation())});let o=a.querySelector(".ticket-checkbox");o.addEventListener("click",m=>m.stopPropagation()),o.addEventListener("change",()=>{o.checked?n.selectedIds.add(e.id):n.selectedIds.delete(e.id),n.lastClickedId=e.id,y()}),a.querySelector(".ticket-status-btn").addEventListener("click",m=>{m.stopPropagation(),_e(e)});let d=a.querySelector(".ticket-category-badge");d.addEventListener("click",m=>{m.stopPropagation(),Be(d,e)});let r=a.querySelector(".ticket-title-input");r.addEventListener("focus",()=>{I||n.selectedIds.size===1&&n.selectedIds.has(e.id)||(n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,O(),B())}),r.addEventListener("input",()=>{Me(e.id,{title:r.value})}),r.addEventListener("keydown",m=>{Le(m,e,r)});let u=a.querySelector(".ticket-priority-indicator");return u.addEventListener("click",m=>{m.stopPropagation(),De(u,e)}),a.querySelector(".ticket-star").addEventListener("click",m=>{m.stopPropagation(),He(e)}),a}function we(e){let t=n.selectedIds.has(e.id),i=e.deleted_at?new Date(e.deleted_at):null,s=f(l("div",{className:`ticket-row trash-row${t?" selected":""}`,"data-id":String(e.id),children:[l("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),l("span",{className:"ticket-category-badge",style:`background-color:${k(e.category)}`,children:S(e.category)}),l("span",{className:"ticket-number",children:e.ticket_number}),l("span",{className:"ticket-title-input trash-title",style:"cursor:default",children:e.title}),l("span",{className:"ticket-number",title:i?`Deleted: ${i.toLocaleString()}`:"",children:i?i.toLocaleDateString():""}),l("button",{className:"btn btn-sm",title:"Restore from trash",children:"Restore"})]}));s.addEventListener("mousedown",o=>{(o.metaKey||o.ctrlKey||o.shiftKey)&&(o.preventDefault(),ae(o,e)&&o.stopPropagation())});let a=s.querySelector(".ticket-checkbox");return a.addEventListener("click",o=>o.stopPropagation()),a.addEventListener("change",()=>{a.checked?n.selectedIds.add(e.id):n.selectedIds.delete(e.id),n.lastClickedId=e.id,y()}),s.querySelector(".trash-title").addEventListener("click",()=>{n.selectedIds.size===1&&n.selectedIds.has(e.id)||(n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,O(),B())}),s.querySelector(".btn").addEventListener("click",async o=>{o.stopPropagation(),await c(`/tickets/${e.id}/restore`,{method:"POST"}),p()}),s}function ae(e,t){let i=e.metaKey||e.ctrlKey,s=e.shiftKey;if(i)n.selectedIds.has(t.id)?n.selectedIds.delete(t.id):n.selectedIds.add(t.id),n.lastClickedId=t.id,y();else if(s&&n.lastClickedId!=null){let a=n.tickets.map(r=>r.id),o=a.indexOf(n.lastClickedId),d=a.indexOf(t.id);if(o!==-1&&d!==-1){let r=Math.min(o,d),u=Math.max(o,d);n.selectedIds.clear();for(let m=r;m<=u;m++)n.selectedIds.add(a[m])}y()}else return!1;return!0}function Le(e,t,i){if(e.key==="Enter")e.preventDefault(),g();else if(e.key==="Backspace"&&i.value==="")e.preventDefault(),Ce(t.id);else if(e.key==="ArrowDown"&&e.shiftKey)e.preventDefault(),ne(t.id,1);else if(e.key==="ArrowUp"&&e.shiftKey)e.preventDefault(),ne(t.id,-1);else if(e.key==="ArrowDown")e.preventDefault(),Se(t.id);else if(e.key==="ArrowUp")e.preventDefault(),xe(t.id);else if((e.metaKey||e.ctrlKey)&&!e.altKey&&M.some(s=>s.key===e.key)){e.preventDefault();let s=M.find(a=>a.key===e.key);ie(t,"category",s.value)}else if(e.altKey&&!e.metaKey&&!e.ctrlKey&&R.some(s=>s.key===e.key)){e.preventDefault();let s=R.find(a=>a.key===e.key);ie(t,"priority",s.value)}}function Se(e){let t=n.tickets.findIndex(i=>i.id===e);t<n.tickets.length-1&&document.querySelector(`.ticket-row[data-id="${n.tickets[t+1].id}"] .ticket-title-input`)?.focus()}function xe(e){let t=n.tickets.findIndex(i=>i.id===e);t>0?document.querySelector(`.ticket-row[data-id="${n.tickets[t-1].id}"] .ticket-title-input`)?.focus():g()}function ne(e,t){let s=n.tickets.findIndex(d=>d.id===e)+t;if(s<0||s>=n.tickets.length)return;let a=n.tickets[s].id;n.selectedIds.add(e),n.selectedIds.has(a)?n.selectedIds.delete(e):n.selectedIds.add(a),I=!0,document.querySelector(`.ticket-row[data-id="${a}"] .ticket-title-input`)?.focus(),I=!1,O(),B()}async function _e(e){let i={not_started:"started",started:"completed",completed:"verified",verified:"not_started"}[e.status]||"not_started",s=await c(`/tickets/${e.id}`,{method:"PATCH",body:{status:i}});Object.assign(e,s),y()}async function He(e){if(!e.up_next&&(e.status==="completed"||e.status==="verified")){if(!confirm("This ticket is already done. Would you like to reopen it and add it to Up Next?"))return;let i=await c(`/tickets/${e.id}`,{method:"PATCH",body:{status:"not_started",up_next:!0}});Object.assign(e,i),y();return}let t=await c(`/tickets/${e.id}/up-next`,{method:"POST"});Object.assign(e,t),y()}async function ie(e,t,i){let s=await c(`/tickets/${e.id}`,{method:"PATCH",body:{[t]:i}});Object.assign(e,s),y()}async function Ce(e){let t=n.tickets.findIndex(i=>i.id===e);if(await c(`/tickets/${e}`,{method:"DELETE"}),n.tickets=n.tickets.filter(i=>i.id!==e),n.selectedIds.delete(e),y(),t>0&&n.tickets.length>0){let i=Math.min(t-1,n.tickets.length-1);document.querySelector(`.ticket-row[data-id="${n.tickets[i].id}"] .ticket-title-input`)?.focus()}else g()}function Me(e,t){$&&clearTimeout($),$=setTimeout(()=>{c(`/tickets/${e}`,{method:"PATCH",body:t})},300)}function Be(e,t){C();let s=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",a=H(e,M.map(o=>({label:o.label,key:o.key,shortcut:`${s}${o.key.toUpperCase()}`,color:k(o.value),active:t.category===o.value,action:async()=>{let d=await c(`/tickets/${t.id}`,{method:"PATCH",body:{category:o.value}});Object.assign(t,d),y()}})));document.body.appendChild(a),_(a,e),a.style.visibility=""}function De(e,t){C();let i=H(e,R.map(s=>({label:s.label,key:s.key,shortcut:`Alt+${s.key}`,color:A(s.value),active:t.priority===s.value,action:async()=>{let a=await c(`/tickets/${t.id}`,{method:"PATCH",body:{priority:s.value}});Object.assign(t,a),y()}})));document.body.appendChild(i),_(i,e),i.style.visibility=""}function O(){document.querySelectorAll(".ticket-row[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10),i=e.querySelector(".ticket-checkbox");n.selectedIds.has(t)?(e.classList.add("selected"),i&&(i.checked=!0)):(e.classList.remove("selected"),i&&(i.checked=!1))})}function B(){let e=n.selectedIds.size,t=n.tickets.length,i=e>0,s=n.view==="trash",a=document.getElementById("batch-select-all");a.checked=t>0&&e===t,a.indeterminate=e>0&&e<t,document.getElementById("batch-count").textContent=i?`${e} selected`:"";let o=["batch-category","batch-priority","batch-status","batch-upnext","batch-delete"];for(let v of o){let w=document.getElementById(v);w.style.display=s?"none":"",s||(w.disabled=!i)}let d=document.getElementById("batch-restore"),r=document.getElementById("batch-empty-trash");if(s){let v=document.getElementById("batch-toolbar");d||(d=f(l("button",{id:"batch-restore",className:"btn btn-sm",children:"Restore"})),d.addEventListener("click",async()=>{await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"restore"}}),n.selectedIds.clear(),p()}),v.insertBefore(d,document.getElementById("batch-count"))),d.disabled=!i,d.style.display="",r||(r=f(l("button",{id:"batch-empty-trash",className:"btn btn-sm btn-danger",children:"Empty Trash"})),r.addEventListener("click",async()=>{confirm("Permanently delete all items in trash? This cannot be undone.")&&(await c("/trash/empty",{method:"POST"}),n.selectedIds.clear(),p())}),v.insertBefore(r,document.getElementById("batch-count"))),r.disabled=t===0,r.style.display=""}else d&&(d.style.display="none"),r&&(r.style.display="none");let u=document.querySelector(".batch-star-icon"),m=document.getElementById("batch-upnext");if(!s&&u&&i){let v=n.tickets.filter(E=>n.selectedIds.has(E.id)),w=v.every(E=>E.up_next),oe=v.every(E=>!E.up_next);w?(u.textContent="\u2605",m.classList.add("active"),m.classList.remove("mixed")):oe?(u.textContent="\u2606",m.classList.remove("active","mixed")):(u.innerHTML=l("span",{className:"star-mixed-wrap",children:[l("span",{className:"star-mixed-fill",children:"\u2605"}),"\u2606"]}).toString(),m.classList.remove("active"),m.classList.add("mixed"))}else u&&(u.textContent="\u2606",m.classList.remove("active","mixed"));Q()}async function p(){let e=new URLSearchParams;n.view==="trash"?e.set("status","deleted"):n.view==="up-next"?e.set("up_next","true"):n.view==="open"?e.set("status","open"):n.view==="completed"?e.set("status","completed"):n.view==="verified"?e.set("status","verified"):n.view.startsWith("category:")?e.set("category",n.view.split(":")[1]):n.view.startsWith("priority:")&&e.set("priority",n.view.split(":")[1]),n.search&&e.set("search",n.search),e.set("sort_by",n.sortBy),e.set("sort_dir",n.sortDir);let t=e.toString();n.tickets=await c(`/tickets${t?"?"+t:""}`),y()}async function Ae(){await Pe(),await p(),Re(),Oe(),qe(),Ke(),Ue(),ze(),Ne(),$e(),te(),Fe(),document.addEventListener("hotsheet:render",()=>y()),g()}async function Pe(){try{let e=await c("/settings");(e.detail_position==="side"||e.detail_position==="bottom")&&(n.settings.detail_position=e.detail_position),e.detail_width&&(n.settings.detail_width=parseInt(e.detail_width,10)||360),e.detail_height&&(n.settings.detail_height=parseInt(e.detail_height,10)||300),e.trash_cleanup_days&&(n.settings.trash_cleanup_days=parseInt(e.trash_cleanup_days,10)||3),e.verified_cleanup_days&&(n.settings.verified_cleanup_days=parseInt(e.verified_cleanup_days,10)||30)}catch{}P(n.settings.detail_position),N()}function Ne(){let e=document.getElementById("settings-overlay"),t=document.getElementById("settings-close");document.getElementById("settings-btn").addEventListener("click",()=>{document.getElementById("settings-detail-position").value=n.settings.detail_position,document.getElementById("settings-trash-days").value=String(n.settings.trash_cleanup_days),document.getElementById("settings-verified-days").value=String(n.settings.verified_cleanup_days),e.style.display="flex"}),t.addEventListener("click",()=>{e.style.display="none"}),e.addEventListener("click",u=>{u.target===e&&(e.style.display="none")});let s=document.getElementById("settings-detail-position");s.addEventListener("change",()=>{n.settings.detail_position=s.value,P(n.settings.detail_position),N(),c("/settings",{method:"PATCH",body:{detail_position:s.value}})});let a=document.getElementById("settings-trash-days"),o=null;a.addEventListener("input",()=>{o&&clearTimeout(o),o=setTimeout(()=>{let u=Math.max(1,parseInt(a.value,10)||3);a.value=String(u),n.settings.trash_cleanup_days=u,c("/settings",{method:"PATCH",body:{trash_cleanup_days:String(u)}})},500)});let d=document.getElementById("settings-verified-days"),r=null;d.addEventListener("input",()=>{r&&clearTimeout(r),r=setTimeout(()=>{let u=Math.max(1,parseInt(d.value,10)||30);d.value=String(u),n.settings.verified_cleanup_days=u,c("/settings",{method:"PATCH",body:{verified_cleanup_days:String(u)}})},500)})}function $e(){let e=document.getElementById("copy-prompt-section"),t=document.getElementById("copy-prompt-btn"),i=document.getElementById("copy-prompt-label"),s=document.getElementById("copy-prompt-icon"),a="";c("/worklist-info").then(o=>{a=o.prompt,e.style.display="",o.skillCreated&&console.log("Hot Sheet: Created /hotsheet skill in .claude/skills/hotsheet/")}),t.addEventListener("click",()=>{a!==""&&navigator.clipboard.writeText(a).then(()=>{i.textContent="Copied!",s.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg>',setTimeout(()=>{i.textContent="Copy AI prompt",s.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>'},1500)})})}function Re(){let e=document.querySelectorAll(".sidebar-item[data-view]");e.forEach(t=>{t.addEventListener("click",()=>{e.forEach(i=>{i.classList.remove("active")}),t.classList.add("active"),n.view=t.dataset.view,n.selectedIds.clear(),p()})})}function Oe(){let e=document.getElementById("sort-select");e.addEventListener("change",()=>{let[t,i]=e.value.split(":");n.sortBy=t,n.sortDir=i,p()})}var q=null;function qe(){let e=document.getElementById("search-input");e.addEventListener("input",()=>{q&&clearTimeout(q),q=setTimeout(()=>{n.search=e.value,p()},200)}),e.addEventListener("keydown",t=>{t.key==="Escape"&&(e.value="",n.search="",p())})}function Ke(){let e=document.getElementById("batch-category");e.addEventListener("change",async()=>{e.value&&(await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"category",value:e.value}}),e.value="",p())});let t=document.getElementById("batch-priority");t.addEventListener("change",async()=>{t.value&&(await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"priority",value:t.value}}),t.value="",p())});let i=document.getElementById("batch-status");i.addEventListener("change",async()=>{i.value&&(await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"status",value:i.value}}),i.value="",p())}),document.getElementById("batch-upnext").addEventListener("click",async()=>{let s=n.tickets.filter(d=>n.selectedIds.has(d.id)),o=!s.every(d=>d.up_next);if(o){let d=s.filter(r=>r.status==="completed"||r.status==="verified");if(d.length>0){if(!confirm("Some selected tickets are already done. Would you like to reopen them and add them to Up Next?"))return;await c("/tickets/batch",{method:"POST",body:{ids:d.map(r=>r.id),action:"status",value:"not_started"}})}}await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"up_next",value:o}}),p()}),document.getElementById("batch-delete").addEventListener("click",async()=>{let s=n.selectedIds.size;confirm(`Delete ${s} ticket(s)?`)&&(await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"delete"}}),n.selectedIds.clear(),p())}),document.getElementById("batch-select-all").addEventListener("change",s=>{if(s.target.checked)for(let o of n.tickets)n.selectedIds.add(o.id);else n.selectedIds.clear();y()})}var K=null;function Ue(){document.getElementById("detail-close").addEventListener("click",X);let e=["detail-title","detail-details"];for(let i of e){let s=document.getElementById(i);s.addEventListener("input",()=>{K&&clearTimeout(K),K=setTimeout(()=>{if(n.activeTicketId==null)return;let a=i.replace("detail-","");c(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{[a]:s.value}}).then(()=>{p()})},300)})}let t=["detail-category","detail-priority","detail-status"];for(let i of t){let s=document.getElementById(i);s.addEventListener("change",async()=>{if(n.activeTicketId==null)return;let a=i.replace("detail-","");await c(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{[a]:s.value}}),p()})}document.getElementById("detail-upnext").addEventListener("change",async()=>{if(n.activeTicketId==null)return;let i=n.tickets.find(a=>a.id===n.activeTicketId),s=document.getElementById("detail-upnext");if(s.checked&&i&&(i.status==="completed"||i.status==="verified")){if(!confirm("This ticket is already done. Would you like to reopen it and add it to Up Next?")){s.checked=!1;return}await c(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{status:"not_started",up_next:!0}})}else await c(`/tickets/${n.activeTicketId}/up-next`,{method:"POST"});p(),x(n.activeTicketId)}),document.getElementById("detail-file-input").addEventListener("change",async i=>{let s=i.target,a=s.files?.[0];!a||n.activeTicketId==null||(await W(`/tickets/${n.activeTicketId}/attachments`,a),s.value="",x(n.activeTicketId),p())}),document.getElementById("detail-attachments").addEventListener("click",async i=>{let a=i.target.closest(".attachment-delete");if(a===null)return;let o=a.dataset.attId;o===void 0||o===""||(await c(`/attachments/${o}`,{method:"DELETE"}),n.activeTicketId!=null&&x(n.activeTicketId))})}function ze(){document.addEventListener("keydown",e=>{let t=e.target.tagName,i=t==="INPUT"||t==="TEXTAREA"||t==="SELECT",s=document.getElementById("settings-overlay");if(e.key==="Escape"&&s.style.display!=="none"){s.style.display="none";return}if(e.key==="Escape"){n.selectedIds.size>0&&(n.selectedIds.clear(),y());return}if((e.metaKey||e.ctrlKey)&&e.key==="a"&&!i){e.preventDefault(),n.selectedIds.clear();for(let a of n.tickets)n.selectedIds.add(a.id);y();return}if((e.metaKey||e.ctrlKey)&&e.key==="d"){if(n.selectedIds.size>0){e.preventDefault();let a=n.tickets.filter(r=>n.selectedIds.has(r.id)),d=!a.every(r=>r.up_next);if(d){let r=a.filter(u=>u.status==="completed"||u.status==="verified");if(r.length>0){if(!confirm("Some selected tickets are already done. Would you like to reopen them and add them to Up Next?"))return;c("/tickets/batch",{method:"POST",body:{ids:r.map(u=>u.id),action:"status",value:"not_started"}}).then(()=>c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"up_next",value:!0}})).then(()=>{p()});return}}c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"up_next",value:d}}).then(()=>{p()})}return}if((e.metaKey||e.ctrlKey)&&e.key==="n"){e.preventDefault(),g();return}if((e.metaKey||e.ctrlKey)&&e.key==="f"){e.preventDefault(),document.getElementById("search-input").focus();return}if(e.key==="n"&&!i){e.preventDefault(),g();return}})}var U=0;function Fe(){async function e(){try{let t=await c(`/poll?version=${U}`);t.version>U&&(U=t.version,p())}catch{await new Promise(t=>setTimeout(t,5e3))}setTimeout(e,100)}e()}Ae();})();
1
+ "use strict";(()=>{var le=Object.defineProperty;var de=(e,t,i)=>t in e?le(e,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[t]=i;var j=(e,t,i)=>de(e,typeof t!="symbol"?t+"":t,i);function F(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function V(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var h=class{constructor(t){j(this,"__html");this.__html=t}toString(){return this.__html}};function k(e){return new h(e)}var ce=new Set(["area","base","br","col","embed","hr","img","input","link","meta","source","track","wbr"]);function D(e){return e==null||typeof e=="boolean"?"":e instanceof h?e.__html:typeof e=="string"?F(e):typeof e=="number"?String(e):Array.isArray(e)?e.map(D).join(""):""}function ue(e,t){if(t==null||t===!1)return"";if(t===!0)return` ${e}`;let i=e==="className"?"class":e==="htmlFor"?"for":e,s;return t instanceof h?s=t.__html:typeof t=="number"?s=String(t):typeof t=="string"?s=V(t):s="",` ${i}="${s}"`}function l(e,t){if(typeof e=="function")return e(t);let{children:i,...s}=t,a=Object.entries(s).map(([d,r])=>ue(d,r)).join("");if(ce.has(e))return new h(`<${e}${a}>`);let o=i!=null?D(i):"";return new h(`<${e}${a}>${o}</${e}>`)}function L({children:e}){return new h(e!=null?D(e):"")}function y(e){let t=document.createElement("template");return t.innerHTML=e.toString(),t.content.firstElementChild}function W(e){document.getElementById("network-error-popup")?.remove();let t=y(l("div",{id:"network-error-popup",className:"error-popup",children:l("div",{className:"error-popup-content",children:[l("strong",{children:"Connection Error"}),l("p",{children:e}),l("button",{children:k("Dismiss")})]})}));t.querySelector("button").addEventListener("click",()=>t.remove()),document.body.appendChild(t)}async function c(e,t={}){try{return(await fetch("/api"+e,{headers:t.body!==void 0?{"Content-Type":"application/json"}:{},method:t.method,body:t.body!==void 0?JSON.stringify(t.body):void 0})).json()}catch(i){throw W("Unable to reach the server. It may have been stopped."),i}}async function G(e,t){try{let i=new FormData;return i.append("file",t),(await fetch("/api"+e,{method:"POST",body:i})).json()}catch(i){throw W("Unable to reach the server. It may have been stopped."),i}}var pe={detail_position:"side",detail_width:360,detail_height:300,trash_cleanup_days:3,verified_cleanup_days:30},n={tickets:[],selectedIds:new Set,lastClickedId:null,activeTicketId:null,view:"all",sortBy:"created",sortDir:"desc",search:"",settings:{...pe}},me={issue:"#6b7280",bug:"#ef4444",feature:"#22c55e",requirement_change:"#f97316",task:"#3b82f6",investigation:"#8b5cf6"},fe={issue:"ISS",bug:"BUG",feature:"FEA",requirement_change:"REQ",task:"TSK",investigation:"INV"},ye={highest:"\u2B06\u2B06",high:"\u2B06",default:"\u2014",low:"\u2B07",lowest:"\u2B07\u2B07"},ge={highest:"#ef4444",high:"#f97316",default:"#6b7280",low:"#3b82f6",lowest:"#94a3b8"},he={not_started:"\u25CB",started:"\u25D4",completed:"\u2713",verified:"svg"},Y='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 7 17l-5-5"/><path d="m22 10-9.5 9.5-2-2"/></svg>';function b(e){return me[e]||"#6b7280"}function S(e){return fe[e]||"ISS"}function J(e){return ye[e]||"\u2014"}function A(e){return ge[e]||"#6b7280"}function X(e){return he[e]||"\u25CB"}function x(e){n.activeTicketId=e,ee(e)}function Q(){n.selectedIds.clear(),n.activeTicketId=null;let e=new CustomEvent("hotsheet:render");document.dispatchEvent(e)}function Z(){let e=n.view==="trash",t=document.getElementById("detail-panel"),i=document.getElementById("detail-resize-handle");if(n.selectedIds.size===1&&!e){let s=Array.from(n.selectedIds)[0];t.style.display="flex",i&&(i.style.display=""),n.activeTicketId!==s&&(n.activeTicketId=s,ee(s))}else n.activeTicketId!=null&&(n.activeTicketId=null),t.style.display="none",i&&(i.style.display="none")}async function ee(e){let t=await c(`/tickets/${e}`);if(n.activeTicketId!==e)return;document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,document.getElementById("detail-category").value=t.category,document.getElementById("detail-priority").value=t.priority,document.getElementById("detail-status").value=t.status,document.getElementById("detail-upnext").checked=t.up_next,document.getElementById("detail-details").value=t.details;let i=document.getElementById("detail-attachments");t.attachments.length>0?i.innerHTML=l(L,{children:t.attachments.map(r=>l("div",{className:"attachment-item",children:[l("span",{className:"attachment-name",children:r.original_filename}),l("button",{className:"attachment-delete","data-att-id":String(r.id),title:"Remove",children:k("&times;")})]}))}).toString():i.innerHTML="";let s=document.getElementById("detail-notes-section"),a=document.getElementById("detail-notes"),o=ve(t.notes);o.length>0?(s.style.display="",a.innerHTML=l(L,{children:o.map(r=>l("div",{className:"note-entry",children:[r.created_at?l("div",{className:"note-timestamp",children:new Date(r.created_at).toLocaleString()}):null,l("div",{className:"note-text",children:r.text})]}))}).toString()):(s.style.display="none",a.innerHTML="");let d=document.getElementById("detail-meta");d.innerHTML=l(L,{children:[l("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),l("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?l("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?l("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function ve(e){if(!e||e==="")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return e.trim()?[{text:e,created_at:""}]:[]}async function te(){try{let e=await c("/stats"),t=document.getElementById("status-bar");t&&(t.textContent=`${e.total} tickets \xB7 ${e.open} open \xB7 ${e.up_next} up next`)}catch{}}function N(e){let t=document.getElementById("content-area");t.classList.remove("detail-side","detail-bottom"),t.classList.add(e==="bottom"?"detail-bottom":"detail-side")}function P(){let e=document.getElementById("detail-panel");n.settings.detail_position==="bottom"?(e.style.width="",e.style.height=`${n.settings.detail_height}px`):(e.style.height="",e.style.width=`${n.settings.detail_width}px`)}function ne(){let e=document.getElementById("detail-resize-handle"),t=document.getElementById("detail-panel"),i=document.getElementById("content-area"),s=!1;e.addEventListener("mousedown",a=>{a.preventDefault(),s=!0,document.body.style.cursor=n.settings.detail_position==="bottom"?"row-resize":"col-resize",document.body.style.userSelect="none"}),document.addEventListener("mousemove",a=>{if(!s)return;let o=i.getBoundingClientRect();if(n.settings.detail_position==="bottom"){let d=Math.max(150,Math.min(500,o.bottom-a.clientY));n.settings.detail_height=d,t.style.height=`${d}px`}else{let d=Math.max(250,Math.min(600,o.right-a.clientX));n.settings.detail_width=d,t.style.width=`${d}px`}}),document.addEventListener("mouseup",()=>{s&&(s=!1,document.body.style.cursor="",document.body.style.userSelect="",n.settings.detail_position==="bottom"?c("/settings",{method:"PATCH",body:{detail_height:String(n.settings.detail_height)}}):c("/settings",{method:"PATCH",body:{detail_width:String(n.settings.detail_width)}}))})}function _(e,t){let i=t.getBoundingClientRect(),s=e.getBoundingClientRect(),a=window.innerWidth,o=window.innerHeight,d=i.left;d+s.width>a-8&&(d=i.right-s.width),d<8&&(d=8);let r=i.bottom+4;r+s.height>o-8&&(r=i.top-s.height-4),r<8&&(r=8),e.style.left=`${d}px`,e.style.top=`${r}px`}function H(e,t){let i=y(l("div",{className:"dropdown-menu",style:"visibility:hidden;top:0;left:0",children:t.map(r=>l("button",{className:`dropdown-item${r.active?" active":""}`,"data-key":r.key,children:[r.color?l("span",{className:"dropdown-dot",style:`background-color:${r.color}`}):null,l("span",{className:"dropdown-label",children:r.label}),r.shortcut?l("kbd",{className:"dropdown-kbd",children:r.shortcut}):null]}))}));i.querySelectorAll(".dropdown-item").forEach((r,u)=>{r.addEventListener("click",()=>{t[u].action(),i.remove()})});function a(r){let u=t.find(p=>r.key.toLowerCase()===p.key.toLowerCase());u?(r.preventDefault(),r.stopPropagation(),u.action(),o()):r.key==="Escape"&&(r.preventDefault(),o())}function o(){i.remove(),document.removeEventListener("keydown",a,!0),document.removeEventListener("click",d)}function d(){o()}return document.addEventListener("keydown",a,!0),setTimeout(()=>{document.addEventListener("click",d)},0),i}function C(){document.querySelectorAll(".dropdown-menu").forEach(e=>{e.remove()})}var $=null,E=!1,I=null,R="",M=[{key:"i",value:"issue",label:"Issue"},{key:"b",value:"bug",label:"Bug"},{key:"f",value:"feature",label:"Feature"},{key:"r",value:"requirement_change",label:"Req Change"},{key:"k",value:"task",label:"Task"},{key:"g",value:"investigation",label:"Investigation"}],O=[{key:"1",value:"highest",label:"Highest"},{key:"2",value:"high",label:"High"},{key:"3",value:"default",label:"Default"},{key:"4",value:"low",label:"Low"},{key:"5",value:"lowest",label:"Lowest"}];function ke(){let e=document.activeElement;if(!e||!(e instanceof HTMLElement))return null;let t=e.closest(".ticket-row");if(!t)return null;if(t.classList.contains("draft-row"))return"draft";let i=t.dataset.id;return i!==void 0&&i!==""?parseInt(i,10):null}function be(e){e!=null&&(E=!0,e==="draft"?g():document.querySelector(`.ticket-row[data-id="${e}"] .ticket-title-input`)?.focus(),E=!1)}function f(){let e=n.view==="trash",t=ke(),i=null;if(t!=null&&t!=="draft"){let a=document.querySelector(`.ticket-row[data-id="${t}"] .ticket-title-input`);a&&(i=a.value)}let s=document.getElementById("ticket-list");s.innerHTML="",e||s.appendChild(Te()),e&&n.tickets.length===0&&s.appendChild(y(l("div",{className:"ticket-list-empty",children:"Trash is empty"})));for(let a of n.tickets)s.appendChild(e?Le(a):we(a));if(t!=null&&t!=="draft"&&i!=null){let a=document.querySelector(`.ticket-row[data-id="${t}"] .ticket-title-input`);a&&a.value!==i&&(a.value=i)}be(t),B(),te()}function Te(){let e=ae(),t=n.view.startsWith("category:"),i=y(l("div",{className:"ticket-row draft-row",children:[l("span",{className:"ticket-checkbox-spacer"}),l("span",{className:"ticket-status-btn draft-placeholder",children:"\u25CB"}),l("span",{className:"ticket-category-badge draft-badge",style:`background-color:${b(e)}${t?"":";cursor:pointer;opacity:1"}`,children:S(e)}),l("span",{className:"ticket-number draft-number"}),l("input",{type:"text",className:"ticket-title-input draft-input",placeholder:"New ticket...",value:R}),l("span",{className:"ticket-priority-indicator draft-placeholder"}),l("span",{className:"ticket-star draft-placeholder"})]}));if(!t){let a=i.querySelector(".ticket-category-badge");a.addEventListener("click",o=>{o.stopPropagation(),Ie(a)})}let s=i.querySelector(".draft-input");return s.addEventListener("input",()=>{R=s.value}),s.addEventListener("keydown",async a=>{if(a.key==="Enter"&&s.value.trim()){a.preventDefault();let o=s.value.trim();R="",s.value="";let d=Ee();I&&!n.view.startsWith("category:")&&(d.category=I);let r=await c("/tickets",{method:"POST",body:{title:o,defaults:d}});r&&(n.selectedIds.clear(),n.selectedIds.add(r.id)),await m(),g()}else a.key==="ArrowDown"&&(a.preventDefault(),n.tickets.length>0&&document.querySelector(`.ticket-row[data-id="${n.tickets[0].id}"] .ticket-title-input`)?.focus())}),i}function g(){document.querySelector(".draft-row .draft-input")?.focus()}function Ee(){let e=n.view;return e==="up-next"?{up_next:!0}:e==="open"?{}:e==="completed"?{status:"completed"}:e.startsWith("category:")?{category:e.split(":")[1]}:e.startsWith("priority:")?{priority:e.split(":")[1]}:{}}function ae(){if(I)return I;let e=n.view;return e.startsWith("category:")?e.split(":")[1]:"issue"}function Ie(e){C();let i=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",s=ae(),a=H(e,M.map(o=>({label:o.label,key:o.key,shortcut:`${i}${o.key.toUpperCase()}`,color:b(o.value),active:s===o.value,action:()=>{I=o.value,f(),g()}})));document.body.appendChild(a),_(a,e),a.style.visibility=""}function we(e){let t=n.selectedIds.has(e.id),i=e.status==="completed"||e.status==="verified",s=e.status==="verified",a=y(l("div",{className:`ticket-row${t?" selected":""}${i?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[l("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),l("button",{className:`ticket-status-btn${s?" verified":""}`,title:e.status.replace("_"," "),children:s?k(Y):X(e.status)}),l("span",{className:"ticket-category-badge",style:`background-color:${b(e.category)}`,title:e.category,children:S(e.category)}),l("span",{className:"ticket-number",children:e.ticket_number}),l("input",{type:"text",className:"ticket-title-input",value:e.title}),l("span",{className:"ticket-priority-indicator",style:`color:${A(e.priority)}`,title:e.priority,children:J(e.priority)}),l("button",{className:`ticket-star${e.up_next?" active":""}`,title:e.up_next?"Remove from Up Next":"Add to Up Next",children:e.up_next?"\u2605":"\u2606"})]}));a.addEventListener("mousedown",p=>{(p.metaKey||p.ctrlKey||p.shiftKey)&&(p.preventDefault(),oe(p,e)&&p.stopPropagation())});let o=a.querySelector(".ticket-checkbox");o.addEventListener("click",p=>p.stopPropagation()),o.addEventListener("change",()=>{o.checked?n.selectedIds.add(e.id):n.selectedIds.delete(e.id),n.lastClickedId=e.id,f()}),a.querySelector(".ticket-status-btn").addEventListener("click",p=>{p.stopPropagation(),He(e)});let d=a.querySelector(".ticket-category-badge");d.addEventListener("click",p=>{p.stopPropagation(),De(d,e)});let r=a.querySelector(".ticket-title-input");r.addEventListener("focus",()=>{E||n.selectedIds.size===1&&n.selectedIds.has(e.id)||(n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,q(),B())}),r.addEventListener("input",()=>{Be(e.id,{title:r.value})}),r.addEventListener("keydown",p=>{Se(p,e,r)});let u=a.querySelector(".ticket-priority-indicator");return u.addEventListener("click",p=>{p.stopPropagation(),Ae(u,e)}),a.querySelector(".ticket-star").addEventListener("click",p=>{p.stopPropagation(),Ce(e)}),a}function Le(e){let t=n.selectedIds.has(e.id),i=e.deleted_at?new Date(e.deleted_at):null,s=y(l("div",{className:`ticket-row trash-row${t?" selected":""}`,"data-id":String(e.id),children:[l("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),l("span",{className:"ticket-category-badge",style:`background-color:${b(e.category)}`,children:S(e.category)}),l("span",{className:"ticket-number",children:e.ticket_number}),l("span",{className:"ticket-title-input trash-title",style:"cursor:default",children:e.title}),l("span",{className:"ticket-number",title:i?`Deleted: ${i.toLocaleString()}`:"",children:i?i.toLocaleDateString():""}),l("button",{className:"btn btn-sm",title:"Restore from trash",children:"Restore"})]}));s.addEventListener("mousedown",o=>{(o.metaKey||o.ctrlKey||o.shiftKey)&&(o.preventDefault(),oe(o,e)&&o.stopPropagation())});let a=s.querySelector(".ticket-checkbox");return a.addEventListener("click",o=>o.stopPropagation()),a.addEventListener("change",()=>{a.checked?n.selectedIds.add(e.id):n.selectedIds.delete(e.id),n.lastClickedId=e.id,f()}),s.querySelector(".trash-title").addEventListener("click",()=>{n.selectedIds.size===1&&n.selectedIds.has(e.id)||(n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,q(),B())}),s.querySelector(".btn").addEventListener("click",async o=>{o.stopPropagation(),await c(`/tickets/${e.id}/restore`,{method:"POST"}),m()}),s}function oe(e,t){let i=e.metaKey||e.ctrlKey,s=e.shiftKey;if(i)n.selectedIds.has(t.id)?n.selectedIds.delete(t.id):n.selectedIds.add(t.id),n.lastClickedId=t.id,f();else if(s&&n.lastClickedId!=null){let a=n.tickets.map(r=>r.id),o=a.indexOf(n.lastClickedId),d=a.indexOf(t.id);if(o!==-1&&d!==-1){let r=Math.min(o,d),u=Math.max(o,d);n.selectedIds.clear();for(let p=r;p<=u;p++)n.selectedIds.add(a[p])}f()}else return!1;return!0}function Se(e,t,i){if(e.key==="Enter")e.preventDefault(),g();else if(e.key==="Backspace"&&i.value==="")e.preventDefault(),Me(t.id);else if(e.key==="ArrowDown"&&e.shiftKey)e.preventDefault(),ie(t.id,1);else if(e.key==="ArrowUp"&&e.shiftKey)e.preventDefault(),ie(t.id,-1);else if(e.key==="ArrowDown")e.preventDefault(),xe(t.id);else if(e.key==="ArrowUp")e.preventDefault(),_e(t.id);else if((e.metaKey||e.ctrlKey)&&!e.altKey&&M.some(s=>s.key===e.key)){e.preventDefault();let s=M.find(a=>a.key===e.key);se(t,"category",s.value)}else if(e.altKey&&!e.metaKey&&!e.ctrlKey&&O.some(s=>s.key===e.key)){e.preventDefault();let s=O.find(a=>a.key===e.key);se(t,"priority",s.value)}}function xe(e){let t=n.tickets.findIndex(i=>i.id===e);t<n.tickets.length-1&&document.querySelector(`.ticket-row[data-id="${n.tickets[t+1].id}"] .ticket-title-input`)?.focus()}function _e(e){let t=n.tickets.findIndex(i=>i.id===e);t>0?document.querySelector(`.ticket-row[data-id="${n.tickets[t-1].id}"] .ticket-title-input`)?.focus():g()}function ie(e,t){let s=n.tickets.findIndex(d=>d.id===e)+t;if(s<0||s>=n.tickets.length)return;let a=n.tickets[s].id;n.selectedIds.add(e),n.selectedIds.has(a)?n.selectedIds.delete(e):n.selectedIds.add(a),E=!0,document.querySelector(`.ticket-row[data-id="${a}"] .ticket-title-input`)?.focus(),E=!1,q(),B()}async function He(e){let i={not_started:"started",started:"completed",completed:"verified",verified:"not_started"}[e.status]||"not_started",s=await c(`/tickets/${e.id}`,{method:"PATCH",body:{status:i}});Object.assign(e,s),f()}async function Ce(e){if(!e.up_next&&(e.status==="completed"||e.status==="verified")){if(!confirm("This ticket is already done. Would you like to reopen it and add it to Up Next?"))return;let i=await c(`/tickets/${e.id}`,{method:"PATCH",body:{status:"not_started",up_next:!0}});Object.assign(e,i),f();return}let t=await c(`/tickets/${e.id}/up-next`,{method:"POST"});Object.assign(e,t),f()}async function se(e,t,i){let s=await c(`/tickets/${e.id}`,{method:"PATCH",body:{[t]:i}});Object.assign(e,s),f()}async function Me(e){let t=n.tickets.findIndex(i=>i.id===e);if(await c(`/tickets/${e}`,{method:"DELETE"}),n.tickets=n.tickets.filter(i=>i.id!==e),n.selectedIds.delete(e),f(),t>0&&n.tickets.length>0){let i=Math.min(t-1,n.tickets.length-1);document.querySelector(`.ticket-row[data-id="${n.tickets[i].id}"] .ticket-title-input`)?.focus()}else g()}function Be(e,t){$&&clearTimeout($),$=setTimeout(()=>{c(`/tickets/${e}`,{method:"PATCH",body:t})},300)}function De(e,t){C();let s=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",a=H(e,M.map(o=>({label:o.label,key:o.key,shortcut:`${s}${o.key.toUpperCase()}`,color:b(o.value),active:t.category===o.value,action:async()=>{let d=await c(`/tickets/${t.id}`,{method:"PATCH",body:{category:o.value}});Object.assign(t,d),f()}})));document.body.appendChild(a),_(a,e),a.style.visibility=""}function Ae(e,t){C();let i=H(e,O.map(s=>({label:s.label,key:s.key,shortcut:`Alt+${s.key}`,color:A(s.value),active:t.priority===s.value,action:async()=>{let a=await c(`/tickets/${t.id}`,{method:"PATCH",body:{priority:s.value}});Object.assign(t,a),f()}})));document.body.appendChild(i),_(i,e),i.style.visibility=""}function q(){document.querySelectorAll(".ticket-row[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10),i=e.querySelector(".ticket-checkbox");n.selectedIds.has(t)?(e.classList.add("selected"),i&&(i.checked=!0)):(e.classList.remove("selected"),i&&(i.checked=!1))})}function B(){let e=n.selectedIds.size,t=n.tickets.length,i=e>0,s=n.view==="trash",a=document.getElementById("batch-select-all");a.checked=t>0&&e===t,a.indeterminate=e>0&&e<t,document.getElementById("batch-count").textContent=i?`${e} selected`:"";let o=["batch-category","batch-priority","batch-status","batch-upnext","batch-delete"];for(let v of o){let w=document.getElementById(v);w.style.display=s?"none":"",s||(w.disabled=!i)}let d=document.getElementById("batch-restore"),r=document.getElementById("batch-empty-trash");if(s){let v=document.getElementById("batch-toolbar");d||(d=y(l("button",{id:"batch-restore",className:"btn btn-sm",children:"Restore"})),d.addEventListener("click",async()=>{await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"restore"}}),n.selectedIds.clear(),m()}),v.insertBefore(d,document.getElementById("batch-count"))),d.disabled=!i,d.style.display="",r||(r=y(l("button",{id:"batch-empty-trash",className:"btn btn-sm btn-danger",children:"Empty Trash"})),r.addEventListener("click",async()=>{confirm("Permanently delete all items in trash? This cannot be undone.")&&(await c("/trash/empty",{method:"POST"}),n.selectedIds.clear(),m())}),v.insertBefore(r,document.getElementById("batch-count"))),r.disabled=t===0,r.style.display=""}else d&&(d.style.display="none"),r&&(r.style.display="none");let u=document.querySelector(".batch-star-icon"),p=document.getElementById("batch-upnext");if(!s&&u&&i){let v=n.tickets.filter(T=>n.selectedIds.has(T.id)),w=v.every(T=>T.up_next),re=v.every(T=>!T.up_next);w?(u.textContent="\u2605",p.classList.add("active"),p.classList.remove("mixed")):re?(u.textContent="\u2606",p.classList.remove("active","mixed")):(u.innerHTML=l("span",{className:"star-mixed-wrap",children:[l("span",{className:"star-mixed-fill",children:"\u2605"}),"\u2606"]}).toString(),p.classList.remove("active"),p.classList.add("mixed"))}else u&&(u.textContent="\u2606",p.classList.remove("active","mixed"));Z()}async function m(){let e=new URLSearchParams;n.view==="trash"?e.set("status","deleted"):n.view==="up-next"?e.set("up_next","true"):n.view==="open"?e.set("status","open"):n.view==="completed"?e.set("status","completed"):n.view==="verified"?e.set("status","verified"):n.view.startsWith("category:")?e.set("category",n.view.split(":")[1]):n.view.startsWith("priority:")&&e.set("priority",n.view.split(":")[1]),n.search&&e.set("search",n.search),e.set("sort_by",n.sortBy),e.set("sort_dir",n.sortDir);let t=e.toString();n.tickets=await c(`/tickets${t?"?"+t:""}`),f()}async function Ne(){await Pe(),await m(),Oe(),qe(),Ke(),Ue(),ze(),Ve(),$e(),Re(),ne(),We(),document.addEventListener("hotsheet:render",()=>f()),g()}async function Pe(){try{let e=await c("/settings");(e.detail_position==="side"||e.detail_position==="bottom")&&(n.settings.detail_position=e.detail_position),e.detail_width&&(n.settings.detail_width=parseInt(e.detail_width,10)||360),e.detail_height&&(n.settings.detail_height=parseInt(e.detail_height,10)||300),e.trash_cleanup_days&&(n.settings.trash_cleanup_days=parseInt(e.trash_cleanup_days,10)||3),e.verified_cleanup_days&&(n.settings.verified_cleanup_days=parseInt(e.verified_cleanup_days,10)||30)}catch{}N(n.settings.detail_position),P()}function $e(){let e=document.getElementById("settings-overlay"),t=document.getElementById("settings-close");document.getElementById("settings-btn").addEventListener("click",()=>{document.getElementById("settings-detail-position").value=n.settings.detail_position,document.getElementById("settings-trash-days").value=String(n.settings.trash_cleanup_days),document.getElementById("settings-verified-days").value=String(n.settings.verified_cleanup_days),e.style.display="flex"}),t.addEventListener("click",()=>{e.style.display="none"}),e.addEventListener("click",u=>{u.target===e&&(e.style.display="none")});let s=document.getElementById("settings-detail-position");s.addEventListener("change",()=>{n.settings.detail_position=s.value,N(n.settings.detail_position),P(),c("/settings",{method:"PATCH",body:{detail_position:s.value}})});let a=document.getElementById("settings-trash-days"),o=null;a.addEventListener("input",()=>{o&&clearTimeout(o),o=setTimeout(()=>{let u=Math.max(1,parseInt(a.value,10)||3);a.value=String(u),n.settings.trash_cleanup_days=u,c("/settings",{method:"PATCH",body:{trash_cleanup_days:String(u)}})},500)});let d=document.getElementById("settings-verified-days"),r=null;d.addEventListener("input",()=>{r&&clearTimeout(r),r=setTimeout(()=>{let u=Math.max(1,parseInt(d.value,10)||30);d.value=String(u),n.settings.verified_cleanup_days=u,c("/settings",{method:"PATCH",body:{verified_cleanup_days:String(u)}})},500)})}function Re(){let e=document.getElementById("copy-prompt-section"),t=document.getElementById("copy-prompt-btn"),i=document.getElementById("copy-prompt-label"),s=document.getElementById("copy-prompt-icon"),a="";c("/worklist-info").then(o=>{a=o.prompt,e.style.display="",o.skillCreated&&console.log("Hot Sheet: Created /hotsheet skill in .claude/skills/hotsheet/")}),t.addEventListener("click",()=>{a!==""&&navigator.clipboard.writeText(a).then(()=>{i.textContent="Copied!",s.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg>',setTimeout(()=>{i.textContent="Copy AI prompt",s.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>'},1500)})})}function Oe(){let e=document.querySelectorAll(".sidebar-item[data-view]");e.forEach(t=>{t.addEventListener("click",()=>{e.forEach(i=>{i.classList.remove("active")}),t.classList.add("active"),n.view=t.dataset.view,n.selectedIds.clear(),m()})})}function qe(){let e=document.getElementById("sort-select");e.addEventListener("change",()=>{let[t,i]=e.value.split(":");n.sortBy=t,n.sortDir=i,m()})}var K=null;function Ke(){let e=document.getElementById("search-input");e.addEventListener("input",()=>{K&&clearTimeout(K),K=setTimeout(()=>{n.search=e.value,m()},200)}),e.addEventListener("keydown",t=>{t.key==="Escape"&&(e.value="",n.search="",m())})}function Ue(){let e=document.getElementById("batch-category");e.addEventListener("change",async()=>{e.value&&(await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"category",value:e.value}}),e.value="",m())});let t=document.getElementById("batch-priority");t.addEventListener("change",async()=>{t.value&&(await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"priority",value:t.value}}),t.value="",m())});let i=document.getElementById("batch-status");i.addEventListener("change",async()=>{i.value&&(await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"status",value:i.value}}),i.value="",m())}),document.getElementById("batch-upnext").addEventListener("click",async()=>{let s=n.tickets.filter(d=>n.selectedIds.has(d.id)),o=!s.every(d=>d.up_next);if(o){let d=s.filter(r=>r.status==="completed"||r.status==="verified");if(d.length>0){if(!confirm("Some selected tickets are already done. Would you like to reopen them and add them to Up Next?"))return;await c("/tickets/batch",{method:"POST",body:{ids:d.map(r=>r.id),action:"status",value:"not_started"}})}}await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"up_next",value:o}}),m()}),document.getElementById("batch-delete").addEventListener("click",async()=>{let s=n.selectedIds.size;confirm(`Delete ${s} ticket(s)?`)&&(await c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"delete"}}),n.selectedIds.clear(),m())}),document.getElementById("batch-select-all").addEventListener("change",s=>{if(s.target.checked)for(let o of n.tickets)n.selectedIds.add(o.id);else n.selectedIds.clear();f()})}var U=null;function ze(){document.getElementById("detail-close").addEventListener("click",Q);let e=["detail-title","detail-details"];for(let i of e){let s=document.getElementById(i);s.addEventListener("input",()=>{U&&clearTimeout(U),U=setTimeout(()=>{if(n.activeTicketId==null)return;let a=i.replace("detail-","");c(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{[a]:s.value}}).then(()=>{m()})},300)})}let t=["detail-category","detail-priority","detail-status"];for(let i of t){let s=document.getElementById(i);s.addEventListener("change",async()=>{if(n.activeTicketId==null)return;let a=i.replace("detail-","");await c(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{[a]:s.value}}),m()})}document.getElementById("detail-upnext").addEventListener("change",async()=>{if(n.activeTicketId==null)return;let i=n.tickets.find(a=>a.id===n.activeTicketId),s=document.getElementById("detail-upnext");if(s.checked&&i&&(i.status==="completed"||i.status==="verified")){if(!confirm("This ticket is already done. Would you like to reopen it and add it to Up Next?")){s.checked=!1;return}await c(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{status:"not_started",up_next:!0}})}else await c(`/tickets/${n.activeTicketId}/up-next`,{method:"POST"});m(),x(n.activeTicketId)}),document.getElementById("detail-file-input").addEventListener("change",async i=>{let s=i.target,a=s.files?.[0];!a||n.activeTicketId==null||(await G(`/tickets/${n.activeTicketId}/attachments`,a),s.value="",x(n.activeTicketId),m())}),document.getElementById("detail-attachments").addEventListener("click",async i=>{let a=i.target.closest(".attachment-delete");if(a===null)return;let o=a.dataset.attId;o===void 0||o===""||(await c(`/attachments/${o}`,{method:"DELETE"}),n.activeTicketId!=null&&x(n.activeTicketId))})}function je(e){if(!e||e==="")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return e.trim()?[{text:e,created_at:""}]:[]}function Fe(e){let t=[];t.push(`${e.ticket_number}: ${e.title}`),e.details.trim()&&(t.push(""),t.push(e.details.trim()));let i=je(e.notes);if(i.length>0){t.push("");for(let s of i)t.push(`- ${s.text}`)}return t.join(`
2
+ `)}function Ve(){document.addEventListener("keydown",e=>{let t=e.target.tagName,i=t==="INPUT"||t==="TEXTAREA"||t==="SELECT",s=document.getElementById("settings-overlay");if(e.key==="Escape"&&s.style.display!=="none"){s.style.display="none";return}if(e.key==="Escape"){n.selectedIds.size>0&&(n.selectedIds.clear(),f());return}if((e.metaKey||e.ctrlKey)&&e.key==="a"&&!i){e.preventDefault(),n.selectedIds.clear();for(let a of n.tickets)n.selectedIds.add(a.id);f();return}if((e.metaKey||e.ctrlKey)&&e.key==="d"){if(n.selectedIds.size>0){e.preventDefault();let a=n.tickets.filter(r=>n.selectedIds.has(r.id)),d=!a.every(r=>r.up_next);if(d){let r=a.filter(u=>u.status==="completed"||u.status==="verified");if(r.length>0){if(!confirm("Some selected tickets are already done. Would you like to reopen them and add them to Up Next?"))return;c("/tickets/batch",{method:"POST",body:{ids:r.map(u=>u.id),action:"status",value:"not_started"}}).then(()=>c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"up_next",value:!0}})).then(()=>{m()});return}}c("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"up_next",value:d}}).then(()=>{m()})}return}if((e.metaKey||e.ctrlKey)&&e.key==="c"&&n.selectedIds.size>0){let a=window.getSelection();if(!a||a.isCollapsed||a.toString().trim()===""){e.preventDefault();let d=n.tickets.filter(r=>n.selectedIds.has(r.id)).map(Fe).join(`
3
+
4
+ `);navigator.clipboard.writeText(d);return}}if((e.metaKey||e.ctrlKey)&&e.key==="n"){e.preventDefault(),g();return}if((e.metaKey||e.ctrlKey)&&e.key==="f"){e.preventDefault(),document.getElementById("search-input").focus();return}if(e.key==="n"&&!i){e.preventDefault(),g();return}})}var z=0;function We(){async function e(){try{let t=await c(`/poll?version=${z}`);t.version>z&&(z=t.version,m())}catch{await new Promise(t=>setTimeout(t,5e3))}setTimeout(e,100)}e()}Ne();})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hotsheet",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "A lightweight local project management tool. Create, categorize, and prioritize tickets with a fast bullet-list interface, then export an Up Next worklist for AI tools.",
5
5
  "type": "module",
6
6
  "license": "MIT",