@sentry/junior 0.168.0 → 0.170.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 (65) hide show
  1. package/dist/{agent-hooks-D7JHU7WE.js → agent-hooks-IPUNCZPZ.js} +10 -10
  2. package/dist/api.js +27 -27
  3. package/dist/app.js +34 -34
  4. package/dist/catalog-runtime-E6XHWRPG.js +16 -0
  5. package/dist/chat/conversations/sql/store.d.ts +7 -0
  6. package/dist/chat/conversations/store.d.ts +14 -0
  7. package/dist/chat/slack/channel.d.ts +0 -13
  8. package/dist/chat/slack/ids.d.ts +7 -1
  9. package/dist/chat/slack/tool-support/channel-target.d.ts +6 -5
  10. package/dist/chat/workspaces/tools.d.ts +1 -1
  11. package/dist/{chunk-I654GTNX.js → chunk-2XI6OLXA.js} +11 -11
  12. package/dist/{chunk-SA6HSGDQ.js → chunk-3SFZJVX5.js} +2 -2
  13. package/dist/{chunk-JYZA27WZ.js → chunk-47GJ7QRO.js} +1 -1
  14. package/dist/{chunk-GFAFJWSD.js → chunk-4PSUCN4P.js} +2 -2
  15. package/dist/{chunk-36ANNINB.js → chunk-5EPG7PYS.js} +1 -1
  16. package/dist/{chunk-2AZWPCBL.js → chunk-6E4WQV75.js} +1 -1
  17. package/dist/{chunk-CHYKJIKV.js → chunk-6GOKKLWF.js} +7 -7
  18. package/dist/{chunk-JW5SNARN.js → chunk-6W2UIZSA.js} +1 -1
  19. package/dist/{chunk-7MA4HV4W.js → chunk-6ZWRNC4D.js} +1 -1
  20. package/dist/{chunk-HFCY2MP6.js → chunk-74XMBKRI.js} +1 -1
  21. package/dist/{chunk-IC2R5ZYK.js → chunk-7TVGQZOH.js} +5 -5
  22. package/dist/{chunk-7JMIQWSP.js → chunk-A22DGDXT.js} +2 -2
  23. package/dist/{chunk-2IMUHQWT.js → chunk-B53NR3XY.js} +4 -4
  24. package/dist/{chunk-24LYO2C5.js → chunk-BW644E3V.js} +1 -1
  25. package/dist/{chunk-FEJNF6FM.js → chunk-CA6JIB7S.js} +226 -97
  26. package/dist/{chunk-BDUENQD3.js → chunk-CGA4ERJ5.js} +1 -1
  27. package/dist/{chunk-RQTHGAPN.js → chunk-E7HKIHI5.js} +2 -2
  28. package/dist/{chunk-KXC3RX7T.js → chunk-F3I6YFB4.js} +6 -6
  29. package/dist/{chunk-PGEWSREG.js → chunk-F4UM52UH.js} +1 -1
  30. package/dist/{chunk-B547UCF7.js → chunk-FKOLWEMX.js} +7 -7
  31. package/dist/{chunk-YPLOMUS4.js → chunk-HZALSYOW.js} +5 -5
  32. package/dist/{chunk-WE6OK3UZ.js → chunk-IF3OK4XO.js} +6 -6
  33. package/dist/{chunk-ME26L5R4.js → chunk-IJTFG6AK.js} +5 -5
  34. package/dist/{chunk-6MG6K3YZ.js → chunk-IX7VHMIJ.js} +32 -4
  35. package/dist/{chunk-AE7IUAXH.js → chunk-KQCHIOME.js} +7 -7
  36. package/dist/{chunk-V7YE4WCP.js → chunk-M63DETLL.js} +7 -4
  37. package/dist/{chunk-KX2QWO3Z.js → chunk-NESGW5HV.js} +1 -1
  38. package/dist/{chunk-AGVNNQCS.js → chunk-NFERKIUX.js} +4 -4
  39. package/dist/{chunk-O6KWHWGM.js → chunk-NGL4XFT2.js} +1 -1
  40. package/dist/{chunk-76TU3ROD.js → chunk-T4SEUU7A.js} +1 -1
  41. package/dist/{chunk-DL4L7BBJ.js → chunk-TX553KXA.js} +5 -5
  42. package/dist/{chunk-T5RDAC5O.js → chunk-UD4BNNM2.js} +1 -1
  43. package/dist/{chunk-7GXMR4MF.js → chunk-UHW5RAIB.js} +13 -13
  44. package/dist/{chunk-H4RVQPJF.js → chunk-YWX7D7BJ.js} +18 -18
  45. package/dist/cli/chat.js +33 -33
  46. package/dist/cli/check.js +8 -8
  47. package/dist/cli/plugins.js +14 -14
  48. package/dist/cli/snapshot-create.js +11 -11
  49. package/dist/cli/upgrade.js +9 -9
  50. package/dist/{db-J2DG77RS.js → db-WMSEGSFM.js} +8 -8
  51. package/dist/instrumentation.js +4 -4
  52. package/dist/nitro.js +2 -2
  53. package/dist/{oauth-callback-server-AZSRYN3C.js → oauth-callback-server-GBS47NTO.js} +24 -24
  54. package/dist/{runner-U2WWTGBB.js → runner-V2A2Z7K3.js} +14 -14
  55. package/dist/{sandbox-egress-signals-U3ZX7C5W.js → sandbox-egress-signals-DXOOBSBI.js} +3 -3
  56. package/dist/{skills-VO5YJ2VN.js → skills-Z35YXLUG.js} +8 -8
  57. package/dist/spawn-AKPJBUS2.js +37 -0
  58. package/dist/{validation-ZNI5KAOD.js → validation-EQCK4DA5.js} +8 -8
  59. package/dist/version.js +1 -1
  60. package/dist/{work-F3T7M2KC.js → work-XIANCABO.js} +20 -20
  61. package/dist/worker-YALLEN2Z.js +24 -0
  62. package/package.json +4 -4
  63. package/dist/catalog-runtime-LXATMEQ6.js +0 -16
  64. package/dist/spawn-KOVJQOQA.js +0 -37
  65. package/dist/worker-B3NU3RWC.js +0 -24
