@sentry/junior 0.118.0 → 0.120.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 (56) hide show
  1. package/dist/{agent-hooks-J2FB7XD6.js → agent-hooks-5DDPWRYO.js} +8 -8
  2. package/dist/api/conversations/detail.d.ts +17 -0
  3. package/dist/api/conversations/event-list.d.ts +17 -0
  4. package/dist/api/schema/conversation.d.ts +68 -0
  5. package/dist/api/schema.js +1 -1
  6. package/dist/api.js +103 -82
  7. package/dist/app.js +24 -24
  8. package/dist/build/copy-build-content.d.ts +2 -2
  9. package/dist/{catalog-runtime-UHHLU53I.js → catalog-runtime-5KR5XBMJ.js} +7 -7
  10. package/dist/chat/discovery.d.ts +2 -0
  11. package/dist/chat/mcp/tool-manager.d.ts +14 -1
  12. package/dist/chat/plugins/types.d.ts +3 -9
  13. package/dist/chat/plugins/user-pages.d.ts +2 -1
  14. package/dist/chat/slack/tools/canvas/api.d.ts +2 -9
  15. package/dist/chat/slack/tools/canvas/markdown.d.ts +9 -0
  16. package/dist/{chunk-GT2ZUALJ.js → chunk-24B5R6OU.js} +92 -6
  17. package/dist/{chunk-L72GDKSN.js → chunk-6WX5SPI3.js} +1 -1
  18. package/dist/{chunk-3N3FMCKN.js → chunk-ALAKN7LR.js} +1 -1
  19. package/dist/{chunk-MLZFK4KP.js → chunk-ALYQOZG7.js} +1 -1
  20. package/dist/{chunk-6BGUAOYP.js → chunk-BHXW734F.js} +13 -7
  21. package/dist/{chunk-4LPPH7Y6.js → chunk-DJDGDJDF.js} +4 -4
  22. package/dist/{chunk-HWUBBHLK.js → chunk-DMKHRBI6.js} +4 -3
  23. package/dist/{chunk-QWCF4RAC.js → chunk-DWOH57FW.js} +1 -1
  24. package/dist/{chunk-7GADTCNS.js → chunk-EIVE6GL4.js} +3 -3
  25. package/dist/{chunk-6K2QE2UI.js → chunk-ERYVNWNE.js} +250 -37
  26. package/dist/{chunk-UXLYAVYL.js → chunk-GNNV3UTY.js} +1 -1
  27. package/dist/chunk-H4HBKISO.js +417 -0
  28. package/dist/{chunk-FXOYURO4.js → chunk-HDFGNU5E.js} +1 -0
  29. package/dist/{chunk-PJPKHGLG.js → chunk-JQWP6V22.js} +4 -11
  30. package/dist/{chunk-KC5EE27Y.js → chunk-M243JMZH.js} +2 -2
  31. package/dist/{chunk-7SM3P4XR.js → chunk-O2ULQJWR.js} +82 -1
  32. package/dist/{chunk-B3IT5END.js → chunk-OOUNJNMR.js} +16 -152
  33. package/dist/{chunk-HN6LFYG3.js → chunk-Q3RL6A4E.js} +2 -2
  34. package/dist/{chunk-3MUSSFMP.js → chunk-QOQPPRFS.js} +221 -14
  35. package/dist/{chunk-S6R23MFB.js → chunk-TKUCRFNX.js} +12 -225
  36. package/dist/{chunk-PWRFTDTY.js → chunk-VURFJVFH.js} +2 -2
  37. package/dist/{chunk-3LGCVRBQ.js → chunk-XAI2HNAY.js} +9 -5
  38. package/dist/{chunk-4SOQPUF4.js → chunk-YEAOUT5W.js} +1 -1
  39. package/dist/cli/chat.js +24 -24
  40. package/dist/cli/check.js +8 -8
  41. package/dist/cli/init.js +2 -2
  42. package/dist/cli/plugins.js +13 -13
  43. package/dist/cli/snapshot-create.js +11 -11
  44. package/dist/cli/upgrade.js +8 -8
  45. package/dist/{db-PMRHFSYL.js → db-T4ZY64PB.js} +6 -6
  46. package/dist/{discovery-RMHYSRL7.js → discovery-GUFTFBTL.js} +3 -1
  47. package/dist/instrumentation.js +3 -3
  48. package/dist/nitro.js +24 -7
  49. package/dist/{oauth-callback-server-QJUC7S4X.js → oauth-callback-server-LQ6DFI26.js} +17 -17
  50. package/dist/{runner-PZMV6JQW.js → runner-D3ZU6TJH.js} +10 -10
  51. package/dist/{skills-W4JETYSV.js → skills-JMXY7LIY.js} +8 -8
  52. package/dist/{validation-IJLNHZSU.js → validation-OEPJS7JX.js} +8 -8
  53. package/dist/version.js +1 -1
  54. package/package.json +8 -7
  55. package/skills/jr-rpc/SKILL.md +40 -0
  56. package/dist/chunk-3V7OFJZC.js +0 -264
