@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,273 @@
1
+ # Schema Types
2
+
3
+ > Covers `@directive-run/core` — schema builders (`t.string` / `t.number` / `t.array` / etc.) and inference helpers.
4
+
5
+ The `t.*()` builders define fact types in module schemas. They provide runtime validation in dev mode and full TypeScript inference.
6
+
7
+ ## Decision Tree: "Which type builder do I use?"
8
+
9
+ ```
10
+ What kind of value?
11
+ ├── String → t.string() or t.string<"a" | "b">() for literal unions
12
+ ├── Number → t.number() with optional .min() / .max()
13
+ ├── Boolean → t.boolean()
14
+ ├── Array → t.array<ItemType>() with optional .of() / .nonEmpty()
15
+ ├── Object/Record → t.object<Shape>()
16
+ ├── Fixed set of string values → t.enum("a", "b", "c")
17
+ ├── Exact value → t.literal(42) or t.literal("active")
18
+ ├── Nullable → t.nullable(t.string())
19
+ ├── Optional → t.optional(t.number())
20
+ ├── Union → t.union(t.string(), t.number())
21
+ ├── Map/Set → t.object<Map<K,V>>() or t.object<Set<T>>()
22
+ ├── Date → t.object<Date>() or t.number() for timestamps
23
+ ├── Unknown/any → t.object<unknown>()
24
+ └── Any type + metadata → t.string().meta({ label: "Email", tags: ["pii"] })
25
+ ```
26
+
27
+ All builders support `.meta({ label, description, category, color, tags })` for devtools/AI annotations. Chains with other methods: `t.string().meta({...}).nullable()`.
28
+
29
+ ## Primitive Types
30
+
31
+ ```typescript
32
+ import { createModule, t } from "@directive-run/core";
33
+
34
+ const myModule = createModule("example", {
35
+ schema: {
36
+ facts: {
37
+ // Basic string
38
+ name: t.string(),
39
+
40
+ // String literal union – full type safety
41
+ phase: t.string<"idle" | "loading" | "done">(),
42
+
43
+ // Number with validation
44
+ count: t.number(),
45
+ age: t.number().min(0).max(150),
46
+
47
+ // Boolean
48
+ isActive: t.boolean(),
49
+ },
50
+ },
51
+ init: (facts) => {
52
+ facts.name = "";
53
+ facts.phase = "idle";
54
+ facts.count = 0;
55
+ facts.age = 25;
56
+ facts.isActive = false;
57
+ },
58
+ });
59
+ ```
60
+
61
+ ## Complex Types
62
+
63
+ ```typescript
64
+ schema: {
65
+ facts: {
66
+ // Object with shape
67
+ user: t.object<{ id: string; name: string; email: string }>(),
68
+
69
+ // Nullable object
70
+ profile: t.object<{ bio: string; avatar: string } | null>(),
71
+
72
+ // Array
73
+ tags: t.array<string>(),
74
+ items: t.array<{ id: string; label: string }>().nonEmpty(),
75
+
76
+ // Record (key-value map)
77
+ scores: t.object<Record<string, number>>(),
78
+
79
+ // Nested complex type
80
+ config: t.object<{
81
+ theme: "light" | "dark";
82
+ notifications: { email: boolean; push: boolean };
83
+ }>(),
84
+ },
85
+ },
86
+ ```
87
+
88
+ ## Enum and Literal
89
+
90
+ ```typescript
91
+ schema: {
92
+ facts: {
93
+ // Enum – string literal union from values
94
+ status: t.enum("pending", "active", "archived"),
95
+ // TypeScript type: "pending" | "active" | "archived"
96
+
97
+ // Literal – exact match
98
+ version: t.literal(2),
99
+ mode: t.literal("strict"),
100
+ enabled: t.literal(true),
101
+ },
102
+ },
103
+ ```
104
+
105
+ ## Nullable and Optional
106
+
107
+ ```typescript
108
+ schema: {
109
+ facts: {
110
+ // Nullable – T | null
111
+ selectedItem: t.nullable(t.string()),
112
+
113
+ // Optional – T | undefined
114
+ nickname: t.optional(t.string()),
115
+
116
+ // Union – combine types
117
+ result: t.union(t.string(), t.number()),
118
+
119
+ // Nullable via object generic (also valid)
120
+ user: t.object<{ id: string } | null>(),
121
+ },
122
+ },
123
+ ```
124
+
125
+ ## Chainable Methods (Available on All Types)
126
+
127
+ ```typescript
128
+ schema: {
129
+ facts: {
130
+ // Default value – used if init doesn't set it
131
+ theme: t.string<"light" | "dark">().default("light"),
132
+
133
+ // Custom validation – runs in dev mode
134
+ email: t.string().validate((val) => val.includes("@")),
135
+
136
+ // Transform on set – runs when fact is mutated
137
+ slug: t.string().transform((val) => val.toLowerCase().replace(/\s+/g, "-")),
138
+
139
+ // Branded type – nominal typing
140
+ userId: t.string().brand<"UserId">(),
141
+
142
+ // Description – for docs and devtools
143
+ retryCount: t.number().describe("Number of failed attempts"),
144
+
145
+ // Refinement – predicate with error message
146
+ port: t.number().refine(
147
+ (n) => n >= 1 && n <= 65535,
148
+ "Port must be between 1 and 65535",
149
+ ),
150
+
151
+ // Chaining – combine multiple modifiers
152
+ score: t.number()
153
+ .min(0)
154
+ .max(100)
155
+ .default(0)
156
+ .describe("Player score"),
157
+ },
158
+ },
159
+ ```
160
+
161
+ ## Array-Specific Methods
162
+
163
+ ```typescript
164
+ schema: {
165
+ facts: {
166
+ // Basic array
167
+ items: t.array<string>(),
168
+
169
+ // Non-empty validation
170
+ requiredItems: t.array<string>().nonEmpty(),
171
+
172
+ // Length constraints
173
+ topFive: t.array<string>().maxLength(5),
174
+ atLeastThree: t.array<number>().minLength(3),
175
+
176
+ // Combined
177
+ tags: t.array<string>().nonEmpty().maxLength(10),
178
+ },
179
+ },
180
+ ```
181
+
182
+ ## Object-Specific Methods
183
+
184
+ ```typescript
185
+ schema: {
186
+ facts: {
187
+ // Non-null assertion
188
+ config: t.object<{ url: string }>().nonNull(),
189
+
190
+ // Required keys validation
191
+ settings: t.object<Record<string, unknown>>().hasKeys("apiUrl", "timeout"),
192
+ },
193
+ },
194
+ ```
195
+
196
+ ## Types That DO NOT Exist
197
+
198
+ These are common AI hallucinations. Do not use them.
199
+
200
+ ```typescript
201
+ // WRONG – t.map() does not exist
202
+ items: t.map<string, number>(),
203
+ // CORRECT
204
+ items: t.object<Map<string, number>>(),
205
+
206
+ // WRONG – t.set() does not exist
207
+ tags: t.set<string>(),
208
+ // CORRECT
209
+ tags: t.object<Set<string>>(),
210
+
211
+ // WRONG – t.date() does not exist
212
+ createdAt: t.date(),
213
+ // CORRECT
214
+ createdAt: t.object<Date>(),
215
+ // OR use timestamps
216
+ createdAt: t.number(), // Unix ms
217
+
218
+ // WRONG – t.tuple() does not exist
219
+ coords: t.tuple<[number, number]>(),
220
+ // CORRECT
221
+ coords: t.array<[number, number]>(),
222
+
223
+ // WRONG – t.record() does not exist
224
+ scores: t.record<string, number>(),
225
+ // CORRECT
226
+ scores: t.object<Record<string, number>>(),
227
+
228
+ // WRONG – t.promise() does not exist (facts are synchronous)
229
+ result: t.promise<string>(),
230
+
231
+ // WRONG – t.any() does not exist
232
+ data: t.any(),
233
+ // CORRECT
234
+ data: t.object<unknown>(),
235
+
236
+ // WRONG – t.void() does not exist (not a fact type)
237
+ // WRONG – t.function() does not exist (functions are not serializable)
238
+ ```
239
+
240
+ ## Type Assertion Alternative
241
+
242
+ For simple modules, you can skip `t.*()` and use TypeScript type assertions:
243
+
244
+ ```typescript
245
+ const myModule = createModule("simple", {
246
+ schema: {
247
+ facts: {} as {
248
+ count: number;
249
+ name: string;
250
+ items: string[];
251
+ },
252
+ derivations: {} as {
253
+ doubled: number;
254
+ },
255
+ },
256
+ init: (facts) => {
257
+ facts.count = 0;
258
+ facts.name = "";
259
+ facts.items = [];
260
+ },
261
+ derive: {
262
+ doubled: (facts) => facts.count * 2,
263
+ },
264
+ });
265
+ ```
266
+
267
+ This gives full TypeScript inference but skips runtime validation. Use `t.*()` when you want dev-mode validation, transforms, or self-documenting schemas.
268
+
269
+ ## See also
270
+
271
+ - [`core-patterns.md`](./core-patterns.md) — where the schemas these builders define get attached (modules)
272
+ - [`system-api.md`](./system-api.md) — schema flows through `createSystem` and shows up on `system.facts.*`
273
+ - [`anti-patterns.md`](./anti-patterns.md) — hallucinated schema types (`t.map`, `t.set`, `t.date`, `t.promise`, `t.tuple`, `t.record`, `t.any`) that don't exist
@@ -0,0 +1,232 @@
1
+ ---
2
+ name: reviewing-directive-code
3
+ description: "Review Directive code for anti-patterns, naming violations, missing error boundaries, constraint/resolver misuse, and performance issues. Use when asked to review, audit, or improve existing Directive modules, systems, or orchestrators."
4
+ ---
5
+
6
+ # Reviewing Directive Code
7
+
8
+ ## Prerequisites
9
+
10
+ This skill applies when the project uses `@directive-run/core`. If not found in `package.json`, suggest installing it: `npm install @directive-run/core`.
11
+
12
+ ## When Claude Should Use This Skill
13
+
14
+ ### Auto-Invoke Triggers
15
+ - User asks to "review my Directive code" or "audit this module"
16
+ - User asks "is this the right pattern" or "am I doing this correctly"
17
+ - User wants a code review of constraint/resolver/module code
18
+ - User asks about Directive best practices for existing code
19
+ - User suspects they have anti-patterns or performance issues
20
+
21
+ ### Exclusions – Use a Different Skill
22
+ - User wants to write NEW code from scratch → `writing-directive-modules`
23
+ - User wants to write tests → `testing-directive-code`
24
+ - User wants to migrate FROM another library → `migrating-to-directive`
25
+
26
+ ---
27
+
28
+ ## Review Checklist
29
+
30
+ ## 1. Module Structure
31
+
32
+ ```
33
+ ✓ Module name is kebab-case
34
+ ✓ Schema keys are camelCase
35
+ ✓ All facts have explicit type builders (t.string(), t.number(), etc.)
36
+ ✓ init() sets ALL schema keys (no undefined facts)
37
+ ✓ No business logic in init() – just defaults
38
+ ```
39
+
40
+ ### Anti-Patterns
41
+
42
+ ```typescript
43
+ // BAD: Missing type builder
44
+ schema: { count: 0 }
45
+ // GOOD: Explicit type builder
46
+ schema: { count: t.number() }
47
+
48
+ // BAD: Business logic in init
49
+ init: (facts) => {
50
+ facts.count = localStorage.getItem("count") ?? 0;
51
+ }
52
+ // GOOD: Use a resolver for async/side-effect init
53
+ init: (facts) => {
54
+ facts.count = 0;
55
+ }
56
+ ```
57
+
58
+ ## 2. Derivations
59
+
60
+ ```
61
+ ✓ Derivations are pure functions (no side effects)
62
+ ✓ No mutations inside derive functions
63
+ ✓ Using derive-to-derive composition correctly (via second arg)
64
+ ✓ Not duplicating fact values (derive should compute, not mirror)
65
+ ```
66
+
67
+ ### Anti-Patterns
68
+
69
+ ```typescript
70
+ // BAD: Side effect in derivation
71
+ derive: {
72
+ status: (facts) => {
73
+ console.log("computing status"); // side effect!
74
+ return facts.isReady ? "ready" : "loading";
75
+ }
76
+ }
77
+
78
+ // BAD: Mirroring a fact (useless derivation)
79
+ derive: {
80
+ currentCount: (facts) => facts.count // just use facts.count
81
+ }
82
+
83
+ // GOOD: Meaningful computation
84
+ derive: {
85
+ isOverBudget: (facts) => facts.spent > facts.budget,
86
+ budgetStatus: (facts, derived) => derived.isOverBudget ? "over" : "under",
87
+ }
88
+ ```
89
+
90
+ ## 3. Constraints
91
+
92
+ ```
93
+ ✓ when() is a pure predicate (no side effects)
94
+ ✓ require returns a typed requirement with UPPER_SNAKE_CASE type
95
+ ✓ Async constraints have explicit deps: []
96
+ ✓ Priority is set when multiple constraints may conflict
97
+ ✓ No redundant constraints (check if constraint already exists)
98
+ ```
99
+
100
+ ### Anti-Patterns
101
+
102
+ ```typescript
103
+ // BAD: Side effect in when()
104
+ when: (facts) => {
105
+ analytics.track("constraint-checked"); // side effect!
106
+ return facts.count > 10;
107
+ }
108
+
109
+ // BAD: Requirement type not UPPER_SNAKE_CASE
110
+ require: { type: "fetchData" }
111
+ // GOOD:
112
+ require: { type: "FETCH_DATA" }
113
+
114
+ // BAD: Async constraint without deps
115
+ constraints: {
116
+ check: {
117
+ async: true,
118
+ when: async (facts) => await validate(facts.input),
119
+ require: { type: "HANDLE_INVALID" },
120
+ // Missing: deps: ["input"]
121
+ }
122
+ }
123
+ ```
124
+
125
+ ## 4. Resolvers
126
+
127
+ ```
128
+ ✓ Resolver params use (req, context) – not (req, ctx)
129
+ ✓ Resolver handles errors (try/catch or error boundaries)
130
+ ✓ Deduplication key set for idempotent requirements
131
+ ✓ Retry policy configured for network/external calls
132
+ ✓ Not doing work that belongs in a constraint or effect
133
+ ```
134
+
135
+ ### Anti-Patterns
136
+
137
+ ```typescript
138
+ // BAD: Abbreviated context parameter
139
+ resolve: async (req, ctx) => { ... }
140
+ // GOOD:
141
+ resolve: async (req, context) => { ... }
142
+
143
+ // BAD: No error handling for external calls
144
+ resolve: async (req, context) => {
145
+ const data = await fetch("/api/data");
146
+ context.facts.data = await data.json();
147
+ }
148
+ // GOOD: With retry
149
+ resolvers: {
150
+ fetchData: {
151
+ requirement: "FETCH_DATA",
152
+ retry: { attempts: 3, backoff: "exponential" },
153
+ resolve: async (req, context) => {
154
+ const data = await fetch("/api/data");
155
+ context.facts.data = await data.json();
156
+ },
157
+ }
158
+ }
159
+
160
+ // BAD: Resolver checking conditions (that's a constraint's job)
161
+ resolve: async (req, context) => {
162
+ if (context.facts.isReady) {
163
+ // do something
164
+ }
165
+ }
166
+ ```
167
+
168
+ ## 5. Effects
169
+
170
+ ```
171
+ ✓ Effects are fire-and-forget (not resolving requirements)
172
+ ✓ Effects have cleanup functions for subscriptions
173
+ ✓ Not mutating critical state in effects (use resolvers instead)
174
+ ✓ Prev parameter used for change detection
175
+ ```
176
+
177
+ ## 6. System Composition
178
+
179
+ ```
180
+ ✓ Multi-module: crossModuleDeps declared for cross-module constraints
181
+ ✓ No circular dependencies between modules
182
+ ✓ Plugins added at system level, not module level
183
+ ✓ Single module uses { module: x }, multi uses { modules: { a, b } }
184
+ ```
185
+
186
+ ## 7. Performance Review
187
+
188
+ ```
189
+ ✓ Derivations don't do expensive computation on every change
190
+ ✓ Constraints are not overly broad (when() triggers on minimal deps)
191
+ ✓ Resolvers use deduplication keys to prevent duplicate work
192
+ ✓ Batch resolvers used for N+1 scenarios
193
+ ✓ Effects don't trigger cascading mutations
194
+ ```
195
+
196
+ ## 8. Naming Convention Audit
197
+
198
+ ```
199
+ Module names: kebab-case ("user-auth", "shopping-cart")
200
+ Fact keys: camelCase (isLoggedIn, userName)
201
+ Derivation keys: camelCase (canEdit, totalPrice)
202
+ Constraint keys: camelCase (enforceAuth, validateInput)
203
+ Resolver keys: camelCase (fetchProfile, submitOrder)
204
+ Requirement type: UPPER_SNAKE_CASE (FETCH_PROFILE, SUBMIT_ORDER)
205
+ Event types: UPPER_SNAKE_CASE (USER_CLICKED, FORM_SUBMITTED)
206
+ ```
207
+
208
+ ## Review Output Format
209
+
210
+ When reviewing, output findings as:
211
+
212
+ ```
213
+ ## Review: [module-name]
214
+
215
+ ### Issues Found
216
+ | Severity | Issue | Location |
217
+ |----------|-------|----------|
218
+ | Critical | ... | file:line |
219
+ | Major | ... | file:line |
220
+ | Minor | ... | file:line |
221
+
222
+ ### Recommendations
223
+ 1. ...
224
+ 2. ...
225
+ ```
226
+
227
+ ## Reference Files
228
+
229
+ Supporting knowledge files loaded with this skill:
230
+ - `anti-patterns.md` – Full anti-pattern catalog with fixes
231
+ - `core-patterns.md` – Correct patterns to recommend
232
+ - `naming.md` – Naming conventions reference