@specship/specship-win32-arm64 0.11.6 → 0.11.8

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 (67) hide show
  1. package/lib/dist/bin/specship.js +7 -7
  2. package/lib/dist/bin/specship.js.map +1 -1
  3. package/lib/dist/commands/{ss-design-implement.md → specship/design-implement.md} +5 -5
  4. package/lib/dist/commands/{ss-design-loop.md → specship/design-loop.md} +6 -6
  5. package/lib/dist/commands/{ss-spec.md → specship/spec.md} +4 -4
  6. package/lib/dist/index.d.ts +1 -1
  7. package/lib/dist/index.js +1 -1
  8. package/lib/dist/installer/instructions-template.js +3 -3
  9. package/lib/dist/installer/instructions-template.js.map +1 -1
  10. package/lib/dist/installer/targets/claude.d.ts +6 -4
  11. package/lib/dist/installer/targets/claude.d.ts.map +1 -1
  12. package/lib/dist/installer/targets/claude.js +69 -17
  13. package/lib/dist/installer/targets/claude.js.map +1 -1
  14. package/lib/dist/mcp/designer-tools.js +1 -1
  15. package/lib/dist/mcp/designer-tools.js.map +1 -1
  16. package/lib/dist/mcp/spec-tools.js +3 -3
  17. package/lib/dist/mcp/spec-tools.js.map +1 -1
  18. package/lib/dist/resolution/domain-gap-seed.d.ts +1 -1
  19. package/lib/dist/resolution/domain-gap-seed.js +1 -1
  20. package/lib/dist/server/chat/classify.js +28 -8
  21. package/lib/dist/server/routes/chat-answer.js +11 -0
  22. package/lib/dist/server/routes/chat.js +2 -3
  23. package/lib/dist/server/routes/claude.js +2 -3
  24. package/lib/dist/server/routes/events.js +2 -3
  25. package/lib/dist/server/routes/projects.js +2 -3
  26. package/lib/dist/server/routes/sse.js +23 -0
  27. package/lib/dist/server/routes/workflow.js +2 -3
  28. package/lib/dist/web/{chunk-H2TR6BKW.js → chunk-7KWBINA7.js} +1 -1
  29. package/lib/dist/web/{chunk-BZ5SMVXG.js → chunk-7MUNFW56.js} +1 -1
  30. package/lib/dist/web/{chunk-Z23KACD6.js → chunk-AZUUBUEJ.js} +1 -1
  31. package/lib/dist/web/{chunk-BDF4LLKR.js → chunk-CYXQILZI.js} +1 -1
  32. package/lib/dist/web/{chunk-PAO2624Y.js → chunk-DTWIJ3GJ.js} +1 -1
  33. package/lib/dist/web/{chunk-G2FTQVMJ.js → chunk-E27QAKAB.js} +1 -1
  34. package/lib/dist/web/{chunk-YPWBUJH7.js → chunk-EXBUKHH2.js} +1 -1
  35. package/lib/dist/web/{chunk-YVAUYHOB.js → chunk-F5TBUYDH.js} +1 -1
  36. package/lib/dist/web/{chunk-C6I5R6UZ.js → chunk-FC3R7YHR.js} +1 -1
  37. package/lib/dist/web/{chunk-IXQIWN6Z.js → chunk-G7RXFHYO.js} +1 -1
  38. package/lib/dist/web/chunk-H723TYYD.js +2 -0
  39. package/lib/dist/web/chunk-HSJNHNOH.js +6 -0
  40. package/lib/dist/web/{chunk-PBRCKHEQ.js → chunk-JGDK6YKG.js} +1 -1
  41. package/lib/dist/web/{chunk-5CR7TMVN.js → chunk-JPSYO24K.js} +1 -1
  42. package/lib/dist/web/{chunk-FYXVIWM2.js → chunk-K7UD24Z4.js} +1 -1
  43. package/lib/dist/web/chunk-KYSTCHAH.js +1 -0
  44. package/lib/dist/web/{chunk-7ALHQYYG.js → chunk-MNFTHCSJ.js} +1 -1
  45. package/lib/dist/web/{chunk-NY5CBIVU.js → chunk-OTQR5VFM.js} +1 -1
  46. package/lib/dist/web/{chunk-G2MHCJUR.js → chunk-PCW6R7OP.js} +1 -1
  47. package/lib/dist/web/{chunk-EAWW6PQJ.js → chunk-POCVU4VK.js} +1 -1
  48. package/lib/dist/web/chunk-PS6HRYQQ.js +3 -0
  49. package/lib/dist/web/chunk-TWVVIWKO.js +1 -0
  50. package/lib/dist/web/{chunk-HZYJAXHL.js → chunk-U67LRNER.js} +1 -1
  51. package/lib/dist/web/{chunk-KXMWAQNB.js → chunk-USVLLFVR.js} +1 -1
  52. package/lib/dist/web/{chunk-7V4MGZCG.js → chunk-XAUQEKZX.js} +1 -1
  53. package/lib/dist/web/{chunk-D7HQMX7C.js → chunk-YXYPTZ6E.js} +1 -1
  54. package/lib/dist/web/index.html +1 -1
  55. package/lib/dist/web/{main-A6QZ3DLK.js → main-FY3HQ4PX.js} +1 -1
  56. package/lib/dist/workflows/defaults/claude-design-implement.yaml +5 -5
  57. package/lib/dist/workflows/defaults/spec-author.yaml +1 -1
  58. package/lib/node_modules/.package-lock.json +1 -1
  59. package/lib/package.json +1 -1
  60. package/package.json +1 -1
  61. package/lib/dist/web/chunk-3H2EZLZN.js +0 -1
  62. package/lib/dist/web/chunk-6FZTSHJS.js +0 -3
  63. package/lib/dist/web/chunk-7ULUC3DC.js +0 -2
  64. package/lib/dist/web/chunk-QJSQ3ORB.js +0 -6
  65. package/lib/dist/web/chunk-U6CWVOZO.js +0 -1
  66. /package/lib/dist/commands/{ss-check.md → specship/check.md} +0 -0
  67. /package/lib/dist/commands/{ss-explore.md → specship/explore.md} +0 -0
@@ -1 +1 @@
1
- import{a as R}from"./chunk-JLOJCDIY.js";import{a as V}from"./chunk-5NTGUSXJ.js";import{a as $}from"./chunk-PZSU53SS.js";import{c as N}from"./chunk-PAO2624Y.js";import"./chunk-PBRCKHEQ.js";import{a as F}from"./chunk-3H2EZLZN.js";import{Aa as p,Ea as S,Fa as T,Ga as h,I as P,Ia as O,Ka as c,M as b,N as y,Ta as E,Ua as I,Va as s,W as C,Wa as l,Xa as g,bb as D,ea as o,ka as z,lb as M,qa as k,ra as x,sa as _,ua as w,va as u,wa as f,xa as d,ya as a,za as r,zb as B}from"./chunk-SYGIPC2P.js";import"./chunk-Q7L6LLAK.js";var j=()=>[0,1,2,3],H=(n,t)=>t.id;function q(n,t){n&1&&p(0,"div",6)}function G(n,t){n&1&&u(0,q,1,0,"div",6,w),n&2&&f(D(0,j))}function J(n,t){n&1&&(a(0,"div",4),s(1,"No tips."),r())}function K(n,t){if(n&1&&p(0,"app-icon",13),n&2){let e=c().$implicit;d("name",e.icon)("size",15)}}function L(n,t){n&1&&p(0,"app-icon",14),n&2&&d("size",15)}function Q(n,t){if(n&1){let e=h();a(0,"div",37),O("click",function(){b(e);let m=c(2).$implicit,v=c(2);return y(v.dismiss(m.id))}),s(1),r()}if(n&2){let e=t.$implicit;o(),g("Snooze ",e)}}function U(n,t){if(n&1&&(a(0,"div",35),u(1,Q,2,1,"div",36,w),r()),n&2){let e=c(3);o(),f(e.snoozeOpts)}}function W(n,t){if(n&1){let e=h();a(0,"div",8),p(1,"div",9),a(2,"div",10)(3,"div",11)(4,"div",12),x(5,K,1,2,"app-icon",13)(6,L,1,1,"app-icon",14),r(),a(7,"div",15)(8,"div",16),s(9),r()(),a(10,"app-pill",3),s(11),r()(),a(12,"div",17),s(13),r(),a(14,"div",18)(15,"div",19)(16,"div",20),s(17,"Evidence"),r(),a(18,"div",21),p(19,"app-icon",22),a(20,"span",23),s(21),r()(),a(22,"div",24),s(23),r()(),a(24,"div",19)(25,"div",20),s(26,"Impact"),r(),a(27,"div",25),s(28),r()()(),a(29,"div",26)(30,"div",27)(31,"span",28),s(32,"fix"),r(),a(33,"code",29),s(34),r(),p(35,"app-copy-btn",30),r(),a(36,"button",31),s(37,"Apply"),r(),a(38,"div",32)(39,"button",33),O("click",function(){let m=b(e).$implicit,v=c(2);return y(v.toggleSnooze(m.id))}),s(40," Dismiss "),p(41,"app-icon",34),r(),x(42,U,3,0,"div",35),r()()()()}if(n&2){let e=t.$implicit,i=c(2);I("dismissed",i.isDismissed(e.id)),k("data-sev",e.severity),o(4),E("background",i.sevBg(e.severity))("color",i.sevColor(e.severity)),o(),_(e.icon?5:6),o(4),l(e.title),o(),d("color",i.sevColor(e.severity))("bg",i.sevBg(e.severity)),o(),l(e.severity),o(2),l(e.why),o(6),d("size",11),o(2),l(e.evidence.session),o(2),l(e.evidence.detail),o(5),l(e.saving),o(6),l(e.fix),o(),d("text",e.fix),o(6),d("size",12),o(),_(i.snoozeOpen(e.id)?42:-1)}}function X(n,t){if(n&1&&(a(0,"div",5),u(1,W,43,21,"div",7,H),r()),n&2){let e=c();o(),f(e.ordered())}}var A=class n{api=P(F);resource=N(this.api,()=>"/api/claude/tips");dismissedIds=C(new Set);snoozeOpenIds=C(new Set);snoozeOpts=["1 day","1 week","Forever"];ordered=M(()=>{let t=this.resource.state().data?.tips??[],e=this.dismissedIds(),i={error:0,warn:1,info:2};return[...t].filter(m=>!e.has(m.id)).sort((m,v)=>(i[m.severity]??9)-(i[v.severity]??9))});counts=M(()=>{let t=this.resource.state().data?.tips??[];return{error:t.filter(e=>e.severity==="error").length,warn:t.filter(e=>e.severity==="warn").length,info:t.filter(e=>e.severity==="info").length}});isDismissed(t){return this.dismissedIds().has(t)}snoozeOpen(t){return this.snoozeOpenIds().has(t)}toggleSnooze(t){this.snoozeOpenIds.update(e=>{let i=new Set(e);return i.has(t)?i.delete(t):i.add(t),i})}dismiss(t){this.dismissedIds.update(e=>new Set([...e,t])),this.snoozeOpenIds.update(e=>{let i=new Set(e);return i.delete(t),i})}sevColor(t){return t==="error"?"var(--error)":t==="warn"?"var(--warn)":"var(--info)"}sevBg(t){return t==="error"?"color-mix(in srgb, var(--error) 16%, transparent)":t==="warn"?"color-mix(in srgb, var(--warn) 16%, transparent)":"color-mix(in srgb, var(--info) 16%, transparent)"}static \u0275fac=function(e){return new(e||n)};static \u0275cmp=z({type:n,selectors:[["app-tips"]],decls:12,vars:10,consts:[[1,"page","scroll-y"],["icon","tips","title","Tips","sub","A senior teammate reviewed your transcripts"],["actions",""],[3,"color","bg"],[1,"empty"],[1,"tips-grid"],[1,"skel","card-skel"],[1,"tip-card","card",3,"dismissed"],[1,"tip-card","card"],[1,"sev-bar"],[1,"tip-body"],[1,"row","gap-10",2,"margin-bottom","10px"],[1,"icon-tile"],[3,"name","size"],["name","tips",3,"size"],[1,"grow",2,"min-width","0"],[1,"tip-title"],[1,"tip-why"],[1,"tip-grid"],[1,"kv-block"],[1,"eyebrow"],[1,"row","gap-6",2,"font-size","11.5px","margin-top","2px"],["name","sessions",2,"color","var(--text-muted)",3,"size"],[1,"mono",2,"color","var(--accent)"],[1,"mono","secondary",2,"font-size","11px","margin-top","4px"],[2,"font-size","16px","font-weight","700","color","var(--success)","font-variant-numeric","tabular-nums","margin-top","2px"],[1,"actions"],[1,"fix-row","grow"],[1,"muted","fix-label"],[1,"mono","fix-code"],[3,"text"],["type","button",1,"btn","btn-primary","btn-sm"],[1,"dismiss-wrap",2,"position","relative"],["type","button",1,"btn","btn-secondary","btn-sm",3,"click"],["name","chevronDown",3,"size"],[1,"snooze-menu"],[1,"snooze-opt"],[1,"snooze-opt",3,"click"]],template:function(e,i){e&1&&(a(0,"div",0)(1,"app-page-head",1),S(2,2),a(3,"app-pill",3),s(4),r(),a(5,"app-pill",3),s(6),r(),a(7,"app-pill",3),s(8),r(),T(),r(),x(9,G,2,1)(10,J,2,0,"div",4)(11,X,3,0,"div",5),r()),e&2&&(o(3),d("color","var(--error)")("bg","var(--error-soft)"),o(),g("",i.counts().error," urgent"),o(),d("color","var(--warn)")("bg","var(--warn-soft)"),o(),g("",i.counts().warn," warn"),o(),d("color","var(--info)")("bg","var(--info-soft)"),o(),g("",i.counts().info," info"),o(),_(i.resource.state().loading?9:i.ordered().length===0?10:11))},dependencies:[V,R,$,B],styles:["[_nghost-%COMP%]{display:contents}.page[_ngcontent-%COMP%]{flex:1;padding:18px}.muted[_ngcontent-%COMP%]{color:var(--text-muted)}.mono[_ngcontent-%COMP%]{font-family:var(--font-mono)}.secondary[_ngcontent-%COMP%]{color:var(--text-secondary)}.grow[_ngcontent-%COMP%]{flex:1}.tips-grid[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:12px;max-width:860px}.tip-card[_ngcontent-%COMP%]{background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:var(--r-lg);overflow:hidden;display:flex}.tip-card.dismissed[_ngcontent-%COMP%]{display:none}.tip-card[data-sev=error][_ngcontent-%COMP%] .sev-bar[_ngcontent-%COMP%]{background:var(--error)}.tip-card[data-sev=warn][_ngcontent-%COMP%] .sev-bar[_ngcontent-%COMP%]{background:var(--warn)}.tip-card[data-sev=info][_ngcontent-%COMP%] .sev-bar[_ngcontent-%COMP%]{background:var(--info)}.sev-bar[_ngcontent-%COMP%]{width:3px;flex-shrink:0}.tip-body[_ngcontent-%COMP%]{padding:14px 16px;flex:1;min-width:0}.icon-tile[_ngcontent-%COMP%]{width:28px;height:28px;border-radius:8px;display:grid;place-items:center;flex-shrink:0}.tip-title[_ngcontent-%COMP%]{font-size:14px;font-weight:600;letter-spacing:-.01em;text-wrap:pretty}.tip-why[_ngcontent-%COMP%]{color:var(--text-secondary);font-size:12.5px;line-height:1.6;margin-bottom:12px}.tip-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px}.kv-block[_ngcontent-%COMP%]{background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:var(--r-md);padding:10px}.eyebrow[_ngcontent-%COMP%]{font-size:10.5px;font-weight:600;text-transform:uppercase;letter-spacing:.07em;color:var(--text-muted);margin-bottom:5px}.actions[_ngcontent-%COMP%]{display:flex;gap:8px;align-items:center}.fix-row[_ngcontent-%COMP%]{min-width:0;display:flex;align-items:center;gap:8px;background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:7px;padding:6px 10px}.fix-label[_ngcontent-%COMP%]{color:var(--text-muted);font-size:10.5px;flex-shrink:0}.fix-code[_ngcontent-%COMP%]{flex:1;min-width:0;color:var(--text-primary);font-size:11.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dismiss-wrap[_ngcontent-%COMP%]{position:relative}.snooze-menu[_ngcontent-%COMP%]{position:absolute;top:100%;right:0;margin-top:4px;background:var(--bg-elevated);border:1px solid var(--border-strong);border-radius:8px;box-shadow:0 4px 16px #00000059;padding:5px;width:130px;z-index:10}.snooze-opt[_ngcontent-%COMP%]{padding:6px 9px;border-radius:5px;cursor:pointer;font-size:12px;color:var(--text-primary)}.snooze-opt[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.skel[_ngcontent-%COMP%]{background:var(--bg-elevated);border-radius:5px;animation:_ngcontent-%COMP%_skeleton 1.4s ease-in-out infinite}.card-skel[_ngcontent-%COMP%]{height:200px;margin-bottom:12px}.empty[_ngcontent-%COMP%]{color:var(--text-muted);font-size:13px;padding:40px;text-align:center}@keyframes _ngcontent-%COMP%_skeleton{0%,to{opacity:.5}50%{opacity:.9}}"],changeDetection:0})};export{A as Tips};
1
+ import{a as R}from"./chunk-JLOJCDIY.js";import{a as V}from"./chunk-5NTGUSXJ.js";import{a as $}from"./chunk-PZSU53SS.js";import{c as N}from"./chunk-DTWIJ3GJ.js";import"./chunk-JGDK6YKG.js";import{a as F}from"./chunk-TWVVIWKO.js";import{Aa as p,Ea as S,Fa as T,Ga as h,I as P,Ia as O,Ka as c,M as b,N as y,Ta as E,Ua as I,Va as s,W as C,Wa as l,Xa as g,bb as D,ea as o,ka as z,lb as M,qa as k,ra as x,sa as _,ua as w,va as u,wa as f,xa as d,ya as a,za as r,zb as B}from"./chunk-SYGIPC2P.js";import"./chunk-Q7L6LLAK.js";var j=()=>[0,1,2,3],H=(n,t)=>t.id;function q(n,t){n&1&&p(0,"div",6)}function G(n,t){n&1&&u(0,q,1,0,"div",6,w),n&2&&f(D(0,j))}function J(n,t){n&1&&(a(0,"div",4),s(1,"No tips."),r())}function K(n,t){if(n&1&&p(0,"app-icon",13),n&2){let e=c().$implicit;d("name",e.icon)("size",15)}}function L(n,t){n&1&&p(0,"app-icon",14),n&2&&d("size",15)}function Q(n,t){if(n&1){let e=h();a(0,"div",37),O("click",function(){b(e);let m=c(2).$implicit,v=c(2);return y(v.dismiss(m.id))}),s(1),r()}if(n&2){let e=t.$implicit;o(),g("Snooze ",e)}}function U(n,t){if(n&1&&(a(0,"div",35),u(1,Q,2,1,"div",36,w),r()),n&2){let e=c(3);o(),f(e.snoozeOpts)}}function W(n,t){if(n&1){let e=h();a(0,"div",8),p(1,"div",9),a(2,"div",10)(3,"div",11)(4,"div",12),x(5,K,1,2,"app-icon",13)(6,L,1,1,"app-icon",14),r(),a(7,"div",15)(8,"div",16),s(9),r()(),a(10,"app-pill",3),s(11),r()(),a(12,"div",17),s(13),r(),a(14,"div",18)(15,"div",19)(16,"div",20),s(17,"Evidence"),r(),a(18,"div",21),p(19,"app-icon",22),a(20,"span",23),s(21),r()(),a(22,"div",24),s(23),r()(),a(24,"div",19)(25,"div",20),s(26,"Impact"),r(),a(27,"div",25),s(28),r()()(),a(29,"div",26)(30,"div",27)(31,"span",28),s(32,"fix"),r(),a(33,"code",29),s(34),r(),p(35,"app-copy-btn",30),r(),a(36,"button",31),s(37,"Apply"),r(),a(38,"div",32)(39,"button",33),O("click",function(){let m=b(e).$implicit,v=c(2);return y(v.toggleSnooze(m.id))}),s(40," Dismiss "),p(41,"app-icon",34),r(),x(42,U,3,0,"div",35),r()()()()}if(n&2){let e=t.$implicit,i=c(2);I("dismissed",i.isDismissed(e.id)),k("data-sev",e.severity),o(4),E("background",i.sevBg(e.severity))("color",i.sevColor(e.severity)),o(),_(e.icon?5:6),o(4),l(e.title),o(),d("color",i.sevColor(e.severity))("bg",i.sevBg(e.severity)),o(),l(e.severity),o(2),l(e.why),o(6),d("size",11),o(2),l(e.evidence.session),o(2),l(e.evidence.detail),o(5),l(e.saving),o(6),l(e.fix),o(),d("text",e.fix),o(6),d("size",12),o(),_(i.snoozeOpen(e.id)?42:-1)}}function X(n,t){if(n&1&&(a(0,"div",5),u(1,W,43,21,"div",7,H),r()),n&2){let e=c();o(),f(e.ordered())}}var A=class n{api=P(F);resource=N(this.api,()=>"/api/claude/tips");dismissedIds=C(new Set);snoozeOpenIds=C(new Set);snoozeOpts=["1 day","1 week","Forever"];ordered=M(()=>{let t=this.resource.state().data?.tips??[],e=this.dismissedIds(),i={error:0,warn:1,info:2};return[...t].filter(m=>!e.has(m.id)).sort((m,v)=>(i[m.severity]??9)-(i[v.severity]??9))});counts=M(()=>{let t=this.resource.state().data?.tips??[];return{error:t.filter(e=>e.severity==="error").length,warn:t.filter(e=>e.severity==="warn").length,info:t.filter(e=>e.severity==="info").length}});isDismissed(t){return this.dismissedIds().has(t)}snoozeOpen(t){return this.snoozeOpenIds().has(t)}toggleSnooze(t){this.snoozeOpenIds.update(e=>{let i=new Set(e);return i.has(t)?i.delete(t):i.add(t),i})}dismiss(t){this.dismissedIds.update(e=>new Set([...e,t])),this.snoozeOpenIds.update(e=>{let i=new Set(e);return i.delete(t),i})}sevColor(t){return t==="error"?"var(--error)":t==="warn"?"var(--warn)":"var(--info)"}sevBg(t){return t==="error"?"color-mix(in srgb, var(--error) 16%, transparent)":t==="warn"?"color-mix(in srgb, var(--warn) 16%, transparent)":"color-mix(in srgb, var(--info) 16%, transparent)"}static \u0275fac=function(e){return new(e||n)};static \u0275cmp=z({type:n,selectors:[["app-tips"]],decls:12,vars:10,consts:[[1,"page","scroll-y"],["icon","tips","title","Tips","sub","A senior teammate reviewed your transcripts"],["actions",""],[3,"color","bg"],[1,"empty"],[1,"tips-grid"],[1,"skel","card-skel"],[1,"tip-card","card",3,"dismissed"],[1,"tip-card","card"],[1,"sev-bar"],[1,"tip-body"],[1,"row","gap-10",2,"margin-bottom","10px"],[1,"icon-tile"],[3,"name","size"],["name","tips",3,"size"],[1,"grow",2,"min-width","0"],[1,"tip-title"],[1,"tip-why"],[1,"tip-grid"],[1,"kv-block"],[1,"eyebrow"],[1,"row","gap-6",2,"font-size","11.5px","margin-top","2px"],["name","sessions",2,"color","var(--text-muted)",3,"size"],[1,"mono",2,"color","var(--accent)"],[1,"mono","secondary",2,"font-size","11px","margin-top","4px"],[2,"font-size","16px","font-weight","700","color","var(--success)","font-variant-numeric","tabular-nums","margin-top","2px"],[1,"actions"],[1,"fix-row","grow"],[1,"muted","fix-label"],[1,"mono","fix-code"],[3,"text"],["type","button",1,"btn","btn-primary","btn-sm"],[1,"dismiss-wrap",2,"position","relative"],["type","button",1,"btn","btn-secondary","btn-sm",3,"click"],["name","chevronDown",3,"size"],[1,"snooze-menu"],[1,"snooze-opt"],[1,"snooze-opt",3,"click"]],template:function(e,i){e&1&&(a(0,"div",0)(1,"app-page-head",1),S(2,2),a(3,"app-pill",3),s(4),r(),a(5,"app-pill",3),s(6),r(),a(7,"app-pill",3),s(8),r(),T(),r(),x(9,G,2,1)(10,J,2,0,"div",4)(11,X,3,0,"div",5),r()),e&2&&(o(3),d("color","var(--error)")("bg","var(--error-soft)"),o(),g("",i.counts().error," urgent"),o(),d("color","var(--warn)")("bg","var(--warn-soft)"),o(),g("",i.counts().warn," warn"),o(),d("color","var(--info)")("bg","var(--info-soft)"),o(),g("",i.counts().info," info"),o(),_(i.resource.state().loading?9:i.ordered().length===0?10:11))},dependencies:[V,R,$,B],styles:["[_nghost-%COMP%]{display:contents}.page[_ngcontent-%COMP%]{flex:1;padding:18px}.muted[_ngcontent-%COMP%]{color:var(--text-muted)}.mono[_ngcontent-%COMP%]{font-family:var(--font-mono)}.secondary[_ngcontent-%COMP%]{color:var(--text-secondary)}.grow[_ngcontent-%COMP%]{flex:1}.tips-grid[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:12px;max-width:860px}.tip-card[_ngcontent-%COMP%]{background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:var(--r-lg);overflow:hidden;display:flex}.tip-card.dismissed[_ngcontent-%COMP%]{display:none}.tip-card[data-sev=error][_ngcontent-%COMP%] .sev-bar[_ngcontent-%COMP%]{background:var(--error)}.tip-card[data-sev=warn][_ngcontent-%COMP%] .sev-bar[_ngcontent-%COMP%]{background:var(--warn)}.tip-card[data-sev=info][_ngcontent-%COMP%] .sev-bar[_ngcontent-%COMP%]{background:var(--info)}.sev-bar[_ngcontent-%COMP%]{width:3px;flex-shrink:0}.tip-body[_ngcontent-%COMP%]{padding:14px 16px;flex:1;min-width:0}.icon-tile[_ngcontent-%COMP%]{width:28px;height:28px;border-radius:8px;display:grid;place-items:center;flex-shrink:0}.tip-title[_ngcontent-%COMP%]{font-size:14px;font-weight:600;letter-spacing:-.01em;text-wrap:pretty}.tip-why[_ngcontent-%COMP%]{color:var(--text-secondary);font-size:12.5px;line-height:1.6;margin-bottom:12px}.tip-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px}.kv-block[_ngcontent-%COMP%]{background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:var(--r-md);padding:10px}.eyebrow[_ngcontent-%COMP%]{font-size:10.5px;font-weight:600;text-transform:uppercase;letter-spacing:.07em;color:var(--text-muted);margin-bottom:5px}.actions[_ngcontent-%COMP%]{display:flex;gap:8px;align-items:center}.fix-row[_ngcontent-%COMP%]{min-width:0;display:flex;align-items:center;gap:8px;background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:7px;padding:6px 10px}.fix-label[_ngcontent-%COMP%]{color:var(--text-muted);font-size:10.5px;flex-shrink:0}.fix-code[_ngcontent-%COMP%]{flex:1;min-width:0;color:var(--text-primary);font-size:11.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dismiss-wrap[_ngcontent-%COMP%]{position:relative}.snooze-menu[_ngcontent-%COMP%]{position:absolute;top:100%;right:0;margin-top:4px;background:var(--bg-elevated);border:1px solid var(--border-strong);border-radius:8px;box-shadow:0 4px 16px #00000059;padding:5px;width:130px;z-index:10}.snooze-opt[_ngcontent-%COMP%]{padding:6px 9px;border-radius:5px;cursor:pointer;font-size:12px;color:var(--text-primary)}.snooze-opt[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.skel[_ngcontent-%COMP%]{background:var(--bg-elevated);border-radius:5px;animation:_ngcontent-%COMP%_skeleton 1.4s ease-in-out infinite}.card-skel[_ngcontent-%COMP%]{height:200px;margin-bottom:12px}.empty[_ngcontent-%COMP%]{color:var(--text-muted);font-size:13px;padding:40px;text-align:center}@keyframes _ngcontent-%COMP%_skeleton{0%,to{opacity:.5}50%{opacity:.9}}"],changeDetection:0})};export{A as Tips};
@@ -142,5 +142,5 @@
142
142
  })();
