@sentry/junior 0.66.0 → 0.66.1

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.
package/dist/app.js CHANGED
@@ -36,13 +36,13 @@ import {
36
36
  truncateStatusText,
37
37
  upsertAgentTurnSessionRecord,
38
38
  withSlackRetries
39
- } from "./chunk-X2HJLKQT.js";
39
+ } from "./chunk-DG2I6GXC.js";
40
40
  import {
41
41
  discoverSkills,
42
42
  findSkillByName,
43
43
  loadSkillsByName,
44
44
  parseSkillInvocation
45
- } from "./chunk-F57QSMOJ.js";
45
+ } from "./chunk-YL5G5YC4.js";
46
46
  import {
47
47
  buildNonInteractiveShellScript,
48
48
  createSandboxInstance,
@@ -51,7 +51,7 @@ import {
51
51
  isSnapshotMissingError,
52
52
  resolveRuntimeDependencySnapshot,
53
53
  runNonInteractiveCommand
54
- } from "./chunk-HRQQS63X.js";
54
+ } from "./chunk-JA5QR3N4.js";
55
55
  import {
56
56
  ACTIVE_LOCK_TTL_MS,
57
57
  FUNCTION_TIMEOUT_BUFFER_SECONDS,
@@ -86,7 +86,7 @@ import {
86
86
  toGenAiPayloadMetadata,
87
87
  toGenAiPayloadTraceAttributes,
88
88
  toGenAiTextMetadata
89
- } from "./chunk-ZOV3XJAH.js";
89
+ } from "./chunk-SAYCFF7O.js";
90
90
  import {
91
91
  CredentialUnavailableError,
92
92
  buildOAuthTokenRequest,
@@ -127,7 +127,7 @@ import {
127
127
  toOptionalString,
128
128
  withContext,
129
129
  withSpan
130
- } from "./chunk-657CJCUO.js";
130
+ } from "./chunk-6QWWMZCK.js";
131
131
  import {
132
132
  sentry_exports
133
133
  } from "./chunk-Z3YD6NHK.js";
@@ -3616,6 +3616,7 @@ export {
3616
3616
  resolvePluginCommandEnv,
3617
3617
  resolveAuthTokenPlaceholder,
3618
3618
  parsePluginManifest,
3619
+ parseInlinePluginManifest,
3619
3620
  CredentialUnavailableError,
3620
3621
  parseCredentialContext,
3621
3622
  hasRequiredOAuthScope,
@@ -8,12 +8,12 @@ import {
8
8
  getStateAdapter,
9
9
  parseSlackThreadId,
10
10
  sandboxSkillDir
11
- } from "./chunk-ZOV3XJAH.js";
11
+ } from "./chunk-SAYCFF7O.js";
12
12
  import {
13
13
  isRecord,
14
14
  logInfo,
15
15
  logWarn
16
- } from "./chunk-657CJCUO.js";
16
+ } from "./chunk-6QWWMZCK.js";
17
17
  import {
18
18
  sentry_exports
19
19
  } from "./chunk-Z3YD6NHK.js";
@@ -2,12 +2,12 @@ import {
2
2
  SANDBOX_WORKSPACE_ROOT,
3
3
  getStateAdapter,
4
4
  toOptionalTrimmed
5
- } from "./chunk-ZOV3XJAH.js";
5
+ } from "./chunk-SAYCFF7O.js";
6
6
  import {
7
7
  getPluginRuntimeDependencies,
8
8
  getPluginRuntimePostinstall,
9
9
  withSpan
10
- } from "./chunk-657CJCUO.js";
10
+ } from "./chunk-6QWWMZCK.js";
11
11
 
12
12
  // src/chat/sandbox/runtime-dependency-snapshots.ts
13
13
  import { createHash } from "crypto";
@@ -6,7 +6,7 @@ import {
6
6
  setSpanAttributes,
7
7
  toOptionalString,
8
8
  withSpan
9
- } from "./chunk-657CJCUO.js";
9
+ } from "./chunk-6QWWMZCK.js";
10
10
 
11
11
  // src/chat/slack/context.ts
12
12
  function toTrimmedSlackString(value) {
@@ -2,7 +2,7 @@ import {
2
2
  getPluginForSkillPath,
3
3
  getPluginSkillRoots,
4
4
  logWarn
5
- } from "./chunk-657CJCUO.js";
5
+ } from "./chunk-6QWWMZCK.js";
6
6
  import {
7
7
  skillRoots
8
8
  } from "./chunk-KVZL5NZS.js";
