@keystrokehq/cli 0.0.23 → 0.0.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +8 -0
  2. package/dist/{agent-manifest-Pg0aURo7.mjs → agent-manifest-UbtgIIhN.mjs} +1 -1
  3. package/dist/{agents-Ccw0IZCx.mjs → agents-B57hZo0M.mjs} +3 -3
  4. package/dist/{build-agents-DseUtzd4-DFh2e5Cn.mjs → build-agents-DseUtzd4-C6S-h9Gi.mjs} +1 -1
  5. package/dist/{build-progress-nYa14iBP.mjs → build-progress-O9f-4Z4D.mjs} +1 -1
  6. package/dist/{build.handler-ChqSwsT_.mjs → build.handler-Bd2x92wh.mjs} +2 -2
  7. package/dist/{credentials-CELZ0QHu.mjs → credentials-CJpJ5qmL.mjs} +4 -4
  8. package/dist/{current-deployment-workflow-CnzlDCBv.mjs → current-deployment-workflow-DupXGMGV.mjs} +3 -3
  9. package/dist/{deploy-Cn3jN7Rl.mjs → deploy-CPhSW3cB.mjs} +1 -1
  10. package/dist/{deploy-progress-Dlp9aBDW.mjs → deploy-progress-C1Y73QVM.mjs} +1 -1
  11. package/dist/{deploy.handler-BikVS9ER.mjs → deploy.handler-C_Wc90KP.mjs} +7 -7
  12. package/dist/{diff.handler-C3EWVBOj.mjs → diff.handler-jJEIJq41.mjs} +1 -1
  13. package/dist/{dist-Br4m3sFZ.mjs → dist-BGYSbs2V.mjs} +1 -1
  14. package/dist/{env.handler-BuFdzUoX.mjs → env.handler-BbH44f51.mjs} +1 -1
  15. package/dist/{init-6tGGTpYO.mjs → init-DonAqdBg.mjs} +1 -1
  16. package/dist/{init.handler-Dcg9MOqx.mjs → init.handler-C60qFTIV.mjs} +32 -9
  17. package/dist/{inspect.handler-BN6p2hI_.mjs → inspect.handler-jtSz17z5.mjs} +1 -1
  18. package/dist/keystroke.mjs +9 -9
  19. package/dist/{list.handler-fcyAKTQe.mjs → list.handler-BapLGgXO.mjs} +2 -2
  20. package/dist/{list.handler-cK8Y-daR.mjs → list.handler-ClrceojF.mjs} +1 -1
  21. package/dist/{requirements.handler-ZZfHV6f0.mjs → requirements.handler-BXFoxG3f.mjs} +1 -1
  22. package/dist/{run-polling-3XOGl4hh.mjs → run-polling-DEO0A7ec.mjs} +1 -1
  23. package/dist/{run.handler-xeUVmlFk.mjs → run.handler-itMzf36_.mjs} +2 -2
  24. package/dist/{skill-installer-Cm9hF6OB.mjs → skill-installer-AX0X-u1J.mjs} +5 -15
  25. package/dist/{skills-sync.handler-09mDbx5q.mjs → skills-sync.handler-DsJP_-XZ.mjs} +1 -1
  26. package/dist/{skills.command-DGIIIRX_.mjs → skills.command-B6jly3ew.mjs} +1 -1
  27. package/dist/{spinner-progress-BtEIJRX4.mjs → spinner-progress-lrKDs4YF.mjs} +1 -0
  28. package/dist/{sync-BlmgsC2W.mjs → sync-B1hBmhJM.mjs} +1 -1
  29. package/dist/{sync.handler-xVxeG-S0.mjs → sync.handler-B9Q_6jI8.mjs} +4 -4
  30. package/dist/{test-cuU0rf9C.mjs → test-BeSgMl0z.mjs} +1 -1
  31. package/dist/{test.handler-B_C-T_IM.mjs → test.handler-DxEIHSy2.mjs} +4 -4
  32. package/dist/{tool.handler-CmpzYYiC.mjs → tool.handler-CjjbaZJB.mjs} +4 -4
  33. package/dist/{upload.handler-81mbKHTY.mjs → upload.handler-ZSOVDEdc.mjs} +1 -1
  34. package/dist/{validate.handler-CWG5HyO3.mjs → validate.handler-zJIDu4gG.mjs} +2 -2
  35. package/dist/{workflow-build-CVG4DSCw.mjs → workflow-build-BIRjDduX.mjs} +2 -2
  36. package/dist/{workflows-eztTnue4.mjs → workflows--ulcsX9G.mjs} +9 -9
  37. package/package.json +9 -9
  38. package/AGENTS-blurb.md +0 -123
package/README.md CHANGED
@@ -46,6 +46,14 @@ keystroke deploy
46
46
 
47
47
  Most project commands auto-discover `keystroke.config.ts` from the current working directory. Pass `--path <dir>` when you want to run against another project directory.
48
48
 
49
+ ## Command Guidelines
50
+
51
+ - Keep command modules focused on CLI parsing, user interaction, and orchestration.
52
+ - Move reusable logic into packages instead of hiding it in CLI commands.
53
+ - Validate inputs at command boundaries and prefer shared schemas when contracts cross package boundaries.
54
+ - Keep command output predictable and script-friendly; use explicit `console.info`, `console.warn`, or `console.error`.
55
+ - Do not introduce root barrel imports or package boundary violations to make CLI wiring convenient.
56
+
49
57
  ## Authentication
50
58
 
51
59
  Start the device flow:
@@ -35,7 +35,7 @@ const CredentialSetProxyConfigSchema = z.object({
35
35
  hostPatterns: z.array(z.string().min(1)).optional(),
36
36
  injection: CredentialSetProxyInjectionSchema.optional()
37
37
  });
