@keystrokehq/hosting 0.1.12 → 0.1.14

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
@@ -4373,8 +4373,11 @@ function superRefine(fn, params) {
4373
4373
  function number(params) {
4374
4374
  return /* @__PURE__ */ _coercedNumber(ZodNumber, params);
4375
4375
  }
4376
- //#endregion
4377
- //#region ../shared/dist/index.mjs
4376
+ new Set([
4377
+ "hello",
4378
+ "greeting",
4379
+ "greet"
4380
+ ]);
4378
4381
  /** Auth, session, and account-entry URL segments. */
4379
4382
  const AUTH_ACCOUNT_SLUGS = [
4380
4383
  "2fa",
@@ -4486,6 +4489,7 @@ const PRODUCT_SLUGS = [
4486
4489
  "execution",
4487
4490
  "executions",
4488
4491
  "explore",
4492
+ "forms",
4489
4493
  "get-started",
4490
4494
  "history",
4491
4495
  "inbox",
@@ -5353,6 +5357,8 @@ const storedRouteManifestEntryV2Schema = discriminatedUnion("kind", [
5353
5357
  moduleFile: string(),
5354
5358
  sourceHash: string().optional(),
5355
5359
  schedule: string(),
5360
+ /** IANA timezone for schedule wall-clock fields. When omitted, UTC. */
5361
+ timezone: string().optional(),
5356
5362
  name: requiredDisplayTextSchema,
5357
5363
  description: requiredDisplayTextSchema
5358
5364
  }),
@@ -5361,7 +5367,9 @@ const storedRouteManifestEntryV2Schema = discriminatedUnion("kind", [
5361
5367
  pollId: string(),
5362
5368
  attachmentIds: array(string()),
5363
5369
  moduleFile: string(),
5364
- schedule: string()
5370
+ schedule: string(),
5371
+ /** IANA timezone for schedule wall-clock fields. When omitted, UTC. */
5372
+ timezone: string().optional()
5365
5373
  }),
5366
5374
  object({
5367
5375
  kind: literal("cron-schedule"),
@@ -5370,6 +5378,8 @@ const storedRouteManifestEntryV2Schema = discriminatedUnion("kind", [
5370
5378
  moduleFile: string(),
5371
5379
  sourceHash: string().optional(),
5372
5380
  schedule: string(),
5381
+ /** IANA timezone for schedule wall-clock fields. When omitted, UTC. */
5382
+ timezone: string().optional(),
5373
5383
  /** Static cron payload from `defineCronSource({ payload })` — omitted when the source has none. */
5374
5384
  payload: unknown().optional(),
5375
5385
  name: requiredDisplayTextSchema,
@@ -5414,6 +5424,8 @@ const AutoTopupSummarySchema = object({
5414
5424
  const PlanLimitsSchema = object({
5415
5425
  includedStorageGb: number$1(),
5416
5426
  concurrencyLimit: number$1(),
5427
+ /** Max non-deleted projects; enforced on create only. */
5428
+ maxProjects: number$1(),
5417
5429
  agentTimeoutMs: number$1(),
5418
5430
  workflowTimeoutMs: number$1(),
5419
5431
  pollTimeoutMs: number$1(),
@@ -5427,8 +5439,15 @@ const PlanLimitsSchema = object({
5427
5439
  object({
5428
5440
  planKey: string(),
5429
5441
  subscriptionStatus: subscriptionStatusSchema,
5442
+ /** Remaining plan-bucket balance this period (µc). */
5430
5443
  planCreditMicroCredits: number$1(),
5444
+ /** Remaining prepaid balance (µc). Never expires. */
5431
5445
  prepaidCreditMicroCredits: number$1(),
5446
+ /**
5447
+ * Resolved monthly plan allotment (µc) — override ?? preset. Powers the
5448
+ * credit-usage progress denominator (`used = allotment − remaining`).
5449
+ */
5450
+ monthlyCreditMicroCredits: number$1(),
5432
5451
  periodStart: isoDateTime$6.nullable(),
5433
5452
  periodEnd: isoDateTime$6.nullable(),
5434
5453
  autoTopup: AutoTopupSummarySchema,
@@ -5671,7 +5690,8 @@ object({
5671
5690
  });
5672
5691
  const NewChannelBindingInputSchema = object({
5673
5692
  channelId: string().min(1),
5674
- channelName: string().min(1),
5693
+ /** Display name. When omitted or equal to `channelId`, the server resolves it from Slack. */
5694
+ channelName: string().min(1).optional(),
5675
5695
  channelKind: ChannelBindingKindSchema.optional(),
5676
5696
  mode: ChannelListenModeSchema.optional(),
5677
5697
  subscribeOnMention: boolean().optional()
@@ -5733,12 +5753,13 @@ const AppAuthKindSchema = _enum([
5733
5753
  "api_key",
5734
5754
  "keystroke"
5735
5755
  ]);
5736
- /** Composio auth scheme for API-key style connections. */
5756
+ /** Composio auth scheme for API-key / no-auth style connections. */
5737
5757
  const AppCredentialSchemeSchema = _enum([
5738
5758
  "API_KEY",
5739
5759
  "BEARER_TOKEN",
5740
5760
  "BASIC",
5741
- "BASIC_WITH_JWT"
5761
+ "BASIC_WITH_JWT",
5762
+ "NO_AUTH"
5742
5763
  ]);
5743
5764
  /**
5744
5765
  * Where app metadata and execution are sourced (e.g. native, composio, pipedream, custom).
@@ -5780,6 +5801,7 @@ object({
5780
5801
  "graphql"
5781
5802
  ]).default("custom"),
5782
5803
  url: string().url().optional(),
5804
+ logo: string().url().optional(),
5783
5805
  authKind: AppAuthKindSchema.optional(),
5784
5806
  fields: optionalCredentialFieldsSchema.optional(),
5785
5807
  credentialScheme: AppCredentialSchemeSchema.optional(),
@@ -5815,6 +5837,7 @@ object({
5815
5837
  authKind: AppAuthKindSchema,
5816
5838
  source: AppSourceSchema,
5817
5839
  url: string().url().nullable().optional(),
5840
+ logo: string().url().nullable().optional(),
5818
5841
  credentialFields: optionalCredentialFieldsSchema.optional(),
5819
5842
  credentialScheme: AppCredentialSchemeSchema.optional(),
5820
5843
  oauthScopes: array(OAuthScopeOptionSchema).optional(),
@@ -5851,12 +5874,14 @@ object({
5851
5874
  /** Endpoint URL for MCP, OpenAPI, or GraphQL custom apps. */
5852
5875
  url: string().url().nullable().optional(),
5853
5876
  /** True when the app has a non-empty credential field template. */
5854
- hasCredentialFields: boolean().optional()
5877
+ hasCredentialFields: boolean().optional(),
5878
+ /** Composio auth scheme — present for API-key and NO_AUTH apps so the picker can choose a flow. */
5879
+ credentialScheme: AppCredentialSchemeSchema.optional()
5855
5880
  }).extend({
5856
5881
  oauthScopes: array(OAuthScopeOptionSchema),
5857
5882
  /** Custom api_key apps — vault field template for connect UI and sync. */
5858
5883
  credentialFields: AppCredentialFieldsSchema.optional(),
5859
- /** Composio auth scheme when credentialFields are present. */
5884
+ /** Composio auth scheme for API-key or NO_AUTH connections. */
5860
5885
  credentialScheme: AppCredentialSchemeSchema.optional(),
5861
5886
  /** When present, the app supports agent gateway bindings (external channels). */
5862
5887
  gateway: AppGatewaySchema.optional()
@@ -5973,8 +5998,12 @@ const AppCredentialScopeSchema = _enum([
5973
5998
  "project",
5974
5999
  "organization"
5975
6000
  ]);
5976
- /** How the credential was connected (OAuth vs manual api-key entry). */
5977
- const AppCredentialConnectionKindSchema = _enum(["oauth", "manual"]);
6001
+ /** How the credential was connected (OAuth, manual api-key entry, or no-auth). */
6002
+ const AppCredentialConnectionKindSchema = _enum([
6003
+ "oauth",
6004
+ "manual",
6005
+ "none"
6006
+ ]);
5978
6007
  /** Connect-dialog permission preset for OAuth scope selection. */
5979
6008
  const OAuthPermissionModeSchema = _enum(["default", "restricted"]);
5980
6009
  const optionalTimestamp$1 = string().optional();
@@ -6068,12 +6097,39 @@ CredentialTargetsFieldsSchema.extend({
6068
6097
  message: "OAuth credentials are created via the OAuth callback",
6069
6098
  path: ["connectionKind"]
6070
6099
  });
6100
+ if (input.connectionKind === "none" && input.value) ctx.addIssue({
6101
+ code: "custom",
6102
+ message: "value is not allowed for no-auth connections",
6103
+ path: ["value"]
6104
+ });
6071
6105
  });
6072
6106
  object({
6073
6107
  label: string().trim().min(1).optional(),
6074
6108
  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" });
6109
+ value: credentialSecretValueSchema.optional(),
6110
+ /** Move this credential to a different scope in place. */
6111
+ scope: AppCredentialScopeSchema.optional(),
6112
+ /** Required when `scope` is `project`. */
6113
+ projectSlug: string().trim().min(1).optional()
6114
+ }).superRefine((input, ctx) => {
6115
+ if (!(input.label !== void 0 || input.isDefault !== void 0 || input.value !== void 0 || input.scope !== void 0)) ctx.addIssue({
6116
+ code: "custom",
6117
+ message: "At least one field is required"
6118
+ });
6119
+ if (input.scope === "project" && !input.projectSlug) ctx.addIssue({
6120
+ code: "custom",
6121
+ message: "projectSlug is required when scope is project",
6122
+ path: ["projectSlug"]
6123
+ });
6124
+ if (input.scope !== "project" && input.projectSlug !== void 0) ctx.addIssue({
6125
+ code: "custom",
6126
+ message: "projectSlug is only valid when scope is project",
6127
+ path: ["projectSlug"]
6128
+ });
6129
+ });
6130
+ CredentialTargetsFieldsSchema.omit({ credentialInstanceId: true }).superRefine((input, ctx) => {
6131
+ if (!hasCredentialTarget(input)) addMissingCredentialTargetIssue(ctx);
6132
+ });
6077
6133
  object({
6078
6134
  limit: number().int().min(1).max(200).optional(),
6079
6135
  cursor: string().min(1).optional()
@@ -6175,11 +6231,46 @@ object({
6175
6231
  "org-deletion",
6176
6232
  "contact",
6177
6233
  "enterprise-upgrade",
6178
- "verification"
6234
+ "verification",
6235
+ "slack-connect"
6179
6236
  ]),
6180
6237
  message: string().trim().max(5e3).optional()
6181
6238
  });
6182
6239
  object({ ok: literal(true) });
6240
+ const TemplateKindSchema = _enum([
6241
+ "agent",
6242
+ "workflow",
6243
+ "both"
6244
+ ]);
6245
+ object({
6246
+ kind: TemplateKindSchema,
6247
+ title: string().min(1),
6248
+ description: string().min(1),
6249
+ tags: array(string().min(1)).default([]),
6250
+ requiredApps: array(string().min(1)).default([])
6251
+ });
6252
+ object({
6253
+ slug: string().min(1),
6254
+ kind: TemplateKindSchema,
6255
+ title: string().min(1),
6256
+ description: string().min(1),
6257
+ tags: array(string()),
6258
+ requiredApps: array(string()),
6259
+ updatedAt: string().datetime()
6260
+ }).extend({ files: record(string(), string()) });
6261
+ object({
6262
+ slug: string().min(1),
6263
+ files: record(string(), string())
6264
+ });
6265
+ object({
6266
+ slug: string().min(1),
6267
+ kind: TemplateKindSchema,
6268
+ title: string().min(1),
6269
+ description: string().min(1),
6270
+ tags: array(string()).default([]),
6271
+ requiredApps: array(string()).default([]),
6272
+ files: record(string(), string())
6273
+ });
6183
6274
  const MarketingContactCompanySizeSchema = _enum([
6184
6275
  "1-10",
6185
6276
  "11-50",
@@ -6204,7 +6295,14 @@ const ValidationErrorDetailSchema = object({
6204
6295
  const ErrorResponseCodeSchema = OrganizationSlugErrorCodeSchema.or(_enum([
6205
6296
  "needs_org_selection",
6206
6297
  "org_unverified",
6207
- "connector_unavailable"
6298
+ "connector_unavailable",
6299
+ "invalid_url",
6300
+ "url_not_allowed",
6301
+ "url_unreachable",
6302
+ "upstream_http_error",
6303
+ "spec_too_large",
6304
+ "spec_parse_error",
6305
+ "invalid_openapi"
6208
6306
  ]));
6209
6307
  object({
6210
6308
  error: string(),
@@ -6241,6 +6339,12 @@ const ChatAttachmentInputSchema = object({
6241
6339
  mediaType: string().min(1),
6242
6340
  filename: string().optional()
6243
6341
  });
6342
+ object({
6343
+ type: literal("file"),
6344
+ mediaType: string().min(1),
6345
+ url: string().min(1),
6346
+ filename: string().optional()
6347
+ });
6244
6348
  object({
6245
6349
  contentType: string().min(1),
6246
6350
  filename: string().min(1),
@@ -6321,12 +6425,7 @@ object({
6321
6425
  params: array(unknown()).default([]),
6322
6426
  method: string().min(1).optional()
6323
6427
  });
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()) })) });
6428
+ object({ rows: array(unknown()) });
6330
6429
  const RunSourceKindSchema = _enum([
6331
6430
  "api",
6332
6431
  "trigger",
@@ -6356,6 +6455,10 @@ object({
6356
6455
  description: string().nullable().optional(),
6357
6456
  type: AgentTriggerTypeSchema,
6358
6457
  schedule: string().nullable(),
6458
+ /** IANA timezone for schedule wall-clock fields. Null when omitted (evaluates in UTC). */
6459
+ timezone: string().nullable(),
6460
+ /** ISO timestamptz of the next scheduled fire. Null for webhooks / unset. */
6461
+ nextRunAt: string().nullable(),
6359
6462
  endpoint: string().nullable(),
6360
6463
  origin: AgentTriggerOriginSchema,
6361
6464
  prompt: string().nullable(),
@@ -6371,6 +6474,7 @@ const HistoryRunStatusSchema = _enum([
6371
6474
  "running",
6372
6475
  "sleeping",
6373
6476
  "waiting_hook",
6477
+ "waiting_children",
6374
6478
  "completed",
6375
6479
  "failed",
6376
6480
  "canceled"
@@ -6511,6 +6615,26 @@ const HistoryAgentCompactionEventSchema = object({
6511
6615
  retainedTailEstimate: number$1().optional(),
6512
6616
  durable: boolean()
6513
6617
  });
6618
+ /** Compact abnormal prompt-finish diagnostics from `agent_end` (optional on older events). */
6619
+ const HistoryAgentPromptFinishEventSchema = object({
6620
+ seq: number$1(),
6621
+ createdAt: string(),
6622
+ promptId: string().optional(),
6623
+ outcome: _enum([
6624
+ "completed",
6625
+ "error",
6626
+ "aborted"
6627
+ ]),
6628
+ finishReason: string().nullable(),
6629
+ rawFinishReason: string().optional(),
6630
+ stepCount: number$1(),
6631
+ maxSteps: number$1(),
6632
+ hitStepLimit: boolean(),
6633
+ error: object({
6634
+ name: string().optional(),
6635
+ message: string()
6636
+ }).optional()
6637
+ });
6514
6638
  const HistoryRunDetailSchema = discriminatedUnion("kind", [HistoryWorkflowRunDetailSchema, object({
6515
6639
  kind: literal("agent"),
6516
6640
  runId: string(),
@@ -6538,6 +6662,8 @@ const HistoryRunDetailSchema = discriminatedUnion("kind", [HistoryWorkflowRunDet
6538
6662
  messages: array(record(string(), unknown())),
6539
6663
  /** Sanitized context-compaction markers for the conversation timeline. */
6540
6664
  compactionEvents: array(HistoryAgentCompactionEventSchema).default([]),
6665
+ /** Abnormal prompt-finish diagnostics from `agent_end` (missing on historical events). */
6666
+ promptFinishEvents: array(HistoryAgentPromptFinishEventSchema).default([]),
6541
6667
  trace: HistoryTraceSchema.nullable(),
6542
6668
  ranAs: HistoryRunActorSchema.nullable().optional(),
6543
6669
  usage: HistoryRunUsageSchema.nullable().optional()
@@ -6555,6 +6681,7 @@ const WorkflowRunStatusSchema = _enum([
6555
6681
  "running",
6556
6682
  "sleeping",
6557
6683
  "waiting_hook",
6684
+ "waiting_children",
6558
6685
  "completed",
6559
6686
  "failed",
6560
6687
  "canceled"
@@ -6575,6 +6702,7 @@ _enum([
6575
6702
  "sleep_completed",
6576
6703
  "hook_created",
6577
6704
  "hook_resumed",
6705
+ "child_dispatched",
6578
6706
  "run_completed",
6579
6707
  "run_failed",
6580
6708
  "run_canceled"
@@ -6780,6 +6908,7 @@ object({
6780
6908
  * log. Defaulted so older servers remain compatible.
6781
6909
  */
6782
6910
  compactionEvents: array(HistoryAgentCompactionEventSchema).default([]),
6911
+ promptFinishEvents: array(HistoryAgentPromptFinishEventSchema).default([]),
6783
6912
  trace: TraceResponseSchema.nullable()
6784
6913
  });
6785
6914
  const SlackGatewayModeSchema = _enum([
@@ -7034,6 +7163,10 @@ object({
7034
7163
  webhookUrl: string().nullable(),
7035
7164
  /** Cron expression or poll cadence label (cron/poll triggers only). */
7036
7165
  schedule: string().nullable(),
7166
+ /** IANA timezone for schedule wall-clock fields. Null when omitted (evaluates in UTC). */
7167
+ timezone: string().nullable(),
7168
+ /** ISO timestamptz of the next scheduled fire. Null for webhooks / unset. */
7169
+ nextRunAt: string().nullable(),
7037
7170
  /** Workflows + agents currently bound to this source. */
7038
7171
  assignments: array(TriggerAssignmentSchema),
7039
7172
  lastFiredAt: string().nullable(),
@@ -7074,6 +7207,8 @@ const TriggerOverviewInputSchema = object({
7074
7207
  description: string().nullable(),
7075
7208
  type: TriggerTypeSchema,
7076
7209
  schedule: string().nullable(),
7210
+ /** IANA timezone for schedule wall-clock fields. Null/omitted → UTC. */
7211
+ timezone: string().nullable().optional(),
7077
7212
  sourcePath: string(),
7078
7213
  sourceContents: string(),
7079
7214
  assignments: array(TriggerAssignmentSchema)
@@ -7259,6 +7394,13 @@ object({
7259
7394
  uploadUrl: url(),
7260
7395
  storageKey: string().min(1)
7261
7396
  });
7397
+ object({ contentType: string().trim().min(1) });
7398
+ object({
7399
+ uploadUrl: url(),
7400
+ storageKey: string().min(1)
7401
+ });
7402
+ object({ storageKey: string().min(1) });
7403
+ object({ logo: url() });
7262
7404
  const UserInterfaceThemeSchema = _enum([
7263
7405
  "system",
7264
7406
  "light",
@@ -7439,90 +7581,6 @@ object({
7439
7581
  lastOpenedAt: string().min(1),
7440
7582
  lastModifiedAt: string().min(1)
7441
7583
  });
7442
- const isoDateTime = string().datetime();
7443
- const sha256Hex = string().regex(/^[a-f0-9]{64}$/, "Expected a lowercase hex sha256 digest");
7444
- /**
7445
- * A single entry in a deploy's file tree, as served to the dashboard. Carries
7446
- * no contents: `id` is a stable, path-derived handle used for selection and
7447
- * `?file=` deep links; `hash` is the content address used to fetch the bytes
7448
- * lazily and to cache them immutably in the browser.
7449
- */
7450
- const ProjectFileSummarySchema = object({
7451
- id: string(),
7452
- path: string().min(1),
7453
- hash: sha256Hex
7454
- });
7455
- /** Maps a runtime resource slug (agent/workflow/skill) to its source file path. */
7456
- const ProjectSourceResourceRefSchema = object({
7457
- slug: string().min(1),
7458
- path: string().min(1)
7459
- });
7460
- const ProjectSourceResourcesSchema = object({
7461
- agents: array(ProjectSourceResourceRefSchema).default([]),
7462
- workflows: array(ProjectSourceResourceRefSchema).default([]),
7463
- skills: array(ProjectSourceResourceRefSchema).default([])
7464
- });
7465
- const emptyResources = () => ({
7466
- agents: [],
7467
- workflows: [],
7468
- skills: []
7469
- });
7470
- object({
7471
- artifactId: string().nullable(),
7472
- files: array(ProjectFileSummarySchema),
7473
- resources: ProjectSourceResourcesSchema.default(emptyResources())
7474
- });
7475
- object({
7476
- path: string().min(1),
7477
- contents: string(),
7478
- hash: sha256Hex
7479
- });
7480
- object({ blobs: array(object({
7481
- hash: sha256Hex,
7482
- size: number$1().int().nonnegative()
7483
- })) });
7484
- object({ uploads: array(object({
7485
- hash: sha256Hex,
7486
- url: string().url()
7487
- })) });
7488
- object({ files: array(object({
7489
- path: string().min(1),
7490
- hash: sha256Hex
7491
- })) });
7492
- object({
7493
- ok: literal(true),
7494
- fileCount: number$1().int().nonnegative()
7495
- });
7496
- object({
7497
- files: array(object({
7498
- id: string(),
7499
- path: string().min(1),
7500
- hash: sha256Hex
7501
- })),
7502
- generatedAt: isoDateTime
7503
- });
7504
- /** A single source file returned by the bulk active-source download endpoint. */
7505
- const DownloadActiveProjectSourceFileSchema = object({
7506
- path: string().min(1),
7507
- contents: string()
7508
- });
7509
- object({
7510
- artifactId: string(),
7511
- files: array(DownloadActiveProjectSourceFileSchema)
7512
- });
7513
- object({
7514
- projectId: string(),
7515
- artifactId: string(),
7516
- pulledAt: string().datetime()
7517
- });
7518
- object({ files: array(object({
7519
- id: string(),
7520
- path: string().min(1)
7521
- })) });
7522
- object({ files: array(object({
7523
- id: string(),
7524
- path: string().min(1)
7525
- })) });
7526
7584
  /** Whether the overview is still being produced or finished. */
7527
7585
  const WorkflowOverviewStatusSchema = _enum(["generating", "ready"]);
7528
7586
  /** One phase of the guided-tour overview. */
@@ -7547,7 +7605,8 @@ const WorkflowInputFieldTypeSchema = _enum([
7547
7605
  "boolean",
7548
7606
  "enum",
7549
7607
  "object",
7550
- "array"
7608
+ "array",
7609
+ "file"
7551
7610
  ]);
7552
7611
  const WorkflowInputFieldSchema = lazy(() => object({
7553
7612
  key: string(),
@@ -7562,6 +7621,8 @@ const WorkflowInputFieldSchema = lazy(() => object({
7562
7621
  number$1(),
7563
7622
  boolean()
7564
7623
  ]).optional(),
7624
+ minimum: number$1().optional(),
7625
+ maximum: number$1().optional(),
7565
7626
  children: array(WorkflowInputFieldSchema).optional(),
7566
7627
  format: string().optional()
7567
7628
  }));
@@ -7761,6 +7822,159 @@ const WorkflowCanvasCredentialBindingSchema = union([
7761
7822
  })
7762
7823
  ]);
7763
7824
  record(string(), array(WorkflowCanvasCredentialBindingSchema));
7825
+ const FormControlSchema = _enum([
7826
+ "input",
7827
+ "textarea",
7828
+ "select",
7829
+ "radio",
7830
+ "stepper",
7831
+ "slider",
7832
+ "checkbox",
7833
+ "switch"
7834
+ ]);
7835
+ const FormFieldConfigEntrySchema = object({
7836
+ label: string().trim().min(1).max(120).optional(),
7837
+ helpText: string().trim().min(1).max(300).optional(),
7838
+ placeholder: string().trim().min(1).max(200).optional(),
7839
+ control: FormControlSchema.optional()
7840
+ });
7841
+ const FormFieldConfigSchema = record(string(), FormFieldConfigEntrySchema);
7842
+ const PublicFormFieldSchema = WorkflowInputFieldSchema.and(object({
7843
+ control: FormControlSchema.optional(),
7844
+ helpText: string().optional()
7845
+ }));
7846
+ const PublishedFormSchema = object({
7847
+ id: string().min(1),
7848
+ workflowId: string().min(1),
7849
+ workflowSlug: string().min(1),
7850
+ enabled: boolean(),
7851
+ title: string().min(1).nullable(),
7852
+ description: string().min(1).nullable(),
7853
+ fieldConfig: FormFieldConfigSchema,
7854
+ publicUrl: string().url(),
7855
+ createdAt: string().min(1),
7856
+ updatedAt: string().min(1)
7857
+ });
7858
+ object({
7859
+ id: string().min(1),
7860
+ projectId: string().min(1),
7861
+ workflowSlug: string().min(1),
7862
+ enabled: boolean(),
7863
+ title: string().min(1).nullable(),
7864
+ description: string().min(1).nullable(),
7865
+ fieldConfig: FormFieldConfigSchema,
7866
+ publicUrl: string().url(),
7867
+ createdAt: string().min(1),
7868
+ updatedAt: string().min(1)
7869
+ });
7870
+ PublishedFormSchema.nullable();
7871
+ object({
7872
+ enabled: boolean().optional(),
7873
+ title: string().trim().min(1).max(120).nullable().optional(),
7874
+ description: string().trim().min(1).max(500).nullable().optional(),
7875
+ fieldConfig: FormFieldConfigSchema.optional()
7876
+ });
7877
+ object({
7878
+ title: string().min(1),
7879
+ description: string().nullable(),
7880
+ fields: array(PublicFormFieldSchema),
7881
+ branding: object({
7882
+ organizationName: string().min(1),
7883
+ projectName: string().min(1),
7884
+ logoLightUrl: string().url().nullable(),
7885
+ logoDarkUrl: string().url().nullable(),
7886
+ logoHeightPx: number$1().int().positive()
7887
+ })
7888
+ });
7889
+ object({
7890
+ values: record(string(), unknown()),
7891
+ website: string().max(200).optional()
7892
+ });
7893
+ object({ ok: literal(true) });
7894
+ const isoDateTime = string().datetime();
7895
+ const sha256Hex = string().regex(/^[a-f0-9]{64}$/, "Expected a lowercase hex sha256 digest");
7896
+ /**
7897
+ * A single entry in a deploy's file tree, as served to the dashboard. Carries
7898
+ * no contents: `id` is a stable, path-derived handle used for selection and
7899
+ * `?file=` deep links; `hash` is the content address used to fetch the bytes
7900
+ * lazily and to cache them immutably in the browser.
7901
+ */
7902
+ const ProjectFileSummarySchema = object({
7903
+ id: string(),
7904
+ path: string().min(1),
7905
+ hash: sha256Hex
7906
+ });
7907
+ /** Maps a runtime resource slug (agent/workflow/skill) to its source file path. */
7908
+ const ProjectSourceResourceRefSchema = object({
7909
+ slug: string().min(1),
7910
+ path: string().min(1)
7911
+ });
7912
+ const ProjectSourceResourcesSchema = object({
7913
+ agents: array(ProjectSourceResourceRefSchema).default([]),
7914
+ workflows: array(ProjectSourceResourceRefSchema).default([]),
7915
+ skills: array(ProjectSourceResourceRefSchema).default([])
7916
+ });
7917
+ const emptyResources = () => ({
7918
+ agents: [],
7919
+ workflows: [],
7920
+ skills: []
7921
+ });
7922
+ object({
7923
+ artifactId: string().nullable(),
7924
+ files: array(ProjectFileSummarySchema),
7925
+ resources: ProjectSourceResourcesSchema.default(emptyResources())
7926
+ });
7927
+ object({
7928
+ path: string().min(1),
7929
+ contents: string(),
7930
+ hash: sha256Hex
7931
+ });
7932
+ object({ blobs: array(object({
7933
+ hash: sha256Hex,
7934
+ size: number$1().int().nonnegative()
7935
+ })) });
7936
+ object({ uploads: array(object({
7937
+ hash: sha256Hex,
7938
+ url: string().url()
7939
+ })) });
7940
+ object({ files: array(object({
7941
+ path: string().min(1),
7942
+ hash: sha256Hex
7943
+ })) });
7944
+ object({
7945
+ ok: literal(true),
7946
+ fileCount: number$1().int().nonnegative()
7947
+ });
7948
+ object({
7949
+ files: array(object({
7950
+ id: string(),
7951
+ path: string().min(1),
7952
+ hash: sha256Hex
7953
+ })),
7954
+ generatedAt: isoDateTime
7955
+ });
7956
+ /** A single source file returned by the bulk active-source download endpoint. */
7957
+ const DownloadActiveProjectSourceFileSchema = object({
7958
+ path: string().min(1),
7959
+ contents: string()
7960
+ });
7961
+ object({
7962
+ artifactId: string(),
7963
+ files: array(DownloadActiveProjectSourceFileSchema)
7964
+ });
7965
+ object({
7966
+ projectId: string(),
7967
+ artifactId: string(),
7968
+ pulledAt: string().datetime()
7969
+ });
7970
+ object({ files: array(object({
7971
+ id: string(),
7972
+ path: string().min(1)
7973
+ })) });
7974
+ object({ files: array(object({
7975
+ id: string(),
7976
+ path: string().min(1)
7977
+ })) });
7764
7978
  record(string(), unknown());
7765
7979
  //#endregion
7766
7980
  //#region src/runtime.ts
@@ -7812,10 +8026,22 @@ const RUNTIME_ENV_KEYS = [
7812
8026
  "REDIS_URL",
7813
8027
  "KEYSTROKE_QUEUE_PREFIX"
7814
8028
  ];
8029
+ /**
8030
+ * Observability ingest config for org workers (PostHog error tracking + crash reports).
8031
+ * Ingest tokens only — never forward `POSTHOG_API_KEY` (management) into workers.
8032
+ */
8033
+ const OBSERVABILITY_ENV_KEYS = [
8034
+ "POSTHOG_PROJECT_TOKEN",
8035
+ "POSTHOG_HOST",
8036
+ "POSTHOG_FLUSH_MODE",
8037
+ "KEYSTROKE_ENVIRONMENT",
8038
+ "KEYSTROKE_RELEASE"
8039
+ ];
7815
8040
  /** Env keys that must never be forwarded into untrusted org workers. */
7816
8041
  const FORBIDDEN_WORKER_ENV_KEYS = [
7817
8042
  "BETTER_AUTH_SECRET",
7818
8043
  "DATABASE_URL",
8044
+ "POSTHOG_API_KEY",
7819
8045
  "POSTGRES_PASSWORD",
7820
8046
  "PLATFORM_WORKER_TOKEN",
7821
8047
  "STRIPE_SECRET_KEY",
@@ -7859,6 +8085,11 @@ function buildRuntimeEnv(source, artifacts, database, extraEnv) {
7859
8085
  if (!value) continue;
7860
8086
  entries.set(key, value);
7861
8087
  }
8088
+ for (const key of OBSERVABILITY_ENV_KEYS) {
8089
+ const value = source[key]?.trim();
8090
+ if (!value) continue;
8091
+ entries.set(key, value);
8092
+ }
7862
8093
  if (!extraEnv) for (const key of PROVIDER_ENV_KEYS) {
7863
8094
  const value = source[key]?.trim();
7864
8095
  if (value) entries.set(key, value);