@cloud-cli/on 1.66.2 → 1.67.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/{oidc-user-repository-CiprwzOj.js → oidc-user-repository-C4HnJLyx.js} +19 -0
- package/dist/oidc-user-repository-pPSfFkOo.js +2 -0
- package/dist/oidc-user-repository.d.ts +7 -2
- package/dist/oidc-user-repository.d.ts.map +1 -1
- package/dist/oidc.d.ts +2 -1
- package/dist/oidc.d.ts.map +1 -1
- package/dist/on.js +3 -3
- package/dist/{server-CQ3FDHUe.js → server-Dlmiez4d.js} +121 -30
- package/dist/server.d.ts +2 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/{worker-BwNyfSpp.js → worker-FXzBXCLz.js} +2 -0
- package/package.json +3 -1
- package/dist/oidc-user-repository-BNQF3qnb.js +0 -2
|
@@ -15,6 +15,25 @@ var t = class {
|
|
|
15
15
|
async role(t) {
|
|
16
16
|
return (await e.get("SELECT role FROM oidc_users WHERE subject = ?", [t]))?.role === "admin" ? "admin" : "user";
|
|
17
17
|
}
|
|
18
|
+
async list() {
|
|
19
|
+
return (await e.all("SELECT subject, name, email, role FROM oidc_users ORDER BY name, email, subject")).map((e) => ({
|
|
20
|
+
id: e.subject,
|
|
21
|
+
name: e.name || void 0,
|
|
22
|
+
email: e.email || void 0,
|
|
23
|
+
role: e.role === "admin" ? "admin" : "user"
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
async setRole(t, n) {
|
|
27
|
+
let r = await e.get("SELECT role FROM oidc_users WHERE subject = ?", [t]);
|
|
28
|
+
if (!r) return "not-found";
|
|
29
|
+
if (r.role === n) return "updated";
|
|
30
|
+
let i = await e.run("UPDATE oidc_users SET role = ?, updated_at = CURRENT_TIMESTAMP\n WHERE subject = ? AND (? = 'admin' OR role != 'admin' OR\n (SELECT COUNT(*) FROM oidc_users WHERE role = 'admin') > 1)", [
|
|
31
|
+
n,
|
|
32
|
+
t,
|
|
33
|
+
n
|
|
34
|
+
]);
|
|
35
|
+
return Number(i?.changes || 0) > 0 ? "updated" : await e.get("SELECT subject FROM oidc_users WHERE subject = ?", [t]) ? "last-admin" : "not-found";
|
|
36
|
+
}
|
|
18
37
|
async promote(t) {
|
|
19
38
|
let n = await e.run("UPDATE oidc_users SET role = 'admin', updated_at = CURRENT_TIMESTAMP WHERE subject = ?", [t]);
|
|
20
39
|
return Number(n?.changes || 0) > 0;
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import type { OidcUser } from
|
|
2
|
-
export type OidcRole =
|
|
1
|
+
import type { OidcUser } from "./oidc.js";
|
|
2
|
+
export type OidcRole = "user" | "admin";
|
|
3
|
+
export type OidcUserRecord = Pick<OidcUser, "id" | "name" | "email"> & {
|
|
4
|
+
role: OidcRole;
|
|
5
|
+
};
|
|
3
6
|
export declare class OidcUserRepository {
|
|
4
7
|
init(): Promise<void>;
|
|
5
8
|
upsert(user: OidcUser): Promise<void>;
|
|
6
9
|
role(subject: string): Promise<OidcRole>;
|
|
10
|
+
list(): Promise<OidcUserRecord[]>;
|
|
11
|
+
setRole(subject: string, role: OidcRole): Promise<"updated" | "not-found" | "last-admin">;
|
|
7
12
|
promote(subject: string): Promise<boolean>;
|
|
8
13
|
}
|
|
9
14
|
//# sourceMappingURL=oidc-user-repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oidc-user-repository.d.ts","sourceRoot":"","sources":["../src/oidc-user-repository.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"oidc-user-repository.d.ts","sourceRoot":"","sources":["../src/oidc-user-repository.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AACxC,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AAE1F,qBAAa,kBAAkB;IACvB,IAAI;IASJ,MAAM,CAAC,IAAI,EAAE,QAAQ;IAQrB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAKxC,IAAI,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAUjC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,GAAG,WAAW,GAAG,YAAY,CAAC;IAmBzF,OAAO,CAAC,OAAO,EAAE,MAAM;CAO9B"}
|
package/dist/oidc.d.ts
CHANGED
|
@@ -23,7 +23,8 @@ export declare class OidcClient {
|
|
|
23
23
|
cookie: string;
|
|
24
24
|
}>;
|
|
25
25
|
userFromCookie(cookieHeader: string | undefined): OidcUser | undefined;
|
|
26
|
-
setRole(cookieHeader: string, role:
|
|
26
|
+
setRole(cookieHeader: string, role: "user" | "admin"): void;
|
|
27
|
+
setRoleForUser(subject: string, role: "user" | "admin"): void;
|
|
27
28
|
roleFromCookie(cookieHeader: string | undefined): "user" | "admin" | undefined;
|
|
28
29
|
accessTokenFromCookie(cookieHeader: string | undefined): {
|
|
29
30
|
accessToken: string;
|
package/dist/oidc.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oidc.d.ts","sourceRoot":"","sources":["../src/oidc.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAoBD,qBAAa,UAAU;IACrB,OAAO,CAAC,qBAAqB,CAAC,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8B;gBAE3C,MAAM,EAAE,UAAU;IAI9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IAEpC,IAAI,OAAO,YAEV;IAED,IAAI,QAAQ,WAEX;IAEK,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUhE,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IA+BpH,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS;IAKtE,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAMpD,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS;IAI/C,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS;;;;IAMhD,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"oidc.d.ts","sourceRoot":"","sources":["../src/oidc.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAoBD,qBAAa,UAAU;IACrB,OAAO,CAAC,qBAAqB,CAAC,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8B;gBAE3C,MAAM,EAAE,UAAU;IAI9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IAEpC,IAAI,OAAO,YAEV;IAED,IAAI,QAAQ,WAEX;IAEK,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUhE,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IA+BpH,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS;IAKtE,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAMpD,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAMtD,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS;IAI/C,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS;;;;IAMhD,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;IAgBvD,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,EAAE,WAAW,CAAC,EAAE,MAAM;IAUlH,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS;IAM5C,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,WAAW;YAOL,cAAc;IAkB5B,OAAO,CAAC,KAAK;IAKb,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,UAAU;CAYnB"}
|
package/dist/on.js
CHANGED
|
@@ -104,11 +104,11 @@ async function m() {
|
|
|
104
104
|
let [{ QueueManager: r }, { SecretStore: i }, { WebhookServer: a }, { startWorkers: o }, { WorkflowRepository: s }, { WorkflowScheduler: c }, { OidcUserRepository: l }] = await Promise.all([
|
|
105
105
|
import("./queue-DhXXzxm3.js"),
|
|
106
106
|
import("./secrets-DhkqmawU.js"),
|
|
107
|
-
import("./server-
|
|
108
|
-
import("./worker-
|
|
107
|
+
import("./server-Dlmiez4d.js"),
|
|
108
|
+
import("./worker-FXzBXCLz.js"),
|
|
109
109
|
import("./workflows-DQQIVH7c.js"),
|
|
110
110
|
import("./scheduler-2d1UPcxM.js"),
|
|
111
|
-
import("./oidc-user-repository-
|
|
111
|
+
import("./oidc-user-repository-pPSfFkOo.js")
|
|
112
112
|
]);
|
|
113
113
|
if (t === "promote-admin") {
|
|
114
114
|
if (!n) throw Error("Usage: on promote-admin --subject <oidc-subject>");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as e, r as t, t as n } from "./rolldown-runtime-B0aSnxlc.js";
|
|
2
2
|
import { t as r } from "./db-client-BvMkK1lx.js";
|
|
3
|
-
import { t as i } from "./oidc-user-repository-
|
|
3
|
+
import { t as i } from "./oidc-user-repository-C4HnJLyx.js";
|
|
4
4
|
import { a, n as o, r as s, t as c } from "./matrix-expander-BItKqWu2.js";
|
|
5
5
|
import { t as l } from "./secrets-BR6K16WY.js";
|
|
6
6
|
import { t as u } from "./events-BoODn7MY.js";
|
|
@@ -1873,12 +1873,13 @@ var nn = {
|
|
|
1873
1873
|
{ name: "discovery" },
|
|
1874
1874
|
{ name: "jobs" },
|
|
1875
1875
|
{ name: "workflows" },
|
|
1876
|
+
{ name: "users" },
|
|
1876
1877
|
{ name: "secrets" },
|
|
1877
1878
|
{ name: "events" },
|
|
1878
1879
|
{ name: "webhooks" },
|
|
1879
1880
|
{ name: "notifications" }
|
|
1880
1881
|
],
|
|
1881
|
-
paths: /* @__PURE__ */ JSON.parse("{\"/api\":{\"get\":{\"tags\":[\"discovery\"],\"summary\":\"Get this OpenAPI specification\",\"security\":[],\"responses\":{\"200\":{\"description\":\"OpenAPI JSON document\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}}}}},\"/api/api-keys\":{\"get\":{\"tags\":[\"discovery\"],\"summary\":\"List active API keys\",\"responses\":{\"200\":{\"description\":\"API key metadata\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/ApiKeyList\"}}}}}},\"post\":{\"tags\":[\"discovery\"],\"summary\":\"Issue a scoped API key\",\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/ApiKeyIssue\"}}}},\"responses\":{\"201\":{\"description\":\"Key metadata and one-time token\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/ApiKeyCreated\"}}}}}}},\"/api/api-keys/{keyId}\":{\"delete\":{\"tags\":[\"discovery\"],\"summary\":\"Revoke an API key\",\"parameters\":[{\"name\":\"keyId\",\"in\":\"path\",\"required\":true,\"schema\":{\"type\":\"string\",\"format\":\"uuid\"}}],\"responses\":{\"204\":{\"description\":\"Key revoked\"},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}}},\"/api/jobs\":{\"get\":{\"tags\":[\"jobs\"],\"summary\":\"List jobs\",\"security\":[],\"parameters\":[{\"$ref\":\"#/components/parameters/AfterId\"},{\"$ref\":\"#/components/parameters/BeforeId\"},{\"$ref\":\"#/components/parameters/Limit\"},{\"$ref\":\"#/components/parameters/Filter\"},{\"$ref\":\"#/components/parameters/WorkflowFilter\"}],\"responses\":{\"200\":{\"description\":\"Dashboard job list\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/JobList\"}}}}}}},\"/api/dispatch/{trigger}\":{\"post\":{\"tags\":[\"jobs\"],\"summary\":\"Dispatch a workflow trigger with manual inputs\",\"security\":[{\"bearerAuth\":[]},{\"basicAuth\":[]}],\"parameters\":[{\"name\":\"trigger\",\"in\":\"path\",\"required\":true,\"schema\":{\"type\":\"string\"}}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}},\"responses\":{\"202\":{\"description\":\"Jobs queued\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}},\"401\":{\"$ref\":\"#/components/responses/Unauthorized\"}}}},\"/api/workflows/{workflowId}/run\":{\"post\":{\"tags\":[\"jobs\"],\"summary\":\"Run the latest saved workflow revision immediately\",\"security\":[{\"oidcSessionCookie\":[]}],\"parameters\":[{\"name\":\"workflowId\",\"in\":\"path\",\"required\":true,\"schema\":{\"type\":\"string\"}}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}},\"responses\":{\"202\":{\"description\":\"Jobs queued\"},\"400\":{\"$ref\":\"#/components/responses/ValidationError\"},\"404\":{\"$ref\":\"#/components/responses/NotFound\"},\"401\":{\"$ref\":\"#/components/responses/Unauthorized\"}}}},\"/api/jobs/{jobId}/wait\":{\"get\":{\"tags\":[\"jobs\"],\"summary\":\"Wait for a job to reach a terminal state\",\"parameters\":[{\"$ref\":\"#/components/parameters/JobId\"},{\"name\":\"timeout\",\"in\":\"query\",\"schema\":{\"type\":\"integer\",\"minimum\":0,\"maximum\":120000,\"default\":30000}}],\"responses\":{\"200\":{\"description\":\"Latest job state\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}}},\"/api/jobs/{jobId}/cancel\":{\"post\":{\"tags\":[\"jobs\"],\"summary\":\"Cancel an active job\",\"parameters\":[{\"$ref\":\"#/components/parameters/JobId\"}],\"responses\":{\"200\":{\"description\":\"Job cancelled\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/JobStatus\"}}}},\"404\":{\"$ref\":\"#/components/responses/NotFound\"},\"409\":{\"$ref\":\"#/components/responses/Conflict\"}}}},\"/api/jobs/{jobId}/secrets\":{\"get\":{\"tags\":[\"jobs\"],\"summary\":\"Get secrets for an assigned worker job\",\"security\":[{\"workerBearerAuth\":[]}],\"parameters\":[{\"$ref\":\"#/components/parameters/JobId\"},{\"$ref\":\"#/components/parameters/WorkerId\"}],\"responses\":{\"200\":{\"description\":\"Decrypted job secrets\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/Secrets\"}}}},\"403\":{\"$ref\":\"#/components/responses/Forbidden\"}}}},\"/api/runs/{jobId}\":{\"get\":{\"tags\":[\"jobs\"],\"summary\":\"Get a run view\",\"parameters\":[{\"$ref\":\"#/components/parameters/JobId\"}],\"responses\":{\"200\":{\"description\":\"Run details\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/RunView\"}}}},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}}},\"/api/runs/{jobId}/artifacts/{path}\":{\"get\":{\"tags\":[\"jobs\"],\"summary\":\"Download an artifact\",\"parameters\":[{\"$ref\":\"#/components/parameters/JobId\"},{\"name\":\"path\",\"in\":\"path\",\"required\":true,\"schema\":{\"type\":\"string\"}}],\"responses\":{\"200\":{\"description\":\"Artifact bytes\",\"content\":{\"application/octet-stream\":{\"schema\":{\"type\":\"string\",\"format\":\"binary\"}}}},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}}},\"/api/runs/{jobId}/ai-help\":{\"post\":{\"tags\":[\"jobs\"],\"summary\":\"Ask AI to diagnose a failed step\",\"parameters\":[{\"$ref\":\"#/components/parameters/JobId\"}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"required\":[\"stepId\"],\"properties\":{\"stepId\":{\"type\":\"string\"}}}}}},\"responses\":{\"200\":{\"description\":\"AI diagnosis\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"properties\":{\"answer\":{\"type\":\"string\"}}}}}},\"401\":{\"$ref\":\"#/components/responses/Unauthorized\"},\"502\":{\"description\":\"AI provider failure\"},\"503\":{\"description\":\"AI help is not configured\"}}}},\"/api/workflows/validate\":{\"post\":{\"tags\":[\"workflows\"],\"summary\":\"Validate workflow YAML\",\"security\":[{\"oidcSessionCookie\":[]}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/WorkflowSource\"}}}},\"responses\":{\"200\":{\"description\":\"Valid workflow definitions\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/ValidationResult\"}}}},\"422\":{\"$ref\":\"#/components/responses/ValidationError\"}}}},\"/api/ai/workflow-help\":{\"post\":{\"tags\":[\"workflows\"],\"summary\":\"Get a workflow YAML suggestion\",\"security\":[{\"oidcSessionCookie\":[]}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"required\":[\"request\"],\"properties\":{\"request\":{\"type\":\"string\"},\"sourceYaml\":{\"type\":\"string\"}}}}}},\"responses\":{\"200\":{\"description\":\"Workflow YAML suggestion stream\",\"content\":{\"text/event-stream\":{\"schema\":{\"type\":\"string\"}}}},\"400\":{\"$ref\":\"#/components/responses/ValidationError\"},\"401\":{\"$ref\":\"#/components/responses/Unauthorized\"},\"502\":{\"description\":\"AI provider failure\"},\"503\":{\"description\":\"AI help is not configured\"}}}},\"/api/workflows\":{\"get\":{\"tags\":[\"workflows\"],\"summary\":\"List workflows\",\"security\":[{\"oidcSessionCookie\":[]}],\"responses\":{\"200\":{\"description\":\"Workflow list\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"properties\":{\"workflows\":{\"type\":\"array\",\"items\":{\"$ref\":\"#/components/schemas/Workflow\"}}}}}}}}}},\"/api/workflows/{workflowId}\":{\"get\":{\"tags\":[\"workflows\"],\"summary\":\"Get a workflow or historical revision\",\"security\":[{\"oidcSessionCookie\":[]}],\"parameters\":[{\"$ref\":\"#/components/parameters/WorkflowId\"},{\"$ref\":\"#/components/parameters/Revision\"}],\"responses\":{\"200\":{\"description\":\"Workflow definition\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/Workflow\"}}}},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}},\"put\":{\"tags\":[\"workflows\"],\"summary\":\"Save a workflow draft\",\"security\":[{\"oidcSessionCookie\":[]}],\"parameters\":[{\"$ref\":\"#/components/parameters/WorkflowId\"}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/WorkflowSave\"}}}},\"responses\":{\"200\":{\"description\":\"Draft saved\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/Workflow\"}}}},\"422\":{\"$ref\":\"#/components/responses/ValidationError\"}}},\"delete\":{\"tags\":[\"workflows\"],\"summary\":\"Delete a workflow and its revisions\",\"security\":[{\"oidcSessionCookie\":[]}],\"parameters\":[{\"$ref\":\"#/components/parameters/WorkflowId\"}],\"responses\":{\"204\":{\"description\":\"Workflow deleted\"},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}}},\"/api/workflows/{workflowId}/publish\":{\"post\":{\"tags\":[\"workflows\"],\"summary\":\"Publish the latest workflow revision\",\"security\":[{\"oidcSessionCookie\":[]}],\"parameters\":[{\"$ref\":\"#/components/parameters/WorkflowId\"}],\"responses\":{\"200\":{\"description\":\"Workflow published\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/Workflow\"}}}},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}}},\"/api/secrets\":{\"get\":{\"tags\":[\"secrets\"],\"summary\":\"List secret names\",\"security\":[{\"oidcSessionCookie\":[]}],\"responses\":{\"200\":{\"description\":\"Secret names\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/SecretNames\"}}}}}}},\"/api/secrets/{name}\":{\"put\":{\"tags\":[\"secrets\"],\"summary\":\"Create or replace an encrypted secret\",\"security\":[{\"oidcSessionCookie\":[]}],\"parameters\":[{\"$ref\":\"#/components/parameters/SecretName\"}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/SecretValue\"}}}},\"responses\":{\"204\":{\"description\":\"Secret saved\"}}},\"delete\":{\"tags\":[\"secrets\"],\"summary\":\"Delete a secret\",\"security\":[{\"oidcSessionCookie\":[]}],\"parameters\":[{\"$ref\":\"#/components/parameters/SecretName\"}],\"responses\":{\"204\":{\"description\":\"Secret deleted\"},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}}},\"/api/events\":{\"get\":{\"tags\":[\"events\"],\"summary\":\"Subscribe to runner events\",\"security\":[],\"responses\":{\"200\":{\"description\":\"Server-sent event stream\",\"content\":{\"text/event-stream\":{\"schema\":{\"type\":\"string\"}}}}}},\"post\":{\"tags\":[\"events\"],\"summary\":\"Publish a worker job-change event\",\"security\":[{\"workerBearerAuth\":[]}],\"requestBody\":{\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/JobEvent\"}}}},\"responses\":{\"202\":{\"description\":\"Event accepted\"}}}},\"/api/push/public-key\":{\"get\":{\"tags\":[\"notifications\"],\"summary\":\"Get the Web Push public key\",\"security\":[],\"responses\":{\"200\":{\"description\":\"VAPID public key\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"properties\":{\"publicKey\":{\"type\":\"string\"}}}}}}}}},\"/api/push/subscriptions\":{\"post\":{\"tags\":[\"notifications\"],\"summary\":\"Register a Web Push subscription\",\"security\":[],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}},\"responses\":{\"201\":{\"description\":\"Subscription saved\"}}},\"delete\":{\"tags\":[\"notifications\"],\"summary\":\"Remove a Web Push subscription\",\"security\":[],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"required\":[\"endpoint\"],\"properties\":{\"endpoint\":{\"type\":\"string\",\"format\":\"uri\"}}}}}},\"responses\":{\"204\":{\"description\":\"Subscription removed\"}}}},\"/webhooks/{provider}\":{\"post\":{\"tags\":[\"webhooks\"],\"summary\":\"Receive a provider webhook\",\"security\":[],\"parameters\":[{\"name\":\"provider\",\"in\":\"path\",\"required\":true,\"schema\":{\"type\":\"string\"}}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}},\"responses\":{\"202\":{\"description\":\"Webhook accepted\"},\"401\":{\"$ref\":\"#/components/responses/Unauthorized\"},\"413\":{\"$ref\":\"#/components/responses/PayloadTooLarge\"}}}},\"/restart/{jobId}\":{\"post\":{\"tags\":[\"jobs\"],\"summary\":\"Create a new run from the active workflow revision\",\"parameters\":[{\"$ref\":\"#/components/parameters/JobId\"}],\"responses\":{\"201\":{\"description\":\"New job created\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"integer\"}}}}}},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}}},\"/admin/reload-secrets\":{\"post\":{\"tags\":[\"secrets\"],\"summary\":\"Reload legacy in-memory secrets\",\"responses\":{\"200\":{\"description\":\"Secrets reloaded\"},\"403\":{\"$ref\":\"#/components/responses/Forbidden\"}}}}}"),
|
|
1882
|
+
paths: /* @__PURE__ */ JSON.parse("{\"/api\":{\"get\":{\"tags\":[\"discovery\"],\"summary\":\"Get this OpenAPI specification\",\"security\":[],\"responses\":{\"200\":{\"description\":\"OpenAPI JSON document\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}}}}},\"/api/api-keys\":{\"get\":{\"tags\":[\"discovery\"],\"summary\":\"List active API keys\",\"responses\":{\"200\":{\"description\":\"API key metadata\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/ApiKeyList\"}}}}}},\"post\":{\"tags\":[\"discovery\"],\"summary\":\"Issue a scoped API key\",\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/ApiKeyIssue\"}}}},\"responses\":{\"201\":{\"description\":\"Key metadata and one-time token\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/ApiKeyCreated\"}}}}}}},\"/api/api-keys/{keyId}\":{\"delete\":{\"tags\":[\"discovery\"],\"summary\":\"Revoke an API key\",\"parameters\":[{\"name\":\"keyId\",\"in\":\"path\",\"required\":true,\"schema\":{\"type\":\"string\",\"format\":\"uuid\"}}],\"responses\":{\"204\":{\"description\":\"Key revoked\"},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}}},\"/api/jobs\":{\"get\":{\"tags\":[\"jobs\"],\"summary\":\"List jobs\",\"security\":[],\"parameters\":[{\"$ref\":\"#/components/parameters/AfterId\"},{\"$ref\":\"#/components/parameters/BeforeId\"},{\"$ref\":\"#/components/parameters/Limit\"},{\"$ref\":\"#/components/parameters/Filter\"},{\"$ref\":\"#/components/parameters/WorkflowFilter\"}],\"responses\":{\"200\":{\"description\":\"Dashboard job list\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/JobList\"}}}}}}},\"/api/dispatch/{trigger}\":{\"post\":{\"tags\":[\"jobs\"],\"summary\":\"Dispatch a workflow trigger with manual inputs\",\"security\":[{\"bearerAuth\":[]},{\"basicAuth\":[]}],\"parameters\":[{\"name\":\"trigger\",\"in\":\"path\",\"required\":true,\"schema\":{\"type\":\"string\"}}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}},\"responses\":{\"202\":{\"description\":\"Jobs queued\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}},\"401\":{\"$ref\":\"#/components/responses/Unauthorized\"}}}},\"/api/workflows/{workflowId}/run\":{\"post\":{\"tags\":[\"jobs\"],\"summary\":\"Run the latest saved workflow revision immediately\",\"security\":[{\"oidcSessionCookie\":[]}],\"parameters\":[{\"name\":\"workflowId\",\"in\":\"path\",\"required\":true,\"schema\":{\"type\":\"string\"}}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}},\"responses\":{\"202\":{\"description\":\"Jobs queued\"},\"400\":{\"$ref\":\"#/components/responses/ValidationError\"},\"404\":{\"$ref\":\"#/components/responses/NotFound\"},\"401\":{\"$ref\":\"#/components/responses/Unauthorized\"}}}},\"/api/jobs/{jobId}/wait\":{\"get\":{\"tags\":[\"jobs\"],\"summary\":\"Wait for a job to reach a terminal state\",\"parameters\":[{\"$ref\":\"#/components/parameters/JobId\"},{\"name\":\"timeout\",\"in\":\"query\",\"schema\":{\"type\":\"integer\",\"minimum\":0,\"maximum\":120000,\"default\":30000}}],\"responses\":{\"200\":{\"description\":\"Latest job state\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}}},\"/api/jobs/{jobId}/cancel\":{\"post\":{\"tags\":[\"jobs\"],\"summary\":\"Cancel an active job\",\"parameters\":[{\"$ref\":\"#/components/parameters/JobId\"}],\"responses\":{\"200\":{\"description\":\"Job cancelled\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/JobStatus\"}}}},\"404\":{\"$ref\":\"#/components/responses/NotFound\"},\"409\":{\"$ref\":\"#/components/responses/Conflict\"}}}},\"/api/jobs/{jobId}/secrets\":{\"get\":{\"tags\":[\"jobs\"],\"summary\":\"Get secrets for an assigned worker job\",\"security\":[{\"workerBearerAuth\":[]}],\"parameters\":[{\"$ref\":\"#/components/parameters/JobId\"},{\"$ref\":\"#/components/parameters/WorkerId\"}],\"responses\":{\"200\":{\"description\":\"Decrypted job secrets\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/Secrets\"}}}},\"403\":{\"$ref\":\"#/components/responses/Forbidden\"}}}},\"/api/runs/{jobId}\":{\"get\":{\"tags\":[\"jobs\"],\"summary\":\"Get a run view\",\"parameters\":[{\"$ref\":\"#/components/parameters/JobId\"}],\"responses\":{\"200\":{\"description\":\"Run details\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/RunView\"}}}},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}}},\"/api/runs/{jobId}/artifacts/{path}\":{\"get\":{\"tags\":[\"jobs\"],\"summary\":\"Download an artifact\",\"parameters\":[{\"$ref\":\"#/components/parameters/JobId\"},{\"name\":\"path\",\"in\":\"path\",\"required\":true,\"schema\":{\"type\":\"string\"}}],\"responses\":{\"200\":{\"description\":\"Artifact bytes\",\"content\":{\"application/octet-stream\":{\"schema\":{\"type\":\"string\",\"format\":\"binary\"}}}},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}}},\"/api/runs/{jobId}/ai-help\":{\"post\":{\"tags\":[\"jobs\"],\"summary\":\"Ask AI to diagnose a failed step\",\"parameters\":[{\"$ref\":\"#/components/parameters/JobId\"}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"required\":[\"stepId\"],\"properties\":{\"stepId\":{\"type\":\"string\"}}}}}},\"responses\":{\"200\":{\"description\":\"AI diagnosis\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"properties\":{\"answer\":{\"type\":\"string\"}}}}}},\"401\":{\"$ref\":\"#/components/responses/Unauthorized\"},\"502\":{\"description\":\"AI provider failure\"},\"503\":{\"description\":\"AI help is not configured\"}}}},\"/api/workflows/validate\":{\"post\":{\"tags\":[\"workflows\"],\"summary\":\"Validate workflow YAML\",\"security\":[{\"oidcSessionCookie\":[]}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/WorkflowSource\"}}}},\"responses\":{\"200\":{\"description\":\"Valid workflow definitions\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/ValidationResult\"}}}},\"422\":{\"$ref\":\"#/components/responses/ValidationError\"}}}},\"/api/ai/workflow-help\":{\"post\":{\"tags\":[\"workflows\"],\"summary\":\"Get a workflow YAML suggestion\",\"security\":[{\"oidcSessionCookie\":[]}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"required\":[\"request\"],\"properties\":{\"request\":{\"type\":\"string\"},\"sourceYaml\":{\"type\":\"string\"}}}}}},\"responses\":{\"200\":{\"description\":\"Workflow YAML suggestion stream\",\"content\":{\"text/event-stream\":{\"schema\":{\"type\":\"string\"}}}},\"400\":{\"$ref\":\"#/components/responses/ValidationError\"},\"401\":{\"$ref\":\"#/components/responses/Unauthorized\"},\"502\":{\"description\":\"AI provider failure\"},\"503\":{\"description\":\"AI help is not configured\"}}}},\"/api/workflows\":{\"get\":{\"tags\":[\"workflows\"],\"summary\":\"List workflows\",\"security\":[{\"oidcSessionCookie\":[]}],\"responses\":{\"200\":{\"description\":\"Workflow list\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"properties\":{\"workflows\":{\"type\":\"array\",\"items\":{\"$ref\":\"#/components/schemas/Workflow\"}}}}}}}}}},\"/api/users\":{\"get\":{\"tags\":[\"users\"],\"summary\":\"List registered OIDC users\",\"description\":\"Administrator OIDC sessions only. Bearer and basic credentials are not accepted.\",\"security\":[{\"oidcAdminSession\":[]}],\"responses\":{\"200\":{\"description\":\"User roster\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/UserList\"}}}},\"401\":{\"$ref\":\"#/components/responses/Unauthorized\"},\"403\":{\"$ref\":\"#/components/responses/Forbidden\"}}}},\"/api/users/{subject}/role\":{\"put\":{\"tags\":[\"users\"],\"summary\":\"Change a user's OIDC role\",\"description\":\"Administrator OIDC sessions only. The final administrator cannot be demoted.\",\"security\":[{\"oidcAdminSession\":[]}],\"parameters\":[{\"$ref\":\"#/components/parameters/UserSubject\"}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/UserRoleUpdate\"}}}},\"responses\":{\"200\":{\"description\":\"Role updated\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/UserRoleResponse\"}}}},\"400\":{\"$ref\":\"#/components/responses/ValidationError\"},\"401\":{\"$ref\":\"#/components/responses/Unauthorized\"},\"403\":{\"$ref\":\"#/components/responses/Forbidden\"},\"404\":{\"$ref\":\"#/components/responses/NotFound\"},\"409\":{\"$ref\":\"#/components/responses/Conflict\"}}}},\"/api/workflows/{workflowId}\":{\"get\":{\"tags\":[\"workflows\"],\"summary\":\"Get a workflow or historical revision\",\"security\":[{\"oidcSessionCookie\":[]}],\"parameters\":[{\"$ref\":\"#/components/parameters/WorkflowId\"},{\"$ref\":\"#/components/parameters/Revision\"}],\"responses\":{\"200\":{\"description\":\"Workflow definition\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/Workflow\"}}}},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}},\"put\":{\"tags\":[\"workflows\"],\"summary\":\"Save a workflow draft\",\"security\":[{\"oidcSessionCookie\":[]}],\"parameters\":[{\"$ref\":\"#/components/parameters/WorkflowId\"}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/WorkflowSave\"}}}},\"responses\":{\"200\":{\"description\":\"Draft saved\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/Workflow\"}}}},\"422\":{\"$ref\":\"#/components/responses/ValidationError\"}}},\"delete\":{\"tags\":[\"workflows\"],\"summary\":\"Delete a workflow and its revisions\",\"security\":[{\"oidcSessionCookie\":[]}],\"parameters\":[{\"$ref\":\"#/components/parameters/WorkflowId\"}],\"responses\":{\"204\":{\"description\":\"Workflow deleted\"},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}}},\"/api/workflows/{workflowId}/publish\":{\"post\":{\"tags\":[\"workflows\"],\"summary\":\"Publish the latest workflow revision\",\"security\":[{\"oidcSessionCookie\":[]}],\"parameters\":[{\"$ref\":\"#/components/parameters/WorkflowId\"}],\"responses\":{\"200\":{\"description\":\"Workflow published\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/Workflow\"}}}},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}}},\"/api/secrets\":{\"get\":{\"tags\":[\"secrets\"],\"summary\":\"List secret names\",\"security\":[{\"oidcSessionCookie\":[]}],\"responses\":{\"200\":{\"description\":\"Secret names\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/SecretNames\"}}}}}}},\"/api/secrets/{name}\":{\"put\":{\"tags\":[\"secrets\"],\"summary\":\"Create or replace an encrypted secret\",\"security\":[{\"oidcSessionCookie\":[]}],\"parameters\":[{\"$ref\":\"#/components/parameters/SecretName\"}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/SecretValue\"}}}},\"responses\":{\"204\":{\"description\":\"Secret saved\"}}},\"delete\":{\"tags\":[\"secrets\"],\"summary\":\"Delete a secret\",\"security\":[{\"oidcSessionCookie\":[]}],\"parameters\":[{\"$ref\":\"#/components/parameters/SecretName\"}],\"responses\":{\"204\":{\"description\":\"Secret deleted\"},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}}},\"/api/events\":{\"get\":{\"tags\":[\"events\"],\"summary\":\"Subscribe to runner events\",\"security\":[],\"responses\":{\"200\":{\"description\":\"Server-sent event stream\",\"content\":{\"text/event-stream\":{\"schema\":{\"type\":\"string\"}}}}}},\"post\":{\"tags\":[\"events\"],\"summary\":\"Publish a worker job-change event\",\"security\":[{\"workerBearerAuth\":[]}],\"requestBody\":{\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/JobEvent\"}}}},\"responses\":{\"202\":{\"description\":\"Event accepted\"}}}},\"/api/push/public-key\":{\"get\":{\"tags\":[\"notifications\"],\"summary\":\"Get the Web Push public key\",\"security\":[],\"responses\":{\"200\":{\"description\":\"VAPID public key\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"properties\":{\"publicKey\":{\"type\":\"string\"}}}}}}}}},\"/api/push/subscriptions\":{\"post\":{\"tags\":[\"notifications\"],\"summary\":\"Register a Web Push subscription\",\"security\":[],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}},\"responses\":{\"201\":{\"description\":\"Subscription saved\"}}},\"delete\":{\"tags\":[\"notifications\"],\"summary\":\"Remove a Web Push subscription\",\"security\":[],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"required\":[\"endpoint\"],\"properties\":{\"endpoint\":{\"type\":\"string\",\"format\":\"uri\"}}}}}},\"responses\":{\"204\":{\"description\":\"Subscription removed\"}}}},\"/webhooks/{provider}\":{\"post\":{\"tags\":[\"webhooks\"],\"summary\":\"Receive a provider webhook\",\"security\":[],\"parameters\":[{\"name\":\"provider\",\"in\":\"path\",\"required\":true,\"schema\":{\"type\":\"string\"}}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}},\"responses\":{\"202\":{\"description\":\"Webhook accepted\"},\"401\":{\"$ref\":\"#/components/responses/Unauthorized\"},\"413\":{\"$ref\":\"#/components/responses/PayloadTooLarge\"}}}},\"/restart/{jobId}\":{\"post\":{\"tags\":[\"jobs\"],\"summary\":\"Create a new run from the active workflow revision\",\"parameters\":[{\"$ref\":\"#/components/parameters/JobId\"}],\"responses\":{\"201\":{\"description\":\"New job created\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"integer\"}}}}}},\"404\":{\"$ref\":\"#/components/responses/NotFound\"}}}},\"/admin/reload-secrets\":{\"post\":{\"tags\":[\"secrets\"],\"summary\":\"Reload legacy in-memory secrets\",\"responses\":{\"200\":{\"description\":\"Secrets reloaded\"},\"403\":{\"$ref\":\"#/components/responses/Forbidden\"}}}}}"),
|
|
1882
1883
|
components: {
|
|
1883
1884
|
securitySchemes: {
|
|
1884
1885
|
bearerAuth: {
|
|
@@ -1894,6 +1895,12 @@ var nn = {
|
|
|
1894
1895
|
in: "cookie",
|
|
1895
1896
|
name: "runner_oidc_session"
|
|
1896
1897
|
},
|
|
1898
|
+
oidcAdminSession: {
|
|
1899
|
+
type: "apiKey",
|
|
1900
|
+
in: "cookie",
|
|
1901
|
+
name: "runner_oidc_session",
|
|
1902
|
+
description: "Requires an authenticated OIDC session with administrator role."
|
|
1903
|
+
},
|
|
1897
1904
|
workerBearerAuth: {
|
|
1898
1905
|
type: "http",
|
|
1899
1906
|
scheme: "bearer",
|
|
@@ -1919,6 +1926,15 @@ var nn = {
|
|
|
1919
1926
|
pattern: "^[a-z0-9-]+$"
|
|
1920
1927
|
}
|
|
1921
1928
|
},
|
|
1929
|
+
UserSubject: {
|
|
1930
|
+
name: "subject",
|
|
1931
|
+
in: "path",
|
|
1932
|
+
required: !0,
|
|
1933
|
+
schema: {
|
|
1934
|
+
type: "string",
|
|
1935
|
+
minLength: 1
|
|
1936
|
+
}
|
|
1937
|
+
},
|
|
1922
1938
|
Revision: {
|
|
1923
1939
|
name: "revision",
|
|
1924
1940
|
in: "query",
|
|
@@ -2039,6 +2055,47 @@ var nn = {
|
|
|
2039
2055
|
enabled: { type: "boolean" }
|
|
2040
2056
|
}
|
|
2041
2057
|
},
|
|
2058
|
+
User: {
|
|
2059
|
+
type: "object",
|
|
2060
|
+
required: ["id", "role"],
|
|
2061
|
+
properties: {
|
|
2062
|
+
id: { type: "string" },
|
|
2063
|
+
name: {
|
|
2064
|
+
type: "string",
|
|
2065
|
+
nullable: !0
|
|
2066
|
+
},
|
|
2067
|
+
email: {
|
|
2068
|
+
type: "string",
|
|
2069
|
+
format: "email",
|
|
2070
|
+
nullable: !0
|
|
2071
|
+
},
|
|
2072
|
+
role: {
|
|
2073
|
+
type: "string",
|
|
2074
|
+
enum: ["user", "admin"]
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
},
|
|
2078
|
+
UserList: {
|
|
2079
|
+
type: "object",
|
|
2080
|
+
required: ["users"],
|
|
2081
|
+
properties: { users: {
|
|
2082
|
+
type: "array",
|
|
2083
|
+
items: { $ref: "#/components/schemas/User" }
|
|
2084
|
+
} }
|
|
2085
|
+
},
|
|
2086
|
+
UserRoleUpdate: {
|
|
2087
|
+
type: "object",
|
|
2088
|
+
required: ["role"],
|
|
2089
|
+
properties: { role: {
|
|
2090
|
+
type: "string",
|
|
2091
|
+
enum: ["user", "admin"]
|
|
2092
|
+
} }
|
|
2093
|
+
},
|
|
2094
|
+
UserRoleResponse: {
|
|
2095
|
+
type: "object",
|
|
2096
|
+
required: ["user"],
|
|
2097
|
+
properties: { user: { $ref: "#/components/schemas/User" } }
|
|
2098
|
+
},
|
|
2042
2099
|
WorkflowSource: {
|
|
2043
2100
|
type: "object",
|
|
2044
2101
|
required: ["sourceYaml"],
|
|
@@ -12196,6 +12253,9 @@ var Zh = 6e5, Qh = 288e5, $h = "runner_oidc_session", eg = class {
|
|
|
12196
12253
|
let n = this.cookieToken(e), r = n ? this.sessions.get(n) : void 0;
|
|
12197
12254
|
r && (r.role = t);
|
|
12198
12255
|
}
|
|
12256
|
+
setRoleForUser(e, t) {
|
|
12257
|
+
for (let n of this.sessions.values()) n.user.id === e && (n.role = t);
|
|
12258
|
+
}
|
|
12199
12259
|
roleFromCookie(e) {
|
|
12200
12260
|
return this.sessionFromCookie(e)?.role;
|
|
12201
12261
|
}
|
|
@@ -12464,6 +12524,32 @@ var mg = pg(dg, fg, ug), hg = "/* global document, window, localStorage, navigat
|
|
|
12464
12524
|
} else if (!this.requireAdmin(e, t)) return;
|
|
12465
12525
|
return this.renderAppShell(t);
|
|
12466
12526
|
}
|
|
12527
|
+
if (e.method === "GET" && n.pathname === "/api/users") return this.requireAdminSession(e, t) ? (await this.workflowsLoaded, t.writeHead(200, {
|
|
12528
|
+
"Cache-Control": "no-store",
|
|
12529
|
+
"Content-Type": "application/json; charset=utf-8"
|
|
12530
|
+
}), t.end(JSON.stringify({ users: await this.oidcUsers.list() }))) : void 0;
|
|
12531
|
+
let a = n.pathname.match(/^\/api\/users\/([^/]+)\/role$/);
|
|
12532
|
+
if (e.method === "PUT" && a) {
|
|
12533
|
+
if (!this.requireAdminSession(e, t)) return;
|
|
12534
|
+
let n = await this.readJson(e, t);
|
|
12535
|
+
if (!n || t.headersSent) return;
|
|
12536
|
+
if (n.role !== "user" && n.role !== "admin") return t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "role must be either \"user\" or \"admin\"" }));
|
|
12537
|
+
let r;
|
|
12538
|
+
try {
|
|
12539
|
+
r = decodeURIComponent(a[1]);
|
|
12540
|
+
} catch {
|
|
12541
|
+
return t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "Invalid user subject" }));
|
|
12542
|
+
}
|
|
12543
|
+
let i = await this.oidcUsers.setRole(r, n.role);
|
|
12544
|
+
if (i === "not-found") return t.writeHead(404, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "User not found" }));
|
|
12545
|
+
if (i === "last-admin") return t.writeHead(409, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "Cannot demote the last administrator" }));
|
|
12546
|
+
this.oidc?.setRoleForUser(r, n.role);
|
|
12547
|
+
let o = (await this.oidcUsers.list()).find((e) => e.id === r);
|
|
12548
|
+
return t.writeHead(200, {
|
|
12549
|
+
"Cache-Control": "no-store",
|
|
12550
|
+
"Content-Type": "application/json; charset=utf-8"
|
|
12551
|
+
}), t.end(JSON.stringify({ user: o }));
|
|
12552
|
+
}
|
|
12467
12553
|
if (n.pathname === "/api/api-keys") {
|
|
12468
12554
|
if (!this.isAdmin(e) && !this.oidc?.userFromCookie(e.headers.cookie) && !this.oidcBearer(e)) return this.requireAdmin(e, t);
|
|
12469
12555
|
if (e.method === "GET") {
|
|
@@ -12484,57 +12570,57 @@ var mg = pg(dg, fg, ug), hg = "/* global document, window, localStorage, navigat
|
|
|
12484
12570
|
}
|
|
12485
12571
|
}
|
|
12486
12572
|
}
|
|
12487
|
-
let
|
|
12488
|
-
if (
|
|
12573
|
+
let o = n.pathname.match(/^\/api\/api-keys\/([^/]+)$/);
|
|
12574
|
+
if (o && e.method === "DELETE") {
|
|
12489
12575
|
if (!this.isAdmin(e) && !this.oidc?.userFromCookie(e.headers.cookie) && !this.oidcBearer(e)) return this.requireAdmin(e, t);
|
|
12490
12576
|
if (this.oidc?.userFromCookie(e.headers.cookie) || this.oidcBearer(e)) {
|
|
12491
|
-
let n = await this.revokeOidcToken(e,
|
|
12577
|
+
let n = await this.revokeOidcToken(e, o[1]);
|
|
12492
12578
|
if (n) return t.writeHead(n.status).end();
|
|
12493
12579
|
}
|
|
12494
|
-
let n = await this.apiKeys.revoke(
|
|
12580
|
+
let n = await this.apiKeys.revoke(o[1]);
|
|
12495
12581
|
t.writeHead(n ? 204 : 404).end();
|
|
12496
12582
|
return;
|
|
12497
12583
|
}
|
|
12498
|
-
let
|
|
12499
|
-
if (e.method === "GET" &&
|
|
12584
|
+
let s = n.pathname.match(/^\/settings\/workflows\/(new|[a-z0-9-]+)$/);
|
|
12585
|
+
if (e.method === "GET" && s) {
|
|
12500
12586
|
if (!this.requireAuthenticatedUser(e, t)) return;
|
|
12501
|
-
|
|
12587
|
+
s[1] === "new" || s[1];
|
|
12502
12588
|
let r = n.searchParams.get("revision");
|
|
12503
12589
|
return r === null || Number(r), this.renderAppShell(t);
|
|
12504
12590
|
}
|
|
12505
|
-
let
|
|
12506
|
-
if (e.method === "GET" &&
|
|
12591
|
+
let c = n.pathname.match(/^\/workflows\/(new|[a-z0-9-]+)$/);
|
|
12592
|
+
if (e.method === "GET" && c) {
|
|
12507
12593
|
if (!this.requireAuthenticatedUser(e, t)) return;
|
|
12508
|
-
let r =
|
|
12594
|
+
let r = c[1] === "new" ? "" : c[1], i = r ? `/settings/workflows/${r}` : "/settings/workflows/new";
|
|
12509
12595
|
return t.writeHead(302, { Location: `${i}${n.search}` }), t.end();
|
|
12510
12596
|
}
|
|
12511
12597
|
if (e.method === "GET" && n.pathname === "/api/jobs") {
|
|
12512
12598
|
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 ? gg : Number(i);
|
|
12513
12599
|
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 > _g ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: `limit must be an integer from 1 to ${_g}` }))) : 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);
|
|
12514
12600
|
}
|
|
12515
|
-
let
|
|
12516
|
-
if (e.method === "POST" &&
|
|
12517
|
-
let
|
|
12518
|
-
if (e.method === "POST" &&
|
|
12519
|
-
let
|
|
12520
|
-
if (e.method === "GET" &&
|
|
12601
|
+
let l = n.pathname.match(/^\/api\/dispatch\/([a-z0-9-]+)$/);
|
|
12602
|
+
if (e.method === "POST" && l) return this.handleDispatch(e, t, l[1]);
|
|
12603
|
+
let u = n.pathname.match(/^\/api\/workflows\/([a-z0-9-]+)\/run$/);
|
|
12604
|
+
if (e.method === "POST" && u) return this.handleWorkflowRun(e, t, u[1]);
|
|
12605
|
+
let d = n.pathname.match(/^\/api\/jobs\/(\d+)\/wait$/);
|
|
12606
|
+
if (e.method === "GET" && d) return this.handleJobWait(d[1], n.searchParams.get("timeout"), t);
|
|
12521
12607
|
if (e.method === "GET" && n.pathname === "/api/events") return this.events.subscribe(e, t);
|
|
12522
12608
|
if (e.method === "GET" && n.pathname === "/api/push/public-key") return this.handlePushPublicKey(t);
|
|
12523
12609
|
if (e.method === "POST" && n.pathname === "/api/push/subscriptions") return this.handlePushSubscribe(e, t);
|
|
12524
12610
|
if (e.method === "DELETE" && n.pathname === "/api/push/subscriptions") return this.handlePushUnsubscribe(e, t);
|
|
12525
12611
|
if (n.pathname === "/api/workflows/validate" && e.method === "POST") return this.handleWorkflowValidation(e, t);
|
|
12526
12612
|
if (n.pathname === "/api/secrets" && e.method === "GET") return this.handleSecretList(e, t);
|
|
12527
|
-
let
|
|
12528
|
-
if (
|
|
12529
|
-
if (
|
|
12530
|
-
let
|
|
12531
|
-
if (
|
|
12532
|
-
let
|
|
12533
|
-
if (
|
|
12613
|
+
let f = n.pathname.match(/^\/api\/secrets\/([A-Z][A-Z0-9_]*)$/);
|
|
12614
|
+
if (f && e.method === "PUT") return this.handleSecretSave(e, t, f[1]);
|
|
12615
|
+
if (f && e.method === "DELETE") return this.handleSecretDelete(e, t, f[1]);
|
|
12616
|
+
let p = n.pathname.match(/^\/api\/jobs\/(\d+)\/secrets$/);
|
|
12617
|
+
if (p && e.method === "GET") return this.handleJobSecrets(e, t, p[1]);
|
|
12618
|
+
let m = n.pathname.match(/^\/api\/jobs\/(\d+)\/cancel$/);
|
|
12619
|
+
if (m && e.method === "POST") return this.handleCancelJob(e, t, m[1]);
|
|
12534
12620
|
if (n.pathname === "/api/workflows" && e.method === "GET") return this.handleWorkflowList(e, t);
|
|
12535
|
-
let
|
|
12536
|
-
if (
|
|
12537
|
-
let [, r, i] =
|
|
12621
|
+
let g = n.pathname.match(/^\/api\/workflows\/([a-z0-9-]+)(\/publish)?$/);
|
|
12622
|
+
if (g) {
|
|
12623
|
+
let [, r, i] = g;
|
|
12538
12624
|
if (e.method === "GET" && !i) return this.handleWorkflowGet(e, t, r, n.searchParams.get("revision"));
|
|
12539
12625
|
if (e.method === "PUT" && !i) return this.handleWorkflowSave(e, t, r);
|
|
12540
12626
|
if (e.method === "DELETE" && !i) return this.handleWorkflowDelete(e, t, r);
|
|
@@ -12546,8 +12632,8 @@ var mg = pg(dg, fg, ug), hg = "/* global document, window, localStorage, navigat
|
|
|
12546
12632
|
let r = n.pathname.replace("/runs/", "");
|
|
12547
12633
|
return this.renderRunDetails(r, t, "html", await this.hasScope(e, "logs:read"));
|
|
12548
12634
|
}
|
|
12549
|
-
let
|
|
12550
|
-
if (e.method === "POST" &&
|
|
12635
|
+
let v = n.pathname.match(/^\/api\/runs\/(\d+)\/ai-help$/);
|
|
12636
|
+
if (e.method === "POST" && v) return this.handleAiHelp(e, t, v[1]);
|
|
12551
12637
|
if (e.method === "GET" && n.pathname.startsWith("/api/runs/")) {
|
|
12552
12638
|
let r = n.pathname.match(/^\/api\/runs\/(\d+)\/diagnostics$/);
|
|
12553
12639
|
if (r) return this.handleDiagnostics(e, t, r[1]);
|
|
@@ -12901,6 +12987,11 @@ var mg = pg(dg, fg, ug), hg = "/* global document, window, localStorage, navigat
|
|
|
12901
12987
|
}
|
|
12902
12988
|
return t.writeHead(401, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "Unauthorized" })), !1;
|
|
12903
12989
|
}
|
|
12990
|
+
requireAdminSession(e, t) {
|
|
12991
|
+
if (this.isAdmin(e)) return !0;
|
|
12992
|
+
let n = !!this.oidc?.userFromCookie(e.headers.cookie);
|
|
12993
|
+
return t.writeHead(n ? 403 : 401, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: n ? "Administrator role required" : "Authentication required" })), !1;
|
|
12994
|
+
}
|
|
12904
12995
|
async readJson(e, t) {
|
|
12905
12996
|
let { rawBuffer: n } = await this.readRequest(e, t);
|
|
12906
12997
|
if (!n || t.headersSent) return null;
|
package/dist/server.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { WebhookPreprocessor, WebhookServerOptions } from
|
|
1
|
+
import type { WebhookPreprocessor, WebhookServerOptions } from "./types.js";
|
|
2
2
|
export declare class WebhookServer {
|
|
3
3
|
private server;
|
|
4
4
|
private preprocessors;
|
|
@@ -50,6 +50,7 @@ export declare class WebhookServer {
|
|
|
50
50
|
private requireScope;
|
|
51
51
|
private matchesToken;
|
|
52
52
|
private requireAdmin;
|
|
53
|
+
private requireAdminSession;
|
|
53
54
|
private readJson;
|
|
54
55
|
private handleWorkflowValidation;
|
|
55
56
|
private handleWorkflowList;
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAc,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAkBxF,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,aAAa,CAA0C;IAC/D,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,IAAI,CAAC,CAAa;IAC1B,OAAO,CAAC,SAAS,CAA4B;IAC7C,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;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAc,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAkBxF,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,aAAa,CAA0C;IAC/D,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,IAAI,CAAC,CAAa;IAC1B,OAAO,CAAC,SAAS,CAA4B;IAC7C,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;IAmBzC,oBAAoB,CAAC,YAAY,EAAE,mBAAmB;YAIxC,aAAa;IA8Z3B;;OAEG;YACW,aAAa;YA0Bb,cAAc;YAcd,iBAAiB;YA2CjB,aAAa;YAsBb,iBAAiB;YA4BjB,WAAW;YAwBX,UAAU;YAyBV,cAAc;IAsD5B,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,QAAQ;YAIF,QAAQ;IAatB,OAAO,CAAC,wBAAwB;YAQlB,eAAe;YAcf,kBAAkB;IA0BhC,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,OAAO;YAID,cAAc;YAsBd,cAAc;YA6Bd,eAAe;IAW7B,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,UAAU;YAKJ,YAAY;IAO1B,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,mBAAmB;YAQb,QAAQ;YAYR,wBAAwB;YAcxB,kBAAkB;YAOlB,iBAAiB;YAoBjB,kBAAkB;YAoBlB,oBAAoB;YASpB,qBAAqB;YAWrB,gBAAgB;YAMhB,gBAAgB;YAiBhB,kBAAkB;YASlB,gBAAgB;IAc9B;;OAEG;YACW,kBAAkB;YAWlB,iBAAiB;IA2B/B,OAAO,CAAC,mBAAmB;YASb,mBAAmB;YAoBnB,qBAAqB;IAcnC;;OAEG;YACW,eAAe;IAK7B,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,mBAAmB;YAgBb,mBAAmB;IAwBjC;;OAEG;YACW,gBAAgB;YAsChB,gBAAgB;YAiBhB,sBAAsB;YAoBtB,YAAY;YAkEZ,oBAAoB;YA0CpB,eAAe;YAkBf,cAAc;IAS5B,OAAO,CAAC,MAAM;YAMA,UAAU;IAIlB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAU5C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAS5B"}
|
|
@@ -335,12 +335,14 @@ var b = class {
|
|
|
335
335
|
devDependencies: {
|
|
336
336
|
"@changesets/cli": "^2.31.1",
|
|
337
337
|
"@eslint/js": "^10.0.1",
|
|
338
|
+
"@tailwindcss/vite": "4.3.3",
|
|
338
339
|
"@types/node": "^26.5.1",
|
|
339
340
|
"@types/web-push": "^3.6.4",
|
|
340
341
|
"@typescript-eslint/eslint-plugin": "^8.70.0",
|
|
341
342
|
"@typescript-eslint/parser": "^8.70.0",
|
|
342
343
|
eslint: "10.8.0",
|
|
343
344
|
marked: "^18.0.12",
|
|
345
|
+
tailwindcss: "4.3.3",
|
|
344
346
|
tsx: "4.23.13",
|
|
345
347
|
typescript: "6.0.3",
|
|
346
348
|
"typescript-eslint": "8.70.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloud-cli/on",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.67.0",
|
|
4
4
|
"description": "CLI entry point for the on plugin ecosystem.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@12.3.4",
|
|
@@ -35,12 +35,14 @@
|
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@changesets/cli": "^2.31.1",
|
|
37
37
|
"@eslint/js": "^10.0.1",
|
|
38
|
+
"@tailwindcss/vite": "4.3.3",
|
|
38
39
|
"@types/node": "^26.5.1",
|
|
39
40
|
"@types/web-push": "^3.6.4",
|
|
40
41
|
"@typescript-eslint/eslint-plugin": "^8.70.0",
|
|
41
42
|
"@typescript-eslint/parser": "^8.70.0",
|
|
42
43
|
"eslint": "10.8.0",
|
|
43
44
|
"marked": "^18.0.12",
|
|
45
|
+
"tailwindcss": "4.3.3",
|
|
44
46
|
"tsx": "4.23.13",
|
|
45
47
|
"typescript": "6.0.3",
|
|
46
48
|
"typescript-eslint": "8.70.0",
|