@keystrokehq/cli 0.1.86 → 0.1.88

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/README.md CHANGED
@@ -15,7 +15,7 @@ Keep the CLI small and boring.
15
15
  - **Agent-first** — commands should be predictable, scriptable, and easy for AI agents to invoke
16
16
  - **Split concerns** — non-secret config in one place, secrets in the OS keychain
17
17
 
18
- Right now the CLI exposes `init`, `build`, `dev`, `start`, `lint`, `typecheck`, `test`, `deploy`, `health`, `auth`, `--help`, and `--version`.
18
+ Right now the CLI exposes `init`, `build`, `dev`, `start`, `lint`, `typecheck`, `test`, `deploy`, `pull`, `update`, `health`, `auth`, `--help`, and `--version`.
19
19
 
20
20
  ## Command grammar
21
21
 
@@ -24,7 +24,7 @@ Stripe-style: plural REST collection, then a verb, then the primary slug. New co
24
24
  ```text
25
25
  keystroke <collection> <verb> [<slug>] [<sub-id>] [--flags]
26
26
  keystroke <collection> <sub-collection> <verb> [<slug>] [<sub-id>] [--flags]
27
- keystroke <verb> # lifecycle only (init, build, dev, deploy, …)
27
+ keystroke <verb> # lifecycle only (init, build, dev, deploy, update, …)
28
28
  ```
29
29
 
