@specific.dev/cli 0.1.51 → 0.1.52

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 (32) hide show
  1. package/dist/admin/404/index.html +1 -1
  2. package/dist/admin/404.html +1 -1
  3. package/dist/admin/__next.__PAGE__.txt +1 -1
  4. package/dist/admin/__next._full.txt +1 -1
  5. package/dist/admin/__next._head.txt +1 -1
  6. package/dist/admin/__next._index.txt +1 -1
  7. package/dist/admin/__next._tree.txt +1 -1
  8. package/dist/admin/_not-found/__next._full.txt +1 -1
  9. package/dist/admin/_not-found/__next._head.txt +1 -1
  10. package/dist/admin/_not-found/__next._index.txt +1 -1
  11. package/dist/admin/_not-found/__next._not-found.__PAGE__.txt +1 -1
  12. package/dist/admin/_not-found/__next._not-found.txt +1 -1
  13. package/dist/admin/_not-found/__next._tree.txt +1 -1
  14. package/dist/admin/_not-found/index.html +1 -1
  15. package/dist/admin/_not-found/index.txt +1 -1
  16. package/dist/admin/databases/__next._full.txt +1 -1
  17. package/dist/admin/databases/__next._head.txt +1 -1
  18. package/dist/admin/databases/__next._index.txt +1 -1
  19. package/dist/admin/databases/__next._tree.txt +1 -1
  20. package/dist/admin/databases/__next.databases.__PAGE__.txt +1 -1
  21. package/dist/admin/databases/__next.databases.txt +1 -1
  22. package/dist/admin/databases/index.html +1 -1
  23. package/dist/admin/databases/index.txt +1 -1
  24. package/dist/admin/index.html +1 -1
  25. package/dist/admin/index.txt +1 -1
  26. package/dist/cli.js +104 -21
  27. package/dist/docs/services.md +19 -0
  28. package/dist/postinstall.js +1 -1
  29. package/package.json +1 -1
  30. /package/dist/admin/_next/static/{h5UEt0QGdPmIwztzVl3eF → 0CmgQNPZi3W-iwSoebP4u}/_buildManifest.js +0 -0
  31. /package/dist/admin/_next/static/{h5UEt0QGdPmIwztzVl3eF → 0CmgQNPZi3W-iwSoebP4u}/_clientMiddlewareManifest.json +0 -0
  32. /package/dist/admin/_next/static/{h5UEt0QGdPmIwztzVl3eF → 0CmgQNPZi3W-iwSoebP4u}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- <!DOCTYPE html><!--h5UEt0QGdPmIwztzVl3eF--><html lang="en" class="inter_b2991b2-module__9mH_6q__variable"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/797e433ab948586e-s.p.dbea232f.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="preload" href="/_next/static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="preload" href="/_next/static/media/caa3a2e1cccd8315-s.p.853070df.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/chunks/951210b423dc9315.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/65ce370ab86b6df6.js"/><script src="/_next/static/chunks/9f53491ced2668ee.js" async=""></script><script src="/_next/static/chunks/63473a6cb811ed42.js" async=""></script><script src="/_next/static/chunks/turbopack-ebee0930f5a58b67.js" async=""></script><script src="/_next/static/chunks/d2b1f8ba26497c0b.js" async=""></script><script src="/_next/static/chunks/6877369fbd84f127.js" async=""></script><script src="/_next/static/chunks/ce9a5f692b87aaa9.js" async=""></script><script src="/_next/static/chunks/b2b4aada246f4749.js" async=""></script><script src="/_next/static/chunks/a308451471d4cb39.js" async=""></script><script src="/_next/static/chunks/75cb455f07e7651a.js" async=""></script><meta name="next-size-adjust" content=""/><title>Specific Dev Admin</title><meta name="description" content="Local development admin UI for Specific"/><link rel="icon" href="/favicon.ico?favicon.0b3bf435.ico" sizes="256x256" type="image/x-icon"/><link rel="icon" href="/icon.svg?icon.456b8582.svg" sizes="any" type="image/svg+xml"/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body class="geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased"><div hidden=""><!--$--><!--/$--></div><script>((a,b,c,d,e,f,g,h)=>{let i=document.documentElement,j=["light","dark"];function k(b){var c;(Array.isArray(a)?a:[a]).forEach(a=>{let c="class"===a,d=c&&f?e.map(a=>f[a]||a):e;c?(i.classList.remove(...d),i.classList.add(f&&f[b]?f[b]:b)):i.setAttribute(a,b)}),c=b,h&&j.includes(c)&&(i.style.colorScheme=c)}if(d)k(d);else try{let a=localStorage.getItem(b)||c,d=g&&"system"===a?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":a;k(d)}catch(a){}})("class","theme","system",null,["light","dark"],null,true,true)</script><div data-slot="sidebar-wrapper" style="--sidebar-width:16rem;--sidebar-width-icon:3rem" class="group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full"><div class="group peer text-sidebar-foreground hidden md:block" data-state="expanded" data-collapsible="" data-variant="inset" data-side="left" data-slot="sidebar"><div data-slot="sidebar-gap" class="relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear group-data-[collapsible=offcanvas]:w-0 group-data-[side=right]:rotate-180 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]"></div><div data-slot="sidebar-container" class="fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]"><div data-sidebar="sidebar" data-slot="sidebar-inner" class="bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm"><div data-slot="sidebar-header" data-sidebar="header" class="flex flex-col gap-2 p-2"><ul data-slot="sidebar-menu" data-sidebar="menu" class="flex w-full min-w-0 flex-col gap-1"><li data-slot="sidebar-menu-item" data-sidebar="menu-item" class="group/menu-item relative"><button data-slot="sidebar-menu-button" data-sidebar="menu-button" data-size="default" data-active="false" class="peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left outline-hidden ring-sidebar-ring transition-[width,height,padding] focus-visible:ring-2 active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&amp;&gt;span:last-child]:truncate [&amp;&gt;svg]:size-4 [&amp;&gt;svg]:shrink-0 hover:text-sidebar-accent-foreground h-8 text-sm cursor-default hover:bg-transparent active:bg-transparent"><div class="size-2 shrink-0 rounded-full bg-muted-foreground"></div><span class="truncate font-medium">Development</span></button></li></ul></div><div data-slot="sidebar-content" data-sidebar="content" class="flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden"><div data-slot="sidebar-group" data-sidebar="group" class="relative flex w-full min-w-0 flex-col p-2"><ul data-slot="sidebar-menu" data-sidebar="menu" class="flex w-full min-w-0 flex-col gap-1"><li data-slot="sidebar-menu-item" data-sidebar="menu-item" class="group/menu-item relative"><a data-slot="sidebar-menu-button" data-sidebar="menu-button" data-size="default" data-active="true" class="peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left outline-hidden ring-sidebar-ring transition-[width,height,padding] focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&amp;&gt;span:last-child]:truncate [&amp;&gt;svg]:size-4 [&amp;&gt;svg]:shrink-0 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground h-8 text-sm" data-state="closed" href="/"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-layout-dashboard" aria-hidden="true"><rect width="7" height="9" x="3" y="3" rx="1"></rect><rect width="7" height="5" x="14" y="3" rx="1"></rect><rect width="7" height="9" x="14" y="12" rx="1"></rect><rect width="7" height="5" x="3" y="16" rx="1"></rect></svg><span>Overview</span></a></li><li data-slot="sidebar-menu-item" data-sidebar="menu-item" class="group/menu-item relative"><button data-slot="sidebar-menu-button" data-sidebar="menu-button" data-size="default" data-active="false" class="peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left outline-hidden ring-sidebar-ring transition-[width,height,padding] focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&amp;&gt;span:last-child]:truncate [&amp;&gt;svg]:size-4 [&amp;&gt;svg]:shrink-0 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground h-8 text-sm" disabled="" data-state="closed"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-database" aria-hidden="true"><ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M3 5V19A9 3 0 0 0 21 19V5"></path><path d="M3 12A9 3 0 0 0 21 12"></path></svg><span>Databases</span></button></li></ul></div></div><div data-slot="sidebar-footer" data-sidebar="footer" class="flex flex-col gap-2 p-2"></div><button data-sidebar="rail" data-slot="sidebar-rail" aria-label="Toggle Sidebar" tabindex="-1" title="Toggle Sidebar" class="hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize [[data-side=left][data-state=collapsed]_&amp;]:cursor-e-resize [[data-side=right][data-state=collapsed]_&amp;]:cursor-w-resize hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full [[data-side=left][data-collapsible=offcanvas]_&amp;]:-right-2 [[data-side=right][data-collapsible=offcanvas]_&amp;]:-left-2"></button></div></div></div><main data-slot="sidebar-inset" class="bg-background relative flex w-full flex-1 flex-col md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2 overflow-hidden"><header class="flex h-12 shrink-0 items-center gap-2 px-4"><button data-slot="sidebar-trigger" data-variant="ghost" data-size="icon" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg:not([class*=&#x27;size-&#x27;])]:size-4 shrink-0 [&amp;_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 size-7 -ml-1" data-sidebar="trigger"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-panel-left" aria-hidden="true"><rect width="18" height="18" x="3" y="3" rx="2"></rect><path d="M9 3v18"></path></svg><span class="sr-only">Toggle Sidebar</span></button></header><main class="flex-1 overflow-hidden"><div class="p-6"><div class="p-6 rounded-lg bg-card border border-border"><p class="text-muted-foreground">Connecting to dev server...</p></div></div></main><!--$--><!--/$--></main></div><script src="/_next/static/chunks/65ce370ab86b6df6.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[49311,[\"/_next/static/chunks/d2b1f8ba26497c0b.js\",\"/_next/static/chunks/6877369fbd84f127.js\",\"/_next/static/chunks/ce9a5f692b87aaa9.js\"],\"ThemeProvider\"]\n3:I[12283,[\"/_next/static/chunks/d2b1f8ba26497c0b.js\",\"/_next/static/chunks/6877369fbd84f127.js\",\"/_next/static/chunks/ce9a5f692b87aaa9.js\"],\"DevStateProvider\"]\n4:I[84220,[\"/_next/static/chunks/d2b1f8ba26497c0b.js\",\"/_next/static/chunks/6877369fbd84f127.js\",\"/_next/static/chunks/ce9a5f692b87aaa9.js\"],\"SidebarProvider\"]\n5:I[94519,[\"/_next/static/chunks/d2b1f8ba26497c0b.js\",\"/_next/static/chunks/6877369fbd84f127.js\",\"/_next/static/chunks/ce9a5f692b87aaa9.js\"],\"AppSidebar\"]\n6:I[84220,[\"/_next/static/chunks/d2b1f8ba26497c0b.js\",\"/_next/static/chunks/6877369fbd84f127.js\",\"/_next/static/chunks/ce9a5f692b87aaa9.js\"],\"SidebarInset\"]\n7:I[93103,[\"/_next/static/chunks/d2b1f8ba26497c0b.js\",\"/_next/static/chunks/6877369fbd84f127.js\",\"/_next/static/chunks/ce9a5f692b87aaa9.js\"],\"SiteHeader\"]\n8:I[26965,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/a308451471d4cb39.js\"],\"default\"]\n9:I[53399,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/a308451471d4cb39.js\"],\"default\"]\na:I[66592,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/a308451471d4cb39.js\"],\"ClientPageRoot\"]\nb:I[68613,[\"/_next/static/chunks/d2b1f8ba26497c0b.js\",\"/_next/static/chunks/6877369fbd84f127.js\",\"/_next/static/chunks/ce9a5f692b87aaa9.js\",\"/_next/static/chunks/75cb455f07e7651a.js\"],\"default\"]\ne:I[15478,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/a308451471d4cb39.js\"],\"OutletBoundary\"]\nf:\"$Sreact.suspense\"\n11:I[15478,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/a308451471d4cb39.js\"],\"ViewportBoundary\"]\n13:I[15478,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/a308451471d4cb39.js\"],\"MetadataBoundary\"]\n15:I[47541,[],\"default\"]\n:HL[\"/_next/static/chunks/951210b423dc9315.css\",\"style\"]\n:HL[\"/_next/static/media/797e433ab948586e-s.p.dbea232f.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"h5UEt0QGdPmIwztzVl3eF\",\"c\":[\"\",\"\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",true],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/951210b423dc9315.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/d2b1f8ba26497c0b.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/6877369fbd84f127.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-2\",{\"src\":\"/_next/static/chunks/ce9a5f692b87aaa9.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"className\":\"inter_b2991b2-module__9mH_6q__variable\",\"suppressHydrationWarning\":true,\"children\":[\"$\",\"body\",null,{\"className\":\"geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased\",\"children\":[\"$\",\"$L2\",null,{\"attribute\":\"class\",\"defaultTheme\":\"system\",\"enableSystem\":true,\"disableTransitionOnChange\":true,\"children\":[\"$\",\"$L3\",null,{\"children\":[\"$\",\"$L4\",null,{\"children\":[[\"$\",\"$L5\",null,{}],[\"$\",\"$L6\",null,{\"className\":\"overflow-hidden\",\"children\":[[\"$\",\"$L7\",null,{}],[\"$\",\"$L8\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L9\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}]]}]}]}]}]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"$La\",null,{\"Component\":\"$b\",\"serverProvidedParams\":{\"searchParams\":{},\"params\":{},\"promises\":[\"$@c\",\"$@d\"]}}],[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/75cb455f07e7651a.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$Le\",null,{\"children\":[\"$\",\"$f\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@10\"}]}]]}],{},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L11\",null,{\"children\":\"$L12\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L13\",null,{\"children\":[\"$\",\"$f\",null,{\"name\":\"Next.Metadata\",\"children\":\"$L14\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$15\",[]],\"S\":true}\n"])</script><script>self.__next_f.push([1,"c:{}\nd:\"$0:f:0:1:1:children:0:props:children:0:props:serverProvidedParams:params\"\n"])</script><script>self.__next_f.push([1,"12:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"16:I[80000,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/a308451471d4cb39.js\"],\"IconMark\"]\n10:null\n14:[[\"$\",\"title\",\"0\",{\"children\":\"Specific Dev Admin\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Local development admin UI for Specific\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0b3bf435.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/icon.svg?icon.456b8582.svg\",\"sizes\":\"any\",\"type\":\"image/svg+xml\"}],[\"$\",\"$L16\",\"4\",{}]]\n"])</script></body></html>
1
+ <!DOCTYPE html><!--0CmgQNPZi3W_iwSoebP4u--><html lang="en" class="inter_b2991b2-module__9mH_6q__variable"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/797e433ab948586e-s.p.dbea232f.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="preload" href="/_next/static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="preload" href="/_next/static/media/caa3a2e1cccd8315-s.p.853070df.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/chunks/951210b423dc9315.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/65ce370ab86b6df6.js"/><script src="/_next/static/chunks/9f53491ced2668ee.js" async=""></script><script src="/_next/static/chunks/63473a6cb811ed42.js" async=""></script><script src="/_next/static/chunks/turbopack-ebee0930f5a58b67.js" async=""></script><script src="/_next/static/chunks/d2b1f8ba26497c0b.js" async=""></script><script src="/_next/static/chunks/6877369fbd84f127.js" async=""></script><script src="/_next/static/chunks/ce9a5f692b87aaa9.js" async=""></script><script src="/_next/static/chunks/b2b4aada246f4749.js" async=""></script><script src="/_next/static/chunks/a308451471d4cb39.js" async=""></script><script src="/_next/static/chunks/75cb455f07e7651a.js" async=""></script><meta name="next-size-adjust" content=""/><title>Specific Dev Admin</title><meta name="description" content="Local development admin UI for Specific"/><link rel="icon" href="/favicon.ico?favicon.0b3bf435.ico" sizes="256x256" type="image/x-icon"/><link rel="icon" href="/icon.svg?icon.456b8582.svg" sizes="any" type="image/svg+xml"/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body class="geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased"><div hidden=""><!--$--><!--/$--></div><script>((a,b,c,d,e,f,g,h)=>{let i=document.documentElement,j=["light","dark"];function k(b){var c;(Array.isArray(a)?a:[a]).forEach(a=>{let c="class"===a,d=c&&f?e.map(a=>f[a]||a):e;c?(i.classList.remove(...d),i.classList.add(f&&f[b]?f[b]:b)):i.setAttribute(a,b)}),c=b,h&&j.includes(c)&&(i.style.colorScheme=c)}if(d)k(d);else try{let a=localStorage.getItem(b)||c,d=g&&"system"===a?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":a;k(d)}catch(a){}})("class","theme","system",null,["light","dark"],null,true,true)</script><div data-slot="sidebar-wrapper" style="--sidebar-width:16rem;--sidebar-width-icon:3rem" class="group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full"><div class="group peer text-sidebar-foreground hidden md:block" data-state="expanded" data-collapsible="" data-variant="inset" data-side="left" data-slot="sidebar"><div data-slot="sidebar-gap" class="relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear group-data-[collapsible=offcanvas]:w-0 group-data-[side=right]:rotate-180 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]"></div><div data-slot="sidebar-container" class="fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]"><div data-sidebar="sidebar" data-slot="sidebar-inner" class="bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm"><div data-slot="sidebar-header" data-sidebar="header" class="flex flex-col gap-2 p-2"><ul data-slot="sidebar-menu" data-sidebar="menu" class="flex w-full min-w-0 flex-col gap-1"><li data-slot="sidebar-menu-item" data-sidebar="menu-item" class="group/menu-item relative"><button data-slot="sidebar-menu-button" data-sidebar="menu-button" data-size="default" data-active="false" class="peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left outline-hidden ring-sidebar-ring transition-[width,height,padding] focus-visible:ring-2 active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&amp;&gt;span:last-child]:truncate [&amp;&gt;svg]:size-4 [&amp;&gt;svg]:shrink-0 hover:text-sidebar-accent-foreground h-8 text-sm cursor-default hover:bg-transparent active:bg-transparent"><div class="size-2 shrink-0 rounded-full bg-muted-foreground"></div><span class="truncate font-medium">Development</span></button></li></ul></div><div data-slot="sidebar-content" data-sidebar="content" class="flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden"><div data-slot="sidebar-group" data-sidebar="group" class="relative flex w-full min-w-0 flex-col p-2"><ul data-slot="sidebar-menu" data-sidebar="menu" class="flex w-full min-w-0 flex-col gap-1"><li data-slot="sidebar-menu-item" data-sidebar="menu-item" class="group/menu-item relative"><a data-slot="sidebar-menu-button" data-sidebar="menu-button" data-size="default" data-active="true" class="peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left outline-hidden ring-sidebar-ring transition-[width,height,padding] focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&amp;&gt;span:last-child]:truncate [&amp;&gt;svg]:size-4 [&amp;&gt;svg]:shrink-0 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground h-8 text-sm" data-state="closed" href="/"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-layout-dashboard" aria-hidden="true"><rect width="7" height="9" x="3" y="3" rx="1"></rect><rect width="7" height="5" x="14" y="3" rx="1"></rect><rect width="7" height="9" x="14" y="12" rx="1"></rect><rect width="7" height="5" x="3" y="16" rx="1"></rect></svg><span>Overview</span></a></li><li data-slot="sidebar-menu-item" data-sidebar="menu-item" class="group/menu-item relative"><button data-slot="sidebar-menu-button" data-sidebar="menu-button" data-size="default" data-active="false" class="peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left outline-hidden ring-sidebar-ring transition-[width,height,padding] focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&amp;&gt;span:last-child]:truncate [&amp;&gt;svg]:size-4 [&amp;&gt;svg]:shrink-0 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground h-8 text-sm" disabled="" data-state="closed"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-database" aria-hidden="true"><ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M3 5V19A9 3 0 0 0 21 19V5"></path><path d="M3 12A9 3 0 0 0 21 12"></path></svg><span>Databases</span></button></li></ul></div></div><div data-slot="sidebar-footer" data-sidebar="footer" class="flex flex-col gap-2 p-2"></div><button data-sidebar="rail" data-slot="sidebar-rail" aria-label="Toggle Sidebar" tabindex="-1" title="Toggle Sidebar" class="hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize [[data-side=left][data-state=collapsed]_&amp;]:cursor-e-resize [[data-side=right][data-state=collapsed]_&amp;]:cursor-w-resize hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full [[data-side=left][data-collapsible=offcanvas]_&amp;]:-right-2 [[data-side=right][data-collapsible=offcanvas]_&amp;]:-left-2"></button></div></div></div><main data-slot="sidebar-inset" class="bg-background relative flex w-full flex-1 flex-col md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2 overflow-hidden"><header class="flex h-12 shrink-0 items-center gap-2 px-4"><button data-slot="sidebar-trigger" data-variant="ghost" data-size="icon" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg:not([class*=&#x27;size-&#x27;])]:size-4 shrink-0 [&amp;_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 size-7 -ml-1" data-sidebar="trigger"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-panel-left" aria-hidden="true"><rect width="18" height="18" x="3" y="3" rx="2"></rect><path d="M9 3v18"></path></svg><span class="sr-only">Toggle Sidebar</span></button></header><main class="flex-1 overflow-hidden"><div class="p-6"><div class="p-6 rounded-lg bg-card border border-border"><p class="text-muted-foreground">Connecting to dev server...</p></div></div></main><!--$--><!--/$--></main></div><script src="/_next/static/chunks/65ce370ab86b6df6.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[49311,[\"/_next/static/chunks/d2b1f8ba26497c0b.js\",\"/_next/static/chunks/6877369fbd84f127.js\",\"/_next/static/chunks/ce9a5f692b87aaa9.js\"],\"ThemeProvider\"]\n3:I[12283,[\"/_next/static/chunks/d2b1f8ba26497c0b.js\",\"/_next/static/chunks/6877369fbd84f127.js\",\"/_next/static/chunks/ce9a5f692b87aaa9.js\"],\"DevStateProvider\"]\n4:I[84220,[\"/_next/static/chunks/d2b1f8ba26497c0b.js\",\"/_next/static/chunks/6877369fbd84f127.js\",\"/_next/static/chunks/ce9a5f692b87aaa9.js\"],\"SidebarProvider\"]\n5:I[94519,[\"/_next/static/chunks/d2b1f8ba26497c0b.js\",\"/_next/static/chunks/6877369fbd84f127.js\",\"/_next/static/chunks/ce9a5f692b87aaa9.js\"],\"AppSidebar\"]\n6:I[84220,[\"/_next/static/chunks/d2b1f8ba26497c0b.js\",\"/_next/static/chunks/6877369fbd84f127.js\",\"/_next/static/chunks/ce9a5f692b87aaa9.js\"],\"SidebarInset\"]\n7:I[93103,[\"/_next/static/chunks/d2b1f8ba26497c0b.js\",\"/_next/static/chunks/6877369fbd84f127.js\",\"/_next/static/chunks/ce9a5f692b87aaa9.js\"],\"SiteHeader\"]\n8:I[26965,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/a308451471d4cb39.js\"],\"default\"]\n9:I[53399,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/a308451471d4cb39.js\"],\"default\"]\na:I[66592,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/a308451471d4cb39.js\"],\"ClientPageRoot\"]\nb:I[68613,[\"/_next/static/chunks/d2b1f8ba26497c0b.js\",\"/_next/static/chunks/6877369fbd84f127.js\",\"/_next/static/chunks/ce9a5f692b87aaa9.js\",\"/_next/static/chunks/75cb455f07e7651a.js\"],\"default\"]\ne:I[15478,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/a308451471d4cb39.js\"],\"OutletBoundary\"]\nf:\"$Sreact.suspense\"\n11:I[15478,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/a308451471d4cb39.js\"],\"ViewportBoundary\"]\n13:I[15478,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/a308451471d4cb39.js\"],\"MetadataBoundary\"]\n15:I[47541,[],\"default\"]\n:HL[\"/_next/static/chunks/951210b423dc9315.css\",\"style\"]\n:HL[\"/_next/static/media/797e433ab948586e-s.p.dbea232f.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"0CmgQNPZi3W-iwSoebP4u\",\"c\":[\"\",\"\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",true],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/951210b423dc9315.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/d2b1f8ba26497c0b.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/6877369fbd84f127.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-2\",{\"src\":\"/_next/static/chunks/ce9a5f692b87aaa9.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"className\":\"inter_b2991b2-module__9mH_6q__variable\",\"suppressHydrationWarning\":true,\"children\":[\"$\",\"body\",null,{\"className\":\"geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased\",\"children\":[\"$\",\"$L2\",null,{\"attribute\":\"class\",\"defaultTheme\":\"system\",\"enableSystem\":true,\"disableTransitionOnChange\":true,\"children\":[\"$\",\"$L3\",null,{\"children\":[\"$\",\"$L4\",null,{\"children\":[[\"$\",\"$L5\",null,{}],[\"$\",\"$L6\",null,{\"className\":\"overflow-hidden\",\"children\":[[\"$\",\"$L7\",null,{}],[\"$\",\"$L8\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L9\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}]]}]}]}]}]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"$La\",null,{\"Component\":\"$b\",\"serverProvidedParams\":{\"searchParams\":{},\"params\":{},\"promises\":[\"$@c\",\"$@d\"]}}],[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/75cb455f07e7651a.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$Le\",null,{\"children\":[\"$\",\"$f\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@10\"}]}]]}],{},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L11\",null,{\"children\":\"$L12\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L13\",null,{\"children\":[\"$\",\"$f\",null,{\"name\":\"Next.Metadata\",\"children\":\"$L14\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$15\",[]],\"S\":true}\n"])</script><script>self.__next_f.push([1,"c:{}\nd:\"$0:f:0:1:1:children:0:props:children:0:props:serverProvidedParams:params\"\n"])</script><script>self.__next_f.push([1,"12:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"16:I[80000,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/a308451471d4cb39.js\"],\"IconMark\"]\n10:null\n14:[[\"$\",\"title\",\"0\",{\"children\":\"Specific Dev Admin\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Local development admin UI for Specific\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0b3bf435.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/icon.svg?icon.456b8582.svg\",\"sizes\":\"any\",\"type\":\"image/svg+xml\"}],[\"$\",\"$L16\",\"4\",{}]]\n"])</script></body></html>
@@ -18,7 +18,7 @@ f:"$Sreact.suspense"
18
18
  :HL["/_next/static/media/797e433ab948586e-s.p.dbea232f.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
19
19
  :HL["/_next/static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
20
20
  :HL["/_next/static/media/caa3a2e1cccd8315-s.p.853070df.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
21
- 0:{"P":null,"b":"h5UEt0QGdPmIwztzVl3eF","c":["",""],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/951210b423dc9315.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/d2b1f8ba26497c0b.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/_next/static/chunks/6877369fbd84f127.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/_next/static/chunks/ce9a5f692b87aaa9.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","className":"inter_b2991b2-module__9mH_6q__variable","suppressHydrationWarning":true,"children":["$","body",null,{"className":"geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased","children":["$","$L2",null,{"attribute":"class","defaultTheme":"system","enableSystem":true,"disableTransitionOnChange":true,"children":["$","$L3",null,{"children":["$","$L4",null,{"children":[["$","$L5",null,{}],["$","$L6",null,{"className":"overflow-hidden","children":[["$","$L7",null,{}],["$","$L8",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L9",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]]}]]}]}]}]}]}]]}],{"children":[["$","$1","c",{"children":[["$","$La",null,{"Component":"$b","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@c","$@d"]}}],[["$","script","script-0",{"src":"/_next/static/chunks/75cb455f07e7651a.js","async":true,"nonce":"$undefined"}]],["$","$Le",null,{"children":["$","$f",null,{"name":"Next.MetadataOutlet","children":"$@10"}]}]]}],{},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$L11",null,{"children":"$L12"}],["$","div",null,{"hidden":true,"children":["$","$L13",null,{"children":["$","$f",null,{"name":"Next.Metadata","children":"$L14"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$15",[]],"S":true}
21
+ 0:{"P":null,"b":"0CmgQNPZi3W-iwSoebP4u","c":["",""],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/951210b423dc9315.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/d2b1f8ba26497c0b.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/_next/static/chunks/6877369fbd84f127.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/_next/static/chunks/ce9a5f692b87aaa9.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","className":"inter_b2991b2-module__9mH_6q__variable","suppressHydrationWarning":true,"children":["$","body",null,{"className":"geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased","children":["$","$L2",null,{"attribute":"class","defaultTheme":"system","enableSystem":true,"disableTransitionOnChange":true,"children":["$","$L3",null,{"children":["$","$L4",null,{"children":[["$","$L5",null,{}],["$","$L6",null,{"className":"overflow-hidden","children":[["$","$L7",null,{}],["$","$L8",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L9",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]]}]]}]}]}]}]}]]}],{"children":[["$","$1","c",{"children":[["$","$La",null,{"Component":"$b","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@c","$@d"]}}],[["$","script","script-0",{"src":"/_next/static/chunks/75cb455f07e7651a.js","async":true,"nonce":"$undefined"}]],["$","$Le",null,{"children":["$","$f",null,{"name":"Next.MetadataOutlet","children":"$@10"}]}]]}],{},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$L11",null,{"children":"$L12"}],["$","div",null,{"hidden":true,"children":["$","$L13",null,{"children":["$","$f",null,{"name":"Next.Metadata","children":"$L14"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$15",[]],"S":true}
22
22
  c:{}
