@selvakumaresra/specship 0.3.0 → 0.5.0

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.
Files changed (97) hide show
  1. package/README.md +11 -1
  2. package/commands/ss-brainstorm.md +68 -0
  3. package/commands/ss-design-implement.md +5 -0
  4. package/commands/ss-design-loop.md +125 -0
  5. package/dist/analytics/specship-impact.d.ts +72 -0
  6. package/dist/analytics/specship-impact.d.ts.map +1 -0
  7. package/dist/analytics/specship-impact.js +216 -0
  8. package/dist/analytics/specship-impact.js.map +1 -0
  9. package/dist/bin/specship.js +70 -4
  10. package/dist/bin/specship.js.map +1 -1
  11. package/dist/db/migrations.d.ts +1 -1
  12. package/dist/db/migrations.d.ts.map +1 -1
  13. package/dist/db/migrations.js +15 -1
  14. package/dist/db/migrations.js.map +1 -1
  15. package/dist/db/schema.sql +8 -0
  16. package/dist/designer/artifact-store.js +54 -0
  17. package/dist/designer/browser.js +141 -0
  18. package/dist/designer/cdp-ensure.js +60 -0
  19. package/dist/designer/cdp-env.js +18 -0
  20. package/dist/designer/cdp-trace.js +599 -0
  21. package/dist/designer/cross-platform.js +74 -0
  22. package/dist/designer/designer-controller.js +1413 -0
  23. package/dist/designer/file-panel.js +39 -0
  24. package/dist/designer/interstitials.js +97 -0
  25. package/dist/designer/oopif-reader.js +176 -0
  26. package/dist/designer/package-meta.js +18 -0
  27. package/dist/designer/preview-host.js +50 -0
  28. package/dist/designer/repo-root.js +31 -0
  29. package/dist/designer/run-state.js +353 -0
  30. package/dist/designer/session-store.js +59 -0
  31. package/dist/designer/ui-anchors.js +651 -0
  32. package/dist/index.d.ts +27 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +48 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/installer/index.d.ts +7 -2
  37. package/dist/installer/index.d.ts.map +1 -1
  38. package/dist/installer/index.js +3 -2
  39. package/dist/installer/index.js.map +1 -1
  40. package/dist/installer/instructions-template.d.ts +17 -0
  41. package/dist/installer/instructions-template.d.ts.map +1 -1
  42. package/dist/installer/instructions-template.js +31 -1
  43. package/dist/installer/instructions-template.js.map +1 -1
  44. package/dist/installer/targets/claude.d.ts +19 -0
  45. package/dist/installer/targets/claude.d.ts.map +1 -1
  46. package/dist/installer/targets/claude.js +100 -1
  47. package/dist/installer/targets/claude.js.map +1 -1
  48. package/dist/installer/targets/shared.d.ts +14 -0
  49. package/dist/installer/targets/shared.d.ts.map +1 -1
  50. package/dist/installer/targets/shared.js +49 -0
  51. package/dist/installer/targets/shared.js.map +1 -1
  52. package/dist/installer/targets/types.d.ts +8 -0
  53. package/dist/installer/targets/types.d.ts.map +1 -1
  54. package/dist/mcp/designer-tools.d.ts +33 -0
  55. package/dist/mcp/designer-tools.d.ts.map +1 -0
  56. package/dist/mcp/designer-tools.js +313 -0
  57. package/dist/mcp/designer-tools.js.map +1 -0
  58. package/dist/mcp/tools.d.ts.map +1 -1
  59. package/dist/mcp/tools.js +22 -1
  60. package/dist/mcp/tools.js.map +1 -1
  61. package/dist/server/ingest/impact-backfill.js +69 -0
  62. package/dist/server/ingest/impact-query.js +343 -0
  63. package/dist/server/ingest/index.js +2 -1
  64. package/dist/server/ingest/ingestor.js +41 -6
  65. package/dist/server/ingest/specship-classify.js +153 -0
  66. package/dist/server/routes/claude.js +32 -0
  67. package/dist/server/routes/spec.js +94 -0
  68. package/dist/server/server.js +26 -2
  69. package/dist/web/{chunk-JN6W7HCN.js → chunk-45QHGCB4.js} +1 -1
  70. package/dist/web/{chunk-RAAMPHPJ.js → chunk-A5R3MJMO.js} +1 -1
  71. package/dist/web/{chunk-2DHIGIOI.js → chunk-ASZ77FMZ.js} +1 -1
  72. package/dist/web/chunk-D5OCNEJA.js +2 -0
  73. package/dist/web/{chunk-3SEJX2BK.js → chunk-FHZHD2ZG.js} +1 -1
  74. package/dist/web/chunk-GR72OOCN.js +1 -0
  75. package/dist/web/{chunk-YAWCRPHV.js → chunk-NZEZCT65.js} +1 -1
  76. package/dist/web/chunk-O7434ZMN.js +1 -0
  77. package/dist/web/chunk-ODX6CT3I.js +6 -0
  78. package/dist/web/chunk-RASJHUXS.js +1 -0
  79. package/dist/web/chunk-TQ3P2QZO.js +1 -0
  80. package/dist/web/{chunk-BCZM5AXU.js → chunk-UBOZGQNK.js} +1 -1
  81. package/dist/web/chunk-WCHGDXWC.js +1 -0
  82. package/dist/web/{chunk-BPECIDVO.js → chunk-WCKHQIYN.js} +1 -1
  83. package/dist/web/{chunk-JFYVCXK3.js → chunk-WLIMNDS3.js} +1 -1
  84. package/dist/web/{chunk-LV4G6QFG.js → chunk-YAMRN47K.js} +1 -1
  85. package/dist/web/index.html +1 -1
  86. package/dist/web/main-X2KCYXZ4.js +1 -0
  87. package/dist/web/sw.js +69 -0
  88. package/dist/workflows/defaults/claude-design-implement.yaml +138 -49
  89. package/hooks/hooks.json +11 -0
  90. package/package.json +7 -3
  91. package/selectors.json +41 -0
  92. package/dist/web/chunk-2OKMB4KX.js +0 -2
  93. package/dist/web/chunk-4N5DWG46.js +0 -1
  94. package/dist/web/chunk-DA6SNNAF.js +0 -1
  95. package/dist/web/chunk-JT7P3DEK.js +0 -6
  96. package/dist/web/chunk-TWXZK6XM.js +0 -1
  97. package/dist/web/main-WVI3YTDU.js +0 -1