30
30
  Rules:
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { $ as CredentialInstanceRecordSchema, $n as WorkflowRunDetailResponseSchema, $t as PresignProjectSourceResponseSchema, A as ConnectManagedServiceCredentialRequestSchema, An as TriggerRunListResponseSchema, At as ListManagedServiceCredentialsResponseSchema, B as CreateCustomAppResponseSchema, Bn as UpdateProjectMemberResponseSchema, Bt as ManagedServiceCredentialSchema, C as ChannelConnectionListResponseSchema, Cn as SubmitMarketingContactRequestSchema, Ct as ListAgentMemoryFilesResponseSchema, D as ConfirmCheckoutRequestSchema, Dn as TriggerInvokeResponseSchema, Dr as resolvePublicPlatformOrigin, Dt as ListChannelPlatformsResponseSchema, E as CompleteProjectArtifactResponseSchema, En as TriggerInvokeInputsSchema, Er as resolveDocsMcpUrl, Et as ListAppsResponseSchema, F as CreateCredentialInstanceBodySchema, Fn as UpdateManagedServiceCredentialRequestSchema, Ft as ListProjectDeploymentsResponseSchema, G as CreateProjectResponseSchema, Gn as UpsertGatewayAttachmentBodySchema, Gt as OrganizationSidebarBrandingSchema, H as CreateOrganizationResponseSchema, Hn as UpdateProjectSettingsRequestSchema, Ht as McpDiscoverResponseSchema, I as CreateCredentialsRequestSchema, In as UpdateOrganizationMemberRequestSchema, It as ListProjectFilesResponseSchema, J as CredentialAssignmentListResponseSchema, Jn as UserPreferencesPatchSchema, Jt as PresignChatAttachmentRequestSchema, K as CreateSubscriptionCheckoutRequestSchema, Kn as UserAvatarPatchSchema, Kt as PROJECT_PULL_STATE_RELATIVE_PATH, L as CreateCredentialsResponseSchema, Ln as UpdateOrganizationMemberResponseSchema, Lt as ListProjectMembersResponseSchema, M as CreateApiKeyRequestSchema, Mn as UpdateChannelBindingBodySchema, Mt as ListOrganizationMembersPageQuerySchema, N as CreateApiKeyResponseSchema, Nn as UpdateCredentialInstanceBodySchema, Nt as ListOrganizationMembersPageResponseSchema, O as ConfirmCheckoutResponseSchema, On as TriggerListResponseSchema, Or as slugifyAppName, Ot as ListCredentialsPageQuerySchema, P as CreateBillingPortalRequestSchema, Pn as UpdateCredentialRequestSchema, Pt as ListOrganizationsResponseSchema, Q as CredentialInstanceListResponseSchema, Qn as WorkflowCanvasSchema, Qt as PresignProjectSourceRequestSchema, R as CreateCreditsCheckoutRequestSchema, Rn as UpdateOrganizationRequestSchema, Rt as ListProjectMetricsResponseSchema, S as ChannelAccountListResponseSchema, Sn as StartOAuthConnectionResultSchema, Sr as parseErrorResponse, T as ChannelDirectoryListResponseSchema, Tn as TriggerDetailResponseSchema, Tr as resolveConnectAppSlug, Tt as ListApiKeysResponseSchema, U as CreateProjectArtifactResponseSchema, Un as UploadProjectSourceManifestRequestSchema, Ut as OpenApiDiscoverResponseSchema, V as CreateOrganizationRequestSchema, Vn as UpdateProjectRequestSchema, Vt as ManagedServiceKindSchema, W as CreateProjectRequestSchema, Wn as UploadProjectSourceResponseSchema, Wt as OrganizationSidebarBrandingPatchSchema, X as CredentialConsumerListQuerySchema, Xn as WorkflowCanvasCredentialBindingsSchema, Xt as PresignOrgLogoRequestSchema, Y as CredentialAssignmentRecordSchema, Yn as UserPreferencesSchema, Yt as PresignChatAttachmentResponseSchema, Z as CredentialConsumerListResponseSchema, Zn as WorkflowCanvasRunSchema, Zt as PresignOrgLogoResponseSchema, _ as BindChannelBodySchema, _n as StartKeystrokeConnectionInputSchema, _r as isAcceptableInstallExit, _t as HistoryRunListResponseSchema, a as AgentSessionListResponseSchema, an as ProjectSettingsResponseSchema, ar as WorkflowSummaryDetailResponseSchema, at as DownloadActiveProjectSourceResponseSchema, b as CatalogAppDetailResponseSchema, bn as StartMcpOAuthConnectionResultSchema, bt as InviteProjectMembersRequestSchema, c as AgentTriggerSummaryListResponseSchema, cn as PromptResponseSchema, cr as WorkspaceTriggerFileSchema, ct as GatewayAttachmentRecordSchema, d as AutoTopupSummarySchema, dn as QueuedRunResponseSchema, dr as WorkspaceTriggerRunListResponseSchema, dt as GetCustomAppResponseSchema, en as PresignUserAvatarRequestSchema, er as WorkflowRunHooksResponseSchema, f as BillingActivityResponseSchema, fr as WorkspaceWorkflowOverviewSchema, ft as GraphqlDiscoverResponseSchema, g as BillingUsageResponseSchema, gn as SlugAvailabilityResponseSchema, gr as detectProjectPackageManagerFromSnapshot, gt as HistoryRunListQuerySchema, h as BillingSummaryResponseSchema, hn as SkillSummaryListResponseSchema, hr as deriveCustomAppDisplay, ht as HistoryRunDetailResponseSchema, i as AgentSessionDetailResponseSchema, in as ProjectResponseSchema, ir as WorkflowRunResponseSchema, it as DownloadActiveProjectArtifactResponseSchema, j as ConnectProvidersResponseSchema, jn as UpdateAutoTopupRequestSchema, jt as ListOrganizationInvitationsResponseSchema, k as ConnectAuthorizeUrlResponseSchema, kn as TriggerRunDetailResponseSchema, kt as ListCredentialsPageResponseSchema, l as AppSlugAvailabilityResponseSchema, lr as WorkspaceTriggerListResponseSchema, lt as GetAppCatalogEntryResponseSchema, m as BillingRedirectResponseSchema, mn as SkillSummaryDetailResponseSchema, mt as HistoryRunCancelResponseSchema, n as AcceptOrganizationInvitationResponseSchema, nn as ProjectPullStateSchema, nr as WorkflowRunInputsSchema, nt as DOCS_SEARCH_TOOL, o as AgentSummaryDetailResponseSchema, on as ProjectSlugAvailabilityResponseSchema, or as WorkflowSummaryListResponseSchema, ot as ErrorResponseSchema, p as BillingInvoiceUrlResponseSchema, pn as RecentResourceListResponseSchema, pr as buildConnectDeeplink, pt as HealthResponseSchema, q as CredentialAssignmentListQuerySchema, qn as UserAvatarSchema, qt as PROJECT_REACHABILITY_REQUEST_TIMEOUT_MS, r as ActiveOrganizationResponseSchema, rn as ProjectReachabilityResponseSchema, rr as WorkflowRunListResponseSchema, rt as DeclineOrganizationInvitationResponseSchema, s as AgentSummaryListResponseSchema, sn as PromptInputSchema, sr as WorkspaceTriggerDetailSchema, st as ExecuteKeystrokeToolRequestSchema, t as ACTIVE_ORG_HEADER, tn as PresignUserAvatarResponseSchema, tr as WorkflowRunInputsPutBodySchema, tt as DOCS_QUERY_TOOL, u as AssignCredentialBodySchema, un as QueuedAgentPromptResponseSchema, ur as WorkspaceTriggerOverviewSchema, ut as GetCredentialResponseSchema, v as CatalogActionDetailResponseSchema, vn as StartKeystrokeConnectionResultSchema, vr as listenPortFromPublicUrl, vt as InviteOrganizationMembersRequestSchema, w as ChannelConnectionSchema, wn as SubmitTeamRequestRequestSchema, wt as ListAgentWorkspaceFilesResponseSchema, x as CatalogAppsPageResponseSchema, xn as StartOAuthConnectionInputSchema, xr as parseAppSlug, xt as InviteProjectMembersResponseSchema, y as CatalogActionsPageResponseSchema, yn as StartMcpOAuthConnectionInputSchema, yt as InviteOrganizationMembersResponseSchema, z as CreateCustomAppRequestSchema, zn as UpdateProjectMemberRequestSchema, zt as ListProjectsResponseSchema } from "./dist-CEmkrm9b.mjs";
3
3
  import { i as packProjectArtifact, n as withMcpReadClient, r as mergeFilteredArtifact, t as mapInParallelBatches } from "./dist-uPQD-3bl.mjs";
