dirac-lang 0.1.19 → 0.1.20
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/dist/{chunk-GR6KWGCI.js → chunk-UXTK2GC2.js} +42 -20
- package/dist/{chunk-QMFCOZ5D.js → chunk-VA7VOLNV.js} +1 -1
- package/dist/cli.js +3 -3
- package/dist/index.js +2 -2
- package/dist/{interpreter-JTOTDC46.js → interpreter-X7EARER5.js} +1 -1
- package/dist/test-runner.js +1 -1
- package/package.json +1 -1
- package/src/tags/defvar.ts +4 -3
- package/src/tags/output.ts +33 -3
- package/tests/generate-dirac.test.di +22 -0
- package/tests/output-file.test.di +19 -0
|
@@ -138,7 +138,7 @@ function serializeToXml(children) {
|
|
|
138
138
|
xml += " />";
|
|
139
139
|
} else {
|
|
140
140
|
xml += ">";
|
|
141
|
-
if (child.text) {
|
|
141
|
+
if (child.text && child.children.length === 0) {
|
|
142
142
|
xml += escapeXml(child.text);
|
|
143
143
|
}
|
|
144
144
|
if (child.children.length > 0) {
|
|
@@ -196,7 +196,29 @@ function executeAssign(session, element) {
|
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
// src/tags/output.ts
|
|
199
|
+
import * as fs from "fs";
|
|
200
|
+
import * as path from "path";
|
|
199
201
|
async function executeOutput(session, element) {
|
|
202
|
+
const fileAttr = element.attributes?.file;
|
|
203
|
+
const filePath = fileAttr ? substituteAttribute(session, fileAttr) : null;
|
|
204
|
+
if (filePath) {
|
|
205
|
+
let content = "";
|
|
206
|
+
if (element.children && element.children.length > 0) {
|
|
207
|
+
const prevOutput = session.output;
|
|
208
|
+
session.output = [];
|
|
209
|
+
await integrateChildren(session, element);
|
|
210
|
+
content = session.output.join("");
|
|
211
|
+
session.output = prevOutput;
|
|
212
|
+
} else if (element.text) {
|
|
213
|
+
content = substituteVariables(session, element.text);
|
|
214
|
+
}
|
|
215
|
+
const dir = path.dirname(filePath);
|
|
216
|
+
if (dir !== "." && !fs.existsSync(dir)) {
|
|
217
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
218
|
+
}
|
|
219
|
+
fs.appendFileSync(filePath, content + "\n", "utf8");
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
200
222
|
if (element.children && element.children.length > 0) {
|
|
201
223
|
await integrateChildren(session, element);
|
|
202
224
|
return;
|
|
@@ -397,12 +419,12 @@ async function executeIf(session, element) {
|
|
|
397
419
|
const condition = await evaluatePredicate(session, conditionElement);
|
|
398
420
|
if (condition) {
|
|
399
421
|
if (thenElement) {
|
|
400
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
422
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
|
|
401
423
|
await integrateChildren2(session, thenElement);
|
|
402
424
|
}
|
|
403
425
|
} else {
|
|
404
426
|
if (elseElement) {
|
|
405
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
427
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
|
|
406
428
|
await integrateChildren2(session, elseElement);
|
|
407
429
|
}
|
|
408
430
|
}
|
|
@@ -415,7 +437,7 @@ async function evaluatePredicate(session, predicateElement) {
|
|
|
415
437
|
return await evaluateCondition(session, predicateElement);
|
|
416
438
|
}
|
|
417
439
|
const outputLengthBefore = session.output.length;
|
|
418
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
440
|
+
const { integrate: integrate2 } = await import("./interpreter-X7EARER5.js");
|
|
419
441
|
await integrate2(session, predicateElement);
|
|
420
442
|
const newOutputChunks = session.output.slice(outputLengthBefore);
|
|
421
443
|
const result = newOutputChunks.join("").trim();
|
|
@@ -438,11 +460,11 @@ async function evaluateCondition(session, condElement) {
|
|
|
438
460
|
}
|
|
439
461
|
const outputLengthBefore = session.output.length;
|
|
440
462
|
const args = [];
|
|
441
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
463
|
+
const { integrate: integrate2 } = await import("./interpreter-X7EARER5.js");
|
|
442
464
|
for (const child of condElement.children) {
|
|
443
465
|
if (child.tag.toLowerCase() === "arg") {
|
|
444
466
|
const argOutputStart = session.output.length;
|
|
445
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
467
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
|
|
446
468
|
await integrateChildren2(session, child);
|
|
447
469
|
const newChunks = session.output.slice(argOutputStart);
|
|
448
470
|
const argValue = newChunks.join("");
|
|
@@ -857,11 +879,11 @@ ${expr}
|
|
|
857
879
|
for (const v of session.variables) {
|
|
858
880
|
context[v.name] = v.value;
|
|
859
881
|
}
|
|
860
|
-
const { default:
|
|
861
|
-
const { default:
|
|
882
|
+
const { default: fs3 } = await import("fs");
|
|
883
|
+
const { default: path2 } = await import("path");
|
|
862
884
|
const { fileURLToPath } = await import("url");
|
|
863
|
-
context.fs =
|
|
864
|
-
context.path =
|
|
885
|
+
context.fs = fs3;
|
|
886
|
+
context.path = path2;
|
|
865
887
|
context.__dirname = process.cwd();
|
|
866
888
|
context.getParams = () => {
|
|
867
889
|
const params = session.parameterStack[session.parameterStack.length - 1];
|
|
@@ -915,13 +937,13 @@ ${diracCode}
|
|
|
915
937
|
|
|
916
938
|
// src/tags/import.ts
|
|
917
939
|
import { readFileSync } from "fs";
|
|
918
|
-
import { resolve, dirname } from "path";
|
|
940
|
+
import { resolve, dirname as dirname2 } from "path";
|
|
919
941
|
async function executeImport(session, element) {
|
|
920
942
|
const src = element.attributes.src;
|
|
921
943
|
if (!src) {
|
|
922
944
|
throw new Error("<import> requires src attribute");
|
|
923
945
|
}
|
|
924
|
-
const currentDir = session.currentFile ?
|
|
946
|
+
const currentDir = session.currentFile ? dirname2(session.currentFile) : process.cwd();
|
|
925
947
|
const importPath = resolve(currentDir, src);
|
|
926
948
|
if (session.debug) {
|
|
927
949
|
console.error(`[IMPORT] Loading: ${importPath}`);
|
|
@@ -1103,13 +1125,13 @@ async function executeRequireModule(session, element) {
|
|
|
1103
1125
|
}
|
|
1104
1126
|
|
|
1105
1127
|
// src/tags/tag-check.ts
|
|
1106
|
-
import
|
|
1128
|
+
import fs2 from "fs";
|
|
1107
1129
|
import yaml from "js-yaml";
|
|
1108
1130
|
var SIMILARITY_CUTOFF = 0.75;
|
|
1109
1131
|
function getEmbeddingServerConfig() {
|
|
1110
1132
|
try {
|
|
1111
1133
|
const configPath = process.env.DIRAC_CONFIG || "config.yml";
|
|
1112
|
-
const config = yaml.load(
|
|
1134
|
+
const config = yaml.load(fs2.readFileSync(configPath, "utf8"));
|
|
1113
1135
|
const host = config.embeddingServer?.host || "localhost";
|
|
1114
1136
|
const port = config.embeddingServer?.port || 11434;
|
|
1115
1137
|
const model = config.embeddingServer?.model || "embeddinggemma";
|
|
@@ -1245,7 +1267,7 @@ async function executeTagCheck(session, element) {
|
|
|
1245
1267
|
const executeTag = correctedTag || tagName;
|
|
1246
1268
|
console.error(`[tag-check] Executing <${executeTag}/> as all checks passed and execute=true.`);
|
|
1247
1269
|
const elementToExecute = correctedTag ? { ...child, tag: correctedTag } : child;
|
|
1248
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
1270
|
+
const { integrate: integrate2 } = await import("./interpreter-X7EARER5.js");
|
|
1249
1271
|
await integrate2(session, elementToExecute);
|
|
1250
1272
|
}
|
|
1251
1273
|
}
|
|
@@ -1254,7 +1276,7 @@ async function executeTagCheck(session, element) {
|
|
|
1254
1276
|
// src/tags/throw.ts
|
|
1255
1277
|
async function executeThrow(session, element) {
|
|
1256
1278
|
const exceptionName = element.attributes?.name || "exception";
|
|
1257
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1279
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
|
|
1258
1280
|
const exceptionDom = {
|
|
1259
1281
|
tag: "exception-content",
|
|
1260
1282
|
attributes: { name: exceptionName },
|
|
@@ -1267,7 +1289,7 @@ async function executeThrow(session, element) {
|
|
|
1267
1289
|
// src/tags/try.ts
|
|
1268
1290
|
async function executeTry(session, element) {
|
|
1269
1291
|
setExceptionBoundary(session);
|
|
1270
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1292
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
|
|
1271
1293
|
await integrateChildren2(session, element);
|
|
1272
1294
|
unsetExceptionBoundary(session);
|
|
1273
1295
|
}
|
|
@@ -1277,7 +1299,7 @@ async function executeCatch(session, element) {
|
|
|
1277
1299
|
const exceptionName = element.attributes?.name || "exception";
|
|
1278
1300
|
const caughtCount = lookupException(session, exceptionName);
|
|
1279
1301
|
if (caughtCount > 0) {
|
|
1280
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1302
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
|
|
1281
1303
|
await integrateChildren2(session, element);
|
|
1282
1304
|
}
|
|
1283
1305
|
flushCurrentException(session);
|
|
@@ -1286,7 +1308,7 @@ async function executeCatch(session, element) {
|
|
|
1286
1308
|
// src/tags/exception.ts
|
|
1287
1309
|
async function executeException(session, element) {
|
|
1288
1310
|
const exceptions = getCurrentExceptions(session);
|
|
1289
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1311
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
|
|
1290
1312
|
for (const exceptionDom of exceptions) {
|
|
1291
1313
|
await integrateChildren2(session, exceptionDom);
|
|
1292
1314
|
}
|
|
@@ -1426,7 +1448,7 @@ async function executeForeach(session, element) {
|
|
|
1426
1448
|
const parser2 = new DiracParser2();
|
|
1427
1449
|
try {
|
|
1428
1450
|
const fromElement = parser2.parse(fromAttr);
|
|
1429
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
1451
|
+
const { integrate: integrate2 } = await import("./interpreter-X7EARER5.js");
|
|
1430
1452
|
await integrate2(session, fromElement);
|
|
1431
1453
|
} catch (e) {
|
|
1432
1454
|
session.output = savedOutput;
|
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
execute
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-VA7VOLNV.js";
|
|
5
|
+
import "./chunk-UXTK2GC2.js";
|
|
6
6
|
import "./chunk-HRHAMPOB.js";
|
|
7
7
|
import "./chunk-E7PWEMZA.js";
|
|
8
8
|
import "./chunk-52ED23DR.js";
|
|
@@ -13,7 +13,7 @@ import "dotenv/config";
|
|
|
13
13
|
// package.json
|
|
14
14
|
var package_default = {
|
|
15
15
|
name: "dirac-lang",
|
|
16
|
-
version: "0.1.
|
|
16
|
+
version: "0.1.20",
|
|
17
17
|
description: "LLM-Augmented Declarative Execution",
|
|
18
18
|
type: "module",
|
|
19
19
|
main: "dist/index.js",
|
package/dist/index.js
CHANGED
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
createLLMAdapter,
|
|
3
3
|
execute,
|
|
4
4
|
executeUserCommand
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-VA7VOLNV.js";
|
|
6
6
|
import {
|
|
7
7
|
integrate
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-UXTK2GC2.js";
|
|
9
9
|
import {
|
|
10
10
|
DiracParser
|
|
11
11
|
} from "./chunk-HRHAMPOB.js";
|
package/dist/test-runner.js
CHANGED
package/package.json
CHANGED
package/src/tags/defvar.ts
CHANGED
|
@@ -86,12 +86,13 @@ function serializeToXml(children: DiracElement[]): string {
|
|
|
86
86
|
} else {
|
|
87
87
|
xml += '>';
|
|
88
88
|
|
|
89
|
-
//
|
|
90
|
-
if
|
|
89
|
+
// Only add text content if there are no children
|
|
90
|
+
// (if there are children, text is stored in text node children)
|
|
91
|
+
if (child.text && child.children.length === 0) {
|
|
91
92
|
xml += escapeXml(child.text);
|
|
92
93
|
}
|
|
93
94
|
|
|
94
|
-
// Add children
|
|
95
|
+
// Add children (which may include text nodes)
|
|
95
96
|
if (child.children.length > 0) {
|
|
96
97
|
xml += serializeToXml(child.children);
|
|
97
98
|
}
|
package/src/tags/output.ts
CHANGED
|
@@ -4,17 +4,47 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { DiracSession, DiracElement } from '../types/index.js';
|
|
7
|
-
import { emit, substituteVariables } from '../runtime/session.js';
|
|
7
|
+
import { emit, substituteVariables, substituteAttribute } from '../runtime/session.js';
|
|
8
8
|
import { integrateChildren } from '../runtime/interpreter.js';
|
|
9
|
+
import * as fs from 'fs';
|
|
10
|
+
import * as path from 'path';
|
|
9
11
|
|
|
10
12
|
export async function executeOutput(session: DiracSession, element: DiracElement): Promise<void> {
|
|
11
|
-
|
|
13
|
+
const fileAttr = element.attributes?.file;
|
|
14
|
+
const filePath = fileAttr ? substituteAttribute(session, fileAttr) : null;
|
|
15
|
+
|
|
16
|
+
// If writing to a file, collect content first
|
|
17
|
+
if (filePath) {
|
|
18
|
+
let content = '';
|
|
19
|
+
|
|
20
|
+
if (element.children && element.children.length > 0) {
|
|
21
|
+
// Capture output from children
|
|
22
|
+
const prevOutput = session.output;
|
|
23
|
+
session.output = [];
|
|
24
|
+
await integrateChildren(session, element);
|
|
25
|
+
content = session.output.join('');
|
|
26
|
+
session.output = prevOutput;
|
|
27
|
+
} else if (element.text) {
|
|
28
|
+
content = substituteVariables(session, element.text);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Ensure directory exists
|
|
32
|
+
const dir = path.dirname(filePath);
|
|
33
|
+
if (dir !== '.' && !fs.existsSync(dir)) {
|
|
34
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Append to file
|
|
38
|
+
fs.appendFileSync(filePath, content + '\n', 'utf8');
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Normal output to stdout
|
|
12
43
|
if (element.children && element.children.length > 0) {
|
|
13
44
|
await integrateChildren(session, element);
|
|
14
45
|
return;
|
|
15
46
|
}
|
|
16
47
|
|
|
17
|
-
// If only text content, use it (with variable substitution)
|
|
18
48
|
if (element.text) {
|
|
19
49
|
const content = substituteVariables(session, element.text);
|
|
20
50
|
emit(session, content);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<!-- TEST: generate_and_execute_dirac -->
|
|
2
|
+
<!-- EXPECT: Generated file executed
|
|
3
|
+
Result: 42 -->
|
|
4
|
+
<dirac>
|
|
5
|
+
<!-- Define a DIRAC script as literal -->
|
|
6
|
+
<defvar name="generated_script" literal="true" trim="false">
|
|
7
|
+
<dirac>
|
|
8
|
+
<defvar name="value">42</defvar>
|
|
9
|
+
<output>Result: <variable name="value" /></output>
|
|
10
|
+
</dirac>
|
|
11
|
+
</defvar>
|
|
12
|
+
|
|
13
|
+
<!-- Write to file -->
|
|
14
|
+
<output file="temp-generated.di"><variable name="generated_script" /></output>
|
|
15
|
+
|
|
16
|
+
<!-- Execute the generated script -->
|
|
17
|
+
<output>Generated file executed</output>
|
|
18
|
+
<system shell="bash">
|
|
19
|
+
node dist/cli.js temp-generated.di
|
|
20
|
+
rm temp-generated.di
|
|
21
|
+
</system>
|
|
22
|
+
</dirac>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<!-- TEST: output_file_basic -->
|
|
2
|
+
<!-- EXPECT: stdout output
|
|
3
|
+
File written -->
|
|
4
|
+
<dirac>
|
|
5
|
+
<!-- Write to file -->
|
|
6
|
+
<output file="output-test-temp.txt">File line 1</output>
|
|
7
|
+
<output file="output-test-temp.txt">File line 2</output>
|
|
8
|
+
|
|
9
|
+
<!-- Output to stdout to verify test runs -->
|
|
10
|
+
<output>stdout output</output>
|
|
11
|
+
|
|
12
|
+
<!-- Use system to verify file and clean up -->
|
|
13
|
+
<system shell="bash">
|
|
14
|
+
if [ -f output-test-temp.txt ]; then
|
|
15
|
+
echo "File written"
|
|
16
|
+
rm output-test-temp.txt
|
|
17
|
+
fi
|
|
18
|
+
</system>
|
|
19
|
+
</dirac>
|