@cloud-cli/on 1.9.0 โ†’ 1.9.1

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/README.md CHANGED
@@ -179,7 +179,7 @@ You can customize engine behavior using `runner.config.mjs` in your project root
179
179
 
180
180
  ```javascript
181
181
  // runner.config.mjs
182
- import { HtmlReporter, SlackReporter, JsonFileReporter } from '@cloud-cli/on/reporters';
182
+ import { GitHubStatusPlugin } from '@cloud-cli/on';
183
183
 
184
184
  export default {
185
185
  port: 3000,
@@ -195,18 +195,19 @@ export default {
195
195
  NODE_ENV: 'production',
196
196
  },
197
197
 
198
- // Custom execution reporters
199
- reporters: [
200
- new JsonFileReporter({ outputDir: './reports/json' }),
201
- new HtmlReporter({ outputDir: './reports/html' }),
202
- new SlackReporter({
203
- webhookUrl: process.env.SLACK_WEBHOOK_URL,
204
- channel: '#ci-deployments',
198
+ plugins: [
199
+ new GitHubStatusPlugin({
200
+ token: process.env.SECRET_GITHUB_TOKEN,
201
+ context: 'on',
205
202
  }),
206
203
  ],
207
204
  };
208
205
  ```
209
206
 
207
+ The GitHub status plugin publishes commit states when a workflow starts and finishes. Its token needs permission to write commit statuses for the target repository.
208
+
209
+ Run details are available as HTML at `/runs/:id` and as sanitized JSON at `/api/runs/:id`. The HTML view refreshes reactively through job-specific SSE events while a run is active. Both representations omit raw webhook bodies, sensitive input fields, execution environment values, and internal rerun state.
210
+
210
211
  ---
211
212
 
212
213
  ## ๐Ÿ“ Deterministic Evaluation Rules
package/dist/index.d.ts CHANGED
@@ -1,5 +1,3 @@
1
1
  #!/usr/bin/env node
2
- export { HtmlReporter } from './reporters/html.reporter.js';
3
- export { JsonFileReporter } from './reporters/json-file.reporter.js';
4
- export { SlackReporter } from './reporters/slack.reporter.js';
2
+ export { GitHubStatusPlugin } from './plugins/github-status.plugin.js';
5
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAYA,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAYA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC"}
package/dist/on.js CHANGED
@@ -74,7 +74,7 @@ function ue(e, t) {
74
74
  tags: i.map((e) => e.trim()).filter(Boolean),
75
75
  storagePath: e.storagePath ?? n.RUNNER_TMP ?? "/tmp/workspaces",
76
76
  env: e.env ?? {},
77
- reporters: e.reporters ?? []
77
+ plugins: e.plugins ?? []
78
78
  };
79
79
  }
80
80
  function de() {
@@ -7954,7 +7954,7 @@ var Mo = class {
7954
7954
  owner: c,
7955
7955
  repo: l,
7956
7956
  clone_url: n.repository?.clone_url,
7957
- commit_sha: n.after || n.head_commit?.id,
7957
+ commit_sha: n.after || n.head_commit?.id || n.pull_request?.head?.sha,
7958
7958
  author: n.pusher?.name || n.sender?.login,
7959
7959
  action: n.action,
7960
7960
  raw: n,
@@ -7982,29 +7982,7 @@ var Mo = class {
7982
7982
  inputs: e
7983
7983
  };
7984
7984
  }
7985
- };
7986
- //#endregion
7987
- //#region src/html-state.ts
7988
- function No(e) {
7989
- return JSON.stringify(e).replace(/[<>&\u2028\u2029]/g, (e) => `\\u${e.charCodeAt(0).toString(16).padStart(4, "0")}`);
7990
- }
7991
- //#endregion
7992
- //#region src/reporters/html.reporter.html?raw
7993
- var Po = "<!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 <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</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 <header class=\"flex flex-col md:flex-row md:items-center justify-between border-b border-gray-800 pb-6 gap-4\">\n <div class=\"min-w-0\">\n <a href=\"/runs\" class=\"text-xs text-indigo-400 hover:underline mb-1 inline-block\">Back to Dashboard</a>\n <h1 class=\"text-2xl font-bold text-white flex flex-wrap items-center gap-3\">\n {{ report.workflowName }}\n <span class=\"text-sm font-mono text-gray-500\">#{{ report.jobId }}</span>\n <template if=\"report.parentId\">\n <a attr-href=\"'/runs/' + report.parentId\" class=\"text-sm font-mono text-indigo-400 hover:underline\">\n from #{{ report.parentId }}\n </a>\n </template>\n </h1>\n <p class=\"text-xs text-gray-400 mt-1\">Started {{ report.startedAt }} ยท {{ timing }}</p>\n </div>\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 <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 </div>\n </header>\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 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 <div class=\"flex flex-wrap items-center gap-3 min-w-0\">\n <span class=\"font-mono text-gray-500\">\n #{{ index + 1 }}<template if=\"step.exitCode !== undefined && step.exitCode !== 0\"> ({{ step.exitCode }})</template>\n </span>\n <h3 class=\"font-semibold text-gray-200 break-words\">{{ step.name }}</h3>\n <span\n class=\"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 <div class=\"font-mono text-gray-400 shrink-0\">{{ step.durationMs }}ms</div>\n </summary>\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 </details>\n </template>\n </section>\n\n <details class=\"bg-gray-900 border border-gray-800 rounded-xl p-4 overflow-auto max-h-[400px]\">\n <summary class=\"cursor-pointer\">\n <h2 class=\"inline text-xs font-semibold text-gray-400 uppercase tracking-wider\">Trigger Inputs</h2>\n </summary>\n <pre class=\"font-mono text-xs text-gray-200 bg-gray-950 p-3 mt-3 rounded-lg overflow-x-auto\">{{ inputsJson }}</pre>\n </details>\n </div>\n\n <script setup>\n import { computed, onInit, ref } from '@li3/web';\n import { AnsiUp } from 'ansi_up';\n\n export default function setup() {\n const report = ref({});\n const ansiUp = new AnsiUp();\n ansiUp.use_classes = 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') return `Running for ${report.value.durationMs}ms`;\n return `Finished in ${report.value.durationMs}ms`;\n });\n\n const upper = (value) => String(value || '').toUpperCase();\n const stepLog = (step) => {\n if (step.status === 'skipped') return '';\n if (step.status === 'running') 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\n onInit(() => {\n document.title = `Run #${report.value.jobId} - ${report.value.workflowName}`;\n if (active.value) setTimeout(() => location.reload(), 3000);\n });\n\n return { report, inputsJson, timing, upper, stepLog, restartJob };\n }\n <\/script>\n <script state>__REPORT_STATE__<\/script>\n </template>\n\n <script type=\"module\">import '@li3/web';<\/script>\n <script src=\"https://cdn.tailwindcss.com\"><\/script>\n</body>\n</html>\n", Fo = "__REPORT_STATE__", Io = class {
7994
- name = "html";
7995
- outputDir;
7996
- constructor(e) {
7997
- this.outputDir = e.outputDir;
7998
- }
7999
- async report(t) {
8000
- e.mkdirSync(this.outputDir, { recursive: !0 });
8001
- let n = this.generateHtml(t), r = a.join(this.outputDir, `run-${t.jobId}.html`);
8002
- e.writeFileSync(r, n, "utf-8"), console.log(`๐Ÿ“Š HTML Execution Report generated: ${r}`);
8003
- }
8004
- generateHtml(e) {
8005
- return Po.replace(Fo, () => No({ report: e }));
8006
- }
8007
- }, Lo = class e {
7985
+ }, No = class e {
8008
7986
  static async from(t) {
8009
7987
  let n = o(t) ? c("/", t) : s(process.cwd(), c("/", t)), r = (await _(n, { withFileTypes: !0 })).filter((e) => e.isFile() && (e.name.endsWith(".yml") || e.name.endsWith(".yaml"))).map((e) => s(n, e.name)), i = [], a = new di(t);
8010
7988
  for (let t of r) i.push(...await e.loadFile(t, a));
@@ -8038,10 +8016,15 @@ var Po = "<!DOCTYPE html>\n<html lang=\"en\" class=\"dark\">\n<head>\n <meta ch
8038
8016
  }
8039
8017
  return n;
8040
8018
  }