package/dist/app.js CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  appendAndEnqueueInboundMessage,
9
9
  beginConversationResume,
10
10
  buildAuthPauseResponse,
11
+ buildSlackOutputMessage,
11
12
  checkInConversationWork,
12
13
  clearConsumedConversationWake,
13
14
  clearExpiredConversationLease,
@@ -45,10 +46,11 @@ import {
45
46
  scheduleAgentContinue,
46
47
  sendSlackReply,
47
48
  shouldKeepProcessingReactionForToolInvocation,
49
+ splitSlackReplyText,
48
50
  startConversationWork,
49
51
  startSlackProcessingReaction,
50
52
  stripLeadingBotMention
51
- } from "./chunk-3MUSSFMP.js";
53
+ } from "./chunk-QOQPPRFS.js";
52
54
  import "./chunk-FA6POGLH.js";
53
55
  import {
54
56
  ConversationTurnLifecycleService,
@@ -63,13 +65,13 @@ import {
63
65
  processPluginTask,
64
66
  requireTurnFailureEventId,
65
67
  scheduleSessionCompletedPluginTasks
66
- } from "./chunk-6BGUAOYP.js";
68
+ } from "./chunk-BHXW734F.js";
67
69
  import {
68
70
  GET,
69
71
  conversationVisibilityFromSlackChannelType,
70
72
  resolveSlackChannelTypeFromMessage,
71
73
  resolveSlackConversationContext
72
- } from "./chunk-HN6LFYG3.js";
74
+ } from "./chunk-Q3RL6A4E.js";
73
75
  import "./chunk-4CODA7P5.js";
74
76
  import "./chunk-PE44LDDQ.js";
75
77
  import {
@@ -88,7 +90,7 @@ import {
88
90
  import {
89
91
  validatePluginEgressCredentialHooks,
90
92
  validatePluginRegistrations
91
- } from "./chunk-4SOQPUF4.js";
93
+ } from "./chunk-YEAOUT5W.js";
92
94
  import {
93
95
  defineJuniorPlugins,
94
96
  pluginCatalogConfigFromEnv,
@@ -121,20 +123,18 @@ import {
121
123
  setConfigDefaults,
122
124
  shouldEmitDevAgentTrace,
123
125
  shouldPropagateSandboxEgressTrace
124
- } from "./chunk-6K2QE2UI.js";
126
+ } from "./chunk-ERYVNWNE.js";
125
127
  import "./chunk-DIB4GX3G.js";
126
128
  import {
127
129
  RetryableDeliveryError,
128
- buildSlackOutputMessage,
129
130
  createUserTokenStore,
130
131
  deleteMcpAuthSessionsForUserProvider,
131
132
  deleteMcpServerSessionId,
132
133
  deleteMcpStoredOAuthCredentials,
133
134
  formatProviderLabel,
134
135
  postSlackMessage,
135
- splitSlackReplyText,
136
136
  startOAuthFlow
137
- } from "./chunk-S6R23MFB.js";
137
+ } from "./chunk-TKUCRFNX.js";
138
138
  import {
139
139
  ConversationTurnBoundaryError,
140
140
  CooperativeTurnYieldError,
@@ -188,10 +188,10 @@ import {
188
188
  trimTrailingAssistantMessages,
189
189
  updateConversationStats,
190
190
  upsertConversationMessage
191
- } from "./chunk-PJPKHGLG.js";
191
+ } from "./chunk-JQWP6V22.js";
192
192
  import "./chunk-HDSDCEPK.js";
193
- import "./chunk-4LPPH7Y6.js";
194
- import "./chunk-L72GDKSN.js";
193
+ import "./chunk-DJDGDJDF.js";
194
+ import "./chunk-6WX5SPI3.js";
195
195
  import "./chunk-MU6HHZEN.js";
196
196
  import "./chunk-PDO5BLNM.js";
197
197
  import "./chunk-UIE3R5XU.js";