@@ -1,6 +0,0 @@
1
- import{a as te}from"./chunk-G7VZT5KB.js";import{a as ne}from"./chunk-EMGMOEVR.js";import{a as ie}from"./chunk-X2HTISHL.js";import{a as ee}from"./chunk-R5W2MDZN.js";import{a as Y}from"./chunk-WDU3WICG.js";import{a as F,b as Z}from"./chunk-HZA6NEAB.js";import{b as W}from"./chunk-4N5DWG46.js";import{c as B}from"./chunk-SHPTC4RL.js";import{a as J}from"./chunk-7RNS77UP.js";import{a as X}from"./chunk-E44X4RH2.js";import{Aa as p,Ga as y,I as M,Ia as x,Ka as s,M as f,N as C,Oa as H,Pa as Q,Qa as U,R as G,T as S,Ta as $,Ua as R,Va as d,W as _,Wa as g,Xa as b,aa as z,ea as o,ka as k,lb as h,ra as m,sa as u,va as I,wa as N,xa as c,ya as r,yb as K,za as l,zb as E}from"./chunk-PDN6QYGJ.js";import"./chunk-Q7L6LLAK.js";var V=null,ue="self.onmessage = () => {};";function oe(){return V||(typeof window<"u"&&!window.MonacoEnvironment&&(window.MonacoEnvironment={getWorker:(i,t)=>{let e=new Blob([ue],{type:"text/javascript"}),n=URL.createObjectURL(e);return new Worker(n,{name:t||"monaco-noop"})}}),V=import("./chunk-FMV5PXRC.js"),V)}var re=!1;function ae(i){re||(re=!0,ge(i))}function le(i,t){let e=[],n=t.getValue().split(`
2
- `),a=null,v=new Map,P=/<!--\s*id\s*:\s*([^\s-][^\s]*)\s*-->/,me=/^#{1,6}\s+/;for(let O=0;O<n.length;O++){let T=n[O]??"",D=O+1,j=T.match(P);if(j&&j[1]){a!==null&&e.push({severity:i.MarkerSeverity.Warning,message:`Stranded <!-- id: ${a.id} -->: no heading follows on line ${a.line+1}.`,startLineNumber:a.line+1,startColumn:1,endLineNumber:a.line+1,endColumn:(n[a.line]??"").length+1,code:"spec_stranded_id"});let w=j[1];a={id:w,line:O};let q=v.get(w);q!==void 0?e.push({severity:i.MarkerSeverity.Warning,message:`Duplicate spec ID "${w}" \u2014 first seen on line ${q+1}. The second occurrence will be silently lost by the parser.`,startLineNumber:D,startColumn:T.indexOf(w)+1,endLineNumber:D,endColumn:T.indexOf(w)+w.length+1,code:"spec_duplicate_id"}):v.set(w,O);continue}me.test(T)&&(a===null?e.push({severity:i.MarkerSeverity.Error,message:"This heading has no embedded ID. Add `<!-- id: REQ-X -->` on the line above it \u2014 required by the SpecShip parser.",startLineNumber:D,startColumn:1,endLineNumber:D,endColumn:T.length+1,code:"spec_missing_id"}):a=null)}i.editor.setModelMarkers(t,"specship-spec",e)}function ge(i){i.languages.registerCompletionItemProvider("markdown",{provideCompletionItems:(t,e)=>{let n=t.getWordUntilPosition(e),a={startLineNumber:e.lineNumber,endLineNumber:e.lineNumber,startColumn:n.startColumn,endColumn:n.endColumn},v=i.languages.CompletionItemKind,P=i.languages.CompletionItemInsertTextRule;return{suggestions:[{label:"req",kind:v.Snippet,insertText:["<!-- id: REQ-${1:AREA}-${2:001} -->","## ${3:Title MUST be concrete}","","${4:Body \u2014 describe the contract, not the implementation.}","","## Acceptance","<!-- id: REQ-${1:AREA}-${2:001}.A1 -->","- ${5:First testable acceptance criterion}","$0"].join(`
3
- `),insertTextRules:P.InsertAsSnippet,documentation:"Insert a full requirement (heading + acceptance) with embedded IDs.",detail:"SpecShip \xB7 requirement",range:a},{label:"doc",kind:v.Snippet,insertText:["---","id: ${1:AREA}-DOC","title: ${2:Title}","owner: ${3:team-or-person}","priority: ${4|high,medium,low|}","---","","<!-- id: ${1:AREA}-DOC -->","# ${2:Title}","","${5:One-paragraph summary of what this document covers.}","$0"].join(`
4
- `),insertTextRules:P.InsertAsSnippet,documentation:"Insert a new spec document with frontmatter.",detail:"SpecShip \xB7 document",range:a},{label:"accept",kind:v.Snippet,insertText:["## Acceptance","<!-- id: ${1:REQ-X}.A1 -->","- ${2:First testable acceptance criterion}","<!-- id: ${1:REQ-X}.A2 -->","- ${3:Second testable acceptance criterion}","$0"].join(`
5
- `),insertTextRules:P.InsertAsSnippet,documentation:"Insert an Acceptance section with two ID-d bullets.",detail:"SpecShip \xB7 acceptance",range:a},{label:"impl",kind:v.Snippet,insertText:["implementations:"," - ${1:src/path/to/file.ts}:${2:QualifiedSymbol}","$0"].join(`
6
- `),insertTextRules:P.InsertAsSnippet,documentation:"Insert an implementations block linking the spec to code.",detail:"SpecShip \xB7 implementations",range:a}]}},triggerCharacters:["r","d","a","i"]})}var _e=["host"];function ve(i,t){if(i&1&&(r(0,"span",5),d(1),l()),i&2){let e=s();c("title",e.path),o(),g(e.path)}}function xe(i,t){i&1&&(r(0,"div",15),d(1,"Loading editor\u2026"),l())}var L=class i{sanitizer=M(K);destroyRef=M(G);value="";path="";valueChange=new S;validationChange=new S;save=new S;cancel=new S;hostRef;loading=_(!0);currentValue=_("");errorCount=_(0);warningCount=_(0);dirty=_(!1);previewHtml=h(()=>this.sanitizer.bypassSecurityTrustHtml(te(this.currentValue()||"")));tokenCount=h(()=>Math.max(1,Math.round((this.currentValue()||"").length/4)));statusLabel=h(()=>{let t=this.errorCount(),e=this.warningCount();return t>0?`${t} error${t===1?"":"s"}`:e>0?`${e} warning${e===1?"":"s"}`:"clean"});statusKind=h(()=>this.errorCount()>0?"error":this.warningCount()>0?"warn":"ok");monaco=null;editor=null;model=null;diagnosticsTimer=null;async ngAfterViewInit(){this.currentValue.set(this.value);try{let t=await oe();this.monaco=t,ae(t),this.model=t.editor.createModel(this.value,"markdown"),this.editor=t.editor.create(this.hostRef.nativeElement,{model:this.model,theme:this.preferDark()?"vs-dark":"vs",automaticLayout:!0,wordWrap:"on",minimap:{enabled:!1},scrollBeyondLastLine:!1,renderWhitespace:"none",fontSize:13,lineNumbers:"on",folding:!1,tabSize:2,insertSpaces:!0,contextmenu:!1}),this.editor.onDidChangeModelContent(()=>this.handleEdit()),this.runDiagnosticsNow(),this.loading.set(!1)}catch(t){console.error("[spec-editor] failed to load Monaco",t),this.loading.set(!1)}this.destroyRef.onDestroy(()=>this.dispose())}ngOnDestroy(){this.dispose()}onSave(){this.save.emit()}onCancel(){this.cancel.emit()}handleEdit(){if(!this.model)return;let t=this.model.getValue();this.currentValue.set(t),this.dirty.set(t!==this.value),this.valueChange.emit(t),this.diagnosticsTimer!==null&&clearTimeout(this.diagnosticsTimer),this.diagnosticsTimer=setTimeout(()=>this.runDiagnosticsNow(),500)}runDiagnosticsNow(){if(!this.monaco||!this.model)return;le(this.monaco,this.model);let t=this.monaco.editor.getModelMarkers({resource:this.model.uri,owner:"specship-spec"}),e=t.filter(a=>a.severity===this.monaco.MarkerSeverity.Error).length,n=t.filter(a=>a.severity===this.monaco.MarkerSeverity.Warning).length;this.errorCount.set(e),this.warningCount.set(n),this.validationChange.emit({errors:e,warnings:n})}preferDark(){if(typeof window>"u")return!1;try{return window.matchMedia("(prefers-color-scheme: dark)").matches}catch{return!1}}dispose(){this.diagnosticsTimer!==null&&(clearTimeout(this.diagnosticsTimer),this.diagnosticsTimer=null),this.editor?.dispose(),this.editor=null,this.model?.dispose(),this.model=null}static \u0275fac=function(e){return new(e||i)};static \u0275cmp=k({type:i,selectors:[["app-spec-editor"]],viewQuery:function(e,n){if(e&1&&H(_e,7),e&2){let a;Q(a=U())&&(n.hostRef=a.first)}},inputs:{value:"value",path:"path"},outputs:{valueChange:"valueChange",validationChange:"validationChange",save:"save",cancel:"cancel"},decls:23,vars:16,consts:[["host",""],[1,"editor-shell","col"],[1,"toolbar","row","gap-8"],["name","memory",3,"size"],[1,"title"],[1,"path","mono",3,"title"],[1,"grow"],[1,"status-pill"],[1,"dot"],[1,"tokens","mono","tabular","muted",3,"title"],["type","button",1,"btn","btn-secondary","btn-sm",3,"click"],["type","button",1,"btn","btn-primary","btn-sm",3,"click","disabled","title"],["name","check",3,"size"],[1,"panes","row"],[1,"editor-pane"],[1,"loading"],[1,"monaco-host"],[1,"preview-pane","md-content",3,"innerHTML"]],template:function(e,n){e&1&&(r(0,"div",1)(1,"div",2),p(2,"app-icon",3),r(3,"span",4),d(4,"Spec editor"),l(),m(5,ve,2,2,"span",5),p(6,"span",6),r(7,"span",7),p(8,"span",8),d(9),l(),r(10,"span",9),d(11),l(),r(12,"button",10),x("click",function(){return n.onCancel()}),d(13," Cancel "),l(),r(14,"button",11),x("click",function(){return n.onSave()}),p(15,"app-icon",12),d(16," Save "),l()(),r(17,"div",13)(18,"div",14),m(19,xe,2,0,"div",15),p(20,"div",16,0),l(),p(22,"div",17),l()()),e&2&&(o(2),c("size",14),o(3),u(n.path?5:-1),o(2),R("ok",n.statusKind()==="ok")("warn",n.statusKind()==="warn")("error",n.statusKind()==="error"),o(2),b(" ",n.statusLabel()," "),o(),c("title","~"+n.tokenCount()+" tokens (rough estimate)"),o(),b(" ~",n.tokenCount(),"t "),o(3),c("disabled",!n.dirty()||n.errorCount()>0)("title",n.errorCount()>0?"Fix errors before saving":n.dirty()?"Save changes":"No changes to save"),o(),c("size",13),o(4),u(n.loading()?19:-1),o(3),c("innerHTML",n.previewHtml(),z))},dependencies:[E],styles:['@charset "UTF-8";[_nghost-%COMP%]{display:flex;flex:1;min-height:0}.editor-shell[_ngcontent-%COMP%]{flex:1;min-height:0;border:1px solid var(--border-subtle);border-radius:10px;overflow:hidden;background:var(--bg-panel)}.toolbar[_ngcontent-%COMP%]{align-items:center;padding:8px 12px;border-bottom:1px solid var(--border-subtle);background:var(--bg-panel);flex-wrap:wrap;row-gap:6px}.toolbar[_ngcontent-%COMP%] .title[_ngcontent-%COMP%]{font-size:12.5px;font-weight:650;color:var(--text-primary)}.toolbar[_ngcontent-%COMP%] .path[_ngcontent-%COMP%]{font-size:11px;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:320px}.toolbar[_ngcontent-%COMP%] .tokens[_ngcontent-%COMP%]{font-size:10.5px;color:var(--text-muted)}.status-pill[_ngcontent-%COMP%]{display:inline-flex;align-items:center;gap:6px;font-size:11px;font-weight:600;padding:3px 9px;border-radius:999px;white-space:nowrap}.status-pill[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%]{width:7px;height:7px;border-radius:50%}.status-pill.ok[_ngcontent-%COMP%]{color:var(--success);background:var(--success-soft)}.status-pill.ok[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%]{background:var(--success)}.status-pill.warn[_ngcontent-%COMP%]{color:var(--warn);background:var(--warn-soft)}.status-pill.warn[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%]{background:var(--warn)}.status-pill.error[_ngcontent-%COMP%]{color:var(--error);background:var(--error-soft)}.status-pill.error[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%]{background:var(--error)}.panes[_ngcontent-%COMP%]{flex:1;min-height:0}.editor-pane[_ngcontent-%COMP%]{flex:1;min-width:0;min-height:0;position:relative;border-right:1px solid var(--border-subtle)}.loading[_ngcontent-%COMP%]{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--text-muted);font-size:12px;background:var(--bg-canvas);z-index:1}.monaco-host[_ngcontent-%COMP%]{position:absolute;inset:0}.preview-pane[_ngcontent-%COMP%]{flex:1;min-width:0;min-height:0;padding:14px 18px;overflow:auto;background:var(--bg-canvas)}.preview-pane.md-content[_ngcontent-%COMP%] .md-h1[_ngcontent-%COMP%]{font-size:15px;font-weight:650;color:var(--text-primary);letter-spacing:-.01em;margin:0 0 10px}.preview-pane.md-content[_ngcontent-%COMP%] .md-h2[_ngcontent-%COMP%]{font-size:13px;font-weight:650;color:var(--text-primary);letter-spacing:-.005em;margin:18px 0 6px;padding-bottom:4px;border-bottom:1px solid var(--border-subtle)}.preview-pane.md-content[_ngcontent-%COMP%] .md-h3[_ngcontent-%COMP%]{font-size:12px;font-weight:650;color:var(--text-primary);margin:14px 0 6px}.preview-pane.md-content[_ngcontent-%COMP%] .md-h4[_ngcontent-%COMP%]{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text-muted);margin:12px 0 4px}.preview-pane.md-content[_ngcontent-%COMP%] .md-p[_ngcontent-%COMP%]{font-size:12.5px;line-height:1.6;color:var(--text-secondary);margin:0 0 4px;overflow-wrap:anywhere}.preview-pane.md-content[_ngcontent-%COMP%] .md-p[_ngcontent-%COMP%] strong[_ngcontent-%COMP%]{color:var(--text-primary)}.preview-pane.md-content[_ngcontent-%COMP%] .md-list[_ngcontent-%COMP%], .preview-pane.md-content[_ngcontent-%COMP%] .md-ol[_ngcontent-%COMP%]{padding:0;margin:4px 0 6px}.preview-pane.md-content[_ngcontent-%COMP%] .md-list[_ngcontent-%COMP%] li[_ngcontent-%COMP%], .preview-pane.md-content[_ngcontent-%COMP%] .md-ol[_ngcontent-%COMP%] li[_ngcontent-%COMP%]{position:relative;padding:2px 0 2px 22px;font-size:12.5px;line-height:1.6;color:var(--text-secondary);overflow-wrap:anywhere}.preview-pane.md-content[_ngcontent-%COMP%] .md-list[_ngcontent-%COMP%] li[_ngcontent-%COMP%] strong[_ngcontent-%COMP%], .preview-pane.md-content[_ngcontent-%COMP%] .md-ol[_ngcontent-%COMP%] li[_ngcontent-%COMP%] strong[_ngcontent-%COMP%]{color:var(--text-primary)}.preview-pane.md-content[_ngcontent-%COMP%] .md-list[_ngcontent-%COMP%]{list-style:none}.preview-pane.md-content[_ngcontent-%COMP%] .md-list[_ngcontent-%COMP%] li[_ngcontent-%COMP%]:before{content:"\\2022";position:absolute;left:6px;top:2px;color:var(--text-faint)}.preview-pane.md-content[_ngcontent-%COMP%] .md-ol[_ngcontent-%COMP%]{list-style:none;counter-reset:md-ol}.preview-pane.md-content[_ngcontent-%COMP%] .md-ol[_ngcontent-%COMP%] li[_ngcontent-%COMP%]{counter-increment:md-ol}.preview-pane.md-content[_ngcontent-%COMP%] .md-ol[_ngcontent-%COMP%] li[_ngcontent-%COMP%]:before{content:counter(md-ol) ".";position:absolute;left:0;top:2px;color:var(--text-faint);font-family:var(--font-mono);font-size:11.5px;min-width:18px;text-align:right}.preview-pane.md-content[_ngcontent-%COMP%] .md-spacer[_ngcontent-%COMP%]{height:6px}.preview-pane.md-content[_ngcontent-%COMP%] .md-import[_ngcontent-%COMP%]{display:inline-block;font-size:11.5px;color:var(--node-route);background:var(--node-route-soft);padding:2px 8px;border-radius:5px;margin:4px 0}.preview-pane.md-content[_ngcontent-%COMP%] .md-inline-code[_ngcontent-%COMP%]{font-size:11.5px;background:var(--bg-canvas);padding:1px 6px;border-radius:4px;border:1px solid var(--border-subtle);color:var(--node-spec)}.preview-pane.md-content[_ngcontent-%COMP%] .md-blockquote[_ngcontent-%COMP%]{margin:6px 0;padding:8px 12px;border-left:3px solid var(--accent);background:var(--accent-soft);color:var(--text-secondary);font-size:12.5px;line-height:1.55;border-radius:0 6px 6px 0}.preview-pane.md-content[_ngcontent-%COMP%] .md-pre[_ngcontent-%COMP%]{position:relative;margin:8px 0 10px;padding:12px 14px;background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:8px;overflow-x:auto}.preview-pane.md-content[_ngcontent-%COMP%] .md-pre[_ngcontent-%COMP%] code[_ngcontent-%COMP%]{display:block;font-size:11.5px;line-height:1.55;color:var(--text-primary);white-space:pre}.preview-pane.md-content[_ngcontent-%COMP%] .md-pre-lang[_ngcontent-%COMP%]{position:absolute;top:6px;right:10px;font-size:10px;font-weight:600;color:var(--text-muted);text-transform:lowercase;background:var(--bg-canvas);padding:1px 6px;border-radius:4px;border:1px solid var(--border-subtle)}.preview-pane.md-content[_ngcontent-%COMP%] .md-table-scroll[_ngcontent-%COMP%]{overflow-x:auto;margin:10px 0;border:1px solid var(--border-subtle);border-radius:8px}.preview-pane.md-content[_ngcontent-%COMP%] .md-table[_ngcontent-%COMP%]{width:100%;border-collapse:collapse;font-size:11.5px}.preview-pane.md-content[_ngcontent-%COMP%] .md-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], .preview-pane.md-content[_ngcontent-%COMP%] .md-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%]{padding:8px 12px;text-align:left;vertical-align:top;border-bottom:1px solid var(--border-subtle)}.preview-pane.md-content[_ngcontent-%COMP%] .md-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%]{background:var(--bg-panel);font-weight:650;color:var(--text-primary);font-size:10.5px;text-transform:uppercase;letter-spacing:.04em;border-bottom:1px solid var(--border-strong);white-space:nowrap}.preview-pane.md-content[_ngcontent-%COMP%] .md-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] td[_ngcontent-%COMP%]{color:var(--text-secondary)}.preview-pane.md-content[_ngcontent-%COMP%] .md-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:last-child td[_ngcontent-%COMP%]{border-bottom:0}.preview-pane.md-content[_ngcontent-%COMP%] .md-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.preview-pane.md-content[_ngcontent-%COMP%] > [_ngcontent-%COMP%]:first-child{margin-top:0}'],changeDetection:0})};function fe(i,t){i&1&&(r(0,"div",14),d(1),l()),i&2&&(o(),g(t))}function Ce(i,t){if(i&1){let e=y();r(0,"div",0),x("click",function(){f(e);let a=s();return C(a.onBackdropClick())}),l(),r(1,"div",1)(2,"header",2)(3,"div",3)(4,"div",4),d(5,"Draft a new spec with Claude"),l(),r(6,"div",5),d(7,"Describe the feature in one sentence. Claude takes it from there."),l()(),r(8,"button",6),x("click",function(){f(e);let a=s();return C(a.onCloseClick())}),p(9,"app-icon",7),l()(),r(10,"div",8)(11,"label",9),d(12,"Feature description"),l(),r(13,"textarea",10),x("input",function(a){f(e);let v=s();return C(v.onDescriptionInput(a))}),l(),r(14,"div",11),d(15,"This will run in Claude Code:"),l(),r(16,"pre",12),d(17),l()(),r(18,"footer",13),m(19,fe,2,1,"div",14),p(20,"span",15),r(21,"button",16),x("click",function(){f(e);let a=s();return C(a.onCopyToClipboard())}),p(22,"app-icon",17),d(23," Copy prompt "),l(),r(24,"button",18),x("click",function(){f(e);let a=s();return C(a.onOpenInClaude())}),p(25,"app-icon",19),d(26," Open in Claude Code "),l()()()}if(i&2){let e,n=s();o(9),c("size",16),o(4),c("value",n.description()),o(4),g(n.slashCommand()),o(2),u((e=n.toast())?19:-1,e),o(2),c("disabled",!n.canSubmit()),o(),c("size",13),o(2),c("disabled",!n.canSubmit()),o(),c("size",13)}}var A=class i{open=!1;close=new S;description=_("");toast=_(null);slashCommand=h(()=>{let t=this.description().trim();return t?`/ss-spec-author "${t.replace(/"/g,'\\"')}"`:"/ss-spec-author"});canSubmit=h(()=>this.description().trim().length>0);onDescriptionInput(t){let e=t.target;this.description.set(e.value)}onBackdropClick(){this.dismiss()}onCloseClick(){this.dismiss()}async onOpenInClaude(){if(!this.canSubmit())return;let t=this.slashCommand();await this.writeToClipboard(t);try{window.location.href=`claude://prompt?text=${encodeURIComponent(t)}`,this.flashToast("Opening Claude Code\u2026 (also copied to clipboard)")}catch{this.flashToast("Claude Code handler unavailable \u2014 prompt copied to clipboard.")}}async onCopyToClipboard(){if(!this.canSubmit())return;let t=this.slashCommand(),e=await this.writeToClipboard(t);this.flashToast(e?"Copied! Switch to Claude Code and paste.":"Could not access clipboard \u2014 copy the prompt manually.")}async writeToClipboard(t){if(!navigator.clipboard)return!1;try{return await navigator.clipboard.writeText(t),!0}catch{return!1}}flashToast(t){this.toast.set(t),setTimeout(()=>this.toast.set(null),2500)}dismiss(){this.description.set(""),this.toast.set(null),this.close.emit()}static \u0275fac=function(e){return new(e||i)};static \u0275cmp=k({type:i,selectors:[["app-draft-with-claude-modal"]],inputs:{open:"open"},outputs:{close:"close"},decls:1,vars:1,consts:[["role","presentation",1,"backdrop",3,"click"],["role","dialog","aria-labelledby","draft-modal-title","aria-modal","true",1,"modal"],[1,"head"],[1,"title-block"],["id","draft-modal-title",1,"title"],[1,"sub"],["type","button","aria-label","Close",1,"close",3,"click"],["name","x",3,"size"],[1,"body"],["for","draft-description",1,"field-label"],["id","draft-description","rows","3","placeholder","e.g. Failed payment retries should back off with T+1d, T+3d, T+7d then downgrade the account.","autofocus","",1,"field",3,"input","value"],[1,"preview-label"],[1,"preview","mono"],[1,"foot"],[1,"toast"],[1,"grow"],["type","button",1,"btn","btn-secondary","btn-sm",3,"click","disabled"],["name","copy",3,"size"],["type","button",1,"btn","btn-primary","btn-sm",3,"click","disabled"],["name","external",3,"size"]],template:function(e,n){e&1&&m(0,Ce,27,8),e&2&&u(n.open?0:-1)},dependencies:[E],styles:[".backdrop[_ngcontent-%COMP%]{position:fixed;inset:0;background:#00000080;z-index:100;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.modal[_ngcontent-%COMP%]{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:min(560px,100vw - 32px);max-height:calc(100vh - 64px);background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:12px;box-shadow:0 24px 48px #0006;z-index:101;display:flex;flex-direction:column;overflow:hidden}.head[_ngcontent-%COMP%]{display:flex;align-items:flex-start;gap:12px;padding:16px 18px;border-bottom:1px solid var(--border-subtle)}.head[_ngcontent-%COMP%] .title-block[_ngcontent-%COMP%]{flex:1;min-width:0}.head[_ngcontent-%COMP%] .title[_ngcontent-%COMP%]{font-size:14.5px;font-weight:650;color:var(--text-primary);letter-spacing:-.01em}.head[_ngcontent-%COMP%] .sub[_ngcontent-%COMP%]{font-size:12px;color:var(--text-secondary);margin-top:2px;line-height:1.45}.head[_ngcontent-%COMP%] .close[_ngcontent-%COMP%]{appearance:none;background:transparent;border:0;width:28px;height:28px;border-radius:6px;color:var(--text-muted);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:background .12s,color .12s}.head[_ngcontent-%COMP%] .close[_ngcontent-%COMP%]:hover{background:var(--bg-hover);color:var(--text-primary)}.head[_ngcontent-%COMP%] .close[_ngcontent-%COMP%]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.body[_ngcontent-%COMP%]{padding:16px 18px;display:flex;flex-direction:column;gap:10px;overflow-y:auto}.field-label[_ngcontent-%COMP%]{font-size:11px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.04em}.field[_ngcontent-%COMP%]{width:100%;box-sizing:border-box;padding:10px 12px;background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:8px;color:var(--text-primary);font-family:var(--font-ui);font-size:13px;line-height:1.5;resize:vertical}.field[_ngcontent-%COMP%]:focus{outline:2px solid var(--accent);outline-offset:1px;border-color:transparent}.preview-label[_ngcontent-%COMP%]{font-size:11px;color:var(--text-muted);margin-top:4px}.preview[_ngcontent-%COMP%]{margin:0;padding:10px 12px;background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:8px;font-size:11.5px;line-height:1.5;color:var(--node-spec);font-family:var(--font-mono);white-space:pre-wrap;word-break:break-all}.foot[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;padding:12px 18px;border-top:1px solid var(--border-subtle);background:var(--bg-canvas);flex-wrap:wrap}.foot[_ngcontent-%COMP%] .grow[_ngcontent-%COMP%]{flex:1}.toast[_ngcontent-%COMP%]{font-size:11.5px;color:var(--success);background:var(--success-soft);padding:4px 10px;border-radius:999px;white-space:nowrap}"],changeDetection:0})};var he=(i,t)=>t.path,pe=(i,t)=>t.id;function be(i,t){i&1&&p(0,"app-pick-project-empty",0)}function ye(i,t){i&1&&p(0,"app-empty",9)}function we(i,t){if(i&1&&(r(0,"span",18),d(1),l()),i&2){let e=s().$implicit,n=s(2);o(),b(" ",n.driftCountForGroup(e)," ")}}function Me(i,t){if(i&1){let e=y();r(0,"div",21),x("click",function(){let a=f(e).$implicit,v=s(4);return C(v.select(a.id))}),p(1,"span",22),r(2,"div",23)(3,"div",24),d(4),l(),r(5,"div",25),d(6),l()()()}if(i&2){let e=t.$implicit,n=s(4);R("selected",n.sel()===e.id),o(),$("background",n.stateColorFor(e.kind)),o(2),$("color",n.sel()===e.id?"var(--accent)":"var(--text-primary)"),o(),g(e.id),o(2),g(e.title)}}function Se(i,t){if(i&1&&(r(0,"div",19),I(1,Me,7,8,"div",20,pe),l()),i&2){let e=s().$implicit;o(),N(e.specs)}}function Pe(i,t){if(i&1){let e=y();r(0,"div",14),x("click",function(){let a=f(e).$implicit,v=s(2);return C(v.toggleGroup(a.path))}),p(1,"app-icon",15)(2,"app-icon",16),r(3,"span",17),d(4),l(),m(5,we,2,1,"span",18),l(),m(6,Se,3,0,"div",19)}if(i&2){let e=t.$implicit,n=s(2);o(),c("name",n.isGroupOpen(e.path)?"chevronDown":"chevronRight")("size",12),o(),c("size",13),o(2),g(e.title),o(),u(n.driftCountForGroup(e)>0?5:-1),o(),u(n.isGroupOpen(e.path)?6:-1)}}function Oe(i,t){if(i&1&&(r(0,"div",26),d(1),l()),i&2){let e=s();o(),b("Loading source for ",e.id,"\u2026")}}function ke(i,t){if(i&1){let e=y();r(0,"app-spec-editor",30),x("valueChange",function(a){f(e);let v=s(4);return C(v.onEditorValueChange(a))})("save",function(){f(e);let a=s(4);return C(a.onEditorSave())})("cancel",function(){f(e);let a=s(4);return C(a.onEditorCancel())}),l()}if(i&2){let e=s(),n=s(3);c("value",n.editingSource())("path",e.sourcePath)}}function Ee(i,t){i&1&&(r(0,"div",28),d(1),l()),i&2&&(o(),g(t))}function Te(i,t){i&1&&(r(0,"div",29),d(1,"Saving\u2026"),l())}function De(i,t){if(i&1&&(m(0,Oe,2,1,"div",26)(1,ke,1,2,"app-spec-editor",27),m(2,Ee,2,1,"div",28),m(3,Te,2,0,"div",29)),i&2){let e,n=s(3);u(n.editingSource()===null?0:1),o(2),u((e=n.saveError())?2:-1,e),o(),u(n.saving()?3:-1)}}function ze(i,t){if(i&1&&m(0,De,4,3),i&2){let e,n=s(2);u((e=n.selectedSpec())?0:-1,e)}}function Ie(i,t){if(i&1&&(r(0,"app-pill"),d(1),l()),i&2){let e=s();o(),g(e.priority)}}function Ne(i,t){if(i&1&&(r(0,"div",37)(1,"div",38),d(2,"Owner"),l(),r(3,"div",39),d(4),l()()),i&2){let e=s();o(4),g(e.owner)}}function $e(i,t){i&1&&p(0,"div",42)}function Re(i,t){if(i&1&&(r(0,"app-pill",56),d(1),l()),i&2){let e=s().$implicit;o(),b("",e.driftAxis," drift")}}function Ve(i,t){if(i&1&&(r(0,"div",55),p(1,"app-state-pill",34),m(2,Re,2,1,"app-pill",56),r(3,"span",57),d(4),l(),r(5,"app-pill"),d(6),l(),r(7,"button",58),p(8,"app-icon",51),d(9," Reveal "),l()()),i&2){let e=t.$implicit,n=t.$index;$("border-top",n>0?"1px solid var(--border-subtle)":"none"),o(),c("state",e.state),o(),u(e.driftAxis?2:-1),o(2),g(e.targetQualifiedName),o(2),g(e.provenance),o(2),c("size",12)}}function Le(i,t){if(i&1&&(r(0,"div",43),I(1,Ve,10,7,"div",54,pe),l()),i&2){let e=s(3);o(),N(e.selectedLinks())}}function Ae(i,t){i&1&&(r(0,"div",44),p(1,"app-icon",59),r(2,"div",60),d(3," Orphaned \u2014 no code implements this requirement yet "),l()()),i&2&&(o(),c("size",16))}function je(i,t){i&1&&(r(0,"div",53),d(1),l()),i&2&&(o(),g(t))}function We(i,t){if(i&1){let e=y();r(0,"div",11)(1,"div",31)(2,"span",32),d(3),l(),p(4,"app-copy-btn",33)(5,"div",6)(6,"app-state-pill",34),m(7,Ie,2,1,"app-pill"),l(),r(8,"h1",35),d(9),l(),r(10,"div",36)(11,"div",37)(12,"div",38),d(13,"Kind"),l(),r(14,"div",39),d(15),l()(),m(16,Ne,5,1,"div",37),r(17,"div",37)(18,"div",38),d(19,"Doc"),l(),r(20,"div",39),d(21),l()(),r(22,"div",37)(23,"div",38),d(24,"Siblings"),l(),r(25,"div",39),d(26),l()(),r(27,"div",37)(28,"div",38),d(29,"Links"),l(),r(30,"div",39),d(31),l()()(),r(32,"div",40),d(33,"Requirement"),l(),p(34,"div",41),r(35,"div",40),d(36,"Linked code"),l(),m(37,$e,1,0,"div",42)(38,Le,3,0,"div",43)(39,Ae,4,1,"div",44),r(40,"div",45)(41,"button",46),p(42,"app-icon",47),d(43," Implement "),l(),r(44,"button",48),p(45,"app-icon",49),d(46," Verify "),l(),r(47,"button",50),x("click",function(){f(e);let a=s(2);return C(a.onEditClick())}),p(48,"app-icon",51),d(49," Edit spec "),l(),r(50,"button",50),x("click",function(){let a=f(e),v=s(2);return C(v.goToGraph(a.id))}),p(51,"app-icon",52),d(52," Show in graph "),l()(),m(53,je,2,1,"div",53),l()}if(i&2){let e,n=t,a=s(2);o(3),g(n.id),o(),c("text",n.id),o(2),c("state",n.kind),o(),u(n.priority?7:-1),o(2),g(n.title),o(6),g(n.kind),o(),u(n.owner?16:-1),o(5),g(n.sourcePath.replace("specs/","")),o(5),b("",a.selectedSiblings().length," reqs"),o(5),g(a.selectedLinks().length),o(3),c("innerHTML",a.mdHtml(n.body),z),o(3),u(a.detailResource.state().loading?37:a.selectedLinks().length>0?38:39),o(5),c("size",13),o(3),c("size",13),o(3),c("size",13),o(3),c("size",13),o(2),u((e=a.saveError())?53:-1,e)}}function Fe(i,t){i&1&&(r(0,"app-empty",12)(1,"code",61),d(2,"specship init -i"),l()())}function qe(i,t){if(i&1){let e=y();r(0,"div",1)(1,"div",2)(2,"div",3),p(3,"app-icon",4),r(4,"span",5),d(5,"Specs"),l(),p(6,"span",6),r(7,"span",7),d(8),l()(),r(9,"div",8),m(10,ye,1,0,"app-empty",9),I(11,Pe,7,6,null,null,he),l()(),r(13,"div",10),m(14,ze,1,1)(15,We,54,17,"div",11)(16,Fe,3,0,"app-empty",12),l()(),r(17,"app-draft-with-claude-modal",13),x("close",function(){f(e);let a=s();return C(a.onDraftModalClose())}),l()}if(i&2){let e,n=s();o(3),c("size",15),o(5),b(" ",n.resource.state().loading?"\u2026":n.totalCount()+" reqs"," "),o(2),u(n.groups().length===0&&!n.resource.state().loading?10:-1),o(),N(n.groups()),o(3),u(n.editing()?14:(e=n.selectedSpec())?15:16,e),o(3),c("open",n.draftModalOpen())}}function Ge(i){return i.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\*\*(.+?)\*\*/g,"<strong style='color:var(--text-primary)'>$1</strong>").replace(/`(.+?)`/g,"<code class='mono' style='font-size:12px;background:var(--bg-canvas);padding:1px 5px;border-radius:4px;border:1px solid var(--border-subtle)'>$1</code>")}var ce=class i{api=M(X);projects=M(J);router=M(B);resource=W(this.api,()=>`/api/specs${this.projects.projectQuery()}`);detailResource=W(this.api,()=>{let t=this.sel();return t?`/api/spec/${encodeURIComponent(t)}${this.projects.projectQuery()}`:null});sel=_(null);expandedGroups=_(new Set);editing=_(!1);editingSource=_(null);editingDirty=_(!1);saving=_(!1);saveError=_(null);draftModalOpen=_(!1);STATE=F;groups=h(()=>{let t=this.resource.state().data?.specs??[],e=new Map;for(let n of t){let a=n.sourcePath||"(unknown)";e.has(a)||e.set(a,{path:a,title:a.replace(/^specs\//,""),specs:[]}),e.get(a).specs.push(n)}return[...e.values()]});totalCount=h(()=>this.groups().reduce((t,e)=>t+e.specs.length,0));selectedSpec=h(()=>{let t=this.sel();if(!t)return null;for(let e of this.groups())for(let n of e.specs)if(n.id===t)return n;return null});selectedLinks=h(()=>this.detailResource.state().data?.links??[]);selectedSiblings=h(()=>{let t=this.selectedSpec();if(!t)return[];let e=this.groups().find(n=>n.path===t.sourcePath);return e?e.specs.filter(n=>n.id!==t.id):[]});isGroupOpen(t){return!this.expandedGroups().has("closed:"+t)}toggleGroup(t){this.expandedGroups.update(e=>{let n="closed:"+t,a=new Set(e);return a.has(n)?a.delete(n):a.add(n),a})}driftCountForGroup(t){let e=this.selectedSpec();return!e||e.sourcePath!==t.path?0:this.selectedLinks().filter(n=>["drifted","broken","orphaned"].includes(n.state)).length}stateColorFor(t){return F[t]?.color??"var(--node-spec)"}select(t){this.editing()&&(this.editing.set(!1),this.editingSource.set(null),this.editingDirty.set(!1)),this.sel.set(t)}mdHtml(t){return Ge(t)}goToGraph(t){this.router.navigate(["/graph"],{queryParams:{focus:"spec:"+t}})}async onEditClick(){let t=this.selectedSpec();if(t){this.saveError.set(null),this.editing.set(!0),this.editingSource.set(null);try{let e=this.projects.projectQuery(),n=await this.api.get(`/api/spec/${encodeURIComponent(t.id)}${e}`);this.editingSource.set(n.source??t.body)}catch(e){this.saveError.set(`Couldn't load source: ${e instanceof Error?e.message:String(e)}`),this.editing.set(!1)}}}onEditorValueChange(t){this.editingSource.set(t),this.editingDirty.set(!0)}async onEditorSave(){let t=this.selectedSpec(),e=this.editingSource();if(!(!t||e===null)){this.saving.set(!0),this.saveError.set(null);try{let n=this.projects.projectQuery();await this.api.put(`/api/spec/${encodeURIComponent(t.id)}${n}`,{content:e}),this.editing.set(!1),this.editingDirty.set(!1),this.editingSource.set(null),this.resource.refetch()}catch(n){this.saveError.set(`Save failed: ${n instanceof Error?n.message:String(n)}`)}finally{this.saving.set(!1)}}}onEditorCancel(){this.editingDirty()&&!window.confirm("Discard unsaved changes?")||(this.editing.set(!1),this.editingSource.set(null),this.editingDirty.set(!1),this.saveError.set(null))}onDraftWithClaudeClick(){this.draftModalOpen.set(!0)}onDraftModalClose(){this.draftModalOpen.set(!1)}static \u0275fac=function(e){return new(e||i)};static \u0275cmp=k({type:i,selectors:[["app-specs"]],decls:2,vars:1,consts:[["surface","Specs"],[1,"specs-shell"],[1,"tree-col"],[1,"tree-header","row","gap-8"],["name","book",2,"color","var(--accent)",3,"size"],[2,"font-weight","600","font-size","13px"],[1,"grow"],[1,"muted","tabular",2,"font-size","11px"],[1,"scroll-y","tree-scroll"],["icon","book","title","No specs found","body","Run specship init -i against a project with a specs/ directory."],[1,"detail-col","col"],[1,"scroll-y","detail-scroll"],["icon","book","title","Pick a spec from the tree","body","Or run specship init -i to index your specs/ folder if you haven't yet."],[3,"close","open"],[1,"doc-row","row","gap-6",3,"click"],[2,"color","var(--text-muted)",3,"name","size"],["name","book",2,"color","var(--node-spec)",3,"size"],[1,"mono","grow","doc-name"],[1,"pill",2,"font-size","9.5px","color","var(--warn)","background","var(--warn-soft)"],[1,"group-body"],[1,"req-row","row","gap-6",3,"selected"],[1,"req-row","row","gap-6",3,"click"],[1,"pill-dot",2,"flex-shrink","0"],[1,"grow",2,"min-width","0"],[1,"mono","req-id"],[1,"muted","req-title"],[1,"loading-detail"],[3,"value","path"],[1,"save-error"],[1,"save-status"],[3,"valueChange","save","cancel","value","path"],[1,"row","gap-8",2,"margin-bottom","4px"],[1,"mono",2,"font-size","12px","color","var(--node-spec)"],[3,"text"],[3,"state"],[1,"detail-title"],[1,"meta-row","row"],[1,"meta-item"],[1,"muted",2,"font-size","10.5px"],[1,"mono",2,"font-size","12.5px","margin-top","1px"],[1,"eyebrow",2,"margin-bottom","8px"],[1,"detail-body",3,"innerHTML"],[1,"skel",2,"height","42px","border-radius","8px","margin-bottom","22px"],[1,"card",2,"overflow","hidden","margin-bottom","22px"],[1,"card","card-pad","orphan-card"],[1,"row","gap-8",2,"flex-wrap","wrap"],["type","button",1,"btn","btn-primary","btn-sm"],["name","play",3,"size"],["type","button",1,"btn","btn-secondary","btn-sm"],["name","check",3,"size"],["type","button",1,"btn","btn-secondary","btn-sm",3,"click"],["name","reveal",3,"size"],["name","graph",3,"size"],[1,"save-error",2,"margin-top","16px"],[1,"row","gap-10","link-row",3,"border-top"],[1,"row","gap-10","link-row"],["color","var(--warn)","bg","var(--warn-soft)"],[1,"mono","grow","link-target"],["type","button",1,"btn","btn-ghost","btn-xs"],["name","drift",3,"size"],[2,"margin-top","6px","font-size","12.5px"],["action","",1,"mono",2,"font-size","11.5px","color","var(--accent)","background","var(--bg-canvas)","padding","5px 10px","border-radius","6px","border","1px solid var(--border-subtle)"]],template:function(e,n){e&1&&m(0,be,1,0,"app-pick-project-empty",0)(1,qe,18,5),e&2&&u(n.resource.state().noProject?0:1)},dependencies:[Y,E,L,A,ne,Z,ie,ee],styles:['@charset "UTF-8";[_nghost-%COMP%]{display:contents}.specs-shell[_ngcontent-%COMP%]{flex:1;display:flex;min-height:0}.tree-col[_ngcontent-%COMP%]{width:280px;flex-shrink:0;border-right:1px solid var(--border-subtle);background:var(--bg-panel);display:flex;flex-direction:column;min-height:0}.tree-header[_ngcontent-%COMP%]{padding:11px 12px;border-bottom:1px solid var(--border-subtle);align-items:center}.tree-scroll[_ngcontent-%COMP%]{flex:1;padding:6px}.doc-row[_ngcontent-%COMP%]{padding:6px 8px;border-radius:6px;cursor:pointer;color:var(--text-secondary);align-items:center}.doc-row[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.doc-name[_ngcontent-%COMP%]{font-size:12px;color:var(--text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.group-body[_ngcontent-%COMP%]{margin-left:14px;border-left:1px solid var(--border-subtle);padding-left:6px}.req-row[_ngcontent-%COMP%]{padding:5px 8px;border-radius:6px;cursor:pointer;align-items:flex-start;background:transparent}.req-row[_ngcontent-%COMP%]:not(.selected):hover{background:var(--bg-hover)}.req-row.selected[_ngcontent-%COMP%]{background:var(--accent-soft)}.req-id[_ngcontent-%COMP%]{font-size:11px}.req-title[_ngcontent-%COMP%]{font-size:10.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.detail-col[_ngcontent-%COMP%]{flex:1;min-width:0}.detail-scroll[_ngcontent-%COMP%]{flex:1;padding:22px}.detail-title[_ngcontent-%COMP%]{font-size:22px;font-weight:650;letter-spacing:-.01em;margin:2px 0 14px;text-wrap:pretty}.meta-row[_ngcontent-%COMP%]{gap:18px;padding:10px 0;border-top:1px solid var(--border-subtle);border-bottom:1px solid var(--border-subtle);margin-bottom:18px;flex-wrap:wrap}.detail-body[_ngcontent-%COMP%]{font-size:13.5px;line-height:1.65;color:var(--text-secondary);margin-bottom:22px;text-wrap:pretty}.link-row[_ngcontent-%COMP%]{padding:10px 12px}.link-target[_ngcontent-%COMP%]{font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.orphan-card[_ngcontent-%COMP%]{text-align:center;color:var(--error);margin-bottom:22px;border-color:#f2555a4d}.loading-detail[_ngcontent-%COMP%]{padding:40px 18px;color:var(--text-muted);font-size:13px;text-align:center}.save-error[_ngcontent-%COMP%]{padding:10px 14px;border:1px solid rgba(255,90,90,.35);background:var(--error-soft);color:var(--error);border-radius:8px;font-size:12.5px;line-height:1.5}.save-status[_ngcontent-%COMP%]{margin-top:8px;color:var(--text-muted);font-size:12px}'],changeDetection:0})};export{ce as Specs};
@@ -1 +0,0 @@
1
- import{a as oe}from"./chunk-MC4DFIHG.js";import{a as te}from"./chunk-UYC52MBC.js";import{a as ne}from"./chunk-SUZYBYDW.js";import{b as Q}from"./chunk-4N5DWG46.js";import"./chunk-7RNS77UP.js";import{a as J}from"./chunk-E44X4RH2.js";import{Aa as _,Ba as C,Ca as M,Da as $,Ea as j,Fa as G,I as B,Ia as I,Ja as V,Ka as u,O as w,P as A,Ta as k,Ua as K,Va as c,W as F,Wa as d,Xa as z,Ya as Y,bb as E,ea as a,fb as Z,gb as U,ib as W,ka as P,lb as p,ob as X,pb as g,qa as b,ra as v,sa as f,ua as H,va as D,vb as q,wa as S,xa as y,ya as r,za as s,zb as ee}from"./chunk-PDN6QYGJ.js";import"./chunk-Q7L6LLAK.js";function ve(o,e){if(o&1&&(w(),$(0,"path",1)(1,"path",2)),o&2){let t=u();b("d",t.fillD())("fill",t.color()),a(),b("d",t.pathD())("stroke",t.color())}}var T=class o{series=g([]);color=g("var(--accent)");height=g(200);hover=X();width=600;stats=p(()=>{let e=this.series();if(!e.length)return{max:1,min:0};let t=e.map(n=>n.cost);return{max:Math.max(...t,.01),min:0}});pathD=p(()=>{let e=this.series();if(!e.length)return"";let t=this.width,n=this.height(),{max:i}=this.stats();return e.map((l,m)=>{let x=m/Math.max(1,e.length-1)*t,h=n-l.cost/i*(n-20)-10;return(m===0?"M":"L")+x.toFixed(2)+" "+h.toFixed(2)}).join(" ")});fillD=p(()=>{let e=this.pathD();return e?e+` L ${this.width} ${this.height()} L 0 ${this.height()} Z`:""});onLeave(){this.hover.emit(null)}onMove(e){let n=e.currentTarget.getBoundingClientRect(),i=(e.clientX-n.left)/n.width,l=this.series();if(!l.length)return;let m=Math.min(l.length-1,Math.max(0,Math.round(i*(l.length-1)))),x=l[m];x&&this.hover.emit(x)}static \u0275fac=function(t){return new(t||o)};static \u0275cmp=P({type:o,selectors:[["app-line-chart"]],inputs:{series:[1,"series"],color:[1,"color"],height:[1,"height"]},outputs:{hover:"hover"},decls:2,vars:3,consts:[["width","100%","preserveAspectRatio","none",1,"line-chart",3,"mousemove","mouseleave"],["opacity","0.10"],["fill","none","stroke-width","1.6","stroke-linecap","round","stroke-linejoin","round"]],template:function(t,n){t&1&&(w(),C(0,"svg",0),V("mousemove",function(l){return n.onMove(l)})("mouseleave",function(){return n.onLeave()}),v(1,ve,2,4),M()),t&2&&(b("viewBox","0 0 "+n.width+" "+n.height())("height",n.height()),a(),f(n.pathD()?1:-1))},styles:["[_nghost-%COMP%]{display:block}.line-chart[_ngcontent-%COMP%]{cursor:crosshair}"],changeDetection:0})};var fe=(o,e)=>e.label;function _e(o,e){if(o&1&&(w(),$(0,"path")),o&2){let t=e.$implicit;b("d",t.d)("fill",t.color)}}function xe(o,e){if(o&1&&(C(0,"div",3),c(1),M()),o&2){let t=u();a(),d(t.centerSub())}}var N=class o{data=g([]);size=g(150);centerLabel=g("");centerSub=g("");arcs=p(()=>{let e=this.data(),t=e.reduce((h,L)=>h+L.cost,0);if(t<=0)return[];let i=this.size()/2,l=i*.6,m=-Math.PI/2,x=[];for(let h of e){let L=h.cost/t*Math.PI*2,O=m+L,R=L>Math.PI?1:0,ce=i+Math.cos(m)*i,le=i+Math.sin(m)*i,de=i+Math.cos(O)*i,pe=i+Math.sin(O)*i,me=i+Math.cos(O)*l,ue=i+Math.sin(O)*l,ge=i+Math.cos(m)*l,he=i+Math.sin(m)*l;x.push({d:`M ${ce} ${le} A ${i} ${i} 0 ${R} 1 ${de} ${pe} L ${me} ${ue} A ${l} ${l} 0 ${R} 0 ${ge} ${he} Z`,color:h.color,label:h.short||h.model||""}),m=O}return x});static \u0275fac=function(t){return new(t||o)};static \u0275cmp=P({type:o,selectors:[["app-donut"]],inputs:{data:[1,"data"],size:[1,"size"],centerLabel:[1,"centerLabel"],centerSub:[1,"centerSub"]},decls:8,vars:9,consts:[[1,"donut"],[1,"donut-center"],[1,"center-label"],[1,"center-sub"]],template:function(t,n){t&1&&(C(0,"div",0),w(),C(1,"svg"),D(2,_e,1,2,":svg:path",null,fe),M(),A(),C(4,"div",1)(5,"div",2),c(6),M(),v(7,xe,2,1,"div",3),M()()),t&2&&(k("width",n.size(),"px")("height",n.size(),"px"),a(),b("width",n.size())("height",n.size())("viewBox","0 0 "+n.size()+" "+n.size()),a(),S(n.arcs()),a(4),d(n.centerLabel()),a(),f(n.centerSub()?7:-1))},styles:["[_nghost-%COMP%]{display:inline-block}.donut[_ngcontent-%COMP%]{position:relative}.donut-center[_ngcontent-%COMP%]{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;pointer-events:none}.center-label[_ngcontent-%COMP%]{font-variant-numeric:tabular-nums;font-size:18px;font-weight:700;color:var(--text-primary)}.center-sub[_ngcontent-%COMP%]{color:var(--text-muted);font-size:10.5px;margin-top:2px}"],changeDetection:0})};var be=()=>({value:"today",label:"Today"}),ye=()=>({value:"week",label:"This week"}),Ce=()=>({value:"month",label:"This month"}),Me=()=>({value:"all",label:"All time"}),we=(o,e,t,n)=>[o,e,t,n],Pe=()=>[0,1,2,3],De=(o,e)=>e.model,Se=(o,e)=>e.id;function ke(o,e){if(o&1&&_(0,"app-delta",10),o&2){let t=u();y("value",t.wowDelta())("invert",!0)}}function Ee(o,e){if(o&1&&(r(0,"div",11)(1,"div",24),c(2),s(),r(3,"div",25),c(4),s()()),o&2){let t=e,n=u();a(2),d(n.fmt$(t.cost)),a(2),Y("",t.prompts," prompts \xB7 day ",t.day)}}function Oe(o,e){if(o&1&&(r(0,"div",19),_(1,"span",26),r(2,"span",27),c(3),s(),r(4,"span",28),c(5),s(),r(6,"span",29),c(7),s()()),o&2){let t=e.$implicit,n=u();a(),k("background",t.color),a(2),d(t.short),a(2),d(n.fmt$(t.cost)),a(2),z("",n.percentOf(t.cost,n.total()),"%")}}function ze(o,e){o&1&&_(0,"div",30)}function Le(o,e){o&1&&D(0,ze,1,0,"div",30,H),o&2&&S(E(0,Pe))}function $e(o,e){if(o&1&&(r(0,"div",32)(1,"span",33),c(2),s(),r(3,"div",34)(4,"div",35),c(5),s(),r(6,"div",36),_(7,"span",37),s()(),r(8,"span",38),c(9),s(),r(10,"span",39),c(11),s(),r(12,"span",40),c(13),U(14,"number"),s(),r(15,"span",41),c(16),s()()),o&2){let t=e.$implicit,n=e.$index,i=u(2);K("first",n===0),a(2),d(n+1),a(3),d(t.text),a(2),k("width",t.cost_usd/i.maxPrompt()*100,"%")("background",t.cost_usd/i.maxPrompt()>.66?"var(--error)":"var(--accent)"),a(2),d(i.modelShort(t.model)),a(2),d(i.fmtK(i.promptTokens(t))),a(),k("color",i.cacheColor(i.cacheRate(t))),a(),z("",W(14,14,i.cacheRate(t)*100,"1.0-0"),"%"),a(3),d(i.fmt$(t.cost_usd))}}function Te(o,e){if(o&1&&D(0,$e,17,17,"div",31,Se),o&2){let t=u();S(t.topPrompts())}}var Ne={"claude-opus-4-7":"#A586F5","claude-opus-4":"#A586F5","claude-sonnet-4-6":"#5B93F2","claude-sonnet-4-7":"#5B93F2","claude-sonnet-4":"#5B93F2","claude-haiku-4-5":"#29D2BE","claude-haiku-4":"#29D2BE"},re={"claude-opus-4-7":"Opus 4.7","claude-opus-4":"Opus 4","claude-sonnet-4-6":"Sonnet 4.6","claude-sonnet-4-7":"Sonnet 4.7","claude-sonnet-4":"Sonnet 4","claude-haiku-4-5":"Haiku 4.5","claude-haiku-4":"Haiku 4"},se=class o{api=B(J);range=F("month");ranges=["today","week","month","all"];hovered=F(null);resource=Q(this.api,()=>`/api/claude/costs?range=${this.range()}`);series=p(()=>this.resource.state().data?.series??[]);topPrompts=p(()=>(this.resource.state().data?.topPrompts??[]).slice(0,12));maxPrompt=p(()=>{let e=this.topPrompts();return Math.max(.01,...e.map(t=>t.cost_usd??0))});byModel=p(()=>(this.resource.state().data?.byModel??[]).map(t=>({model:t.model,short:re[t.model]||t.model,cost:t.cost||0,color:Ne[t.model]||"#5C6573"})));total=p(()=>this.resource.state().data?.total??0);wowDelta=p(()=>this.resource.state().data?.wowDelta??0);setRange(e){this.range.set(e)}onHover(e){this.hovered.set(e)}fmt$(e){return"$"+e.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})}fmtK(e){return e>=1e3?(e/1e3).toFixed(e>=1e4?0:1)+"k":String(e)}promptTokens(e){return(e.input_tokens??0)+(e.output_tokens??0)+(e.cache_creation_tokens??0)+(e.cache_read_tokens??0)}cacheRate(e){let t=(e.input_tokens??0)+(e.cache_creation_tokens??0)+(e.cache_read_tokens??0);return t>0?(e.cache_read_tokens??0)/t:0}cacheColor(e){return e>=.7?"var(--success)":e>=.5?"var(--warn)":"var(--error)"}modelShort(e){return e?re[e]||e.replace(/^claude-/,""):"?"}percentOf(e,t){return t>0?Math.round(e/t*100):0}static \u0275fac=function(t){return new(t||o)};static \u0275cmp=P({type:o,selectors:[["app-costs"]],decls:34,vars:25,consts:[[1,"page","scroll-y"],["icon","dollar","title","Costs","sub","Where the money goes"],["actions",""],["size","sm",3,"change","value","options"],[1,"top-grid"],[1,"card","card-pad","chart-card"],[1,"chart-header"],[1,"big-number","mono"],[1,"row","gap-8",2,"margin-top","2px"],[1,"muted",2,"font-size","11.5px"],[3,"value","invert"],[2,"text-align","right"],["color","var(--accent)",3,"hover","series","height"],[1,"card","card-pad","donut-card"],[1,"row","gap-8",2,"align-self","flex-start","margin-bottom","8px"],["name","layers",2,"color","var(--node-code)",3,"size"],[2,"font-weight","600","font-size","12.5px"],[3,"data","size","centerLabel","centerSub"],[1,"model-legend"],[1,"legend-row"],[1,"card","card-pad"],[1,"row","gap-8",2,"margin-bottom","12px"],["name","sortAsc",2,"color","var(--accent)",3,"size"],[1,"muted",2,"font-size","11px"],[1,"mono",2,"font-size","13px","font-weight","600"],[1,"muted",2,"font-size","10.5px"],[1,"swatch"],[1,"mono","grow",2,"font-size","11.5px"],[1,"mono",2,"font-size","11.5px"],[1,"mono","muted",2,"font-size","10.5px","width","38px","text-align","right"],[1,"skel","row-skel"],[1,"prompt-row",3,"first"],[1,"prompt-row"],[1,"mono","muted","tabular","rank"],[1,"prompt-grow"],[1,"prompt-text"],[1,"bar-track",2,"margin-top","4px","max-width","280px"],[1,"bar-fill"],[1,"mono","muted","prompt-model"],[1,"mono","muted","tabular","prompt-toks"],[1,"mono","tabular","cache-cell"],[1,"mono","tabular","cost-cell"]],template:function(t,n){if(t&1&&(r(0,"div",0)(1,"app-page-head",1),j(2,2),r(3,"app-segmented",3),I("change",function(l){return n.setRange(l)}),s(),G(),s(),r(4,"div",4)(5,"div",5)(6,"div",6)(7,"div")(8,"div",7),c(9),s(),r(10,"div",8)(11,"span",9),c(12),s(),v(13,ke,1,2,"app-delta",10),s()(),v(14,Ee,5,3,"div",11),s(),r(15,"app-line-chart",12),I("hover",function(l){return n.onHover(l)}),s()(),r(16,"div",13)(17,"div",14),_(18,"app-icon",15),r(19,"span",16),c(20,"By model"),s()(),_(21,"app-donut",17),r(22,"div",18),D(23,Oe,8,5,"div",19,De),s()()(),r(25,"div",20)(26,"div",21),_(27,"app-icon",22),r(28,"span",16),c(29,"Most expensive prompts"),s(),r(30,"span",23),c(31),s()(),v(32,Le,2,1)(33,Te,2,0),s()()),t&2){let i;a(3),y("value",n.range())("options",Z(20,we,E(16,be),E(17,ye),E(18,Ce),E(19,Me))),a(6),d(n.fmt$(n.total())),a(3),z("total \xB7 ",n.range()),a(),f(n.range()!=="all"&&n.wowDelta()!==0?13:-1),a(),f((i=n.hovered())?14:-1,i),a(),y("series",n.series())("height",200),a(3),y("size",14),a(3),y("data",n.byModel())("size",150)("centerLabel","$"+n.total().toFixed(0))("centerSub",n.range()+" window"),a(2),S(n.byModel()),a(4),y("size",14),a(4),z("\xB7 top ",n.topPrompts().length),a(),f(n.resource.state().loading?32:33)}},dependencies:[T,N,te,ne,oe,ee,q],styles:["[_nghost-%COMP%]{display:contents}.page[_ngcontent-%COMP%]{flex:1;padding:18px}.muted[_ngcontent-%COMP%]{color:var(--text-muted)}.mono[_ngcontent-%COMP%]{font-family:var(--font-mono)}.grow[_ngcontent-%COMP%]{flex:1}.card[_ngcontent-%COMP%]{background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:var(--r-lg)}.card-pad[_ngcontent-%COMP%]{padding:14px}.top-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:1.3fr 1fr;gap:14px;margin-bottom:14px}.chart-card[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:10px}.chart-header[_ngcontent-%COMP%]{display:flex;justify-content:space-between;align-items:flex-start}.big-number[_ngcontent-%COMP%]{font-size:34px;font-weight:700;letter-spacing:-.02em}.donut-card[_ngcontent-%COMP%]{display:flex;flex-direction:column;align-items:center;gap:10px}.model-legend[_ngcontent-%COMP%]{width:100%;display:flex;flex-direction:column;gap:6px;margin-top:14px}.legend-row[_ngcontent-%COMP%]{display:flex;gap:8px;align-items:center}.swatch[_ngcontent-%COMP%]{width:9px;height:9px;border-radius:3px;flex-shrink:0}.prompt-row[_ngcontent-%COMP%]{display:grid;grid-template-columns:18px 1fr 70px 54px 44px 56px;gap:12px;align-items:center;padding:9px 0;border-top:1px solid var(--border-subtle)}.prompt-row.first[_ngcontent-%COMP%]{border-top:none}.rank[_ngcontent-%COMP%]{width:16px;font-size:11px}.prompt-grow[_ngcontent-%COMP%]{min-width:0}.prompt-text[_ngcontent-%COMP%]{font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.bar-track[_ngcontent-%COMP%]{height:4px;background:#ffffff0f;border-radius:999px;overflow:hidden}.bar-fill[_ngcontent-%COMP%]{display:block;height:100%;border-radius:999px}.prompt-model[_ngcontent-%COMP%]{font-size:10.5px;text-align:right}.prompt-toks[_ngcontent-%COMP%], .cache-cell[_ngcontent-%COMP%]{font-size:11px;text-align:right}.cost-cell[_ngcontent-%COMP%]{font-size:13px;font-weight:600;text-align:right}.skel[_ngcontent-%COMP%]{background:var(--bg-elevated);border-radius:5px;animation:_ngcontent-%COMP%_skeleton 1.4s ease-in-out infinite}.row-skel[_ngcontent-%COMP%]{height:30px;margin:6px 0}@keyframes _ngcontent-%COMP%_skeleton{0%,to{opacity:.5}50%{opacity:.9}}"],changeDetection:0})};export{se as Costs};
@@ -1 +0,0 @@
1
- import{a as $}from"./chunk-SBWU7JFC.js";import{a as me,b as F}from"./chunk-4N5DWG46.js";import{b as se,c as B,d as de,e as pe,f as ce}from"./chunk-SHPTC4RL.js";import{a as j}from"./chunk-7RNS77UP.js";import{a as A}from"./chunk-E44X4RH2.js";import{$ as ne,Aa as p,Ba as d,Ca as c,Da as C,Ga as k,Ha as J,I as v,Ia as h,Ja as R,Ka as m,M as y,N as P,O as Q,R as ee,Ta as oe,Ua as M,V as te,Va as l,W as T,Wa as b,Xa as X,Ya as ae,ca as ie,cb as re,da as Y,ea as o,ka as x,lb as I,ob as N,pb as S,qa as w,ra as g,sa as u,va as O,wa as E,wb as le,xa as f,ya as a,za as r,zb as D}from"./chunk-PDN6QYGJ.js";import"./chunk-Q7L6LLAK.js";var ge=[{path:"",pathMatch:"full",redirectTo:"dashboard"},{path:"dashboard",loadComponent:()=>import("./chunk-2OKMB4KX.js").then(e=>e.Dashboard),data:{nav:"dashboard",title:"Dashboard"}},{path:"graph",loadComponent:()=>import("./chunk-JFYVCXK3.js").then(e=>e.Graph),data:{nav:"graph",title:"Graph"}},{path:"specs",loadComponent:()=>import("./chunk-JT7P3DEK.js").then(e=>e.Specs),data:{nav:"specs",title:"Specs"}},{path:"drift",loadComponent:()=>import("./chunk-3SEJX2BK.js").then(e=>e.Drift),data:{nav:"drift",title:"Drift queue"}},{path:"workflows",loadComponent:()=>import("./chunk-YAWCRPHV.js").then(e=>e.Workflows),data:{nav:"workflows",title:"Workflows"}},{path:"runs",loadComponent:()=>import("./chunk-BCZM5AXU.js").then(e=>e.Runs),data:{nav:"runs",title:"Runs"}},{path:"runs/:id",loadComponent:()=>import("./chunk-MVOMVPYB.js").then(e=>e.RunDetail),data:{nav:"runs",title:"Run detail"}},{path:"chat",loadComponent:()=>import("./chunk-L37MTFSG.js").then(e=>e.Chat),data:{nav:"chat",title:"Chat"}},{path:"sessions",loadComponent:()=>import("./chunk-2DHIGIOI.js").then(e=>e.Sessions),data:{nav:"sessions",title:"Sessions"}},{path:"sessions/:id",loadComponent:()=>import("./chunk-DA6SNNAF.js").then(e=>e.SessionDetail),data:{nav:"sessions",title:"Session detail"}},{path:"heatmap",loadComponent:()=>import("./chunk-LV4G6QFG.js").then(e=>e.Heatmap),data:{nav:"heatmap",title:"Heatmap"}},{path:"costs",loadComponent:()=>import("./chunk-TWXZK6XM.js").then(e=>e.Costs),data:{nav:"costs",title:"Costs"}},{path:"compare",loadComponent:()=>import("./chunk-BPECIDVO.js").then(e=>e.Compare),data:{nav:"compare",title:"Compare projects"}},{path:"tips",loadComponent:()=>import("./chunk-RAAMPHPJ.js").then(e=>e.Tips),data:{nav:"tips",title:"Tips"}},{path:"memory",loadComponent:()=>import("./chunk-JN6W7HCN.js").then(e=>e.Memory),data:{nav:"memory",title:"Memory"}},{path:"design",loadComponent:()=>import("./chunk-WAI2JMZP.js").then(e=>e.Design),data:{nav:"design",title:"Design system"}},{path:"settings",loadComponent:()=>import("./chunk-BYZFQSM6.js").then(e=>e.Settings),data:{nav:"settings",title:"Settings"}},{path:"**",redirectTo:"dashboard"}];var ue={providers:[te(),ce(ge)]};function fe(e,n){e&1&&(Q(),C(0,"rect",14)(1,"rect",15))}var V=class e{size=S(24);tile=S(!0);glow=S(!0);static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-logo-mark"]],inputs:{size:[1,"size"],tile:[1,"tile"],glow:[1,"glow"]},decls:16,vars:5,consts:[["viewBox","0 0 32 32","fill","none",2,"flex-shrink","0"],["id","ssTile","x1","0","y1","0","x2","32","y2","32","gradientUnits","userSpaceOnUse"],["stop-color","#12161E"],["offset","1","stop-color","#0B0D11"],["id","ssLead","x1","18","y1","11","x2","26","y2","21","gradientUnits","userSpaceOnUse"],["stop-color","#6FA0F6"],["offset","1","stop-color","#5B93F2"],["transform","translate(4.6 4.6) scale(0.715)"],["d","M5 16 H11 M11 9 L23 16 L11 23","stroke","rgba(150,165,200,0.5)","stroke-width","1.9","stroke-linecap","round","stroke-linejoin","round","fill","none"],["x1","11","y1","9","x2","11","y2","23","stroke","rgba(150,165,200,0.4)","stroke-width","1.9","stroke-linecap","round"],["cx","23","cy","16","r","3.6","fill","url(#ssLead)"],["cx","11","cy","9","r","2.9","fill","#A586F5"],["cx","11","cy","23","r","2.9","fill","#46C26B"],["cx","5","cy","16","r","2.1","fill","#29D2BE"],["width","32","height","32","rx","7.2","fill","url(#ssTile)"],["x","0.5","y","0.5","width","31","height","31","rx","6.7","fill","none","stroke","rgba(255,255,255,0.08)"]],template:function(t,i){t&1&&(Q(),d(0,"svg",0)(1,"defs")(2,"linearGradient",1),C(3,"stop",2)(4,"stop",3),c(),d(5,"linearGradient",4),C(6,"stop",5)(7,"stop",6),c()(),g(8,fe,2,0),d(9,"g",7),C(10,"path",8)(11,"line",9)(12,"circle",10)(13,"circle",11)(14,"circle",12)(15,"circle",13),c()()),t&2&&(oe("filter",i.glow()?"drop-shadow(0 0 9px rgba(91,147,242,0.35))":"none"),w("width",i.size())("height",i.size()),o(8),u(i.tile()?8:-1))},styles:["[_nghost-%COMP%]{display:inline-flex;align-items:center;justify-content:center;line-height:0}"],changeDetection:0})};var be=e=>["/",e],ve=(e,n)=>n.group,_e=(e,n)=>n.id;function xe(e,n){e&1&&(a(0,"div",3),l(1,"SpecShip "),a(2,"span",14),l(3,"Desktop"),r()())}function he(e,n){if(e&1&&(a(0,"div",15),l(1),r()),e&2){let t=m().$implicit;o(),b(t.group)}}function Ce(e,n){if(e&1&&(a(0,"span",18),l(1),r()),e&2){let t=m(2).$implicit,i=m(2);w("data-kind",t.badgeKind),o(),b(i.badgeOf(t))}}function ye(e,n){if(e&1&&(a(0,"span",11),l(1),r(),g(2,Ce,2,2,"span",18)),e&2){let t=m().$implicit,i=m(2);o(),b(t.label),o(),u(i.badgeOf(t)>0?2:-1)}}function Pe(e,n){if(e&1&&(a(0,"a",16),p(1,"span",8),a(2,"span",9),p(3,"app-icon",17),r(),g(4,ye,3,2),r()),e&2){let t=n.$implicit,i=m(2);f("routerLink",re(5,be,t.id))("title",i.collapsed()?t.label:null),o(3),f("name",t.icon)("size",16),o(),u(i.collapsed()?-1:4)}}function ke(e,n){if(e&1&&(a(0,"div",5),g(1,he,2,1,"div",15),O(2,Pe,5,7,"a",16,_e),r()),e&2){let t=n.$implicit,i=m();o(),u(i.collapsed()?-1:1),o(),E(t.items)}}function we(e,n){e&1&&(a(0,"span",11),l(1,"Design system"),r())}function Me(e,n){e&1&&(a(0,"span",11),l(1,"Settings"),r())}var H=class e{collapsed=S(!1);api=v(A);projects=v(j);status=F(this.api,()=>`/api/status${this.projects.projectQuery()}`);tips=F(this.api,()=>"/api/claude/tips");nav=[{group:"Project",items:[{id:"dashboard",label:"Dashboard",icon:"dashboard"},{id:"graph",label:"Graph",icon:"graph"},{id:"specs",label:"Specs",icon:"book"},{id:"drift",label:"Drift queue",icon:"drift",badge:()=>this.status.state().data?.drift??0,badgeKind:"warn"},{id:"workflows",label:"Workflows",icon:"workflow"},{id:"runs",label:"Runs",icon:"play"},{id:"chat",label:"Chat",icon:"chat"}]},{group:"Claude Code",items:[{id:"sessions",label:"Sessions",icon:"sessions"},{id:"heatmap",label:"Heatmap",icon:"heatmap"},{id:"costs",label:"Costs",icon:"dollar"},{id:"compare",label:"Compare projects",icon:"compare"},{id:"memory",label:"Memory",icon:"memory"},{id:"tips",label:"Tips",icon:"tips",badge:()=>(this.tips.state().data?.tips??[]).filter(n=>n.severity!=="info").length,badgeKind:"error"}]}];badgeOf(n){return n.badge?n.badge():0}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-sidebar"]],inputs:{collapsed:[1,"collapsed"]},decls:18,vars:10,consts:[[1,"sidebar"],[1,"brand"],[3,"size"],[1,"brand-text"],[1,"scroll-y","nav-scroll"],[1,"nav-group"],[1,"pinned"],["routerLink","/design","routerLinkActive","active",1,"nav-item",3,"title"],[1,"indicator"],[1,"nav-icon"],["name","palette",3,"size"],[1,"nav-label"],["routerLink","/settings","routerLinkActive","active",1,"nav-item",3,"title"],["name","settings",3,"size"],[1,"muted"],[1,"eyebrow","group-label"],["routerLinkActive","active",1,"nav-item",3,"routerLink","title"],[3,"name","size"],[1,"badge"]],template:function(t,i){t&1&&(a(0,"nav",0)(1,"div",1),p(2,"app-logo-mark",2),g(3,xe,4,0,"div",3),r(),a(4,"div",4),O(5,ke,4,1,"div",5,ve),r(),a(7,"div",6)(8,"a",7),p(9,"span",8),a(10,"span",9),p(11,"app-icon",10),r(),g(12,we,2,0,"span",11),r(),a(13,"a",12),p(14,"span",8),a(15,"span",9),p(16,"app-icon",13),r(),g(17,Me,2,0,"span",11),r()()()),t&2&&(M("collapsed",i.collapsed()),o(2),f("size",26),o(),u(i.collapsed()?-1:3),o(2),E(i.nav),o(3),f("title",i.collapsed()?"Design system":null),o(3),f("size",16),o(),u(i.collapsed()?-1:12),o(),f("title",i.collapsed()?"Settings":null),o(3),f("size",16),o(),u(i.collapsed()?-1:17))},dependencies:[de,pe,D,V],styles:['@charset "UTF-8";[_nghost-%COMP%]{display:contents}.sidebar[_ngcontent-%COMP%]{width:var(--sidebar-w);flex-shrink:0;background:var(--bg-panel);border-right:1px solid var(--border-subtle);display:flex;flex-direction:column;transition:width .12s;overflow:hidden;font-family:var(--font-ui)}.sidebar.collapsed[_ngcontent-%COMP%]{width:var(--sidebar-w-collapsed)}.brand[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;padding:15px 16px}.collapsed[_ngcontent-%COMP%] .brand[_ngcontent-%COMP%]{justify-content:center;padding:14px 0}.brand-text[_ngcontent-%COMP%]{font-weight:600;font-size:13.5px;letter-spacing:-.01em}.brand-text[_ngcontent-%COMP%] .muted[_ngcontent-%COMP%]{color:var(--text-muted);font-weight:400}.nav-scroll[_ngcontent-%COMP%]{flex:1;padding:4px 8px}.nav-group[_ngcontent-%COMP%]{margin-bottom:10px}.group-label[_ngcontent-%COMP%]{padding:8px 8px 4px}.nav-item[_ngcontent-%COMP%]{position:relative;display:flex;align-items:center;gap:10px;height:32px;padding:0 10px;border-radius:7px;text-decoration:none;margin-bottom:1px;color:var(--text-secondary);font-weight:450;font-size:13px;transition:background .1s}.collapsed[_ngcontent-%COMP%] .nav-item[_ngcontent-%COMP%]{padding:0;justify-content:center}.nav-item[_ngcontent-%COMP%]:hover{background:var(--bg-hover);color:var(--text-primary)}.nav-item.active[_ngcontent-%COMP%]{background:var(--bg-active);color:var(--text-primary);font-weight:600}.nav-item.active[_ngcontent-%COMP%] .indicator[_ngcontent-%COMP%]{position:absolute;left:0;top:7px;bottom:7px;width:2.5px;border-radius:2px;background:var(--accent)}.nav-icon[_ngcontent-%COMP%]{width:16px;height:16px;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;color:var(--text-secondary)}.nav-item[_ngcontent-%COMP%]:hover .nav-icon[_ngcontent-%COMP%]{color:var(--text-primary)}.nav-item.active[_ngcontent-%COMP%] .nav-icon[_ngcontent-%COMP%]{color:var(--accent)}.nav-label[_ngcontent-%COMP%]{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.badge[_ngcontent-%COMP%]{font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-size:10px;font-weight:700;padding:1px 6px;min-width:18px;border-radius:999px;display:inline-flex;justify-content:center;color:var(--text-secondary);background:#ffffff0f}.badge[data-kind=error][_ngcontent-%COMP%]{color:var(--error);background:var(--error-soft)}.badge[data-kind=warn][_ngcontent-%COMP%]{color:var(--warn);background:var(--warn-soft)}.pinned[_ngcontent-%COMP%]{padding:8px;border-top:1px solid var(--border-subtle)}'],changeDetection:0})};function Se(e,n){e&1&&(d(0,"span",8),l(1,"\u26A0"),c()),e&2&&J("title",n)}function Oe(e,n){if(e&1){let t=k();d(0,"span",2),l(1),c(),C(2,"span",3),d(3,"span",4)(4,"span",5),l(5,"backend"),c(),d(6,"span",6),l(7),c()(),C(8,"span",3),d(9,"span",4)(10,"span",5),l(11,"nodes"),c(),d(12,"span",6),l(13),c()(),d(14,"span",4)(15,"span",5),l(16,"edges"),c(),d(17,"span",6),l(18),c()(),C(19,"span",3),d(20,"span",4)(21,"span",5),l(22,"drift"),c(),d(23,"span",6),l(24),c()(),C(25,"span",7),d(26,"span",4)(27,"span",5),l(28,"indexed"),c(),d(29,"span",6),l(30),c()(),g(31,Se,2,1,"span",8),d(32,"button",9),R("click",function(){y(t);let s=m();return P(s.refresh())}),l(33,"\u21BB"),c()}if(e&2){let t,i=m(),s=i.status.state().data;o(),b(s.projectPath),o(6),b(s.backend),o(6),b(s.nodeCount.toLocaleString()),o(5),b(s.edgeCount.toLocaleString()),o(5),M("warn",s.drift>0)("success",s.drift===0),o(),b(s.drift),o(6),b(i.indexedLabel()),o(),u((t=i.refreshSvc.error())?31:-1,t),o(),M("spinning",i.refreshSvc.loading()),J("disabled",i.refreshSvc.loading())("title",i.refreshSvc.loading()?"Refreshing\u2026":"Refresh: sync index + re-ingest Claude Code transcripts. Updates Sessions, Heatmap, Costs, Memory, Drift, Graph."),w("aria-label",i.refreshSvc.loading()?"Refreshing\u2026":"Refresh everything \u2014 sync index + ingest Claude Code transcripts")}}function Ee(e,n){e&1&&(d(0,"span",1),l(1,"loading status\u2026"),c())}function Te(e,n){e&1&&(d(0,"span",1),l(1,"no backend"),c())}var G=class e{api=v(A);projects=v(j);refreshSvc=v(me);status=F(this.api,()=>`/api/status${this.projects.projectQuery()}`);indexedLabel=I(()=>{let n=this.status.state().data?.lastIndexed;if(!n)return"never";try{let t=new Date(n),i=Date.now()-t.getTime();return i<6e4?"just now":i<36e5?`${Math.round(i/6e4)}m ago`:i<864e5?`${Math.round(i/36e5)}h ago`:t.toLocaleDateString()}catch{return String(n)}});async refresh(){await this.refreshSvc.triggerGlobalRefresh()}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-status-strip"]],decls:4,vars:1,consts:[[1,"status-strip"],[1,"mono","muted"],[1,"seg","mono"],[1,"divider"],[1,"seg"],[1,"lbl"],[1,"mono","val"],[1,"grow"],[1,"refresh-error","mono",3,"title"],[1,"refresh",3,"click","disabled","title"]],template:function(t,i){t&1&&(d(0,"div",0),g(1,Oe,34,16)(2,Ee,2,0,"span",1)(3,Te,2,0,"span",1),c()),t&2&&(o(),u(i.status.state().data?1:i.status.state().loading?2:3))},styles:["[_nghost-%COMP%]{display:contents}.status-strip[_ngcontent-%COMP%]{height:var(--status-h);flex-shrink:0;display:flex;align-items:center;gap:14px;padding:0 14px;border-bottom:1px solid var(--border-subtle);background:var(--bg-panel-2);font-size:11.5px;overflow:hidden;white-space:nowrap}.seg[_ngcontent-%COMP%]{display:flex;align-items:center;gap:6px;flex-shrink:0}.lbl[_ngcontent-%COMP%]{color:var(--text-muted);font-size:11px}.val[_ngcontent-%COMP%]{color:var(--text-secondary);font-variant-numeric:tabular-nums}.val.warn[_ngcontent-%COMP%]{color:var(--warn)}.val.success[_ngcontent-%COMP%]{color:var(--success)}.divider[_ngcontent-%COMP%]{width:1px;height:12px;background:var(--border-subtle);flex-shrink:0}.grow[_ngcontent-%COMP%]{flex:1}.muted[_ngcontent-%COMP%]{color:var(--text-muted)}.refresh[_ngcontent-%COMP%]{background:transparent;border:none;color:var(--text-muted);cursor:pointer;font-size:14px;padding:2px 6px;border-radius:4px;transition:background .12s,color .12s}.refresh[_ngcontent-%COMP%]:hover:not(:disabled){background:var(--bg-hover);color:var(--text-primary)}.refresh[_ngcontent-%COMP%]:disabled{cursor:progress;opacity:.8}.refresh[_ngcontent-%COMP%]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.refresh.spinning[_ngcontent-%COMP%]{display:inline-block;animation:_ngcontent-%COMP%_spin .9s linear infinite;color:var(--accent)}@keyframes _ngcontent-%COMP%_spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.refresh-error[_ngcontent-%COMP%]{color:var(--warn);font-size:12px;padding:0 2px;cursor:help}"],changeDetection:0})};var je=(e,n)=>n.slug;function De(e,n){e&1&&p(0,"span",8)}function ze(e,n){e&1&&p(0,"span",9)}function Le(e,n){e&1&&p(0,"span",10)}function Re(e,n){if(e&1&&(a(0,"span",7),l(1),r(),g(2,De,1,0,"span",8)(3,ze,1,0,"span",9)(4,Le,1,0,"span",10)),e&2){let t=n,i=m();o(),b(i.shortPath(t.path)),o(),u(t.exists?t.initialized?4:3:2)}}function Ie(e,n){e&1&&(a(0,"span",3),l(1,"Select project"),r())}function Ne(e,n){if(e&1){let t=k();a(0,"button",20),h("click",function(){y(t);let s=m(2);return P(s.clear())}),p(1,"app-icon",21),l(2," Clear "),r()}e&2&&(o(),f("size",11))}function Fe(e,n){e&1&&(a(0,"span",16),l(1,"\xB7 loading\u2026"),r())}function Be(e,n){if(e&1&&(a(0,"span",16),l(1),r()),e&2){let t=m(2);o(),X("\xB7 ",t.filtered().length," shown \xB7 live")}}function Ae(e,n){e&1&&(a(0,"div",18),l(1,"No projects match."),r())}function $e(e,n){e&1&&(a(0,"span",25),l(1,"missing"),r())}function Ve(e,n){e&1&&(a(0,"span",26),l(1,"not init"),r())}function He(e,n){e&1&&(a(0,"span",27),l(1,"initialized"),r())}function Ge(e,n){if(e&1&&(a(0,"span"),l(1),r()),e&2){let t=m().$implicit,i=m(2);o(),X("\xB7 ",i.formatRelative(t.lastModifiedMs))}}function qe(e,n){e&1&&p(0,"app-icon",29),e&2&&f("size",13)}function Ke(e,n){if(e&1){let t=k();a(0,"button",22),h("click",function(){let s=y(t).$implicit,_=m(2);return P(_.pick(s.slug))}),a(1,"div",23)(2,"div",24)(3,"span",7),l(4),r(),g(5,$e,2,0,"span",25)(6,Ve,2,0,"span",26)(7,He,2,0,"span",27),r(),a(8,"div",28)(9,"span"),l(10),r(),g(11,Ge,2,1,"span"),r()(),g(12,qe,1,1,"app-icon",29),r()}if(e&2){let t=n.$implicit,i=m(2);M("active",i.projects.activeSlug()===t.slug),o(4),b(i.shortPath(t.path)),o(),u(t.exists?t.initialized?7:6:5),o(5),ae("",t.sessionCount," session",t.sessionCount===1?"":"s"),o(),u(t.lastModifiedMs>0?11:-1),o(),u(i.projects.activeSlug()===t.slug?12:-1)}}function We(e,n){if(e&1){let t=k();a(0,"div",6)(1,"div",11),p(2,"app-icon",12),a(3,"input",13),h("input",function(s){y(t);let _=m();return P(_.onQuery(s.target.value))}),r(),g(4,Ne,3,1,"button",14),r(),a(5,"div",15)(6,"span"),l(7),r(),g(8,Fe,2,0,"span",16)(9,Be,2,1,"span",16),r(),a(10,"div",17),g(11,Ae,2,0,"div",18),O(12,Ke,13,8,"button",19,je),r()()}if(e&2){let t=m();o(2),f("size",13),o(),f("value",t.query()),o(),u(t.projects.activeSlug()?4:-1),o(3),b(t.projects.claudeRoot()??"~/.claude/projects"),o(),u(t.projects.loading()?8:9),o(3),u(t.filtered().length===0&&!t.projects.loading()?11:-1),o(),E(t.filtered())}}var q=class e{host=v(ne);projects=v(j);open=T(!1);query=T("");filtered=I(()=>{let n=this.query().trim().toLowerCase(),t=this.projects.projects();return n?t.filter(i=>i.path.toLowerCase().includes(n)||i.slug.toLowerCase().includes(n)):t});badge=I(()=>this.projects.projects().length);toggle(){this.open.update(n=>!n)}pick(n){this.projects.setActive(n),this.open.set(!1),this.query.set("")}clear(){this.projects.setActive(null),this.open.set(!1)}onQuery(n){this.query.set(n)}onDocumentClick(n){if(!this.open())return;let t=n.target;t&&!this.host.nativeElement.contains(t)&&this.open.set(!1)}onEscape(){this.open()&&this.open.set(!1)}formatRelative(n){if(!n)return"";let t=Date.now()-n,i=Math.round(t/1e3);if(i<60)return`${i}s ago`;let s=Math.round(i/60);if(s<60)return`${s}m ago`;let _=Math.round(s/60);if(_<24)return`${_}h ago`;let Z=Math.round(_/24);return Z<30?`${Z}d ago`:new Date(n).toLocaleDateString()}shortPath(n){if(!n)return"";let t=this.detectHome();return t&&n===t?"~":t&&n.startsWith(t+"/")?"~/"+n.slice(t.length+1):n}detectHome(){let n=this.projects.claudeRoot();if(!n)return null;let t="/.claude/projects";return n.endsWith(t)?n.slice(0,-t.length):null}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-project-picker"]],hostBindings:function(t,i){t&1&&h("click",function(_){return i.onDocumentClick(_)},Y)("keydown.escape",function(){return i.onEscape()},Y)},decls:9,vars:9,consts:[[1,"wrap"],["type","button","aria-label","Switch project",1,"trigger",3,"click"],["name","folder",3,"size"],[1,"placeholder"],[1,"badge","mono"],[3,"name","size"],["role","dialog","aria-label","Pick a project",1,"popover"],[1,"path","mono"],["title","path no longer exists on disk",1,"status-dot","missing"],["title","not yet specship init'd",1,"status-dot","warn"],["title","initialized",1,"status-dot","ok"],[1,"popover-head","row","gap-8"],["name","search",3,"size"],["type","text","placeholder","Filter projects\u2026","autofocus","",1,"popover-input",3,"input","value"],["title","Clear selection",1,"btn","btn-ghost","btn-xs"],[1,"popover-meta","mono"],[1,"muted"],[1,"popover-list","scroll-y"],[1,"empty"],["type","button",1,"row-item",3,"active"],["title","Clear selection",1,"btn","btn-ghost","btn-xs",3,"click"],["name","x",3,"size"],["type","button",1,"row-item",3,"click"],[1,"col","gap-2","grow"],[1,"row","gap-6","path-line"],[1,"pill","missing"],[1,"pill","warn"],[1,"pill","ok"],[1,"meta","row","gap-8","mono","muted"],["name","check",3,"size"]],template:function(t,i){if(t&1&&(a(0,"div",0)(1,"button",1),h("click",function(){return i.toggle()}),p(2,"app-icon",2),g(3,Re,5,2)(4,Ie,2,0,"span",3),a(5,"span",4),l(6),r(),p(7,"app-icon",5),r(),g(8,We,14,6,"div",6),r()),t&2){let s;M("open",i.open()),o(),w("aria-expanded",i.open()),o(),f("size",13),o(),u((s=i.projects.active())?3:4,s),o(3),b(i.badge()),o(),f("name",i.open()?"chevronDown":"chevronRight")("size",11),o(),u(i.open()?8:-1)}},dependencies:[D],styles:["[_nghost-%COMP%]{display:inline-flex;min-width:0}.wrap[_ngcontent-%COMP%]{position:relative;min-width:0}.trigger[_ngcontent-%COMP%]{height:30px;padding:0 11px 0 10px;background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:8px;color:var(--text-secondary);display:inline-flex;align-items:center;gap:8px;font-family:var(--font-ui);font-size:12.5px;cursor:pointer;max-width:360px;min-width:0;transition:background .1s,border-color .1s}.trigger[_ngcontent-%COMP%]:hover, .wrap.open[_ngcontent-%COMP%] .trigger[_ngcontent-%COMP%]{background:var(--bg-panel-2);border-color:var(--border-strong);color:var(--text-primary)}.trigger[_ngcontent-%COMP%] app-icon[_ngcontent-%COMP%]{color:var(--text-muted);flex-shrink:0}.trigger[_ngcontent-%COMP%]:hover app-icon[_ngcontent-%COMP%]{color:var(--text-secondary)}.path[_ngcontent-%COMP%]{font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.placeholder[_ngcontent-%COMP%]{color:var(--text-muted);font-style:italic}.status-dot[_ngcontent-%COMP%]{width:6px;height:6px;border-radius:50%;flex-shrink:0}.status-dot.ok[_ngcontent-%COMP%]{background:var(--success)}.status-dot.warn[_ngcontent-%COMP%]{background:var(--warn)}.status-dot.missing[_ngcontent-%COMP%]{background:var(--error)}.badge[_ngcontent-%COMP%]{font-size:10px;padding:1px 6px;border-radius:999px;background:var(--bg-active);color:var(--text-muted);font-variant-numeric:tabular-nums;flex-shrink:0}.popover[_ngcontent-%COMP%]{position:absolute;top:calc(100% + 6px);left:0;z-index:30;width:420px;max-width:calc(100vw - 40px);background:var(--bg-elevated);border:1px solid var(--border-strong);border-radius:10px;box-shadow:var(--shadow-pop);display:flex;flex-direction:column;max-height:480px;animation:_ngcontent-%COMP%_pp-in .12s ease-out}@keyframes _ngcontent-%COMP%_pp-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.popover-head[_ngcontent-%COMP%]{padding:10px 12px 8px;border-bottom:1px solid var(--border-subtle)}.popover-head[_ngcontent-%COMP%] app-icon[_ngcontent-%COMP%]{color:var(--text-muted);flex-shrink:0}.popover-input[_ngcontent-%COMP%]{flex:1;min-width:0;background:transparent;border:none;outline:none;font-family:var(--font-ui);font-size:13px;color:var(--text-primary)}.popover-input[_ngcontent-%COMP%]::placeholder{color:var(--text-muted)}.popover-meta[_ngcontent-%COMP%]{padding:6px 12px 8px;font-size:10.5px;color:var(--text-secondary);border-bottom:1px solid var(--border-subtle);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.popover-meta[_ngcontent-%COMP%] .muted[_ngcontent-%COMP%]{color:var(--text-muted)}.popover-list[_ngcontent-%COMP%]{flex:1;min-height:0;padding:4px}.row-item[_ngcontent-%COMP%]{width:100%;display:flex;align-items:center;gap:10px;padding:9px 10px;border:none;border-radius:7px;background:transparent;color:inherit;cursor:pointer;font-family:inherit;text-align:left;transition:background 80ms}.row-item[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.row-item.active[_ngcontent-%COMP%]{background:var(--accent-soft);color:var(--text-primary)}.row-item.active[_ngcontent-%COMP%] app-icon[_ngcontent-%COMP%]{color:var(--accent)}.path-line[_ngcontent-%COMP%]{min-width:0}.path-line[_ngcontent-%COMP%] .path[_ngcontent-%COMP%]{font-size:12.5px;font-weight:500;color:var(--text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.meta[_ngcontent-%COMP%]{font-size:10.5px}.pill[_ngcontent-%COMP%]{font-size:10px;font-weight:600;padding:1px 7px;border-radius:999px;white-space:nowrap;flex-shrink:0}.pill.ok[_ngcontent-%COMP%]{color:var(--success);background:var(--success-soft)}.pill.warn[_ngcontent-%COMP%]{color:var(--warn);background:var(--warn-soft)}.pill.missing[_ngcontent-%COMP%]{color:var(--error);background:var(--error-soft)}.empty[_ngcontent-%COMP%]{text-align:center;color:var(--text-muted);font-size:12px;padding:18px 12px}.muted[_ngcontent-%COMP%]{color:var(--text-muted)}.mono[_ngcontent-%COMP%]{font-family:var(--font-mono)}.grow[_ngcontent-%COMP%]{flex:1;min-width:0}.row[_ngcontent-%COMP%]{display:flex;align-items:center}.col[_ngcontent-%COMP%]{display:flex;flex-direction:column}.gap-2[_ngcontent-%COMP%]{gap:2px}.gap-6[_ngcontent-%COMP%]{gap:6px}.gap-8[_ngcontent-%COMP%]{gap:8px}.scroll-y[_ngcontent-%COMP%]{overflow-y:auto;overflow-x:hidden}"],changeDetection:0})};var K=class e{toggleSidebar=N();openPalette=N();theme=v($);effective=this.theme.effective;onToggleTheme(){this.theme.toggle()}onMenuClick(){this.toggleSidebar.emit()}onPalette(){this.openPalette.emit()}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-top-bar"]],outputs:{toggleSidebar:"toggleSidebar",openPalette:"openPalette"},decls:13,vars:5,consts:[[1,"topbar"],["title","Toggle sidebar","aria-label","Toggle sidebar",1,"ghost","icon-btn",3,"click"],["name","menu",3,"size"],["aria-label","Open command palette",1,"palette-trigger",3,"click"],["name","search",3,"size"],[1,"grow"],["aria-label","Toggle theme",1,"ghost","icon-btn",3,"click","title"],[3,"name","size"]],template:function(t,i){t&1&&(a(0,"div",0)(1,"button",1),h("click",function(){return i.onMenuClick()}),p(2,"app-icon",2),r(),p(3,"app-project-picker"),a(4,"button",3),h("click",function(){return i.onPalette()}),p(5,"app-icon",4),a(6,"span"),l(7,"Search or jump to\u2026"),r(),a(8,"kbd"),l(9,"\u2318K"),r()(),p(10,"span",5),a(11,"button",6),h("click",function(){return i.onToggleTheme()}),p(12,"app-icon",7),r()()),t&2&&(o(2),f("size",16),o(3),f("size",13),o(6),f("title","Theme: "+i.effective()),o(),f("name",i.effective()==="dark"?"sun":"moon")("size",16))},dependencies:[D,q],styles:["[_nghost-%COMP%]{display:contents}.topbar[_ngcontent-%COMP%]{height:44px;flex-shrink:0;display:flex;align-items:center;gap:10px;padding:0 14px;border-bottom:1px solid var(--border-subtle);background:var(--bg-canvas)}.ghost[_ngcontent-%COMP%]{background:transparent;border:1px solid transparent;color:var(--text-secondary);cursor:pointer}.ghost[_ngcontent-%COMP%]:hover{background:var(--bg-hover);color:var(--text-primary)}.icon-btn[_ngcontent-%COMP%]{padding:6px 9px;border-radius:5px;font-size:16px}.palette-trigger[_ngcontent-%COMP%]{flex:1;max-width:380px;height:30px;padding:0 11px;background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:8px;cursor:text;color:var(--text-muted);font-size:12.5px;text-align:left;display:flex;align-items:center;gap:8px}.palette-trigger[_ngcontent-%COMP%]:hover{border-color:var(--border-strong);color:var(--text-secondary)}.palette-trigger[_ngcontent-%COMP%] app-icon[_ngcontent-%COMP%]{color:var(--text-muted)}.palette-trigger[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{flex:1}kbd[_ngcontent-%COMP%]{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:4px;padding:2px 6px}.grow[_ngcontent-%COMP%]{flex:1}"],changeDetection:0})};var Ue=(e,n)=>n.id;function Qe(e,n){if(e&1){let t=k();d(0,"button",6),R("click",function(){let s=y(t).$implicit,_=m(2);return P(_.go(s.id))}),d(1,"span",7),l(2),c(),d(3,"span",8),l(4),c()()}if(e&2){let t=n.$implicit;o(2),b(t.label),o(2),b(t.sub)}}function Ye(e,n){if(e&1){let t=k();d(0,"div",1),R("click",function(s){y(t);let _=m();return P(_.onBackdrop(s))}),d(1,"div",2)(2,"div",3)(3,"span"),l(4,"Jump to\u2026"),c(),d(5,"kbd"),l(6,"esc"),c()(),d(7,"div",4),O(8,Qe,5,2,"button",5,Ue),c()()()}if(e&2){let t=m();o(8),E(t.items)}}var Je=[{id:"dashboard",label:"Dashboard",sub:"/dashboard"},{id:"graph",label:"Graph",sub:"/graph"},{id:"specs",label:"Specs",sub:"/specs"},{id:"drift",label:"Drift queue",sub:"/drift"},{id:"workflows",label:"Workflows",sub:"/workflows"},{id:"runs",label:"Runs",sub:"/runs"},{id:"chat",label:"Chat",sub:"/chat"},{id:"sessions",label:"Sessions",sub:"/sessions"},{id:"heatmap",label:"Heatmap",sub:"/heatmap"},{id:"costs",label:"Costs",sub:"/costs"},{id:"compare",label:"Compare projects",sub:"/compare"},{id:"tips",label:"Tips",sub:"/tips"},{id:"settings",label:"Settings",sub:"/settings"}],W=class e{open=S(!1);close=N();router=v(B);items=Je;go(n){this.router.navigate(["/"+n]),this.close.emit()}onBackdrop(n){n.target===n.currentTarget&&this.close.emit()}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-command-palette"]],inputs:{open:[1,"open"]},outputs:{close:"close"},decls:1,vars:1,consts:[[1,"backdrop"],[1,"backdrop",3,"click"],[1,"palette"],[1,"palette-header"],[1,"palette-list","scroll-y"],[1,"item"],[1,"item",3,"click"],[1,"label"],[1,"sub","mono"]],template:function(t,i){t&1&&g(0,Ye,10,0,"div",0),t&2&&u(i.open()?0:-1)},styles:["[_nghost-%COMP%]{display:contents}.backdrop[_ngcontent-%COMP%]{position:fixed;inset:0;background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);display:grid;place-items:start center;padding-top:12vh;z-index:100;animation:fadeIn .1s}.palette[_ngcontent-%COMP%]{width:560px;max-width:90vw;background:var(--bg-elevated);border:1px solid var(--border-strong);border-radius:12px;box-shadow:var(--shadow-pop);overflow:hidden}.palette-header[_ngcontent-%COMP%]{display:flex;justify-content:space-between;align-items:center;padding:12px 14px;border-bottom:1px solid var(--border-subtle);font-size:13px}.palette-list[_ngcontent-%COMP%]{max-height:380px;padding:6px}.item[_ngcontent-%COMP%]{display:flex;justify-content:space-between;align-items:center;width:100%;padding:8px 10px;background:transparent;border:none;border-radius:7px;cursor:pointer;color:var(--text-primary);font-family:inherit;font-size:13px;text-align:left}.item[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.label[_ngcontent-%COMP%]{flex:1}.sub[_ngcontent-%COMP%]{font-size:10.5px;color:var(--text-muted)}kbd[_ngcontent-%COMP%]{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:4px;padding:2px 6px}"],changeDetection:0})};var U=class e{_theme=v($);_destroyRef=v(ee);_router=v(B);sidebarCollapsed=T(typeof window<"u"&&window.innerWidth<1100);paletteOpen=T(!1);gChord={armed:!1,t:0};onGlobalKey(n){let t=n.metaKey||n.ctrlKey;if(t&&n.key.toLowerCase()==="k"){n.preventDefault(),this.paletteOpen.update(i=>!i);return}if(n.key==="Escape"){this.paletteOpen.set(!1);return}if(!t&&n.key.toLowerCase()==="g"&&!this.gChord.armed){let i=n.target;if(i&&/input|textarea/i.test(i.tagName))return;this.gChord.armed=!0,this.gChord.t=Date.now(),setTimeout(()=>{this.gChord.armed=!1},600);return}if(this.gChord.armed&&!t){let i=n.key.toLowerCase();i==="d"?this._router.navigate(["/dashboard"]):i==="g"?this._router.navigate(["/graph"]):i==="s"&&this._router.navigate(["/specs"]),this.gChord.armed=!1}}toggleSidebar(){this.sidebarCollapsed.update(n=>!n)}onOpenPalette(){this.paletteOpen.set(!0)}onClosePalette(){this.paletteOpen.set(!1)}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-root"]],hostBindings:function(t,i){t&1&&h("keydown",function(_){return i.onGlobalKey(_)},ie)},decls:8,vars:2,consts:[[1,"shell"],[3,"collapsed"],[1,"main"],[3,"toggleSidebar","openPalette"],[1,"page-frame"],[3,"close","open"]],template:function(t,i){t&1&&(a(0,"div",0),p(1,"app-sidebar",1),a(2,"div",2),p(3,"app-status-strip"),a(4,"app-top-bar",3),h("toggleSidebar",function(){return i.toggleSidebar()})("openPalette",function(){return i.onOpenPalette()}),r(),a(5,"div",4),p(6,"router-outlet"),r()(),a(7,"app-command-palette",5),h("close",function(){return i.onClosePalette()}),r()()),t&2&&(o(),f("collapsed",i.sidebarCollapsed()),o(6),f("open",i.paletteOpen()))},dependencies:[se,H,G,K,W],styles:["[_nghost-%COMP%]{display:block;height:100%}.shell[_ngcontent-%COMP%]{display:flex;height:100vh;background:var(--bg-canvas);color:var(--text-primary);font-family:var(--font-ui);font-size:var(--fs-base)}.main[_ngcontent-%COMP%]{flex:1;display:flex;flex-direction:column;min-width:0;overflow:hidden}.page-frame[_ngcontent-%COMP%]{flex:1;min-height:0;display:flex;flex-direction:column;background:var(--bg-canvas)}"],changeDetection:0})};le(U,ue).catch(e=>console.error(e));