@stacksjs/ts-cloud 0.12.9 → 0.12.10

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 (63) hide show
  1. package/dist/aws/index.js +1 -1
  2. package/dist/aws/sms-voice.d.ts +35 -0
  3. package/dist/bin/cli.js +2 -2
  4. package/dist/{chunk-a5213256.js → chunk-gkj1tpsn.js} +6 -6
  5. package/dist/{chunk-fgfm7cfm.js → chunk-y3tbcxb7.js} +1 -1
  6. package/dist/deploy/index.js +1 -1
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.js +1 -1
  9. package/dist/ui/404.html +1 -1
  10. package/dist/ui/accept-invitation.html +1 -1
  11. package/dist/ui/access-denied.html +1 -1
  12. package/dist/ui/account/automation.html +6 -6
  13. package/dist/ui/account/security.html +2 -2
  14. package/dist/ui/applications/compose.html +6 -6
  15. package/dist/ui/applications/new.html +2 -2
  16. package/dist/ui/data/backups.html +6 -6
  17. package/dist/ui/data/services.html +5 -5
  18. package/dist/ui/data/volumes.html +5 -5
  19. package/dist/ui/index.html +6 -6
  20. package/dist/ui/infrastructure/topology.html +6 -6
  21. package/dist/ui/integrations.html +2 -2
  22. package/dist/ui/operations/alerts.html +6 -6
  23. package/dist/ui/operations/configuration.html +6 -6
  24. package/dist/ui/operations/jobs.html +6 -6
  25. package/dist/ui/operations/maintenance.html +5 -5
  26. package/dist/ui/operations/observability.html +6 -6
  27. package/dist/ui/operations/previews.html +6 -6
  28. package/dist/ui/operations/queue.html +6 -6
  29. package/dist/ui/operations/regions.html +5 -5
  30. package/dist/ui/operations/releases.html +5 -5
  31. package/dist/ui/operations/spend.html +6 -6
  32. package/dist/ui/operations/workloads.html +6 -6
  33. package/dist/ui/security.html +2 -2
  34. package/dist/ui/server/actions.html +6 -6
  35. package/dist/ui/server/activity.html +2 -2
  36. package/dist/ui/server/capacity.html +6 -6
  37. package/dist/ui/server/database.html +5 -5
  38. package/dist/ui/server/deployments.html +5 -5
  39. package/dist/ui/server/diagnostics.html +2 -2
  40. package/dist/ui/server/firewall.html +6 -6
  41. package/dist/ui/server/fleet.html +5 -5
  42. package/dist/ui/server/logs.html +6 -6
  43. package/dist/ui/server/metrics.html +5 -5
  44. package/dist/ui/server/security.html +2 -2
  45. package/dist/ui/server/services.html +2 -2
  46. package/dist/ui/server/sites.html +6 -6
  47. package/dist/ui/server/ssh-keys.html +6 -6
  48. package/dist/ui/server/team.html +6 -6
  49. package/dist/ui/server/terminal.html +2 -2
  50. package/dist/ui/serverless/alarms.html +6 -6
  51. package/dist/ui/serverless/assets.html +2 -2
  52. package/dist/ui/serverless/cost.html +1 -1
  53. package/dist/ui/serverless/data.html +5 -5
  54. package/dist/ui/serverless/deployments.html +2 -2
  55. package/dist/ui/serverless/firewall.html +1 -1
  56. package/dist/ui/serverless/functions.html +6 -6
  57. package/dist/ui/serverless/logs.html +6 -6
  58. package/dist/ui/serverless/metrics.html +2 -2
  59. package/dist/ui/serverless/queues.html +5 -5
  60. package/dist/ui/serverless/secrets.html +6 -6
  61. package/dist/ui/serverless/traces.html +6 -6
  62. package/dist/ui/serverless.html +6 -6
  63. package/package.json +3 -3
