@selvakumaresra/specship 0.1.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/README.md +2 -2
  2. package/commands/ss-design-implement.md +79 -0
  3. package/commands/{cg-drifted.md → ss-drifted.md} +2 -2
  4. package/commands/{cg-fix.md → ss-fix.md} +1 -1
  5. package/commands/{cg-implement.md → ss-implement.md} +1 -1
  6. package/commands/ss-spec-author.md +43 -0
  7. package/commands/ss-spec-review.md +48 -0
  8. package/dist/bin/specship.js +6 -5
  9. package/dist/bin/specship.js.map +1 -1
  10. package/dist/db/index.d.ts +3 -1
  11. package/dist/db/index.d.ts.map +1 -1
  12. package/dist/db/index.js +5 -2
  13. package/dist/db/index.js.map +1 -1
  14. package/dist/db/migrations.d.ts +1 -1
  15. package/dist/db/migrations.d.ts.map +1 -1
  16. package/dist/db/migrations.js +36 -1
  17. package/dist/db/migrations.js.map +1 -1
  18. package/dist/db/schema.sql +9 -0
  19. package/dist/directory.d.ts +13 -3
  20. package/dist/directory.d.ts.map +1 -1
  21. package/dist/directory.js +17 -3
  22. package/dist/directory.js.map +1 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +1 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/installer/index.d.ts.map +1 -1
  27. package/dist/installer/index.js +16 -10
  28. package/dist/installer/index.js.map +1 -1
  29. package/dist/installer/targets/claude.d.ts +11 -1
  30. package/dist/installer/targets/claude.d.ts.map +1 -1
  31. package/dist/installer/targets/claude.js +59 -2
  32. package/dist/installer/targets/claude.js.map +1 -1
  33. package/dist/server/ingest/ingestor.js +117 -17
  34. package/dist/server/routes/claude.js +394 -6
  35. package/dist/server/routes/graph.js +62 -0
  36. package/dist/server/routes/spec.js +161 -1
  37. package/dist/server/routes/status.js +77 -0
  38. package/dist/server/routes/workflow.js +31 -3
  39. package/dist/web/chunk-2AJCHB7P.js +1 -0
  40. package/dist/web/chunk-2CPLUFCH.js +2 -0
  41. package/dist/web/chunk-2DHIGIOI.js +1 -0
  42. package/dist/web/chunk-2GBEK2GM.js +1 -0
  43. package/dist/web/chunk-2I7L37NS.js +1 -0
  44. package/dist/web/chunk-2NAWAJB5.js +1 -0
  45. package/dist/web/chunk-2OJBIPE4.js +1 -0
  46. package/dist/web/chunk-2OKMB4KX.js +2 -0
  47. package/dist/web/chunk-3E2WB6D5.js +1 -0
  48. package/dist/web/chunk-3EBFYSCH.js +2 -0
  49. package/dist/web/chunk-3QCQ4BXS.js +1 -0
  50. package/dist/web/chunk-3SEJX2BK.js +1 -0
  51. package/dist/web/chunk-42XVAQ6I.js +1 -0
  52. package/dist/web/chunk-4IMMPEYM.js +1 -0
  53. package/dist/web/chunk-4N5DWG46.js +1 -0
  54. package/dist/web/chunk-4TJQJPCZ.js +1 -0
  55. package/dist/web/chunk-4WZIHTPC.js +1 -0
  56. package/dist/web/chunk-4YVSYOSD.js +1 -0
  57. package/dist/web/chunk-5BQIOYKW.js +1 -0
  58. package/dist/web/chunk-5HGWHUJA.js +1 -0
  59. package/dist/web/chunk-5Y244R4G.js +1 -0
  60. package/dist/web/chunk-6RRDPT5Z.js +1 -0
  61. package/dist/web/chunk-6VKB2ZWM.js +1 -0
  62. package/dist/web/chunk-7DMFVTU4.js +1 -0
  63. package/dist/web/chunk-7RNS77UP.js +1 -0
  64. package/dist/web/chunk-7SMPKVEP.js +1 -0
  65. package/dist/web/chunk-AZJVTPLU.js +1 -0
  66. package/dist/web/chunk-BCZM5AXU.js +1 -0
  67. package/dist/web/chunk-BLBRMCN2.js +1 -0
  68. package/dist/web/chunk-BMIAXD2V.js +2 -0
  69. package/dist/web/chunk-BPECIDVO.js +1 -0
  70. package/dist/web/chunk-BUXWEHIY.js +1 -0
  71. package/dist/web/chunk-BYZFQSM6.js +1 -0
  72. package/dist/web/chunk-DA6SNNAF.js +1 -0
  73. package/dist/web/chunk-DLQPZWSI.css +1 -0
  74. package/dist/web/chunk-DTRN7FZR.js +1 -0
  75. package/dist/web/chunk-DYRFLPJA.js +1 -0
  76. package/dist/web/chunk-E3J3CXR5.js +1 -0
  77. package/dist/web/chunk-E44X4RH2.js +1 -0
  78. package/dist/web/chunk-E73OX2P7.js +1 -0
  79. package/dist/web/chunk-EAXRKDLV.js +1 -0
  80. package/dist/web/chunk-EBKKDHYI.js +1 -0
  81. package/dist/web/chunk-EE7V7Q5P.js +1 -0
  82. package/dist/web/chunk-EKY2FUHU.js +1 -0
  83. package/dist/web/chunk-EMGMOEVR.js +1 -0
  84. package/dist/web/chunk-EP6XOPXH.js +1 -0
  85. package/dist/web/chunk-ESGDLJOJ.js +1 -0
  86. package/dist/web/chunk-ETJG7NCY.js +1 -0
  87. package/dist/web/chunk-EUUEFEDI.js +1 -0
  88. package/dist/web/chunk-FGNZDHTL.js +11 -0
  89. package/dist/web/chunk-FIJW2UNJ.js +1 -0
  90. package/dist/web/chunk-FMV5PXRC.js +5 -0
  91. package/dist/web/chunk-G7VZT5KB.js +3 -0
  92. package/dist/web/chunk-GRZYXPSO.js +7 -0
  93. package/dist/web/chunk-GYGPS3AN.js +1 -0
  94. package/dist/web/chunk-H7AF7YS4.js +1 -0
  95. package/dist/web/chunk-HDZDQILN.js +1 -0
  96. package/dist/web/chunk-HMK6UO6N.js +1 -0
  97. package/dist/web/chunk-HZA6NEAB.js +1 -0
  98. package/dist/web/chunk-IHEE5NYJ.js +1 -0
  99. package/dist/web/chunk-ISNEBICW.js +1 -0
  100. package/dist/web/chunk-J2GZVLHH.js +1 -0
  101. package/dist/web/chunk-JFYVCXK3.js +1 -0
  102. package/dist/web/chunk-JN6W7HCN.js +17 -0
  103. package/dist/web/chunk-JT7P3DEK.js +6 -0
  104. package/dist/web/chunk-JTFXTIPE.js +903 -0
  105. package/dist/web/chunk-L37MTFSG.js +3 -0
  106. package/dist/web/chunk-LB6JPLX2.js +1 -0
  107. package/dist/web/chunk-LNSVDHCI.js +1 -0
  108. package/dist/web/chunk-LV4G6QFG.js +2 -0
  109. package/dist/web/chunk-LVGIY3SO.js +1 -0
  110. package/dist/web/chunk-LXLHIHEN.js +1 -0
  111. package/dist/web/chunk-MC4DFIHG.js +1 -0
  112. package/dist/web/chunk-MVOMVPYB.js +1 -0
  113. package/dist/web/chunk-N6SS4G6S.js +1 -0
  114. package/dist/web/chunk-NTBJG6SJ.js +1 -0
  115. package/dist/web/chunk-NUDB3Q2Y.js +3 -0
  116. package/dist/web/chunk-OXEF5E3E.js +1 -0
  117. package/dist/web/chunk-PDN6QYGJ.js +4 -0
  118. package/dist/web/chunk-PGGJPDJG.js +1 -0
  119. package/dist/web/chunk-PUYSJNJR.js +1 -0
  120. package/dist/web/chunk-Q2RVFS45.js +1 -0
  121. package/dist/web/chunk-Q7L6LLAK.js +1 -0
  122. package/dist/web/chunk-QCMKJIWY.js +1 -0
  123. package/dist/web/chunk-QH6CF3M3.js +1 -0
  124. package/dist/web/chunk-QQ5LD7PI.js +1 -0
  125. package/dist/web/chunk-QR6L3KAC.js +1 -0
  126. package/dist/web/chunk-R2DLK4HO.js +1 -0
  127. package/dist/web/chunk-R5W2MDZN.js +1 -0
  128. package/dist/web/chunk-RAAMPHPJ.js +1 -0
  129. package/dist/web/chunk-RD6TVPOT.js +1 -0
  130. package/dist/web/chunk-RKY4EJYJ.js +1 -0
  131. package/dist/web/chunk-RONYWVY7.js +1 -0
  132. package/dist/web/chunk-RXKXYF2C.js +1 -0
  133. package/dist/web/chunk-SBWU7JFC.js +1 -0
  134. package/dist/web/chunk-SEXBRGYK.js +1 -0
  135. package/dist/web/chunk-SHPTC4RL.js +1 -0
  136. package/dist/web/chunk-SUZYBYDW.js +1 -0
  137. package/dist/web/chunk-SWKJRNYY.js +1 -0
  138. package/dist/web/chunk-T66XVKGB.js +1 -0
  139. package/dist/web/chunk-T7AZ65JP.js +1 -0
  140. package/dist/web/chunk-TCZDVOHD.js +1 -0
  141. package/dist/web/chunk-TPTITA3V.js +1 -0
  142. package/dist/web/chunk-TR335633.js +1 -0
  143. package/dist/web/chunk-TWXZK6XM.js +1 -0
  144. package/dist/web/chunk-UR5KDXPX.js +1 -0
  145. package/dist/web/chunk-UR6O2GEH.js +1 -0
  146. package/dist/web/chunk-UTNMGWTP.js +1 -0
  147. package/dist/web/chunk-UYC52MBC.js +1 -0
  148. package/dist/web/chunk-VECWMHJP.js +1 -0
  149. package/dist/web/chunk-VUACT35R.js +3 -0
  150. package/dist/web/chunk-VZI7H4SZ.js +1 -0
  151. package/dist/web/chunk-WAI2JMZP.js +1 -0
  152. package/dist/web/chunk-WB6YHOD4.js +1 -0
  153. package/dist/web/chunk-WBT64AWV.js +1 -0
  154. package/dist/web/chunk-WDU3WICG.js +1 -0
  155. package/dist/web/chunk-WFXJIXZE.js +4 -0
  156. package/dist/web/chunk-WTGYRH3Z.js +298 -0
  157. package/dist/web/chunk-WXTCVDTP.js +1 -0
  158. package/dist/web/chunk-X2HTISHL.js +1 -0
  159. package/dist/web/chunk-XCDHWLVH.js +1 -0
  160. package/dist/web/chunk-Y3H6FFUZ.js +1 -0
  161. package/dist/web/chunk-Y4F5ULGJ.js +1 -0
  162. package/dist/web/chunk-YAWCRPHV.js +1 -0
  163. package/dist/web/chunk-YEGKAAEE.js +1 -0
  164. package/dist/web/chunk-YM2KU57F.js +1 -0
  165. package/dist/web/chunk-YRERBP6T.js +1 -0
  166. package/dist/web/chunk-ZLV4VCDG.js +3 -0
  167. package/dist/web/chunk-ZTVI5KFF.js +1 -0
  168. package/dist/web/index.html +3 -3
  169. package/dist/web/main-ESADRXN2.css +1 -0
  170. package/dist/web/main-WVI3YTDU.js +1 -0
  171. package/dist/web/media/codicon-LN6W7LCM.ttf +0 -0
  172. package/dist/web/styles-KSOPUVDA.css +1 -0
  173. package/dist/workflows/defaults/claude-design-implement.yaml +247 -0
  174. package/dist/workflows/defaults/spec-author.yaml +214 -0
  175. package/dist/workflows/executor.d.ts.map +1 -1
  176. package/dist/workflows/executor.js +4 -3
  177. package/dist/workflows/executor.js.map +1 -1
  178. package/package.json +8 -3
  179. package/scripts/offline-install.sh +19 -6
  180. package/scripts/sync-shim-version.mjs +64 -0
  181. package/dist/web/chunk-2YZXEHZ2.js +0 -1
  182. package/dist/web/chunk-3GIC555L.js +0 -18
  183. package/dist/web/chunk-3IIIGRMT.js +0 -1
  184. package/dist/web/chunk-47QYKLE5.js +0 -1
  185. package/dist/web/chunk-4LHBWWP7.js +0 -1
  186. package/dist/web/chunk-4OAZLD5W.js +0 -1
  187. package/dist/web/chunk-5OQKAJAE.js +0 -1
  188. package/dist/web/chunk-7B525GKQ.js +0 -1
  189. package/dist/web/chunk-BPDXCOOZ.js +0 -1
  190. package/dist/web/chunk-DT37HTZB.js +0 -1
  191. package/dist/web/chunk-EIMUHJND.js +0 -1
  192. package/dist/web/chunk-FTESTUEO.js +0 -1
  193. package/dist/web/chunk-GLJZV6MU.js +0 -1
  194. package/dist/web/chunk-I7LS67U5.js +0 -1
  195. package/dist/web/chunk-L4TVIPSR.js +0 -1
  196. package/dist/web/chunk-MASCULC2.js +0 -1
  197. package/dist/web/chunk-MW7ICSRM.js +0 -1
  198. package/dist/web/chunk-OI5VP2A3.js +0 -1
  199. package/dist/web/chunk-RA6EBF6I.js +0 -1
  200. package/dist/web/chunk-RP3WU5Y6.js +0 -1
  201. package/dist/web/chunk-RQDRMTXN.js +0 -1
  202. package/dist/web/chunk-TQMT6UDU.js +0 -1
  203. package/dist/web/chunk-U7IYOV7T.js +0 -1
  204. package/dist/web/chunk-UE227MWF.js +0 -1
  205. package/dist/web/chunk-WV573J4K.js +0 -1
  206. package/dist/web/chunk-WVCKOJZL.js +0 -4
  207. package/dist/web/chunk-XZKLVPHE.js +0 -1
  208. package/dist/web/chunk-ZABKKHJ3.js +0 -1
  209. package/dist/web/main-RI5CO5Z4.js +0 -1
  210. package/dist/web/styles-CYN7IKT4.css +0 -1
  211. /package/commands/{cg-explore.md → ss-explore.md} +0 -0
  212. /package/commands/{cg-impact.md → ss-impact.md} +0 -0
  213. /package/commands/{cg-relink.md → ss-relink.md} +0 -0
  214. /package/commands/{cg-spec.md → ss-spec.md} +0 -0
  215. /package/commands/{cg-sync.md → ss-sync.md} +0 -0
  216. /package/commands/{cg-trace.md → ss-trace.md} +0 -0
