@directive-run/claude-plugin 1.16.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 (83) hide show
  1. package/.claude-plugin/plugin.json +6 -0
  2. package/LICENSE +26 -0
  3. package/README.md +113 -0
  4. package/dist/index.cjs +2 -0
  5. package/dist/index.cjs.map +1 -0
  6. package/dist/index.d.cts +66 -0
  7. package/dist/index.d.ts +66 -0
  8. package/dist/index.js +2 -0
  9. package/dist/index.js.map +1 -0
  10. package/package.json +64 -0
  11. package/skills/README.md +9 -0
  12. package/skills/building-ai-agents/SKILL.md +414 -0
  13. package/skills/building-ai-agents/ai-adapters.md +257 -0
  14. package/skills/building-ai-agents/ai-agents-streaming.md +307 -0
  15. package/skills/building-ai-agents/ai-communication.md +304 -0
  16. package/skills/building-ai-agents/api-skeleton.md +5 -0
  17. package/skills/building-ai-agents/examples.md +849 -0
  18. package/skills/building-ai-orchestrators/SKILL.md +401 -0
  19. package/skills/building-ai-orchestrators/ai-multi-agent.md +375 -0
  20. package/skills/building-ai-orchestrators/ai-orchestrator.md +466 -0
  21. package/skills/building-ai-orchestrators/ai-tasks.md +268 -0
  22. package/skills/building-ai-orchestrators/api-skeleton.md +5 -0
  23. package/skills/building-ai-orchestrators/examples.md +1609 -0
  24. package/skills/building-directive-systems/SKILL.md +499 -0
  25. package/skills/building-directive-systems/api-skeleton.md +5 -0
  26. package/skills/building-directive-systems/examples.md +4149 -0
  27. package/skills/building-directive-systems/multi-module.md +327 -0
  28. package/skills/building-directive-systems/plugins.md +361 -0
  29. package/skills/building-directive-systems/react-adapter.md +376 -0
  30. package/skills/building-directive-systems/system-api.md +463 -0
  31. package/skills/getting-started-with-directive/SKILL.md +198 -0
  32. package/skills/getting-started-with-directive/api-skeleton.md +5 -0
  33. package/skills/getting-started-with-directive/core-patterns.md +240 -0
  34. package/skills/getting-started-with-directive/examples.md +87 -0
  35. package/skills/getting-started-with-directive/sitemap.md +202 -0
  36. package/skills/hardening-ai-systems/SKILL.md +377 -0
  37. package/skills/hardening-ai-systems/ai-budget-resilience.md +408 -0
  38. package/skills/hardening-ai-systems/ai-guardrails-memory.md +370 -0
  39. package/skills/hardening-ai-systems/ai-security.md +400 -0
  40. package/skills/hardening-ai-systems/api-skeleton.md +5 -0
  41. package/skills/hardening-ai-systems/examples.md +628 -0
  42. package/skills/migrating-to-directive/SKILL.md +249 -0
  43. package/skills/migrating-to-directive/anti-patterns.md +382 -0
  44. package/skills/migrating-to-directive/api-skeleton.md +5 -0
  45. package/skills/migrating-to-directive/core-patterns.md +240 -0
  46. package/skills/migrating-to-directive/examples.md +511 -0
  47. package/skills/migrating-to-directive/schema-types.md +273 -0
  48. package/skills/reviewing-directive-code/SKILL.md +232 -0
  49. package/skills/reviewing-directive-code/anti-patterns.md +382 -0
  50. package/skills/reviewing-directive-code/api-skeleton.md +5 -0
  51. package/skills/reviewing-directive-code/core-patterns.md +240 -0
  52. package/skills/reviewing-directive-code/examples.md +463 -0
  53. package/skills/reviewing-directive-code/naming.md +321 -0
  54. package/skills/scaffolding-directive-modules/SKILL.md +218 -0
  55. package/skills/scaffolding-directive-modules/api-skeleton.md +5 -0
  56. package/skills/scaffolding-directive-modules/core-patterns.md +240 -0
  57. package/skills/scaffolding-directive-modules/examples.md +1386 -0
  58. package/skills/scaffolding-directive-modules/naming.md +321 -0
  59. package/skills/scaffolding-directive-modules/schema-types.md +273 -0
  60. package/skills/testing-ai-systems/SKILL.md +398 -0
  61. package/skills/testing-ai-systems/ai-debug-observability.md +329 -0
  62. package/skills/testing-ai-systems/ai-mcp-rag.md +293 -0
  63. package/skills/testing-ai-systems/ai-testing-evals.md +485 -0
  64. package/skills/testing-ai-systems/api-skeleton.md +5 -0
  65. package/skills/testing-ai-systems/examples.md +1261 -0
  66. package/skills/testing-directive-code/SKILL.md +479 -0
  67. package/skills/testing-directive-code/api-skeleton.md +5 -0
  68. package/skills/testing-directive-code/examples.md +156 -0
  69. package/skills/testing-directive-code/history.md +351 -0
  70. package/skills/testing-directive-code/testing.md +412 -0
  71. package/skills/writing-directive-constraints/SKILL.md +486 -0
  72. package/skills/writing-directive-constraints/api-skeleton.md +5 -0
  73. package/skills/writing-directive-constraints/constraints.md +274 -0
  74. package/skills/writing-directive-constraints/error-boundaries.md +330 -0
  75. package/skills/writing-directive-constraints/examples.md +1361 -0
  76. package/skills/writing-directive-constraints/resolvers.md +367 -0
  77. package/skills/writing-directive-modules/SKILL.md +342 -0
  78. package/skills/writing-directive-modules/anti-patterns.md +382 -0
  79. package/skills/writing-directive-modules/api-skeleton.md +5 -0
  80. package/skills/writing-directive-modules/core-patterns.md +240 -0
  81. package/skills/writing-directive-modules/examples.md +1639 -0
  82. package/skills/writing-directive-modules/naming.md +321 -0
  83. package/skills/writing-directive-modules/schema-types.md +273 -0