143
143
  </script>
144
144
  <app-root></app-root>
145
- <link rel="modulepreload" href="chunk-2IVSOVQZ.js"><link rel="modulepreload" href="chunk-YV5LB22R.js"><link rel="modulepreload" href="chunk-DOKZOFKM.js"><link rel="modulepreload" href="chunk-PAO2624Y.js"><link rel="modulepreload" href="chunk-PBRCKHEQ.js"><link rel="modulepreload" href="chunk-3H2EZLZN.js"><link rel="modulepreload" href="chunk-SYGIPC2P.js"><link rel="modulepreload" href="chunk-Q7L6LLAK.js"><script src="main-A6QZ3DLK.js" type="module"></script></body>
145
+ <link rel="modulepreload" href="chunk-2IVSOVQZ.js"><link rel="modulepreload" href="chunk-YV5LB22R.js"><link rel="modulepreload" href="chunk-DOKZOFKM.js"><link rel="modulepreload" href="chunk-DTWIJ3GJ.js"><link rel="modulepreload" href="chunk-JGDK6YKG.js"><link rel="modulepreload" href="chunk-TWVVIWKO.js"><link rel="modulepreload" href="chunk-SYGIPC2P.js"><link rel="modulepreload" href="chunk-Q7L6LLAK.js"><script src="main-FY3HQ4PX.js" type="module"></script></body>
146
146
  </html>
