dirac-lang 0.1.44 → 0.1.46
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-2SNN7MBU.js → chunk-TISVDOGD.js} +1 -1
- package/dist/{chunk-4ROK7OUQ.js → chunk-TXL3RV74.js} +283 -129
- package/dist/cli.js +7 -4
- package/dist/index.js +2 -2
- package/dist/{interpreter-Y2BOWVF4.js → interpreter-XH3RFKVP.js} +1 -1
- package/dist/{schedule-DZ2SPHSX.js → schedule-5HZCREEP.js} +1 -1
- package/dist/{shell-3ZZUMKP3.js → shell-LGNPK4GO.js} +24 -10
- package/dist/test-runner.js +1 -1
- package/package.json +1 -1
|
@@ -460,12 +460,12 @@ async function executeIf(session, element) {
|
|
|
460
460
|
const condition = await evaluatePredicate(session, conditionElement);
|
|
461
461
|
if (condition) {
|
|
462
462
|
if (thenElement) {
|
|
463
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
463
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-XH3RFKVP.js");
|
|
464
464
|
await integrateChildren2(session, thenElement);
|
|
465
465
|
}
|
|
466
466
|
} else {
|
|
467
467
|
if (elseElement) {
|
|
468
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
468
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-XH3RFKVP.js");
|
|
469
469
|
await integrateChildren2(session, elseElement);
|
|
470
470
|
}
|
|
471
471
|
}
|
|
@@ -478,7 +478,7 @@ async function evaluatePredicate(session, predicateElement) {
|
|
|
478
478
|
return await evaluateCondition(session, predicateElement);
|
|
479
479
|
}
|
|
480
480
|
const outputLengthBefore = session.output.length;
|
|
481
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
481
|
+
const { integrate: integrate2 } = await import("./interpreter-XH3RFKVP.js");
|
|
482
482
|
await integrate2(session, predicateElement);
|
|
483
483
|
const newOutputChunks = session.output.slice(outputLengthBefore);
|
|
484
484
|
const result = newOutputChunks.join("").trim();
|
|
@@ -501,11 +501,11 @@ async function evaluateCondition(session, condElement) {
|
|
|
501
501
|
}
|
|
502
502
|
const outputLengthBefore = session.output.length;
|
|
503
503
|
const args = [];
|
|
504
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
504
|
+
const { integrate: integrate2 } = await import("./interpreter-XH3RFKVP.js");
|
|
505
505
|
for (const child of condElement.children) {
|
|
506
506
|
if (child.tag.toLowerCase() === "arg") {
|
|
507
507
|
const argOutputStart = session.output.length;
|
|
508
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
508
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-XH3RFKVP.js");
|
|
509
509
|
await integrateChildren2(session, child);
|
|
510
510
|
const newChunks = session.output.slice(argOutputStart);
|
|
511
511
|
const argValue = newChunks.join("");
|
|
@@ -564,10 +564,113 @@ function evaluateConditionType(evalType, args) {
|
|
|
564
564
|
}
|
|
565
565
|
|
|
566
566
|
// src/tags/llm.ts
|
|
567
|
+
import * as fs2 from "fs";
|
|
568
|
+
import * as path2 from "path";
|
|
569
|
+
import * as os from "os";
|
|
570
|
+
function dumpGeneratedSubroutines(session, diracCode, userPrompt) {
|
|
571
|
+
try {
|
|
572
|
+
let findSubroutines2 = function(element) {
|
|
573
|
+
if (element.tag === "subroutine") {
|
|
574
|
+
subroutines.push(element);
|
|
575
|
+
}
|
|
576
|
+
if (element.children) {
|
|
577
|
+
for (const child of element.children) {
|
|
578
|
+
findSubroutines2(child);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
};
|
|
582
|
+
var findSubroutines = findSubroutines2;
|
|
583
|
+
const parser = new DiracParser();
|
|
584
|
+
const ast = parser.parse(diracCode);
|
|
585
|
+
const subroutines = [];
|
|
586
|
+
findSubroutines2(ast);
|
|
587
|
+
if (subroutines.length === 0) {
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, -5);
|
|
591
|
+
const dumpDir = path2.join(os.homedir(), ".dirac", "lib", timestamp);
|
|
592
|
+
if (!fs2.existsSync(dumpDir)) {
|
|
593
|
+
fs2.mkdirSync(dumpDir, { recursive: true });
|
|
594
|
+
}
|
|
595
|
+
for (const sub of subroutines) {
|
|
596
|
+
const subName = sub.attributes.name || "unnamed";
|
|
597
|
+
const filePath = path2.join(dumpDir, `${subName}.di`);
|
|
598
|
+
const xml = serializeElement(sub, userPrompt);
|
|
599
|
+
fs2.writeFileSync(filePath, xml, "utf-8");
|
|
600
|
+
if (session.debug) {
|
|
601
|
+
console.error(`[LLM] Dumped subroutine '${subName}' to: ${filePath}`);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
if (session.debug) {
|
|
605
|
+
console.error(`[LLM] Dumped ${subroutines.length} subroutine(s) to: ${dumpDir}`);
|
|
606
|
+
}
|
|
607
|
+
} catch (error) {
|
|
608
|
+
if (session.debug) {
|
|
609
|
+
console.error(`[LLM] Failed to dump subroutines: ${error}`);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
function serializeElement(element, prompt) {
|
|
614
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
615
|
+
const lines = [];
|
|
616
|
+
lines.push("<!--");
|
|
617
|
+
lines.push(` Created: ${timestamp}`);
|
|
618
|
+
lines.push(` Generated by: LLM`);
|
|
619
|
+
lines.push(` Prompt: ${prompt.replace(/-->/g, "-->")}`);
|
|
620
|
+
lines.push("-->");
|
|
621
|
+
lines.push("");
|
|
622
|
+
function serialize(el, indent = "") {
|
|
623
|
+
if (el.text && !el.tag) {
|
|
624
|
+
lines.push(indent + el.text);
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
if (!el.tag) return;
|
|
628
|
+
let tag = `${indent}<${el.tag}`;
|
|
629
|
+
if (el.attributes) {
|
|
630
|
+
for (const [key, value] of Object.entries(el.attributes)) {
|
|
631
|
+
tag += ` ${key}="${value.replace(/"/g, """)}"`;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
if (!el.children || el.children.length === 0) {
|
|
635
|
+
if (el.text) {
|
|
636
|
+
lines.push(tag + ">");
|
|
637
|
+
lines.push(indent + " " + el.text);
|
|
638
|
+
lines.push(`${indent}</${el.tag}>`);
|
|
639
|
+
} else {
|
|
640
|
+
lines.push(tag + " />");
|
|
641
|
+
}
|
|
642
|
+
} else {
|
|
643
|
+
lines.push(tag + ">");
|
|
644
|
+
for (const child of el.children) {
|
|
645
|
+
serialize(child, indent + " ");
|
|
646
|
+
}
|
|
647
|
+
lines.push(`${indent}</${el.tag}>`);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
serialize(element);
|
|
651
|
+
return lines.join("\n");
|
|
652
|
+
}
|
|
567
653
|
async function executeLLM(session, element) {
|
|
568
654
|
if (!session.llmClient) {
|
|
569
655
|
throw new Error("<llm> tag requires LLM configuration. Set LLM_PROVIDER (ollama/anthropic/openai/custom) and appropriate API keys in environment or config.yml");
|
|
570
656
|
}
|
|
657
|
+
const callAnthropic = async (client, model2, maxTokens2, temperature2, messages) => {
|
|
658
|
+
const systemMessages = messages.filter((m) => m.role === "system");
|
|
659
|
+
const userAssistantMessages = messages.filter((m) => m.role !== "system");
|
|
660
|
+
const systemContent = systemMessages.map((m) => m.content).join("\n\n");
|
|
661
|
+
const anthropicParams = {
|
|
662
|
+
model: model2,
|
|
663
|
+
max_tokens: maxTokens2,
|
|
664
|
+
temperature: temperature2,
|
|
665
|
+
messages: userAssistantMessages
|
|
666
|
+
};
|
|
667
|
+
if (systemContent) {
|
|
668
|
+
anthropicParams.system = systemContent;
|
|
669
|
+
}
|
|
670
|
+
const response = await client.messages.create(anthropicParams);
|
|
671
|
+
const content = response.content[0];
|
|
672
|
+
return content.type === "text" ? content.text : "";
|
|
673
|
+
};
|
|
571
674
|
if (session.limits.currentLLMCalls >= session.limits.maxLLMCalls) {
|
|
572
675
|
throw new Error("Maximum LLM calls exceeded");
|
|
573
676
|
}
|
|
@@ -580,6 +683,7 @@ async function executeLLM(session, element) {
|
|
|
580
683
|
const model = element.attributes.model || process.env.DEFAULT_MODEL || defaultModel;
|
|
581
684
|
const outputVar = element.attributes.output;
|
|
582
685
|
const contextVar = element.attributes.context;
|
|
686
|
+
const saveDialog = element.attributes["save-dialog"] === "true";
|
|
583
687
|
const executeMode = element.attributes.execute === "true";
|
|
584
688
|
const temperature = parseFloat(element.attributes.temperature || "1.0");
|
|
585
689
|
const maxTokens = parseInt(element.attributes.maxTokens || "4096", 10);
|
|
@@ -598,23 +702,29 @@ async function executeLLM(session, element) {
|
|
|
598
702
|
throw new Error("<LLM> requires prompt content");
|
|
599
703
|
}
|
|
600
704
|
let dialogHistory = [];
|
|
601
|
-
|
|
602
|
-
|
|
705
|
+
let hasExistingDialog = false;
|
|
706
|
+
if (contextVar || saveDialog) {
|
|
707
|
+
const varName = contextVar || "__llm_dialog__";
|
|
708
|
+
const existing = getVariable(session, varName);
|
|
709
|
+
if (session.debug) {
|
|
710
|
+
console.error(`[LLM] Checking for dialog context in variable: ${varName}`);
|
|
711
|
+
console.error(`[LLM] Existing value type: ${Array.isArray(existing) ? "array" : typeof existing}`);
|
|
712
|
+
if (Array.isArray(existing)) {
|
|
713
|
+
console.error(`[LLM] Existing dialog length: ${existing.length} messages`);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
603
716
|
if (Array.isArray(existing)) {
|
|
604
717
|
dialogHistory = [...existing];
|
|
718
|
+
hasExistingDialog = dialogHistory.length > 0;
|
|
605
719
|
} else if (existing) {
|
|
606
720
|
dialogHistory = [{ role: "system", content: String(existing) }];
|
|
721
|
+
hasExistingDialog = true;
|
|
607
722
|
}
|
|
608
723
|
}
|
|
609
724
|
const noExtra = element.attributes.noextra === "true";
|
|
610
|
-
let prompt;
|
|
611
725
|
let systemPrompt = "";
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
if (session.debug || process.env.DIRAC_LOG_PROMPT === "1") {
|
|
615
|
-
console.error("[LLM] Full prompt sent to LLM (noextra):\n" + prompt + "\n");
|
|
616
|
-
}
|
|
617
|
-
} else {
|
|
726
|
+
let currentUserPrompt = userPrompt;
|
|
727
|
+
if (!noExtra) {
|
|
618
728
|
const { getAvailableSubroutines: getAvailableSubroutines2 } = await import("./session-UBATJEND.js");
|
|
619
729
|
const subroutines = getAvailableSubroutines2(session);
|
|
620
730
|
if (session.debug) {
|
|
@@ -623,48 +733,85 @@ async function executeLLM(session, element) {
|
|
|
623
733
|
subroutines.map((s) => ({ name: s.name, description: s.description, parameters: s.parameters }))
|
|
624
734
|
);
|
|
625
735
|
}
|
|
626
|
-
|
|
736
|
+
if (hasExistingDialog && (contextVar || saveDialog)) {
|
|
737
|
+
systemPrompt = "Updated available Dirac XML tags:";
|
|
738
|
+
for (const sub of subroutines) {
|
|
739
|
+
systemPrompt += `
|
|
740
|
+
- ${sub.name} : ${sub.description || ""}`;
|
|
741
|
+
systemPrompt += `
|
|
742
|
+
Ex: <${sub.name}`;
|
|
743
|
+
if (sub.parameters && sub.parameters.length > 0) {
|
|
744
|
+
for (const p of sub.parameters) {
|
|
745
|
+
systemPrompt += ` ${p.name}="${p.example || "string"}"`;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
let example = sub.meta?.body?.example || "";
|
|
749
|
+
example = example.replace(/"/g, '"').replace(/:/g, ":");
|
|
750
|
+
systemPrompt += ">" + example + "</" + sub.name + ">";
|
|
751
|
+
}
|
|
752
|
+
currentUserPrompt = systemPrompt + "\n\nUser request: " + userPrompt;
|
|
753
|
+
if (session.debug || process.env.DIRAC_LOG_PROMPT === "1") {
|
|
754
|
+
console.error("[LLM] Continuing dialog with updated subroutines\n");
|
|
755
|
+
}
|
|
756
|
+
} else {
|
|
757
|
+
systemPrompt = `Dirac is a XML-based language. To define a subroutine with parameters:
|
|
758
|
+
|
|
627
759
|
\`\`\`xml
|
|
628
|
-
<subroutine name=
|
|
629
|
-
|
|
760
|
+
<subroutine name="greet" param-name="string">
|
|
761
|
+
<!-- param-name defines a parameter called "name" -->
|
|
762
|
+
<!-- Access it inside using: <variable name="name"/> -->
|
|
763
|
+
<output>Hello, <variable name="name"/>!</output>
|
|
630
764
|
</subroutine>
|
|
631
765
|
\`\`\`
|
|
632
|
-
|
|
766
|
+
|
|
767
|
+
To call it:
|
|
633
768
|
\`\`\`xml
|
|
634
|
-
<
|
|
769
|
+
<greet name="Alice" />
|
|
770
|
+
<!-- Use just the parameter name (name), NOT param-name -->
|
|
635
771
|
\`\`\`
|
|
772
|
+
|
|
773
|
+
CRITICAL: When defining parameters:
|
|
774
|
+
- Use param-NAME="type" format where NAME is the parameter's name
|
|
775
|
+
- Example: param-username="string" means parameter is called "username"
|
|
776
|
+
- Inside the subroutine, access with: <variable name="username"/>
|
|
777
|
+
- When calling: <mytag username="John" /> (use parameter name directly)
|
|
636
778
|
`;
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
779
|
+
systemPrompt += "Now, You are an expert Dirac XML code generator.\nAllowed Dirac XML tags (use ONLY these tags):";
|
|
780
|
+
for (const sub of subroutines) {
|
|
781
|
+
systemPrompt += `
|
|
640
782
|
- ${sub.name} : ${sub.description || ""}`;
|
|
641
|
-
|
|
783
|
+
systemPrompt += `
|
|
642
784
|
Ex: <${sub.name}`;
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
785
|
+
if (sub.parameters && sub.parameters.length > 0) {
|
|
786
|
+
for (const p of sub.parameters) {
|
|
787
|
+
systemPrompt += ` ${p.name}="${p.example || "string"}"`;
|
|
788
|
+
}
|
|
646
789
|
}
|
|
790
|
+
let example = sub.meta?.body?.example || "";
|
|
791
|
+
example = example.replace(/"/g, '"').replace(/:/g, ":");
|
|
792
|
+
systemPrompt += ">" + example + "</" + sub.name + ">";
|
|
793
|
+
}
|
|
794
|
+
systemPrompt += "\n\nIMPORTANT INSTRUCTIONS:";
|
|
795
|
+
systemPrompt += "\n1. Output ONLY valid XML tags from the list above";
|
|
796
|
+
systemPrompt += "\n2. Do NOT include any explanations, descriptions, or extra text";
|
|
797
|
+
systemPrompt += "\n3. Do NOT use bullet points or formatting - just pure XML";
|
|
798
|
+
systemPrompt += "\n4. Do NOT invent tags - only use tags from the list above";
|
|
799
|
+
systemPrompt += "\n5. Start your response directly with the XML tag (e.g., <add ...>)";
|
|
800
|
+
systemPrompt += "\n\nDouble-check: Does your response contain ONLY XML tags? If not, remove all non-XML text.";
|
|
801
|
+
if (dialogHistory.length === 0) {
|
|
802
|
+
dialogHistory.push({ role: "system", content: systemPrompt });
|
|
803
|
+
}
|
|
804
|
+
currentUserPrompt = userPrompt;
|
|
805
|
+
if (session.debug || process.env.DIRAC_LOG_PROMPT === "1") {
|
|
806
|
+
console.error("[LLM] First call - sending full system prompt\n");
|
|
647
807
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
}
|
|
652
|
-
systemPrompt += "\n\nIMPORTANT INSTRUCTIONS:";
|
|
653
|
-
systemPrompt += "\n1. Output ONLY valid XML tags from the list above";
|
|
654
|
-
systemPrompt += "\n2. Do NOT include any explanations, descriptions, or extra text";
|
|
655
|
-
systemPrompt += "\n3. Do NOT use bullet points or formatting - just pure XML";
|
|
656
|
-
systemPrompt += "\n4. Do NOT invent tags - only use tags from the list above";
|
|
657
|
-
systemPrompt += "\n5. Start your response directly with the XML tag (e.g., <add ...>)";
|
|
658
|
-
systemPrompt += "\n\nDouble-check: Does your response contain ONLY XML tags? If not, remove all non-XML text.";
|
|
659
|
-
prompt = systemPrompt + "\nUser: " + userPrompt + "\nOutput:";
|
|
660
|
-
if (session.debug || process.env.DIRAC_LOG_PROMPT === "1") {
|
|
661
|
-
console.error("[LLM] Full prompt sent to LLM:\n" + prompt + "\n");
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
dialogHistory.push({ role: "user", content: noExtra ? userPrompt : prompt });
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
dialogHistory.push({ role: "user", content: currentUserPrompt });
|
|
665
811
|
if (session.debug) {
|
|
666
|
-
console.error(`[LLM] Calling ${model}
|
|
812
|
+
console.error(`[LLM] Calling ${model}`);
|
|
667
813
|
console.error(`[LLM] Dialog history length: ${dialogHistory.length} messages`);
|
|
814
|
+
console.error(`[LLM] Has existing dialog: ${hasExistingDialog}`);
|
|
668
815
|
}
|
|
669
816
|
try {
|
|
670
817
|
let result;
|
|
@@ -692,21 +839,21 @@ then you call it like
|
|
|
692
839
|
messages: dialogHistory
|
|
693
840
|
});
|
|
694
841
|
} else {
|
|
695
|
-
|
|
696
|
-
model,
|
|
697
|
-
max_tokens: maxTokens,
|
|
698
|
-
temperature,
|
|
699
|
-
messages: dialogHistory
|
|
700
|
-
});
|
|
701
|
-
const content = response.content[0];
|
|
702
|
-
result = content.type === "text" ? content.text : "";
|
|
842
|
+
result = await callAnthropic(session.llmClient, model, maxTokens, temperature, dialogHistory);
|
|
703
843
|
}
|
|
704
844
|
if (session.debug) {
|
|
705
845
|
console.error(`[LLM] Response length: ${result.length}`);
|
|
846
|
+
console.error(`[LLM] Generated code:
|
|
847
|
+
${result}
|
|
848
|
+
`);
|
|
706
849
|
}
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
850
|
+
dialogHistory.push({ role: "assistant", content: result });
|
|
851
|
+
const varName = contextVar || (saveDialog ? "__llm_dialog__" : null);
|
|
852
|
+
if (varName) {
|
|
853
|
+
if (session.debug) {
|
|
854
|
+
console.error(`[LLM] Saving dialog history (${dialogHistory.length} messages) to: ${varName}`);
|
|
855
|
+
}
|
|
856
|
+
setVariable(session, varName, dialogHistory, true);
|
|
710
857
|
}
|
|
711
858
|
if (outputVar) {
|
|
712
859
|
setVariable(session, outputVar, result, false);
|
|
@@ -788,18 +935,13 @@ Please fix these errors and generate valid Dirac XML again. Remember to only use
|
|
|
788
935
|
messages: dialogHistory
|
|
789
936
|
});
|
|
790
937
|
} else {
|
|
791
|
-
|
|
792
|
-
model,
|
|
793
|
-
max_tokens: maxTokens,
|
|
794
|
-
temperature,
|
|
795
|
-
messages: dialogHistory
|
|
796
|
-
});
|
|
797
|
-
const content = response.content[0];
|
|
798
|
-
result = content.type === "text" ? content.text : "";
|
|
938
|
+
result = await callAnthropic(session.llmClient, model, maxTokens, temperature, dialogHistory);
|
|
799
939
|
}
|
|
800
940
|
dialogHistory.push({ role: "assistant", content: result });
|
|
801
941
|
if (contextVar) {
|
|
802
942
|
setVariable(session, contextVar, dialogHistory, true);
|
|
943
|
+
} else if (saveDialog) {
|
|
944
|
+
setVariable(session, "__llm_dialog__", dialogHistory, true);
|
|
803
945
|
}
|
|
804
946
|
if (session.debug) {
|
|
805
947
|
console.error(`[LLM] Retry ${retryCount} response:
|
|
@@ -832,6 +974,9 @@ ${validation.errorMessages.join("\n")}`);
|
|
|
832
974
|
}
|
|
833
975
|
}
|
|
834
976
|
await integrate(session, dynamicAST);
|
|
977
|
+
if (iteration === 1) {
|
|
978
|
+
dumpGeneratedSubroutines(session, diracCode, userPrompt);
|
|
979
|
+
}
|
|
835
980
|
if (feedbackMode) {
|
|
836
981
|
const outputAfter = session.output.slice();
|
|
837
982
|
const executionOutput = outputAfter.slice(outputBefore.length).join("");
|
|
@@ -876,18 +1021,13 @@ ${feedbackPrompt}
|
|
|
876
1021
|
messages: dialogHistory
|
|
877
1022
|
});
|
|
878
1023
|
} else {
|
|
879
|
-
|
|
880
|
-
model,
|
|
881
|
-
max_tokens: maxTokens,
|
|
882
|
-
temperature,
|
|
883
|
-
messages: dialogHistory
|
|
884
|
-
});
|
|
885
|
-
const content = response.content[0];
|
|
886
|
-
result = content.type === "text" ? content.text : "";
|
|
1024
|
+
result = await callAnthropic(session.llmClient, model, maxTokens, temperature, dialogHistory);
|
|
887
1025
|
}
|
|
888
1026
|
dialogHistory.push({ role: "assistant", content: result });
|
|
889
1027
|
if (contextVar) {
|
|
890
1028
|
setVariable(session, contextVar, dialogHistory, true);
|
|
1029
|
+
} else if (saveDialog) {
|
|
1030
|
+
setVariable(session, "__llm_dialog__", dialogHistory, true);
|
|
891
1031
|
}
|
|
892
1032
|
if (session.debug) {
|
|
893
1033
|
console.error(`[LLM] Feedback response:
|
|
@@ -945,11 +1085,11 @@ ${expr}
|
|
|
945
1085
|
for (const v of session.variables) {
|
|
946
1086
|
context[v.name] = v.value;
|
|
947
1087
|
}
|
|
948
|
-
const { default:
|
|
949
|
-
const { default:
|
|
1088
|
+
const { default: fs6 } = await import("fs");
|
|
1089
|
+
const { default: path4 } = await import("path");
|
|
950
1090
|
const { fileURLToPath } = await import("url");
|
|
951
|
-
context.fs =
|
|
952
|
-
context.path =
|
|
1091
|
+
context.fs = fs6;
|
|
1092
|
+
context.path = path4;
|
|
953
1093
|
context.__dirname = process.cwd();
|
|
954
1094
|
context.getParams = () => {
|
|
955
1095
|
const params = session.parameterStack[session.parameterStack.length - 1];
|
|
@@ -1003,8 +1143,8 @@ ${diracCode}
|
|
|
1003
1143
|
}
|
|
1004
1144
|
|
|
1005
1145
|
// src/tags/import.ts
|
|
1006
|
-
import { readFileSync, existsSync as
|
|
1007
|
-
import { resolve, dirname as dirname2, join } from "path";
|
|
1146
|
+
import { readFileSync, existsSync as existsSync3 } from "fs";
|
|
1147
|
+
import { resolve, dirname as dirname2, join as join2 } from "path";
|
|
1008
1148
|
function resolveImportPath(src, currentDir) {
|
|
1009
1149
|
if (src.startsWith("./") || src.startsWith("../") || src.startsWith("/")) {
|
|
1010
1150
|
const resolved2 = resolve(currentDir, src);
|
|
@@ -1012,26 +1152,26 @@ function resolveImportPath(src, currentDir) {
|
|
|
1012
1152
|
}
|
|
1013
1153
|
let searchDir = currentDir;
|
|
1014
1154
|
while (true) {
|
|
1015
|
-
const nodeModulesPath =
|
|
1016
|
-
if (
|
|
1017
|
-
const packageJsonPath =
|
|
1018
|
-
if (
|
|
1155
|
+
const nodeModulesPath = join2(searchDir, "node_modules", src);
|
|
1156
|
+
if (existsSync3(nodeModulesPath)) {
|
|
1157
|
+
const packageJsonPath = join2(nodeModulesPath, "package.json");
|
|
1158
|
+
if (existsSync3(packageJsonPath)) {
|
|
1019
1159
|
try {
|
|
1020
1160
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
1021
1161
|
const mainFile = packageJson.main || "lib/index.di";
|
|
1022
|
-
const entryPath =
|
|
1023
|
-
if (
|
|
1162
|
+
const entryPath = join2(nodeModulesPath, mainFile);
|
|
1163
|
+
if (existsSync3(entryPath)) {
|
|
1024
1164
|
return entryPath;
|
|
1025
1165
|
}
|
|
1026
1166
|
} catch (err) {
|
|
1027
1167
|
}
|
|
1028
1168
|
}
|
|
1029
1169
|
const fallbacks = [
|
|
1030
|
-
|
|
1031
|
-
|
|
1170
|
+
join2(nodeModulesPath, "lib", "index.di"),
|
|
1171
|
+
join2(nodeModulesPath, "index.di")
|
|
1032
1172
|
];
|
|
1033
1173
|
for (const fallback of fallbacks) {
|
|
1034
|
-
if (
|
|
1174
|
+
if (existsSync3(fallback)) {
|
|
1035
1175
|
return fallback;
|
|
1036
1176
|
}
|
|
1037
1177
|
}
|
|
@@ -1252,13 +1392,13 @@ async function executeRequireModule(session, element) {
|
|
|
1252
1392
|
}
|
|
1253
1393
|
|
|
1254
1394
|
// src/tags/tag-check.ts
|
|
1255
|
-
import
|
|
1395
|
+
import fs3 from "fs";
|
|
1256
1396
|
import yaml from "js-yaml";
|
|
1257
1397
|
var SIMILARITY_CUTOFF = 0.75;
|
|
1258
1398
|
function getEmbeddingServerConfig() {
|
|
1259
1399
|
try {
|
|
1260
1400
|
const configPath = process.env.DIRAC_CONFIG || "config.yml";
|
|
1261
|
-
const config = yaml.load(
|
|
1401
|
+
const config = yaml.load(fs3.readFileSync(configPath, "utf8"));
|
|
1262
1402
|
const host = config.embeddingServer?.host || "localhost";
|
|
1263
1403
|
const port = config.embeddingServer?.port || 11434;
|
|
1264
1404
|
const model = config.embeddingServer?.model || "embeddinggemma";
|
|
@@ -1394,7 +1534,7 @@ async function executeTagCheck(session, element) {
|
|
|
1394
1534
|
const executeTag = correctedTag || tagName;
|
|
1395
1535
|
console.error(`[tag-check] Executing <${executeTag}/> as all checks passed and execute=true.`);
|
|
1396
1536
|
const elementToExecute = correctedTag ? { ...child, tag: correctedTag } : child;
|
|
1397
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
1537
|
+
const { integrate: integrate2 } = await import("./interpreter-XH3RFKVP.js");
|
|
1398
1538
|
await integrate2(session, elementToExecute);
|
|
1399
1539
|
}
|
|
1400
1540
|
}
|
|
@@ -1403,7 +1543,7 @@ async function executeTagCheck(session, element) {
|
|
|
1403
1543
|
// src/tags/throw.ts
|
|
1404
1544
|
async function executeThrow(session, element) {
|
|
1405
1545
|
const exceptionName = element.attributes?.name || "exception";
|
|
1406
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1546
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-XH3RFKVP.js");
|
|
1407
1547
|
const exceptionDom = {
|
|
1408
1548
|
tag: "exception-content",
|
|
1409
1549
|
attributes: { name: exceptionName },
|
|
@@ -1416,7 +1556,7 @@ async function executeThrow(session, element) {
|
|
|
1416
1556
|
// src/tags/try.ts
|
|
1417
1557
|
async function executeTry(session, element) {
|
|
1418
1558
|
setExceptionBoundary(session);
|
|
1419
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1559
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-XH3RFKVP.js");
|
|
1420
1560
|
await integrateChildren2(session, element);
|
|
1421
1561
|
unsetExceptionBoundary(session);
|
|
1422
1562
|
}
|
|
@@ -1426,7 +1566,7 @@ async function executeCatch(session, element) {
|
|
|
1426
1566
|
const exceptionName = element.attributes?.name || "exception";
|
|
1427
1567
|
const caughtCount = lookupException(session, exceptionName);
|
|
1428
1568
|
if (caughtCount > 0) {
|
|
1429
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1569
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-XH3RFKVP.js");
|
|
1430
1570
|
await integrateChildren2(session, element);
|
|
1431
1571
|
}
|
|
1432
1572
|
flushCurrentException(session);
|
|
@@ -1435,7 +1575,7 @@ async function executeCatch(session, element) {
|
|
|
1435
1575
|
// src/tags/exception.ts
|
|
1436
1576
|
async function executeException(session, element) {
|
|
1437
1577
|
const exceptions = getCurrentExceptions(session);
|
|
1438
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1578
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-XH3RFKVP.js");
|
|
1439
1579
|
for (const exceptionDom of exceptions) {
|
|
1440
1580
|
await integrateChildren2(session, exceptionDom);
|
|
1441
1581
|
}
|
|
@@ -1630,23 +1770,23 @@ function formatAsText(subroutines) {
|
|
|
1630
1770
|
}
|
|
1631
1771
|
|
|
1632
1772
|
// src/runtime/subroutine-registry.ts
|
|
1633
|
-
import * as
|
|
1634
|
-
import * as
|
|
1635
|
-
import * as
|
|
1773
|
+
import * as fs4 from "fs";
|
|
1774
|
+
import * as path3 from "path";
|
|
1775
|
+
import * as os2 from "os";
|
|
1636
1776
|
var SubroutineRegistry = class {
|
|
1637
1777
|
indexPath;
|
|
1638
1778
|
index;
|
|
1639
1779
|
constructor(indexPath) {
|
|
1640
|
-
this.indexPath = indexPath ||
|
|
1780
|
+
this.indexPath = indexPath || path3.join(os2.homedir(), ".dirac", "subroutine-index.json");
|
|
1641
1781
|
this.index = this.loadIndex();
|
|
1642
1782
|
}
|
|
1643
1783
|
/**
|
|
1644
1784
|
* Load index from disk
|
|
1645
1785
|
*/
|
|
1646
1786
|
loadIndex() {
|
|
1647
|
-
if (
|
|
1787
|
+
if (fs4.existsSync(this.indexPath)) {
|
|
1648
1788
|
try {
|
|
1649
|
-
const data =
|
|
1789
|
+
const data = fs4.readFileSync(this.indexPath, "utf-8");
|
|
1650
1790
|
return JSON.parse(data);
|
|
1651
1791
|
} catch (err) {
|
|
1652
1792
|
console.error("Error loading subroutine index:", err);
|
|
@@ -1661,12 +1801,12 @@ var SubroutineRegistry = class {
|
|
|
1661
1801
|
* Save index to disk
|
|
1662
1802
|
*/
|
|
1663
1803
|
saveIndex() {
|
|
1664
|
-
const dir =
|
|
1665
|
-
if (!
|
|
1666
|
-
|
|
1804
|
+
const dir = path3.dirname(this.indexPath);
|
|
1805
|
+
if (!fs4.existsSync(dir)) {
|
|
1806
|
+
fs4.mkdirSync(dir, { recursive: true });
|
|
1667
1807
|
}
|
|
1668
1808
|
this.index.lastUpdated = Date.now();
|
|
1669
|
-
|
|
1809
|
+
fs4.writeFileSync(this.indexPath, JSON.stringify(this.index, null, 2), "utf-8");
|
|
1670
1810
|
}
|
|
1671
1811
|
/**
|
|
1672
1812
|
* Scan a directory for .di files and index all subroutines
|
|
@@ -1674,9 +1814,9 @@ var SubroutineRegistry = class {
|
|
|
1674
1814
|
async indexDirectory(dirPath) {
|
|
1675
1815
|
let count = 0;
|
|
1676
1816
|
const scanDir = (dir) => {
|
|
1677
|
-
const entries =
|
|
1817
|
+
const entries = fs4.readdirSync(dir, { withFileTypes: true });
|
|
1678
1818
|
for (const entry of entries) {
|
|
1679
|
-
const fullPath =
|
|
1819
|
+
const fullPath = path3.join(dir, entry.name);
|
|
1680
1820
|
if (entry.isDirectory()) {
|
|
1681
1821
|
scanDir(fullPath);
|
|
1682
1822
|
} else if (entry.isFile() && entry.name.endsWith(".di")) {
|
|
@@ -1693,7 +1833,7 @@ var SubroutineRegistry = class {
|
|
|
1693
1833
|
*/
|
|
1694
1834
|
indexFile(filePath) {
|
|
1695
1835
|
try {
|
|
1696
|
-
const content =
|
|
1836
|
+
const content = fs4.readFileSync(filePath, "utf-8");
|
|
1697
1837
|
const parser = new DiracParser();
|
|
1698
1838
|
const ast = parser.parse(content);
|
|
1699
1839
|
this.index.subroutines = this.index.subroutines.filter((s) => s.filePath !== filePath);
|
|
@@ -1898,7 +2038,7 @@ async function executeLoadContext(session, element) {
|
|
|
1898
2038
|
query = element.text.trim();
|
|
1899
2039
|
}
|
|
1900
2040
|
if (!query && element.children.length > 0) {
|
|
1901
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
2041
|
+
const { integrate: integrate2 } = await import("./interpreter-XH3RFKVP.js");
|
|
1902
2042
|
const beforeOutput = session.output.length;
|
|
1903
2043
|
for (const child of element.children) {
|
|
1904
2044
|
await integrate2(session, child);
|
|
@@ -1973,18 +2113,17 @@ async function executeLoadContext(session, element) {
|
|
|
1973
2113
|
}
|
|
1974
2114
|
|
|
1975
2115
|
// src/tags/save-subroutine.ts
|
|
1976
|
-
import { writeFileSync as
|
|
1977
|
-
import { resolve as resolve2, dirname as dirname4 } from "path";
|
|
2116
|
+
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, existsSync as existsSync5 } from "fs";
|
|
2117
|
+
import { resolve as resolve2, dirname as dirname4, join as join4 } from "path";
|
|
2118
|
+
import { homedir as homedir3 } from "os";
|
|
1978
2119
|
async function executeSaveSubroutine(session, element) {
|
|
1979
2120
|
const name = element.attributes.name;
|
|
1980
2121
|
const file = element.attributes.file;
|
|
2122
|
+
const pathAttr = element.attributes.path;
|
|
1981
2123
|
const format = element.attributes.format || "xml";
|
|
1982
2124
|
if (!name) {
|
|
1983
2125
|
throw new Error("<save-subroutine> requires name attribute");
|
|
1984
2126
|
}
|
|
1985
|
-
if (!file) {
|
|
1986
|
-
throw new Error("<save-subroutine> requires file attribute");
|
|
1987
|
-
}
|
|
1988
2127
|
let subroutine = void 0;
|
|
1989
2128
|
for (let i = session.subroutines.length - 1; i >= 0; i--) {
|
|
1990
2129
|
if (session.subroutines[i].name === name) {
|
|
@@ -2001,12 +2140,27 @@ async function executeSaveSubroutine(session, element) {
|
|
|
2001
2140
|
} else {
|
|
2002
2141
|
content = generateXMLNotation(subroutine);
|
|
2003
2142
|
}
|
|
2004
|
-
|
|
2143
|
+
let filePath;
|
|
2144
|
+
if (file) {
|
|
2145
|
+
filePath = resolve2(process.cwd(), file);
|
|
2146
|
+
} else if (pathAttr) {
|
|
2147
|
+
const targetDir = join4(homedir3(), ".dirac", "lib", pathAttr);
|
|
2148
|
+
filePath = join4(targetDir, `${name}.di`);
|
|
2149
|
+
} else {
|
|
2150
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, -5);
|
|
2151
|
+
const defaultDir = join4(homedir3(), ".dirac", "lib", timestamp);
|
|
2152
|
+
filePath = join4(defaultDir, `${name}.di`);
|
|
2153
|
+
}
|
|
2005
2154
|
const dir = dirname4(filePath);
|
|
2006
|
-
|
|
2007
|
-
|
|
2155
|
+
if (!existsSync5(dir)) {
|
|
2156
|
+
mkdirSync4(dir, { recursive: true });
|
|
2157
|
+
}
|
|
2158
|
+
writeFileSync3(filePath, content, "utf-8");
|
|
2008
2159
|
emit(session, `Subroutine '${name}' saved to: ${filePath}
|
|
2009
2160
|
`);
|
|
2161
|
+
if (session.debug) {
|
|
2162
|
+
console.error(`[save-subroutine] Saved '${name}' to: ${filePath}`);
|
|
2163
|
+
}
|
|
2010
2164
|
}
|
|
2011
2165
|
function generateXMLNotation(subroutine) {
|
|
2012
2166
|
let xml = "<!-- Exported subroutine -->\n\n";
|
|
@@ -2137,7 +2291,7 @@ async function executeForeach(session, element) {
|
|
|
2137
2291
|
const parser2 = new DiracParser2();
|
|
2138
2292
|
try {
|
|
2139
2293
|
const fromElement = parser2.parse(fromAttr);
|
|
2140
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
2294
|
+
const { integrate: integrate2 } = await import("./interpreter-XH3RFKVP.js");
|
|
2141
2295
|
await integrate2(session, fromElement);
|
|
2142
2296
|
} catch (e) {
|
|
2143
2297
|
session.output = savedOutput;
|
|
@@ -2285,7 +2439,7 @@ async function executeEnvironment(session, element) {
|
|
|
2285
2439
|
}
|
|
2286
2440
|
|
|
2287
2441
|
// src/tags/input.ts
|
|
2288
|
-
import * as
|
|
2442
|
+
import * as fs5 from "fs";
|
|
2289
2443
|
import * as readline from "readline";
|
|
2290
2444
|
var fileReaders = /* @__PURE__ */ new Map();
|
|
2291
2445
|
var fileIterators = /* @__PURE__ */ new Map();
|
|
@@ -2309,11 +2463,11 @@ async function executeInput(session, element) {
|
|
|
2309
2463
|
throw new Error(`<input> invalid mode: ${mode}. Use 'all' or 'line'`);
|
|
2310
2464
|
}
|
|
2311
2465
|
} else if (source === "file") {
|
|
2312
|
-
const
|
|
2466
|
+
const path4 = substituteAttribute(session, pathAttr);
|
|
2313
2467
|
if (mode === "all") {
|
|
2314
|
-
value =
|
|
2468
|
+
value = fs5.readFileSync(path4, "utf-8");
|
|
2315
2469
|
} else if (mode === "line") {
|
|
2316
|
-
value = await readLineFromFile(
|
|
2470
|
+
value = await readLineFromFile(path4);
|
|
2317
2471
|
} else {
|
|
2318
2472
|
throw new Error(`<input> invalid mode: ${mode}. Use 'all' or 'line'`);
|
|
2319
2473
|
}
|
|
@@ -2370,23 +2524,23 @@ async function readLineStdin() {
|
|
|
2370
2524
|
}
|
|
2371
2525
|
return result.value;
|
|
2372
2526
|
}
|
|
2373
|
-
async function readLineFromFile(
|
|
2374
|
-
if (!fileReaders.has(
|
|
2375
|
-
const fileStream =
|
|
2527
|
+
async function readLineFromFile(path4) {
|
|
2528
|
+
if (!fileReaders.has(path4)) {
|
|
2529
|
+
const fileStream = fs5.createReadStream(path4);
|
|
2376
2530
|
const rl = readline.createInterface({
|
|
2377
2531
|
input: fileStream,
|
|
2378
2532
|
crlfDelay: Infinity
|
|
2379
2533
|
});
|
|
2380
|
-
fileReaders.set(
|
|
2381
|
-
fileIterators.set(
|
|
2534
|
+
fileReaders.set(path4, rl);
|
|
2535
|
+
fileIterators.set(path4, rl[Symbol.asyncIterator]());
|
|
2382
2536
|
}
|
|
2383
|
-
const iterator = fileIterators.get(
|
|
2537
|
+
const iterator = fileIterators.get(path4);
|
|
2384
2538
|
const result = await iterator.next();
|
|
2385
2539
|
if (result.done) {
|
|
2386
|
-
const reader = fileReaders.get(
|
|
2540
|
+
const reader = fileReaders.get(path4);
|
|
2387
2541
|
reader.close();
|
|
2388
|
-
fileReaders.delete(
|
|
2389
|
-
fileIterators.delete(
|
|
2542
|
+
fileReaders.delete(path4);
|
|
2543
|
+
fileIterators.delete(path4);
|
|
2390
2544
|
return "";
|
|
2391
2545
|
}
|
|
2392
2546
|
return result.value;
|
package/dist/cli.js
CHANGED
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
} from "./chunk-UEFKQRYN.js";
|
|
5
5
|
import {
|
|
6
6
|
execute
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-TISVDOGD.js";
|
|
8
|
+
import "./chunk-TXL3RV74.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.46",
|
|
20
20
|
description: "LLM-Augmented Declarative Execution",
|
|
21
21
|
type: "module",
|
|
22
22
|
main: "dist/index.js",
|
|
@@ -96,7 +96,7 @@ async function main() {
|
|
|
96
96
|
process.exit(0);
|
|
97
97
|
}
|
|
98
98
|
if (args[0] === "shell") {
|
|
99
|
-
const { DiracShell } = await import("./shell-
|
|
99
|
+
const { DiracShell } = await import("./shell-LGNPK4GO.js");
|
|
100
100
|
const shellConfig = { debug: false };
|
|
101
101
|
for (let i = 1; i < args.length; i++) {
|
|
102
102
|
const arg = args[i];
|
|
@@ -142,6 +142,9 @@ async function main() {
|
|
|
142
142
|
let filePath;
|
|
143
143
|
let emitXml = false;
|
|
144
144
|
let configFile;
|
|
145
|
+
if (process.env.DEBUG === "1") {
|
|
146
|
+
config.debug = true;
|
|
147
|
+
}
|
|
145
148
|
for (let i = 0; i < args.length; i++) {
|
|
146
149
|
const arg = args[i];
|
|
147
150
|
if (arg === "--debug") {
|
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-TISVDOGD.js";
|
|
6
6
|
import {
|
|
7
7
|
integrate
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-TXL3RV74.js";
|
|
9
9
|
import {
|
|
10
10
|
DiracParser
|
|
11
11
|
} from "./chunk-HRHAMPOB.js";
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-UEFKQRYN.js";
|
|
5
5
|
import {
|
|
6
6
|
integrate
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-TXL3RV74.js";
|
|
8
8
|
import {
|
|
9
9
|
DiracParser
|
|
10
10
|
} from "./chunk-HRHAMPOB.js";
|
|
@@ -66,7 +66,7 @@ var DiracShell = class {
|
|
|
66
66
|
});
|
|
67
67
|
this.rl.on("close", () => {
|
|
68
68
|
this.saveHistory();
|
|
69
|
-
import("./schedule-
|
|
69
|
+
import("./schedule-5HZCREEP.js").then(({ stopAllScheduledTasks }) => {
|
|
70
70
|
stopAllScheduledTasks();
|
|
71
71
|
console.log("\nGoodbye!");
|
|
72
72
|
process.exit(0);
|
|
@@ -195,7 +195,7 @@ Commands:
|
|
|
195
195
|
:index <path> Index subroutines from directory
|
|
196
196
|
:search <query> Search indexed subroutines
|
|
197
197
|
:load <query> Load context (search and import subroutines)
|
|
198
|
-
:save <name>
|
|
198
|
+
:save <name> [file] Save subroutine (default: ~/.dirac/lib/TIMESTAMP/name.di)
|
|
199
199
|
:stats Show registry statistics
|
|
200
200
|
:tasks List all scheduled tasks
|
|
201
201
|
:stop <name> Stop a scheduled task
|
|
@@ -335,13 +335,27 @@ Examples:
|
|
|
335
335
|
}
|
|
336
336
|
break;
|
|
337
337
|
case "save":
|
|
338
|
-
if (args.length
|
|
339
|
-
console.log("Usage: :save <subroutine-name>
|
|
338
|
+
if (args.length === 0) {
|
|
339
|
+
console.log("Usage: :save <subroutine-name> [file]");
|
|
340
|
+
console.log(" If file is omitted, saves to ~/.dirac/lib/TIMESTAMP/NAME.di");
|
|
341
|
+
console.log("Examples:");
|
|
342
|
+
console.log(" :save greet # saves to ~/.dirac/lib/TIMESTAMP/greet.di");
|
|
343
|
+
console.log(" :save greet ./my-lib/greet.di # saves to specific file");
|
|
344
|
+
console.log(" :save greet utils # saves to ~/.dirac/lib/utils/greet.di");
|
|
340
345
|
} else {
|
|
341
346
|
const subName = args[0];
|
|
342
|
-
const fileName = args[1];
|
|
347
|
+
const fileName = args.length > 1 ? args[1] : void 0;
|
|
343
348
|
try {
|
|
344
|
-
|
|
349
|
+
let xml;
|
|
350
|
+
if (fileName) {
|
|
351
|
+
if (fileName.includes("/") || fileName.includes(".di")) {
|
|
352
|
+
xml = `<save-subroutine name="${subName}" file="${fileName}" format="xml" />`;
|
|
353
|
+
} else {
|
|
354
|
+
xml = `<save-subroutine name="${subName}" path="${fileName}" format="xml" />`;
|
|
355
|
+
}
|
|
356
|
+
} else {
|
|
357
|
+
xml = `<save-subroutine name="${subName}" format="xml" />`;
|
|
358
|
+
}
|
|
345
359
|
const ast = this.xmlParser.parse(xml);
|
|
346
360
|
await integrate(this.session, ast);
|
|
347
361
|
if (this.session.output.length > 0) {
|
|
@@ -366,7 +380,7 @@ Examples:
|
|
|
366
380
|
break;
|
|
367
381
|
case "tasks":
|
|
368
382
|
try {
|
|
369
|
-
const { listScheduledTasks } = await import("./schedule-
|
|
383
|
+
const { listScheduledTasks } = await import("./schedule-5HZCREEP.js");
|
|
370
384
|
const tasks = listScheduledTasks();
|
|
371
385
|
if (tasks.length === 0) {
|
|
372
386
|
console.log("No scheduled tasks running.");
|
|
@@ -385,7 +399,7 @@ Examples:
|
|
|
385
399
|
console.log("Usage: :stop <task-name>");
|
|
386
400
|
} else {
|
|
387
401
|
try {
|
|
388
|
-
const { stopScheduledTask } = await import("./schedule-
|
|
402
|
+
const { stopScheduledTask } = await import("./schedule-5HZCREEP.js");
|
|
389
403
|
const taskName = args[0];
|
|
390
404
|
const stopped = stopScheduledTask(taskName);
|
|
391
405
|
if (stopped) {
|
|
@@ -400,7 +414,7 @@ Examples:
|
|
|
400
414
|
break;
|
|
401
415
|
case "stopall":
|
|
402
416
|
try {
|
|
403
|
-
const { stopAllScheduledTasks } = await import("./schedule-
|
|
417
|
+
const { stopAllScheduledTasks } = await import("./schedule-5HZCREEP.js");
|
|
404
418
|
stopAllScheduledTasks();
|
|
405
419
|
console.log("All scheduled tasks stopped.");
|
|
406
420
|
} catch (error) {
|
package/dist/test-runner.js
CHANGED