@pennyfarthing/shared 7.5.0 → 9.3.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 (82) hide show
  1. package/dist/browser.d.ts +6 -0
  2. package/dist/browser.d.ts.map +1 -0
  3. package/dist/browser.js +8 -0
  4. package/dist/browser.js.map +1 -0
  5. package/dist/generate-skill-docs.d.ts +35 -0
  6. package/dist/generate-skill-docs.d.ts.map +1 -0
  7. package/dist/generate-skill-docs.js +442 -0
  8. package/dist/generate-skill-docs.js.map +1 -0
  9. package/dist/generate-skill-docs.test.d.ts +13 -0
  10. package/dist/generate-skill-docs.test.d.ts.map +1 -0
  11. package/dist/generate-skill-docs.test.js +519 -0
  12. package/dist/generate-skill-docs.test.js.map +1 -0
  13. package/dist/index.d.ts +11 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +13 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/marker/constants.d.ts +39 -0
  18. package/dist/marker/constants.d.ts.map +1 -0
  19. package/dist/marker/constants.js +46 -0
  20. package/dist/marker/constants.js.map +1 -0
  21. package/dist/marker/continue.test.d.ts +12 -0
  22. package/dist/marker/continue.test.d.ts.map +1 -0
  23. package/dist/marker/continue.test.js +76 -0
  24. package/dist/marker/continue.test.js.map +1 -0
  25. package/dist/marker/detect.d.ts +25 -0
  26. package/dist/marker/detect.d.ts.map +1 -0
  27. package/dist/marker/detect.js +53 -0
  28. package/dist/marker/detect.js.map +1 -0
  29. package/dist/marker/detect.test.d.ts +10 -0
  30. package/dist/marker/detect.test.d.ts.map +1 -0
  31. package/dist/marker/detect.test.js +418 -0
  32. package/dist/marker/detect.test.js.map +1 -0
  33. package/dist/marker/index.d.ts +14 -0
  34. package/dist/marker/index.d.ts.map +1 -0
  35. package/dist/marker/index.js +15 -0
  36. package/dist/marker/index.js.map +1 -0
  37. package/dist/marker/strip.d.ts +26 -0
  38. package/dist/marker/strip.d.ts.map +1 -0
  39. package/dist/marker/strip.js +39 -0
  40. package/dist/marker/strip.js.map +1 -0
  41. package/dist/marker/types.d.ts +23 -0
  42. package/dist/marker/types.d.ts.map +1 -0
  43. package/dist/marker/types.js +7 -0
  44. package/dist/marker/types.js.map +1 -0
  45. package/dist/migrate-theme-schema.test.d.ts +8 -0
  46. package/dist/migrate-theme-schema.test.d.ts.map +1 -0
  47. package/dist/migrate-theme-schema.test.js +100 -0
  48. package/dist/migrate-theme-schema.test.js.map +1 -0
  49. package/dist/portrait-resolver.d.ts +32 -0
  50. package/dist/portrait-resolver.d.ts.map +1 -0
  51. package/dist/portrait-resolver.js +225 -0
  52. package/dist/portrait-resolver.js.map +1 -0
  53. package/dist/portrait-resolver.test.d.ts +2 -0
  54. package/dist/portrait-resolver.test.d.ts.map +1 -0
  55. package/dist/portrait-resolver.test.js +156 -0
  56. package/dist/portrait-resolver.test.js.map +1 -0
  57. package/dist/skill-search.d.ts +36 -0
  58. package/dist/skill-search.d.ts.map +1 -0
  59. package/dist/skill-search.js +300 -0
  60. package/dist/skill-search.js.map +1 -0
  61. package/dist/skill-search.sh +41 -0
  62. package/dist/skill-search.test.d.ts +16 -0
  63. package/dist/skill-search.test.d.ts.map +1 -0
  64. package/dist/skill-search.test.js +177 -0
  65. package/dist/skill-search.test.js.map +1 -0
  66. package/dist/skill-suggest.d.ts +76 -0
  67. package/dist/skill-suggest.d.ts.map +1 -0
  68. package/dist/skill-suggest.js +256 -0
  69. package/dist/skill-suggest.js.map +1 -0
  70. package/dist/skill-suggest.test.d.ts +12 -0
  71. package/dist/skill-suggest.test.d.ts.map +1 -0
  72. package/dist/skill-suggest.test.js +257 -0
  73. package/dist/skill-suggest.test.js.map +1 -0
  74. package/dist/theme-loader.d.ts +81 -0
  75. package/dist/theme-loader.d.ts.map +1 -0
  76. package/dist/theme-loader.js +491 -0
  77. package/dist/theme-loader.js.map +1 -0
  78. package/dist/theme-loader.test.d.ts +8 -0
  79. package/dist/theme-loader.test.d.ts.map +1 -0
  80. package/dist/theme-loader.test.js +62 -0
  81. package/dist/theme-loader.test.js.map +1 -0
  82. package/package.json +14 -1