@@ -0,0 +1,511 @@
1
+ # Examples
2
+
3
+ > Auto-generated from extracted examples. Do not edit manually.
4
+
5
+ ## counter
6
+
7
+ ```typescript
8
+ // Example: counter
9
+ // Source: examples/counter/src/module.ts
10
+ // Pure module file — no DOM wiring
11
+
12
+ /**
13
+ * Counter — The simplest Directive module.
14
+ *
15
+ * Demonstrates: facts, events, derivations, one constraint, one resolver.
16
+ * Total: ~40 lines.
17
+ */
18
+
19
+ import {
20
+ type ModuleSchema,
21
+ createModule,
22
+ createSystem,
23
+ t,
24
+ } from "@directive-run/core";
25
+
26
+ const schema = {
27
+ facts: {
28
+ count: t.number(),
29
+ },
30
+ derivations: {
31
+ doubled: t.number(),
32
+ isPositive: t.boolean(),
33
+ },
34
+ events: {
35
+ increment: {},
36
+ decrement: {},
37
+ reset: {},
38
+ },
39
+ requirements: {
40
+ CLAMP_TO_ZERO: {},
41
+ },
42
+ } satisfies ModuleSchema;
43
+
44
+ export const counterModule = createModule("counter", {
45
+ schema,
46
+
47
+ init: (facts) => {
48
+ facts.count = 0;
49
+ },
50
+
51
+ derive: {
52
+ doubled: (facts) => facts.count * 2,
53
+ isPositive: (facts) => facts.count > 0,
54
+ },
55
+
56
+ events: {
57
+ increment: (facts) => {
58
+ facts.count += 1;
59
+ },
60
+ decrement: (facts) => {
61
+ facts.count -= 1;
62
+ },
63
+ reset: (facts) => {
64
+ facts.count = 0;
65
+ },
66
+ },
67
+
68
+ // When count goes negative, automatically fix it
69
+ constraints: {
70
+ noNegative: {
71
+ when: (facts) => facts.count < 0,
72
+ require: { type: "CLAMP_TO_ZERO" },
73
+ },
74
+ },
75
+
76
+ resolvers: {
77
+ clamp: {
78
+ requirement: "CLAMP_TO_ZERO",
79
+ resolve: async (_req, context) => {
80
+ context.facts.count = 0;
81
+ },
82
+ },
83
+ },
84
+ });
85
+
86
+ export const system = createSystem({ module: counterModule });
87
+ ```
88
+
89
+ ## shopping-cart
90
+
91
+ ```typescript
92
+ // Example: shopping-cart
93
+ // Source: examples/shopping-cart/src/shopping-cart.ts
94
+ // Pure module file — no DOM wiring
95
+
96
+ /**
97
+ * Shopping Cart — Directive Modules
98
+ *
99
+ * Two modules:
100
+ * - cart: Items, coupons, checkout with cross-module auth dependency
101
+ * - auth: Simple authentication toggle for demo purposes
102
+ *
103
+ * Demonstrates cross-module constraints (`crossModuleDeps`),
104
+ * constraint ordering (`after`), priority-based resolution,
105
+ * and retry with exponential backoff.
106
+ */
107
+
108
+ import {
109
+ type ModuleSchema,
110
+ createModule,
111
+ createSystem,
112
+ t,
113
+ } from "@directive-run/core";
114
+ import { devtoolsPlugin } from "@directive-run/core/plugins";
115
+ import { processCheckout, validateCoupon } from "./mock-api.js";
116
+
117
+ // ============================================================================
118
+ // Types
119
+ // ============================================================================
120
+
121
+ export interface CartItem {
122
+ id: string;
123
+ name: string;
124
+ price: number;
125
+ quantity: number;
126
+ maxStock: number;
127
+ image: string;
128
+ }
129
+
130
+ // ============================================================================
131
+ // Auth Module
132
+ // ============================================================================
133
+
134
+ export const authSchema = {
135
+ facts: {
136
+ isAuthenticated: t.boolean(),
137
+ userName: t.string(),
138
+ },
139
+ derivations: {
140
+ isAuthenticated: t.boolean(),
141
+ },
142
+ events: {
143
+ toggleAuth: {},
144
+ },
145
+ requirements: {},
146
+ } satisfies ModuleSchema;
147
+
148
+ export const authModule = createModule("auth", {
149
+ schema: authSchema,
150
+
151
+ init: (facts) => {
152
+ facts.isAuthenticated = true;
153
+ facts.userName = "Demo User";
154
+ },
155
+
156
+ derive: {
157
+ isAuthenticated: (facts) => facts.isAuthenticated,
158
+ },
159
+
160
+ events: {
161
+ toggleAuth: (facts) => {
162
+ facts.isAuthenticated = !facts.isAuthenticated;
163
+ if (!facts.isAuthenticated) {
164
+ facts.userName = "";
165
+ } else {
166
+ facts.userName = "Demo User";
167
+ }
168
+ },
169
+ },
170
+ });
171
+
172
+ // ============================================================================
173
+ // Cart Module
174
+ // ============================================================================
175
+
176
+ export const cartSchema = {
177
+ facts: {
178
+ items: t.array<CartItem>(),
179
+ couponCode: t.string(),
180
+ couponDiscount: t.number(),
181
+ couponStatus: t.string<"idle" | "checking" | "valid" | "invalid">(),
182
+ checkoutRequested: t.boolean(),
183
+ checkoutStatus: t.string<"idle" | "processing" | "complete" | "failed">(),
184
+ checkoutError: t.string(),
185
+ },
186
+ derivations: {
187
+ subtotal: t.number(),
188
+ itemCount: t.number(),
189
+ isEmpty: t.boolean(),
190
+ discount: t.number(),
191
+ tax: t.number(),
192
+ total: t.number(),
193
+ hasOverstockedItem: t.boolean(),
194
+ freeShipping: t.boolean(),
195
+ },
196
+ events: {
197
+ addItem: {
198
+ id: t.string(),
199
+ name: t.string(),
200
+ price: t.number(),
201
+ maxStock: t.number(),
202
+ image: t.string(),
203
+ },
204
+ removeItem: { id: t.string() },
205
+ updateQuantity: { id: t.string(), quantity: t.number() },
206
+ applyCoupon: { code: t.string() },
207
+ clearCoupon: {},
208
+ requestCheckout: {},
209
+ resetCheckout: {},
210
+ },
211
+ requirements: {
212
+ ADJUST_QUANTITY: {},
213
+ VALIDATE_COUPON: { code: t.string() },
214
+ PROCESS_CHECKOUT: {},
215
+ },
216
+ } satisfies ModuleSchema;
217
+
218
+ export const cartModule = createModule("cart", {
219
+ schema: cartSchema,
220
+
221
+ crossModuleDeps: { auth: authSchema },
222
+
223
+ init: (facts) => {
224
+ facts.items = [
225
+ {
226
+ id: "headphones-1",
227
+ name: "Wireless Headphones",
228
+ price: 79.99,
229
+ quantity: 1,
230
+ maxStock: 5,
231
+ image: "headphones",
232
+ },
233
+ {
234
+ id: "keyboard-1",
235
+ name: "Mechanical Keyboard",
236
+ price: 129.99,
237
+ quantity: 1,
238
+ maxStock: 3,
239
+ image: "keyboard",
240
+ },
241
+ {
242
+ id: "hub-1",
243
+ name: "USB-C Hub",
244
+ price: 49.99,
245
+ quantity: 2,
246
+ maxStock: 10,
247
+ image: "hub",
248
+ },
249
+ ];
250
+ facts.couponCode = "";
251
+ facts.couponDiscount = 0;
252
+ facts.couponStatus = "idle";
253
+ facts.checkoutRequested = false;
254
+ facts.checkoutStatus = "idle";
255
+ facts.checkoutError = "";
256
+ },
257
+
258
+ // ============================================================================
259
+ // Derivations
260
+ // ============================================================================
261
+
262
+ derive: {
263
+ subtotal: (facts) => {
264
+ return facts.self.items.reduce(
265
+ (sum: number, item: CartItem) => sum + item.price * item.quantity,
266
+ 0,
267
+ );
268
+ },
269
+
270
+ itemCount: (facts) => {
271
+ return facts.self.items.reduce(
272
+ (sum: number, item: CartItem) => sum + item.quantity,
273
+ 0,
274
+ );
275
+ },
276
+
277
+ isEmpty: (facts) => {
278
+ return facts.self.items.length === 0;
279
+ },
280
+
281
+ discount: (facts, derived) => {
282
+ const sub = derived.subtotal;
283
+
284
+ return sub * (facts.self.couponDiscount / 100);
285
+ },
286
+
287
+ tax: (_facts, derived) => {
288
+ const sub = derived.subtotal;
289
+ const disc = derived.discount;
290
+
291
+ return (sub - disc) * 0.08;
292
+ },
293
+
294
+ total: (_facts, derived) => {
295
+ const sub = derived.subtotal;
296
+ const disc = derived.discount;
297
+ const tx = derived.tax;
298
+
299
+ return sub - disc + tx;
300
+ },
301
+
302
+ hasOverstockedItem: (facts) => {
303
+ return facts.self.items.some(
304
+ (item: CartItem) => item.quantity > item.maxStock,
305
+ );
306
+ },
307
+
308
+ freeShipping: (_facts, derived) => {
309
+ const sub = derived.subtotal;
310
+
311
+ return sub >= 75;
312
+ },
313
+ },
314
+
315
+ // ============================================================================
316
+ // Events
317
+ // ============================================================================
318
+
319
+ events: {
320
+ addItem: (facts, { id, name, price, maxStock, image }) => {
321
+ const existing = facts.items.find((item: CartItem) => item.id === id);
322
+ if (existing) {
323
+ facts.items = facts.items.map((item: CartItem) =>
324
+ item.id === id
325
+ ? { ...item, quantity: Math.min(item.quantity + 1, item.maxStock) }
326
+ : item,
327
+ );
328
+ } else {
329
+ facts.items = [
330
+ ...facts.items,
331
+ { id, name, price, quantity: 1, maxStock, image },
332
+ ];
333
+ }
334
+ },
335
+
336
+ removeItem: (facts, { id }) => {
337
+ facts.items = facts.items.filter((item: CartItem) => item.id !== id);
338
+ },
339
+
340
+ updateQuantity: (facts, { id, quantity }) => {
341
+ if (quantity <= 0) {
342
+ facts.items = facts.items.filter((item: CartItem) => item.id !== id);
343
+
344
+ return;
345
+ }
346
+
347
+ facts.items = facts.items.map((item: CartItem) =>
348
+ item.id === id ? { ...item, quantity } : item,
349
+ );
350
+ },
351
+
352
+ applyCoupon: (facts, { code }) => {
353
+ facts.couponCode = code;
354
+ facts.couponStatus = "idle";
355
+ facts.couponDiscount = 0;
356
+ },
357
+
358
+ clearCoupon: (facts) => {
359
+ facts.couponCode = "";
360
+ facts.couponDiscount = 0;
361
+ facts.couponStatus = "idle";
362
+ },
363
+
364
+ requestCheckout: (facts) => {
365
+ facts.checkoutRequested = true;
366
+ facts.checkoutStatus = "idle";
367
+ facts.checkoutError = "";
368
+ },
369
+
370
+ resetCheckout: (facts) => {
371
+ facts.checkoutRequested = false;
372
+ facts.checkoutStatus = "idle";
373
+ facts.checkoutError = "";
374
+ },
375
+ },
376
+
377
+ // ============================================================================
378
+ // Constraints
379
+ // ============================================================================
380
+
381
+ constraints: {
382
+ quantityLimit: {
383
+ priority: 80,
384
+ when: (facts) => {
385
+ const hasOverstocked = facts.self.items.some(
386
+ (item: CartItem) => item.quantity > item.maxStock,
387
+ );
388
+
389
+ return hasOverstocked;
390
+ },
391
+ require: { type: "ADJUST_QUANTITY" },
392
+ },
393
+
394
+ couponValidation: {
395
+ priority: 70,
396
+ when: (facts) => {
397
+ return (
398
+ facts.self.couponCode !== "" && facts.self.couponStatus === "idle"
399
+ );
400
+ },
401
+ require: (facts) => ({
402
+ type: "VALIDATE_COUPON",
403
+ code: facts.self.couponCode,
404
+ }),
405
+ },
406
+
407
+ checkoutReady: {
408
+ priority: 60,
409
+ after: ["quantityLimit", "couponValidation"],
410
+ when: (facts) => {
411
+ const items = facts.self.items;
412
+ const notEmpty = items.length > 0;
413
+ const noOverstock = !items.some(
414
+ (item: CartItem) => item.quantity > item.maxStock,
415
+ );
416
+
417
+ return (
418
+ facts.self.checkoutRequested === true &&
419
+ notEmpty &&
420
+ noOverstock &&
421
+ facts.auth.isAuthenticated === true
422
+ );
423
+ },
424
+ require: { type: "PROCESS_CHECKOUT" },
425
+ },
426
+ },
427
+
428
+ // ============================================================================
429
+ // Resolvers
430
+ // ============================================================================
431
+
432
+ resolvers: {
433
+ adjustQuantity: {
434
+ requirement: "ADJUST_QUANTITY",
435
+ resolve: async (_req, context) => {
436
+ context.facts.items = context.facts.items.map((item: CartItem) => {
437
+ if (item.quantity > item.maxStock) {
438
+ return { ...item, quantity: item.maxStock };
439
+ }
440
+
441
+ return item;
442
+ });
443
+ },
444
+ },
445
+
446
+ validateCoupon: {
447
+ requirement: "VALIDATE_COUPON",
448
+ key: (req) => `coupon-${req.code}`,
449
+ resolve: async (req, context) => {
450
+ context.facts.couponStatus = "checking";
451
+
452
+ const result = await validateCoupon(req.code);
453
+
454
+ if (result.valid) {
455
+ context.facts.couponDiscount = result.discount;
456
+ context.facts.couponStatus = "valid";
457
+ } else {
458
+ context.facts.couponDiscount = 0;
459
+ context.facts.couponStatus = "invalid";
460
+ }
461
+ },
462
+ },
463
+
464
+ processCheckout: {
465
+ requirement: "PROCESS_CHECKOUT",
466
+ retry: { attempts: 2, backoff: "exponential" },
467
+ resolve: async (_req, context) => {
468
+ context.facts.checkoutStatus = "processing";
469
+
470
+ try {
471
+ const items = context.facts.items.map((item: CartItem) => ({
472
+ id: item.id,
473
+ name: item.name,
474
+ quantity: item.quantity,
475
+ price: item.price,
476
+ }));
477
+
478
+ await processCheckout(items, context.facts.couponCode);
479
+
480
+ context.facts.checkoutStatus = "complete";
481
+ context.facts.items = [];
482
+ context.facts.couponCode = "";
483
+ context.facts.couponDiscount = 0;
484
+ context.facts.couponStatus = "idle";
485
+ context.facts.checkoutRequested = false;
486
+ } catch (err) {
487
+ const msg = err instanceof Error ? err.message : "Checkout failed";
488
+ context.facts.checkoutStatus = "failed";
489
+ context.facts.checkoutError = msg;
490
+ context.facts.checkoutRequested = false;
491
+ throw err;
492
+ }
493
+ },
494
+ },
495
+ },
496
+ });
497
+
498
+ // ============================================================================
499
+ // System
500
+ // ============================================================================
501
+
502
+ export const system = createSystem({
503
+ modules: {
504
+ cart: cartModule,
505
+ auth: authModule,
506
+ },
507
+ plugins: [devtoolsPlugin({ name: "shopping-cart", panel: true })],
508
+ history: { maxSnapshots: 50 },
509
+ trace: true,
510
+ });
511
+ ```