23
23
  d:"$0:f:0:1:1:children:0:props:children:0:props:serverProvidedParams:params"
24
24
  12:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
package/dist/cli.js CHANGED
@@ -183873,7 +183873,7 @@ function trackEvent(event, properties) {
183873
183873
  event,
183874
183874
  properties: {
183875
183875
  ...properties,
183876
- cli_version: "0.1.51",
183876
+ cli_version: "0.1.52",
183877
183877
  platform: process.platform,
183878
183878
  node_version: process.version,
183879
183879
  project_id: getProjectId(),
@@ -184348,8 +184348,43 @@ function parseReference(value) {
184348
184348
  if (match && match[1]) {
184349
184349
  return parseReferenceString(match[1]);
184350
184350
  }
184351
+ if (value.includes("${")) {
184352
+ return parseInterpolatedString(value);
184353
+ }
184351
184354
  return value;
184352
184355
  }
184356
+ function parseInterpolatedString(value) {
184357
+ const parts = [];
184358
+ const regex = /\$\{([^}]+)\}/g;
184359
+ let lastIndex = 0;
184360
+ let match;
184361
+ while ((match = regex.exec(value)) !== null) {
184362
+ if (match.index > lastIndex) {
184363
+ parts.push({ type: "literal", value: value.slice(lastIndex, match.index) });
184364
+ }
184365
+ const refStr = match[1];
184366
+ const parsed = parseReferenceString(refStr);
184367
+ if (typeof parsed === "string") {
184368
+ parts.push({ type: "literal", value: match[0] });
184369
+ } else {
184370
+ if (parsed.type === "secret") {
184371
+ throw new Error(`Secret references cannot be used inside interpolated strings. Use \${secret.${parsed.name}} as a standalone env var value instead.`);
184372
+ }
184373
+ if (parsed.type === "config") {
184374
+ throw new Error(`Config references cannot be used inside interpolated strings. Use \${config.${parsed.name}} as a standalone env var value instead.`);
184375
+ }
184376
+ if (parsed.type === "build") {
184377
+ throw new Error(`Build references cannot be used inside interpolated strings.`);
184378
+ }
184379
+ parts.push({ type: "ref", ref: parsed });
184380
+ }
184381
+ lastIndex = match.index + match[0].length;
184382
+ }
184383
+ if (lastIndex < value.length) {
184384
+ parts.push({ type: "literal", value: value.slice(lastIndex) });
184385
+ }
184386
+ return { type: "interpolated", parts };
184387
+ }
184353
184388
  function parseReferenceString(str) {
184354
184389
  if (str === "port") {
184355
184390
  return { type: "port" };
@@ -184542,6 +184577,16 @@ function parseBuilds(buildData) {
184542
184577
  continue;
184543
184578
  if (value.type === "service" && value.attribute === "public_url")
184544
184579
  continue;
184580
+ if (value.type === "interpolated") {
184581
+ for (const part of value.parts) {
184582
+ if (part.type === "ref") {
184583
+ if (part.ref.type !== "service" || part.ref.attribute !== "public_url") {
184584
+ throw new Error(`Build "${name}" env var "${key}" uses an unsupported reference type in interpolated string. Build env vars only support string literals and \${service.<name>.public_url} references.`);
184585
+ }
184586
+ }
184587
+ }
184588
+ continue;
184589
+ }
184545
184590
  throw new Error(`Build "${name}" env var "${key}" uses an unsupported reference type. Build env vars only support string literals and \${service.<name>.public_url} references.`);
184546
184591
  }
184547
184592
  build.env = env2;
@@ -184832,12 +184877,21 @@ async function parseConfig(hcl) {
184832
184877
  environments: parseEnvironments(json.environment)
184833
184878
  };
184834
184879
  }
184880
+ function envValueReferences(value) {
184881
+ if (typeof value === "string")
184882
+ return [];
184883
+ if (value.type === "interpolated") {
184884
+ return value.parts.filter((p) => p.type === "ref").map((p) => p.ref);
184885
+ }
184886
+ return [value];
184887
+ }
184835
184888
  function hasPortReference(env2) {
184836
184889
  if (!env2)
184837
184890
  return false;
184838
184891
  for (const value of Object.values(env2)) {
184839
- if (typeof value === "object" && value.type === "port") {
184840
- return true;
184892
+ for (const ref of envValueReferences(value)) {
184893
+ if (ref.type === "port")
184894
+ return true;
184841
184895
  }
184842
184896
  }
184843
184897
  return false;
@@ -184849,20 +184903,19 @@ function validateEndpointReferences(config) {
184849
184903
  serviceEndpointsMap.set(service.name, service.endpoints);
184850
184904
  }
184851
184905
  for (const service of config.services) {
184852
- if (service.endpoints.length > 1 && service.env) {
184853
- for (const [key, value] of Object.entries(service.env)) {
184854
- if (typeof value === "object" && value.type === "port") {
184906
+ if (!service.env)
184907
+ continue;
184908
+ for (const [key, value] of Object.entries(service.env)) {
184909
+ const refs = envValueReferences(value);
184910
+ for (const ref of refs) {
184911
+ if (service.endpoints.length > 1 && ref.type === "port") {
184855
184912
  errors.push({
184856
184913
  service: service.name,
184857
184914
  message: `Service "${service.name}" has multiple endpoints but uses \${port} for env var "${key}". Use \${endpoint.<name>.port} instead.`
184858
184915
  });
184859
184916
  }
184860
- }
184861
- }
184862
- if (service.env) {
184863
- for (const [key, value] of Object.entries(service.env)) {
184864
- if (typeof value === "object" && value.type === "service") {
184865
- const serviceRef = value;
184917
+ if (ref.type === "service") {
184918
+ const serviceRef = ref;
184866
184919
  const targetEndpoints = serviceEndpointsMap.get(serviceRef.serviceName);
184867
184920
  if (!targetEndpoints) {
184868
184921
  errors.push({
@@ -184907,8 +184960,8 @@ function validateEndpointReferences(config) {
184907
184960
  }
184908
184961
  }
184909
184962
  }
184910
- if (typeof value === "object" && value.type === "endpoint") {
184911
- const endpointRef = value;
184963
+ if (ref.type === "endpoint") {
184964
+ const endpointRef = ref;
184912
184965
  const endpointExists = service.endpoints.some((e) => e.name === endpointRef.endpointName);
184913
184966
  if (!endpointExists) {
184914
184967
  errors.push({
@@ -187551,6 +187604,21 @@ function resolveEnvValue(value, resources, secrets, configs, servicePort, servic
187551
187604
  if (typeof value === "string") {
187552
187605
  return value;
187553
187606
  }
187607
+ if (value.type === "interpolated") {
187608
+ return value.parts.map((part) => {
187609
+ if (part.type === "literal") return part.value;
187610
+ return resolveEnvValue(
187611
+ part.ref,
187612
+ resources,
187613
+ secrets,
187614
+ configs,
187615
+ servicePort,
187616
+ serviceEndpoints,
187617
+ currentServicePorts,
187618
+ publicUrls
187619
+ );
187620
+ }).join("");
187621
+ }
187554
187622
  switch (value.type) {
187555
187623
  case "port":
187556
187624
  if (servicePort === void 0) {
@@ -187746,6 +187814,16 @@ function resolveEnvForExec(env2, resources, secrets, configs) {
187746
187814
  if (value.type === "port" || value.type === "endpoint" || value.type === "service") {
187747
187815
  continue;
187748
187816
  }
187817
+ if (value.type === "interpolated") {
187818
+ const hasSkippableRef = value.parts.some(
187819
+ (part) => part.type === "ref" && (part.ref.type === "port" || part.ref.type === "endpoint" || part.ref.type === "service")
187820
+ );
187821
+ if (hasSkippableRef) {
187822
+ continue;
187823
+ }
187824
+ resolved[key] = resolveEnvValue(value, resources, secrets, configs);
187825
+ continue;
187826
+ }
187749
187827
  resolved[key] = resolveEnvValue(value, resources, secrets, configs);
187750
187828
  }
187751
187829
  return resolved;
@@ -188733,10 +188811,14 @@ function detectSyncDatabases(config) {
188733
188811
  for (const service of config.services) {
188734
188812
  if (!service.env) continue;
188735
188813
  for (const value of Object.values(service.env)) {
188736
- if (typeof value === "object" && value.type === "postgres") {
188737
- const attr = value.attribute;
188738
- if (attr === "sync.url" || attr === "sync.secret") {
188739
- needsSync.add(value.name);
188814
+ if (typeof value !== "object") continue;
188815
+ const refs = value.type === "interpolated" ? value.parts.filter((p) => p.type === "ref").map((p) => p.ref) : [value];
188816
+ for (const ref of refs) {
188817
+ if (ref.type === "postgres") {
188818
+ const attr = ref.attribute;
188819
+ if (attr === "sync.url" || attr === "sync.secret") {
188820
+ needsSync.add(ref.name);
188821
+ }
188740
188822
  }
188741
188823
  }
188742
188824
  }
@@ -189031,8 +189113,9 @@ function findRequiredResources(service) {
189031
189113
  const required = { postgres: [], redis: [], storage: [] };
189032
189114
  if (service.env) {
189033
189115
  for (const value of Object.values(service.env)) {
189034
- if (typeof value === "object" && value !== null) {
189035
- const ref = value;
189116
+ if (typeof value !== "object" || value === null) continue;
189117
+ const refs = value.type === "interpolated" ? value.parts.filter((p) => p.type === "ref").map((p) => p.ref) : [value];
189118
+ for (const ref of refs) {
189036
189119
  if (ref.type === "postgres" && !required.postgres.includes(ref.name)) {
189037
189120
  required.postgres.push(ref.name);
189038
189121
  } else if (ref.type === "redis" && !required.redis.includes(ref.name)) {
@@ -192963,7 +193046,7 @@ function betaCommand() {
192963
193046
  var program = new Command();
192964
193047
  var env = "production";
192965
193048
  var envLabel = env !== "production" ? `[${env.toUpperCase()}] ` : "";
192966
- program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.51").enablePositionalOptions();
193049
+ program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.52").enablePositionalOptions();
192967
193050
  program.command("init").description("Initialize project for use with a coding agent").option("--agent <name...>", "Agents to configure (cursor, claude, codex, other)").action((options2) => initCommand(options2));
192968
193051
  program.command("docs [topic]").description("Fetch LLM-optimized documentation").action(docsCommand);
192969
193052
  program.command("check").description("Validate specific.hcl configuration").action(checkCommand);
@@ -259,6 +259,25 @@ service "api" {
259
259
  }
260
260
  ```
261
261
 
262
+ ### String interpolation
263
+
264
+ You can embed references inside strings to compose values:
265
+
266
+ ```hcl
267
+ service "worker" {
268
+ build = build.worker
269
+ command = "./worker"
270
+
271
+ env = {
272
+ QUERY_URL = "http://${service.api.private_url}/api/query"
273
+ CUSTOM_DB = "host=${postgres.main.host} port=${postgres.main.port}"
274
+ PUBLIC_API = "https://${service.api.public_url}/v1"
275
+ }
276
+ }
277
+ ```
278
+
279
+ All resource references (services, postgres, redis, storage, port, endpoint) can be used inside interpolated strings. Secret and config references cannot be interpolated — they must be used as standalone values.
280
+
262
281
  ## Service dev configuration
263
282
 
264
283
  Override how a service runs in development. If the referenced build has no `dev` block, it is skipped.
@@ -111,7 +111,7 @@ function trackEvent(event, properties) {
111
111
  event,
112
112
  properties: {
113
113
  ...properties,
114
- cli_version: "0.1.51",
114
+ cli_version: "0.1.52",
115
115
  platform: process.platform,
116
116
  node_version: process.version,
117
117
  project_id: getProjectId(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@specific.dev/cli",
3
- "version": "0.1.51",
3
+ "version": "0.1.52",
4
4
  "description": "CLI for Specific infrastructure-as-code",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",