@@ -5,28 +5,28 @@ import {
5
5
  isDmChannel,
6
6
  normalizeSlackConversationId,
7
7
  withSlackRetries
8
- } from "./chunk-KXC3RX7T.js";
8
+ } from "./chunk-F3I6YFB4.js";
9
9
  import {
10
10
  parseDestination
11
- } from "./chunk-6MG6K3YZ.js";
11
+ } from "./chunk-IX7VHMIJ.js";
12
12
  import {
13
13
  getStateAdapter
14
- } from "./chunk-HFCY2MP6.js";
14
+ } from "./chunk-74XMBKRI.js";
15
15
  import {
16
16
  normalizeSlackEmojiName
17
- } from "./chunk-RQTHGAPN.js";
17
+ } from "./chunk-E7HKIHI5.js";
18
18
  import {
19
19
  pluginCatalogRuntime
20
- } from "./chunk-2AZWPCBL.js";
20
+ } from "./chunk-6E4WQV75.js";
21
21
  import {
22
22
  parseSlackMessageTs,
23
23
  parseSlackUserId
24
- } from "./chunk-V7YE4WCP.js";
24
+ } from "./chunk-M63DETLL.js";
25
25
  import {
26
26
  isRecord,
27
27
  logInfo,
28
28
  logWarn
29
- } from "./chunk-36ANNINB.js";
29
+ } from "./chunk-5EPG7PYS.js";
30
30
 
31
31
  // src/chat/slack/outbound.ts
32
32
  var MAX_SLACK_MESSAGE_TEXT_CHARS = 4e4;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  DEFAULT_SQL_STATEMENT_TIMEOUT_MS
3
- } from "./chunk-RQTHGAPN.js";
3
+ } from "./chunk-E7HKIHI5.js";
4
4
  import {
5
5
  juniorDestinations,
6
6
  timestamptz
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  credentialContextSchema
3
- } from "./chunk-BDUENQD3.js";
3
+ } from "./chunk-CGA4ERJ5.js";
4
4
 
5
5
  // src/chat/sandbox/egress/schemas.ts
6
6
  import { z } from "zod";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getChatConfig
3
- } from "./chunk-RQTHGAPN.js";
3
+ } from "./chunk-E7HKIHI5.js";
4
4
 
5
5
  // src/chat/state/adapter.ts
6
6
  import { createMemoryState } from "@chat-adapter/state-memory";
@@ -8,22 +8,22 @@ import {
8
8
  getConversationStore,
9
9
  parseDestination,
10
10
  sameDestination
11
- } from "./chunk-6MG6K3YZ.js";
11
+ } from "./chunk-IX7VHMIJ.js";
12
12
  import {
13
13
  getDefaultRedisStateAdapterFor,
14
14
  getStateAdapter
15
- } from "./chunk-HFCY2MP6.js";
15
+ } from "./chunk-74XMBKRI.js";
16
16
  import {
17
17
  getChatConfig
18
- } from "./chunk-RQTHGAPN.js";
18
+ } from "./chunk-E7HKIHI5.js";
19
19
  import {
20
20
  parseStoredSlackActor
21
- } from "./chunk-V7YE4WCP.js";
21
+ } from "./chunk-M63DETLL.js";
22
22
  import {
23
23
  isRecord,
24
24
  toOptionalNumber,
25
25
  toOptionalString
26
- } from "./chunk-36ANNINB.js";
26
+ } from "./chunk-5EPG7PYS.js";
27
27
 
