@sentry/junior 0.65.0 → 0.66.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 (70) hide show
  1. package/dist/app.d.ts +3 -0
  2. package/dist/app.js +3300 -1342
  3. package/dist/chat/agent-dispatch/heartbeat.d.ts +8 -0
  4. package/dist/chat/agent-dispatch/store.d.ts +2 -2
  5. package/dist/chat/agent-dispatch/types.d.ts +8 -22
  6. package/dist/chat/agent-dispatch/validation.d.ts +3 -1
  7. package/dist/chat/app/production.d.ts +11 -5
  8. package/dist/chat/capabilities/factory.d.ts +2 -1
  9. package/dist/chat/capabilities/router.d.ts +3 -2
  10. package/dist/chat/config.d.ts +5 -0
  11. package/dist/chat/credentials/broker.d.ts +2 -1
  12. package/dist/chat/credentials/context.d.ts +28 -0
  13. package/dist/chat/credentials/subject.d.ts +20 -0
  14. package/dist/chat/ingress/slack-webhook.d.ts +19 -0
  15. package/dist/chat/mcp/errors.d.ts +1 -1
  16. package/dist/chat/plugins/github-permissions.d.ts +11 -0
  17. package/dist/chat/plugins/types.d.ts +2 -0
  18. package/dist/chat/prompt.d.ts +2 -0
  19. package/dist/chat/respond-helpers.d.ts +4 -2
  20. package/dist/chat/respond.d.ts +23 -13
  21. package/dist/chat/runtime/processing-reaction.d.ts +1 -0
  22. package/dist/chat/runtime/reply-executor.d.ts +5 -0
  23. package/dist/chat/runtime/request-deadline.d.ts +8 -0
  24. package/dist/chat/runtime/slack-resume.d.ts +4 -5
  25. package/dist/chat/runtime/slack-runtime.d.ts +10 -0
  26. package/dist/chat/runtime/thread-context.d.ts +5 -2
  27. package/dist/chat/runtime/timeout-resume-runner.d.ts +19 -0
  28. package/dist/chat/runtime/turn-preparation.d.ts +1 -0
  29. package/dist/chat/runtime/turn.d.ts +13 -0
  30. package/dist/chat/sandbox/egress-policy.d.ts +1 -1
  31. package/dist/chat/sandbox/egress-session.d.ts +13 -12
  32. package/dist/chat/sandbox/sandbox.d.ts +2 -3
  33. package/dist/chat/services/timeout-resume.d.ts +9 -4
  34. package/dist/chat/services/turn-session-record.d.ts +19 -2
  35. package/dist/chat/slack/adapter-context.d.ts +25 -0
  36. package/dist/chat/slack/conversation-context.d.ts +28 -0
  37. package/dist/chat/state/turn-session.d.ts +1 -1
  38. package/dist/chat/task-execution/heartbeat.d.ts +13 -0
  39. package/dist/chat/task-execution/queue-signing.d.ts +12 -0
  40. package/dist/chat/task-execution/queue.d.ts +13 -0
  41. package/dist/chat/task-execution/slack-work.d.ts +32 -0
  42. package/dist/chat/task-execution/store.d.ts +153 -0
  43. package/dist/chat/task-execution/vercel-callback.d.ts +21 -0
  44. package/dist/chat/task-execution/vercel-queue.d.ts +16 -0
  45. package/dist/chat/task-execution/worker.d.ts +28 -0
  46. package/dist/{chunk-EDHJIYHS.js → chunk-657CJCUO.js} +218 -62
  47. package/dist/chunk-6YY4Q3D4.js +12 -0
  48. package/dist/chunk-75UZ4JLC.js +213 -0
  49. package/dist/{chunk-PYU2YB35.js → chunk-F57QSMOJ.js} +1 -1
  50. package/dist/{chunk-K3JNVV4Q.js → chunk-HRQQS63X.js} +2 -2
  51. package/dist/{chunk-SCQPBJAU.js → chunk-QUXPUKBH.js} +1 -7
  52. package/dist/{chunk-7KZXQNA6.js → chunk-X2HJLKQT.js} +368 -13
  53. package/dist/{chunk-OMQ5X5QH.js → chunk-ZOV3XJAH.js} +3 -2
  54. package/dist/cli/check.js +115 -2
  55. package/dist/cli/init.js +13 -1
  56. package/dist/cli/snapshot-warmup.js +3 -3
  57. package/dist/deployment.d.ts +4 -0
  58. package/dist/handlers/heartbeat.d.ts +5 -1
  59. package/dist/handlers/turn-resume.d.ts +3 -2
  60. package/dist/handlers/webhooks.d.ts +11 -9
  61. package/dist/instrumentation.js +1 -0
  62. package/dist/nitro.d.ts +3 -1
  63. package/dist/nitro.js +69 -5
  64. package/dist/reporting.js +13 -16
  65. package/dist/vercel.d.ts +1 -1
  66. package/dist/vercel.js +1 -1
  67. package/package.json +5 -4
  68. package/dist/chat/services/turn-continuation-response.d.ts +0 -2
  69. package/dist/chat/slack/turn-continuation-notice.d.ts +0 -8
  70. package/dist/chunk-5VDO6LSG.js +0 -104
