@seekrit/cli 2.5.1 → 2.6.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.
Files changed (2) hide show
  1. package/dist/index.js +1441 -965
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { chmodSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
3
- import { z } from "zod";
3
+ import * as z$1 from "zod";
4
4
  import { Command } from "commander";
5
5
  import { arch, homedir, hostname, platform, tmpdir, userInfo } from "node:os";
6
6
  import { basename, dirname, join, parse, resolve } from "node:path";
@@ -17,48 +17,48 @@ const POLICY_DEFAULT_TTL_SECONDS = 604800;
17
17
  const POLICY_MIN_TTL_SECONDS = 3600;
18
18
  const POLICY_MAX_TTL_SECONDS = 7776e3;
19
19
  /** A bare hostname: no scheme, no port, no path, no wildcard. */
20
- const policyHostSchema = z.string().trim().min(1).max(253).toLowerCase().refine((h) => !/[:/\s*]/.test(h), { message: "host must be a bare hostname (no scheme, port, path, or wildcard)" }).refine((h) => /^[a-z0-9.-]+$/.test(h), { message: "host contains invalid characters" });
21
- const policyMethodSchema = z.string().trim().toUpperCase().regex(/^[A-Z]{3,10}$/, "method must be an HTTP method name");
20
+ const policyHostSchema = z$1.string().trim().min(1).max(253).toLowerCase().refine((h) => !/[:/\s*]/.test(h), { message: "host must be a bare hostname (no scheme, port, path, or wildcard)" }).refine((h) => /^[a-z0-9.-]+$/.test(h), { message: "host contains invalid characters" });
21
+ const policyMethodSchema = z$1.string().trim().toUpperCase().regex(/^[A-Z]{3,10}$/, "method must be an HTTP method name");
22
22
  /**
23
23
  * A path pattern. Must be absolute, because it is matched against a request
24
24
  * path — a relative pattern is a mistake that would silently match nothing.
25
25
  */
26
- const policyPathSchema = z.string().trim().min(1).max(512).startsWith("/", "path pattern must start with /").refine((p) => !p.includes("?"), { message: "path patterns match the path only, not the query" });
27
- const policySecretNameSchema = z.string().trim().regex(/^[A-Za-z0-9_]+$/, "secret names are letters, digits, and underscores");
26
+ const policyPathSchema = z$1.string().trim().min(1).max(512).startsWith("/", "path pattern must start with /").refine((p) => !p.includes("?"), { message: "path patterns match the path only, not the query" });
27
+ const policySecretNameSchema = z$1.string().trim().regex(/^[A-Za-z0-9_]+$/, "secret names are letters, digits, and underscores");
28
28
  /** A TCP port. 0 is refused: it never matches a connection, so a rule naming it is a mistake. */
29
- const policyPortSchema = z.number().int().min(1).max(65535);
30
- const agentPolicyRuleSchema = z.object({
29
+ const policyPortSchema = z$1.number().int().min(1).max(65535);
30
+ const agentPolicyRuleSchema = z$1.object({
31
31
  host: policyHostSchema,
32
- methods: z.array(policyMethodSchema).max(16).default([]),
33
- paths: z.array(policyPathSchema).max(64).default([]),
34
- allow: z.array(policySecretNameSchema).max(64).default([]),
35
- https_ports: z.array(policyPortSchema).max(32).optional(),
36
- http_ports: z.array(policyPortSchema).max(32).optional(),
37
- label: z.string().trim().max(120).optional()
32
+ methods: z$1.array(policyMethodSchema).max(16).default([]),
33
+ paths: z$1.array(policyPathSchema).max(64).default([]),
34
+ allow: z$1.array(policySecretNameSchema).max(64).default([]),
35
+ https_ports: z$1.array(policyPortSchema).max(32).optional(),
36
+ http_ports: z$1.array(policyPortSchema).max(32).optional(),
37
+ label: z$1.string().trim().max(120).optional()
38
38
  });
39
- z.object({
39
+ z$1.object({
40
40
  /** `ap1.<body>.<signature>` — opaque to the server. */
41
- bundle: z.string().min(16).max(262144) });
42
- z.object({
43
- name: z.string().trim().min(1).max(120),
44
- slug: z.string().trim().min(1).max(64).regex(/^[a-z0-9][a-z0-9-]*$/, "slug is lowercase letters, digits, and dashes"),
41
+ bundle: z$1.string().min(16).max(262144) });
42
+ z$1.object({
43
+ name: z$1.string().trim().min(1).max(120),
44
+ slug: z$1.string().trim().min(1).max(64).regex(/^[a-z0-9][a-z0-9-]*$/, "slug is lowercase letters, digits, and dashes"),
45
45
  /** The environment whose secrets this agent's policy may name. Optional. */
46
- environmentId: z.string().trim().min(1).max(64).optional()
46
+ environmentId: z$1.string().trim().min(1).max(64).optional()
47
47
  });
48
- z.object({
49
- name: z.string().trim().min(1).max(120).optional(),
50
- enabled: z.boolean().optional(),
51
- environmentId: z.string().trim().min(1).max(64).nullish()
48
+ z$1.object({
49
+ name: z$1.string().trim().min(1).max(120).optional(),
50
+ enabled: z$1.boolean().optional(),
51
+ environmentId: z$1.string().trim().min(1).max(64).nullish()
52
52
  });
53
- z.object({
53
+ z$1.object({
54
54
  host: policyHostSchema,
55
55
  /** How the agent reaches the host. Omit for a destination the operator fixed. */
56
- transport: z.object({
57
- scheme: z.enum(["https", "http"]),
56
+ transport: z$1.object({
57
+ scheme: z$1.enum(["https", "http"]),
58
58
  port: policyPortSchema
59
59
  }).optional(),
60
60
  method: policyMethodSchema,
61
- path: z.string().trim().min(1).max(2048),
61
+ path: z$1.string().trim().min(1).max(2048),
62
62
  secret: policySecretNameSchema.optional()
63
63
  });
64
64
  /**
@@ -170,7 +170,7 @@ async function policySignerThumbprint(jwk) {
170
170
  y: jwk.y
171
171
  });
172
172
  const digest = await crypto.subtle.digest("SHA-256", utf8(canonical));
173
- return base64url(new Uint8Array(digest));
173
+ return base64url$1(new Uint8Array(digest));
174
174
  }
175
175
  /**
176
176
  * Sign a draft bundle with the publishing admin's key, returning the `ap1.`
@@ -197,8 +197,8 @@ async function signAgentPolicy(privateKey, signerJwk, draft) {
197
197
  }, privateKey, bytes));
198
198
  return [
199
199
  "ap1",
200
- base64url(bytes),
201
- base64url(sig)
200
+ base64url$1(bytes),
201
+ base64url$1(sig)
202
202
  ].join(".");
203
203
  }
204
204
  /** A structurally invalid, unverifiable, or expired bundle. */
@@ -386,7 +386,7 @@ function utf8(text) {
386
386
  function utf8Decode$1(bytes) {
387
387
  return new TextDecoder().decode(bytes);
388
388
  }
389
- function base64url(bytes) {
389
+ function base64url$1(bytes) {
390
390
  let binary = "";
391
391
  for (const b of bytes) binary += String.fromCharCode(b);
392
392
  return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
@@ -399,10 +399,10 @@ function fromBase64url(text) {
399
399
  return out;
400
400
  }
401
401
  /** One aggregated cell: a dimension tuple and how many times it happened. */
402
- const activityEntrySchema = z.object({
402
+ const activityEntrySchema = z$1.object({
403
403
  host: policyHostSchema,
404
404
  method: policyMethodSchema,
405
- decision: z.enum([
405
+ decision: z$1.enum([
406
406
  "allow",
407
407
  "no_rule",
408
408
  "port_not_allowed",
@@ -419,27 +419,27 @@ const activityEntrySchema = z.object({
419
419
  * a review, because "rule 3 refused this" and "nothing covered this" call for
420
420
  * opposite changes.
421
421
  */
422
- ruleIndex: z.number().int().min(0).max(255).nullable(),
423
- count: z.number().int().min(1).max(1e6),
422
+ ruleIndex: z$1.number().int().min(0).max(255).nullable(),
423
+ count: z$1.number().int().min(1).max(1e6),
424
424
  /**
425
425
  * Secret names actually injected, name → count. Only meaningful on `allow`.
426
426
  * This is what lets a review say "rule 2 permits three secrets and the agent
427
427
  * has only ever used one" — the most useful narrowing there is, and impossible
428
428
  * to see from policy alone.
429
429
  */
430
- secrets: z.record(policySecretNameSchema, z.number().int().min(1)).optional()
430
+ secrets: z$1.record(policySecretNameSchema, z$1.number().int().min(1)).optional()
431
431
  });
432
- z.object({
432
+ z$1.object({
433
433
  /** Start of the window these counts cover (ISO 8601). */
434
- windowStart: z.string().trim().min(20).max(40),
434
+ windowStart: z$1.string().trim().min(20).max(40),
435
435
  /** Policy version in force while they were collected, for the ledger. */
436
- policyVersion: z.number().int().min(0).optional(),
436
+ policyVersion: z$1.number().int().min(0).optional(),
437
437
  /**
438
438
  * Capped so one report cannot be unbounded work. A proxy with more distinct
439
439
  * cells than this in a window has a policy far broader than a review can help
440
440
  * with, and truncating loudly beats accepting anything.
441
441
  */
442
- entries: z.array(activityEntrySchema).min(1).max(500)
442
+ entries: z$1.array(activityEntrySchema).min(1).max(500)
443
443
  });
444
444
  // ../../packages/core/src/agent-login.ts
445
445
  /** Where each kind of login is stored unless told otherwise. */
@@ -703,38 +703,38 @@ function countApplicable(proposals) {
703
703
  */
704
704
  const TASK_MAX_TTL_SECONDS = 43200;
705
705
  /** An EC P-256 public JWK, for a sender-constraint proof key. */
706
- const taskProofJwkSchema = z.object({
707
- kty: z.literal("EC"),
708
- crv: z.literal("P-256"),
709
- x: z.string().min(1).max(128),
710
- y: z.string().min(1).max(128)
706
+ const taskProofJwkSchema = z$1.object({
707
+ kty: z$1.literal("EC"),
708
+ crv: z$1.literal("P-256"),
709
+ x: z$1.string().min(1).max(128),
710
+ y: z$1.string().min(1).max(128)
711
711
  });
712
- z.object({
712
+ z$1.object({
713
713
  /**
714
714
  * The public `skd_…` segment of the minted token. Sent because the API never
715
715
  * sees the token at dispatch and still needs a readable handle for the audit
716
716
  * row and for a revoke to name — the id half of a credential, without the
717
717
  * secret half.
718
718
  */
719
- taskRef: z.string().trim().regex(/^skd_[0-9A-Za-z]+$/, "taskRef must be the skd_… segment of the minted token"),
719
+ taskRef: z$1.string().trim().regex(/^skd_[0-9A-Za-z]+$/, "taskRef must be the skd_… segment of the minted token"),
720
720
  /**
721
721
  * SHA-256 (base64url) of the token the dispatcher minted. The token itself
722
722
  * never reaches this API on the dispatch path — only on introspection, where
723
723
  * it is hashed and discarded.
724
724
  */
725
- tokenHash: z.string().trim().min(16).max(128),
725
+ tokenHash: z$1.string().trim().min(16).max(128),
726
726
  /**
727
727
  * Secret names this run may use. Omit for "whatever the agent's policy
728
728
  * allows" — mirroring `Session.scopes: Option<BTreeSet<String>>` in the proxy,
729
729
  * so absent means unnarrowed in both places.
730
730
  */
731
- scopes: z.array(policySecretNameSchema).max(64).optional(),
732
- ttlSeconds: z.number().int().min(60).max(TASK_MAX_TTL_SECONDS).optional(),
731
+ scopes: z$1.array(policySecretNameSchema).max(64).optional(),
732
+ ttlSeconds: z$1.number().int().min(60).max(TASK_MAX_TTL_SECONDS).optional(),
733
733
  /**
734
734
  * What this run is for, for the audit row and the operator's task list. Free
735
735
  * text, and **not** a security input: never put a secret value in it.
736
736
  */
737
- label: z.string().trim().max(200).optional(),
737
+ label: z$1.string().trim().max(200).optional(),
738
738
  /**
739
739
  * Public half of a proof key the presenter holds, recorded as an RFC 7638
740
740
  * thumbprint. See `AgentTaskSession.proofThumbprint` for what this does and —
@@ -742,9 +742,9 @@ z.object({
742
742
  */
743
743
  proofJwk: taskProofJwkSchema.optional()
744
744
  });
745
- z.object({
745
+ z$1.object({
746
746
  /** The presented token. In the body, never a URL — it is a credential. */
747
- token: z.string().trim().min(8).max(512) });
747
+ token: z$1.string().trim().min(8).max(512) });
748
748
  // ../../packages/core/src/archive.ts
749
749
  /**
750
750
  * The **break-glass archive** format: one signed JSON file holding everything
@@ -920,43 +920,43 @@ async function verifySignature(manifest, signature) {
920
920
  const publicKey = await crypto.subtle.importKey("raw", hexToBytes(signature.publicKey), { name: "Ed25519" }, false, ["verify"]);
921
921
  return crypto.subtle.verify({ name: "Ed25519" }, publicKey, hexToBytes(signature.value), signingPayload(manifest));
922
922
  }
923
- const sectionHeaderSchema = z.object({
924
- name: z.enum(ARCHIVE_SECTIONS),
925
- count: z.number().int().min(0),
926
- truncated: z.boolean(),
927
- digest: z.string().regex(/^sha256:[0-9a-f]{64}$/)
923
+ const sectionHeaderSchema = z$1.object({
924
+ name: z$1.enum(ARCHIVE_SECTIONS),
925
+ count: z$1.number().int().min(0),
926
+ truncated: z$1.boolean(),
927
+ digest: z$1.string().regex(/^sha256:[0-9a-f]{64}$/)
928
928
  });
929
- const manifestSchema = z.object({
930
- archiveId: z.string().min(1),
931
- createdAt: z.string().min(1),
932
- org: z.object({
933
- id: z.string(),
934
- slug: z.string(),
935
- name: z.string()
929
+ const manifestSchema = z$1.object({
930
+ archiveId: z$1.string().min(1),
931
+ createdAt: z$1.string().min(1),
932
+ org: z$1.object({
933
+ id: z$1.string(),
934
+ slug: z$1.string(),
935
+ name: z$1.string()
936
936
  }),
937
- producer: z.object({
938
- service: z.string(),
939
- environment: z.string(),
940
- formatVersion: z.string()
937
+ producer: z$1.object({
938
+ service: z$1.string(),
939
+ environment: z$1.string(),
940
+ formatVersion: z$1.string()
941
941
  }),
942
- requestedBy: z.object({
943
- actorType: z.string(),
944
- actorId: z.string(),
945
- label: z.string().nullable()
942
+ requestedBy: z$1.object({
943
+ actorType: z$1.string(),
944
+ actorId: z$1.string(),
945
+ label: z$1.string().nullable()
946
946
  }),
947
- options: z.object({
948
- includeVersions: z.boolean(),
949
- includeAudit: z.boolean(),
950
- auditLimit: z.number().int().min(0)
947
+ options: z$1.object({
948
+ includeVersions: z$1.boolean(),
949
+ includeAudit: z$1.boolean(),
950
+ auditLimit: z$1.number().int().min(0)
951
951
  }),
952
- sections: z.array(sectionHeaderSchema),
953
- digest: z.string().regex(/^sha256:[0-9a-f]{64}$/)
952
+ sections: z$1.array(sectionHeaderSchema),
953
+ digest: z$1.string().regex(/^sha256:[0-9a-f]{64}$/)
954
954
  });
955
- const signatureSchema = z.object({
956
- algorithm: z.literal("ed25519"),
957
- publicKey: z.string().regex(/^[0-9a-f]{64}$/),
958
- keyId: z.string().regex(/^[0-9a-f]{16}$/),
959
- value: z.string().regex(/^[0-9a-f]{128}$/)
955
+ const signatureSchema = z$1.object({
956
+ algorithm: z$1.literal("ed25519"),
957
+ publicKey: z$1.string().regex(/^[0-9a-f]{64}$/),
958
+ keyId: z$1.string().regex(/^[0-9a-f]{16}$/),
959
+ value: z$1.string().regex(/^[0-9a-f]{128}$/)
960
960
  });
961
961
  /**
962
962
  * Envelope schema. `data` is validated only as an object: a v1 verifier must
@@ -965,11 +965,11 @@ const signatureSchema = z.object({
965
965
  * `verifyArchive`'s undeclared/declared cross-check rather than by rejecting
966
966
  * the file outright.
967
967
  */
968
- const archiveSchema = z.object({
969
- format: z.literal(ARCHIVE_FORMAT),
968
+ const archiveSchema = z$1.object({
969
+ format: z$1.literal(ARCHIVE_FORMAT),
970
970
  manifest: manifestSchema,
971
971
  signature: signatureSchema.nullable(),
972
- data: z.record(z.string(), z.unknown())
972
+ data: z$1.record(z$1.string(), z$1.unknown())
973
973
  });
974
974
  /** Parse untrusted JSON text into an archive. Throws with a readable message. */
975
975
  function parseArchive(text) {
@@ -1238,15 +1238,15 @@ function describeChange(kind, name, restoreFrom) {
1238
1238
  }
1239
1239
  // ../../packages/core/src/connect.ts
1240
1240
  /** Workload authentication is separate from secret-decryption principals. */
1241
- const workloadPublicKeySchema = z.object({
1242
- kty: z.literal("EC"),
1243
- crv: z.literal("P-256"),
1244
- x: z.string().regex(/^[A-Za-z0-9_-]{43}$/),
1245
- y: z.string().regex(/^[A-Za-z0-9_-]{43}$/)
1241
+ const workloadPublicKeySchema = z$1.object({
1242
+ kty: z$1.literal("EC"),
1243
+ crv: z$1.literal("P-256"),
1244
+ x: z$1.string().regex(/^[A-Za-z0-9_-]{43}$/),
1245
+ y: z$1.string().regex(/^[A-Za-z0-9_-]{43}$/)
1246
1246
  }).strict();
1247
- const audienceSchema = z.string().min(1).max(256).regex(/^[^\s]+$/);
1247
+ const audienceSchema = z$1.string().min(1).max(256).regex(/^[^\s]+$/);
1248
1248
  /** HTTPS endpoint syntax. Resolved-address safety is enforced by the server runtime. */
1249
- const connectUrlSchema = z.string().max(2048).url().refine((value) => {
1249
+ const connectUrlSchema = z$1.string().max(2048).url().refine((value) => {
1250
1250
  try {
1251
1251
  const u = new URL(value);
1252
1252
  return u.protocol === "https:" && !u.username && !u.password && !u.hash && !u.search && !u.port && u.hostname.length <= 253 && u.hostname.split(".").every((label) => /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(label)) && u.hostname.includes(".") && !/^[0-9.]+$/.test(u.hostname) && !u.hostname.endsWith(".") && !/(^|\.)(localhost|local|localdomain|internal|invalid|home|home\.arpa|onion)$/.test(u.hostname);
@@ -1254,12 +1254,12 @@ const connectUrlSchema = z.string().max(2048).url().refine((value) => {
1254
1254
  return false;
1255
1255
  }
1256
1256
  }, "use a public HTTPS hostname without credentials, query, fragment, or port");
1257
- const federationPolicySchema = z.object({
1257
+ const federationPolicySchema = z$1.object({
1258
1258
  issuer: connectUrlSchema,
1259
1259
  jwksUri: connectUrlSchema,
1260
1260
  audience: audienceSchema,
1261
- subject: z.string().min(1).max(512),
1262
- claims: z.record(z.string().regex(/^[a-zA-Z][a-zA-Z0-9_]{0,63}$/), z.string().min(1).max(512)).refine((claims) => Object.keys(claims).length <= 20 && Object.keys(claims).every((key) => ![
1261
+ subject: z$1.string().min(1).max(512),
1262
+ claims: z$1.record(z$1.string().regex(/^[a-zA-Z][a-zA-Z0-9_]{0,63}$/), z$1.string().min(1).max(512)).refine((claims) => Object.keys(claims).length <= 20 && Object.keys(claims).every((key) => ![
1263
1263
  "iss",
1264
1264
  "aud",
1265
1265
  "sub",
@@ -1268,29 +1268,29 @@ const federationPolicySchema = z.object({
1268
1268
  "nbf"
1269
1269
  ].includes(key))).default({})
1270
1270
  }).strict();
1271
- z.object({
1272
- name: z.string().trim().min(1).max(100),
1273
- environmentId: z.string().min(1).max(128),
1271
+ z$1.object({
1272
+ name: z$1.string().trim().min(1).max(100),
1273
+ environmentId: z$1.string().min(1).max(128),
1274
1274
  publicKey: workloadPublicKeySchema.optional(),
1275
1275
  federation: federationPolicySchema.optional(),
1276
- audiences: z.array(audienceSchema).max(20).default([]),
1277
- maxTtlSeconds: z.number().int().min(60).max(900).default(300)
1276
+ audiences: z$1.array(audienceSchema).max(20).default([]),
1277
+ maxTtlSeconds: z$1.number().int().min(60).max(900).default(300)
1278
1278
  }).strict().refine((v) => !!v.publicKey !== !!v.federation, "choose a public key or a federation policy");
1279
- z.object({
1280
- enabled: z.boolean().optional(),
1279
+ z$1.object({
1280
+ enabled: z$1.boolean().optional(),
1281
1281
  publicKey: workloadPublicKeySchema.optional()
1282
1282
  }).strict().refine((v) => v.enabled !== void 0 || v.publicKey !== void 0);
1283
- const githubPermissionsSchema = z.record(z.string().regex(/^[a-z_]{1,64}$/), z.enum(["read", "write"])).refine((p) => Object.keys(p).length > 0 && Object.keys(p).length <= 40, "specify between 1 and 40 permissions");
1284
- const githubScopeSchema = z.object({
1285
- repositoryIds: z.array(z.number().int().positive().max(Number.MAX_SAFE_INTEGER)).min(1).max(100),
1283
+ const githubPermissionsSchema = z$1.record(z$1.string().regex(/^[a-z_]{1,64}$/), z$1.enum(["read", "write"])).refine((p) => Object.keys(p).length > 0 && Object.keys(p).length <= 40, "specify between 1 and 40 permissions");
1284
+ const githubScopeSchema = z$1.object({
1285
+ repositoryIds: z$1.array(z$1.number().int().positive().max(Number.MAX_SAFE_INTEGER)).min(1).max(100),
1286
1286
  permissions: githubPermissionsSchema
1287
1287
  }).strict();
1288
1288
  /** Exact paths or explicitly allowed descendants, without URL decoding ambiguity. */
1289
- const connectPathSchema = z.string().min(1).max(1024).refine((path) => /^\/[A-Za-z0-9_./~-]*$/.test(path) && !path.includes("//") && !path.split("/").some((part) => part === "." || part === ".."), "use an absolute API path without encoded characters or dot segments");
1290
- const proxyRuleSchema = z.object({
1289
+ const connectPathSchema = z$1.string().min(1).max(1024).refine((path) => /^\/[A-Za-z0-9_./~-]*$/.test(path) && !path.includes("//") && !path.split("/").some((part) => part === "." || part === ".."), "use an absolute API path without encoded characters or dot segments");
1290
+ const proxyRuleSchema = z$1.object({
1291
1291
  path: connectPathSchema,
1292
- descendants: z.boolean().default(false),
1293
- methods: z.array(z.enum([
1292
+ descendants: z$1.boolean().default(false),
1293
+ methods: z$1.array(z$1.enum([
1294
1294
  "GET",
1295
1295
  "POST",
1296
1296
  "PUT",
@@ -1299,18 +1299,18 @@ const proxyRuleSchema = z.object({
1299
1299
  "HEAD"
1300
1300
  ])).min(1).max(6)
1301
1301
  }).strict();
1302
- const staticScopeSchema = z.object({ rules: z.array(proxyRuleSchema).min(1).max(30) }).strict();
1303
- const oauthScopeSchema = z.object({ scopes: z.array(z.string().regex(/^[\x21\x23-\x5b\x5d-\x7e]{1,200}$/)).min(1).max(50).refine((scopes) => new Set(scopes).size === scopes.length, "scopes must be unique") }).strict();
1302
+ const staticScopeSchema = z$1.object({ rules: z$1.array(proxyRuleSchema).min(1).max(30) }).strict();
1303
+ const oauthScopeSchema = z$1.object({ scopes: z$1.array(z$1.string().regex(/^[\x21\x23-\x5b\x5d-\x7e]{1,200}$/)).min(1).max(50).refine((scopes) => new Set(scopes).size === scopes.length, "scopes must be unique") }).strict();
1304
1304
  const oauthConfigSchema = oauthScopeSchema.extend({
1305
- provider: z.literal("oauth"),
1306
- grantType: z.enum(["client_credentials", "authorization_code"]),
1307
- clientId: z.string().min(1).max(512),
1305
+ provider: z$1.literal("oauth"),
1306
+ grantType: z$1.enum(["client_credentials", "authorization_code"]),
1307
+ clientId: z$1.string().min(1).max(512),
1308
1308
  tokenEndpoint: connectUrlSchema,
1309
1309
  authorizationEndpoint: connectUrlSchema.optional(),
1310
- tokenAuthMethod: z.enum(["client_secret_basic", "client_secret_post"]).default("client_secret_basic")
1310
+ tokenAuthMethod: z$1.enum(["client_secret_basic", "client_secret_post"]).default("client_secret_basic")
1311
1311
  });
1312
1312
  const customApiConfigSchema = staticScopeSchema.extend({
1313
- provider: z.literal("custom_api"),
1313
+ provider: z$1.literal("custom_api"),
1314
1314
  origin: connectUrlSchema.refine((value) => {
1315
1315
  try {
1316
1316
  return new URL(value).pathname === "/";
@@ -1318,46 +1318,46 @@ const customApiConfigSchema = staticScopeSchema.extend({
1318
1318
  return false;
1319
1319
  }
1320
1320
  }, "use an origin without a path"),
1321
- headerName: z.string().regex(/^[A-Za-z][A-Za-z0-9-]{0,63}$/).refine((v) => !/^(accept$|user-agent$|host|cookie|content-|proxy-|forwarded|x-forwarded-|cf-|connection|transfer-encoding|upgrade|trailer|te$)/i.test(v)),
1322
- headerPrefix: z.string().max(64).regex(/^[\x20-\x7e]*$/).default("Bearer ")
1321
+ headerName: z$1.string().regex(/^[A-Za-z][A-Za-z0-9-]{0,63}$/).refine((v) => !/^(accept$|user-agent$|host|cookie|content-|proxy-|forwarded|x-forwarded-|cf-|connection|transfer-encoding|upgrade|trailer|te$)/i.test(v)),
1322
+ headerPrefix: z$1.string().max(64).regex(/^[\x20-\x7e]*$/).default("Bearer ")
1323
1323
  });
1324
- const connectConfigSchema = z.discriminatedUnion("provider", [
1324
+ const connectConfigSchema = z$1.discriminatedUnion("provider", [
1325
1325
  customApiConfigSchema,
1326
1326
  oauthConfigSchema,
1327
1327
  githubScopeSchema.extend({
1328
- provider: z.literal("github_app"),
1329
- appId: z.string().regex(/^[A-Za-z0-9_.-]{1,128}$/),
1330
- installationId: z.string().regex(/^[1-9][0-9]{0,19}$/)
1328
+ provider: z$1.literal("github_app"),
1329
+ appId: z$1.string().regex(/^[A-Za-z0-9_.-]{1,128}$/),
1330
+ installationId: z$1.string().regex(/^[1-9][0-9]{0,19}$/)
1331
1331
  }),
1332
1332
  staticScopeSchema.extend({
1333
- provider: z.literal("static_key"),
1334
- service: z.literal("resend"),
1335
- rules: z.array(proxyRuleSchema.refine((rule) => rule.path === "/emails" || rule.path.startsWith("/emails/"), "the Resend connector supports only /emails and its descendants")).min(1).max(30)
1333
+ provider: z$1.literal("static_key"),
1334
+ service: z$1.literal("resend"),
1335
+ rules: z$1.array(proxyRuleSchema.refine((rule) => rule.path === "/emails" || rule.path.startsWith("/emails/"), "the Resend connector supports only /emails and its descendants")).min(1).max(30)
1336
1336
  })
1337
1337
  ]).refine((v) => v.provider !== "oauth" || v.grantType !== "authorization_code" || !!v.authorizationEndpoint, "authorization-code connections require an authorization endpoint");
1338
- const connectGrantPolicySchema = z.discriminatedUnion("provider", [
1339
- staticScopeSchema.extend({ provider: z.literal("custom_api") }),
1340
- oauthScopeSchema.extend({ provider: z.literal("oauth") }),
1341
- githubScopeSchema.extend({ provider: z.literal("github_app") }),
1342
- staticScopeSchema.extend({ provider: z.literal("static_key") })
1338
+ const connectGrantPolicySchema = z$1.discriminatedUnion("provider", [
1339
+ staticScopeSchema.extend({ provider: z$1.literal("custom_api") }),
1340
+ oauthScopeSchema.extend({ provider: z$1.literal("oauth") }),
1341
+ githubScopeSchema.extend({ provider: z$1.literal("github_app") }),
1342
+ staticScopeSchema.extend({ provider: z$1.literal("static_key") })
1343
1343
  ]);
1344
- z.object({
1345
- name: z.string().trim().min(1).max(100),
1344
+ z$1.object({
1345
+ name: z$1.string().trim().min(1).max(100),
1346
1346
  config: connectConfigSchema,
1347
- credentialWrapped: z.string().startsWith("wd1.").max(32e3)
1347
+ credentialWrapped: z$1.string().startsWith("wd1.").max(32e3)
1348
1348
  }).strict();
1349
- z.object({
1350
- enabled: z.boolean().optional(),
1351
- credentialWrapped: z.string().startsWith("wd1.").max(32e3).optional()
1349
+ z$1.object({
1350
+ enabled: z$1.boolean().optional(),
1351
+ credentialWrapped: z$1.string().startsWith("wd1.").max(32e3).optional()
1352
1352
  }).strict().refine((v) => v.enabled !== void 0 || v.credentialWrapped !== void 0);
1353
- z.object({
1354
- workloadId: z.string().min(1).max(128),
1355
- connectionId: z.string().min(1).max(128),
1353
+ z$1.object({
1354
+ workloadId: z$1.string().min(1).max(128),
1355
+ connectionId: z$1.string().min(1).max(128),
1356
1356
  policy: connectGrantPolicySchema
1357
1357
  }).strict();
1358
- z.object({
1358
+ z$1.object({
1359
1359
  path: connectPathSchema,
1360
- method: z.enum([
1360
+ method: z$1.enum([
1361
1361
  "GET",
1362
1362
  "POST",
1363
1363
  "PUT",
@@ -1365,11 +1365,11 @@ z.object({
1365
1365
  "DELETE",
1366
1366
  "HEAD"
1367
1367
  ]).default("GET"),
1368
- query: z.record(z.string().min(1).max(100), z.string().max(2048)).default({}),
1368
+ query: z$1.record(z$1.string().min(1).max(100), z$1.string().max(2048)).default({}),
1369
1369
  /** JSON only; callers cannot inject authorization or forwarding headers. */
1370
- body: z.string().max(65536).optional()
1370
+ body: z$1.string().max(65536).optional()
1371
1371
  }).strict().refine((v) => !["GET", "HEAD"].includes(v.method) || v.body === void 0, "GET and HEAD cannot carry a body");
1372
- z.object({ audience: audienceSchema }).strict();
1372
+ z$1.object({ audience: audienceSchema }).strict();
1373
1373
  // ../../packages/core/src/dotenv.ts
1374
1374
  /**
1375
1375
  * `.env` parsing and serialization — the canonical definition of what a `.env`
@@ -1752,7 +1752,7 @@ function prettyJsonOrRaw(value) {
1752
1752
  const inspection = inspectJsonValue(value);
1753
1753
  return inspection.kind === "json" ? inspection.pretty : value;
1754
1754
  }
1755
- z.enum([
1755
+ z$1.enum([
1756
1756
  "postgres",
1757
1757
  "mysql",
1758
1758
  "ssh",
@@ -1761,35 +1761,35 @@ z.enum([
1761
1761
  "gcp",
1762
1762
  "mongodb"
1763
1763
  ]);
1764
- const executorModeSchema = z.enum(["in_do", "remote"]);
1764
+ const executorModeSchema = z$1.enum(["in_do", "remote"]);
1765
1765
  /**
1766
1766
  * A Postgres role name we are willing to create. Deliberately strict — this
1767
1767
  * value is interpolated into a SQL template, so it must be a bare identifier
1768
1768
  * with no way to break out of quoting (no quotes, whitespace, or semicolons).
1769
1769
  */
1770
- const postgresRoleNameSchema = z.string().regex(/^[a-z_][a-z0-9_]{2,62}$/, "must be 3–63 chars, lowercase letters/digits/underscore, starting with a letter or underscore");
1770
+ const postgresRoleNameSchema = z$1.string().regex(/^[a-z_][a-z0-9_]{2,62}$/, "must be 3–63 chars, lowercase letters/digits/underscore, starting with a letter or underscore");
1771
1771
  /**
1772
1772
  * A SCRAM-SHA-256 verifier string as produced by @seekrit/crypto. Validated so
1773
1773
  * it, too, is safe to interpolate into a quoted SQL literal (the alphabet is
1774
1774
  * base64 + the fixed structural characters, none of which is a single quote).
1775
1775
  */
1776
- const scramVerifierSchema = z.string().regex(/^SCRAM-SHA-256\$\d{3,}:[A-Za-z0-9+/=]+\$[A-Za-z0-9+/=]+:[A-Za-z0-9+/=]+$/, "must be a SCRAM-SHA-256 verifier");
1776
+ const scramVerifierSchema = z$1.string().regex(/^SCRAM-SHA-256\$\d{3,}:[A-Za-z0-9+/=]+\$[A-Za-z0-9+/=]+:[A-Za-z0-9+/=]+$/, "must be a SCRAM-SHA-256 verifier");
1777
1777
  /**
1778
1778
  * An SSH login principal (a Unix-style username the certificate authorizes).
1779
1779
  * Bounded and restricted to a safe charset — principals are SSH-wire-encoded,
1780
1780
  * not shell-interpolated, so this is sanity/DoS hardening, not an injection gate.
1781
1781
  */
1782
- const sshPrincipalSchema = z.string().regex(/^[A-Za-z0-9._-]{1,64}$/, "must be 1–64 chars of letters, digits, dot, dash, underscore");
1782
+ const sshPrincipalSchema = z$1.string().regex(/^[A-Za-z0-9._-]{1,64}$/, "must be 1–64 chars of letters, digits, dot, dash, underscore");
1783
1783
  /** An `ssh-ed25519 <base64> [comment]` public key line (deep-validated on sign). */
1784
- const sshPublicKeySchema = z.string().max(2048).regex(/^ssh-ed25519 [A-Za-z0-9+/=]+( .*)?$/, "must be an ssh-ed25519 public key");
1784
+ const sshPublicKeySchema = z$1.string().max(2048).regex(/^ssh-ed25519 [A-Za-z0-9+/=]+( .*)?$/, "must be an ssh-ed25519 public key");
1785
1785
  /** An SSH certificate extension name, e.g. `permit-pty`. */
1786
- const sshExtensionSchema = z.string().regex(/^[a-z0-9-]{1,64}$/);
1786
+ const sshExtensionSchema = z$1.string().regex(/^[a-z0-9-]{1,64}$/);
1787
1787
  /**
1788
1788
  * A MySQL/MariaDB user name we are willing to create. Interpolated into a
1789
1789
  * quoted SQL literal (`'{{name}}'@'%'`), so it is kept strict — plain
1790
1790
  * alphanumerics/underscore, no quotes/whitespace/semicolons to break out.
1791
1791
  */
1792
- const mysqlUserNameSchema = z.string().regex(/^[A-Za-z0-9_]{3,32}$/, "must be 3–32 chars, letters/digits/underscore");
1792
+ const mysqlUserNameSchema = z$1.string().regex(/^[A-Za-z0-9_]{3,32}$/, "must be 3–32 chars, letters/digits/underscore");
1793
1793
  /**
1794
1794
  * A `mysql_native_password` authentication string — `*` followed by 40 upper
1795
1795
  * hex chars (`UPPER(HEX(SHA1(SHA1(password))))`), as produced by
@@ -1797,14 +1797,14 @@ const mysqlUserNameSchema = z.string().regex(/^[A-Za-z0-9_]{3,32}$/, "must be 3
1797
1797
  * `CREATE USER … IDENTIFIED WITH mysql_native_password AS '<str>'`, and its
1798
1798
  * alphabet contains no single quote, so it is safe in a quoted SQL literal.
1799
1799
  */
1800
- const mysqlNativeVerifierSchema = z.string().regex(/^\*[0-9A-F]{40}$/, "must be a mysql_native_password hash (*<40 hex>)");
1800
+ const mysqlNativeVerifierSchema = z$1.string().regex(/^\*[0-9A-F]{40}$/, "must be a mysql_native_password hash (*<40 hex>)");
1801
1801
  /**
1802
1802
  * A Redis ACL user name we are willing to create. Interpolated into a Redis
1803
1803
  * command line as a bare token (`ACL SETUSER <name> …`), so it is kept strict —
1804
1804
  * plain alphanumerics/underscore, no whitespace to split the arg or ACL rule
1805
1805
  * characters (`~ + @ # & %`) that could be read as a permission.
1806
1806
  */
1807
- const redisUserNameSchema = z.string().regex(/^[A-Za-z0-9_]{3,32}$/, "must be 3–32 chars, letters/digits/underscore");
1807
+ const redisUserNameSchema = z$1.string().regex(/^[A-Za-z0-9_]{3,32}$/, "must be 3–32 chars, letters/digits/underscore");
1808
1808
  /**
1809
1809
  * A Redis password verifier — the lowercase-hex SHA-256 of the password, as
1810
1810
  * produced by @seekrit/crypto `redisSha256Verifier`. `ACL SETUSER … on #<hex>`
@@ -1813,22 +1813,22 @@ const redisUserNameSchema = z.string().regex(/^[A-Za-z0-9_]{3,32}$/, "must be 3
1813
1813
  * is preimage-resistant (the password is high-entropy and machine-generated).
1814
1814
  * The alphabet is bare hex, so it is a safe bare command token.
1815
1815
  */
1816
- const redisSha256VerifierSchema = z.string().regex(/^[0-9a-f]{64}$/, "must be a lowercase-hex SHA-256 digest (64 chars)");
1816
+ const redisSha256VerifierSchema = z$1.string().regex(/^[0-9a-f]{64}$/, "must be a lowercase-hex SHA-256 digest (64 chars)");
1817
1817
  /**
1818
1818
  * An IAM role ARN the broker is allowed to assume. Bounded and structurally
1819
1819
  * validated: `arn:<partition>:iam::<account>:role/<path-and-name>`. Partition
1820
1820
  * covers commercial (`aws`), GovCloud (`aws-us-gov`), and China (`aws-cn`).
1821
1821
  */
1822
- const awsRoleArnSchema = z.string().regex(/^arn:aws(?:-us-gov|-cn)?:iam::\d{12}:role\/[\w+=,.@/-]{1,512}$/, "must be an IAM role ARN (arn:aws:iam::<account>:role/<name>)");
1822
+ const awsRoleArnSchema = z$1.string().regex(/^arn:aws(?:-us-gov|-cn)?:iam::\d{12}:role\/[\w+=,.@/-]{1,512}$/, "must be an IAM role ARN (arn:aws:iam::<account>:role/<name>)");
1823
1823
  /** An AWS region id, e.g. `us-east-1`, `eu-west-2`, `us-gov-west-1`. */
1824
- const awsRegionSchema$1 = z.string().regex(/^[a-z]{2}(?:-[a-z]+)+-\d$/, "must be an AWS region id (e.g. us-east-1)");
1824
+ const awsRegionSchema$1 = z$1.string().regex(/^[a-z]{2}(?:-[a-z]+)+-\d$/, "must be an AWS region id (e.g. us-east-1)");
1825
1825
  /**
1826
1826
  * An STS external id — the shared string a role's trust policy can require so a
1827
1827
  * confused-deputy can't assume it. AWS allows a broad charset; we keep to the
1828
1828
  * documented safe set and bound the length.
1829
1829
  */
1830
- const awsExternalIdSchema = z.string().regex(/^[\w+=,.@:/-]{2,1224}$/, "must be a valid STS external id");
1831
- z.string().regex(/^[\w+=,.@-]{2,64}$/, "must be 2–64 chars of [A-Za-z0-9_+=,.@-]");
1830
+ const awsExternalIdSchema = z$1.string().regex(/^[\w+=,.@:/-]{2,1224}$/, "must be a valid STS external id");
1831
+ z$1.string().regex(/^[\w+=,.@-]{2,64}$/, "must be 2–64 chars of [A-Za-z0-9_+=,.@-]");
1832
1832
  /**
1833
1833
  * A GCP service-account email the broker is allowed to impersonate (or that
1834
1834
  * appears in a delegation chain). Structurally validated and bounded: it is
@@ -1837,21 +1837,21 @@ z.string().regex(/^[\w+=,.@-]{2,64}$/, "must be 2–64 chars of [A-Za-z0-9_+=,.@
1837
1837
  * (`name@<project>.iam.gserviceaccount.com`) and Google-managed
1838
1838
  * (`<project-number>-compute@developer.gserviceaccount.com`) forms.
1839
1839
  */
1840
- const gcpServiceAccountEmailSchema = z.string().max(256).regex(/^[a-z0-9-]+@[a-z0-9.-]+\.gserviceaccount\.com$/, "must be a service-account email (…@….gserviceaccount.com)");
1840
+ const gcpServiceAccountEmailSchema = z$1.string().max(256).regex(/^[a-z0-9-]+@[a-z0-9.-]+\.gserviceaccount\.com$/, "must be a service-account email (…@….gserviceaccount.com)");
1841
1841
  /**
1842
1842
  * An OAuth 2.0 scope granted to the minted access token, e.g.
1843
1843
  * `https://www.googleapis.com/auth/cloud-platform`. Bounded and whitespace-free
1844
1844
  * (scopes are space-delimited); passed to the IAM Credentials API in a JSON body
1845
1845
  * array, not a URL, so this is sanity/DoS hardening rather than an injection gate.
1846
1846
  */
1847
- const gcpOauthScopeSchema = z.string().min(1).max(256).regex(/^\S+$/, "must be a single OAuth scope with no whitespace");
1847
+ const gcpOauthScopeSchema = z$1.string().min(1).max(256).regex(/^\S+$/, "must be a single OAuth scope with no whitespace");
1848
1848
  /**
1849
1849
  * The consumer's ephemeral P-256 public key (JWK-serialized) that a tier-2
1850
1850
  * credential is wrapped to before it is returned. Validated structurally here;
1851
1851
  * the executor imports it defensively before wrapping. Bounded so a giant blob
1852
1852
  * can't be pushed through the control plane.
1853
1853
  */
1854
- const p256PublicKeyJwkSchema = z.string().max(2048).refine((s) => {
1854
+ const p256PublicKeyJwkSchema = z$1.string().max(2048).refine((s) => {
1855
1855
  try {
1856
1856
  const jwk = JSON.parse(s);
1857
1857
  return jwk.kty === "EC" && jwk.crv === "P-256" && !!jwk.x && !!jwk.y;
@@ -1859,23 +1859,23 @@ const p256PublicKeyJwkSchema = z.string().max(2048).refine((s) => {
1859
1859
  return false;
1860
1860
  }
1861
1861
  }, "must be a JWK-serialized P-256 public key");
1862
- z.string().regex(/^[A-Za-z0-9_-]{1,64}$/, "must be 1–64 chars of [A-Za-z0-9_-]");
1862
+ z$1.string().regex(/^[A-Za-z0-9_-]{1,64}$/, "must be 1–64 chars of [A-Za-z0-9_-]");
1863
1863
  /**
1864
1864
  * A MongoDB database name — the db a preset role is granted on, or the
1865
1865
  * authentication database a leased user is created in. MongoDB forbids
1866
1866
  * `/\. "$*<>:|?` and the empty string in db names; we keep to a safe subset.
1867
1867
  */
1868
- const mongoDatabaseNameSchema = z.string().regex(/^[A-Za-z0-9_-]{1,63}$/, "must be 1–63 chars of [A-Za-z0-9_-]");
1868
+ const mongoDatabaseNameSchema = z$1.string().regex(/^[A-Za-z0-9_-]{1,63}$/, "must be 1–63 chars of [A-Za-z0-9_-]");
1869
1869
  /**
1870
1870
  * A single MongoDB role grant `{ role, db }` for a `custom` target — e.g.
1871
1871
  * `{ role: "readWrite", db: "app" }` or a user-defined role. Admin-supplied
1872
1872
  * trusted input, set once at registration; still bounded structurally.
1873
1873
  */
1874
- const mongoRoleSchema = z.object({
1875
- role: z.string().regex(/^[A-Za-z0-9_-]{1,64}$/, "must be a role name"),
1874
+ const mongoRoleSchema = z$1.object({
1875
+ role: z$1.string().regex(/^[A-Za-z0-9_-]{1,64}$/, "must be a role name"),
1876
1876
  db: mongoDatabaseNameSchema
1877
1877
  });
1878
- const postgresAccessLevelSchema = z.enum([
1878
+ const postgresAccessLevelSchema = z$1.enum([
1879
1879
  "readonly",
1880
1880
  "readwrite",
1881
1881
  "custom"
@@ -1885,109 +1885,109 @@ const POSTGRES_GROUP_ROLES = {
1885
1885
  readonly: "seekrit_readonly",
1886
1886
  readwrite: "seekrit_readwrite"
1887
1887
  };
1888
- const mysqlAccessLevelSchema = z.enum([
1888
+ const mysqlAccessLevelSchema = z$1.enum([
1889
1889
  "readonly",
1890
1890
  "readwrite",
1891
1891
  "custom"
1892
1892
  ]);
1893
- const redisAccessLevelSchema = z.enum([
1893
+ const redisAccessLevelSchema = z$1.enum([
1894
1894
  "readonly",
1895
1895
  "readwrite",
1896
1896
  "custom"
1897
1897
  ]);
1898
- const mongoAccessLevelSchema = z.enum([
1898
+ const mongoAccessLevelSchema = z$1.enum([
1899
1899
  "readonly",
1900
1900
  "readwrite",
1901
1901
  "custom"
1902
1902
  ]);
1903
- const connectionSchema = z.object({
1904
- host: z.string().min(1),
1905
- port: z.number().int().min(1).max(65535),
1906
- database: z.string().min(1)
1903
+ const connectionSchema = z$1.object({
1904
+ host: z$1.string().min(1),
1905
+ port: z$1.number().int().min(1).max(65535),
1906
+ database: z$1.string().min(1)
1907
1907
  });
1908
1908
  /** A `{{name}}`/`{{verifier}}`/`{{valid_until}}` templated SQL statement. */
1909
- const statementSchema$1 = z.string().min(1).max(4e3);
1909
+ const statementSchema$1 = z$1.string().min(1).max(4e3);
1910
1910
  /** A bare SQL identifier (schema name) — no quotes/whitespace/semicolons. */
1911
- const identifierSchema = z.string().regex(/^[A-Za-z_][A-Za-z0-9_]{0,62}$/, "must be an identifier");
1912
- const postgresTargetConfigSchema = z.object({
1913
- provider: z.literal("postgres"),
1911
+ const identifierSchema = z$1.string().regex(/^[A-Za-z_][A-Za-z0-9_]{0,62}$/, "must be an identifier");
1912
+ const postgresTargetConfigSchema = z$1.object({
1913
+ provider: z$1.literal("postgres"),
1914
1914
  executor: executorModeSchema,
1915
1915
  accessLevel: postgresAccessLevelSchema.optional(),
1916
1916
  schema: identifierSchema.optional(),
1917
1917
  connection: connectionSchema,
1918
- provisionerUrl: z.url().optional(),
1919
- createStatements: z.array(statementSchema$1).max(16).optional(),
1920
- revokeStatements: z.array(statementSchema$1).max(16).optional()
1918
+ provisionerUrl: z$1.url().optional(),
1919
+ createStatements: z$1.array(statementSchema$1).max(16).optional(),
1920
+ revokeStatements: z$1.array(statementSchema$1).max(16).optional()
1921
1921
  });
1922
1922
  /** A MySQL account host part (`'name'@'<host>'`) — no quotes/whitespace. */
1923
- const mysqlHostSchema$1 = z.string().regex(/^[A-Za-z0-9_.%:-]{1,255}$/, "must be a host pattern");
1924
- const mysqlTargetConfigSchema = z.object({
1925
- provider: z.literal("mysql"),
1923
+ const mysqlHostSchema$1 = z$1.string().regex(/^[A-Za-z0-9_.%:-]{1,255}$/, "must be a host pattern");
1924
+ const mysqlTargetConfigSchema = z$1.object({
1925
+ provider: z$1.literal("mysql"),
1926
1926
  executor: executorModeSchema,
1927
1927
  accessLevel: mysqlAccessLevelSchema.optional(),
1928
1928
  connection: connectionSchema,
1929
1929
  userHost: mysqlHostSchema$1.optional(),
1930
- provisionerUrl: z.url().optional(),
1931
- createStatements: z.array(statementSchema$1).max(16).optional(),
1932
- revokeStatements: z.array(statementSchema$1).max(16).optional()
1930
+ provisionerUrl: z$1.url().optional(),
1931
+ createStatements: z$1.array(statementSchema$1).max(16).optional(),
1932
+ revokeStatements: z$1.array(statementSchema$1).max(16).optional()
1933
1933
  });
1934
- const redisConnectionSchema = z.object({
1935
- host: z.string().min(1),
1936
- port: z.number().int().min(1).max(65535),
1934
+ const redisConnectionSchema = z$1.object({
1935
+ host: z$1.string().min(1),
1936
+ port: z$1.number().int().min(1).max(65535),
1937
1937
  /** Redis logical database index (the `/<n>` in a connection URL). */
1938
- db: z.number().int().min(0).max(15).optional()
1938
+ db: z$1.number().int().min(0).max(15).optional()
1939
1939
  });
1940
- const redisTargetConfigSchema = z.object({
1941
- provider: z.literal("redis"),
1940
+ const redisTargetConfigSchema = z$1.object({
1941
+ provider: z$1.literal("redis"),
1942
1942
  executor: executorModeSchema,
1943
1943
  accessLevel: redisAccessLevelSchema.optional(),
1944
1944
  connection: redisConnectionSchema,
1945
- provisionerUrl: z.url().optional(),
1946
- createStatements: z.array(statementSchema$1).max(16).optional(),
1947
- revokeStatements: z.array(statementSchema$1).max(16).optional()
1945
+ provisionerUrl: z$1.url().optional(),
1946
+ createStatements: z$1.array(statementSchema$1).max(16).optional(),
1947
+ revokeStatements: z$1.array(statementSchema$1).max(16).optional()
1948
1948
  });
1949
- const sshTargetConfigSchema = z.object({
1950
- provider: z.literal("ssh"),
1951
- executor: z.literal("in_do"),
1949
+ const sshTargetConfigSchema = z$1.object({
1950
+ provider: z$1.literal("ssh"),
1951
+ executor: z$1.literal("in_do"),
1952
1952
  caPublicKey: sshPublicKeySchema,
1953
- allowedPrincipals: z.array(sshPrincipalSchema).max(64).optional(),
1954
- extensions: z.array(sshExtensionSchema).max(16).optional(),
1955
- maxTtlSeconds: z.number().int().min(60).max(604800).optional(),
1956
- connection: z.object({
1957
- host: z.string().min(1).optional(),
1953
+ allowedPrincipals: z$1.array(sshPrincipalSchema).max(64).optional(),
1954
+ extensions: z$1.array(sshExtensionSchema).max(16).optional(),
1955
+ maxTtlSeconds: z$1.number().int().min(60).max(604800).optional(),
1956
+ connection: z$1.object({
1957
+ host: z$1.string().min(1).optional(),
1958
1958
  user: sshPrincipalSchema.optional()
1959
1959
  }).optional()
1960
1960
  });
1961
1961
  const AWS_MAX_TTL_SECONDS = 43200;
1962
- const awsTargetConfigSchema = z.object({
1963
- provider: z.literal("aws"),
1964
- executor: z.literal("in_do"),
1962
+ const awsTargetConfigSchema = z$1.object({
1963
+ provider: z$1.literal("aws"),
1964
+ executor: z$1.literal("in_do"),
1965
1965
  roleArn: awsRoleArnSchema,
1966
1966
  region: awsRegionSchema$1,
1967
1967
  externalId: awsExternalIdSchema.optional(),
1968
- sessionPolicy: z.string().min(1).max(4e3).optional(),
1969
- maxTtlSeconds: z.number().int().min(900).max(AWS_MAX_TTL_SECONDS).optional()
1968
+ sessionPolicy: z$1.string().min(1).max(4e3).optional(),
1969
+ maxTtlSeconds: z$1.number().int().min(900).max(AWS_MAX_TTL_SECONDS).optional()
1970
1970
  });
1971
1971
  const GCP_MAX_TTL_SECONDS = 43200;
1972
- const gcpTargetConfigSchema = z.object({
1973
- provider: z.literal("gcp"),
1974
- executor: z.literal("in_do"),
1972
+ const gcpTargetConfigSchema = z$1.object({
1973
+ provider: z$1.literal("gcp"),
1974
+ executor: z$1.literal("in_do"),
1975
1975
  serviceAccount: gcpServiceAccountEmailSchema,
1976
- scopes: z.array(gcpOauthScopeSchema).min(1).max(32).optional(),
1977
- delegates: z.array(gcpServiceAccountEmailSchema).max(8).optional(),
1978
- maxTtlSeconds: z.number().int().min(60).max(GCP_MAX_TTL_SECONDS).optional()
1976
+ scopes: z$1.array(gcpOauthScopeSchema).min(1).max(32).optional(),
1977
+ delegates: z$1.array(gcpServiceAccountEmailSchema).max(8).optional(),
1978
+ maxTtlSeconds: z$1.number().int().min(60).max(GCP_MAX_TTL_SECONDS).optional()
1979
1979
  });
1980
- const mongoTargetConfigSchema = z.object({
1981
- provider: z.literal("mongodb"),
1982
- executor: z.literal("in_do"),
1980
+ const mongoTargetConfigSchema = z$1.object({
1981
+ provider: z$1.literal("mongodb"),
1982
+ executor: z$1.literal("in_do"),
1983
1983
  accessLevel: mongoAccessLevelSchema.optional(),
1984
1984
  connection: connectionSchema,
1985
1985
  authSource: mongoDatabaseNameSchema.optional(),
1986
- roles: z.array(mongoRoleSchema).min(1).max(32).optional(),
1987
- tls: z.boolean().optional(),
1988
- maxTtlSeconds: z.number().int().min(60).max(604800).optional()
1986
+ roles: z$1.array(mongoRoleSchema).min(1).max(32).optional(),
1987
+ tls: z$1.boolean().optional(),
1988
+ maxTtlSeconds: z$1.number().int().min(60).max(604800).optional()
1989
1989
  });
1990
- const leaseTargetConfigSchema = z.discriminatedUnion("provider", [
1990
+ const leaseTargetConfigSchema = z$1.discriminatedUnion("provider", [
1991
1991
  postgresTargetConfigSchema,
1992
1992
  mysqlTargetConfigSchema,
1993
1993
  redisTargetConfigSchema,
@@ -1996,26 +1996,26 @@ const leaseTargetConfigSchema = z.discriminatedUnion("provider", [
1996
1996
  gcpTargetConfigSchema,
1997
1997
  mongoTargetConfigSchema
1998
1998
  ]);
1999
- z.object({
2000
- name: z.string().trim().min(1).max(128),
1999
+ z$1.object({
2000
+ name: z$1.string().trim().min(1).max(128),
2001
2001
  config: leaseTargetConfigSchema,
2002
2002
  /**
2003
2003
  * The admin/provisioning credential (e.g. a Postgres connection string),
2004
2004
  * encrypted client-side to the broker's public key (a `wd1.` wrap). The
2005
2005
  * control plane stores only this ciphertext — it never sees the plaintext.
2006
2006
  */
2007
- wrappedAdminSecret: z.string().min(1)
2007
+ wrappedAdminSecret: z$1.string().min(1)
2008
2008
  });
2009
2009
  /** Requested lease lifetime, shared by all providers. */
2010
- const ttlSecondsSchema = z.number().int().min(60).max(604800);
2010
+ const ttlSecondsSchema = z$1.number().int().min(60).max(604800);
2011
2011
  /**
2012
2012
  * Client → API: mint a Postgres lease. The client generates the password and
2013
2013
  * its SCRAM verifier locally and sends only the verifier — the plaintext
2014
2014
  * password never leaves the requesting machine.
2015
2015
  */
2016
- const mintPostgresLeaseSchema = z.object({
2017
- provider: z.literal("postgres"),
2018
- targetId: z.string().min(1),
2016
+ const mintPostgresLeaseSchema = z$1.object({
2017
+ provider: z$1.literal("postgres"),
2018
+ targetId: z$1.string().min(1),
2019
2019
  roleName: postgresRoleNameSchema,
2020
2020
  verifier: scramVerifierSchema,
2021
2021
  ttlSeconds: ttlSecondsSchema
@@ -2025,9 +2025,9 @@ const mintPostgresLeaseSchema = z.object({
2025
2025
  * and its `mysql_native_password` hash locally and sends only the hash — the
2026
2026
  * plaintext password never leaves the requesting machine.
2027
2027
  */
2028
- const mintMysqlLeaseSchema = z.object({
2029
- provider: z.literal("mysql"),
2030
- targetId: z.string().min(1),
2028
+ const mintMysqlLeaseSchema = z$1.object({
2029
+ provider: z$1.literal("mysql"),
2030
+ targetId: z$1.string().min(1),
2031
2031
  roleName: mysqlUserNameSchema,
2032
2032
  verifier: mysqlNativeVerifierSchema,
2033
2033
  ttlSeconds: ttlSecondsSchema
@@ -2037,9 +2037,9 @@ const mintMysqlLeaseSchema = z.object({
2037
2037
  * SHA-256 hex digest locally and sends only the digest — the plaintext password
2038
2038
  * never leaves the requesting machine.
2039
2039
  */
2040
- const mintRedisLeaseSchema = z.object({
2041
- provider: z.literal("redis"),
2042
- targetId: z.string().min(1),
2040
+ const mintRedisLeaseSchema = z$1.object({
2041
+ provider: z$1.literal("redis"),
2042
+ targetId: z$1.string().min(1),
2043
2043
  roleName: redisUserNameSchema,
2044
2044
  verifier: redisSha256VerifierSchema,
2045
2045
  ttlSeconds: ttlSecondsSchema
@@ -2049,11 +2049,11 @@ const mintRedisLeaseSchema = z.object({
2049
2049
  * locally and sends only the public key; the signed certificate comes back in
2050
2050
  * the response. The private key never leaves the requesting machine.
2051
2051
  */
2052
- const mintSshLeaseSchema = z.object({
2053
- provider: z.literal("ssh"),
2054
- targetId: z.string().min(1),
2052
+ const mintSshLeaseSchema = z$1.object({
2053
+ provider: z$1.literal("ssh"),
2054
+ targetId: z$1.string().min(1),
2055
2055
  publicKey: sshPublicKeySchema,
2056
- principals: z.array(sshPrincipalSchema).min(1).max(32),
2056
+ principals: z$1.array(sshPrincipalSchema).min(1).max(32),
2057
2057
  ttlSeconds: ttlSecondsSchema
2058
2058
  });
2059
2059
  /**
@@ -2065,11 +2065,11 @@ const mintSshLeaseSchema = z.object({
2065
2065
  * TTL bounds are STS's own `DurationSeconds` limits (15 min – 12 h), not the
2066
2066
  * generic lease bounds — STS rejects anything below 900 seconds.
2067
2067
  */
2068
- const mintAwsLeaseSchema = z.object({
2069
- provider: z.literal("aws"),
2070
- targetId: z.string().min(1),
2068
+ const mintAwsLeaseSchema = z$1.object({
2069
+ provider: z$1.literal("aws"),
2070
+ targetId: z$1.string().min(1),
2071
2071
  recipientPublicKey: p256PublicKeyJwkSchema,
2072
- ttlSeconds: z.number().int().min(900).max(AWS_MAX_TTL_SECONDS)
2072
+ ttlSeconds: z$1.number().int().min(900).max(AWS_MAX_TTL_SECONDS)
2073
2073
  });
2074
2074
  /**
2075
2075
  * Client → API: mint a GCP lease. Like AWS (tier 2): the client generates an
@@ -2081,11 +2081,11 @@ const mintAwsLeaseSchema = z.object({
2081
2081
  * TTL bounds are GCP's `generateAccessToken` limits (1 min – 12 h); tokens over
2082
2082
  * 1 h require the credential-lifetime-extension org policy.
2083
2083
  */
2084
- const mintGcpLeaseSchema = z.object({
2085
- provider: z.literal("gcp"),
2086
- targetId: z.string().min(1),
2084
+ const mintGcpLeaseSchema = z$1.object({
2085
+ provider: z$1.literal("gcp"),
2086
+ targetId: z$1.string().min(1),
2087
2087
  recipientPublicKey: p256PublicKeyJwkSchema,
2088
- ttlSeconds: z.number().int().min(60).max(GCP_MAX_TTL_SECONDS)
2088
+ ttlSeconds: z$1.number().int().min(60).max(GCP_MAX_TTL_SECONDS)
2089
2089
  });
2090
2090
  /**
2091
2091
  * Client → API: mint a MongoDB lease. Like AWS (tier 2), the client generates
@@ -2094,13 +2094,13 @@ const mintGcpLeaseSchema = z.object({
2094
2094
  * to that key. The private key never leaves the requesting machine, so the
2095
2095
  * plaintext credential is only decryptable there.
2096
2096
  */
2097
- const mintMongoLeaseSchema = z.object({
2098
- provider: z.literal("mongodb"),
2099
- targetId: z.string().min(1),
2097
+ const mintMongoLeaseSchema = z$1.object({
2098
+ provider: z$1.literal("mongodb"),
2099
+ targetId: z$1.string().min(1),
2100
2100
  recipientPublicKey: p256PublicKeyJwkSchema,
2101
2101
  ttlSeconds: ttlSecondsSchema
2102
2102
  });
2103
- z.discriminatedUnion("provider", [
2103
+ z$1.discriminatedUnion("provider", [
2104
2104
  mintPostgresLeaseSchema,
2105
2105
  mintMysqlLeaseSchema,
2106
2106
  mintRedisLeaseSchema,
@@ -2234,6 +2234,13 @@ function sshHostSetupInstructions(config) {
2234
2234
  "sudo systemctl reload sshd"
2235
2235
  ].join("\n");
2236
2236
  }
2237
+ // ../../packages/core/src/slug.ts
2238
+ /**
2239
+ * The slug rule, with no dependencies — so a caller that cannot afford zod (the
2240
+ * resolve gateway's bundle, see apps/api/src/gateway) validates with the same
2241
+ * pattern `slugSchema` uses rather than a copy of it.
2242
+ */
2243
+ const SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
2237
2244
  // ../../packages/core/src/types.ts
2238
2245
  const AUDIT_ACTIONS = [
2239
2246
  "workload.created",
@@ -2468,94 +2475,94 @@ const NOTIFICATION_TYPE_META = {
2468
2475
  };
2469
2476
  // ../../packages/core/src/schemas.ts
2470
2477
  /** URL-safe identifier segment: `my-app`, `production`, … */
2471
- const slugSchema = z.string().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "must be lowercase alphanumeric with hyphens");
2472
- const nameSchema = z.string().trim().min(1).max(128);
2478
+ const slugSchema = z$1.string().min(1).max(64).regex(SLUG_PATTERN, "must be lowercase alphanumeric with hyphens");
2479
+ const nameSchema = z$1.string().trim().min(1).max(128);
2473
2480
  /** An email address, normalized to trimmed lowercase before validation. */
2474
- const emailSchema = z.string().trim().toLowerCase().pipe(z.email().max(320));
2481
+ const emailSchema = z$1.string().trim().toLowerCase().pipe(z$1.email().max(320));
2475
2482
  /** Env-var style secret name: FOO, DATABASE_URL, apiKey2 … */
2476
- const secretNameSchema = z.string().min(1).max(256).regex(/^[A-Za-z_][A-Za-z0-9_]*$/, "must be a valid environment variable name");
2477
- const orgRoleSchema = z.enum([
2483
+ const secretNameSchema = z$1.string().min(1).max(256).regex(/^[A-Za-z_][A-Za-z0-9_]*$/, "must be a valid environment variable name");
2484
+ const orgRoleSchema = z$1.enum([
2478
2485
  "owner",
2479
2486
  "admin",
2480
2487
  "member"
2481
2488
  ]);
2482
2489
  /** Role a person may be invited at — never `owner` (ownership isn't invitable). */
2483
- const inviteRoleSchema = z.enum(["admin", "member"]);
2484
- const principalTypeSchema = z.enum(["user", "service_token"]);
2490
+ const inviteRoleSchema = z$1.enum(["admin", "member"]);
2491
+ const principalTypeSchema = z$1.enum(["user", "service_token"]);
2485
2492
  /** Org-level capability a service token can hold (never `owner`). */
2486
- const serviceTokenRoleSchema = z.enum(["admin", "member"]);
2487
- z.object({
2493
+ const serviceTokenRoleSchema = z$1.enum(["admin", "member"]);
2494
+ z$1.object({
2488
2495
  /** Include the full append-only ciphertext history of every secret. */
2489
- includeVersions: z.boolean().optional(),
2490
- includeAudit: z.boolean().optional(),
2496
+ includeVersions: z$1.boolean().optional(),
2497
+ includeAudit: z$1.boolean().optional(),
2491
2498
  /** Newest audit rows to keep. Exceeding the server cap is a 400, not a silent trim. */
2492
- auditLimit: z.number().int().min(0).optional()
2499
+ auditLimit: z$1.number().int().min(0).optional()
2493
2500
  });
2494
- z.object({
2501
+ z$1.object({
2495
2502
  name: nameSchema,
2496
2503
  slug: slugSchema
2497
2504
  });
2498
- z.object({
2505
+ z$1.object({
2499
2506
  name: nameSchema,
2500
2507
  slug: slugSchema
2501
2508
  });
2502
- z.object({ name: nameSchema });
2503
- z.object({ name: nameSchema });
2504
- z.object({ name: nameSchema });
2505
- z.object({ name: nameSchema });
2506
- z.object({ name: nameSchema });
2507
- z.object({ required: z.boolean() });
2508
- z.object({
2509
+ z$1.object({ name: nameSchema });
2510
+ z$1.object({ name: nameSchema });
2511
+ z$1.object({ name: nameSchema });
2512
+ z$1.object({ name: nameSchema });
2513
+ z$1.object({ name: nameSchema });
2514
+ z$1.object({ required: z$1.boolean() });
2515
+ z$1.object({
2509
2516
  email: emailSchema,
2510
2517
  role: inviteRoleSchema.default("member")
2511
2518
  });
2512
- z.object({
2519
+ z$1.object({
2513
2520
  name: nameSchema,
2514
2521
  slug: slugSchema
2515
2522
  });
2516
2523
  /** Compose a group into an application environment (matched by env slug). */
2517
- const appAccessKeySchema = z.object({
2518
- environmentId: z.string().min(1),
2519
- userId: z.string().min(1),
2520
- wrappedDek: z.string().min(1).max(8192)
2524
+ const appAccessKeySchema = z$1.object({
2525
+ environmentId: z$1.string().min(1),
2526
+ userId: z$1.string().min(1),
2527
+ wrappedDek: z$1.string().min(1).max(8192)
2521
2528
  });
2522
- const appAccessGrantsSchema = z.array(appAccessKeySchema).max(5e3).optional();
2523
- z.object({
2524
- userId: z.string().min(1),
2525
- grants: z.array(appAccessKeySchema).max(5e3)
2529
+ const appAccessGrantsSchema = z$1.array(appAccessKeySchema).max(5e3).optional();
2530
+ z$1.object({
2531
+ userId: z$1.string().min(1),
2532
+ grants: z$1.array(appAccessKeySchema).max(5e3)
2526
2533
  });
2527
- z.object({ role: orgRoleSchema });
2528
- z.object({
2534
+ z$1.object({ role: orgRoleSchema });
2535
+ z$1.object({
2529
2536
  appAccessGrants: appAccessGrantsSchema,
2530
- groupId: z.string().min(1),
2537
+ groupId: z$1.string().min(1),
2531
2538
  /** Precedence among an env's groups (higher wins). Appended if omitted. */
2532
- position: z.number().int().min(0).optional(),
2539
+ position: z$1.number().int().min(0).optional(),
2533
2540
  /** Client-wrapped group DEK for each sync connection newly reading this group. */
2534
- syncGrants: z.array(z.object({
2535
- connectionId: z.string().min(1),
2536
- wrappedDek: z.string().min(1)
2541
+ syncGrants: z$1.array(z$1.object({
2542
+ connectionId: z$1.string().min(1),
2543
+ wrappedDek: z$1.string().min(1)
2537
2544
  })).optional()
2538
2545
  });
2539
- z.object({
2546
+ z$1.object({
2540
2547
  /** Wrap the new DEK to all persistent app recipients. */
2541
- userGrants: z.array(z.object({
2542
- userId: z.string().min(1),
2543
- wrappedDek: z.string().min(1).max(8192)
2548
+ userGrants: z$1.array(z$1.object({
2549
+ userId: z$1.string().min(1),
2550
+ wrappedDek: z$1.string().min(1).max(8192)
2544
2551
  })).max(5e3).optional(),
2545
2552
  name: nameSchema,
2546
2553
  slug: slugSchema,
2547
2554
  /** Environment DEK wrapped to the creator's public key — created client-side. */
2548
- wrappedDek: z.string().min(1),
2555
+ wrappedDek: z$1.string().min(1),
2549
2556
  /**
2550
2557
  * When the org has recovery enabled, the same DEK additionally wrapped to the
2551
2558
  * org recovery public key, so the environment is recovery-protected from
2552
2559
  * creation. Omitted when recovery is off (backfilled later by `recovery sync`).
2553
2560
  */
2554
- recoveryWrappedDek: z.string().min(1).nullish()
2561
+ recoveryWrappedDek: z$1.string().min(1).nullish()
2555
2562
  });
2556
- z.object({
2563
+ z$1.object({
2557
2564
  /** Opaque versioned ciphertext blob from @seekrit/crypto. */
2558
- ciphertext: z.string().min(1).max(65536),
2565
+ ciphertext: z$1.string().min(1).max(65536),
2559
2566
  /**
2560
2567
  * Compare-and-swap: write only if the secret is currently at this version
2561
2568
  * (`0` = only if it does not exist yet), else 412 `precondition_failed`.
@@ -2563,77 +2570,77 @@ z.object({
2563
2570
  * changed, and wrote back — a refreshed agent login, say — find out that
2564
2571
  * someone else wrote in between instead of silently erasing their value.
2565
2572
  */
2566
- expectedVersion: z.number().int().min(0).optional()
2573
+ expectedVersion: z$1.number().int().min(0).optional()
2567
2574
  });
2568
- z.object({ version: z.number().int().positive() });
2569
- z.object({ limit: z.coerce.number().int().min(1).max(200).default(50) });
2570
- z.object({
2571
- requiredApprovals: z.number().int().min(1).max(10).default(1),
2572
- allowSelfApproval: z.boolean().default(false)
2575
+ z$1.object({ version: z$1.number().int().positive() });
2576
+ z$1.object({ limit: z$1.coerce.number().int().min(1).max(200).default(50) });
2577
+ z$1.object({
2578
+ requiredApprovals: z$1.number().int().min(1).max(10).default(1),
2579
+ allowSelfApproval: z$1.boolean().default(false)
2573
2580
  });
2574
- z.object({ comment: z.string().trim().max(1e3).optional() });
2575
- z.string().trim().min(1).max(1e3);
2576
- z.object({
2577
- status: z.enum(CHANGE_REQUEST_STATUSES).optional(),
2578
- envId: z.string().min(1).optional(),
2579
- limit: z.coerce.number().int().min(1).max(200).default(50)
2581
+ z$1.object({ comment: z$1.string().trim().max(1e3).optional() });
2582
+ z$1.string().trim().min(1).max(1e3);
2583
+ z$1.object({
2584
+ status: z$1.enum(CHANGE_REQUEST_STATUSES).optional(),
2585
+ envId: z$1.string().min(1).optional(),
2586
+ limit: z$1.coerce.number().int().min(1).max(200).default(50)
2580
2587
  });
2581
- z.object({
2582
- publicKeyJwk: z.string().min(1),
2588
+ z$1.object({
2589
+ publicKeyJwk: z$1.string().min(1),
2583
2590
  /**
2584
2591
  * Private key encrypted with a passphrase-derived KEK; opaque to the
2585
2592
  * server. Self-contained blob (embeds KDF salt + iterations).
2586
2593
  */
2587
- encryptedPrivateKey: z.string().min(1)
2594
+ encryptedPrivateKey: z$1.string().min(1)
2588
2595
  });
2589
- z.object({
2596
+ z$1.object({
2590
2597
  /** Base64url WebAuthn credential id — what `allowCredentials` is built from. */
2591
- credentialId: z.string().min(1).max(512),
2598
+ credentialId: z$1.string().min(1).max(512),
2592
2599
  /** Human label for the device, e.g. "MacBook Touch ID". Display only. */
2593
- label: z.string().min(1).max(64),
2600
+ label: z$1.string().min(1).max(64),
2594
2601
  /** Base64url PRF evaluation input for this credential; not a secret. */
2595
- prfInput: z.string().min(1).max(256),
2602
+ prfInput: z$1.string().min(1).max(256),
2596
2603
  /** The private key wrapped to this passkey's PRF output. */
2597
- encryptedPrivateKey: z.string().min(1).max(8192).refine((v) => v.startsWith("pk2."), { message: "expected a pk2. passkey wrap" })
2604
+ encryptedPrivateKey: z$1.string().min(1).max(8192).refine((v) => v.startsWith("pk2."), { message: "expected a pk2. passkey wrap" })
2598
2605
  });
2599
- const grantEnvironmentKeySchema = z.object({
2606
+ const grantEnvironmentKeySchema = z$1.object({
2600
2607
  principalType: principalTypeSchema,
2601
- principalId: z.string().min(1),
2602
- wrappedDek: z.string().min(1)
2608
+ principalId: z$1.string().min(1),
2609
+ wrappedDek: z$1.string().min(1)
2603
2610
  });
2604
- z.object({
2611
+ z$1.object({
2605
2612
  slug: slugSchema,
2606
2613
  /** Display name; defaults to the slug. */
2607
2614
  name: nameSchema.optional(),
2608
- ttlSeconds: z.number().int().min(60).max(MAX_BRANCH_TTL_SECONDS).nullish(),
2615
+ ttlSeconds: z$1.number().int().min(60).max(MAX_BRANCH_TTL_SECONDS).nullish(),
2609
2616
  /** The branch's own DEK, wrapped to the creator — generated client-side. */
2610
- wrappedDek: z.string().min(1),
2611
- recoveryWrappedDek: z.string().min(1).nullish(),
2617
+ wrappedDek: z$1.string().min(1),
2618
+ recoveryWrappedDek: z$1.string().min(1).nullish(),
2612
2619
  /** The same DEK wrapped to each of the parent's existing grant-holders. */
2613
- grants: z.array(grantEnvironmentKeySchema).max(500).default([])
2620
+ grants: z$1.array(grantEnvironmentKeySchema).max(500).default([])
2614
2621
  });
2615
2622
  /**
2616
2623
  * Token creation is client-driven so the server never sees the token secret:
2617
2624
  * the client generates the keypair + token string and submits only the hash
2618
2625
  * and public key.
2619
2626
  */
2620
- const environmentGrantBatchSchema = z.array(z.object({
2621
- environmentId: z.string().min(1),
2622
- wrappedDek: z.string().min(1).max(8192)
2627
+ const environmentGrantBatchSchema = z$1.array(z$1.object({
2628
+ environmentId: z$1.string().min(1),
2629
+ wrappedDek: z$1.string().min(1).max(8192)
2623
2630
  })).max(5e3);
2624
- z.object({
2631
+ z$1.object({
2625
2632
  principalType: principalTypeSchema,
2626
- principalId: z.string().min(1),
2633
+ principalId: z$1.string().min(1),
2627
2634
  grants: environmentGrantBatchSchema
2628
2635
  });
2629
- z.object({
2636
+ z$1.object({
2630
2637
  /** Commit the token and all default resolve keys together, when supplied. */
2631
2638
  initialGrants: environmentGrantBatchSchema.optional(),
2632
2639
  name: nameSchema,
2633
- tokenId: z.string().regex(/^skt_[0-9A-Za-z]+$/),
2640
+ tokenId: z$1.string().regex(/^skt_[0-9A-Za-z]+$/),
2634
2641
  /** SHA-256 hash (base64url) of the full token string. */
2635
- tokenHash: z.string().min(1),
2636
- publicKeyJwk: z.string().min(1),
2642
+ tokenHash: z$1.string().min(1),
2643
+ publicKeyJwk: z$1.string().min(1),
2637
2644
  /**
2638
2645
  * Org-level capability. Defaults to `member` (a runtime credential); pass
2639
2646
  * `admin` to mint a headless provisioning token. Only an admin caller may
@@ -2645,35 +2652,35 @@ z.object({
2645
2652
  * Optional so org-admin tokens can exist, but required for runtime tokens
2646
2653
  * that resolve secrets via `GET /v1/resolve`.
2647
2654
  */
2648
- environmentId: z.string().min(1).nullish(),
2649
- expiresAt: z.iso.datetime().nullish()
2655
+ environmentId: z$1.string().min(1).nullish(),
2656
+ expiresAt: z$1.iso.datetime().nullish()
2650
2657
  });
2651
- z.object({
2658
+ z$1.object({
2652
2659
  name: nameSchema,
2653
- tokenId: z.string().regex(/^skt_[0-9A-Za-z]+$/),
2660
+ tokenId: z$1.string().regex(/^skt_[0-9A-Za-z]+$/),
2654
2661
  /** SHA-256 hash (base64url) of the full token string. */
2655
- tokenHash: z.string().min(1),
2662
+ tokenHash: z$1.string().min(1),
2656
2663
  /** Where the decoy was planted, as a reminder for whoever reads the alert. */
2657
- placement: z.string().max(200).nullish()
2664
+ placement: z$1.string().max(200).nullish()
2658
2665
  });
2659
- const kmsKeyPurposeSchema = z.enum(["encrypt", "sign"]);
2660
- const kmsKeySpecSchema = z.enum(["aes-256-gcm", "ecdsa-p256"]);
2666
+ const kmsKeyPurposeSchema = z$1.enum(["encrypt", "sign"]);
2667
+ const kmsKeySpecSchema = z$1.enum(["aes-256-gcm", "ecdsa-p256"]);
2661
2668
  /** A wrapped key grant supplied by the client (server never sees plaintext material). */
2662
- const kmsGrantInputSchema = z.object({
2669
+ const kmsGrantInputSchema = z$1.object({
2663
2670
  principalType: principalTypeSchema,
2664
- principalId: z.string().min(1),
2671
+ principalId: z$1.string().min(1),
2665
2672
  /** Key material wrapped to the principal's public key (`wd1.` blob). */
2666
- wrappedKey: z.string().min(1)
2673
+ wrappedKey: z$1.string().min(1)
2667
2674
  });
2668
- z.object({
2675
+ z$1.object({
2669
2676
  name: nameSchema,
2670
2677
  purpose: kmsKeyPurposeSchema,
2671
2678
  spec: kmsKeySpecSchema,
2672
- applicationId: z.string().min(1).nullish(),
2673
- groupId: z.string().min(1).nullish(),
2679
+ applicationId: z$1.string().min(1).nullish(),
2680
+ groupId: z$1.string().min(1).nullish(),
2674
2681
  /** ECDSA P-256 public key (JWK) for `sign` keys; omit for `encrypt` keys. */
2675
- publicKeyJwk: z.string().min(1).nullish(),
2676
- grants: z.array(kmsGrantInputSchema).min(1)
2682
+ publicKeyJwk: z$1.string().min(1).nullish(),
2683
+ grants: z$1.array(kmsGrantInputSchema).min(1)
2677
2684
  }).refine((v) => !(v.applicationId && v.groupId), {
2678
2685
  message: "a key may be scoped to an application or a group, not both",
2679
2686
  path: ["groupId"]
@@ -2684,15 +2691,15 @@ z.object({
2684
2691
  message: "sign keys require a publicKeyJwk; encrypt keys must omit it",
2685
2692
  path: ["publicKeyJwk"]
2686
2693
  });
2687
- z.object({
2694
+ z$1.object({
2688
2695
  principalType: principalTypeSchema,
2689
- principalId: z.string().min(1),
2696
+ principalId: z$1.string().min(1),
2690
2697
  /** Current-version key material wrapped to the principal's public key. */
2691
- wrappedKey: z.string().min(1)
2698
+ wrappedKey: z$1.string().min(1)
2692
2699
  });
2693
- z.object({
2694
- publicKeyJwk: z.string().min(1).nullish(),
2695
- grants: z.array(kmsGrantInputSchema).min(1)
2700
+ z$1.object({
2701
+ publicKeyJwk: z$1.string().min(1).nullish(),
2702
+ grants: z$1.array(kmsGrantInputSchema).min(1)
2696
2703
  });
2697
2704
  /**
2698
2705
  * One custodian's wrapped Shamir share of the org recovery private key. The
@@ -2700,25 +2707,25 @@ z.object({
2700
2707
  * wraps each share to a custodian's public key — the server stores only the
2701
2708
  * opaque `wrappedShare` and can reconstruct nothing.
2702
2709
  */
2703
- const recoveryShareInputSchema = z.object({
2710
+ const recoveryShareInputSchema = z$1.object({
2704
2711
  principalType: principalTypeSchema,
2705
- principalId: z.string().min(1),
2712
+ principalId: z$1.string().min(1),
2706
2713
  /** Shamir x-coordinate carried by the share (1..255). */
2707
- shareIndex: z.number().int().min(1).max(255),
2714
+ shareIndex: z$1.number().int().min(1).max(255),
2708
2715
  /** The recovery-key share wrapped to the custodian's public key (`wd1.`). */
2709
- wrappedShare: z.string().min(1)
2716
+ wrappedShare: z$1.string().min(1)
2710
2717
  });
2711
2718
  /** An environment DEK additionally wrapped to the org recovery public key. */
2712
- const recoveryEnvGrantSchema = z.object({
2713
- environmentId: z.string().min(1),
2719
+ const recoveryEnvGrantSchema = z$1.object({
2720
+ environmentId: z$1.string().min(1),
2714
2721
  /** The environment's DEK wrapped to the recovery public key (`wd1.`). */
2715
- wrappedDek: z.string().min(1)
2722
+ wrappedDek: z$1.string().min(1)
2716
2723
  });
2717
- z.object({
2718
- recoveryPublicKeyJwk: z.string().min(1),
2719
- threshold: z.number().int().min(1).max(255),
2720
- shares: z.array(recoveryShareInputSchema).min(1).max(255),
2721
- grants: z.array(recoveryEnvGrantSchema).default([])
2724
+ z$1.object({
2725
+ recoveryPublicKeyJwk: z$1.string().min(1),
2726
+ threshold: z$1.number().int().min(1).max(255),
2727
+ shares: z$1.array(recoveryShareInputSchema).min(1).max(255),
2728
+ grants: z$1.array(recoveryEnvGrantSchema).default([])
2722
2729
  }).refine((v) => v.threshold <= v.shares.length, {
2723
2730
  message: "threshold cannot exceed the number of custodians",
2724
2731
  path: ["threshold"]
@@ -2726,104 +2733,104 @@ z.object({
2726
2733
  message: "custodians must be distinct",
2727
2734
  path: ["shares"]
2728
2735
  });
2729
- z.object({ grants: z.array(recoveryEnvGrantSchema).min(1).max(500) });
2730
- z.object({
2731
- targetPublicKeyJwk: z.string().min(1),
2736
+ z$1.object({ grants: z$1.array(recoveryEnvGrantSchema).min(1).max(500) });
2737
+ z$1.object({
2738
+ targetPublicKeyJwk: z$1.string().min(1),
2732
2739
  targetType: principalTypeSchema.nullish(),
2733
- targetId: z.string().min(1).nullish(),
2734
- reason: z.string().max(500).nullish()
2740
+ targetId: z$1.string().min(1).nullish(),
2741
+ reason: z$1.string().max(500).nullish()
2735
2742
  });
2736
- z.object({
2737
- shareIndex: z.number().int().min(1).max(255),
2743
+ z$1.object({
2744
+ shareIndex: z$1.number().int().min(1).max(255),
2738
2745
  /** The custodian's share re-wrapped to the target public key (`wd1.`). */
2739
- contributedShare: z.string().min(1)
2746
+ contributedShare: z$1.string().min(1)
2740
2747
  });
2741
- z.object({
2748
+ z$1.object({
2742
2749
  principalType: principalTypeSchema,
2743
- principalId: z.string().min(1),
2744
- grants: z.array(recoveryEnvGrantSchema).min(1).max(500)
2750
+ principalId: z$1.string().min(1),
2751
+ grants: z$1.array(recoveryEnvGrantSchema).min(1).max(500)
2745
2752
  });
2746
- z.object({ prefs: z.partialRecord(z.enum(NOTIFICATION_TYPES), z.boolean()) });
2747
- z.object({
2748
- endpoint: z.url().max(2048),
2749
- headers: z.record(z.string().min(1).max(256), z.string().max(4096)).optional(),
2750
- enabled: z.boolean().default(true)
2753
+ z$1.object({ prefs: z$1.partialRecord(z$1.enum(NOTIFICATION_TYPES), z$1.boolean()) });
2754
+ z$1.object({
2755
+ endpoint: z$1.url().max(2048),
2756
+ headers: z$1.record(z$1.string().min(1).max(256), z$1.string().max(4096)).optional(),
2757
+ enabled: z$1.boolean().default(true)
2751
2758
  });
2752
- const planFamilySchema = z.enum(PLAN_FAMILY_IDS);
2753
- const subscriptionStatusSchema = z.enum(SUBSCRIPTION_STATUSES);
2754
- z.enum(ENTITLEMENT_KEYS);
2759
+ const planFamilySchema = z$1.enum(PLAN_FAMILY_IDS);
2760
+ const subscriptionStatusSchema = z$1.enum(SUBSCRIPTION_STATUSES);
2761
+ z$1.enum(ENTITLEMENT_KEYS);
2755
2762
  /** An entitlement value: boolean (features), number or null/unlimited (limits, metered). */
2756
- const entitlementValueSchema = z.union([
2757
- z.boolean(),
2758
- z.number(),
2759
- z.null()
2763
+ const entitlementValueSchema = z$1.union([
2764
+ z$1.boolean(),
2765
+ z$1.number(),
2766
+ z$1.null()
2760
2767
  ]);
2761
- z.object({
2768
+ z$1.object({
2762
2769
  family: planFamilySchema,
2763
- version: z.number().int().positive().optional(),
2770
+ version: z$1.number().int().positive().optional(),
2764
2771
  status: subscriptionStatusSchema.default("active")
2765
2772
  });
2766
- z.object({
2773
+ z$1.object({
2767
2774
  value: entitlementValueSchema,
2768
- note: z.string().max(500).nullish(),
2769
- expiresAt: z.iso.datetime().nullish()
2775
+ note: z$1.string().max(500).nullish(),
2776
+ expiresAt: z$1.iso.datetime().nullish()
2770
2777
  });
2771
- z.object({
2772
- code: z.string().min(4).max(40),
2778
+ z$1.object({
2779
+ code: z$1.string().min(4).max(40),
2773
2780
  family: planFamilySchema,
2774
- version: z.number().int().positive().optional(),
2775
- durationDays: z.number().int().positive().max(3650).nullish(),
2776
- maxRedemptions: z.number().int().positive().nullish(),
2777
- startsAt: z.iso.datetime().nullish(),
2778
- endsAt: z.iso.datetime().nullish(),
2779
- note: z.string().max(500).nullish()
2781
+ version: z$1.number().int().positive().optional(),
2782
+ durationDays: z$1.number().int().positive().max(3650).nullish(),
2783
+ maxRedemptions: z$1.number().int().positive().nullish(),
2784
+ startsAt: z$1.iso.datetime().nullish(),
2785
+ endsAt: z$1.iso.datetime().nullish(),
2786
+ note: z$1.string().max(500).nullish()
2780
2787
  });
2781
- z.object({
2782
- maxRedemptions: z.number().int().positive().nullish(),
2783
- startsAt: z.iso.datetime().nullish(),
2784
- endsAt: z.iso.datetime().nullish(),
2785
- note: z.string().max(500).nullish(),
2788
+ z$1.object({
2789
+ maxRedemptions: z$1.number().int().positive().nullish(),
2790
+ startsAt: z$1.iso.datetime().nullish(),
2791
+ endsAt: z$1.iso.datetime().nullish(),
2792
+ note: z$1.string().max(500).nullish(),
2786
2793
  /** Kill switch. Disabling stops new redemptions; live grants are untouched. */
2787
- disabled: z.boolean().optional()
2794
+ disabled: z$1.boolean().optional()
2788
2795
  });
2789
- z.object({ code: z.string().min(1).max(40) });
2790
- z.object({ family: planFamilySchema });
2791
- z.object({
2792
- sessionId: z.string().regex(/^skc_[0-9A-Za-z]+$/),
2796
+ z$1.object({ code: z$1.string().min(1).max(40) });
2797
+ z$1.object({ family: planFamilySchema });
2798
+ z$1.object({
2799
+ sessionId: z$1.string().regex(/^skc_[0-9A-Za-z]+$/),
2793
2800
  /** SHA-256 hash (base64url) of the full session token string. */
2794
- tokenHash: z.string().min(1).max(128),
2801
+ tokenHash: z$1.string().min(1).max(128),
2795
2802
  /** Display-only, e.g. `miles@studio.local`. */
2796
- deviceLabel: z.string().trim().min(1).max(120),
2803
+ deviceLabel: z$1.string().trim().min(1).max(120),
2797
2804
  /** Display-only, e.g. `cli/0.4.2`. */
2798
- client: z.string().trim().max(60).optional()
2805
+ client: z$1.string().trim().max(60).optional()
2799
2806
  });
2800
- z.object({ code: z.string().trim().min(1).max(32) });
2801
- z.object({
2802
- cursor: z.string().optional(),
2803
- limit: z.coerce.number().int().min(1).max(200).default(50),
2804
- action: z.string().optional(),
2805
- resourceType: z.string().optional()
2807
+ z$1.object({ code: z$1.string().trim().min(1).max(32) });
2808
+ z$1.object({
2809
+ cursor: z$1.string().optional(),
2810
+ limit: z$1.coerce.number().int().min(1).max(200).default(50),
2811
+ action: z$1.string().optional(),
2812
+ resourceType: z$1.string().optional()
2806
2813
  });
2807
- z.enum([
2814
+ z$1.enum([
2808
2815
  "generated",
2809
2816
  "postgres",
2810
2817
  "mysql",
2811
2818
  "redis"
2812
2819
  ]);
2813
- z.enum([
2820
+ z$1.enum([
2814
2821
  "active",
2815
2822
  "paused",
2816
2823
  "failed"
2817
2824
  ]);
2818
2825
  /** Statuses an admin may set directly (`failed` is only reached by the sweep). */
2819
- const settableRotationStatusSchema = z.enum(["active", "paused"]);
2820
- const rotationAlphabetSchema = z.enum([
2826
+ const settableRotationStatusSchema = z$1.enum(["active", "paused"]);
2827
+ const rotationAlphabetSchema = z$1.enum([
2821
2828
  "alphanumeric",
2822
2829
  "hex",
2823
2830
  "base64url",
2824
2831
  "printable"
2825
2832
  ]);
2826
- const rotationIntervalSchema = z.number().int().min(300).max(31536e3);
2833
+ const rotationIntervalSchema = z$1.number().int().min(300).max(31536e3);
2827
2834
  /**
2828
2835
  * A database user name we are willing to *re-key*. Deliberately more permissive
2829
2836
  * than the lease providers' name schemas — those name accounts seekrit creates,
@@ -2836,44 +2843,44 @@ const rotationIntervalSchema = z.number().int().min(300).max(31536e3);
2836
2843
  * `;`, so there is no way out of the surrounding quoting, and no whitespace to
2837
2844
  * split one Redis argument into two.
2838
2845
  */
2839
- const rotationUsernameSchema = z.string().regex(/^[A-Za-z0-9_$.-]{1,63}$/, "must be 1–63 chars of letters, digits, underscore, dollar, dot or dash");
2846
+ const rotationUsernameSchema = z$1.string().regex(/^[A-Za-z0-9_$.-]{1,63}$/, "must be 1–63 chars of letters, digits, underscore, dollar, dot or dash");
2840
2847
  /** A `{{name}}`/`{{host}}`/`{{verifier}}` templated statement or command line. */
2841
- const statementSchema = z.string().min(1).max(4e3);
2842
- const passwordLengthSchema = z.number().int().min(16).max(256);
2848
+ const statementSchema = z$1.string().min(1).max(4e3);
2849
+ const passwordLengthSchema = z$1.number().int().min(16).max(256);
2843
2850
  /** A MySQL account host part (`'name'@'<host>'`) — no quotes/whitespace. */
2844
- const mysqlHostSchema = z.string().regex(/^[A-Za-z0-9_.%:-]{1,255}$/, "must be a host pattern");
2845
- const generatedRotationConfigSchema = z.object({
2846
- kind: z.literal("generated"),
2851
+ const mysqlHostSchema = z$1.string().regex(/^[A-Za-z0-9_.%:-]{1,255}$/, "must be a host pattern");
2852
+ const generatedRotationConfigSchema = z$1.object({
2853
+ kind: z$1.literal("generated"),
2847
2854
  length: passwordLengthSchema.optional(),
2848
2855
  alphabet: rotationAlphabetSchema.optional()
2849
2856
  });
2850
- const postgresRotationConfigSchema = z.object({
2851
- kind: z.literal("postgres"),
2857
+ const postgresRotationConfigSchema = z$1.object({
2858
+ kind: z$1.literal("postgres"),
2852
2859
  username: rotationUsernameSchema,
2853
2860
  passwordLength: passwordLengthSchema.optional(),
2854
- statements: z.array(statementSchema).max(16).optional()
2861
+ statements: z$1.array(statementSchema).max(16).optional()
2855
2862
  });
2856
- const mysqlRotationConfigSchema = z.object({
2857
- kind: z.literal("mysql"),
2863
+ const mysqlRotationConfigSchema = z$1.object({
2864
+ kind: z$1.literal("mysql"),
2858
2865
  username: rotationUsernameSchema,
2859
2866
  userHost: mysqlHostSchema.optional(),
2860
2867
  passwordLength: passwordLengthSchema.optional(),
2861
- statements: z.array(statementSchema).max(16).optional()
2868
+ statements: z$1.array(statementSchema).max(16).optional()
2862
2869
  });
2863
- const redisRotationConfigSchema = z.object({
2864
- kind: z.literal("redis"),
2870
+ const redisRotationConfigSchema = z$1.object({
2871
+ kind: z$1.literal("redis"),
2865
2872
  username: rotationUsernameSchema,
2866
2873
  passwordLength: passwordLengthSchema.optional(),
2867
- statements: z.array(statementSchema).max(16).optional()
2874
+ statements: z$1.array(statementSchema).max(16).optional()
2868
2875
  });
2869
- const rotationConfigSchema = z.discriminatedUnion("kind", [
2876
+ const rotationConfigSchema = z$1.discriminatedUnion("kind", [
2870
2877
  generatedRotationConfigSchema,
2871
2878
  postgresRotationConfigSchema,
2872
2879
  mysqlRotationConfigSchema,
2873
2880
  redisRotationConfigSchema
2874
2881
  ]);
2875
- z.object({
2876
- environmentId: z.string().min(1),
2882
+ z$1.object({
2883
+ environmentId: z$1.string().min(1),
2877
2884
  /** The secret whose value rotates. It must already exist. */
2878
2885
  secretName: secretNameSchema,
2879
2886
  config: rotationConfigSchema,
@@ -2882,13 +2889,13 @@ z.object({
2882
2889
  * The registered lease target supplying the connection, executor mode, and
2883
2890
  * wrapped admin credential. Required for every kind but `generated`.
2884
2891
  */
2885
- targetId: z.string().min(1).optional(),
2892
+ targetId: z$1.string().min(1).optional(),
2886
2893
  /** Environment DEK wrapped to the rotator public key (`wd1.` blob). */
2887
- wrappedDek: z.string().min(1).optional(),
2894
+ wrappedDek: z$1.string().min(1).optional(),
2888
2895
  /** Rotate once immediately instead of waiting for the first interval. */
2889
- rotateNow: z.boolean().optional()
2896
+ rotateNow: z$1.boolean().optional()
2890
2897
  });
2891
- z.object({
2898
+ z$1.object({
2892
2899
  intervalSeconds: rotationIntervalSchema.optional(),
2893
2900
  config: rotationConfigSchema.optional(),
2894
2901
  /**
@@ -2948,7 +2955,7 @@ const SYNC_PROVIDER_KINDS = [
2948
2955
  "openai-vault",
2949
2956
  "claude-managed-agents"
2950
2957
  ];
2951
- z.enum(SYNC_PROVIDER_KINDS);
2958
+ z$1.enum(SYNC_PROVIDER_KINDS);
2952
2959
  /**
2953
2960
  * Vercel account scope. The API token itself is never here — it is wrapped to
2954
2961
  * the connection's public key and stored as ciphertext.
@@ -2957,10 +2964,10 @@ z.enum(SYNC_PROVIDER_KINDS);
2957
2964
  * tokens omit it. Vercel rejects team-owned project calls that lack it with a
2958
2965
  * bare 403, so we pass it through as `?teamId=` on every request.
2959
2966
  */
2960
- const vercelConnectionConfigSchema = z.object({
2961
- provider: z.literal("vercel"),
2967
+ const vercelConnectionConfigSchema = z$1.object({
2968
+ provider: z$1.literal("vercel"),
2962
2969
  /** Vercel Team id (`team_…`). Omit for a personal account. */
2963
- teamId: z.string().trim().min(1).max(128).optional()
2970
+ teamId: z$1.string().trim().min(1).max(128).optional()
2964
2971
  });
2965
2972
  /**
2966
2973
  * A Cloudflare account id — 32 lowercase hex characters, found in the sidebar
@@ -2971,7 +2978,7 @@ const vercelConnectionConfigSchema = z.object({
2971
2978
  * hours later inside an alarm, with nobody watching. It does not catch pasting
2972
2979
  * a *zone* id, which has the same shape — only the API can tell those apart.
2973
2980
  */
2974
- const cloudflareAccountIdSchema = z.string().trim().regex(/^[0-9a-f]{32}$/, "must be a 32-character Cloudflare account ID (lowercase hex)");
2981
+ const cloudflareAccountIdSchema = z$1.string().trim().regex(/^[0-9a-f]{32}$/, "must be a 32-character Cloudflare account ID (lowercase hex)");
2975
2982
  /**
2976
2983
  * Cloudflare account scope, shared by all three Cloudflare providers. The API
2977
2984
  * token is never here — it is wrapped to the connection's public key and
@@ -2982,16 +2989,16 @@ const cloudflareAccountIdSchema = z.string().trim().regex(/^[0-9a-f]{32}$/, "mus
2982
2989
  * destinations, and fail in different ways. Splitting them keeps the
2983
2990
  * exhaustiveness guard in `connectorFor` meaningful.
2984
2991
  */
2985
- const cloudflareWorkersConnectionConfigSchema = z.object({
2986
- provider: z.literal("cloudflare-workers"),
2992
+ const cloudflareWorkersConnectionConfigSchema = z$1.object({
2993
+ provider: z$1.literal("cloudflare-workers"),
2987
2994
  accountId: cloudflareAccountIdSchema
2988
2995
  });
2989
- const cloudflarePagesConnectionConfigSchema = z.object({
2990
- provider: z.literal("cloudflare-pages"),
2996
+ const cloudflarePagesConnectionConfigSchema = z$1.object({
2997
+ provider: z$1.literal("cloudflare-pages"),
2991
2998
  accountId: cloudflareAccountIdSchema
2992
2999
  });
2993
- const cloudflareSecretsStoreConnectionConfigSchema = z.object({
2994
- provider: z.literal("cloudflare-secrets-store"),
3000
+ const cloudflareSecretsStoreConnectionConfigSchema = z$1.object({
3001
+ provider: z$1.literal("cloudflare-secrets-store"),
2995
3002
  accountId: cloudflareAccountIdSchema
2996
3003
  });
2997
3004
  /**
@@ -3000,7 +3007,7 @@ const cloudflareSecretsStoreConnectionConfigSchema = z.object({
3000
3007
  * bare GraphQL "Problem processing request" hours later inside an alarm, with
3001
3008
  * nobody watching.
3002
3009
  */
3003
- const railwayIdSchema = z.string().trim().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, "must be a Railway UUID");
3010
+ const railwayIdSchema = z$1.string().trim().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, "must be a Railway UUID");
3004
3011
  /**
3005
3012
  * Which kind of Railway API token the connection holds. This is connection
3006
3013
  * scope rather than a destination detail because it decides the *header* the
@@ -3024,9 +3031,9 @@ const RAILWAY_TOKEN_KINDS = ["account", "project"];
3024
3031
  * a destination names its project outright, so the token plus the destination
3025
3032
  * is the whole address.
3026
3033
  */
3027
- const railwayConnectionConfigSchema = z.object({
3028
- provider: z.literal("railway"),
3029
- tokenKind: z.enum(RAILWAY_TOKEN_KINDS).default("account")
3034
+ const railwayConnectionConfigSchema = z$1.object({
3035
+ provider: z$1.literal("railway"),
3036
+ tokenKind: z$1.enum(RAILWAY_TOKEN_KINDS).default("account")
3030
3037
  });
3031
3038
  /**
3032
3039
  * An AWS region id (`us-east-1`, `eu-central-1`, `us-gov-west-1`).
@@ -3036,7 +3043,7 @@ const railwayConnectionConfigSchema = z.object({
3036
3043
  * would otherwise surface as a DNS failure inside an alarm with nobody
3037
3044
  * watching — which is a much worse place to learn about it than this form.
3038
3045
  */
3039
- const awsRegionSchema = z.string().trim().regex(/^[a-z]{2}(-[a-z]+)+-\d$/, "must be an AWS region ID, e.g. us-east-1");
3046
+ const awsRegionSchema = z$1.string().trim().regex(/^[a-z]{2}(-[a-z]+)+-\d$/, "must be an AWS region ID, e.g. us-east-1");
3040
3047
  /**
3041
3048
  * The IAM access key id seekrit signs with.
3042
3049
  *
@@ -3051,7 +3058,7 @@ const awsRegionSchema = z.string().trim().regex(/^[a-z]{2}(-[a-z]+)+-\d$/, "must
3051
3058
  * Long-lived IAM user keys only. `ASIA…` session credentials from STS expire
3052
3059
  * within hours, and a sync connection has to keep working unattended.
3053
3060
  */
3054
- const awsAccessKeyIdSchema = z.string().trim().regex(/^[A-Z0-9]{16,128}$/, "must be an AWS access key ID, e.g. AKIAIOSFODNN7EXAMPLE");
3061
+ const awsAccessKeyIdSchema = z$1.string().trim().regex(/^[A-Z0-9]{16,128}$/, "must be an AWS access key ID, e.g. AKIAIOSFODNN7EXAMPLE");
3055
3062
  /**
3056
3063
  * AWS account scope, shared by both AWS providers: which region to call and
3057
3064
  * which key to sign with. There is no account id — every endpoint seekrit calls
@@ -3062,13 +3069,13 @@ const awsAccessKeyIdSchema = z.string().trim().regex(/^[A-Z0-9]{16,128}$/, "must
3062
3069
  * the three Cloudflare kinds are separate: different APIs, different
3063
3070
  * destinations, different IAM actions.
3064
3071
  */
3065
- const awsSecretsManagerConnectionConfigSchema = z.object({
3066
- provider: z.literal("aws-secrets-manager"),
3072
+ const awsSecretsManagerConnectionConfigSchema = z$1.object({
3073
+ provider: z$1.literal("aws-secrets-manager"),
3067
3074
  region: awsRegionSchema,
3068
3075
  accessKeyId: awsAccessKeyIdSchema
3069
3076
  });
3070
- const awsParameterStoreConnectionConfigSchema = z.object({
3071
- provider: z.literal("aws-parameter-store"),
3077
+ const awsParameterStoreConnectionConfigSchema = z$1.object({
3078
+ provider: z$1.literal("aws-parameter-store"),
3072
3079
  region: awsRegionSchema,
3073
3080
  accessKeyId: awsAccessKeyIdSchema
3074
3081
  });
@@ -3082,7 +3089,7 @@ const awsParameterStoreConnectionConfigSchema = z.object({
3082
3089
  * nothing is stored. The connection's `name` is what tells an operator which Render
3083
3090
  * workspace it belongs to.
3084
3091
  */
3085
- const renderConnectionConfigSchema = z.object({ provider: z.literal("render") });
3092
+ const renderConnectionConfigSchema = z$1.object({ provider: z$1.literal("render") });
3086
3093
  /**
3087
3094
  * Fly.io account scope — empty, as Render's is.
3088
3095
  *
@@ -3092,7 +3099,7 @@ const renderConnectionConfigSchema = z.object({ provider: z.literal("render") })
3092
3099
  * is — Fly's two token shapes do take different auth schemes, but
3093
3100
  * `flyAuthorization` in the connector reads which one from the token itself.
3094
3101
  */
3095
- const flyConnectionConfigSchema = z.object({ provider: z.literal("fly") });
3102
+ const flyConnectionConfigSchema = z$1.object({ provider: z$1.literal("fly") });
3096
3103
  /**
3097
3104
  * A Northflank id — projects and secret groups are both slugs derived from the
3098
3105
  * name they were created with (`default-project`, `example-secret-group`), and
@@ -3100,7 +3107,7 @@ const flyConnectionConfigSchema = z.object({ provider: z.literal("fly") });
3100
3107
  * so the common slip — pasting the *display name*, spaces and all — fails here
3101
3108
  * rather than as a bare 404 inside an alarm with nobody watching.
3102
3109
  */
3103
- const northflankIdSchema = z.string().trim().min(3).max(100).regex(/^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$/, "must be a Northflank ID — the slug in the resource's URL, not its display name");
3110
+ const northflankIdSchema = z$1.string().trim().min(3).max(100).regex(/^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$/, "must be a Northflank ID — the slug in the resource's URL, not its display name");
3104
3111
  /**
3105
3112
  * Northflank account scope — deliberately empty.
3106
3113
  *
@@ -3110,7 +3117,7 @@ const northflankIdSchema = z.string().trim().min(3).max(100).regex(/^[a-zA-Z0-9]
3110
3117
  * Cloudflare does: the token plus the destination's project is the whole
3111
3118
  * address. The kind exists so the discriminated union stays uniform.
3112
3119
  */
3113
- const northflankConnectionConfigSchema = z.object({ provider: z.literal("northflank") });
3120
+ const northflankConnectionConfigSchema = z$1.object({ provider: z$1.literal("northflank") });
3114
3121
  /**
3115
3122
  * DigitalOcean account scope — deliberately empty, as Render's and Fly's are.
3116
3123
  *
@@ -3120,7 +3127,7 @@ const northflankConnectionConfigSchema = z.object({ provider: z.literal("northfl
3120
3127
  * disambiguate the way Vercel needs one: the token plus the destination's app
3121
3128
  * id is the whole address.
3122
3129
  */
3123
- const digitalOceanConnectionConfigSchema = z.object({ provider: z.literal("digitalocean") });
3130
+ const digitalOceanConnectionConfigSchema = z$1.object({ provider: z$1.literal("digitalocean") });
3124
3131
  /**
3125
3132
  * Heroku account scope — empty, as Fly's and Render's are.
3126
3133
  *
@@ -3131,7 +3138,7 @@ const digitalOceanConnectionConfigSchema = z.object({ provider: z.literal("digit
3131
3138
  * `/apps/{app_id_or_name}` against everything the token can see, team-owned or
3132
3139
  * not.
3133
3140
  */
3134
- const herokuConnectionConfigSchema = z.object({ provider: z.literal("heroku") });
3141
+ const herokuConnectionConfigSchema = z$1.object({ provider: z$1.literal("heroku") });
3135
3142
  /**
3136
3143
  * Netlify team scope — the one thing a Netlify token cannot tell us itself.
3137
3144
  *
@@ -3146,10 +3153,10 @@ const herokuConnectionConfigSchema = z.object({ provider: z.literal("heroku") })
3146
3153
  * can find without an API call — it is in the dashboard URL
3147
3154
  * (`app.netlify.com/teams/<slug>`) and under Team settings → General.
3148
3155
  */
3149
- const netlifyConnectionConfigSchema = z.object({
3150
- provider: z.literal("netlify"),
3156
+ const netlifyConnectionConfigSchema = z$1.object({
3157
+ provider: z$1.literal("netlify"),
3151
3158
  /** Netlify team slug (`acme`) or account id — `{account_id}` accepts either. */
3152
- accountId: z.string().trim().min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9._-]*$/, "must be a Netlify team slug or account ID — no slashes or spaces")
3159
+ accountId: z$1.string().trim().min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9._-]*$/, "must be a Netlify team slug or account ID — no slashes or spaces")
3153
3160
  });
3154
3161
  /**
3155
3162
  * Bunnyshell account scope — empty, as Fly's, Heroku's, and Northflank's are.
@@ -3163,7 +3170,7 @@ const netlifyConnectionConfigSchema = z.object({
3163
3170
  * id is the whole address. The API offers an `organization` filter, but it
3164
3171
  * narrows a listing — it is not part of an address.
3165
3172
  */
3166
- const bunnyshellConnectionConfigSchema = z.object({ provider: z.literal("bunnyshell") });
3173
+ const bunnyshellConnectionConfigSchema = z$1.object({ provider: z$1.literal("bunnyshell") });
3167
3174
  /**
3168
3175
  * GitHub account scope — empty for github.com, which is the whole point.
3169
3176
  *
@@ -3177,13 +3184,13 @@ const bunnyshellConnectionConfigSchema = z.object({ provider: z.literal("bunnysh
3177
3184
  * with a different plan behind it). Set only for a self-hosted GHES appliance,
3178
3185
  * where the REST API is at `https://<host>/api/v3`.
3179
3186
  */
3180
- const githubActionsConnectionConfigSchema = z.object({
3181
- provider: z.literal("github-actions"),
3187
+ const githubActionsConnectionConfigSchema = z$1.object({
3188
+ provider: z$1.literal("github-actions"),
3182
3189
  /**
3183
3190
  * GitHub Enterprise Server API root, e.g. `https://github.acme.com/api/v3`.
3184
3191
  * Omit for github.com. Must be `https:` — this URL carries the token.
3185
3192
  */
3186
- baseUrl: z.string().trim().max(300).refine((value) => {
3193
+ baseUrl: z$1.string().trim().max(300).refine((value) => {
3187
3194
  let parsed;
3188
3195
  try {
3189
3196
  parsed = new URL(value);
@@ -3203,7 +3210,7 @@ const githubActionsConnectionConfigSchema = z.object({
3203
3210
  * Manager URL is built from this string, and a typo would otherwise surface as
3204
3211
  * a 403 from Google hours later inside an alarm, with nobody watching.
3205
3212
  */
3206
- const gcpProjectSchema = z.string().trim().refine((value) => /^[a-z][a-z0-9-]{4,28}[a-z0-9]$/.test(value) || /^\d{1,20}$/.test(value), "must be a Google Cloud project ID (e.g. acme-prod) or project number");
3213
+ const gcpProjectSchema = z$1.string().trim().refine((value) => /^[a-z][a-z0-9-]{4,28}[a-z0-9]$/.test(value) || /^\d{1,20}$/.test(value), "must be a Google Cloud project ID (e.g. acme-prod) or project number");
3207
3214
  /**
3208
3215
  * Google Cloud project scope — which project's Secret Manager to write.
3209
3216
  *
@@ -3222,8 +3229,8 @@ const gcpProjectSchema = z.string().trim().refine((value) => /^[a-z][a-z0-9-]{4,
3222
3229
  * regional secrets live behind. Data residency is expressed instead through the
3223
3230
  * destination's user-managed replication.
3224
3231
  */
3225
- const gcpSecretManagerConnectionConfigSchema = z.object({
3226
- provider: z.literal("gcp-secret-manager"),
3232
+ const gcpSecretManagerConnectionConfigSchema = z$1.object({
3233
+ provider: z$1.literal("gcp-secret-manager"),
3227
3234
  /** Project ID (`acme-prod`) or project number. */
3228
3235
  projectId: gcpProjectSchema
3229
3236
  });
@@ -3263,16 +3270,16 @@ const LANGGRAPH_PLATFORM_REGIONS = [
3263
3270
  * Vercel's `teamId` sets — so it is passed through as `X-Tenant-Id` whenever
3264
3271
  * it is present.
3265
3272
  */
3266
- const langgraphPlatformConnectionConfigSchema = z.object({
3267
- provider: z.literal("langgraph-platform"),
3273
+ const langgraphPlatformConnectionConfigSchema = z$1.object({
3274
+ provider: z$1.literal("langgraph-platform"),
3268
3275
  /** Control-plane region. Omit for `us`. Mutually exclusive with `baseUrl`. */
3269
- region: z.enum(LANGGRAPH_PLATFORM_REGIONS).optional(),
3276
+ region: z$1.enum(LANGGRAPH_PLATFORM_REGIONS).optional(),
3270
3277
  /**
3271
3278
  * Self-hosted LangSmith control-plane root, e.g.
3272
3279
  * `https://langsmith.acme.com/api-host`. Omit for LangChain's own hosts.
3273
3280
  * Must be `https:` — this URL carries the API key.
3274
3281
  */
3275
- baseUrl: z.string().trim().max(300).refine((value) => {
3282
+ baseUrl: z$1.string().trim().max(300).refine((value) => {
3276
3283
  let parsed;
3277
3284
  try {
3278
3285
  parsed = new URL(value);
@@ -3282,7 +3289,7 @@ const langgraphPlatformConnectionConfigSchema = z.object({
3282
3289
  return parsed.protocol === "https:" && !parsed.username && !parsed.password;
3283
3290
  }, "must be an https:// URL — the self-hosted control-plane root, e.g. https://langsmith.acme.com/api-host").optional(),
3284
3291
  /** LangSmith workspace (tenant) UUID, sent as `X-Tenant-Id`. */
3285
- tenantId: z.string().trim().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, "must be a LangSmith workspace UUID").optional()
3292
+ tenantId: z$1.string().trim().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, "must be a LangSmith workspace UUID").optional()
3286
3293
  }).refine((c) => !(c.baseUrl !== void 0 && c.region !== void 0), {
3287
3294
  message: "set region for a LangChain-hosted account or baseUrl for a self-hosted one, not both",
3288
3295
  path: ["baseUrl"]
@@ -3309,7 +3316,7 @@ const AZURE_CLOUDS = [
3309
3316
  * keeps one rule — a tenant's GUID is on the same admin-center page as the
3310
3317
  * client id it pairs with, so nothing is harder to find.
3311
3318
  */
3312
- const azureGuidSchema = z.string().trim().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, "must be a GUID, as the Entra admin center shows it");
3319
+ const azureGuidSchema = z$1.string().trim().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, "must be a GUID, as the Entra admin center shows it");
3313
3320
  /**
3314
3321
  * Azure account scope: which directory to authenticate against, as which app.
3315
3322
  *
@@ -3326,14 +3333,14 @@ const azureGuidSchema = z.string().trim().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-
3326
3333
  * has nowhere to keep, and Entra caps a client secret at 24 months, which is a
3327
3334
  * rotation the connection's `lastError` will make loud.
3328
3335
  */
3329
- const azureKeyVaultConnectionConfigSchema = z.object({
3330
- provider: z.literal("azure-key-vault"),
3336
+ const azureKeyVaultConnectionConfigSchema = z$1.object({
3337
+ provider: z$1.literal("azure-key-vault"),
3331
3338
  /** Entra directory (tenant) ID. */
3332
3339
  tenantId: azureGuidSchema,
3333
3340
  /** Application (client) ID of the service principal seekrit signs in as. */
3334
3341
  clientId: azureGuidSchema,
3335
3342
  /** Which Azure cloud the tenant and its vaults live in. */
3336
- cloud: z.enum(AZURE_CLOUDS).default("public")
3343
+ cloud: z$1.enum(AZURE_CLOUDS).default("public")
3337
3344
  });
3338
3345
  /**
3339
3346
  * Hugging Face account scope — empty, as Render's and Fly's are.
@@ -3349,9 +3356,9 @@ const azureKeyVaultConnectionConfigSchema = z.object({
3349
3356
  * not something a mirror is expected to accept a write on. Adding the field
3350
3357
  * would invite pointing a connection at a host that silently swallows secrets.
3351
3358
  */
3352
- const huggingfaceSpacesConnectionConfigSchema = z.object({ provider: z.literal("huggingface-spaces") });
3359
+ const huggingfaceSpacesConnectionConfigSchema = z$1.object({ provider: z$1.literal("huggingface-spaces") });
3353
3360
  /** The wrapped credential is an OpenAI project API key with vault read/write access. */
3354
- const openaiVaultConnectionConfigSchema = z.object({ provider: z.literal("openai-vault") });
3361
+ const openaiVaultConnectionConfigSchema = z$1.object({ provider: z$1.literal("openai-vault") });
3355
3362
  /**
3356
3363
  * Claude Managed Agents account scope — empty, for Hugging Face's reason.
3357
3364
  *
@@ -3368,8 +3375,8 @@ const openaiVaultConnectionConfigSchema = z.object({ provider: z.literal("openai
3368
3375
  * credential shape and a different connector (one that would reuse
3369
3376
  * `lib/leases/aws-sigv4.ts`), not a different host for this one.
3370
3377
  */
3371
- const claudeManagedAgentsConnectionConfigSchema = z.object({ provider: z.literal("claude-managed-agents") });
3372
- const syncConnectionConfigSchema = z.discriminatedUnion("provider", [
3378
+ const claudeManagedAgentsConnectionConfigSchema = z$1.object({ provider: z$1.literal("claude-managed-agents") });
3379
+ const syncConnectionConfigSchema = z$1.discriminatedUnion("provider", [
3373
3380
  vercelConnectionConfigSchema,
3374
3381
  cloudflareWorkersConnectionConfigSchema,
3375
3382
  cloudflarePagesConnectionConfigSchema,
@@ -3398,17 +3405,17 @@ const VERCEL_TARGETS = [
3398
3405
  "preview",
3399
3406
  "development"
3400
3407
  ];
3401
- const vercelDestinationSchema = z.object({
3402
- provider: z.literal("vercel"),
3408
+ const vercelDestinationSchema = z$1.object({
3409
+ provider: z$1.literal("vercel"),
3403
3410
  /** Vercel project id (`prj_…`) or project name. */
3404
- projectId: z.string().trim().min(1).max(128),
3411
+ projectId: z$1.string().trim().min(1).max(128),
3405
3412
  /** Which deployment targets receive these values. At least one. */
3406
- targets: z.array(z.enum(VERCEL_TARGETS)).min(1),
3413
+ targets: z$1.array(z$1.enum(VERCEL_TARGETS)).min(1),
3407
3414
  /**
3408
3415
  * Restrict `preview` writes to one git branch. Vercel only honors this when
3409
3416
  * `targets` includes `preview`; ignored otherwise.
3410
3417
  */
3411
- gitBranch: z.string().trim().min(1).max(255).optional()
3418
+ gitBranch: z$1.string().trim().min(1).max(255).optional()
3412
3419
  });
3413
3420
  /**
3414
3421
  * The Worker whose secrets a binding owns. Wrangler *environments* are not a
@@ -3416,19 +3423,19 @@ const vercelDestinationSchema = z.object({
3416
3423
  * `my-api` with `--env staging` creates a Worker literally named
3417
3424
  * `my-api-staging`, so pointing at an environment means naming that script.
3418
3425
  */
3419
- const cloudflareWorkersDestinationSchema = z.object({
3420
- provider: z.literal("cloudflare-workers"),
3426
+ const cloudflareWorkersDestinationSchema = z$1.object({
3427
+ provider: z$1.literal("cloudflare-workers"),
3421
3428
  /** Worker script name, as shown in the dashboard (`my-api`). */
3422
- scriptName: z.string().trim().min(1).max(63).regex(/^[A-Za-z0-9_][A-Za-z0-9_-]*$/, "must be a Worker script name")
3429
+ scriptName: z$1.string().trim().min(1).max(63).regex(/^[A-Za-z0-9_][A-Za-z0-9_-]*$/, "must be a Worker script name")
3423
3430
  });
3424
3431
  /** The two deployment configs a Pages project keeps env vars under. */
3425
3432
  const CLOUDFLARE_PAGES_ENVIRONMENTS = ["production", "preview"];
3426
- const cloudflarePagesDestinationSchema = z.object({
3427
- provider: z.literal("cloudflare-pages"),
3433
+ const cloudflarePagesDestinationSchema = z$1.object({
3434
+ provider: z$1.literal("cloudflare-pages"),
3428
3435
  /** Pages project name (`my-site`) — Pages has no separate project id. */
3429
- projectName: z.string().trim().min(1).max(58).regex(/^[A-Za-z0-9][A-Za-z0-9-]*$/, "must be a Pages project name"),
3436
+ projectName: z$1.string().trim().min(1).max(58).regex(/^[A-Za-z0-9][A-Za-z0-9-]*$/, "must be a Pages project name"),
3430
3437
  /** Which deployment configs receive these values. At least one. */
3431
- environments: z.array(z.enum(CLOUDFLARE_PAGES_ENVIRONMENTS)).min(1)
3438
+ environments: z$1.array(z$1.enum(CLOUDFLARE_PAGES_ENVIRONMENTS)).min(1)
3432
3439
  });
3433
3440
  /**
3434
3441
  * Scopes a Secrets Store secret may be used by. Cloudflare requires at least
@@ -3442,12 +3449,12 @@ const CLOUDFLARE_SECRETS_STORE_SCOPES = [
3442
3449
  "containers",
3443
3450
  "websearch"
3444
3451
  ];
3445
- const cloudflareSecretsStoreDestinationSchema = z.object({
3446
- provider: z.literal("cloudflare-secrets-store"),
3452
+ const cloudflareSecretsStoreDestinationSchema = z$1.object({
3453
+ provider: z$1.literal("cloudflare-secrets-store"),
3447
3454
  /** Store id (32 hex). An account has exactly one store today. */
3448
- storeId: z.string().trim().regex(/^[0-9a-f]{32}$/, "must be a 32-character Secrets Store ID (lowercase hex)"),
3455
+ storeId: z$1.string().trim().regex(/^[0-9a-f]{32}$/, "must be a 32-character Secrets Store ID (lowercase hex)"),
3449
3456
  /** Scopes applied to secrets this binding creates. At least one. */
3450
- scopes: z.array(z.enum(CLOUDFLARE_SECRETS_STORE_SCOPES)).min(1)
3457
+ scopes: z$1.array(z$1.enum(CLOUDFLARE_SECRETS_STORE_SCOPES)).min(1)
3451
3458
  });
3452
3459
  /**
3453
3460
  * Where inside Railway a binding writes.
@@ -3462,8 +3469,8 @@ const cloudflareSecretsStoreDestinationSchema = z.object({
3462
3469
  * genuinely different destination from any one service's variables, so it is an
3463
3470
  * absent field rather than a sentinel.
3464
3471
  */
3465
- const railwayDestinationSchema = z.object({
3466
- provider: z.literal("railway"),
3472
+ const railwayDestinationSchema = z$1.object({
3473
+ provider: z$1.literal("railway"),
3467
3474
  /** Railway project id (a UUID, from the project's Settings page or URL). */
3468
3475
  projectId: railwayIdSchema,
3469
3476
  /** Railway environment id (a UUID) — the deployment environment to write. */
@@ -3479,7 +3486,7 @@ const railwayDestinationSchema = z.object({
3479
3486
  * gated behind a release process and a secrets push must not start one; the
3480
3487
  * values then sit staged until the next deploy.
3481
3488
  */
3482
- skipDeploys: z.boolean().optional()
3489
+ skipDeploys: z$1.boolean().optional()
3483
3490
  });
3484
3491
  /**
3485
3492
  * A customer-managed KMS key to encrypt with, as a key id, ARN, or alias
@@ -3490,7 +3497,7 @@ const railwayDestinationSchema = z.object({
3490
3497
  * cross-account ARNs, and rejecting a valid one here would be worse than
3491
3498
  * letting KMS give its own (very clear) error.
3492
3499
  */
3493
- const awsKmsKeyIdSchema = z.string().trim().min(1).max(2048);
3500
+ const awsKmsKeyIdSchema = z$1.string().trim().min(1).max(2048);
3494
3501
  /**
3495
3502
  * How a binding lays its secrets out in Secrets Manager.
3496
3503
  *
@@ -3510,18 +3517,18 @@ const AWS_SECRETS_MANAGER_LAYOUTS = ["secret-per-name", "json-bundle"];
3510
3517
  * *variable name* (`[A-Za-z0-9_]`, no slashes), while this produces a
3511
3518
  * *namespace* — `prod/storefront/` — and slashes are the whole point of it.
3512
3519
  */
3513
- const awsSecretsManagerDestinationSchema = z.object({
3514
- provider: z.literal("aws-secrets-manager"),
3515
- layout: z.enum(AWS_SECRETS_MANAGER_LAYOUTS).default("secret-per-name"),
3520
+ const awsSecretsManagerDestinationSchema = z$1.object({
3521
+ provider: z$1.literal("aws-secrets-manager"),
3522
+ layout: z$1.enum(AWS_SECRETS_MANAGER_LAYOUTS).default("secret-per-name"),
3516
3523
  /**
3517
3524
  * `secret-per-name` only: prepended to every secret's name, e.g.
3518
3525
  * `prod/storefront/`. Optional, but strongly advised in an account that
3519
3526
  * holds anything else — without it a binding writes at the root of a
3520
3527
  * namespace it does not own.
3521
3528
  */
3522
- pathPrefix: z.string().trim().max(400).regex(/^[A-Za-z0-9/_+=.@-]*$/, "may contain letters, digits, and / _ + = . @ -").optional(),
3529
+ pathPrefix: z$1.string().trim().max(400).regex(/^[A-Za-z0-9/_+=.@-]*$/, "may contain letters, digits, and / _ + = . @ -").optional(),
3523
3530
  /** `json-bundle` only: the one secret that holds every value, e.g. `prod/storefront/env`. */
3524
- secretName: z.string().trim().min(1).max(512).regex(/^[A-Za-z0-9/_+=.@-]+$/, "may contain letters, digits, and / _ + = . @ -").optional(),
3531
+ secretName: z$1.string().trim().min(1).max(512).regex(/^[A-Za-z0-9/_+=.@-]+$/, "may contain letters, digits, and / _ + = . @ -").optional(),
3525
3532
  kmsKeyId: awsKmsKeyIdSchema.optional()
3526
3533
  }).refine((d) => d.layout !== "json-bundle" || d.secretName !== void 0, {
3527
3534
  message: "a json-bundle destination needs the name of the secret to write",
@@ -3544,17 +3551,17 @@ const AWS_PARAMETER_TIERS = [
3544
3551
  * and trailing slashes are required so the binding's names concatenate
3545
3552
  * unambiguously — `/prod/storefront/` + `DB_URL`.
3546
3553
  */
3547
- const awsParameterStoreDestinationSchema = z.object({
3548
- provider: z.literal("aws-parameter-store"),
3554
+ const awsParameterStoreDestinationSchema = z$1.object({
3555
+ provider: z$1.literal("aws-parameter-store"),
3549
3556
  /** Must start and end with `/`. `aws`/`ssm` are reserved by AWS as the first segment. */
3550
- path: z.string().trim().max(1011).regex(/^\/([A-Za-z0-9_.-]+\/)*$/, "must be a parameter path like /prod/storefront/"),
3551
- type: z.enum(AWS_PARAMETER_TYPES).default("SecureString"),
3557
+ path: z$1.string().trim().max(1011).regex(/^\/([A-Za-z0-9_.-]+\/)*$/, "must be a parameter path like /prod/storefront/"),
3558
+ type: z$1.enum(AWS_PARAMETER_TYPES).default("SecureString"),
3552
3559
  /**
3553
3560
  * Standard caps a value at 4KB and costs nothing; Advanced raises that to 8KB
3554
3561
  * and is billed per parameter per month. `Intelligent-Tiering` lets AWS pick,
3555
3562
  * upgrading only the parameters that need it.
3556
3563
  */
3557
- tier: z.enum(AWS_PARAMETER_TIERS).default("Standard"),
3564
+ tier: z$1.enum(AWS_PARAMETER_TIERS).default("Standard"),
3558
3565
  kmsKeyId: awsKmsKeyIdSchema.optional()
3559
3566
  });
3560
3567
  /**
@@ -3569,12 +3576,12 @@ const awsParameterStoreDestinationSchema = z.object({
3569
3576
  * the day Render introduces a new resource prefix, which is not our call to
3570
3577
  * make.
3571
3578
  */
3572
- const renderServiceIdSchema = z.string().trim().regex(/^(?!evg-)[A-Za-z0-9_-]{1,64}$/, "must be a Render service ID (`srv-…` or `crn-…`), not an environment group");
3573
- const renderEnvGroupIdSchema = z.string().trim().regex(/^(?!srv-|crn-)[A-Za-z0-9_-]{1,64}$/, "must be a Render environment group ID (`evg-…`), not a service");
3579
+ const renderServiceIdSchema = z$1.string().trim().regex(/^(?!evg-)[A-Za-z0-9_-]{1,64}$/, "must be a Render service ID (`srv-…` or `crn-…`), not an environment group");
3580
+ const renderEnvGroupIdSchema = z$1.string().trim().regex(/^(?!srv-|crn-)[A-Za-z0-9_-]{1,64}$/, "must be a Render environment group ID (`evg-…`), not a service");
3574
3581
  /** Environment variables set directly on one service. */
3575
- const renderServiceDestinationSchema = z.object({
3576
- provider: z.literal("render"),
3577
- kind: z.literal("service"),
3582
+ const renderServiceDestinationSchema = z$1.object({
3583
+ provider: z$1.literal("render"),
3584
+ kind: z$1.literal("service"),
3578
3585
  /** Service id (`srv-…`, or `crn-…` for a cron job), from its dashboard URL. */
3579
3586
  serviceId: renderServiceIdSchema
3580
3587
  });
@@ -3584,13 +3591,13 @@ const renderServiceDestinationSchema = z.object({
3584
3591
  * worth thinking about twice: its blast radius is the link list, not one
3585
3592
  * service.
3586
3593
  */
3587
- const renderEnvGroupDestinationSchema = z.object({
3588
- provider: z.literal("render"),
3589
- kind: z.literal("env-group"),
3594
+ const renderEnvGroupDestinationSchema = z$1.object({
3595
+ provider: z$1.literal("render"),
3596
+ kind: z$1.literal("env-group"),
3590
3597
  /** Environment group id (`evg-…`), from its dashboard URL. */
3591
3598
  envGroupId: renderEnvGroupIdSchema
3592
3599
  });
3593
- const renderDestinationSchema = z.discriminatedUnion("kind", [renderServiceDestinationSchema, renderEnvGroupDestinationSchema]);
3600
+ const renderDestinationSchema = z$1.discriminatedUnion("kind", [renderServiceDestinationSchema, renderEnvGroupDestinationSchema]);
3594
3601
  /**
3595
3602
  * The Fly app whose secret set a binding owns.
3596
3603
  *
@@ -3607,10 +3614,10 @@ const renderDestinationSchema = z.discriminatedUnion("kind", [renderServiceDesti
3607
3614
  * after the push get them straight away. The connector deliberately restarts
3608
3615
  * nothing — see the note in `apps/api/src/lib/sync/connectors/fly.ts`.
3609
3616
  */
3610
- const flyDestinationSchema = z.object({
3611
- provider: z.literal("fly"),
3617
+ const flyDestinationSchema = z$1.object({
3618
+ provider: z$1.literal("fly"),
3612
3619
  /** Fly app name, as `fly apps list` prints it. */
3613
- appName: z.string().trim().min(1).max(63).regex(/^[a-z0-9][a-z0-9-]*$/, "must be a Fly app name (lowercase letters, numbers, and dashes)")
3620
+ appName: z$1.string().trim().min(1).max(63).regex(/^[a-z0-9][a-z0-9-]*$/, "must be a Fly app name (lowercase letters, numbers, and dashes)")
3614
3621
  });
3615
3622
  /**
3616
3623
  * Where inside Northflank a binding writes: one **secret group** in one
@@ -3627,8 +3634,8 @@ const flyDestinationSchema = z.object({
3627
3634
  * separate environments are separate projects (or separate groups restricted to
3628
3635
  * a stage), so the binding's seekrit environment maps to a group, one to one.
3629
3636
  */
3630
- const northflankDestinationSchema = z.object({
3631
- provider: z.literal("northflank"),
3637
+ const northflankDestinationSchema = z$1.object({
3638
+ provider: z$1.literal("northflank"),
3632
3639
  /** Project id — the slug in the project URL (`default-project`). */
3633
3640
  projectId: northflankIdSchema,
3634
3641
  /** Secret group id — the slug in the group's URL (`example-secret-group`). */
@@ -3660,13 +3667,13 @@ const DIGITALOCEAN_ENV_SCOPES = [
3660
3667
  * from a typo: pasting the app's *name* (`storefront`), which `GET /v2/apps/{id}`
3661
3668
  * answers with a flat 404 hours later inside an alarm, with nobody watching.
3662
3669
  */
3663
- const digitalOceanAppIdSchema = z.string().trim().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, "must be a DigitalOcean app ID (the UUID in the app's URL), not its name");
3670
+ const digitalOceanAppIdSchema = z$1.string().trim().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, "must be a DigitalOcean app ID (the UUID in the app's URL), not its name");
3664
3671
  /**
3665
3672
  * A component name, matching App Platform's own pattern for one. Names are
3666
3673
  * unique within an app, which is what makes a name — rather than an index into
3667
3674
  * `services` — the stable way to address a component's variables.
3668
3675
  */
3669
- const digitalOceanComponentNameSchema = z.string().trim().regex(/^[a-z][a-z0-9-]{0,30}[a-z0-9]$/, "must be an App Platform component name (lowercase letters, numbers, and dashes)");
3676
+ const digitalOceanComponentNameSchema = z$1.string().trim().regex(/^[a-z][a-z0-9-]{0,30}[a-z0-9]$/, "must be an App Platform component name (lowercase letters, numbers, and dashes)");
3670
3677
  /**
3671
3678
  * Where inside a DigitalOcean app a binding writes.
3672
3679
  *
@@ -3693,27 +3700,27 @@ const digitalOceanComponentNameSchema = z.string().trim().regex(/^[a-z][a-z0-9-]
3693
3700
  * about to write is already there — see
3694
3701
  * `apps/api/src/lib/sync/connectors/digitalocean.ts`.
3695
3702
  */
3696
- const digitalOceanAppDestinationSchema = z.object({
3697
- provider: z.literal("digitalocean"),
3698
- kind: z.literal("app"),
3703
+ const digitalOceanAppDestinationSchema = z$1.object({
3704
+ provider: z$1.literal("digitalocean"),
3705
+ kind: z$1.literal("app"),
3699
3706
  /** App id — the UUID in `cloud.digitalocean.com/apps/<id>`. */
3700
3707
  appId: digitalOceanAppIdSchema,
3701
- scope: z.enum(DIGITALOCEAN_ENV_SCOPES).default("RUN_TIME")
3708
+ scope: z$1.enum(DIGITALOCEAN_ENV_SCOPES).default("RUN_TIME")
3702
3709
  });
3703
3710
  /**
3704
3711
  * One component's own environment variables. Narrower than the app-level list:
3705
3712
  * only this service, worker, job, static site, or function sees them, and a key
3706
3713
  * here wins over the same key at app level.
3707
3714
  */
3708
- const digitalOceanComponentDestinationSchema = z.object({
3709
- provider: z.literal("digitalocean"),
3710
- kind: z.literal("component"),
3715
+ const digitalOceanComponentDestinationSchema = z$1.object({
3716
+ provider: z$1.literal("digitalocean"),
3717
+ kind: z$1.literal("component"),
3711
3718
  appId: digitalOceanAppIdSchema,
3712
3719
  /** Component name, as it appears in the app spec — not its type. */
3713
3720
  componentName: digitalOceanComponentNameSchema,
3714
- scope: z.enum(DIGITALOCEAN_ENV_SCOPES).default("RUN_TIME")
3721
+ scope: z$1.enum(DIGITALOCEAN_ENV_SCOPES).default("RUN_TIME")
3715
3722
  });
3716
- const digitalOceanDestinationSchema = z.discriminatedUnion("kind", [digitalOceanAppDestinationSchema, digitalOceanComponentDestinationSchema]);
3723
+ const digitalOceanDestinationSchema = z$1.discriminatedUnion("kind", [digitalOceanAppDestinationSchema, digitalOceanComponentDestinationSchema]);
3717
3724
  /**
3718
3725
  * A Heroku app, named the way `/apps/{app_id_or_name}` names one: either the
3719
3726
  * app name or its UUID id. Both are accepted because both work, and the id is
@@ -3726,7 +3733,7 @@ const digitalOceanDestinationSchema = z.discriminatedUnion("kind", [digitalOcean
3726
3733
  * capitals — into a message at the form rather than a bare 404 from an alarm
3727
3734
  * with nobody watching.
3728
3735
  */
3729
- const herokuAppSchema = z.string().trim().refine((value) => /^[a-z][a-z0-9-]{1,28}[a-z0-9]$/.test(value) || /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value), "must be a Heroku app name (lowercase letters, numbers, and dashes) or its UUID");
3736
+ const herokuAppSchema = z$1.string().trim().refine((value) => /^[a-z][a-z0-9-]{1,28}[a-z0-9]$/.test(value) || /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value), "must be a Heroku app name (lowercase letters, numbers, and dashes) or its UUID");
3730
3737
  /**
3731
3738
  * The Heroku app whose config vars a binding owns.
3732
3739
  *
@@ -3740,8 +3747,8 @@ const herokuAppSchema = z.string().trim().refine((value) => /^[a-z][a-z0-9-]{1,2
3740
3747
  * release and restarts the app's dynos, which is why a run sends exactly one
3741
3748
  * request — see the note in `apps/api/src/lib/sync/connectors/heroku.ts`.
3742
3749
  */
3743
- const herokuDestinationSchema = z.object({
3744
- provider: z.literal("heroku"),
3750
+ const herokuDestinationSchema = z$1.object({
3751
+ provider: z$1.literal("heroku"),
3745
3752
  /** App name as `heroku apps` prints it, or the app's UUID. */
3746
3753
  app: herokuAppSchema
3747
3754
  });
@@ -3779,7 +3786,7 @@ const NETLIFY_CONTEXTS = [
3779
3786
  * by every site in it. Refusing anything but the UUID keeps a slip from turning
3780
3787
  * into a much wider blast radius than the operator asked for.
3781
3788
  */
3782
- const netlifySiteIdSchema = z.string().trim().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, "must be the site's API ID (a UUID), not its name or URL");
3789
+ const netlifySiteIdSchema = z$1.string().trim().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, "must be the site's API ID (a UUID), not its name or URL");
3783
3790
  /**
3784
3791
  * The Netlify site, and which of its deploy contexts a binding owns.
3785
3792
  *
@@ -3801,16 +3808,16 @@ const netlifySiteIdSchema = z.string().trim().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0
3801
3808
  * existing variable, or removed from one ever — and it needs a plan that
3802
3809
  * includes Secrets Controller.
3803
3810
  */
3804
- const netlifyDestinationSchema = z.object({
3805
- provider: z.literal("netlify"),
3811
+ const netlifyDestinationSchema = z$1.object({
3812
+ provider: z$1.literal("netlify"),
3806
3813
  /** Site API ID (a UUID), from Project configuration → General. */
3807
3814
  siteId: netlifySiteIdSchema,
3808
3815
  /** Which deploy contexts receive these values. At least one. */
3809
- contexts: z.array(z.enum(NETLIFY_CONTEXTS)).min(1),
3816
+ contexts: z$1.array(z$1.enum(NETLIFY_CONTEXTS)).min(1),
3810
3817
  /** Branch name, required when `contexts` includes `branch`; ignored otherwise. */
3811
- branch: z.string().trim().min(1).max(255).optional(),
3818
+ branch: z$1.string().trim().min(1).max(255).optional(),
3812
3819
  /** Create variables as Netlify secrets (default true). */
3813
- secret: z.boolean().optional()
3820
+ secret: z$1.boolean().optional()
3814
3821
  }).refine((d) => !d.contexts.includes("branch") || d.branch !== void 0, {
3815
3822
  message: "a branch context needs the branch name it applies to",
3816
3823
  path: ["branch"]
@@ -3832,7 +3839,7 @@ const netlifyDestinationSchema = z.object({
3832
3839
  * before it touches it, so a filter that failed to bite cannot turn into an
3833
3840
  * edit of a neighbouring environment's variables.
3834
3841
  */
3835
- const bunnyshellIdSchema = z.string().trim().min(1).max(64).regex(/^[A-Za-z0-9][A-Za-z0-9._-]*$/, "must be a Bunnyshell ID — no slashes or spaces");
3842
+ const bunnyshellIdSchema = z$1.string().trim().min(1).max(64).regex(/^[A-Za-z0-9][A-Za-z0-9._-]*$/, "must be a Bunnyshell ID — no slashes or spaces");
3836
3843
  /**
3837
3844
  * Variables on one Bunnyshell **environment** — the set every component in it
3838
3845
  * inherits, and the closest match to a seekrit environment.
@@ -3840,13 +3847,13 @@ const bunnyshellIdSchema = z.string().trim().min(1).max(64).regex(/^[A-Za-z0-9][
3840
3847
  * This is the destination for an environment that already exists and stays
3841
3848
  * around: a primary environment, or a long-lived ephemeral one.
3842
3849
  */
3843
- const bunnyshellEnvironmentDestinationSchema = z.object({
3844
- provider: z.literal("bunnyshell"),
3845
- kind: z.literal("environment"),
3850
+ const bunnyshellEnvironmentDestinationSchema = z$1.object({
3851
+ provider: z$1.literal("bunnyshell"),
3852
+ kind: z$1.literal("environment"),
3846
3853
  /** Environment ID, as `bns environments list` prints it. */
3847
3854
  environmentId: bunnyshellIdSchema,
3848
3855
  /** Mark what seekrit creates as a Bunnyshell secret (default true). */
3849
- secret: z.boolean().optional()
3856
+ secret: z$1.boolean().optional()
3850
3857
  });
3851
3858
  /**
3852
3859
  * Variables on a Bunnyshell **project** — inherited by every environment
@@ -3863,13 +3870,13 @@ const bunnyshellEnvironmentDestinationSchema = z.object({
3863
3870
  * overridden at its own scope — so a project binding does not fight an
3864
3871
  * environment binding pointed at the same name, it loses to it.
3865
3872
  */
3866
- const bunnyshellProjectDestinationSchema = z.object({
3867
- provider: z.literal("bunnyshell"),
3868
- kind: z.literal("project"),
3873
+ const bunnyshellProjectDestinationSchema = z$1.object({
3874
+ provider: z$1.literal("bunnyshell"),
3875
+ kind: z$1.literal("project"),
3869
3876
  /** Project ID, as `bns projects list` prints it. */
3870
3877
  projectId: bunnyshellIdSchema,
3871
3878
  /** Mark what seekrit creates as a Bunnyshell secret (default true). */
3872
- secret: z.boolean().optional()
3879
+ secret: z$1.boolean().optional()
3873
3880
  });
3874
3881
  /**
3875
3882
  * Where in Bunnyshell a binding writes.
@@ -3889,7 +3896,7 @@ const bunnyshellProjectDestinationSchema = z.object({
3889
3896
  * variables seekrit **creates**: an update never sends the flag, so a variable
3890
3897
  * an operator deliberately un-secreted stays that way.
3891
3898
  */
3892
- const bunnyshellDestinationSchema = z.discriminatedUnion("kind", [bunnyshellEnvironmentDestinationSchema, bunnyshellProjectDestinationSchema]);
3899
+ const bunnyshellDestinationSchema = z$1.discriminatedUnion("kind", [bunnyshellEnvironmentDestinationSchema, bunnyshellProjectDestinationSchema]);
3893
3900
  /**
3894
3901
  * Which repositories in an organization can read an org-level secret.
3895
3902
  *
@@ -3912,14 +3919,14 @@ const GITHUB_ACTIONS_VISIBILITIES = [
3912
3919
  * owner field — fails at the form rather than as a 404 from an alarm with nobody
3913
3920
  * watching.
3914
3921
  */
3915
- const githubOwnerSchema = z.string().trim().min(1).max(39).regex(/^[A-Za-z0-9](?:-?[A-Za-z0-9])*$/, "must be a GitHub user or organization login — not a URL or an owner/repo pair");
3922
+ const githubOwnerSchema = z$1.string().trim().min(1).max(39).regex(/^[A-Za-z0-9](?:-?[A-Za-z0-9])*$/, "must be a GitHub user or organization login — not a URL or an owner/repo pair");
3916
3923
  /**
3917
3924
  * A repository name. GitHub's rules are looser than an owner's: letters,
3918
3925
  * numbers, hyphens, underscores, and periods, up to 100 characters. `.` and `..`
3919
3926
  * are refused outright — they would traverse the API path rather than name a
3920
3927
  * repository.
3921
3928
  */
3922
- const githubRepoSchema = z.string().trim().min(1).max(100).regex(/^[A-Za-z0-9._-]+$/, "must be a repository name alone (`api`), not `owner/repo` or a URL").refine((value) => value !== "." && value !== "..", "is not a repository name");
3929
+ const githubRepoSchema = z$1.string().trim().min(1).max(100).regex(/^[A-Za-z0-9._-]+$/, "must be a repository name alone (`api`), not `owner/repo` or a URL").refine((value) => value !== "." && value !== "..", "is not a repository name");
3923
3930
  /**
3924
3931
  * A deployment environment name.
3925
3932
  *
@@ -3928,7 +3935,7 @@ const githubRepoSchema = z.string().trim().min(1).max(100).regex(/^[A-Za-z0-9._-
3928
3935
  * break the request are refused — an empty name, and the path separators that
3929
3936
  * would let a name escape its URL segment. Everything else is GitHub's to reject.
3930
3937
  */
3931
- const githubEnvironmentSchema = z.string().trim().min(1).max(255).refine((value) => !value.includes("/") && !value.includes("\\"), "cannot contain a slash — that is a path separator, not part of an environment name");
3938
+ const githubEnvironmentSchema = z$1.string().trim().min(1).max(255).refine((value) => !value.includes("/") && !value.includes("\\"), "cannot contain a slash — that is a path separator, not part of an environment name");
3932
3939
  /**
3933
3940
  * One repository's Actions secrets.
3934
3941
  *
@@ -3937,9 +3944,9 @@ const githubEnvironmentSchema = z.string().trim().min(1).max(255).refine((value)
3937
3944
  * choice this connector makes — but it is the reason `environment` exists below,
3938
3945
  * and the reason to prefer it for anything that touches production.
3939
3946
  */
3940
- const githubActionsRepoDestinationSchema = z.object({
3941
- provider: z.literal("github-actions"),
3942
- kind: z.literal("repo"),
3947
+ const githubActionsRepoDestinationSchema = z$1.object({
3948
+ provider: z$1.literal("github-actions"),
3949
+ kind: z$1.literal("repo"),
3943
3950
  /** Repository owner — a user or organization login. */
3944
3951
  owner: githubOwnerSchema,
3945
3952
  /** Repository name, without the owner. */
@@ -3959,9 +3966,9 @@ const githubActionsRepoDestinationSchema = z.object({
3959
3966
  * because a name was misspelled would quietly remove the protection the operator
3960
3967
  * was relying on.
3961
3968
  */
3962
- const githubActionsEnvironmentDestinationSchema = z.object({
3963
- provider: z.literal("github-actions"),
3964
- kind: z.literal("environment"),
3969
+ const githubActionsEnvironmentDestinationSchema = z$1.object({
3970
+ provider: z$1.literal("github-actions"),
3971
+ kind: z$1.literal("environment"),
3965
3972
  owner: githubOwnerSchema,
3966
3973
  repo: githubRepoSchema,
3967
3974
  /** Environment name, exactly as the repository's Settings → Environments shows it. */
@@ -3981,15 +3988,15 @@ const githubActionsEnvironmentDestinationSchema = z.object({
3981
3988
  * resolution would mean this connector picking which repository an ambiguous
3982
3989
  * name meant, and getting that wrong widens a secret's reach silently.
3983
3990
  */
3984
- const githubActionsOrgDestinationSchema = z.object({
3985
- provider: z.literal("github-actions"),
3986
- kind: z.literal("org"),
3991
+ const githubActionsOrgDestinationSchema = z$1.object({
3992
+ provider: z$1.literal("github-actions"),
3993
+ kind: z$1.literal("org"),
3987
3994
  /** Organization login. */
3988
3995
  org: githubOwnerSchema,
3989
3996
  /** Which repositories may read these secrets. Stated, never defaulted. */
3990
- visibility: z.enum(GITHUB_ACTIONS_VISIBILITIES),
3997
+ visibility: z$1.enum(GITHUB_ACTIONS_VISIBILITIES),
3991
3998
  /** Numeric repository ids, required when `visibility` is `selected`. */
3992
- selectedRepositoryIds: z.array(z.number().int().positive()).max(500).optional()
3999
+ selectedRepositoryIds: z$1.array(z$1.number().int().positive()).max(500).optional()
3993
4000
  }).refine((dest) => dest.visibility !== "selected" || dest.selectedRepositoryIds !== void 0 && dest.selectedRepositoryIds.length > 0, {
3994
4001
  message: "selected visibility needs at least one repository id",
3995
4002
  path: ["selectedRepositoryIds"]
@@ -3997,7 +4004,7 @@ const githubActionsOrgDestinationSchema = z.object({
3997
4004
  message: "repository ids only apply to selected visibility — remove them, or select it",
3998
4005
  path: ["selectedRepositoryIds"]
3999
4006
  });
4000
- const githubActionsDestinationSchema = z.discriminatedUnion("kind", [
4007
+ const githubActionsDestinationSchema = z$1.discriminatedUnion("kind", [
4001
4008
  githubActionsRepoDestinationSchema,
4002
4009
  githubActionsEnvironmentDestinationSchema,
4003
4010
  githubActionsOrgDestinationSchema
@@ -4036,14 +4043,14 @@ const GCP_REPLICATION_POLICIES = ["automatic", "user-managed"];
4036
4043
  * Manager namespace is spelled `prod-storefront-DB_URL`, not
4037
4044
  * `prod/storefront/DB_URL`.
4038
4045
  */
4039
- const gcpSecretIdSchema = z.string().trim().min(1).max(255).regex(/^[A-Za-z0-9_-]+$/, "may contain letters, digits, hyphens, and underscores");
4046
+ const gcpSecretIdSchema = z$1.string().trim().min(1).max(255).regex(/^[A-Za-z0-9_-]+$/, "may contain letters, digits, hyphens, and underscores");
4040
4047
  /**
4041
4048
  * A GCP region for a user-managed replica (`us-east1`, `europe-west4`,
4042
4049
  * `northamerica-northeast1`). Validated by shape rather than against a list,
4043
4050
  * because Google adds regions faster than we ship — a name Secret Manager does
4044
4051
  * not know is refused by Google with a clear message at creation.
4045
4052
  */
4046
- const gcpLocationSchema = z.string().trim().regex(/^[a-z]+-[a-z]+\d+$/, "must be a GCP region ID, e.g. us-east1");
4053
+ const gcpLocationSchema = z$1.string().trim().regex(/^[a-z]+-[a-z]+\d+$/, "must be a GCP region ID, e.g. us-east1");
4047
4054
  /**
4048
4055
  * A Cloud KMS key, as its full resource name — the only form the API accepts:
4049
4056
  * `projects/p/locations/l/keyRings/r/cryptoKeys/k`.
@@ -4053,7 +4060,7 @@ const gcpLocationSchema = z.string().trim().regex(/^[a-z]+-[a-z]+\d+$/, "must be
4053
4060
  * rejected at creation: an automatic-replication secret needs a `global` key,
4054
4061
  * and a user-managed replica needs one in its own region.
4055
4062
  */
4056
- const gcpKmsKeyNameSchema = z.string().trim().max(1024).regex(/^projects\/[^/]+\/locations\/[^/]+\/keyRings\/[^/]+\/cryptoKeys\/[^/]+$/, "must be a full Cloud KMS key name (projects/…/locations/…/keyRings/…/cryptoKeys/…)");
4063
+ const gcpKmsKeyNameSchema = z$1.string().trim().max(1024).regex(/^projects\/[^/]+\/locations\/[^/]+\/keyRings\/[^/]+\/cryptoKeys\/[^/]+$/, "must be a full Cloud KMS key name (projects/…/locations/…/keyRings/…/cryptoKeys/…)");
4057
4064
  /**
4058
4065
  * Where inside a project's Secret Manager a binding writes.
4059
4066
  *
@@ -4072,25 +4079,25 @@ const gcpKmsKeyNameSchema = z.string().trim().max(1024).regex(/^projects\/[^/]+\
4072
4079
  * on, the version a push supersedes is destroyed as soon as the new one lands,
4073
4080
  * so a secret keeps exactly one active version.
4074
4081
  */
4075
- const gcpSecretManagerDestinationSchema = z.object({
4076
- provider: z.literal("gcp-secret-manager"),
4077
- layout: z.enum(GCP_SECRET_MANAGER_LAYOUTS).default("secret-per-name"),
4082
+ const gcpSecretManagerDestinationSchema = z$1.object({
4083
+ provider: z$1.literal("gcp-secret-manager"),
4084
+ layout: z$1.enum(GCP_SECRET_MANAGER_LAYOUTS).default("secret-per-name"),
4078
4085
  /**
4079
4086
  * `secret-per-name` only: prepended to every secret ID, e.g.
4080
4087
  * `prod-storefront-`. Optional, but strongly advised in a project that holds
4081
4088
  * anything else — without it a binding writes at the root of a namespace it
4082
4089
  * does not own, and Secret Manager has no folders to hide behind.
4083
4090
  */
4084
- idPrefix: z.string().trim().max(200).regex(/^[A-Za-z0-9_-]*$/, "may contain letters, digits, hyphens, and underscores").optional(),
4091
+ idPrefix: z$1.string().trim().max(200).regex(/^[A-Za-z0-9_-]*$/, "may contain letters, digits, hyphens, and underscores").optional(),
4085
4092
  /** `json-bundle` only: the one secret that holds every value, e.g. `prod-storefront-env`. */
4086
4093
  secretId: gcpSecretIdSchema.optional(),
4087
- replication: z.enum(GCP_REPLICATION_POLICIES).default("automatic"),
4094
+ replication: z$1.enum(GCP_REPLICATION_POLICIES).default("automatic"),
4088
4095
  /** `user-managed` only: the regions to replicate to. At least one. */
4089
- locations: z.array(gcpLocationSchema).min(1).max(16).optional(),
4096
+ locations: z$1.array(gcpLocationSchema).min(1).max(16).optional(),
4090
4097
  /** Customer-managed encryption key. Omitted means Google-managed keys. */
4091
4098
  kmsKeyName: gcpKmsKeyNameSchema.optional(),
4092
4099
  /** Destroy the version each push supersedes, keeping one active version. */
4093
- pruneVersions: z.boolean().optional()
4100
+ pruneVersions: z$1.boolean().optional()
4094
4101
  }).refine((d) => d.layout !== "json-bundle" || d.secretId !== void 0, {
4095
4102
  message: "a json-bundle destination needs the ID of the secret to write",
4096
4103
  path: ["secretId"]
@@ -4117,10 +4124,10 @@ const gcpSecretManagerDestinationSchema = z.object({
4117
4124
  * the `id` from `GET /v2/deployments`, and the UUID in the deployment's
4118
4125
  * dashboard URL.
4119
4126
  */
4120
- const langgraphPlatformDestinationSchema = z.object({
4121
- provider: z.literal("langgraph-platform"),
4127
+ const langgraphPlatformDestinationSchema = z$1.object({
4128
+ provider: z$1.literal("langgraph-platform"),
4122
4129
  /** Deployment UUID, from the dashboard URL or `GET /v2/deployments`. */
4123
- deploymentId: z.string().trim().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, "must be a LangGraph Platform deployment UUID")
4130
+ deploymentId: z$1.string().trim().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, "must be a LangGraph Platform deployment UUID")
4124
4131
  });
4125
4132
  /**
4126
4133
  * A Key Vault's name — the leftmost label of its DNS name, so the vault
@@ -4136,7 +4143,7 @@ const langgraphPlatformDestinationSchema = z.object({
4136
4143
  * any host, and the whole address seekrit needs is this label plus the cloud
4137
4144
  * already named on the connection.
4138
4145
  */
4139
- const azureVaultNameSchema = z.string().trim().regex(/^[A-Za-z](?!.*--)[A-Za-z0-9-]{1,22}[A-Za-z0-9]$/, "must be a Key Vault name: 3–24 letters, digits, and single hyphens, starting with a letter");
4146
+ const azureVaultNameSchema = z$1.string().trim().regex(/^[A-Za-z](?!.*--)[A-Za-z0-9-]{1,22}[A-Za-z0-9]$/, "must be a Key Vault name: 3–24 letters, digits, and single hyphens, starting with a letter");
4140
4147
  /**
4141
4148
  * What to do with a name Key Vault cannot store.
4142
4149
  *
@@ -4167,8 +4174,8 @@ const AZURE_KEY_VAULT_NAME_MODES = ["dash", "reject"];
4167
4174
  * charges per *operation*, so fifty names cost the same stored fifty ways. One
4168
4175
  * secret per name is simply correct here.
4169
4176
  */
4170
- const azureKeyVaultDestinationSchema = z.object({
4171
- provider: z.literal("azure-key-vault"),
4177
+ const azureKeyVaultDestinationSchema = z$1.object({
4178
+ provider: z$1.literal("azure-key-vault"),
4172
4179
  /** Vault name, e.g. `acme-prod` for `acme-prod.vault.azure.net`. */
4173
4180
  vault: azureVaultNameSchema,
4174
4181
  /**
@@ -4177,9 +4184,9 @@ const azureKeyVaultDestinationSchema = z.object({
4177
4184
  * accepts — so unlike Parameter Store's `path` this is a naming convention
4178
4185
  * and nothing more. Worth setting in a vault that holds anything else.
4179
4186
  */
4180
- prefix: z.string().trim().max(64).regex(/^[A-Za-z0-9-]*$/, "may contain letters, digits, and hyphens").optional(),
4187
+ prefix: z$1.string().trim().max(64).regex(/^[A-Za-z0-9-]*$/, "may contain letters, digits, and hyphens").optional(),
4181
4188
  /** What to do with a name Key Vault cannot store — see {@link AZURE_KEY_VAULT_NAME_MODES}. */
4182
- nameMode: z.enum(AZURE_KEY_VAULT_NAME_MODES).default("dash")
4189
+ nameMode: z$1.enum(AZURE_KEY_VAULT_NAME_MODES).default("dash")
4183
4190
  });
4184
4191
  /**
4185
4192
  * The Space whose secrets a binding owns, addressed the way the Hub addresses
@@ -4198,7 +4205,7 @@ const azureKeyVaultDestinationSchema = z.object({
4198
4205
  * leading character is held to alphanumeric, which is also what rejects the
4199
4206
  * `.` and `..` that no repository may be called.
4200
4207
  */
4201
- const huggingfaceRepoIdSchema = z.string().trim().regex(/^[A-Za-z0-9][A-Za-z0-9._-]{0,95}\/[A-Za-z0-9][A-Za-z0-9._-]{0,95}$/, "must be a Space ID as owner/name, e.g. acme/support-demo — not a URL");
4208
+ const huggingfaceRepoIdSchema = z$1.string().trim().regex(/^[A-Za-z0-9][A-Za-z0-9._-]{0,95}\/[A-Za-z0-9][A-Za-z0-9._-]{0,95}$/, "must be a Space ID as owner/name, e.g. acme/support-demo — not a URL");
4202
4209
  /**
4203
4210
  * One Hugging Face **Space**, whose secrets arrive in the app's container as
4204
4211
  * environment variables.
@@ -4210,16 +4217,16 @@ const huggingfaceRepoIdSchema = z.string().trim().regex(/^[A-Za-z0-9][A-Za-z0-9.
4210
4217
  * it, so this connector has no variables mode — a binding that wants one is
4211
4218
  * asking for the wrong thing.
4212
4219
  */
4213
- const huggingfaceSpacesDestinationSchema = z.object({
4214
- provider: z.literal("huggingface-spaces"),
4220
+ const huggingfaceSpacesDestinationSchema = z$1.object({
4221
+ provider: z$1.literal("huggingface-spaces"),
4215
4222
  /** Space ID as `owner/name`, e.g. `acme/support-demo`. */
4216
4223
  repoId: huggingfaceRepoIdSchema
4217
4224
  });
4218
4225
  /** One existing OpenAI vault; every credential in this binding gets the same host boundary. */
4219
- const openaiVaultDestinationSchema = z.object({
4220
- provider: z.literal("openai-vault"),
4221
- vaultId: z.string().trim().regex(/^vault_[A-Za-z0-9_-]+$/, "must be an OpenAI vault ID"),
4222
- allowedHosts: z.array(z.string().trim().toLowerCase().max(253).regex(/^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/, "must be an exact hostname without scheme, port, path, or wildcard")).min(1).max(100).refine((hosts) => new Set(hosts).size === hosts.length, "hostnames must be unique")
4226
+ const openaiVaultDestinationSchema = z$1.object({
4227
+ provider: z$1.literal("openai-vault"),
4228
+ vaultId: z$1.string().trim().regex(/^vault_[A-Za-z0-9_-]+$/, "must be an OpenAI vault ID"),
4229
+ allowedHosts: z$1.array(z$1.string().trim().toLowerCase().max(253).regex(/^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/, "must be an exact hostname without scheme, port, path, or wildcard")).min(1).max(100).refine((hosts) => new Set(hosts).size === hosts.length, "hostnames must be unique")
4223
4230
  });
4224
4231
  /**
4225
4232
  * A vault ID as the Claude Console and API show it: `vlt_` and an opaque
@@ -4227,7 +4234,7 @@ const openaiVaultDestinationSchema = z.object({
4227
4234
  * vault's display name — is a 404 from inside an alarm, which says nothing
4228
4235
  * about which half of the address was wrong.
4229
4236
  */
4230
- const claudeVaultIdSchema = z.string().trim().regex(/^vlt_[A-Za-z0-9]{1,128}$/, "must be a vault ID, e.g. vlt_01ABC… — not its display name");
4237
+ const claudeVaultIdSchema = z$1.string().trim().regex(/^vlt_[A-Za-z0-9]{1,128}$/, "must be a vault ID, e.g. vlt_01ABC… — not its display name");
4231
4238
  /** Ceiling on per-name host rules; a vault itself holds at most 20 credentials. */
4232
4239
  const CLAUDE_VAULT_MAX_HOST_RULES = 100;
4233
4240
  /** A hostname of two or more labels whose last label starts with a letter. */
@@ -4244,14 +4251,14 @@ const CLAUDE_VAULT_IPV4 = /^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2
4244
4251
  * `stripe.com` **but not `stripe.com` itself**, so a service reached at its apex
4245
4252
  * needs both entries. A bare TLD wildcard (`*.com`) is refused by shape.
4246
4253
  */
4247
- const claudeVaultHostSchema = z.string().trim().toLowerCase().max(253).refine((host) => CLAUDE_VAULT_HOSTNAME.test(host) || CLAUDE_VAULT_IPV4.test(host), "must be a bare hostname (api.example.com), a *.example.com wildcard, or an IPv4 address — not a URL");
4254
+ const claudeVaultHostSchema = z$1.string().trim().toLowerCase().max(253).refine((host) => CLAUDE_VAULT_HOSTNAME.test(host) || CLAUDE_VAULT_IPV4.test(host), "must be a bare hostname (api.example.com), a *.example.com wildcard, or an IPv4 address — not a URL");
4248
4255
  /**
4249
4256
  * Where one secret's value may be substituted: a list of hosts, or the literal
4250
4257
  * `"unrestricted"`, which lets it reach any host the agent's *environment*
4251
4258
  * permits. The literal is spelled out rather than implied by an empty list, so
4252
4259
  * the widest setting is never something a binding arrives at by omission.
4253
4260
  */
4254
- const claudeVaultHostRuleSchema = z.union([z.literal("unrestricted"), z.array(claudeVaultHostSchema).min(1).max(16)]);
4261
+ const claudeVaultHostRuleSchema = z$1.union([z$1.literal("unrestricted"), z$1.array(claudeVaultHostSchema).min(1).max(16)]);
4255
4262
  /**
4256
4263
  * Which parts of an outbound request a secret's placeholder is swapped in. The
4257
4264
  * API's own default when the field is omitted is both; seekrit's is `header`,
@@ -4284,15 +4291,15 @@ const CLAUDE_VAULT_INJECTION_LOCATIONS = [
4284
4291
  * flow. Both levels apply beside the agent environment's own network policy,
4285
4292
  * which must also let the host through; this shape cannot see that policy.
4286
4293
  */
4287
- const claudeManagedAgentsDestinationSchema = z.object({
4288
- provider: z.literal("claude-managed-agents"),
4294
+ const claudeManagedAgentsDestinationSchema = z$1.object({
4295
+ provider: z$1.literal("claude-managed-agents"),
4289
4296
  /** The vault's ID, e.g. `vlt_01ABC…`. */
4290
4297
  vaultId: claudeVaultIdSchema,
4291
4298
  /** Hosts for every name without its own entry in `allowedHostsByName`. */
4292
4299
  allowedHosts: claudeVaultHostRuleSchema.optional(),
4293
4300
  /** Destination name → the hosts that one value may be substituted on. */
4294
- allowedHostsByName: z.record(secretNameSchema, claudeVaultHostRuleSchema).optional(),
4295
- injectionLocation: z.enum(CLAUDE_VAULT_INJECTION_LOCATIONS).default("header")
4301
+ allowedHostsByName: z$1.record(secretNameSchema, claudeVaultHostRuleSchema).optional(),
4302
+ injectionLocation: z$1.enum(CLAUDE_VAULT_INJECTION_LOCATIONS).default("header")
4296
4303
  }).refine((d) => d.allowedHosts !== void 0 || Object.keys(d.allowedHostsByName ?? {}).length > 0, {
4297
4304
  message: "name the hosts each secret may be used on — allowedHosts for all of them, allowedHostsByName per name, or \"unrestricted\"",
4298
4305
  path: ["allowedHosts"]
@@ -4300,7 +4307,7 @@ const claudeManagedAgentsDestinationSchema = z.object({
4300
4307
  message: `at most ${CLAUDE_VAULT_MAX_HOST_RULES} per-name host rules`,
4301
4308
  path: ["allowedHostsByName"]
4302
4309
  });
4303
- const syncDestinationSchema = z.discriminatedUnion("provider", [
4310
+ const syncDestinationSchema = z$1.discriminatedUnion("provider", [
4304
4311
  vercelDestinationSchema,
4305
4312
  cloudflareWorkersDestinationSchema,
4306
4313
  cloudflarePagesDestinationSchema,
@@ -4327,59 +4334,59 @@ const syncDestinationSchema = z.discriminatedUnion("provider", [
4327
4334
  * How seekrit secret names become destination key names. Applied in order:
4328
4335
  * explicit `rename` (wins outright), then `prefix`/`suffix`, then `case`.
4329
4336
  */
4330
- const nameTransformSchema = z.object({
4331
- prefix: z.string().max(64).regex(/^[A-Za-z0-9_]*$/, "must be alphanumeric or underscore").optional(),
4332
- suffix: z.string().max(64).regex(/^[A-Za-z0-9_]*$/, "must be alphanumeric or underscore").optional(),
4333
- case: z.enum([
4337
+ const nameTransformSchema = z$1.object({
4338
+ prefix: z$1.string().max(64).regex(/^[A-Za-z0-9_]*$/, "must be alphanumeric or underscore").optional(),
4339
+ suffix: z$1.string().max(64).regex(/^[A-Za-z0-9_]*$/, "must be alphanumeric or underscore").optional(),
4340
+ case: z$1.enum([
4334
4341
  "preserve",
4335
4342
  "upper",
4336
4343
  "lower"
4337
4344
  ]).optional(),
4338
4345
  /** Exact per-secret overrides, seekrit name → destination name. */
4339
- rename: z.record(secretNameSchema, secretNameSchema).optional()
4346
+ rename: z$1.record(secretNameSchema, secretNameSchema).optional()
4340
4347
  });
4341
- z.object({
4348
+ z$1.object({
4342
4349
  /**
4343
4350
  * The id the client already fetched a public key for. Connections are a
4344
4351
  * two-step dance — mint the key, wrap the credential to it, then create the
4345
4352
  * row — so the id has to be chosen before the row exists. Omit it and the
4346
4353
  * server generates one (only useful when there is no credential to wrap yet).
4347
4354
  */
4348
- id: z.string().regex(/^syc_[A-Za-z0-9]{24}$/, "must be a connection id from the public-key call").optional(),
4349
- name: z.string().trim().min(1).max(128),
4355
+ id: z$1.string().regex(/^syc_[A-Za-z0-9]{24}$/, "must be a connection id from the public-key call").optional(),
4356
+ name: z$1.string().trim().min(1).max(128),
4350
4357
  config: syncConnectionConfigSchema,
4351
4358
  /**
4352
4359
  * The destination's API credential (a Vercel token), encrypted client-side to
4353
4360
  * the connection's public key (a `wd1.` wrap). The control plane stores only
4354
4361
  * this ciphertext; it is unwrapped transiently inside the sync engine DO.
4355
4362
  */
4356
- wrappedCredential: z.string().min(1)
4363
+ wrappedCredential: z$1.string().min(1)
4357
4364
  });
4358
- z.object({ destination: syncDestinationSchema });
4359
- const globListSchema = z.array(z.string().trim().min(1).max(256)).max(100);
4360
- z.object({
4361
- connectionId: z.string().min(1),
4362
- environmentId: z.string().min(1),
4365
+ z$1.object({ destination: syncDestinationSchema });
4366
+ const globListSchema = z$1.array(z$1.string().trim().min(1).max(256)).max(100);
4367
+ z$1.object({
4368
+ connectionId: z$1.string().min(1),
4369
+ environmentId: z$1.string().min(1),
4363
4370
  destination: syncDestinationSchema,
4364
4371
  nameTransform: nameTransformSchema.optional(),
4365
4372
  include: globListSchema.optional(),
4366
4373
  exclude: globListSchema.optional(),
4367
- onDelete: z.enum(["delete", "retain"]).default("delete"),
4368
- mode: z.enum(["auto", "manual"]).default("auto"),
4369
- wrappedDeks: z.array(z.object({
4370
- environmentId: z.string().min(1),
4371
- wrappedDek: z.string().min(1)
4374
+ onDelete: z$1.enum(["delete", "retain"]).default("delete"),
4375
+ mode: z$1.enum(["auto", "manual"]).default("auto"),
4376
+ wrappedDeks: z$1.array(z$1.object({
4377
+ environmentId: z$1.string().min(1),
4378
+ wrappedDek: z$1.string().min(1)
4372
4379
  })).min(1),
4373
- acknowledgedDecryption: z.literal(true)
4380
+ acknowledgedDecryption: z$1.literal(true)
4374
4381
  });
4375
- z.object({
4382
+ z$1.object({
4376
4383
  destination: syncDestinationSchema.optional(),
4377
4384
  nameTransform: nameTransformSchema.nullable().optional(),
4378
4385
  include: globListSchema.nullable().optional(),
4379
4386
  exclude: globListSchema.nullable().optional(),
4380
- onDelete: z.enum(["delete", "retain"]).optional(),
4381
- mode: z.enum(["auto", "manual"]).optional(),
4382
- enabled: z.boolean().optional()
4387
+ onDelete: z$1.enum(["delete", "retain"]).optional(),
4388
+ mode: z$1.enum(["auto", "manual"]).optional(),
4389
+ enabled: z$1.boolean().optional()
4383
4390
  });
4384
4391
  // ../../packages/core/src/vault.ts
4385
4392
  /** One encrypted credential within a connection. */
@@ -4411,73 +4418,73 @@ const VAULT_WEBHOOK_EVENTS = [
4411
4418
  "connection.reauth_required",
4412
4419
  "connection.revoked"
4413
4420
  ];
4414
- const base64urlMember = z.string().regex(/^[A-Za-z0-9_-]{43}$/, "not a P-256 coordinate");
4415
- const vaultPublicJwkSchema = z.object({
4416
- kty: z.literal("EC"),
4417
- crv: z.literal("P-256"),
4421
+ const base64urlMember = z$1.string().regex(/^[A-Za-z0-9_-]{43}$/, "not a P-256 coordinate");
4422
+ const vaultPublicJwkSchema = z$1.object({
4423
+ kty: z$1.literal("EC"),
4424
+ crv: z$1.literal("P-256"),
4418
4425
  x: base64urlMember,
4419
4426
  y: base64urlMember
4420
4427
  });
4421
- const isoInstant = z.iso.datetime({ offset: true });
4422
- z.object({
4423
- v: z.literal(1),
4424
- accessToken: z.string().min(1).max(16384),
4425
- tokenType: z.literal("Bearer"),
4428
+ const isoInstant = z$1.iso.datetime({ offset: true });
4429
+ z$1.object({
4430
+ v: z$1.literal(1),
4431
+ accessToken: z$1.string().min(1).max(16384),
4432
+ tokenType: z$1.literal("Bearer"),
4426
4433
  accessTokenExpiresAt: isoInstant.optional(),
4427
- refreshToken: z.string().min(1).max(16384).optional(),
4434
+ refreshToken: z$1.string().min(1).max(16384).optional(),
4428
4435
  refreshTokenExpiresAt: isoInstant.optional(),
4429
- scope: z.array(z.string().max(512)).max(128),
4436
+ scope: z$1.array(z$1.string().max(512)).max(128),
4430
4437
  obtainedAt: isoInstant
4431
4438
  });
4432
- z.object({
4433
- v: z.literal(1),
4434
- key: z.string().min(1).max(8192)
4439
+ z$1.object({
4440
+ v: z$1.literal(1),
4441
+ key: z$1.string().min(1).max(8192)
4435
4442
  });
4436
4443
  /** RFC 6238 parameters, as an authenticator app would hold them. */
4437
- const vaultTotpSchema = z.object({
4444
+ const vaultTotpSchema = z$1.object({
4438
4445
  /** Base32 (RFC 4648), upper case, no padding, no separators. */
4439
- secret: z.string().regex(/^[A-Z2-7]{16,128}$/, "TOTP secret must be base32"),
4440
- digits: z.union([z.literal(6), z.literal(8)]),
4441
- period: z.number().int().min(15).max(120),
4442
- algorithm: z.enum([
4446
+ secret: z$1.string().regex(/^[A-Z2-7]{16,128}$/, "TOTP secret must be base32"),
4447
+ digits: z$1.union([z$1.literal(6), z$1.literal(8)]),
4448
+ period: z$1.number().int().min(15).max(120),
4449
+ algorithm: z$1.enum([
4443
4450
  "SHA1",
4444
4451
  "SHA256",
4445
4452
  "SHA512"
4446
4453
  ])
4447
4454
  });
4448
- z.object({
4449
- v: z.literal(1),
4450
- username: z.string().min(1).max(512),
4451
- password: z.string().min(1).max(4096),
4455
+ z$1.object({
4456
+ v: z$1.literal(1),
4457
+ username: z$1.string().min(1).max(512),
4458
+ password: z$1.string().min(1).max(4096),
4452
4459
  totp: vaultTotpSchema.optional()
4453
4460
  });
4454
- const vaultSessionCookieSchema = z.object({
4455
- name: z.string().min(1).max(4096),
4456
- value: z.string().max(16384),
4461
+ const vaultSessionCookieSchema = z$1.object({
4462
+ name: z$1.string().min(1).max(4096),
4463
+ value: z$1.string().max(16384),
4457
4464
  /** Kept exactly as captured — parent-domain cookies restore to their parent. */
4458
- domain: z.string().min(1).max(253),
4459
- path: z.string().min(1).max(4096),
4465
+ domain: z$1.string().min(1).max(253),
4466
+ path: z$1.string().min(1).max(4096),
4460
4467
  /** Unix seconds; -1 ⇒ a session cookie. */
4461
- expires: z.number(),
4462
- httpOnly: z.boolean(),
4463
- secure: z.boolean(),
4464
- sameSite: z.enum([
4468
+ expires: z$1.number(),
4469
+ httpOnly: z$1.boolean(),
4470
+ secure: z$1.boolean(),
4471
+ sameSite: z$1.enum([
4465
4472
  "Strict",
4466
4473
  "Lax",
4467
4474
  "None"
4468
4475
  ]).optional(),
4469
- partitionKey: z.unknown().optional()
4476
+ partitionKey: z$1.unknown().optional()
4470
4477
  });
4471
- z.object({
4472
- v: z.literal(1),
4473
- siteId: z.string().min(1).max(64),
4478
+ z$1.object({
4479
+ v: z$1.literal(1),
4480
+ siteId: z$1.string().min(1).max(64),
4474
4481
  capturedAt: isoInstant,
4475
- userAgent: z.string().max(1024),
4476
- cookies: z.array(vaultSessionCookieSchema).max(4096),
4482
+ userAgent: z$1.string().max(1024),
4483
+ cookies: z$1.array(vaultSessionCookieSchema).max(4096),
4477
4484
  /** origin → key → value. */
4478
- localStorage: z.record(z.string(), z.record(z.string(), z.string()))
4485
+ localStorage: z$1.record(z$1.string(), z$1.record(z$1.string(), z$1.string()))
4479
4486
  });
4480
- const vaultProviderIdSchema = z.string().trim().min(1).max(64).regex(/^[a-z0-9][a-z0-9._-]*$/, "provider ids are lowercase letters, digits, dots and dashes");
4487
+ const vaultProviderIdSchema = z$1.string().trim().min(1).max(64).regex(/^[a-z0-9][a-z0-9._-]*$/, "provider ids are lowercase letters, digits, dots and dashes");
4481
4488
  /**
4482
4489
  * What the dashboard, Connect and the SDK may know about a provider: its name,
4483
4490
  * its method, and — for the consent screen — a plain sentence about what the
@@ -4485,90 +4492,90 @@ const vaultProviderIdSchema = z.string().trim().min(1).max(64).regex(/^[a-z0-9][
4485
4492
  * those are compiled into the executor and the API must not be able to serve a
4486
4493
  * different version of them.
4487
4494
  */
4488
- const vaultCatalogProviderSchema = z.object({
4495
+ const vaultCatalogProviderSchema = z$1.object({
4489
4496
  id: vaultProviderIdSchema,
4490
- displayName: z.string().trim().min(1).max(80),
4491
- method: z.enum(["oauth2", "api_key"]),
4497
+ displayName: z$1.string().trim().min(1).max(80),
4498
+ method: z$1.enum(["oauth2", "api_key"]),
4492
4499
  /** The one sentence Connect shows: "read and send email as you". */
4493
- consentSummary: z.string().trim().min(1).max(240),
4500
+ consentSummary: z$1.string().trim().min(1).max(240),
4494
4501
  /** Hosts the executor will forward to, for display. */
4495
- hosts: z.array(z.string().trim().min(1).max(253)).max(64).default([]),
4502
+ hosts: z$1.array(z$1.string().trim().min(1).max(253)).max(64).default([]),
4496
4503
  /** Where the end user finds the key (api_key providers). */
4497
- helpUrl: z.url().max(2048).optional(),
4504
+ helpUrl: z$1.url().max(2048).optional(),
4498
4505
  /** Label for the key field (api_key providers), e.g. "API key". */
4499
- keyLabel: z.string().trim().min(1).max(60).optional(),
4506
+ keyLabel: z$1.string().trim().min(1).max(60).optional(),
4500
4507
  /** OAuth scopes the provider will be asked for (oauth2 providers), for display. */
4501
- scopes: z.array(z.string().trim().min(1).max(512)).max(64).optional()
4508
+ scopes: z$1.array(z$1.string().trim().min(1).max(512)).max(64).optional()
4502
4509
  });
4503
- const vaultCatalogSiteSchema = z.object({
4510
+ const vaultCatalogSiteSchema = z$1.object({
4504
4511
  id: vaultProviderIdSchema,
4505
- displayName: z.string().trim().min(1).max(80),
4506
- consentSummary: z.string().trim().min(1).max(240),
4512
+ displayName: z$1.string().trim().min(1).max(80),
4513
+ consentSummary: z$1.string().trim().min(1).max(240),
4507
4514
  /** Origins the login form must live on (shown so the person can check). */
4508
- loginOrigins: z.array(z.url().max(2048)).max(16).default([]),
4515
+ loginOrigins: z$1.array(z$1.url().max(2048)).max(16).default([]),
4509
4516
  /** Where a restored session lands, for display. */
4510
- startUrl: z.url().max(2048).optional()
4517
+ startUrl: z$1.url().max(2048).optional()
4511
4518
  });
4512
- const vaultCatalogSchema = z.object({
4513
- v: z.literal(1),
4514
- providers: z.array(vaultCatalogProviderSchema).max(200).default([]),
4515
- sites: z.array(vaultCatalogSiteSchema).max(200).default([])
4519
+ const vaultCatalogSchema = z$1.object({
4520
+ v: z$1.literal(1),
4521
+ providers: z$1.array(vaultCatalogProviderSchema).max(200).default([]),
4522
+ sites: z$1.array(vaultCatalogSiteSchema).max(200).default([])
4516
4523
  });
4517
- const vaultDisplaySchema = z.object({
4524
+ const vaultDisplaySchema = z$1.object({
4518
4525
  /** The platform's name as its users know it: "Instinct", not "instinct-prod". */
4519
- name: z.string().trim().min(1).max(80),
4520
- logoUrl: z.url().max(2048).startsWith("https://").optional(),
4526
+ name: z$1.string().trim().min(1).max(80),
4527
+ logoUrl: z$1.url().max(2048).startsWith("https://").optional(),
4521
4528
  /** `#rrggbb`. */
4522
- accent: z.string().regex(/^#[0-9a-fA-F]{6}$/, "accent must be a #rrggbb colour").optional(),
4529
+ accent: z$1.string().regex(/^#[0-9a-fA-F]{6}$/, "accent must be a #rrggbb colour").optional(),
4523
4530
  /** Origins a `returnUrl` may point at. Exact-match, scheme + host (+ port). */
4524
- returnOrigins: z.array(z.url().max(2048)).max(16).default([])
4531
+ returnOrigins: z$1.array(z$1.url().max(2048)).max(16).default([])
4525
4532
  });
4526
- z.object({
4533
+ z$1.object({
4527
4534
  name: nameSchema,
4528
4535
  display: vaultDisplaySchema.optional()
4529
4536
  });
4530
- z.object({
4537
+ z$1.object({
4531
4538
  name: nameSchema.optional(),
4532
4539
  display: vaultDisplaySchema.optional(),
4533
- status: z.enum(["active", "disabled"]).optional()
4540
+ status: z$1.enum(["active", "disabled"]).optional()
4534
4541
  });
4535
- z.object({ name: nameSchema });
4542
+ z$1.object({ name: nameSchema });
4536
4543
  /**
4537
4544
  * The platform's opaque identifier for its end user. Stored as given and
4538
4545
  * returned as given. It must not be an email address or anything else that
4539
4546
  * identifies the person outside the platform: the person has no seekrit
4540
4547
  * account, and this is the one field about them Vault holds in the clear.
4541
4548
  */
4542
- const vaultUserRefSchema = z.string().trim().min(1).max(200).refine((v) => !/\s/.test(v), { message: "userRef must not contain whitespace" }).refine((v) => !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(v), { message: "userRef must be an opaque identifier, not an email address" });
4543
- z.object({
4549
+ const vaultUserRefSchema = z$1.string().trim().min(1).max(200).refine((v) => !/\s/.test(v), { message: "userRef must not contain whitespace" }).refine((v) => !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(v), { message: "userRef must be an opaque identifier, not an email address" });
4550
+ z$1.object({
4544
4551
  userRef: vaultUserRefSchema,
4545
4552
  providerId: vaultProviderIdSchema,
4546
- purpose: z.enum(["connect", "reconnect"]).default("connect"),
4553
+ purpose: z$1.enum(["connect", "reconnect"]).default("connect"),
4547
4554
  /** Required for `reconnect`: the connection being repaired. */
4548
- connectionId: z.string().trim().min(1).max(64).optional(),
4555
+ connectionId: z$1.string().trim().min(1).max(64).optional(),
4549
4556
  /** Where the done screen may send the person. Must match a registered origin. */
4550
- returnUrl: z.url().max(2048).optional(),
4551
- expiresInSeconds: z.number().int().min(60).max(VAULT_CONNECT_SESSION_MAX_TTL_SECONDS).optional()
4557
+ returnUrl: z$1.url().max(2048).optional(),
4558
+ expiresInSeconds: z$1.number().int().min(60).max(VAULT_CONNECT_SESSION_MAX_TTL_SECONDS).optional()
4552
4559
  });
4553
- z.object({
4560
+ z$1.object({
4554
4561
  userRef: vaultUserRefSchema,
4555
- returnUrl: z.url().max(2048).optional(),
4556
- expiresInSeconds: z.number().int().min(60).max(VAULT_CONNECT_SESSION_MAX_TTL_SECONDS).optional()
4562
+ returnUrl: z$1.url().max(2048).optional(),
4563
+ expiresInSeconds: z$1.number().int().min(60).max(VAULT_CONNECT_SESSION_MAX_TTL_SECONDS).optional()
4557
4564
  });
4558
- z.object({
4559
- url: z.url().max(2048).refine((u) => u.startsWith("https://"), "webhook URLs must be https"),
4565
+ z$1.object({
4566
+ url: z$1.url().max(2048).refine((u) => u.startsWith("https://"), "webhook URLs must be https"),
4560
4567
  /** Defaults to every event. */
4561
- events: z.array(z.enum(VAULT_WEBHOOK_EVENTS)).min(1).max(VAULT_WEBHOOK_EVENTS.length).optional(),
4562
- description: z.string().trim().max(200).optional()
4568
+ events: z$1.array(z$1.enum(VAULT_WEBHOOK_EVENTS)).min(1).max(VAULT_WEBHOOK_EVENTS.length).optional(),
4569
+ description: z$1.string().trim().max(200).optional()
4563
4570
  });
4564
- z.object({
4571
+ z$1.object({
4565
4572
  userRef: vaultUserRefSchema.optional(),
4566
- status: z.enum(VAULT_CONNECTION_STATUSES).optional(),
4567
- cursor: z.string().max(200).optional(),
4568
- limit: z.coerce.number().int().min(1).max(200).default(50)
4573
+ status: z$1.enum(VAULT_CONNECTION_STATUSES).optional(),
4574
+ cursor: z$1.string().max(200).optional(),
4575
+ limit: z$1.coerce.number().int().min(1).max(200).default(50)
4569
4576
  });
4570
4577
  /** An `https://host[:port]` origin with nothing after it; `http://localhost` in dev. */
4571
- const vaultOriginSchema = z.string().trim().max(2048).refine((v) => {
4578
+ const vaultOriginSchema = z$1.string().trim().max(2048).refine((v) => {
4572
4579
  let url;
4573
4580
  try {
4574
4581
  url = new URL(v);
@@ -4583,85 +4590,85 @@ const vaultOriginSchema = z.string().trim().max(2048).refine((v) => {
4583
4590
  "[::1]"
4584
4591
  ].includes(url.hostname);
4585
4592
  }, { message: "must be an https origin (scheme + host, nothing else)" });
4586
- const vaultWrappingKeySchema = z.object({
4593
+ const vaultWrappingKeySchema = z$1.object({
4587
4594
  jwk: vaultPublicJwkSchema,
4588
- thumbprint: z.string().regex(/^[A-Za-z0-9_-]{43}$/)
4595
+ thumbprint: z$1.string().regex(/^[A-Za-z0-9_-]{43}$/)
4589
4596
  });
4590
- z.object({
4591
- code: z.string().trim().min(16).max(200),
4597
+ z$1.object({
4598
+ code: z$1.string().trim().min(16).max(200),
4592
4599
  origin: vaultOriginSchema,
4593
4600
  wrappingKey: vaultWrappingKeySchema,
4594
4601
  catalog: vaultCatalogSchema,
4595
- sdkVersion: z.string().trim().min(1).max(40)
4602
+ sdkVersion: z$1.string().trim().min(1).max(40)
4596
4603
  });
4597
- z.object({
4604
+ z$1.object({
4598
4605
  catalog: vaultCatalogSchema,
4599
- sdkVersion: z.string().trim().min(1).max(40)
4606
+ sdkVersion: z$1.string().trim().min(1).max(40)
4600
4607
  });
4601
- z.object({ wrappingKey: vaultWrappingKeySchema });
4608
+ z$1.object({ wrappingKey: vaultWrappingKeySchema });
4602
4609
  /** One encrypted slot, as produced by Connect or the executor. */
4603
- const vaultEncryptedSlotSchema = z.object({
4604
- slot: z.enum(VAULT_SLOTS),
4605
- revision: z.number().int().min(1),
4606
- ciphertext: z.string().startsWith("sc1.").max(VAULT_CIPHERTEXT_MAX_CHARS),
4607
- wrappedDek: z.string().startsWith("wd1.").max(2048),
4608
- keyThumbprint: z.string().regex(/^[A-Za-z0-9_-]{43}$/)
4610
+ const vaultEncryptedSlotSchema = z$1.object({
4611
+ slot: z$1.enum(VAULT_SLOTS),
4612
+ revision: z$1.number().int().min(1),
4613
+ ciphertext: z$1.string().startsWith("sc1.").max(VAULT_CIPHERTEXT_MAX_CHARS),
4614
+ wrappedDek: z$1.string().startsWith("wd1.").max(2048),
4615
+ keyThumbprint: z$1.string().regex(/^[A-Za-z0-9_-]{43}$/)
4609
4616
  });
4610
- z.object({
4611
- slots: z.array(vaultEncryptedSlotSchema).min(1).max(2),
4617
+ z$1.object({
4618
+ slots: z$1.array(vaultEncryptedSlotSchema).min(1).max(2),
4612
4619
  /** "ava@example.com" / "@ava" — shown to the platform and the org, never used for auth. */
4613
- accountLabel: z.string().trim().min(1).max(200).optional()
4620
+ accountLabel: z$1.string().trim().min(1).max(200).optional()
4614
4621
  });
4615
- z.object({
4622
+ z$1.object({
4616
4623
  /** The revision the writer read; the write lands as `expectedRevision + 1`. */
4617
- expectedRevision: z.number().int().min(0),
4618
- ciphertext: z.string().startsWith("sc1.").max(VAULT_CIPHERTEXT_MAX_CHARS),
4619
- wrappedDek: z.string().startsWith("wd1.").max(2048),
4620
- keyThumbprint: z.string().regex(/^[A-Za-z0-9_-]{43}$/)
4624
+ expectedRevision: z$1.number().int().min(0),
4625
+ ciphertext: z$1.string().startsWith("sc1.").max(VAULT_CIPHERTEXT_MAX_CHARS),
4626
+ wrappedDek: z$1.string().startsWith("wd1.").max(2048),
4627
+ keyThumbprint: z$1.string().regex(/^[A-Za-z0-9_-]{43}$/)
4621
4628
  });
4622
- z.discriminatedUnion("status", [z.object({
4623
- status: z.literal("reauth_required"),
4624
- reason: z.string().trim().min(1).max(120)
4625
- }), z.object({ status: z.literal("active") })]);
4626
- z.object({ claimToken: z.string().min(16).max(200) });
4627
- z.object({ token: z.string().min(16).max(200) });
4628
- z.object({ consentVersion: z.literal(1) });
4629
- z.object({ connectionId: z.string().trim().min(1).max(64) });
4630
- z.object({
4629
+ z$1.discriminatedUnion("status", [z$1.object({
4630
+ status: z$1.literal("reauth_required"),
4631
+ reason: z$1.string().trim().min(1).max(120)
4632
+ }), z$1.object({ status: z$1.literal("active") })]);
4633
+ z$1.object({ claimToken: z$1.string().min(16).max(200) });
4634
+ z$1.object({ token: z$1.string().min(16).max(200) });
4635
+ z$1.object({ consentVersion: z$1.literal(1) });
4636
+ z$1.object({ connectionId: z$1.string().trim().min(1).max(64) });
4637
+ z$1.object({
4631
4638
  login: vaultEncryptedSlotSchema.refine((slot) => slot.slot === "login", "must be the login slot").optional(),
4632
- accountLabel: z.string().trim().min(1).max(200).optional()
4639
+ accountLabel: z$1.string().trim().min(1).max(200).optional()
4633
4640
  });
4634
- z.object({
4641
+ z$1.object({
4635
4642
  userRef: vaultUserRefSchema,
4636
- connectionId: z.string().trim().min(1).max(64),
4637
- request: z.object({
4638
- method: z.string().trim().toUpperCase().regex(/^[A-Z]{3,10}$/),
4639
- url: z.url().max(8192),
4640
- headers: z.record(z.string().max(256), z.string().max(16384)).optional(),
4643
+ connectionId: z$1.string().trim().min(1).max(64),
4644
+ request: z$1.object({
4645
+ method: z$1.string().trim().toUpperCase().regex(/^[A-Z]{3,10}$/),
4646
+ url: z$1.url().max(8192),
4647
+ headers: z$1.record(z$1.string().max(256), z$1.string().max(16384)).optional(),
4641
4648
  /** UTF-8 text. Binary bodies are out of scope for V1. */
4642
- body: z.string().max(4194304).optional()
4649
+ body: z$1.string().max(4194304).optional()
4643
4650
  })
4644
4651
  });
4645
- const connectionIdSchema = z.string().trim().min(1).max(64);
4646
- const leaseIdSchema = z.string().trim().min(1).max(64);
4647
- z.object({
4652
+ const connectionIdSchema = z$1.string().trim().min(1).max(64);
4653
+ const leaseIdSchema = z$1.string().trim().min(1).max(64);
4654
+ z$1.object({
4648
4655
  userRef: vaultUserRefSchema,
4649
4656
  connectionId: connectionIdSchema,
4650
4657
  /** How long the agent may hold the browser. Clamped to the site's ceiling. */
4651
- keepAliveMs: z.number().int().min(VAULT_LEASE_MIN_MS).max(VAULT_LEASE_MAX_MS).optional()
4658
+ keepAliveMs: z$1.number().int().min(VAULT_LEASE_MIN_MS).max(VAULT_LEASE_MAX_MS).optional()
4652
4659
  });
4653
- z.object({
4660
+ z$1.object({
4654
4661
  userRef: vaultUserRefSchema,
4655
4662
  leaseId: leaseIdSchema,
4656
- field: z.enum(VAULT_FILL_FIELDS)
4663
+ field: z$1.enum(VAULT_FILL_FIELDS)
4657
4664
  });
4658
- z.object({
4665
+ z$1.object({
4659
4666
  userRef: vaultUserRefSchema,
4660
4667
  leaseId: leaseIdSchema,
4661
4668
  /** Write the rotated session back (default). `false` drops the browser without saving. */
4662
- save: z.boolean().default(true)
4669
+ save: z$1.boolean().default(true)
4663
4670
  });
4664
- z.object({
4671
+ z$1.object({
4665
4672
  userRef: vaultUserRefSchema,
4666
4673
  leaseId: leaseIdSchema
4667
4674
  });
@@ -5887,7 +5894,7 @@ async function createAgentTaskToken() {
5887
5894
  };
5888
5895
  }
5889
5896
  // package.json
5890
- var version = "2.5.1";
5897
+ var version = "2.6.0";
5891
5898
  // ../../packages/api-client/src/index.ts
5892
5899
  /**
5893
5900
  * The proposer's note travels as a header, not a body field: an unprotected
@@ -7052,13 +7059,13 @@ const CLI_CLIENT = `cli/${version}`;
7052
7059
  * bearer of nothing: a 401 where the honest answer is "you have no
7053
7060
  * credentials", pointing at the API instead of at the missing variable.
7054
7061
  */
7055
- function present(value) {
7062
+ function present$1(value) {
7056
7063
  const trimmed = value?.trim();
7057
7064
  return trimmed ? trimmed : void 0;
7058
7065
  }
7059
7066
  function tryBuildContext(dotenvVars = {}) {
7060
7067
  const config = readGlobalConfig();
7061
- const fromEnv = (key) => present(process.env[key]) ?? present(dotenvVars[key]);
7068
+ const fromEnv = (key) => present$1(process.env[key]) ?? present$1(dotenvVars[key]);
7062
7069
  const apiUrl = fromEnv("SEEKRIT_API_URL") ?? config.apiUrl ?? "https://api.seekrit.dev";
7063
7070
  const token = fromEnv("SEEKRIT_TOKEN") ?? config.token ?? config.sessionToken;
7064
7071
  const devUser = fromEnv("SEEKRIT_DEV_USER") ?? config.devUser;
@@ -7103,7 +7110,7 @@ function describeError(err) {
7103
7110
  if (!(err instanceof Error)) return String(err);
7104
7111
  if (err.message !== "fetch failed") return err.message;
7105
7112
  const config = readGlobalConfig();
7106
- const apiUrl = present(process.env.SEEKRIT_API_URL) ?? config.apiUrl ?? "https://api.seekrit.dev";
7113
+ const apiUrl = present$1(process.env.SEEKRIT_API_URL) ?? config.apiUrl ?? "https://api.seekrit.dev";
7107
7114
  const cause = err.cause;
7108
7115
  const reason = cause instanceof Error ? cause.code ?? cause.message : void 0;
7109
7116
  return `cannot reach the seekrit API at ${apiUrl}${reason ? ` (${reason})` : ""} — check SEEKRIT_API_URL, your network, and that the API is up`;
@@ -7658,7 +7665,7 @@ function defaultIsAlive(pid) {
7658
7665
  }
7659
7666
  }
7660
7667
  /** Write a file so a reader sees the old bytes or the new ones, never half of each. */
7661
- function writeAtomic(path, content) {
7668
+ function writeAtomic$1(path, content) {
7662
7669
  mkdirSync(dirname(path), {
7663
7670
  recursive: true,
7664
7671
  mode: 448
@@ -7725,7 +7732,7 @@ var AgentLoginSession = class {
7725
7732
  await this.recoverLeftover();
7726
7733
  await this.acquire();
7727
7734
  this.registerHolder();
7728
- writeAtomic(this.o.path, this.synced);
7735
+ writeAtomic$1(this.o.path, this.synced);
7729
7736
  this.placed = true;
7730
7737
  this.lastRemotePoll = this.o.now();
7731
7738
  this.timer = setInterval(() => void this.tick(), this.o.localPollMs);
@@ -7899,7 +7906,7 @@ var AgentLoginSession = class {
7899
7906
  this.version = snapshot.version;
7900
7907
  continue;
7901
7908
  }
7902
- writeAtomic(this.o.path, remote.content);
7909
+ writeAtomic$1(this.o.path, remote.content);
7903
7910
  this.adopt(snapshot, remote);
7904
7911
  this.o.log(`another sandbox refreshed the ${this.o.adapter.label} login at the same moment; switched to its copy. If ${this.o.adapter.label} reports a sign-in error, run \`seekrit agent-login ${this.o.adapter.id}\` again.`);
7905
7912
  return;
@@ -7925,7 +7932,7 @@ var AgentLoginSession = class {
7925
7932
  const local = readIfExists(this.o.path);
7926
7933
  if (local !== null && local !== this.synced) return;
7927
7934
  if (remote.content !== this.synced && !this.fresher(this.synced, remote.content)) {
7928
- writeAtomic(this.o.path, remote.content);
7935
+ writeAtomic$1(this.o.path, remote.content);
7929
7936
  this.o.log(`picked up a ${this.o.adapter.label} login another sandbox refreshed`);
7930
7937
  }
7931
7938
  if (remote.claim?.holder !== this.o.holder) this.claimUntil = null;
@@ -7976,7 +7983,7 @@ var AgentLoginSession = class {
7976
7983
  secret: this.o.secretName,
7977
7984
  holders
7978
7985
  };
7979
- writeAtomic(this.markerPath, `${JSON.stringify(marker, null, 2)}\n`);
7986
+ writeAtomic$1(this.markerPath, `${JSON.stringify(marker, null, 2)}\n`);
7980
7987
  }
7981
7988
  /** Several runs on one machine can share a home; the last one out cleans up. */
7982
7989
  registerHolder() {
@@ -9560,7 +9567,7 @@ async function syncGrantsForGroupLink(ctx, orgId, envId, envSlug, groupId) {
9560
9567
  }
9561
9568
  // src/kms.ts
9562
9569
  /** Collect a repeatable option into a list. */
9563
- function collect$9(value, acc = []) {
9570
+ function collect$10(value, acc = []) {
9564
9571
  acc.push(value);
9565
9572
  return acc;
9566
9573
  }
@@ -9628,7 +9635,7 @@ async function kmsRecoverMaterial(ctx, orgId, keyId, version) {
9628
9635
  }
9629
9636
  function registerKmsCommands(program) {
9630
9637
  const kms = program.command("kms").description("managed keys for application-layer encryption & signing (client-side)");
9631
- kms.command("create").description("create a managed key (material is generated locally and wrapped, never sent)").requiredOption("--name <name>", "org-unique key name").requiredOption("--purpose <purpose>", "encrypt | sign").option("--org <slug>", "organization slug (defaults to seekrit.json, or your only org)").option("--app <slug>", "scope the key to an application").option("--group <slug>", "scope the key to a group").option("--grant-user <email>", "also grant an org member (repeatable)", collect$9, []).option("--grant-token <tokenId>", "also grant a service token (repeatable)", collect$9, []).action(async (options) => {
9638
+ kms.command("create").description("create a managed key (material is generated locally and wrapped, never sent)").requiredOption("--name <name>", "org-unique key name").requiredOption("--purpose <purpose>", "encrypt | sign").option("--org <slug>", "organization slug (defaults to seekrit.json, or your only org)").option("--app <slug>", "scope the key to an application").option("--group <slug>", "scope the key to a group").option("--grant-user <email>", "also grant an org member (repeatable)", collect$10, []).option("--grant-token <tokenId>", "also grant a service token (repeatable)", collect$10, []).action(async (options) => {
9632
9639
  if (options.purpose !== "encrypt" && options.purpose !== "sign") fail("--purpose must be encrypt or sign");
9633
9640
  if (options.app && options.group) fail("pass at most one of --app or --group");
9634
9641
  const ctx = buildContext();
@@ -9849,7 +9856,7 @@ function registerKmsCommands(program) {
9849
9856
  }
9850
9857
  // src/recovery.ts
9851
9858
  /** Collect a repeatable option into a list. */
9852
- function collect$8(value, acc = []) {
9859
+ function collect$9(value, acc = []) {
9853
9860
  acc.push(value);
9854
9861
  return acc;
9855
9862
  }
@@ -9946,7 +9953,7 @@ function registerRecoveryCommands(program) {
9946
9953
  for (const cst of status.custodians) console.log(` - ${cst.label ?? cst.principalId} (${cst.principalType}, share #${cst.shareIndex})`);
9947
9954
  if (status.coverage.unprotectedEnvIds.length > 0) console.log(`${status.coverage.unprotectedEnvIds.length} environment(s) not yet protected — run \`seekrit recovery sync\``);
9948
9955
  });
9949
- recovery.command("setup").description("enable recovery: split a fresh recovery key across custodians").requiredOption("--threshold <M>", "custodians required to recover (M in M-of-N)").option("--custodian <email|skt_id>", "a recovery custodian (repeatable)", collect$8, []).option("--org <slug>", "organization slug (defaults to seekrit.json, or your only org)").action(async (options) => {
9956
+ recovery.command("setup").description("enable recovery: split a fresh recovery key across custodians").requiredOption("--threshold <M>", "custodians required to recover (M in M-of-N)").option("--custodian <email|skt_id>", "a recovery custodian (repeatable)", collect$9, []).option("--org <slug>", "organization slug (defaults to seekrit.json, or your only org)").action(async (options) => {
9950
9957
  const ctx = buildContext();
9951
9958
  const org = await resolveOrg(ctx, options.org);
9952
9959
  const config = await buildRecoveryConfig(ctx, org.id, options.threshold, options.custodian);
@@ -9964,7 +9971,7 @@ function registerRecoveryCommands(program) {
9964
9971
  const { wrapped, skipped } = await syncRecoveryGrants(ctx, (await resolveOrg(ctx, options.org)).id);
9965
9972
  console.error(`recovery-protected ${wrapped} environment(s); skipped ${skipped} you cannot decrypt`);
9966
9973
  });
9967
- recovery.command("rotate").description("rotate the recovery key (new keypair, custodians, and env re-wraps)").requiredOption("--threshold <M>", "custodians required to recover (M in M-of-N)").option("--custodian <email|skt_id>", "a recovery custodian (repeatable)", collect$8, []).option("--org <slug>", "organization slug (defaults to seekrit.json, or your only org)").action(async (options) => {
9974
+ recovery.command("rotate").description("rotate the recovery key (new keypair, custodians, and env re-wraps)").requiredOption("--threshold <M>", "custodians required to recover (M in M-of-N)").option("--custodian <email|skt_id>", "a recovery custodian (repeatable)", collect$9, []).option("--org <slug>", "organization slug (defaults to seekrit.json, or your only org)").action(async (options) => {
9968
9975
  const ctx = buildContext();
9969
9976
  const org = await resolveOrg(ctx, options.org);
9970
9977
  const config = await buildRecoveryConfig(ctx, org.id, options.threshold, options.custodian);
@@ -11103,7 +11110,7 @@ function formatSecrets(values, format) {
11103
11110
  * `buildContext()` in any of them silently breaks the promise the feature makes.
11104
11111
  */
11105
11112
  /** Collect a repeatable option into a list. */
11106
- function collect$7(value, acc = []) {
11113
+ function collect$8(value, acc = []) {
11107
11114
  acc.push(value);
11108
11115
  return acc;
11109
11116
  }
@@ -11380,7 +11387,7 @@ function registerArchiveCommands(program) {
11380
11387
  } catch {}
11381
11388
  fail("none of the recovery shares in this archive unwrap with that key");
11382
11389
  });
11383
- archive.command("decrypt <file>").description("decrypt an archive's secrets with your own key (offline)").option("-o, --out <dir>", "write one file per environment into this directory").option("--stdout", "print plaintext to stdout instead of writing files").option("--env <label>", "only this environment (app/env, group@env, slug, or id)").option("--format <format>", "dotenv | json | shell", "dotenv").option("--token <skt_…>", "decrypt as a service token instead of a passphrase").option("--key-file <path>", "decrypt with a private key JWK file").option("--share <file>", "custodian share for an offline quorum (repeatable)", collect$7).option("-y, --yes", "skip the confirmation when printing plaintext to stdout").action(async (file, options) => {
11390
+ archive.command("decrypt <file>").description("decrypt an archive's secrets with your own key (offline)").option("-o, --out <dir>", "write one file per environment into this directory").option("--stdout", "print plaintext to stdout instead of writing files").option("--env <label>", "only this environment (app/env, group@env, slug, or id)").option("--format <format>", "dotenv | json | shell", "dotenv").option("--token <skt_…>", "decrypt as a service token instead of a passphrase").option("--key-file <path>", "decrypt with a private key JWK file").option("--share <file>", "custodian share for an offline quorum (repeatable)", collect$8).option("-y, --yes", "skip the confirmation when printing plaintext to stdout").action(async (file, options) => {
11384
11391
  if (!options.out && !options.stdout) fail("choose a destination: --out <dir> to write files, or --stdout to print plaintext");
11385
11392
  if (![
11386
11393
  "dotenv",
@@ -13123,6 +13130,644 @@ function registerHoneyTokenCommands(program) {
13123
13130
  console.error(`${honeyTokenId} deleted`);
13124
13131
  });
13125
13132
  }
13133
+ // src/run-command.ts
13134
+ /** Keep signal handlers installed from provisioning through asynchronous cleanup. */
13135
+ async function runCommand(cmd, args, prepare, cleanup) {
13136
+ let child;
13137
+ let forwarded;
13138
+ let result = { code: 1 };
13139
+ const stragglers = /* @__PURE__ */ new Set();
13140
+ const collect = () => {
13141
+ if (process.platform === "win32" || !child?.pid) return;
13142
+ for (const pid of teardownTargets(child.pid)) stragglers.add(pid);
13143
+ };
13144
+ const forward = (signal) => {
13145
+ forwarded ??= signal;
13146
+ if (!child || child.exitCode !== null || child.signalCode !== null) return;
13147
+ collect();
13148
+ child.kill(signal);
13149
+ for (const pid of stragglers) try {
13150
+ process.kill(pid, signal);
13151
+ } catch {}
13152
+ };
13153
+ const signals = [
13154
+ "SIGINT",
13155
+ "SIGTERM",
13156
+ "SIGHUP",
13157
+ "SIGQUIT"
13158
+ ];
13159
+ for (const signal of signals) process.on(signal, forward);
13160
+ try {
13161
+ const env = await prepare(() => forwarded !== void 0);
13162
+ if (!forwarded) {
13163
+ const running = spawn(cmd, args, {
13164
+ stdio: "inherit",
13165
+ env
13166
+ });
13167
+ child = running;
13168
+ result = await new Promise((resolve, reject) => {
13169
+ running.once("exit", (code, signal) => resolve({
13170
+ code: code ?? 1,
13171
+ signal: signal ?? void 0
13172
+ }));
13173
+ running.once("error", (err) => reject(/* @__PURE__ */ new Error(`failed to start ${cmd}: ${err.message}`)));
13174
+ });
13175
+ }
13176
+ } finally {
13177
+ try {
13178
+ if (forwarded) {
13179
+ collect();
13180
+ await reapStragglers(stragglers, forwarded);
13181
+ }
13182
+ } finally {
13183
+ try {
13184
+ if (!await cleanup() && result.code === 0) result.code = 1;
13185
+ } finally {
13186
+ for (const signal of signals) process.off(signal, forward);
13187
+ }
13188
+ }
13189
+ }
13190
+ if (!child && forwarded) result.signal = forwarded;
13191
+ return result;
13192
+ }
13193
+ /**
13194
+ * Every live process `seekrit run` is responsible for tearing down, from a
13195
+ * single `ps(1)` snapshot: each descendant of `root`, plus — when we lead our
13196
+ * own process group — every other member of that group.
13197
+ *
13198
+ * Two mechanisms, because each covers the other's blind spot:
13199
+ *
13200
+ * - The parent-chain walk reaches a process that left our group via
13201
+ * setsid(2)/setpgid(2), which no group-wide kill and no tty-generated signal
13202
+ * can touch. But it loses anything whose chain up to `root` has already
13203
+ * broken — teardown kills the middle layers first, and an orphan reparents to
13204
+ * init, out of reach of any walk down from `root`.
13205
+ * - Group membership survives exactly that: a pgid outlives the parent that
13206
+ * passed it down. But it misses the ones that left the group.
13207
+ *
13208
+ * The group half applies only when our pid *is* our pgid, which is the shell-job
13209
+ * case: the shell put this command in a new group, so every other member of it
13210
+ * descends from us. Nested inside a shell script or a CI runner we are not the
13211
+ * leader and the group holds processes we did not start, so there we use the
13212
+ * walk alone.
13213
+ *
13214
+ * Zombies are skipped: they are already dead and waiting to be reaped, so
13215
+ * counting them would stall teardown for the full grace period and then report
13216
+ * a kill that did nothing. Returns nothing if `ps` is unavailable; callers fall
13217
+ * back to signalling the immediate child.
13218
+ */
13219
+ function teardownTargets(root) {
13220
+ const ps = spawnSync("ps", [
13221
+ "-A",
13222
+ "-o",
13223
+ "pid=,ppid=,pgid=,stat="
13224
+ ], { encoding: "utf8" });
13225
+ if (ps.status !== 0 || typeof ps.stdout !== "string") return [];
13226
+ const childrenOf = /* @__PURE__ */ new Map();
13227
+ const groupOf = /* @__PURE__ */ new Map();
13228
+ const isId = (value) => value !== void 0 && Number.isInteger(value);
13229
+ for (const line of ps.stdout.split("\n")) {
13230
+ const [pid, ppid, pgid, stat] = line.trim().split(/\s+/, 4);
13231
+ const [id, parent, group] = [
13232
+ pid,
13233
+ ppid,
13234
+ pgid
13235
+ ].map(Number);
13236
+ if (!isId(id) || !isId(parent) || !isId(group)) continue;
13237
+ if (stat?.startsWith("Z")) continue;
13238
+ const siblings = childrenOf.get(parent);
13239
+ if (siblings) siblings.push(id);
13240
+ else childrenOf.set(parent, [id]);
13241
+ groupOf.set(id, group);
13242
+ }
13243
+ const found = /* @__PURE__ */ new Set();
13244
+ const queue = [root];
13245
+ const seen = new Set(queue);
13246
+ for (let pid = queue.shift(); pid !== void 0; pid = queue.shift()) for (const kid of childrenOf.get(pid) ?? []) {
13247
+ if (seen.has(kid)) continue;
13248
+ seen.add(kid);
13249
+ found.add(kid);
13250
+ queue.push(kid);
13251
+ }
13252
+ if (groupOf.get(process.pid) === process.pid) {
13253
+ for (const [pid, group] of groupOf) if (group === process.pid) found.add(pid);
13254
+ }
13255
+ found.delete(process.pid);
13256
+ found.delete(root);
13257
+ return [...found];
13258
+ }
13259
+ /** Whether `pid` still exists — signal 0 tests reachability, delivers nothing. */
13260
+ function isAlive(pid) {
13261
+ try {
13262
+ process.kill(pid, 0);
13263
+ return true;
13264
+ } catch {
13265
+ return false;
13266
+ }
13267
+ }
13268
+ /** How long a straggler gets to finish shutting down before SIGKILL. */
13269
+ const STRAGGLER_GRACE_MS = 2e3;
13270
+ /**
13271
+ * Once the command has exited, make sure nothing it started outlives us.
13272
+ *
13273
+ * Anything still alive here has ignored the signal we forwarded *and* lost the
13274
+ * parent that launched it, and we are the last process that knows its pid:
13275
+ * the tty won't hang it up (it is no longer in the foreground group, and the
13276
+ * shell has moved on), so it survives until the machine reboots. That is how
13277
+ * `tsx` and the server under it stacked up for days.
13278
+ *
13279
+ * So escalate rather than trust. SIGTERM first — it costs no extra time and is
13280
+ * a rung the SIGINT-only handlers common in dev servers don't catch — then
13281
+ * SIGKILL whatever is left after the grace period. Nothing is killed unless it
13282
+ * was asked to stop first and declined, and this runs only when we forwarded a
13283
+ * termination signal: a command that exits on its own having deliberately left a
13284
+ * daemon behind keeps working.
13285
+ */
13286
+ async function reapStragglers(pids, signal) {
13287
+ let live = [...pids].filter(isAlive);
13288
+ if (live.length === 0) return;
13289
+ for (const pid of live) try {
13290
+ process.kill(pid, "SIGTERM");
13291
+ } catch {}
13292
+ const deadline = Date.now() + STRAGGLER_GRACE_MS;
13293
+ while (live.length > 0 && Date.now() < deadline) {
13294
+ await new Promise((resolve) => setTimeout(resolve, 50));
13295
+ live = live.filter(isAlive);
13296
+ }
13297
+ if (live.length === 0) return;
13298
+ console.error(`seekrit: force-killed ${live.length} leftover process(es) that ignored ${signal} and SIGTERM (${live.join(", ")})`);
13299
+ for (const pid of live) try {
13300
+ process.kill(pid, "SIGKILL");
13301
+ } catch {}
13302
+ }
13303
+ // src/identity.ts
13304
+ /**
13305
+ * `seekrit identity` — keyless access to AWS, Google Cloud, OpenAI and Anthropic
13306
+ * from a seekrit workload identity, the way a hosting platform's OIDC
13307
+ * integration works.
13308
+ *
13309
+ * The workload authenticates to seekrit (an enrolled P-256 key, or a platform
13310
+ * JWT it already has), asks for a short-lived identity token addressed to each
13311
+ * provider, and writes it to the token file that provider's own SDK already
13312
+ * knows how to read. The provider verifies the token against the org's issuer
13313
+ * (`https://oidc.seekrit.dev/<orgId>`) and its own trust policy, and mints its own short-lived
13314
+ * credential. No provider key is stored anywhere — not here, not in seekrit.
13315
+ *
13316
+ * Identity, not secrets: nothing on this path decrypts anything, and the API
13317
+ * signs these tokens with its own issuer key, so the zero-knowledge invariant is
13318
+ * untouched.
13319
+ */
13320
+ const DEFAULT_ISSUER = "https://api.seekrit.dev";
13321
+ const CLIENT_ASSERTION_TYPE = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
13322
+ const TOKEN_EXCHANGE_GRANT = "urn:ietf:params:oauth:grant-type:token-exchange";
13323
+ const JWT_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:jwt";
13324
+ function present(value) {
13325
+ return value?.trim() ? value.trim() : void 0;
13326
+ }
13327
+ function httpsOrigin(value, what) {
13328
+ let url;
13329
+ try {
13330
+ url = new URL(value);
13331
+ } catch {
13332
+ throw new Error(`${what} must be an HTTPS origin, got "${value}"`);
13333
+ }
13334
+ if (url.protocol !== "https:" || url.username || url.password || url.search || url.hash) throw new Error(`${what} must be an HTTPS origin, got "${value}"`);
13335
+ return url.origin;
13336
+ }
13337
+ /**
13338
+ * Where the workload's credential comes from: the file the dashboard downloads
13339
+ * at enrollment (`SEEKRIT_WORKLOAD_FILE`), or — for a platform-federated
13340
+ * workload — its id plus the platform token's path.
13341
+ */
13342
+ function loadWorkloadCredentials(opts, env = process.env) {
13343
+ const file = present(opts.workloadFile) ?? present(env.SEEKRIT_WORKLOAD_FILE);
13344
+ let fromFile = {};
13345
+ if (file) {
13346
+ let parsed;
13347
+ try {
13348
+ parsed = JSON.parse(readFileSync(file, "utf8"));
13349
+ } catch (err) {
13350
+ throw new Error(`cannot read workload credentials from ${file}: ${err instanceof Error ? err.message : String(err)}`);
13351
+ }
13352
+ if (!parsed || typeof parsed !== "object") throw new Error(`${file} is not a workload credential file`);
13353
+ fromFile = parsed;
13354
+ }
13355
+ const workloadId = present(opts.workloadId) ?? present(fromFile.workloadId) ?? present(env.SEEKRIT_WORKLOAD_ID);
13356
+ if (!workloadId) throw new Error("no workload identity: set SEEKRIT_WORKLOAD_FILE (or --workload-file) to the credentials downloaded at enrollment, or --workload-id with --platform-token-file");
13357
+ if (!/^wli_[A-Za-z0-9_-]{1,128}$/.test(workloadId)) throw new Error(`"${workloadId}" is not a workload id (expected wli_…)`);
13358
+ const issuer = httpsOrigin(present(opts.issuer) ?? present(fromFile.issuer) ?? present(env.SEEKRIT_ISSUER) ?? DEFAULT_ISSUER, "the seekrit issuer");
13359
+ const platformTokenFile = present(opts.platformTokenFile) ?? present(fromFile.platformTokenFile) ?? present(env.SEEKRIT_PLATFORM_TOKEN_FILE);
13360
+ const signingKey = fromFile.signingKey;
13361
+ if (!!signingKey === !!platformTokenFile) throw new Error(signingKey ? "the workload file holds an enrollment key; do not also pass a platform token" : "this workload needs an enrollment key (in its credential file) or --platform-token-file");
13362
+ if (signingKey && (signingKey.kty !== "EC" || signingKey.crv !== "P-256" || !signingKey.d || !signingKey.x)) throw new Error("the workload file's signingKey is not a private P-256 key");
13363
+ return {
13364
+ workloadId,
13365
+ issuer,
13366
+ signingKey,
13367
+ platformTokenFile
13368
+ };
13369
+ }
13370
+ function base64url(bytes) {
13371
+ return Buffer.from(bytes).toString("base64url");
13372
+ }
13373
+ /** A one-use, 60-second ES256 client assertion, the shape `/oauth/token` verifies. */
13374
+ async function signClientAssertion(creds, key, nowSeconds) {
13375
+ const unsigned = `${base64url(new TextEncoder().encode(JSON.stringify({
13376
+ alg: "ES256",
13377
+ typ: "JWT"
13378
+ })))}.${base64url(new TextEncoder().encode(JSON.stringify({
13379
+ iss: creds.workloadId,
13380
+ sub: creds.workloadId,
13381
+ aud: `${creds.issuer}/oauth/token`,
13382
+ iat: nowSeconds,
13383
+ exp: nowSeconds + 60,
13384
+ jti: crypto.randomUUID()
13385
+ })))}`;
13386
+ const signature = await crypto.subtle.sign({
13387
+ name: "ECDSA",
13388
+ hash: "SHA-256"
13389
+ }, key, new TextEncoder().encode(unsigned));
13390
+ return `${unsigned}.${base64url(new Uint8Array(signature))}`;
13391
+ }
13392
+ async function errorText(response) {
13393
+ try {
13394
+ const body = await response.json();
13395
+ if (body.error_description) return body.error_description;
13396
+ if (typeof body.error === "object" && body.error?.message) return body.error.message;
13397
+ if (typeof body.error === "string") return body.error;
13398
+ } catch {}
13399
+ return `HTTP ${response.status}`;
13400
+ }
13401
+ /** Session exchange + identity-token requests against one seekrit deployment. */
13402
+ var WorkloadClient = class {
13403
+ creds;
13404
+ fetcher;
13405
+ now;
13406
+ session;
13407
+ key;
13408
+ constructor(creds, fetcher = (input, init) => fetch(input, init), now = Date.now) {
13409
+ this.creds = creds;
13410
+ this.fetcher = fetcher;
13411
+ this.now = now;
13412
+ }
13413
+ signingKey() {
13414
+ this.key ??= crypto.subtle.importKey("jwk", this.creds.signingKey, {
13415
+ name: "ECDSA",
13416
+ namedCurve: "P-256"
13417
+ }, false, ["sign"]);
13418
+ return this.key;
13419
+ }
13420
+ async exchange() {
13421
+ const form = new URLSearchParams({
13422
+ client_id: this.creds.workloadId,
13423
+ scope: "connect"
13424
+ });
13425
+ if (this.creds.platformTokenFile) {
13426
+ const platformToken = readFileSync(this.creds.platformTokenFile, "utf8").trim();
13427
+ form.set("grant_type", TOKEN_EXCHANGE_GRANT);
13428
+ form.set("subject_token_type", JWT_TOKEN_TYPE);
13429
+ form.set("subject_token", platformToken);
13430
+ } else {
13431
+ form.set("grant_type", "client_credentials");
13432
+ form.set("client_assertion_type", CLIENT_ASSERTION_TYPE);
13433
+ form.set("client_assertion", await signClientAssertion(this.creds, await this.signingKey(), Math.floor(this.now() / 1e3)));
13434
+ }
13435
+ const response = await this.fetcher(`${this.creds.issuer}/oauth/token`, {
13436
+ method: "POST",
13437
+ headers: { "content-type": "application/x-www-form-urlencoded" },
13438
+ body: form
13439
+ });
13440
+ if (!response.ok) throw new Error(`workload sign-in failed: ${await errorText(response)}`);
13441
+ const body = await response.json();
13442
+ this.session = {
13443
+ token: body.access_token,
13444
+ expiresAt: this.now() + body.expires_in * 1e3
13445
+ };
13446
+ return body.access_token;
13447
+ }
13448
+ async accessToken() {
13449
+ if (this.session && this.session.expiresAt - 3e4 > this.now()) return this.session.token;
13450
+ return this.exchange();
13451
+ }
13452
+ /** An identity token for one enrolled audience. */
13453
+ async identityToken(audience) {
13454
+ for (let attempt = 0;; attempt++) {
13455
+ const response = await this.fetcher(`${this.creds.issuer}/v1/connect/identity-token`, {
13456
+ method: "POST",
13457
+ headers: {
13458
+ authorization: `Bearer ${await this.accessToken()}`,
13459
+ "content-type": "application/json"
13460
+ },
13461
+ body: JSON.stringify({ audience })
13462
+ });
13463
+ if (response.status === 401 && attempt === 0) {
13464
+ this.session = void 0;
13465
+ continue;
13466
+ }
13467
+ if (!response.ok) throw new Error(`identity token for "${audience}" refused: ${await errorText(response)}`);
13468
+ return await response.json();
13469
+ }
13470
+ }
13471
+ };
13472
+ /** The audience each provider's own docs use; any enrolled audience can override it. */
13473
+ const DEFAULT_AUDIENCES = {
13474
+ aws: "sts.amazonaws.com",
13475
+ openai: "https://api.openai.com/v1",
13476
+ anthropic: "https://api.anthropic.com"
13477
+ };
13478
+ /**
13479
+ * Credentials that outrank web identity in each provider's default chain. An
13480
+ * explicit `--aws`/`--anthropic`/… means "use the federated identity", so a
13481
+ * long-lived key left in the shell must not quietly win — the same rule as
13482
+ * `seekrit run --lease`.
13483
+ */
13484
+ const SHADOWING = {
13485
+ aws: [
13486
+ "AWS_ACCESS_KEY_ID",
13487
+ "AWS_SECRET_ACCESS_KEY",
13488
+ "AWS_SESSION_TOKEN",
13489
+ "AWS_PROFILE"
13490
+ ],
13491
+ gcp: [],
13492
+ openai: ["OPENAI_API_KEY"],
13493
+ anthropic: [
13494
+ "ANTHROPIC_API_KEY",
13495
+ "ANTHROPIC_AUTH_TOKEN",
13496
+ "ANTHROPIC_PROFILE",
13497
+ "ANTHROPIC_IDENTITY_TOKEN"
13498
+ ]
13499
+ };
13500
+ /** `projects/N/locations/global/workloadIdentityPools/P/providers/R`, from any of its spellings. */
13501
+ function normalizeGcpProvider(input) {
13502
+ const resource = input.trim().replace(/^https:\/\/iam\.googleapis\.com\//, "").replace(/^\/\/iam\.googleapis\.com\//, "");
13503
+ if (!/^projects\/\d+\/locations\/global\/workloadIdentityPools\/[a-z0-9-]{4,32}\/providers\/[a-z0-9-]{4,32}$/.test(resource)) throw new Error(`--gcp must name a workload identity pool provider by project number: projects/<number>/locations/global/workloadIdentityPools/<pool>/providers/<provider> (got "${input}")`);
13504
+ return resource;
13505
+ }
13506
+ function parseAudienceOverrides(values = []) {
13507
+ const out = {};
13508
+ for (const value of values) {
13509
+ const at = value.indexOf("=");
13510
+ const id = value.slice(0, at);
13511
+ const audience = value.slice(at + 1).trim();
13512
+ if (at < 1 || ![
13513
+ "aws",
13514
+ "gcp",
13515
+ "openai",
13516
+ "anthropic"
13517
+ ].includes(id) || !audience) throw new Error(`--audience takes provider=audience, e.g. anthropic=api.anthropic.com`);
13518
+ if (out[id]) throw new Error(`--audience given twice for ${id}`);
13519
+ out[id] = audience;
13520
+ }
13521
+ return out;
13522
+ }
13523
+ /**
13524
+ * What to write and export for each requested provider. Pure: paths are inside
13525
+ * `dir`, which the caller creates (mode 0700) and removes.
13526
+ */
13527
+ function planProviders(opts, dir, workloadId, env = process.env) {
13528
+ const audiences = parseAudienceOverrides(opts.audience);
13529
+ const plans = [];
13530
+ if (opts.aws !== void 0) {
13531
+ if (!/^arn:aws[a-z-]*:iam::\d{12}:role\/[\w+=,.@/-]+$/.test(opts.aws.trim())) throw new Error(`--aws must be an IAM role ARN, got "${opts.aws}"`);
13532
+ const tokenFile = join(dir, "aws-token");
13533
+ plans.push({
13534
+ id: "aws",
13535
+ audience: audiences.aws ?? DEFAULT_AUDIENCES.aws,
13536
+ tokenFile,
13537
+ env: {
13538
+ AWS_ROLE_ARN: opts.aws.trim(),
13539
+ AWS_WEB_IDENTITY_TOKEN_FILE: tokenFile,
13540
+ AWS_ROLE_SESSION_NAME: present(env.AWS_ROLE_SESSION_NAME) ?? `seekrit-${workloadId}`.slice(0, 64)
13541
+ },
13542
+ unset: SHADOWING.aws,
13543
+ files: []
13544
+ });
13545
+ }
13546
+ if (opts.gcp !== void 0) {
13547
+ const resource = normalizeGcpProvider(opts.gcp);
13548
+ const tokenFile = join(dir, "gcp-token");
13549
+ const configFile = join(dir, "gcp-credentials.json");
13550
+ const sa = present(opts.gcpServiceAccount);
13551
+ if (sa && !/^[a-z0-9-]+@[a-z0-9.-]+\.gserviceaccount\.com$/.test(sa)) throw new Error(`--gcp-service-account must be a service account email, got "${sa}"`);
13552
+ const config = {
13553
+ type: "external_account",
13554
+ audience: `//iam.googleapis.com/${resource}`,
13555
+ subject_token_type: JWT_TOKEN_TYPE,
13556
+ token_url: "https://sts.googleapis.com/v1/token",
13557
+ credential_source: {
13558
+ file: tokenFile,
13559
+ format: { type: "text" }
13560
+ },
13561
+ ...sa ? { service_account_impersonation_url: `https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${sa}:generateAccessToken` } : {}
13562
+ };
13563
+ plans.push({
13564
+ id: "gcp",
13565
+ audience: audiences.gcp ?? `https://iam.googleapis.com/${resource}`,
13566
+ tokenFile,
13567
+ env: {
13568
+ GOOGLE_APPLICATION_CREDENTIALS: configFile,
13569
+ CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE: configFile
13570
+ },
13571
+ unset: SHADOWING.gcp,
13572
+ files: [{
13573
+ path: configFile,
13574
+ content: `${JSON.stringify(config, null, 2)}\n`
13575
+ }]
13576
+ });
13577
+ } else if (opts.gcpServiceAccount) throw new Error("--gcp-service-account needs --gcp");
13578
+ if (opts.openai) {
13579
+ const tokenFile = join(dir, "openai-token");
13580
+ plans.push({
13581
+ id: "openai",
13582
+ audience: audiences.openai ?? DEFAULT_AUDIENCES.openai,
13583
+ tokenFile,
13584
+ env: { OPENAI_IDENTITY_TOKEN_FILE: tokenFile },
13585
+ unset: SHADOWING.openai,
13586
+ files: []
13587
+ });
13588
+ }
13589
+ if (opts.anthropic) {
13590
+ const tokenFile = join(dir, "anthropic-token");
13591
+ plans.push({
13592
+ id: "anthropic",
13593
+ audience: audiences.anthropic ?? DEFAULT_AUDIENCES.anthropic,
13594
+ tokenFile,
13595
+ env: { ANTHROPIC_IDENTITY_TOKEN_FILE: tokenFile },
13596
+ unset: SHADOWING.anthropic,
13597
+ files: []
13598
+ });
13599
+ }
13600
+ for (const id of Object.keys(audiences)) if (!plans.some((p) => p.id === id)) throw new Error(`--audience ${id}=… without --${id}`);
13601
+ if (plans.length === 0) throw new Error("name at least one provider: --aws <role-arn>, --gcp <provider>, --openai, --anthropic");
13602
+ return plans;
13603
+ }
13604
+ /**
13605
+ * The child's environment: shadowing credentials removed, provider variables
13606
+ * set. Returns the names it removed (never values) so the caller can say so.
13607
+ */
13608
+ function childEnvironment(base, plans) {
13609
+ const env = { ...base };
13610
+ const removed = [];
13611
+ for (const plan of plans) for (const name of plan.unset) if (env[name] !== void 0) {
13612
+ delete env[name];
13613
+ removed.push(name);
13614
+ }
13615
+ for (const plan of plans) Object.assign(env, plan.env);
13616
+ return {
13617
+ env,
13618
+ removed
13619
+ };
13620
+ }
13621
+ /** Variables a provider SDK needs from the operator before it will federate at all. */
13622
+ function missingProviderSettings(plans, env) {
13623
+ const missing = [];
13624
+ if (plans.some((p) => p.id === "anthropic")) {
13625
+ for (const name of ["ANTHROPIC_FEDERATION_RULE_ID", "ANTHROPIC_ORGANIZATION_ID"]) if (!present(env[name])) missing.push(name);
13626
+ }
13627
+ return missing;
13628
+ }
13629
+ /** Write-then-rename, so a reader never sees half a token. */
13630
+ function writeAtomic(path, content) {
13631
+ const tmp = `${path}.${crypto.randomUUID()}.tmp`;
13632
+ writeFileSync(tmp, content, { mode: 384 });
13633
+ renameSync(tmp, path);
13634
+ }
13635
+ /**
13636
+ * Keeps each provider's token file current. Refreshes at half the token's
13637
+ * lifetime, so a provider SDK rereading the file always finds a token with
13638
+ * plenty of life left — and, for Anthropic, which accepts each token's `jti`
13639
+ * only once, a fresh one by the time it next exchanges.
13640
+ */
13641
+ var TokenFileRefresher = class {
13642
+ client;
13643
+ plans;
13644
+ timers = /* @__PURE__ */ new Map();
13645
+ expiries = /* @__PURE__ */ new Map();
13646
+ stopped = false;
13647
+ log;
13648
+ minIntervalMs;
13649
+ setTimer;
13650
+ clearTimer;
13651
+ now;
13652
+ constructor(client, plans, opts = {}) {
13653
+ this.client = client;
13654
+ this.plans = plans;
13655
+ this.log = opts.log ?? ((m) => console.error(m));
13656
+ this.minIntervalMs = opts.minIntervalMs ?? 3e4;
13657
+ this.setTimer = opts.setTimer ?? ((fn, ms) => setTimeout(fn, ms));
13658
+ this.clearTimer = opts.clearTimer ?? ((t) => clearTimeout(t));
13659
+ this.now = opts.now ?? Date.now;
13660
+ }
13661
+ /** Fetch every token once. Throws if any provider's first token cannot be had. */
13662
+ async start() {
13663
+ for (const plan of this.plans) for (const file of plan.files) writeAtomic(file.path, file.content);
13664
+ await Promise.all(this.plans.map((plan) => this.refresh(plan, true)));
13665
+ }
13666
+ async refresh(plan, first = false) {
13667
+ if (this.stopped) return;
13668
+ try {
13669
+ const issued = await this.client.identityToken(plan.audience);
13670
+ if (this.stopped) return;
13671
+ writeAtomic(plan.tokenFile, issued.token);
13672
+ this.expiries.set(plan.id, this.now() + issued.expiresIn * 1e3);
13673
+ this.schedule(plan, Math.max(this.minIntervalMs, issued.expiresIn * 1e3 / 2));
13674
+ } catch (err) {
13675
+ if (first) throw err;
13676
+ const left = (this.expiries.get(plan.id) ?? 0) - this.now();
13677
+ this.log(`seekrit: could not refresh the ${plan.id} identity token (${err instanceof Error ? err.message : String(err)}); ${left > 0 ? `the current one is valid for ${Math.round(left / 1e3)}s more, retrying` : "the current one has expired, retrying"}`);
13678
+ this.schedule(plan, Math.min(this.minIntervalMs, Math.max(1e3, left / 4)));
13679
+ }
13680
+ }
13681
+ schedule(plan, ms) {
13682
+ if (this.stopped) return;
13683
+ const timer = this.setTimer(() => void this.refresh(plan), ms);
13684
+ timer.unref?.();
13685
+ this.timers.set(plan.id, timer);
13686
+ }
13687
+ stop() {
13688
+ this.stopped = true;
13689
+ for (const timer of this.timers.values()) this.clearTimer(timer);
13690
+ this.timers.clear();
13691
+ }
13692
+ };
13693
+ /**
13694
+ * Run `cmd` with provider token files kept fresh for as long as it lives. The
13695
+ * token directory is private (0700, files 0600) and removed afterwards.
13696
+ */
13697
+ async function runWithIdentity(cmd, args, client, opts) {
13698
+ const log = opts.log ?? ((m) => console.error(m));
13699
+ const dir = mkdtempSync(join(tmpdir(), "seekrit-identity-"));
13700
+ let refresher;
13701
+ try {
13702
+ const plans = planProviders(opts, dir, opts.workloadId);
13703
+ for (const name of missingProviderSettings(plans, process.env)) log(`seekrit: ${name} is not set; the provider SDK will not use the federated token without it`);
13704
+ return await runCommand(cmd, args, async () => {
13705
+ refresher = new TokenFileRefresher(client, plans, { log });
13706
+ await refresher.start();
13707
+ const { env, removed } = childEnvironment(process.env, plans);
13708
+ if (removed.length > 0) log(`seekrit: unset ${removed.join(", ")} for the command so the federated identity is used`);
13709
+ return env;
13710
+ }, async () => {
13711
+ refresher?.stop();
13712
+ rmSync(dir, {
13713
+ recursive: true,
13714
+ force: true
13715
+ });
13716
+ return true;
13717
+ });
13718
+ } catch (err) {
13719
+ rmSync(dir, {
13720
+ recursive: true,
13721
+ force: true
13722
+ });
13723
+ throw err;
13724
+ }
13725
+ }
13726
+ function collect$7(value, previous = []) {
13727
+ return [...previous, value];
13728
+ }
13729
+ function clientFrom(options) {
13730
+ try {
13731
+ const creds = loadWorkloadCredentials(options);
13732
+ return {
13733
+ client: new WorkloadClient(creds),
13734
+ workloadId: creds.workloadId
13735
+ };
13736
+ } catch (err) {
13737
+ fail(err instanceof Error ? err.message : String(err));
13738
+ }
13739
+ }
13740
+ function credentialFlags(command) {
13741
+ return command.option("--workload-file <path>", "credentials downloaded at enrollment (default: $SEEKRIT_WORKLOAD_FILE)").option("--workload-id <id>", "workload id, for a platform-federated workload").option("--platform-token-file <path>", "platform JWT to exchange, reread on every sign-in (default: $SEEKRIT_PLATFORM_TOKEN_FILE)").option("--issuer <origin>", `seekrit API origin (default: the credential file's, or ${DEFAULT_ISSUER})`);
13742
+ }
13743
+ function registerIdentityCommands(program) {
13744
+ const identity = program.command("identity").description("keyless AWS, Google Cloud, OpenAI and Anthropic access from a seekrit workload identity");
13745
+ credentialFlags(identity.command("token").description("print a signed identity token for one enrolled audience").requiredOption("--audience <aud>", "an audience enrolled on the workload").option("--json", "print {token, expiresIn, issuer, subject} instead of the bare token")).action(async (options) => {
13746
+ const { client } = clientFrom(options);
13747
+ try {
13748
+ const issued = await client.identityToken(options.audience);
13749
+ console.log(options.json ? JSON.stringify(issued, null, 2) : issued.token);
13750
+ } catch (err) {
13751
+ fail(err instanceof Error ? err.message : String(err));
13752
+ }
13753
+ });
13754
+ credentialFlags(identity.command("run").description("run a command with provider identity-token files kept fresh and the provider SDK variables set").passThroughOptions().option("--aws <role-arn>", "assume this IAM role via web identity").option("--gcp <provider>", "workload identity pool provider: projects/<number>/locations/global/workloadIdentityPools/<pool>/providers/<id>").option("--gcp-service-account <email>", "impersonate this service account after federating").option("--openai", "write OPENAI_IDENTITY_TOKEN_FILE").option("--anthropic", "write ANTHROPIC_IDENTITY_TOKEN_FILE").option("--audience <provider=aud>", "override a provider's default audience (repeatable)", collect$7).argument("<command...>", "command to run (prefix with -- to pass flags)")).action(async (commandParts, options) => {
13755
+ const [cmd, ...args] = commandParts;
13756
+ if (!cmd) fail("no command given");
13757
+ const { client, workloadId } = clientFrom(options);
13758
+ let result;
13759
+ try {
13760
+ result = await runWithIdentity(cmd, args, client, {
13761
+ ...options,
13762
+ workloadId
13763
+ });
13764
+ } catch (err) {
13765
+ fail(err instanceof Error ? err.message : String(err));
13766
+ }
13767
+ if (result.signal) process.kill(process.pid, result.signal);
13768
+ else process.exit(result.code);
13769
+ });
13770
+ }
13126
13771
  // src/m2m.ts
13127
13772
  /**
13128
13773
  * Resolve M2M client credentials from (in order) the process environment, a
@@ -16171,176 +16816,6 @@ function registerRotationCommands(program) {
16171
16816
  console.error(`disabled rotation of ${r.secretName}${rotatorRevoked ? " — rotator key access revoked for this environment" : ""}`);
16172
16817
  });
16173
16818
  }
16174
- // src/run-command.ts
16175
- /** Keep signal handlers installed from provisioning through asynchronous cleanup. */
16176
- async function runCommand(cmd, args, prepare, cleanup) {
16177
- let child;
16178
- let forwarded;
16179
- let result = { code: 1 };
16180
- const stragglers = /* @__PURE__ */ new Set();
16181
- const collect = () => {
16182
- if (process.platform === "win32" || !child?.pid) return;
16183
- for (const pid of teardownTargets(child.pid)) stragglers.add(pid);
16184
- };
16185
- const forward = (signal) => {
16186
- forwarded ??= signal;
16187
- if (!child || child.exitCode !== null || child.signalCode !== null) return;
16188
- collect();
16189
- child.kill(signal);
16190
- for (const pid of stragglers) try {
16191
- process.kill(pid, signal);
16192
- } catch {}
16193
- };
16194
- const signals = [
16195
- "SIGINT",
16196
- "SIGTERM",
16197
- "SIGHUP",
16198
- "SIGQUIT"
16199
- ];
16200
- for (const signal of signals) process.on(signal, forward);
16201
- try {
16202
- const env = await prepare(() => forwarded !== void 0);
16203
- if (!forwarded) {
16204
- const running = spawn(cmd, args, {
16205
- stdio: "inherit",
16206
- env
16207
- });
16208
- child = running;
16209
- result = await new Promise((resolve, reject) => {
16210
- running.once("exit", (code, signal) => resolve({
16211
- code: code ?? 1,
16212
- signal: signal ?? void 0
16213
- }));
16214
- running.once("error", (err) => reject(/* @__PURE__ */ new Error(`failed to start ${cmd}: ${err.message}`)));
16215
- });
16216
- }
16217
- } finally {
16218
- try {
16219
- if (forwarded) {
16220
- collect();
16221
- await reapStragglers(stragglers, forwarded);
16222
- }
16223
- } finally {
16224
- try {
16225
- if (!await cleanup() && result.code === 0) result.code = 1;
16226
- } finally {
16227
- for (const signal of signals) process.off(signal, forward);
16228
- }
16229
- }
16230
- }
16231
- if (!child && forwarded) result.signal = forwarded;
16232
- return result;
16233
- }
16234
- /**
16235
- * Every live process `seekrit run` is responsible for tearing down, from a
16236
- * single `ps(1)` snapshot: each descendant of `root`, plus — when we lead our
16237
- * own process group — every other member of that group.
16238
- *
16239
- * Two mechanisms, because each covers the other's blind spot:
16240
- *
16241
- * - The parent-chain walk reaches a process that left our group via
16242
- * setsid(2)/setpgid(2), which no group-wide kill and no tty-generated signal
16243
- * can touch. But it loses anything whose chain up to `root` has already
16244
- * broken — teardown kills the middle layers first, and an orphan reparents to
16245
- * init, out of reach of any walk down from `root`.
16246
- * - Group membership survives exactly that: a pgid outlives the parent that
16247
- * passed it down. But it misses the ones that left the group.
16248
- *
16249
- * The group half applies only when our pid *is* our pgid, which is the shell-job
16250
- * case: the shell put this command in a new group, so every other member of it
16251
- * descends from us. Nested inside a shell script or a CI runner we are not the
16252
- * leader and the group holds processes we did not start, so there we use the
16253
- * walk alone.
16254
- *
16255
- * Zombies are skipped: they are already dead and waiting to be reaped, so
16256
- * counting them would stall teardown for the full grace period and then report
16257
- * a kill that did nothing. Returns nothing if `ps` is unavailable; callers fall
16258
- * back to signalling the immediate child.
16259
- */
16260
- function teardownTargets(root) {
16261
- const ps = spawnSync("ps", [
16262
- "-A",
16263
- "-o",
16264
- "pid=,ppid=,pgid=,stat="
16265
- ], { encoding: "utf8" });
16266
- if (ps.status !== 0 || typeof ps.stdout !== "string") return [];
16267
- const childrenOf = /* @__PURE__ */ new Map();
16268
- const groupOf = /* @__PURE__ */ new Map();
16269
- const isId = (value) => value !== void 0 && Number.isInteger(value);
16270
- for (const line of ps.stdout.split("\n")) {
16271
- const [pid, ppid, pgid, stat] = line.trim().split(/\s+/, 4);
16272
- const [id, parent, group] = [
16273
- pid,
16274
- ppid,
16275
- pgid
16276
- ].map(Number);
16277
- if (!isId(id) || !isId(parent) || !isId(group)) continue;
16278
- if (stat?.startsWith("Z")) continue;
16279
- const siblings = childrenOf.get(parent);
16280
- if (siblings) siblings.push(id);
16281
- else childrenOf.set(parent, [id]);
16282
- groupOf.set(id, group);
16283
- }
16284
- const found = /* @__PURE__ */ new Set();
16285
- const queue = [root];
16286
- const seen = new Set(queue);
16287
- for (let pid = queue.shift(); pid !== void 0; pid = queue.shift()) for (const kid of childrenOf.get(pid) ?? []) {
16288
- if (seen.has(kid)) continue;
16289
- seen.add(kid);
16290
- found.add(kid);
16291
- queue.push(kid);
16292
- }
16293
- if (groupOf.get(process.pid) === process.pid) {
16294
- for (const [pid, group] of groupOf) if (group === process.pid) found.add(pid);
16295
- }
16296
- found.delete(process.pid);
16297
- found.delete(root);
16298
- return [...found];
16299
- }
16300
- /** Whether `pid` still exists — signal 0 tests reachability, delivers nothing. */
16301
- function isAlive(pid) {
16302
- try {
16303
- process.kill(pid, 0);
16304
- return true;
16305
- } catch {
16306
- return false;
16307
- }
16308
- }
16309
- /** How long a straggler gets to finish shutting down before SIGKILL. */
16310
- const STRAGGLER_GRACE_MS = 2e3;
16311
- /**
16312
- * Once the command has exited, make sure nothing it started outlives us.
16313
- *
16314
- * Anything still alive here has ignored the signal we forwarded *and* lost the
16315
- * parent that launched it, and we are the last process that knows its pid:
16316
- * the tty won't hang it up (it is no longer in the foreground group, and the
16317
- * shell has moved on), so it survives until the machine reboots. That is how
16318
- * `tsx` and the server under it stacked up for days.
16319
- *
16320
- * So escalate rather than trust. SIGTERM first — it costs no extra time and is
16321
- * a rung the SIGINT-only handlers common in dev servers don't catch — then
16322
- * SIGKILL whatever is left after the grace period. Nothing is killed unless it
16323
- * was asked to stop first and declined, and this runs only when we forwarded a
16324
- * termination signal: a command that exits on its own having deliberately left a
16325
- * daemon behind keeps working.
16326
- */
16327
- async function reapStragglers(pids, signal) {
16328
- let live = [...pids].filter(isAlive);
16329
- if (live.length === 0) return;
16330
- for (const pid of live) try {
16331
- process.kill(pid, "SIGTERM");
16332
- } catch {}
16333
- const deadline = Date.now() + STRAGGLER_GRACE_MS;
16334
- while (live.length > 0 && Date.now() < deadline) {
16335
- await new Promise((resolve) => setTimeout(resolve, 50));
16336
- live = live.filter(isAlive);
16337
- }
16338
- if (live.length === 0) return;
16339
- console.error(`seekrit: force-killed ${live.length} leftover process(es) that ignored ${signal} and SIGTERM (${live.join(", ")})`);
16340
- for (const pid of live) try {
16341
- process.kill(pid, "SIGKILL");
16342
- } catch {}
16343
- }
16344
16819
  // src/run-leases.ts
16345
16820
  /** Validate all flags before contacting the API or creating any database roles. */
16346
16821
  function parseRunLeaseOptions(bindings = [], ttl) {
@@ -18000,6 +18475,7 @@ registerHermesCommands(program);
18000
18475
  registerSshCommands(program);
18001
18476
  registerAwsCommands(program);
18002
18477
  registerGcpCommands(program);
18478
+ registerIdentityCommands(program);
18003
18479
  registerMongoCommands(program);
18004
18480
  registerKmsCommands(program);
18005
18481
  registerRotationCommands(program);