28
28
  // src/chat/task-execution/state.ts
29
29
  import { randomUUID } from "crypto";
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  credentialUserSubjectId
3
- } from "./chunk-BDUENQD3.js";
3
+ } from "./chunk-CGA4ERJ5.js";
4
4
  import {
5
5
  logInfo,
6
6
  logWarn,
7
7
  setSpanAttributes
8
- } from "./chunk-36ANNINB.js";
8
+ } from "./chunk-5EPG7PYS.js";
9
9
  import {
10
10
  discoverInstalledPluginPackageContent,
11
11
  normalizePluginPackageNames
@@ -5,18 +5,18 @@ import {
5
5
  } from "./chunk-BVREIWBD.js";
6
6
  import {
7
7
  getStateAdapter
8
- } from "./chunk-HFCY2MP6.js";
8
+ } from "./chunk-74XMBKRI.js";
9
9
  import {
10
10
  toOptionalTrimmed
11
- } from "./chunk-RQTHGAPN.js";
11
+ } from "./chunk-E7HKIHI5.js";
12
12
  import {
13
13
  pluginCatalogRuntime
14
- } from "./chunk-2AZWPCBL.js";
14
+ } from "./chunk-6E4WQV75.js";
15
15
  import {
16
16
  setSpanAttributes,
17
17
  setSpanStatus,
18
18
  withSpan
19
- } from "./chunk-36ANNINB.js";
19
+ } from "./chunk-5EPG7PYS.js";
20
20
 
21
21
  // src/chat/sandbox/resources.ts
22
22
  var configuredResources;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  JUNIOR_VERSION
3
- } from "./chunk-PGEWSREG.js";
3
+ } from "./chunk-F4UM52UH.js";
4
4
 
5
5
  // src/deployment.ts
6
6
  var JUNIOR_HEARTBEAT_ROUTE = "/api/internal/heartbeat";
@@ -7,7 +7,7 @@ import {
7
7
  PluginCredentialFailureError,
8
8
  agentNameSchema,
9
9
  createPluginAuthOrchestration
10
- } from "./chunk-B547UCF7.js";
10
+ } from "./chunk-FKOLWEMX.js";
11
11
  import {
12
12
  authorizationId
13
13
  } from "./chunk-DIB4GX3G.js";
@@ -32,7 +32,7 @@ import {
32
32
  searchSlackUsers,
33
33
  selectPluginGrant,
34
34
  toMcpProviderError
35
- } from "./chunk-AE7IUAXH.js";
35
+ } from "./chunk-KQCHIOME.js";
36
36
  import {
37
37
  RetryableDeliveryError,
38
38
  actorFromRun,
@@ -48,13 +48,13 @@ import {
48
48
  getSlackMessagePermalink,
49
49
  resolveBaseUrl,
50
50
  uploadFilesToConversation
51
- } from "./chunk-CHYKJIKV.js";
51
+ } from "./chunk-6GOKKLWF.js";
52
52
  import {
53
53
  parseSandboxEgressAuthRequiredSignal,
54
54
  parseSandboxEgressPermissionDeniedSignal,
55
55
  sandboxEgressCredentialContextSchema,
56
56
  sandboxEgressCredentialLeaseSchema
57
- } from "./chunk-7MA4HV4W.js";
57
+ } from "./chunk-6ZWRNC4D.js";
58
58
  import {
59
59
  SANDBOX_RUNTIME,
60
60
  SCHEDULED_TASK_SYSTEM_ACTOR,
@@ -88,10 +88,10 @@ import {
88
88
  scheduledTaskAttributes,
89
89
  storeAttachments,
90
90
  writableEventTask
91
- } from "./chunk-ME26L5R4.js";
91
+ } from "./chunk-IJTFG6AK.js";
92
92
  import {
93
93
  parseSlackThreadId
94
- } from "./chunk-GFAFJWSD.js";
94
+ } from "./chunk-4PSUCN4P.js";
95
95
  import {
96
96
  AGENTS_REMOVAL_NOTICE,
97
97
  AGENTS_REPLACEMENT_NOTICE,
@@ -162,7 +162,7 @@ import {
162
162
  stripRuntimeTurnContext,
163
163
  trimTrailingAssistantMessages,
164
164
  truncateText
165
- } from "./chunk-YPLOMUS4.js";
165
+ } from "./chunk-HZALSYOW.js";
166
166
  import {
167
167
  JUNIOR_THREAD_STATE_TTL_MS
168
168
  } from "./chunk-3Y47VMHV.js";
