@keystrokehq/cli 0.0.32 → 0.0.38

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 (148) hide show
  1. package/README.md +25 -4
  2. package/dist/{accept.handler-DNfIXPSP.mjs → accept.handler-CykuBpt6.mjs} +4 -4
  3. package/dist/{admin-CJp8XksD.mjs → admin-gRjPC3eD.mjs} +10 -10
  4. package/dist/{agent-manifest-De5TCxZq.mjs → agent-manifest-DfWD5tvv.mjs} +17 -27
  5. package/dist/{agents-G37PM35Z.mjs → agents-BpyuvM9p.mjs} +9 -9
  6. package/dist/{api-keys-4igNHJ_W.mjs → api-keys-BSKhdD_x.mjs} +6 -6
  7. package/dist/{api-BK3EhPvs.mjs → api-sWkB_Wta.mjs} +1 -1
  8. package/dist/{auth-CIOmmV4x.mjs → auth-DCgToFf5.mjs} +6 -6
  9. package/dist/{auth.handler-CznN_vfz.mjs → auth.handler-QRQAEUJC.mjs} +3 -3
  10. package/dist/authored-workflow-ref-BRCQgyWl.mjs +113 -0
  11. package/dist/{build-agents-DseUtzd4-CSGpNXur.mjs → build-agents-CUzBnlAG-3ePFZiJ6.mjs} +12 -11
  12. package/dist/{build-progress-DLM1Bt4T.mjs → build-progress-D_SQqdHA.mjs} +2 -2
  13. package/dist/{build-tasks-C09SdfjC-BmAVLTtQ.mjs → build-tasks-5eOvI19S-tbN6CRx9.mjs} +4 -4
  14. package/dist/{build-workflows-BZ_m97Pr-BiyptCrn.mjs → build-workflows-C-gQM3l5-_zcBHE3M.mjs} +14 -9
  15. package/dist/{build.handler-zHimoO7c.mjs → build.handler-DGQn_clk.mjs} +12 -9
  16. package/dist/{clear-cache.handler-BP0K1-uN.mjs → clear-cache.handler-gJpwslkK.mjs} +2 -2
  17. package/dist/{clear.handler-PsA5QKHx.mjs → clear.handler-CuXYvUj2.mjs} +2 -2
  18. package/dist/{clear.handler-T27GpgSu.mjs → clear.handler-DnjvgyMj.mjs} +1 -1
  19. package/dist/{commander-BlrSdFcu.mjs → commander-B_8QwPpe.mjs} +22 -3
  20. package/dist/{connect-BbLJhlIA.mjs → connect-DV9lhP6C.mjs} +3 -3
  21. package/dist/{connect.handler-BthE-7Wg.mjs → connect.handler-D6JzuFuT.mjs} +5 -5
  22. package/dist/{context-sgKhRc5v.mjs → context-Brc9VGV9.mjs} +4 -4
  23. package/dist/{create.handler-BovbO_g0.mjs → create.handler-D_tmjANR.mjs} +3 -3
  24. package/dist/{credential-env-map-CRs0llf0.mjs → credential-env-map-5a41jLwM.mjs} +1 -1
  25. package/dist/{credential-requirements-D0mavK8j-CFMf0Xwu.mjs → credential-requirements-B5Alhu1v-DanlSKnT.mjs} +3 -3
  26. package/dist/{credential-schema-mismatch-ClQgEVtO.mjs → credential-schema-mismatch-CStYUB2h.mjs} +1 -1
  27. package/dist/{credentials-DKrSaaLw.mjs → credentials-DtwLbee6.mjs} +1 -1
  28. package/dist/{credentials-CsncZ52a.mjs → credentials-UDrvrKj-.mjs} +10 -10
  29. package/dist/current-deployment-workflow-CknsHF5T.mjs +20 -0
  30. package/dist/current.handler-Cy91EeLU.mjs +19 -0
  31. package/dist/{delete.handler-DkAK396w.mjs → delete.handler-rUDDUrDQ.mjs} +2 -2
  32. package/dist/{deploy-DvPfR9fC.mjs → deploy-DgWPlEKO.mjs} +2 -2
  33. package/dist/{deploy-progress-BsUH7fGE.mjs → deploy-progress-BDOCSm_U.mjs} +2 -2
  34. package/dist/{deploy.handler-BW3f2N2G.mjs → deploy.handler-BDCHCk_A.mjs} +16 -16
  35. package/dist/{diff-utils-Bs--xmoV.mjs → diff-utils-YEUYtSRs.mjs} +1 -1
  36. package/dist/{diff.handler-BwhsoAg0.mjs → diff.handler-CGERP-Qn.mjs} +15 -9
  37. package/dist/{dist-Dw7gCE7y.mjs → dist-B5jy238v.mjs} +37 -11
  38. package/dist/{dist-CTEtWDW4.mjs → dist-BmbFJq8U.mjs} +8 -27
  39. package/dist/{env.handler-Dks6ZQh-.mjs → env.handler--8FRrSlJ.mjs} +52 -29
  40. package/dist/{error-boundary-0veZ_RDS.mjs → error-boundary-D2DiCLAp.mjs} +3 -3
  41. package/dist/{iam-command-utils-CSZj4XlH.mjs → iam-command-utils-D01Gw8-M.mjs} +3 -13
  42. package/dist/{import-module-y0glInUe-DV_3dsU0.mjs → import-module-y0glInUe-EuAWaw9g.mjs} +506 -128
  43. package/dist/{init-BOCDwqKR.mjs → init-Mpe_8lA_.mjs} +3 -3
  44. package/dist/{init.handler-B3T4J6u_.mjs → init.handler-BjLAIAmm.mjs} +5 -5
  45. package/dist/{inspect.handler-v9snxDLi.mjs → inspect.handler-CXCi7fhH.mjs} +24 -13
  46. package/dist/{integration-catalog-CiZ62hb_.mjs → integration-catalog-mZs6EAlN.mjs} +3 -3
  47. package/dist/{integrations-m7_tb3GV.mjs → integrations-D_IH5Ud1.mjs} +7 -7
  48. package/dist/{invites-BuatfJmN.mjs → invites-CWWz4wmY.mjs} +5 -5
  49. package/dist/{invites.list.handler-CK6mL10z.mjs → invites.list.handler-CQLWSoWo.mjs} +6 -5
  50. package/dist/{invites.resend.handler-CKZouK1Z.mjs → invites.resend.handler-CeIGE_qM.mjs} +6 -5
  51. package/dist/{invites.revoke.handler-H0VI-3sp.mjs → invites.revoke.handler-9K6jkym_.mjs} +6 -5
  52. package/dist/keystroke.mjs +139 -82
  53. package/dist/{list-enrichment-DP1wEyBZ.mjs → list-enrichment-dqbkXJzy.mjs} +2 -2
  54. package/dist/list.handler-BvuxTFLe.mjs +64 -0
  55. package/dist/list.handler-CDWPmiMy.mjs +39 -0
  56. package/dist/{list.handler-DVnFrlis.mjs → list.handler-Co32_F3n.mjs} +7 -7
  57. package/dist/{list.handler-CMRQKH4b.mjs → list.handler-Cuw1fWO_.mjs} +41 -12
  58. package/dist/{list.handler-DbYUk6ko.mjs → list.handler-D-rSyrX0.mjs} +5 -5
  59. package/dist/{list.handler-DIMWZx78.mjs → list.handler-DMvq96UA.mjs} +4 -4
  60. package/dist/{list.handler-LxZInip2.mjs → list.handler-DUTNS8du.mjs} +4 -4
  61. package/dist/{list.handler-BiY5NFWd.mjs → list.handler-Dz-Yeijp.mjs} +3 -3
  62. package/dist/list2.handler-BpqKZTZk.mjs +99 -0
  63. package/dist/{listen-C_7Rgwkb.mjs → listen-CeNwufij.mjs} +3 -3
  64. package/dist/{listen.handler-dJgorIzr.mjs → listen.handler-CfRoaOwu.mjs} +4 -4
  65. package/dist/{logs-B9YMhUGt.mjs → logs-B7k2_W1R.mjs} +3 -3
  66. package/dist/{logs.handler-DGGVPMOX.mjs → logs.handler-BIqJ0FED.mjs} +1 -1
  67. package/dist/{logs.handler-BfjCsAyq.mjs → logs.handler-CSqOzxCU.mjs} +26 -29
  68. package/dist/{members.add.handler-DSRCRxsI.mjs → members.add.handler-CBjoA6vG.mjs} +6 -5
  69. package/dist/{members.invite.handler-BNpHn1dY.mjs → members.invite.handler-D8KcKJ9Y.mjs} +6 -5
  70. package/dist/{members.list.handler-Bn9LJEPG.mjs → members.list.handler-CB_qSJK0.mjs} +6 -5
  71. package/dist/{members.remove.handler-Dkr2t_tX.mjs → members.remove.handler-DNhO81mo.mjs} +6 -5
  72. package/dist/{members.update.handler-DBtUYuAY.mjs → members.update.handler-Bjdk_uz4.mjs} +6 -5
  73. package/dist/{operations-CF2nUiBs.mjs → operations-HHwoArwE.mjs} +5 -5
  74. package/dist/org-context-CNh2p2DP.mjs +112 -0
  75. package/dist/{org-DOH7YHk2.mjs → org-f-qo68Em.mjs} +35 -28
  76. package/dist/org-output-BcI17Uan.mjs +64 -0
  77. package/dist/{orgs.create.handler-BO70zIdp.mjs → orgs.create.handler-DOE9ZIed.mjs} +4 -4
  78. package/dist/{orgs.get.handler-BuGg5bc9.mjs → orgs.get.handler-sWErVI7r.mjs} +4 -4
  79. package/dist/{orgs.list.handler--5HutMkl.mjs → orgs.list.handler-Cp-mXsA0.mjs} +4 -4
  80. package/dist/{output-BWcVRt-T.mjs → output-BPydP5tG.mjs} +1 -1
  81. package/dist/{package-manager-CvY4IW7X.mjs → package-manager-BwJ6muas.mjs} +27 -2
  82. package/dist/{paused.handler-DHvxz-cC.mjs → paused.handler-DWdoKYY8.mjs} +20 -33
  83. package/dist/{projects-C5GZ5Jrf.mjs → projects-CCC36zbJ.mjs} +11 -9
  84. package/dist/{register.handler-CKMZ2WmD.mjs → register.handler-Dxae5iq8.mjs} +3 -3
  85. package/dist/{render-credential-Bn15FEUC.mjs → render-credential-D-H1ECDt.mjs} +1 -1
  86. package/dist/{render-operation-DWbMwhfc.mjs → render-operation-iF7Wblv2.mjs} +2 -2
  87. package/dist/{requirements.handler-B5rqCjMu.mjs → requirements.handler-Bg3mRnER.mjs} +7 -7
  88. package/dist/{resolve-cli-credentials-CAOSVMJP.mjs → resolve-cli-credentials-GVOOedoQ.mjs} +1 -1
  89. package/dist/{resolve-project-E9mrh_el.mjs → resolve-project-CoCN9xfi.mjs} +24 -8
  90. package/dist/{run-polling-DawiBus-.mjs → run-polling-htHWhG0T.mjs} +97 -14
  91. package/dist/{run.handler-BG7xitEK.mjs → run.handler-C-CM-xZG.mjs} +42 -30
  92. package/dist/{runs-swYYBT6C.mjs → runs-BRJPNq4B.mjs} +4 -4
  93. package/dist/{schema-display-FvI8QjOQ.mjs → schema-display-sZ6ConJd.mjs} +33 -26
  94. package/dist/schemas-ClAIoIrX.mjs +281 -0
  95. package/dist/{search-CA0J5NOY.mjs → search-CQMgdp51.mjs} +3 -3
  96. package/dist/{search.handler-BVDsYZlJ.mjs → search.handler-Dn5jjyF-.mjs} +6 -6
  97. package/dist/show.handler-CdZF0aao.mjs +79 -0
  98. package/dist/{show.handler-CsidInW8.mjs → show.handler-D3nDc1MJ.mjs} +5 -5
  99. package/dist/{show.handler-CwwnCmbp.mjs → show.handler-DUDxnNiZ.mjs} +6 -6
  100. package/dist/{skill-installer-DG8kTaQR.mjs → skill-installer-DYNH_MJT.mjs} +3 -1
  101. package/dist/{skills-sync.handler-yRmi3OgP.mjs → skills-sync.handler-_LVhIMRH.mjs} +13 -7
  102. package/dist/{skills.command-COYd3k4Z.mjs → skills.command-DSHGwXPX.mjs} +5 -5
  103. package/dist/skills.handler-DqLXJepA.mjs +9 -0
  104. package/dist/{spinner-progress-lrKDs4YF.mjs → spinner-progress-fLaD0sjH.mjs} +1 -1
  105. package/dist/status.handler-1hEzX5oB.mjs +72 -0
  106. package/dist/{switch.handler-BwYndsP-.mjs → switch.handler-D135WwfB.mjs} +17 -4
  107. package/dist/{sync-6fZkIUtn.mjs → sync-CFScllh3.mjs} +2 -2
  108. package/dist/{sync.handler-Ctr-cN9X.mjs → sync.handler-x8v53-TT.mjs} +8 -8
  109. package/dist/{task-BWuIKWh4.mjs → task-DTvLzUkA.mjs} +2 -88
  110. package/dist/{task-target-build-QllcCfoN.mjs → task-target-build-CtvRyVjH.mjs} +5 -5
  111. package/dist/task-target-deploy-runner.mjs +6 -6
  112. package/dist/{test-C8VIZe9V.mjs → test-Dx4RXoLZ.mjs} +5 -5
  113. package/dist/{test.handler-DLaxrJ9V.mjs → test.handler-BmvL5vF8.mjs} +19 -16
  114. package/dist/{test.handler-BCW0YBPd.mjs → test.handler-Mz_XOnJl.mjs} +2 -2
  115. package/dist/{tool.handler-8qNmgdRe.mjs → tool.handler-DsbpocYI.mjs} +12 -12
  116. package/dist/{trigger-artifacts-BcRScRSp-BiD2h6do.mjs → trigger-artifacts-BcRScRSp-BRpU-He5.mjs} +2 -2
  117. package/dist/{trigger-manifest-C07EM-b2.mjs → trigger-manifest-BVqjDhxU.mjs} +1 -1
  118. package/dist/{upgrade-DgOcc8IT.mjs → upgrade-C9G6HksL.mjs} +4 -8
  119. package/dist/upgrade.handler-DsFeAFF4.mjs +99 -0
  120. package/dist/{upload.handler-B7xle1oX.mjs → upload.handler-DscKDQ63.mjs} +9 -9
  121. package/dist/{users.get.handler-C4t1vXwi.mjs → users.get.handler-CaUv_maM.mjs} +4 -4
  122. package/dist/{users.list.handler-Dvl90grq.mjs → users.list.handler-DzsOvAtd.mjs} +4 -4
  123. package/dist/{users.set-role.handler-Djw1_VGf.mjs → users.set-role.handler-koRzA0V9.mjs} +4 -4
  124. package/dist/{validate.handler-Drf_lssw.mjs → validate.handler-BkBsS8BL.mjs} +171 -26
  125. package/dist/{workflow-build-Begvjfq8.mjs → workflow-build-Db6at6IA.mjs} +234 -32
  126. package/dist/{workflow-build-manifest-1sC52TIG.mjs → workflow-build-manifest-CV6bBmDO.mjs} +1 -1
  127. package/dist/{workflow-bundler-BzHk73PM-muPv1yGG.mjs → workflow-bundler-Bs3zQNQv-Dy7lXxy3.mjs} +15 -4
  128. package/dist/{workflows-DjMlxuBX.mjs → workflows-B8VG6nKg.mjs} +34 -37
  129. package/dist/{writer-byNNUjRm-B-on1n6c.mjs → writer-BLg0RuZa-Y6ExdYH9.mjs} +6 -4
  130. package/package.json +10 -10
  131. package/dist/current-deployment-workflow-B1VQCYC-.mjs +0 -94
  132. package/dist/current.handler-BaGaCLzB.mjs +0 -21
  133. package/dist/list.handler-BEMj3FyH.mjs +0 -76
  134. package/dist/list.handler-Cq_oQY5B.mjs +0 -52
  135. package/dist/list.handler-htR9TeiS.mjs +0 -24
  136. package/dist/schemas-D2zfmyC-.mjs +0 -671
  137. package/dist/show.handler-nkK6Erbb.mjs +0 -31
  138. package/dist/skills.handler-DYIQK0Vu.mjs +0 -9
  139. package/dist/status.handler-Ch_DtyBp.mjs +0 -109
  140. package/dist/upgrade.handler-DSZuw7-9.mjs +0 -80
  141. /package/dist/{build-metadata-BB_L45ZS-DSJL7dTy.mjs → build-metadata-BB_L45ZS-DRQsV6JK.mjs} +0 -0
  142. /package/dist/{deploy-DhCbYFc7.mjs → deploy-BiKBH25R.mjs} +0 -0
  143. /package/dist/{detect-env-access-CwkOYeYM-COq4U-4Y.mjs → detect-env-access-CwkOYeYM-r4aynBU0.mjs} +0 -0
  144. /package/dist/{read-credential-keys-77a91T8M-DGK5XTQp.mjs → read-credential-keys-77a91T8M-I07NYwfH.mjs} +0 -0
  145. /package/dist/{run-polling-fBouPjJ2.mjs → run-polling-1c0ckC1A.mjs} +0 -0
  146. /package/dist/{schemas-4Mq_bxob.mjs → schemas-8nhXlXWh.mjs} +0 -0
  147. /package/dist/{task-target-deploy-B_3HPSo2.mjs → task-target-deploy-m9LfE488.mjs} +0 -0
  148. /package/dist/{types-AlA-ifK9.mjs → types-Cb0eWmUU.mjs} +0 -0
