@specific.dev/cli 0.1.167 → 0.1.169

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 (105) hide show
  1. package/dist/admin/404/index.html +1 -1
  2. package/dist/admin/404.html +1 -1
  3. package/dist/admin/__next.!KGRlZmF1bHQp.__PAGE__.txt +2 -2
  4. package/dist/admin/__next.!KGRlZmF1bHQp.txt +5 -5
  5. package/dist/admin/__next._full.txt +7 -7
  6. package/dist/admin/__next._head.txt +1 -1
  7. package/dist/admin/__next._index.txt +2 -2
  8. package/dist/admin/__next._tree.txt +2 -2
  9. package/dist/admin/_next/static/chunks/{c7aaec1998a39e17.js → 21d31e8f6bca9c4d.js} +1 -1
  10. package/dist/admin/_next/static/chunks/461c9cd69d7b1183.js +1 -0
  11. package/dist/admin/_next/static/chunks/{03b7f2d1ca0f0722.js → 49ece73e3ba09824.js} +2 -2
  12. package/dist/admin/_next/static/chunks/{9835cc4e14c5aee3.js → 65e3cacf9bc29c63.js} +1 -1
  13. package/dist/admin/_next/static/chunks/7c4fab64146f782a.css +4 -0
  14. package/dist/admin/_next/static/chunks/cc07cda99550cd06.js +1 -0
  15. package/dist/admin/_not-found/__next._full.txt +2 -2
  16. package/dist/admin/_not-found/__next._head.txt +1 -1
  17. package/dist/admin/_not-found/__next._index.txt +2 -2
  18. package/dist/admin/_not-found/__next._not-found.__PAGE__.txt +1 -1
  19. package/dist/admin/_not-found/__next._not-found.txt +1 -1
  20. package/dist/admin/_not-found/__next._tree.txt +2 -2
  21. package/dist/admin/_not-found/index.html +1 -1
  22. package/dist/admin/_not-found/index.txt +2 -2
  23. package/dist/admin/crons/__next.!KGRlZmF1bHQp.crons.__PAGE__.txt +9 -0
  24. package/dist/admin/crons/__next.!KGRlZmF1bHQp.crons.txt +4 -0
  25. package/dist/admin/crons/__next.!KGRlZmF1bHQp.txt +8 -0
  26. package/dist/admin/crons/__next._full.txt +27 -0
  27. package/dist/admin/crons/__next._head.txt +6 -0
  28. package/dist/admin/crons/__next._index.txt +7 -0
  29. package/dist/admin/crons/__next._tree.txt +5 -0
  30. package/dist/admin/crons/index.html +1 -0
  31. package/dist/admin/crons/index.txt +27 -0
  32. package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.__PAGE__.txt +2 -2
  33. package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.txt +1 -1
  34. package/dist/admin/databases/__next.!KGRlZmF1bHQp.txt +5 -5
  35. package/dist/admin/databases/__next._full.txt +7 -7
  36. package/dist/admin/databases/__next._head.txt +1 -1
  37. package/dist/admin/databases/__next._index.txt +2 -2
  38. package/dist/admin/databases/__next._tree.txt +2 -2
  39. package/dist/admin/databases/index.html +1 -1
  40. package/dist/admin/databases/index.txt +7 -7
  41. package/dist/admin/fullscreen/__next._full.txt +3 -3
  42. package/dist/admin/fullscreen/__next._head.txt +1 -1
  43. package/dist/admin/fullscreen/__next._index.txt +2 -2
  44. package/dist/admin/fullscreen/__next._tree.txt +2 -2
  45. package/dist/admin/fullscreen/__next.fullscreen.__PAGE__.txt +2 -2
  46. package/dist/admin/fullscreen/__next.fullscreen.txt +1 -1
  47. package/dist/admin/fullscreen/databases/__next._full.txt +2 -2
  48. package/dist/admin/fullscreen/databases/__next._head.txt +1 -1
  49. package/dist/admin/fullscreen/databases/__next._index.txt +2 -2
  50. package/dist/admin/fullscreen/databases/__next._tree.txt +2 -2
  51. package/dist/admin/fullscreen/databases/__next.fullscreen.databases.__PAGE__.txt +1 -1
  52. package/dist/admin/fullscreen/databases/__next.fullscreen.databases.txt +1 -1
  53. package/dist/admin/fullscreen/databases/__next.fullscreen.txt +1 -1
  54. package/dist/admin/fullscreen/databases/index.html +1 -1
  55. package/dist/admin/fullscreen/databases/index.txt +2 -2
  56. package/dist/admin/fullscreen/index.html +1 -1
  57. package/dist/admin/fullscreen/index.txt +3 -3
  58. package/dist/admin/index.html +1 -1
  59. package/dist/admin/index.txt +7 -7
  60. package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.__PAGE__.txt +2 -2
  61. package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.txt +1 -1
  62. package/dist/admin/mail/__next.!KGRlZmF1bHQp.txt +5 -5
  63. package/dist/admin/mail/__next._full.txt +7 -7
  64. package/dist/admin/mail/__next._head.txt +1 -1
  65. package/dist/admin/mail/__next._index.txt +2 -2
  66. package/dist/admin/mail/__next._tree.txt +2 -2
  67. package/dist/admin/mail/index.html +1 -1
  68. package/dist/admin/mail/index.txt +7 -7
  69. package/dist/admin/services/__next.!KGRlZmF1bHQp.services.__PAGE__.txt +2 -2
  70. package/dist/admin/services/__next.!KGRlZmF1bHQp.services.txt +1 -1
  71. package/dist/admin/services/__next.!KGRlZmF1bHQp.txt +5 -5
  72. package/dist/admin/services/__next._full.txt +7 -7
  73. package/dist/admin/services/__next._head.txt +1 -1
  74. package/dist/admin/services/__next._index.txt +2 -2
  75. package/dist/admin/services/__next._tree.txt +2 -2
  76. package/dist/admin/services/index.html +1 -1
  77. package/dist/admin/services/index.txt +7 -7
  78. package/dist/admin/storage/__next.!KGRlZmF1bHQp.storage.__PAGE__.txt +2 -2
  79. package/dist/admin/storage/__next.!KGRlZmF1bHQp.storage.txt +1 -1
  80. package/dist/admin/storage/__next.!KGRlZmF1bHQp.txt +5 -5
  81. package/dist/admin/storage/__next._full.txt +7 -7
  82. package/dist/admin/storage/__next._head.txt +1 -1
  83. package/dist/admin/storage/__next._index.txt +2 -2
  84. package/dist/admin/storage/__next._tree.txt +2 -2
  85. package/dist/admin/storage/index.html +1 -1
  86. package/dist/admin/storage/index.txt +7 -7
  87. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.txt +5 -5
  88. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.__PAGE__.txt +2 -2
  89. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.txt +1 -1
  90. package/dist/admin/workflows/__next._full.txt +7 -7
  91. package/dist/admin/workflows/__next._head.txt +1 -1
  92. package/dist/admin/workflows/__next._index.txt +2 -2
  93. package/dist/admin/workflows/__next._tree.txt +2 -2
  94. package/dist/admin/workflows/index.html +1 -1
  95. package/dist/admin/workflows/index.txt +7 -7
  96. package/dist/cli.js +222 -19
  97. package/dist/docs/crons.md +107 -0
  98. package/dist/docs/index.md +1 -0
  99. package/dist/docs/services.md +1 -0
  100. package/package.json +1 -1
  101. package/dist/admin/_next/static/chunks/4ae8172f753ceb22.css +0 -4
  102. package/dist/admin/_next/static/chunks/86c4724b5ef98ffe.js +0 -1
  103. /package/dist/admin/_next/static/{2gH7QpZ0ueS3xubY4NeVz → Zr-PlDbPRMPF3cZlaFFvl}/_buildManifest.js +0 -0
  104. /package/dist/admin/_next/static/{2gH7QpZ0ueS3xubY4NeVz → Zr-PlDbPRMPF3cZlaFFvl}/_clientMiddlewareManifest.json +0 -0
  105. /package/dist/admin/_next/static/{2gH7QpZ0ueS3xubY4NeVz → Zr-PlDbPRMPF3cZlaFFvl}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- <!DOCTYPE html><!--2gH7QpZ0ueS3xubY4NeVz--><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.479bea2b.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.3b6cae6d.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/chunks/4ae8172f753ceb22.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/48f1de3af928e439.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-2830c15bd3d8f58b.js" async=""></script><script src="/_next/static/chunks/c52b2ebc474a0535.js" async=""></script><script src="/_next/static/chunks/b2b4aada246f4749.js" async=""></script><script src="/_next/static/chunks/7c2bbd09e9922443.js" async=""></script><script src="/_next/static/chunks/c7aaec1998a39e17.js" async=""></script><script src="/_next/static/chunks/b44581875c51fcd8.js" async=""></script><script src="/_next/static/chunks/9835cc4e14c5aee3.js" async=""></script><script src="/_next/static/chunks/dc5c264e3262a84a.js" async=""></script><script src="/_next/static/chunks/e3baf0c708c5b9ae.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="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" 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-server" aria-hidden="true"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"></rect><rect width="20" height="8" x="2" y="14" rx="2" ry="2"></rect><line x1="6" x2="6.01" y1="6" y2="6"></line><line x1="6" x2="6.01" y1="18" y2="18"></line></svg><span>Services</span></button></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><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-hard-drive" aria-hidden="true"><line x1="22" x2="2" y1="12" y2="12"></line><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path><line x1="6" x2="6.01" y1="16" y2="16"></line><line x1="10" x2="10.01" y1="16" y2="16"></line></svg><span>Storage</span></button></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="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" 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-workflow" aria-hidden="true"><rect width="8" height="8" x="3" y="3" rx="2"></rect><path d="M7 11v4a2 2 0 0 0 2 2h4"></path><rect width="8" height="8" x="13" y="13" rx="2"></rect></svg><span>Workflows</span></button></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-mail" aria-hidden="true"><path d="m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7"></path><rect x="2" y="4" width="20" height="16" rx="2"></rect></svg><span>Mail</span></button></li></ul></div></div><div data-slot="sidebar-footer" data-sidebar="footer" class="flex flex-col gap-2 p-2"></div></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="h-14 shrink-0 items-center gap-2 border-b border-border px-3 hidden"><div data-header-portal="true" class="flex flex-1 items-center gap-2"></div></header><div class="flex min-h-0 flex-1 flex-col overflow-hidden"><main class="flex-1 overflow-hidden"><div class="p-6"><div class="p-6 rounded-lg bg-card border border-border text-center"><p class="text-muted-foreground">No workflow engine configured.</p><p class="text-sm text-muted-foreground mt-1">Add a temporal block to your specific.hcl to use the workflow engine.</p></div></div></main><!--$--><!--/$--></div></main></div><script src="/_next/static/chunks/48f1de3af928e439.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/c52b2ebc474a0535.js\"],\"ThemeProvider\"]\n3:I[12283,[\"/_next/static/chunks/c52b2ebc474a0535.js\"],\"DevStateProvider\"]\n4:I[26965,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/7c2bbd09e9922443.js\"],\"default\"]\n5:I[53399,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/7c2bbd09e9922443.js\"],\"default\"]\n6:I[84220,[\"/_next/static/chunks/c52b2ebc474a0535.js\",\"/_next/static/chunks/c7aaec1998a39e17.js\",\"/_next/static/chunks/b44581875c51fcd8.js\",\"/_next/static/chunks/9835cc4e14c5aee3.js\",\"/_next/static/chunks/dc5c264e3262a84a.js\"],\"SidebarProvider\"]\n7:I[94519,[\"/_next/static/chunks/c52b2ebc474a0535.js\",\"/_next/static/chunks/c7aaec1998a39e17.js\",\"/_next/static/chunks/b44581875c51fcd8.js\",\"/_next/static/chunks/9835cc4e14c5aee3.js\",\"/_next/static/chunks/dc5c264e3262a84a.js\"],\"AppSidebar\"]\n8:I[84220,[\"/_next/static/chunks/c52b2ebc474a0535.js\",\"/_next/static/chunks/c7aaec1998a39e17.js\",\"/_next/static/chunks/b44581875c51fcd8.js\",\"/_next/static/chunks/9835cc4e14c5aee3.js\",\"/_next/static/chunks/dc5c264e3262a84a.js\"],\"SidebarInset\"]\n9:I[93103,[\"/_next/static/chunks/c52b2ebc474a0535.js\",\"/_next/static/chunks/c7aaec1998a39e17.js\",\"/_next/static/chunks/b44581875c51fcd8.js\",\"/_next/static/chunks/9835cc4e14c5aee3.js\",\"/_next/static/chunks/dc5c264e3262a84a.js\"],\"SiteHeaderProvider\"]\na:I[66592,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/7c2bbd09e9922443.js\"],\"ClientPageRoot\"]\nb:I[14627,[\"/_next/static/chunks/c52b2ebc474a0535.js\",\"/_next/static/chunks/c7aaec1998a39e17.js\",\"/_next/static/chunks/b44581875c51fcd8.js\",\"/_next/static/chunks/9835cc4e14c5aee3.js\",\"/_next/static/chunks/dc5c264e3262a84a.js\",\"/_next/static/chunks/e3baf0c708c5b9ae.js\"],\"default\"]\ne:I[15478,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/7c2bbd09e9922443.js\"],\"OutletBoundary\"]\nf:\"$Sreact.suspense\"\n11:I[15478,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/7c2bbd09e9922443.js\"],\"ViewportBoundary\"]\n13:I[15478,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/7c2bbd09e9922443.js\"],\"MetadataBoundary\"]\n15:I[47541,[],\"default\"]\n:HL[\"/_next/static/chunks/4ae8172f753ceb22.css\",\"style\"]\n:HL[\"/_next/static/media/797e433ab948586e-s.p.479bea2b.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.3b6cae6d.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"2gH7QpZ0ueS3xubY4NeVz\",\"c\":[\"\",\"workflows\",\"\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"(default)\",{\"children\":[\"workflows\",{\"children\":[\"__PAGE__\",{}]}]}]},\"$undefined\",\"$undefined\",true],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/4ae8172f753ceb22.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/c52b2ebc474a0535.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,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",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\":[[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/c7aaec1998a39e17.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/b44581875c51fcd8.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-2\",{\"src\":\"/_next/static/chunks/9835cc4e14c5aee3.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-3\",{\"src\":\"/_next/static/chunks/dc5c264e3262a84a.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$L6\",null,{\"children\":[[\"$\",\"$L7\",null,{}],[\"$\",\"$L8\",null,{\"className\":\"overflow-hidden\",\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:style\",\"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\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style\",\"children\":404}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"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/e3baf0c708c5b9ae.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$Le\",null,{\"children\":[\"$\",\"$f\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@10\"}]}]]}],{},null,false,false]},null,false,false]},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:1:children: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/7c2bbd09e9922443.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><!--Zr_PlDbPRMPF3cZlaFFvl--><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.479bea2b.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.3b6cae6d.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/chunks/7c4fab64146f782a.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/48f1de3af928e439.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-2830c15bd3d8f58b.js" async=""></script><script src="/_next/static/chunks/c52b2ebc474a0535.js" async=""></script><script src="/_next/static/chunks/b2b4aada246f4749.js" async=""></script><script src="/_next/static/chunks/7c2bbd09e9922443.js" async=""></script><script src="/_next/static/chunks/21d31e8f6bca9c4d.js" async=""></script><script src="/_next/static/chunks/b44581875c51fcd8.js" async=""></script><script src="/_next/static/chunks/65e3cacf9bc29c63.js" async=""></script><script src="/_next/static/chunks/dc5c264e3262a84a.js" async=""></script><script src="/_next/static/chunks/e3baf0c708c5b9ae.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="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" 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-server" aria-hidden="true"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"></rect><rect width="20" height="8" x="2" y="14" rx="2" ry="2"></rect><line x1="6" x2="6.01" y1="6" y2="6"></line><line x1="6" x2="6.01" y1="18" y2="18"></line></svg><span>Services</span></button></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-clock" aria-hidden="true"><path d="M12 6v6l4 2"></path><circle cx="12" cy="12" r="10"></circle></svg><span>Crons</span></button></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><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-hard-drive" aria-hidden="true"><line x1="22" x2="2" y1="12" y2="12"></line><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path><line x1="6" x2="6.01" y1="16" y2="16"></line><line x1="10" x2="10.01" y1="16" y2="16"></line></svg><span>Storage</span></button></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="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" 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-workflow" aria-hidden="true"><rect width="8" height="8" x="3" y="3" rx="2"></rect><path d="M7 11v4a2 2 0 0 0 2 2h4"></path><rect width="8" height="8" x="13" y="13" rx="2"></rect></svg><span>Workflows</span></button></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-mail" aria-hidden="true"><path d="m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7"></path><rect x="2" y="4" width="20" height="16" rx="2"></rect></svg><span>Mail</span></button></li></ul></div></div><div data-slot="sidebar-footer" data-sidebar="footer" class="flex flex-col gap-2 p-2"></div></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="h-14 shrink-0 items-center gap-2 border-b border-border px-3 hidden"><div data-header-portal="true" class="flex flex-1 items-center gap-2"></div></header><div class="flex min-h-0 flex-1 flex-col overflow-hidden"><main class="flex-1 overflow-hidden"><div class="p-6"><div class="p-6 rounded-lg bg-card border border-border text-center"><p class="text-muted-foreground">No workflow engine configured.</p><p class="text-sm text-muted-foreground mt-1">Add a temporal block to your specific.hcl to use the workflow engine.</p></div></div></main><!--$--><!--/$--></div></main></div><script src="/_next/static/chunks/48f1de3af928e439.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/c52b2ebc474a0535.js\"],\"ThemeProvider\"]\n3:I[12283,[\"/_next/static/chunks/c52b2ebc474a0535.js\"],\"DevStateProvider\"]\n4:I[26965,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/7c2bbd09e9922443.js\"],\"default\"]\n5:I[53399,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/7c2bbd09e9922443.js\"],\"default\"]\n6:I[84220,[\"/_next/static/chunks/c52b2ebc474a0535.js\",\"/_next/static/chunks/21d31e8f6bca9c4d.js\",\"/_next/static/chunks/b44581875c51fcd8.js\",\"/_next/static/chunks/65e3cacf9bc29c63.js\",\"/_next/static/chunks/dc5c264e3262a84a.js\"],\"SidebarProvider\"]\n7:I[94519,[\"/_next/static/chunks/c52b2ebc474a0535.js\",\"/_next/static/chunks/21d31e8f6bca9c4d.js\",\"/_next/static/chunks/b44581875c51fcd8.js\",\"/_next/static/chunks/65e3cacf9bc29c63.js\",\"/_next/static/chunks/dc5c264e3262a84a.js\"],\"AppSidebar\"]\n8:I[84220,[\"/_next/static/chunks/c52b2ebc474a0535.js\",\"/_next/static/chunks/21d31e8f6bca9c4d.js\",\"/_next/static/chunks/b44581875c51fcd8.js\",\"/_next/static/chunks/65e3cacf9bc29c63.js\",\"/_next/static/chunks/dc5c264e3262a84a.js\"],\"SidebarInset\"]\n9:I[93103,[\"/_next/static/chunks/c52b2ebc474a0535.js\",\"/_next/static/chunks/21d31e8f6bca9c4d.js\",\"/_next/static/chunks/b44581875c51fcd8.js\",\"/_next/static/chunks/65e3cacf9bc29c63.js\",\"/_next/static/chunks/dc5c264e3262a84a.js\"],\"SiteHeaderProvider\"]\na:I[66592,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/7c2bbd09e9922443.js\"],\"ClientPageRoot\"]\nb:I[14627,[\"/_next/static/chunks/c52b2ebc474a0535.js\",\"/_next/static/chunks/21d31e8f6bca9c4d.js\",\"/_next/static/chunks/b44581875c51fcd8.js\",\"/_next/static/chunks/65e3cacf9bc29c63.js\",\"/_next/static/chunks/dc5c264e3262a84a.js\",\"/_next/static/chunks/e3baf0c708c5b9ae.js\"],\"default\"]\ne:I[15478,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/7c2bbd09e9922443.js\"],\"OutletBoundary\"]\nf:\"$Sreact.suspense\"\n11:I[15478,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/7c2bbd09e9922443.js\"],\"ViewportBoundary\"]\n13:I[15478,[\"/_next/static/chunks/b2b4aada246f4749.js\",\"/_next/static/chunks/7c2bbd09e9922443.js\"],\"MetadataBoundary\"]\n15:I[47541,[],\"default\"]\n:HL[\"/_next/static/chunks/7c4fab64146f782a.css\",\"style\"]\n:HL[\"/_next/static/media/797e433ab948586e-s.p.479bea2b.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.3b6cae6d.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"Zr-PlDbPRMPF3cZlaFFvl\",\"c\":[\"\",\"workflows\",\"\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"(default)\",{\"children\":[\"workflows\",{\"children\":[\"__PAGE__\",{}]}]}]},\"$undefined\",\"$undefined\",true],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/7c4fab64146f782a.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/c52b2ebc474a0535.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,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",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\":[[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/21d31e8f6bca9c4d.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/b44581875c51fcd8.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-2\",{\"src\":\"/_next/static/chunks/65e3cacf9bc29c63.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-3\",{\"src\":\"/_next/static/chunks/dc5c264e3262a84a.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$L6\",null,{\"children\":[[\"$\",\"$L7\",null,{}],[\"$\",\"$L8\",null,{\"className\":\"overflow-hidden\",\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:style\",\"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\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style\",\"children\":404}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"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/e3baf0c708c5b9ae.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$Le\",null,{\"children\":[\"$\",\"$f\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@10\"}]}]]}],{},null,false,false]},null,false,false]},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:1:children: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/7c2bbd09e9922443.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>
