@sentry/junior 0.75.0 → 0.76.0

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 (100) hide show
  1. package/README.md +1 -1
  2. package/bin/junior.mjs +4 -66
  3. package/dist/agent-hooks-ZOE7RIED.js +37 -0
  4. package/dist/api-reference.d.ts +2 -0
  5. package/dist/app.js +317 -118
  6. package/dist/build/virtual-config.d.ts +2 -2
  7. package/dist/chat/agent-dispatch/runner.d.ts +2 -0
  8. package/dist/chat/config.d.ts +1 -0
  9. package/dist/chat/credentials/state-adapter-token-store.d.ts +2 -0
  10. package/dist/chat/credentials/user-token-store.d.ts +17 -12
  11. package/dist/chat/db.d.ts +8 -0
  12. package/dist/chat/mcp/auth-store.d.ts +2 -1
  13. package/dist/chat/mcp/oauth.d.ts +2 -1
  14. package/dist/chat/oauth-flow.d.ts +3 -1
  15. package/dist/chat/pi/client.d.ts +15 -7
  16. package/dist/chat/plugins/agent-hooks.d.ts +7 -0
  17. package/dist/chat/plugins/auth/oauth-request.d.ts +11 -7
  18. package/dist/chat/plugins/model.d.ts +9 -0
  19. package/dist/chat/plugins/prompt.d.ts +5 -0
  20. package/dist/chat/plugins/task-callback.d.ts +5 -0
  21. package/dist/chat/plugins/task-message.d.ts +23 -0
  22. package/dist/chat/plugins/task-queue.d.ts +5 -0
  23. package/dist/chat/plugins/task-runner.d.ts +12 -0
  24. package/dist/chat/plugins/task-signing.d.ts +31 -0
  25. package/dist/chat/prompt.d.ts +4 -0
  26. package/dist/chat/requester.d.ts +6 -5
  27. package/dist/chat/respond-helpers.d.ts +2 -0
  28. package/dist/chat/respond.d.ts +4 -2
  29. package/dist/chat/runtime/agent-continue-runner.d.ts +4 -0
  30. package/dist/chat/runtime/reply-executor.d.ts +5 -1
  31. package/dist/chat/runtime/slack-resume.d.ts +10 -2
  32. package/dist/chat/sentry.d.ts +1 -0
  33. package/dist/chat/services/mcp-auth-orchestration.d.ts +2 -1
  34. package/dist/chat/services/plugin-auth-orchestration.d.ts +2 -1
  35. package/dist/chat/services/subscribed-decision.d.ts +2 -2
  36. package/dist/chat/services/turn-session-record.d.ts +11 -7
  37. package/dist/chat/state/turn-session.d.ts +8 -5
  38. package/dist/chat/tools/agent-tools.d.ts +8 -1
  39. package/dist/chat/tools/slack/context.d.ts +2 -2
  40. package/dist/chat/tools/types.d.ts +4 -4
  41. package/dist/chat/vercel-queue-client.d.ts +3 -0
  42. package/dist/{chunk-C3AM4Z4J.js → chunk-2ECJXSVQ.js} +5 -5
  43. package/dist/{chunk-OJODNL2P.js → chunk-4SCWV7TJ.js} +2 -2
  44. package/dist/chunk-4UO6FK4G.js +64 -0
  45. package/dist/{chunk-BNJIEFQC.js → chunk-56TBVRJG.js} +2 -2
  46. package/dist/{chunk-OK4KKR7B.js → chunk-EJN6G5A2.js} +28 -12
  47. package/dist/{chunk-TQ74BATR.js → chunk-HHDUKWVG.js} +428 -111
  48. package/dist/{chunk-XJHDZUGD.js → chunk-JBASI5VV.js} +4 -4
  49. package/dist/chunk-KNFROR7R.js +127 -0
  50. package/dist/{chunk-VNTLUFTY.js → chunk-KOIMO7S3.js} +126 -87
  51. package/dist/chunk-MLKGABMK.js +9 -0
  52. package/dist/{chunk-NPVUAXUE.js → chunk-NFTMTIP3.js} +303 -33
  53. package/dist/chunk-NYKJ3KON.js +1082 -0
  54. package/dist/{chunk-SJHUF3DP.js → chunk-OJ53FYVG.js} +2 -10
  55. package/dist/{chunk-62FUNJYS.js → chunk-Q6XFTRV5.js} +54 -3
  56. package/dist/{chunk-UJ7OTHPO.js → chunk-R6Z5XWY3.js} +12 -670
  57. package/dist/chunk-RV5RYIJW.js +56 -0
  58. package/dist/{chunk-EE6PJWY4.js → chunk-SG5WAA7H.js} +7 -5
  59. package/dist/chunk-ST6YNAXG.js +54 -0
  60. package/dist/{chunk-FCZO7LAR.js → chunk-T77LUIX3.js} +139 -153
  61. package/dist/{chunk-EIYL7I4S.js → chunk-VALUBQ7R.js} +22 -30
  62. package/dist/{chunk-OZSPLAQ4.js → chunk-XBBC6W45.js} +1 -1
  63. package/dist/{chunk-ZNNTSPNF.js → chunk-Y5OFBCBZ.js} +1 -1
  64. package/dist/{chunk-74HO27II.js → chunk-Z4CIQ3EB.js} +5 -1
  65. package/dist/{chunk-2RWFUS5F.js → chunk-ZLMBNBUG.js} +101 -44
  66. package/dist/{chunk-JEELK46E.js → chunk-ZQB37HUX.js} +11 -11
  67. package/dist/cli/chat.js +52 -23
  68. package/dist/cli/check.js +7 -7
  69. package/dist/cli/env.js +4 -53
  70. package/dist/cli/init.js +6 -1
  71. package/dist/cli/main.js +84 -0
  72. package/dist/cli/plugins.js +244 -0
  73. package/dist/cli/run.js +5 -52
  74. package/dist/cli/snapshot-warmup.js +9 -9
  75. package/dist/cli/upgrade.js +167 -48
  76. package/dist/db-7A7PFRGL.js +17 -0
  77. package/dist/deployment.d.ts +1 -0
  78. package/dist/instrumentation.js +14 -18
  79. package/dist/nitro.d.ts +1 -1
  80. package/dist/nitro.js +43 -22
  81. package/dist/plugins-PZMDS7AT.js +15 -0
  82. package/dist/plugins.d.ts +4 -2
  83. package/dist/{registry-NLZFIW23.js → registry-OIPAJU2O.js} +6 -6
  84. package/dist/reporting.js +34 -26
  85. package/dist/{runner-LUQZ5G67.js → runner-KPLNHDCV.js} +76 -23
  86. package/dist/sentry-4CP5NNQ5.js +31 -0
  87. package/dist/validation-SLA6IGF7.js +15 -0
  88. package/dist/vercel.js +1 -1
  89. package/package.json +7 -6
  90. package/dist/agent-hooks-2HEB4C3Q.js +0 -33
  91. package/dist/chat/conversations/configured.d.ts +0 -7
  92. package/dist/chat/conversations/state.d.ts +0 -4
  93. package/dist/chat/plugins/db.d.ts +0 -31
  94. package/dist/chunk-2KG3PWR4.js +0 -17
  95. package/dist/chunk-D7NFH5GD.js +0 -570
  96. package/dist/chunk-MCMROINU.js +0 -12
  97. package/dist/chunk-WBZ4M5N5.js +0 -59
  98. package/dist/db-A3ILH67H.js +0 -20
  99. package/dist/plugins-OMJKLRJ2.js +0 -13
  100. package/dist/validation-VMCPP3YO.js +0 -15
