@directive-run/knowledge 0.2.0 → 0.4.2

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 (54) hide show
  1. package/README.md +3 -3
  2. package/ai/ai-adapters.md +7 -7
  3. package/ai/ai-agents-streaming.md +8 -8
  4. package/ai/ai-budget-resilience.md +5 -5
  5. package/ai/ai-communication.md +1 -1
  6. package/ai/ai-guardrails-memory.md +7 -7
  7. package/ai/ai-mcp-rag.md +5 -5
  8. package/ai/ai-multi-agent.md +14 -14
  9. package/ai/ai-orchestrator.md +8 -8
  10. package/ai/ai-security.md +2 -2
  11. package/ai/ai-tasks.md +9 -9
  12. package/ai/ai-testing-evals.md +2 -2
  13. package/core/anti-patterns.md +39 -39
  14. package/core/constraints.md +15 -15
  15. package/core/core-patterns.md +9 -9
  16. package/core/error-boundaries.md +7 -7
  17. package/core/multi-module.md +16 -16
  18. package/core/naming.md +21 -21
  19. package/core/plugins.md +14 -14
  20. package/core/react-adapter.md +13 -13
  21. package/core/resolvers.md +14 -14
  22. package/core/schema-types.md +22 -22
  23. package/core/system-api.md +16 -16
  24. package/core/testing.md +5 -5
  25. package/core/time-travel.md +20 -20
  26. package/dist/index.cjs +6 -105
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.js +7 -97
  29. package/dist/index.js.map +1 -1
  30. package/examples/ab-testing.ts +18 -90
  31. package/examples/ai-checkpoint.ts +68 -87
  32. package/examples/ai-guardrails.ts +20 -70
  33. package/examples/auth-flow.ts +2 -2
  34. package/examples/batch-resolver.ts +19 -59
  35. package/examples/contact-form.ts +220 -69
  36. package/examples/counter.ts +77 -95
  37. package/examples/dashboard-loader.ts +37 -55
  38. package/examples/debounce-constraints.ts +0 -2
  39. package/examples/dynamic-modules.ts +17 -20
  40. package/examples/error-boundaries.ts +30 -81
  41. package/examples/newsletter.ts +22 -49
  42. package/examples/notifications.ts +24 -23
  43. package/examples/optimistic-updates.ts +36 -41
  44. package/examples/pagination.ts +2 -2
  45. package/examples/permissions.ts +22 -32
  46. package/examples/provider-routing.ts +26 -83
  47. package/examples/shopping-cart.ts +8 -8
  48. package/examples/sudoku.ts +55 -62
  49. package/examples/theme-locale.ts +4 -7
  50. package/examples/time-machine.ts +12 -90
  51. package/examples/topic-guard.ts +30 -38
  52. package/examples/url-sync.ts +8 -8
  53. package/examples/websocket.ts +5 -5
  54. package/package.json +3 -3
@@ -1,12 +1,12 @@
1
1
  // Example: ai-guardrails
2
- // Source: examples/ai-guardrails/src/main.ts
3
- // Extracted for AI rules — DOM wiring stripped
2
+ // Source: examples/ai-guardrails/src/module.ts
3
+ // Pure module fileno DOM wiring
4
4
 
5
5
  /**
6
- * AI Safety Shield — Prompt Injection & PII Detection
6
+ * AI Safety Shield — Directive Module
7
7
  *
8
- * Chat interface where every message passes through prompt injection detection,
9
- * PII detection, and compliance checks. All run locally using built-in patterns.
8
+ * Types, schema, module definition, timeline, analysis functions,
9
+ * and system creation for prompt injection & PII detection guardrails.
10
10
  */
11
11
 
