@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.
@@ -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;
@@ -0,0 +1,2 @@
1
+ import { t as e } from "./oidc-user-repository-C4HnJLyx.js";
2
+ export { e as OidcUserRepository };
@@ -1,9 +1,14 @@
1
- import type { OidcUser } from './oidc.js';
2
- export type OidcRole = 'user' | 'admin';
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;AAExC,qBAAa,kBAAkB;IACvB,IAAI;IASJ,MAAM,CAAC,IAAI,EAAE,QAAQ;IAMrB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAKxC,OAAO,CAAC,OAAO,EAAE,MAAM;CAI9B"}
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: 'user' | 'admin'): void;
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;
@@ -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;IAUvD,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;IAa5B,OAAO,CAAC,KAAK;IAKb,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,UAAU;CAUnB"}
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-CQ3FDHUe.js"),
108
- import("./worker-BwNyfSpp.js"),
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-BNQF3qnb.js")
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-CiprwzOj.js";
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 a = n.pathname.match(/^\/api\/api-keys\/([^/]+)$/);
12488
- if (a && e.method === "DELETE") {
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, a[1]);
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(a[1]);
12580
+ let n = await this.apiKeys.revoke(o[1]);
12495
12581
  t.writeHead(n ? 204 : 404).end();
12496
12582
  return;
12497
12583
  }
12498
- let o = n.pathname.match(/^\/settings\/workflows\/(new|[a-z0-9-]+)$/);
12499
- if (e.method === "GET" && o) {
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
- o[1] === "new" || o[1];
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 s = n.pathname.match(/^\/workflows\/(new|[a-z0-9-]+)$/);
12506
- if (e.method === "GET" && s) {
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 = s[1] === "new" ? "" : s[1], i = r ? `/settings/workflows/${r}` : "/settings/workflows/new";
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 c = n.pathname.match(/^\/api\/dispatch\/([a-z0-9-]+)$/);
12516
- if (e.method === "POST" && c) return this.handleDispatch(e, t, c[1]);
12517
- let l = n.pathname.match(/^\/api\/workflows\/([a-z0-9-]+)\/run$/);
12518
- if (e.method === "POST" && l) return this.handleWorkflowRun(e, t, l[1]);
12519
- let u = n.pathname.match(/^\/api\/jobs\/(\d+)\/wait$/);
12520
- if (e.method === "GET" && u) return this.handleJobWait(u[1], n.searchParams.get("timeout"), t);
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 d = n.pathname.match(/^\/api\/secrets\/([A-Z][A-Z0-9_]*)$/);
12528
- if (d && e.method === "PUT") return this.handleSecretSave(e, t, d[1]);
12529
- if (d && e.method === "DELETE") return this.handleSecretDelete(e, t, d[1]);
12530
- let f = n.pathname.match(/^\/api\/jobs\/(\d+)\/secrets$/);
12531
- if (f && e.method === "GET") return this.handleJobSecrets(e, t, f[1]);
12532
- let p = n.pathname.match(/^\/api\/jobs\/(\d+)\/cancel$/);
12533
- if (p && e.method === "POST") return this.handleCancelJob(e, t, p[1]);
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 m = n.pathname.match(/^\/api\/workflows\/([a-z0-9-]+)(\/publish)?$/);
12536
- if (m) {
12537
- let [, r, i] = m;
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 g = n.pathname.match(/^\/api\/runs\/(\d+)\/ai-help$/);
12550
- if (e.method === "POST" && g) return this.handleAiHelp(e, t, g[1]);
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 './types.js';
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;
@@ -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;IAczC,oBAAoB,CAAC,YAAY,EAAE,mBAAmB;YAIxC,aAAa;IA4V3B;;OAEG;YACW,aAAa;YA0Bb,cAAc;YASd,iBAAiB;YAwCjB,aAAa;YAiBb,iBAAiB;YA0BjB,WAAW;YAwBX,UAAU;YAyBV,cAAc;IA8C5B,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,QAAQ;YAIF,QAAQ;IAatB,OAAO,CAAC,wBAAwB;YAQlB,eAAe;YAaf,kBAAkB;IAuBhC,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,OAAO;YAID,cAAc;YAYd,cAAc;YAmBd,eAAe;IAM7B,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,UAAU;YAKJ,YAAY;IAO1B,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,YAAY;YAqBN,QAAQ;YAYR,wBAAwB;YAcxB,kBAAkB;YAOlB,iBAAiB;YAcjB,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;YAWnB,qBAAqB;IAWnC;;OAEG;YACW,eAAe;IAK7B,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,mBAAmB;YAcb,mBAAmB;IAwBjC;;OAEG;YACW,gBAAgB;YA+BhB,gBAAgB;YAiBhB,sBAAsB;YAetB,YAAY;YAsDZ,oBAAoB;YA4BpB,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"}
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.66.2",
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",
@@ -1,2 +0,0 @@
1
- import { t as e } from "./oidc-user-repository-CiprwzOj.js";
2
- export { e as OidcUserRepository };