@keystrokehq/cli 0.0.165 → 0.0.167

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 +11 -0
  2. package/dist/dist-BMPry9tj.mjs +577 -0
  3. package/dist/dist-BMPry9tj.mjs.map +1 -0
  4. package/dist/dist-CegYAHE0.mjs +3 -0
  5. package/dist/{schemas-Bq8SXmZk.mjs → dist-D_0UmqFb.mjs} +2113 -6
  6. package/dist/dist-D_0UmqFb.mjs.map +1 -0
  7. package/dist/{dist-CgV0MxBq.mjs → dist-WoxxHzM6.mjs} +123 -25
  8. package/dist/dist-WoxxHzM6.mjs.map +1 -0
  9. package/dist/index.mjs +147 -37
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/{maybe-auto-update-CIcDJRrg.mjs → maybe-auto-update-B03C4E8i.mjs} +2 -2
  12. package/dist/{maybe-auto-update-CIcDJRrg.mjs.map → maybe-auto-update-B03C4E8i.mjs.map} +1 -1
  13. package/dist/skills-bundle/_AGENTS.md +7 -3
  14. package/dist/skills-bundle/skills/keystroke-actions/SKILL.md +1 -1
  15. package/dist/skills-bundle/skills/keystroke-actions/references/catalog-and-imports.md +2 -3
  16. package/dist/skills-bundle/skills/keystroke-agents/references/tools-mcp-codemode.md +1 -1
  17. package/dist/skills-bundle/skills/keystroke-cli/SKILL.md +4 -2
  18. package/dist/skills-bundle/skills/keystroke-deploy/SKILL.md +92 -0
  19. package/dist/skills-bundle/skills/keystroke-deploy/references/build-and-full-deploy.md +28 -0
  20. package/dist/skills-bundle/skills/keystroke-deploy/references/filtered-deploy.md +49 -0
  21. package/dist/skills-bundle/skills/keystroke-deploy/references/wip-ignore.md +32 -0
  22. package/dist/skills-bundle/skills/keystroke-gateways/SKILL.md +5 -6
  23. package/dist/skills-bundle/skills/keystroke-gateways/references/slack-setup.md +0 -11
  24. package/dist/templates/hello-world/README.md +1 -1
  25. package/dist/templates/hello-world/keystroke.config.ts +1 -5
  26. package/dist/{version-DdbxgFWa.mjs → version-FrEOAEU7.mjs} +2 -2
  27. package/dist/{version-DdbxgFWa.mjs.map → version-FrEOAEU7.mjs.map} +1 -1
  28. package/package.json +1 -1
  29. package/dist/discovery-DV7FkTRA-JYiC_9cY.mjs +0 -71
  30. package/dist/discovery-DV7FkTRA-JYiC_9cY.mjs.map +0 -1
  31. package/dist/dist-CgV0MxBq.mjs.map +0 -1
  32. package/dist/dist-DtqmE5R_.mjs +0 -2113
  33. package/dist/dist-DtqmE5R_.mjs.map +0 -1
  34. package/dist/dist-sXdjEZpP.mjs +0 -293
  35. package/dist/dist-sXdjEZpP.mjs.map +0 -1
  36. package/dist/schemas-Bq8SXmZk.mjs.map +0 -1
  37. package/dist/walk-project-171B4cvO-DKtupJ6Z.mjs +0 -102
  38. package/dist/walk-project-171B4cvO-DKtupJ6Z.mjs.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { $ as OrganizationSidebarBrandingPatchSchema, $t as parseErrorResponse, A as ErrorResponseSchema, At as UpdateCredentialInstanceBodySchema, B as InviteProjectMembersRequestSchema, Bt as UploadProjectSourceResponseSchema, C as CreateOrganizationResponseSchema, Ct as StartOAuthConnectionResultSchema, D as CredentialInstanceListResponseSchema, Dt as TriggerRunDetailResponseSchema, E as CreateProjectResponseSchema, Et as TriggerListResponseSchema, F as HistoryRunDetailResponseSchema, Ft as UpdateProjectMemberRequestSchema, G as ListOrganizationInvitationsResponseSchema, Gt as UserPreferencesSchema, H as ListApiKeysResponseSchema, Ht as UserAvatarPatchSchema, I as HistoryRunListQuerySchema, It as UpdateProjectMemberResponseSchema, J as ListProjectDeploymentsResponseSchema, Jt as WorkflowSummaryDetailResponseSchema, K as ListOrganizationMembersResponseSchema, Kt as WorkflowRunDetailResponseSchema, L as HistoryRunListResponseSchema, Lt as UpdateProjectRequestSchema, M as GetCredentialResponseSchema, Mt as UpdateOrganizationMemberRequestSchema, N as HealthResponseSchema, Nt as UpdateOrganizationMemberResponseSchema, O as CredentialInstanceRecordSchema, Ot as TriggerRunListResponseSchema, P as HistoryRunCancelResponseSchema, Pt as UpdateOrganizationRequestSchema, Q as ListProjectsResponseSchema, R as InviteOrganizationMembersRequestSchema, Rt as UpdateProjectSettingsRequestSchema, S as CreateOrganizationRequestSchema, St as StartOAuthConnectionInputSchema, T as CreateProjectRequestSchema, Tt as TriggerDetailResponseSchema, U as ListAppsResponseSchema, Ut as UserAvatarSchema, V as InviteProjectMembersResponseSchema, Vt as UpsertGatewayAttachmentBodySchema, W as ListCredentialsResponseSchema, Wt as UserPreferencesPatchSchema, X as ListProjectMembersResponseSchema, Xt as listenPortFromPublicUrl, Y as ListProjectFilesResponseSchema, Yt as WorkflowSummaryListResponseSchema, Z as ListProjectMetricsResponseSchema, _ as CreateApiKeyRequestSchema, _t as ROUTE_MANIFEST_REL_PATH, a as AgentSessionListResponseSchema, at as PresignProjectSourceRequestSchema, b as CreateCredentialsRequestSchema, bt as SkillSummaryListResponseSchema, c as BindChannelBodySchema, ct as PresignUserAvatarResponseSchema, d as ChannelConnectionSchema, dt as ProjectSettingsResponseSchema, et as OrganizationSidebarBrandingSchema, f as ChannelDirectoryListResponseSchema, ft as ProjectSlugAvailabilityResponseSchema, g as ConnectProvidersResponseSchema, gt as QueuedRunResponseSchema, h as ConnectAuthorizeUrlResponseSchema, ht as QueuedAgentPromptResponseSchema, i as AgentSessionDetailResponseSchema, it as PresignOrgLogoResponseSchema, j as GatewayAttachmentRecordSchema, jt as UpdateCredentialRequestSchema, k as DeclineOrganizationInvitationResponseSchema, kt as UpdateChannelBindingBodySchema, l as ChannelAccountListResponseSchema, lt as ProjectReachabilityResponseSchema, m as CompleteProjectArtifactResponseSchema, mt as PromptResponseSchema, n as AcceptOrganizationInvitationResponseSchema, nt as PollRunResponseSchema, o as AgentSummaryDetailResponseSchema, ot as PresignProjectSourceResponseSchema, p as ChannelPlatformSchema, pt as PromptInputSchema, q as ListOrganizationsResponseSchema, qt as WorkflowRunListResponseSchema, r as ActiveOrganizationResponseSchema, rt as PresignOrgLogoRequestSchema, s as AgentSummaryListResponseSchema, st as PresignUserAvatarRequestSchema, t as ACTIVE_ORG_HEADER, tt as PROJECT_REACHABILITY_REQUEST_TIMEOUT_MS, u as ChannelConnectionListResponseSchema, ut as ProjectResponseSchema, v as CreateApiKeyResponseSchema, vt as RecentResourceListResponseSchema, w as CreateProjectArtifactResponseSchema, wt as SubmitTeamRequestRequestSchema, x as CreateCredentialsResponseSchema, xt as SlugAvailabilityResponseSchema, y as CreateCredentialInstanceBodySchema, yt as SkillSummaryDetailResponseSchema, z as InviteOrganizationMembersResponseSchema, zt as UploadProjectSourceManifestRequestSchema } from "./dist-DtqmE5R_.mjs";