8041
- }, Ro = "<!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 <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 <header class=\"flex flex-col sm:flex-row sm:items-center justify-between gap-3 border-b border-gray-800 pb-4\">\n <div>\n <h1 class=\"text-2xl font-bold text-white\">Runner Engine Status</h1>\n <p class=\"text-xs text-gray-400\">Live Job Queue &amp; Execution Traces</p>\n </div>\n <div class=\"flex items-center gap-3 text-xs font-mono\">\n <span class=\"text-gray-500\">Updated {{ lastUpdated }}</span>\n <span\n class=\"px-3 py-1 rounded-full border\"\n bind-class=\"{\n 'bg-emerald-500/10.text-emerald-400.border-emerald-500/20': !refreshError,\n 'bg-rose-500/10.text-rose-400.border-rose-500/20': refreshError\n }\"\n >\n {{ refreshError ? 'Refresh failed' : 'System operational' }}\n </span>\n </div>\n </header>\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=\"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',\n 'bg-gray-500/10.text-gray-400': !['success', 'failed', 'running'].includes(job.status)\n }\"\n >\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\">{{ job.workerId || '-' }}</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 attr-href=\"'/runs/' + job.id\" class=\"text-xs bg-gray-800 hover:bg-gray-700 text-gray-200 px-3 py-1 rounded border border-gray-700\">View Trace</a>\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\">No jobs recorded yet.</div>\n </template>\n </section>\n\n <section class=\"md:hidden bg-gray-900 border border-gray-800 rounded-xl divide-y divide-gray-800 overflow-hidden\">\n <template for=\"job of jobs\">\n <article class=\"p-4 bg-gray-900/60\">\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 <span\n class=\"w-2.5 h-2.5 rounded-full shrink-0\"\n bind-class=\"{\n 'bg-emerald-400': job.status === 'success',\n 'bg-rose-400': job.status === 'failed',\n 'bg-indigo-400.animate-pulse': job.status === 'running',\n 'bg-gray-500': !['success', 'failed', 'running'].includes(job.status)\n }\"\n ></span>\n <h2 class=\"font-medium text-white truncate\">{{ job.workflowId }}</h2>\n </div>\n <p class=\"mt-1 pl-[18px] text-xs font-mono text-gray-400\">#{{ job.id }} ยท {{ upper(job.status) }}</p>\n </div>\n <a attr-href=\"'/runs/' + job.id\" class=\"shrink-0 text-xs bg-gray-800 hover:bg-gray-700 text-gray-300 px-2.5 py-1 rounded border border-gray-700\">Trace</a>\n </div>\n </article>\n </template>\n <template if=\"!jobs.length\">\n <div class=\"p-8 text-center text-gray-500\">No jobs recorded yet.</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 lastUpdated = ref('now');\n const refreshError = ref(false);\n const hasMore = ref(false);\n const loadingMore = ref(false);\n let refreshTimer;\n let eventSource;\n let refreshing = false;\n let refreshPending = false;\n\n const upper = (value) => String(value || '').toUpperCase();\n const terminalStatuses = new Set(['success', 'failed', 'cancelled']);\n const refreshJobs = async () => {\n if (refreshing) {\n refreshPending = true;\n return;\n }\n refreshing = true;\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 url = afterId === null ? '/api/jobs?limit=500' : `/api/jobs?afterId=${afterId}&limit=500`;\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 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 lastUpdated.value = new Date().toLocaleTimeString();\n refreshError.value = false;\n } catch (error) {\n console.error(error);\n refreshError.value = true;\n } finally {\n refreshing = false;\n if (refreshPending) {\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 response = await fetch(`/api/jobs?beforeId=${beforeId}`, {\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\n onInit(() => {\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 refreshTimer = setInterval(refreshJobs, 60000);\n });\n onDestroy(() => {\n eventSource?.close();\n clearInterval(refreshTimer);\n });\n\n return { jobs, lastUpdated, refreshError, hasMore, loadingMore, loadMore, upper };\n }\n <\/script>\n <script state>__DASHBOARD_STATE__<\/script>\n </template>\n\n <script type=\"module\">import '@li3/web';<\/script>\n <script src=\"https://cdn.tailwindcss.com\"><\/script>\n</body>\n</html>\n";
8019
+ }, Po = "<!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 <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 <header class=\"flex flex-col sm:flex-row sm:items-center justify-between gap-3 border-b border-gray-800 pb-4\">\n <div>\n <h1 class=\"text-2xl font-bold text-white\">Runner Engine Status</h1>\n <p class=\"text-xs text-gray-400\">Live Job Queue &amp; Execution Traces</p>\n </div>\n <div class=\"flex items-center gap-3 text-xs font-mono\">\n <span class=\"text-gray-500\">Updated {{ lastUpdated }}</span>\n <span\n class=\"px-3 py-1 rounded-full border\"\n bind-class=\"{\n 'bg-emerald-500/10.text-emerald-400.border-emerald-500/20': !refreshError,\n 'bg-rose-500/10.text-rose-400.border-rose-500/20': refreshError\n }\"\n >\n {{ refreshError ? 'Refresh failed' : 'System operational' }}\n </span>\n </div>\n </header>\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=\"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',\n 'bg-gray-500/10.text-gray-400': !['success', 'failed', 'running'].includes(job.status)\n }\"\n >\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\">{{ job.workerId || '-' }}</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 attr-href=\"'/runs/' + job.id\" class=\"text-xs bg-gray-800 hover:bg-gray-700 text-gray-200 px-3 py-1 rounded border border-gray-700\">View Trace</a>\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\">No jobs recorded yet.</div>\n </template>\n </section>\n\n <section class=\"md:hidden bg-gray-900 border border-gray-800 rounded-xl divide-y divide-gray-800 overflow-hidden\">\n <template for=\"job of jobs\">\n <article class=\"p-4 bg-gray-900/60\">\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 <span\n class=\"w-2.5 h-2.5 rounded-full shrink-0\"\n bind-class=\"{\n 'bg-emerald-400': job.status === 'success',\n 'bg-rose-400': job.status === 'failed',\n 'bg-indigo-400.animate-pulse': job.status === 'running',\n 'bg-gray-500': !['success', 'failed', 'running'].includes(job.status)\n }\"\n ></span>\n <h2 class=\"font-medium text-white truncate\">{{ job.workflowId }}</h2>\n </div>\n <p class=\"mt-1 pl-[18px] text-xs font-mono text-gray-400\">#{{ job.id }} ยท {{ upper(job.status) }}</p>\n </div>\n <a attr-href=\"'/runs/' + job.id\" class=\"shrink-0 text-xs bg-gray-800 hover:bg-gray-700 text-gray-300 px-2.5 py-1 rounded border border-gray-700\">Trace</a>\n </div>\n </article>\n </template>\n <template if=\"!jobs.length\">\n <div class=\"p-8 text-center text-gray-500\">No jobs recorded yet.</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 lastUpdated = ref('now');\n const refreshError = ref(false);\n const hasMore = ref(false);\n const loadingMore = ref(false);\n let refreshTimer;\n let eventSource;\n let refreshing = false;\n let refreshPending = false;\n\n const upper = (value) => String(value || '').toUpperCase();\n const terminalStatuses = new Set(['success', 'failed', 'cancelled']);\n const refreshJobs = async () => {\n if (refreshing) {\n refreshPending = true;\n return;\n }\n refreshing = true;\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 url = afterId === null ? '/api/jobs?limit=500' : `/api/jobs?afterId=${afterId}&limit=500`;\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 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 lastUpdated.value = new Date().toLocaleTimeString();\n refreshError.value = false;\n } catch (error) {\n console.error(error);\n refreshError.value = true;\n } finally {\n refreshing = false;\n if (refreshPending) {\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 response = await fetch(`/api/jobs?beforeId=${beforeId}`, {\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\n onInit(() => {\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 refreshTimer = setInterval(refreshJobs, 60000);\n });\n onDestroy(() => {\n eventSource?.close();\n clearInterval(refreshTimer);\n });\n\n return { jobs, lastUpdated, refreshError, hasMore, loadingMore, loadMore, upper };\n }\n <\/script>\n <script state>__DASHBOARD_STATE__<\/script>\n </template>\n\n <script type=\"module\">import '@li3/web';<\/script>\n <script src=\"https://cdn.tailwindcss.com\"><\/script>\n</body>\n</html>\n";
8020
+ //#endregion
8021
+ //#region src/html-state.ts
8022
+ function Fo(e) {
8023
+ return JSON.stringify(e).replace(/[<>&\u2028\u2029]/g, (e) => `\\u${e.charCodeAt(0).toString(16).padStart(4, "0")}`);
8024
+ }
8042
8025
  //#endregion
8043
8026
  //#region src/dashboard.ts
