@scenetest/scenes 0.1.2 → 0.2.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 (64) hide show
  1. package/dist/__tests__/markdown-scene.test.js +134 -2
  2. package/dist/__tests__/markdown-scene.test.js.map +1 -1
  3. package/dist/__tests__/selectors.test.d.ts +2 -0
  4. package/dist/__tests__/selectors.test.d.ts.map +1 -0
  5. package/dist/__tests__/selectors.test.js +165 -0
  6. package/dist/__tests__/selectors.test.js.map +1 -0
  7. package/dist/__tests__/swarm.test.js +1 -0
  8. package/dist/__tests__/swarm.test.js.map +1 -1
  9. package/dist/__tests__/team-manager.test.d.ts +2 -0
  10. package/dist/__tests__/team-manager.test.d.ts.map +1 -0
  11. package/dist/__tests__/team-manager.test.js +180 -0
  12. package/dist/__tests__/team-manager.test.js.map +1 -0
  13. package/dist/__tests__/warmup.test.d.ts +2 -0
  14. package/dist/__tests__/warmup.test.d.ts.map +1 -0
  15. package/dist/__tests__/warmup.test.js +170 -0
  16. package/dist/__tests__/warmup.test.js.map +1 -0
  17. package/dist/cli.js +37 -1
  18. package/dist/cli.js.map +1 -1
  19. package/dist/config.d.ts +21 -2
  20. package/dist/config.d.ts.map +1 -1
  21. package/dist/config.js +54 -4
  22. package/dist/config.js.map +1 -1
  23. package/dist/index.d.ts +3 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/markdown-scene.d.ts +2 -0
  28. package/dist/markdown-scene.d.ts.map +1 -1
  29. package/dist/markdown-scene.js +24 -7
  30. package/dist/markdown-scene.js.map +1 -1
  31. package/dist/prompt-generator.d.ts +59 -0
  32. package/dist/prompt-generator.d.ts.map +1 -0
  33. package/dist/prompt-generator.js +517 -0
  34. package/dist/prompt-generator.js.map +1 -0
  35. package/dist/reactive.d.ts +2 -1
  36. package/dist/reactive.d.ts.map +1 -1
  37. package/dist/reactive.js +22 -53
  38. package/dist/reactive.js.map +1 -1
  39. package/dist/runner.d.ts +8 -2
  40. package/dist/runner.d.ts.map +1 -1
  41. package/dist/runner.js +70 -3
  42. package/dist/runner.js.map +1 -1
  43. package/dist/scene.d.ts +8 -1
  44. package/dist/scene.d.ts.map +1 -1
  45. package/dist/scene.js +6 -15
  46. package/dist/scene.js.map +1 -1
  47. package/dist/selectors.d.ts.map +1 -1
  48. package/dist/selectors.js +8 -39
  49. package/dist/selectors.js.map +1 -1
  50. package/dist/swarm.d.ts +1 -1
  51. package/dist/swarm.d.ts.map +1 -1
  52. package/dist/swarm.js +10 -1
  53. package/dist/swarm.js.map +1 -1
  54. package/dist/team-manager.d.ts +28 -5
  55. package/dist/team-manager.d.ts.map +1 -1
  56. package/dist/team-manager.js +94 -15
  57. package/dist/team-manager.js.map +1 -1
  58. package/dist/types.d.ts +92 -0
  59. package/dist/types.d.ts.map +1 -1
  60. package/dist/warmup.d.ts +61 -0
  61. package/dist/warmup.d.ts.map +1 -0
  62. package/dist/warmup.js +186 -0
  63. package/dist/warmup.js.map +1 -0
  64. package/package.json +2 -2