@@ -216,7 +216,7 @@ import {
216
216
  validatePlugins,
217
217
  verifyScheduledTaskCredentialSubject,
218
218
  verifySlackDirectCredentialSubject
219
- } from "./chunk-GT2ZUALJ.js";
219
+ } from "./chunk-24B5R6OU.js";
220
220
  import {
221
221
  contextProvenance,
222
222
  createSlackDestination,
@@ -227,7 +227,7 @@ import {
227
227
  instructionProvenanceFor,
228
228
  requireSlackDestination,
229
229
  withConversationEventLock
230
- } from "./chunk-KC5EE27Y.js";
230
+ } from "./chunk-M243JMZH.js";
231
231
  import {
232
232
  juniorConversationEvents,
233
233
  juniorConversations
@@ -236,7 +236,7 @@ import {
236
236
  acquireActiveLock,
237
237
  getStateAdapter,
238
238
  sleep
239
- } from "./chunk-3N3FMCKN.js";
239
+ } from "./chunk-ALAKN7LR.js";
240
240
  import {
241
241
  STANDARD_MODEL_PROFILE,
242
242
  botConfig,
@@ -254,18 +254,18 @@ import {
254
254
  modelIdForProfile,
255
255
  setSlackReactionConfig,
256
256
  standardModelId
257
- } from "./chunk-PWRFTDTY.js";
257
+ } from "./chunk-VURFJVFH.js";
258
258
  import {
259
259
  juniorDestinations
260
260
  } from "./chunk-VFUK3X5B.js";
261
261
  import {
262
262
  parseSlackThreadId
263
- } from "./chunk-FXOYURO4.js";
264
- import "./chunk-7GADTCNS.js";
263
+ } from "./chunk-HDFGNU5E.js";
264
+ import "./chunk-EIVE6GL4.js";
265
265
  import {
266
266
  pluginCatalogRuntime
267
- } from "./chunk-UXLYAVYL.js";
268
- import "./chunk-3LGCVRBQ.js";
267
+ } from "./chunk-GNNV3UTY.js";
268
+ import "./chunk-XAI2HNAY.js";
269
269
  import {
270
270
  credentialSubjectSchema
271
271
  } from "./chunk-W3U3YQYI.js";
@@ -291,7 +291,7 @@ import {
291
291
  setTags,
292
292
  withContext,
293
293
  withSpan
294
- } from "./chunk-MLZFK4KP.js";
294
+ } from "./chunk-ALYQOZG7.js";
295
295
  import {
296
296
  toOptionalString
297
297
  } from "./chunk-OB42YVAE.js";
@@ -302,14 +302,14 @@ import {
302
302
  import {
303
303
  continueTrace
304
304
  } from "./chunk-6GWA276C.js";
305
- import "./chunk-B3IT5END.js";
306
- import "./chunk-3V7OFJZC.js";
305
+ import "./chunk-OOUNJNMR.js";
306
+ import "./chunk-H4HBKISO.js";
307
307
  import {
308
308
  JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE
309
- } from "./chunk-QWCF4RAC.js";
309
+ } from "./chunk-DWOH57FW.js";
310
310
  import {
311
311
  JUNIOR_VERSION
312
- } from "./chunk-HWUBBHLK.js";
312
+ } from "./chunk-DMKHRBI6.js";
313
313
  import "./chunk-MLKGABMK.js";
314
314
 
315
315
  // src/app.ts
@@ -1,5 +1,5 @@
1
- /** Copy app and declared plugin package content into the server output. */
2
- export declare function copyAppAndPluginContent(cwd: string, serverRoot: string, packageNames?: unknown): void;
1
+ /** Copy app, built-in skill, and declared plugin content into server output. */
2
+ export declare function copyRuntimeContent(cwd: string, serverRoot: string, packageNames?: unknown): void;
3
3
  /** Copy dashboard browser assets when core dashboard routes are enabled. */
4
4
  export declare function copyDashboardAssets(cwd: string, serverRoot: string): void;
5
5
  /** Copy extra file patterns into server output for files the bundler cannot trace. */
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-UXLYAVYL.js";
4
- import "./chunk-3LGCVRBQ.js";
3
+ } from "./chunk-GNNV3UTY.js";
4
+ import "./chunk-XAI2HNAY.js";
5
5
  import "./chunk-W3U3YQYI.js";
6
6
  import "./chunk-HZF5P5UN.js";
7
- import "./chunk-MLZFK4KP.js";
7
+ import "./chunk-ALYQOZG7.js";
8
8
  import "./chunk-OB42YVAE.js";