@@ -3,22 +3,22 @@
3
3
  3:I[12283,["/_next/static/chunks/c52b2ebc474a0535.js"],"DevStateProvider"]
4
4
  4:I[26965,["/_next/static/chunks/b2b4aada246f4749.js","/_next/static/chunks/7c2bbd09e9922443.js"],"default"]
5
5
  5:I[53399,["/_next/static/chunks/b2b4aada246f4749.js","/_next/static/chunks/7c2bbd09e9922443.js"],"default"]
6
- 6:I[84220,["/_next/static/chunks/c52b2ebc474a0535.js","/_next/static/chunks/c7aaec1998a39e17.js","/_next/static/chunks/b44581875c51fcd8.js","/_next/static/chunks/9835cc4e14c5aee3.js","/_next/static/chunks/dc5c264e3262a84a.js"],"SidebarProvider"]
7
- 7:I[94519,["/_next/static/chunks/c52b2ebc474a0535.js","/_next/static/chunks/c7aaec1998a39e17.js","/_next/static/chunks/b44581875c51fcd8.js","/_next/static/chunks/9835cc4e14c5aee3.js","/_next/static/chunks/dc5c264e3262a84a.js"],"AppSidebar"]
8
- 8:I[84220,["/_next/static/chunks/c52b2ebc474a0535.js","/_next/static/chunks/c7aaec1998a39e17.js","/_next/static/chunks/b44581875c51fcd8.js","/_next/static/chunks/9835cc4e14c5aee3.js","/_next/static/chunks/dc5c264e3262a84a.js"],"SidebarInset"]
9
- 9:I[93103,["/_next/static/chunks/c52b2ebc474a0535.js","/_next/static/chunks/c7aaec1998a39e17.js","/_next/static/chunks/b44581875c51fcd8.js","/_next/static/chunks/9835cc4e14c5aee3.js","/_next/static/chunks/dc5c264e3262a84a.js"],"SiteHeaderProvider"]
6
+ 6:I[84220,["/_next/static/chunks/c52b2ebc474a0535.js","/_next/static/chunks/21d31e8f6bca9c4d.js","/_next/static/chunks/b44581875c51fcd8.js","/_next/static/chunks/65e3cacf9bc29c63.js","/_next/static/chunks/dc5c264e3262a84a.js"],"SidebarProvider"]
7
+ 7:I[94519,["/_next/static/chunks/c52b2ebc474a0535.js","/_next/static/chunks/21d31e8f6bca9c4d.js","/_next/static/chunks/b44581875c51fcd8.js","/_next/static/chunks/65e3cacf9bc29c63.js","/_next/static/chunks/dc5c264e3262a84a.js"],"AppSidebar"]
8
+ 8:I[84220,["/_next/static/chunks/c52b2ebc474a0535.js","/_next/static/chunks/21d31e8f6bca9c4d.js","/_next/static/chunks/b44581875c51fcd8.js","/_next/static/chunks/65e3cacf9bc29c63.js","/_next/static/chunks/dc5c264e3262a84a.js"],"SidebarInset"]
9
+ 9:I[93103,["/_next/static/chunks/c52b2ebc474a0535.js","/_next/static/chunks/21d31e8f6bca9c4d.js","/_next/static/chunks/b44581875c51fcd8.js","/_next/static/chunks/65e3cacf9bc29c63.js","/_next/static/chunks/dc5c264e3262a84a.js"],"SiteHeaderProvider"]
10
10
  a:I[66592,["/_next/static/chunks/b2b4aada246f4749.js","/_next/static/chunks/7c2bbd09e9922443.js"],"ClientPageRoot"]
