@keystrokehq/cli 0.0.11 → 0.0.13

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 (146) hide show
  1. package/dist/{accept.handler-DWuxmMuY.mjs → accept.handler-BU6kg8ET.mjs} +1 -1
  2. package/dist/{admin-BK4bFTTd.mjs → admin-B4GNbCl5.mjs} +9 -9
  3. package/dist/{agent-manifest-sJFbH5H8.mjs → agent-manifest-CZdlCTFs.mjs} +5 -5
  4. package/dist/{agents-DYnw2VPX.mjs → agents-LtoIcJGY.mjs} +6 -6
  5. package/dist/api-DuKKdCpF.mjs +246 -0
  6. package/dist/{api-keys-Dizx3YqE.mjs → api-keys-BE_hLonn.mjs} +5 -5
  7. package/dist/{auth-BqsKd4IA.mjs → auth-DNK5MYm4.mjs} +5 -5
  8. package/dist/{auth.handler-BsoWeCFD.mjs → auth.handler-DrjDODhZ.mjs} +1 -1
  9. package/dist/{build-agents-DfbiMZ_e-CgnKa9A6.mjs → build-agents-DseUtzd4-DIDGsZWL.mjs} +12 -13
  10. package/dist/{build-metadata-zidV9Cai-Bq37kBOM.mjs → build-metadata-qebrtraZ-D4SQNsBw.mjs} +19 -35
  11. package/dist/{build-progress-DigAP-BN.mjs → build-progress-CITED2tv.mjs} +1 -1
  12. package/dist/{build-tasks-O1jYtlv1-Bkw0w1r3.mjs → build-tasks-GVuMLS0h-DnS9QWzf.mjs} +4 -4
  13. package/dist/{build-workflows-3fdvdHHf-BDTy9QgT.mjs → build-workflows-Dmzay1vP-DKVuBAjD.mjs} +17 -18
  14. package/dist/{build.handler-B2UDhh72.mjs → build.handler-BZnLQt0_.mjs} +4 -4
  15. package/dist/{clear.handler-BR97yudD.mjs → clear.handler-B1c17nAi.mjs} +1 -1
  16. package/dist/{commander-DcftG6dX.mjs → commander-BwtBoukr.mjs} +2 -2
  17. package/dist/{common-B3bLe3Mk.mjs → common-BaGFkj3n.mjs} +2 -2
  18. package/dist/{connect-DQ4xIcyE.mjs → connect-IPcL37np.mjs} +12 -6
  19. package/dist/{connect.handler-CWSLgf87.mjs → connect.handler-ToY6qmMz.mjs} +74 -224
  20. package/dist/{context-1VgRbzr-.mjs → context-DQ4IA0yO.mjs} +1 -1
  21. package/dist/{create.handler-C2CkPWsy.mjs → create.handler-BAyG0PmG.mjs} +1 -1
  22. package/dist/credential-requirements-FtBk5JVB.mjs +250 -0
  23. package/dist/credentials-Bu1MBiCL.mjs +182 -0
  24. package/dist/{credentials-D8_AwH9o.mjs → credentials-CZiu-534.mjs} +12 -7
  25. package/dist/{current-deployment-workflow-B05z0EQa.mjs → current-deployment-workflow-zTmYbUjh.mjs} +5 -5
  26. package/dist/{current.handler-CuAtMZmm.mjs → current.handler-DA4FGfUP.mjs} +1 -1
  27. package/dist/{declared-credential-requirements-BtlcsEVn.mjs → declared-credential-requirements-B6h4WRv4.mjs} +5 -34
  28. package/dist/{delete.handler-DDY3X1Zm.mjs → delete.handler-CJcyvnUF.mjs} +1 -1
  29. package/dist/{deploy-B8TYutOi.mjs → deploy-BvaFgVvf.mjs} +1 -1
  30. package/dist/{deploy-Cn6FFnOM.mjs → deploy-DdMP-YaQ.mjs} +2 -2
  31. package/dist/{deploy-progress-XAfautnA.mjs → deploy-progress-CLO-yidq.mjs} +1 -1
  32. package/dist/{deploy.handler-D1DcAe-h.mjs → deploy.handler-Bag7rBG-.mjs} +16 -16
  33. package/dist/{detect-env-access-CwkOYeYM-D4o8gRZs.mjs → detect-env-access-CwkOYeYM-EmkYvbfJ.mjs} +1 -1
  34. package/dist/{diff.handler-BU6IewNG.mjs → diff.handler-Brgc-Ccl.mjs} +3 -3
  35. package/dist/{dist-DvO0q6Fo.mjs → dist-BMkNN03r.mjs} +16 -16
  36. package/dist/{env.handler-C6YAmHLi.mjs → env.handler-DFKzjIQT.mjs} +10 -7
  37. package/dist/{error-boundary-CpaVvFXk.mjs → error-boundary-B2ZKRkZI.mjs} +1 -1
  38. package/dist/{file-metadata-BvGM-B2v.mjs → file-metadata-Dwy9KKq_.mjs} +2 -2
  39. package/dist/{import-module-DDPnzlJ1-BIBSgOhK.mjs → import-module-DEI7R8Yh-Xz-KAPvB.mjs} +248 -246
  40. package/dist/{init-Da6_obl0.mjs → init-DhnABm3J.mjs} +2 -2
  41. package/dist/{init.handler-Cq2nk8DO.mjs → init.handler-QgehN8B4.mjs} +4 -4
  42. package/dist/{inspect.handler-D4YGryQB.mjs → inspect.handler-CMOFOb4G.mjs} +3 -3
  43. package/dist/{integration-catalog-DtNWaMvh.mjs → integration-catalog-BRrJIAVz.mjs} +5 -5
  44. package/dist/{integrations-CB_Ukq2g.mjs → integrations-7-U7nmkh.mjs} +7 -6
  45. package/dist/{invites-BOhuBtoq.mjs → invites-CmGmnUla.mjs} +4 -4
  46. package/dist/{invites.list.handler-C-Wv6E1g.mjs → invites.list.handler-CmkIf-uW.mjs} +1 -1
  47. package/dist/{invites.resend.handler-CI78XlQS.mjs → invites.resend.handler-FZl20yat.mjs} +1 -1
  48. package/dist/{invites.revoke.handler-DigAgNwB.mjs → invites.revoke.handler-D95mrfmB.mjs} +1 -1
  49. package/dist/keystroke.mjs +21 -21
  50. package/dist/{list-enrichment-Cxlq6BB9.mjs → list-enrichment-I4XQaMg0.mjs} +5 -1
  51. package/dist/{list.handler-OiLEylzS.mjs → list.handler-BrTW2viq.mjs} +1 -1
  52. package/dist/{list.handler-CsODcH6e.mjs → list.handler-Cp767f5l.mjs} +1 -1
  53. package/dist/{list.handler-BsyGhXns.mjs → list.handler-DRnHsEa0.mjs} +1 -1
  54. package/dist/{list.handler-B6IByHHB.mjs → list.handler-DXl8igi2.mjs} +13 -5
  55. package/dist/{list.handler-BpVNYShU.mjs → list.handler-DsYyTUhA.mjs} +1 -1
  56. package/dist/{list.handler--a1JEGSD.mjs → list.handler-H8aQSsFM.mjs} +3 -3
  57. package/dist/{list.handler-Dr9Ti-dt.mjs → list.handler-uzC77oIy.mjs} +3 -3
  58. package/dist/{listen-DUPk6cZC.mjs → listen-DckJq0y0.mjs} +2 -2
  59. package/dist/{listen.handler-B5WimrfF.mjs → listen.handler-Bf5MXKPO.mjs} +2 -2
  60. package/dist/{logs-C5_4lh3p.mjs → logs-D_l5BIn2.mjs} +3 -3
  61. package/dist/{logs.handler-CBHPwDuC.mjs → logs.handler-kYO3Uv9t.mjs} +2 -2
  62. package/dist/{members.add.handler-LcQJYBsu.mjs → members.add.handler-C2cppd-9.mjs} +1 -1
  63. package/dist/{members.invite.handler-p279O2aC.mjs → members.invite.handler-DY6kS4LN.mjs} +1 -1
  64. package/dist/{members.list.handler-Cjukjuot.mjs → members.list.handler-CFBG3SBw.mjs} +1 -1
  65. package/dist/{members.remove.handler-CzxPiQFv.mjs → members.remove.handler-LQ61_qip.mjs} +1 -1
  66. package/dist/{members.update.handler-CX5q86e3.mjs → members.update.handler-CqISA1mf.mjs} +1 -1
  67. package/dist/{normalize-path-CojS-CgQ-D_WTiHKw.mjs → normalize-path-CojS-CgQ-D5D0AIHR.mjs} +1 -1
  68. package/dist/{org-CnlKW-Hl.mjs → org-KQ2nD0yN.mjs} +15 -15
  69. package/dist/{orgs.create.handler-DRILhxdn.mjs → orgs.create.handler-Mv5CTGcG.mjs} +1 -1
  70. package/dist/{orgs.get.handler-Cue6stoX.mjs → orgs.get.handler-DvvOhshX.mjs} +1 -1
  71. package/dist/{orgs.list.handler-fuDLNI5X.mjs → orgs.list.handler-wWAg6cKg.mjs} +1 -1
  72. package/dist/{paused.handler-CuOVH4DZ.mjs → paused.handler-CbMkPD9e.mjs} +1 -1
  73. package/dist/{project-config-D9eFU8Jk.mjs → project-config-CJGSh2RQ.mjs} +4 -7
  74. package/dist/{projects-DN7dX6nN.mjs → projects-CWLOF5x4.mjs} +656 -3
  75. package/dist/{projects-DdgHbUpR.mjs → projects-CYqeKQGT.mjs} +4 -4
  76. package/dist/{requirements.handler-CX13XiXT.mjs → requirements.handler-CnDTBcH5.mjs} +5 -5
  77. package/dist/{resolve-project-C6UAOfAG.mjs → resolve-project-bVPMcs-y.mjs} +1 -1
  78. package/dist/{run-polling-1CTIeDea.mjs → run-polling-49w3PYAv.mjs} +3 -3
  79. package/dist/{run.handler-BxLH75WW.mjs → run.handler-Bma88649.mjs} +5 -5
  80. package/dist/{runs-lfE7r6i2.mjs → runs-HJejvQnQ.mjs} +2 -2
  81. package/dist/{schema-BgGlAs8a.mjs → schema-DFJiNWyd.mjs} +2 -1
  82. package/dist/schemas-DodkHgnS.mjs +280 -0
  83. package/dist/{skills-sync.handler-CntKndFm.mjs → skills-sync.handler-Cf74vKJA.mjs} +1 -1
  84. package/dist/{skills.command-X5zZwz2d.mjs → skills.command-KyAwBeST.mjs} +3 -3
  85. package/dist/{source-analysis-CHkWMC40.mjs → source-analysis-CJPymdaA.mjs} +1 -1
  86. package/dist/{source-analysis-DEEChuND-Csu0oOlw.mjs → source-analysis-DTnwNwKq-DoBxUDCg.mjs} +5 -5
  87. package/dist/{src--fCtOxNX.mjs → src-D-dFmoAF.mjs} +1 -1
  88. package/dist/{switch.handler-RaeKZ3ZB.mjs → switch.handler-DfsKVtR6.mjs} +1 -1
  89. package/dist/{sync-C89mJp7Y.mjs → sync-Bi2M_TUK.mjs} +2 -2
  90. package/dist/{sync.handler-BoAHHUQs.mjs → sync.handler-D6YFuVlq.mjs} +6 -6
  91. package/dist/{schedule-BWAI6qLx.mjs → task-BBgEvdG1.mjs} +395 -25
  92. package/dist/{task-target-build-D5IrHqSl.mjs → task-target-build-atWwwnSF.mjs} +8 -8
  93. package/dist/task-target-deploy-CRsrQTOy.mjs +4 -0
  94. package/dist/{task-target-deploy-Bf5i3ox1-2K0hAwzk.mjs → task-target-deploy-CZBGNC0H-BwPSfaJQ.mjs} +2 -2
  95. package/dist/task-target-deploy-runner.mjs +5 -5
  96. package/dist/{test-gPQJRkqa.mjs → test-Ctjy8mwC.mjs} +32 -144
  97. package/dist/{test.handler-B5GF5txS.mjs → test.handler-St9sBXyH.mjs} +1 -1
  98. package/dist/{trigger-artifacts-B3OCTX9K-ME6IVdUB.mjs → trigger-artifacts-RizI57RC-C-yCtEi-.mjs} +9 -9
  99. package/dist/{trigger-manifest-B3Gq1739.mjs → trigger-manifest-D5rnpPkA.mjs} +1 -1
  100. package/dist/{try-deploy.handler-dA_YGWRq.mjs → try-deploy.handler-BMcWQVST.mjs} +9 -9
  101. package/dist/{upgrade-xByIxaYu.mjs → upgrade-YavAf8AC.mjs} +2 -2
  102. package/dist/{upload.handler-BFDM6n_6.mjs → upload.handler-DemogvI1.mjs} +129 -18
  103. package/dist/{users.get.handler-CzaYM2bi.mjs → users.get.handler-B20PMSbl.mjs} +1 -1
  104. package/dist/{users.list.handler-CpOWwzBb.mjs → users.list.handler-BplFTjv3.mjs} +1 -1
  105. package/dist/{users.set-role.handler-BjiSNP2d.mjs → users.set-role.handler-wdmI6o3G.mjs} +1 -1
  106. package/dist/{utils-C_qCshBA.mjs → utils-DpEtybzI.mjs} +2 -2
  107. package/dist/{validate.handler-BtDSKAFY.mjs → validate.handler-DSAvNgns.mjs} +3 -3
  108. package/dist/{workflow-build-Z2_jkOsZ.mjs → workflow-build-Cmu1TOFu.mjs} +32 -32
  109. package/dist/{workflow-manifest-BfL74mjp.mjs → workflow-build-manifest-OPFqFD6f.mjs} +26 -28
  110. package/dist/{workflow-bundler-BzHk73PM-tt09RbIA.mjs → workflow-bundler-BzHk73PM-UJQa7Ubk.mjs} +2 -2
  111. package/dist/{workflows-V09d2r2H.mjs → workflows-DTlypo2t.mjs} +26 -27
  112. package/dist/{writer-CtvttJdP-DZJ0mZCm.mjs → writer-CtvttJdP-BfNsrheU.mjs} +5 -5
  113. package/package.json +11 -9
  114. package/dist/constants-BUgIAu2a.mjs +0 -8
  115. package/dist/credential-requirements-BCW8aQWS.mjs +0 -480
  116. package/dist/credentials-DAQfKqn0.mjs +0 -152025
  117. package/dist/get-intrinsic-BjqiGgLt.mjs +0 -658
  118. package/dist/hosted-action-dispatcher-registry-BWEtn13o.mjs +0 -126
  119. package/dist/schema-B-Wgo4rJ.mjs +0 -81
  120. package/dist/schemas-9FmGqrPT.mjs +0 -42
  121. package/dist/task-1qz1XNq7.mjs +0 -96
  122. package/dist/task-target-deploy-Bzfftyru.mjs +0 -4
  123. /package/dist/{agent-bundle-package-DWV6B_5q-B-qzc3zC.mjs → agent-bundle-package-DWV6B_5q-cB76j6UL.mjs} +0 -0
  124. /package/dist/{browser-CvuyMLhI.mjs → browser-B4K0VW8p.mjs} +0 -0
  125. /package/dist/{clear-cache.handler-D-wboLB6.mjs → clear-cache.handler-Dywqc7TG.mjs} +0 -0
  126. /package/dist/{clear.handler-BC6pz0x-.mjs → clear.handler-ui4e1CnJ.mjs} +0 -0
  127. /package/dist/{concurrency-gXn9Rw8x-CnBnF2cg.mjs → concurrency-gXn9Rw8x-CaI6Vtbu.mjs} +0 -0
  128. /package/dist/{credential-env-map-C23GV6LN.mjs → credential-env-map-D0zgoUl0.mjs} +0 -0
  129. /package/dist/{credential-schema-mismatch-DM9Y91jL.mjs → credential-schema-mismatch-8pqwvswO.mjs} +0 -0
  130. /package/dist/{diff-utils-AATn2n56.mjs → diff-utils-BoXI705D.mjs} +0 -0
  131. /package/dist/{layout-CXkZEsXI.mjs → layout-DRf9qUf8.mjs} +0 -0
  132. /package/dist/{logs.handler-ClIIOeQB.mjs → logs.handler-DxSKmDCq.mjs} +0 -0
  133. /package/dist/{metadata-layout-C6ed-9dl-C6Bylr_z.mjs → metadata-layout-C6ed-9dl-EF5pCtIH.mjs} +0 -0
  134. /package/dist/{options-CIVqkc8V.mjs → options-DFPs-tAB.mjs} +0 -0
  135. /package/dist/{oxc-B3KI3rf_-ghZc3xZ5.mjs → oxc-B3KI3rf_-CHDUXsus.mjs} +0 -0
  136. /package/dist/{read-credential-keys-77a91T8M-B0eiobOd.mjs → read-credential-keys-77a91T8M-CzXPGxdU.mjs} +0 -0
  137. /package/dist/{register.handler-CpP_KB2u.mjs → register.handler-D7ZZAnGP.mjs} +0 -0
  138. /package/dist/{rolldown-runtime-twds-ZHy-RuJszab7.mjs → rolldown-runtime-twds-ZHy-3DMm_Sby.mjs} +0 -0
  139. /package/dist/{run-polling-DDpkIvwy.mjs → run-polling-Cb4ssXIE.mjs} +0 -0
  140. /package/dist/{schema-display-DuWBmkwk.mjs → schema-display-CyCWSgfY.mjs} +0 -0
  141. /package/dist/{skills.handler-CofL4oKs.mjs → skills.handler-C_4VzVmc.mjs} +0 -0
  142. /package/dist/{spinner-progress-Bt8zXPOc.mjs → spinner-progress-CS1BEdNB.mjs} +0 -0
  143. /package/dist/{status.handler-6cuHa0R0.mjs → status.handler-Cm9aNUBn.mjs} +0 -0
  144. /package/dist/{sync-keystroke-agent-skills-D746f2W_.mjs → sync-keystroke-agent-skills-CX9fS5nQ.mjs} +0 -0
  145. /package/dist/{upgrade.handler-DhKeyCy5.mjs → upgrade.handler-C2eZ_tg3.mjs} +0 -0
  146. /package/dist/{upload-C1qFWMm0.mjs → upload-C0kaZu08.mjs} +0 -0