9
9
  import "./chunk-F3B2YJ76.js";
10
10
  import "./chunk-6GWA276C.js";
11
- import "./chunk-B3IT5END.js";
12
- import "./chunk-3V7OFJZC.js";
13
- import "./chunk-QWCF4RAC.js";
14
- import "./chunk-HWUBBHLK.js";
11
+ import "./chunk-OOUNJNMR.js";
12
+ import "./chunk-H4HBKISO.js";
13
+ import "./chunk-DWOH57FW.js";
14
+ import "./chunk-DMKHRBI6.js";
15
15
  import "./chunk-MLKGABMK.js";
16
16
  export {
17
17
  pluginCatalogRuntime
@@ -19,6 +19,8 @@ export interface ResolveHomeDirOptions {
19
19
  }
20
20
  /** Resolve the app home directory by scoring candidate `app/` directories. */
21
21
  export declare function resolveHomeDir(cwd?: string, options?: ResolveHomeDirOptions): string;
22
+ /** Return the built-in skills directory in source and packaged builds. */
23
+ export declare function builtInSkillsDir(): string;
22
24
  /** Return the data directory (same as homeDir). */
23
25
  export declare function dataDir(): string;
24
26
  /** Return the path to the SOUL.md file. */
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import type { ImageContent, TextContent } from "@earendil-works/pi-ai";
10
10
  import type { OAuthClientProvider } from "@modelcontextprotocol/sdk/client/auth.js";
11
- import type { ToolAnnotations } from "@sentry/junior-plugin-api";
11
+ import type { PluginMcpToolResult, ToolAnnotations } from "@sentry/junior-plugin-api";
12
12
  import type { ConversationPrivacy } from "@/chat/conversation-privacy";
13
13
  import type { SkillMetadata } from "@/chat/skills";
14
14
  import type { PluginDefinition } from "@/chat/plugins/types";
@@ -19,7 +19,15 @@ export interface McpToolManagerOptions {
19
19
  onAuthorizationRequired?: (provider: string, error: McpAuthorizationRequiredError) => Promise<boolean | void> | boolean | void;
20
20
  }
21
21
  export interface ManagedMcpToolResult {
22
+ /**
23
+ * Internal bridge for direct model calls, which need placeholder content
24
+ * while the wrapper boundary receives a content-free discriminated result.
25
+ */
26
+ authorizationPending?: boolean;
22
27
  content: Array<TextContent | ImageContent>;
28
+ /** Original provider content before model-visible result normalization. */
29
+ providerContent?: Array<TextContent | ImageContent>;
30
+ structuredContent?: unknown;
23
31
  }
24
32
  export interface ManagedMcpToolDescriptor {
25
33
  name: string;
@@ -62,6 +70,7 @@ export declare class McpToolManager {
62
70
  provider?: string;
63
71
  }): ManagedMcpToolDescriptor[];
64
72
  private filterListedTools;
73
+ private assertWrappedToolsAvailable;
65
74
  private getClient;
66
75
  private createClient;
67
76
  private toManagedTool;
@@ -70,6 +79,10 @@ export declare class McpToolManager {
70
79
  getResolvedActiveTools(options?: {
71
80
  provider?: string;
72
81
  }): ManagedMcpTool[];
82
+ /** Call one active provider tool declared for plugin-owned wrapping. */
83
+ callWrappedTool(provider: string, rawName: string, args: Record<string, unknown>, options?: {
84
+ toolCallId?: string;
85
+ }): Promise<PluginMcpToolResult>;
73
86
  private toToolDescriptor;
74
87
  }
75
88
  export {};
@@ -1,6 +1,6 @@
1
- import type { PluginRuntimeDependency, PluginRuntimePostinstallCommand } from "@sentry/junior-plugin-api";
1
+ import type { PluginMcpConfig, PluginRuntimeDependency, PluginRuntimePostinstallCommand } from "@sentry/junior-plugin-api";
2
2
  import type { UserTokenStore } from "@/chat/credentials/user-token-store";
3
- export type { PluginNpmRuntimeDependency, PluginRuntimeDependency, PluginRuntimePostinstallCommand, PluginSystemRuntimeDependency, PluginSystemRuntimeDependencyFromUrl, } from "@sentry/junior-plugin-api";
3
+ export type { PluginNpmRuntimeDependency, PluginMcpConfig, PluginRuntimeDependency, PluginRuntimePostinstallCommand, PluginSystemRuntimeDependency, PluginSystemRuntimeDependencyFromUrl, } from "@sentry/junior-plugin-api";
4
4
  export interface PluginOAuthConfig {
5
5
  clientIdEnv: string;
6
6
  clientSecretEnv: string;
@@ -30,13 +30,6 @@ export interface OAuthBearerCredentials {
30
30
  authTokenPlaceholder?: string;
31
31
  }
32
32
  export type PluginCredentials = OAuthBearerCredentials;
33
- export interface PluginMcpHttpConfig {
34
- transport: "http";
35
- url: string;
36
- headers?: Record<string, string>;
37
- allowedTools?: string[];
38
- }
39
- export type PluginMcpConfig = PluginMcpHttpConfig;
40
33
  export interface PluginEnvVarDeclaration {
41
34
  default?: string;
42
35
  exposeToCommandEnv?: boolean;
@@ -103,6 +96,7 @@ export interface PluginManifestConfig {
103
96
  url?: string;
104
97
  headers?: Record<string, string | null> | null;
105
98
  allowedTools?: string[] | null;
99
+ wrappedTools?: string[] | null;
106
100
  } | null;
107
101
  oauth?: PluginOAuthConfigPatch | null;
108
102
  target?: {
@@ -4,7 +4,7 @@
4
4
  * This module joins registered readers with the authenticated viewer and
5
5
  * validates every plugin response before it reaches the dashboard.
6
6
  */
7
- import { type PluginUserPageContent, type PluginUserPageLink } from "@sentry/junior-plugin-api";
7
+ import { type PluginUserPageContent, type PluginUserPageInput, type PluginUserPageLink } from "@sentry/junior-plugin-api";
8
8
  /** List safe navigation metadata for registered plugin user pages. */
9
9
  export declare function readPluginUserPageLinks(): PluginUserPageLink[];
10
10
  /** Read one registered plugin user page for the authenticated viewer. */
@@ -12,4 +12,5 @@ export declare function readPluginUserPage(input: {
12
12
  email: string;
13
13
  pageId: string;
14
14
  pluginName: string;
15
+ query: PluginUserPageInput;
15
16
  }): Promise<PluginUserPageContent | undefined>;
@@ -1,3 +1,4 @@
1
+ import { type CanvasMarkdownNormalization } from "@/chat/slack/tools/canvas/markdown";
1
2
  export { extractCanvasId } from "@/chat/slack/canvas-references";
2
3
  export interface CanvasCreateInput {
3
4
  title: string;
@@ -13,11 +14,6 @@ export interface CanvasReadResult {
13
14
  content: string;
14
15
  byteLength: number;
15
16
  }
16
- /** Clamp headings deeper than h3 to h3 (Slack canvas limitation). */
17
- export declare function normalizeCanvasMarkdown(markdown: string): {
18
- markdown: string;
19
- normalizedHeadingCount: number;
20
- };
21
17
  /**
22
18
  * Create a standalone Slack canvas owned by the bot and best-effort grant write
23
19
  * access to the active channel. Standalone canvases (`canvases.create`) are not
@@ -32,10 +28,7 @@ export declare function createCanvas(input: CanvasCreateInput): Promise<{
32
28
  export declare function writeCanvasMarkdown(input: {
33
29
  canvasId: string;
34
30
  markdown: string;
35
- }): Promise<{
36
- markdown: string;
37
- normalizedHeadingCount: number;
38
- }>;
31
+ }): Promise<CanvasMarkdownNormalization>;
39
32
  /**
40
33
  * Read a Slack canvas the bot has access to and return its raw downloadable
41
34
  * content. Slack does not expose a structured canvas-read API, so we fetch
@@ -0,0 +1,9 @@
1
+ export interface CanvasMarkdownNormalization {
2
+ markdown: string;
3
+ normalizedCount: number;
4
+ normalizedHeadingCount: number;
5
+ normalizedMixedListCount: number;
6
+ unwrappedBlockquoteCount: number;
7
+ }
8
+ /** Normalize Markdown constructs known to be rejected by Slack Canvas. */
9
+ export declare function normalizeCanvasMarkdown(markdown: string): CanvasMarkdownNormalization;
@@ -1,21 +1,23 @@
1
1
  import {
2
2
  getDb
3
- } from "./chunk-KC5EE27Y.js";
3
+ } from "./chunk-M243JMZH.js";
4
4
  import {
5
- juniorConversationAnnotations
5
+ juniorConversationAnnotations,
6
+ juniorIdentities,
7
+ juniorUsers
6
8
  } from "./chunk-GCGJGSQL.js";
7
9
  import {
8
10
  SANDBOX_WORKSPACE_ROOT,
9
11
  getStateAdapter,
10
12
  sleep
11
- } from "./chunk-3N3FMCKN.js";
13
+ } from "./chunk-ALAKN7LR.js";
12
14
  import {
13
15
  botConfig,
14
16
  completeObject,
15
17
  embedTexts,
16
18
  getSlackBotToken,
17
19
  standardModelId
18
- } from "./chunk-PWRFTDTY.js";
20
+ } from "./chunk-VURFJVFH.js";
19
21
  import {
20
22
  isActorUserId,
21
23
  parseActorUserId
@@ -24,10 +26,11 @@ import {
24
26
  logException,
25
27
  logInfo,
26
28
  logWarn,
29
+ normalizeIdentityEmail,
27
30
  setSpanAttributes,
28
31
  setSpanStatus,
29
32
  withSpan
30
- } from "./chunk-MLZFK4KP.js";
33
+ } from "./chunk-ALYQOZG7.js";
31
34
  import {
32
35
  parseSlackChannelReferenceId,
33
36
  parseSlackMessageTs,
@@ -321,6 +324,55 @@ function getSlackToolContext(context) {
321
324
  };
322
325
  }
323
326
 
327
+ // src/chat/plugins/viewer-actors.ts
328
+ import { and as and2, eq as eq2 } from "drizzle-orm";
329
+ import {
330
+ actorSchema
331
+ } from "@sentry/junior-plugin-api";
332
+ async function readViewerActorsFromSql(db, email) {
333
+ const normalizedEmail = normalizeIdentityEmail(email);
334
+ if (!normalizedEmail) return [];
335
+ const rows = await db.select({
336
+ displayName: juniorIdentities.displayName,
337
+ email: juniorUsers.primaryEmail,
338
+ handle: juniorIdentities.handle,
339
+ provider: juniorIdentities.provider,
340
+ providerSubjectId: juniorIdentities.providerSubjectId,
341
+ providerTenantId: juniorIdentities.providerTenantId
342
+ }).from(juniorIdentities).innerJoin(juniorUsers, eq2(juniorUsers.id, juniorIdentities.userId)).where(
343
+ and2(
344
+ eq2(juniorUsers.primaryEmailNormalized, normalizedEmail),
345
+ eq2(juniorIdentities.kind, "user")
346
+ )
347
+ );
348
+ const actors = [];
349
+ for (const row of rows) {
350
+ const candidate = row.provider === "slack" ? {
351
+ platform: "slack",
352
+ teamId: row.providerTenantId,
353
+ userId: row.providerSubjectId,
354
+ email: row.email,
355
+ ...row.displayName ? { fullName: row.displayName } : {},
356
+ ...row.handle ? { userName: row.handle } : {}
357
+ } : row.provider === "local" ? {
358
+ platform: "local",
359
+ userId: row.providerSubjectId,
360
+ email: row.email,
361
+ ...row.displayName ? { fullName: row.displayName } : {},
362
+ ...row.handle ? { userName: row.handle } : {}
363
+ } : void 0;
364
+ if (!candidate) continue;
365
+ const parsed = actorSchema.safeParse(candidate);
366
+ if (parsed.success && parsed.data.platform !== "system") {
367
+ actors.push(parsed.data);
368
+ }
369
+ }
370
+ return actors;
371
+ }
372
+ async function readViewerActors(email) {
373
+ return await readViewerActorsFromSql(getDb(), email);
374
+ }
375
+
324
376
  // src/chat/credentials/subject.ts
325
377
  import { createHmac, timingSafeEqual } from "crypto";
326
378
 
@@ -941,6 +993,7 @@ function invocationPluginContext(plugin, context) {
941
993
  ...base,
942
994
  conversationId: context.conversationId,
943
995
  embedder: createPluginEmbedder(plugin.manifest.name),
996
+ model: createPluginModel(plugin.manifest.name, plugin.model),
944
997
  source: context.source,
945
998
  text: context.userText ?? "",
946
999
  state: createPluginState(plugin.manifest.name)
@@ -968,6 +1021,32 @@ function invocationPluginContext(plugin, context) {
968
1021
  actor: context.actor?.platform === "local" ? context.actor : void 0
969
1022
  };
970
1023
  }
1024
+ function pluginMcpContext(plugin, context) {
1025
+ const manager = context.mcpToolManager;
1026
+ const wrappedTools = new Set(plugin.manifest.mcp?.wrappedTools ?? []);
1027
+ if (!manager || wrappedTools.size === 0) {
1028
+ return void 0;
1029
+ }
1030
+ const provider = plugin.manifest.name;
1031
+ const prepare = async () => {
1032
+ await manager.activateProvider(provider);
1033
+ return manager.getActiveProviders().includes(provider) ? "ready" : "authorization_pending";
1034
+ };
1035
+ return {
1036
+ prepare,
1037
+ async callTool(input) {
1038
+ if (await prepare() === "authorization_pending") {
1039
+ return { status: "authorization_pending" };
1040
+ }
1041
+ return await manager.callWrappedTool(
1042
+ provider,
1043
+ input.name,
1044
+ input.arguments ?? {},
1045
+ input.toolCallId ? { toolCallId: input.toolCallId } : void 0
1046
+ );
1047
+ }
1048
+ };
1049
+ }
971
1050
  function safeErrorMessage(error) {
972
1051
  return error instanceof Error ? error.message : String(error);
973
1052
  }
@@ -1239,6 +1318,7 @@ function getPluginTools(context) {
1239
1318
  db: getDb(),
1240
1319
  plugin: pluginName
1241
1320
  }) : void 0;
1321
+ const mcp = pluginMcpContext(plugin, context);
1242
1322
  let pluginContext;
1243
1323
  if (context.source.platform === "slack") {
1244
1324
  if (context.destination.platform !== "slack") {
@@ -1257,6 +1337,7 @@ function getPluginTools(context) {
1257
1337
  userText: context.userText,
1258
1338
  embedder: createPluginEmbedder(pluginName),
1259
1339
  egress: context.egress,
1340
+ ...mcp ? { mcp } : {},
1260
1341
  model: createPluginModel(pluginName, plugin.model),
1261
1342
  state: createPluginState(pluginName)
1262
1343
  };
@@ -1276,6 +1357,7 @@ function getPluginTools(context) {
1276
1357
  userText: context.userText,
1277
1358
  embedder: createPluginEmbedder(pluginName),
1278
1359
  egress: context.egress,
1360
+ ...mcp ? { mcp } : {},
1279
1361
  model: createPluginModel(pluginName, plugin.model),
1280
1362
  state: createPluginState(pluginName)
1281
1363
  };
@@ -1416,7 +1498,10 @@ function getPluginApiRoutes() {
1416
1498
  continue;
1417
1499
  }
1418
1500
  const app = hook({
1419
- ...basePluginContext(plugin)
1501
+ ...basePluginContext(plugin),
1502
+ viewer: {
1503
+ actors: readViewerActors
1504
+ }
1420
1505
  });
1421
1506
  if (app === void 0) {
1422
1507
  continue;
@@ -1853,6 +1938,7 @@ export {
1853
1938
  setDashboardConversationLinkOptions,
1854
1939
  getDashboardConversationLink,
1855
1940
  getSlackToolContext,
1941
+ readViewerActors,
1856
1942
  runWithWorkspaceTeamId,
1857
1943
  getWorkspaceTeamId,
1858
1944
  SlackActionError,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getDb
3
- } from "./chunk-KC5EE27Y.js";
3
+ } from "./chunk-M243JMZH.js";
4
4
  import {
5
5
  juniorStats
6
6
  } from "./chunk-GCGJGSQL.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getChatConfig
3
- } from "./chunk-PWRFTDTY.js";
3
+ } from "./chunk-VURFJVFH.js";
4
4
 
5
5
  // src/chat/state/adapter.ts
6
6
  import { createMemoryState } from "@chat-adapter/state-memory";
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-6GWA276C.js";
14
14
  import {
15
15
  getDeploymentTelemetryAttributes
16
- } from "./chunk-QWCF4RAC.js";
16
+ } from "./chunk-DWOH57FW.js";
17
17
 
