dirac-lang 0.1.18 → 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.
@@ -85,7 +85,8 @@ async function executeDefvar(session, element) {
85
85
  const valueAttr = element.attributes.value;
86
86
  const visibleAttr = element.attributes.visible || "false";
87
87
  const literal = "literal" in element.attributes;
88
- const trim = "trim" in element.attributes;
88
+ const trimAttr = element.attributes.trim;
89
+ const trim = trimAttr !== "false";
89
90
  if (!name) {
90
91
  throw new Error("<defvar> requires name attribute");
91
92
  }
@@ -137,7 +138,7 @@ function serializeToXml(children) {
137
138
  xml += " />";
138
139
  } else {
139
140
  xml += ">";
140
- if (child.text) {
141
+ if (child.text && child.children.length === 0) {
141
142
  xml += escapeXml(child.text);
142
143
  }
143
144
  if (child.children.length > 0) {
@@ -195,7 +196,29 @@ function executeAssign(session, element) {
195
196
  }
196
197
 
197
198
  // src/tags/output.ts
199
+ import * as fs from "fs";
200
+ import * as path from "path";
198
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
+ }
199
222
  if (element.children && element.children.length > 0) {
200
223
  await integrateChildren(session, element);
201
224
  return;
@@ -396,12 +419,12 @@ async function executeIf(session, element) {
396
419
  const condition = await evaluatePredicate(session, conditionElement);
397
420
  if (condition) {
398
421
  if (thenElement) {
399
- const { integrateChildren: integrateChildren2 } = await import("./interpreter-MCDR5L7R.js");
422
+ const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
400
423
  await integrateChildren2(session, thenElement);
401
424
  }
402
425
  } else {
403
426
  if (elseElement) {
404
- const { integrateChildren: integrateChildren2 } = await import("./interpreter-MCDR5L7R.js");
427
+ const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
405
428
  await integrateChildren2(session, elseElement);
406
429
  }
407
430
  }
@@ -414,7 +437,7 @@ async function evaluatePredicate(session, predicateElement) {
414
437
  return await evaluateCondition(session, predicateElement);
415
438
  }
416
439
  const outputLengthBefore = session.output.length;
417
- const { integrate: integrate2 } = await import("./interpreter-MCDR5L7R.js");
440
+ const { integrate: integrate2 } = await import("./interpreter-X7EARER5.js");
418
441
  await integrate2(session, predicateElement);
419
442
  const newOutputChunks = session.output.slice(outputLengthBefore);
420
443
  const result = newOutputChunks.join("").trim();
@@ -437,11 +460,11 @@ async function evaluateCondition(session, condElement) {
437
460
  }
438
461
  const outputLengthBefore = session.output.length;
439
462
  const args = [];
440
- const { integrate: integrate2 } = await import("./interpreter-MCDR5L7R.js");
463
+ const { integrate: integrate2 } = await import("./interpreter-X7EARER5.js");
441
464
  for (const child of condElement.children) {
442
465
  if (child.tag.toLowerCase() === "arg") {
443
466
  const argOutputStart = session.output.length;
444
- const { integrateChildren: integrateChildren2 } = await import("./interpreter-MCDR5L7R.js");
467
+ const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
445
468
  await integrateChildren2(session, child);
446
469
  const newChunks = session.output.slice(argOutputStart);
447
470
  const argValue = newChunks.join("");
@@ -856,11 +879,11 @@ ${expr}
856
879
  for (const v of session.variables) {
857
880
  context[v.name] = v.value;
858
881
  }
859
- const { default: fs2 } = await import("fs");
860
- const { default: path } = await import("path");
882
+ const { default: fs3 } = await import("fs");
883
+ const { default: path2 } = await import("path");
861
884
  const { fileURLToPath } = await import("url");
862
- context.fs = fs2;
863
- context.path = path;
885
+ context.fs = fs3;
886
+ context.path = path2;
864
887
  context.__dirname = process.cwd();
865
888
  context.getParams = () => {
866
889
  const params = session.parameterStack[session.parameterStack.length - 1];
@@ -914,13 +937,13 @@ ${diracCode}
914
937
 
915
938
  // src/tags/import.ts
916
939
  import { readFileSync } from "fs";
917
- import { resolve, dirname } from "path";
940
+ import { resolve, dirname as dirname2 } from "path";
918
941
  async function executeImport(session, element) {
919
942
  const src = element.attributes.src;
920
943
  if (!src) {
921
944
  throw new Error("<import> requires src attribute");
922
945
  }
923
- const currentDir = session.currentFile ? dirname(session.currentFile) : process.cwd();
946
+ const currentDir = session.currentFile ? dirname2(session.currentFile) : process.cwd();
924
947
  const importPath = resolve(currentDir, src);
925
948
  if (session.debug) {
926
949
  console.error(`[IMPORT] Loading: ${importPath}`);
@@ -1102,13 +1125,13 @@ async function executeRequireModule(session, element) {
1102
1125
  }
1103
1126
 
1104
1127
  // src/tags/tag-check.ts
1105
- import fs from "fs";
1128
+ import fs2 from "fs";
1106
1129
  import yaml from "js-yaml";
1107
1130
  var SIMILARITY_CUTOFF = 0.75;
1108
1131
  function getEmbeddingServerConfig() {
1109
1132
  try {
1110
1133
  const configPath = process.env.DIRAC_CONFIG || "config.yml";
1111
- const config = yaml.load(fs.readFileSync(configPath, "utf8"));
1134
+ const config = yaml.load(fs2.readFileSync(configPath, "utf8"));
1112
1135
  const host = config.embeddingServer?.host || "localhost";
1113
1136
  const port = config.embeddingServer?.port || 11434;
1114
1137
  const model = config.embeddingServer?.model || "embeddinggemma";
@@ -1244,7 +1267,7 @@ async function executeTagCheck(session, element) {
1244
1267
  const executeTag = correctedTag || tagName;
1245
1268
  console.error(`[tag-check] Executing <${executeTag}/> as all checks passed and execute=true.`);
1246
1269
  const elementToExecute = correctedTag ? { ...child, tag: correctedTag } : child;
1247
- const { integrate: integrate2 } = await import("./interpreter-MCDR5L7R.js");
1270
+ const { integrate: integrate2 } = await import("./interpreter-X7EARER5.js");
1248
1271
  await integrate2(session, elementToExecute);
1249
1272
  }
1250
1273
  }
@@ -1253,7 +1276,7 @@ async function executeTagCheck(session, element) {
1253
1276
  // src/tags/throw.ts
1254
1277
  async function executeThrow(session, element) {
1255
1278
  const exceptionName = element.attributes?.name || "exception";
1256
- const { integrateChildren: integrateChildren2 } = await import("./interpreter-MCDR5L7R.js");
1279
+ const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
1257
1280
  const exceptionDom = {
1258
1281
  tag: "exception-content",
1259
1282
  attributes: { name: exceptionName },
@@ -1266,7 +1289,7 @@ async function executeThrow(session, element) {
1266
1289
  // src/tags/try.ts
1267
1290
  async function executeTry(session, element) {
1268
1291
  setExceptionBoundary(session);
1269
- const { integrateChildren: integrateChildren2 } = await import("./interpreter-MCDR5L7R.js");
1292
+ const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
1270
1293
  await integrateChildren2(session, element);
1271
1294
  unsetExceptionBoundary(session);
1272
1295
  }
@@ -1276,7 +1299,7 @@ async function executeCatch(session, element) {
1276
1299
  const exceptionName = element.attributes?.name || "exception";
1277
1300
  const caughtCount = lookupException(session, exceptionName);
1278
1301
  if (caughtCount > 0) {
1279
- const { integrateChildren: integrateChildren2 } = await import("./interpreter-MCDR5L7R.js");
1302
+ const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
1280
1303
  await integrateChildren2(session, element);
1281
1304
  }
1282
1305
  flushCurrentException(session);
@@ -1285,7 +1308,7 @@ async function executeCatch(session, element) {
1285
1308
  // src/tags/exception.ts
1286
1309
  async function executeException(session, element) {
1287
1310
  const exceptions = getCurrentExceptions(session);
1288
- const { integrateChildren: integrateChildren2 } = await import("./interpreter-MCDR5L7R.js");
1311
+ const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
1289
1312
  for (const exceptionDom of exceptions) {
1290
1313
  await integrateChildren2(session, exceptionDom);
1291
1314
  }
@@ -1425,7 +1448,7 @@ async function executeForeach(session, element) {
1425
1448
  const parser2 = new DiracParser2();
1426
1449
  try {
1427
1450
  const fromElement = parser2.parse(fromAttr);
1428
- const { integrate: integrate2 } = await import("./interpreter-MCDR5L7R.js");
1451
+ const { integrate: integrate2 } = await import("./interpreter-X7EARER5.js");
1429
1452
  await integrate2(session, fromElement);
1430
1453
  } catch (e) {
1431
1454
  session.output = savedOutput;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  integrate
3
- } from "./chunk-VZEKPMWN.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-E2MR7FMI.js";
5
- import "./chunk-VZEKPMWN.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.18",
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-E2MR7FMI.js";
5
+ } from "./chunk-VA7VOLNV.js";
6
6
  import {
7
7
  integrate
8
- } from "./chunk-VZEKPMWN.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-VZEKPMWN.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-VZEKPMWN.js";
3
+ } from "./chunk-UXTK2GC2.js";
4
4
  import {
5
5
  DiracParser
6
6
  } from "./chunk-HRHAMPOB.js";
@@ -18,9 +18,9 @@
18
18
  <output></output>
19
19
 
20
20
  <!-- Define variables in main scope -->
21
- <defvar name="x" trim="true">value-x</defvar>
22
- <defvar name="y" trim="true">value-y</defvar>
23
- <defvar name="z" trim="true">value-z</defvar>
21
+ <defvar name="x">value-x</defvar>
22
+ <defvar name="y">value-y</defvar>
23
+ <defvar name="z">value-z</defvar>
24
24
 
25
25
  <output>Variables defined in main scope:</output>
26
26
  <output> x = <variable name="x" /></output>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dirac-lang",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "description": "LLM-Augmented Declarative Execution",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -14,7 +14,8 @@ export async function executeDefvar(session: DiracSession, element: DiracElement
14
14
  const valueAttr = element.attributes.value;
15
15
  const visibleAttr = element.attributes.visible || 'false';
16
16
  const literal = 'literal' in element.attributes;
17
- const trim = 'trim' in element.attributes; // Support trim attribute to remove leading/trailing whitespace
17
+ const trimAttr = element.attributes.trim;
18
+ const trim = trimAttr !== 'false'; // Trim by default unless explicitly set to false
18
19
 
19
20
  if (!name) {
20
21
  throw new Error('<defvar> requires name attribute');
@@ -85,12 +86,13 @@ function serializeToXml(children: DiracElement[]): string {
85
86
  } else {
86
87
  xml += '>';
87
88
 
88
- // Add text content if present
89
- 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) {
90
92
  xml += escapeXml(child.text);
91
93
  }
92
94
 
93
- // Add children
95
+ // Add children (which may include text nodes)
94
96
  if (child.children.length > 0) {
95
97
  xml += serializeToXml(child.children);
96
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>
@@ -18,9 +18,9 @@ main after outer: a=x b=y c=z -->
18
18
  </subroutine>
19
19
 
20
20
  <!-- Define main scope variables -->
21
- <defvar name="a" trim="true">x</defvar>
22
- <defvar name="b" trim="true">y</defvar>
23
- <defvar name="c" trim="true">z</defvar>
21
+ <defvar name="a">x</defvar>
22
+ <defvar name="b">y</defvar>
23
+ <defvar name="c">z</defvar>
24
24
 
25
25
  <output>main: a=<variable name="a" /> b=<variable name="b" /> c=<variable name="c" /></output>
26
26
 
@@ -15,9 +15,9 @@ x=a y=b z=c -->
15
15
  </subroutine>
16
16
 
17
17
  <!-- Define main scope variables -->
18
- <defvar name="x" trim="true">a</defvar>
19
- <defvar name="y" trim="true">b</defvar>
20
- <defvar name="z" trim="true">c</defvar>
18
+ <defvar name="x">a</defvar>
19
+ <defvar name="y">b</defvar>
20
+ <defvar name="z">c</defvar>
21
21
 
22
22
  <!-- Verify initial state -->
23
23
  <output>x=<variable name="x" /> y=<variable name="y" /> z=<variable name="z" /></output>
@@ -18,7 +18,7 @@ Color changed to: red -->
18
18
  </subroutine>
19
19
 
20
20
  <!-- Test: tag-check should auto-correct similar tag names and execute -->
21
- <defvar name="result" trim="true">
21
+ <defvar name="result">
22
22
  <tag-check execute="true" autocorrect="true">
23
23
  <background-set color="red" />
24
24
  </tag-check>
package/test-eval.di DELETED
@@ -1,4 +0,0 @@
1
- <dirac>
2
- <eval name="test">"hello"</eval>
3
- <output>test=$test</output>
4
- </dirac>