@keystrokehq/hosting 0.1.13 → 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/LICENSE CHANGED
@@ -1,21 +1,13 @@
1
- MIT License
1
+ Copyright 2026 Sprint Labs, Inc. All rights reserved.
2
2
 
3
- Copyright (c) 2026 Dallin
3
+ This private canonical monorepo contains materials under different terms:
4
4
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
5
+ - The downstream public projection described by `oss/` is made available under
6
+ the Elastic License 2.0 in `oss/LICENSE`.
7
+ - Code and materials in paths containing an exact `cloud` segment are
8
+ proprietary and governed by the nearest applicable proprietary license.
11
9
 
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
10
+ Access to this private repository does not itself grant a license to use, copy,
11
+ modify, distribute, make available, or create derivative works from its
12
+ contents. Sprint Labs employees, contractors, customers, and partners receive
13
+ rights only under their applicable written agreements.
package/dist/index.cjs CHANGED
@@ -4397,8 +4397,11 @@ function superRefine(fn, params) {
4397
4397
  function number(params) {
4398
4398
  return /* @__PURE__ */ _coercedNumber(ZodNumber, params);
4399
4399
  }
4400
- //#endregion
4401
- //#region ../shared/dist/index.mjs
4400
+ new Set([
4401
+ "hello",
4402
+ "greeting",
4403
+ "greet"
4404
+ ]);
4402
4405
  /** Auth, session, and account-entry URL segments. */
4403
4406
  const AUTH_ACCOUNT_SLUGS = [
4404
4407
  "2fa",
@@ -4510,6 +4513,7 @@ const PRODUCT_SLUGS = [
4510
4513
  "execution",
4511
4514
  "executions",
4512
4515
  "explore",
4516
+ "forms",
4513
4517
  "get-started",
4514
4518
  "history",
4515
4519
  "inbox",
@@ -5377,6 +5381,8 @@ const storedRouteManifestEntryV2Schema = discriminatedUnion("kind", [
5377
5381
  moduleFile: string(),
5378
5382
  sourceHash: string().optional(),
5379
5383
  schedule: string(),
5384
+ /** IANA timezone for schedule wall-clock fields. When omitted, UTC. */
5385
+ timezone: string().optional(),
5380
5386
  name: requiredDisplayTextSchema,
5381
5387
  description: requiredDisplayTextSchema
5382
5388
  }),
@@ -5385,7 +5391,9 @@ const storedRouteManifestEntryV2Schema = discriminatedUnion("kind", [
5385
5391
  pollId: string(),
5386
5392
  attachmentIds: array(string()),
5387
5393
  moduleFile: string(),
5388
- schedule: string()
5394
+ schedule: string(),
5395
+ /** IANA timezone for schedule wall-clock fields. When omitted, UTC. */
5396
+ timezone: string().optional()
5389
5397
  }),
5390
5398
  object({
5391
5399
  kind: literal("cron-schedule"),
@@ -5394,6 +5402,8 @@ const storedRouteManifestEntryV2Schema = discriminatedUnion("kind", [
5394
5402
  moduleFile: string(),
5395
5403
  sourceHash: string().optional(),
5396
5404
  schedule: string(),
5405
+ /** IANA timezone for schedule wall-clock fields. When omitted, UTC. */
5406
+ timezone: string().optional(),
5397
5407
  /** Static cron payload from `defineCronSource({ payload })` — omitted when the source has none. */
5398
5408
  payload: unknown().optional(),
5399
5409
  name: requiredDisplayTextSchema,
@@ -5438,6 +5448,8 @@ const AutoTopupSummarySchema = object({
5438
5448
  const PlanLimitsSchema = object({
5439
5449
  includedStorageGb: number$1(),
5440
5450
  concurrencyLimit: number$1(),
5451
+ /** Max non-deleted projects; enforced on create only. */
5452
+ maxProjects: number$1(),
5441
5453
  agentTimeoutMs: number$1(),
5442
5454
  workflowTimeoutMs: number$1(),
5443
5455
  pollTimeoutMs: number$1(),
@@ -5451,8 +5463,15 @@ const PlanLimitsSchema = object({
5451
5463
  object({
5452
5464
  planKey: string(),
5453
5465
  subscriptionStatus: subscriptionStatusSchema,
5466
+ /** Remaining plan-bucket balance this period (µc). */
5454
5467
  planCreditMicroCredits: number$1(),
5468
+ /** Remaining prepaid balance (µc). Never expires. */
5455
5469
  prepaidCreditMicroCredits: number$1(),
5470
+ /**
5471
+ * Resolved monthly plan allotment (µc) — override ?? preset. Powers the
5472
+ * credit-usage progress denominator (`used = allotment − remaining`).
5473
+ */
5474
+ monthlyCreditMicroCredits: number$1(),
5456
5475
  periodStart: isoDateTime$6.nullable(),
5457
5476
  periodEnd: isoDateTime$6.nullable(),
5458
5477
  autoTopup: AutoTopupSummarySchema,
@@ -5695,7 +5714,8 @@ object({
5695
5714
  });
5696
5715
  const NewChannelBindingInputSchema = object({
5697
5716
  channelId: string().min(1),
5698
- channelName: string().min(1),
5717
+ /** Display name. When omitted or equal to `channelId`, the server resolves it from Slack. */
5718
+ channelName: string().min(1).optional(),
5699
5719
  channelKind: ChannelBindingKindSchema.optional(),
5700
5720
  mode: ChannelListenModeSchema.optional(),
5701
5721
  subscribeOnMention: boolean().optional()
@@ -5757,12 +5777,13 @@ const AppAuthKindSchema = _enum([
5757
5777
  "api_key",
5758
5778
  "keystroke"
5759
5779
  ]);
5760
- /** Composio auth scheme for API-key style connections. */
5780
+ /** Composio auth scheme for API-key / no-auth style connections. */
5761
5781
  const AppCredentialSchemeSchema = _enum([
5762
5782
  "API_KEY",
5763
5783
  "BEARER_TOKEN",
5764
5784
  "BASIC",
5765
- "BASIC_WITH_JWT"
5785
+ "BASIC_WITH_JWT",
5786
+ "NO_AUTH"
5766
5787
  ]);
5767
5788
  /**
5768
5789
  * Where app metadata and execution are sourced (e.g. native, composio, pipedream, custom).
@@ -5804,6 +5825,7 @@ object({
5804
5825
  "graphql"
5805
5826
  ]).default("custom"),
5806
5827
  url: string().url().optional(),
5828
+ logo: string().url().optional(),
5807
5829
  authKind: AppAuthKindSchema.optional(),
5808
5830
  fields: optionalCredentialFieldsSchema.optional(),
5809
5831
  credentialScheme: AppCredentialSchemeSchema.optional(),
@@ -5839,6 +5861,7 @@ object({
5839
5861
  authKind: AppAuthKindSchema,
5840
5862
  source: AppSourceSchema,
5841
5863
  url: string().url().nullable().optional(),
5864
+ logo: string().url().nullable().optional(),
5842
5865
  credentialFields: optionalCredentialFieldsSchema.optional(),
5843
5866
  credentialScheme: AppCredentialSchemeSchema.optional(),
5844
5867
  oauthScopes: array(OAuthScopeOptionSchema).optional(),
@@ -5875,12 +5898,14 @@ object({
5875
5898
  /** Endpoint URL for MCP, OpenAPI, or GraphQL custom apps. */
5876
5899
  url: string().url().nullable().optional(),
5877
5900
  /** True when the app has a non-empty credential field template. */
5878
- hasCredentialFields: boolean().optional()
5901
+ hasCredentialFields: boolean().optional(),
5902
+ /** Composio auth scheme — present for API-key and NO_AUTH apps so the picker can choose a flow. */
5903
+ credentialScheme: AppCredentialSchemeSchema.optional()
5879
5904
  }).extend({
5880
5905
  oauthScopes: array(OAuthScopeOptionSchema),
5881
5906
  /** Custom api_key apps — vault field template for connect UI and sync. */
5882
5907
  credentialFields: AppCredentialFieldsSchema.optional(),
5883
- /** Composio auth scheme when credentialFields are present. */
5908
+ /** Composio auth scheme for API-key or NO_AUTH connections. */
5884
5909
  credentialScheme: AppCredentialSchemeSchema.optional(),
5885
5910
  /** When present, the app supports agent gateway bindings (external channels). */
5886
5911
  gateway: AppGatewaySchema.optional()
@@ -5997,8 +6022,12 @@ const AppCredentialScopeSchema = _enum([
5997
6022
  "project",
5998
6023
  "organization"
5999
6024
  ]);
6000
- /** How the credential was connected (OAuth vs manual api-key entry). */
6001
- const AppCredentialConnectionKindSchema = _enum(["oauth", "manual"]);
6025
+ /** How the credential was connected (OAuth, manual api-key entry, or no-auth). */
6026
+ const AppCredentialConnectionKindSchema = _enum([
6027
+ "oauth",
6028
+ "manual",
6029
+ "none"
6030
+ ]);
6002
6031
  /** Connect-dialog permission preset for OAuth scope selection. */
6003
6032
  const OAuthPermissionModeSchema = _enum(["default", "restricted"]);
6004
6033
  const optionalTimestamp$1 = string().optional();
@@ -6092,12 +6121,39 @@ CredentialTargetsFieldsSchema.extend({
6092
6121
  message: "OAuth credentials are created via the OAuth callback",
6093
6122
  path: ["connectionKind"]
6094
6123
  });
6124
+ if (input.connectionKind === "none" && input.value) ctx.addIssue({
6125
+ code: "custom",
6126
+ message: "value is not allowed for no-auth connections",
6127
+ path: ["value"]
6128
+ });
6095
6129
  });
6096
6130
  object({
6097
6131
  label: string().trim().min(1).optional(),
6098
6132
  isDefault: boolean().optional(),
6099
- value: credentialSecretValueSchema.optional()
6100
- }).refine((input) => input.label !== void 0 || input.isDefault !== void 0 || input.value !== void 0, { message: "At least one field is required" });
6133
+ value: credentialSecretValueSchema.optional(),
6134
+ /** Move this credential to a different scope in place. */
6135
+ scope: AppCredentialScopeSchema.optional(),
6136
+ /** Required when `scope` is `project`. */
6137
+ projectSlug: string().trim().min(1).optional()
6138
+ }).superRefine((input, ctx) => {
6139
+ if (!(input.label !== void 0 || input.isDefault !== void 0 || input.value !== void 0 || input.scope !== void 0)) ctx.addIssue({
6140
+ code: "custom",
6141
+ message: "At least one field is required"
6142
+ });
6143
+ if (input.scope === "project" && !input.projectSlug) ctx.addIssue({
6144
+ code: "custom",
6145
+ message: "projectSlug is required when scope is project",
6146
+ path: ["projectSlug"]
6147
+ });
6148
+ if (input.scope !== "project" && input.projectSlug !== void 0) ctx.addIssue({
6149
+ code: "custom",
6150
+ message: "projectSlug is only valid when scope is project",
6151
+ path: ["projectSlug"]
6152
+ });
6153
+ });
6154
+ CredentialTargetsFieldsSchema.omit({ credentialInstanceId: true }).superRefine((input, ctx) => {
6155
+ if (!hasCredentialTarget(input)) addMissingCredentialTargetIssue(ctx);
6156
+ });
6101
6157
  object({
6102
6158
  limit: number().int().min(1).max(200).optional(),
6103
6159
  cursor: string().min(1).optional()
@@ -6199,11 +6255,46 @@ object({
6199
6255
  "org-deletion",
6200
6256
  "contact",
6201
6257
  "enterprise-upgrade",
6202
- "verification"
6258
+ "verification",
6259
+ "slack-connect"
6203
6260
  ]),
6204
6261
  message: string().trim().max(5e3).optional()
6205
6262
  });
6206
6263
  object({ ok: literal(true) });
6264
+ const TemplateKindSchema = _enum([
6265
+ "agent",
6266
+ "workflow",
6267
+ "both"
6268
+ ]);
6269
+ object({
6270
+ kind: TemplateKindSchema,
6271
+ title: string().min(1),
6272
+ description: string().min(1),
6273
+ tags: array(string().min(1)).default([]),
6274
+ requiredApps: array(string().min(1)).default([])
6275
+ });
6276
+ object({
6277
+ slug: string().min(1),
6278
+ kind: TemplateKindSchema,
6279
+ title: string().min(1),
6280
+ description: string().min(1),
6281
+ tags: array(string()),
6282
+ requiredApps: array(string()),
6283
+ updatedAt: string().datetime()
6284
+ }).extend({ files: record(string(), string()) });
6285
+ object({
6286
+ slug: string().min(1),
6287
+ files: record(string(), string())
6288
+ });
6289
+ object({
6290
+ slug: string().min(1),
6291
+ kind: TemplateKindSchema,
6292
+ title: string().min(1),
6293
+ description: string().min(1),
6294
+ tags: array(string()).default([]),
6295
+ requiredApps: array(string()).default([]),
6296
+ files: record(string(), string())
6297
+ });
6207
6298
  const MarketingContactCompanySizeSchema = _enum([
6208
6299
  "1-10",
6209
6300
  "11-50",
@@ -6228,7 +6319,14 @@ const ValidationErrorDetailSchema = object({
6228
6319
  const ErrorResponseCodeSchema = OrganizationSlugErrorCodeSchema.or(_enum([
6229
6320
  "needs_org_selection",
6230
6321
  "org_unverified",
6231
- "connector_unavailable"
6322
+ "connector_unavailable",
6323
+ "invalid_url",
6324
+ "url_not_allowed",
6325
+ "url_unreachable",
6326
+ "upstream_http_error",
6327
+ "spec_too_large",
6328
+ "spec_parse_error",
6329
+ "invalid_openapi"
6232
6330
  ]));
6233
6331
  object({
6234
6332
  error: string(),
@@ -6265,6 +6363,12 @@ const ChatAttachmentInputSchema = object({
6265
6363
  mediaType: string().min(1),
6266
6364
  filename: string().optional()
6267
6365
  });
6366
+ object({
6367
+ type: literal("file"),
6368
+ mediaType: string().min(1),
6369
+ url: string().min(1),
6370
+ filename: string().optional()
6371
+ });
6268
6372
  object({
6269
6373
  contentType: string().min(1),
6270
6374
  filename: string().min(1),
@@ -6345,12 +6449,7 @@ object({
6345
6449
  params: array(unknown()).default([]),
6346
6450
  method: string().min(1).optional()
6347
6451
  });
6348
- object({ migrations: array(object({
6349
- sql: array(string().min(1)),
6350
- hash: string().min(1),
6351
- folderMillis: number$1()
6352
- })) });
6353
- object({ results: array(object({ rows: array(unknown()) })) });
6452
+ object({ rows: array(unknown()) });
6354
6453
  const RunSourceKindSchema = _enum([
6355
6454
  "api",
6356
6455
  "trigger",
@@ -6380,6 +6479,10 @@ object({
6380
6479
  description: string().nullable().optional(),
6381
6480
  type: AgentTriggerTypeSchema,
6382
6481
  schedule: string().nullable(),
6482
+ /** IANA timezone for schedule wall-clock fields. Null when omitted (evaluates in UTC). */
6483
+ timezone: string().nullable(),
6484
+ /** ISO timestamptz of the next scheduled fire. Null for webhooks / unset. */
6485
+ nextRunAt: string().nullable(),
6383
6486
  endpoint: string().nullable(),
6384
6487
  origin: AgentTriggerOriginSchema,
6385
6488
  prompt: string().nullable(),
@@ -6536,6 +6639,26 @@ const HistoryAgentCompactionEventSchema = object({
6536
6639
  retainedTailEstimate: number$1().optional(),
6537
6640
  durable: boolean()
6538
6641
  });
6642
+ /** Compact abnormal prompt-finish diagnostics from `agent_end` (optional on older events). */
6643
+ const HistoryAgentPromptFinishEventSchema = object({
6644
+ seq: number$1(),
6645
+ createdAt: string(),
6646
+ promptId: string().optional(),
6647
+ outcome: _enum([
6648
+ "completed",
6649
+ "error",
6650
+ "aborted"
6651
+ ]),
6652
+ finishReason: string().nullable(),
6653
+ rawFinishReason: string().optional(),
6654
+ stepCount: number$1(),
6655
+ maxSteps: number$1(),
6656
+ hitStepLimit: boolean(),
6657
+ error: object({
6658
+ name: string().optional(),
6659
+ message: string()
6660
+ }).optional()
6661
+ });
6539
6662
  const HistoryRunDetailSchema = discriminatedUnion("kind", [HistoryWorkflowRunDetailSchema, object({
6540
6663
  kind: literal("agent"),
6541
6664
  runId: string(),
@@ -6563,6 +6686,8 @@ const HistoryRunDetailSchema = discriminatedUnion("kind", [HistoryWorkflowRunDet
6563
6686
  messages: array(record(string(), unknown())),
6564
6687
  /** Sanitized context-compaction markers for the conversation timeline. */
6565
6688
  compactionEvents: array(HistoryAgentCompactionEventSchema).default([]),
6689
+ /** Abnormal prompt-finish diagnostics from `agent_end` (missing on historical events). */
6690
+ promptFinishEvents: array(HistoryAgentPromptFinishEventSchema).default([]),
6566
6691
  trace: HistoryTraceSchema.nullable(),
6567
6692
  ranAs: HistoryRunActorSchema.nullable().optional(),
6568
6693
  usage: HistoryRunUsageSchema.nullable().optional()
@@ -6807,6 +6932,7 @@ object({
6807
6932
  * log. Defaulted so older servers remain compatible.
6808
6933
  */
6809
6934
  compactionEvents: array(HistoryAgentCompactionEventSchema).default([]),
6935
+ promptFinishEvents: array(HistoryAgentPromptFinishEventSchema).default([]),
6810
6936
  trace: TraceResponseSchema.nullable()
6811
6937
  });
6812
6938
  const SlackGatewayModeSchema = _enum([
@@ -7061,6 +7187,10 @@ object({
7061
7187
  webhookUrl: string().nullable(),
7062
7188
  /** Cron expression or poll cadence label (cron/poll triggers only). */
7063
7189
  schedule: string().nullable(),
7190
+ /** IANA timezone for schedule wall-clock fields. Null when omitted (evaluates in UTC). */
7191
+ timezone: string().nullable(),
7192
+ /** ISO timestamptz of the next scheduled fire. Null for webhooks / unset. */
7193
+ nextRunAt: string().nullable(),
7064
7194
  /** Workflows + agents currently bound to this source. */
7065
7195
  assignments: array(TriggerAssignmentSchema),
7066
7196
  lastFiredAt: string().nullable(),
@@ -7101,6 +7231,8 @@ const TriggerOverviewInputSchema = object({
7101
7231
  description: string().nullable(),
7102
7232
  type: TriggerTypeSchema,
7103
7233
  schedule: string().nullable(),
7234
+ /** IANA timezone for schedule wall-clock fields. Null/omitted → UTC. */
7235
+ timezone: string().nullable().optional(),
7104
7236
  sourcePath: string(),
7105
7237
  sourceContents: string(),
7106
7238
  assignments: array(TriggerAssignmentSchema)
@@ -7286,6 +7418,13 @@ object({
7286
7418
  uploadUrl: url(),
7287
7419
  storageKey: string().min(1)
7288
7420
  });
7421
+ object({ contentType: string().trim().min(1) });
7422
+ object({
7423
+ uploadUrl: url(),
7424
+ storageKey: string().min(1)
7425
+ });
7426
+ object({ storageKey: string().min(1) });
7427
+ object({ logo: url() });
7289
7428
  const UserInterfaceThemeSchema = _enum([
7290
7429
  "system",
7291
7430
  "light",
@@ -7466,90 +7605,6 @@ object({
7466
7605
  lastOpenedAt: string().min(1),
7467
7606
  lastModifiedAt: string().min(1)
7468
7607
  });
7469
- const isoDateTime = string().datetime();
7470
- const sha256Hex = string().regex(/^[a-f0-9]{64}$/, "Expected a lowercase hex sha256 digest");
7471
- /**
7472
- * A single entry in a deploy's file tree, as served to the dashboard. Carries
7473
- * no contents: `id` is a stable, path-derived handle used for selection and
7474
- * `?file=` deep links; `hash` is the content address used to fetch the bytes
7475
- * lazily and to cache them immutably in the browser.
7476
- */
7477
- const ProjectFileSummarySchema = object({
7478
- id: string(),
7479
- path: string().min(1),
7480
- hash: sha256Hex
7481
- });
7482
- /** Maps a runtime resource slug (agent/workflow/skill) to its source file path. */
7483
- const ProjectSourceResourceRefSchema = object({
7484
- slug: string().min(1),
7485
- path: string().min(1)
7486
- });
7487
- const ProjectSourceResourcesSchema = object({
7488
- agents: array(ProjectSourceResourceRefSchema).default([]),
7489
- workflows: array(ProjectSourceResourceRefSchema).default([]),
7490
- skills: array(ProjectSourceResourceRefSchema).default([])
7491
- });
7492
- const emptyResources = () => ({
7493
- agents: [],
7494
- workflows: [],
7495
- skills: []
7496
- });
7497
- object({
7498
- artifactId: string().nullable(),
7499
- files: array(ProjectFileSummarySchema),
7500
- resources: ProjectSourceResourcesSchema.default(emptyResources())
7501
- });
7502
- object({
7503
- path: string().min(1),
7504
- contents: string(),
7505
- hash: sha256Hex
7506
- });
7507
- object({ blobs: array(object({
7508
- hash: sha256Hex,
7509
- size: number$1().int().nonnegative()
7510
- })) });
7511
- object({ uploads: array(object({
7512
- hash: sha256Hex,
7513
- url: string().url()
7514
- })) });
7515
- object({ files: array(object({
7516
- path: string().min(1),
7517
- hash: sha256Hex
7518
- })) });
7519
- object({
7520
- ok: literal(true),
7521
- fileCount: number$1().int().nonnegative()
7522
- });
7523
- object({
7524
- files: array(object({
7525
- id: string(),
7526
- path: string().min(1),
7527
- hash: sha256Hex
7528
- })),
7529
- generatedAt: isoDateTime
7530
- });
7531
- /** A single source file returned by the bulk active-source download endpoint. */
7532
- const DownloadActiveProjectSourceFileSchema = object({
7533
- path: string().min(1),
7534
- contents: string()
7535
- });
7536
- object({
7537
- artifactId: string(),
7538
- files: array(DownloadActiveProjectSourceFileSchema)
7539
- });
7540
- object({
7541
- projectId: string(),
7542
- artifactId: string(),
7543
- pulledAt: string().datetime()
7544
- });
7545
- object({ files: array(object({
7546
- id: string(),
7547
- path: string().min(1)
7548
- })) });
7549
- object({ files: array(object({
7550
- id: string(),
7551
- path: string().min(1)
7552
- })) });
7553
7608
  /** Whether the overview is still being produced or finished. */
7554
7609
  const WorkflowOverviewStatusSchema = _enum(["generating", "ready"]);
7555
7610
  /** One phase of the guided-tour overview. */
@@ -7574,7 +7629,8 @@ const WorkflowInputFieldTypeSchema = _enum([
7574
7629
  "boolean",
7575
7630
  "enum",
7576
7631
  "object",
7577
- "array"
7632
+ "array",
7633
+ "file"
7578
7634
  ]);
7579
7635
  const WorkflowInputFieldSchema = lazy(() => object({
7580
7636
  key: string(),
@@ -7589,6 +7645,8 @@ const WorkflowInputFieldSchema = lazy(() => object({
7589
7645
  number$1(),
7590
7646
  boolean()
7591
7647
  ]).optional(),
7648
+ minimum: number$1().optional(),
7649
+ maximum: number$1().optional(),
7592
7650
  children: array(WorkflowInputFieldSchema).optional(),
7593
7651
  format: string().optional()
7594
7652
  }));
@@ -7788,6 +7846,159 @@ const WorkflowCanvasCredentialBindingSchema = union([
7788
7846
  })
7789
7847
  ]);
7790
7848
  record(string(), array(WorkflowCanvasCredentialBindingSchema));
7849
+ const FormControlSchema = _enum([
7850
+ "input",
7851
+ "textarea",
7852
+ "select",
7853
+ "radio",
7854
+ "stepper",
7855
+ "slider",
7856
+ "checkbox",
7857
+ "switch"
7858
+ ]);
7859
+ const FormFieldConfigEntrySchema = object({
7860
+ label: string().trim().min(1).max(120).optional(),
7861
+ helpText: string().trim().min(1).max(300).optional(),
7862
+ placeholder: string().trim().min(1).max(200).optional(),
7863
+ control: FormControlSchema.optional()
7864
+ });
7865
+ const FormFieldConfigSchema = record(string(), FormFieldConfigEntrySchema);
7866
+ const PublicFormFieldSchema = WorkflowInputFieldSchema.and(object({
7867
+ control: FormControlSchema.optional(),
7868
+ helpText: string().optional()
7869
+ }));
7870
+ const PublishedFormSchema = object({
7871
+ id: string().min(1),
7872
+ workflowId: string().min(1),
7873
+ workflowSlug: string().min(1),
7874
+ enabled: boolean(),
7875
+ title: string().min(1).nullable(),
7876
+ description: string().min(1).nullable(),
7877
+ fieldConfig: FormFieldConfigSchema,
7878
+ publicUrl: string().url(),
7879
+ createdAt: string().min(1),
7880
+ updatedAt: string().min(1)
7881
+ });
7882
+ object({
7883
+ id: string().min(1),
7884
+ projectId: string().min(1),
7885
+ workflowSlug: string().min(1),
7886
+ enabled: boolean(),
7887
+ title: string().min(1).nullable(),
7888
+ description: string().min(1).nullable(),
7889
+ fieldConfig: FormFieldConfigSchema,
7890
+ publicUrl: string().url(),
7891
+ createdAt: string().min(1),
7892
+ updatedAt: string().min(1)
7893
+ });
7894
+ PublishedFormSchema.nullable();
7895
+ object({
7896
+ enabled: boolean().optional(),
7897
+ title: string().trim().min(1).max(120).nullable().optional(),
7898
+ description: string().trim().min(1).max(500).nullable().optional(),
7899
+ fieldConfig: FormFieldConfigSchema.optional()
7900
+ });
7901
+ object({
7902
+ title: string().min(1),
7903
+ description: string().nullable(),
7904
+ fields: array(PublicFormFieldSchema),
7905
+ branding: object({
7906
+ organizationName: string().min(1),
7907
+ projectName: string().min(1),
7908
+ logoLightUrl: string().url().nullable(),
7909
+ logoDarkUrl: string().url().nullable(),
7910
+ logoHeightPx: number$1().int().positive()
7911
+ })
7912
+ });
7913
+ object({
7914
+ values: record(string(), unknown()),
7915
+ website: string().max(200).optional()
7916
+ });
7917
+ object({ ok: literal(true) });
7918
+ const isoDateTime = string().datetime();
7919
+ const sha256Hex = string().regex(/^[a-f0-9]{64}$/, "Expected a lowercase hex sha256 digest");
7920
+ /**
7921
+ * A single entry in a deploy's file tree, as served to the dashboard. Carries
7922
+ * no contents: `id` is a stable, path-derived handle used for selection and
7923
+ * `?file=` deep links; `hash` is the content address used to fetch the bytes
7924
+ * lazily and to cache them immutably in the browser.
7925
+ */
7926
+ const ProjectFileSummarySchema = object({
7927
+ id: string(),
7928
+ path: string().min(1),
7929
+ hash: sha256Hex
7930
+ });
7931
+ /** Maps a runtime resource slug (agent/workflow/skill) to its source file path. */
7932
+ const ProjectSourceResourceRefSchema = object({
7933
+ slug: string().min(1),
7934
+ path: string().min(1)
7935
+ });
7936
+ const ProjectSourceResourcesSchema = object({
7937
+ agents: array(ProjectSourceResourceRefSchema).default([]),
7938
+ workflows: array(ProjectSourceResourceRefSchema).default([]),
7939
+ skills: array(ProjectSourceResourceRefSchema).default([])
7940
+ });
7941
+ const emptyResources = () => ({
7942
+ agents: [],
7943
+ workflows: [],
7944
+ skills: []
7945
+ });
7946
+ object({
7947
+ artifactId: string().nullable(),
7948
+ files: array(ProjectFileSummarySchema),
7949
+ resources: ProjectSourceResourcesSchema.default(emptyResources())
7950
+ });
7951
+ object({
7952
+ path: string().min(1),
7953
+ contents: string(),
7954
+ hash: sha256Hex
7955
+ });
7956
+ object({ blobs: array(object({
7957
+ hash: sha256Hex,
7958
+ size: number$1().int().nonnegative()
7959
+ })) });
7960
+ object({ uploads: array(object({
7961
+ hash: sha256Hex,
7962
+ url: string().url()
7963
+ })) });
7964
+ object({ files: array(object({
7965
+ path: string().min(1),
7966
+ hash: sha256Hex
7967
+ })) });
7968
+ object({
7969
+ ok: literal(true),
7970
+ fileCount: number$1().int().nonnegative()
7971
+ });
7972
+ object({
7973
+ files: array(object({
7974
+ id: string(),
7975
+ path: string().min(1),
7976
+ hash: sha256Hex
7977
+ })),
7978
+ generatedAt: isoDateTime
7979
+ });
7980
+ /** A single source file returned by the bulk active-source download endpoint. */
7981
+ const DownloadActiveProjectSourceFileSchema = object({
7982
+ path: string().min(1),
7983
+ contents: string()
7984
+ });
7985
+ object({
7986
+ artifactId: string(),
7987
+ files: array(DownloadActiveProjectSourceFileSchema)
7988
+ });
7989
+ object({
7990
+ projectId: string(),
7991
+ artifactId: string(),
7992
+ pulledAt: string().datetime()
7993
+ });
7994
+ object({ files: array(object({
7995
+ id: string(),
7996
+ path: string().min(1)
7997
+ })) });
7998
+ object({ files: array(object({
7999
+ id: string(),
8000
+ path: string().min(1)
8001
+ })) });
7791
8002
  record(string(), unknown());
7792
8003
  //#endregion
7793
8004
  //#region src/runtime.ts
@@ -7839,10 +8050,22 @@ const RUNTIME_ENV_KEYS = [
7839
8050
  "REDIS_URL",
7840
8051
  "KEYSTROKE_QUEUE_PREFIX"
7841
8052
  ];
8053
+ /**
8054
+ * Observability ingest config for org workers (PostHog error tracking + crash reports).
8055
+ * Ingest tokens only — never forward `POSTHOG_API_KEY` (management) into workers.
8056
+ */
8057
+ const OBSERVABILITY_ENV_KEYS = [
8058
+ "POSTHOG_PROJECT_TOKEN",
8059
+ "POSTHOG_HOST",
8060
+ "POSTHOG_FLUSH_MODE",
8061
+ "KEYSTROKE_ENVIRONMENT",
8062
+ "KEYSTROKE_RELEASE"
8063
+ ];
7842
8064
  /** Env keys that must never be forwarded into untrusted org workers. */
7843
8065
  const FORBIDDEN_WORKER_ENV_KEYS = [
7844
8066
  "BETTER_AUTH_SECRET",
7845
8067
  "DATABASE_URL",
8068
+ "POSTHOG_API_KEY",
7846
8069
  "POSTGRES_PASSWORD",
7847
8070
  "PLATFORM_WORKER_TOKEN",
7848
8071
  "STRIPE_SECRET_KEY",
@@ -7886,6 +8109,11 @@ function buildRuntimeEnv(source, artifacts, database, extraEnv) {
7886
8109
  if (!value) continue;
7887
8110
  entries.set(key, value);
7888
8111
  }
8112
+ for (const key of OBSERVABILITY_ENV_KEYS) {
8113
+ const value = source[key]?.trim();
8114
+ if (!value) continue;
8115
+ entries.set(key, value);
8116
+ }
7889
8117
  if (!extraEnv) for (const key of PROVIDER_ENV_KEYS) {
7890
8118
  const value = source[key]?.trim();
7891
8119
  if (value) entries.set(key, value);