@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 +1 @@
1
- import{a as oe}from"./chunk-R5W2MDZN.js";import{a as ie}from"./chunk-WDU3WICG.js";import{b as ae}from"./chunk-HZA6NEAB.js";import{a as ne}from"./chunk-2GBEK2GM.js";import{a as te}from"./chunk-SUZYBYDW.js";import{b as K}from"./chunk-4N5DWG46.js";import{c as J}from"./chunk-SHPTC4RL.js";import{a as Z}from"./chunk-7RNS77UP.js";import{a as Y}from"./chunk-E44X4RH2.js";import{Aa as p,Ga as y,I as N,Ia as b,Ka as c,M as h,N as v,O as f,P as C,Ta as I,Ua as R,Va as l,W as P,Wa as m,Xa as z,Za as W,bb as X,ea as o,ka as q,lb as w,qa as T,ra as g,sa as u,ua as G,va as k,wa as S,xa as x,ya as i,za as a,zb as ee}from"./chunk-PDN6QYGJ.js";import{a as A,b as U}from"./chunk-Q7L6LLAK.js";var de=()=>[1,2,3,4],pe=(t,n)=>n.node.id,L=(t,n)=>n.id;function se(t,n){t&1&&p(0,"app-pick-project-empty",0)}function ce(t,n){if(t&1){let e=y();i(0,"button",19),b("click",function(){let d=h(e).$implicit,s=c(2);return v(s.toggleFilter(d))}),p(1,"span",20),l(2),i(3,"span",21),l(4),a()()}if(t&2){let e=n.$implicit,r=c(2);I("--chip-color",r.chipColor(e)),R("is-active",r.isFilterActive(e)),o(),T("data-kind",e),o(),z(" ",r.kindLabel(e)," "),o(2),m(r.countFor(e))}}function me(t,n){t&1&&p(0,"span",12)}function ge(t,n){if(t&1){let e=y();i(0,"button",23),b("click",function(){let d=h(e).$implicit,s=c(3);return v(s.pickResult(d.node))}),p(1,"span",24),i(2,"span",25),l(3),a(),i(4,"span",26),l(5),a(),i(6,"span",27),l(7),a()()}if(t&2){let e=n.$implicit,r=c(3);o(),R("is-spec",e.node.kind==="spec")("is-route",e.node.kind==="route")("is-test",e.node.kind==="test"),o(2),m(e.node.name),o(2),m(e.node.kind),o(2),m(r.shortPath(e.node.filePath))}}function ue(t,n){if(t&1&&(i(0,"div",13),k(1,ge,8,9,"button",22,pe),a()),t&2){let e=c(2);o(),S(e.searchResults.state().data.results)}}function _e(t,n){if(t&1&&(i(0,"p",28),l(1),a()),t&2){let e=n;o(),W("",e.nodeCount.toLocaleString()," nodes \xB7 ",e.edgeCount.toLocaleString()," edges \xB7 ",e.fileCount.toLocaleString()," files")}}function xe(t,n){if(t&1&&(i(0,"div",17)(1,"h3"),l(2,"Explore the graph"),a(),i(3,"p"),l(4,"Search for a function, method or class to start. The graph renders the symbol with its callers, callees and any linked specs."),a(),g(5,_e,2,3,"p",28),a()),t&2){let e,r=c(2);o(5),u((e=r.status.state().data)?5:-1,e)}}function he(t,n){t&1&&(i(0,"div",17)(1,"p"),l(2,"Loading\u2026"),a()())}function ve(t,n){if(t&1&&(i(0,"div",17)(1,"h3"),l(2,"Couldn't load that symbol"),a(),i(3,"p"),l(4),a()()),t&2){let e=c(2);o(4),m(e.nodeDetail.state().error)}}function fe(t,n){if(t&1&&(i(0,"div",17)(1,"p"),l(2),a()()),t&2){let e=c(2);o(2),z('No match for "',e.selectedSymbol(),'".')}}function Ce(t,n){if(t&1&&(i(0,"div",32),p(1,"span",42),i(2,"span",43),l(3),a()()),t&2){let e=n.$implicit;o(),T("data-kind",e),o(2),m(e)}}function be(t,n){if(t&1){let e=y();i(0,"app-graph-canvas",29),b("nodeClick",function(d){h(e);let s=c(2);return v(s.pickFromCanvas(d))}),a(),i(1,"div",30)(2,"div",31),k(3,Ce,4,2,"div",32,G),a(),p(5,"div",33),i(6,"div",34)(7,"div",35),f(),i(8,"svg",36),p(9,"line",37),a(),C(),i(10,"span",38),l(11,"implements"),a()(),i(12,"div",35),f(),i(13,"svg",36),p(14,"line",39),a(),C(),i(15,"span",38),l(16,"tests"),a()(),i(17,"div",35),f(),i(18,"svg",36),p(19,"line",40),a(),C(),i(20,"span",38),l(21,"calls"),a()(),i(22,"div",35),f(),i(23,"svg",36),p(24,"line",41),a(),C(),i(25,"span",38),l(26,"synth"),a()()()()}if(t&2){let e=c(2);x("nodes",e.visibleNodes())("edges",e.visibleEdges())("selectedId",e.selectedDetail().id)("fitKey",e.fitKey())("hiddenIds",e.hiddenIds()),o(3),S(e.kindKeys)}}function ye(t,n){if(t&1&&(i(0,"span",50),l(1),a()),t&2){let e=c();o(),m(e.startLine?"L"+e.startLine:"")}}function ke(t,n){if(t&1&&(i(0,"div",58)(1,"div",60),l(2,"Signature"),a(),i(3,"pre",61),l(4),a()()),t&2){let e=c();o(4),m(e.signature)}}function Se(t,n){if(t&1&&(i(0,"div",58)(1,"div",60),l(2,"Docstring"),a(),i(3,"p",62),l(4),a()()),t&2){let e=c();o(4),m(e.docstring)}}function we(t,n){if(t&1&&(i(0,"span",67),l(1),a()),t&2){let e=c().$implicit;o(),m(e.specTitle)}}function Me(t,n){if(t&1&&(i(0,"div",64),p(1,"app-state-pill",65),i(2,"span",66),l(3),a(),g(4,we,2,1,"span",67),a()),t&2){let e=n.$implicit;o(),x("state",e.state),o(2),m(e.specId),o(),u(e.specTitle?4:-1)}}function Ee(t,n){if(t&1&&(i(0,"div",58)(1,"div",60),l(2,"Linked specs "),i(3,"span",63),l(4),a()(),k(5,Me,5,3,"div",64,L),a()),t&2){let e=c();o(4),m(e.linkedSpecs.length),o(),S(e.linkedSpecs)}}function Pe(t,n){if(t&1){let e=y();i(0,"button",70),b("click",function(){let d=h(e).$implicit,s=c(5);return v(s.pickResult(d))}),p(1,"app-icon",71),i(2,"span",66),l(3),a(),i(4,"span",72),l(5),a()()}if(t&2){let e=n.$implicit,r=c(5);o(),x("size",12),o(2),m(e.name),o(2),m(r.fileName(e.filePath))}}function Oe(t,n){if(t&1&&k(0,Pe,6,3,"button",69,L),t&2){let e=c(2);S(e.callers)}}function Te(t,n){t&1&&(i(0,"div",68),l(1,"No callers"),a())}function Ge(t,n){if(t&1){let e=y();i(0,"button",70),b("click",function(){let d=h(e).$implicit,s=c(5);return v(s.pickResult(d))}),p(1,"app-icon",71),i(2,"span",66),l(3),a(),i(4,"span",72),l(5),a()()}if(t&2){let e=n.$implicit,r=c(5);o(),x("size",12),o(2),m(e.name),o(2),m(r.fileName(e.filePath))}}function Ie(t,n){if(t&1&&k(0,Ge,6,3,"button",69,L),t&2){let e=c(2);S(e.callees)}}function ze(t,n){t&1&&(i(0,"div",68),l(1,"No callees"),a())}function Ke(t,n){if(t&1&&(i(0,"div",58)(1,"div",60),l(2,"Callers "),i(3,"span",63),l(4),a()(),g(5,Oe,2,0)(6,Te,2,0,"div",68),a(),i(7,"div",58)(8,"div",60),l(9,"Callees "),i(10,"span",63),l(11),a()(),g(12,Ie,2,0)(13,ze,2,0,"div",68),a()),t&2){let e=c();o(4),m(e.callers.length),o(),u(e.callers.length?5:6),o(6),m(e.callees.length),o(),u(e.callees.length?12:13)}}function De(t,n){if(t&1){let e=y();i(0,"button",73),p(1,"app-icon",74),l(2," Implement "),a(),i(3,"button",14),b("click",function(){h(e);let d=c(3);return v(d.navigateToDrift())}),l(4,"Fix"),a(),i(5,"button",75),l(6,"Relink"),a()}t&2&&(o(),x("size",13))}function Ve(t,n){if(t&1){let e=y();i(0,"button",73),p(1,"app-icon",76),l(2," Reveal in editor "),a(),i(3,"button",14),b("click",function(){h(e);let d=c(3);return v(d.navigateToSpecs())}),l(4,"Open Specs"),a()}t&2&&(o(),x("size",13))}function Ne(t,n){if(t&1){let e=y();i(0,"div",44)(1,"div",45),p(2,"span",46),i(3,"div",47)(4,"div",48),l(5),a(),i(6,"div",49)(7,"span",50),l(8),a(),g(9,ye,2,1,"span",50),a()(),i(10,"button",51),b("click",function(){h(e);let d=c(2);return v(d.clearSelection())}),p(11,"app-icon",52),a()(),i(12,"div",53),p(13,"app-icon",54),i(14,"span",55),l(15),a(),p(16,"app-copy-btn",56),a()(),i(17,"div",57),g(18,ke,5,1,"div",58),g(19,Se,5,1,"div",58),g(20,Ee,7,1,"div",58),g(21,Ke,14,4),a(),i(22,"div",59),g(23,De,7,1)(24,Ve,5,1),a()}if(t&2){let e=n,r=e.kind==="spec",d=c(2).detailColor(e);o(2),I("background",d)("box-shadow","0 0 8px "+d),R("is-rect",r),o(3),m(e.name),o(2),I("color",d)("background","color-mix(in srgb, "+d+" 14%, transparent)"),o(),m(e.kind),o(),u(e.signature?9:-1),o(2),x("size",14),o(2),x("size",12),o(2),m(e.filePath),o(),x("text",e.filePath),o(2),u(e.signature?18:-1),o(),u(e.docstring?19:-1),o(),u(e.linkedSpecs&&e.linkedSpecs.length?20:-1),o(),u(r?-1:21),o(2),u(r?23:24)}}function Re(t,n){t&1&&(i(0,"span",81),l(1),a()),t&2&&(o(),z("",n.nodeCount.toLocaleString()," shown"))}function Le(t,n){if(t&1&&(i(0,"div",84),p(1,"span",86),i(2,"span",87),l(3),a(),i(4,"span",88),l(5),a()()),t&2){let e=n.$implicit,r=c(3);o(),T("data-kind",e),o(2),m(e),o(2),m(r.overviewKindCounts()[e])}}function Fe(t,n){t&1&&(i(0,"div",85),p(1,"app-state-pill",89)(2,"span",90)(3,"app-state-pill",91)(4,"span",90)(5,"app-state-pill",92)(6,"span",90),a())}function He(t,n){if(t&1&&(i(0,"div",85),p(1,"app-state-pill",89),i(2,"span",93),l(3),a(),p(4,"app-state-pill",91),i(5,"span",93),l(6),a(),p(7,"app-state-pill",92),i(8,"span",93),l(9),a()()),t&2){let e,r,d,s=c(3);o(3),m(((e=s.health.state().data)==null||e.linkHealth==null?null:e.linkHealth.verified)??0),o(3),m(((r=s.health.state().data)==null||r.linkHealth==null?null:r.linkHealth.drifted)??0),o(3),m((((d=s.health.state().data)==null||d.linkHealth==null?null:d.linkHealth.broken)??0)+(((d=s.health.state().data)==null||d.linkHealth==null?null:d.linkHealth.orphaned)??0))}}function $e(t,n){t&1&&(i(0,"div",94),f(),i(1,"svg",95),p(2,"line",96),a(),C(),p(3,"span",97),a(),i(4,"div",94),f(),i(5,"svg",95),p(6,"line",98),a(),C(),p(7,"span",97),a(),i(8,"div",94),f(),i(9,"svg",95),p(10,"line",99),a(),C(),p(11,"span",97),a(),i(12,"div",94),f(),i(13,"svg",95),p(14,"line",100),a(),C(),p(15,"span",97),a())}function je(t,n){if(t&1&&(i(0,"div",94),f(),i(1,"svg",95),p(2,"line",96),a(),C(),i(3,"span",101),l(4,"calls"),a(),i(5,"span",102),l(6),a()(),i(7,"div",94),f(),i(8,"svg",95),p(9,"line",98),a(),C(),i(10,"span",101),l(11,"implements / documents"),a(),i(12,"span",102),l(13),a()(),i(14,"div",94),f(),i(15,"svg",95),p(16,"line",99),a(),C(),i(17,"span",101),l(18,"tests"),a(),i(19,"span",102),l(20),a()(),i(21,"div",94),f(),i(22,"svg",95),p(23,"line",100),a(),C(),i(24,"span",101),l(25,"synthesized (heuristic)"),a(),i(26,"span",102),l(27),a()()),t&2){let e,r,d,s,M=c(3);o(6),m(((e=M.health.state().data)==null||e.edgeKinds==null?null:e.edgeKinds.calls)??0),o(7),m(((r=M.health.state().data)==null||r.edgeKinds==null?null:r.edgeKinds.implements)??0),o(7),m(((d=M.health.state().data)==null||d.edgeKinds==null?null:d.edgeKinds.tests)??0),o(7),m(((s=M.health.state().data)==null||s.edgeKinds==null?null:s.edgeKinds.synth)??0)}}function Be(t,n){t&1&&(i(0,"div",103),p(1,"span",104)(2,"span",105),a())}function Qe(t,n){t&1&&(i(0,"div",83)(1,"div",60),l(2,"Most connected"),a(),k(3,Be,3,0,"div",103,G),a()),t&2&&(o(3),S(X(0,de)))}function Ae(t,n){if(t&1){let e=y();i(0,"button",107),b("click",function(){let d=h(e).$implicit,s=c(4);return v(s.pickHub(d))}),p(1,"span",108),i(2,"span",109),l(3),a(),i(4,"span",110),l(5),a(),p(6,"app-icon",111),a()}if(t&2){let e=n.$implicit,r=c(4);T("aria-label",e.name+", "+e.degree+" edges"),o(),I("background",r.nodeColor(e.kind))("border-radius",e.kind==="spec"?"2px":"50%"),o(2),m(e.name),o(2),z("",e.degree," edges"),o(),x("size",11)}}function Ue(t,n){if(t&1&&(i(0,"div",83)(1,"div",60),l(2,"Most connected"),a(),k(3,Ae,7,8,"button",106,L),a()),t&2){let e=c(3);o(3),S(e.health.state().data.hubs.slice(0,8))}}function qe(t,n){if(t&1&&(i(0,"div",77),p(1,"app-icon",78),i(2,"span",79),l(3,"Graph overview"),a(),p(4,"div",80),g(5,Re,2,1,"span",81),a(),i(6,"div",57)(7,"p",82),l(8," Click any node to inspect its signature, links, callers and callees \u2014 without leaving this view. "),a(),i(9,"div",83)(10,"div",60),l(11,"Nodes by kind"),a(),k(12,Le,6,3,"div",84,G),a(),i(14,"div",83)(15,"div",60),l(16,"Spec link health"),a(),g(17,Fe,7,0,"div",85)(18,He,10,3,"div",85),a(),i(19,"div",83)(20,"div",60),l(21,"Edge types"),a(),g(22,$e,16,0)(23,je,28,4),a(),g(24,Qe,5,1,"div",83)(25,Ue,5,0,"div",83),a()),t&2){let e,r,d,s=c(2);o(),x("size",15),o(4),u((e=s.status.state().data)?5:-1,e),o(7),S(s.kindKeys),o(5),u(s.health.state().loading?17:18),o(5),u(s.health.state().loading?22:(r=s.health.state().data)!=null&&r.edgeKinds?23:-1),o(2),u(s.health.state().loading?24:!((d=s.health.state().data)==null||d.hubs==null)&&d.hubs.length?25:-1)}}function We(t,n){if(t&1){let e=y();i(0,"div",1)(1,"div",2)(2,"div",3)(3,"app-segmented",4),b("change",function(d){h(e);let s=c();return v(s.onLayoutChange(d))}),a(),p(4,"div",5),k(5,ce,5,7,"button",6,G),p(7,"div",7),i(8,"div",8)(9,"div",9),p(10,"app-icon",10),i(11,"input",11),b("input",function(d){h(e);let s=c();return v(s.onSearchInput(d.target.value))}),a(),g(12,me,1,0,"span",12),a(),g(13,ue,3,0,"div",13),a(),i(14,"button",14),b("click",function(){h(e);let d=c();return v(d.recenter())}),p(15,"app-icon",15),l(16," Recenter "),a()(),i(17,"div",16),g(18,xe,6,1,"div",17)(19,he,3,0,"div",17)(20,ve,5,1,"div",17)(21,fe,3,1,"div",17)(22,be,27,5),a()(),i(23,"aside",18),g(24,Ne,25,22)(25,qe,26,5),a()()}if(t&2){let e,r=c();o(3),x("options",r.layoutOptions)("value",r.layoutMode()),o(2),S(r.kindKeys),o(5),x("size",13),o(),x("value",r.searchInput()),o(),u(r.searchResults.state().loading?12:-1),o(),u(r.searchResults.state().data&&r.searchResults.state().data.results.length>0?13:-1),o(2),x("size",13),o(3),u(r.selectedSymbol()?r.nodeDetail.state().loading?19:r.nodeDetail.state().error?20:r.selectedDetail()?22:21:18),o(6),u((e=r.selectedDetail())?24:25,e)}}var re=class t{api=N(Y);projects=N(Z);router=N(J);status=K(this.api,()=>`/api/status${this.projects.projectQuery()}`);health=K(this.api,()=>`/api/graph/health${this.projects.projectQuery()}`);layoutMode=P("hierarchical");layoutOptions=[{value:"hierarchical",label:"Hierarchical"},{value:"force",label:"Force"},{value:"anchored",label:"Anchored"}];searchInput=P("");searchQuery=P("");searchDebounce=null;searchResults=K(this.api,()=>{let n=this.searchQuery().trim();return n.length>=2?`/api/graph/search?q=${encodeURIComponent(n)}&limit=12${this.projects.projectQuery("&")}`:null});selectedSymbol=P(null);nodeDetail=K(this.api,()=>{let n=this.selectedSymbol();return n?`/api/graph/node?symbol=${encodeURIComponent(n)}${this.projects.projectQuery("&")}`:null});selectedDetail=w(()=>this.nodeDetail.state().data?.matches?.[0]??null);filters=P({code:!0,spec:!0,route:!0,test:!0});fitKey=P(0);canvasData=w(()=>{let n=this.selectedDetail();if(!n)return{nodes:[],edges:[]};let e=this.filters(),r=_=>{let E=F(_);return e[E]},d={id:n.id,label:n.name,sub:H(n.filePath),kind:n.kind,x:0,y:0},s=(n.callers??[]).filter(_=>r(_.kind)),M=(n.callees??[]).filter(_=>r(_.kind)),$=(n.linkedSpecs??[]).filter(()=>e.spec),j=280,B=56,D=[d],V=[];return s.forEach((_,E)=>{let O=(E-(s.length-1)/2)*B;D.push(le(_,-j,O)),V.push({from:_.id,to:n.id,kind:"calls"})}),M.forEach((_,E)=>{let O=(E-(M.length-1)/2)*B;D.push(le(_,j,O)),V.push({from:n.id,to:_.id,kind:"calls"})}),$.forEach((_,E)=>{let O=(E-($.length-1)/2)*220,Q="spec:"+_.specId;D.push({id:Q,label:_.specId,sub:_.specTitle??void 0,kind:"spec",state:_.state,x:O,y:-160}),V.push({from:Q,to:n.id,kind:"implements"})}),{nodes:D,edges:V}});visibleNodes=w(()=>this.canvasData().nodes);visibleEdges=w(()=>this.canvasData().edges);hiddenIds=w(()=>{let n=this.filters(),e=new Set;for(let r of this.canvasData().nodes)n[F(r.kind)]||e.add(r.id);return e});kindCounts=w(()=>{let n={code:0,spec:0,route:0,test:0};for(let e of this.canvasData().nodes)n[F(e.kind)]++;return n});overviewKindCounts=w(()=>{let n=this.status.state().data;if(!n?.nodesByKind)return{code:0,spec:0,route:0,test:0};let e=n.nodesByKind;return{code:(e.function??0)+(e.method??0)+(e.class??0)+(e.variable??0)+(e.constant??0)+(e.type_alias??0)+(e.interface??0)+(e.struct??0)+(e.enum??0)+(e.property??0)+(e.field??0)+(e.file??0)+(e.module??0)+(e.namespace??0)+(e.component??0),spec:e.spec??0,route:e.route??0,test:e.test??0}});kindKeys=["code","spec","route","test"];isFilterActive(n){return this.filters()[n]}countFor(n){return this.kindCounts()[n]}chipColor(n){switch(n){case"spec":return"var(--node-spec)";case"route":return"var(--node-route)";case"test":return"var(--node-test)";default:return"var(--node-code)"}}onSearchInput(n){this.searchInput.set(n),this.searchDebounce&&clearTimeout(this.searchDebounce),this.searchDebounce=setTimeout(()=>this.searchQuery.set(n),180)}pickResult(n){this.searchInput.set(n.name),this.searchQuery.set(""),this.selectedSymbol.set(n.name)}pickFromCanvas(n){let e=this.selectedDetail();if(!e||n===e.id)return;let d=[...e.callers??[],...e.callees??[]].find(s=>s.id===n);d&&(this.selectedSymbol.set(d.name),this.fitKey.update(s=>s+1))}toggleFilter(n){this.filters.update(e=>U(A({},e),{[n]:!e[n]})),this.fitKey.update(e=>e+1)}recenter(){this.fitKey.update(n=>n+1)}clearSelection(){this.selectedSymbol.set(null),this.searchInput.set("")}onLayoutChange(n){this.layoutMode.set(n),this.fitKey.update(e=>e+1)}shortPath(n){return H(n)}fileName(n){return n?n.split("/").pop()??"":""}kindLabel(n){return n.charAt(0).toUpperCase()+n.slice(1)}navigateToSpecs(){this.router.navigate(["/specs"])}navigateToDrift(){this.router.navigate(["/drift"])}nodeColor(n){return n==="spec"?"var(--node-spec)":n==="route"?"var(--node-route)":n==="test"?"var(--node-test)":"var(--node-code)"}pickHub(n){this.selectedSymbol.set(n.name),this.fitKey.update(e=>e+1)}detailColor(n){if(n.kind==="spec"){let e=n.linkedSpecs??[],r=e.some(s=>s.state==="broken"||s.state==="orphaned"),d=!r&&e.some(s=>s.state==="drifted");return r?"var(--error)":d?"var(--warn)":"var(--node-spec)"}return n.kind==="test"?"var(--node-test)":n.kind==="route"?"var(--node-route)":"var(--node-code)"}static \u0275fac=function(e){return new(e||t)};static \u0275cmp=q({type:t,selectors:[["app-graph"]],decls:2,vars:1,consts:[["surface","The graph"],[1,"gp-root"],[1,"gp-main"],[1,"gp-toolbar"],["size","sm",3,"change","options","value"],[1,"gp-divider"],["type","button",1,"gp-chip",3,"is-active","--chip-color"],[1,"gp-spacer"],[1,"gp-search"],[1,"gp-search-inner"],["name","search",1,"gp-search-icon",3,"size"],["type","text","placeholder","Fuzzy symbol search\u2026","aria-label","Symbol search",3,"input","value"],["aria-hidden","true",1,"gp-spinner"],["role","listbox",1,"gp-results"],["type","button",1,"btn","btn-secondary","btn-sm",3,"click"],["name","recenter",3,"size"],[1,"gp-canvas-wrap"],[1,"gp-empty"],[1,"gp-panel"],["type","button",1,"gp-chip",3,"click"],[1,"gp-chip-dot"],[1,"gp-chip-count"],["type","button",1,"gp-result"],["type","button",1,"gp-result",3,"click"],[1,"gp-result-dot"],[1,"gp-result-name","mono"],[1,"gp-result-kind"],[1,"gp-result-path","mono"],[1,"gp-stats"],[3,"nodeClick","nodes","edges","selectedId","fitKey","hiddenIds"],[1,"gp-legend"],[1,"gp-legend-kinds"],[1,"gp-legend-item"],[1,"gp-legend-sep"],[1,"gp-legend-edges"],[1,"gp-legend-edge-row"],["width","16","height","8"],["x1","0","y1","4","x2","16","y2","4","stroke","var(--node-spec)","stroke-width","1.6"],[1,"secondary"],["x1","0","y1","4","x2","16","y2","4","stroke","var(--node-test)","stroke-width","1.6"],["x1","0","y1","4","x2","16","y2","4","stroke","var(--text-muted)","stroke-width","1.6"],["x1","0","y1","4","x2","16","y2","4","stroke","var(--text-muted)","stroke-width","1.6","stroke-dasharray","4 3"],[1,"gp-legend-dot"],[1,"secondary",2,"text-transform","capitalize"],[1,"gp-panel-header"],[1,"gp-panel-header-inner"],[1,"gp-node-dot"],[1,"grow",2,"min-width","0"],[1,"mono","gp-panel-name"],[1,"row","gap-6",2,"margin-top","3px"],[1,"pill"],["type","button","aria-label","Close panel",1,"btn","btn-ghost","btn-xs",3,"click"],["name","x",3,"size"],[1,"gp-panel-path","row","gap-6"],["name","folder",2,"color","var(--text-muted)","flex-shrink","0",3,"size"],[1,"mono","secondary","gp-path-text"],[3,"text"],[1,"gp-panel-body","scroll-y"],[1,"gp-section"],[1,"gp-panel-footer"],[1,"eyebrow","gp-eyebrow"],[1,"gp-code","mono"],[1,"secondary",2,"font-size","12px","line-height","1.6","margin","0"],[1,"muted",2,"font-weight","400","margin-left","5px"],[1,"gp-link-row"],[3,"state"],[1,"mono","grow","gp-link-text"],[1,"muted",2,"font-size","10px","flex-shrink","0","overflow","hidden","text-overflow","ellipsis","white-space","nowrap","max-width","120px"],[1,"muted",2,"font-size","12px","padding","4px 8px"],["type","button",1,"gp-node-link"],["type","button",1,"gp-node-link",3,"click"],["name","box",2,"color","var(--node-code)","flex-shrink","0",3,"size"],[1,"mono","muted","gp-link-file"],["type","button",1,"btn","btn-primary","btn-sm","grow",2,"justify-content","center"],["name","play",3,"size"],["type","button",1,"btn","btn-secondary","btn-sm"],["name","reveal",3,"size"],[1,"gp-panel-header","gp-overview-head"],["name","graph",2,"color","var(--accent)",3,"size"],[2,"font-weight","600","font-size","13.5px"],[1,"grow"],[1,"mono","muted",2,"font-size","11px"],[1,"secondary",2,"font-size","12px","line-height","1.55","margin","0 0 18px"],[1,"gp-section-plain"],[1,"gp-kind-row"],[1,"row","gap-6",2,"flex-wrap","wrap","align-items","center"],[1,"gp-kind-dot"],[1,"grow",2,"font-size","12.5px","text-transform","capitalize"],[1,"mono","tabular",2,"font-size","12.5px","font-weight","600"],["state","verified"],["aria-hidden","true",1,"gp-skel","gp-skel-sm"],["state","drifted"],["state","broken"],[1,"mono","tabular","muted",2,"font-size","11px","align-self","center"],[1,"gp-edge-row"],["width","20","height","8"],["x1","0","y1","4","x2","20","y2","4","stroke","var(--text-muted)","stroke-width","1.8"],["aria-hidden","true",1,"gp-skel","gp-skel-lg"],["x1","0","y1","4","x2","20","y2","4","stroke","var(--node-spec)","stroke-width","1.8"],["x1","0","y1","4","x2","20","y2","4","stroke","var(--node-test)","stroke-width","1.8"],["x1","0","y1","4","x2","20","y2","4","stroke","var(--text-muted)","stroke-width","1.8","stroke-dasharray","4 3"],[1,"grow","secondary",2,"font-size","12px"],[1,"mono","tabular","muted",2,"font-size","11px"],["aria-hidden","true",1,"gp-hub-row"],[1,"gp-hub-dot","gp-skel-dot"],["aria-hidden","true",1,"gp-skel","gp-skel-hub"],["type","button",1,"gp-hub-row"],["type","button",1,"gp-hub-row",3,"click"],[1,"gp-hub-dot"],[1,"mono","grow","gp-hub-name"],[1,"muted","gp-hub-degree"],["name","chevron-right",2,"color","var(--text-muted)","flex-shrink","0",3,"size"]],template:function(e,r){e&1&&g(0,se,1,0,"app-pick-project-empty",0)(1,We,26,9,"div",1),e&2&&u(r.status.state().noProject?0:1)},dependencies:[ne,ie,ee,te,ae,oe],styles:["[_nghost-%COMP%]{display:contents}.gp-root[_ngcontent-%COMP%]{flex:1;display:flex;min-height:0;min-width:0}.gp-main[_ngcontent-%COMP%]{flex:1;min-width:0;display:flex;flex-direction:column}.gp-toolbar[_ngcontent-%COMP%]{display:flex;align-items:center;gap:10px;padding:9px 14px;border-bottom:1px solid var(--border-subtle);background:var(--bg-panel-2, var(--bg-panel));flex-wrap:wrap;flex-shrink:0}.gp-divider[_ngcontent-%COMP%]{width:1px;height:20px;background:var(--border-subtle);flex-shrink:0}.gp-chip[_ngcontent-%COMP%]{display:flex;align-items:center;gap:6px;height:26px;padding:0 10px;border-radius:999px;font-size:11.5px;font-weight:500;cursor:pointer;border:1px solid var(--border-subtle);background:var(--bg-panel);color:var(--text-secondary);transition:all .1s}.gp-chip.is-active[_ngcontent-%COMP%]{border-color:transparent;background:color-mix(in srgb,var(--chip-color, var(--accent)) 22%,var(--bg-panel));color:var(--chip-color, var(--accent))}.gp-chip-dot[_ngcontent-%COMP%]{width:7px;height:7px;border-radius:50%}.gp-chip-dot[data-kind=code][_ngcontent-%COMP%]{background:var(--node-code)}.gp-chip-dot[data-kind=spec][_ngcontent-%COMP%]{background:var(--node-spec);border-radius:2px}.gp-chip-dot[data-kind=route][_ngcontent-%COMP%]{background:var(--node-route)}.gp-chip-dot[data-kind=test][_ngcontent-%COMP%]{background:var(--node-test)}.gp-chip-count[_ngcontent-%COMP%]{font-size:10.5px;color:var(--text-muted);font-variant-numeric:tabular-nums}.gp-spacer[_ngcontent-%COMP%]{flex:1}.gp-search[_ngcontent-%COMP%]{position:relative;flex-shrink:0}.gp-search-inner[_ngcontent-%COMP%]{display:flex;align-items:center;gap:6px;height:28px;padding:0 10px;background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:7px;width:220px}.gp-search-inner[_ngcontent-%COMP%] input[_ngcontent-%COMP%]{flex:1;background:transparent;border:none;outline:none;color:var(--text-primary);font-size:12px;font-family:var(--font-mono)}.gp-search-icon[_ngcontent-%COMP%]{color:var(--text-muted);flex-shrink:0}.gp-spinner[_ngcontent-%COMP%]{width:12px;height:12px;border:2px solid var(--border-subtle);border-top-color:var(--accent);border-radius:50%;animation:_ngcontent-%COMP%_gp-spin .7s linear infinite;flex-shrink:0}@keyframes _ngcontent-%COMP%_gp-spin{to{transform:rotate(360deg)}}.gp-results[_ngcontent-%COMP%]{position:absolute;top:32px;left:0;right:0;background:var(--bg-elevated);border:1px solid var(--border-strong);border-radius:8px;box-shadow:var(--shadow-pop, 0 12px 28px rgba(0, 0, 0, .5));padding:5px;z-index:30;max-height:320px;overflow-y:auto}.gp-result[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;width:100%;padding:6px 8px;border-radius:5px;background:transparent;border:none;cursor:pointer;font:inherit;color:var(--text-primary);text-align:left}.gp-result[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.gp-result-dot[_ngcontent-%COMP%]{width:7px;height:7px;border-radius:50%;background:var(--node-code);flex-shrink:0}.gp-result-dot.is-spec[_ngcontent-%COMP%]{background:var(--node-spec);border-radius:2px}.gp-result-dot.is-route[_ngcontent-%COMP%]{background:var(--node-route)}.gp-result-dot.is-test[_ngcontent-%COMP%]{background:var(--node-test)}.gp-result-name[_ngcontent-%COMP%]{font-size:12px;flex-shrink:0}.gp-result-kind[_ngcontent-%COMP%]{font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted)}.gp-result-path[_ngcontent-%COMP%]{flex:1;text-align:right;font-size:10px;color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gp-canvas-wrap[_ngcontent-%COMP%]{flex:1;min-height:0;position:relative;display:flex}.gp-canvas-wrap[_ngcontent-%COMP%] app-graph-canvas[_ngcontent-%COMP%]{flex:1;min-height:0}.gp-empty[_ngcontent-%COMP%]{flex:1;display:grid;place-items:center;text-align:center;padding:60px 24px;background:var(--bg-canvas-2, var(--bg-canvas))}.gp-empty[_ngcontent-%COMP%] h3[_ngcontent-%COMP%]{font-size:18px;font-weight:600;margin:0 0 8px}.gp-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{color:var(--text-secondary);font-size:13.5px;line-height:1.6;margin:0;max-width:520px}.gp-stats[_ngcontent-%COMP%]{margin-top:18px!important;font-family:var(--font-mono);font-size:11.5px!important;color:var(--text-muted)!important}.gp-legend[_ngcontent-%COMP%]{position:absolute;top:14px;left:14px;display:flex;align-items:center;gap:12px;flex-wrap:wrap;max-width:70%;background:color-mix(in srgb,var(--bg-panel) 86%,transparent);border:1px solid var(--border-subtle);border-radius:8px;padding:6px 10px;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);font-size:11px;pointer-events:none;z-index:3}.gp-legend-kinds[_ngcontent-%COMP%]{display:flex;align-items:center;gap:12px}.gp-legend-item[_ngcontent-%COMP%]{display:flex;align-items:center;gap:4px}.gp-legend-dot[_ngcontent-%COMP%]{width:8px;height:8px;border-radius:50%;flex-shrink:0}.gp-legend-dot[data-kind=code][_ngcontent-%COMP%]{background:var(--node-code)}.gp-legend-dot[data-kind=spec][_ngcontent-%COMP%]{background:var(--node-spec);border-radius:2px}.gp-legend-dot[data-kind=route][_ngcontent-%COMP%]{background:var(--node-route)}.gp-legend-dot[data-kind=test][_ngcontent-%COMP%]{background:var(--node-test)}.gp-legend-sep[_ngcontent-%COMP%]{width:1px;height:16px;background:var(--border-subtle);flex-shrink:0}.gp-legend-edges[_ngcontent-%COMP%]{display:flex;align-items:center;gap:10px}.gp-legend-edge-row[_ngcontent-%COMP%]{display:flex;align-items:center;gap:4px}.gp-panel[_ngcontent-%COMP%]{width:360px;flex-shrink:0;border-left:1px solid var(--border-subtle);background:var(--bg-panel);display:flex;flex-direction:column;overflow:hidden}.gp-panel-header[_ngcontent-%COMP%]{padding:12px 14px;border-bottom:1px solid var(--border-subtle);flex-shrink:0}.gp-panel-header-inner[_ngcontent-%COMP%]{display:flex;align-items:flex-start;gap:8px}.gp-overview-head[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px}.gp-node-dot[_ngcontent-%COMP%]{width:9px;height:9px;border-radius:50%;flex-shrink:0;margin-top:5px}.gp-node-dot.is-rect[_ngcontent-%COMP%]{border-radius:2px}.gp-panel-name[_ngcontent-%COMP%]{font-size:14px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gp-panel-path[_ngcontent-%COMP%]{margin-top:8px;font-size:11.5px;color:var(--text-secondary)}.gp-path-text[_ngcontent-%COMP%]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.gp-panel-body[_ngcontent-%COMP%]{flex:1;padding:14px;overflow-y:auto;display:flex;flex-direction:column;gap:18px}.gp-section[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:4px}.gp-section-plain[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:2px}.gp-eyebrow[_ngcontent-%COMP%]{font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-muted);margin-bottom:6px}.gp-code[_ngcontent-%COMP%]{margin:0;font-size:11.5px;line-height:1.6;color:var(--text-secondary);background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:7px;padding:10px;overflow-x:auto;white-space:pre-wrap;word-break:break-word}.gp-link-row[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:6px;border:1px solid var(--border-subtle);margin-bottom:5px;font-size:11.5px}.gp-link-text[_ngcontent-%COMP%]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px}.gp-node-link[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;width:100%;padding:5px 8px;border-radius:6px;border:none;background:transparent;cursor:pointer;font:inherit;color:inherit;text-align:left;font-size:12px}.gp-node-link[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.gp-link-file[_ngcontent-%COMP%]{font-size:10px;flex-shrink:0}.gp-edge-row[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;padding:4px 0}.gp-kind-row[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;padding:5px 0}.gp-kind-dot[_ngcontent-%COMP%]{width:9px;height:9px;border-radius:50%;flex-shrink:0}.gp-kind-dot[data-kind=code][_ngcontent-%COMP%]{background:var(--node-code);box-shadow:0 0 6px var(--node-code)}.gp-kind-dot[data-kind=spec][_ngcontent-%COMP%]{background:var(--node-spec);border-radius:2px;box-shadow:0 0 6px var(--node-spec)}.gp-kind-dot[data-kind=route][_ngcontent-%COMP%]{background:var(--node-route);box-shadow:0 0 6px var(--node-route)}.gp-kind-dot[data-kind=test][_ngcontent-%COMP%]{background:var(--node-test);box-shadow:0 0 6px var(--node-test)}.gp-panel-footer[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;padding:12px 14px;border-top:1px solid var(--border-subtle);flex-shrink:0}.gp-hub-row[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;width:100%;padding:5px 8px;border-radius:6px;border:none;background:transparent;cursor:pointer;font:inherit;color:inherit;text-align:left}.gp-hub-row[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.gp-hub-dot[_ngcontent-%COMP%]{width:8px;height:8px;flex-shrink:0}.gp-hub-name[_ngcontent-%COMP%]{font-size:11.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gp-hub-degree[_ngcontent-%COMP%]{font-size:10.5px;color:var(--text-muted);flex-shrink:0;font-variant-numeric:tabular-nums}@keyframes _ngcontent-%COMP%_gp-skel-pulse{0%,to{opacity:.35}50%{opacity:.7}}.gp-skel[_ngcontent-%COMP%]{display:inline-block;background:var(--border-subtle);border-radius:4px;animation:_ngcontent-%COMP%_gp-skel-pulse 1.4s ease-in-out infinite}.gp-skel-sm[_ngcontent-%COMP%]{width:24px;height:12px}.gp-skel-lg[_ngcontent-%COMP%]{width:80px;height:12px;flex:1}.gp-skel-hub[_ngcontent-%COMP%]{width:120px;height:12px;flex:1}.gp-skel-dot[_ngcontent-%COMP%]{width:8px;height:8px;border-radius:50%;flex-shrink:0;background:var(--border-subtle);animation:_ngcontent-%COMP%_gp-skel-pulse 1.4s ease-in-out infinite}.grow[_ngcontent-%COMP%]{flex:1}.muted[_ngcontent-%COMP%]{color:var(--text-muted)}.mono[_ngcontent-%COMP%]{font-family:var(--font-mono)}"],changeDetection:0})};function le(t,n,e){return{id:t.id,label:t.name,sub:H(t.filePath),kind:t.kind,x:n,y:e}}function H(t){return t?t.split("/").slice(-2).join("/"):""}function F(t){return t==="spec"?"spec":t==="route"?"route":t==="test"?"test":"code"}export{re as Graph};
1
+ import{a as oe}from"./chunk-R5W2MDZN.js";import{a as ie}from"./chunk-WDU3WICG.js";import{b as ae}from"./chunk-HZA6NEAB.js";import{a as ne}from"./chunk-2GBEK2GM.js";import{a as te}from"./chunk-SUZYBYDW.js";import{c as K}from"./chunk-GR72OOCN.js";import{c as J}from"./chunk-SHPTC4RL.js";import{a as Z}from"./chunk-7RNS77UP.js";import{a as Y}from"./chunk-E44X4RH2.js";import{Aa as p,Ga as y,I as N,Ia as b,Ka as c,M as h,N as v,O as f,P as C,Ta as I,Ua as R,Va as l,W as P,Wa as m,Xa as z,Za as W,bb as X,ea as o,ka as q,lb as w,qa as T,ra as g,sa as u,ua as G,va as k,wa as S,xa as x,ya as i,za as a,zb as ee}from"./chunk-PDN6QYGJ.js";import{a as A,b as U}from"./chunk-Q7L6LLAK.js";var de=()=>[1,2,3,4],pe=(t,n)=>n.node.id,L=(t,n)=>n.id;function se(t,n){t&1&&p(0,"app-pick-project-empty",0)}function ce(t,n){if(t&1){let e=y();i(0,"button",19),b("click",function(){let d=h(e).$implicit,s=c(2);return v(s.toggleFilter(d))}),p(1,"span",20),l(2),i(3,"span",21),l(4),a()()}if(t&2){let e=n.$implicit,r=c(2);I("--chip-color",r.chipColor(e)),R("is-active",r.isFilterActive(e)),o(),T("data-kind",e),o(),z(" ",r.kindLabel(e)," "),o(2),m(r.countFor(e))}}function me(t,n){t&1&&p(0,"span",12)}function ge(t,n){if(t&1){let e=y();i(0,"button",23),b("click",function(){let d=h(e).$implicit,s=c(3);return v(s.pickResult(d.node))}),p(1,"span",24),i(2,"span",25),l(3),a(),i(4,"span",26),l(5),a(),i(6,"span",27),l(7),a()()}if(t&2){let e=n.$implicit,r=c(3);o(),R("is-spec",e.node.kind==="spec")("is-route",e.node.kind==="route")("is-test",e.node.kind==="test"),o(2),m(e.node.name),o(2),m(e.node.kind),o(2),m(r.shortPath(e.node.filePath))}}function ue(t,n){if(t&1&&(i(0,"div",13),k(1,ge,8,9,"button",22,pe),a()),t&2){let e=c(2);o(),S(e.searchResults.state().data.results)}}function _e(t,n){if(t&1&&(i(0,"p",28),l(1),a()),t&2){let e=n;o(),W("",e.nodeCount.toLocaleString()," nodes \xB7 ",e.edgeCount.toLocaleString()," edges \xB7 ",e.fileCount.toLocaleString()," files")}}function xe(t,n){if(t&1&&(i(0,"div",17)(1,"h3"),l(2,"Explore the graph"),a(),i(3,"p"),l(4,"Search for a function, method or class to start. The graph renders the symbol with its callers, callees and any linked specs."),a(),g(5,_e,2,3,"p",28),a()),t&2){let e,r=c(2);o(5),u((e=r.status.state().data)?5:-1,e)}}function he(t,n){t&1&&(i(0,"div",17)(1,"p"),l(2,"Loading\u2026"),a()())}function ve(t,n){if(t&1&&(i(0,"div",17)(1,"h3"),l(2,"Couldn't load that symbol"),a(),i(3,"p"),l(4),a()()),t&2){let e=c(2);o(4),m(e.nodeDetail.state().error)}}function fe(t,n){if(t&1&&(i(0,"div",17)(1,"p"),l(2),a()()),t&2){let e=c(2);o(2),z('No match for "',e.selectedSymbol(),'".')}}function Ce(t,n){if(t&1&&(i(0,"div",32),p(1,"span",42),i(2,"span",43),l(3),a()()),t&2){let e=n.$implicit;o(),T("data-kind",e),o(2),m(e)}}function be(t,n){if(t&1){let e=y();i(0,"app-graph-canvas",29),b("nodeClick",function(d){h(e);let s=c(2);return v(s.pickFromCanvas(d))}),a(),i(1,"div",30)(2,"div",31),k(3,Ce,4,2,"div",32,G),a(),p(5,"div",33),i(6,"div",34)(7,"div",35),f(),i(8,"svg",36),p(9,"line",37),a(),C(),i(10,"span",38),l(11,"implements"),a()(),i(12,"div",35),f(),i(13,"svg",36),p(14,"line",39),a(),C(),i(15,"span",38),l(16,"tests"),a()(),i(17,"div",35),f(),i(18,"svg",36),p(19,"line",40),a(),C(),i(20,"span",38),l(21,"calls"),a()(),i(22,"div",35),f(),i(23,"svg",36),p(24,"line",41),a(),C(),i(25,"span",38),l(26,"synth"),a()()()()}if(t&2){let e=c(2);x("nodes",e.visibleNodes())("edges",e.visibleEdges())("selectedId",e.selectedDetail().id)("fitKey",e.fitKey())("hiddenIds",e.hiddenIds()),o(3),S(e.kindKeys)}}function ye(t,n){if(t&1&&(i(0,"span",50),l(1),a()),t&2){let e=c();o(),m(e.startLine?"L"+e.startLine:"")}}function ke(t,n){if(t&1&&(i(0,"div",58)(1,"div",60),l(2,"Signature"),a(),i(3,"pre",61),l(4),a()()),t&2){let e=c();o(4),m(e.signature)}}function Se(t,n){if(t&1&&(i(0,"div",58)(1,"div",60),l(2,"Docstring"),a(),i(3,"p",62),l(4),a()()),t&2){let e=c();o(4),m(e.docstring)}}function we(t,n){if(t&1&&(i(0,"span",67),l(1),a()),t&2){let e=c().$implicit;o(),m(e.specTitle)}}function Me(t,n){if(t&1&&(i(0,"div",64),p(1,"app-state-pill",65),i(2,"span",66),l(3),a(),g(4,we,2,1,"span",67),a()),t&2){let e=n.$implicit;o(),x("state",e.state),o(2),m(e.specId),o(),u(e.specTitle?4:-1)}}function Ee(t,n){if(t&1&&(i(0,"div",58)(1,"div",60),l(2,"Linked specs "),i(3,"span",63),l(4),a()(),k(5,Me,5,3,"div",64,L),a()),t&2){let e=c();o(4),m(e.linkedSpecs.length),o(),S(e.linkedSpecs)}}function Pe(t,n){if(t&1){let e=y();i(0,"button",70),b("click",function(){let d=h(e).$implicit,s=c(5);return v(s.pickResult(d))}),p(1,"app-icon",71),i(2,"span",66),l(3),a(),i(4,"span",72),l(5),a()()}if(t&2){let e=n.$implicit,r=c(5);o(),x("size",12),o(2),m(e.name),o(2),m(r.fileName(e.filePath))}}function Oe(t,n){if(t&1&&k(0,Pe,6,3,"button",69,L),t&2){let e=c(2);S(e.callers)}}function Te(t,n){t&1&&(i(0,"div",68),l(1,"No callers"),a())}function Ge(t,n){if(t&1){let e=y();i(0,"button",70),b("click",function(){let d=h(e).$implicit,s=c(5);return v(s.pickResult(d))}),p(1,"app-icon",71),i(2,"span",66),l(3),a(),i(4,"span",72),l(5),a()()}if(t&2){let e=n.$implicit,r=c(5);o(),x("size",12),o(2),m(e.name),o(2),m(r.fileName(e.filePath))}}function Ie(t,n){if(t&1&&k(0,Ge,6,3,"button",69,L),t&2){let e=c(2);S(e.callees)}}function ze(t,n){t&1&&(i(0,"div",68),l(1,"No callees"),a())}function Ke(t,n){if(t&1&&(i(0,"div",58)(1,"div",60),l(2,"Callers "),i(3,"span",63),l(4),a()(),g(5,Oe,2,0)(6,Te,2,0,"div",68),a(),i(7,"div",58)(8,"div",60),l(9,"Callees "),i(10,"span",63),l(11),a()(),g(12,Ie,2,0)(13,ze,2,0,"div",68),a()),t&2){let e=c();o(4),m(e.callers.length),o(),u(e.callers.length?5:6),o(6),m(e.callees.length),o(),u(e.callees.length?12:13)}}function De(t,n){if(t&1){let e=y();i(0,"button",73),p(1,"app-icon",74),l(2," Implement "),a(),i(3,"button",14),b("click",function(){h(e);let d=c(3);return v(d.navigateToDrift())}),l(4,"Fix"),a(),i(5,"button",75),l(6,"Relink"),a()}t&2&&(o(),x("size",13))}function Ve(t,n){if(t&1){let e=y();i(0,"button",73),p(1,"app-icon",76),l(2," Reveal in editor "),a(),i(3,"button",14),b("click",function(){h(e);let d=c(3);return v(d.navigateToSpecs())}),l(4,"Open Specs"),a()}t&2&&(o(),x("size",13))}function Ne(t,n){if(t&1){let e=y();i(0,"div",44)(1,"div",45),p(2,"span",46),i(3,"div",47)(4,"div",48),l(5),a(),i(6,"div",49)(7,"span",50),l(8),a(),g(9,ye,2,1,"span",50),a()(),i(10,"button",51),b("click",function(){h(e);let d=c(2);return v(d.clearSelection())}),p(11,"app-icon",52),a()(),i(12,"div",53),p(13,"app-icon",54),i(14,"span",55),l(15),a(),p(16,"app-copy-btn",56),a()(),i(17,"div",57),g(18,ke,5,1,"div",58),g(19,Se,5,1,"div",58),g(20,Ee,7,1,"div",58),g(21,Ke,14,4),a(),i(22,"div",59),g(23,De,7,1)(24,Ve,5,1),a()}if(t&2){let e=n,r=e.kind==="spec",d=c(2).detailColor(e);o(2),I("background",d)("box-shadow","0 0 8px "+d),R("is-rect",r),o(3),m(e.name),o(2),I("color",d)("background","color-mix(in srgb, "+d+" 14%, transparent)"),o(),m(e.kind),o(),u(e.signature?9:-1),o(2),x("size",14),o(2),x("size",12),o(2),m(e.filePath),o(),x("text",e.filePath),o(2),u(e.signature?18:-1),o(),u(e.docstring?19:-1),o(),u(e.linkedSpecs&&e.linkedSpecs.length?20:-1),o(),u(r?-1:21),o(2),u(r?23:24)}}function Re(t,n){t&1&&(i(0,"span",81),l(1),a()),t&2&&(o(),z("",n.nodeCount.toLocaleString()," shown"))}function Le(t,n){if(t&1&&(i(0,"div",84),p(1,"span",86),i(2,"span",87),l(3),a(),i(4,"span",88),l(5),a()()),t&2){let e=n.$implicit,r=c(3);o(),T("data-kind",e),o(2),m(e),o(2),m(r.overviewKindCounts()[e])}}function Fe(t,n){t&1&&(i(0,"div",85),p(1,"app-state-pill",89)(2,"span",90)(3,"app-state-pill",91)(4,"span",90)(5,"app-state-pill",92)(6,"span",90),a())}function He(t,n){if(t&1&&(i(0,"div",85),p(1,"app-state-pill",89),i(2,"span",93),l(3),a(),p(4,"app-state-pill",91),i(5,"span",93),l(6),a(),p(7,"app-state-pill",92),i(8,"span",93),l(9),a()()),t&2){let e,r,d,s=c(3);o(3),m(((e=s.health.state().data)==null||e.linkHealth==null?null:e.linkHealth.verified)??0),o(3),m(((r=s.health.state().data)==null||r.linkHealth==null?null:r.linkHealth.drifted)??0),o(3),m((((d=s.health.state().data)==null||d.linkHealth==null?null:d.linkHealth.broken)??0)+(((d=s.health.state().data)==null||d.linkHealth==null?null:d.linkHealth.orphaned)??0))}}function $e(t,n){t&1&&(i(0,"div",94),f(),i(1,"svg",95),p(2,"line",96),a(),C(),p(3,"span",97),a(),i(4,"div",94),f(),i(5,"svg",95),p(6,"line",98),a(),C(),p(7,"span",97),a(),i(8,"div",94),f(),i(9,"svg",95),p(10,"line",99),a(),C(),p(11,"span",97),a(),i(12,"div",94),f(),i(13,"svg",95),p(14,"line",100),a(),C(),p(15,"span",97),a())}function je(t,n){if(t&1&&(i(0,"div",94),f(),i(1,"svg",95),p(2,"line",96),a(),C(),i(3,"span",101),l(4,"calls"),a(),i(5,"span",102),l(6),a()(),i(7,"div",94),f(),i(8,"svg",95),p(9,"line",98),a(),C(),i(10,"span",101),l(11,"implements / documents"),a(),i(12,"span",102),l(13),a()(),i(14,"div",94),f(),i(15,"svg",95),p(16,"line",99),a(),C(),i(17,"span",101),l(18,"tests"),a(),i(19,"span",102),l(20),a()(),i(21,"div",94),f(),i(22,"svg",95),p(23,"line",100),a(),C(),i(24,"span",101),l(25,"synthesized (heuristic)"),a(),i(26,"span",102),l(27),a()()),t&2){let e,r,d,s,M=c(3);o(6),m(((e=M.health.state().data)==null||e.edgeKinds==null?null:e.edgeKinds.calls)??0),o(7),m(((r=M.health.state().data)==null||r.edgeKinds==null?null:r.edgeKinds.implements)??0),o(7),m(((d=M.health.state().data)==null||d.edgeKinds==null?null:d.edgeKinds.tests)??0),o(7),m(((s=M.health.state().data)==null||s.edgeKinds==null?null:s.edgeKinds.synth)??0)}}function Be(t,n){t&1&&(i(0,"div",103),p(1,"span",104)(2,"span",105),a())}function Qe(t,n){t&1&&(i(0,"div",83)(1,"div",60),l(2,"Most connected"),a(),k(3,Be,3,0,"div",103,G),a()),t&2&&(o(3),S(X(0,de)))}function Ae(t,n){if(t&1){let e=y();i(0,"button",107),b("click",function(){let d=h(e).$implicit,s=c(4);return v(s.pickHub(d))}),p(1,"span",108),i(2,"span",109),l(3),a(),i(4,"span",110),l(5),a(),p(6,"app-icon",111),a()}if(t&2){let e=n.$implicit,r=c(4);T("aria-label",e.name+", "+e.degree+" edges"),o(),I("background",r.nodeColor(e.kind))("border-radius",e.kind==="spec"?"2px":"50%"),o(2),m(e.name),o(2),z("",e.degree," edges"),o(),x("size",11)}}function Ue(t,n){if(t&1&&(i(0,"div",83)(1,"div",60),l(2,"Most connected"),a(),k(3,Ae,7,8,"button",106,L),a()),t&2){let e=c(3);o(3),S(e.health.state().data.hubs.slice(0,8))}}function qe(t,n){if(t&1&&(i(0,"div",77),p(1,"app-icon",78),i(2,"span",79),l(3,"Graph overview"),a(),p(4,"div",80),g(5,Re,2,1,"span",81),a(),i(6,"div",57)(7,"p",82),l(8," Click any node to inspect its signature, links, callers and callees \u2014 without leaving this view. "),a(),i(9,"div",83)(10,"div",60),l(11,"Nodes by kind"),a(),k(12,Le,6,3,"div",84,G),a(),i(14,"div",83)(15,"div",60),l(16,"Spec link health"),a(),g(17,Fe,7,0,"div",85)(18,He,10,3,"div",85),a(),i(19,"div",83)(20,"div",60),l(21,"Edge types"),a(),g(22,$e,16,0)(23,je,28,4),a(),g(24,Qe,5,1,"div",83)(25,Ue,5,0,"div",83),a()),t&2){let e,r,d,s=c(2);o(),x("size",15),o(4),u((e=s.status.state().data)?5:-1,e),o(7),S(s.kindKeys),o(5),u(s.health.state().loading?17:18),o(5),u(s.health.state().loading?22:(r=s.health.state().data)!=null&&r.edgeKinds?23:-1),o(2),u(s.health.state().loading?24:!((d=s.health.state().data)==null||d.hubs==null)&&d.hubs.length?25:-1)}}function We(t,n){if(t&1){let e=y();i(0,"div",1)(1,"div",2)(2,"div",3)(3,"app-segmented",4),b("change",function(d){h(e);let s=c();return v(s.onLayoutChange(d))}),a(),p(4,"div",5),k(5,ce,5,7,"button",6,G),p(7,"div",7),i(8,"div",8)(9,"div",9),p(10,"app-icon",10),i(11,"input",11),b("input",function(d){h(e);let s=c();return v(s.onSearchInput(d.target.value))}),a(),g(12,me,1,0,"span",12),a(),g(13,ue,3,0,"div",13),a(),i(14,"button",14),b("click",function(){h(e);let d=c();return v(d.recenter())}),p(15,"app-icon",15),l(16," Recenter "),a()(),i(17,"div",16),g(18,xe,6,1,"div",17)(19,he,3,0,"div",17)(20,ve,5,1,"div",17)(21,fe,3,1,"div",17)(22,be,27,5),a()(),i(23,"aside",18),g(24,Ne,25,22)(25,qe,26,5),a()()}if(t&2){let e,r=c();o(3),x("options",r.layoutOptions)("value",r.layoutMode()),o(2),S(r.kindKeys),o(5),x("size",13),o(),x("value",r.searchInput()),o(),u(r.searchResults.state().loading?12:-1),o(),u(r.searchResults.state().data&&r.searchResults.state().data.results.length>0?13:-1),o(2),x("size",13),o(3),u(r.selectedSymbol()?r.nodeDetail.state().loading?19:r.nodeDetail.state().error?20:r.selectedDetail()?22:21:18),o(6),u((e=r.selectedDetail())?24:25,e)}}var re=class t{api=N(Y);projects=N(Z);router=N(J);status=K(this.api,()=>`/api/status${this.projects.projectQuery()}`);health=K(this.api,()=>`/api/graph/health${this.projects.projectQuery()}`);layoutMode=P("hierarchical");layoutOptions=[{value:"hierarchical",label:"Hierarchical"},{value:"force",label:"Force"},{value:"anchored",label:"Anchored"}];searchInput=P("");searchQuery=P("");searchDebounce=null;searchResults=K(this.api,()=>{let n=this.searchQuery().trim();return n.length>=2?`/api/graph/search?q=${encodeURIComponent(n)}&limit=12${this.projects.projectQuery("&")}`:null});selectedSymbol=P(null);nodeDetail=K(this.api,()=>{let n=this.selectedSymbol();return n?`/api/graph/node?symbol=${encodeURIComponent(n)}${this.projects.projectQuery("&")}`:null});selectedDetail=w(()=>this.nodeDetail.state().data?.matches?.[0]??null);filters=P({code:!0,spec:!0,route:!0,test:!0});fitKey=P(0);canvasData=w(()=>{let n=this.selectedDetail();if(!n)return{nodes:[],edges:[]};let e=this.filters(),r=_=>{let E=F(_);return e[E]},d={id:n.id,label:n.name,sub:H(n.filePath),kind:n.kind,x:0,y:0},s=(n.callers??[]).filter(_=>r(_.kind)),M=(n.callees??[]).filter(_=>r(_.kind)),$=(n.linkedSpecs??[]).filter(()=>e.spec),j=280,B=56,D=[d],V=[];return s.forEach((_,E)=>{let O=(E-(s.length-1)/2)*B;D.push(le(_,-j,O)),V.push({from:_.id,to:n.id,kind:"calls"})}),M.forEach((_,E)=>{let O=(E-(M.length-1)/2)*B;D.push(le(_,j,O)),V.push({from:n.id,to:_.id,kind:"calls"})}),$.forEach((_,E)=>{let O=(E-($.length-1)/2)*220,Q="spec:"+_.specId;D.push({id:Q,label:_.specId,sub:_.specTitle??void 0,kind:"spec",state:_.state,x:O,y:-160}),V.push({from:Q,to:n.id,kind:"implements"})}),{nodes:D,edges:V}});visibleNodes=w(()=>this.canvasData().nodes);visibleEdges=w(()=>this.canvasData().edges);hiddenIds=w(()=>{let n=this.filters(),e=new Set;for(let r of this.canvasData().nodes)n[F(r.kind)]||e.add(r.id);return e});kindCounts=w(()=>{let n={code:0,spec:0,route:0,test:0};for(let e of this.canvasData().nodes)n[F(e.kind)]++;return n});overviewKindCounts=w(()=>{let n=this.status.state().data;if(!n?.nodesByKind)return{code:0,spec:0,route:0,test:0};let e=n.nodesByKind;return{code:(e.function??0)+(e.method??0)+(e.class??0)+(e.variable??0)+(e.constant??0)+(e.type_alias??0)+(e.interface??0)+(e.struct??0)+(e.enum??0)+(e.property??0)+(e.field??0)+(e.file??0)+(e.module??0)+(e.namespace??0)+(e.component??0),spec:e.spec??0,route:e.route??0,test:e.test??0}});kindKeys=["code","spec","route","test"];isFilterActive(n){return this.filters()[n]}countFor(n){return this.kindCounts()[n]}chipColor(n){switch(n){case"spec":return"var(--node-spec)";case"route":return"var(--node-route)";case"test":return"var(--node-test)";default:return"var(--node-code)"}}onSearchInput(n){this.searchInput.set(n),this.searchDebounce&&clearTimeout(this.searchDebounce),this.searchDebounce=setTimeout(()=>this.searchQuery.set(n),180)}pickResult(n){this.searchInput.set(n.name),this.searchQuery.set(""),this.selectedSymbol.set(n.name)}pickFromCanvas(n){let e=this.selectedDetail();if(!e||n===e.id)return;let d=[...e.callers??[],...e.callees??[]].find(s=>s.id===n);d&&(this.selectedSymbol.set(d.name),this.fitKey.update(s=>s+1))}toggleFilter(n){this.filters.update(e=>U(A({},e),{[n]:!e[n]})),this.fitKey.update(e=>e+1)}recenter(){this.fitKey.update(n=>n+1)}clearSelection(){this.selectedSymbol.set(null),this.searchInput.set("")}onLayoutChange(n){this.layoutMode.set(n),this.fitKey.update(e=>e+1)}shortPath(n){return H(n)}fileName(n){return n?n.split("/").pop()??"":""}kindLabel(n){return n.charAt(0).toUpperCase()+n.slice(1)}navigateToSpecs(){this.router.navigate(["/specs"])}navigateToDrift(){this.router.navigate(["/drift"])}nodeColor(n){return n==="spec"?"var(--node-spec)":n==="route"?"var(--node-route)":n==="test"?"var(--node-test)":"var(--node-code)"}pickHub(n){this.selectedSymbol.set(n.name),this.fitKey.update(e=>e+1)}detailColor(n){if(n.kind==="spec"){let e=n.linkedSpecs??[],r=e.some(s=>s.state==="broken"||s.state==="orphaned"),d=!r&&e.some(s=>s.state==="drifted");return r?"var(--error)":d?"var(--warn)":"var(--node-spec)"}return n.kind==="test"?"var(--node-test)":n.kind==="route"?"var(--node-route)":"var(--node-code)"}static \u0275fac=function(e){return new(e||t)};static \u0275cmp=q({type:t,selectors:[["app-graph"]],decls:2,vars:1,consts:[["surface","The graph"],[1,"gp-root"],[1,"gp-main"],[1,"gp-toolbar"],["size","sm",3,"change","options","value"],[1,"gp-divider"],["type","button",1,"gp-chip",3,"is-active","--chip-color"],[1,"gp-spacer"],[1,"gp-search"],[1,"gp-search-inner"],["name","search",1,"gp-search-icon",3,"size"],["type","text","placeholder","Fuzzy symbol search\u2026","aria-label","Symbol search",3,"input","value"],["aria-hidden","true",1,"gp-spinner"],["role","listbox",1,"gp-results"],["type","button",1,"btn","btn-secondary","btn-sm",3,"click"],["name","recenter",3,"size"],[1,"gp-canvas-wrap"],[1,"gp-empty"],[1,"gp-panel"],["type","button",1,"gp-chip",3,"click"],[1,"gp-chip-dot"],[1,"gp-chip-count"],["type","button",1,"gp-result"],["type","button",1,"gp-result",3,"click"],[1,"gp-result-dot"],[1,"gp-result-name","mono"],[1,"gp-result-kind"],[1,"gp-result-path","mono"],[1,"gp-stats"],[3,"nodeClick","nodes","edges","selectedId","fitKey","hiddenIds"],[1,"gp-legend"],[1,"gp-legend-kinds"],[1,"gp-legend-item"],[1,"gp-legend-sep"],[1,"gp-legend-edges"],[1,"gp-legend-edge-row"],["width","16","height","8"],["x1","0","y1","4","x2","16","y2","4","stroke","var(--node-spec)","stroke-width","1.6"],[1,"secondary"],["x1","0","y1","4","x2","16","y2","4","stroke","var(--node-test)","stroke-width","1.6"],["x1","0","y1","4","x2","16","y2","4","stroke","var(--text-muted)","stroke-width","1.6"],["x1","0","y1","4","x2","16","y2","4","stroke","var(--text-muted)","stroke-width","1.6","stroke-dasharray","4 3"],[1,"gp-legend-dot"],[1,"secondary",2,"text-transform","capitalize"],[1,"gp-panel-header"],[1,"gp-panel-header-inner"],[1,"gp-node-dot"],[1,"grow",2,"min-width","0"],[1,"mono","gp-panel-name"],[1,"row","gap-6",2,"margin-top","3px"],[1,"pill"],["type","button","aria-label","Close panel",1,"btn","btn-ghost","btn-xs",3,"click"],["name","x",3,"size"],[1,"gp-panel-path","row","gap-6"],["name","folder",2,"color","var(--text-muted)","flex-shrink","0",3,"size"],[1,"mono","secondary","gp-path-text"],[3,"text"],[1,"gp-panel-body","scroll-y"],[1,"gp-section"],[1,"gp-panel-footer"],[1,"eyebrow","gp-eyebrow"],[1,"gp-code","mono"],[1,"secondary",2,"font-size","12px","line-height","1.6","margin","0"],[1,"muted",2,"font-weight","400","margin-left","5px"],[1,"gp-link-row"],[3,"state"],[1,"mono","grow","gp-link-text"],[1,"muted",2,"font-size","10px","flex-shrink","0","overflow","hidden","text-overflow","ellipsis","white-space","nowrap","max-width","120px"],[1,"muted",2,"font-size","12px","padding","4px 8px"],["type","button",1,"gp-node-link"],["type","button",1,"gp-node-link",3,"click"],["name","box",2,"color","var(--node-code)","flex-shrink","0",3,"size"],[1,"mono","muted","gp-link-file"],["type","button",1,"btn","btn-primary","btn-sm","grow",2,"justify-content","center"],["name","play",3,"size"],["type","button",1,"btn","btn-secondary","btn-sm"],["name","reveal",3,"size"],[1,"gp-panel-header","gp-overview-head"],["name","graph",2,"color","var(--accent)",3,"size"],[2,"font-weight","600","font-size","13.5px"],[1,"grow"],[1,"mono","muted",2,"font-size","11px"],[1,"secondary",2,"font-size","12px","line-height","1.55","margin","0 0 18px"],[1,"gp-section-plain"],[1,"gp-kind-row"],[1,"row","gap-6",2,"flex-wrap","wrap","align-items","center"],[1,"gp-kind-dot"],[1,"grow",2,"font-size","12.5px","text-transform","capitalize"],[1,"mono","tabular",2,"font-size","12.5px","font-weight","600"],["state","verified"],["aria-hidden","true",1,"gp-skel","gp-skel-sm"],["state","drifted"],["state","broken"],[1,"mono","tabular","muted",2,"font-size","11px","align-self","center"],[1,"gp-edge-row"],["width","20","height","8"],["x1","0","y1","4","x2","20","y2","4","stroke","var(--text-muted)","stroke-width","1.8"],["aria-hidden","true",1,"gp-skel","gp-skel-lg"],["x1","0","y1","4","x2","20","y2","4","stroke","var(--node-spec)","stroke-width","1.8"],["x1","0","y1","4","x2","20","y2","4","stroke","var(--node-test)","stroke-width","1.8"],["x1","0","y1","4","x2","20","y2","4","stroke","var(--text-muted)","stroke-width","1.8","stroke-dasharray","4 3"],[1,"grow","secondary",2,"font-size","12px"],[1,"mono","tabular","muted",2,"font-size","11px"],["aria-hidden","true",1,"gp-hub-row"],[1,"gp-hub-dot","gp-skel-dot"],["aria-hidden","true",1,"gp-skel","gp-skel-hub"],["type","button",1,"gp-hub-row"],["type","button",1,"gp-hub-row",3,"click"],[1,"gp-hub-dot"],[1,"mono","grow","gp-hub-name"],[1,"muted","gp-hub-degree"],["name","chevron-right",2,"color","var(--text-muted)","flex-shrink","0",3,"size"]],template:function(e,r){e&1&&g(0,se,1,0,"app-pick-project-empty",0)(1,We,26,9,"div",1),e&2&&u(r.status.state().noProject?0:1)},dependencies:[ne,ie,ee,te,ae,oe],styles:["[_nghost-%COMP%]{display:contents}.gp-root[_ngcontent-%COMP%]{flex:1;display:flex;min-height:0;min-width:0}.gp-main[_ngcontent-%COMP%]{flex:1;min-width:0;display:flex;flex-direction:column}.gp-toolbar[_ngcontent-%COMP%]{display:flex;align-items:center;gap:10px;padding:9px 14px;border-bottom:1px solid var(--border-subtle);background:var(--bg-panel-2, var(--bg-panel));flex-wrap:wrap;flex-shrink:0}.gp-divider[_ngcontent-%COMP%]{width:1px;height:20px;background:var(--border-subtle);flex-shrink:0}.gp-chip[_ngcontent-%COMP%]{display:flex;align-items:center;gap:6px;height:26px;padding:0 10px;border-radius:999px;font-size:11.5px;font-weight:500;cursor:pointer;border:1px solid var(--border-subtle);background:var(--bg-panel);color:var(--text-secondary);transition:all .1s}.gp-chip.is-active[_ngcontent-%COMP%]{border-color:transparent;background:color-mix(in srgb,var(--chip-color, var(--accent)) 22%,var(--bg-panel));color:var(--chip-color, var(--accent))}.gp-chip-dot[_ngcontent-%COMP%]{width:7px;height:7px;border-radius:50%}.gp-chip-dot[data-kind=code][_ngcontent-%COMP%]{background:var(--node-code)}.gp-chip-dot[data-kind=spec][_ngcontent-%COMP%]{background:var(--node-spec);border-radius:2px}.gp-chip-dot[data-kind=route][_ngcontent-%COMP%]{background:var(--node-route)}.gp-chip-dot[data-kind=test][_ngcontent-%COMP%]{background:var(--node-test)}.gp-chip-count[_ngcontent-%COMP%]{font-size:10.5px;color:var(--text-muted);font-variant-numeric:tabular-nums}.gp-spacer[_ngcontent-%COMP%]{flex:1}.gp-search[_ngcontent-%COMP%]{position:relative;flex-shrink:0}.gp-search-inner[_ngcontent-%COMP%]{display:flex;align-items:center;gap:6px;height:28px;padding:0 10px;background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:7px;width:220px}.gp-search-inner[_ngcontent-%COMP%] input[_ngcontent-%COMP%]{flex:1;background:transparent;border:none;outline:none;color:var(--text-primary);font-size:12px;font-family:var(--font-mono)}.gp-search-icon[_ngcontent-%COMP%]{color:var(--text-muted);flex-shrink:0}.gp-spinner[_ngcontent-%COMP%]{width:12px;height:12px;border:2px solid var(--border-subtle);border-top-color:var(--accent);border-radius:50%;animation:_ngcontent-%COMP%_gp-spin .7s linear infinite;flex-shrink:0}@keyframes _ngcontent-%COMP%_gp-spin{to{transform:rotate(360deg)}}.gp-results[_ngcontent-%COMP%]{position:absolute;top:32px;left:0;right:0;background:var(--bg-elevated);border:1px solid var(--border-strong);border-radius:8px;box-shadow:var(--shadow-pop, 0 12px 28px rgba(0, 0, 0, .5));padding:5px;z-index:30;max-height:320px;overflow-y:auto}.gp-result[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;width:100%;padding:6px 8px;border-radius:5px;background:transparent;border:none;cursor:pointer;font:inherit;color:var(--text-primary);text-align:left}.gp-result[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.gp-result-dot[_ngcontent-%COMP%]{width:7px;height:7px;border-radius:50%;background:var(--node-code);flex-shrink:0}.gp-result-dot.is-spec[_ngcontent-%COMP%]{background:var(--node-spec);border-radius:2px}.gp-result-dot.is-route[_ngcontent-%COMP%]{background:var(--node-route)}.gp-result-dot.is-test[_ngcontent-%COMP%]{background:var(--node-test)}.gp-result-name[_ngcontent-%COMP%]{font-size:12px;flex-shrink:0}.gp-result-kind[_ngcontent-%COMP%]{font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted)}.gp-result-path[_ngcontent-%COMP%]{flex:1;text-align:right;font-size:10px;color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gp-canvas-wrap[_ngcontent-%COMP%]{flex:1;min-height:0;position:relative;display:flex}.gp-canvas-wrap[_ngcontent-%COMP%] app-graph-canvas[_ngcontent-%COMP%]{flex:1;min-height:0}.gp-empty[_ngcontent-%COMP%]{flex:1;display:grid;place-items:center;text-align:center;padding:60px 24px;background:var(--bg-canvas-2, var(--bg-canvas))}.gp-empty[_ngcontent-%COMP%] h3[_ngcontent-%COMP%]{font-size:18px;font-weight:600;margin:0 0 8px}.gp-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{color:var(--text-secondary);font-size:13.5px;line-height:1.6;margin:0;max-width:520px}.gp-stats[_ngcontent-%COMP%]{margin-top:18px!important;font-family:var(--font-mono);font-size:11.5px!important;color:var(--text-muted)!important}.gp-legend[_ngcontent-%COMP%]{position:absolute;top:14px;left:14px;display:flex;align-items:center;gap:12px;flex-wrap:wrap;max-width:70%;background:color-mix(in srgb,var(--bg-panel) 86%,transparent);border:1px solid var(--border-subtle);border-radius:8px;padding:6px 10px;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);font-size:11px;pointer-events:none;z-index:3}.gp-legend-kinds[_ngcontent-%COMP%]{display:flex;align-items:center;gap:12px}.gp-legend-item[_ngcontent-%COMP%]{display:flex;align-items:center;gap:4px}.gp-legend-dot[_ngcontent-%COMP%]{width:8px;height:8px;border-radius:50%;flex-shrink:0}.gp-legend-dot[data-kind=code][_ngcontent-%COMP%]{background:var(--node-code)}.gp-legend-dot[data-kind=spec][_ngcontent-%COMP%]{background:var(--node-spec);border-radius:2px}.gp-legend-dot[data-kind=route][_ngcontent-%COMP%]{background:var(--node-route)}.gp-legend-dot[data-kind=test][_ngcontent-%COMP%]{background:var(--node-test)}.gp-legend-sep[_ngcontent-%COMP%]{width:1px;height:16px;background:var(--border-subtle);flex-shrink:0}.gp-legend-edges[_ngcontent-%COMP%]{display:flex;align-items:center;gap:10px}.gp-legend-edge-row[_ngcontent-%COMP%]{display:flex;align-items:center;gap:4px}.gp-panel[_ngcontent-%COMP%]{width:360px;flex-shrink:0;border-left:1px solid var(--border-subtle);background:var(--bg-panel);display:flex;flex-direction:column;overflow:hidden}.gp-panel-header[_ngcontent-%COMP%]{padding:12px 14px;border-bottom:1px solid var(--border-subtle);flex-shrink:0}.gp-panel-header-inner[_ngcontent-%COMP%]{display:flex;align-items:flex-start;gap:8px}.gp-overview-head[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px}.gp-node-dot[_ngcontent-%COMP%]{width:9px;height:9px;border-radius:50%;flex-shrink:0;margin-top:5px}.gp-node-dot.is-rect[_ngcontent-%COMP%]{border-radius:2px}.gp-panel-name[_ngcontent-%COMP%]{font-size:14px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gp-panel-path[_ngcontent-%COMP%]{margin-top:8px;font-size:11.5px;color:var(--text-secondary)}.gp-path-text[_ngcontent-%COMP%]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.gp-panel-body[_ngcontent-%COMP%]{flex:1;padding:14px;overflow-y:auto;display:flex;flex-direction:column;gap:18px}.gp-section[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:4px}.gp-section-plain[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:2px}.gp-eyebrow[_ngcontent-%COMP%]{font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-muted);margin-bottom:6px}.gp-code[_ngcontent-%COMP%]{margin:0;font-size:11.5px;line-height:1.6;color:var(--text-secondary);background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:7px;padding:10px;overflow-x:auto;white-space:pre-wrap;word-break:break-word}.gp-link-row[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:6px;border:1px solid var(--border-subtle);margin-bottom:5px;font-size:11.5px}.gp-link-text[_ngcontent-%COMP%]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px}.gp-node-link[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;width:100%;padding:5px 8px;border-radius:6px;border:none;background:transparent;cursor:pointer;font:inherit;color:inherit;text-align:left;font-size:12px}.gp-node-link[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.gp-link-file[_ngcontent-%COMP%]{font-size:10px;flex-shrink:0}.gp-edge-row[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;padding:4px 0}.gp-kind-row[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;padding:5px 0}.gp-kind-dot[_ngcontent-%COMP%]{width:9px;height:9px;border-radius:50%;flex-shrink:0}.gp-kind-dot[data-kind=code][_ngcontent-%COMP%]{background:var(--node-code);box-shadow:0 0 6px var(--node-code)}.gp-kind-dot[data-kind=spec][_ngcontent-%COMP%]{background:var(--node-spec);border-radius:2px;box-shadow:0 0 6px var(--node-spec)}.gp-kind-dot[data-kind=route][_ngcontent-%COMP%]{background:var(--node-route);box-shadow:0 0 6px var(--node-route)}.gp-kind-dot[data-kind=test][_ngcontent-%COMP%]{background:var(--node-test);box-shadow:0 0 6px var(--node-test)}.gp-panel-footer[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;padding:12px 14px;border-top:1px solid var(--border-subtle);flex-shrink:0}.gp-hub-row[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;width:100%;padding:5px 8px;border-radius:6px;border:none;background:transparent;cursor:pointer;font:inherit;color:inherit;text-align:left}.gp-hub-row[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.gp-hub-dot[_ngcontent-%COMP%]{width:8px;height:8px;flex-shrink:0}.gp-hub-name[_ngcontent-%COMP%]{font-size:11.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gp-hub-degree[_ngcontent-%COMP%]{font-size:10.5px;color:var(--text-muted);flex-shrink:0;font-variant-numeric:tabular-nums}@keyframes _ngcontent-%COMP%_gp-skel-pulse{0%,to{opacity:.35}50%{opacity:.7}}.gp-skel[_ngcontent-%COMP%]{display:inline-block;background:var(--border-subtle);border-radius:4px;animation:_ngcontent-%COMP%_gp-skel-pulse 1.4s ease-in-out infinite}.gp-skel-sm[_ngcontent-%COMP%]{width:24px;height:12px}.gp-skel-lg[_ngcontent-%COMP%]{width:80px;height:12px;flex:1}.gp-skel-hub[_ngcontent-%COMP%]{width:120px;height:12px;flex:1}.gp-skel-dot[_ngcontent-%COMP%]{width:8px;height:8px;border-radius:50%;flex-shrink:0;background:var(--border-subtle);animation:_ngcontent-%COMP%_gp-skel-pulse 1.4s ease-in-out infinite}.grow[_ngcontent-%COMP%]{flex:1}.muted[_ngcontent-%COMP%]{color:var(--text-muted)}.mono[_ngcontent-%COMP%]{font-family:var(--font-mono)}"],changeDetection:0})};function le(t,n,e){return{id:t.id,label:t.name,sub:H(t.filePath),kind:t.kind,x:n,y:e}}function H(t){return t?t.split("/").slice(-2).join("/"):""}function F(t){return t==="spec"?"spec":t==="route"?"route":t==="test"?"test":"code"}export{re as Graph};
@@ -1,2 +1,2 @@
1
- import{a as X}from"./chunk-SEXBRGYK.js";import{a as L,b as J,c as Q}from"./chunk-T66XVKGB.js";import{a as G}from"./chunk-DTRN7FZR.js";import{a as W}from"./chunk-UYC52MBC.js";import{a as q}from"./chunk-SUZYBYDW.js";import{b as T}from"./chunk-4N5DWG46.js";import"./chunk-7RNS77UP.js";import{a as K}from"./chunk-E44X4RH2.js";import{Aa as p,Ea as P,Fa as N,Ga as E,I as H,Ia as w,Ka as c,M as C,N as S,Ta as k,Ua as R,Va as o,W as M,Wa as u,Xa as v,Ya as z,bb as f,db as O,ea as a,fb as $,gb as V,hb as j,ka as F,lb as x,ra as _,sa as h,ta as I,va as b,vb as A,wa as y,xa as m,ya as i,za as n,zb as U}from"./chunk-PDN6QYGJ.js";import"./chunk-Q7L6LLAK.js";var te=()=>({value:"today",label:"Today"}),ne=()=>({value:"week",label:"This week"}),ie=()=>({value:"month",label:"This month"}),ae=()=>({value:"all",label:"All time"}),oe=(r,e,t,l)=>[r,e,t,l],le=()=>({value:"calls",label:"Calls"}),re=()=>({value:"tokens",label:"Tokens"}),de=(r,e)=>[r,e],se=()=>[],Z=(r,e)=>e.name,ee=(r,e)=>e.session_id;function pe(r,e){r&1&&(i(0,"div",23),o(1,"No file-targeted tool calls in this window."),n())}function me(r,e){if(r&1){let t=E();i(0,"app-treemap",45),w("pick",function(s){C(t);let d=c();return S(d.openFile(s))}),n(),i(1,"div",46)(2,"span",47),o(3,"tokens / call"),n(),p(4,"div",48),i(5,"span",49),o(6,"efficient \u2192 wasteful"),n(),p(7,"div",22),i(8,"span",47),o(9,"click a tile to drill in"),n()()}if(r&2){let t,l=c();m("items",l.treemapItems())("height",268)("selKey",((t=l.drill())==null?null:t.kind)==="file"?l.drill().key:null)}}function ce(r,e){if(r&1){let t=E();i(0,"button",50),w("click",function(){let s=C(t).$implicit,d=c();return S(d.openToolByName(s.name))}),i(1,"span",51),o(2),n(),i(3,"div",52),p(4,"div",53),n(),i(5,"span",54),o(6),n(),i(7,"span",55),o(8),n(),i(9,"span",56),o(10),n(),p(11,"app-icon",57),n()}if(r&2){let t,l,s=e.$implicit,d=c();R("sel",((t=d.drill())==null?null:t.kind)==="tool"&&d.drill().key===s.name),a(),k("color",((l=d.drill())==null?null:l.kind)==="tool"&&d.drill().key===s.name?"var(--accent)":"var(--text-secondary)"),a(),u(s.name),a(2),k("width",s.resultBytes/d.maxToolTokens()*100,"%")("background",d.effColor(s.resultBytes/d.Math.max(1,s.calls))),a(2),v("\xD7",s.calls),a(),k("color",d.effColor(s.resultBytes/d.Math.max(1,s.calls))),a(),v("",d.fmtTokens(d.Math.round(s.resultBytes/d.Math.max(1,s.calls))),"/call"),a(2),u(d.fmtTokens(s.resultBytes)),a(),m("size",12)}}function ue(r,e){r&1&&(i(0,"div",23),o(1,"No Task tool calls \u2014 no subagents dispatched."),n())}function xe(r,e){if(r&1){let t=E();i(0,"app-h-bars",58),w("itemClick",function(s){C(t);let d=c();return S(d.openSubagent(s.name))}),n()}if(r&2){let t,l=c();m("items",l.subagentByName())("fmt",l.fmtTokens)("selectedKey",((t=l.drill())==null?null:t.kind)==="subagent"?l.drill().key:null)}}function ge(r,e){r&1&&(i(0,"div",65),o(1,"Loading\u2026"),n())}function ve(r,e){if(r&1&&(i(0,"div",73)(1,"span",78),o(2),n(),i(3,"div",22),p(4,"app-bar",79),n(),i(5,"span",80),o(6),n(),i(7,"span",81),o(8),n()()),r&2){let t=e.$implicit,l=c(),s=c(2);a(2),u(t.name),a(2),m("frac",t.bytes/s.Math.max(1,l.byTool[0].bytes))("color",t.bytes>4e4?"var(--error)":t.bytes>12e3?"var(--warn)":"var(--node-code)"),a(2),v("\xD7",t.calls),a(2),u(s.fmtTokens(t.bytes))}}function _e(r,e){if(r&1&&(i(0,"div",75)(1,"span",82),o(2),n(),i(3,"span",83),o(4),n(),p(5,"app-icon",84),n()),r&2){let t,l=e.$implicit,s=c(3);a(2),u(s.shortId(l.session_id)),a(2),z(" ",(l.project_path==null||(t=l.project_path.split("/"))==null?null:t.pop())||""," \xB7 ",s.timeAgo(l.lastTs)," "),a(),m("size",12)}}function he(r,e){if(r&1&&(i(0,"div",66)(1,"div",67)(2,"div")(3,"div",47),o(4,"Tool calls"),n(),i(5,"div",68),o(6),n()(),i(7,"div",22)(8,"div",69),o(9,"7-day trend"),n(),p(10,"app-sparkline",70),n()(),i(11,"div",71),o(12,"Tool breakdown"),n(),i(13,"div",72),b(14,ve,9,5,"div",73,Z),n(),i(16,"div",71),o(17),n(),i(18,"div",74),b(19,_e,6,4,"div",75,ee),n(),i(21,"button",76),p(22,"app-icon",77),o(23,"Reveal in editor "),n()()),r&2){let t=e,l=c(),s=c();a(6),u(s.fileTotalCalls(t.sessions)),a(4),m("data",s.fileTrendFor(l.key))("fill",!0)("width",150)("height",30),a(4),y(t.byTool),a(3),z("Touched in ",t.sessions.length," session",t.sessions.length!==1?"s":""),a(2),y(t.sessions),a(3),m("size",13)}}function fe(r,e){if(r&1&&(i(0,"div",60)(1,"span",93),o(2),n(),i(3,"span",94),o(4),n(),i(5,"span",95),o(6),n()()),r&2){let t=e.$implicit,l=c(3);a(2),u(l.truncate(t.input,140)),a(2),v("\xD7",t.calls),a(2),u(l.fmtTokens(t.bytes))}}function be(r,e){r&1&&(i(0,"div",91),o(1,"No inputs captured."),n())}function ye(r,e){if(r&1&&(i(0,"div",75)(1,"span",82),o(2),n(),i(3,"span",83),o(4),n(),p(5,"app-icon",84),n()),r&2){let t,l=e.$implicit,s=c(3);a(2),u(s.shortId(l.session_id)),a(2),z(" ",(l.project_path==null||(t=l.project_path.split("/"))==null?null:t.pop())||""," \xB7 ",s.timeAgo(l.lastTs)," "),a(),m("size",12)}}function we(r,e){if(r&1&&(i(0,"div",66)(1,"div",85)(2,"div")(3,"div",47),o(4,"Calls"),n(),i(5,"div",86),o(6),n()(),i(7,"div")(8,"div",47),o(9,"Result tokens"),n(),i(10,"div",86),o(11),n()(),i(12,"div",22)(13,"div",69),o(14,"7-day"),n(),p(15,"app-sparkline",87),n()(),i(16,"div",88)(17,"span",21),o(18,"avg per call"),n(),i(19,"span",89),o(20),n()(),i(21,"div",71),o(22,"Top inputs"),n(),i(23,"div",90),b(24,fe,7,3,"div",60,I,!1,be,2,0,"div",91),n(),i(27,"div",71),o(28),n(),i(29,"div",92),b(30,ye,6,4,"div",75,ee),n()()),r&2){let t=e,l=c(2);a(6),u(t.totals.calls),a(4),k("color",t.totals.bytes>1e6?"var(--error)":"var(--text-primary)"),a(),u(l.fmtTokens(t.totals.bytes)),a(4),m("data",f(13,se))("fill",!0)("width",110)("height",28),a(4),k("color",t.totals.calls>0&&t.totals.bytes/t.totals.calls>3e4?"var(--error)":t.totals.calls>0&&t.totals.bytes/t.totals.calls>8e3?"var(--warn)":"var(--text-secondary)"),a(),v(" ",l.fmtTokens(t.totals.calls>0?l.Math.round(t.totals.bytes/t.totals.calls):0)," tokens "),a(4),y(t.inputs),a(4),v("Used in ",t.totals.sessions," sessions"),a(2),y(t.recentSessions)}}function ke(r,e){if(r&1&&(i(0,"div",104),o(1),n()),r&2){let t=c().$implicit,l=c(3);a(),u(l.truncate(t.description,160))}}function Ce(r,e){if(r&1&&(i(0,"div",105),o(1),n()),r&2){let t=c().$implicit,l=c(3);a(),u(l.truncate(t.prompt,200))}}function Se(r,e){if(r&1&&(i(0,"div",98)(1,"div",101)(2,"span",102),o(3),n(),i(4,"span",103),o(5),n()(),_(6,ke,2,1,"div",104),_(7,Ce,2,1,"div",105),n()),r&2){let t=e.$implicit,l=c(3);a(3),u(l.shortId(t.session_id)),a(2),u(l.timeAgo(t.ts)),a(),h(t.description?6:-1),a(),h(t.prompt?7:-1)}}function Ee(r,e){r&1&&(i(0,"div",99),o(1,"No invocations in window."),n())}function Te(r,e){if(r&1&&(i(0,"div",66)(1,"div",85)(2,"div")(3,"div",47),o(4,"Invocations"),n(),i(5,"div",96),o(6),n()(),i(7,"div")(8,"div",47),o(9,"Sessions"),n(),i(10,"div",96),o(11),n()()(),i(12,"div",71),o(13,"Invocations"),n(),i(14,"div",97),b(15,Se,8,4,"div",98,I,!1,Ee,2,0,"div",99),n(),i(18,"button",76),p(19,"app-icon",100),o(20,"See related tips "),n()()),r&2){let t=e;a(6),u(t.totals.calls),a(5),u(t.totals.sessions),a(4),y(t.invocations),a(4),m("size",13)}}function Me(r,e){if(r&1){let t=E();i(0,"aside",44)(1,"header",59)(2,"div",60),p(3,"app-icon",61),i(4,"span",62),o(5),n()(),i(6,"button",63),w("click",function(){C(t);let s=c();return S(s.closeDrill())}),p(7,"app-icon",64),n()(),_(8,ge,2,0,"div",65),_(9,he,24,8,"div",66),_(10,we,32,14,"div",66),_(11,Te,21,4,"div",66),n()}if(r&2){let t,l,s,d=e,g=c();a(3),k("color",d.kind==="file"?"var(--warn)":d.kind==="tool"?"var(--node-code)":"var(--node-route)"),m("name",d.kind==="file"?"box":d.kind==="tool"?"wrench":"bot")("size",14),a(2),u(g.drillTitle()),a(2),m("size",14),a(),h(g.drillLoading()?8:-1),a(),h((t=d.kind==="file"&&g.fileDrill.state().data)?9:-1,t),a(),h((l=d.kind==="tool"&&g.toolDrill.state().data)?10:-1,l),a(),h((s=d.kind==="subagent"&&g.subagentDrill.state().data)?11:-1,s)}}var Y=class r{Math=Math;api=H(K);range=M("week");metric=M("calls");resource=T(this.api,()=>`/api/claude/heatmap?range=${this.range()}`);files=x(()=>this.resource.state().data?.files??[]);tools=x(()=>this.resource.state().data?.tools??[]);subagents=x(()=>this.resource.state().data?.subagents??[]);subagentByName=x(()=>this.resource.state().data?.subagentByName??[]);totalCalls=x(()=>this.tools().reduce((e,t)=>e+t.calls,0));totalResultTokens=x(()=>this.tools().reduce((e,t)=>e+(t.resultBytes||0),0));busiestFile=x(()=>[...this.files()].sort((e,t)=>t.calls-e.calls)[0]??null);heaviestTool=x(()=>[...this.tools()].sort((e,t)=>(t.resultBytes||0)-(e.resultBytes||0))[0]??null);toolsByTokens=x(()=>[...this.tools()].sort((e,t)=>(t.resultBytes||0)-(e.resultBytes||0)));maxToolTokens=x(()=>Math.max(1,...this.toolsByTokens().map(e=>e.resultBytes||0)));treemapItems=x(()=>{let e=this.metric(),t=d=>e==="tokens"?d.resultBytes||0:d.calls,l=[...this.files()].sort((d,g)=>t(g)-t(d)).slice(0,48);if(!l.length)return[];let s=Math.max(1,...l.map(d=>(d.resultBytes||0)/Math.max(1,d.calls)));return l.map(d=>{let g=(d.resultBytes||0)/Math.max(1,d.calls);return{key:d.path,label:L(d.path),value:t(d),intensity:g/s,sub:e==="tokens"?this.fmtTokens(d.resultBytes||0):d.calls+" calls",title:`${d.path}
1
+ import{a as X}from"./chunk-SEXBRGYK.js";import{a as L,b as J,c as Q}from"./chunk-T66XVKGB.js";import{a as G}from"./chunk-DTRN7FZR.js";import{a as W}from"./chunk-UYC52MBC.js";import{a as q}from"./chunk-SUZYBYDW.js";import{c as T}from"./chunk-GR72OOCN.js";import"./chunk-7RNS77UP.js";import{a as K}from"./chunk-E44X4RH2.js";import{Aa as p,Ea as P,Fa as N,Ga as E,I as H,Ia as w,Ka as c,M as C,N as S,Ta as k,Ua as R,Va as o,W as M,Wa as u,Xa as v,Ya as z,bb as f,db as O,ea as a,fb as $,gb as V,hb as j,ka as F,lb as x,ra as _,sa as h,ta as I,va as b,vb as A,wa as y,xa as m,ya as i,za as n,zb as U}from"./chunk-PDN6QYGJ.js";import"./chunk-Q7L6LLAK.js";var te=()=>({value:"today",label:"Today"}),ne=()=>({value:"week",label:"This week"}),ie=()=>({value:"month",label:"This month"}),ae=()=>({value:"all",label:"All time"}),oe=(r,e,t,l)=>[r,e,t,l],le=()=>({value:"calls",label:"Calls"}),re=()=>({value:"tokens",label:"Tokens"}),de=(r,e)=>[r,e],se=()=>[],Z=(r,e)=>e.name,ee=(r,e)=>e.session_id;function pe(r,e){r&1&&(i(0,"div",23),o(1,"No file-targeted tool calls in this window."),n())}function me(r,e){if(r&1){let t=E();i(0,"app-treemap",45),w("pick",function(s){C(t);let d=c();return S(d.openFile(s))}),n(),i(1,"div",46)(2,"span",47),o(3,"tokens / call"),n(),p(4,"div",48),i(5,"span",49),o(6,"efficient \u2192 wasteful"),n(),p(7,"div",22),i(8,"span",47),o(9,"click a tile to drill in"),n()()}if(r&2){let t,l=c();m("items",l.treemapItems())("height",268)("selKey",((t=l.drill())==null?null:t.kind)==="file"?l.drill().key:null)}}function ce(r,e){if(r&1){let t=E();i(0,"button",50),w("click",function(){let s=C(t).$implicit,d=c();return S(d.openToolByName(s.name))}),i(1,"span",51),o(2),n(),i(3,"div",52),p(4,"div",53),n(),i(5,"span",54),o(6),n(),i(7,"span",55),o(8),n(),i(9,"span",56),o(10),n(),p(11,"app-icon",57),n()}if(r&2){let t,l,s=e.$implicit,d=c();R("sel",((t=d.drill())==null?null:t.kind)==="tool"&&d.drill().key===s.name),a(),k("color",((l=d.drill())==null?null:l.kind)==="tool"&&d.drill().key===s.name?"var(--accent)":"var(--text-secondary)"),a(),u(s.name),a(2),k("width",s.resultBytes/d.maxToolTokens()*100,"%")("background",d.effColor(s.resultBytes/d.Math.max(1,s.calls))),a(2),v("\xD7",s.calls),a(),k("color",d.effColor(s.resultBytes/d.Math.max(1,s.calls))),a(),v("",d.fmtTokens(d.Math.round(s.resultBytes/d.Math.max(1,s.calls))),"/call"),a(2),u(d.fmtTokens(s.resultBytes)),a(),m("size",12)}}function ue(r,e){r&1&&(i(0,"div",23),o(1,"No Task tool calls \u2014 no subagents dispatched."),n())}function xe(r,e){if(r&1){let t=E();i(0,"app-h-bars",58),w("itemClick",function(s){C(t);let d=c();return S(d.openSubagent(s.name))}),n()}if(r&2){let t,l=c();m("items",l.subagentByName())("fmt",l.fmtTokens)("selectedKey",((t=l.drill())==null?null:t.kind)==="subagent"?l.drill().key:null)}}function ge(r,e){r&1&&(i(0,"div",65),o(1,"Loading\u2026"),n())}function ve(r,e){if(r&1&&(i(0,"div",73)(1,"span",78),o(2),n(),i(3,"div",22),p(4,"app-bar",79),n(),i(5,"span",80),o(6),n(),i(7,"span",81),o(8),n()()),r&2){let t=e.$implicit,l=c(),s=c(2);a(2),u(t.name),a(2),m("frac",t.bytes/s.Math.max(1,l.byTool[0].bytes))("color",t.bytes>4e4?"var(--error)":t.bytes>12e3?"var(--warn)":"var(--node-code)"),a(2),v("\xD7",t.calls),a(2),u(s.fmtTokens(t.bytes))}}function _e(r,e){if(r&1&&(i(0,"div",75)(1,"span",82),o(2),n(),i(3,"span",83),o(4),n(),p(5,"app-icon",84),n()),r&2){let t,l=e.$implicit,s=c(3);a(2),u(s.shortId(l.session_id)),a(2),z(" ",(l.project_path==null||(t=l.project_path.split("/"))==null?null:t.pop())||""," \xB7 ",s.timeAgo(l.lastTs)," "),a(),m("size",12)}}function he(r,e){if(r&1&&(i(0,"div",66)(1,"div",67)(2,"div")(3,"div",47),o(4,"Tool calls"),n(),i(5,"div",68),o(6),n()(),i(7,"div",22)(8,"div",69),o(9,"7-day trend"),n(),p(10,"app-sparkline",70),n()(),i(11,"div",71),o(12,"Tool breakdown"),n(),i(13,"div",72),b(14,ve,9,5,"div",73,Z),n(),i(16,"div",71),o(17),n(),i(18,"div",74),b(19,_e,6,4,"div",75,ee),n(),i(21,"button",76),p(22,"app-icon",77),o(23,"Reveal in editor "),n()()),r&2){let t=e,l=c(),s=c();a(6),u(s.fileTotalCalls(t.sessions)),a(4),m("data",s.fileTrendFor(l.key))("fill",!0)("width",150)("height",30),a(4),y(t.byTool),a(3),z("Touched in ",t.sessions.length," session",t.sessions.length!==1?"s":""),a(2),y(t.sessions),a(3),m("size",13)}}function fe(r,e){if(r&1&&(i(0,"div",60)(1,"span",93),o(2),n(),i(3,"span",94),o(4),n(),i(5,"span",95),o(6),n()()),r&2){let t=e.$implicit,l=c(3);a(2),u(l.truncate(t.input,140)),a(2),v("\xD7",t.calls),a(2),u(l.fmtTokens(t.bytes))}}function be(r,e){r&1&&(i(0,"div",91),o(1,"No inputs captured."),n())}function ye(r,e){if(r&1&&(i(0,"div",75)(1,"span",82),o(2),n(),i(3,"span",83),o(4),n(),p(5,"app-icon",84),n()),r&2){let t,l=e.$implicit,s=c(3);a(2),u(s.shortId(l.session_id)),a(2),z(" ",(l.project_path==null||(t=l.project_path.split("/"))==null?null:t.pop())||""," \xB7 ",s.timeAgo(l.lastTs)," "),a(),m("size",12)}}function we(r,e){if(r&1&&(i(0,"div",66)(1,"div",85)(2,"div")(3,"div",47),o(4,"Calls"),n(),i(5,"div",86),o(6),n()(),i(7,"div")(8,"div",47),o(9,"Result tokens"),n(),i(10,"div",86),o(11),n()(),i(12,"div",22)(13,"div",69),o(14,"7-day"),n(),p(15,"app-sparkline",87),n()(),i(16,"div",88)(17,"span",21),o(18,"avg per call"),n(),i(19,"span",89),o(20),n()(),i(21,"div",71),o(22,"Top inputs"),n(),i(23,"div",90),b(24,fe,7,3,"div",60,I,!1,be,2,0,"div",91),n(),i(27,"div",71),o(28),n(),i(29,"div",92),b(30,ye,6,4,"div",75,ee),n()()),r&2){let t=e,l=c(2);a(6),u(t.totals.calls),a(4),k("color",t.totals.bytes>1e6?"var(--error)":"var(--text-primary)"),a(),u(l.fmtTokens(t.totals.bytes)),a(4),m("data",f(13,se))("fill",!0)("width",110)("height",28),a(4),k("color",t.totals.calls>0&&t.totals.bytes/t.totals.calls>3e4?"var(--error)":t.totals.calls>0&&t.totals.bytes/t.totals.calls>8e3?"var(--warn)":"var(--text-secondary)"),a(),v(" ",l.fmtTokens(t.totals.calls>0?l.Math.round(t.totals.bytes/t.totals.calls):0)," tokens "),a(4),y(t.inputs),a(4),v("Used in ",t.totals.sessions," sessions"),a(2),y(t.recentSessions)}}function ke(r,e){if(r&1&&(i(0,"div",104),o(1),n()),r&2){let t=c().$implicit,l=c(3);a(),u(l.truncate(t.description,160))}}function Ce(r,e){if(r&1&&(i(0,"div",105),o(1),n()),r&2){let t=c().$implicit,l=c(3);a(),u(l.truncate(t.prompt,200))}}function Se(r,e){if(r&1&&(i(0,"div",98)(1,"div",101)(2,"span",102),o(3),n(),i(4,"span",103),o(5),n()(),_(6,ke,2,1,"div",104),_(7,Ce,2,1,"div",105),n()),r&2){let t=e.$implicit,l=c(3);a(3),u(l.shortId(t.session_id)),a(2),u(l.timeAgo(t.ts)),a(),h(t.description?6:-1),a(),h(t.prompt?7:-1)}}function Ee(r,e){r&1&&(i(0,"div",99),o(1,"No invocations in window."),n())}function Te(r,e){if(r&1&&(i(0,"div",66)(1,"div",85)(2,"div")(3,"div",47),o(4,"Invocations"),n(),i(5,"div",96),o(6),n()(),i(7,"div")(8,"div",47),o(9,"Sessions"),n(),i(10,"div",96),o(11),n()()(),i(12,"div",71),o(13,"Invocations"),n(),i(14,"div",97),b(15,Se,8,4,"div",98,I,!1,Ee,2,0,"div",99),n(),i(18,"button",76),p(19,"app-icon",100),o(20,"See related tips "),n()()),r&2){let t=e;a(6),u(t.totals.calls),a(5),u(t.totals.sessions),a(4),y(t.invocations),a(4),m("size",13)}}function Me(r,e){if(r&1){let t=E();i(0,"aside",44)(1,"header",59)(2,"div",60),p(3,"app-icon",61),i(4,"span",62),o(5),n()(),i(6,"button",63),w("click",function(){C(t);let s=c();return S(s.closeDrill())}),p(7,"app-icon",64),n()(),_(8,ge,2,0,"div",65),_(9,he,24,8,"div",66),_(10,we,32,14,"div",66),_(11,Te,21,4,"div",66),n()}if(r&2){let t,l,s,d=e,g=c();a(3),k("color",d.kind==="file"?"var(--warn)":d.kind==="tool"?"var(--node-code)":"var(--node-route)"),m("name",d.kind==="file"?"box":d.kind==="tool"?"wrench":"bot")("size",14),a(2),u(g.drillTitle()),a(2),m("size",14),a(),h(g.drillLoading()?8:-1),a(),h((t=d.kind==="file"&&g.fileDrill.state().data)?9:-1,t),a(),h((l=d.kind==="tool"&&g.toolDrill.state().data)?10:-1,l),a(),h((s=d.kind==="subagent"&&g.subagentDrill.state().data)?11:-1,s)}}var Y=class r{Math=Math;api=H(K);range=M("week");metric=M("calls");resource=T(this.api,()=>`/api/claude/heatmap?range=${this.range()}`);files=x(()=>this.resource.state().data?.files??[]);tools=x(()=>this.resource.state().data?.tools??[]);subagents=x(()=>this.resource.state().data?.subagents??[]);subagentByName=x(()=>this.resource.state().data?.subagentByName??[]);totalCalls=x(()=>this.tools().reduce((e,t)=>e+t.calls,0));totalResultTokens=x(()=>this.tools().reduce((e,t)=>e+(t.resultBytes||0),0));busiestFile=x(()=>[...this.files()].sort((e,t)=>t.calls-e.calls)[0]??null);heaviestTool=x(()=>[...this.tools()].sort((e,t)=>(t.resultBytes||0)-(e.resultBytes||0))[0]??null);toolsByTokens=x(()=>[...this.tools()].sort((e,t)=>(t.resultBytes||0)-(e.resultBytes||0)));maxToolTokens=x(()=>Math.max(1,...this.toolsByTokens().map(e=>e.resultBytes||0)));treemapItems=x(()=>{let e=this.metric(),t=d=>e==="tokens"?d.resultBytes||0:d.calls,l=[...this.files()].sort((d,g)=>t(g)-t(d)).slice(0,48);if(!l.length)return[];let s=Math.max(1,...l.map(d=>(d.resultBytes||0)/Math.max(1,d.calls)));return l.map(d=>{let g=(d.resultBytes||0)/Math.max(1,d.calls);return{key:d.path,label:L(d.path),value:t(d),intensity:g/s,sub:e==="tokens"?this.fmtTokens(d.resultBytes||0):d.calls+" calls",title:`${d.path}
2
2
  ${d.calls} calls \xB7 ${this.fmtTokens(d.resultBytes||0)} result tokens \xB7 ${this.fmtTokens(Math.round(g))}/call`}})});drill=M(null);fileDrill=T(this.api,()=>{let e=this.drill();return e?.kind==="file"?`/api/claude/heatmap/file?path=${encodeURIComponent(e.key)}&range=${this.range()}`:null});toolDrill=T(this.api,()=>{let e=this.drill();return e?.kind==="tool"?`/api/claude/heatmap/tool?name=${encodeURIComponent(e.key)}&range=${this.range()}`:null});subagentDrill=T(this.api,()=>{let e=this.drill();return e?.kind==="subagent"?`/api/claude/heatmap/subagent?type=${encodeURIComponent(e.key)}&range=${this.range()}`:null});drillTitle=x(()=>{let e=this.drill();return e?e.key:""});drillLoading=x(()=>{let e=this.drill();return e?e.kind==="file"?this.fileDrill.state().loading:e.kind==="tool"?this.toolDrill.state().loading:this.subagentDrill.state().loading:!1});setRange(e){this.range.set(e)}setMetric(e){this.metric.set(e)}openFile(e){this.drill.set({kind:"file",key:e})}openToolByName(e){this.drill.set({kind:"tool",key:e})}openSubagent(e){this.drill.set({kind:"subagent",key:e})}closeDrill(){this.drill.set(null)}fileTrendFor(e){return this.files().find(t=>t.path===e)?.trend??[]}fileTotalCalls(e){return e.reduce((t,l)=>t+l.calls,0)}effColor(e){return e>2e4?"var(--error)":e>8e3?"var(--warn)":"var(--success)"}fmtTokens=e=>e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(0)+"k":String(e);fmtBytes(e){return e>=1e6?(e/1e6).toFixed(1)+"MB":e>=1e3?(e/1e3).toFixed(0)+"kB":e+"B"}timeAgo(e){let t=Date.now()-e;return t<6e4?"just now":t<36e5?Math.round(t/6e4)+"m ago":t<864e5?Math.round(t/36e5)+"h ago":Math.round(t/864e5)+"d ago"}shortId(e){return e.slice(0,8)}shortFile(e){return e?e.split("/").filter(Boolean).slice(-2).join("/")||e:"\u2014"}truncate(e,t=120){return e.length>t?e.slice(0,t)+"\u2026":e}static \u0275fac=function(t){return new(t||r)};static \u0275cmp=F({type:r,selectors:[["app-heatmap"]],decls:98,vars:38,consts:[[1,"hm-root"],[1,"page","scroll-y"],[2,"margin-bottom","18px"],["icon","heatmap","title","Heatmap","sub","Where tool calls land \u2014 files, tools, subagents"],["actions",""],["size","sm",3,"change","value","options"],[1,"sum-grid",2,"margin-bottom","14px"],[1,"card","sum-card"],[1,"row","gap-6",2,"color","var(--text-muted)","white-space","nowrap","margin-bottom","3px"],["name","wrench",2,"color","var(--node-spec)","flex-shrink","0",3,"size"],[1,"eyebrow"],[1,"mono","tabular",2,"font-size","18px","font-weight","650","letter-spacing","-0.01em"],[1,"mono","muted",2,"font-size","10px"],["name","database",2,"color","var(--node-route)","flex-shrink","0",3,"size"],["name","box",2,"color","var(--warn)","flex-shrink","0",3,"size"],[1,"mono","tabular",2,"font-size","18px","font-weight","650","letter-spacing","-0.01em","overflow","hidden","text-overflow","ellipsis","white-space","nowrap"],["name","flame",2,"color","var(--error)","flex-shrink","0",3,"size"],[1,"card","card-pad",2,"margin-bottom","14px"],[1,"row","gap-8",2,"margin-bottom","12px"],["name","box",2,"color","var(--warn)",3,"size"],[2,"font-weight","600","font-size","12.5px"],[1,"muted",2,"font-size","11px"],[1,"grow"],[1,"empty"],[1,"bottom-grid"],[1,"card","card-pad"],[1,"row","gap-8",2,"margin-bottom","4px"],["name","wrench",2,"color","var(--node-code)",3,"size"],[1,"row",2,"padding","8px 0 4px","font-size","9.5px","color","var(--text-muted)","text-transform","uppercase","letter-spacing","0.05em","font-weight","600"],[2,"width","116px"],[2,"width","36px","text-align","right"],[2,"width","64px","text-align","right"],[2,"width","48px","text-align","right"],[2,"width","14px"],[1,"col","gap-2"],["type","button",1,"tool-eff-row","row","gap-8",3,"sel"],[1,"muted","row","gap-12",2,"font-size","10.5px","margin-top","10px"],[1,"row","gap-4"],[2,"width","8px","height","8px","border-radius","2px","background","var(--error)"],[2,"width","8px","height","8px","border-radius","2px","background","var(--warn)"],[2,"width","8px","height","8px","border-radius","2px","background","var(--success)"],[1,"row","gap-8",2,"margin-bottom","14px"],["name","bot",2,"color","var(--node-route)",3,"size"],["valueKey","calls","color","var(--node-route)",3,"items","fmt","selectedKey"],[1,"hm-drawer"],["variant","detailed",3,"pick","items","height","selKey"],[1,"row","gap-12",2,"margin-top","10px","align-items","center"],[1,"muted",2,"font-size","10.5px"],[1,"row",2,"width","120px","height","7px","border-radius","999px","overflow","hidden","background","linear-gradient(90deg, var(--node-route), var(--warn), var(--error))"],[1,"muted",2,"font-size","10px"],["type","button",1,"tool-eff-row","row","gap-8",3,"click"],[1,"mono",2,"width","116px","flex-shrink","0","font-size","11.5px","overflow","hidden","text-overflow","ellipsis","white-space","nowrap"],[1,"grow",2,"height","16px","background","var(--bg-hover)","border-radius","4px","overflow","hidden"],[2,"height","100%","border-radius","4px"],[1,"mono","tabular","muted",2,"width","36px","text-align","right","font-size","10.5px","flex-shrink","0"],[1,"mono","tabular",2,"width","64px","text-align","right","font-size","10.5px","flex-shrink","0"],[1,"mono","tabular",2,"width","48px","text-align","right","font-size","11.5px","font-weight","600","flex-shrink","0"],["name","chevronRight",2,"color","var(--text-faint)","flex-shrink","0",3,"size"],["valueKey","calls","color","var(--node-route)",3,"itemClick","items","fmt","selectedKey"],[1,"hm-drawer-head"],[1,"row","gap-8"],[3,"name","size"],[1,"mono","grow",2,"font-size","13px","font-weight","600","overflow","hidden","text-overflow","ellipsis","white-space","nowrap"],["type","button","aria-label","Close",1,"btn","btn-ghost","btn-xs",3,"click"],["name","x",3,"size"],[1,"muted","hm-pad"],[1,"scroll-y",2,"flex","1","padding","14px"],[1,"row",2,"gap","20px","margin-bottom","16px"],[1,"tabular",2,"font-size","26px","font-weight","700","line-height","1"],[1,"muted",2,"font-size","10.5px","margin-bottom","4px"],["color","var(--warn)",3,"data","fill","width","height"],[1,"eyebrow",2,"margin-bottom","8px"],[1,"col","gap-8",2,"margin-bottom","18px"],[1,"row","gap-10"],[1,"col","gap-6",2,"margin-bottom","18px"],[1,"session-link","row","gap-8"],[1,"btn","btn-secondary","btn-sm",2,"width","100%","justify-content","center"],["name","reveal",3,"size"],[1,"mono",2,"font-size","11.5px","width","92px","flex-shrink","0","overflow","hidden","text-overflow","ellipsis","white-space","nowrap"],[3,"frac","color"],[1,"mono","tabular","muted",2,"font-size","10.5px","width","22px","text-align","right"],[1,"mono","tabular",2,"font-size","10.5px","width","44px","text-align","right"],[1,"mono",2,"font-size","11.5px","flex-shrink","0"],[1,"muted","grow",2,"font-size","10.5px","overflow","hidden","text-overflow","ellipsis","white-space","nowrap"],["name","chevronRight",2,"color","var(--text-muted)","flex-shrink","0",3,"size"],[1,"row",2,"gap","16px","margin-bottom","16px"],[1,"tabular",2,"font-size","24px","font-weight","700","line-height","1"],["color","var(--node-code)",3,"data","fill","width","height"],[1,"row","gap-8",2,"margin-bottom","16px"],[1,"mono","tabular",2,"font-size","12px"],[1,"col","gap-7",2,"margin-bottom","18px"],[1,"muted",2,"padding","8px 0","font-size","11.5px"],[1,"col","gap-6"],[1,"mono",2,"font-size","11px","flex","1","min-width","0","overflow","hidden","text-overflow","ellipsis","white-space","nowrap","color","var(--text-secondary)"],[1,"mono","tabular","muted",2,"font-size","10px","width","20px","text-align","right"],[1,"mono","tabular",2,"font-size","10px","width","40px","text-align","right"],[1,"tabular",2,"font-size","22px","font-weight","700","line-height","1"],[1,"col","gap-6",2,"margin-bottom","16px"],[1,"inv-card"],[1,"muted",2,"font-size","11.5px","padding","8px 0"],["name","tips",3,"size"],[1,"row","gap-8",2,"margin-bottom","4px","font-size","11px"],[1,"mono"],[1,"muted"],[2,"font-size","12px","line-height","1.45"],[1,"muted","mono",2,"font-size","11px","line-height","1.45","margin-top","4px","overflow-wrap","anywhere"]],template:function(t,l){if(t&1&&(i(0,"div",0)(1,"div",1)(2,"div",2)(3,"app-page-head",3),P(4,4),i(5,"app-segmented",5),w("change",function(d){return l.setRange(d)}),n(),N(),n()(),i(6,"div",6)(7,"div",7)(8,"div",8),p(9,"app-icon",9),i(10,"span",10),o(11,"Tool calls"),n()(),i(12,"div",11),o(13),V(14,"number"),n(),i(15,"div",12),o(16),n()(),i(17,"div",7)(18,"div",8),p(19,"app-icon",13),i(20,"span",10),o(21,"Result tokens"),n()(),i(22,"div",11),o(23),n(),i(24,"div",12),o(25,"returned to context"),n()(),i(26,"div",7)(27,"div",8),p(28,"app-icon",14),i(29,"span",10),o(30,"Busiest file"),n()(),i(31,"div",15),o(32),n(),i(33,"div",12),o(34),n()(),i(35,"div",7)(36,"div",8),p(37,"app-icon",16),i(38,"span",10),o(39,"Heaviest tool"),n()(),i(40,"div",11),o(41),n(),i(42,"div",12),o(43),n()()(),i(44,"div",17)(45,"div",18),p(46,"app-icon",19),i(47,"span",20),o(48,"Files"),n(),i(49,"span",21),o(50),n(),p(51,"div",22),i(52,"app-segmented",5),w("change",function(d){return l.setMetric(d)}),n()(),_(53,pe,2,0,"div",23)(54,me,10,3),n(),i(55,"div",24)(56,"div",25)(57,"div",26),p(58,"app-icon",27),i(59,"span",20),o(60,"Tools"),n(),i(61,"span",21),o(62,"\xB7 by result tokens, ranked"),n()(),i(63,"div",28)(64,"span",29),o(65,"Tool"),n(),i(66,"span",22),o(67,"Result tokens"),n(),i(68,"span",30),o(69,"Calls"),n(),i(70,"span",31),o(71,"Per call"),n(),i(72,"span",32),o(73,"Total"),n(),p(74,"span",33),n(),i(75,"div",34),b(76,ce,12,15,"button",35,Z),n(),i(78,"div",36)(79,"span",37),p(80,"span",38),o(81,">20k / call"),n(),i(82,"span",37),p(83,"span",39),o(84,">8k"),n(),i(85,"span",37),p(86,"span",40),o(87,"lean"),n()()(),i(88,"div",25)(89,"div",41),p(90,"app-icon",42),i(91,"span",20),o(92,"Subagents"),n(),i(93,"span",21),o(94,"\xB7 by sidechain attribution"),n()(),_(95,ue,2,0,"div",23)(96,xe,1,3,"app-h-bars",43),n()()(),_(97,Me,12,10,"aside",44),n()),t&2){let s,d,g,B,D;a(5),m("value",l.range())("options",$(28,oe,f(24,te),f(25,ne),f(26,ie),f(27,ae))),a(4),m("size",12),a(4),u(j(14,22,l.totalCalls())),a(3),v("this ",l.range()),a(3),m("size",12),a(4),u(l.fmtTokens(l.totalResultTokens())),a(5),m("size",12),a(4),v(" ",l.shortFile((s=l.busiestFile())==null?null:s.path)," "),a(2),v("",((d=l.busiestFile())==null?null:d.calls)||0," calls"),a(3),m("size",12),a(4),u(((g=l.heaviestTool())==null?null:g.name)||"\u2014"),a(2),v("",l.fmtTokens(((B=l.heaviestTool())==null?null:B.resultBytes)||0)," tokens"),a(3),m("size",14),a(4),v("\xB7 area = ",l.metric()==="tokens"?"result tokens":"tool calls",", color = tokens / call"),a(2),m("value",l.metric())("options",O(35,de,f(33,le),f(34,re))),a(),h(l.files().length===0?53:54),a(5),m("size",14),a(18),y(l.toolsByTokens()),a(14),m("size",14),a(5),h(l.subagentByName().length===0?95:96),a(2),h((D=l.drill())?97:-1,D)}},dependencies:[W,q,G,X,Q,J,U,A],styles:["[_nghost-%COMP%]{display:contents}.hm-root[_ngcontent-%COMP%]{flex:1;display:flex;min-height:0;min-width:0}.page[_ngcontent-%COMP%]{flex:1;min-width:0;padding:18px}.muted[_ngcontent-%COMP%]{color:var(--text-muted)}.mono[_ngcontent-%COMP%]{font-family:var(--font-mono)}.tabular[_ngcontent-%COMP%]{font-variant-numeric:tabular-nums}.empty[_ngcontent-%COMP%]{color:var(--text-muted);padding:18px;text-align:center;font-size:12.5px}.card[_ngcontent-%COMP%]{background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:var(--r-lg)}.card-pad[_ngcontent-%COMP%]{padding:14px}.sum-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}.sum-card[_ngcontent-%COMP%]{padding:10px 13px;display:flex;flex-direction:column;gap:3px;min-width:0}.bottom-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:1fr 1fr;gap:14px}@media(max-width:1100px){.bottom-grid[_ngcontent-%COMP%]{grid-template-columns:1fr}}.tool-eff-row[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;padding:6px 8px;margin:0 -8px;border-radius:6px;cursor:pointer;background:transparent;border:none;color:inherit;font-family:inherit;text-align:left}.tool-eff-row[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.tool-eff-row.sel[_ngcontent-%COMP%]{background:var(--accent-soft)}.hm-drawer[_ngcontent-%COMP%]{width:360px;flex-shrink:0;border-left:1px solid var(--border-subtle);background:var(--bg-panel);display:flex;flex-direction:column;height:100%;overflow:hidden;animation:_ngcontent-%COMP%_hm-slide-in .16s ease-out}@keyframes _ngcontent-%COMP%_hm-slide-in{0%{transform:translate(20px);opacity:0}to{transform:translate(0);opacity:1}}.hm-drawer-head[_ngcontent-%COMP%]{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 14px;border-bottom:1px solid var(--border-subtle);flex-shrink:0;position:sticky;top:0;background:var(--bg-panel);z-index:1}.hm-pad[_ngcontent-%COMP%]{padding:16px}.session-link[_ngcontent-%COMP%]{padding:7px 9px;border-radius:7px;border:1px solid var(--border-subtle);cursor:pointer}.session-link[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.inv-card[_ngcontent-%COMP%]{background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:6px;padding:8px 10px;margin-bottom:8px}.inv-card[_ngcontent-%COMP%]:last-child{margin-bottom:0}"],changeDetection:0})};export{Y as Heatmap};
@@ -141,5 +141,5 @@
141
141
  })();
142
142
  </script>
143
143
  <app-root></app-root>
144
- <link rel="modulepreload" href="chunk-SBWU7JFC.js"><link rel="modulepreload" href="chunk-4N5DWG46.js"><link rel="modulepreload" href="chunk-SHPTC4RL.js"><link rel="modulepreload" href="chunk-7RNS77UP.js"><link rel="modulepreload" href="chunk-E44X4RH2.js"><link rel="modulepreload" href="chunk-PDN6QYGJ.js"><link rel="modulepreload" href="chunk-Q7L6LLAK.js"><script src="main-WVI3YTDU.js" type="module"></script></body>
144
+ <link rel="modulepreload" href="chunk-SBWU7JFC.js"><link rel="modulepreload" href="chunk-GR72OOCN.js"><link rel="modulepreload" href="chunk-SHPTC4RL.js"><link rel="modulepreload" href="chunk-7RNS77UP.js"><link rel="modulepreload" href="chunk-E44X4RH2.js"><link rel="modulepreload" href="chunk-PDN6QYGJ.js"><link rel="modulepreload" href="chunk-Q7L6LLAK.js"><script src="main-X2KCYXZ4.js" type="module"></script></body>
145
145
  </html>
@@ -0,0 +1 @@
1
+ import{a as V}from"./chunk-SBWU7JFC.js";import{a as me,b as ge,c as A}from"./chunk-GR72OOCN.js";import{b as se,c as $,d as de,e as pe,f as ce}from"./chunk-SHPTC4RL.js";import{a as D}from"./chunk-7RNS77UP.js";import{a as H}from"./chunk-E44X4RH2.js";import{$ as ne,Aa as c,Ba as s,Ca as p,Da as x,Ga as O,Ha as B,I as _,Ia as C,Ja as R,Ka as u,M as w,N as M,O as J,R as ee,Ta as oe,Ua as y,V as te,Va as l,W as T,Wa as v,Xa as N,Ya as ae,ca as ie,cb as re,da as X,ea as o,ka as h,lb as j,ob as F,pb as k,qa as P,ra as m,sa as g,va as S,wa as E,wb as le,xa as f,ya as a,za as r,zb as z}from"./chunk-PDN6QYGJ.js";import"./chunk-Q7L6LLAK.js";var ue=[{path:"",pathMatch:"full",redirectTo:"dashboard"},{path:"dashboard",loadComponent:()=>import("./chunk-D5OCNEJA.js").then(e=>e.Dashboard),data:{nav:"dashboard",title:"Dashboard"}},{path:"graph",loadComponent:()=>import("./chunk-WLIMNDS3.js").then(e=>e.Graph),data:{nav:"graph",title:"Graph"}},{path:"specs",loadComponent:()=>import("./chunk-ODX6CT3I.js").then(e=>e.Specs),data:{nav:"specs",title:"Specs"}},{path:"drift",loadComponent:()=>import("./chunk-FHZHD2ZG.js").then(e=>e.Drift),data:{nav:"drift",title:"Drift queue"}},{path:"workflows",loadComponent:()=>import("./chunk-NZEZCT65.js").then(e=>e.Workflows),data:{nav:"workflows",title:"Workflows"}},{path:"runs",loadComponent:()=>import("./chunk-UBOZGQNK.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-ASZ77FMZ.js").then(e=>e.Sessions),data:{nav:"sessions",title:"Sessions"}},{path:"sessions/:id",loadComponent:()=>import("./chunk-RASJHUXS.js").then(e=>e.SessionDetail),data:{nav:"sessions",title:"Session detail"}},{path:"heatmap",loadComponent:()=>import("./chunk-YAMRN47K.js").then(e=>e.Heatmap),data:{nav:"heatmap",title:"Heatmap"}},{path:"costs",loadComponent:()=>import("./chunk-WCHGDXWC.js").then(e=>e.Costs),data:{nav:"costs",title:"Costs"}},{path:"specship-impact",loadComponent:()=>import("./chunk-TQ3P2QZO.js").then(e=>e.SpecshipImpact),data:{nav:"specship-impact",title:"SpecShip Impact"}},{path:"compare",loadComponent:()=>import("./chunk-WCKHQIYN.js").then(e=>e.Compare),data:{nav:"compare",title:"Compare projects"}},{path:"tips",loadComponent:()=>import("./chunk-A5R3MJMO.js").then(e=>e.Tips),data:{nav:"tips",title:"Tips"}},{path:"memory",loadComponent:()=>import("./chunk-45QHGCB4.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 fe={providers:[te(),ce(ue)]};function ve(e,n){e&1&&(J(),x(0,"rect",14)(1,"rect",15))}var G=class e{size=k(24);tile=k(!0);glow=k(!0);static \u0275fac=function(t){return new(t||e)};static \u0275cmp=h({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&&(J(),s(0,"svg",0)(1,"defs")(2,"linearGradient",1),x(3,"stop",2)(4,"stop",3),p(),s(5,"linearGradient",4),x(6,"stop",5)(7,"stop",6),p()(),m(8,ve,2,0),s(9,"g",7),x(10,"path",8)(11,"line",9)(12,"circle",10)(13,"circle",11)(14,"circle",12)(15,"circle",13),p()()),t&2&&(oe("filter",i.glow()?"drop-shadow(0 0 9px rgba(91,147,242,0.35))":"none"),P("width",i.size())("height",i.size()),o(8),g(i.tile()?8:-1))},styles:["[_nghost-%COMP%]{display:inline-flex;align-items:center;justify-content:center;line-height:0}"],changeDetection:0})};var _e=e=>["/",e],be=(e,n)=>n.group,he=(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 Ce(e,n){if(e&1&&(a(0,"div",15),l(1),r()),e&2){let t=u().$implicit;o(),v(t.group)}}function ye(e,n){if(e&1&&(a(0,"span",18),l(1),r()),e&2){let t=u(2).$implicit,i=u(2);P("data-kind",t.badgeKind),o(),v(i.badgeOf(t))}}function Pe(e,n){if(e&1&&(a(0,"span",11),l(1),r(),m(2,ye,2,2,"span",18)),e&2){let t=u().$implicit,i=u(2);o(),v(t.label),o(),g(i.badgeOf(t)>0?2:-1)}}function ke(e,n){if(e&1&&(a(0,"a",16),c(1,"span",8),a(2,"span",9),c(3,"app-icon",17),r(),m(4,Pe,3,2),r()),e&2){let t=n.$implicit,i=u(2);f("routerLink",re(5,_e,t.id))("title",i.collapsed()?t.label:null),o(3),f("name",t.icon)("size",16),o(),g(i.collapsed()?-1:4)}}function we(e,n){if(e&1&&(a(0,"div",5),m(1,Ce,2,1,"div",15),S(2,ke,5,7,"a",16,he),r()),e&2){let t=n.$implicit,i=u();o(),g(i.collapsed()?-1:1),o(),E(t.items)}}function Me(e,n){e&1&&(a(0,"span",11),l(1,"Design system"),r())}function Se(e,n){e&1&&(a(0,"span",11),l(1,"Settings"),r())}var q=class e{collapsed=k(!1);api=_(H);projects=_(D);status=A(this.api,()=>`/api/status${this.projects.projectQuery()}`);tips=A(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:"specship-impact",label:"SpecShip Impact",icon:"graph"},{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=h({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),c(2,"app-logo-mark",2),m(3,xe,4,0,"div",3),r(),a(4,"div",4),S(5,we,4,1,"div",5,be),r(),a(7,"div",6)(8,"a",7),c(9,"span",8),a(10,"span",9),c(11,"app-icon",10),r(),m(12,Me,2,0,"span",11),r(),a(13,"a",12),c(14,"span",8),a(15,"span",9),c(16,"app-icon",13),r(),m(17,Se,2,0,"span",11),r()()()),t&2&&(y("collapsed",i.collapsed()),o(2),f("size",26),o(),g(i.collapsed()?-1:3),o(2),E(i.nav),o(3),f("title",i.collapsed()?"Design system":null),o(3),f("size",16),o(),g(i.collapsed()?-1:12),o(),f("title",i.collapsed()?"Settings":null),o(3),f("size",16),o(),g(i.collapsed()?-1:17))},dependencies:[de,pe,z,G],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 Ee(e,n){if(e&1&&(s(0,"span",8),l(1),p(),x(2,"span",1),s(3,"span",9)(4,"span",10),l(5,"backend"),p(),s(6,"span",4),l(7),p()(),x(8,"span",1),s(9,"span",9)(10,"span",10),l(11,"nodes"),p(),s(12,"span",4),l(13),p()(),s(14,"span",9)(15,"span",10),l(16,"edges"),p(),s(17,"span",4),l(18),p()(),x(19,"span",1),s(20,"span",9)(21,"span",10),l(22,"drift"),p(),s(23,"span",4),l(24),p()(),x(25,"span",11),s(26,"span",9)(27,"span",10),l(28,"indexed"),p(),s(29,"span",4),l(30),p()()),e&2){let t=u(),i=t.status.state().data;o(),v(i.projectPath),o(6),v(i.backend),o(6),v(i.nodeCount.toLocaleString()),o(5),v(i.edgeCount.toLocaleString()),o(5),y("warn",i.drift>0)("success",i.drift===0),o(),v(i.drift),o(6),v(t.indexedLabel())}}function Oe(e,n){e&1&&(s(0,"span",12),l(1,"loading status\u2026"),p(),x(2,"span",11))}function Te(e,n){if(e&1&&(s(0,"span",12),l(1),p(),x(2,"span",11)),e&2){let t=u();o(),v(t.conn.online()?"no backend":"offline \u2014 no cached data")}}function je(e,n){e&1&&(s(0,"span",5),l(1),p()),e&2&&(o(),N("\xB7 ",n))}function De(e,n){e&1&&(s(0,"span",6),l(1,"\u26A0"),p()),e&2&&B("title",n)}var K=class e{api=_(H);projects=_(D);refreshSvc=_(ge);conn=_(me);status=A(this.api,()=>`/api/status${this.projects.projectQuery()}`);offlineAge=j(()=>{let n=this.status.state().cachedAt??this.conn.lastOnlineAt();if(n===null)return null;let t=Date.now()-n;return t<1e4?"just now":t<6e4?`${Math.round(t/1e3)}s ago`:t<36e5?`${Math.round(t/6e4)}m ago`:t<864e5?`${Math.round(t/36e5)}h ago`:`${Math.round(t/864e5)}d ago`});indexedLabel=j(()=>{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=h({type:e,selectors:[["app-status-strip"]],decls:13,vars:14,consts:[[1,"status-strip"],[1,"divider"],[1,"seg","conn",3,"title"],[1,"conn-dot"],[1,"mono","val"],[1,"muted","conn-age"],[1,"refresh-error","mono",3,"title"],[1,"refresh",3,"click","disabled","title"],[1,"seg","mono"],[1,"seg"],[1,"lbl"],[1,"grow"],[1,"mono","muted"]],template:function(t,i){if(t&1&&(s(0,"div",0),m(1,Ee,31,10)(2,Oe,3,0)(3,Te,3,1),x(4,"span",1),s(5,"span",2),x(6,"span",3),s(7,"span",4),l(8),p(),m(9,je,2,1,"span",5),p(),m(10,De,2,1,"span",6),s(11,"button",7),R("click",function(){return i.refresh()}),l(12,"\u21BB"),p()()),t&2){let d,b;o(),g(i.status.state().data?1:i.status.state().loading?2:3),o(4),B("title",i.conn.online()?"Connected to the SpecShip server":"Server unreachable \u2014 showing the last cached data"),o(),y("live",i.conn.online())("off",!i.conn.online()),o(2),v(i.conn.online()?"Live":"Offline"),o(),g((d=!i.conn.online()&&i.offlineAge())?9:-1,d),o(),g((b=i.refreshSvc.error())?10:-1,b),o(),y("spinning",i.refreshSvc.loading()),B("disabled",i.refreshSvc.loading()||!i.conn.online())("title",i.conn.online()?i.refreshSvc.loading()?"Refreshing\u2026":"Refresh: sync index + re-ingest Claude Code transcripts. Updates Sessions, Heatmap, Costs, Memory, Drift, Graph.":"Offline \u2014 reconnect to refresh"),P("aria-label",i.conn.online()?i.refreshSvc.loading()?"Refreshing\u2026":"Refresh everything \u2014 sync index + ingest Claude Code transcripts":"Offline \u2014 reconnect to refresh")}},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}.conn[_ngcontent-%COMP%]{gap:5px}.conn-dot[_ngcontent-%COMP%]{width:6px;height:6px;border-radius:50%;flex-shrink:0}.conn-dot.live[_ngcontent-%COMP%]{background:var(--success);box-shadow:0 0 6px var(--success)}.conn-dot.off[_ngcontent-%COMP%]{background:var(--warn);box-shadow:0 0 6px var(--warn)}.conn-age[_ngcontent-%COMP%]{font-size:11px}"],changeDetection:0})};var ze=(e,n)=>n.slug;function Ie(e,n){e&1&&c(0,"span",8)}function Le(e,n){e&1&&c(0,"span",9)}function Re(e,n){e&1&&c(0,"span",10)}function Ne(e,n){if(e&1&&(a(0,"span",7),l(1),r(),m(2,Ie,1,0,"span",8)(3,Le,1,0,"span",9)(4,Re,1,0,"span",10)),e&2){let t=n,i=u();o(),v(i.shortPath(t.path)),o(),g(t.exists?t.initialized?4:3:2)}}function Fe(e,n){e&1&&(a(0,"span",3),l(1,"Select project"),r())}function Ae(e,n){if(e&1){let t=O();a(0,"button",20),C("click",function(){w(t);let d=u(2);return M(d.clear())}),c(1,"app-icon",21),l(2," Clear "),r()}e&2&&(o(),f("size",11))}function Be(e,n){e&1&&(a(0,"span",16),l(1,"\xB7 loading\u2026"),r())}function $e(e,n){if(e&1&&(a(0,"span",16),l(1),r()),e&2){let t=u(2);o(),N("\xB7 ",t.filtered().length," shown \xB7 live")}}function He(e,n){e&1&&(a(0,"div",18),l(1,"No projects match."),r())}function Ve(e,n){e&1&&(a(0,"span",25),l(1,"missing"),r())}function Ge(e,n){e&1&&(a(0,"span",26),l(1,"not init"),r())}function qe(e,n){e&1&&(a(0,"span",27),l(1,"initialized"),r())}function Ke(e,n){if(e&1&&(a(0,"span"),l(1),r()),e&2){let t=u().$implicit,i=u(2);o(),N("\xB7 ",i.formatRelative(t.lastModifiedMs))}}function We(e,n){e&1&&c(0,"app-icon",29),e&2&&f("size",13)}function Ue(e,n){if(e&1){let t=O();a(0,"button",22),C("click",function(){let d=w(t).$implicit,b=u(2);return M(b.pick(d.slug))}),a(1,"div",23)(2,"div",24)(3,"span",7),l(4),r(),m(5,Ve,2,0,"span",25)(6,Ge,2,0,"span",26)(7,qe,2,0,"span",27),r(),a(8,"div",28)(9,"span"),l(10),r(),m(11,Ke,2,1,"span"),r()(),m(12,We,1,1,"app-icon",29),r()}if(e&2){let t=n.$implicit,i=u(2);y("active",i.projects.activeSlug()===t.slug),o(4),v(i.shortPath(t.path)),o(),g(t.exists?t.initialized?7:6:5),o(5),ae("",t.sessionCount," session",t.sessionCount===1?"":"s"),o(),g(t.lastModifiedMs>0?11:-1),o(),g(i.projects.activeSlug()===t.slug?12:-1)}}function Qe(e,n){if(e&1){let t=O();a(0,"div",6)(1,"div",11),c(2,"app-icon",12),a(3,"input",13),C("input",function(d){w(t);let b=u();return M(b.onQuery(d.target.value))}),r(),m(4,Ae,3,1,"button",14),r(),a(5,"div",15)(6,"span"),l(7),r(),m(8,Be,2,0,"span",16)(9,$e,2,1,"span",16),r(),a(10,"div",17),m(11,He,2,0,"div",18),S(12,Ue,13,8,"button",19,ze),r()()}if(e&2){let t=u();o(2),f("size",13),o(),f("value",t.query()),o(),g(t.projects.activeSlug()?4:-1),o(3),v(t.projects.claudeRoot()??"~/.claude/projects"),o(),g(t.projects.loading()?8:9),o(3),g(t.filtered().length===0&&!t.projects.loading()?11:-1),o(),E(t.filtered())}}var W=class e{host=_(ne);projects=_(D);open=T(!1);query=T("");filtered=j(()=>{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=j(()=>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 d=Math.round(i/60);if(d<60)return`${d}m ago`;let b=Math.round(d/60);if(b<24)return`${b}h ago`;let Z=Math.round(b/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=h({type:e,selectors:[["app-project-picker"]],hostBindings:function(t,i){t&1&&C("click",function(b){return i.onDocumentClick(b)},X)("keydown.escape",function(){return i.onEscape()},X)},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),C("click",function(){return i.toggle()}),c(2,"app-icon",2),m(3,Ne,5,2)(4,Fe,2,0,"span",3),a(5,"span",4),l(6),r(),c(7,"app-icon",5),r(),m(8,Qe,14,6,"div",6),r()),t&2){let d;y("open",i.open()),o(),P("aria-expanded",i.open()),o(),f("size",13),o(),g((d=i.projects.active())?3:4,d),o(3),v(i.badge()),o(),f("name",i.open()?"chevronDown":"chevronRight")("size",11),o(),g(i.open()?8:-1)}},dependencies:[z],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 U=class e{toggleSidebar=F();openPalette=F();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=h({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),C("click",function(){return i.onMenuClick()}),c(2,"app-icon",2),r(),c(3,"app-project-picker"),a(4,"button",3),C("click",function(){return i.onPalette()}),c(5,"app-icon",4),a(6,"span"),l(7,"Search or jump to\u2026"),r(),a(8,"kbd"),l(9,"\u2318K"),r()(),c(10,"span",5),a(11,"button",6),C("click",function(){return i.onToggleTheme()}),c(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:[z,W],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 Ye=(e,n)=>n.id;function Je(e,n){if(e&1){let t=O();s(0,"button",6),R("click",function(){let d=w(t).$implicit,b=u(2);return M(b.go(d.id))}),s(1,"span",7),l(2),p(),s(3,"span",8),l(4),p()()}if(e&2){let t=n.$implicit;o(2),v(t.label),o(2),v(t.sub)}}function Xe(e,n){if(e&1){let t=O();s(0,"div",1),R("click",function(d){w(t);let b=u();return M(b.onBackdrop(d))}),s(1,"div",2)(2,"div",3)(3,"span"),l(4,"Jump to\u2026"),p(),s(5,"kbd"),l(6,"esc"),p()(),s(7,"div",4),S(8,Je,5,2,"button",5,Ye),p()()()}if(e&2){let t=u();o(8),E(t.items)}}var Ze=[{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"}],Q=class e{open=k(!1);close=F();router=_($);items=Ze;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=h({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&&m(0,Xe,10,0,"div",0),t&2&&g(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 Y=class e{_theme=_(V);_destroyRef=_(ee);_router=_($);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=h({type:e,selectors:[["app-root"]],hostBindings:function(t,i){t&1&&C("keydown",function(b){return i.onGlobalKey(b)},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),c(1,"app-sidebar",1),a(2,"div",2),c(3,"app-status-strip"),a(4,"app-top-bar",3),C("toggleSidebar",function(){return i.toggleSidebar()})("openPalette",function(){return i.onOpenPalette()}),r(),a(5,"div",4),c(6,"router-outlet"),r()(),a(7,"app-command-palette",5),C("close",function(){return i.onClosePalette()}),r()()),t&2&&(o(),f("collapsed",i.sidebarCollapsed()),o(6),f("open",i.paletteOpen()))},dependencies:[se,q,K,U,Q],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(Y,fe).catch(e=>console.error(e));typeof navigator<"u"&&"serviceWorker"in navigator&&window.addEventListener("load",()=>{navigator.serviceWorker.register("sw.js").catch(e=>{console.warn("[specship] offline service worker registration failed",e)})});
package/dist/web/sw.js ADDED
@@ -0,0 +1,69 @@
1
+ /*
2
+ * SpecShip Desktop — offline service worker (REQ-OFFLINE-001).
3
+ *
4
+ * Dependency-free network-first cache with an offline shell fallback so the
5
+ * dashboard loads from cache when the `specship serve` process is down, instead
6
+ * of the browser's native "this site can't be reached" page.
7
+ *
8
+ * Strategy — network-first for every handled request:
9
+ * - When the server is reachable, always fetch fresh and update the cache.
10
+ * This keeps users on the current build (REQ-OFFLINE-001.A3) and is correct
11
+ * whether or not asset filenames are content-hashed (dev builds reuse
12
+ * `main.js`; a cache-first strategy would pin a stale bundle).
13
+ * - When a fetch fails (server down), serve the cached copy. Navigations fall
14
+ * back to the cached app shell so any route renders the SPA offline.
15
+ * - /api/* and EventSource streams are NOT handled here — the app's own
16
+ * per-surface cache (apiResource → localStorage) owns offline DATA and
17
+ * staleness so the UI controls how stale data is presented (REQ-OFFLINE-003).
18
+ *
19
+ * Only same-origin GETs are handled; cross-origin (an API on another host/port,
20
+ * Google Fonts, …) passes straight through.
21
+ */
22
+
23
+ const CACHE = 'specship-shell-v2';
24
+ const SHELL = '/index.html';
25
+
26
+ self.addEventListener('install', (event) => {
27
+ event.waitUntil(
28
+ caches.open(CACHE)
29
+ .then((c) => c.add(SHELL).catch(() => undefined))
30
+ .then(() => self.skipWaiting()),
31
+ );
32
+ });
33
+
34
+ self.addEventListener('activate', (event) => {
35
+ event.waitUntil(
36
+ caches.keys()
37
+ .then((keys) => Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k))))
38
+ .then(() => self.clients.claim()),
39
+ );
40
+ });
41
+
42
+ self.addEventListener('fetch', (event) => {
43
+ const req = event.request;
44
+ if (req.method !== 'GET') return;
45
+
46
+ const url = new URL(req.url);
47
+ if (url.origin !== self.location.origin) return; // API on another origin, fonts, etc.
48
+ if (url.pathname.startsWith('/api/')) return; // data layer owns offline data
49
+ if (req.headers.get('accept') === 'text/event-stream') return; // SSE must stream live
50
+
51
+ // Cache key: all navigations share the SPA shell entry; assets key on the request.
52
+ const isNav = req.mode === 'navigate';
53
+ const key = isNav ? SHELL : req;
54
+
55
+ // Network-first: fresh when reachable, cached copy when the server is down.
56
+ event.respondWith(
57
+ fetch(req)
58
+ .then((res) => {
59
+ if (res && res.ok && res.type === 'basic') {
60
+ const copy = res.clone();
61
+ caches.open(CACHE).then((c) => c.put(key, copy)).catch(() => undefined);
62
+ }
63
+ return res;
64
+ })
65
+ .catch(() =>
66
+ caches.match(key).then((hit) => hit || (isNav ? caches.match(SHELL) : undefined)).then((hit) => hit || Response.error()),
67
+ ),
68
+ );
69
+ });