station-kit 1.0.9 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/.next/standalone/packages/station-kit/.next/BUILD_ID +1 -1
  2. package/.next/standalone/packages/station-kit/.next/app-build-manifest.json +57 -36
  3. package/.next/standalone/packages/station-kit/.next/app-path-routes-manifest.json +13 -10
  4. package/.next/standalone/packages/station-kit/.next/build-manifest.json +2 -2
  5. package/.next/standalone/packages/station-kit/.next/prerender-manifest.json +72 -24
  6. package/.next/standalone/packages/station-kit/.next/routes-manifest.json +20 -0
  7. package/.next/standalone/packages/station-kit/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  8. package/.next/standalone/packages/station-kit/.next/server/app/_not-found.html +1 -1
  9. package/.next/standalone/packages/station-kit/.next/server/app/_not-found.rsc +8 -8
  10. package/.next/standalone/packages/station-kit/.next/server/app/beacons/[name]/page.js +2 -0
  11. package/.next/standalone/packages/station-kit/.next/server/app/beacons/[name]/page.js.nft.json +1 -0
  12. package/.next/standalone/packages/station-kit/.next/server/app/beacons/[name]/page_client-reference-manifest.js +1 -0
  13. package/.next/standalone/packages/station-kit/.next/server/app/beacons/page.js +2 -0
  14. package/.next/standalone/packages/station-kit/.next/server/app/beacons/page.js.nft.json +1 -0
  15. package/.next/standalone/packages/station-kit/.next/server/app/beacons/page_client-reference-manifest.js +1 -0
  16. package/.next/standalone/packages/station-kit/.next/server/app/beacons.html +1 -0
  17. package/.next/standalone/packages/station-kit/.next/server/app/beacons.meta +7 -0
  18. package/.next/standalone/packages/station-kit/.next/server/app/beacons.rsc +25 -0
  19. package/.next/standalone/packages/station-kit/.next/server/app/broadcasts/[id]/page_client-reference-manifest.js +1 -1
  20. package/.next/standalone/packages/station-kit/.next/server/app/broadcasts/dyn/[name]/page_client-reference-manifest.js +1 -1
  21. package/.next/standalone/packages/station-kit/.next/server/app/broadcasts/dyn/[name]/v/[n]/page_client-reference-manifest.js +1 -1
  22. package/.next/standalone/packages/station-kit/.next/server/app/broadcasts/new/page_client-reference-manifest.js +1 -1
  23. package/.next/standalone/packages/station-kit/.next/server/app/broadcasts/new.html +1 -1
  24. package/.next/standalone/packages/station-kit/.next/server/app/broadcasts/new.rsc +9 -9
  25. package/.next/standalone/packages/station-kit/.next/server/app/broadcasts/page_client-reference-manifest.js +1 -1
  26. package/.next/standalone/packages/station-kit/.next/server/app/broadcasts.html +1 -1
  27. package/.next/standalone/packages/station-kit/.next/server/app/broadcasts.rsc +9 -9
  28. package/.next/standalone/packages/station-kit/.next/server/app/environment/page.js +2 -0
  29. package/.next/standalone/packages/station-kit/.next/server/app/environment/page.js.nft.json +1 -0
  30. package/.next/standalone/packages/station-kit/.next/server/app/environment/page_client-reference-manifest.js +1 -0
  31. package/.next/standalone/packages/station-kit/.next/server/app/environment.html +1 -0
  32. package/.next/standalone/packages/station-kit/.next/server/app/environment.meta +7 -0
  33. package/.next/standalone/packages/station-kit/.next/server/app/environment.rsc +25 -0
  34. package/.next/standalone/packages/station-kit/.next/server/app/index.html +1 -1
  35. package/.next/standalone/packages/station-kit/.next/server/app/index.rsc +9 -9
  36. package/.next/standalone/packages/station-kit/.next/server/app/page_client-reference-manifest.js +1 -1
  37. package/.next/standalone/packages/station-kit/.next/server/app/playground/expression/page_client-reference-manifest.js +1 -1
  38. package/.next/standalone/packages/station-kit/.next/server/app/playground/expression.html +1 -1
  39. package/.next/standalone/packages/station-kit/.next/server/app/playground/expression.rsc +9 -9
  40. package/.next/standalone/packages/station-kit/.next/server/app/runs/[id]/page_client-reference-manifest.js +1 -1
  41. package/.next/standalone/packages/station-kit/.next/server/app/schedules/[id]/page_client-reference-manifest.js +1 -1
  42. package/.next/standalone/packages/station-kit/.next/server/app/schedules/new/page_client-reference-manifest.js +1 -1
  43. package/.next/standalone/packages/station-kit/.next/server/app/schedules/new.html +1 -1
  44. package/.next/standalone/packages/station-kit/.next/server/app/schedules/new.rsc +9 -9
  45. package/.next/standalone/packages/station-kit/.next/server/app/schedules/page_client-reference-manifest.js +1 -1
  46. package/.next/standalone/packages/station-kit/.next/server/app/schedules.html +1 -1
  47. package/.next/standalone/packages/station-kit/.next/server/app/schedules.rsc +9 -9
  48. package/.next/standalone/packages/station-kit/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  49. package/.next/standalone/packages/station-kit/.next/server/app/settings.html +1 -1
  50. package/.next/standalone/packages/station-kit/.next/server/app/settings.rsc +9 -9
  51. package/.next/standalone/packages/station-kit/.next/server/app/signals/[name]/page_client-reference-manifest.js +1 -1
  52. package/.next/standalone/packages/station-kit/.next/server/app/signals/page_client-reference-manifest.js +1 -1
  53. package/.next/standalone/packages/station-kit/.next/server/app/signals.html +1 -1
  54. package/.next/standalone/packages/station-kit/.next/server/app/signals.rsc +9 -9
  55. package/.next/standalone/packages/station-kit/.next/server/app-paths-manifest.json +13 -10
  56. package/.next/standalone/packages/station-kit/.next/server/chunks/102.js +1 -1
  57. package/.next/standalone/packages/station-kit/.next/server/pages/404.html +1 -1
  58. package/.next/standalone/packages/station-kit/.next/server/pages/500.html +1 -1
  59. package/.next/standalone/packages/station-kit/.next/server/pages-manifest.json +1 -1
  60. package/.next/standalone/packages/station-kit/.next/server/server-reference-manifest.json +1 -1
  61. package/.next/standalone/packages/station-kit/.next/static/chunks/285-583f23ee7827983f.js +1 -0
  62. package/.next/standalone/packages/station-kit/.next/static/chunks/561-05a7ef9669e3921a.js +1 -0
  63. package/.next/standalone/packages/station-kit/.next/static/chunks/app/beacons/[name]/page-eb1f82847734e145.js +1 -0
  64. package/.next/standalone/packages/station-kit/.next/static/chunks/app/beacons/page-64e296346197e44b.js +1 -0
  65. package/.next/standalone/packages/station-kit/.next/static/chunks/app/broadcasts/dyn/[name]/v/[n]/page-15edf07ab26241c9.js +1 -0
  66. package/.next/standalone/packages/station-kit/.next/static/chunks/app/broadcasts/page-b23a03097c8f75c4.js +1 -0
  67. package/.next/standalone/packages/station-kit/.next/static/chunks/app/environment/page-111242bec067fdee.js +1 -0
  68. package/.next/standalone/packages/station-kit/.next/static/chunks/app/layout-e9ac56fcaf7a5ea7.js +1 -0
  69. package/.next/standalone/packages/station-kit/.next/static/chunks/app/page-ef78692958c2fc01.js +1 -0
  70. package/.next/standalone/packages/station-kit/.next/static/chunks/app/playground/expression/page-29294a705dd8f471.js +1 -0
  71. package/.next/standalone/packages/station-kit/.next/static/chunks/app/runs/[id]/page-287bbb8f6dec2e23.js +1 -0
  72. package/.next/standalone/packages/station-kit/.next/static/chunks/app/schedules/page-c869218da203e3b4.js +1 -0
  73. package/.next/standalone/packages/station-kit/.next/static/chunks/app/settings/page-05cf43b6ae6b3187.js +1 -0
  74. package/.next/standalone/packages/station-kit/.next/static/chunks/app/signals/[name]/page-4027803be00c695a.js +1 -0
  75. package/.next/standalone/packages/station-kit/.next/static/chunks/app/signals/page-8e076fc5d0188d72.js +1 -0
  76. package/.next/standalone/packages/station-kit/.next/static/css/ddb1646dc25ed100.css +1 -0
  77. package/.next/standalone/packages/station-kit/.next/static/vTGEzSqxhR_E57YAFn9DC/_buildManifest.js +1 -0
  78. package/.next/standalone/packages/station-kit/package.json +6 -4
  79. package/dist/config/schema.d.ts +31 -3
  80. package/dist/config/schema.d.ts.map +1 -1
  81. package/dist/config/schema.js +4 -0
  82. package/dist/config/schema.js.map +1 -1
  83. package/dist/index.d.ts +1 -0
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +3 -0
  86. package/dist/index.js.map +1 -1
  87. package/dist/server/auth/keys.d.ts +58 -6
  88. package/dist/server/auth/keys.d.ts.map +1 -1
  89. package/dist/server/auth/keys.js +179 -14
  90. package/dist/server/auth/keys.js.map +1 -1
  91. package/dist/server/auth/session.d.ts.map +1 -1
  92. package/dist/server/auth/session.js +34 -11
  93. package/dist/server/auth/session.js.map +1 -1
  94. package/dist/server/index.d.ts +5 -2
  95. package/dist/server/index.d.ts.map +1 -1
  96. package/dist/server/index.js +169 -24
  97. package/dist/server/index.js.map +1 -1
  98. package/dist/server/log-store.d.ts +102 -6
  99. package/dist/server/log-store.d.ts.map +1 -1
  100. package/dist/server/log-store.js +140 -32
  101. package/dist/server/log-store.js.map +1 -1
  102. package/dist/server/metadata.d.ts +2 -0
  103. package/dist/server/metadata.d.ts.map +1 -1
  104. package/dist/server/metadata.js.map +1 -1
  105. package/dist/server/middleware/rate-limit.d.ts.map +1 -1
  106. package/dist/server/middleware/rate-limit.js +22 -1
  107. package/dist/server/middleware/rate-limit.js.map +1 -1
  108. package/dist/server/routes/beacons.d.ts +10 -0
  109. package/dist/server/routes/beacons.d.ts.map +1 -0
  110. package/dist/server/routes/beacons.js +98 -0
  111. package/dist/server/routes/beacons.js.map +1 -0
  112. package/dist/server/routes/broadcasts.d.ts.map +1 -1
  113. package/dist/server/routes/broadcasts.js +9 -3
  114. package/dist/server/routes/broadcasts.js.map +1 -1
  115. package/dist/server/routes/runs.d.ts.map +1 -1
  116. package/dist/server/routes/runs.js +20 -60
  117. package/dist/server/routes/runs.js.map +1 -1
  118. package/dist/server/routes/signals.d.ts.map +1 -1
  119. package/dist/server/routes/signals.js +17 -13
  120. package/dist/server/routes/signals.js.map +1 -1
  121. package/dist/server/routes/v1/env.d.ts +10 -0
  122. package/dist/server/routes/v1/env.d.ts.map +1 -0
  123. package/dist/server/routes/v1/env.js +132 -0
  124. package/dist/server/routes/v1/env.js.map +1 -0
  125. package/dist/server/routes/v1/events.js +2 -2
  126. package/dist/server/routes/v1/events.js.map +1 -1
  127. package/dist/server/routes/v1/runs.d.ts.map +1 -1
  128. package/dist/server/routes/v1/runs.js +11 -32
  129. package/dist/server/routes/v1/runs.js.map +1 -1
  130. package/dist/server/sse.d.ts +2 -1
  131. package/dist/server/sse.d.ts.map +1 -1
  132. package/dist/server/sse.js +5 -1
  133. package/dist/server/sse.js.map +1 -1
  134. package/dist/server/subscriber.d.ts +56 -0
  135. package/dist/server/subscriber.d.ts.map +1 -1
  136. package/dist/server/subscriber.js +94 -0
  137. package/dist/server/subscriber.js.map +1 -1
  138. package/dist/server/ws.d.ts +8 -2
  139. package/dist/server/ws.d.ts.map +1 -1
  140. package/dist/server/ws.js +28 -3
  141. package/dist/server/ws.js.map +1 -1
  142. package/package.json +13 -11
  143. package/src/app/beacons/[name]/beacon-detail.tsx +253 -0
  144. package/src/app/beacons/[name]/page.tsx +6 -0
  145. package/src/app/beacons/page.tsx +98 -0
  146. package/src/app/components/shell.tsx +24 -0
  147. package/src/app/components/status-badge.tsx +13 -1
  148. package/src/app/environment/page.tsx +415 -0
  149. package/src/app/globals.css +48 -0
  150. package/src/app/hooks/use-api.ts +80 -0
  151. package/src/config/schema.ts +35 -3
  152. package/src/index.ts +12 -0
  153. package/src/server/auth/keys.ts +215 -15
  154. package/src/server/auth/session.ts +38 -11
  155. package/src/server/index.ts +192 -23
  156. package/src/server/log-store.ts +196 -45
  157. package/src/server/metadata.ts +2 -0
  158. package/src/server/middleware/rate-limit.ts +20 -1
  159. package/src/server/routes/beacons.ts +112 -0
  160. package/src/server/routes/broadcasts.ts +9 -3
  161. package/src/server/routes/runs.ts +21 -68
  162. package/src/server/routes/signals.ts +17 -13
  163. package/src/server/routes/v1/env.ts +144 -0
  164. package/src/server/routes/v1/events.ts +2 -2
  165. package/src/server/routes/v1/runs.ts +12 -36
  166. package/src/server/sse.ts +7 -2
  167. package/src/server/subscriber.ts +111 -0
  168. package/src/server/ws.ts +38 -4
  169. package/.next/standalone/packages/station-kit/.next/static/chunks/285-ff198f0a909c4fdd.js +0 -1
  170. package/.next/standalone/packages/station-kit/.next/static/chunks/561-33d912169940283e.js +0 -1
  171. package/.next/standalone/packages/station-kit/.next/static/chunks/app/broadcasts/dyn/[name]/v/[n]/page-5eac0507f49a00ec.js +0 -1
  172. package/.next/standalone/packages/station-kit/.next/static/chunks/app/broadcasts/page-dee500ccc01f0821.js +0 -1
  173. package/.next/standalone/packages/station-kit/.next/static/chunks/app/layout-e14e14f3e5b0b8a9.js +0 -1
  174. package/.next/standalone/packages/station-kit/.next/static/chunks/app/page-aac41ef7a470daab.js +0 -1
  175. package/.next/standalone/packages/station-kit/.next/static/chunks/app/playground/expression/page-dc9d91f3f50f4716.js +0 -1
  176. package/.next/standalone/packages/station-kit/.next/static/chunks/app/runs/[id]/page-9e4c4f751a4bea72.js +0 -1
  177. package/.next/standalone/packages/station-kit/.next/static/chunks/app/schedules/page-738d98dc0b63166e.js +0 -1
  178. package/.next/standalone/packages/station-kit/.next/static/chunks/app/settings/page-fc5654b31f57ac21.js +0 -1
  179. package/.next/standalone/packages/station-kit/.next/static/chunks/app/signals/[name]/page-4b1c09a539a1ebcd.js +0 -1
  180. package/.next/standalone/packages/station-kit/.next/static/chunks/app/signals/page-d2f2403dfede87cc.js +0 -1
  181. package/.next/standalone/packages/station-kit/.next/static/css/0be0e65a5f561f37.css +0 -1
  182. package/.next/standalone/packages/station-kit/.next/static/demLiQWDy62JuUkBw-ILG/_buildManifest.js +0 -1
  183. /package/.next/standalone/packages/station-kit/.next/static/{demLiQWDy62JuUkBw-ILG → vTGEzSqxhR_E57YAFn9DC}/_ssgManifest.js +0 -0
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[293],{593:(e,t,n)=>{"use strict";async function a(e,t){let n=await fetch("".concat("","/api").concat(e),{...t,credentials:"include",headers:{"Content-Type":"application/json",...null==t?void 0:t.headers}});if(!n.ok)throw Error((await n.json().catch(()=>({error:"unknown",message:"Request failed."}))).message);return n.json()}async function s(){let e=await fetch("".concat("","/api/auth/check"),{credentials:"include"});return(await e.json()).data}async function r(e,t){return(await fetch("".concat("","/api/auth/login"),{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:e,password:t})})).ok}async function o(){await fetch("".concat("","/api/auth/logout"),{method:"POST",credentials:"include"})}function i(){return{getHealth:()=>a("/health"),getSignals:()=>a("/signals"),getScheduledSignals:()=>a("/signals/scheduled"),getSignal:e=>a("/signals/".concat(encodeURIComponent(e))),getSignalRuns:e=>a("/signals/".concat(encodeURIComponent(e),"/runs")),triggerSignal:(e,t)=>a("/signals/".concat(encodeURIComponent(e),"/trigger"),{method:"POST",body:JSON.stringify({input:null!=t?t:{}})}),getRuns:e=>{let t=new URLSearchParams;(null==e?void 0:e.status)&&t.set("status",e.status),(null==e?void 0:e.signalName)&&t.set("signalName",e.signalName);let n=t.toString();return a("/runs".concat(n?"?".concat(n):""))},getRunStats:()=>a("/runs/stats"),getRun:e=>a("/runs/".concat(e)),getRunSteps:e=>a("/runs/".concat(e,"/steps")),getRunLogs:e=>a("/runs/".concat(e,"/logs")),cancelRun:e=>a("/runs/".concat(e,"/cancel"),{method:"POST"}),rerunRun:e=>a("/runs/".concat(e,"/rerun"),{method:"POST"}),retryRun:e=>a("/runs/".concat(e,"/retry"),{method:"POST"}),getBroadcasts:()=>a("/broadcasts"),getBroadcast:e=>a("/broadcasts/".concat(encodeURIComponent(e))),triggerBroadcast:(e,t)=>a("/broadcasts/".concat(encodeURIComponent(e),"/trigger"),{method:"POST",body:JSON.stringify({input:null!=t?t:{}})}),getBroadcastRuns:e=>a("/broadcasts/".concat(encodeURIComponent(e),"/runs")),getBroadcastRun:e=>a("/broadcast-runs/".concat(e)),getBroadcastRunNodes:e=>a("/broadcast-runs/".concat(e,"/nodes")),getBroadcastRunLogs:e=>a("/broadcast-runs/".concat(e,"/logs")),cancelBroadcastRun:e=>a("/broadcast-runs/".concat(e,"/cancel"),{method:"POST"}),rerunBroadcastRun:e=>a("/broadcast-runs/".concat(e,"/rerun"),{method:"POST"}),getBeacons:()=>a("/beacons"),getBeacon:e=>a("/beacons/".concat(encodeURIComponent(e))),getBeaconEvents:e=>a("/beacons/".concat(encodeURIComponent(e),"/events")),getBeaconLogs:e=>a("/beacons/".concat(encodeURIComponent(e),"/logs")),startBeacon:e=>a("/beacons/".concat(encodeURIComponent(e),"/start"),{method:"POST"}),stopBeacon:e=>a("/beacons/".concat(encodeURIComponent(e),"/stop"),{method:"POST"}),restartBeacon:e=>a("/beacons/".concat(encodeURIComponent(e),"/restart"),{method:"POST"}),getBroadcastDefinitions:()=>a("/v1/broadcast-definitions"),getBroadcastDefinition:e=>a("/v1/broadcast-definitions/".concat(encodeURIComponent(e))),getBroadcastDefinitionVersions:e=>a("/v1/broadcast-definitions/".concat(encodeURIComponent(e),"/versions")),saveBroadcastDefinition:e=>a("/v1/broadcast-definitions",{method:"POST",body:JSON.stringify(e)}),validateBroadcastDefinition:e=>a("/v1/broadcast-definitions/validate",{method:"POST",body:JSON.stringify(e)}),deleteBroadcastDefinition:e=>a("/v1/broadcast-definitions/".concat(encodeURIComponent(e)),{method:"DELETE"}),triggerDynamicBroadcast:(e,t)=>a("/v1/trigger-dynamic-broadcast",{method:"POST",body:JSON.stringify({broadcastName:e,input:null!=t?t:{}})}),getSchedules:e=>{let t=new URLSearchParams;(null==e?void 0:e.kind)&&t.set("kind",e.kind),(null==e?void 0:e.enabled)!==void 0&&t.set("enabled",String(e.enabled));let n=t.toString();return a("/v1/schedules".concat(n?"?".concat(n):""))},getSchedule:e=>a("/v1/schedules/".concat(e)),createSchedule:e=>a("/v1/schedules",{method:"POST",body:JSON.stringify(e)}),updateSchedule:(e,t)=>a("/v1/schedules/".concat(e),{method:"PATCH",body:JSON.stringify(t)}),deleteSchedule:e=>a("/v1/schedules/".concat(e),{method:"DELETE"}),previewSchedule:function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:5;return a("/v1/schedules/".concat(e,"/preview"),{method:"POST",body:JSON.stringify({count:t})})},evaluateExpression:(e,t)=>a("/v1/expressions/evaluate",{method:"POST",body:JSON.stringify({node:e,context:t})}),validateExpression:(e,t)=>a("/v1/expressions/validate",{method:"POST",body:JSON.stringify({node:e,schemaContext:t})}),parseExpression:e=>a("/v1/expressions/parse",{method:"POST",body:JSON.stringify({source:e})}),getEnvVars:()=>a("/v1/env"),createEnvVar:e=>a("/v1/env",{method:"POST",body:JSON.stringify(e)}),updateEnvVar:(e,t)=>a("/v1/env/".concat(e),{method:"PATCH",body:JSON.stringify(t)}),deleteEnvVar:e=>a("/v1/env/".concat(e),{method:"DELETE"}),getApiKeys:()=>a("/v1/keys"),createApiKey:(e,t)=>a("/v1/keys",{method:"POST",body:JSON.stringify({name:e,scopes:t})}),revokeApiKey:e=>a("/v1/keys/".concat(e),{method:"DELETE"})}}n.d(t,{T5:()=>s,gf:()=>i,iD:()=>r,ri:()=>o})},1253:(e,t,n)=>{"use strict";n.d(t,{W:()=>s});var a=n(8111);function s(e){let{status:t}=e;return(0,a.jsxs)("span",{className:"status-badge status-badge--".concat(t),children:[(0,a.jsx)("span",{className:"status-badge-dot"}),t]})}},1794:(e,t,n)=>{"use strict";n.d(t,{p:()=>r});var a=n(8111),s=n(5271);function r(e){let t,{data:n,label:r}=e,[o,i]=(0,s.useState)(!0),[l,c]=(0,s.useState)(!0),[d,u]=(0,s.useState)("copy"),m=(0,s.useCallback)(()=>{if(!n)return;let e=function(e){try{let t=JSON.parse(e);return JSON.stringify(t,null,2)}catch(t){return e}}(n);navigator.clipboard.writeText(e).then(()=>{u("copied"),setTimeout(()=>u("copy"),1500)}).catch(()=>{u("failed"),setTimeout(()=>u("copy"),1500)})},[n]);if(!n)return null;try{t=JSON.parse(n)}catch(e){t=n}let p="object"==typeof t&&null!==t&&JSON.stringify(t).length>200;return(0,a.jsxs)("div",{children:[r&&(0,a.jsxs)("button",{onClick:()=>i(!o),style:{background:"none",border:"none",cursor:"pointer",fontFamily:"var(--font-mono)",fontSize:"0.75rem",color:"var(--muted)",padding:"0.25rem 0",textTransform:"uppercase",letterSpacing:"0.1em"},children:[o?"- ":"+ ",r]}),o&&(0,a.jsxs)("pre",{className:"json-viewer",style:{position:"relative"},children:[(0,a.jsx)("button",{className:"copy-btn",onClick:m,type:"button",children:d}),p&&(0,a.jsx)("button",{onClick:()=>c(!l),style:{position:"absolute",top:"0.5rem",right:"4rem",background:"var(--wire)",border:"none",borderRadius:"3px",padding:"0.25rem 0.5rem",fontFamily:"var(--font-mono)",fontSize:"0.625rem",color:"var(--muted-light)",cursor:"pointer",textTransform:"uppercase",letterSpacing:"0.1em"},type:"button",children:l?"collapse":"expand"}),function e(t,n,s){if(null===t)return(0,a.jsx)("span",{className:"json-null",children:"null"});if("boolean"==typeof t)return(0,a.jsx)("span",{className:"json-boolean",children:String(t)});if("number"==typeof t)return(0,a.jsx)("span",{className:"json-number",children:t});if("string"==typeof t)return(0,a.jsxs)("span",{className:"json-string",children:['"',t,'"']});if(Array.isArray(t))return 0===t.length?(0,a.jsx)("span",{children:"[]"}):!s&&n>3?(0,a.jsxs)("span",{children:["[",t.length," items]"]}):(0,a.jsxs)("span",{children:["[\n",t.map((r,o)=>(0,a.jsxs)("span",{children:[" ".repeat(n+1),e(r,n+1,s),o<t.length-1?",":"","\n"]},o))," ".repeat(n),"]"]});if("object"==typeof t){let r=Object.entries(t);return 0===r.length?(0,a.jsx)("span",{children:"{}"}):!s&&n>3?(0,a.jsx)("span",{children:"{".concat(r.length," keys}")}):(0,a.jsxs)("span",{children:["{\n",r.map((t,o)=>{let[i,l]=t;return(0,a.jsxs)("span",{children:[" ".repeat(n+1),(0,a.jsxs)("span",{className:"json-key",children:['"',i,'"']}),": ",e(l,n+1,s),o<r.length-1?",":"","\n"]},i)})," ".repeat(n),"}"]})}return(0,a.jsx)("span",{children:String(t)})}(t,0,l)]})]})}},3611:(e,t,n)=>{Promise.resolve().then(n.bind(n,9103))},4736:(e,t,n)=>{"use strict";var a=n(1504);n.o(a,"useParams")&&n.d(t,{useParams:function(){return a.useParams}}),n.o(a,"usePathname")&&n.d(t,{usePathname:function(){return a.usePathname}}),n.o(a,"useRouter")&&n.d(t,{useRouter:function(){return a.useRouter}})},7646:(e,t,n)=>{"use strict";n.d(t,{Hc:()=>s,iQ:()=>o,rT:()=>r});var a=n(5271);let s=(0,a.createContext)({segments:[],activeSection:null,setSegments:()=>{},setActiveSection:()=>{}});function r(e,t){let n=(0,a.useContext)(s);(0,a.useEffect)(()=>{n.setSegments(e),n.setActiveSection(t)},[JSON.stringify(e),t])}function o(){return(0,a.useContext)(s)}},9103:(e,t,n)=>{"use strict";n.d(t,{RunDetail:()=>f});var a=n(8111),s=n(5271),r=n(4736),o=n(5935),i=n.n(o),l=n(593),c=n(9275),d=n(7646),u=n(1253),m=n(1794);function p(e){let{step:t}=e,[n,r]=(0,s.useState)(!1),[o,i]=(0,s.useState)(!1),l=!!t.input,c=!!t.output,d=!!t.error;return l||c||d?(0,a.jsxs)("div",{style:{marginTop:"0.5rem"},children:[d&&(0,a.jsx)("div",{className:"error-block",style:{marginBottom:l||c?"0.5rem":0},children:t.error}),l&&(0,a.jsxs)("div",{style:{marginBottom:c?"0.375rem":0},children:[(0,a.jsxs)("button",{onClick:()=>r(!n),style:{background:"none",border:"none",cursor:"pointer",fontFamily:"var(--font-mono)",fontSize:"0.6875rem",color:"var(--muted)",padding:"0.125rem 0",textTransform:"uppercase",letterSpacing:"0.1em"},children:[n?"- ":"+ ","input"]}),n&&(0,a.jsx)(m.p,{data:t.input})]}),c&&(0,a.jsxs)("div",{children:[(0,a.jsxs)("button",{onClick:()=>i(!o),style:{background:"none",border:"none",cursor:"pointer",fontFamily:"var(--font-mono)",fontSize:"0.6875rem",color:"var(--muted)",padding:"0.125rem 0",textTransform:"uppercase",letterSpacing:"0.1em"},children:[o?"- ":"+ ","output"]}),o&&(0,a.jsx)(m.p,{data:t.output})]})]}):null}function h(e){let{steps:t}=e;return 0===t.length?null:(0,a.jsx)("div",{className:"step-timeline",children:t.map((e,t)=>{let n=function(e,t){if(!e)return"";let n=new Date(e).getTime(),a=(t?new Date(t).getTime():Date.now())-n;return a<1e3?"".concat(a,"ms"):a<6e4?"".concat((a/1e3).toFixed(1),"s"):"".concat((a/6e4).toFixed(1),"m")}(e.startedAt,e.completedAt);return(0,a.jsxs)("div",{className:"step-timeline-item reveal-item",style:{animationDelay:"".concat(80*t,"ms")},children:[(0,a.jsx)("div",{className:"step-timeline-dot step-timeline-dot--".concat(e.status)}),(0,a.jsxs)("div",{className:"step-timeline-name",children:[e.name,n&&(0,a.jsx)("span",{style:{marginLeft:"0.5rem",fontFamily:"var(--font-mono)",fontSize:"0.6875rem",color:"var(--muted)"},children:n})]}),(0,a.jsxs)("div",{className:"step-timeline-meta",children:[e.status,e.startedAt&&(0,a.jsx)("span",{style:{marginLeft:"0.375rem",color:"var(--muted-light)"},children:new Date(e.startedAt).toLocaleTimeString()})]}),(0,a.jsx)(p,{step:e})]},e.id)})})}function g(e){return e<1e3?"".concat(e,"ms"):e<6e4?"".concat((e/1e3).toFixed(1),"s"):e<36e5?"".concat((e/6e4).toFixed(1),"m"):"".concat((e/36e5).toFixed(1),"h")}function f(){var e,t;let n=(0,r.useParams)().id,o=(0,r.useRouter)(),p=(0,l.gf)(),{events:f}=(0,c.q)(),[v,x]=(0,s.useState)(null),[b,j]=(0,s.useState)([]),[y,S]=(0,s.useState)([]),[N,R]=(0,s.useState)(!0),[T,O]=(0,s.useState)(!1),[C,w]=(0,s.useState)(!1),[k,P]=(0,s.useState)(!1),[E,B]=(0,s.useState)(!1),D=(0,s.useRef)(null);async function I(){O(!0);try{await p.cancelRun(n);let e=await p.getRun(n);x(e.data)}catch(e){e instanceof Error&&console.error("Cancel failed:",e.message)}O(!1)}async function J(){w(!0);try{let e=await p.rerunRun(n);o.push("/runs/".concat(e.data.id))}catch(e){e instanceof Error&&console.error("Rerun failed:",e.message)}w(!1)}async function A(){P(!0);try{await p.retryRun(n);let e=await p.getRun(n);x(e.data);let t=await p.getRunSteps(n);j(t.data)}catch(e){e instanceof Error&&console.error("Retry failed:",e.message)}P(!1)}if((0,d.rT)(v?[{label:"Signals",href:"/signals"},{label:v.signalName,href:"/signals/".concat(encodeURIComponent(v.signalName))},{label:"Run ".concat(n.slice(0,8))}]:[{label:"Signals",href:"/signals"},{label:"Run ".concat(n.slice(0,8))}],"signals"),(0,s.useEffect)(()=>{!async function(){try{let[e,t,a]=await Promise.all([p.getRun(n),p.getRunSteps(n),p.getRunLogs(n)]);x(e.data),j(t.data),S(a.data)}catch(e){e instanceof Error&&console.error("Failed to load run:",e.message)}R(!1)}()},[n]),(0,s.useEffect)(()=>{var e,t,a;if(0===f.length)return;let s=f[0];(null!=(a=null==(e=s.data.run)?void 0:e.id)?a:null==(t=s.data)?void 0:t.runId)===n&&("log:output"===s.type?S(e=>{var t;return[...e,{runId:s.data.runId,signalName:s.data.signalName,level:s.data.level,message:s.data.message,timestamp:null!=(t=s.data.timestamp)?t:s.timestamp}]}):(p.getRun(n).then(e=>x(e.data)).catch(e=>console.error("Failed to refresh run:",e)),p.getRunSteps(n).then(e=>j(e.data)).catch(e=>console.error("Failed to refresh steps:",e))))},[f.length,n]),(0,s.useEffect)(()=>{var e;null==(e=D.current)||e.scrollIntoView({behavior:"smooth"})},[y.length]),N)return(0,a.jsxs)("div",{children:[(0,a.jsx)("h1",{className:"page-title",children:"Run"}),(0,a.jsx)("div",{className:"loading-bar",children:(0,a.jsx)("div",{className:"loading-bar-fill"})})]});if(!v)return(0,a.jsxs)("div",{children:[(0,a.jsx)("h1",{className:"page-title",children:"Run"}),(0,a.jsx)("div",{className:"empty-state",children:(0,a.jsx)("p",{className:"empty-state-text",children:"Run not found."})})]});let U="pending"===v.status||"running"===v.status,F="failed"===v.status||"completed"===v.status||"cancelled"===v.status,L="failed"===v.status;return(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"page-header",children:[(0,a.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"0.75rem"},children:[(0,a.jsx)(u.W,{status:v.status}),(0,a.jsx)(i(),{href:"/signals/".concat(v.signalName),className:"page-title",style:{marginBottom:0,textDecoration:"none"},children:v.signalName})]}),(0,a.jsxs)("div",{className:"page-header-actions",children:[L&&(0,a.jsx)("button",{className:"btn",onClick:A,disabled:k,children:k?"Retrying...":"Retry"}),F&&(0,a.jsx)("button",{className:"btn btn--primary",onClick:J,disabled:C,children:C?"Rerunning...":"Rerun"}),U&&(0,a.jsx)("button",{className:"btn btn--danger",onClick:I,disabled:T,children:T?"Cancelling...":"Cancel"})]})]}),(0,a.jsxs)("div",{className:"detail-section",children:[(0,a.jsx)("div",{className:"detail-section-label",children:"Metadata"}),(0,a.jsxs)("div",{className:"detail-grid",children:[(0,a.jsx)("span",{className:"detail-label",children:"ID"}),(0,a.jsxs)("span",{className:"detail-value mono",style:{display:"flex",alignItems:"center",gap:"0.5rem"},children:[v.id,(0,a.jsx)("button",{onClick:function(){navigator.clipboard.writeText(v.id).then(()=>{B(!0),setTimeout(()=>B(!1),1500)}).catch(()=>{})},className:"btn btn--sm",style:{fontSize:"0.625rem",padding:"0.125rem 0.375rem",lineHeight:1.2},children:E?"copied":"copy"})]}),(0,a.jsx)("span",{className:"detail-label",children:"Signal"}),(0,a.jsx)("span",{className:"detail-value",children:(0,a.jsx)(i(),{href:"/signals/".concat(v.signalName),className:"mono meta-value--link",children:v.signalName})}),(0,a.jsx)("span",{className:"detail-label",children:"Kind"}),(0,a.jsx)("span",{className:"detail-value",children:v.kind}),(0,a.jsx)("span",{className:"detail-label",children:"Attempts"}),(0,a.jsxs)("span",{className:"detail-value",children:[v.attempts," of ",v.maxAttempts]}),(0,a.jsx)("span",{className:"detail-label",children:"Timeout"}),(0,a.jsx)("span",{className:"detail-value mono",children:v.timeout?g(v.timeout):"—"}),(0,a.jsx)("span",{className:"detail-label",children:"Duration"}),(0,a.jsx)("span",{className:"detail-value mono",children:function(e,t){if(!e)return"—";let n=new Date(e).getTime();return g((t?new Date(t).getTime():Date.now())-n)}(v.startedAt,v.completedAt)}),(0,a.jsx)("span",{className:"detail-label",children:"Created"}),(0,a.jsx)("span",{className:"detail-value mono",children:v.createdAt}),(0,a.jsx)("span",{className:"detail-label",children:"Started"}),(0,a.jsx)("span",{className:"detail-value mono",children:null!=(e=v.startedAt)?e:"—"}),(0,a.jsx)("span",{className:"detail-label",children:"Completed"}),(0,a.jsx)("span",{className:"detail-value mono",children:null!=(t=v.completedAt)?t:"—"})]})]}),v.error&&(0,a.jsxs)("div",{className:"detail-section",children:[(0,a.jsx)("div",{className:"detail-section-label",children:"Error"}),(0,a.jsx)("div",{className:"error-block",children:v.error})]}),(0,a.jsxs)("div",{className:"detail-section",children:[(0,a.jsx)("div",{className:"detail-section-label",children:"Input"}),(0,a.jsx)(m.p,{data:v.input})]}),v.output&&(0,a.jsxs)("div",{className:"detail-section",children:[(0,a.jsx)("div",{className:"detail-section-label",children:"Output"}),(0,a.jsx)(m.p,{data:v.output})]}),b.length>0&&(0,a.jsxs)("div",{className:"detail-section",children:[(0,a.jsx)("div",{className:"detail-section-label",children:"Steps"}),(0,a.jsx)(h,{steps:b})]}),(0,a.jsxs)("div",{className:"detail-section",children:[(0,a.jsx)("div",{className:"detail-section-label",children:"Logs"}),(0,a.jsxs)("div",{className:"log-container",children:[0===y.length?(0,a.jsx)("div",{style:{padding:"1rem",color:"var(--muted)",fontFamily:"var(--font-mono)",fontSize:"0.75rem"},children:"pending"===v.status?"Waiting for execution...":"No log output captured."}):y.map((e,t)=>(0,a.jsxs)("div",{className:"log-line",style:{color:"stderr"===e.level?"var(--rust)":"var(--charcoal)"},children:[(0,a.jsx)("span",{className:"log-timestamp",children:new Date(e.timestamp).toLocaleTimeString()}),(0,a.jsx)("span",{className:"log-level","data-level":e.level,children:"stderr"===e.level?"ERR":"OUT"}),(0,a.jsx)("span",{className:"log-message",children:e.message})]},t)),(0,a.jsx)("div",{ref:D})]})]})]})}},9275:(e,t,n)=>{"use strict";n.d(t,{StationProvider:()=>i,q:()=>o});var a=n(8111),s=n(5271);let r=(0,s.createContext)({connected:!1,events:[]});function o(){return(0,s.useContext)(r)}function i(e){let{children:t}=e,[n,o]=(0,s.useState)([]),{connected:i}=function(e){let[t,n]=(0,s.useState)(!1),a=(0,s.useRef)(e);return a.current=e,(0,s.useEffect)(()=>{let e=null,t=null,s=0,r=!1;return!function o(){if(r)return;let i="https:"===window.location.protocol?"wss:":"ws:";(e=new WebSocket("".concat(i,"//").concat(window.location.host,"/api/events"))).onopen=()=>{n(!0),s=0},e.onmessage=e=>{try{let t=JSON.parse(e.data);a.current(t)}catch(e){console.error("Failed to parse WebSocket message:",e)}},e.onclose=()=>{if(n(!1),!r){let e=Math.min(1e3*Math.pow(2,s),1e4);s++,t=setTimeout(o,e)}},e.onerror=()=>{null==e||e.close()}}(),()=>{r=!0,t&&clearTimeout(t),null==e||e.close()}},[]),{connected:t}}((0,s.useCallback)(e=>{o(t=>[e,...t].slice(0,100))},[]));return(0,a.jsx)(r.Provider,{value:{connected:i,events:n},children:t})}}},e=>{e.O(0,[935,814,743,358],()=>e(e.s=3611)),_N_E=e.O()}]);
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[547],{593:(e,t,n)=>{"use strict";async function a(e,t){let n=await fetch("".concat("","/api").concat(e),{...t,credentials:"include",headers:{"Content-Type":"application/json",...null==t?void 0:t.headers}});if(!n.ok)throw Error((await n.json().catch(()=>({error:"unknown",message:"Request failed."}))).message);return n.json()}async function s(){let e=await fetch("".concat("","/api/auth/check"),{credentials:"include"});return(await e.json()).data}async function o(e,t){return(await fetch("".concat("","/api/auth/login"),{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:e,password:t})})).ok}async function r(){await fetch("".concat("","/api/auth/logout"),{method:"POST",credentials:"include"})}function c(){return{getHealth:()=>a("/health"),getSignals:()=>a("/signals"),getScheduledSignals:()=>a("/signals/scheduled"),getSignal:e=>a("/signals/".concat(encodeURIComponent(e))),getSignalRuns:e=>a("/signals/".concat(encodeURIComponent(e),"/runs")),triggerSignal:(e,t)=>a("/signals/".concat(encodeURIComponent(e),"/trigger"),{method:"POST",body:JSON.stringify({input:null!=t?t:{}})}),getRuns:e=>{let t=new URLSearchParams;(null==e?void 0:e.status)&&t.set("status",e.status),(null==e?void 0:e.signalName)&&t.set("signalName",e.signalName);let n=t.toString();return a("/runs".concat(n?"?".concat(n):""))},getRunStats:()=>a("/runs/stats"),getRun:e=>a("/runs/".concat(e)),getRunSteps:e=>a("/runs/".concat(e,"/steps")),getRunLogs:e=>a("/runs/".concat(e,"/logs")),cancelRun:e=>a("/runs/".concat(e,"/cancel"),{method:"POST"}),rerunRun:e=>a("/runs/".concat(e,"/rerun"),{method:"POST"}),retryRun:e=>a("/runs/".concat(e,"/retry"),{method:"POST"}),getBroadcasts:()=>a("/broadcasts"),getBroadcast:e=>a("/broadcasts/".concat(encodeURIComponent(e))),triggerBroadcast:(e,t)=>a("/broadcasts/".concat(encodeURIComponent(e),"/trigger"),{method:"POST",body:JSON.stringify({input:null!=t?t:{}})}),getBroadcastRuns:e=>a("/broadcasts/".concat(encodeURIComponent(e),"/runs")),getBroadcastRun:e=>a("/broadcast-runs/".concat(e)),getBroadcastRunNodes:e=>a("/broadcast-runs/".concat(e,"/nodes")),getBroadcastRunLogs:e=>a("/broadcast-runs/".concat(e,"/logs")),cancelBroadcastRun:e=>a("/broadcast-runs/".concat(e,"/cancel"),{method:"POST"}),rerunBroadcastRun:e=>a("/broadcast-runs/".concat(e,"/rerun"),{method:"POST"}),getBeacons:()=>a("/beacons"),getBeacon:e=>a("/beacons/".concat(encodeURIComponent(e))),getBeaconEvents:e=>a("/beacons/".concat(encodeURIComponent(e),"/events")),getBeaconLogs:e=>a("/beacons/".concat(encodeURIComponent(e),"/logs")),startBeacon:e=>a("/beacons/".concat(encodeURIComponent(e),"/start"),{method:"POST"}),stopBeacon:e=>a("/beacons/".concat(encodeURIComponent(e),"/stop"),{method:"POST"}),restartBeacon:e=>a("/beacons/".concat(encodeURIComponent(e),"/restart"),{method:"POST"}),getBroadcastDefinitions:()=>a("/v1/broadcast-definitions"),getBroadcastDefinition:e=>a("/v1/broadcast-definitions/".concat(encodeURIComponent(e))),getBroadcastDefinitionVersions:e=>a("/v1/broadcast-definitions/".concat(encodeURIComponent(e),"/versions")),saveBroadcastDefinition:e=>a("/v1/broadcast-definitions",{method:"POST",body:JSON.stringify(e)}),validateBroadcastDefinition:e=>a("/v1/broadcast-definitions/validate",{method:"POST",body:JSON.stringify(e)}),deleteBroadcastDefinition:e=>a("/v1/broadcast-definitions/".concat(encodeURIComponent(e)),{method:"DELETE"}),triggerDynamicBroadcast:(e,t)=>a("/v1/trigger-dynamic-broadcast",{method:"POST",body:JSON.stringify({broadcastName:e,input:null!=t?t:{}})}),getSchedules:e=>{let t=new URLSearchParams;(null==e?void 0:e.kind)&&t.set("kind",e.kind),(null==e?void 0:e.enabled)!==void 0&&t.set("enabled",String(e.enabled));let n=t.toString();return a("/v1/schedules".concat(n?"?".concat(n):""))},getSchedule:e=>a("/v1/schedules/".concat(e)),createSchedule:e=>a("/v1/schedules",{method:"POST",body:JSON.stringify(e)}),updateSchedule:(e,t)=>a("/v1/schedules/".concat(e),{method:"PATCH",body:JSON.stringify(t)}),deleteSchedule:e=>a("/v1/schedules/".concat(e),{method:"DELETE"}),previewSchedule:function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:5;return a("/v1/schedules/".concat(e,"/preview"),{method:"POST",body:JSON.stringify({count:t})})},evaluateExpression:(e,t)=>a("/v1/expressions/evaluate",{method:"POST",body:JSON.stringify({node:e,context:t})}),validateExpression:(e,t)=>a("/v1/expressions/validate",{method:"POST",body:JSON.stringify({node:e,schemaContext:t})}),parseExpression:e=>a("/v1/expressions/parse",{method:"POST",body:JSON.stringify({source:e})}),getEnvVars:()=>a("/v1/env"),createEnvVar:e=>a("/v1/env",{method:"POST",body:JSON.stringify(e)}),updateEnvVar:(e,t)=>a("/v1/env/".concat(e),{method:"PATCH",body:JSON.stringify(t)}),deleteEnvVar:e=>a("/v1/env/".concat(e),{method:"DELETE"}),getApiKeys:()=>a("/v1/keys"),createApiKey:(e,t)=>a("/v1/keys",{method:"POST",body:JSON.stringify({name:e,scopes:t})}),revokeApiKey:e=>a("/v1/keys/".concat(e),{method:"DELETE"})}}n.d(t,{T5:()=>s,gf:()=>c,iD:()=>o,ri:()=>r})},3562:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>m});var a=n(8111),s=n(5271),o=n(5935),r=n.n(o),c=n(4736),i=n(593),d=n(7646),l=n(6990);let u={signal:"Signal","broadcast-static":"Broadcast (file)","broadcast-dynamic":"Broadcast (dynamic)"};function m(){let e=(0,i.gf)(),t=(0,c.useRouter)(),[n,o]=(0,s.useState)([]),[m,h]=(0,s.useState)(!0),[g,p]=(0,s.useState)(null);return((0,d.rT)([{label:"Schedules"}],"schedules"),(0,s.useEffect)(()=>{e.getSchedules().then(e=>o(e.data)).catch(e=>p(e instanceof Error?e.message:String(e))).finally(()=>h(!1))},[]),m)?(0,a.jsxs)("div",{children:[(0,a.jsx)("h1",{className:"page-title",children:"Schedules"}),(0,a.jsx)("div",{className:"loading-bar",children:(0,a.jsx)("div",{className:"loading-bar-fill"})})]}):(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"1rem"},children:[(0,a.jsx)("h1",{className:"page-title",style:{margin:0},children:"Schedules"}),(0,a.jsx)(r(),{href:"/schedules/new",className:"btn btn--primary",children:"+ New schedule"})]}),g&&(0,a.jsx)("div",{style:{marginBottom:"1rem",padding:"0.625rem 0.75rem",background:"var(--error-bg, #fee)",color:"var(--error, #b00)",borderRadius:"4px",fontSize:"0.8125rem"},children:g}),0===n.length?(0,a.jsx)("div",{className:"empty-state",children:(0,a.jsxs)("p",{className:"empty-state-text",children:["No schedules yet. ",(0,a.jsx)(r(),{href:"/schedules/new",children:"Create one"})," to fire signals or broadcasts on intervals."]})}):(0,a.jsxs)("table",{className:"station-table",children:[(0,a.jsx)("thead",{children:(0,a.jsxs)("tr",{children:[(0,a.jsx)("th",{children:"Target"}),(0,a.jsx)("th",{children:"Kind"}),(0,a.jsx)("th",{children:"Interval"}),(0,a.jsx)("th",{children:"Next run"}),(0,a.jsx)("th",{children:"Last run"}),(0,a.jsx)("th",{children:"Status"}),(0,a.jsx)("th",{})]})}),(0,a.jsx)("tbody",{children:n.map(e=>(0,a.jsxs)("tr",{className:"clickable-row",onClick:()=>t.push("/schedules/".concat(e.id)),children:[(0,a.jsx)("td",{className:"mono",children:e.target}),(0,a.jsx)("td",{className:"mono",style:{fontSize:"0.75rem",color:"var(--muted)"},children:u[e.kind]}),(0,a.jsx)("td",{className:"mono",children:e.interval}),(0,a.jsx)("td",{className:"mono",style:{fontSize:"0.75rem",color:"var(--muted)"},children:new Date(e.nextRunAt).toLocaleString()}),(0,a.jsx)("td",{className:"mono",style:{fontSize:"0.75rem",color:"var(--muted)"},children:e.lastRunAt?new Date(e.lastRunAt).toLocaleString():"—"}),(0,a.jsx)("td",{className:"mono",style:{fontSize:"0.75rem"},children:(0,a.jsx)("span",{style:{padding:"0.125rem 0.375rem",borderRadius:"3px",background:e.enabled?"var(--success-bg, #efe)":"var(--surface)",color:e.enabled?"var(--success, #060)":"var(--muted)"},children:e.enabled?"enabled":"disabled"})}),(0,a.jsx)("td",{})]},e.id))})]}),(0,a.jsx)(l.F,{title:"List & manage schedules",snippets:[{label:"List all",method:"GET",path:"/api/v1/schedules"},{label:"List by kind",method:"GET",path:"/api/v1/schedules",query:{kind:"signal"}},{label:"Create",method:"POST",path:"/api/v1/schedules",body:{kind:"signal",target:"<signalName>",interval:"5m",enabled:!0,input:{}}}]})]})}},4736:(e,t,n)=>{"use strict";var a=n(1504);n.o(a,"useParams")&&n.d(t,{useParams:function(){return a.useParams}}),n.o(a,"usePathname")&&n.d(t,{usePathname:function(){return a.usePathname}}),n.o(a,"useRouter")&&n.d(t,{useRouter:function(){return a.useRouter}})},6990:(e,t,n)=>{"use strict";n.d(t,{F:()=>o});var a=n(8111),s=n(5271);function o(e){let{title:t="API equivalent",snippets:n}=e,[o,r]=(0,s.useState)(!1),[c,i]=(0,s.useState)(null),[d,l]=(0,s.useState)(null);if(0===n.length)return null;async function u(e,t){try{var n;if(null==(n=navigator.clipboard)?void 0:n.writeText){await navigator.clipboard.writeText(e),i(t),setTimeout(()=>i(e=>e===t?null:e),1500);return}throw Error("clipboard API unavailable")}catch(n){try{let n=document.createElement("textarea");n.value=e,n.style.position="fixed",n.style.left="-9999px",document.body.appendChild(n),n.select();let a=document.execCommand("copy");if(document.body.removeChild(n),a)i(t),setTimeout(()=>i(e=>e===t?null:e),1500);else throw Error("execCommand copy returned false")}catch(e){l(t),setTimeout(()=>l(e=>e===t?null:e),2e3)}}}return(0,a.jsxs)("details",{open:o,onToggle:e=>r(e.target.open),style:{marginTop:"1.5rem",border:"1px solid var(--border)",borderRadius:"4px",background:"var(--surface)"},children:[(0,a.jsxs)("summary",{style:{padding:"0.5rem 0.75rem",fontSize:"0.75rem",fontFamily:"var(--mono-font, monospace)",color:"var(--muted)",textTransform:"uppercase",letterSpacing:"0.05em",cursor:"pointer",listStyle:"none"},children:["▸ ",t]}),(0,a.jsx)("div",{style:{padding:"0.5rem 0.75rem 0.75rem"},children:n.map((e,t)=>{let s=function(e){var t;let n=[];if(e.query)for(let[t,a]of Object.entries(e.query))void 0!==a&&n.push("".concat(encodeURIComponent(t),"=").concat(encodeURIComponent(String(a))));let a="".concat(e.path).concat(n.length?"?".concat(n.join("&")):""),s=(null==(t=window.location)?void 0:t.origin)?window.location.origin:"https://your-station.example.com",o=[];if(o.push("curl -X ".concat(e.method," \\")),o.push(" ".concat(s).concat(a," \\")),o.push(" -H 'Authorization: Bearer sk_live_…' \\"),void 0!==e.body){o.push(" -H 'Content-Type: application/json' \\");let t="string"==typeof e.body?e.body:JSON.stringify(e.body,null,2);o.push(" -d ".concat(JSON.stringify(t)))}else o[o.length-1]=o[o.length-1].replace(/ \\$/,"");return o.join("\n")}(e);return(0,a.jsxs)("div",{style:{marginBottom:t===n.length-1?0:"0.75rem"},children:[(0,a.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"0.25rem"},children:[(0,a.jsx)("div",{className:"mono",style:{fontSize:"0.75rem",color:"var(--muted)"},children:e.label}),(0,a.jsx)("button",{type:"button",className:"btn btn--sm",onClick:()=>u(s,t),title:d===t?"Copy failed — select the text manually":"",children:c===t?"Copied":d===t?"Copy failed":"Copy"})]}),(0,a.jsx)("pre",{className:"mono",style:{margin:0,padding:"0.5rem 0.75rem",background:"var(--bg, #fff)",border:"1px solid var(--border)",borderRadius:"4px",fontSize:"0.75rem",overflowX:"auto",whiteSpace:"pre"},children:s})]},t)})})]})}},7646:(e,t,n)=>{"use strict";n.d(t,{Hc:()=>s,iQ:()=>r,rT:()=>o});var a=n(5271);let s=(0,a.createContext)({segments:[],activeSection:null,setSegments:()=>{},setActiveSection:()=>{}});function o(e,t){let n=(0,a.useContext)(s);(0,a.useEffect)(()=>{n.setSegments(e),n.setActiveSection(t)},[JSON.stringify(e),t])}function r(){return(0,a.useContext)(s)}},9503:(e,t,n)=>{Promise.resolve().then(n.bind(n,3562))}},e=>{e.O(0,[935,814,743,358],()=>e(e.s=9503)),_N_E=e.O()}]);
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[662],{593:(e,t,n)=>{"use strict";async function a(e,t){let n=await fetch("".concat("","/api").concat(e),{...t,credentials:"include",headers:{"Content-Type":"application/json",...null==t?void 0:t.headers}});if(!n.ok)throw Error((await n.json().catch(()=>({error:"unknown",message:"Request failed."}))).message);return n.json()}async function s(){let e=await fetch("".concat("","/api/auth/check"),{credentials:"include"});return(await e.json()).data}async function o(e,t){return(await fetch("".concat("","/api/auth/login"),{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:e,password:t})})).ok}async function r(){await fetch("".concat("","/api/auth/logout"),{method:"POST",credentials:"include"})}function i(){return{getHealth:()=>a("/health"),getSignals:()=>a("/signals"),getScheduledSignals:()=>a("/signals/scheduled"),getSignal:e=>a("/signals/".concat(encodeURIComponent(e))),getSignalRuns:e=>a("/signals/".concat(encodeURIComponent(e),"/runs")),triggerSignal:(e,t)=>a("/signals/".concat(encodeURIComponent(e),"/trigger"),{method:"POST",body:JSON.stringify({input:null!=t?t:{}})}),getRuns:e=>{let t=new URLSearchParams;(null==e?void 0:e.status)&&t.set("status",e.status),(null==e?void 0:e.signalName)&&t.set("signalName",e.signalName);let n=t.toString();return a("/runs".concat(n?"?".concat(n):""))},getRunStats:()=>a("/runs/stats"),getRun:e=>a("/runs/".concat(e)),getRunSteps:e=>a("/runs/".concat(e,"/steps")),getRunLogs:e=>a("/runs/".concat(e,"/logs")),cancelRun:e=>a("/runs/".concat(e,"/cancel"),{method:"POST"}),rerunRun:e=>a("/runs/".concat(e,"/rerun"),{method:"POST"}),retryRun:e=>a("/runs/".concat(e,"/retry"),{method:"POST"}),getBroadcasts:()=>a("/broadcasts"),getBroadcast:e=>a("/broadcasts/".concat(encodeURIComponent(e))),triggerBroadcast:(e,t)=>a("/broadcasts/".concat(encodeURIComponent(e),"/trigger"),{method:"POST",body:JSON.stringify({input:null!=t?t:{}})}),getBroadcastRuns:e=>a("/broadcasts/".concat(encodeURIComponent(e),"/runs")),getBroadcastRun:e=>a("/broadcast-runs/".concat(e)),getBroadcastRunNodes:e=>a("/broadcast-runs/".concat(e,"/nodes")),getBroadcastRunLogs:e=>a("/broadcast-runs/".concat(e,"/logs")),cancelBroadcastRun:e=>a("/broadcast-runs/".concat(e,"/cancel"),{method:"POST"}),rerunBroadcastRun:e=>a("/broadcast-runs/".concat(e,"/rerun"),{method:"POST"}),getBeacons:()=>a("/beacons"),getBeacon:e=>a("/beacons/".concat(encodeURIComponent(e))),getBeaconEvents:e=>a("/beacons/".concat(encodeURIComponent(e),"/events")),getBeaconLogs:e=>a("/beacons/".concat(encodeURIComponent(e),"/logs")),startBeacon:e=>a("/beacons/".concat(encodeURIComponent(e),"/start"),{method:"POST"}),stopBeacon:e=>a("/beacons/".concat(encodeURIComponent(e),"/stop"),{method:"POST"}),restartBeacon:e=>a("/beacons/".concat(encodeURIComponent(e),"/restart"),{method:"POST"}),getBroadcastDefinitions:()=>a("/v1/broadcast-definitions"),getBroadcastDefinition:e=>a("/v1/broadcast-definitions/".concat(encodeURIComponent(e))),getBroadcastDefinitionVersions:e=>a("/v1/broadcast-definitions/".concat(encodeURIComponent(e),"/versions")),saveBroadcastDefinition:e=>a("/v1/broadcast-definitions",{method:"POST",body:JSON.stringify(e)}),validateBroadcastDefinition:e=>a("/v1/broadcast-definitions/validate",{method:"POST",body:JSON.stringify(e)}),deleteBroadcastDefinition:e=>a("/v1/broadcast-definitions/".concat(encodeURIComponent(e)),{method:"DELETE"}),triggerDynamicBroadcast:(e,t)=>a("/v1/trigger-dynamic-broadcast",{method:"POST",body:JSON.stringify({broadcastName:e,input:null!=t?t:{}})}),getSchedules:e=>{let t=new URLSearchParams;(null==e?void 0:e.kind)&&t.set("kind",e.kind),(null==e?void 0:e.enabled)!==void 0&&t.set("enabled",String(e.enabled));let n=t.toString();return a("/v1/schedules".concat(n?"?".concat(n):""))},getSchedule:e=>a("/v1/schedules/".concat(e)),createSchedule:e=>a("/v1/schedules",{method:"POST",body:JSON.stringify(e)}),updateSchedule:(e,t)=>a("/v1/schedules/".concat(e),{method:"PATCH",body:JSON.stringify(t)}),deleteSchedule:e=>a("/v1/schedules/".concat(e),{method:"DELETE"}),previewSchedule:function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:5;return a("/v1/schedules/".concat(e,"/preview"),{method:"POST",body:JSON.stringify({count:t})})},evaluateExpression:(e,t)=>a("/v1/expressions/evaluate",{method:"POST",body:JSON.stringify({node:e,context:t})}),validateExpression:(e,t)=>a("/v1/expressions/validate",{method:"POST",body:JSON.stringify({node:e,schemaContext:t})}),parseExpression:e=>a("/v1/expressions/parse",{method:"POST",body:JSON.stringify({source:e})}),getEnvVars:()=>a("/v1/env"),createEnvVar:e=>a("/v1/env",{method:"POST",body:JSON.stringify(e)}),updateEnvVar:(e,t)=>a("/v1/env/".concat(e),{method:"PATCH",body:JSON.stringify(t)}),deleteEnvVar:e=>a("/v1/env/".concat(e),{method:"DELETE"}),getApiKeys:()=>a("/v1/keys"),createApiKey:(e,t)=>a("/v1/keys",{method:"POST",body:JSON.stringify({name:e,scopes:t})}),revokeApiKey:e=>a("/v1/keys/".concat(e),{method:"DELETE"})}}n.d(t,{T5:()=>s,gf:()=>i,iD:()=>o,ri:()=>r})},4521:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var a=n(8111),s=n(5271),o=n(593),r=n(7646);let i=["trigger","read","cancel","admin"];function c(e){return new Date(e).toLocaleDateString(void 0,{month:"short",day:"numeric",year:"numeric"})}function l(){let e=(0,o.gf)(),[t,n]=(0,s.useState)([]),[l,d]=(0,s.useState)(!0),[m,u]=(0,s.useState)(null),[h,g]=(0,s.useState)(!1),[y,f]=(0,s.useState)(""),[p,v]=(0,s.useState)(["trigger","read"]),[b,S]=(0,s.useState)(!1),[x,j]=(0,s.useState)(null),[N,C]=(0,s.useState)(!1),[k,O]=(0,s.useState)(null);(0,r.rT)([{label:"Settings"}],"settings");let R=(0,s.useCallback)(()=>{e.getApiKeys().then(e=>{n(e.data),u(null)}).catch(e=>{e instanceof Error&&u(e.message)}).finally(()=>d(!1))},[]);async function T(){if(y.trim()){S(!0);try{let t=await e.createApiKey(y.trim(),p);j(t.data.key),f(""),v(["trigger","read"]),g(!1),C(!1),R()}catch(e){e instanceof Error&&u(e.message)}S(!1)}}async function w(t){try{await e.revokeApiKey(t),O(null),R()}catch(e){e instanceof Error&&u(e.message)}}async function B(){x&&(await navigator.clipboard.writeText(x),C(!0),setTimeout(()=>C(!1),2e3))}if((0,s.useEffect)(()=>{R()},[R]),l)return(0,a.jsxs)("div",{children:[(0,a.jsx)("h1",{className:"page-title",children:"Settings"}),(0,a.jsx)("div",{className:"loading-bar",children:(0,a.jsx)("div",{className:"loading-bar-fill"})})]});let P=t.filter(e=>!e.revoked),E=t.filter(e=>e.revoked);return(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"page-header",children:(0,a.jsx)("h1",{className:"page-title",style:{marginBottom:0},children:"Settings"})}),m&&(0,a.jsx)("div",{className:"detail-section",style:{color:"var(--rust)",fontSize:"0.8125rem"},children:m}),x&&(0,a.jsxs)("div",{className:"detail-section",style:{background:"var(--patina)",color:"#fff",borderRadius:"6px",padding:"1rem 1.25rem",marginBottom:"1.5rem"},children:[(0,a.jsx)("div",{style:{fontSize:"0.8125rem",fontWeight:500,marginBottom:"0.5rem"},children:"Key created. Copy it now — it won't be shown again."}),(0,a.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"0.75rem"},children:[(0,a.jsx)("code",{style:{fontFamily:"var(--font-mono)",fontSize:"0.8125rem",background:"rgba(0,0,0,0.2)",padding:"0.375rem 0.625rem",borderRadius:"4px",flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:x}),(0,a.jsx)("button",{className:"btn btn--primary",onClick:B,style:{flexShrink:0,minWidth:"5rem"},children:N?"Copied":"Copy"}),(0,a.jsx)("button",{className:"btn",onClick:()=>j(null),style:{flexShrink:0,color:"#fff",borderColor:"rgba(255,255,255,0.4)"},children:"Dismiss"})]})]}),(0,a.jsxs)("div",{className:"detail-section",children:[(0,a.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"1rem"},children:[(0,a.jsx)("div",{className:"detail-section-label",style:{marginBottom:0},children:"API Keys"}),(0,a.jsx)("button",{className:"btn btn--primary",onClick:()=>g(!h),children:h?"Cancel":"Create key"})]}),h&&(0,a.jsxs)("div",{style:{border:"1px solid var(--concrete-dark)",borderRadius:"6px",padding:"1rem",marginBottom:"1rem"},children:[(0,a.jsxs)("div",{style:{marginBottom:"0.75rem"},children:[(0,a.jsx)("label",{style:{display:"block",fontSize:"0.75rem",color:"var(--muted)",marginBottom:"0.25rem",fontFamily:"var(--font-mono)",textTransform:"uppercase",letterSpacing:"0.08em"},children:"Name"}),(0,a.jsx)("input",{type:"text",value:y,onChange:e=>f(e.target.value),placeholder:"e.g. Production App",style:{width:"100%",padding:"0.5rem 0.625rem",fontFamily:"var(--font-body)",fontSize:"0.875rem",border:"1px solid var(--concrete-dark)",borderRadius:"4px",background:"var(--surface)",color:"var(--charcoal)"}})]}),(0,a.jsxs)("div",{style:{marginBottom:"0.75rem"},children:[(0,a.jsx)("label",{style:{display:"block",fontSize:"0.75rem",color:"var(--muted)",marginBottom:"0.5rem",fontFamily:"var(--font-mono)",textTransform:"uppercase",letterSpacing:"0.08em"},children:"Scopes"}),(0,a.jsx)("div",{style:{display:"flex",gap:"0.5rem",flexWrap:"wrap"},children:i.map(e=>(0,a.jsx)("button",{onClick:()=>{v(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e])},className:"filter-btn".concat(p.includes(e)?" filter-btn--active":""),children:e},e))})]}),(0,a.jsx)("button",{className:"btn btn--primary",onClick:T,disabled:b||!y.trim()||0===p.length,children:b?"Creating...":"Create"})]}),0!==P.length||h?P.length>0?(0,a.jsxs)("table",{className:"station-table",children:[(0,a.jsx)("thead",{children:(0,a.jsxs)("tr",{children:[(0,a.jsx)("th",{children:"Name"}),(0,a.jsx)("th",{children:"Key"}),(0,a.jsx)("th",{children:"Scopes"}),(0,a.jsx)("th",{children:"Created"}),(0,a.jsx)("th",{children:"Last used"}),(0,a.jsx)("th",{})]})}),(0,a.jsx)("tbody",{children:P.map((e,t)=>(0,a.jsxs)("tr",{className:"reveal-item",style:{animationDelay:"".concat(40*t,"ms")},children:[(0,a.jsx)("td",{style:{fontWeight:500},children:e.name}),(0,a.jsxs)("td",{className:"mono",style:{color:"var(--muted)",fontSize:"0.8125rem"},children:[e.keyPrefix,"..."]}),(0,a.jsx)("td",{children:(0,a.jsx)("div",{style:{display:"flex",gap:"0.25rem",flexWrap:"wrap"},children:e.scopes.map(e=>(0,a.jsx)("span",{style:{fontSize:"0.6875rem",fontFamily:"var(--font-mono)",padding:"0.125rem 0.375rem",borderRadius:"3px",background:"var(--concrete-dark)",color:"var(--muted)"},children:e},e))})}),(0,a.jsx)("td",{style:{fontSize:"0.8125rem",color:"var(--muted)"},children:c(e.createdAt)}),(0,a.jsx)("td",{style:{fontSize:"0.8125rem",color:"var(--muted)"},children:e.lastUsed?function(e){let t=Date.now()-new Date(e).getTime();return t<6e4?"just now":t<36e5?"".concat(Math.floor(t/6e4),"m ago"):t<864e5?"".concat(Math.floor(t/36e5),"h ago"):"".concat(Math.floor(t/864e5),"d ago")}(e.lastUsed):"Never"}),(0,a.jsx)("td",{children:k===e.id?(0,a.jsxs)("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center"},children:[(0,a.jsx)("button",{className:"btn",onClick:()=>w(e.id),style:{color:"var(--rust)",borderColor:"var(--rust)",fontSize:"0.75rem"},children:"Confirm"}),(0,a.jsx)("button",{className:"btn",onClick:()=>O(null),style:{fontSize:"0.75rem"},children:"Cancel"})]}):(0,a.jsx)("button",{className:"btn",onClick:()=>O(e.id),style:{fontSize:"0.75rem",color:"var(--muted)"},children:"Revoke"})})]},e.id))})]}):null:(0,a.jsx)("div",{className:"empty-state",children:(0,a.jsx)("p",{className:"empty-state-text",children:"No API keys. Create one to enable remote triggers."})}),E.length>0&&(0,a.jsxs)("div",{style:{marginTop:"1.5rem"},children:[(0,a.jsx)("div",{className:"detail-section-label",style:{color:"var(--muted)",fontSize:"0.6875rem"},children:"Revoked"}),(0,a.jsx)("table",{className:"station-table",style:{opacity:.5},children:(0,a.jsx)("tbody",{children:E.map(e=>(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{style:{textDecoration:"line-through"},children:e.name}),(0,a.jsxs)("td",{className:"mono",style:{color:"var(--muted)",fontSize:"0.8125rem"},children:[e.keyPrefix,"..."]}),(0,a.jsx)("td",{style:{fontSize:"0.8125rem",color:"var(--muted)"},children:c(e.createdAt)})]},e.id))})})]})]})]})}},7646:(e,t,n)=>{"use strict";n.d(t,{Hc:()=>s,iQ:()=>r,rT:()=>o});var a=n(5271);let s=(0,a.createContext)({segments:[],activeSection:null,setSegments:()=>{},setActiveSection:()=>{}});function o(e,t){let n=(0,a.useContext)(s);(0,a.useEffect)(()=>{n.setSegments(e),n.setActiveSection(t)},[JSON.stringify(e),t])}function r(){return(0,a.useContext)(s)}},9612:(e,t,n)=>{Promise.resolve().then(n.bind(n,4521))}},e=>{e.O(0,[814,743,358],()=>e(e.s=9612)),_N_E=e.O()}]);
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[80],{593:(e,t,n)=>{"use strict";async function a(e,t){let n=await fetch("".concat("","/api").concat(e),{...t,credentials:"include",headers:{"Content-Type":"application/json",...null==t?void 0:t.headers}});if(!n.ok)throw Error((await n.json().catch(()=>({error:"unknown",message:"Request failed."}))).message);return n.json()}async function s(){let e=await fetch("".concat("","/api/auth/check"),{credentials:"include"});return(await e.json()).data}async function c(e,t){return(await fetch("".concat("","/api/auth/login"),{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:e,password:t})})).ok}async function r(){await fetch("".concat("","/api/auth/logout"),{method:"POST",credentials:"include"})}function i(){return{getHealth:()=>a("/health"),getSignals:()=>a("/signals"),getScheduledSignals:()=>a("/signals/scheduled"),getSignal:e=>a("/signals/".concat(encodeURIComponent(e))),getSignalRuns:e=>a("/signals/".concat(encodeURIComponent(e),"/runs")),triggerSignal:(e,t)=>a("/signals/".concat(encodeURIComponent(e),"/trigger"),{method:"POST",body:JSON.stringify({input:null!=t?t:{}})}),getRuns:e=>{let t=new URLSearchParams;(null==e?void 0:e.status)&&t.set("status",e.status),(null==e?void 0:e.signalName)&&t.set("signalName",e.signalName);let n=t.toString();return a("/runs".concat(n?"?".concat(n):""))},getRunStats:()=>a("/runs/stats"),getRun:e=>a("/runs/".concat(e)),getRunSteps:e=>a("/runs/".concat(e,"/steps")),getRunLogs:e=>a("/runs/".concat(e,"/logs")),cancelRun:e=>a("/runs/".concat(e,"/cancel"),{method:"POST"}),rerunRun:e=>a("/runs/".concat(e,"/rerun"),{method:"POST"}),retryRun:e=>a("/runs/".concat(e,"/retry"),{method:"POST"}),getBroadcasts:()=>a("/broadcasts"),getBroadcast:e=>a("/broadcasts/".concat(encodeURIComponent(e))),triggerBroadcast:(e,t)=>a("/broadcasts/".concat(encodeURIComponent(e),"/trigger"),{method:"POST",body:JSON.stringify({input:null!=t?t:{}})}),getBroadcastRuns:e=>a("/broadcasts/".concat(encodeURIComponent(e),"/runs")),getBroadcastRun:e=>a("/broadcast-runs/".concat(e)),getBroadcastRunNodes:e=>a("/broadcast-runs/".concat(e,"/nodes")),getBroadcastRunLogs:e=>a("/broadcast-runs/".concat(e,"/logs")),cancelBroadcastRun:e=>a("/broadcast-runs/".concat(e,"/cancel"),{method:"POST"}),rerunBroadcastRun:e=>a("/broadcast-runs/".concat(e,"/rerun"),{method:"POST"}),getBeacons:()=>a("/beacons"),getBeacon:e=>a("/beacons/".concat(encodeURIComponent(e))),getBeaconEvents:e=>a("/beacons/".concat(encodeURIComponent(e),"/events")),getBeaconLogs:e=>a("/beacons/".concat(encodeURIComponent(e),"/logs")),startBeacon:e=>a("/beacons/".concat(encodeURIComponent(e),"/start"),{method:"POST"}),stopBeacon:e=>a("/beacons/".concat(encodeURIComponent(e),"/stop"),{method:"POST"}),restartBeacon:e=>a("/beacons/".concat(encodeURIComponent(e),"/restart"),{method:"POST"}),getBroadcastDefinitions:()=>a("/v1/broadcast-definitions"),getBroadcastDefinition:e=>a("/v1/broadcast-definitions/".concat(encodeURIComponent(e))),getBroadcastDefinitionVersions:e=>a("/v1/broadcast-definitions/".concat(encodeURIComponent(e),"/versions")),saveBroadcastDefinition:e=>a("/v1/broadcast-definitions",{method:"POST",body:JSON.stringify(e)}),validateBroadcastDefinition:e=>a("/v1/broadcast-definitions/validate",{method:"POST",body:JSON.stringify(e)}),deleteBroadcastDefinition:e=>a("/v1/broadcast-definitions/".concat(encodeURIComponent(e)),{method:"DELETE"}),triggerDynamicBroadcast:(e,t)=>a("/v1/trigger-dynamic-broadcast",{method:"POST",body:JSON.stringify({broadcastName:e,input:null!=t?t:{}})}),getSchedules:e=>{let t=new URLSearchParams;(null==e?void 0:e.kind)&&t.set("kind",e.kind),(null==e?void 0:e.enabled)!==void 0&&t.set("enabled",String(e.enabled));let n=t.toString();return a("/v1/schedules".concat(n?"?".concat(n):""))},getSchedule:e=>a("/v1/schedules/".concat(e)),createSchedule:e=>a("/v1/schedules",{method:"POST",body:JSON.stringify(e)}),updateSchedule:(e,t)=>a("/v1/schedules/".concat(e),{method:"PATCH",body:JSON.stringify(t)}),deleteSchedule:e=>a("/v1/schedules/".concat(e),{method:"DELETE"}),previewSchedule:function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:5;return a("/v1/schedules/".concat(e,"/preview"),{method:"POST",body:JSON.stringify({count:t})})},evaluateExpression:(e,t)=>a("/v1/expressions/evaluate",{method:"POST",body:JSON.stringify({node:e,context:t})}),validateExpression:(e,t)=>a("/v1/expressions/validate",{method:"POST",body:JSON.stringify({node:e,schemaContext:t})}),parseExpression:e=>a("/v1/expressions/parse",{method:"POST",body:JSON.stringify({source:e})}),getEnvVars:()=>a("/v1/env"),createEnvVar:e=>a("/v1/env",{method:"POST",body:JSON.stringify(e)}),updateEnvVar:(e,t)=>a("/v1/env/".concat(e),{method:"PATCH",body:JSON.stringify(t)}),deleteEnvVar:e=>a("/v1/env/".concat(e),{method:"DELETE"}),getApiKeys:()=>a("/v1/keys"),createApiKey:(e,t)=>a("/v1/keys",{method:"POST",body:JSON.stringify({name:e,scopes:t})}),revokeApiKey:e=>a("/v1/keys/".concat(e),{method:"DELETE"})}}n.d(t,{T5:()=>s,gf:()=>i,iD:()=>c,ri:()=>r})},1253:(e,t,n)=>{"use strict";n.d(t,{W:()=>s});var a=n(8111);function s(e){let{status:t}=e;return(0,a.jsxs)("span",{className:"status-badge status-badge--".concat(t),children:[(0,a.jsx)("span",{className:"status-badge-dot"}),t]})}},1489:(e,t,n)=>{"use strict";n.d(t,{s:()=>r});var a=n(8111),s=n(5271);function c(e){let t=Date.now()-new Date(e).getTime();if(t<0)return"just now";let n=Math.floor(t/1e3);if(n<5)return"just now";if(n<60)return"".concat(n,"s ago");let a=Math.floor(n/60);if(a<60)return"".concat(a,"m ago");let s=Math.floor(a/60);if(s<24)return"".concat(s,"h ago");let c=Math.floor(s/24);return"".concat(c,"d ago")}function r(e){let{date:t}=e,[n,r]=(0,s.useState)(()=>c(t));return(0,s.useEffect)(()=>{let e=setInterval(()=>{r(c(t))},5e3);return()=>clearInterval(e)},[t]),(0,a.jsx)("span",{className:"mono",title:new Date(t).toLocaleString(),style:{fontSize:"0.8125rem",color:"var(--muted)"},children:n})}},2638:(e,t,n)=>{"use strict";n.d(t,{SignalDetail:()=>p});var a=n(8111),s=n(5271),c=n(4736),r=n(593),i=n(9275),o=n(7646),l=n(1253),d=n(1489);function u(e){let{runs:t}=e,n=(0,c.useRouter)();return 0===t.length?(0,a.jsx)("div",{className:"empty-state",children:(0,a.jsx)("p",{className:"empty-state-text",children:"No runs recorded."})}):(0,a.jsxs)("table",{className:"station-table",children:[(0,a.jsx)("thead",{children:(0,a.jsxs)("tr",{children:[(0,a.jsx)("th",{children:"Status"}),(0,a.jsx)("th",{children:"Signal"}),(0,a.jsx)("th",{children:"Run ID"}),(0,a.jsx)("th",{children:"Duration"}),(0,a.jsx)("th",{children:"Created"}),(0,a.jsx)("th",{children:"Error"})]})}),(0,a.jsx)("tbody",{children:t.map((e,t)=>{var s,c;return(0,a.jsxs)("tr",{className:"reveal-item clickable-row",style:{animationDelay:"".concat(40*t,"ms")},onClick:()=>n.push("/runs/".concat(e.id)),children:[(0,a.jsx)("td",{children:(0,a.jsx)(l.W,{status:e.status})}),(0,a.jsx)("td",{className:"mono",children:e.signalName}),(0,a.jsx)("td",{className:"mono truncate",title:e.id,children:e.id.slice(0,8)}),(0,a.jsx)("td",{className:"mono",children:function(e,t){if(!e)return"-";let n=new Date(e).getTime(),a=(t?new Date(t).getTime():Date.now())-n;return a<1e3?"".concat(a,"ms"):a<6e4?"".concat((a/1e3).toFixed(1),"s"):"".concat((a/6e4).toFixed(1),"m")}(e.startedAt,e.completedAt)}),(0,a.jsx)("td",{children:(0,a.jsx)(d.s,{date:e.createdAt})}),(0,a.jsx)("td",{style:{color:e.error?"var(--rust)":"var(--muted)",fontFamily:"var(--font-mono)",fontSize:"0.75rem",maxWidth:"200px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},title:null!=(s=e.error)?s:void 0,children:(c=e.error,c?c.length<=60?c:c.slice(0,60)+"…":"-")})]},e.id)})})]})}var m=n(3055);function h(e){if("object"===e.type&&e.properties){let t=Object.entries(e.properties).map(e=>{let[t,n]=e;return"".concat(t,": ").concat(n.type).concat(n.required?"":"?")}).join(", ");return"{ ".concat(t," }")}return"array"===e.type&&e.items?"".concat(h(e.items),"[]"):"enum"===e.type&&e.values?e.values.map(e=>'"'.concat(e,'"')).join(" | "):e.type}let g=["all","completed","failed","running","pending"];function p(){var e,t,n;let l=(0,c.useParams)().name,d=decodeURIComponent(l),p=(0,r.gf)(),{events:f}=(0,i.q)(),[v,x]=(0,s.useState)(null),[S,j]=(0,s.useState)([]),[y,N]=(0,s.useState)(!0),[b,O]=(0,s.useState)(!1),[T,R]=(0,s.useState)("{}"),[w,C]=(0,s.useState)("all");(0,o.rT)([{label:"Signals",href:"/signals"},{label:d}],"signals");let P=(0,s.useCallback)(()=>{p.getSignalRuns(l).then(e=>j(e.data)).catch(e=>console.error("Failed to refresh runs:",e))},[l]);async function E(){O(!0);try{let e=JSON.parse(T);await p.triggerSignal(l,e),R("{}"),setTimeout(P,300)}catch(e){e instanceof Error&&console.error("Trigger failed:",e.message)}O(!1)}if((0,s.useEffect)(()=>{!async function(){try{let[e,t]=await Promise.all([p.getSignal(l),p.getSignalRuns(l)]);x(e.data),j(t.data)}catch(e){e instanceof Error&&console.error("Failed to load signal:",e.message)}N(!1)}()},[l]),(0,s.useEffect)(()=>{if(0===f.length)return;let e=f[0];if(e.type.startsWith("run:")){var t,n;(null!=(n=null==(t=e.data.run)?void 0:t.signalName)?n:e.data.signalName)===d&&P()}},[f.length,d,P]),y)return(0,a.jsxs)("div",{children:[(0,a.jsx)("h1",{className:"page-title",children:d}),(0,a.jsx)("div",{className:"loading-bar",children:(0,a.jsx)("div",{className:"loading-bar-fill"})})]});if(!v)return(0,a.jsxs)("div",{children:[(0,a.jsx)("h1",{className:"page-title",children:d}),(0,a.jsx)("div",{className:"empty-state",children:(0,a.jsx)("p",{className:"empty-state-text",children:"Signal not found."})})]});let B=null!==v.inputSchema||null!==v.outputSchema,k="all"===w?S:S.filter(e=>e.status===w);return(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"page-header",children:[(0,a.jsx)("h1",{className:"page-title",style:{marginBottom:0},children:d}),(0,a.jsx)("div",{className:"page-header-actions",children:(0,a.jsx)("button",{className:"btn btn--primary",onClick:E,disabled:b,children:b?"Dispatching...":"Trigger"})})]}),(0,a.jsxs)("div",{className:"detail-section",children:[(0,a.jsx)("div",{className:"detail-section-label",children:"Configuration"}),(0,a.jsxs)("div",{className:"config-grid",children:[(0,a.jsxs)("div",{className:"config-item",children:[(0,a.jsx)("span",{className:"config-item-label",children:"Schedule"}),(0,a.jsx)("span",{className:"config-item-value",children:null!=(e=v.interval)?e:"Manual trigger"})]}),(0,a.jsxs)("div",{className:"config-item",children:[(0,a.jsx)("span",{className:"config-item-label",children:"Timeout"}),(0,a.jsx)("span",{className:"config-item-value",children:(n=v.timeout)<1e3?"".concat(n,"ms"):n<6e4?"".concat((n/1e3).toFixed(0),"s"):n<36e5?"".concat((n/6e4).toFixed(0),"m"):"".concat((n/36e5).toFixed(0),"h")})]}),(0,a.jsxs)("div",{className:"config-item",children:[(0,a.jsx)("span",{className:"config-item-label",children:"Max Attempts"}),(0,a.jsx)("span",{className:"config-item-value",children:v.maxAttempts})]}),(0,a.jsxs)("div",{className:"config-item",children:[(0,a.jsx)("span",{className:"config-item-label",children:"Max Concurrency"}),(0,a.jsx)("span",{className:"config-item-value",children:null!=(t=v.maxConcurrency)?t:"—"})]}),(0,a.jsxs)("div",{className:"config-item",children:[(0,a.jsx)("span",{className:"config-item-label",children:"Steps"}),(0,a.jsx)("span",{className:"config-item-value",children:v.hasSteps?v.stepNames.join(", "):"Single handler"})]})]})]}),B&&(0,a.jsxs)("div",{className:"detail-section",children:[(0,a.jsx)("div",{className:"detail-section-label",children:"Schema"}),(0,a.jsxs)("div",{className:"schema-pair",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{style:{fontFamily:"var(--font-mono)",fontSize:"0.6875rem",textTransform:"uppercase",letterSpacing:"0.08em",color:"var(--muted)",marginBottom:"0.5rem"},children:"Input"}),v.inputSchema?(0,a.jsx)("pre",{className:"json-viewer",style:{fontSize:"0.75rem"},children:h(v.inputSchema)}):(0,a.jsx)("span",{style:{color:"var(--muted)",fontSize:"0.8125rem"},children:"None"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{style:{fontFamily:"var(--font-mono)",fontSize:"0.6875rem",textTransform:"uppercase",letterSpacing:"0.08em",color:"var(--muted)",marginBottom:"0.5rem"},children:"Output"}),v.outputSchema?(0,a.jsx)("pre",{className:"json-viewer",style:{fontSize:"0.75rem"},children:h(v.outputSchema)}):(0,a.jsx)("span",{style:{color:"var(--muted)",fontSize:"0.8125rem"},children:"None"})]})]})]}),(0,a.jsxs)("div",{className:"detail-section",children:[(0,a.jsx)("div",{className:"detail-section-label",children:"Trigger"}),(0,a.jsx)(m.q,{schema:v.inputSchema,value:T,onChange:R}),(0,a.jsx)("div",{style:{marginTop:"0.5rem"},children:(0,a.jsx)("button",{className:"btn btn--primary",onClick:E,disabled:b,children:b?"Dispatching...":"Dispatch"})})]}),(0,a.jsxs)("div",{className:"detail-section",children:[(0,a.jsx)("div",{className:"detail-section-label",children:"Run History"}),(0,a.jsx)("div",{className:"filter-bar",children:g.map(e=>(0,a.jsx)("button",{className:"filter-btn".concat(w===e?" filter-btn--active":""),onClick:()=>C(e),children:e.charAt(0).toUpperCase()+e.slice(1)},e))}),(0,a.jsx)(u,{runs:k})]})]})}},3055:(e,t,n)=>{"use strict";n.d(t,{q:()=>r});var a=n(8111),s=n(5271);function c(e){let{schema:t}=e;if("object"!==t.type||!t.properties)return null;let n=Object.entries(t.properties);return 0===n.length?null:(0,a.jsxs)("div",{className:"schema-ref",children:[(0,a.jsx)("div",{className:"schema-ref-title",children:"Expected Input"}),n.map(e=>{let[t,n]=e;return(0,a.jsxs)("div",{className:"schema-field",children:[(0,a.jsx)("span",{className:"schema-field-name",children:t}),(0,a.jsx)("span",{className:"schema-field-type".concat(n.required?"":" schema-field-type--optional"),children:n.type})]},t)})]})}function r(e){let{schema:t,value:n,onChange:r}=e,[i,o]=(0,s.useState)(null),[l,d]=(0,s.useState)(!1);return(0,s.useEffect)(()=>{if(!l){if(t&&"{}"===n){let e=JSON.stringify(function e(t){switch(t.type){case"string":return"";case"number":case"integer":return 0;case"boolean":return!1;case"array":return[];case"enum":if(t.values&&t.values.length>0)return t.values[0];return"";case"object":{if(!t.properties)return{};let n={};for(let[a,s]of Object.entries(t.properties))n[a]=e(s);return n}default:return null}}(t),null,2);"{}"!==e&&r(e)}d(!0)}},[t,n,r,l]),(0,a.jsxs)("div",{children:[t&&"object"===t.type&&t.properties&&(0,a.jsx)(c,{schema:t}),(0,a.jsx)("textarea",{className:"input-textarea",value:n,onChange:e=>(function(e){if(r(e),""===e.trim())return void o(null);try{JSON.parse(e),o(null)}catch(e){e instanceof SyntaxError?o(e.message):o("Invalid JSON")}})(e.target.value),rows:6,spellCheck:!1,placeholder:"{}"}),i&&(0,a.jsx)("div",{className:"json-parse-error",children:i})]})}},4736:(e,t,n)=>{"use strict";var a=n(1504);n.o(a,"useParams")&&n.d(t,{useParams:function(){return a.useParams}}),n.o(a,"usePathname")&&n.d(t,{usePathname:function(){return a.usePathname}}),n.o(a,"useRouter")&&n.d(t,{useRouter:function(){return a.useRouter}})},7646:(e,t,n)=>{"use strict";n.d(t,{Hc:()=>s,iQ:()=>r,rT:()=>c});var a=n(5271);let s=(0,a.createContext)({segments:[],activeSection:null,setSegments:()=>{},setActiveSection:()=>{}});function c(e,t){let n=(0,a.useContext)(s);(0,a.useEffect)(()=>{n.setSegments(e),n.setActiveSection(t)},[JSON.stringify(e),t])}function r(){return(0,a.useContext)(s)}},9275:(e,t,n)=>{"use strict";n.d(t,{StationProvider:()=>i,q:()=>r});var a=n(8111),s=n(5271);let c=(0,s.createContext)({connected:!1,events:[]});function r(){return(0,s.useContext)(c)}function i(e){let{children:t}=e,[n,r]=(0,s.useState)([]),{connected:i}=function(e){let[t,n]=(0,s.useState)(!1),a=(0,s.useRef)(e);return a.current=e,(0,s.useEffect)(()=>{let e=null,t=null,s=0,c=!1;return!function r(){if(c)return;let i="https:"===window.location.protocol?"wss:":"ws:";(e=new WebSocket("".concat(i,"//").concat(window.location.host,"/api/events"))).onopen=()=>{n(!0),s=0},e.onmessage=e=>{try{let t=JSON.parse(e.data);a.current(t)}catch(e){console.error("Failed to parse WebSocket message:",e)}},e.onclose=()=>{if(n(!1),!c){let e=Math.min(1e3*Math.pow(2,s),1e4);s++,t=setTimeout(r,e)}},e.onerror=()=>{null==e||e.close()}}(),()=>{c=!0,t&&clearTimeout(t),null==e||e.close()}},[]),{connected:t}}((0,s.useCallback)(e=>{r(t=>[e,...t].slice(0,100))},[]));return(0,a.jsx)(c.Provider,{value:{connected:i,events:n},children:t})}},9486:(e,t,n)=>{Promise.resolve().then(n.bind(n,2638))}},e=>{e.O(0,[814,743,358],()=>e(e.s=9486)),_N_E=e.O()}]);
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[764],{593:(e,t,n)=>{"use strict";async function s(e,t){let n=await fetch("".concat("","/api").concat(e),{...t,credentials:"include",headers:{"Content-Type":"application/json",...null==t?void 0:t.headers}});if(!n.ok)throw Error((await n.json().catch(()=>({error:"unknown",message:"Request failed."}))).message);return n.json()}async function a(){let e=await fetch("".concat("","/api/auth/check"),{credentials:"include"});return(await e.json()).data}async function o(e,t){return(await fetch("".concat("","/api/auth/login"),{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:e,password:t})})).ok}async function c(){await fetch("".concat("","/api/auth/logout"),{method:"POST",credentials:"include"})}function i(){return{getHealth:()=>s("/health"),getSignals:()=>s("/signals"),getScheduledSignals:()=>s("/signals/scheduled"),getSignal:e=>s("/signals/".concat(encodeURIComponent(e))),getSignalRuns:e=>s("/signals/".concat(encodeURIComponent(e),"/runs")),triggerSignal:(e,t)=>s("/signals/".concat(encodeURIComponent(e),"/trigger"),{method:"POST",body:JSON.stringify({input:null!=t?t:{}})}),getRuns:e=>{let t=new URLSearchParams;(null==e?void 0:e.status)&&t.set("status",e.status),(null==e?void 0:e.signalName)&&t.set("signalName",e.signalName);let n=t.toString();return s("/runs".concat(n?"?".concat(n):""))},getRunStats:()=>s("/runs/stats"),getRun:e=>s("/runs/".concat(e)),getRunSteps:e=>s("/runs/".concat(e,"/steps")),getRunLogs:e=>s("/runs/".concat(e,"/logs")),cancelRun:e=>s("/runs/".concat(e,"/cancel"),{method:"POST"}),rerunRun:e=>s("/runs/".concat(e,"/rerun"),{method:"POST"}),retryRun:e=>s("/runs/".concat(e,"/retry"),{method:"POST"}),getBroadcasts:()=>s("/broadcasts"),getBroadcast:e=>s("/broadcasts/".concat(encodeURIComponent(e))),triggerBroadcast:(e,t)=>s("/broadcasts/".concat(encodeURIComponent(e),"/trigger"),{method:"POST",body:JSON.stringify({input:null!=t?t:{}})}),getBroadcastRuns:e=>s("/broadcasts/".concat(encodeURIComponent(e),"/runs")),getBroadcastRun:e=>s("/broadcast-runs/".concat(e)),getBroadcastRunNodes:e=>s("/broadcast-runs/".concat(e,"/nodes")),getBroadcastRunLogs:e=>s("/broadcast-runs/".concat(e,"/logs")),cancelBroadcastRun:e=>s("/broadcast-runs/".concat(e,"/cancel"),{method:"POST"}),rerunBroadcastRun:e=>s("/broadcast-runs/".concat(e,"/rerun"),{method:"POST"}),getBeacons:()=>s("/beacons"),getBeacon:e=>s("/beacons/".concat(encodeURIComponent(e))),getBeaconEvents:e=>s("/beacons/".concat(encodeURIComponent(e),"/events")),getBeaconLogs:e=>s("/beacons/".concat(encodeURIComponent(e),"/logs")),startBeacon:e=>s("/beacons/".concat(encodeURIComponent(e),"/start"),{method:"POST"}),stopBeacon:e=>s("/beacons/".concat(encodeURIComponent(e),"/stop"),{method:"POST"}),restartBeacon:e=>s("/beacons/".concat(encodeURIComponent(e),"/restart"),{method:"POST"}),getBroadcastDefinitions:()=>s("/v1/broadcast-definitions"),getBroadcastDefinition:e=>s("/v1/broadcast-definitions/".concat(encodeURIComponent(e))),getBroadcastDefinitionVersions:e=>s("/v1/broadcast-definitions/".concat(encodeURIComponent(e),"/versions")),saveBroadcastDefinition:e=>s("/v1/broadcast-definitions",{method:"POST",body:JSON.stringify(e)}),validateBroadcastDefinition:e=>s("/v1/broadcast-definitions/validate",{method:"POST",body:JSON.stringify(e)}),deleteBroadcastDefinition:e=>s("/v1/broadcast-definitions/".concat(encodeURIComponent(e)),{method:"DELETE"}),triggerDynamicBroadcast:(e,t)=>s("/v1/trigger-dynamic-broadcast",{method:"POST",body:JSON.stringify({broadcastName:e,input:null!=t?t:{}})}),getSchedules:e=>{let t=new URLSearchParams;(null==e?void 0:e.kind)&&t.set("kind",e.kind),(null==e?void 0:e.enabled)!==void 0&&t.set("enabled",String(e.enabled));let n=t.toString();return s("/v1/schedules".concat(n?"?".concat(n):""))},getSchedule:e=>s("/v1/schedules/".concat(e)),createSchedule:e=>s("/v1/schedules",{method:"POST",body:JSON.stringify(e)}),updateSchedule:(e,t)=>s("/v1/schedules/".concat(e),{method:"PATCH",body:JSON.stringify(t)}),deleteSchedule:e=>s("/v1/schedules/".concat(e),{method:"DELETE"}),previewSchedule:function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:5;return s("/v1/schedules/".concat(e,"/preview"),{method:"POST",body:JSON.stringify({count:t})})},evaluateExpression:(e,t)=>s("/v1/expressions/evaluate",{method:"POST",body:JSON.stringify({node:e,context:t})}),validateExpression:(e,t)=>s("/v1/expressions/validate",{method:"POST",body:JSON.stringify({node:e,schemaContext:t})}),parseExpression:e=>s("/v1/expressions/parse",{method:"POST",body:JSON.stringify({source:e})}),getEnvVars:()=>s("/v1/env"),createEnvVar:e=>s("/v1/env",{method:"POST",body:JSON.stringify(e)}),updateEnvVar:(e,t)=>s("/v1/env/".concat(e),{method:"PATCH",body:JSON.stringify(t)}),deleteEnvVar:e=>s("/v1/env/".concat(e),{method:"DELETE"}),getApiKeys:()=>s("/v1/keys"),createApiKey:(e,t)=>s("/v1/keys",{method:"POST",body:JSON.stringify({name:e,scopes:t})}),revokeApiKey:e=>s("/v1/keys/".concat(e),{method:"DELETE"})}}n.d(t,{T5:()=>a,gf:()=>i,iD:()=>o,ri:()=>c})},1510:(e,t,n)=>{Promise.resolve().then(n.bind(n,4913))},4736:(e,t,n)=>{"use strict";var s=n(1504);n.o(s,"useParams")&&n.d(t,{useParams:function(){return s.useParams}}),n.o(s,"usePathname")&&n.d(t,{usePathname:function(){return s.usePathname}}),n.o(s,"useRouter")&&n.d(t,{useRouter:function(){return s.useRouter}})},4913:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});var s=n(8111),a=n(5271),o=n(4736),c=n(593),i=n(7646);function r(){let e=(0,c.gf)(),t=(0,o.useRouter)(),[n,r]=(0,a.useState)([]),[d,l]=(0,a.useState)(!0);return((0,i.rT)([{label:"Signals"}],"signals"),(0,a.useEffect)(()=>{e.getSignals().then(e=>r(e.data)).catch(e=>{e instanceof Error&&console.error("Failed to load signals:",e.message)}).finally(()=>l(!1))},[]),d)?(0,s.jsxs)("div",{children:[(0,s.jsx)("h1",{className:"page-title",children:"Signals"}),(0,s.jsx)("div",{className:"loading-bar",children:(0,s.jsx)("div",{className:"loading-bar-fill"})})]}):0===n.length?(0,s.jsxs)("div",{children:[(0,s.jsx)("h1",{className:"page-title",children:"Signals"}),(0,s.jsx)("div",{className:"empty-state",children:(0,s.jsx)("p",{className:"empty-state-text",children:"No signals discovered."})})]}):(0,s.jsxs)("div",{children:[(0,s.jsx)("h1",{className:"page-title",children:"Signals"}),(0,s.jsxs)("table",{className:"station-table",children:[(0,s.jsx)("thead",{children:(0,s.jsxs)("tr",{children:[(0,s.jsx)("th",{children:"Name"}),(0,s.jsx)("th",{children:"Kind"}),(0,s.jsx)("th",{children:"Schedule"}),(0,s.jsx)("th",{children:"Timeout"}),(0,s.jsx)("th",{children:"Retries"}),(0,s.jsx)("th",{children:"Steps"})]})}),(0,s.jsx)("tbody",{children:n.map((e,n)=>{var a,o;return(0,s.jsxs)("tr",{className:"reveal-item clickable-row",style:{animationDelay:"".concat(40*n,"ms")},onClick:()=>t.push("/signals/".concat(encodeURIComponent(e.name))),children:[(0,s.jsx)("td",{className:"mono",children:e.name}),(0,s.jsx)("td",{style:{color:"var(--muted)",fontSize:"0.8125rem"},children:e.interval?"recurring":"trigger"}),(0,s.jsx)("td",{className:"mono",style:{color:"var(--muted)",fontSize:"0.8125rem"},children:null!=(a=e.interval)?a:"—"}),(0,s.jsx)("td",{className:"mono",style:{fontSize:"0.8125rem"},children:(o=e.timeout)<1e3?"".concat(o,"ms"):o<6e4?"".concat((o/1e3).toFixed(0),"s"):o<36e5?"".concat((o/6e4).toFixed(0),"m"):"".concat((o/36e5).toFixed(0),"h")}),(0,s.jsx)("td",{className:"mono",style:{fontSize:"0.8125rem"},children:e.maxAttempts>1?e.maxAttempts-1:"0"}),(0,s.jsx)("td",{className:"mono",style:{fontSize:"0.8125rem"},children:e.hasSteps?e.stepNames.length:"—"})]},e.name)})})]})]})}},7646:(e,t,n)=>{"use strict";n.d(t,{Hc:()=>a,iQ:()=>c,rT:()=>o});var s=n(5271);let a=(0,s.createContext)({segments:[],activeSection:null,setSegments:()=>{},setActiveSection:()=>{}});function o(e,t){let n=(0,s.useContext)(a);(0,s.useEffect)(()=>{n.setSegments(e),n.setActiveSection(t)},[JSON.stringify(e),t])}function c(){return(0,s.useContext)(a)}}},e=>{e.O(0,[814,743,358],()=>e(e.s=1510)),_N_E=e.O()}]);
@@ -0,0 +1 @@
1
+ :root{--rust:#8B5A2B;--rust-light:#A0622D;--rust-pale:#C4834A;--patina:#4A6741;--patina-light:#5C7C52;--signal-green:#6B9962;--concrete:#F4F1EC;--concrete-dark:#E8E4DC;--concrete-mid:#D4CEBF;--charcoal:#1C1C1E;--charcoal-mid:#2C2C2E;--wire:#3A3A3C;--muted:#8A8A8E;--muted-light:#AEAEB2;--sky:#7FB2CC;--surface:#FFFFFF;--code-bg:#1C1C1E;--code-text:#F4F1EC;--code-key:#AEAEB2;--code-string:#C4834A;--code-number:#7FB2CC;--code-bool:#5C7C52;--code-null:#8A8A8E;--font-display:"Instrument Serif",serif;--font-mono:"IBM Plex Mono",monospace;--font-body:"Space Grotesk",sans-serif;--ease-standard:cubic-bezier(0.25,0.46,0.45,0.94);--ease-enter:cubic-bezier(0.0,0.0,0.2,1.0);--ease-exit:cubic-bezier(0.4,0.0,1.0,1.0);--duration-pulse:2.4s;--duration-blink:3s;--duration-reveal:500ms;--delay-stagger:120ms;--border-width:1.5px;--sidebar-width:200px;--header-height:48px}[data-theme=dark]{--rust:#C4834A;--rust-light:#D4975C;--rust-pale:#E0A86A;--patina:#6B9962;--patina-light:#7DAF72;--signal-green:#8BB882;--concrete:#1A1A1C;--concrete-dark:#252527;--concrete-mid:#3A3A3C;--charcoal:#E8E4DC;--charcoal-mid:#C4C0B8;--wire:#4A4A4C;--muted:#8A8A8E;--muted-light:#6A6A6E;--sky:#8FC2DC;--surface:#222224;--code-bg:#111113}[data-theme=dark] .station-sidebar{--charcoal:#1C1C1E;--charcoal-mid:#2C2C2E;--wire:#3A3A3C;--concrete:#F4F1EC;--concrete-dark:#E8E4DC;--muted:#8A8A8E;--muted-light:#AEAEB2;--rust:#8B5A2B}[data-theme=dark] .status-badge--running{background:rgba(107,153,98,.2)}[data-theme=dark] .status-badge--completed{background:rgba(74,103,65,.18)}[data-theme=dark] .status-badge--failed{background:rgba(196,131,74,.15)}@keyframes signal-pulse{0%{box-shadow:0 0 0 0 rgba(107,153,98,.4)}70%{box-shadow:0 0 0 6px rgba(107,153,98,0)}to{box-shadow:0 0 0 0 rgba(107,153,98,0)}}@keyframes status-blink{0%,45%,55%,to{opacity:1}50%{opacity:.15}}@keyframes stagger-reveal{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes load-sweep{0%{width:0}15%{width:15%}40%{width:45%}70%{width:70%}90%{width:90%}to{width:100%}}*,:after,:before{box-sizing:border-box;margin:0;padding:0}html{font-size:16px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body{font-family:var(--font-body);font-weight:300;color:var(--charcoal);background-color:var(--concrete);line-height:1.5}a{color:var(--rust);text-decoration:none}a:hover{color:var(--rust-light)}.font-display{font-family:var(--font-display);font-weight:400}.font-mono{font-family:var(--font-mono);font-size:.875rem}.font-body{font-family:var(--font-body);font-weight:300}.section-label{font-family:var(--font-mono);font-size:.65rem;text-transform:uppercase;letter-spacing:.22em;color:var(--rust);display:flex;align-items:center;gap:.5rem}.section-label:before{content:"";display:block;width:1.5rem;height:var(--border-width);background:var(--rust)}.station-layout{display:flex;min-height:100vh}.station-sidebar{width:var(--sidebar-width);background:var(--charcoal);color:var(--concrete);display:flex;flex-direction:column;position:fixed;top:0;left:0;bottom:0;z-index:10;transition:width .2s var(--ease-standard);overflow:hidden}.station-sidebar-logo{padding:1rem 1rem .75rem;border-bottom:var(--border-width) solid var(--wire)}.station-sidebar-mark{display:flex;align-items:center;gap:.5rem;color:var(--concrete)}.station-sidebar-mark svg{flex-shrink:0;opacity:.85}.station-sidebar-logo h1{font-family:var(--font-display);font-size:1.125rem;font-weight:400;color:var(--concrete);line-height:1}.station-sidebar-logo span{display:block;font-family:var(--font-mono);font-size:.5625rem;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-top:.375rem}.station-sidebar-nav{padding:.5rem 0;flex:1 1}.station-sidebar-nav-label{font-family:var(--font-mono);font-size:.5625rem;text-transform:uppercase;letter-spacing:.2em;color:var(--muted);padding:.5rem 1rem .25rem}.station-sidebar-nav a{display:flex;align-items:center;gap:.5rem;padding:.375rem 1rem;font-family:var(--font-mono);font-size:.8125rem;color:var(--muted-light);border-left:2px solid transparent;transition:color .2s var(--ease-standard),background .2s var(--ease-standard)}.station-sidebar-nav a svg{flex-shrink:0;opacity:.7;transition:opacity .2s var(--ease-standard)}.station-sidebar-nav a:hover{color:var(--concrete);background:var(--charcoal-mid)}.station-sidebar-nav a:hover svg{opacity:1}.station-sidebar-nav a.active{color:var(--concrete);background:var(--wire);border-left:2px solid var(--rust)}.station-sidebar-nav a.active svg{opacity:1}.sidebar-collapse-btn{display:flex;align-items:center;justify-content:center;width:100%;padding:.5rem;border:none;border-top:var(--border-width) solid var(--wire);background:transparent;color:var(--muted);cursor:pointer;transition:color .2s var(--ease-standard),background .2s var(--ease-standard)}.sidebar-collapse-btn:hover{color:var(--concrete);background:var(--charcoal-mid)}[data-collapsed=true] .station-sidebar{width:48px}[data-collapsed=true] .station-main{margin-left:48px}[data-collapsed=true] .nav-label,[data-collapsed=true] .station-sidebar-logo h1,[data-collapsed=true] .station-sidebar-logo>span,[data-collapsed=true] .station-sidebar-nav-label{display:none}[data-collapsed=true] .station-sidebar-logo{padding:.75rem;display:flex;justify-content:center}[data-collapsed=true] .station-sidebar-mark{justify-content:center}[data-collapsed=true] .station-sidebar-nav a{justify-content:center;padding:.5rem;border-left-color:transparent}[data-collapsed=true] .station-sidebar-nav a.active{border-left-color:transparent}.station-main{margin-left:var(--sidebar-width);flex:1 1;display:flex;flex-direction:column;transition:margin-left .2s var(--ease-standard)}.station-header{height:var(--header-height);background:var(--concrete);border-bottom:var(--border-width) solid var(--concrete-dark);justify-content:space-between;padding:0 1.5rem;position:-webkit-sticky;position:sticky;top:0;z-index:5}.breadcrumb,.station-header{display:flex;align-items:center}.breadcrumb{font-family:var(--font-mono);font-size:.75rem;color:var(--muted);gap:0}.breadcrumb-item{display:inline-flex;align-items:center}.breadcrumb-sep{margin:0 .375rem;color:var(--concrete-mid);-webkit-user-select:none;-moz-user-select:none;user-select:none}.breadcrumb-link{color:var(--muted);text-decoration:none;transition:color .15s var(--ease-standard);max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.breadcrumb-link:hover{color:var(--rust)}.breadcrumb-segment{color:var(--muted)}.breadcrumb-segment--current{color:var(--charcoal);max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.station-content{flex:1 1;padding:1.5rem;max-width:1100px}.status-badge{display:inline-flex;align-items:center;gap:.375rem;padding:.125rem .5rem;border-radius:3px;font-family:var(--font-mono);font-size:.6875rem;text-transform:uppercase;letter-spacing:.05em;line-height:1.6}.status-badge-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}.status-badge--pending{background:var(--concrete-dark);color:var(--muted)}.status-badge--pending .status-badge-dot{background:var(--muted)}.status-badge--running{background:rgba(74,103,65,.12);color:var(--patina)}.status-badge--running .status-badge-dot{background:var(--signal-green);animation:status-blink var(--duration-blink) ease-in-out infinite}.status-badge--completed{background:rgba(74,103,65,.1);color:var(--patina)}.status-badge--completed .status-badge-dot{background:var(--patina)}.status-badge--failed{background:rgba(139,90,43,.1);color:var(--rust)}.status-badge--failed .status-badge-dot{background:var(--rust)}.status-badge--cancelled{background:rgba(58,58,60,.08);color:var(--muted)}.status-badge--cancelled .status-badge-dot{background:var(--wire)}.status-badge--skipped{background:transparent;color:var(--muted);border:var(--border-width) dashed var(--muted-light)}.status-badge--skipped .status-badge-dot{background:var(--muted-light)}.status-badge--stopped{background:rgba(58,58,60,.08);color:var(--muted)}.status-badge--stopped .status-badge-dot{background:var(--wire)}.status-badge--starting{background:rgba(139,90,43,.1);color:var(--rust)}.status-badge--starting .status-badge-dot{background:var(--rust-pale);animation:status-blink var(--duration-blink) ease-in-out infinite}.status-badge--stopping{background:rgba(139,90,43,.08);color:var(--rust-light)}.status-badge--stopping .status-badge-dot{background:var(--rust-pale);animation:status-blink var(--duration-blink) ease-in-out infinite}.status-badge--backoff{background:rgba(139,90,43,.08);color:var(--rust-light)}.status-badge--backoff .status-badge-dot{background:var(--rust-pale)}.status-badge--errored{background:rgba(139,90,43,.1);color:var(--rust)}.status-badge--errored .status-badge-dot{background:var(--rust)}.station-table{width:100%;border-collapse:collapse;font-family:var(--font-body);font-size:.875rem}.station-table th{font-family:var(--font-mono);font-size:.6875rem;text-transform:uppercase;letter-spacing:.1em;color:var(--muted);text-align:left;padding:.5rem .75rem;border-bottom:var(--border-width) solid var(--concrete-dark);font-weight:400}.station-table td{padding:.625rem .75rem;border-bottom:1px solid var(--concrete-dark);vertical-align:middle}.station-table tr:hover td{background:var(--concrete-dark)}.station-table .mono{font-family:var(--font-mono);font-size:.8125rem}.station-table .truncate{max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.station-card{background:var(--surface);border:var(--border-width) solid var(--concrete-dark);border-radius:4px;padding:1.25rem}.station-card h3{font-family:var(--font-display);font-size:1.125rem;margin-bottom:.75rem}.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));grid-gap:.75rem;gap:.75rem;margin-bottom:1.5rem}.stat-card{background:var(--surface);border:var(--border-width) solid var(--concrete-dark);border-radius:4px;padding:1rem}.stat-card-label{font-family:var(--font-mono);font-size:.625rem;text-transform:uppercase;letter-spacing:.15em;color:var(--muted);margin-bottom:.25rem}.stat-card-value{font-family:var(--font-display);font-size:2rem;color:var(--charcoal);line-height:1.1}.pulse-dot{width:8px;height:8px;border-radius:50%;background:var(--signal-green);animation:signal-pulse var(--duration-pulse) ease-out infinite}.pulse-dot--disconnected{background:var(--muted);animation:none}.step-timeline{position:relative;padding-left:1.5rem}.step-timeline:before{content:"";position:absolute;left:5px;top:0;bottom:0;width:var(--border-width);background:var(--concrete-dark)}.step-timeline-item{position:relative;padding:.75rem 0}.step-timeline-dot{position:absolute;left:-1.5rem;top:1rem;width:10px;height:10px;border-radius:50%;border:var(--border-width) solid var(--concrete-dark);background:var(--surface);transform:translateX(-50%);left:calc(-1.5rem + 5px)}.step-timeline-dot--completed{background:var(--patina);border-color:var(--patina)}.step-timeline-dot--running{background:var(--signal-green);border-color:var(--signal-green);animation:signal-pulse var(--duration-pulse) ease-out infinite}.step-timeline-dot--failed{background:var(--rust);border-color:var(--rust)}.step-timeline-name{font-family:var(--font-mono);font-size:.8125rem;color:var(--charcoal)}.step-timeline-meta{font-family:var(--font-mono);font-size:.6875rem;color:var(--muted);margin-top:.125rem}.json-viewer{font-family:var(--font-mono);font-size:.8125rem;line-height:1.5;background:var(--code-bg);color:var(--code-text);border-radius:4px;padding:1rem;overflow-x:auto}.json-viewer .json-key{color:var(--code-key)}.json-viewer .json-string{color:var(--code-string)}.json-viewer .json-number{color:var(--code-number)}.json-viewer .json-boolean{color:var(--code-bool)}.json-viewer .json-null{color:var(--code-null)}.empty-state{text-align:center;padding:3rem 1rem;color:var(--muted)}.empty-state-text{font-family:var(--font-mono);font-size:.8125rem}.loading-bar{height:var(--border-width);background:var(--concrete-dark);position:relative;overflow:hidden;border-radius:1px}.loading-bar-fill{height:100%;background:var(--rust);animation:load-sweep 3.5s cubic-bezier(.4,0,.2,1) infinite}.dag-container{background:var(--surface);border:var(--border-width) solid var(--concrete-dark);border-radius:4px;padding:1.5rem;overflow-x:auto}.dag-node{cursor:pointer}.dag-node rect{stroke-width:1.5;rx:4;ry:4}.dag-node text{font-family:var(--font-mono);font-size:11px}.dag-edge{fill:none;stroke:var(--concrete-mid);stroke-width:1.5;transition:stroke .3s var(--ease-standard)}.dag-edge--active{stroke:var(--patina);stroke-width:2}.page-title{font-family:var(--font-display);font-size:1.75rem;font-weight:400;margin-bottom:1.5rem;color:var(--charcoal)}.btn{display:inline-flex;align-items:center;gap:.375rem;font-family:var(--font-mono);font-size:.75rem;padding:.375rem .75rem;border:var(--border-width) solid var(--charcoal);border-radius:3px;background:var(--charcoal);color:var(--concrete);cursor:pointer;transition:transform .2s var(--ease-standard),background .2s var(--ease-standard)}.btn:hover{transform:translateY(-2px);background:var(--rust);border-color:var(--rust)}.btn--primary{background:var(--patina);border-color:var(--patina)}.btn--primary:hover{background:var(--patina-light);border-color:var(--patina-light)}.btn--primary:disabled{opacity:.5;cursor:not-allowed;transform:none}.btn--sm{font-size:.6875rem;padding:.25rem .5rem}.btn--danger{background:var(--rust);border-color:var(--rust)}.btn--danger:hover{background:var(--rust-light);border-color:var(--rust-light)}.btn:disabled{opacity:.5;cursor:not-allowed;transform:none}.detail-grid{display:grid;grid-template-columns:auto 1fr;grid-gap:.25rem 1rem;gap:.25rem 1rem;font-size:.875rem}.detail-label{font-family:var(--font-mono);font-size:.75rem;color:var(--muted);text-transform:uppercase;letter-spacing:.05em}.detail-value{font-family:var(--font-body);color:var(--charcoal)}.detail-value.mono{font-family:var(--font-mono);font-size:.8125rem}.reveal-item{animation:stagger-reveal var(--duration-reveal) var(--ease-standard) both}.input-textarea{width:100%;margin-top:.5rem;padding:.75rem;font-family:var(--font-mono);font-size:.8125rem;line-height:1.5;color:var(--code-text);background:var(--code-bg);border:var(--border-width) solid var(--wire);border-radius:4px;resize:vertical;outline:none}.input-textarea:focus{border-color:var(--patina)}.log-container{background:var(--code-bg);border-radius:4px;max-height:400px;overflow-y:auto;overflow-x:auto}.log-line{display:flex;gap:.625rem;padding:.125rem .75rem;font-family:var(--font-mono);font-size:.75rem;line-height:1.6;border-bottom:1px solid var(--wire)}.log-line:last-of-type{border-bottom:none}.log-timestamp{min-width:5.5rem}.log-level,.log-timestamp{color:var(--muted);flex-shrink:0}.log-level{min-width:2rem}.log-level[data-level=stderr]{color:var(--rust-pale)}.log-message{color:var(--code-text);white-space:pre-wrap;word-break:break-all}.schema-ref{border:var(--border-width) solid var(--concrete-dark);border-radius:4px;padding:.75rem;background:var(--surface);margin-bottom:.75rem}.schema-ref-title{font-family:var(--font-mono);font-size:.625rem;text-transform:uppercase;letter-spacing:.15em;color:var(--muted);margin-bottom:.5rem}.schema-field{display:flex;justify-content:space-between;padding:.25rem 0;font-family:var(--font-mono);font-size:.8125rem;border-bottom:1px solid var(--concrete-dark)}.schema-field:last-child{border-bottom:none}.schema-field-name{color:var(--charcoal)}.schema-field-type{color:var(--muted)}.schema-field-type--optional:after{content:"?";color:var(--rust-pale)}.error-block{background:rgba(139,90,43,.08);border:var(--border-width) solid rgba(139,90,43,.2);border-radius:4px;padding:.75rem 1rem;font-size:.8125rem;color:var(--rust);white-space:pre-wrap;word-break:break-word;line-height:1.5}.copy-btn,.error-block{font-family:var(--font-mono)}.copy-btn{position:absolute;top:.5rem;right:.5rem;background:var(--wire);border:none;border-radius:3px;padding:.25rem .5rem;font-size:.625rem;color:var(--muted-light);cursor:pointer;opacity:0;transition:opacity .2s var(--ease-standard);text-transform:uppercase;letter-spacing:.1em}.copy-btn:focus,.json-viewer:hover .copy-btn{opacity:1}.copy-btn:hover{color:var(--concrete);background:var(--muted)}.filter-bar{display:flex;gap:.375rem;margin-bottom:1rem}.filter-btn{font-family:var(--font-mono);font-size:.6875rem;padding:.25rem .625rem;border:var(--border-width) solid var(--concrete-dark);border-radius:3px;background:var(--surface);color:var(--muted);cursor:pointer;text-transform:uppercase;letter-spacing:.05em;transition:all .15s var(--ease-standard)}.filter-btn:hover{border-color:var(--charcoal);color:var(--charcoal)}.filter-btn--active{background:var(--charcoal);border-color:var(--charcoal);color:var(--concrete)}.node-detail{background:var(--surface);border:var(--border-width) solid var(--concrete-dark);border-radius:4px;padding:1.25rem;margin-top:1rem}.node-detail-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:1rem}.node-detail-title{font-family:var(--font-mono);font-size:.875rem;font-weight:500}.detail-section{margin-bottom:1.5rem}.detail-section:last-child{margin-bottom:0}.detail-section-label{font-family:var(--font-mono);font-size:.65rem;text-transform:uppercase;letter-spacing:.22em;color:var(--rust);margin-bottom:.5rem;display:flex;align-items:center;gap:.5rem}.detail-section-label:before{content:"";display:block;width:1rem;height:var(--border-width);background:var(--rust)}.meta-value--link{color:var(--rust);cursor:pointer}.meta-value--link:hover{color:var(--rust-light);text-decoration:underline}.dag-node--selected rect{stroke:var(--rust)!important;stroke-width:2.5!important}.json-parse-error{font-family:var(--font-mono);font-size:.6875rem;color:var(--rust);margin-top:.25rem}.station-table tr.clickable-row{cursor:pointer}.station-table tr.clickable-row:hover td{background:var(--concrete-dark)}.page-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem}.page-header-actions{display:flex;gap:.5rem;align-items:center}.schema-pair{display:grid;grid-template-columns:1fr 1fr;grid-gap:1rem;gap:1rem}.config-grid{display:flex;flex-wrap:wrap;gap:1.5rem;margin-bottom:.5rem}.config-item{display:flex;flex-direction:column;gap:.125rem}.config-item-label{font-family:var(--font-mono);font-size:.625rem;text-transform:uppercase;letter-spacing:.15em;color:var(--muted)}.config-item-value{font-family:var(--font-mono);font-size:.875rem;color:var(--charcoal)}.workflow-layout{display:flex;gap:0;align-items:flex-start;border:var(--border-width) solid var(--concrete-dark);border-radius:4px;background:var(--surface);min-height:400px}.workflow-sidebar{width:220px;flex-shrink:0;border-right:var(--border-width) solid var(--concrete-dark);padding:.5rem 0;overflow-y:auto;max-height:calc(100vh - var(--header-height) - 10rem);position:-webkit-sticky;position:sticky;top:calc(var(--header-height) + 1.5rem)}.workflow-sidebar-label{font-family:var(--font-mono);font-size:.6rem;text-transform:uppercase;letter-spacing:.2em;color:var(--muted);padding:.375rem .75rem .5rem}.workflow-node-item{display:flex;align-items:center;gap:.5rem;width:100%;padding:.5rem .75rem;background:none;cursor:pointer;font-family:var(--font-mono);font-size:.8125rem;color:var(--charcoal);text-align:left;transition:background .15s var(--ease-standard);border:none;border-left:2px solid transparent}.workflow-node-item:hover{background:var(--concrete)}.workflow-node-item--active{background:var(--concrete);border-left-color:var(--patina)}.workflow-node-item--failed{color:var(--rust)}.workflow-node-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.workflow-node-dot--running{animation:signal-pulse var(--duration-pulse) ease-out infinite}.workflow-node-name{flex:1 1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.workflow-node-duration{font-size:.6875rem;color:var(--muted);flex-shrink:0}.workflow-panel{flex:1 1;min-width:0;padding:1.25rem;overflow-y:auto;max-height:calc(100vh - var(--header-height) - 10rem)}.node-detail-meta{font-family:var(--font-mono);font-size:.75rem;color:var(--muted)}@media (max-width:768px){.workflow-layout{flex-direction:column;min-height:auto}.workflow-sidebar{width:100%;max-height:none;position:static;border-right:none;border-bottom:var(--border-width) solid var(--concrete-dark);display:flex;overflow-x:auto;padding:.25rem;gap:.25rem}.workflow-sidebar-label{display:none}.workflow-node-item{white-space:nowrap;padding:.375rem .5rem;border-left:none;border-bottom:2px solid transparent;font-size:.75rem}.workflow-node-item--active{border-bottom-color:var(--patina);border-left-color:transparent}.workflow-panel{max-height:none}}.collapsible-header{display:flex;align-items:center;gap:.375rem;font-family:var(--font-mono);font-size:.75rem;color:var(--muted);cursor:pointer;background:none;border:none;padding:.375rem 0;text-transform:uppercase;letter-spacing:.1em;transition:color .15s var(--ease-standard)}.collapsible-header:hover{color:var(--charcoal)}.collapsible-chevron{font-size:.625rem;line-height:1}.collapsible-content{padding-top:.5rem}.activity-row{cursor:pointer;border-radius:2px;transition:background .15s var(--ease-standard)}.activity-row:hover{background:var(--concrete-dark)}.theme-toggle{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;border-radius:4px;background:transparent;color:var(--muted);cursor:pointer;transition:color .2s var(--ease-standard),background .2s var(--ease-standard)}.theme-toggle:hover{color:var(--charcoal);background:var(--concrete-dark)}.login-page{display:flex;align-items:center;justify-content:center;min-height:100vh;background:var(--concrete)}.login-card{width:320px;background:var(--surface);border:var(--border-width) solid var(--concrete-dark);border-radius:4px;padding:2rem 1.5rem}.login-header{display:flex;align-items:center;gap:.5rem;margin-bottom:1.5rem;color:var(--charcoal)}.login-header h1{font-family:var(--font-display);font-size:1.25rem;font-weight:400}.login-field{margin-bottom:.75rem}.login-field label{display:block;font-family:var(--font-mono);font-size:.625rem;text-transform:uppercase;letter-spacing:.15em;color:var(--muted);margin-bottom:.25rem}.login-field input{width:100%;padding:.5rem .625rem;font-family:var(--font-mono);font-size:.8125rem;color:var(--charcoal);background:var(--concrete);border:var(--border-width) solid var(--concrete-dark);border-radius:3px;outline:none;transition:border-color .15s var(--ease-standard)}.login-field input:focus{border-color:var(--patina)}.login-error{font-family:var(--font-mono);font-size:.75rem;color:var(--rust);margin-bottom:.75rem}.login-btn{width:100%;justify-content:center;margin-top:.25rem}.logout-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;border-radius:4px;background:transparent;color:var(--muted);cursor:pointer;transition:color .2s var(--ease-standard),background .2s var(--ease-standard)}.logout-btn:hover{color:var(--rust);background:var(--concrete-dark)}
@@ -0,0 +1 @@
1
+ self.__BUILD_MANIFEST=function(e,r,t,_){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},__routerFilterStatic:{numItems:11,errorRate:1e-4,numBits:211,numHashes:14,bitArray:[0,0,r,1,r,r,r,r,1,e,r,e,e,e,e,r,e,e,r,r,e,r,e,e,r,r,r,r,r,e,e,r,e,e,e,r,r,r,r,e,r,e,r,e,e,r,e,r,e,e,e,r,r,r,r,r,r,r,r,e,e,e,e,r,e,r,e,r,e,r,e,r,e,r,r,e,r,e,e,r,e,r,r,r,e,e,r,e,r,e,e,e,r,e,e,e,r,e,r,r,e,e,r,e,r,r,e,r,e,e,r,e,r,r,e,e,e,r,e,r,e,e,e,e,e,e,r,e,e,e,r,e,e,e,r,e,r,r,e,e,r,r,e,r,e,e,e,r,e,r,r,r,r,r,r,e,e,r,r,e,r,r,r,e,e,e,r,r,r,r,e,r,e,e,e,e,r,e,r,r,r,e,e,e,r,r,r,r,r,e,e,r,e,e,e,r,e,e,r,r,r,e,r,e,e,r,r,r,e,e,r]},__routerFilterDynamic:{numItems:6,errorRate:1e-4,numBits:116,numHashes:14,bitArray:[r,r,r,e,r,e,r,e,e,e,r,r,r,r,e,e,e,r,r,r,r,r,e,e,e,e,r,e,e,e,r,r,e,e,r,r,e,e,e,e,e,r,e,r,e,e,r,e,e,r,r,e,r,r,r,e,r,r,r,r,r,e,r,e,r,r,e,r,e,e,r,e,r,r,e,e,r,e,e,r,e,e,e,r,e,r,r,e,r,r,e,e,r,e,r,e,r,r,r,r,e,r,e,e,r,r,r,r,e,e,e,e,e,r,e,e]},"/_error":["static/chunks/pages/_error-273a093c18b5ed0f.js"],sortedPages:["/_app","/_error"]}}(1,0,1e-4,14),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "station-kit",
3
- "version": "1.0.8",
3
+ "version": "2.0.0",
4
4
  "description": "Dashboard for station-signal — inspect and control signals and broadcasts",
5
5
  "type": "module",
6
6
  "engines": {
@@ -33,32 +33,34 @@
33
33
  "build": "tsc && next build && cp -r .next/static .next/standalone/packages/station-kit/.next/static",
34
34
  "dev": "tsx src/cli.ts",
35
35
  "typecheck": "tsc --noEmit",
36
- "test": "node --import tsx --test test/**/*.test.ts"
36
+ "test": "node --import tsx --test \"test/**/*.test.ts\""
37
37
  },
38
38
  "peerDependencies": {
39
+ "station-beacon": "workspace:*",
39
40
  "station-broadcast": "workspace:*",
40
41
  "station-signal": "workspace:*"
41
42
  },
42
43
  "dependencies": {
43
44
  "@hono/node-server": "^1",
44
- "better-sqlite3": "^11.9.1",
45
45
  "esbuild": "^0.25.12",
46
46
  "hono": "^4",
47
47
  "next": "^15",
48
48
  "react": "^19",
49
49
  "react-dom": "^19",
50
+ "station-env": "workspace:*",
50
51
  "station-expressions": "workspace:*",
51
52
  "station-schedules": "workspace:*",
52
53
  "tsx": "^4.21.0",
53
54
  "ws": "^8"
54
55
  },
55
56
  "devDependencies": {
56
- "@types/better-sqlite3": "^7.6.13",
57
57
  "@types/node": "^25.3.0",
58
58
  "@types/react": "^19",
59
59
  "@types/react-dom": "^19",
60
60
  "@types/ws": "^8",
61
+ "better-sqlite3": "^11.9.1",
61
62
  "station-adapter-sqlite": "workspace:*",
63
+ "station-beacon": "workspace:*",
62
64
  "station-broadcast": "workspace:*",
63
65
  "station-signal": "workspace:*",
64
66
  "typescript": "^5.9.3"
@@ -1,15 +1,19 @@
1
1
  import type { SignalQueueAdapter } from "station-signal";
2
2
  import type { BroadcastQueueAdapter } from "station-broadcast";
3
+ import type { BeaconStateAdapter } from "station-beacon";
3
4
  import type { ScheduleAdapter } from "station-schedules";
5
+ import type { EnvStorageAdapter } from "station-env";
4
6
  import type { ApiKeyStorageAdapter } from "../server/auth/keys.js";
7
+ import type { LogStorageAdapter } from "../server/log-store.js";
5
8
  export interface AuthConfig {
6
9
  username: string;
7
10
  password: string;
8
11
  sessionTtlMs?: number;
9
12
  /**
10
- * Pluggable storage backend for API keys. Defaults to a SQLite store at
11
- * `<dataDir>/station-keys.db`. Provide a custom adapter to host keys in
12
- * Postgres, MySQL, Redis, etc.
13
+ * Pluggable storage backend for API keys. Defaults to a JSON file at
14
+ * `<dataDir>/station-keys.json` (no native dependencies required).
15
+ * Provide a custom adapter to host keys in SQLite, Postgres, MySQL,
16
+ * Redis, etc.
13
17
  */
14
18
  keyStorage?: ApiKeyStorageAdapter;
15
19
  }
@@ -30,13 +34,37 @@ export interface StationConfig {
30
34
  host: string;
31
35
  adapter?: SignalQueueAdapter;
32
36
  broadcastAdapter?: BroadcastQueueAdapter;
37
+ /**
38
+ * Optional beacon supervision-state adapter. When provided (or when
39
+ * `beaconsDir` is set), the dashboard supervises long-running beacons and
40
+ * exposes them under `/api/beacons`.
41
+ */
42
+ beaconAdapter?: BeaconStateAdapter;
33
43
  /**
34
44
  * Optional schedule storage adapter. When provided, runtime-editable
35
45
  * schedules are persisted here and reconciled by both runners.
36
46
  */
37
47
  scheduleAdapter?: ScheduleAdapter;
48
+ /**
49
+ * Pluggable storage backend for runtime environment variables. Defaults to a
50
+ * JSON file at `<dataDir>/station-env.json` (no native dependencies). When
51
+ * set — or by default — signals/beacons can require env vars via `.env()`,
52
+ * and variables defined here (globally or scoped to specific targets) are
53
+ * injected into runs. For multi-process deployments pass a durable adapter
54
+ * from a `station-adapter-*` package's `/env` subpath.
55
+ */
56
+ envStorage?: EnvStorageAdapter;
57
+ /**
58
+ * Pluggable storage backend for run logs. Defaults to a `FileLogStorage`
59
+ * (append-only JSONL file at `<dataDir>/station-logs.jsonl`, no native
60
+ * dependencies). The default is single-process only — for multi-process
61
+ * deployments or guaranteed durability, implement `LogStorageAdapter`
62
+ * against Postgres, MySQL, Redis, S3, etc., and pass it here.
63
+ */
64
+ logStorage?: LogStorageAdapter;
38
65
  signalsDir?: string;
39
66
  broadcastsDir?: string;
67
+ beaconsDir?: string;
40
68
  stationDir: string;
41
69
  runner: RunnerConfig;
42
70
  broadcastRunner: BroadcastRunnerConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAEnE,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,oBAAoB,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;IACzC;;;OAGG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,eAAe,EAAE,qBAAqB,CAAC;IACvC,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC9C,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,iBAAiB,CAAC,CAAC,GAAG;IAC3F,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAClD,CAAC;AAoBF,wBAAgB,aAAa,CAAC,KAAK,EAAE,iBAAiB,GAAG,aAAa,CA0CrE"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,oBAAoB,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;IACzC;;;;OAIG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC;;;OAGG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,eAAe,EAAE,qBAAqB,CAAC;IACvC,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC9C,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,iBAAiB,CAAC,CAAC,GAAG;IAC3F,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAClD,CAAC;AAoBF,wBAAgB,aAAa,CAAC,KAAK,EAAE,iBAAiB,GAAG,aAAa,CA8CrE"}
@@ -37,9 +37,13 @@ export function resolveConfig(input) {
37
37
  host: input.host ?? envHost ?? DEFAULTS.host,
38
38
  adapter: input.adapter,
39
39
  broadcastAdapter: input.broadcastAdapter,
40
+ beaconAdapter: input.beaconAdapter,
40
41
  scheduleAdapter: input.scheduleAdapter,
42
+ envStorage: input.envStorage,
43
+ logStorage: input.logStorage,
41
44
  signalsDir: input.signalsDir,
42
45
  broadcastsDir: input.broadcastsDir,
46
+ beaconsDir: input.beaconsDir,
43
47
  stationDir: input.stationDir ?? DEFAULTS.stationDir,
44
48
  runner: {
45
49
  pollIntervalMs: input.runner?.pollIntervalMs ?? DEFAULTS.runner.pollIntervalMs,
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AA2DA,MAAM,QAAQ,GAAkB;IAC9B,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,WAAW;IACjB,UAAU,EAAE,UAAU;IACtB,MAAM,EAAE;QACN,cAAc,EAAE,IAAI;QACpB,aAAa,EAAE,CAAC;QAChB,WAAW,EAAE,CAAC;QACd,cAAc,EAAE,IAAI;KACrB;IACD,eAAe,EAAE;QACf,cAAc,EAAE,IAAI;KACrB;IACD,UAAU,EAAE,IAAI;IAChB,IAAI,EAAE,IAAI;IACV,QAAQ,EAAE,MAAM;CACjB,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,KAAwB;IACpD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9E,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;IACjC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;IACtD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;IAEtD,4EAA4E;IAC5E,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACtB,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,GAAG;YACL,GAAG,IAAI;YACP,QAAQ,EAAE,WAAW,IAAI,IAAI,CAAC,QAAQ;YACtC,QAAQ,EAAE,WAAW,IAAI,IAAI,CAAC,QAAQ;SACvC,CAAC;IACJ,CAAC;SAAM,IAAI,WAAW,IAAI,WAAW,EAAE,CAAC;QACtC,IAAI,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;IAC1D,CAAC;IAED,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,OAAO,IAAI,QAAQ,CAAC,IAAI;QAC5C,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,OAAO,IAAI,QAAQ,CAAC,IAAI;QAC5C,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;QACxC,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU;QACnD,MAAM,EAAE;YACN,cAAc,EAAE,KAAK,CAAC,MAAM,EAAE,cAAc,IAAI,QAAQ,CAAC,MAAM,CAAC,cAAc;YAC9E,aAAa,EAAE,KAAK,CAAC,MAAM,EAAE,aAAa,IAAI,QAAQ,CAAC,MAAM,CAAC,aAAa;YAC3E,WAAW,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,IAAI,QAAQ,CAAC,MAAM,CAAC,WAAW;YACrE,cAAc,EAAE,KAAK,CAAC,MAAM,EAAE,cAAc,IAAI,QAAQ,CAAC,MAAM,CAAC,cAAc;SAC/E;QACD,eAAe,EAAE;YACf,cAAc,EAAE,KAAK,CAAC,eAAe,EAAE,cAAc,IAAI,QAAQ,CAAC,eAAe,CAAC,cAAc;SACjG;QACD,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU;QACnD,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI;QACjC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ;QAC7C,IAAI;QACJ,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,4 +3,5 @@ export declare function defineConfig(config: StationUserConfig): StationUserConf
3
3
  export type { StationConfig, StationUserConfig, AuthConfig, DeployConfig } from "./config/schema.js";
4
4
  export { resolveConfig } from "./config/schema.js";
5
5
  export { loadConfig } from "./config/loader.js";
6
+ export { EnvStore, MemoryEnvStorage, FileEnvStorage, type EnvStorageAdapter, type EnvVar, type EnvVarPublic, type EnvTarget, } from "station-env";
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CAEzE;AAED,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACrG,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CAEzE;AAED,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACrG,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIhD,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,KAAK,SAAS,GACf,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -3,4 +3,7 @@ export function defineConfig(config) {
3
3
  }
4
4
  export { resolveConfig } from "./config/schema.js";
5
5
  export { loadConfig } from "./config/loader.js";
6
+ // Re-export the runtime env store surface so consumers can construct custom
7
+ // storage or the store itself without a separate `station-env` import.
8
+ export { EnvStore, MemoryEnvStorage, FileEnvStorage, } from "station-env";
6
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,YAAY,CAAC,MAAyB;IACpD,OAAO,MAAM,CAAC;AAChB,CAAC;AAGD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,YAAY,CAAC,MAAyB;IACpD,OAAO,MAAM,CAAC;AAChB,CAAC;AAGD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,4EAA4E;AAC5E,uEAAuE;AACvE,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,cAAc,GAKf,MAAM,aAAa,CAAC"}
@@ -23,15 +23,49 @@ export interface ApiKeyStorageAdapter {
23
23
  revoke(id: string): Promise<boolean> | boolean;
24
24
  close?(): Promise<void> | void;
25
25
  }
26
+ export interface FileKeyStorageOptions {
27
+ filePath: string;
28
+ }
29
+ /**
30
+ * Default ApiKeyStorageAdapter backed by a JSON file. Used by the Station
31
+ * server when no `keyStorage` is configured. Has no native dependencies —
32
+ * works on any Node 18+ install without compiling bindings.
33
+ *
34
+ * Crash-safety: writes go through a fsync'd tmp-file + rename, with a
35
+ * second fsync on the parent directory so the rename itself survives
36
+ * power loss. The keys file is created with `0o600` and the parent dir
37
+ * with `0o700` so a default umask doesn't expose key metadata.
38
+ *
39
+ * Single-process only: do not point two `createStation` instances at
40
+ * the same file or last-rename-wins will silently clobber writes. For
41
+ * multi-process or high-volume deployments, implement
42
+ * `ApiKeyStorageAdapter` against Postgres / MySQL / Redis.
43
+ */
44
+ export declare class FileKeyStorage implements ApiKeyStorageAdapter {
45
+ private filePath;
46
+ private records;
47
+ constructor(options: FileKeyStorageOptions);
48
+ private load;
49
+ private flush;
50
+ insert(record: ApiKey): void;
51
+ findByHash(keyHash: string): ApiKey | null;
52
+ list(): ApiKeyPublic[];
53
+ touch(id: string, lastUsedIso: string): void;
54
+ revoke(id: string): boolean;
55
+ }
26
56
  export interface SqliteKeyStorageOptions {
27
57
  dbPath: string;
28
58
  /** Override the table name (default: "api_keys"). */
29
59
  tableName?: string;
30
60
  }
31
61
  /**
32
- * Default ApiKeyStorageAdapter backed by better-sqlite3. Used by the Station
33
- * server when no `keyStorage` is configured. For Postgres / MySQL / Redis,
34
- * implement `ApiKeyStorageAdapter` and pass it to `KeyStore` directly.
62
+ * Optional ApiKeyStorageAdapter backed by better-sqlite3. Requires the
63
+ * `better-sqlite3` package to be installed separately Station Kit no
64
+ * longer ships it as a hard dependency.
65
+ *
66
+ * Prefer `FileKeyStorage` (the default) unless you specifically need
67
+ * sqlite features (concurrent reads from multiple processes, large
68
+ * key catalogs, etc.).
35
69
  */
36
70
  export declare class SqliteKeyStorage implements ApiKeyStorageAdapter {
37
71
  private db;
@@ -40,6 +74,8 @@ export declare class SqliteKeyStorage implements ApiKeyStorageAdapter {
40
74
  insert(record: ApiKey): void;
41
75
  findByHash(keyHash: string): ApiKey | null;
42
76
  list(): ApiKeyPublic[];
77
+ /** Last persisted lastUsed per key id, to skip per-request UPDATEs. */
78
+ private lastTouched;
43
79
  touch(id: string, lastUsedIso: string): void;
44
80
  revoke(id: string): boolean;
45
81
  close(): void;
@@ -52,14 +88,30 @@ export declare class MemoryKeyStorage implements ApiKeyStorageAdapter {
52
88
  touch(id: string, lastUsedIso: string): void;
53
89
  revoke(id: string): boolean;
54
90
  }
91
+ export interface KeyStoreOptions {
92
+ /**
93
+ * Server-side secret ("pepper") mixed into stored key hashes via HMAC.
94
+ * Defense-in-depth: a leaked key file alone can't be brute-forced or
95
+ * precomputed against without also stealing this secret. Optional — when
96
+ * omitted, keys are hashed with plain SHA-256 (legacy behavior). Existing
97
+ * plain-SHA-256 keys keep verifying after a pepper is added (see verify()).
98
+ */
99
+ pepper?: string;
100
+ }
55
101
  export declare class KeyStore {
56
102
  private storage;
103
+ private pepper?;
57
104
  /**
58
105
  * Pass an `ApiKeyStorageAdapter` for any backend. The string overload is
59
- * retained for backwards compatibility — it constructs a SqliteKeyStorage
60
- * at the given path.
106
+ * retained for backwards compatibility — it constructs a FileKeyStorage
107
+ * at the given path. (Previously this returned a SqliteKeyStorage; SQLite
108
+ * is now opt-in to avoid native build dependencies.)
61
109
  */
62
- constructor(storageOrDbPath: ApiKeyStorageAdapter | string);
110
+ constructor(storageOrPath: ApiKeyStorageAdapter | string, options?: KeyStoreOptions);
111
+ /** Peppered hash for new keys — HMAC-SHA256 when a pepper is set, else SHA-256. */
112
+ private hashKey;
113
+ /** Unpeppered SHA-256 — used to verify keys stored before a pepper was configured. */
114
+ private legacyHashKey;
63
115
  /** Generate a new API key. Returns the full key (only shown once) and the stored record. */
64
116
  create(name: string, scopes?: string[]): Promise<{
65
117
  key: string;
@@ -1 +1 @@
1
- {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../src/server/auth/keys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../src/server/auth/keys.ts"],"names":[],"mappings":"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"}