@keystrokehq/hosting 0.1.13 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -4369,12 +4369,34 @@ function superRefine(fn, params) {
4369
4369
  return /* @__PURE__ */ _superRefine(fn, params);
4370
4370
  }
4371
4371
  //#endregion
4372
+ //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/compat.js
4373
+ /** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
4374
+ const ZodIssueCode = {
4375
+ invalid_type: "invalid_type",
4376
+ too_big: "too_big",
4377
+ too_small: "too_small",
4378
+ invalid_format: "invalid_format",
4379
+ not_multiple_of: "not_multiple_of",
4380
+ unrecognized_keys: "unrecognized_keys",
4381
+ invalid_union: "invalid_union",
4382
+ invalid_key: "invalid_key",
4383
+ invalid_element: "invalid_element",
4384
+ invalid_value: "invalid_value",
4385
+ custom: "custom"
4386
+ };
4387
+ /** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
4388
+ var ZodFirstPartyTypeKind;
4389
+ (function(ZodFirstPartyTypeKind) {})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
4390
+ //#endregion
4372
4391
  //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/coerce.js
4373
4392
  function number(params) {
4374
4393
  return /* @__PURE__ */ _coercedNumber(ZodNumber, params);
4375
4394
  }
4376
- //#endregion
4377
- //#region ../shared/dist/index.mjs
4395
+ new Set([
4396
+ "hello",
4397
+ "greeting",
4398
+ "greet"
4399
+ ]);
4378
4400
  /** Auth, session, and account-entry URL segments. */