@@ -1,5 +1,5 @@
1
- <!DOCTYPE html><html lang="en" data-theme="dark"><head><meta charset="UTF-8"><meta name="stx-build" content="mtekc2s63mrzwt"><meta name="title" content="stx Project"><meta name="description" content="A website built with stx templating engine"><meta property="og:title" content="stx Project"><meta property="og:description" content="A website built with stx templating engine"><meta property="og:type" content="website"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="stx Project"><meta name="twitter:description" content="A website built with stx templating engine"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ts-cloud · Workers &amp; schedules</title><link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect x='3' y='3' width='26' height='26' rx='8' fill='%235a8be0'/%3E%3C/svg%3E"><link rel="preconnect" href="https://fonts.googleapis.com"><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"><link rel="stylesheet" href="/_stx/style.448ab192.css"> <script data-stx-runtime src="/_stx/runtime.dbee66d1.js"></script> <script data-stx-composables src="/_stx/chunk.5ddb5087.js"></script> <script data-stx-scoped>
2
- function __stx_setup_1788018981018_8() {
1
+ <!DOCTYPE html><html lang="en" data-theme="dark"><head><meta charset="UTF-8"><meta name="stx-build" content="mtekhpm3jmsm9i"><meta name="title" content="stx Project"><meta name="description" content="A website built with stx templating engine"><meta property="og:title" content="stx Project"><meta property="og:description" content="A website built with stx templating engine"><meta property="og:type" content="website"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="stx Project"><meta name="twitter:description" content="A website built with stx templating engine"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ts-cloud · Workers &amp; schedules</title><link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect x='3' y='3' width='26' height='26' rx='8' fill='%235a8be0'/%3E%3C/svg%3E"><link rel="preconnect" href="https://fonts.googleapis.com"><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"><link rel="stylesheet" href="/_stx/style.448ab192.css"> <script data-stx-runtime src="/_stx/runtime.dbee66d1.js"></script> <script data-stx-composables src="/_stx/chunk.5ddb5087.js"></script> <script data-stx-scoped>
2
+ function __stx_setup_1788019243862_13() {
3
3
  const { batch, computed, configureFetch, defineEmits, defineExpose, definePageMeta, defineProps, defineSlots, defineStore, derived, effect, goBack, goForward, inject, invalidateRoute, isDerived, isSignal, navigate, nextTick, onBeforeMount, onBeforeUnmount, onDestroy, onMount, onMounted, onUnmounted, peek, provide, reactive, ref, registerStoresClient, setRouteParams, state, untrack, useAsync, useClickOutside, useColorMode, useCookie, useCounter, useDark, useDebounce, useDebouncedValue, useEventListener, useFetch, useFocus, useHead, useId, useInterval, useLocalStorage, useMediaQuery, useMutation, useOptimistic, usePreferredContrast, usePreferredDark, usePreferredLight, usePreferredReducedMotion, useQuery, useReactiveProp, useRef, useRoute, useRouteParam, useRouteParams, useScrollLock, useSearchParams, useSeoMeta, useSessionStorage, useSlots, useStore, useThrottle, useTimeout, useToggle, useWebSocket, watch, watchEffect, watchMultiple, withDefaults } = window.stx;
4
4
 
5
5
  var actionError = undefined;
@@ -315,9 +315,9 @@ when = __stxBundle_da87383c4b96["when"];
315
315
  workers = __stxBundle_da87383c4b96["workers"];
316
316
  return { actionError, api, busy, createJob, duration, editJob, filteredJobs, formBody, history, jobAction, jobs, lastUpdatedAt, load, mode, notice, operations, pollingError, pollingState, preview, previewForm, previewTimer, providerFilter, queuePreview, reconcile, refresh, restartWorker, search, selectedJob, setPreset, showHistory, statusFilter, tab, tone, when, workers, __stxBundle_da87383c4b96 };
317
317
  }
318
- window.__stx_latestSetup=__stx_setup_1788018981018_8;
319
- if(window.stx)window.stx._latestSetup=__stx_setup_1788018981018_8;
320
- </script> <style data-stx-cloak>[x-cloak]{display:none !important}</style><link data-crosswind="generated" rel="stylesheet" href="/_stx/crosswind.906ee17c.css"></head><body data-stx="__stx_setup_1788018981018_8"><a data-stx-scope="stx_scope_nav_11" class="skip-link" href="#main-content">Skip to content</a><button class="nav-toggle-button" type="button" aria-label="Open navigation" aria-controls="primary-navigation" aria-expanded="false"><span></span><span></span><span></span></button><button class="nav-scrim" type="button" aria-label="Close navigation"></button><aside class="app-sidebar" id="primary-navigation" aria-label="Primary navigation"><a class="brand" href="/?env=production"><span class="dot"></span><span>ts-cloud</span></a><div class="sidebar-context"><span class="context-label">Project</span><strong>Project</strong></div><div class="environment-picker" aria-label="Environment"><span class="context-label">Environment</span><details><summary class="environment-current production"><span>PROD</span><strong>production</strong></summary></details></div><button class="command-trigger" type="button" aria-keyshortcuts="Meta+K Control+K"><span>Search resources</span><kbd>⌘ K</kbd></button><div class="nav-groups"><section class="nav-group"><h2>Overview</h2><a class="" href="/?env=production">Dashboard</a><a href="/server/activity?env=production">Activity</a></section><section class="nav-group"><h2>Applications</h2><a class="" href="/server/sites?env=production">Services</a><a class="" href="/server/deployments?env=production">Deployments</a><a class="" href="/server/logs?env=production">Logs</a><a class="" href="/integrations?env=production">Git integrations</a><a class="" href="/applications/new?env=production">Create application</a><a class="" href="/applications/compose?env=production">Compose applications</a></section><section class="nav-group"><h2>Operations</h2><a class="" href="/operations/queue?env=production">Deployment queue</a><a class="" href="/operations/previews?env=production">Preview environments</a><a class="" href="/operations/releases?env=production">Releases & promotion</a><a class="" href="/operations/regions?env=production">Regions & failover</a><a class="" href="/operations/maintenance?env=production">Maintenance & DR</a><a class="" href="/operations/workloads?env=production">Workloads</a><a class="" href="/operations/observability?env=production">Observability</a><a class="" href="/operations/alerts?env=production">Alerts & health</a><a class="" href="/operations/spend?env=production">Spend & budgets</a><a href="/server/metrics?env=production">Metrics</a><a href="/server/services?env=production">Runtime services</a><a class="active" href="/operations/jobs?env=production">Workers & schedules</a><a class="" href="/operations/configuration?env=production">Environment &amp; secrets</a><a class="" href="/data/backups?env=production">Backups &amp; recovery</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/actions?env=production">Run operations</a></section><section class="nav-group"><h2>Infrastructure</h2><a class="" href="/infrastructure/topology?env=production">Infrastructure map</a><a class="" href="/data/services?env=production">Data services</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/firewall?env=production">Network & firewall</a><a href="/server/ssh-keys?env=production">SSH keys</a><a class="" href="/server/fleet?env=production">Fleet inventory</a><a class="" href="/server/capacity?env=production">Capacity & placement</a><a href="/security?env=production">Security posture</a><a href="/server/terminal?env=production">Terminal</a></section><section class="nav-group"><h2>Organization</h2><a class="" href="/server/team?env=production">People & access</a><a class="" href="/account/automation?env=production">API & automation</a></section><section class="nav-group"><h2>Account</h2><a class="" href="/account/security?env=production">Sign-in & security</a></section></div><form method="post" action="/api/logout" class="signout"><button type="submit">Sign out</button></form></aside><dialog class="command-palette" aria-labelledby="command-title"><div class="command-search"><span aria-hidden="true">⌕</span><input type="search" placeholder="Search services, domains, deployments…" aria-label="Search resources" autocomplete="off"><button type="button" class="command-close" aria-label="Close search">Esc</button></div><h2 id="command-title" class="sr-only">Search resources and navigation</h2><div class="command-status" role="status">Start typing to search this project.</div><section class="saved-views" aria-labelledby="saved-views-title"><div class="saved-views-heading"><h3 id="saved-views-title">Saved views</h3><form class="save-view-form"><label class="sr-only" for="save-view-name">Saved view name</label><input id="save-view-name" maxlength="64" placeholder="Name this view" autocomplete="off"><button type="submit">Save current filters</button></form></div><div class="saved-view-list"></div></section><form class="tag-result-form"><label for="tag-result-name">Tag selected resource</label><input id="tag-result-name" maxlength="32" placeholder="customer-facing" pattern="[A-Za-z0-9][A-Za-z0-9 -]{0,31}" autocomplete="off"><input class="tag-color" type="color" value="#5a8be0" aria-label="Tag color"><button type="submit">Add tag</button></form><div class="command-results" role="listbox" aria-label="Search results"></div><footer><span>↑ ↓ navigate</span><span>Enter open</span><span>Esc close</span></footer></dialog><div class="context-bar" aria-label="Current scope"><div class="context-path"><div class="context-breadcrumb"><span>Project</span><i>/</i><strong>production</strong></div><div class="context-filters" aria-label="Active filters"></div></div><span class="scope-safety production">Production scope</span></div> <script data-stx-scoped data-stx-run="always">
318
+ window.__stx_latestSetup=__stx_setup_1788019243862_13;
319
+ if(window.stx)window.stx._latestSetup=__stx_setup_1788019243862_13;
320
+ </script> <style data-stx-cloak>[x-cloak]{display:none !important}</style><link data-crosswind="generated" rel="stylesheet" href="/_stx/crosswind.906ee17c.css"></head><body data-stx="__stx_setup_1788019243862_13"><a data-stx-scope="stx_scope_nav_17" class="skip-link" href="#main-content">Skip to content</a><button class="nav-toggle-button" type="button" aria-label="Open navigation" aria-controls="primary-navigation" aria-expanded="false"><span></span><span></span><span></span></button><button class="nav-scrim" type="button" aria-label="Close navigation"></button><aside class="app-sidebar" id="primary-navigation" aria-label="Primary navigation"><a class="brand" href="/?env=production"><span class="dot"></span><span>ts-cloud</span></a><div class="sidebar-context"><span class="context-label">Project</span><strong>Project</strong></div><div class="environment-picker" aria-label="Environment"><span class="context-label">Environment</span><details><summary class="environment-current production"><span>PROD</span><strong>production</strong></summary></details></div><button class="command-trigger" type="button" aria-keyshortcuts="Meta+K Control+K"><span>Search resources</span><kbd>⌘ K</kbd></button><div class="nav-groups"><section class="nav-group"><h2>Overview</h2><a class="" href="/?env=production">Dashboard</a><a href="/server/activity?env=production">Activity</a></section><section class="nav-group"><h2>Applications</h2><a class="" href="/server/sites?env=production">Services</a><a class="" href="/server/deployments?env=production">Deployments</a><a class="" href="/server/logs?env=production">Logs</a><a class="" href="/integrations?env=production">Git integrations</a><a class="" href="/applications/new?env=production">Create application</a><a class="" href="/applications/compose?env=production">Compose applications</a></section><section class="nav-group"><h2>Operations</h2><a class="" href="/operations/queue?env=production">Deployment queue</a><a class="" href="/operations/previews?env=production">Preview environments</a><a class="" href="/operations/releases?env=production">Releases & promotion</a><a class="" href="/operations/regions?env=production">Regions & failover</a><a class="" href="/operations/maintenance?env=production">Maintenance & DR</a><a class="" href="/operations/workloads?env=production">Workloads</a><a class="" href="/operations/observability?env=production">Observability</a><a class="" href="/operations/alerts?env=production">Alerts & health</a><a class="" href="/operations/spend?env=production">Spend & budgets</a><a href="/server/metrics?env=production">Metrics</a><a href="/server/services?env=production">Runtime services</a><a class="active" href="/operations/jobs?env=production">Workers & schedules</a><a class="" href="/operations/configuration?env=production">Environment &amp; secrets</a><a class="" href="/data/backups?env=production">Backups &amp; recovery</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/actions?env=production">Run operations</a></section><section class="nav-group"><h2>Infrastructure</h2><a class="" href="/infrastructure/topology?env=production">Infrastructure map</a><a class="" href="/data/services?env=production">Data services</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/firewall?env=production">Network & firewall</a><a href="/server/ssh-keys?env=production">SSH keys</a><a class="" href="/server/fleet?env=production">Fleet inventory</a><a class="" href="/server/capacity?env=production">Capacity & placement</a><a href="/security?env=production">Security posture</a><a href="/server/terminal?env=production">Terminal</a></section><section class="nav-group"><h2>Organization</h2><a class="" href="/server/team?env=production">People & access</a><a class="" href="/account/automation?env=production">API & automation</a></section><section class="nav-group"><h2>Account</h2><a class="" href="/account/security?env=production">Sign-in & security</a></section></div><form method="post" action="/api/logout" class="signout"><button type="submit">Sign out</button></form></aside><dialog class="command-palette" aria-labelledby="command-title"><div class="command-search"><span aria-hidden="true">⌕</span><input type="search" placeholder="Search services, domains, deployments…" aria-label="Search resources" autocomplete="off"><button type="button" class="command-close" aria-label="Close search">Esc</button></div><h2 id="command-title" class="sr-only">Search resources and navigation</h2><div class="command-status" role="status">Start typing to search this project.</div><section class="saved-views" aria-labelledby="saved-views-title"><div class="saved-views-heading"><h3 id="saved-views-title">Saved views</h3><form class="save-view-form"><label class="sr-only" for="save-view-name">Saved view name</label><input id="save-view-name" maxlength="64" placeholder="Name this view" autocomplete="off"><button type="submit">Save current filters</button></form></div><div class="saved-view-list"></div></section><form class="tag-result-form"><label for="tag-result-name">Tag selected resource</label><input id="tag-result-name" maxlength="32" placeholder="customer-facing" pattern="[A-Za-z0-9][A-Za-z0-9 -]{0,31}" autocomplete="off"><input class="tag-color" type="color" value="#5a8be0" aria-label="Tag color"><button type="submit">Add tag</button></form><div class="command-results" role="listbox" aria-label="Search results"></div><footer><span>↑ ↓ navigate</span><span>Enter open</span><span>Esc close</span></footer></dialog><div class="context-bar" aria-label="Current scope"><div class="context-path"><div class="context-breadcrumb"><span>Project</span><i>/</i><strong>production</strong></div><div class="context-filters" aria-label="Active filters"></div></div><span class="scope-safety production">Production scope</span></div> <script data-stx-scoped data-stx-run="always">
321
321
  (function() {
322
322
  var { batch, computed, configureFetch, defineEmits, defineExpose, definePageMeta, defineProps, defineSlots, defineStore, derived, effect, goBack, goForward, inject, invalidateRoute, isDerived, isSignal, navigate, nextTick, onBeforeMount, onBeforeUnmount, onDestroy, onMount, onMounted, onUnmounted, peek, provide, reactive, ref, refresh, registerStoresClient, setRouteParams, state, untrack, useAsync, useClickOutside, useColorMode, useCookie, useCounter, useDark, useDebounce, useDebouncedValue, useEventListener, useFetch, useFocus, useHead, useId, useInterval, useLocalStorage, useMediaQuery, useMutation, useOptimistic, usePreferredContrast, usePreferredDark, usePreferredLight, usePreferredReducedMotion, useQuery, useReactiveProp, useRef, useRoute, useRouteParam, useRouteParams, useScrollLock, useSearchParams, useSeoMeta, useSessionStorage, useSlots, useStore, useThrottle, useTimeout, useToggle, useWebSocket, watch, watchEffect, watchMultiple, withDefaults } = window.stx;
323
323
  var __destroyHooks = [];
@@ -668,6 +668,6 @@ if(window.stx)window.stx._latestSetup=__stx_setup_1788018981018_8;
668
668
 
669
669
 
670
670
  try { if (typeof __stxScopeRenames !== 'undefined' && __stxScopeRenames) { for (var __stxRK in __stxScopeRenames) __scopeRegistration[__stxRK] = __stxScopeRenames[__stxRK]; } } catch (e) { /* no renames */ }
671
- window.stx._scopes['stx_scope_nav_11'] = __scopeRegistration;
671
+ window.stx._scopes['stx_scope_nav_17'] = __scopeRegistration;
672
672
  })();
673
673
  </script> <main class="jobs-wrap wrap" id="main-content"><div class="crumbs">Operations <span class="sep">/</span> Workers &amp; schedules</div><header class="page"><div><h1>Workers &amp; schedules</h1><p>One control plane for cron, EventBridge schedules, recurring operations, queue workers, retries, and execution evidence.</p></div><div class="header-actions" x-cloak><span class="pill" :class="pollingState()==='live'?'ok':'warn'" x-cloak>{{ pollingState() }}</span><small x-cloak>{{ lastUpdatedAt()?.toLocaleTimeString() || 'connecting' }}</small><button class="btn ghost sm" @click="refresh()">Refresh</button><button class="btn ghost sm" @click="reconcile()">Reconcile config</button></div></header><p class="notice" role="status" @show="!!notice()" x-cloak>{{ notice() }}</p><p class="bad notice" role="alert" @show="!!actionError() || !!pollingError()" x-cloak>{{ actionError() || pollingError() }}</p><div class="summary"><article class="panel"><b>Schedules</b><strong x-cloak>{{ jobs().length }}</strong><small x-cloak>{{ jobs().filter(item=>item.enabled).length }} enabled</small></article><article class="panel"><b>Workers</b><strong x-cloak>{{ workers().length }}</strong><small x-cloak>{{ workers().reduce((sum,item)=>sum+item.processes,0) }} processes</small></article><article class="panel"><b>Needs review</b><strong x-cloak>{{ jobs().filter(item=>['drifted','unsupported','unavailable'].includes(item.reconciliationStatus)).length + workers().filter(item=>['drifted','unsupported','unavailable'].includes(item.reconciliationStatus)).length }}</strong><small>drift or provider gaps</small></article><article class="panel"><b>Failed last run</b><strong x-cloak>{{ jobs().filter(item=>['failed','dead'].includes(item.lastExecution?.status)).length }}</strong><small>retry from history</small></article></div><nav class="tabs" aria-label="Jobs workspace"><button :class="{active:tab()==='schedules'}" @click="tab.set('schedules')">Schedules</button><button :class="{active:tab()==='workers'}" @click="tab.set('workers')">Workers</button><button :class="{active:tab()==='history'}" @click="tab.set('history')">Execution history</button></nav><section @show="tab()==='schedules'" class="schedule-layout" x-cloak><div><div class="filters panel"><input aria-label="Search schedules" type="search" placeholder="Search name, expression, timezone" @input="search.set($event.currentTarget.value)"><select aria-label="Filter provider" @change="providerFilter.set($event.currentTarget.value)"><option value="all">All providers</option><option value="server">Server cron</option><option value="eventbridge">EventBridge</option><option value="platform">Platform</option></select><select aria-label="Filter state" @change="statusFilter.set($event.currentTarget.value)"><option value="all">All states</option><option value="enabled">Enabled</option><option value="disabled">Disabled</option></select></div><div class="cards-list" x-cloak><template :for="item in filteredJobs()"><article class="job-card panel" x-cloak><div class="job-title" x-cloak><div x-cloak><span class="pill" :class="item.enabled?'ok':'warn'" x-cloak>{{ item.enabled?'enabled':'disabled' }}</span><span class="pill" x-cloak>{{ item.provider }}</span><span class="pill" :class="tone(item.reconciliationStatus)" x-cloak>{{ item.reconciliationStatus }}</span><h2 x-cloak>{{ item.name }}</h2></div><div class="actions"><button class="btn ghost sm" :disabled="busy()" @click="jobAction(item,'run')">Run now</button><button class="btn ghost sm" @click="showHistory(item)">History</button><button class="btn ghost sm" @click="editJob(item)">Edit</button><button class="btn ghost sm" @click="jobAction(item,item.enabled?'disable':'enable')" x-cloak>{{ item.enabled?'Disable':'Enable' }}</button><button class="btn danger sm" @show="item.origin!=='config'" @click="jobAction(item,'delete')" x-cloak>Delete</button></div></div><div class="job-grid"><div><small>Schedule</small><code x-cloak>{{ item.expression }}</code><span x-cloak>{{ item.timezone }}</span></div><div><small>Next run</small><b x-cloak>{{ when(item.nextRunAt) }}</b><span x-cloak>Last {{ when(item.lastExecution?.finishedAt || item.lastScheduledFor) }}</span></div><div><small>Target</small><b x-cloak>{{ item.target.operationId || item.target.action || item.target.functionName || item.target.kind }}</b><span x-cloak>{{ item.origin }} · owner {{ item.ownerActorId || 'configuration' }}</span></div><div><small>Policies</small><b x-cloak>{{ item.overlapPolicy }} overlap · {{ item.missedRunPolicy }}</b><span x-cloak>{{ item.retryPolicy.maxAttempts }} attempts · {{ item.timeoutSeconds }}s timeout</span></div></div><div class="run-preview"><small>Next five</small><span x-cloak>{{ item.preview?.nextRuns?.map(when).join(' · ') || 'No run in active window' }}</span></div><p class="bad note" @show="!!item.lastExecution?.error" x-cloak>{{ item.lastExecution.error }}</p></article></template><div class="empty panel" @show="!filteredJobs().length" x-cloak><strong>No schedules match</strong><span>Create a recurring operation or adjust the filters. Empty means no provider execution will occur.</span></div></div></div><form class="editor panel" @submit="createJob($event)" @input="queuePreview($event.currentTarget)"><h2>New schedule</h2><p class="note" x-cloak>Provider: <b x-cloak>{{ mode()==='serverless'?'EventBridge Scheduler':'server cron' }}</b>. Targets are constrained to safe, configured operations.</p><label>Name<input name="name" required maxlength="120" placeholder="Nightly backup verification"></label><label>Preset<select @change="setPreset($event)"><option value="">Custom</option><option value="every_minute">Every minute</option><option value="hourly">Hourly</option><option value="daily">Daily</option><option value="weekly">Weekly</option><option value="monthly">Monthly</option><option value="rate(5 minutes)">Every 5 minutes</option></select></label><label class="wide">Expression<input name="expression" class="mono" required value="0 * * * *" placeholder="cron or rate(5 minutes)"></label><label>Timezone<input name="timezone" required value="UTC" placeholder="America/Los_Angeles"></label><label @show="mode()==='server'" x-cloak><span>Allowlisted target</span><select name="operationId" :required="mode()==='server'"><option value="">Choose operation</option><template :for="operation in operations()"><option :value="operation.id">{{ operation.label }}</option></template></select></label><label>Starts at<input name="startsAt" type="datetime-local"></label><label>Ends at<input name="endsAt" type="datetime-local"></label><label>Flexible window (minutes)<input name="flexibleMinutes" type="number" min="0" max="1440" value="0"></label><label>Missed runs<select name="missedRunPolicy"><option value="skip">Skip</option><option value="catch_up">Catch up (max 10)</option></select></label><label>Overlap<select name="overlapPolicy"><option value="forbid">Forbid</option><option value="allow">Allow</option><option value="replace">Replace active run</option></select></label><label>Max attempts<input name="maxAttempts" type="number" min="1" max="20" value="3"></label><label>Backoff seconds<input name="backoffSeconds" type="number" min="0" value="30"></label><label>Timeout seconds<input name="timeoutSeconds" type="number" min="1" max="86400" value="900"></label><label class="wide">Dead-letter reference<input name="deadLetterRef" placeholder="arn://aws/sqs/... or secret://jobs/dlq"></label><label class="wide">Payload reference (optional)<input name="payloadRef" placeholder="secret://jobs/nightly-input"><span>Inline payload values are rejected. Use secret://, ssm://, arn://, or env:// references.</span></label><div class="preview wide" @show="!!preview()" x-cloak><b x-cloak>{{ preview()?.description }}</b><code x-cloak>{{ preview()?.normalized }}</code><ol><template :for="run in preview()?.nextRuns || []"><li x-cloak>{{ when(run) }}</li></template></ol><p class="note">Preview only—no production execution or incident is created.</p></div><button class="btn wide" type="submit" :disabled="busy() || (mode()==='server' && !operations().length)" x-cloak>{{ busy()?'Creating…':'Create schedule' }}</button><p class="bad note wide" @show="mode()==='server' && !operations().length" x-cloak>No safe recurring target is configured. Enable a scheduler, worker, or backup operation first.</p></form></section><section @show="tab()==='workers'" class="cards-list" x-cloak><template :for="item in workers()"><article class="panel worker-card" x-cloak><div x-cloak><span class="pill" x-cloak>{{ item.provider }}</span><span class="pill" :class="tone(item.observedState?.status || item.reconciliationStatus)" x-cloak>{{ item.observedState?.status || item.reconciliationStatus }}</span><h2 x-cloak>{{ item.name }}</h2></div><div class="job-grid"><div><small>Queue</small><b x-cloak>{{ item.queue }}</b><span x-cloak>{{ item.processes }} processes</span></div><div><small>Current job</small><b x-cloak>{{ item.observedState?.currentJob || 'idle / unavailable' }}</b><span x-cloak>{{ item.observedState?.processed || 0 }} processed</span></div><div><small>Failures</small><b x-cloak>{{ item.observedState?.failures || 0 }}</b><span x-cloak>{{ item.timeoutSeconds }}s timeout</span></div><div><small>Lifecycle</small><b x-cloak>{{ item.restartPolicy }}</b><span x-cloak>{{ item.origin }} · {{ item.reconciliationStatus }}</span></div></div><div class="actions"><button class="btn ghost sm" @show="item.provider==='systemd'" @click="restartWorker(item)" x-cloak>Graceful restart</button><span class="note" @show="item.provider!=='systemd'" x-cloak>Scaling and restarts remain provider/config managed for this worker.</span></div></article></template><div class="empty panel" @show="!workers().length" x-cloak><strong>No workers configured</strong><span>Add site queues or serverless queue definitions, then reconcile configuration.</span></div></section><section @show="tab()==='history'" x-cloak><div class="empty panel" @show="!selectedJob()" x-cloak><strong>Select a schedule</strong><span>Open History from a schedule to inspect attempts, retry state, duration, output, and redacted logs.</span></div><div @show="!!selectedJob()" x-cloak><header class="history-head" x-cloak><div x-cloak><h2 x-cloak>{{ selectedJob()?.name }}</h2><p class="note">At-least-once execution evidence; retries reuse the durable operation and preserve every log line.</p></div><button class="btn sm" @click="jobAction(selectedJob(),'run')">Run again</button></header><div class="cards-list" x-cloak><template :for="item in history()"><article class="execution panel" x-cloak><div class="execution-head" x-cloak><span class="pill" :class="tone(item.status)" x-cloak>{{ item.status }}</span><b x-cloak>{{ when(item.scheduledFor) }}</b><span x-cloak>{{ item.trigger }} · attempt {{ item.attempt }} · {{ duration(item) }}</span></div><p class="bad note" @show="!!item.error" x-cloak>{{ item.error }}</p><pre @show="item.logs?.length" x-cloak>{{ item.logs?.map(log=>'['+log.stream+'] '+log.message).join('\n') }}</pre><pre @show="Object.keys(item.output||{}).length" x-cloak>{{ JSON.stringify(item.output,null,2) }}</pre></article></template><div class="empty panel" @show="!history().length" x-cloak><strong>No executions</strong><span>Run the schedule manually or wait for its next due time.</span></div></div></div></section></main><style> .jobs-wrap{max-width:1500px}.summary{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:16px}.summary article{display:grid;gap:5px}.summary strong{font-size:28px}.summary small{color:var(--txt3)}.tabs{display:flex;gap:5px;overflow:auto;border-bottom:1px solid var(--line);margin-bottom:18px}.tabs button{border:0;background:transparent;color:var(--txt3);padding:10px 14px;white-space:nowrap}.tabs button.active{color:var(--txt);border-bottom:2px solid var(--accent)}.schedule-layout{display:grid;grid-template-columns:minmax(0,1.6fr) minmax(340px,.8fr);gap:14px;align-items:start}.filters{display:grid;grid-template-columns:1fr 170px 150px;gap:8px;margin-bottom:10px}.filters input,.filters select,.editor input,.editor select{width:100%;background:var(--bg2);border:1px solid var(--line);border-radius:8px;color:var(--txt);padding:9px}.cards-list{display:grid;gap:10px}.job-title,.execution-head,.history-head{display:flex;justify-content:space-between;gap:10px;align-items:center;flex-wrap:wrap}.job-title>div:first-child,.worker-card>div:first-child{display:flex;gap:7px;align-items:center;flex-wrap:wrap}.job-title h2,.worker-card h2{font-size:17px;margin:0 0 0 4px}.actions{display:flex;gap:6px;align-items:center;flex-wrap:wrap}.job-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;margin-top:14px}.job-grid>div{display:grid;gap:4px;min-width:0}.job-grid small,.run-preview small{color:var(--txt3);text-transform:uppercase;font-size:9px;letter-spacing:.08em}.job-grid span,.run-preview span{color:var(--txt3);font-size:11px;overflow-wrap:anywhere}.job-grid code{overflow-wrap:anywhere}.run-preview{display:grid;gap:4px;border-top:1px solid var(--line);margin-top:12px;padding-top:10px}.editor{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;position:sticky;top:10px}.editor h2,.editor>p{grid-column:1/-1;margin:0}.editor label{display:grid;gap:5px;color:var(--txt3);font-size:11px}.editor label span{font-size:10px}.wide{grid-column:1/-1}.preview{background:var(--bg2);border:1px solid var(--line);border-radius:8px;padding:10px;display:grid;gap:6px}.preview ol{margin:0;padding-left:20px;color:var(--txt2);font-size:11px}.worker-card .actions{margin-top:12px}.execution pre{max-height:260px;overflow:auto;background:var(--bg2);padding:10px;border-radius:8px;font-size:11px}.history-head{margin-bottom:10px}.mono,code{font-family:var(--mono)}@media(max-width:1050px){.schedule-layout{grid-template-columns:1fr}.editor{position:static}.job-grid{grid-template-columns:repeat(2,1fr)}}@media(max-width:720px){.summary{grid-template-columns:repeat(2,1fr)}.filters{grid-template-columns:1fr}.job-grid{grid-template-columns:1fr}}@media(max-width:480px){.summary{grid-template-columns:1fr}.editor{grid-template-columns:1fr}.editor>*{grid-column:1!important}} </style></body></html>
@@ -1,5 +1,5 @@
1
- <!DOCTYPE html><html lang="en" data-theme="dark"><head><meta charset="UTF-8"><meta name="stx-build" content="mtekc2s63mrzwt"><meta name="title" content="stx Project"><meta name="description" content="A website built with stx templating engine"><meta property="og:title" content="stx Project"><meta property="og:description" content="A website built with stx templating engine"><meta property="og:type" content="website"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="stx Project"><meta name="twitter:description" content="A website built with stx templating engine"> <script data-stx-runtime src="/_stx/runtime.dbee66d1.js"></script> <script data-stx-composables src="/_stx/chunk.5ddb5087.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ts-cloud · Maintenance &amp; disaster recovery</title><link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect x='3' y='3' width='26' height='26' rx='8' fill='%235a8be0'/%3E%3C/svg%3E"><link rel="preconnect" href="https://fonts.googleapis.com"><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"><link rel="stylesheet" href="/_stx/style.448ab192.css"> <script data-stx-scoped>
2
- function __stx_setup_1788018981171_16() {
1
+ <!DOCTYPE html><html lang="en" data-theme="dark"><head><meta charset="UTF-8"><meta name="stx-build" content="mtekhpm3jmsm9i"><meta name="title" content="stx Project"><meta name="description" content="A website built with stx templating engine"><meta property="og:title" content="stx Project"><meta property="og:description" content="A website built with stx templating engine"><meta property="og:type" content="website"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="stx Project"><meta name="twitter:description" content="A website built with stx templating engine"> <script data-stx-runtime src="/_stx/runtime.dbee66d1.js"></script> <script data-stx-composables src="/_stx/chunk.5ddb5087.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ts-cloud · Maintenance &amp; disaster recovery</title><link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect x='3' y='3' width='26' height='26' rx='8' fill='%235a8be0'/%3E%3C/svg%3E"><link rel="preconnect" href="https://fonts.googleapis.com"><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"><link rel="stylesheet" href="/_stx/style.448ab192.css"> <script data-stx-scoped>
2
+ function __stx_setup_1788019243971_16() {
3
3
  const { batch, computed, configureFetch, defineEmits, defineExpose, definePageMeta, defineProps, defineSlots, defineStore, derived, effect, goBack, goForward, inject, invalidateRoute, isDerived, isSignal, navigate, nextTick, onBeforeMount, onBeforeUnmount, onDestroy, onMount, onMounted, onUnmounted, peek, provide, reactive, ref, registerStoresClient, setRouteParams, state, untrack, useAsync, useClickOutside, useColorMode, useCookie, useCounter, useDark, useDebounce, useDebouncedValue, useEventListener, useFetch, useFocus, useHead, useId, useInterval, useLocalStorage, useMediaQuery, useMutation, useOptimistic, usePreferredContrast, usePreferredDark, usePreferredLight, usePreferredReducedMotion, useQuery, useReactiveProp, useRef, useRoute, useRouteParam, useRouteParams, useScrollLock, useSearchParams, useSeoMeta, useSessionStorage, useSlots, useStore, useThrottle, useTimeout, useToggle, useWebSocket, watch, watchEffect, watchMultiple, withDefaults } = window.stx;
4
4
 
5
5
  const data = state({ manifests: [], windows: [], campaigns: [], cleanups: [], drills: [] }), tab = state("upgrades"), error = state(""), notice = state(""), busy = state(false);
@@ -60,9 +60,9 @@ function bytes(value) {
60
60
 
61
61
  return { data, api, load, pollingState, pollingError, lastUpdatedAt, refresh, post, preview, cleanup, drill, runDrill, tone, bytes };
62
62
  }
63
- window.__stx_latestSetup=__stx_setup_1788018981171_16;
64
- if(window.stx)window.stx._latestSetup=__stx_setup_1788018981171_16;
65
- </script> <style data-stx-cloak>[x-cloak]{display:none !important}</style><link data-crosswind="generated" rel="stylesheet" href="/_stx/crosswind.b7a99a5c.css"></head><body data-stx="__stx_setup_1788018981171_16"><a data-stx-scope="stx_scope_nav_20" class="skip-link" href="#main-content">Skip to content</a><button class="nav-toggle-button" type="button" aria-label="Open navigation" aria-controls="primary-navigation" aria-expanded="false"><span></span><span></span><span></span></button><button class="nav-scrim" type="button" aria-label="Close navigation"></button><aside class="app-sidebar" id="primary-navigation" aria-label="Primary navigation"><a class="brand" href="/?env=production"><span class="dot"></span><span>ts-cloud</span></a><div class="sidebar-context"><span class="context-label">Project</span><strong>Project</strong></div><div class="environment-picker" aria-label="Environment"><span class="context-label">Environment</span><details><summary class="environment-current production"><span>PROD</span><strong>production</strong></summary></details></div><button class="command-trigger" type="button" aria-keyshortcuts="Meta+K Control+K"><span>Search resources</span><kbd>⌘ K</kbd></button><div class="nav-groups"><section class="nav-group"><h2>Overview</h2><a class="" href="/?env=production">Dashboard</a><a href="/server/activity?env=production">Activity</a></section><section class="nav-group"><h2>Applications</h2><a class="" href="/server/sites?env=production">Services</a><a class="" href="/server/deployments?env=production">Deployments</a><a class="" href="/server/logs?env=production">Logs</a><a class="" href="/integrations?env=production">Git integrations</a><a class="" href="/applications/new?env=production">Create application</a><a class="" href="/applications/compose?env=production">Compose applications</a></section><section class="nav-group"><h2>Operations</h2><a class="" href="/operations/queue?env=production">Deployment queue</a><a class="" href="/operations/previews?env=production">Preview environments</a><a class="" href="/operations/releases?env=production">Releases & promotion</a><a class="" href="/operations/regions?env=production">Regions & failover</a><a class="active" href="/operations/maintenance?env=production">Maintenance & DR</a><a class="" href="/operations/workloads?env=production">Workloads</a><a class="" href="/operations/observability?env=production">Observability</a><a class="" href="/operations/alerts?env=production">Alerts & health</a><a class="" href="/operations/spend?env=production">Spend & budgets</a><a href="/server/metrics?env=production">Metrics</a><a href="/server/services?env=production">Runtime services</a><a class="" href="/operations/jobs?env=production">Workers & schedules</a><a class="" href="/operations/configuration?env=production">Environment &amp; secrets</a><a class="" href="/data/backups?env=production">Backups &amp; recovery</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/actions?env=production">Run operations</a></section><section class="nav-group"><h2>Infrastructure</h2><a class="" href="/infrastructure/topology?env=production">Infrastructure map</a><a class="" href="/data/services?env=production">Data services</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/firewall?env=production">Network & firewall</a><a href="/server/ssh-keys?env=production">SSH keys</a><a class="" href="/server/fleet?env=production">Fleet inventory</a><a class="" href="/server/capacity?env=production">Capacity & placement</a><a href="/security?env=production">Security posture</a><a href="/server/terminal?env=production">Terminal</a></section><section class="nav-group"><h2>Organization</h2><a class="" href="/server/team?env=production">People & access</a><a class="" href="/account/automation?env=production">API & automation</a></section><section class="nav-group"><h2>Account</h2><a class="" href="/account/security?env=production">Sign-in & security</a></section></div><form method="post" action="/api/logout" class="signout"><button type="submit">Sign out</button></form></aside><dialog class="command-palette" aria-labelledby="command-title"><div class="command-search"><span aria-hidden="true">⌕</span><input type="search" placeholder="Search services, domains, deployments…" aria-label="Search resources" autocomplete="off"><button type="button" class="command-close" aria-label="Close search">Esc</button></div><h2 id="command-title" class="sr-only">Search resources and navigation</h2><div class="command-status" role="status">Start typing to search this project.</div><section class="saved-views" aria-labelledby="saved-views-title"><div class="saved-views-heading"><h3 id="saved-views-title">Saved views</h3><form class="save-view-form"><label class="sr-only" for="save-view-name">Saved view name</label><input id="save-view-name" maxlength="64" placeholder="Name this view" autocomplete="off"><button type="submit">Save current filters</button></form></div><div class="saved-view-list"></div></section><form class="tag-result-form"><label for="tag-result-name">Tag selected resource</label><input id="tag-result-name" maxlength="32" placeholder="customer-facing" pattern="[A-Za-z0-9][A-Za-z0-9 -]{0,31}" autocomplete="off"><input class="tag-color" type="color" value="#5a8be0" aria-label="Tag color"><button type="submit">Add tag</button></form><div class="command-results" role="listbox" aria-label="Search results"></div><footer><span>↑ ↓ navigate</span><span>Enter open</span><span>Esc close</span></footer></dialog><div class="context-bar" aria-label="Current scope"><div class="context-path"><div class="context-breadcrumb"><span>Project</span><i>/</i><strong>production</strong></div><div class="context-filters" aria-label="Active filters"></div></div><span class="scope-safety production">Production scope</span></div> <script data-stx-scoped data-stx-run="always">
63
+ window.__stx_latestSetup=__stx_setup_1788019243971_16;
64
+ if(window.stx)window.stx._latestSetup=__stx_setup_1788019243971_16;
65
+ </script> <style data-stx-cloak>[x-cloak]{display:none !important}</style><link data-crosswind="generated" rel="stylesheet" href="/_stx/crosswind.b7a99a5c.css"></head><body data-stx="__stx_setup_1788019243971_16"><a data-stx-scope="stx_scope_nav_20" class="skip-link" href="#main-content">Skip to content</a><button class="nav-toggle-button" type="button" aria-label="Open navigation" aria-controls="primary-navigation" aria-expanded="false"><span></span><span></span><span></span></button><button class="nav-scrim" type="button" aria-label="Close navigation"></button><aside class="app-sidebar" id="primary-navigation" aria-label="Primary navigation"><a class="brand" href="/?env=production"><span class="dot"></span><span>ts-cloud</span></a><div class="sidebar-context"><span class="context-label">Project</span><strong>Project</strong></div><div class="environment-picker" aria-label="Environment"><span class="context-label">Environment</span><details><summary class="environment-current production"><span>PROD</span><strong>production</strong></summary></details></div><button class="command-trigger" type="button" aria-keyshortcuts="Meta+K Control+K"><span>Search resources</span><kbd>⌘ K</kbd></button><div class="nav-groups"><section class="nav-group"><h2>Overview</h2><a class="" href="/?env=production">Dashboard</a><a href="/server/activity?env=production">Activity</a></section><section class="nav-group"><h2>Applications</h2><a class="" href="/server/sites?env=production">Services</a><a class="" href="/server/deployments?env=production">Deployments</a><a class="" href="/server/logs?env=production">Logs</a><a class="" href="/integrations?env=production">Git integrations</a><a class="" href="/applications/new?env=production">Create application</a><a class="" href="/applications/compose?env=production">Compose applications</a></section><section class="nav-group"><h2>Operations</h2><a class="" href="/operations/queue?env=production">Deployment queue</a><a class="" href="/operations/previews?env=production">Preview environments</a><a class="" href="/operations/releases?env=production">Releases & promotion</a><a class="" href="/operations/regions?env=production">Regions & failover</a><a class="active" href="/operations/maintenance?env=production">Maintenance & DR</a><a class="" href="/operations/workloads?env=production">Workloads</a><a class="" href="/operations/observability?env=production">Observability</a><a class="" href="/operations/alerts?env=production">Alerts & health</a><a class="" href="/operations/spend?env=production">Spend & budgets</a><a href="/server/metrics?env=production">Metrics</a><a href="/server/services?env=production">Runtime services</a><a class="" href="/operations/jobs?env=production">Workers & schedules</a><a class="" href="/operations/configuration?env=production">Environment &amp; secrets</a><a class="" href="/data/backups?env=production">Backups &amp; recovery</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/actions?env=production">Run operations</a></section><section class="nav-group"><h2>Infrastructure</h2><a class="" href="/infrastructure/topology?env=production">Infrastructure map</a><a class="" href="/data/services?env=production">Data services</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/firewall?env=production">Network & firewall</a><a href="/server/ssh-keys?env=production">SSH keys</a><a class="" href="/server/fleet?env=production">Fleet inventory</a><a class="" href="/server/capacity?env=production">Capacity & placement</a><a href="/security?env=production">Security posture</a><a href="/server/terminal?env=production">Terminal</a></section><section class="nav-group"><h2>Organization</h2><a class="" href="/server/team?env=production">People & access</a><a class="" href="/account/automation?env=production">API & automation</a></section><section class="nav-group"><h2>Account</h2><a class="" href="/account/security?env=production">Sign-in & security</a></section></div><form method="post" action="/api/logout" class="signout"><button type="submit">Sign out</button></form></aside><dialog class="command-palette" aria-labelledby="command-title"><div class="command-search"><span aria-hidden="true">⌕</span><input type="search" placeholder="Search services, domains, deployments…" aria-label="Search resources" autocomplete="off"><button type="button" class="command-close" aria-label="Close search">Esc</button></div><h2 id="command-title" class="sr-only">Search resources and navigation</h2><div class="command-status" role="status">Start typing to search this project.</div><section class="saved-views" aria-labelledby="saved-views-title"><div class="saved-views-heading"><h3 id="saved-views-title">Saved views</h3><form class="save-view-form"><label class="sr-only" for="save-view-name">Saved view name</label><input id="save-view-name" maxlength="64" placeholder="Name this view" autocomplete="off"><button type="submit">Save current filters</button></form></div><div class="saved-view-list"></div></section><form class="tag-result-form"><label for="tag-result-name">Tag selected resource</label><input id="tag-result-name" maxlength="32" placeholder="customer-facing" pattern="[A-Za-z0-9][A-Za-z0-9 -]{0,31}" autocomplete="off"><input class="tag-color" type="color" value="#5a8be0" aria-label="Tag color"><button type="submit">Add tag</button></form><div class="command-results" role="listbox" aria-label="Search results"></div><footer><span>↑ ↓ navigate</span><span>Enter open</span><span>Esc close</span></footer></dialog><div class="context-bar" aria-label="Current scope"><div class="context-path"><div class="context-breadcrumb"><span>Project</span><i>/</i><strong>production</strong></div><div class="context-filters" aria-label="Active filters"></div></div><span class="scope-safety production">Production scope</span></div> <script data-stx-scoped data-stx-run="always">
66
66
  (function() {
67
67
  var { batch, computed, configureFetch, defineEmits, defineExpose, definePageMeta, defineProps, defineSlots, defineStore, derived, effect, goBack, goForward, inject, invalidateRoute, isDerived, isSignal, navigate, nextTick, onBeforeMount, onBeforeUnmount, onDestroy, onMount, onMounted, onUnmounted, peek, provide, reactive, ref, refresh, registerStoresClient, setRouteParams, state, untrack, useAsync, useClickOutside, useColorMode, useCookie, useCounter, useDark, useDebounce, useDebouncedValue, useEventListener, useFetch, useFocus, useHead, useId, useInterval, useLocalStorage, useMediaQuery, useMutation, useOptimistic, usePreferredContrast, usePreferredDark, usePreferredLight, usePreferredReducedMotion, useQuery, useReactiveProp, useRef, useRoute, useRouteParam, useRouteParams, useScrollLock, useSearchParams, useSeoMeta, useSessionStorage, useSlots, useStore, useThrottle, useTimeout, useToggle, useWebSocket, watch, watchEffect, watchMultiple, withDefaults } = window.stx;
68
68
  var __destroyHooks = [];
@@ -1,5 +1,5 @@
1
- <!DOCTYPE html><html lang="en" data-theme="dark"><head><meta charset="UTF-8"><meta name="stx-build" content="mtekc2s63mrzwt"><meta name="title" content="stx Project"><meta name="description" content="A website built with stx templating engine"><meta property="og:title" content="stx Project"><meta property="og:description" content="A website built with stx templating engine"><meta property="og:type" content="website"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="stx Project"><meta name="twitter:description" content="A website built with stx templating engine"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ts-cloud - Observability</title><link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect x='3' y='3' width='26' height='26' rx='8' fill='%235a8be0'/%3E%3C/svg%3E"><link rel="preconnect" href="https://fonts.googleapis.com"><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"><link rel="stylesheet" href="/_stx/style.448ab192.css"> <script data-stx-runtime src="/_stx/runtime.dbee66d1.js"></script> <script data-stx-composables src="/_stx/chunk.5ddb5087.js"></script> <script data-stx-scoped>
2
- function __stx_setup_1788018981028_14() {
1
+ <!DOCTYPE html><html lang="en" data-theme="dark"><head><meta charset="UTF-8"><meta name="stx-build" content="mtekhpm3jmsm9i"><meta name="title" content="stx Project"><meta name="description" content="A website built with stx templating engine"><meta property="og:title" content="stx Project"><meta property="og:description" content="A website built with stx templating engine"><meta property="og:type" content="website"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="stx Project"><meta name="twitter:description" content="A website built with stx templating engine"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ts-cloud - Observability</title><link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect x='3' y='3' width='26' height='26' rx='8' fill='%235a8be0'/%3E%3C/svg%3E"><link rel="preconnect" href="https://fonts.googleapis.com"><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"><link rel="stylesheet" href="/_stx/style.448ab192.css"> <script data-stx-runtime src="/_stx/runtime.dbee66d1.js"></script> <script data-stx-composables src="/_stx/chunk.5ddb5087.js"></script> <script data-stx-scoped>
2
+ function __stx_setup_1788019243861_12() {
3
3
  const { batch, computed, configureFetch, defineEmits, defineExpose, definePageMeta, defineProps, defineSlots, defineStore, derived, effect, goBack, goForward, inject, invalidateRoute, isDerived, isSignal, navigate, nextTick, onBeforeMount, onBeforeUnmount, onDestroy, onMount, onMounted, onUnmounted, peek, provide, reactive, ref, registerStoresClient, setRouteParams, state, untrack, useAsync, useClickOutside, useColorMode, useCookie, useCounter, useDark, useDebounce, useDebouncedValue, useEventListener, useFetch, useFocus, useHead, useId, useInterval, useLocalStorage, useMediaQuery, useMutation, useOptimistic, usePreferredContrast, usePreferredDark, usePreferredLight, usePreferredReducedMotion, useQuery, useReactiveProp, useRef, useRoute, useRouteParam, useRouteParams, useScrollLock, useSearchParams, useSeoMeta, useSessionStorage, useSlots, useStore, useThrottle, useTimeout, useToggle, useWebSocket, watch, watchEffect, watchMultiple, withDefaults } = window.stx;
4
4
 
5
5
  var allPoints = undefined;
@@ -360,9 +360,9 @@ useSaved = __stxBundle_bcc87ca4db18["useSaved"];
360
360
  windowParams = __stxBundle_bcc87ca4db18["windowParams"];
361
361
  return { allPoints, applyFilters, barHeight, closeTail, compare, comparisonDelta, connectTail, exportData, fmt, freshnessTone, json, lastUpdatedAt, latest, load, loadMore, maxPoint, nextCursor, openCorrelation, p95, pollingError, pollingLabel, pollingState, range, ranges, refresh, requestTotal, saturationSignal, savePolicy, saveQuery, seriesUrl, status, tailSource, timezone, togglePause, total, traffic, useSaved, windowParams, __stxBundle_bcc87ca4db18 };
362
362
  }
363
- window.__stx_latestSetup=__stx_setup_1788018981028_14;
364
- if(window.stx)window.stx._latestSetup=__stx_setup_1788018981028_14;
365
- </script> <style data-stx-cloak>[x-cloak]{display:none !important}</style><link data-crosswind="generated" rel="stylesheet" href="/_stx/crosswind.906ee17c.css"></head><body data-stx="__stx_setup_1788018981028_14"><a data-stx-scope="stx_scope_nav_18" class="skip-link" href="#main-content">Skip to content</a><button class="nav-toggle-button" type="button" aria-label="Open navigation" aria-controls="primary-navigation" aria-expanded="false"><span></span><span></span><span></span></button><button class="nav-scrim" type="button" aria-label="Close navigation"></button><aside class="app-sidebar" id="primary-navigation" aria-label="Primary navigation"><a class="brand" href="/?env=production"><span class="dot"></span><span>ts-cloud</span></a><div class="sidebar-context"><span class="context-label">Project</span><strong>Project</strong></div><div class="environment-picker" aria-label="Environment"><span class="context-label">Environment</span><details><summary class="environment-current production"><span>PROD</span><strong>production</strong></summary></details></div><button class="command-trigger" type="button" aria-keyshortcuts="Meta+K Control+K"><span>Search resources</span><kbd>⌘ K</kbd></button><div class="nav-groups"><section class="nav-group"><h2>Overview</h2><a class="" href="/?env=production">Dashboard</a><a href="/server/activity?env=production">Activity</a></section><section class="nav-group"><h2>Applications</h2><a class="" href="/server/sites?env=production">Services</a><a class="" href="/server/deployments?env=production">Deployments</a><a class="" href="/server/logs?env=production">Logs</a><a class="" href="/integrations?env=production">Git integrations</a><a class="" href="/applications/new?env=production">Create application</a><a class="" href="/applications/compose?env=production">Compose applications</a></section><section class="nav-group"><h2>Operations</h2><a class="" href="/operations/queue?env=production">Deployment queue</a><a class="" href="/operations/previews?env=production">Preview environments</a><a class="" href="/operations/releases?env=production">Releases & promotion</a><a class="" href="/operations/regions?env=production">Regions & failover</a><a class="" href="/operations/maintenance?env=production">Maintenance & DR</a><a class="" href="/operations/workloads?env=production">Workloads</a><a class="active" href="/operations/observability?env=production">Observability</a><a class="" href="/operations/alerts?env=production">Alerts & health</a><a class="" href="/operations/spend?env=production">Spend & budgets</a><a href="/server/metrics?env=production">Metrics</a><a href="/server/services?env=production">Runtime services</a><a class="" href="/operations/jobs?env=production">Workers & schedules</a><a class="" href="/operations/configuration?env=production">Environment &amp; secrets</a><a class="" href="/data/backups?env=production">Backups &amp; recovery</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/actions?env=production">Run operations</a></section><section class="nav-group"><h2>Infrastructure</h2><a class="" href="/infrastructure/topology?env=production">Infrastructure map</a><a class="" href="/data/services?env=production">Data services</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/firewall?env=production">Network & firewall</a><a href="/server/ssh-keys?env=production">SSH keys</a><a class="" href="/server/fleet?env=production">Fleet inventory</a><a class="" href="/server/capacity?env=production">Capacity & placement</a><a href="/security?env=production">Security posture</a><a href="/server/terminal?env=production">Terminal</a></section><section class="nav-group"><h2>Organization</h2><a class="" href="/server/team?env=production">People & access</a><a class="" href="/account/automation?env=production">API & automation</a></section><section class="nav-group"><h2>Account</h2><a class="" href="/account/security?env=production">Sign-in & security</a></section></div><form method="post" action="/api/logout" class="signout"><button type="submit">Sign out</button></form></aside><dialog class="command-palette" aria-labelledby="command-title"><div class="command-search"><span aria-hidden="true">⌕</span><input type="search" placeholder="Search services, domains, deployments…" aria-label="Search resources" autocomplete="off"><button type="button" class="command-close" aria-label="Close search">Esc</button></div><h2 id="command-title" class="sr-only">Search resources and navigation</h2><div class="command-status" role="status">Start typing to search this project.</div><section class="saved-views" aria-labelledby="saved-views-title"><div class="saved-views-heading"><h3 id="saved-views-title">Saved views</h3><form class="save-view-form"><label class="sr-only" for="save-view-name">Saved view name</label><input id="save-view-name" maxlength="64" placeholder="Name this view" autocomplete="off"><button type="submit">Save current filters</button></form></div><div class="saved-view-list"></div></section><form class="tag-result-form"><label for="tag-result-name">Tag selected resource</label><input id="tag-result-name" maxlength="32" placeholder="customer-facing" pattern="[A-Za-z0-9][A-Za-z0-9 -]{0,31}" autocomplete="off"><input class="tag-color" type="color" value="#5a8be0" aria-label="Tag color"><button type="submit">Add tag</button></form><div class="command-results" role="listbox" aria-label="Search results"></div><footer><span>↑ ↓ navigate</span><span>Enter open</span><span>Esc close</span></footer></dialog><div class="context-bar" aria-label="Current scope"><div class="context-path"><div class="context-breadcrumb"><span>Project</span><i>/</i><strong>production</strong></div><div class="context-filters" aria-label="Active filters"></div></div><span class="scope-safety production">Production scope</span></div> <script data-stx-scoped data-stx-run="always">
363
+ window.__stx_latestSetup=__stx_setup_1788019243861_12;
364
+ if(window.stx)window.stx._latestSetup=__stx_setup_1788019243861_12;
365
+ </script> <style data-stx-cloak>[x-cloak]{display:none !important}</style><link data-crosswind="generated" rel="stylesheet" href="/_stx/crosswind.906ee17c.css"></head><body data-stx="__stx_setup_1788019243861_12"><a data-stx-scope="stx_scope_nav_16" class="skip-link" href="#main-content">Skip to content</a><button class="nav-toggle-button" type="button" aria-label="Open navigation" aria-controls="primary-navigation" aria-expanded="false"><span></span><span></span><span></span></button><button class="nav-scrim" type="button" aria-label="Close navigation"></button><aside class="app-sidebar" id="primary-navigation" aria-label="Primary navigation"><a class="brand" href="/?env=production"><span class="dot"></span><span>ts-cloud</span></a><div class="sidebar-context"><span class="context-label">Project</span><strong>Project</strong></div><div class="environment-picker" aria-label="Environment"><span class="context-label">Environment</span><details><summary class="environment-current production"><span>PROD</span><strong>production</strong></summary></details></div><button class="command-trigger" type="button" aria-keyshortcuts="Meta+K Control+K"><span>Search resources</span><kbd>⌘ K</kbd></button><div class="nav-groups"><section class="nav-group"><h2>Overview</h2><a class="" href="/?env=production">Dashboard</a><a href="/server/activity?env=production">Activity</a></section><section class="nav-group"><h2>Applications</h2><a class="" href="/server/sites?env=production">Services</a><a class="" href="/server/deployments?env=production">Deployments</a><a class="" href="/server/logs?env=production">Logs</a><a class="" href="/integrations?env=production">Git integrations</a><a class="" href="/applications/new?env=production">Create application</a><a class="" href="/applications/compose?env=production">Compose applications</a></section><section class="nav-group"><h2>Operations</h2><a class="" href="/operations/queue?env=production">Deployment queue</a><a class="" href="/operations/previews?env=production">Preview environments</a><a class="" href="/operations/releases?env=production">Releases & promotion</a><a class="" href="/operations/regions?env=production">Regions & failover</a><a class="" href="/operations/maintenance?env=production">Maintenance & DR</a><a class="" href="/operations/workloads?env=production">Workloads</a><a class="active" href="/operations/observability?env=production">Observability</a><a class="" href="/operations/alerts?env=production">Alerts & health</a><a class="" href="/operations/spend?env=production">Spend & budgets</a><a href="/server/metrics?env=production">Metrics</a><a href="/server/services?env=production">Runtime services</a><a class="" href="/operations/jobs?env=production">Workers & schedules</a><a class="" href="/operations/configuration?env=production">Environment &amp; secrets</a><a class="" href="/data/backups?env=production">Backups &amp; recovery</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/actions?env=production">Run operations</a></section><section class="nav-group"><h2>Infrastructure</h2><a class="" href="/infrastructure/topology?env=production">Infrastructure map</a><a class="" href="/data/services?env=production">Data services</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/firewall?env=production">Network & firewall</a><a href="/server/ssh-keys?env=production">SSH keys</a><a class="" href="/server/fleet?env=production">Fleet inventory</a><a class="" href="/server/capacity?env=production">Capacity & placement</a><a href="/security?env=production">Security posture</a><a href="/server/terminal?env=production">Terminal</a></section><section class="nav-group"><h2>Organization</h2><a class="" href="/server/team?env=production">People & access</a><a class="" href="/account/automation?env=production">API & automation</a></section><section class="nav-group"><h2>Account</h2><a class="" href="/account/security?env=production">Sign-in & security</a></section></div><form method="post" action="/api/logout" class="signout"><button type="submit">Sign out</button></form></aside><dialog class="command-palette" aria-labelledby="command-title"><div class="command-search"><span aria-hidden="true">⌕</span><input type="search" placeholder="Search services, domains, deployments…" aria-label="Search resources" autocomplete="off"><button type="button" class="command-close" aria-label="Close search">Esc</button></div><h2 id="command-title" class="sr-only">Search resources and navigation</h2><div class="command-status" role="status">Start typing to search this project.</div><section class="saved-views" aria-labelledby="saved-views-title"><div class="saved-views-heading"><h3 id="saved-views-title">Saved views</h3><form class="save-view-form"><label class="sr-only" for="save-view-name">Saved view name</label><input id="save-view-name" maxlength="64" placeholder="Name this view" autocomplete="off"><button type="submit">Save current filters</button></form></div><div class="saved-view-list"></div></section><form class="tag-result-form"><label for="tag-result-name">Tag selected resource</label><input id="tag-result-name" maxlength="32" placeholder="customer-facing" pattern="[A-Za-z0-9][A-Za-z0-9 -]{0,31}" autocomplete="off"><input class="tag-color" type="color" value="#5a8be0" aria-label="Tag color"><button type="submit">Add tag</button></form><div class="command-results" role="listbox" aria-label="Search results"></div><footer><span>↑ ↓ navigate</span><span>Enter open</span><span>Esc close</span></footer></dialog><div class="context-bar" aria-label="Current scope"><div class="context-path"><div class="context-breadcrumb"><span>Project</span><i>/</i><strong>production</strong></div><div class="context-filters" aria-label="Active filters"></div></div><span class="scope-safety production">Production scope</span></div> <script data-stx-scoped data-stx-run="always">
366
366
  (function() {
367
367
  var { batch, computed, configureFetch, defineEmits, defineExpose, definePageMeta, defineProps, defineSlots, defineStore, derived, effect, goBack, goForward, inject, invalidateRoute, isDerived, isSignal, navigate, nextTick, onBeforeMount, onBeforeUnmount, onDestroy, onMount, onMounted, onUnmounted, peek, provide, reactive, ref, refresh, registerStoresClient, setRouteParams, state, untrack, useAsync, useClickOutside, useColorMode, useCookie, useCounter, useDark, useDebounce, useDebouncedValue, useEventListener, useFetch, useFocus, useHead, useId, useInterval, useLocalStorage, useMediaQuery, useMutation, useOptimistic, usePreferredContrast, usePreferredDark, usePreferredLight, usePreferredReducedMotion, useQuery, useReactiveProp, useRef, useRoute, useRouteParam, useRouteParams, useScrollLock, useSearchParams, useSeoMeta, useSessionStorage, useSlots, useStore, useThrottle, useTimeout, useToggle, useWebSocket, watch, watchEffect, watchMultiple, withDefaults } = window.stx;
368
368
  var __destroyHooks = [];
@@ -713,6 +713,6 @@ if(window.stx)window.stx._latestSetup=__stx_setup_1788018981028_14;
713
713
 
714
714
 
715
715
  try { if (typeof __stxScopeRenames !== 'undefined' && __stxScopeRenames) { for (var __stxRK in __stxScopeRenames) __scopeRegistration[__stxRK] = __stxScopeRenames[__stxRK]; } } catch (e) { /* no renames */ }
716
- window.stx._scopes['stx_scope_nav_18'] = __scopeRegistration;
716
+ window.stx._scopes['stx_scope_nav_16'] = __scopeRegistration;
717
717
  })();
718
718
  </script> <main class="telemetry-wrap wrap" id="main-content"><div class="crumbs">Operations <span class="sep">/</span> Observability</div><header class="page"><div><h1>Observability</h1><p>Correlated metrics, logs, requests, traces, releases, and runtime context—with explicit source freshness and retention.</p></div><div class="header-actions" x-cloak><span class="pill" :class="pollingState() === 'live' ? 'ok' : 'warn'" x-cloak>{{ paused() ? 'paused' : pollingLabel() }}</span><span class="pill" :class="tailState() === 'live' ? 'ok' : 'warn'" x-cloak>tail {{ tailState() }}</span><small x-cloak>{{ lastUpdatedAt() ? lastUpdatedAt().toLocaleTimeString() : 'connecting' }}</small><button class="btn ghost sm" type="button" @click="togglePause()" x-cloak>{{ paused() ? 'Resume' : 'Pause' }}</button><button class="btn ghost sm" type="button" @click="refresh()">Refresh</button></div></header><p class="bad notice" role="status" @show="!!pollingError()" x-cloak>{{ pollingError() }}</p><p class="notice" role="status" @show="!!message()" x-cloak>{{ message() }}</p><section class="panel timebar"><label>Time range<select :value="range()" @change="range.set($event.target.value); applyFilters()"><option value="1h">Last hour</option><option value="6h">Last 6 hours</option><option value="24h">Last 24 hours</option><option value="7d">Last 7 days</option><option value="30d">Last 30 days</option></select></label><label>Timezone<input :value="timezone()" @change="timezone.set($event.target.value); applyFilters()"></label><label class="check"><input type="checkbox" :checked="compare()" @change="compare.set($event.target.checked); applyFilters()"> Compare previous period</label><span class="note" x-cloak>Auto-refresh 15s · provider refresh is cached separately · {{ status().policy?.samplingRate != null ? Math.round(status().policy.samplingRate * 100) + '% sampled' : 'sampling unavailable' }}</span></section><details class="panel policy"><summary>Collection, retention, and estimated cost</summary><div class="cost-summary" x-cloak><span x-cloak>~{{ fmt(status().estimatedMonthlyBytes, ' B/month') }}</span><span x-cloak>{{ status().costEstimateConfigured ? '$' + status().estimatedMonthlyCostUsd + '/month at configured storage rate' : 'Cost unavailable until a storage $/GB-month rate is configured' }}</span></div><form @submit="savePolicy($event)"><label>Raw retention days<input name="rawDays" type="number" min="1" max="3650" :value="status().policy?.rawDays || 30"></label><label>Downsample after days<input name="downsampleAfterDays" type="number" min="1" max="3650" :value="status().policy?.downsampleAfterDays || 7"></label><label>Maximum local records<input name="maxRecords" type="number" min="1000" :value="status().policy?.maxRecords || 1000000"></label><label>Sample rate (0.01–1)<input name="samplingRate" type="number" min="0.01" max="1" step="0.01" :value="status().policy?.samplingRate || 1"></label><label>Storage $/GB-month<input name="estimatedStorageUsdPerGbMonth" type="number" min="0" step="0.001" :value="status().policy?.estimatedStorageUsdPerGbMonth || 0"></label><label class="check"><input name="collectLogs" type="checkbox" :checked="status().policy?.collectLogs !== false"> Logs</label><label class="check"><input name="collectTraces" type="checkbox" :checked="status().policy?.collectTraces !== false"> Traces</label><label class="check"><input name="collectRequestAnalytics" type="checkbox" :checked="status().policy?.collectRequestAnalytics !== false"> Request analytics</label><button class="btn sm" type="submit">Save policy</button></form><p class="note">Lower sampling and retention reduce local ingestion/storage, but can hide rare events. Cost is an estimate using your configured storage rate; provider allocation is never invented.</p></details><section class="source-grid" aria-label="Telemetry collection sources" x-cloak><template :for="item in status().sources || []"><article class="panel source-card" x-cloak><div x-cloak><b x-cloak>{{ item.source }}</b><span class="pill" :class="freshnessTone(item.freshness)" x-cloak>{{ item.freshness }}</span></div><small x-cloak>last {{ item.lastObservedAt ? new Date(item.lastObservedAt).toLocaleString() : 'never' }} · lag {{ item.lagSeconds ?? '—' }}s</small><small x-cloak>{{ item.retentionDays }}d retention · {{ Math.round(item.samplingRate * 100) }}% sampled · ~{{ fmt(item.estimatedDailyBytes, ' B/day') }}</small><p class="note" @show="!!item.message" x-cloak>{{ item.message }}</p></article></template><article class="panel source-card" @show="!(status().sources || []).length" x-cloak><b>No collection sources</b><small>Refresh to collect live provider data. Empty data is never replaced with samples.</small></article></section><section class="golden"><article class="panel"><h3>Traffic</h3><strong x-cloak>{{ fmt(requestTotal()) }}</strong><small>requests · summed buckets</small></article><article class="panel"><h3>Errors</h3><strong x-cloak>{{ fmt(errorRate(), '%') }}</strong><small x-cloak>{{ fmt(errorTotal()) }} errors</small></article><article class="panel"><h3>Latency</h3><strong x-cloak>{{ fmt(p95(), ' ms') }}</strong><small>latest p95 · worst available source</small></article><article class="panel"><h3>Saturation</h3><strong x-cloak>{{ fmt(saturationSignal()?.value, saturationSignal()?.unit ? ' ' + saturationSignal().unit : '') }}</strong><small x-cloak>{{ saturationSignal()?.name || 'unsupported in this window' }}</small></article></section><section class="chart-grid" x-cloak><template :for="series in [...traffic(), ...errors(), ...latency(), ...saturation(), ...infrastructure(), ...siteSignals()].slice(0, 24)"><article class="chart-card panel" x-cloak><div class="chart-head" x-cloak><b x-cloak>{{ series.name }}</b><span x-cloak>{{ series.source }} · {{ series.aggregation }} / {{ Math.round(series.bucketMs / 60000) }}m</span></div><div class="telemetry-bars" :aria-label="series.name + ' time series'"><template :for="point in series.points"><i :class="{ gap: point.gap }" :style="'height:' + barHeight(series, point) + '%'" :title="point.label + ': ' + (point.gap ? 'gap' : point.value)"></i></template></div><small x-cloak>{{ timezone() }} · gaps shown as dim baseline bars <span @show="comparisonDelta(series) != null" x-cloak>· {{ comparisonDelta(series) > 0 ? '+' : '' }}{{ comparisonDelta(series)?.toFixed(1) }}% vs previous</span></small></article></template><article class="chart-card panel" @show="![...traffic(), ...errors(), ...latency(), ...saturation(), ...infrastructure(), ...siteSignals()].length" x-cloak><b>No metric series</b><p class="note">The selected sources have not emitted these golden signals in this window, or the provider reports them as unsupported.</p></article></section><section class="section"><div class="section-title"><div><h2>Logs, requests, traces, and events</h2><p class="note">Bodies, authorization, cookies, query values, and configured PII are removed before persistence.</p></div><div class="header-actions"><input class="save-name" :value="savedName()" @input="savedName.set($event.target.value)" placeholder="Query name" aria-label="Saved query name"><button class="btn ghost sm" type="button" @click="saveQuery()">Save query</button><button class="btn ghost sm" type="button" @click="exportData('json')">JSON</button><button class="btn ghost sm" type="button" @click="exportData('csv')">CSV</button></div></div><div class="log-filters panel"><label>Search<input type="search" :value="textQuery()" @input="textQuery.set($event.target.value)" @change="applyFilters()" placeholder="Message, request, release…"></label><label>Level<select :value="level()" @change="level.set($event.target.value); applyFilters()"><option value="">All</option><option value="debug">debug</option><option value="info">info</option><option value="warning">warning</option><option value="error">error</option></select></label><label>Source<input :value="source()" @change="source.set($event.target.value); applyFilters()" placeholder="cloudwatch:http"></label></div><div class="saved" @show="savedQueries().length" x-cloak><span>Saved:</span><template :for="item in savedQueries()"><button type="button" class="btn ghost sm" @click="useSaved(item)" x-cloak>{{ item.name }}</button></template></div><div class="panel telemetry-table-wrap"><table class="telemetry-table"><thead><tr><th scope="col">Time</th><th scope="col">Kind</th><th scope="col">Source</th><th scope="col">Signal</th><th scope="col">Message / value</th><th scope="col">Correlation</th></tr></thead><tbody><template :for="record in records()"><tr tabindex="0" @click="openCorrelation(record)" @keydown.enter="openCorrelation(record)"><td x-cloak>{{ new Date(record.timestamp).toLocaleString([], {timeZone: timezone()}) }}</td><td x-cloak><span class="tag" x-cloak>{{ record.kind }}</span></td><td x-cloak>{{ record.source }}</td><td x-cloak><span class="pill" :class="record.level === 'error' ? 'bad' : record.level === 'warning' ? 'warn' : ''" x-cloak>{{ record.level || record.name }}</span></td><td class="mono" x-cloak>{{ record.message || (record.value != null ? record.value + ' ' + (record.unit || '') : record.durationMs != null ? record.durationMs + 'ms' : record.name) }}</td><td class="mono" x-cloak>{{ record.requestId || record.traceId || record.releaseId || record.deploymentId || '—' }}</td></tr></template></tbody></table><div class="empty" @show="!records().length" x-cloak><strong>No telemetry in this window</strong><span>Empty, unavailable, and filtered results remain explicit; no demo rows are shown.</span></div><button class="btn ghost load-more sm" type="button" @show="!!nextCursor()" @click="loadMore()" x-cloak>Load older records</button></div></section><aside class="correlation panel" @show="!!correlation()" x-cloak><button class="detail-close" type="button" aria-label="Close correlation detail" @click="correlation.set(null)">×</button><h2>Correlation</h2><p class="mono" x-cloak>{{ correlation()?.key }}</p><div class="timeline" x-cloak><template :for="item in correlation()?.records || []"><article x-cloak><span x-cloak>{{ new Date(item.timestamp).toLocaleString() }}</span><b x-cloak>{{ item.name }}</b><small x-cloak>{{ item.source }} · {{ item.kind }} · {{ item.message || item.value || '' }}</small><nav><a @show="!!item.releaseId" :href="'/operations/releases?release=' + encodeURIComponent(item.releaseId)" x-cloak>Release</a><a @show="!!item.workloadId" :href="'/operations/workloads?search=' + encodeURIComponent(item.workloadId)" x-cloak>Workload</a></nav></article></template></div></aside></main><style> .telemetry-wrap{max-width:1540px}.timebar,.log-filters{display:flex;gap:12px;align-items:end;flex-wrap:wrap;padding:14px}.timebar label,.log-filters label,.policy label{display:grid;gap:5px;color:var(--txt3);font-size:11px}.timebar select,.timebar input,.log-filters select,.log-filters input,.policy input,.save-name{min-width:160px;background:var(--bg2);border:1px solid var(--line);border-radius:8px;color:var(--txt);padding:8px}.timebar .check,.policy .check{display:flex;align-items:center;gap:7px;padding:8px}.timebar .check input,.policy .check input{min-width:0}.policy{margin-top:10px}.policy summary{cursor:pointer;font-weight:600}.policy form,.cost-summary{display:flex;gap:12px;align-items:end;flex-wrap:wrap;margin-top:14px}.cost-summary{justify-content:space-between;color:var(--txt2)}.source-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:10px;margin:12px 0}.source-card{display:grid;gap:5px;padding:13px}.source-card>div{display:flex;justify-content:space-between;gap:8px}.source-card small{color:var(--txt3)}.golden{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:16px 0}.golden article{display:grid;gap:5px}.golden strong{font-size:28px}.golden small{color:var(--txt3)}.chart-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.chart-card{min-width:0}.chart-head{display:flex;justify-content:space-between;gap:10px}.chart-head span,.chart-card small{color:var(--txt3);font-size:10px}.telemetry-bars{display:flex;align-items:end;gap:2px;height:110px;margin:14px 0 7px;border-bottom:1px solid var(--line)}.telemetry-bars i{flex:1;min-width:2px;background:var(--accent);border-radius:2px 2px 0 0}.telemetry-bars i.gap{opacity:.18;background:var(--txt3)}.section-title{display:flex;align-items:end;justify-content:space-between;gap:12px}.saved{display:flex;gap:7px;align-items:center;flex-wrap:wrap;margin:8px 0}.telemetry-table-wrap{overflow:auto;padding:0}.telemetry-table{min-width:1050px}.telemetry-table tbody tr{cursor:pointer}.telemetry-table td{max-width:420px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.load-more{margin:12px}.correlation{position:fixed;z-index:20;right:20px;top:20px;bottom:20px;width:min(480px,calc(100vw - 40px));overflow:auto;padding:20px;box-shadow:0 20px 70px #000b}.detail-close{float:right;border:0;background:transparent;color:var(--txt3);font-size:24px}.timeline{display:grid;gap:14px;margin-top:20px;border-left:1px solid var(--line);padding-left:16px}.timeline article{display:grid;gap:4px}.timeline span,.timeline small{color:var(--txt3);font-size:11px}.timeline nav{display:flex;gap:10px} @media(max-width:900px){.golden{grid-template-columns:repeat(2,1fr)}.chart-grid{grid-template-columns:1fr}}@media(max-width:600px){.golden{grid-template-columns:1fr}.timebar>*{width:100%}.section-title{align-items:start;flex-direction:column}.source-grid{grid-template-columns:1fr}.telemetry-table{min-width:0}.telemetry-table thead{display:none}.telemetry-table tbody,.telemetry-table tr,.telemetry-table td{display:block}.telemetry-table tr{padding:12px;border-bottom:1px solid var(--line)}.telemetry-table td{padding:4px 0;white-space:normal}.telemetry-table td:before{display:inline-block;width:90px;color:var(--txt3);font-size:10px}.telemetry-table td:nth-child(1):before{content:'Time'}.telemetry-table td:nth-child(2):before{content:'Kind'}.telemetry-table td:nth-child(3):before{content:'Source'}.telemetry-table td:nth-child(4):before{content:'Signal'}.telemetry-table td:nth-child(5):before{content:'Value'}.telemetry-table td:nth-child(6):before{content:'Correlation'}} </style></body></html>
@@ -1,5 +1,5 @@
1
- <!DOCTYPE html><html lang="en" data-theme="dark"><head><meta charset="UTF-8"><meta name="stx-build" content="mtekc2s63mrzwt"><meta name="title" content="stx Project"><meta name="description" content="A website built with stx templating engine"><meta property="og:title" content="stx Project"><meta property="og:description" content="A website built with stx templating engine"><meta property="og:type" content="website"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="stx Project"><meta name="twitter:description" content="A website built with stx templating engine"> <script data-stx-runtime src="/_stx/runtime.dbee66d1.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ts-cloud - Preview environments</title><link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect x='3' y='3' width='26' height='26' rx='8' fill='%235a8be0'/%3E%3C/svg%3E"><link rel="preconnect" href="https://fonts.googleapis.com"><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"><link rel="stylesheet" href="/_stx/style.448ab192.css"> <script data-stx-scoped>
2
- function __stx_setup_1788018981021_10() {
1
+ <!DOCTYPE html><html lang="en" data-theme="dark"><head><meta charset="UTF-8"><meta name="stx-build" content="mtekhpm3jmsm9i"><meta name="title" content="stx Project"><meta name="description" content="A website built with stx templating engine"><meta property="og:title" content="stx Project"><meta property="og:description" content="A website built with stx templating engine"><meta property="og:type" content="website"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="stx Project"><meta name="twitter:description" content="A website built with stx templating engine"> <script data-stx-runtime src="/_stx/runtime.dbee66d1.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ts-cloud - Preview environments</title><link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect x='3' y='3' width='26' height='26' rx='8' fill='%235a8be0'/%3E%3C/svg%3E"><link rel="preconnect" href="https://fonts.googleapis.com"><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"><link rel="stylesheet" href="/_stx/style.448ab192.css"> <script data-stx-scoped>
2
+ function __stx_setup_1788019243863_14() {
3
3
  const { batch, computed, configureFetch, defineEmits, defineExpose, definePageMeta, defineProps, defineSlots, defineStore, derived, effect, goBack, goForward, inject, invalidateRoute, isDerived, isSignal, navigate, nextTick, onBeforeMount, onBeforeUnmount, onDestroy, onMount, onMounted, onUnmounted, peek, provide, reactive, ref, registerStoresClient, setRouteParams, state, untrack, useAsync, useClickOutside, useColorMode, useCookie, useCounter, useDark, useDebounce, useDebouncedValue, useEventListener, useFetch, useFocus, useHead, useId, useInterval, useLocalStorage, useMediaQuery, useMutation, useOptimistic, usePreferredContrast, usePreferredDark, usePreferredLight, usePreferredReducedMotion, useQuery, useReactiveProp, useRef, useRoute, useRouteParam, useRouteParams, useScrollLock, useSearchParams, useSeoMeta, useSessionStorage, useSlots, useStore, useThrottle, useTimeout, useToggle, useWebSocket, watch, watchEffect, watchMultiple, withDefaults } = window.stx;
4
4
 
5
5
  const data = state({ previews: [], definitions: [], resources: [], environments: [] });
@@ -107,9 +107,9 @@ onMount(() => {
107
107
 
108
108
  return { data, message, loading, destroyId, destroyConfirm, cleanup, request, refresh, tone, age, configure, deploy, extend, rebuild, destroy, runCleanup };
109
109
  }
110
- window.__stx_latestSetup=__stx_setup_1788018981021_10;
111
- if(window.stx)window.stx._latestSetup=__stx_setup_1788018981021_10;
112
- </script> <style data-stx-cloak>[x-cloak]{display:none !important}</style><link data-crosswind="generated" rel="stylesheet" href="/_stx/crosswind.906ee17c.css"></head><body data-stx="__stx_setup_1788018981021_10"><a data-stx-scope="stx_scope_nav_13" class="skip-link" href="#main-content">Skip to content</a><button class="nav-toggle-button" type="button" aria-label="Open navigation" aria-controls="primary-navigation" aria-expanded="false"><span></span><span></span><span></span></button><button class="nav-scrim" type="button" aria-label="Close navigation"></button><aside class="app-sidebar" id="primary-navigation" aria-label="Primary navigation"><a class="brand" href="/?env=production"><span class="dot"></span><span>ts-cloud</span></a><div class="sidebar-context"><span class="context-label">Project</span><strong>Project</strong></div><div class="environment-picker" aria-label="Environment"><span class="context-label">Environment</span><details><summary class="environment-current production"><span>PROD</span><strong>production</strong></summary></details></div><button class="command-trigger" type="button" aria-keyshortcuts="Meta+K Control+K"><span>Search resources</span><kbd>⌘ K</kbd></button><div class="nav-groups"><section class="nav-group"><h2>Overview</h2><a class="" href="/?env=production">Dashboard</a><a href="/server/activity?env=production">Activity</a></section><section class="nav-group"><h2>Applications</h2><a class="" href="/server/sites?env=production">Services</a><a class="" href="/server/deployments?env=production">Deployments</a><a class="" href="/server/logs?env=production">Logs</a><a class="" href="/integrations?env=production">Git integrations</a><a class="" href="/applications/new?env=production">Create application</a><a class="" href="/applications/compose?env=production">Compose applications</a></section><section class="nav-group"><h2>Operations</h2><a class="" href="/operations/queue?env=production">Deployment queue</a><a class="active" href="/operations/previews?env=production">Preview environments</a><a class="" href="/operations/releases?env=production">Releases & promotion</a><a class="" href="/operations/regions?env=production">Regions & failover</a><a class="" href="/operations/maintenance?env=production">Maintenance & DR</a><a class="" href="/operations/workloads?env=production">Workloads</a><a class="" href="/operations/observability?env=production">Observability</a><a class="" href="/operations/alerts?env=production">Alerts & health</a><a class="" href="/operations/spend?env=production">Spend & budgets</a><a href="/server/metrics?env=production">Metrics</a><a href="/server/services?env=production">Runtime services</a><a class="" href="/operations/jobs?env=production">Workers & schedules</a><a class="" href="/operations/configuration?env=production">Environment &amp; secrets</a><a class="" href="/data/backups?env=production">Backups &amp; recovery</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/actions?env=production">Run operations</a></section><section class="nav-group"><h2>Infrastructure</h2><a class="" href="/infrastructure/topology?env=production">Infrastructure map</a><a class="" href="/data/services?env=production">Data services</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/firewall?env=production">Network & firewall</a><a href="/server/ssh-keys?env=production">SSH keys</a><a class="" href="/server/fleet?env=production">Fleet inventory</a><a class="" href="/server/capacity?env=production">Capacity & placement</a><a href="/security?env=production">Security posture</a><a href="/server/terminal?env=production">Terminal</a></section><section class="nav-group"><h2>Organization</h2><a class="" href="/server/team?env=production">People & access</a><a class="" href="/account/automation?env=production">API & automation</a></section><section class="nav-group"><h2>Account</h2><a class="" href="/account/security?env=production">Sign-in & security</a></section></div><form method="post" action="/api/logout" class="signout"><button type="submit">Sign out</button></form></aside><dialog class="command-palette" aria-labelledby="command-title"><div class="command-search"><span aria-hidden="true">⌕</span><input type="search" placeholder="Search services, domains, deployments…" aria-label="Search resources" autocomplete="off"><button type="button" class="command-close" aria-label="Close search">Esc</button></div><h2 id="command-title" class="sr-only">Search resources and navigation</h2><div class="command-status" role="status">Start typing to search this project.</div><section class="saved-views" aria-labelledby="saved-views-title"><div class="saved-views-heading"><h3 id="saved-views-title">Saved views</h3><form class="save-view-form"><label class="sr-only" for="save-view-name">Saved view name</label><input id="save-view-name" maxlength="64" placeholder="Name this view" autocomplete="off"><button type="submit">Save current filters</button></form></div><div class="saved-view-list"></div></section><form class="tag-result-form"><label for="tag-result-name">Tag selected resource</label><input id="tag-result-name" maxlength="32" placeholder="customer-facing" pattern="[A-Za-z0-9][A-Za-z0-9 -]{0,31}" autocomplete="off"><input class="tag-color" type="color" value="#5a8be0" aria-label="Tag color"><button type="submit">Add tag</button></form><div class="command-results" role="listbox" aria-label="Search results"></div><footer><span>↑ ↓ navigate</span><span>Enter open</span><span>Esc close</span></footer></dialog><div class="context-bar" aria-label="Current scope"><div class="context-path"><div class="context-breadcrumb"><span>Project</span><i>/</i><strong>production</strong></div><div class="context-filters" aria-label="Active filters"></div></div><span class="scope-safety production">Production scope</span></div> <script data-stx-scoped data-stx-run="always">
110
+ window.__stx_latestSetup=__stx_setup_1788019243863_14;
111
+ if(window.stx)window.stx._latestSetup=__stx_setup_1788019243863_14;
112
+ </script> <style data-stx-cloak>[x-cloak]{display:none !important}</style><link data-crosswind="generated" rel="stylesheet" href="/_stx/crosswind.906ee17c.css"></head><body data-stx="__stx_setup_1788019243863_14"><a data-stx-scope="stx_scope_nav_18" class="skip-link" href="#main-content">Skip to content</a><button class="nav-toggle-button" type="button" aria-label="Open navigation" aria-controls="primary-navigation" aria-expanded="false"><span></span><span></span><span></span></button><button class="nav-scrim" type="button" aria-label="Close navigation"></button><aside class="app-sidebar" id="primary-navigation" aria-label="Primary navigation"><a class="brand" href="/?env=production"><span class="dot"></span><span>ts-cloud</span></a><div class="sidebar-context"><span class="context-label">Project</span><strong>Project</strong></div><div class="environment-picker" aria-label="Environment"><span class="context-label">Environment</span><details><summary class="environment-current production"><span>PROD</span><strong>production</strong></summary></details></div><button class="command-trigger" type="button" aria-keyshortcuts="Meta+K Control+K"><span>Search resources</span><kbd>⌘ K</kbd></button><div class="nav-groups"><section class="nav-group"><h2>Overview</h2><a class="" href="/?env=production">Dashboard</a><a href="/server/activity?env=production">Activity</a></section><section class="nav-group"><h2>Applications</h2><a class="" href="/server/sites?env=production">Services</a><a class="" href="/server/deployments?env=production">Deployments</a><a class="" href="/server/logs?env=production">Logs</a><a class="" href="/integrations?env=production">Git integrations</a><a class="" href="/applications/new?env=production">Create application</a><a class="" href="/applications/compose?env=production">Compose applications</a></section><section class="nav-group"><h2>Operations</h2><a class="" href="/operations/queue?env=production">Deployment queue</a><a class="active" href="/operations/previews?env=production">Preview environments</a><a class="" href="/operations/releases?env=production">Releases & promotion</a><a class="" href="/operations/regions?env=production">Regions & failover</a><a class="" href="/operations/maintenance?env=production">Maintenance & DR</a><a class="" href="/operations/workloads?env=production">Workloads</a><a class="" href="/operations/observability?env=production">Observability</a><a class="" href="/operations/alerts?env=production">Alerts & health</a><a class="" href="/operations/spend?env=production">Spend & budgets</a><a href="/server/metrics?env=production">Metrics</a><a href="/server/services?env=production">Runtime services</a><a class="" href="/operations/jobs?env=production">Workers & schedules</a><a class="" href="/operations/configuration?env=production">Environment &amp; secrets</a><a class="" href="/data/backups?env=production">Backups &amp; recovery</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/actions?env=production">Run operations</a></section><section class="nav-group"><h2>Infrastructure</h2><a class="" href="/infrastructure/topology?env=production">Infrastructure map</a><a class="" href="/data/services?env=production">Data services</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/firewall?env=production">Network & firewall</a><a href="/server/ssh-keys?env=production">SSH keys</a><a class="" href="/server/fleet?env=production">Fleet inventory</a><a class="" href="/server/capacity?env=production">Capacity & placement</a><a href="/security?env=production">Security posture</a><a href="/server/terminal?env=production">Terminal</a></section><section class="nav-group"><h2>Organization</h2><a class="" href="/server/team?env=production">People & access</a><a class="" href="/account/automation?env=production">API & automation</a></section><section class="nav-group"><h2>Account</h2><a class="" href="/account/security?env=production">Sign-in & security</a></section></div><form method="post" action="/api/logout" class="signout"><button type="submit">Sign out</button></form></aside><dialog class="command-palette" aria-labelledby="command-title"><div class="command-search"><span aria-hidden="true">⌕</span><input type="search" placeholder="Search services, domains, deployments…" aria-label="Search resources" autocomplete="off"><button type="button" class="command-close" aria-label="Close search">Esc</button></div><h2 id="command-title" class="sr-only">Search resources and navigation</h2><div class="command-status" role="status">Start typing to search this project.</div><section class="saved-views" aria-labelledby="saved-views-title"><div class="saved-views-heading"><h3 id="saved-views-title">Saved views</h3><form class="save-view-form"><label class="sr-only" for="save-view-name">Saved view name</label><input id="save-view-name" maxlength="64" placeholder="Name this view" autocomplete="off"><button type="submit">Save current filters</button></form></div><div class="saved-view-list"></div></section><form class="tag-result-form"><label for="tag-result-name">Tag selected resource</label><input id="tag-result-name" maxlength="32" placeholder="customer-facing" pattern="[A-Za-z0-9][A-Za-z0-9 -]{0,31}" autocomplete="off"><input class="tag-color" type="color" value="#5a8be0" aria-label="Tag color"><button type="submit">Add tag</button></form><div class="command-results" role="listbox" aria-label="Search results"></div><footer><span>↑ ↓ navigate</span><span>Enter open</span><span>Esc close</span></footer></dialog><div class="context-bar" aria-label="Current scope"><div class="context-path"><div class="context-breadcrumb"><span>Project</span><i>/</i><strong>production</strong></div><div class="context-filters" aria-label="Active filters"></div></div><span class="scope-safety production">Production scope</span></div> <script data-stx-scoped data-stx-run="always">
113
113
  (function() {
114
114
  var { batch, computed, configureFetch, defineEmits, defineExpose, definePageMeta, defineProps, defineSlots, defineStore, derived, effect, goBack, goForward, inject, invalidateRoute, isDerived, isSignal, navigate, nextTick, onBeforeMount, onBeforeUnmount, onDestroy, onMount, onMounted, onUnmounted, peek, provide, reactive, ref, refresh, registerStoresClient, setRouteParams, state, untrack, useAsync, useClickOutside, useColorMode, useCookie, useCounter, useDark, useDebounce, useDebouncedValue, useEventListener, useFetch, useFocus, useHead, useId, useInterval, useLocalStorage, useMediaQuery, useMutation, useOptimistic, usePreferredContrast, usePreferredDark, usePreferredLight, usePreferredReducedMotion, useQuery, useReactiveProp, useRef, useRoute, useRouteParam, useRouteParams, useScrollLock, useSearchParams, useSeoMeta, useSessionStorage, useSlots, useStore, useThrottle, useTimeout, useToggle, useWebSocket, watch, watchEffect, watchMultiple, withDefaults } = window.stx;
115
115
  var __destroyHooks = [];
@@ -460,6 +460,6 @@ if(window.stx)window.stx._latestSetup=__stx_setup_1788018981021_10;
460
460
 
461
461
 
462
462
  try { if (typeof __stxScopeRenames !== 'undefined' && __stxScopeRenames) { for (var __stxRK in __stxScopeRenames) __scopeRegistration[__stxRK] = __stxScopeRenames[__stxRK]; } } catch (e) { /* no renames */ }
463
- window.stx._scopes['stx_scope_nav_13'] = __scopeRegistration;
463
+ window.stx._scopes['stx_scope_nav_18'] = __scopeRegistration;
464
464
  })();
465
465
  </script> <div class="preview-wrap wrap" id="main-content"><div class="crumbs">Operations <span class="sep">/</span> Preview environments</div><header class="page preview-hero"><div><h1>Preview environments</h1><p>Isolated, exact-commit deployments with stable URLs, bounded resources, and automatic teardown.</p></div><button class="btn ghost" type="button" @click="refresh()">Refresh</button></header><p class="notice" @show="!!message()" x-cloak>{{ message() }}</p><section class="section stats"><div class="panel"><small>Total</small><strong x-cloak>{{ data().previews.length }}</strong></div><div class="panel"><small>Active</small><strong x-cloak>{{ data().previews.filter(v=>v.status==='active').length }}</strong></div><div class="panel"><small>Expiring</small><strong x-cloak>{{ data().previews.filter(v=>!['destroyed','destroying'].includes(v.status)&&new Date(v.expiresAt)-Date.now()<86400000).length }}</strong></div><div class="panel"><small>Cleanup errors</small><strong x-cloak>{{ data().previews.filter(v=>v.status==='cleanup_failed').length }}</strong></div></section><section class="panel preview-list section"><div class="section-heading"><div><h2>Environments</h2><p class="note">A URL always corresponds to the immutable commit shown here.</p></div></div><div class="empty" @show="!loading() && !data().previews.length" x-cloak><strong>No previews yet</strong><span>Configure an application policy or enable PR previews on a Git binding.</span></div><div class="preview-grid" x-cloak><article class="preview-card" @each="item in data().previews" :key="item.id" x-cloak><div class="card-head" x-cloak><div x-cloak><h3 x-cloak>{{ item.name }}</h3><p class="note" x-cloak>{{ item.pullRequestNumber ? 'PR #' + item.pullRequestNumber : item.branch }} · {{ item.commitSha.slice(0,12) }}</p></div><span class="pill" :class="tone(item.status)" x-cloak>{{ item.status }}</span></div><a class="preview-url" :href="item.url" target="_blank" rel="noopener" x-cloak>{{ item.url || 'URL pending' }}</a><dl><div><dt>Age / expiry</dt><dd x-cloak>{{ age(item.createdAt) }} · {{ new Date(item.expiresAt).toLocaleString() }}</dd></div><div><dt>Latest deployment</dt><dd class="mono" x-cloak>{{ item.latestOperationId || '—' }}</dd></div><div><dt>Estimated cost</dt><dd x-cloak>{{ item.costEstimate == null ? 'Not available' : '$' + item.costEstimate.toFixed(2) + '/mo' }}</dd></div><div @show="!!item.teardownError" x-cloak><dt>Teardown error</dt><dd class="bad-text" x-cloak>{{ item.teardownError }}</dd></div></dl><div class="actions"><a class="btn ghost sm" href="/operations/queue?state=all">Operation</a></div><div class="confirm" @show="destroyId()===item.id" x-cloak><p x-cloak>Type <b x-cloak>{{ item.name }}</b>. Only resources with matching preview tags are eligible.</p><input :value="destroyConfirm()" @input="destroyConfirm.set($event.target.value)"><button class="btn danger sm" :disabled="destroyConfirm()!==item.name" @click="destroy()">Queue teardown</button></div></article></div></section><div class="forms section"></div></div><style> .preview-wrap{max-width:1450px}.preview-hero,.card-head,.actions{display:flex;justify-content:space-between;gap:12px;align-items:flex-start}.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}.stats strong{display:block;font-size:1.7rem;margin-top:8px}.preview-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.preview-card{border:1px solid var(--line);border-radius:11px;padding:16px;background:var(--bg2);display:grid;gap:13px}.preview-card h3{margin:0}.preview-url{overflow:hidden;text-overflow:ellipsis}.preview-card dl{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:0}.preview-card dt{color:var(--txt3);font-size:11px}.preview-card dd{margin:3px 0 0;font-size:12px;overflow-wrap:anywhere}.actions{justify-content:flex-start;flex-wrap:wrap}.confirm{border:1px solid rgba(235,100,100,.35);padding:12px;border-radius:8px;display:grid;gap:8px}.confirm p{margin:0;font-size:12px}.forms{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;align-items:start}.forms .panel{display:grid;gap:10px}.forms h2{margin:0 0 5px}.forms label{display:grid;gap:5px;color:var(--txt3);font-size:12px}.forms :is(input,select,textarea){width:100%}.forms .check{display:flex;align-items:center}.forms .check input{width:auto}.pair{display:grid;grid-template-columns:1fr 1fr;gap:8px}.bad-text{color:#ff9b9b}.notice{padding:10px}.empty{padding:25px}.empty span{display:block;color:var(--txt3);margin-top:5px} @media(max-width:1000px){.forms{grid-template-columns:1fr 1fr}.preview-grid{grid-template-columns:1fr}}@media(max-width:650px){.stats,.forms{grid-template-columns:1fr 1fr}.preview-card dl{grid-template-columns:1fr}.preview-hero{display:grid}}@media(max-width:440px){.stats,.forms{grid-template-columns:1fr}.pair{grid-template-columns:1fr}} </style></body></html>
@@ -1,5 +1,5 @@
1
- <!DOCTYPE html><html lang="en" data-theme="dark"><head><meta charset="UTF-8"><meta name="stx-build" content="mtekc2s63mrzwt"><meta name="title" content="stx Project"><meta name="description" content="A website built with stx templating engine"><meta property="og:title" content="stx Project"><meta property="og:description" content="A website built with stx templating engine"><meta property="og:type" content="website"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="stx Project"><meta name="twitter:description" content="A website built with stx templating engine"> <script data-stx-runtime src="/_stx/runtime.dbee66d1.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ts-cloud - Deployment queue</title><link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect x='3' y='3' width='26' height='26' rx='8' fill='%235a8be0'/%3E%3C/svg%3E"><link rel="preconnect" href="https://fonts.googleapis.com"><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"><link rel="stylesheet" href="/_stx/style.448ab192.css"> <script data-stx-scoped>
2
- function __stx_setup_1788018981022_11() {
1
+ <!DOCTYPE html><html lang="en" data-theme="dark"><head><meta charset="UTF-8"><meta name="stx-build" content="mtekhpm3jmsm9i"><meta name="title" content="stx Project"><meta name="description" content="A website built with stx templating engine"><meta property="og:title" content="stx Project"><meta property="og:description" content="A website built with stx templating engine"><meta property="og:type" content="website"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="stx Project"><meta name="twitter:description" content="A website built with stx templating engine"> <script data-stx-runtime src="/_stx/runtime.dbee66d1.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ts-cloud - Deployment queue</title><link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect x='3' y='3' width='26' height='26' rx='8' fill='%235a8be0'/%3E%3C/svg%3E"><link rel="preconnect" href="https://fonts.googleapis.com"><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"><link rel="stylesheet" href="/_stx/style.448ab192.css"> <script data-stx-scoped>
2
+ function __stx_setup_1788019243856_8() {
3
3
  const { batch, computed, configureFetch, defineEmits, defineExpose, definePageMeta, defineProps, defineSlots, defineStore, derived, effect, goBack, goForward, inject, invalidateRoute, isDerived, isSignal, navigate, nextTick, onBeforeMount, onBeforeUnmount, onDestroy, onMount, onMounted, onUnmounted, peek, provide, reactive, ref, registerStoresClient, setRouteParams, state, untrack, useAsync, useClickOutside, useColorMode, useCookie, useCounter, useDark, useDebounce, useDebouncedValue, useEventListener, useFetch, useFocus, useHead, useId, useInterval, useLocalStorage, useMediaQuery, useMutation, useOptimistic, usePreferredContrast, usePreferredDark, usePreferredLight, usePreferredReducedMotion, useQuery, useReactiveProp, useRef, useRoute, useRouteParam, useRouteParams, useScrollLock, useSearchParams, useSeoMeta, useSessionStorage, useSlots, useStore, useThrottle, useTimeout, useToggle, useWebSocket, watch, watchEffect, watchMultiple, withDefaults } = window.stx;
4
4
 
5
5
  const operations = state([]);
@@ -135,9 +135,9 @@ onMount(() => {
135
135
 
136
136
  return { operations, concurrency, selectedId, logs, filter, loading, message, confirmLimits, confirmClear, source, selected, visible, duration, statusTone, setFilter, refresh, appendLog, openDetail, closeDetail, mutate, cancelSelected, retrySelected, saveLimits, clearHistory };
137
137
  }
138
- window.__stx_latestSetup=__stx_setup_1788018981022_11;
139
- if(window.stx)window.stx._latestSetup=__stx_setup_1788018981022_11;
140
- </script> <style data-stx-cloak>[x-cloak]{display:none !important}</style><link data-crosswind="generated" rel="stylesheet" href="/_stx/crosswind.906ee17c.css"></head><body data-stx="__stx_setup_1788018981022_11"><a data-stx-scope="stx_scope_nav_14" class="skip-link" href="#main-content">Skip to content</a><button class="nav-toggle-button" type="button" aria-label="Open navigation" aria-controls="primary-navigation" aria-expanded="false"><span></span><span></span><span></span></button><button class="nav-scrim" type="button" aria-label="Close navigation"></button><aside class="app-sidebar" id="primary-navigation" aria-label="Primary navigation"><a class="brand" href="/?env=production"><span class="dot"></span><span>ts-cloud</span></a><div class="sidebar-context"><span class="context-label">Project</span><strong>Project</strong></div><div class="environment-picker" aria-label="Environment"><span class="context-label">Environment</span><details><summary class="environment-current production"><span>PROD</span><strong>production</strong></summary></details></div><button class="command-trigger" type="button" aria-keyshortcuts="Meta+K Control+K"><span>Search resources</span><kbd>⌘ K</kbd></button><div class="nav-groups"><section class="nav-group"><h2>Overview</h2><a class="" href="/?env=production">Dashboard</a><a href="/server/activity?env=production">Activity</a></section><section class="nav-group"><h2>Applications</h2><a class="" href="/server/sites?env=production">Services</a><a class="" href="/server/deployments?env=production">Deployments</a><a class="" href="/server/logs?env=production">Logs</a><a class="" href="/integrations?env=production">Git integrations</a><a class="" href="/applications/new?env=production">Create application</a><a class="" href="/applications/compose?env=production">Compose applications</a></section><section class="nav-group"><h2>Operations</h2><a class="active" href="/operations/queue?env=production">Deployment queue</a><a class="" href="/operations/previews?env=production">Preview environments</a><a class="" href="/operations/releases?env=production">Releases & promotion</a><a class="" href="/operations/regions?env=production">Regions & failover</a><a class="" href="/operations/maintenance?env=production">Maintenance & DR</a><a class="" href="/operations/workloads?env=production">Workloads</a><a class="" href="/operations/observability?env=production">Observability</a><a class="" href="/operations/alerts?env=production">Alerts & health</a><a class="" href="/operations/spend?env=production">Spend & budgets</a><a href="/server/metrics?env=production">Metrics</a><a href="/server/services?env=production">Runtime services</a><a class="" href="/operations/jobs?env=production">Workers & schedules</a><a class="" href="/operations/configuration?env=production">Environment &amp; secrets</a><a class="" href="/data/backups?env=production">Backups &amp; recovery</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/actions?env=production">Run operations</a></section><section class="nav-group"><h2>Infrastructure</h2><a class="" href="/infrastructure/topology?env=production">Infrastructure map</a><a class="" href="/data/services?env=production">Data services</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/firewall?env=production">Network & firewall</a><a href="/server/ssh-keys?env=production">SSH keys</a><a class="" href="/server/fleet?env=production">Fleet inventory</a><a class="" href="/server/capacity?env=production">Capacity & placement</a><a href="/security?env=production">Security posture</a><a href="/server/terminal?env=production">Terminal</a></section><section class="nav-group"><h2>Organization</h2><a class="" href="/server/team?env=production">People & access</a><a class="" href="/account/automation?env=production">API & automation</a></section><section class="nav-group"><h2>Account</h2><a class="" href="/account/security?env=production">Sign-in & security</a></section></div><form method="post" action="/api/logout" class="signout"><button type="submit">Sign out</button></form></aside><dialog class="command-palette" aria-labelledby="command-title"><div class="command-search"><span aria-hidden="true">⌕</span><input type="search" placeholder="Search services, domains, deployments…" aria-label="Search resources" autocomplete="off"><button type="button" class="command-close" aria-label="Close search">Esc</button></div><h2 id="command-title" class="sr-only">Search resources and navigation</h2><div class="command-status" role="status">Start typing to search this project.</div><section class="saved-views" aria-labelledby="saved-views-title"><div class="saved-views-heading"><h3 id="saved-views-title">Saved views</h3><form class="save-view-form"><label class="sr-only" for="save-view-name">Saved view name</label><input id="save-view-name" maxlength="64" placeholder="Name this view" autocomplete="off"><button type="submit">Save current filters</button></form></div><div class="saved-view-list"></div></section><form class="tag-result-form"><label for="tag-result-name">Tag selected resource</label><input id="tag-result-name" maxlength="32" placeholder="customer-facing" pattern="[A-Za-z0-9][A-Za-z0-9 -]{0,31}" autocomplete="off"><input class="tag-color" type="color" value="#5a8be0" aria-label="Tag color"><button type="submit">Add tag</button></form><div class="command-results" role="listbox" aria-label="Search results"></div><footer><span>↑ ↓ navigate</span><span>Enter open</span><span>Esc close</span></footer></dialog><div class="context-bar" aria-label="Current scope"><div class="context-path"><div class="context-breadcrumb"><span>Project</span><i>/</i><strong>production</strong></div><div class="context-filters" aria-label="Active filters"></div></div><span class="scope-safety production">Production scope</span></div> <script data-stx-scoped data-stx-run="always">
138
+ window.__stx_latestSetup=__stx_setup_1788019243856_8;
139
+ if(window.stx)window.stx._latestSetup=__stx_setup_1788019243856_8;
140
+ </script> <style data-stx-cloak>[x-cloak]{display:none !important}</style><link data-crosswind="generated" rel="stylesheet" href="/_stx/crosswind.906ee17c.css"></head><body data-stx="__stx_setup_1788019243856_8"><a data-stx-scope="stx_scope_nav_11" class="skip-link" href="#main-content">Skip to content</a><button class="nav-toggle-button" type="button" aria-label="Open navigation" aria-controls="primary-navigation" aria-expanded="false"><span></span><span></span><span></span></button><button class="nav-scrim" type="button" aria-label="Close navigation"></button><aside class="app-sidebar" id="primary-navigation" aria-label="Primary navigation"><a class="brand" href="/?env=production"><span class="dot"></span><span>ts-cloud</span></a><div class="sidebar-context"><span class="context-label">Project</span><strong>Project</strong></div><div class="environment-picker" aria-label="Environment"><span class="context-label">Environment</span><details><summary class="environment-current production"><span>PROD</span><strong>production</strong></summary></details></div><button class="command-trigger" type="button" aria-keyshortcuts="Meta+K Control+K"><span>Search resources</span><kbd>⌘ K</kbd></button><div class="nav-groups"><section class="nav-group"><h2>Overview</h2><a class="" href="/?env=production">Dashboard</a><a href="/server/activity?env=production">Activity</a></section><section class="nav-group"><h2>Applications</h2><a class="" href="/server/sites?env=production">Services</a><a class="" href="/server/deployments?env=production">Deployments</a><a class="" href="/server/logs?env=production">Logs</a><a class="" href="/integrations?env=production">Git integrations</a><a class="" href="/applications/new?env=production">Create application</a><a class="" href="/applications/compose?env=production">Compose applications</a></section><section class="nav-group"><h2>Operations</h2><a class="active" href="/operations/queue?env=production">Deployment queue</a><a class="" href="/operations/previews?env=production">Preview environments</a><a class="" href="/operations/releases?env=production">Releases & promotion</a><a class="" href="/operations/regions?env=production">Regions & failover</a><a class="" href="/operations/maintenance?env=production">Maintenance & DR</a><a class="" href="/operations/workloads?env=production">Workloads</a><a class="" href="/operations/observability?env=production">Observability</a><a class="" href="/operations/alerts?env=production">Alerts & health</a><a class="" href="/operations/spend?env=production">Spend & budgets</a><a href="/server/metrics?env=production">Metrics</a><a href="/server/services?env=production">Runtime services</a><a class="" href="/operations/jobs?env=production">Workers & schedules</a><a class="" href="/operations/configuration?env=production">Environment &amp; secrets</a><a class="" href="/data/backups?env=production">Backups &amp; recovery</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/actions?env=production">Run operations</a></section><section class="nav-group"><h2>Infrastructure</h2><a class="" href="/infrastructure/topology?env=production">Infrastructure map</a><a class="" href="/data/services?env=production">Data services</a><a class="" href="/data/volumes?env=production">Persistent volumes</a><a href="/server/firewall?env=production">Network & firewall</a><a href="/server/ssh-keys?env=production">SSH keys</a><a class="" href="/server/fleet?env=production">Fleet inventory</a><a class="" href="/server/capacity?env=production">Capacity & placement</a><a href="/security?env=production">Security posture</a><a href="/server/terminal?env=production">Terminal</a></section><section class="nav-group"><h2>Organization</h2><a class="" href="/server/team?env=production">People & access</a><a class="" href="/account/automation?env=production">API & automation</a></section><section class="nav-group"><h2>Account</h2><a class="" href="/account/security?env=production">Sign-in & security</a></section></div><form method="post" action="/api/logout" class="signout"><button type="submit">Sign out</button></form></aside><dialog class="command-palette" aria-labelledby="command-title"><div class="command-search"><span aria-hidden="true">⌕</span><input type="search" placeholder="Search services, domains, deployments…" aria-label="Search resources" autocomplete="off"><button type="button" class="command-close" aria-label="Close search">Esc</button></div><h2 id="command-title" class="sr-only">Search resources and navigation</h2><div class="command-status" role="status">Start typing to search this project.</div><section class="saved-views" aria-labelledby="saved-views-title"><div class="saved-views-heading"><h3 id="saved-views-title">Saved views</h3><form class="save-view-form"><label class="sr-only" for="save-view-name">Saved view name</label><input id="save-view-name" maxlength="64" placeholder="Name this view" autocomplete="off"><button type="submit">Save current filters</button></form></div><div class="saved-view-list"></div></section><form class="tag-result-form"><label for="tag-result-name">Tag selected resource</label><input id="tag-result-name" maxlength="32" placeholder="customer-facing" pattern="[A-Za-z0-9][A-Za-z0-9 -]{0,31}" autocomplete="off"><input class="tag-color" type="color" value="#5a8be0" aria-label="Tag color"><button type="submit">Add tag</button></form><div class="command-results" role="listbox" aria-label="Search results"></div><footer><span>↑ ↓ navigate</span><span>Enter open</span><span>Esc close</span></footer></dialog><div class="context-bar" aria-label="Current scope"><div class="context-path"><div class="context-breadcrumb"><span>Project</span><i>/</i><strong>production</strong></div><div class="context-filters" aria-label="Active filters"></div></div><span class="scope-safety production">Production scope</span></div> <script data-stx-scoped data-stx-run="always">
141
141
  (function() {
142
142
  var { batch, computed, configureFetch, defineEmits, defineExpose, definePageMeta, defineProps, defineSlots, defineStore, derived, effect, goBack, goForward, inject, invalidateRoute, isDerived, isSignal, navigate, nextTick, onBeforeMount, onBeforeUnmount, onDestroy, onMount, onMounted, onUnmounted, peek, provide, reactive, ref, refresh, registerStoresClient, setRouteParams, state, untrack, useAsync, useClickOutside, useColorMode, useCookie, useCounter, useDark, useDebounce, useDebouncedValue, useEventListener, useFetch, useFocus, useHead, useId, useInterval, useLocalStorage, useMediaQuery, useMutation, useOptimistic, usePreferredContrast, usePreferredDark, usePreferredLight, usePreferredReducedMotion, useQuery, useReactiveProp, useRef, useRoute, useRouteParam, useRouteParams, useScrollLock, useSearchParams, useSeoMeta, useSessionStorage, useSlots, useStore, useThrottle, useTimeout, useToggle, useWebSocket, watch, watchEffect, watchMultiple, withDefaults } = window.stx;
143
143
  var __destroyHooks = [];
@@ -488,6 +488,6 @@ if(window.stx)window.stx._latestSetup=__stx_setup_1788018981022_11;
488
488
 
489
489
 
490
490
  try { if (typeof __stxScopeRenames !== 'undefined' && __stxScopeRenames) { for (var __stxRK in __stxScopeRenames) __scopeRegistration[__stxRK] = __stxScopeRenames[__stxRK]; } } catch (e) { /* no renames */ }
491
- window.stx._scopes['stx_scope_nav_14'] = __scopeRegistration;
491
+ window.stx._scopes['stx_scope_nav_11'] = __scopeRegistration;
492
492
  })();
493
493
  </script> <div class="queue-wrap wrap"><div class="crumbs">Operations <span class="sep">/</span> Deployment queue</div><header class="page"><div><h1>Deployment queue</h1><p>Durable deployments and mutations, with ordered progress, resource locks, cancellation, and safe retries.</p></div><div class="queue-limits" x-cloak><span x-cloak>Project <b x-cloak>{{ concurrency().project }}</b></span><span x-cloak>Environment <b x-cloak>{{ concurrency().environment }}</b></span><span x-cloak>Provider <b x-cloak>{{ concurrency().provider }}</b></span><span x-cloak>Builds <b x-cloak>{{ concurrency().builds }}</b></span></div></header><div class="bad notice" @show="!!message()" x-cloak>{{ message() }}</div><div class="queue-layout" :class="{ inspecting: !!selectedId() }"><main class="panel queue-main"><div class="filters queue-filters"><div class="segmented" role="group" aria-label="Filter queue state"><button type="button" :class="{ active: filter() === 'active' }" @click="setFilter('active')">Active</button><button type="button" :class="{ active: filter() === 'all' }" @click="setFilter('all')">All</button><button type="button" :class="{ active: filter() === 'failed' }" @click="setFilter('failed')">Failed</button><button type="button" :class="{ active: filter() === 'cancelled' }" @click="setFilter('cancelled')">Cancelled</button></div><button class="btn sm" type="button" @click="refresh()">Refresh</button></div><div class="queue-table-wrap"><table class="queue-table"><thead><tr><th scope="col">Status</th><th scope="col">Target</th><th scope="col">Operation</th><th scope="col">Actor / trigger</th><th scope="col">Commit</th><th scope="col">Progress</th><th scope="col">Attempt</th><th scope="col">Timing</th></tr></thead><tbody><template :for="item in visible()"><tr class="queue-row" :class="{ selected: item.operation.id === selectedId() }" @click="openDetail(item)" tabindex="0"><td x-cloak><span class="pill" :class="statusTone(item.operation.state)" x-cloak>{{ item.operation.state }}</span></td><td x-cloak><b x-cloak>{{ item.target.name }}</b><small x-cloak>{{ item.target.kind }} · {{ item.target.slug }}</small></td><td class="mono" x-cloak>{{ item.operation.kind }}<small x-cloak>{{ item.operation.id.slice(0, 8) }}</small></td><td x-cloak>{{ item.actor?.name || 'System' }}<small x-cloak>{{ item.actor?.kind || 'automation' }}</small></td><td class="mono" x-cloak>{{ item.commit ? String(item.commit).slice(0, 12) : '—' }}</td><td x-cloak><span @show="!!item.job.currentStep" x-cloak>{{ item.job.currentStep }}</span><span class="blocked" @show="!!item.job.blockedReason" x-cloak>{{ item.job.blockedReason }}</span><small @show="!!item.approximatePosition && item.operation.state === 'queued'" x-cloak>About {{ item.approximatePosition.ahead }} ahead</small></td><td class="mono" x-cloak>{{ item.operation.attempt }} / {{ item.job.maxAttempts }}</td><td x-cloak>{{ duration(item.operation) }}<small x-cloak>{{ new Date(item.operation.createdAt).toLocaleString() }}</small></td></tr></template></tbody></table></div><div class="empty" @show="!loading() && visible().length === 0" x-cloak><strong>No matching work</strong><span>Queued deployments and other long-lived mutations will appear here.</span></div></main><aside class="panel queue-detail" @show="!!selected()" x-cloak><button class="detail-close" type="button" aria-label="Close operation detail" @click="closeDetail()">×</button><template :if="selected()" x-cloak><div class="eyebrow" x-cloak>{{ selected().operation.kind }}</div><h2 x-cloak>{{ selected().target.name }}</h2><div class="detail-meta" x-cloak><span class="pill" :class="statusTone(selected().operation.state)" x-cloak>{{ selected().operation.state }}</span><span x-cloak>Attempt {{ selected().operation.attempt }} of {{ selected().job.maxAttempts }}</span><span x-cloak>{{ duration(selected().operation) }}</span></div><div class="blocked-card" @show="!!selected().job.blockedReason" x-cloak><b>Waiting</b><span x-cloak>{{ selected().job.blockedReason }}</span><small>Position is an estimate because earlier work may unblock or retry.</small></div><div class="detail-actions"></div><h3>Structured progress</h3><div class="step-list"><template :for="entry in logs().filter(item => item.stream === 'step')"><div><span></span><b x-cloak>{{ entry.step || 'Step' }}</b><small x-cloak>{{ entry.message }}</small></div></template></div><details class="raw-logs" open><summary x-cloak>Raw logs · {{ logs().length }} chunks</summary><pre x-cloak><template :for="entry in logs()"><span :class="entry.stream" x-cloak>{{ entry.sequence }} {{ entry.stream.toUpperCase() }}{{ entry.redacted ? ' [REDACTED]' : '' }}{{ entry.truncated ? ' [TRUNCATED]' : '' }} {{ entry.message }} </span></template></pre></details><div class="detail-foot mono" x-cloak>{{ selected().operation.id }}</div></template></aside></div></div><style> .queue-wrap{max-width:1500px}.queue-limits{display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end}.queue-limits span{border:1px solid var(--line);background:var(--bg2);border-radius:8px;padding:8px 10px;color:var(--txt3);font-size:12px}.queue-limits b{color:var(--txt);margin-left:5px}.queue-layout{display:grid;grid-template-columns:minmax(0,1fr);gap:16px}.queue-layout.inspecting{grid-template-columns:minmax(620px,1.4fr) minmax(340px,.6fr)}.queue-main{padding:0;overflow:hidden}.queue-filters{padding:14px 16px;margin:0;border-bottom:1px solid var(--line);display:flex;justify-content:space-between}.queue-table-wrap{overflow:auto}.queue-table{min-width:1060px}.queue-row{cursor:pointer}.queue-row.selected{background:color-mix(in srgb,var(--accent) 9%,transparent)}.queue-row td small{display:block;margin-top:4px;color:var(--txt3);font-size:11px}.blocked{color:var(--yellow);font-size:12px}.queue-detail{position:sticky;top:16px;align-self:start;max-height:calc(100vh - 32px);overflow:auto;padding:22px}.detail-close{float:right;border:0;background:transparent;color:var(--txt3);font-size:24px;cursor:pointer}.eyebrow{text-transform:uppercase;letter-spacing:.08em;color:var(--accent);font-size:11px}.queue-detail h2{margin:5px 0 10px}.detail-meta,.detail-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap;color:var(--txt3);font-size:12px}.blocked-card{display:grid;gap:5px;margin:16px 0;padding:12px;border:1px solid color-mix(in srgb,var(--yellow) 35%,var(--line));border-radius:8px;background:color-mix(in srgb,var(--yellow) 6%,transparent)}.blocked-card small{color:var(--txt3)}.detail-actions{margin:16px 0}.step-list>div{display:grid;grid-template-columns:12px 1fr;gap:0 8px;margin:10px 0}.step-list span{width:8px;height:8px;margin-top:5px;border-radius:50%;background:var(--accent)}.step-list small{grid-column:2;color:var(--txt3)}.raw-logs{margin-top:14px}.raw-logs pre{max-height:330px;overflow:auto;background:#090c12;border:1px solid var(--line);border-radius:8px;padding:12px;font-size:11px;white-space:pre-wrap}.raw-logs .stderr{color:#ff9b9b}.raw-logs .step{color:#8dd6ff}.detail-foot{margin-top:16px;color:var(--txt3);font-size:10px}.queue-admin{margin-top:16px;display:grid;grid-template-columns:1fr 1fr;gap:14px 24px}.limit-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}.limit-grid label{font-size:11px;color:var(--txt3)}.limit-grid input,.confirm-row input{width:100%;margin-top:5px}.confirm-row{display:flex;gap:8px;align-items:end}.confirm-row input{margin:0}.notice{margin-bottom:12px}.notice.bad{padding:10px 12px} @media(max-width:1050px){.queue-layout.inspecting{grid-template-columns:1fr}.queue-detail{position:static;max-height:none}.queue-admin{grid-template-columns:1fr}} @media(max-width:680px){.queue-limits{justify-content:flex-start}.queue-table{min-width:0}.queue-table thead{display:none}.queue-table tbody,.queue-row{display:block}.queue-row{padding:14px;border-bottom:1px solid var(--line)}.queue-row td{display:grid;grid-template-columns:100px 1fr;padding:4px 0;border:0}.queue-row td:before{color:var(--txt3);font-size:11px}.queue-row td:nth-child(1):before{content:'Status'}.queue-row td:nth-child(2):before{content:'Target'}.queue-row td:nth-child(3):before{content:'Operation'}.queue-row td:nth-child(4):before{content:'Actor'}.queue-row td:nth-child(5):before{content:'Commit'}.queue-row td:nth-child(6):before{content:'Progress'}.queue-row td:nth-child(7):before{content:'Attempt'}.queue-row td:nth-child(8):before{content:'Timing'}.limit-grid{grid-template-columns:repeat(2,1fr)}.confirm-row{flex-direction:column;align-items:stretch}} </style></body></html>