3
- import { _ as resolvePlatformUrlForWebUrl, a as installPlaygroundDependencies, c as createCliConfig, d as getEffectiveApiTarget, f as getPlatformUrl, h as DEFAULT_PLATFORM_URL, i as installDependencies, l as getCliConfigDir, m as getWebUrl, n as buildPlaygroundWorkspace, o as resolvePackageManager, p as getServerUrl, s as resolveCliRoot, t as readCliVersion, u as getConfigDir } from "./version-DdbxgFWa.mjs";
4
- import { t as walkProject } from "./walk-project-171B4cvO-DKtupJ6Z.mjs";
2
+ import { $ as ListProjectsResponseSchema, A as DownloadActiveProjectArtifactResponseSchema, At as TriggerRunListResponseSchema, B as InviteOrganizationMembersResponseSchema, Bt as UpdateProjectSettingsRequestSchema, C as CreateOrganizationResponseSchema, Ct as StartOAuthConnectionInputSchema, D as CredentialInstanceListResponseSchema, Dt as TriggerDetailResponseSchema, E as CreateProjectResponseSchema, Et as SubmitTeamRequestRequestSchema, F as HistoryRunCancelResponseSchema, Ft as UpdateOrganizationMemberResponseSchema, G as ListCredentialsResponseSchema, Gt as UserAvatarSchema, H as InviteProjectMembersResponseSchema, Ht as UploadProjectSourceResponseSchema, I as HistoryRunDetailResponseSchema, It as UpdateOrganizationRequestSchema, J as ListOrganizationsResponseSchema, Jt as WorkflowRunDetailResponseSchema, K as ListOrganizationInvitationsResponseSchema, Kt as UserPreferencesPatchSchema, L as HistoryRunListQuerySchema, Lt as UpdateProjectMemberRequestSchema, M as GatewayAttachmentRecordSchema, Mt as UpdateCredentialInstanceBodySchema, N as GetCredentialResponseSchema, Nt as UpdateCredentialRequestSchema, O as CredentialInstanceRecordSchema, Ot as TriggerListResponseSchema, P as HealthResponseSchema, Pt as UpdateOrganizationMemberRequestSchema, Q as ListProjectMetricsResponseSchema, Qt as listenPortFromPublicUrl, R as HistoryRunListResponseSchema, Rt as UpdateProjectMemberResponseSchema, S as CreateOrganizationRequestSchema, St as SlugAvailabilityResponseSchema, T as CreateProjectRequestSchema, Tt as StoredRouteManifestSchema, U as ListApiKeysResponseSchema, Ut as UpsertGatewayAttachmentBodySchema, V as InviteProjectMembersRequestSchema, Vt as UploadProjectSourceManifestRequestSchema, W as ListAppsResponseSchema, Wt as UserAvatarPatchSchema, X as ListProjectFilesResponseSchema, Xt as WorkflowSummaryDetailResponseSchema, Y as ListProjectDeploymentsResponseSchema, Yt as WorkflowRunListResponseSchema, Z as ListProjectMembersResponseSchema, Zt as WorkflowSummaryListResponseSchema, _ as CreateApiKeyRequestSchema, _t as QueuedRunResponseSchema, a as AgentSessionListResponseSchema, at as PresignOrgLogoResponseSchema, b as CreateCredentialsRequestSchema, bt as SkillSummaryDetailResponseSchema, c as BindChannelBodySchema, ct as PresignUserAvatarRequestSchema, d as ChannelConnectionSchema, dt as ProjectResponseSchema, et as OrganizationSidebarBrandingPatchSchema, f as ChannelDirectoryListResponseSchema, ft as ProjectSettingsResponseSchema, g as ConnectProvidersResponseSchema, gt as QueuedAgentPromptResponseSchema, h as ConnectAuthorizeUrlResponseSchema, ht as PromptResponseSchema, i as AgentSessionDetailResponseSchema, it as PresignOrgLogoRequestSchema, j as ErrorResponseSchema, jt as UpdateChannelBindingBodySchema, k as DeclineOrganizationInvitationResponseSchema, kt as TriggerRunDetailResponseSchema, l as ChannelAccountListResponseSchema, lt as PresignUserAvatarResponseSchema, m as CompleteProjectArtifactResponseSchema, mt as PromptInputSchema, n as AcceptOrganizationInvitationResponseSchema, nt as PROJECT_REACHABILITY_REQUEST_TIMEOUT_MS, o as AgentSummaryDetailResponseSchema, ot as PresignProjectSourceRequestSchema, p as ChannelPlatformSchema, pt as ProjectSlugAvailabilityResponseSchema, q as ListOrganizationMembersResponseSchema, qt as UserPreferencesSchema, r as ActiveOrganizationResponseSchema, rt as PollRunResponseSchema, s as AgentSummaryListResponseSchema, st as PresignProjectSourceResponseSchema, t as ACTIVE_ORG_HEADER, tn as parseErrorResponse, tt as OrganizationSidebarBrandingSchema, u as ChannelConnectionListResponseSchema, ut as ProjectReachabilityResponseSchema, v as CreateApiKeyResponseSchema, vt as ROUTE_MANIFEST_REL_PATH, w as CreateProjectArtifactResponseSchema, wt as StartOAuthConnectionResultSchema, x as CreateCredentialsResponseSchema, xt as SkillSummaryListResponseSchema, y as CreateCredentialInstanceBodySchema, yt as RecentResourceListResponseSchema, z as InviteOrganizationMembersRequestSchema, zt as UpdateProjectRequestSchema } from "./dist-D_0UmqFb.mjs";
3
+ import { _ as resolvePlatformUrlForWebUrl, a as installPlaygroundDependencies, c as createCliConfig, d as getEffectiveApiTarget, f as getPlatformUrl, h as DEFAULT_PLATFORM_URL, i as installDependencies, l as getCliConfigDir, m as getWebUrl, n as buildPlaygroundWorkspace, o as resolvePackageManager, p as getServerUrl, s as resolveCliRoot, t as readCliVersion, u as getConfigDir } from "./version-FrEOAEU7.mjs";
5
4
  import { createRequire } from "node:module";