12
12
  import {
@@ -27,7 +27,7 @@ import { devtoolsPlugin, emitDevToolsEvent } from "@directive-run/core/plugins";
27
27
  // Types
28
28
  // ============================================================================
29
29
 
30
- interface ChatMessage {
30
+ export interface ChatMessage {
31
31
  id: string;
32
32
  text: string;
33
33
  blocked: boolean;
@@ -36,22 +36,22 @@ interface ChatMessage {
36
36
  piiResult: PIIDetectionResult | null;
37
37
  }
38
38
 
39
- interface TimelineEntry {
39
+ export interface TimelineEntry {
40
40
  time: number;
41
41
  event: string;
42
42
  detail: string;
43
43
  type: "pass" | "injection" | "pii" | "compliance" | "info";
44
44
  }
45
45
 
46
- type ComplianceMode = "standard" | "gdpr" | "hipaa";
46
+ export type ComplianceMode = "standard" | "gdpr" | "hipaa";
47
47
 
48
48
  // ============================================================================
49
49
  // Timeline
50
50
  // ============================================================================
51
51
 
52
- const timeline: TimelineEntry[] = [];
52
+ export const timeline: TimelineEntry[] = [];
53
53
 
54
- function addTimeline(
54
+ export function addTimeline(
55
55
  event: string,
56
56
  detail: string,
57
57
  type: TimelineEntry["type"],
@@ -66,9 +66,9 @@ function addTimeline(
66
66
  // Schema
67
67
  // ============================================================================
68
68
 
69
- const schema = {
69
+ export const schema = {
70
70
  facts: {
71
- messages: t.object<ChatMessage[]>(),
71
+ messages: t.array<ChatMessage>(),
72
72
  complianceMode: t.string<ComplianceMode>(),
73
73
  redactionEnabled: t.boolean(),
74
74
  blockedCount: t.number(),
@@ -159,18 +159,17 @@ const guardrailModule = createModule("guardrails", {
159
159
  // System
160
160
  // ============================================================================
161
161
 
162
- const system = createSystem({
162
+ export const system = createSystem({
163
163
  module: guardrailModule,
164
164
  debug: { runHistory: true },
165
165
  plugins: [devtoolsPlugin({ name: "ai-guardrails" })],
166
166
  });
167
- system.start();
168
167
 
169
168
  // ============================================================================
170
169
  // Analysis Functions
171
170
  // ============================================================================
172
171
 
173
- function analyzeMessage(text: string): ChatMessage {
172
+ export function analyzeMessage(text: string): ChatMessage {
174
173
  const id = `msg-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
175
174
  let blocked = false;
176
175
 
@@ -181,6 +180,7 @@ function analyzeMessage(text: string): ChatMessage {
181
180
  system.facts.injectionAttempts =
182
181
  (system.facts.injectionAttempts as number) + 1;
183
182
  for (const p of injectionResult.patterns) {
183
+ addTimeline("injection", `${p.name} (${p.severity})`, "injection");
184
184
  }
185
185
  }
186
186
 
@@ -200,6 +200,7 @@ function analyzeMessage(text: string): ChatMessage {
200
200
  if (piiResult.detected) {
201
201
  system.facts.piiDetections = (system.facts.piiDetections as number) + 1;
202
202
  for (const item of piiResult.items) {
203
+ addTimeline("pii", `${item.type} found`, "pii");
203
204
  }
204
205
  }
205
206
 
@@ -228,12 +229,14 @@ function analyzeMessage(text: string): ChatMessage {
228
229
  blocked = true;
229
230
  system.facts.complianceBlocks =
230
231
  (system.facts.complianceBlocks as number) + 1;
232
+ addTimeline("compliance", "HIPAA: PHI detected", "compliance");
231
233
  }
232
234
 
233
235
  if (mode === "gdpr" && hasContactInfo) {
234
236
  blocked = true;
235
237
  system.facts.complianceBlocks =
236
238
  (system.facts.complianceBlocks as number) + 1;
239
+ addTimeline("compliance", "GDPR: personal data detected", "compliance");
237
240
  }
238
241
  }
239
242
 
@@ -250,8 +253,10 @@ function analyzeMessage(text: string): ChatMessage {
250
253
  }
251
254
 
252
255
  if (!blocked && !piiResult.detected) {
256
+ addTimeline("pass", "message passed all checks", "pass");
253
257
  }
254
258
 
259
+ const redactedText = piiResult.redactedText ?? text;
255
260
 
256
261
  return {
257
262
  id,
@@ -262,58 +267,3 @@ function analyzeMessage(text: string): ChatMessage {
262
267
  piiResult: piiResult.detected ? piiResult : null,
263
268
  };
264
269
  }
265
-
266
- // ============================================================================
267
- // DOM References
268
- // ============================================================================
269
-
270
- "gs-compliance",
271
- "gs-redaction",
272
-
273
- // Timeline
274
-
275
- // Pre-built test buttons
276
-
277
- // ============================================================================
278
- // Render
279
- // ============================================================================
280
-
281
- function escapeHtml(text: string): string {
282
-
283
- return div.innerHTML;
284
- }
285
-
286
-
287
- // ============================================================================
288
- // Subscribe
289
- // ============================================================================
290
-
291
- const allKeys = [
292
- ...Object.keys(schema.facts),
293
- ...Object.keys(schema.derivations),
294
- ];
295
- system.subscribe(allKeys, render);
296
-
297
- // ============================================================================
298
- // Controls
299
- // ============================================================================
300
-
301
- function sendMessage(text: string) {
302
- if (!text.trim()) {
303
- return;
304
- }
305
-
306
- const msg = analyzeMessage(text);
307
- const messages = [...(system.facts.messages as ChatMessage[]), msg];
308
- system.facts.messages = messages;
309
- }
310
-
311
-
312
- // Test buttons
313
-
314
-
315
- // ============================================================================
316
- // Initial Render
317
- // ============================================================================
318
-
319
- render();
@@ -54,7 +54,7 @@ export const authFlowSchema = {
54
54
  refreshBuffer: t.number(),
55
55
  loginFailRate: t.number(),
56
56
  refreshFailRate: t.number(),
57
- eventLog: t.object<EventLogEntry[]>(),
57
+ eventLog: t.array<EventLogEntry>(),
58
58
  },
59
59
  derivations: {
60
60
  isAuthenticated: t.boolean(),
@@ -87,7 +87,7 @@ export const authFlowSchema = {
87
87
  // ============================================================================
88
88
 
89
89
  function addLogEntry(facts: any, event: string, detail: string): void {
90
- const log = [...(facts.eventLog as EventLogEntry[])];
90
+ const log = [...facts.eventLog];
91
91
  log.push({ timestamp: Date.now(), event, detail });
92
92
  facts.eventLog = log;
93
93
  }
@@ -1,13 +1,12 @@
1
1
  // Example: batch-resolver
2
- // Source: examples/batch-resolver/src/main.ts
3
- // Extracted for AI rules — DOM wiring stripped
2
+ // Source: examples/batch-resolver/src/module.ts
3
+ // Pure module fileno DOM wiring
4
4
 
5
5
  /**
6
- * Batch Data Loader — Batched Resolution & Schema Validation
6
+ * Batch Data Loader — Directive Module
7
7
  *
8
- * User directory that loads profiles. Multiple constraints fire simultaneously;
9
- * the batch resolver groups them into one call. Dev-mode schema validation
10
- * catches type mismatches.
8
+ * Types, schema, mock data, module definition, timeline, and system creation
9
+ * for a batched user profile loader with schema validation.
11
10
  */
12
11
 
13
12
  import {
@@ -22,14 +21,14 @@ import { devtoolsPlugin } from "@directive-run/core/plugins";
22
21
  // Types
23
22
  // ============================================================================
24
23
 
25
- interface UserProfile {
24
+ export interface UserProfile {
26
25
  id: number;
27
26
  name: string;
28
27
  email: string;
29
28
  role: string;
30
29
  }
31
30
 
32
- interface TimelineEntry {
31
+ export interface TimelineEntry {
33
32
  time: number;
34
33
  event: string;
35
34
  detail: string;
@@ -67,9 +66,9 @@ const MOCK_USERS: Record<number, UserProfile> = {
67
66
  // Timeline
68
67
  // ============================================================================
69
68
 
70
- const timeline: TimelineEntry[] = [];
69
+ export const timeline: TimelineEntry[] = [];
71
70
 
72
- function addTimeline(
71
+ export function addTimeline(
73
72
  event: string,
74
73
  detail: string,
75
74
  type: TimelineEntry["type"],
@@ -84,15 +83,15 @@ function addTimeline(
84
83
  // Schema
85
84
  // ============================================================================
86
85
 
87
- const schema = {
86
+ export const schema = {
88
87
  facts: {
89
- users: t.object<UserProfile[]>(),
90
- loadingIds: t.object<number[]>(),
88
+ users: t.array<UserProfile>(),
89
+ loadingIds: t.array<number>(),
91
90
  batchCount: t.number(),
92
91
  totalRequests: t.number(),
93
92
  batchWindowMs: t.number(),
94
93
  failItemId: t.number(),
95
- validationErrors: t.object<string[]>(),
94
+ validationErrors: t.array<string>(),
96
95
  },
97
96
  derivations: {
98
97
  userCount: t.number(),
@@ -182,6 +181,7 @@ const batchModule = createModule("batch-loader", {
182
181
  ...facts.validationErrors,
183
182
  "schema: expected array for 'users', got string",
184
183
  ];
184
+ addTimeline(
185
185
  "validation",
186
186
  "schema error: expected array for 'users'",
187
187
  "validation",
@@ -225,6 +225,7 @@ const batchModule = createModule("batch-loader", {
225
225
  },
226
226
  resolveBatchWithResults: async (requirements, context) => {
227
227
  const ids = requirements.map((r) => r.userId);
228
+ addTimeline(
228
229
  "batch",
229
230
  `batch formed: ${ids.length} items [${ids.join(", ")}]`,
230
231
  "batch",
@@ -239,6 +240,7 @@ const batchModule = createModule("batch-loader", {
239
240
  const failId = context.facts.failItemId;
240
241
  const results = ids.map((id) => {
241
242
  if (id === failId) {
243
+ addTimeline("error", `user ${id}: simulated failure`, "error");
242
244
 
243
245
  return {
244
246
  success: false as const,
@@ -248,6 +250,7 @@ const batchModule = createModule("batch-loader", {
248
250
 
249
251
  const user = MOCK_USERS[id];
250
252
  if (!user) {
253
+ addTimeline("error", `user ${id}: not found`, "error");
251
254
 
252
255
  return {
253
256
  success: false as const,
@@ -275,6 +278,7 @@ const batchModule = createModule("batch-loader", {
275
278
  );
276
279
 
277
280
  const successCount = results.filter((r) => r.success).length;
281
+ addTimeline(
278
282
  "success",
279
283
  `batch resolved: ${successCount}/${ids.length} success`,
280
284
  "success",
@@ -290,52 +294,8 @@ const batchModule = createModule("batch-loader", {
290
294
  // System
291
295
  // ============================================================================
292
296
 
293
- const system = createSystem({
297
+ export const system = createSystem({
294
298
  module: batchModule,
295
299
  debug: { runHistory: true },
296
300
  plugins: [devtoolsPlugin({ name: "batch-resolver" })],
297
301
  });
298
- system.start();
299
-
300
- // ============================================================================
301
- // DOM References
302
- // ============================================================================
303
-
304
- "bl-fail-item",
305
-
306
- // ============================================================================
307
- // Render
308
- // ============================================================================
309
-
310
- function escapeHtml(text: string): string {
311
-
312
- return div.innerHTML;
313
- }
314
-
315
-
316
- // ============================================================================
317
- // Subscribe
318
- // ============================================================================
319
-
320
- const allKeys = [
321
- ...Object.keys(schema.facts),
322
- ...Object.keys(schema.derivations),
323
- ];
324
- system.subscribe(allKeys, render);
325
-
326
- // ============================================================================
327
- // Controls
328
- // ============================================================================
329
-
330
- // Individual load buttons (1-5)
331
- for (let i = 1; i <= 5; i++) {
332
- system.events.loadUser({ id: i });
333
- });
334
- }
335
-
336
-
337
- // ============================================================================
338
- // Initial Render
339
- // ============================================================================
340
-
341
- render();