38
- const CredentialDefinitionIdSchema = z.string().trim().min(1).max(255).refine((value) => /^[a-zA-Z0-9_-]+$/.test(value), { error: "resolvedId must be a valid credential definition id (e.g. \"slack\")" });
38
+ const CredentialDefinitionIdSchema = z.string().trim().min(1).max(255).refine((value) => /^[a-zA-Z0-9_:-]+$/.test(value), { error: "resolvedId must be a valid credential definition id (e.g. \"slack\" or \"keystroke:slack\")" });
39
39
  const McpTransportSchema = z.discriminatedUnion("type", [
40
40
  z.object({
41
41
  type: z.literal("stdio"),
@@ -4,10 +4,10 @@ import { a as ui, j as throwReportedCliExit, n as style, t as ANSI, y as toError
4
4
  import { i as projects } from "./dist-D_KgdxW5.mjs";
5
5
  import { i as writeJson, n as JsonOptionSchema, t as JSON_OPTION_CONFIG } from "./output-BWcVRt-T.mjs";
6
6
  import { t as createTypedCommand } from "./commander-BTMzBiLq.mjs";
7
- import { i as readAgentManifestsFromOutDir } from "./dist-Br4m3sFZ.mjs";
7
+ import { i as readAgentManifestsFromOutDir } from "./dist-BGYSbs2V.mjs";
8
8
  import { t as requireWorkflowsDir } from "./resolve-project-DJJZIOmu.mjs";
9
- import { t as createSpinnerProgress } from "./spinner-progress-BtEIJRX4.mjs";
10
- import { a as runWorkflowBuild, n as renderBuildFailure } from "./workflow-build-CVG4DSCw.mjs";
9
+ import { t as createSpinnerProgress } from "./spinner-progress-lrKDs4YF.mjs";
10
+ import { a as runWorkflowBuild, n as renderBuildFailure } from "./workflow-build-BIRjDduX.mjs";
11
11
  import { i as resolveTypeHint } from "./schema-display-XrRCdFL0.mjs";
12
12
  import { z } from "zod";
13
13
  //#region src/commands/agents/inspect-display.ts
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { n as readOptionalJsonSchemaKeys, t as manifestToDeclaredCredentialRequirement } from "./declared-credential-requirements-B6h4WRv4.mjs";
4
- import { t as AgentVersionManifestSchema } from "./agent-manifest-Pg0aURo7.mjs";
4
+ import { t as AgentVersionManifestSchema } from "./agent-manifest-UbtgIIhN.mjs";
5
5
  import { i as createAgentSandboxPackage, n as AGENT_VM_PI_SKILLS_ROOT, r as AGENT_VM_TOOLS_RUNTIME_RELATIVE_PATH, t as AGENT_VM_HOST_CALL_RELATIVE_PATH } from "./agent-bundle-package-DWV6B_5q-B-qzc3zC.mjs";
6
6
  import { t as readCredentialKeysFromSchemaObject } from "./read-credential-keys-77a91T8M-aLuQvlIq.mjs";
7
7
  import { t as bundleSandboxAgentTarget } from "./workflow-bundler-BzHk73PM-xQwAF08W.mjs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { P as logger } from "./keystroke.mjs";
4
- import { n as formatProgressDuration, t as createSpinnerProgress } from "./spinner-progress-BtEIJRX4.mjs";
4
+ import { n as formatProgressDuration, t as createSpinnerProgress } from "./spinner-progress-lrKDs4YF.mjs";
5
5
  //#region src/lib/build-progress.ts
6
6
  const NEW_STAGE_LABELS = {
7
7
  start: "Starting build",
@@ -3,8 +3,8 @@
3
3
  import { D as CliExitError } from "./keystroke.mjs";
4
4
  import { i as projects } from "./dist-D_KgdxW5.mjs";
5
5
  import { t as requireWorkflowsDir } from "./resolve-project-DJJZIOmu.mjs";
6
- import { a as runWorkflowBuild, i as renderBuildSummary, n as renderBuildFailure, r as renderBuildHeader } from "./workflow-build-CVG4DSCw.mjs";
7
- import { t as createBuildProgress } from "./build-progress-nYa14iBP.mjs";
6
+ import { a as runWorkflowBuild, i as renderBuildSummary, n as renderBuildFailure, r as renderBuildHeader } from "./workflow-build-BIRjDduX.mjs";
7
+ import { t as createBuildProgress } from "./build-progress-O9f-4Z4D.mjs";
8
8
  import { t as withErrorBoundary } from "./error-boundary-DVZipk-A.mjs";
9
9
  //#region src/commands/workflows/build.handler.ts
10
10
  async function handleWorkflowsBuild(options, _ctx) {
@@ -46,7 +46,7 @@ function createCredentialsListCommand() {
46
46
  description: "List credential sets on the server",
47
47
  schema: ListOptionsSchema,
48
48
  optionsConfig: LIST_OPTIONS_CONFIG,
49
- loadHandler: async () => (await import("./list.handler-cK8Y-daR.mjs")).handleCredentialsList
49
+ loadHandler: async () => (await import("./list.handler-ClrceojF.mjs")).handleCredentialsList
50
50
  });
51
51
  }
52
52
  //#endregion
@@ -65,7 +65,7 @@ function createCredentialsRequirementsCommand() {
65
65
  description: "Show what credentials built workflows need (keys, KEYSTROKE_* env names, workflows) — from dist manifests, no API call",
66
66
  schema: RequirementsOptionsSchema,
67
67
  optionsConfig: REQUIREMENTS_OPTIONS_CONFIG,
68
- loadHandler: async () => (await import("./requirements.handler-ZZfHV6f0.mjs")).handleCredentialsRequirements
68
+ loadHandler: async () => (await import("./requirements.handler-BXFoxG3f.mjs")).handleCredentialsRequirements
69
69
  });
70
70
  }
71
71
  //#endregion
@@ -126,7 +126,7 @@ function createCredentialsUploadCommand() {
126
126
  description: "Upload credentials from env vars to the server. Default: reads requirements from built workflow manifests. Use --integration for an official integration or --credential-set + --keys for a custom explicit upload.",
127
127
  schema: UploadOptionsSchema,
128
128
  optionsConfig: UPLOAD_OPTIONS_CONFIG,
129
- loadHandler: async () => (await import("./upload.handler-81mbKHTY.mjs")).handleCredentialsUpload
129
+ loadHandler: async () => (await import("./upload.handler-ZSOVDEdc.mjs")).handleCredentialsUpload
130
130
  });
131
131
  }
132
132
  //#endregion
@@ -157,7 +157,7 @@ function createCredentialsCommand() {
157
157
  }
158
158
  },
