@sentry/junior 0.11.1 → 0.12.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.
@@ -1,560 +0,0 @@
1
- // src/chat/plugins/package-discovery.ts
2
- import { readFileSync, readdirSync as readdirSync2 } from "fs";
3
- import path2 from "path";
4
- import { parse as parseYaml } from "yaml";
5
-
6
- // src/chat/discovery.ts
7
- import fs, { readdirSync, statSync } from "fs";
8
- import path from "path";
9
- import { fileURLToPath } from "url";
10
- function isDirectory(targetPath) {
11
- try {
12
- return statSync(targetPath).isDirectory();
13
- } catch {
14
- return false;
15
- }
16
- }
17
- function isFile(targetPath) {
18
- try {
19
- return statSync(targetPath).isFile();
20
- } catch {
21
- return false;
22
- }
23
- }
24
- function normalizePath(targetPath) {
25
- return path.resolve(targetPath);
26
- }
27
- function uniqueResolvedPathsInOrder(values) {
28
- const seen = /* @__PURE__ */ new Set();
29
- const resolved = [];
30
- for (const value of values) {
31
- const normalized = normalizePath(value);
32
- if (seen.has(normalized)) {
33
- continue;
34
- }
35
- seen.add(normalized);
36
- resolved.push(normalized);
37
- }
38
- return resolved;
39
- }
40
- function isNodeModulesPath(candidatePath) {
41
- return path.basename(candidatePath) === "node_modules";
42
- }
43
- function isInsidePnpmStore(candidatePath) {
44
- return candidatePath.split(path.sep).includes(".pnpm");
45
- }
46
- function runningFromInstalledPackage() {
47
- const currentFile = fileURLToPath(import.meta.url);
48
- const marker = `${path.sep}node_modules${path.sep}@sentry${path.sep}junior${path.sep}`;
49
- return currentFile.includes(marker);
50
- }
51
- function listInstalledPackageNodeModulesDirs() {
52
- if (!runningFromInstalledPackage()) {
53
- return [];
54
- }
55
- const dirs = [];
56
- let current = path.resolve(path.dirname(fileURLToPath(import.meta.url)));
57
- while (true) {
58
- if (isNodeModulesPath(current) && !isInsidePnpmStore(current) && isDirectory(current)) {
59
- dirs.push(current);
60
- }
61
- const parent = path.dirname(current);
62
- if (parent === current) {
63
- break;
64
- }
65
- current = parent;
66
- }
67
- return dirs;
68
- }
69
- function listCwdAncestorNodeModulesDirs(cwd) {
70
- const resolvedCwd = normalizePath(cwd);
71
- const dirs = [];
72
- let current = resolvedCwd;
73
- while (true) {
74
- const nodeModulesDir = path.join(current, "node_modules");
75
- if (isDirectory(nodeModulesDir)) {
76
- dirs.push(nodeModulesDir);
77
- }
78
- if (isFile(path.join(current, "package.json"))) {
79
- break;
80
- }
81
- const parent = path.dirname(current);
82
- if (parent === current) {
83
- break;
84
- }
85
- current = parent;
86
- }
87
- return dirs;
88
- }
89
- function discoverNodeModulesDirs(cwd = process.cwd(), options) {
90
- const explicit = options?.candidateDirs?.filter((dir) => isDirectory(dir)) ?? [];
91
- if (explicit.length > 0) {
92
- return uniqueResolvedPathsInOrder(explicit);
93
- }
94
- return uniqueResolvedPathsInOrder([
95
- ...listInstalledPackageNodeModulesDirs(),
96
- ...listCwdAncestorNodeModulesDirs(cwd)
97
- ]);
98
- }
99
- function discoverProjectRoots(cwd = process.cwd(), options) {
100
- const roots = discoverNodeModulesDirs(
101
- cwd,
102
- options?.nodeModulesDirs ? { candidateDirs: options.nodeModulesDirs } : void 0
103
- ).map((nodeModulesDir) => path.dirname(nodeModulesDir));
104
- return uniqueResolvedPathsInOrder([cwd, ...roots]);
105
- }
106
- function listTopLevelPackages(nodeModulesDir) {
107
- const entries = readdirSync(nodeModulesDir, { withFileTypes: true }).filter(
108
- (entry) => !entry.name.startsWith(".") && entry.name !== ".bin" && entry.name !== ".pnpm"
109
- ).sort((left, right) => left.name.localeCompare(right.name));
110
- const packages = [];
111
- for (const entry of entries) {
112
- const entryPath = path.join(nodeModulesDir, entry.name);
113
- if (entry.name.startsWith("@")) {
114
- if (!isDirectory(entryPath)) {
115
- continue;
116
- }
117
- const scopedEntries = readdirSync(entryPath, {
118
- withFileTypes: true
119
- }).sort((left, right) => left.name.localeCompare(right.name));
120
- for (const scopedEntry of scopedEntries) {
121
- const packageName = `${entry.name}/${scopedEntry.name}`;
122
- const packagePath = path.join(entryPath, scopedEntry.name);
123
- if (!isDirectory(packagePath)) {
124
- continue;
125
- }
126
- packages.push({ name: packageName, dir: packagePath });
127
- }
128
- continue;
129
- }
130
- if (!isDirectory(entryPath)) {
131
- continue;
132
- }
133
- packages.push({ name: entry.name, dir: entryPath });
134
- }
135
- return packages;
136
- }
137
- function unique(values) {
138
- return [...new Set(values)];
139
- }
140
- function pathExists(targetPath) {
141
- try {
142
- fs.accessSync(targetPath);
143
- return true;
144
- } catch {
145
- return false;
146
- }
147
- }
148
- function hasAnyDataMarkers(appDir) {
149
- return pathExists(path.join(appDir, "SOUL.md")) || pathExists(path.join(appDir, "ABOUT.md"));
150
- }
151
- function scoreAppCandidate(appDir) {
152
- let score = 0;
153
- if (pathExists(path.join(appDir, "SOUL.md"))) {
154
- score += 4;
155
- }
156
- if (pathExists(path.join(appDir, "ABOUT.md"))) {
157
- score += 2;
158
- }
159
- if (pathExists(path.join(appDir, "skills"))) {
160
- score += 1;
161
- }
162
- if (pathExists(path.join(appDir, "plugins"))) {
163
- score += 1;
164
- }
165
- return score;
166
- }
167
- function resolveCandidateAppDirs(cwd, projectRoots) {
168
- const roots = projectRoots ?? discoverProjectRoots(cwd);
169
- const resolved = [];
170
- const seen = /* @__PURE__ */ new Set();
171
- for (const root of roots) {
172
- const appDir = path.resolve(root, "app");
173
- if (!pathExists(appDir)) {
174
- continue;
175
- }
176
- if (seen.has(appDir)) {
177
- continue;
178
- }
179
- seen.add(appDir);
180
- resolved.push(appDir);
181
- }
182
- return resolved;
183
- }
184
- function homeDir() {
185
- return resolveHomeDir();
186
- }
187
- function resolveHomeDir(cwd = process.cwd(), options) {
188
- const resolvedCwd = path.resolve(cwd);
189
- const directApp = path.resolve(resolvedCwd, "app");
190
- if (pathExists(directApp) && hasAnyDataMarkers(directApp)) {
191
- return directApp;
192
- }
193
- const candidates = resolveCandidateAppDirs(
194
- resolvedCwd,
195
- options?.projectRoots
196
- );
197
- if (candidates.length === 0) {
198
- return directApp;
199
- }
200
- candidates.sort((left, right) => {
201
- const leftScore = scoreAppCandidate(left);
202
- const rightScore = scoreAppCandidate(right);
203
- if (leftScore !== rightScore) {
204
- return rightScore - leftScore;
205
- }
206
- const leftDistance = path.relative(resolvedCwd, left).split(path.sep).length;
207
- const rightDistance = path.relative(resolvedCwd, right).split(path.sep).length;
208
- if (leftDistance !== rightDistance) {
209
- return leftDistance - rightDistance;
210
- }
211
- return left.localeCompare(right);
212
- });
213
- return candidates[0];
214
- }
215
- function resolveContentRoots(subdir) {
216
- if (subdir === "data") {
217
- return [homeDir()];
218
- }
219
- return [path.join(homeDir(), subdir)];
220
- }
221
- function dataRoots() {
222
- return unique(resolveContentRoots("data"));
223
- }
224
- function skillRoots() {
225
- return unique(resolveContentRoots("skills"));
226
- }
227
- function pluginRoots() {
228
- return unique(resolveContentRoots("plugins"));
229
- }
230
- function soulPathCandidates() {
231
- const candidates = dataRoots().map((root) => path.join(root, "SOUL.md"));
232
- return unique(candidates);
233
- }
234
- function aboutPathCandidates() {
235
- const candidates = dataRoots().map((root) => path.join(root, "ABOUT.md"));
236
- return unique(candidates);
237
- }
238
-
239
- // src/chat/plugins/package-discovery.ts
240
- function normalizeForGlob(targetPath) {
241
- return targetPath.split(path2.sep).join("/");
242
- }
243
- function uniqueStringsInOrder(values) {
244
- const seen = /* @__PURE__ */ new Set();
245
- const resolved = [];
246
- for (const value of values) {
247
- if (seen.has(value)) {
248
- continue;
249
- }
250
- seen.add(value);
251
- resolved.push(value);
252
- }
253
- return resolved;
254
- }
255
- function pathForTracingInclude(cwd, targetPath) {
256
- const relative = path2.relative(cwd, targetPath);
257
- if (!relative || path2.isAbsolute(relative)) {
258
- return null;
259
- }
260
- const normalized = normalizeForGlob(relative);
261
- return normalized.startsWith(".") ? normalized : `./${normalized}`;
262
- }
263
- function parseRuntimeConfiguredPackageNames(value) {
264
- if (!Array.isArray(value)) {
265
- return null;
266
- }
267
- const parsed = value.filter(
268
- (entry) => typeof entry === "string" && entry.trim().length > 0
269
- );
270
- return uniqueStringsInOrder(parsed.map((entry) => entry.trim()));
271
- }
272
- var configuredPluginPackages;
273
- function setPluginPackages(packages) {
274
- configuredPluginPackages = packages;
275
- }
276
- function readNextRuntimeConfiguredPackageNames() {
277
- if (configuredPluginPackages !== void 0) {
278
- return configuredPluginPackages;
279
- }
280
- const raw = process.env.JUNIOR_PLUGIN_PACKAGES;
281
- if (raw === void 0) {
282
- return null;
283
- }
284
- try {
285
- return parseRuntimeConfiguredPackageNames(JSON.parse(raw)) ?? [];
286
- } catch {
287
- return [];
288
- }
289
- }
290
- function findWorkspaceRoot(cwd) {
291
- let current = path2.resolve(cwd);
292
- while (true) {
293
- const candidate = path2.join(current, "pnpm-workspace.yaml");
294
- if (isFile(candidate)) {
295
- return current;
296
- }
297
- const parent = path2.dirname(current);
298
- if (parent === current) {
299
- return null;
300
- }
301
- current = parent;
302
- }
303
- }
304
- function listWorkspacePackageDirs(cwd) {
305
- const workspaceRoot = findWorkspaceRoot(cwd);
306
- if (!workspaceRoot) {
307
- return [];
308
- }
309
- let packagePatterns = [];
310
- try {
311
- const raw = readFileSync(
312
- path2.join(workspaceRoot, "pnpm-workspace.yaml"),
313
- "utf8"
314
- );
315
- const parsed = parseYaml(raw);
316
- packagePatterns = Array.isArray(parsed.packages) ? parsed.packages.filter(
317
- (entry) => typeof entry === "string" && entry.trim().length > 0
318
- ) : [];
319
- } catch {
320
- return [];
321
- }
322
- const discovered = [];
323
- const seen = /* @__PURE__ */ new Set();
324
- const addDir = (candidate) => {
325
- const normalized = path2.resolve(candidate);
326
- if (seen.has(normalized) || !isDirectory(normalized)) {
327
- return;
328
- }
329
- seen.add(normalized);
330
- discovered.push(normalized);
331
- };
332
- for (const pattern of packagePatterns) {
333
- const trimmed = pattern.trim();
334
- if (!trimmed) {
335
- continue;
336
- }
337
- if (trimmed.endsWith("/*")) {
338
- const baseDir = path2.join(workspaceRoot, trimmed.slice(0, -2));
339
- if (!isDirectory(baseDir)) {
340
- continue;
341
- }
342
- for (const entry of readdirSync2(baseDir)) {
343
- addDir(path2.join(baseDir, entry));
344
- }
345
- continue;
346
- }
347
- addDir(path2.join(workspaceRoot, trimmed));
348
- }
349
- return discovered;
350
- }
351
- function readPluginPackageFlags(dir) {
352
- const hasRootPluginManifest = isFile(path2.join(dir, "plugin.yaml"));
353
- const hasPluginsDir = isDirectory(path2.join(dir, "plugins"));
354
- const hasSkillsDir = isDirectory(path2.join(dir, "skills"));
355
- if (!hasRootPluginManifest && !hasPluginsDir && !hasSkillsDir) {
356
- return null;
357
- }
358
- return {
359
- hasRootPluginManifest,
360
- hasPluginsDir,
361
- hasSkillsDir
362
- };
363
- }
364
- function discoverWorkspacePluginPackageDirs(cwd, packageNames) {
365
- if (packageNames !== null) {
366
- return [];
367
- }
368
- return listWorkspacePackageDirs(cwd).filter(
369
- (candidate) => readPluginPackageFlags(candidate) !== null
370
- );
371
- }
372
- function readWorkspacePackageName(dir) {
373
- try {
374
- const raw = readFileSync(path2.join(dir, "package.json"), "utf8");
375
- const name = JSON.parse(raw).name;
376
- return typeof name === "string" && name.trim().length > 0 ? name : null;
377
- } catch {
378
- return null;
379
- }
380
- }
381
- function resolveWorkspacePackageDirFromName(cwd, packageName) {
382
- for (const candidate of listWorkspacePackageDirs(cwd)) {
383
- if (readWorkspacePackageName(candidate) !== packageName) {
384
- continue;
385
- }
386
- return candidate;
387
- }
388
- return null;
389
- }
390
- function resolvePackageDirFromName(packageName, candidateNodeModulesDirs) {
391
- for (const nodeModulesDir of candidateNodeModulesDirs) {
392
- const packageDir = path2.join(nodeModulesDir, ...packageName.split("/"));
393
- if (isDirectory(packageDir)) {
394
- return {
395
- dir: path2.resolve(packageDir),
396
- nodeModulesDir: path2.resolve(nodeModulesDir)
397
- };
398
- }
399
- }
400
- return null;
401
- }
402
- function discoverDeclaredPackages(cwd, packageNames, candidateNodeModulesDirs) {
403
- const discovered = [];
404
- const seenPackageNames = /* @__PURE__ */ new Set();
405
- const seenPackageDirs = /* @__PURE__ */ new Set();
406
- for (const packageName of packageNames) {
407
- const resolved = resolvePackageDirFromName(
408
- packageName,
409
- candidateNodeModulesDirs
410
- );
411
- const workspaceDir = resolved ? null : resolveWorkspacePackageDirFromName(cwd, packageName);
412
- if (!resolved && !workspaceDir) {
413
- continue;
414
- }
415
- const packageDir = resolved?.dir ?? workspaceDir;
416
- if (seenPackageNames.has(packageName) || seenPackageDirs.has(packageDir)) {
417
- continue;
418
- }
419
- const pluginFlags = readPluginPackageFlags(packageDir);
420
- if (!pluginFlags) {
421
- continue;
422
- }
423
- seenPackageNames.add(packageName);
424
- seenPackageDirs.add(packageDir);
425
- discovered.push({
426
- name: packageName,
427
- dir: packageDir,
428
- nodeModulesDir: resolved?.nodeModulesDir ?? null,
429
- ...pluginFlags
430
- });
431
- }
432
- return discovered;
433
- }
434
- function discoverInstalledJuniorContentPackages(cwd = process.cwd(), nodeModulesDirs, packageNames) {
435
- const resolvedCwd = path2.resolve(cwd);
436
- const candidateNodeModulesDirs = nodeModulesDirs ?? discoverNodeModulesDirs(resolvedCwd);
437
- const configuredPackageNames = packageNames ?? readNextRuntimeConfiguredPackageNames();
438
- const declaredPackages = discoverDeclaredPackages(
439
- resolvedCwd,
440
- configuredPackageNames ?? [],
441
- candidateNodeModulesDirs
442
- );
443
- const useFallbackScan = configuredPackageNames === null;
444
- const discovered = [...declaredPackages];
445
- const seenPackageNames = /* @__PURE__ */ new Set();
446
- const seenPackageDirs = /* @__PURE__ */ new Set();
447
- for (const pkg of declaredPackages) {
448
- seenPackageNames.add(pkg.name);
449
- seenPackageDirs.add(pkg.dir);
450
- }
451
- if (!useFallbackScan) {
452
- return discovered;
453
- }
454
- for (const nodeModulesDir of candidateNodeModulesDirs) {
455
- for (const pkg of listTopLevelPackages(nodeModulesDir)) {
456
- const resolvedDir = path2.resolve(pkg.dir);
457
- if (seenPackageNames.has(pkg.name) || seenPackageDirs.has(resolvedDir)) {
458
- continue;
459
- }
460
- seenPackageNames.add(pkg.name);
461
- seenPackageDirs.add(resolvedDir);
462
- const hasRootPluginManifest = isFile(
463
- path2.join(resolvedDir, "plugin.yaml")
464
- );
465
- const hasPluginsDir = isDirectory(path2.join(resolvedDir, "plugins"));
466
- const hasSkillsDir = isDirectory(path2.join(resolvedDir, "skills"));
467
- if (!hasRootPluginManifest && !hasPluginsDir && !hasSkillsDir) {
468
- continue;
469
- }
470
- discovered.push({
471
- name: pkg.name,
472
- dir: resolvedDir,
473
- nodeModulesDir: path2.resolve(nodeModulesDir),
474
- hasRootPluginManifest,
475
- hasPluginsDir,
476
- hasSkillsDir
477
- });
478
- }
479
- }
480
- return discovered;
481
- }
482
- function discoverInstalledPluginPackageContent(cwd = process.cwd(), options) {
483
- const resolvedCwd = path2.resolve(cwd);
484
- const configuredPackageNames = options?.packageNames ?? readNextRuntimeConfiguredPackageNames();
485
- const discoveredPackages = discoverInstalledJuniorContentPackages(
486
- resolvedCwd,
487
- options?.nodeModulesDirs,
488
- configuredPackageNames
489
- );
490
- const workspacePluginDirs = discoverWorkspacePluginPackageDirs(
491
- resolvedCwd,
492
- configuredPackageNames
493
- );
494
- const manifestRoots = [];
495
- const skillRoots2 = [];
496
- const tracingIncludes = [];
497
- for (const pkg of discoveredPackages) {
498
- const tracingBasePath = pkg.nodeModulesDir ? pathForTracingInclude(
499
- resolvedCwd,
500
- path2.join(pkg.nodeModulesDir, ...pkg.name.split("/"))
501
- ) : pathForTracingInclude(resolvedCwd, pkg.dir);
502
- if (pkg.hasRootPluginManifest) {
503
- manifestRoots.push(pkg.dir);
504
- if (tracingBasePath) {
505
- tracingIncludes.push(`${tracingBasePath}/plugin.yaml`);
506
- }
507
- }
508
- if (pkg.hasPluginsDir) {
509
- manifestRoots.push(path2.join(pkg.dir, "plugins"));
510
- if (tracingBasePath) {
511
- tracingIncludes.push(`${tracingBasePath}/plugins/**/*`);
512
- }
513
- }
514
- if (pkg.hasSkillsDir) {
515
- skillRoots2.push(path2.join(pkg.dir, "skills"));
516
- if (tracingBasePath) {
517
- tracingIncludes.push(`${tracingBasePath}/skills/**/*`);
518
- }
519
- }
520
- }
521
- for (const pluginDir of workspacePluginDirs) {
522
- const tracingBasePath = pathForTracingInclude(resolvedCwd, pluginDir);
523
- if (isFile(path2.join(pluginDir, "plugin.yaml"))) {
524
- manifestRoots.push(pluginDir);
525
- if (tracingBasePath) {
526
- tracingIncludes.push(`${tracingBasePath}/plugin.yaml`);
527
- }
528
- }
529
- if (isDirectory(path2.join(pluginDir, "plugins"))) {
530
- manifestRoots.push(path2.join(pluginDir, "plugins"));
531
- if (tracingBasePath) {
532
- tracingIncludes.push(`${tracingBasePath}/plugins/**/*`);
533
- }
534
- }
535
- if (isDirectory(path2.join(pluginDir, "skills"))) {
536
- skillRoots2.push(path2.join(pluginDir, "skills"));
537
- if (tracingBasePath) {
538
- tracingIncludes.push(`${tracingBasePath}/skills/**/*`);
539
- }
540
- }
541
- }
542
- return {
543
- packageNames: uniqueStringsInOrder(
544
- discoveredPackages.map((pkg) => pkg.name)
545
- ),
546
- manifestRoots: uniqueStringsInOrder(manifestRoots),
547
- skillRoots: uniqueStringsInOrder(skillRoots2),
548
- tracingIncludes: uniqueStringsInOrder(tracingIncludes)
549
- };
550
- }
551
-
552
- export {
553
- homeDir,
554
- skillRoots,
555
- pluginRoots,
556
- soulPathCandidates,
557
- aboutPathCandidates,
558
- setPluginPackages,
559
- discoverInstalledPluginPackageContent
560
- };
package/dist/nitro.d.ts DELETED
@@ -1,27 +0,0 @@
1
- interface JuniorNitroConfigOptions {
2
- cwd?: string;
3
- maxDuration?: number;
4
- }
5
- /** Return the default Nitro config used by scaffolded Junior apps. */
6
- declare function juniorNitroConfig(options?: JuniorNitroConfigOptions): {
7
- preset: "vercel";
8
- vercel: {
9
- functions: {
10
- maxDuration: number;
11
- };
12
- };
13
- modules: {
14
- setup(nitro: {
15
- hooks: {
16
- hook(name: "compiled", callback: () => void): void;
17
- };
18
- options: {
19
- output: {
20
- serverDir: string;
21
- };
22
- };
23
- }): void;
24
- }[];
25
- };
26
-
27
- export { type JuniorNitroConfigOptions, juniorNitroConfig };
package/dist/nitro.js DELETED
@@ -1,62 +0,0 @@
1
- import {
2
- discoverInstalledPluginPackageContent
3
- } from "./chunk-XH7TV4JS.js";
4
- import "./chunk-2KG3PWR4.js";
5
-
6
- // src/nitro.ts
7
- import { cpSync, existsSync, mkdirSync } from "fs";
8
- import path from "path";
9
- function copyAppAndPluginContent(cwd, serverRoot) {
10
- copyIfExists(path.join(cwd, "app"), path.join(serverRoot, "app"));
11
- const packagedContent = discoverInstalledPluginPackageContent(cwd);
12
- for (const root of packagedContent.manifestRoots) {
13
- if (existsSync(path.join(root, "plugin.yaml"))) {
14
- copyIfExists(
15
- path.join(root, "plugin.yaml"),
16
- path.join(serverRoot, path.relative(cwd, root), "plugin.yaml")
17
- );
18
- continue;
19
- }
20
- copyRootIntoServerOutput(cwd, serverRoot, root);
21
- }
22
- for (const root of packagedContent.skillRoots) {
23
- copyRootIntoServerOutput(cwd, serverRoot, root);
24
- }
25
- }
26
- function copyIfExists(source, target) {
27
- if (!existsSync(source)) {
28
- return;
29
- }
30
- mkdirSync(path.dirname(target), { recursive: true });
31
- cpSync(source, target, { recursive: true });
32
- }
33
- function copyRootIntoServerOutput(cwd, serverRoot, root) {
34
- const relative = path.relative(cwd, root);
35
- if (!relative || path.isAbsolute(relative) || relative.startsWith("..")) {
36
- return;
37
- }
38
- copyIfExists(root, path.join(serverRoot, relative));
39
- }
40
- function juniorNitroConfig(options = {}) {
41
- const cwd = path.resolve(options.cwd ?? process.cwd());
42
- return {
43
- preset: "vercel",
44
- vercel: {
45
- functions: {
46
- maxDuration: options.maxDuration ?? 800
47
- }
48
- },
49
- modules: [
50
- {
51
- setup(nitro) {
52
- nitro.hooks.hook("compiled", () => {
53
- copyAppAndPluginContent(cwd, nitro.options.output.serverDir);
54
- });
55
- }
56
- }
57
- ]
58
- };
59
- }
60
- export {
61
- juniorNitroConfig
62
- };