@directive-run/knowledge 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 (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +63 -0
  3. package/ai/ai-adapters.md +250 -0
  4. package/ai/ai-agents-streaming.md +269 -0
  5. package/ai/ai-budget-resilience.md +235 -0
  6. package/ai/ai-communication.md +281 -0
  7. package/ai/ai-debug-observability.md +243 -0
  8. package/ai/ai-guardrails-memory.md +332 -0
  9. package/ai/ai-mcp-rag.md +288 -0
  10. package/ai/ai-multi-agent.md +274 -0
  11. package/ai/ai-orchestrator.md +227 -0
  12. package/ai/ai-security.md +293 -0
  13. package/ai/ai-tasks.md +261 -0
  14. package/ai/ai-testing-evals.md +378 -0
  15. package/api-skeleton.md +5 -0
  16. package/core/anti-patterns.md +382 -0
  17. package/core/constraints.md +263 -0
  18. package/core/core-patterns.md +228 -0
  19. package/core/error-boundaries.md +322 -0
  20. package/core/multi-module.md +315 -0
  21. package/core/naming.md +283 -0
  22. package/core/plugins.md +344 -0
  23. package/core/react-adapter.md +262 -0
  24. package/core/resolvers.md +357 -0
  25. package/core/schema-types.md +262 -0
  26. package/core/system-api.md +271 -0
  27. package/core/testing.md +257 -0
  28. package/core/time-travel.md +238 -0
  29. package/dist/index.cjs +111 -0
  30. package/dist/index.cjs.map +1 -0
  31. package/dist/index.d.cts +10 -0
  32. package/dist/index.d.ts +10 -0
  33. package/dist/index.js +102 -0
  34. package/dist/index.js.map +1 -0
  35. package/examples/ab-testing.ts +385 -0
  36. package/examples/ai-checkpoint.ts +509 -0
  37. package/examples/ai-guardrails.ts +319 -0
  38. package/examples/ai-orchestrator.ts +589 -0
  39. package/examples/async-chains.ts +287 -0
  40. package/examples/auth-flow.ts +371 -0
  41. package/examples/batch-resolver.ts +341 -0
  42. package/examples/checkers.ts +589 -0
  43. package/examples/contact-form.ts +176 -0
  44. package/examples/counter.ts +393 -0
  45. package/examples/dashboard-loader.ts +512 -0
  46. package/examples/debounce-constraints.ts +105 -0
  47. package/examples/dynamic-modules.ts +293 -0
  48. package/examples/error-boundaries.ts +430 -0
  49. package/examples/feature-flags.ts +220 -0
  50. package/examples/form-wizard.ts +347 -0
  51. package/examples/fraud-analysis.ts +663 -0
  52. package/examples/goal-heist.ts +341 -0
  53. package/examples/multi-module.ts +57 -0
  54. package/examples/newsletter.ts +241 -0
  55. package/examples/notifications.ts +210 -0
  56. package/examples/optimistic-updates.ts +317 -0
  57. package/examples/pagination.ts +260 -0
  58. package/examples/permissions.ts +337 -0
  59. package/examples/provider-routing.ts +403 -0
  60. package/examples/server.ts +316 -0
  61. package/examples/shopping-cart.ts +422 -0
  62. package/examples/sudoku.ts +630 -0
  63. package/examples/theme-locale.ts +204 -0
  64. package/examples/time-machine.ts +225 -0
  65. package/examples/topic-guard.ts +306 -0
  66. package/examples/url-sync.ts +333 -0
  67. package/examples/websocket.ts +404 -0
  68. package/package.json +65 -0
@@ -0,0 +1,204 @@
1
+ // Example: theme-locale
2
+ // Source: examples/theme-locale/src/theme-locale.ts
3
+ // Pure module file — no DOM wiring
4
+
5
+ /**
6
+ * Theme & Locale — Directive Modules
7
+ *
8
+ * Two modules:
9
+ * - `preferences` — theme, locale, sidebar, translations, system dark preference
10
+ * - `layout` — responsive breakpoint tracking
11
+ *
12
+ * Demonstrates multi-module composition, auto-tracked derivations,
13
+ * effects for DOM side-effects, and persistence plugin for user prefs.
14
+ */
15
+
16
+ import { type ModuleSchema, createModule, t } from "@directive-run/core";
17
+
18
+ // ============================================================================
19
+ // Types
20
+ // ============================================================================
21
+
22
+ export interface Translations {
23
+ greeting: string;
24
+ settings: string;
25
+ theme: string;
26
+ language: string;
27
+ sidebar: string;
28
+ }
29
+
30
+ export type ThemeChoice = "light" | "dark" | "system";
31
+ export type Breakpoint = "mobile" | "tablet" | "desktop";
32
+
33
+ // ============================================================================
34
+ // Translation data
35
+ // ============================================================================
36
+
37
+ const TRANSLATIONS: Record<string, Translations> = {
38
+ en: {
39
+ greeting: "Hello",
40
+ settings: "Settings",
41
+ theme: "Theme",
42
+ language: "Language",
43
+ sidebar: "Sidebar",
44
+ },
45
+ es: {
46
+ greeting: "Hola",
47
+ settings: "Configuraci\u00f3n",
48
+ theme: "Tema",
49
+ language: "Idioma",
50
+ sidebar: "Barra lateral",
51
+ },
52
+ fr: {
53
+ greeting: "Bonjour",
54
+ settings: "Param\u00e8tres",
55
+ theme: "Th\u00e8me",
56
+ language: "Langue",
57
+ sidebar: "Barre lat\u00e9rale",
58
+ },
59
+ };
60
+
61
+ function getTranslations(locale: string): Translations {
62
+ return TRANSLATIONS[locale] ?? TRANSLATIONS.en;
63
+ }
64
+
65
+ // ============================================================================
66
+ // Preferences Schema
67
+ // ============================================================================
68
+
69
+ export const preferencesSchema = {
70
+ facts: {
71
+ theme: t.string<ThemeChoice>(),
72
+ locale: t.string(),
73
+ sidebarOpen: t.boolean(),
74
+ systemPrefersDark: t.boolean(),
75
+ loadedLocale: t.string(),
76
+ translations: t.object<Translations>(),
77
+ },
78
+ derivations: {
79
+ effectiveTheme: t.string(),
80
+ isRTL: t.boolean(),
81
+ },
82
+ events: {
83
+ setTheme: { value: t.string() },
84
+ setLocale: { value: t.string() },
85
+ toggleSidebar: {},
86
+ setSystemPreference: { value: t.boolean() },
87
+ },
88
+ requirements: {},
89
+ } satisfies ModuleSchema;
90
+
91
+ // ============================================================================
92
+ // Layout Schema
93
+ // ============================================================================
94
+
95
+ export const layoutSchema = {
96
+ facts: {
97
+ breakpoint: t.string<Breakpoint>(),
98
+ },
99
+ derivations: {},
100
+ events: {
101
+ setBreakpoint: { value: t.string() },
102
+ },
103
+ requirements: {},
104
+ } satisfies ModuleSchema;
105
+
106
+ // ============================================================================
107
+ // Preferences Module
108
+ // ============================================================================
109
+
110
+ export const preferencesModule = createModule("preferences", {
111
+ schema: preferencesSchema,
112
+
113
+ init: (facts) => {
114
+ facts.theme = "system";
115
+ facts.locale = "en";
116
+ facts.sidebarOpen = true;
117
+ facts.systemPrefersDark = false;
118
+ facts.loadedLocale = "en";
119
+ facts.translations = getTranslations("en");
120
+ },
121
+
122
+ // ============================================================================
123
+ // Derivations
124
+ // ============================================================================
125
+
126
+ derive: {
127
+ effectiveTheme: (facts) => {
128
+ if (facts.theme === "system") {
129
+ return facts.systemPrefersDark ? "dark" : "light";
130
+ }
131
+
132
+ return facts.theme;
133
+ },
134
+
135
+ isRTL: (facts) => {
136
+ const rtlLocales = ["ar", "he", "fa", "ur"];
137
+
138
+ return rtlLocales.includes(facts.locale as string);
139
+ },
140
+ },
141
+
142
+ // ============================================================================
143
+ // Events
144
+ // ============================================================================
145
+
146
+ events: {
147
+ setTheme: (facts, { value }) => {
148
+ facts.theme = value;
149
+ },
150
+
151
+ setLocale: (facts, { value }) => {
152
+ facts.locale = value;
153
+ facts.loadedLocale = value;
154
+ facts.translations = getTranslations(value);
155
+ },
156
+
157
+ toggleSidebar: (facts) => {
158
+ facts.sidebarOpen = !facts.sidebarOpen;
159
+ },
160
+
161
+ setSystemPreference: (facts, { value }) => {
162
+ facts.systemPrefersDark = value;
163
+ },
164
+ },
165
+
166
+ // ============================================================================
167
+ // Effects
168
+ // ============================================================================
169
+
170
+ effects: {
171
+ applyTheme: {
172
+ run: (facts) => {
173
+ const effective =
174
+ facts.theme === "system"
175
+ ? facts.systemPrefersDark
176
+ ? "dark"
177
+ : "light"
178
+ : facts.theme;
179
+ document.documentElement.setAttribute(
180
+ "data-theme",
181
+ effective as string,
182
+ );
183
+ },
184
+ },
185
+ },
186
+ });
187
+
188
+ // ============================================================================
189
+ // Layout Module
190
+ // ============================================================================
191
+
192
+ export const layoutModule = createModule("layout", {
193
+ schema: layoutSchema,
194
+
195
+ init: (facts) => {
196
+ facts.breakpoint = "desktop";
197
+ },
198
+
199
+ events: {
200
+ setBreakpoint: (facts, { value }) => {
201
+ facts.breakpoint = value;
202
+ },
203
+ },
204
+ });
@@ -0,0 +1,225 @@
1
+ // Example: time-machine
2
+ // Source: examples/time-machine/src/main.ts
3
+ // Extracted for AI rules — DOM wiring stripped
4
+
5
+ /**
6
+ * Time Machine — Time-Travel Debugging
7
+ *
8
+ * Drawing canvas where each stroke is a fact mutation. Full time-travel:
9
+ * undo/redo, export/import JSON, replay animation, changesets, snapshot slider.
10
+ */
11
+
12
+ import {
13
+ type ModuleSchema,
14
+ createModule,
15
+ createSystem,
16
+ t,
17
+ } from "@directive-run/core";
18
+ import { devtoolsPlugin } from "@directive-run/core/plugins";
19
+
20
+ // ============================================================================
21
+ // Types
22
+ // ============================================================================
23
+
24
+ interface Stroke {
25
+ id: string;
26
+ x: number;
27
+ y: number;
28
+ color: string;
29
+ size: number;
30
+ }
31
+
32
+ interface TimelineEntry {
33
+ time: number;
34
+ event: string;
35
+ detail: string;
36
+ type:
37
+ | "stroke"
38
+ | "undo"
39
+ | "redo"
40
+ | "changeset"
41
+ | "export"
42
+ | "import"
43
+ | "replay"
44
+ | "goto";
45
+ }
46
+
47
+ // ============================================================================
48
+ // Timeline
49
+ // ============================================================================
50
+
51
+ const timeline: TimelineEntry[] = [];
52
+
53
+ function addTimeline(
54
+ event: string,
55
+ detail: string,
56
+ type: TimelineEntry["type"],
57
+ ) {
58
+ timeline.unshift({ time: Date.now(), event, detail, type });
59
+ if (timeline.length > 50) {
60
+ timeline.length = 50;
61
+ }
62
+ }
63
+
64
+ // ============================================================================
65
+ // Schema
66
+ // ============================================================================
67
+
68
+ const schema = {
69
+ facts: {
70
+ strokes: t.object<Stroke[]>(),
71
+ currentColor: t.string(),
72
+ brushSize: t.number(),
73
+ changesetActive: t.boolean(),
74
+ changesetLabel: t.string(),
75
+ },
76
+ derivations: {
77
+ strokeCount: t.number(),
78
+ canUndo: t.boolean(),
79
+ canRedo: t.boolean(),
80
+ currentIndex: t.number(),
81
+ totalSnapshots: t.number(),
82
+ },
83
+ events: {
84
+ addStroke: { x: t.number(), y: t.number() },
85
+ setColor: { value: t.string() },
86
+ setBrushSize: { value: t.number() },
87
+ clearCanvas: {},
88
+ },
89
+ requirements: {},
90
+ } satisfies ModuleSchema;
91
+
92
+ // ============================================================================
93
+ // Module
94
+ // ============================================================================
95
+
96
+ const canvasModule = createModule("canvas", {
97
+ schema,
98
+
99
+ init: (facts) => {
100
+ facts.strokes = [];
101
+ facts.currentColor = "#5ba3a3";
102
+ facts.brushSize = 12;
103
+ facts.changesetActive = false;
104
+ facts.changesetLabel = "";
105
+ },
106
+
107
+ derive: {
108
+ strokeCount: (facts) => facts.strokes.length,
109
+ // These will be updated from the time-travel manager
110
+ canUndo: () => false,
111
+ canRedo: () => false,
112
+ currentIndex: () => 0,
113
+ totalSnapshots: () => 0,
114
+ },
115
+
116
+ events: {
117
+ addStroke: (facts, { x, y }) => {
118
+ const stroke: Stroke = {
119
+ id: `s${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
120
+ x,
121
+ y,
122
+ color: facts.currentColor,
123
+ size: facts.brushSize,
124
+ };
125
+ facts.strokes = [...facts.strokes, stroke];
126
+ },
127
+ setColor: (facts, { value }) => {
128
+ facts.currentColor = value;
129
+ },
130
+ setBrushSize: (facts, { value }) => {
131
+ facts.brushSize = value;
132
+ },
133
+ clearCanvas: (facts) => {
134
+ facts.strokes = [];
135
+ },
136
+ },
137
+ });
138
+
139
+ // ============================================================================
140
+ // System with Time-Travel
141
+ // ============================================================================
142
+
143
+ const system = createSystem({
144
+ module: canvasModule,
145
+ debug: { timeTravel: true, maxSnapshots: 200, runHistory: true },
146
+ plugins: [devtoolsPlugin({ name: "time-machine" })],
147
+ });
148
+ system.start();
149
+
150
+ const tt = system.debug!;
151
+
152
+ // ============================================================================
153
+ // DOM References
154
+ // ============================================================================
155
+
156
+ const ctx = canvasEl.getContext("2d")!;
157
+ "tm-brush-size",
158
+ "tm-snapshot-slider",
159
+ "tm-export-area",
160
+ "tm-begin-changeset",
161
+ "tm-end-changeset",
162
+
163
+ // Timeline
164
+
165
+ // ============================================================================
166
+ // Canvas Rendering
167
+ // ============================================================================
168
+
169
+ function drawCanvas(): void {
170
+ ctx.fillStyle = "#0f172a";
171
+ ctx.fillRect(0, 0, canvasEl.width, canvasEl.height);
172
+
173
+ const strokes = system.facts.strokes as Stroke[];
174
+ for (const stroke of strokes) {
175
+ ctx.beginPath();
176
+ ctx.arc(stroke.x, stroke.y, stroke.size / 2, 0, Math.PI * 2);
177
+ ctx.fillStyle = stroke.color;
178
+ ctx.fill();
179
+ }
180
+ }
181
+
182
+ // ============================================================================
183
+ // Render
184
+ // ============================================================================
185
+
186
+ function escapeHtml(text: string): string {
187
+
188
+ return div.innerHTML;
189
+ }
190
+
191
+
192
+ // ============================================================================
193
+ // Subscribe
194
+ // ============================================================================
195
+
196
+ const allKeys = [...Object.keys(schema.facts)];
197
+ system.subscribe(allKeys, render);
198
+
199
+ // ============================================================================
200
+ // Canvas Interaction (pointer events for mouse + touch)
201
+ // ============================================================================
202
+
203
+ let isDrawing = false;
204
+
205
+ function canvasCoords(e: PointerEvent): { x: number; y: number } {
206
+ const scaleX = canvasEl.width / rect.width;
207
+ const scaleY = canvasEl.height / rect.height;
208
+
209
+ return {
210
+ x: Math.round((e.clientX - rect.left) * scaleX),
211
+ y: Math.round((e.clientY - rect.top) * scaleY),
212
+ };
213
+ }
214
+
215
+
216
+ // ============================================================================
217
+ // Controls
218
+ // ============================================================================
219
+
220
+
221
+ // ============================================================================
222
+ // Initial Render
223
+ // ============================================================================
224
+
225
+ render();