159
159
  handler: async (opts, ctx) => {
160
- const { handleCredentialsList } = await import("./list.handler-cK8Y-daR.mjs");
160
+ const { handleCredentialsList } = await import("./list.handler-ClrceojF.mjs");
161
161
  await handleCredentialsList({
162
162
  ...opts,
163
163
  scope: void 0,
@@ -2,10 +2,10 @@
2
2
 
3
3
  import { A as WorkflowResolutionError, a as ui, g as getHttpStatus, h as getApiErrorCode } from "./keystroke.mjs";
4
4
  import { t as assertWorkflowProjectRoot } from "./project-config-DudGRFPO.mjs";
5
- import { a as readManifestsFromOutDir } from "./dist-Br4m3sFZ.mjs";
5
+ import { a as readManifestsFromOutDir } from "./dist-BGYSbs2V.mjs";
6
6
  import { t as requireWorkflowsDir } from "./resolve-project-DJJZIOmu.mjs";
7
- import { t as createSpinnerProgress } from "./spinner-progress-BtEIJRX4.mjs";
8
- import { a as runWorkflowBuild, n as renderBuildFailure } from "./workflow-build-CVG4DSCw.mjs";
7
+ import { t as createSpinnerProgress } from "./spinner-progress-lrKDs4YF.mjs";
8
+ import { a as runWorkflowBuild, n as renderBuildFailure } from "./workflow-build-BIRjDduX.mjs";
9
9
  //#region src/commands/workflows/_shared/current-deployment-workflow.ts
10
10
  /**
11
11
  * Lightweight resolution: gets projectId from keystroke.config.ts and authoredWorkflowId
@@ -64,7 +64,7 @@ function createDeployCommand() {
64
64
  schema: DeployOptionsSchema,
65
65
  optionsConfig: DEPLOY_OPTIONS_CONFIG,
66
66
  contextMode: "auth",
67
- loadHandler: async () => (await import("./deploy.handler-BikVS9ER.mjs")).handleDeploy
67
+ loadHandler: async () => (await import("./deploy.handler-C_Wc90KP.mjs")).handleDeploy
68
68
  });
69
69
  cmd.enablePositionalOptions();
70
70
  cmd.passThroughOptions();
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { a as ui } from "./keystroke.mjs";
4
- import { t as createSpinnerProgress } from "./spinner-progress-BtEIJRX4.mjs";
4
+ import { t as createSpinnerProgress } from "./spinner-progress-lrKDs4YF.mjs";
5
5
  //#region src/lib/deploy-progress.ts
6
6
  function renderItemFailure(event, kind, spinner) {
7
7
  if (event.result === "failure") spinner.fail(`${kind} failed (${event.name})`, void 0, event.error);
@@ -4,13 +4,13 @@ import { D as CliExitError, P as logger, a as ui, l as isLocalMode, n as style,
4
4
  import { i as projects } from "./dist-D_KgdxW5.mjs";
5
5
  import { t as assertWorkflowProjectRoot } from "./project-config-DudGRFPO.mjs";
6
6
  import { r as requireAuthOptions, t as assertProjectConfigMatchesAuthenticatedOrg } from "./context-DHOTSgPb.mjs";
7
- import { i as readAgentManifestsFromOutDir, o as readWorkflowsFromDisk } from "./dist-Br4m3sFZ.mjs";
7
+ import { i as readAgentManifestsFromOutDir, o as readWorkflowsFromDisk } from "./dist-BGYSbs2V.mjs";
8
8
  import { t as requireWorkflowsDir } from "./resolve-project-DJJZIOmu.mjs";
9
- import { n as renderBuildFailure, r as renderBuildHeader } from "./workflow-build-CVG4DSCw.mjs";
10
- import { t as createBuildProgress } from "./build-progress-nYa14iBP.mjs";
11
- import { t as createDeployProgress } from "./deploy-progress-Dlp9aBDW.mjs";
9
+ import { n as renderBuildFailure, r as renderBuildHeader } from "./workflow-build-BIRjDduX.mjs";
10
+ import { t as createBuildProgress } from "./build-progress-O9f-4Z4D.mjs";
11
+ import { t as createDeployProgress } from "./deploy-progress-C1Y73QVM.mjs";
12
12
  import { t as withErrorBoundary } from "./error-boundary-DVZipk-A.mjs";
13
- import { t as lookupCurrentDeploymentWorkflow } from "./current-deployment-workflow-CnzlDCBv.mjs";
13
+ import { t as lookupCurrentDeploymentWorkflow } from "./current-deployment-workflow-DupXGMGV.mjs";
14
14
  import { t as computeWorkflowDiff } from "./diff-utils-CXKNQUXO.mjs";
15
15
  import path from "node:path";
16
16
  import { access } from "node:fs/promises";
@@ -198,7 +198,7 @@ async function handleDeploy(options, ctx) {
198
198
  let outDir;
199
199
  let artifactFilter;
200
200
  try {
201
- const { runWorkflowBuild } = await import("./workflow-build-CVG4DSCw.mjs").then((n) => n.o);
201
+ const { runWorkflowBuild } = await import("./workflow-build-BIRjDduX.mjs").then((n) => n.o);
202
202
  const buildOutcome = await runWorkflowBuild({
203
203
  workflowsDir,
204
204
  verbose: options.verbose,
@@ -233,7 +233,7 @@ async function handleDeploy(options, ctx) {
233
233
  const progress = createDeployProgress();
234
234
  let result;
235
235
  try {
236
- result = await (deployHandlerDependencies.deployFromDir ?? (await import("./dist-Br4m3sFZ.mjs").then((n) => n.r)).deployFromDir)({
236
+ result = await (deployHandlerDependencies.deployFromDir ?? (await import("./dist-BGYSbs2V.mjs").then((n) => n.r)).deployFromDir)({
237
237
  outDir,
238
238
  workflowsDir,
239
239
  client,
@@ -4,7 +4,7 @@ import { D as CliExitError, a as ui, j as throwReportedCliExit, y as toErrorMess
4
4
  import { i as projects } from "./dist-D_KgdxW5.mjs";
5
5
  import { i as writeJson } from "./output-BWcVRt-T.mjs";
6
6
  import { i as requireClient, t as assertProjectConfigMatchesAuthenticatedOrg } from "./context-DHOTSgPb.mjs";
7
- import { n as resolveLocalWorkflowManifest, t as lookupCurrentDeploymentWorkflow } from "./current-deployment-workflow-CnzlDCBv.mjs";
7
+ import { n as resolveLocalWorkflowManifest, t as lookupCurrentDeploymentWorkflow } from "./current-deployment-workflow-DupXGMGV.mjs";
8
8
  import { n as renderDiff, t as computeWorkflowDiff } from "./diff-utils-CXKNQUXO.mjs";
9
9
  //#region src/commands/workflows/diff/diff.handler.ts
10
10
  async function handleWorkflowsDiff(options, ctx) {
@@ -5,7 +5,7 @@ import { t as assertWorkflowProjectRoot } from "./project-config-DudGRFPO.mjs";
5
5
  import { n as SHA256HashSchema } from "./common-AK0q0Oz0.mjs";
6
6
  import { f as collectCredentialRequirementEntries, u as TriggerUploadDataSchema } from "./credential-requirements-D0mavK8j-CFMf0Xwu.mjs";
7
7
  import { a as FlowGraphSchema, r as WorkflowBuildManifestSchema } from "./workflow-build-manifest-1sC52TIG.mjs";
8
- import { t as AgentVersionManifestSchema } from "./agent-manifest-Pg0aURo7.mjs";
8
+ import { t as AgentVersionManifestSchema } from "./agent-manifest-UbtgIIhN.mjs";
9
9
  import { n as TaskBuildManifestSchema } from "./task-BWuIKWh4.mjs";
10
10
  import { n as FileMetadataSchema } from "./file-metadata-DQVDjr7M.mjs";
11
11
  import { t as computeProjectSnapshotHash } from "./task-target-deploy-dQYnMO8n-d2vdeqXH.mjs";
@@ -5,7 +5,7 @@ import { i as projects } from "./dist-D_KgdxW5.mjs";
5
5
  import { i as writeJson } from "./output-BWcVRt-T.mjs";
6
6
  import { i as requireClient } from "./context-DHOTSgPb.mjs";
7
7
  import { n as CredentialConnectionIdSchema, r as CredentialScopeSchema, t as ConnectionStatusSchema } from "./schema-DFJiNWyd.mjs";
8
- import { a as readManifestsFromOutDir } from "./dist-Br4m3sFZ.mjs";
8
+ import { a as readManifestsFromOutDir } from "./dist-BGYSbs2V.mjs";
9
9
  import { t as requireWorkflowsDir } from "./resolve-project-DJJZIOmu.mjs";
10
10
  import { t as getIntegrationCatalog } from "./integration-catalog-Cub_7xCw.mjs";
11
11
  import { t as groupCredentialRequirements } from "./credentials-DQW8xxof.mjs";
@@ -45,7 +45,7 @@ function createInitCommand() {
45
45
  description: "Initialize a Keystroke project (creates keystroke.config.ts)",
46
46
  schema: InitOptionsSchema,
47
47
  optionsConfig: INIT_OPTIONS_CONFIG,
48
- loadHandler: async () => (await import("./init.handler-Dcg9MOqx.mjs")).handleInit
48
+ loadHandler: async () => (await import("./init.handler-C60qFTIV.mjs")).handleInit
49
49
  });
50
50
  }
51
51
  //#endregion
@@ -4,7 +4,7 @@ import { D as CliExitError, a as ui, i as fetchLatestNpmPackageVersion } from ".
4
4
  import { i as projects } from "./dist-D_KgdxW5.mjs";
5
5
  import { a as writeProjectConfig, i as readProjectConfig, r as getProjectConfigPath } from "./project-config-DudGRFPO.mjs";
6
6
  import { i as requireClient } from "./context-DHOTSgPb.mjs";
7
- import { i as UnknownSkillAgentError, n as resolveSkillInstallChoices, r as installKeystrokeAgentSkills, t as summarizeSkillInstall } from "./skill-installer-Cm9hF6OB.mjs";
7
+ import { i as UnknownSkillAgentError, n as resolveSkillInstallChoices, r as installKeystrokeAgentSkills, t as summarizeSkillInstall } from "./skill-installer-AX0X-u1J.mjs";
8
8
  import { createRequire } from "node:module";
9
9
  import path from "node:path";
10
10
  import { access, mkdir, readFile, writeFile } from "node:fs/promises";
@@ -13,7 +13,8 @@ import { cancel, isCancel, text } from "@clack/prompts";
13
13
  //#region src/lib/keystroke-scaffold-version-ranges.ts
14
14
  const WORKFLOW_CORE_PACKAGE_NAME = "@keystrokehq/core";
15
15
  const CONFIG_PACKAGE_NAME = "@keystrokehq/config";
16
- const FALLBACK_WORKFLOW_CORE_VERSION_RANGE = "latest";
16
+ const RUNTIME_PACKAGE_NAME = "@keystrokehq/runtime";
17
+ const FALLBACK_SCAFFOLD_VERSION_RANGE = "latest";
17
18
  const DEFAULT_TIMEOUT_MS = 750;
18
19
  /**
19
20
  * Semver range for scaffold `package.json` — prefers the latest published
@@ -33,6 +34,13 @@ async function configScaffoldVersionRange(options = {}) {
33
34
  readLocalVersion: options.readLocalConfigVersion ?? readLocalConfigVersion
34
35
  });
35
36
  }
37
+ async function runtimeScaffoldVersionRange(options = {}) {
38
+ return packageScaffoldVersionRange({
39
+ packageName: RUNTIME_PACKAGE_NAME,
40
+ timeoutMs: options.timeoutMs,
41
+ readLocalVersion: options.readLocalRuntimeVersion ?? readLocalRuntimeVersion
42
+ });
43
+ }
36
44
  async function packageScaffoldVersionRange(options) {
37
45
  const latestVersion = await fetchLatestNpmPackageVersion({
38
46
  packageName: options.packageName,
@@ -41,7 +49,7 @@ async function packageScaffoldVersionRange(options) {
41
49
  if (latestVersion) return `^${latestVersion}`;
42
50
  const localVersion = options.readLocalVersion();
43
51
  if (localVersion) return `^${localVersion}`;
44
- return FALLBACK_WORKFLOW_CORE_VERSION_RANGE;
52
+ return FALLBACK_SCAFFOLD_VERSION_RANGE;
45
53
  }
46
54
  function readLocalWorkflowCoreVersion() {
47
55
  try {
@@ -59,6 +67,14 @@ function readLocalConfigVersion() {
59
67
  } catch {}
60
68
  return null;
61
69
  }
70
+ function readLocalRuntimeVersion() {
71
+ try {
72
+ const raw = readFileSync(createRequire(import.meta.url).resolve(`${RUNTIME_PACKAGE_NAME}/package.json`), "utf-8");
73
+ const version = JSON.parse(raw).version?.trim();
74
+ if (version) return version;
75
+ } catch {}
76
+ return null;
77
+ }
62
78
  //#endregion
63
79
  //#region src/commands/init/templates/biome-config.ts
64
80
  /**
@@ -210,6 +226,7 @@ function createPackageJsonContent(projectName, options) {
210
226
  },
211
227
  devDependencies: {
212
228
  "@biomejs/biome": "2.4.13",
229
+ "@keystrokehq/runtime": options.runtimeVersionRange,
213
230
  "@keystrokehq/testing": options.workflowCoreVersionRange,
214
231
  vitest: "^4.0.18",
215
232
  typescript: "^5.9.3"
@@ -312,7 +329,7 @@ async function promptProjectDescription(options) {
312
329
  const t = typeof answer === "string" ? answer.trim() : "";
313
330
  return t.length > 0 ? t : void 0;
314
331
  }
315
- async function ensureScaffoldPackageJson(targetDir, projectName, workflowCoreRange, configRange) {
332
+ async function ensureScaffoldPackageJson(targetDir, projectName, workflowCoreRange, configRange, runtimeRange) {
316
333
  const pkgPath = path.join(targetDir, "package.json");
317
334
  try {
318
335
  const raw = await readFile(pkgPath, "utf-8");
@@ -322,6 +339,7 @@ async function ensureScaffoldPackageJson(targetDir, projectName, workflowCoreRan
322
339
  pkg.dependencies["@keystrokehq/core"] = workflowCoreRange;
323
340
  pkg.dependencies.zod = pkg.dependencies.zod ?? "^4.3.6";
324
341
  pkg.devDependencies = pkg.devDependencies ?? {};
342
+ pkg.devDependencies["@keystrokehq/runtime"] = runtimeRange;
325
343
  pkg.devDependencies["@keystrokehq/testing"] = workflowCoreRange;
326
344
  pkg.devDependencies.vitest = pkg.devDependencies.vitest ?? "^4.0.18";
327
345
  pkg.devDependencies.typescript = pkg.devDependencies.typescript ?? "^5.9.3";
@@ -331,6 +349,7 @@ async function ensureScaffoldPackageJson(targetDir, projectName, workflowCoreRan
331
349
  } catch {
332
350
  await writeFile(pkgPath, `${createPackageJsonContent(projectName, {
333
351
  configVersionRange: configRange,
352
+ runtimeVersionRange: runtimeRange,
334
353
  workflowCoreVersionRange: workflowCoreRange
335
354
  })}\n`, "utf-8");
336
355
  return "created";
@@ -408,8 +427,12 @@ async function handleInit(options, ctx) {
408
427
  await projects.track(targetDir, { name: projectName });
409
428
  await installAgentSkillsForInit(targetDir, options);
410
429
  if (options.scaffold) {
411
- const [workflowCoreVersionRange, configVersionRange] = await Promise.all([workflowCoreScaffoldVersionRange(), configScaffoldVersionRange()]);
412
- await scaffoldProject(targetDir, projectName, workflowCoreVersionRange, configVersionRange);
430
+ const [workflowCoreVersionRange, configVersionRange, runtimeVersionRange] = await Promise.all([
431
+ workflowCoreScaffoldVersionRange(),
432
+ configScaffoldVersionRange(),
433
+ runtimeScaffoldVersionRange()
434
+ ]);
435
+ await scaffoldProject(targetDir, projectName, workflowCoreVersionRange, configVersionRange, runtimeVersionRange);
413
436
  }
414
437
  }
415
438
  /** Write a file only if it does not already exist. Returns true if written. */
@@ -422,9 +445,9 @@ async function writeIfMissing(filePath, content) {
422
445
  return true;
423
446
  }
424
447
  }
425
- async function scaffoldProject(targetDir, projectName, workflowCoreVersionRange, configVersionRange) {
426
- const pkgAction = await ensureScaffoldPackageJson(targetDir, projectName, workflowCoreVersionRange, configVersionRange);
427
- ui.success(pkgAction === "created" ? `Created package.json (@keystrokehq/core ${workflowCoreVersionRange}, @keystrokehq/config ${configVersionRange})` : `Updated package.json (Keystroke deps -> core ${workflowCoreVersionRange}, config ${configVersionRange})`);
448
+ async function scaffoldProject(targetDir, projectName, workflowCoreVersionRange, configVersionRange, runtimeVersionRange) {
449
+ const pkgAction = await ensureScaffoldPackageJson(targetDir, projectName, workflowCoreVersionRange, configVersionRange, runtimeVersionRange);
450
+ ui.success(pkgAction === "created" ? `Created package.json (@keystrokehq/core ${workflowCoreVersionRange}, @keystrokehq/config ${configVersionRange}, @keystrokehq/runtime ${runtimeVersionRange})` : `Updated package.json (Keystroke deps -> core ${workflowCoreVersionRange}, config ${configVersionRange}, runtime ${runtimeVersionRange})`);
428
451
  const files = [
429
452
  {
430
453
  rel: "vitest.config.ts",
@@ -5,7 +5,7 @@ import { i as projects } from "./dist-D_KgdxW5.mjs";
5
5
  import { i as writeJson } from "./output-BWcVRt-T.mjs";
6
6
  import { i as requireClient, t as assertProjectConfigMatchesAuthenticatedOrg } from "./context-DHOTSgPb.mjs";
7
7
  import { i as resolveTypeHint } from "./schema-display-XrRCdFL0.mjs";
8
- import { n as resolveLocalWorkflowManifest, r as resolveProjectContext, t as lookupCurrentDeploymentWorkflow } from "./current-deployment-workflow-CnzlDCBv.mjs";
8
+ import { n as resolveLocalWorkflowManifest, r as resolveProjectContext, t as lookupCurrentDeploymentWorkflow } from "./current-deployment-workflow-DupXGMGV.mjs";
9
9
  import dayjs from "dayjs";
10
10
  //#region src/commands/workflows/inspect/inspect-display.ts
11
11
  function formatBuildTimestamp(iso) {
@@ -521,7 +521,7 @@ const logger = {
521
521
  };
522
522
  //#endregion
523
523
  //#region package.json
524
- var version = "0.0.23";
524
+ var version = "0.0.26";
525
525
  //#endregion
526
526
  //#region src/command-registry.ts
527
527
  const ROOT_OPTIONS_WITH_VALUES$1 = new Set([
@@ -533,7 +533,7 @@ const ROOT_VERSION_FLAGS = new Set(["-V", "--version"]);
533
533
  const lazyCommandDefinitions = [
534
534
  {
535
535
  name: "agents",
536
- loadCommand: async () => (await import("./agents-Ccw0IZCx.mjs")).createAgentsCommand()
536
+ loadCommand: async () => (await import("./agents-B57hZo0M.mjs")).createAgentsCommand()
537
537
  },
538
538
  {
539
539
  name: "admin",
@@ -553,7 +553,7 @@ const lazyCommandDefinitions = [
553
553
  },
554
554
  {
555
555
  name: "credentials",
556
- loadCommand: async () => (await import("./credentials-CELZ0QHu.mjs")).createCredentialsCommand(),
556
+ loadCommand: async () => (await import("./credentials-CJpJ5qmL.mjs")).createCredentialsCommand(),
557
557
  copyInheritedSettings: true
558
558
  },
559
559
  {
@@ -562,11 +562,11 @@ const lazyCommandDefinitions = [
562
562
  },
563
563
  {
564
564
  name: "deploy",
565
- loadCommand: async () => (await import("./deploy-Cn3jN7Rl.mjs")).createDeployCommand()
565
+ loadCommand: async () => (await import("./deploy-CPhSW3cB.mjs")).createDeployCommand()
566
566
  },
567
567
  {
568
568
  name: "init",
569
- loadCommand: async () => (await import("./init-6tGGTpYO.mjs")).createInitCommand()
569
+ loadCommand: async () => (await import("./init-DonAqdBg.mjs")).createInitCommand()
570
570
  },
571
571
  {
572
572
  name: "integrations",
@@ -594,15 +594,15 @@ const lazyCommandDefinitions = [
594
594
  },
595
595
  {
596
596
  name: "skills",
597
- loadCommand: async () => (await import("./skills.command-DGIIIRX_.mjs")).createSkillsCommand()
597
+ loadCommand: async () => (await import("./skills.command-B6jly3ew.mjs")).createSkillsCommand()
598
598
  },
599
599
  {
600
600
  name: "sync",
601
- loadCommand: async () => (await import("./sync-BlmgsC2W.mjs")).createSyncCommand()
601
+ loadCommand: async () => (await import("./sync-B1hBmhJM.mjs")).createSyncCommand()
602
602
  },
603
603
  {
604
604
  name: "test",
605
- loadCommand: async () => (await import("./test-cuU0rf9C.mjs")).createTestCommand()
605
+ loadCommand: async () => (await import("./test-BeSgMl0z.mjs")).createTestCommand()
606
606
  },
607
607
  {
608
608
  name: "upgrade",
@@ -610,7 +610,7 @@ const lazyCommandDefinitions = [
610
610
  },
611
611
  {
612
612
  name: "workflows",
613
- loadCommand: async () => (await import("./workflows-eztTnue4.mjs")).createWorkflowsCommand()
613
+ loadCommand: async () => (await import("./workflows--ulcsX9G.mjs")).createWorkflowsCommand()
614
614
  }
615
615
  ];
616
616
  function selectCommandRegistration(argv, commandNames = new Set(lazyCommandDefinitions.map((definition) => definition.name))) {
@@ -4,8 +4,8 @@ import { a as ui, j as throwReportedCliExit, n as style, t as ANSI } from "./key
4
4
  import { i as projects } from "./dist-D_KgdxW5.mjs";
5
5
  import { i as writeJson } from "./output-BWcVRt-T.mjs";
6
6
  import { t as requireWorkflowsDir } from "./resolve-project-DJJZIOmu.mjs";
7
- import { t as createSpinnerProgress } from "./spinner-progress-BtEIJRX4.mjs";
8
- import { a as runWorkflowBuild, n as renderBuildFailure } from "./workflow-build-CVG4DSCw.mjs";
7
+ import { t as createSpinnerProgress } from "./spinner-progress-lrKDs4YF.mjs";
8
+ import { a as runWorkflowBuild, n as renderBuildFailure } from "./workflow-build-BIRjDduX.mjs";
9
9
  //#region src/commands/workflows/list.handler.ts
10
10
  function formatWorkflow(artifact) {
11
11
  const name = style(artifact.manifest.name, `${ANSI.bold}${ANSI.cyan}`);
@@ -3,7 +3,7 @@
3
3
  import { a as ui, c as getProcessEnv, j as throwReportedCliExit } from "./keystroke.mjs";
4
4
  import { i as writeJson } from "./output-BWcVRt-T.mjs";
5
5
  import { i as requireClient } from "./context-DHOTSgPb.mjs";
6
- import { a as readManifestsFromOutDir } from "./dist-Br4m3sFZ.mjs";
6
+ import { a as readManifestsFromOutDir } from "./dist-BGYSbs2V.mjs";
7
7
  import { n as resolveWorkflowsDir } from "./resolve-project-DJJZIOmu.mjs";
8
8
  import { t as readCredentialEnvMap } from "./credential-env-map-CtmzNkwU.mjs";
9
9
  import { a as loadProjectDotenvFile, i as enrichServerCredentialRow, l as renderCredentialListBlocks, n as buildSyntheticNotOnServerRows, r as collectMergedManifestGroups, t as buildCredentialWorkflowConsumersByGroup } from "./list-enrichment-CCRHYslm.mjs";
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { a as ui, c as getProcessEnv, n as style, t as ANSI } from "./keystroke.mjs";
4
4
  import { i as writeJson } from "./output-BWcVRt-T.mjs";
5
- import { a as readManifestsFromOutDir } from "./dist-Br4m3sFZ.mjs";
5
+ import { a as readManifestsFromOutDir } from "./dist-BGYSbs2V.mjs";
6
6
  import { t as requireWorkflowsDir } from "./resolve-project-DJJZIOmu.mjs";
7
7
  import { t as readCredentialEnvMap } from "./credential-env-map-CtmzNkwU.mjs";
8
8
  import { a as loadProjectDotenvFile, c as getTerminalContentWidth, o as manifestGroupKey, s as normalizeManifestScopeToServer, t as buildCredentialWorkflowConsumersByGroup, u as truncateWithEllipsis } from "./list-enrichment-CCRHYslm.mjs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { O as InputValidationError, a as ui, y as toErrorMessage } from "./keystroke.mjs";
4
- import { a as readManifestsFromOutDir } from "./dist-Br4m3sFZ.mjs";
4
+ import { a as readManifestsFromOutDir } from "./dist-BGYSbs2V.mjs";
5
5
  import { a as validateRequiredFields, n as formatValidationError, t as formatMissingInputError } from "./schema-display-XrRCdFL0.mjs";
6
6
  import { n as sleep, t as TERMINAL_STATUSES } from "./run-polling-DKWPGLyF.mjs";
7
7
  import * as path$1 from "node:path";
@@ -6,8 +6,8 @@ import { t as assertWorkflowProjectRoot } from "./project-config-DudGRFPO.mjs";
6
6
  import { i as writeJson } from "./output-BWcVRt-T.mjs";
7
7
  import { i as requireClient, t as assertProjectConfigMatchesAuthenticatedOrg } from "./context-DHOTSgPb.mjs";
8
8
  import { n as resolveWorkflowsDir } from "./resolve-project-DJJZIOmu.mjs";
9
- import { t as lookupCurrentDeploymentWorkflow } from "./current-deployment-workflow-CnzlDCBv.mjs";
10
- import { i as resolveWorkflowGlobals, o as validateInputOrExit, r as resolveRunInput, s as validateWorkflowGlobalsOrExit, t as pollForCompletion } from "./run-polling-3XOGl4hh.mjs";
9
+ import { t as lookupCurrentDeploymentWorkflow } from "./current-deployment-workflow-DupXGMGV.mjs";
10
+ import { i as resolveWorkflowGlobals, o as validateInputOrExit, r as resolveRunInput, s as validateWorkflowGlobalsOrExit, t as pollForCompletion } from "./run-polling-DEO0A7ec.mjs";
11
11
  //#region src/commands/workflows/run.handler.ts
12
12
  async function handleWorkflowsRun(options, ctx) {
13
13
  const client = requireClient(ctx);
@@ -4,11 +4,10 @@ import { D as CliExitError, a as ui } from "./keystroke.mjs";
4
4
  import { createRequire } from "node:module";
5
5
  import path from "node:path";
6
6
  import { access, cp, mkdir, readFile, readdir, rm, symlink, writeFile } from "node:fs/promises";
7
- import { fileURLToPath } from "node:url";
8
7
  import { autocompleteMultiselect, cancel, isCancel, select } from "@clack/prompts";
9
8
  //#region src/lib/skill-installer/package.ts
10
9
  const SKILLS_PACKAGE_CONTENT_DIR = "src";
11
- const AGENTS_PACKAGE_PATH = "src/AGENTS.md";
10
+ const AGENTS_PACKAGE_PATH = "src/_AGENTS.md";
12
11
  async function resolveKeystrokeSkillsPackageRoot() {
13
12
  try {
14
13
  const require = createRequire(import.meta.url);
@@ -39,29 +38,20 @@ function normalizeLineEndings$1(value) {
39
38
  function normalizeGuidanceBlurb(value) {
40
39
  return `${normalizeLineEndings$1(value).trim()}\n`;
41
40
  }
42
- function resolveMonorepoSkillsBlurbPath() {
43
- return fileURLToPath(new URL("../../../../../packages/skills/src/AGENTS.md", import.meta.url));
44
- }
45
- function resolveCliPackageSkillsBlurbPath() {
46
- const relativePath = import.meta.url.includes("/dist/") ? "../AGENTS-blurb.md" : "../../../AGENTS-blurb.md";
47
- return fileURLToPath(new URL(relativePath, import.meta.url));
48
- }
49
41
  function resolveBundledKeystrokeAgentsBlurbPath() {
50
42
  const require = createRequire(import.meta.url);
51
43
  try {
52
44
  const skillsPackageJsonPath = require.resolve("@keystrokehq/skills/package.json");
53
45
  return path.join(path.dirname(skillsPackageJsonPath), AGENTS_PACKAGE_PATH);
54
- } catch {}
55
- try {
56
- return resolveCliPackageSkillsBlurbPath();
57
- } catch {}
58
- return resolveMonorepoSkillsBlurbPath();
46
+ } catch {
47
+ throw new CliExitError("Could not resolve @keystrokehq/skills. Reinstall the CLI with its bundled skills package.", { exitCode: 1 });
48
+ }
59
49
  }
60
50
  async function loadKeystrokeAgentsBlurb() {
61
51
  try {
62
52
  return normalizeGuidanceBlurb(await readFile(resolveBundledKeystrokeAgentsBlurbPath(), "utf-8"));
63
53
  } catch (error) {
64
- throw new CliExitError("Could not load the bundled Keystroke AGENTS.md content. Reinstall the CLI or republish @keystrokehq/cli with @keystrokehq/skills/src/AGENTS.md.", { cause: error });
54
+ throw new CliExitError("Could not load the bundled Keystroke AGENTS.md content. Reinstall the CLI or republish @keystrokehq/cli with @keystrokehq/skills/src/_AGENTS.md.", { cause: error });
65
55
  }
66
56
  }
67
57
  //#endregion
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { D as CliExitError, a as ui } from "./keystroke.mjs";
4
4
  import { i as writeJson, r as isJsonMode } from "./output-BWcVRt-T.mjs";
5
- import { i as UnknownSkillAgentError, n as resolveSkillInstallChoices, r as installKeystrokeAgentSkills, t as summarizeSkillInstall } from "./skill-installer-Cm9hF6OB.mjs";
5
+ import { i as UnknownSkillAgentError, n as resolveSkillInstallChoices, r as installKeystrokeAgentSkills, t as summarizeSkillInstall } from "./skill-installer-AX0X-u1J.mjs";
6
6
  import path from "node:path";
7
7
  //#region src/commands/skills/skills-sync.handler.ts
8
8
  async function handleSkillsSync(options, _ctx) {
@@ -38,7 +38,7 @@ function createSkillsCommand() {
38
38
  description: "Install bundled Keystroke skills into selected agent skill directories",
39
39
  schema: SkillsCommandOptionsSchema,
40
40
  optionsConfig: SKILLS_OPTIONS_CONFIG,
41
- loadHandler: async () => (await import("./skills-sync.handler-09mDbx5q.mjs")).handleSkillsSync
41
+ loadHandler: async () => (await import("./skills-sync.handler-DsJP_-XZ.mjs")).handleSkillsSync
42
42
  })]
43
43
  });
44
44
  cmd.enablePositionalOptions();
@@ -35,6 +35,7 @@ function printSkippedLine(label) {
35
35
  }
36
36
  function createWorker() {
37
37
  if (!isTTY()) return null;
38
+ if ("Bun" in globalThis) return null;
38
39
  try {
39
40
  return new Worker(new URL("./spinner-worker.mjs", import.meta.url));
40
41
  } catch {
@@ -32,7 +32,7 @@ function createSyncCommand() {
32
32
  description: "Sync local workflows with Keystroke",
33
33
  schema: SyncOptionsSchema,
34
34
  optionsConfig: SYNC_OPTIONS_CONFIG,
35
- loadHandler: async () => (await import("./sync.handler-xVxeG-S0.mjs")).handleSync
35
+ loadHandler: async () => (await import("./sync.handler-B9Q_6jI8.mjs")).handleSync
36
36
  });
37
37
  }
38
38
  //#endregion
@@ -3,11 +3,11 @@
3
3
  import { P as logger, a as ui, j as throwReportedCliExit, l as isLocalMode, y as toErrorMessage } from "./keystroke.mjs";
4
4
  import { i as projects } from "./dist-D_KgdxW5.mjs";
5
5
  import { a as validateApiKey, i as requireClient } from "./context-DHOTSgPb.mjs";
6
- import { n as deployFromDir } from "./dist-Br4m3sFZ.mjs";
6
+ import { n as deployFromDir } from "./dist-BGYSbs2V.mjs";
7
7
  import { t as requireWorkflowsDir } from "./resolve-project-DJJZIOmu.mjs";
8
- import { a as runWorkflowBuild, n as renderBuildFailure, r as renderBuildHeader } from "./workflow-build-CVG4DSCw.mjs";
9
- import { t as createBuildProgress } from "./build-progress-nYa14iBP.mjs";
10
- import { t as createDeployProgress } from "./deploy-progress-Dlp9aBDW.mjs";
8
+ import { a as runWorkflowBuild, n as renderBuildFailure, r as renderBuildHeader } from "./workflow-build-BIRjDduX.mjs";
9
+ import { t as createBuildProgress } from "./build-progress-O9f-4Z4D.mjs";
10
+ import { t as createDeployProgress } from "./deploy-progress-C1Y73QVM.mjs";
11
11
  //#region src/commands/sync/sync.handler.ts
12
12
  async function handleSync(options, ctx) {
13
13
  try {
@@ -63,7 +63,7 @@ function createTestCommand() {
63
63
  description: "Agent tool name from the built manifest",
64
64
  key: "toolName"
65
65
  },
66
- loadHandler: async () => (await import("./tool.handler-CmpzYYiC.mjs")).handleTestTool
66
+ loadHandler: async () => (await import("./tool.handler-CjjbaZJB.mjs")).handleTestTool
67
67
  })]
68
68
  });
69
69
  cmd.enablePositionalOptions();
@@ -4,13 +4,13 @@ import { D as CliExitError, a as ui, l as isLocalMode, y as toErrorMessage } fro
4
4
  import { i as projects } from "./dist-D_KgdxW5.mjs";
5
5
  import { t as assertWorkflowProjectRoot } from "./project-config-DudGRFPO.mjs";
6
6
  import { i as requireClient, t as assertProjectConfigMatchesAuthenticatedOrg } from "./context-DHOTSgPb.mjs";
7
- import { o as readWorkflowsFromDisk, s as uploadTestBundle } from "./dist-Br4m3sFZ.mjs";
7
+ import { o as readWorkflowsFromDisk, s as uploadTestBundle } from "./dist-BGYSbs2V.mjs";
8
8
  import { t as requireWorkflowsDir } from "./resolve-project-DJJZIOmu.mjs";
9
- import { a as runWorkflowBuild, t as WorkflowNotFoundError } from "./workflow-build-CVG4DSCw.mjs";
9
+ import { a as runWorkflowBuild, t as WorkflowNotFoundError } from "./workflow-build-BIRjDduX.mjs";
10
10
  import { r as isUnknownSchema } from "./schema-display-XrRCdFL0.mjs";
11
- import { t as createBuildProgress } from "./build-progress-nYa14iBP.mjs";
11
+ import { t as createBuildProgress } from "./build-progress-O9f-4Z4D.mjs";
12
12
  import { t as withErrorBoundary } from "./error-boundary-DVZipk-A.mjs";
13
- import { a as tryReadExistingInputSchema, n as resolveInput, o as validateInputOrExit, t as pollForCompletion } from "./run-polling-3XOGl4hh.mjs";
13
+ import { a as tryReadExistingInputSchema, n as resolveInput, o as validateInputOrExit, t as pollForCompletion } from "./run-polling-DEO0A7ec.mjs";
14
14
  //#region src/lib/format.ts
15
15
  function formatBytes(bytes) {
16
16
  if (bytes < 1024) return `${bytes} B`;
@@ -5,11 +5,11 @@ import { t as Credentials } from "./dist-D_KgdxW5.mjs";
5
5
  import { t as assertWorkflowProjectRoot } from "./project-config-DudGRFPO.mjs";
6
6
  import { i as writeJson } from "./output-BWcVRt-T.mjs";
7
7
  import { i as requireClient, t as assertProjectConfigMatchesAuthenticatedOrg } from "./context-DHOTSgPb.mjs";
8
- import { a as readManifestsFromOutDir } from "./dist-Br4m3sFZ.mjs";
8
+ import { a as readManifestsFromOutDir } from "./dist-BGYSbs2V.mjs";
9
9
  import { t as requireWorkflowsDir } from "./resolve-project-DJJZIOmu.mjs";
10
- import { a as runWorkflowBuild, n as renderBuildFailure } from "./workflow-build-CVG4DSCw.mjs";
11
- import { t as lookupCurrentDeploymentWorkflow } from "./current-deployment-workflow-CnzlDCBv.mjs";
12
- import { n as resolveInput, o as validateInputOrExit, t as pollForCompletion } from "./run-polling-3XOGl4hh.mjs";
10
+ import { a as runWorkflowBuild, n as renderBuildFailure } from "./workflow-build-BIRjDduX.mjs";
11
+ import { t as lookupCurrentDeploymentWorkflow } from "./current-deployment-workflow-DupXGMGV.mjs";
12
+ import { n as resolveInput, o as validateInputOrExit, t as pollForCompletion } from "./run-polling-DEO0A7ec.mjs";
13
13
  import * as os from "node:os";
14
14
  import { tmpdir } from "node:os";
15
15
  import * as path$1 from "node:path";
@@ -4,7 +4,7 @@ import { a as ui, c as getProcessEnv, j as throwReportedCliExit, y as toErrorMes
4
4
  import { t as assertWorkflowProjectRoot } from "./project-config-DudGRFPO.mjs";
5
5
  import { a as writeJsonError, i as writeJson } from "./output-BWcVRt-T.mjs";
6
6
  import { i as requireClient } from "./context-DHOTSgPb.mjs";
7
- import { a as readManifestsFromOutDir, t as collectCredentialFingerprintMapFromProjectDist } from "./dist-Br4m3sFZ.mjs";
7
+ import { a as readManifestsFromOutDir, t as collectCredentialFingerprintMapFromProjectDist } from "./dist-BGYSbs2V.mjs";
8
8
  import { t as requireWorkflowsDir } from "./resolve-project-DJJZIOmu.mjs";
9
9
  import { t as getIntegrationCatalog } from "./integration-catalog-Cub_7xCw.mjs";
10
10
  import { t as readCredentialEnvMap } from "./credential-env-map-CtmzNkwU.mjs";
@@ -4,8 +4,8 @@ import { a as ui, j as throwReportedCliExit, y as toErrorMessage } from "./keyst
4
4
  import { i as projects } from "./dist-D_KgdxW5.mjs";
5
5
  import { i as writeJson } from "./output-BWcVRt-T.mjs";
6
6
  import { t as requireWorkflowsDir } from "./resolve-project-DJJZIOmu.mjs";
7
- import { s as build, t as WorkflowNotFoundError } from "./workflow-build-CVG4DSCw.mjs";
8
- import { t as createBuildProgress } from "./build-progress-nYa14iBP.mjs";
7
+ import { s as build, t as WorkflowNotFoundError } from "./workflow-build-BIRjDduX.mjs";
8
+ import { t as createBuildProgress } from "./build-progress-O9f-4Z4D.mjs";
9
9
  import * as os from "node:os";
10
10
  import * as path$1 from "node:path";
11
11
  import { mkdtemp, rm } from "node:fs/promises";
@@ -5,7 +5,7 @@ import { F as originalConsole, P as logger, a as ui, n as style, t as ANSI, y as
5
5
  import { r as getKeystrokeTmpDir } from "./dist-D_KgdxW5.mjs";
6
6
  import { t as assertWorkflowProjectRoot } from "./project-config-DudGRFPO.mjs";
7
7
  import { a as FlowGraphSchema, r as WorkflowBuildManifestSchema } from "./workflow-build-manifest-1sC52TIG.mjs";
8
- import { t as AgentVersionManifestSchema } from "./agent-manifest-Pg0aURo7.mjs";
8
+ import { t as AgentVersionManifestSchema } from "./agent-manifest-UbtgIIhN.mjs";
9
9
  import { r as RelativeFilePathSchema } from "./file-metadata-DQVDjr7M.mjs";
10
10
  import { c as createArtifactOutputFiles, l as createMetadataOutputFile, o as METADATA_ROOT_DIR_NAME, p as getWorkflowArtifactPaths, t as BUILD_DIR_NAME } from "./layout-B95Tku8F.mjs";
11
11
  import { t as resolveConfiguredBuildOutputDir } from "./utils-BaxDlCsW.mjs";
@@ -993,7 +993,7 @@ async function buildDiscoveredWorkflows(options) {
993
993
  warnings.push(...result.warnings);
994
994
  }
995
995
  if (buildPlan.agents.length > 0) {
996
- const { buildAgentArtifacts } = await import("./build-agents-DseUtzd4-DFh2e5Cn.mjs");
996
+ const { buildAgentArtifacts } = await import("./build-agents-DseUtzd4-C6S-h9Gi.mjs");
997
997
  const result = await buildAgentArtifacts({
998
998
  entries: buildPlan.agents,
999
999
  projectRoot: options.projectRoot
@@ -320,7 +320,7 @@ function createWorkflowsBuildCommand() {
320
320
  description: "Build workflows locally",
321
321
  schema: WorkflowsBuildOptionsSchema,
322
322
  optionsConfig: BUILD_OPTIONS_CONFIG,
323
- loadHandler: async () => (await import("./build.handler-ChqSwsT_.mjs")).handleWorkflowsBuild
323
+ loadHandler: async () => (await import("./build.handler-Bd2x92wh.mjs")).handleWorkflowsBuild
324
324
  });
325
325
  }
326
326
  //#endregion
@@ -347,7 +347,7 @@ function createWorkflowsDiffCommand() {
347
347
  description: "Authored workflow id (preferred) or workflow name",
348
348
  key: "workflow"
349
349
  },
350
- loadHandler: async () => (await import("./diff.handler-C3EWVBOj.mjs")).handleWorkflowsDiff
350
+ loadHandler: async () => (await import("./diff.handler-jJEIJq41.mjs")).handleWorkflowsDiff
351
351
  });
352
352
  }
353
353
  //#endregion
@@ -380,7 +380,7 @@ function createWorkflowsEnvCommand() {
380
380
  key: "workflow",
381
381
  required: false
382
382
  },
383
- loadHandler: async () => (await import("./env.handler-BuFdzUoX.mjs")).handleWorkflowsEnv
383
+ loadHandler: async () => (await import("./env.handler-BbH44f51.mjs")).handleWorkflowsEnv
384
384
  });
385
385
  }
386
386
  //#endregion
@@ -412,7 +412,7 @@ function createWorkflowsInspectCommand() {
412
412
  description: "Authored workflow id (preferred) or workflow name",
413
413
  key: "workflow"
414
414
  },
415
- loadHandler: async () => (await import("./inspect.handler-BN6p2hI_.mjs")).handleWorkflowsInspect
415
+ loadHandler: async () => (await import("./inspect.handler-jtSz17z5.mjs")).handleWorkflowsInspect
416
416
  });
417
417
  }
418
418
  //#endregion
@@ -792,7 +792,7 @@ function createWorkflowsRunCommand() {
792
792
  key: "payload",
793
793
  required: false
794
794
  }],
795
- loadHandler: async () => (await import("./run.handler-xeUVmlFk.mjs")).handleWorkflowsRun
795
+ loadHandler: async () => (await import("./run.handler-itMzf36_.mjs")).handleWorkflowsRun
796
796
  });
797
797
  }
798
798
  //#endregion
@@ -847,7 +847,7 @@ function createWorkflowsTestCommand() {
847
847
  description: "Authored workflow id (preferred) or workflow name. Multiple workflows with the same name run sequentially.",
848
848
  key: "workflow"
849
849
  },
850
- loadHandler: async () => (await import("./test.handler-B_C-T_IM.mjs")).handleWorkflowsTest
850
+ loadHandler: async () => (await import("./test.handler-DxEIHSy2.mjs")).handleWorkflowsTest
851
851
  });
852
852
  }