4379
4401
  const AUTH_ACCOUNT_SLUGS = [
4380
4402
  "2fa",
@@ -4486,6 +4508,7 @@ const PRODUCT_SLUGS = [
4486
4508
  "execution",
4487
4509
  "executions",
4488
4510
  "explore",
4511
+ "forms",
4489
4512
  "get-started",
4490
4513
  "history",
4491
4514
  "inbox",
@@ -5305,7 +5328,9 @@ const storedRouteManifestEntryV2Schema = discriminatedUnion("kind", [
5305
5328
  appSlugs: array(string()).default([]),
5306
5329
  toolSlugs: array(string()).default([]),
5307
5330
  /** Credential requirements per tool slug (the agent's credential consumer key). */
5308
- toolRequirements: record(string(), array(CredentialRequirementSummarySchema)).optional()
5331
+ toolRequirements: record(string(), array(CredentialRequirementSummarySchema)).optional(),
5332
+ /** Credential requirements for the agent's VM sandbox env / git bootstrap. */
5333
+ sandboxRequirements: array(CredentialRequirementSummarySchema).optional()
5309
5334
  }),
5310
5335
  object({
5311
5336
  kind: literal("action"),
@@ -5353,6 +5378,8 @@ const storedRouteManifestEntryV2Schema = discriminatedUnion("kind", [
5353
5378
  moduleFile: string(),
5354
5379
  sourceHash: string().optional(),
5355
5380
  schedule: string(),
5381
+ /** IANA timezone for schedule wall-clock fields. When omitted, UTC. */
5382
+ timezone: string().optional(),
5356
5383
  name: requiredDisplayTextSchema,
5357
5384
  description: requiredDisplayTextSchema
5358
5385
  }),
@@ -5361,7 +5388,9 @@ const storedRouteManifestEntryV2Schema = discriminatedUnion("kind", [
5361
5388
  pollId: string(),
5362
5389
  attachmentIds: array(string()),
5363
5390
  moduleFile: string(),
5364
- schedule: string()
5391
+ schedule: string(),
5392
+ /** IANA timezone for schedule wall-clock fields. When omitted, UTC. */
5393
+ timezone: string().optional()
5365
5394
  }),
5366
5395
  object({
5367
5396
  kind: literal("cron-schedule"),
@@ -5370,6 +5399,8 @@ const storedRouteManifestEntryV2Schema = discriminatedUnion("kind", [
5370
5399
  moduleFile: string(),
5371
5400
  sourceHash: string().optional(),
5372
5401
  schedule: string(),
5402
+ /** IANA timezone for schedule wall-clock fields. When omitted, UTC. */
5403
+ timezone: string().optional(),
5373
5404
  /** Static cron payload from `defineCronSource({ payload })` — omitted when the source has none. */
5374
5405
  payload: unknown().optional(),
5375
5406
  name: requiredDisplayTextSchema,
@@ -5414,6 +5445,8 @@ const AutoTopupSummarySchema = object({
5414
5445
  const PlanLimitsSchema = object({
5415
5446
  includedStorageGb: number$1(),
5416
5447
  concurrencyLimit: number$1(),
5448
+ /** Max non-deleted projects; enforced on create only. */
5449
+ maxProjects: number$1(),
5417
5450
  agentTimeoutMs: number$1(),
5418
5451
  workflowTimeoutMs: number$1(),
5419
5452
  pollTimeoutMs: number$1(),
@@ -5427,8 +5460,15 @@ const PlanLimitsSchema = object({
5427
5460
  object({
5428
5461
  planKey: string(),
5429
5462
  subscriptionStatus: subscriptionStatusSchema,
5463
+ /** Remaining plan-bucket balance this period (µc). */
5430
5464
  planCreditMicroCredits: number$1(),
5465
+ /** Remaining prepaid balance (µc). Never expires. */
5431
5466
  prepaidCreditMicroCredits: number$1(),
5467
+ /**
5468
+ * Resolved monthly plan allotment (µc) — override ?? preset. Powers the
5469
+ * credit-usage progress denominator (`used = allotment − remaining`).
5470
+ */
5471
+ monthlyCreditMicroCredits: number$1(),
5432
5472
  periodStart: isoDateTime$6.nullable(),
5433
5473
  periodEnd: isoDateTime$6.nullable(),
5434
5474
  autoTopup: AutoTopupSummarySchema,
@@ -5671,7 +5711,8 @@ object({
5671
5711
  });
5672
5712
  const NewChannelBindingInputSchema = object({
5673
5713
  channelId: string().min(1),
5674
- channelName: string().min(1),
5714
+ /** Display name. When omitted or equal to `channelId`, the server resolves it from Slack. */
5715
+ channelName: string().min(1).optional(),
5675
5716
  channelKind: ChannelBindingKindSchema.optional(),
5676
5717
  mode: ChannelListenModeSchema.optional(),
5677
5718
  subscribeOnMention: boolean().optional()
@@ -5733,12 +5774,13 @@ const AppAuthKindSchema = _enum([
5733
5774
  "api_key",
5734
5775
  "keystroke"
5735
5776
  ]);
5736
- /** Composio auth scheme for API-key style connections. */
5777
+ /** Composio auth scheme for API-key / no-auth style connections. */
5737
5778
  const AppCredentialSchemeSchema = _enum([
5738
5779
  "API_KEY",
5739
5780
  "BEARER_TOKEN",
5740
5781
  "BASIC",
5741
- "BASIC_WITH_JWT"
5782
+ "BASIC_WITH_JWT",
5783
+ "NO_AUTH"
5742
5784
  ]);
5743
5785
  /**
5744
5786
  * Where app metadata and execution are sourced (e.g. native, composio, pipedream, custom).
@@ -5780,6 +5822,7 @@ object({
5780
5822
  "graphql"
5781
5823
  ]).default("custom"),
5782
5824
  url: string().url().optional(),
5825
+ logo: string().url().optional(),
5783
5826
  authKind: AppAuthKindSchema.optional(),
5784
5827
  fields: optionalCredentialFieldsSchema.optional(),
5785
5828
  credentialScheme: AppCredentialSchemeSchema.optional(),
@@ -5815,6 +5858,7 @@ object({
5815
5858
  authKind: AppAuthKindSchema,
5816
5859
  source: AppSourceSchema,
5817
5860
  url: string().url().nullable().optional(),
5861
+ logo: string().url().nullable().optional(),
5818
5862
  credentialFields: optionalCredentialFieldsSchema.optional(),
5819
5863
  credentialScheme: AppCredentialSchemeSchema.optional(),
5820
5864
  oauthScopes: array(OAuthScopeOptionSchema).optional(),
@@ -5851,12 +5895,14 @@ object({
5851
5895
  /** Endpoint URL for MCP, OpenAPI, or GraphQL custom apps. */
5852
5896
  url: string().url().nullable().optional(),
5853
5897
  /** True when the app has a non-empty credential field template. */
5854
- hasCredentialFields: boolean().optional()
5898
+ hasCredentialFields: boolean().optional(),
5899
+ /** Composio auth scheme — present for API-key and NO_AUTH apps so the picker can choose a flow. */
5900
+ credentialScheme: AppCredentialSchemeSchema.optional()
5855
5901
  }).extend({
5856
5902
  oauthScopes: array(OAuthScopeOptionSchema),
5857
5903
  /** Custom api_key apps — vault field template for connect UI and sync. */
5858
5904
  credentialFields: AppCredentialFieldsSchema.optional(),
5859
- /** Composio auth scheme when credentialFields are present. */
5905
+ /** Composio auth scheme for API-key or NO_AUTH connections. */
5860
5906
  credentialScheme: AppCredentialSchemeSchema.optional(),
5861
5907
  /** When present, the app supports agent gateway bindings (external channels). */
5862
5908
  gateway: AppGatewaySchema.optional()
@@ -5973,8 +6019,12 @@ const AppCredentialScopeSchema = _enum([
5973
6019
  "project",
5974
6020
  "organization"
5975
6021
  ]);
5976
- /** How the credential was connected (OAuth vs manual api-key entry). */
5977
- const AppCredentialConnectionKindSchema = _enum(["oauth", "manual"]);
6022
+ /** How the credential was connected (OAuth, manual api-key entry, or no-auth). */
6023
+ const AppCredentialConnectionKindSchema = _enum([
6024
+ "oauth",
6025
+ "manual",
6026
+ "none"
6027
+ ]);
5978
6028
  /** Connect-dialog permission preset for OAuth scope selection. */
5979
6029
  const OAuthPermissionModeSchema = _enum(["default", "restricted"]);
5980
6030
  const optionalTimestamp$1 = string().optional();
@@ -6068,12 +6118,39 @@ CredentialTargetsFieldsSchema.extend({
6068
6118
  message: "OAuth credentials are created via the OAuth callback",
6069
6119
  path: ["connectionKind"]
6070
6120
  });
6121
+ if (input.connectionKind === "none" && input.value) ctx.addIssue({
6122
+ code: "custom",
6123
+ message: "value is not allowed for no-auth connections",
6124
+ path: ["value"]
6125
+ });
6071
6126
  });
6072
6127
  object({
6073
6128
  label: string().trim().min(1).optional(),
6074
6129
  isDefault: boolean().optional(),
6075
- value: credentialSecretValueSchema.optional()
6076
- }).refine((input) => input.label !== void 0 || input.isDefault !== void 0 || input.value !== void 0, { message: "At least one field is required" });
6130
+ value: credentialSecretValueSchema.optional(),
6131
+ /** Move this credential to a different scope in place. */
6132
+ scope: AppCredentialScopeSchema.optional(),
6133
+ /** Required when `scope` is `project`. */
6134
+ projectSlug: string().trim().min(1).optional()
6135
+ }).superRefine((input, ctx) => {
6136
+ if (!(input.label !== void 0 || input.isDefault !== void 0 || input.value !== void 0 || input.scope !== void 0)) ctx.addIssue({
6137
+ code: "custom",
6138
+ message: "At least one field is required"
6139
+ });
6140
+ if (input.scope === "project" && !input.projectSlug) ctx.addIssue({
6141
+ code: "custom",
6142
+ message: "projectSlug is required when scope is project",
6143
+ path: ["projectSlug"]
6144
+ });
6145
+ if (input.scope !== "project" && input.projectSlug !== void 0) ctx.addIssue({
6146
+ code: "custom",
6147
+ message: "projectSlug is only valid when scope is project",
6148
+ path: ["projectSlug"]
6149
+ });
6150
+ });
6151
+ CredentialTargetsFieldsSchema.omit({ credentialInstanceId: true }).superRefine((input, ctx) => {
6152
+ if (!hasCredentialTarget(input)) addMissingCredentialTargetIssue(ctx);
6153
+ });
6077
6154
  object({
6078
6155
  limit: number().int().min(1).max(200).optional(),
6079
6156
  cursor: string().min(1).optional()
@@ -6175,11 +6252,61 @@ object({
6175
6252
  "org-deletion",
6176
6253
  "contact",
6177
6254
  "enterprise-upgrade",
6178
- "verification"
6255
+ "verification",
6256
+ "slack-connect",
6257
+ "connector-access"
6179
6258
  ]),
6180
- message: string().trim().max(5e3).optional()
6259
+ message: string().trim().max(5e3).optional(),
6260
+ /** Required for connector-access requests (sandbox VM secret exposure). */
6261
+ appSlug: string().trim().min(1).optional()
6262
+ }).superRefine((value, ctx) => {
6263
+ if (value.type === "connector-access" && !value.appSlug) ctx.addIssue({
6264
+ code: ZodIssueCode.custom,
6265
+ path: ["appSlug"],
6266
+ message: "appSlug is required for connector-access requests"
6267
+ });
6181
6268
  });
6182
6269
  object({ ok: literal(true) });
6270
+ object({
6271
+ message: string().trim().min(1).max(1e4),
6272
+ cliVersion: string().trim().min(1).max(64).optional(),
6273
+ projectSlug: string().trim().min(1).max(128).optional()
6274
+ });
6275
+ object({ ok: literal(true) });
6276
+ const TemplateKindSchema = _enum([
6277
+ "agent",
6278
+ "workflow",
6279
+ "both"
6280
+ ]);
6281
+ object({
6282
+ kind: TemplateKindSchema,
6283
+ title: string().min(1),
6284
+ description: string().min(1),
6285
+ tags: array(string().min(1)).default([]),
6286
+ requiredApps: array(string().min(1)).default([])
6287
+ });
6288
+ object({
6289
+ slug: string().min(1),
6290
+ kind: TemplateKindSchema,
6291
+ title: string().min(1),
6292
+ description: string().min(1),
6293
+ tags: array(string()),
6294
+ requiredApps: array(string()),
6295
+ updatedAt: string().datetime()
6296
+ }).extend({ files: record(string(), string()) });
6297
+ object({
6298
+ slug: string().min(1),
6299
+ files: record(string(), string())
6300
+ });
6301
+ object({
6302
+ slug: string().min(1),
6303
+ kind: TemplateKindSchema,
6304
+ title: string().min(1),
6305
+ description: string().min(1),
6306
+ tags: array(string()).default([]),
6307
+ requiredApps: array(string()).default([]),
6308
+ files: record(string(), string())
6309
+ });
6183
6310
  const MarketingContactCompanySizeSchema = _enum([
6184
6311
  "1-10",
6185
6312
  "11-50",
@@ -6196,6 +6323,46 @@ object({
6196
6323
  companyWebsite: string().optional()
6197
6324
  });
6198
6325
  object({ models: array(string()) });
6326
+ object({ accessToken: string() });
6327
+ const CredentialAccessUnavailableReasonSchema = _enum(["request_access", "reconnect_required"]);
6328
+ object({
6329
+ error: literal("credential_access_unavailable"),
6330
+ code: literal("credential_access_unavailable"),
6331
+ appSlug: string().min(1),
6332
+ reason: CredentialAccessUnavailableReasonSchema,
6333
+ requestAccessUrl: string().url().optional(),
6334
+ message: string().optional()
6335
+ });
6336
+ discriminatedUnion("kind", [
6337
+ object({
6338
+ kind: literal("api_key"),
6339
+ instanceId: string().min(1)
6340
+ }),
6341
+ object({
6342
+ kind: literal("oauth"),
6343
+ connectionId: string().min(1)
6344
+ }),
6345
+ object({
6346
+ kind: literal("keystroke"),
6347
+ instanceId: string().min(1),
6348
+ connectionId: string().min(1),
6349
+ appSlug: string().min(1)
6350
+ })
6351
+ ]);
6352
+ discriminatedUnion("kind", [
6353
+ object({
6354
+ kind: literal("api_key"),
6355
+ value: unknown()
6356
+ }),
6357
+ object({
6358
+ kind: literal("oauth"),
6359
+ accessToken: string().min(1)
6360
+ }),
6361
+ object({
6362
+ kind: literal("keystroke"),
6363
+ value: unknown()
6364
+ })
6365
+ ]);
6199
6366
  const ValidationErrorDetailSchema = object({
6200
6367
  path: string(),
6201
6368
  message: string()
@@ -6204,7 +6371,14 @@ const ValidationErrorDetailSchema = object({
6204
6371
  const ErrorResponseCodeSchema = OrganizationSlugErrorCodeSchema.or(_enum([
6205
6372
  "needs_org_selection",
6206
6373
  "org_unverified",
6207
- "connector_unavailable"
6374
+ "connector_unavailable",
6375
+ "invalid_url",
6376
+ "url_not_allowed",
6377
+ "url_unreachable",
6378
+ "upstream_http_error",
6379
+ "spec_too_large",
6380
+ "spec_parse_error",
6381
+ "invalid_openapi"
6208
6382
  ]));
6209
6383
  object({
6210
6384
  error: string(),
@@ -6241,6 +6415,12 @@ const ChatAttachmentInputSchema = object({
6241
6415
  mediaType: string().min(1),
6242
6416
  filename: string().optional()
6243
6417
  });
6418
+ object({
6419
+ type: literal("file"),
6420
+ mediaType: string().min(1),
6421
+ url: string().min(1),
6422
+ filename: string().optional()
6423
+ });
6244
6424
  object({
6245
6425
  contentType: string().min(1),
6246
6426
  filename: string().min(1),
@@ -6321,12 +6501,7 @@ object({
6321
6501
  params: array(unknown()).default([]),
6322
6502
  method: string().min(1).optional()
6323
6503
  });
6324
- object({ migrations: array(object({
6325
- sql: array(string().min(1)),
6326
- hash: string().min(1),
6327
- folderMillis: number$1()
6328
- })) });
6329
- object({ results: array(object({ rows: array(unknown()) })) });
6504
+ object({ rows: array(unknown()) });
6330
6505
  const RunSourceKindSchema = _enum([
6331
6506
  "api",
6332
6507
  "trigger",
@@ -6356,6 +6531,10 @@ object({
6356
6531
  description: string().nullable().optional(),
6357
6532
  type: AgentTriggerTypeSchema,
6358
6533
  schedule: string().nullable(),
6534
+ /** IANA timezone for schedule wall-clock fields. Null when omitted (evaluates in UTC). */
6535
+ timezone: string().nullable(),
6536
+ /** ISO timestamptz of the next scheduled fire. Null for webhooks / unset. */
6537
+ nextRunAt: string().nullable(),
6359
6538
  endpoint: string().nullable(),
6360
6539
  origin: AgentTriggerOriginSchema,
6361
6540
  prompt: string().nullable(),
@@ -6512,6 +6691,26 @@ const HistoryAgentCompactionEventSchema = object({
6512
6691
  retainedTailEstimate: number$1().optional(),
6513
6692
  durable: boolean()
6514
6693
  });
6694
+ /** Compact abnormal prompt-finish diagnostics from `agent_end` (optional on older events). */
6695
+ const HistoryAgentPromptFinishEventSchema = object({
6696
+ seq: number$1(),
6697
+ createdAt: string(),
6698
+ promptId: string().optional(),
6699
+ outcome: _enum([
6700
+ "completed",
6701
+ "error",
6702
+ "aborted"
6703
+ ]),
6704
+ finishReason: string().nullable(),
6705
+ rawFinishReason: string().optional(),
6706
+ stepCount: number$1(),
6707
+ maxSteps: number$1(),
6708
+ hitStepLimit: boolean(),
6709
+ error: object({
6710
+ name: string().optional(),
6711
+ message: string()
6712
+ }).optional()
6713
+ });
6515
6714
  const HistoryRunDetailSchema = discriminatedUnion("kind", [HistoryWorkflowRunDetailSchema, object({
6516
6715
  kind: literal("agent"),
6517
6716
  runId: string(),
@@ -6539,6 +6738,8 @@ const HistoryRunDetailSchema = discriminatedUnion("kind", [HistoryWorkflowRunDet
6539
6738
  messages: array(record(string(), unknown())),
6540
6739
  /** Sanitized context-compaction markers for the conversation timeline. */
6541
6740
  compactionEvents: array(HistoryAgentCompactionEventSchema).default([]),
6741
+ /** Abnormal prompt-finish diagnostics from `agent_end` (missing on historical events). */
6742
+ promptFinishEvents: array(HistoryAgentPromptFinishEventSchema).default([]),
6542
6743
  trace: HistoryTraceSchema.nullable(),
6543
6744
  ranAs: HistoryRunActorSchema.nullable().optional(),
6544
6745
  usage: HistoryRunUsageSchema.nullable().optional()
@@ -6783,6 +6984,7 @@ object({
6783
6984
  * log. Defaulted so older servers remain compatible.
6784
6985
  */
6785
6986
  compactionEvents: array(HistoryAgentCompactionEventSchema).default([]),
6987
+ promptFinishEvents: array(HistoryAgentPromptFinishEventSchema).default([]),
6786
6988
  trace: TraceResponseSchema.nullable()
6787
6989
  });
6788
6990
  const SlackGatewayModeSchema = _enum([
@@ -7037,6 +7239,10 @@ object({
7037
7239
  webhookUrl: string().nullable(),
7038
7240
  /** Cron expression or poll cadence label (cron/poll triggers only). */
7039
7241
  schedule: string().nullable(),
7242
+ /** IANA timezone for schedule wall-clock fields. Null when omitted (evaluates in UTC). */
7243
+ timezone: string().nullable(),
7244
+ /** ISO timestamptz of the next scheduled fire. Null for webhooks / unset. */
7245
+ nextRunAt: string().nullable(),
7040
7246
  /** Workflows + agents currently bound to this source. */
7041
7247
  assignments: array(TriggerAssignmentSchema),
7042
7248
  lastFiredAt: string().nullable(),
@@ -7077,6 +7283,8 @@ const TriggerOverviewInputSchema = object({
7077
7283
  description: string().nullable(),
7078
7284
  type: TriggerTypeSchema,
7079
7285
  schedule: string().nullable(),
7286
+ /** IANA timezone for schedule wall-clock fields. Null/omitted → UTC. */
7287
+ timezone: string().nullable().optional(),
7080
7288
  sourcePath: string(),
7081
7289
  sourceContents: string(),
7082
7290
  assignments: array(TriggerAssignmentSchema)
@@ -7262,6 +7470,13 @@ object({
7262
7470
  uploadUrl: url(),
7263
7471
  storageKey: string().min(1)
7264
7472
  });
7473
+ object({ contentType: string().trim().min(1) });
7474
+ object({
7475
+ uploadUrl: url(),
7476
+ storageKey: string().min(1)
7477
+ });
7478
+ object({ storageKey: string().min(1) });
7479
+ object({ logo: url() });
7265
7480
  const UserInterfaceThemeSchema = _enum([
7266
7481
  "system",
7267
7482
  "light",
@@ -7442,90 +7657,6 @@ object({
7442
7657
  lastOpenedAt: string().min(1),
7443
7658
  lastModifiedAt: string().min(1)
7444
7659
  });
7445
- const isoDateTime = string().datetime();
7446
- const sha256Hex = string().regex(/^[a-f0-9]{64}$/, "Expected a lowercase hex sha256 digest");
7447
- /**
7448
- * A single entry in a deploy's file tree, as served to the dashboard. Carries
7449
- * no contents: `id` is a stable, path-derived handle used for selection and
7450
- * `?file=` deep links; `hash` is the content address used to fetch the bytes
7451
- * lazily and to cache them immutably in the browser.
7452
- */
7453
- const ProjectFileSummarySchema = object({
7454
- id: string(),
7455
- path: string().min(1),
7456
- hash: sha256Hex
7457
- });
7458
- /** Maps a runtime resource slug (agent/workflow/skill) to its source file path. */
7459
- const ProjectSourceResourceRefSchema = object({
7460
- slug: string().min(1),
7461
- path: string().min(1)
7462
- });
7463
- const ProjectSourceResourcesSchema = object({
7464
- agents: array(ProjectSourceResourceRefSchema).default([]),
7465
- workflows: array(ProjectSourceResourceRefSchema).default([]),
7466
- skills: array(ProjectSourceResourceRefSchema).default([])
7467
- });
7468
- const emptyResources = () => ({
7469
- agents: [],
7470
- workflows: [],
7471
- skills: []
7472
- });
7473
- object({
7474
- artifactId: string().nullable(),
7475
- files: array(ProjectFileSummarySchema),
7476
- resources: ProjectSourceResourcesSchema.default(emptyResources())
7477
- });
7478
- object({
7479
- path: string().min(1),
7480
- contents: string(),
7481
- hash: sha256Hex
7482
- });
7483
- object({ blobs: array(object({
7484
- hash: sha256Hex,
7485
- size: number$1().int().nonnegative()
7486
- })) });
7487
- object({ uploads: array(object({
7488
- hash: sha256Hex,
7489
- url: string().url()
7490
- })) });
7491
- object({ files: array(object({
7492
- path: string().min(1),
7493
- hash: sha256Hex
7494
- })) });
7495
- object({
7496
- ok: literal(true),
7497
- fileCount: number$1().int().nonnegative()
7498
- });
7499
- object({
7500
- files: array(object({
7501
- id: string(),
7502
- path: string().min(1),
7503
- hash: sha256Hex
7504
- })),
7505
- generatedAt: isoDateTime
7506
- });
7507
- /** A single source file returned by the bulk active-source download endpoint. */
7508
- const DownloadActiveProjectSourceFileSchema = object({
7509
- path: string().min(1),
7510
- contents: string()
7511
- });
7512
- object({
7513
- artifactId: string(),
7514
- files: array(DownloadActiveProjectSourceFileSchema)
7515
- });
7516
- object({
7517
- projectId: string(),
7518
- artifactId: string(),
7519
- pulledAt: string().datetime()
7520
- });
7521
- object({ files: array(object({
7522
- id: string(),
7523
- path: string().min(1)
7524
- })) });
7525
- object({ files: array(object({
7526
- id: string(),
7527
- path: string().min(1)
7528
- })) });
7529
7660
  /** Whether the overview is still being produced or finished. */
7530
7661
  const WorkflowOverviewStatusSchema = _enum(["generating", "ready"]);
7531
7662
  /** One phase of the guided-tour overview. */
@@ -7550,7 +7681,8 @@ const WorkflowInputFieldTypeSchema = _enum([
7550
7681
  "boolean",
7551
7682
  "enum",
7552
7683
  "object",
7553
- "array"
7684
+ "array",
7685
+ "file"
7554
7686
  ]);
7555
7687
  const WorkflowInputFieldSchema = lazy(() => object({
7556
7688
  key: string(),
@@ -7565,6 +7697,8 @@ const WorkflowInputFieldSchema = lazy(() => object({
7565
7697
  number$1(),
7566
7698
  boolean()
7567
7699
  ]).optional(),
7700
+ minimum: number$1().optional(),
7701
+ maximum: number$1().optional(),
7568
7702
  children: array(WorkflowInputFieldSchema).optional(),
7569
7703
  format: string().optional()
7570
7704
  }));
@@ -7764,6 +7898,159 @@ const WorkflowCanvasCredentialBindingSchema = union([
7764
7898
  })
7765
7899
  ]);
7766
7900
  record(string(), array(WorkflowCanvasCredentialBindingSchema));
7901
+ const FormControlSchema = _enum([
7902
+ "input",
7903
+ "textarea",
7904
+ "select",
7905
+ "radio",
7906
+ "stepper",
7907
+ "slider",
7908
+ "checkbox",
7909
+ "switch"
7910
+ ]);
7911
+ const FormFieldConfigEntrySchema = object({
7912
+ label: string().trim().min(1).max(120).optional(),
7913
+ helpText: string().trim().min(1).max(300).optional(),
7914
+ placeholder: string().trim().min(1).max(200).optional(),
7915
+ control: FormControlSchema.optional()
7916
+ });
7917
+ const FormFieldConfigSchema = record(string(), FormFieldConfigEntrySchema);
7918
+ const PublicFormFieldSchema = WorkflowInputFieldSchema.and(object({
7919
+ control: FormControlSchema.optional(),
7920
+ helpText: string().optional()
7921
+ }));
7922
+ const PublishedFormSchema = object({
7923
+ id: string().min(1),
7924
+ workflowId: string().min(1),
7925
+ workflowSlug: string().min(1),
7926
+ enabled: boolean(),
7927
+ title: string().min(1).nullable(),
7928
+ description: string().min(1).nullable(),
7929
+ fieldConfig: FormFieldConfigSchema,
7930
+ publicUrl: string().url(),
7931
+ createdAt: string().min(1),
7932
+ updatedAt: string().min(1)
7933
+ });
7934
+ object({
7935
+ id: string().min(1),
7936
+ projectId: string().min(1),
7937
+ workflowSlug: string().min(1),
7938
+ enabled: boolean(),
7939
+ title: string().min(1).nullable(),
7940
+ description: string().min(1).nullable(),
7941
+ fieldConfig: FormFieldConfigSchema,
7942
+ publicUrl: string().url(),
7943
+ createdAt: string().min(1),
7944
+ updatedAt: string().min(1)
7945
+ });
7946
+ PublishedFormSchema.nullable();
7947
+ object({
7948
+ enabled: boolean().optional(),
7949
+ title: string().trim().min(1).max(120).nullable().optional(),
7950
+ description: string().trim().min(1).max(500).nullable().optional(),
7951
+ fieldConfig: FormFieldConfigSchema.optional()
7952
+ });
7953
+ object({
7954
+ title: string().min(1),
7955
+ description: string().nullable(),
7956
+ fields: array(PublicFormFieldSchema),
7957
+ branding: object({
7958
+ organizationName: string().min(1),
7959
+ projectName: string().min(1),
7960
+ logoLightUrl: string().url().nullable(),
7961
+ logoDarkUrl: string().url().nullable(),
7962
+ logoHeightPx: number$1().int().positive()
7963
+ })
7964
+ });
7965
+ object({
7966
+ values: record(string(), unknown()),
7967
+ website: string().max(200).optional()
7968
+ });
7969
+ object({ ok: literal(true) });
7970
+ const isoDateTime = string().datetime();
7971
+ const sha256Hex = string().regex(/^[a-f0-9]{64}$/, "Expected a lowercase hex sha256 digest");
7972
+ /**
7973
+ * A single entry in a deploy's file tree, as served to the dashboard. Carries
7974
+ * no contents: `id` is a stable, path-derived handle used for selection and
7975
+ * `?file=` deep links; `hash` is the content address used to fetch the bytes
7976
+ * lazily and to cache them immutably in the browser.
7977
+ */
7978
+ const ProjectFileSummarySchema = object({
7979
+ id: string(),
7980
+ path: string().min(1),
7981
+ hash: sha256Hex
7982
+ });
7983
+ /** Maps a runtime resource slug (agent/workflow/skill) to its source file path. */
7984
+ const ProjectSourceResourceRefSchema = object({
7985
+ slug: string().min(1),
7986
+ path: string().min(1)
7987
+ });
7988
+ const ProjectSourceResourcesSchema = object({
7989
+ agents: array(ProjectSourceResourceRefSchema).default([]),
7990
+ workflows: array(ProjectSourceResourceRefSchema).default([]),
7991
+ skills: array(ProjectSourceResourceRefSchema).default([])
7992
+ });
7993
+ const emptyResources = () => ({
7994
+ agents: [],
7995
+ workflows: [],
7996
+ skills: []
7997
+ });
7998
+ object({
7999
+ artifactId: string().nullable(),
8000
+ files: array(ProjectFileSummarySchema),
8001
+ resources: ProjectSourceResourcesSchema.default(emptyResources())
8002
+ });
8003
+ object({
8004
+ path: string().min(1),
8005
+ contents: string(),
8006
+ hash: sha256Hex
8007
+ });
8008
+ object({ blobs: array(object({
8009
+ hash: sha256Hex,
8010
+ size: number$1().int().nonnegative()
8011
+ })) });
8012
+ object({ uploads: array(object({
8013
+ hash: sha256Hex,
8014
+ url: string().url()
8015
+ })) });
8016
+ object({ files: array(object({
8017
+ path: string().min(1),
8018
+ hash: sha256Hex
8019
+ })) });
8020
+ object({
8021
+ ok: literal(true),
8022
+ fileCount: number$1().int().nonnegative()
8023
+ });
8024
+ object({
8025
+ files: array(object({
8026
+ id: string(),
8027
+ path: string().min(1),
8028
+ hash: sha256Hex
8029
+ })),
8030
+ generatedAt: isoDateTime
8031
+ });
8032
+ /** A single source file returned by the bulk active-source download endpoint. */
8033
+ const DownloadActiveProjectSourceFileSchema = object({
8034
+ path: string().min(1),
8035
+ contents: string()
8036
+ });
8037
+ object({
8038
+ artifactId: string(),
8039
+ files: array(DownloadActiveProjectSourceFileSchema)
8040
+ });
8041
+ object({
8042
+ projectId: string(),
8043
+ artifactId: string(),
8044
+ pulledAt: string().datetime()
8045
+ });
8046
+ object({ files: array(object({
8047
+ id: string(),
8048
+ path: string().min(1)
8049
+ })) });
8050
+ object({ files: array(object({
8051
+ id: string(),
8052
+ path: string().min(1)
8053
+ })) });
7767
8054
  record(string(), unknown());
7768
8055
  //#endregion
7769
8056
  //#region src/runtime.ts
@@ -7777,7 +8064,7 @@ function parseOrgArtifactsFromEnv(env = process.env) {
7777
8064
  const parsed = JSON.parse(Buffer.from(raw, "base64").toString("utf8"));
7778
8065
  if (!Array.isArray(parsed)) throw new Error("KEYSTROKE_ORG_ARTIFACTS must decode to a JSON array");
7779
8066
  return parsed.map((entry) => {
7780
- if (!entry || typeof entry !== "object" || typeof entry.projectId !== "string" || typeof entry.artifactStorageKey !== "string") throw new Error("KEYSTROKE_ORG_ARTIFACTS entries require projectId and artifactStorageKey");
8067
+ if (!entry || typeof entry !== "object" || typeof entry.projectId !== "string" || typeof entry.artifactStorageKey !== "string" || typeof entry.artifactId !== "string" || typeof entry.artifactVersion !== "number") throw new Error("KEYSTROKE_ORG_ARTIFACTS entries require projectId, artifactStorageKey, artifactId, and artifactVersion");
7781
8068
  return entry;
7782
8069
  });
7783
8070
  }
@@ -7815,10 +8102,22 @@ const RUNTIME_ENV_KEYS = [
7815
8102
  "REDIS_URL",
7816
8103
  "KEYSTROKE_QUEUE_PREFIX"
7817
8104
  ];
8105
+ /**
8106
+ * Observability ingest config for org workers (PostHog error tracking + crash reports).
8107
+ * Ingest tokens only — never forward `POSTHOG_API_KEY` (management) into workers.
8108
+ */
8109
+ const OBSERVABILITY_ENV_KEYS = [
8110
+ "POSTHOG_PROJECT_TOKEN",
8111
+ "POSTHOG_HOST",
8112
+ "POSTHOG_FLUSH_MODE",
8113
+ "KEYSTROKE_ENVIRONMENT",
8114
+ "KEYSTROKE_RELEASE"
8115
+ ];
7818
8116
  /** Env keys that must never be forwarded into untrusted org workers. */
7819
8117
  const FORBIDDEN_WORKER_ENV_KEYS = [
7820
8118
  "BETTER_AUTH_SECRET",
7821
8119
  "DATABASE_URL",
8120
+ "POSTHOG_API_KEY",
7822
8121
  "POSTGRES_PASSWORD",
7823
8122
  "PLATFORM_WORKER_TOKEN",
7824
8123
  "STRIPE_SECRET_KEY",
@@ -7862,6 +8161,11 @@ function buildRuntimeEnv(source, artifacts, database, extraEnv) {
7862
8161
  if (!value) continue;
7863
8162
  entries.set(key, value);
7864
8163
  }
8164
+ for (const key of OBSERVABILITY_ENV_KEYS) {
8165
+ const value = source[key]?.trim();
8166
+ if (!value) continue;
8167
+ entries.set(key, value);
8168
+ }
7865
8169
  if (!extraEnv) for (const key of PROVIDER_ENV_KEYS) {
7866
8170
  const value = source[key]?.trim();
7867
8171
  if (value) entries.set(key, value);
@@ -7962,7 +8266,9 @@ function createDockerRuntime(options = {}) {
7962
8266
  if (input.projects.length === 0) throw new Error("Docker org runtime requires at least one project deploy");
7963
8267
  let launch = resolveRuntimeLaunch(options, input.projects.map((project) => ({
7964
8268
  projectId: project.projectId,
7965
- artifactStorageKey: project.artifactStorageKey
8269
+ artifactStorageKey: project.artifactStorageKey,
8270
+ artifactId: project.artifactId,
8271
+ artifactVersion: project.artifactVersion
7966
8272
  })), input.database, input.env);
7967
8273
  if (options.workspacesMount) {
7968
8274
  const { hostPath, containerPath } = options.workspacesMount;