18
18
  // src/chat/logging.ts
19
19
  import path from "path";
@@ -8,7 +8,6 @@ import {
8
8
  clearPendingAuth,
9
9
  coerceThreadConversationState,
10
10
  getAgentTurnSessionRecord,
11
- getInterruptionMarker,
12
11
  getPersistedThreadState,
13
12
  getPiMessageRole,
14
13
  hydrateConversationMessages,
@@ -23,28 +22,28 @@ import {
23
22
  persistThreadStateById,
24
23
  stripRuntimeTurnContext,
25
24
  updateConversationStats
26
- } from "./chunk-PJPKHGLG.js";
25
+ } from "./chunk-JQWP6V22.js";
27
26
  import {
28
27
  createPluginEmbedder,
29
28
  createPluginLogger,
30
29
  createPluginModel,
31
30
  createPluginState,
32
31
  getPlugins
33
- } from "./chunk-GT2ZUALJ.js";
32
+ } from "./chunk-24B5R6OU.js";
34
33
  import {
35
34
  getDb
36
- } from "./chunk-KC5EE27Y.js";
35
+ } from "./chunk-M243JMZH.js";
37
36
  import {
38
37
  getStateAdapter
39
- } from "./chunk-3N3FMCKN.js";
38
+ } from "./chunk-ALAKN7LR.js";
40
39
  import {
41
40
  ProviderError,
42
41
  getProviderErrorAttributes,
43
42
  getProviderErrorUserMessage
44
- } from "./chunk-PWRFTDTY.js";
43
+ } from "./chunk-VURFJVFH.js";
45
44
  import {
46
45
  buildTurnFailureResponse
47
- } from "./chunk-MLZFK4KP.js";
46
+ } from "./chunk-ALYQOZG7.js";
48
47
  import {
49
48
  parseSlackMessageTs
50
49
  } from "./chunk-F3B2YJ76.js";
