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.
- package/dist/{chunk-MVMLG434.js → chunk-NWGHO23V.js} +465 -32
- package/dist/{chunk-E66LTAOE.js → chunk-UEFKQRYN.js} +25 -3
- package/dist/{chunk-4J2UJXJZ.js → chunk-W6BEEC5D.js} +1 -1
- package/dist/cli.js +10 -7
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -2
- package/dist/{interpreter-GLWAQHAW.js → interpreter-UCWBT6KP.js} +1 -1
- package/dist/{shell-B5RBRWK2.js → shell-T5G3PTPT.js} +96 -5
- package/dist/test-runner.js +1 -1
- package/package.json +2 -1
|
@@ -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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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 =
|
|
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:
|
|
936
|
-
const { default:
|
|
936
|
+
const { default: fs5 } = await import("fs");
|
|
937
|
+
const { default: path3 } = await import("path");
|
|
937
938
|
const { fileURLToPath } = await import("url");
|
|
938
|
-
context.fs =
|
|
939
|
-
context.path =
|
|
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 =
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
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-
|
|
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
|
|
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
|
|
2151
|
+
const path3 = substituteAttribute(session, pathAttr);
|
|
1734
2152
|
if (mode === "all") {
|
|
1735
|
-
value =
|
|
2153
|
+
value = fs4.readFileSync(path3, "utf-8");
|
|
1736
2154
|
} else if (mode === "line") {
|
|
1737
|
-
value = await readLineFromFile(
|
|
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(
|
|
1795
|
-
if (!fileReaders.has(
|
|
1796
|
-
const fileStream =
|
|
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(
|
|
1802
|
-
fileIterators.set(
|
|
2219
|
+
fileReaders.set(path3, rl);
|
|
2220
|
+
fileIterators.set(path3, rl[Symbol.asyncIterator]());
|
|
1803
2221
|
}
|
|
1804
|
-
const iterator = fileIterators.get(
|
|
2222
|
+
const iterator = fileIterators.get(path3);
|
|
1805
2223
|
const result = await iterator.next();
|
|
1806
2224
|
if (result.done) {
|
|
1807
|
-
const reader = fileReaders.get(
|
|
2225
|
+
const reader = fileReaders.get(path3);
|
|
1808
2226
|
reader.close();
|
|
1809
|
-
fileReaders.delete(
|
|
1810
|
-
fileIterators.delete(
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
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 < 10 and y > 5"
|
|
283
290
|
*/
|
|
284
291
|
convertInlineKets(text) {
|
|
285
|
-
|
|
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
|
-
|
|
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
|
|
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
BraKetParser
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-UEFKQRYN.js";
|
|
5
5
|
import {
|
|
6
6
|
execute
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
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.
|
|
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-
|
|
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
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-W6BEEC5D.js";
|
|
6
6
|
import {
|
|
7
7
|
integrate
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-NWGHO23V.js";
|
|
9
9
|
import {
|
|
10
10
|
DiracParser
|
|
11
11
|
} from "./chunk-HRHAMPOB.js";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
BraKetParser
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-UEFKQRYN.js";
|
|
5
5
|
import {
|
|
6
6
|
integrate
|
|
7
|
-
} from "./chunk-
|
|
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();
|
package/dist/test-runner.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dirac-lang",
|
|
3
|
-
"version": "0.1.
|
|
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",
|