@@ -0,0 +1,281 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { z } from "zod";
4
+ //#region ../../packages/core/src/shared/schema.ts
5
+ const MAX_JSON_DEPTH = 20;
6
+ function buildJsonValueSchema(depth) {
7
+ const primitives = z.union([
8
+ z.string(),
9
+ z.number(),
10
+ z.boolean(),
11
+ z.null()
12
+ ]);
13
+ if (depth <= 0) return primitives;
14
+ const nested = buildJsonValueSchema(depth - 1);
15
+ return z.union([
16
+ primitives,
17
+ z.array(nested),
18
+ z.record(z.string(), nested)
19
+ ]);
20
+ }
21
+ const jsonValueSchema = buildJsonValueSchema(MAX_JSON_DEPTH);
22
+ const jsonSchemaObject = z.record(z.string(), jsonValueSchema);
23
+ const anyZodSchemaSchema = z.custom((value) => value instanceof z.ZodType, "Expected a Zod schema");
24
+ const zodObjectSchema = z.custom((value) => value instanceof z.ZodObject, "Expected a Zod object schema");
25
+ /**
26
+ * Creates a Zod schema that validates an object structurally by checking
27
+ * for required properties. This avoids `instanceof` checks which fail
28
+ * when class definitions are duplicated across bundle boundaries.
29
+ */
30
+ function createStructuralSchema(requiredKeys, label) {
31
+ return z.custom((value) => value != null && (typeof value === "object" || typeof value === "function") && requiredKeys.every((key) => key in value), `Expected ${label}`);
32
+ }
33
+ function trimmedNonEmptyString(fieldName) {
34
+ return z.string().trim().min(1, { error: `${fieldName} cannot be empty` }).max(255, { error: `${fieldName} cannot exceed 255 characters` });
35
+ }
36
+ /** Trimmed string with at least one character; no upper length limit. */
37
+ function trimmedNonEmptyStringUnbounded(fieldName) {
38
+ return z.string().trim().min(1, { error: `${fieldName} cannot be empty` });
39
+ }
40
+ /**
41
+ * Non-empty trimmed string restricted to URL-safe characters.
42
+ * Use for IDs (workflow, step, etc.) that must be safe in URLs, env vars, and as object keys.
43
+ */
44
+ function idNoSpacesString(fieldName) {
45
+ return z.string().trim().min(1, { error: `${fieldName} cannot be empty` }).max(255, { error: `${fieldName} cannot exceed 255 characters` }).refine((s) => /^[a-zA-Z0-9_-]+$/.test(s), { error: `${fieldName} must only contain letters, numbers, hyphens, and underscores` });
46
+ }
47
+ /**
48
+ * Non-empty trimmed string for credential definition ids.
49
+ * Allows namespaced ids such as `keystroke:slack` plus letters, numbers,
50
+ * hyphens, and underscores.
51
+ */
52
+ function credentialSetIdString(fieldName) {
53
+ return z.string().trim().min(1, { error: `${fieldName} cannot be empty` }).max(255, { error: `${fieldName} cannot exceed 255 characters` }).refine((s) => /^[a-zA-Z0-9_:-]+$/.test(s), { error: `${fieldName} must only contain letters, numbers, hyphens, underscores, and colons` });
54
+ }
55
+ function optionalTrimmedNonEmptyString(fieldName) {
56
+ return trimmedNonEmptyString(fieldName).optional();
57
+ }
58
+ function descriptionString(fieldName) {
59
+ return z.string().trim().min(1, { error: `${fieldName} cannot be empty` }).max(1024, { error: `${fieldName} cannot exceed 1024 characters` });
60
+ }
61
+ function optionalDescriptionString(fieldName) {
62
+ return descriptionString(fieldName).optional();
63
+ }
64
+ //#endregion
65
+ //#region ../../packages/core/src/credential-set/constants.ts
66
+ /**
67
+ * Shared constants for the credential/connection system.
68
+ * Defined in core (bottom of dependency chain) so all packages can import them.
69
+ */
70
+ const CREDENTIAL_EXPOSURES = {
71
+ "user-runtime": "user-runtime",
72
+ "platform-only": "platform-only"
73
+ };
74
+ //#endregion
75
+ //#region ../../packages/core/src/credential-set/schemas.ts
76
+ const credentialSetProxyInjectionSchema = z.object({
77
+ /** Substitute placeholder in HTTP headers (default: true). */
78
+ headers: z.boolean().optional(),
79
+ /** Substitute placeholder in the HTTP Basic Auth credential (default: true). */
80
+ basicAuth: z.boolean().optional(),
81
+ /** Substitute placeholder in URL query params (default: false).
82
+ * Use for APIs that authenticate via `?api_key=...` (Google Maps, OWM, etc.). */
83
+ queryParams: z.boolean().optional(),
84
+ /** Substitute placeholder in the HTTP request body (default: false).
85
+ * Use for form-encoded auth payloads (Stripe, AWS SigV4 query, etc.). */
86
+ body: z.boolean().optional()
87
+ });
88
+ const credentialSetProxyConfigSchema = z.object({
89
+ /** Exact-match host allowlist (forwarded to SecretBuilder.allowHost). */
90
+ hosts: z.array(z.string().min(1)).optional(),
91
+ /** Wildcard host allowlist (forwarded to SecretBuilder.allowHostPattern).
92
+ * Example: `["*.browserbase.com"]` covers any subdomain. */
93
+ hostPatterns: z.array(z.string().min(1)).optional(),
94
+ /** Per-scope substitution toggles. Omit to use SDK defaults. */
95
+ injection: credentialSetProxyInjectionSchema.optional()
96
+ });
97
+ const onCredentialRevokedSchema = z.enum(["fail", "retry-once"]);
98
+ const credentialExposureSchema = z.enum([CREDENTIAL_EXPOSURES["user-runtime"], CREDENTIAL_EXPOSURES["platform-only"]]);
99
+ const connectionMetadataConfigSchema = z.object({
100
+ id: credentialSetIdString("Credential connection id").optional(),
101
+ label: optionalTrimmedNonEmptyString("Credential connection label"),
102
+ description: optionalDescriptionString("Credential connection description"),
103
+ recommended: z.boolean().optional(),
104
+ advanced: z.boolean().optional(),
105
+ needsRawSecret: z.boolean().optional()
106
+ });
107
+ const connectionMetadataManifestSchema = connectionMetadataConfigSchema;
108
+ const registeredDescriptorSchema = z.object({
109
+ id: trimmedNonEmptyString("Registered descriptor id"),
110
+ config: z.record(z.string(), z.unknown()).optional()
111
+ });
112
+ const registeredResolverDescriptorSchema = registeredDescriptorSchema.extend({ cacheMs: z.number().int().nonnegative().optional() });
113
+ const manualConnectionConfigSchema = connectionMetadataConfigSchema.extend({
114
+ kind: z.literal("manual"),
115
+ input: zodObjectSchema.optional(),
116
+ instructions: z.string().min(1).optional(),
117
+ validate: z.function().optional()
118
+ });
119
+ const manualConnectionFieldManifestSchema = z.object({
120
+ key: z.string().min(1),
121
+ label: z.string().min(1),
122
+ description: z.string().min(1).optional(),
123
+ optional: z.boolean(),
124
+ secret: z.literal(true)
125
+ });
126
+ const manualConnectionConfigManifestSchema = connectionMetadataManifestSchema.extend({
127
+ kind: z.literal("manual"),
128
+ input: jsonSchemaObject.optional(),
129
+ fields: z.array(manualConnectionFieldManifestSchema).optional(),
130
+ generated: z.boolean().optional(),
131
+ instructions: z.string().min(1).optional()
132
+ });
133
+ /** Declarative form of `Vault` — strings typed against the credential set's
134
+ * stored/auth schema keys at the {@link CredentialSetConfig} boundary; the Zod
135
+ * schema here enforces non-empty strings only. `CredentialSet` itself performs
136
+ * the schema-key membership check at construction time. */
137
+ const vaultMappingSchema = z.object({
138
+ accessToken: z.string().min(1),
139
+ refreshToken: z.string().min(1).optional(),
140
+ instanceUrl: z.string().min(1).optional(),
141
+ raw: z.record(z.string().min(1), z.string().min(1)).optional()
142
+ });
143
+ /** Function form of `Vault` — an object pairing the access-token vault key
144
+ * (`accessTokenKey`) with the `build` function that computes the full vault
145
+ * write map. The explicit key keeps the disconnect path's revocation read
146
+ * reliable even when `build` transforms the access token. */
147
+ const vaultMappingFnSchema = z.object({
148
+ accessTokenKey: z.string().min(1),
149
+ build: z.custom((val) => typeof val === "function", { message: "vault.build must be a function." })
150
+ });
151
+ /** Runtime shape of `Vault`. Accepts either the declarative mapping or the
152
+ * function-form object `{ accessTokenKey, build }`. */
153
+ const vaultConfigSchema = z.union([vaultMappingSchema, vaultMappingFnSchema], { error: "vault must be a declarative mapping object or a `{ accessTokenKey, build }` object." });
154
+ /** Manifest projection of `Vault` — declarative mappings serialize verbatim;
155
+ * function-form mappings serialize as `{ kind: 'function', accessTokenKey }`
156
+ * since closures are not manifest-safe but the access-token key is. */
157
+ const vaultManifestSchema = z.discriminatedUnion("kind", [z.object({
158
+ kind: z.literal("declarative"),
159
+ accessToken: z.string().min(1),
160
+ refreshToken: z.string().min(1).optional(),
161
+ instanceUrl: z.string().min(1).optional(),
162
+ raw: z.record(z.string().min(1), z.string().min(1)).optional()
163
+ }), z.object({
164
+ kind: z.literal("function"),
165
+ accessTokenKey: z.string().min(1)
166
+ })]);
167
+ const oauthConnectionConfigBaseSchema = z.object({
168
+ kind: z.literal("oauth"),
169
+ authUrl: z.string().url(),
170
+ tokenUrl: z.string().url(),
171
+ scopes: z.array(z.string()).readonly(),
172
+ revokeUrl: z.string().url().nullable().optional(),
173
+ tokenType: z.enum(["long-lived", "refreshable"]),
174
+ pkce: z.boolean().optional(),
175
+ /** Fallback token lifetime when the provider omits `expires_in`. Positive
176
+ * integer seconds. Shared between config + manifest schemas (both extend
177
+ * this base). */
178
+ defaultExpiresInSeconds: z.number().int().positive().optional()
179
+ });
180
+ const oauthConnectionConfigSchema = oauthConnectionConfigBaseSchema.extend({
181
+ ...connectionMetadataConfigSchema.shape,
182
+ vault: vaultConfigSchema,
183
+ oauth: registeredDescriptorSchema.optional(),
184
+ buildAuthUrl: z.function().optional(),
185
+ exchangeCode: z.function().optional(),
186
+ refreshToken: z.function().optional(),
187
+ extractInstallationInfo: z.function().optional(),
188
+ validate: z.function().optional()
189
+ });
190
+ const oauthConnectionConfigManifestSchema = oauthConnectionConfigBaseSchema.extend({
191
+ ...connectionMetadataManifestSchema.shape,
192
+ vault: vaultManifestSchema,
193
+ oauth: registeredDescriptorSchema.optional()
194
+ });
195
+ const credentialsExchangeConnectionConfigSchema = connectionMetadataConfigSchema.extend({
196
+ kind: z.literal("credentials-exchange"),
197
+ instructions: z.string().min(1).optional(),
198
+ input: zodObjectSchema
199
+ }).extend({
200
+ exchange: z.function(),
201
+ rotate: z.function().optional(),
202
+ validate: z.function().optional()
203
+ });
204
+ /** Manifest projection of `CredentialsExchangeConnectionConfig` — only the
205
+ * declarative `input` schema (rendered as JSON Schema) and `instructions`
206
+ * copy survive serialization. The three hooks (`exchange`, `rotate`,
207
+ * `validate`) are runtime closures and are stripped. */
208
+ const credentialsExchangeConnectionConfigManifestSchema = z.object({
209
+ kind: z.literal("credentials-exchange"),
210
+ ...connectionMetadataManifestSchema.shape,
211
+ instructions: z.string().min(1).optional(),
212
+ input: jsonSchemaObject
213
+ });
214
+ const exchangeCredentialConnectionConfigSchema = connectionMetadataConfigSchema.extend({
215
+ kind: z.literal("exchange"),
216
+ input: zodObjectSchema,
217
+ exchange: registeredDescriptorSchema
218
+ });
219
+ const exchangeCredentialConnectionManifestSchema = connectionMetadataManifestSchema.extend({
220
+ kind: z.literal("exchange"),
221
+ input: jsonSchemaObject,
222
+ exchange: registeredDescriptorSchema
223
+ });
224
+ const dynamicCredentialConnectionConfigSchema = connectionMetadataConfigSchema.extend({
225
+ kind: z.literal("dynamic"),
226
+ input: zodObjectSchema.optional(),
227
+ resolver: registeredResolverDescriptorSchema
228
+ });
229
+ const dynamicCredentialConnectionManifestSchema = connectionMetadataManifestSchema.extend({
230
+ kind: z.literal("dynamic"),
231
+ input: jsonSchemaObject.optional(),
232
+ resolver: registeredResolverDescriptorSchema
233
+ });
234
+ const platformCredentialConnectionConfigSchema = connectionMetadataConfigSchema.extend({ kind: z.literal("platform") });
235
+ const platformCredentialConnectionManifestSchema = connectionMetadataManifestSchema.extend({ kind: z.literal("platform") });
236
+ const connectionConfigSchema = z.discriminatedUnion("kind", [
237
+ manualConnectionConfigSchema,
238
+ oauthConnectionConfigSchema,
239
+ credentialsExchangeConnectionConfigSchema,
240
+ exchangeCredentialConnectionConfigSchema,
241
+ dynamicCredentialConnectionConfigSchema,
242
+ platformCredentialConnectionConfigSchema
243
+ ]);
244
+ /** Manifest projection of `ConnectionConfig` — declarative metadata only. */
245
+ const connectionConfigManifestSchema = z.discriminatedUnion("kind", [
246
+ manualConnectionConfigManifestSchema,
247
+ oauthConnectionConfigManifestSchema,
248
+ credentialsExchangeConnectionConfigManifestSchema,
249
+ exchangeCredentialConnectionManifestSchema,
250
+ dynamicCredentialConnectionManifestSchema,
251
+ platformCredentialConnectionManifestSchema
252
+ ]);
253
+ const CredentialSetManifestSchema = z.object({
254
+ manifestVersion: z.literal(1),
255
+ type: z.literal("credentialSet"),
256
+ id: credentialSetIdString("Credential set id"),
257
+ name: trimmedNonEmptyString("Credential set name"),
258
+ description: optionalDescriptionString("Credential set description"),
259
+ auth: jsonSchemaObject,
260
+ exposure: credentialExposureSchema.optional(),
261
+ proxy: credentialSetProxyConfigSchema.optional(),
262
+ /** When true, resolved values are passed into execution as raw secrets (no ref-token proxy). */
263
+ needsRawSecret: z.boolean().optional(),
264
+ /** Policy when a step throws `CredentialRevokedError` against this credential set. */
265
+ onCredentialRevoked: onCredentialRevokedSchema.optional(),
266
+ connections: z.array(connectionConfigManifestSchema).optional()
267
+ });
268
+ z.object({
269
+ id: credentialSetIdString("Credential set id"),
270
+ name: optionalTrimmedNonEmptyString("Credential set name"),
271
+ description: optionalDescriptionString("Credential set description"),
272
+ auth: zodObjectSchema,
273
+ exposure: credentialExposureSchema.optional(),
274
+ proxy: credentialSetProxyConfigSchema.optional(),
275
+ /** When true, resolved values are passed into execution as raw secrets (no ref-token proxy). */
276
+ needsRawSecret: z.boolean().optional(),
277
+ onCredentialRevoked: onCredentialRevokedSchema.optional(),
278
+ connections: z.array(connectionConfigSchema).readonly().optional()
279
+ });
280
+ //#endregion
281
+ export { descriptionString as a, optionalDescriptionString as c, trimmedNonEmptyStringUnbounded as d, createStructuralSchema as i, optionalTrimmedNonEmptyString as l, credentialSetProxyConfigSchema as n, idNoSpacesString as o, anyZodSchemaSchema as r, jsonSchemaObject as s, CredentialSetManifestSchema as t, trimmedNonEmptyString as u };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { n as JsonOptionSchema, t as JSON_OPTION_CONFIG } from "./output-BWcVRt-T.mjs";
4
- import { t as createTypedCommand } from "./commander-BlrSdFcu.mjs";
3
+ import { n as JsonOptionSchema, t as JSON_OPTION_CONFIG } from "./output-BPydP5tG.mjs";
4
+ import { t as createTypedCommand } from "./commander-B_8QwPpe.mjs";
5
5
  import { z } from "zod";