6
5
  import { Command } from "commander";
7
6
  import { platform, tmpdir } from "node:os";
@@ -10,8 +9,8 @@ import { Entry } from "@napi-rs/keyring";
10
9
  import { confirm, input, select } from "@inquirer/prompts";
11
10
  import { existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
12
11
  import { spawn, spawnSync } from "node:child_process";
13
- import { access, copyFile, cp, lstat, mkdir, readFile, readdir, rm, stat, symlink, unlink, writeFile } from "node:fs/promises";
14
12
  import { pathToFileURL } from "node:url";
13
+ import { access, copyFile, cp, lstat, mkdir, readFile, readdir, rm, stat, symlink, unlink, writeFile } from "node:fs/promises";
15
14
  //#region ../../node_modules/.pnpm/ky@2.0.2/node_modules/ky/distribution/errors/KyError.js
16
15
  /**
17
16
  Base class for all Ky-specific errors. `HTTPError`, `NetworkError`, `TimeoutError`, and `ForceRetryError` extend this class.
@@ -3395,6 +3394,26 @@ function createArtifactsResource(http) {
3395
3394
  } catch (error) {
3396
3395
  throw await toPlatformError(error);
3397
3396
  }
3397
+ },
3398
+ /** Presigned GET for the project's currently active deploy artifact tarball. */
3399
+ async downloadActive(projectId) {
3400
+ try {
3401
+ const data = await http.get(`/api/projects/${encodeURIComponent(projectId)}/artifacts/active/download`).json();
3402
+ return DownloadActiveProjectArtifactResponseSchema.parse(data);
3403
+ } catch (error) {
3404
+ throw await toPlatformError(error);
3405
+ }
3406
+ },
3407
+ /** Download the active artifact tarball bytes via the presigned URL. */
3408
+ async downloadActiveArchive(projectId) {
3409
+ const { artifactId, downloadUrl } = await this.downloadActive(projectId);
3410
+ const response = await fetch(downloadUrl);
3411
+ if (!response.ok) throw new Error(`Active artifact download failed (${response.status})`);
3412
+ const bytes = await response.arrayBuffer();
3413
+ return {
3414
+ artifactId,
3415
+ buffer: Buffer.from(bytes)
3416
+ };
3398
3417
  }
3399
3418
  };