@@ -183,19 +183,23 @@ import {
183
183
  stopSession,
184
184
  throwSandboxOperationError,
185
185
  wrapSandboxSetupError
186
- } from "./chunk-2IMUHQWT.js";
186
+ } from "./chunk-B53NR3XY.js";
187
187
  import {
188
188
  privateTraceResultAttributes
189
189
  } from "./chunk-UIE3R5XU.js";
190
190
  import {
191
191
  SlackActionError,
192
+ WorkspaceValidationError,
192
193
  createPluginHookRunner,
194
+ createWorkspace,
195
+ deleteWorkspace,
193
196
  downloadPrivateSlackFile,
194
197
  getDashboardTaskLink,
195
198
  getFilePermalink,
196
199
  getPluginSystemPromptContributions,
197
200
  getPluginTools,
198
201
  getPluginUserPromptContributions,
202
+ getPlugins,
199
203
  getSlackClient,
200
204
  getSlackToolContext,
201
205
  getWorkspace,
@@ -207,9 +211,10 @@ import {
207
211
  recordResolvedWorkspaceSnapshot,
208
212
  resolveChannelCapabilities,
209
213
  tryWorkspaceRepoCheckoutPath,
214
+ updateWorkspace,
210
215
  withSlackRetries,
211
216
  workspaceRepoCheckoutPath
212
- } from "./chunk-KXC3RX7T.js";
217
+ } from "./chunk-F3I6YFB4.js";
213
218
  import {
214
219
  KNOWN_CONVERSATION_EVENT_TYPES,
215
220
  contextProvenance,
@@ -221,11 +226,11 @@ import {
221
226
  instructionActors,
222
227
  instructionProvenanceFor,
223
228
  sameActorIdentity
224
- } from "./chunk-6MG6K3YZ.js";
229
+ } from "./chunk-IX7VHMIJ.js";
225
230
  import {
226
231
  juniorArtifacts,
227
232
  juniorIdentities
228
- } from "./chunk-JW5SNARN.js";
233
+ } from "./chunk-6W2UIZSA.js";
229
234
  import {
230
235
  SANDBOX_DATA_ROOT,
231
236
  SANDBOX_REPOS_ROOT,
@@ -241,7 +246,7 @@ import {
241
246
  } from "./chunk-BVREIWBD.js";
242
247
  import {
243
248
  getStateAdapter
244
- } from "./chunk-HFCY2MP6.js";
249
+ } from "./chunk-74XMBKRI.js";
245
250
  import {
246
251
  ACTIVE_TURN_COMPACTION_SUMMARY_PREFIX,
247
252
  COMPACTION_SUMMARY_PREFIX,
@@ -274,7 +279,7 @@ import {
274
279
  resolveGatewayCredential,
275
280
  resolveGatewayModel,
276
281
  unwrapCurrentInstruction
277
- } from "./chunk-RQTHGAPN.js";
282
+ } from "./chunk-E7HKIHI5.js";
278
283
  import {
279
284
  canExposeConversationPayload,
280
285
  resolveConversationPrivacy,
@@ -284,16 +289,16 @@ import {
284
289
  toGenAiMessagesTraceAttributes,
285
290
  toGenAiPayloadMetadata,
286
291
  toGenAiPayloadTraceAttributes
287
- } from "./chunk-O6KWHWGM.js";
292
+ } from "./chunk-NGL4XFT2.js";
288
293
  import {
289
294
  discoverSkills,
290
295
  findSkillByName,
291
296
  loadSkillsByName,
292
297
  parseSkillInvocation
293
- } from "./chunk-SA6HSGDQ.js";
298
+ } from "./chunk-3SFZJVX5.js";
294
299
  import {
295
300
  pluginCatalogRuntime
296
- } from "./chunk-2AZWPCBL.js";
301
+ } from "./chunk-6E4WQV75.js";
297
302
  import {
298
303
  CredentialUnavailableError,
299
304
  OAuthProviderError,
@@ -301,16 +306,18 @@ import {
301
306
  getOAuthProviderErrorAttributes,
302
307
  resolveAuthTokenPlaceholder,
303
308
  resolvePluginCommandEnv
304
- } from "./chunk-7JMIQWSP.js";
309
+ } from "./chunk-A22DGDXT.js";
305
310
  import {
306
311
  credentialUserSubjectId
307
- } from "./chunk-BDUENQD3.js";
312
+ } from "./chunk-CGA4ERJ5.js";
308
313
  import {
309
314
  isUserActor,
310
315
  parseSlackChannelId,
316
+ parseSlackChannelReferenceId,
311
317
  parseSlackMessageTs,
318
+ parseSlackTeamId,
312
319
  parseSlackUserId
313
- } from "./chunk-V7YE4WCP.js";
320
+ } from "./chunk-M63DETLL.js";
314
321
  import {
315
322
  extractGenAiUsageAttributes,
316
323
  extractGenAiUsageSummary,
@@ -329,7 +336,7 @@ import {
329
336
  summarizeMessageText,
330
337
  withLogContext,
331
338
  withSpan
332
- } from "./chunk-36ANNINB.js";
339
+ } from "./chunk-5EPG7PYS.js";
333
340
  import {
334
341
  startInactiveSpan,
335
342
  withActiveSpan
@@ -9656,58 +9663,6 @@ async function joinPublicChannel(channelId) {
9656
9663
  { action: "conversations.join", idempotent: true }
9657
9664
  );
9658
9665
  }