6
6
  //#region src/commands/search/search.command.ts
7
7
  const SearchTypeValues = [
@@ -46,7 +46,7 @@ function createSearchCommand() {
46
46
  description: "Search query (matches name and related fields per --type)",
47
47
  key: "query"
48
48
  },
49
- loadHandler: async () => (await import("./search.handler-BVDsYZlJ.mjs")).handleSearch
49
+ loadHandler: async () => (await import("./search.handler-Dn5jjyF-.mjs")).handleSearch
50
50
  });
51
51
  }
52
52
  //#endregion
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { a as ui } from "./keystroke.mjs";
4
- import { i as writeJson } from "./output-BWcVRt-T.mjs";
5
- import { i as requireClient } from "./context-sgKhRc5v.mjs";
6
- import { t as renderCredential } from "./render-credential-Bn15FEUC.mjs";
7
- import { n as detectPackageManager, r as formatPackageInstallCommand } from "./package-manager-CvY4IW7X.mjs";
8
- import { t as renderOperation } from "./render-operation-DWbMwhfc.mjs";
3
+ import { p as ui } from "./keystroke.mjs";
4
+ import { i as writeJson } from "./output-BPydP5tG.mjs";
5
+ import { i as requireClient } from "./context-Brc9VGV9.mjs";
6
+ import { t as renderCredential } from "./render-credential-D-H1ECDt.mjs";
7
+ import { i as formatPackageInstallCommand, r as detectPackageManager } from "./package-manager-BwJ6muas.mjs";
8
+ import { t as renderOperation } from "./render-operation-iF7Wblv2.mjs";
9
9
  //#region src/lib/render-integration.ts