@@ -0,0 +1,491 @@
1
+ /**
2
+ * Theme Loader - Unified theme discovery, loading, and metadata for Pennyfarthing
3
+ *
4
+ * This is the ONE canonical implementation of theme loading. All other packages
5
+ * (core CLI, cyclist, Python scripts, bash scripts) should delegate here.
6
+ *
7
+ * Discovery algorithm (checked in order, deduped by theme ID):
8
+ * 1. Core themes: resolvePennyfarthingDist()/personas/themes/
9
+ * 2. Theme packages: node_modules/@pennyfarthing/themes-* /themes/
10
+ * 3. Project custom: {projectRoot}/.claude/pennyfarthing/themes/
11
+ * 4. User custom: ~/.claude/pennyfarthing/themes/
12
+ */
13
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
14
+ import { join, basename, dirname } from 'node:path';
15
+ import { homedir } from 'node:os';
16
+ import { parse as parseYaml } from 'yaml';
17
+ import { resolvePennyfarthingDist, getPortraitPaths } from './portrait-resolver.js';
18
+ // ---------------------------------------------------------------------------
19
+ // Category mapping (moved from packages/cyclist/src/theme-metadata.ts)
20
+ // ---------------------------------------------------------------------------
21
+ export const CATEGORY_MAP = {
22
+ // TV Series
23
+ 'star-trek-tos': 'TV Series',
24
+ 'star-trek-tng': 'TV Series',
25
+ 'star-trek-ds9': 'TV Series',
26
+ 'star-trek-voyager': 'TV Series',
27
+ 'breaking-bad': 'TV Series',
28
+ 'the-office': 'TV Series',
29
+ 'the-wire': 'TV Series',
30
+ 'game-of-thrones': 'TV Series',
31
+ 'ted-lasso': 'TV Series',
32
+ 'parks-and-recreation': 'TV Series',
33
+ 'friends': 'TV Series',
34
+ 'seinfeld': 'TV Series',
35
+ 'mad-men': 'TV Series',
36
+ 'the-sopranos': 'TV Series',
37
+ 'arrested-development': 'TV Series',
38
+ 'schitts-creek': 'TV Series',
39
+ 'brooklyn-nine-nine': 'TV Series',
40
+ 'firefly': 'TV Series',
41
+ 'battlestar-galactica': 'TV Series',
42
+ 'doctor-who': 'TV Series',
43
+ 'stranger-things': 'TV Series',
44
+ 'the-good-place': 'TV Series',
45
+ 'its-always-sunny': 'TV Series',
46
+ 'downton-abbey': 'TV Series',
47
+ 'the-crown': 'TV Series',
48
+ 'succession': 'TV Series',
49
+ 'the-simpsons': 'TV Series',
50
+ 'futurama': 'TV Series',
51
+ 'arcane': 'TV Series',
52
+ 'avatar-the-last-airbender': 'TV Series',
53
+ 'severance': 'TV Series',
54
+ 'the-west-wing': 'TV Series',
55
+ 'lost': 'TV Series',
56
+ 'the-x-files': 'TV Series',
57
+ 'twin-peaks': 'TV Series',
58
+ 'the-twilight-zone': 'TV Series',
59
+ 'mash': 'TV Series',
60
+ 'a-team': 'TV Series',
61
+ // Literature
62
+ 'alice-in-wonderland': 'Literature',
63
+ 'lord-of-the-rings': 'Literature',
64
+ 'discworld': 'Literature',
65
+ 'hitchhikers-guide': 'Literature',
66
+ 'dune': 'Literature',
67
+ 'pride-and-prejudice': 'Literature',
68
+ 'sherlock-holmes': 'Literature',
69
+ 'harry-potter': 'Literature',
70
+ 'narnia': 'Literature',
71
+ 'foundation': 'Literature',
72
+ 'wheel-of-time': 'Literature',
73
+ 'stormlight-archive': 'Literature',
74
+ 'mistborn': 'Literature',
75
+ 'good-omens': 'Literature',
76
+ 'american-gods': 'Literature',
77
+ 'the-expanse': 'Literature',
78
+ 'enders-game': 'Literature',
79
+ 'three-body-problem': 'Literature',
80
+ 'hyperion': 'Literature',
81
+ '1984': 'Literature',
82
+ 'brave-new-world': 'Literature',
83
+ 'frankenstein': 'Literature',
84
+ 'dracula': 'Literature',
85
+ 'moby-dick': 'Literature',
86
+ 'odyssey': 'Literature',
87
+ 'iliad': 'Literature',
88
+ 'don-quixote': 'Literature',
89
+ 'count-of-monte-cristo': 'Literature',
90
+ 'les-miserables': 'Literature',
91
+ 'great-gatsby': 'Literature',
92
+ 'winnie-the-pooh': 'Literature',
93
+ 'peter-pan': 'Literature',
94
+ 'wizard-of-oz': 'Literature',
95
+ // Film
96
+ 'star-wars': 'Film',
97
+ 'matrix': 'Film',
98
+ 'inception': 'Film',
99
+ 'pulp-fiction': 'Film',
100
+ 'godfather': 'Film',
101
+ 'shawshank-redemption': 'Film',
102
+ 'fight-club': 'Film',
103
+ 'blade-runner': 'Film',
104
+ 'back-to-the-future': 'Film',
105
+ 'jurassic-park': 'Film',
106
+ 'indiana-jones': 'Film',
107
+ 'marvel-avengers': 'Film',
108
+ 'guardians-of-the-galaxy': 'Film',
109
+ 'pirates-of-the-caribbean': 'Film',
110
+ 'princess-bride': 'Film',
111
+ 'monty-python': 'Film',
112
+ 'ghostbusters': 'Film',
113
+ 'men-in-black': 'Film',
114
+ 'ocean-eleven': 'Film',
115
+ 'big-lebowski': 'Film',
116
+ 'grand-budapest-hotel': 'Film',
117
+ 'kill-bill': 'Film',
118
+ 'john-wick': 'Film',
119
+ 'die-hard': 'Film',
120
+ 'terminator': 'Film',
121
+ 'alien': 'Film',
122
+ 'predator': 'Film',
123
+ 'mad-max': 'Film',
124
+ 'studio-ghibli': 'Film',
125
+ 'pixar': 'Film',
126
+ 'disney-classics': 'Film',
127
+ 'interstellar': 'Film',
128
+ 'arrival': 'Film',
129
+ 'her': 'Film',
130
+ 'ex-machina': 'Film',
131
+ // Mythology
132
+ 'greek-mythology': 'Mythology',
133
+ 'norse-mythology': 'Mythology',
134
+ 'egyptian-mythology': 'Mythology',
135
+ 'celtic-mythology': 'Mythology',
136
+ 'japanese-mythology': 'Mythology',
137
+ 'hindu-mythology': 'Mythology',
138
+ 'arthurian-legend': 'Mythology',
139
+ // Games
140
+ 'zelda': 'Games',
141
+ 'mario': 'Games',
142
+ 'final-fantasy': 'Games',
143
+ 'mass-effect': 'Games',
144
+ 'bioshock': 'Games',
145
+ 'portal': 'Games',
146
+ 'half-life': 'Games',
147
+ 'halo': 'Games',
148
+ 'overwatch': 'Games',
149
+ 'world-of-warcraft': 'Games',
150
+ 'elder-scrolls': 'Games',
151
+ 'fallout': 'Games',
152
+ 'cyberpunk': 'Games',
153
+ 'witcher': 'Games',
154
+ 'red-dead-redemption': 'Games',
155
+ 'last-of-us': 'Games',
156
+ 'god-of-war': 'Games',
157
+ 'dark-souls': 'Games',
158
+ 'elden-ring': 'Games',
159
+ 'pokemon': 'Games',
160
+ 'animal-crossing': 'Games',
161
+ 'minecraft': 'Games',
162
+ // History
163
+ 'ancient-rome': 'History',
164
+ 'ancient-greece': 'History',
165
+ 'ancient-egypt': 'History',
166
+ 'renaissance': 'History',
167
+ 'victorian-era': 'History',
168
+ 'wild-west': 'History',
169
+ 'world-war-2': 'History',
170
+ 'cold-war': 'History',
171
+ 'founding-fathers': 'History',
172
+ // Music
173
+ 'classical-composers': 'Music',
174
+ 'jazz-legends': 'Music',
175
+ 'rock-legends': 'Music',
176
+ 'beatles': 'Music',
177
+ 'queen': 'Music',
178
+ // Science
179
+ 'scientists': 'Science',
180
+ 'space-exploration': 'Science',
181
+ };
182
+ /**
183
+ * Derive category from theme ID and source text.
184
+ * Uses CATEGORY_MAP for known themes, falls back to pattern matching.
185
+ */
186
+ export function deriveCategory(themeId, source) {
187
+ if (CATEGORY_MAP[themeId]) {
188
+ return CATEGORY_MAP[themeId];
189
+ }
190
+ const s = source.toLowerCase();
191
+ if (s.includes('tv series') || s.includes('tv show') ||
192
+ s.includes('amc') || s.includes('hbo') ||
193
+ s.includes('netflix') || s.includes('bbc')) {
194
+ return 'TV Series';
195
+ }
196
+ if (s.includes('film') || s.includes('movie') ||
197
+ s.includes('cinema') || s.includes('disney') ||
198
+ s.includes('pixar') || s.includes('studio ghibli')) {
199
+ return 'Film';
200
+ }
201
+ if (s.includes('mythology') || s.includes('myth') ||
202
+ s.includes('legend') || s.includes('folklore')) {
203
+ return 'Mythology';
204
+ }
205
+ if (s.includes('novel') || s.includes('book') ||
206
+ s.includes(' by ') || s.includes('author') ||
207
+ s.includes('literary') || s.includes('classic')) {
208
+ return 'Literature';
209
+ }
210
+ if (s.includes('game') || s.includes('video game') ||
211
+ s.includes('nintendo') || s.includes('playstation') ||
212
+ s.includes('xbox')) {
213
+ return 'Games';
214
+ }
215
+ if (s.includes('history') || s.includes('historical') ||
216
+ s.includes('century') || s.includes('ancient') ||
217
+ s.includes('era')) {
218
+ return 'History';
219
+ }
220
+ if (s.includes('music') || s.includes('composer') ||
221
+ s.includes('band') || s.includes('musician')) {
222
+ return 'Music';
223
+ }
224
+ return 'Other';
225
+ }
226
+ // ---------------------------------------------------------------------------
227
+ // Theme package discovery
228
+ // ---------------------------------------------------------------------------
229
+ /**
230
+ * Discover installed @pennyfarthing/themes-* packages.
231
+ * Walks up from projectRoot looking for node_modules/@pennyfarthing/,
232
+ * then checks each themes-* directory for a valid theme pack.
233
+ */
234
+ export function discoverThemePackages(projectRoot) {
235
+ const results = [];
236
+ const startDir = projectRoot || process.cwd();
237
+ // Walk up looking for node_modules/@pennyfarthing/
238
+ let currentDir = startDir;
239
+ for (let i = 0; i < 10; i++) {
240
+ const nmPfDir = join(currentDir, 'node_modules', '@pennyfarthing');
241
+ if (existsSync(nmPfDir)) {
242
+ try {
243
+ const entries = readdirSync(nmPfDir);
244
+ for (const entry of entries) {
245
+ if (!entry.startsWith('themes-'))
246
+ continue;
247
+ const pkgDir = join(nmPfDir, entry);
248
+ const pkgJsonPath = join(pkgDir, 'package.json');
249
+ if (!existsSync(pkgJsonPath))
250
+ continue;
251
+ try {
252
+ const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
253
+ if (pkgJson['pennyfarthing-theme-pack'] === true) {
254
+ results.push({
255
+ packageName: pkgJson.name || `@pennyfarthing/${entry}`,
256
+ themesDir: join(pkgDir, 'themes'),
257
+ portraitsDir: join(pkgDir, 'portraits'),
258
+ });
259
+ }
260
+ }
261
+ catch {
262
+ // Invalid package.json — skip
263
+ }
264
+ }
265
+ }
266
+ catch {
267
+ // Can't read directory — skip
268
+ }
269
+ break; // Found node_modules, stop walking up
270
+ }
271
+ const parentDir = dirname(currentDir);
272
+ if (parentDir === currentDir)
273
+ break;
274
+ currentDir = parentDir;
275
+ }
276
+ // Also check monorepo packages/ directory (for development with workspace links)
277
+ // Walk up looking for packages/ dir containing themes-* dirs
278
+ currentDir = startDir;
279
+ for (let i = 0; i < 10; i++) {
280
+ const packagesDir = join(currentDir, 'packages');
281
+ if (existsSync(packagesDir)) {
282
+ try {
283
+ const entries = readdirSync(packagesDir);
284
+ for (const entry of entries) {
285
+ if (!entry.startsWith('themes-'))
286
+ continue;
287
+ const pkgDir = join(packagesDir, entry);
288
+ const pkgJsonPath = join(pkgDir, 'package.json');
289
+ if (!existsSync(pkgJsonPath))
290
+ continue;
291
+ // Skip if already found via node_modules
292
+ try {
293
+ const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
294
+ if (pkgJson['pennyfarthing-theme-pack'] === true) {
295
+ const alreadyFound = results.some(r => r.packageName === (pkgJson.name || `@pennyfarthing/${entry}`));
296
+ if (!alreadyFound) {
297
+ results.push({
298
+ packageName: pkgJson.name || `@pennyfarthing/${entry}`,
299
+ themesDir: join(pkgDir, 'themes'),
300
+ portraitsDir: join(pkgDir, 'portraits'),
301
+ });
302
+ }
303
+ }
304
+ }
305
+ catch {
306
+ // Invalid package.json — skip
307
+ }
308
+ }
309
+ }
310
+ catch {
311
+ // Can't read directory — skip
312
+ }
313
+ break;
314
+ }
315
+ const parentDir = dirname(currentDir);
316
+ if (parentDir === currentDir)
317
+ break;
318
+ currentDir = parentDir;
319
+ }
320
+ return results;
321
+ }
322
+ /**
323
+ * Discover all directories containing theme YAML files.
324
+ * Returns dirs in priority order (core, theme packages, project custom, user custom).
325
+ */
326
+ export function discoverAllThemeDirs(projectRoot) {
327
+ const dirs = [];
328
+ const root = projectRoot || process.cwd();
329
+ // 1. Core themes from pennyfarthing-dist
330
+ const distPath = resolvePennyfarthingDist();
331
+ if (distPath) {
332
+ const paths = getPortraitPaths(distPath);
333
+ const coreThemesDir = join(paths.themesDir, 'themes');
334
+ if (existsSync(coreThemesDir)) {
335
+ dirs.push(coreThemesDir);
336
+ }
337
+ }
338
+ // 2. Theme packages (e.g., @pennyfarthing/themes-realistic)
339
+ const packages = discoverThemePackages(root);
340
+ for (const pkg of packages) {
341
+ if (existsSync(pkg.themesDir)) {
342
+ dirs.push(pkg.themesDir);
343
+ }
344
+ }
345
+ // 3. Project-level custom themes
346
+ const projectCustom = join(root, '.claude', 'pennyfarthing', 'themes');
347
+ if (existsSync(projectCustom)) {
348
+ dirs.push(projectCustom);
349
+ }
350
+ // 4. User-level custom themes
351
+ const userCustom = join(homedir(), '.claude', 'pennyfarthing', 'themes');
352
+ if (existsSync(userCustom)) {
353
+ dirs.push(userCustom);
354
+ }
355
+ return dirs;
356
+ }
357
+ /**
358
+ * Resolve the file path for a specific theme across all sources.
359
+ * Returns the first match found in priority order, or null.
360
+ */
361
+ export function resolveThemePath(themeId, projectRoot) {
362
+ const dirs = discoverAllThemeDirs(projectRoot);
363
+ for (const dir of dirs) {
364
+ const themePath = join(dir, `${themeId}.yaml`);
365
+ if (existsSync(themePath)) {
366
+ return themePath;
367
+ }
368
+ }
369
+ return null;
370
+ }
371
+ // ---------------------------------------------------------------------------
372
+ // Theme metadata loading
373
+ // ---------------------------------------------------------------------------
374
+ /**
375
+ * Load metadata for all discoverable themes.
376
+ * Deduplicates by theme ID (first source wins).
377
+ */
378
+ export function loadAllThemeMetadata(projectRoot) {
379
+ const dirs = discoverAllThemeDirs(projectRoot);
380
+ const seenIds = new Set();
381
+ const metadata = [];
382
+ for (const dir of dirs) {
383
+ let files;
384
+ try {
385
+ files = readdirSync(dir).filter(f => f.endsWith('.yaml')).sort();
386
+ }
387
+ catch {
388
+ continue;
389
+ }
390
+ for (const file of files) {
391
+ const themeId = basename(file, '.yaml');
392
+ if (seenIds.has(themeId))
393
+ continue;
394
+ seenIds.add(themeId);
395
+ try {
396
+ const content = readFileSync(join(dir, file), 'utf-8');
397
+ const parsed = parseYaml(content);
398
+ if (!parsed?.theme)
399
+ continue;
400
+ const agentCount = parsed.agents ? Object.keys(parsed.agents).length : 0;
401
+ metadata.push({
402
+ id: themeId,
403
+ name: parsed.theme.name || themeId,
404
+ description: parsed.theme.description || '',
405
+ source: parsed.theme.source || '',
406
+ tier: parsed.theme.tier || 'U',
407
+ category: deriveCategory(themeId, parsed.theme.source || ''),
408
+ agentCount,
409
+ });
410
+ }
411
+ catch {
412
+ // Skip unparseable files
413
+ }
414
+ }
415
+ }
416
+ return metadata;
417
+ }
418
+ // ---------------------------------------------------------------------------
419
+ // Existing API (kept stable)
420
+ // ---------------------------------------------------------------------------
421
+ /**
422
+ * Load a theme configuration by name.
423
+ * Searches all theme sources in priority order.
424
+ */
425
+ export function loadTheme(themeName) {
426
+ const themePath = resolveThemePath(themeName);
427
+ if (!themePath) {
428
+ return null;
429
+ }
430
+ try {
431
+ const content = readFileSync(themePath, 'utf-8');
432
+ const raw = parseYaml(content);
433
+ const agents = {};
434
+ for (const [agentKey, agentData] of Object.entries(raw.agents || {})) {
435
+ agents[agentKey] = {
436
+ character: agentData.character || '',
437
+ style: agentData.style || '',
438
+ role: agentData.role || '',
439
+ trait: agentData.trait || '',
440
+ catchphrases: agentData.catchphrases || [],
441
+ helper: agentData.helper?.name,
442
+ };
443
+ }
444
+ return {
445
+ name: themeName,
446
+ description: raw.theme?.description || '',
447
+ agents,
448
+ };
449
+ }
450
+ catch {
451
+ return null;
452
+ }
453
+ }
454
+ /**
455
+ * List all available theme IDs across all sources.
456
+ * Deduplicates — first source wins.
457
+ */
458
+ export function listThemes(projectRoot) {
459
+ const dirs = discoverAllThemeDirs(projectRoot);
460
+ const seenIds = new Set();
461
+ const themeIds = [];
462
+ for (const dir of dirs) {
463
+ try {
464
+ const files = readdirSync(dir);
465
+ for (const f of files) {
466
+ if (!f.endsWith('.yaml'))
467
+ continue;
468
+ const id = basename(f, '.yaml');
469
+ if (!seenIds.has(id)) {
470
+ seenIds.add(id);
471
+ themeIds.push(id);
472
+ }
473
+ }
474
+ }
475
+ catch {
476
+ // Skip unreadable dirs
477
+ }
478
+ }
479
+ return themeIds;
480
+ }
481
+ /**
482
+ * Get agent persona from a theme.
483
+ */
484
+ export function getAgentPersona(themeName, agentName) {
485
+ const theme = loadTheme(themeName);
486
+ if (!theme) {
487
+ return null;
488
+ }
489
+ return theme.agents[agentName] || null;
490
+ }
491
+ //# sourceMappingURL=theme-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-loader.js","sourceRoot":"","sources":["../src/theme-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAiEpF,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E;AAE9E,MAAM,CAAC,MAAM,YAAY,GAA2B;IAClD,YAAY;IACZ,eAAe,EAAE,WAAW;IAC5B,eAAe,EAAE,WAAW;IAC5B,eAAe,EAAE,WAAW;IAC5B,mBAAmB,EAAE,WAAW;IAChC,cAAc,EAAE,WAAW;IAC3B,YAAY,EAAE,WAAW;IACzB,UAAU,EAAE,WAAW;IACvB,iBAAiB,EAAE,WAAW;IAC9B,WAAW,EAAE,WAAW;IACxB,sBAAsB,EAAE,WAAW;IACnC,SAAS,EAAE,WAAW;IACtB,UAAU,EAAE,WAAW;IACvB,SAAS,EAAE,WAAW;IACtB,cAAc,EAAE,WAAW;IAC3B,sBAAsB,EAAE,WAAW;IACnC,eAAe,EAAE,WAAW;IAC5B,oBAAoB,EAAE,WAAW;IACjC,SAAS,EAAE,WAAW;IACtB,sBAAsB,EAAE,WAAW;IACnC,YAAY,EAAE,WAAW;IACzB,iBAAiB,EAAE,WAAW;IAC9B,gBAAgB,EAAE,WAAW;IAC7B,kBAAkB,EAAE,WAAW;IAC/B,eAAe,EAAE,WAAW;IAC5B,WAAW,EAAE,WAAW;IACxB,YAAY,EAAE,WAAW;IACzB,cAAc,EAAE,WAAW;IAC3B,UAAU,EAAE,WAAW;IACvB,QAAQ,EAAE,WAAW;IACrB,2BAA2B,EAAE,WAAW;IACxC,WAAW,EAAE,WAAW;IACxB,eAAe,EAAE,WAAW;IAC5B,MAAM,EAAE,WAAW;IACnB,aAAa,EAAE,WAAW;IAC1B,YAAY,EAAE,WAAW;IACzB,mBAAmB,EAAE,WAAW;IAChC,MAAM,EAAE,WAAW;IACnB,QAAQ,EAAE,WAAW;IACrB,aAAa;IACb,qBAAqB,EAAE,YAAY;IACnC,mBAAmB,EAAE,YAAY;IACjC,WAAW,EAAE,YAAY;IACzB,mBAAmB,EAAE,YAAY;IACjC,MAAM,EAAE,YAAY;IACpB,qBAAqB,EAAE,YAAY;IACnC,iBAAiB,EAAE,YAAY;IAC/B,cAAc,EAAE,YAAY;IAC5B,QAAQ,EAAE,YAAY;IACtB,YAAY,EAAE,YAAY;IAC1B,eAAe,EAAE,YAAY;IAC7B,oBAAoB,EAAE,YAAY;IAClC,UAAU,EAAE,YAAY;IACxB,YAAY,EAAE,YAAY;IAC1B,eAAe,EAAE,YAAY;IAC7B,aAAa,EAAE,YAAY;IAC3B,aAAa,EAAE,YAAY;IAC3B,oBAAoB,EAAE,YAAY;IAClC,UAAU,EAAE,YAAY;IACxB,MAAM,EAAE,YAAY;IACpB,iBAAiB,EAAE,YAAY;IAC/B,cAAc,EAAE,YAAY;IAC5B,SAAS,EAAE,YAAY;IACvB,WAAW,EAAE,YAAY;IACzB,SAAS,EAAE,YAAY;IACvB,OAAO,EAAE,YAAY;IACrB,aAAa,EAAE,YAAY;IAC3B,uBAAuB,EAAE,YAAY;IACrC,gBAAgB,EAAE,YAAY;IAC9B,cAAc,EAAE,YAAY;IAC5B,iBAAiB,EAAE,YAAY;IAC/B,WAAW,EAAE,YAAY;IACzB,cAAc,EAAE,YAAY;IAC5B,OAAO;IACP,WAAW,EAAE,MAAM;IACnB,QAAQ,EAAE,MAAM;IAChB,WAAW,EAAE,MAAM;IACnB,cAAc,EAAE,MAAM;IACtB,WAAW,EAAE,MAAM;IACnB,sBAAsB,EAAE,MAAM;IAC9B,YAAY,EAAE,MAAM;IACpB,cAAc,EAAE,MAAM;IACtB,oBAAoB,EAAE,MAAM;IAC5B,eAAe,EAAE,MAAM;IACvB,eAAe,EAAE,MAAM;IACvB,iBAAiB,EAAE,MAAM;IACzB,yBAAyB,EAAE,MAAM;IACjC,0BAA0B,EAAE,MAAM;IAClC,gBAAgB,EAAE,MAAM;IACxB,cAAc,EAAE,MAAM;IACtB,cAAc,EAAE,MAAM;IACtB,cAAc,EAAE,MAAM;IACtB,cAAc,EAAE,MAAM;IACtB,cAAc,EAAE,MAAM;IACtB,sBAAsB,EAAE,MAAM;IAC9B,WAAW,EAAE,MAAM;IACnB,WAAW,EAAE,MAAM;IACnB,UAAU,EAAE,MAAM;IAClB,YAAY,EAAE,MAAM;IACpB,OAAO,EAAE,MAAM;IACf,UAAU,EAAE,MAAM;IAClB,SAAS,EAAE,MAAM;IACjB,eAAe,EAAE,MAAM;IACvB,OAAO,EAAE,MAAM;IACf,iBAAiB,EAAE,MAAM;IACzB,cAAc,EAAE,MAAM;IACtB,SAAS,EAAE,MAAM;IACjB,KAAK,EAAE,MAAM;IACb,YAAY,EAAE,MAAM;IACpB,YAAY;IACZ,iBAAiB,EAAE,WAAW;IAC9B,iBAAiB,EAAE,WAAW;IAC9B,oBAAoB,EAAE,WAAW;IACjC,kBAAkB,EAAE,WAAW;IAC/B,oBAAoB,EAAE,WAAW;IACjC,iBAAiB,EAAE,WAAW;IAC9B,kBAAkB,EAAE,WAAW;IAC/B,QAAQ;IACR,OAAO,EAAE,OAAO;IAChB,OAAO,EAAE,OAAO;IAChB,eAAe,EAAE,OAAO;IACxB,aAAa,EAAE,OAAO;IACtB,UAAU,EAAE,OAAO;IACnB,QAAQ,EAAE,OAAO;IACjB,WAAW,EAAE,OAAO;IACpB,MAAM,EAAE,OAAO;IACf,WAAW,EAAE,OAAO;IACpB,mBAAmB,EAAE,OAAO;IAC5B,eAAe,EAAE,OAAO;IACxB,SAAS,EAAE,OAAO;IAClB,WAAW,EAAE,OAAO;IACpB,SAAS,EAAE,OAAO;IAClB,qBAAqB,EAAE,OAAO;IAC9B,YAAY,EAAE,OAAO;IACrB,YAAY,EAAE,OAAO;IACrB,YAAY,EAAE,OAAO;IACrB,YAAY,EAAE,OAAO;IACrB,SAAS,EAAE,OAAO;IAClB,iBAAiB,EAAE,OAAO;IAC1B,WAAW,EAAE,OAAO;IACpB,UAAU;IACV,cAAc,EAAE,SAAS;IACzB,gBAAgB,EAAE,SAAS;IAC3B,eAAe,EAAE,SAAS;IAC1B,aAAa,EAAE,SAAS;IACxB,eAAe,EAAE,SAAS;IAC1B,WAAW,EAAE,SAAS;IACtB,aAAa,EAAE,SAAS;IACxB,UAAU,EAAE,SAAS;IACrB,kBAAkB,EAAE,SAAS;IAC7B,QAAQ;IACR,qBAAqB,EAAE,OAAO;IAC9B,cAAc,EAAE,OAAO;IACvB,cAAc,EAAE,OAAO;IACvB,SAAS,EAAE,OAAO;IAClB,OAAO,EAAE,OAAO;IAChB,UAAU;IACV,YAAY,EAAE,SAAS;IACvB,mBAAmB,EAAE,SAAS;CAC/B,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,MAAc;IAC5D,IAAI,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1B,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAE/B,IAAI,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC;QAChD,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QACtC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/C,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;QACzC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC5C,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QACvD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC7C,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QACnD,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;QACzC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC1C,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACpD,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC9C,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;QACnD,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACvB,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;QACjD,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC9C,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC7C,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QACjD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,8EAA8E;AAC9E,0BAA0B;AAC1B,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,WAAoB;IACxD,MAAM,OAAO,GAAuB,EAAE,CAAC;IACvC,MAAM,QAAQ,GAAG,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAE9C,mDAAmD;IACnD,IAAI,UAAU,GAAG,QAAQ,CAAC;IAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,EAAE,gBAAgB,CAAC,CAAC;QACnE,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;gBACrC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;oBAC5B,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC;wBAAE,SAAS;oBAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;oBACpC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;oBACjD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;wBAAE,SAAS;oBAEvC,IAAI,CAAC;wBACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;wBAC/D,IAAI,OAAO,CAAC,0BAA0B,CAAC,KAAK,IAAI,EAAE,CAAC;4BACjD,OAAO,CAAC,IAAI,CAAC;gCACX,WAAW,EAAE,OAAO,CAAC,IAAI,IAAI,kBAAkB,KAAK,EAAE;gCACtD,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC;gCACjC,YAAY,EAAE,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC;6BACxC,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,8BAA8B;oBAChC,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,8BAA8B;YAChC,CAAC;YACD,MAAM,CAAC,sCAAsC;QAC/C,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QACtC,IAAI,SAAS,KAAK,UAAU;YAAE,MAAM;QACpC,UAAU,GAAG,SAAS,CAAC;IACzB,CAAC;IAED,iFAAiF;IACjF,6DAA6D;IAC7D,UAAU,GAAG,QAAQ,CAAC;IACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QACjD,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;gBACzC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;oBAC5B,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC;wBAAE,SAAS;oBAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;oBACxC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;oBACjD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;wBAAE,SAAS;oBAEvC,yCAAyC;oBACzC,IAAI,CAAC;wBACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;wBAC/D,IAAI,OAAO,CAAC,0BAA0B,CAAC,KAAK,IAAI,EAAE,CAAC;4BACjD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,OAAO,CAAC,IAAI,IAAI,kBAAkB,KAAK,EAAE,CAAC,CAAC,CAAC;4BACtG,IAAI,CAAC,YAAY,EAAE,CAAC;gCAClB,OAAO,CAAC,IAAI,CAAC;oCACX,WAAW,EAAE,OAAO,CAAC,IAAI,IAAI,kBAAkB,KAAK,EAAE;oCACtD,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC;oCACjC,YAAY,EAAE,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC;iCACxC,CAAC,CAAC;4BACL,CAAC;wBACH,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,8BAA8B;oBAChC,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,8BAA8B;YAChC,CAAC;YACD,MAAM;QACR,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QACtC,IAAI,SAAS,KAAK,UAAU;YAAE,MAAM;QACpC,UAAU,GAAG,SAAS,CAAC;IACzB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAoB;IACvD,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1C,yCAAyC;IACzC,MAAM,QAAQ,GAAG,wBAAwB,EAAE,CAAC;IAC5C,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACzC,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACtD,IAAI,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IAC7C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,iCAAiC;IACjC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC;IACvE,IAAI,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC3B,CAAC;IAED,8BAA8B;IAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC;IACzE,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,WAAoB;IACpE,MAAM,IAAI,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAC/C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,OAAO,CAAC,CAAC;QAC/C,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,yBAAyB;AACzB,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAoB;IACvD,MAAM,IAAI,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,QAAQ,GAAoB,EAAE,CAAC;IAErC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,KAAe,CAAC;QACpB,IAAI,CAAC;YACH,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACnE,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACxC,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;gBAAE,SAAS;YACnC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAErB,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;gBACvD,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAa,CAAC;gBAC9C,IAAI,CAAC,MAAM,EAAE,KAAK;oBAAE,SAAS;gBAE7B,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;gBAEzE,QAAQ,CAAC,IAAI,CAAC;oBACZ,EAAE,EAAE,OAAO;oBACX,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO;oBAClC,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE;oBAC3C,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE;oBACjC,IAAI,EAAG,MAAM,CAAC,KAAK,CAAC,IAA8B,IAAI,GAAG;oBACzD,QAAQ,EAAE,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;oBAC5D,UAAU;iBACX,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,yBAAyB;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,8EAA8E;AAC9E,6BAA6B;AAC7B,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,SAAiB;IACzC,MAAM,SAAS,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC9C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAa,CAAC;QAE3C,MAAM,MAAM,GAA+B,EAAE,CAAC;QAC9C,KAAK,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;YACrE,MAAM,CAAC,QAAQ,CAAC,GAAG;gBACjB,SAAS,EAAE,SAAS,CAAC,SAAS,IAAI,EAAE;gBACpC,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,EAAE;gBAC5B,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,EAAE;gBAC1B,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,EAAE;gBAC5B,YAAY,EAAE,SAAS,CAAC,YAAY,IAAI,EAAE;gBAC1C,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,IAAI;aAC/B,CAAC;QACJ,CAAC;QAED,OAAO;YACL,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,GAAG,CAAC,KAAK,EAAE,WAAW,IAAI,EAAE;YACzC,MAAM;SACP,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,WAAoB;IAC7C,MAAM,IAAI,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YAC/B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;oBAAE,SAAS;gBACnC,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;gBAChC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBACrB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBAChB,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACpB,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,uBAAuB;QACzB,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,SAAiB,EAAE,SAAiB;IAClE,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;AACzC,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Theme Schema Consolidation Tests - MSSCI-12478
3
+ *
4
+ * Tests for consolidating quote field into catchphrases array.
5
+ * RED STATE: These tests should FAIL until implementation is complete.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=theme-loader.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-loader.test.d.ts","sourceRoot":"","sources":["../src/theme-loader.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Theme Schema Consolidation Tests - MSSCI-12478
3
+ *
4
+ * Tests for consolidating quote field into catchphrases array.
5
+ * RED STATE: These tests should FAIL until implementation is complete.
6
+ */
7
+ import { describe, it } from 'node:test';
8
+ import assert from 'node:assert';
9
+ import { loadTheme } from './theme-loader.js';
10
+ describe('MSSCI-12478: Theme Schema Consolidation', () => {
11
+ describe('AC3: quote field removed from schema', () => {
12
+ it('ThemeAgent interface should have catchphrases array, not quote string', () => {
13
+ // Load any theme and check the agent structure
14
+ const theme = loadTheme('the-expanse');
15
+ assert.ok(theme !== null, 'Theme should load');
16
+ const agent = theme.agents['sm'];
17
+ assert.ok(agent !== undefined, 'SM agent should exist');
18
+ // Should have catchphrases array
19
+ assert.ok('catchphrases' in agent, 'Agent should have catchphrases property');
20
+ assert.ok(Array.isArray(agent.catchphrases), 'catchphrases should be an array');
21
+ // Should NOT have quote field (removed from schema)
22
+ assert.ok(!('quote' in agent), 'Agent should NOT have quote property after migration');
23
+ });
24
+ it('catchphrases array should contain at least one entry', () => {
25
+ const theme = loadTheme('the-expanse');
26
+ assert.ok(theme !== null, 'Theme should load');
27
+ const agent = theme.agents['tea'];
28
+ assert.ok(agent.catchphrases !== undefined, 'catchphrases should be defined');
29
+ assert.ok(agent.catchphrases.length > 0, 'catchphrases should have at least one entry');
30
+ });
31
+ });
32
+ describe('AC1: Migration script merges quote into catchphrases', () => {
33
+ it('original quote should be present in catchphrases array', () => {
34
+ // The Investigator's quote was "Doors and corners, kid. That's where they get you."
35
+ // After migration, this should be in the catchphrases array
36
+ const theme = loadTheme('the-expanse');
37
+ assert.ok(theme !== null, 'Theme should load');
38
+ const agent = theme.agents['orchestrator'];
39
+ assert.ok(agent.catchphrases.includes("Doors and corners, kid. That's where they get you."), 'Original quote should be in catchphrases array');
40
+ });
41
+ it('catchphrases should not have duplicates after migration', () => {
42
+ const theme = loadTheme('the-expanse');
43
+ assert.ok(theme !== null, 'Theme should load');
44
+ const agent = theme.agents['sm'];
45
+ // Check for duplicates
46
+ const uniqueCatchphrases = [...new Set(agent.catchphrases)];
47
+ assert.strictEqual(agent.catchphrases.length, uniqueCatchphrases.length, 'catchphrases should have no duplicates');
48
+ });
49
+ });
50
+ describe('AC4: Theme validation updated', () => {
51
+ it('should parse catchphrases array from YAML', () => {
52
+ const theme = loadTheme('star-trek-tng');
53
+ assert.ok(theme !== null, 'Theme should load');
54
+ // Every agent should have catchphrases parsed
55
+ for (const [agentName, agent] of Object.entries(theme.agents)) {
56
+ assert.ok(agent.catchphrases !== undefined, `Agent ${agentName} should have catchphrases`);
57
+ assert.ok(Array.isArray(agent.catchphrases), `Agent ${agentName} catchphrases should be array`);
58
+ }
59
+ });
60
+ });
61
+ });
62
+ //# sourceMappingURL=theme-loader.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-loader.test.js","sourceRoot":"","sources":["../src/theme-loader.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,10 +1,20 @@
1
1
  {
2
2
  "name": "@pennyfarthing/shared",
3
- "version": "7.5.0",
3
+ "version": "9.3.0",
4
4
  "description": "Shared utilities for Pennyfarthing including portrait path resolution",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ },
13
+ "./browser": {
14
+ "types": "./dist/browser.d.ts",
15
+ "default": "./dist/browser.js"
16
+ }
17
+ },
8
18
  "files": [
9
19
  "dist/"
10
20
  ],
@@ -34,5 +44,8 @@
34
44
  "devDependencies": {
35
45
  "@types/node": "^20.10.0",
36
46
  "typescript": "^5.3.3"
47
+ },
48
+ "dependencies": {
49
+ "yaml": "^2.8.2"
37
50
  }
38
51
  }