@@ -0,0 +1,517 @@
1
+ /**
2
+ * LLM Prompt Generator for Team/Seed Data Creation
3
+ *
4
+ * Analyzes the user's project and generates context-rich prompts that can be
5
+ * fed to an LLM (Claude, GPT, etc.) to generate team configurations and
6
+ * corresponding seed data for scenetest.
7
+ *
8
+ * The generator scans for:
9
+ * - User/account models (TypeScript types, Prisma schema, etc.)
10
+ * - Database schemas
11
+ * - Existing seeds
12
+ * - Existing actor team files (scenetest/actors/)
13
+ * - Existing scene specs (scenetest/scenes/)
14
+ * - Auth-related files
15
+ */
16
+ import fs from 'fs';
17
+ import path from 'path';
18
+ import { glob } from 'glob';
19
+ /**
20
+ * Gather project context for prompt generation.
21
+ *
22
+ * Scans the project for relevant files that an LLM would need to understand
23
+ * the application's user model, data layer, and existing test setup.
24
+ */
25
+ export async function gatherProjectContext(configPath) {
26
+ const cwd = process.cwd();
27
+ const projectName = path.basename(cwd);
28
+ // Try to load package.json
29
+ let packageJson;
30
+ const pkgPath = path.join(cwd, 'package.json');
31
+ if (fs.existsSync(pkgPath)) {
32
+ try {
33
+ packageJson = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
34
+ }
35
+ catch {
36
+ // Ignore parse errors
37
+ }
38
+ }
39
+ // Find scenetest config (new location: scenetest/config.ts)
40
+ const configFile = await findFile(cwd, [
41
+ 'scenetest/config.ts',
42
+ 'scenetest/config.js',
43
+ 'scenetest/config.mjs',
44
+ ]);
45
+ // Find existing actor team files (new location: scenetest/actors/)
46
+ const existingActors = await findFilesMatching(cwd, [
47
+ 'scenetest/actors/*.ts',
48
+ 'scenetest/actors/*.js',
49
+ 'scenetest/actors/*.mjs',
50
+ ]);
51
+ // Find user models (common patterns)
52
+ const userModels = await findFilesMatching(cwd, [
53
+ '**/models/user*.ts',
54
+ '**/models/User*.ts',
55
+ '**/types/user*.ts',
56
+ '**/types/User*.ts',
57
+ '**/schema/user*.ts',
58
+ '**/schema/User*.ts',
59
+ '**/entities/user*.ts',
60
+ '**/entities/User*.ts',
61
+ '**/prisma/schema.prisma',
62
+ '**/drizzle/schema*.ts',
63
+ '**/db/schema*.ts',
64
+ ]);
65
+ // Find existing seeds
66
+ const existingSeeds = await findFilesMatching(cwd, [
67
+ '**/seeds/**/*.ts',
68
+ '**/seeds/**/*.js',
69
+ '**/seed/**/*.ts',
70
+ '**/seed/**/*.js',
71
+ '**/prisma/seed.ts',
72
+ '**/prisma/seed.js',
73
+ '**/db/seed*.ts',
74
+ '**/db/seed*.js',
75
+ ]);
76
+ // Find existing scenes (to understand what roles are used)
77
+ const existingScenes = await findFilesMatching(cwd, ['scenetest/scenes/**/*.spec.ts', 'scenetest/scenes/**/*.spec.md'], 5);
78
+ // Find auth-related files
79
+ const authPatterns = await findFilesMatching(cwd, [
80
+ '**/auth/**/*.ts',
81
+ '**/auth.ts',
82
+ '**/authentication*.ts',
83
+ '**/login*.ts',
84
+ '**/middleware/auth*.ts',
85
+ ]);
86
+ // Find database schema files
87
+ const dbSchema = await findFilesMatching(cwd, [
88
+ '**/prisma/schema.prisma',
89
+ '**/drizzle/schema*.ts',
90
+ '**/drizzle/*.ts',
91
+ '**/db/schema*.ts',
92
+ '**/schema.sql',
93
+ '**/migrations/*.sql',
94
+ ]);
95
+ return {
96
+ projectName,
97
+ packageJson,
98
+ userModels,
99
+ existingSeeds,
100
+ existingActors,
101
+ existingScenes,
102
+ authPatterns,
103
+ dbSchema,
104
+ configFile,
105
+ };
106
+ }
107
+ async function findFile(cwd, patterns) {
108
+ for (const pattern of patterns) {
109
+ const fullPath = path.join(cwd, pattern);
110
+ if (fs.existsSync(fullPath)) {
111
+ try {
112
+ const content = fs.readFileSync(fullPath, 'utf-8');
113
+ return { path: pattern, content: truncateContent(content) };
114
+ }
115
+ catch {
116
+ // Ignore read errors
117
+ }
118
+ }
119
+ }
120
+ return null;
121
+ }
122
+ async function findFilesMatching(cwd, patterns, maxFiles = 10) {
123
+ const results = [];
124
+ const seen = new Set();
125
+ for (const pattern of patterns) {
126
+ if (results.length >= maxFiles)
127
+ break;
128
+ try {
129
+ const files = await glob(pattern, {
130
+ cwd,
131
+ ignore: ['**/node_modules/**', '**/dist/**', '**/.git/**'],
132
+ absolute: false,
133
+ });
134
+ for (const file of files) {
135
+ if (results.length >= maxFiles)
136
+ break;
137
+ if (seen.has(file))
138
+ continue;
139
+ seen.add(file);
140
+ const fullPath = path.join(cwd, file);
141
+ try {
142
+ const content = fs.readFileSync(fullPath, 'utf-8');
143
+ results.push({ path: file, content: truncateContent(content) });
144
+ }
145
+ catch {
146
+ // Ignore read errors
147
+ }
148
+ }
149
+ }
150
+ catch {
151
+ // Ignore glob errors
152
+ }
153
+ }
154
+ return results;
155
+ }
156
+ function truncateContent(content, maxLines = 150) {
157
+ const lines = content.split('\n');
158
+ if (lines.length <= maxLines)
159
+ return content;
160
+ return lines.slice(0, maxLines).join('\n') + `\n\n... (${lines.length - maxLines} more lines)`;
161
+ }
162
+ // ─── Prompt generators ──────────────────────────────────────────────────────
163
+ /**
164
+ * Generate an LLM prompt for team/actor generation
165
+ */
166
+ export function generateTeamsPrompt(ctx) {
167
+ const sections = [];
168
+ sections.push(`# Generate Scenetest Actor Teams
169
+
170
+ I need help creating scenetest team configurations for my project.
171
+
172
+ ## Project: ${ctx.projectName}
173
+ `);
174
+ if (ctx.packageJson) {
175
+ const deps = {
176
+ ...ctx.packageJson.dependencies,
177
+ ...ctx.packageJson.devDependencies,
178
+ };
179
+ const relevantDeps = Object.keys(deps).filter((d) => d.includes('prisma') ||
180
+ d.includes('drizzle') ||
181
+ d.includes('sequelize') ||
182
+ d.includes('typeorm') ||
183
+ d.includes('mongoose') ||
184
+ d.includes('auth') ||
185
+ d.includes('passport') ||
186
+ d.includes('next-auth') ||
187
+ d.includes('lucia') ||
188
+ d.includes('clerk'));
189
+ if (relevantDeps.length > 0) {
190
+ sections.push(`**Relevant dependencies:** ${relevantDeps.join(', ')}\n`);
191
+ }
192
+ }
193
+ if (ctx.userModels.length > 0) {
194
+ sections.push(`## User/Account Models\n`);
195
+ for (const model of ctx.userModels) {
196
+ sections.push(`### ${model.path}\n\`\`\`\n${model.content}\n\`\`\`\n`);
197
+ }
198
+ }
199
+ if (ctx.dbSchema.length > 0) {
200
+ sections.push(`## Database Schema\n`);
201
+ for (const schema of ctx.dbSchema.slice(0, 3)) {
202
+ sections.push(`### ${schema.path}\n\`\`\`\n${schema.content}\n\`\`\`\n`);
203
+ }
204
+ }
205
+ if (ctx.existingActors.length > 0) {
206
+ sections.push(`## Existing Actor Teams (for reference)\n`);
207
+ for (const actor of ctx.existingActors) {
208
+ sections.push(`### ${actor.path}\n\`\`\`typescript\n${actor.content}\n\`\`\`\n`);
209
+ }
210
+ }
211
+ if (ctx.existingScenes.length > 0) {
212
+ sections.push(`## Existing Scenes (to understand what roles are used)\n`);
213
+ for (const scene of ctx.existingScenes.slice(0, 3)) {
214
+ sections.push(`### ${scene.path}\n\`\`\`\n${scene.content}\n\`\`\`\n`);
215
+ }
216
+ }
217
+ sections.push(`## Scenetest Team Format
218
+
219
+ Teams live in \`scenetest/actors/\`, one file per team. Each file exports a single team object mapping role names to actor configs.
220
+
221
+ ### File structure
222
+
223
+ \`\`\`
224
+ your-project/
225
+ scenetest/
226
+ config.ts
227
+ actors/
228
+ team-maria.ts ← one team per file
229
+ team-john.ts
230
+ scenes/
231
+ ...
232
+ \`\`\`
233
+
234
+ ### Team file format
235
+
236
+ \`\`\`typescript
237
+ // scenetest/actors/team-maria.ts
238
+ import type { TeamConfig } from '@scenetest/scenes'
239
+
240
+ export default {
241
+ 'primary-learner': {
242
+ key: 'maria-1', // Unique key (used for data-key matching in DOM)
243
+ email: 'maria@test.com',
244
+ password: 'test123',
245
+ nativeLanguage: 'english', // Custom fields are allowed
246
+ },
247
+ 'existing-friend': {
248
+ key: 'carlos-1',
249
+ email: 'carlos@test.com',
250
+ password: 'test123',
251
+ },
252
+ 'new-signup': {
253
+ key: 'fresh-a-1',
254
+ email: 'fresh-a@test.com',
255
+ password: 'willregister123',
256
+ },
257
+ } satisfies TeamConfig
258
+ \`\`\`
259
+
260
+ ### Key requirements
261
+
262
+ - **Every team must have identical role names** — scenes call \`actor('role-name')\`, and that role must exist in every team
263
+ - **\`key\`** is the only required field on ActorConfig (used for data-key selector matching)
264
+ - Credentials (\`email\`, \`password\`, \`username\`) must match seed data users
265
+ - Relationships (friendships, org membership, etc.) between actors must exist in seed data
266
+ - Each team is a self-contained "world" — no cross-team references
267
+ - Use descriptive role names: \`primary-buyer\`, \`competing-seller\`, not \`user\`, \`admin\`
268
+
269
+ ## What I Need
270
+
271
+ Generate actor team files for my project:
272
+ 1. Identify the user types and relationships in my app
273
+ 2. Create 2-3 team files in \`scenetest/actors/\`
274
+ 3. Use descriptive, scenario-based role names
275
+ 4. Include all credential fields my app needs
276
+ 5. Note what relationships need to exist in seed data
277
+ `);
278
+ return sections.join('\n');
279
+ }
280
+ /**
281
+ * Generate an LLM prompt for seed data generation
282
+ */
283
+ export function generateSeedsPrompt(ctx) {
284
+ const sections = [];
285
+ sections.push(`# Generate Seed Data for Scenetest Teams
286
+
287
+ I need help creating seed data that matches my scenetest actor teams.
288
+
289
+ ## Project: ${ctx.projectName}
290
+ `);
291
+ if (ctx.existingActors.length > 0) {
292
+ sections.push(`## Actor Team Files\n`);
293
+ for (const actor of ctx.existingActors) {
294
+ sections.push(`### ${actor.path}\n\`\`\`typescript\n${actor.content}\n\`\`\`\n`);
295
+ }
296
+ }
297
+ else {
298
+ sections.push(`## Actor Teams
299
+
300
+ **No actor files found in \`scenetest/actors/\`.** Please either:
301
+ 1. First generate team configurations (\`scenetest prompt teams\`)
302
+ 2. Or paste your team files here
303
+ `);
304
+ }
305
+ if (ctx.dbSchema.length > 0) {
306
+ sections.push(`## Database Schema\n`);
307
+ for (const schema of ctx.dbSchema) {
308
+ sections.push(`### ${schema.path}\n\`\`\`\n${schema.content}\n\`\`\`\n`);
309
+ }
310
+ }
311
+ if (ctx.existingSeeds.length > 0) {
312
+ sections.push(`## Existing Seed Files (for style reference)\n`);
313
+ for (const seed of ctx.existingSeeds.slice(0, 3)) {
314
+ sections.push(`### ${seed.path}\n\`\`\`\n${seed.content}\n\`\`\`\n`);
315
+ }
316
+ }
317
+ if (ctx.authPatterns.length > 0) {
318
+ sections.push(`## Auth Implementation (for password hashing, etc.)\n`);
319
+ for (const auth of ctx.authPatterns.slice(0, 2)) {
320
+ sections.push(`### ${auth.path}\n\`\`\`\n${auth.content}\n\`\`\`\n`);
321
+ }
322
+ }
323
+ sections.push(`## What I Need
324
+
325
+ Generate seed data files that:
326
+
327
+ 1. **Create users** matching every actor in every team file
328
+ 2. **Establish relationships** between actors (friendships, org membership, etc.)
329
+ 3. **Match my existing seed style** (if I have existing seeds above)
330
+ 4. **Include supporting data** that tests might need (posts, products, etc.)
331
+
332
+ ### Key requirements
333
+
334
+ - User credentials must match exactly: the email/password in actor files must work to log in
335
+ - Passwords must be hashed using my app's auth system
336
+ - Relationships assumed by scenes must be seeded (e.g., if a scene expects two actors to be friends, the friendship must exist)
337
+ - Each team's data is self-contained — all relationships hold within a single team
338
+
339
+ ### Output format
340
+
341
+ Generate:
342
+ 1. Seed data files in my project's format/style
343
+ 2. A seed runner script if I don't have one
344
+ 3. A list of all relationships established between actors
345
+ `);
346
+ return sections.join('\n');
347
+ }
348
+ /**
349
+ * Generate a combined prompt for both teams and seeds
350
+ */
351
+ export function generateCombinedPrompt(ctx) {
352
+ const sections = [];
353
+ sections.push(`# Generate Scenetest Teams and Seed Data
354
+
355
+ I'm setting up scenetest for my project and need both actor team files and matching seed data.
356
+
357
+ ## Project: ${ctx.projectName}
358
+ `);
359
+ if (ctx.packageJson) {
360
+ const deps = {
361
+ ...ctx.packageJson.dependencies,
362
+ ...ctx.packageJson.devDependencies,
363
+ };
364
+ const relevantDeps = Object.keys(deps).filter((d) => d.includes('prisma') ||
365
+ d.includes('drizzle') ||
366
+ d.includes('sequelize') ||
367
+ d.includes('typeorm') ||
368
+ d.includes('mongoose') ||
369
+ d.includes('auth') ||
370
+ d.includes('passport') ||
371
+ d.includes('next-auth') ||
372
+ d.includes('lucia') ||
373
+ d.includes('clerk') ||
374
+ d.includes('react') ||
375
+ d.includes('vue') ||
376
+ d.includes('svelte') ||
377
+ d.includes('solid'));
378
+ if (relevantDeps.length > 0) {
379
+ sections.push(`**Tech stack:** ${relevantDeps.join(', ')}\n`);
380
+ }
381
+ }
382
+ if (ctx.userModels.length > 0) {
383
+ sections.push(`## User/Account Models\n`);
384
+ for (const model of ctx.userModels) {
385
+ sections.push(`### ${model.path}\n\`\`\`\n${model.content}\n\`\`\`\n`);
386
+ }
387
+ }
388
+ if (ctx.dbSchema.length > 0) {
389
+ sections.push(`## Database Schema\n`);
390
+ for (const schema of ctx.dbSchema.slice(0, 3)) {
391
+ sections.push(`### ${schema.path}\n\`\`\`\n${schema.content}\n\`\`\`\n`);
392
+ }
393
+ }
394
+ if (ctx.existingSeeds.length > 0) {
395
+ sections.push(`## Existing Seed Files (for style reference)\n`);
396
+ for (const seed of ctx.existingSeeds.slice(0, 2)) {
397
+ sections.push(`### ${seed.path}\n\`\`\`\n${seed.content}\n\`\`\`\n`);
398
+ }
399
+ }
400
+ if (ctx.existingScenes.length > 0) {
401
+ sections.push(`## Existing Scenes (to understand usage patterns)\n`);
402
+ for (const scene of ctx.existingScenes.slice(0, 2)) {
403
+ sections.push(`### ${scene.path}\n\`\`\`\n${scene.content}\n\`\`\`\n`);
404
+ }
405
+ }
406
+ sections.push(`## Scenetest Project Layout
407
+
408
+ \`\`\`
409
+ your-project/
410
+ scenetest/
411
+ config.ts ← project config
412
+ actors/
413
+ team-maria.ts ← one team per file
414
+ team-john.ts
415
+ scenes/
416
+ onboarding.spec.ts
417
+ social/
418
+ friend-request.spec.ts
419
+ \`\`\`
420
+
421
+ ## Team File Format
422
+
423
+ Each file in \`scenetest/actors/\` exports one team:
424
+
425
+ \`\`\`typescript
426
+ // scenetest/actors/team-maria.ts
427
+ import type { TeamConfig } from '@scenetest/scenes'
428
+
429
+ export default {
430
+ 'primary-learner': {
431
+ key: 'maria-1',
432
+ email: 'maria@test.com',
433
+ password: 'test123',
434
+ },
435
+ 'existing-friend': {
436
+ key: 'carlos-1',
437
+ email: 'carlos@test.com',
438
+ password: 'test123',
439
+ },
440
+ } satisfies TeamConfig
441
+ \`\`\`
442
+
443
+ - \`key\` is the only required field (used for data-key selector matching)
444
+ - Every team must have the same role names
445
+ - Credentials must match seed data users
446
+ - Use descriptive role names: \`primary-buyer\`, not \`user\`
447
+
448
+ ## What I Need
449
+
450
+ ### Part 1: Actor Teams
451
+
452
+ Generate 2-3 team files for \`scenetest/actors/\`:
453
+ - Identify user types from my models/schema
454
+ - Choose descriptive, scenario-based role names
455
+ - Include credentials that match seed data
456
+
457
+ ### Part 2: Seed Data
458
+
459
+ Generate seed files that:
460
+ - Create all users from the team files
461
+ - Establish relationships between actors
462
+ - Follow my existing seed patterns
463
+ - Include supporting data for tests
464
+
465
+ ### Output
466
+
467
+ 1. Complete team files (one per team)
468
+ 2. Seed data files in my project's format
469
+ 3. Explanation of each role and its purpose
470
+ 4. List of relationships established in seeds
471
+ `);
472
+ return sections.join('\n');
473
+ }
474
+ /**
475
+ * Generate the appropriate prompt based on type
476
+ */
477
+ export function generatePrompt(ctx, type) {
478
+ switch (type) {
479
+ case 'teams':
480
+ return generateTeamsPrompt(ctx);
481
+ case 'seeds':
482
+ return generateSeedsPrompt(ctx);
483
+ case 'both':
484
+ return generateCombinedPrompt(ctx);
485
+ }
486
+ }
487
+ /**
488
+ * Format the prompt for CLI output with header/footer
489
+ */
490
+ export function formatPromptOutput(prompt, type) {
491
+ const divider = '='.repeat(60);
492
+ const label = type === 'both' ? 'teams and seed data' : type;
493
+ return `
494
+ ${divider}
495
+ SCENETEST PROMPT GENERATOR - ${type.toUpperCase()}
496
+ ${divider}
497
+
498
+ Copy the prompt below and paste it into your preferred LLM
499
+ (Claude, ChatGPT, etc.) to generate your ${label}.
500
+
501
+ ${divider}
502
+
503
+ ${prompt}
504
+
505
+ ${divider}
506
+ END OF PROMPT
507
+ ${divider}
508
+
509
+ Tips:
510
+ - Review the prompt and add any missing context about your app
511
+ - Specify the number of teams you want (2-3 is typical)
512
+ - Mention any specific test scenarios you're planning
513
+ - After generating, audit alignment with: building-teams.md audit prompt
514
+
515
+ `;
516
+ }
517
+ //# sourceMappingURL=prompt-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-generator.js","sourceRoot":"","sources":["../src/prompt-generator.ts"],"names":[],"mappings":"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"}
@@ -46,7 +46,7 @@
46
46
  * ```
47
47
  */
48
48
  import type { Page } from 'playwright';
49
- import type { ActorConfig, Selector, TimelineEntry, ScriptWarning, FlowFn, ConcurrentActorHandle } from './types.js';
49
+ import type { ActorConfig, Selector, TimelineEntry, ScriptWarning, FlowFn, SceneOptions, ConcurrentActorHandle } from './types.js';
50
50
  import { MessageBus } from './message-bus.js';
51
51
  /**
52
52
  * Concurrent actor handle implementation (declarative / flow model).
@@ -275,4 +275,5 @@ export declare function drainAll(actors: ConcurrentActorHandleImpl[]): Promise<v
275
275
  * ```