10
10
  function renderIntegration(i, { full = false, packageManager } = {}) {
11
11
  ui.br();
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { P as throwReportedCliExit, S as toErrorMessage, b as isAuthError, g as REAUTH_HINT, p as ui, v as getApiErrorMessage, x as isNetworkError, y as getHttpStatus } from "./keystroke.mjs";
4
+ import { a as writeJsonError, i as writeJson } from "./output-BPydP5tG.mjs";
5
+ import { i as requireClient } from "./context-Brc9VGV9.mjs";
6
+ import { i as formatPackageInstallCommand, r as detectPackageManager } from "./package-manager-BwJ6muas.mjs";
7
+ //#region src/commands/integrations/show.handler.ts
8
+ async function reportIntegrationShowFailure(ctx, integrationId, error) {
9
+ if (getHttpStatus(error) === 404) {
10
+ const message = await getApiErrorMessage(error) ?? `Integration "${integrationId}" was not found.`;
11
+ if (ctx.jsonMode) writeJsonError(message, {
12
+ code: "NOT_FOUND",
13
+ cause: error
14
+ });
15
+ else ui.error(message);
16
+ throwReportedCliExit(message, { cause: error });
17
+ }
18
+ if (isAuthError(error)) {
19
+ const message = `Not authenticated. ${REAUTH_HINT}`;
20
+ if (ctx.jsonMode) writeJsonError(message, {
21
+ code: "AUTH_ERROR",
22
+ hint: REAUTH_HINT,
23
+ cause: error
24
+ });
25
+ else ui.error(message);
26
+ throwReportedCliExit(message, { cause: error });
27
+ }
28
+ if (isNetworkError(error)) {
29
+ const url = ctx.baseUrl ?? "the Keystroke server";
30
+ const message = `Could not reach ${url} to load integration "${integrationId}".`;
31
+ const hint = `Check that your local services are running and that the CLI is pointed at ${url}.`;
32
+ if (ctx.jsonMode) writeJsonError(message, {
33
+ code: "NETWORK_ERROR",
34
+ hint,
35
+ cause: error
36
+ });
37
+ else {
38
+ ui.error(message);
39
+ ui.hint(hint);
40
+ }
41
+ throwReportedCliExit(message, { cause: error });
42
+ }
43
+ const message = `Failed to load integration "${integrationId}": ${toErrorMessage(error)}`;
44
+ if (ctx.jsonMode) writeJsonError(message, {
45
+ code: "INTEGRATION_SHOW_FAILED",
46
+ cause: error
47
+ });
48
+ else ui.error(message);
49
+ throwReportedCliExit(message, { cause: error });
50
+ }
51
+ async function handleIntegrationShow(options, ctx) {
52
+ const client = requireClient(ctx);
53
+ const integrationId = options.id;
54
+ try {
55
+ const [integration, operations] = await Promise.all([client.integrations.get(integrationId), client.integrations.listOperations(integrationId)]);
56
+ if (ctx.jsonMode) {
57
+ writeJson({
58
+ integration: integration.integration,
59
+ operations: operations.operations
60
+ });
61
+ return;
62
+ }
63
+ const entry = integration.integration;
64
+ const packageManager = detectPackageManager();
65
+ const npmPackageName = entry.npmPackageName ?? `@keystrokehq/${entry.publicId}`;
66
+ ui.text(entry.publicId);
67
+ ui.text(` ${entry.name}`);
68
+ if (entry.description) ui.text(` ${entry.description}`);
69
+ ui.text(` install: ${formatPackageInstallCommand(npmPackageName, { packageManager })}`);
70
+ ui.text(` operations (${operations.operations.length}):`);
71
+ for (const op of operations.operations) ui.text(` ${op.id} — ${op.name}`);
72
+ ui.br();
73
+ ui.hint(`Usage examples are in ${entry.npmPackageName ?? `@keystrokehq/${entry.publicId}`}'s TSDoc — open in your IDE for hover docs.`);
74
+ } catch (error) {
75
+ await reportIntegrationShowFailure(ctx, integrationId, error);
76
+ }
77
+ }
78
+ //#endregion
79
+ export { handleIntegrationShow };
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { a as ui } from "./keystroke.mjs";
4
- import { i as writeJson } from "./output-BWcVRt-T.mjs";
5
- import { i as requireClient } from "./context-sgKhRc5v.mjs";
6
- import { i as renderJsonSchema } from "./schema-display-FvI8QjOQ.mjs";
7
- import { t as renderCredential } from "./render-credential-Bn15FEUC.mjs";
3
+ import { p as ui } from "./keystroke.mjs";
4
+ import { i as writeJson } from "./output-BPydP5tG.mjs";
5
+ import { i as requireClient } from "./context-Brc9VGV9.mjs";
6
+ import { o as renderJsonSchema } from "./schema-display-sZ6ConJd.mjs";
7
+ import { t as renderCredential } from "./render-credential-D-H1ECDt.mjs";
8
8
  //#region src/commands/credentials/definitions/show.handler.ts
9
9
  async function handleCredentialDefinitionShow(options, ctx) {
10
10
  const { credential } = await requireClient(ctx).credentials.definitions.get(options.id);
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { a as ui } from "./keystroke.mjs";
4
- import { i as writeJson } from "./output-BWcVRt-T.mjs";
5
- import { i as requireClient } from "./context-sgKhRc5v.mjs";
6
- import { i as renderJsonSchema } from "./schema-display-FvI8QjOQ.mjs";
7
- import { n as detectPackageManager } from "./package-manager-CvY4IW7X.mjs";
8
- import { t as renderOperation } from "./render-operation-DWbMwhfc.mjs";
3
+ import { p as ui } from "./keystroke.mjs";
4
+ import { i as writeJson } from "./output-BPydP5tG.mjs";
5
+ import { i as requireClient } from "./context-Brc9VGV9.mjs";
6
+ import { o as renderJsonSchema } from "./schema-display-sZ6ConJd.mjs";
7
+ import { r as detectPackageManager } from "./package-manager-BwJ6muas.mjs";
8
+ import { t as renderOperation } from "./render-operation-iF7Wblv2.mjs";
9
9
  //#region src/commands/operations/show.handler.ts
10
10
  async function handleOperationShow(options, ctx) {
11
11
  const { operation } = await requireClient(ctx).operations.get(options.id);
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { D as CliExitError, a as ui } from "./keystroke.mjs";
3
+ import { A as CliExitError, p 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";
@@ -487,6 +487,8 @@ async function resolveSkillInstallChoices(options) {
487
487
  //#region src/lib/skill-installer/summary.ts
488
488
  function summarizeSkillInstall(result, verb) {
489
489
  ui.success(`${verb} ${result.skills.length} Keystroke skill(s) to ${result.canonicalDir}: ${result.skills.join(", ")}`);
490
+ const universalCanonicalAgents = result.agentTargets.filter((target) => target.slug !== "universal" && target.action === "canonical");
491
+ if (universalCanonicalAgents.length > 0) ui.hint(`${universalCanonicalAgents.map((target) => target.label).join(", ")} read skills from ${result.canonicalDir} (no separate agent skill folder).`);
490
492
  const additionalTargets = result.agentTargets.filter((target) => target.action !== "canonical");
491
493
  if (additionalTargets.length > 0) ui.success(`Provisioned ${additionalTargets.length} agent target(s): ${additionalTargets.map((target) => `${target.label} (${target.path}, ${target.action})`).join(", ")}`);
492
494
  const changedGuidance = result.guidanceFiles.filter((file) => file.action !== "skipped");
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { D as CliExitError, a as ui } from "./keystroke.mjs";
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-DG8kTaQR.mjs";
3
+ import { A as CliExitError } from "./keystroke.mjs";
4
+ import { a as writeJsonError, i as writeJson, r as isJsonMode } from "./output-BPydP5tG.mjs";
5
+ import { i as UnknownSkillAgentError, n as resolveSkillInstallChoices, r as installKeystrokeAgentSkills, t as summarizeSkillInstall } from "./skill-installer-DYNH_MJT.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) {
@@ -12,7 +12,7 @@ async function handleSkillsSync(options, _ctx) {
12
12
  const choices = await resolveSkillInstallChoices({
13
13
  agentSlugs: options.agent,
14
14
  method: options.method,
15
- interactive: process.stdin.isTTY && !isJsonMode(options)
15
+ interactive: Boolean(process.stdin.isTTY) && !isJsonMode(options)
16
16
  });
17
17
  result = await installKeystrokeAgentSkills({
18
18
  projectDir,
@@ -20,7 +20,13 @@ async function handleSkillsSync(options, _ctx) {
20
20
  method: choices.method
21
21
  });
22
22
  } catch (error) {
23
- if (error instanceof UnknownSkillAgentError) throw new CliExitError(error.message, { cause: error });
23
+ if (error instanceof UnknownSkillAgentError) {
24
+ if (isJsonMode(options)) writeJsonError(error.message, {
25
+ code: "UNKNOWN_AGENT",
26
+ cause: error
27
+ });
28
+ throw new CliExitError(error.message, { cause: error });
29
+ }
24
30
  throw error;
25
31
  }
26
32
  if (isJsonMode(options)) {
@@ -40,8 +46,8 @@ async function handleSkillsSync(options, _ctx) {
40
46
  summarizeSkillInstall(result, "Synced");
41
47
  return;
42
48
  }
43
- if (result.reason === "not_installed") throw new CliExitError("Could not resolve @keystrokehq/skills from this project or the installed CLI. Reinstall the CLI or add @keystrokehq/skills to devDependencies, run install, then run `keystroke skills sync`.", { exitCode: 1 });
44
- ui.warn(`@keystrokehq/skills is installed at ${result.packageRoot} but no skill directories with SKILL.md were found.`);
49
+ if (result.reason === "not_installed") throw new CliExitError("Could not resolve @keystrokehq/skills from the installed CLI. Reinstall the CLI, then run `keystroke skills sync`.", { exitCode: 1 });
50
+ throw new CliExitError(`@keystrokehq/skills is installed at ${result.packageRoot} but no skill directories with SKILL.md were found.`, { exitCode: 1 });
45
51
  }
46
52
  //#endregion
47
53
  export { handleSkillsSync };
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { n as JsonOptionSchema, t as JSON_OPTION_CONFIG } from "./output-BWcVRt-T.mjs";
4
- import { t as createTypedCommand } from "./commander-BlrSdFcu.mjs";
5
- import { t as SKILL_INSTALL_METHODS } from "./types-AlA-ifK9.mjs";
3
+ import { n as JsonOptionSchema, t as JSON_OPTION_CONFIG } from "./output-BPydP5tG.mjs";
4
+ import { t as createTypedCommand } from "./commander-B_8QwPpe.mjs";
5
+ import { t as SKILL_INSTALL_METHODS } from "./types-Cb0eWmUU.mjs";
6
6
  import { z } from "zod";
7
7
  //#region src/commands/skills/skills.command.ts
8
8
  const SkillsCommandOptionsSchema = JsonOptionSchema.extend({
@@ -32,13 +32,13 @@ function createSkillsCommand() {
32
32
  description: "Sync Keystroke agent skills (SKILL.md) from @keystrokehq/skills",
33
33
  schema: SkillsCommandOptionsSchema,
34
34
  optionsConfig: SKILLS_OPTIONS_CONFIG,
35
- loadHandler: async () => (await import("./skills.handler-DYIQK0Vu.mjs")).handleSkillsParent,
35
+ loadHandler: async () => (await import("./skills.handler-DqLXJepA.mjs")).handleSkillsParent,
36
36
  subcommands: [createTypedCommand({
37
37
  name: "sync",
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-yRmi3OgP.mjs")).handleSkillsSync
41
+ loadHandler: async () => (await import("./skills-sync.handler-_LVhIMRH.mjs")).handleSkillsSync
42
42
  })]
43
43
  });
44
44
  cmd.enablePositionalOptions();
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { p as ui } from "./keystroke.mjs";
4
+ //#region src/commands/skills/skills.handler.ts
5
+ async function handleSkillsParent(_options, _ctx) {
6
+ ui.hint("Run `keystroke skills sync` to refresh bundled skills in `.agents/skills`, or `keystroke skills sync --agent claude-code --method symlink` for agent-specific folders.");
7
+ }
8
+ //#endregion
9
+ export { handleSkillsParent };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { F as originalConsole, P as logger, n as style, r as isTTY, t as ANSI } from "./keystroke.mjs";
3
+ import { L as logger, R as originalConsole, n as style, r as isTTY, t as ANSI } from "./keystroke.mjs";
4
4
  import { writeSync } from "node:fs";
5
5
  import { Worker } from "node:worker_threads";
6
6
  //#region src/lib/spinner-progress.ts
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { g as REAUTH_HINT, h as AUTH_HINT, p as ui } from "./keystroke.mjs";
4
+ import { a as getApiKeyValidationStatus, c as resolveEffectiveOrganization, i as formatOrgSourceLabel, t as ORG_CONTEXT_HINT } from "./org-context-CNh2p2DP.mjs";
5
+ //#region src/commands/auth/status.handler.ts
6
+ async function getLiveUser(ctx, validation) {
7
+ if (!ctx.client || validation.kind !== "valid") return;
8
+ try {
9
+ const { user } = await ctx.client.users.getMe();
10
+ return user;
11
+ } catch {
12
+ return;
13
+ }
14
+ }
15
+ function printOrganization(effective) {
16
+ if (!effective) {
17
+ ui.warn(`No organization set. ${ORG_CONTEXT_HINT}`);
18
+ return;
19
+ }
20
+ if (effective.name) {
21
+ ui.text(`Current organization: ${effective.name}`);
22
+ return;
23
+ }
24
+ ui.text(`Current organization: ${effective.organizationId}`);
25
+ }
26
+ function printValidationStatus(validation) {
27
+ switch (validation.kind) {
28
+ case "valid":
29
+ ui.success("API key is valid.");
30
+ ui.hint(`Key ID: ${validation.apiKeyId}`);
31
+ return;
32
+ case "invalid":
33
+ ui.warn("Saved API key is invalid or expired.");
34
+ ui.hint(REAUTH_HINT);
35
+ ui.hint(`Validation error: ${validation.message}`);
36
+ return;
37
+ case "unavailable":
38
+ ui.warn(validation.reason === "network" ? "Could not reach the API to verify the saved API key." : "Could not verify the saved API key right now.");
39
+ ui.hint(`Validation error: ${validation.message}`);
40
+ return;
41
+ case "not_authenticated":
42
+ ui.warn(`Not authenticated. ${AUTH_HINT}`);
43
+ return;
44
+ }
45
+ }
46
+ function printCredentialStorage(ctx) {
47
+ if (ctx.credentialReadError) {
48
+ ui.warn("Saved credentials could not be read.");
49
+ ui.hint(`Credential read error: ${ctx.credentialReadError}`);
50
+ return;
51
+ }
52
+ if (ctx.storedOrgs.length === 0) return;
53
+ ui.hint(`Credentials: ${ctx.credentialStorageInfo.credentialsFilePath}`);
54
+ }
55
+ async function handleAuthStatus(_options, ctx) {
56
+ const validation = await getApiKeyValidationStatus(ctx);
57
+ const liveUser = await getLiveUser(ctx, validation);
58
+ const effective = await resolveEffectiveOrganization(ctx, liveUser?.organizations ?? []);
59
+ const userEmail = liveUser?.email ?? ctx.storedUser?.email;
60
+ ui.header("Keystroke CLI auth status");
61
+ if (userEmail) ui.text(`Signed in as: ${userEmail}`);
62
+ else if (validation.kind === "not_authenticated") ui.hint("No saved user identity found.");
63
+ else ui.warn("Signed-in user could not be determined from saved credentials.");
64
+ printOrganization(effective);
65
+ if (effective?.source) ui.hint(`Source: ${formatOrgSourceLabel(effective.source)}`);
66
+ else if (ctx.orgSource) ui.hint(`Source: ${formatOrgSourceLabel(ctx.orgSource)}`);
67
+ printValidationStatus(validation);
68
+ if (ctx.baseUrl) ui.hint(`API URL: ${ctx.baseUrl}`);
69
+ printCredentialStorage(ctx);
70
+ }
71
+ //#endregion
72
+ export { handleAuthStatus };