3400
3419
  }
@@ -5457,7 +5476,7 @@ function registerBuildCommand(program) {
5457
5476
  program.command("build").description("Build the keystroke project for production").option("--dir <path>", "Project directory", process.cwd()).action(async (options) => {
5458
5477
  try {
5459
5478
  const root = resolveProjectRoot(options.dir);
5460
- const { buildApp } = await import("./dist-sXdjEZpP.mjs");
5479
+ const { buildApp } = await import("./dist-BMPry9tj.mjs");
5461
5480
  await buildApp({ root });
5462
5481
  process.stdout.write(`Built ${root}\n`);
5463
5482
  } catch (error) {
@@ -5468,11 +5487,13 @@ function registerBuildCommand(program) {
5468
5487
  });
5469
5488
  }
5470
5489
  //#endregion
5471
- //#region ../../packages/storage/dist/pack-artifact.mjs
5472
- /** Pack `dist/` into a gzip tarball suitable for `/app` extraction in the project server image. */
5473
- function packProjectArtifact(projectRoot) {
5474
- if (!existsSync(join(projectRoot, "dist"))) throw new Error("dist/ not found — run keystroke build first");
5475
- const tempDir = mkdtempSync(join(tmpdir(), "keystroke-artifact-"));
5490
+ //#region ../../packages/storage/dist/pack-artifact-NGxvGcXq.mjs
5491
+ /**
5492
+ * Pack a directory tree that contains a `dist/` folder into a gzip tarball
5493
+ * suitable for project-server extraction.
5494
+ */
5495
+ function packDistTree(rootContainingDist) {
5496
+ const tempDir = mkdtempSync(join(tmpdir(), "keystroke-artifact-pack-"));
5476
5497
  const archivePath = join(tempDir, "artifact.tgz");
5477
5498
  try {
5478
5499
  const result = spawnSync("tar", [
@@ -5481,7 +5502,7 @@ function packProjectArtifact(projectRoot) {
5481
5502
  "--exclude=._*",
5482
5503
  "--exclude=.DS_Store",
5483
5504
  "-C",
5484
- projectRoot,
5505
+ rootContainingDist,
5485
5506
  "dist"
5486
5507
  ], {
5487
5508
  encoding: "utf8",
@@ -5499,12 +5520,74 @@ function packProjectArtifact(projectRoot) {
5499
5520
  });
5500
5521
  }
5501
5522
  }
5502
- //#endregion
5503
- //#region src/project/collect-source.ts
5504
- /** Collect deploy source files via the shared project walk (for `--skip-build`). */
5505
- function collectProjectSource(root) {
5506
- if (!existsSync(join(root, "dist/.keystroke/route-manifest.json"))) throw new Error(`Route manifest missing at ${ROUTE_MANIFEST_REL_PATH}. Run keystroke build before deploy --skip-build.`);
5507
- return { files: walkProject(root, { collectSources: true }).sourceFiles };
5523
+ /** Extract a packed project artifact tarball into `destDir` (creates `destDir/dist/`). */
5524
+ function extractProjectArtifact(archive, destDir) {
5525
+ const tempDir = mkdtempSync(join(tmpdir(), "keystroke-artifact-extract-"));
5526
+ const archivePath = join(tempDir, "artifact.tgz");
5527
+ try {
5528
+ writeFileSync(archivePath, archive);
5529
+ const result = spawnSync("tar", [
5530
+ "-xzf",
5531
+ archivePath,
5532
+ "-C",
5533
+ destDir
5534
+ ], {
5535
+ encoding: "utf8",
5536
+ env: {
5537
+ ...process.env,
5538
+ COPYFILE_DISABLE: "1"
5539
+ }
5540
+ });
5541
+ if (result.status !== 0) throw new Error(result.stderr?.trim() || "Failed to extract project artifact");
5542
+ } finally {
5543
+ rmSync(tempDir, {
5544
+ recursive: true,
5545
+ force: true
5546
+ });
5547
+ }
5548
+ }
5549
+ function moduleFileOf(entry) {
5550
+ return "moduleFile" in entry && typeof entry.moduleFile === "string" ? entry.moduleFile : void 0;
5551
+ }
5552
+ /** Replace manifest rows for rebuilt modules while keeping untouched routes and metadata. */
5553
+ function mergeStoredRouteManifest(base, rebuiltEntries) {
5554
+ const rebuiltModuleFiles = new Set(rebuiltEntries.map(moduleFileOf).filter((value) => Boolean(value)));
5555
+ const keptEntries = base.entries.filter((entry) => {
5556
+ const moduleFile = moduleFileOf(entry);
5557
+ if (!moduleFile) return true;
5558
+ return !rebuiltModuleFiles.has(moduleFile);
5559
+ });
5560
+ const filteredRebuilt = rebuiltEntries.filter((entry) => entry.kind !== "health");
5561
+ return {
5562
+ ...base,
5563
+ entries: [...keptEntries, ...filteredRebuilt]
5564
+ };
5565
+ }
5566
+ async function mergeFilteredArtifact(input) {
5567
+ const mergeRoot = mkdtempSync(join(tmpdir(), "keystroke-artifact-merge-"));
5568
+ try {
5569
+ extractProjectArtifact(input.baseArchive, mergeRoot);
5570
+ const manifestPath = join(mergeRoot, ROUTE_MANIFEST_REL_PATH);
5571
+ const mergedManifest = mergeStoredRouteManifest(StoredRouteManifestSchema.parse(JSON.parse(readFileSync(manifestPath, "utf8"))), input.filtered.manifestEntries);
5572
+ writeFileSync(manifestPath, `${JSON.stringify(mergedManifest, null, 2)}\n`);
5573
+ for (const file of input.filtered.files) {
5574
+ const destination = join(mergeRoot, "dist", file.relativePath);
5575
+ mkdirSync(dirname(destination), { recursive: true });
5576
+ writeFileSync(destination, file.contents);
5577
+ if (file.sourceMap) writeFileSync(`${destination}.map`, file.sourceMap);
5578
+ }
5579
+ return packDistTree(mergeRoot);
5580
+ } finally {
5581
+ rmSync(mergeRoot, {
5582
+ recursive: true,
5583
+ force: true
5584
+ });
5585
+ }
5586
+ }
5587
+ /** Pack `dist/` into a gzip tarball suitable for `/app` extraction in the project server image. */
5588
+ function packProjectArtifact(projectRoot) {
5589
+ if (!existsSync(join(projectRoot, "dist"))) throw new Error("dist/ not found — run keystroke build first");
5590
+ return packDistTree(projectRoot);
5508
5591
  }
5509
5592
  //#endregion
5510
5593
  //#region src/commands/deploy.ts
@@ -5517,10 +5600,10 @@ const SOURCE_BLOB_CONTENT_TYPE = "text/plain; charset=utf-8";
5517
5600
  * unchanged files are never re-uploaded. The manifest (path -> hash) is sent
5518
5601
  * last and marks the snapshot complete.
5519
5602
  */
5520
- async function uploadProjectSourceSnapshot(client, projectId, artifactId, source) {
5603
+ async function uploadProjectSourceSnapshot(client, projectId, artifactId, files) {
5521
5604
  const contentsByHash = /* @__PURE__ */ new Map();
5522
5605
  const blobsByHash = /* @__PURE__ */ new Map();
5523
- for (const file of source.files) {
5606
+ for (const file of files) {
5524
5607
  contentsByHash.set(file.hash, file.contents);
5525
5608
  if (!blobsByHash.has(file.hash)) blobsByHash.set(file.hash, {
5526
5609
  hash: file.hash,
@@ -5538,7 +5621,7 @@ async function uploadProjectSourceSnapshot(client, projectId, artifactId, source
5538
5621
  });
5539
5622
  if (!response.ok) throw new Error(`Source blob upload failed (${response.status})`);
5540
5623
  }));
5541
- await client.artifacts.uploadManifest(projectId, artifactId, { files: source.files.map((file) => ({
5624
+ await client.artifacts.uploadManifest(projectId, artifactId, { files: files.map((file) => ({
5542
5625
  path: file.path,
5543
5626
  hash: file.hash
5544
5627
  })) });
@@ -5548,31 +5631,58 @@ async function sleep(ms) {
5548
5631
  setTimeout(resolve, ms);
5549
5632
  });
5550
5633
  }
5634
+ async function buildDeployArchive(client, root, projectId, filter) {
5635
+ if (filter?.length) {
5636
+ const { buildFilteredApp } = await import("./dist-BMPry9tj.mjs");
5637
+ const filtered = await buildFilteredApp({
5638
+ root,
5639
+ filter,
5640
+ collectSources: true,
5641
+ phase: "deploy"
5642
+ });
5643
+ let activeArchive;
5644
+ try {
5645
+ ({buffer: activeArchive} = await client.artifacts.downloadActiveArchive(projectId));
5646
+ } catch (error) {
5647
+ if (error instanceof PlatformError && error.status === 404) throw new Error("Targeted deploy requires an active artifact — run a full deploy first");
5648
+ throw error;
5649
+ }
5650
+ return {
5651
+ archive: await mergeFilteredArtifact({
5652
+ baseArchive: activeArchive,
5653
+ filtered
5654
+ }),
5655
+ sourceFiles: filtered.sourceFiles
5656
+ };
5657
+ }
5658
+ const { buildApp } = await import("./dist-BMPry9tj.mjs");
5659
+ const { sourceFiles } = await buildApp({
5660
+ root,
5661
+ collectSources: true,
5662
+ emitManifest: true,
5663
+ phase: "deploy"
5664
+ });
5665
+ return {
5666
+ archive: packProjectArtifact(root),
5667
+ sourceFiles
5668
+ };
5669
+ }
5551
5670
  async function runDeploy(options) {
5552
5671
  const root = resolveProjectRoot(options.dir);
5553
5672
  const config = createCliConfig();
5554
5673
  const client = createCliPlatformClient(config);
5555
- let source;
5556
- if (!options.skipBuild) {
5557
- const { buildApp } = await import("./dist-sXdjEZpP.mjs");
5558
- source = { files: (await buildApp({
5559
- root,
5560
- collectSources: true,
5561
- emitManifest: true
5562
- })).sourceFiles };
5563
- } else source = collectProjectSource(root);
5564
- const archive = packProjectArtifact(root);
5565
5674
  let active = await client.organizations.getActive();
5566
5675
  if (!active) active = await selectActiveOrganization(config);
5567
5676
  client.setActiveOrganizationId(active.organization.id);
5568
5677
  const project = await client.projects.get(options.projectId);
5678
+ const { archive, sourceFiles } = await buildDeployArchive(client, root, project.id, options.filter);
5569
5679
  const created = await client.artifacts.create(project.id);
5570
5680
  const uploadPromise = fetch(created.uploadUrl, {
5571
5681
  method: "PUT",
5572
5682
  body: archive,
5573
5683
  headers: { "Content-Type": "application/gzip" }
5574
5684
  });
5575
- const sourcePromise = uploadProjectSourceSnapshot(client, project.id, created.artifact.id, source).catch((error) => {
5685
+ const sourcePromise = uploadProjectSourceSnapshot(client, project.id, created.artifact.id, sourceFiles).catch((error) => {
5576
5686
  const message = error instanceof Error ? error.message : "unknown error";
5577
5687
  process.stderr.write(`Warning: failed to upload project source files: ${message}\n`);
5578
5688
  });
@@ -5596,14 +5706,14 @@ async function runDeploy(options) {
5596
5706
  throw new Error("Timed out waiting for project to become active");
5597
5707
  }
5598
5708
  function registerDeployCommand(program) {
5599
- program.command("deploy").description("Build, upload, and deploy the project to the platform").option("--dir <path>", "Project directory", process.cwd()).option("--skip-build", "Upload the existing dist/ without rebuilding").action(async (options) => {
5709
+ program.command("deploy").description("Build, upload, and deploy the project to the platform").option("--dir <path>", "Project directory", process.cwd()).option("--filter <entry>", "Build and deploy only matching module entry keys (repeatable)", (value, previous) => [...previous, value], []).action(async (options) => {
5600
5710
  try {
5601
5711
  const projectId = await resolveActiveProjectId(createCliConfig());
5602
5712
  if (!projectId) throw new Error("Usage: keystroke deploy --project <slug>");
5603
5713
  await runDeploy({
5604
5714
  dir: options.dir,
5605
5715
  projectId,
5606
- skipBuild: options.skipBuild
5716
+ filter: options.filter.length > 0 ? options.filter : void 0
5607
5717
  });
5608
5718
  } catch (error) {
5609
5719
  const message = error instanceof Error ? error.message : "Deploy failed";
@@ -5654,7 +5764,7 @@ function runtimeChildEnv(parentEnv, overrides) {
5654
5764
  //#region src/project/bootstrap-run.ts
5655
5765
  /** Node args + env for `@keystrokehq/build` bootstrap (shared by start + dev). */
5656
5766
  async function resolveBootstrapRun(options) {
5657
- const { resolveRuntimeBuildArtifact } = await import("./dist-sXdjEZpP.mjs");
5767
+ const { resolveRuntimeBuildArtifact } = await import("./dist-BMPry9tj.mjs");
5658
5768
  const loader = pathToFileURL(resolveRuntimeBuildArtifact(options.runtimeNodeModules, "dist/runtime-loader.mjs")).href;
5659
5769
  const bootstrap = resolveRuntimeBuildArtifact(options.runtimeNodeModules, "dist/bootstrap.mjs");
5660
5770
  const args = [`--import=${loader}`];
@@ -5804,7 +5914,7 @@ async function runDev(options) {
5804
5914
  process.on("SIGINT", shutdown);
5805
5915
  process.on("SIGTERM", shutdown);
5806
5916
  try {
5807
- const { watchApp } = await import("./dist-sXdjEZpP.mjs");
5917
+ const { watchApp } = await import("./dist-BMPry9tj.mjs");
5808
5918
  await watchApp({
5809
5919
  root,
5810
5920
  clean: false,
@@ -6632,7 +6742,7 @@ async function runStart(options) {
6632
6742
  const apiPort = Number(new URL(serverUrl).port || 80);
6633
6743
  const runtimeNodeModules = resolveCliRuntimeNodeModules(resolveCliRoot(import.meta.url));
6634
6744
  ensureNativeDeps(runtimeNodeModules);
6635
- const { buildApp } = await import("./dist-sXdjEZpP.mjs");
6745
+ const { buildApp } = await import("./dist-BMPry9tj.mjs");
6636
6746
  await buildApp({
6637
6747
  root,
6638
6748
  clean: false
@@ -7168,7 +7278,7 @@ function createProgram() {
7168
7278
  return program;
7169
7279
  }
7170
7280
  async function runCli(argv) {
7171
- const { maybeAutoUpdate } = await import("./maybe-auto-update-CIcDJRrg.mjs");
7281
+ const { maybeAutoUpdate } = await import("./maybe-auto-update-B03C4E8i.mjs");
7172
7282
  await maybeAutoUpdate(argv);
7173
7283
  createProgram().parse(argv);
7174
7284
  }