@@ -0,0 +1 @@
1
+ import{a as $}from"./chunk-SBWU7JFC.js";import{a as me,b as F}from"./chunk-4N5DWG46.js";import{b as se,c as B,d as de,e as pe,f as ce}from"./chunk-SHPTC4RL.js";import{a as j}from"./chunk-7RNS77UP.js";import{a as A}from"./chunk-E44X4RH2.js";import{$ as ne,Aa as p,Ba as d,Ca as c,Da as C,Ga as k,Ha as J,I as v,Ia as h,Ja as R,Ka as m,M as y,N as P,O as Q,R as ee,Ta as oe,Ua as M,V as te,Va as l,W as T,Wa as b,Xa as X,Ya as ae,ca as ie,cb as re,da as Y,ea as o,ka as x,lb as I,ob as N,pb as S,qa as w,ra as g,sa as u,va as O,wa as E,wb as le,xa as f,ya as a,za as r,zb as D}from"./chunk-PDN6QYGJ.js";import"./chunk-Q7L6LLAK.js";var ge=[{path:"",pathMatch:"full",redirectTo:"dashboard"},{path:"dashboard",loadComponent:()=>import("./chunk-2OKMB4KX.js").then(e=>e.Dashboard),data:{nav:"dashboard",title:"Dashboard"}},{path:"graph",loadComponent:()=>import("./chunk-JFYVCXK3.js").then(e=>e.Graph),data:{nav:"graph",title:"Graph"}},{path:"specs",loadComponent:()=>import("./chunk-JT7P3DEK.js").then(e=>e.Specs),data:{nav:"specs",title:"Specs"}},{path:"drift",loadComponent:()=>import("./chunk-3SEJX2BK.js").then(e=>e.Drift),data:{nav:"drift",title:"Drift queue"}},{path:"workflows",loadComponent:()=>import("./chunk-YAWCRPHV.js").then(e=>e.Workflows),data:{nav:"workflows",title:"Workflows"}},{path:"runs",loadComponent:()=>import("./chunk-BCZM5AXU.js").then(e=>e.Runs),data:{nav:"runs",title:"Runs"}},{path:"runs/:id",loadComponent:()=>import("./chunk-MVOMVPYB.js").then(e=>e.RunDetail),data:{nav:"runs",title:"Run detail"}},{path:"chat",loadComponent:()=>import("./chunk-L37MTFSG.js").then(e=>e.Chat),data:{nav:"chat",title:"Chat"}},{path:"sessions",loadComponent:()=>import("./chunk-2DHIGIOI.js").then(e=>e.Sessions),data:{nav:"sessions",title:"Sessions"}},{path:"sessions/:id",loadComponent:()=>import("./chunk-DA6SNNAF.js").then(e=>e.SessionDetail),data:{nav:"sessions",title:"Session detail"}},{path:"heatmap",loadComponent:()=>import("./chunk-LV4G6QFG.js").then(e=>e.Heatmap),data:{nav:"heatmap",title:"Heatmap"}},{path:"costs",loadComponent:()=>import("./chunk-TWXZK6XM.js").then(e=>e.Costs),data:{nav:"costs",title:"Costs"}},{path:"compare",loadComponent:()=>import("./chunk-BPECIDVO.js").then(e=>e.Compare),data:{nav:"compare",title:"Compare projects"}},{path:"tips",loadComponent:()=>import("./chunk-RAAMPHPJ.js").then(e=>e.Tips),data:{nav:"tips",title:"Tips"}},{path:"memory",loadComponent:()=>import("./chunk-JN6W7HCN.js").then(e=>e.Memory),data:{nav:"memory",title:"Memory"}},{path:"design",loadComponent:()=>import("./chunk-WAI2JMZP.js").then(e=>e.Design),data:{nav:"design",title:"Design system"}},{path:"settings",loadComponent:()=>import("./chunk-BYZFQSM6.js").then(e=>e.Settings),data:{nav:"settings",title:"Settings"}},{path:"**",redirectTo:"dashboard"}];var ue={providers:[te(),ce(ge)]};function fe(e,n){e&1&&(Q(),C(0,"rect",14)(1,"rect",15))}var V=class e{size=S(24);tile=S(!0);glow=S(!0);static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-logo-mark"]],inputs:{size:[1,"size"],tile:[1,"tile"],glow:[1,"glow"]},decls:16,vars:5,consts:[["viewBox","0 0 32 32","fill","none",2,"flex-shrink","0"],["id","ssTile","x1","0","y1","0","x2","32","y2","32","gradientUnits","userSpaceOnUse"],["stop-color","#12161E"],["offset","1","stop-color","#0B0D11"],["id","ssLead","x1","18","y1","11","x2","26","y2","21","gradientUnits","userSpaceOnUse"],["stop-color","#6FA0F6"],["offset","1","stop-color","#5B93F2"],["transform","translate(4.6 4.6) scale(0.715)"],["d","M5 16 H11 M11 9 L23 16 L11 23","stroke","rgba(150,165,200,0.5)","stroke-width","1.9","stroke-linecap","round","stroke-linejoin","round","fill","none"],["x1","11","y1","9","x2","11","y2","23","stroke","rgba(150,165,200,0.4)","stroke-width","1.9","stroke-linecap","round"],["cx","23","cy","16","r","3.6","fill","url(#ssLead)"],["cx","11","cy","9","r","2.9","fill","#A586F5"],["cx","11","cy","23","r","2.9","fill","#46C26B"],["cx","5","cy","16","r","2.1","fill","#29D2BE"],["width","32","height","32","rx","7.2","fill","url(#ssTile)"],["x","0.5","y","0.5","width","31","height","31","rx","6.7","fill","none","stroke","rgba(255,255,255,0.08)"]],template:function(t,i){t&1&&(Q(),d(0,"svg",0)(1,"defs")(2,"linearGradient",1),C(3,"stop",2)(4,"stop",3),c(),d(5,"linearGradient",4),C(6,"stop",5)(7,"stop",6),c()(),g(8,fe,2,0),d(9,"g",7),C(10,"path",8)(11,"line",9)(12,"circle",10)(13,"circle",11)(14,"circle",12)(15,"circle",13),c()()),t&2&&(oe("filter",i.glow()?"drop-shadow(0 0 9px rgba(91,147,242,0.35))":"none"),w("width",i.size())("height",i.size()),o(8),u(i.tile()?8:-1))},styles:["[_nghost-%COMP%]{display:inline-flex;align-items:center;justify-content:center;line-height:0}"],changeDetection:0})};var be=e=>["/",e],ve=(e,n)=>n.group,_e=(e,n)=>n.id;function xe(e,n){e&1&&(a(0,"div",3),l(1,"SpecShip "),a(2,"span",14),l(3,"Desktop"),r()())}function he(e,n){if(e&1&&(a(0,"div",15),l(1),r()),e&2){let t=m().$implicit;o(),b(t.group)}}function Ce(e,n){if(e&1&&(a(0,"span",18),l(1),r()),e&2){let t=m(2).$implicit,i=m(2);w("data-kind",t.badgeKind),o(),b(i.badgeOf(t))}}function ye(e,n){if(e&1&&(a(0,"span",11),l(1),r(),g(2,Ce,2,2,"span",18)),e&2){let t=m().$implicit,i=m(2);o(),b(t.label),o(),u(i.badgeOf(t)>0?2:-1)}}function Pe(e,n){if(e&1&&(a(0,"a",16),p(1,"span",8),a(2,"span",9),p(3,"app-icon",17),r(),g(4,ye,3,2),r()),e&2){let t=n.$implicit,i=m(2);f("routerLink",re(5,be,t.id))("title",i.collapsed()?t.label:null),o(3),f("name",t.icon)("size",16),o(),u(i.collapsed()?-1:4)}}function ke(e,n){if(e&1&&(a(0,"div",5),g(1,he,2,1,"div",15),O(2,Pe,5,7,"a",16,_e),r()),e&2){let t=n.$implicit,i=m();o(),u(i.collapsed()?-1:1),o(),E(t.items)}}function we(e,n){e&1&&(a(0,"span",11),l(1,"Design system"),r())}function Me(e,n){e&1&&(a(0,"span",11),l(1,"Settings"),r())}var H=class e{collapsed=S(!1);api=v(A);projects=v(j);status=F(this.api,()=>`/api/status${this.projects.projectQuery()}`);tips=F(this.api,()=>"/api/claude/tips");nav=[{group:"Project",items:[{id:"dashboard",label:"Dashboard",icon:"dashboard"},{id:"graph",label:"Graph",icon:"graph"},{id:"specs",label:"Specs",icon:"book"},{id:"drift",label:"Drift queue",icon:"drift",badge:()=>this.status.state().data?.drift??0,badgeKind:"warn"},{id:"workflows",label:"Workflows",icon:"workflow"},{id:"runs",label:"Runs",icon:"play"},{id:"chat",label:"Chat",icon:"chat"}]},{group:"Claude Code",items:[{id:"sessions",label:"Sessions",icon:"sessions"},{id:"heatmap",label:"Heatmap",icon:"heatmap"},{id:"costs",label:"Costs",icon:"dollar"},{id:"compare",label:"Compare projects",icon:"compare"},{id:"memory",label:"Memory",icon:"memory"},{id:"tips",label:"Tips",icon:"tips",badge:()=>(this.tips.state().data?.tips??[]).filter(n=>n.severity!=="info").length,badgeKind:"error"}]}];badgeOf(n){return n.badge?n.badge():0}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-sidebar"]],inputs:{collapsed:[1,"collapsed"]},decls:18,vars:10,consts:[[1,"sidebar"],[1,"brand"],[3,"size"],[1,"brand-text"],[1,"scroll-y","nav-scroll"],[1,"nav-group"],[1,"pinned"],["routerLink","/design","routerLinkActive","active",1,"nav-item",3,"title"],[1,"indicator"],[1,"nav-icon"],["name","palette",3,"size"],[1,"nav-label"],["routerLink","/settings","routerLinkActive","active",1,"nav-item",3,"title"],["name","settings",3,"size"],[1,"muted"],[1,"eyebrow","group-label"],["routerLinkActive","active",1,"nav-item",3,"routerLink","title"],[3,"name","size"],[1,"badge"]],template:function(t,i){t&1&&(a(0,"nav",0)(1,"div",1),p(2,"app-logo-mark",2),g(3,xe,4,0,"div",3),r(),a(4,"div",4),O(5,ke,4,1,"div",5,ve),r(),a(7,"div",6)(8,"a",7),p(9,"span",8),a(10,"span",9),p(11,"app-icon",10),r(),g(12,we,2,0,"span",11),r(),a(13,"a",12),p(14,"span",8),a(15,"span",9),p(16,"app-icon",13),r(),g(17,Me,2,0,"span",11),r()()()),t&2&&(M("collapsed",i.collapsed()),o(2),f("size",26),o(),u(i.collapsed()?-1:3),o(2),E(i.nav),o(3),f("title",i.collapsed()?"Design system":null),o(3),f("size",16),o(),u(i.collapsed()?-1:12),o(),f("title",i.collapsed()?"Settings":null),o(3),f("size",16),o(),u(i.collapsed()?-1:17))},dependencies:[de,pe,D,V],styles:['@charset "UTF-8";[_nghost-%COMP%]{display:contents}.sidebar[_ngcontent-%COMP%]{width:var(--sidebar-w);flex-shrink:0;background:var(--bg-panel);border-right:1px solid var(--border-subtle);display:flex;flex-direction:column;transition:width .12s;overflow:hidden;font-family:var(--font-ui)}.sidebar.collapsed[_ngcontent-%COMP%]{width:var(--sidebar-w-collapsed)}.brand[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;padding:15px 16px}.collapsed[_ngcontent-%COMP%] .brand[_ngcontent-%COMP%]{justify-content:center;padding:14px 0}.brand-text[_ngcontent-%COMP%]{font-weight:600;font-size:13.5px;letter-spacing:-.01em}.brand-text[_ngcontent-%COMP%] .muted[_ngcontent-%COMP%]{color:var(--text-muted);font-weight:400}.nav-scroll[_ngcontent-%COMP%]{flex:1;padding:4px 8px}.nav-group[_ngcontent-%COMP%]{margin-bottom:10px}.group-label[_ngcontent-%COMP%]{padding:8px 8px 4px}.nav-item[_ngcontent-%COMP%]{position:relative;display:flex;align-items:center;gap:10px;height:32px;padding:0 10px;border-radius:7px;text-decoration:none;margin-bottom:1px;color:var(--text-secondary);font-weight:450;font-size:13px;transition:background .1s}.collapsed[_ngcontent-%COMP%] .nav-item[_ngcontent-%COMP%]{padding:0;justify-content:center}.nav-item[_ngcontent-%COMP%]:hover{background:var(--bg-hover);color:var(--text-primary)}.nav-item.active[_ngcontent-%COMP%]{background:var(--bg-active);color:var(--text-primary);font-weight:600}.nav-item.active[_ngcontent-%COMP%] .indicator[_ngcontent-%COMP%]{position:absolute;left:0;top:7px;bottom:7px;width:2.5px;border-radius:2px;background:var(--accent)}.nav-icon[_ngcontent-%COMP%]{width:16px;height:16px;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;color:var(--text-secondary)}.nav-item[_ngcontent-%COMP%]:hover .nav-icon[_ngcontent-%COMP%]{color:var(--text-primary)}.nav-item.active[_ngcontent-%COMP%] .nav-icon[_ngcontent-%COMP%]{color:var(--accent)}.nav-label[_ngcontent-%COMP%]{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.badge[_ngcontent-%COMP%]{font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-size:10px;font-weight:700;padding:1px 6px;min-width:18px;border-radius:999px;display:inline-flex;justify-content:center;color:var(--text-secondary);background:#ffffff0f}.badge[data-kind=error][_ngcontent-%COMP%]{color:var(--error);background:var(--error-soft)}.badge[data-kind=warn][_ngcontent-%COMP%]{color:var(--warn);background:var(--warn-soft)}.pinned[_ngcontent-%COMP%]{padding:8px;border-top:1px solid var(--border-subtle)}'],changeDetection:0})};function Se(e,n){e&1&&(d(0,"span",8),l(1,"\u26A0"),c()),e&2&&J("title",n)}function Oe(e,n){if(e&1){let t=k();d(0,"span",2),l(1),c(),C(2,"span",3),d(3,"span",4)(4,"span",5),l(5,"backend"),c(),d(6,"span",6),l(7),c()(),C(8,"span",3),d(9,"span",4)(10,"span",5),l(11,"nodes"),c(),d(12,"span",6),l(13),c()(),d(14,"span",4)(15,"span",5),l(16,"edges"),c(),d(17,"span",6),l(18),c()(),C(19,"span",3),d(20,"span",4)(21,"span",5),l(22,"drift"),c(),d(23,"span",6),l(24),c()(),C(25,"span",7),d(26,"span",4)(27,"span",5),l(28,"indexed"),c(),d(29,"span",6),l(30),c()(),g(31,Se,2,1,"span",8),d(32,"button",9),R("click",function(){y(t);let s=m();return P(s.refresh())}),l(33,"\u21BB"),c()}if(e&2){let t,i=m(),s=i.status.state().data;o(),b(s.projectPath),o(6),b(s.backend),o(6),b(s.nodeCount.toLocaleString()),o(5),b(s.edgeCount.toLocaleString()),o(5),M("warn",s.drift>0)("success",s.drift===0),o(),b(s.drift),o(6),b(i.indexedLabel()),o(),u((t=i.refreshSvc.error())?31:-1,t),o(),M("spinning",i.refreshSvc.loading()),J("disabled",i.refreshSvc.loading())("title",i.refreshSvc.loading()?"Refreshing\u2026":"Refresh: sync index + re-ingest Claude Code transcripts. Updates Sessions, Heatmap, Costs, Memory, Drift, Graph."),w("aria-label",i.refreshSvc.loading()?"Refreshing\u2026":"Refresh everything \u2014 sync index + ingest Claude Code transcripts")}}function Ee(e,n){e&1&&(d(0,"span",1),l(1,"loading status\u2026"),c())}function Te(e,n){e&1&&(d(0,"span",1),l(1,"no backend"),c())}var G=class e{api=v(A);projects=v(j);refreshSvc=v(me);status=F(this.api,()=>`/api/status${this.projects.projectQuery()}`);indexedLabel=I(()=>{let n=this.status.state().data?.lastIndexed;if(!n)return"never";try{let t=new Date(n),i=Date.now()-t.getTime();return i<6e4?"just now":i<36e5?`${Math.round(i/6e4)}m ago`:i<864e5?`${Math.round(i/36e5)}h ago`:t.toLocaleDateString()}catch{return String(n)}});async refresh(){await this.refreshSvc.triggerGlobalRefresh()}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-status-strip"]],decls:4,vars:1,consts:[[1,"status-strip"],[1,"mono","muted"],[1,"seg","mono"],[1,"divider"],[1,"seg"],[1,"lbl"],[1,"mono","val"],[1,"grow"],[1,"refresh-error","mono",3,"title"],[1,"refresh",3,"click","disabled","title"]],template:function(t,i){t&1&&(d(0,"div",0),g(1,Oe,34,16)(2,Ee,2,0,"span",1)(3,Te,2,0,"span",1),c()),t&2&&(o(),u(i.status.state().data?1:i.status.state().loading?2:3))},styles:["[_nghost-%COMP%]{display:contents}.status-strip[_ngcontent-%COMP%]{height:var(--status-h);flex-shrink:0;display:flex;align-items:center;gap:14px;padding:0 14px;border-bottom:1px solid var(--border-subtle);background:var(--bg-panel-2);font-size:11.5px;overflow:hidden;white-space:nowrap}.seg[_ngcontent-%COMP%]{display:flex;align-items:center;gap:6px;flex-shrink:0}.lbl[_ngcontent-%COMP%]{color:var(--text-muted);font-size:11px}.val[_ngcontent-%COMP%]{color:var(--text-secondary);font-variant-numeric:tabular-nums}.val.warn[_ngcontent-%COMP%]{color:var(--warn)}.val.success[_ngcontent-%COMP%]{color:var(--success)}.divider[_ngcontent-%COMP%]{width:1px;height:12px;background:var(--border-subtle);flex-shrink:0}.grow[_ngcontent-%COMP%]{flex:1}.muted[_ngcontent-%COMP%]{color:var(--text-muted)}.refresh[_ngcontent-%COMP%]{background:transparent;border:none;color:var(--text-muted);cursor:pointer;font-size:14px;padding:2px 6px;border-radius:4px;transition:background .12s,color .12s}.refresh[_ngcontent-%COMP%]:hover:not(:disabled){background:var(--bg-hover);color:var(--text-primary)}.refresh[_ngcontent-%COMP%]:disabled{cursor:progress;opacity:.8}.refresh[_ngcontent-%COMP%]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.refresh.spinning[_ngcontent-%COMP%]{display:inline-block;animation:_ngcontent-%COMP%_spin .9s linear infinite;color:var(--accent)}@keyframes _ngcontent-%COMP%_spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.refresh-error[_ngcontent-%COMP%]{color:var(--warn);font-size:12px;padding:0 2px;cursor:help}"],changeDetection:0})};var je=(e,n)=>n.slug;function De(e,n){e&1&&p(0,"span",8)}function ze(e,n){e&1&&p(0,"span",9)}function Le(e,n){e&1&&p(0,"span",10)}function Re(e,n){if(e&1&&(a(0,"span",7),l(1),r(),g(2,De,1,0,"span",8)(3,ze,1,0,"span",9)(4,Le,1,0,"span",10)),e&2){let t=n,i=m();o(),b(i.shortPath(t.path)),o(),u(t.exists?t.initialized?4:3:2)}}function Ie(e,n){e&1&&(a(0,"span",3),l(1,"Select project"),r())}function Ne(e,n){if(e&1){let t=k();a(0,"button",20),h("click",function(){y(t);let s=m(2);return P(s.clear())}),p(1,"app-icon",21),l(2," Clear "),r()}e&2&&(o(),f("size",11))}function Fe(e,n){e&1&&(a(0,"span",16),l(1,"\xB7 loading\u2026"),r())}function Be(e,n){if(e&1&&(a(0,"span",16),l(1),r()),e&2){let t=m(2);o(),X("\xB7 ",t.filtered().length," shown \xB7 live")}}function Ae(e,n){e&1&&(a(0,"div",18),l(1,"No projects match."),r())}function $e(e,n){e&1&&(a(0,"span",25),l(1,"missing"),r())}function Ve(e,n){e&1&&(a(0,"span",26),l(1,"not init"),r())}function He(e,n){e&1&&(a(0,"span",27),l(1,"initialized"),r())}function Ge(e,n){if(e&1&&(a(0,"span"),l(1),r()),e&2){let t=m().$implicit,i=m(2);o(),X("\xB7 ",i.formatRelative(t.lastModifiedMs))}}function qe(e,n){e&1&&p(0,"app-icon",29),e&2&&f("size",13)}function Ke(e,n){if(e&1){let t=k();a(0,"button",22),h("click",function(){let s=y(t).$implicit,_=m(2);return P(_.pick(s.slug))}),a(1,"div",23)(2,"div",24)(3,"span",7),l(4),r(),g(5,$e,2,0,"span",25)(6,Ve,2,0,"span",26)(7,He,2,0,"span",27),r(),a(8,"div",28)(9,"span"),l(10),r(),g(11,Ge,2,1,"span"),r()(),g(12,qe,1,1,"app-icon",29),r()}if(e&2){let t=n.$implicit,i=m(2);M("active",i.projects.activeSlug()===t.slug),o(4),b(i.shortPath(t.path)),o(),u(t.exists?t.initialized?7:6:5),o(5),ae("",t.sessionCount," session",t.sessionCount===1?"":"s"),o(),u(t.lastModifiedMs>0?11:-1),o(),u(i.projects.activeSlug()===t.slug?12:-1)}}function We(e,n){if(e&1){let t=k();a(0,"div",6)(1,"div",11),p(2,"app-icon",12),a(3,"input",13),h("input",function(s){y(t);let _=m();return P(_.onQuery(s.target.value))}),r(),g(4,Ne,3,1,"button",14),r(),a(5,"div",15)(6,"span"),l(7),r(),g(8,Fe,2,0,"span",16)(9,Be,2,1,"span",16),r(),a(10,"div",17),g(11,Ae,2,0,"div",18),O(12,Ke,13,8,"button",19,je),r()()}if(e&2){let t=m();o(2),f("size",13),o(),f("value",t.query()),o(),u(t.projects.activeSlug()?4:-1),o(3),b(t.projects.claudeRoot()??"~/.claude/projects"),o(),u(t.projects.loading()?8:9),o(3),u(t.filtered().length===0&&!t.projects.loading()?11:-1),o(),E(t.filtered())}}var q=class e{host=v(ne);projects=v(j);open=T(!1);query=T("");filtered=I(()=>{let n=this.query().trim().toLowerCase(),t=this.projects.projects();return n?t.filter(i=>i.path.toLowerCase().includes(n)||i.slug.toLowerCase().includes(n)):t});badge=I(()=>this.projects.projects().length);toggle(){this.open.update(n=>!n)}pick(n){this.projects.setActive(n),this.open.set(!1),this.query.set("")}clear(){this.projects.setActive(null),this.open.set(!1)}onQuery(n){this.query.set(n)}onDocumentClick(n){if(!this.open())return;let t=n.target;t&&!this.host.nativeElement.contains(t)&&this.open.set(!1)}onEscape(){this.open()&&this.open.set(!1)}formatRelative(n){if(!n)return"";let t=Date.now()-n,i=Math.round(t/1e3);if(i<60)return`${i}s ago`;let s=Math.round(i/60);if(s<60)return`${s}m ago`;let _=Math.round(s/60);if(_<24)return`${_}h ago`;let Z=Math.round(_/24);return Z<30?`${Z}d ago`:new Date(n).toLocaleDateString()}shortPath(n){if(!n)return"";let t=this.detectHome();return t&&n===t?"~":t&&n.startsWith(t+"/")?"~/"+n.slice(t.length+1):n}detectHome(){let n=this.projects.claudeRoot();if(!n)return null;let t="/.claude/projects";return n.endsWith(t)?n.slice(0,-t.length):null}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-project-picker"]],hostBindings:function(t,i){t&1&&h("click",function(_){return i.onDocumentClick(_)},Y)("keydown.escape",function(){return i.onEscape()},Y)},decls:9,vars:9,consts:[[1,"wrap"],["type","button","aria-label","Switch project",1,"trigger",3,"click"],["name","folder",3,"size"],[1,"placeholder"],[1,"badge","mono"],[3,"name","size"],["role","dialog","aria-label","Pick a project",1,"popover"],[1,"path","mono"],["title","path no longer exists on disk",1,"status-dot","missing"],["title","not yet specship init'd",1,"status-dot","warn"],["title","initialized",1,"status-dot","ok"],[1,"popover-head","row","gap-8"],["name","search",3,"size"],["type","text","placeholder","Filter projects\u2026","autofocus","",1,"popover-input",3,"input","value"],["title","Clear selection",1,"btn","btn-ghost","btn-xs"],[1,"popover-meta","mono"],[1,"muted"],[1,"popover-list","scroll-y"],[1,"empty"],["type","button",1,"row-item",3,"active"],["title","Clear selection",1,"btn","btn-ghost","btn-xs",3,"click"],["name","x",3,"size"],["type","button",1,"row-item",3,"click"],[1,"col","gap-2","grow"],[1,"row","gap-6","path-line"],[1,"pill","missing"],[1,"pill","warn"],[1,"pill","ok"],[1,"meta","row","gap-8","mono","muted"],["name","check",3,"size"]],template:function(t,i){if(t&1&&(a(0,"div",0)(1,"button",1),h("click",function(){return i.toggle()}),p(2,"app-icon",2),g(3,Re,5,2)(4,Ie,2,0,"span",3),a(5,"span",4),l(6),r(),p(7,"app-icon",5),r(),g(8,We,14,6,"div",6),r()),t&2){let s;M("open",i.open()),o(),w("aria-expanded",i.open()),o(),f("size",13),o(),u((s=i.projects.active())?3:4,s),o(3),b(i.badge()),o(),f("name",i.open()?"chevronDown":"chevronRight")("size",11),o(),u(i.open()?8:-1)}},dependencies:[D],styles:["[_nghost-%COMP%]{display:inline-flex;min-width:0}.wrap[_ngcontent-%COMP%]{position:relative;min-width:0}.trigger[_ngcontent-%COMP%]{height:30px;padding:0 11px 0 10px;background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:8px;color:var(--text-secondary);display:inline-flex;align-items:center;gap:8px;font-family:var(--font-ui);font-size:12.5px;cursor:pointer;max-width:360px;min-width:0;transition:background .1s,border-color .1s}.trigger[_ngcontent-%COMP%]:hover, .wrap.open[_ngcontent-%COMP%] .trigger[_ngcontent-%COMP%]{background:var(--bg-panel-2);border-color:var(--border-strong);color:var(--text-primary)}.trigger[_ngcontent-%COMP%] app-icon[_ngcontent-%COMP%]{color:var(--text-muted);flex-shrink:0}.trigger[_ngcontent-%COMP%]:hover app-icon[_ngcontent-%COMP%]{color:var(--text-secondary)}.path[_ngcontent-%COMP%]{font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.placeholder[_ngcontent-%COMP%]{color:var(--text-muted);font-style:italic}.status-dot[_ngcontent-%COMP%]{width:6px;height:6px;border-radius:50%;flex-shrink:0}.status-dot.ok[_ngcontent-%COMP%]{background:var(--success)}.status-dot.warn[_ngcontent-%COMP%]{background:var(--warn)}.status-dot.missing[_ngcontent-%COMP%]{background:var(--error)}.badge[_ngcontent-%COMP%]{font-size:10px;padding:1px 6px;border-radius:999px;background:var(--bg-active);color:var(--text-muted);font-variant-numeric:tabular-nums;flex-shrink:0}.popover[_ngcontent-%COMP%]{position:absolute;top:calc(100% + 6px);left:0;z-index:30;width:420px;max-width:calc(100vw - 40px);background:var(--bg-elevated);border:1px solid var(--border-strong);border-radius:10px;box-shadow:var(--shadow-pop);display:flex;flex-direction:column;max-height:480px;animation:_ngcontent-%COMP%_pp-in .12s ease-out}@keyframes _ngcontent-%COMP%_pp-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.popover-head[_ngcontent-%COMP%]{padding:10px 12px 8px;border-bottom:1px solid var(--border-subtle)}.popover-head[_ngcontent-%COMP%] app-icon[_ngcontent-%COMP%]{color:var(--text-muted);flex-shrink:0}.popover-input[_ngcontent-%COMP%]{flex:1;min-width:0;background:transparent;border:none;outline:none;font-family:var(--font-ui);font-size:13px;color:var(--text-primary)}.popover-input[_ngcontent-%COMP%]::placeholder{color:var(--text-muted)}.popover-meta[_ngcontent-%COMP%]{padding:6px 12px 8px;font-size:10.5px;color:var(--text-secondary);border-bottom:1px solid var(--border-subtle);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.popover-meta[_ngcontent-%COMP%] .muted[_ngcontent-%COMP%]{color:var(--text-muted)}.popover-list[_ngcontent-%COMP%]{flex:1;min-height:0;padding:4px}.row-item[_ngcontent-%COMP%]{width:100%;display:flex;align-items:center;gap:10px;padding:9px 10px;border:none;border-radius:7px;background:transparent;color:inherit;cursor:pointer;font-family:inherit;text-align:left;transition:background 80ms}.row-item[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.row-item.active[_ngcontent-%COMP%]{background:var(--accent-soft);color:var(--text-primary)}.row-item.active[_ngcontent-%COMP%] app-icon[_ngcontent-%COMP%]{color:var(--accent)}.path-line[_ngcontent-%COMP%]{min-width:0}.path-line[_ngcontent-%COMP%] .path[_ngcontent-%COMP%]{font-size:12.5px;font-weight:500;color:var(--text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.meta[_ngcontent-%COMP%]{font-size:10.5px}.pill[_ngcontent-%COMP%]{font-size:10px;font-weight:600;padding:1px 7px;border-radius:999px;white-space:nowrap;flex-shrink:0}.pill.ok[_ngcontent-%COMP%]{color:var(--success);background:var(--success-soft)}.pill.warn[_ngcontent-%COMP%]{color:var(--warn);background:var(--warn-soft)}.pill.missing[_ngcontent-%COMP%]{color:var(--error);background:var(--error-soft)}.empty[_ngcontent-%COMP%]{text-align:center;color:var(--text-muted);font-size:12px;padding:18px 12px}.muted[_ngcontent-%COMP%]{color:var(--text-muted)}.mono[_ngcontent-%COMP%]{font-family:var(--font-mono)}.grow[_ngcontent-%COMP%]{flex:1;min-width:0}.row[_ngcontent-%COMP%]{display:flex;align-items:center}.col[_ngcontent-%COMP%]{display:flex;flex-direction:column}.gap-2[_ngcontent-%COMP%]{gap:2px}.gap-6[_ngcontent-%COMP%]{gap:6px}.gap-8[_ngcontent-%COMP%]{gap:8px}.scroll-y[_ngcontent-%COMP%]{overflow-y:auto;overflow-x:hidden}"],changeDetection:0})};var K=class e{toggleSidebar=N();openPalette=N();theme=v($);effective=this.theme.effective;onToggleTheme(){this.theme.toggle()}onMenuClick(){this.toggleSidebar.emit()}onPalette(){this.openPalette.emit()}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-top-bar"]],outputs:{toggleSidebar:"toggleSidebar",openPalette:"openPalette"},decls:13,vars:5,consts:[[1,"topbar"],["title","Toggle sidebar","aria-label","Toggle sidebar",1,"ghost","icon-btn",3,"click"],["name","menu",3,"size"],["aria-label","Open command palette",1,"palette-trigger",3,"click"],["name","search",3,"size"],[1,"grow"],["aria-label","Toggle theme",1,"ghost","icon-btn",3,"click","title"],[3,"name","size"]],template:function(t,i){t&1&&(a(0,"div",0)(1,"button",1),h("click",function(){return i.onMenuClick()}),p(2,"app-icon",2),r(),p(3,"app-project-picker"),a(4,"button",3),h("click",function(){return i.onPalette()}),p(5,"app-icon",4),a(6,"span"),l(7,"Search or jump to\u2026"),r(),a(8,"kbd"),l(9,"\u2318K"),r()(),p(10,"span",5),a(11,"button",6),h("click",function(){return i.onToggleTheme()}),p(12,"app-icon",7),r()()),t&2&&(o(2),f("size",16),o(3),f("size",13),o(6),f("title","Theme: "+i.effective()),o(),f("name",i.effective()==="dark"?"sun":"moon")("size",16))},dependencies:[D,q],styles:["[_nghost-%COMP%]{display:contents}.topbar[_ngcontent-%COMP%]{height:44px;flex-shrink:0;display:flex;align-items:center;gap:10px;padding:0 14px;border-bottom:1px solid var(--border-subtle);background:var(--bg-canvas)}.ghost[_ngcontent-%COMP%]{background:transparent;border:1px solid transparent;color:var(--text-secondary);cursor:pointer}.ghost[_ngcontent-%COMP%]:hover{background:var(--bg-hover);color:var(--text-primary)}.icon-btn[_ngcontent-%COMP%]{padding:6px 9px;border-radius:5px;font-size:16px}.palette-trigger[_ngcontent-%COMP%]{flex:1;max-width:380px;height:30px;padding:0 11px;background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:8px;cursor:text;color:var(--text-muted);font-size:12.5px;text-align:left;display:flex;align-items:center;gap:8px}.palette-trigger[_ngcontent-%COMP%]:hover{border-color:var(--border-strong);color:var(--text-secondary)}.palette-trigger[_ngcontent-%COMP%] app-icon[_ngcontent-%COMP%]{color:var(--text-muted)}.palette-trigger[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{flex:1}kbd[_ngcontent-%COMP%]{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:4px;padding:2px 6px}.grow[_ngcontent-%COMP%]{flex:1}"],changeDetection:0})};var Ue=(e,n)=>n.id;function Qe(e,n){if(e&1){let t=k();d(0,"button",6),R("click",function(){let s=y(t).$implicit,_=m(2);return P(_.go(s.id))}),d(1,"span",7),l(2),c(),d(3,"span",8),l(4),c()()}if(e&2){let t=n.$implicit;o(2),b(t.label),o(2),b(t.sub)}}function Ye(e,n){if(e&1){let t=k();d(0,"div",1),R("click",function(s){y(t);let _=m();return P(_.onBackdrop(s))}),d(1,"div",2)(2,"div",3)(3,"span"),l(4,"Jump to\u2026"),c(),d(5,"kbd"),l(6,"esc"),c()(),d(7,"div",4),O(8,Qe,5,2,"button",5,Ue),c()()()}if(e&2){let t=m();o(8),E(t.items)}}var Je=[{id:"dashboard",label:"Dashboard",sub:"/dashboard"},{id:"graph",label:"Graph",sub:"/graph"},{id:"specs",label:"Specs",sub:"/specs"},{id:"drift",label:"Drift queue",sub:"/drift"},{id:"workflows",label:"Workflows",sub:"/workflows"},{id:"runs",label:"Runs",sub:"/runs"},{id:"chat",label:"Chat",sub:"/chat"},{id:"sessions",label:"Sessions",sub:"/sessions"},{id:"heatmap",label:"Heatmap",sub:"/heatmap"},{id:"costs",label:"Costs",sub:"/costs"},{id:"compare",label:"Compare projects",sub:"/compare"},{id:"tips",label:"Tips",sub:"/tips"},{id:"settings",label:"Settings",sub:"/settings"}],W=class e{open=S(!1);close=N();router=v(B);items=Je;go(n){this.router.navigate(["/"+n]),this.close.emit()}onBackdrop(n){n.target===n.currentTarget&&this.close.emit()}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-command-palette"]],inputs:{open:[1,"open"]},outputs:{close:"close"},decls:1,vars:1,consts:[[1,"backdrop"],[1,"backdrop",3,"click"],[1,"palette"],[1,"palette-header"],[1,"palette-list","scroll-y"],[1,"item"],[1,"item",3,"click"],[1,"label"],[1,"sub","mono"]],template:function(t,i){t&1&&g(0,Ye,10,0,"div",0),t&2&&u(i.open()?0:-1)},styles:["[_nghost-%COMP%]{display:contents}.backdrop[_ngcontent-%COMP%]{position:fixed;inset:0;background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);display:grid;place-items:start center;padding-top:12vh;z-index:100;animation:fadeIn .1s}.palette[_ngcontent-%COMP%]{width:560px;max-width:90vw;background:var(--bg-elevated);border:1px solid var(--border-strong);border-radius:12px;box-shadow:var(--shadow-pop);overflow:hidden}.palette-header[_ngcontent-%COMP%]{display:flex;justify-content:space-between;align-items:center;padding:12px 14px;border-bottom:1px solid var(--border-subtle);font-size:13px}.palette-list[_ngcontent-%COMP%]{max-height:380px;padding:6px}.item[_ngcontent-%COMP%]{display:flex;justify-content:space-between;align-items:center;width:100%;padding:8px 10px;background:transparent;border:none;border-radius:7px;cursor:pointer;color:var(--text-primary);font-family:inherit;font-size:13px;text-align:left}.item[_ngcontent-%COMP%]:hover{background:var(--bg-hover)}.label[_ngcontent-%COMP%]{flex:1}.sub[_ngcontent-%COMP%]{font-size:10.5px;color:var(--text-muted)}kbd[_ngcontent-%COMP%]{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:4px;padding:2px 6px}"],changeDetection:0})};var U=class e{_theme=v($);_destroyRef=v(ee);_router=v(B);sidebarCollapsed=T(typeof window<"u"&&window.innerWidth<1100);paletteOpen=T(!1);gChord={armed:!1,t:0};onGlobalKey(n){let t=n.metaKey||n.ctrlKey;if(t&&n.key.toLowerCase()==="k"){n.preventDefault(),this.paletteOpen.update(i=>!i);return}if(n.key==="Escape"){this.paletteOpen.set(!1);return}if(!t&&n.key.toLowerCase()==="g"&&!this.gChord.armed){let i=n.target;if(i&&/input|textarea/i.test(i.tagName))return;this.gChord.armed=!0,this.gChord.t=Date.now(),setTimeout(()=>{this.gChord.armed=!1},600);return}if(this.gChord.armed&&!t){let i=n.key.toLowerCase();i==="d"?this._router.navigate(["/dashboard"]):i==="g"?this._router.navigate(["/graph"]):i==="s"&&this._router.navigate(["/specs"]),this.gChord.armed=!1}}toggleSidebar(){this.sidebarCollapsed.update(n=>!n)}onOpenPalette(){this.paletteOpen.set(!0)}onClosePalette(){this.paletteOpen.set(!1)}static \u0275fac=function(t){return new(t||e)};static \u0275cmp=x({type:e,selectors:[["app-root"]],hostBindings:function(t,i){t&1&&h("keydown",function(_){return i.onGlobalKey(_)},ie)},decls:8,vars:2,consts:[[1,"shell"],[3,"collapsed"],[1,"main"],[3,"toggleSidebar","openPalette"],[1,"page-frame"],[3,"close","open"]],template:function(t,i){t&1&&(a(0,"div",0),p(1,"app-sidebar",1),a(2,"div",2),p(3,"app-status-strip"),a(4,"app-top-bar",3),h("toggleSidebar",function(){return i.toggleSidebar()})("openPalette",function(){return i.onOpenPalette()}),r(),a(5,"div",4),p(6,"router-outlet"),r()(),a(7,"app-command-palette",5),h("close",function(){return i.onClosePalette()}),r()()),t&2&&(o(),f("collapsed",i.sidebarCollapsed()),o(6),f("open",i.paletteOpen()))},dependencies:[se,H,G,K,W],styles:["[_nghost-%COMP%]{display:block;height:100%}.shell[_ngcontent-%COMP%]{display:flex;height:100vh;background:var(--bg-canvas);color:var(--text-primary);font-family:var(--font-ui);font-size:var(--fs-base)}.main[_ngcontent-%COMP%]{flex:1;display:flex;flex-direction:column;min-width:0;overflow:hidden}.page-frame[_ngcontent-%COMP%]{flex:1;min-height:0;display:flex;flex-direction:column;background:var(--bg-canvas)}"],changeDetection:0})};le(U,ue).catch(e=>console.error(e));
@@ -0,0 +1 @@
1
+ @charset "UTF-8";@layer properties;@layer theme,base,components,utilities;@layer theme{:root,:host{--font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing: .25rem;--ease-out: cubic-bezier(0, 0, .2, 1);--ease-in-out: cubic-bezier(.4, 0, .2, 1);--default-transition-duration: .15s;--default-transition-timing-function: cubic-bezier(.4, 0, .2, 1);--default-font-family: var(--font-sans);--default-mono-font-family: var(--font-mono)}}@layer base{*,:after,:before,::backdrop,::file-selector-button{box-sizing:border-box;margin:0;padding:0;border:0 solid}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;tab-size:4;font-family:var(--default-font-family, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings, normal);font-variation-settings:var(--default-font-variation-settings, normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings, normal);font-variation-settings:var(--default-mono-font-variation-settings, normal);font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea,::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;border-radius:0;background-color:transparent;opacity:1}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px){::placeholder{color:currentcolor}@supports (color: color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]),::file-selector-button{appearance:button}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer utilities{.collapse{visibility:collapse}.visible{visibility:visible}.fixed{position:fixed}.relative{position:relative}.static{position:static}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.table{display:table}.flex-shrink{flex-shrink:1}.grow{flex-grow:1}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.flex-wrap{flex-wrap:wrap}.gap-2{gap:calc(var(--spacing) * 2)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-7{gap:calc(var(--spacing) * 7)}.gap-8{gap:calc(var(--spacing) * 8)}.gap-10{gap:calc(var(--spacing) * 10)}.gap-12{gap:calc(var(--spacing) * 12)}.gap-16{gap:calc(var(--spacing) * 16)}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.border{border-style:var(--tw-border-style);border-width:1px}.capitalize{text-transform:capitalize}.ring{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.invert{--tw-invert: invert(100%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function));transition-duration:var(--tw-duration, var(--default-transition-duration))}.ease-in-out{--tw-ease: var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease: var(--ease-out);transition-timing-function:var(--ease-out)}}:root{color-scheme:dark;--bg-canvas: #0E1014;--bg-canvas-2: #0B0D11;--bg-panel: #161A21;--bg-panel-2: #1A1F28;--bg-elevated: #20262F;--bg-hover: rgba(255,255,255,.04);--bg-active: rgba(255,255,255,.07);--border-subtle: rgba(255,255,255,.07);--border-strong: rgba(255,255,255,.12);--border-focus: #3B82F6;--text-primary: #E8EBF0;--text-secondary: #9AA3B2;--text-muted: #5C6573;--text-faint: #424B59;--accent: #3B82F6;--accent-strong: #2563EB;--accent-soft: rgba(59,130,246,.14);--accent-line: rgba(59,130,246,.35);--node-code: #A586F5;--node-spec: #5B93F2;--node-test: #46C26B;--node-route: #29D2BE;--node-code-soft: rgba(165,134,245,.14);--node-spec-soft: rgba(91,147,242,.14);--node-test-soft: rgba(70,194,107,.14);--node-route-soft: rgba(41,210,190,.14);--node-text: #ffffff;--dot-grid: rgba(255,255,255,.045);--success: #46C26B;--success-soft: rgba(70,194,107,.13);--warn: #E5A50A;--warn-soft: rgba(229,165,10,.14);--error: #F2555A;--error-soft: rgba(242,85,90,.14);--info: #58A6FF;--info-soft: rgba(88,166,255,.13);--font-ui: "Geist", system-ui, -apple-system, sans-serif;--font-mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace;--fs-title: 22px;--fs-base: 13px;--fs-sm: 12px;--fs-xs: 11px;--fs-big: 28px;--r-sm: 5px;--r-md: 8px;--r-lg: 12px;--r-pill: 999px;--shadow-pop: 0 12px 32px -8px rgba(0,0,0,.6), 0 2px 8px rgba(0,0,0,.4);--shadow-panel: 0 1px 0 rgba(255,255,255,.02) inset;--sidebar-w: 232px;--sidebar-w-collapsed: 56px;--status-h: 30px}[data-theme=light]{color-scheme:light;--bg-canvas: #F4F6F8;--bg-canvas-2: #E9ECF1;--bg-panel: #FFFFFF;--bg-panel-2: #F8FAFC;--bg-elevated: #FFFFFF;--bg-hover: rgba(15,23,42,.045);--bg-active: rgba(15,23,42,.07);--border-subtle: rgba(15,23,42,.1);--border-strong: rgba(15,23,42,.18);--border-focus: #2563EB;--text-primary: #161B22;--text-secondary: #4A5566;--text-muted: #7B8696;--text-faint: #A9B2C0;--accent: #2563EB;--accent-strong: #2563EB;--accent-soft: rgba(37,99,235,.1);--accent-line: rgba(37,99,235,.3);--node-code: #7C56E0;--node-spec: #2F6FE0;--node-test: #1E9E4C;--node-route: #0E9C8E;--node-code-soft: rgba(124,86,224,.12);--node-spec-soft: rgba(47,111,224,.12);--node-test-soft: rgba(30,158,76,.12);--node-route-soft: rgba(14,156,142,.12);--node-text: #1A2230;--dot-grid: rgba(15,23,42,.07);--success: #1E9E4C;--success-soft: rgba(30,158,76,.12);--warn: #B27500;--warn-soft: rgba(178,117,0,.13);--error: #DC4A4F;--error-soft: rgba(220,74,79,.12);--info: #2563EB;--info-soft: rgba(37,99,235,.11);--shadow-pop: 0 12px 32px -10px rgba(15,23,42,.22), 0 2px 8px rgba(15,23,42,.1);--shadow-panel: 0 1px 0 rgba(15,23,42,.02) inset}*{box-sizing:border-box}html,body{margin:0;padding:0;height:100%;background:var(--bg-canvas);color:var(--text-primary);font-family:var(--font-ui);font-size:var(--fs-base);line-height:1.45;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;font-feature-settings:"cv01","cv03","ss03";overflow:hidden}#root{height:100%}::selection{background:var(--accent-soft)}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#ffffff14;border-radius:999px;border:2px solid transparent;background-clip:content-box}::-webkit-scrollbar-thumb:hover{background:#ffffff29;background-clip:content-box}.mono{font-family:var(--font-mono);font-feature-settings:"zero"}.tnum{font-variant-numeric:tabular-nums}.btn{font-family:var(--font-ui);font-size:var(--fs-base);font-weight:500;border:1px solid transparent;border-radius:var(--r-sm);padding:6px 12px;display:inline-flex;align-items:center;gap:7px;cursor:pointer;white-space:nowrap;transition:background .1s ease,border-color .1s ease,color .1s ease;-webkit-user-select:none;user-select:none}.btn svg{width:14px;height:14px;flex-shrink:0}.btn-primary{background:var(--accent-strong);color:#fff}.btn-primary:hover{background:var(--accent)}.btn-secondary{background:var(--bg-elevated);color:var(--text-primary);border-color:var(--border-subtle)}.btn-secondary:hover{background:#283039;border-color:var(--border-strong)}.btn-ghost{background:transparent;color:var(--text-secondary)}.btn-ghost:hover{background:var(--bg-hover);color:var(--text-primary)}.btn-destructive{background:var(--error-soft);color:var(--error);border-color:#f2555a4d}.btn-destructive:hover{background:#f2555a38}.btn-sm{padding:4px 9px;font-size:var(--fs-sm)}.btn-xs{padding:2px 7px;font-size:var(--fs-xs);border-radius:4px}.btn:disabled{opacity:.4;cursor:not-allowed}.pill{display:inline-flex;align-items:center;gap:5px;font-size:var(--fs-xs);font-weight:600;padding:2px 8px;border-radius:var(--r-pill);letter-spacing:.01em;white-space:nowrap;line-height:1.5}.pill svg{width:11px;height:11px}.pill-dot{width:6px;height:6px;border-radius:50%}.card{background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:var(--r-lg)}.card-pad{padding:14px}.input{background:var(--bg-canvas);border:1px solid var(--border-subtle);border-radius:var(--r-sm);color:var(--text-primary);font-family:var(--font-ui);font-size:var(--fs-base);padding:6px 10px;outline:none;transition:border-color .1s ease,box-shadow .1s ease}.input:focus{border-color:var(--border-focus);box-shadow:0 0 0 3px var(--accent-soft)}.input::placeholder{color:var(--text-muted)}.eyebrow{font-size:var(--fs-xs);font-weight:600;text-transform:uppercase;letter-spacing:.07em;color:var(--text-muted)}:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.row{display:flex;align-items:center}.col{display:flex;flex-direction:column}.gap-2{gap:2px}.gap-4{gap:4px}.gap-6{gap:6px}.gap-8{gap:8px}.gap-10{gap:10px}.gap-12{gap:12px}.gap-16{gap:16px}.grow{flex:1}.muted{color:var(--text-muted)}.secondary{color:var(--text-secondary)}.tabular{font-variant-numeric:tabular-nums}.scroll-y{overflow-y:auto;overflow-x:hidden}@keyframes pulsePill{0%{box-shadow:0 0 0 0 currentColor}to{box-shadow:0 0 0 8px transparent}}@keyframes slideInRight{0%{opacity:0;transform:translate(14px)}to{opacity:1;transform:translate(0)}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes runningDash{to{stroke-dashoffset:-16}}@keyframes spin{to{transform:rotate(360deg)}}@keyframes skeleton{0%{opacity:.5}50%{opacity:.9}to{opacity:.5}}.skel{background:var(--bg-elevated);border-radius:5px;animation:skeleton 1.4s ease-in-out infinite}@media(prefers-reduced-motion:reduce){*{animation-duration:.001ms!important;transition-duration:.001ms!important}}@property --tw-rotate-x{syntax: "*"; inherits: false;}@property --tw-rotate-y{syntax: "*"; inherits: false;}@property --tw-rotate-z{syntax: "*"; inherits: false;}@property --tw-skew-x{syntax: "*"; inherits: false;}@property --tw-skew-y{syntax: "*"; inherits: false;}@property --tw-border-style{syntax: "*"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: "*"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: "*"; inherits: false;}@property --tw-shadow-alpha{syntax: "<percentage>"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: "*"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: "*"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: "<percentage>"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: "*"; inherits: false;}@property --tw-ring-shadow{syntax: "*"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: "*"; inherits: false;}@property --tw-inset-ring-shadow{syntax: "*"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: "*"; inherits: false;}@property --tw-ring-offset-width{syntax: "<length>"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: "*"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: "*"; inherits: false; initial-value: 0 0 #0000;}@property --tw-blur{syntax: "*"; inherits: false;}@property --tw-brightness{syntax: "*"; inherits: false;}@property --tw-contrast{syntax: "*"; inherits: false;}@property --tw-grayscale{syntax: "*"; inherits: false;}@property --tw-hue-rotate{syntax: "*"; inherits: false;}@property --tw-invert{syntax: "*"; inherits: false;}@property --tw-opacity{syntax: "*"; inherits: false;}@property --tw-saturate{syntax: "*"; inherits: false;}@property --tw-sepia{syntax: "*"; inherits: false;}@property --tw-drop-shadow{syntax: "*"; inherits: false;}@property --tw-drop-shadow-color{syntax: "*"; inherits: false;}@property --tw-drop-shadow-alpha{syntax: "<percentage>"; inherits: false; initial-value: 100%;}@property --tw-drop-shadow-size{syntax: "*"; inherits: false;}@property --tw-ease{syntax: "*"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x: initial;--tw-rotate-y: initial;--tw-rotate-z: initial;--tw-skew-x: initial;--tw-skew-y: initial;--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-blur: initial;--tw-brightness: initial;--tw-contrast: initial;--tw-grayscale: initial;--tw-hue-rotate: initial;--tw-invert: initial;--tw-opacity: initial;--tw-saturate: initial;--tw-sepia: initial;--tw-drop-shadow: initial;--tw-drop-shadow-color: initial;--tw-drop-shadow-alpha: 100%;--tw-drop-shadow-size: initial;--tw-ease: initial}}}
@@ -0,0 +1,247 @@
1
+ name: claude-design-implement
2
+ description: Import a Claude Design file (snapshot + tokens + source record), draft the spec, gate at review, write the spec — ready to hand off to /ss-implement.
3
+ tags: [spec, ui, claude-design, default]
4
+ requires: [specship, git]
5
+
6
+ # Worktree isolation: the spec draft and snapshot live in the user's
7
+ # working tree (not the worktree) so the artifacts survive the run,
8
+ # but the worktree gives the spec author a clean diff to review and
9
+ # means a rejected run leaves no half-written specs/<slug>.md.
10
+ worktree:
11
+ enabled: true
12
+
13
+ inputs:
14
+ - name: CONNECTOR_URL
15
+ description: The full Claude Design URL (https://claude.ai/design/p/<id>/?file=<name>.html)
16
+ required: true
17
+ - name: FILE_LABEL
18
+ description: Human label for the imported file (e.g. "Data Flow")
19
+ required: true
20
+ - name: SLUG
21
+ description: Kebab-case directory name under specs/ (e.g. "data-flow")
22
+ required: true
23
+ - name: OWNER
24
+ description: Spec owner — used in frontmatter when set
25
+ required: false
26
+ - name: PRIORITY
27
+ description: high / medium / low — used in frontmatter when set
28
+ required: false
29
+
30
+ systemPromptAppend: |
31
+ You are implementing a Claude Design import for SpecShip.
32
+
33
+ The fidelity principle: never paraphrase or summarise design content
34
+ when capturing it. The snapshot HTML and tokens.css are the
35
+ zero-loss reference layer; the spec captures contract only (behaviour,
36
+ accessibility, responsive, interaction states, data shape).
37
+
38
+ Use whichever Claude Design tooling is available (an MCP connector,
39
+ the figma-implement-design skill, or a direct fetch) to pull the
40
+ source file. Save it byte-for-byte to specs/$INPUT.SLUG/snapshot.html.
41
+ Never edit the snapshot during this workflow.
42
+
43
+ nodes:
44
+ - id: snapshot
45
+ kind: prompt
46
+ output_type: snapshot_summary
47
+ allowed_tools:
48
+ - Read
49
+ - Write
50
+ - Bash
51
+ - mcp__specship__specship_explore
52
+ - mcp__specship__specship_search
53
+ prompt: |
54
+ Source URL: $INPUT.CONNECTOR_URL
55
+ File label: $INPUT.FILE_LABEL
56
+ Slug: $INPUT.SLUG
57
+
58
+ Goal: snapshot the Claude Design source into specs/$INPUT.SLUG/
59
+ so the rest of the workflow has a zero-loss reference layer.
60
+
61
+ 1. Create the directory `specs/$INPUT.SLUG/` if it doesn't exist.
62
+
63
+ 2. Fetch the design content from $INPUT.CONNECTOR_URL. Try in
64
+ this order:
65
+ a. Any Claude Design MCP connector tool available in this
66
+ session (look for `mcp__*design*` or similar).
67
+ b. The `figma-implement-design` or `figma-use` skill if
68
+ loaded — Claude Design and Figma share a similar handoff
69
+ shape.
70
+ c. A direct `curl` of the URL, as a last resort.
71
+
72
+ Save the FULL rendered HTML byte-for-byte to
73
+ `specs/$INPUT.SLUG/snapshot.html`. Do NOT filter, summarise, or
74
+ re-format. If the design has linked CSS / asset files, save
75
+ them alongside.
76
+
77
+ 3. Write `specs/$INPUT.SLUG/source.md` with the import audit
78
+ record:
79
+
80
+ ```markdown
81
+ # $INPUT.FILE_LABEL — Claude Design import
82
+
83
+ **Imported:** <today's date in YYYY-MM-DD>
84
+ **Connector URL:** $INPUT.CONNECTOR_URL
85
+ **Project ID:** <extracted from the URL — the segment after /p/>
86
+ **File:** $INPUT.FILE_LABEL
87
+
88
+ **Snapshot:** snapshot.html (byte-for-byte capture)
89
+ **Tokens:** tokens.css (extracted CSS custom properties)
90
+
91
+ **Original prompt:**
92
+ > Import this Claude Design project using the Claude Design connector:
93
+ > $INPUT.CONNECTOR_URL
94
+ > Implement: $INPUT.FILE_LABEL
95
+ ```
96
+
97
+ 4. Extract CSS custom properties + literal token-like values
98
+ (colors, spacing, font sizes, radii, transitions) from the
99
+ snapshot to `specs/$INPUT.SLUG/tokens.css`. Use
100
+ `specship_explore` first to find the project's existing token
101
+ system — if a value in the snapshot matches an existing
102
+ project token, map it by name instead of duplicating.
103
+
104
+ Output: a ≤250-word summary covering:
105
+ - Snapshot structure (top-level layout, key components).
106
+ - Token mapping (which match existing project tokens, which are
107
+ new and added to tokens.css).
108
+ - Any visible interaction or state cues in the CSS (`:hover`,
109
+ `:focus`, `:disabled`, `[aria-*]` selectors) the spec
110
+ author should be aware of.
111
+
112
+ - id: draft_spec
113
+ kind: prompt
114
+ depends_on: [snapshot]
115
+ output_type: spec_markdown
116
+ allowed_tools:
117
+ - Read
118
+ - mcp__specship__specship_explore
119
+ - mcp__specship__specship_search
120
+ - mcp__specship__specship_node
121
+ - mcp__specship__specship_spec
122
+ prompt: |
123
+ Use the spec-author skill (~/.claude/skills/spec-author/SKILL.md
124
+ and its references/) to draft a SpecShip-compatible spec for the
125
+ Claude Design import. Inputs available on disk:
126
+
127
+ - specs/$INPUT.SLUG/snapshot.html (visual + structural source)
128
+ - specs/$INPUT.SLUG/tokens.css (design tokens)
129
+ - specs/$INPUT.SLUG/source.md (audit record)
130
+
131
+ Spec scope: $INPUT.FILE_LABEL component(s).
132
+ Optional inputs: owner=$INPUT.OWNER priority=$INPUT.PRIORITY
133
+
134
+ Cover, as separate REQs:
135
+ - Behavioural contract (what the component renders, given what data).
136
+ - Each visible state (default, hover, focused, pressed, disabled,
137
+ loading, error, empty) — derive from the CSS, gap-fill the rest.
138
+ - Accessibility (keyboard nav, ARIA roles, focus order, contrast,
139
+ screen-reader behaviour).
140
+ - Responsive behaviour (breakpoints by name, not pixels).
141
+ - Data shape + failure-mode contracts.
142
+ - Performance contract (initial render budget, interaction
143
+ latency, if applicable).
144
+
145
+ DO NOT put exact hex colors, pixel values, font names, or animation
146
+ durations in the spec. Reference design tokens by name
147
+ (`MUST use the --error color token`). The values themselves live
148
+ in tokens.css.
149
+
150
+ Embed the import-source record in the spec's frontmatter so the
151
+ spec carries its provenance:
152
+
153
+ ```yaml
154
+ ---
155
+ id: <SLUG-DOC>
156
+ title: <FILE_LABEL>
157
+ owner: <OWNER or "[needs review]">
158
+ priority: <PRIORITY or "[needs review]">
159
+ source: specs/<SLUG>/source.md
160
+ snapshot: specs/<SLUG>/snapshot.html
161
+ tokens: specs/<SLUG>/tokens.css
162
+ ---
163
+ ```
164
+
165
+ Output: the full Markdown body of the proposed spec
166
+ (with frontmatter, embedded `<!-- id: -->` markers, RFC 2119
167
+ keywords, acceptance bullets with .A1/.A2 IDs). DO NOT write
168
+ it to disk yet — the next node is a review gate.
169
+
170
+ - id: gap_review
171
+ kind: approval
172
+ depends_on: [draft_spec]
173
+ message: |
174
+ Spec draft ready for $INPUT.FILE_LABEL.
175
+
176
+ Walk the [needs review] markers and gap-fill questions, then
177
+ approve to write the file. Reject with feedback to revise.
178
+
179
+ ─────── DRAFT ───────
180
+ $draft_spec.output
181
+ capture_response: true
182
+ on_reject:
183
+ prompt: |
184
+ The draft was rejected with this feedback. Revise the spec
185
+ per the feedback; keep ALL existing REQ IDs stable so any
186
+ downstream tracking survives the rewrite.
187
+
188
+ Feedback:
189
+ $gap_review.output
190
+
191
+ Current draft:
192
+ $draft_spec.output
193
+
194
+ Output the revised draft.
195
+ max_attempts: 3
196
+
197
+ - id: write_spec
198
+ kind: prompt
199
+ depends_on: [gap_review]
200
+ output_type: file_path
201
+ allowed_tools:
202
+ - Write
203
+ - Read
204
+ - Bash
205
+ prompt: |
206
+ Write the approved spec to `specs/$INPUT.SLUG.md` using the
207
+ Write tool.
208
+
209
+ If `specs/$INPUT.SLUG.md` already exists (re-importing an
210
+ iteration), APPEND the new requirements to it instead of
211
+ overwriting; preserve all existing REQ IDs. Tell the user
212
+ explicitly what you did.
213
+
214
+ Approved draft:
215
+ $gap_review.output
216
+
217
+ Then run:
218
+ specship sync
219
+
220
+ Output: the relative path of the file written + the first REQ
221
+ ID (e.g. "REQ-DATA-FLOW-001") so the next step can hand it to
222
+ /ss-implement.
223
+
224
+ - id: handoff
225
+ kind: prompt
226
+ depends_on: [write_spec]
227
+ output_type: handoff_message
228
+ allowed_tools:
229
+ - Read
230
+ prompt: |
231
+ The spec is now indexed. Output a short hand-off message for the
232
+ user with EXACTLY these elements:
233
+
234
+ 1. The path of the spec file: `specs/$INPUT.SLUG.md`.
235
+ 2. The full list of REQ IDs the spec defines, one per line.
236
+ 3. The reference files the implementation phase should read:
237
+ - specs/$INPUT.SLUG/snapshot.html
238
+ - specs/$INPUT.SLUG/tokens.css
239
+ - specs/$INPUT.SLUG/source.md
240
+ 4. The exact next command:
241
+ /ss-implement <first REQ ID>
242
+ 5. A one-line reminder that the implementation step should
243
+ load the snapshot for visual fidelity — the spec covers
244
+ contract only.
245
+
246
+ Keep the message ≤200 words. The user is about to switch from
247
+ this workflow to the implement workflow; this is the bridge.
@@ -0,0 +1,214 @@
1
+ name: spec-author
2
+ description: Author a new spec. Draft → gap-fill review → quality review → final approval → write file.
3
+ tags: [spec, default]
4
+ requires: [specship, git]
5
+
6
+ # Worktree isolation isn't strictly needed for spec authoring (no code
7
+ # changes) — but enabling it keeps the artifact directory under the same
8
+ # umbrella the other spec workflows use, and a future expansion that adds
9
+ # example-code touches stays safe.
10
+ worktree:
11
+ enabled: true
12
+
13
+ inputs:
14
+ - name: DESCRIPTION
15
+ description: One-line description of the feature you want to spec
16
+ required: true
17
+ - name: PARENT_DOC
18
+ description: Optional spec ID of an existing doc to attach the new requirements under
19
+ required: false
20
+ - name: OWNER
21
+ description: Owner team or person (e.g. "security", "payments-team")
22
+ required: false
23
+ - name: PRIORITY
24
+ description: high / medium / low
25
+ required: false
26
+
27
+ systemPromptAppend: |
28
+ You are authoring a SpecShip-compatible Markdown spec. Use the
29
+ spec-author skill loop and references throughout this workflow.
30
+ The output of every node should be markdown that is ready for the
31
+ next stage — do NOT write the file until the `write_file` node.
32
+
33
+ nodes:
34
+ - id: ground
35
+ kind: prompt
36
+ output_type: code_grounding
37
+ allowed_tools:
38
+ - mcp__specship__specship_explore
39
+ - mcp__specship__specship_search
40
+ - mcp__specship__specship_files
41
+ - Read
42
+ prompt: |
43
+ Feature: $INPUT.DESCRIPTION
44
+
45
+ Walk the codebase to find where this feature would live:
46
+
47
+ 1. Use specship_explore on terms drawn from the description to
48
+ surface relevant existing symbols.
49
+ 2. Note any existing conventions, similar features, or shared
50
+ primitives the new spec should align with.
51
+ 3. List candidate file paths + qualified symbol names that the
52
+ new implementation might touch — these become the `implementations:`
53
+ block of the spec.
54
+
55
+ If this is greenfield (no relevant existing code), say so explicitly
56
+ and propose a target directory under src/ where the implementation
57
+ will live.
58
+
59
+ Output: a ≤300-word grounding report — paths, conventions, and
60
+ candidate symbols. Do NOT write the spec yet.
61
+
62
+ - id: draft
63
+ kind: prompt
64
+ depends_on: [ground]
65
+ output_type: spec_draft
66
+ allowed_tools:
67
+ - mcp__specship__specship_spec
68
+ - mcp__specship__specship_explore
69
+ - mcp__specship__specship_node
70
+ - Read
71
+ prompt: |
72
+ Feature: $INPUT.DESCRIPTION
73
+ Optional parent doc: $INPUT.PARENT_DOC
74
+ Optional owner: $INPUT.OWNER
75
+ Optional priority: $INPUT.PRIORITY
76
+
77
+ Code grounding:
78
+ $ground.output
79
+
80
+ Produce a complete first-draft Markdown spec following the spec-author
81
+ skill's `references/format.md`:
82
+
83
+ - YAML frontmatter with id/title/owner/priority (use the inputs if
84
+ provided; mark as `[needs review]` if not).
85
+ - Embedded `<!-- id: -->` markers above every heading.
86
+ - RFC 2119 keyword (MUST / SHOULD / MAY) in each requirement title.
87
+ - One concern per requirement.
88
+ - `## Acceptance` section with bulleted criteria, each carrying its
89
+ own `.A<N>` ID. Cover both happy path and failure path.
90
+ - Optional `implementations:` block, populated from the grounding
91
+ report (or empty for greenfield).
92
+ - Wherever the description doesn't tell you something, insert a
93
+ `[needs user confirmation]` marker — DO NOT invent.
94
+
95
+ Output: the full spec markdown, ready for the gap-fill review.
96
+
97
+ - id: gap_review
98
+ kind: approval
99
+ depends_on: [draft]
100
+ message: |
101
+ Draft is ready. The gap-fill questions below identify areas the
102
+ description didn't cover. Approve with answers (e.g. "owner: security,
103
+ TTL: 1h, on non-existent email: 200 OK"), or reject with feedback to
104
+ revise.
105
+
106
+ Draft:
107
+ $draft.output
108
+
109
+ Gap-fill questions for THIS draft — walk references/gap-questions.md
110
+ and surface only the unanswered ones (max 5):
111
+ [the agent fills these in based on the draft above]
112
+ capture_response: true
113
+ on_reject:
114
+ prompt: |
115
+ The draft was rejected with this feedback. Revise the draft to
116
+ address it. Keep all existing IDs stable so any pre-existing links
117
+ survive.
118
+
119
+ Feedback:
120
+ $gap_review.output
121
+ max_attempts: 3
122
+
123
+ - id: incorporate
124
+ kind: prompt
125
+ depends_on: [gap_review]
126
+ output_type: spec_draft
127
+ allowed_tools:
128
+ - Read
129
+ prompt: |
130
+ Apply the gap-fill answers to the draft. Replace `[needs user
131
+ confirmation]` markers with the user's answers where given; leave
132
+ others as `[needs review]` if they explicitly skipped.
133
+
134
+ Draft:
135
+ $draft.output
136
+
137
+ Answers:
138
+ $gap_review.output
139
+
140
+ Output: the updated spec markdown.
141
+
142
+ - id: quality_review
143
+ kind: prompt
144
+ depends_on: [incorporate]
145
+ output_type: review_findings
146
+ allowed_tools:
147
+ - mcp__specship__specship_explore
148
+ - mcp__specship__specship_node
149
+ - mcp__specship__specship_search
150
+ - Read
151
+ prompt: |
152
+ Run the spec-author skill's `references/review-checklist.md` against
153
+ this draft and produce a structured findings list.
154
+
155
+ Updated draft:
156
+ $incorporate.output
157
+
158
+ Group findings into STRUCTURAL (blocks the file write), QUALITY (block
159
+ on critical, warn on minor), HYGIENE (warn only). For each, give:
160
+ line number, what's wrong, suggested fix. Don't be polite — sharp
161
+ signal is more useful than soft language.
162
+
163
+ If any STRUCTURAL findings exist, propose a corrected version of the
164
+ affected sections inline.
165
+
166
+ - id: finalize
167
+ kind: approval
168
+ depends_on: [quality_review]
169
+ message: |
170
+ Quality review complete. Approve to write the spec file, or reject to
171
+ revise further.
172
+
173
+ Review:
174
+ $quality_review.output
175
+
176
+ Final draft:
177
+ $incorporate.output
178
+ capture_response: true
179
+ on_reject:
180
+ prompt: |
181
+ Final approval was rejected. Revise the draft per the feedback,
182
+ re-run the quality review pass, and produce a new draft.
183
+
184
+ Feedback:
185
+ $finalize.output
186
+
187
+ Current draft:
188
+ $incorporate.output
189
+ max_attempts: 2
190
+
191
+ - id: write_file
192
+ kind: prompt
193
+ depends_on: [finalize]
194
+ output_type: file_path
195
+ allowed_tools:
196
+ - Write
197
+ - Read
198
+ - Bash
199
+ prompt: |
200
+ Write the approved spec to disk.
201
+
202
+ Final draft:
203
+ $incorporate.output
204
+
205
+ Use the `Write` tool to create `specs/<slug>.md` at the project root,
206
+ where `<slug>` is derived from the feature name (kebab-case, no date
207
+ prefix). If a file with that name already exists, APPEND the new
208
+ requirements to it (preserving any pre-existing content) instead of
209
+ overwriting; the user will resolve the merge in review.
210
+
211
+ After writing:
212
+ - Run `specship sync` to index the new spec.
213
+ - Output the relative path of the file written + a one-line note
214
+ about what to do next (typically: `/ss-implement <REQ-ID>`).
@@ -1 +1 @@
1
- {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/workflows/executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,EACL,kBAAkB,EAClB,OAAO,EAOR,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,WAAW,EACX,iBAAiB,EAGlB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EACL,UAAU,EAIX,MAAM,uBAAuB,CAAC;AAQ/B,MAAM,WAAW,cAAc;IAC7B,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,uBAAuB;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,WAAW,CAAC;IACjB,sCAAsC;IACtC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC3C,4CAA4C;IAC5C,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CAClC;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,OAAO,CAAmC;gBAEtC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,gBAAgB;IAgB3D,KAAK,CACT,QAAQ,EAAE,kBAAkB,EAC5B,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,aAAa,CAAC;IA8EzB;;OAEG;IACG,MAAM,CACV,QAAQ,EAAE,kBAAkB,EAC5B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,GAClC,OAAO,CAAC,aAAa,CAAC;IAqCzB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,MAA4B,GAAG,IAAI;IA8BjE;;;;OAIG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAuC9C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;YA6B9B,cAAc;YA0Id,YAAY;IA2B1B,OAAO,CAAC,YAAY;IAuBpB;;;;;;;;;OASG;IACH,OAAO,CAAC,eAAe;IAiDvB,OAAO,CAAC,uBAAuB;YAajB,QAAQ;YA4CR,aAAa;IAyB3B,OAAO,CAAC,KAAK;CA0Bd;AAMD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,CA6BnD"}
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/workflows/executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,EACL,kBAAkB,EAClB,OAAO,EAOR,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,WAAW,EACX,iBAAiB,EAGlB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EACL,UAAU,EAIX,MAAM,uBAAuB,CAAC;AAQ/B,MAAM,WAAW,cAAc;IAC7B,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,uBAAuB;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,WAAW,CAAC;IACjB,sCAAsC;IACtC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC3C,4CAA4C;IAC5C,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CAClC;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,OAAO,CAAmC;gBAEtC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,gBAAgB;IAgB3D,KAAK,CACT,QAAQ,EAAE,kBAAkB,EAC5B,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,aAAa,CAAC;IA8EzB;;OAEG;IACG,MAAM,CACV,QAAQ,EAAE,kBAAkB,EAC5B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,GAClC,OAAO,CAAC,aAAa,CAAC;IAoCzB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,MAA4B,GAAG,IAAI;IA8BjE;;;;OAIG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAuC9C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;YA6B9B,cAAc;YA0Id,YAAY;IA2B1B,OAAO,CAAC,YAAY;IAuBpB;;;;;;;;;OASG;IACH,OAAO,CAAC,eAAe;IAiDvB,OAAO,CAAC,uBAAuB;YAajB,QAAQ;YA4CR,aAAa;IAyB3B,OAAO,CAAC,KAAK;CA0Bd;AAMD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,CA6BnD"}
@@ -55,6 +55,7 @@ const fs = __importStar(require("fs"));
55
55
  const path = __importStar(require("path"));
56
56
  const os = __importStar(require("os"));
57
57
  const crypto_1 = require("crypto");
58
+ const directory_1 = require("../directory");
58
59
  const condition_evaluator_1 = require("./condition-evaluator");
59
60
  const prompt_1 = require("./runners/prompt");
60
61
  const bash_1 = require("./runners/bash");
@@ -124,7 +125,7 @@ class WorkflowExecutor {
124
125
  }
125
126
  }
126
127
  // Set up artifacts + logs dirs.
127
- const specshipRoot = path.join(opts.projectRoot, '.specship');
128
+ const specshipRoot = (0, directory_1.getSpecShipDir)(opts.projectRoot);
128
129
  const artifactsDir = path.join(specshipRoot, 'artifacts', 'runs', runId, 'nodes');
129
130
  const logsDir = path.join(specshipRoot, 'logs');
130
131
  try {
@@ -168,8 +169,8 @@ class WorkflowExecutor {
168
169
  ? this.specQueries.getIsolationEnvById(existing.isolationEnvId)?.workingPath ??
169
170
  opts.projectRoot
170
171
  : opts.projectRoot;
171
- const artifactsDir = path.join(opts.projectRoot, '.specship', 'artifacts', 'runs', runId, 'nodes');
172
- const logsDir = path.join(opts.projectRoot, '.specship', 'logs');
172
+ const artifactsDir = path.join((0, directory_1.getSpecShipDir)(opts.projectRoot), 'artifacts', 'runs', runId, 'nodes');
173
+ const logsDir = path.join((0, directory_1.getSpecShipDir)(opts.projectRoot), 'logs');
173
174
  const now = Date.now();
174
175
  const refreshed = {
175
176
  ...existing,