@keystrokehq/keystroke 1.0.11 → 1.0.12

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 (44) hide show
  1. package/dist/action.cjs +1 -1
  2. package/dist/action.mjs +1 -1
  3. package/dist/agent.cjs +7 -5
  4. package/dist/agent.cjs.map +1 -1
  5. package/dist/agent.mjs +7 -5
  6. package/dist/agent.mjs.map +1 -1
  7. package/dist/app.cjs +1 -1
  8. package/dist/app.mjs +1 -1
  9. package/dist/client.cjs +1 -1
  10. package/dist/client.mjs +1 -1
  11. package/dist/credentials.cjs +1 -1
  12. package/dist/credentials.mjs +1 -1
  13. package/dist/{dist-HI6bM6LK.cjs → dist-C5UmW-zB.cjs} +13 -1
  14. package/dist/dist-C5UmW-zB.cjs.map +1 -0
  15. package/dist/{dist-CziP-YTK.mjs → dist-D53HZMV9.mjs} +166 -97
  16. package/dist/{dist-CziP-YTK.mjs.map → dist-D53HZMV9.mjs.map} +1 -1
  17. package/dist/{dist-CDz1FyR5.mjs → dist-DSbrc1sP.mjs} +3 -3
  18. package/dist/{dist-CDz1FyR5.mjs.map → dist-DSbrc1sP.mjs.map} +1 -1
  19. package/dist/{dist-DBHK70o1.cjs → dist-DpZL1LE1.cjs} +166 -97
  20. package/dist/dist-DpZL1LE1.cjs.map +1 -0
  21. package/dist/{dist-CppO7361.mjs → dist-DtejauR-.mjs} +8 -2
  22. package/dist/dist-DtejauR-.mjs.map +1 -0
  23. package/dist/{dist-DDxVzzAb.cjs → dist-Zh8nB_45.cjs} +3 -3
  24. package/dist/{dist-DDxVzzAb.cjs.map → dist-Zh8nB_45.cjs.map} +1 -1
  25. package/dist/index-BTz2OMAM.d.cts.map +1 -1
  26. package/dist/index-Cq2F2XdS.d.mts.map +1 -1
  27. package/dist/index-WT4ULMiw.d.cts.map +1 -1
  28. package/dist/index-WT4ULMiw.d.mts.map +1 -1
  29. package/dist/{mistral-D5gNPl_r.cjs → mistral-6XMKgah3.cjs} +2 -2
  30. package/dist/{mistral-D5gNPl_r.cjs.map → mistral-6XMKgah3.cjs.map} +1 -1
  31. package/dist/{mistral-wc8R8T2i.mjs → mistral-tahkZ8Hu.mjs} +2 -2
  32. package/dist/{mistral-wc8R8T2i.mjs.map → mistral-tahkZ8Hu.mjs.map} +1 -1
  33. package/dist/{sse-BDeUGz09.mjs → sse-CSbz_aIR.mjs} +2 -2
  34. package/dist/{sse-BDeUGz09.mjs.map → sse-CSbz_aIR.mjs.map} +1 -1
  35. package/dist/{sse-Axv1Rmj7.cjs → sse-PotOG2Pc.cjs} +2 -2
  36. package/dist/{sse-Axv1Rmj7.cjs.map → sse-PotOG2Pc.cjs.map} +1 -1
  37. package/dist/trigger.cjs +1 -1
  38. package/dist/trigger.mjs +1 -1
  39. package/dist/workflow.cjs +1 -1
  40. package/dist/workflow.mjs +1 -1
  41. package/package.json +1 -1
  42. package/dist/dist-CppO7361.mjs.map +0 -1
  43. package/dist/dist-DBHK70o1.cjs.map +0 -1
  44. package/dist/dist-HI6bM6LK.cjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { a as __toESM, i as __require, t as __commonJSMin } from "./chunk-D0VCBZRD.mjs";
2
- import { E as normalizeCredentialList, T as mcpEntityId } from "./dist-CppO7361.mjs";
2
+ import { D as normalizeCredentialList, E as mcpEntityId, x as buildConnectDeeplink } from "./dist-DtejauR-.mjs";
3
3
  import { AsyncLocalStorage } from "node:async_hooks";
