@cloud-cli/on 1.50.2 → 1.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/on.js CHANGED
@@ -307,6 +307,13 @@ var de = class extends l {
307
307
  async getStoredFiles(e, t) {
308
308
  return this.fileStorage.enabled ? this.fileStorage.load(`${e}/${t}`) : C.all("SELECT file_path AS path, content FROM stored_files WHERE kind = ? AND owner_key = ?", [e, t]);
309
309
  }
310
+ async saveAiRequest(e, t, n) {
311
+ await C.run("INSERT INTO ai_requests (job_id, workflow_url, request_json) VALUES (?, ?, ?)", [
312
+ e,
313
+ t,
314
+ JSON.stringify(n)
315
+ ]);
316
+ }
310
317
  }, me = class {
311
318
  secrets = /* @__PURE__ */ new Map();
312
319
  constructor() {
@@ -333,7 +340,7 @@ var de = class extends l {
333
340
  for (let n of t) e = e.replaceAll(n, "****");
334
341
  return e;
335
342
  }
336
- }, he = "<!doctype html>\n<html lang=\"en\" class=\"dark\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <meta name=\"theme-color\" content=\"#030712\" />\n <meta name=\"mobile-web-app-capable\" content=\"yes\" />\n <link rel=\"manifest\" href=\"/manifest.webmanifest\" />\n <link rel=\"icon\" href=\"/app-icon.svg\" type=\"image/svg+xml\" />\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/lucide-icon.html\" />\n <link rel=\"component\" href=\"/app-header.html\" />\n <title>Workflow Engine Dashboard</title>\n <script type=\"importmap\">\n { \"imports\": { \"@li3/\": \"https://cdn.li3.dev/@li3/\" } }\n <\/script>\n </head>\n <body class=\"bg-gray-950 text-gray-100 min-h-screen p-4 md:p-6 font-sans\">\n <template app>\n <main class=\"max-w-6xl mx-auto space-y-6\">\n <app-header title=\"Runner Engine Status\" subtitle=\"Live Job Queue &amp; Execution Traces\"></app-header>\n <div class=\"flex justify-end gap-2 text-xs font-mono\">\n <template if=\"refreshError\">\n <span class=\"rounded border border-rose-500/20 bg-rose-500/10 px-3 py-1 text-rose-400\"\n >Refresh failed</span\n >\n </template>\n </div>\n\n <form class=\"flex items-center gap-2\" on-submit.prevent=\"applyFilter()\">\n <div class=\"relative min-w-0 flex-1\">\n <label class=\"sr-only\" for=\"job-filter\">Filter jobs</label>\n <input\n id=\"job-filter\"\n bind-value=\"filter\"\n on-input=\"setFilter($event)\"\n class=\"w-full rounded-lg border border-gray-800 bg-gray-900 px-3 py-2 pr-10 text-sm text-gray-200 outline-none placeholder:text-gray-600 focus:border-indigo-500\"\n placeholder=\"Filter: name:cloud-cli/* or text search\"\n />\n <template if=\"filter\">\n <button\n type=\"button\"\n on-click=\"clearFilter()\"\n class=\"absolute right-1 top-1/2 -translate-y-1/2 rounded-md p-1 text-gray-500 hover:bg-gray-800 hover:text-gray-200\"\n >\n <lucide-icon icon=\"x\" size=\"15\"></lucide-icon>\n <span class=\"sr-only\">Clear job filter</span>\n </button>\n </template>\n </div>\n <button\n type=\"submit\"\n aria-label=\"Search jobs\"\n class=\"inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-lg border border-indigo-500/40 bg-indigo-500/10 text-indigo-200 hover:bg-indigo-500/20\"\n >\n <lucide-icon icon=\"search\" size=\"16\"></lucide-icon>\n </button>\n </form>\n\n <template if=\"activeFilter\">\n <p class=\"flex items-center gap-1\">\n <span class=\"text-xs text-gray-400\">Showing {{ jobs.length }} jobs matching </span\n ><span class=\"font-mono text-indigo-300\">{{ activeFilter }}</span>\n </p>\n </template>\n\n <template if=\"notificationNotice\">\n <button\n class=\"w-full rounded-lg border border-gray-700 bg-gray-900 px-4 py-3 text-left text-sm text-gray-300\"\n on-click=\"notificationNotice = ''\"\n >\n {{ notificationNotice }}\n </button>\n </template>\n\n <section class=\"bg-gray-900 border border-gray-800 rounded-xl overflow-hidden hidden md:block\">\n <table class=\"w-full text-left text-sm\">\n <thead class=\"bg-gray-800/50 text-gray-400 text-xs uppercase font-mono border-b border-gray-800\">\n <tr>\n <th class=\"py-3 px-4\">Job ID</th>\n <th class=\"py-3 px-4\">Workflow</th>\n <th class=\"py-3 px-4\">Status</th>\n <th class=\"py-3 px-4 hidden xl:table-cell\">Worker</th>\n <th class=\"py-3 px-4 hidden lg:table-cell\">Created At</th>\n <th class=\"py-3 px-4 text-right\">Action</th>\n </tr>\n </thead>\n <tbody>\n <template for=\"job of jobs\">\n <tr class=\"border-b border-gray-800 hover:bg-gray-800/40 transition\">\n <td class=\"py-3 px-4 font-mono text-indigo-400\">\n <a attr-href=\"'/runs/' + job.id\" class=\"hover:underline\">#{{ job.id }}</a>\n </td>\n <td class=\"py-3 px-4 font-medium text-white\">{{ job.workflowId }}</td>\n <td class=\"py-3 px-4\">\n <span\n class=\"inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-semibold\"\n bind-class=\"{\n 'bg-emerald-500/10.text-emerald-400': job.status === 'success',\n 'bg-rose-500/10.text-rose-400': job.status === 'failed',\n 'bg-indigo-500/10.text-indigo-400.animate-pulse': job.status === 'running' || job.status === 'pending',\n 'bg-gray-500/10.text-gray-400': !['success', 'failed', 'running'].includes(job.status)\n }\"\n >\n <lucide-icon\n class=\"shrink-0\"\n bind-class=\"{\n 'text-emerald-400': job.status === 'success',\n 'text-rose-400': job.status === 'failed',\n 'text-indigo-400.animate-spin': job.status === 'running' || job.status === 'pending',\n 'text-gray-400': !['success', 'failed', 'running'].includes(job.status)\n }\"\n bind-icon=\"\n job.status === 'success'\n ? 'circle-check'\n : job.status === 'failed'\n ? 'circle-x'\n : job.status === 'running'\n ? 'loader-circle'\n : 'circle'\n \"\n size=\"14\"\n ></lucide-icon>\n {{ upper(job.status) }}\n </span>\n </td>\n <td class=\"py-3 px-4 hidden xl:table-cell text-xs font-mono text-gray-400\">\n {{ job.workerId || '-' }}\n </td>\n <td class=\"py-3 px-4 hidden lg:table-cell text-xs text-gray-400\">{{ job.createdAt }}</td>\n <td class=\"py-3 px-4 text-right whitespace-nowrap\">\n <a\n attr-href=\"'/runs/' + job.id\"\n class=\"text-xs bg-gray-800 hover:bg-gray-700 text-gray-200 px-3 py-1 rounded border border-gray-700\"\n >View Trace</a\n >\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n <template if=\"!jobs.length\">\n <div class=\"p-8 text-center text-gray-500\">\n {{ activeFilter ? 'No jobs match the current filter.' : 'No jobs recorded yet.' }}\n </div>\n </template>\n </section>\n\n <section\n class=\"md:hidden bg-gray-900 border border-gray-800 rounded-xl divide-y divide-gray-800 overflow-hidden\"\n >\n <template for=\"job of jobs\">\n <a\n attr-href=\"'/runs/' + job.id\"\n class=\"block p-4 bg-gray-900/60 hover:bg-gray-800/40 focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-indigo-400\"\n >\n <div class=\"flex items-start justify-between gap-3\">\n <div class=\"min-w-0\">\n <div class=\"flex items-center gap-2\">\n <lucide-icon\n class=\"flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-gray-700/70\"\n bind-class=\"{\n 'text-emerald-400': job.status === 'success',\n 'text-rose-400': job.status === 'failed',\n 'text-indigo-400.animate-spin': job.status === 'running' || job.status === 'pending',\n 'text-gray-400': !['success', 'failed', 'running'].includes(job.status)\n }\"\n bind-icon=\"\n job.status === 'success'\n ? 'circle-check'\n : job.status === 'failed'\n ? 'circle-x'\n : job.status === 'running'\n ? 'loader-circle'\n : 'circle'\n \"\n size=\"15\"\n ></lucide-icon>\n <h2 class=\"font-medium text-white truncate\">{{ job.workflowId }}</h2>\n </div>\n <p class=\"mt-1 pl-[36px] text-xs font-mono text-gray-400\">#{{ job.id }} · {{ upper(job.status) }}</p>\n </div>\n </div>\n </a>\n </template>\n <template if=\"!jobs.length\">\n <div class=\"p-8 text-center text-gray-500\">\n {{ activeFilter ? 'No jobs match the current filter.' : 'No jobs recorded yet.' }}\n </div>\n </template>\n </section>\n\n <template if=\"hasMore\">\n <div class=\"flex justify-center\">\n <button\n class=\"px-4 py-2 text-sm text-gray-200 bg-gray-800 hover:bg-gray-700 border border-gray-700 rounded-lg\"\n on-click=\"loadMore()\"\n >\n {{ loadingMore ? 'Loading...' : 'Load more' }}\n </button>\n </div>\n </template>\n </main>\n\n <script setup>\n import { onDestroy, onInit, ref } from '@li3/web';\n\n export default function setup() {\n const jobs = ref([]);\n const refreshError = ref(false);\n const hasMore = ref(false);\n const loadingMore = ref(false);\n const filter = ref('');\n const activeFilter = ref('');\n const pushConfigured = ref(false);\n const notificationsSupported = ref('Notification' in window && 'serviceWorker' in navigator);\n const notificationsEnabled = ref(\n notificationsSupported.value &&\n Notification.permission === 'granted' &&\n localStorage.getItem('runner-notifications') === 'enabled',\n );\n const notificationNotice = ref('');\n let refreshTimer;\n let eventSource;\n let refreshing = false;\n let refreshPending = false;\n let searchInProgress = false;\n let refreshGeneration = 0;\n\n const upper = (value) => String(value || '').toUpperCase();\n const terminalStatuses = new Set(['success', 'failed', 'cancelled']);\n const notifyCompletedJob = async (job) => {\n if (!notificationsEnabled.value || pushConfigured.value || !['success', 'failed'].includes(job.status))\n return;\n try {\n const registration = await navigator.serviceWorker.ready;\n await registration.showNotification(\n job.status === 'success' ? `Job #${job.id} succeeded` : `Job #${job.id} failed`,\n {\n body: `${job.workflowId} finished with status ${job.status}.`,\n icon: '/app-icon.svg',\n badge: '/app-icon.svg',\n tag: `runner-job-${job.id}`,\n renotify: true,\n data: { url: `/runs/${job.id}` },\n },\n );\n } catch (error) {\n console.error('Unable to show job notification', error);\n }\n };\n const toggleNotifications = async () => {\n if (notificationsEnabled.value) {\n notificationsEnabled.value = false;\n localStorage.removeItem('runner-notifications');\n await disablePushNotifications();\n notificationNotice.value = 'Job notifications are paused on this device.';\n return;\n }\n if (Notification.permission === 'denied') {\n notificationNotice.value =\n 'Notifications are blocked. Allow them in this site’s Android browser settings.';\n return;\n }\n const permission = await Notification.requestPermission();\n notificationsEnabled.value = permission === 'granted';\n if (notificationsEnabled.value) {\n localStorage.setItem('runner-notifications', 'enabled');\n await enablePushNotifications();\n notificationNotice.value =\n 'Notifications enabled. Background delivery is available when server push is configured.';\n } else {\n notificationNotice.value = 'Notification permission was not granted.';\n }\n };\n const urlBase64ToUint8Array = (value) => {\n const padding = '='.repeat((4 - (value.length % 4)) % 4);\n const raw = atob((value + padding).replace(/-/g, '+').replace(/_/g, '/'));\n return Uint8Array.from([...raw].map((character) => character.charCodeAt(0)));\n };\n const enablePushNotifications = async () => {\n try {\n if (!notificationsSupported.value) return;\n const response = await fetch('/api/push/public-key', { headers: { accept: 'application/json' } });\n if (!response.ok) return;\n const { publicKey } = await response.json();\n pushConfigured.value = true;\n const registration = await navigator.serviceWorker.ready;\n const subscription =\n (await registration.pushManager.getSubscription()) ||\n (await registration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: urlBase64ToUint8Array(publicKey),\n }));\n const saveResponse = await fetch('/api/push/subscriptions', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(subscription),\n });\n if (!saveResponse.ok) throw new Error(`Push subscription failed: ${saveResponse.status}`);\n } catch (error) {\n console.error('Unable to enable background notifications', error);\n }\n };\n const disablePushNotifications = async () => {\n try {\n const registration = await navigator.serviceWorker.ready;\n const subscription = await registration.pushManager.getSubscription();\n if (!subscription) return;\n await fetch('/api/push/subscriptions', {\n method: 'DELETE',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ endpoint: subscription.endpoint }),\n });\n await subscription.unsubscribe();\n } catch (error) {\n console.error('Unable to disable background notifications', error);\n }\n };\n const refreshJobs = async (isSearch = false) => {\n if (searchInProgress && !isSearch) return;\n if (refreshing && !isSearch) {\n refreshPending = true;\n return;\n }\n refreshing = true;\n const generation = refreshGeneration;\n\n try {\n const activeIds = jobs.value\n .filter((job) => !terminalStatuses.has(job.status))\n .map((job) => Number(job.id));\n const knownIds = jobs.value.map((job) => Number(job.id));\n const afterId = activeIds.length\n ? Math.max(0, Math.min(...activeIds) - 1)\n : knownIds.length\n ? Math.max(...knownIds)\n : null;\n const filterQuery = activeFilter.value ? `&filter=${encodeURIComponent(activeFilter.value)}` : '';\n const url =\n afterId === null\n ? `/api/jobs?limit=100${filterQuery}`\n : `/api/jobs?afterId=${afterId}&limit=100${filterQuery}`;\n const response = await fetch(url, { headers: { accept: 'application/json' } });\n if (!response.ok) throw new Error(`Dashboard refresh failed: ${response.status}`);\n\n const data = await response.json();\n if (generation !== refreshGeneration) return;\n hasMore.value = data.hasMore;\n const previousStatuses = new Map(jobs.value.map((job) => [job.id, job.status]));\n const merged = new Map(jobs.value.map((job) => [job.id, job]));\n for (const job of data.jobs) {\n const previousStatus = previousStatuses.get(job.id);\n merged.set(job.id, job);\n if (previousStatus && !terminalStatuses.has(previousStatus) && terminalStatuses.has(job.status)) {\n void notifyCompletedJob(job);\n }\n }\n jobs.value = Array.from(merged.values()).sort((a, b) => Number(b.id) - Number(a.id));\n refreshError.value = false;\n } catch (error) {\n console.error(error);\n refreshError.value = true;\n } finally {\n refreshing = false;\n if (refreshPending && !searchInProgress) {\n refreshPending = false;\n void refreshJobs();\n }\n }\n };\n\n const loadMore = async () => {\n if (loadingMore.value || !hasMore.value || !jobs.value.length) return;\n loadingMore.value = true;\n\n try {\n const beforeId = Math.min(...jobs.value.map((job) => Number(job.id)));\n const filterQuery = activeFilter.value ? `&filter=${encodeURIComponent(activeFilter.value)}` : '';\n const response = await fetch(`/api/jobs?beforeId=${beforeId}${filterQuery}`, {\n headers: { accept: 'application/json' },\n });\n if (!response.ok) throw new Error(`Loading older jobs failed: ${response.status}`);\n\n const data = await response.json();\n const merged = new Map(jobs.value.map((job) => [job.id, job]));\n for (const job of data.jobs) merged.set(job.id, job);\n jobs.value = Array.from(merged.values()).sort((a, b) => Number(b.id) - Number(a.id));\n hasMore.value = data.hasMore;\n } catch (error) {\n console.error(error);\n refreshError.value = true;\n } finally {\n loadingMore.value = false;\n }\n };\n const applyFilter = async () => {\n searchInProgress = true;\n refreshGeneration++;\n activeFilter.value = filter.value.trim();\n updateSearchUrl(activeFilter.value);\n jobs.value = [];\n hasMore.value = false;\n try {\n await refreshJobs(true);\n } finally {\n searchInProgress = false;\n refreshPending = false;\n }\n };\n const setFilter = (event) => {\n filter.value = event.target.value;\n };\n const updateSearchUrl = (value) => {\n const params = new URLSearchParams(window.location.search);\n if (value) params.set('search', value);\n else params.delete('search');\n const query = params.toString();\n history.pushState(null, '', `${window.location.pathname}${query ? `?${query}` : ''}`);\n };\n const clearFilter = async () => {\n searchInProgress = true;\n refreshGeneration++;\n filter.value = '';\n activeFilter.value = '';\n updateSearchUrl('');\n jobs.value = [];\n hasMore.value = false;\n try {\n await refreshJobs(true);\n } finally {\n searchInProgress = false;\n refreshPending = false;\n }\n };\n\n onInit(() => {\n const initialSearch = new URLSearchParams(window.location.search).get('search')?.trim() || '';\n filter.value = initialSearch;\n activeFilter.value = initialSearch;\n if (notificationsSupported.value) {\n navigator.serviceWorker\n .register('/service-worker.js')\n .then(() => {\n if (notificationsEnabled.value) void enablePushNotifications();\n })\n .catch((error) => {\n console.error('Service worker registration failed', error);\n });\n }\n eventSource = new EventSource('/api/events');\n eventSource.addEventListener('jobs.available', refreshJobs);\n eventSource.addEventListener('jobs.changed', refreshJobs);\n eventSource.onerror = () => {\n refreshError.value = true;\n };\n void refreshJobs();\n refreshTimer = setInterval(refreshJobs, 60000);\n });\n onDestroy(() => {\n eventSource?.close();\n clearInterval(refreshTimer);\n });\n\n return {\n jobs,\n refreshError,\n hasMore,\n loadingMore,\n filter,\n activeFilter,\n pushConfigured,\n setFilter,\n loadMore,\n applyFilter,\n clearFilter,\n upper,\n notificationsSupported,\n notificationsEnabled,\n notificationNotice,\n toggleNotifications,\n };\n }\n <\/script>\n </template>\n\n <script type=\"module\">\n import '@li3/web';\n <\/script>\n <script src=\"https://cdn.tailwindcss.com\"><\/script>\n </body>\n</html>\n";
343
+ }, he = "<!doctype html>\n<html lang=\"en\" class=\"dark\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <meta name=\"theme-color\" content=\"#030712\" />\n <meta name=\"mobile-web-app-capable\" content=\"yes\" />\n <link rel=\"manifest\" href=\"/manifest.webmanifest\" />\n <link rel=\"icon\" href=\"/app-icon.svg\" type=\"image/svg+xml\" />\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/lucide-icon.html\" />\n <link rel=\"component\" href=\"/app-header.html\" />\n <title>Workflow Engine Dashboard</title>\n <script type=\"importmap\">\n { \"imports\": { \"@li3/\": \"https://cdn.li3.dev/@li3/\" } }\n <\/script>\n </head>\n <body class=\"bg-gray-950 text-gray-100 min-h-screen p-4 md:p-6 font-sans\">\n <template app>\n <main class=\"max-w-6xl mx-auto space-y-6 py-6\">\n <app-header title=\"Runner Engine Status\" subtitle=\"Live Job Queue &amp; Execution Traces\"></app-header>\n <div class=\"flex justify-end gap-2 text-xs font-mono\">\n <template if=\"refreshError\">\n <span class=\"rounded border border-rose-500/20 bg-rose-500/10 px-3 py-1 text-rose-400\"\n >Refresh failed</span\n >\n </template>\n </div>\n\n <form class=\"flex items-center gap-2\" on-submit.prevent=\"applyFilter()\">\n <div class=\"relative min-w-0 flex-1\">\n <label class=\"sr-only\" for=\"job-filter\">Filter jobs</label>\n <input\n id=\"job-filter\"\n bind-value=\"filter\"\n on-input=\"setFilter($event)\"\n class=\"w-full rounded-lg border border-gray-800 bg-gray-900 px-3 py-2 pr-10 text-sm text-gray-200 outline-none placeholder:text-gray-600 focus:border-indigo-500\"\n placeholder=\"Filter: name:cloud-cli/* or text search\"\n />\n <template if=\"filter\">\n <button\n type=\"button\"\n on-click=\"clearFilter()\"\n class=\"absolute right-1 top-1/2 -translate-y-1/2 rounded-md p-1 text-gray-500 hover:bg-gray-800 hover:text-gray-200\"\n >\n <lucide-icon icon=\"x\" size=\"15\"></lucide-icon>\n <span class=\"sr-only\">Clear job filter</span>\n </button>\n </template>\n </div>\n <button\n type=\"submit\"\n aria-label=\"Search jobs\"\n class=\"inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-lg border border-indigo-500/40 bg-indigo-500/10 text-indigo-200 hover:bg-indigo-500/20\"\n >\n <lucide-icon icon=\"search\" size=\"16\"></lucide-icon>\n </button>\n </form>\n\n <template if=\"activeFilter\">\n <p class=\"flex items-center gap-1\">\n <span class=\"text-xs text-gray-400\">Showing {{ jobs.length }} jobs matching </span\n ><span class=\"font-mono text-indigo-300\">{{ activeFilter }}</span>\n </p>\n </template>\n\n <template if=\"notificationNotice\">\n <button\n class=\"w-full rounded-lg border border-gray-700 bg-gray-900 px-4 py-3 text-left text-sm text-gray-300\"\n on-click=\"notificationNotice = ''\"\n >\n {{ notificationNotice }}\n </button>\n </template>\n\n <section class=\"bg-gray-900 border border-gray-800 rounded-xl overflow-hidden hidden md:block\">\n <table class=\"w-full text-left text-sm\">\n <thead class=\"bg-gray-800/50 text-gray-400 text-xs uppercase font-mono border-b border-gray-800\">\n <tr>\n <th class=\"py-3 px-4\">Job ID</th>\n <th class=\"py-3 px-4\">Workflow</th>\n <th class=\"py-3 px-4\">Status</th>\n <th class=\"py-3 px-4 hidden xl:table-cell\">Worker</th>\n <th class=\"py-3 px-4 hidden lg:table-cell\">Created At</th>\n <th class=\"py-3 px-4 text-right\">Action</th>\n </tr>\n </thead>\n <tbody>\n <template for=\"job of jobs\">\n <tr class=\"border-b border-gray-800 hover:bg-gray-800/40 transition\">\n <td class=\"py-3 px-4 font-mono text-indigo-400\">\n <a attr-href=\"'/runs/' + job.id\" class=\"hover:underline\">#{{ job.id }}</a>\n </td>\n <td class=\"py-3 px-4 font-medium text-white\">{{ job.workflowId }}</td>\n <td class=\"py-3 px-4\">\n <span\n class=\"inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-semibold\"\n bind-class=\"{\n 'bg-emerald-500/10.text-emerald-400': job.status === 'success',\n 'bg-rose-500/10.text-rose-400': job.status === 'failed',\n 'bg-indigo-500/10.text-indigo-400.animate-pulse': job.status === 'running' || job.status === 'pending',\n 'bg-gray-500/10.text-gray-400': !['success', 'failed', 'running'].includes(job.status)\n }\"\n >\n <lucide-icon\n class=\"shrink-0\"\n bind-class=\"{\n 'text-emerald-400': job.status === 'success',\n 'text-rose-400': job.status === 'failed',\n 'text-indigo-400.animate-spin': job.status === 'running' || job.status === 'pending',\n 'text-gray-400': !['success', 'failed', 'running'].includes(job.status)\n }\"\n bind-icon=\"\n job.status === 'success'\n ? 'circle-check'\n : job.status === 'failed'\n ? 'circle-x'\n : job.status === 'running'\n ? 'loader-circle'\n : 'circle'\n \"\n size=\"14\"\n ></lucide-icon>\n {{ upper(job.status) }}\n </span>\n </td>\n <td class=\"py-3 px-4 hidden xl:table-cell text-xs font-mono text-gray-400\">\n {{ job.workerId || '-' }}\n </td>\n <td class=\"py-3 px-4 hidden lg:table-cell text-xs text-gray-400\">{{ job.createdAt }}</td>\n <td class=\"py-3 px-4 text-right whitespace-nowrap\">\n <a\n attr-href=\"'/runs/' + job.id\"\n class=\"text-xs bg-gray-800 hover:bg-gray-700 text-gray-200 px-3 py-1 rounded border border-gray-700\"\n >View Trace</a\n >\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n <template if=\"!jobs.length\">\n <div class=\"p-8 text-center text-gray-500\">\n {{ activeFilter ? 'No jobs match the current filter.' : 'No jobs recorded yet.' }}\n </div>\n </template>\n </section>\n\n <section\n class=\"md:hidden bg-gray-900 border border-gray-800 rounded-xl divide-y divide-gray-800 overflow-hidden\"\n >\n <template for=\"job of jobs\">\n <a\n attr-href=\"'/runs/' + job.id\"\n class=\"block p-4 bg-gray-900/60 hover:bg-gray-800/40 focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-indigo-400\"\n >\n <div class=\"flex items-start justify-between gap-3\">\n <div class=\"min-w-0\">\n <div class=\"flex items-center gap-2\">\n <lucide-icon\n class=\"flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-gray-700/70\"\n bind-class=\"{\n 'text-emerald-400': job.status === 'success',\n 'text-rose-400': job.status === 'failed',\n 'text-indigo-400.animate-spin': job.status === 'running' || job.status === 'pending',\n 'text-gray-400': !['success', 'failed', 'running'].includes(job.status)\n }\"\n bind-icon=\"\n job.status === 'success'\n ? 'circle-check'\n : job.status === 'failed'\n ? 'circle-x'\n : job.status === 'running'\n ? 'loader-circle'\n : 'circle'\n \"\n size=\"15\"\n ></lucide-icon>\n <h2 class=\"font-medium text-white truncate\">{{ job.workflowId }}</h2>\n </div>\n <p class=\"mt-1 pl-[36px] text-xs font-mono text-gray-400\">#{{ job.id }} · {{ upper(job.status) }}</p>\n </div>\n </div>\n </a>\n </template>\n <template if=\"!jobs.length\">\n <div class=\"p-8 text-center text-gray-500\">\n {{ activeFilter ? 'No jobs match the current filter.' : 'No jobs recorded yet.' }}\n </div>\n </template>\n </section>\n\n <template if=\"hasMore\">\n <div class=\"flex justify-center\">\n <button\n class=\"px-4 py-2 text-sm text-gray-200 bg-gray-800 hover:bg-gray-700 border border-gray-700 rounded-lg\"\n on-click=\"loadMore()\"\n >\n {{ loadingMore ? 'Loading...' : 'Load more' }}\n </button>\n </div>\n </template>\n </main>\n\n <script setup>\n import { onDestroy, onInit, ref } from '@li3/web';\n\n export default function setup() {\n const jobs = ref([]);\n const refreshError = ref(false);\n const hasMore = ref(false);\n const loadingMore = ref(false);\n const filter = ref('');\n const activeFilter = ref('');\n const pushConfigured = ref(false);\n const notificationsSupported = ref('Notification' in window && 'serviceWorker' in navigator);\n const notificationsEnabled = ref(\n notificationsSupported.value &&\n Notification.permission === 'granted' &&\n localStorage.getItem('runner-notifications') === 'enabled',\n );\n const notificationNotice = ref('');\n let refreshTimer;\n let eventSource;\n let refreshing = false;\n let refreshPending = false;\n let searchInProgress = false;\n let refreshGeneration = 0;\n\n const upper = (value) => String(value || '').toUpperCase();\n const terminalStatuses = new Set(['success', 'failed', 'cancelled']);\n const notifyCompletedJob = async (job) => {\n if (!notificationsEnabled.value || pushConfigured.value || !['success', 'failed'].includes(job.status))\n return;\n try {\n const registration = await navigator.serviceWorker.ready;\n await registration.showNotification(\n job.status === 'success' ? `Job #${job.id} succeeded` : `Job #${job.id} failed`,\n {\n body: `${job.workflowId} finished with status ${job.status}.`,\n icon: '/app-icon.svg',\n badge: '/app-icon.svg',\n tag: `runner-job-${job.id}`,\n renotify: true,\n data: { url: `/runs/${job.id}` },\n },\n );\n } catch (error) {\n console.error('Unable to show job notification', error);\n }\n };\n const toggleNotifications = async () => {\n if (notificationsEnabled.value) {\n notificationsEnabled.value = false;\n localStorage.removeItem('runner-notifications');\n await disablePushNotifications();\n notificationNotice.value = 'Job notifications are paused on this device.';\n return;\n }\n if (Notification.permission === 'denied') {\n notificationNotice.value =\n 'Notifications are blocked. Allow them in this site’s Android browser settings.';\n return;\n }\n const permission = await Notification.requestPermission();\n notificationsEnabled.value = permission === 'granted';\n if (notificationsEnabled.value) {\n localStorage.setItem('runner-notifications', 'enabled');\n await enablePushNotifications();\n notificationNotice.value =\n 'Notifications enabled. Background delivery is available when server push is configured.';\n } else {\n notificationNotice.value = 'Notification permission was not granted.';\n }\n };\n const urlBase64ToUint8Array = (value) => {\n const padding = '='.repeat((4 - (value.length % 4)) % 4);\n const raw = atob((value + padding).replace(/-/g, '+').replace(/_/g, '/'));\n return Uint8Array.from([...raw].map((character) => character.charCodeAt(0)));\n };\n const enablePushNotifications = async () => {\n try {\n if (!notificationsSupported.value) return;\n const response = await fetch('/api/push/public-key', { headers: { accept: 'application/json' } });\n if (!response.ok) return;\n const { publicKey } = await response.json();\n pushConfigured.value = true;\n const registration = await navigator.serviceWorker.ready;\n const subscription =\n (await registration.pushManager.getSubscription()) ||\n (await registration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: urlBase64ToUint8Array(publicKey),\n }));\n const saveResponse = await fetch('/api/push/subscriptions', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(subscription),\n });\n if (!saveResponse.ok) throw new Error(`Push subscription failed: ${saveResponse.status}`);\n } catch (error) {\n console.error('Unable to enable background notifications', error);\n }\n };\n const disablePushNotifications = async () => {\n try {\n const registration = await navigator.serviceWorker.ready;\n const subscription = await registration.pushManager.getSubscription();\n if (!subscription) return;\n await fetch('/api/push/subscriptions', {\n method: 'DELETE',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ endpoint: subscription.endpoint }),\n });\n await subscription.unsubscribe();\n } catch (error) {\n console.error('Unable to disable background notifications', error);\n }\n };\n const refreshJobs = async (isSearch = false) => {\n if (searchInProgress && !isSearch) return;\n if (refreshing && !isSearch) {\n refreshPending = true;\n return;\n }\n refreshing = true;\n const generation = refreshGeneration;\n\n try {\n const activeIds = jobs.value\n .filter((job) => !terminalStatuses.has(job.status))\n .map((job) => Number(job.id));\n const knownIds = jobs.value.map((job) => Number(job.id));\n const afterId = activeIds.length\n ? Math.max(0, Math.min(...activeIds) - 1)\n : knownIds.length\n ? Math.max(...knownIds)\n : null;\n const filterQuery = activeFilter.value ? `&filter=${encodeURIComponent(activeFilter.value)}` : '';\n const url =\n afterId === null\n ? `/api/jobs?limit=100${filterQuery}`\n : `/api/jobs?afterId=${afterId}&limit=100${filterQuery}`;\n const response = await fetch(url, { headers: { accept: 'application/json' } });\n if (!response.ok) throw new Error(`Dashboard refresh failed: ${response.status}`);\n\n const data = await response.json();\n if (generation !== refreshGeneration) return;\n hasMore.value = data.hasMore;\n const previousStatuses = new Map(jobs.value.map((job) => [job.id, job.status]));\n const merged = new Map(jobs.value.map((job) => [job.id, job]));\n for (const job of data.jobs) {\n const previousStatus = previousStatuses.get(job.id);\n merged.set(job.id, job);\n if (previousStatus && !terminalStatuses.has(previousStatus) && terminalStatuses.has(job.status)) {\n void notifyCompletedJob(job);\n }\n }\n jobs.value = Array.from(merged.values()).sort((a, b) => Number(b.id) - Number(a.id));\n refreshError.value = false;\n } catch (error) {\n console.error(error);\n refreshError.value = true;\n } finally {\n refreshing = false;\n if (refreshPending && !searchInProgress) {\n refreshPending = false;\n void refreshJobs();\n }\n }\n };\n\n const loadMore = async () => {\n if (loadingMore.value || !hasMore.value || !jobs.value.length) return;\n loadingMore.value = true;\n\n try {\n const beforeId = Math.min(...jobs.value.map((job) => Number(job.id)));\n const filterQuery = activeFilter.value ? `&filter=${encodeURIComponent(activeFilter.value)}` : '';\n const response = await fetch(`/api/jobs?beforeId=${beforeId}${filterQuery}`, {\n headers: { accept: 'application/json' },\n });\n if (!response.ok) throw new Error(`Loading older jobs failed: ${response.status}`);\n\n const data = await response.json();\n const merged = new Map(jobs.value.map((job) => [job.id, job]));\n for (const job of data.jobs) merged.set(job.id, job);\n jobs.value = Array.from(merged.values()).sort((a, b) => Number(b.id) - Number(a.id));\n hasMore.value = data.hasMore;\n } catch (error) {\n console.error(error);\n refreshError.value = true;\n } finally {\n loadingMore.value = false;\n }\n };\n const applyFilter = async () => {\n searchInProgress = true;\n refreshGeneration++;\n activeFilter.value = filter.value.trim();\n updateSearchUrl(activeFilter.value);\n jobs.value = [];\n hasMore.value = false;\n try {\n await refreshJobs(true);\n } finally {\n searchInProgress = false;\n refreshPending = false;\n }\n };\n const setFilter = (event) => {\n filter.value = event.target.value;\n };\n const updateSearchUrl = (value) => {\n const params = new URLSearchParams(window.location.search);\n if (value) params.set('search', value);\n else params.delete('search');\n const query = params.toString();\n history.pushState(null, '', `${window.location.pathname}${query ? `?${query}` : ''}`);\n };\n const clearFilter = async () => {\n searchInProgress = true;\n refreshGeneration++;\n filter.value = '';\n activeFilter.value = '';\n updateSearchUrl('');\n jobs.value = [];\n hasMore.value = false;\n try {\n await refreshJobs(true);\n } finally {\n searchInProgress = false;\n refreshPending = false;\n }\n };\n\n onInit(() => {\n const initialSearch = new URLSearchParams(window.location.search).get('search')?.trim() || '';\n filter.value = initialSearch;\n activeFilter.value = initialSearch;\n if (notificationsSupported.value) {\n navigator.serviceWorker\n .register('/service-worker.js')\n .then(() => {\n if (notificationsEnabled.value) void enablePushNotifications();\n })\n .catch((error) => {\n console.error('Service worker registration failed', error);\n });\n }\n eventSource = new EventSource('/api/events');\n eventSource.addEventListener('jobs.available', refreshJobs);\n eventSource.addEventListener('jobs.changed', refreshJobs);\n eventSource.onerror = () => {\n refreshError.value = true;\n };\n void refreshJobs();\n refreshTimer = setInterval(refreshJobs, 60000);\n });\n onDestroy(() => {\n eventSource?.close();\n clearInterval(refreshTimer);\n });\n\n return {\n jobs,\n refreshError,\n hasMore,\n loadingMore,\n filter,\n activeFilter,\n pushConfigured,\n setFilter,\n loadMore,\n applyFilter,\n clearFilter,\n upper,\n notificationsSupported,\n notificationsEnabled,\n notificationNotice,\n toggleNotifications,\n };\n }\n <\/script>\n </template>\n\n <script type=\"module\">\n import '@li3/web';\n <\/script>\n <script src=\"https://cdn.tailwindcss.com\"><\/script>\n </body>\n</html>\n";
337
344
  //#endregion
338
345
  //#region src/dashboard.ts
339
346
  function ge(e) {
@@ -491,7 +498,7 @@ var Ce = class {
491
498
  type: "image/svg+xml",
492
499
  purpose: "any maskable"
493
500
  }]
494
- }), Te = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <rect width=\"512\" height=\"512\" rx=\"112\" fill=\"#030712\"/>\n <path d=\"M128 144h256v224H128z\" fill=\"#111827\" stroke=\"#6366f1\" stroke-width=\"24\"/>\n <path d=\"m174 218 62 38-62 38M260 300h78\" fill=\"none\" stroke=\"#f9fafb\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"24\"/>\n <circle cx=\"365\" cy=\"147\" r=\"47\" fill=\"#10b981\" stroke=\"#030712\" stroke-width=\"18\"/>\n</svg>", Ee = "self.addEventListener('install', () => self.skipWaiting());\nself.addEventListener('activate', (event) => event.waitUntil(self.clients.claim()));\nself.addEventListener('push', (event) => {\n const data = event.data?.json() || {};\n event.waitUntil(self.registration.showNotification(data.title || 'Runner Engine', {\n body: data.body || 'A job status changed.',\n icon: '/app-icon.svg',\n badge: '/app-icon.svg',\n data: { url: data.url || '/runs' },\n }));\n});\nself.addEventListener('notificationclick', (event) => {\n event.notification.close();\n const target = event.notification.data?.url || '/runs';\n event.waitUntil((async () => {\n const windows = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });\n const existing = windows.find((client) => new URL(client.url).pathname === target);\n if (existing) return existing.focus();\n return self.clients.openWindow(target);\n })());\n});", De = "<!doctype html>\n<html lang=\"en\" class=\"dark\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <meta name=\"theme-color\" content=\"#030712\" />\n <meta name=\"mobile-web-app-capable\" content=\"yes\" />\n <link rel=\"manifest\" href=\"/manifest.webmanifest\" />\n <link rel=\"icon\" href=\"/app-icon.svg\" type=\"image/svg+xml\" />\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/lucide-icon.html\" />\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/code-block.html\" />\n <link rel=\"component\" href=\"/app-header.html\" />\n <title>Workflow Run</title>\n <script type=\"importmap\">\n {\n \"imports\": {\n \"@li3/\": \"https://cdn.li3.dev/@li3/\",\n \"ansi_up\": \"https://esm.sh/ansi_up@6.0.6\"\n }\n }\n <\/script>\n <style>\n </style>\n </head>\n <body class=\"bg-gray-950 text-gray-100 min-h-screen p-4 md:p-6 font-sans\">\n <template app>\n <div class=\"max-w-5xl mx-auto space-y-4\">\n <app-header bind-title=\"report.workflowName\" bind-subtitle=\"'Run #' + report.jobId\" back=\"/runs\" back-label=\"Back to jobs\"></app-header>\n <div class=\"flex flex-wrap items-center justify-between gap-3 border-b border-gray-800 pb-4\">\n <p class=\"text-xs text-gray-400\">\n Started {{ report.startedAt }} · {{ timing }}\n <template if=\"report.workerId\"> · worker: {{ report.workerId }}</template>\n <template if=\"report.parentId\"> · from #{{ report.parentId }}</template>\n </p>\n <div class=\"flex items-center gap-2 shrink-0\">\n <span\n class=\"px-4 py-1.5 rounded-full text-sm font-semibold border\"\n bind-class=\"{\n 'bg-emerald-500/10.text-emerald-400.border-emerald-500/20': report.status === 'success',\n 'bg-rose-500/10.text-rose-400.border-rose-500/20': report.status === 'failed',\n 'bg-indigo-500/10.text-indigo-400.border-indigo-500/20': report.status === 'running',\n 'bg-amber-500/10.text-amber-400.border-amber-500/20': !['success', 'failed', 'running'].includes(report.status)\n }\"\n >\n {{ upper(report.status) }}\n </span>\n <template if=\"report.status === 'running'\">\n <button\n class=\"text-sm text-rose-300 px-4 py-1.5 border border-rose-500/50 hover:border-rose-400 rounded-full disabled:opacity-50\"\n on-click=\"cancelJob()\"\n bind-disabled.bool=\"cancelling\"\n >\n {{ cancelling ? 'Cancelling...' : 'Cancel' }}\n </button>\n </template>\n <template if=\"report.status !== 'running'\">\n <button\n class=\"text-sm text-white px-4 py-1.5 border border-gray-600 hover:border-gray-400 rounded-full\"\n on-click=\"restartJob()\"\n >\n Restart\n </button>\n </template>\n </div>\n </div>\n <template if=\"previousRuns.length\">\n <details class=\"rounded-xl border border-gray-800 bg-gray-900/70\">\n <summary class=\"cursor-pointer px-4 py-3 text-sm font-medium text-gray-300 outline-none hover:bg-gray-800 focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n Previous runs\n </summary>\n <ul class=\"divide-y divide-gray-800 border-t border-gray-800\">\n <template for=\"run of previousRuns\">\n <li>\n <a attr-href=\"'/runs/' + run.id\" class=\"flex items-center justify-between gap-3 px-4 py-3 text-sm outline-none hover:bg-gray-800 focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n <span><span class=\"font-mono text-indigo-300\">#{{ run.id }}</span><span class=\"ml-3 text-gray-400\">{{ run.createdAt }}</span></span>\n <span class=\"font-semibold uppercase text-xs text-gray-400\">{{ upper(run.status) }}</span>\n </a>\n </li>\n </template>\n </ul>\n </details>\n </template>\n\n <section class=\"rounded overflow-hidden border-b border-gray-800\">\n <h2 class=\"sr-only\">Execution Steps</h2>\n <template for=\"step of report.steps\">\n <details class=\"border border-b-0 border-gray-800 bg-gray-900/50 text-sm\">\n <summary\n class=\"flex flex-col md:flex-row md:items-center justify-between gap-2 p-3 bg-gray-800/40 border-b border-gray-800 cursor-pointer\"\n >\n <div class=\"flex items-center gap-3 min-w-0\">\n <lucide-icon\n class=\"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-gray-700/70\"\n bind-class=\"{\n 'text-emerald-400': step.status === 'success',\n 'text-rose-400': step.status === 'failed',\n 'text-indigo-400.animate-spin': step.status === 'running',\n 'text-gray-400': !['success', 'failed', 'running'].includes(step.status)\n }\"\n bind-icon=\"\n step.status === 'success'\n ? 'circle-check'\n : step.status === 'failed'\n ? 'circle-x'\n : step.status === 'running'\n ? 'loader-circle'\n : 'circle'\n \"\n size=\"15\"\n ></lucide-icon>\n <template if=\"step.exitCode !== undefined && step.exitCode !== 0\">\n <span class=\"font-mono text-gray-500\">({{ step.exitCode }})</span>\n </template>\n <h3 class=\"font-semibold text-gray-200 truncate min-w-0 flex-1\">{{ step.name }}</h3>\n <div class=\"font-mono text-gray-400 shrink-0\">{{ step.durationMs }}ms</div>\n <span\n class=\"sr-only px-2.5 py-0.5 rounded-full font-medium\"\n bind-class=\"{\n 'text-emerald-400.bg-emerald-500/10': step.status === 'success',\n 'text-rose-400.bg-rose-500/10': step.status === 'failed',\n 'text-indigo-400.bg-indigo-500/10': step.status === 'running',\n 'text-gray-400.bg-gray-500/10': !['success', 'failed', 'running'].includes(step.status)\n }\"\n >\n {{ upper(step.status) }}\n </span>\n </div>\n </summary>\n <template if=\"report.canViewLogs\">\n <div class=\"p-4 bg-gray-950 font-mono text-gray-300 leading-relaxed overflow-auto w-full\">\n <pre class=\"whitespace-pre-wrap\" bind-innerhtml=\"stepLog(step)\"></pre>\n </div>\n </template>\n <template if=\"!report.canViewLogs\">\n <div class=\"p-4 bg-gray-950 text-sm text-gray-500\">Logs are available to authenticated users.</div>\n </template>\n </details>\n </template>\n </section>\n\n <details class=\"bg-gray-900 border border-gray-800 rounded-xl overflow-hidden\">\n <summary class=\"cursor-pointer px-4 py-3 text-xs font-semibold uppercase tracking-wider text-gray-400 outline-none transition hover:bg-gray-800 focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n Trigger Inputs\n </summary>\n <code-block\n language=\"json\"\n theme=\"atom-one-dark\"\n bind-source=\"inputsJson\"\n class=\"block max-h-[38rem] overflow-auto border-t border-gray-800 bg-gray-950 p-4\"\n ></code-block>\n </details>\n <template if=\"report.workflowSourceYaml\">\n <details class=\"bg-gray-900 border border-gray-800 rounded-xl overflow-hidden\">\n <summary class=\"cursor-pointer px-4 py-3 text-xs font-semibold uppercase tracking-wider text-gray-400 outline-none transition hover:bg-gray-800 focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n Workflow source YAML · revision {{ report.workflowRevision }}\n </summary>\n <code-block\n language=\"yaml\"\n theme=\"atom-one-dark\"\n bind-source=\"report.workflowSourceYaml\"\n class=\"block max-h-[38rem] overflow-auto border-t border-gray-800 bg-gray-950 p-4\"\n ></code-block>\n </details>\n </template>\n <template if=\"report.canViewLogs && report.artifacts.length\">\n <details class=\"bg-gray-900 border border-gray-800 rounded-xl overflow-hidden\">\n <summary class=\"cursor-pointer px-4 py-3 text-xs font-semibold uppercase tracking-wider text-gray-400 outline-none transition hover:bg-gray-800 focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n Artifacts\n </summary>\n <ul class=\"divide-y divide-gray-800 border-t border-gray-800\">\n <template for=\"artifact of report.artifacts\">\n <li class=\"px-4 py-3\">\n <a\n attr-href=\"artifactUrl(artifact)\"\n class=\"font-mono text-sm text-indigo-300 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-400/60\"\n >{{ artifact }}</a>\n </li>\n </template>\n </ul>\n </details>\n </template>\n </div>\n\n <script setup>\n import { computed, onDestroy, onInit, ref } from '@li3/web';\n import { AnsiUp } from 'ansi_up';\n\n export default function setup() {\n const jobId = window.location.pathname.split('/').filter(Boolean).pop() || '';\n const report = ref({ jobId });\n const previousRuns = ref([]);\n let previousRunsLoaded = false;\n const now = ref(Date.now());\n const ansiUp = new AnsiUp();\n ansiUp.use_classes = false;\n let eventSource;\n let refreshTimer;\n let clockTimer;\n let refreshing = false;\n let refreshPending = false;\n const cancelling = ref(false);\n\n const active = computed(() => ['pending', 'running'].includes(report.value.status));\n const inputsJson = computed(() => JSON.stringify(report.value.inputs || {}, null, 2));\n const timing = computed(() => {\n if (report.value.status === 'pending') return 'Waiting for a worker';\n if (report.value.status === 'running') {\n return `Running for ${Math.max(0, now.value - Date.parse(report.value.startedAt))}ms`;\n }\n return `Finished in ${report.value.durationMs}ms`;\n });\n\n const upper = (value) => String(value || '').toUpperCase();\n const artifactUrl = (path) => `/api/runs/${report.value.jobId}/artifacts/${encodeURIComponent(path)}`;\n const loadPreviousRuns = async () => {\n if (previousRunsLoaded || !report.value.workflowId) return;\n const response = await fetch(`/api/jobs?workflowId=${encodeURIComponent(report.value.workflowId)}&limit=50`, { headers: { accept: 'application/json' } });\n if (!response.ok) throw new Error(`Previous runs request failed: ${response.status}`);\n const data = await response.json();\n previousRuns.value = data.jobs.filter((run) => String(run.id) !== String(report.value.jobId));\n previousRunsLoaded = true;\n };\n const stepLog = (step) => {\n if (step.status === 'skipped') return '';\n if (step.status === 'running')\n return '<span class=\"text-indigo-400\">Step is running. Logs will appear after it finishes.</span>';\n if (step.status === 'pending') return '<span class=\"text-gray-500\">Waiting to run.</span>';\n if (step.logContent) return ansiUp.ansi_to_html(step.logContent);\n return '<span class=\"text-gray-500\">(No terminal log output recorded for this step)</span>';\n };\n const restartJob = async () => {\n const response = await fetch(`/restart/${report.value.jobId}`, { method: 'POST' });\n if (response.ok) {\n const { id } = await response.json();\n location.href = `/runs/${id}`;\n }\n };\n const cancelJob = async () => {\n if (cancelling.value || report.value.status !== 'running') return;\n cancelling.value = true;\n try {\n const response = await fetch(`/api/jobs/${report.value.jobId}/cancel`, { method: 'POST' });\n if (!response.ok) throw new Error(`Cancel failed: ${response.status}`);\n await refreshRun();\n } catch (error) {\n console.error(error);\n } finally {\n cancelling.value = false;\n }\n };\n const refreshRun = async () => {\n if (refreshing) {\n refreshPending = true;\n return;\n }\n refreshing = true;\n\n try {\n const response = await fetch(`/api/runs/${jobId}`, {\n headers: { accept: 'application/json' },\n });\n if (!response.ok) throw new Error(`Run refresh failed: ${response.status}`);\n const previousStatus = report.value.status;\n const nextReport = await response.json();\n report.value = nextReport;\n document.title = `Run #${nextReport.jobId} - ${nextReport.workflowName}`;\n void loadPreviousRuns();\n if (\n ['pending', 'running'].includes(previousStatus) &&\n ['success', 'failed'].includes(nextReport.status) &&\n 'Notification' in window &&\n 'serviceWorker' in navigator &&\n Notification.permission === 'granted' &&\n localStorage.getItem('runner-notifications') === 'enabled'\n ) {\n const registration = await navigator.serviceWorker.ready;\n await registration.showNotification(\n nextReport.status === 'success'\n ? `Job #${nextReport.jobId} succeeded`\n : `Job #${nextReport.jobId} failed`,\n {\n body: `${nextReport.workflowName} finished with status ${nextReport.status}.`,\n icon: '/app-icon.svg',\n badge: '/app-icon.svg',\n tag: `runner-job-${nextReport.jobId}`,\n renotify: true,\n data: { url: `/runs/${nextReport.jobId}` },\n },\n );\n }\n } catch (error) {\n console.error(error);\n } finally {\n refreshing = false;\n if (refreshPending) {\n refreshPending = false;\n void refreshRun();\n }\n }\n };\n const handleJobChange = (event) => {\n const data = JSON.parse(event.data || '{}');\n if (!data.jobId || String(data.jobId) === String(report.value.jobId)) void refreshRun();\n };\n\n onInit(() => {\n void refreshRun();\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.register('/service-worker.js').catch((error) => {\n console.error('Service worker registration failed', error);\n });\n }\n eventSource = new EventSource('/api/events');\n eventSource.addEventListener('jobs.changed', handleJobChange);\n refreshTimer = setInterval(() => {\n if (active.value) void refreshRun();\n }, 60000);\n clockTimer = setInterval(() => {\n now.value = Date.now();\n }, 1000);\n });\n onDestroy(() => {\n eventSource?.close();\n clearInterval(refreshTimer);\n clearInterval(clockTimer);\n });\n\n return { report, previousRuns, inputsJson, timing, upper, artifactUrl, stepLog, restartJob, cancelJob, cancelling };\n }\n <\/script>\n </template>\n\n <script type=\"module\">\n import '@li3/web';\n <\/script>\n <script src=\"https://cdn.tailwindcss.com\"><\/script>\n </body>\n</html>\n", Oe = /(?:^|[_-])auth(?:entication)?(?:$|[_-])|access[_-]?key|api[_-]?key|authorization|cookie|credential|passphrase|password|private[_-]?key|secret|session(?:id)?|signing[_-]?key|token/i;
501
+ }), Te = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <rect width=\"512\" height=\"512\" rx=\"112\" fill=\"#030712\"/>\n <path d=\"M128 144h256v224H128z\" fill=\"#111827\" stroke=\"#6366f1\" stroke-width=\"24\"/>\n <path d=\"m174 218 62 38-62 38M260 300h78\" fill=\"none\" stroke=\"#f9fafb\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"24\"/>\n <circle cx=\"365\" cy=\"147\" r=\"47\" fill=\"#10b981\" stroke=\"#030712\" stroke-width=\"18\"/>\n</svg>", Ee = "self.addEventListener('install', () => self.skipWaiting());\nself.addEventListener('activate', (event) => event.waitUntil(self.clients.claim()));\nself.addEventListener('push', (event) => {\n const data = event.data?.json() || {};\n event.waitUntil(self.registration.showNotification(data.title || 'Runner Engine', {\n body: data.body || 'A job status changed.',\n icon: '/app-icon.svg',\n badge: '/app-icon.svg',\n data: { url: data.url || '/runs' },\n }));\n});\nself.addEventListener('notificationclick', (event) => {\n event.notification.close();\n const target = event.notification.data?.url || '/runs';\n event.waitUntil((async () => {\n const windows = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });\n const existing = windows.find((client) => new URL(client.url).pathname === target);\n if (existing) return existing.focus();\n return self.clients.openWindow(target);\n })());\n});", De = "<!doctype html>\n<html lang=\"en\" class=\"dark\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <meta name=\"theme-color\" content=\"#030712\" />\n <meta name=\"mobile-web-app-capable\" content=\"yes\" />\n <link rel=\"manifest\" href=\"/manifest.webmanifest\" />\n <link rel=\"icon\" href=\"/app-icon.svg\" type=\"image/svg+xml\" />\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/lucide-icon.html\" />\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/code-block.html\" />\n <link rel=\"component\" href=\"/app-header.html\" />\n <title>Workflow Run</title>\n <script type=\"importmap\">\n {\n \"imports\": {\n \"@li3/\": \"https://cdn.li3.dev/@li3/\",\n \"ansi_up\": \"https://esm.sh/ansi_up@6.0.6\"\n }\n }\n <\/script>\n <style>\n </style>\n </head>\n <body class=\"bg-gray-950 text-gray-100 min-h-screen p-4 md:p-6 font-sans\">\n <template app>\n <div class=\"max-w-7xl mx-auto space-y-4 py-6 lg:pr-[22rem]\">\n <app-header bind-title=\"report.workflowName\" bind-subtitle=\"'Run #' + report.jobId\" back=\"/runs\" back-label=\"Back to jobs\"></app-header>\n <div class=\"flex flex-wrap items-center justify-between gap-3 border-b border-gray-800 pb-4\">\n <p class=\"text-xs text-gray-400\">\n Started {{ report.startedAt }} · {{ timing }}\n <template if=\"report.workerId\"> · worker: {{ report.workerId }}</template>\n <template if=\"report.parentId\"> · from #{{ report.parentId }}</template>\n </p>\n <div class=\"flex items-center gap-2 shrink-0\">\n <span\n class=\"px-4 py-1.5 rounded-full text-sm font-semibold border\"\n bind-class=\"{\n 'bg-emerald-500/10.text-emerald-400.border-emerald-500/20': report.status === 'success',\n 'bg-rose-500/10.text-rose-400.border-rose-500/20': report.status === 'failed',\n 'bg-indigo-500/10.text-indigo-400.border-indigo-500/20': report.status === 'running',\n 'bg-amber-500/10.text-amber-400.border-amber-500/20': !['success', 'failed', 'running'].includes(report.status)\n }\"\n >\n {{ upper(report.status) }}\n </span>\n <template if=\"report.status === 'running'\">\n <button\n class=\"text-sm text-rose-300 px-4 py-1.5 border border-rose-500/50 hover:border-rose-400 rounded-full disabled:opacity-50\"\n on-click=\"cancelJob()\"\n bind-disabled.bool=\"cancelling\"\n >\n {{ cancelling ? 'Cancelling...' : 'Cancel' }}\n </button>\n </template>\n <template if=\"report.status !== 'running'\">\n <button\n class=\"text-sm text-white px-4 py-1.5 border border-gray-600 hover:border-gray-400 rounded-full\"\n on-click=\"restartJob()\"\n >\n Restart\n </button>\n </template>\n </div>\n </div>\n <template if=\"previousRuns.length\">\n <details class=\"rounded-xl border border-gray-800 bg-gray-900/70\">\n <summary class=\"cursor-pointer px-4 py-3 text-sm font-medium text-gray-300 outline-none hover:bg-gray-800 focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n Previous runs\n </summary>\n <ul class=\"divide-y divide-gray-800 border-t border-gray-800\">\n <template for=\"run of previousRuns\">\n <li>\n <a attr-href=\"'/runs/' + run.id\" class=\"flex items-center justify-between gap-3 px-4 py-3 text-sm outline-none hover:bg-gray-800 focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n <span><span class=\"font-mono text-indigo-300\">#{{ run.id }}</span><span class=\"ml-3 text-gray-400\">{{ run.startedAt }}</span></span>\n <span class=\"font-semibold uppercase text-xs text-gray-400\">{{ upper(run.status) }}</span>\n </a>\n </li>\n </template>\n </ul>\n </details>\n </template>\n\n <section class=\"rounded overflow-hidden border-b border-gray-800\">\n <h2 class=\"sr-only\">Execution Steps</h2>\n <template for=\"[step, index] of report.steps\">\n <details class=\"border border-b-0 border-gray-800 bg-gray-900/50 text-sm\">\n <summary\n class=\"flex flex-col md:flex-row md:items-center justify-between gap-2 p-3 bg-gray-800/40 border-b border-gray-800 cursor-pointer\"\n >\n <div class=\"flex items-center gap-3 min-w-0\">\n <lucide-icon\n class=\"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-gray-700/70\"\n bind-class=\"{\n 'text-emerald-400': step.status === 'success',\n 'text-rose-400': step.status === 'failed',\n 'text-indigo-400.animate-spin': step.status === 'running',\n 'text-gray-400': !['success', 'failed', 'running'].includes(step.status)\n }\"\n bind-icon=\"\n step.status === 'success'\n ? 'circle-check'\n : step.status === 'failed'\n ? 'circle-x'\n : step.status === 'running'\n ? 'loader-circle'\n : 'circle'\n \"\n size=\"15\"\n ></lucide-icon>\n <template if=\"step.exitCode !== undefined && step.exitCode !== 0\">\n <span class=\"font-mono text-gray-500\">({{ step.exitCode }})</span>\n </template>\n <h3 class=\"font-semibold text-gray-200 truncate min-w-0 flex-1\">{{ step.name }}</h3>\n <div class=\"font-mono text-gray-400 shrink-0\">{{ step.durationMs }}ms</div>\n <span\n class=\"sr-only px-2.5 py-0.5 rounded-full font-medium\"\n bind-class=\"{\n 'text-emerald-400.bg-emerald-500/10': step.status === 'success',\n 'text-rose-400.bg-rose-500/10': step.status === 'failed',\n 'text-indigo-400.bg-indigo-500/10': step.status === 'running',\n 'text-gray-400.bg-gray-500/10': !['success', 'failed', 'running'].includes(step.status)\n }\"\n >\n {{ upper(step.status) }}\n </span>\n </div>\n </summary>\n <template if=\"report.canViewLogs\">\n <div class=\"relative p-4 bg-gray-950 font-mono text-gray-300 leading-relaxed overflow-auto w-full\">\n <template if=\"step.status === 'failed'\">\n <button type=\"button\" on-click=\"askAi(step, $event)\" aria-label=\"Get AI help for failed step\" title=\"Get AI help\" class=\"absolute right-3 top-3 z-10 inline-flex h-7 w-7 items-center justify-center rounded-lg bg-gray-900 text-indigo-300 outline-none hover:bg-indigo-500/10 focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n <lucide-icon bind-icon=\"aiLoading && aiStepId === step.id ? 'loader-circle' : 'sparkles'\" bind-class=\"aiLoading && aiStepId === step.id ? 'animate-spin' : ''\" size=\"16\"></lucide-icon>\n </button>\n </template>\n <pre class=\"whitespace-pre-wrap\" bind-innerhtml=\"stepLog(step)\"></pre>\n </div>\n </template>\n <template if=\"!report.canViewLogs\">\n <div class=\"p-4 bg-gray-950 text-sm text-gray-500\">Logs are available to authenticated users.</div>\n </template>\n </details>\n </template>\n </section>\n\n <details class=\"bg-gray-900 border border-gray-800 rounded-xl overflow-hidden\">\n <summary class=\"cursor-pointer px-4 py-3 text-xs font-semibold uppercase tracking-wider text-gray-400 outline-none transition hover:bg-gray-800 focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n Trigger Inputs\n </summary>\n <code-block\n language=\"json\"\n theme=\"atom-one-dark\"\n bind-source=\"inputsJson\"\n class=\"block max-h-[38rem] overflow-auto border-t border-gray-800 bg-gray-950 p-4\"\n ></code-block>\n </details>\n <template if=\"report.workflowSourceYaml\">\n <details class=\"bg-gray-900 border border-gray-800 rounded-xl overflow-hidden\">\n <summary class=\"cursor-pointer px-4 py-3 text-xs font-semibold uppercase tracking-wider text-gray-400 outline-none transition hover:bg-gray-800 focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n Workflow source YAML · revision {{ report.workflowRevision }}\n </summary>\n <code-block\n language=\"yaml\"\n theme=\"atom-one-dark\"\n bind-source=\"report.workflowSourceYaml\"\n class=\"block max-h-[38rem] overflow-auto border-t border-gray-800 bg-gray-950 p-4\"\n ></code-block>\n </details>\n </template>\n <template if=\"report.canViewLogs && aiStepId\">\n <aside class=\"mt-4 rounded-2xl border border-indigo-500/20 bg-gray-900/95 p-4 lg:fixed lg:right-6 lg:top-24 lg:mt-0 lg:flex lg:max-h-[calc(100vh-7rem)] lg:w-[20rem] lg:flex-col\" aria-labelledby=\"ai-help-title\">\n <div class=\"flex items-start justify-between gap-3 border-b border-gray-800 pb-3\">\n <div><h2 id=\"ai-help-title\" class=\"font-semibold text-white\">AI help</h2><p class=\"mt-1 text-xs text-gray-500\">Ask about a failed step.</p></div>\n <lucide-icon icon=\"sparkles\" size=\"18\" class=\"text-indigo-300\"></lucide-icon>\n </div>\n <div class=\"min-h-0 flex-1 space-y-3 overflow-y-auto py-3\" aria-live=\"polite\">\n <p class=\"text-sm text-gray-500\" class-hidden=\"aiMessages.length > 0\">Select the help icon beside a failed step to start.</p>\n <template for=\"message of aiMessages\">\n <div class=\"rounded-lg p-3 text-sm\" bind-class=\"message.role === 'assistant' ? 'bg-indigo-500/10.text-gray-200' : 'bg-gray-800.text-gray-300'\">\n <p class=\"mb-1 text-[10px] font-semibold uppercase tracking-wider text-gray-500\">{{ message.role }}</p>\n <pre class=\"whitespace-pre-wrap font-sans leading-relaxed\">{{ message.content }}</pre>\n </div>\n </template>\n <p class=\"text-sm text-rose-300\" class-hidden=\"!aiError\">{{ aiError }}</p>\n </div>\n <form class=\"border-t border-gray-800 pt-3\" on-submit.prevent=\"askFollowup()\">\n <label class=\"sr-only\" for=\"ai-question\">Ask a follow-up question</label>\n <div class=\"flex gap-2\">\n <input id=\"ai-question\" bind-value=\"aiQuestion\" placeholder=\"Ask a follow-up...\" bind-disabled=\"!aiStepId || aiLoading\" class=\"min-w-0 flex-1 rounded-lg border border-gray-700 bg-gray-950 px-3 py-2 text-sm text-gray-200 outline-none placeholder:text-gray-600 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/30 disabled:opacity-50\" />\n <button type=\"submit\" aria-label=\"Ask AI\" bind-disabled=\"!aiStepId || aiLoading\" class=\"inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-indigo-500 text-white outline-none hover:bg-indigo-400 focus-visible:ring-2 focus-visible:ring-indigo-400/60 disabled:opacity-50\"><lucide-icon icon=\"arrow-up\" size=\"16\"></lucide-icon></button>\n </div>\n </form>\n </aside>\n </template>\n <template if=\"report.canViewLogs && report.artifacts.length\">\n <details class=\"bg-gray-900 border border-gray-800 rounded-xl overflow-hidden\">\n <summary class=\"cursor-pointer px-4 py-3 text-xs font-semibold uppercase tracking-wider text-gray-400 outline-none transition hover:bg-gray-800 focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n Artifacts\n </summary>\n <ul class=\"divide-y divide-gray-800 border-t border-gray-800\">\n <template for=\"artifact of report.artifacts\">\n <li class=\"px-4 py-3\">\n <a\n attr-href=\"artifactUrl(artifact)\"\n class=\"font-mono text-sm text-indigo-300 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-400/60\"\n >{{ artifact }}</a>\n </li>\n </template>\n </ul>\n </details>\n </template>\n </div>\n\n <script setup>\n import { computed, onDestroy, onInit, ref } from '@li3/web';\n import { AnsiUp } from 'ansi_up';\n\n export default function setup() {\n const jobId = window.location.pathname.split('/').filter(Boolean).pop() || '';\n const report = ref({ jobId });\n const previousRuns = ref([]);\n const aiMessages = ref([]);\n const aiStepId = ref('');\n const aiQuestion = ref('');\n const aiError = ref('');\n const aiLoading = ref(false);\n let previousRunsLoaded = false;\n const now = ref(Date.now());\n const ansiUp = new AnsiUp();\n ansiUp.use_classes = false;\n let eventSource;\n let refreshTimer;\n let clockTimer;\n let refreshing = false;\n let refreshPending = false;\n const cancelling = ref(false);\n\n const active = computed(() => ['pending', 'running'].includes(report.value.status));\n const inputsJson = computed(() => JSON.stringify(report.value.inputs || {}, null, 2));\n const timing = computed(() => {\n if (report.value.status === 'pending') return 'Waiting for a worker';\n if (report.value.status === 'running') {\n return `Running for ${Math.max(0, now.value - Date.parse(report.value.startedAt))}ms`;\n }\n return `Finished in ${report.value.durationMs}ms`;\n });\n\n const upper = (value) => String(value || '').toUpperCase();\n const artifactUrl = (path) => `/api/runs/${report.value.jobId}/artifacts/${encodeURIComponent(path)}`;\n const loadPreviousRuns = async () => {\n if (previousRunsLoaded || !report.value.parentId) return;\n const lineage = [];\n const visited = new Set();\n let parentId = report.value.parentId;\n while (parentId && !visited.has(String(parentId)) && lineage.length < 50) {\n visited.add(String(parentId));\n const response = await fetch(`/api/runs/${parentId}`, { headers: { accept: 'application/json' } });\n if (!response.ok) throw new Error(`Previous run request failed: ${response.status}`);\n const parent = await response.json();\n lineage.push({ id: parent.jobId, status: parent.status, startedAt: parent.startedAt });\n parentId = parent.parentId;\n }\n previousRuns.value = lineage;\n previousRunsLoaded = true;\n };\n const stepLog = (step) => {\n if (step.status === 'skipped') return '';\n if (step.status === 'running')\n return '<span class=\"text-indigo-400\">Step is running. Logs will appear after it finishes.</span>';\n if (step.status === 'pending') return '<span class=\"text-gray-500\">Waiting to run.</span>';\n if (step.logContent) return ansiUp.ansi_to_html(step.logContent);\n return '<span class=\"text-gray-500\">(No terminal log output recorded for this step)</span>';\n };\n const askAi = async (step, event) => {\n event.stopPropagation();\n aiStepId.value = step.id;\n aiMessages.value = [];\n aiQuestion.value = '';\n await requestAiHelp(step.id, 'Please explain why this step failed and what I should do next.');\n };\n const requestAiHelp = async (stepId, question) => {\n aiLoading.value = true;\n aiError.value = '';\n try {\n const response = await fetch(`/api/runs/${report.value.jobId}/ai-help`, {\n method: 'POST',\n headers: { accept: 'application/json', 'content-type': 'application/json' },\n body: JSON.stringify({ stepId, question, conversation: aiMessages.value }),\n });\n const data = await response.json().catch(() => ({}));\n if (!response.ok) throw new Error(data.error || `AI help failed: ${response.status}`);\n aiMessages.value = [...aiMessages.value, { role: 'user', content: question }, { role: 'assistant', content: data.answer }];\n } catch (error) {\n aiError.value = error.message;\n } finally {\n aiLoading.value = false;\n }\n };\n const askFollowup = async () => {\n const question = aiQuestion.value.trim();\n if (!question || !aiStepId.value) return;\n aiQuestion.value = '';\n await requestAiHelp(aiStepId.value, question);\n };\n const restartJob = async () => {\n const response = await fetch(`/restart/${report.value.jobId}`, { method: 'POST' });\n if (response.ok) {\n const { id } = await response.json();\n location.href = `/runs/${id}`;\n }\n };\n const cancelJob = async () => {\n if (cancelling.value || report.value.status !== 'running') return;\n cancelling.value = true;\n try {\n const response = await fetch(`/api/jobs/${report.value.jobId}/cancel`, { method: 'POST' });\n if (!response.ok) throw new Error(`Cancel failed: ${response.status}`);\n await refreshRun();\n } catch (error) {\n console.error(error);\n } finally {\n cancelling.value = false;\n }\n };\n const refreshRun = async () => {\n if (refreshing) {\n refreshPending = true;\n return;\n }\n refreshing = true;\n\n try {\n const response = await fetch(`/api/runs/${jobId}`, {\n headers: { accept: 'application/json' },\n });\n if (!response.ok) throw new Error(`Run refresh failed: ${response.status}`);\n const previousStatus = report.value.status;\n const nextReport = await response.json();\n report.value = nextReport;\n document.title = `Run #${nextReport.jobId} - ${nextReport.workflowName}`;\n void loadPreviousRuns();\n if (\n ['pending', 'running'].includes(previousStatus) &&\n ['success', 'failed'].includes(nextReport.status) &&\n 'Notification' in window &&\n 'serviceWorker' in navigator &&\n Notification.permission === 'granted' &&\n localStorage.getItem('runner-notifications') === 'enabled'\n ) {\n const registration = await navigator.serviceWorker.ready;\n await registration.showNotification(\n nextReport.status === 'success'\n ? `Job #${nextReport.jobId} succeeded`\n : `Job #${nextReport.jobId} failed`,\n {\n body: `${nextReport.workflowName} finished with status ${nextReport.status}.`,\n icon: '/app-icon.svg',\n badge: '/app-icon.svg',\n tag: `runner-job-${nextReport.jobId}`,\n renotify: true,\n data: { url: `/runs/${nextReport.jobId}` },\n },\n );\n }\n } catch (error) {\n console.error(error);\n } finally {\n refreshing = false;\n if (refreshPending) {\n refreshPending = false;\n void refreshRun();\n }\n }\n };\n const handleJobChange = (event) => {\n const data = JSON.parse(event.data || '{}');\n if (!data.jobId || String(data.jobId) === String(report.value.jobId)) void refreshRun();\n };\n\n onInit(() => {\n void refreshRun();\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.register('/service-worker.js').catch((error) => {\n console.error('Service worker registration failed', error);\n });\n }\n eventSource = new EventSource('/api/events');\n eventSource.addEventListener('jobs.changed', handleJobChange);\n refreshTimer = setInterval(() => {\n if (active.value) void refreshRun();\n }, 60000);\n clockTimer = setInterval(() => {\n now.value = Date.now();\n }, 1000);\n });\n onDestroy(() => {\n eventSource?.close();\n clearInterval(refreshTimer);\n clearInterval(clockTimer);\n });\n\n return { report, previousRuns, aiMessages, aiStepId, aiQuestion, aiError, aiLoading, inputsJson, timing, upper, artifactUrl, stepLog, askAi, askFollowup, restartJob, cancelJob, cancelling };\n }\n <\/script>\n </template>\n\n <script type=\"module\">\n import '@li3/web';\n <\/script>\n <script src=\"https://cdn.tailwindcss.com\"><\/script>\n </body>\n</html>\n", Oe = /(?:^|[_-])auth(?:entication)?(?:$|[_-])|access[_-]?key|api[_-]?key|authorization|cookie|credential|passphrase|password|private[_-]?key|secret|session(?:id)?|signing[_-]?key|token/i;
495
502
  function ke(e, t, n, r = [], i = !0, a) {
496
503
  let o = JSON.parse(e.payload), s = e.report ? JSON.parse(e.report) : je(e, o, r), c = e.status;
497
504
  return {
@@ -5773,6 +5780,31 @@ var Vi = {
5773
5780
  404: { $ref: "#/components/responses/NotFound" }
5774
5781
  }
5775
5782
  } },
5783
+ "/api/runs/{jobId}/ai-help": { post: {
5784
+ tags: ["jobs"],
5785
+ summary: "Ask AI to diagnose a failed step",
5786
+ parameters: [{ $ref: "#/components/parameters/JobId" }],
5787
+ requestBody: {
5788
+ required: !0,
5789
+ content: { "application/json": { schema: {
5790
+ type: "object",
5791
+ required: ["stepId"],
5792
+ properties: { stepId: { type: "string" } }
5793
+ } } }
5794
+ },
5795
+ responses: {
5796
+ 200: {
5797
+ description: "AI diagnosis",
5798
+ content: { "application/json": { schema: {
5799
+ type: "object",
5800
+ properties: { answer: { type: "string" } }
5801
+ } } }
5802
+ },
5803
+ 401: { $ref: "#/components/responses/Unauthorized" },
5804
+ 502: { description: "AI provider failure" },
5805
+ 503: { description: "AI help is not configured" }
5806
+ }
5807
+ } },
5776
5808
  "/api/workflows/validate": { post: {
5777
5809
  tags: ["workflows"],
5778
5810
  summary: "Validate workflow YAML",
@@ -6279,99 +6311,144 @@ var Vi = {
6279
6311
  let t = await C.run("UPDATE api_keys SET revoked_at = CURRENT_TIMESTAMP WHERE id = ? AND revoked_at IS NULL", [e]);
6280
6312
  return Number(t?.changes || 0) > 0;
6281
6313
  }
6282
- }, Wi = "<!doctype html>\n<html lang=\"en\" class=\"dark\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>Runner settings</title>\n <script type=\"importmap\">\n { \"imports\": { \"@li3/\": \"https://cdn.li3.dev/@li3/\" } }\n <\/script>\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/lucide-icon.html\" />\n <link rel=\"component\" href=\"/app-header.html\" />\n </head>\n <body data-page=\"__SETTINGS_PAGE__\" class=\"min-h-screen bg-gray-950 p-4 font-sans text-gray-100 md:p-6\">\n <template app>\n <main class=\"mx-auto max-w-6xl space-y-5\">\n <app-header title=\"Settings\" subtitle=\"Human-admin controls and automation credentials\" back=\"/runs\" back-label=\"Back to jobs\"></app-header>\n <nav class=\"flex flex-wrap gap-1 rounded-xl border border-gray-800 bg-gray-900/70 p-1\" aria-label=\"Settings navigation\">\n <a href=\"/settings/workflows\" class=\"rounded-lg px-3 py-2 text-sm text-gray-300 hover:bg-gray-800\">Workflows</a>\n <a href=\"/settings/secrets\" class=\"rounded-lg px-3 py-2 text-sm text-gray-300 hover:bg-gray-800\">Secrets</a>\n <a href=\"/settings/tokens\" bind-class=\"page === 'tokens' ? 'bg-gray-800.text-white' : ''\" class=\"rounded-lg px-3 py-2 text-sm text-gray-300 hover:bg-gray-800\">API tokens</a>\n <a href=\"/settings/notifications\" bind-class=\"page === 'notifications' ? 'bg-gray-800.text-white' : ''\" class=\"rounded-lg px-3 py-2 text-sm text-gray-300 hover:bg-gray-800\">Notifications</a>\n </nav>\n\n <template if=\"page === 'tokens'\">\n </template>\n <template if=\"page === 'notifications'\">\n <section class=\"rounded-2xl border border-gray-800 bg-gray-900/80 p-5\" aria-labelledby=\"notifications-title\">\n <h2 id=\"notifications-title\" class=\"text-lg font-semibold text-white\">Notifications</h2>\n <p class=\"mt-1 text-sm text-gray-400\">Receive job completion notifications on this device.</p>\n <button type=\"button\" on-click=\"toggleNotifications()\" class=\"mt-5 inline-flex items-center gap-2 rounded-lg border border-indigo-500/60 px-4 py-2.5 text-sm font-medium text-indigo-200 outline-none hover:bg-indigo-500/10 focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n <lucide-icon bind-icon=\"notificationsEnabled ? 'bell-off' : 'bell-ring'\" size=\"16\"></lucide-icon>\n {{ notificationsEnabled ? 'Disable notifications' : 'Enable notifications' }}\n </button>\n <p class=\"mt-3 text-sm text-gray-400\" role=\"status\">{{ notificationMessage }}</p>\n </section>\n </template>\n\n <template if=\"page === 'tokens'\">\n <section class=\"rounded-2xl border border-gray-800 bg-gray-900/80 p-5\" aria-labelledby=\"keys-title\">\n <div class=\"flex items-start justify-between gap-3\">\n <div>\n <h2 id=\"keys-title\" class=\"text-lg font-semibold text-white\">API keys</h2>\n <p class=\"mt-1 text-sm text-gray-400\">Issue narrowly scoped credentials for automation tools. Keys are shown only once.</p>\n </div>\n </div>\n <div class=\"mt-5 grid gap-3 rounded-xl border border-gray-800 bg-gray-950/50 p-4 md:grid-cols-[1fr_auto]\">\n <label class=\"sr-only\" for=\"key-name\">Key name</label>\n <input id=\"key-name\" bind-value=\"keyName\" on-input=\"setKeyName($event)\" placeholder=\"Documentation bot\" class=\"rounded-lg border border-gray-700 bg-gray-900 px-3 py-2.5 text-sm outline-none focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/30\" />\n <button type=\"button\" on-click=\"issueKey()\" class=\"inline-flex items-center justify-center gap-2 rounded-lg bg-indigo-500 px-4 py-2.5 text-sm font-semibold text-white outline-none hover:bg-indigo-400 focus-visible:ring-2 focus-visible:ring-indigo-400/60\"><lucide-icon icon=\"key-round\" size=\"16\"></lucide-icon>Issue key</button>\n <fieldset class=\"md:col-span-2\">\n <legend class=\"mb-2 text-xs font-semibold uppercase tracking-wider text-gray-500\">Scopes</legend>\n <div class=\"space-y-2\">\n <template for=\"scope of scopeOptions\">\n <label class=\"group flex cursor-pointer items-center gap-3 text-sm text-gray-300\">\n <input type=\"checkbox\" bind-checked=\"scope.selected\" on-change=\"toggleScope(scope)\" class=\"peer sr-only\" />\n <span aria-hidden=\"true\" class=\"flex h-5 w-5 shrink-0 items-center justify-center rounded-md border border-gray-600 bg-gray-900 text-transparent transition peer-checked:border-indigo-400 peer-checked:bg-indigo-500 peer-checked:text-white peer-focus-visible:ring-2 peer-focus-visible:ring-indigo-400/70 peer-disabled:opacity-50\">\n <svg viewBox=\"0 0 16 16\" width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m3 8 3 3 7-7\"></path></svg>\n </span>\n <span class=\"group-hover:text-white\">{{ scope.label }}</span>\n </label>\n </template>\n </div>\n </fieldset>\n </div>\n <template if=\"newToken\">\n <div class=\"mt-4 rounded-xl border border-amber-500/40 bg-amber-500/10 p-4\" role=\"alert\">\n <p class=\"text-sm font-semibold text-amber-200\">Copy this key now. It cannot be shown again.</p>\n <code class=\"mt-2 block select-all break-all rounded bg-gray-950 p-3 font-mono text-xs text-amber-100\">{{ newToken }}</code>\n </div>\n </template>\n <h3 class=\"mt-5 text-xs font-semibold uppercase tracking-wider text-gray-500\">Active tokens</h3>\n <ul class=\"mt-2 space-y-2\" aria-label=\"Active API keys\">\n <template for=\"key of keys\">\n <li class=\"flex items-center justify-between gap-3 rounded-xl border border-gray-800 bg-gray-950/60 px-4 py-3\">\n <div class=\"min-w-0\"><p class=\"truncate text-sm font-medium text-gray-200\">{{ key.name }}</p><p class=\"text-xs text-gray-500\">{{ key.scopes.join(', ') }} · created {{ key.created_at }}</p></div>\n <button type=\"button\" on-click=\"revokeKey(key)\" class=\"shrink-0 rounded-lg p-2 text-rose-300 outline-none hover:bg-rose-500/10 focus-visible:ring-2 focus-visible:ring-rose-400/60\" aria-label=\"Revoke {{ key.name }}\" title=\"Revoke key\"><lucide-icon icon=\"trash\" size=\"16\"></lucide-icon></button>\n </li>\n </template>\n </ul>\n </section>\n </template>\n <p class=\"text-sm text-rose-300\" role=\"alert\" class-hidden=\"!error\">{{ error }}</p>\n </main>\n <script setup>\n import { onInit, ref } from '@li3/web';\n export default function () {\n const page = document.body.dataset.page;\n const keys = ref([]);\n const keyName = ref('');\n const newToken = ref('');\n const error = ref('');\n const notificationsSupported = ref('Notification' in window && 'serviceWorker' in navigator);\n const notificationsEnabled = ref(notificationsSupported.value && Notification.permission === 'granted' && localStorage.getItem('runner-notifications') === 'enabled');\n const notificationMessage = ref('');\n const scopeOptions = ref([\n { name: 'workflows:read', label: 'Read workflows', selected: true },\n { name: 'workflows:write', label: 'Modify workflows', selected: false },\n { name: 'logs:read', label: 'Read logs', selected: false },\n { name: 'artifacts:read', label: 'Read artifacts', selected: false },\n { name: 'runs:control', label: 'Control runs', selected: false },\n ]);\n const api = async (url, options = {}) => { const response = await fetch(url, { headers: { accept: 'application/json', ...(options.body ? { 'content-type': 'application/json' } : {}) }, ...options }); const body = await response.json().catch(() => ({})); if (!response.ok) throw new Error(body.error || `Request failed: ${response.status}`); return body; };\n const load = async () => { keys.value = (await api('/api/api-keys')).keys; };\n const issueKey = async () => { try { error.value = ''; const result = await api('/api/api-keys', { method: 'POST', body: JSON.stringify({ name: keyName.value, scopes: scopeOptions.value.filter((scope) => scope.selected).map((scope) => scope.name) }) }); newToken.value = result.token; keyName.value = ''; await load(); } catch (reason) { error.value = reason.message; } };\n const revokeKey = async (key) => { if (!confirm(`Revoke ${key.name}?`)) return; try { await api(`/api/api-keys/${key.id}`, { method: 'DELETE' }); await load(); } catch (reason) { error.value = reason.message; } };\n const setKeyName = (event) => { keyName.value = event.target.value; };\n const toggleScope = (scope) => { scope.selected = !scope.selected; };\n const toggleNotifications = async () => {\n if (notificationsEnabled.value) {\n notificationsEnabled.value = false;\n localStorage.removeItem('runner-notifications');\n notificationMessage.value = 'Notifications disabled on this device.';\n return;\n }\n if (!notificationsSupported.value) { notificationMessage.value = 'Notifications are not supported by this browser.'; return; }\n const permission = await Notification.requestPermission();\n notificationsEnabled.value = permission === 'granted';\n if (notificationsEnabled.value) { localStorage.setItem('runner-notifications', 'enabled'); notificationMessage.value = 'Notifications enabled.'; }\n else notificationMessage.value = 'Notification permission was not granted.';\n };\n onInit(() => { if (page === 'tokens') load().catch((reason) => { error.value = reason.message; }); });\n return { page, keys, keyName, newToken, error, scopeOptions, issueKey, revokeKey, setKeyName, toggleScope, notificationsEnabled, notificationMessage, toggleNotifications };\n }\n <\/script>\n </template>\n <script type=\"module\">import '@li3/web';<\/script>\n <script src=\"https://cdn.tailwindcss.com\"><\/script>\n </body>\n</html>\n";
6314
+ }, Wi = "<!doctype html>\n<html lang=\"en\" class=\"dark\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>Runner settings</title>\n <script type=\"importmap\">\n { \"imports\": { \"@li3/\": \"https://cdn.li3.dev/@li3/\" } }\n <\/script>\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/lucide-icon.html\" />\n <link rel=\"component\" href=\"/app-header.html\" />\n </head>\n <body data-page=\"__SETTINGS_PAGE__\" class=\"min-h-screen bg-gray-950 p-4 font-sans text-gray-100 md:p-6\">\n <template app>\n <main class=\"mx-auto max-w-6xl space-y-5 py-6\">\n <app-header title=\"Settings\" subtitle=\"Human-admin controls and automation credentials\" back=\"/runs\" back-label=\"Back to jobs\"></app-header>\n <nav class=\"flex flex-wrap gap-1 rounded-xl border border-gray-800 bg-gray-900/70 p-1\" aria-label=\"Settings navigation\">\n <a href=\"/settings/workflows\" class=\"rounded-lg px-3 py-2 text-sm text-gray-300 hover:bg-gray-800\">Workflows</a>\n <a href=\"/settings/secrets\" class=\"rounded-lg px-3 py-2 text-sm text-gray-300 hover:bg-gray-800\">Secrets</a>\n <a href=\"/settings/tokens\" bind-class=\"page === 'tokens' ? 'bg-gray-800.text-white' : ''\" class=\"rounded-lg px-3 py-2 text-sm text-gray-300 hover:bg-gray-800\">API tokens</a>\n <a href=\"/settings/notifications\" bind-class=\"page === 'notifications' ? 'bg-gray-800.text-white' : ''\" class=\"rounded-lg px-3 py-2 text-sm text-gray-300 hover:bg-gray-800\">Notifications</a>\n </nav>\n\n <template if=\"page === 'tokens'\">\n </template>\n <template if=\"page === 'notifications'\">\n <section class=\"rounded-2xl border border-gray-800 bg-gray-900/80 p-5\" aria-labelledby=\"notifications-title\">\n <h2 id=\"notifications-title\" class=\"text-lg font-semibold text-white\">Notifications</h2>\n <p class=\"mt-1 text-sm text-gray-400\">Receive job completion notifications on this device.</p>\n <button type=\"button\" on-click=\"toggleNotifications()\" class=\"mt-5 inline-flex items-center gap-2 rounded-lg border border-indigo-500/60 px-4 py-2.5 text-sm font-medium text-indigo-200 outline-none hover:bg-indigo-500/10 focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n <lucide-icon bind-icon=\"notificationsEnabled ? 'bell-off' : 'bell-ring'\" size=\"16\"></lucide-icon>\n {{ notificationsEnabled ? 'Disable notifications' : 'Enable notifications' }}\n </button>\n <p class=\"mt-3 text-sm text-gray-400\" role=\"status\">{{ notificationMessage }}</p>\n </section>\n </template>\n\n <template if=\"page === 'tokens'\">\n <section class=\"rounded-2xl border border-gray-800 bg-gray-900/80 p-5\" aria-labelledby=\"keys-title\">\n <div class=\"flex items-start justify-between gap-3\">\n <div>\n <h2 id=\"keys-title\" class=\"text-lg font-semibold text-white\">API keys</h2>\n <p class=\"mt-1 text-sm text-gray-400\">Issue narrowly scoped credentials for automation tools. Keys are shown only once.</p>\n </div>\n </div>\n <div class=\"mt-5 grid gap-3 rounded-xl border border-gray-800 bg-gray-950/50 p-4 md:grid-cols-[1fr_auto]\">\n <label class=\"sr-only\" for=\"key-name\">Key name</label>\n <input id=\"key-name\" bind-value=\"keyName\" on-input=\"setKeyName($event)\" placeholder=\"Documentation bot\" class=\"rounded-lg border border-gray-700 bg-gray-900 px-3 py-2.5 text-sm outline-none focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/30\" />\n <button type=\"button\" on-click=\"issueKey()\" class=\"inline-flex items-center justify-center gap-2 rounded-lg bg-indigo-500 px-4 py-2.5 text-sm font-semibold text-white outline-none hover:bg-indigo-400 focus-visible:ring-2 focus-visible:ring-indigo-400/60\"><lucide-icon icon=\"key-round\" size=\"16\"></lucide-icon>Issue key</button>\n <fieldset class=\"md:col-span-2\">\n <legend class=\"mb-2 text-xs font-semibold uppercase tracking-wider text-gray-500\">Scopes</legend>\n <div class=\"space-y-2\">\n <template for=\"scope of scopeOptions\">\n <label class=\"group flex cursor-pointer items-center gap-3 text-sm text-gray-300\">\n <input type=\"checkbox\" bind-checked=\"scope.selected\" on-change=\"toggleScope(scope)\" class=\"peer sr-only\" />\n <span aria-hidden=\"true\" class=\"flex h-5 w-5 shrink-0 items-center justify-center rounded-md border border-gray-600 bg-gray-900 text-transparent transition peer-checked:border-indigo-400 peer-checked:bg-indigo-500 peer-checked:text-white peer-focus-visible:ring-2 peer-focus-visible:ring-indigo-400/70 peer-disabled:opacity-50\">\n <svg viewBox=\"0 0 16 16\" width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m3 8 3 3 7-7\"></path></svg>\n </span>\n <span class=\"group-hover:text-white\">{{ scope.label }}</span>\n </label>\n </template>\n </div>\n </fieldset>\n </div>\n <template if=\"newToken\">\n <div class=\"mt-4 rounded-xl border border-amber-500/40 bg-amber-500/10 p-4\" role=\"alert\">\n <p class=\"text-sm font-semibold text-amber-200\">Copy this key now. It cannot be shown again.</p>\n <code class=\"mt-2 block select-all break-all rounded bg-gray-950 p-3 font-mono text-xs text-amber-100\">{{ newToken }}</code>\n </div>\n </template>\n <h3 class=\"mt-5 text-xs font-semibold uppercase tracking-wider text-gray-500\">Active tokens</h3>\n <ul class=\"mt-2 space-y-2\" aria-label=\"Active API keys\">\n <template for=\"key of keys\">\n <li class=\"flex items-center justify-between gap-3 rounded-xl border border-gray-800 bg-gray-950/60 px-4 py-3\">\n <div class=\"min-w-0\"><p class=\"truncate text-sm font-medium text-gray-200\">{{ key.name }}</p><p class=\"text-xs text-gray-500\">{{ key.scopes.join(', ') }} · created {{ key.created_at }}</p></div>\n <button type=\"button\" on-click=\"revokeKey(key)\" class=\"shrink-0 rounded-lg p-2 text-rose-300 outline-none hover:bg-rose-500/10 focus-visible:ring-2 focus-visible:ring-rose-400/60\" aria-label=\"Revoke {{ key.name }}\" title=\"Revoke key\"><lucide-icon icon=\"trash\" size=\"16\"></lucide-icon></button>\n </li>\n </template>\n </ul>\n </section>\n </template>\n <p class=\"text-sm text-rose-300\" role=\"alert\" class-hidden=\"!error\">{{ error }}</p>\n </main>\n <script setup>\n import { onInit, ref } from '@li3/web';\n export default function () {\n const page = document.body.dataset.page;\n const keys = ref([]);\n const keyName = ref('');\n const newToken = ref('');\n const error = ref('');\n const notificationsSupported = ref('Notification' in window && 'serviceWorker' in navigator);\n const notificationsEnabled = ref(notificationsSupported.value && Notification.permission === 'granted' && localStorage.getItem('runner-notifications') === 'enabled');\n const notificationMessage = ref('');\n const scopeOptions = ref([\n { name: 'workflows:read', label: 'Read workflows', selected: true },\n { name: 'workflows:write', label: 'Modify workflows', selected: false },\n { name: 'logs:read', label: 'Read logs', selected: false },\n { name: 'artifacts:read', label: 'Read artifacts', selected: false },\n { name: 'runs:control', label: 'Control runs', selected: false },\n ]);\n const api = async (url, options = {}) => { const response = await fetch(url, { headers: { accept: 'application/json', ...(options.body ? { 'content-type': 'application/json' } : {}) }, ...options }); const body = await response.json().catch(() => ({})); if (!response.ok) throw new Error(body.error || `Request failed: ${response.status}`); return body; };\n const load = async () => { keys.value = (await api('/api/api-keys')).keys; };\n const issueKey = async () => { try { error.value = ''; const result = await api('/api/api-keys', { method: 'POST', body: JSON.stringify({ name: keyName.value, scopes: scopeOptions.value.filter((scope) => scope.selected).map((scope) => scope.name) }) }); newToken.value = result.token; keyName.value = ''; await load(); } catch (reason) { error.value = reason.message; } };\n const revokeKey = async (key) => { if (!confirm(`Revoke ${key.name}?`)) return; try { await api(`/api/api-keys/${key.id}`, { method: 'DELETE' }); await load(); } catch (reason) { error.value = reason.message; } };\n const setKeyName = (event) => { keyName.value = event.target.value; };\n const toggleScope = (scope) => { scope.selected = !scope.selected; };\n const toggleNotifications = async () => {\n if (notificationsEnabled.value) {\n notificationsEnabled.value = false;\n localStorage.removeItem('runner-notifications');\n notificationMessage.value = 'Notifications disabled on this device.';\n return;\n }\n if (!notificationsSupported.value) { notificationMessage.value = 'Notifications are not supported by this browser.'; return; }\n const permission = await Notification.requestPermission();\n notificationsEnabled.value = permission === 'granted';\n if (notificationsEnabled.value) { localStorage.setItem('runner-notifications', 'enabled'); notificationMessage.value = 'Notifications enabled.'; }\n else notificationMessage.value = 'Notification permission was not granted.';\n };\n onInit(() => { if (page === 'tokens') load().catch((reason) => { error.value = reason.message; }); });\n return { page, keys, keyName, newToken, error, scopeOptions, issueKey, revokeKey, setKeyName, toggleScope, notificationsEnabled, notificationMessage, toggleNotifications };\n }\n <\/script>\n </template>\n <script type=\"module\">import '@li3/web';<\/script>\n <script src=\"https://cdn.tailwindcss.com\"><\/script>\n </body>\n</html>\n";
6283
6315
  //#endregion
6284
6316
  //#region src/settings-ui.ts
6285
6317
  function Gi(e = "tokens") {
6286
6318
  return Wi.replace("__SETTINGS_PAGE__", e);
6287
6319
  }
6288
6320
  //#endregion
6321
+ //#region src/ai-help.ts
6322
+ function Ki(e, t, n, r, i, a = `Please explain why step '${r}' failed and list the most useful next steps to fix or verify the problem.`, o = []) {
6323
+ let s = t.findIndex((e) => e.id === r), c = t.slice(0, s >= 0 ? s + 1 : t.length).map((e) => `===== STEP ${e.id} (${e.status}) =====\n${i(n[e.id] || e.logContent || "(no log output)")}`).join("\n\n");
6324
+ return [
6325
+ {
6326
+ role: "system",
6327
+ content: "You are an expert assistant helping diagnose an On CI workflow runner failure. Explain the likely root cause using only the supplied workflow and logs. Suggest concrete, safe next steps. Never invent hidden values or secrets."
6328
+ },
6329
+ {
6330
+ role: "user",
6331
+ content: `The workflow source YAML is:\n\n\`\`\`yaml\n${i(e)}\n\`\`\``
6332
+ },
6333
+ {
6334
+ role: "user",
6335
+ content: `The logs and step results from the beginning through the failed step are:\n\n\`\`\`text\n${c}\n\`\`\``
6336
+ },
6337
+ ...o,
6338
+ {
6339
+ role: "user",
6340
+ content: a
6341
+ }
6342
+ ];
6343
+ }
6344
+ function qi(e, t) {
6345
+ return {
6346
+ model: e,
6347
+ messages: t
6348
+ };
6349
+ }
6350
+ async function Ji(e, t, n) {
6351
+ let r = e.endsWith("/chat/completions") ? e : `${e.replace(/\/$/, "")}/chat/completions`, i = await fetch(r, {
6352
+ method: "POST",
6353
+ headers: {
6354
+ ...t ? { Authorization: `Bearer ${t}` } : {},
6355
+ "Content-Type": "application/json"
6356
+ },
6357
+ body: JSON.stringify(n),
6358
+ signal: AbortSignal.timeout(6e4)
6359
+ });
6360
+ if (!i.ok) throw Error(`AI help request failed with HTTP ${i.status}`);
6361
+ let a = (await i.json()).choices?.[0]?.message?.content;
6362
+ if (typeof a != "string" || !a.trim()) throw Error("AI help returned no response");
6363
+ return a;
6364
+ }
6365
+ //#endregion
6289
6366
  //#region src/app-header.html?raw
6290
- var Ki = "<template component=\"app-header\">\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/lucide-icon.html\" />\n <header class=\"mx-auto flex w-full max-w-[78rem] items-center justify-between gap-4 border-b border-gray-800 pb-5\">\n <div class=\"flex min-w-0 items-start gap-3\">\n <template if=\"back\">\n <a class=\"mt-0.5 inline-flex h-9 w-9 items-center justify-center rounded-lg border border-gray-800 text-gray-400 no-underline outline-none hover:border-indigo-500 hover:text-indigo-200 focus-visible:ring-2 focus-visible:ring-indigo-400/60\" attr-href=\"back\" attr-aria-label=\"backLabel || 'Back'\" attr-title=\"backLabel || 'Back'\">\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m15 18-6-6 6-6\"></path></svg>\n </a>\n </template>\n <div>\n <div class=\"text-[.7rem] font-bold uppercase tracking-[.16em] text-indigo-400\">Runner engine</div>\n <h1 class=\"mt-1 text-2xl font-bold tracking-tight text-white\">{{ title }}</h1>\n <p class=\"mt-1 text-xs text-gray-400\">{{ subtitle }}</p>\n </div>\n </div>\n <div class=\"flex items-center gap-2\">\n <a class=\"inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-700 text-indigo-200 no-underline outline-none hover:border-indigo-500 hover:bg-gray-900 hover:text-white focus-visible:ring-2 focus-visible:ring-indigo-400/60\" href=\"/help\" aria-label=\"Help\" title=\"Help\">\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"9\"></circle><path d=\"M9.6 9a2.5 2.5 0 1 1 4.2 1.8c-1.2 1-1.8 1.4-1.8 2.7\"></path><path d=\"M12 17h.01\"></path></svg>\n </a>\n <a class=\"inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-700 text-indigo-200 no-underline outline-none hover:border-indigo-500 hover:bg-gray-900 hover:text-white focus-visible:ring-2 focus-visible:ring-indigo-400/60\" href=\"/settings\" aria-label=\"Settings\" title=\"Settings\">\n <lucide-icon icon=\"settings\" size=\"16\"></lucide-icon>\n </a>\n </div>\n </header>\n <script setup>\n import { defineProp } from '@li3/web';\n export default function () {\n return { title: defineProp('title'), subtitle: defineProp('subtitle'), back: defineProp('back'), backLabel: defineProp('back-label') };\n }\n <\/script>\n</template>\n", qi = "<!doctype html>\n<html lang=\"en\" class=\"dark\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <meta name=\"theme-color\" content=\"#030712\" />\n <link rel=\"manifest\" href=\"/manifest.webmanifest\" />\n <link rel=\"icon\" href=\"/app-icon.svg\" type=\"image/svg+xml\" />\n <script type=\"importmap\">\n { \"imports\": { \"@li3/\": \"https://cdn.li3.dev/@li3/\", \"ansi_up\": \"https://esm.sh/ansi_up@6.0.6\", \"diff\": \"https://unpkg.com/diff@9.0.0/libesm/index.js\" } }\n <\/script>\n <link rel=\"component\" href=\"/app-router.html\" />\n <link rel=\"component\" href=\"/app-header.html\" />\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/lucide-icon.html\" />\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/code-editor.html\" />\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/code-block.html\" />\n <title>On Workflow Runner</title>\n </head>\n <body class=\"min-h-screen bg-gray-950 text-gray-100 font-sans\">\n <template app>\n <app-router></app-router>\n </template>\n <script type=\"module\">import '@li3/web';<\/script>\n <script src=\"https://cdn.tailwindcss.com\"><\/script>\n </body>\n</html>\n", Ji = "<template component=\"app-router\">\n <div ref=\"outlet\" aria-live=\"polite\"></div>\n <script setup>\n import { getElement, onDestroy, onInit, templateRef } from '@li3/web';\n import { load } from '@li3/web';\n\n export default function () {\n const outlet = templateRef('outlet');\n let navigating = false;\n\n const route = () => {\n const url = new URL(window.location.href);\n const path = url.pathname;\n if (path === '/' || path === '/runs') return { component: 'page-dashboard', url: '/pages/dashboard.html', page: 'dashboard' };\n if (path.match(/^\\/runs\\/\\d+$/)) return { component: 'page-run', url: `/pages/run.html?jobId=${path.split('/').pop()}`, page: 'run' };\n if (path === '/help') return { component: 'page-help', url: '/pages/help.html', page: 'help' };\n if (path === '/settings/workflows') return { component: 'page-workflows', url: '/pages/workflows.html?page=workflows', page: 'workflows' };\n if (path === '/settings/secrets') return { component: 'page-secrets', url: '/pages/workflows.html?page=secrets', page: 'secrets' };\n if (path === '/settings/tokens') return { component: 'page-settings', url: '/pages/settings.html?page=tokens', page: 'tokens' };\n if (path === '/settings/notifications') return { component: 'page-settings', url: '/pages/settings.html?page=notifications', page: 'notifications' };\n if (path === '/settings' || path === '/workflows') return { component: 'page-workflows', url: '/pages/workflows.html?page=workflows', page: 'workflows' };\n const editor = path.match(/^\\/settings\\/workflows\\/(new|[a-z0-9-]+)$/);\n if (editor) return { component: 'page-workflow-editor', url: `/pages/workflows.html?page=editor&id=${editor[1]}${url.searchParams.get('revision') ? `&revision=${url.searchParams.get('revision')}` : ''}`, page: 'editor' };\n const legacyEditor = path.match(/^\\/workflows\\/(new|[a-z0-9-]+)$/);\n if (legacyEditor) return { component: 'page-workflow-editor', url: `/pages/workflows.html?page=editor&id=${legacyEditor[1]}${url.searchParams.get('revision') ? `&revision=${url.searchParams.get('revision')}` : ''}`, page: 'editor' };\n return { component: 'page-dashboard', url: '/pages/dashboard.html', page: 'dashboard' };\n };\n\n const navigate = async (replace = false) => {\n if (navigating) return;\n navigating = true;\n try {\n const current = route();\n document.body.dataset.page = current.page;\n await load(current.url);\n outlet.value.replaceChildren(document.createElement(current.component));\n if (replace) history.replaceState(null, '', window.location.href);\n } catch (error) {\n outlet.value.innerHTML = `<main class=\"mx-auto max-w-4xl p-8\"><h1 class=\"text-xl font-semibold text-white\">Unable to load page</h1><p class=\"mt-2 text-sm text-rose-300\">${String(error.message || error)}</p></main>`;\n } finally {\n navigating = false;\n }\n };\n const handleClick = (event) => {\n const anchor = event.target.closest?.('a');\n if (!anchor || anchor.target || anchor.hasAttribute('download')) return;\n const target = new URL(anchor.href, window.location.href);\n if (target.origin !== window.location.origin || !target.pathname.startsWith('/')) return;\n if (target.pathname.startsWith('/api/') || target.pathname.startsWith('/webhooks/')) return;\n event.preventDefault();\n history.pushState(null, '', `${target.pathname}${target.search}${target.hash}`);\n void navigate();\n };\n const element = getElement();\n onInit(() => {\n element.addEventListener('click', handleClick);\n window.addEventListener('popstate', navigate);\n void navigate(true);\n });\n onDestroy(() => {\n element.removeEventListener('click', handleClick);\n window.removeEventListener('popstate', navigate);\n });\n return {};\n }\n <\/script>\n</template>\n", Yi = "<!doctype html>\n<html lang=\"en\" class=\"dark\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <meta name=\"theme-color\" content=\"#030712\" />\n <meta name=\"mobile-web-app-capable\" content=\"yes\" />\n <link rel=\"manifest\" href=\"/manifest.webmanifest\" />\n <link rel=\"icon\" href=\"/app-icon.svg\" type=\"image/svg+xml\" />\n <title>Runner Workflow Management</title>\n <script type=\"importmap\">\n { \"imports\": { \"@li3/\": \"https://cdn.li3.dev/@li3/\", \"diff\": \"https://unpkg.com/diff@9.0.0/libesm/index.js\" } }\n <\/script>\n <style>\n body[data-page='list'] .editor-panel {\n display: none;\n }\n body[data-page='workflows'] .editor-panel,\n body[data-page='workflows'] .secrets-panel,\n body[data-page='secrets'] .workflow-list,\n body[data-page='secrets'] .editor-panel {\n display: none;\n }\n body[data-page='editor'] .workflow-list,\n body[data-page='editor'] .secrets-panel {\n display: none;\n }\n </style>\n </head>\n <body data-page=\"__WORKFLOW_PAGE__\" class=\"min-h-screen bg-gray-950 p-4 font-sans text-gray-100 md:p-6\">\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/code-editor.html\" />\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/code-block.html\" />\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/lucide-icon.html\" />\n <link rel=\"component\" href=\"/app-header.html\" />\n\n <template app>\n <main class=\"mx-auto max-w-6xl space-y-5\">\n <template if=\"page === 'secrets'\"><app-header title=\"Secrets\" subtitle=\"Write-only credentials available to workflows\" back=\"/runs\" back-label=\"Back to dashboard\"></app-header></template>\n <template if=\"page !== 'secrets'\"><app-header title=\"Workflow control room\" subtitle=\"Draft, validate, and publish revisioned YAML definitions\" back=\"/runs\" back-label=\"Back to dashboard\"></app-header></template>\n <nav class=\"flex flex-wrap gap-1 rounded-xl border border-gray-800 bg-gray-900/70 p-1\" aria-label=\"Settings navigation\">\n <a href=\"/settings/workflows\" class=\"rounded-lg px-3 py-2 text-sm text-gray-300 hover:bg-gray-800\" bind-class=\"page === 'workflows' || page === 'editor' ? 'bg-gray-800.text-white' : ''\">Workflows</a>\n <a href=\"/settings/secrets\" class=\"rounded-lg px-3 py-2 text-sm text-gray-300 hover:bg-gray-800\" bind-class=\"page === 'secrets' ? 'bg-gray-800.text-white' : ''\">Secrets</a>\n <a href=\"/settings/tokens\" class=\"rounded-lg px-3 py-2 text-sm text-gray-300 hover:bg-gray-800\">API tokens</a>\n <a href=\"/settings/notifications\" class=\"rounded-lg px-3 py-2 text-sm text-gray-300 hover:bg-gray-800\">Notifications</a>\n </nav>\n\n <template if=\"notice\">\n <div\n role=\"status\"\n class=\"flex items-center gap-2 rounded-lg border px-3 py-2.5 text-sm\"\n bind-class=\"noticeError ? 'border-rose-500/40 bg-rose-500/10 text-rose-100' : 'border-emerald-500/40 bg-emerald-500/10 text-emerald-100'\"\n >\n <lucide-icon bind-icon=\"noticeError ? 'circle-alert' : 'circle-check'\" size=\"17\"></lucide-icon>\n <span>{{ notice }}</span>\n </div>\n </template>\n\n <section id=\"workflow-layout\" class=\"space-y-5\">\n <nav\n class=\"workflow-list rounded-2xl border border-gray-800 bg-gray-900/80 p-4 shadow-xl shadow-black/10\"\n aria-labelledby=\"workflow-list-title\"\n >\n <div class=\"mb-4 flex items-end justify-between gap-3 border-b border-gray-800 pb-4\">\n <div>\n <p class=\"text-[11px] font-semibold uppercase tracking-[0.18em] text-indigo-400\">Definitions</p>\n <h2 id=\"workflow-list-title\" class=\"mt-1 text-lg font-semibold text-white\">Workflows</h2>\n </div>\n <a\n href=\"/workflows/new\"\n class=\"inline-flex items-center gap-2 rounded-lg bg-indigo-500 px-3 py-2 text-sm font-semibold text-white outline-none transition hover:bg-indigo-400 focus-visible:ring-2 focus-visible:ring-indigo-400/60\"\n >\n <lucide-icon icon=\"plus\" size=\"16\"></lucide-icon>\n New workflow\n </a>\n </div>\n <ul class=\"grid gap-2\" aria-label=\"Workflow definitions\">\n <template for=\"workflow of workflows\">\n <li>\n <a\n attr-href=\"'/workflows/' + workflow.id\"\n class=\"group flex min-h-16 items-center gap-3 rounded-xl border border-gray-800 bg-gray-950/50 px-3.5 py-3 text-left text-sm text-gray-300 outline-none transition hover:border-indigo-500/50 hover:bg-indigo-500/10 focus-visible:border-indigo-400 focus-visible:ring-2 focus-visible:ring-indigo-400/50\"\n >\n <span\n class=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-gray-800 text-gray-400 transition group-hover:bg-indigo-500/15 group-hover:text-indigo-300\"\n >\n <lucide-icon icon=\"workflow\" size=\"17\"></lucide-icon>\n </span>\n <span class=\"min-w-0 flex-1\">\n <span class=\"block truncate text-base font-semibold text-gray-100\">{{ workflow.name }}</span>\n <span class=\"mt-0.5 block truncate font-mono text-[11px] text-gray-500\">{{ workflow.id }}</span>\n </span>\n <span\n class=\"rounded-full border px-2 py-1 text-[10px] font-semibold uppercase tracking-wide\"\n bind-class=\"workflow.status === 'published' ? 'border-emerald-500/30 bg-emerald-500/10 text-emerald-300' : workflow.status === 'archived' ? 'border-gray-700 bg-gray-800 text-gray-500' : 'border-amber-500/30 bg-amber-500/10 text-amber-300'\"\n >{{ workflow.status }}</span\n >\n <lucide-icon\n icon=\"arrow-up-right\"\n size=\"16\"\n class=\"shrink-0 text-gray-600 transition group-hover:text-indigo-300\"\n ></lucide-icon>\n </a>\n </li>\n </template>\n </ul>\n <div\n class=\"rounded-xl border border-dashed border-gray-700 px-4 py-8 text-center\"\n class-hidden=\"workflows.length > 0\"\n >\n <lucide-icon icon=\"workflow\" size=\"22\" class=\"mx-auto text-gray-600\"></lucide-icon>\n <p class=\"mt-2 text-sm font-medium text-gray-300\">No workflows yet</p>\n <p class=\"mt-1 text-xs text-gray-500\">Create a definition to start automating jobs.</p>\n </div>\n </nav>\n\n <section\n class=\"editor-panel overflow-hidden rounded-xl border border-gray-800 bg-gray-900/80 shadow-xl shadow-black/10\"\n >\n <div class=\"border-b border-gray-800 px-4 pt-3 sm:px-5\">\n <a\n href=\"/workflows\"\n class=\"inline-flex items-center gap-1.5 rounded-md px-2 py-1.5 text-xs font-medium text-gray-400 outline-none transition hover:bg-gray-800 hover:text-gray-100 focus-visible:ring-2 focus-visible:ring-indigo-400/60\"\n >\n <lucide-icon icon=\"arrow-left\" size=\"14\"></lucide-icon>\n Back to workflows\n </a>\n </div>\n <div class=\"border-b border-gray-800 bg-gray-900 px-4 py-4 sm:px-5\">\n <div class=\"flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between\">\n <label class=\"block max-w-xl flex-1 text-xs font-semibold uppercase tracking-wider text-gray-400\"\n >Workflow ID\n <input\n bind-value=\"workflowId\"\n on-input=\"setWorkflowId($event)\"\n bind-disabled=\"selectedId\"\n aria-describedby=\"workflow-id-help\"\n class=\"mt-2 w-full rounded-lg border border-gray-700 bg-gray-950 px-3 py-2.5 font-mono text-sm normal-case tracking-normal text-white outline-none transition focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20\"\n placeholder=\"derived-from-workflow-name\"\n />\n <span\n id=\"workflow-id-help\"\n class=\"mt-1 block text-[11px] font-normal normal-case tracking-normal text-gray-500\"\n >The ID becomes permanent after the first save.</span\n >\n </label>\n <label class=\"inline-flex items-center gap-2 text-sm text-gray-300\">\n <input\n type=\"checkbox\"\n bind-checked=\"enabled\"\n on-change=\"setEnabled($event)\"\n class=\"h-4 w-4 rounded border-gray-700 bg-gray-950 text-indigo-500 focus:ring-2 focus:ring-indigo-500/30\"\n />\n Enabled\n </label>\n <div class=\"flex flex-wrap gap-2\" class-hidden=\"readOnly\">\n <button\n type=\"button\"\n aria-label=\"Save workflow draft\"\n title=\"Save workflow draft\"\n on-click=\"save()\"\n bind-disabled=\"busy\"\n class=\"inline-flex items-center gap-2 rounded-lg bg-indigo-500 px-3 py-2.5 text-sm font-semibold text-white transition hover:bg-indigo-400 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <lucide-icon icon=\"save\" size=\"16\"></lucide-icon>\n <span class=\"hidden sm:inline\">Save draft</span>\n </button>\n <button\n type=\"button\"\n aria-label=\"Publish workflow\"\n title=\"Publish workflow\"\n on-click=\"publish()\"\n bind-disabled=\"busy || !selectedId || source !== savedSource || enabled !== savedEnabled\"\n class=\"inline-flex items-center gap-2 rounded-lg border border-emerald-500/50 px-3 py-2.5 text-sm font-medium text-emerald-300 transition hover:bg-emerald-500/10 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <lucide-icon icon=\"rocket\" size=\"16\"></lucide-icon>\n <span class=\"hidden sm:inline\">Publish</span>\n </button>\n <button\n type=\"button\"\n aria-label=\"Delete workflow\"\n title=\"Delete workflow\"\n on-click=\"remove()\"\n bind-disabled=\"busy\"\n class=\"inline-flex items-center gap-2 rounded-lg border border-rose-500/50 px-3 py-2.5 text-sm font-medium text-rose-300 transition hover:bg-rose-500/10 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <lucide-icon icon=\"trash\" size=\"16\"></lucide-icon>\n <span class=\"hidden sm:inline\">Delete</span>\n </button>\n </div>\n </div>\n </div>\n <div class=\"p-3 sm:p-5\">\n <div class=\"mb-2 flex items-center justify-between px-1 text-xs text-gray-500\">\n <div class=\"flex items-center gap-2\">\n <button\n type=\"button\"\n aria-label=\"Validate workflow\"\n title=\"Validate workflow\"\n on-click=\"validate(1)\"\n bind-disabled=\"validation.running\"\n bind-class=\"{ 'hidden': readOnly, 'text-emerald-400': validation.valid, 'text-rose-400': !validation.valid }\"\n class=\"disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <lucide-icon\n class=\"inline-block\"\n bind-icon=\"validation.running ? 'loader-circle' : (validation.valid ? 'circle-check' : 'circle-alert')\"\n bind-class=\"validation.running ? 'animate-spin' : ''\"\n size=\"16\"\n ></lucide-icon>\n </button>\n <span class=\"font-medium\" bind-class=\"validation.error ? 'bg-rose-500/10 text-rose-100' : ''\"\n >{{ validation.error || '' }}</span\n >\n </div>\n <template if=\"revision\">\n <button\n type=\"button\"\n on-click=\"openRevisionDialog()\"\n class=\"font-mono text-indigo-300 outline-none hover:underline focus-visible:rounded focus-visible:ring-2 focus-visible:ring-indigo-400/60\"\n >Revision {{ revision }}</button>\n </template>\n <template if=\"!revision\"><span class=\"font-mono\">Unsaved draft</span></template>\n </div>\n <template if=\"readOnly\">\n <code-block\n language=\"yaml\"\n theme=\"atom-one-dark\"\n class=\"block h-[calc(100vh-23rem)] min-h-[28rem] overflow-auto rounded-lg border border-gray-700 bg-gray-950 p-4\"\n bind-source=\"source\"\n ></code-block>\n </template>\n <template if=\"!readOnly\">\n <code-editor\n id=\"source-yaml\"\n language=\"yaml\"\n theme=\"atom-one-dark\"\n nostatus=\"true\"\n class=\"block h-[calc(100vh-23rem)] min-h-[28rem] overflow-hidden rounded-lg border border-gray-700 bg-gray-950\"\n bind-value=\"source\"\n on-change=\"setSource($event.detail)\"\n ></code-editor>\n </template>\n <details\n class=\"mt-4 overflow-hidden rounded-xl border border-gray-800 bg-gray-950/50\"\n on-toggle=\"loadHelp($event)\"\n >\n <summary\n class=\"flex cursor-pointer list-none items-center gap-2 px-4 py-3 text-sm font-medium text-gray-300 outline-none transition hover:bg-gray-900 focus-visible:ring-2 focus-visible:ring-indigo-400/60\"\n >\n <span class=\"inline-flex items-center gap-2\"\n ><lucide-icon icon=\"circle-question-mark\" size=\"16\"></lucide-icon>Syntax</span\n >\n <span class=\"ml-2 text-xs font-normal text-gray-500\">Reference, tutorials, and examples</span>\n </summary>\n <div\n ref=\"helpContent\"\n class=\"max-h-[38rem] overflow-y-auto border-t border-gray-800 bg-gray-950 px-4 py-5\"\n role=\"region\"\n aria-label=\"Workflow syntax help\"\n aria-live=\"polite\"\n >\n <p class=\"text-sm text-gray-500\">Expand to load the workflow syntax reference.</p>\n </div>\n </details>\n </div>\n </section>\n </section>\n\n <template if=\"revisionDialogOpen\">\n <div class=\"fixed inset-0 z-50 flex items-center justify-center bg-gray-950/80 p-4\" role=\"presentation\">\n <div\n class=\"flex max-h-[90vh] w-full max-w-4xl flex-col overflow-hidden rounded-2xl border border-gray-700 bg-gray-900 shadow-2xl\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"revision-dialog-title\"\n >\n <div class=\"flex items-center justify-between border-b border-gray-800 px-4 py-3\">\n <div>\n <h2 id=\"revision-dialog-title\" class=\"font-semibold text-white\">Workflow revision {{ revisionNumber }}</h2>\n <p class=\"text-xs text-gray-500\">Read-only source snapshot</p>\n </div>\n <button type=\"button\" on-click=\"closeRevisionDialog()\" aria-label=\"Close revision dialog\" class=\"rounded-lg p-2 text-gray-400 outline-none hover:bg-gray-800 hover:text-white focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n <lucide-icon icon=\"x\" size=\"17\"></lucide-icon>\n </button>\n </div>\n <div class=\"min-h-0 flex-1 overflow-auto p-4\">\n <p class=\"mb-3 text-sm text-rose-300\" class-hidden=\"!revisionError\">{{ revisionError }}</p>\n <pre class=\"min-h-[20rem] overflow-auto rounded-lg border border-gray-700 bg-gray-950 p-4 font-mono text-xs leading-6\" bind-innerhtml=\"revisionDiffHtml\"></pre>\n </div>\n <div class=\"flex items-center justify-between border-t border-gray-800 px-4 py-3\">\n <button type=\"button\" on-click=\"navigateRevision(-1)\" bind-disabled=\"revisionLoading || revisionNumber <= 1\" class=\"inline-flex items-center gap-2 rounded-lg border border-gray-700 px-3 py-2 text-sm text-gray-200 outline-none hover:bg-gray-800 focus-visible:ring-2 focus-visible:ring-indigo-400/60 disabled:opacity-40\">\n <lucide-icon icon=\"chevron-left\" size=\"16\"></lucide-icon>Previous\n </button>\n <button type=\"button\" on-click=\"navigateRevision(1)\" bind-disabled=\"revisionLoading || revisionNumber >= revision\" class=\"inline-flex items-center gap-2 rounded-lg border border-gray-700 px-3 py-2 text-sm text-gray-200 outline-none hover:bg-gray-800 focus-visible:ring-2 focus-visible:ring-indigo-400/60 disabled:opacity-40\">\n Next<lucide-icon icon=\"chevron-right\" size=\"16\"></lucide-icon>\n </button>\n </div>\n </div>\n </div>\n </template>\n\n <section\n class=\"secrets-panel rounded-2xl border border-gray-800 bg-gray-900/80 p-4 shadow-xl shadow-black/10 sm:p-5\"\n aria-labelledby=\"secrets-title\"\n >\n <div class=\"mb-5 flex items-start justify-between gap-3\">\n <div class=\"flex items-start gap-3\">\n <span class=\"rounded-lg bg-indigo-500/10 p-2 text-indigo-300\"\n ><lucide-icon icon=\"key-round\" size=\"18\"></lucide-icon\n ></span>\n <div>\n <h2 id=\"secrets-title\" class=\"text-lg font-semibold text-white\">Secrets</h2>\n <p class=\"mt-0.5 text-sm text-gray-400\">Write-only credentials available to workflows.</p>\n </div>\n </div>\n <span\n class=\"rounded-full border border-gray-700 bg-gray-950 px-2.5 py-1 text-xs font-mono text-gray-400\"\n aria-label=\"Secret count\"\n >{{ secrets.length }}</span\n >\n </div>\n <details ref=\"secretForm\" class=\"mb-5 overflow-hidden rounded-xl border border-gray-800 bg-gray-950/50\">\n <summary class=\"flex cursor-pointer list-none items-center justify-between px-4 py-3 text-sm font-medium text-gray-300 outline-none hover:bg-gray-900 focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n <span>Add a secret</span>\n <lucide-icon icon=\"plus\" size=\"17\"></lucide-icon>\n </summary>\n <div class=\"space-y-3 border-t border-gray-800 p-4\">\n <p class=\"text-xs text-gray-500\">Saving an existing name replaces its encrypted value.</p>\n <label class=\"sr-only\" for=\"secret-name\">Secret name</label>\n <input\n id=\"secret-name\"\n bind-value=\"secretName\"\n on-input=\"setSecretName($event)\"\n class=\"rounded-lg border border-gray-700 bg-gray-900 px-3 py-2.5 font-mono text-sm uppercase outline-none transition placeholder:text-gray-600 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/30\"\n placeholder=\"NPM_TOKEN\"\n />\n <label class=\"inline-flex items-center gap-2 text-sm text-gray-300\">\n <input type=\"checkbox\" bind-checked=\"fileMode\" on-change=\"setFileMode($event)\" class=\"h-4 w-4 rounded border-gray-700 bg-gray-900 text-indigo-500 focus:ring-2 focus:ring-indigo-500/30\" />\n Binary file secret\n </label>\n <template if=\"!fileMode\">\n <label class=\"sr-only\" for=\"secret-value\">Text secret value</label>\n <input\n id=\"secret-value\"\n ref=\"secretValueInput\"\n bind-value=\"secretValue\"\n on-input=\"setSecretValue($event)\"\n type=\"password\"\n class=\"rounded-lg border border-gray-700 bg-gray-900 px-3 py-2.5 font-mono text-sm outline-none transition placeholder:text-gray-600 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/30\"\n placeholder=\"New secret value\"\n />\n </template>\n <template if=\"fileMode\">\n <label class=\"sr-only\" for=\"secret-file\">Binary secret file</label>\n <input\n id=\"secret-file\"\n ref=\"secretFileInput\"\n on-change=\"setSecretFile($event)\"\n type=\"file\"\n class=\"rounded-lg border border-gray-700 bg-gray-900 px-3 py-2 text-xs text-gray-400 file:mr-3 file:rounded file:border-0 file:bg-gray-700 file:px-2 file:py-1 file:text-xs file:text-gray-200 focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/30\"\n />\n </template>\n <div>\n <button\n type=\"button\"\n aria-label=\"Save secret value\"\n title=\"Save secret value\"\n on-click=\"saveSecret()\"\n bind-disabled=\"busy\"\n class=\"inline-flex items-center justify-center gap-2 rounded-lg border border-indigo-500/60 px-3 py-2.5 text-sm font-medium text-indigo-200 outline-none transition hover:bg-indigo-500/10 focus-visible:ring-2 focus-visible:ring-indigo-400/60 disabled:opacity-50\"\n >\n <lucide-icon icon=\"lock-keyhole\" size=\"16\"></lucide-icon>Save secret\n </button>\n </div>\n </div>\n </div>\n </details>\n <ul class=\"grid gap-2\" aria-label=\"Saved secrets\">\n <template for=\"name of secrets\">\n <li>\n <div class=\"flex min-h-14 items-center gap-2 rounded-xl border border-gray-800 bg-gray-950/50 px-3.5 py-3\">\n <button\n type=\"button\"\n on-click=\"selectSecret(name)\"\n class=\"group flex min-w-0 flex-1 items-center gap-3 text-left outline-none focus-visible:ring-2 focus-visible:ring-indigo-400/50\"\n aria-label=\"Edit secret {{ name }}\"\n >\n <span\n class=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-gray-800 text-gray-500 group-hover:text-indigo-300\"\n ><lucide-icon icon=\"key-round\" size=\"15\"></lucide-icon\n ></span>\n <span class=\"min-w-0 flex-1 truncate font-mono text-sm text-gray-200\">{{ name }}</span>\n <span class=\"text-xs text-gray-500\">Select</span>\n <lucide-icon icon=\"chevron-right\" size=\"16\" class=\"text-gray-600 transition group-hover:text-indigo-300\"></lucide-icon>\n </button>\n <button\n type=\"button\"\n on-click=\"removeSecret(name)\"\n aria-label=\"Delete secret {{ name }}\"\n title=\"Delete secret\"\n class=\"inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-rose-300 outline-none transition hover:bg-rose-500/10 focus-visible:ring-2 focus-visible:ring-rose-400/60\"\n >\n <lucide-icon icon=\"trash\" size=\"15\"></lucide-icon>\n </button>\n </div>\n </li>\n </template>\n </ul>\n <div\n class=\"rounded-xl border border-dashed border-gray-700 px-4 py-8 text-center\"\n class-hidden=\"secrets.length > 0\"\n >\n <lucide-icon icon=\"key-round\" size=\"22\" class=\"mx-auto text-gray-600\"></lucide-icon>\n <p class=\"mt-2 text-sm font-medium text-gray-300\">No secrets configured</p>\n <p class=\"mt-1 text-xs text-gray-500\">Add one above to make it available to a workflow.</p>\n </div>\n </section>\n </main>\n\n <script setup>\n import { onDestroy, onInit, ref, templateRef } from '@li3/web';\n import { diffLines } from 'diff';\n\n export default function () {\n const page = document.body.dataset.page;\n const initialId = __WORKFLOW_ID__;\n const initialRevision = __WORKFLOW_REVISION__;\n const readOnly = Boolean(initialRevision);\n const workflows = ref([]);\n const secrets = ref([]);\n const source = ref('');\n const validation = ref({ valid: true });\n const savedSource = ref('');\n const revision = ref(null);\n const revisionDialogOpen = ref(false);\n const revisionNumber = ref(0);\n const revisionDiffHtml = ref('');\n const revisionError = ref('');\n const revisionLoading = ref(false);\n const workflowId = ref('');\n const enabled = ref(true);\n const savedEnabled = ref(true);\n const selectedId = ref('');\n const secretName = ref('');\n const secretValue = ref('');\n const fileMode = ref(false);\n const secretFileName = ref('');\n const secretFileData = ref('');\n const notice = ref('');\n const noticeError = ref(false);\n const busy = ref(false);\n const secretValueInput = templateRef('secretValueInput');\n const secretFileInput = templateRef('secretFileInput');\n const secretForm = templateRef('secretForm');\n const helpContent = templateRef('helpContent');\n const helpLoaded = ref(false);\n const helpLoading = ref(false);\n let validationTimer;\n\n const showNotice = (message, error = false) => {\n notice.value = message;\n noticeError.value = error;\n };\n\n const api = async (url, options = {}) => {\n const response = await fetch(url, {\n headers: { accept: 'application/json', ...(options.body ? { 'content-type': 'application/json' } : {}) },\n ...options,\n });\n const body = response.status === 204 ? null : await response.json().catch(() => ({}));\n if (!response.ok) throw new Error(body.error || `Request failed: ${response.status}`);\n return body;\n };\n\n const derivedId = () =>\n source.value\n .match(/^\\s*(?:id:\\s*([^\\n]+)|name:\\s*([^\\n]+))/m)\n ?.slice(1)\n .find(Boolean)\n ?.trim()\n .toLowerCase()\n .replace(/[^a-z0-9]/g, '-')\n .replace(/(^-|-$)/g, '') || '';\n\n const run = async (action) => {\n if (busy.value) return;\n\n busy.value = true;\n\n try {\n await action();\n } catch (error) {\n showNotice(error.message, true);\n } finally {\n busy.value = false;\n }\n };\n\n const loadWorkflows = async () => {\n workflows.value = (await api('/api/workflows')).workflows;\n };\n\n const loadSecrets = async () => {\n secrets.value = (await api('/api/secrets')).secrets;\n };\n\n const openWorkflow = async (id) => {\n const workflowUrl = initialRevision\n ? `/api/workflows/${id}?revision=${initialRevision}`\n : `/api/workflows/${id}`;\n const workflow = await api(workflowUrl);\n selectedId.value = workflow.id;\n workflowId.value = workflow.id;\n source.value = workflow.sourceYaml;\n savedSource.value = workflow.sourceYaml;\n enabled.value = workflow.enabled;\n savedEnabled.value = workflow.enabled;\n revision.value = workflow.revision || null;\n };\n\n const validateSource = async () => {\n return api('/api/workflows/validate', {\n method: 'POST',\n body: JSON.stringify({ sourceYaml: source.value }),\n });\n };\n\n const validate = (ms = 1000) => {\n if (page !== 'editor') return;\n\n clearTimeout(validationTimer);\n validationTimer = setTimeout(() => {\n validation.value = { ...validation.value, running: true, error: '' };\n void validateSource()\n .then((result) => {\n validation.value = { ...result, running: false };\n })\n .catch((error) => {\n validation.value = { valid: false, running: false, error: error.message };\n \n });\n }, ms);\n };\n\n const save = () =>\n run(async () => {\n const id = workflowId.value.trim() || derivedId();\n if (!id) throw new Error('Set an ID or add a workflow name first.');\n if (\n initialId &&\n id === selectedId.value &&\n source.value === savedSource.value &&\n enabled.value === savedEnabled.value\n ) {\n showNotice('No changes to save.');\n return;\n }\n const workflow = await api(`/api/workflows/${id}`, {\n method: 'PUT',\n body: JSON.stringify({ sourceYaml: source.value, enabled: enabled.value }),\n });\n selectedId.value = workflow.id;\n workflowId.value = workflow.id;\n savedSource.value = source.value;\n savedEnabled.value = enabled.value;\n revision.value = workflow.revision;\n showNotice(`Saved ${workflow.id} as draft revision ${workflow.revision}.`);\n if (!initialId) history.replaceState(null, '', `/workflows/${workflow.id}`);\n });\n const publish = () =>\n run(async () => {\n const id = workflowId.value.trim() || selectedId.value;\n if (!id) throw new Error('Save a workflow before publishing it.');\n const workflow = await api(`/api/workflows/${id}/publish`, { method: 'POST' });\n selectedId.value = workflow.id;\n revision.value = workflow.revision;\n showNotice(`Published ${workflow.id} revision ${workflow.revision}.`);\n });\n const remove = () =>\n run(async () => {\n const id = workflowId.value.trim() || selectedId.value;\n if (!id || !confirm(`Delete ${id} and all of its revisions?`)) return;\n await api(`/api/workflows/${id}`, { method: 'DELETE' });\n window.location.href = '/workflows';\n });\n const saveSecret = () =>\n run(async () => {\n const name = secretName.value.trim();\n if (!name || (fileMode.value ? !secretFileData.value : !secretValue.value)) throw new Error(fileMode.value ? 'Choose a file first.' : 'Set a secret value first.');\n await api(`/api/secrets/${name}`, {\n method: 'PUT',\n body: JSON.stringify(fileMode.value ? { value: secretFileData.value, encoding: 'base64', originalName: secretFileName.value } : { value: secretValue.value, encoding: 'utf8' }),\n });\n secretValue.value = '';\n secretFileName.value = '';\n secretFileData.value = '';\n fileMode.value = false;\n if (secretFileInput.value) secretFileInput.value.value = '';\n if (secretForm.value) secretForm.value.open = false;\n await loadSecrets();\n showNotice(`Saved ${name}.`);\n });\n const removeSecret = (requestedName = '') =>\n run(async () => {\n const name = requestedName || secretName.value.trim();\n if (!name || !confirm(`Delete ${name}?`)) return;\n await api(`/api/secrets/${name}`, { method: 'DELETE' });\n if (secretName.value.trim() === name) {\n secretName.value = '';\n secretValue.value = '';\n secretFileName.value = '';\n secretFileData.value = '';\n fileMode.value = false;\n if (secretFileInput.value) secretFileInput.value.value = '';\n }\n await loadSecrets();\n showNotice(`Deleted ${name}.`);\n });\n const setSource = (value) => {\n source.value = value;\n validate();\n };\n const setWorkflowId = (event) => {\n workflowId.value = event.target.value;\n };\n const setEnabled = (event) => {\n enabled.value = event.target.checked;\n };\n const setSecretName = (event) => {\n secretName.value = event.target.value;\n };\n const setSecretValue = (event) => {\n secretValue.value = event.target.value;\n fileMode.value = false;\n if (secretValue.value) {\n secretFileName.value = '';\n secretFileData.value = '';\n if (secretFileInput.value) secretFileInput.value.value = '';\n }\n };\n const setFileMode = (event) => {\n fileMode.value = event.target.checked;\n if (!fileMode.value) {\n secretFileName.value = '';\n secretFileData.value = '';\n if (secretFileInput.value) secretFileInput.value.value = '';\n } else {\n secretValue.value = '';\n }\n };\n const setSecretFile = async (event) => {\n const file = event.target.files?.[0];\n if (!file) return;\n const bytes = new Uint8Array(await file.arrayBuffer());\n let binary = '';\n for (let index = 0; index < bytes.length; index += 0x8000) {\n binary += String.fromCharCode(...bytes.subarray(index, index + 0x8000));\n }\n secretFileName.value = file.name;\n secretFileData.value = btoa(binary);\n secretValue.value = '';\n };\n const selectSecret = (name) => {\n secretName.value = name;\n secretValueInput.value?.focus();\n };\n const visitWorkflow = (id) => {\n window.location.href = `/workflows/${id}`;\n };\n const loadHelp = async (event) => {\n if (!event.target.open || helpLoaded.value || helpLoading.value || !helpContent.value) return;\n helpLoading.value = true;\n helpContent.value.textContent = 'Loading workflow syntax help...';\n try {\n const response = await fetch('/help?embed=1', { headers: { accept: 'text/html' } });\n if (!response.ok) throw new Error(`Help request failed: ${response.status}`);\n const html = await response.text();\n const parsed = new DOMParser().parseFromString(html, 'text/html');\n const sourceNodes = [\n ...Array.from(parsed.head.querySelectorAll('style')),\n ...Array.from(parsed.body.childNodes),\n ];\n const nodes = sourceNodes.map((node) => document.importNode(node, true));\n helpContent.value.replaceChildren(...nodes);\n helpLoaded.value = true;\n } catch (error) {\n helpContent.value.textContent = 'Unable to load workflow syntax help.';\n console.error(error);\n } finally {\n helpLoading.value = false;\n }\n };\n\n const escapeRevisionHtml = (value) => value.replace(/[&<>\"']/g, (character) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' })[character] || '');\n const renderRevisionDiff = (previousSource, currentSource) => {\n if (previousSource === null) return `<span class=\"text-emerald-300\">+ ${escapeRevisionHtml(currentSource)}</span>\\n`;\n return diffLines(previousSource, currentSource).map((part) => {\n const className = part.added ? 'text-emerald-300 bg-emerald-500/10' : part.removed ? 'text-rose-300 bg-rose-500/10' : 'text-gray-300';\n const prefix = part.added ? '+ ' : part.removed ? '- ' : ' ';\n return part.value.split('\\n').filter((line, index, lines) => index < lines.length - 1 || line).map((line) => `<span class=\"block ${className}\">${prefix}${escapeRevisionHtml(line)}</span>`).join('');\n }).join('');\n };\n const openRevisionDialog = async () => {\n if (!revision.value) return;\n revisionNumber.value = revision.value;\n revisionDiffHtml.value = '';\n revisionError.value = '';\n revisionDialogOpen.value = true;\n await loadRevisionDiff(revision.value);\n };\n const closeRevisionDialog = () => {\n revisionDialogOpen.value = false;\n };\n const loadRevisionDiff = async (number) => {\n revisionLoading.value = true;\n revisionError.value = '';\n try {\n const current = await api(`/api/workflows/${selectedId.value}?revision=${number}`);\n const previous = number > 1 ? await api(`/api/workflows/${selectedId.value}?revision=${number - 1}`) : null;\n revisionDiffHtml.value = renderRevisionDiff(previous?.sourceYaml ?? null, current.sourceYaml);\n } catch (error) {\n revisionError.value = error.message;\n } finally {\n revisionLoading.value = false;\n }\n };\n const navigateRevision = async (offset) => {\n if (!selectedId.value || revisionLoading.value) return;\n const target = revisionNumber.value + offset;\n if (target < 1 || target > revision.value) return;\n revisionNumber.value = target;\n await loadRevisionDiff(target);\n };\n\n onDestroy(() => clearTimeout(validationTimer));\n\n onInit(() => {\n const loadPage = page === 'editor'\n ? initialId ? openWorkflow(initialId) : Promise.resolve()\n : page === 'secrets' ? loadSecrets() : loadWorkflows();\n loadPage.catch((error) => showNotice(error.message, true));\n });\n\n return {\n page,\n workflows,\n secrets,\n source,\n validation,\n revision,\n revisionDialogOpen,\n revisionNumber,\n revisionDiffHtml,\n revisionError,\n revisionLoading,\n workflowId,\n enabled,\n readOnly,\n selectedId,\n secretName,\n secretValue,\n fileMode,\n secretFileName,\n secretFileData,\n notice,\n noticeError,\n busy,\n validate,\n save,\n publish,\n remove,\n saveSecret,\n removeSecret,\n setSource,\n setWorkflowId,\n setEnabled,\n setSecretName,\n setSecretValue,\n setFileMode,\n setSecretFile,\n selectSecret,\n visitWorkflow,\n loadHelp,\n openRevisionDialog,\n closeRevisionDialog,\n navigateRevision,\n };\n }\n <\/script>\n </template>\n\n <script type=\"module\">\n import '@li3/web';\n <\/script>\n <script src=\"https://cdn.tailwindcss.com\"><\/script>\n </body>\n</html>\n";
6367
+ var Yi = "<template component=\"app-header\">\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/lucide-icon.html\" />\n <header class=\"mx-auto flex w-full max-w-[78rem] items-center justify-between gap-4 border-b border-gray-800 pb-5\">\n <div class=\"flex min-w-0 items-start gap-3\">\n <template if=\"back\">\n <a class=\"mt-0.5 inline-flex h-9 w-9 items-center justify-center rounded-lg border border-gray-800 text-gray-400 no-underline outline-none hover:border-indigo-500 hover:text-indigo-200 focus-visible:ring-2 focus-visible:ring-indigo-400/60\" attr-href=\"back\" attr-aria-label=\"backLabel || 'Back'\" attr-title=\"backLabel || 'Back'\">\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" width=\"17\" height=\"17\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m15 18-6-6 6-6\"></path></svg>\n </a>\n </template>\n <div>\n <div class=\"text-[.7rem] font-bold uppercase tracking-[.16em] text-indigo-400\">Runner engine</div>\n <h1 class=\"mt-1 text-2xl font-bold tracking-tight text-white\">{{ title }}</h1>\n <template if=\"subtitle\"><p class=\"mt-1 text-xs text-gray-400\">{{ subtitle }}</p></template>\n </div>\n </div>\n <div class=\"flex items-center gap-2\">\n <a class=\"inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-700 text-indigo-200 no-underline outline-none hover:border-indigo-500 hover:bg-gray-900 hover:text-white focus-visible:ring-2 focus-visible:ring-indigo-400/60\" href=\"/help\" aria-label=\"Help\" title=\"Help\">\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"9\"></circle><path d=\"M9.6 9a2.5 2.5 0 1 1 4.2 1.8c-1.2 1-1.8 1.4-1.8 2.7\"></path><path d=\"M12 17h.01\"></path></svg>\n </a>\n <a class=\"inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-700 text-indigo-200 no-underline outline-none hover:border-indigo-500 hover:bg-gray-900 hover:text-white focus-visible:ring-2 focus-visible:ring-indigo-400/60\" href=\"/settings\" aria-label=\"Settings\" title=\"Settings\">\n <lucide-icon icon=\"settings\" size=\"16\"></lucide-icon>\n </a>\n </div>\n </header>\n <script setup>\n import { defineProp } from '@li3/web';\n export default function () {\n return { title: defineProp('title'), subtitle: defineProp('subtitle'), back: defineProp('back'), backLabel: defineProp('back-label') };\n }\n <\/script>\n</template>\n", Xi = "<!doctype html>\n<html lang=\"en\" class=\"dark\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <meta name=\"theme-color\" content=\"#030712\" />\n <link rel=\"manifest\" href=\"/manifest.webmanifest\" />\n <link rel=\"icon\" href=\"/app-icon.svg\" type=\"image/svg+xml\" />\n <script type=\"importmap\">\n { \"imports\": { \"@li3/\": \"https://cdn.li3.dev/@li3/\", \"ansi_up\": \"https://esm.sh/ansi_up@6.0.6\", \"diff\": \"https://unpkg.com/diff@9.0.0/libesm/index.js\" } }\n <\/script>\n <link rel=\"component\" href=\"/app-router.html\" />\n <link rel=\"component\" href=\"/app-header.html\" />\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/lucide-icon.html\" />\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/code-editor.html\" />\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/code-block.html\" />\n <title>On Workflow Runner</title>\n </head>\n <body class=\"min-h-screen bg-gray-950 text-gray-100 font-sans\">\n <template app>\n <app-router></app-router>\n </template>\n <script type=\"module\">import '@li3/web';<\/script>\n <script src=\"https://cdn.tailwindcss.com\"><\/script>\n </body>\n</html>\n", Zi = "<template component=\"app-router\">\n <div ref=\"outlet\" aria-live=\"polite\"></div>\n <script setup>\n import { getElement, onDestroy, onInit, templateRef } from '@li3/web';\n import { load } from '@li3/web';\n\n export default function () {\n const outlet = templateRef('outlet');\n let navigating = false;\n\n const route = () => {\n const url = new URL(window.location.href);\n const path = url.pathname;\n if (path === '/' || path === '/runs') return { component: 'page-dashboard', url: '/pages/dashboard.html', page: 'dashboard' };\n if (path.match(/^\\/runs\\/\\d+$/)) return { component: 'page-run', url: `/pages/run.html?jobId=${path.split('/').pop()}`, page: 'run' };\n if (path === '/help') return { component: 'page-help', url: '/pages/help.html', page: 'help' };\n if (path === '/settings/workflows') return { component: 'page-workflows', url: '/pages/workflows.html?page=workflows', page: 'workflows' };\n if (path === '/settings/secrets') return { component: 'page-secrets', url: '/pages/workflows.html?page=secrets', page: 'secrets' };\n if (path === '/settings/tokens') return { component: 'page-settings', url: '/pages/settings.html?page=tokens', page: 'tokens' };\n if (path === '/settings/notifications') return { component: 'page-settings', url: '/pages/settings.html?page=notifications', page: 'notifications' };\n if (path === '/settings' || path === '/workflows') return { component: 'page-workflows', url: '/pages/workflows.html?page=workflows', page: 'workflows' };\n const editor = path.match(/^\\/settings\\/workflows\\/(new|[a-z0-9-]+)$/);\n if (editor) return { component: 'page-workflow-editor', url: `/pages/workflows.html?page=editor&id=${editor[1]}${url.searchParams.get('revision') ? `&revision=${url.searchParams.get('revision')}` : ''}`, page: 'editor' };\n const legacyEditor = path.match(/^\\/workflows\\/(new|[a-z0-9-]+)$/);\n if (legacyEditor) return { component: 'page-workflow-editor', url: `/pages/workflows.html?page=editor&id=${legacyEditor[1]}${url.searchParams.get('revision') ? `&revision=${url.searchParams.get('revision')}` : ''}`, page: 'editor' };\n return { component: 'page-dashboard', url: '/pages/dashboard.html', page: 'dashboard' };\n };\n\n const navigate = async (replace = false) => {\n if (navigating) return;\n navigating = true;\n try {\n const current = route();\n document.body.dataset.page = current.page;\n await load(current.url);\n outlet.value.replaceChildren(document.createElement(current.component));\n if (replace) history.replaceState(null, '', window.location.href);\n } catch (error) {\n outlet.value.innerHTML = `<main class=\"mx-auto max-w-4xl p-8\"><h1 class=\"text-xl font-semibold text-white\">Unable to load page</h1><p class=\"mt-2 text-sm text-rose-300\">${String(error.message || error)}</p></main>`;\n } finally {\n navigating = false;\n }\n };\n const handleClick = (event) => {\n const anchor = event.target.closest?.('a');\n if (!anchor || anchor.target || anchor.hasAttribute('download')) return;\n const target = new URL(anchor.href, window.location.href);\n if (target.origin !== window.location.origin || !target.pathname.startsWith('/')) return;\n if (target.pathname.startsWith('/api/') || target.pathname.startsWith('/webhooks/')) return;\n if (target.pathname === window.location.pathname && target.hash) return;\n event.preventDefault();\n history.pushState(null, '', `${target.pathname}${target.search}${target.hash}`);\n void navigate();\n };\n const element = getElement();\n onInit(() => {\n element.addEventListener('click', handleClick);\n window.addEventListener('popstate', navigate);\n void navigate(true);\n });\n onDestroy(() => {\n element.removeEventListener('click', handleClick);\n window.removeEventListener('popstate', navigate);\n });\n return {};\n }\n <\/script>\n</template>\n", Qi = "<!doctype html>\n<html lang=\"en\" class=\"dark\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <meta name=\"theme-color\" content=\"#030712\" />\n <meta name=\"mobile-web-app-capable\" content=\"yes\" />\n <link rel=\"manifest\" href=\"/manifest.webmanifest\" />\n <link rel=\"icon\" href=\"/app-icon.svg\" type=\"image/svg+xml\" />\n <title>Runner Workflow Management</title>\n <script type=\"importmap\">\n { \"imports\": { \"@li3/\": \"https://cdn.li3.dev/@li3/\", \"diff\": \"https://unpkg.com/diff@9.0.0/libesm/index.js\" } }\n <\/script>\n <style>\n body[data-page='list'] .editor-panel {\n display: none;\n }\n body[data-page='workflows'] .editor-panel,\n body[data-page='workflows'] .secrets-panel,\n body[data-page='secrets'] .workflow-list,\n body[data-page='secrets'] .editor-panel {\n display: none;\n }\n body[data-page='editor'] .workflow-list,\n body[data-page='editor'] .secrets-panel {\n display: none;\n }\n </style>\n </head>\n <body data-page=\"__WORKFLOW_PAGE__\" class=\"min-h-screen bg-gray-950 p-4 font-sans text-gray-100 md:p-6\">\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/code-editor.html\" />\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/code-block.html\" />\n <link rel=\"component\" href=\"https://sodium.static.apphor.de/lucide-icon.html\" />\n <link rel=\"component\" href=\"/app-header.html\" />\n\n <template app>\n <main class=\"mx-auto max-w-6xl space-y-5 py-6\">\n <template if=\"page === 'secrets'\"><app-header title=\"Secrets\" subtitle=\"Write-only credentials available to workflows\" back=\"/runs\" back-label=\"Back to dashboard\"></app-header></template>\n <template if=\"page !== 'secrets'\"><app-header title=\"Workflow control room\" subtitle=\"Draft, validate, and publish revisioned YAML definitions\" back=\"/runs\" back-label=\"Back to dashboard\"></app-header></template>\n <nav class=\"flex flex-wrap gap-1 rounded-xl border border-gray-800 bg-gray-900/70 p-1\" aria-label=\"Settings navigation\">\n <a href=\"/settings/workflows\" class=\"rounded-lg px-3 py-2 text-sm text-gray-300 hover:bg-gray-800\" bind-class=\"page === 'workflows' || page === 'editor' ? 'bg-gray-800.text-white' : ''\">Workflows</a>\n <a href=\"/settings/secrets\" class=\"rounded-lg px-3 py-2 text-sm text-gray-300 hover:bg-gray-800\" bind-class=\"page === 'secrets' ? 'bg-gray-800.text-white' : ''\">Secrets</a>\n <a href=\"/settings/tokens\" class=\"rounded-lg px-3 py-2 text-sm text-gray-300 hover:bg-gray-800\">API tokens</a>\n <a href=\"/settings/notifications\" class=\"rounded-lg px-3 py-2 text-sm text-gray-300 hover:bg-gray-800\">Notifications</a>\n </nav>\n\n <template if=\"notice\">\n <div\n role=\"status\"\n class=\"flex items-center gap-2 rounded-lg border px-3 py-2.5 text-sm\"\n bind-class=\"noticeError ? 'border-rose-500/40 bg-rose-500/10 text-rose-100' : 'border-emerald-500/40 bg-emerald-500/10 text-emerald-100'\"\n >\n <lucide-icon bind-icon=\"noticeError ? 'circle-alert' : 'circle-check'\" size=\"17\"></lucide-icon>\n <span>{{ notice }}</span>\n </div>\n </template>\n\n <section id=\"workflow-layout\" class=\"space-y-5\">\n <nav\n class=\"workflow-list rounded-2xl border border-gray-800 bg-gray-900/80 p-4 shadow-xl shadow-black/10\"\n aria-labelledby=\"workflow-list-title\"\n >\n <div class=\"mb-4 flex items-end justify-between gap-3 border-b border-gray-800 pb-4\">\n <div>\n <p class=\"text-[11px] font-semibold uppercase tracking-[0.18em] text-indigo-400\">Definitions</p>\n <h2 id=\"workflow-list-title\" class=\"mt-1 text-lg font-semibold text-white\">Workflows</h2>\n </div>\n <a\n href=\"/workflows/new\"\n class=\"inline-flex items-center gap-2 rounded-lg bg-indigo-500 px-3 py-2 text-sm font-semibold text-white outline-none transition hover:bg-indigo-400 focus-visible:ring-2 focus-visible:ring-indigo-400/60\"\n >\n <lucide-icon icon=\"plus\" size=\"16\"></lucide-icon>\n New workflow\n </a>\n </div>\n <ul class=\"grid gap-2\" aria-label=\"Workflow definitions\">\n <template for=\"workflow of workflows\">\n <li>\n <a\n attr-href=\"'/workflows/' + workflow.id\"\n class=\"group flex min-h-16 items-center gap-3 rounded-xl border border-gray-800 bg-gray-950/50 px-3.5 py-3 text-left text-sm text-gray-300 outline-none transition hover:border-indigo-500/50 hover:bg-indigo-500/10 focus-visible:border-indigo-400 focus-visible:ring-2 focus-visible:ring-indigo-400/50\"\n >\n <span\n class=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-gray-800 text-gray-400 transition group-hover:bg-indigo-500/15 group-hover:text-indigo-300\"\n >\n <lucide-icon icon=\"workflow\" size=\"17\"></lucide-icon>\n </span>\n <span class=\"min-w-0 flex-1\">\n <span class=\"block truncate text-base font-semibold text-gray-100\">{{ workflow.name }}</span>\n <span class=\"mt-0.5 block truncate font-mono text-[11px] text-gray-500\">{{ workflow.id }}</span>\n </span>\n <span\n class=\"rounded-full border px-2 py-1 text-[10px] font-semibold uppercase tracking-wide\"\n bind-class=\"workflow.status === 'published' ? 'border-emerald-500/30 bg-emerald-500/10 text-emerald-300' : workflow.status === 'archived' ? 'border-gray-700 bg-gray-800 text-gray-500' : 'border-amber-500/30 bg-amber-500/10 text-amber-300'\"\n >{{ workflow.status }}</span\n >\n <lucide-icon\n icon=\"arrow-up-right\"\n size=\"16\"\n class=\"shrink-0 text-gray-600 transition group-hover:text-indigo-300\"\n ></lucide-icon>\n </a>\n </li>\n </template>\n </ul>\n <div\n class=\"rounded-xl border border-dashed border-gray-700 px-4 py-8 text-center\"\n class-hidden=\"workflows.length > 0\"\n >\n <lucide-icon icon=\"workflow\" size=\"22\" class=\"mx-auto text-gray-600\"></lucide-icon>\n <p class=\"mt-2 text-sm font-medium text-gray-300\">No workflows yet</p>\n <p class=\"mt-1 text-xs text-gray-500\">Create a definition to start automating jobs.</p>\n </div>\n </nav>\n\n <section\n class=\"editor-panel overflow-hidden rounded-xl border border-gray-800 bg-gray-900/80 shadow-xl shadow-black/10\"\n >\n <div class=\"border-b border-gray-800 px-4 pt-3 sm:px-5\">\n <a\n href=\"/workflows\"\n class=\"inline-flex items-center gap-1.5 rounded-md px-2 py-1.5 text-xs font-medium text-gray-400 outline-none transition hover:bg-gray-800 hover:text-gray-100 focus-visible:ring-2 focus-visible:ring-indigo-400/60\"\n >\n <lucide-icon icon=\"arrow-left\" size=\"14\"></lucide-icon>\n Back to workflows\n </a>\n </div>\n <div class=\"border-b border-gray-800 bg-gray-900 px-4 py-4 sm:px-5\">\n <div class=\"flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between\">\n <label class=\"block max-w-xl flex-1 text-xs font-semibold uppercase tracking-wider text-gray-400\"\n >Workflow ID\n <input\n bind-value=\"workflowId\"\n on-input=\"setWorkflowId($event)\"\n bind-disabled=\"selectedId\"\n aria-describedby=\"workflow-id-help\"\n class=\"mt-2 w-full rounded-lg border border-gray-700 bg-gray-950 px-3 py-2.5 font-mono text-sm normal-case tracking-normal text-white outline-none transition focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20\"\n placeholder=\"derived-from-workflow-name\"\n />\n <span\n id=\"workflow-id-help\"\n class=\"mt-1 block text-[11px] font-normal normal-case tracking-normal text-gray-500\"\n >The ID becomes permanent after the first save.</span\n >\n </label>\n <label class=\"inline-flex items-center gap-2 text-sm text-gray-300\">\n <input\n type=\"checkbox\"\n bind-checked=\"enabled\"\n on-change=\"setEnabled($event)\"\n class=\"h-4 w-4 rounded border-gray-700 bg-gray-950 text-indigo-500 focus:ring-2 focus:ring-indigo-500/30\"\n />\n Enabled\n </label>\n <div class=\"flex flex-wrap gap-2\" class-hidden=\"readOnly\">\n <button\n type=\"button\"\n aria-label=\"Save workflow draft\"\n title=\"Save workflow draft\"\n on-click=\"save()\"\n bind-disabled=\"busy\"\n class=\"inline-flex items-center gap-2 rounded-lg bg-indigo-500 px-3 py-2.5 text-sm font-semibold text-white transition hover:bg-indigo-400 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <lucide-icon icon=\"save\" size=\"16\"></lucide-icon>\n <span class=\"hidden sm:inline\">Save draft</span>\n </button>\n <button\n type=\"button\"\n aria-label=\"Publish workflow\"\n title=\"Publish workflow\"\n on-click=\"publish()\"\n bind-disabled=\"busy || !selectedId || source !== savedSource || enabled !== savedEnabled\"\n class=\"inline-flex items-center gap-2 rounded-lg border border-emerald-500/50 px-3 py-2.5 text-sm font-medium text-emerald-300 transition hover:bg-emerald-500/10 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <lucide-icon icon=\"rocket\" size=\"16\"></lucide-icon>\n <span class=\"hidden sm:inline\">Publish</span>\n </button>\n <button\n type=\"button\"\n aria-label=\"Delete workflow\"\n title=\"Delete workflow\"\n on-click=\"remove()\"\n bind-disabled=\"busy\"\n class=\"inline-flex items-center gap-2 rounded-lg border border-rose-500/50 px-3 py-2.5 text-sm font-medium text-rose-300 transition hover:bg-rose-500/10 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <lucide-icon icon=\"trash\" size=\"16\"></lucide-icon>\n <span class=\"hidden sm:inline\">Delete</span>\n </button>\n </div>\n </div>\n </div>\n <div class=\"p-3 sm:p-5\">\n <div class=\"mb-2 flex items-center justify-between px-1 text-xs text-gray-500\">\n <div class=\"flex items-center gap-2\">\n <button\n type=\"button\"\n aria-label=\"Validate workflow\"\n title=\"Validate workflow\"\n on-click=\"validate(1)\"\n bind-disabled=\"validation.running\"\n bind-class=\"{ 'hidden': readOnly, 'text-emerald-400': validation.valid, 'text-rose-400': !validation.valid }\"\n class=\"disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <lucide-icon\n class=\"inline-block\"\n bind-icon=\"validation.running ? 'loader-circle' : (validation.valid ? 'circle-check' : 'circle-alert')\"\n bind-class=\"validation.running ? 'animate-spin' : ''\"\n size=\"16\"\n ></lucide-icon>\n </button>\n <span class=\"font-medium\" bind-class=\"validation.error ? 'bg-rose-500/10 text-rose-100' : ''\"\n >{{ validation.error || '' }}</span\n >\n </div>\n <template if=\"revision\">\n <button\n type=\"button\"\n on-click=\"openRevisionDialog()\"\n class=\"font-mono text-indigo-300 outline-none hover:underline focus-visible:rounded focus-visible:ring-2 focus-visible:ring-indigo-400/60\"\n >Revision {{ revision }}</button>\n </template>\n <template if=\"!revision\"><span class=\"font-mono\">Unsaved draft</span></template>\n </div>\n <template if=\"readOnly\">\n <code-block\n language=\"yaml\"\n theme=\"atom-one-dark\"\n class=\"block h-[calc(100vh-23rem)] min-h-[28rem] overflow-auto rounded-lg border border-gray-700 bg-gray-950 p-4\"\n bind-source=\"source\"\n ></code-block>\n </template>\n <template if=\"!readOnly\">\n <code-editor\n id=\"source-yaml\"\n language=\"yaml\"\n theme=\"atom-one-dark\"\n nostatus=\"true\"\n class=\"block h-[calc(100vh-23rem)] min-h-[28rem] overflow-hidden rounded-lg border border-gray-700 bg-gray-950\"\n bind-value=\"source\"\n on-change=\"setSource($event.detail)\"\n ></code-editor>\n </template>\n <details\n class=\"mt-4 overflow-hidden rounded-xl border border-gray-800 bg-gray-950/50\"\n on-toggle=\"loadHelp($event)\"\n >\n <summary\n class=\"flex cursor-pointer list-none items-center gap-2 px-4 py-3 text-sm font-medium text-gray-300 outline-none transition hover:bg-gray-900 focus-visible:ring-2 focus-visible:ring-indigo-400/60\"\n >\n <span class=\"inline-flex items-center gap-2\"\n ><lucide-icon icon=\"circle-question-mark\" size=\"16\"></lucide-icon>Syntax</span\n >\n <span class=\"ml-2 text-xs font-normal text-gray-500\">Reference, tutorials, and examples</span>\n </summary>\n <div\n ref=\"helpContent\"\n class=\"max-h-[38rem] overflow-y-auto border-t border-gray-800 bg-gray-950 px-4 py-5\"\n role=\"region\"\n aria-label=\"Workflow syntax help\"\n aria-live=\"polite\"\n >\n <p class=\"text-sm text-gray-500\">Expand to load the workflow syntax reference.</p>\n </div>\n </details>\n </div>\n </section>\n </section>\n\n <template if=\"revisionDialogOpen\">\n <div class=\"fixed inset-0 z-50 flex items-center justify-center bg-gray-950/80 p-4\" role=\"presentation\">\n <div\n class=\"flex max-h-[90vh] w-full max-w-4xl flex-col overflow-hidden rounded-2xl border border-gray-700 bg-gray-900 shadow-2xl\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"revision-dialog-title\"\n >\n <div class=\"flex items-center justify-between border-b border-gray-800 px-4 py-3\">\n <div>\n <h2 id=\"revision-dialog-title\" class=\"font-semibold text-white\">Workflow revision {{ revisionNumber }}</h2>\n <p class=\"text-xs text-gray-500\">Read-only source snapshot</p>\n </div>\n <button type=\"button\" on-click=\"closeRevisionDialog()\" aria-label=\"Close revision dialog\" class=\"rounded-lg p-2 text-gray-400 outline-none hover:bg-gray-800 hover:text-white focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n <lucide-icon icon=\"x\" size=\"17\"></lucide-icon>\n </button>\n </div>\n <div class=\"min-h-0 flex-1 overflow-auto p-4\">\n <p class=\"mb-3 text-sm text-rose-300\" class-hidden=\"!revisionError\">{{ revisionError }}</p>\n <pre class=\"min-h-[20rem] overflow-auto rounded-lg border border-gray-700 bg-gray-950 p-4 font-mono text-xs leading-6\" bind-innerhtml=\"revisionDiffHtml\"></pre>\n </div>\n <div class=\"flex items-center justify-between border-t border-gray-800 px-4 py-3\">\n <button type=\"button\" on-click=\"navigateRevision(-1)\" bind-disabled=\"revisionLoading || revisionNumber <= 1\" class=\"inline-flex items-center gap-2 rounded-lg border border-gray-700 px-3 py-2 text-sm text-gray-200 outline-none hover:bg-gray-800 focus-visible:ring-2 focus-visible:ring-indigo-400/60 disabled:opacity-40\">\n <lucide-icon icon=\"chevron-left\" size=\"16\"></lucide-icon>Previous\n </button>\n <button type=\"button\" on-click=\"navigateRevision(1)\" bind-disabled=\"revisionLoading || revisionNumber >= revision\" class=\"inline-flex items-center gap-2 rounded-lg border border-gray-700 px-3 py-2 text-sm text-gray-200 outline-none hover:bg-gray-800 focus-visible:ring-2 focus-visible:ring-indigo-400/60 disabled:opacity-40\">\n Next<lucide-icon icon=\"chevron-right\" size=\"16\"></lucide-icon>\n </button>\n </div>\n </div>\n </div>\n </template>\n\n <section\n class=\"secrets-panel rounded-2xl border border-gray-800 bg-gray-900/80 p-4 shadow-xl shadow-black/10 sm:p-5\"\n aria-labelledby=\"secrets-title\"\n >\n <div class=\"mb-5 flex items-start justify-between gap-3\">\n <div class=\"flex items-start gap-3\">\n <span class=\"rounded-lg bg-indigo-500/10 p-2 text-indigo-300\"\n ><lucide-icon icon=\"key-round\" size=\"18\"></lucide-icon\n ></span>\n <div>\n <h2 id=\"secrets-title\" class=\"text-lg font-semibold text-white\">Secrets</h2>\n <p class=\"mt-0.5 text-sm text-gray-400\">Write-only credentials available to workflows.</p>\n </div>\n </div>\n <span\n class=\"rounded-full border border-gray-700 bg-gray-950 px-2.5 py-1 text-xs font-mono text-gray-400\"\n aria-label=\"Secret count\"\n >{{ secrets.length }}</span\n >\n </div>\n <details ref=\"secretForm\" class=\"mb-5 overflow-hidden rounded-xl border border-gray-800 bg-gray-950/50\">\n <summary class=\"flex cursor-pointer list-none items-center justify-between px-4 py-3 text-sm font-medium text-gray-300 outline-none hover:bg-gray-900 focus-visible:ring-2 focus-visible:ring-indigo-400/60\">\n <span>Add a secret</span>\n <lucide-icon icon=\"plus\" size=\"17\"></lucide-icon>\n </summary>\n <div class=\"space-y-3 border-t border-gray-800 p-4\">\n <p class=\"text-xs text-gray-500\">Saving an existing name replaces its encrypted value.</p>\n <label class=\"sr-only\" for=\"secret-name\">Secret name</label>\n <input\n id=\"secret-name\"\n bind-value=\"secretName\"\n on-input=\"setSecretName($event)\"\n class=\"rounded-lg border border-gray-700 bg-gray-900 px-3 py-2.5 font-mono text-sm uppercase outline-none transition placeholder:text-gray-600 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/30\"\n placeholder=\"NPM_TOKEN\"\n />\n <label class=\"inline-flex items-center gap-2 text-sm text-gray-300\">\n <input type=\"checkbox\" bind-checked=\"fileMode\" on-change=\"setFileMode($event)\" class=\"h-4 w-4 rounded border-gray-700 bg-gray-900 text-indigo-500 focus:ring-2 focus:ring-indigo-500/30\" />\n Binary file secret\n </label>\n <template if=\"!fileMode\">\n <label class=\"sr-only\" for=\"secret-value\">Text secret value</label>\n <input\n id=\"secret-value\"\n ref=\"secretValueInput\"\n bind-value=\"secretValue\"\n on-input=\"setSecretValue($event)\"\n type=\"password\"\n class=\"rounded-lg border border-gray-700 bg-gray-900 px-3 py-2.5 font-mono text-sm outline-none transition placeholder:text-gray-600 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/30\"\n placeholder=\"New secret value\"\n />\n </template>\n <template if=\"fileMode\">\n <label class=\"sr-only\" for=\"secret-file\">Binary secret file</label>\n <input\n id=\"secret-file\"\n ref=\"secretFileInput\"\n on-change=\"setSecretFile($event)\"\n type=\"file\"\n class=\"rounded-lg border border-gray-700 bg-gray-900 px-3 py-2 text-xs text-gray-400 file:mr-3 file:rounded file:border-0 file:bg-gray-700 file:px-2 file:py-1 file:text-xs file:text-gray-200 focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/30\"\n />\n </template>\n <div>\n <button\n type=\"button\"\n aria-label=\"Save secret value\"\n title=\"Save secret value\"\n on-click=\"saveSecret()\"\n bind-disabled=\"busy\"\n class=\"inline-flex items-center justify-center gap-2 rounded-lg border border-indigo-500/60 px-3 py-2.5 text-sm font-medium text-indigo-200 outline-none transition hover:bg-indigo-500/10 focus-visible:ring-2 focus-visible:ring-indigo-400/60 disabled:opacity-50\"\n >\n <lucide-icon icon=\"lock-keyhole\" size=\"16\"></lucide-icon>Save secret\n </button>\n </div>\n </div>\n </div>\n </details>\n <ul class=\"grid gap-2\" aria-label=\"Saved secrets\">\n <template for=\"name of secrets\">\n <li>\n <div class=\"flex min-h-14 items-center gap-2 rounded-xl border border-gray-800 bg-gray-950/50 px-3.5 py-3\">\n <button\n type=\"button\"\n on-click=\"selectSecret(name)\"\n class=\"group flex min-w-0 flex-1 items-center gap-3 text-left outline-none focus-visible:ring-2 focus-visible:ring-indigo-400/50\"\n aria-label=\"Edit secret {{ name }}\"\n >\n <span\n class=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-gray-800 text-gray-500 group-hover:text-indigo-300\"\n ><lucide-icon icon=\"key-round\" size=\"15\"></lucide-icon\n ></span>\n <span class=\"min-w-0 flex-1 truncate font-mono text-sm text-gray-200\">{{ name }}</span>\n <span class=\"text-xs text-gray-500\">Select</span>\n <lucide-icon icon=\"chevron-right\" size=\"16\" class=\"text-gray-600 transition group-hover:text-indigo-300\"></lucide-icon>\n </button>\n <button\n type=\"button\"\n on-click=\"removeSecret(name)\"\n aria-label=\"Delete secret {{ name }}\"\n title=\"Delete secret\"\n class=\"inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-rose-300 outline-none transition hover:bg-rose-500/10 focus-visible:ring-2 focus-visible:ring-rose-400/60\"\n >\n <lucide-icon icon=\"trash\" size=\"15\"></lucide-icon>\n </button>\n </div>\n </li>\n </template>\n </ul>\n <div\n class=\"rounded-xl border border-dashed border-gray-700 px-4 py-8 text-center\"\n class-hidden=\"secrets.length > 0\"\n >\n <lucide-icon icon=\"key-round\" size=\"22\" class=\"mx-auto text-gray-600\"></lucide-icon>\n <p class=\"mt-2 text-sm font-medium text-gray-300\">No secrets configured</p>\n <p class=\"mt-1 text-xs text-gray-500\">Add one above to make it available to a workflow.</p>\n </div>\n </section>\n </main>\n\n <script setup>\n import { onDestroy, onInit, ref, templateRef } from '@li3/web';\n import { diffLines } from 'diff';\n\n export default function () {\n const page = document.body.dataset.page;\n const initialId = __WORKFLOW_ID__;\n const initialRevision = __WORKFLOW_REVISION__;\n const readOnly = Boolean(initialRevision);\n const workflows = ref([]);\n const secrets = ref([]);\n const source = ref('');\n const validation = ref({ valid: true });\n const savedSource = ref('');\n const revision = ref(null);\n const revisionDialogOpen = ref(false);\n const revisionNumber = ref(0);\n const revisionDiffHtml = ref('');\n const revisionError = ref('');\n const revisionLoading = ref(false);\n const workflowId = ref('');\n const enabled = ref(true);\n const savedEnabled = ref(true);\n const selectedId = ref('');\n const secretName = ref('');\n const secretValue = ref('');\n const fileMode = ref(false);\n const secretFileName = ref('');\n const secretFileData = ref('');\n const notice = ref('');\n const noticeError = ref(false);\n const busy = ref(false);\n const secretValueInput = templateRef('secretValueInput');\n const secretFileInput = templateRef('secretFileInput');\n const secretForm = templateRef('secretForm');\n const helpContent = templateRef('helpContent');\n const helpLoaded = ref(false);\n const helpLoading = ref(false);\n let validationTimer;\n\n const showNotice = (message, error = false) => {\n notice.value = message;\n noticeError.value = error;\n };\n\n const api = async (url, options = {}) => {\n const response = await fetch(url, {\n headers: { accept: 'application/json', ...(options.body ? { 'content-type': 'application/json' } : {}) },\n ...options,\n });\n const body = response.status === 204 ? null : await response.json().catch(() => ({}));\n if (!response.ok) throw new Error(body.error || `Request failed: ${response.status}`);\n return body;\n };\n\n const derivedId = () =>\n source.value\n .match(/^\\s*(?:id:\\s*([^\\n]+)|name:\\s*([^\\n]+))/m)\n ?.slice(1)\n .find(Boolean)\n ?.trim()\n .toLowerCase()\n .replace(/[^a-z0-9]/g, '-')\n .replace(/(^-|-$)/g, '') || '';\n\n const run = async (action) => {\n if (busy.value) return;\n\n busy.value = true;\n\n try {\n await action();\n } catch (error) {\n showNotice(error.message, true);\n } finally {\n busy.value = false;\n }\n };\n\n const loadWorkflows = async () => {\n workflows.value = (await api('/api/workflows')).workflows;\n };\n\n const loadSecrets = async () => {\n secrets.value = (await api('/api/secrets')).secrets;\n };\n\n const openWorkflow = async (id) => {\n const workflowUrl = initialRevision\n ? `/api/workflows/${id}?revision=${initialRevision}`\n : `/api/workflows/${id}`;\n const workflow = await api(workflowUrl);\n selectedId.value = workflow.id;\n workflowId.value = workflow.id;\n source.value = workflow.sourceYaml;\n savedSource.value = workflow.sourceYaml;\n enabled.value = workflow.enabled;\n savedEnabled.value = workflow.enabled;\n revision.value = workflow.revision || null;\n };\n\n const validateSource = async () => {\n return api('/api/workflows/validate', {\n method: 'POST',\n body: JSON.stringify({ sourceYaml: source.value }),\n });\n };\n\n const validate = (ms = 1000) => {\n if (page !== 'editor') return;\n\n clearTimeout(validationTimer);\n validationTimer = setTimeout(() => {\n validation.value = { ...validation.value, running: true, error: '' };\n void validateSource()\n .then((result) => {\n validation.value = { ...result, running: false };\n })\n .catch((error) => {\n validation.value = { valid: false, running: false, error: error.message };\n \n });\n }, ms);\n };\n\n const save = () =>\n run(async () => {\n const id = workflowId.value.trim() || derivedId();\n if (!id) throw new Error('Set an ID or add a workflow name first.');\n if (\n initialId &&\n id === selectedId.value &&\n source.value === savedSource.value &&\n enabled.value === savedEnabled.value\n ) {\n showNotice('No changes to save.');\n return;\n }\n const workflow = await api(`/api/workflows/${id}`, {\n method: 'PUT',\n body: JSON.stringify({ sourceYaml: source.value, enabled: enabled.value }),\n });\n selectedId.value = workflow.id;\n workflowId.value = workflow.id;\n savedSource.value = source.value;\n savedEnabled.value = enabled.value;\n revision.value = workflow.revision;\n showNotice(`Saved ${workflow.id} as draft revision ${workflow.revision}.`);\n if (!initialId) history.replaceState(null, '', `/workflows/${workflow.id}`);\n });\n const publish = () =>\n run(async () => {\n const id = workflowId.value.trim() || selectedId.value;\n if (!id) throw new Error('Save a workflow before publishing it.');\n const workflow = await api(`/api/workflows/${id}/publish`, { method: 'POST' });\n selectedId.value = workflow.id;\n revision.value = workflow.revision;\n showNotice(`Published ${workflow.id} revision ${workflow.revision}.`);\n });\n const remove = () =>\n run(async () => {\n const id = workflowId.value.trim() || selectedId.value;\n if (!id || !confirm(`Delete ${id} and all of its revisions?`)) return;\n await api(`/api/workflows/${id}`, { method: 'DELETE' });\n window.location.href = '/workflows';\n });\n const saveSecret = () =>\n run(async () => {\n const name = secretName.value.trim();\n if (!name || (fileMode.value ? !secretFileData.value : !secretValue.value)) throw new Error(fileMode.value ? 'Choose a file first.' : 'Set a secret value first.');\n await api(`/api/secrets/${name}`, {\n method: 'PUT',\n body: JSON.stringify(fileMode.value ? { value: secretFileData.value, encoding: 'base64', originalName: secretFileName.value } : { value: secretValue.value, encoding: 'utf8' }),\n });\n secretValue.value = '';\n secretFileName.value = '';\n secretFileData.value = '';\n fileMode.value = false;\n if (secretFileInput.value) secretFileInput.value.value = '';\n if (secretForm.value) secretForm.value.open = false;\n await loadSecrets();\n showNotice(`Saved ${name}.`);\n });\n const removeSecret = (requestedName = '') =>\n run(async () => {\n const name = requestedName || secretName.value.trim();\n if (!name || !confirm(`Delete ${name}?`)) return;\n await api(`/api/secrets/${name}`, { method: 'DELETE' });\n if (secretName.value.trim() === name) {\n secretName.value = '';\n secretValue.value = '';\n secretFileName.value = '';\n secretFileData.value = '';\n fileMode.value = false;\n if (secretFileInput.value) secretFileInput.value.value = '';\n }\n await loadSecrets();\n showNotice(`Deleted ${name}.`);\n });\n const setSource = (value) => {\n source.value = value;\n validate();\n };\n const setWorkflowId = (event) => {\n workflowId.value = event.target.value;\n };\n const setEnabled = (event) => {\n enabled.value = event.target.checked;\n };\n const setSecretName = (event) => {\n secretName.value = event.target.value;\n };\n const setSecretValue = (event) => {\n secretValue.value = event.target.value;\n fileMode.value = false;\n if (secretValue.value) {\n secretFileName.value = '';\n secretFileData.value = '';\n if (secretFileInput.value) secretFileInput.value.value = '';\n }\n };\n const setFileMode = (event) => {\n fileMode.value = event.target.checked;\n if (!fileMode.value) {\n secretFileName.value = '';\n secretFileData.value = '';\n if (secretFileInput.value) secretFileInput.value.value = '';\n } else {\n secretValue.value = '';\n }\n };\n const setSecretFile = async (event) => {\n const file = event.target.files?.[0];\n if (!file) return;\n const bytes = new Uint8Array(await file.arrayBuffer());\n let binary = '';\n for (let index = 0; index < bytes.length; index += 0x8000) {\n binary += String.fromCharCode(...bytes.subarray(index, index + 0x8000));\n }\n secretFileName.value = file.name;\n secretFileData.value = btoa(binary);\n secretValue.value = '';\n };\n const selectSecret = (name) => {\n secretName.value = name;\n secretValueInput.value?.focus();\n };\n const visitWorkflow = (id) => {\n window.location.href = `/workflows/${id}`;\n };\n const loadHelp = async (event) => {\n if (!event.target.open || helpLoaded.value || helpLoading.value || !helpContent.value) return;\n helpLoading.value = true;\n helpContent.value.textContent = 'Loading workflow syntax help...';\n try {\n const response = await fetch('/help?embed=1', { headers: { accept: 'text/html' } });\n if (!response.ok) throw new Error(`Help request failed: ${response.status}`);\n const html = await response.text();\n const parsed = new DOMParser().parseFromString(html, 'text/html');\n const sourceNodes = [\n ...Array.from(parsed.head.querySelectorAll('style')),\n ...Array.from(parsed.body.childNodes),\n ];\n const nodes = sourceNodes.map((node) => document.importNode(node, true));\n helpContent.value.replaceChildren(...nodes);\n helpLoaded.value = true;\n } catch (error) {\n helpContent.value.textContent = 'Unable to load workflow syntax help.';\n console.error(error);\n } finally {\n helpLoading.value = false;\n }\n };\n\n const escapeRevisionHtml = (value) => value.replace(/[&<>\"']/g, (character) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' })[character] || '');\n const renderRevisionDiff = (previousSource, currentSource) => {\n if (previousSource === null) return `<span class=\"text-emerald-300\">+ ${escapeRevisionHtml(currentSource)}</span>\\n`;\n return diffLines(previousSource, currentSource).map((part) => {\n const className = part.added ? 'text-emerald-300 bg-emerald-500/10' : part.removed ? 'text-rose-300 bg-rose-500/10' : 'text-gray-300';\n const prefix = part.added ? '+ ' : part.removed ? '- ' : ' ';\n return part.value.split('\\n').filter((line, index, lines) => index < lines.length - 1 || line).map((line) => `<span class=\"block ${className}\">${prefix}${escapeRevisionHtml(line)}</span>`).join('');\n }).join('');\n };\n const openRevisionDialog = async () => {\n if (!revision.value) return;\n revisionNumber.value = revision.value;\n revisionDiffHtml.value = '';\n revisionError.value = '';\n revisionDialogOpen.value = true;\n await loadRevisionDiff(revision.value);\n };\n const closeRevisionDialog = () => {\n revisionDialogOpen.value = false;\n };\n const loadRevisionDiff = async (number) => {\n revisionLoading.value = true;\n revisionError.value = '';\n try {\n const current = await api(`/api/workflows/${selectedId.value}?revision=${number}`);\n const previous = number > 1 ? await api(`/api/workflows/${selectedId.value}?revision=${number - 1}`) : null;\n revisionDiffHtml.value = renderRevisionDiff(previous?.sourceYaml ?? null, current.sourceYaml);\n } catch (error) {\n revisionError.value = error.message;\n } finally {\n revisionLoading.value = false;\n }\n };\n const navigateRevision = async (offset) => {\n if (!selectedId.value || revisionLoading.value) return;\n const target = revisionNumber.value + offset;\n if (target < 1 || target > revision.value) return;\n revisionNumber.value = target;\n await loadRevisionDiff(target);\n };\n\n onDestroy(() => clearTimeout(validationTimer));\n\n onInit(() => {\n const loadPage = page === 'editor'\n ? initialId ? openWorkflow(initialId) : Promise.resolve()\n : page === 'secrets' ? loadSecrets() : loadWorkflows();\n loadPage.catch((error) => showNotice(error.message, true));\n });\n\n return {\n page,\n workflows,\n secrets,\n source,\n validation,\n revision,\n revisionDialogOpen,\n revisionNumber,\n revisionDiffHtml,\n revisionError,\n revisionLoading,\n workflowId,\n enabled,\n readOnly,\n selectedId,\n secretName,\n secretValue,\n fileMode,\n secretFileName,\n secretFileData,\n notice,\n noticeError,\n busy,\n validate,\n save,\n publish,\n remove,\n saveSecret,\n removeSecret,\n setSource,\n setWorkflowId,\n setEnabled,\n setSecretName,\n setSecretValue,\n setFileMode,\n setSecretFile,\n selectSecret,\n visitWorkflow,\n loadHelp,\n openRevisionDialog,\n closeRevisionDialog,\n navigateRevision,\n };\n }\n <\/script>\n </template>\n\n <script type=\"module\">\n import '@li3/web';\n <\/script>\n <script src=\"https://cdn.tailwindcss.com\"><\/script>\n </body>\n</html>\n";
6291
6368
  //#endregion
6292
6369
  //#region src/workflows-ui.ts
6293
- function Xi(e, t = "", n) {
6294
- return Yi.replace("__WORKFLOW_PAGE__", e).replace("__WORKFLOW_ID__", JSON.stringify(t)).replace("__WORKFLOW_REVISION__", JSON.stringify(n ?? null));
6370
+ function $i(e, t = "", n) {
6371
+ return Qi.replace("__WORKFLOW_PAGE__", e).replace("__WORKFLOW_ID__", JSON.stringify(t)).replace("__WORKFLOW_REVISION__", JSON.stringify(n ?? null));
6295
6372
  }
6296
6373
  //#endregion
6297
6374
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/nodes/identity.js
6298
- var Zi = Symbol.for("yaml.alias"), Qi = Symbol.for("yaml.document"), $i = Symbol.for("yaml.map"), ea = Symbol.for("yaml.pair"), ta = Symbol.for("yaml.scalar"), na = Symbol.for("yaml.seq"), G = Symbol.for("yaml.node.type"), ra = (e) => !!e && typeof e == "object" && e[G] === Zi, ia = (e) => !!e && typeof e == "object" && e[G] === Qi, aa = (e) => !!e && typeof e == "object" && e[G] === $i, K = (e) => !!e && typeof e == "object" && e[G] === ea, q = (e) => !!e && typeof e == "object" && e[G] === ta, oa = (e) => !!e && typeof e == "object" && e[G] === na;
6375
+ var ea = Symbol.for("yaml.alias"), ta = Symbol.for("yaml.document"), na = Symbol.for("yaml.map"), ra = Symbol.for("yaml.pair"), ia = Symbol.for("yaml.scalar"), aa = Symbol.for("yaml.seq"), G = Symbol.for("yaml.node.type"), oa = (e) => !!e && typeof e == "object" && e[G] === ea, sa = (e) => !!e && typeof e == "object" && e[G] === ta, ca = (e) => !!e && typeof e == "object" && e[G] === na, K = (e) => !!e && typeof e == "object" && e[G] === ra, q = (e) => !!e && typeof e == "object" && e[G] === ia, la = (e) => !!e && typeof e == "object" && e[G] === aa;
6299
6376
  function J(e) {
6300
6377
  if (e && typeof e == "object") switch (e[G]) {
6301
- case $i:
6302
- case na: return !0;
6378
+ case na:
6379
+ case aa: return !0;
6303
6380
  }
6304
6381
  return !1;
6305
6382
  }
6306
6383
  function Y(e) {
6307
6384
  if (e && typeof e == "object") switch (e[G]) {
6308
- case Zi:
6309
- case $i:
6310
- case ta:
6311
- case na: return !0;
6385
+ case ea:
6386
+ case na:
6387
+ case ia:
6388
+ case aa: return !0;
6312
6389
  }
6313
6390
  return !1;
6314
6391
  }
6315
- var sa = (e) => (q(e) || J(e)) && !!e.anchor, X = Symbol("break visit"), ca = Symbol("skip children"), la = Symbol("remove node");
6316
- function ua(e, t) {
6317
- let n = ma(t);
6318
- ia(e) ? da(null, e.contents, n, Object.freeze([e])) === la && (e.contents = null) : da(null, e, n, Object.freeze([]));
6392
+ var ua = (e) => (q(e) || J(e)) && !!e.anchor, X = Symbol("break visit"), da = Symbol("skip children"), fa = Symbol("remove node");
6393
+ function pa(e, t) {
6394
+ let n = _a(t);
6395
+ sa(e) ? ma(null, e.contents, n, Object.freeze([e])) === fa && (e.contents = null) : ma(null, e, n, Object.freeze([]));
6319
6396
  }
6320
- ua.BREAK = X, ua.SKIP = ca, ua.REMOVE = la;
6321
- function da(e, t, n, r) {
6322
- let i = ha(e, t, n, r);
6323
- if (Y(i) || K(i)) return ga(e, r, i), da(e, i, n, r);
6397
+ pa.BREAK = X, pa.SKIP = da, pa.REMOVE = fa;
6398
+ function ma(e, t, n, r) {
6399
+ let i = va(e, t, n, r);
6400
+ if (Y(i) || K(i)) return ya(e, r, i), ma(e, i, n, r);
6324
6401
  if (typeof i != "symbol") {
6325
6402
  if (J(t)) {
6326
6403
  r = Object.freeze(r.concat(t));
6327
6404
  for (let e = 0; e < t.items.length; ++e) {
6328
- let i = da(e, t.items[e], n, r);
6405
+ let i = ma(e, t.items[e], n, r);
6329
6406
  if (typeof i == "number") e = i - 1;
6330
6407
  else if (i === X) return X;
6331
- else i === la && (t.items.splice(e, 1), --e);
6408
+ else i === fa && (t.items.splice(e, 1), --e);
6332
6409
  }
6333
6410
  } else if (K(t)) {
6334
6411
  r = Object.freeze(r.concat(t));
6335
- let e = da("key", t.key, n, r);
6412
+ let e = ma("key", t.key, n, r);
6336
6413
  if (e === X) return X;
6337
- e === la && (t.key = null);
6338
- let i = da("value", t.value, n, r);
6414
+ e === fa && (t.key = null);
6415
+ let i = ma("value", t.value, n, r);
6339
6416
  if (i === X) return X;
6340
- i === la && (t.value = null);
6417
+ i === fa && (t.value = null);
6341
6418
  }
6342
6419
  }
6343
6420
  return i;
6344
6421
  }
6345
- async function fa(e, t) {
6346
- let n = ma(t);
6347
- ia(e) ? await pa(null, e.contents, n, Object.freeze([e])) === la && (e.contents = null) : await pa(null, e, n, Object.freeze([]));
6422
+ async function ha(e, t) {
6423
+ let n = _a(t);
6424
+ sa(e) ? await ga(null, e.contents, n, Object.freeze([e])) === fa && (e.contents = null) : await ga(null, e, n, Object.freeze([]));
6348
6425
  }
6349
- fa.BREAK = X, fa.SKIP = ca, fa.REMOVE = la;
6350
- async function pa(e, t, n, r) {
6351
- let i = await ha(e, t, n, r);
6352
- if (Y(i) || K(i)) return ga(e, r, i), pa(e, i, n, r);
6426
+ ha.BREAK = X, ha.SKIP = da, ha.REMOVE = fa;
6427
+ async function ga(e, t, n, r) {
6428
+ let i = await va(e, t, n, r);
6429
+ if (Y(i) || K(i)) return ya(e, r, i), ga(e, i, n, r);
6353
6430
  if (typeof i != "symbol") {
6354
6431
  if (J(t)) {
6355
6432
  r = Object.freeze(r.concat(t));
6356
6433
  for (let e = 0; e < t.items.length; ++e) {
6357
- let i = await pa(e, t.items[e], n, r);
6434
+ let i = await ga(e, t.items[e], n, r);
6358
6435
  if (typeof i == "number") e = i - 1;
6359
6436
  else if (i === X) return X;
6360
- else i === la && (t.items.splice(e, 1), --e);
6437
+ else i === fa && (t.items.splice(e, 1), --e);
6361
6438
  }
6362
6439
  } else if (K(t)) {
6363
6440
  r = Object.freeze(r.concat(t));
6364
- let e = await pa("key", t.key, n, r);
6441
+ let e = await ga("key", t.key, n, r);
6365
6442
  if (e === X) return X;
6366
- e === la && (t.key = null);
6367
- let i = await pa("value", t.value, n, r);
6443
+ e === fa && (t.key = null);
6444
+ let i = await ga("value", t.value, n, r);
6368
6445
  if (i === X) return X;
6369
- i === la && (t.value = null);
6446
+ i === fa && (t.value = null);
6370
6447
  }
6371
6448
  }
6372
6449
  return i;
6373
6450
  }
6374
- function ma(e) {
6451
+ function _a(e) {
6375
6452
  return typeof e == "object" && (e.Collection || e.Node || e.Value) ? Object.assign({
6376
6453
  Alias: e.Node,
6377
6454
  Map: e.Node,
@@ -6386,34 +6463,34 @@ function ma(e) {
6386
6463
  Seq: e.Collection
6387
6464
  }, e) : e;
6388
6465
  }
6389
- function ha(e, t, n, r) {
6466
+ function va(e, t, n, r) {
6390
6467
  if (typeof n == "function") return n(e, t, r);
6391
- if (aa(t)) return n.Map?.(e, t, r);
6392
- if (oa(t)) return n.Seq?.(e, t, r);
6468
+ if (ca(t)) return n.Map?.(e, t, r);
6469
+ if (la(t)) return n.Seq?.(e, t, r);
6393
6470
  if (K(t)) return n.Pair?.(e, t, r);
6394
6471
  if (q(t)) return n.Scalar?.(e, t, r);
6395
- if (ra(t)) return n.Alias?.(e, t, r);
6472
+ if (oa(t)) return n.Alias?.(e, t, r);
6396
6473
  }
6397
- function ga(e, t, n) {
6474
+ function ya(e, t, n) {
6398
6475
  let r = t[t.length - 1];
6399
6476
  if (J(r)) r.items[e] = n;
6400
6477
  else if (K(r)) e === "key" ? r.key = n : r.value = n;
6401
- else if (ia(r)) r.contents = n;
6478
+ else if (sa(r)) r.contents = n;
6402
6479
  else {
6403
- let e = ra(r) ? "alias" : "scalar";
6480
+ let e = oa(r) ? "alias" : "scalar";
6404
6481
  throw Error(`Cannot replace node with ${e} parent`);
6405
6482
  }
6406
6483
  }
6407
6484
  //#endregion
6408
6485
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/doc/directives.js
6409
- var _a = {
6486
+ var ba = {
6410
6487
  "!": "%21",
6411
6488
  ",": "%2C",
6412
6489
  "[": "%5B",
6413
6490
  "]": "%5D",
6414
6491
  "{": "%7B",
6415
6492
  "}": "%7D"
6416
- }, va = (e) => e.replace(/[!,[\]{}]/g, (e) => _a[e]), ya = class e {
6493
+ }, xa = (e) => e.replace(/[!,[\]{}]/g, (e) => ba[e]), Sa = class e {
6417
6494
  constructor(t, n) {
6418
6495
  this.docStart = null, this.docEnd = !1, this.yaml = Object.assign({}, e.defaultYaml, t), this.tags = Object.assign({}, e.defaultTags, n);
6419
6496
  }
@@ -6476,14 +6553,14 @@ var _a = {
6476
6553
  return n === "!" ? e : (t(`Could not resolve tag: ${e}`), null);
6477
6554
  }
6478
6555
  tagString(e) {
6479
- for (let [t, n] of Object.entries(this.tags)) if (e.startsWith(n)) return t + va(e.substring(n.length));
6556
+ for (let [t, n] of Object.entries(this.tags)) if (e.startsWith(n)) return t + xa(e.substring(n.length));
6480
6557
  return e[0] === "!" ? e : `!<${e}>`;
6481
6558
  }
6482
6559
  toString(e) {
6483
6560
  let t = this.yaml.explicit ? [`%YAML ${this.yaml.version || "1.2"}`] : [], n = Object.entries(this.tags), r;
6484
6561
  if (e && n.length > 0 && Y(e.contents)) {
6485
6562
  let t = {};
6486
- ua(e.contents, (e, n) => {
6563
+ pa(e.contents, (e, n) => {
6487
6564
  Y(n) && n.tag && (t[n.tag] = !0);
6488
6565
  }), r = Object.keys(t);
6489
6566
  } else r = [];
@@ -6491,37 +6568,37 @@ var _a = {
6491
6568
  return t.join("\n");
6492
6569
  }
6493
6570
  };
6494
- ya.defaultYaml = {
6571
+ Sa.defaultYaml = {
6495
6572
  explicit: !1,
6496
6573
  version: "1.2"
6497
- }, ya.defaultTags = { "!!": "tag:yaml.org,2002:" };
6574
+ }, Sa.defaultTags = { "!!": "tag:yaml.org,2002:" };
6498
6575
  //#endregion
6499
6576
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/doc/anchors.js
6500
- function ba(e) {
6577
+ function Ca(e) {
6501
6578
  if (/[\x00-\x19\s,[\]{}]/.test(e)) {
6502
6579
  let t = `Anchor must not contain whitespace or control characters: ${JSON.stringify(e)}`;
6503
6580
  throw Error(t);
6504
6581
  }
6505
6582
  return !0;
6506
6583
  }
6507
- function xa(e) {
6584
+ function wa(e) {
6508
6585
  let t = /* @__PURE__ */ new Set();
6509
- return ua(e, { Value(e, n) {
6586
+ return pa(e, { Value(e, n) {
6510
6587
  n.anchor && t.add(n.anchor);
6511
6588
  } }), t;
6512
6589
  }
6513
- function Sa(e, t) {
6590
+ function Ta(e, t) {
6514
6591
  for (let n = 1;; ++n) {
6515
6592
  let r = `${e}${n}`;
6516
6593
  if (!t.has(r)) return r;
6517
6594
  }
6518
6595
  }
6519
- function Ca(e, t) {
6596
+ function Ea(e, t) {
6520
6597
  let n = [], r = /* @__PURE__ */ new Map(), i = null;
6521
6598
  return {
6522
6599
  onAnchor: (r) => {
6523
- n.push(r), i ??= xa(e);
6524
- let a = Sa(t, i);
6600
+ n.push(r), i ??= wa(e);
6601
+ let a = Ta(t, i);
6525
6602
  return i.add(a), a;
6526
6603
  },
6527
6604
  setAnchors: () => {
@@ -6539,22 +6616,22 @@ function Ca(e, t) {
6539
6616
  }
6540
6617
  //#endregion
6541
6618
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/doc/applyReviver.js
6542
- function wa(e, t, n, r) {
6619
+ function Da(e, t, n, r) {
6543
6620
  if (r && typeof r == "object") {
6544
6621
  if (Array.isArray(r)) for (let t = 0, n = r.length; t < n; ++t) {
6545
- let n = r[t], i = wa(e, r, String(t), n);
6622
+ let n = r[t], i = Da(e, r, String(t), n);
6546
6623
  i === void 0 ? delete r[t] : i !== n && (r[t] = i);
6547
6624
  }
6548
6625
  else if (r instanceof Map) for (let t of Array.from(r.keys())) {
6549
- let n = r.get(t), i = wa(e, r, t, n);
6626
+ let n = r.get(t), i = Da(e, r, t, n);
6550
6627
  i === void 0 ? r.delete(t) : i !== n && r.set(t, i);
6551
6628
  }
6552
6629
  else if (r instanceof Set) for (let t of Array.from(r)) {
6553
- let n = wa(e, r, t, t);
6630
+ let n = Da(e, r, t, t);
6554
6631
  n === void 0 ? r.delete(t) : n !== t && (r.delete(t), r.add(n));
6555
6632
  }
6556
6633
  else for (let [t, n] of Object.entries(r)) {
6557
- let i = wa(e, r, t, n);
6634
+ let i = Da(e, r, t, n);
6558
6635
  i === void 0 ? delete r[t] : i !== n && (r[t] = i);
6559
6636
  }
6560
6637
  }
@@ -6562,10 +6639,10 @@ function wa(e, t, n, r) {
6562
6639
  }
6563
6640
  //#endregion
6564
6641
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/nodes/toJS.js
6565
- function Ta(e, t, n) {
6566
- if (Array.isArray(e)) return e.map((e, t) => Ta(e, String(t), n));
6642
+ function Oa(e, t, n) {
6643
+ if (Array.isArray(e)) return e.map((e, t) => Oa(e, String(t), n));
6567
6644
  if (e && typeof e.toJSON == "function") {
6568
- if (!n || !sa(e)) return e.toJSON(t, n);
6645
+ if (!n || !ua(e)) return e.toJSON(t, n);
6569
6646
  let r = {
6570
6647
  aliasCount: 0,
6571
6648
  count: 1,
@@ -6581,7 +6658,7 @@ function Ta(e, t, n) {
6581
6658
  }
6582
6659
  //#endregion
6583
6660
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/nodes/Node.js
6584
- var Ea = class {
6661
+ var ka = class {
6585
6662
  constructor(e) {
6586
6663
  Object.defineProperty(this, G, { value: e });
6587
6664
  }
@@ -6590,7 +6667,7 @@ var Ea = class {
6590
6667
  return this.range && (e.range = this.range.slice()), e;
6591
6668
  }
6592
6669
  toJS(e, { mapAsMap: t, maxAliasCount: n, onAnchor: r, reviver: i } = {}) {
6593
- if (!ia(e)) throw TypeError("A document argument is required");
6670
+ if (!sa(e)) throw TypeError("A document argument is required");
6594
6671
  let a = {
6595
6672
  anchors: /* @__PURE__ */ new Map(),
6596
6673
  doc: e,
@@ -6598,21 +6675,21 @@ var Ea = class {
6598
6675
  mapAsMap: t === !0,
6599
6676
  mapKeyWarned: !1,
6600
6677
  maxAliasCount: typeof n == "number" ? n : 100
6601
- }, o = Ta(this, "", a);
6678
+ }, o = Oa(this, "", a);
6602
6679
  if (typeof r == "function") for (let { count: e, res: t } of a.anchors.values()) r(t, e);
6603
- return typeof i == "function" ? wa(i, { "": o }, "", o) : o;
6680
+ return typeof i == "function" ? Da(i, { "": o }, "", o) : o;
6604
6681
  }
6605
- }, Da = class extends Ea {
6682
+ }, Aa = class extends ka {
6606
6683
  constructor(e) {
6607
- super(Zi), this.source = e, Object.defineProperty(this, "tag", { set() {
6684
+ super(ea), this.source = e, Object.defineProperty(this, "tag", { set() {
6608
6685
  throw Error("Alias nodes cannot have tags");
6609
6686
  } });
6610
6687
  }
6611
6688
  resolve(e, t) {
6612
6689
  if (t?.maxAliasCount === 0) throw ReferenceError("Alias resolution is disabled");
6613
6690
  let n;
6614
- t?.aliasResolveCache ? n = t.aliasResolveCache : (n = [], ua(e, { Node: (e, t) => {
6615
- (ra(t) || sa(t)) && n.push(t);
6691
+ t?.aliasResolveCache ? n = t.aliasResolveCache : (n = [], pa(e, { Node: (e, t) => {
6692
+ (oa(t) || ua(t)) && n.push(t);
6616
6693
  } }), t && (t.aliasResolveCache = n));
6617
6694
  let r;
6618
6695
  for (let e of n) {
@@ -6630,14 +6707,14 @@ var Ea = class {
6630
6707
  }
6631
6708
  let o = n.get(a);
6632
6709
  /* istanbul ignore if */
6633
- if (o ||= (Ta(a, null, t), n.get(a)), o?.res === void 0) throw ReferenceError("This should not happen: Alias anchor was not resolved?");
6634
- if (i >= 0 && (o.count += 1, o.aliasCount === 0 && (o.aliasCount = Oa(r, a, n)), o.count * o.aliasCount > i)) throw ReferenceError("Excessive alias count indicates a resource exhaustion attack");
6710
+ if (o ||= (Oa(a, null, t), n.get(a)), o?.res === void 0) throw ReferenceError("This should not happen: Alias anchor was not resolved?");
6711
+ if (i >= 0 && (o.count += 1, o.aliasCount === 0 && (o.aliasCount = ja(r, a, n)), o.count * o.aliasCount > i)) throw ReferenceError("Excessive alias count indicates a resource exhaustion attack");
6635
6712
  return o.res;
6636
6713
  }
6637
6714
  toString(e, t, n) {
6638
6715
  let r = `*${this.source}`;
6639
6716
  if (e) {
6640
- if (ba(this.source), e.options.verifyAliasOrder && !e.anchors.has(this.source)) {
6717
+ if (Ca(this.source), e.options.verifyAliasOrder && !e.anchors.has(this.source)) {
6641
6718
  let e = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
6642
6719
  throw Error(e);
6643
6720
  }
@@ -6646,33 +6723,33 @@ var Ea = class {
6646
6723
  return r;
6647
6724
  }
6648
6725
  };
6649
- function Oa(e, t, n) {
6650
- if (ra(t)) {
6726
+ function ja(e, t, n) {
6727
+ if (oa(t)) {
6651
6728
  let r = t.resolve(e), i = n && r && n.get(r);
6652
6729
  return i ? i.count * i.aliasCount : 0;
6653
6730
  }
6654
6731
  if (J(t)) {
6655
6732
  let r = 0;
6656
6733
  for (let i of t.items) {
6657
- let t = Oa(e, i, n);
6734
+ let t = ja(e, i, n);
6658
6735
  t > r && (r = t);
6659
6736
  }
6660
6737
  return r;
6661
6738
  }
6662
6739
  if (K(t)) {
6663
- let r = Oa(e, t.key, n), i = Oa(e, t.value, n);
6740
+ let r = ja(e, t.key, n), i = ja(e, t.value, n);
6664
6741
  return Math.max(r, i);
6665
6742
  }
6666
6743
  return 1;
6667
6744
  }
6668
6745
  //#endregion
6669
6746
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/nodes/Scalar.js
6670
- var ka = (e) => !e || typeof e != "function" && typeof e != "object", Z = class extends Ea {
6747
+ var Ma = (e) => !e || typeof e != "function" && typeof e != "object", Z = class extends ka {
6671
6748
  constructor(e) {
6672
- super(ta), this.value = e;
6749
+ super(ia), this.value = e;
6673
6750
  }
6674
6751
  toJSON(e, t) {
6675
- return t?.keep ? this.value : Ta(this.value, e, t);
6752
+ return t?.keep ? this.value : Oa(this.value, e, t);
6676
6753
  }
6677
6754
  toString() {
6678
6755
  return String(this.value);
@@ -6681,8 +6758,8 @@ var ka = (e) => !e || typeof e != "function" && typeof e != "object", Z = class
6681
6758
  Z.BLOCK_FOLDED = "BLOCK_FOLDED", Z.BLOCK_LITERAL = "BLOCK_LITERAL", Z.PLAIN = "PLAIN", Z.QUOTE_DOUBLE = "QUOTE_DOUBLE", Z.QUOTE_SINGLE = "QUOTE_SINGLE";
6682
6759
  //#endregion
6683
6760
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/doc/createNode.js
6684
- var Aa = "tag:yaml.org,2002:";
6685
- function ja(e, t, n) {
6761
+ var Na = "tag:yaml.org,2002:";
6762
+ function Pa(e, t, n) {
6686
6763
  if (t) {
6687
6764
  let e = n.filter((e) => e.tag === t), r = e.find((e) => !e.format) ?? e[0];
6688
6765
  if (!r) throw Error(`Tag ${t} not found`);
@@ -6690,29 +6767,29 @@ function ja(e, t, n) {
6690
6767
  }
6691
6768
  return n.find((t) => t.identify?.(e) && !t.format);
6692
6769
  }
6693
- function Ma(e, t, n) {
6694
- if (ia(e) && (e = e.contents), Y(e)) return e;
6770
+ function Fa(e, t, n) {
6771
+ if (sa(e) && (e = e.contents), Y(e)) return e;
6695
6772
  if (K(e)) {
6696
- let t = n.schema[$i].createNode?.(n.schema, null, n);
6773
+ let t = n.schema[na].createNode?.(n.schema, null, n);
6697
6774
  return t.items.push(e), t;
6698
6775
  }
6699
6776
  (e instanceof String || e instanceof Number || e instanceof Boolean || typeof BigInt < "u" && e instanceof BigInt) && (e = e.valueOf());
6700
6777
  let { aliasDuplicateObjects: r, onAnchor: i, onTagObj: a, schema: o, sourceObjects: s } = n, c;
6701
6778
  if (r && e && typeof e == "object") {
6702
- if (c = s.get(e), c) return c.anchor ?? (c.anchor = i(e)), new Da(c.anchor);
6779
+ if (c = s.get(e), c) return c.anchor ?? (c.anchor = i(e)), new Aa(c.anchor);
6703
6780
  c = {
6704
6781
  anchor: null,
6705
6782
  node: null
6706
6783
  }, s.set(e, c);
6707
6784
  }
6708
- t?.startsWith("!!") && (t = Aa + t.slice(2));
6709
- let l = ja(e, t, o.tags);
6785
+ t?.startsWith("!!") && (t = Na + t.slice(2));
6786
+ let l = Pa(e, t, o.tags);
6710
6787
  if (!l) {
6711
6788
  if (e && typeof e.toJSON == "function" && (e = e.toJSON()), !e || typeof e != "object") {
6712
6789
  let t = new Z(e);
6713
6790
  return c && (c.node = t), t;
6714
6791
  }
6715
- l = e instanceof Map ? o[$i] : Symbol.iterator in Object(e) ? o[na] : o[$i];
6792
+ l = e instanceof Map ? o[na] : Symbol.iterator in Object(e) ? o[aa] : o[na];
6716
6793
  }
6717
6794
  a && (a(l), delete n.onTagObj);
6718
6795
  let u = l?.createNode ? l.createNode(n.schema, e, n) : typeof l?.nodeClass?.from == "function" ? l.nodeClass.from(n.schema, e, n) : new Z(e);
@@ -6720,7 +6797,7 @@ function Ma(e, t, n) {
6720
6797
  }
6721
6798
  //#endregion
6722
6799
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/nodes/Collection.js
6723
- function Na(e, t, n) {
6800
+ function Ia(e, t, n) {
6724
6801
  let r = n;
6725
6802
  for (let e = t.length - 1; e >= 0; --e) {
6726
6803
  let n = t[e];
@@ -6729,7 +6806,7 @@ function Na(e, t, n) {
6729
6806
  e[n] = r, r = e;
6730
6807
  } else r = /* @__PURE__ */ new Map([[n, r]]);
6731
6808
  }
6732
- return Ma(r, void 0, {
6809
+ return Fa(r, void 0, {
6733
6810
  aliasDuplicateObjects: !1,
6734
6811
  keepUndefined: !1,
6735
6812
  onAnchor: () => {
@@ -6739,7 +6816,7 @@ function Na(e, t, n) {
6739
6816
  sourceObjects: /* @__PURE__ */ new Map()
6740
6817
  });
6741
6818
  }
6742
- var Pa = (e) => e == null || typeof e == "object" && !!e[Symbol.iterator]().next().done, Fa = class extends Ea {
6819
+ var La = (e) => e == null || typeof e == "object" && !!e[Symbol.iterator]().next().done, Ra = class extends ka {
6743
6820
  constructor(e, t) {
6744
6821
  super(e), Object.defineProperty(this, "schema", {
6745
6822
  value: t,
@@ -6753,11 +6830,11 @@ var Pa = (e) => e == null || typeof e == "object" && !!e[Symbol.iterator]().next
6753
6830
  return e && (t.schema = e), t.items = t.items.map((t) => Y(t) || K(t) ? t.clone(e) : t), this.range && (t.range = this.range.slice()), t;
6754
6831
  }
6755
6832
  addIn(e, t) {
6756
- if (Pa(e)) this.add(t);
6833
+ if (La(e)) this.add(t);
6757
6834
  else {
6758
6835
  let [n, ...r] = e, i = this.get(n, !0);
6759
6836
  if (J(i)) i.addIn(r, t);
6760
- else if (i === void 0 && this.schema) this.set(n, Na(this.schema, r, t));
6837
+ else if (i === void 0 && this.schema) this.set(n, Ia(this.schema, r, t));
6761
6838
  else throw Error(`Expected YAML collection at ${n}. Remaining path: ${r}`);
6762
6839
  }
6763
6840
  }
@@ -6791,16 +6868,16 @@ var Pa = (e) => e == null || typeof e == "object" && !!e[Symbol.iterator]().next
6791
6868
  else {
6792
6869
  let e = this.get(n, !0);
6793
6870
  if (J(e)) e.setIn(r, t);
6794
- else if (e === void 0 && this.schema) this.set(n, Na(this.schema, r, t));
6871
+ else if (e === void 0 && this.schema) this.set(n, Ia(this.schema, r, t));
6795
6872
  else throw Error(`Expected YAML collection at ${n}. Remaining path: ${r}`);
6796
6873
  }
6797
6874
  }
6798
- }, Ia = (e) => e.replace(/^(?!$)(?: $)?/gm, "#");
6799
- function La(e, t) {
6875
+ }, za = (e) => e.replace(/^(?!$)(?: $)?/gm, "#");
6876
+ function Ba(e, t) {
6800
6877
  return /^\n+$/.test(e) ? e.substring(1) : t ? e.replace(/^(?! *$)/gm, t) : e;
6801
6878
  }
6802
- var Ra = (e, t, n) => e.endsWith("\n") ? La(n, t) : n.includes("\n") ? "\n" + La(n, t) : (e.endsWith(" ") ? "" : " ") + n, za = "flow", Ba = "block", Va = "quoted";
6803
- function Ha(e, t, n = "flow", { indentAtStart: r, lineWidth: i = 80, minContentWidth: a = 20, onFold: o, onOverflow: s } = {}) {
6879
+ var Va = (e, t, n) => e.endsWith("\n") ? Ba(n, t) : n.includes("\n") ? "\n" + Ba(n, t) : (e.endsWith(" ") ? "" : " ") + n, Ha = "flow", Ua = "block", Wa = "quoted";
6880
+ function Ga(e, t, n = "flow", { indentAtStart: r, lineWidth: i = 80, minContentWidth: a = 20, onFold: o, onOverflow: s } = {}) {
6804
6881
  if (!i || i < 0) return e;
6805
6882
  i < a && (a = 0);
6806
6883
  let c = Math.max(1 + a, 1 + i - t.length);
@@ -6808,7 +6885,7 @@ function Ha(e, t, n = "flow", { indentAtStart: r, lineWidth: i = 80, minContentW
6808
6885
  let l = [], u = {}, d = i - t.length;
6809
6886
  typeof r == "number" && (r > i - Math.max(2, a) ? l.push(0) : d = i - r);
6810
6887
  let f, p, m = !1, h = -1, g = -1, _ = -1;
6811
- n === "block" && (h = Ua(e, h, t.length), h !== -1 && (d = h + c));
6888
+ n === "block" && (h = Ka(e, h, t.length), h !== -1 && (d = h + c));
6812
6889
  for (let r; r = e[h += 1];) {
6813
6890
  if (n === "quoted" && r === "\\") {
6814
6891
  switch (g = h, e[h + 1]) {
@@ -6825,7 +6902,7 @@ function Ha(e, t, n = "flow", { indentAtStart: r, lineWidth: i = 80, minContentW
6825
6902
  }
6826
6903
  _ = h;
6827
6904
  }
6828
- if (r === "\n") n === "block" && (h = Ua(e, h, t.length)), d = h + t.length + c, f = void 0;
6905
+ if (r === "\n") n === "block" && (h = Ka(e, h, t.length)), d = h + t.length + c, f = void 0;
6829
6906
  else {
6830
6907
  if (r === " " && p && p !== " " && p !== "\n" && p !== " ") {
6831
6908
  let t = e[h + 1];
@@ -6852,7 +6929,7 @@ function Ha(e, t, n = "flow", { indentAtStart: r, lineWidth: i = 80, minContentW
6852
6929
  }
6853
6930
  return v;
6854
6931
  }
6855
- function Ua(e, t, n) {
6932
+ function Ka(e, t, n) {
6856
6933
  let r = t, i = t + 1, a = e[i];
6857
6934
  for (; a === " " || a === " ";) if (t < i + n) a = e[++t];
6858
6935
  else {
@@ -6865,12 +6942,12 @@ function Ua(e, t, n) {
6865
6942
  }
6866
6943
  //#endregion
6867
6944
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/stringify/stringifyString.js
6868
- var Wa = (e, t) => ({
6945
+ var qa = (e, t) => ({
6869
6946
  indentAtStart: t ? e.indent.length : e.indentAtStart,
6870
6947
  lineWidth: e.options.lineWidth,
6871
6948
  minContentWidth: e.options.minContentWidth
6872
- }), Ga = (e) => /^(%|---|\.\.\.)/m.test(e);
6873
- function Ka(e, t, n) {
6949
+ }), Ja = (e) => /^(%|---|\.\.\.)/m.test(e);
6950
+ function Ya(e, t, n) {
6874
6951
  if (!t || t < 0) return !1;
6875
6952
  let r = t - n, i = e.length;
6876
6953
  if (i <= r) return !1;
@@ -6880,10 +6957,10 @@ function Ka(e, t, n) {
6880
6957
  }
6881
6958
  return !0;
6882
6959
  }
6883
- function qa(e, t) {
6960
+ function Xa(e, t) {
6884
6961
  let n = JSON.stringify(e);
6885
6962
  if (t.options.doubleQuotedAsJSON) return n;
6886
- let { implicitKey: r } = t, i = t.options.doubleQuotedMinMultiLineLength, a = t.indent || (Ga(e) ? " " : ""), o = "", s = 0;
6963
+ let { implicitKey: r } = t, i = t.options.doubleQuotedMinMultiLineLength, a = t.indent || (Ja(e) ? " " : ""), o = "", s = 0;
6887
6964
  for (let e = 0, t = n[e]; t; t = n[++e]) if (t === " " && n[e + 1] === "\\" && n[e + 2] === "n" && (o += n.slice(s, e) + "\\ ", e += 1, s = e, t = "\\"), t === "\\") switch (n[e + 1]) {
6888
6965
  case "u":
6889
6966
  {
@@ -6928,32 +7005,32 @@ function qa(e, t) {
6928
7005
  break;
6929
7006
  default: e += 1;
6930
7007
  }
6931
- return o = s ? o + n.slice(s) : n, r ? o : Ha(o, a, Va, Wa(t, !1));
7008
+ return o = s ? o + n.slice(s) : n, r ? o : Ga(o, a, Wa, qa(t, !1));
6932
7009
  }
6933
- function Ja(e, t) {
6934
- if (t.options.singleQuote === !1 || t.implicitKey && e.includes("\n") || /[ \t]\n|\n[ \t]/.test(e)) return qa(e, t);
6935
- let n = t.indent || (Ga(e) ? " " : ""), r = "'" + e.replace(/'/g, "''").replace(/\n+/g, `$&\n${n}`) + "'";
6936
- return t.implicitKey ? r : Ha(r, n, za, Wa(t, !1));
7010
+ function Za(e, t) {
7011
+ if (t.options.singleQuote === !1 || t.implicitKey && e.includes("\n") || /[ \t]\n|\n[ \t]/.test(e)) return Xa(e, t);
7012
+ let n = t.indent || (Ja(e) ? " " : ""), r = "'" + e.replace(/'/g, "''").replace(/\n+/g, `$&\n${n}`) + "'";
7013
+ return t.implicitKey ? r : Ga(r, n, Ha, qa(t, !1));
6937
7014
  }
6938
- function Ya(e, t) {
7015
+ function Qa(e, t) {
6939
7016
  let { singleQuote: n } = t.options, r;
6940
- if (n === !1) r = qa;
7017
+ if (n === !1) r = Xa;
6941
7018
  else {
6942
7019
  let t = e.includes("\""), i = e.includes("'");
6943
- r = t && !i ? Ja : i && !t ? qa : n ? Ja : qa;
7020
+ r = t && !i ? Za : i && !t ? Xa : n ? Za : Xa;
6944
7021
  }
6945
7022
  return r(e, t);
6946
7023
  }
6947
- var Xa;
7024
+ var $a;
6948
7025
  try {
6949
- Xa = /* @__PURE__ */ RegExp("(^|(?<!\n))\n+(?!\n|$)", "g");
7026
+ $a = /* @__PURE__ */ RegExp("(^|(?<!\n))\n+(?!\n|$)", "g");
6950
7027
  } catch {
6951
- Xa = /\n+(?!\n|$)/g;
7028
+ $a = /\n+(?!\n|$)/g;
6952
7029
  }
6953
- function Za({ comment: e, type: t, value: n }, r, i, a) {
7030
+ function eo({ comment: e, type: t, value: n }, r, i, a) {
6954
7031
  let { blockQuote: o, commentString: s, lineWidth: c } = r.options;
6955
- if (!o || /\n[\t ]+$/.test(n)) return Ya(n, r);
6956
- let l = r.indent || (r.forceBlockIndent || Ga(n) ? " " : ""), u = o === "literal" ? !0 : o === "folded" || t === Z.BLOCK_FOLDED ? !1 : t === Z.BLOCK_LITERAL || !Ka(n, c, l.length);
7032
+ if (!o || /\n[\t ]+$/.test(n)) return Qa(n, r);
7033
+ let l = r.indent || (r.forceBlockIndent || Ja(n) ? " " : ""), u = o === "literal" ? !0 : o === "folded" || t === Z.BLOCK_FOLDED ? !1 : t === Z.BLOCK_LITERAL || !Ya(n, c, l.length);
6957
7034
  if (!n) return u ? "|\n" : ">\n";
6958
7035
  let d, f;
6959
7036
  for (f = n.length; f > 0; --f) {
@@ -6961,7 +7038,7 @@ function Za({ comment: e, type: t, value: n }, r, i, a) {
6961
7038
  if (e !== "\n" && e !== " " && e !== " ") break;
6962
7039
  }
6963
7040
  let p = n.substring(f), m = p.indexOf("\n");
6964
- m === -1 ? d = "-" : n === p || m !== p.length - 1 ? (d = "+", a && a()) : d = "", p &&= (n = n.slice(0, -p.length), p[p.length - 1] === "\n" && (p = p.slice(0, -1)), p.replace(Xa, `$&${l}`));
7041
+ m === -1 ? d = "-" : n === p || m !== p.length - 1 ? (d = "+", a && a()) : d = "", p &&= (n = n.slice(0, -p.length), p[p.length - 1] === "\n" && (p = p.slice(0, -1)), p.replace($a, `$&${l}`));
6965
7042
  let h = !1, g, _ = -1;
6966
7043
  for (g = 0; g < n.length; ++g) {
6967
7044
  let e = n[g];
@@ -6973,41 +7050,41 @@ function Za({ comment: e, type: t, value: n }, r, i, a) {
6973
7050
  v &&= (n = n.substring(v.length), v.replace(/\n+/g, `$&${l}`));
6974
7051
  let y = (h ? l ? "2" : "1" : "") + d;
6975
7052
  if (e && (y += " " + s(e.replace(/ ?[\r\n]+/g, " ")), i && i()), !u) {
6976
- let e = n.replace(/\n+/g, "\n$&").replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, "$1$2").replace(/\n+/g, `$&${l}`), i = !1, a = Wa(r, !0);
7053
+ let e = n.replace(/\n+/g, "\n$&").replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, "$1$2").replace(/\n+/g, `$&${l}`), i = !1, a = qa(r, !0);
6977
7054
  o !== "folded" && t !== Z.BLOCK_FOLDED && (a.onOverflow = () => {
6978
7055
  i = !0;
6979
7056
  });
6980
- let s = Ha(`${v}${e}${p}`, l, Ba, a);
7057
+ let s = Ga(`${v}${e}${p}`, l, Ua, a);
6981
7058
  if (!i) return `>${y}\n${l}${s}`;
6982
7059
  }
6983
7060
  return n = n.replace(/\n+/g, `$&${l}`), `|${y}\n${l}${v}${n}${p}`;
6984
7061
  }
6985
- function Qa(e, t, n, r) {
7062
+ function to(e, t, n, r) {
6986
7063
  let { type: i, value: a } = e, { actualString: o, implicitKey: s, indent: c, indentStep: l, inFlow: u } = t;
6987
- if (s && a.includes("\n") || u && /[[\]{},]/.test(a)) return Ya(a, t);
6988
- if (/^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(a)) return s || u || !a.includes("\n") ? Ya(a, t) : Za(e, t, n, r);
6989
- if (!s && !u && i !== Z.PLAIN && a.includes("\n")) return Za(e, t, n, r);
6990
- if (Ga(a)) {
6991
- if (c === "") return t.forceBlockIndent = !0, Za(e, t, n, r);
6992
- if (s && c === l) return Ya(a, t);
7064
+ if (s && a.includes("\n") || u && /[[\]{},]/.test(a)) return Qa(a, t);
7065
+ if (/^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(a)) return s || u || !a.includes("\n") ? Qa(a, t) : eo(e, t, n, r);
7066
+ if (!s && !u && i !== Z.PLAIN && a.includes("\n")) return eo(e, t, n, r);
7067
+ if (Ja(a)) {
7068
+ if (c === "") return t.forceBlockIndent = !0, eo(e, t, n, r);
7069
+ if (s && c === l) return Qa(a, t);
6993
7070
  }
6994
7071
  let d = a.replace(/\n+/g, `$&\n${c}`);
6995
7072
  if (o) {
6996
7073
  let e = (e) => e.default && e.tag !== "tag:yaml.org,2002:str" && e.test?.test(d), { compat: n, tags: r } = t.doc.schema;
6997
- if (r.some(e) || n?.some(e)) return Ya(a, t);
7074
+ if (r.some(e) || n?.some(e)) return Qa(a, t);
6998
7075
  }
6999
- return s ? d : Ha(d, c, za, Wa(t, !1));
7076
+ return s ? d : Ga(d, c, Ha, qa(t, !1));
7000
7077
  }
7001
- function $a(e, t, n, r) {
7078
+ function no(e, t, n, r) {
7002
7079
  let { implicitKey: i, inFlow: a } = t, o = typeof e.value == "string" ? e : Object.assign({}, e, { value: String(e.value) }), { type: s } = e;
7003
7080
  s !== Z.QUOTE_DOUBLE && /[\x00-\x08\x0b-\x1f\x7f-\x9f\u{D800}-\u{DFFF}]/u.test(o.value) && (s = Z.QUOTE_DOUBLE);
7004
7081
  let c = (e) => {
7005
7082
  switch (e) {
7006
7083
  case Z.BLOCK_FOLDED:
7007
- case Z.BLOCK_LITERAL: return i || a ? Ya(o.value, t) : Za(o, t, n, r);
7008
- case Z.QUOTE_DOUBLE: return qa(o.value, t);
7009
- case Z.QUOTE_SINGLE: return Ja(o.value, t);
7010
- case Z.PLAIN: return Qa(o, t, n, r);
7084
+ case Z.BLOCK_LITERAL: return i || a ? Qa(o.value, t) : eo(o, t, n, r);
7085
+ case Z.QUOTE_DOUBLE: return Xa(o.value, t);
7086
+ case Z.QUOTE_SINGLE: return Za(o.value, t);
7087
+ case Z.PLAIN: return to(o, t, n, r);
7011
7088
  default: return null;
7012
7089
  }
7013
7090
  }, l = c(s);
@@ -7019,10 +7096,10 @@ function $a(e, t, n, r) {
7019
7096
  }
7020
7097
  //#endregion
7021
7098
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/stringify/stringify.js
7022
- function eo(e, t) {
7099
+ function ro(e, t) {
7023
7100
  let n = Object.assign({
7024
7101
  blockQuote: !0,
7025
- commentString: Ia,
7102
+ commentString: za,
7026
7103
  defaultKeyType: null,
7027
7104
  defaultStringType: "PLAIN",
7028
7105
  directives: null,
@@ -7059,7 +7136,7 @@ function eo(e, t) {
7059
7136
  options: n
7060
7137
  };
7061
7138
  }
7062
- function to(e, t) {
7139
+ function io(e, t) {
7063
7140
  if (t.tag) {
7064
7141
  let n = e.filter((e) => e.tag === t.tag);
7065
7142
  if (n.length > 0) return n.find((e) => e.format === t.format) ?? n[0];
@@ -7080,30 +7157,30 @@ function to(e, t) {
7080
7157
  }
7081
7158
  return n;
7082
7159
  }
7083
- function no(e, t, { anchors: n, doc: r }) {
7160
+ function ao(e, t, { anchors: n, doc: r }) {
7084
7161
  if (!r.directives) return "";
7085
7162
  let i = [], a = (q(e) || J(e)) && e.anchor;
7086
- a && ba(a) && (n.add(a), i.push(`&${a}`));
7163
+ a && Ca(a) && (n.add(a), i.push(`&${a}`));
7087
7164
  let o = e.tag ?? (t.default ? null : t.tag);
7088
7165
  return o && i.push(r.directives.tagString(o)), i.join(" ");
7089
7166
  }
7090
- function ro(e, t, n, r) {
7167
+ function oo(e, t, n, r) {
7091
7168
  if (K(e)) return e.toString(t, n, r);
7092
- if (ra(e)) {
7169
+ if (oa(e)) {
7093
7170
  if (t.doc.directives) return e.toString(t);
7094
7171
  if (t.resolvedAliases?.has(e)) throw TypeError("Cannot stringify circular structure without alias nodes");
7095
7172
  t.resolvedAliases ? t.resolvedAliases.add(e) : t.resolvedAliases = /* @__PURE__ */ new Set([e]), e = e.resolve(t.doc);
7096
7173
  }
7097
7174
  let i, a = Y(e) ? e : t.doc.createNode(e, { onTagObj: (e) => i = e });
7098
- i ??= to(t.doc.schema.tags, a);
7099
- let o = no(a, i, t);
7175
+ i ??= io(t.doc.schema.tags, a);
7176
+ let o = ao(a, i, t);
7100
7177
  o.length > 0 && (t.indentAtStart = (t.indentAtStart ?? 0) + o.length + 1);
7101
- let s = typeof i.stringify == "function" ? i.stringify(a, t, n, r) : q(a) ? $a(a, t, n, r) : a.toString(t, n, r);
7178
+ let s = typeof i.stringify == "function" ? i.stringify(a, t, n, r) : q(a) ? no(a, t, n, r) : a.toString(t, n, r);
7102
7179
  return o ? q(a) || s[0] === "{" || s[0] === "[" ? `${o} ${s}` : `${o}\n${t.indent}${s}` : s;
7103
7180
  }
7104
7181
  //#endregion
7105
7182
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/stringify/stringifyPair.js
7106
- function io({ key: e, value: t }, n, r, i) {
7183
+ function so({ key: e, value: t }, n, r, i) {
7107
7184
  let { allNullValues: a, doc: o, indent: s, indentStep: c, options: { commentString: l, indentSeq: u, simpleKeys: d } } = n, f = Y(e) && e.comment || null;
7108
7185
  if (d) {
7109
7186
  if (f) throw Error("With simple keys, key nodes cannot have comments");
@@ -7115,22 +7192,22 @@ function io({ key: e, value: t }, n, r, i) {
7115
7192
  implicitKey: !p && (d || !a),
7116
7193
  indent: s + c
7117
7194
  });
7118
- let m = !1, h = !1, g = ro(e, n, () => m = !0, () => h = !0);
7195
+ let m = !1, h = !1, g = oo(e, n, () => m = !0, () => h = !0);
7119
7196
  if (!p && !n.inFlow && g.length > 1024) {
7120
7197
  if (d) throw Error("With simple keys, single line scalar must not span more than 1024 characters");
7121
7198
  p = !0;
7122
7199
  }
7123
7200
  if (n.inFlow) {
7124
7201
  if (a || t == null) return m && r && r(), g === "" ? "?" : p ? `? ${g}` : g;
7125
- } else if (a && !d || t == null && p) return g = `? ${g}`, f && !m ? g += Ra(g, n.indent, l(f)) : h && i && i(), g;
7126
- m && (f = null), p ? (f && (g += Ra(g, n.indent, l(f))), g = `? ${g}\n${s}:`) : (g = `${g}:`, f && (g += Ra(g, n.indent, l(f))));
7202
+ } else if (a && !d || t == null && p) return g = `? ${g}`, f && !m ? g += Va(g, n.indent, l(f)) : h && i && i(), g;
7203
+ m && (f = null), p ? (f && (g += Va(g, n.indent, l(f))), g = `? ${g}\n${s}:`) : (g = `${g}:`, f && (g += Va(g, n.indent, l(f))));
7127
7204
  let _, v, y;
7128
- Y(t) ? (_ = !!t.spaceBefore, v = t.commentBefore, y = t.comment) : (_ = !1, v = null, y = null, t && typeof t == "object" && (t = o.createNode(t))), n.implicitKey = !1, !p && !f && q(t) && (n.indentAtStart = g.length + 1), h = !1, !u && c.length >= 2 && !n.inFlow && !p && oa(t) && !t.flow && !t.tag && !t.anchor && (n.indent = n.indent.substring(2));
7129
- let b = !1, x = ro(t, n, () => b = !0, () => h = !0), S = " ";
7205
+ Y(t) ? (_ = !!t.spaceBefore, v = t.commentBefore, y = t.comment) : (_ = !1, v = null, y = null, t && typeof t == "object" && (t = o.createNode(t))), n.implicitKey = !1, !p && !f && q(t) && (n.indentAtStart = g.length + 1), h = !1, !u && c.length >= 2 && !n.inFlow && !p && la(t) && !t.flow && !t.tag && !t.anchor && (n.indent = n.indent.substring(2));
7206
+ let b = !1, x = oo(t, n, () => b = !0, () => h = !0), S = " ";
7130
7207
  if (f || _ || v) {
7131
7208
  if (S = _ ? "\n" : "", v) {
7132
7209
  let e = l(v);
7133
- S += `\n${La(e, n.indent)}`;
7210
+ S += `\n${Ba(e, n.indent)}`;
7134
7211
  }
7135
7212
  x === "" && !n.inFlow ? S === "\n" && y && (S = "\n\n") : S += `\n${n.indent}`;
7136
7213
  } else if (!p && J(t)) {
@@ -7144,32 +7221,32 @@ function io({ key: e, value: t }, n, r, i) {
7144
7221
  t || (S = `\n${n.indent}`);
7145
7222
  }
7146
7223
  } else (x === "" || x[0] === "\n") && (S = "");
7147
- return g += S + x, n.inFlow ? b && r && r() : y && !b ? g += Ra(g, n.indent, l(y)) : h && i && i(), g;
7224
+ return g += S + x, n.inFlow ? b && r && r() : y && !b ? g += Va(g, n.indent, l(y)) : h && i && i(), g;
7148
7225
  }
7149
7226
  //#endregion
7150
7227
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/log.js
7151
- function ao(e, t) {
7228
+ function co(e, t) {
7152
7229
  (e === "debug" || e === "warn") && console.warn(t);
7153
7230
  }
7154
7231
  //#endregion
7155
7232
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/schema/yaml-1.1/merge.js
7156
- var oo = "<<", so = {
7157
- identify: (e) => e === oo || typeof e == "symbol" && e.description === oo,
7233
+ var lo = "<<", uo = {
7234
+ identify: (e) => e === lo || typeof e == "symbol" && e.description === lo,
7158
7235
  default: "key",
7159
7236
  tag: "tag:yaml.org,2002:merge",
7160
7237
  test: /^<<$/,
7161
- resolve: () => Object.assign(new Z(Symbol(oo)), { addToJSMap: lo }),
7162
- stringify: () => oo
7163
- }, co = (e, t) => (so.identify(t) || q(t) && (!t.type || t.type === Z.PLAIN) && so.identify(t.value)) && e?.doc.schema.tags.some((e) => e.tag === so.tag && e.default);
7164
- function lo(e, t, n) {
7165
- let r = fo(e, n);
7166
- if (oa(r)) for (let n of r.items) uo(e, t, n);
7167
- else if (Array.isArray(r)) for (let n of r) uo(e, t, n);
7168
- else uo(e, t, r);
7169
- }
7170
- function uo(e, t, n) {
7171
- let r = fo(e, n);
7172
- if (!aa(r)) throw Error("Merge sources must be maps or map aliases");
7238
+ resolve: () => Object.assign(new Z(Symbol(lo)), { addToJSMap: po }),
7239
+ stringify: () => lo
7240
+ }, fo = (e, t) => (uo.identify(t) || q(t) && (!t.type || t.type === Z.PLAIN) && uo.identify(t.value)) && e?.doc.schema.tags.some((e) => e.tag === uo.tag && e.default);
7241
+ function po(e, t, n) {
7242
+ let r = ho(e, n);
7243
+ if (la(r)) for (let n of r.items) mo(e, t, n);
7244
+ else if (Array.isArray(r)) for (let n of r) mo(e, t, n);
7245
+ else mo(e, t, r);
7246
+ }
7247
+ function mo(e, t, n) {
7248
+ let r = ho(e, n);
7249
+ if (!ca(r)) throw Error("Merge sources must be maps or map aliases");
7173
7250
  let i = r.toJSON(null, e, Map);
7174
7251
  for (let [e, n] of i) t instanceof Map ? t.has(e) || t.set(e, n) : t instanceof Set ? t.add(e) : Object.prototype.hasOwnProperty.call(t, e) || Object.defineProperty(t, e, {
7175
7252
  value: n,
@@ -7179,20 +7256,20 @@ function uo(e, t, n) {
7179
7256
  });
7180
7257
  return t;
7181
7258
  }
7182
- function fo(e, t) {
7183
- return e && ra(t) ? t.resolve(e.doc, e) : t;
7259
+ function ho(e, t) {
7260
+ return e && oa(t) ? t.resolve(e.doc, e) : t;
7184
7261
  }
7185
7262
  //#endregion
7186
7263
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/nodes/addPairToJSMap.js
7187
- function po(e, t, { key: n, value: r }) {
7264
+ function go(e, t, { key: n, value: r }) {
7188
7265
  if (Y(n) && n.addToJSMap) n.addToJSMap(e, t, r);
7189
- else if (co(e, n)) lo(e, t, r);
7266
+ else if (fo(e, n)) po(e, t, r);
7190
7267
  else {
7191
- let i = Ta(n, "", e);
7192
- if (t instanceof Map) t.set(i, Ta(r, i, e));
7268
+ let i = Oa(n, "", e);
7269
+ if (t instanceof Map) t.set(i, Oa(r, i, e));
7193
7270
  else if (t instanceof Set) t.add(i);
7194
7271
  else {
7195
- let a = mo(n, i, e), o = Ta(r, a, e);
7272
+ let a = _o(n, i, e), o = Oa(r, a, e);
7196
7273
  a in t ? Object.defineProperty(t, a, {
7197
7274
  value: o,
7198
7275
  writable: !0,
@@ -7203,18 +7280,18 @@ function po(e, t, { key: n, value: r }) {
7203
7280
  }
7204
7281
  return t;
7205
7282
  }
7206
- function mo(e, t, n) {
7283
+ function _o(e, t, n) {
7207
7284
  if (t === null) return "";
7208
7285
  if (typeof t != "object") return String(t);
7209
7286
  if (Y(e) && n?.doc) {
7210
- let t = eo(n.doc, {});
7287
+ let t = ro(n.doc, {});
7211
7288
  t.anchors = /* @__PURE__ */ new Set();
7212
7289
  for (let e of n.anchors.keys()) t.anchors.add(e.anchor);
7213
7290
  t.inFlow = !0, t.inStringifyKey = !0;
7214
7291
  let r = e.toString(t);
7215
7292
  if (!n.mapKeyWarned) {
7216
7293
  let e = JSON.stringify(r);
7217
- e.length > 40 && (e = e.substring(0, 36) + "...\""), ao(n.doc.options.logLevel, `Keys with collection values will be stringified due to JS Object restrictions: ${e}. Set mapAsMap: true to use object keys.`), n.mapKeyWarned = !0;
7294
+ e.length > 40 && (e = e.substring(0, 36) + "...\""), co(n.doc.options.logLevel, `Keys with collection values will be stringified due to JS Object restrictions: ${e}. Set mapAsMap: true to use object keys.`), n.mapKeyWarned = !0;
7218
7295
  }
7219
7296
  return r;
7220
7297
  }
@@ -7222,44 +7299,44 @@ function mo(e, t, n) {
7222
7299
  }
7223
7300
  //#endregion
7224
7301
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/nodes/Pair.js
7225
- function ho(e, t, n) {
7226
- return new Q(Ma(e, void 0, n), Ma(t, void 0, n));
7302
+ function vo(e, t, n) {
7303
+ return new Q(Fa(e, void 0, n), Fa(t, void 0, n));
7227
7304
  }
7228
7305
  var Q = class e {
7229
7306
  constructor(e, t = null) {
7230
- Object.defineProperty(this, G, { value: ea }), this.key = e, this.value = t;
7307
+ Object.defineProperty(this, G, { value: ra }), this.key = e, this.value = t;
7231
7308
  }
7232
7309
  clone(t) {
7233
7310
  let { key: n, value: r } = this;
7234
7311
  return Y(n) && (n = n.clone(t)), Y(r) && (r = r.clone(t)), new e(n, r);
7235
7312
  }
7236
7313
  toJSON(e, t) {
7237
- return po(t, t?.mapAsMap ? /* @__PURE__ */ new Map() : {}, this);
7314
+ return go(t, t?.mapAsMap ? /* @__PURE__ */ new Map() : {}, this);
7238
7315
  }
7239
7316
  toString(e, t, n) {
7240
- return e?.doc ? io(this, e, t, n) : JSON.stringify(this);
7317
+ return e?.doc ? so(this, e, t, n) : JSON.stringify(this);
7241
7318
  }
7242
7319
  };
7243
7320
  //#endregion
7244
7321
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/stringify/stringifyCollection.js
7245
- function go(e, t, n) {
7246
- return (t.inFlow ?? e.flow ? vo : _o)(e, t, n);
7322
+ function yo(e, t, n) {
7323
+ return (t.inFlow ?? e.flow ? xo : bo)(e, t, n);
7247
7324
  }
7248
- function _o({ comment: e, items: t }, n, { blockItemPrefix: r, flowChars: i, itemIndent: a, onChompKeep: o, onComment: s }) {
7325
+ function bo({ comment: e, items: t }, n, { blockItemPrefix: r, flowChars: i, itemIndent: a, onChompKeep: o, onComment: s }) {
7249
7326
  let { indent: c, options: { commentString: l } } = n, u = Object.assign({}, n, {
7250
7327
  indent: a,
7251
7328
  type: null
7252
7329
  }), d = !1, f = [];
7253
7330
  for (let e = 0; e < t.length; ++e) {
7254
7331
  let i = t[e], o = null;
7255
- if (Y(i)) !d && i.spaceBefore && f.push(""), yo(n, f, i.commentBefore, d), i.comment && (o = i.comment);
7332
+ if (Y(i)) !d && i.spaceBefore && f.push(""), So(n, f, i.commentBefore, d), i.comment && (o = i.comment);
7256
7333
  else if (K(i)) {
7257
7334
  let e = Y(i.key) ? i.key : null;
7258
- e && (!d && e.spaceBefore && f.push(""), yo(n, f, e.commentBefore, d));
7335
+ e && (!d && e.spaceBefore && f.push(""), So(n, f, e.commentBefore, d));
7259
7336
  }
7260
7337
  d = !1;
7261
- let s = ro(i, u, () => o = null, () => d = !0);
7262
- o && (s += Ra(s, a, l(o))), d && o && (d = !1), f.push(r + s);
7338
+ let s = oo(i, u, () => o = null, () => d = !0);
7339
+ o && (s += Va(s, a, l(o))), d && o && (d = !1), f.push(r + s);
7263
7340
  }
7264
7341
  let p;
7265
7342
  if (f.length === 0) p = i.start + i.end;
@@ -7270,9 +7347,9 @@ function _o({ comment: e, items: t }, n, { blockItemPrefix: r, flowChars: i, ite
7270
7347
  p += t ? `\n${c}${t}` : "\n";
7271
7348
  }
7272
7349
  }
7273
- return e ? (p += "\n" + La(l(e), c), s && s()) : d && o && o(), p;
7350
+ return e ? (p += "\n" + Ba(l(e), c), s && s()) : d && o && o(), p;
7274
7351
  }
7275
- function vo({ items: e }, t, { flowChars: n, itemIndent: r }) {
7352
+ function xo({ items: e }, t, { flowChars: n, itemIndent: r }) {
7276
7353
  let { indent: i, indentStep: a, flowCollectionPadding: o, options: { commentString: s } } = t;
7277
7354
  r += a;
7278
7355
  let c = Object.assign({}, t, {
@@ -7282,16 +7359,16 @@ function vo({ items: e }, t, { flowChars: n, itemIndent: r }) {
7282
7359
  }), l = !1, u = 0, d = [];
7283
7360
  for (let n = 0; n < e.length; ++n) {
7284
7361
  let i = e[n], a = null;
7285
- if (Y(i)) i.spaceBefore && d.push(""), yo(t, d, i.commentBefore, !1), i.comment && (a = i.comment);
7362
+ if (Y(i)) i.spaceBefore && d.push(""), So(t, d, i.commentBefore, !1), i.comment && (a = i.comment);
7286
7363
  else if (K(i)) {
7287
7364
  let e = Y(i.key) ? i.key : null;
7288
- e && (e.spaceBefore && d.push(""), yo(t, d, e.commentBefore, !1), e.comment && (l = !0));
7365
+ e && (e.spaceBefore && d.push(""), So(t, d, e.commentBefore, !1), e.comment && (l = !0));
7289
7366
  let n = Y(i.value) ? i.value : null;
7290
7367
  n ? (n.comment && (a = n.comment), n.commentBefore && (l = !0)) : i.value == null && e?.comment && (a = e.comment);
7291
7368
  }
7292
7369
  a && (l = !0);
7293
- let o = ro(i, c, () => a = null);
7294
- l ||= d.length > u || o.includes("\n"), n < e.length - 1 ? o += "," : t.options.trailingComma && (t.options.lineWidth > 0 && (l ||= d.reduce((e, t) => e + t.length + 2, 2) + (o.length + 2) > t.options.lineWidth), l && (o += ",")), a && (o += Ra(o, r, s(a))), d.push(o), u = d.length;
7370
+ let o = oo(i, c, () => a = null);
7371
+ l ||= d.length > u || o.includes("\n"), n < e.length - 1 ? o += "," : t.options.trailingComma && (t.options.lineWidth > 0 && (l ||= d.reduce((e, t) => e + t.length + 2, 2) + (o.length + 2) > t.options.lineWidth), l && (o += ",")), a && (o += Va(o, r, s(a))), d.push(o), u = d.length;
7295
7372
  }
7296
7373
  let { start: f, end: p } = n;
7297
7374
  if (d.length === 0) return f + p;
@@ -7306,30 +7383,30 @@ function vo({ items: e }, t, { flowChars: n, itemIndent: r }) {
7306
7383
  }
7307
7384
  return `${f}${o}${d.join(" ")}${o}${p}`;
7308
7385
  }
7309
- function yo({ indent: e, options: { commentString: t } }, n, r, i) {
7386
+ function So({ indent: e, options: { commentString: t } }, n, r, i) {
7310
7387
  if (r && i && (r = r.replace(/^\n+/, "")), r) {
7311
- let i = La(t(r), e);
7388
+ let i = Ba(t(r), e);
7312
7389
  n.push(i.trimStart());
7313
7390
  }
7314
7391
  }
7315
7392
  //#endregion
7316
7393
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/nodes/YAMLMap.js
7317
- function bo(e, t) {
7394
+ function Co(e, t) {
7318
7395
  let n = q(t) ? t.value : t;
7319
7396
  for (let r of e) if (K(r) && (r.key === t || r.key === n || q(r.key) && r.key.value === n)) return r;
7320
7397
  }
7321
- var $ = class extends Fa {
7398
+ var $ = class extends Ra {
7322
7399
  static get tagName() {
7323
7400
  return "tag:yaml.org,2002:map";
7324
7401
  }
7325
7402
  constructor(e) {
7326
- super($i, e), this.items = [];
7403
+ super(na, e), this.items = [];
7327
7404
  }
7328
7405
  static from(e, t, n) {
7329
7406
  let { keepUndefined: r, replacer: i } = n, a = new this(e), o = (e, o) => {
7330
7407
  if (typeof i == "function") o = i.call(t, e, o);
7331
7408
  else if (Array.isArray(i) && !i.includes(e)) return;
7332
- (o !== void 0 || r) && a.items.push(ho(e, o, n));
7409
+ (o !== void 0 || r) && a.items.push(vo(e, o, n));
7333
7410
  };
7334
7411
  if (t instanceof Map) for (let [e, n] of t) o(e, n);
7335
7412
  else if (t && typeof t == "object") for (let e of Object.keys(t)) o(e, t[e]);
@@ -7338,25 +7415,25 @@ var $ = class extends Fa {
7338
7415
  add(e, t) {
7339
7416
  let n;
7340
7417
  n = K(e) ? e : !e || typeof e != "object" || !("key" in e) ? new Q(e, e?.value) : new Q(e.key, e.value);
7341
- let r = bo(this.items, n.key), i = this.schema?.sortMapEntries;
7418
+ let r = Co(this.items, n.key), i = this.schema?.sortMapEntries;
7342
7419
  if (r) {
7343
7420
  if (!t) throw Error(`Key ${n.key} already set`);
7344
- q(r.value) && ka(n.value) ? r.value.value = n.value : r.value = n.value;
7421
+ q(r.value) && Ma(n.value) ? r.value.value = n.value : r.value = n.value;
7345
7422
  } else if (i) {
7346
7423
  let e = this.items.findIndex((e) => i(n, e) < 0);
7347
7424
  e === -1 ? this.items.push(n) : this.items.splice(e, 0, n);
7348
7425
  } else this.items.push(n);
7349
7426
  }
7350
7427
  delete(e) {
7351
- let t = bo(this.items, e);
7428
+ let t = Co(this.items, e);
7352
7429
  return t ? this.items.splice(this.items.indexOf(t), 1).length > 0 : !1;
7353
7430
  }
7354
7431
  get(e, t) {
7355
- let n = bo(this.items, e)?.value;
7432
+ let n = Co(this.items, e)?.value;
7356
7433
  return (!t && q(n) ? n.value : n) ?? void 0;
7357
7434
  }
7358
7435
  has(e) {
7359
- return !!bo(this.items, e);
7436
+ return !!Co(this.items, e);
7360
7437
  }
7361
7438
  set(e, t) {
7362
7439
  this.add(new Q(e, t), !0);
@@ -7364,13 +7441,13 @@ var $ = class extends Fa {
7364
7441
  toJSON(e, t, n) {
7365
7442
  let r = n ? new n() : t?.mapAsMap ? /* @__PURE__ */ new Map() : {};
7366
7443
  t?.onCreate && t.onCreate(r);
7367
- for (let e of this.items) po(t, r, e);
7444
+ for (let e of this.items) go(t, r, e);
7368
7445
  return r;
7369
7446
  }
7370
7447
  toString(e, t, n) {
7371
7448
  if (!e) return JSON.stringify(this);
7372
7449
  for (let e of this.items) if (!K(e)) throw Error(`Map items must all be pairs; found ${JSON.stringify(e)} instead`);
7373
- return !e.allNullValues && this.hasAllNullValues(!1) && (e = Object.assign({}, e, { allNullValues: !0 })), go(this, e, {
7450
+ return !e.allNullValues && this.hasAllNullValues(!1) && (e = Object.assign({}, e, { allNullValues: !0 })), yo(this, e, {
7374
7451
  blockItemPrefix: "",
7375
7452
  flowChars: {
7376
7453
  start: "{",
@@ -7381,54 +7458,54 @@ var $ = class extends Fa {
7381
7458
  onComment: t
7382
7459
  });
7383
7460
  }
7384
- }, xo = {
7461
+ }, wo = {
7385
7462
  collection: "map",
7386
7463
  default: !0,
7387
7464
  nodeClass: $,
7388
7465
  tag: "tag:yaml.org,2002:map",
7389
7466
  resolve(e, t) {
7390
- return aa(e) || t("Expected a mapping for this tag"), e;
7467
+ return ca(e) || t("Expected a mapping for this tag"), e;
7391
7468
  },
7392
7469
  createNode: (e, t, n) => $.from(e, t, n)
7393
- }, So = class extends Fa {
7470
+ }, To = class extends Ra {
7394
7471
  static get tagName() {
7395
7472
  return "tag:yaml.org,2002:seq";
7396
7473
  }
7397
7474
  constructor(e) {
7398
- super(na, e), this.items = [];
7475
+ super(aa, e), this.items = [];
7399
7476
  }
7400
7477
  add(e) {
7401
7478
  this.items.push(e);
7402
7479
  }
7403
7480
  delete(e) {
7404
- let t = Co(e);
7481
+ let t = Eo(e);
7405
7482
  return typeof t == "number" && this.items.splice(t, 1).length > 0;
7406
7483
  }
7407
7484
  get(e, t) {
7408
- let n = Co(e);
7485
+ let n = Eo(e);
7409
7486
  if (typeof n != "number") return;
7410
7487
  let r = this.items[n];
7411
7488
  return !t && q(r) ? r.value : r;
7412
7489
  }
7413
7490
  has(e) {
7414
- let t = Co(e);
7491
+ let t = Eo(e);
7415
7492
  return typeof t == "number" && t < this.items.length;
7416
7493
  }
7417
7494
  set(e, t) {
7418
- let n = Co(e);
7495
+ let n = Eo(e);
7419
7496
  if (typeof n != "number") throw Error(`Expected a valid index, not ${e}.`);
7420
7497
  let r = this.items[n];
7421
- q(r) && ka(t) ? r.value = t : this.items[n] = t;
7498
+ q(r) && Ma(t) ? r.value = t : this.items[n] = t;
7422
7499
  }
7423
7500
  toJSON(e, t) {
7424
7501
  let n = [];
7425
7502
  t?.onCreate && t.onCreate(n);
7426
7503
  let r = 0;
7427
- for (let e of this.items) n.push(Ta(e, String(r++), t));
7504
+ for (let e of this.items) n.push(Oa(e, String(r++), t));
7428
7505
  return n;
7429
7506
  }
7430
7507
  toString(e, t, n) {
7431
- return e ? go(this, e, {
7508
+ return e ? yo(this, e, {
7432
7509
  blockItemPrefix: "- ",
7433
7510
  flowChars: {
7434
7511
  start: "[",
@@ -7448,56 +7525,56 @@ var $ = class extends Fa {
7448
7525
  let n = t instanceof Set ? a : String(e++);
7449
7526
  a = r.call(t, n, a);
7450
7527
  }
7451
- i.items.push(Ma(a, void 0, n));
7528
+ i.items.push(Fa(a, void 0, n));
7452
7529
  }
7453
7530
  }
7454
7531
  return i;
7455
7532
  }
7456
7533
  };
7457
- function Co(e) {
7534
+ function Eo(e) {
7458
7535
  let t = q(e) ? e.value : e;
7459
7536
  return t && typeof t == "string" && (t = Number(t)), typeof t == "number" && Number.isInteger(t) && t >= 0 ? t : null;
7460
7537
  }
7461
7538
  //#endregion
7462
7539
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/schema/common/seq.js
7463
- var wo = {
7540
+ var Do = {
7464
7541
  collection: "seq",
7465
7542
  default: !0,
7466
- nodeClass: So,
7543
+ nodeClass: To,
7467
7544
  tag: "tag:yaml.org,2002:seq",
7468
7545
  resolve(e, t) {
7469
- return oa(e) || t("Expected a sequence for this tag"), e;
7546
+ return la(e) || t("Expected a sequence for this tag"), e;
7470
7547
  },
7471
- createNode: (e, t, n) => So.from(e, t, n)
7472
- }, To = {
7548
+ createNode: (e, t, n) => To.from(e, t, n)
7549
+ }, Oo = {
7473
7550
  identify: (e) => typeof e == "string",
7474
7551
  default: !0,
7475
7552
  tag: "tag:yaml.org,2002:str",
7476
7553
  resolve: (e) => e,
7477
7554
  stringify(e, t, n, r) {
7478
- return t = Object.assign({ actualString: !0 }, t), $a(e, t, n, r);
7555
+ return t = Object.assign({ actualString: !0 }, t), no(e, t, n, r);
7479
7556
  }
7480
- }, Eo = {
7557
+ }, ko = {
7481
7558
  identify: (e) => e == null,
7482
7559
  createNode: () => new Z(null),
7483
7560
  default: !0,
7484
7561
  tag: "tag:yaml.org,2002:null",
7485
7562
  test: /^(?:~|[Nn]ull|NULL)?$/,
7486
7563
  resolve: () => new Z(null),
7487
- stringify: ({ source: e }, t) => typeof e == "string" && Eo.test.test(e) ? e : t.options.nullStr
7488
- }, Do = {
7564
+ stringify: ({ source: e }, t) => typeof e == "string" && ko.test.test(e) ? e : t.options.nullStr
7565
+ }, Ao = {
7489
7566
  identify: (e) => typeof e == "boolean",
7490
7567
  default: !0,
7491
7568
  tag: "tag:yaml.org,2002:bool",
7492
7569
  test: /^(?:[Tt]rue|TRUE|[Ff]alse|FALSE)$/,
7493
7570
  resolve: (e) => new Z(e[0] === "t" || e[0] === "T"),
7494
7571
  stringify({ source: e, value: t }, n) {
7495
- return e && Do.test.test(e) && t === (e[0] === "t" || e[0] === "T") ? e : t ? n.options.trueStr : n.options.falseStr;
7572
+ return e && Ao.test.test(e) && t === (e[0] === "t" || e[0] === "T") ? e : t ? n.options.trueStr : n.options.falseStr;
7496
7573
  }
7497
7574
  };
7498
7575
  //#endregion
7499
7576
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/stringify/stringifyNumber.js
7500
- function Oo({ format: e, minFractionDigits: t, tag: n, value: r }) {
7577
+ function jo({ format: e, minFractionDigits: t, tag: n, value: r }) {
7501
7578
  if (typeof r == "bigint") return String(r);
7502
7579
  let i = typeof r == "number" ? r : Number(r);
7503
7580
  if (!isFinite(i)) return isNaN(i) ? ".nan" : i < 0 ? "-.inf" : ".inf";
@@ -7512,14 +7589,14 @@ function Oo({ format: e, minFractionDigits: t, tag: n, value: r }) {
7512
7589
  }
7513
7590
  //#endregion
7514
7591
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/schema/core/float.js
7515
- var ko = {
7592
+ var Mo = {
7516
7593
  identify: (e) => typeof e == "number",
7517
7594
  default: !0,
7518
7595
  tag: "tag:yaml.org,2002:float",
7519
7596
  test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
7520
7597
  resolve: (e) => e.slice(-3).toLowerCase() === "nan" ? NaN : e[0] === "-" ? -Infinity : Infinity,
7521
- stringify: Oo
7522
- }, Ao = {
7598
+ stringify: jo
7599
+ }, No = {
7523
7600
  identify: (e) => typeof e == "number",
7524
7601
  default: !0,
7525
7602
  tag: "tag:yaml.org,2002:float",
@@ -7528,9 +7605,9 @@ var ko = {
7528
7605
  resolve: (e) => parseFloat(e),
7529
7606
  stringify(e) {
7530
7607
  let t = Number(e.value);
7531
- return isFinite(t) ? t.toExponential() : Oo(e);
7608
+ return isFinite(t) ? t.toExponential() : jo(e);
7532
7609
  }
7533
- }, jo = {
7610
+ }, Po = {
7534
7611
  identify: (e) => typeof e == "number",
7535
7612
  default: !0,
7536
7613
  tag: "tag:yaml.org,2002:float",
@@ -7539,60 +7616,60 @@ var ko = {
7539
7616
  let t = new Z(parseFloat(e)), n = e.indexOf(".");
7540
7617
  return n !== -1 && e[e.length - 1] === "0" && (t.minFractionDigits = e.length - n - 1), t;
7541
7618
  },
7542
- stringify: Oo
7543
- }, Mo = (e) => typeof e == "bigint" || Number.isInteger(e), No = (e, t, n, { intAsBigInt: r }) => r ? BigInt(e) : parseInt(e.substring(t), n);
7544
- function Po(e, t, n) {
7619
+ stringify: jo
7620
+ }, Fo = (e) => typeof e == "bigint" || Number.isInteger(e), Io = (e, t, n, { intAsBigInt: r }) => r ? BigInt(e) : parseInt(e.substring(t), n);
7621
+ function Lo(e, t, n) {
7545
7622
  let { value: r } = e;
7546
- return Mo(r) && r >= 0 ? n + r.toString(t) : Oo(e);
7623
+ return Fo(r) && r >= 0 ? n + r.toString(t) : jo(e);
7547
7624
  }
7548
- var Fo = {
7549
- identify: (e) => Mo(e) && e >= 0,
7625
+ var Ro = {
7626
+ identify: (e) => Fo(e) && e >= 0,
7550
7627
  default: !0,
7551
7628
  tag: "tag:yaml.org,2002:int",
7552
7629
  format: "OCT",
7553
7630
  test: /^0o[0-7]+$/,
7554
- resolve: (e, t, n) => No(e, 2, 8, n),
7555
- stringify: (e) => Po(e, 8, "0o")
7556
- }, Io = {
7557
- identify: Mo,
7631
+ resolve: (e, t, n) => Io(e, 2, 8, n),
7632
+ stringify: (e) => Lo(e, 8, "0o")
7633
+ }, zo = {
7634
+ identify: Fo,
7558
7635
  default: !0,
7559
7636
  tag: "tag:yaml.org,2002:int",
7560
7637
  test: /^[-+]?[0-9]+$/,
7561
- resolve: (e, t, n) => No(e, 0, 10, n),
7562
- stringify: Oo
7563
- }, Lo = {
7564
- identify: (e) => Mo(e) && e >= 0,
7638
+ resolve: (e, t, n) => Io(e, 0, 10, n),
7639
+ stringify: jo
7640
+ }, Bo = {
7641
+ identify: (e) => Fo(e) && e >= 0,
7565
7642
  default: !0,
7566
7643
  tag: "tag:yaml.org,2002:int",
7567
7644
  format: "HEX",
7568
7645
  test: /^0x[0-9a-fA-F]+$/,
7569
- resolve: (e, t, n) => No(e, 2, 16, n),
7570
- stringify: (e) => Po(e, 16, "0x")
7571
- }, Ro = [
7572
- xo,
7646
+ resolve: (e, t, n) => Io(e, 2, 16, n),
7647
+ stringify: (e) => Lo(e, 16, "0x")
7648
+ }, Vo = [
7573
7649
  wo,
7574
- To,
7575
- Eo,
7576
7650
  Do,
7577
- Fo,
7578
- Io,
7579
- Lo,
7651
+ Oo,
7580
7652
  ko,
7581
7653
  Ao,
7582
- jo
7654
+ Ro,
7655
+ zo,
7656
+ Bo,
7657
+ Mo,
7658
+ No,
7659
+ Po
7583
7660
  ];
7584
7661
  //#endregion
7585
7662
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/schema/json/schema.js
7586
- function zo(e) {
7663
+ function Ho(e) {
7587
7664
  return typeof e == "bigint" || Number.isInteger(e);
7588
7665
  }
7589
- var Bo = ({ value: e }) => JSON.stringify(e), Vo = [
7666
+ var Uo = ({ value: e }) => JSON.stringify(e), Wo = [
7590
7667
  {
7591
7668
  identify: (e) => typeof e == "string",
7592
7669
  default: !0,
7593
7670
  tag: "tag:yaml.org,2002:str",
7594
7671
  resolve: (e) => e,
7595
- stringify: Bo
7672
+ stringify: Uo
7596
7673
  },
7597
7674
  {
7598
7675
  identify: (e) => e == null,
@@ -7601,7 +7678,7 @@ var Bo = ({ value: e }) => JSON.stringify(e), Vo = [
7601
7678
  tag: "tag:yaml.org,2002:null",
7602
7679
  test: /^null$/,
7603
7680
  resolve: () => null,
7604
- stringify: Bo
7681
+ stringify: Uo
7605
7682
  },
7606
7683
  {
7607
7684
  identify: (e) => typeof e == "boolean",
@@ -7609,15 +7686,15 @@ var Bo = ({ value: e }) => JSON.stringify(e), Vo = [
7609
7686
  tag: "tag:yaml.org,2002:bool",
7610
7687
  test: /^true$|^false$/,
7611
7688
  resolve: (e) => e === "true",
7612
- stringify: Bo
7689
+ stringify: Uo
7613
7690
  },
7614
7691
  {
7615
- identify: zo,
7692
+ identify: Ho,
7616
7693
  default: !0,
7617
7694
  tag: "tag:yaml.org,2002:int",
7618
7695
  test: /^-?(?:0|[1-9][0-9]*)$/,
7619
7696
  resolve: (e, t, { intAsBigInt: n }) => n ? BigInt(e) : parseInt(e, 10),
7620
- stringify: ({ value: e }) => zo(e) ? e.toString() : JSON.stringify(e)
7697
+ stringify: ({ value: e }) => Ho(e) ? e.toString() : JSON.stringify(e)
7621
7698
  },
7622
7699
  {
7623
7700
  identify: (e) => typeof e == "number",
@@ -7625,16 +7702,16 @@ var Bo = ({ value: e }) => JSON.stringify(e), Vo = [
7625
7702
  tag: "tag:yaml.org,2002:float",
7626
7703
  test: /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]*)?(?:[eE][-+]?[0-9]+)?$/,
7627
7704
  resolve: (e) => parseFloat(e),
7628
- stringify: Bo
7705
+ stringify: Uo
7629
7706
  }
7630
- ], Ho = [xo, wo].concat(Vo, {
7707
+ ], Go = [wo, Do].concat(Wo, {
7631
7708
  default: !0,
7632
7709
  tag: "",
7633
7710
  test: /^/,
7634
7711
  resolve(e, t) {
7635
7712
  return t(`Unresolved plain scalar ${JSON.stringify(e)}`), e;
7636
7713
  }
7637
- }), Uo = {
7714
+ }), Ko = {
7638
7715
  identify: (e) => e instanceof Uint8Array,
7639
7716
  default: !1,
7640
7717
  tag: "tag:yaml.org,2002:binary",
@@ -7659,7 +7736,7 @@ var Bo = ({ value: e }) => JSON.stringify(e), Vo = [
7659
7736
  for (let t = 0, r = 0; t < n; ++t, r += e) i[t] = s.substr(r, e);
7660
7737
  s = i.join(t === Z.BLOCK_LITERAL ? "\n" : " ");
7661
7738
  }
7662
- return $a({
7739
+ return no({
7663
7740
  comment: e,
7664
7741
  type: t,
7665
7742
  value: s
@@ -7668,11 +7745,11 @@ var Bo = ({ value: e }) => JSON.stringify(e), Vo = [
7668
7745
  };
7669
7746
  //#endregion
7670
7747
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/schema/yaml-1.1/pairs.js
7671
- function Wo(e, t) {
7672
- if (oa(e)) for (let n = 0; n < e.items.length; ++n) {
7748
+ function qo(e, t) {
7749
+ if (la(e)) for (let n = 0; n < e.items.length; ++n) {
7673
7750
  let r = e.items[n];
7674
7751
  if (!K(r)) {
7675
- if (aa(r)) {
7752
+ if (ca(r)) {
7676
7753
  r.items.length > 1 && t("Each pair must have its own sequence indicator");
7677
7754
  let e = r.items[0] || new Q(new Z(null));
7678
7755
  if (r.commentBefore && (e.key.commentBefore = e.key.commentBefore ? `${r.commentBefore}\n${e.key.commentBefore}` : r.commentBefore), r.comment) {
@@ -7687,8 +7764,8 @@ function Wo(e, t) {
7687
7764
  else t("Expected a sequence for this tag");
7688
7765
  return e;
7689
7766
  }
7690
- function Go(e, t, n) {
7691
- let { replacer: r } = n, i = new So(e);
7767
+ function Jo(e, t, n) {
7768
+ let { replacer: r } = n, i = new To(e);
7692
7769
  i.tag = "tag:yaml.org,2002:pairs";
7693
7770
  let a = 0;
7694
7771
  if (t && Symbol.iterator in Object(t)) for (let e of t) {
@@ -7702,17 +7779,17 @@ function Go(e, t, n) {
7702
7779
  if (t.length === 1) o = t[0], s = e[o];
7703
7780
  else throw TypeError(`Expected tuple with one key, not ${t.length} keys`);
7704
7781
  } else o = e;
7705
- i.items.push(ho(o, s, n));
7782
+ i.items.push(vo(o, s, n));
7706
7783
  }
7707
7784
  return i;
7708
7785
  }
7709
- var Ko = {
7786
+ var Yo = {
7710
7787
  collection: "seq",
7711
7788
  default: !1,
7712
7789
  tag: "tag:yaml.org,2002:pairs",
7713
- resolve: Wo,
7714
- createNode: Go
7715
- }, qo = class e extends So {
7790
+ resolve: qo,
7791
+ createNode: Jo
7792
+ }, Xo = class e extends To {
7716
7793
  constructor() {
7717
7794
  super(), this.add = $.prototype.add.bind(this), this.delete = $.prototype.delete.bind(this), this.get = $.prototype.get.bind(this), this.has = $.prototype.has.bind(this), this.set = $.prototype.set.bind(this), this.tag = e.tag;
7718
7795
  }
@@ -7722,57 +7799,57 @@ var Ko = {
7722
7799
  t?.onCreate && t.onCreate(n);
7723
7800
  for (let e of this.items) {
7724
7801
  let r, i;
7725
- if (K(e) ? (r = Ta(e.key, "", t), i = Ta(e.value, r, t)) : r = Ta(e, "", t), n.has(r)) throw Error("Ordered maps must not include duplicate keys");
7802
+ if (K(e) ? (r = Oa(e.key, "", t), i = Oa(e.value, r, t)) : r = Oa(e, "", t), n.has(r)) throw Error("Ordered maps must not include duplicate keys");
7726
7803
  n.set(r, i);
7727
7804
  }
7728
7805
  return n;
7729
7806
  }
7730
7807
  static from(e, t, n) {
7731
- let r = Go(e, t, n), i = new this();
7808
+ let r = Jo(e, t, n), i = new this();
7732
7809
  return i.items = r.items, i;
7733
7810
  }
7734
7811
  };
7735
- qo.tag = "tag:yaml.org,2002:omap";
7736
- var Jo = {
7812
+ Xo.tag = "tag:yaml.org,2002:omap";
7813
+ var Zo = {
7737
7814
  collection: "seq",
7738
7815
  identify: (e) => e instanceof Map,
7739
- nodeClass: qo,
7816
+ nodeClass: Xo,
7740
7817
  default: !1,
7741
7818
  tag: "tag:yaml.org,2002:omap",
7742
7819
  resolve(e, t) {
7743
- let n = Wo(e, t), r = [];
7820
+ let n = qo(e, t), r = [];
7744
7821
  for (let { key: e } of n.items) q(e) && (r.includes(e.value) ? t(`Ordered maps must not include duplicate keys: ${e.value}`) : r.push(e.value));
7745
- return Object.assign(new qo(), n);
7822
+ return Object.assign(new Xo(), n);
7746
7823
  },
7747
- createNode: (e, t, n) => qo.from(e, t, n)
7824
+ createNode: (e, t, n) => Xo.from(e, t, n)
7748
7825
  };
7749
7826
  //#endregion
7750
7827
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/schema/yaml-1.1/bool.js
7751
- function Yo({ value: e, source: t }, n) {
7752
- return t && (e ? Xo : Zo).test.test(t) ? t : e ? n.options.trueStr : n.options.falseStr;
7828
+ function Qo({ value: e, source: t }, n) {
7829
+ return t && (e ? $o : es).test.test(t) ? t : e ? n.options.trueStr : n.options.falseStr;
7753
7830
  }
7754
- var Xo = {
7831
+ var $o = {
7755
7832
  identify: (e) => e === !0,
7756
7833
  default: !0,
7757
7834
  tag: "tag:yaml.org,2002:bool",
7758
7835
  test: /^(?:Y|y|[Yy]es|YES|[Tt]rue|TRUE|[Oo]n|ON)$/,
7759
7836
  resolve: () => new Z(!0),
7760
- stringify: Yo
7761
- }, Zo = {
7837
+ stringify: Qo
7838
+ }, es = {
7762
7839
  identify: (e) => e === !1,
7763
7840
  default: !0,
7764
7841
  tag: "tag:yaml.org,2002:bool",
7765
7842
  test: /^(?:N|n|[Nn]o|NO|[Ff]alse|FALSE|[Oo]ff|OFF)$/,
7766
7843
  resolve: () => new Z(!1),
7767
- stringify: Yo
7768
- }, Qo = {
7844
+ stringify: Qo
7845
+ }, ts = {
7769
7846
  identify: (e) => typeof e == "number",
7770
7847
  default: !0,
7771
7848
  tag: "tag:yaml.org,2002:float",
7772
7849
  test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
7773
7850
  resolve: (e) => e.slice(-3).toLowerCase() === "nan" ? NaN : e[0] === "-" ? -Infinity : Infinity,
7774
- stringify: Oo
7775
- }, $o = {
7851
+ stringify: jo
7852
+ }, ns = {
7776
7853
  identify: (e) => typeof e == "number",
7777
7854
  default: !0,
7778
7855
  tag: "tag:yaml.org,2002:float",
@@ -7781,9 +7858,9 @@ var Xo = {
7781
7858
  resolve: (e) => parseFloat(e.replace(/_/g, "")),
7782
7859
  stringify(e) {
7783
7860
  let t = Number(e.value);
7784
- return isFinite(t) ? t.toExponential() : Oo(e);
7861
+ return isFinite(t) ? t.toExponential() : jo(e);
7785
7862
  }
7786
- }, es = {
7863
+ }, rs = {
7787
7864
  identify: (e) => typeof e == "number",
7788
7865
  default: !0,
7789
7866
  tag: "tag:yaml.org,2002:float",
@@ -7796,9 +7873,9 @@ var Xo = {
7796
7873
  }
7797
7874
  return t;
7798
7875
  },
7799
- stringify: Oo
7800
- }, ts = (e) => typeof e == "bigint" || Number.isInteger(e);
7801
- function ns(e, t, n, { intAsBigInt: r }) {
7876
+ stringify: jo
7877
+ }, is = (e) => typeof e == "bigint" || Number.isInteger(e);
7878
+ function as(e, t, n, { intAsBigInt: r }) {
7802
7879
  let i = e[0];
7803
7880
  if ((i === "-" || i === "+") && (t += 1), e = e.substring(t).replace(/_/g, ""), r) {
7804
7881
  switch (n) {
@@ -7816,60 +7893,60 @@ function ns(e, t, n, { intAsBigInt: r }) {
7816
7893
  let a = parseInt(e, n);
7817
7894
  return i === "-" ? -1 * a : a;
7818
7895
  }
7819
- function rs(e, t, n) {
7896
+ function os(e, t, n) {
7820
7897
  let { value: r } = e;
7821
- if (ts(r)) {
7898
+ if (is(r)) {
7822
7899
  let e = r.toString(t);
7823
7900
  return r < 0 ? "-" + n + e.substr(1) : n + e;
7824
7901
  }
7825
- return Oo(e);
7902
+ return jo(e);
7826
7903
  }
7827
- var is = {
7828
- identify: ts,
7904
+ var ss = {
7905
+ identify: is,
7829
7906
  default: !0,
7830
7907
  tag: "tag:yaml.org,2002:int",
7831
7908
  format: "BIN",
7832
7909
  test: /^[-+]?0b[0-1_]+$/,
7833
- resolve: (e, t, n) => ns(e, 2, 2, n),
7834
- stringify: (e) => rs(e, 2, "0b")
7835
- }, as = {
7836
- identify: ts,
7910
+ resolve: (e, t, n) => as(e, 2, 2, n),
7911
+ stringify: (e) => os(e, 2, "0b")
7912
+ }, cs = {
7913
+ identify: is,
7837
7914
  default: !0,
7838
7915
  tag: "tag:yaml.org,2002:int",
7839
7916
  format: "OCT",
7840
7917
  test: /^[-+]?0[0-7_]+$/,
7841
- resolve: (e, t, n) => ns(e, 1, 8, n),
7842
- stringify: (e) => rs(e, 8, "0")
7843
- }, os = {
7844
- identify: ts,
7918
+ resolve: (e, t, n) => as(e, 1, 8, n),
7919
+ stringify: (e) => os(e, 8, "0")
7920
+ }, ls = {
7921
+ identify: is,
7845
7922
  default: !0,
7846
7923
  tag: "tag:yaml.org,2002:int",
7847
7924
  test: /^[-+]?[0-9][0-9_]*$/,
7848
- resolve: (e, t, n) => ns(e, 0, 10, n),
7849
- stringify: Oo
7850
- }, ss = {
7851
- identify: ts,
7925
+ resolve: (e, t, n) => as(e, 0, 10, n),
7926
+ stringify: jo
7927
+ }, us = {
7928
+ identify: is,
7852
7929
  default: !0,
7853
7930
  tag: "tag:yaml.org,2002:int",
7854
7931
  format: "HEX",
7855
7932
  test: /^[-+]?0x[0-9a-fA-F_]+$/,
7856
- resolve: (e, t, n) => ns(e, 2, 16, n),
7857
- stringify: (e) => rs(e, 16, "0x")
7858
- }, cs = class e extends $ {
7933
+ resolve: (e, t, n) => as(e, 2, 16, n),
7934
+ stringify: (e) => os(e, 16, "0x")
7935
+ }, ds = class e extends $ {
7859
7936
  constructor(t) {
7860
7937
  super(t), this.tag = e.tag;
7861
7938
  }
7862
7939
  add(e) {
7863
7940
  let t;
7864
- t = K(e) ? e : e && typeof e == "object" && "key" in e && "value" in e && e.value === null ? new Q(e.key, null) : new Q(e, null), bo(this.items, t.key) || this.items.push(t);
7941
+ t = K(e) ? e : e && typeof e == "object" && "key" in e && "value" in e && e.value === null ? new Q(e.key, null) : new Q(e, null), Co(this.items, t.key) || this.items.push(t);
7865
7942
  }
7866
7943
  get(e, t) {
7867
- let n = bo(this.items, e);
7944
+ let n = Co(this.items, e);
7868
7945
  return !t && K(n) ? q(n.key) ? n.key.value : n.key : n;
7869
7946
  }
7870
7947
  set(e, t) {
7871
7948
  if (typeof t != "boolean") throw Error(`Expected boolean value for set(key, value) in a YAML set, not ${typeof t}`);
7872
- let n = bo(this.items, e);
7949
+ let n = Co(this.items, e);
7873
7950
  n && !t ? this.items.splice(this.items.indexOf(n), 1) : !n && t && this.items.push(new Q(e));
7874
7951
  }
7875
7952
  toJSON(e, t) {
@@ -7882,21 +7959,21 @@ var is = {
7882
7959
  }
7883
7960
  static from(e, t, n) {
7884
7961
  let { replacer: r } = n, i = new this(e);
7885
- if (t && Symbol.iterator in Object(t)) for (let e of t) typeof r == "function" && (e = r.call(t, e, e)), i.items.push(ho(e, null, n));
7962
+ if (t && Symbol.iterator in Object(t)) for (let e of t) typeof r == "function" && (e = r.call(t, e, e)), i.items.push(vo(e, null, n));
7886
7963
  return i;
7887
7964
  }
7888
7965
  };
7889
- cs.tag = "tag:yaml.org,2002:set";
7890
- var ls = {
7966
+ ds.tag = "tag:yaml.org,2002:set";
7967
+ var fs = {
7891
7968
  collection: "map",
7892
7969
  identify: (e) => e instanceof Set,
7893
- nodeClass: cs,
7970
+ nodeClass: ds,
7894
7971
  default: !1,
7895
7972
  tag: "tag:yaml.org,2002:set",
7896
- createNode: (e, t, n) => cs.from(e, t, n),
7973
+ createNode: (e, t, n) => ds.from(e, t, n),
7897
7974
  resolve(e, t) {
7898
- if (aa(e)) {
7899
- if (e.hasAllNullValues(!0)) return Object.assign(new cs(), e);
7975
+ if (ca(e)) {
7976
+ if (e.hasAllNullValues(!0)) return Object.assign(new ds(), e);
7900
7977
  t("Set items must all have null values");
7901
7978
  } else t("Expected a mapping for this tag");
7902
7979
  return e;
@@ -7904,127 +7981,127 @@ var ls = {
7904
7981
  };
7905
7982
  //#endregion
7906
7983
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/schema/yaml-1.1/timestamp.js
7907
- function us(e, t) {
7984
+ function ps(e, t) {
7908
7985
  let n = e[0], r = n === "-" || n === "+" ? e.substring(1) : e, i = (e) => t ? BigInt(e) : Number(e), a = r.replace(/_/g, "").split(":").reduce((e, t) => e * i(60) + i(t), i(0));
7909
7986
  return n === "-" ? i(-1) * a : a;
7910
7987
  }
7911
- function ds(e) {
7988
+ function ms(e) {
7912
7989
  let { value: t } = e, n = (e) => e;
7913
7990
  if (typeof t == "bigint") n = (e) => BigInt(e);
7914
- else if (isNaN(t) || !isFinite(t)) return Oo(e);
7991
+ else if (isNaN(t) || !isFinite(t)) return jo(e);
7915
7992
  let r = "";
7916
7993
  t < 0 && (r = "-", t *= n(-1));
7917
7994
  let i = n(60), a = [t % i];
7918
7995
  return t < 60 ? a.unshift(0) : (t = (t - a[0]) / i, a.unshift(t % i), t >= 60 && (t = (t - a[0]) / i, a.unshift(t))), r + a.map((e) => String(e).padStart(2, "0")).join(":").replace(/000000\d*$/, "");
7919
7996
  }
7920
- var fs = {
7997
+ var hs = {
7921
7998
  identify: (e) => typeof e == "bigint" || Number.isInteger(e),
7922
7999
  default: !0,
7923
8000
  tag: "tag:yaml.org,2002:int",
7924
8001
  format: "TIME",
7925
8002
  test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+$/,
7926
- resolve: (e, t, { intAsBigInt: n }) => us(e, n),
7927
- stringify: ds
7928
- }, ps = {
8003
+ resolve: (e, t, { intAsBigInt: n }) => ps(e, n),
8004
+ stringify: ms
8005
+ }, gs = {
7929
8006
  identify: (e) => typeof e == "number",
7930
8007
  default: !0,
7931
8008
  tag: "tag:yaml.org,2002:float",
7932
8009
  format: "TIME",
7933
8010
  test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*$/,
7934
- resolve: (e) => us(e, !1),
7935
- stringify: ds
7936
- }, ms = {
8011
+ resolve: (e) => ps(e, !1),
8012
+ stringify: ms
8013
+ }, _s = {
7937
8014
  identify: (e) => e instanceof Date,
7938
8015
  default: !0,
7939
8016
  tag: "tag:yaml.org,2002:timestamp",
7940
8017
  test: RegExp("^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})(?:(?:t|T|[ \\t]+)([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}(\\.[0-9]+)?)(?:[ \\t]*(Z|[-+][012]?[0-9](?::[0-9]{2})?))?)?$"),
7941
8018
  resolve(e) {
7942
- let t = e.match(ms.test);
8019
+ let t = e.match(_s.test);
7943
8020
  if (!t) throw Error("!!timestamp expects a date, starting with yyyy-mm-dd");
7944
8021
  let [, n, r, i, a, o, s] = t.map(Number), c = t[7] ? Number((t[7] + "00").substr(1, 3)) : 0, l = Date.UTC(n, r - 1, i, a || 0, o || 0, s || 0, c), u = t[8];
7945
8022
  if (u && u !== "Z") {
7946
- let e = us(u, !1);
8023
+ let e = ps(u, !1);
7947
8024
  Math.abs(e) < 30 && (e *= 60), l -= 6e4 * e;
7948
8025
  }
7949
8026
  return new Date(l);
7950
8027
  },
7951
8028
  stringify: ({ value: e }) => e?.toISOString().replace(/(T00:00:00)?\.000Z$/, "") ?? ""
7952
- }, hs = [
7953
- xo,
8029
+ }, vs = [
7954
8030
  wo,
7955
- To,
7956
- Eo,
7957
- Xo,
7958
- Zo,
7959
- is,
7960
- as,
7961
- os,
7962
- ss,
7963
- Qo,
8031
+ Do,
8032
+ Oo,
8033
+ ko,
7964
8034
  $o,
7965
8035
  es,
7966
- Uo,
7967
- so,
7968
- Jo,
7969
- Ko,
8036
+ ss,
8037
+ cs,
7970
8038
  ls,
8039
+ us,
8040
+ ts,
8041
+ ns,
8042
+ rs,
8043
+ Ko,
8044
+ uo,
8045
+ Zo,
8046
+ Yo,
7971
8047
  fs,
7972
- ps,
7973
- ms
7974
- ], gs = /* @__PURE__ */ new Map([
7975
- ["core", Ro],
8048
+ hs,
8049
+ gs,
8050
+ _s
8051
+ ], ys = /* @__PURE__ */ new Map([
8052
+ ["core", Vo],
7976
8053
  ["failsafe", [
7977
- xo,
7978
8054
  wo,
7979
- To
8055
+ Do,
8056
+ Oo
7980
8057
  ]],
7981
- ["json", Ho],
7982
- ["yaml11", hs],
7983
- ["yaml-1.1", hs]
7984
- ]), _s = {
7985
- binary: Uo,
7986
- bool: Do,
7987
- float: jo,
7988
- floatExp: Ao,
7989
- floatNaN: ko,
7990
- floatTime: ps,
7991
- int: Io,
7992
- intHex: Lo,
7993
- intOct: Fo,
7994
- intTime: fs,
7995
- map: xo,
7996
- merge: so,
7997
- null: Eo,
7998
- omap: Jo,
7999
- pairs: Ko,
8000
- seq: wo,
8001
- set: ls,
8002
- timestamp: ms
8003
- }, vs = {
8004
- "tag:yaml.org,2002:binary": Uo,
8005
- "tag:yaml.org,2002:merge": so,
8006
- "tag:yaml.org,2002:omap": Jo,
8007
- "tag:yaml.org,2002:pairs": Ko,
8008
- "tag:yaml.org,2002:set": ls,
8009
- "tag:yaml.org,2002:timestamp": ms
8058
+ ["json", Go],
8059
+ ["yaml11", vs],
8060
+ ["yaml-1.1", vs]
8061
+ ]), bs = {
8062
+ binary: Ko,
8063
+ bool: Ao,
8064
+ float: Po,
8065
+ floatExp: No,
8066
+ floatNaN: Mo,
8067
+ floatTime: gs,
8068
+ int: zo,
8069
+ intHex: Bo,
8070
+ intOct: Ro,
8071
+ intTime: hs,
8072
+ map: wo,
8073
+ merge: uo,
8074
+ null: ko,
8075
+ omap: Zo,
8076
+ pairs: Yo,
8077
+ seq: Do,
8078
+ set: fs,
8079
+ timestamp: _s
8080
+ }, xs = {
8081
+ "tag:yaml.org,2002:binary": Ko,
8082
+ "tag:yaml.org,2002:merge": uo,
8083
+ "tag:yaml.org,2002:omap": Zo,
8084
+ "tag:yaml.org,2002:pairs": Yo,
8085
+ "tag:yaml.org,2002:set": fs,
8086
+ "tag:yaml.org,2002:timestamp": _s
8010
8087
  };
8011
- function ys(e, t, n) {
8012
- let r = gs.get(t);
8013
- if (r && !e) return n && !r.includes(so) ? r.concat(so) : r.slice();
8088
+ function Ss(e, t, n) {
8089
+ let r = ys.get(t);
8090
+ if (r && !e) return n && !r.includes(uo) ? r.concat(uo) : r.slice();
8014
8091
  let i = r;
8015
8092
  if (!i) {
8016
8093
  if (Array.isArray(e)) i = [];
8017
8094
  else {
8018
- let e = Array.from(gs.keys()).filter((e) => e !== "yaml11").map((e) => JSON.stringify(e)).join(", ");
8095
+ let e = Array.from(ys.keys()).filter((e) => e !== "yaml11").map((e) => JSON.stringify(e)).join(", ");
8019
8096
  throw Error(`Unknown schema "${t}"; use one of ${e} or define customTags array`);
8020
8097
  }
8021
8098
  }
8022
8099
  if (Array.isArray(e)) for (let t of e) i = i.concat(t);
8023
8100
  else typeof e == "function" && (i = e(i.slice()));
8024
- return n && (i = i.concat(so)), i.reduce((e, t) => {
8025
- let n = typeof t == "string" ? _s[t] : t;
8101
+ return n && (i = i.concat(uo)), i.reduce((e, t) => {
8102
+ let n = typeof t == "string" ? bs[t] : t;
8026
8103
  if (!n) {
8027
- let e = JSON.stringify(t), n = Object.keys(_s).map((e) => JSON.stringify(e)).join(", ");
8104
+ let e = JSON.stringify(t), n = Object.keys(bs).map((e) => JSON.stringify(e)).join(", ");
8028
8105
  throw Error(`Unknown custom tag ${e}; use one of ${n}`);
8029
8106
  }
8030
8107
  return e.includes(n) || e.push(n), e;
@@ -8032,9 +8109,9 @@ function ys(e, t, n) {
8032
8109
  }
8033
8110
  //#endregion
8034
8111
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/schema/Schema.js
8035
- var bs = (e, t) => e.key < t.key ? -1 : +(e.key > t.key), xs = class e {
8112
+ var Cs = (e, t) => e.key < t.key ? -1 : +(e.key > t.key), ws = class e {
8036
8113
  constructor({ compat: e, customTags: t, merge: n, resolveKnownTags: r, schema: i, sortMapEntries: a, toStringDefaults: o }) {
8037
- this.compat = Array.isArray(e) ? ys(e, "compat") : e ? ys(null, e) : null, this.name = typeof i == "string" && i || "core", this.knownTags = r ? vs : {}, this.tags = ys(t, this.name, n), this.toStringOptions = o ?? null, Object.defineProperty(this, $i, { value: xo }), Object.defineProperty(this, ta, { value: To }), Object.defineProperty(this, na, { value: wo }), this.sortMapEntries = typeof a == "function" ? a : a === !0 ? bs : null;
8114
+ this.compat = Array.isArray(e) ? Ss(e, "compat") : e ? Ss(null, e) : null, this.name = typeof i == "string" && i || "core", this.knownTags = r ? xs : {}, this.tags = Ss(t, this.name, n), this.toStringOptions = o ?? null, Object.defineProperty(this, na, { value: wo }), Object.defineProperty(this, ia, { value: Oo }), Object.defineProperty(this, aa, { value: Do }), this.sortMapEntries = typeof a == "function" ? a : a === !0 ? Cs : null;
8038
8115
  }
8039
8116
  clone() {
8040
8117
  let t = Object.create(e.prototype, Object.getOwnPropertyDescriptors(this));
@@ -8043,47 +8120,47 @@ var bs = (e, t) => e.key < t.key ? -1 : +(e.key > t.key), xs = class e {
8043
8120
  };
8044
8121
  //#endregion
8045
8122
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/stringify/stringifyDocument.js
8046
- function Ss(e, t) {
8123
+ function Ts(e, t) {
8047
8124
  let n = [], r = t.directives === !0;
8048
8125
  if (t.directives !== !1 && e.directives) {
8049
8126
  let t = e.directives.toString(e);
8050
8127
  t ? (n.push(t), r = !0) : e.directives.docStart && (r = !0);
8051
8128
  }
8052
8129
  r && n.push("---");
8053
- let i = eo(e, t), { commentString: a } = i.options;
8130
+ let i = ro(e, t), { commentString: a } = i.options;
8054
8131
  if (e.commentBefore) {
8055
8132
  n.length !== 1 && n.unshift("");
8056
8133
  let t = a(e.commentBefore);
8057
- n.unshift(La(t, ""));
8134
+ n.unshift(Ba(t, ""));
8058
8135
  }
8059
8136
  let o = !1, s = null;
8060
8137
  if (e.contents) {
8061
8138
  if (Y(e.contents)) {
8062
8139
  if (e.contents.spaceBefore && r && n.push(""), e.contents.commentBefore) {
8063
8140
  let t = a(e.contents.commentBefore);
8064
- n.push(La(t, ""));
8141
+ n.push(Ba(t, ""));
8065
8142
  }
8066
8143
  i.forceBlockIndent = !!e.comment, s = e.contents.comment;
8067
8144
  }
8068
- let t = s ? void 0 : () => o = !0, c = ro(e.contents, i, () => s = null, t);
8069
- s && (c += Ra(c, "", a(s))), (c[0] === "|" || c[0] === ">") && n[n.length - 1] === "---" ? n[n.length - 1] = `--- ${c}` : n.push(c);
8070
- } else n.push(ro(e.contents, i));
8145
+ let t = s ? void 0 : () => o = !0, c = oo(e.contents, i, () => s = null, t);
8146
+ s && (c += Va(c, "", a(s))), (c[0] === "|" || c[0] === ">") && n[n.length - 1] === "---" ? n[n.length - 1] = `--- ${c}` : n.push(c);
8147
+ } else n.push(oo(e.contents, i));
8071
8148
  if (e.directives?.docEnd) {
8072
8149
  if (e.comment) {
8073
8150
  let t = a(e.comment);
8074
- t.includes("\n") ? (n.push("..."), n.push(La(t, ""))) : n.push(`... ${t}`);
8151
+ t.includes("\n") ? (n.push("..."), n.push(Ba(t, ""))) : n.push(`... ${t}`);
8075
8152
  } else n.push("...");
8076
8153
  } else {
8077
8154
  let t = e.comment;
8078
- t && o && (t = t.replace(/^\n+/, "")), t && ((!o || s) && n[n.length - 1] !== "" && n.push(""), n.push(La(a(t), "")));
8155
+ t && o && (t = t.replace(/^\n+/, "")), t && ((!o || s) && n[n.length - 1] !== "" && n.push(""), n.push(Ba(a(t), "")));
8079
8156
  }
8080
8157
  return n.join("\n") + "\n";
8081
8158
  }
8082
8159
  //#endregion
8083
8160
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/doc/Document.js
8084
- var Cs = class e {
8161
+ var Es = class e {
8085
8162
  constructor(e, t, n) {
8086
- this.commentBefore = null, this.comment = null, this.errors = [], this.warnings = [], Object.defineProperty(this, G, { value: Qi });
8163
+ this.commentBefore = null, this.comment = null, this.errors = [], this.warnings = [], Object.defineProperty(this, G, { value: ta });
8087
8164
  let r = null;
8088
8165
  typeof t == "function" || Array.isArray(t) ? r = t : n === void 0 && t && (n = t, t = void 0);
8089
8166
  let i = Object.assign({
@@ -8098,24 +8175,24 @@ var Cs = class e {
8098
8175
  }, n);
8099
8176
  this.options = i;
8100
8177
  let { version: a } = i;
8101
- n?._directives ? (this.directives = n._directives.atDocument(), this.directives.yaml.explicit && (a = this.directives.yaml.version)) : this.directives = new ya({ version: a }), this.setSchema(a, n), this.contents = e === void 0 ? null : this.createNode(e, r, n);
8178
+ n?._directives ? (this.directives = n._directives.atDocument(), this.directives.yaml.explicit && (a = this.directives.yaml.version)) : this.directives = new Sa({ version: a }), this.setSchema(a, n), this.contents = e === void 0 ? null : this.createNode(e, r, n);
8102
8179
  }
8103
8180
  clone() {
8104
- let t = Object.create(e.prototype, { [G]: { value: Qi } });
8181
+ let t = Object.create(e.prototype, { [G]: { value: ta } });
8105
8182
  return t.commentBefore = this.commentBefore, t.comment = this.comment, t.errors = this.errors.slice(), t.warnings = this.warnings.slice(), t.options = Object.assign({}, this.options), this.directives && (t.directives = this.directives.clone()), t.schema = this.schema.clone(), t.contents = Y(this.contents) ? this.contents.clone(t.schema) : this.contents, this.range && (t.range = this.range.slice()), t;
8106
8183
  }
8107
8184
  add(e) {
8108
- ws(this.contents) && this.contents.add(e);
8185
+ Ds(this.contents) && this.contents.add(e);
8109
8186
  }
8110
8187
  addIn(e, t) {
8111
- ws(this.contents) && this.contents.addIn(e, t);
8188
+ Ds(this.contents) && this.contents.addIn(e, t);
8112
8189
  }
8113
8190
  createAlias(e, t) {
8114
8191
  if (!e.anchor) {
8115
- let n = xa(this);
8116
- e.anchor = !t || n.has(t) ? Sa(t || "a", n) : t;
8192
+ let n = wa(this);
8193
+ e.anchor = !t || n.has(t) ? Ta(t || "a", n) : t;
8117
8194
  }
8118
- return new Da(e.anchor);
8195
+ return new Aa(e.anchor);
8119
8196
  }
8120
8197
  createNode(e, t, n) {
8121
8198
  let r;
@@ -8124,7 +8201,7 @@ var Cs = class e {
8124
8201
  let e = t.filter((e) => typeof e == "number" || e instanceof String || e instanceof Number).map(String);
8125
8202
  e.length > 0 && (t = t.concat(e)), r = t;
8126
8203
  } else n === void 0 && t && (n = t, t = void 0);
8127
- let { aliasDuplicateObjects: i, anchorPrefix: a, flow: o, keepUndefined: s, onTagObj: c, tag: l } = n ?? {}, { onAnchor: u, setAnchors: d, sourceObjects: f } = Ca(this, a || "a"), p = {
8204
+ let { aliasDuplicateObjects: i, anchorPrefix: a, flow: o, keepUndefined: s, onTagObj: c, tag: l } = n ?? {}, { onAnchor: u, setAnchors: d, sourceObjects: f } = Ea(this, a || "a"), p = {
8128
8205
  aliasDuplicateObjects: i ?? !0,
8129
8206
  keepUndefined: s ?? !1,
8130
8207
  onAnchor: u,
@@ -8132,49 +8209,49 @@ var Cs = class e {
8132
8209
  replacer: r,
8133
8210
  schema: this.schema,
8134
8211
  sourceObjects: f
8135
- }, m = Ma(e, l, p);
8212
+ }, m = Fa(e, l, p);
8136
8213
  return o && J(m) && (m.flow = !0), d(), m;
8137
8214
  }
8138
8215
  createPair(e, t, n = {}) {
8139
8216
  return new Q(this.createNode(e, null, n), this.createNode(t, null, n));
8140
8217
  }
8141
8218
  delete(e) {
8142
- return ws(this.contents) ? this.contents.delete(e) : !1;
8219
+ return Ds(this.contents) ? this.contents.delete(e) : !1;
8143
8220
  }
8144
8221
  deleteIn(e) {
8145
- return Pa(e) ? this.contents != null && (this.contents = null, !0) : ws(this.contents) ? this.contents.deleteIn(e) : !1;
8222
+ return La(e) ? this.contents != null && (this.contents = null, !0) : Ds(this.contents) ? this.contents.deleteIn(e) : !1;
8146
8223
  }
8147
8224
  get(e, t) {
8148
8225
  return J(this.contents) ? this.contents.get(e, t) : void 0;
8149
8226
  }
8150
8227
  getIn(e, t) {
8151
- return Pa(e) ? !t && q(this.contents) ? this.contents.value : this.contents : J(this.contents) ? this.contents.getIn(e, t) : void 0;
8228
+ return La(e) ? !t && q(this.contents) ? this.contents.value : this.contents : J(this.contents) ? this.contents.getIn(e, t) : void 0;
8152
8229
  }
8153
8230
  has(e) {
8154
8231
  return J(this.contents) ? this.contents.has(e) : !1;
8155
8232
  }
8156
8233
  hasIn(e) {
8157
- return Pa(e) ? this.contents !== void 0 : J(this.contents) ? this.contents.hasIn(e) : !1;
8234
+ return La(e) ? this.contents !== void 0 : J(this.contents) ? this.contents.hasIn(e) : !1;
8158
8235
  }
8159
8236
  set(e, t) {
8160
- this.contents == null ? this.contents = Na(this.schema, [e], t) : ws(this.contents) && this.contents.set(e, t);
8237
+ this.contents == null ? this.contents = Ia(this.schema, [e], t) : Ds(this.contents) && this.contents.set(e, t);
8161
8238
  }
8162
8239
  setIn(e, t) {
8163
- Pa(e) ? this.contents = t : this.contents == null ? this.contents = Na(this.schema, Array.from(e), t) : ws(this.contents) && this.contents.setIn(e, t);
8240
+ La(e) ? this.contents = t : this.contents == null ? this.contents = Ia(this.schema, Array.from(e), t) : Ds(this.contents) && this.contents.setIn(e, t);
8164
8241
  }
8165
8242
  setSchema(e, t = {}) {
8166
8243
  typeof e == "number" && (e = String(e));
8167
8244
  let n;
8168
8245
  switch (e) {
8169
8246
  case "1.1":
8170
- this.directives ? this.directives.yaml.version = "1.1" : this.directives = new ya({ version: "1.1" }), n = {
8247
+ this.directives ? this.directives.yaml.version = "1.1" : this.directives = new Sa({ version: "1.1" }), n = {
8171
8248
  resolveKnownTags: !1,
8172
8249
  schema: "yaml-1.1"
8173
8250
  };
8174
8251
  break;
8175
8252
  case "1.2":
8176
8253
  case "next":
8177
- this.directives ? this.directives.yaml.version = e : this.directives = new ya({ version: e }), n = {
8254
+ this.directives ? this.directives.yaml.version = e : this.directives = new Sa({ version: e }), n = {
8178
8255
  resolveKnownTags: !0,
8179
8256
  schema: "core"
8180
8257
  };
@@ -8188,7 +8265,7 @@ var Cs = class e {
8188
8265
  }
8189
8266
  }
8190
8267
  if (t.schema instanceof Object) this.schema = t.schema;
8191
- else if (n) this.schema = new xs(Object.assign(n, t));
8268
+ else if (n) this.schema = new ws(Object.assign(n, t));
8192
8269
  else throw Error("With a null YAML version, the { schema: Schema } option is required");
8193
8270
  }
8194
8271
  toJS({ json: e, jsonArg: t, mapAsMap: n, maxAliasCount: r, onAnchor: i, reviver: a } = {}) {
@@ -8199,9 +8276,9 @@ var Cs = class e {
8199
8276
  mapAsMap: n === !0,
8200
8277
  mapKeyWarned: !1,
8201
8278
  maxAliasCount: typeof r == "number" ? r : 100
8202
- }, s = Ta(this.contents, t ?? "", o);
8279
+ }, s = Oa(this.contents, t ?? "", o);
8203
8280
  if (typeof i == "function") for (let { count: e, res: t } of o.anchors.values()) i(t, e);
8204
- return typeof a == "function" ? wa(a, { "": s }, "", s) : s;
8281
+ return typeof a == "function" ? Da(a, { "": s }, "", s) : s;
8205
8282
  }
8206
8283
  toJSON(e, t) {
8207
8284
  return this.toJS({
@@ -8217,28 +8294,28 @@ var Cs = class e {
8217
8294
  let t = JSON.stringify(e.indent);
8218
8295
  throw Error(`"indent" option must be a positive integer, not ${t}`);
8219
8296
  }
8220
- return Ss(this, e);
8297
+ return Ts(this, e);
8221
8298
  }
8222
8299
  };
8223
- function ws(e) {
8300
+ function Ds(e) {
8224
8301
  if (J(e)) return !0;
8225
8302
  throw Error("Expected a YAML collection as document contents");
8226
8303
  }
8227
8304
  //#endregion
8228
8305
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/errors.js
8229
- var Ts = class extends Error {
8306
+ var Os = class extends Error {
8230
8307
  constructor(e, t, n, r) {
8231
8308
  super(), this.name = e, this.code = n, this.message = r, this.pos = t;
8232
8309
  }
8233
- }, Es = class extends Ts {
8310
+ }, ks = class extends Os {
8234
8311
  constructor(e, t, n) {
8235
8312
  super("YAMLParseError", e, t, n);
8236
8313
  }
8237
- }, Ds = class extends Ts {
8314
+ }, As = class extends Os {
8238
8315
  constructor(e, t, n) {
8239
8316
  super("YAMLWarning", e, t, n);
8240
8317
  }
8241
- }, Os = (e, t) => (n) => {
8318
+ }, js = (e, t) => (n) => {
8242
8319
  if (n.pos[0] === -1) return;
8243
8320
  n.linePos = n.pos.map((e) => t.linePos(e));
8244
8321
  let { line: r, col: i } = n.linePos[0];
@@ -8261,7 +8338,7 @@ var Ts = class extends Error {
8261
8338
  };
8262
8339
  //#endregion
8263
8340
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/compose/resolve-props.js
8264
- function ks(e, { flow: t, indicator: n, next: r, offset: i, onError: a, parentIndent: o, startOnNewline: s }) {
8341
+ function Ms(e, { flow: t, indicator: n, next: r, offset: i, onError: a, parentIndent: o, startOnNewline: s }) {
8265
8342
  let c = !1, l = s, u = s, d = "", f = "", p = !1, m = !1, h = null, g = null, _ = null, v = null, y = null, b = null, x = null;
8266
8343
  for (let i of e) switch (m &&= (i.type !== "space" && i.type !== "newline" && i.type !== "comma" && a(i.offset, "MISSING_CHAR", "Tags and anchors must be separated from the next token by white space"), !1), h &&= (l && i.type !== "comment" && i.type !== "newline" && a(h, "TAB_AS_INDENT", "Tabs are not allowed as indentation"), null), i.type) {
8267
8344
  case "space":
@@ -8307,7 +8384,7 @@ function ks(e, { flow: t, indicator: n, next: r, offset: i, onError: a, parentIn
8307
8384
  }
8308
8385
  //#endregion
8309
8386
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/compose/util-contains-newline.js
8310
- function As(e) {
8387
+ function Ns(e) {
8311
8388
  if (!e) return null;
8312
8389
  switch (e.type) {
8313
8390
  case "alias":
@@ -8325,7 +8402,7 @@ function As(e) {
8325
8402
  if (t.sep) {
8326
8403
  for (let e of t.sep) if (e.type === "newline") return !0;
8327
8404
  }
8328
- if (As(t.key) || As(t.value)) return !0;
8405
+ if (Ns(t.key) || Ns(t.value)) return !0;
8329
8406
  }
8330
8407
  return !1;
8331
8408
  default: return !0;
@@ -8333,15 +8410,15 @@ function As(e) {
8333
8410
  }
8334
8411
  //#endregion
8335
8412
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/compose/util-flow-indent-check.js
8336
- function js(e, t, n) {
8413
+ function Ps(e, t, n) {
8337
8414
  if (t?.type === "flow-collection") {
8338
8415
  let r = t.end[0];
8339
- r.indent === e && (r.source === "]" || r.source === "}") && As(t) && n(r, "BAD_INDENT", "Flow end indicator should be more indented than parent", !0);
8416
+ r.indent === e && (r.source === "]" || r.source === "}") && Ns(t) && n(r, "BAD_INDENT", "Flow end indicator should be more indented than parent", !0);
8340
8417
  }
8341
8418
  }
8342
8419
  //#endregion
8343
8420
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/compose/util-map-includes.js
8344
- function Ms(e, t, n) {
8421
+ function Fs(e, t, n) {
8345
8422
  let { uniqueKeys: r } = e.options;
8346
8423
  if (r === !1) return !1;
8347
8424
  let i = typeof r == "function" ? r : (e, t) => e === t || q(e) && q(t) && e.value === t.value;
@@ -8349,13 +8426,13 @@ function Ms(e, t, n) {
8349
8426
  }
8350
8427
  //#endregion
8351
8428
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/compose/resolve-block-map.js
8352
- var Ns = "All mapping items must start at the same column";
8353
- function Ps({ composeNode: e, composeEmptyNode: t }, n, r, i, a) {
8429
+ var Is = "All mapping items must start at the same column";
8430
+ function Ls({ composeNode: e, composeEmptyNode: t }, n, r, i, a) {
8354
8431
  let o = new ((a?.nodeClass) ?? $)(n.schema);
8355
8432
  n.atRoot &&= !1;
8356
8433
  let s = r.offset, c = null;
8357
8434
  for (let a of r.items) {
8358
- let { start: l, key: u, sep: d, value: f } = a, p = ks(l, {
8435
+ let { start: l, key: u, sep: d, value: f } = a, p = Ms(l, {
8359
8436
  indicator: "explicit-key-ind",
8360
8437
  next: u ?? d?.[0],
8361
8438
  offset: s,
@@ -8364,16 +8441,16 @@ function Ps({ composeNode: e, composeEmptyNode: t }, n, r, i, a) {
8364
8441
  startOnNewline: !0
8365
8442
  }), m = !p.found;
8366
8443
  if (m) {
8367
- if (u && (u.type === "block-seq" ? i(s, "BLOCK_AS_IMPLICIT_KEY", "A block sequence may not be used as an implicit map key") : "indent" in u && u.indent !== r.indent && i(s, "BAD_INDENT", Ns)), !p.anchor && !p.tag && !d) {
8444
+ if (u && (u.type === "block-seq" ? i(s, "BLOCK_AS_IMPLICIT_KEY", "A block sequence may not be used as an implicit map key") : "indent" in u && u.indent !== r.indent && i(s, "BAD_INDENT", Is)), !p.anchor && !p.tag && !d) {
8368
8445
  c = p.end, p.comment && (o.comment ? o.comment += "\n" + p.comment : o.comment = p.comment);
8369
8446
  continue;
8370
8447
  }
8371
- (p.newlineAfterProp || As(u)) && i(u ?? l[l.length - 1], "MULTILINE_IMPLICIT_KEY", "Implicit keys need to be on a single line");
8372
- } else p.found?.indent !== r.indent && i(s, "BAD_INDENT", Ns);
8448
+ (p.newlineAfterProp || Ns(u)) && i(u ?? l[l.length - 1], "MULTILINE_IMPLICIT_KEY", "Implicit keys need to be on a single line");
8449
+ } else p.found?.indent !== r.indent && i(s, "BAD_INDENT", Is);
8373
8450
  n.atKey = !0;
8374
8451
  let h = p.end, g = u ? e(n, u, p, i) : t(n, h, l, null, p, i);
8375
- n.schema.compat && js(r.indent, u, i), n.atKey = !1, Ms(n, o.items, g) && i(h, "DUPLICATE_KEY", "Map keys must be unique");
8376
- let _ = ks(d ?? [], {
8452
+ n.schema.compat && Ps(r.indent, u, i), n.atKey = !1, Fs(n, o.items, g) && i(h, "DUPLICATE_KEY", "Map keys must be unique");
8453
+ let _ = Ms(d ?? [], {
8377
8454
  indicator: "map-value-ind",
8378
8455
  next: f,
8379
8456
  offset: g.range[2],
@@ -8384,7 +8461,7 @@ function Ps({ composeNode: e, composeEmptyNode: t }, n, r, i, a) {
8384
8461
  if (s = _.end, _.found) {
8385
8462
  m && (f?.type === "block-map" && !_.hasNewline && i(s, "BLOCK_AS_IMPLICIT_KEY", "Nested mappings are not allowed in compact mappings"), n.options.strict && p.start < _.found.offset - 1024 && i(g.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key"));
8386
8463
  let c = f ? e(n, f, _, i) : t(n, s, d, null, _, i);
8387
- n.schema.compat && js(r.indent, f, i), s = c.range[2];
8464
+ n.schema.compat && Ps(r.indent, f, i), s = c.range[2];
8388
8465
  let l = new Q(g, c);
8389
8466
  n.options.keepSourceTokens && (l.srcToken = a), o.items.push(l);
8390
8467
  } else {
@@ -8401,12 +8478,12 @@ function Ps({ composeNode: e, composeEmptyNode: t }, n, r, i, a) {
8401
8478
  }
8402
8479
  //#endregion
8403
8480
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/compose/resolve-block-seq.js
8404
- function Fs({ composeNode: e, composeEmptyNode: t }, n, r, i, a) {
8405
- let o = new ((a?.nodeClass) ?? So)(n.schema);
8481
+ function Rs({ composeNode: e, composeEmptyNode: t }, n, r, i, a) {
8482
+ let o = new ((a?.nodeClass) ?? To)(n.schema);
8406
8483
  n.atRoot &&= !1, n.atKey &&= !1;
8407
8484
  let s = r.offset, c = null;
8408
8485
  for (let { start: a, value: l } of r.items) {
8409
- let u = ks(a, {
8486
+ let u = Ms(a, {
8410
8487
  indicator: "seq-item-ind",
8411
8488
  next: l,
8412
8489
  offset: s,
@@ -8422,7 +8499,7 @@ function Fs({ composeNode: e, composeEmptyNode: t }, n, r, i, a) {
8422
8499
  }
8423
8500
  }
8424
8501
  let d = l ? e(n, l, u, i) : t(n, u.end, a, null, u, i);
8425
- n.schema.compat && js(r.indent, l, i), s = d.range[2], o.items.push(d);
8502
+ n.schema.compat && Ps(r.indent, l, i), s = d.range[2], o.items.push(d);
8426
8503
  }
8427
8504
  return o.range = [
8428
8505
  r.offset,
@@ -8432,7 +8509,7 @@ function Fs({ composeNode: e, composeEmptyNode: t }, n, r, i, a) {
8432
8509
  }
8433
8510
  //#endregion
8434
8511
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/compose/resolve-end.js
8435
- function Is(e, t, n, r) {
8512
+ function zs(e, t, n, r) {
8436
8513
  let i = "";
8437
8514
  if (e) {
8438
8515
  let a = !1, o = "";
@@ -8463,15 +8540,15 @@ function Is(e, t, n, r) {
8463
8540
  }
8464
8541
  //#endregion
8465
8542
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/compose/resolve-flow-collection.js
8466
- var Ls = "Block collections are not allowed within flow collections", Rs = (e) => e && (e.type === "block-map" || e.type === "block-seq");
8467
- function zs({ composeNode: e, composeEmptyNode: t }, n, r, i, a) {
8468
- let o = r.start.source === "{", s = o ? "flow map" : "flow sequence", c = new ((a?.nodeClass) ?? (o ? $ : So))(n.schema);
8543
+ var Bs = "Block collections are not allowed within flow collections", Vs = (e) => e && (e.type === "block-map" || e.type === "block-seq");
8544
+ function Hs({ composeNode: e, composeEmptyNode: t }, n, r, i, a) {
8545
+ let o = r.start.source === "{", s = o ? "flow map" : "flow sequence", c = new ((a?.nodeClass) ?? (o ? $ : To))(n.schema);
8469
8546
  c.flow = !0;
8470
8547
  let l = n.atRoot;
8471
8548
  l && (n.atRoot = !1), n.atKey &&= !1;
8472
8549
  let u = r.offset + r.start.source.length;
8473
8550
  for (let a = 0; a < r.items.length; ++a) {
8474
- let l = r.items[a], { start: d, key: f, sep: p, value: m } = l, h = ks(d, {
8551
+ let l = r.items[a], { start: d, key: f, sep: p, value: m } = l, h = Ms(d, {
8475
8552
  flow: s,
8476
8553
  indicator: "explicit-key-ind",
8477
8554
  next: f ?? p?.[0],
@@ -8485,7 +8562,7 @@ function zs({ composeNode: e, composeEmptyNode: t }, n, r, i, a) {
8485
8562
  a === 0 && h.comma ? i(h.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${s}`) : a < r.items.length - 1 && i(h.start, "UNEXPECTED_TOKEN", `Unexpected empty item in ${s}`), h.comment && (c.comment ? c.comment += "\n" + h.comment : c.comment = h.comment), u = h.end;
8486
8563
  continue;
8487
8564
  }
8488
- !o && n.options.strict && As(f) && i(f, "MULTILINE_IMPLICIT_KEY", "Implicit keys of flow sequence pairs need to be on a single line");
8565
+ !o && n.options.strict && Ns(f) && i(f, "MULTILINE_IMPLICIT_KEY", "Implicit keys of flow sequence pairs need to be on a single line");
8489
8566
  }
8490
8567
  if (a === 0) h.comma && i(h.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${s}`);
8491
8568
  else if (h.comma || i(h.start, "MISSING_CHAR", `Missing , between ${s} items`), h.comment) {
@@ -8505,12 +8582,12 @@ function zs({ composeNode: e, composeEmptyNode: t }, n, r, i, a) {
8505
8582
  }
8506
8583
  if (!o && !p && !h.found) {
8507
8584
  let r = m ? e(n, m, h, i) : t(n, h.end, p, null, h, i);
8508
- c.items.push(r), u = r.range[2], Rs(m) && i(r.range, "BLOCK_IN_FLOW", Ls);
8585
+ c.items.push(r), u = r.range[2], Vs(m) && i(r.range, "BLOCK_IN_FLOW", Bs);
8509
8586
  } else {
8510
8587
  n.atKey = !0;
8511
8588
  let a = h.end, g = f ? e(n, f, h, i) : t(n, a, d, null, h, i);
8512
- Rs(f) && i(g.range, "BLOCK_IN_FLOW", Ls), n.atKey = !1;
8513
- let _ = ks(p ?? [], {
8589
+ Vs(f) && i(g.range, "BLOCK_IN_FLOW", Bs), n.atKey = !1;
8590
+ let _ = Ms(p ?? [], {
8514
8591
  flow: s,
8515
8592
  indicator: "map-value-ind",
8516
8593
  next: m,
@@ -8532,11 +8609,11 @@ function zs({ composeNode: e, composeEmptyNode: t }, n, r, i, a) {
8532
8609
  }
8533
8610
  } else m && ("source" in m && m.source?.[0] === ":" ? i(m, "MISSING_CHAR", `Missing space after : in ${s}`) : i(_.start, "MISSING_CHAR", `Missing , or : between ${s} items`));
8534
8611
  let v = m ? e(n, m, _, i) : _.found ? t(n, _.end, p, null, _, i) : null;
8535
- v ? Rs(m) && i(v.range, "BLOCK_IN_FLOW", Ls) : _.comment && (g.comment ? g.comment += "\n" + _.comment : g.comment = _.comment);
8612
+ v ? Vs(m) && i(v.range, "BLOCK_IN_FLOW", Bs) : _.comment && (g.comment ? g.comment += "\n" + _.comment : g.comment = _.comment);
8536
8613
  let y = new Q(g, v);
8537
8614
  if (n.options.keepSourceTokens && (y.srcToken = l), o) {
8538
8615
  let e = c;
8539
- Ms(n, e.items, g) && i(a, "DUPLICATE_KEY", "Map keys must be unique"), e.items.push(y);
8616
+ Fs(n, e.items, g) && i(a, "DUPLICATE_KEY", "Map keys must be unique"), e.items.push(y);
8540
8617
  } else {
8541
8618
  let e = new $(n.schema);
8542
8619
  e.flow = !0, e.items.push(y);
@@ -8557,7 +8634,7 @@ function zs({ composeNode: e, composeEmptyNode: t }, n, r, i, a) {
8557
8634
  i(u, l ? "MISSING_CHAR" : "BAD_INDENT", t), f && f.source.length !== 1 && p.unshift(f);
8558
8635
  }
8559
8636
  if (p.length > 0) {
8560
- let e = Is(p, m, n.options.strict, i);
8637
+ let e = zs(p, m, n.options.strict, i);
8561
8638
  e.comment && (c.comment ? c.comment += "\n" + e.comment : c.comment = e.comment), c.range = [
8562
8639
  r.offset,
8563
8640
  m,
@@ -8572,31 +8649,31 @@ function zs({ composeNode: e, composeEmptyNode: t }, n, r, i, a) {
8572
8649
  }
8573
8650
  //#endregion
8574
8651
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/compose/compose-collection.js
8575
- function Bs(e, t, n, r, i, a) {
8576
- let o = n.type === "block-map" ? Ps(e, t, n, r, a) : n.type === "block-seq" ? Fs(e, t, n, r, a) : zs(e, t, n, r, a), s = o.constructor;
8652
+ function Us(e, t, n, r, i, a) {
8653
+ let o = n.type === "block-map" ? Ls(e, t, n, r, a) : n.type === "block-seq" ? Rs(e, t, n, r, a) : Hs(e, t, n, r, a), s = o.constructor;
8577
8654
  return i === "!" || i === s.tagName ? (o.tag = s.tagName, o) : (i && (o.tag = i), o);
8578
8655
  }
8579
- function Vs(e, t, n, r, i) {
8656
+ function Ws(e, t, n, r, i) {
8580
8657
  let a = r.tag, o = a ? t.directives.tagName(a.source, (e) => i(a, "TAG_RESOLVE_FAILED", e)) : null;
8581
8658
  if (n.type === "block-seq") {
8582
8659
  let { anchor: e, newlineAfterProp: t } = r, n = e && a ? e.offset > a.offset ? e : a : e ?? a;
8583
8660
  n && (!t || t.offset < n.offset) && i(n, "MISSING_CHAR", "Missing newline after block sequence props");
8584
8661
  }
8585
8662
  let s = n.type === "block-map" ? "map" : n.type === "block-seq" ? "seq" : n.start.source === "{" ? "map" : "seq";
8586
- if (!a || !o || o === "!" || o === $.tagName && s === "map" || o === So.tagName && s === "seq") return Bs(e, t, n, i, o);
8663
+ if (!a || !o || o === "!" || o === $.tagName && s === "map" || o === To.tagName && s === "seq") return Us(e, t, n, i, o);
8587
8664
  let c = t.schema.tags.find((e) => e.tag === o && e.collection === s);
8588
8665
  if (!c) {
8589
8666
  let r = t.schema.knownTags[o];
8590
8667
  if (r?.collection === s) t.schema.tags.push(Object.assign({}, r, { default: !1 })), c = r;
8591
- else return r ? i(a, "BAD_COLLECTION_TYPE", `${r.tag} used for ${s} collection, but expects ${r.collection ?? "scalar"}`, !0) : i(a, "TAG_RESOLVE_FAILED", `Unresolved tag: ${o}`, !0), Bs(e, t, n, i, o);
8668
+ else return r ? i(a, "BAD_COLLECTION_TYPE", `${r.tag} used for ${s} collection, but expects ${r.collection ?? "scalar"}`, !0) : i(a, "TAG_RESOLVE_FAILED", `Unresolved tag: ${o}`, !0), Us(e, t, n, i, o);
8592
8669
  }
8593
- let l = Bs(e, t, n, i, o, c), u = c.resolve?.(l, (e) => i(a, "TAG_RESOLVE_FAILED", e), t.options) ?? l, d = Y(u) ? u : new Z(u);
8670
+ let l = Us(e, t, n, i, o, c), u = c.resolve?.(l, (e) => i(a, "TAG_RESOLVE_FAILED", e), t.options) ?? l, d = Y(u) ? u : new Z(u);
8594
8671
  return d.range = l.range, d.tag = o, c?.format && (d.format = c.format), d;
8595
8672
  }
8596
8673
  //#endregion
8597
8674
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/compose/resolve-block-scalar.js
8598
- function Hs(e, t, n) {
8599
- let r = t.offset, i = Us(t, e.options.strict, n);
8675
+ function Gs(e, t, n) {
8676
+ let r = t.offset, i = Ks(t, e.options.strict, n);
8600
8677
  if (!i) return {
8601
8678
  value: "",
8602
8679
  type: null,
@@ -8607,7 +8684,7 @@ function Hs(e, t, n) {
8607
8684
  r
8608
8685
  ]
8609
8686
  };
8610
- let a = i.mode === ">" ? Z.BLOCK_FOLDED : Z.BLOCK_LITERAL, o = t.source ? Ws(t.source) : [], s = o.length;
8687
+ let a = i.mode === ">" ? Z.BLOCK_FOLDED : Z.BLOCK_LITERAL, o = t.source ? qs(t.source) : [], s = o.length;
8611
8688
  for (let e = o.length - 1; e >= 0; --e) {
8612
8689
  let t = o[e][1];
8613
8690
  if (t === "" || t === "\r") s = e;
@@ -8670,7 +8747,7 @@ function Hs(e, t, n) {
8670
8747
  ]
8671
8748
  };
8672
8749
  }
8673
- function Us({ offset: e, props: t }, n, r) {
8750
+ function Ks({ offset: e, props: t }, n, r) {
8674
8751
  /* istanbul ignore if should not happen */
8675
8752
  if (t[0].type !== "block-scalar-header") return r(t[0], "IMPOSSIBLE", "Block scalar header not found"), null;
8676
8753
  let { source: i } = t[0], a = i[0], o = 0, s = "", c = -1;
@@ -8713,24 +8790,24 @@ function Us({ offset: e, props: t }, n, r) {
8713
8790
  length: d
8714
8791
  };
8715
8792
  }
8716
- function Ws(e) {
8793
+ function qs(e) {
8717
8794
  let t = e.split(/\n( *)/), n = t[0], r = n.match(/^( *)/), i = [r?.[1] ? [r[1], n.slice(r[1].length)] : ["", n]];
8718
8795
  for (let e = 1; e < t.length; e += 2) i.push([t[e], t[e + 1]]);
8719
8796
  return i;
8720
8797
  }
8721
8798
  //#endregion
8722
8799
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/compose/resolve-flow-scalar.js
8723
- function Gs(e, t, n) {
8800
+ function Js(e, t, n) {
8724
8801
  let { offset: r, type: i, source: a, end: o } = e, s, c, l = (e, t, i) => n(r + e, t, i);
8725
8802
  switch (i) {
8726
8803
  case "scalar":
8727
- s = Z.PLAIN, c = Ks(a, l);
8804
+ s = Z.PLAIN, c = Ys(a, l);
8728
8805
  break;
8729
8806
  case "single-quoted-scalar":
8730
- s = Z.QUOTE_SINGLE, c = qs(a, l);
8807
+ s = Z.QUOTE_SINGLE, c = Xs(a, l);
8731
8808
  break;
8732
8809
  case "double-quoted-scalar":
8733
- s = Z.QUOTE_DOUBLE, c = Ys(a, l);
8810
+ s = Z.QUOTE_DOUBLE, c = Qs(a, l);
8734
8811
  break;
8735
8812
  /* istanbul ignore next should not happen */
8736
8813
  default: return n(e, "UNEXPECTED_TOKEN", `Expected a flow scalar value, but found: ${i}`), {
@@ -8744,7 +8821,7 @@ function Gs(e, t, n) {
8744
8821
  ]
8745
8822
  };
8746
8823
  }
8747
- let u = r + a.length, d = Is(o, u, t, n);
8824
+ let u = r + a.length, d = zs(o, u, t, n);
8748
8825
  return {
8749
8826
  value: c,
8750
8827
  type: s,
@@ -8756,7 +8833,7 @@ function Gs(e, t, n) {
8756
8833
  ]
8757
8834
  };
8758
8835
  }
8759
- function Ks(e, t) {
8836
+ function Ys(e, t) {
8760
8837
  let n = "";
8761
8838
  switch (e[0]) {
8762
8839
  /* istanbul ignore next should not happen */
@@ -8776,12 +8853,12 @@ function Ks(e, t) {
8776
8853
  case "@":
8777
8854
  case "`": n = `reserved character ${e[0]}`;
8778
8855
  }
8779
- return n && t(0, "BAD_SCALAR_START", `Plain value cannot start with ${n}`), Js(e);
8856
+ return n && t(0, "BAD_SCALAR_START", `Plain value cannot start with ${n}`), Zs(e);
8780
8857
  }
8781
- function qs(e, t) {
8782
- return (e[e.length - 1] !== "'" || e.length === 1) && t(e.length, "MISSING_CHAR", "Missing closing 'quote"), Js(e.slice(1, -1)).replace(/''/g, "'");
8858
+ function Xs(e, t) {
8859
+ return (e[e.length - 1] !== "'" || e.length === 1) && t(e.length, "MISSING_CHAR", "Missing closing 'quote"), Zs(e.slice(1, -1)).replace(/''/g, "'");
8783
8860
  }
8784
- function Js(e) {
8861
+ function Zs(e) {
8785
8862
  let t, n;
8786
8863
  try {
8787
8864
  t = /* @__PURE__ */ RegExp("(.*?)(?<![ ])[ ]*\r?\n", "sy"), n = /* @__PURE__ */ RegExp("[ ]*(.*?)(?:(?<![ ])[ ]*)?\r?\n", "sy");
@@ -8795,22 +8872,22 @@ function Js(e) {
8795
8872
  let s = /[ \t]*(.*)/sy;
8796
8873
  return s.lastIndex = o, r = s.exec(e), i + a + (r?.[1] ?? "");
8797
8874
  }
8798
- function Ys(e, t) {
8875
+ function Qs(e, t) {
8799
8876
  let n = "";
8800
8877
  for (let r = 1; r < e.length - 1; ++r) {
8801
8878
  let i = e[r];
8802
8879
  if (i !== "\r" || e[r + 1] !== "\n") {
8803
8880
  if (i === "\n") {
8804
- let { fold: t, offset: i } = Xs(e, r);
8881
+ let { fold: t, offset: i } = $s(e, r);
8805
8882
  n += t, r = i;
8806
8883
  } else if (i === "\\") {
8807
- let i = e[++r], a = Zs[i];
8884
+ let i = e[++r], a = ec[i];
8808
8885
  if (a) n += a;
8809
8886
  else if (i === "\n") for (i = e[r + 1]; i === " " || i === " ";) i = e[++r + 1];
8810
8887
  else if (i === "\r" && e[r + 1] === "\n") for (i = e[++r + 1]; i === " " || i === " ";) i = e[++r + 1];
8811
8888
  else if (i === "x" || i === "u" || i === "U") {
8812
8889
  let a = i === "x" ? 2 : i === "u" ? 4 : 8;
8813
- n += Qs(e, r + 1, a, t), r += a;
8890
+ n += tc(e, r + 1, a, t), r += a;
8814
8891
  } else {
8815
8892
  let i = e.substr(r - 1, 2);
8816
8893
  t(r - 1, "BAD_DQ_ESCAPE", `Invalid escape sequence ${i}`), n += i;
@@ -8824,7 +8901,7 @@ function Ys(e, t) {
8824
8901
  }
8825
8902
  return (e[e.length - 1] !== "\"" || e.length === 1) && t(e.length, "MISSING_CHAR", "Missing closing \"quote"), n;
8826
8903
  }
8827
- function Xs(e, t) {
8904
+ function $s(e, t) {
8828
8905
  let n = "", r = e[t + 1];
8829
8906
  for (; (r === " " || r === " " || r === "\n" || r === "\r") && (r !== "\r" || e[t + 2] === "\n");) r === "\n" && (n += "\n"), t += 1, r = e[t + 1];
8830
8907
  return n ||= " ", {
@@ -8832,7 +8909,7 @@ function Xs(e, t) {
8832
8909
  offset: t
8833
8910
  };
8834
8911
  }
8835
- var Zs = {
8912
+ var ec = {
8836
8913
  0: "\0",
8837
8914
  a: "\x07",
8838
8915
  b: "\b",
@@ -8852,7 +8929,7 @@ var Zs = {
8852
8929
  "\\": "\\",
8853
8930
  " ": " "
8854
8931
  };
8855
- function Qs(e, t, n, r) {
8932
+ function tc(e, t, n, r) {
8856
8933
  let i = e.substr(t, n), a = i.length === n && /^[0-9a-fA-F]+$/.test(i) ? parseInt(i, 16) : NaN;
8857
8934
  try {
8858
8935
  return String.fromCodePoint(a);
@@ -8863,9 +8940,9 @@ function Qs(e, t, n, r) {
8863
8940
  }
8864
8941
  //#endregion
8865
8942
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/compose/compose-scalar.js
8866
- function $s(e, t, n, r) {
8867
- let { value: i, type: a, comment: o, range: s } = t.type === "block-scalar" ? Hs(e, t, r) : Gs(t, e.options.strict, r), c = n ? e.directives.tagName(n.source, (e) => r(n, "TAG_RESOLVE_FAILED", e)) : null, l;
8868
- l = e.options.stringKeys && e.atKey ? e.schema[ta] : c ? ec(e.schema, i, c, n, r) : t.type === "scalar" ? tc(e, i, t, r) : e.schema[ta];
8943
+ function nc(e, t, n, r) {
8944
+ let { value: i, type: a, comment: o, range: s } = t.type === "block-scalar" ? Gs(e, t, r) : Js(t, e.options.strict, r), c = n ? e.directives.tagName(n.source, (e) => r(n, "TAG_RESOLVE_FAILED", e)) : null, l;
8945
+ l = e.options.stringKeys && e.atKey ? e.schema[ia] : c ? rc(e.schema, i, c, n, r) : t.type === "scalar" ? ic(e, i, t, r) : e.schema[ia];
8869
8946
  let u;
8870
8947
  try {
8871
8948
  let a = l.resolve(i, (e) => r(n ?? t, "TAG_RESOLVE_FAILED", e), e.options);
@@ -8876,8 +8953,8 @@ function $s(e, t, n, r) {
8876
8953
  }
8877
8954
  return u.range = s, u.source = i, a && (u.type = a), c && (u.tag = c), l.format && (u.format = l.format), o && (u.comment = o), u;
8878
8955
  }
8879
- function ec(e, t, n, r, i) {
8880
- if (n === "!") return e[ta];
8956
+ function rc(e, t, n, r, i) {
8957
+ if (n === "!") return e[ia];
8881
8958
  let a = [];
8882
8959
  for (let t of e.tags) if (!t.collection && t.tag === n) {
8883
8960
  if (t.default && t.test) a.push(t);
@@ -8888,19 +8965,19 @@ function ec(e, t, n, r, i) {
8888
8965
  return o && !o.collection ? (e.tags.push(Object.assign({}, o, {
8889
8966
  default: !1,
8890
8967
  test: void 0
8891
- })), o) : (i(r, "TAG_RESOLVE_FAILED", `Unresolved tag: ${n}`, n !== "tag:yaml.org,2002:str"), e[ta]);
8968
+ })), o) : (i(r, "TAG_RESOLVE_FAILED", `Unresolved tag: ${n}`, n !== "tag:yaml.org,2002:str"), e[ia]);
8892
8969
  }
8893
- function tc({ atKey: e, directives: t, schema: n }, r, i, a) {
8894
- let o = n.tags.find((t) => (t.default === !0 || e && t.default === "key") && t.test?.test(r)) || n[ta];
8970
+ function ic({ atKey: e, directives: t, schema: n }, r, i, a) {
8971
+ let o = n.tags.find((t) => (t.default === !0 || e && t.default === "key") && t.test?.test(r)) || n[ia];
8895
8972
  if (n.compat) {
8896
- let e = n.compat.find((e) => e.default && e.test?.test(r)) ?? n[ta];
8973
+ let e = n.compat.find((e) => e.default && e.test?.test(r)) ?? n[ia];
8897
8974
  o.tag !== e.tag && a(i, "TAG_RESOLVE_FAILED", `Value may be parsed as either ${t.tagString(o.tag)} or ${t.tagString(e.tag)}`, !0);
8898
8975
  }
8899
8976
  return o;
8900
8977
  }
8901
8978
  //#endregion
8902
8979
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/compose/util-empty-scalar-position.js
8903
- function nc(e, t, n) {
8980
+ function ac(e, t, n) {
8904
8981
  if (t) {
8905
8982
  n ??= t.length;
8906
8983
  for (let r = n - 1; r >= 0; --r) {
@@ -8920,48 +8997,48 @@ function nc(e, t, n) {
8920
8997
  }
8921
8998
  //#endregion
8922
8999
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/compose/compose-node.js
8923
- var rc = {
8924
- composeNode: ic,
8925
- composeEmptyNode: ac
9000
+ var oc = {
9001
+ composeNode: sc,
9002
+ composeEmptyNode: cc
8926
9003
  };
8927
- function ic(e, t, n, r) {
9004
+ function sc(e, t, n, r) {
8928
9005
  let i = e.atKey, { spaceBefore: a, comment: o, anchor: s, tag: c } = n, l, u = !0;
8929
9006
  switch (t.type) {
8930
9007
  case "alias":
8931
- l = oc(e, t, r), (s || c) && r(t, "ALIAS_PROPS", "An alias node must not specify any properties");
9008
+ l = lc(e, t, r), (s || c) && r(t, "ALIAS_PROPS", "An alias node must not specify any properties");
8932
9009
  break;
8933
9010
  case "scalar":
8934
9011
  case "single-quoted-scalar":
8935
9012
  case "double-quoted-scalar":
8936
9013
  case "block-scalar":
8937
- l = $s(e, t, c, r), s && (l.anchor = s.source.substring(1));
9014
+ l = nc(e, t, c, r), s && (l.anchor = s.source.substring(1));
8938
9015
  break;
8939
9016
  case "block-map":
8940
9017
  case "block-seq":
8941
9018
  case "flow-collection":
8942
9019
  try {
8943
- l = Vs(rc, e, t, n, r), s && (l.anchor = s.source.substring(1));
9020
+ l = Ws(oc, e, t, n, r), s && (l.anchor = s.source.substring(1));
8944
9021
  } catch (e) {
8945
9022
  r(t, "RESOURCE_EXHAUSTION", e instanceof Error ? e.message : String(e));
8946
9023
  }
8947
9024
  break;
8948
9025
  default: r(t, "UNEXPECTED_TOKEN", t.type === "error" ? t.message : `Unsupported token (type: ${t.type})`), u = !1;
8949
9026
  }
8950
- return l ??= ac(e, t.offset, void 0, null, n, r), s && l.anchor === "" && r(s, "BAD_ALIAS", "Anchor cannot be an empty string"), i && e.options.stringKeys && (!q(l) || typeof l.value != "string" || l.tag && l.tag !== "tag:yaml.org,2002:str") && r(c ?? t, "NON_STRING_KEY", "With stringKeys, all keys must be strings"), a && (l.spaceBefore = !0), o && (t.type === "scalar" && t.source === "" ? l.comment = o : l.commentBefore = o), e.options.keepSourceTokens && u && (l.srcToken = t), l;
9027
+ return l ??= cc(e, t.offset, void 0, null, n, r), s && l.anchor === "" && r(s, "BAD_ALIAS", "Anchor cannot be an empty string"), i && e.options.stringKeys && (!q(l) || typeof l.value != "string" || l.tag && l.tag !== "tag:yaml.org,2002:str") && r(c ?? t, "NON_STRING_KEY", "With stringKeys, all keys must be strings"), a && (l.spaceBefore = !0), o && (t.type === "scalar" && t.source === "" ? l.comment = o : l.commentBefore = o), e.options.keepSourceTokens && u && (l.srcToken = t), l;
8951
9028
  }
8952
- function ac(e, t, n, r, { spaceBefore: i, comment: a, anchor: o, tag: s, end: c }, l) {
8953
- let u = $s(e, {
9029
+ function cc(e, t, n, r, { spaceBefore: i, comment: a, anchor: o, tag: s, end: c }, l) {
9030
+ let u = nc(e, {
8954
9031
  type: "scalar",
8955
- offset: nc(t, n, r),
9032
+ offset: ac(t, n, r),
8956
9033
  indent: -1,
8957
9034
  source: ""
8958
9035
  }, s, l);
8959
9036
  return o && (u.anchor = o.source.substring(1), u.anchor === "" && l(o, "BAD_ALIAS", "Anchor cannot be an empty string")), i && (u.spaceBefore = !0), a && (u.comment = a, u.range[2] = c), u;
8960
9037
  }
8961
- function oc({ options: e }, { offset: t, source: n, end: r }, i) {
8962
- let a = new Da(n.substring(1));
9038
+ function lc({ options: e }, { offset: t, source: n, end: r }, i) {
9039
+ let a = new Aa(n.substring(1));
8963
9040
  a.source === "" && i(t, "BAD_ALIAS", "Alias cannot be an empty string"), a.source.endsWith(":") && i(t + n.length - 1, "BAD_ALIAS", "Alias ending in : is ambiguous", !0);
8964
- let o = t + n.length, s = Is(r, o, e.strict, i);
9041
+ let o = t + n.length, s = zs(r, o, e.strict, i);
8965
9042
  return a.range = [
8966
9043
  t,
8967
9044
  o,
@@ -8970,14 +9047,14 @@ function oc({ options: e }, { offset: t, source: n, end: r }, i) {
8970
9047
  }
8971
9048
  //#endregion
8972
9049
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/compose/compose-doc.js
8973
- function sc(e, t, { offset: n, start: r, value: i, end: a }, o) {
8974
- let s = new Cs(void 0, Object.assign({ _directives: t }, e)), c = {
9050
+ function uc(e, t, { offset: n, start: r, value: i, end: a }, o) {
9051
+ let s = new Es(void 0, Object.assign({ _directives: t }, e)), c = {
8975
9052
  atKey: !1,
8976
9053
  atRoot: !0,
8977
9054
  directives: s.directives,
8978
9055
  options: s.options,
8979
9056
  schema: s.schema
8980
- }, l = ks(r, {
9057
+ }, l = Ms(r, {
8981
9058
  indicator: "doc-start",
8982
9059
  next: i ?? a?.[0],
8983
9060
  offset: n,
@@ -8985,8 +9062,8 @@ function sc(e, t, { offset: n, start: r, value: i, end: a }, o) {
8985
9062
  parentIndent: 0,
8986
9063
  startOnNewline: !0
8987
9064
  });
8988
- l.found && (s.directives.docStart = !0, i && (i.type === "block-map" || i.type === "block-seq") && !l.hasNewline && o(l.end, "MISSING_CHAR", "Block collection cannot start on same line with directives-end marker")), s.contents = i ? ic(c, i, l, o) : ac(c, l.end, r, null, l, o);
8989
- let u = s.contents.range[2], d = Is(a, u, !1, o);
9065
+ l.found && (s.directives.docStart = !0, i && (i.type === "block-map" || i.type === "block-seq") && !l.hasNewline && o(l.end, "MISSING_CHAR", "Block collection cannot start on same line with directives-end marker")), s.contents = i ? sc(c, i, l, o) : cc(c, l.end, r, null, l, o);
9066
+ let u = s.contents.range[2], d = zs(a, u, !1, o);
8990
9067
  return d.comment && (s.comment = d.comment), s.range = [
8991
9068
  n,
8992
9069
  u,
@@ -8995,13 +9072,13 @@ function sc(e, t, { offset: n, start: r, value: i, end: a }, o) {
8995
9072
  }
8996
9073
  //#endregion
8997
9074
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/compose/composer.js
8998
- function cc(e) {
9075
+ function dc(e) {
8999
9076
  if (typeof e == "number") return [e, e + 1];
9000
9077
  if (Array.isArray(e)) return e.length === 2 ? e : [e[0], e[1]];
9001
9078
  let { offset: t, source: n } = e;
9002
9079
  return [t, t + (typeof n == "string" ? n.length : 1)];
9003
9080
  }
9004
- function lc(e) {
9081
+ function fc(e) {
9005
9082
  let t = "", n = !1, r = !1;
9006
9083
  for (let i = 0; i < e.length; ++i) {
9007
9084
  let a = e[i];
@@ -9020,15 +9097,15 @@ function lc(e) {
9020
9097
  afterEmptyLine: r
9021
9098
  };
9022
9099
  }
9023
- var uc = class {
9100
+ var pc = class {
9024
9101
  constructor(e = {}) {
9025
9102
  this.doc = null, this.atDirectives = !1, this.prelude = [], this.errors = [], this.warnings = [], this.onError = (e, t, n, r) => {
9026
- let i = cc(e);
9027
- r ? this.warnings.push(new Ds(i, t, n)) : this.errors.push(new Es(i, t, n));
9028
- }, this.directives = new ya({ version: e.version || "1.2" }), this.options = e;
9103
+ let i = dc(e);
9104
+ r ? this.warnings.push(new As(i, t, n)) : this.errors.push(new ks(i, t, n));
9105
+ }, this.directives = new Sa({ version: e.version || "1.2" }), this.options = e;
9029
9106
  }
9030
9107
  decorate(e, t) {
9031
- let { comment: n, afterEmptyLine: r } = lc(this.prelude);
9108
+ let { comment: n, afterEmptyLine: r } = fc(this.prelude);
9032
9109
  if (n) {
9033
9110
  let i = e.contents;
9034
9111
  if (t) e.comment = e.comment ? `${e.comment}\n${n}` : n;
@@ -9051,7 +9128,7 @@ var uc = class {
9051
9128
  }
9052
9129
  streamInfo() {
9053
9130
  return {
9054
- comment: lc(this.prelude).comment,
9131
+ comment: fc(this.prelude).comment,
9055
9132
  directives: this.directives,
9056
9133
  errors: this.errors,
9057
9134
  warnings: this.warnings
@@ -9065,12 +9142,12 @@ var uc = class {
9065
9142
  switch (e.type) {
9066
9143
  case "directive":
9067
9144
  this.directives.add(e.source, (t, n, r) => {
9068
- let i = cc(e);
9145
+ let i = dc(e);
9069
9146
  i[0] += t, this.onError(i, "BAD_DIRECTIVE", n, r);
9070
9147
  }), this.prelude.push(e.source), this.atDirectives = !0;
9071
9148
  break;
9072
9149
  case "document": {
9073
- let t = sc(this.options, this.directives, e, this.onError);
9150
+ let t = uc(this.options, this.directives, e, this.onError);
9074
9151
  this.atDirectives && !t.directives.docStart && this.onError(e, "MISSING_CHAR", "Missing directives-end/doc-start indicator line"), this.decorate(t, !1), this.doc && (yield this.doc), this.doc = t, this.atDirectives = !1;
9075
9152
  break;
9076
9153
  }
@@ -9081,17 +9158,17 @@ var uc = class {
9081
9158
  this.prelude.push(e.source);
9082
9159
  break;
9083
9160
  case "error": {
9084
- let t = e.source ? `${e.message}: ${JSON.stringify(e.source)}` : e.message, n = new Es(cc(e), "UNEXPECTED_TOKEN", t);
9161
+ let t = e.source ? `${e.message}: ${JSON.stringify(e.source)}` : e.message, n = new ks(dc(e), "UNEXPECTED_TOKEN", t);
9085
9162
  this.atDirectives || !this.doc ? this.errors.push(n) : this.doc.errors.push(n);
9086
9163
  break;
9087
9164
  }
9088
9165
  case "doc-end": {
9089
9166
  if (!this.doc) {
9090
- this.errors.push(new Es(cc(e), "UNEXPECTED_TOKEN", "Unexpected doc-end without preceding document"));
9167
+ this.errors.push(new ks(dc(e), "UNEXPECTED_TOKEN", "Unexpected doc-end without preceding document"));
9091
9168
  break;
9092
9169
  }
9093
9170
  this.doc.directives.docEnd = !0;
9094
- let t = Is(e.end, e.offset + e.source.length, this.doc.options.strict, this.onError);
9171
+ let t = zs(e.end, e.offset + e.source.length, this.doc.options.strict, this.onError);
9095
9172
  if (this.decorate(this.doc, !0), t.comment) {
9096
9173
  let e = this.doc.comment;
9097
9174
  this.doc.comment = e ? `${e}\n${t.comment}` : t.comment;
@@ -9099,13 +9176,13 @@ var uc = class {
9099
9176
  this.doc.range[2] = t.offset;
9100
9177
  break;
9101
9178
  }
9102
- default: this.errors.push(new Es(cc(e), "UNEXPECTED_TOKEN", `Unsupported token ${e.type}`));
9179
+ default: this.errors.push(new ks(dc(e), "UNEXPECTED_TOKEN", `Unsupported token ${e.type}`));
9103
9180
  }
9104
9181
  }
9105
9182
  *end(e = !1, t = -1) {
9106
9183
  if (this.doc) this.decorate(this.doc, !0), yield this.doc, this.doc = null;
9107
9184
  else if (e) {
9108
- let e = new Cs(void 0, Object.assign({ _directives: this.directives }, this.options));
9185
+ let e = new Es(void 0, Object.assign({ _directives: this.directives }, this.options));
9109
9186
  this.atDirectives && this.onError(t, "MISSING_CHAR", "Missing directives-end indicator line"), e.range = [
9110
9187
  0,
9111
9188
  t,
@@ -9116,24 +9193,24 @@ var uc = class {
9116
9193
  };
9117
9194
  //#endregion
9118
9195
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/parse/cst-scalar.js
9119
- function dc(e, t = !0, n) {
9196
+ function mc(e, t = !0, n) {
9120
9197
  if (e) {
9121
9198
  let r = (e, t, r) => {
9122
9199
  let i = typeof e == "number" ? e : Array.isArray(e) ? e[0] : e.offset;
9123
9200
  if (n) n(i, t, r);
9124
- else throw new Es([i, i + 1], t, r);
9201
+ else throw new ks([i, i + 1], t, r);
9125
9202
  };
9126
9203
  switch (e.type) {
9127
9204
  case "scalar":
9128
9205
  case "single-quoted-scalar":
9129
- case "double-quoted-scalar": return Gs(e, t, r);
9130
- case "block-scalar": return Hs({ options: { strict: t } }, e, r);
9206
+ case "double-quoted-scalar": return Js(e, t, r);
9207
+ case "block-scalar": return Gs({ options: { strict: t } }, e, r);
9131
9208
  }
9132
9209
  }
9133
9210
  return null;
9134
9211
  }
9135
- function fc(e, t) {
9136
- let { implicitKey: n = !1, indent: r, inFlow: i = !1, offset: a = -1, type: o = "PLAIN" } = t, s = $a({
9212
+ function hc(e, t) {
9213
+ let { implicitKey: n = !1, indent: r, inFlow: i = !1, offset: a = -1, type: o = "PLAIN" } = t, s = no({
9137
9214
  type: o,
9138
9215
  value: e
9139
9216
  }, {
@@ -9159,7 +9236,7 @@ function fc(e, t) {
9159
9236
  indent: r,
9160
9237
  source: t
9161
9238
  }];
9162
- return hc(i, c) || i.push({
9239
+ return vc(i, c) || i.push({
9163
9240
  type: "newline",
9164
9241
  offset: -1,
9165
9242
  indent: r,
@@ -9195,7 +9272,7 @@ function fc(e, t) {
9195
9272
  };
9196
9273
  }
9197
9274
  }
9198
- function pc(e, t, n = {}) {
9275
+ function gc(e, t, n = {}) {
9199
9276
  let { afterKey: r = !1, implicitKey: i = !1, inFlow: a = !1, type: o } = n, s = "indent" in e ? e.indent : null;
9200
9277
  if (r && typeof s == "number" && (s += 2), !o) switch (e.type) {
9201
9278
  case "single-quoted-scalar":
@@ -9212,7 +9289,7 @@ function pc(e, t, n = {}) {
9212
9289
  }
9213
9290
  default: o = "PLAIN";
9214
9291
  }
9215
- let c = $a({
9292
+ let c = no({
9216
9293
  type: o,
9217
9294
  value: t
9218
9295
  }, {
@@ -9227,18 +9304,18 @@ function pc(e, t, n = {}) {
9227
9304
  switch (c[0]) {
9228
9305
  case "|":
9229
9306
  case ">":
9230
- mc(e, c);
9307
+ _c(e, c);
9231
9308
  break;
9232
9309
  case "\"":
9233
- gc(e, c, "double-quoted-scalar");
9310
+ yc(e, c, "double-quoted-scalar");
9234
9311
  break;
9235
9312
  case "'":
9236
- gc(e, c, "single-quoted-scalar");
9313
+ yc(e, c, "single-quoted-scalar");
9237
9314
  break;
9238
- default: gc(e, c, "scalar");
9315
+ default: yc(e, c, "scalar");
9239
9316
  }
9240
9317
  }
9241
- function mc(e, t) {
9318
+ function _c(e, t) {
9242
9319
  let n = t.indexOf("\n"), r = t.substring(0, n), i = t.substring(n + 1) + "\n";
9243
9320
  if (e.type === "block-scalar") {
9244
9321
  let t = e.props[0];
@@ -9251,7 +9328,7 @@ function mc(e, t) {
9251
9328
  indent: n,
9252
9329
  source: r
9253
9330
  }];
9254
- hc(a, "end" in e ? e.end : void 0) || a.push({
9331
+ vc(a, "end" in e ? e.end : void 0) || a.push({
9255
9332
  type: "newline",
9256
9333
  offset: -1,
9257
9334
  indent: n,
@@ -9266,7 +9343,7 @@ function mc(e, t) {
9266
9343
  });
9267
9344
  }
9268
9345
  }
9269
- function hc(e, t) {
9346
+ function vc(e, t) {
9270
9347
  if (t) for (let n of t) switch (n.type) {
9271
9348
  case "space":
9272
9349
  case "comment":
@@ -9276,7 +9353,7 @@ function hc(e, t) {
9276
9353
  }
9277
9354
  return !1;
9278
9355
  }
9279
- function gc(e, t, n) {
9356
+ function yc(e, t, n) {
9280
9357
  switch (e.type) {
9281
9358
  case "scalar":
9282
9359
  case "double-quoted-scalar":
@@ -9323,28 +9400,28 @@ function gc(e, t, n) {
9323
9400
  }
9324
9401
  //#endregion
9325
9402
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/parse/cst-stringify.js
9326
- var _c = (e) => "type" in e ? vc(e) : yc(e);
9327
- function vc(e) {
9403
+ var bc = (e) => "type" in e ? xc(e) : Sc(e);
9404
+ function xc(e) {
9328
9405
  switch (e.type) {
9329
9406
  case "block-scalar": {
9330
9407
  let t = "";
9331
- for (let n of e.props) t += vc(n);
9408
+ for (let n of e.props) t += xc(n);
9332
9409
  return t + e.source;
9333
9410
  }
9334
9411
  case "block-map":
9335
9412
  case "block-seq": {
9336
9413
  let t = "";
9337
- for (let n of e.items) t += yc(n);
9414
+ for (let n of e.items) t += Sc(n);
9338
9415
  return t;
9339
9416
  }
9340
9417
  case "flow-collection": {
9341
9418
  let t = e.start.source;
9342
- for (let n of e.items) t += yc(n);
9419
+ for (let n of e.items) t += Sc(n);
9343
9420
  for (let n of e.end) t += n.source;
9344
9421
  return t;
9345
9422
  }
9346
9423
  case "document": {
9347
- let t = yc(e);
9424
+ let t = Sc(e);
9348
9425
  if (e.end) for (let n of e.end) t += n.source;
9349
9426
  return t;
9350
9427
  }
@@ -9355,22 +9432,22 @@ function vc(e) {
9355
9432
  }
9356
9433
  }
9357
9434
  }
9358
- function yc({ start: e, key: t, sep: n, value: r }) {
9435
+ function Sc({ start: e, key: t, sep: n, value: r }) {
9359
9436
  let i = "";
9360
9437
  for (let t of e) i += t.source;
9361
- if (t && (i += vc(t)), n) for (let e of n) i += e.source;
9362
- return r && (i += vc(r)), i;
9438
+ if (t && (i += xc(t)), n) for (let e of n) i += e.source;
9439
+ return r && (i += xc(r)), i;
9363
9440
  }
9364
9441
  //#endregion
9365
9442
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/parse/cst-visit.js
9366
- var bc = Symbol("break visit"), xc = Symbol("skip children"), Sc = Symbol("remove item");
9367
- function Cc(e, t) {
9443
+ var Cc = Symbol("break visit"), wc = Symbol("skip children"), Tc = Symbol("remove item");
9444
+ function Ec(e, t) {
9368
9445
  "type" in e && e.type === "document" && (e = {
9369
9446
  start: e.start,
9370
9447
  value: e.value
9371
- }), wc(Object.freeze([]), e, t);
9448
+ }), Dc(Object.freeze([]), e, t);
9372
9449
  }
9373
- Cc.BREAK = bc, Cc.SKIP = xc, Cc.REMOVE = Sc, Cc.itemAtPath = (e, t) => {
9450
+ Ec.BREAK = Cc, Ec.SKIP = wc, Ec.REMOVE = Tc, Ec.itemAtPath = (e, t) => {
9374
9451
  let n = e;
9375
9452
  for (let [e, r] of t) {
9376
9453
  let t = n?.[e];
@@ -9378,22 +9455,22 @@ Cc.BREAK = bc, Cc.SKIP = xc, Cc.REMOVE = Sc, Cc.itemAtPath = (e, t) => {
9378
9455
  else return;
9379
9456
  }
9380
9457
  return n;
9381
- }, Cc.parentCollection = (e, t) => {
9382
- let n = Cc.itemAtPath(e, t.slice(0, -1)), r = t[t.length - 1][0], i = n?.[r];
9458
+ }, Ec.parentCollection = (e, t) => {
9459
+ let n = Ec.itemAtPath(e, t.slice(0, -1)), r = t[t.length - 1][0], i = n?.[r];
9383
9460
  if (i && "items" in i) return i;
9384
9461
  throw Error("Parent collection not found");
9385
9462
  };
9386
- function wc(e, t, n) {
9463
+ function Dc(e, t, n) {
9387
9464
  let r = n(t, e);
9388
9465
  if (typeof r == "symbol") return r;
9389
9466
  for (let i of ["key", "value"]) {
9390
9467
  let a = t[i];
9391
9468
  if (a && "items" in a) {
9392
9469
  for (let t = 0; t < a.items.length; ++t) {
9393
- let r = wc(Object.freeze(e.concat([[i, t]])), a.items[t], n);
9470
+ let r = Dc(Object.freeze(e.concat([[i, t]])), a.items[t], n);
9394
9471
  if (typeof r == "number") t = r - 1;
9395
- else if (r === bc) return bc;
9396
- else r === Sc && (a.items.splice(t, 1), --t);
9472
+ else if (r === Cc) return Cc;
9473
+ else r === Tc && (a.items.splice(t, 1), --t);
9397
9474
  }
9398
9475
  typeof r == "function" && i === "key" && (r = r(t, e));
9399
9476
  }
@@ -9402,23 +9479,23 @@ function wc(e, t, n) {
9402
9479
  }
9403
9480
  //#endregion
9404
9481
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/parse/cst.js
9405
- var Tc = /* @__PURE__ */ v({
9482
+ var Oc = /* @__PURE__ */ v({
9406
9483
  BOM: () => "",
9407
9484
  DOCUMENT: () => "",
9408
9485
  FLOW_END: () => "",
9409
9486
  SCALAR: () => "",
9410
- createScalarToken: () => fc,
9411
- isCollection: () => Ec,
9412
- isScalar: () => Dc,
9413
- prettyToken: () => Oc,
9414
- resolveAsScalar: () => dc,
9415
- setScalarValue: () => pc,
9416
- stringify: () => _c,
9417
- tokenType: () => kc,
9418
- visit: () => Cc
9419
- }), Ec = (e) => !!e && "items" in e, Dc = (e) => !!e && (e.type === "scalar" || e.type === "single-quoted-scalar" || e.type === "double-quoted-scalar" || e.type === "block-scalar");
9487
+ createScalarToken: () => hc,
9488
+ isCollection: () => kc,
9489
+ isScalar: () => Ac,
9490
+ prettyToken: () => jc,
9491
+ resolveAsScalar: () => mc,
9492
+ setScalarValue: () => gc,
9493
+ stringify: () => bc,
9494
+ tokenType: () => Mc,
9495
+ visit: () => Ec
9496
+ }), kc = (e) => !!e && "items" in e, Ac = (e) => !!e && (e.type === "scalar" || e.type === "single-quoted-scalar" || e.type === "double-quoted-scalar" || e.type === "block-scalar");
9420
9497
  /* istanbul ignore next */
9421
- function Oc(e) {
9498
+ function jc(e) {
9422
9499
  switch (e) {
9423
9500
  case "": return "<BOM>";
9424
9501
  case "": return "<DOC>";
@@ -9427,7 +9504,7 @@ function Oc(e) {
9427
9504
  default: return JSON.stringify(e);
9428
9505
  }
9429
9506
  }
9430
- function kc(e) {
9507
+ function Mc(e) {
9431
9508
  switch (e) {
9432
9509
  case "": return "byte-order-mark";
9433
9510
  case "": return "doc-mode";
@@ -9464,7 +9541,7 @@ function kc(e) {
9464
9541
  }
9465
9542
  //#endregion
9466
9543
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/parse/lexer.js
9467
- function Ac(e) {
9544
+ function Nc(e) {
9468
9545
  switch (e) {
9469
9546
  case void 0:
9470
9547
  case " ":
@@ -9474,7 +9551,7 @@ function Ac(e) {
9474
9551
  default: return !1;
9475
9552
  }
9476
9553
  }
9477
- var jc = /* @__PURE__ */ new Set("0123456789ABCDEFabcdef"), Mc = /* @__PURE__ */ new Set("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()"), Nc = /* @__PURE__ */ new Set(",[]{}"), Pc = /* @__PURE__ */ new Set(" ,[]{}\n\r "), Fc = (e) => !e || Pc.has(e), Ic = class {
9554
+ var Pc = /* @__PURE__ */ new Set("0123456789ABCDEFabcdef"), Fc = /* @__PURE__ */ new Set("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()"), Ic = /* @__PURE__ */ new Set(",[]{}"), Lc = /* @__PURE__ */ new Set(" ,[]{}\n\r "), Rc = (e) => !e || Lc.has(e), zc = class {
9478
9555
  constructor() {
9479
9556
  this.atEnd = !1, this.blockScalarIndent = -1, this.blockScalarKeep = !1, this.buffer = "", this.flowKey = !1, this.flowLevel = 0, this.indentNext = 0, this.indentValue = 0, this.lineEndPos = null, this.next = null, this.pos = 0;
9480
9557
  }
@@ -9508,7 +9585,7 @@ var jc = /* @__PURE__ */ new Set("0123456789ABCDEFabcdef"), Mc = /* @__PURE__ */
9508
9585
  }
9509
9586
  if (t === "-" || t === ".") {
9510
9587
  let t = this.buffer.substr(e, 3);
9511
- if ((t === "---" || t === "...") && Ac(this.buffer[e + 3])) return -1;
9588
+ if ((t === "---" || t === "...") && Nc(this.buffer[e + 3])) return -1;
9512
9589
  }
9513
9590
  return e;
9514
9591
  }
@@ -9570,14 +9647,14 @@ var jc = /* @__PURE__ */ new Set("0123456789ABCDEFabcdef"), Mc = /* @__PURE__ */
9570
9647
  if (e === "-" || e === ".") {
9571
9648
  if (!this.atEnd && !this.hasChars(4)) return this.setNext("line-start");
9572
9649
  let e = this.peek(3);
9573
- if ((e === "---" || e === "...") && Ac(this.charAt(3))) return yield* this.pushCount(3), this.indentValue = 0, this.indentNext = 0, e === "---" ? "doc" : "stream";
9650
+ if ((e === "---" || e === "...") && Nc(this.charAt(3))) return yield* this.pushCount(3), this.indentValue = 0, this.indentNext = 0, e === "---" ? "doc" : "stream";
9574
9651
  }
9575
- return this.indentValue = yield* this.pushSpaces(!1), this.indentNext > this.indentValue && !Ac(this.charAt(1)) && (this.indentNext = this.indentValue), yield* this.parseBlockStart();
9652
+ return this.indentValue = yield* this.pushSpaces(!1), this.indentNext > this.indentValue && !Nc(this.charAt(1)) && (this.indentNext = this.indentValue), yield* this.parseBlockStart();
9576
9653
  }
9577
9654
  *parseBlockStart() {
9578
9655
  let [e, t] = this.peek(2);
9579
9656
  if (!t && !this.atEnd) return this.setNext("block-start");
9580
- if ((e === "-" || e === "?" || e === ":") && Ac(t)) {
9657
+ if ((e === "-" || e === "?" || e === ":") && Nc(t)) {
9581
9658
  let e = (yield* this.pushCount(1)) + (yield* this.pushSpaces(!0));
9582
9659
  return this.indentNext = this.indentValue + 1, this.indentValue += e, "block-start";
9583
9660
  }
@@ -9595,7 +9672,7 @@ var jc = /* @__PURE__ */ new Set("0123456789ABCDEFabcdef"), Mc = /* @__PURE__ */
9595
9672
  case "[": return yield* this.pushCount(1), this.flowKey = !1, this.flowLevel = 1, "flow";
9596
9673
  case "}":
9597
9674
  case "]": return yield* this.pushCount(1), "doc";
9598
- case "*": return yield* this.pushUntil(Fc), "doc";
9675
+ case "*": return yield* this.pushUntil(Rc), "doc";
9599
9676
  case "\"":
9600
9677
  case "'": return yield* this.parseQuotedScalar();
9601
9678
  case "|":
@@ -9610,7 +9687,7 @@ var jc = /* @__PURE__ */ new Set("0123456789ABCDEFabcdef"), Mc = /* @__PURE__ */
9610
9687
  while (e + t > 0);
9611
9688
  let r = this.getLine();
9612
9689
  if (r === null) return this.setNext("flow");
9613
- if ((n !== -1 && n < this.indentNext && r[0] !== "#" || n === 0 && (r.startsWith("---") || r.startsWith("...")) && Ac(r[3])) && (n !== this.indentNext - 1 || this.flowLevel !== 1 || r[0] !== "]" && r[0] !== "}")) return this.flowLevel = 0, yield "", yield* this.parseLineStart();
9690
+ if ((n !== -1 && n < this.indentNext && r[0] !== "#" || n === 0 && (r.startsWith("---") || r.startsWith("...")) && Nc(r[3])) && (n !== this.indentNext - 1 || this.flowLevel !== 1 || r[0] !== "]" && r[0] !== "}")) return this.flowLevel = 0, yield "", yield* this.parseLineStart();
9614
9691
  let i = 0;
9615
9692
  for (; r[i] === ",";) i += yield* this.pushCount(1), i += yield* this.pushSpaces(!0), this.flowKey = !1;
9616
9693
  switch (i += yield* this.pushIndicators(), r[i]) {
@@ -9620,12 +9697,12 @@ var jc = /* @__PURE__ */ new Set("0123456789ABCDEFabcdef"), Mc = /* @__PURE__ */
9620
9697
  case "[": return yield* this.pushCount(1), this.flowKey = !1, this.flowLevel += 1, "flow";
9621
9698
  case "}":
9622
9699
  case "]": return yield* this.pushCount(1), this.flowKey = !0, --this.flowLevel, this.flowLevel ? "flow" : "doc";
9623
- case "*": return yield* this.pushUntil(Fc), "flow";
9700
+ case "*": return yield* this.pushUntil(Rc), "flow";
9624
9701
  case "\"":
9625
9702
  case "'": return this.flowKey = !0, yield* this.parseQuotedScalar();
9626
9703
  case ":": {
9627
9704
  let e = this.charAt(1);
9628
- if (this.flowKey || Ac(e) || e === ",") return this.flowKey = !1, yield* this.pushCount(1), yield* this.pushSpaces(!0), "flow";
9705
+ if (this.flowKey || Nc(e) || e === ",") return this.flowKey = !1, yield* this.pushCount(1), yield* this.pushSpaces(!0), "flow";
9629
9706
  }
9630
9707
  default: return this.flowKey = !1, yield* this.parsePlainScalar();
9631
9708
  }
@@ -9663,7 +9740,7 @@ var jc = /* @__PURE__ */ new Set("0123456789ABCDEFabcdef"), Mc = /* @__PURE__ */
9663
9740
  else if (t > "0" && t <= "9") this.blockScalarIndent = Number(t) - 1;
9664
9741
  else if (t !== "-") break;
9665
9742
  }
9666
- return yield* this.pushUntil((e) => Ac(e) || e === "#");
9743
+ return yield* this.pushUntil((e) => Nc(e) || e === "#");
9667
9744
  }
9668
9745
  *parseBlockScalar() {
9669
9746
  let e = this.pos - 1, t = 0, n;
@@ -9713,18 +9790,18 @@ var jc = /* @__PURE__ */ new Set("0123456789ABCDEFabcdef"), Mc = /* @__PURE__ */
9713
9790
  let e = this.flowLevel > 0, t = this.pos - 1, n = this.pos - 1, r;
9714
9791
  for (; r = this.buffer[++n];) if (r === ":") {
9715
9792
  let r = this.buffer[n + 1];
9716
- if (Ac(r) || e && Nc.has(r)) break;
9793
+ if (Nc(r) || e && Ic.has(r)) break;
9717
9794
  t = n;
9718
- } else if (Ac(r)) {
9795
+ } else if (Nc(r)) {
9719
9796
  let i = this.buffer[n + 1];
9720
- if (r === "\r" && (i === "\n" ? (n += 1, r = "\n", i = this.buffer[n + 1]) : t = n), i === "#" || e && Nc.has(i)) break;
9797
+ if (r === "\r" && (i === "\n" ? (n += 1, r = "\n", i = this.buffer[n + 1]) : t = n), i === "#" || e && Ic.has(i)) break;
9721
9798
  if (r === "\n") {
9722
9799
  let e = this.continueScalar(n + 1);
9723
9800
  if (e === -1) break;
9724
9801
  n = Math.max(n, e - 2);
9725
9802
  }
9726
9803
  } else {
9727
- if (e && Nc.has(r)) break;
9804
+ if (e && Ic.has(r)) break;
9728
9805
  t = n;
9729
9806
  }
9730
9807
  return !r && !this.atEnd ? this.setNext("plain-scalar") : (yield "", yield* this.pushToIndex(t + 1, !0), e ? "flow" : "doc");
@@ -9744,13 +9821,13 @@ var jc = /* @__PURE__ */ new Set("0123456789ABCDEFabcdef"), Mc = /* @__PURE__ */
9744
9821
  e += yield* this.pushTag(), e += yield* this.pushSpaces(!0);
9745
9822
  continue loop;
9746
9823
  case "&":
9747
- e += yield* this.pushUntil(Fc), e += yield* this.pushSpaces(!0);
9824
+ e += yield* this.pushUntil(Rc), e += yield* this.pushSpaces(!0);
9748
9825
  continue loop;
9749
9826
  case "-":
9750
9827
  case "?":
9751
9828
  case ":": {
9752
9829
  let t = this.flowLevel > 0, n = this.charAt(1);
9753
- if (Ac(n) || t && Nc.has(n)) {
9830
+ if (Nc(n) || t && Ic.has(n)) {
9754
9831
  t ? this.flowKey &&= !1 : this.indentNext = this.indentValue + 1, e += yield* this.pushCount(1), e += yield* this.pushSpaces(!0);
9755
9832
  continue loop;
9756
9833
  }
@@ -9763,13 +9840,13 @@ var jc = /* @__PURE__ */ new Set("0123456789ABCDEFabcdef"), Mc = /* @__PURE__ */
9763
9840
  *pushTag() {
9764
9841
  if (this.charAt(1) === "<") {
9765
9842
  let e = this.pos + 2, t = this.buffer[e];
9766
- for (; !Ac(t) && t !== ">";) t = this.buffer[++e];
9843
+ for (; !Nc(t) && t !== ">";) t = this.buffer[++e];
9767
9844
  return yield* this.pushToIndex(t === ">" ? e + 1 : e, !1);
9768
9845
  }
9769
9846
  {
9770
9847
  let e = this.pos + 1, t = this.buffer[e];
9771
- for (; t;) if (Mc.has(t)) t = this.buffer[++e];
9772
- else if (t === "%" && jc.has(this.buffer[e + 1]) && jc.has(this.buffer[e + 2])) t = this.buffer[e += 3];
9848
+ for (; t;) if (Fc.has(t)) t = this.buffer[++e];
9849
+ else if (t === "%" && Pc.has(this.buffer[e + 1]) && Pc.has(this.buffer[e + 2])) t = this.buffer[e += 3];
9773
9850
  else break;
9774
9851
  return yield* this.pushToIndex(e, !1);
9775
9852
  }
@@ -9791,7 +9868,7 @@ var jc = /* @__PURE__ */ new Set("0123456789ABCDEFabcdef"), Mc = /* @__PURE__ */
9791
9868
  for (; !e(n);) n = this.buffer[++t];
9792
9869
  return yield* this.pushToIndex(t, !1);
9793
9870
  }
9794
- }, Lc = class {
9871
+ }, Bc = class {
9795
9872
  constructor() {
9796
9873
  this.lineStarts = [], this.addNewLine = (e) => this.lineStarts.push(e), this.linePos = (e) => {
9797
9874
  let t = 0, n = this.lineStarts.length;
@@ -9817,11 +9894,11 @@ var jc = /* @__PURE__ */ new Set("0123456789ABCDEFabcdef"), Mc = /* @__PURE__ */
9817
9894
  };
9818
9895
  //#endregion
9819
9896
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/parse/parser.js
9820
- function Rc(e, t) {
9897
+ function Vc(e, t) {
9821
9898
  for (let n = 0; n < e.length; ++n) if (e[n].type === t) return !0;
9822
9899
  return !1;
9823
9900
  }
9824
- function zc(e) {
9901
+ function Hc(e) {
9825
9902
  for (let t = 0; t < e.length; ++t) switch (e[t].type) {
9826
9903
  case "space":
9827
9904
  case "comment":
@@ -9830,7 +9907,7 @@ function zc(e) {
9830
9907
  }
9831
9908
  return -1;
9832
9909
  }
9833
- function Bc(e) {
9910
+ function Uc(e) {
9834
9911
  switch (e?.type) {
9835
9912
  case "alias":
9836
9913
  case "scalar":
@@ -9840,7 +9917,7 @@ function Bc(e) {
9840
9917
  default: return !1;
9841
9918
  }
9842
9919
  }
9843
- function Vc(e) {
9920
+ function Wc(e) {
9844
9921
  switch (e.type) {
9845
9922
  case "document": return e.start;
9846
9923
  case "block-map": {
@@ -9852,7 +9929,7 @@ function Vc(e) {
9852
9929
  default: return [];
9853
9930
  }
9854
9931
  }
9855
- function Hc(e) {
9932
+ function Gc(e) {
9856
9933
  if (e.length === 0) return [];
9857
9934
  let t = e.length;
9858
9935
  loop: for (; --t >= 0;) switch (e[t].type) {
@@ -9865,16 +9942,16 @@ function Hc(e) {
9865
9942
  for (; e[++t]?.type === "space";);
9866
9943
  return e.splice(t, e.length);
9867
9944
  }
9868
- function Uc(e, t) {
9945
+ function Kc(e, t) {
9869
9946
  if (t.length < 1e5) Array.prototype.push.apply(e, t);
9870
9947
  else for (let n = 0; n < t.length; ++n) e.push(t[n]);
9871
9948
  }
9872
- function Wc(e) {
9873
- if (e.start.type === "flow-seq-start") for (let t of e.items) t.sep && !t.value && !Rc(t.start, "explicit-key-ind") && !Rc(t.sep, "map-value-ind") && (t.key && (t.value = t.key), delete t.key, Bc(t.value) ? t.value.end ? Uc(t.value.end, t.sep) : t.value.end = t.sep : Uc(t.start, t.sep), delete t.sep);
9949
+ function qc(e) {
9950
+ if (e.start.type === "flow-seq-start") for (let t of e.items) t.sep && !t.value && !Vc(t.start, "explicit-key-ind") && !Vc(t.sep, "map-value-ind") && (t.key && (t.value = t.key), delete t.key, Uc(t.value) ? t.value.end ? Kc(t.value.end, t.sep) : t.value.end = t.sep : Kc(t.start, t.sep), delete t.sep);
9874
9951
  }
9875
- var Gc = class {
9952
+ var Jc = class {
9876
9953
  constructor(e) {
9877
- this.atNewLine = !0, this.atScalar = !1, this.indent = 0, this.offset = 0, this.onKeyLine = !1, this.stack = [], this.source = "", this.type = "", this.lexer = new Ic(), this.onNewLine = e;
9954
+ this.atNewLine = !0, this.atScalar = !1, this.indent = 0, this.offset = 0, this.onKeyLine = !1, this.stack = [], this.source = "", this.type = "", this.lexer = new zc(), this.onNewLine = e;
9878
9955
  }
9879
9956
  *parse(e, t = !1) {
9880
9957
  this.onNewLine && this.offset === 0 && this.onNewLine(0);
@@ -9886,7 +9963,7 @@ var Gc = class {
9886
9963
  this.atScalar = !1, yield* this.step(), this.offset += e.length;
9887
9964
  return;
9888
9965
  }
9889
- let t = kc(e);
9966
+ let t = Mc(e);
9890
9967
  if (!t) {
9891
9968
  let t = `Not a YAML token: ${e}`;
9892
9969
  yield* this.pop({
@@ -9969,7 +10046,7 @@ var Gc = class {
9969
10046
  else if (this.stack.length === 0) yield t;
9970
10047
  else {
9971
10048
  let e = this.peek(1);
9972
- switch (t.type === "block-scalar" ? t.indent = "indent" in e ? e.indent : 0 : t.type === "flow-collection" && e.type === "document" && (t.indent = 0), t.type === "flow-collection" && Wc(t), e.type) {
10049
+ switch (t.type === "block-scalar" ? t.indent = "indent" in e ? e.indent : 0 : t.type === "flow-collection" && e.type === "document" && (t.indent = 0), t.type === "flow-collection" && qc(t), e.type) {
9973
10050
  case "document":
9974
10051
  e.value = t;
9975
10052
  break;
@@ -10021,7 +10098,7 @@ var Gc = class {
10021
10098
  }
10022
10099
  if ((e.type === "document" || e.type === "block-map" || e.type === "block-seq") && (t.type === "block-map" || t.type === "block-seq")) {
10023
10100
  let n = t.items[t.items.length - 1];
10024
- n && !n.sep && !n.value && n.start.length > 0 && zc(n.start) === -1 && (t.indent === 0 || n.start.every((e) => e.type !== "comment" || e.indent < t.indent)) && (e.type === "document" ? e.end = n.start : e.items.push({ start: n.start }), t.items.splice(-1, 1));
10101
+ n && !n.sep && !n.value && n.start.length > 0 && Hc(n.start) === -1 && (t.indent === 0 || n.start.every((e) => e.type !== "comment" || e.indent < t.indent)) && (e.type === "document" ? e.end = n.start : e.items.push({ start: n.start }), t.items.splice(-1, 1));
10025
10102
  }
10026
10103
  }
10027
10104
  }
@@ -10062,7 +10139,7 @@ var Gc = class {
10062
10139
  if (e.value) return yield* this.lineEnd(e);
10063
10140
  switch (this.type) {
10064
10141
  case "doc-start":
10065
- zc(e.start) === -1 ? e.start.push(this.sourceToken) : (yield* this.pop(), yield* this.step());
10142
+ Hc(e.start) === -1 ? e.start.push(this.sourceToken) : (yield* this.pop(), yield* this.step());
10066
10143
  return;
10067
10144
  case "anchor":
10068
10145
  case "tag":
@@ -10082,7 +10159,7 @@ var Gc = class {
10082
10159
  }
10083
10160
  *scalar(e) {
10084
10161
  if (this.type === "map-value-ind") {
10085
- let t = Hc(Vc(this.peek(2))), n;
10162
+ let t = Gc(Wc(this.peek(2))), n;
10086
10163
  e.end ? (n = e.end, n.push(this.sourceToken), delete e.end) : n = [this.sourceToken];
10087
10164
  let r = {
10088
10165
  type: "block-map",
@@ -10132,7 +10209,7 @@ var Gc = class {
10132
10209
  if (this.atIndentedComment(t.start, e.indent)) {
10133
10210
  let n = e.items[e.items.length - 2]?.value?.end;
10134
10211
  if (Array.isArray(n)) {
10135
- Uc(n, t.start), n.push(this.sourceToken), e.items.pop();
10212
+ Kc(n, t.start), n.push(this.sourceToken), e.items.pop();
10136
10213
  return;
10137
10214
  }
10138
10215
  }
@@ -10181,12 +10258,12 @@ var Gc = class {
10181
10258
  case "map-value-ind":
10182
10259
  if (t.explicitKey) {
10183
10260
  if (!t.sep) {
10184
- if (Rc(t.start, "newline")) Object.assign(t, {
10261
+ if (Vc(t.start, "newline")) Object.assign(t, {
10185
10262
  key: null,
10186
10263
  sep: [this.sourceToken]
10187
10264
  });
10188
10265
  else {
10189
- let e = Hc(t.start);
10266
+ let e = Gc(t.start);
10190
10267
  this.stack.push({
10191
10268
  type: "block-map",
10192
10269
  offset: this.offset,
@@ -10203,7 +10280,7 @@ var Gc = class {
10203
10280
  key: null,
10204
10281
  sep: [this.sourceToken]
10205
10282
  });
10206
- else if (Rc(t.sep, "map-value-ind")) this.stack.push({
10283
+ else if (Vc(t.sep, "map-value-ind")) this.stack.push({
10207
10284
  type: "block-map",
10208
10285
  offset: this.offset,
10209
10286
  indent: this.indent,
@@ -10213,8 +10290,8 @@ var Gc = class {
10213
10290
  sep: [this.sourceToken]
10214
10291
  }]
10215
10292
  });
10216
- else if (Bc(t.key) && !Rc(t.sep, "newline")) {
10217
- let e = Hc(t.start), n = t.key, r = t.sep;
10293
+ else if (Uc(t.key) && !Vc(t.sep, "newline")) {
10294
+ let e = Gc(t.start), n = t.key, r = t.sep;
10218
10295
  r.push(this.sourceToken), delete t.key, delete t.sep, this.stack.push({
10219
10296
  type: "block-map",
10220
10297
  offset: this.offset,
@@ -10230,7 +10307,7 @@ var Gc = class {
10230
10307
  start: i,
10231
10308
  key: null,
10232
10309
  sep: [this.sourceToken]
10233
- }) : Rc(t.sep, "map-value-ind") ? this.stack.push({
10310
+ }) : Vc(t.sep, "map-value-ind") ? this.stack.push({
10234
10311
  type: "block-map",
10235
10312
  offset: this.offset,
10236
10313
  indent: this.indent,
@@ -10264,7 +10341,7 @@ var Gc = class {
10264
10341
  let r = this.startBlockValue(e);
10265
10342
  if (r) {
10266
10343
  if (r.type === "block-seq") {
10267
- if (!t.explicitKey && t.sep && !Rc(t.sep, "newline")) {
10344
+ if (!t.explicitKey && t.sep && !Vc(t.sep, "newline")) {
10268
10345
  yield* this.pop({
10269
10346
  type: "error",
10270
10347
  offset: this.offset,
@@ -10298,7 +10375,7 @@ var Gc = class {
10298
10375
  if (this.atIndentedComment(t.start, e.indent)) {
10299
10376
  let n = e.items[e.items.length - 2]?.value?.end;
10300
10377
  if (Array.isArray(n)) {
10301
- Uc(n, t.start), n.push(this.sourceToken), e.items.pop();
10378
+ Kc(n, t.start), n.push(this.sourceToken), e.items.pop();
10302
10379
  return;
10303
10380
  }
10304
10381
  }
@@ -10312,7 +10389,7 @@ var Gc = class {
10312
10389
  return;
10313
10390
  case "seq-item-ind":
10314
10391
  if (this.indent !== e.indent) break;
10315
- t.value || Rc(t.start, "seq-item-ind") ? e.items.push({ start: [this.sourceToken] }) : t.start.push(this.sourceToken);
10392
+ t.value || Vc(t.start, "seq-item-ind") ? e.items.push({ start: [this.sourceToken] }) : t.start.push(this.sourceToken);
10316
10393
  return;
10317
10394
  }
10318
10395
  if (this.indent > e.indent) {
@@ -10381,8 +10458,8 @@ var Gc = class {
10381
10458
  let t = this.peek(2);
10382
10459
  if (t.type === "block-map" && (this.type === "map-value-ind" && t.indent === e.indent || this.type === "newline" && !t.items[t.items.length - 1].sep)) yield* this.pop(), yield* this.step();
10383
10460
  else if (this.type === "map-value-ind" && t.type !== "flow-collection") {
10384
- let n = Hc(Vc(t));
10385
- Wc(e);
10461
+ let n = Gc(Wc(t));
10462
+ qc(e);
10386
10463
  let r = e.end.splice(1, e.end.length);
10387
10464
  r.push(this.sourceToken);
10388
10465
  let i = {
@@ -10441,7 +10518,7 @@ var Gc = class {
10441
10518
  };
10442
10519
  case "explicit-key-ind": {
10443
10520
  this.onKeyLine = !0;
10444
- let t = Hc(Vc(e));
10521
+ let t = Gc(Wc(e));
10445
10522
  return t.push(this.sourceToken), {
10446
10523
  type: "block-map",
10447
10524
  offset: this.offset,
@@ -10454,7 +10531,7 @@ var Gc = class {
10454
10531
  }
10455
10532
  case "map-value-ind": {
10456
10533
  this.onKeyLine = !0;
10457
- let t = Hc(Vc(e));
10534
+ let t = Gc(Wc(e));
10458
10535
  return {
10459
10536
  type: "block-map",
10460
10537
  offset: this.offset,
@@ -10492,39 +10569,39 @@ var Gc = class {
10492
10569
  };
10493
10570
  //#endregion
10494
10571
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/public-api.js
10495
- function Kc(e) {
10572
+ function Yc(e) {
10496
10573
  let t = e.prettyErrors !== !1;
10497
10574
  return {
10498
- lineCounter: e.lineCounter || t && new Lc() || null,
10575
+ lineCounter: e.lineCounter || t && new Bc() || null,
10499
10576
  prettyErrors: t
10500
10577
  };
10501
10578
  }
10502
- function qc(e, t = {}) {
10503
- let { lineCounter: n, prettyErrors: r } = Kc(t), i = new Gc(n?.addNewLine), a = new uc(t), o = Array.from(a.compose(i.parse(e)));
10504
- if (r && n) for (let t of o) t.errors.forEach(Os(e, n)), t.warnings.forEach(Os(e, n));
10579
+ function Xc(e, t = {}) {
10580
+ let { lineCounter: n, prettyErrors: r } = Yc(t), i = new Jc(n?.addNewLine), a = new pc(t), o = Array.from(a.compose(i.parse(e)));
10581
+ if (r && n) for (let t of o) t.errors.forEach(js(e, n)), t.warnings.forEach(js(e, n));
10505
10582
  return o.length > 0 ? o : Object.assign([], { empty: !0 }, a.streamInfo());
10506
10583
  }
10507
- function Jc(e, t = {}) {
10508
- let { lineCounter: n, prettyErrors: r } = Kc(t), i = new Gc(n?.addNewLine), a = new uc(t), o = null;
10584
+ function Zc(e, t = {}) {
10585
+ let { lineCounter: n, prettyErrors: r } = Yc(t), i = new Jc(n?.addNewLine), a = new pc(t), o = null;
10509
10586
  for (let t of a.compose(i.parse(e), !0, e.length)) if (!o) o = t;
10510
10587
  else if (o.options.logLevel !== "silent") {
10511
- o.errors.push(new Es(t.range.slice(0, 2), "MULTIPLE_DOCS", "Source contains multiple documents; please use YAML.parseAllDocuments()"));
10588
+ o.errors.push(new ks(t.range.slice(0, 2), "MULTIPLE_DOCS", "Source contains multiple documents; please use YAML.parseAllDocuments()"));
10512
10589
  break;
10513
10590
  }
10514
- return r && n && (o.errors.forEach(Os(e, n)), o.warnings.forEach(Os(e, n))), o;
10591
+ return r && n && (o.errors.forEach(js(e, n)), o.warnings.forEach(js(e, n))), o;
10515
10592
  }
10516
- function Yc(e, t, n) {
10593
+ function Qc(e, t, n) {
10517
10594
  let r;
10518
10595
  typeof t == "function" ? r = t : n === void 0 && t && typeof t == "object" && (n = t);
10519
- let i = Jc(e, n);
10596
+ let i = Zc(e, n);
10520
10597
  if (!i) return null;
10521
- if (i.warnings.forEach((e) => ao(i.options.logLevel, e)), i.errors.length > 0) {
10598
+ if (i.warnings.forEach((e) => co(i.options.logLevel, e)), i.errors.length > 0) {
10522
10599
  if (i.options.logLevel !== "silent") throw i.errors[0];
10523
10600
  i.errors = [];
10524
10601
  }
10525
10602
  return i.toJS(Object.assign({ reviver: r }, n));
10526
10603
  }
10527
- function Xc(e, t, n) {
10604
+ function $c(e, t, n) {
10528
10605
  let r = null;
10529
10606
  if (typeof t == "function" || Array.isArray(t) ? r = t : n === void 0 && t && (n = t), typeof n == "string" && (n = n.length), typeof n == "number") {
10530
10607
  let e = Math.round(n);
@@ -10534,41 +10611,41 @@ function Xc(e, t, n) {
10534
10611
  let { keepUndefined: e } = n ?? t ?? {};
10535
10612
  if (!e) return;
10536
10613
  }
10537
- return ia(e) && !r ? e.toString(n) : new Cs(e, r, n).toString(n);
10614
+ return sa(e) && !r ? e.toString(n) : new Es(e, r, n).toString(n);
10538
10615
  }
10539
10616
  //#endregion
10540
10617
  //#region node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/index.js
10541
- var Zc = /* @__PURE__ */ v({
10542
- Alias: () => Da,
10543
- CST: () => Tc,
10544
- Composer: () => uc,
10545
- Document: () => Cs,
10546
- Lexer: () => Ic,
10547
- LineCounter: () => Lc,
10618
+ var el = /* @__PURE__ */ v({
10619
+ Alias: () => Aa,
10620
+ CST: () => Oc,
10621
+ Composer: () => pc,
10622
+ Document: () => Es,
10623
+ Lexer: () => zc,
10624
+ LineCounter: () => Bc,
10548
10625
  Pair: () => Q,
10549
- Parser: () => Gc,
10626
+ Parser: () => Jc,
10550
10627
  Scalar: () => Z,
10551
- Schema: () => xs,
10552
- YAMLError: () => Ts,
10628
+ Schema: () => ws,
10629
+ YAMLError: () => Os,
10553
10630
  YAMLMap: () => $,
10554
- YAMLParseError: () => Es,
10555
- YAMLSeq: () => So,
10556
- YAMLWarning: () => Ds,
10557
- isAlias: () => ra,
10631
+ YAMLParseError: () => ks,
10632
+ YAMLSeq: () => To,
10633
+ YAMLWarning: () => As,
10634
+ isAlias: () => oa,
10558
10635
  isCollection: () => J,
10559
- isDocument: () => ia,
10560
- isMap: () => aa,
10636
+ isDocument: () => sa,
10637
+ isMap: () => ca,
10561
10638
  isNode: () => Y,
10562
10639
  isPair: () => K,
10563
10640
  isScalar: () => q,
10564
- isSeq: () => oa,
10565
- parse: () => Yc,
10566
- parseAllDocuments: () => qc,
10567
- parseDocument: () => Jc,
10568
- stringify: () => Xc,
10569
- visit: () => ua,
10570
- visitAsync: () => fa
10571
- }), Qc = [
10641
+ isSeq: () => la,
10642
+ parse: () => Qc,
10643
+ parseAllDocuments: () => Xc,
10644
+ parseDocument: () => Zc,
10645
+ stringify: () => $c,
10646
+ visit: () => pa,
10647
+ visitAsync: () => ha
10648
+ }), tl = [
10572
10649
  {
10573
10650
  version: "001_add_workflow_enabled",
10574
10651
  async apply() {
@@ -10586,20 +10663,26 @@ var Zc = /* @__PURE__ */ v({
10586
10663
  async apply() {
10587
10664
  await C.exec("\n CREATE TABLE IF NOT EXISTS push_deliveries (\n job_id INTEGER PRIMARY KEY,\n delivered_at DATETIME DEFAULT CURRENT_TIMESTAMP\n )\n ");
10588
10665
  }
10666
+ },
10667
+ {
10668
+ version: "004_add_ai_requests",
10669
+ async apply() {
10670
+ await C.exec("\n CREATE TABLE IF NOT EXISTS ai_requests (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n job_id INTEGER NOT NULL,\n workflow_url TEXT NOT NULL,\n request_json TEXT NOT NULL,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP\n );\n CREATE INDEX IF NOT EXISTS idx_ai_requests_job ON ai_requests(job_id);\n ");
10671
+ }
10589
10672
  }
10590
10673
  ];
10591
- async function $c() {
10674
+ async function nl() {
10592
10675
  await C.exec("\n CREATE TABLE IF NOT EXISTS schema_migrations (\n version TEXT PRIMARY KEY,\n applied_at DATETIME DEFAULT CURRENT_TIMESTAMP\n )\n ");
10593
10676
  let e = new Set((await C.all("SELECT version FROM schema_migrations")).map((e) => e.version));
10594
- for (let t of Qc) e.has(t.version) || (await t.apply(), await C.run("INSERT INTO schema_migrations (version) VALUES (?)", [t.version]));
10677
+ for (let t of tl) e.has(t.version) || (await t.apply(), await C.run("INSERT INTO schema_migrations (version) VALUES (?)", [t.version]));
10595
10678
  }
10596
- function el(e) {
10679
+ function rl(e) {
10597
10680
  let t = String(e || "").toLowerCase().replace(/[^a-z0-9]/g, "-").replace(/^-+|-+$/g, "");
10598
10681
  if (!t) throw Error("Workflow requires a name or id");
10599
10682
  return t;
10600
10683
  }
10601
- function tl(e) {
10602
- let t = Zc.parse(e);
10684
+ function il(e) {
10685
+ let t = el.parse(e);
10603
10686
  if (!t || typeof t != "object" || Array.isArray(t)) throw Error("Workflow must be a YAML object");
10604
10687
  if (t.includes) throw Error("includes is not supported for database workflows");
10605
10688
  if (typeof t.name != "string" || !t.name.trim()) throw Error("Workflow name is required");
@@ -10626,7 +10709,7 @@ function tl(e) {
10626
10709
  if (a && a.paths.some((e) => typeof e != "string" || !e.trim())) throw Error("artifacts.paths must contain non-empty strings");
10627
10710
  if (o && (typeof o.key != "string" || !o.key.trim() || o.paths.some((e) => typeof e != "string" || !e.trim()))) throw Error("cache requires a non-empty key and paths");
10628
10711
  return [{
10629
- id: el(t.id || t.name),
10712
+ id: rl(t.id || t.name),
10630
10713
  name: t.name,
10631
10714
  matrix: t.matrix,
10632
10715
  on: {
@@ -10646,12 +10729,12 @@ function tl(e) {
10646
10729
  tags: Array.isArray(t.tags) ? [...new Set(t.tags.filter((e) => typeof e == "string").map((e) => e.trim()).filter(Boolean))] : void 0
10647
10730
  }];
10648
10731
  }
10649
- var nl = class {
10732
+ var al = class {
10650
10733
  async init() {
10651
- await C.exec("\n CREATE TABLE IF NOT EXISTS workflows (\n id TEXT PRIMARY KEY, name TEXT NOT NULL, source_yaml TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'draft', active_revision INTEGER, enabled INTEGER NOT NULL DEFAULT 1,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP\n );\n CREATE TABLE IF NOT EXISTS workflow_revisions (\n workflow_id TEXT NOT NULL, revision INTEGER NOT NULL, source_yaml TEXT NOT NULL,\n normalized_json TEXT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (workflow_id, revision)\n );\n CREATE TABLE IF NOT EXISTS scheduled_runs (\n workflow_id TEXT NOT NULL, trigger_id TEXT NOT NULL, scheduled_for TEXT NOT NULL,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (workflow_id, trigger_id, scheduled_for)\n );\n "), await $c();
10734
+ await C.exec("\n CREATE TABLE IF NOT EXISTS workflows (\n id TEXT PRIMARY KEY, name TEXT NOT NULL, source_yaml TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'draft', active_revision INTEGER, enabled INTEGER NOT NULL DEFAULT 1,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP\n );\n CREATE TABLE IF NOT EXISTS workflow_revisions (\n workflow_id TEXT NOT NULL, revision INTEGER NOT NULL, source_yaml TEXT NOT NULL,\n normalized_json TEXT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (workflow_id, revision)\n );\n CREATE TABLE IF NOT EXISTS scheduled_runs (\n workflow_id TEXT NOT NULL, trigger_id TEXT NOT NULL, scheduled_for TEXT NOT NULL,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (workflow_id, trigger_id, scheduled_for)\n );\n "), await nl();
10652
10735
  }
10653
10736
  validate(e) {
10654
- let t = tl(e);
10737
+ let t = il(e);
10655
10738
  for (let e of t) {
10656
10739
  for (let t of e.schedule || []) if (typeof t.cron != "string" || t.cron.trim().split(/\s+/).length !== 5) throw Error("schedule.cron must have five fields");
10657
10740
  for (let t of e.solar || []) if (!t.event || !Number.isFinite(t.latitude) || !Number.isFinite(t.longitude)) throw Error("solar triggers require event, latitude, and longitude");
@@ -10661,7 +10744,7 @@ var nl = class {
10661
10744
  async saveDraft(e, t, n = !0) {
10662
10745
  let r = this.validate(t);
10663
10746
  if (r.length !== 1) throw Error("Workflow must contain exactly one definition");
10664
- let i = el(e);
10747
+ let i = rl(e);
10665
10748
  r[0].id = i;
10666
10749
  let a = await C.get("SELECT COALESCE(MAX(revision), 0) AS revision FROM workflow_revisions WHERE workflow_id = ?", [i]), o = Number(a?.revision || 0) + 1;
10667
10750
  return await C.run("INSERT INTO workflows (id, name, source_yaml, status, enabled) VALUES (?, ?, ?, 'draft', ?)\n ON CONFLICT(id) DO UPDATE SET name = excluded.name, source_yaml = excluded.source_yaml, status = 'draft', enabled = excluded.enabled, updated_at = CURRENT_TIMESTAMP", [
@@ -10752,10 +10835,10 @@ var nl = class {
10752
10835
  n
10753
10836
  ]);
10754
10837
  }
10755
- }, rl = 50, il = 500, al = class e {
10838
+ }, ol = 50, sl = 500, cl = class e {
10756
10839
  server;
10757
10840
  preprocessors = /* @__PURE__ */ new Map();
10758
- workflows = new nl();
10841
+ workflows = new al();
10759
10842
  secretRepository = new tr();
10760
10843
  queue;
10761
10844
  secrets;
@@ -10796,11 +10879,11 @@ var nl = class {
10796
10879
  if (e.method === "GET" && n.pathname === "/app-header.html") return t.writeHead(200, {
10797
10880
  "Content-Type": "text/html; charset=utf-8",
10798
10881
  "Cache-Control": "no-store"
10799
- }), t.end(Ki);
10882
+ }), t.end(Yi);
10800
10883
  if (e.method === "GET" && n.pathname === "/app-router.html") return t.writeHead(200, {
10801
10884
  "Content-Type": "text/html; charset=utf-8",
10802
10885
  "Cache-Control": "no-store"
10803
- }), t.end(Ji);
10886
+ }), t.end(Zi);
10804
10887
  if (e.method === "GET" && (n.pathname === "/runs" || n.pathname === "/") || e.method === "GET" && n.pathname === "/help") return this.renderAppShell(t);
10805
10888
  if (e.method === "GET" && n.pathname === "/api") return t.writeHead(200, {
10806
10889
  "Cache-Control": "no-store",
@@ -10812,7 +10895,7 @@ var nl = class {
10812
10895
  if (e.method === "GET" && n.pathname === "/pages/workflows.html") {
10813
10896
  if (!this.requireAdmin(e, t)) return;
10814
10897
  let r = n.searchParams.get("page") === "secrets" ? "secrets" : n.searchParams.get("page") === "editor" ? "editor" : "workflows", i = n.searchParams.get("id") || "", a = Number(n.searchParams.get("revision"));
10815
- return this.renderPageComponent(t, r === "editor" ? "page-workflow-editor" : r === "secrets" ? "page-secrets" : "page-workflows", Xi(r, i, Number.isSafeInteger(a) && a > 0 ? a : void 0));
10898
+ return this.renderPageComponent(t, r === "editor" ? "page-workflow-editor" : r === "secrets" ? "page-secrets" : "page-workflows", $i(r, i, Number.isSafeInteger(a) && a > 0 ? a : void 0));
10816
10899
  }
10817
10900
  if (e.method === "GET" && n.pathname === "/pages/settings.html") {
10818
10901
  if (!this.requireAdmin(e, t)) return;
@@ -10857,8 +10940,8 @@ var nl = class {
10857
10940
  return t.writeHead(302, { Location: `${i}${n.search}` }), t.end();
10858
10941
  }
10859
10942
  if (e.method === "GET" && n.pathname === "/api/jobs") {
10860
- let e = n.searchParams.get("afterId"), r = n.searchParams.get("beforeId"), i = n.searchParams.get("limit"), a = n.searchParams.get("filter")?.trim() || void 0, o = n.searchParams.get("workflowId")?.trim() || void 0, s = e === null ? void 0 : Number(e), c = r === null ? void 0 : Number(r), l = i === null ? rl : Number(i);
10861
- return s !== void 0 && (!Number.isSafeInteger(s) || s < 0) ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "afterId must be a non-negative integer" }))) : c !== void 0 && (!Number.isSafeInteger(c) || c < 1) ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "beforeId must be a positive integer" }))) : !Number.isSafeInteger(l) || l < 1 || l > il ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: `limit must be an integer from 1 to ${il}` }))) : a && a.length > 200 ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "filter must be at most 200 characters" }))) : this.renderDashboardJobs(t, l, s, c, a, o);
10943
+ let e = n.searchParams.get("afterId"), r = n.searchParams.get("beforeId"), i = n.searchParams.get("limit"), a = n.searchParams.get("filter")?.trim() || void 0, o = n.searchParams.get("workflowId")?.trim() || void 0, s = e === null ? void 0 : Number(e), c = r === null ? void 0 : Number(r), l = i === null ? ol : Number(i);
10944
+ return s !== void 0 && (!Number.isSafeInteger(s) || s < 0) ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "afterId must be a non-negative integer" }))) : c !== void 0 && (!Number.isSafeInteger(c) || c < 1) ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "beforeId must be a positive integer" }))) : !Number.isSafeInteger(l) || l < 1 || l > sl ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: `limit must be an integer from 1 to ${sl}` }))) : a && a.length > 200 ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "filter must be at most 200 characters" }))) : this.renderDashboardJobs(t, l, s, c, a, o);
10862
10945
  }
10863
10946
  if (e.method === "GET" && n.pathname === "/api/events") return this.events.subscribe(e, t);
10864
10947
  if (e.method === "GET" && n.pathname === "/api/push/public-key") return this.handlePushPublicKey(t);
@@ -10887,6 +10970,8 @@ var nl = class {
10887
10970
  let r = n.pathname.replace("/runs/", "");
10888
10971
  return this.renderRunDetails(r, t, "html", await this.hasScope(e, "logs:read"));
10889
10972
  }
10973
+ let d = n.pathname.match(/^\/api\/runs\/(\d+)\/ai-help$/);
10974
+ if (e.method === "POST" && d) return this.handleAiHelp(e, t, d[1]);
10890
10975
  if (e.method === "GET" && n.pathname.startsWith("/api/runs/")) {
10891
10976
  let r = n.pathname.match(/^\/api\/runs\/(\d+)\/artifacts\/(.+)$/);
10892
10977
  if (r) return this.handleArtifactDownload(e, t, r[1], decodeURIComponent(r[2]));
@@ -11181,7 +11266,7 @@ var nl = class {
11181
11266
  return e.writeHead(200, {
11182
11267
  "Content-Type": "text/html; charset=utf-8",
11183
11268
  "Cache-Control": "no-store"
11184
- }), e.end(qi);
11269
+ }), e.end(Xi);
11185
11270
  }
11186
11271
  renderPageComponent(e, t, n, r = !1) {
11187
11272
  let i = Array.from(n.matchAll(/<style[\s\S]*?<\/style>/gi)).map((e) => e[0]).join(""), a = n;
@@ -11242,6 +11327,27 @@ var nl = class {
11242
11327
  "Content-Disposition": `attachment; filename="${r.replace(/[^a-zA-Z0-9._-]/g, "_")}"`
11243
11328
  }), t.end(Buffer.from(i.content, "base64"))) : (t.writeHead(404, { "Content-Type": "application/json" }), t.end(JSON.stringify({ error: "Artifact not found" })));
11244
11329
  }
11330
+ async handleAiHelp(e, t, n) {
11331
+ if (!await this.hasScope(e, "logs:read")) return this.requireScope(e, t, "logs:read");
11332
+ let r = await this.currentSecrets().then((e) => e.OPENAI_API_KEY || process.env.OPENAI_API_KEY), i = process.env.OPENAI_API_MODEL, a = process.env.OPENAI_API_URL;
11333
+ if (!i || !a) return t.writeHead(503, { "Content-Type": "application/json" }), t.end(JSON.stringify({ error: "AI help is not configured" }));
11334
+ let o = await this.queue.getJob(n);
11335
+ if (!o?.report) return t.writeHead(404, { "Content-Type": "application/json" }), t.end(JSON.stringify({ error: "Run report not found" }));
11336
+ let s = await this.readJson(e, t), c = typeof s?.stepId == "string" ? s.stepId : "", l = typeof s?.question == "string" && s.question.trim() ? s.question.trim() : void 0, u = Array.isArray(s?.conversation) ? s.conversation.filter((e) => (e?.role === "user" || e?.role === "assistant") && typeof e.content == "string").slice(-20) : [], d = JSON.parse(o.report), p = await this.workflows.getRevisionSnapshot(o.workflow_id, o.workflow_revision);
11337
+ if (!p || !c) return t.writeHead(400, { "Content-Type": "application/json" }), t.end(JSON.stringify({ error: "A failed step and workflow revision are required" }));
11338
+ let m = await this.currentSecrets(), h = Ki(p.sourceYaml, d.steps || [], await this.queue.getJobLogs(n), c, (e) => this.redact(e, m), l, u);
11339
+ try {
11340
+ let o = qi(i, h), s = new f(`/runs/${n}`, `${e.headers["x-forwarded-proto"] || "http"}://${e.headers["x-forwarded-host"] || e.headers.host}`).toString();
11341
+ await this.queue.saveAiRequest(n, s, o);
11342
+ let c = await Ji(a, r, o);
11343
+ return t.writeHead(200, {
11344
+ "Cache-Control": "no-store",
11345
+ "Content-Type": "application/json"
11346
+ }), t.end(JSON.stringify({ answer: c }));
11347
+ } catch (e) {
11348
+ return t.writeHead(502, { "Content-Type": "application/json" }), t.end(JSON.stringify({ error: e.message }));
11349
+ }
11350
+ }
11245
11351
  async handleCancelJob(e, t, n) {
11246
11352
  if (!await this.requireScope(e, t, "runs:control")) return;
11247
11353
  let r = await this.queue.cancelJob(n);
@@ -11281,7 +11387,7 @@ var nl = class {
11281
11387
  });
11282
11388
  });
11283
11389
  }
11284
- }, ol = c(m), sl = class {
11390
+ }, ll = c(m), ul = class {
11285
11391
  name = "systemd";
11286
11392
  async isSupported() {
11287
11393
  try {
@@ -11405,7 +11511,7 @@ var nl = class {
11405
11511
  cancel: async () => {
11406
11512
  f = !0;
11407
11513
  try {
11408
- t.image && await ol(`docker stop -t 2 ${s}`).catch(() => {}), await ol(`systemctl stop ${s}.service`).catch(() => {});
11514
+ t.image && await ll(`docker stop -t 2 ${s}`).catch(() => {}), await ll(`systemctl stop ${s}.service`).catch(() => {});
11409
11515
  } catch {}
11410
11516
  },
11411
11517
  logFilePath: o
@@ -11415,7 +11521,7 @@ var nl = class {
11415
11521
  let t = await g(e, "utf-8"), n = t.includes("Running as unit: ") ? t.indexOf("\n") + 1 : 0, r = t.includes("Finished with result: ") ? t.lastIndexOf("Finished with result: ") : t.length;
11416
11522
  return t.slice(n, r);
11417
11523
  }
11418
- }, cl = class {
11524
+ }, dl = class {
11419
11525
  name = "standard-process";
11420
11526
  async isSupported() {
11421
11527
  return !0;
@@ -11531,19 +11637,19 @@ var nl = class {
11531
11637
  };
11532
11638
  //#endregion
11533
11639
  //#region src/drivers/index.ts
11534
- async function ll() {
11535
- let e = new sl();
11536
- return await e.isSupported() ? (console.log("⚡ Selected Execution Driver: Systemd (cgroups enabled)"), e) : (console.log("📦 Selected Execution Driver: Standard Process (Fallback)"), new cl());
11640
+ async function fl() {
11641
+ let e = new ul();
11642
+ return await e.isSupported() ? (console.log("⚡ Selected Execution Driver: Systemd (cgroups enabled)"), e) : (console.log("📦 Selected Execution Driver: Standard Process (Fallback)"), new dl());
11537
11643
  }
11538
11644
  //#endregion
11539
11645
  //#region src/signals.ts
11540
- async function ul(e) {
11646
+ async function pl(e) {
11541
11647
  let t = !1;
11542
11648
  async function n(n) {
11543
11649
  if (!t) {
11544
11650
  t = !0, console.log(`\n🛑 Received ${n}. Initiating graceful shutdown...`);
11545
11651
  try {
11546
- bl(), e.length > 0 && (console.log("⚙️ Waiting for active worker jobs to drain..."), await Promise.allSettled(e)), console.log("✨ Engine stopped cleanly. Goodbye!"), process.exit(0);
11652
+ Cl(), e.length > 0 && (console.log("⚙️ Waiting for active worker jobs to drain..."), await Promise.allSettled(e)), console.log("✨ Engine stopped cleanly. Goodbye!"), process.exit(0);
11547
11653
  } catch (e) {
11548
11654
  console.error("❌ Error during graceful shutdown:", e.message), process.exit(1);
11549
11655
  }
@@ -11553,7 +11659,7 @@ async function ul(e) {
11553
11659
  }
11554
11660
  //#endregion
11555
11661
  //#region src/plugins/manager.ts
11556
- var dl = class {
11662
+ var ml = class {
11557
11663
  plugins;
11558
11664
  constructor(e = []) {
11559
11665
  this.plugins = e;
@@ -11575,7 +11681,7 @@ var dl = class {
11575
11681
  console.error(`[Plugin Error] ${n.name}.onWorkflowFinish:`, e);
11576
11682
  }
11577
11683
  }
11578
- }, fl = class {
11684
+ }, hl = class {
11579
11685
  name = "github-commit-status";
11580
11686
  token;
11581
11687
  apiUrl;
@@ -11614,20 +11720,20 @@ var dl = class {
11614
11720
  hasCoordinates(e) {
11615
11721
  return !!(this.token && e.inputs.owner && e.inputs.repo && e.inputs.commit_sha);
11616
11722
  }
11617
- }, pl = /* @__PURE__ */ new Map();
11618
- function ml(e, t) {
11723
+ }, gl = /* @__PURE__ */ new Map();
11724
+ function _l(e, t) {
11619
11725
  if (!e.trim()) throw Error("Workflow plugin name is required");
11620
- pl.set(e, t);
11726
+ gl.set(e, t);
11621
11727
  }
11622
- function hl(e) {
11623
- let t = pl.get(e.name);
11728
+ function vl(e) {
11729
+ let t = gl.get(e.name);
11624
11730
  if (!t) throw Error(`Unknown workflow plugin '${e.name}'`);
11625
11731
  return t(e);
11626
11732
  }
11627
- ml("github-status", (e) => {
11733
+ _l("github-status", (e) => {
11628
11734
  let t = e.secrets.GITHUB_TOKEN || e.secrets.token;
11629
11735
  if (!t) throw Error("Plugin 'github-status' requires a GITHUB_TOKEN secret mapping");
11630
- return new fl({
11736
+ return new hl({
11631
11737
  token: t,
11632
11738
  context: e.context,
11633
11739
  apiUrl: e.apiUrl
@@ -11635,38 +11741,38 @@ ml("github-status", (e) => {
11635
11741
  });
11636
11742
  //#endregion
11637
11743
  //#region src/worker.ts
11638
- var gl = { isStopping: !1 }, _l = /* @__PURE__ */ new Set(), vl = null, yl = null;
11639
- function bl() {
11640
- gl.isStopping = !0, vl?.abort(), yl?.();
11744
+ var yl = { isStopping: !1 }, bl = /* @__PURE__ */ new Set(), xl = null, Sl = null;
11745
+ function Cl() {
11746
+ yl.isStopping = !0, xl?.abort(), Sl?.();
11641
11747
  }
11642
- function xl(e, t, n, r) {
11643
- gl.isStopping = !1;
11644
- let i = [Sl(e, t, n, r)];
11645
- return ul(i), i;
11748
+ function wl(e, t, n, r) {
11749
+ yl.isStopping = !1;
11750
+ let i = [Tl(e, t, n, r)];
11751
+ return pl(i), i;
11646
11752
  }
11647
- async function Sl(e, t, n, r) {
11648
- let i = await ll(), a = new nl(), o = /* @__PURE__ */ new Set(), s = 0, c = null, l = () => {
11753
+ async function Tl(e, t, n, r) {
11754
+ let i = await fl(), a = new al(), o = /* @__PURE__ */ new Set(), s = 0, c = null, l = () => {
11649
11755
  s++, c?.();
11650
11756
  };
11651
- yl = l, vl = new AbortController();
11652
- let u = Cl(r, vl.signal, l);
11653
- for (console.log(`🚀 Worker scheduler started. Driver: ${i.name}. Concurrency: ${e}. Tags: ${r.tags.join(", ") || "(none)"}`); !gl.isStopping;) {
11757
+ Sl = l, xl = new AbortController();
11758
+ let u = El(r, xl.signal, l);
11759
+ for (console.log(`🚀 Worker scheduler started. Driver: ${i.name}. Concurrency: ${e}. Tags: ${r.tags.join(", ") || "(none)"}`); !yl.isStopping;) {
11654
11760
  let n = s;
11655
11761
  try {
11656
- for (; o.size < e && !gl.isStopping;) {
11762
+ for (; o.size < e && !yl.isStopping;) {
11657
11763
  let e = await t.claimNextJob(r.tags);
11658
11764
  if (!e) break;
11659
- if (gl.isStopping) {
11765
+ if (yl.isStopping) {
11660
11766
  await t.releaseJob(e.id);
11661
11767
  break;
11662
11768
  }
11663
11769
  let n = process.env.WORKER_NAME || "cli", s;
11664
11770
  s = (async () => {
11665
- El(r, e.id);
11771
+ kl(r, e.id);
11666
11772
  let o = await a.getRevision(e.workflow_id, e.workflow_revision);
11667
11773
  if (!o) throw await t.finishJob(e.id, "failed"), Error(`Workflow ${e.workflow_id} revision ${e.workflow_revision} was not found`);
11668
11774
  let s = new me();
11669
- s.replace(await Dl(r, n, e.id)), await Ol({
11775
+ s.replace(await Al(r, n, e.id)), await jl({
11670
11776
  workerId: n,
11671
11777
  job: e,
11672
11778
  queue: t,
@@ -11676,17 +11782,17 @@ async function Sl(e, t, n, r) {
11676
11782
  workflow: o
11677
11783
  });
11678
11784
  })().catch((e) => console.error(`[${n}] ⚠️ Worker execution error:`, e)).finally(() => {
11679
- o.delete(s), El(r, e.id), l();
11785
+ o.delete(s), kl(r, e.id), l();
11680
11786
  }), o.add(s);
11681
11787
  }
11682
11788
  } catch (e) {
11683
11789
  console.error("⚠️ Worker scheduler claim error:", e), setTimeout(l, 5e3).unref();
11684
11790
  }
11685
- !gl.isStopping && s === n && (await wl(n, () => s, (e) => c = e), c = null);
11791
+ !yl.isStopping && s === n && (await Dl(n, () => s, (e) => c = e), c = null);
11686
11792
  }
11687
- vl.abort(), await Promise.allSettled(o), await u, yl = null, console.log("🛑 Worker scheduler stopped cleanly.");
11793
+ xl.abort(), await Promise.allSettled(o), await u, Sl = null, console.log("🛑 Worker scheduler stopped cleanly.");
11688
11794
  }
11689
- async function Cl(e, t, n) {
11795
+ async function El(e, t, n) {
11690
11796
  let r = 1e3;
11691
11797
  for (; !t.aborted;) {
11692
11798
  try {
@@ -11697,10 +11803,10 @@ async function Cl(e, t, n) {
11697
11803
  if (t.aborted || e?.name === "AbortError") break;
11698
11804
  console.error(`⚠️ Worker event stream disconnected: ${e.message}`);
11699
11805
  }
11700
- await Tl(r, t), r = Math.min(r * 2, 3e4);
11806
+ await Ol(r, t), r = Math.min(r * 2, 3e4);
11701
11807
  }
11702
11808
  }
11703
- function wl(e, t, n) {
11809
+ function Dl(e, t, n) {
11704
11810
  return new Promise((r) => {
11705
11811
  if (t() !== e) return r();
11706
11812
  let i = setTimeout(r, 6e4);
@@ -11709,7 +11815,7 @@ function wl(e, t, n) {
11709
11815
  });
11710
11816
  });
11711
11817
  }
11712
- function Tl(e, t) {
11818
+ function Ol(e, t) {
11713
11819
  return new Promise((n) => {
11714
11820
  if (t.aborted) return n();
11715
11821
  let r = () => {
@@ -11720,7 +11826,7 @@ function Tl(e, t) {
11720
11826
  t.addEventListener("abort", r, { once: !0 });
11721
11827
  });
11722
11828
  }
11723
- async function El(e, t) {
11829
+ async function kl(e, t) {
11724
11830
  if (e.workerToken) try {
11725
11831
  let n = await fetch(new URL("/api/events", e.serverUrl), {
11726
11832
  method: "POST",
@@ -11736,7 +11842,7 @@ async function El(e, t) {
11736
11842
  Jn("Failed to publish job status event:", e);
11737
11843
  }
11738
11844
  }
11739
- async function Dl(e, t, n) {
11845
+ async function Al(e, t, n) {
11740
11846
  if (!e.workerToken) return {};
11741
11847
  try {
11742
11848
  let r = await fetch(new URL(`/api/jobs/${n}/secrets`, e.serverUrl), {
@@ -11752,7 +11858,7 @@ async function Dl(e, t, n) {
11752
11858
  throw console.error(`Unable to retrieve secrets for job ${n}:`, e), e;
11753
11859
  }
11754
11860
  }
11755
- async function Ol(e) {
11861
+ async function jl(e) {
11756
11862
  let { workerId: t, job: n, config: r, secrets: a, queue: o } = e;
11757
11863
  console.log(`\n[${t}] 📦 Claimed Job #${n.id} (Workflow: ${n.workflow_id})`);
11758
11864
  let s = typeof n.payload == "string" ? JSON.parse(n.payload) : n.payload;
@@ -11777,10 +11883,10 @@ async function Ol(e) {
11777
11883
  durationMs: 0,
11778
11884
  outputs: {},
11779
11885
  logContent: ""
11780
- })), b = Hl(n, "running", p, f, _.env, y, s);
11781
- await o.saveReport(n.id, b), El(r, n.id);
11886
+ })), b = Gl(n, "running", p, f, _.env, y, s);
11887
+ await o.saveReport(n.id, b), kl(r, n.id);
11782
11888
  try {
11783
- Object.assign(_.env, await Ml(l.env, _)), zl(l.secretFiles, a, g), v = l.cache ? String(await Zn.evaluateValue(l.cache.key, _)) : "", v && l.cache && await Rl(o, "cache", `${n.workflow_id}:${v}`, l.cache.paths, g), await o.saveReport(n.id, b);
11889
+ Object.assign(_.env, await Fl(l.env, _)), Hl(l.secretFiles, a, g), v = l.cache ? String(await Zn.evaluateValue(l.cache.key, _)) : "", v && l.cache && await Vl(o, "cache", `${n.workflow_id}:${v}`, l.cache.paths, g), await o.saveReport(n.id, b);
11784
11890
  } catch (e) {
11785
11891
  b.status = "failed", b.finishedAt = (/* @__PURE__ */ new Date()).toISOString(), b.durationMs = Date.now() - p;
11786
11892
  let r = {
@@ -11795,39 +11901,39 @@ async function Ol(e) {
11795
11901
  }
11796
11902
  let x = [...r.plugins];
11797
11903
  for (let e of l.plugins || []) try {
11798
- let t = await Ml(e.secrets, _);
11799
- x.push(hl({
11904
+ let t = await Fl(e.secrets, _);
11905
+ x.push(vl({
11800
11906
  ...e,
11801
11907
  secrets: t
11802
11908
  }));
11803
11909
  } catch (n) {
11804
11910
  console.error(`[${t}] Workflow plugin '${e.name}' failed to initialize:`, n);
11805
11911
  }
11806
- let S = new dl(x), ee = {
11912
+ let S = new ml(x), ee = {
11807
11913
  jobId: String(n.id),
11808
11914
  workflowName: l.name,
11809
11915
  inputs: f,
11810
11916
  runUrl: new URL(`/runs/${n.id}`, r.serverUrl).toString()
11811
11917
  };
11812
11918
  await S.triggerWorkflowStart(ee);
11813
- let { cancelled: te, failed: ne } = await kl({
11919
+ let { cancelled: te, failed: ne } = await Ml({
11814
11920
  payload: s,
11815
11921
  steps: d,
11816
11922
  executionContext: _,
11817
11923
  ...u
11818
11924
  }, b), re = te ? "cancelled" : ne ? "failed" : "success";
11819
11925
  if (re === "success") try {
11820
- let e = l.artifacts ? await Ll(l.artifacts.paths, g) : [];
11926
+ let e = l.artifacts ? await Bl(l.artifacts.paths, g) : [];
11821
11927
  if (e.length && (await o.saveStoredFiles("artifact", String(n.id), e), b.artifacts = e.map((e) => e.path)), v && l.cache) {
11822
- let e = await Ll(l.cache.paths, g);
11928
+ let e = await Bl(l.cache.paths, g);
11823
11929
  e.length && await o.saveStoredFiles("cache", `${n.workflow_id}:${v}`, e);
11824
11930
  }
11825
11931
  } catch (e) {
11826
11932
  console.error(`[${t}] ⚠️ Failed to store workflow files:`, e), re = "failed";
11827
11933
  }
11828
- b.status = re, b.durationMs = Date.now() - p, b.finishedAt = (/* @__PURE__ */ new Date()).toISOString(), await o.completeJob(n.id, re, b), El(r, n.id), console.log(`[${t}] ✅ Job #${n.id} completed as: ${re}`), await S.triggerWorkflowFinish(ee, re);
11934
+ b.status = re, b.durationMs = Date.now() - p, b.finishedAt = (/* @__PURE__ */ new Date()).toISOString(), await o.completeJob(n.id, re, b), kl(r, n.id), console.log(`[${t}] ✅ Job #${n.id} completed as: ${re}`), await S.triggerWorkflowFinish(ee, re);
11829
11935
  }
11830
- async function kl(e, t) {
11936
+ async function Ml(e, t) {
11831
11937
  let { driver: n, workerId: r, queue: i, config: a, job: o, payload: s, steps: c, executionContext: l } = e, u = t.steps, d = !1, f = !1, p = 0;
11832
11938
  try {
11833
11939
  for (let s = 0; s < c.length; s++) {
@@ -11842,14 +11948,14 @@ async function kl(e, t) {
11842
11948
  logContent: "",
11843
11949
  startedAt: h,
11844
11950
  finishedAt: void 0
11845
- }, t.durationMs = Date.now() - Date.parse(t.startedAt), await i.saveReport(o.id, t), El(a, o.id);
11951
+ }, t.durationMs = Date.now() - Date.parse(t.startedAt), await i.saveReport(o.id, t), kl(a, o.id);
11846
11952
  let g = {
11847
11953
  failed: !0,
11848
11954
  skipped: !1,
11849
11955
  cancelled: !1,
11850
11956
  report: null
11851
11957
  }, _ = e.workflow?.retries ?? 0;
11852
- for (let e = 1; e <= _ + 1 && (g = await Al({
11958
+ for (let e = 1; e <= _ + 1 && (g = await Nl({
11853
11959
  workerId: r,
11854
11960
  jobId: o.id,
11855
11961
  step: m,
@@ -11877,7 +11983,7 @@ async function kl(e, t) {
11877
11983
  exitCode: 1,
11878
11984
  error: "Step failed before execution started",
11879
11985
  finishedAt: (/* @__PURE__ */ new Date()).toISOString()
11880
- }, p = s + 1, t.durationMs = Date.now() - Date.parse(t.startedAt), await i.saveReport(o.id, t), El(a, o.id), g.skipped) break;
11986
+ }, p = s + 1, t.durationMs = Date.now() - Date.parse(t.startedAt), await i.saveReport(o.id, t), kl(a, o.id), g.skipped) break;
11881
11987
  if (g.cancelled) {
11882
11988
  f = !0, d = !0;
11883
11989
  break;
@@ -11890,13 +11996,13 @@ async function kl(e, t) {
11890
11996
  } catch (e) {
11891
11997
  console.log("🛑 Step failed", e), d = !0;
11892
11998
  }
11893
- return p < c.length && (Vl(c, p, u), t.durationMs = Date.now() - Date.parse(t.startedAt), await i.saveReport(o.id, t), El(a, o.id)), {
11999
+ return p < c.length && (Wl(c, p, u), t.durationMs = Date.now() - Date.parse(t.startedAt), await i.saveReport(o.id, t), kl(a, o.id)), {
11894
12000
  failed: d,
11895
12001
  cancelled: f,
11896
12002
  stepReports: u
11897
12003
  };
11898
12004
  }
11899
- async function Al(e) {
12005
+ async function Nl(e) {
11900
12006
  let { step: t, stepIndex: n, executionContext: r } = e;
11901
12007
  if (t.id ||= `step-${n}`, t.name ||= t.id, t.if && !await Zn.evaluateConditions(t.if, r)) return Jn(`⏩ Skipped step ${t.id} based on condition: ${t.if}`, r), {
11902
12008
  failed: !1,
@@ -11905,7 +12011,7 @@ async function Al(e) {
11905
12011
  report: null
11906
12012
  };
11907
12013
  try {
11908
- let n = await Ml(t.env, r), i = {
12014
+ let n = await Fl(t.env, r), i = {
11909
12015
  jobId: String(e.jobId),
11910
12016
  step: t,
11911
12017
  command: t.run,
@@ -11922,10 +12028,10 @@ async function Al(e) {
11922
12028
  WORKING_DIR: r.workingDir
11923
12029
  }
11924
12030
  };
11925
- return t.eval ? jl({
12031
+ return t.eval ? Pl({
11926
12032
  ...e,
11927
12033
  stepContext: i
11928
- }) : Bl({
12034
+ }) : Ul({
11929
12035
  ...e,
11930
12036
  stepContext: i
11931
12037
  });
@@ -11948,7 +12054,7 @@ async function Al(e) {
11948
12054
  };
11949
12055
  }
11950
12056
  }
11951
- async function jl(e) {
12057
+ async function Pl(e) {
11952
12058
  let { queue: t, stepContext: n, executionContext: r } = e, { jobId: i, step: a } = n, o = Date.now(), s = a.id, c = a.name, l;
11953
12059
  try {
11954
12060
  let e = new Promise((e, t) => {
@@ -11998,7 +12104,7 @@ async function jl(e) {
11998
12104
  l && clearTimeout(l);
11999
12105
  }
12000
12106
  }
12001
- async function Ml(e, t) {
12107
+ async function Fl(e, t) {
12002
12108
  let n = {};
12003
12109
  if (e) for (let [r, i] of Object.entries(e)) n[r] = String(await Zn.evaluateValue(i, {
12004
12110
  ...t,
@@ -12009,18 +12115,18 @@ async function Ml(e, t) {
12009
12115
  }));
12010
12116
  return n;
12011
12117
  }
12012
- var Nl = 52428800;
12013
- function Pl(e, t) {
12118
+ var Il = 52428800;
12119
+ function Ll(e, t) {
12014
12120
  let n = i.resolve(e), r = i.resolve(n, t);
12015
12121
  if (r !== n && !r.startsWith(`${n}${i.sep}`)) throw Error(`Stored file path escapes workspace: ${t}`);
12016
12122
  return r;
12017
12123
  }
12018
- function Fl(e, t) {
12124
+ function Rl(e, t) {
12019
12125
  let n = "^";
12020
12126
  for (let e = 0; e < t.length; e++) t[e] === "*" && t[e + 1] === "*" ? (n += ".*", e++) : t[e] === "*" ? n += "[^/]*" : n += t[e].replace(/[|\\{}()[\]^$+?.]/g, "\\$&");
12021
12127
  return RegExp(`${n}$`).test(e);
12022
12128
  }
12023
- function Il(t, n) {
12129
+ function zl(t, n) {
12024
12130
  let r = i.resolve(n), a = [], o = (t) => {
12025
12131
  for (let n of e.readdirSync(t, { withFileTypes: !0 })) {
12026
12132
  let e = i.join(t, n.name);
@@ -12028,42 +12134,42 @@ function Il(t, n) {
12028
12134
  }
12029
12135
  };
12030
12136
  return o(r), a.filter((r) => t.some((t) => {
12031
- let i = Pl(n, t);
12137
+ let i = Ll(n, t);
12032
12138
  if (e.existsSync(i)) {
12033
12139
  let n = e.statSync(i);
12034
12140
  if (n.isFile()) return r === t;
12035
12141
  if (n.isDirectory()) return r === t || r.startsWith(`${t.replace(/\/$/, "")}/`);
12036
12142
  }
12037
- return Fl(r, t);
12143
+ return Rl(r, t);
12038
12144
  }));
12039
12145
  }
12040
- async function Ll(t, n) {
12041
- let r = Il(t, n), i = 0;
12146
+ async function Bl(t, n) {
12147
+ let r = zl(t, n), i = 0;
12042
12148
  return r.map((t) => {
12043
- let r = e.readFileSync(Pl(n, t));
12044
- if (r.byteLength > Nl || (i += r.byteLength) > Nl) throw Error(`Stored files exceed ${Nl} bytes`);
12149
+ let r = e.readFileSync(Ll(n, t));
12150
+ if (r.byteLength > Il || (i += r.byteLength) > Il) throw Error(`Stored files exceed ${Il} bytes`);
12045
12151
  return {
12046
12152
  path: t,
12047
12153
  content: r.toString("base64")
12048
12154
  };
12049
12155
  });
12050
12156
  }
12051
- async function Rl(t, n, r, a, o) {
12157
+ async function Vl(t, n, r, a, o) {
12052
12158
  for (let s of await t.getStoredFiles(n, r)) {
12053
- if (!a.some((e) => s.path === e || s.path.startsWith(`${e.replace(/\/$/, "")}/`) || Fl(s.path, e))) continue;
12054
- let t = Pl(o, s.path);
12159
+ if (!a.some((e) => s.path === e || s.path.startsWith(`${e.replace(/\/$/, "")}/`) || Rl(s.path, e))) continue;
12160
+ let t = Ll(o, s.path);
12055
12161
  e.mkdirSync(i.dirname(t), { recursive: !0 }), e.writeFileSync(t, Buffer.from(s.content, "base64"));
12056
12162
  }
12057
12163
  }
12058
- function zl(t, n, r) {
12164
+ function Hl(t, n, r) {
12059
12165
  for (let [a, o] of Object.entries(t || {})) {
12060
12166
  let t = n.getValue(o);
12061
12167
  if (!t) throw Error(`Secret '${o}' is not available for file '${a}'`);
12062
- let s = Pl(r, a);
12168
+ let s = Ll(r, a);
12063
12169
  e.mkdirSync(i.dirname(s), { recursive: !0 }), e.writeFileSync(s, t.encoding === "base64" ? Buffer.from(t.value, "base64") : t.value, { mode: 384 }), e.chmodSync(s, 384);
12064
12170
  }
12065
12171
  }
12066
- async function Bl(t) {
12172
+ async function Ul(t) {
12067
12173
  let { workerId: n, jobId: r, stepContext: i, executionContext: a, driver: o, queue: s } = t, { step: c } = i, l = c.id, u = c.name, d;
12068
12174
  try {
12069
12175
  d = o.execute(i);
@@ -12078,11 +12184,11 @@ async function Bl(t) {
12078
12184
  logFilePath: ""
12079
12185
  };
12080
12186
  }
12081
- _l.add(d);
12187
+ bl.add(d);
12082
12188
  let f = !1, p = setInterval(async () => {
12083
12189
  await s.isCancelled(r) && (console.log(`[${n}] 🛑 Job #${r} was cancelled! Halting execution.`), f = !0, clearInterval(p), await d.cancel());
12084
12190
  }, 3e3), m = await d.done;
12085
- if (clearInterval(p), _l.delete(d), d.logFilePath && e.existsSync(d.logFilePath)) try {
12191
+ if (clearInterval(p), bl.delete(d), d.logFilePath && e.existsSync(d.logFilePath)) try {
12086
12192
  let e = await o.readLog(d.logFilePath);
12087
12193
  await s.saveStepLog(r, l, e);
12088
12194
  } catch (e) {
@@ -12109,7 +12215,7 @@ async function Bl(t) {
12109
12215
  }
12110
12216
  };
12111
12217
  }
12112
- function Vl(e, t, n) {
12218
+ function Wl(e, t, n) {
12113
12219
  for (let r = t; r < e.length; r++) {
12114
12220
  let t = e[r], i = t.id || `step-${r}`;
12115
12221
  n[r] = {
@@ -12123,7 +12229,7 @@ function Vl(e, t, n) {
12123
12229
  };
12124
12230
  }
12125
12231
  }
12126
- function Hl(e, t, n, r, i, a, o) {
12232
+ function Gl(e, t, n, r, i, a, o) {
12127
12233
  return {
12128
12234
  jobId: String(e.id),
12129
12235
  parentId: String(e.parentId || ""),
@@ -12144,7 +12250,7 @@ function Hl(e, t, n, r, i, a, o) {
12144
12250
  }
12145
12251
  //#endregion
12146
12252
  //#region src/scheduler.ts
12147
- function Ul(e, t, n, r) {
12253
+ function Kl(e, t, n, r) {
12148
12254
  return e.split(",").some((e) => {
12149
12255
  let [i, a] = e.split("/"), o = a ? Number(a) : 1;
12150
12256
  if (!Number.isInteger(o) || o < 1) return !1;
@@ -12152,7 +12258,7 @@ function Ul(e, t, n, r) {
12152
12258
  return Number.isInteger(l) && Number.isInteger(u) && t >= l && t <= u && (t - l) % o === 0;
12153
12259
  });
12154
12260
  }
12155
- function Wl(e, t, n = "UTC") {
12261
+ function ql(e, t, n = "UTC") {
12156
12262
  let r = e.trim().split(/\s+/);
12157
12263
  if (r.length !== 5) return !1;
12158
12264
  let i = new Intl.DateTimeFormat("en-US", {
@@ -12174,16 +12280,16 @@ function Wl(e, t, n = "UTC") {
12174
12280
  "Thu",
12175
12281
  "Fri",
12176
12282
  "Sat"
12177
- ].indexOf(i.weekday), o = Ul(r[2], Number(i.day), 1, 31), s = Ul(r[4].replace(/7/g, "0"), a, 0, 6);
12178
- return Ul(r[0], Number(i.minute), 0, 59) && Ul(r[1], Number(i.hour), 0, 23) && Ul(r[3], Number(i.month), 1, 12) && (r[2] === "*" || r[4] === "*" ? o && s : o || s);
12283
+ ].indexOf(i.weekday), o = Kl(r[2], Number(i.day), 1, 31), s = Kl(r[4].replace(/7/g, "0"), a, 0, 6);
12284
+ return Kl(r[0], Number(i.minute), 0, 59) && Kl(r[1], Number(i.hour), 0, 23) && Kl(r[3], Number(i.month), 1, 12) && (r[2] === "*" || r[4] === "*" ? o && s : o || s);
12179
12285
  }
12180
- function Gl(e) {
12286
+ function Jl(e) {
12181
12287
  if (!e) return 0;
12182
12288
  let t = e.match(/^([+-]?)(\d+)(m|h)$/);
12183
12289
  if (!t) throw Error(`Invalid solar offset: ${e}`);
12184
12290
  return (t[1] === "-" ? -1 : 1) * Number(t[2]) * (t[3] === "h" ? 36e5 : 6e4);
12185
12291
  }
12186
- function Kl(e, t) {
12292
+ function Yl(e, t) {
12187
12293
  let n = t.latitude, r = t.longitude, i = Date.UTC(e.getUTCFullYear(), e.getUTCMonth(), e.getUTCDate()), a = Math.floor((i - Date.UTC(e.getUTCFullYear(), 0, 0)) / 864e5), o = r / 15, s = a + ((t.event === "sunrise" ? 6 : 18) - o) / 24, c = .9856 * s - 3.289, l = c + 1.916 * Math.sin(c * Math.PI / 180) + .02 * Math.sin(2 * c * Math.PI / 180) + 282.634;
12188
12294
  l = (l + 360) % 360;
12189
12295
  let u = Math.atan(.91764 * Math.tan(l * Math.PI / 180)) * 180 / Math.PI;
@@ -12191,9 +12297,9 @@ function Kl(e, t) {
12191
12297
  let d = .39782 * Math.sin(l * Math.PI / 180), f = Math.cos(Math.asin(d)), p = (Math.cos(90.833 * Math.PI / 180) - d * Math.sin(n * Math.PI / 180)) / (f * Math.cos(n * Math.PI / 180));
12192
12298
  if (p > 1 || p < -1) return null;
12193
12299
  let m = (t.event === "sunrise" ? 360 - Math.acos(p) * 180 / Math.PI : Math.acos(p) * 180 / Math.PI) / 15;
12194
- return m = (m + u - .06571 * s - 6.622 - o + 24) % 24, new Date(i + m * 36e5 + Gl(t.offset));
12300
+ return m = (m + u - .06571 * s - 6.622 - o + 24) % 24, new Date(i + m * 36e5 + Jl(t.offset));
12195
12301
  }
12196
- var ql = class {
12302
+ var Xl = class {
12197
12303
  queue;
12198
12304
  workflows;
12199
12305
  config;
@@ -12210,9 +12316,9 @@ var ql = class {
12210
12316
  async tick(e = /* @__PURE__ */ new Date()) {
12211
12317
  let t = /* @__PURE__ */ new Date(Math.floor(e.getTime() / 6e4) * 6e4);
12212
12318
  for (let { definition: e, revision: n } of await this.workflows.published()) {
12213
- for (let [r, i] of (e.schedule || []).entries()) Wl(i.cron, t, i.timezone || "UTC") && await this.enqueue(e, n, i, `cron-${r}`, t);
12319
+ for (let [r, i] of (e.schedule || []).entries()) ql(i.cron, t, i.timezone || "UTC") && await this.enqueue(e, n, i, `cron-${r}`, t);
12214
12320
  for (let [r, i] of (e.solar || []).entries()) {
12215
- let a = Kl(t, i);
12321
+ let a = Yl(t, i);
12216
12322
  a && Math.floor(a.getTime() / 6e4) === t.getTime() / 6e4 && await this.enqueue(e, n, i, `solar-${r}`, t);
12217
12323
  }
12218
12324
  }
@@ -12238,7 +12344,7 @@ var ql = class {
12238
12344
  };
12239
12345
  //#endregion
12240
12346
  //#region src/logger.ts
12241
- function Jl() {
12347
+ function Zl() {
12242
12348
  for (let e of [
12243
12349
  "log",
12244
12350
  "info",
@@ -12253,14 +12359,14 @@ function Jl() {
12253
12359
  }
12254
12360
  //#endregion
12255
12361
  //#region src/index.ts
12256
- async function Yl() {
12257
- Jl();
12362
+ async function Ql() {
12363
+ Zl();
12258
12364
  let { config: e, command: t } = await ce();
12259
12365
  e || process.exit(1);
12260
12366
  let n = new me(), r = new pe(process.env.WORKER_NAME || "cli");
12261
12367
  switch (t) {
12262
12368
  case "start-server":
12263
- console.log("🌐 Starting Ingress Gateway..."), await r.init(), await al.withPort({
12369
+ console.log("🌐 Starting Ingress Gateway..."), await r.init(), await cl.withPort({
12264
12370
  config: e,
12265
12371
  queue: r,
12266
12372
  secrets: n,
@@ -12269,13 +12375,13 @@ async function Yl() {
12269
12375
  });
12270
12376
  break;
12271
12377
  case "start-workers":
12272
- console.log(`⚙️ Starting worker scheduler with ${e.workers} concurrent slot(s)...`), await r.init(), xl(e.workers, r, n, e);
12378
+ console.log(`⚙️ Starting worker scheduler with ${e.workers} concurrent slot(s)...`), await r.init(), wl(e.workers, r, n, e);
12273
12379
  break;
12274
12380
  case "start-scheduler": {
12275
12381
  console.log("Starting workflow scheduler..."), await r.init();
12276
- let t = new nl();
12382
+ let t = new al();
12277
12383
  await t.init();
12278
- let n = new ql(r, t, e);
12384
+ let n = new Xl(r, t, e);
12279
12385
  n.start();
12280
12386
  let i = () => {
12281
12387
  n.stop(), process.exit(0);
@@ -12286,6 +12392,6 @@ async function Yl() {
12286
12392
  default: console.error(`❌ Unknown command: '${t}'`), se(), process.exit(1);
12287
12393
  }
12288
12394
  }
12289
- Yl().catch(console.error);
12395
+ Ql().catch(console.error);
12290
12396
  //#endregion
12291
- export { fl as GitHubStatusPlugin, hl as createWorkflowPlugin, ml as registerWorkflowPlugin };
12397
+ export { hl as GitHubStatusPlugin, vl as createWorkflowPlugin, _l as registerWorkflowPlugin };