@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.
- package/README.md +3 -3
- package/ai/ai-adapters.md +7 -7
- package/ai/ai-agents-streaming.md +8 -8
- package/ai/ai-budget-resilience.md +5 -5
- package/ai/ai-communication.md +1 -1
- package/ai/ai-guardrails-memory.md +7 -7
- package/ai/ai-mcp-rag.md +5 -5
- package/ai/ai-multi-agent.md +14 -14
- package/ai/ai-orchestrator.md +8 -8
- package/ai/ai-security.md +2 -2
- package/ai/ai-tasks.md +9 -9
- package/ai/ai-testing-evals.md +2 -2
- package/core/anti-patterns.md +39 -39
- package/core/constraints.md +15 -15
- package/core/core-patterns.md +9 -9
- package/core/error-boundaries.md +7 -7
- package/core/multi-module.md +16 -16
- package/core/naming.md +21 -21
- package/core/plugins.md +14 -14
- package/core/react-adapter.md +13 -13
- package/core/resolvers.md +14 -14
- package/core/schema-types.md +22 -22
- package/core/system-api.md +16 -16
- package/core/testing.md +5 -5
- package/core/time-travel.md +20 -20
- package/dist/index.cjs +6 -105
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -97
- package/dist/index.js.map +1 -1
- package/examples/ab-testing.ts +18 -90
- package/examples/ai-checkpoint.ts +68 -87
- package/examples/ai-guardrails.ts +20 -70
- package/examples/auth-flow.ts +2 -2
- package/examples/batch-resolver.ts +19 -59
- package/examples/contact-form.ts +220 -69
- package/examples/counter.ts +77 -95
- package/examples/dashboard-loader.ts +37 -55
- package/examples/debounce-constraints.ts +0 -2
- package/examples/dynamic-modules.ts +17 -20
- package/examples/error-boundaries.ts +30 -81
- package/examples/newsletter.ts +22 -49
- package/examples/notifications.ts +24 -23
- package/examples/optimistic-updates.ts +36 -41
- package/examples/pagination.ts +2 -2
- package/examples/permissions.ts +22 -32
- package/examples/provider-routing.ts +26 -83
- package/examples/shopping-cart.ts +8 -8
- package/examples/sudoku.ts +55 -62
- package/examples/theme-locale.ts +4 -7
- package/examples/time-machine.ts +12 -90
- package/examples/topic-guard.ts +30 -38
- package/examples/url-sync.ts +8 -8
- package/examples/websocket.ts +5 -5
- package/package.json +3 -3
package/examples/time-machine.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// Example: time-machine
|
|
2
|
-
// Source: examples/time-machine/src/
|
|
3
|
-
//
|
|
2
|
+
// Source: examples/time-machine/src/module.ts
|
|
3
|
+
// Pure module file — no DOM wiring
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Time Machine —
|
|
6
|
+
* Time Machine — Directive Module
|
|
7
7
|
*
|
|
8
8
|
* Drawing canvas where each stroke is a fact mutation. Full time-travel:
|
|
9
9
|
* undo/redo, export/import JSON, replay animation, changesets, snapshot slider.
|
|
@@ -21,7 +21,7 @@ import { devtoolsPlugin } from "@directive-run/core/plugins";
|
|
|
21
21
|
// Types
|
|
22
22
|
// ============================================================================
|
|
23
23
|
|
|
24
|
-
interface Stroke {
|
|
24
|
+
export interface Stroke {
|
|
25
25
|
id: string;
|
|
26
26
|
x: number;
|
|
27
27
|
y: number;
|
|
@@ -29,7 +29,7 @@ interface Stroke {
|
|
|
29
29
|
size: number;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
interface TimelineEntry {
|
|
32
|
+
export interface TimelineEntry {
|
|
33
33
|
time: number;
|
|
34
34
|
event: string;
|
|
35
35
|
detail: string;
|
|
@@ -45,16 +45,16 @@ interface TimelineEntry {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
// ============================================================================
|
|
48
|
-
// Timeline
|
|
48
|
+
// Timeline (external mutable array, same pattern as fraud-analysis)
|
|
49
49
|
// ============================================================================
|
|
50
50
|
|
|
51
|
-
const timeline: TimelineEntry[] = [];
|
|
51
|
+
export const timeline: TimelineEntry[] = [];
|
|
52
52
|
|
|
53
|
-
function addTimeline(
|
|
53
|
+
export function addTimeline(
|
|
54
54
|
event: string,
|
|
55
55
|
detail: string,
|
|
56
56
|
type: TimelineEntry["type"],
|
|
57
|
-
) {
|
|
57
|
+
): void {
|
|
58
58
|
timeline.unshift({ time: Date.now(), event, detail, type });
|
|
59
59
|
if (timeline.length > 50) {
|
|
60
60
|
timeline.length = 50;
|
|
@@ -65,9 +65,9 @@ function addTimeline(
|
|
|
65
65
|
// Schema
|
|
66
66
|
// ============================================================================
|
|
67
67
|
|
|
68
|
-
const schema = {
|
|
68
|
+
export const schema = {
|
|
69
69
|
facts: {
|
|
70
|
-
strokes: t.
|
|
70
|
+
strokes: t.array<Stroke>(),
|
|
71
71
|
currentColor: t.string(),
|
|
72
72
|
brushSize: t.number(),
|
|
73
73
|
changesetActive: t.boolean(),
|
|
@@ -140,86 +140,8 @@ const canvasModule = createModule("canvas", {
|
|
|
140
140
|
// System with Time-Travel
|
|
141
141
|
// ============================================================================
|
|
142
142
|
|
|
143
|
-
const system = createSystem({
|
|
143
|
+
export const system = createSystem({
|
|
144
144
|
module: canvasModule,
|
|
145
145
|
debug: { timeTravel: true, maxSnapshots: 200, runHistory: true },
|
|
146
146
|
plugins: [devtoolsPlugin({ name: "time-machine" })],
|
|
147
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();
|
package/examples/topic-guard.ts
CHANGED
|
@@ -42,11 +42,11 @@ export interface GuardrailLogEntry {
|
|
|
42
42
|
export const topicGuardSchema = {
|
|
43
43
|
facts: {
|
|
44
44
|
input: t.string(),
|
|
45
|
-
messages: t.
|
|
45
|
+
messages: t.array<ChatMessage>(),
|
|
46
46
|
isProcessing: t.boolean(),
|
|
47
47
|
lastGuardrailResult: t.object<GuardrailResult | null>(),
|
|
48
|
-
guardrailLog: t.
|
|
49
|
-
allowedTopics: t.
|
|
48
|
+
guardrailLog: t.array<GuardrailLogEntry>(),
|
|
49
|
+
allowedTopics: t.array<string>(),
|
|
50
50
|
},
|
|
51
51
|
derivations: {
|
|
52
52
|
messageCount: t.number(),
|
|
@@ -93,42 +93,36 @@ export const topicGuardModule = createModule("topic-guard", {
|
|
|
93
93
|
|
|
94
94
|
derive: {
|
|
95
95
|
messageCount: (facts) => {
|
|
96
|
-
return
|
|
97
|
-
.length;
|
|
96
|
+
return facts.messages.filter((m) => m.role === "user").length;
|
|
98
97
|
},
|
|
99
98
|
|
|
100
99
|
blockedCount: (facts) => {
|
|
101
|
-
return
|
|
102
|
-
|
|
103
|
-
).length;
|
|
100
|
+
return facts.messages.filter((m) => m.role === "user" && m.blocked)
|
|
101
|
+
.length;
|
|
104
102
|
},
|
|
105
103
|
|
|
106
104
|
allowedCount: (facts) => {
|
|
107
|
-
return
|
|
108
|
-
|
|
109
|
-
).length;
|
|
105
|
+
return facts.messages.filter((m) => m.role === "user" && !m.blocked)
|
|
106
|
+
.length;
|
|
110
107
|
},
|
|
111
108
|
|
|
112
109
|
blockRate: (facts, derive) => {
|
|
113
|
-
const total = derive.messageCount
|
|
110
|
+
const total = derive.messageCount;
|
|
114
111
|
if (total === 0) {
|
|
115
112
|
return "0%";
|
|
116
113
|
}
|
|
117
|
-
const blocked = derive.blockedCount
|
|
114
|
+
const blocked = derive.blockedCount;
|
|
118
115
|
const rate = Math.round((blocked / total) * 100);
|
|
119
116
|
|
|
120
117
|
return `${rate}%`;
|
|
121
118
|
},
|
|
122
119
|
|
|
123
120
|
canSend: (facts) => {
|
|
124
|
-
return (
|
|
125
|
-
(facts.input as string).trim().length > 0 &&
|
|
126
|
-
!(facts.isProcessing as boolean)
|
|
127
|
-
);
|
|
121
|
+
return facts.input.trim().length > 0 && !facts.isProcessing;
|
|
128
122
|
},
|
|
129
123
|
|
|
130
124
|
lastMessageBlocked: (facts) => {
|
|
131
|
-
const msgs = facts.messages
|
|
125
|
+
const msgs = facts.messages;
|
|
132
126
|
if (msgs.length === 0) {
|
|
133
127
|
return false;
|
|
134
128
|
}
|
|
@@ -143,13 +137,13 @@ export const topicGuardModule = createModule("topic-guard", {
|
|
|
143
137
|
|
|
144
138
|
events: {
|
|
145
139
|
send: (facts) => {
|
|
146
|
-
const text =
|
|
140
|
+
const text = facts.input.trim();
|
|
147
141
|
if (text.length === 0 || facts.isProcessing) {
|
|
148
142
|
return;
|
|
149
143
|
}
|
|
150
144
|
|
|
151
145
|
// Add user message
|
|
152
|
-
const messages = [...
|
|
146
|
+
const messages = [...facts.messages];
|
|
153
147
|
messages.push({ role: "user", text, blocked: false });
|
|
154
148
|
facts.messages = messages;
|
|
155
149
|
|
|
@@ -163,10 +157,7 @@ export const topicGuardModule = createModule("topic-guard", {
|
|
|
163
157
|
return;
|
|
164
158
|
}
|
|
165
159
|
|
|
166
|
-
const classifierResult = checkTopicClassifier(
|
|
167
|
-
text,
|
|
168
|
-
facts.allowedTopics as string[],
|
|
169
|
-
);
|
|
160
|
+
const classifierResult = checkTopicClassifier(text, facts.allowedTopics);
|
|
170
161
|
facts.lastGuardrailResult = classifierResult;
|
|
171
162
|
facts.isProcessing = true;
|
|
172
163
|
facts.input = "";
|
|
@@ -184,7 +175,7 @@ export const topicGuardModule = createModule("topic-guard", {
|
|
|
184
175
|
},
|
|
185
176
|
|
|
186
177
|
toggleTopic: (facts, { topic }) => {
|
|
187
|
-
const topics = [...
|
|
178
|
+
const topics = [...facts.allowedTopics];
|
|
188
179
|
const idx = topics.indexOf(topic);
|
|
189
180
|
if (idx >= 0) {
|
|
190
181
|
topics.splice(idx, 1);
|
|
@@ -203,12 +194,12 @@ export const topicGuardModule = createModule("topic-guard", {
|
|
|
203
194
|
offTopicDetected: {
|
|
204
195
|
priority: 100,
|
|
205
196
|
when: (facts) => {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
197
|
+
return (
|
|
198
|
+
facts.lastGuardrailResult?.blocked === true && facts.isProcessing
|
|
199
|
+
);
|
|
209
200
|
},
|
|
210
201
|
require: (facts) => {
|
|
211
|
-
const result = facts.lastGuardrailResult
|
|
202
|
+
const result = facts.lastGuardrailResult!;
|
|
212
203
|
|
|
213
204
|
return {
|
|
214
205
|
type: "BLOCK_MESSAGE",
|
|
@@ -221,9 +212,9 @@ export const topicGuardModule = createModule("topic-guard", {
|
|
|
221
212
|
onTopicConfirmed: {
|
|
222
213
|
priority: 90,
|
|
223
214
|
when: (facts) => {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
215
|
+
return (
|
|
216
|
+
facts.lastGuardrailResult?.blocked === false && facts.isProcessing
|
|
217
|
+
);
|
|
227
218
|
},
|
|
228
219
|
require: () => ({
|
|
229
220
|
type: "ALLOW_MESSAGE",
|
|
@@ -239,7 +230,7 @@ export const topicGuardModule = createModule("topic-guard", {
|
|
|
239
230
|
blockMessage: {
|
|
240
231
|
requirement: "BLOCK_MESSAGE",
|
|
241
232
|
resolve: async (req, context) => {
|
|
242
|
-
const messages = [...
|
|
233
|
+
const messages = [...context.facts.messages];
|
|
243
234
|
// Mark the last user message as blocked
|
|
244
235
|
const lastUserIdx = messages.length - 1;
|
|
245
236
|
if (lastUserIdx >= 0) {
|
|
@@ -264,7 +255,7 @@ export const topicGuardModule = createModule("topic-guard", {
|
|
|
264
255
|
allowMessage: {
|
|
265
256
|
requirement: "ALLOW_MESSAGE",
|
|
266
257
|
resolve: async (_req, context) => {
|
|
267
|
-
const messages = [...
|
|
258
|
+
const messages = [...context.facts.messages];
|
|
268
259
|
const lastUserMsg = messages.filter((m) => m.role === "user").pop();
|
|
269
260
|
const responseText = getMockAgentResponse(lastUserMsg?.text ?? "");
|
|
270
261
|
messages.push({
|
|
@@ -286,14 +277,15 @@ export const topicGuardModule = createModule("topic-guard", {
|
|
|
286
277
|
logGuardrailResult: {
|
|
287
278
|
deps: ["lastGuardrailResult"],
|
|
288
279
|
run: (facts) => {
|
|
289
|
-
const result = facts.lastGuardrailResult
|
|
280
|
+
const result = facts.lastGuardrailResult;
|
|
290
281
|
if (!result) {
|
|
291
282
|
return;
|
|
292
283
|
}
|
|
293
284
|
|
|
294
|
-
const
|
|
295
|
-
|
|
296
|
-
|
|
285
|
+
const lastUserMsg = [...facts.messages]
|
|
286
|
+
.reverse()
|
|
287
|
+
.find((m) => m.role === "user");
|
|
288
|
+
const log = [...facts.guardrailLog];
|
|
297
289
|
log.push({
|
|
298
290
|
timestamp: Date.now(),
|
|
299
291
|
input: lastUserMsg?.text ?? "",
|
package/examples/url-sync.ts
CHANGED
|
@@ -82,7 +82,7 @@ export const urlModule = createModule("url", {
|
|
|
82
82
|
const params = readUrlParams();
|
|
83
83
|
facts.search = params.search;
|
|
84
84
|
facts.category = params.category;
|
|
85
|
-
facts.sortBy = params.sortBy;
|
|
85
|
+
facts.sortBy = params.sortBy as "newest" | "price-asc" | "price-desc";
|
|
86
86
|
facts.page = params.page;
|
|
87
87
|
facts.syncingFromUrl = false;
|
|
88
88
|
},
|
|
@@ -103,7 +103,7 @@ export const urlModule = createModule("url", {
|
|
|
103
103
|
},
|
|
104
104
|
|
|
105
105
|
setSortBy: (facts, { value }) => {
|
|
106
|
-
facts.sortBy = value;
|
|
106
|
+
facts.sortBy = value as "newest" | "price-asc" | "price-desc";
|
|
107
107
|
facts.page = 1;
|
|
108
108
|
},
|
|
109
109
|
|
|
@@ -115,7 +115,7 @@ export const urlModule = createModule("url", {
|
|
|
115
115
|
facts.syncingFromUrl = true;
|
|
116
116
|
facts.search = search;
|
|
117
117
|
facts.category = category;
|
|
118
|
-
facts.sortBy = sortBy;
|
|
118
|
+
facts.sortBy = sortBy as "newest" | "price-asc" | "price-desc";
|
|
119
119
|
facts.page = page;
|
|
120
120
|
},
|
|
121
121
|
|
|
@@ -160,15 +160,15 @@ export const urlModule = createModule("url", {
|
|
|
160
160
|
const params = new URLSearchParams();
|
|
161
161
|
|
|
162
162
|
if (facts.search !== "") {
|
|
163
|
-
params.set("q", facts.search
|
|
163
|
+
params.set("q", facts.search);
|
|
164
164
|
}
|
|
165
165
|
if (facts.category !== "" && facts.category !== "all") {
|
|
166
|
-
params.set("cat", facts.category
|
|
166
|
+
params.set("cat", facts.category);
|
|
167
167
|
}
|
|
168
168
|
if (facts.sortBy !== "newest") {
|
|
169
|
-
params.set("sort", facts.sortBy
|
|
169
|
+
params.set("sort", facts.sortBy);
|
|
170
170
|
}
|
|
171
|
-
if (
|
|
171
|
+
if (facts.page > 1) {
|
|
172
172
|
params.set("page", String(facts.page));
|
|
173
173
|
}
|
|
174
174
|
|
|
@@ -191,7 +191,7 @@ export const urlModule = createModule("url", {
|
|
|
191
191
|
|
|
192
192
|
export const productsSchema = {
|
|
193
193
|
facts: {
|
|
194
|
-
items: t.
|
|
194
|
+
items: t.array<Product>(),
|
|
195
195
|
totalItems: t.number(),
|
|
196
196
|
isLoading: t.boolean(),
|
|
197
197
|
itemsPerPage: t.number(),
|
package/examples/websocket.ts
CHANGED
|
@@ -49,7 +49,7 @@ export const websocketSchema = {
|
|
|
49
49
|
url: t.string(),
|
|
50
50
|
status: t.string<WsStatus>(),
|
|
51
51
|
connectRequested: t.boolean(),
|
|
52
|
-
messages: t.
|
|
52
|
+
messages: t.array<WsMessage>(),
|
|
53
53
|
retryCount: t.number(),
|
|
54
54
|
maxRetries: t.number(),
|
|
55
55
|
messageToSend: t.string(),
|
|
@@ -58,7 +58,7 @@ export const websocketSchema = {
|
|
|
58
58
|
messageRate: t.number(),
|
|
59
59
|
connectFailRate: t.number(),
|
|
60
60
|
reconnectFailRate: t.number(),
|
|
61
|
-
eventLog: t.
|
|
61
|
+
eventLog: t.array<EventLogEntry>(),
|
|
62
62
|
},
|
|
63
63
|
derivations: {
|
|
64
64
|
isConnected: t.boolean(),
|
|
@@ -100,7 +100,7 @@ export const websocketSchema = {
|
|
|
100
100
|
// ============================================================================
|
|
101
101
|
|
|
102
102
|
function addLogEntry(facts: any, event: string, detail: string): void {
|
|
103
|
-
const log = [...
|
|
103
|
+
const log = [...facts.eventLog];
|
|
104
104
|
log.push({ timestamp: Date.now(), event, detail });
|
|
105
105
|
// Cap at 100
|
|
106
106
|
if (log.length > 100) {
|
|
@@ -312,7 +312,7 @@ export const websocketModule = createModule("websocket", {
|
|
|
312
312
|
return;
|
|
313
313
|
}
|
|
314
314
|
|
|
315
|
-
const messages = [...
|
|
315
|
+
const messages = [...context.facts.messages];
|
|
316
316
|
messages.push(msg);
|
|
317
317
|
// Cap at 50
|
|
318
318
|
if (messages.length > 50) {
|
|
@@ -369,7 +369,7 @@ export const websocketModule = createModule("websocket", {
|
|
|
369
369
|
requirement: "RECONNECT",
|
|
370
370
|
timeout: 60000,
|
|
371
371
|
resolve: async (req, context) => {
|
|
372
|
-
const retryCount = context.facts.retryCount
|
|
372
|
+
const retryCount = context.facts.retryCount;
|
|
373
373
|
context.facts.status = "reconnecting";
|
|
374
374
|
context.facts.reconnectTargetTime = Date.now() + req.delay;
|
|
375
375
|
addLogEntry(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@directive-run/knowledge",
|
|
3
|
-
"version": "0.2
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Knowledge files, examples, and validation for Directive — the constraint-driven TypeScript runtime.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Jason Comes",
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"tsx": "^4.19.2",
|
|
51
51
|
"typescript": "^5.7.2",
|
|
52
52
|
"vitest": "^3.0.0",
|
|
53
|
-
"@directive-run/core": "0.4.
|
|
54
|
-
"@directive-run/ai": "0.4.
|
|
53
|
+
"@directive-run/core": "0.4.2",
|
|
54
|
+
"@directive-run/ai": "0.4.2"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"build": "tsx scripts/generate-api-skeleton.ts && tsx scripts/extract-examples.ts && tsup",
|