@@ -385,6 +384,12 @@ async function processPluginTask(message, options = {}) {
385
384
  });
386
385
  }
387
386
 
387
+ // src/chat/interruption-marker.ts
388
+ var INTERRUPTED_MARKER = "\n\n[Response interrupted before completion]";
389
+ function getInterruptionMarker() {
390
+ return INTERRUPTED_MARKER;
391
+ }
392
+
388
393
  // src/chat/services/turn-failure-response.ts
389
394
  function requireTurnFailureEventId(eventId, eventName) {
390
395
  if (!eventId) {
@@ -594,6 +599,7 @@ export {
594
599
  getTurnUserReplyAttachmentContext,
595
600
  scheduleSessionCompletedPluginTasks,
596
601
  processPluginTask,
602
+ getInterruptionMarker,
597
603
  requireTurnFailureEventId,
598
604
  getAgentTurnDiagnosticsAttributes,
599
605
  finalizeFailedTurnReplyWithEvent,
@@ -2,18 +2,18 @@ import {
2
2
  SANDBOX_WORKSPACE_ROOT,
3
3
  getStateAdapter,
4
4
  sleep
5
- } from "./chunk-3N3FMCKN.js";
5
+ } from "./chunk-ALAKN7LR.js";
6
6
  import {
7
7
  toOptionalTrimmed
8
- } from "./chunk-PWRFTDTY.js";
8
+ } from "./chunk-VURFJVFH.js";
9
9
  import {
10
10
  pluginCatalogRuntime
11
- } from "./chunk-UXLYAVYL.js";
11
+ } from "./chunk-GNNV3UTY.js";
12
12
  import {
13
13
  setSpanAttributes,
14
14
  setSpanStatus,
15
15
  withSpan
16
- } from "./chunk-MLZFK4KP.js";
16
+ } from "./chunk-ALYQOZG7.js";
17
17
 
