@jaypie/mcp 0.2.6 → 0.2.7

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/index.js CHANGED
@@ -885,7 +885,7 @@ function listLlmProviders() {
885
885
  };
886
886
  }
887
887
 
888
- const BUILD_VERSION_STRING = "@jaypie/mcp@0.2.6#e43f0153"
888
+ const BUILD_VERSION_STRING = "@jaypie/mcp@0.2.7#8fb79282"
889
889
  ;
890
890
  const __filename$1 = fileURLToPath(import.meta.url);
891
891
  const __dirname$1 = path.dirname(__filename$1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaypie/mcp",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "Jaypie MCP",
5
5
  "repository": {
6
6
  "type": "git",
@@ -153,12 +153,44 @@ Note: API Gateway has a 29-second timeout limit. For longer streaming operations
153
153
 
154
154
  ### Stack Types
155
155
 
156
- Use specialized stacks for different purposes:
156
+ Always extend Jaypie stack classes instead of raw CDK classes:
157
+
158
+ | Use | Instead of |
159
+ |-----|------------|
160
+ | `JaypieAppStack` | `cdk.Stack` |
161
+ | `JaypieInfrastructureStack` | `cdk.Stack` |
162
+
163
+ Jaypie stacks automatically configure:
164
+ - `env` with `CDK_DEFAULT_ACCOUNT` and `CDK_DEFAULT_REGION` (required for context providers)
165
+ - Standard tagging
166
+ - Removal policies based on environment
167
+
157
168
  ```typescript
158
169
  new JaypieAppStack(scope, "AppStack"); // Application resources
159
170
  new JaypieInfrastructureStack(scope, "InfraStack"); // Infrastructure resources
160
171
  ```
161
172
 
173
+ #### Error: Using cdk.Stack with Context Providers
174
+
175
+ Using `cdk.Stack` directly with constructs that need context providers causes:
176
+
177
+ ```
178
+ ValidationError: Cannot retrieve value from context provider hosted-zone since
179
+ account/region are not specified at the stack level.
180
+ ```
181
+
182
+ **Solution:** Change the base class:
183
+
184
+ ```typescript
185
+ // Wrong
186
+ import * as cdk from "aws-cdk-lib";
187
+ export class AppStack extends cdk.Stack { ... }
188
+
189
+ // Correct
190
+ import { JaypieAppStack } from "@jaypie/constructs";
191
+ export class AppStack extends JaypieAppStack { ... }
192
+ ```
193
+
162
194
  ### Secrets Management
163
195
 
164
196
  Use `JaypieEnvSecret` for cross-stack secret sharing:
@@ -314,7 +346,7 @@ const table = new JaypieDynamoDb(this, "MyTable", {
314
346
  // Connect table to Lambda
315
347
  new JaypieLambda(this, "Worker", {
316
348
  code: "dist",
317
- tables: [table], // Grants read/write, sets CDK_ENV_DYNAMO_TABLE
349
+ tables: [table], // Grants read/write, sets DYNAMODB_TABLE_NAME
318
350
  });
319
351
  ```
320
352
 
@@ -190,6 +190,25 @@ Pass secrets only to steps that need them:
190
190
 
191
191
  Never expose secrets in logs or workflow outputs.
192
192
 
193
+ ## CDK Stack Names
194
+
195
+ The `stack-name` parameter in deploy workflows must match the stack ID defined in `packages/cdk/bin/cdk.ts`:
196
+
197
+ ```typescript
198
+ // bin/cdk.ts
199
+ new AppStack(app, "AppStack"); // "AppStack" is the stack ID
200
+ ```
201
+
202
+ ```yaml
203
+ # deploy-*.yml
204
+ - name: Deploy CDK Stack
205
+ uses: ./.github/actions/cdk-deploy
206
+ with:
207
+ stack-name: AppStack # Must match the stack ID above
208
+ ```
209
+
210
+ If you rename the stack ID (e.g., to "MyProjectAppStack" for clarity in AWS), update all deploy workflows to match. Mismatched names cause "No stacks match the name(s)" errors.
211
+
193
212
  ## Integrations
194
213
 
195
214
  ### AWS
@@ -359,3 +359,259 @@ class TenantFabricator {
359
359
  4. **Seed Flexibility**: Accepts strings, numbers, or UUIDs as seeds
360
360
  5. **Hierarchical Generation**: Nested fabricators enable deterministic tree structures for complex data models
361
361
  6. **Identity & Naming**: Every fabricator has a unique ID and name for tracking and debugging
362
+
363
+ ## EventFabricator: Temporal Event Generation
364
+
365
+ ### Overview
366
+
367
+ `EventFabricator` is an abstract base class for generating temporally-distributed events across a year. It builds on `Fabricator` to add:
368
+ - Annual event counts with configurable distribution
369
+ - Temporal templates for hour, day, week, month, and date weighting
370
+ - Timezone-aware hour shifting
371
+ - Derived event system for cascading events
372
+
373
+ ### Basic Usage
374
+
375
+ ```typescript
376
+ import {
377
+ EventFabricator,
378
+ HOURS_BUSINESS,
379
+ DAYS_WEEKDAYS_ONLY,
380
+ type CreateEventParams,
381
+ } from "@jaypie/fabricator";
382
+
383
+ interface SimpleEvent {
384
+ id: string;
385
+ timestamp: Date;
386
+ }
387
+
388
+ class SimpleEventFabricator extends EventFabricator<SimpleEvent> {
389
+ protected createEvent({ seed, timestamp }: CreateEventParams): SimpleEvent {
390
+ return { id: seed, timestamp };
391
+ }
392
+ }
393
+
394
+ const fab = new SimpleEventFabricator({
395
+ seed: "my-events",
396
+ annualCount: 1000,
397
+ template: [HOURS_BUSINESS, DAYS_WEEKDAYS_ONLY],
398
+ });
399
+
400
+ const events = fab.events({ year: 2025 });
401
+ // Returns 1000 events during business hours on weekdays
402
+ ```
403
+
404
+ ### Temporal Templates
405
+
406
+ Templates control event distribution. They can be combined:
407
+
408
+ **Hour Templates:**
409
+ - `HOURS_BUSINESS` - 8am-5pm
410
+ - `HOURS_RETAIL` - 10am-8pm
411
+ - `HOURS_EVENING` - 6pm-10pm
412
+ - `HOURS_24_7` - All hours equal
413
+
414
+ **Day Templates:**
415
+ - `DAYS_WEEKDAYS_ONLY` - Mon-Fri only
416
+ - `DAYS_NO_SUNDAY` - All but Sunday
417
+ - `DAYS_NO_MONDAY` - All but Monday
418
+
419
+ **Curve Templates (gradual peaks):**
420
+ - `CURVE_EVENING_PEAK` - Peaks at 7pm
421
+ - `CURVE_ECOMMERCE` - Peaks at 8pm
422
+ - `CURVE_MIDDAY_PEAK` - Peaks at 11am
423
+
424
+ **Spike Templates (sharp peaks):**
425
+ - `SPIKE_MORNING` - 7-8am peak
426
+ - `SPIKE_LUNCH` - 12-1pm peak
427
+ - `SPIKE_EVENING` - 6-7pm peak
428
+
429
+ **Boost/Lull Templates (multipliers):**
430
+ - `BOOST_SUMMER`, `LULL_SUMMER`
431
+ - `BOOST_WINTER`, `LULL_WINTER`
432
+ - `BOOST_WEEKENDS`, `LULL_WEEKENDS`
433
+ - `BOOST_HOLIDAY_SEASON` - Nov-Dec 1.5x
434
+
435
+ ```typescript
436
+ const fab = new MyFabricator({
437
+ template: [
438
+ HOURS_BUSINESS,
439
+ DAYS_WEEKDAYS_ONLY,
440
+ BOOST_HOLIDAY_SEASON,
441
+ CURVE_MIDDAY_PEAK,
442
+ ],
443
+ });
444
+ ```
445
+
446
+ ## Derived Events: Cascading Event Generation
447
+
448
+ ### Overview
449
+
450
+ The derived event system allows events to spawn follow-up events based on probabilistic rules. This is ideal for modeling:
451
+ - Financial transactions with voids, refunds, chargebacks
452
+ - Subscription renewals with payment retries
453
+ - Any event chains with cause-and-effect relationships
454
+
455
+ ### Configuration
456
+
457
+ ```typescript
458
+ import {
459
+ EventFabricator,
460
+ CHANCE,
461
+ type DerivedConfig,
462
+ type TimestampedEvent,
463
+ } from "@jaypie/fabricator";
464
+
465
+ interface Transaction extends TimestampedEvent {
466
+ id: string;
467
+ amount: number;
468
+ type: "purchase" | "void" | "refund" | "chargeback";
469
+ parentId?: string;
470
+ timestamp: Date;
471
+ }
472
+
473
+ const derivedConfig: DerivedConfig<Transaction> = {
474
+ rules: [
475
+ {
476
+ name: "void",
477
+ probability: CHANCE.RARE, // 2.1%
478
+ condition: (parent) => parent.type === "purchase",
479
+ timing: { mode: "same-day" },
480
+ createDerived: ({ parent, seed, timestamp }) => ({
481
+ id: seed,
482
+ type: "void",
483
+ amount: -parent.amount,
484
+ timestamp,
485
+ parentId: parent.id,
486
+ }),
487
+ },
488
+ {
489
+ name: "refund",
490
+ probability: 0.10, // 10%
491
+ timing: {
492
+ mode: "range",
493
+ delayMin: 1,
494
+ delayMax: 14,
495
+ unit: "days",
496
+ },
497
+ createDerived: ({ parent, seed, timestamp }) => ({
498
+ id: seed,
499
+ type: "refund",
500
+ amount: -parent.amount,
501
+ timestamp,
502
+ parentId: parent.id,
503
+ }),
504
+ },
505
+ ],
506
+ boundaryBehavior: "include", // include | exclude | clamp
507
+ maxDepth: 4, // Prevent infinite chains
508
+ };
509
+ ```
510
+
511
+ ### Timing Modes
512
+
513
+ ```typescript
514
+ interface DerivedTiming {
515
+ mode: "same-day" | "fixed" | "range" | "recurring";
516
+ delayMin?: number;
517
+ delayMax?: number;
518
+ unit?: "days" | "weeks" | "months" | "hours" | "minutes" | "seconds";
519
+ interval?: number; // For recurring
520
+ maxRecurrences?: number; // For recurring
521
+ until?: Date | "end-of-year";
522
+ }
523
+ ```
524
+
525
+ **Examples:**
526
+ - Same day: `{ mode: "same-day" }`
527
+ - Fixed delay: `{ mode: "fixed", delayMin: 7, unit: "days" }`
528
+ - Range: `{ mode: "range", delayMin: 1, delayMax: 14, unit: "days" }`
529
+ - Monthly recurring: `{ mode: "recurring", interval: 1, unit: "months", until: "end-of-year" }`
530
+
531
+ ### Nested Derived Events (Chains)
532
+
533
+ Derived events can spawn their own derived events:
534
+
535
+ ```typescript
536
+ {
537
+ name: "chargeback",
538
+ probability: CHANCE.RARE,
539
+ timing: { mode: "range", delayMin: 30, delayMax: 90, unit: "days" },
540
+ createDerived: ({ parent, seed, timestamp }) => ({
541
+ id: seed,
542
+ type: "chargeback",
543
+ amount: -parent.amount,
544
+ timestamp,
545
+ parentId: parent.id,
546
+ }),
547
+ derived: [ // Nested rules for chargebacks
548
+ {
549
+ name: "representment",
550
+ probability: 0.70, // 70% of chargebacks
551
+ timing: { mode: "range", delayMin: 7, delayMax: 21, unit: "days" },
552
+ createDerived: ({ parent, seed, timestamp }) => ({
553
+ id: seed,
554
+ type: "representment",
555
+ amount: Math.abs(parent.amount), // Re-charge
556
+ timestamp,
557
+ parentId: parent.id,
558
+ }),
559
+ },
560
+ ],
561
+ }
562
+ ```
563
+
564
+ ### Using with EventFabricator
565
+
566
+ ```typescript
567
+ class TransactionFabricator extends EventFabricator<Transaction> {
568
+ constructor(options = {}) {
569
+ super({
570
+ ...options,
571
+ derived: derivedConfig,
572
+ template: [HOURS_BUSINESS, DAYS_WEEKDAYS_ONLY],
573
+ });
574
+ }
575
+
576
+ protected createEvent({ seed, timestamp }: CreateEventParams): Transaction {
577
+ const fab = new Fabricator({ seed });
578
+ return {
579
+ id: seed,
580
+ type: "purchase",
581
+ amount: fab.random({ min: 10, max: 500, currency: true }),
582
+ timestamp,
583
+ };
584
+ }
585
+ }
586
+
587
+ const fab = new TransactionFabricator({
588
+ seed: "my-business",
589
+ annualCount: 1000,
590
+ });
591
+
592
+ // Get all events including derived events
593
+ const events = fab.events({ year: 2025 });
594
+
595
+ // Get events with metadata (parent refs, depth, rule names)
596
+ const eventsWithMeta = fab.eventsWithMeta({ year: 2025 });
597
+ ```
598
+
599
+ ### Event Metadata
600
+
601
+ `eventsWithMeta()` returns events with relationship data:
602
+
603
+ ```typescript
604
+ interface EventWithDerivedMeta<T> {
605
+ event: T;
606
+ depth: number; // 0 = primary, 1 = first derived, etc.
607
+ parentSeed?: string; // Seed of parent event
608
+ ruleName?: string; // Rule that created this derived event
609
+ }
610
+ ```
611
+
612
+ ### Key Properties
613
+
614
+ 1. **Deterministic**: Same seed produces same derived event cascade
615
+ 2. **Chronological**: All events (primary + derived) sorted by timestamp
616
+ 3. **Depth-Limited**: `maxDepth` prevents infinite chains
617
+ 4. **Boundary Control**: Events outside target year can be included, excluded, or clamped
@@ -1115,6 +1115,22 @@ The environment must be created in GitHub repository settings before the workflo
1115
1115
  - Verify the AWS role has permissions to access any Secrets Manager secrets
1116
1116
  - Review CloudFormation events in the AWS Console for specific errors
1117
1117
 
1118
+ ### Error: "Cannot retrieve value from context provider hosted-zone"
1119
+
1120
+ Stacks using context providers must extend `JaypieAppStack`, not `cdk.Stack`:
1121
+
1122
+ ```typescript
1123
+ // Wrong
1124
+ import * as cdk from "aws-cdk-lib";
1125
+ export class AppStack extends cdk.Stack { ... }
1126
+
1127
+ // Correct
1128
+ import { JaypieAppStack } from "@jaypie/constructs";
1129
+ export class AppStack extends JaypieAppStack { ... }
1130
+ ```
1131
+
1132
+ `JaypieAppStack` automatically sets `env` with `CDK_DEFAULT_ACCOUNT` and `CDK_DEFAULT_REGION`.
1133
+
1118
1134
  ### Variables Not Being Applied
1119
1135
 
1120
1136
  - Composite actions cannot access `vars.*` directly
@@ -22,6 +22,8 @@ new InfrastructureStack(app, "InfrastructureStack");
22
22
  new AppStack(app, "AppStack");
23
23
  ```
24
24
 
25
+ > **Important:** The second argument to `new AppStack(app, "AppStack")` is the stack ID used by CloudFormation. This must exactly match the `stack-name` parameter in your GitHub Actions deploy workflows. If you customize this value (e.g., `"MyProjectAppStack"`), update `.github/workflows/deploy-*.yml` accordingly.
26
+
25
27
  ## lib/cdk-app.ts
26
28
 
27
29
  ```typescript