@@ -1,3 +1,4 @@
1
+ import { type TimeoutResumeRunnerOptions } from "@/chat/runtime/timeout-resume-runner";
1
2
  import type { WaitUntilFn } from "@/handlers/types";
2
- /** Handle the authenticated internal timeout-resume callback. */
3
- export declare function POST(request: Request, waitUntil: WaitUntilFn): Promise<Response>;
3
+ /** Handle an authenticated internal timeout-resume callback. */
4
+ export declare function POST(request: Request, waitUntil: WaitUntilFn, options?: TimeoutResumeRunnerOptions): Promise<Response>;
@@ -1,15 +1,17 @@
1
+ import type { SlackAdapter } from "@chat-adapter/slack";
2
+ import { JuniorChat } from "@/chat/ingress/junior-chat";
1
3
  import type { WaitUntilFn } from "@/handlers/types";
4
+ type LegacyChatSdkBot = JuniorChat<{
5
+ slack: SlackAdapter;
6
+ }>;
2
7
  /**
3
8
  * Handles `POST /api/webhooks/:platform`.
4
9
  *
5
- * The router only resolves the platform and delegates to the adapter webhook
6
- * implementation; request semantics stay owned by the adapter package.
7
- *
8
- * For Slack, the body is read once and used to detect `message_changed` events
9
- * that introduce a new bot @mention, which the Slack adapter silently ignores.
10
- * The request is then reconstructed so the adapter can consume it normally.
10
+ * Slack production ingress persists messages into the durable conversation
11
+ * mailbox and wakes the queue worker. The optional `legacyBot` parameter is
12
+ * kept for integration tests that still exercise Chat SDK fixtures directly.
11
13
  */
12
- export declare function handlePlatformWebhook(request: Request, platform: string, waitUntil: WaitUntilFn, bot?: import("../chat/ingress/junior-chat").JuniorChat<{
13
- slack: import("@chat-adapter/slack").SlackAdapter;
14
- }>): Promise<Response>;
14
+ export declare function handlePlatformWebhook(request: Request, platform: string, waitUntil: WaitUntilFn, legacyBot?: LegacyChatSdkBot): Promise<Response>;
15
+ /** Handle a platform webhook request from the app route. */
15
16
  export declare function POST(request: Request, platform: string, waitUntil: WaitUntilFn): Promise<Response>;