4
- import { _ as resolvePlatformUrlForWebUrl, a as installPlaygroundDependencies, c as isNewerVersion, d as getConfigDir, f as getEffectiveApiTarget, h as DEFAULT_PLATFORM_URL, i as installDependencies$1, l as createCliConfig, m as getWebUrl, n as buildPlaygroundWorkspace, o as resolvePackageManager, p as getPlatformUrl, s as resolveCliRoot, t as readCliVersion, u as getCliConfigDir } from "./version-ikvpTH-2.mjs";
4
+ import { C as getWebUrl, E as resolvePlatformUrlForWebUrl, S as getPlatformUrl, _ as isNewerVersion, a as formatReleaseAgeBlockMessage, b as getConfigDir, c as detectManagerFromLockfile, d as detectPackageManager, f as installDependencies$1, g as resolveCliRoot, h as resolvePackageManager, i as fetchLatestCliRelease, l as readCliVersion, m as resolveGithubPackagesToken, n as computeReleaseAgeRetryAfter, o as isReleaseAgeBlock, p as installPlaygroundDependencies, r as readPnpmMinimumReleaseAgeMinutes, s as detectCliInstall, t as runPackageManagerUpdate, u as buildPlaygroundWorkspace, v as createCliConfig, w as DEFAULT_PLATFORM_URL, x as getEffectiveApiTarget, y as getCliConfigDir } from "./run-package-manager-update-BycMpenj.mjs";
5
5
  import { createRequire } from "node:module";
6
6
  import { Command } from "commander";
7
7
  import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
@@ -6662,12 +6662,12 @@ function registerAuthCommand(program) {
6662
6662
  registerAuthLogoutCommand(auth);
6663
6663
  registerAuthStatusCommand(auth);
6664
6664
  }
6665
- const KEYSTROKE_SCOPE = "@keystrokehq/";
6665
+ const KEYSTROKE_SCOPE$1 = "@keystrokehq/";
6666
6666
  const REGISTRY_TIMEOUT_MS = 3e3;
6667
6667
  function shouldSkip() {
6668
6668
  return Boolean(process.env.KEYSTROKE_SKIP_UPDATE || process.env.CI === "true" || process.env.CI === "1");
6669
6669
  }
