agent-issues 0.0.126 → 0.0.128
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/build-info.json
CHANGED
package/dist/cli.js
CHANGED
|
@@ -47817,7 +47817,7 @@ function String2(descriptor, ...args) {
|
|
|
47817
47817
|
// package.json
|
|
47818
47818
|
var package_default = {
|
|
47819
47819
|
name: "agent-issues",
|
|
47820
|
-
version: "0.0.
|
|
47820
|
+
version: "0.0.128",
|
|
47821
47821
|
description: "CLI for managing initiatives, PRDs, user stories, ADRs, and issues.",
|
|
47822
47822
|
type: "module",
|
|
47823
47823
|
bin: {
|
|
@@ -71184,7 +71184,7 @@ ${renderListSkills(capabilities.skills)}`
|
|
|
71184
71184
|
import { spawn as spawn2 } from "node:child_process";
|
|
71185
71185
|
|
|
71186
71186
|
// src/site/server.ts
|
|
71187
|
-
import { readFileSync as readFileSync9 } from "node:fs";
|
|
71187
|
+
import { existsSync as existsSync14, readFileSync as readFileSync9, statSync as statSync5 } from "node:fs";
|
|
71188
71188
|
import { createServer as createServer3, request as sendRequest2 } from "node:http";
|
|
71189
71189
|
|
|
71190
71190
|
// src/site/assets.ts
|
|
@@ -71328,6 +71328,15 @@ var PROJECT_MUTATION_METHODS = /* @__PURE__ */ new Set([
|
|
|
71328
71328
|
"updatePlanEntry",
|
|
71329
71329
|
"upsertContext"
|
|
71330
71330
|
]);
|
|
71331
|
+
function computeFileStatSignature2(dbPath) {
|
|
71332
|
+
return [dbPath, `${dbPath}-wal`, `${dbPath}-shm`].map((candidate) => {
|
|
71333
|
+
if (!existsSync14(candidate)) {
|
|
71334
|
+
return `${candidate}:missing`;
|
|
71335
|
+
}
|
|
71336
|
+
const stats = statSync5(candidate);
|
|
71337
|
+
return `${candidate}:${stats.size}:${stats.mtimeMs}`;
|
|
71338
|
+
}).join("|");
|
|
71339
|
+
}
|
|
71331
71340
|
function isInitiativeTab(value) {
|
|
71332
71341
|
return typeof value === "string" && INITIATIVE_TABS.includes(value);
|
|
71333
71342
|
}
|
|
@@ -71339,6 +71348,7 @@ async function startLiveSite(input) {
|
|
|
71339
71348
|
const host = input.host ?? "127.0.0.1";
|
|
71340
71349
|
const port = input.port ?? 4173;
|
|
71341
71350
|
const pollIntervalMs = input.pollIntervalMs ?? 1e3;
|
|
71351
|
+
const readLocalSignature = input.readLocalSignature ?? computeFileStatSignature2;
|
|
71342
71352
|
const info = {
|
|
71343
71353
|
dbPath,
|
|
71344
71354
|
defaultTenant,
|
|
@@ -71354,7 +71364,7 @@ async function startLiveSite(input) {
|
|
|
71354
71364
|
localDaemon: { buildHash: readBuildContentHash() }
|
|
71355
71365
|
});
|
|
71356
71366
|
await opened.store.close();
|
|
71357
|
-
let databaseSignature = opened.backend === "local" ?
|
|
71367
|
+
let databaseSignature = opened.backend === "local" ? readLocalSignature(dbPath) : void 0;
|
|
71358
71368
|
let pollTimer;
|
|
71359
71369
|
let pollingStopped = false;
|
|
71360
71370
|
let stopCloudEventsRelay;
|
|
@@ -71410,7 +71420,7 @@ async function startLiveSite(input) {
|
|
|
71410
71420
|
return;
|
|
71411
71421
|
}
|
|
71412
71422
|
pollTimer = setTimeout(() => {
|
|
71413
|
-
void
|
|
71423
|
+
void Promise.resolve().then(() => readLocalSignature(dbPath)).then((nextSignature) => {
|
|
71414
71424
|
if (nextSignature !== databaseSignature) {
|
|
71415
71425
|
databaseSignature = nextSignature;
|
|
71416
71426
|
broadcast(clients, JSON.stringify({ type: "snapshot-changed", at: (/* @__PURE__ */ new Date()).toISOString(), category: "unknown" }));
|
|
@@ -72005,9 +72015,6 @@ function parseSearchLimit(value) {
|
|
|
72005
72015
|
const limit = Number(value);
|
|
72006
72016
|
return limit > 0 && limit <= 100 ? limit : null;
|
|
72007
72017
|
}
|
|
72008
|
-
async function readSnapshotSignature(dbPath, tenant, currentWorkingDirectory, credentialStoreOptions) {
|
|
72009
|
-
return withStore(dbPath, { credentialStoreOptions, currentWorkingDirectory, tenant }, (store) => store.getSnapshotSignature());
|
|
72010
|
-
}
|
|
72011
72018
|
async function readProjectMutationRequest(request) {
|
|
72012
72019
|
const chunks = [];
|
|
72013
72020
|
for await (const chunk of request) {
|
package/package.json
CHANGED
|
@@ -2944,7 +2944,7 @@ Please report this to https://github.com/markedjs/marked.`,n){let s="<p>An error
|
|
|
2944
2944
|
align-items: flex-start;
|
|
2945
2945
|
}
|
|
2946
2946
|
}
|
|
2947
|
-
`];let oi=ts;customElements.define("agent-issues-detail-view",oi);const rc="0123456789ABCDEFGHJKMNPQRSTVWXYZ",nc=6,tn=5,ac="agent-issues-global-search-recents",oc=400,lc=300*1e3,cc=[{key:"questions",title:"Questions"},{key:"decisions",title:"Decisions"},{key:"includedScope",title:"Included scope"},{key:"excludedScope",title:"Excluded scope"},{key:"constraints",title:"Constraints"},{key:"preferences",title:"Preferences"},{key:"considerations",title:"Considerations"}],dc={project:"PROJ",epic:"EPIC",version:"VER",initiative:"INIT",prd:"PRD",userStory:"US",adr:"ADR",issue:"ISS",debt:"DEBT",handoff:"HO"};function uc(n){if(n.shortReference)return n.shortReference;const e=dc[n.kind]??n.kind.slice(0,4).toUpperCase();let t=2166136261;for(let r=0;r<n.id.length;r+=1)t^=n.id.charCodeAt(r),t=Math.imul(t,16777619);let s=BigInt(t>>>0),i="";for(let r=0;r<nc;r+=1)i=rc[Number(s&31n)]+i,s>>=5n;return`${e}_${i}`}const Nn=["overview","issues","plans","prds","adrs","context","userStories","debt","graph"],pc=Nn.filter(n=>n!=="overview");function hc(n){if(!n||typeof n!="object"||!("type"in n))return!1;const e=n;return e.type==="entity"?typeof e.entityId=="string":e.type==="plan-entry"?typeof e.planId=="string"&&typeof e.entryId=="string":e.type==="issue-comment"?typeof e.issueId=="string"&&typeof e.commentId=="string":(e.type==="context"||e.type==="context-term"&&typeof e.term=="string")&&(e.scopeRef===void 0||typeof e.scopeRef=="string")}function sn(n,e){const t=n.nodes.filter(a=>e.has(a.kind)),s=new Set(t.map(a=>a.key)),i=[...new Set(t.map(a=>a.col))].sort((a,o)=>a-o),r=new Map(i.map((a,o)=>[a,o]));return{columns:i.map(a=>n.columns[a]),edges:n.edges.filter(a=>s.has(a.from)&&s.has(a.to)),nodes:t.map(a=>({...a,col:r.get(a.col)}))}}function zt(n){return{...n,body:""}}function gc(n){return[...(n.incoming??[]).map(({entity:e,relationType:t})=>({createdAt:n.entity.createdAt,fromId:e.id,toId:n.entity.id,type:t})),...(n.outgoing??[]).map(({entity:e,relationType:t})=>({createdAt:n.entity.createdAt,fromId:n.entity.id,toId:e.id,type:t}))]}function fc(n){if(n.category==="relation")return new Set(["issues","plans","prds","adrs","context","userStories","debt","graph"]);if(n.category==="context")return new Set(["context"]);if(n.category==="plan-entry")return new Set(["plans"]);if(n.category!=="entity")return new Set;const e={adr:"adrs",debt:"debt",issue:"issues",plan:"plans",prd:"prds",userStory:"userStories"};return new Set([...(n.affectedEntityKinds??[]).flatMap(t=>e[t]?[e[t]]:[]),"graph"])}class mc{constructor(){this.config=A(null),this.snapshot=A(null),this.projectSummary=A(null),this.entityDetails=A(new Map),this.projectAdrsCache=A({data:null,error:null,loading:!1}),this.projectDebtCache=A({data:null,error:null,loading:!1}),this.projectContextCache=A({data:null,error:null,loading:!1}),this.projectGraphCache=A({data:null,error:null,loading:!1}),this.planEntryPages=A(new Map),this.issueCommentPages=A(new Map),this.initiativeDetails=A(new Map),this.initiativeTabs=A(new Map),this.projectDiscovery=A(null),this.search=A(""),this.globalSearchCapability=A(null),this.globalSearchQuery=A(""),this.globalSearchScope=A("current-project"),this.globalSearchSourceTypes=A(["entity","context","context-term","plan-entry","issue-comment"]),this.globalSearchResponse=A(null),this.globalSearchResults=A([]),this.globalSearchRecents=A([]),this.globalSearchProgress=A(!1),this.globalSearchOpen=A(!1),this.contextSearch=A(""),this.contextTab=A("all"),this.selectedContextInitiativeId=A(null),this.visibleProjectGraphKinds=A(new Set(ze)),this.initiativeStatusFilter=A("all"),this.adrStatusFilter=A("all"),this.debtLifecycleFilter=A("open"),this.debtCategoryFilter=A("all"),this.debtPriorityFilter=A("all"),this.kindFilter=A("all"),this.selectedTenant=A(null),this.selectedProjectId=A(null),this.selectedInitiativeId=A(null),this.selectedId=A(null),this.selectedNestedTarget=A(null),this.cascadePath=A([]),this.cascadeAvailableWidth=A(0),this.cascadeWindowStart=A(null),this.reRootTrail=A([]),this.railCollapsed=A(!1),this.masterCollapsedOverride=A(null),this.collapsedEpicIdsByProject=A(new Map),this.syncLabel=A("loading"),this.errorMessage=A(null),this.activeView=A("overview"),this.activePage=A("list"),this.activeRootTab=A("initiatives"),this.activeSection=A("initiatives"),this.initTab=A("overview"),this.globalSearchAbortController=null,this.globalSearchProgressTimer=null,this.globalSearchRequestTimer=null,this.initiativeTabPrefetchGeneration=0,this.initiativeTabPrefetchTimer=null,this.localChangeCorrelations=new Map,this.tenantById=j(()=>new Map((this.config.get()?.availableTenants??[]).map(e=>[e.id,e]))),this.tenantOptions=j(()=>{const e=new Map(this.tenantById.get()),t=this.selectedTenant.get();return t&&!e.has(t)&&e.set(t,{displayName:this.formatTenantDisplayName(t),id:t}),[...e.values()].sort((s,i)=>s.displayName.localeCompare(i.displayName))}),this.selectedTenantDisplayName=j(()=>{const e=this.selectedTenant.get();return e?this.tenantById.get().get(e)?.displayName??this.formatTenantDisplayName(e):null}),this.selectedProjectDisplayName=j(()=>{const e=this.selectedProjectId.get();if(!e)return null;const t=this.projectDiscovery.get();return t?.kind!=="available"?e:t.projects.find(s=>s.project.id===e)?.project.title??e}),this.entityById=j(()=>{const e=this.snapshot.get(),t=e?.initiatives.flatMap(a=>[a.initiative,...a.prds,...a.userStories,...a.adrs,...a.issues])??[],s=[...this.entityDetails.get().values()].flatMap(a=>a.detail?[a.detail]:[]),i=s.map(a=>a.entity),r=s.flatMap(a=>[...(a.incoming??[]).map(({entity:o})=>zt(o)),...(a.outgoing??[]).map(({entity:o})=>zt(o))]);return new Map([...e?.entities??[],...e?.projectAdrs??[],...t,...r,...i].map(a=>[a.id,a]))}),this.globalSearchRecentRecords=j(()=>this.globalSearchRecents.get().flatMap(e=>{const t=this.snapshot.get();if(!t)return[];if(e.type==="entity"){const a=this.entityForId(e.entityId);return a?[{sourceType:"entity",target:e,title:a.title}]:[]}if(e.type==="plan-entry"){const a=t.planEntries?.find(o=>o.id===e.entryId&&o.planId===e.planId&&!o.tombstone);return a&&this.entityForId(e.planId)?[{sourceType:"plan-entry",target:e,title:a.body??"Plan entry"}]:[]}if(e.type==="issue-comment"){const a=t.issueComments[e.issueId]?.comments.find(o=>o.id===e.commentId&&!o.tombstone);return a&&this.entityForId(e.issueId)?[{sourceType:"issue-comment",target:e,title:a.body??"Comment"}]:[]}const s=[t.contexts.shared,...t.contexts.initiatives],i=e.scopeRef?s.find(a=>a.context.key===e.scopeRef||a.context.scopeEntityId===e.scopeRef):t.contexts.shared;if(!i?.context.exists)return[];if(e.type==="context")return[{sourceType:"context",target:e,title:i.context.title}];const r=i.terms.find(a=>a.term===e.term);return r?[{sourceType:"context-term",target:e,title:r.term}]:[]})),this.cascadeColumns=j(()=>this.cascadePath.get().map(e=>this.entityForId(e)).filter(e=>!!e)),this.masterCollapsed=j(()=>{const e=this.masterCollapsedOverride.get();return e!==null?e:!1}),this.cascadeColumnWidth=480,this.cascadeColumnGap=16,this.cascadeColumnWindow=j(()=>{const e=this.cascadeColumns.get(),t=this.cascadeCapacityForWidth(this.cascadeAvailableWidth.get());if(e.length<=t)return{breadcrumb:[],columns:e};const s=e.length-t,i=this.cascadeWindowStart.get(),r=Math.min(Math.max(i??s,0),e.length-1);return{breadcrumb:e.slice(0,r),columns:e.slice(r)}}),this.selectedEntity=j(()=>this.entityForId(this.selectedId.get())),this.selectedBundle=j(()=>this.bundleForEntityId(this.selectedId.get())),this.selectedInitiativeBundle=j(()=>this.bundleForInitiativeId(this.selectedInitiativeId.get())),this.activeInitiativeId=j(()=>this.selectedInitiativeId.get()??this.selectedBundle.get()?.initiative.id??null),this.sharedContext=j(()=>this.projectContextCache.get().data?.shared??this.snapshot.get()?.contexts.shared??null),this.initiativeContextById=j(()=>new Map((this.projectContextCache.get().data?.initiatives??this.snapshot.get()?.contexts.initiatives??[]).filter(e=>!!e.context.scopeEntityId).map(e=>[e.context.scopeEntityId??e.context.key,e]))),this.selectedContext=j(()=>{const e=this.selectedBundle.get();return e?this.initiativeContextById.get().get(e.initiative.id)??null:this.sharedContext.get()}),this.projectContextTerms=j(()=>{const e=this.projectContextCache.get().data?.terms;if(e)return e;const t=new Map;for(const s of[this.sharedContext.get(),...this.projectContextCache.get().data?.initiatives??this.snapshot.get()?.contexts.initiatives??[]])if(s)for(const i of s.terms){const r=i.term.toLowerCase(),a={avoid:[...i.avoid],contextKey:s.context.key,contextTitle:s.context.title,definition:i.definition,scopeEntityId:s.context.scopeEntityId,scopeKind:s.context.scopeKind,scopeLabel:s.context.scopeLabel,updatedAt:i.updatedAt},o=t.get(r);if(!o){t.set(r,{term:i.term,sources:[a],hasSharedSource:s.context.scopeKind==="default",hasDuplicates:!1,hasConflictingDefinitions:!1});continue}o.sources.push(a),o.hasDuplicates=o.sources.length>1,o.hasSharedSource=o.hasSharedSource||s.context.scopeKind==="default",o.hasConflictingDefinitions=rn(o.sources),i.term.localeCompare(o.term)<0&&(o.term=i.term)}return[...t.values()].map(s=>({...s,sources:s.sources.sort(vc)})).sort((s,i)=>s.term.localeCompare(i.term))}),this.filteredProjectContextTerms=j(()=>{const e=this.contextSearch.get().trim().toLowerCase();return e?this.projectContextTerms.get().filter(t=>t.term.toLowerCase().includes(e)?!0:t.sources.some(s=>[s.scopeLabel,s.contextTitle,s.definition,...s.avoid].join(" ").toLowerCase().includes(e))):this.projectContextTerms.get()}),this.filteredInitiativeContextTerms=j(()=>{const e=this.selectedContextInitiativeId.get(),t=this.contextSearch.get().trim().toLowerCase();return this.projectContextTerms.get().map(s=>{const i=s.sources.filter(a=>a.scopeKind==="initiative"&&(!e||a.scopeEntityId===e));return i.length===0||!(!t||s.term.toLowerCase().includes(t)||i.some(a=>[a.scopeLabel,a.contextTitle,a.definition,...a.avoid].join(" ").toLowerCase().includes(t)))?null:{...s,sources:i,hasSharedSource:!1,hasDuplicates:i.length>1,hasConflictingDefinitions:rn(i)}}).filter(s=>s!==null)}),this.filteredSharedContext=j(()=>{const e=this.sharedContext.get();if(!e)return null;const t=this.contextSearch.get().trim().toLowerCase();if(!t)return e;const s=[e.context.key,e.context.scopeLabel,e.context.summary,e.context.title].join(" ").toLowerCase().includes(t),i=e.terms.filter(r=>[r.term,r.definition,...r.avoid].join(" ").toLowerCase().includes(t));return!s&&i.length===0?null:{context:{...e.context,summary:s?e.context.summary:""},terms:i}}),this.projectContextDuplicateCount=j(()=>this.projectContextTerms.get().filter(e=>e.hasDuplicates).length),this.selectedIncoming=j(()=>this.incomingRelationsFor(this.selectedId.get())),this.selectedOutgoing=j(()=>this.outgoingRelationsFor(this.selectedId.get())),this.relatedEntities=j(()=>{const e=new Set;for(const t of[...this.selectedIncoming.get(),...this.selectedOutgoing.get()])e.add(t.fromId),e.add(t.toId);return e.delete(this.selectedId.get()??""),this.sortEntities([...e].map(t=>this.entityById.get().get(t)).filter(t=>!!t))}),this.localGraphEntities=j(()=>{const e=this.selectedEntity.get();return e?[e,...this.relatedEntities.get()]:[]}),this.localGraphRelations=j(()=>{const e=new Set(this.localGraphEntities.get().map(t=>t.id));return this.scopedRelations().filter(t=>e.has(t.fromId)&&e.has(t.toId))}),this.filteredEntities=j(()=>{const e=this.search.get().trim().toLowerCase(),t=this.kindFilter.get();return this.sortEntities((this.snapshot.get()?.entities??[]).filter(s=>t!=="all"&&s.kind!==t?!1:e?[s.id,s.kind,s.status,s.title].join(" ").toLowerCase().includes(e):!0))}),this.kindOptions=j(()=>["issue","all",...new Set((this.snapshot.get()?.entities??[]).map(e=>e.kind).filter(e=>e!=="issue"))]),this.rootTabCounts=j(()=>({adrs:(this.snapshot.get()?.entities??[]).filter(e=>e.kind==="adr").length,initiatives:this.snapshot.get()?.initiatives.length??0})),this.allDebtRecords=j(()=>this.sortEntities(this.projectDebtCache.get().data?.records??(this.snapshot.get()?.entities??[]).filter(e=>e.kind==="debt"))),this.debtRecords=j(()=>{const e=this.debtLifecycleFilter.get(),t=this.debtCategoryFilter.get(),s=this.debtPriorityFilter.get();return this.sortEntities(this.allDebtRecords.get().filter(i=>(e==="all"||i.status===e)&&(t==="all"||i.category===t)&&(s==="all"||i.priority===s)))}),this.projectInitiatives=j(()=>this.snapshot.get()?.initiatives??this.projectSummaryInitiatives.get().map(e=>({adrs:[],blockerLinks:[],constrainsLinks:[],entities:[zt(e.initiative)],fixLinks:[],initiative:zt(e.initiative),issues:[],prds:[],subIssueLinks:[],userStories:[]}))),this.projectSummaryEpicGroups=j(()=>{const e=this.projectSummary.get();return e?.kind==="available"?e.epics:[]}),this.projectSummaryInitiatives=j(()=>this.projectSummaryEpicGroups.get().flatMap(e=>e.initiatives)),this.epicInitiativeGroups=j(()=>{const e=this.snapshot.get();if(!e)return[];const t=new Map(e.initiatives.map(i=>[i.initiative.id,i])),s=new Map;for(const i of e.relations){if(i.type!=="contains"||!t.has(i.toId))continue;const r=s.get(i.fromId)??[];r.push(i.toId),s.set(i.fromId,r)}return this.sortEntities(e.entities.filter(i=>i.kind==="epic")).map(i=>{const r=(s.get(i.id)??[]).map(a=>t.get(a)).filter(a=>!!a);return{epic:i,initiatives:r,completedInitiativeCount:r.filter(a=>this.isDoneStatus(a.initiative.status)).length}}).filter(i=>i.initiatives.length>0)}),this.projectAdrs=j(()=>this.sortEntities(this.projectAdrsCache.get().data?.projectAdrs??this.snapshot.get()?.projectAdrs??(this.snapshot.get()?.entities??[]).filter(e=>e.kind==="adr"))),this.adrRailEntries=j(()=>{const e=this.snapshot.get(),t=this.projectAdrs.get().map(r=>({adr:r,scope:"project",scopeLabel:"project decision"})),i=(this.projectAdrsCache.get().data?.initiativeAdrs??e?.initiatives??[]).flatMap(r=>this.sortEntities(r.adrs).map(a=>({adr:a,scope:"initiative",scopeLabel:`initiative ${r.initiative.title}`})));return[...t,...i]}),this.projectStoryCount=j(()=>this.projectSummaryInitiatives.get().reduce((e,t)=>e+t.userStoryCount,0)),this.projectIssueCount=j(()=>this.projectSummaryInitiatives.get().reduce((e,t)=>e+t.issueCount,0)),this.projectDescription=j(()=>this.sharedContext.get()?.context.summary??this.selectedTenantDisplayName.get()??""),this.orphanIds=j(()=>new Set((this.snapshot.get()?.orphans??[]).map(e=>e.id))),this.connected=!1,this.events=null,this.pollTimer=null,this.onHashChange=()=>{const e=this.applyRoute(this.readRoute());this.writeRoute(e,!0)},this.onPopState=async()=>{const e=this.readRoute();if(e.tenantId!==this.selectedTenant.get()||e.projectId!==this.selectedProjectId.get()){await this.navigateToRoute(e);return}this.applyRoute(e)},this.onBrowserNavigation=async()=>{await this.navigateToRoute(this.readRoute()),new URLSearchParams(new URL(window.location.href).hash.slice(1)).has("cascade")&&this.writeRoute(this.currentRoute(),!0)},this.setSearchFromEvent=e=>{this.search.set(e.target.value)},this.setKindFilterFromEvent=e=>{this.kindFilter.set(e.target.value)},this.setTenantFromEvent=e=>{const t=e.target.value;this.selectTenant(t)},this.selectEntityFromEvent=e=>{const t=e.currentTarget.dataset.id;t&&this.selectEntity(t)},this.openViewFromEvent=e=>{const t=e.currentTarget.dataset.view;t&&this.activeView.set(t)},this.selectInitiativeFromEvent=e=>{const t=e.currentTarget.dataset.id;t&&this.selectInitiative(t)}}entityForId(e){return e?this.entityById.get().get(e)??null:null}requestEntityTab(e,t){t==="plan"&&this.loadPlanEntryPage(e)}async loadMorePlanEntries(e){const t=this.planEntryPages.get().get(e)?.data?.nextBefore;t&&await this.loadPlanEntryPage(e,!1,t)}async loadMoreIssueComments(e){const t=this.issueCommentPages.get().get(e)?.data?.nextBefore;t&&await this.loadIssueCommentPage(e,!1,t)}openGlobalSearch(){this.globalSearchOpen.set(!0),this.globalSearchRecents.set(this.readGlobalSearchRecents()),this.reloadGlobalSearchCapability()}planEntriesFor(e){return this.planEntryPages.get().get(e)?.data?.entries??(this.snapshot.get()?.planEntries??[]).filter(t=>t.planId===e)}issueCommentsFor(e){return this.issueCommentPages.get().get(e)?.data?.comments??this.snapshot.get()?.issueComments[e]?.comments??[]}displayUser(e,t){const s=this.issueCommentPages.get().get(t)?.data?.users.find(i=>i.id===e)??this.snapshot.get()?.users.find(i=>i.id===e);return s?.displayName??s?.authenticationSubject??e}closeGlobalSearch(){this.globalSearchOpen.set(!1),this.setGlobalSearchQuery("")}setGlobalSearchQuery(e){if(this.globalSearchQuery.set(e),this.globalSearchResponse.set(null),this.globalSearchProgress.set(!1),this.cancelGlobalSearchRequest(),!e.trim()){this.globalSearchResults.set([]);return}this.globalSearchRequestTimer=window.setTimeout(()=>{this.requestGlobalSearch(e)},150)}setGlobalSearchScope(e){this.globalSearchScope.set(e),this.setGlobalSearchQuery(this.globalSearchQuery.get())}setGlobalSearchSourceTypes(e){this.globalSearchSourceTypes.set(e),this.setGlobalSearchQuery(this.globalSearchQuery.get())}async retryGlobalSearch(){const e=this.globalSearchQuery.get();e.trim()&&await this.requestGlobalSearch(e)}async reloadGlobalSearchCapability(){const e=this.selectedTenant.get();if(!e){this.globalSearchCapability.set(null);return}try{const t=await fetch(`/api/search/capability?${new URLSearchParams({tenant:e})}`,{cache:"no-store"});if(!t.ok)throw new Error("Global search capability request failed.");const s=await t.json();this.selectedTenant.get()===e&&this.globalSearchCapability.set(s)}catch{this.globalSearchCapability.set(null)}}async requestGlobalSearch(e){if(e!==this.globalSearchQuery.get())return;const t=this.selectedTenant.get(),s=this.selectedProjectId.get();if(!t||!s)return;const i=new AbortController;this.globalSearchAbortController=i,this.globalSearchProgressTimer=window.setTimeout(()=>{this.globalSearchAbortController===i&&this.globalSearchProgress.set(!0)},150);const r=new URLSearchParams({tenant:t,project:s,query:e,scope:this.globalSearchScope.get()});r.set("sourceTypes",this.globalSearchSourceTypes.get().join(","));try{const a=await fetch(`/api/search?${r}`,{cache:"no-store",signal:i.signal});if(!a.ok)throw new Error("Global search request failed.");const o=await a.json();this.globalSearchAbortController===i&&(this.globalSearchResponse.set(o),o.state==="available"&&this.globalSearchResults.set(o.results))}catch(a){if(a instanceof DOMException&&a.name==="AbortError")return;this.globalSearchAbortController===i&&this.globalSearchResponse.set({state:"operational-error"})}finally{this.globalSearchAbortController===i&&(this.globalSearchAbortController=null,this.clearGlobalSearchProgressTimer(),this.globalSearchProgress.set(!1))}}cancelGlobalSearchRequest(){this.globalSearchRequestTimer!==null&&(window.clearTimeout(this.globalSearchRequestTimer),this.globalSearchRequestTimer=null),this.globalSearchAbortController?.abort(),this.globalSearchAbortController=null,this.clearGlobalSearchProgressTimer()}clearGlobalSearchProgressTimer(){this.globalSearchProgressTimer!==null&&(window.clearTimeout(this.globalSearchProgressTimer),this.globalSearchProgressTimer=null)}cascadeCapacityForWidth(e){return e<=0?Number.POSITIVE_INFINITY:Math.max(1,Math.floor(e/(this.cascadeColumnWidth+this.cascadeColumnGap)))}cascadeHopRelation(e,t){const s=this.snapshot.get()?.relations??[],i=s.find(a=>a.fromId===e&&a.toId===t);return i?i.type:s.find(a=>a.fromId===t&&a.toId===e)?.type??null}cascadePathForLeaf(e){const t=this.snapshot.get()?.relations??[],s=[e],i=new Set([e]);let r=e;for(;;){const p=t.find(d=>d.type==="decomposes"&&d.toId===r);if(!p||i.has(p.fromId))break;s.unshift(p.fromId),i.add(p.fromId),r=p.fromId}const a=s[0],l=this.sortEntities(t.filter(p=>p.type==="fixes"&&p.fromId===a).map(p=>this.entityForId(p.toId)).filter(p=>!!p))[0]?.id??null;return[...this.spineForStory(l,a),...s]}spineForStory(e,t){const s=this.snapshot.get()?.relations??[],i=e?s.find(o=>o.type==="creates"&&o.toId===e)?.fromId??null:null,r=i?s.find(o=>o.type==="owns"&&o.toId===i)?.fromId??null:s.find(o=>o.type==="tracks"&&o.toId===t)?.fromId??null,a=[];return r&&a.push(r),i&&a.push(i),e&&a.push(e),a}cascadeSeamFor(e,t){const s=this.cascadeHopRelation(e,t);if(s!=="fixes")return{relation:s,branch:null};const i=this.snapshot.get()?.relations??[],r=this.sortEntities(i.filter(a=>a.type==="fixes"&&a.fromId===t).map(a=>this.entityForId(a.toId)).filter(a=>!!a));return r.length<=1?{relation:s,branch:null}:{relation:s,branch:{options:r,selectedIndex:r.findIndex(a=>a.id===e)}}}selectCascadeBranch(e,t){const s=this.cascadePath.get(),i=s.indexOf(e);if(i===-1)return;const r=s.slice(i),a=this.spineForStory(t,e);this.cascadeWindowStart.set(null),this.cascadePath.set([...a,...r]),this.clearMasterOverrideIfShallow(),this.writeCascadeHash()}bundleForEntityId(e){return e?(this.snapshot.get()?.initiatives??[]).find(t=>[t.initiative,...t.entities,...t.prds,...t.userStories,...t.adrs,...t.issues].some(s=>s.id===e))??null:null}bundleForInitiativeId(e){if(!e)return null;const t=(this.snapshot.get()?.initiatives??[]).find(p=>p.initiative.id===e)??null;if(t)return t;const s=this.projectSummaryInitiatives.get().find(p=>p.initiative.id===e);if(!s)return null;const i=this.initiativeDetailForId(e),r=this.initiativeTabForId(e,this.initTab.get()),a=i?.initiative??{...s.initiative,body:""},o=r?.records??[],l=new Map([a,...o].map(p=>[p.id,p])),u=r?.relations??[];return{adrs:o.filter(p=>p.kind==="adr"),blockerLinks:u.filter(p=>p.type==="blocks").flatMap(p=>{const d=l.get(p.fromId),g=l.get(p.toId);return d&&g?[{source:d,target:g}]:[]}),constrainsLinks:u.filter(p=>p.type==="constrains").flatMap(p=>{const d=l.get(p.fromId),g=l.get(p.toId);return d&&g?[{adr:d,issue:g}]:[]}),entities:[a,...o],fixLinks:u.filter(p=>p.type==="fixes").flatMap(p=>{const d=l.get(p.fromId),g=l.get(p.toId);return d&&g?[{issue:d,userStory:g}]:[]}),initiative:a,issues:o.filter(p=>p.kind==="issue"),prds:o.filter(p=>p.kind==="prd"),relations:u,subIssueLinks:u.filter(p=>p.type==="decomposes").flatMap(p=>{const d=l.get(p.fromId),g=l.get(p.toId);return d&&g?[{parent:d,issue:g}]:[]}),userStories:o.filter(p=>p.kind==="userStory")}}initiativeDetailForId(e){return e?this.initiativeDetails.get().get(e)?.detail??null:null}initiativeTabForId(e,t){return e?this.initiativeTabs.get().get(this.initiativeTabCacheKey(e,t))?.data??null:null}isSummaryInitiative(e){return!this.snapshot.get()?.initiatives.some(t=>t.initiative.id===e)&&this.projectSummaryInitiatives.get().some(t=>t.initiative.id===e)}incomingRelationsFor(e){return e?this.scopedRelations().filter(t=>t.toId===e):[]}outgoingRelationsFor(e){return e?this.scopedRelations().filter(t=>t.fromId===e):[]}scopedRelations(){const e=new Map;for(const t of this.snapshot.get()?.relations??[])e.set(`${t.fromId}:${t.type}:${t.toId}`,t);for(const t of[...this.entityDetails.get().values()].flatMap(s=>s.detail?[s.detail]:[]))for(const s of gc(t))e.set(`${s.fromId}:${s.type}:${s.toId}`,s);return[...e.values()]}connect(){this.connected||(this.connected=!0,this.applyRoute(this.readRoute(),!1),window.addEventListener("hashchange",this.onBrowserNavigation),window.addEventListener("popstate",this.onPopState),this.bootstrap())}disconnect(){this.connected&&(this.connected=!1,this.cancelInitiativeTabPrefetch(),window.removeEventListener("hashchange",this.onBrowserNavigation),window.removeEventListener("popstate",this.onPopState),this.cancelGlobalSearchRequest(),this.events?.close(),this.events=null,this.pollTimer!==null&&(window.clearInterval(this.pollTimer),this.pollTimer=null))}applyLocalProjectChange(e){this.handleProjectChange(e),this.registerLocalChangeCorrelation(e.correlationId)}async mutateProject(e,t){const s=globalThis.crypto.randomUUID();this.registerLocalChangeCorrelation(s);try{const i=await fetch(this.buildTenantScopedPath("/api/project-mutation"),{body:JSON.stringify({correlationId:s,method:e,params:t}),cache:"no-store",headers:{"content-type":"application/json"},method:"POST"});if(!i.ok)throw new Error(`Project mutation ${e} failed.`);const r=await i.json();return this.applyLocalProjectChange(r.event),r.result}catch(i){throw this.localChangeCorrelations.delete(s),i}}registerLocalChangeCorrelation(e){if(!e)return;const t=Date.now();for(const[s,i]of this.localChangeCorrelations)i<t&&this.localChangeCorrelations.delete(s);this.localChangeCorrelations.set(e,t+lc)}openRootTab(e){this.activeRootTab.set(e)}selectSection(e){this.activeSection.set(e),this.selectedInitiativeId.set(null),this.selectedId.set(null),this.selectedNestedTarget.set(null),this.initTab.set("overview"),this.contextSearch.set(""),this.contextTab.set("all"),this.selectedContextInitiativeId.set(null),this.activePage.set("list"),this.writeRoute(this.currentRoute()),e==="adrs"?this.loadProjectAdrs():e==="debt"?this.loadProjectDebt():e==="context"?this.loadProjectContext():e==="graph"&&this.loadProjectGraph()}setContextTab(e){this.contextTab.set(e)}setContextInitiativeFilter(e){this.selectedContextInitiativeId.set(e)}setMasterStatusFilter(e,t){if(e==="initiatives"){this.initiativeStatusFilter.set(t);return}this.adrStatusFilter.set(t)}setDebtFilter(e,t){if(e==="lifecycle"){this.debtLifecycleFilter.set(t);return}if(e==="category"){this.debtCategoryFilter.set(t);return}this.debtPriorityFilter.set(t)}setInitTab(e){this.initTab.set(e),this.writeRoute(this.currentRoute());const t=this.selectedInitiativeId.get();t&&e!=="overview"&&this.projectSummaryInitiatives.get().some(s=>s.initiative.id===t)&&this.loadInitiativeTab(t,e)}async retryInitiativeDetail(e){await this.loadInitiativeDetail(e,!0)}async retryInitiativeTab(e,t){await this.loadInitiativeTab(e,t,!0)}openSearchTarget(e){if(this.recordGlobalSearchRecent(e),e.type==="entity"){this.selectEntity(e.entityId);return}if(e.type==="plan-entry"){this.selectEntity(e.planId,{id:e.entryId,type:e.type});return}if(e.type==="issue-comment"){this.selectEntity(e.issueId,{id:e.commentId,type:e.type});return}(e.type==="context"||e.type==="context-term")&&(this.activeSection.set("context"),this.selectedInitiativeId.set(null),this.selectedId.set(null),this.activePage.set("list"),this.contextTab.set(e.scopeRef?"initiatives":"global"),this.selectedContextInitiativeId.set(e.scopeRef??null),this.selectedNestedTarget.set(e.type==="context"?{id:null,scopeRef:e.scopeRef,type:e.type}:{id:e.term,scopeRef:e.scopeRef,type:e.type}),this.writeRoute(this.currentRoute()))}globalSearchRecentsStorageKey(){const e=this.selectedTenant.get(),t=this.selectedProjectId.get();return e&&t?`${ac}:${e}:${t}`:null}readGlobalSearchRecents(){const e=this.globalSearchRecentsStorageKey();if(!e)return[];try{const t=window.localStorage.getItem(e);if(!t)return[];const s=JSON.parse(t);return Array.isArray(s)?s.filter(hc).slice(0,tn):[]}catch{return[]}}recordGlobalSearchRecent(e){const t=this.globalSearchRecentsStorageKey();if(!t)return;const s=this.readGlobalSearchRecents(),i=JSON.stringify(e),r=[e,...s.filter(a=>JSON.stringify(a)!==i)].slice(0,tn);window.localStorage.setItem(t,JSON.stringify(r)),this.globalSearchRecents.set(r)}selectEntity(e,t=null){if(this.entityForId(e)?.kind==="initiative"){this.selectInitiative(e);return}this.cascadePath.set([]),this.selectedInitiativeId.set(null),this.selectedId.set(e),this.selectedNestedTarget.set(t),this.activePage.set("entity"),this.writeRoute(this.currentRoute()),this.loadEntityDetail(e),this.entityForId(e)?.kind==="issue"&&this.loadIssueCommentPage(e)}selectProjectGraphEntity(e,t){this.activeSection.set(t==="adr"?"adrs":"initiatives"),this.selectEntity(e)}openCascade(e){this.cascadeWindowStart.set(null),this.cascadePath.set([e]),this.clearMasterOverrideIfShallow(),this.writeCascadeHash()}toggleRail(){this.railCollapsed.set(!this.railCollapsed.get())}toggleMaster(){this.masterCollapsedOverride.set(!this.masterCollapsed.get())}isEpicExpanded(e){const t=this.selectedProjectId.get();return!t||!this.collapsedEpicIdsByProject.get().get(t)?.has(e)}toggleEpicExpanded(e){const t=this.selectedProjectId.get();if(!t)return;const s=new Map(this.collapsedEpicIdsByProject.get()),i=new Set(s.get(t));i.has(e)?i.delete(e):i.add(e),s.set(t,i),this.collapsedEpicIdsByProject.set(s)}clearMasterOverrideIfShallow(){this.cascadePath.get().length<2&&this.masterCollapsedOverride.set(null)}reRootCascade(e){const t=this.cascadePath.get();t.length>0&&this.reRootTrail.set([...this.reRootTrail.get(),t]),this.cascadeWindowStart.set(null),this.cascadePath.set(this.cascadePathForLeaf(e)),this.clearMasterOverrideIfShallow(),this.writeCascadeHash()}restoreReRoot(e){const t=this.reRootTrail.get(),s=t[e];s&&(this.reRootTrail.set(t.slice(0,e)),this.cascadeWindowStart.set(null),this.cascadePath.set(s),this.clearMasterOverrideIfShallow(),this.writeCascadeHash())}popReRoot(){const e=this.reRootTrail.get();e.length!==0&&this.restoreReRoot(e.length-1)}drillCascade(e,t){const s=this.cascadePath.get().indexOf(e);s!==-1&&(this.cascadeWindowStart.set(null),this.cascadePath.set([...this.cascadePath.get().slice(0,s+1),t]),this.writeCascadeHash())}restoreAncestor(e){const t=this.cascadePath.get().indexOf(e);t!==-1&&this.cascadeWindowStart.set(t)}truncateCascadeTo(e){const t=this.cascadePath.get(),s=t.indexOf(e);s===-1||s===t.length-1||(this.cascadeWindowStart.set(null),this.cascadePath.set(t.slice(0,s+1)),this.clearMasterOverrideIfShallow(),this.writeCascadeHash())}writeCascadeHash(){this.writeRoute(this.currentRoute())}selectInitiative(e){this.cancelInitiativeTabPrefetch(),this.selectedId.set(null),this.selectedInitiativeId.set(e),this.selectedNestedTarget.set(null),this.activePage.set("initiative"),this.activeSection.set("initiatives"),this.activeView.set("overview"),this.initTab.set("overview"),this.cascadePath.set([]),this.clearMasterOverrideIfShallow(),this.writeRoute(this.currentRoute()),this.isSummaryInitiative(e)&&(this.loadInitiativeDetail(e),this.startInitiativeTabPrefetch(e))}clearSelection(){this.cancelInitiativeTabPrefetch(),this.cascadePath.set([]),this.clearMasterOverrideIfShallow(),this.selectedInitiativeId.set(null),this.selectedId.set(null),this.selectedNestedTarget.set(null),this.activePage.set("list"),this.activeView.set("overview"),this.writeRoute(this.currentRoute())}async selectTenant(e){!e||e===this.selectedTenant.get()||(this.selectedTenant.set(e),this.selectedProjectId.set(null),this.resetScopeDetail(),this.writeRoute(this.currentRoute()),this.stopLiveUpdates(),this.syncLabel.set("choose a project"),await this.reloadProjectDiscovery())}async returnToProjectChooser(){!this.selectedTenant.get()||!this.selectedProjectId.get()||(this.selectedProjectId.set(null),this.snapshot.set(null),this.projectSummary.set(null),this.resetScopeDetail(),this.writeRoute(this.currentRoute()),this.stopLiveUpdates(),this.syncLabel.set("choose a project"),await this.reloadProjectDiscovery())}async selectProject(e){if(!(!this.selectedTenant.get()||!e||e===this.selectedProjectId.get())){this.selectedProjectId.set(e),this.resetScopeDetail(),this.writeRoute(this.currentRoute()),this.stopLiveUpdates(),this.syncLabel.set("connecting");try{await this.reloadProjectSummary(),this.connectEvents()}catch(s){this.selectedProjectId.set(null),this.snapshot.set(null),this.projectSummary.set(null),this.writeRoute(this.currentRoute(),!0),this.errorMessage.set(s instanceof Error?s.message:String(s)),this.syncLabel.set("project unavailable")}}}initiativeStats(e){const t=this.projectSummaryInitiatives.get().find(a=>a.initiative.id===e.initiative.id);if(t){const a=t.issueCount>0?Math.round(t.completedIssueCount/t.issueCount*100):0;return{adrs:t.adrCount??e.adrs.length,done:t.completedIssueCount,issues:t.issueCount,pct:a,stories:t.userStoryCount}}const s=e.issues.length,i=e.issues.filter(a=>this.isDoneStatus(a.status)).length,r=s>0?Math.round(i/s*100):0;return{adrs:e.adrs.length,done:i,issues:s,pct:r,stories:e.userStories.length}}issuesForStory(e,t){const s=new Set(e.fixLinks.filter(i=>i.userStory.id===t).map(i=>i.issue.id));return this.sortEntities(e.issues.filter(i=>s.has(i.id)))}subIssuesForIssue(e,t){return this.sortEntities(e.subIssueLinks.filter(s=>s.parent.id===t).map(s=>s.issue))}parentIssueForIssue(e,t){return e.subIssueLinks.find(s=>s.issue.id===t)?.parent??null}issueTreeForStory(e,t){const s=new Map(e.subIssueLinks.map(l=>[l.issue.id,l.parent.id])),i=new Map;for(const l of e.subIssueLinks){const u=i.get(l.parent.id)??[];u.push(l.issue.id),i.set(l.parent.id,u)}const r=new Set,a=this.issuesForStory(e,t);for(const l of a){const u=[l.id];for(;u.length>0;){const d=u.shift();if(!(!d||r.has(d))){r.add(d);for(const g of i.get(d)??[])u.push(g)}}let p=l.id;for(;p;){if(r.has(p)){p=s.get(p)??null;continue}r.add(p),p=s.get(p)??null}}const o=[...r].filter(l=>{const u=s.get(l);return!u||!r.has(u)});return this.buildIssueTree(e,o,r)}issueTreeForDirectIssues(e){const t=new Set(e.userStories.flatMap(a=>this.issueTreeForStory(e,a.id).flatMap(o=>this.issueTreeNodeIds(o)))),s=new Set(e.issues.map(a=>a.id).filter(a=>!t.has(a))),i=new Map(e.subIssueLinks.map(a=>[a.issue.id,a.parent.id])),r=[...s].filter(a=>{const o=i.get(a);return!o||!s.has(o)});return this.buildIssueTree(e,r,s)}subIssueTreeForIssue(e,t){const s=new Set,i=this.subIssuesForIssue(e,t).map(r=>r.id);for(;i.length>0;){const r=i.shift();if(!(!r||s.has(r))){s.add(r);for(const a of this.subIssuesForIssue(e,r))i.push(a.id)}}return this.buildIssueTree(e,this.subIssuesForIssue(e,t).map(r=>r.id),s)}buildInitiativeGraph(e,t){const s=e.initiative,i=this.snapshot.get(),r=e.relations??i?.relations??[],a=e.relations?e.entities:i?.entities??[],o=[],l=[];new Map(e.issues.map(m=>[m.id,m]));const u=new Map,p=new Set(e.subIssueLinks.map(m=>m.issue.id)),d=new Map,g=this.sortEntities(e.entities.filter(m=>m.kind==="plan"));o.push({col:0,fullLabel:s.title,id:s.id,key:s.id,kind:"initiative",label:s.title});for(const m of g)o.push({col:1,fullLabel:m.title,id:m.id,key:m.id,kind:"plan",label:m.title,status:m.status}),l.push({from:s.id,to:m.id});for(const m of e.prds)o.push({col:1,fullLabel:m.title,id:m.id,key:m.id,kind:"prd",label:m.title}),l.push({from:s.id,to:m.id});for(const m of e.adrs)o.push({col:1,fullLabel:m.title,id:m.id,key:m.id,kind:"adr",label:m.title}),l.push({from:s.id,to:m.id});for(const m of e.userStories)o.push({col:2,fullLabel:m.title,id:m.id,key:m.id,kind:"story",label:m.title}),l.push({from:s.id,to:m.id});for(const m of e.subIssueLinks){const P=u.get(m.parent.id)??[];P.push(m.issue),u.set(m.parent.id,P)}for(const[m,P]of u)u.set(m,this.sortEntities(P));for(const m of e.fixLinks){const P=d.get(m.issue.id)??[];P.push(m.userStory.id),d.set(m.issue.id,P)}const b=this.sortEntities(e.issues.filter(m=>!p.has(m.id)));let x=0;const E=new Set,O=(m,P)=>{if(E.has(m.id)){x=Math.max(x,P);return}E.add(m.id),x=Math.max(x,P),o.push({col:3+P,fullLabel:m.title,id:m.id,key:m.id,kind:"issue",label:m.title,status:m.status});const J=d.get(m.id)??[];if(J.length>0)for(const we of J)l.push({from:we,to:m.id});else P===0&&l.push({from:s.id,to:m.id});for(const we of u.get(m.id)??[])O(we,P+1),l.push({from:m.id,to:we.id})};for(const m of b)O(m,0);for(const m of this.sortEntities(e.issues))E.has(m.id)||O(m,0);const I=["Issues"];for(let m=1;m<=x;m+=1)I.push(m===1?"Sub-issues":"Nested sub-issues");const _=3+I.length,y=this.sortEntities(a.filter(m=>m.kind==="debt"&&r.some(P=>P.fromId===s.id&&P.toId===m.id&&P.type==="records")));for(const m of y)o.push({col:_,fullLabel:m.title,id:m.id,key:m.id,kind:"debt",label:m.title,status:m.status}),l.push({from:s.id,label:"records",to:m.id});const R=new Set(o.map(m=>m.id)),T=new Set(y.map(m=>m.id)),M=new Set(g.map(m=>m.id));for(const m of r)m.type==="informs"&&M.has(m.fromId)&&R.has(m.toId)&&l.push({from:m.fromId,label:"informs",to:m.toId}),m.type==="resolves"&&R.has(m.fromId)&&T.has(m.toId)&&l.push({from:m.fromId,label:"resolves",to:m.toId}),m.type==="relatesTo"&&T.has(m.fromId)&&R.has(m.toId)&&l.push({from:m.fromId,label:"relatesTo",to:m.toId});const X={columns:["Initiative","Plans, PRDs & ADRs","User stories",...I,"Debt records"],edges:l,nodes:o};return t?sn(X,t):X}buildProjectGraph(){const e=this.projectGraphCache.get().data;if(e)return this.buildScopedProjectGraph(e);const t=this.snapshot.get(),s=this.epicInitiativeGroups.get(),i="__project",r=new Map,a=this.selectedProjectId.get(),o=[{col:0,fullLabel:this.projectDescription.get(),id:"",key:i,kind:"project",label:this.selectedTenantDisplayName.get()??""}],l=[];a&&r.set(a,i);for(const d of t?.projectAdrs??[])o.push({col:1,fullLabel:d.title,id:d.id,key:d.id,kind:"adr",label:d.title,status:d.status}),r.set(d.id,d.id),l.push({from:i,to:d.id});for(const d of s){const{epic:g}=d;o.push({col:1,fullLabel:g.title,id:g.id,key:g.id,kind:"epic",label:g.title,status:g.status}),r.set(g.id,g.id),l.push({from:i,to:g.id});for(const b of d.initiatives){const x=b.initiative,E=new Map,O=new Map;o.push({col:2,fullLabel:`${x.title} — ${b.userStories.length} stories, ${b.issues.length} issues`,id:x.id,key:x.id,kind:"initiative",label:x.title,status:x.status}),r.set(x.id,x.id),l.push({from:g.id,to:x.id});const I=[...this.sortEntities(b.entities.filter(_=>_.kind==="plan")).map(_=>({entity:_,kind:"plan"})),...b.prds.map(_=>({entity:_,kind:"prd"})),...b.adrs.map(_=>({entity:_,kind:"adr"}))];for(const{entity:_,kind:y}of I){const R=`${x.id}:${_.id}`;o.push({col:3,fullLabel:_.title,id:_.id,key:R,kind:y,label:_.title,status:_.status}),r.set(_.id,R),l.push({from:x.id,to:R})}for(const _ of this.sortEntities(b.userStories)){const y=`${x.id}:${_.id}`;E.set(_.id,y),r.set(_.id,y),o.push({col:4,fullLabel:_.title,id:_.id,key:y,kind:"story",label:_.title,status:_.status}),l.push({from:x.id,to:y})}for(const _ of b.fixLinks){const y=O.get(_.issue.id)??[];y.push(_.userStory.id),O.set(_.issue.id,y)}for(const _ of this.sortEntities(b.issues)){const y=`${x.id}:${_.id}`;r.set(_.id,y),o.push({col:5,fullLabel:_.title,id:_.id,key:y,kind:"issue",label:_.title,status:_.status});const R=(O.get(_.id)??[]).map(T=>E.get(T)).filter(T=>!!T);if(R.length>0)for(const T of R)l.push({from:T,to:y});else l.push({from:x.id,to:y})}}}const u=new Map,p=this.sortEntities((t?.entities??[]).filter(d=>d.kind==="debt"));for(const d of p){const g=(t?.relations??[]).find(x=>x.fromId!==d.id&&x.toId===d.id&&x.type==="records"),b=g?r.get(g.fromId):void 0;b&&(u.set(d.id,d.id),o.push({col:6,fullLabel:d.title,id:d.id,key:d.id,kind:"debt",label:d.title,status:d.status}),l.push({from:b,label:"records",to:d.id}))}for(const d of t?.relations??[]){if(d.type==="informs"){const g=r.get(d.fromId),b=r.get(d.toId);g&&b&&l.push({from:g,label:"informs",to:b})}if(d.type==="resolves"){const g=r.get(d.fromId),b=u.get(d.toId);g&&b&&l.push({from:g,label:"resolves",to:b})}if(d.type==="relatesTo"){const g=u.get(d.fromId),b=r.get(d.toId)??u.get(d.toId);g&&b&&l.push({from:g,label:"relatesTo",to:b})}}return sn({columns:["Project","Epics","Initiatives","Plans, PRDs & ADRs","User stories","Issues","Debt records"],edges:l,nodes:o},this.visibleProjectGraphKinds.get())}buildScopedProjectGraph(e){const t=this.sortEntities(e.records),s=[...new Set(t.map(l=>l.kind==="userStory"?"story":l.kind).filter(l=>ze.includes(l)))],i=new Map(s.map((l,u)=>[l,u])),r=new Set(t.map(l=>l.id)),a=t.flatMap(l=>{const u=l.kind==="userStory"?"story":l.kind,p=i.get(u);return p===void 0?[]:[{col:p,fullLabel:l.title,id:l.id,key:l.id,kind:u,label:l.title,status:l.status}]}),o=e.relations.filter(l=>r.has(l.fromId)&&r.has(l.toId)).map(l=>({from:l.fromId,label:l.type,to:l.toId}));return{columns:s.map(l=>l==="story"?"User stories":`${l.slice(0,1).toUpperCase()}${l.slice(1)}s`),edges:o,nodes:a}}toggleProjectGraphKind(e){const t=new Set(this.visibleProjectGraphKinds.get());t.has(e)?t.delete(e):t.add(e),this.visibleProjectGraphKinds.set(t)}isDoneStatus(e){return e==="done"||e==="complete"||e==="closed"}sortIssuesByExpectedCompletion(e,t){const s=new Map(e.map(g=>[g.id,g])),i=new Map(e.map((g,b)=>[g.id,b])),r=new Map(e.map(g=>[g.id,0])),a=new Map(e.map(g=>[g.id,[]])),o=new Set,l=(g,b)=>+!this.isDoneStatus(g.status)-+!this.isDoneStatus(b.status)||i.get(g.id)-i.get(b.id);for(const g of t.blockerLinks){if(!s.has(g.source.id)||!s.has(g.target.id)||!this.isDoneStatus(g.source.status)&&this.isDoneStatus(g.target.status))continue;const b=`${g.source.id}:${g.target.id}`;o.has(b)||(o.add(b),r.set(g.target.id,r.get(g.target.id)+1),a.get(g.source.id).push(g.target.id))}const u=e.filter(g=>r.get(g.id)===0),p=[],d=new Set;for(;u.length>0;){u.sort(l);const g=u.shift();if(!d.has(g.id)){d.add(g.id),p.push(g);for(const b of a.get(g.id)??[]){const x=r.get(b)-1;r.set(b,x),x===0&&u.push(s.get(b))}}}return[...p,...e.filter(g=>!d.has(g.id)).sort(l)]}issueStatusTone(e){return this.isDoneStatus(e)?"done":e==="blocked"||e==="paused"?"blocked":"open"}formatKindLabel(e){return e==="all"?"All work items":e==="userStory"?"User story":e==="prd"?"PRD":e==="adr"?"ADR":e?`${e.charAt(0).toUpperCase()}${e.slice(1)}`:"Unknown"}statusTone(e){return e==="blocked"||e==="paused"?"warn":e==="cancelled"?"danger":e==="archived"||e==="done"||e==="complete"||e==="closed"?"neutral":"success"}badgeTone(e){return e==="done"||e==="complete"||e==="closed"?"done":e==="blocked"||e==="cancelled"?"danger":e==="ready"||e==="in-progress"?"info":e==="paused"?"warn":e==="active"||e==="current"||e==="approved"?"success":"neutral"}compactPath(e){const t=e.split("/").filter(Boolean);return t.length<=3?e:`.../${t.slice(-3).join("/")}`}formatTimestamp(e){const t=new Date(e);return Number.isNaN(t.getTime())?e:new Intl.DateTimeFormat(void 0,{year:"numeric",month:"short",day:"numeric",hour:"numeric",minute:"2-digit"}).format(t)}truncate(e,t){return e.length<=t?e:`${e.slice(0,Math.max(0,t-3)).trimEnd()}...`}shortRef(e){return uc(e)}buildOpenedText(e){const t=this.selectedBundle.get(),s=t?`inside ${t.initiative.id}`:"outside a visible initiative bundle";return`Opened ${this.formatTimestamp(e.createdAt)} and currently ${s}. Last updated ${this.formatTimestamp(e.updatedAt)}.`}buildSummaryBody(e){const t=this.selectedBundle.get(),s=this.selectedContext.get(),i=this.selectedIncoming.get(),r=this.selectedOutgoing.get(),a=this.orphanIds.get(),o=t?`It currently sits in ${t.initiative.id}, which includes ${t.prds.length} PRDs, ${t.userStories.length} stories, ${t.adrs.length} ADRs, and ${t.issues.length} issues.`:"It is not currently connected to a visible initiative bundle in this snapshot.",l=a.has(e.id)?"This record is marked as orphaned from the initiative structure.":"This record remains connected to the main initiative structure.",u=s?`${s.context.title} is currently ${s.context.exists?"stored":"using its default shell"} with ${s.terms.length} defined terms.`:"No context is currently available for this record.";return`${e.id} is a ${this.formatKindLabel(e.kind).toLowerCase()} with ${i.length} incoming links and ${r.length} outgoing links. ${o} ${u} ${l}`}buildRelationSentence(e){return`${e.fromId} ${e.type} ${e.toId}`}relationLabel(e,t){const s={blocks:"Blocked by",constrains:"Constrained by",decomposes:"Parent issue",creates:"Created by",fixes:"Fixed by",handsOff:"Incoming handoffs",owns:"Owned by",records:"Recorded by",resolves:"Resolved by",tracks:"Tracked by"},i={blocks:"Blocks",constrains:"Constrains",decomposes:"Sub-issues",creates:"Creates",fixes:"Fixes",relatesTo:"Related records",resolves:"Resolves debt",owns:"Owns",records:"Records",tracks:"Tracks"};return t?s[e]??`${e} (incoming)`:i[e]??e}detailMeta(e){return this.detailMetaFor(e.id)}detailMetaFor(e){const t=e?this.entityById.get().get(e)??null:null,s=this.bundleForEntityId(e),i=t?this.incomingRelationsFor(t.id).find(u=>u.type==="records")?.fromId:null,r=i?this.entityById.get().get(i)??null:null,a=t?.kind==="debt"?[["Category",t.category??"—"],["Priority",t.priority??"—"],["Lifecycle",t.status],["Owner",r?`${this.shortRef(r)} ${r.title}`:"—"]]:[],o=t?.kind==="debt"?[]:[["Status",t?.status??"—"]],l=t?.type?[["Type",t.type]]:[];return[["Initiative",s?`${this.shortRef(s.initiative)} ${s.initiative.title}`:"—"],...a,...o,...l,["Created",t?this.formatTimestamp(t.createdAt):"—"],["Updated",t?this.formatTimestamp(t.updatedAt):"—"]]}linkedRecordSections(e){return this.linkedRecordSectionsFor(this.selectedId.get(),e)}linkedRecordSectionsFor(e,t){const s=new Set(["owns","creates","fixes","decomposes","tracks","constrains"]),i=new Map,r=new Set(t?.excludeRelationTypes??[]),a=new Set(t?.excludeRelatedIds??[]),o=(l,u,p)=>{if(a.has(l))return;const d=this.entityById.get().get(l);if(!d)return;const g=i.get(u)??{crossLink:!s.has(p),records:[]};g.records.push(d),i.set(u,g)};for(const l of this.outgoingRelationsFor(e))r.has(l.type)||o(l.toId,this.relationLabel(l.type,!1),l.type);for(const l of this.incomingRelationsFor(e))r.has(l.type)||o(l.fromId,this.relationLabel(l.type,!0),l.type);return[...i.entries()].map(([l,u])=>({crossLink:u.crossLink,key:l,records:this.sortEntities(u.records),title:l}))}debtRecordSectionsFor(e){const t=e?this.entityById.get().get(e)??null:null;if(!t||!["project","epic","initiative","issue"].includes(t.kind))return[];const s=this.outgoingRelationsFor(t.id).filter(r=>r.type==="records").map(r=>this.entityById.get().get(r.toId)).filter(r=>r?.kind==="debt"),i=["epic","initiative","issue"].includes(t.kind)?this.outgoingRelationsFor(t.id).filter(r=>r.type==="resolves").map(r=>this.entityById.get().get(r.toId)).filter(r=>r?.kind==="debt"):[];return[...s.length>0?[{key:"owned-debt",records:this.sortEntities(s),title:"Owned debt"}]:[],...i.length>0?[{key:"resolved-debt",records:this.sortEntities(i),title:"Resolves debt"}]:[]]}planProjectionFor(e){const t=[...this.planEntriesFor(e)].sort((r,a)=>r.createdAt.localeCompare(a.createdAt)||r.reference.localeCompare(a.reference)),s=new Set(t.flatMap(r=>r.supersededEntryIds)),i=t.filter(r=>!r.tombstone&&!s.has(r.id));return{current:cc.map(r=>({key:r.key,title:r.title,entries:i.filter(a=>bc(a,r.key))})),history:t}}closeEntity(){const e=this.selectedBundle.get();if(this.selectedId.set(null),this.selectedNestedTarget.set(null),this.activeSection.get()!=="adrs"&&e){this.selectedInitiativeId.set(e.initiative.id),this.activePage.set("initiative"),this.writeRoute(this.currentRoute());return}this.activePage.set("list"),this.writeRoute(this.currentRoute())}getContextForInitiative(e){return this.initiativeTabForId(e,"context")?.context??this.initiativeContextById.get().get(e)??null}async bootstrap(){try{const e=await this.fetchJson("site-config.json");this.config.set(e);const t=this.readRoute(),s={...t,tenantId:t.tenantId??e.currentTenant};this.selectedTenant.set(s.tenantId),await this.reloadProjectDiscovery(),await this.navigateToRoute(s),this.writeRoute(this.currentRoute(),!0)}catch(e){this.errorMessage.set(e instanceof Error?e.message:String(e)),this.syncLabel.set("load failed")}}async reloadProjectSummary(){const e=this.selectedTenant.get(),t=this.selectedProjectId.get(),s=await this.fetchJson(this.buildTenantScopedPath("/api/project-summary"));if(!(this.selectedTenant.get()!==e||this.selectedProjectId.get()!==t)){if(s.kind==="unavailable")throw new Error("Selected project is unavailable.");this.projectSummary.set(s),this.snapshot.set(null),this.errorMessage.set(null),this.syncLabel.set("listening")}}refreshProjectSummaryInBackground(){this.reloadProjectSummary().catch(e=>{this.errorMessage.set(e instanceof Error?e.message:String(e)),this.syncLabel.set("refresh failed")})}async loadInitiativeDetail(e,t=!1){const s=this.initiativeDetails.get().get(e);if(s?.loading||!t&&s?.detail&&!s.stale)return;const i=this.selectedTenant.get(),r=this.selectedProjectId.get();this.setInitiativeDetailCache(e,{detail:s?.detail??null,error:null,loading:!0,stale:s?.stale});try{const a=await this.fetchJson(this.buildTenantScopedPath(`/api/initiative-detail?initiative=${encodeURIComponent(e)}`));if(this.selectedTenant.get()!==i||this.selectedProjectId.get()!==r)return;if(!("initiative"in a)){this.selectedInitiativeId.get()===e&&this.clearSelection();return}this.setInitiativeDetailCache(e,{detail:a,error:null,loading:!1})}catch(a){if(this.selectedTenant.get()===i&&this.selectedProjectId.get()===r){const o=this.initiativeDetails.get().get(e);this.setInitiativeDetailCache(e,{detail:o?.detail??s?.detail??null,error:a instanceof Error?a.message:String(a),loading:!1,stale:o?.stale??s?.stale})}}}async retryProjectAdrs(){await this.loadProjectAdrs(!0)}async loadProjectAdrs(e=!1){const t=this.projectAdrsCache.get();if(t.loading||!e&&t.data&&!t.stale)return;const s=this.selectedTenant.get(),i=this.selectedProjectId.get();this.projectAdrsCache.set({data:t.data,error:null,loading:!0,stale:t.stale});try{const r=await this.fetchJson(this.buildTenantScopedPath("/api/project-adrs"));this.selectedTenant.get()===s&&this.selectedProjectId.get()===i&&this.projectAdrsCache.set({data:r,error:null,loading:!1})}catch(r){if(this.selectedTenant.get()===s&&this.selectedProjectId.get()===i){const a=this.projectAdrsCache.get();this.projectAdrsCache.set({data:a.data,error:r instanceof Error?r.message:String(r),loading:!1,stale:a.stale??t.stale})}}}async retryProjectDebt(){await this.loadProjectDebt(!0)}async loadProjectDebt(e=!1){await this.loadProjectRecordData("/api/project-debt",this.projectDebtCache,e)}async retryProjectContext(){await this.loadProjectContext(!0)}async loadProjectContext(e=!1){const t=this.projectContextCache.get();if(t.loading||!e&&t.data&&!t.stale)return;const s=this.selectedTenant.get(),i=this.selectedProjectId.get();this.projectContextCache.set({data:t.data,error:null,loading:!0,stale:t.stale});try{const r=await this.fetchJson(this.buildTenantScopedPath("/api/project-context"));this.selectedTenant.get()===s&&this.selectedProjectId.get()===i&&this.projectContextCache.set({data:r,error:null,loading:!1})}catch(r){if(this.selectedTenant.get()===s&&this.selectedProjectId.get()===i){const a=this.projectContextCache.get();this.projectContextCache.set({data:a.data,error:r instanceof Error?r.message:String(r),loading:!1,stale:a.stale??t.stale})}}}async retryProjectGraph(){await this.loadProjectGraph(!0)}async loadProjectGraph(e=!1){await this.loadProjectRecordData("/api/project-graph",this.projectGraphCache,e)}async loadProjectRecordData(e,t,s){const i=t.get();if(i.loading||!s&&i.data&&!i.stale)return;const r=this.selectedTenant.get(),a=this.selectedProjectId.get();t.set({data:i.data,error:null,loading:!0,stale:i.stale});try{const o=await this.fetchJson(this.buildTenantScopedPath(e));this.selectedTenant.get()===r&&this.selectedProjectId.get()===a&&t.set({data:o,error:null,loading:!1})}catch(o){if(this.selectedTenant.get()===r&&this.selectedProjectId.get()===a){const l=t.get();t.set({data:l.data,error:o instanceof Error?o.message:String(o),loading:!1,stale:l.stale??i.stale})}}}async loadPlanEntryPage(e,t=!1,s){const i=this.planEntryPages.get().get(e);if(i?.loading||!t&&i?.data&&!i.stale&&!s)return;const r=this.selectedTenant.get(),a=this.selectedProjectId.get();this.setPlanEntryPageCache(e,{data:i?.data??null,error:null,loading:!0,stale:i?.stale});try{const o=await this.fetchJson(this.buildTenantScopedPath(`/api/plan-entries?plan=${encodeURIComponent(e)}${s?`&before=${encodeURIComponent(s)}`:""}`));if(this.selectedTenant.get()===r&&this.selectedProjectId.get()===a){const l=s?[...new Map([...i?.data?.entries??[],...o.entries].map(u=>[u.id,u])).values()]:o.entries;this.setPlanEntryPageCache(e,{data:{...o,entries:l},error:null,loading:!1})}}catch(o){if(this.selectedTenant.get()===r&&this.selectedProjectId.get()===a){const l=this.planEntryPages.get().get(e);this.setPlanEntryPageCache(e,{data:l?.data??i?.data??null,error:o instanceof Error?o.message:String(o),loading:!1,stale:l?.stale??i?.stale})}}}setPlanEntryPageCache(e,t){const s=new Map(this.planEntryPages.get());s.set(e,t),this.planEntryPages.set(s)}async loadIssueCommentPage(e,t=!1,s){const i=this.issueCommentPages.get().get(e);if(i?.loading||!t&&i?.data&&!i.stale&&!s)return;const r=this.selectedTenant.get(),a=this.selectedProjectId.get();this.setIssueCommentPageCache(e,{data:i?.data??null,error:null,loading:!0,stale:i?.stale});try{const o=await this.fetchJson(this.buildTenantScopedPath(`/api/issue-comments?issue=${encodeURIComponent(e)}${s?`&before=${encodeURIComponent(s)}`:""}`));if(this.selectedTenant.get()===r&&this.selectedProjectId.get()===a){const l=s?[...new Map([...i?.data?.comments??[],...o.comments].map(p=>[p.id,p])).values()]:o.comments,u=s?[...new Map([...i?.data?.users??[],...o.users].map(p=>[p.id,p])).values()]:o.users;this.setIssueCommentPageCache(e,{data:{...o,comments:l,users:u},error:null,loading:!1})}}catch(o){if(this.selectedTenant.get()===r&&this.selectedProjectId.get()===a){const l=this.issueCommentPages.get().get(e);this.setIssueCommentPageCache(e,{data:l?.data??i?.data??null,error:o instanceof Error?o.message:String(o),loading:!1,stale:l?.stale??i?.stale})}}}setIssueCommentPageCache(e,t){const s=new Map(this.issueCommentPages.get());s.set(e,t),this.issueCommentPages.set(s)}entityDetailForId(e){return e?this.entityDetails.get().get(e)?.detail??null:null}async retryEntityDetail(e){await this.loadEntityDetail(e,!0)}async loadEntityDetail(e,t=!1){const s=this.entityDetails.get().get(e);if(s?.loading||!t&&s?.detail&&!s.stale)return;const i=this.selectedTenant.get(),r=this.selectedProjectId.get();this.setEntityDetailCache(e,{detail:s?.detail??null,error:null,loading:!0,stale:s?.stale});try{const a=await this.fetchJson(this.buildTenantScopedPath(`/api/entity-detail?entity=${encodeURIComponent(e)}`));if(this.selectedTenant.get()!==i||this.selectedProjectId.get()!==r)return;if(!("entity"in a)){this.selectedId.get()===e&&this.clearSelection();return}this.setEntityDetailCache(e,{detail:a,error:null,loading:!1}),a.entity.kind==="issue"&&this.loadIssueCommentPage(e)}catch(a){if(this.selectedTenant.get()===i&&this.selectedProjectId.get()===r){const o=this.entityDetails.get().get(e);this.setEntityDetailCache(e,{detail:o?.detail??s?.detail??null,error:a instanceof Error?a.message:String(a),loading:!1,stale:o?.stale??s?.stale})}}}setEntityDetailCache(e,t){const s=new Map(this.entityDetails.get());s.set(e,t),this.entityDetails.set(s)}setInitiativeDetailCache(e,t){const s=new Map(this.initiativeDetails.get());s.set(e,t),this.initiativeDetails.set(s)}async loadInitiativeTab(e,t,s=!1){const i=this.initiativeTabCacheKey(e,t),r=this.initiativeTabs.get().get(i);if(r?.loading||!s&&r?.data&&!r.stale)return;const a=this.selectedTenant.get(),o=this.selectedProjectId.get();this.setInitiativeTabCache(i,{data:r?.data??null,error:null,loading:!0,stale:r?.stale});try{const l=await this.fetchJson(this.buildTenantScopedPath(`/api/initiative-tab?initiative=${encodeURIComponent(e)}&tab=${t}`));if(this.selectedTenant.get()!==a||this.selectedProjectId.get()!==o)return;this.setInitiativeTabCache(i,{data:l,error:null,loading:!1})}catch(l){if(this.selectedTenant.get()===a&&this.selectedProjectId.get()===o){const u=this.initiativeTabs.get().get(i);this.setInitiativeTabCache(i,{data:u?.data??r?.data??null,error:l instanceof Error?l.message:String(l),loading:!1,stale:u?.stale??r?.stale})}}}startInitiativeTabPrefetch(e){if(this.cancelInitiativeTabPrefetch(),!this.connected)return;const t=this.initiativeTabPrefetchGeneration,s=[...pc],i=()=>{t!==this.initiativeTabPrefetchGeneration||this.selectedInitiativeId.get()!==e||s.length===0||(this.initiativeTabPrefetchTimer=window.setTimeout(()=>{this.initiativeTabPrefetchTimer=null,r()},oc))},r=async()=>{if(t!==this.initiativeTabPrefetchGeneration||this.selectedInitiativeId.get()!==e)return;const a=s[0];if(!a)return;const o=this.initiativeTabs.get().get(this.initiativeTabCacheKey(e,a));if(o?.loading){i();return}s.shift(),(!o?.data||o.stale)&&await this.loadInitiativeTab(e,a),i()};i()}cancelInitiativeTabPrefetch(){this.initiativeTabPrefetchGeneration+=1,this.initiativeTabPrefetchTimer!==null&&(window.clearTimeout(this.initiativeTabPrefetchTimer),this.initiativeTabPrefetchTimer=null)}initiativeTabCacheKey(e,t){return`${e}:${t}`}setInitiativeTabCache(e,t){const s=new Map(this.initiativeTabs.get());s.set(e,t),this.initiativeTabs.set(s)}async reloadProjectDiscovery(){try{this.projectDiscovery.set(await this.fetchJson(this.buildTenantScopedPath("/api/projects"))),this.errorMessage.set(null)}catch(e){this.projectDiscovery.set({kind:"unavailable"}),this.errorMessage.set(e instanceof Error?e.message:String(e))}}async navigateToRoute(e){const t=e.tenantId!==this.selectedTenant.get()||e.projectId!==this.selectedProjectId.get();if(this.selectedTenant.set(e.tenantId),this.selectedProjectId.set(e.projectId),t&&this.resetScopeDetail(),!e.projectId){this.snapshot.set(null),this.projectSummary.set(null),this.syncLabel.set("choose a project"),await this.reloadProjectDiscovery(),this.applyRoute(e);return}this.stopLiveUpdates(),this.syncLabel.set("connecting");try{await this.reloadProjectSummary(),this.connectEvents(),this.applyRoute(e)}catch(s){this.selectedProjectId.set(null),this.snapshot.set(null),this.projectSummary.set(null),this.writeRoute(this.currentRoute(),!0),this.errorMessage.set(s instanceof Error?s.message:String(s)),this.syncLabel.set("project unavailable")}}resetScopeDetail(){this.cancelInitiativeTabPrefetch(),this.cancelGlobalSearchRequest(),this.globalSearchCapability.set(null),this.globalSearchQuery.set(""),this.globalSearchResponse.set(null),this.globalSearchProgress.set(!1),this.globalSearchOpen.set(!1),this.entityDetails.set(new Map),this.projectAdrsCache.set({data:null,error:null,loading:!1}),this.projectDebtCache.set({data:null,error:null,loading:!1}),this.projectContextCache.set({data:null,error:null,loading:!1}),this.projectGraphCache.set({data:null,error:null,loading:!1}),this.planEntryPages.set(new Map),this.issueCommentPages.set(new Map),this.initiativeDetails.set(new Map),this.initiativeTabs.set(new Map),this.selectedId.set(null),this.selectedInitiativeId.set(null),this.selectedNestedTarget.set(null),this.cascadePath.set([]),this.reRootTrail.set([]),this.activeSection.set("initiatives"),this.activePage.set("list"),this.activeView.set("overview"),this.initTab.set("overview"),this.initiativeStatusFilter.set("all"),this.adrStatusFilter.set("all"),this.clearMasterOverrideIfShallow()}connectEvents(){if(typeof EventSource!="function"){this.startPolling();return}this.events=new EventSource(this.buildTenantScopedPath("/events")),this.events.onmessage=e=>{this.handleProjectChangeEvent(e)},this.events.onerror=()=>{this.syncLabel.set("reconnecting"),this.startPolling()}}handleProjectChangeEvent(e){let t;try{t=JSON.parse(e.data)}catch{this.refreshProjectSummaryInBackground();return}if(t.correlationId){const s=this.localChangeCorrelations.get(t.correlationId);if(this.localChangeCorrelations.delete(t.correlationId),s!==void 0&&s>=Date.now())return}this.handleProjectChange(t)}handleProjectChange(e){if(e.projectId&&e.projectId!==this.selectedProjectId.get())return;if(!e.category||e.category==="bulk"||e.category==="unknown"){this.refreshProjectSummaryInBackground();return}const t=this.selectedId.get(),s=fc(e);let i=!1;if(e.category==="entity"){for(const a of e.affectedEntityIds??[]){const o=this.entityDetails.get().get(a);o&&(this.setEntityDetailCache(a,{...o,stale:!0}),i=!0)}if(t&&e.affectedEntityIds?.includes(t)&&(this.loadEntityDetail(t,!0),i=!0),e.affectedEntityKinds?.includes("adr")){const a=this.projectAdrsCache.get();a.data&&this.projectAdrsCache.set({...a,stale:!0}),this.activeSection.get()==="adrs"&&this.activePage.get()==="list"&&this.loadProjectAdrs(!0),i=!0}if(e.affectedEntityKinds?.includes("debt")){const a=this.projectDebtCache.get();a.data&&this.projectDebtCache.set({...a,stale:!0}),this.activeSection.get()==="debt"&&this.activePage.get()==="list"&&this.loadProjectDebt(!0),i=!0}const r=this.projectGraphCache.get();r.data&&this.projectGraphCache.set({...r,stale:!0}),this.activeSection.get()==="graph"&&this.activePage.get()==="list"&&(this.loadProjectGraph(!0),i=!0)}if(e.category==="issue-comment")for(const r of e.affectedEntityIds??[]){const a=this.issueCommentPages.get().get(r);a&&(this.setIssueCommentPageCache(r,{...a,stale:!0}),i=!0),t===r&&(this.loadIssueCommentPage(r,!0),i=!0)}if(e.category==="plan-entry")for(const r of e.affectedEntityIds??[]){const a=this.planEntryPages.get().get(r),o=a!==void 0||this.entityForId(r)?.kind==="plan";a&&(this.setPlanEntryPageCache(r,{...a,stale:!0}),i=!0),t===r&&o&&(this.loadPlanEntryPage(r,!0),i=!0);const l=this.entityDetails.get().get(r);l&&!o&&(this.setEntityDetailCache(r,{...l,stale:!0}),i=!0),t===r&&!o&&(this.loadEntityDetail(r,!0),i=!0)}if(e.category==="context"){const r=this.projectContextCache.get();r.data&&this.projectContextCache.set({...r,stale:!0}),this.activeSection.get()==="context"&&this.activePage.get()==="list"&&this.loadProjectContext(!0),i=!0}if(e.category==="relation"){for(const a of e.affectedEntityIds??[]){const o=this.entityDetails.get().get(a);o&&(this.setEntityDetailCache(a,{...o,stale:!0}),i=!0),t===a&&(this.loadEntityDetail(a,!0),i=!0)}const r=this.projectGraphCache.get();r.data&&this.projectGraphCache.set({...r,stale:!0}),this.activeSection.get()==="graph"&&this.activePage.get()==="list"&&this.loadProjectGraph(!0),i=!0}for(const r of e.affectedInitiativeIds??[]){if(e.affectedEntityIds?.includes(r)){const a=this.initiativeDetails.get().get(r);a&&(this.setInitiativeDetailCache(r,{...a,stale:!0}),i=!0),this.selectedInitiativeId.get()===r&&this.initTab.get()==="overview"&&(this.loadInitiativeDetail(r,!0),i=!0)}for(const[a,o]of this.initiativeTabs.get()){const l=a.slice(`${r}:`.length);a.startsWith(`${r}:`)&&s.has(l)&&(this.setInitiativeTabCache(a,{...o,stale:!0}),i=!0)}this.selectedInitiativeId.get()===r&&this.initTab.get()!=="overview"&&s.has(this.initTab.get())&&(this.loadInitiativeTab(r,this.initTab.get(),!0),i=!0)}if(i){e.affectsProjectSummary&&this.refreshProjectSummaryInBackground();return}this.refreshProjectSummaryInBackground()}startPolling(){this.pollTimer===null&&(this.pollTimer=window.setInterval(()=>{this.refreshProjectSummaryInBackground()},3e3))}async fetchJson(e){const t=e.includes("?")?"&":"?",s=await fetch(`${e}${t}ts=${Date.now()}`,{cache:"no-store"});if(!s.ok)throw new Error(`Request failed for ${e}`);return await s.json()}sortEntities(e){return[...e].sort((t,s)=>{const i=new Date(t.updatedAt).getTime(),r=new Date(s.updatedAt).getTime();return i!==r?r-i:t.id.localeCompare(s.id)})}buildIssueTree(e,t,s){const i=new Map(e.issues.map(l=>[l.id,l])),r=new Map;for(const l of e.subIssueLinks){if(!s.has(l.parent.id)||!s.has(l.issue.id))continue;const u=r.get(l.parent.id)??[];u.push(l.issue.id),r.set(l.parent.id,u)}const a=l=>{const u=i.get(l);if(!u)return null;const p=this.sortEntities((r.get(l)??[]).map(d=>i.get(d)).filter(d=>!!d));return{issue:u,children:p.map(d=>a(d.id)).filter(d=>d!==null)}};return this.sortEntities(t.map(l=>i.get(l)).filter(l=>!!l)).map(l=>a(l.id)).filter(l=>l!==null)}issueTreeNodeIds(e){return[e.issue.id,...e.children.flatMap(t=>this.issueTreeNodeIds(t))]}formatTenantDisplayName(e){return e.replace(/-[0-9a-f]{12}$/i,"").split(/[-_]+/).filter(t=>t.length>0).map(t=>`${t.charAt(0).toUpperCase()}${t.slice(1)}`).join(" ")}readTenantFromUrl(){return this.readRoute().tenantId}readProjectFromUrl(){return this.readRoute().projectId}currentRoute(){return{tenantId:this.selectedTenant.get(),projectId:this.selectedProjectId.get(),page:this.activePage.get(),section:this.activeSection.get(),entityId:this.selectedId.get(),initiativeId:this.selectedInitiativeId.get(),initiativeTab:this.initTab.get(),target:this.selectedNestedTarget.get()}}readRoute(){const e=new URL(window.location.href),t=new URLSearchParams(e.hash.slice(1)),s=e.searchParams,i=t.get("tenant")??s.get("tenant"),r=t.get("project")??s.get("project"),a=t.get("section"),o=t.get("entity"),l=t.get("initiative"),u=t.get("page"),p=u==="entity"?"entity":u==="initiative"?"initiative":u==="project"?"list":o?"entity":l?"initiative":"list",d=t.get("tab"),g=Nn.includes(d)?d:"overview",b=t.get("target"),x=t.get("target-id"),E=t.get("target-scope")??void 0,O=b==="context"?{id:null,scopeRef:E,type:"context"}:x&&b==="context-term"?{id:x,scopeRef:E,type:b}:x&&(b==="context-term"||b==="issue-comment"||b==="plan-entry")?{type:b,id:x}:null;return{tenantId:i,projectId:r,page:p,section:Gl(a)?a:"initiatives",entityId:o,initiativeId:l,initiativeTab:g,target:O}}normalizeRoute(e){const t=this.entityById.get();if(t.size===0)return e;const s=e.page==="entity"&&e.entityId&&(this.snapshot.get()===null||t.has(e.entityId))?e.entityId:null,i=e.page==="initiative"&&e.initiativeId&&this.bundleForInitiativeId(e.initiativeId)?e.initiativeId:null;return{...e,page:s?"entity":i?"initiative":"list",entityId:s,initiativeId:i,initiativeTab:i?e.initiativeTab:"overview",target:this.normalizeNestedTarget(e.target,s)}}normalizeNestedTarget(e,t){if(!e)return null;if(e.type==="plan-entry")return(this.snapshot.get()?.planEntries??[]).find(r=>r.id===e.id&&r.planId===t&&!r.tombstone)?e:null;if(e.type==="issue-comment")return(t?this.snapshot.get()?.issueComments[t]?.comments.find(r=>r.id===e.id&&!r.tombstone):null)?e:null;const s=e.scopeRef?this.getContextForInitiative(e.scopeRef):this.sharedContext.get();return s?.context.exists&&(e.type==="context"||s.terms.some(i=>i.term===e.id))?e:null}applyRoute(e,t=!0){const s=this.normalizeRoute(e);return this.selectedTenant.set(s.tenantId),this.selectedProjectId.set(s.projectId),this.activeSection.set(s.section),this.selectedId.set(s.entityId),this.selectedInitiativeId.set(s.initiativeId),this.initTab.set(s.initiativeTab),this.selectedNestedTarget.set(s.target),(s.target?.type==="context"||s.target?.type==="context-term")&&(this.contextTab.set(s.target.scopeRef?"initiatives":"global"),this.selectedContextInitiativeId.set(s.target.scopeRef??null)),this.cascadePath.set([]),this.reRootTrail.set([]),this.clearMasterOverrideIfShallow(),this.activePage.set(s.page),this.activeView.set("overview"),t&&(s.entityId?this.loadEntityDetail(s.entityId):s.initiativeId&&this.isSummaryInitiative(s.initiativeId)?(this.loadInitiativeDetail(s.initiativeId),s.initiativeTab!=="overview"&&this.loadInitiativeTab(s.initiativeId,s.initiativeTab),this.startInitiativeTabPrefetch(s.initiativeId)):s.section==="adrs"?this.loadProjectAdrs():s.section==="debt"?this.loadProjectDebt():s.section==="context"?this.loadProjectContext():s.section==="graph"&&this.loadProjectGraph()),s}writeRoute(e,t=!1){const s=new URL(window.location.href),i=[],r=(a,o)=>{o&&i.push(`${a}=${encodeURIComponent(o)}`)};r("tenant",e.tenantId),r("project",e.projectId),r("page",e.projectId?e.page==="list"?"project":e.page:null),r("section",e.section==="initiatives"?null:e.section),r("entity",e.entityId),r("initiative",e.initiativeId),r("tab",e.page==="initiative"?e.initiativeTab:null),r("target",e.target?.type??null),r("target-id",e.target?.id??null),r("target-scope",e.target?.scopeRef??null),s.searchParams.delete("tenant"),s.searchParams.delete("project"),s.hash=i.join("&"),window.history[t?"replaceState":"pushState"]({},"",s)}buildTenantScopedPath(e){const t=this.selectedTenant.get(),s=this.selectedProjectId.get();if(!t&&!s)return e;const i=e.includes("?")?"&":"?",r=new URLSearchParams;return t&&r.set("tenant",t),s&&r.set("project",s),r.size>0?`${e}${i}${r}`:e}stopLiveUpdates(){this.events?.close(),this.events=null,this.pollTimer!==null&&(window.clearInterval(this.pollTimer),this.pollTimer=null)}}function rn(n){return new Set(n.map(t=>t.definition.trim().toLowerCase()).filter(t=>t.length>0)).size>1}function bc(n,e){switch(e){case"questions":return n.role==="question";case"decisions":return n.role==="decision";case"includedScope":return n.role==="scope"&&n.scopeDirection==="included";case"excludedScope":return n.role==="scope"&&n.scopeDirection==="excluded";case"constraints":return n.role==="constraint";case"preferences":return n.role==="preference";case"considerations":return n.role==="consideration"}}function vc(n,e){return n.scopeKind!==e.scopeKind?n.scopeKind==="default"?-1:1:n.scopeLabel!==e.scopeLabel?n.scopeLabel.localeCompare(e.scopeLabel):n.contextKey.localeCompare(e.contextKey)}const Gs="tenant-switcher-menu",nn="agent-issues-theme",Ei=class Ei extends rs(de){constructor(){super(...arguments),this.store=new mc,this.medium=!1,this.narrow=!1,this.mobileMasterOpen=!1,this.theme="light",this.globalSearchTrigger=null,this.onSelectTenant=e=>{const t=e.currentTarget.dataset.tenant;t&&this.store.selectTenant(t)},this.onSelectSection=e=>{const t=e.currentTarget.dataset.section;t&&(this.store.selectSection(t),this.mobileMasterOpen=!1,this.requestUpdate())},this.onSelectInitiative=e=>{const t=e.currentTarget.dataset.initiative;t&&(this.store.selectInitiative(t),this.mobileMasterOpen=!1,this.requestUpdate())},this.onSelectProject=e=>{const t=e.currentTarget.dataset.project;t&&this.store.selectProject(t)},this.onOpenProjectChooser=()=>{this.store.returnToProjectChooser()},this.onSelectEntity=e=>{const t=e.currentTarget.dataset.id;t&&(this.store.selectEntity(t),this.mobileMasterOpen=!1,this.requestUpdate())},this.onSearchInput=e=>{this.store.search.set(e.target.value)},this.onOpenGlobalSearch=e=>{this.globalSearchTrigger=e.currentTarget,this.store.openGlobalSearch()},this.onCloseGlobalSearch=()=>{this.store.closeGlobalSearch(),this.globalSearchTrigger?.focus()},this.onOpenGlobalSearchTarget=e=>{this.store.openSearchTarget(e.detail),this.onCloseGlobalSearch()},this.onRetryGlobalSearch=()=>{this.store.retryGlobalSearch()},this.onRetryProjectSection=e=>{const t=e.currentTarget.dataset.section;t==="adrs"?this.store.retryProjectAdrs():t==="debt"?this.store.retryProjectDebt():t==="context"?this.store.retryProjectContext():t==="graph"&&this.store.retryProjectGraph()},this.onWindowKeyDown=e=>{const t=e.target;e.key.toLowerCase()!=="k"||!e.metaKey&&!e.ctrlKey||t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t?.isContentEditable||(e.preventDefault(),this.globalSearchTrigger=document.activeElement instanceof HTMLElement?document.activeElement:this.shadowRoot?.querySelector("[data-global-search-trigger]")??null,this.store.openGlobalSearch())},this.onToggleRail=()=>{this.store.toggleRail()},this.onToggleMaster=()=>{this.store.toggleMaster()},this.onToggleMobileMaster=async()=>{this.mobileMasterOpen=!this.mobileMasterOpen,this.requestUpdate(),this.mobileMasterOpen&&(await this.updateComplete,this.shadowRoot?.querySelector(".master-search")?.focus())},this.onToggleTheme=()=>{const e=this.theme==="light"?"dark":"light";this.setTheme(e,!0)},this.onToggleEpic=e=>{const t=e.currentTarget.dataset.epicToggle;t&&this.store.toggleEpicExpanded(t)},this.onContextSearchInput=e=>{this.store.contextSearch.set(e.target.value)},this.onSetContextTab=e=>{const t=e.currentTarget.dataset.contextTab;t&&this.store.setContextTab(t)},this.onSetContextInitiativeFilter=e=>{const t=e.currentTarget.dataset.contextInitiative??"";this.store.setContextInitiativeFilter(t||null)},this.onSetMasterStatusFilter=e=>{const t=e.currentTarget,s=t.dataset.masterSection,i=t.dataset.masterStatus;s!=="initiatives"&&s!=="adrs"||!i||this.store.setMasterStatusFilter(s,i)},this.onSetDebtFilter=e=>{const t=e.currentTarget,s=t.dataset.debtFilter,i=t.dataset.debtValue;!s||!i||this.store.setDebtFilter(s,i)},this.onToggleProjectGraphKind=e=>{const t=e.detail.kind;t&&this.store.toggleProjectGraphKind(t)},this.onProjectNodeOpen=e=>{const{id:t,kind:s}=e.detail;if(t){if(s==="initiative"){this.store.selectInitiative(t);return}this.store.selectProjectGraphEntity(t,s)}},this.updateNarrowMode=()=>{const e=window.innerWidth<=900,t=!e&&window.innerWidth<=1200;this.narrow===e&&this.medium===t||(this.narrow=e,this.medium=t,e||(this.mobileMasterOpen=!1),this.requestUpdate())}}toAriaBoolean(e){return e?"true":"false"}formatStatusFilter(e){return e==="all"?"All":e.split("-").map(t=>`${t.charAt(0).toUpperCase()}${t.slice(1)}`).join(" ")}focusContextTarget(){for(const i of this.renderRoot.querySelectorAll(".is-context-target, .is-context-term-target"))i.classList.remove("is-context-target","is-context-term-target");const e=this.store.selectedNestedTarget.get();if(!e||e.type!=="context"&&e.type!=="context-term")return;const t=e.type==="context"?[...this.renderRoot.querySelectorAll(".ctx-context-summary")].find(i=>i.dataset.contextScope===(e.scopeRef??"shared")):[...this.renderRoot.querySelectorAll(".ctx-term")].find(i=>i.dataset.term===e.id);if(!t)return;const s=e.type==="context"?"is-context-target":"is-context-term-target";t.classList.remove(s),t.offsetWidth,t.classList.add(s),t.focus({preventScroll:!0}),typeof t.scrollIntoView=="function"&&t.scrollIntoView({behavior:"smooth",block:"center"})}updated(){this.focusContextTarget()}connectedCallback(){super.connectedCallback();const e=window.localStorage.getItem(nn);this.setTheme(e==="dark"?"dark":"light"),this.updateNarrowMode(),window.addEventListener("resize",this.updateNarrowMode),window.addEventListener("keydown",this.onWindowKeyDown),this.store.connect()}disconnectedCallback(){window.removeEventListener("resize",this.updateNarrowMode),window.removeEventListener("keydown",this.onWindowKeyDown),this.store.disconnect(),super.disconnectedCallback()}setTheme(e,t=!1){this.theme=e,document.documentElement.dataset.theme=e,t&&window.localStorage.setItem(nn,e),this.requestUpdate()}renderThemeToggle(e){const t=this.theme==="light"?"dark":"light",s=this.theme==="light"?"☾":"☼";return h`
|
|
2947
|
+
`];let oi=ts;customElements.define("agent-issues-detail-view",oi);const rc="0123456789ABCDEFGHJKMNPQRSTVWXYZ",nc=6,tn=5,ac="agent-issues-global-search-recents",oc=400,lc=300*1e3,cc=[{key:"questions",title:"Questions"},{key:"decisions",title:"Decisions"},{key:"includedScope",title:"Included scope"},{key:"excludedScope",title:"Excluded scope"},{key:"constraints",title:"Constraints"},{key:"preferences",title:"Preferences"},{key:"considerations",title:"Considerations"}],dc={project:"PROJ",epic:"EPIC",version:"VER",initiative:"INIT",prd:"PRD",userStory:"US",adr:"ADR",issue:"ISS",debt:"DEBT",handoff:"HO"};function uc(n){if(n.shortReference)return n.shortReference;const e=dc[n.kind]??n.kind.slice(0,4).toUpperCase();let t=2166136261;for(let r=0;r<n.id.length;r+=1)t^=n.id.charCodeAt(r),t=Math.imul(t,16777619);let s=BigInt(t>>>0),i="";for(let r=0;r<nc;r+=1)i=rc[Number(s&31n)]+i,s>>=5n;return`${e}_${i}`}const Nn=["overview","issues","plans","prds","adrs","context","userStories","debt","graph"],pc=Nn.filter(n=>n!=="overview");function hc(n){if(!n||typeof n!="object"||!("type"in n))return!1;const e=n;return e.type==="entity"?typeof e.entityId=="string":e.type==="plan-entry"?typeof e.planId=="string"&&typeof e.entryId=="string":e.type==="issue-comment"?typeof e.issueId=="string"&&typeof e.commentId=="string":(e.type==="context"||e.type==="context-term"&&typeof e.term=="string")&&(e.scopeRef===void 0||typeof e.scopeRef=="string")}function sn(n,e){const t=n.nodes.filter(a=>e.has(a.kind)),s=new Set(t.map(a=>a.key)),i=[...new Set(t.map(a=>a.col))].sort((a,o)=>a-o),r=new Map(i.map((a,o)=>[a,o]));return{columns:i.map(a=>n.columns[a]),edges:n.edges.filter(a=>s.has(a.from)&&s.has(a.to)),nodes:t.map(a=>({...a,col:r.get(a.col)}))}}function zt(n){return{...n,body:""}}function gc(n){return[...(n.incoming??[]).map(({entity:e,relationType:t})=>({createdAt:n.entity.createdAt,fromId:e.id,toId:n.entity.id,type:t})),...(n.outgoing??[]).map(({entity:e,relationType:t})=>({createdAt:n.entity.createdAt,fromId:n.entity.id,toId:e.id,type:t}))]}function fc(n){if(n.category==="relation")return new Set(["issues","plans","prds","adrs","context","userStories","debt","graph"]);if(n.category==="context")return new Set(["context"]);if(n.category==="plan-entry")return new Set(["plans"]);if(n.category!=="entity")return new Set;const e={adr:"adrs",debt:"debt",issue:"issues",plan:"plans",prd:"prds",userStory:"userStories"};return new Set([...(n.affectedEntityKinds??[]).flatMap(t=>e[t]?[e[t]]:[]),"graph"])}class mc{constructor(){this.config=A(null),this.snapshot=A(null),this.projectSummary=A(null),this.entityDetails=A(new Map),this.projectAdrsCache=A({data:null,error:null,loading:!1}),this.projectDebtCache=A({data:null,error:null,loading:!1}),this.projectContextCache=A({data:null,error:null,loading:!1}),this.projectGraphCache=A({data:null,error:null,loading:!1}),this.planEntryPages=A(new Map),this.issueCommentPages=A(new Map),this.initiativeDetails=A(new Map),this.initiativeTabs=A(new Map),this.projectDiscovery=A(null),this.search=A(""),this.globalSearchCapability=A(null),this.globalSearchQuery=A(""),this.globalSearchScope=A("current-project"),this.globalSearchSourceTypes=A(["entity","context","context-term","plan-entry","issue-comment"]),this.globalSearchResponse=A(null),this.globalSearchResults=A([]),this.globalSearchRecents=A([]),this.globalSearchProgress=A(!1),this.globalSearchOpen=A(!1),this.contextSearch=A(""),this.contextTab=A("all"),this.selectedContextInitiativeId=A(null),this.visibleProjectGraphKinds=A(new Set(ze)),this.initiativeStatusFilter=A("all"),this.adrStatusFilter=A("all"),this.debtLifecycleFilter=A("open"),this.debtCategoryFilter=A("all"),this.debtPriorityFilter=A("all"),this.kindFilter=A("all"),this.selectedTenant=A(null),this.selectedProjectId=A(null),this.selectedInitiativeId=A(null),this.selectedId=A(null),this.selectedNestedTarget=A(null),this.cascadePath=A([]),this.cascadeAvailableWidth=A(0),this.cascadeWindowStart=A(null),this.reRootTrail=A([]),this.railCollapsed=A(!1),this.masterCollapsedOverride=A(null),this.collapsedEpicIdsByProject=A(new Map),this.syncLabel=A("loading"),this.errorMessage=A(null),this.activeView=A("overview"),this.activePage=A("list"),this.activeRootTab=A("initiatives"),this.activeSection=A("initiatives"),this.initTab=A("overview"),this.globalSearchAbortController=null,this.globalSearchProgressTimer=null,this.globalSearchRequestTimer=null,this.initiativeTabPrefetchGeneration=0,this.initiativeTabPrefetchTimer=null,this.localChangeCorrelations=new Map,this.tenantById=j(()=>new Map((this.config.get()?.availableTenants??[]).map(e=>[e.id,e]))),this.tenantOptions=j(()=>{const e=new Map(this.tenantById.get()),t=this.selectedTenant.get();return t&&!e.has(t)&&e.set(t,{displayName:this.formatTenantDisplayName(t),id:t}),[...e.values()].sort((s,i)=>s.displayName.localeCompare(i.displayName))}),this.selectedTenantDisplayName=j(()=>{const e=this.selectedTenant.get();return e?this.tenantById.get().get(e)?.displayName??this.formatTenantDisplayName(e):null}),this.selectedProjectDisplayName=j(()=>{const e=this.selectedProjectId.get();if(!e)return null;const t=this.projectDiscovery.get();return t?.kind!=="available"?e:t.projects.find(s=>s.project.id===e)?.project.title??e}),this.entityById=j(()=>{const e=this.snapshot.get(),t=e?.initiatives.flatMap(a=>[a.initiative,...a.prds,...a.userStories,...a.adrs,...a.issues])??[],s=[...this.entityDetails.get().values()].flatMap(a=>a.detail?[a.detail]:[]),i=s.map(a=>a.entity),r=s.flatMap(a=>[...(a.incoming??[]).map(({entity:o})=>zt(o)),...(a.outgoing??[]).map(({entity:o})=>zt(o))]);return new Map([...e?.entities??[],...e?.projectAdrs??[],...t,...r,...i].map(a=>[a.id,a]))}),this.globalSearchRecentRecords=j(()=>this.globalSearchRecents.get().flatMap(e=>{const t=this.snapshot.get();if(!t)return[];if(e.type==="entity"){const a=this.entityForId(e.entityId);return a?[{sourceType:"entity",target:e,title:a.title}]:[]}if(e.type==="plan-entry"){const a=t.planEntries?.find(o=>o.id===e.entryId&&o.planId===e.planId&&!o.tombstone);return a&&this.entityForId(e.planId)?[{sourceType:"plan-entry",target:e,title:a.body??"Plan entry"}]:[]}if(e.type==="issue-comment"){const a=t.issueComments[e.issueId]?.comments.find(o=>o.id===e.commentId&&!o.tombstone);return a&&this.entityForId(e.issueId)?[{sourceType:"issue-comment",target:e,title:a.body??"Comment"}]:[]}const s=[t.contexts.shared,...t.contexts.initiatives],i=e.scopeRef?s.find(a=>a.context.key===e.scopeRef||a.context.scopeEntityId===e.scopeRef):t.contexts.shared;if(!i?.context.exists)return[];if(e.type==="context")return[{sourceType:"context",target:e,title:i.context.title}];const r=i.terms.find(a=>a.term===e.term);return r?[{sourceType:"context-term",target:e,title:r.term}]:[]})),this.cascadeColumns=j(()=>this.cascadePath.get().map(e=>this.entityForId(e)).filter(e=>!!e)),this.masterCollapsed=j(()=>{const e=this.masterCollapsedOverride.get();return e!==null?e:!1}),this.cascadeColumnWidth=480,this.cascadeColumnGap=16,this.cascadeColumnWindow=j(()=>{const e=this.cascadeColumns.get(),t=this.cascadeCapacityForWidth(this.cascadeAvailableWidth.get());if(e.length<=t)return{breadcrumb:[],columns:e};const s=e.length-t,i=this.cascadeWindowStart.get(),r=Math.min(Math.max(i??s,0),e.length-1);return{breadcrumb:e.slice(0,r),columns:e.slice(r)}}),this.selectedEntity=j(()=>this.entityForId(this.selectedId.get())),this.selectedBundle=j(()=>this.bundleForEntityId(this.selectedId.get())),this.selectedInitiativeBundle=j(()=>this.bundleForInitiativeId(this.selectedInitiativeId.get())),this.activeInitiativeId=j(()=>this.selectedInitiativeId.get()??this.selectedBundle.get()?.initiative.id??null),this.sharedContext=j(()=>this.projectContextCache.get().data?.shared??this.snapshot.get()?.contexts.shared??null),this.initiativeContextById=j(()=>new Map((this.projectContextCache.get().data?.initiatives??this.snapshot.get()?.contexts.initiatives??[]).filter(e=>!!e.context.scopeEntityId).map(e=>[e.context.scopeEntityId??e.context.key,e]))),this.selectedContext=j(()=>{const e=this.selectedBundle.get();return e?this.initiativeContextById.get().get(e.initiative.id)??null:this.sharedContext.get()}),this.projectContextTerms=j(()=>{const e=this.projectContextCache.get().data?.terms;if(e)return e;const t=new Map;for(const s of[this.sharedContext.get(),...this.projectContextCache.get().data?.initiatives??this.snapshot.get()?.contexts.initiatives??[]])if(s)for(const i of s.terms){const r=i.term.toLowerCase(),a={avoid:[...i.avoid],contextKey:s.context.key,contextTitle:s.context.title,definition:i.definition,scopeEntityId:s.context.scopeEntityId,scopeKind:s.context.scopeKind,scopeLabel:s.context.scopeLabel,updatedAt:i.updatedAt},o=t.get(r);if(!o){t.set(r,{term:i.term,sources:[a],hasSharedSource:s.context.scopeKind==="default",hasDuplicates:!1,hasConflictingDefinitions:!1});continue}o.sources.push(a),o.hasDuplicates=o.sources.length>1,o.hasSharedSource=o.hasSharedSource||s.context.scopeKind==="default",o.hasConflictingDefinitions=rn(o.sources),i.term.localeCompare(o.term)<0&&(o.term=i.term)}return[...t.values()].map(s=>({...s,sources:s.sources.sort(vc)})).sort((s,i)=>s.term.localeCompare(i.term))}),this.filteredProjectContextTerms=j(()=>{const e=this.contextSearch.get().trim().toLowerCase();return e?this.projectContextTerms.get().filter(t=>t.term.toLowerCase().includes(e)?!0:t.sources.some(s=>[s.scopeLabel,s.contextTitle,s.definition,...s.avoid].join(" ").toLowerCase().includes(e))):this.projectContextTerms.get()}),this.filteredInitiativeContextTerms=j(()=>{const e=this.selectedContextInitiativeId.get(),t=this.contextSearch.get().trim().toLowerCase();return this.projectContextTerms.get().map(s=>{const i=s.sources.filter(a=>a.scopeKind==="initiative"&&(!e||a.scopeEntityId===e));return i.length===0||!(!t||s.term.toLowerCase().includes(t)||i.some(a=>[a.scopeLabel,a.contextTitle,a.definition,...a.avoid].join(" ").toLowerCase().includes(t)))?null:{...s,sources:i,hasSharedSource:!1,hasDuplicates:i.length>1,hasConflictingDefinitions:rn(i)}}).filter(s=>s!==null)}),this.filteredSharedContext=j(()=>{const e=this.sharedContext.get();if(!e)return null;const t=this.contextSearch.get().trim().toLowerCase();if(!t)return e;const s=[e.context.key,e.context.scopeLabel,e.context.summary,e.context.title].join(" ").toLowerCase().includes(t),i=e.terms.filter(r=>[r.term,r.definition,...r.avoid].join(" ").toLowerCase().includes(t));return!s&&i.length===0?null:{context:{...e.context,summary:s?e.context.summary:""},terms:i}}),this.projectContextDuplicateCount=j(()=>this.projectContextTerms.get().filter(e=>e.hasDuplicates).length),this.selectedIncoming=j(()=>this.incomingRelationsFor(this.selectedId.get())),this.selectedOutgoing=j(()=>this.outgoingRelationsFor(this.selectedId.get())),this.relatedEntities=j(()=>{const e=new Set;for(const t of[...this.selectedIncoming.get(),...this.selectedOutgoing.get()])e.add(t.fromId),e.add(t.toId);return e.delete(this.selectedId.get()??""),this.sortEntities([...e].map(t=>this.entityById.get().get(t)).filter(t=>!!t))}),this.localGraphEntities=j(()=>{const e=this.selectedEntity.get();return e?[e,...this.relatedEntities.get()]:[]}),this.localGraphRelations=j(()=>{const e=new Set(this.localGraphEntities.get().map(t=>t.id));return this.scopedRelations().filter(t=>e.has(t.fromId)&&e.has(t.toId))}),this.filteredEntities=j(()=>{const e=this.search.get().trim().toLowerCase(),t=this.kindFilter.get();return this.sortEntities((this.snapshot.get()?.entities??[]).filter(s=>t!=="all"&&s.kind!==t?!1:e?[s.id,s.kind,s.status,s.title].join(" ").toLowerCase().includes(e):!0))}),this.kindOptions=j(()=>["issue","all",...new Set((this.snapshot.get()?.entities??[]).map(e=>e.kind).filter(e=>e!=="issue"))]),this.rootTabCounts=j(()=>({adrs:(this.snapshot.get()?.entities??[]).filter(e=>e.kind==="adr").length,initiatives:this.snapshot.get()?.initiatives.length??0})),this.allDebtRecords=j(()=>this.sortEntities(this.projectDebtCache.get().data?.records??(this.snapshot.get()?.entities??[]).filter(e=>e.kind==="debt"))),this.debtRecords=j(()=>{const e=this.debtLifecycleFilter.get(),t=this.debtCategoryFilter.get(),s=this.debtPriorityFilter.get();return this.sortEntities(this.allDebtRecords.get().filter(i=>(e==="all"||i.status===e)&&(t==="all"||i.category===t)&&(s==="all"||i.priority===s)))}),this.projectInitiatives=j(()=>this.snapshot.get()?.initiatives??this.projectSummaryInitiatives.get().map(e=>({adrs:[],blockerLinks:[],constrainsLinks:[],entities:[zt(e.initiative)],fixLinks:[],initiative:zt(e.initiative),issues:[],prds:[],subIssueLinks:[],userStories:[]}))),this.projectSummaryEpicGroups=j(()=>{const e=this.projectSummary.get();return e?.kind==="available"?e.epics:[]}),this.projectSummaryInitiatives=j(()=>this.projectSummaryEpicGroups.get().flatMap(e=>e.initiatives)),this.epicInitiativeGroups=j(()=>{const e=this.snapshot.get();if(!e)return[];const t=new Map(e.initiatives.map(i=>[i.initiative.id,i])),s=new Map;for(const i of e.relations){if(i.type!=="contains"||!t.has(i.toId))continue;const r=s.get(i.fromId)??[];r.push(i.toId),s.set(i.fromId,r)}return this.sortEntities(e.entities.filter(i=>i.kind==="epic")).map(i=>{const r=(s.get(i.id)??[]).map(a=>t.get(a)).filter(a=>!!a);return{epic:i,initiatives:r,completedInitiativeCount:r.filter(a=>this.isDoneStatus(a.initiative.status)).length}}).filter(i=>i.initiatives.length>0)}),this.projectAdrs=j(()=>this.sortEntities(this.projectAdrsCache.get().data?.projectAdrs??this.snapshot.get()?.projectAdrs??(this.snapshot.get()?.entities??[]).filter(e=>e.kind==="adr"))),this.adrRailEntries=j(()=>{const e=this.snapshot.get(),t=this.projectAdrs.get().map(r=>({adr:r,scope:"project",scopeLabel:"project decision"})),i=(this.projectAdrsCache.get().data?.initiativeAdrs??e?.initiatives??[]).flatMap(r=>this.sortEntities(r.adrs).map(a=>({adr:a,scope:"initiative",scopeLabel:`initiative ${r.initiative.title}`})));return[...t,...i]}),this.projectStoryCount=j(()=>this.projectSummaryInitiatives.get().reduce((e,t)=>e+t.userStoryCount,0)),this.projectIssueCount=j(()=>this.projectSummaryInitiatives.get().reduce((e,t)=>e+t.issueCount,0)),this.projectDescription=j(()=>this.sharedContext.get()?.context.summary??this.selectedTenantDisplayName.get()??""),this.orphanIds=j(()=>new Set((this.snapshot.get()?.orphans??[]).map(e=>e.id))),this.connected=!1,this.events=null,this.pollTimer=null,this.onHashChange=()=>{const e=this.applyRoute(this.readRoute());this.writeRoute(e,!0)},this.onPopState=async()=>{const e=this.readRoute();if(e.tenantId!==this.selectedTenant.get()||e.projectId!==this.selectedProjectId.get()){await this.navigateToRoute(e);return}this.applyRoute(e)},this.onBrowserNavigation=async()=>{await this.navigateToRoute(this.readRoute()),new URLSearchParams(new URL(window.location.href).hash.slice(1)).has("cascade")&&this.writeRoute(this.currentRoute(),!0)},this.setSearchFromEvent=e=>{this.search.set(e.target.value)},this.setKindFilterFromEvent=e=>{this.kindFilter.set(e.target.value)},this.setTenantFromEvent=e=>{const t=e.target.value;this.selectTenant(t)},this.selectEntityFromEvent=e=>{const t=e.currentTarget.dataset.id;t&&this.selectEntity(t)},this.openViewFromEvent=e=>{const t=e.currentTarget.dataset.view;t&&this.activeView.set(t)},this.selectInitiativeFromEvent=e=>{const t=e.currentTarget.dataset.id;t&&this.selectInitiative(t)}}entityForId(e){return e?this.entityById.get().get(e)??null:null}requestEntityTab(e,t){t==="plan"&&this.loadPlanEntryPage(e)}async loadMorePlanEntries(e){const t=this.planEntryPages.get().get(e)?.data?.nextBefore;t&&await this.loadPlanEntryPage(e,!1,t)}async loadMoreIssueComments(e){const t=this.issueCommentPages.get().get(e)?.data?.nextBefore;t&&await this.loadIssueCommentPage(e,!1,t)}openGlobalSearch(){this.globalSearchOpen.set(!0),this.globalSearchRecents.set(this.readGlobalSearchRecents()),this.reloadGlobalSearchCapability()}planEntriesFor(e){return this.planEntryPages.get().get(e)?.data?.entries??(this.snapshot.get()?.planEntries??[]).filter(t=>t.planId===e)}issueCommentsFor(e){return this.issueCommentPages.get().get(e)?.data?.comments??this.snapshot.get()?.issueComments[e]?.comments??[]}displayUser(e,t){const s=this.issueCommentPages.get().get(t)?.data?.users.find(i=>i.id===e)??this.snapshot.get()?.users.find(i=>i.id===e);return s?.displayName??s?.authenticationSubject??e}closeGlobalSearch(){this.globalSearchOpen.set(!1),this.setGlobalSearchQuery("")}setGlobalSearchQuery(e){if(this.globalSearchQuery.set(e),this.globalSearchResponse.set(null),this.globalSearchProgress.set(!1),this.cancelGlobalSearchRequest(),!e.trim()){this.globalSearchResults.set([]);return}this.globalSearchRequestTimer=window.setTimeout(()=>{this.requestGlobalSearch(e)},150)}setGlobalSearchScope(e){this.globalSearchScope.set(e),this.setGlobalSearchQuery(this.globalSearchQuery.get())}setGlobalSearchSourceTypes(e){this.globalSearchSourceTypes.set(e),this.setGlobalSearchQuery(this.globalSearchQuery.get())}async retryGlobalSearch(){const e=this.globalSearchQuery.get();e.trim()&&await this.requestGlobalSearch(e)}async reloadGlobalSearchCapability(){const e=this.selectedTenant.get();if(!e){this.globalSearchCapability.set(null);return}try{const t=await fetch(`/api/search/capability?${new URLSearchParams({tenant:e})}`,{cache:"no-store"});if(!t.ok)throw new Error("Global search capability request failed.");const s=await t.json();this.selectedTenant.get()===e&&this.globalSearchCapability.set(s)}catch{this.globalSearchCapability.set(null)}}async requestGlobalSearch(e){if(e!==this.globalSearchQuery.get())return;const t=this.selectedTenant.get(),s=this.selectedProjectId.get();if(!t||!s)return;const i=new AbortController;this.globalSearchAbortController=i,this.globalSearchProgressTimer=window.setTimeout(()=>{this.globalSearchAbortController===i&&this.globalSearchProgress.set(!0)},150);const r=new URLSearchParams({tenant:t,project:s,query:e,scope:this.globalSearchScope.get()});r.set("sourceTypes",this.globalSearchSourceTypes.get().join(","));try{const a=await fetch(`/api/search?${r}`,{cache:"no-store",signal:i.signal});if(!a.ok)throw new Error("Global search request failed.");const o=await a.json();this.globalSearchAbortController===i&&(this.globalSearchResponse.set(o),o.state==="available"&&this.globalSearchResults.set(o.results))}catch(a){if(a instanceof DOMException&&a.name==="AbortError")return;this.globalSearchAbortController===i&&this.globalSearchResponse.set({state:"operational-error"})}finally{this.globalSearchAbortController===i&&(this.globalSearchAbortController=null,this.clearGlobalSearchProgressTimer(),this.globalSearchProgress.set(!1))}}cancelGlobalSearchRequest(){this.globalSearchRequestTimer!==null&&(window.clearTimeout(this.globalSearchRequestTimer),this.globalSearchRequestTimer=null),this.globalSearchAbortController?.abort(),this.globalSearchAbortController=null,this.clearGlobalSearchProgressTimer()}clearGlobalSearchProgressTimer(){this.globalSearchProgressTimer!==null&&(window.clearTimeout(this.globalSearchProgressTimer),this.globalSearchProgressTimer=null)}cascadeCapacityForWidth(e){return e<=0?Number.POSITIVE_INFINITY:Math.max(1,Math.floor(e/(this.cascadeColumnWidth+this.cascadeColumnGap)))}cascadeHopRelation(e,t){const s=this.snapshot.get()?.relations??[],i=s.find(a=>a.fromId===e&&a.toId===t);return i?i.type:s.find(a=>a.fromId===t&&a.toId===e)?.type??null}cascadePathForLeaf(e){const t=this.snapshot.get()?.relations??[],s=[e],i=new Set([e]);let r=e;for(;;){const p=t.find(d=>d.type==="decomposes"&&d.toId===r);if(!p||i.has(p.fromId))break;s.unshift(p.fromId),i.add(p.fromId),r=p.fromId}const a=s[0],l=this.sortEntities(t.filter(p=>p.type==="fixes"&&p.fromId===a).map(p=>this.entityForId(p.toId)).filter(p=>!!p))[0]?.id??null;return[...this.spineForStory(l,a),...s]}spineForStory(e,t){const s=this.snapshot.get()?.relations??[],i=e?s.find(o=>o.type==="creates"&&o.toId===e)?.fromId??null:null,r=i?s.find(o=>o.type==="owns"&&o.toId===i)?.fromId??null:s.find(o=>o.type==="tracks"&&o.toId===t)?.fromId??null,a=[];return r&&a.push(r),i&&a.push(i),e&&a.push(e),a}cascadeSeamFor(e,t){const s=this.cascadeHopRelation(e,t);if(s!=="fixes")return{relation:s,branch:null};const i=this.snapshot.get()?.relations??[],r=this.sortEntities(i.filter(a=>a.type==="fixes"&&a.fromId===t).map(a=>this.entityForId(a.toId)).filter(a=>!!a));return r.length<=1?{relation:s,branch:null}:{relation:s,branch:{options:r,selectedIndex:r.findIndex(a=>a.id===e)}}}selectCascadeBranch(e,t){const s=this.cascadePath.get(),i=s.indexOf(e);if(i===-1)return;const r=s.slice(i),a=this.spineForStory(t,e);this.cascadeWindowStart.set(null),this.cascadePath.set([...a,...r]),this.clearMasterOverrideIfShallow(),this.writeCascadeHash()}bundleForEntityId(e){return e?(this.snapshot.get()?.initiatives??[]).find(t=>[t.initiative,...t.entities,...t.prds,...t.userStories,...t.adrs,...t.issues].some(s=>s.id===e))??null:null}bundleForInitiativeId(e){if(!e)return null;const t=(this.snapshot.get()?.initiatives??[]).find(p=>p.initiative.id===e)??null;if(t)return t;const s=this.projectSummaryInitiatives.get().find(p=>p.initiative.id===e);if(!s)return null;const i=this.initiativeDetailForId(e),r=this.initiativeTabForId(e,this.initTab.get()),a=i?.initiative??{...s.initiative,body:""},o=r?.records??[],l=new Map([a,...o].map(p=>[p.id,p])),u=r?.relations??[];return{adrs:o.filter(p=>p.kind==="adr"),blockerLinks:u.filter(p=>p.type==="blocks").flatMap(p=>{const d=l.get(p.fromId),g=l.get(p.toId);return d&&g?[{source:d,target:g}]:[]}),constrainsLinks:u.filter(p=>p.type==="constrains").flatMap(p=>{const d=l.get(p.fromId),g=l.get(p.toId);return d&&g?[{adr:d,issue:g}]:[]}),entities:[a,...o],fixLinks:u.filter(p=>p.type==="fixes").flatMap(p=>{const d=l.get(p.fromId),g=l.get(p.toId);return d&&g?[{issue:d,userStory:g}]:[]}),initiative:a,issues:o.filter(p=>p.kind==="issue"),prds:o.filter(p=>p.kind==="prd"),relations:u,subIssueLinks:u.filter(p=>p.type==="decomposes").flatMap(p=>{const d=l.get(p.fromId),g=l.get(p.toId);return d&&g?[{parent:d,issue:g}]:[]}),userStories:o.filter(p=>p.kind==="userStory")}}initiativeDetailForId(e){return e?this.initiativeDetails.get().get(e)?.detail??null:null}initiativeTabForId(e,t){return e?this.initiativeTabs.get().get(this.initiativeTabCacheKey(e,t))?.data??null:null}isSummaryInitiative(e){return!this.snapshot.get()?.initiatives.some(t=>t.initiative.id===e)&&this.projectSummaryInitiatives.get().some(t=>t.initiative.id===e)}incomingRelationsFor(e){return e?this.scopedRelations().filter(t=>t.toId===e):[]}outgoingRelationsFor(e){return e?this.scopedRelations().filter(t=>t.fromId===e):[]}scopedRelations(){const e=new Map;for(const t of this.snapshot.get()?.relations??[])e.set(`${t.fromId}:${t.type}:${t.toId}`,t);for(const t of[...this.entityDetails.get().values()].flatMap(s=>s.detail?[s.detail]:[]))for(const s of gc(t))e.set(`${s.fromId}:${s.type}:${s.toId}`,s);return[...e.values()]}connect(){this.connected||(this.connected=!0,this.applyRoute(this.readRoute(),!1),window.addEventListener("hashchange",this.onBrowserNavigation),window.addEventListener("popstate",this.onPopState),this.bootstrap())}disconnect(){this.connected&&(this.connected=!1,this.cancelInitiativeTabPrefetch(),window.removeEventListener("hashchange",this.onBrowserNavigation),window.removeEventListener("popstate",this.onPopState),this.cancelGlobalSearchRequest(),this.events?.close(),this.events=null,this.pollTimer!==null&&(window.clearInterval(this.pollTimer),this.pollTimer=null))}applyLocalProjectChange(e){this.handleProjectChange(e),this.registerLocalChangeCorrelation(e.correlationId)}async mutateProject(e,t){const s=globalThis.crypto.randomUUID();this.registerLocalChangeCorrelation(s);try{const i=await fetch(this.buildTenantScopedPath("/api/project-mutation"),{body:JSON.stringify({correlationId:s,method:e,params:t}),cache:"no-store",headers:{"content-type":"application/json"},method:"POST"});if(!i.ok)throw new Error(`Project mutation ${e} failed.`);const r=await i.json();return this.applyLocalProjectChange(r.event),r.result}catch(i){throw this.localChangeCorrelations.delete(s),i}}registerLocalChangeCorrelation(e){if(!e)return;const t=Date.now();for(const[s,i]of this.localChangeCorrelations)i<t&&this.localChangeCorrelations.delete(s);this.localChangeCorrelations.set(e,t+lc)}openRootTab(e){this.activeRootTab.set(e)}selectSection(e){this.activeSection.set(e),this.selectedInitiativeId.set(null),this.selectedId.set(null),this.selectedNestedTarget.set(null),this.initTab.set("overview"),this.contextSearch.set(""),this.contextTab.set("all"),this.selectedContextInitiativeId.set(null),this.activePage.set("list"),this.writeRoute(this.currentRoute()),e==="adrs"?this.loadProjectAdrs():e==="debt"?this.loadProjectDebt():e==="context"?this.loadProjectContext():e==="graph"&&this.loadProjectGraph()}setContextTab(e){this.contextTab.set(e)}setContextInitiativeFilter(e){this.selectedContextInitiativeId.set(e)}setMasterStatusFilter(e,t){if(e==="initiatives"){this.initiativeStatusFilter.set(t);return}this.adrStatusFilter.set(t)}setDebtFilter(e,t){if(e==="lifecycle"){this.debtLifecycleFilter.set(t);return}if(e==="category"){this.debtCategoryFilter.set(t);return}this.debtPriorityFilter.set(t)}setInitTab(e){this.initTab.set(e),this.writeRoute(this.currentRoute());const t=this.selectedInitiativeId.get();t&&e!=="overview"&&this.projectSummaryInitiatives.get().some(s=>s.initiative.id===t)&&this.loadInitiativeTab(t,e)}async retryInitiativeDetail(e){await this.loadInitiativeDetail(e,!0)}async retryInitiativeTab(e,t){await this.loadInitiativeTab(e,t,!0)}openSearchTarget(e){if(this.recordGlobalSearchRecent(e),e.type==="entity"){this.selectEntity(e.entityId);return}if(e.type==="plan-entry"){this.selectEntity(e.planId,{id:e.entryId,type:e.type});return}if(e.type==="issue-comment"){this.selectEntity(e.issueId,{id:e.commentId,type:e.type});return}(e.type==="context"||e.type==="context-term")&&(this.activeSection.set("context"),this.selectedInitiativeId.set(null),this.selectedId.set(null),this.activePage.set("list"),this.contextTab.set(e.scopeRef?"initiatives":"global"),this.selectedContextInitiativeId.set(e.scopeRef??null),this.selectedNestedTarget.set(e.type==="context"?{id:null,scopeRef:e.scopeRef,type:e.type}:{id:e.term,scopeRef:e.scopeRef,type:e.type}),this.writeRoute(this.currentRoute()))}globalSearchRecentsStorageKey(){const e=this.selectedTenant.get(),t=this.selectedProjectId.get();return e&&t?`${ac}:${e}:${t}`:null}readGlobalSearchRecents(){const e=this.globalSearchRecentsStorageKey();if(!e)return[];try{const t=window.localStorage.getItem(e);if(!t)return[];const s=JSON.parse(t);return Array.isArray(s)?s.filter(hc).slice(0,tn):[]}catch{return[]}}recordGlobalSearchRecent(e){const t=this.globalSearchRecentsStorageKey();if(!t)return;const s=this.readGlobalSearchRecents(),i=JSON.stringify(e),r=[e,...s.filter(a=>JSON.stringify(a)!==i)].slice(0,tn);window.localStorage.setItem(t,JSON.stringify(r)),this.globalSearchRecents.set(r)}selectEntity(e,t=null){if(this.entityForId(e)?.kind==="initiative"){this.selectInitiative(e);return}this.cascadePath.set([]),this.selectedInitiativeId.set(null),this.selectedId.set(e),this.selectedNestedTarget.set(t),this.activePage.set("entity"),this.writeRoute(this.currentRoute()),this.loadEntityDetail(e),this.entityForId(e)?.kind==="issue"&&this.loadIssueCommentPage(e)}selectProjectGraphEntity(e,t){this.activeSection.set(t==="adr"?"adrs":"initiatives"),this.selectEntity(e)}openCascade(e){this.cascadeWindowStart.set(null),this.cascadePath.set([e]),this.clearMasterOverrideIfShallow(),this.writeCascadeHash()}toggleRail(){this.railCollapsed.set(!this.railCollapsed.get())}toggleMaster(){this.masterCollapsedOverride.set(!this.masterCollapsed.get())}isEpicExpanded(e){const t=this.selectedProjectId.get();return!t||!this.collapsedEpicIdsByProject.get().get(t)?.has(e)}toggleEpicExpanded(e){const t=this.selectedProjectId.get();if(!t)return;const s=new Map(this.collapsedEpicIdsByProject.get()),i=new Set(s.get(t));i.has(e)?i.delete(e):i.add(e),s.set(t,i),this.collapsedEpicIdsByProject.set(s)}clearMasterOverrideIfShallow(){this.cascadePath.get().length<2&&this.masterCollapsedOverride.set(null)}reRootCascade(e){const t=this.cascadePath.get();t.length>0&&this.reRootTrail.set([...this.reRootTrail.get(),t]),this.cascadeWindowStart.set(null),this.cascadePath.set(this.cascadePathForLeaf(e)),this.clearMasterOverrideIfShallow(),this.writeCascadeHash()}restoreReRoot(e){const t=this.reRootTrail.get(),s=t[e];s&&(this.reRootTrail.set(t.slice(0,e)),this.cascadeWindowStart.set(null),this.cascadePath.set(s),this.clearMasterOverrideIfShallow(),this.writeCascadeHash())}popReRoot(){const e=this.reRootTrail.get();e.length!==0&&this.restoreReRoot(e.length-1)}drillCascade(e,t){const s=this.cascadePath.get().indexOf(e);s!==-1&&(this.cascadeWindowStart.set(null),this.cascadePath.set([...this.cascadePath.get().slice(0,s+1),t]),this.writeCascadeHash())}restoreAncestor(e){const t=this.cascadePath.get().indexOf(e);t!==-1&&this.cascadeWindowStart.set(t)}truncateCascadeTo(e){const t=this.cascadePath.get(),s=t.indexOf(e);s===-1||s===t.length-1||(this.cascadeWindowStart.set(null),this.cascadePath.set(t.slice(0,s+1)),this.clearMasterOverrideIfShallow(),this.writeCascadeHash())}writeCascadeHash(){this.writeRoute(this.currentRoute())}selectInitiative(e){this.cancelInitiativeTabPrefetch(),this.selectedId.set(null),this.selectedInitiativeId.set(e),this.selectedNestedTarget.set(null),this.activePage.set("initiative"),this.activeSection.set("initiatives"),this.activeView.set("overview"),this.initTab.set("overview"),this.cascadePath.set([]),this.clearMasterOverrideIfShallow(),this.writeRoute(this.currentRoute()),this.isSummaryInitiative(e)&&this.loadInitiativeRoute(e,"overview")}clearSelection(){this.cancelInitiativeTabPrefetch(),this.cascadePath.set([]),this.clearMasterOverrideIfShallow(),this.selectedInitiativeId.set(null),this.selectedId.set(null),this.selectedNestedTarget.set(null),this.activePage.set("list"),this.activeView.set("overview"),this.writeRoute(this.currentRoute())}async selectTenant(e){!e||e===this.selectedTenant.get()||(this.selectedTenant.set(e),this.selectedProjectId.set(null),this.resetScopeDetail(),this.writeRoute(this.currentRoute()),this.stopLiveUpdates(),this.syncLabel.set("choose a project"),await this.reloadProjectDiscovery())}async returnToProjectChooser(){!this.selectedTenant.get()||!this.selectedProjectId.get()||(this.selectedProjectId.set(null),this.snapshot.set(null),this.projectSummary.set(null),this.resetScopeDetail(),this.writeRoute(this.currentRoute()),this.stopLiveUpdates(),this.syncLabel.set("choose a project"),await this.reloadProjectDiscovery())}async selectProject(e){if(!(!this.selectedTenant.get()||!e||e===this.selectedProjectId.get())){this.selectedProjectId.set(e),this.resetScopeDetail(),this.writeRoute(this.currentRoute()),this.stopLiveUpdates(),this.syncLabel.set("connecting");try{await this.reloadProjectSummary(),this.connectEvents()}catch(s){this.selectedProjectId.set(null),this.snapshot.set(null),this.projectSummary.set(null),this.writeRoute(this.currentRoute(),!0),this.errorMessage.set(s instanceof Error?s.message:String(s)),this.syncLabel.set("project unavailable")}}}initiativeStats(e){const t=this.projectSummaryInitiatives.get().find(a=>a.initiative.id===e.initiative.id);if(t){const a=t.issueCount>0?Math.round(t.completedIssueCount/t.issueCount*100):0;return{adrs:t.adrCount??e.adrs.length,done:t.completedIssueCount,issues:t.issueCount,pct:a,stories:t.userStoryCount}}const s=e.issues.length,i=e.issues.filter(a=>this.isDoneStatus(a.status)).length,r=s>0?Math.round(i/s*100):0;return{adrs:e.adrs.length,done:i,issues:s,pct:r,stories:e.userStories.length}}issuesForStory(e,t){const s=new Set(e.fixLinks.filter(i=>i.userStory.id===t).map(i=>i.issue.id));return this.sortEntities(e.issues.filter(i=>s.has(i.id)))}subIssuesForIssue(e,t){return this.sortEntities(e.subIssueLinks.filter(s=>s.parent.id===t).map(s=>s.issue))}parentIssueForIssue(e,t){return e.subIssueLinks.find(s=>s.issue.id===t)?.parent??null}issueTreeForStory(e,t){const s=new Map(e.subIssueLinks.map(l=>[l.issue.id,l.parent.id])),i=new Map;for(const l of e.subIssueLinks){const u=i.get(l.parent.id)??[];u.push(l.issue.id),i.set(l.parent.id,u)}const r=new Set,a=this.issuesForStory(e,t);for(const l of a){const u=[l.id];for(;u.length>0;){const d=u.shift();if(!(!d||r.has(d))){r.add(d);for(const g of i.get(d)??[])u.push(g)}}let p=l.id;for(;p;){if(r.has(p)){p=s.get(p)??null;continue}r.add(p),p=s.get(p)??null}}const o=[...r].filter(l=>{const u=s.get(l);return!u||!r.has(u)});return this.buildIssueTree(e,o,r)}issueTreeForDirectIssues(e){const t=new Set(e.userStories.flatMap(a=>this.issueTreeForStory(e,a.id).flatMap(o=>this.issueTreeNodeIds(o)))),s=new Set(e.issues.map(a=>a.id).filter(a=>!t.has(a))),i=new Map(e.subIssueLinks.map(a=>[a.issue.id,a.parent.id])),r=[...s].filter(a=>{const o=i.get(a);return!o||!s.has(o)});return this.buildIssueTree(e,r,s)}subIssueTreeForIssue(e,t){const s=new Set,i=this.subIssuesForIssue(e,t).map(r=>r.id);for(;i.length>0;){const r=i.shift();if(!(!r||s.has(r))){s.add(r);for(const a of this.subIssuesForIssue(e,r))i.push(a.id)}}return this.buildIssueTree(e,this.subIssuesForIssue(e,t).map(r=>r.id),s)}buildInitiativeGraph(e,t){const s=e.initiative,i=this.snapshot.get(),r=e.relations??i?.relations??[],a=e.relations?e.entities:i?.entities??[],o=[],l=[];new Map(e.issues.map(m=>[m.id,m]));const u=new Map,p=new Set(e.subIssueLinks.map(m=>m.issue.id)),d=new Map,g=this.sortEntities(e.entities.filter(m=>m.kind==="plan"));o.push({col:0,fullLabel:s.title,id:s.id,key:s.id,kind:"initiative",label:s.title});for(const m of g)o.push({col:1,fullLabel:m.title,id:m.id,key:m.id,kind:"plan",label:m.title,status:m.status}),l.push({from:s.id,to:m.id});for(const m of e.prds)o.push({col:1,fullLabel:m.title,id:m.id,key:m.id,kind:"prd",label:m.title}),l.push({from:s.id,to:m.id});for(const m of e.adrs)o.push({col:1,fullLabel:m.title,id:m.id,key:m.id,kind:"adr",label:m.title}),l.push({from:s.id,to:m.id});for(const m of e.userStories)o.push({col:2,fullLabel:m.title,id:m.id,key:m.id,kind:"story",label:m.title}),l.push({from:s.id,to:m.id});for(const m of e.subIssueLinks){const P=u.get(m.parent.id)??[];P.push(m.issue),u.set(m.parent.id,P)}for(const[m,P]of u)u.set(m,this.sortEntities(P));for(const m of e.fixLinks){const P=d.get(m.issue.id)??[];P.push(m.userStory.id),d.set(m.issue.id,P)}const b=this.sortEntities(e.issues.filter(m=>!p.has(m.id)));let x=0;const E=new Set,O=(m,P)=>{if(E.has(m.id)){x=Math.max(x,P);return}E.add(m.id),x=Math.max(x,P),o.push({col:3+P,fullLabel:m.title,id:m.id,key:m.id,kind:"issue",label:m.title,status:m.status});const J=d.get(m.id)??[];if(J.length>0)for(const we of J)l.push({from:we,to:m.id});else P===0&&l.push({from:s.id,to:m.id});for(const we of u.get(m.id)??[])O(we,P+1),l.push({from:m.id,to:we.id})};for(const m of b)O(m,0);for(const m of this.sortEntities(e.issues))E.has(m.id)||O(m,0);const I=["Issues"];for(let m=1;m<=x;m+=1)I.push(m===1?"Sub-issues":"Nested sub-issues");const _=3+I.length,y=this.sortEntities(a.filter(m=>m.kind==="debt"&&r.some(P=>P.fromId===s.id&&P.toId===m.id&&P.type==="records")));for(const m of y)o.push({col:_,fullLabel:m.title,id:m.id,key:m.id,kind:"debt",label:m.title,status:m.status}),l.push({from:s.id,label:"records",to:m.id});const R=new Set(o.map(m=>m.id)),T=new Set(y.map(m=>m.id)),M=new Set(g.map(m=>m.id));for(const m of r)m.type==="informs"&&M.has(m.fromId)&&R.has(m.toId)&&l.push({from:m.fromId,label:"informs",to:m.toId}),m.type==="resolves"&&R.has(m.fromId)&&T.has(m.toId)&&l.push({from:m.fromId,label:"resolves",to:m.toId}),m.type==="relatesTo"&&T.has(m.fromId)&&R.has(m.toId)&&l.push({from:m.fromId,label:"relatesTo",to:m.toId});const X={columns:["Initiative","Plans, PRDs & ADRs","User stories",...I,"Debt records"],edges:l,nodes:o};return t?sn(X,t):X}buildProjectGraph(){const e=this.projectGraphCache.get().data;if(e)return this.buildScopedProjectGraph(e);const t=this.snapshot.get(),s=this.epicInitiativeGroups.get(),i="__project",r=new Map,a=this.selectedProjectId.get(),o=[{col:0,fullLabel:this.projectDescription.get(),id:"",key:i,kind:"project",label:this.selectedTenantDisplayName.get()??""}],l=[];a&&r.set(a,i);for(const d of t?.projectAdrs??[])o.push({col:1,fullLabel:d.title,id:d.id,key:d.id,kind:"adr",label:d.title,status:d.status}),r.set(d.id,d.id),l.push({from:i,to:d.id});for(const d of s){const{epic:g}=d;o.push({col:1,fullLabel:g.title,id:g.id,key:g.id,kind:"epic",label:g.title,status:g.status}),r.set(g.id,g.id),l.push({from:i,to:g.id});for(const b of d.initiatives){const x=b.initiative,E=new Map,O=new Map;o.push({col:2,fullLabel:`${x.title} — ${b.userStories.length} stories, ${b.issues.length} issues`,id:x.id,key:x.id,kind:"initiative",label:x.title,status:x.status}),r.set(x.id,x.id),l.push({from:g.id,to:x.id});const I=[...this.sortEntities(b.entities.filter(_=>_.kind==="plan")).map(_=>({entity:_,kind:"plan"})),...b.prds.map(_=>({entity:_,kind:"prd"})),...b.adrs.map(_=>({entity:_,kind:"adr"}))];for(const{entity:_,kind:y}of I){const R=`${x.id}:${_.id}`;o.push({col:3,fullLabel:_.title,id:_.id,key:R,kind:y,label:_.title,status:_.status}),r.set(_.id,R),l.push({from:x.id,to:R})}for(const _ of this.sortEntities(b.userStories)){const y=`${x.id}:${_.id}`;E.set(_.id,y),r.set(_.id,y),o.push({col:4,fullLabel:_.title,id:_.id,key:y,kind:"story",label:_.title,status:_.status}),l.push({from:x.id,to:y})}for(const _ of b.fixLinks){const y=O.get(_.issue.id)??[];y.push(_.userStory.id),O.set(_.issue.id,y)}for(const _ of this.sortEntities(b.issues)){const y=`${x.id}:${_.id}`;r.set(_.id,y),o.push({col:5,fullLabel:_.title,id:_.id,key:y,kind:"issue",label:_.title,status:_.status});const R=(O.get(_.id)??[]).map(T=>E.get(T)).filter(T=>!!T);if(R.length>0)for(const T of R)l.push({from:T,to:y});else l.push({from:x.id,to:y})}}}const u=new Map,p=this.sortEntities((t?.entities??[]).filter(d=>d.kind==="debt"));for(const d of p){const g=(t?.relations??[]).find(x=>x.fromId!==d.id&&x.toId===d.id&&x.type==="records"),b=g?r.get(g.fromId):void 0;b&&(u.set(d.id,d.id),o.push({col:6,fullLabel:d.title,id:d.id,key:d.id,kind:"debt",label:d.title,status:d.status}),l.push({from:b,label:"records",to:d.id}))}for(const d of t?.relations??[]){if(d.type==="informs"){const g=r.get(d.fromId),b=r.get(d.toId);g&&b&&l.push({from:g,label:"informs",to:b})}if(d.type==="resolves"){const g=r.get(d.fromId),b=u.get(d.toId);g&&b&&l.push({from:g,label:"resolves",to:b})}if(d.type==="relatesTo"){const g=u.get(d.fromId),b=r.get(d.toId)??u.get(d.toId);g&&b&&l.push({from:g,label:"relatesTo",to:b})}}return sn({columns:["Project","Epics","Initiatives","Plans, PRDs & ADRs","User stories","Issues","Debt records"],edges:l,nodes:o},this.visibleProjectGraphKinds.get())}buildScopedProjectGraph(e){const t=this.sortEntities(e.records),s=[...new Set(t.map(l=>l.kind==="userStory"?"story":l.kind).filter(l=>ze.includes(l)))],i=new Map(s.map((l,u)=>[l,u])),r=new Set(t.map(l=>l.id)),a=t.flatMap(l=>{const u=l.kind==="userStory"?"story":l.kind,p=i.get(u);return p===void 0?[]:[{col:p,fullLabel:l.title,id:l.id,key:l.id,kind:u,label:l.title,status:l.status}]}),o=e.relations.filter(l=>r.has(l.fromId)&&r.has(l.toId)).map(l=>({from:l.fromId,label:l.type,to:l.toId}));return{columns:s.map(l=>l==="story"?"User stories":`${l.slice(0,1).toUpperCase()}${l.slice(1)}s`),edges:o,nodes:a}}toggleProjectGraphKind(e){const t=new Set(this.visibleProjectGraphKinds.get());t.has(e)?t.delete(e):t.add(e),this.visibleProjectGraphKinds.set(t)}isDoneStatus(e){return e==="done"||e==="complete"||e==="closed"}sortIssuesByExpectedCompletion(e,t){const s=new Map(e.map(g=>[g.id,g])),i=new Map(e.map((g,b)=>[g.id,b])),r=new Map(e.map(g=>[g.id,0])),a=new Map(e.map(g=>[g.id,[]])),o=new Set,l=(g,b)=>+!this.isDoneStatus(g.status)-+!this.isDoneStatus(b.status)||i.get(g.id)-i.get(b.id);for(const g of t.blockerLinks){if(!s.has(g.source.id)||!s.has(g.target.id)||!this.isDoneStatus(g.source.status)&&this.isDoneStatus(g.target.status))continue;const b=`${g.source.id}:${g.target.id}`;o.has(b)||(o.add(b),r.set(g.target.id,r.get(g.target.id)+1),a.get(g.source.id).push(g.target.id))}const u=e.filter(g=>r.get(g.id)===0),p=[],d=new Set;for(;u.length>0;){u.sort(l);const g=u.shift();if(!d.has(g.id)){d.add(g.id),p.push(g);for(const b of a.get(g.id)??[]){const x=r.get(b)-1;r.set(b,x),x===0&&u.push(s.get(b))}}}return[...p,...e.filter(g=>!d.has(g.id)).sort(l)]}issueStatusTone(e){return this.isDoneStatus(e)?"done":e==="blocked"||e==="paused"?"blocked":"open"}formatKindLabel(e){return e==="all"?"All work items":e==="userStory"?"User story":e==="prd"?"PRD":e==="adr"?"ADR":e?`${e.charAt(0).toUpperCase()}${e.slice(1)}`:"Unknown"}statusTone(e){return e==="blocked"||e==="paused"?"warn":e==="cancelled"?"danger":e==="archived"||e==="done"||e==="complete"||e==="closed"?"neutral":"success"}badgeTone(e){return e==="done"||e==="complete"||e==="closed"?"done":e==="blocked"||e==="cancelled"?"danger":e==="ready"||e==="in-progress"?"info":e==="paused"?"warn":e==="active"||e==="current"||e==="approved"?"success":"neutral"}compactPath(e){const t=e.split("/").filter(Boolean);return t.length<=3?e:`.../${t.slice(-3).join("/")}`}formatTimestamp(e){const t=new Date(e);return Number.isNaN(t.getTime())?e:new Intl.DateTimeFormat(void 0,{year:"numeric",month:"short",day:"numeric",hour:"numeric",minute:"2-digit"}).format(t)}truncate(e,t){return e.length<=t?e:`${e.slice(0,Math.max(0,t-3)).trimEnd()}...`}shortRef(e){return uc(e)}buildOpenedText(e){const t=this.selectedBundle.get(),s=t?`inside ${t.initiative.id}`:"outside a visible initiative bundle";return`Opened ${this.formatTimestamp(e.createdAt)} and currently ${s}. Last updated ${this.formatTimestamp(e.updatedAt)}.`}buildSummaryBody(e){const t=this.selectedBundle.get(),s=this.selectedContext.get(),i=this.selectedIncoming.get(),r=this.selectedOutgoing.get(),a=this.orphanIds.get(),o=t?`It currently sits in ${t.initiative.id}, which includes ${t.prds.length} PRDs, ${t.userStories.length} stories, ${t.adrs.length} ADRs, and ${t.issues.length} issues.`:"It is not currently connected to a visible initiative bundle in this snapshot.",l=a.has(e.id)?"This record is marked as orphaned from the initiative structure.":"This record remains connected to the main initiative structure.",u=s?`${s.context.title} is currently ${s.context.exists?"stored":"using its default shell"} with ${s.terms.length} defined terms.`:"No context is currently available for this record.";return`${e.id} is a ${this.formatKindLabel(e.kind).toLowerCase()} with ${i.length} incoming links and ${r.length} outgoing links. ${o} ${u} ${l}`}buildRelationSentence(e){return`${e.fromId} ${e.type} ${e.toId}`}relationLabel(e,t){const s={blocks:"Blocked by",constrains:"Constrained by",decomposes:"Parent issue",creates:"Created by",fixes:"Fixed by",handsOff:"Incoming handoffs",owns:"Owned by",records:"Recorded by",resolves:"Resolved by",tracks:"Tracked by"},i={blocks:"Blocks",constrains:"Constrains",decomposes:"Sub-issues",creates:"Creates",fixes:"Fixes",relatesTo:"Related records",resolves:"Resolves debt",owns:"Owns",records:"Records",tracks:"Tracks"};return t?s[e]??`${e} (incoming)`:i[e]??e}detailMeta(e){return this.detailMetaFor(e.id)}detailMetaFor(e){const t=e?this.entityById.get().get(e)??null:null,s=this.bundleForEntityId(e),i=t?this.incomingRelationsFor(t.id).find(u=>u.type==="records")?.fromId:null,r=i?this.entityById.get().get(i)??null:null,a=t?.kind==="debt"?[["Category",t.category??"—"],["Priority",t.priority??"—"],["Lifecycle",t.status],["Owner",r?`${this.shortRef(r)} ${r.title}`:"—"]]:[],o=t?.kind==="debt"?[]:[["Status",t?.status??"—"]],l=t?.type?[["Type",t.type]]:[];return[["Initiative",s?`${this.shortRef(s.initiative)} ${s.initiative.title}`:"—"],...a,...o,...l,["Created",t?this.formatTimestamp(t.createdAt):"—"],["Updated",t?this.formatTimestamp(t.updatedAt):"—"]]}linkedRecordSections(e){return this.linkedRecordSectionsFor(this.selectedId.get(),e)}linkedRecordSectionsFor(e,t){const s=new Set(["owns","creates","fixes","decomposes","tracks","constrains"]),i=new Map,r=new Set(t?.excludeRelationTypes??[]),a=new Set(t?.excludeRelatedIds??[]),o=(l,u,p)=>{if(a.has(l))return;const d=this.entityById.get().get(l);if(!d)return;const g=i.get(u)??{crossLink:!s.has(p),records:[]};g.records.push(d),i.set(u,g)};for(const l of this.outgoingRelationsFor(e))r.has(l.type)||o(l.toId,this.relationLabel(l.type,!1),l.type);for(const l of this.incomingRelationsFor(e))r.has(l.type)||o(l.fromId,this.relationLabel(l.type,!0),l.type);return[...i.entries()].map(([l,u])=>({crossLink:u.crossLink,key:l,records:this.sortEntities(u.records),title:l}))}debtRecordSectionsFor(e){const t=e?this.entityById.get().get(e)??null:null;if(!t||!["project","epic","initiative","issue"].includes(t.kind))return[];const s=this.outgoingRelationsFor(t.id).filter(r=>r.type==="records").map(r=>this.entityById.get().get(r.toId)).filter(r=>r?.kind==="debt"),i=["epic","initiative","issue"].includes(t.kind)?this.outgoingRelationsFor(t.id).filter(r=>r.type==="resolves").map(r=>this.entityById.get().get(r.toId)).filter(r=>r?.kind==="debt"):[];return[...s.length>0?[{key:"owned-debt",records:this.sortEntities(s),title:"Owned debt"}]:[],...i.length>0?[{key:"resolved-debt",records:this.sortEntities(i),title:"Resolves debt"}]:[]]}planProjectionFor(e){const t=[...this.planEntriesFor(e)].sort((r,a)=>r.createdAt.localeCompare(a.createdAt)||r.reference.localeCompare(a.reference)),s=new Set(t.flatMap(r=>r.supersededEntryIds)),i=t.filter(r=>!r.tombstone&&!s.has(r.id));return{current:cc.map(r=>({key:r.key,title:r.title,entries:i.filter(a=>bc(a,r.key))})),history:t}}closeEntity(){const e=this.selectedBundle.get();if(this.selectedId.set(null),this.selectedNestedTarget.set(null),this.activeSection.get()!=="adrs"&&e){this.selectedInitiativeId.set(e.initiative.id),this.activePage.set("initiative"),this.writeRoute(this.currentRoute());return}this.activePage.set("list"),this.writeRoute(this.currentRoute())}getContextForInitiative(e){return this.initiativeTabForId(e,"context")?.context??this.initiativeContextById.get().get(e)??null}async bootstrap(){try{const e=await this.fetchJson("site-config.json");this.config.set(e);const t=this.readRoute(),s={...t,tenantId:t.tenantId??e.currentTenant};this.selectedTenant.set(s.tenantId),await this.reloadProjectDiscovery(),await this.navigateToRoute(s),this.writeRoute(this.currentRoute(),!0)}catch(e){this.errorMessage.set(e instanceof Error?e.message:String(e)),this.syncLabel.set("load failed")}}async reloadProjectSummary(){const e=this.selectedTenant.get(),t=this.selectedProjectId.get(),s=await this.fetchJson(this.buildTenantScopedPath("/api/project-summary"));if(!(this.selectedTenant.get()!==e||this.selectedProjectId.get()!==t)){if(s.kind==="unavailable")throw new Error("Selected project is unavailable.");this.projectSummary.set(s),this.snapshot.set(null),this.errorMessage.set(null),this.syncLabel.set("listening")}}refreshProjectSummaryInBackground(){this.reloadProjectSummary().catch(e=>{this.errorMessage.set(e instanceof Error?e.message:String(e)),this.syncLabel.set("refresh failed")})}async loadInitiativeDetail(e,t=!1){const s=this.initiativeDetails.get().get(e);if(s?.loading||!t&&s?.detail&&!s.stale)return;const i=this.selectedTenant.get(),r=this.selectedProjectId.get();this.setInitiativeDetailCache(e,{detail:s?.detail??null,error:null,loading:!0,stale:s?.stale});try{const a=await this.fetchJson(this.buildTenantScopedPath(`/api/initiative-detail?initiative=${encodeURIComponent(e)}`));if(this.selectedTenant.get()!==i||this.selectedProjectId.get()!==r)return;if(!("initiative"in a)){this.selectedInitiativeId.get()===e&&this.clearSelection();return}this.setInitiativeDetailCache(e,{detail:a,error:null,loading:!1})}catch(a){if(this.selectedTenant.get()===i&&this.selectedProjectId.get()===r){const o=this.initiativeDetails.get().get(e);this.setInitiativeDetailCache(e,{detail:o?.detail??s?.detail??null,error:a instanceof Error?a.message:String(a),loading:!1,stale:o?.stale??s?.stale})}}}async loadInitiativeRoute(e,t){await this.loadInitiativeDetail(e),!(this.selectedInitiativeId.get()!==e||!this.initiativeDetailForId(e))&&(t!=="overview"&&this.initTab.get()===t&&await this.loadInitiativeTab(e,t),this.selectedInitiativeId.get()===e&&this.startInitiativeTabPrefetch(e))}async retryProjectAdrs(){await this.loadProjectAdrs(!0)}async loadProjectAdrs(e=!1){const t=this.projectAdrsCache.get();if(t.loading||!e&&t.data&&!t.stale)return;const s=this.selectedTenant.get(),i=this.selectedProjectId.get();this.projectAdrsCache.set({data:t.data,error:null,loading:!0,stale:t.stale});try{const r=await this.fetchJson(this.buildTenantScopedPath("/api/project-adrs"));this.selectedTenant.get()===s&&this.selectedProjectId.get()===i&&this.projectAdrsCache.set({data:r,error:null,loading:!1})}catch(r){if(this.selectedTenant.get()===s&&this.selectedProjectId.get()===i){const a=this.projectAdrsCache.get();this.projectAdrsCache.set({data:a.data,error:r instanceof Error?r.message:String(r),loading:!1,stale:a.stale??t.stale})}}}async retryProjectDebt(){await this.loadProjectDebt(!0)}async loadProjectDebt(e=!1){await this.loadProjectRecordData("/api/project-debt",this.projectDebtCache,e)}async retryProjectContext(){await this.loadProjectContext(!0)}async loadProjectContext(e=!1){const t=this.projectContextCache.get();if(t.loading||!e&&t.data&&!t.stale)return;const s=this.selectedTenant.get(),i=this.selectedProjectId.get();this.projectContextCache.set({data:t.data,error:null,loading:!0,stale:t.stale});try{const r=await this.fetchJson(this.buildTenantScopedPath("/api/project-context"));this.selectedTenant.get()===s&&this.selectedProjectId.get()===i&&this.projectContextCache.set({data:r,error:null,loading:!1})}catch(r){if(this.selectedTenant.get()===s&&this.selectedProjectId.get()===i){const a=this.projectContextCache.get();this.projectContextCache.set({data:a.data,error:r instanceof Error?r.message:String(r),loading:!1,stale:a.stale??t.stale})}}}async retryProjectGraph(){await this.loadProjectGraph(!0)}async loadProjectGraph(e=!1){await this.loadProjectRecordData("/api/project-graph",this.projectGraphCache,e)}async loadProjectRecordData(e,t,s){const i=t.get();if(i.loading||!s&&i.data&&!i.stale)return;const r=this.selectedTenant.get(),a=this.selectedProjectId.get();t.set({data:i.data,error:null,loading:!0,stale:i.stale});try{const o=await this.fetchJson(this.buildTenantScopedPath(e));this.selectedTenant.get()===r&&this.selectedProjectId.get()===a&&t.set({data:o,error:null,loading:!1})}catch(o){if(this.selectedTenant.get()===r&&this.selectedProjectId.get()===a){const l=t.get();t.set({data:l.data,error:o instanceof Error?o.message:String(o),loading:!1,stale:l.stale??i.stale})}}}async loadPlanEntryPage(e,t=!1,s){const i=this.planEntryPages.get().get(e);if(i?.loading||!t&&i?.data&&!i.stale&&!s)return;const r=this.selectedTenant.get(),a=this.selectedProjectId.get();this.setPlanEntryPageCache(e,{data:i?.data??null,error:null,loading:!0,stale:i?.stale});try{const o=await this.fetchJson(this.buildTenantScopedPath(`/api/plan-entries?plan=${encodeURIComponent(e)}${s?`&before=${encodeURIComponent(s)}`:""}`));if(this.selectedTenant.get()===r&&this.selectedProjectId.get()===a){const l=s?[...new Map([...i?.data?.entries??[],...o.entries].map(u=>[u.id,u])).values()]:o.entries;this.setPlanEntryPageCache(e,{data:{...o,entries:l},error:null,loading:!1})}}catch(o){if(this.selectedTenant.get()===r&&this.selectedProjectId.get()===a){const l=this.planEntryPages.get().get(e);this.setPlanEntryPageCache(e,{data:l?.data??i?.data??null,error:o instanceof Error?o.message:String(o),loading:!1,stale:l?.stale??i?.stale})}}}setPlanEntryPageCache(e,t){const s=new Map(this.planEntryPages.get());s.set(e,t),this.planEntryPages.set(s)}async loadIssueCommentPage(e,t=!1,s){const i=this.issueCommentPages.get().get(e);if(i?.loading||!t&&i?.data&&!i.stale&&!s)return;const r=this.selectedTenant.get(),a=this.selectedProjectId.get();this.setIssueCommentPageCache(e,{data:i?.data??null,error:null,loading:!0,stale:i?.stale});try{const o=await this.fetchJson(this.buildTenantScopedPath(`/api/issue-comments?issue=${encodeURIComponent(e)}${s?`&before=${encodeURIComponent(s)}`:""}`));if(this.selectedTenant.get()===r&&this.selectedProjectId.get()===a){const l=s?[...new Map([...i?.data?.comments??[],...o.comments].map(p=>[p.id,p])).values()]:o.comments,u=s?[...new Map([...i?.data?.users??[],...o.users].map(p=>[p.id,p])).values()]:o.users;this.setIssueCommentPageCache(e,{data:{...o,comments:l,users:u},error:null,loading:!1})}}catch(o){if(this.selectedTenant.get()===r&&this.selectedProjectId.get()===a){const l=this.issueCommentPages.get().get(e);this.setIssueCommentPageCache(e,{data:l?.data??i?.data??null,error:o instanceof Error?o.message:String(o),loading:!1,stale:l?.stale??i?.stale})}}}setIssueCommentPageCache(e,t){const s=new Map(this.issueCommentPages.get());s.set(e,t),this.issueCommentPages.set(s)}entityDetailForId(e){return e?this.entityDetails.get().get(e)?.detail??null:null}async retryEntityDetail(e){await this.loadEntityDetail(e,!0)}async loadEntityDetail(e,t=!1){const s=this.entityDetails.get().get(e);if(s?.loading||!t&&s?.detail&&!s.stale)return;const i=this.selectedTenant.get(),r=this.selectedProjectId.get();this.setEntityDetailCache(e,{detail:s?.detail??null,error:null,loading:!0,stale:s?.stale});try{const a=await this.fetchJson(this.buildTenantScopedPath(`/api/entity-detail?entity=${encodeURIComponent(e)}`));if(this.selectedTenant.get()!==i||this.selectedProjectId.get()!==r)return;if(!("entity"in a)){this.selectedId.get()===e&&this.clearSelection();return}this.setEntityDetailCache(e,{detail:a,error:null,loading:!1}),a.entity.kind==="issue"&&this.loadIssueCommentPage(e)}catch(a){if(this.selectedTenant.get()===i&&this.selectedProjectId.get()===r){const o=this.entityDetails.get().get(e);this.setEntityDetailCache(e,{detail:o?.detail??s?.detail??null,error:a instanceof Error?a.message:String(a),loading:!1,stale:o?.stale??s?.stale})}}}setEntityDetailCache(e,t){const s=new Map(this.entityDetails.get());s.set(e,t),this.entityDetails.set(s)}setInitiativeDetailCache(e,t){const s=new Map(this.initiativeDetails.get());s.set(e,t),this.initiativeDetails.set(s)}async loadInitiativeTab(e,t,s=!1){const i=this.initiativeTabCacheKey(e,t),r=this.initiativeTabs.get().get(i);if(r?.loading||!s&&r?.data&&!r.stale)return;const a=this.selectedTenant.get(),o=this.selectedProjectId.get();this.setInitiativeTabCache(i,{data:r?.data??null,error:null,loading:!0,stale:r?.stale});try{const l=await this.fetchJson(this.buildTenantScopedPath(`/api/initiative-tab?initiative=${encodeURIComponent(e)}&tab=${t}`));if(this.selectedTenant.get()!==a||this.selectedProjectId.get()!==o)return;this.setInitiativeTabCache(i,{data:l,error:null,loading:!1})}catch(l){if(this.selectedTenant.get()===a&&this.selectedProjectId.get()===o){const u=this.initiativeTabs.get().get(i);this.setInitiativeTabCache(i,{data:u?.data??r?.data??null,error:l instanceof Error?l.message:String(l),loading:!1,stale:u?.stale??r?.stale})}}}startInitiativeTabPrefetch(e){if(this.cancelInitiativeTabPrefetch(),!this.connected)return;const t=this.initiativeTabPrefetchGeneration,s=[...pc],i=()=>{t!==this.initiativeTabPrefetchGeneration||this.selectedInitiativeId.get()!==e||s.length===0||(this.initiativeTabPrefetchTimer=window.setTimeout(()=>{this.initiativeTabPrefetchTimer=null,r()},oc))},r=async()=>{if(t!==this.initiativeTabPrefetchGeneration||this.selectedInitiativeId.get()!==e)return;const a=s[0];if(!a)return;const o=this.initiativeTabs.get().get(this.initiativeTabCacheKey(e,a));if(o?.loading){i();return}s.shift(),(!o?.data||o.stale)&&await this.loadInitiativeTab(e,a),i()};i()}cancelInitiativeTabPrefetch(){this.initiativeTabPrefetchGeneration+=1,this.initiativeTabPrefetchTimer!==null&&(window.clearTimeout(this.initiativeTabPrefetchTimer),this.initiativeTabPrefetchTimer=null)}initiativeTabCacheKey(e,t){return`${e}:${t}`}setInitiativeTabCache(e,t){const s=new Map(this.initiativeTabs.get());s.set(e,t),this.initiativeTabs.set(s)}async reloadProjectDiscovery(){try{this.projectDiscovery.set(await this.fetchJson(this.buildTenantScopedPath("/api/projects"))),this.errorMessage.set(null)}catch(e){this.projectDiscovery.set({kind:"unavailable"}),this.errorMessage.set(e instanceof Error?e.message:String(e))}}async navigateToRoute(e){const t=e.tenantId!==this.selectedTenant.get()||e.projectId!==this.selectedProjectId.get();if(this.selectedTenant.set(e.tenantId),this.selectedProjectId.set(e.projectId),t&&this.resetScopeDetail(),!e.projectId){this.snapshot.set(null),this.projectSummary.set(null),this.syncLabel.set("choose a project"),await this.reloadProjectDiscovery(),this.applyRoute(e);return}this.stopLiveUpdates(),this.syncLabel.set("connecting");try{await this.reloadProjectSummary(),this.connectEvents(),this.applyRoute(e)}catch(s){this.selectedProjectId.set(null),this.snapshot.set(null),this.projectSummary.set(null),this.writeRoute(this.currentRoute(),!0),this.errorMessage.set(s instanceof Error?s.message:String(s)),this.syncLabel.set("project unavailable")}}resetScopeDetail(){this.cancelInitiativeTabPrefetch(),this.cancelGlobalSearchRequest(),this.globalSearchCapability.set(null),this.globalSearchQuery.set(""),this.globalSearchResponse.set(null),this.globalSearchProgress.set(!1),this.globalSearchOpen.set(!1),this.entityDetails.set(new Map),this.projectAdrsCache.set({data:null,error:null,loading:!1}),this.projectDebtCache.set({data:null,error:null,loading:!1}),this.projectContextCache.set({data:null,error:null,loading:!1}),this.projectGraphCache.set({data:null,error:null,loading:!1}),this.planEntryPages.set(new Map),this.issueCommentPages.set(new Map),this.initiativeDetails.set(new Map),this.initiativeTabs.set(new Map),this.selectedId.set(null),this.selectedInitiativeId.set(null),this.selectedNestedTarget.set(null),this.cascadePath.set([]),this.reRootTrail.set([]),this.activeSection.set("initiatives"),this.activePage.set("list"),this.activeView.set("overview"),this.initTab.set("overview"),this.initiativeStatusFilter.set("all"),this.adrStatusFilter.set("all"),this.clearMasterOverrideIfShallow()}connectEvents(){if(typeof EventSource!="function"){this.startPolling();return}this.events=new EventSource(this.buildTenantScopedPath("/events")),this.events.onmessage=e=>{this.handleProjectChangeEvent(e)},this.events.onerror=()=>{this.syncLabel.set("reconnecting"),this.startPolling()}}handleProjectChangeEvent(e){let t;try{t=JSON.parse(e.data)}catch{this.refreshProjectSummaryInBackground();return}if(t.correlationId){const s=this.localChangeCorrelations.get(t.correlationId);if(this.localChangeCorrelations.delete(t.correlationId),s!==void 0&&s>=Date.now())return}this.handleProjectChange(t)}handleProjectChange(e){if(e.projectId&&e.projectId!==this.selectedProjectId.get())return;if(!e.category||e.category==="bulk"||e.category==="unknown"){this.refreshProjectSummaryInBackground();return}const t=this.selectedId.get(),s=fc(e);let i=!1;if(e.category==="entity"){for(const a of e.affectedEntityIds??[]){const o=this.entityDetails.get().get(a);o&&(this.setEntityDetailCache(a,{...o,stale:!0}),i=!0)}if(t&&e.affectedEntityIds?.includes(t)&&(this.loadEntityDetail(t,!0),i=!0),e.affectedEntityKinds?.includes("adr")){const a=this.projectAdrsCache.get();a.data&&this.projectAdrsCache.set({...a,stale:!0}),this.activeSection.get()==="adrs"&&this.activePage.get()==="list"&&this.loadProjectAdrs(!0),i=!0}if(e.affectedEntityKinds?.includes("debt")){const a=this.projectDebtCache.get();a.data&&this.projectDebtCache.set({...a,stale:!0}),this.activeSection.get()==="debt"&&this.activePage.get()==="list"&&this.loadProjectDebt(!0),i=!0}const r=this.projectGraphCache.get();r.data&&this.projectGraphCache.set({...r,stale:!0}),this.activeSection.get()==="graph"&&this.activePage.get()==="list"&&(this.loadProjectGraph(!0),i=!0)}if(e.category==="issue-comment")for(const r of e.affectedEntityIds??[]){const a=this.issueCommentPages.get().get(r);a&&(this.setIssueCommentPageCache(r,{...a,stale:!0}),i=!0),t===r&&(this.loadIssueCommentPage(r,!0),i=!0)}if(e.category==="plan-entry")for(const r of e.affectedEntityIds??[]){const a=this.planEntryPages.get().get(r),o=a!==void 0||this.entityForId(r)?.kind==="plan";a&&(this.setPlanEntryPageCache(r,{...a,stale:!0}),i=!0),t===r&&o&&(this.loadPlanEntryPage(r,!0),i=!0);const l=this.entityDetails.get().get(r);l&&!o&&(this.setEntityDetailCache(r,{...l,stale:!0}),i=!0),t===r&&!o&&(this.loadEntityDetail(r,!0),i=!0)}if(e.category==="context"){const r=this.projectContextCache.get();r.data&&this.projectContextCache.set({...r,stale:!0}),this.activeSection.get()==="context"&&this.activePage.get()==="list"&&this.loadProjectContext(!0),i=!0}if(e.category==="relation"){for(const a of e.affectedEntityIds??[]){const o=this.entityDetails.get().get(a);o&&(this.setEntityDetailCache(a,{...o,stale:!0}),i=!0),t===a&&(this.loadEntityDetail(a,!0),i=!0)}const r=this.projectGraphCache.get();r.data&&this.projectGraphCache.set({...r,stale:!0}),this.activeSection.get()==="graph"&&this.activePage.get()==="list"&&this.loadProjectGraph(!0),i=!0}for(const r of e.affectedInitiativeIds??[]){if(e.affectedEntityIds?.includes(r)){const a=this.initiativeDetails.get().get(r);a&&(this.setInitiativeDetailCache(r,{...a,stale:!0}),i=!0),this.selectedInitiativeId.get()===r&&this.initTab.get()==="overview"&&(this.loadInitiativeDetail(r,!0),i=!0)}for(const[a,o]of this.initiativeTabs.get()){const l=a.slice(`${r}:`.length);a.startsWith(`${r}:`)&&s.has(l)&&(this.setInitiativeTabCache(a,{...o,stale:!0}),i=!0)}this.selectedInitiativeId.get()===r&&this.initTab.get()!=="overview"&&s.has(this.initTab.get())&&(this.loadInitiativeTab(r,this.initTab.get(),!0),i=!0)}if(i){e.affectsProjectSummary&&this.refreshProjectSummaryInBackground();return}this.refreshProjectSummaryInBackground()}startPolling(){this.pollTimer===null&&(this.pollTimer=window.setInterval(()=>{this.refreshProjectSummaryInBackground()},3e3))}async fetchJson(e){const t=e.includes("?")?"&":"?",s=await fetch(`${e}${t}ts=${Date.now()}`,{cache:"no-store"});if(!s.ok)throw new Error(`Request failed for ${e}`);return await s.json()}sortEntities(e){return[...e].sort((t,s)=>{const i=new Date(t.updatedAt).getTime(),r=new Date(s.updatedAt).getTime();return i!==r?r-i:t.id.localeCompare(s.id)})}buildIssueTree(e,t,s){const i=new Map(e.issues.map(l=>[l.id,l])),r=new Map;for(const l of e.subIssueLinks){if(!s.has(l.parent.id)||!s.has(l.issue.id))continue;const u=r.get(l.parent.id)??[];u.push(l.issue.id),r.set(l.parent.id,u)}const a=l=>{const u=i.get(l);if(!u)return null;const p=this.sortEntities((r.get(l)??[]).map(d=>i.get(d)).filter(d=>!!d));return{issue:u,children:p.map(d=>a(d.id)).filter(d=>d!==null)}};return this.sortEntities(t.map(l=>i.get(l)).filter(l=>!!l)).map(l=>a(l.id)).filter(l=>l!==null)}issueTreeNodeIds(e){return[e.issue.id,...e.children.flatMap(t=>this.issueTreeNodeIds(t))]}formatTenantDisplayName(e){return e.replace(/-[0-9a-f]{12}$/i,"").split(/[-_]+/).filter(t=>t.length>0).map(t=>`${t.charAt(0).toUpperCase()}${t.slice(1)}`).join(" ")}readTenantFromUrl(){return this.readRoute().tenantId}readProjectFromUrl(){return this.readRoute().projectId}currentRoute(){return{tenantId:this.selectedTenant.get(),projectId:this.selectedProjectId.get(),page:this.activePage.get(),section:this.activeSection.get(),entityId:this.selectedId.get(),initiativeId:this.selectedInitiativeId.get(),initiativeTab:this.initTab.get(),target:this.selectedNestedTarget.get()}}readRoute(){const e=new URL(window.location.href),t=new URLSearchParams(e.hash.slice(1)),s=e.searchParams,i=t.get("tenant")??s.get("tenant"),r=t.get("project")??s.get("project"),a=t.get("section"),o=t.get("entity"),l=t.get("initiative"),u=t.get("page"),p=u==="entity"?"entity":u==="initiative"?"initiative":u==="project"?"list":o?"entity":l?"initiative":"list",d=t.get("tab"),g=Nn.includes(d)?d:"overview",b=t.get("target"),x=t.get("target-id"),E=t.get("target-scope")??void 0,O=b==="context"?{id:null,scopeRef:E,type:"context"}:x&&b==="context-term"?{id:x,scopeRef:E,type:b}:x&&(b==="context-term"||b==="issue-comment"||b==="plan-entry")?{type:b,id:x}:null;return{tenantId:i,projectId:r,page:p,section:Gl(a)?a:"initiatives",entityId:o,initiativeId:l,initiativeTab:g,target:O}}normalizeRoute(e){const t=this.entityById.get();if(t.size===0)return e;const s=e.page==="entity"&&e.entityId&&(this.snapshot.get()===null||t.has(e.entityId))?e.entityId:null,i=e.page==="initiative"&&e.initiativeId&&this.bundleForInitiativeId(e.initiativeId)?e.initiativeId:null;return{...e,page:s?"entity":i?"initiative":"list",entityId:s,initiativeId:i,initiativeTab:i?e.initiativeTab:"overview",target:this.normalizeNestedTarget(e.target,s)}}normalizeNestedTarget(e,t){if(!e)return null;if(e.type==="plan-entry")return(this.snapshot.get()?.planEntries??[]).find(r=>r.id===e.id&&r.planId===t&&!r.tombstone)?e:null;if(e.type==="issue-comment")return(t?this.snapshot.get()?.issueComments[t]?.comments.find(r=>r.id===e.id&&!r.tombstone):null)?e:null;const s=e.scopeRef?this.getContextForInitiative(e.scopeRef):this.sharedContext.get();return s?.context.exists&&(e.type==="context"||s.terms.some(i=>i.term===e.id))?e:null}applyRoute(e,t=!0){const s=this.normalizeRoute(e);return s.initiativeId!==this.selectedInitiativeId.get()&&this.cancelInitiativeTabPrefetch(),this.selectedTenant.set(s.tenantId),this.selectedProjectId.set(s.projectId),this.activeSection.set(s.section),this.selectedId.set(s.entityId),this.selectedInitiativeId.set(s.initiativeId),this.initTab.set(s.initiativeTab),this.selectedNestedTarget.set(s.target),(s.target?.type==="context"||s.target?.type==="context-term")&&(this.contextTab.set(s.target.scopeRef?"initiatives":"global"),this.selectedContextInitiativeId.set(s.target.scopeRef??null)),this.cascadePath.set([]),this.reRootTrail.set([]),this.clearMasterOverrideIfShallow(),this.activePage.set(s.page),this.activeView.set("overview"),t&&(s.entityId?this.loadEntityDetail(s.entityId):s.initiativeId&&this.isSummaryInitiative(s.initiativeId)?this.loadInitiativeRoute(s.initiativeId,s.initiativeTab):s.section==="adrs"?this.loadProjectAdrs():s.section==="debt"?this.loadProjectDebt():s.section==="context"?this.loadProjectContext():s.section==="graph"&&this.loadProjectGraph()),s}writeRoute(e,t=!1){const s=new URL(window.location.href),i=[],r=(a,o)=>{o&&i.push(`${a}=${encodeURIComponent(o)}`)};r("tenant",e.tenantId),r("project",e.projectId),r("page",e.projectId?e.page==="list"?"project":e.page:null),r("section",e.section==="initiatives"?null:e.section),r("entity",e.entityId),r("initiative",e.initiativeId),r("tab",e.page==="initiative"?e.initiativeTab:null),r("target",e.target?.type??null),r("target-id",e.target?.id??null),r("target-scope",e.target?.scopeRef??null),s.searchParams.delete("tenant"),s.searchParams.delete("project"),s.hash=i.join("&"),window.history[t?"replaceState":"pushState"]({},"",s)}buildTenantScopedPath(e){const t=this.selectedTenant.get(),s=this.selectedProjectId.get();if(!t&&!s)return e;const i=e.includes("?")?"&":"?",r=new URLSearchParams;return t&&r.set("tenant",t),s&&r.set("project",s),r.size>0?`${e}${i}${r}`:e}stopLiveUpdates(){this.events?.close(),this.events=null,this.pollTimer!==null&&(window.clearInterval(this.pollTimer),this.pollTimer=null)}}function rn(n){return new Set(n.map(t=>t.definition.trim().toLowerCase()).filter(t=>t.length>0)).size>1}function bc(n,e){switch(e){case"questions":return n.role==="question";case"decisions":return n.role==="decision";case"includedScope":return n.role==="scope"&&n.scopeDirection==="included";case"excludedScope":return n.role==="scope"&&n.scopeDirection==="excluded";case"constraints":return n.role==="constraint";case"preferences":return n.role==="preference";case"considerations":return n.role==="consideration"}}function vc(n,e){return n.scopeKind!==e.scopeKind?n.scopeKind==="default"?-1:1:n.scopeLabel!==e.scopeLabel?n.scopeLabel.localeCompare(e.scopeLabel):n.contextKey.localeCompare(e.contextKey)}const Gs="tenant-switcher-menu",nn="agent-issues-theme",Ei=class Ei extends rs(de){constructor(){super(...arguments),this.store=new mc,this.medium=!1,this.narrow=!1,this.mobileMasterOpen=!1,this.theme="light",this.globalSearchTrigger=null,this.onSelectTenant=e=>{const t=e.currentTarget.dataset.tenant;t&&this.store.selectTenant(t)},this.onSelectSection=e=>{const t=e.currentTarget.dataset.section;t&&(this.store.selectSection(t),this.mobileMasterOpen=!1,this.requestUpdate())},this.onSelectInitiative=e=>{const t=e.currentTarget.dataset.initiative;t&&(this.store.selectInitiative(t),this.mobileMasterOpen=!1,this.requestUpdate())},this.onSelectProject=e=>{const t=e.currentTarget.dataset.project;t&&this.store.selectProject(t)},this.onOpenProjectChooser=()=>{this.store.returnToProjectChooser()},this.onSelectEntity=e=>{const t=e.currentTarget.dataset.id;t&&(this.store.selectEntity(t),this.mobileMasterOpen=!1,this.requestUpdate())},this.onSearchInput=e=>{this.store.search.set(e.target.value)},this.onOpenGlobalSearch=e=>{this.globalSearchTrigger=e.currentTarget,this.store.openGlobalSearch()},this.onCloseGlobalSearch=()=>{this.store.closeGlobalSearch(),this.globalSearchTrigger?.focus()},this.onOpenGlobalSearchTarget=e=>{this.store.openSearchTarget(e.detail),this.onCloseGlobalSearch()},this.onRetryGlobalSearch=()=>{this.store.retryGlobalSearch()},this.onRetryProjectSection=e=>{const t=e.currentTarget.dataset.section;t==="adrs"?this.store.retryProjectAdrs():t==="debt"?this.store.retryProjectDebt():t==="context"?this.store.retryProjectContext():t==="graph"&&this.store.retryProjectGraph()},this.onWindowKeyDown=e=>{const t=e.target;e.key.toLowerCase()!=="k"||!e.metaKey&&!e.ctrlKey||t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t?.isContentEditable||(e.preventDefault(),this.globalSearchTrigger=document.activeElement instanceof HTMLElement?document.activeElement:this.shadowRoot?.querySelector("[data-global-search-trigger]")??null,this.store.openGlobalSearch())},this.onToggleRail=()=>{this.store.toggleRail()},this.onToggleMaster=()=>{this.store.toggleMaster()},this.onToggleMobileMaster=async()=>{this.mobileMasterOpen=!this.mobileMasterOpen,this.requestUpdate(),this.mobileMasterOpen&&(await this.updateComplete,this.shadowRoot?.querySelector(".master-search")?.focus())},this.onToggleTheme=()=>{const e=this.theme==="light"?"dark":"light";this.setTheme(e,!0)},this.onToggleEpic=e=>{const t=e.currentTarget.dataset.epicToggle;t&&this.store.toggleEpicExpanded(t)},this.onContextSearchInput=e=>{this.store.contextSearch.set(e.target.value)},this.onSetContextTab=e=>{const t=e.currentTarget.dataset.contextTab;t&&this.store.setContextTab(t)},this.onSetContextInitiativeFilter=e=>{const t=e.currentTarget.dataset.contextInitiative??"";this.store.setContextInitiativeFilter(t||null)},this.onSetMasterStatusFilter=e=>{const t=e.currentTarget,s=t.dataset.masterSection,i=t.dataset.masterStatus;s!=="initiatives"&&s!=="adrs"||!i||this.store.setMasterStatusFilter(s,i)},this.onSetDebtFilter=e=>{const t=e.currentTarget,s=t.dataset.debtFilter,i=t.dataset.debtValue;!s||!i||this.store.setDebtFilter(s,i)},this.onToggleProjectGraphKind=e=>{const t=e.detail.kind;t&&this.store.toggleProjectGraphKind(t)},this.onProjectNodeOpen=e=>{const{id:t,kind:s}=e.detail;if(t){if(s==="initiative"){this.store.selectInitiative(t);return}this.store.selectProjectGraphEntity(t,s)}},this.updateNarrowMode=()=>{const e=window.innerWidth<=900,t=!e&&window.innerWidth<=1200;this.narrow===e&&this.medium===t||(this.narrow=e,this.medium=t,e||(this.mobileMasterOpen=!1),this.requestUpdate())}}toAriaBoolean(e){return e?"true":"false"}formatStatusFilter(e){return e==="all"?"All":e.split("-").map(t=>`${t.charAt(0).toUpperCase()}${t.slice(1)}`).join(" ")}focusContextTarget(){for(const i of this.renderRoot.querySelectorAll(".is-context-target, .is-context-term-target"))i.classList.remove("is-context-target","is-context-term-target");const e=this.store.selectedNestedTarget.get();if(!e||e.type!=="context"&&e.type!=="context-term")return;const t=e.type==="context"?[...this.renderRoot.querySelectorAll(".ctx-context-summary")].find(i=>i.dataset.contextScope===(e.scopeRef??"shared")):[...this.renderRoot.querySelectorAll(".ctx-term")].find(i=>i.dataset.term===e.id);if(!t)return;const s=e.type==="context"?"is-context-target":"is-context-term-target";t.classList.remove(s),t.offsetWidth,t.classList.add(s),t.focus({preventScroll:!0}),typeof t.scrollIntoView=="function"&&t.scrollIntoView({behavior:"smooth",block:"center"})}updated(){this.focusContextTarget()}connectedCallback(){super.connectedCallback();const e=window.localStorage.getItem(nn);this.setTheme(e==="dark"?"dark":"light"),this.updateNarrowMode(),window.addEventListener("resize",this.updateNarrowMode),window.addEventListener("keydown",this.onWindowKeyDown),this.store.connect()}disconnectedCallback(){window.removeEventListener("resize",this.updateNarrowMode),window.removeEventListener("keydown",this.onWindowKeyDown),this.store.disconnect(),super.disconnectedCallback()}setTheme(e,t=!1){this.theme=e,document.documentElement.dataset.theme=e,t&&window.localStorage.setItem(nn,e),this.requestUpdate()}renderThemeToggle(e){const t=this.theme==="light"?"dark":"light",s=this.theme==="light"?"☾":"☼";return h`
|
|
2948
2948
|
<button
|
|
2949
2949
|
aria-label=${`Switch to ${t} theme`}
|
|
2950
2950
|
aria-pressed=${this.toAriaBoolean(this.theme==="dark")}
|
|
@@ -3071,9 +3071,9 @@ Please report this to https://github.com/markedjs/marked.`,n){let s="<p>An error
|
|
|
3071
3071
|
</nav>
|
|
3072
3072
|
<div class="rail-foot">
|
|
3073
3073
|
<span class="rail-foot-copy">${e.projectDescription.get()}</span>
|
|
3074
|
-
${w(!this.narrow,()=>this.renderThemeToggle("rail"),()=>k)}
|
|
3074
|
+
${w(!this.narrow&&!this.medium,()=>this.renderThemeToggle("rail"),()=>k)}
|
|
3075
3075
|
</div>
|
|
3076
|
-
${w(this.narrow,()=>this.renderThemeToggle("header"),()=>k)}
|
|
3076
|
+
${w(this.narrow||this.medium,()=>this.renderThemeToggle("header"),()=>k)}
|
|
3077
3077
|
</aside>
|
|
3078
3078
|
`}renderProjectCard(e){const t=e.initiativeCount>0?Math.round(e.completedInitiativeCount/e.initiativeCount*100):0;return h`
|
|
3079
3079
|
<button
|
|
@@ -3973,6 +3973,18 @@ Please report this to https://github.com/markedjs/marked.`,n){let s="<p>An error
|
|
|
3973
3973
|
margin: 6px 0 0;
|
|
3974
3974
|
font-size: 24px;
|
|
3975
3975
|
}
|
|
3976
|
+
.console.medium .header-theme-toggle {
|
|
3977
|
+
display: inline-flex;
|
|
3978
|
+
flex: 0 0 40px;
|
|
3979
|
+
align-self: stretch;
|
|
3980
|
+
width: 40px;
|
|
3981
|
+
height: auto;
|
|
3982
|
+
margin-left: auto;
|
|
3983
|
+
border-top: 0;
|
|
3984
|
+
border-right: 0;
|
|
3985
|
+
border-bottom: 0;
|
|
3986
|
+
border-radius: 0;
|
|
3987
|
+
}
|
|
3976
3988
|
.d-sub {
|
|
3977
3989
|
max-width: 70ch;
|
|
3978
3990
|
margin: 10px 0 0;
|
package/site/dist/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>agent-issues viewer</title>
|
|
7
7
|
<style>#app { min-height: 100vh; }</style>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-BRvRYF7I.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-DKEVC0aQ.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|