8044
- function zo(e) {
8027
+ function Io(e) {
8045
8028
  return e.map((e) => ({
8046
8029
  id: e.id,
8047
8030
  workflowId: e.workflow_id,
@@ -8051,15 +8034,15 @@ function zo(e) {
8051
8034
  updatedAt: e.updated_at
8052
8035
  }));
8053
8036
  }
8054
- function Bo(e, t = !1) {
8055
- return Ro.replace("__DASHBOARD_STATE__", () => No({
8037
+ function Lo(e, t = !1) {
8038
+ return Po.replace("__DASHBOARD_STATE__", () => Fo({
8056
8039
  jobs: e,
8057
8040
  hasMore: t
8058
8041
  }));
8059
8042
  }
8060
8043
  //#endregion
8061
8044
  //#region src/events.ts
8062
- var Vo = class {
8045
+ var Ro = class {
8063
8046
  clients = /* @__PURE__ */ new Map();
8064
8047
  nextId = 1;
8065
8048
  maxClients = 1e3;
@@ -8091,7 +8074,7 @@ var Vo = class {
8091
8074
  this.clients.clear();
8092
8075
  }
8093
8076
  };
8094
- async function Ho(e, t, n, r) {
8077
+ async function zo(e, t, n, r) {
8095
8078
  let i = await fetch(new URL("/api/events", e), {
8096
8079
  headers: { Accept: "text/event-stream" },
8097
8080
  signal: t
@@ -8113,22 +8096,83 @@ async function Ho(e, t, n, r) {
8113
8096
  }
8114
8097
  }
8115
8098
  //#endregion
8099
+ //#region src/run.html?raw
8100
+ var Bo = "<!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 <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</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 <header class=\"flex flex-col md:flex-row md:items-center justify-between border-b border-gray-800 pb-6 gap-4\">\n <div class=\"min-w-0\">\n <a href=\"/runs\" class=\"text-xs text-indigo-400 hover:underline mb-1 inline-block\">Back to Dashboard</a>\n <h1 class=\"text-2xl font-bold text-white flex flex-wrap items-center gap-3\">\n {{ report.workflowName }}\n <span class=\"text-sm font-mono text-gray-500\">#{{ report.jobId }}</span>\n <template if=\"report.parentId\">\n <a attr-href=\"'/runs/' + report.parentId\" class=\"text-sm font-mono text-indigo-400 hover:underline\">\n from #{{ report.parentId }}\n </a>\n </template>\n </h1>\n <p class=\"text-xs text-gray-400 mt-1\">Started {{ report.startedAt }} ยท {{ timing }}</p>\n </div>\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 <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 </div>\n </header>\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 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 <div class=\"flex flex-wrap items-center gap-3 min-w-0\">\n <span class=\"font-mono text-gray-500\">\n #{{ index + 1 }}<template if=\"step.exitCode !== undefined && step.exitCode !== 0\"> ({{ step.exitCode }})</template>\n </span>\n <h3 class=\"font-semibold text-gray-200 break-words\">{{ step.name }}</h3>\n <span\n class=\"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 <div class=\"font-mono text-gray-400 shrink-0\">{{ step.durationMs }}ms</div>\n </summary>\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 </details>\n </template>\n </section>\n\n <details class=\"bg-gray-900 border border-gray-800 rounded-xl p-4 overflow-auto max-h-[400px]\">\n <summary class=\"cursor-pointer\">\n <h2 class=\"inline text-xs font-semibold text-gray-400 uppercase tracking-wider\">Trigger Inputs</h2>\n </summary>\n <pre class=\"font-mono text-xs text-gray-200 bg-gray-950 p-3 mt-3 rounded-lg overflow-x-auto\">{{ inputsJson }}</pre>\n </details>\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 report = ref({});\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\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 stepLog = (step) => {\n if (step.status === 'skipped') return '';\n if (step.status === 'running') 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 refreshRun = async () => {\n if (refreshing) {\n refreshPending = true;\n return;\n }\n refreshing = true;\n\n try {\n const response = await fetch(`/api/runs/${report.value.jobId}`, {\n headers: { accept: 'application/json' },\n });\n if (!response.ok) throw new Error(`Run refresh failed: ${response.status}`);\n report.value = await response.json();\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 document.title = `Run #${report.value.jobId} - ${report.value.workflowName}`;\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, inputsJson, timing, upper, stepLog, restartJob };\n }\n <\/script>\n <script state>__REPORT_STATE__<\/script>\n </template>\n\n <script type=\"module\">import '@li3/web';<\/script>\n <script src=\"https://cdn.tailwindcss.com\"><\/script>\n</body>\n</html>\n", Vo = /(?:^|[_-])auth(?:entication)?(?:$|[_-])|access[_-]?key|api[_-]?key|authorization|cookie|credential|passphrase|password|private[_-]?key|secret|session(?:id)?|signing[_-]?key|token/i;
8101
+ function Ho(e, t, n) {
8102
+ let r = JSON.parse(e.payload), i = e.report ? JSON.parse(e.report) : Wo(e, r), a = e.status;
8103
+ return {
8104
+ jobId: String(e.id),
8105
+ parentId: String(i.parentId || e.parentId || ""),
8106
+ workflowName: n(i.workflowName),
8107
+ status: a,
8108
+ durationMs: a === "running" ? Math.max(0, Date.now() - Date.parse(i.startedAt)) : i.durationMs,
8109
+ startedAt: i.startedAt,
8110
+ finishedAt: i.finishedAt,
8111
+ inputs: Go(i.inputs || {}, n),
8112
+ steps: (i.steps || []).map((e) => {
8113
+ let r = Object.hasOwn(t, e.id) && typeof t[e.id] == "string" ? t[e.id] : "";
8114
+ return {
8115
+ id: e.id,
8116
+ name: n(e.name),
8117
+ status: e.status,
8118
+ durationMs: e.durationMs,
8119
+ exitCode: e.exitCode,
8120
+ startedAt: e.startedAt,
8121
+ finishedAt: e.finishedAt,
8122
+ error: e.error ? n(e.error) : void 0,
8123
+ outputs: Go(e.outputs || {}, n),
8124
+ logContent: e.status === "running" || e.status === "pending" ? "" : n(r || e.logContent || "")
8125
+ };
8126
+ }),
8127
+ artifacts: (i.artifacts || []).map(n)
8128
+ };
8129
+ }
8130
+ function Uo(e) {
8131
+ return Bo.replace("__REPORT_STATE__", () => Fo({ report: e }));
8132
+ }
8133
+ function Wo(e, t) {
8134
+ let n = e.started_at || e.created_at;
8135
+ return {
8136
+ jobId: String(e.id),
8137
+ parentId: String(e.parentId || ""),
8138
+ workflowName: e.workflow_id,
8139
+ status: e.status,
8140
+ durationMs: e.status === "running" ? Math.max(0, Date.now() - Date.parse(n)) : 0,
8141
+ startedAt: n,
8142
+ inputs: t.inputs || {},
8143
+ environment: {},
8144
+ steps: (t.steps || []).map((e, t) => ({
8145
+ id: e.id || `step-${t}`,
8146
+ name: e.name || e.id || `step-${t}`,
8147
+ status: "pending",
8148
+ durationMs: 0,
8149
+ outputs: {},
8150
+ logContent: ""
8151
+ })),
8152
+ artifacts: [],
8153
+ rerunToken: ""
8154
+ };
8155
+ }
8156
+ function Go(e, t) {
8157
+ return typeof e == "string" ? t(e) : Array.isArray(e) ? e.map((e) => Go(e, t)) : !e || typeof e != "object" ? e : Object.fromEntries(Object.entries(e).filter(([e]) => e.toLowerCase() !== "raw" && !Vo.test(e)).map(([e, n]) => [e, Go(n, t)]));
8158
+ }
8159
+ //#endregion
8116
8160
  //#region src/server.ts
8117
- var Uo = 50, Wo = 500, Go = class e {
8161
+ var Ko = 50, qo = 500, Jo = class e {
8118
8162
  server;
8119
8163
  preprocessors = /* @__PURE__ */ new Map();
8120
8164
  workflows = [];
8121
8165
  queue;
8122
8166
  secrets;
8123
8167
  adminToken;
8124
- events = new Vo();
8168
+ events = new Ro();
8125
8169
  workflowsLoaded;
8126
8170
  static async withPort(t) {
8127
8171
  let { port: n, ...r } = t;
8128
8172
  return new e(r).listen(n);
8129
8173
  }
8130
8174
  constructor(e) {
8131
- this.queue = e.queue, this.secrets = e.secrets, this.adminToken = e.adminToken, this.workflowsLoaded = Lo.from(e.config.workflows).then((t) => {
8175
+ this.queue = e.queue, this.secrets = e.secrets, this.adminToken = e.adminToken, this.workflowsLoaded = No.from(e.config.workflows).then((t) => {
8132
8176
  this.workflows = t, console.log(`โœ… Loaded ${t.length} workflow(s) from ${e.config.workflows}`);
8133
8177
  }), this.registerPreprocessor(new Mo()), this.server = f.createServer((e, t) => this.handleRequest(e, t));
8134
8178
  }
@@ -8139,14 +8183,18 @@ var Uo = 50, Wo = 500, Go = class e {
8139
8183
  let n = new p(e.url || "/", `${e.headers["x-forwarded-proto"] || "http"}://${e.headers["x-forwarded-host"] || e.headers.host}`);
8140
8184
  if (e.method === "GET" && (n.pathname === "/runs" || n.pathname === "/")) return this.renderDashboard(t);
8141
8185
  if (e.method === "GET" && n.pathname === "/api/jobs") {
8142
- let e = n.searchParams.get("afterId"), r = n.searchParams.get("beforeId"), i = n.searchParams.get("limit"), a = e === null ? void 0 : Number(e), o = r === null ? void 0 : Number(r), s = i === null ? Uo : Number(i);
8143
- return a !== void 0 && (!Number.isSafeInteger(a) || a < 0) ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "afterId must be a non-negative integer" }))) : o !== void 0 && (!Number.isSafeInteger(o) || o < 1) ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "beforeId must be a positive integer" }))) : !Number.isSafeInteger(s) || s < 1 || s > Wo ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: `limit must be an integer from 1 to ${Wo}` }))) : this.renderDashboardJobs(t, s, a, o);
8186
+ let e = n.searchParams.get("afterId"), r = n.searchParams.get("beforeId"), i = n.searchParams.get("limit"), a = e === null ? void 0 : Number(e), o = r === null ? void 0 : Number(r), s = i === null ? Ko : Number(i);
8187
+ return a !== void 0 && (!Number.isSafeInteger(a) || a < 0) ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "afterId must be a non-negative integer" }))) : o !== void 0 && (!Number.isSafeInteger(o) || o < 1) ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "beforeId must be a positive integer" }))) : !Number.isSafeInteger(s) || s < 1 || s > qo ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: `limit must be an integer from 1 to ${qo}` }))) : this.renderDashboardJobs(t, s, a, o);
8144
8188
  }
8145
8189
  if (e.method === "GET" && n.pathname === "/api/events") return this.events.subscribe(e, t);
8146
8190
  if (e.method === "POST" && n.pathname === "/api/events") return this.handleWorkerEvent(e, t);
