dirac-lang 0.1.37 → 0.1.39

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.
@@ -9,6 +9,7 @@ import {
9
9
  cleanToBoundary,
10
10
  emit,
11
11
  flushCurrentException,
12
+ getAvailableSubroutines,
12
13
  getCurrentExceptions,
13
14
  getCurrentParameters,
14
15
  getParentSubroutine,
@@ -447,12 +448,12 @@ async function executeIf(session, element) {
447
448
  const condition = await evaluatePredicate(session, conditionElement);
448
449
  if (condition) {
449
450
  if (thenElement) {
450
- const { integrateChildren: integrateChildren2 } = await import("./interpreter-GLWAQHAW.js");
451
+ const { integrateChildren: integrateChildren2 } = await import("./interpreter-UCWBT6KP.js");
451
452
  await integrateChildren2(session, thenElement);
452
453
  }
453
454
  } else {
454
455
  if (elseElement) {
455
- const { integrateChildren: integrateChildren2 } = await import("./interpreter-GLWAQHAW.js");
456
+ const { integrateChildren: integrateChildren2 } = await import("./interpreter-UCWBT6KP.js");
456
457
  await integrateChildren2(session, elseElement);
457
458
  }
458
459
  }
@@ -465,7 +466,7 @@ async function evaluatePredicate(session, predicateElement) {
465
466
  return await evaluateCondition(session, predicateElement);
466
467
  }
467
468
  const outputLengthBefore = session.output.length;
468
- const { integrate: integrate2 } = await import("./interpreter-GLWAQHAW.js");
469
+ const { integrate: integrate2 } = await import("./interpreter-UCWBT6KP.js");
469
470
  await integrate2(session, predicateElement);
470
471
  const newOutputChunks = session.output.slice(outputLengthBefore);
471
472
  const result = newOutputChunks.join("").trim();
@@ -488,11 +489,11 @@ async function evaluateCondition(session, condElement) {
488
489
  }
489
490
  const outputLengthBefore = session.output.length;
490
491
  const args = [];
491
- const { integrate: integrate2 } = await import("./interpreter-GLWAQHAW.js");
492
+ const { integrate: integrate2 } = await import("./interpreter-UCWBT6KP.js");
492
493
  for (const child of condElement.children) {
493
494
  if (child.tag.toLowerCase() === "arg") {
494
495
  const argOutputStart = session.output.length;
495
- const { integrateChildren: integrateChildren2 } = await import("./interpreter-GLWAQHAW.js");
496
+ const { integrateChildren: integrateChildren2 } = await import("./interpreter-UCWBT6KP.js");
496
497
  await integrateChildren2(session, child);
497
498
  const newChunks = session.output.slice(argOutputStart);
498
499
  const argValue = newChunks.join("");
@@ -602,8 +603,8 @@ async function executeLLM(session, element) {
602
603
  console.error("[LLM] Full prompt sent to LLM (noextra):\n" + prompt + "\n");
603
604
  }
604
605
  } else {
605
- const { getAvailableSubroutines } = await import("./session-UBATJEND.js");
606
- const subroutines = getAvailableSubroutines(session);
606
+ const { getAvailableSubroutines: getAvailableSubroutines2 } = await import("./session-UBATJEND.js");
607
+ const subroutines = getAvailableSubroutines2(session);
607
608
  if (session.debug) {
608
609
  console.error(
609
610
  "[LLM] Subroutines available at prompt composition:",
@@ -932,11 +933,11 @@ ${expr}
932
933
  for (const v of session.variables) {
933
934
  context[v.name] = v.value;
934
935
  }
935
- const { default: fs4 } = await import("fs");
936
- const { default: path2 } = await import("path");
936
+ const { default: fs5 } = await import("fs");
937
+ const { default: path3 } = await import("path");
937
938
  const { fileURLToPath } = await import("url");
938
- context.fs = fs4;
939
- context.path = path2;
939
+ context.fs = fs5;
940
+ context.path = path3;
940
941
  context.__dirname = process.cwd();
941
942
  context.getParams = () => {
942
943
  const params = session.parameterStack[session.parameterStack.length - 1];
@@ -1284,8 +1285,8 @@ async function getBestTagMatch(candidate, allowed) {
1284
1285
  return { tag: allowed[bestIdx], score: bestScore };
1285
1286
  }
1286
1287
  async function executeTagCheck(session, element) {
1287
- const { getAvailableSubroutines } = await import("./session-UBATJEND.js");
1288
- const subroutines = getAvailableSubroutines(session);
1288
+ const { getAvailableSubroutines: getAvailableSubroutines2 } = await import("./session-UBATJEND.js");
1289
+ const subroutines = getAvailableSubroutines2(session);
1289
1290
  const allowed = new Set(subroutines.map((s) => s.name));
1290
1291
  console.error("[tag-check] Allowed subroutines:", Array.from(allowed));
1291
1292
  const autocorrect = element.attributes?.autocorrect === "true";
@@ -1377,7 +1378,7 @@ async function executeTagCheck(session, element) {
1377
1378
  const executeTag = correctedTag || tagName;
1378
1379
  console.error(`[tag-check] Executing <${executeTag}/> as all checks passed and execute=true.`);
1379
1380
  const elementToExecute = correctedTag ? { ...child, tag: correctedTag } : child;
1380
- const { integrate: integrate2 } = await import("./interpreter-GLWAQHAW.js");
1381
+ const { integrate: integrate2 } = await import("./interpreter-UCWBT6KP.js");
1381
1382
  await integrate2(session, elementToExecute);
1382
1383
  }
1383
1384
  }
@@ -1386,7 +1387,7 @@ async function executeTagCheck(session, element) {
1386
1387
  // src/tags/throw.ts
1387
1388
  async function executeThrow(session, element) {
1388
1389
  const exceptionName = element.attributes?.name || "exception";
1389
- const { integrateChildren: integrateChildren2 } = await import("./interpreter-GLWAQHAW.js");
1390
+ const { integrateChildren: integrateChildren2 } = await import("./interpreter-UCWBT6KP.js");
1390
1391
  const exceptionDom = {
1391
1392
  tag: "exception-content",
1392
1393
  attributes: { name: exceptionName },
@@ -1399,7 +1400,7 @@ async function executeThrow(session, element) {
1399
1400
  // src/tags/try.ts
1400
1401
  async function executeTry(session, element) {
1401
1402
  setExceptionBoundary(session);
1402
- const { integrateChildren: integrateChildren2 } = await import("./interpreter-GLWAQHAW.js");
1403
+ const { integrateChildren: integrateChildren2 } = await import("./interpreter-UCWBT6KP.js");
1403
1404
  await integrateChildren2(session, element);
1404
1405
  unsetExceptionBoundary(session);
1405
1406
  }
@@ -1409,7 +1410,7 @@ async function executeCatch(session, element) {
1409
1410
  const exceptionName = element.attributes?.name || "exception";
1410
1411
  const caughtCount = lookupException(session, exceptionName);
1411
1412
  if (caughtCount > 0) {
1412
- const { integrateChildren: integrateChildren2 } = await import("./interpreter-GLWAQHAW.js");
1413
+ const { integrateChildren: integrateChildren2 } = await import("./interpreter-UCWBT6KP.js");
1413
1414
  await integrateChildren2(session, element);
1414
1415
  }
1415
1416
  flushCurrentException(session);
@@ -1418,7 +1419,7 @@ async function executeCatch(session, element) {
1418
1419
  // src/tags/exception.ts
1419
1420
  async function executeException(session, element) {
1420
1421
  const exceptions = getCurrentExceptions(session);
1421
- const { integrateChildren: integrateChildren2 } = await import("./interpreter-GLWAQHAW.js");
1422
+ const { integrateChildren: integrateChildren2 } = await import("./interpreter-UCWBT6KP.js");
1422
1423
  for (const exceptionDom of exceptions) {
1423
1424
  await integrateChildren2(session, exceptionDom);
1424
1425
  }
@@ -1538,6 +1539,423 @@ function escapeXml2(text) {
1538
1539
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
1539
1540
  }
1540
1541
 
1542
+ // src/tags/list-subroutines.ts
1543
+ async function executeListSubroutines(session, element) {
1544
+ const format = element.attributes.format || "text";
1545
+ const outputVar = element.attributes.output;
1546
+ const subroutines = getAvailableSubroutines(session);
1547
+ let output = "";
1548
+ switch (format) {
1549
+ case "braket":
1550
+ output = formatAsBraKet(subroutines);
1551
+ break;
1552
+ case "xml":
1553
+ output = formatAsXml(subroutines);
1554
+ break;
1555
+ case "json":
1556
+ output = JSON.stringify(subroutines, null, 2);
1557
+ break;
1558
+ case "text":
1559
+ default:
1560
+ output = formatAsText(subroutines);
1561
+ break;
1562
+ }
1563
+ if (outputVar) {
1564
+ setVariable(session, outputVar, output, false);
1565
+ } else {
1566
+ emit(session, output);
1567
+ }
1568
+ }
1569
+ function formatAsBraKet(subroutines) {
1570
+ const lines = ["Available subroutines:\n"];
1571
+ for (const sub of subroutines) {
1572
+ const params = sub.parameters?.map(
1573
+ (p) => `${p.name}=${p.type || "any"}`
1574
+ ).join(" ") || "";
1575
+ const braLine = params ? `<${sub.name} ${params}|` : `<${sub.name}|`;
1576
+ lines.push(braLine);
1577
+ if (sub.description) {
1578
+ lines.push(` ${sub.description}`);
1579
+ }
1580
+ lines.push("");
1581
+ }
1582
+ return lines.join("\n");
1583
+ }
1584
+ function formatAsXml(subroutines) {
1585
+ const lines = ["Available subroutines:\n"];
1586
+ for (const sub of subroutines) {
1587
+ const params = sub.parameters?.map(
1588
+ (p) => `param-${p.name}="${p.type || "any"}"`
1589
+ ).join(" ") || "";
1590
+ const xmlLine = params ? `<subroutine name="${sub.name}" ${params}/>` : `<subroutine name="${sub.name}"/>`;
1591
+ lines.push(xmlLine);
1592
+ if (sub.description) {
1593
+ lines.push(` <!-- ${sub.description} -->`);
1594
+ }
1595
+ lines.push("");
1596
+ }
1597
+ return lines.join("\n");
1598
+ }
1599
+ function formatAsText(subroutines) {
1600
+ const lines = ["Available subroutines:\n"];
1601
+ for (const sub of subroutines) {
1602
+ lines.push(`${sub.name}(`);
1603
+ if (sub.parameters && sub.parameters.length > 0) {
1604
+ for (const param of sub.parameters) {
1605
+ const required = param.required ? " [required]" : "";
1606
+ const desc = param.description ? ` - ${param.description}` : "";
1607
+ lines.push(` ${param.name}: ${param.type || "any"}${required}${desc}`);
1608
+ }
1609
+ }
1610
+ lines.push(`)${sub.description ? " - " + sub.description : ""}
1611
+ `);
1612
+ }
1613
+ return lines.join("\n");
1614
+ }
1615
+
1616
+ // src/runtime/subroutine-registry.ts
1617
+ import * as fs3 from "fs";
1618
+ import * as path2 from "path";
1619
+ import * as os from "os";
1620
+ var SubroutineRegistry = class {
1621
+ indexPath;
1622
+ index;
1623
+ constructor(indexPath) {
1624
+ this.indexPath = indexPath || path2.join(os.homedir(), ".dirac", "subroutine-index.json");
1625
+ this.index = this.loadIndex();
1626
+ }
1627
+ /**
1628
+ * Load index from disk
1629
+ */
1630
+ loadIndex() {
1631
+ if (fs3.existsSync(this.indexPath)) {
1632
+ try {
1633
+ const data = fs3.readFileSync(this.indexPath, "utf-8");
1634
+ return JSON.parse(data);
1635
+ } catch (err) {
1636
+ console.error("Error loading subroutine index:", err);
1637
+ }
1638
+ }
1639
+ return {
1640
+ subroutines: [],
1641
+ lastUpdated: Date.now()
1642
+ };
1643
+ }
1644
+ /**
1645
+ * Save index to disk
1646
+ */
1647
+ saveIndex() {
1648
+ const dir = path2.dirname(this.indexPath);
1649
+ if (!fs3.existsSync(dir)) {
1650
+ fs3.mkdirSync(dir, { recursive: true });
1651
+ }
1652
+ this.index.lastUpdated = Date.now();
1653
+ fs3.writeFileSync(this.indexPath, JSON.stringify(this.index, null, 2), "utf-8");
1654
+ }
1655
+ /**
1656
+ * Scan a directory for .di files and index all subroutines
1657
+ */
1658
+ async indexDirectory(dirPath) {
1659
+ let count = 0;
1660
+ const scanDir = (dir) => {
1661
+ const entries = fs3.readdirSync(dir, { withFileTypes: true });
1662
+ for (const entry of entries) {
1663
+ const fullPath = path2.join(dir, entry.name);
1664
+ if (entry.isDirectory()) {
1665
+ scanDir(fullPath);
1666
+ } else if (entry.isFile() && entry.name.endsWith(".di")) {
1667
+ count += this.indexFile(fullPath);
1668
+ }
1669
+ }
1670
+ };
1671
+ scanDir(dirPath);
1672
+ this.saveIndex();
1673
+ return count;
1674
+ }
1675
+ /**
1676
+ * Index a single .di file
1677
+ */
1678
+ indexFile(filePath) {
1679
+ try {
1680
+ const content = fs3.readFileSync(filePath, "utf-8");
1681
+ const parser = new DiracParser();
1682
+ const ast = parser.parse(content);
1683
+ this.index.subroutines = this.index.subroutines.filter((s) => s.filePath !== filePath);
1684
+ const subroutines = this.extractSubroutines(ast, filePath);
1685
+ this.index.subroutines.push(...subroutines);
1686
+ return subroutines.length;
1687
+ } catch (err) {
1688
+ if (process.env.DEBUG_REGISTRY === "1") {
1689
+ console.error(`Error indexing ${filePath}:`, err);
1690
+ }
1691
+ return 0;
1692
+ }
1693
+ }
1694
+ /**
1695
+ * Extract subroutines from AST
1696
+ */
1697
+ extractSubroutines(element, filePath) {
1698
+ const subroutines = [];
1699
+ if (element.tag === "subroutine") {
1700
+ const name = element.attributes.name;
1701
+ if (name) {
1702
+ const metadata = {
1703
+ name,
1704
+ description: element.attributes.description,
1705
+ parameters: [],
1706
+ filePath
1707
+ };
1708
+ for (const [attrName, attrValue] of Object.entries(element.attributes)) {
1709
+ if (attrName.startsWith("param-")) {
1710
+ const paramName = attrName.substring(6);
1711
+ const parts = attrValue.split(":");
1712
+ metadata.parameters.push({
1713
+ name: paramName,
1714
+ type: parts[0] || "any",
1715
+ required: parts[1] === "required",
1716
+ description: parts[2]
1717
+ });
1718
+ }
1719
+ }
1720
+ subroutines.push(metadata);
1721
+ }
1722
+ }
1723
+ if (element.children) {
1724
+ for (const child of element.children) {
1725
+ subroutines.push(...this.extractSubroutines(child, filePath));
1726
+ }
1727
+ }
1728
+ return subroutines;
1729
+ }
1730
+ /**
1731
+ * Simple text search (will be replaced with vector search)
1732
+ * Supports multi-word queries by tokenizing and matching individual words
1733
+ */
1734
+ search(query, limit = 10) {
1735
+ const lowerQuery = query.toLowerCase();
1736
+ const queryTokens = lowerQuery.split(/[\s\-_]+/).filter((t) => t.length > 0);
1737
+ const results = this.index.subroutines.map((sub) => {
1738
+ let score = 0;
1739
+ const lowerName = sub.name.toLowerCase();
1740
+ const lowerDesc = (sub.description || "").toLowerCase();
1741
+ const nameTokens = lowerName.split(/[\s\-_]+/);
1742
+ if (lowerName === lowerQuery) {
1743
+ score += 100;
1744
+ } else if (lowerName.includes(lowerQuery)) {
1745
+ score += 50;
1746
+ } else if (lowerDesc.includes(lowerQuery)) {
1747
+ score += 30;
1748
+ }
1749
+ let tokenMatchCount = 0;
1750
+ for (const queryToken of queryTokens) {
1751
+ if (nameTokens.some((nt) => nt === queryToken)) {
1752
+ score += 40;
1753
+ tokenMatchCount++;
1754
+ } else if (nameTokens.some((nt) => nt.includes(queryToken))) {
1755
+ score += 20;
1756
+ tokenMatchCount++;
1757
+ }
1758
+ if (lowerDesc.includes(queryToken)) {
1759
+ score += 15;
1760
+ tokenMatchCount++;
1761
+ }
1762
+ for (const param of sub.parameters) {
1763
+ const lowerParamName = param.name.toLowerCase();
1764
+ if (lowerParamName === queryToken) {
1765
+ score += 10;
1766
+ tokenMatchCount++;
1767
+ } else if (lowerParamName.includes(queryToken)) {
1768
+ score += 5;
1769
+ }
1770
+ }
1771
+ }
1772
+ if (queryTokens.length > 1 && tokenMatchCount >= queryTokens.length * 0.5) {
1773
+ score += 25;
1774
+ }
1775
+ return { sub, score };
1776
+ }).filter((r) => r.score > 0).sort((a, b) => b.score - a.score).slice(0, limit).map((r) => r.sub);
1777
+ return results;
1778
+ }
1779
+ /**
1780
+ * Get all subroutines
1781
+ */
1782
+ getAll() {
1783
+ return this.index.subroutines;
1784
+ }
1785
+ /**
1786
+ * Get statistics
1787
+ */
1788
+ getStats() {
1789
+ const files = new Set(this.index.subroutines.map((s) => s.filePath));
1790
+ return {
1791
+ totalSubroutines: this.index.subroutines.length,
1792
+ totalFiles: files.size,
1793
+ lastUpdated: new Date(this.index.lastUpdated)
1794
+ };
1795
+ }
1796
+ };
1797
+
1798
+ // src/tags/subroutine-index.ts
1799
+ var registry = new SubroutineRegistry();
1800
+ async function executeIndexSubroutines(session, element) {
1801
+ const pathAttr = element.attributes.path;
1802
+ if (!pathAttr) {
1803
+ throw new Error("<index-subroutines> requires path attribute");
1804
+ }
1805
+ const count = await registry.indexDirectory(pathAttr);
1806
+ if (session.debug) {
1807
+ emit(session, `Indexed ${count} subroutines from ${pathAttr}
1808
+ `);
1809
+ }
1810
+ }
1811
+ async function executeSearchSubroutines(session, element) {
1812
+ const query = element.attributes.query;
1813
+ const limitAttr = element.attributes.limit;
1814
+ const outputVar = element.attributes.output;
1815
+ const format = element.attributes.format || "text";
1816
+ if (!query) {
1817
+ throw new Error("<search-subroutines> requires query attribute");
1818
+ }
1819
+ const limit = limitAttr ? parseInt(limitAttr, 10) : 10;
1820
+ const results = registry.search(query, limit);
1821
+ let output = "";
1822
+ switch (format) {
1823
+ case "json":
1824
+ output = JSON.stringify(results, null, 2);
1825
+ break;
1826
+ case "xml":
1827
+ output = "<subroutines>\n";
1828
+ for (const sub of results) {
1829
+ const params = sub.parameters.map((p) => `param-${p.name}="${p.type}"`).join(" ");
1830
+ output += ` <subroutine name="${sub.name}" ${params} file="${sub.filePath}"/>
1831
+ `;
1832
+ if (sub.description) {
1833
+ output += ` <!-- ${sub.description} -->
1834
+ `;
1835
+ }
1836
+ }
1837
+ output += "</subroutines>";
1838
+ break;
1839
+ case "text":
1840
+ default:
1841
+ if (results.length === 0) {
1842
+ output = "No subroutines found.\n";
1843
+ } else {
1844
+ output = `Found ${results.length} subroutine(s):
1845
+
1846
+ `;
1847
+ for (const sub of results) {
1848
+ output += `${sub.name}(${sub.parameters.map((p) => p.name).join(", ")})
1849
+ `;
1850
+ if (sub.description) {
1851
+ output += ` ${sub.description}
1852
+ `;
1853
+ }
1854
+ output += ` File: ${sub.filePath}
1855
+
1856
+ `;
1857
+ }
1858
+ }
1859
+ break;
1860
+ }
1861
+ if (outputVar) {
1862
+ setVariable(session, outputVar, output, false);
1863
+ } else {
1864
+ emit(session, output);
1865
+ }
1866
+ }
1867
+ async function executeRegistryStats(session, element) {
1868
+ const stats = registry.getStats();
1869
+ const output = `Subroutine Registry Statistics:
1870
+ Total Subroutines: ${stats.totalSubroutines}
1871
+ Total Files: ${stats.totalFiles}
1872
+ Last Updated: ${stats.lastUpdated.toLocaleString()}
1873
+ `;
1874
+ emit(session, output);
1875
+ }
1876
+
1877
+ // src/tags/load-context.ts
1878
+ var registry2 = new SubroutineRegistry();
1879
+ async function executeLoadContext(session, element) {
1880
+ let query = element.attributes.query;
1881
+ if (!query && element.text) {
1882
+ query = element.text.trim();
1883
+ }
1884
+ if (!query && element.children.length > 0) {
1885
+ const { integrate: integrate2 } = await import("./interpreter-UCWBT6KP.js");
1886
+ const beforeOutput = session.output.length;
1887
+ for (const child of element.children) {
1888
+ await integrate2(session, child);
1889
+ }
1890
+ const childOutput = session.output.slice(beforeOutput);
1891
+ query = childOutput.join("").trim();
1892
+ session.output = session.output.slice(0, beforeOutput);
1893
+ }
1894
+ if (!query) {
1895
+ throw new Error("<load-context> requires query attribute or text content");
1896
+ }
1897
+ const limitAttr = element.attributes.limit;
1898
+ const shouldImport = element.attributes.import !== "false";
1899
+ const outputVar = element.attributes.output;
1900
+ const stats = registry2.getStats();
1901
+ if (stats.totalSubroutines === 0) {
1902
+ emit(session, `[load-context] Registry is empty. Use :index <path> or <index-subroutines path="..."> first.
1903
+ `);
1904
+ return;
1905
+ }
1906
+ const limit = limitAttr ? parseInt(limitAttr, 10) : 5;
1907
+ const results = registry2.search(query, limit);
1908
+ if (results.length === 0) {
1909
+ emit(session, `[load-context] No subroutines found for query: "${query}". Try indexing more libraries.
1910
+ `);
1911
+ return;
1912
+ }
1913
+ emit(session, `[load-context] Found ${results.length} subroutine(s): ${results.map((s) => s.name).join(", ")}
1914
+ `);
1915
+ const fileMap = /* @__PURE__ */ new Map();
1916
+ for (const sub of results) {
1917
+ if (!fileMap.has(sub.filePath)) {
1918
+ fileMap.set(sub.filePath, []);
1919
+ }
1920
+ fileMap.get(sub.filePath).push(sub);
1921
+ }
1922
+ emit(session, `[load-context] Importing ${fileMap.size} file(s)...
1923
+ `);
1924
+ if (shouldImport) {
1925
+ for (const filePath of fileMap.keys()) {
1926
+ try {
1927
+ const { resolve: resolve2 } = await import("path");
1928
+ const absolutePath = filePath.startsWith("/") ? filePath : resolve2(process.cwd(), filePath);
1929
+ const importElement = {
1930
+ tag: "import",
1931
+ attributes: { src: absolutePath },
1932
+ children: [],
1933
+ text: ""
1934
+ };
1935
+ await executeImport(session, importElement);
1936
+ emit(session, `[load-context] \u2713 Imported: ${filePath}
1937
+ `);
1938
+ } catch (error) {
1939
+ emit(session, `[load-context] \u2717 Failed to import ${filePath}: ${error}
1940
+ `);
1941
+ }
1942
+ }
1943
+ } else {
1944
+ emit(session, `[load-context] (import=false, not loading files)
1945
+ `);
1946
+ }
1947
+ if (outputVar) {
1948
+ const summary = results.map((s) => ({
1949
+ name: s.name,
1950
+ description: s.description,
1951
+ parameters: s.parameters.map((p) => p.name),
1952
+ filePath: s.filePath
1953
+ }));
1954
+ const { setVariable: setVariable2 } = await import("./session-UBATJEND.js");
1955
+ setVariable2(session, outputVar, JSON.stringify(summary, null, 2), false);
1956
+ }
1957
+ }
1958
+
1541
1959
  // src/tags/foreach.ts
1542
1960
  import { XMLParser } from "fast-xml-parser";
1543
1961
  async function executeForeach(session, element) {
@@ -1558,7 +1976,7 @@ async function executeForeach(session, element) {
1558
1976
  const parser2 = new DiracParser2();
1559
1977
  try {
1560
1978
  const fromElement = parser2.parse(fromAttr);
1561
- const { integrate: integrate2 } = await import("./interpreter-GLWAQHAW.js");
1979
+ const { integrate: integrate2 } = await import("./interpreter-UCWBT6KP.js");
1562
1980
  await integrate2(session, fromElement);
1563
1981
  } catch (e) {
1564
1982
  session.output = savedOutput;
@@ -1706,7 +2124,7 @@ async function executeEnvironment(session, element) {
1706
2124
  }
1707
2125
 
1708
2126
  // src/tags/input.ts
1709
- import * as fs3 from "fs";
2127
+ import * as fs4 from "fs";
1710
2128
  import * as readline from "readline";
1711
2129
  var fileReaders = /* @__PURE__ */ new Map();
1712
2130
  var fileIterators = /* @__PURE__ */ new Map();
@@ -1730,11 +2148,11 @@ async function executeInput(session, element) {
1730
2148
  throw new Error(`<input> invalid mode: ${mode}. Use 'all' or 'line'`);
1731
2149
  }
1732
2150
  } else if (source === "file") {
1733
- const path2 = substituteAttribute(session, pathAttr);
2151
+ const path3 = substituteAttribute(session, pathAttr);
1734
2152
  if (mode === "all") {
1735
- value = fs3.readFileSync(path2, "utf-8");
2153
+ value = fs4.readFileSync(path3, "utf-8");
1736
2154
  } else if (mode === "line") {
1737
- value = await readLineFromFile(path2);
2155
+ value = await readLineFromFile(path3);
1738
2156
  } else {
1739
2157
  throw new Error(`<input> invalid mode: ${mode}. Use 'all' or 'line'`);
1740
2158
  }
@@ -1791,23 +2209,23 @@ async function readLineStdin() {
1791
2209
  }
1792
2210
  return result.value;
1793
2211
  }
1794
- async function readLineFromFile(path2) {
1795
- if (!fileReaders.has(path2)) {
1796
- const fileStream = fs3.createReadStream(path2);
2212
+ async function readLineFromFile(path3) {
2213
+ if (!fileReaders.has(path3)) {
2214
+ const fileStream = fs4.createReadStream(path3);
1797
2215
  const rl = readline.createInterface({
1798
2216
  input: fileStream,
1799
2217
  crlfDelay: Infinity
1800
2218
  });
1801
- fileReaders.set(path2, rl);
1802
- fileIterators.set(path2, rl[Symbol.asyncIterator]());
2219
+ fileReaders.set(path3, rl);
2220
+ fileIterators.set(path3, rl[Symbol.asyncIterator]());
1803
2221
  }
1804
- const iterator = fileIterators.get(path2);
2222
+ const iterator = fileIterators.get(path3);
1805
2223
  const result = await iterator.next();
1806
2224
  if (result.done) {
1807
- const reader = fileReaders.get(path2);
2225
+ const reader = fileReaders.get(path3);
1808
2226
  reader.close();
1809
- fileReaders.delete(path2);
1810
- fileIterators.delete(path2);
2227
+ fileReaders.delete(path3);
2228
+ fileIterators.delete(path3);
1811
2229
  return "";
1812
2230
  }
1813
2231
  return result.value;
@@ -1902,6 +2320,21 @@ async function integrate(session, element) {
1902
2320
  case "available-subroutines":
1903
2321
  await executeAvailableSubroutines(session, element);
1904
2322
  break;
2323
+ case "list-subroutines":
2324
+ await executeListSubroutines(session, element);
2325
+ break;
2326
+ case "index-subroutines":
2327
+ await executeIndexSubroutines(session, element);
2328
+ break;
2329
+ case "search-subroutines":
2330
+ await executeSearchSubroutines(session, element);
2331
+ break;
2332
+ case "registry-stats":
2333
+ await executeRegistryStats(session, element);
2334
+ break;
2335
+ case "load-context":
2336
+ await executeLoadContext(session, element);
2337
+ break;
1905
2338
  case "foreach":
1906
2339
  await executeForeach(session, element);
1907
2340
  break;
@@ -277,15 +277,37 @@ var BraKetParser = class {
277
277
  }
278
278
  return `"${value}"`;
279
279
  }
280
+ /**
281
+ * Escape XML special characters in text content
282
+ */
283
+ escapeXml(text) {
284
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
285
+ }
280
286
  /**
281
287
  * Convert inline kets within text content
282
288
  * Example: "Hello |variable name=x> world" → "Hello <variable name="x"/> world"
289
+ * Example: "if x < 10 and y > 5" → "if x &lt; 10 and y &gt; 5"
283
290
  */
284
291
  convertInlineKets(text) {
285
- return text.replace(/\|([a-zA-Z_][a-zA-Z0-9_-]*)\s*([^>]*?)>/g, (match, tag, attrs) => {
292
+ const parts = [];
293
+ let lastIndex = 0;
294
+ const ketRegex = /\|([a-zA-Z_][a-zA-Z0-9_-]*)\s*([^>]*?)>/g;
295
+ let match;
296
+ while ((match = ketRegex.exec(text)) !== null) {
297
+ if (match.index > lastIndex) {
298
+ const beforeText = text.substring(lastIndex, match.index);
299
+ parts.push(this.escapeXml(beforeText));
300
+ }
301
+ const [, tag, attrs] = match;
286
302
  const attrStr = attrs.trim() ? ` ${this.convertAttributes(attrs.trim())}` : "";
287
- return `<${tag}${attrStr}/>`;
288
- });
303
+ parts.push(`<${tag}${attrStr}/>`);
304
+ lastIndex = ketRegex.lastIndex;
305
+ }
306
+ if (lastIndex < text.length) {
307
+ const remainingText = text.substring(lastIndex);
308
+ parts.push(this.escapeXml(remainingText));
309
+ }
310
+ return parts.join("");
289
311
  }
290
312
  };
291
313
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  integrate
3
- } from "./chunk-MVMLG434.js";
3
+ } from "./chunk-NWGHO23V.js";
4
4
  import {
5
5
  DiracParser
6
6
  } from "./chunk-HRHAMPOB.js";
package/dist/cli.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  BraKetParser
4
- } from "./chunk-E66LTAOE.js";
4
+ } from "./chunk-UEFKQRYN.js";
5
5
  import {
6
6
  execute
7
- } from "./chunk-4J2UJXJZ.js";
8
- import "./chunk-MVMLG434.js";
7
+ } from "./chunk-W6BEEC5D.js";
8
+ import "./chunk-NWGHO23V.js";
9
9
  import "./chunk-HRHAMPOB.js";
10
10
  import "./chunk-4QLTSCDG.js";
11
11
  import "./chunk-GLXVY235.js";
@@ -16,7 +16,7 @@ import "dotenv/config";
16
16
  // package.json
17
17
  var package_default = {
18
18
  name: "dirac-lang",
19
- version: "0.1.37",
19
+ version: "0.1.38",
20
20
  description: "LLM-Augmented Declarative Execution",
21
21
  type: "module",
22
22
  main: "dist/index.js",
@@ -46,6 +46,7 @@ var package_default = {
46
46
  license: "MIT",
47
47
  dependencies: {
48
48
  "@anthropic-ai/sdk": "^0.30.1",
49
+ "dirac-stdlib": "^0.1.0",
49
50
  dotenv: "^17.2.3",
50
51
  "fast-xml-parser": "^4.3.5",
51
52
  "js-yaml": "^4.1.1",
@@ -95,7 +96,7 @@ async function main() {
95
96
  process.exit(0);
96
97
  }
97
98
  if (args[0] === "shell") {
98
- const { DiracShell } = await import("./shell-B5RBRWK2.js");
99
+ const { DiracShell } = await import("./shell-T5G3PTPT.js");
99
100
  const shellConfig = { debug: false };
100
101
  for (let i = 1; i < args.length; i++) {
101
102
  const arg = args[i];
@@ -108,7 +109,8 @@ async function main() {
108
109
  Object.assign(shellConfig, {
109
110
  llmProvider: configData.llmProvider,
110
111
  llmModel: configData.llmModel,
111
- customLLMUrl: configData.customLLMUrl
112
+ customLLMUrl: configData.customLLMUrl,
113
+ initScript: configData.initScript
112
114
  });
113
115
  }
114
116
  }
@@ -121,12 +123,13 @@ async function main() {
121
123
  shellConfig.llmProvider = shellConfig.llmProvider || configData.llmProvider;
122
124
  shellConfig.llmModel = shellConfig.llmModel || configData.llmModel;
123
125
  shellConfig.customLLMUrl = shellConfig.customLLMUrl || configData.customLLMUrl;
126
+ shellConfig.initScript = shellConfig.initScript || configData.initScript;
124
127
  } catch (err) {
125
128
  }
126
129
  }
127
130
  }
128
131
  const shell = new DiracShell(shellConfig);
129
- shell.start();
132
+ await shell.start();
130
133
  return;
131
134
  }
132
135
  if (args.length === 0) {
package/dist/index.d.ts CHANGED
@@ -95,6 +95,7 @@ interface DiracConfig {
95
95
  llmProvider?: string;
96
96
  llmModel?: string;
97
97
  customLLMUrl?: string;
98
+ initScript?: string;
98
99
  }
99
100
 
100
101
  /**
package/dist/index.js CHANGED
@@ -2,10 +2,10 @@ import {
2
2
  createLLMAdapter,
3
3
  execute,
4
4
  executeUserCommand
5
- } from "./chunk-4J2UJXJZ.js";
5
+ } from "./chunk-W6BEEC5D.js";
6
6
  import {
7
7
  integrate
8
- } from "./chunk-MVMLG434.js";
8
+ } from "./chunk-NWGHO23V.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-MVMLG434.js";
4
+ } from "./chunk-NWGHO23V.js";
5
5
  import "./chunk-HRHAMPOB.js";
6
6
  import "./chunk-4QLTSCDG.js";
7
7
  import "./chunk-GLXVY235.js";
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  BraKetParser
4
- } from "./chunk-E66LTAOE.js";
4
+ } from "./chunk-UEFKQRYN.js";
5
5
  import {
6
6
  integrate
7
- } from "./chunk-MVMLG434.js";
7
+ } from "./chunk-NWGHO23V.js";
8
8
  import {
9
9
  DiracParser
10
10
  } from "./chunk-HRHAMPOB.js";
@@ -185,6 +185,10 @@ Commands:
185
185
  :clear Clear session (reset variables and subroutines)
186
186
  :debug Toggle debug mode
187
187
  :config Show current configuration
188
+ :index <path> Index subroutines from directory
189
+ :search <query> Search indexed subroutines
190
+ :load <query> Load context (search and import subroutines)
191
+ :stats Show registry statistics
188
192
  :exit Exit shell
189
193
 
190
194
  Syntax:
@@ -255,6 +259,69 @@ Examples:
255
259
  console.log(` Custom LLM URL: ${this.config.customLLMUrl}`);
256
260
  }
257
261
  break;
262
+ case "index":
263
+ if (args.length === 0) {
264
+ console.log("Usage: :index <path>");
265
+ } else {
266
+ const indexPath = args[0];
267
+ try {
268
+ const xml = `<index-subroutines path="${indexPath}" />`;
269
+ const ast = this.xmlParser.parse(xml);
270
+ await integrate(this.session, ast);
271
+ if (this.session.output.length > 0) {
272
+ console.log(this.session.output.join(""));
273
+ }
274
+ } catch (error) {
275
+ console.error("Error indexing:", error instanceof Error ? error.message : String(error));
276
+ }
277
+ }
278
+ break;
279
+ case "search":
280
+ if (args.length === 0) {
281
+ console.log("Usage: :search <query>");
282
+ } else {
283
+ const query = args.join(" ");
284
+ try {
285
+ const xml = `<search-subroutines query="${query}" format="text" />`;
286
+ const ast = this.xmlParser.parse(xml);
287
+ await integrate(this.session, ast);
288
+ if (this.session.output.length > 0) {
289
+ console.log(this.session.output.join(""));
290
+ }
291
+ } catch (error) {
292
+ console.error("Error searching:", error instanceof Error ? error.message : String(error));
293
+ }
294
+ }
295
+ break;
296
+ case "load":
297
+ if (args.length === 0) {
298
+ console.log("Usage: :load <query>");
299
+ } else {
300
+ const query = args.join(" ");
301
+ try {
302
+ const xml = `<load-context query="${query}" limit="5" import="true" />`;
303
+ const ast = this.xmlParser.parse(xml);
304
+ await integrate(this.session, ast);
305
+ if (this.session.output.length > 0) {
306
+ console.log(this.session.output.join(""));
307
+ }
308
+ } catch (error) {
309
+ console.error("Error loading context:", error instanceof Error ? error.message : String(error));
310
+ }
311
+ }
312
+ break;
313
+ case "stats":
314
+ try {
315
+ const xml = "<registry-stats />";
316
+ const ast = this.xmlParser.parse(xml);
317
+ await integrate(this.session, ast);
318
+ if (this.session.output.length > 0) {
319
+ console.log(this.session.output.join(""));
320
+ }
321
+ } catch (error) {
322
+ console.error("Error getting stats:", error instanceof Error ? error.message : String(error));
323
+ }
324
+ break;
258
325
  case "exit":
259
326
  case "quit":
260
327
  this.rl.close();
@@ -318,7 +385,7 @@ Examples:
318
385
  });
319
386
  });
320
387
  }
321
- start() {
388
+ async start() {
322
389
  console.log("Dirac Shell v0.1.0");
323
390
  console.log("Type :help for commands, :exit to quit\n");
324
391
  if (this.config.llmProvider) {
@@ -327,8 +394,31 @@ Examples:
327
394
  } else {
328
395
  console.log("Warning: No LLM provider configured. Set LLM_PROVIDER environment variable.\n");
329
396
  }
397
+ if (this.config.initScript) {
398
+ await this.runInitScript(this.config.initScript);
399
+ }
330
400
  this.rl.prompt();
331
401
  }
402
+ async runInitScript(scriptPath) {
403
+ try {
404
+ const resolvedPath = path.isAbsolute(scriptPath) ? scriptPath : path.join(process.cwd(), scriptPath);
405
+ if (!fs.existsSync(resolvedPath)) {
406
+ console.log(`Init script not found: ${scriptPath}
407
+ `);
408
+ return;
409
+ }
410
+ console.log(`Loading init script: ${scriptPath}`);
411
+ const scriptContent = fs.readFileSync(resolvedPath, "utf-8");
412
+ const xml = this.braketParser.parse(scriptContent);
413
+ const ast = this.xmlParser.parse(xml);
414
+ await integrate(this.session, ast);
415
+ console.log(`Init script loaded.
416
+ `);
417
+ } catch (err) {
418
+ console.error(`Error loading init script: ${err instanceof Error ? err.message : String(err)}
419
+ `);
420
+ }
421
+ }
332
422
  };
333
423
  async function main() {
334
424
  let config = {
@@ -342,7 +432,8 @@ async function main() {
342
432
  ...config,
343
433
  llmProvider: configData.llmProvider || process.env.LLM_PROVIDER,
344
434
  llmModel: configData.llmModel || process.env.LLM_MODEL,
345
- customLLMUrl: configData.customLLMUrl || process.env.CUSTOM_LLM_URL
435
+ customLLMUrl: configData.customLLMUrl || process.env.CUSTOM_LLM_URL,
436
+ initScript: configData.initScript
346
437
  };
347
438
  } catch (err) {
348
439
  console.error("Warning: Could not load config.yml");
@@ -353,7 +444,7 @@ async function main() {
353
444
  config.customLLMUrl = process.env.CUSTOM_LLM_URL;
354
445
  }
355
446
  const shell = new DiracShell(config);
356
- shell.start();
447
+ await shell.start();
357
448
  }
358
449
  if (import.meta.url === `file://${process.argv[1]}`) {
359
450
  main();
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  integrate
3
- } from "./chunk-MVMLG434.js";
3
+ } from "./chunk-NWGHO23V.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.37",
3
+ "version": "0.1.39",
4
4
  "description": "LLM-Augmented Declarative Execution",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -30,6 +30,7 @@
30
30
  "license": "MIT",
31
31
  "dependencies": {
32
32
  "@anthropic-ai/sdk": "^0.30.1",
33
+ "dirac-stdlib": "^0.1.0",
33
34
  "dotenv": "^17.2.3",
34
35
  "fast-xml-parser": "^4.3.5",
35
36
  "js-yaml": "^4.1.1",