11
- b:I[14627,["/_next/static/chunks/c52b2ebc474a0535.js","/_next/static/chunks/c7aaec1998a39e17.js","/_next/static/chunks/b44581875c51fcd8.js","/_next/static/chunks/9835cc4e14c5aee3.js","/_next/static/chunks/dc5c264e3262a84a.js","/_next/static/chunks/e3baf0c708c5b9ae.js"],"default"]
11
+ b:I[14627,["/_next/static/chunks/c52b2ebc474a0535.js","/_next/static/chunks/21d31e8f6bca9c4d.js","/_next/static/chunks/b44581875c51fcd8.js","/_next/static/chunks/65e3cacf9bc29c63.js","/_next/static/chunks/dc5c264e3262a84a.js","/_next/static/chunks/e3baf0c708c5b9ae.js"],"default"]
12
12
  e:I[15478,["/_next/static/chunks/b2b4aada246f4749.js","/_next/static/chunks/7c2bbd09e9922443.js"],"OutletBoundary"]
13
13
  f:"$Sreact.suspense"
14
14
  11:I[15478,["/_next/static/chunks/b2b4aada246f4749.js","/_next/static/chunks/7c2bbd09e9922443.js"],"ViewportBoundary"]
15
15
  13:I[15478,["/_next/static/chunks/b2b4aada246f4749.js","/_next/static/chunks/7c2bbd09e9922443.js"],"MetadataBoundary"]
