deepclause-sdk 0.0.69 → 0.0.70

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 (46) hide show
  1. package/dist/agent.d.ts.map +1 -1
  2. package/dist/agent.js +125 -10
  3. package/dist/agent.js.map +1 -1
  4. package/dist/cli/commands.d.ts.map +1 -1
  5. package/dist/cli/commands.js +64 -7
  6. package/dist/cli/commands.js.map +1 -1
  7. package/dist/cli/config.d.ts +15 -12
  8. package/dist/cli/config.d.ts.map +1 -1
  9. package/dist/cli/config.js +34 -5
  10. package/dist/cli/config.js.map +1 -1
  11. package/dist/cli/default-skills.d.ts +1 -0
  12. package/dist/cli/default-skills.d.ts.map +1 -1
  13. package/dist/cli/default-skills.js +31 -0
  14. package/dist/cli/default-skills.js.map +1 -1
  15. package/dist/cli/tui.d.ts +15 -1
  16. package/dist/cli/tui.d.ts.map +1 -1
  17. package/dist/cli/tui.js +209 -7
  18. package/dist/cli/tui.js.map +1 -1
  19. package/dist/prolog/bridge.d.ts +15 -0
  20. package/dist/prolog/bridge.d.ts.map +1 -1
  21. package/dist/prolog/bridge.js +68 -0
  22. package/dist/prolog/bridge.js.map +1 -1
  23. package/dist/prolog-src/deepclause_mi.pl +135 -7
  24. package/dist/runner.d.ts +8 -0
  25. package/dist/runner.d.ts.map +1 -1
  26. package/dist/runner.js +78 -0
  27. package/dist/runner.js.map +1 -1
  28. package/dist/system/assets/docs/DML_REFERENCE.md +656 -0
  29. package/dist/system/assets/docs/TUI.md +11 -0
  30. package/dist/system/assets/index.d.ts +3 -2
  31. package/dist/system/assets/index.d.ts.map +1 -1
  32. package/dist/system/assets/index.js +5 -0
  33. package/dist/system/assets/index.js.map +1 -1
  34. package/dist/system/assets/recipes/deepclause-coding-workflow/SKILL.md +56 -1
  35. package/dist/system/assets/skills/plan.dml +259 -0
  36. package/dist/system/runtime/dml-executor.d.ts.map +1 -1
  37. package/dist/system/runtime/dml-executor.js +2 -14
  38. package/dist/system/runtime/dml-executor.js.map +1 -1
  39. package/dist/system/runtime/runtime-tools.d.ts +1 -0
  40. package/dist/system/runtime/runtime-tools.d.ts.map +1 -1
  41. package/dist/system/runtime/runtime-tools.js +95 -0
  42. package/dist/system/runtime/runtime-tools.js.map +1 -1
  43. package/dist/system/runtime/shell-manager.js +1 -1
  44. package/dist/system/runtime/shell-manager.js.map +1 -1
  45. package/package.json +4 -3
  46. package/src/prolog-src/deepclause_mi.pl +135 -7