@@ -1 +1 @@
1
- import{a as q,b as fe}from"./chunk-2IVSOVQZ.js";import{a as ge}from"./chunk-YV5LB22R.js";import{b as le,c as D,d as pe,e as de,f as ce}from"./chunk-DOKZOFKM.js";import{a as me,b as ue,c as z}from"./chunk-PAO2624Y.js";import{a as I}from"./chunk-PBRCKHEQ.js";import{a as V}from"./chunk-3H2EZLZN.js";import{$ as ie,Aa as p,Ba as c,Ca as v,Da as M,E as B,Ga as P,Ha as $,I as g,Ia as b,Ja as L,Ka as d,M as C,N as y,R as te,Ua as k,V as ne,Va as s,W as w,Wa as h,Xa as A,Ya as ae,ca as oe,cb as re,da as Z,ea as o,ka as x,lb as T,ob as N,pb as H,qa as j,ra as m,sa as u,va as S,wa as O,wb as se,xa as f,ya as a,za as r,zb as R}from"./chunk-SYGIPC2P.js";import"./chunk-Q7L6LLAK.js";var ve=[{path:"",pathMatch:"full",redirectTo:"dashboard"},{path:"dashboard",loadComponent:()=>import("./chunk-7ULUC3DC.js").then(e=>e.Dashboard),data:{nav:"dashboard",title:"Dashboard"}},{path:"graph",loadComponent:()=>import("./chunk-YVAUYHOB.js").then(e=>e.Graph),data:{nav:"graph",title:"Graph"}},{path:"specs",loadComponent:()=>import("./chunk-QJSQ3ORB.js").then(e=>e.Specs),data:{nav:"specs",title:"Specs"}},{path:"specs/:id",loadComponent:()=>import("./chunk-U6CWVOZO.js").then(e=>e.SpecDetail),data:{nav:"specs",title:"Spec"}},{path:"drift",loadComponent:()=>import("./chunk-H2TR6BKW.js").then(e=>e.Drift),data:{nav:"drift",title:"Drift queue"}},{path:"improvements",loadComponent:()=>import("./chunk-BDF4LLKR.js").then(e=>e.Improvements),data:{nav:"improvements",title:"Improvements"}},{path:"maintainability",loadComponent:()=>import("./chunk-FYXVIWM2.js").then(e=>e.Maintainability),data:{nav:"maintainability",title:"Maintainability"}},{path:"domain",loadComponent:()=>import("./chunk-NY5CBIVU.js").then(e=>e.Domain),data:{nav:"domain",title:"Domain"}},{path:"workflows",loadComponent:()=>import("./chunk-KXMWAQNB.js").then(e=>e.Workflows),data:{nav:"workflows",title:"Workflows"}},{path:"runs",loadComponent:()=>import("./chunk-IXQIWN6Z.js").then(e=>e.Runs),data:{nav:"runs",title:"Runs"}},{path:"runs/:id",loadComponent:()=>import("./chunk-HZYJAXHL.js").then(e=>e.RunDetail),data:{nav:"runs",title:"Run detail"}},{path:"chat",loadComponent:()=>import("./chunk-6FZTSHJS.js").then(e=>e.Chat),data:{nav:"chat",title:"Chat"}},{path:"sessions",loadComponent:()=>import("./chunk-7ALHQYYG.js").then(e=>e.Sessions),data:{nav:"sessions",title:"Sessions"}},{path:"sessions/:id",loadComponent:()=>import("./chunk-C6I5R6UZ.js").then(e=>e.SessionDetail),data:{nav:"sessions",title:"Session detail"}},{path:"heatmap",loadComponent:()=>import("./chunk-EAWW6PQJ.js").then(e=>e.Heatmap),data:{nav:"heatmap",title:"Heatmap"}},{path:"costs",loadComponent:()=>import("./chunk-G2FTQVMJ.js").then(e=>e.Costs),data:{nav:"costs",title:"Costs"}},{path:"specship-impact",loadComponent:()=>import("./chunk-5CR7TMVN.js").then(e=>e.SpecshipImpact),data:{nav:"specship-impact",title:"SpecShip Impact"}},{path:"compare",loadComponent:()=>import("./chunk-7V4MGZCG.js").then(e=>e.Compare),data:{nav:"compare",title:"Compare projects"}},{path:"tips",loadComponent:()=>import("./chunk-D7HQMX7C.js").then(e=>e.Tips),data:{nav:"tips",title:"Tips"}},{path:"memory",loadComponent:()=>import("./chunk-YPWBUJH7.js").then(e=>e.Memory),data:{nav:"memory",title:"Memory"}},{path:"design",loadComponent:()=>import("./chunk-4G7XU55L.js").then(e=>e.Design),data:{nav:"design",title:"Design system"}},{path:"mcp",loadComponent:()=>import("./chunk-BZ5SMVXG.js").then(e=>e.Mcp),data:{nav:"mcp",title:"MCP servers"}},{path:"mcp/:id",loadComponent:()=>import("./chunk-Z23KACD6.js").then(e=>e.McpDetail),data:{nav:"mcp",title:"MCP server"}},{path:"settings",loadComponent:()=>import("./chunk-G2MHCJUR.js").then(e=>e.Settings),data:{nav:"settings",title:"Settings"}},{path:"**",redirectTo:"dashboard"}];var he={providers:[ne(),ce(ve)]};var _e=e=>["/",e],be=(e,n)=>n.group,xe=(e,n)=>n.id;function Ce(e,n){e&1&&(a(0,"div",3),s(1,"SpecShip "),a(2,"span",14),s(3,"Desktop"),r()())}function ye(e,n){if(e&1&&(a(0,"div",15),s(1),r()),e&2){let t=d().$implicit;o(),h(t.group)}}function Pe(e,n){if(e&1&&(a(0,"span",18),s(1),r()),e&2){let t=d(2).$implicit,i=d(2);j("data-kind",t.badgeKind),o(),h(i.badgeOf(t))}}function ke(e,n){if(e&1&&(a(0,"span",11),s(1),r(),m(2,Pe,2,2,"span",18)),e&2){let t=d().$implicit,i=d(2);o(),h(t.label),o(),u(i.badgeOf(t)>0?2:-1)}}function we(e,n){if(e&1&&(a(0,"a",16),p(1,"span",8),a(2,"span",9),p(3,"app-icon",17),r(),m(4,ke,3,2),r()),e&2){let t=n.$implicit,i=d(2);f("routerLink",re(5,_e,t.id))("title",i.collapsed()?t.label:null),o(3),f("name",t.icon)("size",16),o(),u(i.collapsed()?-1:4)}}function Me(e,n){if(e&1&&(a(0,"div",5),m(1,ye,2,1,"div",15),S(2,we,5,7,"a",16,xe),r()),e&2){let t=n.$implicit,i=d();o(),u(i.collapsed()?-1:1),o(),O(t.items)}}function Se(e,n){e&1&&(a(0,"span",11),s(1,"Design system"),r())}function Oe(e,n){e&1&&(a(0,"span",11),s(1,"Settings"),r())}var G=class e{collapsed=H(!1);api=g(V);projects=g(I);status=z(this.api,()=>`/api/status${this.projects.projectQuery()}`);tips=z(this.api,()=>"/api/claude/tips");improvements=z(this.api,()=>"/api/reflect?state=open");nav=[{group:"Project",items:[{id:"dashboard",label:"Dashboard",icon:"dashboard"},{id:"graph",label:"Graph",icon:"graph"},{id:"specs",label:"Specs",icon:"book"},{id:"domain",label:"Domain",icon:"layers"},{id:"drift",label:"Drift queue",icon:"drift",badge:()=>this.status.state().data?.drift??0,badgeKind:"warn"},{id:"maintainability",label:"Maintainability",icon:"wrench"},{id:"improvements",label:"Improvements",icon:"sparkles",badge:()=>(this.improvements.state().data?.proposals??[]).filter(n=>n.severity==="high").length,badgeKind:"error"},{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:"mcp",label:"MCP",icon:"plug"},{id:"tips",label:"Tips",icon:"tips",badge:()=>(this.tips.state().data?.tips??[]).filter(n=>n.severity!=="info").length,badgeKind:"error"}]}];badgeOf(n){return n.badge?n.badge():0}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-sidebar"]],inputs:{collapsed:[1,"collapsed"]},decls:18,vars:10,consts:[[1,"sidebar"],[1,"brand"],[3,"size"],[1,"brand-text"],[1,"scroll-y","nav-scroll"],[1,"nav-group"],[1,"pinned"],["routerLink","/design","routerLinkActive","active",1,"nav-item",3,"title"],[1,"indicator"],[1,"nav-icon"],["name","palette",3,"size"],[1,"nav-label"],["routerLink","/settings","routerLinkActive","active",1,"nav-item",3,"title"],["name","settings",3,"size"],[1,"muted"],[1,"eyebrow","group-label"],["routerLinkActive","active",1,"nav-item",3,"routerLink","title"],[3,"name","size"],[1,"badge"]],template:function(t,i){t&1&&(a(0,"nav",0)(1,"div",1),p(2,"app-logo-mark",2),m(3,Ce,4,0,"div",3),r(),a(4,"div",4),S(5,Me,4,1,"div",5,be),r(),a(7,"div",6)(8,"a",7),p(9,"span",8),a(10,"span",9),p(11,"app-icon",10),r(),m(12,Se,2,0,"span",11),r(),a(13,"a",12),p(14,"span",8),a(15,"span",9),p(16,"app-icon",13),r(),m(17,Oe,2,0,"span",11),r()()()),t&2&&(k("collapsed",i.collapsed()),o(2),f("size",26),o(),u(i.collapsed()?-1:3),o(2),O(i.nav),o(3),f("title",i.collapsed()?"Design system":null),o(3),f("size",16),o(),u(i.collapsed()?-1:12),o(),f("title",i.collapsed()?"Settings":null),o(3),f("size",16),o(),u(i.collapsed()?-1:17))},dependencies:[pe,de,R,ge],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&&(c(0,"span",8),s(1),v(),M(2,"span",1),c(3,"span",9)(4,"span",10),s(5,"nodes"),v(),c(6,"span",4),s(7),v()(),c(8,"span",9)(9,"span",10),s(10,"edges"),v(),c(11,"span",4),s(12),v()(),M(13,"span",1),c(14,"span",9)(15,"span",10),s(16,"drift"),v(),c(17,"span",4),s(18),v()(),M(19,"span",11),c(20,"span",9)(21,"span",10),s(22,"indexed"),v(),c(23,"span",4),s(24),v()()),e&2){let t=d(),i=t.status.state().data;o(),h(i.projectPath),o(6),h(i.nodeCount.toLocaleString()),o(5),h(i.edgeCount.toLocaleString()),o(5),k("warn",i.drift>0)("success",i.drift===0),o(),h(i.drift),o(6),h(t.indexedLabel())}}function je(e,n){e&1&&(c(0,"span",12),s(1,"loading status\u2026"),v(),M(2,"span",11))}function Te(e,n){if(e&1&&(c(0,"span",12),s(1),v(),M(2,"span",11)),e&2){let t=d();o(),h(t.conn.online()?"no backend":"offline \u2014 no cached data")}}function De(e,n){e&1&&(c(0,"span",5),s(1),v()),e&2&&(o(),A("\xB7 ",n))}function Ie(e,n){e&1&&(c(0,"span",6),s(1,"\u26A0"),v()),e&2&&$("title",n)}var K=class e{api=g(V);projects=g(I);refreshSvc=g(ue);conn=g(me);status=z(this.api,()=>`/api/status${this.projects.projectQuery()}`);offlineAge=T(()=>{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=T(()=>{let n=this.status.state().data?.lastIndexed;if(!n)return"never";try{let t=new Date(n),i=Date.now()-t.getTime();return i<6e4?"just now":i<36e5?`${Math.round(i/6e4)}m ago`:i<864e5?`${Math.round(i/36e5)}h ago`:t.toLocaleDateString()}catch{return String(n)}});async refresh(){await this.refreshSvc.triggerGlobalRefresh()}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-status-strip"]],decls: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&&(c(0,"div",0),m(1,Ee,25,9)(2,je,3,0)(3,Te,3,1),M(4,"span",1),c(5,"span",2),M(6,"span",3),c(7,"span",4),s(8),v(),m(9,De,2,1,"span",5),v(),m(10,Ie,2,1,"span",6),c(11,"button",7),L("click",function(){return i.refresh()}),s(12,"\u21BB"),v()()),t&2){let l,_;o(),u(i.status.state().data?1:i.status.state().loading?2:3),o(4),$("title",i.conn.online()?"Connected to the SpecShip server":"Server unreachable \u2014 showing the last cached data"),o(),k("live",i.conn.online())("off",!i.conn.online()),o(2),h(i.conn.online()?"Live":"Offline"),o(),u((l=!i.conn.online()&&i.offlineAge())?9:-1,l),o(),u((_=i.refreshSvc.error())?10:-1,_),o(),k("spinning",i.refreshSvc.loading()),$("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"),j("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 Re(e,n){e&1&&p(0,"span",8)}function Le(e,n){e&1&&p(0,"span",9)}function Ae(e,n){e&1&&p(0,"span",10)}function Ne(e,n){if(e&1&&(a(0,"span",7),s(1),r(),m(2,Re,1,0,"span",8)(3,Le,1,0,"span",9)(4,Ae,1,0,"span",10)),e&2){let t=n,i=d();o(),h(i.shortPath(t.path)),o(),u(t.exists?t.initialized?4:3:2)}}function Fe(e,n){e&1&&(a(0,"span",3),s(1,"Select project"),r())}function Be(e,n){if(e&1){let t=P();a(0,"button",20),b("click",function(){C(t);let l=d(2);return y(l.clear())}),p(1,"app-icon",21),s(2," Clear "),r()}e&2&&(o(),f("size",11))}function $e(e,n){e&1&&(a(0,"span",16),s(1,"\xB7 loading\u2026"),r())}function He(e,n){if(e&1&&(a(0,"span",16),s(1),r()),e&2){let t=d(2);o(),A("\xB7 ",t.filtered().length," shown \xB7 live")}}function Ve(e,n){e&1&&(a(0,"div",18),s(1,"No projects match."),r())}function qe(e,n){e&1&&(a(0,"span",25),s(1,"missing"),r())}function Ge(e,n){e&1&&(a(0,"span",26),s(1,"not init"),r())}function Ke(e,n){e&1&&(a(0,"span",27),s(1,"initialized"),r())}function We(e,n){if(e&1&&(a(0,"span"),s(1),r()),e&2){let t=d().$implicit,i=d(2);o(),A("\xB7 ",i.formatRelative(t.lastModifiedMs))}}function Qe(e,n){e&1&&p(0,"app-icon",29),e&2&&f("size",13)}function Je(e,n){if(e&1){let t=P();a(0,"button",22),b("click",function(){let l=C(t).$implicit,_=d(2);return y(_.pick(l.slug))}),a(1,"div",23)(2,"div",24)(3,"span",7),s(4),r(),m(5,qe,2,0,"span",25)(6,Ge,2,0,"span",26)(7,Ke,2,0,"span",27),r(),a(8,"div",28)(9,"span"),s(10),r(),m(11,We,2,1,"span"),r()(),m(12,Qe,1,1,"app-icon",29),r()}if(e&2){let t=n.$implicit,i=d(2);k("active",i.projects.activeSlug()===t.slug),o(4),h(i.shortPath(t.path)),o(),u(t.exists?t.initialized?7:6:5),o(5),ae("",t.sessionCount," session",t.sessionCount===1?"":"s"),o(),u(t.lastModifiedMs>0?11:-1),o(),u(i.projects.activeSlug()===t.slug?12:-1)}}function Ue(e,n){if(e&1){let t=P();a(0,"div",6)(1,"div",11),p(2,"app-icon",12),a(3,"input",13),b("input",function(l){C(t);let _=d();return y(_.onQuery(l.target.value))}),r(),m(4,Be,3,1,"button",14),r(),a(5,"div",15)(6,"span"),s(7),r(),m(8,$e,2,0,"span",16)(9,He,2,1,"span",16),r(),a(10,"div",17),m(11,Ve,2,0,"div",18),S(12,Je,13,8,"button",19,ze),r()()}if(e&2){let t=d();o(2),f("size",13),o(),f("value",t.query()),o(),u(t.projects.activeSlug()?4:-1),o(3),h(t.projects.claudeRoot()??"~/.claude/projects"),o(),u(t.projects.loading()?8:9),o(3),u(t.filtered().length===0&&!t.projects.loading()?11:-1),o(),O(t.filtered())}}var W=class e{host=g(ie);projects=g(I);open=w(!1);query=w("");filtered=T(()=>{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=T(()=>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 l=Math.round(i/60);if(l<60)return`${l}m ago`;let _=Math.round(l/60);if(_<24)return`${_}h ago`;let ee=Math.round(_/24);return ee<30?`${ee}d ago`:new Date(n).toLocaleDateString()}shortPath(n){if(!n)return"";let t=this.detectHome();return t&&n===t?"~":t&&n.startsWith(t+"/")?"~/"+n.slice(t.length+1):n}detectHome(){let n=this.projects.claudeRoot();if(!n)return null;let t="/.claude/projects";return n.endsWith(t)?n.slice(0,-t.length):null}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-project-picker"]],hostBindings:function(t,i){t&1&&b("click",function(_){return i.onDocumentClick(_)},Z)("keydown.escape",function(){return i.onEscape()},Z)},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),b("click",function(){return i.toggle()}),p(2,"app-icon",2),m(3,Ne,5,2)(4,Fe,2,0,"span",3),a(5,"span",4),s(6),r(),p(7,"app-icon",5),r(),m(8,Ue,14,6,"div",6),r()),t&2){let l;k("open",i.open()),o(),j("aria-expanded",i.open()),o(),f("size",13),o(),u((l=i.projects.active())?3:4,l),o(3),h(i.badge()),o(),f("name",i.open()?"chevronDown":"chevronRight")("size",11),o(),u(i.open()?8:-1)}},dependencies:[R],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 Q=class e{deferred=null;canInstall=w(!1);constructor(){typeof window>"u"||window.matchMedia?.("(display-mode: standalone)").matches===!0||window.navigator.standalone===!0||(window.addEventListener("beforeinstallprompt",t=>{t.preventDefault(),this.deferred=t,this.canInstall.set(!0)}),window.addEventListener("appinstalled",()=>{this.deferred=null,this.canInstall.set(!1)}))}async install(){let n=this.deferred;if(n){this.deferred=null,this.canInstall.set(!1);try{await n.prompt(),await n.userChoice}catch{}}}static \u0275fac=function(t){return new(t||e)};static \u0275prov=B({token:e,factory:e.\u0275fac,providedIn:"root"})};function Ye(e,n){if(e&1){let t=P();a(0,"button",9),b("click",function(){C(t);let l=d();return y(l.onInstall())}),p(1,"app-icon",10),a(2,"span"),s(3,"Install"),r()()}e&2&&(o(),f("size",14))}var J=class e{toggleSidebar=N();openPalette=N();theme=g(q);effective=this.theme.effective;pwa=g(Q);onToggleTheme(){this.theme.toggle()}onMenuClick(){this.toggleSidebar.emit()}onPalette(){this.openPalette.emit()}onInstall(){this.pwa.install()}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-top-bar"]],outputs:{toggleSidebar:"toggleSidebar",openPalette:"openPalette"},decls:14,vars:6,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"],["title","Install SpecShip as an app","aria-label","Install SpecShip as an app",1,"ghost",2,"display","inline-flex","align-items","center","gap","6px","padding","0 10px","height","30px","font-size","12px"],["aria-label","Toggle theme",1,"ghost","icon-btn",3,"click","title"],[3,"name","size"],["title","Install SpecShip as an app","aria-label","Install SpecShip as an app",1,"ghost",2,"display","inline-flex","align-items","center","gap","6px","padding","0 10px","height","30px","font-size","12px",3,"click"],["name","plus",3,"size"]],template:function(t,i){t&1&&(a(0,"div",0)(1,"button",1),b("click",function(){return i.onMenuClick()}),p(2,"app-icon",2),r(),p(3,"app-project-picker"),a(4,"button",3),b("click",function(){return i.onPalette()}),p(5,"app-icon",4),a(6,"span"),s(7,"Search or jump to\u2026"),r(),a(8,"kbd"),s(9,"\u2318K"),r()(),p(10,"span",5),m(11,Ye,4,1,"button",6),a(12,"button",7),b("click",function(){return i.onToggleTheme()}),p(13,"app-icon",8),r()()),t&2&&(o(2),f("size",16),o(3),f("size",13),o(6),u(i.pwa.canInstall()?11:-1),o(),f("title","Theme: "+i.effective()),o(),f("name",i.effective()==="dark"?"sun":"moon")("size",16))},dependencies:[R,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 Xe=(e,n)=>n.id;function Ze(e,n){if(e&1){let t=P();c(0,"button",6),L("click",function(){let l=C(t).$implicit,_=d(2);return y(_.go(l.id))}),c(1,"span",7),s(2),v(),c(3,"span",8),s(4),v()()}if(e&2){let t=n.$implicit;o(2),h(t.label),o(2),h(t.sub)}}function et(e,n){if(e&1){let t=P();c(0,"div",1),L("click",function(l){C(t);let _=d();return y(_.onBackdrop(l))}),c(1,"div",2)(2,"div",3)(3,"span"),s(4,"Jump to\u2026"),v(),c(5,"kbd"),s(6,"esc"),v()(),c(7,"div",4),S(8,Ze,5,2,"button",5,Xe),v()()()}if(e&2){let t=d();o(8),O(t.items)}}var tt=[{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"}],U=class e{open=H(!1);close=N();router=g(D);items=tt;go(n){this.router.navigate(["/"+n]),this.close.emit()}onBackdrop(n){n.target===n.currentTarget&&this.close.emit()}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-command-palette"]],inputs:{open:[1,"open"]},outputs:{close:"close"},decls:1,vars:1,consts:[[1,"backdrop"],[1,"backdrop",3,"click"],[1,"palette"],[1,"palette-header"],[1,"palette-list","scroll-y"],[1,"item"],[1,"item",3,"click"],[1,"label"],[1,"sub","mono"]],template:function(t,i){t&1&&m(0,et,10,0,"div",0),t&2&&u(i.open()?0:-1)},styles:["[_nghost-%COMP%]{display:contents}.backdrop[_ngcontent-%COMP%]{position:fixed;inset:0;background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);display:grid;place-items:start center;padding-top:12vh;z-index:100;animation:fadeIn .1s}.palette[_ngcontent-%COMP%]{width:560px;max-width:90vw;background:var(--bg-elevated);border:1px solid var(--border-strong);border-radius:12px;box-shadow:var(--shadow-pop);overflow:hidden}.palette-header[_ngcontent-%COMP%]{display:flex;justify-content:space-between;align-items:center;padding:12px 14px;border-bottom:1px solid var(--border-subtle);font-size:13px}.palette-list[_ngcontent-%COMP%]{max-height:380px;padding:6px}.item[_ngcontent-%COMP%]{display:flex;justify-content:space-between;align-items:center;width:100%;padding:8px 10px;background:transparent;border:none;border-radius:7px;cursor:pointer;color:var(--text-primary);font-family:inherit;font-size:13px;text-align:left}.item[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.label[_ngcontent-%COMP%]{flex:1}.sub[_ngcontent-%COMP%]{font-size:10.5px;color:var(--text-muted)}kbd[_ngcontent-%COMP%]{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:4px;padding:2px 6px}"],changeDetection:0})};var Y=class e{es=null;notify=g(fe);router=g(D);start(){if(!(this.es||typeof EventSource>"u")){try{this.es=new EventSource("/api/events")}catch{return}this.es.onmessage=n=>{let t;try{t=JSON.parse(n.data)}catch{return}!t||t.kind!=="approval"&&t.kind!=="runDone"&&t.kind!=="drift"&&t.kind!=="reflect"||this.notify.notify(t.kind,t.title,{body:t.detail,tag:`${t.project}:${t.kind}:${t.id}`,onClick:()=>this.routeFor(t)})}}}stop(){this.es?.close(),this.es=null}routeFor(n){let t={project:n.project};n.kind==="drift"?this.router.navigate(["/drift"],{queryParams:t}):n.kind==="reflect"?this.router.navigate(["/improvements"],{queryParams:t}):this.router.navigate(["/runs",n.id],{queryParams:t})}static \u0275fac=function(t){return new(t||e)};static \u0275prov=B({token:e,factory:e.\u0275fac,providedIn:"root"})};var X=class e{_theme=g(q);_destroyRef=g(te);_router=g(D);_events=g(Y);constructor(){this._events.start()}sidebarCollapsed=w(typeof window<"u"&&window.innerWidth<1100);paletteOpen=w(!1);gChord={armed:!1,t:0};onGlobalKey(n){let t=n.metaKey||n.ctrlKey;if(t&&n.key.toLowerCase()==="k"){n.preventDefault(),this.paletteOpen.update(i=>!i);return}if(n.key==="Escape"){this.paletteOpen.set(!1);return}if(!t&&n.key.toLowerCase()==="g"&&!this.gChord.armed){let i=n.target;if(i&&/input|textarea/i.test(i.tagName))return;this.gChord.armed=!0,this.gChord.t=Date.now(),setTimeout(()=>{this.gChord.armed=!1},600);return}if(this.gChord.armed&&!t){let i=n.key.toLowerCase();i==="d"?this._router.navigate(["/dashboard"]):i==="g"?this._router.navigate(["/graph"]):i==="s"&&this._router.navigate(["/specs"]),this.gChord.armed=!1}}toggleSidebar(){this.sidebarCollapsed.update(n=>!n)}onOpenPalette(){this.paletteOpen.set(!0)}onClosePalette(){this.paletteOpen.set(!1)}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-root"]],hostBindings:function(t,i){t&1&&b("keydown",function(_){return i.onGlobalKey(_)},oe)},decls:8,vars:2,consts:[[1,"shell"],[3,"collapsed"],[1,"main"],[3,"toggleSidebar","openPalette"],[1,"page-frame"],[3,"close","open"]],template:function(t,i){t&1&&(a(0,"div",0),p(1,"app-sidebar",1),a(2,"div",2),p(3,"app-status-strip"),a(4,"app-top-bar",3),b("toggleSidebar",function(){return i.toggleSidebar()})("openPalette",function(){return i.onOpenPalette()}),r(),a(5,"div",4),p(6,"router-outlet"),r()(),a(7,"app-command-palette",5),b("close",function(){return i.onClosePalette()}),r()()),t&2&&(o(),f("collapsed",i.sidebarCollapsed()),o(6),f("open",i.paletteOpen()))},dependencies:[le,G,K,J,U],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})};se(X,he).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)})});
1
+ import{a as q,b as fe}from"./chunk-2IVSOVQZ.js";import{a as ge}from"./chunk-YV5LB22R.js";import{b as le,c as D,d as pe,e as de,f as ce}from"./chunk-DOKZOFKM.js";import{a as me,b as ue,c as z}from"./chunk-DTWIJ3GJ.js";import{a as I}from"./chunk-JGDK6YKG.js";import{a as V}from"./chunk-TWVVIWKO.js";import{$ as ie,Aa as p,Ba as c,Ca as v,Da as M,E as B,Ga as P,Ha as $,I as g,Ia as b,Ja as L,Ka as d,M as C,N as y,R as te,Ua as k,V as ne,Va as s,W as w,Wa as h,Xa as A,Ya as ae,ca as oe,cb as re,da as Z,ea as o,ka as x,lb as T,ob as N,pb as H,qa as j,ra as m,sa as u,va as S,wa as O,wb as se,xa as f,ya as a,za as r,zb as R}from"./chunk-SYGIPC2P.js";import"./chunk-Q7L6LLAK.js";var ve=[{path:"",pathMatch:"full",redirectTo:"dashboard"},{path:"dashboard",loadComponent:()=>import("./chunk-H723TYYD.js").then(e=>e.Dashboard),data:{nav:"dashboard",title:"Dashboard"}},{path:"graph",loadComponent:()=>import("./chunk-F5TBUYDH.js").then(e=>e.Graph),data:{nav:"graph",title:"Graph"}},{path:"specs",loadComponent:()=>import("./chunk-HSJNHNOH.js").then(e=>e.Specs),data:{nav:"specs",title:"Specs"}},{path:"specs/:id",loadComponent:()=>import("./chunk-KYSTCHAH.js").then(e=>e.SpecDetail),data:{nav:"specs",title:"Spec"}},{path:"drift",loadComponent:()=>import("./chunk-7KWBINA7.js").then(e=>e.Drift),data:{nav:"drift",title:"Drift queue"}},{path:"improvements",loadComponent:()=>import("./chunk-CYXQILZI.js").then(e=>e.Improvements),data:{nav:"improvements",title:"Improvements"}},{path:"maintainability",loadComponent:()=>import("./chunk-K7UD24Z4.js").then(e=>e.Maintainability),data:{nav:"maintainability",title:"Maintainability"}},{path:"domain",loadComponent:()=>import("./chunk-OTQR5VFM.js").then(e=>e.Domain),data:{nav:"domain",title:"Domain"}},{path:"workflows",loadComponent:()=>import("./chunk-USVLLFVR.js").then(e=>e.Workflows),data:{nav:"workflows",title:"Workflows"}},{path:"runs",loadComponent:()=>import("./chunk-G7RXFHYO.js").then(e=>e.Runs),data:{nav:"runs",title:"Runs"}},{path:"runs/:id",loadComponent:()=>import("./chunk-U67LRNER.js").then(e=>e.RunDetail),data:{nav:"runs",title:"Run detail"}},{path:"chat",loadComponent:()=>import("./chunk-PS6HRYQQ.js").then(e=>e.Chat),data:{nav:"chat",title:"Chat"}},{path:"sessions",loadComponent:()=>import("./chunk-MNFTHCSJ.js").then(e=>e.Sessions),data:{nav:"sessions",title:"Sessions"}},{path:"sessions/:id",loadComponent:()=>import("./chunk-FC3R7YHR.js").then(e=>e.SessionDetail),data:{nav:"sessions",title:"Session detail"}},{path:"heatmap",loadComponent:()=>import("./chunk-POCVU4VK.js").then(e=>e.Heatmap),data:{nav:"heatmap",title:"Heatmap"}},{path:"costs",loadComponent:()=>import("./chunk-E27QAKAB.js").then(e=>e.Costs),data:{nav:"costs",title:"Costs"}},{path:"specship-impact",loadComponent:()=>import("./chunk-JPSYO24K.js").then(e=>e.SpecshipImpact),data:{nav:"specship-impact",title:"SpecShip Impact"}},{path:"compare",loadComponent:()=>import("./chunk-XAUQEKZX.js").then(e=>e.Compare),data:{nav:"compare",title:"Compare projects"}},{path:"tips",loadComponent:()=>import("./chunk-YXYPTZ6E.js").then(e=>e.Tips),data:{nav:"tips",title:"Tips"}},{path:"memory",loadComponent:()=>import("./chunk-EXBUKHH2.js").then(e=>e.Memory),data:{nav:"memory",title:"Memory"}},{path:"design",loadComponent:()=>import("./chunk-4G7XU55L.js").then(e=>e.Design),data:{nav:"design",title:"Design system"}},{path:"mcp",loadComponent:()=>import("./chunk-7MUNFW56.js").then(e=>e.Mcp),data:{nav:"mcp",title:"MCP servers"}},{path:"mcp/:id",loadComponent:()=>import("./chunk-AZUUBUEJ.js").then(e=>e.McpDetail),data:{nav:"mcp",title:"MCP server"}},{path:"settings",loadComponent:()=>import("./chunk-PCW6R7OP.js").then(e=>e.Settings),data:{nav:"settings",title:"Settings"}},{path:"**",redirectTo:"dashboard"}];var he={providers:[ne(),ce(ve)]};var _e=e=>["/",e],be=(e,n)=>n.group,xe=(e,n)=>n.id;function Ce(e,n){e&1&&(a(0,"div",3),s(1,"SpecShip "),a(2,"span",14),s(3,"Desktop"),r()())}function ye(e,n){if(e&1&&(a(0,"div",15),s(1),r()),e&2){let t=d().$implicit;o(),h(t.group)}}function Pe(e,n){if(e&1&&(a(0,"span",18),s(1),r()),e&2){let t=d(2).$implicit,i=d(2);j("data-kind",t.badgeKind),o(),h(i.badgeOf(t))}}function ke(e,n){if(e&1&&(a(0,"span",11),s(1),r(),m(2,Pe,2,2,"span",18)),e&2){let t=d().$implicit,i=d(2);o(),h(t.label),o(),u(i.badgeOf(t)>0?2:-1)}}function we(e,n){if(e&1&&(a(0,"a",16),p(1,"span",8),a(2,"span",9),p(3,"app-icon",17),r(),m(4,ke,3,2),r()),e&2){let t=n.$implicit,i=d(2);f("routerLink",re(5,_e,t.id))("title",i.collapsed()?t.label:null),o(3),f("name",t.icon)("size",16),o(),u(i.collapsed()?-1:4)}}function Me(e,n){if(e&1&&(a(0,"div",5),m(1,ye,2,1,"div",15),S(2,we,5,7,"a",16,xe),r()),e&2){let t=n.$implicit,i=d();o(),u(i.collapsed()?-1:1),o(),O(t.items)}}function Se(e,n){e&1&&(a(0,"span",11),s(1,"Design system"),r())}function Oe(e,n){e&1&&(a(0,"span",11),s(1,"Settings"),r())}var G=class e{collapsed=H(!1);api=g(V);projects=g(I);status=z(this.api,()=>`/api/status${this.projects.projectQuery()}`);tips=z(this.api,()=>"/api/claude/tips");improvements=z(this.api,()=>"/api/reflect?state=open");nav=[{group:"Project",items:[{id:"dashboard",label:"Dashboard",icon:"dashboard"},{id:"graph",label:"Graph",icon:"graph"},{id:"specs",label:"Specs",icon:"book"},{id:"domain",label:"Domain",icon:"layers"},{id:"drift",label:"Drift queue",icon:"drift",badge:()=>this.status.state().data?.drift??0,badgeKind:"warn"},{id:"maintainability",label:"Maintainability",icon:"wrench"},{id:"improvements",label:"Improvements",icon:"sparkles",badge:()=>(this.improvements.state().data?.proposals??[]).filter(n=>n.severity==="high").length,badgeKind:"error"},{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:"mcp",label:"MCP",icon:"plug"},{id:"tips",label:"Tips",icon:"tips",badge:()=>(this.tips.state().data?.tips??[]).filter(n=>n.severity!=="info").length,badgeKind:"error"}]}];badgeOf(n){return n.badge?n.badge():0}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-sidebar"]],inputs:{collapsed:[1,"collapsed"]},decls:18,vars:10,consts:[[1,"sidebar"],[1,"brand"],[3,"size"],[1,"brand-text"],[1,"scroll-y","nav-scroll"],[1,"nav-group"],[1,"pinned"],["routerLink","/design","routerLinkActive","active",1,"nav-item",3,"title"],[1,"indicator"],[1,"nav-icon"],["name","palette",3,"size"],[1,"nav-label"],["routerLink","/settings","routerLinkActive","active",1,"nav-item",3,"title"],["name","settings",3,"size"],[1,"muted"],[1,"eyebrow","group-label"],["routerLinkActive","active",1,"nav-item",3,"routerLink","title"],[3,"name","size"],[1,"badge"]],template:function(t,i){t&1&&(a(0,"nav",0)(1,"div",1),p(2,"app-logo-mark",2),m(3,Ce,4,0,"div",3),r(),a(4,"div",4),S(5,Me,4,1,"div",5,be),r(),a(7,"div",6)(8,"a",7),p(9,"span",8),a(10,"span",9),p(11,"app-icon",10),r(),m(12,Se,2,0,"span",11),r(),a(13,"a",12),p(14,"span",8),a(15,"span",9),p(16,"app-icon",13),r(),m(17,Oe,2,0,"span",11),r()()()),t&2&&(k("collapsed",i.collapsed()),o(2),f("size",26),o(),u(i.collapsed()?-1:3),o(2),O(i.nav),o(3),f("title",i.collapsed()?"Design system":null),o(3),f("size",16),o(),u(i.collapsed()?-1:12),o(),f("title",i.collapsed()?"Settings":null),o(3),f("size",16),o(),u(i.collapsed()?-1:17))},dependencies:[pe,de,R,ge],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&&(c(0,"span",8),s(1),v(),M(2,"span",1),c(3,"span",9)(4,"span",10),s(5,"nodes"),v(),c(6,"span",4),s(7),v()(),c(8,"span",9)(9,"span",10),s(10,"edges"),v(),c(11,"span",4),s(12),v()(),M(13,"span",1),c(14,"span",9)(15,"span",10),s(16,"drift"),v(),c(17,"span",4),s(18),v()(),M(19,"span",11),c(20,"span",9)(21,"span",10),s(22,"indexed"),v(),c(23,"span",4),s(24),v()()),e&2){let t=d(),i=t.status.state().data;o(),h(i.projectPath),o(6),h(i.nodeCount.toLocaleString()),o(5),h(i.edgeCount.toLocaleString()),o(5),k("warn",i.drift>0)("success",i.drift===0),o(),h(i.drift),o(6),h(t.indexedLabel())}}function je(e,n){e&1&&(c(0,"span",12),s(1,"loading status\u2026"),v(),M(2,"span",11))}function Te(e,n){if(e&1&&(c(0,"span",12),s(1),v(),M(2,"span",11)),e&2){let t=d();o(),h(t.conn.online()?"no backend":"offline \u2014 no cached data")}}function De(e,n){e&1&&(c(0,"span",5),s(1),v()),e&2&&(o(),A("\xB7 ",n))}function Ie(e,n){e&1&&(c(0,"span",6),s(1,"\u26A0"),v()),e&2&&$("title",n)}var K=class e{api=g(V);projects=g(I);refreshSvc=g(ue);conn=g(me);status=z(this.api,()=>`/api/status${this.projects.projectQuery()}`);offlineAge=T(()=>{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=T(()=>{let n=this.status.state().data?.lastIndexed;if(!n)return"never";try{let t=new Date(n),i=Date.now()-t.getTime();return i<6e4?"just now":i<36e5?`${Math.round(i/6e4)}m ago`:i<864e5?`${Math.round(i/36e5)}h ago`:t.toLocaleDateString()}catch{return String(n)}});async refresh(){await this.refreshSvc.triggerGlobalRefresh()}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-status-strip"]],decls: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&&(c(0,"div",0),m(1,Ee,25,9)(2,je,3,0)(3,Te,3,1),M(4,"span",1),c(5,"span",2),M(6,"span",3),c(7,"span",4),s(8),v(),m(9,De,2,1,"span",5),v(),m(10,Ie,2,1,"span",6),c(11,"button",7),L("click",function(){return i.refresh()}),s(12,"\u21BB"),v()()),t&2){let l,_;o(),u(i.status.state().data?1:i.status.state().loading?2:3),o(4),$("title",i.conn.online()?"Connected to the SpecShip server":"Server unreachable \u2014 showing the last cached data"),o(),k("live",i.conn.online())("off",!i.conn.online()),o(2),h(i.conn.online()?"Live":"Offline"),o(),u((l=!i.conn.online()&&i.offlineAge())?9:-1,l),o(),u((_=i.refreshSvc.error())?10:-1,_),o(),k("spinning",i.refreshSvc.loading()),$("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"),j("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 Re(e,n){e&1&&p(0,"span",8)}function Le(e,n){e&1&&p(0,"span",9)}function Ae(e,n){e&1&&p(0,"span",10)}function Ne(e,n){if(e&1&&(a(0,"span",7),s(1),r(),m(2,Re,1,0,"span",8)(3,Le,1,0,"span",9)(4,Ae,1,0,"span",10)),e&2){let t=n,i=d();o(),h(i.shortPath(t.path)),o(),u(t.exists?t.initialized?4:3:2)}}function Fe(e,n){e&1&&(a(0,"span",3),s(1,"Select project"),r())}function Be(e,n){if(e&1){let t=P();a(0,"button",20),b("click",function(){C(t);let l=d(2);return y(l.clear())}),p(1,"app-icon",21),s(2," Clear "),r()}e&2&&(o(),f("size",11))}function $e(e,n){e&1&&(a(0,"span",16),s(1,"\xB7 loading\u2026"),r())}function He(e,n){if(e&1&&(a(0,"span",16),s(1),r()),e&2){let t=d(2);o(),A("\xB7 ",t.filtered().length," shown \xB7 live")}}function Ve(e,n){e&1&&(a(0,"div",18),s(1,"No projects match."),r())}function qe(e,n){e&1&&(a(0,"span",25),s(1,"missing"),r())}function Ge(e,n){e&1&&(a(0,"span",26),s(1,"not init"),r())}function Ke(e,n){e&1&&(a(0,"span",27),s(1,"initialized"),r())}function We(e,n){if(e&1&&(a(0,"span"),s(1),r()),e&2){let t=d().$implicit,i=d(2);o(),A("\xB7 ",i.formatRelative(t.lastModifiedMs))}}function Qe(e,n){e&1&&p(0,"app-icon",29),e&2&&f("size",13)}function Je(e,n){if(e&1){let t=P();a(0,"button",22),b("click",function(){let l=C(t).$implicit,_=d(2);return y(_.pick(l.slug))}),a(1,"div",23)(2,"div",24)(3,"span",7),s(4),r(),m(5,qe,2,0,"span",25)(6,Ge,2,0,"span",26)(7,Ke,2,0,"span",27),r(),a(8,"div",28)(9,"span"),s(10),r(),m(11,We,2,1,"span"),r()(),m(12,Qe,1,1,"app-icon",29),r()}if(e&2){let t=n.$implicit,i=d(2);k("active",i.projects.activeSlug()===t.slug),o(4),h(i.shortPath(t.path)),o(),u(t.exists?t.initialized?7:6:5),o(5),ae("",t.sessionCount," session",t.sessionCount===1?"":"s"),o(),u(t.lastModifiedMs>0?11:-1),o(),u(i.projects.activeSlug()===t.slug?12:-1)}}function Ue(e,n){if(e&1){let t=P();a(0,"div",6)(1,"div",11),p(2,"app-icon",12),a(3,"input",13),b("input",function(l){C(t);let _=d();return y(_.onQuery(l.target.value))}),r(),m(4,Be,3,1,"button",14),r(),a(5,"div",15)(6,"span"),s(7),r(),m(8,$e,2,0,"span",16)(9,He,2,1,"span",16),r(),a(10,"div",17),m(11,Ve,2,0,"div",18),S(12,Je,13,8,"button",19,ze),r()()}if(e&2){let t=d();o(2),f("size",13),o(),f("value",t.query()),o(),u(t.projects.activeSlug()?4:-1),o(3),h(t.projects.claudeRoot()??"~/.claude/projects"),o(),u(t.projects.loading()?8:9),o(3),u(t.filtered().length===0&&!t.projects.loading()?11:-1),o(),O(t.filtered())}}var W=class e{host=g(ie);projects=g(I);open=w(!1);query=w("");filtered=T(()=>{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=T(()=>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 l=Math.round(i/60);if(l<60)return`${l}m ago`;let _=Math.round(l/60);if(_<24)return`${_}h ago`;let ee=Math.round(_/24);return ee<30?`${ee}d ago`:new Date(n).toLocaleDateString()}shortPath(n){if(!n)return"";let t=this.detectHome();return t&&n===t?"~":t&&n.startsWith(t+"/")?"~/"+n.slice(t.length+1):n}detectHome(){let n=this.projects.claudeRoot();if(!n)return null;let t="/.claude/projects";return n.endsWith(t)?n.slice(0,-t.length):null}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-project-picker"]],hostBindings:function(t,i){t&1&&b("click",function(_){return i.onDocumentClick(_)},Z)("keydown.escape",function(){return i.onEscape()},Z)},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),b("click",function(){return i.toggle()}),p(2,"app-icon",2),m(3,Ne,5,2)(4,Fe,2,0,"span",3),a(5,"span",4),s(6),r(),p(7,"app-icon",5),r(),m(8,Ue,14,6,"div",6),r()),t&2){let l;k("open",i.open()),o(),j("aria-expanded",i.open()),o(),f("size",13),o(),u((l=i.projects.active())?3:4,l),o(3),h(i.badge()),o(),f("name",i.open()?"chevronDown":"chevronRight")("size",11),o(),u(i.open()?8:-1)}},dependencies:[R],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 Q=class e{deferred=null;canInstall=w(!1);constructor(){typeof window>"u"||window.matchMedia?.("(display-mode: standalone)").matches===!0||window.navigator.standalone===!0||(window.addEventListener("beforeinstallprompt",t=>{t.preventDefault(),this.deferred=t,this.canInstall.set(!0)}),window.addEventListener("appinstalled",()=>{this.deferred=null,this.canInstall.set(!1)}))}async install(){let n=this.deferred;if(n){this.deferred=null,this.canInstall.set(!1);try{await n.prompt(),await n.userChoice}catch{}}}static \u0275fac=function(t){return new(t||e)};static \u0275prov=B({token:e,factory:e.\u0275fac,providedIn:"root"})};function Ye(e,n){if(e&1){let t=P();a(0,"button",9),b("click",function(){C(t);let l=d();return y(l.onInstall())}),p(1,"app-icon",10),a(2,"span"),s(3,"Install"),r()()}e&2&&(o(),f("size",14))}var J=class e{toggleSidebar=N();openPalette=N();theme=g(q);effective=this.theme.effective;pwa=g(Q);onToggleTheme(){this.theme.toggle()}onMenuClick(){this.toggleSidebar.emit()}onPalette(){this.openPalette.emit()}onInstall(){this.pwa.install()}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-top-bar"]],outputs:{toggleSidebar:"toggleSidebar",openPalette:"openPalette"},decls:14,vars:6,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"],["title","Install SpecShip as an app","aria-label","Install SpecShip as an app",1,"ghost",2,"display","inline-flex","align-items","center","gap","6px","padding","0 10px","height","30px","font-size","12px"],["aria-label","Toggle theme",1,"ghost","icon-btn",3,"click","title"],[3,"name","size"],["title","Install SpecShip as an app","aria-label","Install SpecShip as an app",1,"ghost",2,"display","inline-flex","align-items","center","gap","6px","padding","0 10px","height","30px","font-size","12px",3,"click"],["name","plus",3,"size"]],template:function(t,i){t&1&&(a(0,"div",0)(1,"button",1),b("click",function(){return i.onMenuClick()}),p(2,"app-icon",2),r(),p(3,"app-project-picker"),a(4,"button",3),b("click",function(){return i.onPalette()}),p(5,"app-icon",4),a(6,"span"),s(7,"Search or jump to\u2026"),r(),a(8,"kbd"),s(9,"\u2318K"),r()(),p(10,"span",5),m(11,Ye,4,1,"button",6),a(12,"button",7),b("click",function(){return i.onToggleTheme()}),p(13,"app-icon",8),r()()),t&2&&(o(2),f("size",16),o(3),f("size",13),o(6),u(i.pwa.canInstall()?11:-1),o(),f("title","Theme: "+i.effective()),o(),f("name",i.effective()==="dark"?"sun":"moon")("size",16))},dependencies:[R,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 Xe=(e,n)=>n.id;function Ze(e,n){if(e&1){let t=P();c(0,"button",6),L("click",function(){let l=C(t).$implicit,_=d(2);return y(_.go(l.id))}),c(1,"span",7),s(2),v(),c(3,"span",8),s(4),v()()}if(e&2){let t=n.$implicit;o(2),h(t.label),o(2),h(t.sub)}}function et(e,n){if(e&1){let t=P();c(0,"div",1),L("click",function(l){C(t);let _=d();return y(_.onBackdrop(l))}),c(1,"div",2)(2,"div",3)(3,"span"),s(4,"Jump to\u2026"),v(),c(5,"kbd"),s(6,"esc"),v()(),c(7,"div",4),S(8,Ze,5,2,"button",5,Xe),v()()()}if(e&2){let t=d();o(8),O(t.items)}}var tt=[{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"}],U=class e{open=H(!1);close=N();router=g(D);items=tt;go(n){this.router.navigate(["/"+n]),this.close.emit()}onBackdrop(n){n.target===n.currentTarget&&this.close.emit()}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-command-palette"]],inputs:{open:[1,"open"]},outputs:{close:"close"},decls:1,vars:1,consts:[[1,"backdrop"],[1,"backdrop",3,"click"],[1,"palette"],[1,"palette-header"],[1,"palette-list","scroll-y"],[1,"item"],[1,"item",3,"click"],[1,"label"],[1,"sub","mono"]],template:function(t,i){t&1&&m(0,et,10,0,"div",0),t&2&&u(i.open()?0:-1)},styles:["[_nghost-%COMP%]{display:contents}.backdrop[_ngcontent-%COMP%]{position:fixed;inset:0;background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);display:grid;place-items:start center;padding-top:12vh;z-index:100;animation:fadeIn .1s}.palette[_ngcontent-%COMP%]{width:560px;max-width:90vw;background:var(--bg-elevated);border:1px solid var(--border-strong);border-radius:12px;box-shadow:var(--shadow-pop);overflow:hidden}.palette-header[_ngcontent-%COMP%]{display:flex;justify-content:space-between;align-items:center;padding:12px 14px;border-bottom:1px solid var(--border-subtle);font-size:13px}.palette-list[_ngcontent-%COMP%]{max-height:380px;padding:6px}.item[_ngcontent-%COMP%]{display:flex;justify-content:space-between;align-items:center;width:100%;padding:8px 10px;background:transparent;border:none;border-radius:7px;cursor:pointer;color:var(--text-primary);font-family:inherit;font-size:13px;text-align:left}.item[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.label[_ngcontent-%COMP%]{flex:1}.sub[_ngcontent-%COMP%]{font-size:10.5px;color:var(--text-muted)}kbd[_ngcontent-%COMP%]{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:4px;padding:2px 6px}"],changeDetection:0})};var Y=class e{es=null;notify=g(fe);router=g(D);start(){if(!(this.es||typeof EventSource>"u")){try{this.es=new EventSource("/api/events")}catch{return}this.es.onmessage=n=>{let t;try{t=JSON.parse(n.data)}catch{return}!t||t.kind!=="approval"&&t.kind!=="runDone"&&t.kind!=="drift"&&t.kind!=="reflect"||this.notify.notify(t.kind,t.title,{body:t.detail,tag:`${t.project}:${t.kind}:${t.id}`,onClick:()=>this.routeFor(t)})}}}stop(){this.es?.close(),this.es=null}routeFor(n){let t={project:n.project};n.kind==="drift"?this.router.navigate(["/drift"],{queryParams:t}):n.kind==="reflect"?this.router.navigate(["/improvements"],{queryParams:t}):this.router.navigate(["/runs",n.id],{queryParams:t})}static \u0275fac=function(t){return new(t||e)};static \u0275prov=B({token:e,factory:e.\u0275fac,providedIn:"root"})};var X=class e{_theme=g(q);_destroyRef=g(te);_router=g(D);_events=g(Y);constructor(){this._events.start()}sidebarCollapsed=w(typeof window<"u"&&window.innerWidth<1100);paletteOpen=w(!1);gChord={armed:!1,t:0};onGlobalKey(n){let t=n.metaKey||n.ctrlKey;if(t&&n.key.toLowerCase()==="k"){n.preventDefault(),this.paletteOpen.update(i=>!i);return}if(n.key==="Escape"){this.paletteOpen.set(!1);return}if(!t&&n.key.toLowerCase()==="g"&&!this.gChord.armed){let i=n.target;if(i&&/input|textarea/i.test(i.tagName))return;this.gChord.armed=!0,this.gChord.t=Date.now(),setTimeout(()=>{this.gChord.armed=!1},600);return}if(this.gChord.armed&&!t){let i=n.key.toLowerCase();i==="d"?this._router.navigate(["/dashboard"]):i==="g"?this._router.navigate(["/graph"]):i==="s"&&this._router.navigate(["/specs"]),this.gChord.armed=!1}}toggleSidebar(){this.sidebarCollapsed.update(n=>!n)}onOpenPalette(){this.paletteOpen.set(!0)}onClosePalette(){this.paletteOpen.set(!1)}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-root"]],hostBindings:function(t,i){t&1&&b("keydown",function(_){return i.onGlobalKey(_)},oe)},decls:8,vars:2,consts:[[1,"shell"],[3,"collapsed"],[1,"main"],[3,"toggleSidebar","openPalette"],[1,"page-frame"],[3,"close","open"]],template:function(t,i){t&1&&(a(0,"div",0),p(1,"app-sidebar",1),a(2,"div",2),p(3,"app-status-strip"),a(4,"app-top-bar",3),b("toggleSidebar",function(){return i.toggleSidebar()})("openPalette",function(){return i.onOpenPalette()}),r(),a(5,"div",4),p(6,"router-outlet"),r()(),a(7,"app-command-palette",5),b("close",function(){return i.onClosePalette()}),r()()),t&2&&(o(),f("collapsed",i.sidebarCollapsed()),o(6),f("open",i.paletteOpen()))},dependencies:[le,G,K,J,U],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})};se(X,he).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)})});
@@ -1,5 +1,5 @@
1
1
  name: claude-design-implement
2
- description: Import a Claude Design (live URL or a designer handoff bundle) — snapshot + tokens + source record — draft the spec, gate at review, write the spec — ready to hand off to /ss-spec implement.
2
+ description: Import a Claude Design (live URL or a designer handoff bundle) — snapshot + tokens + source record — draft the spec, gate at review, write the spec — ready to hand off to /specship:spec implement.
3
3
  tags: [spec, ui, claude-design, default]
4
4
  requires: [specship, git]
5
5
 
@@ -11,10 +11,10 @@ worktree:
11
11
  enabled: true
12
12
 
13
13
  # Two entry shapes (provide exactly one source):
14
- # - CONNECTOR_URL — a live claude.ai/design URL (the `/ss-design-implement`
14
+ # - CONNECTOR_URL — a live claude.ai/design URL (the `/specship:design-implement`
15
15
  # command). The snapshot node fetches it, preferring the `designer` MCP.
16
16
  # - HANDOFF_DIR — a designer handoff bundle already on disk (the
17
- # `/ss-design-loop` command, after the human-tasted loop + designer_handoff).
17
+ # `/specship:design-loop` command, after the human-tasted loop + designer_handoff).
18
18
  # The snapshot node reads files straight from the bundle — no fetch, no CDP.
19
19
  # Optional inputs default to "" (see the CLI's declared-default handling), so a
20
20
  # `$INPUT.X` reference to an omitted optional input resolves to "" rather than
@@ -308,7 +308,7 @@ nodes:
308
308
 
309
309
  Output: the relative path of the file written + the first REQ
310
310
  ID (e.g. "REQ-DATA-FLOW-001") so the next step can hand it to
311
- /ss-spec implement.
311
+ /specship:spec implement.
312
312
 
313
313
  - id: handoff
314
314
  kind: prompt
@@ -327,7 +327,7 @@ nodes:
327
327
  - specs/$INPUT.SLUG/tokens.css
328
328
  - specs/$INPUT.SLUG/source.md
329
329
  4. The exact next command:
330
- /ss-spec implement <first REQ ID>
330
+ /specship:spec implement <first REQ ID>
331
331
  5. A one-line reminder that the implementation step should
332
332
  load the snapshot for visual fidelity — the spec covers
333
333
  contract only.
@@ -211,4 +211,4 @@ nodes:
211
211
  After writing:
212
212
  - Run `specship sync` to index the new spec.
213
213
  - Output the relative path of the file written + a one-line note
214
- about what to do next (typically: `/ss-spec implement <REQ-ID>`).
214
+ about what to do next (typically: `/specship:spec implement <REQ-ID>`).
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@specship/specship",
3
- "version": "0.11.6",
3
+ "version": "0.11.8",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@specship/specship",
3
- "version": "0.11.6",
3
+ "version": "0.11.8",
4
4
  "description": "Supercharge Claude Code with semantic code intelligence. 94% fewer tool calls • 77% faster exploration • 100% local.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@specship/specship-win32-arm64",
3
- "version": "0.11.6",
3
+ "version": "0.11.8",
4
4
  "description": "SpecShip self-contained bundle for win32-arm64",
5
5
  "os": [
6
6
  "win32"
@@ -1 +0,0 @@
1
- import{E as f}from"./chunk-SYGIPC2P.js";var g="specship.api",w=class i{base;constructor(){this.base=this.resolveBase()}resolveBase(){if(typeof window>"u")return null;try{let t=new URLSearchParams(window.location.search).get("api");if(t){try{window.localStorage.setItem(g,t)}catch{}return t.replace(/\/$/,"")}}catch{}try{let t=window.localStorage.getItem(g);if(t)return t.replace(/\/$/,"")}catch{}let e=window.SPECSHIP_API_URL;if(typeof e=="string")return e.replace(/\/$/,"");let n=window.location.hostname;return n==="localhost"||n==="127.0.0.1"?"http://localhost:4242":null}get apiBase(){return this.base}get isConfigured(){return this.base!==null}async get(e,n){if(!this.base)throw new Error("no API base configured");let t=this.base+(e.startsWith("/")?e:"/"+e),r=await fetch(t,{method:"GET",headers:{Accept:"application/json"},signal:n});if(!r.ok)throw await l("GET",e,r);return r.json()}async post(e,n,t){if(!this.base)throw new Error("no API base configured");let r=this.base+(e.startsWith("/")?e:"/"+e),s=await fetch(r,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:n==null?void 0:JSON.stringify(n),signal:t});if(!s.ok)throw await l("POST",e,s);return s.json()}async put(e,n,t){if(!this.base)throw new Error("no API base configured");let r=this.base+(e.startsWith("/")?e:"/"+e),s=await fetch(r,{method:"PUT",headers:{Accept:"application/json","Content-Type":"application/json"},body:n==null?void 0:JSON.stringify(n),signal:t});if(!s.ok)throw await l("PUT",e,s);return s.json()}openEventStream(e,n,t,r){if(!this.base)return t?.(new Error("no API base configured")),()=>{};let s=this.base+(e.startsWith("/")?e:"/"+e),a=new EventSource(s),h=r??b,d=o=>{try{return JSON.parse(o.data)}catch{return o.data}},p=[];for(let o of h){let c=y=>n(o,d(y));a.addEventListener(o,c),p.push([o,c])}return a.onmessage=o=>n("message",d(o)),a.onerror=o=>{t?.(o)},()=>{for(let[o,c]of p)a.removeEventListener(o,c);a.close()}}static \u0275fac=function(n){return new(n||i)};static \u0275prov=f({token:i,factory:i.\u0275fac,providedIn:"root"})},u=class extends Error{constructor(n,t,r,s,a){super(a);this.status=n;this.code=t;this.path=r;this.payload=s}status;code;path;payload;name="ApiError"};async function l(i,e,n){let t=await n.text().catch(()=>""),r=null,s=null;if(t)try{if(r=JSON.parse(t),r&&typeof r=="object"&&"code"in r){let a=r.code;typeof a=="string"&&(s=a)}}catch{r=t}return new u(n.status,s,e,r,`${i} ${e} \u2192 ${n.status} ${t.slice(0,200)}`)}var b=["run_started","run_completed","run_failed","run_cancelled","run_paused","step_started","step_completed","step_failed","step_skipped","tool_called","artifact_created","approval_requested","approval_granted","approval_rejected","done"];export{w as a,u as b};
@@ -1,3 +0,0 @@
1
- import{a as W}from"./chunk-JLOJCDIY.js";import{a as G}from"./chunk-YV5LB22R.js";import{b as U}from"./chunk-WBJ5VEB5.js";import{a as Q}from"./chunk-IOB4JJT4.js";import{a as K}from"./chunk-3H2EZLZN.js";import{Aa as x,Ga as k,I as O,Ia as h,Ka as s,M as v,N as y,Ra as N,Sa as H,Ta as R,Ua as B,Va as l,W as w,Wa as u,Xa as g,Ya as $,aa as z,ea as i,ka as V,lb as D,qa as T,qb as L,ra as p,sa as _,ta as F,ua as A,va as C,wa as f,xa as m,ya as o,yb as j,za as a,zb as q}from"./chunk-SYGIPC2P.js";import{a as S,b as M}from"./chunk-Q7L6LLAK.js";var te=["listEl"],ne=(t,n)=>n.name,Z=(t,n)=>n.qualifiedName,ie=(t,n)=>n.target,oe=(t,n)=>n.cmd;function ae(t,n){if(t&1&&(o(0,"div",22),x(1,"div",24),a()),t&2){let e=s().$implicit,r=s();i(),m("innerHTML",r.renderMd(e.text),z)}}function re(t,n){if(t&1&&(o(0,"div",39)(1,"div",40),l(2,"output"),a(),o(3,"div",41),l(4),a()()),t&2){let e=s().$implicit;i(4),u(e.output)}}function le(t,n){if(t&1){let e=k();o(0,"div",31)(1,"button",32),h("click",function(){let d=v(e).$implicit,c=s(3).$implicit,b=s();return y(b.toggleToolCall(c,d))}),x(2,"app-icon",33)(3,"app-icon",34),o(4,"span",35),l(5),o(6,"span",36),l(7),a()(),o(8,"span",37),x(9,"app-icon",38),l(10),a()(),p(11,re,5,1,"div",39),a()}if(t&2){let e=n.$implicit;i(),T("aria-expanded",e.open),i(),m("name",e.open?"chevronDown":"chevronRight")("size",12),i(),m("size",12),i(2),g(" ",e.name),i(2),g("(",e.input,")"),i(2),m("size",9),i(),g(" ",e.status," "),i(),_(e.open?11:-1)}}function de(t,n){if(t&1&&C(0,le,12,9,"div",31,ne),t&2){let e=s(2).$implicit;f(e.tools)}}function se(t,n){if(t&1&&l(0),t&2){let e=s(2).$implicit;g(":",e.line)}}function ce(t,n){if(t&1&&(l(0),p(1,se,1,1)),t&2){let e=s().$implicit;g(" \xB7 ",e.filePath),i(),_(e.line?1:-1)}}function pe(t,n){if(t&1&&l(0),t&2){let e=s().$implicit;g(" \xB7 ",e.ref," ")}}function _e(t,n){if(t&1&&(o(0,"div",47),l(1),a()),t&2){let e=s(3).$implicit;i(),u(e.detail.signature)}}function me(t,n){if(t&1&&(o(0,"pre",48),l(1),a()),t&2){let e=s(3).$implicit;i(),u(e.detail.body)}}function xe(t,n){if(t&1&&(o(0,"div",51),l(1),o(2,"span",36),l(3),a()()),t&2){let e=n.$implicit;i(),g("",e.name," "),i(2),$("",e.filePath,":",e.line)}}function ue(t,n){if(t&1&&(o(0,"div",49)(1,"div",50),l(2,"callers"),a(),C(3,xe,4,3,"div",51,Z),a()),t&2){let e=s(3).$implicit;i(3),f(e.detail.callers)}}function ge(t,n){if(t&1&&(o(0,"div",51),l(1),o(2,"span",36),l(3),a()()),t&2){let e=n.$implicit;i(),g("",e.name," "),i(2),$("",e.filePath,":",e.line)}}function he(t,n){if(t&1&&(o(0,"div",49)(1,"div",50),l(2,"callees"),a(),C(3,ge,4,3,"div",51,Z),a()),t&2){let e=s(3).$implicit;i(3),f(e.detail.callees)}}function Ce(t,n){if(t&1&&(p(0,_e,2,1,"div",47),p(1,me,2,1,"pre",48),p(2,ue,5,0,"div",49),p(3,he,5,0,"div",49)),t&2){let e=s(2).$implicit;_(e.detail!=null&&e.detail.signature?0:-1),i(),_(e.detail!=null&&e.detail.body?1:-1),i(),_(!(e.detail==null||e.detail.callers==null)&&e.detail.callers.length?2:-1),i(),_(!(e.detail==null||e.detail.callees==null)&&e.detail.callees.length?3:-1)}}function fe(t,n){if(t&1&&(o(0,"pre",48),l(1),a()),t&2){let e=s(3).$implicit;i(),u(e.detail.body)}}function be(t,n){if(t&1&&(o(0,"div",52)(1,"span",53),l(2),a(),x(3,"app-state-pill",54),a()),t&2){let e=n.$implicit;i(2),u(e.target),i(),m("state",e.state)}}function ve(t,n){if(t&1&&(o(0,"div",49)(1,"div",50),l(2,"links"),a(),C(3,be,4,2,"div",52,ie),a()),t&2){let e=s(3).$implicit;i(3),f(e.detail.links)}}function ye(t,n){if(t&1&&(p(0,fe,2,1,"pre",48),p(1,ve,5,0,"div",49)),t&2){let e=s(2).$implicit;_(e.detail!=null&&e.detail.body?0:-1),i(),_(!(e.detail==null||e.detail.links==null)&&e.detail.links.length?1:-1)}}function we(t,n){if(t&1&&(o(0,"pre",48),l(1),a()),t&2){let e=s(3).$implicit;i(),u(e.detail.body)}}function ke(t,n){if(t&1&&p(0,we,2,1,"pre",48),t&2){let e=s(2).$implicit;_(e.detail!=null&&e.detail.body?0:-1)}}function Se(t,n){if(t&1&&(o(0,"div",46),p(1,Ce,4,4)(2,ye,2,2)(3,ke,1,1),a()),t&2){let e=s().$implicit;i(),_(e.kind==="symbol"?1:e.kind==="spec"?2:3)}}function Me(t,n){if(t&1){let e=k();o(0,"div",43)(1,"button",44),h("click",function(){let d=v(e).$index,c=s(3).$index,b=s();return y(b.toggleDetail(c,d))}),x(2,"app-icon",33),o(3,"span",35),l(4),o(5,"span",36),p(6,ce,2,2)(7,pe,1,1),a()(),o(8,"span",45),l(9),a()(),p(10,Se,4,1,"div",46),a()}if(t&2){let e=n.$implicit,r=n.$index,d=s(3).$index,c=s();i(),T("aria-expanded",c.isDetailOpen(d,r)),i(),m("name",c.isDetailOpen(d,r)?"chevronDown":"chevronRight")("size",12),i(2),g(" ",e.label),i(2),_(e.filePath?6:7),i(3),u(e.kind),i(),_(c.isDetailOpen(d,r)?10:-1)}}function Te(t,n){if(t&1&&(o(0,"div",30)(1,"div",42),l(2),a(),C(3,Me,11,7,"div",43,F),a()),t&2){let e=s(2).$implicit;i(2),g("Retrieved detail \xB7 ",e.sources.length),i(),f(e.sources)}}function Ee(t,n){if(t&1&&(o(0,"div",23)(1,"div",25),x(2,"app-logo-mark",26),o(3,"span",27),l(4,"specship"),a()(),o(5,"div",28),x(6,"div",29),p(7,de,2,0),p(8,Te,5,1,"div",30),a()()),t&2){let e=s().$implicit,r=s();i(2),m("size",22)("glow",!1),i(4),m("innerHTML",r.renderMd(e.text),z),i(),_(e.tools!=null&&e.tools.length?7:-1),i(),_(e.sources!=null&&e.sources.length?8:-1)}}function Pe(t,n){if(t&1&&p(0,ae,2,1,"div",22)(1,Ee,9,5,"div",23),t&2){let e=n.$implicit;_(e.role==="user"?0:1)}}function Oe(t,n){t&1&&(o(0,"div",5),x(1,"span",55),l(2," thinking with specship context\u2026 "),a())}function ze(t,n){if(t&1&&(o(0,"span",59),l(1),a()),t&2){let e=s().$implicit;i(),u(e.arg)}}function Fe(t,n){if(t&1){let e=k();o(0,"button",57),h("click",function(){let d=v(e).$implicit,c=s(2);return y(c.pickSlash(d.cmd))}),o(1,"span",58),l(2),a(),p(3,ze,2,1,"span",59),o(4,"span",60),l(5),a()()}if(t&2){let e=n.$implicit;i(2),u(e.cmd),i(),_(e.arg?3:-1),i(2),u(e.desc)}}function $e(t,n){if(t&1&&(o(0,"div",8),C(1,Fe,6,3,"button",56,oe),a()),t&2){let e=s();i(),f(e.filteredSlash())}}function De(t,n){if(t&1){let e=k();o(0,"div",20)(1,"button",61),h("click",function(){v(e);let d=s();return y(d.toggleContext())}),x(2,"app-icon",62),a()()}t&2&&(i(2),m("size",14))}function Ie(t,n){if(t&1){let e=k();o(0,"div",77)(1,"button",81),h("click",function(){let d=v(e).$implicit,c=s(2);return y(c.toggleTool(d))}),x(2,"span",82),a(),o(3,"span",83),l(4),a()()}if(t&2){let e=n.$implicit,r=s(2);i(),B("on",r.enabledTools().has(e)),T("aria-pressed",r.enabledTools().has(e))("aria-label",e+(r.enabledTools().has(e)?" enabled":" disabled")),i(2),R("color",r.enabledTools().has(e)?"var(--text-primary)":"var(--text-muted)"),i(),u(e)}}function Ve(t,n){if(t&1){let e=k();o(0,"aside",21)(1,"div",63)(2,"span",64),l(3,"Context"),a(),o(4,"button",65),h("click",function(){v(e);let d=s();return y(d.toggleContext())}),x(5,"app-icon",66),a()(),o(6,"div",67)(7,"div",68),x(8,"app-icon",69),o(9,"div",70)(10,"div",71),l(11,"Project"),a(),o(12,"div",72),l(13,"~/dev/specship"),a()()(),o(14,"div",68),x(15,"app-icon",73),o(16,"div",70)(17,"div",71),l(18,"Indexed files"),a(),o(19,"div",74),l(20),a()()(),o(21,"div",68),x(22,"app-icon",75),o(23,"div",70)(24,"div",71),l(25,"Drift queue"),a(),o(26,"div",74),l(27,"\u2013 links"),a()()(),o(28,"div",76),l(29,"MCP tools"),a(),C(30,Ie,5,7,"div",77,A),a(),o(32,"div",78)(33,"div",79),l(34,"Tool access"),a(),o(35,"app-segmented",80),h("change",function(d){v(e);let c=s();return y(c.setToolAccess(d))}),a()()()}if(t&2){let e=s();i(5),m("size",13),i(3),m("size",13),i(7),m("size",13),i(5),u(e.api.isConfigured?"\u2013":"offline"),i(2),m("size",13),i(8),f(e.mcpTools),i(5),m("value",e.toolAccess())("options",e.toolAccessOptions)}}var J=[{cmd:"/ss-spec",arg:"REQ-ID | new <desc>",desc:"Intent door \u2014 view, author, implement, or review a spec"},{cmd:"/ss-explore",arg:"symbols | from\u2192to",desc:"Reads door \u2014 explore an area, trace a flow, or get impact"},{cmd:"/ss-check",arg:"(gate) | drifted | health",desc:"Gate & health door \u2014 run the gate, review drift, or see health"}],X=["specship_explore","specship_search","specship_spec","specship_link_verify"],Y=class t{sanitizer=O(j);api=O(K);listEl=L("listEl");closeStream;messages=w([{role:"assistant",text:`Hi \u2014 ask anything about your specs, code, or recent Claude Code sessions.
2
-
3
- Try **/ss-spec REQ-AUTH-005** to inspect a requirement, or **/ss-explore validateSession** to walk its callers.`}]);draft=w("");thinking=w(!1);contextCollapsed=w(!1);enabledTools=w(new Set(X));toolAccess=w("safe");slashCommands=J;mcpTools=X;toolAccessOptions=[{value:"ask",label:"Ask"},{value:"safe",label:"Auto-safe"},{value:"all",label:"All"}];showSlash=D(()=>{let n=this.draft();return n.startsWith("/")&&!n.includes(" ")});filteredSlash=D(()=>{let n=this.draft();return J.filter(e=>e.cmd.startsWith(n))});setDraft(n){this.draft.set(n)}onKey(n){n.key==="Enter"&&!n.shiftKey&&(n.preventDefault(),this.send())}send(){let n=this.draft().trim();if(!n)return;this.draft.set(""),this.messages.update(d=>[...d,{role:"user",text:n}]),this.thinking.set(!0),this.scrollToBottom();let e=this.messages().length;this.messages.update(d=>[...d,{role:"assistant",text:"",tools:[]}]),this.closeStream?.();let r="/api/chat/stream?question="+encodeURIComponent(n);this.closeStream=this.api.openEventStream(r,(d,c)=>this.onStreamEvent(e,d,c),()=>this.endStream(),["thinking","tool","result_summary","chunk","done"])}onStreamEvent(n,e,r){switch(e){case"tool":{let d=r??{};this.patchMsg(n,c=>M(S({},c),{tools:[...c.tools??[],{name:d.name??"",input:d.input??"",output:"",status:"ok"}]}));break}case"result_summary":{let d=r??{},c=d.sourceCount??0,b=d.found?`${c} source${c===1?"":"s"} returned`:"no matches in the index";this.patchMsg(n,E=>{let P=E.tools??[];return P.length===0?E:M(S({},E),{tools:P.map((I,ee)=>ee===P.length-1?M(S({},I),{output:b}):I)})});break}case"chunk":{let c=(r??{}).text??"";this.patchMsg(n,b=>M(S({},b),{text:b.text+c})),this.scrollToBottom();break}case"done":{let d=r??{};d.sources?.length&&this.patchMsg(n,c=>M(S({},c),{sources:d.sources})),this.endStream();break}}}patchMsg(n,e){this.messages.update(r=>r.map((d,c)=>c===n?e(d):d))}endStream(){this.thinking.set(!1),this.closeStream?.(),this.closeStream=void 0,this.scrollToBottom()}ngOnDestroy(){this.closeStream?.(),this.closeStream=void 0}pickSlash(n){this.draft.set(n+" ")}toggleTool(n){this.enabledTools.update(e=>{let r=new Set(e);return r.has(n)?r.delete(n):r.add(n),r})}setToolAccess(n){this.toolAccess.set(n)}toggleContext(){this.contextCollapsed.update(n=>!n)}toggleToolCall(n,e){e.open=!e.open,this.messages.update(r=>[...r])}openDetails=w(new Set);detailKey(n,e){return`${n}:${e}`}isDetailOpen(n,e){return this.openDetails().has(this.detailKey(n,e))}toggleDetail(n,e){let r=this.detailKey(n,e);this.openDetails.update(d=>{let c=new Set(d);return c.has(r)?c.delete(r):c.add(r),c})}renderMd(n){let e=n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\*\*(.+?)\*\*/g,'<strong style="color:var(--text-primary)">$1</strong>').replace(/`(.+?)`/g,'<code class="mono" style="font-size:12px;background:var(--bg-canvas);padding:1px 5px;border-radius:4px;border:1px solid var(--border-subtle);color:var(--node-spec)">$1</code>').replace(/\n\n/g,"<br/><br/>").replace(/\n/g,"<br/>");return this.sanitizer.bypassSecurityTrustHtml(e)}scrollToBottom(){setTimeout(()=>{let n=this.listEl()?.nativeElement;n&&(n.scrollTop=n.scrollHeight)},0)}static \u0275fac=function(e){return new(e||t)};static \u0275cmp=V({type:t,selectors:[["app-chat"]],viewQuery:function(e,r){e&1&&N(r.listEl,te,5),e&2&&H()},decls:29,vars:8,consts:[["listEl",""],[1,"chat-page"],[1,"chat-col"],[1,"thread","scroll-y"],[1,"thread-inner"],[1,"row","gap-8","muted","thinking"],[1,"composer"],[1,"composer-inner"],["role","listbox","aria-label","Slash commands",1,"slash-menu"],[1,"composer-box","row"],["type","button","title","Attach files or spec IDs",1,"btn","btn-ghost","btn-sm","attach-btn"],["name","paperclip",3,"size"],["placeholder","Ask with specship context\u2026 / for commands, Tab to complete spec IDs","rows","1",1,"composer-ta",3,"input","keydown","value"],["type","button","aria-label","Send message",1,"btn","btn-primary","btn-sm","send-btn",3,"click","disabled"],["name","send",3,"size"],[1,"composer-footer","row","gap-8"],[1,"row","gap-6"],["name","bot",3,"size"],[1,"muted",2,"font-size","10.5px"],[1,"grow"],[1,"ctx-collapsed"],["aria-label","Context panel",1,"ctx-panel","col"],[1,"msg-user"],[1,"msg-assistant"],[1,"bubble-user",3,"innerHTML"],[1,"row","gap-8","asst-meta"],["aria-hidden","true",3,"size","glow"],[2,"font-size","12px","font-weight","600"],[1,"asst-body"],[1,"bubble-asst",3,"innerHTML"],[1,"detail-list"],[1,"tool-call"],["type","button",1,"tool-header","row","gap-8",3,"click"],[2,"color","var(--text-muted)",3,"name","size"],["name","wrench",2,"color","var(--node-code)",3,"size"],[1,"mono","grow",2,"font-size","11.5px"],[1,"muted"],[1,"pill",2,"font-size","9.5px","color","var(--success)","background","var(--success-soft)"],["name","check",3,"size"],[1,"tool-output"],[1,"mono","muted",2,"font-size","10.5px","margin-bottom","3px"],[1,"mono",2,"font-size","11.5px","color","var(--text-secondary)"],[1,"eyebrow",2,"margin","4px 0 2px"],[1,"source-detail"],["type","button",1,"detail-header","row","gap-8",3,"click"],[1,"pill",2,"font-size","9.5px","color","var(--text-muted)","background","var(--bg-canvas)"],[1,"detail-body"],[1,"mono","detail-sig"],[1,"mono","detail-src"],[1,"detail-rel"],[1,"mono","muted","detail-rel-label"],[1,"mono","detail-rel-item"],[1,"row","gap-8","detail-rel-item"],[1,"mono","grow"],[3,"state"],[1,"thinking-dot"],["type","button","role","option",1,"slash-item","row","gap-8"],["type","button","role","option",1,"slash-item","row","gap-8",3,"click"],[1,"mono",2,"font-size","12px","color","var(--accent)"],[1,"mono","muted",2,"font-size","11px"],[1,"muted","grow",2,"font-size","11px","text-align","right"],["type","button","title","Show context",1,"btn","btn-ghost","btn-xs",3,"click"],["name","chevronLeft",3,"size"],[1,"ctx-header","row"],[1,"eyebrow","grow"],["type","button",1,"btn","btn-ghost","btn-xs",3,"click"],["name","chevronRight",3,"size"],[1,"ctx-body","scroll-y"],[1,"ctx-row","row","gap-8"],["name","folder",2,"color","var(--text-muted)","flex-shrink","0",3,"size"],[2,"min-width","0"],[1,"muted",2,"font-size","10px"],[1,"mono",2,"font-size","11.5px","overflow","hidden","text-overflow","ellipsis","white-space","nowrap"],["name","box",2,"color","var(--text-muted)","flex-shrink","0",3,"size"],[1,"mono",2,"font-size","11.5px"],["name","drift",2,"color","var(--warn)","flex-shrink","0",3,"size"],[1,"eyebrow",2,"margin","16px 0 8px"],[1,"row","gap-8",2,"padding","5px 0"],[1,"ctx-footer"],[1,"eyebrow",2,"margin-bottom","6px"],["size","sm",3,"change","value","options"],["type","button",1,"toggle-btn",3,"click"],[1,"toggle-thumb"],[1,"mono",2,"font-size","11px"]],template:function(e,r){e&1&&(o(0,"div",1)(1,"div",2)(2,"div",3,0)(4,"div",4),C(5,Pe,2,1,null,null,F),p(7,Oe,3,0,"div",5),a()(),o(8,"div",6)(9,"div",7),p(10,$e,3,0,"div",8),o(11,"div",9)(12,"button",10),x(13,"app-icon",11),a(),o(14,"textarea",12),h("input",function(c){return r.setDraft(c.target.value)})("keydown",function(c){return r.onKey(c)}),a(),o(15,"button",13),h("click",function(){return r.send()}),x(16,"app-icon",14),a()(),o(17,"div",15)(18,"div",16)(19,"app-pill"),x(20,"app-icon",17),l(21," Opus 4 "),a(),o(22,"span",18),l(23,"single thread \xB7 this project"),a()(),x(24,"span",19),o(25,"span",18),l(26,"Enter to send \xB7 Shift+Enter for newline"),a()()()()(),p(27,De,3,1,"div",20)(28,Ve,36,7,"aside",21),a()),e&2&&(i(5),f(r.messages()),i(2),_(r.thinking()?7:-1),i(3),_(r.showSlash()&&r.filteredSlash().length>0?10:-1),i(3),m("size",15),i(),m("value",r.draft()),i(),m("disabled",!r.draft().trim()),i(),m("size",14),i(4),m("size",10),i(7),_(r.contextCollapsed()?27:28))},dependencies:[q,W,Q,U,G],styles:["[_nghost-%COMP%]{display:flex;flex:1;min-height:0}.chat-page[_ngcontent-%COMP%]{display:flex;flex:1;min-height:0;min-width:0}.chat-col[_ngcontent-%COMP%]{display:flex;flex-direction:column;flex:1;min-width:0;min-height:0}.thread[_ngcontent-%COMP%]{flex:1;padding:20px 24px;overflow-y:auto}.thread-inner[_ngcontent-%COMP%]{max-width:760px;margin:0 auto}.msg-user[_ngcontent-%COMP%]{display:flex;justify-content:flex-end;margin-bottom:18px}.bubble-user[_ngcontent-%COMP%]{max-width:76%;background:var(--bg-elevated);border:1px solid var(--border-subtle);border-radius:12px 12px 4px;padding:9px 13px;font-size:13.5px;line-height:1.55}.msg-assistant[_ngcontent-%COMP%]{margin-bottom:22px}.asst-meta[_ngcontent-%COMP%]{align-items:center;margin-bottom:8px}.asst-logo[_ngcontent-%COMP%]{display:inline-grid;place-items:center;width:22px;height:22px;border-radius:50%;background:var(--accent);color:#fff;font-size:11px;font-weight:700;flex-shrink:0}.asst-body[_ngcontent-%COMP%]{padding-left:30px}.bubble-asst[_ngcontent-%COMP%]{font-size:13.5px;line-height:1.62;color:var(--text-secondary);text-wrap:pretty;margin-bottom:4px}.tool-call[_ngcontent-%COMP%]{border:1px solid var(--border-subtle);border-radius:7px;margin-top:8px;overflow:hidden;background:var(--bg-canvas)}.tool-header[_ngcontent-%COMP%]{width:100%;background:transparent;border:none;cursor:pointer;padding:6px 10px;text-align:left;color:inherit;font-family:var(--font-ui)}.tool-header[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.tool-header[_ngcontent-%COMP%]:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}.tool-output[_ngcontent-%COMP%]{padding:8px 10px 10px 30px;border-top:1px solid var(--border-subtle)}.detail-list[_ngcontent-%COMP%]{margin-top:10px;display:flex;flex-direction:column;gap:6px}.source-detail[_ngcontent-%COMP%]{border:1px solid var(--border-subtle);border-radius:7px;overflow:hidden;background:var(--bg-canvas)}.detail-header[_ngcontent-%COMP%]{width:100%;background:transparent;border:none;cursor:pointer;padding:6px 10px;text-align:left;color:inherit;font-family:var(--font-ui)}.detail-header[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.detail-header[_ngcontent-%COMP%]:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}.detail-body[_ngcontent-%COMP%]{padding:8px 10px 10px;border-top:1px solid var(--border-subtle);display:flex;flex-direction:column;gap:8px}.detail-sig[_ngcontent-%COMP%]{font-size:11.5px;color:var(--node-code);white-space:pre-wrap;word-break:break-word}.detail-src[_ngcontent-%COMP%]{margin:0;padding:8px 10px;font-size:11.5px;line-height:1.5;color:var(--text-secondary);background:var(--bg-base);border:1px solid var(--border-subtle);border-radius:5px;overflow-x:auto;white-space:pre;max-height:320px;overflow-y:auto}.detail-rel-label[_ngcontent-%COMP%]{font-size:10.5px;margin-bottom:3px}.detail-rel-item[_ngcontent-%COMP%]{font-size:11.5px;color:var(--text-secondary);padding:1px 0}.thinking[_ngcontent-%COMP%]{padding-left:30px;font-size:12px}.thinking-dot[_ngcontent-%COMP%]{width:6px;height:6px;border-radius:50%;background:var(--accent);animation:skeleton 1s infinite;flex-shrink:0}.composer[_ngcontent-%COMP%]{padding:12px 24px 18px;border-top:1px solid var(--border-subtle);flex-shrink:0}.composer-inner[_ngcontent-%COMP%]{max-width:760px;margin:0 auto;position:relative}.composer-box[_ngcontent-%COMP%]{align-items:flex-end;background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:12px;padding:8px;gap:8px}.attach-btn[_ngcontent-%COMP%]{padding:7px;flex-shrink:0}.send-btn[_ngcontent-%COMP%]{padding:7px 10px;flex-shrink:0}.composer-ta[_ngcontent-%COMP%]{flex:1;resize:none;background:transparent;border:none;outline:none;color:var(--text-primary);font-size:13.5px;font-family:var(--font-ui);line-height:1.5;padding:5px 2px;max-height:120px}.composer-ta[_ngcontent-%COMP%]::placeholder{color:var(--text-muted)}.composer-footer[_ngcontent-%COMP%]{margin-top:8px;align-items:center}.slash-menu[_ngcontent-%COMP%]{position:absolute;bottom:100%;left:0;margin-bottom:8px;background:var(--bg-elevated);border:1px solid var(--border-strong);border-radius:8px;box-shadow:var(--shadow-pop);padding:5px;width:320px;z-index:10}.slash-item[_ngcontent-%COMP%]{width:100%;background:transparent;border:none;cursor:pointer;padding:6px 9px;border-radius:5px;text-align:left;color:inherit;font-family:var(--font-ui)}.slash-item[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.slash-item[_ngcontent-%COMP%]:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}.ctx-collapsed[_ngcontent-%COMP%]{width:40px;flex-shrink:0;border-left:1px solid var(--border-subtle);display:flex;justify-content:center;padding-top:12px}.ctx-panel[_ngcontent-%COMP%]{width:264px;flex-shrink:0;border-left:1px solid var(--border-subtle);background:var(--bg-panel);display:flex;flex-direction:column;min-height:0}.ctx-header[_ngcontent-%COMP%]{padding:11px 13px;border-bottom:1px solid var(--border-subtle);align-items:center}.ctx-body[_ngcontent-%COMP%]{flex:1;padding:13px;overflow-y:auto;min-height:0}.ctx-row[_ngcontent-%COMP%]{padding:5px 0;align-items:flex-start}.ctx-footer[_ngcontent-%COMP%]{padding:12px;border-top:1px solid var(--border-subtle)}.toggle-btn[_ngcontent-%COMP%]{width:30px;height:17px;border-radius:999px;border:none;cursor:pointer;padding:2px;background:var(--bg-elevated);display:flex;justify-content:flex-start;align-items:center;transition:background .12s,justify-content .12s;flex-shrink:0}.toggle-btn.on[_ngcontent-%COMP%]{background:var(--accent);justify-content:flex-end}.toggle-btn[_ngcontent-%COMP%]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.toggle-thumb[_ngcontent-%COMP%]{width:13px;height:13px;border-radius:50%;background:#fff;flex-shrink:0}.eyebrow[_ngcontent-%COMP%]{color:var(--text-muted);font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase}.muted[_ngcontent-%COMP%]{color:var(--text-muted)}.mono[_ngcontent-%COMP%]{font-family:var(--font-mono)}.pill[_ngcontent-%COMP%]{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;padding:3px 9px;border-radius:999px;line-height:1.4;white-space:nowrap}.grow[_ngcontent-%COMP%]{flex:1}"],changeDetection:0})};export{Y as Chat};
@@ -1,2 +0,0 @@
1
- import{a as K,b as J,c as X}from"./chunk-7656MA24.js";import{a as W}from"./chunk-P62EJGSF.js";import{a as q}from"./chunk-YNYVOPWF.js";import{a as U}from"./chunk-5NTGUSXJ.js";import{a as Z}from"./chunk-QIZ65CGB.js";import{a as Q}from"./chunk-IOB4JJT4.js";import{c as V,d as j}from"./chunk-DOKZOFKM.js";import{a as H,c as _}from"./chunk-PAO2624Y.js";import{a as A}from"./chunk-PBRCKHEQ.js";import{a as L}from"./chunk-3H2EZLZN.js";import{Aa as l,Ga as T,I as E,Ia as b,Ka as c,M as C,N as y,Ta as w,Ua as M,Va as s,W as R,Wa as x,Xa as v,Ya as O,bb as N,ea as r,gb as z,ib as I,ka as $,lb as m,qa as G,ra as u,sa as g,ua as D,va as S,vb as B,wa as k,xa as p,ya as a,za as o,zb as Y}from"./chunk-SYGIPC2P.js";import"./chunk-Q7L6LLAK.js";var te=()=>[0,1,2,3],ne=()=>[0,1,2,3,4],F=(i,t)=>t.id;function ie(i,t){if(i&1&&s(0),i&2){let e=c();v(" ",e.fmt$(e.lastSessionCostStat().value)," ")}}function ae(i,t){i&1&&s(0," \xA0 ")}function oe(i,t){if(i&1&&l(0,"app-sparkline",11),i&2){let e=c();p("data",e.lastSessionCostStat().series)("width",64)("height",22)("fill",!0)}}function re(i,t){if(i&1&&l(0,"app-delta",12),i&2){let e=c();p("value",e.lastSessionCostStat().delta)("invert",!0)}}function se(i,t){if(i&1&&s(0),i&2){let e=c();v(" ",e.toolCallsStat().value.toLocaleString()," ")}}function le(i,t){i&1&&s(0," \xA0 ")}function de(i,t){if(i&1&&l(0,"app-sparkline",14),i&2){let e=c();p("data",e.toolCallsStat().series)("width",64)("height",22)("fill",!0)}}function pe(i,t){if(i&1&&l(0,"app-delta",12),i&2){let e=c();p("value",e.toolCallsStat().delta)("invert",!0)}}function ce(i,t){if(i&1&&s(0),i&2){let e=c();v(" ",e.subagentPctStat().value,"% ")}}function me(i,t){i&1&&s(0," \xA0 ")}function ue(i,t){if(i&1&&l(0,"app-sparkline",16),i&2){let e=c();p("data",e.subagentPctStat().series)("width",64)("height",22)("fill",!0)}}function ge(i,t){if(i&1&&l(0,"app-delta",12),i&2){let e=c();p("value",e.subagentPctStat().delta)("invert",!0)}}function he(i,t){if(i&1&&s(0),i&2){let e=c();v(" ",e.driftStat().value," ")}}function be(i,t){i&1&&s(0," \xA0 ")}function ve(i,t){if(i&1&&(a(0,"span",72),s(1),o()),i&2){let e=t.$implicit;r(),x(e)}}function xe(i,t){if(i&1){let e=T();a(0,"button",63),b("click",function(){let d=C(e).$implicit,h=c();return y(h.go(d.route))}),a(1,"div",64)(2,"span",65),l(3,"app-icon",66),o(),a(4,"div",67)(5,"div",68),s(6),o(),a(7,"code",69),s(8),o()()(),a(9,"div",70),s(10),o(),a(11,"div",71),S(12,ve,2,1,"span",72,D),o()()}if(i&2){let e=t.$implicit;G("aria-label",e.label+" door \u2014 "+e.cmd+". "+e.blurb),r(2),w("color",e.color)("background","color-mix(in srgb, "+e.color+" 14%, transparent)"),r(),p("name",e.icon)("size",15),r(3),v("",e.label," door"),r(),w("color",e.color),r(),x(e.cmd),r(2),x(e.blurb),r(2),k(e.subs)}}function _e(i,t){i&1&&(a(0,"span",32),s(1,"seed"),o())}function fe(i,t){if(i&1&&(a(0,"span",39),s(1),o()),i&2){let e=c();r(),v(" ",e.urgentTipCount()," urgent ")}}function Ce(i,t){i&1&&l(0,"div",73)}function ye(i,t){i&1&&S(0,Ce,1,0,"div",73,D),i&2&&k(N(0,te))}function Se(i,t){i&1&&(a(0,"div",42),s(1,"No tips yet. Run more sessions to populate."),o())}function ke(i,t){if(i&1&&(a(0,"code",80),s(1),o()),i&2){let e=c().$implicit;r(),x(e.fix)}}function we(i,t){if(i&1&&(a(0,"span",87),s(1),o()),i&2){let e=c().$implicit,n=c(2);w("color",n.tipSevColor(e.severity)),r(),x(e.saving)}}function Me(i,t){if(i&1){let e=T();a(0,"div",75)(1,"div",76),l(2,"app-icon",66),o(),a(3,"div",77)(4,"div",78),s(5),o(),a(6,"div",79),u(7,ke,2,1,"code",80),l(8,"span",81),u(9,we,2,3,"span",82),o()(),a(10,"div",83)(11,"button",84),b("click",function(){C(e);let d=c(2);return y(d.go("tips"))}),s(12,"Apply"),o(),a(13,"button",85),b("click",function(){let d=C(e).$implicit,h=c(2);return y(h.dismissTip(d.id))}),l(14,"app-icon",86),o()()()}if(i&2){let e=t.$implicit,n=c(2);w("border-left-color",n.tipSevColor(e.severity)),r(),w("color",n.tipSevColor(e.severity)),r(),p("name",n.tipIcon(e))("size",14),r(3),x(e.title),r(2),g(e.fix?7:-1),r(2),g(e.saving?9:-1),r(5),p("size",12)}}function Pe(i,t){if(i&1&&S(0,Me,15,10,"div",74,F),i&2){let e=c();k(e.visibleTips())}}function Ee(i,t){i&1&&l(0,"div",47)}function Te(i,t){i&1&&(a(0,"div",48),s(1," No tool calls in the selected window. "),o())}function De(i,t){if(i&1){let e=T();a(0,"app-treemap",88),b("pick",function(){C(e);let d=c();return y(d.go("heatmap"))}),o()}if(i&2){let e=c();p("items",e.treemapItems())("height",116)("selKey",null)}}function Oe(i,t){i&1&&l(0,"div",89)}function ze(i,t){i&1&&S(0,Oe,1,0,"div",89,D),i&2&&k(N(0,ne))}function Ie(i,t){i&1&&(a(0,"div",42),s(1,"No prompts ingested for this range."),o())}function Re(i,t){i&1&&l(0,"app-icon",94),i&2&&p("size",11)}function Ne(i,t){if(i&1){let e=T();a(0,"div",91),b("click",function(){C(e);let d=c(2);return y(d.go("sessions"))})("keydown.enter",function(){C(e);let d=c(2);return y(d.go("sessions"))})("keydown.space",function(){C(e);let d=c(2);return y(d.go("sessions"))}),a(1,"div",92)(2,"div",93),u(3,Re,1,1,"app-icon",94),s(4),o(),a(5,"div",95),l(6,"app-bar",96),o()(),a(7,"div",97)(8,"div",98),s(9),o(),a(10,"div",99),s(11),z(12,"number"),o()()()}if(i&2){let e=t.$implicit,n=c(2);r(3),g(e.is_sidechain?3:-1),r(),v(" ",e.text||"(no text)"," "),r(2),p("frac",n.promptFrac(e.cost_usd))("color",n.promptBarColor(e.cost_usd))("height",4),r(2),w("color",e.cost_usd/n.maxPromptCost()>.7?"var(--error)":"var(--text-primary)"),M("expensive",e.cost_usd/n.maxPromptCost()>.7),r(),v(" ",n.fmt$(e.cost_usd)," "),r(2),O(" ",n.fmtK(n.promptTotalTokens(e))," \xB7 ",I(12,12,n.promptCacheRate(e)*100,"1.0-0"),"% ")}}function Fe(i,t){if(i&1&&S(0,Ne,13,15,"div",90,F),i&2){let e=c();k(e.topPrompts())}}function $e(i,t){i&1&&l(0,"div",61)}function Ge(i,t){if(i&1&&(a(0,"div",100)(1,"div",101),s(2),z(3,"number"),o(),a(4,"div",102)(5,"div",23),s(6,"cache read rate"),o(),l(7,"app-delta",12),o()(),l(8,"div",103),a(9,"div",104)(10,"div",105)(11,"div",106),s(12,"Creation tokens"),o(),a(13,"div",107),s(14),o(),a(15,"div",108),s(16,"ephemeral"),o()(),a(17,"div",105)(18,"div",106),s(19,"Read tokens"),o(),a(20,"div",107),s(21),o(),a(22,"div",108),s(23,"charged at ~10%"),o()(),a(24,"div",105)(25,"div",106),s(26,"Saved this week"),o(),a(27,"div",109),s(28),o(),a(29,"div",108),s(30,"vs no cache"),o()(),a(31,"div",105)(32,"div",106),s(33,"WoW"),o(),a(34,"div",109),s(35),z(36,"number"),o(),a(37,"div",108),s(38,"more reuse"),o()()()),i&2){let e=c(),n=e.cache.state().data;r(2),v("",I(3,8,n.readRate*100,"1.0-0"),"%"),r(5),p("value",n.wowDelta)("invert",!1),r(7),x(e.fmtK(n.creationTokens)),r(7),x(e.fmtK(n.readTokens)),r(7),x(e.fmt$(n.dollarsSaved)),r(7),O(" ",n.wowDelta>=0?"+":"","",I(36,11,n.wowDelta*100,"1.0-0"),"% ")}}var ee=class i{api=E(L);router=E(V);projects=E(A);conn=E(H);range=R("week");rangeOptions=[{value:"today",label:"Today"},{value:"week",label:"This week"},{value:"month",label:"This month"},{value:"all",label:"All time"}];status=_(this.api,()=>`/api/status${this.projects.projectQuery()}`);miniGraphSearch=_(this.api,()=>`/api/graph/search?q=on&limit=18${this.projects.projectQuery("&")}`);tips=_(this.api,()=>"/api/claude/tips");heatmap=_(this.api,()=>`/api/claude/heatmap?range=${this.range()}`);costs=_(this.api,()=>`/api/claude/costs?range=${this.range()}`);cache=_(this.api,()=>`/api/claude/cache?range=${this.range()}`);sessions=_(this.api,()=>`/api/claude/sessions?range=${this.range()}&limit=10`);stats=_(this.api,()=>`/api/claude/stats?range=${this.range()}`);EMPTY_METRIC={value:0,delta:0,series:[]};lastSessionCostStat=m(()=>this.stats.state().data?.lastSessionCost??this.EMPTY_METRIC);toolCallsStat=m(()=>this.stats.state().data?.toolCalls??this.EMPTY_METRIC);subagentPctStat=m(()=>this.stats.state().data?.subagentPct??this.EMPTY_METRIC);driftStat=m(()=>this.stats.state().data?.drift??this.EMPTY_METRIC);lastSession=m(()=>(this.sessions.state().data?.sessions??[])[0]??null);lastSessionCost=m(()=>this.lastSession()?.total_cost_usd??0);toolCallCount=m(()=>(this.heatmap.state().data?.tools??[]).reduce((e,n)=>e+(n.calls??0),0));subagentShare=m(()=>{let t=this.heatmap.state().data?.subagents??[],e=t.find(f=>f.type==="subagent"),n=t.find(f=>f.type==="main"),d=e?.cost??0,h=n?.cost??0,P=d+h;return P>0?Math.round(d/P*100):0});driftCount=m(()=>this.status.state().data?.drift??0);nodeCountLabel=m(()=>this.status.state().data?.nodeCount??0);urgentTipCount=m(()=>(this.tips.state().data?.tips??[]).filter(e=>e.severity==="error").length);dismissedTips=R(new Set);dismissTip(t){this.dismissedTips.update(e=>{let n=new Set(e);return n.add(t),n})}isTipDismissed(t){return this.dismissedTips().has(t)}visibleTips=m(()=>{let t=this.dismissedTips();return(this.tips.state().data?.tips??[]).filter(e=>!t.has(e.id)).slice(0,4)});treemapItems=m(()=>{let t=(this.heatmap.state().data?.files??[]).slice(0,30);if(!t.length)return[];let e=Math.max(1,...t.map(n=>n.resultBytes&&n.calls?n.resultBytes/n.calls:0));return t.map(n=>{let d=n.calls>0?n.resultBytes/n.calls:0,h=Math.min(1,d/e);return{key:n.path,label:K(n.path),value:n.calls,intensity:h,sub:n.calls+" calls",title:`${n.path}
2
- ${n.calls} calls \xB7 ${this.fmtK(Math.round(d))}/call`}})});topPrompts=m(()=>(this.costs.state().data?.topPrompts??[]).slice(0,8));maxPromptCost=m(()=>Math.max(.01,...this.topPrompts().map(t=>t.cost_usd??0)));rangeTotal=m(()=>(this.costs.state().data?.series??[]).reduce((e,n)=>e+(n.cost??0),0));liveSource=m(()=>this.conn.online()?"live":"offline");miniGraphSource=m(()=>(this.miniGraphSearch.state().data?.results?.length??0)>0?"api":"seed");miniGraphNodes=m(()=>{let t=this.miniGraphSearch.state().data?.results??[];return t.length>0?je(t.slice(0,18).map(e=>({id:e.node.id,label:e.node.name,sub:e.node.filePath?.split("/").slice(-2).join("/"),kind:e.node.kind}))):Be});miniGraphEdges=m(()=>{if(this.miniGraphSource()==="api"){let t=this.miniGraphNodes(),e=[];for(let n=1;n<t.length;n++){let d=t[Math.floor(Math.random()*n)],h=t[n];d&&h&&e.push({from:d.id,to:h.id,kind:"calls"})}return e}return Ve});onMiniGraphPick(t){this.router.navigate(["/graph"],{queryParams:{focus:t}})}doors=[{id:"intent",label:"Intent",cmd:"/ss-spec",icon:"book",color:"var(--node-spec)",route:"specs",blurb:"View, author, implement, review, or extend a spec \u2014 the whole lifecycle.",subs:["new","fast","implement","review","triage","behaviour","domain"]},{id:"reads",label:"Reads",cmd:"/ss-explore",icon:"search",color:"var(--accent)",route:"graph",blurb:"Explore an area, trace a flow, or get a change\u2019s blast radius.",subs:["explore","flow","impact"]},{id:"gate",label:"Gate & health",cmd:"/ss-check",icon:"check",color:"var(--warn)",route:"drift",blurb:"Run the enforcement gate, review drift, repair links, or see code-health.",subs:["gate","drifted","fix","relink","health"]}];setRange(t){this.range.set(t)}go(t){this.router.navigate(["/"+t])}fmt$(t){return"$"+t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})}fmtK(t){return t>=1e6?(t/1e6).toFixed(1)+"M":t>=1e3?(t/1e3).toFixed(t>=1e4?0:1)+"k":String(t)}promptCacheRate(t){let e=(t.input_tokens??0)+(t.cache_creation_tokens??0)+(t.cache_read_tokens??0);return e>0?(t.cache_read_tokens??0)/e:0}promptTotalTokens(t){return(t.input_tokens??0)+(t.output_tokens??0)+(t.cache_creation_tokens??0)+(t.cache_read_tokens??0)}promptBarColor(t){return t/this.maxPromptCost()>.7?"var(--error)":"var(--accent)"}promptFrac(t){return Math.max(0,Math.min(1,t/this.maxPromptCost()))}tipSevColor(t){return t==="error"?"var(--error)":t==="warn"?"var(--warn)":"var(--info)"}tipIcon(t){return t.icon?t.icon:t.severity==="error"?"cancel":t.severity==="warn"?"warn":"info"}static \u0275fac=function(e){return new(e||i)};static \u0275cmp=$({type:i,selectors:[["app-dashboard"]],decls:133,vars:49,consts:[[1,"scroll-y","dashboard"],["icon","dashboard","title","Dashboard",3,"sub"],["actions",""],["size","sm",3,"change","options","value"],[1,"stat-grid"],["type","button",1,"stat-tile",3,"click"],[1,"row","gap-8","stat-eyebrow"],["name","coins",2,"color","var(--accent)",3,"size"],[1,"eyebrow",2,"letter-spacing","0.04em"],[1,"row","stat-value-row"],[1,"stat-value","tabular"],["color","var(--accent)",3,"data","width","height","fill"],[3,"value","invert"],["name","wrench",2,"color","var(--node-spec)",3,"size"],["color","var(--node-spec)",3,"data","width","height","fill"],["name","bot",2,"color","var(--node-code)",3,"size"],["color","var(--node-code)",3,"data","width","height","fill"],["name","drift",2,"color","var(--warn)",3,"size"],[1,"card","card-pad","doors-card"],[1,"row","doors-head"],[1,"row","gap-8"],["name","command",2,"color","var(--node-spec)",3,"size"],[2,"font-weight","600","font-size","12.5px"],[1,"muted",2,"font-size","11px"],[1,"doors-grid"],["type","button",1,"door-tile"],[1,"center-grid"],[1,"card","graph-card"],[1,"card-head"],[1,"card-title","row","gap-8"],["name","graph",2,"color","var(--accent)",3,"size"],[1,"muted",2,"font-size","11px","font-weight","400"],["title","No graph data yet \u2014 illustrative",1,"pill","seed-pill"],["routerLink","/graph",1,"btn","btn-ghost","btn-xs"],["name","arrowRight",3,"size"],[1,"mini-graph"],[3,"nodeClick","nodes","edges"],[1,"card","tips-card"],["name","tips",2,"color","var(--warn)",3,"size"],[1,"pill",2,"font-size","10px","background","var(--error-soft)","color","var(--error)"],["routerLink","/tips",1,"btn","btn-ghost","btn-xs"],[1,"scroll-y","tips-body"],[1,"tip-empty"],[1,"card","card-pad","heatmap-card"],[1,"row","heatmap-head"],["name","flame",2,"color","var(--warn)",3,"size"],["routerLink","/heatmap",1,"btn","btn-ghost","btn-xs"],[1,"skel",2,"height","116px","border-radius","7px"],[1,"tip-empty",2,"height","116px","display","grid","place-items","center"],[3,"items","height","selKey"],[1,"row","gap-10","heatmap-legend"],[1,"muted",2,"font-size","10px"],[1,"heatmap-gradient"],[1,"muted",2,"font-size","9.5px"],[1,"bottom-grid"],[1,"card","card-pad","prompts-card"],[1,"row","prompts-head"],["routerLink","/costs",1,"btn","btn-ghost","btn-xs"],[1,"col"],[1,"card","card-pad","cache-card"],["name","database",2,"color","var(--node-route)",3,"size"],[1,"skel",2,"height","70px","border-radius","5px"],[1,"dash-footer","mono","muted"],["type","button",1,"door-tile",3,"click"],[1,"row","door-top"],[1,"door-ic"],[3,"name","size"],[1,"door-titles"],[1,"door-label"],[1,"mono","door-cmd"],[1,"door-blurb"],[1,"door-subs"],[1,"door-sub"],[1,"skel",2,"height","64px","border-radius","8px"],[1,"tip-row",3,"border-left-color"],[1,"tip-row"],[1,"tip-sev-icon"],[1,"grow","tip-body-col",2,"min-width","0"],[1,"tip-title"],[1,"row","gap-8","tip-meta-row"],[1,"mono","tip-fix"],[1,"grow"],[1,"pill",2,"font-size","10px","color","inherit","background","transparent",3,"color"],[1,"row","gap-4",2,"flex-shrink","0"],["type","button",1,"btn","btn-secondary","btn-xs",3,"click"],["type","button","title","Dismiss",1,"btn","btn-ghost","btn-xs",3,"click"],["name","x",3,"size"],[1,"pill",2,"font-size","10px","color","inherit","background","transparent"],[3,"pick","items","height","selKey"],[1,"skel",2,"height","26px","margin","4px 0","border-radius","4px"],["role","button","tabindex","0",1,"prompt-row"],["role","button","tabindex","0",1,"prompt-row",3,"click","keydown.enter","keydown.space"],[1,"grow","prompt-left",2,"min-width","0"],[1,"prompt-text"],["name","bot",2,"color","var(--node-code)","margin-right","5px","vertical-align","-1px",3,"size"],[2,"margin-top","4px","width","70%"],[3,"frac","color","height"],[1,"prompt-right"],[1,"mono","tabular","prompt-cost"],[1,"mono","muted",2,"font-size","10px"],[1,"row","cache-headline"],[1,"tabular","cache-rate"],[2,"padding-bottom","3px"],[1,"cache-divider"],[1,"cache-kv-grid"],[1,"kv"],[1,"kv-label"],[1,"kv-value","mono","tabular"],[1,"kv-sub","mono","muted"],[1,"kv-value","mono","tabular",2,"color","var(--success)"]],template:function(e,n){e&1&&(a(0,"div",0)(1,"app-page-head",1)(2,"div",2)(3,"app-segmented",3),b("change",function(h){return n.setRange(h)}),o()()(),a(4,"div",4)(5,"button",5),b("click",function(){return n.go("sessions")}),a(6,"div",6),l(7,"app-icon",7),a(8,"span",8),s(9,"Last session cost"),o()(),a(10,"div",9)(11,"div",10),u(12,ie,1,1)(13,ae,1,0),o(),u(14,oe,1,4,"app-sparkline",11),o(),u(15,re,1,2,"app-delta",12),o(),a(16,"button",5),b("click",function(){return n.go("heatmap")}),a(17,"div",6),l(18,"app-icon",13),a(19,"span",8),s(20),o()(),a(21,"div",9)(22,"div",10),u(23,se,1,1)(24,le,1,0),o(),u(25,de,1,4,"app-sparkline",14),o(),u(26,pe,1,2,"app-delta",12),o(),a(27,"button",5),b("click",function(){return n.go("heatmap")}),a(28,"div",6),l(29,"app-icon",15),a(30,"span",8),s(31,"Subagent spend"),o()(),a(32,"div",9)(33,"div",10),u(34,ce,1,1)(35,me,1,0),o(),u(36,ue,1,4,"app-sparkline",16),o(),u(37,ge,1,2,"app-delta",12),o(),a(38,"button",5),b("click",function(){return n.go("drift")}),a(39,"div",6),l(40,"app-icon",17),a(41,"span",8),s(42,"Drift queue"),o()(),a(43,"div",9)(44,"div",10),u(45,he,1,1)(46,be,1,0),o()()()(),a(47,"div",18)(48,"div",19)(49,"div",20),l(50,"app-icon",21),a(51,"span",22),s(52,"Command doors"),o(),a(53,"span",23),s(54,"\xB7 your whole SpecShip command surface, in Claude Code"),o()()(),a(55,"div",24),S(56,xe,14,12,"button",25,F),o()(),a(58,"div",26)(59,"div",27)(60,"div",28)(61,"div",29),l(62,"app-icon",30),a(63,"span"),s(64,"Recent neighborhood"),o(),a(65,"span",31),s(66,"\xB7 last edited files"),o(),u(67,_e,2,0,"span",32),o(),a(68,"a",33),s(69," Open graph "),l(70,"app-icon",34),o()(),a(71,"div",35)(72,"app-graph-canvas",36),b("nodeClick",function(h){return n.onMiniGraphPick(h)}),o()()(),a(73,"div",37)(74,"div",28)(75,"div",29),l(76,"app-icon",38),a(77,"span"),s(78,"Tips"),o(),u(79,fe,2,1,"span",39),o(),a(80,"a",40),s(81,"All"),o()(),a(82,"div",41),u(83,ye,2,1)(84,Se,2,0,"div",42)(85,Pe,2,0),o()()(),a(86,"div",43)(87,"div",44)(88,"div",20),l(89,"app-icon",45),a(90,"span",22),s(91,"Tool-call heatmap"),o(),a(92,"span",23),s(93,"\xB7 area = calls, color = tokens / call"),o()(),a(94,"a",46),s(95," Open heatmap "),l(96,"app-icon",34),o()(),u(97,Ee,1,0,"div",47)(98,Te,2,0,"div",48)(99,De,1,3,"app-treemap",49),a(100,"div",50)(101,"span",51),s(102,"tokens / call"),o(),l(103,"div",52),a(104,"span",53),s(105,"efficient \u2192 wasteful"),o()()(),a(106,"div",54)(107,"div",55)(108,"div",56)(109,"div",20),l(110,"app-icon",7),a(111,"span",22),s(112,"Recent prompts"),o(),a(113,"span",23),s(114,"\xB7 by cost"),o()(),a(115,"a",57),s(116,"Cost ranking"),o()(),a(117,"div",58),u(118,ze,2,1)(119,Ie,2,0,"div",42)(120,Fe,2,0),o()(),a(121,"div",59)(122,"div",20),l(123,"app-icon",60),a(124,"span",22),s(125,"Cache analytics"),o()(),u(126,$e,1,0,"div",61)(127,Ge,39,14),o()(),a(128,"footer",62),s(129),a(130,"span"),s(131,"\u25CF"),o(),s(132),o()()),e&2&&(r(),p("sub","specship \xB7 "+n.nodeCountLabel().toLocaleString()+" nodes \xB7 last session "+n.fmt$(n.lastSessionCost())),r(2),p("options",n.rangeOptions)("value",n.range()),r(4),p("size",13),r(4),M("skel",n.stats.state().loading),r(),g(n.stats.state().loading?13:12),r(2),g(n.lastSessionCostStat().series.length>0?14:-1),r(),g(n.lastSessionCostStat().delta!==0?15:-1),r(3),p("size",13),r(2),v("Tool calls \xB7 ",n.range()),r(2),M("skel",n.stats.state().loading),r(),g(n.stats.state().loading?24:23),r(2),g(n.toolCallsStat().series.length>0?25:-1),r(),g(n.toolCallsStat().delta!==0?26:-1),r(3),p("size",13),r(4),M("skel",n.stats.state().loading),r(),g(n.stats.state().loading?35:34),r(2),g(n.subagentPctStat().series.length>0?36:-1),r(),g(n.subagentPctStat().delta!==0?37:-1),r(3),p("size",13),r(4),M("skel",n.stats.state().loading),r(),g(n.stats.state().loading?46:45),r(5),p("size",14),r(6),k(n.doors),r(6),p("size",14),r(5),g(n.miniGraphSource()==="seed"?67:-1),r(3),p("size",11),r(2),p("nodes",n.miniGraphNodes())("edges",n.miniGraphEdges()),r(4),p("size",14),r(3),g(n.urgentTipCount()>0?79:-1),r(4),g(n.tips.state().loading?83:n.visibleTips().length===0?84:85),r(6),p("size",14),r(7),p("size",11),r(),g(n.heatmap.state().loading?97:n.treemapItems().length===0?98:99),r(13),p("size",14),r(8),g(n.costs.state().loading?118:n.topPrompts().length===0?119:120),r(5),p("size",14),r(3),g(n.cache.state().loading?126:n.cache.state().data?127:-1),r(3),O(" ",n.range()," window total: ",n.fmt$(n.rangeTotal())," \xB7 "),r(),M("dot-live",n.liveSource()==="live")("dot-mock",n.liveSource()==="offline"),r(2),v(" ",n.liveSource()==="live"?"Live":"Offline"," "))},dependencies:[j,Y,U,Q,q,W,J,X,Z,B],styles:['@charset "UTF-8";[_nghost-%COMP%]{display:contents}.dashboard[_ngcontent-%COMP%]{flex:1;padding:18px;color:var(--text-primary);background:var(--bg-canvas)}.stat-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:14px}.stat-tile[_ngcontent-%COMP%]{text-align:left;padding:11px 13px;cursor:pointer;background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:var(--r-lg);display:flex;flex-direction:column;gap:6px;color:var(--text-primary);font-family:inherit;transition:background .1s,border-color .1s}.stat-tile[_ngcontent-%COMP%]:hover{background:var(--bg-panel-2);border-color:var(--border-strong)}.stat-eyebrow[_ngcontent-%COMP%]{color:var(--text-muted)}.stat-value-row[_ngcontent-%COMP%]{justify-content:space-between;align-items:flex-end;gap:8px}.stat-value[_ngcontent-%COMP%]{font-size:23px;font-weight:650;letter-spacing:-.02em;line-height:1;min-height:23px}.doors-card[_ngcontent-%COMP%]{margin-bottom:14px}.doors-head[_ngcontent-%COMP%]{margin-bottom:12px}.doors-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}@media(max-width:760px){.doors-grid[_ngcontent-%COMP%]{grid-template-columns:1fr}}.door-tile[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:8px;text-align:left;padding:12px 13px;border:1px solid var(--border-subtle);border-radius:var(--r-lg);background:var(--bg-panel-2);cursor:pointer;transition:border-color .12s,transform .12s}.door-tile[_ngcontent-%COMP%]:hover{border-color:var(--border-strong);transform:translateY(-1px)}.door-tile[_ngcontent-%COMP%]:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}.door-top[_ngcontent-%COMP%]{gap:10px;align-items:center}.door-ic[_ngcontent-%COMP%]{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:8px;flex-shrink:0}.door-titles[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:1px;min-width:0}.door-label[_ngcontent-%COMP%]{font-weight:650;font-size:12.5px;color:var(--text-primary)}.door-cmd[_ngcontent-%COMP%]{font-size:11.5px}.door-blurb[_ngcontent-%COMP%]{font-size:11.5px;line-height:1.45;color:var(--text-secondary)}.door-subs[_ngcontent-%COMP%]{display:flex;flex-wrap:wrap;gap:4px;margin-top:auto}.door-sub[_ngcontent-%COMP%]{font-family:ui-monospace,Geist Mono,monospace;font-size:10px;padding:2px 6px;border-radius:5px;color:var(--text-muted);background:var(--bg-hover);border:1px solid var(--border-subtle)}.center-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:2fr 1fr;gap:12px;margin-bottom:14px}.graph-card[_ngcontent-%COMP%], .tips-card[_ngcontent-%COMP%]{height:340px;display:flex;flex-direction:column;background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:var(--r-lg);overflow:hidden}.card-head[_ngcontent-%COMP%]{display:flex;justify-content:space-between;align-items:center;padding:11px 13px;border-bottom:1px solid var(--border-subtle);flex-shrink:0}.card-title[_ngcontent-%COMP%]{font-weight:600;font-size:12.5px;display:inline-flex;align-items:center;gap:8px}.mini-graph[_ngcontent-%COMP%]{flex:1;min-height:0;overflow:hidden;border-bottom-left-radius:var(--r-lg);border-bottom-right-radius:var(--r-lg)}.mini-graph[_ngcontent-%COMP%] app-graph-canvas[_ngcontent-%COMP%]{display:block;width:100%;height:100%}.seed-pill[_ngcontent-%COMP%]{color:var(--warn);background:var(--warn-soft);font-size:9.5px;font-weight:600;padding:1px 6px}.tips-body[_ngcontent-%COMP%]{flex:1;padding:10px;display:flex;flex-direction:column;gap:8px;min-height:0}.tip-empty[_ngcontent-%COMP%]{color:var(--text-muted);font-size:12px;text-align:center;padding:12px}.tip-row[_ngcontent-%COMP%]{display:flex;gap:10px;padding:10px 12px;border-radius:8px;background:var(--bg-panel-2);border:1px solid var(--border-subtle);border-left-width:2.5px;animation:_ngcontent-%COMP%_slideInRight .2s ease;flex-shrink:0}.tip-sev-icon[_ngcontent-%COMP%]{flex-shrink:0;margin-top:1px}.tip-body-col[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:0}.tip-title[_ngcontent-%COMP%]{font-size:12.5px;font-weight:550;line-height:1.35;text-wrap:pretty}.tip-meta-row[_ngcontent-%COMP%]{margin-top:7px}.tip-fix[_ngcontent-%COMP%]{font-size:10.5px;color:var(--text-secondary);background:var(--bg-canvas);padding:2px 6px;border-radius:4px;border:1px solid var(--border-subtle);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:220px}.heatmap-card[_ngcontent-%COMP%]{margin-bottom:14px}.heatmap-head[_ngcontent-%COMP%]{justify-content:space-between;margin-bottom:10px}.heatmap-legend[_ngcontent-%COMP%]{margin-top:9px;align-items:center}.heatmap-gradient[_ngcontent-%COMP%]{width:96px;height:6px;border-radius:999px;background:linear-gradient(90deg,var(--node-route),var(--warn),var(--error))}.bottom-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:1.4fr 1fr;gap:12px}.prompts-card[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:0}.prompts-head[_ngcontent-%COMP%]{justify-content:space-between;margin-bottom:6px}.prompt-row[_ngcontent-%COMP%]{display:flex;gap:10px;padding:7px 4px;border-radius:6px;cursor:pointer;align-items:center}.prompt-row[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.prompt-text[_ngcontent-%COMP%]{font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.prompt-right[_ngcontent-%COMP%]{text-align:right;flex-shrink:0}.prompt-cost[_ngcontent-%COMP%]{font-size:12px;font-weight:600}.prompt-cost.expensive[_ngcontent-%COMP%]{color:var(--error)}.cache-card[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:12px}.cache-headline[_ngcontent-%COMP%]{align-items:flex-end;gap:10px}.cache-rate[_ngcontent-%COMP%]{font-size:38px;font-weight:700;letter-spacing:-.03em;line-height:.9;color:var(--node-route)}.cache-divider[_ngcontent-%COMP%]{height:1px;background:var(--border-subtle)}.cache-kv-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:1fr 1fr;gap:10px 14px}.kv[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:1px}.kv-label[_ngcontent-%COMP%]{color:var(--text-muted);font-size:10.5px}.kv-value[_ngcontent-%COMP%]{font-size:15px;font-weight:600}.kv-sub[_ngcontent-%COMP%]{font-size:9.5px}.dash-footer[_ngcontent-%COMP%]{margin-top:16px;text-align:right;font-size:10px}.dot-live[_ngcontent-%COMP%]{color:var(--success)}.dot-mock[_ngcontent-%COMP%]{color:var(--warn)}@keyframes _ngcontent-%COMP%_slideInRight{0%{opacity:0;transform:translate(14px)}to{opacity:1;transform:translate(0)}}'],changeDetection:0})},Be=[{id:"s-1",label:"validateSession",sub:"src/auth.ts",kind:"function",x:0,y:0},{id:"s-2",label:"checkExpiry",sub:"src/auth.ts",kind:"method",x:-180,y:-70},{id:"s-3",label:"signToken",sub:"src/auth.ts",kind:"function",x:-180,y:50},{id:"s-4",label:"AuthRoute",sub:"src/routes/auth.ts",kind:"route",x:200,y:-90},{id:"s-5",label:"login",sub:"src/routes/auth.ts",kind:"function",x:200,y:30},{id:"s-6",label:"logout",sub:"src/routes/auth.ts",kind:"function",x:230,y:110},{id:"s-7",label:"auth.test.ts",sub:"test/auth.test.ts",kind:"test",x:-240,y:140},{id:"s-8",label:"session.test.ts",sub:"test/session.test.ts",kind:"test",x:-100,y:180},{id:"s-9",label:"REQ-AUTH-005",sub:"reject expired tokens",kind:"spec",state:"drifted",x:30,y:-180},{id:"s-10",label:"REQ-AUTH-001",sub:"sign session tokens",kind:"spec",state:"verified",x:-150,y:-190},{id:"s-11",label:"User",sub:"src/types/user.ts",kind:"class",x:-340,y:-10},{id:"s-12",label:"Session",sub:"src/types/session.ts",kind:"class",x:60,y:130},{id:"s-13",label:"jwtSign",sub:"src/lib/jwt.ts",kind:"function",x:-340,y:80},{id:"s-14",label:"jwtVerify",sub:"src/lib/jwt.ts",kind:"function",x:350,y:-10},{id:"s-15",label:"tokenStore",sub:"src/db/tokens.ts",kind:"function",x:350,y:90}],Ve=[{from:"s-1",to:"s-2",kind:"calls"},{from:"s-1",to:"s-3",kind:"calls"},{from:"s-4",to:"s-5",kind:"calls"},{from:"s-4",to:"s-6",kind:"calls"},{from:"s-5",to:"s-1",kind:"calls"},{from:"s-6",to:"s-1",kind:"calls"},{from:"s-3",to:"s-13",kind:"calls"},{from:"s-2",to:"s-14",kind:"calls"},{from:"s-1",to:"s-12",kind:"references"},{from:"s-5",to:"s-11",kind:"references"},{from:"s-9",to:"s-1",kind:"implements"},{from:"s-10",to:"s-3",kind:"implements"},{from:"s-7",to:"s-1",kind:"references"},{from:"s-8",to:"s-12",kind:"references"},{from:"s-14",to:"s-15",kind:"calls"}];function je(i){if(i.length===0)return[];let t=i[0],e=i.slice(1),n=[{id:t.id,label:t.label,sub:t.sub,kind:t.kind,x:0,y:0}],d=220;for(let h=0;h<e.length;h++){let P=h/e.length*Math.PI*2-Math.PI/2,f=e[h];n.push({id:f.id,label:f.label,sub:f.sub,kind:f.kind,x:Math.cos(P)*d,y:Math.sin(P)*d})}return n}export{ee as Dashboard};