9659
- async function listPublicChannels(input = {}) {
9660
- const client = getSlackClient();
9661
- const targetLimit = Math.max(1, Math.min(input.limit ?? 1e3, 1e3));
9662
- const maxPages = Math.max(1, Math.min(input.maxPages ?? 10, 20));
9663
- const channels = [];
9664
- let cursor;
9665
- let pages = 0;
9666
- while (channels.length < targetLimit && pages < maxPages) {
9667
- pages += 1;
9668
- const pageLimit = Math.max(1, Math.min(200, targetLimit - channels.length));
9669
- const response = await withSlackRetries(
9670
- () => client.conversations.list({
9671
- types: "public_channel",
9672
- exclude_archived: true,
9673
- limit: pageLimit,
9674
- cursor
9675
- }),
9676
- 3,
9677
- { action: "conversations.list", idempotent: true }
9678
- );
9679
- const batch = response.channels ?? [];
9680
- for (const item of batch) {
9681
- if (typeof item.id !== "string" || !item.id) {
9682
- continue;
9683
- }
9684
- if (item.is_private === true) {
9685
- continue;
9686
- }
9687
- channels.push({
9688
- id: item.id,
9689
- ...typeof item.name === "string" && item.name ? { name: item.name } : {},
9690
- ...typeof item.is_member === "boolean" ? { isMember: item.is_member } : {},
9691
- ...typeof item.is_archived === "boolean" ? { isArchived: item.is_archived } : {}
9692
- });
9693
- }
9694
- cursor = response.response_metadata?.next_cursor || void 0;
9695
- if (!cursor) {
9696
- break;
9697
- }
9698
- }
9699
- return channels.slice(0, targetLimit);
9700
- }
9701
- async function resolvePublicChannelByName(channelName) {
9702
- const normalized = channelName.trim().replace(/^#/, "").toLowerCase();
9703
- if (!normalized) {
9704
- return void 0;
9705
- }
9706
- const channels = await listPublicChannels();
9707
- return channels.find(
9708
- (channel) => channel.name?.trim().toLowerCase() === normalized
9709
- );
9710
- }
9711
9666
 
9712
9667
  // src/chat/slack/tool-support/channel-access.ts
9713
9668
  var DENIED_PRIVATE = "Cannot read this Slack conversation because it is private. Only the current conversation or public channels are readable.";
@@ -9801,44 +9756,47 @@ async function joinPublicChannelForRead(args) {
9801
9756
 
9802
9757
  // src/chat/slack/tool-support/channel-target.ts
9803
9758
  import { z as z35 } from "zod";
9804
- var slackChannelRefParam = z35.string().trim().min(1).max(80).describe("Slack channel ID or public channel name.");
9759
+ var SLACK_CHANNEL_REF_MAX_LENGTH = 160;
9760
+ var slackChannelRefParam = z35.string().trim().min(1).max(SLACK_CHANNEL_REF_MAX_LENGTH).describe(
9761
+ "Slack channel id (`C123`), mention (`<#C123>` / `<#C123|name>`), Junior slack reference (`slack:C123`), or a channel name Junior already knows in this workspace."
9762
+ );
9805
9763
  async function resolveSlackChannelRef(input) {
9806
9764
  const trimmed = input.value.trim();
9807
9765
  if (!trimmed) {
9808
9766
  throw new ToolInputError(
9809
- `Invalid \`${input.field}\`. Provide a Slack channel id like \`C123\` or a public channel name like \`#proj-foo\`.`
9767
+ `Invalid \`${input.field}\`. Use a channel id (\`C123\`), a Slack mention (\`<#C123>\`), a Junior slack reference (\`slack:C123\`), or a channel name Junior already knows.`
9810
9768
  );
9811
9769
  }
9812
- const channelId = parseSlackChannelId(trimmed);
9770
+ const channelId = parseSlackChannelReferenceId(trimmed);
9813
9771
  if (channelId) {
9772
+ return { channelId };
9773
+ }
9774
+ const known = await getConversationStore().findSlackDestinationByName({
9775
+ teamId: input.teamId,
9776
+ channelName: trimmed
9777
+ });
9778
+ const knownChannelId = known ? parseSlackChannelId(known.channelId) : void 0;
9779
+ if (known && knownChannelId) {
9814
9780
  return {
9815
- channelId,
9816
- resolvedFromName: false
9781
+ channelId: knownChannelId,
9782
+ ...known.channelName ? { channelName: known.channelName } : {}
9817
9783
  };
9818
9784
  }
9819
- const match = await resolvePublicChannelByName(trimmed);
9820
- if (!match) {
9821
- throw new ToolInputError(
9822
- `No public Slack channel named \`${trimmed}\` was found. Use an exact public channel name or a channel id.`
9823
- );
9824
- }
9825
- return {
9826
- channelId: match.id,
9827
- ...match.name ? { channelName: match.name } : {},
9828
- resolvedFromName: true
9829
- };
9785
+ throw new ToolInputError(
9786
+ `Unknown \`${input.field}\` \`${trimmed}\`. Use a channel id (\`C123\`), a Slack mention (\`<#C123>\`), a link, or a channel name Junior has already seen in this workspace. Public search can discover channels; plain names are not scanned from Slack.`
9787
+ );
9830
9788
  }
9831
9789
  async function resolveOptionalSlackChannelRef(input) {
9832
9790
  if (input.value !== void 0) {
9833
9791
  return resolveSlackChannelRef({
9834
9792
  field: input.field ?? "channel_id",
9835
- value: input.value
9793
+ value: input.value,
9794
+ teamId: input.teamId
9836
9795
  });
9837
9796
  }
9838
9797
  if (input.defaultChannelId) {
9839
9798
  return {
9840
- channelId: input.defaultChannelId,
9841
- resolvedFromName: false
9799
+ channelId: input.defaultChannelId
9842
9800
  };
9843
9801
  }
9844
9802
  throw new ToolInputError(
@@ -9864,7 +9822,8 @@ function createSlackChannelJoinTool(context) {
9864
9822
  execute: async ({ channel_id }) => {
9865
9823
  const target = await resolveSlackChannelRef({
9866
9824
  field: "channel_id",
9867
- value: channel_id
9825
+ value: channel_id,
9826
+ teamId: context.teamId
9868
9827
  });
9869
9828
  const access = await checkSlackChannelReadAccess({
9870
9829
  currentChannelIds: [
@@ -10008,7 +9967,8 @@ function createSlackChannelListMessagesTool(context) {
10008
9967
  const target = await resolveOptionalSlackChannelRef({
10009
9968
  field: "channel_id",
10010
9969
  value: channel_id,
10011
- defaultChannelId: context.destinationChannelId
9970
+ defaultChannelId: context.destinationChannelId,
9971
+ teamId: context.teamId
10012
9972
  });
10013
9973
  const targetChannelId = target.channelId;
10014
9974
  const access = await checkSlackChannelReadAccess({
@@ -10166,7 +10126,8 @@ async function resolveSearchFilters(input) {
10166
10126
  if (input.channel_id != null && input.channel_id.trim() !== "") {
10167
10127
  const target = await resolveSlackChannelRef({
10168
10128
  field: "channel_id",
10169
- value: input.channel_id
10129
+ value: input.channel_id,
10130
+ teamId: input.teamId
10170
10131
  });
10171
10132
  channelId = target.channelId;
10172
10133
  }
@@ -10211,7 +10172,13 @@ function createSlackConversationMessageSearchTool(scope, currentConversationId)
10211
10172
  }).strict(),
10212
10173
  outputSchema: conversationMessageSearchOutputSchema,
10213
10174
  execute: async (input) => {
10214
- const filters = await resolveSearchFilters(input);
10175
+ const teamId = parseSlackTeamId(scope.providerTenantId);
10176
+ if (!teamId) {
10177
+ throw new ToolInputError(
10178
+ "Cannot search retained messages without a valid Slack workspace id."
10179
+ );
10180
+ }
10181
+ const filters = await resolveSearchFilters({ ...input, teamId });
10215
10182
  const store = getConversationMessageSearchStore();
10216
10183
  const matches = await store.search({
10217
10184
  currentConversationId,
@@ -12088,7 +12055,8 @@ function createSlackThreadReadTool(context) {
12088
12055
  }
12089
12056
  const target = await resolveSlackChannelRef({
12090
12057
  field: "channel_id",
12091
- value: channel_id
12058
+ value: channel_id,
12059
+ teamId: context.teamId
12092
12060
  });
12093
12061
  channelId = target.channelId;
12094
12062
  messageTs = parsedTs.value;
@@ -13678,6 +13646,22 @@ function createWriteFileTool() {
13678
13646
 
13679
13647
  // src/chat/workspaces/tools.ts
13680
13648
  import { z as z63 } from "zod";
13649
+ async function tryRecordWorkspaceSwitchStat(workspace) {
13650
+ if (!process.env.DATABASE_URL) return;
13651
+ try {
13652
+ await incrementStat({
13653
+ namespace: "junior",
13654
+ metric: "workspace_switch",
13655
+ name: workspace.id
13656
+ });
13657
+ } catch (error) {
13658
+ logWarn("workspace.switch.stat.failed", {
13659
+ "app.workspace.id": workspace.id,
13660
+ "app.workspace.name": workspace.name,
13661
+ "exception.message": error instanceof Error ? error.message : String(error)
13662
+ });
13663
+ }
13664
+ }
13681
13665
  var repoSchema = z63.object({
13682
13666
  provider: z63.string(),
13683
13667
  repo: z63.string(),
@@ -13701,9 +13685,153 @@ function view(workspace) {
13701
13685
  }))
13702
13686
  };
13703
13687
  }
13688
+ function workspaceProviderNames() {
13689
+ const providers = getPlugins().filter((plugin) => plugin.hooks?.workspacePrepare).map((plugin) => plugin.manifest.name).sort((left, right) => left.localeCompare(right));
13690
+ if (providers.length === 0) return void 0;
13691
+ return providers;
13692
+ }
13693
+ function workspaceWriteSchemas(providers) {
13694
+ const providerNames = providers.map((provider) => `\`${provider}\``).join(", ");
13695
+ const repoInputSchema = z63.object({
13696
+ provider: z63.enum(providers).describe(`Repository provider. Supported: ${providerNames}.`),
13697
+ repo: z63.string().trim().min(1).describe("Repository in owner/name format.")
13698
+ }).strict();
13699
+ const workspaceInputSchema = z63.object({
13700
+ name: z63.string().trim().min(1).describe(
13701
+ "Workspace name. Use lowercase letters, digits, underscores, or hyphens."
13702
+ ),
13703
+ setup_script: z63.string().nullable().describe(
13704
+ "Optional shell script to run after repository checkout whenever this Workspace starts. Omit or use null for no setup script."
13705
+ ).optional(),
13706
+ repos: z63.array(repoInputSchema).max(32).describe("Complete repository list.")
13707
+ }).strict();
13708
+ return { providerNames, workspaceInputSchema };
13709
+ }
13710
+ function writeInput(input) {
13711
+ return {
13712
+ name: input.name,
13713
+ ...input.setup_script == null ? {} : { setupScript: input.setup_script },
13714
+ repos: input.repos.map((repo) => ({
13715
+ provider: repo.provider,
13716
+ repo: repo.repo
13717
+ }))
13718
+ };
13719
+ }
13720
+ function prepareWorkspaceWriteArguments(args) {
13721
+ const input = args;
13722
+ const prepared = { ...input };
13723
+ if (prepared.setup_script == null) {
13724
+ delete prepared.setup_script;
13725
+ }
13726
+ return prepared;
13727
+ }
13728
+ async function workspaceWrite(operation) {
13729
+ try {
13730
+ return await operation();
13731
+ } catch (error) {
13732
+ if (error instanceof WorkspaceValidationError) {
13733
+ throw new ToolInputError(error.message);
13734
+ }
13735
+ throw error;
13736
+ }
13737
+ }
13738
+ function describeWorkspaceWrite(action, input) {
13739
+ const repositories = `${input.repos.length} ${input.repos.length === 1 ? "repository" : "repositories"}`;
13740
+ const setupText = input.setup_script ? "; includes a setup script" : "";
13741
+ return `${action} Workspace ${input.name} (${repositories}${setupText}).`;
13742
+ }
13743
+ function createWorkspaceWriteTools(providers) {
13744
+ const { providerNames, workspaceInputSchema } = workspaceWriteSchemas(providers);
13745
+ return {
13746
+ createWorkspace: zodTool({
13747
+ approvalMode: "review",
13748
+ describeProposal: (input) => describeWorkspaceWrite("Create", input),
13749
+ executionMode: "sequential",
13750
+ annotations: {
13751
+ destructiveHint: false,
13752
+ idempotentHint: false,
13753
+ openWorldHint: false,
13754
+ readOnlyHint: false
13755
+ },
13756
+ description: `Create an install-wide Workspace recipe. Repository providers: ${providerNames}. The Workspace becomes available to future conversations.`,
13757
+ inputSchema: workspaceInputSchema,
13758
+ prepareArguments: prepareWorkspaceWriteArguments,
13759
+ outputSchema: juniorToolOutputSchema.extend({
13760
+ workspace: workspaceSchema
13761
+ }),
13762
+ async execute(input) {
13763
+ const workspace = await workspaceWrite(
13764
+ () => createWorkspace(writeInput(input))
13765
+ );
13766
+ return { workspace: view(workspace) };
13767
+ }
13768
+ }),
13769
+ updateWorkspace: zodTool({
13770
+ approvalMode: "review",
13771
+ describeProposal: ({ id: _id, ...input }) => describeWorkspaceWrite("Replace", input),
13772
+ executionMode: "sequential",
13773
+ annotations: {
13774
+ destructiveHint: true,
13775
+ idempotentHint: true,
13776
+ openWorldHint: false,
13777
+ readOnlyHint: false
13778
+ },
13779
+ description: `Replace an install-wide Workspace recipe. Repository providers: ${providerNames}. Use the Workspace ID returned by listWorkspaces.`,
13780
+ inputSchema: workspaceInputSchema.extend({
13781
+ id: z63.string().uuid().describe("Workspace ID from listWorkspaces.")
13782
+ }).strict(),
13783
+ prepareArguments(args) {
13784
+ const input = args;
13785
+ return {
13786
+ ...prepareWorkspaceWriteArguments(input),
13787
+ id: input.id
13788
+ };
13789
+ },
13790
+ outputSchema: juniorToolOutputSchema.extend({
13791
+ workspace: workspaceSchema
13792
+ }),
13793
+ async execute({ id, ...input }) {
13794
+ const workspace = await workspaceWrite(
13795
+ () => updateWorkspace(id, writeInput(input))
13796
+ );
13797
+ if (!workspace) {
13798
+ throw new ToolInputError(`Workspace not found: ${id}`);
13799
+ }
13800
+ return { workspace: view(workspace) };
13801
+ }
13802
+ }),
13803
+ deleteWorkspace: zodTool({
13804
+ approvalMode: "review",
13805
+ describeProposal: ({ id }) => `Delete Workspace ${id}.`,
13806
+ executionMode: "sequential",
13807
+ annotations: {
13808
+ destructiveHint: true,
13809
+ idempotentHint: true,
13810
+ openWorldHint: false,
13811
+ readOnlyHint: false
13812
+ },
13813
+ description: "Delete one install-wide Workspace recipe. Use the Workspace ID returned by listWorkspaces.",
13814
+ inputSchema: z63.object({
13815
+ id: z63.string().uuid().describe("Workspace ID from listWorkspaces.")
13816
+ }).strict(),
13817
+ outputSchema: juniorToolOutputSchema.extend({
13818
+ deleted: z63.literal(true)
13819
+ }),
13820
+ async execute({ id }) {
13821
+ const deleted = await workspaceWrite(() => deleteWorkspace(id));
13822
+ if (!deleted) {
13823
+ throw new ToolInputError(`Workspace not found: ${id}`);
13824
+ }
13825
+ return { deleted: true };
13826
+ }
13827
+ })
13828
+ };
13829
+ }
13704
13830
  function createWorkspaceTools(context) {
13705
13831
  if (!context.workspaces) return {};
13832
+ const providers = workspaceProviderNames();
13706
13833
  return {
13834
+ ...providers ? createWorkspaceWriteTools(providers) : {},
13707
13835
  listWorkspaces: zodTool({
13708
13836
  annotations: {
13709
13837
  destructiveHint: false,
@@ -13711,7 +13839,7 @@ function createWorkspaceTools(context) {
13711
13839
  openWorldHint: false,
13712
13840
  readOnlyHint: true
13713
13841
  },
13714
- description: "List named repository workspaces that can replace the current sandbox. Manage install-wide Workspace recipes from the authenticated dashboard or `/api/workspaces`.",
13842
+ description: "List named repository workspaces that can replace the current sandbox.",
13715
13843
  inputSchema: z63.object({}).strict(),
13716
13844
  outputSchema: juniorToolOutputSchema.extend({
13717
13845
  active_workspace_id: z63.string().nullable(),
@@ -13744,6 +13872,7 @@ function createWorkspaceTools(context) {
13744
13872
  if (!workspace)
13745
13873
  throw new ToolInputError(`Workspace not found: ${name}`);
13746
13874
  await context.workspaces.switch(workspace, options.signal);
13875
+ await tryRecordWorkspaceSwitchStat(workspace);
13747
13876
  return { workspace: view(workspace) };
13748
13877
  }
13749
13878
  })
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseActorUserId
3
- } from "./chunk-V7YE4WCP.js";
3
+ } from "./chunk-M63DETLL.js";
4
4
 
5
5
  // src/chat/credentials/context.ts
6
6
  import { z } from "zod";