@@ -2,227 +2,41 @@
2
2
 
3
3
  import { N as throwReportedCliExit, b as isNetworkError, h as AUTH_HINT, n as ui, x as toErrorMessage } from "./keystroke.mjs";
4
4
  import { i as writeJson } from "./output-CGdYhH0p.mjs";
5
- import { n as CredentialScopeSchema, t as ConnectionStatusSchema } from "./schema-BgGlAs8a.mjs";
6
- import { t as openBrowser } from "./browser-CvuyMLhI.mjs";
7
- import { t as getIntegrationCatalog } from "./integration-catalog-DtNWaMvh.mjs";
8
- import { z } from "zod";
9
- //#region ../../packages/shared-types/src/connections/api.ts
10
- /**
11
- * API request/response types for the integration catalog and connection endpoints.
12
- *
13
- * These types are shared between the server route handlers, the Keystroke SDK, and
14
- * any in-repo consumer (CLI, web). They divide the surface into two clearly-scoped
15
- * endpoints:
16
- *
17
- * GET /api/v1/integrations — the static Keystroke integration catalog (what can
18
- * be connected). Auth required; not org-scoped; long-cached.
19
- *
20
- * GET /api/v1/connections — the caller's configured connections for the current
21
- * org (what has been connected). Auth + org required; no-cache.
22
- *
23
- * Each endpoint validates its query string with the exported `*QuerySchema`, and
24
- * the SDK types its method signatures against the same schema so that invalid
25
- * params cannot be sent or accepted.
26
- */
27
- const ShopifyShopDomainSchema = z.string().min(1).regex(/^[a-z0-9][a-z0-9-]*\.myshopify\.com$/i, "Shopify store domain must look like \"example.myshopify.com\".");
28
- const InitiateConnectionRequestSchema = z.object({
29
- providerAppId: z.string().optional(),
30
- shopDomain: ShopifyShopDomainSchema.optional(),
31
- requestedScopes: z.array(z.string()).optional()
32
- });
33
- const InitiateConnectionResponseSchema = z.object({
34
- authUrl: z.string(),
35
- initiatedAt: z.number()
36
- });
37
- const ConnectionFailureReasonSchema = z.enum([
38
- "missing_state",
39
- "invalid_state",
40
- "provider_denied",
41
- "unknown_integration",
42
- "provider_app_not_configured",
43
- "token_exchange_failed",
44
- "installation_metadata_invalid",
45
- "validation_failed",
46
- "persist_failed",
47
- "unknown_error"
48
- ]);
49
- const ConnectionStatusNotStartedSchema = z.object({ status: z.literal("not_started") });
50
- const ConnectionStatusPendingSchema = z.object({ status: z.literal("pending") });
51
- const ConnectionStatusConnectedSchema = z.object({ status: z.literal("connected") });
52
- const ConnectionStatusFailedSchema = z.object({
53
- status: z.literal("failed"),
54
- reason: ConnectionFailureReasonSchema,
55
- /**
56
- * Optional human-readable detail. Truncated by the server to
57
- * {@link CONNECTION_FAILURE_DETAIL_MAX_CHARS} characters before being
58
- * persisted in `credential_sets.last_callback_error_detail` and
59
- * before being echoed in the callback redirect query.
60
- */
61
- message: z.string().max(300).optional(),
62
- /** ISO-8601 timestamp of when the failure was recorded. */
63
- failedAt: z.string()
64
- });
65
- const ConnectionStatusResponseSchema = z.discriminatedUnion("status", [
66
- ConnectionStatusNotStartedSchema,
67
- ConnectionStatusPendingSchema,
68
- ConnectionStatusConnectedSchema,
69
- ConnectionStatusFailedSchema
70
- ]);
71
- const ConnectionKindSchema = z.enum([
72
- "oauth",
73
- "manual",
74
- "credentials-exchange"
75
- ]);
76
- const InternalCredentialSetEntrySchema = z.object({
77
- resolvedCredentialSetId: z.string(),
78
- publicId: z.string(),
79
- displayName: z.string(),
80
- /**
81
- * Internal credential-set role. Currently the only first-class role is
82
- * `'provider-app-definition'`; other values are accepted for forward-compat
83
- * so newer servers can introduce roles without breaking older SDKs.
84
- */
85
- role: z.string()
86
- });
87
- const IntegrationCatalogEntryBaseSchema = z.object({
88
- publicId: z.string(),
89
- /**
90
- * Public-facing aliases that resolve to this canonical `publicId`
91
- * (e.g., `"github"` aliases `"github-account"`). Includes the canonical
92
- * ID itself — callers can key a lookup table by every entry in this
93
- * list and get the same catalog record back.
94
- */
95
- aliases: z.array(z.string()),
96
- name: z.string(),
97
- description: z.string().optional(),
98
- /**
99
- * Resolved credential-set metadata for the integration's primary connection.
100
- * `storedKeys` drives upload flows (what the vault stores), while
101
- * `authKeys` describes the post-resolve runtime shape.
102
- */
103
- credentialSet: z.object({
104
- resolvedCredentialSetId: z.string(),
105
- authKeys: z.array(z.string()),
106
- storedKeys: z.array(z.string()),
107
- optionalStoredKeys: z.array(z.string()).optional(),
108
- schemaFingerprint: z.string().optional()
109
- }),
110
- /**
111
- * Internal credential sets associated with the integration (e.g., provider
112
- * app definitions). Populated only when the caller requests
113
- * `includeInternal=true`; otherwise empty.
114
- */
115
- internalCredentialSets: z.array(InternalCredentialSetEntrySchema)
116
- });
117
- const OAuthIntegrationCatalogEntrySchema = IntegrationCatalogEntryBaseSchema.extend({
118
- connectionKind: z.literal("oauth"),
119
- tokenType: z.enum(["long-lived", "refreshable"]),
120
- scopes: z.array(z.string())
121
- });
122
- const ManualIntegrationCatalogEntrySchema = IntegrationCatalogEntryBaseSchema.extend({ connectionKind: z.literal("manual") });
123
- /**
124
- * Catalog entry for `credentials-exchange`-kind integrations.
125
- *
126
- * Carries the JSON-schema projection of the connection's `input` schema so
127
- * the CLI and web UI can render an input form without re-loading the
128
- * original Zod schema (which only exists in the integration bundle's
129
- * runtime module). `credentialSet.storedKeys` reflects the stored-schema
130
- * keys that get persisted after exchange.
131
- *
132
- * @see packages/core/src/credential-set/connection.ts CredentialsExchangeConnectionConfig
133
- */
134
- const CredentialsExchangeIntegrationCatalogEntrySchema = IntegrationCatalogEntryBaseSchema.extend({
135
- connectionKind: z.literal("credentials-exchange"),
136
- /** JSON-schema projection of the connection's `input` schema. */
137
- input: z.record(z.string(), z.unknown()),
138
- /** Optional free-form copy rendered above the input form. */
139
- instructions: z.string().optional()
140
- });
141
- const IntegrationCatalogEntrySchema = z.discriminatedUnion("connectionKind", [
142
- OAuthIntegrationCatalogEntrySchema,
143
- ManualIntegrationCatalogEntrySchema,
144
- CredentialsExchangeIntegrationCatalogEntrySchema
145
- ]);
146
- z.object({
147
- /** Restrict results to one connection kind. */
148
- connectionKind: ConnectionKindSchema.optional(),
149
- /**
150
- * Return only the integration whose `publicId` (or alias) matches.
151
- * When no integration matches, the endpoint returns an empty array.
152
- */
153
- publicId: z.string().min(1).optional(),
154
- /**
155
- * Case-insensitive substring match against `publicId`, `aliases`, and `name`.
156
- */
157
- q: z.string().min(1).optional(),
158
- /**
159
- * Opt into `internalCredentialSets[]` on each entry. Defaults to `false`
160
- * so the common catalog call stays lean. CLI commands that need to render
161
- * credential-set display names set this to `true`.
162
- */
163
- includeInternal: z.stringbool().optional().default(false)
164
- }).strict();
165
- z.object({ integrations: z.array(IntegrationCatalogEntrySchema) });
166
- const ConnectionEntrySchema = z.object({
167
- id: z.string(),
168
- /**
169
- * Public-facing integration ID this connection is associated with
170
- * (post alias resolution). `null` when the underlying credential set is
171
- * not backed by an official Keystroke integration (e.g., user-defined
172
- * custom credential sets).
173
- */
174
- integrationPublicId: z.string().nullable(),
175
- /**
176
- * Resolved credential-set ID, e.g., `"keystroke:slack"` or a custom set's
177
- * identifier. Stable across alias resolution.
178
- */
179
- credentialSetId: z.string(),
180
- name: z.string(),
181
- scope: CredentialScopeSchema,
182
- platformConnected: z.boolean(),
183
- connectionStatus: ConnectionStatusSchema,
184
- expiresAt: z.string().nullable(),
185
- isDefault: z.boolean(),
186
- createdAt: z.string()
187
- });
188
- /**
189
- * Coerces a `status` query-param value that may arrive as a single string,
190
- * a comma-separated string, or (in Hono/ky's query handling) an array of
191
- * strings, into a canonical `ConnectionStatus[]`. Invalid entries cause the
192
- * surrounding Zod parse to fail with a helpful issue.
193
- *
194
- * The field itself is made optional at the object level (see
195
- * `ListConnectionsQuerySchema`), so passing `undefined` / omitting the key
196
- * is always valid; this preprocessor only runs when a value is actually
197
- * present.
198
- */
199
- const ConnectionStatusQueryParam = z.preprocess((value) => {
200
- if (value === void 0 || value === null || value === "") return void 0;
201
- const trimmed = (Array.isArray(value) ? value : String(value).split(",")).flatMap((entry) => String(entry).split(",")).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
202
- return trimmed.length === 0 ? void 0 : trimmed;
203
- }, z.array(ConnectionStatusSchema));
204
- z.object({
205
- /** Filter to connections for a specific integration's public ID (alias-resolved). */
206
- integrationPublicId: z.string().min(1).optional(),
207
- /**
208
- * Filter by one or more connection statuses. Accepts a single value, a
209
- * comma-separated string, or repeated query keys. Omit to return all statuses.
210
- */
211
- status: ConnectionStatusQueryParam.optional(),
212
- scope: CredentialScopeSchema.optional(),
213
- projectId: z.uuid().optional()
214
- }).strict();
215
- z.object({ connections: z.array(ConnectionEntrySchema) });
216
- //#endregion
5
+ import { t as openBrowser } from "./browser-B4K0VW8p.mjs";
6
+ import { i as InitiateConnectionResponseSchema, n as ConnectionStatusResponseSchema, r as InitiateConnectionRequestSchema } from "./api-DuKKdCpF.mjs";
7
+ import { t as getIntegrationCatalog } from "./integration-catalog-BRrJIAVz.mjs";
217
8
  //#region src/commands/connect/connect.handler.ts