16
16
  15:I[47541,[],"default"]
17
- :HL["/_next/static/chunks/4ae8172f753ceb22.css","style"]
17
+ :HL["/_next/static/chunks/7c4fab64146f782a.css","style"]
18
18
  :HL["/_next/static/media/797e433ab948586e-s.p.479bea2b.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.3b6cae6d.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
21
- 0:{"P":null,"b":"2gH7QpZ0ueS3xubY4NeVz","c":["","workflows",""],"q":"","i":false,"f":[[["",{"children":["(default)",{"children":["workflows",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/4ae8172f753ceb22.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/c52b2ebc474a0535.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,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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":[[["$","script","script-0",{"src":"/_next/static/chunks/c7aaec1998a39e17.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/_next/static/chunks/b44581875c51fcd8.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/_next/static/chunks/9835cc4e14c5aee3.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/_next/static/chunks/dc5c264e3262a84a.js","async":true,"nonce":"$undefined"}]],["$","$L6",null,{"children":[["$","$L7",null,{}],["$","$L8",null,{"className":"overflow-hidden","children":["$","$L9",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:style","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":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style","children":404}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style","children":["$","h2",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style","children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]]}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","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/e3baf0c708c5b9ae.js","async":true,"nonce":"$undefined"}]],["$","$Le",null,{"children":["$","$f",null,{"name":"Next.MetadataOutlet","children":"$@10"}]}]]}],{},null,false,false]},null,false,false]},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":"Zr-PlDbPRMPF3cZlaFFvl","c":["","workflows",""],"q":"","i":false,"f":[[["",{"children":["(default)",{"children":["workflows",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/7c4fab64146f782a.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/c52b2ebc474a0535.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,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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":[[["$","script","script-0",{"src":"/_next/static/chunks/21d31e8f6bca9c4d.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/_next/static/chunks/b44581875c51fcd8.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/_next/static/chunks/65e3cacf9bc29c63.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/_next/static/chunks/dc5c264e3262a84a.js","async":true,"nonce":"$undefined"}]],["$","$L6",null,{"children":[["$","$L7",null,{}],["$","$L8",null,{"className":"overflow-hidden","children":["$","$L9",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:style","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":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style","children":404}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style","children":["$","h2",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style","children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]]}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","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/e3baf0c708c5b9ae.js","async":true,"nonce":"$undefined"}]],["$","$Le",null,{"children":["$","$f",null,{"name":"Next.MetadataOutlet","children":"$@10"}]}]]}],{},null,false,false]},null,false,false]},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:1:children: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
@@ -368663,6 +368663,99 @@ function parseServices(serviceData) {
368663
368663
  }
368664
368664
  return services;
368665
368665
  }
368666
+ var CRON_MACROS = /* @__PURE__ */ new Set([
368667
+ "@hourly",
368668
+ "@daily",
368669
+ "@midnight",
368670
+ "@weekly",
368671
+ "@monthly",
368672
+ "@yearly",
368673
+ "@annually"
368674
+ ]);
368675
+ var CRON_FIELD = /^[A-Za-z0-9*][A-Za-z0-9*,\-/]*$/;
368676
+ function validateCronSchedule(name, schedule) {
368677
+ const trimmed = schedule.trim();
368678
+ if (trimmed === "") {
368679
+ throw new Error(`Cron "${name}" has an empty "schedule".`);
368680
+ }
368681
+ if (trimmed.startsWith("@")) {
368682
+ if (!CRON_MACROS.has(trimmed)) {
368683
+ throw new Error(`Cron "${name}" has invalid schedule macro "${trimmed}". Supported macros: @hourly, @daily, @weekly, @monthly, @yearly.`);
368684
+ }
368685
+ return;
368686
+ }
368687
+ const fields = trimmed.split(/\s+/);
368688
+ if (fields.length !== 5) {
368689
+ throw new Error(`Cron "${name}" has invalid schedule "${schedule}". Expected a 5-field cron expression (minute hour day-of-month month day-of-week) or a macro like @daily.`);
368690
+ }
368691
+ for (const field of fields) {
368692
+ if (!CRON_FIELD.test(field)) {
368693
+ throw new Error(`Cron "${name}" has invalid schedule "${schedule}": unexpected field "${field}".`);
368694
+ }
368695
+ }
368696
+ }
368697
+ function parseCrons(cronData) {
368698
+ if (!cronData || typeof cronData !== "object" || Array.isArray(cronData)) {
368699
+ return [];
368700
+ }
368701
+ const crons = [];
368702
+ for (const [name, fieldsArray] of Object.entries(cronData)) {
368703
+ const fields = Array.isArray(fieldsArray) ? fieldsArray[0] : fieldsArray;
368704
+ if (!fields || typeof fields !== "object" || Array.isArray(fields)) {
368705
+ continue;
368706
+ }
368707
+ const fieldObj = fields;
368708
+ if (fieldObj.endpoint !== void 0) {
368709
+ throw new Error(`Cron "${name}" cannot define an "endpoint". Crons run a command on a schedule and do not serve network traffic.`);
368710
+ }
368711
+ if (fieldObj.volume !== void 0) {
368712
+ throw new Error(`Cron "${name}" cannot define a "volume".`);
368713
+ }
368714
+ if (fieldObj.health_check !== void 0) {
368715
+ throw new Error(`Cron "${name}" cannot define a "health_check".`);
368716
+ }
368717
+ if (typeof fieldObj.schedule !== "string" || fieldObj.schedule.trim() === "") {
368718
+ throw new Error(`Cron "${name}" must specify a "schedule" (a 5-field cron expression or a macro like @daily).`);
368719
+ }
368720
+ validateCronSchedule(name, fieldObj.schedule);
368721
+ const cron = { name, schedule: fieldObj.schedule };
368722
+ const buildRef = parseBuildRef(fieldObj.build);
368723
+ if (buildRef) {
368724
+ cron.build = buildRef;
368725
+ }
368726
+ if (fieldObj.image) {
368727
+ if (typeof fieldObj.image !== "string" || fieldObj.image.trim() === "") {
368728
+ throw new Error(`Cron "${name}" has invalid "image" value. Must be a non-empty string.`);
368729
+ }
368730
+ cron.image = String(fieldObj.image);
368731
+ }
368732
+ if (cron.build && cron.image) {
368733
+ throw new Error(`Cron "${name}" cannot have both "build" and "image". Use one or the other.`);
368734
+ }
368735
+ if (!cron.build && !cron.image) {
368736
+ throw new Error(`Cron "${name}" must have a "build" or an "image" \u2014 there is nothing to run on a schedule otherwise.`);
368737
+ }
368738
+ if (fieldObj.command) {
368739
+ cron.command = String(fieldObj.command);
368740
+ }
368741
+ if (cron.build && !cron.command) {
368742
+ throw new Error(`Cron "${name}" has a "build" but no "command". Crons with a build must specify a command to run.`);
368743
+ }
368744
+ if (fieldObj.root) {
368745
+ cron.root = String(fieldObj.root);
368746
+ }
368747
+ const env2 = parseEnv(fieldObj.env);
368748
+ if (env2) {
368749
+ cron.env = env2;
368750
+ }
368751
+ const dev = parseServiceDevBlock(fieldObj.dev);
368752
+ if (dev) {
368753
+ cron.dev = dev;
368754
+ }
368755
+ crons.push(cron);
368756
+ }
368757
+ return crons;
368758
+ }
368666
368759
  function parseReshapeBlock(reshape) {
368667
368760
  if (!reshape) {
368668
368761
  return void 0;
@@ -368851,6 +368944,7 @@ async function parseConfig(hcl) {
368851
368944
  return {
368852
368945
  builds: parseBuilds(json.build),
368853
368946
  services: parseServices(json.service),
368947
+ crons: parseCrons(json.cron),
368854
368948
  postgres: parsePostgres(json.postgres),
368855
368949
  redis: parseRedis(json.redis),
368856
368950
  storage: parseStorage(json.storage),
@@ -373963,6 +374057,12 @@ Add them to the config block in specific.local`
373963
374057
  volumes: svc.volumes?.map((v) => v.name)
373964
374058
  };
373965
374059
  }),
374060
+ crons: config.crons.map((cron) => ({
374061
+ name: cron.name,
374062
+ schedule: cron.schedule,
374063
+ command: cron.command,
374064
+ env: cron.env
374065
+ })),
373966
374066
  resources: [...resources.entries()].map(([name, r]) => ({
373967
374067
  name,
373968
374068
  type: r.type,
@@ -374629,7 +374729,7 @@ function trackEvent(event, properties) {
374629
374729
  event,
374630
374730
  properties: {
374631
374731
  ...properties,
374632
- cli_version: "0.1.167",
374732
+ cli_version: "0.1.169",
374633
374733
  platform: process.platform,
374634
374734
  node_version: process.version,
374635
374735
  project_id: getProjectId()
@@ -375566,6 +375666,99 @@ function parseServices2(serviceData) {
375566
375666
  }
375567
375667
  return services;
375568
375668
  }
375669
+ var CRON_MACROS2 = /* @__PURE__ */ new Set([
375670
+ "@hourly",
375671
+ "@daily",
375672
+ "@midnight",
375673
+ "@weekly",
375674
+ "@monthly",
375675
+ "@yearly",
375676
+ "@annually"
375677
+ ]);
375678
+ var CRON_FIELD2 = /^[A-Za-z0-9*][A-Za-z0-9*,\-/]*$/;
375679
+ function validateCronSchedule2(name, schedule) {
375680
+ const trimmed = schedule.trim();
375681
+ if (trimmed === "") {
375682
+ throw new Error(`Cron "${name}" has an empty "schedule".`);
375683
+ }
375684
+ if (trimmed.startsWith("@")) {
375685
+ if (!CRON_MACROS2.has(trimmed)) {
375686
+ throw new Error(`Cron "${name}" has invalid schedule macro "${trimmed}". Supported macros: @hourly, @daily, @weekly, @monthly, @yearly.`);
375687
+ }
375688
+ return;
375689
+ }
375690
+ const fields = trimmed.split(/\s+/);
375691
+ if (fields.length !== 5) {
375692
+ throw new Error(`Cron "${name}" has invalid schedule "${schedule}". Expected a 5-field cron expression (minute hour day-of-month month day-of-week) or a macro like @daily.`);
375693
+ }
375694
+ for (const field of fields) {
375695
+ if (!CRON_FIELD2.test(field)) {
375696
+ throw new Error(`Cron "${name}" has invalid schedule "${schedule}": unexpected field "${field}".`);
375697
+ }
375698
+ }
375699
+ }
375700
+ function parseCrons2(cronData) {
375701
+ if (!cronData || typeof cronData !== "object" || Array.isArray(cronData)) {
375702
+ return [];
375703
+ }
375704
+ const crons = [];
375705
+ for (const [name, fieldsArray] of Object.entries(cronData)) {
375706
+ const fields = Array.isArray(fieldsArray) ? fieldsArray[0] : fieldsArray;
375707
+ if (!fields || typeof fields !== "object" || Array.isArray(fields)) {
375708
+ continue;
375709
+ }
375710
+ const fieldObj = fields;
375711
+ if (fieldObj.endpoint !== void 0) {
375712
+ throw new Error(`Cron "${name}" cannot define an "endpoint". Crons run a command on a schedule and do not serve network traffic.`);
375713
+ }
375714
+ if (fieldObj.volume !== void 0) {
375715
+ throw new Error(`Cron "${name}" cannot define a "volume".`);
375716
+ }
375717
+ if (fieldObj.health_check !== void 0) {
375718
+ throw new Error(`Cron "${name}" cannot define a "health_check".`);
375719
+ }
375720
+ if (typeof fieldObj.schedule !== "string" || fieldObj.schedule.trim() === "") {
375721
+ throw new Error(`Cron "${name}" must specify a "schedule" (a 5-field cron expression or a macro like @daily).`);
375722
+ }
375723
+ validateCronSchedule2(name, fieldObj.schedule);
375724
+ const cron = { name, schedule: fieldObj.schedule };
375725
+ const buildRef = parseBuildRef2(fieldObj.build);
375726
+ if (buildRef) {
375727
+ cron.build = buildRef;
375728
+ }
375729
+ if (fieldObj.image) {
375730
+ if (typeof fieldObj.image !== "string" || fieldObj.image.trim() === "") {
375731
+ throw new Error(`Cron "${name}" has invalid "image" value. Must be a non-empty string.`);
375732
+ }
375733
+ cron.image = String(fieldObj.image);
375734
+ }
375735
+ if (cron.build && cron.image) {
375736
+ throw new Error(`Cron "${name}" cannot have both "build" and "image". Use one or the other.`);
375737
+ }
375738
+ if (!cron.build && !cron.image) {
375739
+ throw new Error(`Cron "${name}" must have a "build" or an "image" \u2014 there is nothing to run on a schedule otherwise.`);
375740
+ }
375741
+ if (fieldObj.command) {
375742
+ cron.command = String(fieldObj.command);
375743
+ }
375744
+ if (cron.build && !cron.command) {
375745
+ throw new Error(`Cron "${name}" has a "build" but no "command". Crons with a build must specify a command to run.`);
375746
+ }
375747
+ if (fieldObj.root) {
375748
+ cron.root = String(fieldObj.root);
375749
+ }
375750
+ const env2 = parseEnv2(fieldObj.env);
375751
+ if (env2) {
375752
+ cron.env = env2;
375753
+ }
375754
+ const dev = parseServiceDevBlock2(fieldObj.dev);
375755
+ if (dev) {
375756
+ cron.dev = dev;
375757
+ }
375758
+ crons.push(cron);
375759
+ }
375760
+ return crons;
375761
+ }
375569
375762
  function parseReshapeBlock2(reshape) {
375570
375763
  if (!reshape) {
375571
375764
  return void 0;
@@ -375754,6 +375947,7 @@ async function parseConfig2(hcl) {
375754
375947
  return {
375755
375948
  builds: parseBuilds2(json.build),
375756
375949
  services: parseServices2(json.service),
375950
+ crons: parseCrons2(json.cron),
375757
375951
  postgres: parsePostgres2(json.postgres),
375758
375952
  redis: parseRedis2(json.redis),
375759
375953
  storage: parseStorage2(json.storage),
@@ -375874,7 +376068,7 @@ function CheckUI() {
375874
376068
  const reshapeChecks = state.reshapeChecks ?? [];
375875
376069
  const reshapeErrors = reshapeChecks.filter((r) => !r.success);
375876
376070
  const hasReshapeErrors = reshapeErrors.length > 0;
375877
- return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: hasReshapeErrors ? "yellow" : "green" }, hasReshapeErrors ? "Configuration is valid but reshape migrations have errors" : "Configuration is valid"), config.builds.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Builds (", config.builds.length, "):"), config.builds.map((b) => /* @__PURE__ */ React3.createElement(Text3, { key: b.name }, " ", "- ", b.name, b.base ? ` (${b.base})` : "", b.dockerfile ? ` (dockerfile: ${b.dockerfile})` : ""))), config.services.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Services (", config.services.length, "):"), config.services.map((s) => /* @__PURE__ */ React3.createElement(Text3, { key: s.name }, " ", "- ", s.name, s.build ? ` (build: ${s.build.name})` : "", s.image ? ` (image: ${s.image})` : ""))), config.postgres.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Postgres (", config.postgres.length, "):"), config.postgres.map((p) => /* @__PURE__ */ React3.createElement(Text3, { key: p.name }, " ", "- ", p.name, p.reshape?.enabled ? " (reshape enabled)" : ""))), reshapeChecks.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Reshape Migrations:"), reshapeChecks.map((r) => /* @__PURE__ */ React3.createElement(Box3, { key: r.databaseName, flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, null, " ", /* @__PURE__ */ React3.createElement(Text3, { color: r.success ? "green" : "red" }, r.success ? "pass" : "fail"), " ", r.databaseName, " (", r.migrationsDir, ")"), r.error && /* @__PURE__ */ React3.createElement(Text3, { color: "red" }, " ", r.error)))), config.redis.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Redis (", config.redis.length, "):"), config.redis.map((r) => /* @__PURE__ */ React3.createElement(Text3, { key: r.name }, " ", "- ", r.name))), config.storage.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Storage (", config.storage.length, "):"), config.storage.map((s) => /* @__PURE__ */ React3.createElement(Text3, { key: s.name }, " ", "- ", s.name))), config.configs.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Config (", config.configs.length, "):"), config.configs.map((c) => /* @__PURE__ */ React3.createElement(Text3, { key: c.name }, " ", "- ", c.name, c.default ? ` (default: ${c.default})` : ""))), config.environments.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Environments (", config.environments.length, "):"), config.environments.map((e) => /* @__PURE__ */ React3.createElement(Text3, { key: e.name }, " ", "- ", e.name))));
376071
+ return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: hasReshapeErrors ? "yellow" : "green" }, hasReshapeErrors ? "Configuration is valid but reshape migrations have errors" : "Configuration is valid"), config.builds.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Builds (", config.builds.length, "):"), config.builds.map((b) => /* @__PURE__ */ React3.createElement(Text3, { key: b.name }, " ", "- ", b.name, b.base ? ` (${b.base})` : "", b.dockerfile ? ` (dockerfile: ${b.dockerfile})` : ""))), config.services.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Services (", config.services.length, "):"), config.services.map((s) => /* @__PURE__ */ React3.createElement(Text3, { key: s.name }, " ", "- ", s.name, s.build ? ` (build: ${s.build.name})` : "", s.image ? ` (image: ${s.image})` : ""))), config.crons.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Crons (", config.crons.length, "):"), config.crons.map((c) => /* @__PURE__ */ React3.createElement(Text3, { key: c.name }, " ", "- ", c.name, " (", c.schedule, ")", c.build ? ` (build: ${c.build.name})` : "", c.image ? ` (image: ${c.image})` : ""))), config.postgres.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Postgres (", config.postgres.length, "):"), config.postgres.map((p) => /* @__PURE__ */ React3.createElement(Text3, { key: p.name }, " ", "- ", p.name, p.reshape?.enabled ? " (reshape enabled)" : ""))), reshapeChecks.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Reshape Migrations:"), reshapeChecks.map((r) => /* @__PURE__ */ React3.createElement(Box3, { key: r.databaseName, flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, null, " ", /* @__PURE__ */ React3.createElement(Text3, { color: r.success ? "green" : "red" }, r.success ? "pass" : "fail"), " ", r.databaseName, " (", r.migrationsDir, ")"), r.error && /* @__PURE__ */ React3.createElement(Text3, { color: "red" }, " ", r.error)))), config.redis.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Redis (", config.redis.length, "):"), config.redis.map((r) => /* @__PURE__ */ React3.createElement(Text3, { key: r.name }, " ", "- ", r.name))), config.storage.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Storage (", config.storage.length, "):"), config.storage.map((s) => /* @__PURE__ */ React3.createElement(Text3, { key: s.name }, " ", "- ", s.name))), config.configs.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Config (", config.configs.length, "):"), config.configs.map((c) => /* @__PURE__ */ React3.createElement(Text3, { key: c.name }, " ", "- ", c.name, c.default ? ` (default: ${c.default})` : ""))), config.environments.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Environments (", config.environments.length, "):"), config.environments.map((e) => /* @__PURE__ */ React3.createElement(Text3, { key: e.name }, " ", "- ", e.name))));
375878
376072
  }
375879
376073
  function checkCommand() {
375880
376074
  render3(/* @__PURE__ */ React3.createElement(CheckUI, null));
@@ -378026,12 +378220,6 @@ function startSpinner(text) {
378026
378220
  };
378027
378221
  }
378028
378222
  async function execCommand(serviceName, command, instanceKey = "default", options2 = {}) {
378029
- if (command.length === 0) {
378030
- console.error(
378031
- "Error: No command provided. Usage: specific exec <service> -- <command>"
378032
- );
378033
- process.exit(1);
378034
- }
378035
378223
  let startedResources = [];
378036
378224
  let startedElectric = [];
378037
378225
  let ownsInstances = false;
@@ -378066,14 +378254,29 @@ async function execCommand(serviceName, command, instanceKey = "default", option
378066
378254
  process.exit(1);
378067
378255
  }
378068
378256
  const service = config.services.find((s) => s.name === serviceName);
378069
- if (!service) {
378070
- const available = config.services.map((s) => s.name).join(", ");
378257
+ const cron = config.crons.find((c) => c.name === serviceName);
378258
+ const target = service ?? cron;
378259
+ if (!target) {
378260
+ const available = [
378261
+ ...config.services.map((s) => s.name),
378262
+ ...config.crons.map((c) => c.name)
378263
+ ].join(", ");
378071
378264
  console.error(
378072
- `Error: Service "${serviceName}" not found. Available services: ${available || "none"}`
378265
+ `Error: Service or cron "${serviceName}" not found. Available: ${available || "none"}`
378073
378266
  );
378074
378267
  process.exit(1);
378075
378268
  }
378076
- const required = findRequiredResources(service);
378269
+ if (command.length === 0) {
378270
+ if (cron?.command) {
378271
+ command = ["sh", "-c", cron.command];
378272
+ } else {
378273
+ console.error(
378274
+ "Error: No command provided. Usage: specific exec <service> -- <command>"
378275
+ );
378276
+ process.exit(1);
378277
+ }
378278
+ }
378279
+ const required = findRequiredResources(target);
378077
378280
  let resources = /* @__PURE__ */ new Map();
378078
378281
  const hasRequiredResources = required.postgres.length > 0 || required.redis.length > 0 || required.storage.length > 0 || required.temporal.length > 0 || required.mail.length > 0;
378079
378282
  stateManager = new InstanceStateManager(process.cwd(), instanceKey);
@@ -378183,7 +378386,7 @@ async function execCommand(serviceName, command, instanceKey = "default", option
378183
378386
  runningContext.publicUrls = new Map(Object.entries(existingInstances.publicUrls));
378184
378387
  }
378185
378388
  }
378186
- const effectiveEnv = runningContext && service.dev?.env ? { ...service.env, ...service.dev.env } : service.env;
378389
+ const effectiveEnv = runningContext && target.dev?.env ? { ...target.env, ...target.dev.env } : target.env;
378187
378390
  let resolvedEnv;
378188
378391
  try {
378189
378392
  const secrets = await prepareSecrets(config.secrets);
@@ -378225,10 +378428,10 @@ async function execCommand(serviceName, command, instanceKey = "default", option
378225
378428
  let effectiveCwd = process.cwd();
378226
378429
  if (options2.cwd) {
378227
378430
  effectiveCwd = path22.resolve(process.cwd(), options2.cwd);
378228
- } else if (service.root) {
378229
- effectiveCwd = path22.resolve(process.cwd(), service.root);
378230
- } else if (service.build) {
378231
- const build = config.builds.find((b) => b.name === service.build.name);
378431
+ } else if (target.root) {
378432
+ effectiveCwd = path22.resolve(process.cwd(), target.root);
378433
+ } else if (target.build) {
378434
+ const build = config.builds.find((b) => b.name === target.build.name);
378232
378435
  if (build?.root) {
378233
378436
  effectiveCwd = path22.resolve(process.cwd(), build.root);
378234
378437
  }
@@ -378885,7 +379088,7 @@ function compareVersions(a, b) {
378885
379088
  return 0;
378886
379089
  }
378887
379090
  async function checkForUpdate() {
378888
- const currentVersion = "0.1.167";
379091
+ const currentVersion = "0.1.169";
378889
379092
  const response = await fetch(`${BINARIES_BASE_URL}/latest?t=${Date.now()}`);
378890
379093
  if (!response.ok) {
378891
379094
  throw new Error(`Failed to check for updates: HTTP ${response.status}`);
@@ -379548,7 +379751,7 @@ async function domainAddCommand(service, domain, options2) {
379548
379751
  var program = new Command();
379549
379752
  var env = "production";
379550
379753
  var envLabel = env !== "production" ? `[${env.toUpperCase()}] ` : "";
379551
- program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.167").enablePositionalOptions();
379754
+ program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.169").enablePositionalOptions();
379552
379755
  program.command("init").description("Initialize project for use with a coding agent").option("--agent <name...>", "Agents to configure (cursor, claude, codex, other)").addHelpText("after", `
379553
379756
  Examples:
379554
379757
  $ specific init