package/dist/cli/check.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import {
2
2
  parseSkillFile
3
- } from "../chunk-F57QSMOJ.js";
3
+ } from "../chunk-YL5G5YC4.js";
4
4
  import {
5
+ parseInlinePluginManifest,
5
6
  parsePluginManifest
6
- } from "../chunk-657CJCUO.js";
7
+ } from "../chunk-6QWWMZCK.js";
7
8
  import "../chunk-Z3YD6NHK.js";
8
9
  import {
9
10
  JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE,
@@ -16,6 +17,7 @@ import "../chunk-2KG3PWR4.js";
16
17
  // src/cli/check.ts
17
18
  import fs from "fs/promises";
18
19
  import path from "path";
20
+ import { pathToFileURL } from "url";
19
21
  var DEFAULT_IO = {
20
22
  info: console.log,
21
23
  warn: console.warn,
@@ -187,35 +189,12 @@ async function validatePluginDirectory(pluginDir, duplicatePluginNames, duplicat
187
189
  try {
188
190
  const raw = await fs.readFile(manifestPath, "utf8");
189
191
  const manifest = parsePluginManifest(raw, pluginDir);
190
- const errors = [];
191
- const firstSeen = duplicatePluginNames.get(manifest.name);
192
- if (firstSeen) {
193
- errors.push(
194
- `${manifestPath}: duplicate plugin name "${manifest.name}" (already defined in ${firstSeen})`
195
- );
196
- }
197
- const domains = [
198
- .../* @__PURE__ */ new Set([
199
- ...manifest.credentials?.domains ?? [],
200
- ...manifest.domains ?? []
201
- ])
202
- ];
203
- for (const domain of domains) {
204
- const firstDomainSeen = duplicateProviderDomains.get(domain);
205
- if (firstDomainSeen) {
206
- errors.push(
207
- `${manifestPath}: duplicate provider domain "${domain}" (already defined in ${firstDomainSeen})`
208
- );
209
- }
210
- }
211
- if (errors.length > 0) {
212
- return { manifestPath, manifest, errors };
213
- }
214
- duplicatePluginNames.set(manifest.name, manifestPath);
215
- for (const domain of domains) {
216
- duplicateProviderDomains.set(domain, manifestPath);
217
- }
218
- return { manifestPath, manifest, errors: [] };
192
+ return validatePluginManifest(
193
+ manifestPath,
194
+ manifest,
195
+ duplicatePluginNames,
196
+ duplicateProviderDomains
197
+ );
219
198
  } catch (error) {
220
199
  return {
221
200
  manifestPath,
@@ -225,6 +204,135 @@ async function validatePluginDirectory(pluginDir, duplicatePluginNames, duplicat
225
204
  };
226
205
  }
227
206
  }
207
+ function validatePluginManifest(manifestPath, manifest, duplicatePluginNames, duplicateProviderDomains) {
208
+ const errors = [];
209
+ const firstSeen = duplicatePluginNames.get(manifest.name);
210
+ if (firstSeen) {
211
+ errors.push(
212
+ `${manifestPath}: duplicate plugin name "${manifest.name}" (already defined in ${firstSeen})`
213
+ );
214
+ }
215
+ const domains = [
216
+ .../* @__PURE__ */ new Set([
217
+ ...manifest.credentials?.domains ?? [],
218
+ ...manifest.domains ?? []
219
+ ])
220
+ ];
221
+ for (const domain of domains) {
222
+ const firstDomainSeen = duplicateProviderDomains.get(domain);
223
+ if (firstDomainSeen) {
224
+ errors.push(
225
+ `${manifestPath}: duplicate provider domain "${domain}" (already defined in ${firstDomainSeen})`
226
+ );
227
+ }
228
+ }
229
+ if (errors.length > 0) {
230
+ return { manifestPath, manifest, errors };
231
+ }
232
+ duplicatePluginNames.set(manifest.name, manifestPath);
233
+ for (const domain of domains) {
234
+ duplicateProviderDomains.set(domain, manifestPath);
235
+ }
236
+ return { manifestPath, manifest, errors: [] };
237
+ }
238
+ function packageExportsEntryPath(exportsValue) {
239
+ if (typeof exportsValue === "string") {
240
+ return exportsValue;
241
+ }
242
+ if (!isRecord(exportsValue)) {
243
+ return void 0;
244
+ }
245
+ const rootExport = exportsValue["."] ?? exportsValue;
246
+ if (typeof rootExport === "string") {
247
+ return rootExport;
248
+ }
249
+ if (!isRecord(rootExport)) {
250
+ return void 0;
251
+ }
252
+ for (const condition of ["default", "import", "node"]) {
253
+ const target = rootExport[condition];
254
+ if (typeof target === "string") {
255
+ return target;
256
+ }
257
+ }
258
+ return void 0;
259
+ }
260
+ async function resolvePackageEntryPath(packageDir) {
261
+ const packageJson = await readJsonFile(
262
+ path.join(packageDir, "package.json")
263
+ );
264
+ const entry = packageExportsEntryPath(packageJson?.exports) ?? packageJson?.main;
265
+ const candidates = [
266
+ ...entry ? [entry] : [],
267
+ "./index.js",
268
+ "./dist/index.js"
269
+ ];
270
+ for (const candidate of candidates) {
271
+ if (path.isAbsolute(candidate) || candidate.startsWith("../")) {
272
+ continue;
273
+ }
274
+ const normalizedCandidate = candidate.startsWith("./") ? candidate : `./${candidate}`;
275
+ const entryPath = path.resolve(packageDir, normalizedCandidate);
276
+ if (await pathIsFile(entryPath)) {
277
+ return entryPath;
278
+ }
279
+ }
280
+ return void 0;
281
+ }
282
+ function isPluginFactoryExport(name, value) {
283
+ return typeof value === "function" && (name === "default" || name.endsWith("Plugin"));
284
+ }
285
+ function isPluginRegistrationLike(value) {
286
+ return isRecord(value) && isRecord(value.manifest);
287
+ }
288
+ async function collectPackageJsPluginSources(packageDir, packageName) {
289
+ const entryPath = await resolvePackageEntryPath(packageDir);
290
+ if (!entryPath) {
291
+ return [];
292
+ }
293
+ let moduleExports;
294
+ try {
295
+ moduleExports = await import(pathToFileURL(entryPath).href);
296
+ } catch {
297
+ return [];
298
+ }
299
+ const pluginSources = [];
300
+ for (const [exportName, exportedValue] of Object.entries(moduleExports).sort(
301
+ ([left], [right]) => left.localeCompare(right)
302
+ )) {
303
+ if (!isPluginFactoryExport(exportName, exportedValue)) {
304
+ continue;
305
+ }
306
+ let registration;
307
+ try {
308
+ registration = await exportedValue();
309
+ } catch {
310
+ continue;
311
+ }
312
+ if (!isPluginRegistrationLike(registration)) {
313
+ continue;
314
+ }
315
+ const manifestPath = `${entryPath}#${exportName}`;
316
+ try {
317
+ pluginSources.push({
318
+ pluginDir: packageDir,
319
+ packageName,
320
+ manifestPath,
321
+ manifest: parseInlinePluginManifest(registration.manifest, packageDir)
322
+ });
323
+ } catch (error) {
324
+ pluginSources.push({
325
+ pluginDir: packageDir,
326
+ packageName,
327
+ manifestPath,
328
+ errors: [
329
+ `${manifestPath}: ${error instanceof Error ? error.message : String(error)}`
330
+ ]
331
+ });
332
+ }
333
+ }
334
+ return pluginSources;
335
+ }
228
336
  async function collectPluginDirectories(rootDir) {
229
337
  const pluginDirs = [];
230
338
  let entries;
@@ -247,7 +355,7 @@ async function collectPluginDirectories(rootDir) {
247
355
  return pluginDirs.sort((left, right) => left.localeCompare(right));
248
356
  }
249
357
  async function collectPackagedContent(rootDir, packages) {
250
- const pluginDirs = [];
358
+ const pluginSources = [];
251
359
  const skillRoots = [];
252
360
  for (const declaredPackage of packages) {
253
361
  const packageDir = packageInstallDir(rootDir, declaredPackage.name);
@@ -257,16 +365,26 @@ async function collectPackagedContent(rootDir, packages) {
257
365
  const rootManifestPath = path.join(packageDir, "plugin.yaml");
258
366
  const hasRootManifest = await pathIsFile(rootManifestPath);
259
367
  const packageSkillsRoot = path.join(packageDir, "skills");
368
+ const hasPackageSkills = await pathIsDirectory(packageSkillsRoot);
260
369
  if (hasRootManifest) {
261
- pluginDirs.push({
370
+ pluginSources.push({
262
371
  pluginDir: packageDir,
372
+ manifestPath: rootManifestPath,
263
373
  packageName: declaredPackage.name
264
374
  });
265
- } else if (await pathIsDirectory(packageSkillsRoot)) {
266
- skillRoots.push({
267
- root: packageSkillsRoot,
268
- packageName: declaredPackage.name
269
- });
375
+ } else if (hasPackageSkills) {
376
+ const jsPluginSources = await collectPackageJsPluginSources(
377
+ packageDir,
378
+ declaredPackage.name
379
+ );
380
+ if (jsPluginSources.length > 0) {
381
+ pluginSources.push(...jsPluginSources);
382
+ } else {
383
+ skillRoots.push({
384
+ root: packageSkillsRoot,
385
+ packageName: declaredPackage.name
386
+ });
387
+ }
270
388
  }
271
389
  const nestedPluginsRoot = path.join(packageDir, "plugins");
272
390
  let nestedEntries;
@@ -283,15 +401,16 @@ async function collectPackagedContent(rootDir, packages) {
283
401
  }
284
402
  const pluginDir = path.join(nestedPluginsRoot, entry.name);
285
403
  if (await pathIsFile(path.join(pluginDir, "plugin.yaml"))) {
286
- pluginDirs.push({
404
+ pluginSources.push({
287
405
  pluginDir,
406
+ manifestPath: path.join(pluginDir, "plugin.yaml"),
288
407
  packageName: declaredPackage.name
289
408
  });
290
409
  }
291
410
  }
292
411
  }
293
412
  return {
294
- pluginDirs: pluginDirs.sort(
413
+ pluginSources: pluginSources.sort(
295
414
  (left, right) => `${left.packageName}:${left.pluginDir}`.localeCompare(
296
415
  `${right.packageName}:${right.pluginDir}`
297
416
  )
@@ -571,18 +690,18 @@ async function runCheck(rootDir = process.cwd(), io = DEFAULT_IO) {
571
690
  const packageWarnings = await collectPackageWarnings(resolvedRoot, packages);
572
691
  const packagedContent = await collectPackagedContent(resolvedRoot, packages);
573
692
  const appPluginDirs = await collectPluginDirectories(resolvedRoot);
574
- const packagedPluginDirs = packagedContent.pluginDirs;
575
- const pluginDirs = [
693
+ const packagedPluginSources = packagedContent.pluginSources;
694
+ const pluginSources = [
576
695
  ...appPluginDirs.map((pluginDir) => ({
577
696
  pluginDir,
578
- packageName: void 0
697
+ manifestPath: path.join(pluginDir, "plugin.yaml")
579
698
  })),
580
- ...packagedPluginDirs
699
+ ...packagedPluginSources
581
700
  ];
582
701
  const appSkillsRoot = contentRoot(resolvedRoot, "skills");
583
702
  const appSkillDirs = await collectSkillDirectories(appSkillsRoot);
584
703
  const pluginSkillDirs = /* @__PURE__ */ new Map();
585
- for (const { pluginDir } of pluginDirs) {
704
+ for (const { pluginDir } of pluginSources) {
586
705
  pluginSkillDirs.set(
587
706
  pluginDir,
588
707
  await collectSkillDirectories(path.join(pluginDir, "skills"))
@@ -605,7 +724,7 @@ async function runCheck(rootDir = process.cwd(), io = DEFAULT_IO) {
605
724
  )
606
725
  ].sort((left, right) => left.localeCompare(right));
607
726
  const packagedSkillDirs = [
608
- ...packagedPluginDirs.flatMap(
727
+ ...packagedPluginSources.flatMap(
609
728
  ({ pluginDir }) => pluginSkillDirs.get(pluginDir) ?? []
610
729
  ),
611
730
  ...packagedStandaloneSkillDirs
@@ -630,10 +749,20 @@ async function runCheck(rootDir = process.cwd(), io = DEFAULT_IO) {
630
749
  );
631
750
  warnings.push(...deploymentConfigResult.warnings);
632
751
  errors.push(...deploymentConfigResult.errors);
633
- for (const { pluginDir, packageName } of pluginDirs) {
752
+ for (const source of pluginSources) {
753
+ const { pluginDir, packageName } = source;
634
754
  const pluginNameMap = packageName ? duplicatePackagedPluginNames : duplicatePluginNames;
635
755
  const providerDomainMap = packageName ? duplicatePackagedProviderDomains : duplicateProviderDomains;
636
- const result = await validatePluginDirectory(
756
+ const result = source.errors ? {
757
+ manifestPath: source.manifestPath,
758
+ ...source.manifest ? { manifest: source.manifest } : {},
759
+ errors: source.errors
760
+ } : source.manifest ? validatePluginManifest(
761
+ source.manifestPath,
762
+ source.manifest,
763
+ pluginNameMap,
764
+ providerDomainMap
765
+ ) : await validatePluginDirectory(
637
766
  pluginDir,
638
767
  pluginNameMap,
639
768
  providerDomainMap
@@ -741,11 +870,11 @@ async function runCheck(rootDir = process.cwd(), io = DEFAULT_IO) {
741
870
  io.error(`${statusIcon("error")} error: ${error}`);
742
871
  }
743
872
  throw new Error(
744
- `Validation failed (${errors.length} error${errors.length === 1 ? "" : "s"}, ${pluginDirs.length} plugin manifest${pluginDirs.length === 1 ? "" : "s"}, ${skillDirs.length} skill director${skillDirs.length === 1 ? "y" : "ies"} checked).`
873
+ `Validation failed (${errors.length} error${errors.length === 1 ? "" : "s"}, ${pluginSources.length} plugin manifest${pluginSources.length === 1 ? "" : "s"}, ${skillDirs.length} skill director${skillDirs.length === 1 ? "y" : "ies"} checked).`
745
874
  );
746
875
  }
747
876
  io.info(
748
- `${formatHeading("ok", `Validation passed (${pluginDirs.length} plugin manifest${pluginDirs.length === 1 ? "" : "s"}, ${skillDirs.length} skill director${skillDirs.length === 1 ? "y" : "ies"} checked).`)}`
877
+ `${formatHeading("ok", `Validation passed (${pluginSources.length} plugin manifest${pluginSources.length === 1 ? "" : "s"}, ${skillDirs.length} skill director${skillDirs.length === 1 ? "y" : "ies"} checked).`)}`
749
878
  );
750
879
  }
751
880
  export {
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  resolveRuntimeDependencySnapshot
3
- } from "../chunk-HRQQS63X.js";
3
+ } from "../chunk-JA5QR3N4.js";
4
4
  import {
5
5
  disconnectStateAdapter
6
- } from "../chunk-ZOV3XJAH.js";
6
+ } from "../chunk-SAYCFF7O.js";
7
7
  import {
8
8
  getPluginProviders,
9
9
  getPluginRuntimeDependencies,
10
10
  getPluginRuntimePostinstall
11
- } from "../chunk-657CJCUO.js";
11
+ } from "../chunk-6QWWMZCK.js";
12
12
  import "../chunk-Z3YD6NHK.js";
13
13
  import "../chunk-KVZL5NZS.js";
14
14
  import "../chunk-2KG3PWR4.js";
package/dist/reporting.js CHANGED
@@ -8,20 +8,20 @@ import {
8
8
  listAgentTurnSessionSummaries,
9
9
  listAgentTurnSessionSummariesForConversation,
10
10
  resolveSlackConversationContextFromThreadId
11
- } from "./chunk-X2HJLKQT.js";
11
+ } from "./chunk-DG2I6GXC.js";
12
12
  import {
13
13
  discoverSkills
14
- } from "./chunk-F57QSMOJ.js";
14
+ } from "./chunk-YL5G5YC4.js";
15
15
  import {
16
16
  canExposeConversationPayload,
17
17
  parseSlackThreadId,
18
18
  resolveConversationPrivacy
19
- } from "./chunk-ZOV3XJAH.js";
19
+ } from "./chunk-SAYCFF7O.js";
20
20
  import {
21
21
  getPluginPackageContent,
22
22
  getPluginProviders,
23
23
  isRecord
24
- } from "./chunk-657CJCUO.js";
24
+ } from "./chunk-6QWWMZCK.js";
25
25
  import "./chunk-Z3YD6NHK.js";
26
26
  import {
27
27
  homeDir
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior",
3
- "version": "0.66.0",
3
+ "version": "0.66.1",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -65,7 +65,7 @@
65
65
  "node-html-markdown": "^2.0.0",
66
66
  "yaml": "^2.9.0",
67
67
  "zod": "^4.4.3",
68
- "@sentry/junior-plugin-api": "0.66.0"
68
+ "@sentry/junior-plugin-api": "0.66.1"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@types/node": "^25.9.1",
@@ -77,7 +77,7 @@
77
77
  "typescript": "^6.0.3",
78
78
  "vercel": "^54.4.0",
79
79
  "vitest": "^4.1.7",
80
- "@sentry/junior-scheduler": "0.66.0"
80
+ "@sentry/junior-scheduler": "0.66.1"
81
81
  },
82
82
  "scripts": {
83
83
  "build": "tsup && tsc -p tsconfig.build.json --emitDeclarationOnly",