4
4
  import "node:fs";
5
5
  import "node:path";
@@ -17248,7 +17248,7 @@ async function connectMcpServer(name, options) {
17248
17248
  }
17249
17249
  async function createTransport(url, transport, requestInit, fetchImpl) {
17250
17250
  if (transport === "sse") {
17251
- const { SSEClientTransport } = await import("./sse-BDeUGz09.mjs");
17251
+ const { SSEClientTransport } = await import("./sse-CSbz_aIR.mjs");
17252
17252
  return new SSEClientTransport(url, {
17253
17253
  requestInit,
17254
17254
  fetch: fetchImpl
@@ -17899,6 +17899,12 @@ function requireOrganizationScopeId() {
17899
17899
  function getDb() {
17900
17900
  return getDbFromContext();
17901
17901
  }
17902
+ async function selectOrganizationById(id) {
17903
+ return (await getDb().select().from(organizations).where(eq(organizations.id, id)).limit(1))[0];
17904
+ }
17905
+ async function selectProjectById(projectId) {
17906
+ return (await getDb().select().from(projects).where(eq(projects.id, projectId)).limit(1))[0];
17907
+ }
17902
17908
  new AsyncLocalStorage();
17903
17909
  function eqOrganizationScope(table) {
17904
17910
  return eq(table.organizationId, requireOrganizationScopeId());
@@ -18130,6 +18136,31 @@ async function readCredentialInstanceSecret(instanceId) {
18130
18136
  }
18131
18137
  //#endregion
18132
18138
  //#region ../credentials/dist/index.mjs
18139
+ function formatCredentialErrorMessage(error, connect) {
18140
+ switch (error.code) {
18141
+ case "missing_credentials":
18142
+ if (connect) {
18143
+ const connectUrl = buildConnectDeeplink({
18144
+ webUrl: connect.webUrl,
18145
+ orgSlug: connect.orgSlug,
18146
+ appSlug: error.key
18147
+ });
18148
+ return `This agent needs the \`${error.key}\` credential. Connect it here: ${connectUrl}`;
18149
+ }
18150
+ return `This agent needs the \`${error.key}\` credential. Run \`keystroke connect ${error.key}\` or \`keystroke credentials set ${error.key}\` to configure it.`;
18151
+ case "needs_selection":
18152
+ if (connect) {
18153
+ const connectUrl = buildConnectDeeplink({
18154
+ webUrl: connect.webUrl,
18155
+ orgSlug: connect.orgSlug,
18156
+ appSlug: error.key
18157
+ });
18158
+ return `Multiple \`${error.key}\` credentials are available. Pick one here: ${connectUrl}`;
18159
+ }
18160
+ return `Multiple \`${error.key}\` credentials are available. Pick one in the Keystroke dashboard before running this agent.`;
18161
+ case "oauth_not_configured": return error.message;
18162
+ }
18163
+ }
18133
18164
  var MissingCredentialsError = class extends Error {
18134
18165
  code = "missing_credentials";
18135
18166
  key;
@@ -18182,6 +18213,132 @@ function credentialScopeMatchesContext(scopeType, scopeId, context) {
18182
18213
  case "user": return scopeId === context.userId;
18183
18214
  }
18184
18215
  }
18216
+ function createLocalCredentialBackend(options = {}) {
18217
+ const { tokenRefresh } = options;
18218
+ return {
18219
+ async resolveApiKey(instanceId, schema) {
18220
+ const row = await selectCredentialInstanceById(instanceId);
18221
+ if (!row) throw new MissingCredentialsError({
18222
+ key: instanceId,
18223
+ chainAttempted: ["api_key"]
18224
+ });
18225
+ if (row.ciphertext) {
18226
+ const plaintext = decryptCredentialPayload(row.ciphertext);
18227
+ return schema.parse(JSON.parse(plaintext));
18228
+ }
18229
+ const secret = await readCredentialInstanceSecret(instanceId);
18230
+ if (secret) return schema.parse(JSON.parse(secret));
18231
+ throw new MissingCredentialsError({
18232
+ key: row.appSlug,
18233
+ chainAttempted: ["api_key"]
18234
+ });
18235
+ },
18236
+ async getOAuthAccessToken(connectionId) {
18237
+ const connection = await getDecryptedOAuthConnectionById(connectionId);
18238
+ if (!connection) throw new Error(`OAuth connection not found: ${connectionId}`);
18239
+ const app = await getDecryptedOAuthAppById(connection.appId);
18240
+ if (!app) throw new Error(`OAuth app not found for connection: ${connectionId}`);
18241
+ return { accessToken: await resolveOAuthAccessToken(connection, app, tokenRefresh) };
18242
+ }
18243
+ };
18244
+ }
18245
+ function materializeUrl(baseUrl, projectId) {
18246
+ return `${baseUrl}/internal/projects/${encodeURIComponent(projectId)}/credentials/materialize`;
18247
+ }
18248
+ function requireProjectScopeId() {
18249
+ const projectId = getBoundProjectScopeId();
18250
+ if (!projectId) throw new Error("Credential backend requires project scope");
18251
+ return projectId;
18252
+ }
18253
+ function createPlatformCredentialBackend(options) {
18254
+ const baseUrl = options.platformUrl.replace(/\/+$/, "");
18255
+ async function materialize(body) {
18256
+ const response = await fetch(materializeUrl(baseUrl, requireProjectScopeId()), {
18257
+ method: "POST",
18258
+ headers: {
18259
+ Authorization: `Bearer ${options.workerToken}`,
18260
+ "Content-Type": "application/json"
18261
+ },
18262
+ body: JSON.stringify(body)
18263
+ });
18264
+ if (!response.ok) {
18265
+ const payload = await response.json().catch(() => null);
18266
+ throw new Error(payload?.message ?? `Platform credential materialize failed (${response.status})`);
18267
+ }
18268
+ const payload = await response.json();
18269
+ if (payload.kind === "api_key") return { value: payload.value };
18270
+ return { accessToken: payload.accessToken };
18271
+ }
18272
+ return {
18273
+ async resolveApiKey(instanceId, schema) {
18274
+ const { value } = await materialize({
18275
+ kind: "api_key",
18276
+ instanceId
18277
+ });
18278
+ return schema.parse(value);
18279
+ },
18280
+ async getOAuthAccessToken(connectionId) {
18281
+ const { accessToken } = await materialize({
18282
+ kind: "oauth",
18283
+ connectionId
18284
+ });
18285
+ if (!accessToken) throw new Error(`Platform did not return an access token for connection: ${connectionId}`);
18286
+ return { accessToken };
18287
+ }
18288
+ };
18289
+ }
18290
+ /**
18291
+ * A hosted worker is identified by the platform connection it must route through:
18292
+ * `PLATFORM_URL` + `WORKER_INTERNAL_TOKEN`. Workers never hold the decryption key, so
18293
+ * they always materialize secrets over the platform internal API; everything else
18294
+ * (platform process, standalone CLI) resolves locally against its own database.
18295
+ *
18296
+ * Org workers share one platform backend; project id comes from async job scope at
18297
+ * resolve time, not from env.
18298
+ */
18299
+ function isWorkerRuntime(env = process.env) {
18300
+ return Boolean(env.WORKER_INTERNAL_TOKEN?.trim() && env.PLATFORM_URL?.trim());
18301
+ }
18302
+ function createCredentialBackend(options = {}) {
18303
+ if (isWorkerRuntime()) return createPlatformCredentialBackend({
18304
+ platformUrl: process.env.PLATFORM_URL.trim(),
18305
+ workerToken: process.env.WORKER_INTERNAL_TOKEN.trim()
18306
+ });
18307
+ return createLocalCredentialBackend(options);
18308
+ }
18309
+ /**
18310
+ * Web connect context (org slug + web URL) for the current project scope, or
18311
+ * `null` when unavailable — standalone, no bound project scope, or no
18312
+ * `PUBLIC_WEB_URL`. Org slug comes from the platform internal API on workers
18313
+ * (no decryption key, so no direct DB), otherwise the platform DB.
18314
+ */
18315
+ async function resolveAgentConnectContext() {
18316
+ const projectId = getBoundProjectScopeId();
18317
+ if (!projectId) return null;
18318
+ const webUrl = process.env.PUBLIC_WEB_URL?.trim();
18319
+ if (!webUrl) return null;
18320
+ const orgSlug = await resolveOrgSlug(projectId);
18321
+ if (!orgSlug) return null;
18322
+ return {
18323
+ orgSlug,
18324
+ webUrl
18325
+ };
18326
+ }
18327
+ async function resolveOrgSlug(projectId) {
18328
+ if (isWorkerRuntime()) return fetchOrgSlugFromPlatform(projectId);
18329
+ const project = await selectProjectById(projectId);
18330
+ if (!project) return null;
18331
+ return (await selectOrganizationById(project.organizationId))?.slug.trim() || null;
18332
+ }
18333
+ async function fetchOrgSlugFromPlatform(projectId) {
18334
+ const platformUrl = process.env.PLATFORM_URL?.trim();
18335
+ const workerToken = process.env.WORKER_INTERNAL_TOKEN?.trim();
18336
+ if (!platformUrl || !workerToken) return null;
18337
+ const baseUrl = platformUrl.replace(/\/+$/, "");
18338
+ const response = await fetch(`${baseUrl}/internal/projects/${encodeURIComponent(projectId)}/connect-context`, { headers: { Authorization: `Bearer ${workerToken}` } });
18339
+ if (!response.ok) return null;
18340
+ return (await response.json()).orgSlug?.trim() || null;
18341
+ }
18185
18342
  function captureCredentialToolErrors(tools) {
18186
18343
  let captured;
18187
18344
  return {
@@ -18194,7 +18351,12 @@ function captureCredentialToolErrors(tools) {
18194
18351
  try {
18195
18352
  return await execute(...args);
18196
18353
  } catch (error) {
18197
- if (isCredentialError(error)) captured = error;
18354
+ if (isCredentialError(error)) {
18355
+ captured = error;
18356
+ try {
18357
+ error.message = formatCredentialErrorMessage(error, await resolveAgentConnectContext() ?? void 0);
18358
+ } catch {}
18359
+ }
18198
18360
  throw error;
18199
18361
  }
18200
18362
  }
@@ -18307,99 +18469,6 @@ function buildCredentialRunContext(input) {
18307
18469
  }
18308
18470
  };
18309
18471
  }
18310
- function createLocalCredentialBackend(options = {}) {
18311
- const { tokenRefresh } = options;
18312
- return {
18313
- async resolveApiKey(instanceId, schema) {
18314
- const row = await selectCredentialInstanceById(instanceId);
18315
- if (!row) throw new MissingCredentialsError({
18316
- key: instanceId,
18317
- chainAttempted: ["api_key"]
18318
- });
18319
- if (row.ciphertext) {
18320
- const plaintext = decryptCredentialPayload(row.ciphertext);
18321
- return schema.parse(JSON.parse(plaintext));
18322
- }
18323
- const secret = await readCredentialInstanceSecret(instanceId);
18324
- if (secret) return schema.parse(JSON.parse(secret));
18325
- throw new MissingCredentialsError({
18326
- key: row.appSlug,
18327
- chainAttempted: ["api_key"]
18328
- });
18329
- },
18330
- async getOAuthAccessToken(connectionId) {
18331
- const connection = await getDecryptedOAuthConnectionById(connectionId);
18332
- if (!connection) throw new Error(`OAuth connection not found: ${connectionId}`);
18333
- const app = await getDecryptedOAuthAppById(connection.appId);
18334
- if (!app) throw new Error(`OAuth app not found for connection: ${connectionId}`);
18335
- return { accessToken: await resolveOAuthAccessToken(connection, app, tokenRefresh) };
18336
- }
18337
- };
18338
- }
18339
- function materializeUrl(baseUrl, projectId) {
18340
- return `${baseUrl}/internal/projects/${encodeURIComponent(projectId)}/credentials/materialize`;
18341
- }
18342
- function requireProjectScopeId() {
18343
- const projectId = getBoundProjectScopeId();
18344
- if (!projectId) throw new Error("Credential backend requires project scope");
18345
- return projectId;
18346
- }
18347
- function createPlatformCredentialBackend(options) {
18348
- const baseUrl = options.platformUrl.replace(/\/+$/, "");
18349
- async function materialize(body) {
18350
- const response = await fetch(materializeUrl(baseUrl, requireProjectScopeId()), {
18351
- method: "POST",
18352
- headers: {
18353
- Authorization: `Bearer ${options.workerToken}`,
18354
- "Content-Type": "application/json"
18355
- },
18356
- body: JSON.stringify(body)
18357
- });
18358
- if (!response.ok) {
18359
- const payload = await response.json().catch(() => null);
18360
- throw new Error(payload?.message ?? `Platform credential materialize failed (${response.status})`);
18361
- }
18362
- const payload = await response.json();
18363
- if (payload.kind === "api_key") return { value: payload.value };
18364
- return { accessToken: payload.accessToken };
18365
- }
18366
- return {
18367
- async resolveApiKey(instanceId, schema) {
18368
- const { value } = await materialize({
18369
- kind: "api_key",
18370
- instanceId
18371
- });
18372
- return schema.parse(value);
18373
- },
18374
- async getOAuthAccessToken(connectionId) {
18375
- const { accessToken } = await materialize({
18376
- kind: "oauth",
18377
- connectionId
18378
- });
18379
- if (!accessToken) throw new Error(`Platform did not return an access token for connection: ${connectionId}`);
18380
- return { accessToken };
18381
- }
18382
- };
18383
- }
18384
- /**
18385
- * A hosted worker is identified by the platform connection it must route through:
18386
- * `PLATFORM_URL` + `WORKER_INTERNAL_TOKEN`. Workers never hold the decryption key, so
18387
- * they always materialize secrets over the platform internal API; everything else
18388
- * (platform process, standalone CLI) resolves locally against its own database.
18389
- *
18390
- * Org workers share one platform backend; project id comes from async job scope at
18391
- * resolve time, not from env.
18392
- */
18393
- function isWorkerRuntime(env = process.env) {
18394
- return Boolean(env.WORKER_INTERNAL_TOKEN?.trim() && env.PLATFORM_URL?.trim());
18395
- }
18396
- function createCredentialBackend(options = {}) {
18397
- if (isWorkerRuntime()) return createPlatformCredentialBackend({
18398
- platformUrl: process.env.PLATFORM_URL.trim(),
18399
- workerToken: process.env.WORKER_INTERNAL_TOKEN.trim()
18400
- });
18401
- return createLocalCredentialBackend(options);
18402
- }
18403
18472
  function toSelectionOption(row) {
18404
18473
  return {
18405
18474
  id: row.id,
@@ -18711,4 +18780,4 @@ async function resolveActionCredentials(requirements, options) {
18711
18780
  //#endregion
18712
18781
  export { recordLlmUsageFromAssistantMessage as A, appendEvent as C, getProjectScopeId as D, getAgentByRoute as E, captureConsole as F, getTraceContext as I, logSystem as L, setSessionLiveMessage as M, setSessionTitle as N, getSession as O, touchSession as P, withSpan as R, addAgentSessionDuration as S, createSession as T, createFetchWithInit as _, resolveActionCredentials as a, JSONRPCMessageSchema as b, connectMcpDefinition as c, defineMcp as d, isMcp as f, extractWWWAuthenticateParams as g, auth as h, isCredentialError as i, resolveRunSourceFromTraceContext as j, listMessageEvents as k, connectMcpServer as l, UnauthorizedError as m, captureCredentialToolErrors as n, resolveMcpTools as o, createParser as p, createCredentialResolver as r, withCredentialAssignments as s, buildCredentialRunContext as t, connectMcpStdio as u, normalizeHeaders as v, clearLiveMessage as w, MESSAGE_EVENT_TYPE as x, zodToJsonSchema as y };
18713
18782
 
18714
- //# sourceMappingURL=dist-CziP-YTK.mjs.map
18783
+ //# sourceMappingURL=dist-D53HZMV9.mjs.map