@@ -1,16 +1,16 @@
1
+ import {
2
+ parseActorUserId
3
+ } from "./chunk-VALUBQ7R.js";
1
4
  import {
2
5
  discoverInstalledPluginPackageContent,
3
6
  normalizePluginPackageNames,
4
7
  pluginRoots
5
8
  } from "./chunk-Q3XNY442.js";
6
- import {
7
- parseActorUserId
8
- } from "./chunk-EIYL7I4S.js";
9
9
  import {
10
10
  logInfo,
11
11
  logWarn,
12
12
  setSpanAttributes
13
- } from "./chunk-OK4KKR7B.js";
13
+ } from "./chunk-EJN6G5A2.js";
14
14
 
15
15
  // src/chat/plugins/registry.ts
16
16
  import { readFileSync, readdirSync, statSync } from "fs";
@@ -1252,6 +1252,7 @@ function createApiHeadersBroker(manifest) {
1252
1252
  }
1253
1253
 
1254
1254
  // src/chat/plugins/auth/oauth-request.ts
1255
+ import { z as z3 } from "zod";
1255
1256
  var DEFAULT_TOKEN_CONTENT_TYPE = "application/x-www-form-urlencoded";
1256
1257
  function requireNonEmptyTokenField(data, field) {
1257
1258
  const value = data[field];
@@ -1260,6 +1261,19 @@ function requireNonEmptyTokenField(data, field) {
1260
1261
  }
1261
1262
  return value;
1262
1263
  }
