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.
@@ -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-JTOTDC46.js");
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-JTOTDC46.js");
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-JTOTDC46.js");
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-JTOTDC46.js");
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-JTOTDC46.js");
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: fs2 } = await import("fs");
861
- const { default: path } = await import("path");
882
+ const { default: fs3 } = await import("fs");
883
+ const { default: path2 } = await import("path");
862
884
  const { fileURLToPath } = await import("url");
863
- context.fs = fs2;
864
- context.path = 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 ? dirname(session.currentFile) : process.cwd();
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 fs from "fs";
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(fs.readFileSync(configPath, "utf8"));
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-JTOTDC46.js");
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-JTOTDC46.js");
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-JTOTDC46.js");
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-JTOTDC46.js");
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-JTOTDC46.js");
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-JTOTDC46.js");
1451
+ const { integrate: integrate2 } = await import("./interpreter-X7EARER5.js");
1430
1452
  await integrate2(session, fromElement);
1431
1453
  } catch (e) {
1432
1454
  session.output = savedOutput;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  integrate
3
- } from "./chunk-GR6KWGCI.js";
3
+ } from "./chunk-UXTK2GC2.js";
4
4
  import {
5
5
  DiracParser
6
6
  } from "./chunk-HRHAMPOB.js";
package/dist/cli.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  execute
4
- } from "./chunk-QMFCOZ5D.js";
5
- import "./chunk-GR6KWGCI.js";
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.19",
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-QMFCOZ5D.js";
5
+ } from "./chunk-VA7VOLNV.js";
6
6
  import {
7
7
  integrate
8
- } from "./chunk-GR6KWGCI.js";
8
+ } from "./chunk-UXTK2GC2.js";
9
9
  import {
10
10
  DiracParser
11
11
  } from "./chunk-HRHAMPOB.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  integrate,
3
3
  integrateChildren
4
- } from "./chunk-GR6KWGCI.js";
4
+ } from "./chunk-UXTK2GC2.js";
5
5
  import "./chunk-HRHAMPOB.js";
6
6
  import "./chunk-E7PWEMZA.js";
7
7
  import "./chunk-52ED23DR.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  integrate
3
- } from "./chunk-GR6KWGCI.js";
3
+ } from "./chunk-UXTK2GC2.js";
4
4
  import {
5
5
  DiracParser
6
6
  } from "./chunk-HRHAMPOB.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dirac-lang",
3
- "version": "0.1.19",
3
+ "version": "0.1.20",
4
4
  "description": "LLM-Augmented Declarative Execution",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -86,12 +86,13 @@ function serializeToXml(children: DiracElement[]): string {
86
86
  } else {
87
87
  xml += '>';
88
88
 
89
- // Add text content if present
90
- if (child.text) {
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
  }
@@ -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
- // If has children, process them (handles mixed content)
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>