8147
8191
  if (e.method === "GET" && n.pathname.startsWith("/runs/")) {
8148
8192
  let e = n.pathname.replace("/runs/", "");
8149
- return this.renderRunDetails(e, t);
8193
+ return this.renderRunDetails(e, t, "html");
8194
+ }
8195
+ if (e.method === "GET" && n.pathname.startsWith("/api/runs/")) {
8196
+ let e = n.pathname.replace("/api/runs/", "");
8197
+ return this.renderRunDetails(e, t, "json");
8150
8198
  }
8151
8199
  if (e.method === "POST" && n.pathname.startsWith("/restart/")) {
8152
8200
  let e = n.pathname.replace("/restart/", "");
@@ -8246,14 +8294,23 @@ var Uo = 50, Wo = 500, Go = class e {
8246
8294
  }
8247
8295
  async handleWorkerEvent(e, t) {
8248
8296
  if (!this.adminToken || e.headers.authorization !== `Bearer ${this.adminToken}`) return t.writeHead(403, { "Content-Type": "application/json" }), t.end(JSON.stringify({ error: "Unauthorized" }));
8249
- this.events.publish("jobs.changed"), t.writeHead(202).end();
8297
+ let { rawBuffer: n } = await this.readRequest(e, t);
8298
+ if (!n || t.headersSent) return;
8299
+ let r;
8300
+ try {
8301
+ let e = n.length ? JSON.parse(n.toString("utf8")) : {}, t = Number(e.jobId);
8302
+ Number.isSafeInteger(t) && t > 0 && (r = t);
8303
+ } catch {
8304
+ return t.writeHead(400, { "Content-Type": "application/json" }), t.end(JSON.stringify({ error: "Invalid event payload" }));
8305
+ }
8306
+ this.events.publish("jobs.changed", r ? { jobId: r } : {}), t.writeHead(202).end();
8250
8307
  }
8251
8308
  async renderDashboard(e) {
8252
- let t = await this.queue.listJobs(51), n = zo(t.slice(0, Uo)), r = this.secrets.redactText(Bo(n, t.length > Uo));
8309
+ let t = await this.queue.listJobs(51), n = Io(t.slice(0, Ko)), r = this.secrets.redactText(Lo(n, t.length > Ko));
8253
8310
  e.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }), e.end(r);
8254
8311
  }
8255
8312
  async renderDashboardJobs(e, t, n, r) {
8256
- let i = await this.queue.listJobs(t + 1, n, r), a = zo(i.slice(0, t)), o = this.secrets.redactText(JSON.stringify({
8313
+ let i = await this.queue.listJobs(t + 1, n, r), a = Io(i.slice(0, t)), o = this.secrets.redactText(JSON.stringify({
8257
8314
  jobs: a,
8258
8315
  hasMore: i.length > t
8259
8316
  }));
@@ -8262,44 +8319,18 @@ var Uo = 50, Wo = 500, Go = class e {
8262
8319
  "Content-Type": "application/json; charset=utf-8"
8263
8320
  }), e.end(o);
8264
8321
  }
8265
- async renderRunDetails(e, t) {
8266
- let n = await this.queue.getJob(e);
8267
- if (!n) return t.writeHead(404, { "Content-Type": "text/html; charset=utf-8" }), t.end("<h1>404 - Report Not Found</h1>");
8268
- let r = n.report ? JSON.parse(n.report) : this.buildPendingReport(n);
8269
- r.status = n.status, r.status === "running" && (r.durationMs = Math.max(0, Date.now() - Date.parse(r.startedAt)));
8270
- let i = await this.queue.getJobLogs(e);
8271
- r.steps = (r.steps || []).map((e) => ({
8272
- ...e,
8273
- logContent: e.status === "running" || e.status === "pending" ? "" : i[e.id] || ""
8274
- }));
8275
- let a = new Io({ outputDir: "" }).generateHtml(r), o = this.secrets.redactText(a);
8276
- t.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }), t.end(o);
8277
- }
8278
- buildPendingReport(e) {
8279
- let t = JSON.parse(e.payload), n = e.started_at || e.created_at;
8280
- return {
8281
- jobId: String(e.id),
8282
- parentId: String(e.parentId || ""),
8283
- workflowName: e.workflow_id,
8284
- status: e.status,
8285
- durationMs: e.status === "running" ? Math.max(0, Date.now() - Date.parse(n)) : 0,
8286
- startedAt: n,
8287
- inputs: t.inputs || {},
8288
- environment: t.env || {},
8289
- steps: (t.steps || []).map((e, t) => ({
8290
- id: e.id || `step-${t}`,
8291
- name: e.name || e.id || `step-${t}`,
8292
- status: "pending",
8293
- durationMs: 0,
8294
- outputs: {},
8295
- logContent: ""
8296
- })),
8297
- artifacts: [],
8298
- rerunToken: JSON.stringify({
8299
- jobId: e.id,
8300
- payload: t
8301
- })
8302
- };
8322
+ async renderRunDetails(e, t, n) {
8323
+ let r = await this.queue.getJob(e);
8324
+ if (!r) {
8325
+ let e = n === "json" ? "application/json; charset=utf-8" : "text/html; charset=utf-8";
8326
+ return t.writeHead(404, { "Content-Type": e }), t.end(n === "json" ? JSON.stringify({ error: "Run not found" }) : "<h1>404 - Run Not Found</h1>");
8327
+ }
8328
+ let i = Ho(r, await this.queue.getJobLogs(e), (e) => this.secrets.redactText(e));
8329
+ if (n === "json") return t.writeHead(200, {
8330
+ "Cache-Control": "no-store",
8331
+ "Content-Type": "application/json; charset=utf-8"
8332
+ }), t.end(JSON.stringify(i));
8333
+ t.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }), t.end(Uo(i));
8303
8334
  }
8304
8335
  async handleRestartJob(e, t) {
8305
8336
  let n = await this.queue.restartJob(e);
@@ -8323,7 +8354,7 @@ var Uo = 50, Wo = 500, Go = class e {
8323
8354
  });
8324
8355
  });
8325
8356
  }