218
9
  function formatIntegrationLabel(catalog, integrationId) {
219
10
  return catalog.lookupByPublicId(integrationId)?.name ?? integrationId;
220
11
  }
221
- function normalizeShopifyShopDomain(shop) {
222
- const trimmed = shop?.trim().toLowerCase();
223
- if (!trimmed) return;
224
- const normalized = trimmed.endsWith(".myshopify.com") ? trimmed : `${trimmed}.myshopify.com`;
225
- return ShopifyShopDomainSchema.parse(normalized);
12
+ function formatConnectionLabel(connection) {
13
+ return connection.label ?? connection.id;
14
+ }
15
+ function formatConnectionFlags(connection) {
16
+ const flags = [connection.recommended === true ? "recommended" : null, connection.advanced === true ? "advanced" : null].filter((flag) => flag !== null);
17
+ return flags.length > 0 ? `, ${flags.join(", ")}` : "";
18
+ }
19
+ function availableOAuthConnectionHint(connections) {
20
+ const oauthConnections = connections?.filter((connection) => connection.kind === "oauth") ?? [];
21
+ if (oauthConnections.length === 0) return "Run `keystroke integrations list --kind oauth` to see integrations with OAuth connection paths.";
22
+ return `Available OAuth connection IDs: ${oauthConnections.map((connection) => `${connection.id}${connection.recommended ? " (recommended)" : ""}`).join(", ")}.`;
23
+ }
24
+ function selectOAuthConnection(params) {
25
+ const { catalogEntry, requestedCredentialConnectionId, ctx, integrationId } = params;
26
+ const connections = catalogEntry?.connections ?? [];
27
+ if (requestedCredentialConnectionId) {
28
+ const selected = connections.find((connection) => connection.id === requestedCredentialConnectionId);
29
+ if (!selected) exitWithError(ctx, `Credential connection "${requestedCredentialConnectionId}" is not defined for "${integrationId}".`, {
30
+ code: "UNKNOWN_CREDENTIAL_CONNECTION",
31
+ hint: availableOAuthConnectionHint(connections)
32
+ });
33
+ if (selected.kind !== "oauth") exitWithError(ctx, `Credential connection "${selected.id}" for "${integrationId}" is "${selected.kind}", not oauth.`, {
34
+ code: "UNSUPPORTED_CREDENTIAL_CONNECTION",
35
+ hint: availableOAuthConnectionHint(connections)
36
+ });
37
+ return selected;
38
+ }
39
+ return connections.find((connection) => connection.kind === "oauth" && connection.recommended === true) ?? connections.find((connection) => connection.kind === "oauth");
226
40
  }
227
41
  /**
228
42
  * Per-reason CLI hint table for `failed` status responses.
@@ -261,6 +75,24 @@ function exitWithError(ctx, message, opts) {
261
75
  if (opts?.hint) ui.hint(opts.hint);
262
76
  throwReportedCliExit(message);
263
77
  }
78
+ function parseConnectionInput(rawInputs, ctx) {
79
+ const input = {};
80
+ for (const rawInput of rawInputs) {
81
+ const separatorIndex = rawInput.indexOf("=");
82
+ if (separatorIndex <= 0) exitWithError(ctx, `Invalid --input value "${rawInput}".`, {
83
+ code: "USAGE_ERROR",
84
+ hint: "Use --input key=value. Repeat --input for multiple fields."
85
+ });
86
+ const key = rawInput.slice(0, separatorIndex).trim();
87
+ const value = rawInput.slice(separatorIndex + 1);
88
+ if (!key) exitWithError(ctx, `Invalid --input value "${rawInput}".`, {
89
+ code: "USAGE_ERROR",
90
+ hint: "Input keys must be non-empty: --input key=value"
91
+ });
92
+ input[key] = value;
93
+ }
94
+ return input;
95
+ }
264
96
  /**
265
97
  * Handle the `keystroke connect <integrationId>` command.
266
98
  *
@@ -281,20 +113,27 @@ async function handleConnect(options, ctx) {
281
113
  hint: "Example: keystroke connect github"
282
114
  });
283
115
  const catalog = await getIntegrationCatalog(ctx);
284
- const integrationLabel = catalog.oauthPublicIds.includes(integrationId) ? formatIntegrationLabel(catalog, integrationId) : integrationId;
285
- const shopDomain = integrationId === "shopify" ? normalizeShopifyShopDomain(options.shop) : void 0;
286
- if (integrationId === "shopify" && !shopDomain) exitWithError(ctx, "Shopify connections require a store domain.", {
287
- code: "USAGE_ERROR",
288
- hint: "Example: keystroke connect shopify --shop example.myshopify.com"
116
+ const catalogEntry = catalog.lookupByPublicId(integrationId);
117
+ const oauthConnection = selectOAuthConnection({
118
+ catalogEntry,
119
+ requestedCredentialConnectionId: options.connection,
120
+ ctx,
121
+ integrationId
289
122
  });
123
+ const integrationLabel = Boolean(oauthConnection) ? formatIntegrationLabel(catalog, integrationId) : integrationId;
124
+ const connectionInput = parseConnectionInput(options.input ?? [], ctx);
290
125
  if (!ctx.jsonMode) {
291
126
  ui.text(`Connect ${integrationLabel}`);
127
+ if (oauthConnection && ((catalogEntry?.connections.length ?? 0) > 1 || options.connection)) ui.text(`Connection: ${formatConnectionLabel(oauthConnection)} (id: ${oauthConnection.id}${formatConnectionFlags(oauthConnection)})`);
292
128
  ui.br();
293
129
  }
294
130
  let authUrl;
295
131
  let initiatedAt;
296
132
  try {
297
- const requestBody = InitiateConnectionRequestSchema.parse({ ...shopDomain ? { shopDomain } : {} });
133
+ const requestBody = InitiateConnectionRequestSchema.parse({
134
+ ...oauthConnection ? { credentialConnectionId: oauthConnection.id } : {},
135
+ ...Object.keys(connectionInput).length > 0 ? { input: connectionInput } : {}
136
+ });
298
137
  const hasRequestBody = Object.keys(requestBody).length > 0;
299
138
  const response = await fetch(`${baseUrl}/api/v1/connections/${integrationId}/initiate`, {
300
139
  method: "POST",
@@ -348,6 +187,14 @@ async function handleConnect(options, ctx) {
348
187
  writeJson({
349
188
  status: "authorization_required",
350
189
  integrationId,
190
+ credentialConnectionId: oauthConnection?.id,
191
+ ...oauthConnection ? { selectedConnection: {
192
+ id: oauthConnection.id,
193
+ kind: oauthConnection.kind,
194
+ ...oauthConnection.label ? { label: oauthConnection.label } : {},
195
+ ...oauthConnection.recommended === true ? { recommended: true } : {},
196
+ ...oauthConnection.advanced === true ? { advanced: true } : {}
197
+ } } : {},
351
198
  authUrl,
352
199
  initiatedAt,
353
200
  timeoutSeconds: options.timeout
@@ -377,7 +224,10 @@ async function handleConnect(options, ctx) {
377
224
  while (Date.now() - startTime < timeoutMs) {
378
225
  await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
379
226
  try {
380
- const response = await fetch(`${baseUrl}/api/v1/connections/${integrationId}/status?since=${initiatedAt}`, { headers: { Authorization: `Bearer ${apiKey}` } });
227
+ const statusUrl = new URL(`${baseUrl}/api/v1/connections/${integrationId}/status`);
228
+ statusUrl.searchParams.set("since", String(initiatedAt));
229
+ if (oauthConnection) statusUrl.searchParams.set("credentialConnectionId", oauthConnection.id);
230
+ const response = await fetch(statusUrl.toString(), { headers: { Authorization: `Bearer ${apiKey}` } });
381
231
  if (!response.ok) {
382
232
  consecutivePollFailures += 1;
383
233
  if (response.status === 401) exitWithError(ctx, "Your CLI session is no longer authenticated.", {
@@ -36,7 +36,7 @@ async function resolveBaseContext(overrides = {}) {
36
36
  const authContext = await resolveAuthContext(overrides);
37
37
  let client = null;
38
38
  if (authContext.apiKey && authContext.baseUrl) try {
39
- const { createClient } = await import("./src--fCtOxNX.mjs");
39
+ const { createClient } = await import("./src-D-dFmoAF.mjs");
40
40
  client = createClient({
41
41
  apiKey: authContext.apiKey,
42
42
  baseUrl: authContext.baseUrl,
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { N as throwReportedCliExit, n as ui, x as toErrorMessage } from "./keystroke.mjs";
4
4
  import { i as writeJson } from "./output-CGdYhH0p.mjs";
5
- import { i as requireClient } from "./context-1VgRbzr-.mjs";
5
+ import { i as requireClient } from "./context-DQ4IA0yO.mjs";
6
6
  //#region src/commands/api-keys/create.handler.ts
7
7
  async function handleApiKeysCreate(options, ctx) {
8
8
  const client = requireClient(ctx);
@@ -0,0 +1,250 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { t as JsonSchemaSchema } from "./common-BaGFkj3n.mjs";
4
+ import { n as credentialSetProxyConfigSchema } from "./schemas-DodkHgnS.mjs";
5
+ import { a as SourceLocationSchema, i as ImportSourceSchema, t as CallKindSchema } from "./source-analysis-CJPymdaA.mjs";
6
+ import { z } from "zod";
7
+ const IntegrationScopeSchema = z.enum([
8
+ "organization",
9
+ "project",
10
+ "user_provided_credential"
11
+ ]);
12
+ const IntegrationCredentialRefSchema = z.discriminatedUnion("type", [z.object({
13
+ type: z.literal("id"),
14
+ id: z.string().startsWith("cset_")
15
+ }), z.object({
16
+ type: z.literal("name"),
17
+ name: z.string().trim().min(1)
18
+ })]);
19
+ function hasProjectOrOrganizationScope(scope) {
20
+ return scope === "organization" || scope === "project";
21
+ }
22
+ const CredentialRefTokenKeyNameSchema = z.string().regex(/^[A-Za-z0-9_]+$/, "Credential key must contain only letters, digits, and underscores (required for ref-token proxying)");
23
+ /** Shared enum for top-level credential-set `onCredentialRevoked` policy. */
24
+ const OnCredentialRevokedSchema = z.enum(["fail", "retry-once"]);
25
+ /** A credential set after resolution in a built manifest. Contains definition id, scope, alias, and credential keys.*/
26
+ const ResolvedCredentialSetSchema = z.object({
27
+ resolvedId: z.string(),
28
+ scope: IntegrationScopeSchema.optional(),
29
+ alias: z.string().optional(),
30
+ credentialRef: IntegrationCredentialRefSchema.optional(),
31
+ /** Auth-shape keys expected post-resolve. */
32
+ credentialKeys: z.array(CredentialRefTokenKeyNameSchema),
33
+ /** Subset of `credentialKeys` that are optional in the auth shape. */
34
+ optionalCredentialKeys: z.array(CredentialRefTokenKeyNameSchema).optional(),
35
+ /** Stored-shape keys required for vault reads and upload flows. */
36
+ storedCredentialKeys: z.array(CredentialRefTokenKeyNameSchema).optional(),
37
+ /** Subset of `storedCredentialKeys` that may be absent from the vault without
38
+ * failing resolution. Derived from the credential set's `stored` schema:
39
+ * a Zod field wrapped in `.optional()` / `.default()` or a JSON Schema
40
+ * property not listed in `required` is considered optional. */
41
+ optionalStoredCredentialKeys: z.array(CredentialRefTokenKeyNameSchema).optional(),
42
+ proxy: credentialSetProxyConfigSchema.optional(),
43
+ /** When true, resolved values are passed raw (no ref-token proxy) for this set. */
44
+ needsRawSecret: z.boolean().optional(),
45
+ /** When true, this requirement uses a registered dynamic resolver phase. */
46
+ needsDynamicResolution: z.boolean().optional(),
47
+ /** Cache TTL in milliseconds for registered dynamic resolver output.
48
+ * `0` or absence means no cache hint. */
49
+ dynamicResolutionCacheMs: z.number().int().nonnegative().optional(),
50
+ /** Policy when a step throws `CredentialRevokedError` against this credential set. */
51
+ onCredentialRevoked: OnCredentialRevokedSchema.optional(),
52
+ /** Persistence-layer schema fingerprint stamped at build time. The
53
+ * resolver's phase 2 compares this against the vault row's stored
54
+ * fingerprint and raises `CredentialSchemaMismatchError` on drift.
55
+ * Optional here so pre-fingerprint artifacts still parse; the
56
+ * workflow builder populates it for every authored credential set
57
+ * that has a resolvable fingerprint. */
58
+ schemaFingerprint: z.string().optional()
59
+ }).superRefine((value, ctx) => {
60
+ if (value.credentialRef && !hasProjectOrOrganizationScope(value.scope)) ctx.addIssue({
61
+ code: z.ZodIssueCode.custom,
62
+ path: ["credentialRef"],
63
+ message: "credentialRef requires scope to be \"project\" or \"organization\""
64
+ });
65
+ });
66
+ const DeclaredCredentialRequirementSchema = z.object({
67
+ credentialSetId: z.string(),
68
+ /** Auth-shape keys expected post-resolve. */
69
+ credentialKeys: z.array(CredentialRefTokenKeyNameSchema),
70
+ /** Optional subset of the auth-shape keys. */
71
+ optionalCredentialKeys: z.array(CredentialRefTokenKeyNameSchema).optional(),
72
+ /** Stored-shape keys required for vault reads. */
73
+ storedCredentialKeys: z.array(CredentialRefTokenKeyNameSchema).optional(),
74
+ /** Optional subset of the stored-shape keys. */
75
+ optionalStoredCredentialKeys: z.array(CredentialRefTokenKeyNameSchema).optional(),
76
+ schemaFingerprint: z.string().optional(),
77
+ needsDynamicResolution: z.boolean().optional(),
78
+ /** Cache TTL in milliseconds for registered dynamic resolver output.
79
+ * `0` or absence means no cache hint. */
80
+ dynamicResolutionCacheMs: z.number().int().nonnegative().optional(),
81
+ /** Policy when a step throws `CredentialRevokedError` against this credential set. */
82
+ onCredentialRevoked: OnCredentialRevokedSchema.optional(),
83
+ proxy: credentialSetProxyConfigSchema.optional(),
84
+ needsRawSecret: z.boolean().optional(),
85
+ requiredOAuthScopes: z.array(z.string()).optional()
86
+ });
87
+ const CredentialRequirementEntrySchema = z.object({
88
+ credentialSetId: z.string(),
89
+ scope: IntegrationScopeSchema.optional(),
90
+ alias: z.string().optional(),
91
+ credentialRef: IntegrationCredentialRefSchema.optional(),
92
+ /** Auth-shape keys expected post-resolve. */
93
+ credentialKeys: z.array(CredentialRefTokenKeyNameSchema),
94
+ /** Optional subset of the auth-shape keys. */
95
+ optionalCredentialKeys: z.array(CredentialRefTokenKeyNameSchema).optional(),
96
+ /** Stored-shape keys required for vault reads. */
97
+ storedCredentialKeys: z.array(CredentialRefTokenKeyNameSchema).optional(),
98
+ /** Optional subset of the stored-shape keys. */
99
+ optionalStoredCredentialKeys: z.array(CredentialRefTokenKeyNameSchema).optional(),
100
+ schemaFingerprint: z.string().optional(),
101
+ proxy: credentialSetProxyConfigSchema.optional(),
102
+ needsRawSecret: z.boolean().optional(),
103
+ /** When true, this requirement uses a registered dynamic resolver phase. */
104
+ needsDynamicResolution: z.boolean().optional(),
105
+ /** Cache TTL in milliseconds for registered dynamic resolver output.
106
+ * `0` or absence means no cache hint. */
107
+ dynamicResolutionCacheMs: z.number().int().nonnegative().optional(),
108
+ /** Policy when a step throws `CredentialRevokedError` against this credential set. */
109
+ onCredentialRevoked: OnCredentialRevokedSchema.optional(),
110
+ requiredOAuthScopes: z.array(z.string()).optional()
111
+ }).superRefine((value, ctx) => {
112
+ if (value.credentialRef && !hasProjectOrOrganizationScope(value.scope)) ctx.addIssue({
113
+ code: z.ZodIssueCode.custom,
114
+ path: ["credentialRef"],
115
+ message: "credentialRef requires scope to be \"project\" or \"organization\""
116
+ });
117
+ });
118
+ const CredentialRequirementsSchema = z.object({
119
+ required: z.array(z.string()),
120
+ byStep: z.record(z.string(), z.array(CredentialRequirementEntrySchema))
121
+ });
122
+ const TriggerCallbackNameSchema = z.enum([
123
+ "filter",
124
+ "idempotencyKey",
125
+ "verify",
126
+ "callback"
127
+ ]);
128
+ const TriggerCredentialRequirementEntrySchema = CredentialRequirementEntrySchema;
129
+ const TriggerCredentialRequirementsSchema = z.object({
130
+ required: z.array(z.string()),
131
+ byCallback: z.partialRecord(TriggerCallbackNameSchema, z.array(TriggerCredentialRequirementEntrySchema))
132
+ });
133
+ function buildCredentialRequirementEntryKey(entry) {
134
+ const credentialRefKey = entry.credentialRef ? entry.credentialRef.type === "id" ? `id:${entry.credentialRef.id}` : `name:${entry.credentialRef.name}` : "";
135
+ return [
136
+ entry.credentialSetId,
137
+ entry.scope ?? "",
138
+ entry.alias ?? "",
139
+ credentialRefKey,
140
+ entry.schemaFingerprint ?? "",
141
+ [...entry.credentialKeys].sort().join(","),
142
+ [...entry.optionalCredentialKeys ?? []].sort().join(","),
143
+ [...entry.storedCredentialKeys ?? []].sort().join(","),
144
+ [...entry.optionalStoredCredentialKeys ?? []].sort().join(","),
145
+ entry.needsRawSecret === true ? "1" : "0",
146
+ entry.needsDynamicResolution === true ? "1" : "0",
147
+ typeof entry.dynamicResolutionCacheMs === "number" ? String(entry.dynamicResolutionCacheMs) : "",
148
+ entry.onCredentialRevoked ?? "",
149
+ entry.proxy ? JSON.stringify(entry.proxy) : ""
150
+ ].join("|");
151
+ }
152
+ function deduplicateCredentialRequirementEntries(entries) {
153
+ const deduped = /* @__PURE__ */ new Map();
154
+ for (const entry of entries) {
155
+ const key = buildCredentialRequirementEntryKey(entry);
156
+ const existing = deduped.get(key);
157
+ if (!existing) deduped.set(key, {
158
+ ...entry,
159
+ credentialKeys: [...entry.credentialKeys].sort(),
160
+ ...entry.optionalCredentialKeys ? { optionalCredentialKeys: [...entry.optionalCredentialKeys].sort() } : {},
161
+ ...entry.storedCredentialKeys ? { storedCredentialKeys: [...entry.storedCredentialKeys].sort() } : {},
162
+ ...entry.optionalStoredCredentialKeys ? { optionalStoredCredentialKeys: [...entry.optionalStoredCredentialKeys].sort() } : {}
163
+ });
164
+ else if (entry.requiredOAuthScopes?.length) {
165
+ const merged = new Set([...existing.requiredOAuthScopes ?? [], ...entry.requiredOAuthScopes]);
166
+ deduped.set(key, {
167
+ ...existing,
168
+ requiredOAuthScopes: [...merged].sort()
169
+ });
170
+ }
171
+ }
172
+ return [...deduped.values()];
173
+ }
174
+ function collectCredentialRequirementEntries(credentialRequirements) {
175
+ if (!credentialRequirements) return [];
176
+ return deduplicateCredentialRequirementEntries(Object.values(credentialRequirements.byStep ?? {}).flat());
177
+ }
178
+ z.object({ subjectMode: z.enum(["never", "requiredWhenUserProvidedCredential"]) });
179
+ /** A step's entry within a WorkflowManifest. Describes how a step is used in a workflow, not what the step itself is. */
180
+ const WorkflowStepEntrySchema = z.object({
181
+ nodeId: z.string().min(1),
182
+ stepName: z.string().min(1),
183
+ label: z.string().min(1),
184
+ callKind: CallKindSchema,
185
+ stepId: z.string().min(1).optional(),
186
+ source: SourceLocationSchema.optional(),
187
+ astKind: z.string().min(1).optional(),
188
+ importSource: ImportSourceSchema.optional(),
189
+ outputBinding: z.string().min(1).optional(),
190
+ scopeOverride: IntegrationScopeSchema.optional(),
191
+ description: z.string().optional(),
192
+ sourceCode: z.string().optional(),
193
+ exportName: z.string().optional(),
194
+ inputSchema: JsonSchemaSchema.optional(),
195
+ outputSchema: JsonSchemaSchema.optional(),
196
+ credentialSets: z.array(ResolvedCredentialSetSchema).optional()
197
+ });
198
+ const TriggerTypeSchema = z.enum([
199
+ "webhook",
200
+ "cron",
201
+ "polling"
202
+ ]);
203
+ /**
204
+ * Persisted on `deployment_triggers.trigger_source`. Mirrors the
205
+ * `webhookTrigger({ source: { type } })` discriminator so the server
206
+ * can index-filter app-source rows during provider-webhook fanout.
207
+ */
208
+ const TriggerSourceSchema = z.enum(["custom", "app"]);
209
+ const WebhookMethodSchema = z.enum([
210
+ "GET",
211
+ "POST",
212
+ "PUT",
213
+ "PATCH"
214
+ ]);
215
+ const TriggerCallbackBundleUploadSchema = z.object({
216
+ code: z.string(),
217
+ hash: z.string(),
218
+ size: z.number()
219
+ });
220
+ const TriggerCallbackExportsSchema = z.object({
221
+ verify: z.string().min(1).optional(),
222
+ filter: z.string().min(1).optional(),
223
+ idempotencyKey: z.string().min(1).optional(),
224
+ callback: z.string().min(1).optional()
225
+ });
226
+ const TransformCallbackExportsSchema = z.object({ transform: z.string().min(1).optional() });
227
+ const TriggerUploadDataSchema = z.object({
228
+ id: z.string(),
229
+ type: TriggerTypeSchema,
230
+ /**
231
+ * Source-of-truth discriminator for webhook triggers. `'custom'` means
232
+ * the trigger owns its own HTTP path; `'app'` means it is fanned out by
233
+ * a Keystroke-managed provider app. Undefined for non-webhook triggers.
234
+ */
235
+ triggerSource: TriggerSourceSchema.optional(),
236
+ enabled: z.boolean(),
237
+ path: z.string().optional(),
238
+ method: WebhookMethodSchema.optional(),
239
+ schedule: z.string().optional(),
240
+ timezone: z.string().optional(),
241
+ config: z.record(z.string(), z.unknown()).optional(),
242
+ requiredCredentials: TriggerCredentialRequirementsSchema.optional(),
243
+ storagePath: z.string().min(1).optional(),
244
+ callbackBundle: TriggerCallbackBundleUploadSchema.optional(),
245
+ callbackExports: TriggerCallbackExportsSchema.optional(),
246
+ transformCallbackBundle: TriggerCallbackBundleUploadSchema.optional(),
247
+ transformCallbackExports: TransformCallbackExportsSchema.optional()
248
+ });
249
+ //#endregion
250
+ export { TriggerCredentialRequirementsSchema as a, TriggerUploadDataSchema as c, collectCredentialRequirementEntries as d, deduplicateCredentialRequirementEntries as f, ResolvedCredentialSetSchema as i, WebhookMethodSchema as l, DeclaredCredentialRequirementSchema as n, TriggerSourceSchema as o, IntegrationScopeSchema as r, TriggerTypeSchema as s, CredentialRequirementsSchema as t, WorkflowStepEntrySchema as u };