17
+ export {};
@@ -30,6 +30,7 @@ function initSentry() {
30
30
  sendDefaultPii: true,
31
31
  enabled: Boolean(dsn),
32
32
  enableLogs,
33
+ registerEsmLoaderHooks: false,
33
34
  streamGenAiSpans: true,
34
35
  integrations: [
35
36
  sentry_exports.vercelAIIntegration({
package/dist/nitro.d.ts CHANGED
@@ -9,6 +9,8 @@ export type JuniorNitroPluginSource = JuniorPluginModuleReference | JuniorPlugin
9
9
  export interface JuniorNitroOptions {
10
10
  cwd?: string;
11
11
  maxDuration?: number;
12
+ /** Vercel Queue topic for durable conversation work. Must match the runtime queue producer topic. */
13
+ conversationWorkQueueTopic?: string;
12
14
  /** Plugin catalog set or runtime-safe plugin module. Direct sets must not include trusted hooks. */
13
15
  plugins?: JuniorNitroPluginSource;
14
16
  /**
@@ -19,7 +21,7 @@ export interface JuniorNitroOptions {
19
21
  */
20
22
  includeFiles?: string[];
21
23
  }
22
- /** Nitro module that copies app and plugin content into the Vercel build output. */
24
+ /** Nitro module that configures deployment wiring and copies app/plugin content into the Vercel build output. */
23
25
  export declare function juniorNitro(options?: JuniorNitroOptions): {
24
26
  nitro: {
25
27
  setup(nitro: unknown): void;
package/dist/nitro.js CHANGED
@@ -1,7 +1,13 @@
1
1
  import {
2
+ DEFAULT_CONVERSATION_WORK_QUEUE_TOPIC,
2
3
  pluginCatalogConfigFromPluginSet,
3
4
  trustedPluginRegistrationsFromPluginSet
4
- } from "./chunk-5VDO6LSG.js";
5
+ } from "./chunk-75UZ4JLC.js";
6
+ import {
7
+ JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE,
8
+ JUNIOR_HEARTBEAT_CRON_SCHEDULE,
9
+ JUNIOR_HEARTBEAT_ROUTE
10
+ } from "./chunk-6YY4Q3D4.js";
5
11
  import {
6
12
  discoverInstalledPluginPackageContent,
7
13
  isValidPackageName,
@@ -207,6 +213,8 @@ function injectVirtualConfig(nitro, options = {}) {
207
213
  }
208
214
 
209
215
  // src/nitro.ts
216
+ var DEFAULT_FUNCTION_MAX_DURATION_SECONDS = 300;
217
+ var VERCEL_QUEUE_TRIGGER_TYPE = "queue/v2beta";
210
218
  var PLUGIN_MODULE_EXTENSIONS = [
211
219
  "",
212
220
  ".ts",
@@ -302,6 +310,53 @@ function assertSerializableDirectPluginSet(pluginSet) {
302
310
  `juniorNitro({ plugins }) cannot receive a direct defineJuniorPlugins(...) set with trusted plugin registration(s): ${trustedPluginNames.join(", ")}. Export the set from a runtime-safe plugin module and pass juniorNitro({ plugins: "./plugins" }) so createApp() can import the same hooks at runtime.`
303
311
  );
304
312
  }
313
+ function resolveConversationWorkQueueTopic(options) {
314
+ return options.conversationWorkQueueTopic?.trim() || process.env.JUNIOR_CONVERSATION_WORK_QUEUE_TOPIC?.trim() || DEFAULT_CONVERSATION_WORK_QUEUE_TOPIC;
315
+ }
316
+ function bundleOpenTelemetryLoaderHooks(nitro) {
317
+ const existing = Array.isArray(nitro.options.noExternals) ? nitro.options.noExternals : [];
318
+ const additions = ["import-in-the-middle", "require-in-the-middle"].filter(
319
+ (pkg) => !existing.includes(pkg)
320
+ );
321
+ if (additions.length > 0) {
322
+ nitro.options.noExternals = [...existing, ...additions];
323
+ }
324
+ }
325
+ function configureVercelDeployment(nitro, options) {
326
+ const defaultMaxDuration = options.maxDuration ?? DEFAULT_FUNCTION_MAX_DURATION_SECONDS;
327
+ const queueTopic = resolveConversationWorkQueueTopic(options);
328
+ nitro.options.vercel ??= {};
329
+ nitro.options.vercel.config ??= { version: 3 };
330
+ nitro.options.vercel.config.crons ??= [];
331
+ if (!nitro.options.vercel.config.crons.some(
332
+ (cron) => cron.path === JUNIOR_HEARTBEAT_ROUTE
333
+ )) {
334
+ nitro.options.vercel.config.crons.push({
335
+ path: JUNIOR_HEARTBEAT_ROUTE,
336
+ schedule: JUNIOR_HEARTBEAT_CRON_SCHEDULE
337
+ });
338
+ }
339
+ nitro.options.vercel.functions ??= {};
340
+ nitro.options.vercel.functions.maxDuration ??= defaultMaxDuration;
341
+ const callbackMaxDuration = nitro.options.vercel.functions.maxDuration ?? defaultMaxDuration;
342
+ nitro.options.vercel.functionRules ??= {};
343
+ const existingRule = nitro.options.vercel.functionRules[JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE] ?? {};
344
+ const existingTriggers = Array.isArray(existingRule.experimentalTriggers) ? existingRule.experimentalTriggers : [];
345
+ const otherTriggers = existingTriggers.filter(
346
+ (trigger) => trigger.type !== VERCEL_QUEUE_TRIGGER_TYPE
347
+ );
348
+ nitro.options.vercel.functionRules[JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE] = {
349
+ maxDuration: callbackMaxDuration,
350
+ ...existingRule,
351
+ experimentalTriggers: [
352
+ ...otherTriggers,
353
+ {
354
+ type: VERCEL_QUEUE_TRIGGER_TYPE,
355
+ topic: queueTopic
356
+ }
357
+ ]
358
+ };
359
+ }
305
360
  function juniorNitro(options = {}) {
306
361
  return {
307
362
  nitro: {
@@ -309,9 +364,8 @@ function juniorNitro(options = {}) {
309
364
  const cwd = path2.resolve(
310
365
  options.cwd ?? nitro.options.rootDir ?? process.cwd()
311
366
  );
312
- nitro.options.vercel ??= {};
313
- nitro.options.vercel.functions ??= {};
314
- nitro.options.vercel.functions.maxDuration ??= options.maxDuration ?? 800;
367
+ configureVercelDeployment(nitro, options);
368
+ bundleOpenTelemetryLoaderHooks(nitro);
315
369
  applyRolldownTreeshakeWorkaround(nitro);
316
370
  const pluginSource = options.plugins;
317
371
  const pluginModule = isPluginModuleReference(pluginSource) ? resolvePluginModule(cwd, pluginSource) : void 0;
@@ -336,7 +390,7 @@ function juniorNitro(options = {}) {
336
390
  plugins: pluginCatalogConfig,
337
391
  trustedPluginRegistrations
338
392
  });
339
- nitro.hooks.hook("compiled", async () => {
393
+ const copyBuildContent = async () => {
340
394
  const pluginSet = await loadConfiguredPluginSet();
341
395
  const compiledPluginCatalogConfig = pluginCatalogConfigFromPluginSet(pluginSet);
342
396
  copyAppAndPluginContent(
@@ -349,6 +403,16 @@ function juniorNitro(options = {}) {
349
403
  nitro.options.output.serverDir,
350
404
  options.includeFiles
351
405
  );
406
+ };
407
+ nitro.hooks.hook("rollup:before", (_nitro, config) => {
408
+ const buildConfig = config;
409
+ buildConfig.plugins ??= [];
410
+ buildConfig.plugins.push({
411
+ name: "junior:copy-build-content",
412
+ async writeBundle() {
413
+ await copyBuildContent();
414
+ }
415
+ });
352
416
  });
353
417
  }
354
418
  }
package/dist/reporting.js CHANGED
@@ -3,23 +3,25 @@ import {
3
3
  buildSentryConversationUrl,
4
4
  buildSentryTraceUrl,
5
5
  buildSystemPrompt,
6
+ formatSlackConversationRedactedLabel,
6
7
  getAgentTurnSessionRecord,
7
8
  listAgentTurnSessionSummaries,
8
- listAgentTurnSessionSummariesForConversation
9
- } from "./chunk-7KZXQNA6.js";
9
+ listAgentTurnSessionSummariesForConversation,
10
+ resolveSlackConversationContextFromThreadId
11
+ } from "./chunk-X2HJLKQT.js";
10
12
  import {
11
13
  discoverSkills
12
- } from "./chunk-PYU2YB35.js";
14
+ } from "./chunk-F57QSMOJ.js";
13
15
  import {
14
16
  canExposeConversationPayload,
15
17
  parseSlackThreadId,
16
18
  resolveConversationPrivacy
17
- } from "./chunk-OMQ5X5QH.js";
19
+ } from "./chunk-ZOV3XJAH.js";
18
20
  import {
19
21
  getPluginPackageContent,
20
22
  getPluginProviders,
21
23
  isRecord
22
- } from "./chunk-EDHJIYHS.js";
24
+ } from "./chunk-657CJCUO.js";
23
25
  import "./chunk-Z3YD6NHK.js";
24
26
  import {
25
27
  homeDir
@@ -31,6 +33,7 @@ import { readFileSync } from "fs";
31
33
  import path from "path";
32
34
  var HUNG_TURN_PROGRESS_MS = 5 * 60 * 1e3;
33
35
  var SAFE_METADATA_KEY_LIMIT = 20;
36
+ var PRIVATE_CONVERSATION_LABEL = "Private Conversation";
34
37
  function readDescriptionText() {
35
38
  try {
36
39
  const raw = readFileSync(
@@ -80,16 +83,6 @@ function titleFromSummary(summary) {
80
83
  }
81
84
  return `Turn ${summary.sessionId}`;
82
85
  }
83
- function safePrivateLabel(summary) {
84
- const slackThread = parseSlackThreadId(summary.conversationId);
85
- if (slackThread?.channelId.startsWith("D")) {
86
- return "Direct Message";
87
- }
88
- if (slackThread?.channelId.startsWith("G")) {
89
- return summary.channelName?.startsWith("mpdm-") ? "Group DM" : "Private Channel";
90
- }
91
- return "Private Channel";
92
- }
93
86
  function requesterIdentityReport(requester) {
94
87
  if (!requester) return void 0;
95
88
  const identity = {
@@ -116,7 +109,11 @@ function sessionReportFromSummary(summary) {
116
109
  const privacy = resolveConversationPrivacy({
117
110
  conversationId: summary.conversationId
118
111
  });
119
- const privateLabel = privacy !== "public" ? safePrivateLabel(summary) : void 0;
112
+ const slackConversation = resolveSlackConversationContextFromThreadId({
113
+ threadId: summary.conversationId,
114
+ channelName: summary.channelName
115
+ });
116
+ const privateLabel = privacy !== "public" ? slackConversation ? formatSlackConversationRedactedLabel(slackConversation) : PRIVATE_CONVERSATION_LABEL : void 0;
120
117
  const conversationTitle = privateLabel ?? summary.conversationTitle;
121
118
  const channelName = privateLabel ?? summary.channelName;
122
119
  const sentryConversationUrl = buildSentryConversationUrl(
package/dist/vercel.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export interface JuniorVercelConfigOptions {
2
2
  buildCommand?: string | null;
3
3
  }
4
- /** Return a minimal Vercel config for scaffolded Junior apps. */
4
+ /** Return the root Vercel project config for scaffolded Junior apps. */
5
5
  export declare function juniorVercelConfig(options?: JuniorVercelConfigOptions): Record<string, unknown>;
package/dist/vercel.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  juniorVercelConfig
3
- } from "./chunk-SCQPBJAU.js";
3
+ } from "./chunk-QUXPUKBH.js";
4
4
  import "./chunk-2KG3PWR4.js";
5
5
  export {
6
6
  juniorVercelConfig
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior",
3
- "version": "0.65.0",
3
+ "version": "0.66.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -54,6 +54,7 @@
54
54
  "@slack/web-api": "^7.16.0",
55
55
  "@sentry/node": "10.53.1",
56
56
  "@vercel/functions": "^3.6.0",
57
+ "@vercel/queue": "^0.2.0",
57
58
  "@vercel/sandbox": "2.0.0",
58
59
  "ai": "^6.0.190",
59
60
  "bash-tool": "^1.3.16",
@@ -64,7 +65,7 @@
64
65
  "node-html-markdown": "^2.0.0",
65
66
  "yaml": "^2.9.0",
66
67
  "zod": "^4.4.3",
67
- "@sentry/junior-plugin-api": "0.65.0"
68
+ "@sentry/junior-plugin-api": "0.66.0"
68
69
  },
69
70
  "devDependencies": {
70
71
  "@types/node": "^25.9.1",
@@ -76,13 +77,13 @@
76
77
  "typescript": "^6.0.3",
77
78
  "vercel": "^54.4.0",
78
79
  "vitest": "^4.1.7",
79
- "@sentry/junior-scheduler": "0.65.0"
80
+ "@sentry/junior-scheduler": "0.66.0"
80
81
  },
81
82
  "scripts": {
82
83
  "build": "tsup && tsc -p tsconfig.build.json --emitDeclarationOnly",
83
84
  "lint": "oxlint --config .oxlintrc.json --deny-warnings src tests scripts bin tsup.config.ts",
84
85
  "lint:fix": "oxlint --config .oxlintrc.json --deny-warnings --fix src tests scripts bin tsup.config.ts",
85
- "test": "pnpm run test:slack-boundary && pnpm run test:arch-boundary && vitest run",
86
+ "test": "pnpm run test:slack-boundary && pnpm run test:arch-boundary && vitest run --maxWorkers=4",
86
87
  "test:watch": "vitest",
87
88
  "test:slack-boundary": "node scripts/check-slack-test-boundary.mjs",
88
89
  "test:arch-boundary": "depcruise --config .dependency-cruiser.mjs src/chat",
@@ -1,2 +0,0 @@
1
- /** Build the user-facing response for a turn parked for continuation. */
2
- export declare function buildTurnContinuationResponse(): string;
@@ -1,8 +0,0 @@
1
- import { type SlackMessageBlock } from "@/chat/slack/footer";
2
- /** Build the Slack timeout-continuation acknowledgement with correlation-only metadata. */
3
- export declare function buildSlackTurnContinuationNotice(args: {
4
- conversationId?: string;
5
- }): {
6
- blocks?: SlackMessageBlock[];
7
- text: string;
8
- };
@@ -1,104 +0,0 @@
1
- // src/plugins.ts
2
- function cloneManifests(manifests) {
3
- return manifests ? structuredClone(manifests) : void 0;
4
- }
5
- function cloneInlineManifests(registrations) {
6
- const inlineManifests = registrations.flatMap(
7
- (plugin) => plugin.manifest ? [
8
- {
9
- manifest: {
10
- ...structuredClone(plugin.manifest),
11
- capabilities: plugin.manifest.capabilities?.map(
12
- (capability) => capability.includes(".") ? capability : `${plugin.manifest.name}.${capability}`
13
- ) ?? [],
14
- configKeys: plugin.manifest.configKeys?.map(
15
- (key) => key.includes(".") ? key : `${plugin.manifest.name}.${key}`
16
- ) ?? [],
17
- ...plugin.manifest.target ? {
18
- target: {
19
- ...plugin.manifest.target,
20
- configKey: plugin.manifest.target.configKey.includes(".") ? plugin.manifest.target.configKey : `${plugin.manifest.name}.${plugin.manifest.target.configKey}`
21
- }
22
- } : {}
23
- },
24
- ...plugin.packageName ? { packageName: plugin.packageName } : {}
25
- }
26
- ] : []
27
- );
28
- return inlineManifests.length > 0 ? inlineManifests : void 0;
29
- }
30
- function assertUniquePluginNames(registrations) {
31
- const seen = /* @__PURE__ */ new Set();
32
- for (const plugin of registrations) {
33
- if (seen.has(plugin.name)) {
34
- throw new Error(`Duplicate plugin registration name "${plugin.name}"`);
35
- }
36
- seen.add(plugin.name);
37
- }
38
- }
39
- function assertUniquePackageNames(packageNames) {
40
- const seen = /* @__PURE__ */ new Set();
41
- for (const packageName of packageNames) {
42
- if (seen.has(packageName)) {
43
- throw new Error(`Duplicate plugin package name "${packageName}"`);
44
- }
45
- seen.add(packageName);
46
- }
47
- }
48
- function normalizePluginInput(input) {
49
- if (typeof input === "string") {
50
- return { packageName: input };
51
- }
52
- return { registration: input };
53
- }
54
- function defineJuniorPlugins(inputs, options = {}) {
55
- const normalized = inputs.map(normalizePluginInput);
56
- const packageNames = normalized.flatMap(
57
- (input) => input.packageName ? [input.packageName] : []
58
- );
59
- const registrations = normalized.flatMap(
60
- (input) => input.registration ? [input.registration] : []
61
- );
62
- assertUniquePackageNames(packageNames);
63
- assertUniquePluginNames(registrations);
64
- const manifests = cloneManifests(options.manifests);
65
- return {
66
- packageNames,
67
- registrations: registrations.map((plugin) => ({ ...plugin })),
68
- ...manifests ? { manifests } : {}
69
- };
70
- }
71
- function pluginCatalogConfigFromPluginSet(pluginSet) {
72
- if (!pluginSet) {
73
- return void 0;
74
- }
75
- const packages = [
76
- .../* @__PURE__ */ new Set([
77
- ...pluginSet.packageNames,
78
- ...pluginSet.registrations.flatMap(
79
- (plugin) => plugin.packageName ? [plugin.packageName] : []
80
- )
81
- ])
82
- ];
83
- const manifests = cloneManifests(pluginSet.manifests);
84
- const inlineManifests = cloneInlineManifests(pluginSet.registrations);
85
- if (packages.length === 0 && !manifests && !inlineManifests) {
86
- return void 0;
87
- }
88
- return {
89
- ...inlineManifests ? { inlineManifests } : {},
90
- ...packages.length > 0 ? { packages } : {},
91
- ...manifests ? { manifests } : {}
92
- };
93
- }
94
- function trustedPluginRegistrationsFromPluginSet(pluginSet) {
95
- return pluginSet?.registrations.filter(
96
- (plugin) => plugin.hooks || plugin.legacyStatePrefixes
97
- ) ?? [];
98
- }
99
-
100
- export {
101
- defineJuniorPlugins,
102
- pluginCatalogConfigFromPluginSet,
103
- trustedPluginRegistrationsFromPluginSet
104
- };