18
18
  // src/chat/sandbox/snapshot/profile.ts
19
19
  import { createHash } from "crypto";
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "@sentry/junior",
4
- version: "0.118.0",
4
+ version: "0.120.0",
5
5
  private: false,
6
6
  publishConfig: {
7
7
  access: "public"
@@ -49,7 +49,8 @@ var package_default = {
49
49
  files: [
50
50
  "dist",
51
51
  "bin",
52
- "migrations"
52
+ "migrations",
53
+ "skills"
53
54
  ],
54
55
  scripts: {
55
56
  prepare: "pnpm run build",
@@ -61,7 +62,7 @@ var package_default = {
61
62
  test: "vitest run --maxWorkers=4",
62
63
  "test:watch": "vitest",
63
64
  typecheck: "tsc --noEmit",
64
- "skills:check": "node scripts/check-skills.mjs",
65
+ "skills:check": "node --test scripts/check-skills.test.mjs && node scripts/check-skills.mjs",
65
66
  "test:coverage": "vitest run --maxWorkers=4 --coverage --reporter=default --reporter=junit --outputFile.junit=coverage/results.junit.xml"
66
67
  },
67
68
  dependencies: {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  JUNIOR_VERSION
3
- } from "./chunk-HWUBBHLK.js";
3
+ } from "./chunk-DMKHRBI6.js";
4
4
 
5
5
  // src/deployment.ts
6
6
  var JUNIOR_HEARTBEAT_ROUTE = "/api/internal/heartbeat";