6670
- function readPackageJson(root) {
6670
+ function readPackageJson$1(root) {
6671
6671
  const path = join(root, "package.json");
6672
6672
  if (!existsSync(path)) return;
6673
6673
  try {
@@ -6683,7 +6683,7 @@ function isLocalSdkSpec(spec) {
6683
6683
  return trimmed.startsWith("workspace:") || trimmed.startsWith("link:") || trimmed.startsWith("file:");
6684
6684
  }
6685
6685
  function listManagedKeystrokePackages(root) {
6686
- const pkg = readPackageJson(root);
6686
+ const pkg = readPackageJson$1(root);
6687
6687
  if (!pkg) return [];
6688
6688
  const packages = [];
6689
6689
  for (const [name, spec] of Object.entries({
@@ -6691,11 +6691,11 @@ function listManagedKeystrokePackages(root) {
6691
6691
  ...pkg.devDependencies
6692
6692
  })) {
6693
6693
  if (name === "@keystrokehq/cli") continue;
6694
- if (name.startsWith(KEYSTROKE_SCOPE) && !isLocalSdkSpec(spec)) packages.push({ name });
6694
+ if (name.startsWith(KEYSTROKE_SCOPE$1) && !isLocalSdkSpec(spec)) packages.push({ name });
6695
6695
  }
6696
6696
  return packages;
6697
6697
  }
6698
- function readInstalledVersion(root, packageName) {
6698
+ function readInstalledVersion$1(root, packageName) {
6699
6699
  const path = join(root, "node_modules", ...packageName.split("/"), "package.json");
6700
6700
  if (!existsSync(path)) return;
6701
6701
  try {
@@ -6727,7 +6727,7 @@ function formatOutdatedLine(pkg) {
6727
6727
  }
6728
6728
  async function packagesNeedingUpdate(root, packages) {
6729
6729
  return (await Promise.all(packages.map(async (pkg) => {
6730
- const installed = readInstalledVersion(root, pkg.name);
6730
+ const installed = readInstalledVersion$1(root, pkg.name);
6731
6731
  const latest = await fetchLatestPackageVersion(pkg.name);
6732
6732
  if (!latest) return installed ? void 0 : {
6733
6733
  name: pkg.name,
@@ -6751,7 +6751,7 @@ async function ensureSdkCurrent(root) {
6751
6751
  const outdated = await packagesNeedingUpdate(root, packages);
6752
6752
  if (outdated.length === 0) return;
6753
6753
  const lines = outdated.map(formatOutdatedLine).join("\n");
6754
- throw new Error(`Outdated @keystrokehq packages:\n${lines}\n\nPlease update your versions before continuing.`);
6754
+ throw new Error(`Outdated @keystrokehq packages:\n${lines}\n\nPlease run \`keystroke update\` before continuing.`);
6755
6755
  }
6756
6756
  //#endregion
6757
6757
  //#region src/commands/build.ts
@@ -8485,6 +8485,177 @@ function registerTriggersCommand(program) {
8485
8485
  registerTriggerToggleCommands(triggers);
8486
8486
  }
8487
8487
  //#endregion
8488
+ //#region src/update/update-project-packages.ts
8489
+ const KEYSTROKE_SCOPE = "@keystrokehq/";
8490
+ function readPackageJson(root) {
8491
+ const path = join(root, "package.json");
8492
+ if (!existsSync(path)) return;
8493
+ try {
8494
+ return JSON.parse(readFileSync(path, "utf8"));
8495
+ } catch (error) {
8496
+ const detail = error instanceof Error ? error.message : String(error);
8497
+ throw new Error(`Failed to read package.json at ${path}: ${detail}`);
8498
+ }
8499
+ }
8500
+ /** Registry-managed @keystrokehq/* deps (excludes workspace/link/file). */
8501
+ function listUpdatableKeystrokePackages(root) {
8502
+ const pkg = readPackageJson(root);
8503
+ if (!pkg) return [];
8504
+ const packages = [];
8505
+ for (const [name, spec] of Object.entries(pkg.dependencies ?? {})) {
8506
+ if (name === "@keystrokehq/cli") continue;
8507
+ if (name.startsWith(KEYSTROKE_SCOPE) && !isLocalSdkSpec(spec)) packages.push({
8508
+ name,
8509
+ dev: false
8510
+ });
8511
+ }
8512
+ for (const [name, spec] of Object.entries(pkg.devDependencies ?? {})) {
8513
+ if (name === "@keystrokehq/cli") continue;
8514
+ if (name.startsWith(KEYSTROKE_SCOPE) && !isLocalSdkSpec(spec)) packages.push({
8515
+ name,
8516
+ dev: true
8517
+ });
8518
+ }
8519
+ return packages;
8520
+ }
8521
+ function readInstalledVersion(root, packageName) {
8522
+ const path = join(root, "node_modules", ...packageName.split("/"), "package.json");
8523
+ if (!existsSync(path)) return;
8524
+ try {
8525
+ return JSON.parse(readFileSync(path, "utf8")).version?.trim() || void 0;
8526
+ } catch {
8527
+ return;
8528
+ }
8529
+ }
8530
+ function updateCommand(manager, packageName, dev) {
8531
+ const spec = `${packageName}@latest`;
8532
+ if (manager === "npm") return {
8533
+ command: "npm",
8534
+ args: dev ? [
8535
+ "install",
8536
+ "-D",
8537
+ spec
8538
+ ] : ["install", spec]
8539
+ };
8540
+ return {
8541
+ command: manager,
8542
+ args: dev ? [
8543
+ "add",
8544
+ "-D",
8545
+ spec
8546
+ ] : ["add", spec]
8547
+ };
8548
+ }
8549
+ function warnReleaseAgeBlock(packageName) {
8550
+ process.stderr.write(`Warning: ${packageName}@latest is held back by your minimum-release-age setting; continuing with the currently installed version.\n`);
8551
+ }
8552
+ /**
8553
+ * Install @latest for every managed project @keystrokehq/* dependency.
8554
+ * Skips `@keystrokehq/cli` (global; refreshed separately by `keystroke update`).
8555
+ * Release-age blocks warn and continue; other install failures throw.
8556
+ */
8557
+ function updateProjectPackages(root) {
8558
+ const packages = listUpdatableKeystrokePackages(root);
8559
+ if (packages.length === 0) return {
8560
+ updated: [],
8561
+ skippedReleaseAge: []
8562
+ };
8563
+ const manager = detectManagerFromLockfile(root) ?? detectPackageManager();
8564
+ const token = resolveGithubPackagesToken();
8565
+ const env = token ? {
8566
+ ...process.env,
8567
+ NODE_AUTH_TOKEN: token
8568
+ } : process.env;
8569
+ const updated = [];
8570
+ const skippedReleaseAge = [];
8571
+ for (const pkg of packages) {
8572
+ const from = readInstalledVersion(root, pkg.name);
8573
+ const { command, args } = updateCommand(manager, pkg.name, pkg.dev);
8574
+ process.stderr.write(`Updating ${pkg.name}...\n`);
8575
+ const result = spawnSync(command, args, {
8576
+ cwd: root,
8577
+ env,
8578
+ encoding: "utf8"
8579
+ });
8580
+ if (result.status === 0) {
8581
+ const to = readInstalledVersion(root, pkg.name);
8582
+ if (to && to !== from) updated.push({
8583
+ name: pkg.name,
8584
+ from,
8585
+ to
8586
+ });
8587
+ continue;
8588
+ }
8589
+ const output = `${result.stdout ?? ""}${result.stderr ?? ""}`;
8590
+ if (isReleaseAgeBlock(output)) {
8591
+ warnReleaseAgeBlock(pkg.name);
8592
+ skippedReleaseAge.push(pkg.name);
8593
+ continue;
8594
+ }
8595
+ throw new Error(`Failed to update ${pkg.name}:\n${output.trim() || `${command} exited ${result.status}`}`);
8596
+ }
8597
+ return {
8598
+ updated,
8599
+ skippedReleaseAge
8600
+ };
8601
+ }
8602
+ //#endregion
8603
+ //#region src/commands/update.ts
8604
+ async function updateCliInstall() {
8605
+ if (process.env.KEYSTROKE_DEV) return;
8606
+ const install = detectCliInstall(resolveCliRoot(import.meta.url));
8607
+ if (!install || install.kind === "local" && !install.projectRoot) return;
8608
+ const currentVersion = readCliVersion();
8609
+ const release = await fetchLatestCliRelease();
8610
+ if (!release || !isNewerVersion(release.version, currentVersion)) {
8611
+ process.stdout.write(`@keystrokehq/cli is up to date (${currentVersion}).\n`);
8612
+ return;
8613
+ }
8614
+ process.stderr.write(`Updating @keystrokehq/cli ${currentVersion} -> ${release.version} via ${install.packageManager}...\n`);
8615
+ const result = runPackageManagerUpdate(install);
8616
+ const installedVersion = readCliVersion();
8617
+ if (isNewerVersion(installedVersion, currentVersion)) {
8618
+ process.stdout.write(`Updated @keystrokehq/cli ${currentVersion} -> ${installedVersion}.\n`);
8619
+ return;
8620
+ }
8621
+ if (result.ok) {
8622
+ process.stdout.write(`@keystrokehq/cli is up to date (${installedVersion}).\n`);
8623
+ return;
8624
+ }
8625
+ if (isReleaseAgeBlock(result.output)) {
8626
+ const retryAfter = install.packageManager === "pnpm" ? computeReleaseAgeRetryAfter(release.publishedAt, readPnpmMinimumReleaseAgeMinutes()) : void 0;
8627
+ process.stderr.write(`${formatReleaseAgeBlockMessage({
8628
+ currentVersion,
8629
+ availableVersion: release.version,
8630
+ retryAfter
8631
+ })}\n`);
8632
+ return;
8633
+ }
8634
+ throw new Error(`Failed to update @keystrokehq/cli:\n${result.output.trim() || "package manager update failed"}`);
8635
+ }
8636
+ async function runUpdate(options) {
8637
+ const result = updateProjectPackages(resolveProjectRoot(options.dir));
8638
+ if (result.updated.length === 0 && result.skippedReleaseAge.length === 0) process.stdout.write("Project @keystrokehq packages are up to date.\n");
8639
+ else {
8640
+ for (const pkg of result.updated) {
8641
+ const range = pkg.from && pkg.to ? `${pkg.from} -> ${pkg.to}` : pkg.to ? `-> ${pkg.to}` : "updated";
8642
+ process.stdout.write(`Updated ${pkg.name} (${range}).\n`);
8643
+ }
8644
+ if (result.updated.length === 0 && result.skippedReleaseAge.length > 0) process.stdout.write("No project @keystrokehq packages were updated.\n");
8645
+ }
8646
+ await updateCliInstall();
8647
+ }
8648
+ function registerUpdateCommand(program) {
8649
+ program.command("update").description("Update @keystrokehq packages and the CLI to latest").option("--dir <path>", "Project directory", process.cwd()).action(async (options) => {
8650
+ try {
8651
+ await runUpdate(options);
8652
+ } catch (error) {
8653
+ process.stderr.write(`${formatCliError(error, "update failed")}\n`);
8654
+ process.exitCode = 1;
8655
+ }
8656
+ });
8657
+ }
8658
+ //#endregion
8488
8659
  //#region src/commands/workflows/list.ts
8489
8660
  function registerWorkflowListCommand(workflow) {
8490
8661
  workflow.command("list").description("List workflows in the active organization").option("--admin", "List all org resources (org owner or admin only)").action((options) => runCliCommand("List workflows failed", async () => {
@@ -8840,6 +9011,7 @@ function createProgram() {
8840
9011
  registerTestCommand(program);
8841
9012
  registerDeployCommand(program);
8842
9013
  registerPullCommand(program);
9014
+ registerUpdateCommand(program);
8843
9015
  registerDevCommand(program);
8844
9016
  registerStartCommand(program);
8845
9017
  registerAgentsCommand(program);
@@ -8850,7 +9022,7 @@ function createProgram() {
8850
9022
  return program;
8851
9023
  }
8852
9024
  async function runCli(argv) {
8853
- const { maybeAutoUpdate } = await import("./maybe-auto-update-B3xm1MYv.mjs");
9025
+ const { maybeAutoUpdate } = await import("./maybe-auto-update-x2nClrff.mjs");
8854
9026
  await maybeAutoUpdate(argv);
8855
9027
  createProgram().parse(argv);
8856
9028
  }