1264
+ function requireTokenResponseObject(data) {
1265
+ if (!data || typeof data !== "object" || Array.isArray(data)) {
1266
+ throw new Error("OAuth token response must be an object");
1267
+ }
1268
+ return data;
1269
+ }
1270
+ var parsedOAuthTokenResponseSchema = z3.object({
1271
+ accessToken: z3.string().min(1),
1272
+ refreshToken: z3.string().min(1),
1273
+ expiresAt: z3.number().positive().optional(),
1274
+ refreshTokenExpiresAt: z3.number().positive().optional(),
1275
+ scope: z3.string().min(1).optional()
1276
+ }).strict();
1263
1277
  function contentTypeToBody(contentType, payload) {
1264
1278
  const mediaType = contentType.split(";", 1)[0]?.trim().toLowerCase();
1265
1279
  if (!mediaType || mediaType === DEFAULT_TOKEN_CONTENT_TYPE) {
@@ -1299,10 +1313,12 @@ function buildOAuthTokenRequest(input) {
1299
1313
  };
1300
1314
  }
1301
1315
  function parseOAuthTokenResponse(data, requestedScope, options) {
1302
- const accessToken = requireNonEmptyTokenField(data, "access_token");
1303
- const refreshToken = requireNonEmptyTokenField(data, "refresh_token");
1304
- const expiresIn = data.expires_in;
1305
- const responseScope = data.scope;
1316
+ const response = requireTokenResponseObject(data);
1317
+ const accessToken = requireNonEmptyTokenField(response, "access_token");
1318
+ const refreshToken = requireNonEmptyTokenField(response, "refresh_token");
1319
+ const expiresIn = response.expires_in;
1320
+ const refreshTokenExpiresIn = response.refresh_token_expires_in;
1321
+ const responseScope = response.scope;
1306
1322
  let scope;
1307
1323
  if (responseScope !== void 0) {
1308
1324
  if (typeof responseScope !== "string") {
@@ -1319,23 +1335,28 @@ function parseOAuthTokenResponse(data, requestedScope, options) {
1319
1335
  } else {
1320
1336
  scope = normalizeOAuthScope(requestedScope);
1321
1337
  }
1322
- if (expiresIn === void 0) {
1323
- return { accessToken, refreshToken, ...scope ? { scope } : {} };
1338
+ const result = { accessToken, refreshToken, ...scope ? { scope } : {} };
1339
+ if (expiresIn !== void 0) {
1340
+ if (typeof expiresIn !== "number" || !Number.isFinite(expiresIn) || expiresIn <= 0) {
1341
+ throw new Error("OAuth token response returned invalid expires_in");
1342
+ }
1343
+ result.expiresAt = Date.now() + expiresIn * 1e3;
1324
1344
  }
1325
- if (typeof expiresIn !== "number" || !Number.isFinite(expiresIn) || expiresIn <= 0) {
1326
- throw new Error("OAuth token response returned invalid expires_in");
1345
+ if (refreshTokenExpiresIn !== void 0) {
1346
+ if (typeof refreshTokenExpiresIn !== "number" || !Number.isFinite(refreshTokenExpiresIn) || refreshTokenExpiresIn <= 0) {
1347
+ throw new Error(
1348
+ "OAuth token response returned invalid refresh_token_expires_in"
1349
+ );
1350
+ }
1351
+ result.refreshTokenExpiresAt = Date.now() + refreshTokenExpiresIn * 1e3;
1327
1352
  }
1328
- return {
1329
- accessToken,
1330
- refreshToken,
1331
- expiresAt: Date.now() + expiresIn * 1e3,
1332
- ...scope ? { scope } : {}
1333
- };
1353
+ return parsedOAuthTokenResponseSchema.parse(result);
1334
1354
  }
1335
1355
 
1336
1356
  // src/chat/plugins/auth/oauth-bearer-broker.ts
1337
1357
  var MAX_LEASE_MS2 = 60 * 60 * 1e3;
1338
1358
  var REFRESH_BUFFER_MS = 5 * 60 * 1e3;
1359
+ var TOKEN_REFRESH_TIMEOUT_MS = 2e4;
1339
1360
  var OAuthRefreshRejectedError = class extends Error {
1340
1361
  constructor(message) {
1341
1362
  super(message);
@@ -1374,7 +1395,8 @@ async function refreshAccessToken(refreshToken, oauth, requestedScope) {
1374
1395
  const response = await fetch(oauth.tokenEndpoint, {
1375
1396
  method: "POST",
1376
1397
  headers: request.headers,
1377
- body: request.body
1398
+ body: request.body,
1399
+ signal: AbortSignal.timeout(TOKEN_REFRESH_TIMEOUT_MS)
1378
1400
  });
1379
1401
  if (!response.ok) {
1380
1402
  const errorCode = parseRefreshError(await response.text());
@@ -1395,6 +1417,12 @@ async function refreshAccessToken(refreshToken, oauth, requestedScope) {
1395
1417
  function getLeaseExpiry(expiresAt) {
1396
1418
  return expiresAt ? Math.min(expiresAt, Date.now() + MAX_LEASE_MS2) : Date.now() + MAX_LEASE_MS2;
1397
1419
  }
1420
+ function canUseStoredToken(stored) {
1421
+ return stored !== void 0 && (stored.expiresAt === void 0 || stored.expiresAt > Date.now());
1422
+ }
1423
+ function shouldRefreshStoredToken(stored) {
1424
+ return stored !== void 0 && stored.expiresAt !== void 0 && stored.expiresAt - Date.now() < REFRESH_BUFFER_MS;
1425
+ }
1398
1426
  function createOAuthBearerBroker(manifest, credentials, deps) {
1399
1427
  const provider = manifest.name;
1400
1428
  const { domains, apiHeaders, authTokenEnv } = credentials;
@@ -1442,33 +1470,62 @@ function createOAuthBearerBroker(manifest, credentials, deps) {
1442
1470
  `Your ${provider} connection needs to be reauthorized.`
1443
1471
  );
1444
1472
  }
1445
- const now = Date.now();
1446
- if (stored.expiresAt !== void 0 && stored.expiresAt - now < REFRESH_BUFFER_MS) {
1473
+ if (shouldRefreshStoredToken(stored)) {
1447
1474
  try {
1448
- const refreshed = await refreshAccessToken(
1449
- stored.refreshToken,
1450
- oauth,
1451
- stored.scope ?? oauth.scope
1452
- );
1453
- if (!hasRequiredOAuthScope(refreshed.scope, oauth.scope)) {
1454
- throw new CredentialUnavailableError(
1455
- provider,
1456
- `Your ${provider} connection needs to be reauthorized.`
1457
- );
1458
- }
1459
- const refreshedTokens = {
1460
- ...refreshed,
1461
- ...stored.account ? { account: stored.account } : {}
1462
- };
1463
- await deps.userTokenStore.set(
1475
+ return await deps.userTokenStore.withRefresh(
1464
1476
  userSubjectId,
1465
1477
  provider,
1466
- refreshedTokens
1467
- );
1468
- return buildLease(
1469
- refreshed.accessToken,
1470
- getLeaseExpiry(refreshed.expiresAt),
1471
- input.reason
1478
+ async () => {
1479
+ const latest = await deps.userTokenStore.get(
1480
+ userSubjectId,
1481
+ provider
1482
+ );
1483
+ if (latest && !hasRequiredOAuthScope(latest.scope, oauth.scope)) {
1484
+ throw new CredentialUnavailableError(
1485
+ provider,
1486
+ `Your ${provider} connection needs to be reauthorized.`
1487
+ );
1488
+ }
1489
+ if (!shouldRefreshStoredToken(latest) && canUseStoredToken(latest)) {
1490
+ return buildLease(
1491
+ latest.accessToken,
1492
+ getLeaseExpiry(latest.expiresAt),
1493
+ input.reason
1494
+ );
1495
+ }
1496
+ if (!latest) {
1497
+ throw new CredentialUnavailableError(
1498
+ provider,
1499
+ `No ${provider} credentials available.`
1500
+ );
1501
+ }
1502
+ const refreshed = await refreshAccessToken(
1503
+ latest.refreshToken,
1504
+ oauth,
1505
+ latest.scope ?? oauth.scope
1506
+ );
1507
+ if (!hasRequiredOAuthScope(refreshed.scope, oauth.scope)) {
1508
+ throw new CredentialUnavailableError(
1509
+ provider,
1510
+ `Your ${provider} connection needs to be reauthorized.`
1511
+ );
1512
+ }
1513
+ const refreshedTokens = {
1514
+ ...latest.refreshTokenExpiresAt ? { refreshTokenExpiresAt: latest.refreshTokenExpiresAt } : {},
1515
+ ...refreshed,
1516
+ ...latest.account ? { account: latest.account } : {}
1517
+ };
1518
+ await deps.userTokenStore.set(
1519
+ userSubjectId,
1520
+ provider,
1521
+ refreshedTokens
1522
+ );
1523
+ return buildLease(
1524
+ refreshed.accessToken,
1525
+ getLeaseExpiry(refreshed.expiresAt),
1526
+ input.reason
1527
+ );
1528
+ }
1472
1529
  );
1473
1530
  } catch (error) {
1474
1531
  if (error instanceof CredentialUnavailableError) {
@@ -1483,7 +1540,7 @@ function createOAuthBearerBroker(manifest, credentials, deps) {
1483
1540
  throw error;
1484
1541
  }
1485
1542
  }
1486
- if (stored.expiresAt === void 0 || stored.expiresAt > Date.now()) {
1543
+ if (canUseStoredToken(stored)) {
1487
1544
  return buildLease(
1488
1545
  stored.accessToken,
1489
1546
  getLeaseExpiry(stored.expiresAt),
@@ -1,22 +1,22 @@
1
- import {
2
- normalizeSlackConversationId
3
- } from "./chunk-62FUNJYS.js";
4
1
  import {
5
2
  getStateAdapter
6
- } from "./chunk-ZNNTSPNF.js";
3
+ } from "./chunk-Y5OFBCBZ.js";
4
+ import {
5
+ normalizeSlackConversationId
6
+ } from "./chunk-Q6XFTRV5.js";
7
7
  import {
8
8
  parseSlackThreadId
9
- } from "./chunk-FCZO7LAR.js";
9
+ } from "./chunk-T77LUIX3.js";
10
10
  import {
11
11
  parseStoredSlackRequester
12
- } from "./chunk-EIYL7I4S.js";
12
+ } from "./chunk-VALUBQ7R.js";
13
13
  import {
14
14
  isRecord,
15
15
  toOptionalNumber
16
- } from "./chunk-OK4KKR7B.js";
16
+ } from "./chunk-EJN6G5A2.js";
17
17
  import {
18
- sentry_exports
19
- } from "./chunk-SJHUF3DP.js";
18
+ getClient
19
+ } from "./chunk-ST6YNAXG.js";
20
20
 
21
21
  // src/handlers/health.ts
22
22
  function GET() {
@@ -44,7 +44,7 @@ function buildSentryWebBaseUrl(dsn) {
44
44
  return `${dsn.protocol}://${dsn.host}${port}${path}`;
45
45
  }
46
46
  function buildSentryConversationUrl(conversationId) {
47
- const client = sentry_exports.getClient();
47
+ const client = getClient();
48
48
  const dsn = client?.getDsn();
49
49
  if (!dsn?.host || !dsn.projectId) {
50
50
  return void 0;
@@ -63,7 +63,7 @@ function buildSentryConversationUrl(conversationId) {
63
63
  return `${buildSentryWebBaseUrl(dsn)}/organizations/${orgSlug}/${path}`;
64
64
  }
65
65
  function buildSentryTraceUrl(traceId) {
66
- const client = sentry_exports.getClient();
66
+ const client = getClient();
67
67
  const dsn = client?.getDsn();
68
68
  if (!dsn?.host || !dsn.projectId) {
69
69
  return void 0;
package/dist/cli/chat.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  loadAppPluginSet
3
3
  } from "../chunk-Y2CM7HXH.js";
4
- import "../chunk-2KG3PWR4.js";
4
+ import "../chunk-MLKGABMK.js";
5
5
 
6
6
  // src/cli/chat.ts
7
7
  import {
@@ -75,6 +75,29 @@ async function reportStatus(io, status) {
75
75
  throw new ChatOutputError(error);
76
76
  }
77
77
  }
78
+ function formatToolPayload(payload) {
79
+ if (payload && typeof payload === "object" && !Array.isArray(payload) && Object.keys(payload).length === 0) {
80
+ return "";
81
+ }
82
+ const rendered = JSON.stringify(payload);
83
+ if (rendered.length <= 500) {
84
+ return ` ${rendered}`;
85
+ }
86
+ return ` ${rendered.slice(0, 497)}...`;
87
+ }
88
+ async function reportToolResult(io, result) {
89
+ if (!result.ok) {
90
+ await reportStatus(
91
+ io,
92
+ `tool: ${result.toolName} error ${result.error ?? "Tool execution failed"}`
93
+ );
94
+ return;
95
+ }
96
+ await reportStatus(
97
+ io,
98
+ `tool: ${result.toolName} ok${formatToolPayload(result.result ?? {})}`
99
+ );
100
+ }
78
101
  function writeStream(stream, text) {
79
102
  return new Promise((resolve, reject) => {
80
103
  stream.write(text, (error) => {
@@ -98,7 +121,7 @@ async function loadLocalPluginSet() {
98
121
  async (moduleRef) => localPluginLoader.import(moduleRef.importPath)
99
122
  );
100
123
  }
101
- async function configureLocalChatPlugins() {
124
+ async function configureLocalChatPlugins(pluginSet) {
102
125
  const [
103
126
  pluginsModule,
104
127
  agentHooksModule,
@@ -106,29 +129,29 @@ async function configureLocalChatPlugins() {
106
129
  validationModule,
107
130
  databaseModule
108
131
  ] = await Promise.all([
109
- import("../plugins-OMJKLRJ2.js"),
110
- import("../agent-hooks-2HEB4C3Q.js"),
111
- import("../registry-NLZFIW23.js"),
112
- import("../validation-VMCPP3YO.js"),
113
- import("../db-A3ILH67H.js")
132
+ import("../plugins-PZMDS7AT.js"),
133
+ import("../agent-hooks-ZOE7RIED.js"),
134
+ import("../registry-OIPAJU2O.js"),
135
+ import("../validation-SLA6IGF7.js"),
136
+ import("../db-7A7PFRGL.js")
114
137
  ]);
115
- const pluginSet = await loadLocalPluginSet();
116
- const plugins = pluginsModule.pluginHookRegistrationsFromPluginSet(pluginSet);
117
- const pluginConfig = pluginSet ? pluginsModule.pluginCatalogConfigFromPluginSet(pluginSet) : pluginsModule.pluginCatalogConfigFromEnv();
118
- const shouldValidatePluginCatalog = Boolean(pluginConfig) || Boolean(pluginSet?.registrations.length);
138
+ const resolvedPluginSet = pluginSet === void 0 ? await loadLocalPluginSet() : pluginSet ?? void 0;
139
+ const plugins = pluginsModule.pluginRuntimeRegistrationsFromPluginSet(resolvedPluginSet);
140
+ const pluginConfig = resolvedPluginSet ? pluginsModule.pluginCatalogConfigFromPluginSet(resolvedPluginSet) : pluginsModule.pluginCatalogConfigFromEnv();
141
+ const shouldValidatePluginCatalog = Boolean(pluginConfig) || Boolean(resolvedPluginSet?.registrations.length);
119
142
  agentHooksModule.validatePlugins(plugins);
120
143
  const previousPluginCatalogConfig = registryModule.setPluginCatalogConfig(pluginConfig);
121
144
  try {
122
145
  if (shouldValidatePluginCatalog) {
123
146
  registryModule.getPluginCatalogSignature();
124
147
  validationModule.validatePluginRegistrations(
125
- pluginSet?.registrations ?? []
148
+ resolvedPluginSet?.registrations ?? []
126
149
  );
127
150
  validationModule.validatePluginEgressCredentialHooks(
128
- pluginSet?.registrations ?? []
151
+ resolvedPluginSet?.registrations ?? []
129
152
  );
130
153
  }
131
- databaseModule.validatePluginDatabaseRequirements(plugins);
154
+ databaseModule.getDb();
132
155
  agentHooksModule.setPlugins(plugins);
133
156
  } catch (error) {
134
157
  registryModule.setPluginCatalogConfig(previousPluginCatalogConfig);
@@ -166,11 +189,11 @@ function newRunConversationId() {
166
189
  }
167
190
  return conversationId;
168
191
  }
169
- async function runPrompt(options, io) {
192
+ async function runPrompt(options, io, pluginSet) {
170
193
  defaultStateAdapterForLocalChat();
171
- await configureLocalChatPlugins();
194
+ await configureLocalChatPlugins(pluginSet);
172
195
  const conversationId = newRunConversationId();
173
- const { runLocalAgentTurn } = await import("../runner-LUQZ5G67.js");
196
+ const { runLocalAgentTurn } = await import("../runner-KPLNHDCV.js");
174
197
  const result = await runLocalAgentTurn(
175
198
  {
176
199
  conversationId,
@@ -182,16 +205,19 @@ async function runPrompt(options, io) {
182
205
  },
183
206
  onStatus: async (status) => {
184
207
  await reportStatus(io, status);
208
+ },
209
+ onToolResult: async (result2) => {
210
+ await reportToolResult(io, result2);
185
211
  }
186
212
  }
187
213
  );
188
214
  return result.outcome === "success" ? 0 : 1;
189
215
  }
190
- async function runInteractive(io) {
216
+ async function runInteractive(io, pluginSet) {
191
217
  defaultStateAdapterForLocalChat();
192
- await configureLocalChatPlugins();
218
+ await configureLocalChatPlugins(pluginSet);
193
219
  const conversationId = newRunConversationId();
194
- const { runLocalAgentTurn } = await import("../runner-LUQZ5G67.js");
220
+ const { runLocalAgentTurn } = await import("../runner-KPLNHDCV.js");
195
221
  const rl = readline.createInterface({
196
222
  input: io.input,
197
223
  output: io.output,
@@ -218,6 +244,9 @@ async function runInteractive(io) {
218
244
  },
219
245
  onStatus: async (status) => {
220
246
  await reportStatus(io, status);
247
+ },
248
+ onToolResult: async (result) => {
249
+ await reportToolResult(io, result);
221
250
  }
222
251
  }
223
252
  );
@@ -232,7 +261,7 @@ async function runInteractive(io) {
232
261
  rl.close();
233
262
  }
234
263
  }
235
- async function runChat(argv, io = DEFAULT_IO) {
264
+ async function runChat(argv, io = DEFAULT_IO, deps = {}) {
236
265
  const options = parseChatArgs(argv);
237
266
  if (!options) {
238
267
  await io.error(CHAT_USAGE);
@@ -240,9 +269,9 @@ async function runChat(argv, io = DEFAULT_IO) {
240
269
  }
241
270
  try {
242
271
  if (options.mode === "prompt") {
243
- return await runPrompt(options, io);
272
+ return await runPrompt(options, io, deps.pluginSet);
244
273
  }
245
- await runInteractive(io);
274
+ await runInteractive(io, deps.pluginSet);
246
275
  return 0;
247
276
  } catch (error) {
248
277
  await io.error(errorMessage(error));
package/dist/cli/check.js CHANGED
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  parseSkillFile
3
- } from "../chunk-OJODNL2P.js";
3
+ } from "../chunk-4SCWV7TJ.js";
4
4
  import {
5
5
  parseInlinePluginManifest,
6
6
  parsePluginManifest
7
- } from "../chunk-2RWFUS5F.js";
7
+ } from "../chunk-ZLMBNBUG.js";
8
+ import "../chunk-VALUBQ7R.js";
8
9
  import "../chunk-Q3XNY442.js";
9
- import "../chunk-EIYL7I4S.js";
10
- import "../chunk-MCMROINU.js";
11
- import "../chunk-OK4KKR7B.js";
10
+ import "../chunk-EJN6G5A2.js";
12
11
  import {
13
12
  JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE,
14
13
  JUNIOR_HEARTBEAT_ROUTE,
15
14
  LEGACY_JUNIOR_CONVERSATION_WORK_FUNCTION
16
- } from "../chunk-SJHUF3DP.js";
17
- import "../chunk-2KG3PWR4.js";
15
+ } from "../chunk-OJ53FYVG.js";
16
+ import "../chunk-ST6YNAXG.js";
17
+ import "../chunk-MLKGABMK.js";
18
18
 
19
19
  // src/cli/check.ts
20
20
  import fs from "fs/promises";
package/dist/cli/env.js CHANGED
@@ -1,56 +1,7 @@
1
- import "../chunk-2KG3PWR4.js";
2
-
3
- // src/cli/env.ts
4
- import fs from "fs";
5
- import path from "path";
6
- function envFileNames(nodeEnv) {
7
- return [
8
- `.env.${nodeEnv}.local`,
9
- ...nodeEnv === "test" ? [] : [".env.local"],
10
- `.env.${nodeEnv}`,
11
- ".env"
12
- ];
13
- }
14
- function hasEnvRootMarker(dir) {
15
- return fs.existsSync(path.join(dir, "package.json")) || fs.existsSync(path.join(dir, "pnpm-workspace.yaml"));
16
- }
17
- function resolveCliEnvRoots(cwd) {
18
- const roots = [];
19
- const seen = /* @__PURE__ */ new Set();
20
- const addRoot = (candidate) => {
21
- const resolved = path.resolve(candidate);
22
- if (seen.has(resolved)) {
23
- return;
24
- }
25
- seen.add(resolved);
26
- roots.push(resolved);
27
- };
28
- let current = path.resolve(cwd);
29
- addRoot(current);
30
- while (true) {
31
- if (hasEnvRootMarker(current)) {
32
- addRoot(current);
33
- }
34
- const parent = path.dirname(current);
35
- if (parent === current) {
36
- break;
37
- }
38
- current = parent;
39
- }
40
- return roots;
41
- }
42
- function loadCliEnvFiles(cwd = process.cwd()) {
43
- const nodeEnv = process.env.NODE_ENV ?? "development";
44
- for (const root of resolveCliEnvRoots(cwd)) {
45
- for (const envFile of envFileNames(nodeEnv)) {
46
- const absolutePath = path.join(root, envFile);
47
- if (!fs.existsSync(absolutePath)) {
48
- continue;
49
- }
50
- process.loadEnvFile(absolutePath);
51
- }
52
- }
53
- }
1
+ import {
2
+ loadCliEnvFiles
3
+ } from "../chunk-RV5RYIJW.js";
4
+ import "../chunk-MLKGABMK.js";
54
5
  export {
55
6
  loadCliEnvFiles
56
7
  };
package/dist/cli/init.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  juniorVercelConfig
3
3
  } from "../chunk-Y7X25LFY.js";
4
- import "../chunk-2KG3PWR4.js";
4
+ import "../chunk-MLKGABMK.js";
5
5
 
6
6
  // src/cli/init.ts
7
7
  import fs from "fs";
@@ -35,8 +35,10 @@ function writePluginsFile(targetDir) {
35
35
  fs.writeFileSync(
36
36
  path.join(targetDir, "plugins.ts"),
37
37
  `import { defineJuniorPlugins } from "@sentry/junior";
38
+ import { createMemoryPlugin } from "@sentry/junior-memory";
38
39
 
39
40
  export const plugins = defineJuniorPlugins([
41
+ createMemoryPlugin(),
40
42
  "@sentry/junior-maintenance",
41
43
  ]);
42
44
  `
@@ -144,6 +146,7 @@ async function runInit(dir, log = console.log) {
144
146
  },
145
147
  dependencies: {
146
148
  "@sentry/junior": "latest",
149
+ "@sentry/junior-memory": "latest",
147
150
  "@sentry/junior-maintenance": "latest",
148
151
  hono: "^4.12.0"
149
152
  },
@@ -205,6 +208,8 @@ JUNIOR_BOT_NAME=
205
208
  JUNIOR_SLASH_COMMAND=
206
209
  AI_MODEL=
207
210
  AI_FAST_MODEL=
211
+ AI_MEMORY_MODEL=
212
+ AI_EMBEDDING_MODEL=
208
213
  AI_VISION_MODEL=
209
214
  AI_WEB_SEARCH_MODEL=
210
215
  REDIS_URL=
@@ -0,0 +1,84 @@
1
+ import {
2
+ loadCliEnvFiles
3
+ } from "../chunk-RV5RYIJW.js";
4
+ import {
5
+ runCli
6
+ } from "../chunk-4UO6FK4G.js";
7
+ import "../chunk-MLKGABMK.js";
8
+
9
+ // src/cli/main.ts
10
+ import { pathToFileURL } from "url";
11
+ var SENTRY_FLUSH_TIMEOUT_MS = 2e3;
12
+ async function flushSentry() {
13
+ const mod = await import("../sentry-4CP5NNQ5.js");
14
+ await mod.flush(SENTRY_FLUSH_TIMEOUT_MS);
15
+ }
16
+ async function initSentry() {
17
+ const mod = await import("../instrumentation.js");
18
+ mod.initSentry();
19
+ }
20
+ async function runInit(dir) {
21
+ const mod = await import("./init.js");
22
+ await mod.runInit(dir);
23
+ }
24
+ async function runSnapshotCreate() {
25
+ const mod = await import("./snapshot-warmup.js");
26
+ await mod.runSnapshotCreate();
27
+ }
28
+ async function runCheck(dir) {
29
+ const mod = await import("./check.js");
30
+ await mod.runCheck(dir);
31
+ }
32
+ async function runUpgrade(pluginSet) {
33
+ const mod = await import("./upgrade.js");
34
+ await mod.runUpgrade(void 0, { pluginSet });
35
+ }
36
+ async function runChat(argv, pluginSet) {
37
+ const mod = await import("./chat.js");
38
+ return await mod.runChat(argv, void 0, { pluginSet });
39
+ }
40
+ function topLevelCommand(argv) {
41
+ const normalized = argv[0] === "--" ? argv.slice(1) : argv;
42
+ return normalized[0];
43
+ }
44
+ async function runMain(argv, options = {}) {
45
+ loadCliEnvFiles();
46
+ const instrument = options.instrument ?? true;
47
+ if (instrument) {
48
+ await initSentry();
49
+ }
50
+ const command = topLevelCommand(argv);
51
+ const cliPluginsModule = command && command !== "init" ? await import("./plugins.js") : void 0;
52
+ const pluginSet = cliPluginsModule ? await cliPluginsModule.loadCliPluginSet() ?? null : void 0;
53
+ const pluginCommands = cliPluginsModule ? await cliPluginsModule.loadCliPluginCommands(pluginSet) : void 0;
54
+ const exitCode = await runCli(argv, {
55
+ runChat: async (chatArgv) => await runChat(chatArgv, pluginSet),
56
+ runInit,
57
+ runSnapshotCreate,
58
+ runCheck,
59
+ runUpgrade: async () => await runUpgrade(pluginSet),
60
+ ...pluginCommands ? { runPluginCommand: pluginCommands.run } : {}
61
+ });
62
+ if (instrument) {
63
+ await flushSentry();
64
+ }
65
+ process.exit(exitCode);
66
+ }
67
+ function isDirectCliEntry() {
68
+ return Boolean(
69
+ process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href
70
+ );
71
+ }
72
+ if (isDirectCliEntry()) {
73
+ runMain(process.argv.slice(2)).catch((error) => {
74
+ void (async () => {
75
+ const message = error instanceof Error ? error.message : String(error);
76
+ console.error(`junior command failed: ${message}`);
77
+ await flushSentry();
78
+ process.exit(1);
79
+ })();
80
+ });
81
+ }
82
+ export {
83
+ runMain
84
+ };