276
276
  */
277
277
  export declare function flow(name: string, fn: FlowFn): void;
278
+ export declare function flow(name: string, options: SceneOptions, fn: FlowFn): void;
278
279
  //# sourceMappingURL=reactive.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reactive.d.ts","sourceRoot":"","sources":["../src/reactive.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reactive.d.ts","sourceRoot":"","sources":["../src/reactive.ts"],"names":[],"mappings":"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"}
package/dist/reactive.js CHANGED
@@ -750,59 +750,12 @@ export async function drainAll(actors) {
750
750
  throw (original ?? failures[0]).reason;
751
751
  }
752
752
  }
753
- // ---------------------------------------------------------------------------
754
- // flow() reactive scene registration
755
- // ---------------------------------------------------------------------------
756
- /**
757
- * Define a reactive flow.
758
- *
759
- * Inside the flow function, actor DSL calls just queue actions — nothing
760
- * executes. After the function returns, all actors drain their queues
761
- * concurrently through the application.
762
- *
763
- * @example
764
- * ```ts
765
- * import { flow } from '@scenetest/scenes'
766
- *
767
- * flow('user updates profile', ({ actor }) => {
768
- * const user = actor('user')
769
- *
770
- * user.openTo('/login')
771
- * user
772
- * .see('login-form')
773
- * .typeInto('email', user.email!)
774
- * .typeInto('password', user.password!)
775
- * .click('submit')
776
- *
777
- * user.see('dashboard')
778
- * user.openTo('/profile')
779
- * user
780
- * .see('profile-form')
781
- * .typeInto('name-input', 'New Name')
782
- * .click('save-button')
783
- *
784
- * user.seeText('New Name')
785
- * })
786
- * ```
787
- *
788
- * @example Multi-actor
789
- * ```ts
790
- * flow('two users chat', ({ actor }) => {
791
- * const alice = actor('alice')
792
- * const bob = actor('bob')
793
- *
794
- * alice.openTo('/chat')
795
- * alice.see('message-input').typeInto('message-input', 'Hello!').click('send')
796
- *
797
- * bob.openTo('/chat')
798
- * bob.seeText('Hello!')
799
- * })
800
- * ```
801
- */
802
- export function flow(name, fn) {
753
+ export function flow(name, fnOrOptions, maybeFn) {
754
+ const fn = typeof fnOrOptions === 'function' ? fnOrOptions : maybeFn;
755
+ const options = typeof fnOrOptions === 'function' ? undefined : fnOrOptions;
803
756
  // Register as a normal scene — the runner doesn't need to know it's
804
757
  // reactive. The wrapping scene fn handles the three-phase execution.
805
- scene(name, async (context) => {
758
+ const wrappedFn = async (context) => {
806
759
  const session = getCurrentSession();
807
760
  if (!session) {
808
761
  throw new Error('flow() must be run inside the scene runner');
@@ -811,6 +764,12 @@ export function flow(name, fn) {
811
764
  const actorRoles = [];
812
765
  // Actor registry for [role.field] interpolation across actors
813
766
  const actorRegistry = new Map();
767
+ // Build team metadata for [team.field] interpolation from tags
768
+ const teamMeta = session.meta;
769
+ const teamMetadataForInterpolation = {
770
+ ...(teamMeta.tags ?? {}),
771
+ ...(teamMeta.name ? { name: teamMeta.name } : {}),
772
+ };
814
773
  const flowContext = {
815
774
  actor: (role) => {
816
775
  // Check if already created (re-referencing an actor)
@@ -829,6 +788,7 @@ export function flow(name, fn) {
829
788
  return reactive;
830
789
  },
831
790
  teamIndex: context.teamIndex,
791
+ team: teamMeta,
832
792
  };
833
793
  // Phase 1: Declaration — user code queues actions, nothing executes.
834
794
  // actor() is synchronous so the flow body can be sync too.
@@ -836,9 +796,12 @@ export function flow(name, fn) {
836
796
  if (result && typeof result.then === 'function') {
837
797
  await result;
838
798
  }
839
- // Set actor registry on all actors for [role.field] interpolation
799
+ // Set actor registry and team metadata on all actors for interpolation
840
800
  for (const actor of reactiveActors) {
841
801
  actor._setActorRegistry(actorRegistry);
802
+ if (Object.keys(teamMetadataForInterpolation).length > 0) {
803
+ actor._setTeamMetadata(teamMetadataForInterpolation);
804
+ }
842
805
  }
843
806
  // Phase 2: Initialize — create browser contexts in parallel
844
807
  await Promise.all(reactiveActors.map(async (actor, i) => {
@@ -847,6 +810,12 @@ export function flow(name, fn) {
847
810
  }));
848
811
  // Phase 3: Execution — all actors drain concurrently
849
812
  await drainAll(reactiveActors);
850
- });
813
+ };
814
+ if (options) {
815
+ scene(name, options, wrappedFn);
816
+ }
817
+ else {
818
+ scene(name, wrappedFn);
819
+ }
851
820
  }
852
821
  //# sourceMappingURL=reactive.js.map