@@ -0,0 +1,656 @@
1
+ # DML Language Reference
2
+
3
+ **DML** (DeepClause Meta Language) is a simplified Prolog dialect for programming AI agents. It combines declarative logic programming with LLM-powered task execution.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Program Structure](#program-structure)
8
+ - [Entry Point](#entry-point)
9
+ - [Core Predicates](#core-predicates)
10
+ - [task/1, task/2, task/3, task/4](#task-predicates)
11
+ - [exec/2](#exec2)
12
+ - [Tool Definitions](#tool-definitions)
13
+ - [Tool Scoping](#tool-scoping)
14
+ - [system/1, user/1](#memory-predicates)
15
+ - [output/1, yield/1, log/1](#output-predicates)
16
+ - [answer/1](#answer1)
17
+ - [param/3](#param3)
18
+ - [Control Flow](#control-flow)
19
+ - [String Interpolation](#string-interpolation)
20
+ - [Backtracking](#backtracking)
21
+ - [Full Prolog Support](#full-prolog-support)
22
+
23
+ ---
24
+
25
+ ## Program Structure
26
+
27
+ A DML program is a collection of Prolog clauses. Comments use `%` for single lines or `/* */` for blocks:
28
+
29
+ ```prolog
30
+ % This is a single line comment
31
+
32
+ /*
33
+ This is a
34
+ multi-line comment
35
+ */
36
+
37
+ % Define helper predicates
38
+ greet(Name, Greeting) :-
39
+ format(string(Greeting), "Hello, ~w!", [Name]).
40
+
41
+ % Main entry point
42
+ agent_main :-
43
+ greet("World", Msg),
44
+ answer(Msg).
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Entry Point
50
+
51
+ Every DML program must define `agent_main` as the entry point. It can have 0, 1, or 2 arguments:
52
+
53
+ ### agent_main/0
54
+ ```prolog
55
+ agent_main :-
56
+ task("Do something"),
57
+ answer("Done").
58
+ ```
59
+
60
+ ### agent_main/1
61
+ Receives the first parameter:
62
+ ```prolog
63
+ agent_main(Name) :-
64
+ format(string(Msg), "Hello, ~w!", [Name]),
65
+ answer(Msg).
66
+ ```
67
+
68
+ ### agent_main/2
69
+ Receives first two parameters:
70
+ ```prolog
71
+ agent_main(Name, Task) :-
72
+ system("You are a helpful assistant."),
73
+ task(Task),
74
+ answer("Complete").
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Core Predicates
80
+
81
+ ### `sample_token(+Prompt, -Token)`
82
+
83
+ Run a fresh prompt and normalize the result down to a single raw token string.
84
+ This is useful when the model should emit one grammar symbol, label, or keyword
85
+ instead of a full sentence.
86
+
87
+ ```prolog
88
+ agent_main :-
89
+ sample_token("Pick a SQL keyword for starting a query.", Token),
90
+ answer(Token).
91
+ ```
92
+
93
+ ### `sample_token(+Prompt, +Allowed, -Token)`
94
+
95
+ Same as `sample_token/2`, but constrains the result to an allowed token list.
96
+ If the model returns something outside that list, DML falls back deterministically
97
+ to the first allowed token. The runtime still samples just one model token, so
98
+ the prompt can stay terse and the grammar frontier can live in `Allowed`.
99
+
100
+ ```prolog
101
+ agent_main :-
102
+ sample_token("Pick the next token for a query.", ["select", "update"], Token),
103
+ answer(Token).
104
+ ```
105
+
106
+ ### Task Predicates
107
+
108
+ #### `task(+Description)`
109
+
110
+ Invoke an LLM to perform a task. The description is sent to the model.
111
+
112
+ ```prolog
113
+ agent_main :-
114
+ system("You are a coding assistant."),
115
+ task("Write a function to calculate factorial in Python."),
116
+ answer("Code generated!").
117
+ ```
118
+
119
+ #### `task(+Description, -Var1)`
120
+
121
+ Invoke LLM and bind output to a variable. Mention the variable name in the description:
122
+
123
+ ```prolog
124
+ agent_main :-
125
+ task("Calculate 2 + 2 and store the result in Answer.", Answer),
126
+ format(string(Msg), "The answer is: ~w", [Answer]),
127
+ answer(Msg).
128
+ ```
129
+
130
+ #### `task(+Description, -Var1, -Var2)`
131
+
132
+ Bind multiple variables:
133
+
134
+ ```prolog
135
+ agent_main :-
136
+ task("Generate a name and age for a character. Store name in Name and age in Age.", Name, Age),
137
+ format(string(Msg), "Character: ~w, Age: ~w", [Name, Age]),
138
+ answer(Msg).
139
+ ```
140
+
141
+ #### `task(+Description, -Var1, -Var2, -Var3)`
142
+
143
+ Bind up to three variables.
144
+
145
+ ### Type-Safe Output Variables
146
+
147
+ You can wrap output variables with type specifiers to enforce strict validation on the LLM's output. The runtime will ensure the value matches the specified type.
148
+
149
+ | Wrapper | Description | Zod Equivalent |
150
+ |---------|-------------|----------------|
151
+ | `string(Var)` | Default string type | `z.string()` |
152
+ | `integer(Var)` | Integer number | `z.number().int()` |
153
+ | `number(Var)` | Any number (float or int) | `z.number()` |
154
+ | `float(Var)` | Alias for number | `z.number()` |
155
+ | `boolean(Var)` | Boolean value | `z.boolean()` |
156
+ | `list(Type(Var))` | Array of specified type | `z.array(Type)` |
157
+ | `object(Var)` | Dictionary/Object | `z.record(z.unknown())` |
158
+
159
+ **Examples:**
160
+
161
+ ```prolog
162
+ % Enforce integer result
163
+ task("Calculate 10 + 5", integer(Result)).
164
+
165
+ % Enforce boolean result
166
+ task("Is this true?", boolean(IsTrue)).
167
+
168
+ % Enforce list of strings
169
+ task("List 3 colors", list(string(Colors))).
170
+
171
+ % Enforce object result
172
+ task("Extract user details", object(User)).
173
+ ```
174
+
175
+ **Note:** The LLM during `task()` can only call tools defined in DML (see [Tool Definitions](#tool-definitions)). Registered TypeScript tools are not automatically available - this gives you control over what the LLM can do.
176
+
177
+ ---
178
+
179
+ ### `exec(+ToolCall, -Output)`
180
+
181
+ Execute a registered TypeScript tool directly and capture its output.
182
+
183
+ ```prolog
184
+ % Assuming 'calculator' tool is registered in TypeScript
185
+ agent_main :-
186
+ exec(calculator(expression: "15 * 23"), Result),
187
+ format(string(Msg), "Calculation result: ~w", [Result]),
188
+ answer(Msg).
189
+ ```
190
+
191
+ Tool arguments use `key: value` syntax:
192
+
193
+ ```prolog
194
+ exec(fetch_url(url: "https://example.com"), Response)
195
+ ```
196
+
197
+ Or positional if the tool supports it:
198
+
199
+ ```prolog
200
+ exec(get_time, CurrentTime)
201
+ ```
202
+
203
+ ---
204
+
205
+ ### Tool Definitions
206
+
207
+ Define tools in DML that the LLM can call during `task()`. Tools use the `tool/2` predicate with a description:
208
+
209
+ ```prolog
210
+ % Define a tool - makes it available to the LLM with description
211
+ tool(calculate(Expression, Result), "Calculate a mathematical expression") :-
212
+ exec(calculator(expression: Expression), Result).
213
+
214
+ agent_main :-
215
+ system("You have a calculate tool."),
216
+ task("What is the square root of 144?"),
217
+ answer("Done").
218
+ ```
219
+
220
+ Tool definitions have the form:
221
+ ```prolog
222
+ tool(name(Arg1, Arg2, ..., Result), "Description") :- Body.
223
+ ```
224
+
225
+ The last argument is typically the output. The description is shown to the LLM.
226
+ ```
227
+
228
+ You can add Prolog logic in tool implementations:
229
+ ```prolog
230
+ tool(safe_divide(A, B, Result), "Safely divide two numbers") :-
231
+ ( B =:= 0
232
+ -> Result = error("Division by zero")
233
+ ; exec(calculator(expression: A/B), Result)
234
+ ).
235
+ ```
236
+
237
+ #### Using `task()` Inside Tools
238
+
239
+ Tools can use `task()` and `prompt()` internally to combine Prolog logic with LLM reasoning:
240
+
241
+ ```prolog
242
+ % A tool that computes then explains
243
+ :- tool(explain_calculation(A, B), "Calculate and explain the result").
244
+
245
+ tool(explain_calculation(A, B, Explanation)) :-
246
+ Sum is A + B, % Prolog computation
247
+ format(string(Desc), "Explain ~w + ~w = ~w to a child", [A, B, Sum]),
248
+ task(Desc, Explanation). % LLM explanation
249
+
250
+ % A tool that uses LLM for formatting
251
+ :- tool(format_data(Data), "Format data nicely using LLM").
252
+
253
+ tool(format_data(Data, FormattedOutput)) :-
254
+ format(string(Desc), "Format this data nicely: ~w", [Data]),
255
+ task(Desc, FormattedOutput).
256
+ ```
257
+
258
+ **Memory Isolation:** When `task()` or `prompt()` runs inside a tool, the nested agent starts with **fresh memory**. It does NOT inherit the parent's accumulated memory from `system()`, `user()`, or previous `task()` calls. If you need context in a nested task, pass it explicitly as a tool argument or add it with `system()` inside the tool body.
259
+
260
+ **Tool Access:** The nested agent has access to all DML tools **except** the tool that is currently executing (automatic call stack exclusion to prevent infinite recursion). You can further control tool access using `with_tools/2` and `without_tools/2`.
261
+
262
+ ```prolog
263
+ % Example: Passing context explicitly
264
+ tool(smart_search(Context, Query, Summary), "Search with context") :-
265
+ system(Context), % Add context to nested task's memory
266
+ exec(web_search(query: Query), Results),
267
+ format(string(Desc), "Summarize: ~w", [Results]),
268
+ task(Desc, Summary).
269
+ ```
270
+
271
+ ---
272
+
273
+ ### Tool Scoping
274
+
275
+ You can control which tools are available to nested `task()` calls using `with_tools/2` and `without_tools/2`.
276
+
277
+ #### `with_tools(+ToolList, +Goal)`
278
+
279
+ Run Goal with only the specified tools available to nested tasks:
280
+
281
+ ```prolog
282
+ % Only allow tool_a and tool_b in the nested task
283
+ tool(restricted_task(Input, Output), "Runs with limited tools") :-
284
+ with_tools([tool_a, tool_b], (
285
+ format(string(Desc), "Process '~w' using available tools", [Input]),
286
+ task(Desc, Output)
287
+ )).
288
+ ```
289
+
290
+ #### `without_tools(+ToolList, +Goal)`
291
+
292
+ Run Goal with the specified tools excluded from nested tasks:
293
+
294
+ ```prolog
295
+ % Exclude expensive_tool from the nested task
296
+ tool(cheap_task(Input, Output), "Runs without expensive tools") :-
297
+ without_tools([expensive_tool], (
298
+ format(string(Desc), "Process '~w' cheaply", [Input]),
299
+ task(Desc, Output)
300
+ )).
301
+ ```
302
+
303
+ #### Using Tool Scoping in `agent_main`
304
+
305
+ You can also use `with_tools/2` and `without_tools/2` directly in `agent_main`:
306
+
307
+ ```prolog
308
+ agent_main :-
309
+ system("You are a safe assistant."),
310
+
311
+ % Run task with only safe tools
312
+ with_tools([read_file, list_files], (
313
+ task("Analyze the files in the workspace.", Analysis)
314
+ )),
315
+
316
+ output(Analysis),
317
+ answer("Done").
318
+ ```
319
+
320
+ **Automatic call stack exclusion:** When a tool calls `task()`, the calling tool is automatically excluded from the nested agent's available tools to prevent infinite recursion. This happens in addition to any manual scoping via `with_tools/2` or `without_tools/2`.
321
+
322
+ ---
323
+
324
+ ### Memory Predicates
325
+
326
+ Memory predicates build the conversation context sent to the LLM.
327
+
328
+ #### `system(+Text)`
329
+
330
+ Add a system message (instructions for the LLM):
331
+
332
+ ```prolog
333
+ agent_main :-
334
+ system("You are a helpful cooking assistant."),
335
+ system("Always provide measurements in metric units."),
336
+ task("Suggest a recipe for pasta."),
337
+ answer("Done").
338
+ ```
339
+
340
+ #### `user(+Text)`
341
+
342
+ Add a user message to the context:
343
+
344
+ ```prolog
345
+ agent_main :-
346
+ system("You are a helpful assistant."),
347
+ user("I want to learn about machine learning."),
348
+ task("Explain the basics of machine learning."),
349
+ answer("Explained!").
350
+ ```
351
+
352
+ ---
353
+
354
+ ### Output Predicates
355
+
356
+ #### `output(+Text)`
357
+
358
+ Emit an output event to the caller. Does NOT affect the LLM conversation. Useful for progress updates:
359
+
360
+ ```prolog
361
+ agent_main :-
362
+ output("Starting analysis..."),
363
+ task("Analyze the data"),
364
+ output("Analysis complete!"),
365
+ answer("Done").
366
+ ```
367
+
368
+ #### `yield(+Text)`
369
+
370
+ Alias for `output/1`.
371
+
372
+ #### `log(+Text)`
373
+
374
+ Emit a log event. Similar to output but typed as 'log' for filtering:
375
+
376
+ ```prolog
377
+ agent_main :-
378
+ log("Debug: entering main"),
379
+ task("Process request"),
380
+ log("Debug: task completed"),
381
+ answer("Done").
382
+ ```
383
+
384
+ ---
385
+
386
+ ### `answer(+Text)`
387
+
388
+ Emit the final answer and **commit** - no backtracking occurs after `answer/1`:
389
+
390
+ ```prolog
391
+ agent_main :-
392
+ task("Generate a poem"),
393
+ answer("Poem complete!"). % Execution stops here
394
+ ```
395
+
396
+ **Important:** `answer/1` commits the execution. After answering, the program completes and does not try alternative clauses.
397
+
398
+ ---
399
+
400
+ ### `param(+Key, +Description, -Value)`
401
+
402
+ Access parameters passed from the caller:
403
+
404
+ ```prolog
405
+ agent_main :-
406
+ param(name, "User's name", Name),
407
+ param(age, "User's age", Age),
408
+ format(string(Msg), "Hello ~w, you are ~w years old!", [Name, Age]),
409
+ answer(Msg).
410
+ ```
411
+
412
+ Called from TypeScript:
413
+ ```typescript
414
+ dc.runDML(code, { params: { name: 'Alice', age: 30 } });
415
+ ```
416
+
417
+ ---
418
+
419
+ ## Control Flow
420
+
421
+ DML supports standard Prolog control flow:
422
+
423
+ ### Conjunction (and)
424
+ ```prolog
425
+ goal1, goal2, goal3
426
+ ```
427
+
428
+ ### Disjunction (or)
429
+ ```prolog
430
+ (goal1 ; goal2)
431
+ ```
432
+
433
+ ### If-Then-Else
434
+ ```prolog
435
+ (Condition -> Then ; Else)
436
+ ```
437
+
438
+ ### If-Then (soft cut)
439
+ ```prolog
440
+ (Condition -> Then)
441
+ ```
442
+
443
+ ### Negation as Failure
444
+ ```prolog
445
+ \+ goal
446
+ ```
447
+
448
+ ### Cut
449
+ ```prolog
450
+ !
451
+ ```
452
+
453
+ ### Catch/Throw
454
+ ```prolog
455
+ catch(Goal, Error, Recovery)
456
+ throw(Error)
457
+ ```
458
+
459
+ ---
460
+
461
+ ## String Interpolation
462
+
463
+ Text arguments support `{variable}` interpolation with parameters:
464
+
465
+ ```prolog
466
+ agent_main :-
467
+ param(topic, "Research topic", Topic),
468
+ system("You are a research assistant."),
469
+ task("Research the topic: {topic}"), % Topic is interpolated
470
+ answer("Research on {topic} complete!").
471
+ ```
472
+
473
+ ---
474
+
475
+ ## Backtracking
476
+
477
+ DML supports full Prolog backtracking, **including across LLM calls**. This enables powerful retry logic:
478
+
479
+ ### Multiple Clauses
480
+ ```prolog
481
+ % Try first approach
482
+ agent_main :-
483
+ output("Trying approach 1..."),
484
+ task("Solve using method A"),
485
+ fail. % Force failure to try next clause
486
+
487
+ % Fallback approach
488
+ agent_main :-
489
+ output("Trying approach 2..."),
490
+ task("Solve using method B"),
491
+ answer("Solved!").
492
+ ```
493
+
494
+ ### State Restoration
495
+
496
+ When backtracking occurs, the memory state is automatically restored:
497
+
498
+ ```prolog
499
+ agent_main :-
500
+ system("Context A"), % This is in memory
501
+ output("Trying path A"),
502
+ fail. % Memory is rolled back!
503
+
504
+ agent_main :-
505
+ system("Context B"), % Fresh memory
506
+ output("Trying path B"),
507
+ answer("Done").
508
+ ```
509
+
510
+ ### Disjunction Backtracking
511
+
512
+ ```prolog
513
+ agent_main :-
514
+ (
515
+ task("Try difficult approach"),
516
+ fail % Backtrack
517
+ ;
518
+ task("Try easier approach")
519
+ ),
520
+ answer("Completed").
521
+ ```
522
+
523
+ ---
524
+
525
+ ## Full Prolog Support
526
+
527
+ DML is built on SWI-Prolog, so you have access to the full Prolog language:
528
+
529
+ ### Lists
530
+ ```prolog
531
+ process_items([]).
532
+ process_items([H|T]) :-
533
+ format(string(Msg), "Processing: ~w", [H]),
534
+ output(Msg),
535
+ process_items(T).
536
+
537
+ agent_main :-
538
+ process_items([apple, banana, cherry]),
539
+ answer("All items processed").
540
+ ```
541
+
542
+ Not all builtin SWI Prolog predicates are guaranteed to work at this stage!
543
+
544
+ ### Arithmetic
545
+ ```prolog
546
+ agent_main :-
547
+ X is 10 + 5 * 2,
548
+ format(string(Msg), "Result: ~w", [X]),
549
+ answer(Msg).
550
+ ```
551
+
552
+ ### String Formatting
553
+ ```prolog
554
+ agent_main :-
555
+ format(string(S), "Hello ~w, you are ~d years old", [alice, 30]),
556
+ answer(S).
557
+ ```
558
+
559
+ ### Findall
560
+ ```prolog
561
+ color(red).
562
+ color(green).
563
+ color(blue).
564
+
565
+ agent_main :-
566
+ findall(C, color(C), Colors),
567
+ format(string(Msg), "Colors: ~w", [Colors]),
568
+ answer(Msg).
569
+ ```
570
+
571
+ ### Assert/Retract (within session)
572
+ ```prolog
573
+ agent_main :-
574
+ assertz(fact(42)),
575
+ fact(X),
576
+ format(string(Msg), "Stored fact: ~w", [X]),
577
+ answer(Msg).
578
+ ```
579
+
580
+ ### Constraint Logic Programming (CLP)
581
+
582
+ DML supports Prolog's CLP libraries for solving optimization and logic problems without needing Python:
583
+
584
+ - **CLP(FD)**: Finite domains (integers). Use `:- use_module(library(clpfd)).`
585
+ - **CLP(Q)**: Rational numbers. Use `:- use_module(library(clpq)).`
586
+ - **CLP(R)**: Real numbers. Use `:- use_module(library(clpr)).`
587
+
588
+ ```prolog
589
+ :- use_module(library(clpfd)).
590
+
591
+ agent_main(Total) :-
592
+ [X,Y] ins 0..100,
593
+ X + Y #= Total,
594
+ X * Y #= 2400,
595
+ label([X,Y]),
596
+ format(string(Msg), "X=~w, Y=~w", [X, Y]),
597
+ answer(Msg).
598
+ ```
599
+
600
+ ### Dictionaries (SWI-Prolog)
601
+ ```prolog
602
+ agent_main :-
603
+ D = point{x: 10, y: 20},
604
+ X = D.x,
605
+ format(string(Msg), "X coordinate: ~w", [X]),
606
+ answer(Msg).
607
+ ```
608
+
609
+ ---
610
+
611
+ ## Complete Example
612
+
613
+ ```prolog
614
+ % research_assistant.dml
615
+ % A multi-step research assistant
616
+
617
+ % Helper to log progress
618
+ step(N, Desc) :-
619
+ format(string(Msg), "Step ~w: ~w", [N, Desc]),
620
+ output(Msg).
621
+
622
+ % Main entry point
623
+ agent_main :-
624
+ param(topic, "Research topic", Topic),
625
+
626
+ % Set up the assistant
627
+ system("You are a thorough research assistant."),
628
+ system("Provide detailed, accurate information."),
629
+
630
+ % Step 1: Overview
631
+ step(1, "Getting overview"),
632
+ format(string(Task1), "Provide a brief overview of ~w", [Topic]),
633
+ task(Task1),
634
+
635
+ % Step 2: Key concepts
636
+ step(2, "Identifying key concepts"),
637
+ task("List the 3 most important concepts related to this topic. Store them in Concepts.", Concepts),
638
+
639
+ % Step 3: Deep dive
640
+ step(3, "Deep dive analysis"),
641
+ format(string(Task3), "Explain these concepts in detail: ~w", [Concepts]),
642
+ task(Task3),
643
+
644
+ % Complete
645
+ format(string(FinalMsg), "Research on '~w' complete!", [Topic]),
646
+ answer(FinalMsg).
647
+ ```
648
+
649
+ Run with:
650
+ ```typescript
651
+ for await (const event of dc.runDML(code, {
652
+ params: { topic: 'quantum computing' }
653
+ })) {
654
+ console.log(event.type, event.content);
655
+ }
656
+ ```
@@ -11,6 +11,8 @@ The TUI is the operator interface around a single built-in agent: the conductor.
11
11
  - The upper-right pane shows live execution activity.
12
12
  - The lower-right pane shows context, token usage, system asset sources, and shell execution details.
13
13
 
14
+ The local `.deepclause/docs/` folder contains editable workspace docs such as `TUI.md` and `DML_REFERENCE.md`. The system `plan` skill reads `DML_REFERENCE.md` and `.deepclause/system/DML_COMPILER_PROMPT.md` before generating new plan files.
15
+
14
16
  ## Command Bar
15
17
 
16
18
  The command bar accepts three main input styles plus direct skill execution:
@@ -18,6 +20,9 @@ The command bar accepts three main input styles plus direct skill execution:
18
20
  - Plain text sends a normal request to the conductor.
19
21
  - `/...` runs a built-in slash command.
20
22
  - `/<skill> [args]` runs a compiled local skill directly.
23
+ - `/plan <request>` runs the system `plan` skill from `.deepclause/system/plan.dml`.
24
+ - `/<plan> [args]` runs `plans/<plan>.dml` when no compiled local skill matches that name.
25
+ - `/run <file> [args]` runs a workspace DML file directly.
21
26
  - `!<command>` runs a shell command directly in the configured workspace shell.
22
27
 
23
28
  Examples:
@@ -26,6 +31,8 @@ Examples:
26
31
  summarize the latest test failures
27
32
  /sessions
28
33
  /set-model openai:gpt-4.1 --slot run
34
+ /plan create a simple repo cleanup workflow
35
+ /run plans/repo_cleanup.dml
29
36
  /compile create a skill that reviews changelogs
30
37
  /deep-research transformers scaling laws
31
38
  !git status
@@ -41,6 +48,8 @@ Common built-in slash commands:
41
48
  - `/new [title]` creates a new conductor session.
42
49
  - `/sessions` refreshes or switches sessions.
43
50
  - `/set-model <model> [--slot <slot>]` updates the configured model for all slots or one slot.
51
+ - `/plan <request>` runs the system plan skill and writes a simple standalone plan under `plans/`.
52
+ - `/run <file> [args]` runs a workspace DML file directly.
44
53
  - `/compile <spec>` runs the skill creator.
45
54
  - `/skill-creator <spec>` is an alias for `/compile`.
46
55
  - `/cancel` aborts the current running task, skill, or shell command.
@@ -48,6 +57,7 @@ Common built-in slash commands:
48
57
  - `/quit` or `/exit` closes the TUI.
49
58
 
50
59
  Any other `/name` is treated as a compiled skill invocation if that skill exists in the local catalog.
60
+ If no compiled skill matches, the TUI looks for `plans/<name>.dml` and runs that file directly.
51
61
 
52
62
  ## Direct Shell Mode
53
63
 
@@ -126,6 +136,7 @@ The conductor is not the same thing as a compiled skill.
126
136
 
127
137
  - The conductor handles freeform user requests and orchestration.
128
138
  - Compiled skills are reusable DML workers in `.deepclause/tools/`.
139
+ - The `plan` system skill lives at `.deepclause/system/plan.dml` and follows the same override model as the other system DML assets.
129
140
  - `/set-model` updates the configured gateway, run, and compile model selection for future turns, or only one slot when `--slot` is provided.
130
141
  - `/compile` and `/skill-creator` use the skill creator to turn a spec into a validated local skill.
131
142
 
@@ -1,7 +1,7 @@
1
- export type SystemSkillAssetName = 'conductor' | 'skill-creator';
1
+ export type SystemSkillAssetName = 'conductor' | 'skill-creator' | 'plan';
2
2
  export type SystemPromptAssetName = 'conductor' | 'skill-creator' | 'task';
3
3
  export type SystemCompactorAssetName = 'default-session-compactor' | 'default-loop-compactor';
4
- export type WorkspaceDocAssetName = 'tui';
4
+ export type WorkspaceDocAssetName = 'tui' | 'dml-reference';
5
5
  interface SystemAssetLookupOptions {
6
6
  workspaceRoot?: string;
7
7
  workspacePath?: string;
@@ -15,6 +15,7 @@ export declare function getWorkspaceRecipeAssetsDir(workspaceRoot: string): stri
15
15
  export declare function getSystemAssetSourcePaths(workspaceRoot?: string): {
16
16
  conductorDml: string;
17
17
  conductorPrompt: string;
18
+ planDml: string;
18
19
  skillCreatorDml: string;
19
20
  skillCreatorPrompt: string;
20
21
  taskPrompt: string;