853
853
  //#endregion
@@ -885,7 +885,7 @@ function createWorkflowsValidateCommand() {
885
885
  key: "workflow",
886
886
  required: false
887
887
  },
888
- loadHandler: async () => (await import("./validate.handler-CWG5HyO3.mjs")).handleWorkflowsValidate
888
+ loadHandler: async () => (await import("./validate.handler-zJIDu4gG.mjs")).handleWorkflowsValidate
889
889
  });
890
890
  }
891
891
  //#endregion
@@ -904,14 +904,14 @@ function createWorkflowsCommand() {
904
904
  description: "Manage, run, inspect, and debug workflows",
905
905
  schema: WorkflowsOptionsSchema,
906
906
  optionsConfig: WORKFLOWS_OPTIONS_CONFIG,
907
- loadHandler: async () => (await import("./list.handler-fcyAKTQe.mjs")).handleWorkflowsList,
907
+ loadHandler: async () => (await import("./list.handler-BapLGgXO.mjs")).handleWorkflowsList,
908
908
  subcommands: [
909
909
  createTypedCommand({
910
910
  name: "list",
911
911
  description: "List all workflows in the project",
912
912
  schema: WorkflowsOptionsSchema,
913
913
  optionsConfig: WORKFLOWS_OPTIONS_CONFIG,
914
- loadHandler: async () => (await import("./list.handler-fcyAKTQe.mjs")).handleWorkflowsList
914
+ loadHandler: async () => (await import("./list.handler-BapLGgXO.mjs")).handleWorkflowsList
915
915
  }),
916
916
  createWorkflowsBuildCommand(),
917
917
  createWorkflowsTestCommand(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keystrokehq/cli",
3
- "version": "0.0.23",
3
+ "version": "0.0.26",
4
4
  "private": false,
5
5
  "description": "Command-line interface for creating, managing, and deploying Keystroke automations.",
6
6
  "type": "module",
@@ -17,7 +17,6 @@
17
17
  "keystroke": "./bin/keystroke.mjs"
18
18
  },
19
19
  "files": [
20
- "AGENTS-blurb.md",
21
20
  "bin",
22
21
  "dist",
23
22
  "README.md"
@@ -32,26 +31,27 @@
32
31
  "oxc-parser": "^0.128.0",
33
32
  "rolldown": "1.0.0",
34
33
  "tsx": "^4.21.0",
35
- "zod": "^4.3.6",
36
- "@keystrokehq/skills": "0.0.4"
34
+ "zod": "4.4.3",
35
+ "@keystrokehq/skills": "0.0.7"
37
36
  },
38
37
  "devDependencies": {
39
38
  "tsdown": "0.21.10",
40
39
  "typescript": "^5.9.3",
41
40
  "vitest": "^4.1.5",
42
- "@keystroke/local-memory": "0.0.1",
43
41
  "@keystroke/env-utils": "0.0.0",
44
- "@keystrokehq/config": "0.0.2",
42
+ "@keystroke/local-memory": "0.0.1",
45
43
  "@keystroke/shared-types": "0.0.5",
44
+ "@keystrokehq/config": "0.0.2",
45
+ "@keystroke/test-utils": "0.0.3",
46
46
  "@keystroke/typescript-config": "0.0.0",
47
47
  "@keystroke/utils": "0.0.0",
48
- "@keystroke/workflow-builder": "0.0.7",
48
+ "@keystrokehq/core": "0.0.7",
49
+ "@keystrokehq/runtime": "0.0.4",
49
50
  "@keystrokehq/workflow-build-contracts": "0.0.3",
50
51
  "@keystrokehq/testing": "0.2.2",
51
52
  "@keystroke/workflow-deploy": "0.0.6",
52
53
  "@keystroke/workflow-sdk": "0.0.4",
53
- "@keystrokehq/core": "0.0.7",
54
- "@keystroke/test-utils": "0.0.3"
54
+ "@keystroke/workflow-builder": "0.0.7"
55
55
  },
56
56
  "keywords": [
57
57
  "automation",
package/AGENTS-blurb.md DELETED
@@ -1,123 +0,0 @@
1
- # Keystroke Project Context
2
-
3
- You are working inside a Keystroke project. Keystroke is a code-first workflow and agent automation platform. Authors define workflows, agents, operations, tasks, triggers, messaging gateways, MCP servers, sandboxes, and credential bindings in TypeScript, then build and deploy them with the Keystroke CLI.
4
-
5
- When reasoning about authored code, use this top-level split:
6
-
7
- - A `Workflow` is deterministic orchestration. Its `run(...)` method coordinates steps, child workflows, waits, hooks, and agents.
8
- - An `Agent` is model-driven execution. It runs with agent tools, can use sandboxes, MCP servers, and messaging gateways, and is the right place for llm driven work.
9
- - A `Task` is the trigger-driven agent path. It combines triggers, a prompt, and an agent run.
10
- - A workflow can also be registered as an agent tool. Sync workflow tools return inline results; suspending workflow tools yield and resume later; large outputs can return refs inspected with bounded data toolkit tools.
11
-
12
- Triggers, tasks, and agent conversations are different entry models:
13
-
14
- - a workflow is started by a trigger or direct invocation
15
- - a trigger is a code-based primitive you author in TypeScript and attach to a workflow
16
- - a trigger attaches to a workflow and resolves external payload into validated workflow input
17
- - a trigger is not a chat session; it is an ingress boundary that transforms payload and starts a workflow
18
- - a task is not attached with `trigger.attach(...)`; it lists triggers inline and resolves a prompt for an agent run
19
- - an agent conversation is a chat session, not a code-authored primitive like `CronTrigger`, `WebhookTrigger`, or `PollingTrigger`
20
- - conversations can be started from the UI, from messaging adapters such as Slack, Linear, or GitHub, or from a workflow when the workflow runs an agent
21
- - messaging gateways configure conversational entry on agents; they are not workflow triggers
22
- - an agent keeps full context of the conversation session while the workflow side stays replay-safe and stateless between execution boundaries
23
-
24
- Keystroke also has one shared unit-of-work primitive: `Operation`.
25
-
26
- - `Operation`, `Step`, and `Tool` are aliases for the same class from `@keystrokehq/core`.
27
- - Use the `Step` name when teaching workflow-side usage.
28
- - Use the `Tool` name when teaching agent-side usage.
29
- - Use the `Operation` name when describing shared infrastructure, integrations, or a reusable unit that can be used in both places.
30
- - The runtime behavior comes from context, not from which alias name was used in the constructor.
31
-
32
- Runtime boundary:
33
-
34
- - workflows and steps are authored as TypeScript control-flow and unit-of-work code
35
- - workflows do not run bash commands as part of the workflow authoring model
36
- - agents are the correct place for bash, filesystem work, and sandbox-managed dependencies such as Python
37
-
38
- Keystroke workflow execution is replay-based and stateless at the workflow layer:
39
-
40
- - Keystroke does not persist live in-memory workflow state.
41
- - Instead, it persists execution events and terminal results for execution boundaries, then replays the workflow code from the top with that saved state.
42
- - The workflow body itself is re-executed during replay. Local variables and control flow are recomputed, not resumed from memory.
43
- - Because of that, workflow code must be replay-safe and deterministic.
44
-
45
- Treat these calls inside `Workflow.run(...)` as execution boundaries:
46
-
47
- - `await step.run(...)`
48
- - `await operation.run(...)`
49
- - `await childWorkflow.run(...)`
50
- - `await agent.run(...)`
51
-
52
- What gets persisted:
53
-
54
- - For steps, Keystroke persists created/completed/failed state and reuses the saved result during workflow replay.
55
- - For child workflows, Keystroke persists the child run and its terminal result, then resumes the parent workflow with that saved outcome.
56
- - For agents, Keystroke persists agent execution state and terminal output, then resumes the workflow with that saved result.
57
- - The workflow's own in-memory logic is not persisted. The platform saves boundary state, not the live workflow stack.
58
-
59
- Where code runs:
60
-
61
- - Operations used as workflow steps are low-level units of work and run in separate worker executions.
62
- - Child workflows run as separate workflow executions in their own workers, using the same replay model as parent workflows.
63
- - Agents run outside the workflow replay worker. They run in persisted sandboxes with a persistent filesystem, where they can use files, shell commands, installed skills, MCP servers, and other runtime tools. The filesystem persists over all agent runs for a deployed agent.
64
- - Operations used as agent tools are not top-level orchestration units. A tool runs inside the agent runtime when the agent chooses to call it, inside that persisted sandbox context.
65
-
66
- Workflow triggers versus agent conversations:
67
-
68
- - use code-authored triggers when external schedules, webhook requests, or polling results should become workflow input
69
- - use agent conversations when a user or system is chatting with an agent over time
70
- - author triggers in code; do not think of conversations as authored primitives in the same way
71
- - messaging adapters normalize inbound events into thread-based conversations, and the agent responds inside that conversation context
72
- - a workflow can still start an agent-backed conversation by running an agent, but that is different from a workflow trigger boundary
73
-
74
- Authoring implications:
75
-
76
- - Put orchestration, branching, loops, waits, and composition in workflows.
77
- - Put deterministic side effects and integration calls in operations used as steps.
78
- - Put LLM-driven reasoning and tool selection in agents.
79
- - Put concrete callable actions in operations used as tools.
80
- - Use `largeResultMode: 'ref'` plus `describe_ref`, `read_ref`, and `slice_ref` for large workflow-tool outputs. Reducers and DuckDB-backed data tools are deferred.
81
- - Use `midSessionSnapshot: true` only for measured workflow-tool cases that need Phase D replay. Current snapshot behavior is conversation-log replay, not native Pi process restore.
82
- - Do not depend on workflow-local mutable state, random values, direct network I/O, or filesystem mutations in the workflow body itself unless they happen behind a Keystroke execution boundary.
83
- - Never assume workflow-local memory or filesystem state survives between replays. If state must survive, return it from an operation, agent, or child workflow, or persist it externally.
84
-
85
- ## Workflow Builder File Structure
86
-
87
- The workflow builder now relies on explicit file structure. Teach and author Keystroke code with one exported primitive per typed file:
88
-
89
- - `*.workflow.ts` for one `Workflow`
90
- - `*.step.ts`, `*.tool.ts`, or `*.operation.ts` for one exported `Operation`
91
- - `*.agent.ts` for one `Agent`
92
- - `*.gateway.ts` for one `MessagingGateway`
93
- - `*.trigger.ts` for one trigger
94
- - `*.credential-set.ts` for one `CredentialSet`
95
- - `*.mcp-server.ts` for one `McpServer`
96
-
97
- Builder note:
98
-
99
- - `*.step.ts`, `*.tool.ts`, and `*.operation.ts` all validate as the same operation convention
100
- - choose the suffix that communicates intent to the reader
101
-
102
- Required structure:
103
-
104
- - exported primitives should be top-level and statically visible
105
- - helper files such as `schemas.ts`, `utils.ts`, or `prompts.ts` should not export primitives
106
- - a `*.trigger.ts` file may also export that trigger's `TriggerAttachment` values
107
- - tests are exempt, but authored project code should follow the typed-file convention everywhere
108
-
109
- Example layout:
110
-
111
- ```text
112
- customer-support/
113
- crm-api.credential-set.ts
114
- lookup-customer.tool.ts
115
- support.agent.ts
116
- support.gateway.ts
117
- triage.step.ts
118
- support.workflow.ts
119
- support.trigger.ts
120
- coding.sandbox.ts
121
- docs.mcp-server.ts
122
- schemas.ts
123
- ```