@keystrokehq/cli 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS-blurb.md +1 -1
- package/LICENSE +0 -21
- package/README.md +14 -6
- package/dist/accept.handler-DFtM0IuO.mjs +22 -0
- package/dist/admin-D_7tenRC.mjs +208 -0
- package/dist/{agent-manifest-CDnbkR2f.mjs → agent-manifest-Bfa3DBgc.mjs} +4 -4
- package/dist/{agents-CZJGxVqV.mjs → agents-DMEo-6QB.mjs} +8 -8
- package/dist/api-keys-BThGvtdn.mjs +58 -0
- package/dist/{auth-DN2VusyU.mjs → auth-CY0Gg9sN.mjs} +7 -11
- package/dist/{auth.handler-CT1BQUvu.mjs → auth.handler-CbhiLOG1.mjs} +83 -8
- package/dist/{build-agents-BmM_AsSd-BGi9wtzt.mjs → build-agents-DfbiMZ_e-CRnzruSu.mjs} +7 -7
- package/dist/{build-metadata-BWS7uhd_-DR8gJjTX.mjs → build-metadata-zidV9Cai-RgG4ndIH.mjs} +11 -11
- package/dist/{build-progress-DgYKb4hB.mjs → build-progress-Cn2j1LqF.mjs} +1 -1
- package/dist/{build-tasks-CdihpudT-D5r5HUHe.mjs → build-tasks-O1jYtlv1-Y65uGWuz.mjs} +4 -5
- package/dist/{build-workflows-CfxBnIWh-CdYPv8w2.mjs → build-workflows-3fdvdHHf-DJ_lH1NH.mjs} +9 -9
- package/dist/{build.handler-4799CjWH.mjs → build.handler-Tb3IpABI.mjs} +5 -5
- package/dist/{clear-cache.handler-B9tqSoSM.mjs → clear-cache.handler-BEbPz5Ej.mjs} +1 -1
- package/dist/{clear.handler-BydlX-zE.mjs → clear.handler-CtOZ4aRn.mjs} +1 -1
- package/dist/{clear.handler-BTIXXPTJ.mjs → clear.handler-YS8gPriq.mjs} +2 -2
- package/dist/{commander-DfTVqQ-3.mjs → commander-DZ3F3CVq.mjs} +6 -5
- package/dist/common-BrVAdUyD.mjs +20 -0
- package/dist/{connect-BUXkeH0F.mjs → connect-DpQgYg8z.mjs} +3 -3
- package/dist/{connect.handler-CYel9cy6.mjs → connect.handler-DuRr_yyN.mjs} +5 -5
- package/dist/{context-T7HZuB97.mjs → context-Y1f1hGYy.mjs} +7 -7
- package/dist/create.handler-uNG3I4wS.mjs +24 -0
- package/dist/credential-requirements-DjDFthio.mjs +480 -0
- package/dist/{credential-schema-mismatch-BKo5PjcQ.mjs → credential-schema-mismatch-B-wwbCvw.mjs} +2 -2
- package/dist/{credentials-OfVHOtG3.mjs → credentials-DHlK_O4L.mjs} +823 -14
- package/dist/{credentials-CvmjU0lK.mjs → credentials-UpgEcaub.mjs} +7 -7
- package/dist/{current-deployment-workflow-poHt27i3.mjs → current-deployment-workflow-M8GEIHxv.mjs} +5 -5
- package/dist/{current.handler-B8zKzfPp.mjs → current.handler-BqPUKCvn.mjs} +1 -1
- package/dist/declared-credential-requirements-Bwlb-KZE.mjs +132 -0
- package/dist/default-urls-BS4twrsS.mjs +7 -0
- package/dist/{delete.handler-bAu1iXVQ.mjs → delete.handler-CJTHVZaz.mjs} +1 -1
- package/dist/{deploy-7Jjls436.mjs → deploy-CdnaZY3s.mjs} +1 -1
- package/dist/{deploy-BOPIpRWm.mjs → deploy-Gw0KPrkf.mjs} +2 -2
- package/dist/{deploy-progress-BmGUNFKg.mjs → deploy-progress-CZ2rPlOj.mjs} +1 -1
- package/dist/{deploy.handler-BAzgiNhd.mjs → deploy.handler-zzFAt7pp.mjs} +18 -18
- package/dist/{detect-env-access-CwkOYeYM-D_BCZqV6.mjs → detect-env-access-CwkOYeYM-h2W05D_Q.mjs} +1 -1
- package/dist/{diff.handler-Du7SY8K4.mjs → diff.handler--zdSkUnK.mjs} +5 -5
- package/dist/{dist-CUK7yBM0.mjs → dist-BF6r1hfv.mjs} +3 -3
- package/dist/{dist-BkJUoBiG.mjs → dist-C2Dq_nx3.mjs} +12 -12
- package/dist/{env-91KwMKov.mjs → env-YTZGKGIu.mjs} +9 -10
- package/dist/{env.handler-BAzBuMzQ.mjs → env.handler-d4sJ706C.mjs} +8 -8
- package/dist/{error-boundary-VL-JLfIa.mjs → error-boundary-B9PgBkv8.mjs} +2 -2
- package/dist/{file-metadata-D1vm-XY2.mjs → file-metadata-CdFXMMIw.mjs} +1 -1
- package/dist/hosted-action-dispatcher-registry-TOVzMhUR.mjs +126 -0
- package/dist/iam-command-utils-CNC8JfZ5.mjs +72 -0
- package/dist/{import-module-CV84H5fZ-B_CBCmb4.mjs → import-module-DDPnzlJ1-CYJD2n2b.mjs} +395 -10
- package/dist/{init-DpMCotSK.mjs → init-C0sps8R7.mjs} +2 -2
- package/dist/{init.handler-CPRnif52.mjs → init.handler-DSW6XFZn.mjs} +17 -17
- package/dist/{inspect.handler-DT_cD036.mjs → inspect.handler-DbN0ZVTh.mjs} +5 -5
- package/dist/{integration-catalog-Bt-L3GjF.mjs → integration-catalog-DFlytKJS.mjs} +2 -2
- package/dist/{integrations-DlatPK4W.mjs → integrations-Dcadds2b.mjs} +5 -5
- package/dist/invites-DvsxTRAb.mjs +44 -0
- package/dist/invites.list.handler-B5quln3m.mjs +43 -0
- package/dist/invites.resend.handler-CSpj7bQ5.mjs +23 -0
- package/dist/invites.revoke.handler-_hdEkBdO.mjs +28 -0
- package/dist/keystroke.mjs +31 -22
- package/dist/{list-enrichment-y-cwizLr.mjs → list-enrichment-CTqx0Rk_.mjs} +1 -1
- package/dist/{list.handler-CWF_Dj15.mjs → list.handler-08GY-wnx.mjs} +1 -1
- package/dist/{list.handler-DWaQkJaR.mjs → list.handler-20v4uRMk.mjs} +2 -2
- package/dist/{list.handler-BTWvCyjA.mjs → list.handler-BRq-nScx.mjs} +5 -5
- package/dist/{list.handler-lq3ZGAn4.mjs → list.handler-CWO6DExh.mjs} +3 -3
- package/dist/{list.handler-CZ6G2x_G.mjs → list.handler-DAiJtW20.mjs} +3 -3
- package/dist/list.handler-DLl8ca6F.mjs +42 -0
- package/dist/{list.handler-DqbFcBW7.mjs → list.handler-DSPr0OxS.mjs} +7 -7
- package/dist/{logs-BEg9L5l8.mjs → logs-D_48skmi.mjs} +3 -3
- package/dist/{logs.handler-BD_dXiL1.mjs → logs.handler-4ctMVYMj.mjs} +3 -3
- package/dist/{logs.handler-6hoMBzqw.mjs → logs.handler-C3QnSCaH.mjs} +1 -1
- package/dist/members.add.handler-Dq_giQ8g.mjs +31 -0
- package/dist/members.invite.handler-v404bUsq.mjs +32 -0
- package/dist/members.list.handler-D6TE0yp8.mjs +43 -0
- package/dist/members.remove.handler-BhQ3cyeR.mjs +28 -0
- package/dist/members.update.handler-BVy2cv1K.mjs +28 -0
- package/dist/{metadata-layout-GUYIUo0i-_aG2zjue.mjs → metadata-layout-C6ed-9dl-aBmqqvD5.mjs} +2 -2
- package/dist/{normalize-path-CojS-CgQ-DLCOvnD1.mjs → normalize-path-CojS-CgQ-BKRFUzWW.mjs} +1 -1
- package/dist/org-CkRr-f3S.mjs +234 -0
- package/dist/orgs.create.handler-swGnT2ce.mjs +26 -0
- package/dist/orgs.get.handler-ClAqYTH0.mjs +28 -0
- package/dist/orgs.list.handler-D-ptz8It.mjs +41 -0
- package/dist/{paused.handler-BMFm9Cff.mjs → paused.handler-B3aVqw-m.mjs} +2 -2
- package/dist/{project-config-D1qsQlO7.mjs → project-config-opj6DsPF.mjs} +2 -2
- package/dist/{projects-CHkRE9rS.mjs → projects-Bdl6-Z8l.mjs} +2 -2
- package/dist/{projects-Cjb7sovS.mjs → projects-yA9AAaDM.mjs} +5 -5
- package/dist/{register.handler-BPCdor1_.mjs → register.handler-WzpvVXHx.mjs} +1 -1
- package/dist/{requirements.handler-DPXdSks3.mjs → requirements.handler-coArDE8x.mjs} +7 -7
- package/dist/{resolve-project-DDJ29sCF.mjs → resolve-project-DgfftdPm.mjs} +2 -2
- package/dist/{runs-D9hNLb9A.mjs → runs-B8mW4PqP.mjs} +3 -3
- package/dist/schedule-BRN4hzQM.mjs +505 -0
- package/dist/schema-_FQrHcIS.mjs +17 -0
- package/dist/schema-kbMHVnhm.mjs +81 -0
- package/dist/schemas-DsvCZfF0.mjs +42 -0
- package/dist/{skills-sync.handler-DIy8GR16.mjs → skills-sync.handler-C2faeat-.mjs} +2 -2
- package/dist/{skills.command-CrjI2dN9.mjs → skills.command-DWxcc3Ui.mjs} +4 -4
- package/dist/source-analysis-BspLa3E5.mjs +75 -0
- package/dist/{source-analysis-Cj-ADyu--BJQcFPCG.mjs → source-analysis-DEEChuND-eixwPnPP.mjs} +5 -5
- package/dist/{src-eHwu-Gfw.mjs → src-J09NGJ6Z.mjs} +42 -6
- package/dist/{switch.handler-D_9213Vf.mjs → switch.handler-C4hgbhcH.mjs} +2 -2
- package/dist/{sync-BL_Mo5st.mjs → sync-CL6zXiiA.mjs} +2 -2
- package/dist/{sync.handler-BUFPdzWz.mjs → sync.handler-D1uF8E8I.mjs} +8 -8
- package/dist/{schemas-CDib1RhE.mjs → task-DsrXI6XH.mjs} +10 -39
- package/dist/{task-target-build-CBeCKbu2.mjs → task-target-build-DTzz4fpG.mjs} +4 -4
- package/dist/task-target-deploy-BPLlP__P.mjs +4 -0
- package/dist/{task-target-deploy-CA6elFpF-BEr4gkol.mjs → task-target-deploy-Bf5i3ox1-BU16VPsE.mjs} +2 -3
- package/dist/task-target-deploy-runner.mjs +15 -14
- package/dist/{test-BHTgR3UA.mjs → test-BsTLXIPB.mjs} +31 -31
- package/dist/{test.handler-BcPQ8b74.mjs → test.handler-D25kziPi.mjs} +1 -1
- package/dist/{trigger-artifacts-DQPbQNqC-B4yeeFBY.mjs → trigger-artifacts-B3OCTX9K-DG-FGGJT.mjs} +5 -5
- package/dist/{trigger-manifest-CY7brZeg.mjs → trigger-manifest-CXD9I7Rb.mjs} +1 -2
- package/dist/{try-deploy.handler-DqybNhXx.mjs → try-deploy.handler-2aX5TmLk.mjs} +11 -11
- package/dist/{upload.handler-DCtiznQp.mjs → upload.handler-CqProKVJ.mjs} +10 -10
- package/dist/users.get.handler-C_d2GWKX.mjs +24 -0
- package/dist/users.list.handler-DXAsO8Yk.mjs +36 -0
- package/dist/users.set-role.handler-Bn_yV4RI.mjs +27 -0
- package/dist/{utils-CywxCDM7.mjs → utils-DlYHjGg9.mjs} +2 -2
- package/dist/{validate.handler-DOcTaJL0.mjs → validate.handler-CGD6GttR.mjs} +5 -5
- package/dist/{workflow-build-DBQaBfnn.mjs → workflow-build-BcaIdRR6.mjs} +22 -45
- package/dist/{workflow-bundler-BPiqVscj-X1PFFAuP.mjs → workflow-bundler-BzHk73PM-Cde7cKiU.mjs} +4 -4
- package/dist/{_manifest-JSRE3H8k.mjs → workflow-manifest-CAW5FlX0.mjs} +7 -131
- package/dist/{workflows-g9z87AJJ.mjs → workflows-S-gbfw8f.mjs} +16 -15
- package/dist/{writer-BG8poUm3-BbXlU2kI.mjs → writer-CtvttJdP-DrJruQgR.mjs} +8 -8
- package/package.json +9 -11
- package/THIRD_PARTY_NOTICES.md +0 -16
- package/dist/api-keys-D2lgguuY.mjs +0 -40
- package/dist/org-xLzBtt2_.mjs +0 -41
- package/dist/schedule-BXx3uXwr.mjs +0 -1142
- package/dist/src-C0X6u_Mw.mjs +0 -1340
- package/dist/task-B2sZMaZu.mjs +0 -8
- package/dist/task-target-deploy-C5X-USeR.mjs +0 -4
- /package/dist/{agent-bundle-package-DWV6B_5q-BtV7Xycc.mjs → agent-bundle-package-DWV6B_5q-FPT0bJaA.mjs} +0 -0
- /package/dist/{browser-qwFrUH82.mjs → browser-gddMccBQ.mjs} +0 -0
- /package/dist/{concurrency-gXn9Rw8x-DNl2YtrS.mjs → concurrency-gXn9Rw8x-BTlfau8D.mjs} +0 -0
- /package/dist/{constants-CPpPdSNg.mjs → constants-DHdiT5hc.mjs} +0 -0
- /package/dist/{credential-env-map-CI8yWHVy.mjs → credential-env-map-C8P7uTD-.mjs} +0 -0
- /package/dist/{diff-utils-NEfcjqxt.mjs → diff-utils-DWNcRA8g.mjs} +0 -0
- /package/dist/{get-intrinsic-zLxwtrLK.mjs → get-intrinsic-ZMBBjBEr.mjs} +0 -0
- /package/dist/{layout-CbMtQ2tm.mjs → layout-B95Tku8F.mjs} +0 -0
- /package/dist/{options-CeaTcFxP.mjs → options-Dn9t3K4a.mjs} +0 -0
- /package/dist/{output-DM4b7KgY.mjs → output-q4KljAhu.mjs} +0 -0
- /package/dist/{oxc-B3KI3rf_-n9d1hKNq.mjs → oxc-B3KI3rf_-BeimiQ2U.mjs} +0 -0
- /package/dist/{read-credential-keys-77a91T8M-KA0Iw0Z1.mjs → read-credential-keys-77a91T8M-CAJLnMRi.mjs} +0 -0
- /package/dist/{rolldown-runtime-twds-ZHy-BWWzu8VG.mjs → rolldown-runtime-twds-ZHy-8uqgIurC.mjs} +0 -0
- /package/dist/{run-polling-CAgFRdK3.mjs → run-polling-CTzhTgyN.mjs} +0 -0
- /package/dist/{schema-17qMfNyI.mjs → schema-Di90TXoX.mjs} +0 -0
- /package/dist/{schema-display-CgmeKigW.mjs → schema-display-D4A1gQEM.mjs} +0 -0
- /package/dist/{skills.handler-Bz8bJKql.mjs → skills.handler-8KCSF7wp.mjs} +0 -0
- /package/dist/{spinner-progress-DMVwgqO9.mjs → spinner-progress-bvKd1jXc.mjs} +0 -0
- /package/dist/{status.handler-BO4nwvWn.mjs → status.handler-D9GBEmao.mjs} +0 -0
- /package/dist/{sync-keystroke-agent-skills-Kx_H7UTd.mjs → sync-keystroke-agent-skills-CY9h25_5.mjs} +0 -0
- /package/dist/{upload-CkU--iDC.mjs → upload-B8fiWveA.mjs} +0 -0
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { i as __toESM, n as __exportAll$1, r as __require, t as __commonJSMin$1 } from "./chunk-CH6r78ws.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import "./
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
4
|
+
import { n as RetryConfigSchema } from "./common-BrVAdUyD.mjs";
|
|
5
|
+
import { d as schemaToJsonSchema, f as trimmedNonEmptyString, i as descriptionString, m as validateConfig, n as createStructuralSchema, o as jsonSchemaObject, t as anyZodSchemaSchema } from "./schema-kbMHVnhm.mjs";
|
|
6
|
+
import { _ as CREDENTIAL_VISIBILITIES, f as collectCredentialRequirementEntries, g as CREDENTIAL_KINDS, h as credentialSetConfigSchema, m as CredentialSetManifestSchema } from "./credential-requirements-DjDFthio.mjs";
|
|
7
|
+
import { r as toDeclaredCredentialRequirements } from "./declared-credential-requirements-Bwlb-KZE.mjs";
|
|
8
|
+
import { i as parseDurationToMs, t as DurationSchema } from "./schedule-BRN4hzQM.mjs";
|
|
9
|
+
import { _ as registerOfficialIntegrationOperation, d as getRegisteredOperationContext, g as getOfficialIntegrationMetadata, i as getRegisteredHostedActionDispatcher, l as resolveRegisteredOperationCredentials, m as getRegisteredRuntime, r as getHostedActionExecutionPolicy } from "./hosted-action-dispatcher-registry-TOVzMhUR.mjs";
|
|
10
|
+
import { a as require_type, i as require_shams$1, n as require_hasown, t as require_get_intrinsic } from "./get-intrinsic-ZMBBjBEr.mjs";
|
|
8
11
|
import { readFile } from "node:fs/promises";
|
|
9
12
|
import { ZodType, z } from "zod";
|
|
10
13
|
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
11
14
|
import { EventEmitter } from "events";
|
|
12
15
|
import util from "util";
|
|
13
16
|
import stream, { Readable } from "stream";
|
|
17
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
14
18
|
import https from "https";
|
|
15
19
|
import process$1 from "process";
|
|
16
20
|
import crypto$1 from "crypto";
|
|
@@ -20,7 +24,812 @@ import url from "url";
|
|
|
20
24
|
import zlib from "zlib";
|
|
21
25
|
import { ZodFirstPartyTypeKind } from "zod/v3";
|
|
22
26
|
import http2 from "http2";
|
|
23
|
-
//#region ../../packages/
|
|
27
|
+
//#region ../../packages/core/src/internal/runtime-call-interceptor.ts
|
|
28
|
+
const ASYNC_STORAGE_KEY = "__ks_runtime_call_interceptor_async_storage";
|
|
29
|
+
const STACK_KEY = "__ks_runtime_call_interceptor_stack";
|
|
30
|
+
function getAsyncStorage() {
|
|
31
|
+
const g = globalThis;
|
|
32
|
+
if (ASYNC_STORAGE_KEY in g) return g[ASYNC_STORAGE_KEY];
|
|
33
|
+
const AsyncLocalStorage = g.process?.getBuiltinModule?.("async_hooks")?.AsyncLocalStorage;
|
|
34
|
+
const storage = AsyncLocalStorage ? new AsyncLocalStorage() : void 0;
|
|
35
|
+
g[ASYNC_STORAGE_KEY] = storage;
|
|
36
|
+
return storage;
|
|
37
|
+
}
|
|
38
|
+
function getStack() {
|
|
39
|
+
const g = globalThis;
|
|
40
|
+
if (!g[STACK_KEY]) g[STACK_KEY] = [];
|
|
41
|
+
return g[STACK_KEY];
|
|
42
|
+
}
|
|
43
|
+
function getActiveRuntimeCallInterceptor() {
|
|
44
|
+
const asyncStorage = getAsyncStorage();
|
|
45
|
+
if (asyncStorage) return asyncStorage.getStore()?.at(-1);
|
|
46
|
+
const stack = getStack();
|
|
47
|
+
return stack.length > 0 ? stack[stack.length - 1] : void 0;
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region ../../packages/core/src/shared/primitive.ts
|
|
51
|
+
/**
|
|
52
|
+
* Base class for all Keystroke primitives. The `kind` discriminator lets
|
|
53
|
+
* downstream code narrow primitive unions (e.g. `AnyAgentToolEntry =
|
|
54
|
+
* AnyOperation | AnyWorkflow`) without resorting to structural `'x' in tool`
|
|
55
|
+
* checks. Each subclass declares a literal `kind` matching its identity.
|
|
56
|
+
*/
|
|
57
|
+
var Primitive = class {};
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region ../../packages/core/src/credential-set/zod-shape.ts
|
|
60
|
+
/**
|
|
61
|
+
* Shape-reflection helpers for `CredentialSet` schemas.
|
|
62
|
+
*
|
|
63
|
+
* Shared between the `CredentialSet` constructor (which memoizes the key
|
|
64
|
+
* lists onto the instance) and the construction-time identity registry
|
|
65
|
+
* (which hashes the same shape into a fingerprint). Kept in its own
|
|
66
|
+
* module to avoid an import cycle between `CredentialSet.ts` and
|
|
67
|
+
* `registry.ts`.
|
|
68
|
+
*/
|
|
69
|
+
/**
|
|
70
|
+
* Inspect a `z.ZodObject` once and return its sorted property keys plus the
|
|
71
|
+
* subset wrapped in `.optional()` / `.default()`.
|
|
72
|
+
*
|
|
73
|
+
* Tolerates both the Zod v3 `.shape` getter and the Zod v4 `_def.shape`
|
|
74
|
+
* thunk so the helper stays stable across schema versions.
|
|
75
|
+
*/
|
|
76
|
+
function readZodObjectKeyMetadata(schema) {
|
|
77
|
+
const resolvedShape = resolveZodObjectShape(schema);
|
|
78
|
+
if (resolvedShape === null || typeof resolvedShape !== "object") return {
|
|
79
|
+
all: [],
|
|
80
|
+
optional: []
|
|
81
|
+
};
|
|
82
|
+
const entries = Object.entries(resolvedShape);
|
|
83
|
+
return {
|
|
84
|
+
all: entries.map(([key]) => key).sort(),
|
|
85
|
+
optional: entries.filter(([, field]) => field instanceof z.ZodOptional || field instanceof z.ZodDefault).map(([key]) => key).sort()
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Resolve the raw shape record of a `z.ZodObject` tolerating v3 and v4
|
|
90
|
+
* internal layouts. Returns `null` when the object cannot be reflected.
|
|
91
|
+
*/
|
|
92
|
+
function resolveZodObjectShape(schema) {
|
|
93
|
+
const internals = schema;
|
|
94
|
+
const rawShape = internals._def?.shape ?? internals.shape;
|
|
95
|
+
const resolved = typeof rawShape === "function" ? rawShape() : rawShape;
|
|
96
|
+
if (resolved === null || typeof resolved !== "object") return null;
|
|
97
|
+
return resolved;
|
|
98
|
+
}
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region ../../packages/core/src/credential-set/registry.ts
|
|
101
|
+
/**
|
|
102
|
+
* The backing map is keyed on `globalThis` under a well-known
|
|
103
|
+
* `Symbol.for(...)` so (a) multiple bundles/subpaths of this package share
|
|
104
|
+
* a single registry instance at runtime and (b) host-side test harnesses
|
|
105
|
+
* that cannot take a direct dependency on `@keystrokehq/core`
|
|
106
|
+
* (e.g. `@keystroke/test-utils`, which would otherwise form a cycle
|
|
107
|
+
* through `@keystroke/local-memory`) can still drive the reset hook by
|
|
108
|
+
* clearing the same `Map` via the exported {@link CREDENTIAL_SET_REGISTRY_SYMBOL}.
|
|
109
|
+
*/
|
|
110
|
+
const CREDENTIAL_SET_REGISTRY_SYMBOL = Symbol.for("@keystrokehq/core/credential-set-registry");
|
|
111
|
+
function getRegistry$1() {
|
|
112
|
+
const globalWithRegistry = globalThis;
|
|
113
|
+
const existing = globalWithRegistry[CREDENTIAL_SET_REGISTRY_SYMBOL];
|
|
114
|
+
if (existing) return existing;
|
|
115
|
+
const fresh = /* @__PURE__ */ new Map();
|
|
116
|
+
globalWithRegistry[CREDENTIAL_SET_REGISTRY_SYMBOL] = fresh;
|
|
117
|
+
return fresh;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Thrown when two `CredentialSet` instances share the same
|
|
121
|
+
* `resolvedCredentialSetId` but declare different shapes.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```ts
|
|
125
|
+
* new CredentialSet({ id: 'stripe', auth: z.object({ STRIPE_SECRET_KEY: z.string() }) });
|
|
126
|
+
* // later, in a maintenance script:
|
|
127
|
+
* new CredentialSet({ id: 'stripe', auth: z.object({ STRIPE_API_KEY: z.string() }) });
|
|
128
|
+
* // -> throws DuplicateCredentialSetDefinitionError
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
var DuplicateCredentialSetDefinitionError = class extends Error {
|
|
132
|
+
manifestId;
|
|
133
|
+
firstDeclaredAt;
|
|
134
|
+
secondDeclaredAt;
|
|
135
|
+
firstFingerprint;
|
|
136
|
+
secondFingerprint;
|
|
137
|
+
constructor(options) {
|
|
138
|
+
super([
|
|
139
|
+
`Two CredentialSet instances were declared with the same manifestId "${options.manifestId}",`,
|
|
140
|
+
`but they have different shapes:`,
|
|
141
|
+
` first (${options.firstDeclaredAt}): ${options.firstFingerprint}`,
|
|
142
|
+
` second (${options.secondDeclaredAt}): ${options.secondFingerprint}`,
|
|
143
|
+
"",
|
|
144
|
+
"If you meant to share these credentials, import the same instance from a single module.",
|
|
145
|
+
"If you meant two distinct credential sets, give them different ids (or namespaces)."
|
|
146
|
+
].join("\n"));
|
|
147
|
+
this.name = "DuplicateCredentialSetDefinitionError";
|
|
148
|
+
this.manifestId = options.manifestId;
|
|
149
|
+
this.firstDeclaredAt = options.firstDeclaredAt;
|
|
150
|
+
this.secondDeclaredAt = options.secondDeclaredAt;
|
|
151
|
+
this.firstFingerprint = options.firstFingerprint;
|
|
152
|
+
this.secondFingerprint = options.secondFingerprint;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Register a newly constructed credential set by its
|
|
157
|
+
* `resolvedCredentialSetId`. Called once per `CredentialSet` constructor.
|
|
158
|
+
*
|
|
159
|
+
* @throws {DuplicateCredentialSetDefinitionError} when the id was
|
|
160
|
+
* previously registered with a different schema fingerprint.
|
|
161
|
+
*/
|
|
162
|
+
function registerCredentialSet(params) {
|
|
163
|
+
const registry = getRegistry$1();
|
|
164
|
+
const existing = registry.get(params.manifestId);
|
|
165
|
+
if (existing && existing.fingerprint !== params.fingerprint) throw new DuplicateCredentialSetDefinitionError({
|
|
166
|
+
manifestId: params.manifestId,
|
|
167
|
+
firstDeclaredAt: existing.sourceHint,
|
|
168
|
+
secondDeclaredAt: params.sourceHint,
|
|
169
|
+
firstFingerprint: existing.fingerprint,
|
|
170
|
+
secondFingerprint: params.fingerprint
|
|
171
|
+
});
|
|
172
|
+
registry.set(params.manifestId, {
|
|
173
|
+
fingerprint: params.fingerprint,
|
|
174
|
+
sourceHint: params.sourceHint
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Produce a deterministic fingerprint of a `CredentialSet`'s auth (and
|
|
179
|
+
* `stored`, when present) schema. The fingerprint is a stable string of
|
|
180
|
+
* sorted `key:typeTag` pairs separated by `|`, with the stored shape
|
|
181
|
+
* concatenated after a `#` delimiter when the credential set declares a
|
|
182
|
+
* `stored` schema.
|
|
183
|
+
*
|
|
184
|
+
* Refinements (`.min(1)`, regex, etc.) are intentionally ignored — they
|
|
185
|
+
* are not breaking changes for vault compatibility. Structural changes
|
|
186
|
+
* (added keys, renamed keys, changed underlying Zod types, flipping
|
|
187
|
+
* required ↔ optional) produce a different fingerprint.
|
|
188
|
+
*
|
|
189
|
+
* @see registerCredentialSet
|
|
190
|
+
*/
|
|
191
|
+
function fingerprintAuthShape(auth, stored) {
|
|
192
|
+
const authPart = shapeSignature(auth);
|
|
193
|
+
if (!stored) return authPart;
|
|
194
|
+
return `${authPart}#${shapeSignature(stored)}`;
|
|
195
|
+
}
|
|
196
|
+
function shapeSignature(schema) {
|
|
197
|
+
const resolvedShape = resolveZodObjectShape(schema);
|
|
198
|
+
if (!resolvedShape) return "";
|
|
199
|
+
return readZodObjectKeyMetadata(schema).all.map((key) => `${key}:${typeTag(resolvedShape[key])}`).sort().join("|");
|
|
200
|
+
}
|
|
201
|
+
function typeTag(zodType) {
|
|
202
|
+
if (zodType === null || zodType === void 0) return "Unknown";
|
|
203
|
+
const def = zodType._def;
|
|
204
|
+
return def?.typeName ?? def?.type ?? "Unknown";
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Best-effort source hint — a short file:line string recovered from a
|
|
208
|
+
* lightweight stack trace at call time. Used only in the error message;
|
|
209
|
+
* does not affect correctness of the registry comparison.
|
|
210
|
+
*
|
|
211
|
+
* @remarks
|
|
212
|
+
* The hint format is `path/to/file.ts:line:col` when a repo frame can
|
|
213
|
+
* be isolated, and `'unknown'` otherwise. Callers should treat the
|
|
214
|
+
* value as opaque.
|
|
215
|
+
*/
|
|
216
|
+
function captureStackOrigin() {
|
|
217
|
+
const frame = ((/* @__PURE__ */ new Error()).stack?.split("\n") ?? []).slice(1).find((line) => (line.includes("/packages/") || line.includes("/apps/")) && !/\/credential-set\/registry\.[mc]?[jt]s/.test(line) && !/\/credential-set\/CredentialSet\.[mc]?[jt]s/.test(line));
|
|
218
|
+
if (!frame) return "unknown";
|
|
219
|
+
const parens = frame.match(/\(([^)]+)\)/);
|
|
220
|
+
if (parens?.[1]) return parens[1];
|
|
221
|
+
const bare = frame.match(/at\s+(.+)$/);
|
|
222
|
+
if (bare?.[1]) return bare[1];
|
|
223
|
+
return "unknown";
|
|
224
|
+
}
|
|
225
|
+
//#endregion
|
|
226
|
+
//#region ../../packages/core/src/credential-set/CredentialSet.ts
|
|
227
|
+
var CredentialSet = class extends Primitive {
|
|
228
|
+
kind = "credential-set";
|
|
229
|
+
id;
|
|
230
|
+
/** Optional namespace. Official Keystroke integrations use 'keystroke'. */
|
|
231
|
+
namespace;
|
|
232
|
+
/**
|
|
233
|
+
* Computed namespaced identifier used for storage and manifest-facing wiring.
|
|
234
|
+
*
|
|
235
|
+
* Use this value for DB storage, manifest entries, and explicit credential
|
|
236
|
+
* bindings. Do not use it as the runtime `ctx.credentials` key inside authored
|
|
237
|
+
* code.
|
|
238
|
+
*
|
|
239
|
+
* @remarks
|
|
240
|
+
* Runtime credential context is keyed by the raw `id`, not this field. That
|
|
241
|
+
* is why `ctx.credentials.slack` uses `slack` rather than `keystroke:slack`.
|
|
242
|
+
*/
|
|
243
|
+
resolvedCredentialSetId;
|
|
244
|
+
name;
|
|
245
|
+
description;
|
|
246
|
+
auth;
|
|
247
|
+
stored;
|
|
248
|
+
resolve;
|
|
249
|
+
/**
|
|
250
|
+
* Run-scoped cache TTL in milliseconds for the {@link resolve} output.
|
|
251
|
+
*
|
|
252
|
+
* Always a number; `0` means "no cache". Consumed by the credential
|
|
253
|
+
* runtime's `ResolveCache` when present.
|
|
254
|
+
*
|
|
255
|
+
* @see {@link CredentialSetConfig.resolveCacheMs}
|
|
256
|
+
*/
|
|
257
|
+
resolveCacheMs;
|
|
258
|
+
/**
|
|
259
|
+
* Platform-side `stored`→`auth` transform. Mutually exclusive with
|
|
260
|
+
* {@link resolve}. Runs on the trusted host via
|
|
261
|
+
* `@keystroke/credential-runtime`'s `executePlatformResolve` helper.
|
|
262
|
+
*
|
|
263
|
+
* @see {@link resolveLocation}
|
|
264
|
+
* @see {@link platformEnvAllowlist}
|
|
265
|
+
*/
|
|
266
|
+
resolveAtPlatform;
|
|
267
|
+
/**
|
|
268
|
+
* Resolved description of where the `stored`→`auth` transform runs.
|
|
269
|
+
*
|
|
270
|
+
* Computed at construction as `'platform'` when `resolveAtPlatform`
|
|
271
|
+
* is declared, `'sandbox'` when `resolve` is declared, `'none'`
|
|
272
|
+
* otherwise. The credential runtime's phase 3 branches on this value
|
|
273
|
+
* to pick the right execution location.
|
|
274
|
+
*
|
|
275
|
+
* @see {@link CredentialResolveLocation}
|
|
276
|
+
*/
|
|
277
|
+
resolveLocation;
|
|
278
|
+
/**
|
|
279
|
+
* Env-var names `resolveAtPlatform` may read through `ctx.env`.
|
|
280
|
+
* Frozen at construction. Empty when `resolveLocation !== 'platform'`.
|
|
281
|
+
*
|
|
282
|
+
* @see {@link PlatformResolveContext.env}
|
|
283
|
+
*/
|
|
284
|
+
platformEnvAllowlist;
|
|
285
|
+
needsResolve;
|
|
286
|
+
/** Required when namespace is 'keystroke'. Optional for user-authored credential sets. */
|
|
287
|
+
platformMetadata;
|
|
288
|
+
proxy;
|
|
289
|
+
needsRawSecret;
|
|
290
|
+
/**
|
|
291
|
+
* Policy when a step throws `CredentialRevokedError` against this credential set.
|
|
292
|
+
*
|
|
293
|
+
* @see {@link import('./types').CredentialSetConfig.onCredentialRevoked}
|
|
294
|
+
*/
|
|
295
|
+
onCredentialRevoked;
|
|
296
|
+
/**
|
|
297
|
+
* Describe the optional user-facing connect flow for this credential set.
|
|
298
|
+
*
|
|
299
|
+
* Set this when the credential should be uploaded through a manual form or an
|
|
300
|
+
* OAuth handshake. Omit it for platform-seeded or internal credentials that do
|
|
301
|
+
* not expose a user-facing connect flow.
|
|
302
|
+
*
|
|
303
|
+
* @see {@link CredentialSetConfig.connection}
|
|
304
|
+
*/
|
|
305
|
+
connection;
|
|
306
|
+
/** Sorted keys declared on the `auth` schema. Source of truth for what the
|
|
307
|
+
* built manifest advertises this credential set requires. Memoized at
|
|
308
|
+
* construction so neither the build pipeline nor the runtime needs to walk
|
|
309
|
+
* the Zod schema again. */
|
|
310
|
+
credentialKeys;
|
|
311
|
+
/** Subset of `credentialKeys` declared as `z.optional()` / `z.default()` on
|
|
312
|
+
* `auth`. Used by the build pipeline to record which vault keys may be
|
|
313
|
+
* absent without failing manifest declaration. */
|
|
314
|
+
optionalCredentialKeys;
|
|
315
|
+
/** Sorted keys declared on `stored` (or `auth` when no `stored` schema is
|
|
316
|
+
* provided). This is what the runtime credential resolver actually fetches
|
|
317
|
+
* from the vault, since `stored` represents the persisted shape. */
|
|
318
|
+
storedCredentialKeys;
|
|
319
|
+
/** Subset of `storedCredentialKeys` declared as `z.optional()` /
|
|
320
|
+
* `z.default()`. Tells the runtime resolver which vault keys are allowed to
|
|
321
|
+
* be missing. */
|
|
322
|
+
optionalStoredCredentialKeys;
|
|
323
|
+
#manifest;
|
|
324
|
+
constructor(config) {
|
|
325
|
+
super();
|
|
326
|
+
const validatedConfig = validateConfig(credentialSetConfigSchema, (() => {
|
|
327
|
+
if (config.platformMetadata !== void 0) return config;
|
|
328
|
+
if (config.namespace === "keystroke") return config;
|
|
329
|
+
if (config.connection !== void 0) return {
|
|
330
|
+
...config,
|
|
331
|
+
platformMetadata: {
|
|
332
|
+
kind: CREDENTIAL_KINDS["user-connection"],
|
|
333
|
+
visibility: CREDENTIAL_VISIBILITIES["user-visible"]
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
return config;
|
|
337
|
+
})());
|
|
338
|
+
const hasStored = validatedConfig.stored !== void 0;
|
|
339
|
+
const hasResolve = validatedConfig.resolve !== void 0;
|
|
340
|
+
const hasResolveAtPlatform = validatedConfig.resolveAtPlatform !== void 0;
|
|
341
|
+
if (hasResolve && hasResolveAtPlatform) throw new Error(`CredentialSet "${validatedConfig.id}": "resolve" and "resolveAtPlatform" are mutually exclusive.`);
|
|
342
|
+
if ((hasResolve || hasResolveAtPlatform) && !hasStored) throw new Error(`CredentialSet "${validatedConfig.id}": "resolve" / "resolveAtPlatform" require "stored".`);
|
|
343
|
+
if (hasStored && !hasResolve && !hasResolveAtPlatform) throw new Error(`CredentialSet "${validatedConfig.id}": "stored" requires either "resolve" or "resolveAtPlatform".`);
|
|
344
|
+
if (validatedConfig.platformEnvAllowlist !== void 0 && validatedConfig.platformEnvAllowlist.length > 0 && !hasResolveAtPlatform) throw new Error(`CredentialSet "${validatedConfig.id}": "platformEnvAllowlist" requires "resolveAtPlatform".`);
|
|
345
|
+
this.id = validatedConfig.id;
|
|
346
|
+
this.namespace = validatedConfig.namespace;
|
|
347
|
+
this.resolvedCredentialSetId = this.namespace ? `${this.namespace}:${this.id}` : this.id;
|
|
348
|
+
registerCredentialSet({
|
|
349
|
+
manifestId: this.resolvedCredentialSetId,
|
|
350
|
+
fingerprint: fingerprintAuthShape(validatedConfig.auth, validatedConfig.stored),
|
|
351
|
+
sourceHint: captureStackOrigin()
|
|
352
|
+
});
|
|
353
|
+
this.name = validatedConfig.name ?? validatedConfig.id;
|
|
354
|
+
this.description = validatedConfig.description;
|
|
355
|
+
this.auth = validatedConfig.auth;
|
|
356
|
+
this.stored = validatedConfig.stored;
|
|
357
|
+
this.resolve = validatedConfig.resolve;
|
|
358
|
+
this.resolveCacheMs = hasResolve && typeof validatedConfig.resolveCacheMs === "number" ? validatedConfig.resolveCacheMs : 0;
|
|
359
|
+
this.resolveAtPlatform = validatedConfig.resolveAtPlatform;
|
|
360
|
+
this.resolveLocation = hasResolve ? "sandbox" : hasResolveAtPlatform ? "platform" : "none";
|
|
361
|
+
this.platformEnvAllowlist = Object.freeze(validatedConfig.platformEnvAllowlist ? [...validatedConfig.platformEnvAllowlist] : []);
|
|
362
|
+
this.needsResolve = hasStored && (hasResolve || hasResolveAtPlatform);
|
|
363
|
+
this.platformMetadata = validatedConfig.platformMetadata;
|
|
364
|
+
this.proxy = validatedConfig.proxy;
|
|
365
|
+
this.needsRawSecret = validatedConfig.needsRawSecret;
|
|
366
|
+
this.onCredentialRevoked = validatedConfig.onCredentialRevoked;
|
|
367
|
+
this.connection = validatedConfig.connection;
|
|
368
|
+
if (this.onCredentialRevoked === "retry-once" && !this.resolve) warnRetryOnceWithoutResolve(this.resolvedCredentialSetId);
|
|
369
|
+
const authKeyMetadata = readZodObjectKeyMetadata(this.auth);
|
|
370
|
+
const storedKeyMetadata = this.stored ? readZodObjectKeyMetadata(this.stored) : authKeyMetadata;
|
|
371
|
+
this.credentialKeys = Object.freeze(authKeyMetadata.all);
|
|
372
|
+
this.optionalCredentialKeys = Object.freeze(authKeyMetadata.optional);
|
|
373
|
+
this.storedCredentialKeys = Object.freeze(storedKeyMetadata.all);
|
|
374
|
+
this.optionalStoredCredentialKeys = Object.freeze(storedKeyMetadata.optional);
|
|
375
|
+
if (this.connection?.kind === "oauth") {
|
|
376
|
+
assertDeclarativeVaultKeysAreKnown(validatedConfig.id, this.connection.vault, this.storedCredentialKeys);
|
|
377
|
+
assertOAuthClientSourceIsWellFormed(validatedConfig.id, this.connection);
|
|
378
|
+
}
|
|
379
|
+
this.#manifest = Object.freeze(CredentialSetManifestSchema.parse({
|
|
380
|
+
manifestVersion: 1,
|
|
381
|
+
type: "credentialSet",
|
|
382
|
+
id: this.id,
|
|
383
|
+
namespace: this.namespace,
|
|
384
|
+
resolvedCredentialSetId: this.resolvedCredentialSetId,
|
|
385
|
+
name: this.name,
|
|
386
|
+
auth: schemaToJsonSchema(this.auth),
|
|
387
|
+
...this.description ? { description: this.description } : {},
|
|
388
|
+
...this.stored ? { stored: schemaToJsonSchema(this.stored) } : {},
|
|
389
|
+
...this.needsResolve ? { needsResolve: true } : {},
|
|
390
|
+
...this.resolveCacheMs > 0 ? { resolveCacheMs: this.resolveCacheMs } : {},
|
|
391
|
+
...this.resolveLocation !== "none" ? { resolveLocation: this.resolveLocation } : {},
|
|
392
|
+
...this.platformEnvAllowlist.length > 0 ? { platformEnvAllowlist: [...this.platformEnvAllowlist] } : {},
|
|
393
|
+
...this.platformMetadata ? { platformMetadata: this.platformMetadata } : {},
|
|
394
|
+
...this.proxy ? { proxy: this.proxy } : {},
|
|
395
|
+
...this.needsRawSecret === true ? { needsRawSecret: true } : {},
|
|
396
|
+
...this.onCredentialRevoked ? { onCredentialRevoked: this.onCredentialRevoked } : {},
|
|
397
|
+
...this.connection ? { connection: serializeConnectionForManifest(this.connection) } : {}
|
|
398
|
+
}));
|
|
399
|
+
Object.freeze(this);
|
|
400
|
+
}
|
|
401
|
+
describe() {
|
|
402
|
+
return `CredentialSet "${this.name}" (${this.resolvedCredentialSetId})`;
|
|
403
|
+
}
|
|
404
|
+
toManifest() {
|
|
405
|
+
return this.#manifest;
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
/** Strip runtime hooks from the connection config before serializing to the
|
|
409
|
+
* manifest. Hooks are functions and not manifest-safe; the manifest captures
|
|
410
|
+
* only declarative metadata (kind, URLs, scopes, etc.).
|
|
411
|
+
*
|
|
412
|
+
* Declarative {@link Vault} mappings serialize as-is. Function-form vault
|
|
413
|
+
* mappings cannot be serialized (they are runtime closures); the serialized
|
|
414
|
+
* manifest records only the kind marker so the shape stays well-typed. */
|
|
415
|
+
function serializeConnectionForManifest(connection) {
|
|
416
|
+
if (connection.kind === "manual") return {
|
|
417
|
+
kind: "manual",
|
|
418
|
+
...connection.instructions ? { instructions: connection.instructions } : {}
|
|
419
|
+
};
|
|
420
|
+
if (connection.kind === "oauth") return {
|
|
421
|
+
kind: "oauth",
|
|
422
|
+
authUrl: connection.authUrl,
|
|
423
|
+
tokenUrl: connection.tokenUrl,
|
|
424
|
+
scopes: connection.scopes,
|
|
425
|
+
tokenType: connection.tokenType,
|
|
426
|
+
vault: serializeVaultForManifest(connection.vault),
|
|
427
|
+
...connection.revokeUrl !== void 0 ? { revokeUrl: connection.revokeUrl } : {},
|
|
428
|
+
...connection.pkce === true ? { pkce: true } : {},
|
|
429
|
+
...typeof connection.defaultExpiresInSeconds === "number" ? { defaultExpiresInSeconds: connection.defaultExpiresInSeconds } : {},
|
|
430
|
+
...connection.oauthClientSource ? { oauthClientSource: serializeOAuthClientSourceForManifest(connection.oauthClientSource) } : {}
|
|
431
|
+
};
|
|
432
|
+
if (connection.kind === "credentials-exchange") return {
|
|
433
|
+
kind: "credentials-exchange",
|
|
434
|
+
input: schemaToJsonSchema(connection.input),
|
|
435
|
+
...connection.instructions ? { instructions: connection.instructions } : {}
|
|
436
|
+
};
|
|
437
|
+
throw new Error(`Unknown connection kind: ${JSON.stringify(connection)}`);
|
|
438
|
+
}
|
|
439
|
+
/** Project the live {@link OAuthClientSource} into its manifest-safe form.
|
|
440
|
+
* The workspace variant substitutes the object reference with the
|
|
441
|
+
* referenced credential set's `resolvedCredentialSetId` so the manifest
|
|
442
|
+
* carries a stable, persistable id instead of a closure-backed object. */
|
|
443
|
+
function serializeOAuthClientSourceForManifest(source) {
|
|
444
|
+
if (source.kind === "keystroke-platform") return { kind: "keystroke-platform" };
|
|
445
|
+
return {
|
|
446
|
+
kind: "workspace-provider-app",
|
|
447
|
+
credentialSetId: source.credentialSet.resolvedCredentialSetId,
|
|
448
|
+
...source.keyMap ? { keyMap: source.keyMap } : {}
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
function serializeVaultForManifest(vault) {
|
|
452
|
+
if ("build" in vault) return {
|
|
453
|
+
kind: "function",
|
|
454
|
+
accessTokenKey: vault.accessTokenKey
|
|
455
|
+
};
|
|
456
|
+
return {
|
|
457
|
+
kind: "declarative",
|
|
458
|
+
accessToken: vault.accessToken,
|
|
459
|
+
...vault.instanceUrl !== void 0 ? { instanceUrl: vault.instanceUrl } : {},
|
|
460
|
+
...vault.raw !== void 0 ? { raw: { ...vault.raw } } : {}
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
/** Tracks credential-set ids that already emitted the `retry-once + no resolve`
|
|
464
|
+
* construction warning so repeated tree-shake re-registration in the same
|
|
465
|
+
* process does not spam the log. */
|
|
466
|
+
const warnedRetryOnceWithoutResolve = /* @__PURE__ */ new Set();
|
|
467
|
+
function warnRetryOnceWithoutResolve(resolvedCredentialSetId) {
|
|
468
|
+
if (warnedRetryOnceWithoutResolve.has(resolvedCredentialSetId)) return;
|
|
469
|
+
warnedRetryOnceWithoutResolve.add(resolvedCredentialSetId);
|
|
470
|
+
console.warn(`CredentialSet "${resolvedCredentialSetId}": onCredentialRevoked: 'retry-once' is set but no resolve is declared. The retry will be a no-op because re-resolving stored values would produce the same result.`);
|
|
471
|
+
}
|
|
472
|
+
/** Runtime safety net: the referenced `clientApp` for a
|
|
473
|
+
* `workspace-provider-app` `oauthClientSource` must declare both the
|
|
474
|
+
* clientId and clientSecret keys (either under the default names or via
|
|
475
|
+
* `keyMap` aliases). The `visibility: 'internal'` check happens earlier at
|
|
476
|
+
* the Zod refinement layer; this validator covers the deeper schema-shape
|
|
477
|
+
* check so authors catch mismatches at construction rather than at
|
|
478
|
+
* handshake time. */
|
|
479
|
+
function assertOAuthClientSourceIsWellFormed(credentialSetId, connection) {
|
|
480
|
+
const source = connection.oauthClientSource;
|
|
481
|
+
if (!source || source.kind !== "workspace-provider-app") return;
|
|
482
|
+
const clientIdKey = source.keyMap?.clientId ?? "clientId";
|
|
483
|
+
const clientSecretKey = source.keyMap?.clientSecret ?? "clientSecret";
|
|
484
|
+
const referenced = source.credentialSet;
|
|
485
|
+
const keys = new Set(referenced.credentialKeys);
|
|
486
|
+
const missing = [];
|
|
487
|
+
if (!keys.has(clientIdKey)) missing.push(`clientId key "${clientIdKey}"`);
|
|
488
|
+
if (!keys.has(clientSecretKey)) missing.push(`clientSecret key "${clientSecretKey}"`);
|
|
489
|
+
if (missing.length > 0) throw new Error(`CredentialSet "${credentialSetId}": oauthClientSource.credentialSet "${referenced.id}" does not declare ${missing.join(" or ")}. Adjust the referenced credential set's auth schema or pass an explicit keyMap.`);
|
|
490
|
+
}
|
|
491
|
+
/** Runtime safety net: when a caller constructs with a typed-erased shape
|
|
492
|
+
* (e.g. via `as never`), verify every declared vault slot still maps to a
|
|
493
|
+
* known stored/auth schema key. The static `CredentialVaultKeys` parameter on
|
|
494
|
+
* `CredentialSetConfig.connection` catches typos at the construction site;
|
|
495
|
+
* this runtime check catches the erased case. */
|
|
496
|
+
function assertDeclarativeVaultKeysAreKnown(credentialSetId, vault, knownKeys) {
|
|
497
|
+
if ("build" in vault) return;
|
|
498
|
+
const known = new Set(knownKeys);
|
|
499
|
+
const invalid = [];
|
|
500
|
+
if (!known.has(vault.accessToken)) invalid.push(`vault.accessToken="${vault.accessToken}"`);
|
|
501
|
+
if (vault.instanceUrl !== void 0 && !known.has(vault.instanceUrl)) invalid.push(`vault.instanceUrl="${vault.instanceUrl}"`);
|
|
502
|
+
if (vault.raw) {
|
|
503
|
+
for (const rawKey of Object.keys(vault.raw)) if (!known.has(rawKey)) invalid.push(`vault.raw.${rawKey}`);
|
|
504
|
+
}
|
|
505
|
+
if (invalid.length > 0) throw new Error(`CredentialSet "${credentialSetId}": OAuth vault references unknown credential keys (${invalid.join(", ")}). Valid keys are [${[...known].sort().join(", ")}].`);
|
|
506
|
+
}
|
|
507
|
+
//#endregion
|
|
508
|
+
//#region ../../packages/core/src/shared/credential-sets.ts
|
|
509
|
+
function cloneCredentialSets(credentialSets) {
|
|
510
|
+
return credentialSets ? [...credentialSets] : void 0;
|
|
511
|
+
}
|
|
512
|
+
function assertUniqueCredentialSetIds(credentialSets, ownerKind, ownerName) {
|
|
513
|
+
const seenCredentialSetIds = /* @__PURE__ */ new Set();
|
|
514
|
+
for (const credentialSet of credentialSets) {
|
|
515
|
+
if (seenCredentialSetIds.has(credentialSet.id)) throw new Error(`${ownerKind} "${ownerName}" declares duplicate credential set id "${credentialSet.id}".`);
|
|
516
|
+
seenCredentialSetIds.add(credentialSet.id);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
//#endregion
|
|
520
|
+
//#region ../../packages/core/src/operation/nesting-guard.ts
|
|
521
|
+
const NESTING_GUARD_KEY = "__ks_operation_nesting_guard__";
|
|
522
|
+
function getStorage() {
|
|
523
|
+
const g = globalThis;
|
|
524
|
+
if (!g[NESTING_GUARD_KEY]) g[NESTING_GUARD_KEY] = new AsyncLocalStorage();
|
|
525
|
+
return g[NESTING_GUARD_KEY];
|
|
526
|
+
}
|
|
527
|
+
function getActiveOperationRun() {
|
|
528
|
+
return getStorage().getStore()?.operationName;
|
|
529
|
+
}
|
|
530
|
+
function runWithOperationScope(operationName, fn) {
|
|
531
|
+
return getStorage().run({ operationName }, fn);
|
|
532
|
+
}
|
|
533
|
+
//#endregion
|
|
534
|
+
//#region ../../packages/core/src/operation/schemas.ts
|
|
535
|
+
const credentialSetInstanceSchema = createStructuralSchema([
|
|
536
|
+
"id",
|
|
537
|
+
"auth",
|
|
538
|
+
"needsResolve"
|
|
539
|
+
], "a CredentialSet instance");
|
|
540
|
+
const operationConfigSchema = z.object({
|
|
541
|
+
credentialSets: z.array(credentialSetInstanceSchema).optional(),
|
|
542
|
+
description: descriptionString("Operation description"),
|
|
543
|
+
id: trimmedNonEmptyString("Operation id"),
|
|
544
|
+
input: anyZodSchemaSchema,
|
|
545
|
+
name: trimmedNonEmptyString("Operation name"),
|
|
546
|
+
needsApproval: z.boolean().optional(),
|
|
547
|
+
output: anyZodSchemaSchema,
|
|
548
|
+
requiredOAuthScopes: z.array(z.string()).optional(),
|
|
549
|
+
retries: RetryConfigSchema.optional(),
|
|
550
|
+
run: z.function(),
|
|
551
|
+
tags: z.array(z.string()).optional(),
|
|
552
|
+
timeout: DurationSchema.optional(),
|
|
553
|
+
maxDurationMs: z.number().int().positive().optional(),
|
|
554
|
+
workflowGlobals: anyZodSchemaSchema.optional()
|
|
555
|
+
});
|
|
556
|
+
const OperationManifestSchema = z.object({
|
|
557
|
+
manifestVersion: z.literal(1),
|
|
558
|
+
type: z.literal("operation"),
|
|
559
|
+
name: trimmedNonEmptyString("Operation name"),
|
|
560
|
+
id: trimmedNonEmptyString("Operation id"),
|
|
561
|
+
description: descriptionString("Operation description"),
|
|
562
|
+
credentialSets: z.array(CredentialSetManifestSchema),
|
|
563
|
+
input: jsonSchemaObject,
|
|
564
|
+
output: jsonSchemaObject,
|
|
565
|
+
timeout: DurationSchema.optional(),
|
|
566
|
+
tags: z.array(z.string()).optional(),
|
|
567
|
+
retries: RetryConfigSchema.optional(),
|
|
568
|
+
needsApproval: z.boolean().optional(),
|
|
569
|
+
requiredOAuthScopes: z.array(z.string()).optional(),
|
|
570
|
+
maxDurationMs: z.number().int().positive().optional(),
|
|
571
|
+
workflowGlobals: jsonSchemaObject.optional()
|
|
572
|
+
});
|
|
573
|
+
//#endregion
|
|
574
|
+
//#region ../../packages/core/src/operation/step-registry.ts
|
|
575
|
+
const REGISTRY_KEY = "__ks_step_registry";
|
|
576
|
+
function getRegistry() {
|
|
577
|
+
const g = globalThis;
|
|
578
|
+
if (!g[REGISTRY_KEY]) g[REGISTRY_KEY] = [];
|
|
579
|
+
return g[REGISTRY_KEY];
|
|
580
|
+
}
|
|
581
|
+
function registerStep(step) {
|
|
582
|
+
getRegistry().push(step);
|
|
583
|
+
}
|
|
584
|
+
//#endregion
|
|
585
|
+
//#region ../../packages/core/src/operation/Operation.ts
|
|
586
|
+
function createHostedOperationExecutionError(integrationId, detail) {
|
|
587
|
+
return /* @__PURE__ */ new Error(`Hosted integration "${integrationId}" cannot run locally in this environment. ${detail}`);
|
|
588
|
+
}
|
|
589
|
+
var Operation = class Operation extends Primitive {
|
|
590
|
+
kind = "operation";
|
|
591
|
+
credentialSets;
|
|
592
|
+
description;
|
|
593
|
+
id;
|
|
594
|
+
input;
|
|
595
|
+
name;
|
|
596
|
+
needsApproval;
|
|
597
|
+
output;
|
|
598
|
+
requiredOAuthScopes;
|
|
599
|
+
retries;
|
|
600
|
+
tags;
|
|
601
|
+
timeout;
|
|
602
|
+
/**
|
|
603
|
+
* Upper bound on the operation's expected duration, in milliseconds.
|
|
604
|
+
* See {@link OperationConfig.maxDurationMs}.
|
|
605
|
+
*/
|
|
606
|
+
maxDurationMs;
|
|
607
|
+
workflowGlobals;
|
|
608
|
+
#manifest;
|
|
609
|
+
#runImplementation;
|
|
610
|
+
#config;
|
|
611
|
+
constructor(config) {
|
|
612
|
+
super();
|
|
613
|
+
const validatedConfig = validateConfig(operationConfigSchema, {
|
|
614
|
+
...config,
|
|
615
|
+
credentialSets: cloneCredentialSets(config.credentialSets),
|
|
616
|
+
tags: config.tags ? [...config.tags] : void 0,
|
|
617
|
+
requiredOAuthScopes: config.requiredOAuthScopes ? [...config.requiredOAuthScopes] : void 0
|
|
618
|
+
});
|
|
619
|
+
this.#config = {
|
|
620
|
+
...config,
|
|
621
|
+
...validatedConfig,
|
|
622
|
+
credentialSets: validatedConfig.credentialSets ?? config.credentialSets ?? [],
|
|
623
|
+
timeout: validatedConfig.timeout,
|
|
624
|
+
input: validatedConfig.input,
|
|
625
|
+
output: validatedConfig.output,
|
|
626
|
+
run: config.run,
|
|
627
|
+
workflowGlobals: validatedConfig.workflowGlobals
|
|
628
|
+
};
|
|
629
|
+
this.credentialSets = this.#config.credentialSets ?? [];
|
|
630
|
+
assertUniqueCredentialSetIds(this.credentialSets, "Operation", this.#config.name);
|
|
631
|
+
this.description = validatedConfig.description;
|
|
632
|
+
this.id = validatedConfig.id;
|
|
633
|
+
this.input = this.#config.input;
|
|
634
|
+
this.name = validatedConfig.name;
|
|
635
|
+
this.needsApproval = validatedConfig.needsApproval;
|
|
636
|
+
this.output = this.#config.output;
|
|
637
|
+
this.requiredOAuthScopes = validatedConfig.requiredOAuthScopes ? [...validatedConfig.requiredOAuthScopes] : void 0;
|
|
638
|
+
this.retries = validatedConfig.retries;
|
|
639
|
+
this.tags = [...validatedConfig.tags ?? []];
|
|
640
|
+
this.timeout = validatedConfig.timeout;
|
|
641
|
+
this.maxDurationMs = validatedConfig.maxDurationMs;
|
|
642
|
+
this.workflowGlobals = this.#config.workflowGlobals;
|
|
643
|
+
this.#runImplementation = this.#config.run;
|
|
644
|
+
registerStep(this);
|
|
645
|
+
this.#manifest = Object.freeze(OperationManifestSchema.parse({
|
|
646
|
+
manifestVersion: 1,
|
|
647
|
+
type: "operation",
|
|
648
|
+
name: this.name,
|
|
649
|
+
id: this.id,
|
|
650
|
+
description: this.description,
|
|
651
|
+
credentialSets: this.credentialSets.map((cs) => cs.toManifest()),
|
|
652
|
+
input: schemaToJsonSchema(this.input),
|
|
653
|
+
output: schemaToJsonSchema(this.output),
|
|
654
|
+
tags: [...this.tags],
|
|
655
|
+
...this.timeout ? { timeout: this.timeout } : {},
|
|
656
|
+
...this.retries ? { retries: this.retries } : {},
|
|
657
|
+
...typeof this.maxDurationMs === "number" ? { maxDurationMs: this.maxDurationMs } : {},
|
|
658
|
+
...this.needsApproval !== void 0 ? { needsApproval: this.needsApproval } : {},
|
|
659
|
+
...this.requiredOAuthScopes?.length ? { requiredOAuthScopes: [...this.requiredOAuthScopes] } : {},
|
|
660
|
+
...this.workflowGlobals ? { workflowGlobals: schemaToJsonSchema(this.workflowGlobals) } : {}
|
|
661
|
+
}));
|
|
662
|
+
Object.freeze(this);
|
|
663
|
+
}
|
|
664
|
+
withTimeout(duration) {
|
|
665
|
+
return new Operation({
|
|
666
|
+
...this.#config,
|
|
667
|
+
timeout: duration
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
retry(policy) {
|
|
671
|
+
return new Operation({
|
|
672
|
+
...this.#config,
|
|
673
|
+
retries: policy
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
configure(config) {
|
|
677
|
+
return new Operation({
|
|
678
|
+
...this.#config,
|
|
679
|
+
...config
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
getCredentialRequirements() {
|
|
683
|
+
return toDeclaredCredentialRequirements(this.credentialSets);
|
|
684
|
+
}
|
|
685
|
+
/** @internal Used by the flow graph builder for nesting detection. */
|
|
686
|
+
getRunFunctionSource() {
|
|
687
|
+
return this.#runImplementation.toString();
|
|
688
|
+
}
|
|
689
|
+
mapInput(schema, fn) {
|
|
690
|
+
const originalRun = this.#runImplementation;
|
|
691
|
+
return new Operation({
|
|
692
|
+
...this.#config,
|
|
693
|
+
input: schema,
|
|
694
|
+
run: async (input, ctx) => {
|
|
695
|
+
return originalRun(fn(input), ctx);
|
|
696
|
+
}
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
mapOutput(schema, fn) {
|
|
700
|
+
const originalRun = this.#runImplementation;
|
|
701
|
+
return new Operation({
|
|
702
|
+
...this.#config,
|
|
703
|
+
output: schema,
|
|
704
|
+
run: async (input, ctx) => {
|
|
705
|
+
return fn(await originalRun(input, ctx));
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
async run(input, ctx) {
|
|
710
|
+
const parsedInput = this.input.parse(input);
|
|
711
|
+
const interceptor = getActiveRuntimeCallInterceptor();
|
|
712
|
+
if (interceptor) {
|
|
713
|
+
const intercepted = await interceptor({
|
|
714
|
+
instance: this,
|
|
715
|
+
kind: "workflow-step",
|
|
716
|
+
name: this.name,
|
|
717
|
+
input: parsedInput,
|
|
718
|
+
outputSchema: this.output
|
|
719
|
+
});
|
|
720
|
+
return this.output.parse(intercepted);
|
|
721
|
+
}
|
|
722
|
+
if (!ctx) {
|
|
723
|
+
const workflowRuntime = getRegisteredRuntime();
|
|
724
|
+
if (workflowRuntime?.handleStep) {
|
|
725
|
+
const intercepted = await workflowRuntime.handleStep(this, parsedInput);
|
|
726
|
+
return this.output.parse(intercepted);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
const integrationMetadata = getOfficialIntegrationMetadata(this);
|
|
730
|
+
if (integrationMetadata?.hosted) {
|
|
731
|
+
const hostedActionExecutionPolicy = getHostedActionExecutionPolicy();
|
|
732
|
+
const dispatcher = getRegisteredHostedActionDispatcher();
|
|
733
|
+
if (!dispatcher) {
|
|
734
|
+
if (hostedActionExecutionPolicy === "strict") throw createHostedOperationExecutionError(integrationMetadata.integrationId, "Use `keystrokeTestPlugin()` in auto mode, run `keystroke auth`, and ensure the Keystroke dev server is running.");
|
|
735
|
+
} else {
|
|
736
|
+
const dispatchResult = await dispatcher.dispatch(this, integrationMetadata.integrationId, parsedInput);
|
|
737
|
+
if (dispatchResult.handled) return this.output.parse(dispatchResult.result);
|
|
738
|
+
if (hostedActionExecutionPolicy === "strict") throw createHostedOperationExecutionError(integrationMetadata.integrationId, "The hosted-action dispatcher declined execution. Hosted integrations must execute through the Keystroke dev server.");
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
const execute = async () => {
|
|
742
|
+
const parentOperation = getActiveOperationRun();
|
|
743
|
+
if (parentOperation) throw new Error(`Operation "${this.name}" was called inside the run function of "${parentOperation}". Steps and Operations cannot call other Operations inside their run function. Move the "${this.name}" call into the Workflow's run function, or use a plain async helper function instead of a Step.`);
|
|
744
|
+
return runWithOperationScope(this.name, async () => {
|
|
745
|
+
const result = await this.#runImplementation(parsedInput, await this.#resolveRuntimeContext(ctx));
|
|
746
|
+
return this.output.parse(result);
|
|
747
|
+
});
|
|
748
|
+
};
|
|
749
|
+
if (this.timeout) {
|
|
750
|
+
const ms = parseDurationToMs(this.timeout);
|
|
751
|
+
return Promise.race([execute(), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error(`Operation "${this.name}" timed out after ${ms}ms`)), ms))]);
|
|
752
|
+
}
|
|
753
|
+
return execute();
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Execute the step implementation directly, bypassing interceptors and
|
|
757
|
+
* runtime checks. Used by the inline step execution runtime to avoid
|
|
758
|
+
* recursion through handleStep.
|
|
759
|
+
* @internal
|
|
760
|
+
*/
|
|
761
|
+
async executeDirectly(input, ctx) {
|
|
762
|
+
const parsedInput = this.input.parse(input);
|
|
763
|
+
const result = await this.#runImplementation(parsedInput, await this.#resolveRuntimeContext(ctx));
|
|
764
|
+
return this.output.parse(result);
|
|
765
|
+
}
|
|
766
|
+
describe() {
|
|
767
|
+
return `Operation "${this.name}"`;
|
|
768
|
+
}
|
|
769
|
+
toManifest() {
|
|
770
|
+
return this.#manifest;
|
|
771
|
+
}
|
|
772
|
+
#createImplicitRuntimeContext() {
|
|
773
|
+
return {
|
|
774
|
+
credentials: {},
|
|
775
|
+
workflowGlobals: void 0
|
|
776
|
+
};
|
|
777
|
+
}
|
|
778
|
+
#normalizeRuntimeContext(ctx) {
|
|
779
|
+
const tracing = ctx;
|
|
780
|
+
return {
|
|
781
|
+
attempt: ctx.attempt,
|
|
782
|
+
credentials: ctx.credentials ?? {},
|
|
783
|
+
maxAttempts: ctx.maxAttempts,
|
|
784
|
+
stepId: ctx.stepId,
|
|
785
|
+
toolCallId: tracing.toolCallId,
|
|
786
|
+
traceparent: tracing.traceparent,
|
|
787
|
+
tracestate: tracing.tracestate,
|
|
788
|
+
workflowGlobals: ctx.workflowGlobals
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
async #resolveRuntimeContext(ctx) {
|
|
792
|
+
const runtimeContext = ctx ?? getRegisteredOperationContext(this);
|
|
793
|
+
if (runtimeContext) {
|
|
794
|
+
const normalizedContext = this.#normalizeRuntimeContext(runtimeContext);
|
|
795
|
+
return this.#validateRuntimeContext(await this.#resolveMissingCredentials(normalizedContext));
|
|
796
|
+
}
|
|
797
|
+
if (this.credentialSets.length === 0 && !this.workflowGlobals) return this.#createImplicitRuntimeContext();
|
|
798
|
+
throw new Error(`Operation "${this.name}" was executed without a runtime context. Pass one explicitly to .run(input, ctx), or use keystrokeTestPlugin() from "@keystrokehq/core/vitest" in Vitest.`);
|
|
799
|
+
}
|
|
800
|
+
async #resolveMissingCredentials(ctx) {
|
|
801
|
+
if (this.credentialSets.map((credentialSet) => credentialSet.id).filter((credentialSetId) => ctx.credentials[credentialSetId] === void 0).length === 0) return ctx;
|
|
802
|
+
const resolvedCredentials = await resolveRegisteredOperationCredentials(this, ctx);
|
|
803
|
+
if (!resolvedCredentials) return ctx;
|
|
804
|
+
return {
|
|
805
|
+
...ctx,
|
|
806
|
+
credentials: {
|
|
807
|
+
...resolvedCredentials,
|
|
808
|
+
...ctx.credentials
|
|
809
|
+
}
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
#validateRuntimeContext(ctx) {
|
|
813
|
+
const validatedCredentials = {};
|
|
814
|
+
for (const credentialSet of this.credentialSets) {
|
|
815
|
+
const credentialId = credentialSet.id;
|
|
816
|
+
const rawCredential = ctx.credentials[credentialId];
|
|
817
|
+
validatedCredentials[credentialSet.id] = credentialSet.auth.parse(rawCredential);
|
|
818
|
+
}
|
|
819
|
+
return {
|
|
820
|
+
attempt: ctx.attempt,
|
|
821
|
+
credentials: validatedCredentials,
|
|
822
|
+
maxAttempts: ctx.maxAttempts,
|
|
823
|
+
stepId: ctx.stepId,
|
|
824
|
+
...ctx.toolCallId !== void 0 ? { toolCallId: ctx.toolCallId } : {},
|
|
825
|
+
...ctx.traceparent !== void 0 ? { traceparent: ctx.traceparent } : {},
|
|
826
|
+
...ctx.tracestate !== void 0 ? { tracestate: ctx.tracestate } : {},
|
|
827
|
+
workflowGlobals: this.workflowGlobals ? this.workflowGlobals.parse(ctx.workflowGlobals) : ctx.workflowGlobals
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
};
|
|
831
|
+
//#endregion
|
|
832
|
+
//#region ../../packages/core/src/errors/credential-revoked-error.ts
|
|
24
833
|
/**
|
|
25
834
|
* Thrown by integration client wrappers when a provider returns 401/403,
|
|
26
835
|
* indicating the stored credentials have been revoked or expired.
|
|
@@ -45538,7 +46347,7 @@ const gustoBundle = defineOfficialIntegration({
|
|
|
45538
46347
|
});
|
|
45539
46348
|
gustoBundle.connection;
|
|
45540
46349
|
//#endregion
|
|
45541
|
-
//#region ../../packages/integrations/integration-hubspot/dist/integration-
|
|
46350
|
+
//#region ../../packages/integrations/integration-hubspot/dist/integration-C4wYr0hZ.mjs
|
|
45542
46351
|
/**
|
|
45543
46352
|
* Internal credential set for the Keystroke-managed HubSpot OAuth app.
|
|
45544
46353
|
* Used for webhook signature verification on inbound webhooks.
|
|
@@ -54244,7 +55053,7 @@ const linearAppCredentialSet = new CredentialSet({
|
|
|
54244
55053
|
});
|
|
54245
55054
|
z.string().optional(), z.string().optional(), z.string().optional();
|
|
54246
55055
|
//#endregion
|
|
54247
|
-
//#region ../../packages/
|
|
55056
|
+
//#region ../../packages/core/src/shared/create-error-normalizing-proxy.ts
|
|
54248
55057
|
function isThenable$1(value) {
|
|
54249
55058
|
return !!value && typeof value === "object" && "then" in value && typeof value.then === "function";
|
|
54250
55059
|
}
|
|
@@ -139221,7 +140030,7 @@ var LinearClient = class extends LinearSdk {
|
|
|
139221
140030
|
}
|
|
139222
140031
|
};
|
|
139223
140032
|
//#endregion
|
|
139224
|
-
//#region ../../packages/integrations/integration-linear/dist/schemas-
|
|
140033
|
+
//#region ../../packages/integrations/integration-linear/dist/schemas-aVLy3iV7.mjs
|
|
139225
140034
|
/**
|
|
139226
140035
|
* Linear OAuth connection configuration.
|
|
139227
140036
|
*
|
|
@@ -141575,7 +142384,7 @@ z.string().optional(), z.string().optional(), z.string().optional();
|
|
|
141575
142384
|
*/
|
|
141576
142385
|
const SENTRY_DEFAULT_BASE_URL = "https://sentry.io";
|
|
141577
142386
|
//#endregion
|
|
141578
|
-
//#region ../../packages/integrations/integration-sentry/dist/integration-
|
|
142387
|
+
//#region ../../packages/integrations/integration-sentry/dist/integration-C7EDI5L4.mjs
|
|
141579
142388
|
const sentryOAuthConnection = {
|
|
141580
142389
|
kind: "oauth",
|
|
141581
142390
|
tokenType: "refreshable",
|
|
@@ -144409,7 +145218,7 @@ const slackAppCredentialSet = new CredentialSet({
|
|
|
144409
145218
|
});
|
|
144410
145219
|
z.string().optional(), z.string().optional(), z.string().optional(), z.string().optional();
|
|
144411
145220
|
//#endregion
|
|
144412
|
-
//#region ../../packages/integrations/integration-slack/dist/integration-
|
|
145221
|
+
//#region ../../packages/integrations/integration-slack/dist/integration-CTNuSaOh.mjs
|
|
144413
145222
|
/**
|
|
144414
145223
|
* Slack OAuth connection configuration.
|
|
144415
145224
|
*
|
|
@@ -144465,7 +145274,7 @@ const slackBundle = defineOfficialIntegration({
|
|
|
144465
145274
|
});
|
|
144466
145275
|
slackBundle.connection;
|
|
144467
145276
|
//#endregion
|
|
144468
|
-
//#region ../../packages/integrations/integration-snowflake/dist/integration-
|
|
145277
|
+
//#region ../../packages/integrations/integration-snowflake/dist/integration-lylQDjSA.mjs
|
|
144469
145278
|
/**
|
|
144470
145279
|
* Webhook credential sets for the Snowflake auto-ingest triggers.
|
|
144471
145280
|
*
|
|
@@ -150747,12 +151556,12 @@ zoomBundle.connection;
|
|
|
150747
151556
|
* Registry of Keystroke-managed (a.k.a. "official") platform providers.
|
|
150748
151557
|
*
|
|
150749
151558
|
* This registry is intentionally part of `@keystroke/official-integrations`
|
|
150750
|
-
* (not `@
|
|
151559
|
+
* (not `@keystrokehq/core`) because the providers it lists are platform
|
|
150751
151560
|
* concerns: which integrations Keystroke ships out of the box, which of them
|
|
150752
151561
|
* support a chat-style messaging gateway, and which messaging adapter id
|
|
150753
151562
|
* each one delivers through.
|
|
150754
151563
|
*
|
|
150755
|
-
* `@
|
|
151564
|
+
* `@keystrokehq/core` itself is provider-agnostic: its `MessagingGateway`
|
|
150756
151565
|
* and `ProviderTrigger` primitives accept any string `provider`, and
|
|
150757
151566
|
* integration packages narrow that string at their own boundary.
|
|
150758
151567
|
*/
|
|
@@ -151163,7 +151972,7 @@ async function verifyCredentialResolvable(params) {
|
|
|
151163
151972
|
* Enforces an 8-second platform timeout so a hung provider endpoint cannot
|
|
151164
151973
|
* stall the CLI indefinitely.
|
|
151165
151974
|
*
|
|
151166
|
-
* @see packages/
|
|
151975
|
+
* @see packages/core/src/credential-set/connection.ts — `ValidateManualHook`
|
|
151167
151976
|
*/
|
|
151168
151977
|
/**
|
|
151169
151978
|
* Run the manual `validate` hook for an official integration's credential
|