@pimzino/claude-code-spec-workflow
Version:
Automated workflows for Claude Code. Includes spec-driven development (Requirements → Design → Tasks → Implementation) with intelligent task execution, optional steering documents and streamlined bug fix workflow (Report → Analyze → Fix → Verify). We have
49 lines (46 loc) • 42.6 kB
JavaScript
// Production build - optimized for performance
;(()=>{var f=class extends Error{constructor(c,e,t,s){super(c);this.code=e;this.path=t;this.details=s;this.name="ValidationError"}};var S=class{static parseJSON(a){try{return{success:!0,data:JSON.parse(a)}}catch(c){return{success:!1,error:new f(`Failed to parse JSON: ${c instanceof Error?c.message:"Unknown error"}`,"JSON_PARSE_ERROR",void 0,{jsonString:a.substring(0,100)+"..."})}}}static parseDate(a,c){try{if(a instanceof Date)return isNaN(a.getTime())?{success:!1,error:new f("Invalid Date object","INVALID_DATE")}:{success:!0,data:a};if(typeof a=="string"||typeof a=="number"){let e=new Date(a);return isNaN(e.getTime())?c?{success:!0,data:c}:{success:!1,error:new f(`Invalid date format: ${a}`,"INVALID_DATE_FORMAT")}:{success:!0,data:e}}return{success:!1,error:new f(`Unsupported date type: ${typeof a}`,"UNSUPPORTED_DATE_TYPE")}}catch(e){return c?{success:!0,data:c}:{success:!1,error:new f(`Date parsing failed: ${e instanceof Error?e.message:"Unknown error"}`,"DATE_PARSING_ERROR")}}}static parseNumber(a,c,e){try{let t;if(typeof a=="number")t=a;else if(typeof a=="string")t=parseFloat(a);else return{success:!1,error:new f(`Cannot parse number from type: ${typeof a}`,"INVALID_NUMBER_TYPE")};return isNaN(t)?{success:!1,error:new f(`Not a valid number: ${a}`,"NAN_VALUE")}:c!==void 0&&t<c?{success:!1,error:new f(`Number ${t} is below minimum ${c}`,"BELOW_MINIMUM")}:e!==void 0&&t>e?{success:!1,error:new f(`Number ${t} is above maximum ${e}`,"ABOVE_MAXIMUM")}:{success:!0,data:t}}catch(t){return{success:!1,error:new f(`Number parsing failed: ${t instanceof Error?t.message:"Unknown error"}`,"NUMBER_PARSING_ERROR")}}}static parseBoolean(a,c){if(typeof a=="boolean")return{success:!0,data:a};if(typeof a=="string"){let e=a.toLowerCase().trim();if(e==="true"||e==="1"||e==="yes")return{success:!0,data:!0};if(e==="false"||e==="0"||e==="no")return{success:!0,data:!1}}return typeof a=="number"?{success:!0,data:a!==0}:c!==void 0?{success:!0,data:c}:{success:!1,error:new f(`Cannot parse boolean from: ${a}`,"INVALID_BOOLEAN")}}};var E={success(i){return{success:!0,data:i}},error(i){return{success:!1,error:i}},map(i,a){if(i.success)try{return this.success(a(i.data))}catch(c){return this.error(new f(`Transform function failed: ${c instanceof Error?c.message:"Unknown error"}`,"TRANSFORM_ERROR"))}return{success:!1,error:i.error}},flatMap(i,a){if(i.success)try{return a(i.data)}catch(c){return this.error(new f(`FlatMap function failed: ${c instanceof Error?c.message:"Unknown error"}`,"FLATMAP_ERROR"))}return{success:!1,error:i.error}},unwrap(i){if(i.success)return i.data;throw i.error},unwrapOr(i,a){return i.success?i.data:a},combine(i){let a=[];for(let c of i){if(!c.success)return{success:!1,error:c.error};a.push(c.data)}return this.success(a)}};function V(i){let a=S.parseDate(i,new Date);if(!a.success)return console.warn("Invalid date string:",i,a.error.message),"invalid date";let c=a.data,t=Math.abs(new Date().getTime()-c.getTime()),s=Math.floor(t/(1e3*60*60*24)),r=Math.floor(t/(1e3*60*60)),n=Math.floor(t/(1e3*60));return n<1?"just now":n<60?`${n}m ago`:r<24?`${r}h ago`:s<7?`${s}d ago`:c.toLocaleDateString()}function W(i){let a=S.parseDate(i);if(!a.success){let c=a;return E.error(c.error)}return E.map(a,c=>{let t=Math.abs(new Date().getTime()-c.getTime()),s=Math.floor(t/(1e3*60*60*24)),r=Math.floor(t/(1e3*60*60)),n=Math.floor(t/(1e3*60));return n<1?"just now":n<60?`${n}m ago`:r<24?`${r}h ago`:s<7?`${s}d ago`:c.toLocaleDateString()})}var $={"not-started":"bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300",requirements:"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200",design:"bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200",tasks:"bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200","in-progress":"bg-indigo-100 text-indigo-800 dark:bg-indigo-900 dark:text-indigo-200",completed:"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200"};function D(i){return $[i]||$["not-started"]}var _={"not-started":"Not Started",requirements:"Requirements",design:"Design",tasks:"Tasks","in-progress":"In Progress",completed:"Completed"};function L(i){return _[i]||i}async function q(i,a){if(console.log("copyCommand called with:",i,"length:",i?.length),!i){console.warn("No command provided to copy");return}let c=a?.currentTarget||a?.target&&a.target.closest("button")||globalThis.document.activeElement,e=async()=>{if(globalThis.navigator.clipboard)await globalThis.navigator.clipboard.writeText(i);else{let t=globalThis.document.createElement("textarea");return t.value=i,t.style.position="fixed",t.style.opacity="0",globalThis.document.body.appendChild(t),t.select(),new Promise((s,r)=>{try{let n=globalThis.document.execCommand("copy");globalThis.document.body.removeChild(t),n?s():r(new Error("Copy command failed"))}catch(n){globalThis.document.body.removeChild(t),r(n)}})}};try{if(await e(),c){let t=c.innerHTML;c.innerHTML='<i class="fas fa-check"></i> Copied!',c.classList.add("text-green-600","dark:text-green-400"),setTimeout(()=>{c.innerHTML=t,c.classList.remove("text-green-600","dark:text-green-400")},2e3)}console.log("Command copied to clipboard:",i)}catch(t){if(c){let s=c.innerHTML;c.innerHTML='<i class="fas fa-times"></i> Failed',c.classList.add("text-red-600","dark:text-red-400"),setTimeout(()=>{c.innerHTML=s,c.classList.remove("text-red-600","dark:text-red-400")},2e3)}console.error("Failed to copy command:",t)}}function H(i){if(!i?.trim())return"";let a=globalThis.marked;if(!a?.parse)return console.error("Marked library not loaded or incomplete"),i;let c=i.replace(/^(\s*)-\s*\[([ x])\]\s*(\d+(?:\.\d+)*)\.(\s*)(.*?)$/gm,(t,s,r,n,o,d)=>`${s}- [${r}] **${n}.** ${d}${r==="x"?" ✅":""}`),e=new a.Renderer;return e.code=function(t,s){let r="";typeof t=="string"?r=t:t&&typeof t=="object"?r=t.text||t.raw||String(t):r=String(t||"");let n=r.replace(/[&<>"']/g,g=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[g]||g),o=globalThis.btoa(unescape(encodeURIComponent(r))),d=s?` language-${s}`:"";return`<div class="code-block-wrapper relative group">
<pre data-code-content="${o}"><code class="hljs${d}">${n}</code></pre>
<button class="code-copy-btn" title="Copy code">
<i class="fas fa-copy"></i>
<span>Copy</span>
</button>
</div>`},a.parse(c,{renderer:e})}var F=["GIVEN","WHEN","THEN","IF","SHALL NOT","SHALL"];function G(i){let a=i;return a=a.replace(/\*\*(GIVEN|WHEN|THEN)\*\*/g,'<span class="ears-keyword font-semibold">$1</span>'),F.forEach(c=>{let e=new RegExp(`(?<!<span[^>]*>)\\b(${c.replace(" ","\\s+")})\\b(?![^<]*</span>)`,"g");a=a.replace(e,'<span class="ears-keyword">$1</span>')}),a=a.replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>"),a}var z=["As a","I want","So that","WHEN","IF","THEN","SHALL"];function J(i){if(!i)return"";let a=i;return z.forEach(c=>{let e=new RegExp(`\\b(${c.replace(" ","\\s+")})\\b`,"g");a=a.replace(e,'<span class="ears-keyword">$1</span>')}),a=a.replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>"),a}function K(i){return`
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium ${D(i)}">
${L(i)}
</span>
`}function Y(i,a){let c=a>0?Math.round(i/a*100):0;return`
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2">
<div class="bg-indigo-600 dark:bg-indigo-500 h-2 rounded-full transition-all duration-300"
style="width: ${c}%" aria-label="Progress: ${c}%"></div>
</div>
`}function X(i){if(!i||i.exists&&i.hasProduct&&i.hasTech&&i.hasStructure)return"";let a=[];return i.hasProduct||a.push("Product vision and goals (product.md)"),i.hasTech||a.push("Technology stack and architecture (tech.md)"),i.hasStructure||a.push("Project structure and patterns (structure.md)"),`
<div class="mb-6 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4">
<div class="flex">
<div class="flex-shrink-0">
<i class="fas fa-exclamation-triangle text-yellow-400"></i>
</div>
<div class="ml-3">
<h3 class="text-sm font-medium text-yellow-800 dark:text-yellow-200">
Steering Documents Incomplete
</h3>
<div class="mt-2 text-sm text-yellow-700 dark:text-yellow-300">
<p>
Run <button @click.stop="copyCommand('/spec-steering-setup', $event)"
class="inline-flex items-center gap-1 bg-yellow-100 dark:bg-yellow-800 px-1.5 py-0.5 rounded text-xs font-mono hover:bg-yellow-200 dark:hover:bg-yellow-700 transition-colors">
<i class="fas fa-copy"></i>/spec-steering-setup
</button> to create missing steering documents:
</p>
<ul class="list-disc list-inside mt-1">
${a.map(c=>`<li>${c}</li>`).join("")}
</ul>
</div>
</div>
</div>
</div>
`}var y={formatDate:V,safeFormatDate:W,getStatusClass:D,getStatusLabel:L,copyCommand:q,renderMarkdown:H,formatAcceptanceCriteria:G,formatUserStory:J,StatusBadgeTemplate:K,ProgressBarTemplate:Y,SteeringWarningTemplate:X,SafeParser:S,ResultUtils:E};typeof globalThis.window<"u"&&(globalThis.window.DashboardShared=y);var k=new Map,M=[{primary:"cyan-600",light:"cyan-100",ring:"cyan-500",dark:{primary:"cyan-400",light:"cyan-900"}},{primary:"violet-600",light:"violet-100",ring:"violet-500",dark:{primary:"violet-400",light:"violet-900"}},{primary:"rose-600",light:"rose-100",ring:"rose-500",dark:{primary:"rose-400",light:"rose-900"}},{primary:"amber-600",light:"amber-100",ring:"amber-500",dark:{primary:"amber-400",light:"amber-900"}},{primary:"emerald-600",light:"emerald-100",ring:"emerald-500",dark:{primary:"emerald-400",light:"emerald-900"}},{primary:"fuchsia-600",light:"fuchsia-100",ring:"fuchsia-500",dark:{primary:"fuchsia-400",light:"fuchsia-900"}},{primary:"orange-600",light:"orange-100",ring:"orange-500",dark:{primary:"orange-400",light:"orange-900"}},{primary:"teal-600",light:"teal-100",ring:"teal-500",dark:{primary:"teal-400",light:"teal-900"}},{primary:"indigo-600",light:"indigo-100",ring:"indigo-500",dark:{primary:"indigo-400",light:"indigo-900"}},{primary:"lime-600",light:"lime-100",ring:"lime-500",dark:{primary:"lime-400",light:"lime-900"}},{primary:"sky-600",light:"sky-100",ring:"sky-500",dark:{primary:"sky-400",light:"sky-900"}},{primary:"pink-600",light:"pink-100",ring:"pink-500",dark:{primary:"pink-400",light:"pink-900"}},{primary:"red-600",light:"red-100",ring:"red-500",dark:{primary:"red-400",light:"red-900"}},{primary:"green-600",light:"green-100",ring:"green-500",dark:{primary:"green-400",light:"green-900"}},{primary:"blue-600",light:"blue-100",ring:"blue-500",dark:{primary:"blue-400",light:"blue-900"}}],N={"cyan-600":"rgb(8, 145, 178)","cyan-400":"rgb(34, 211, 238)","cyan-100":"rgb(207, 250, 254)","cyan-900":"rgb(22, 78, 99)","violet-600":"rgb(124, 58, 237)","violet-400":"rgb(167, 139, 250)","violet-100":"rgb(237, 233, 254)","violet-900":"rgb(76, 29, 149)","rose-600":"rgb(225, 29, 72)","rose-400":"rgb(251, 113, 133)","rose-100":"rgb(255, 228, 230)","rose-900":"rgb(136, 19, 55)","amber-600":"rgb(217, 119, 6)","amber-400":"rgb(251, 191, 36)","amber-100":"rgb(254, 243, 199)","amber-900":"rgb(120, 53, 15)","emerald-600":"rgb(5, 150, 105)","emerald-400":"rgb(52, 211, 153)","emerald-100":"rgb(209, 250, 229)","emerald-900":"rgb(6, 78, 59)","fuchsia-600":"rgb(219, 39, 119)","fuchsia-400":"rgb(244, 114, 182)","fuchsia-100":"rgb(250, 232, 255)","fuchsia-900":"rgb(134, 25, 143)","orange-600":"rgb(234, 88, 12)","orange-400":"rgb(251, 146, 60)","orange-100":"rgb(254, 215, 170)","orange-900":"rgb(124, 45, 18)","teal-600":"rgb(13, 148, 136)","teal-400":"rgb(45, 212, 191)","teal-100":"rgb(204, 251, 241)","teal-900":"rgb(19, 78, 74)","indigo-600":"rgb(79, 70, 229)","indigo-400":"rgb(129, 140, 248)","indigo-100":"rgb(224, 231, 255)","indigo-900":"rgb(49, 46, 129)","lime-600":"rgb(132, 204, 22)","lime-400":"rgb(163, 230, 53)","lime-100":"rgb(236, 252, 203)","lime-900":"rgb(54, 83, 20)","sky-600":"rgb(2, 132, 199)","sky-400":"rgb(56, 189, 248)","sky-100":"rgb(224, 242, 254)","sky-900":"rgb(12, 74, 110)","pink-600":"rgb(219, 39, 119)","pink-400":"rgb(244, 114, 182)","pink-100":"rgb(252, 231, 243)","pink-900":"rgb(131, 24, 67)","red-600":"rgb(220, 38, 38)","red-400":"rgb(248, 113, 113)","red-100":"rgb(254, 226, 226)","red-900":"rgb(127, 29, 29)","green-600":"rgb(22, 163, 74)","green-400":"rgb(74, 222, 128)","green-100":"rgb(220, 252, 231)","green-900":"rgb(20, 83, 45)","blue-600":"rgb(37, 99, 235)","blue-400":"rgb(96, 165, 250)","blue-100":"rgb(219, 234, 254)","blue-900":"rgb(30, 58, 138)"};function I(){console.log("initApp called - Initializing multi-dashboard app with shared components"),console.log("Creating appState object...");let i={theme:"system",collapsedCompletedTasks:{},markdownPreview:{show:!1,title:"",content:"",rawContent:"",loading:!1},get markdownShow(){return this.markdownPreview.show},get markdownTitle(){return this.markdownPreview.title},get markdownContent(){return this.markdownPreview.content},get markdownRawContent(){return this.markdownPreview.rawContent},get markdownLoading(){return this.markdownPreview.loading},projects:[],selectedProject:null,selectedSpec:null,activeSessions:[],activeTab:"active",connected:!1,ws:null,username:"User",expandedRequirements:{},expandedDesigns:{},expandedTasks:{},selectedTasks:{},expandedRequirementAccordions:{},pendingProjectRoute:null,showCompleted:localStorage.getItem("showCompleted")!=="false",tunnelStatus:null,e:null,t:{},projectTabsData:[],get activeSessionCount(){return this.projects.filter(e=>e.hasActiveSession).length},get groupedProjectsList(){let e=this.getCachedGroupedProjects();return!e||e.length===0?[]:e.map(t=>{let s=t.steeringStatus;return console.log(`Project ${t.name} steering data:`,s),{path:t.path,name:t.name,level:t.level||0,hasActiveSession:t.hasActiveSession||!1,specs:t.specs||[],bugs:t.bugs||[],steeringStatus:s}})},getVisibleSpecs(e){return e?.specs?this.showCompleted?e.specs:e.specs.filter(t=>t?.status!=="completed"):[]},getVisibleBugs(e){return e?.bugs?this.showCompleted?e.bugs:e.bugs.filter(t=>t?.status!=="resolved"):[]},getProjectColor(e){if(!e)return{primary:"indigo-600",light:"indigo-100",ring:"indigo-500"};let t=k.get(e);if(t)return t;let s=this.getCachedGroupedProjects();if(!s||s.length===0)return{primary:"indigo-600",light:"indigo-100",ring:"indigo-500"};let r=[];for(let u=0;u<s.length;u++){let p=s[u];p?.level===0&&r.push(p)}let n=null,o=-1;for(let u=0;u<r.length;u++){let p=r[u];if(p&&(e===p.path||e.startsWith(p.path+"/"))){n=p,o=u;break}}o===-1&&(o=r.findIndex(u=>u?.path===e),o>=0&&(n=r[o]||null));let d=o>=0?o%M.length:0,g=M[d];if(n){k.set(n.path,g);for(let u=0;u<s.length;u++){let p=s[u];p?.path&&(p.path.startsWith(n.path+"/")||p.path===n.path)&&k.set(p.path,g)}}else k.set(e,g);return g},getProjectColorClasses(e,t="text"){let s=this.getProjectColor(e);if(!s?.primary)return"";let r=document.documentElement.classList.contains("dark");switch(t){case"text":return r&&s.dark?.primary?`text-${s.dark.primary}`:`text-${s.primary}`;case"bg":return r&&s.dark?.light?`bg-${s.dark.light}`:`bg-${s.light||"indigo-100"}`;case"bg-primary":return`bg-${s.primary}`;case"border":return`border-${s.primary}`;case"border-l":return`border-l-${s.primary}`;case"border-r":return`border-r-${s.primary}`;case"border-b":return`border-b-${s.primary}`;case"text-primary":return`text-${s.primary}`;default:return""}},getProjectColorValue(e){if(!e)return"rgb(79, 70, 229)";let t=this.t?.[e];if(t)return t;let s=this.getProjectColor(e),r=s?.primary&&N[s.primary]||"rgb(8, 145, 178)";return this.t||(this.t={}),this.t[e]=r,r},getProjectTabStyles(e){let t=[],s=this.activeTab==="projects"&&this.selectedProject?.path===e?.path,r=this.getProjectColor(e?.path||""),n=this.getColorValue(r?.primary||"indigo-600"),o=document.documentElement.classList.contains("dark"),d=this.getCachedGroupedProjects(),g=d.findIndex(m=>m?.path===e?.path);s&&(t.push(`border-bottom-color: ${n}`),t.push(`color: ${n}`));let u=g>=0&&g<d.length-1?d[g+1]:null,p=u?.level!==void 0&&u.level>0;if((e?.level||0)>0||p){let m;if((e?.level||0)>0){let j=this.getParentProjectPath(e?.path||"",d,g);m=this.getProjectColor(j)}else m=r||{primary:"indigo-600",light:"indigo-100",ring:"indigo-500"};let P=this.getColorValue(m?.primary||"indigo-600");(e?.level||0)===0&&p&&t.push(`border-left: 2px solid ${P}`);let w=o?"0.1":"0.05";t.push(`background-color: ${this.getColorWithOpacity(m?.primary||"indigo-600",w)}`);let R=g<d.length-1?d[g+1]:null;(e?.level||0)>0&&(g===d.length-1||R?.level===0)&&t.push(`border-right: 2px solid ${P}`)}return t.join("; ")},getProjectBadgeStyles(e){let t=[],s=this.getProjectColor(e?.path||""),r=document.documentElement.classList.contains("dark");if(e?.hasActiveSession){let n={"cyan-600":"rgb(207, 250, 254)","violet-600":"rgb(237, 233, 254)","rose-600":"rgb(255, 228, 230)","amber-600":"rgb(254, 243, 199)","emerald-600":"rgb(209, 250, 229)","fuchsia-600":"rgb(250, 232, 255)","orange-600":"rgb(255, 237, 213)","teal-600":"rgb(204, 251, 241)","indigo-600":"rgb(224, 231, 255)","lime-600":"rgb(236, 252, 203)","sky-600":"rgb(224, 242, 254)"},o={"cyan-600":"rgb(22, 78, 99)","violet-600":"rgb(76, 29, 149)","rose-600":"rgb(136, 19, 55)","amber-600":"rgb(120, 53, 15)","emerald-600":"rgb(6, 78, 59)","fuchsia-600":"rgb(134, 25, 143)","orange-600":"rgb(124, 45, 18)","teal-600":"rgb(19, 78, 74)","indigo-600":"rgb(49, 46, 129)","lime-600":"rgb(54, 83, 20)","sky-600":"rgb(12, 74, 110)"},d=s?.primary||"indigo-600",g=r?o[d]||"rgb(55, 65, 81)":n[d]||"rgb(243, 244, 246)",u=this.getColorValue(d);t.push(`background-color: ${g}`),t.push(`color: ${u}`)}else t.push(`background-color: ${r?"rgb(55, 65, 81)":"rgb(243, 244, 246)"}`),t.push(`color: ${r?"rgb(156, 163, 175)":"rgb(75, 85, 99)"}`);return t.join("; ")},getColorValue(e){return N[e]||"rgb(79, 70, 229)"},getColorWithOpacity(e,t){return`rgba(${{"cyan-600":"8, 145, 178","violet-600":"124, 58, 237","rose-600":"225, 29, 72","amber-600":"217, 119, 6","emerald-600":"5, 150, 105","fuchsia-600":"219, 39, 119","orange-600":"234, 88, 12","teal-600":"13, 148, 136","indigo-600":"79, 70, 229","lime-600":"132, 204, 22","sky-600":"2, 132, 199"}[e]||"79, 70, 229"}, ${t})`},getCachedGroupedProjects(){return(!this.e||this.e.projectsCount!==this.projects.length||this.e.projectsHash!==JSON.stringify(this.projects.map(e=>e.path)))&&(this.e={projectsCount:this.projects.length,projectsHash:JSON.stringify(this.projects.map(e=>e.path)),data:this.s()}),this.e.data},getGroupedProjects(){return this.groupedProjectsList},s(){if(!this.projects||this.projects.length===0)return[];let e=[...this.projects].sort((o,d)=>o.path.localeCompare(d.path)),t=new Map;e.forEach(o=>t.set(o.path,o));let s=[],r=new Set,n=(o,d=0)=>{if(r.has(o.path))return;s.push({...o,level:d}),r.add(o.path);let g=e.filter(u=>r.has(u.path)?!1:u.path.startsWith(o.path+"/"));g.sort((u,p)=>{let v=u.path.split("/").length,m=p.path.split("/").length;return v!==m?v-m:u.name.localeCompare(p.name)}),g.forEach(u=>{let v=u.path.substring(o.path.length+1).split("/").length;s.push({...u,level:d+v}),r.add(u.path)})};return e.forEach(o=>{if(r.has(o.path))return;let d=o.path.split("/"),g=!1;for(let u=d.length-1;u>0;u--){let p=d.slice(0,u).join("/");if(t.has(p)){g=!0;break}}g||n(o,0)}),console.log("Grouped projects:",s.map(o=>`${" ".repeat((o?.level||0)*2)}${o?.name||"Unknown"} (${o?.path||"Unknown"})`).join(`
`)),s},getParentProjectPath(e,t,s){let r=t[s];if(!r||(r?.level||0)===0)return e;for(let n=s-1;n>=0;n--){let o=t[n];if(o&&(o?.level||0)===0)return o?.path||e}return e},getProjectAtIndex(e){return this.groupedProjectsList?.[e]||null},isNextProjectTopLevel(e){let t=this.groupedProjectsList;return!t||e<0||e>=t.length-1?!1:t[e+1]?.level===0},isPreviousProjectNested(e){if(e===0)return!1;let t=this.groupedProjectsList;return!t||e<=0||e>=t.length?!1:(t[e-1]?.level||0)>0},updateProjectTabsData(){let e=this.getCachedGroupedProjects();if(!e||e.length===0){this.projectTabsData=[];return}this.projectTabsData=e.map((t,s)=>{let r=this.getProjectColorValue(t?.path||""),n=this.getProjectColor(t?.path||""),o=s<e.length-1&&(e[s+1]?.level||0)===0,d=s>0&&(e[s-1]?.level||0)>0;return{path:t.path,name:t.name,level:t.level||0,hasActiveSession:t.hasActiveSession||!1,colorValue:r,colorPrimary:n.primary,isNextTopLevel:o,isPrevNested:d,specs:t.specs||[],bugs:t.bugs||[]}})},async init(){console.log("Multi-project dashboard initializing..."),this.initTheme(),this.setupKeyboardHandlers(),this.setupCodeBlockCopyHandlers(),this.initializeRouting(),this.connectWebSocket(),await this.fetchTunnelStatus()},connectWebSocket(){let t=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/ws`;this.ws=new WebSocket(t),this.ws.onopen=()=>{console.log("WebSocket connected"),this.connected=!0},this.ws.onmessage=s=>{let r=JSON.parse(s.data);console.log("WebSocket message:",r),this.handleWebSocketMessage(r)},this.ws.onclose=()=>{console.log("WebSocket disconnected"),this.connected=!1,setTimeout(()=>this.connectWebSocket(),2e3)},this.ws.onerror=s=>{console.error("WebSocket error:",s)}},handleWebSocketMessage(e){switch(e.type){case"initial":console.log("Initial message received:",e),console.log("message.data type:",typeof e.data,"isArray:",Array.isArray(e.data)),console.log("message.data:",e.data);let t=[],s=[],r="User";if("data"in e&&(Array.isArray(e.data)&&(t=e.data),"activeSessions"in e&&Array.isArray(e.activeSessions)&&(s=e.activeSessions),"username"in e&&typeof e.username=="string"&&(r=e.username)),this.projects=this.normalizeProjects(t),this.activeSessions=s.map(l=>({...l,projectColorValue:this.getProjectColorValue(l.projectPath)})),this.username=r,this.e=null,k.clear(),this.t={},this.updateProjectTabsData(),console.log(`Received initial data: ${this.projects.length} projects, ${this.activeSessions.length} active sessions`),console.log("Projects after normalization:",this.projects),console.log("Active sessions:",this.activeSessions),this.sortProjects(),this.pendingProjectRoute&&this.projects.length>0){let l=this.projects.find(h=>this.getProjectSlug(h)===this.pendingProjectRoute);l?(this.selectedProject=l,this.activeTab="projects",this.updateURL()):(this.activeTab="active",this.selectedProject=null,this.updateURL()),this.pendingProjectRoute=null}else!this.selectedProject&&this.projects.length>0&&this.activeTab==="projects"&&(this.selectedProject=this.projects[0]||null,this.updateURL());break;case"update":let n=e.data;if(n.projects){let l=this.selectedProject!==null,h=this.selectedProject?.path;this.projects=this.normalizeProjects(n.projects),this.sortProjects(),l&&h&&(this.projects.find(O=>O.path===h)||(this.activeTab="active",this.selectedProject=null,this.updateURL())),this.e=null,k.clear(),this.t={},this.updateProjectTabsData()}break;case"steering-update":let o=e,d=o.projectPath,g=this.projects.find(l=>l.path===d);g&&(g.steeringStatus=o.data,console.log(`Steering documents updated for ${g.name}:`,o.data));break;case"tunnel:started":let u=e.data;this.tunnelStatus={active:!0,info:u,url:u?.url,viewers:0},console.log("Tunnel started:",this.tunnelStatus);break;case"tunnel:stopped":this.tunnelStatus={active:!1,info:null,viewers:0},console.log("Tunnel stopped:",this.tunnelStatus);break;case"tunnel:metrics:updated":this.tunnelStatus&&(this.tunnelStatus.viewers=e.data.viewers||0);break;case"project-update":let p=e,v=p.projectPath,m=this.projects.find(l=>l.path===v);if(m&&p.data){let l=p.data;if(console.log(`Project update for ${m.name}:`,l),l.type==="spec-update"&&l.spec&&l.data){let h=m.specs.findIndex(A=>A.name===l.spec);h!==-1?(m.specs[h]=l.data,console.log(`Updated spec ${l.spec} for project ${m.name}`)):(m.specs.push(l.data),console.log(`Added new spec ${l.spec} for project ${m.name}`))}else(l.type==="added"||l.type==="changed"||l.type==="removed")&&console.log(`Other event type ${l.type} for ${m.name}`)}break;case"active-sessions-update":let P=e.data;Array.isArray(P)&&(this.activeSessions=P,console.log("Active sessions updated:",P.length));break;case"git-update":let w=e,R=w.projectPath,T=this.projects.find(l=>l.path===R);T&&(T.gitBranch=w.gitBranch,T.gitCommit=w.gitCommit,console.log(`Git updated for ${T.name}: ${w.gitBranch} (${w.gitCommit})`));break;case"bug-update":let j=e,U=j.projectPath,b=this.projects.find(l=>l.path===U);if(b&&j.data){let l=j.data;if(console.log(`Bug update for ${b.name}:`,l),l.bug&&l.data&&b.bugs){let h=b.bugs.findIndex(A=>A.name===l.bug);h!==-1?(b.bugs[h]=l.data,console.log(`Updated bug ${l.bug} for project ${b.name}`)):(b.bugs.push(l.data),console.log(`Added new bug ${l.bug} for project ${b.name}`))}else l.bug&&l.data&&!b.bugs&&(b.bugs=[l.data],console.log(`Initialized bugs array and added bug ${l.bug} for project ${b.name}`))}break;case"new-project":let C=e.data;if(C&&this.projects.findIndex(h=>h.path===C.path)===-1){let h=this.normalizeProjects([C]);h.length>0&&h[0]&&(this.projects.push(h[0]),this.sortProjects(),this.e=null,k.clear(),this.t={},this.updateProjectTabsData(),console.log(`Added new project: ${C.name} at ${C.path}`))}break;case"remove-project":let x=e.data;if(x&&x.path){let l=this.projects.findIndex(h=>h.path===x.path);if(l!==-1){let h=this.projects[l];this.projects.splice(l,1),this.selectedProject?.path===x.path&&(this.selectedProject=null,this.activeTab="active",this.updateURL()),this.e=null,k.clear(),this.t={},this.updateProjectTabsData(),console.log(`Removed project: ${h?.name||"unknown"} from ${x.path}`)}}break;default:console.log("Unknown message type:",e.type)}},switchTab(e){this.activeTab=e,this.updateURL()},selectProject(e){this.selectedProject=e,this.activeTab="projects",this.updateURL()},selectProjectAndShowBugs(e){this.selectedProject=e,this.activeTab="projects",this.updateURL(),e&&this.getOpenBugsCount(e)>0&&setTimeout(()=>{let t=document.querySelector("[data-bug-section]");t&&t.scrollIntoView({behavior:"smooth",block:"start"})},100)},selectProjectFromSession(e){let t=this.projects.find(s=>s.path===e.projectPath);if(t)if(this.selectedProject=t,this.activeTab="projects",this.updateURL(),e.type==="spec"&&t.specs){let s=t.specs.find(r=>r.name===e.specName);s&&(this.selectedSpec=s)}else e.type==="bug"&&setTimeout(()=>{let s=document.getElementById(`bug-${e.bugName}`);s&&s.scrollIntoView({behavior:"smooth",block:"start"})},100)},selectProjectFromTask(e,t,s="spec"){let r=this.projects.find(o=>o.path===e);if(!r)return;let n;s==="bug"||r.bugs&&r.bugs.find(o=>o.name===t)?n={type:"bug",projectPath:e,bugName:t}:n={type:"spec",projectPath:e,specName:t},this.selectProjectFromSession(n)},toggleRequirementsExpanded(e){this.expandedRequirements[e]?delete this.expandedRequirements[e]:this.expandedRequirements[e]=!0},isRequirementsExpanded(e){return!!this.expandedRequirements[e]},toggleDesignExpanded(e){this.expandedDesigns[e]?delete this.expandedDesigns[e]:this.expandedDesigns[e]=!0},isDesignExpanded(e){return!!this.expandedDesigns[e]},toggleTasksExpanded(e){if(this.expandedTasks[e])delete this.expandedTasks[e],delete this.selectedTasks[e];else{this.expandedTasks[e]=!0;let t=this.selectedProject;if(t&&t.specs){let s=t.specs.find(r=>r?.name===e);if(s&&s.tasks&&s.tasks.taskList&&s.tasks.taskList.length>0){let r=this.findFirstIncompleteTask(s.tasks.taskList);if(r)this.selectedTasks[e]=r.id;else{let n=s.tasks.taskList[0];n&&(this.selectedTasks[e]=n.id)}}}}},isTasksExpanded(e){return!!this.expandedTasks[e]},toggleRequirementAccordion(e,t){let s=`${e}-${t}`,r=this.expandedRequirementAccordions[s];Object.keys(this.expandedRequirementAccordions).forEach(n=>{n.startsWith(e+"-")&&delete this.expandedRequirementAccordions[n]}),r||(this.expandedRequirementAccordions[s]=!0)},isRequirementExpanded(e,t){let s=`${e}-${t}`;return!!this.expandedRequirementAccordions[s]},selectTask(e,t){this.selectedTasks[e]===t?delete this.selectedTasks[e]:this.selectedTasks[e]=t},isTaskSelected(e,t){return this.selectedTasks[e]===t},selectedTaskId(e){return this.selectedTasks[e]},getSelectedTask(e){let t=this.selectedTasks[e];if(!t)return null;let s=this.selectedProject;if(!s||!s.specs)return null;let r=s.specs.find(n=>n.name===e);return!r||!r.tasks||!r.tasks.taskList?null:r.tasks.taskList.find(n=>n.id===t)||null},initializeSelectedTask(e){if(!this.selectedTasks[e.name]&&e.tasks&&e.tasks.taskList){let t=this.findFirstIncompleteTask(e.tasks.taskList);t&&(this.selectedTasks[e.name]=t.id)}},findFirstIncompleteTask(e){for(let t of e){if(!t.completed)return t;if(t.subtasks){let s=this.findFirstIncompleteTask(t.subtasks);if(s)return s}}return null},getTaskNumber(e){if(e?.type!=="spec")return 1;let t=this.projects.find(n=>n?.path===e?.projectPath)?.specs?.find(n=>n?.name===e?.specName);if(!t?.tasks?.taskList)return 1;let s=e?.task?.id;if(!s)return 1;let r=t.tasks.taskList.findIndex(n=>n?.id===s);return r>=0?r+1:1},getSpecTaskCount(e){return e?.type!=="spec"?0:this.projects.find(s=>s?.path===e?.projectPath)?.specs?.find(s=>s?.name===e?.specName)?.tasks?.total||0},getSpecProgress(e){if(e?.type!=="spec")return 0;let t=this.projects.find(s=>s?.path===e?.projectPath)?.specs?.find(s=>s?.name===e?.specName);return t?.tasks?.total?t.tasks.completed/t.tasks.total*100:0},getNextTask(e){if(e?.type!=="spec")return null;let t=this.projects.find(o=>o?.path===e?.projectPath)?.specs?.find(o=>o?.name===e?.specName);if(!t?.tasks?.taskList)return null;let s=e?.task?.id;if(!s)return null;let r=t.tasks.taskList,n=r.findIndex(o=>o?.id===s);if(n>=0&&n<r.length-1){let o=r[n+1];if(o&&!o.completed)return o}return r.find(o=>o&&!o.completed&&o.id!==s)||null},getCurrentTask(e){if(!e?.tasks?.taskList||!e.tasks.inProgress)return null;let t=e.tasks.taskList,s=e.tasks.inProgress;return t.find(r=>r?.id===s)||null},getSpecsInProgress(e){return e?.specs?e.specs.filter(t=>t?.status==="in-progress").length:0},getSpecsCompleted(e){return e?.specs?e.specs.filter(t=>t?.status==="completed").length:0},getTotalTasks(e){return e?.specs?e.specs.reduce((t,s)=>t+(s?.tasks?.total||0),0):0},getOpenSpecsCount(e){return e?.specs?e.specs.filter(t=>t?.status!=="completed").length:0},getOpenBugsCount(e){return e?.bugs?e.bugs.filter(t=>t?.status!=="resolved").length:0},getBugsInProgress(e){return e?.bugs?e.bugs.filter(t=>t?.status&&["analyzing","fixing","verifying"].includes(t.status)).length:0},getBugsResolved(e){return e?.bugs?e.bugs.filter(t=>t?.status==="resolved").length:0},initializeRouting(){window.addEventListener("popstate",()=>{this.handleRouteChange()}),this.handleRouteChange()},handleRouteChange(){let e=window.location.pathname;if(e==="/"||e==="/active"||e==="/dashboard"||e==="/dashboard/"||e.includes("/dashboard/public")){this.activeTab="active",this.selectedProject=null,e==="/"&&window.history.replaceState(null,"","/active");return}let t=e.match(/^\/project\/(.+)$/);if(t){let s=t[1],r=this.projects.find(n=>this.getProjectSlug(n)===s);r?(this.selectedProject=r,this.activeTab="projects"):this.projects.length===0&&s&&!s.includes(".")?this.pendingProjectRoute=s:(this.activeTab="active",this.selectedProject=null,window.history.replaceState(null,"","/active"))}else this.activeTab="active",this.selectedProject=null,window.history.replaceState(null,"","/active")},updateURL(){let e="/active";this.activeTab==="projects"&&this.selectedProject&&(e="/project/"+this.getProjectSlug(this.selectedProject)),window.location.pathname!==e&&window.history.pushState(null,"",e)},getProjectSlug(e){return(e?.name||"").trim().toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")},copyNextTaskCommand(e,t){if(e?.tasks?.taskList){let s=this.findFirstIncompleteTask(e.tasks.taskList);if(s?.id&&e.name){let r=`/spec-execute ${e.name} ${s.id}`;y.copyCommand(r,t)}}},copyOrchestrateCommand(e,t){if(e?.name){let s=`/spec-orchestrate ${e.name}`;y.copyCommand(s,t)}},sortProjects(){this.projects.sort((e,t)=>{if(e.hasActiveSession&&!t.hasActiveSession)return-1;if(!e.hasActiveSession&&t.hasActiveSession)return 1;let s=e.lastActivity?new Date(e.lastActivity):new Date(0);return(t.lastActivity?new Date(t.lastActivity):new Date(0)).getTime()-s.getTime()})},sortSpecs(e){!e||!Array.isArray(e)||e.sort((t,s)=>{let r={"in-progress":1,tasks:2,design:3,requirements:4,"not-started":5,completed:6},n=r[t.status]||99,o=r[s.status]||99;if(n!==o)return n-o;let d=t.lastModified?new Date(t.lastModified).getTime():0;return(s.lastModified?new Date(s.lastModified).getTime():0)-d})},sortBugs(e){!e||!Array.isArray(e)||e.sort((t,s)=>{let r={reported:1,analyzing:2,fixing:3,fixed:4,verifying:5,resolved:6},n=r[t.status]||99,o=r[s.status]||99;if(n!==o)return n-o;let d=t.lastModified?new Date(t.lastModified).getTime():0;return(s.lastModified?new Date(s.lastModified).getTime():0)-d})},normalizeProjects(e){return console.log("normalizeProjects input:",e),e.map(t=>(console.log(`Project ${t.name} raw data:`,{steeringStatus:t.steeringStatus}),t.specs&&(t.specs=t.specs.map(s=>{if(this.initializeSelectedTask(s),s.requirements&&s.requirements.content&&typeof s.requirements.content=="string")try{s.requirements.content=JSON.parse(s.requirements.content)}catch(r){console.warn("Failed to parse requirements content:",r)}if(s.design&&s.design.codeReuseContent&&typeof s.design.codeReuseContent=="string")try{s.design.codeReuseContent=JSON.parse(s.design.codeReuseContent)}catch(r){console.warn("Failed to parse design content:",r)}return s})),console.log(`Project ${t.name} normalized with steering:`,t.steeringStatus),t))},scrollToRequirement(e,t){let s=document.getElementById(`${e}-req-${t}`);s&&s.scrollIntoView({behavior:"smooth",block:"start"})},toggleShowCompleted(){this.showCompleted=!this.showCompleted,localStorage.setItem("showCompleted",this.showCompleted.toString())},async fetchTunnelStatus(){try{let e=await fetch("/api/tunnel/status");e.ok?(this.tunnelStatus=await e.json(),console.log("Tunnel status:",this.tunnelStatus)):this.tunnelStatus={active:!1}}catch(e){console.error("Error fetching tunnel status:",e),this.tunnelStatus={active:!1}}},async startTunnel(){try{let e=await fetch("/api/tunnel/start",{method:"POST"});if(e.ok){let t=await e.json();console.log("Tunnel started successfully:",t)}else console.error("Failed to start tunnel:",e.status),alert("Failed to start tunnel. Check the console for details.")}catch(e){console.error("Error starting tunnel:",e),alert("Error starting tunnel. Check the console for details.")}},async stopTunnel(){try{let e=await fetch("/api/tunnel/stop",{method:"POST"});e.ok?(this.tunnelStatus={active:!1},console.log("Tunnel stopped successfully")):console.error("Failed to stop tunnel:",e.status)}catch(e){console.error("Error stopping tunnel:",e)}},formatTunnelExpiry(e){if(!e)return"";let t=new Date(e),s=new Date,r=t.getTime()-s.getTime(),n=Math.floor(r/6e4),o=Math.floor(n/60);return o>0?`in ${o}h ${n%60}m`:n>0?`in ${n}m`:"soon"},async viewMarkdown(e,t,s=null){if(console.log("viewMarkdown called:",{specName:e,docType:t,projectPath:s}),console.log("Current markdownPreview state:",JSON.parse(JSON.stringify(this.markdownPreview))),s)return console.log("Using provided projectPath:",s),this.viewMarkdownWithProject(e,t,s);if(!this.selectedProject){console.error("No project selected for viewing markdown");return}return console.log("Using selectedProject.path:",this.selectedProject.path),this.viewMarkdownWithProject(e,t,this.selectedProject.path)},async viewBugMarkdown(e,t,s){this.markdownPreview={show:!0,loading:!0,title:`${t} - ${s}.md`,content:"",rawContent:""};try{let r=encodeURIComponent(e),n=await fetch(`/api/projects/${r}/bugs/${t}/${s}`);if(!n.ok){let d=await n.text();throw console.error("Response not OK:",n.status,d),new Error(`Failed to fetch ${s} content: ${n.status}`)}let o=await n.json();console.log("Setting bug markdown preview content, data:",o),this.markdownPreview.content=o.content,this.markdownPreview.rawContent=o.content,console.log("markdownPreview.rawContent is now:",this.markdownPreview.rawContent?.substring(0,100))}catch(r){console.error(`Error fetching ${s} content:`,r),this.markdownPreview.content=`# Error loading ${s} content
${r.message}`,this.markdownPreview.rawContent=""}finally{this.markdownPreview.loading=!1}},hasBugDocument(e,t){for(let s of this.activeSessions)if(s.type==="bug"&&s.bugName===e){let r=this.projects.find(n=>n.path===s.projectPath);if(r&&r.bugs){let n=r.bugs.find(o=>o.name===e);if(n)switch(t){case"report":return n.report?.exists||!1;case"analysis":return n.analysis?.exists||!1;case"fix":return n.fix?.exists||!1}}}if(this.selectedProject&&this.selectedProject.bugs){let s=this.selectedProject.bugs.find(r=>r.name===e);if(s)switch(t){case"report":return s.report?.exists||!1;case"analysis":return s.analysis?.exists||!1;case"fix":return s.fix?.exists||!1}}return!1},async viewBugDocument(e,t,s){await this.viewBugMarkdown(e,t,s)},getSpecStatus(e){if(e.type!=="spec")return null;let t=this.projects.find(r=>r.path===e.projectPath);return!t||!t.specs?null:t.specs.find(r=>r.name===e.specName)?.status||null},getTaskTooltip(e){if(!e)return"";let t=[];return e.description&&t.push(`Task ${e.id}: ${e.description}`),e.completed?t.push("Status: Completed ✅"):e.inProgress?t.push("Status: In Progress"):t.push("Status: Not Started"),e.requirements&&e.requirements.length>0&&t.push(`Requirements: ${e.requirements.join(", ")}`),e.leverage&&t.push(`Leverage: ${e.leverage}`),t.join(`
`)},copyTaskCommand(e,t,s){let r=`/spec-execute ${e} ${t}`;y.copyCommand(r,s)},copyOrchestrationCommand(e,t,s){let r=`/spec-orchestrate ${e} ${t}`;y.copyCommand(r,s)},initTheme(){let e=localStorage.getItem("theme")||"system";this.theme=e,this.applyTheme(this.theme)},applyTheme(e){let t=document.documentElement;e==="dark"||e==="system"&&window.matchMedia("(prefers-color-scheme: dark)").matches?t.classList.add("dark"):t.classList.remove("dark")},cycleTheme(){let e=["light","dark","system"],t=e.indexOf(this.theme);this.theme=e[(t+1)%e.length]||"system",localStorage.setItem("theme",this.theme),this.applyTheme(this.theme)},showModal(e,t){this.markdownPreview={show:!0,loading:!0,title:`${e} - ${t}.md`,content:this.markdownPreview.content||"",rawContent:this.markdownPreview.rawContent||""}},closeMarkdownPreview(){this.markdownPreview.show=!1,this.markdownPreview.title="",this.markdownPreview.content="",this.markdownPreview.rawContent=""},setupKeyboardHandlers(){document.addEventListener("keydown",e=>{e.key==="Escape"&&this.markdownPreview.show&&this.closeMarkdownPreview()})},setupCodeBlockCopyHandlers(){document.addEventListener("click",e=>{e.target&&e.target.closest(".code-copy-btn")&&(e.preventDefault(),e.stopPropagation(),this.copyCodeBlock(e))})},copyCodeBlock(e){let t=e.target&&e.target.closest(".code-copy-btn");if(!t)return;let s=t.parentElement?.querySelector("pre[data-code-content]");if(!s)return;let r=s.getAttribute("data-code-content");if(r)try{let n=decodeURIComponent(escape(atob(r)));y.copyCommand(n,e)}catch(n){console.error("Failed to decode code content:",n);let o=t.innerHTML;t.innerHTML='<i class="fas fa-times"></i> Error',t.classList.add("text-red-600","dark:text-red-400"),setTimeout(()=>{t.innerHTML=o,t.classList.remove("text-red-600","dark:text-red-400")},2e3)}},async viewMarkdownWithProject(e,t,s){console.log("viewMarkdownWithProject called:",{specName:e,docType:t,projectPath:s}),console.log("Setting markdownPreview.show to true"),this.markdownPreview.show=!0,this.markdownPreview.loading=!0,this.markdownPreview.title=`${e} - ${t}.md`,this.markdownPreview.content="",this.markdownPreview.rawContent="",console.log("After setting show=true, markdownPreview state:",JSON.parse(JSON.stringify(this.markdownPreview))),setTimeout(()=>{let r=document.querySelector(".markdown-modal");console.log("Modal element found:",!!r),r&&(console.log("Modal classes:",r.className),console.log("Modal computed style display:",window.getComputedStyle(r).display),console.log('Modal has "show" class:',r.classList.contains("show")))},10);try{let n=`/api/projects/${encodeURIComponent(s)}/specs/${e}/${t}`;console.log("Fetching:",n);let o=await fetch(n);if(!o.ok)throw new Error(`Failed to fetch ${t} content: ${o.status}`);let d=await o.json();console.log("Received data, setting content"),this.markdownPreview.content=d.content,this.markdownPreview.rawContent=d.content}catch(r){console.error(`Error fetching ${t} content:`,r),this.markdownPreview.content=`# Error loading ${t} content
${r.message}`,this.markdownPreview.rawContent=""}finally{this.markdownPreview.loading=!1,console.log("Final markdown state:",{show:this.markdownPreview.show,title:this.markdownPreview.title,hasContent:!!this.markdownPreview.content})}},getStatusLabel:y.getStatusLabel,getStatusClass:y.getStatusClass,formatDate:y.formatDate,copyCommand:y.copyCommand,renderMarkdown:y.renderMarkdown,formatAcceptanceCriteria:y.formatAcceptanceCriteria,formatUserStory:y.formatUserStory};console.log("appState created, mounting PetiteVue app..."),console.log("appState.viewMarkdown:",typeof i.viewMarkdown),console.log("appState.viewBugDocument:",typeof i.viewBugDocument);let a=document.getElementById("app");if(console.log("App element found:",a),!a){console.error("ERROR: #app element not found in DOM!");return}let c=PetiteVue.createApp(i);console.log("PetiteVue app created, mounting to body..."),c.mount("#app"),console.log("PetiteVue app mounted successfully"),console.log("Calling init() after mount..."),i.init(),setTimeout(()=>{let e=document.querySelector(".markdown-modal");if(e){let t=e.hasAttribute("data-v-scope");console.log("Modal has PetiteVue data-v-scope?",t),console.log("Modal innerHTML sample:",e.innerHTML.substring(0,200))}},500),console.log("Testing app state after mount - markdownPreview:",i.markdownPreview),setTimeout(()=>{let e=document.querySelector(".markdown-modal");console.log("Modal element found:",!!e),e&&(console.log("Modal classes:",e.className),console.log("Modal computed style display:",window.getComputedStyle(e).display))},100),window.debugAppState=i,console.log("App state exposed as window.debugAppState for debugging")}function B(){if(console.log("startApp called, PetiteVue:",typeof PetiteVue),typeof PetiteVue>"u"){console.log("Waiting for PetiteVue to load..."),setTimeout(B,10);return}console.log("PetiteVue is available, checking document ready state:",document.readyState),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",I):(console.log("Document ready, calling initApp"),I())}console.log("multi-app.ts loaded, calling startApp");B();})();
//# sourceMappingURL=app.js.map