8326
- }, Ko = d(v), qo = class {
8357
+ }, Yo = d(v), Xo = class {
8327
8358
  name = "systemd";
8328
8359
  async isSupported() {
8329
8360
  try {
@@ -8446,7 +8477,7 @@ var Uo = 50, Wo = 500, Go = class e {
8446
8477
  cancel: async () => {
8447
8478
  d = !0;
8448
8479
  try {
8449
- t.image && await Ko(`docker stop -t 2 ${o}`).catch(() => {}), await Ko(`systemctl stop ${o}.service`).catch(() => {});
8480
+ t.image && await Yo(`docker stop -t 2 ${o}`).catch(() => {}), await Yo(`systemctl stop ${o}.service`).catch(() => {});
8450
8481
  } catch {}
8451
8482
  },
8452
8483
  logFilePath: i
@@ -8456,7 +8487,7 @@ var Uo = 50, Wo = 500, Go = class e {
8456
8487
  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;
8457
8488
  return t.slice(n, r);
8458
8489
  }
8459
- }, Jo = class {
8490
+ }, Zo = class {
8460
8491
  name = "standard-process";
8461
8492
  async isSupported() {
8462
8493
  return !0;
@@ -8571,13 +8602,13 @@ var Uo = 50, Wo = 500, Go = class e {
8571
8602
  };
8572
8603
  //#endregion
8573
8604
  //#region src/drivers/index.ts
8574
- async function Yo() {
8575
- let e = new qo();
8576
- return await e.isSupported() ? (console.log("โšก Selected Execution Driver: Systemd (cgroups enabled)"), e) : (console.log("๐Ÿ“ฆ Selected Execution Driver: Standard Process (Fallback)"), new Jo());
8605
+ async function Qo() {
8606
+ let e = new Xo();
8607
+ return await e.isSupported() ? (console.log("โšก Selected Execution Driver: Systemd (cgroups enabled)"), e) : (console.log("๐Ÿ“ฆ Selected Execution Driver: Standard Process (Fallback)"), new Zo());
8577
8608
  }
8578
8609
  //#endregion
8579
8610
  //#region src/signals.ts
8580
- async function Xo(e) {
8611
+ async function $o(e) {
8581
8612
  let t = !1;
8582
8613
  async function n(n) {
8583
8614
  if (!t) {
@@ -8585,7 +8616,7 @@ async function Xo(e) {
8585
8616
  console.error("โš ๏ธ Graceful shutdown timed out after 10s. Forcing exit!"), process.exit(1);
8586
8617
  }, 1e4).unref();
8587
8618
  try {
8588
- ns(), 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);
8619
+ os(), 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);
8589
8620
  } catch (e) {
8590
8621
  console.error("โŒ Error during graceful shutdown:", e.message), process.exit(1);
8591
8622
  }
@@ -8594,35 +8625,57 @@ async function Xo(e) {
8594
8625
  process.on("SIGINT", () => n("SIGINT")), process.on("SIGTERM", () => n("SIGTERM"));
8595
8626
  }
8596
8627
  //#endregion
8597
- //#region src/worker.ts
8598
- var Zo = !!process.env.DEBUG, Qo = { isStopping: !1 }, $o = /* @__PURE__ */ new Set(), es = null, ts = null;
8599
- function ns() {
8600
- Qo.isStopping = !0, es?.abort(), ts?.();
8601
- }
8602
- function rs(e, t, n, r) {
8603
- Qo.isStopping = !1;
8604
- let i = [is(e, t, n, r)];
8605
- return Xo(i), i;
8606
- }
8607
- async function is(e, t, n, r) {
8608
- let i = await Yo(), a = /* @__PURE__ */ new Set(), o = 0, s = null, c = () => {
8628
+ //#region src/plugins/manager.ts
8629
+ var es = class {
8630
+ plugins;
8631
+ constructor(e = []) {
8632
+ this.plugins = e;
8633
+ }
8634
+ register(e) {
8635
+ console.log(`๐Ÿ”Œ Registered Plugin: ${e.name}`), this.plugins.push(e);
8636
+ }
8637
+ async triggerWorkflowStart(e) {
8638
+ for (let t of this.plugins) if (t.onWorkflowStart) try {
8639
+ await t.onWorkflowStart(e);
8640
+ } catch (e) {
8641
+ console.error(`[Plugin Error] ${t.name}.onWorkflowStart:`, e);
8642
+ }
8643
+ }
8644
+ async triggerWorkflowFinish(e, t) {
8645
+ for (let n of this.plugins) if (n.onWorkflowFinish) try {
8646
+ await n.onWorkflowFinish(e, t);
8647
+ } catch (e) {
8648
+ console.error(`[Plugin Error] ${n.name}.onWorkflowFinish:`, e);
8649
+ }
8650
+ }
8651
+ }, ts = !!process.env.DEBUG, ns = { isStopping: !1 }, rs = /* @__PURE__ */ new Set(), is = null, as = null;
8652
+ function os() {
8653
+ ns.isStopping = !0, is?.abort(), as?.();
8654
+ }
8655
+ function ss(e, t, n, r) {
8656
+ ns.isStopping = !1;
8657
+ let i = [cs(e, t, n, r)];
8658
+ return $o(i), i;
8659
+ }
8660
+ async function cs(e, t, n, r) {
8661
+ let i = await Qo(), a = /* @__PURE__ */ new Set(), o = 0, s = null, c = () => {
8609
8662
  o++, s?.();
8610
8663
  };
8611
- ts = c, es = new AbortController();
8612
- let l = as(r, es.signal, c);
8613
- for (console.log(`๐Ÿš€ Worker scheduler started. Driver: ${i.name}. Concurrency: ${e}. Tags: ${r.tags.join(", ") || "(none)"}`); !Qo.isStopping;) {
8664
+ as = c, is = new AbortController();
8665
+ let l = ls(r, is.signal, c);
8666
+ for (console.log(`๐Ÿš€ Worker scheduler started. Driver: ${i.name}. Concurrency: ${e}. Tags: ${r.tags.join(", ") || "(none)"}`); !ns.isStopping;) {
8614
8667
  let l = o;
8615
8668
  try {
8616
- for (; a.size < e && !Qo.isStopping;) {
8669
+ for (; a.size < e && !ns.isStopping;) {
8617
8670
  let e = await t.claimNextJob(r.tags);
8618
8671
  if (!e) break;
8619
- if (Qo.isStopping) {
8672
+ if (ns.isStopping) {
8620
8673
  await t.releaseJob(e.id);
8621
8674
  break;
8622
8675
  }
8623
8676
  let o = `worker-${e.id}`, s;
8624
8677
  s = (async () => {
8625
- cs(r), await ls({
8678
+ fs(r, e.id), await ps({
8626
8679
  workerId: o,
8627
8680
  job: e,
8628
8681
  queue: t,
@@ -8631,31 +8684,31 @@ async function is(e, t, n, r) {
8631
8684
  driver: i
8632
8685
  });
8633
8686
  })().catch((e) => console.error(`[${o}] โš ๏ธ Worker execution error:`, e)).finally(() => {
8634
- a.delete(s), cs(r), c();
8687
+ a.delete(s), fs(r, e.id), c();
8635
8688
  }), a.add(s);
8636
8689
  }
8637
8690
  } catch (e) {
8638
8691
  console.error("โš ๏ธ Worker scheduler claim error:", e), setTimeout(c, 5e3).unref();
8639
8692
  }
8640
- !Qo.isStopping && o === l && (await os(l, () => o, (e) => s = e), s = null);
8693
+ !ns.isStopping && o === l && (await us(l, () => o, (e) => s = e), s = null);
8641
8694
  }
8642
- es.abort(), await Promise.allSettled(a), await l, ts = null, console.log("๐Ÿ›‘ Worker scheduler stopped cleanly.");
8695
+ is.abort(), await Promise.allSettled(a), await l, as = null, console.log("๐Ÿ›‘ Worker scheduler stopped cleanly.");
8643
8696
  }
8644
- async function as(e, t, n) {
8697
+ async function ls(e, t, n) {
8645
8698
  let r = 1e3;
8646
8699
  for (; !t.aborted;) {
8647
8700
  try {
8648
- await Ho(e.serverUrl, t, (t, r) => {
8701
+ await zo(e.serverUrl, t, (t, r) => {
8649
8702
  t === "jobs.available" && (Array.isArray(r.tags) ? r.tags.filter((e) => typeof e == "string") : []).every((t) => e.tags.includes(t)) && n();
8650
8703
  }, n), r = 1e3;
8651
8704
  } catch (e) {
8652
8705
  if (t.aborted || e?.name === "AbortError") break;
8653
8706
  console.error(`โš ๏ธ Worker event stream disconnected: ${e.message}`);
8654
8707
  }
8655
- await ss(r, t), r = Math.min(r * 2, 3e4);
8708
+ await ds(r, t), r = Math.min(r * 2, 3e4);
8656
8709
  }
8657
8710
  }
8658
- function os(e, t, n) {
8711
+ function us(e, t, n) {
8659
8712
  return new Promise((r) => {
8660
8713
  if (t() !== e) return r();
8661
8714
  let i = setTimeout(r, 6e4);
@@ -8664,7 +8717,7 @@ function os(e, t, n) {
8664
8717
  });
8665
8718
  });
8666
8719
  }
8667
- function ss(e, t) {
8720
+ function ds(e, t) {
8668
8721
  return new Promise((n) => {
8669
8722
  if (t.aborted) return n();
8670
8723
  let r = () => {
@@ -8675,19 +8728,23 @@ function ss(e, t) {
8675
8728
  t.addEventListener("abort", r, { once: !0 });
8676
8729
  });
8677
8730
  }
8678
- async function cs(e) {
8731
+ async function fs(e, t) {
8679
8732
  if (e.adminToken) try {
8680
- let t = await fetch(new URL("/api/events", e.serverUrl), {
8733
+ let n = await fetch(new URL("/api/events", e.serverUrl), {
8681
8734
  method: "POST",
8682
- headers: { Authorization: `Bearer ${e.adminToken}` },
8735
+ headers: {
8736
+ Authorization: `Bearer ${e.adminToken}`,
8737
+ "Content-Type": "application/json"
8738
+ },
8739
+ body: JSON.stringify({ jobId: t }),
8683
8740
  signal: AbortSignal.timeout(5e3)
8684
8741
  });
8685
- !t.ok && Zo && console.error(`Failed to publish job status event: HTTP ${t.status}`);
8742
+ !n.ok && ts && console.error(`Failed to publish job status event: HTTP ${n.status}`);
8686
8743
  } catch (e) {
8687
- Zo && console.error("Failed to publish job status event:", e);
8744
+ ts && console.error("Failed to publish job status event:", e);
8688
8745
  }
8689
8746
  }
8690
- async function ls(e) {
8747
+ async function ps(e) {
8691
8748
  let { workerId: t, job: n, config: r, secrets: i, queue: o } = e;
8692
8749
  console.log(`\n[${t}] ๐Ÿ“ฆ Claimed Job #${n.id} (Workflow: ${n.workflow_id})`);
8693
8750
  let s = typeof n.payload == "string" ? JSON.parse(n.payload) : n.payload, c = s.steps || [], l = s.inputs || {}, u = Date.now(), d = a.join(r.storagePath, `job-${n.id}`), f = a.join(d, "logs"), p = a.join(d, "wd"), m = {
@@ -8704,20 +8761,27 @@ async function ls(e) {
8704
8761
  durationMs: 0,
8705
8762
  outputs: {},
8706
8763
  logContent: ""
8707
- })), g = gs(n, "running", u, l, m.env, h, s);
8708
- await o.saveReport(n.id, g);
8709
- let { cancelled: _, failed: v } = await us({
8764
+ })), g = bs(n, "running", u, l, m.env, h, s);
8765
+ await o.saveReport(n.id, g), fs(r, n.id);
8766
+ let _ = new es(r.plugins), v = {
8767
+ jobId: String(n.id),
8768
+ workflowName: n.workflow_id,
8769
+ inputs: l,
8770
+ runUrl: new URL(`/runs/${n.id}`, r.serverUrl).toString()
8771
+ };
8772
+ await _.triggerWorkflowStart(v);
8773
+ let { cancelled: y, failed: ee } = await ms({
8710
8774
  payload: s,
8711
8775
  steps: c,
8712
8776
  executionContext: m,
8713
8777
  ...e
8714
- }, g), y = _ ? "cancelled" : v ? "failed" : "success";
8715
- g.status = y, g.durationMs = Date.now() - u, g.finishedAt = (/* @__PURE__ */ new Date()).toISOString(), await o.completeJob(n.id, y, g), console.log(`[${t}] โœ… Job #${n.id} completed as: ${y}`), await _s(t, r.reporters, g);
8778
+ }, g), b = y ? "cancelled" : ee ? "failed" : "success";
8779
+ g.status = b, g.durationMs = Date.now() - u, g.finishedAt = (/* @__PURE__ */ new Date()).toISOString(), await o.completeJob(n.id, b, g), fs(r, n.id), console.log(`[${t}] โœ… Job #${n.id} completed as: ${b}`), await _.triggerWorkflowFinish(v, b);
8716
8780
  }
8717
- async function us(e, t) {
8781
+ async function ms(e, t) {
8718
8782
  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;
8719
8783
  try {
8720
- s.env && Object.assign(l.env, await ps(s.env, l));
8784
+ s.env && Object.assign(l.env, await _s(s.env, l));
8721
8785
  for (let e = 0; e < c.length; e++) {
8722
8786
  let s = c[e], m = (/* @__PURE__ */ new Date()).toISOString();
8723
8787
  u[e] = {
@@ -8730,8 +8794,8 @@ async function us(e, t) {
8730
8794
  logContent: "",
8731
8795
  startedAt: m,
8732
8796
  finishedAt: void 0
8733
- }, t.durationMs = Date.now() - Date.parse(t.startedAt), await i.saveReport(o.id, t);
8734
- let h = await ds({
8797
+ }, t.durationMs = Date.now() - Date.parse(t.startedAt), await i.saveReport(o.id, t), fs(a, o.id);
8798
+ let h = await hs({
8735
8799
  workerId: r,
8736
8800
  jobId: o.id,
8737
8801
  step: s,
@@ -8758,7 +8822,7 @@ async function us(e, t) {
8758
8822
  exitCode: 1,
8759
8823
  error: "Step failed before execution started",
8760
8824
  finishedAt: (/* @__PURE__ */ new Date()).toISOString()
8761
- }, p = e + 1, t.durationMs = Date.now() - Date.parse(t.startedAt), await i.saveReport(o.id, t), h.skipped) break;
8825
+ }, p = e + 1, t.durationMs = Date.now() - Date.parse(t.startedAt), await i.saveReport(o.id, t), fs(a, o.id), h.skipped) break;
8762
8826
  if (h.cancelled) {
8763
8827
  f = !0, d = !0;
8764
8828
  break;
@@ -8771,22 +8835,22 @@ async function us(e, t) {
8771
8835
  } catch (e) {
8772
8836
  console.log("๐Ÿ›‘ Step failed", e), d = !0;
8773
8837
  }
8774
- return p < c.length && (hs(c, p, u), t.durationMs = Date.now() - Date.parse(t.startedAt), await i.saveReport(o.id, t)), {
8838
+ return p < c.length && (ys(c, p, u), t.durationMs = Date.now() - Date.parse(t.startedAt), await i.saveReport(o.id, t), fs(a, o.id)), {
8775
8839
  failed: d,
8776
8840
  cancelled: f,
8777
8841
  stepReports: u
8778
8842
  };
8779
8843
  }
8780
- async function ds(e) {
8844
+ async function hs(e) {
8781
8845
  let { step: t, stepIndex: n, executionContext: r } = e;
8782
- if (t.id ||= `step-${n}`, t.name ||= t.id, t.if && !await ko.evaluateConditions(t.if, r)) return Zo && console.log(`โฉ Skipped step ${t.id} based on condition: ${t.if}`, r), {
8846
+ if (t.id ||= `step-${n}`, t.name ||= t.id, t.if && !await ko.evaluateConditions(t.if, r)) return ts && console.log(`โฉ Skipped step ${t.id} based on condition: ${t.if}`, r), {
8783
8847
  failed: !1,
8784
8848
  cancelled: !1,
8785
8849
  skipped: !0,
8786
8850
  report: null
8787
8851
  };
8788
8852
  try {
8789
- let n = await ps(t.env, r), i = {
8853
+ let n = await _s(t.env, r), i = {
8790
8854
  jobId: String(e.jobId),
8791
8855
  step: t,
8792
8856
  command: t.run,
@@ -8800,15 +8864,15 @@ async function ds(e) {
8800
8864
  WORKING_DIR: r.workingDir
8801
8865
  }
8802
8866
  };
8803
- return t.eval ? fs({
8867
+ return t.eval ? gs({
8804
8868
  ...e,
8805
8869
  stepContext: i
8806
- }) : ms({
8870
+ }) : vs({
8807
8871
  ...e,
8808
8872
  stepContext: i
8809
8873
  });
8810
8874
  } catch (e) {
8811
- return Zo && console.error(`โฉ Failed to run step ${t.id}`, r, e), {
8875
+ return ts && console.error(`โฉ Failed to run step ${t.id}`, r, e), {
8812
8876
  failed: !0,
8813
8877
  cancelled: !1,
8814
8878
  skipped: !1,
@@ -8816,7 +8880,7 @@ async function ds(e) {
8816
8880
  };
8817
8881
  }
8818
8882
  }
8819
- async function fs(e) {
8883
+ async function gs(e) {
8820
8884
  let { queue: t, stepContext: n, executionContext: r } = e, { jobId: i, step: a } = n, o = Date.now(), s = a.id, c = a.name;
8821
8885
  try {
8822
8886
  let e = await ko.evaluateExpression(a.eval, r);
@@ -8862,12 +8926,12 @@ async function fs(e) {
8862
8926
  };
8863
8927
  }
8864
8928
  }
8865
- async function ps(e, t) {
8929
+ async function _s(e, t) {
8866
8930
  let n = {};
8867
8931
  if (e) for (let [r, i] of Object.entries(e)) n[r] = String(await ko.evaluateValue(i, t));
8868
8932
  return n;
8869
8933
  }
8870
- async function ms(t) {
8934
+ async function vs(t) {
8871
8935
  let { workerId: n, jobId: r, stepContext: i, executionContext: a, driver: o, queue: s } = t, { step: c } = i, l = c.id, u = c.name, d;
8872
8936
  try {
8873
8937
  d = o.execute(i);
@@ -8882,11 +8946,11 @@ async function ms(t) {
8882
8946
  logFilePath: ""
8883
8947
  };
8884
8948
  }
8885
- $o.add(d);
8949
+ rs.add(d);
8886
8950
  let f = !1, p = setInterval(async () => {
8887
8951
  await s.isCancelled(r) && (console.log(`[${n}] ๐Ÿ›‘ Job #${r} was cancelled! Halting execution.`), f = !0, clearInterval(p), await d.cancel());
8888
8952
  }, 3e3), m = await d.done;
8889
- if (clearInterval(p), $o.delete(d), d.logFilePath && e.existsSync(d.logFilePath)) try {
8953
+ if (clearInterval(p), rs.delete(d), d.logFilePath && e.existsSync(d.logFilePath)) try {
8890
8954
  let e = await o.readLog(d.logFilePath);
8891
8955
  await s.saveStepLog(r, l, e);
8892
8956
  } catch (e) {
@@ -8913,7 +8977,7 @@ async function ms(t) {
8913
8977
  }
8914
8978
  };
8915
8979
  }
8916
- function hs(e, t, n) {
8980
+ function ys(e, t, n) {
8917
8981
  for (let r = t; r < e.length; r++) {
8918
8982
  let t = e[r], i = t.id || `step-${r}`;
8919
8983
  n[r] = {
@@ -8927,7 +8991,7 @@ function hs(e, t, n) {
8927
8991
  };
8928
8992
  }
8929
8993
  }
8930
- function gs(e, t, n, r, i, a, o) {
8994
+ function bs(e, t, n, r, i, a, o) {
8931
8995
  return {
8932
8996
  jobId: String(e.id),
8933
8997
  parentId: String(e.parentId || ""),
@@ -8946,56 +9010,51 @@ function gs(e, t, n, r, i, a, o) {
8946
9010
  })
8947
9011
  };
8948
9012
  }
8949
- async function _s(e, t = [], n) {
8950
- !Array.isArray(t) || t.length === 0 || (console.log(`[${e}] ๐Ÿ“ข Dispatching execution report to ${t.length} reporter(s)...`), await Promise.allSettled(t.map(async (t) => {
8951
- try {
8952
- await t.report(n);
8953
- } catch (n) {
8954
- console.error(`[${e}] โš ๏ธ Reporter '${t.name || "unknown"}' failed:`, n.message);
8955
- }
8956
- })));
8957
- }
8958
9013
  //#endregion
8959
- //#region src/reporters/json-file.reporter.ts
8960
- var vs = class {
8961
- name = "json-file";
8962
- outputDir;
9014
+ //#region src/plugins/github-status.plugin.ts
9015
+ var xs = class {
9016
+ name = "github-commit-status";
9017
+ token;
9018
+ apiUrl;
9019
+ context;
8963
9020
  constructor(e) {
8964
- this.outputDir = e.outputDir;
8965
- }
8966
- async report(t) {
8967
- e.mkdirSync(this.outputDir, { recursive: !0 });
8968
- let n = a.join(this.outputDir, `run-${t.jobId}.json`);
8969
- e.writeFileSync(n, JSON.stringify(t, null, 2), "utf-8"), console.log(`๐Ÿ“Š Execution report saved to: ${n}`);
8970
- }
8971
- }, ys = class {
8972
- name = "slack";
8973
- webhookUrl = "";
8974
- token = "";
8975
- channel = "";
8976
- notifyOn = ["failed"];
8977
- constructor(e) {
8978
- Object.assign(this, e);
9021
+ this.token = e.token, this.apiUrl = e.apiUrl || "https://api.github.com/", this.context = e.context || "on";
9022
+ }
9023
+ async onWorkflowStart(e) {
9024
+ this.hasCoordinates(e) && await this.updateStatus(e, "pending", "Workflow build has started.");
8979
9025
  }
8980
- async report(e) {
8981
- if (!this.notifyOn.includes(e.status)) return;
8982
- let t = `${e.status === "success" ? "โœ…" : "โŒ"} *Workflow ${e.workflowName} (#${e.jobId})* finished with status: *${e.status.toUpperCase()}* (${e.durationMs}ms)`;
8983
- await fetch(this.webhookUrl, {
9026
+ async onWorkflowFinish(e, t) {
9027
+ if (!this.hasCoordinates(e)) return;
9028
+ let n = t === "success" ? "success" : t === "failed" ? "failure" : "error", r = t === "success" ? "Workflow completed successfully." : `Workflow ${t}.`;
9029
+ await this.updateStatus(e, n, r);
9030
+ }
9031
+ async updateStatus(e, t, n) {
9032
+ let r = encodeURIComponent(String(e.inputs.owner)), i = encodeURIComponent(String(e.inputs.repo)), a = encodeURIComponent(String(e.inputs.commit_sha)), o = this.apiUrl.endsWith("/") ? this.apiUrl : `${this.apiUrl}/`, s = await fetch(new URL(`repos/${r}/${i}/statuses/${a}`, o), {
8984
9033
  method: "POST",
8985
9034
  headers: {
9035
+ Accept: "application/vnd.github+json",
8986
9036
  Authorization: `Bearer ${this.token}`,
8987
- "Content-Type": "application/json"
9037
+ "Content-Type": "application/json",
9038
+ "User-Agent": "@cloud-cli/on",
9039
+ "X-GitHub-Api-Version": "2022-11-28"
8988
9040
  },
9041
+ signal: AbortSignal.timeout(1e4),
8989
9042
  body: JSON.stringify({
8990
- channel: this.channel,
8991
- text: t
9043
+ state: t,
9044
+ target_url: e.runUrl,
9045
+ description: n.slice(0, 140),
9046
+ context: `${this.context}/${e.workflowName}`.slice(0, 100)
8992
9047
  })
8993
9048
  });
9049
+ if (!s.ok) throw Error(`GitHub status update failed with HTTP ${s.status}: ${await s.text()}`);
9050
+ }
9051
+ hasCoordinates(e) {
9052
+ return !!(this.token && e.inputs.owner && e.inputs.repo && e.inputs.commit_sha);
8994
9053
  }
8995
9054
  };
8996
9055
  //#endregion
8997
9056
  //#region src/index.ts
8998
- function bs(e) {
9057
+ function Ss(e) {
8999
9058
  console.log("๐Ÿ” Validating Workflows in:", e.workflows);
9000
9059
  let t = new di(e.workflows), n = r(e.workflows).filter((e) => e.endsWith(".yml") || e.endsWith(".yaml"));
9001
9060
  for (let e of n) {
@@ -9003,13 +9062,13 @@ function bs(e) {
9003
9062
  console.log(` โœ… ${e} -> Valid! (${n.length} job matrix variant(s) generated)`);
9004
9063
  }
9005
9064
  }
9006
- async function xs() {
9065
+ async function Cs() {
9007
9066
  let { config: e, command: t } = await fe();
9008
- if (e || process.exit(1), t === "validate") return bs(e);
9067
+ if (e || process.exit(1), t === "validate") return Ss(e);
9009
9068
  let n = new mi("./.env"), r = new pi(process.env.WORKER_NAME || "cli");
9010
9069
  switch (t) {
9011
9070
  case "start-server":
9012
- console.log("๐ŸŒ Starting Ingress Gateway..."), await r.init(), await Go.withPort({
9071
+ console.log("๐ŸŒ Starting Ingress Gateway..."), await r.init(), await Jo.withPort({
9013
9072
  config: e,
9014
9073
  queue: r,
9015
9074
  secrets: n,
@@ -9018,11 +9077,11 @@ async function xs() {
9018
9077
  });
9019
9078
  break;
9020
9079
  case "start-workers":
9021
- console.log(`โš™๏ธ Starting worker scheduler with ${e.workers} concurrent slot(s)...`), await r.init(), rs(e.workers, r, n, e);
9080
+ console.log(`โš™๏ธ Starting worker scheduler with ${e.workers} concurrent slot(s)...`), await r.init(), ss(e.workers, r, n, e);
9022
9081
  break;
9023
9082
  default: console.error(`โŒ Unknown command: '${t}'`), de(), process.exit(1);
9024
9083
  }
9025
9084
  }
9026
- xs().catch(console.error);
9085
+ Cs().catch(console.error);
9027
9086
  //#endregion
9028
- export { Io as HtmlReporter, vs as JsonFileReporter, ys as SlackReporter };
9087
+ export { xs as GitHubStatusPlugin };
@@ -1,8 +1,18 @@
1
- import { WorkflowPlugin, WorkflowContext } from '../types.js';
1
+ import type { FinalJobStatus, WorkflowContext, WorkflowPlugin } from '../types.js';
2
+ export interface GitHubStatusPluginOptions {
3
+ token: string;
4
+ apiUrl?: string;
5
+ context?: string;
6
+ }
2
7
  export declare class GitHubStatusPlugin implements WorkflowPlugin {
3
- name: string;
8
+ readonly name = "github-commit-status";
9
+ private readonly token;
10
+ private readonly apiUrl;
11
+ private readonly context;
12
+ constructor(options: GitHubStatusPluginOptions);
4
13
  onWorkflowStart(wf: WorkflowContext): Promise<void>;
5
- onWorkflowFinish(wf: WorkflowContext, status: 'success' | 'failed'): Promise<void>;
14
+ onWorkflowFinish(wf: WorkflowContext, status: FinalJobStatus): Promise<void>;
6
15
  private updateStatus;
16
+ private hasCoordinates;
7
17
  }
8
18
  //# sourceMappingURL=github-status.plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"github-status.plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/github-status.plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9D,qBAAa,kBAAmB,YAAW,cAAc;IACvD,IAAI,SAA0B;IAExB,eAAe,CAAC,EAAE,EAAE,eAAe;IAMnC,gBAAgB,CAAC,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE,SAAS,GAAG,QAAQ;YAS1D,YAAY;CAK3B"}
1
+ {"version":3,"file":"github-status.plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/github-status.plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEnF,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,kBAAmB,YAAW,cAAc;IACvD,QAAQ,CAAC,IAAI,0BAA0B;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,EAAE,yBAAyB;IAMxC,eAAe,CAAC,EAAE,EAAE,eAAe;IAMnC,gBAAgB,CAAC,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE,cAAc;YASpD,YAAY;IA4B1B,OAAO,CAAC,cAAc;CAGvB"}
@@ -1,8 +1,9 @@
1
- import { WorkflowPlugin, WorkflowContext } from '../types.js';
1
+ import type { FinalJobStatus, WorkflowContext, WorkflowPlugin } from '../types.js';
2
2
  export declare class PluginManager {
3
3
  private plugins;
4
+ constructor(plugins?: WorkflowPlugin[]);
4
5
  register(plugin: WorkflowPlugin): void;
5
6
  triggerWorkflowStart(wf: WorkflowContext): Promise<void>;
6
- triggerWorkflowFinish(wf: WorkflowContext, status: 'success' | 'failed'): Promise<void>;
7
+ triggerWorkflowFinish(wf: WorkflowContext, status: FinalJobStatus): Promise<void>;
7
8
  }
8
9
  //# sourceMappingURL=manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/plugins/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9D,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAwB;IAEvC,QAAQ,CAAC,MAAM,EAAE,cAAc;IAKzB,oBAAoB,CAAC,EAAE,EAAE,eAAe;IAUxC,qBAAqB,CAAC,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE,SAAS,GAAG,QAAQ;CAS9E"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/plugins/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEnF,qBAAa,aAAa;IACZ,OAAO,CAAC,OAAO;gBAAP,OAAO,GAAE,cAAc,EAAO;IAElD,QAAQ,CAAC,MAAM,EAAE,cAAc;IAKzB,oBAAoB,CAAC,EAAE,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAYxD,qBAAqB,CAAC,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAWxF"}
@@ -0,0 +1,16 @@
1
+ import type { JobRecord, StepReport, WorkflowExecutionReport } from './types.js';
2
+ export interface RunView {
3
+ jobId: string;
4
+ parentId: string;
5
+ workflowName: string;
6
+ status: WorkflowExecutionReport['status'];
7
+ durationMs: number;
8
+ startedAt: string;
9
+ finishedAt?: string;
10
+ inputs: Record<string, unknown>;
11
+ steps: StepReport[];
12
+ artifacts: string[];
13
+ }
14
+ export declare function buildRunView(job: JobRecord & Record<string, any>, logs: Record<string, string>, redact: (value: string) => string): RunView;
15
+ export declare function renderRunHtml(report: RunView): string;
16
+ //# sourceMappingURL=run-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-view.d.ts","sourceRoot":"","sources":["../src/run-view.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAc,SAAS,EAAE,UAAU,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAK7F,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,YAAY,CAC1B,GAAG,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACpC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAChC,OAAO,CAgCT;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAErD"}
package/dist/server.d.ts CHANGED
@@ -35,7 +35,6 @@ export declare class WebhookServer {
35
35
  * Serves single job HTML report
36
36
  */
37
37
  private renderRunDetails;
38
- private buildPendingReport;
39
38
  private handleRestartJob;
40
39
  listen(port: number): Promise<WebhookServer>;
41
40
  stop(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,mBAAmB,EACnB,oBAAoB,EAGrB,MAAM,YAAY,CAAC;AAQpB,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,aAAa,CAA0C;IAC/D,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,eAAe,CAAgB;WAE1B,QAAQ,CAAC,OAAO,EAAE,oBAAoB,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;gBAK1D,OAAO,EAAE,oBAAoB;IAczC,oBAAoB,CAAC,YAAY,EAAE,mBAAmB;YAIxC,aAAa;IAkE3B;;OAEG;YACW,aAAa;YA0Bb,WAAW;IAwBzB,OAAO,CAAC,UAAU;YAiBJ,cAAc;IA2C5B;;OAEG;YACW,kBAAkB;YAelB,iBAAiB;IAU/B;;OAEG;YACW,eAAe;YAQf,mBAAmB;IAWjC;;OAEG;YACW,gBAAgB;IAkC9B,OAAO,CAAC,kBAAkB;YA0BZ,gBAAgB;IAc9B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAStC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAS5B"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,mBAAmB,EACnB,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAQpB,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,aAAa,CAA0C;IAC/D,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,eAAe,CAAgB;WAE1B,QAAQ,CAAC,OAAO,EAAE,oBAAoB,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;gBAK1D,OAAO,EAAE,oBAAoB;IAczC,oBAAoB,CAAC,YAAY,EAAE,mBAAmB;YAIxC,aAAa;IAuE3B;;OAEG;YACW,aAAa;YA0Bb,WAAW;IAwBzB,OAAO,CAAC,UAAU;YAiBJ,cAAc;IA2C5B;;OAEG;YACW,kBAAkB;YAelB,iBAAiB;IAuB/B;;OAEG;YACW,eAAe;YAQf,mBAAmB;IAWjC;;OAEG;YACW,gBAAgB;YAqBhB,gBAAgB;IAc9B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAStC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAS5B"}
package/dist/types.d.ts CHANGED
@@ -1,9 +1,5 @@
1
1
  import { QueueManager } from './queue.js';
2
2
  import { SecretStore } from './secrets.js';
3
- export interface Reporter {
4
- name: string;
5
- report(execReport: WorkflowExecutionReport): Promise<void>;
6
- }
7
3
  export interface RunnerConfig {
8
4
  /** Ingress HTTP Gateway Port */
9
5
  port: number;
@@ -13,7 +9,7 @@ export interface RunnerConfig {
13
9
  database: string;
14
10
  /** Directory where workflow YAML files live */
15
11
  workflows: string;
16
- /** Number of concurrent worker loops to spawn */
12
+ /** Maximum number of jobs executed concurrently on this node */
17
13
  workers: number;
18
14
  /** Webhook server URL used for worker event notifications */
19
15
  serverUrl: string;
@@ -23,8 +19,8 @@ export interface RunnerConfig {
23
19
  storagePath: string;
24
20
  /** Global environment variables injected into all step runs */
25
21
  env: Record<string, string>;
26
- /** Registered reporter plugins (JSON, Slack, HTML, etc.) */
27
- reporters: Reporter[];
22
+ /** External integrations notified about workflow lifecycle changes */
23
+ plugins: WorkflowPlugin[];
28
24
  }
29
25
  export type UserRunnerConfig = Partial<RunnerConfig>;
30
26
  export interface StepContext {
@@ -149,35 +145,18 @@ export interface ParsedWorkflow {
149
145
  steps: WorkflowStep[];
150
146
  [key: string]: any;
151
147
  }
152
- export interface IngressContext {
153
- provider: string;
154
- headers: Record<string, string>;
155
- body: any;
156
- rawBuffer: Buffer;
157
- }
158
148
  export interface WorkflowContext {
159
149
  jobId: string;
160
150
  workflowName: string;
161
151
  inputs: WorkflowInputs;
162
- env: Record<string, string>;
152
+ runUrl: string;
163
153
  }
164
154
  export interface WorkflowPlugin {
165
155
  name: string;
166
- /** Verify HMAC or signatures */
167
- onAuthenticate?: (ctx: IngressContext) => Promise<boolean> | boolean;
168
- /** Convert raw body/headers into normalized inputs */
169
- onTransform?: (ctx: IngressContext) => Promise<Record<string, any>> | Record<string, any>;
170
- /** Final gatekeeper check (return false to drop job before enqueueing) */
171
- onFilter?: (inputs: Record<string, any>, ctx: IngressContext) => Promise<boolean> | boolean;
172
- /** Runs before any steps execute (e.g. notify Slack, update GitHub status to "Pending") */
173
156
  onWorkflowStart?: (wf: WorkflowContext) => Promise<void>;
174
- /** Runs right before a step executes (e.g. inject dynamic secrets, prepare workspace) */
175
- onStepBefore?: (step: StepContext, wf: WorkflowContext) => Promise<void>;
176
- /** Runs after a step finishes (e.g. parse outputs, stream step metrics) */
177
- onStepAfter?: (step: StepContext, result: StepResult, wf: WorkflowContext) => Promise<void>;
178
- /** Runs when workflow succeeds or fails (e.g. update GitHub status to "Success/Failure", wipe layers) */
179
- onWorkflowFinish?: (wf: WorkflowContext, status: 'success' | 'failed', error?: Error) => Promise<void>;
157
+ onWorkflowFinish?: (wf: WorkflowContext, status: FinalJobStatus) => Promise<void>;
180
158
  }
159
+ export type FinalJobStatus = Exclude<JobStatus, 'pending' | 'running'>;
181
160
  export interface StepReport {
182
161
  id: string;
183
162
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAGL,YAAY,EAOZ,WAAW,EAIZ,MAAM,YAAY,CAAC;AAMpB,eAAO,MAAM,aAAa;;CAEzB,CAAC;AAMF;;GAEG;AACH,wBAAsB,qBAAqB,kBAK1C;AAED,wBAAgB,qBAAqB,SAIpC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,mBAK1G;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,YAAY,iBA4DrB;AA4ED;;GAEG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAAE,WAAW,iBA2D9C"}
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAGL,YAAY,EAOZ,WAAW,EAIZ,MAAM,YAAY,CAAC;AAOpB,eAAO,MAAM,aAAa;;CAEzB,CAAC;AAMF;;GAEG;AACH,wBAAsB,qBAAqB,kBAK1C;AAED,wBAAgB,qBAAqB,SAIpC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,mBAK1G;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,YAAY,iBA4DrB;AAgFD;;GAEG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAAE,WAAW,iBAoE9C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloud-cli/on",
3
- "version": "1.9.0",
3
+ "version": "1.9.1",
4
4
  "description": "CLI entry point for the on plugin ecosystem.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.30.3",
@@ -1,11 +0,0 @@
1
- import { Reporter, WorkflowExecutionReport } from '../types.js';
2
- export declare class HtmlReporter implements Reporter {
3
- name: string;
4
- private outputDir;
5
- constructor(options: {
6
- outputDir: string;
7
- });
8
- report(execReport: WorkflowExecutionReport): Promise<void>;
9
- generateHtml(execReport: WorkflowExecutionReport): string;
10
- }
11
- //# sourceMappingURL=html.reporter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"html.reporter.d.ts","sourceRoot":"","sources":["../../src/reporters/html.reporter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAMhE,qBAAa,YAAa,YAAW,QAAQ;IAC3C,IAAI,SAAU;IACd,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE;IAIpC,MAAM,CAAC,UAAU,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAShE,YAAY,CAAC,UAAU,EAAE,uBAAuB,GAAG,MAAM;CAG1D"}
@@ -1,10 +0,0 @@
1
- import { Reporter, WorkflowExecutionReport } from '../types.js';
2
- export declare class JsonFileReporter implements Reporter {
3
- name: string;
4
- private outputDir;
5
- constructor(options: {
6
- outputDir: string;
7
- });
8
- report(execReport: WorkflowExecutionReport): Promise<void>;
9
- }
10
- //# sourceMappingURL=json-file.reporter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"json-file.reporter.d.ts","sourceRoot":"","sources":["../../src/reporters/json-file.reporter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEhE,qBAAa,gBAAiB,YAAW,QAAQ;IAC/C,IAAI,SAAe;IACnB,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE;IAIpC,MAAM,CAAC,UAAU,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;CAQjE"}
@@ -1,16 +0,0 @@
1
- import { Reporter, WorkflowExecutionReport } from '../types.js';
2
- export declare class SlackReporter implements Reporter {
3
- readonly name = "slack";
4
- private webhookUrl;
5
- private token;
6
- private channel;
7
- private notifyOn;
8
- constructor(options: {
9
- webhookUrl: string;
10
- token: string;
11
- channel: string;
12
- notifyOn?: ('success' | 'failed')[];
13
- });
14
- report(execReport: WorkflowExecutionReport): Promise<void>;
15
- }
16
- //# sourceMappingURL=slack.reporter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"slack.reporter.d.ts","sourceRoot":"","sources":["../../src/reporters/slack.reporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEhE,qBAAa,aAAc,YAAW,QAAQ;IAC5C,QAAQ,CAAC,IAAI,WAAW;IACxB,OAAO,CAAC,UAAU,CAAc;IAChC,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,QAAQ,CAAwC;gBAE5C,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,CAAC,SAAS,GAAG,QAAQ,CAAC,EAAE,CAAA;KAAE;IAI1G,MAAM,CAAC,UAAU,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;CAejE"}