@keystrokehq/hosting 0.1.7 → 0.1.9

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.cjs CHANGED
@@ -34,6 +34,10 @@ const PROJECT_SERVER_HEALTH = {
34
34
  path: "/health",
35
35
  port: PROJECT_SERVER_PORT
36
36
  };
37
+ const PROJECT_SERVER_DEPLOY_STATUS = {
38
+ path: "/deploy-status",
39
+ port: PROJECT_SERVER_PORT
40
+ };
37
41
  //#endregion
38
42
  //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/core.js
39
43
  var _a$1;
@@ -2299,6 +2303,21 @@ function handleReadonlyResult(payload) {
2299
2303
  payload.value = Object.freeze(payload.value);
2300
2304
  return payload;
2301
2305
  }
2306
+ const $ZodLazy = /* @__PURE__ */ $constructor("$ZodLazy", (inst, def) => {
2307
+ $ZodType.init(inst, def);
2308
+ defineLazy(inst._zod, "innerType", () => {
2309
+ const d = def;
2310
+ if (!d._cachedInner) d._cachedInner = def.getter();
2311
+ return d._cachedInner;
2312
+ });
2313
+ defineLazy(inst._zod, "pattern", () => inst._zod.innerType?._zod?.pattern);
2314
+ defineLazy(inst._zod, "propValues", () => inst._zod.innerType?._zod?.propValues);
2315
+ defineLazy(inst._zod, "optin", () => inst._zod.innerType?._zod?.optin ?? void 0);
2316
+ defineLazy(inst._zod, "optout", () => inst._zod.innerType?._zod?.optout ?? void 0);
2317
+ inst._zod.parse = (payload, ctx) => {
2318
+ return inst._zod.innerType._zod.run(payload, ctx);
2319
+ };
2320
+ });
2302
2321
  const $ZodCustom = /* @__PURE__ */ $constructor("$ZodCustom", (inst, def) => {
2303
2322
  $ZodCheck.init(inst, def);
2304
2323
  $ZodType.init(inst, def);
@@ -3441,6 +3460,12 @@ const optionalProcessor = (schema, ctx, _json, params) => {
3441
3460
  const seen = ctx.seen.get(schema);
3442
3461
  seen.ref = def.innerType;
3443
3462
  };
3463
+ const lazyProcessor = (schema, ctx, _json, params) => {
3464
+ const innerType = schema._zod.innerType;
3465
+ process$1(innerType, ctx, params);
3466
+ const seen = ctx.seen.get(schema);
3467
+ seen.ref = innerType;
3468
+ };
3444
3469
  //#endregion
3445
3470
  //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/iso.js
3446
3471
  const ZodISODateTime = /* @__PURE__ */ $constructor("ZodISODateTime", (inst, def) => {
@@ -4304,6 +4329,18 @@ function readonly(innerType) {
4304
4329
  innerType
4305
4330
  });
4306
4331
  }
4332
+ const ZodLazy = /* @__PURE__ */ $constructor("ZodLazy", (inst, def) => {
4333
+ $ZodLazy.init(inst, def);
4334
+ ZodType.init(inst, def);
4335
+ inst._zod.processJSONSchema = (ctx, json, params) => lazyProcessor(inst, ctx, json, params);
4336
+ inst.unwrap = () => inst._zod.def.getter();
4337
+ });
4338
+ function lazy(getter) {
4339
+ return new ZodLazy({
4340
+ type: "lazy",
4341
+ getter
4342
+ });
4343
+ }
4307
4344
  const ZodCustom = /* @__PURE__ */ $constructor("ZodCustom", (inst, def) => {
4308
4345
  $ZodCustom.init(inst, def);
4309
4346
  ZodType.init(inst, def);
@@ -4979,10 +5016,244 @@ const AppSlugSchema = ProjectSlugSchema;
4979
5016
  function resolveExplicitPublicPlatformOrigin(env = process.env) {
4980
5017
  return env.PUBLIC_PLATFORM_URL?.replace(/\/$/, "") || void 0;
4981
5018
  }
5019
+ /** How a credential instance is stored (`credential_instances.auth_kind`). */
5020
+ const CredentialAuthKindSchema = _enum([
5021
+ "api_key",
5022
+ "oauth_managed",
5023
+ "keystroke"
5024
+ ]);
5025
+ /**
5026
+ * Where a credential instance is stored (`credential_instances.scope_type`), and the only thing an
5027
+ * action/tool can pin via `.scope(...)`. There is no resolution chain: when no scope is pinned, the
5028
+ * resolver tries the project default, then the org default, then throws.
5029
+ */
5030
+ const CredentialScopeTypeSchema = _enum([
5031
+ "organization",
5032
+ "project",
5033
+ "user"
5034
+ ]);
5035
+ CredentialAuthKindSchema.options;
5036
+ CredentialScopeTypeSchema.options;
5037
+ /** Non-empty human-readable label or description (trimmed). */
5038
+ const requiredDisplayTextSchema = string().trim().min(1);
5039
+ /**
5040
+ * Structural workflow-canvas graph contract.
5041
+ *
5042
+ * This is the deterministic skeleton the deploy-time AST producer emits for a
5043
+ * workflow (nodes + edges), plus the manifest-derived trigger-source nodes. It
5044
+ * is the single source of truth shared by:
5045
+ * - the AST producer (emits it at deploy, stored with the manifest),
5046
+ * - the platform route that serves the canvas, and
5047
+ * - the SDK / web client that renders it (React Flow).
5048
+ *
5049
+ * Only the structural skeleton lives here. The LLM enrichment + run-overlay
5050
+ * envelope types live in `workflow-canvas-envelope.ts`; the SDK re-exports them.
5051
+ * See WORKFLOW.md (§4 grammar, §8 node ids, §9 caching).
5052
+ */
5053
+ /**
5054
+ * Canvas node taxonomy — the single discriminator for every canvas node. The
5055
+ * client derives the React Flow component, icon, and per-node treatment from it
5056
+ * (no parallel `type` / `data.kind` fields), and the producer + fixtures emit it
5057
+ * directly, so the structural contract can never silently diverge across the
5058
+ * deploy → render boundary.
5059
+ * - Boundaries: `entry` (Start, owns input) · `exit` (Output, owns output) ·
5060
+ * `error` (a terminal `throw` — an error output that ends the run on a branch)
5061
+ * - Callable: `step` (action / agent / llm / hook / child-workflow invocation) —
5062
+ * the invocation flavor lives in {@link WorkflowCanvasCallKind}
5063
+ * - Structural control flow: `code-block` · `decision` · `merge` · `loop` ·
5064
+ * `parallel` (group containers) · `loop-start` (the group body's entry marker,
5065
+ * shared by loop + parallel)
5066
+ * - Upstream of entry: `trigger-source` (one per manifest trigger attachment)
5067
+ *
5068
+ * `Promise.all([...])` is modeled as a `parallel` group container: the branches
5069
+ * are stacked inside and the container itself is the single prong leaving the
5070
+ * wrapper (there is no separate fork/join pair).
5071
+ *
5072
+ * `exit` and `error` are both terminals: a `return` flows to the shared `exit`
5073
+ * (the workflow output), while a `throw` gets its own `error` terminal off the
5074
+ * branch so guard clauses (`if (bad) throw …`) read as a visible dead-end.
5075
+ */
5076
+ const WorkflowCanvasNodeTypeSchema = _enum([
5077
+ "entry",
5078
+ "exit",
5079
+ "error",
5080
+ "step",
5081
+ "code-block",
5082
+ "decision",
5083
+ "merge",
5084
+ "loop",
5085
+ "parallel",
5086
+ "loop-start",
5087
+ "trigger-source"
5088
+ ]);
5089
+ _enum([
5090
+ "workflow-step",
5091
+ "agent",
5092
+ "llm",
5093
+ "wait",
5094
+ "hook",
5095
+ "tool",
5096
+ "child-workflow"
5097
+ ]);
5098
+ /** A labeled branch output on a decision-style node. */
5099
+ const WorkflowCanvasNodeOutputSchema = object({
5100
+ id: string(),
5101
+ label: string()
5102
+ });
5103
+ /**
5104
+ * A step input's configured value at its call site, captured deterministically
5105
+ * by the producer from the call's argument object. The platform join turns this
5106
+ * into the inspector's {@link WorkflowNodeInputBinding} (filling display labels).
5107
+ */
5108
+ const WorkflowCanvasRawBindingSchema = object({
5109
+ tokens: array(discriminatedUnion("kind", [
5110
+ object({
5111
+ kind: literal("text"),
5112
+ text: string()
5113
+ }),
5114
+ object({
5115
+ kind: literal("reference"),
5116
+ /** Upstream node id this value flows from; absent only for unresolved refs. */
5117
+ sourceNodeId: string().optional(),
5118
+ /** Output field of the source (dotted path); omitted = the whole output. */
5119
+ field: string().optional()
5120
+ }),
5121
+ object({
5122
+ kind: literal("variable"),
5123
+ text: string()
5124
+ }),
5125
+ object({
5126
+ kind: literal("call"),
5127
+ name: string()
5128
+ })
5129
+ ])),
5130
+ /** Render as a tall multi-line box (object/array/multiline template values). */
5131
+ multiline: boolean().optional()
5132
+ });
5133
+ /**
5134
+ * Statically-captured `promptLlm` options for an `llm` step node. Literal-only:
5135
+ * dynamic/expression values (a computed model, a `system` built by a function) are
5136
+ * not captured; `system`/`outputSchema` record presence so the inspector can note
5137
+ * "a system prompt is configured" / "structured output" without their values.
5138
+ */
5139
+ const WorkflowCanvasLlmOptionsSchema = object({
5140
+ model: string().optional(),
5141
+ maxTokens: number$1().optional(),
5142
+ temperature: number$1().optional(),
5143
+ thinkingLevel: string().optional(),
5144
+ hasSystemPrompt: boolean().optional(),
5145
+ hasOutputSchema: boolean().optional()
5146
+ });
5147
+ const WorkflowCanvasNodeDataSchema = object({
5148
+ label: string(),
5149
+ /** Set on group nodes (loop / parallel section containers). */
5150
+ groupKind: _enum([
5151
+ "loop",
5152
+ "parallel",
5153
+ "conditional"
5154
+ ]).optional(),
5155
+ description: string().optional(),
5156
+ /** {@link WorkflowCanvasCallKind} or a looser raw call-site label. */
5157
+ callKind: string().optional(),
5158
+ /**
5159
+ * App/integration slug for a `step` whose action/agent is imported directly
5160
+ * from a `@keystrokehq/<app>` package (e.g. "slack", "apollo"). Lets the client
5161
+ * badge the node with that app's logo; absent for custom (project-local)
5162
+ * actions, which fall back to the call-kind icon.
5163
+ */
5164
+ appSlug: string().optional(),
5165
+ /** Cron/webhook/poll discriminator on trigger-source nodes. */
5166
+ triggerType: string().optional(),
5167
+ /** Branch outputs (decision nodes). */
5168
+ outputs: array(WorkflowCanvasNodeOutputSchema).optional(),
5169
+ /**
5170
+ * Action/agent/workflow slug resolved at deploy time (via import → definition).
5171
+ * Optional when the deploy build cannot resolve source (dist-only artifacts).
5172
+ */
5173
+ slug: string().optional(),
5174
+ /**
5175
+ * Durable call-site ids nested inside an off-grammar `code-block` (same-file only).
5176
+ * Used by the run overlay to light the block when any contained step executes.
5177
+ */
5178
+ containedCallSiteIds: array(string()).optional(),
5179
+ /**
5180
+ * Per-input call-site value bindings for `step` nodes, keyed by input field name.
5181
+ * Deterministically captured from the call's argument object; reference tokens point
5182
+ * at the upstream node that produced the value. The platform join fills display labels.
5183
+ */
5184
+ inputBindings: record(string(), WorkflowCanvasRawBindingSchema).optional(),
5185
+ /**
5186
+ * Static `promptLlm(prompt, options)` configuration captured at the call site for
5187
+ * `llm` step nodes. Only literal values are captured (model/maxTokens/temperature/
5188
+ * thinkingLevel); `system`/`outputSchema` are usually expressions, so only their
5189
+ * presence is recorded. Absent when no options are statically resolvable.
5190
+ */
5191
+ llmOptions: WorkflowCanvasLlmOptionsSchema.optional()
5192
+ });
5193
+ /**
5194
+ * A single structural node. This is the deploy artifact's shape: identity
5195
+ * (`id`), the canonical discriminator (`nodeType`), display `data`, and group
5196
+ * nesting (`parentId`). All layout/rendering — React Flow component key,
5197
+ * positions, sizes, `extent`, group box dimensions — is derived entirely
5198
+ * client-side from this structure, so it never leaks into the wire contract.
5199
+ */
5200
+ const WorkflowCanvasGraphNodeSchema = object({
5201
+ id: string(),
5202
+ nodeType: WorkflowCanvasNodeTypeSchema,
5203
+ data: WorkflowCanvasNodeDataSchema,
5204
+ /** Set on children nested inside a group (loop / parallel) container. */
5205
+ parentId: string().optional()
5206
+ });
5207
+ const WorkflowCanvasEdgeSchema = object({
5208
+ id: string(),
5209
+ source: string(),
5210
+ target: string(),
5211
+ type: string().optional(),
5212
+ label: string().optional(),
5213
+ sourceHandle: string().optional(),
5214
+ targetHandle: string().optional(),
5215
+ data: object({ branchKind: _enum([
5216
+ "then",
5217
+ "else",
5218
+ "parallel-branch",
5219
+ "error"
5220
+ ]).optional() }).optional()
5221
+ });
5222
+ /** A statically-evaluable top-level `const` value (literal scalars only). */
5223
+ const WorkflowCanvasConstantValueSchema = union([
5224
+ string(),
5225
+ number$1(),
5226
+ boolean()
5227
+ ]);
5228
+ /**
5229
+ * Top-level `const NAME = <literal>` declarations in the workflow source, captured
5230
+ * at deploy. Lets the platform resolve `variable` value tokens (e.g. a `model` set
5231
+ * to a named const) to their concrete value for display. Scalars only — computed,
5232
+ * function-local, or non-literal consts are intentionally omitted.
5233
+ */
5234
+ const WorkflowCanvasConstantsSchema = record(string(), WorkflowCanvasConstantValueSchema);
5235
+ const WorkflowCanvasGraphSchema = object({
5236
+ nodes: array(WorkflowCanvasGraphNodeSchema),
5237
+ edges: array(WorkflowCanvasEdgeSchema),
5238
+ /** Top-level literal constants from the workflow source (for value-token resolution). */
5239
+ constants: WorkflowCanvasConstantsSchema.optional()
5240
+ });
5241
+ /**
5242
+ * Deploy-time summary of one credential a step requires, derived from the
5243
+ * action/agent-tool definition's `.credentials`. The workflow-canvas credential
5244
+ * overlay joins a step node's `slug` to these to resolve the bound instance.
5245
+ * `key` doubles as the app slug (matches `credential_instances.app_slug`).
5246
+ */
5247
+ const CredentialRequirementSummarySchema = object({
5248
+ key: string(),
5249
+ kind: CredentialAuthKindSchema,
5250
+ /** Scope pinned via `.scope(...)`; absent means project-default → org-default. */
5251
+ scope: CredentialScopeTypeSchema.optional()
5252
+ });
4982
5253
  const StoredRouteManifestSkillSchema = object({
4983
5254
  slug: string(),
4984
- name: string().optional(),
4985
- description: string().optional(),
5255
+ name: requiredDisplayTextSchema,
5256
+ description: requiredDisplayTextSchema,
4986
5257
  moduleFile: string()
4987
5258
  });
4988
5259
  const attachmentSchemasSchema = record(string(), object({
@@ -4990,8 +5261,8 @@ const attachmentSchemasSchema = record(string(), object({
4990
5261
  filterSchema: record(string(), unknown()).optional()
4991
5262
  }));
4992
5263
  const attachmentMetaSchema = record(string(), object({
4993
- name: string().optional(),
4994
- description: string().optional()
5264
+ name: requiredDisplayTextSchema,
5265
+ description: requiredDisplayTextSchema
4995
5266
  }));
4996
5267
  const storedRouteManifestEntryV2Schema = discriminatedUnion("kind", [
4997
5268
  object({ kind: literal("health") }),
@@ -4999,23 +5270,43 @@ const storedRouteManifestEntryV2Schema = discriminatedUnion("kind", [
4999
5270
  kind: literal("agent"),
5000
5271
  slug: string(),
5001
5272
  moduleFile: string(),
5002
- name: string().optional(),
5003
- description: string().optional(),
5273
+ name: requiredDisplayTextSchema,
5274
+ description: requiredDisplayTextSchema,
5004
5275
  model: string(),
5005
5276
  systemPrompt: string(),
5006
5277
  toolCount: number$1().int().nonnegative(),
5007
5278
  credentialCount: number$1().int().nonnegative(),
5008
5279
  appSlugs: array(string()).default([]),
5009
- toolSlugs: array(string()).default([])
5280
+ toolSlugs: array(string()).default([]),
5281
+ /** Credential requirements per tool slug (the agent's credential consumer key). */
5282
+ toolRequirements: record(string(), array(CredentialRequirementSummarySchema)).optional()
5283
+ }),
5284
+ object({
5285
+ kind: literal("action"),
5286
+ slug: string(),
5287
+ name: requiredDisplayTextSchema,
5288
+ description: requiredDisplayTextSchema,
5289
+ moduleFile: string(),
5290
+ /** App slug for actions imported from an integration package (`@keystrokehq/<app>/actions`). */
5291
+ appSlug: string().optional(),
5292
+ inputSchema: record(string(), unknown()),
5293
+ outputSchema: record(string(), unknown()),
5294
+ /** Credentials this action requires (for the canvas credential overlay). */
5295
+ requirements: array(CredentialRequirementSummarySchema).optional()
5010
5296
  }),
5011
5297
  object({
5012
5298
  kind: literal("workflow"),
5013
5299
  slug: string(),
5014
- name: string().optional(),
5015
- description: string().optional(),
5300
+ name: requiredDisplayTextSchema,
5301
+ description: requiredDisplayTextSchema,
5016
5302
  subscribable: boolean(),
5017
5303
  moduleFile: string(),
5018
- requestSchema: record(string(), unknown())
5304
+ requestSchema: record(string(), unknown()),
5305
+ responseSchema: record(string(), unknown()).optional(),
5306
+ /** Deterministic AST control-flow skeleton (deploy-time producer). */
5307
+ flowGraph: WorkflowCanvasGraphSchema.optional(),
5308
+ /** sha256 of the workflow source the `flowGraph` was produced from (staleness). */
5309
+ flowGraphSourceHash: string().optional()
5019
5310
  }),
5020
5311
  object({
5021
5312
  kind: literal("trigger-webhook"),
@@ -5034,8 +5325,8 @@ const storedRouteManifestEntryV2Schema = discriminatedUnion("kind", [
5034
5325
  moduleFile: string(),
5035
5326
  sourceHash: string().optional(),
5036
5327
  schedule: string(),
5037
- name: string().optional(),
5038
- description: string().optional()
5328
+ name: requiredDisplayTextSchema,
5329
+ description: requiredDisplayTextSchema
5039
5330
  }),
5040
5331
  object({
5041
5332
  kind: literal("trigger-poll-group"),
@@ -5051,8 +5342,8 @@ const storedRouteManifestEntryV2Schema = discriminatedUnion("kind", [
5051
5342
  moduleFile: string(),
5052
5343
  sourceHash: string().optional(),
5053
5344
  schedule: string(),
5054
- name: string().optional(),
5055
- description: string().optional()
5345
+ name: requiredDisplayTextSchema,
5346
+ description: requiredDisplayTextSchema
5056
5347
  })
5057
5348
  ]);
5058
5349
  object({
@@ -5478,24 +5769,6 @@ object({
5478
5769
  outputParameters: record(string(), unknown()).optional(),
5479
5770
  version: string().optional()
5480
5771
  });
5481
- /** How a credential instance is stored (`credential_instances.auth_kind`). */
5482
- const CredentialAuthKindSchema = _enum([
5483
- "api_key",
5484
- "oauth_managed",
5485
- "keystroke"
5486
- ]);
5487
- /**
5488
- * Where a credential instance is stored (`credential_instances.scope_type`), and the only thing an
5489
- * action/tool can pin via `.scope(...)`. There is no resolution chain: when no scope is pinned, the
5490
- * resolver tries the project default, then the org default, then throws.
5491
- */
5492
- const CredentialScopeTypeSchema = _enum([
5493
- "organization",
5494
- "project",
5495
- "user"
5496
- ]);
5497
- CredentialAuthKindSchema.options;
5498
- CredentialScopeTypeSchema.options;
5499
5772
  /** Scope of a platform app credential (maps to `credential_instances.scope_type`). */
5500
5773
  const AppCredentialScopeSchema = _enum([
5501
5774
  "user",
@@ -5511,6 +5784,8 @@ const nullableOptionalTimestamp = string().nullable().optional();
5511
5784
  object({
5512
5785
  id: string().min(1),
5513
5786
  appId: string().min(1),
5787
+ /** Stable per-scope identifier; pass to `--credential` to pin a specific instance. */
5788
+ slug: string().min(1),
5514
5789
  label: string().min(1),
5515
5790
  scope: AppCredentialScopeSchema,
5516
5791
  lastRefreshedAt: string().nullable(),
@@ -5667,7 +5942,11 @@ object({
5667
5942
  /** When set, platform MCP resolve checks credential assignments before scope defaults. */
5668
5943
  assignmentTarget: McpCredentialAssignmentTargetSchema.optional(),
5669
5944
  /** Tool/step consumer id for assignment lookup (action slug or workflow step correlation id). */
5670
- consumerId: string().trim().min(1).optional()
5945
+ consumerId: string().trim().min(1).optional(),
5946
+ /** Explicit credential instance slug; overrides default resolution to pick that instance. */
5947
+ credentialSlug: string().trim().min(1).optional(),
5948
+ /** Project slug (CLI --project); the platform resolves it to a project and binds that scope. */
5949
+ projectSlug: string().trim().min(1).optional()
5671
5950
  });
5672
5951
  object({
5673
5952
  error: _enum([
@@ -6491,7 +6770,7 @@ object({
6491
6770
  id: string(),
6492
6771
  slug: string(),
6493
6772
  name: string(),
6494
- description: string().nullable(),
6773
+ description: string().min(1),
6495
6774
  type: TriggerTypeSchema,
6496
6775
  status: TriggerStatusSchema,
6497
6776
  projectId: string(),
@@ -6787,7 +7066,7 @@ const AgentSummarySchema = object({
6787
7066
  name: string().min(1),
6788
7067
  projectId: string().min(1),
6789
7068
  updatedAt: string().min(1),
6790
- description: string().optional(),
7069
+ description: string().min(1),
6791
7070
  sourcePath: string().min(1).optional(),
6792
7071
  model: string().optional(),
6793
7072
  capabilities: object({
@@ -6809,7 +7088,7 @@ const WorkflowSummarySchema = object({
6809
7088
  name: string().min(1),
6810
7089
  projectId: string().min(1),
6811
7090
  updatedAt: string().min(1),
6812
- description: string().optional(),
7091
+ description: string().min(1),
6813
7092
  sourcePath: string().min(1).optional(),
6814
7093
  lastRunAt: optionalTimestamp
6815
7094
  });
@@ -6819,7 +7098,7 @@ const SkillSummarySchema = object({
6819
7098
  name: string().min(1),
6820
7099
  projectId: string().min(1),
6821
7100
  updatedAt: string().min(1),
6822
- description: string().optional(),
7101
+ description: string().min(1),
6823
7102
  sourcePath: string().min(1).optional()
6824
7103
  });
6825
7104
  AgentSummarySchema.nullable();
@@ -6928,6 +7207,245 @@ object({ files: array(object({
6928
7207
  id: string(),
6929
7208
  path: string().min(1)
6930
7209
  })) });
7210
+ /** Whether the overview is still being produced or finished. */
7211
+ const WorkflowOverviewStatusSchema = _enum(["generating", "ready"]);
7212
+ /** One phase of the guided-tour overview. */
7213
+ const WorkflowPhaseSchema = object({
7214
+ id: string(),
7215
+ title: string(),
7216
+ copy: string(),
7217
+ nodeIds: array(string())
7218
+ });
7219
+ object({
7220
+ status: WorkflowOverviewStatusSchema,
7221
+ summary: string(),
7222
+ phases: array(WorkflowPhaseSchema),
7223
+ hash: string(),
7224
+ generatedAt: string().nullable(),
7225
+ model: string()
7226
+ });
7227
+ /** Subset of JSON-Schema field types the dashboard form renders inline. */
7228
+ const WorkflowInputFieldTypeSchema = _enum([
7229
+ "string",
7230
+ "number",
7231
+ "boolean",
7232
+ "enum",
7233
+ "object",
7234
+ "array"
7235
+ ]);
7236
+ const WorkflowInputFieldSchema = lazy(() => object({
7237
+ key: string(),
7238
+ label: string(),
7239
+ type: WorkflowInputFieldTypeSchema,
7240
+ required: boolean(),
7241
+ description: string().optional(),
7242
+ placeholder: string().optional(),
7243
+ options: array(string()).optional(),
7244
+ default: union([
7245
+ string(),
7246
+ number$1(),
7247
+ boolean()
7248
+ ]).optional(),
7249
+ children: array(WorkflowInputFieldSchema).optional(),
7250
+ format: string().optional()
7251
+ }));
7252
+ object({
7253
+ schema: object({ fields: array(WorkflowInputFieldSchema) }),
7254
+ values: record(string(), unknown()).nullable()
7255
+ });
7256
+ object({ runId: string() });
7257
+ /** Annotation lifecycle: "generating" while the LLM pass streams in, then "ready". */
7258
+ const WorkflowCanvasStatusSchema = _enum(["generating", "ready"]);
7259
+ /** LLM-produced enrichment for a single skeleton node. */
7260
+ const WorkflowCanvasAnnotationSchema = object({
7261
+ label: string().optional(),
7262
+ description: string().optional()
7263
+ });
7264
+ /** The configured value of one input at this call site. */
7265
+ const WorkflowNodeInputBindingSchema = object({
7266
+ tokens: array(discriminatedUnion("kind", [
7267
+ object({
7268
+ kind: literal("text"),
7269
+ text: string()
7270
+ }),
7271
+ object({
7272
+ kind: literal("reference"),
7273
+ sourceNodeId: string().optional(),
7274
+ sourceLabel: string(),
7275
+ field: string().optional()
7276
+ }),
7277
+ object({
7278
+ kind: literal("variable"),
7279
+ text: string(),
7280
+ /** Concrete value when `text` resolves to a top-level literal constant. */
7281
+ resolvedValue: string().optional()
7282
+ }),
7283
+ object({
7284
+ kind: literal("call"),
7285
+ name: string()
7286
+ })
7287
+ ])),
7288
+ multiline: boolean().optional()
7289
+ });
7290
+ /** An inspector input with optional call-site binding. */
7291
+ const WorkflowCanvasNodeInputSchema = WorkflowInputFieldSchema.and(object({
7292
+ binding: WorkflowNodeInputBindingSchema.optional(),
7293
+ additional: boolean().optional()
7294
+ }));
7295
+ /** Authored, deterministic metadata for a single node. */
7296
+ const WorkflowCanvasNodeMetaSchema = object({
7297
+ kind: _enum([
7298
+ "action",
7299
+ "agent",
7300
+ "workflow",
7301
+ "llm",
7302
+ "trigger",
7303
+ "boundary"
7304
+ ]),
7305
+ slug: string(),
7306
+ name: string(),
7307
+ description: string().optional(),
7308
+ appSlug: string().optional(),
7309
+ inputs: array(WorkflowCanvasNodeInputSchema),
7310
+ outputs: array(WorkflowInputFieldSchema),
7311
+ requiredApps: array(string()).optional(),
7312
+ model: string().optional(),
7313
+ toolCount: number$1().int().nonnegative().optional()
7314
+ });
7315
+ object({
7316
+ graph: WorkflowCanvasGraphSchema,
7317
+ nodeMetadata: record(string(), WorkflowCanvasNodeMetaSchema),
7318
+ annotations: record(string(), WorkflowCanvasAnnotationSchema),
7319
+ status: WorkflowCanvasStatusSchema,
7320
+ hash: string(),
7321
+ generatedAt: string().nullable(),
7322
+ model: string()
7323
+ });
7324
+ const WorkflowCanvasNodeRunStateSchema = object({
7325
+ status: _enum([
7326
+ "pending",
7327
+ "running",
7328
+ "succeeded",
7329
+ "failed",
7330
+ "skipped"
7331
+ ]),
7332
+ iteration: object({
7333
+ index: number$1().int().nonnegative(),
7334
+ total: number$1().int().nonnegative()
7335
+ }).optional()
7336
+ });
7337
+ /** Overall lifecycle of a run as the canvas animates it. */
7338
+ const WorkflowCanvasRunStatusSchema = _enum([
7339
+ "running",
7340
+ "succeeded",
7341
+ "failed",
7342
+ "canceled"
7343
+ ]);
7344
+ object({
7345
+ runId: string(),
7346
+ status: WorkflowCanvasRunStatusSchema,
7347
+ startedAt: string(),
7348
+ finishedAt: string().nullable(),
7349
+ nodeStates: record(string(), WorkflowCanvasNodeRunStateSchema)
7350
+ });
7351
+ /** Scope a credential instance lives in. */
7352
+ const WorkflowCredentialScopeSchema = _enum([
7353
+ "organization",
7354
+ "project",
7355
+ "user"
7356
+ ]);
7357
+ /** The concrete credential instance a binding currently resolves to. */
7358
+ const WorkflowResolvedCredentialSchema = object({
7359
+ id: string(),
7360
+ name: string(),
7361
+ scope: WorkflowCredentialScopeSchema,
7362
+ appSlug: string().optional(),
7363
+ isDefault: boolean().optional(),
7364
+ projectId: string().optional(),
7365
+ projectName: string().optional()
7366
+ });
7367
+ record(string(), WorkflowCanvasAnnotationSchema);
7368
+ /** One opaque code-block the annotation pass should label, keyed by its canvas node id. */
7369
+ const WorkflowCanvasAnnotationCodeBlockSchema = object({
7370
+ nodeId: string(),
7371
+ /** The raw source snippet (the node's label) the LLM turns into human copy. */
7372
+ source: string()
7373
+ });
7374
+ /** Inputs the worker feeds the LLM for the gated code-block annotation pass. */
7375
+ const WorkflowCanvasAnnotationsInputSchema = object({
7376
+ workflowName: string(),
7377
+ workflowDescription: string().nullable(),
7378
+ codeBlocks: array(WorkflowCanvasAnnotationCodeBlockSchema)
7379
+ });
7380
+ object({
7381
+ workflowId: string(),
7382
+ projectId: string(),
7383
+ hash: string(),
7384
+ model: string(),
7385
+ input: WorkflowCanvasAnnotationsInputSchema
7386
+ });
7387
+ /** One node as the overview LLM sees it (derived from the canvas node metadata + graph). */
7388
+ const WorkflowOverviewNodeSchema = object({
7389
+ nodeId: string(),
7390
+ label: string(),
7391
+ kind: string(),
7392
+ description: string().optional(),
7393
+ /** App/integration slug for steps imported from a `@keystrokehq/<app>` package. */
7394
+ appSlug: string().optional(),
7395
+ /** Authored input field keys (from the action/agent/workflow definition). */
7396
+ inputs: array(string()).optional(),
7397
+ /** Authored output field keys. */
7398
+ outputs: array(string()).optional(),
7399
+ /** Agent-only: the model the agent runs on. */
7400
+ model: string().optional(),
7401
+ /** Agent-only: number of tools available to the agent. */
7402
+ toolCount: number$1().int().nonnegative().optional()
7403
+ });
7404
+ /** Inputs the worker feeds the LLM to produce the workflow overview (summary + phases). */
7405
+ const WorkflowOverviewInputSchema = object({
7406
+ workflowName: string(),
7407
+ workflowDescription: string().nullable(),
7408
+ /** Display labels of the trigger sources upstream of the workflow (read-only context). */
7409
+ triggers: array(string()),
7410
+ nodes: array(WorkflowOverviewNodeSchema),
7411
+ /** The workflow's TypeScript source (best-effort; null when the deploy has no source snapshot). */
7412
+ source: string().nullable()
7413
+ });
7414
+ object({
7415
+ workflowId: string(),
7416
+ projectId: string(),
7417
+ hash: string(),
7418
+ model: string(),
7419
+ input: WorkflowOverviewInputSchema
7420
+ });
7421
+ const WorkflowCanvasCredentialBindingBaseSchema = object({
7422
+ credentialKey: string(),
7423
+ label: string(),
7424
+ appSlug: string().optional()
7425
+ });
7426
+ /** How one credential requirement on a step currently resolves. */
7427
+ const WorkflowCanvasCredentialBindingSchema = union([
7428
+ WorkflowCanvasCredentialBindingBaseSchema.extend({
7429
+ policy: _enum([
7430
+ "project-default",
7431
+ "org-default",
7432
+ "assigned"
7433
+ ]),
7434
+ instance: WorkflowResolvedCredentialSchema
7435
+ }),
7436
+ WorkflowCanvasCredentialBindingBaseSchema.extend({
7437
+ policy: literal("scope-pinned"),
7438
+ pinnedScope: WorkflowCredentialScopeSchema,
7439
+ instance: WorkflowResolvedCredentialSchema
7440
+ }),
7441
+ WorkflowCanvasCredentialBindingBaseSchema.extend({
7442
+ policy: literal("unresolved"),
7443
+ reason: _enum(["needs-selection", "missing"]),
7444
+ pinnedScope: WorkflowCredentialScopeSchema.optional()
7445
+ })
7446
+ ]);
7447
+ record(string(), array(WorkflowCanvasCredentialBindingSchema));
7448
+ record(string(), unknown());
6931
7449
  //#endregion
6932
7450
  //#region src/runtime.ts
6933
7451
  /** Builds base64 `KEYSTROKE_ORG_ARTIFACTS` payload for org worker containers. */
@@ -7247,8 +7765,29 @@ async function pingProjectTarget(target, options = {}) {
7247
7765
  });
7248
7766
  }
7249
7767
  //#endregion
7768
+ //#region src/deploy-status.ts
7769
+ /**
7770
+ * Ask a running org machine which projects bootstrapped and which failed.
7771
+ * Best-effort: returns undefined on any error so callers can fall back to
7772
+ * treating every project as healthy (preserving pre-existing behavior).
7773
+ */
7774
+ async function fetchDeployStatus(baseUrl, options = {}) {
7775
+ const timeoutMs = options.timeoutMs ?? 15e3;
7776
+ try {
7777
+ const response = await (options.fetchImpl ?? fetch)(new URL(PROJECT_SERVER_DEPLOY_STATUS.path, baseUrl), { signal: AbortSignal.timeout(timeoutMs) });
7778
+ if (!response.ok) return;
7779
+ const data = await response.json();
7780
+ if (!data || !Array.isArray(data.projects)) return;
7781
+ return data;
7782
+ } catch (error) {
7783
+ console.warn(`[deploy-status] failed to fetch from ${baseUrl}:`, error);
7784
+ return;
7785
+ }
7786
+ }
7787
+ //#endregion
7250
7788
  exports.DEV_PLATFORM_WORKER_TOKEN = DEV_PLATFORM_WORKER_TOKEN;
7251
7789
  exports.PROJECT_DATABASE_ENV_KEYS = PROJECT_DATABASE_ENV_KEYS;
7790
+ exports.PROJECT_SERVER_DEPLOY_STATUS = PROJECT_SERVER_DEPLOY_STATUS;
7252
7791
  exports.PROJECT_SERVER_FRAMEWORK_NODE_MODULES = PROJECT_SERVER_FRAMEWORK_NODE_MODULES;
7253
7792
  exports.PROJECT_SERVER_FRAMEWORK_ROOT = PROJECT_SERVER_FRAMEWORK_ROOT;
7254
7793
  exports.PROJECT_SERVER_HEALTH = PROJECT_SERVER_HEALTH;
@@ -7262,6 +7801,7 @@ exports.canPingProjectTarget = canPingProjectTarget;
7262
7801
  exports.defaultHostingPlugin = defaultHostingPlugin;
7263
7802
  exports.dockerPlugin = dockerPlugin;
7264
7803
  exports.encodeOrgArtifacts = encodeOrgArtifacts;
7804
+ exports.fetchDeployStatus = fetchDeployStatus;
7265
7805
  exports.formatDockerEnv = formatDockerEnv;
7266
7806
  exports.parseOrgArtifactsFromEnv = parseOrgArtifactsFromEnv;
7267
7807
  exports.pingProject = pingProject;