dirac-lang 0.1.33 → 0.1.35

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.
@@ -0,0 +1,166 @@
1
+ // src/runtime/braket-parser.ts
2
+ var BraKetParser = class {
3
+ lines = [];
4
+ currentLine = 0;
5
+ /**
6
+ * Parse bra-ket notation and compile to XML
7
+ */
8
+ parse(source) {
9
+ this.lines = source.split("\n");
10
+ this.currentLine = 0;
11
+ const xml = ["<dirac>"];
12
+ this.parseBlock(xml, -1);
13
+ xml.push("</dirac>");
14
+ return xml.join("\n");
15
+ }
16
+ /**
17
+ * Parse a block of lines at a given indentation level
18
+ */
19
+ parseBlock(output, parentIndent) {
20
+ while (this.currentLine < this.lines.length) {
21
+ const line = this.parseLine(this.lines[this.currentLine]);
22
+ if (line.type === "empty") {
23
+ this.currentLine++;
24
+ continue;
25
+ }
26
+ if (line.indent <= parentIndent) {
27
+ break;
28
+ }
29
+ if (line.type === "bra") {
30
+ const attrs = line.attrs ? ` ${this.convertAttributes(line.attrs)}` : "";
31
+ output.push(`${" ".repeat(line.indent)}<subroutine name="${line.tag}"${attrs}>`);
32
+ this.currentLine++;
33
+ this.parseBlock(output, line.indent);
34
+ output.push(`${" ".repeat(line.indent)}</subroutine>`);
35
+ continue;
36
+ }
37
+ if (line.type === "ket") {
38
+ const indent = " ".repeat(line.indent);
39
+ const attrs = line.attrs ? ` ${this.convertAttributes(line.attrs)}` : "";
40
+ const nextLine = this.currentLine + 1 < this.lines.length ? this.parseLine(this.lines[this.currentLine + 1]) : null;
41
+ if (nextLine && nextLine.indent > line.indent && nextLine.type !== "empty") {
42
+ output.push(`${indent}<${line.tag}${attrs}>`);
43
+ this.currentLine++;
44
+ this.parseBlock(output, line.indent);
45
+ output.push(`${indent}</${line.tag}>`);
46
+ } else {
47
+ if (line.text) {
48
+ const content = this.convertInlineKets(line.text);
49
+ output.push(`${indent}<${line.tag}${attrs}>${content}</${line.tag}>`);
50
+ } else {
51
+ output.push(`${indent}<${line.tag}${attrs}/>`);
52
+ }
53
+ this.currentLine++;
54
+ }
55
+ continue;
56
+ }
57
+ if (line.type === "text") {
58
+ const indent = " ".repeat(line.indent);
59
+ const content = this.convertInlineKets(line.text || "");
60
+ output.push(`${indent}${content}`);
61
+ this.currentLine++;
62
+ continue;
63
+ }
64
+ }
65
+ }
66
+ /**
67
+ * Parse a single line into structured form
68
+ */
69
+ parseLine(raw) {
70
+ const match = raw.match(/^(\s*)(.*)/);
71
+ const indent = match ? Math.floor(match[1].length / 2) : 0;
72
+ const content = match ? match[2] : "";
73
+ if (!content.trim()) {
74
+ return { indent, type: "empty", raw };
75
+ }
76
+ const braMatch = content.match(/^<([a-zA-Z_][a-zA-Z0-9_-]*)\s*([^|]*)\|$/);
77
+ if (braMatch) {
78
+ return {
79
+ indent,
80
+ type: "bra",
81
+ tag: braMatch[1],
82
+ attrs: braMatch[2].trim() || void 0,
83
+ raw
84
+ };
85
+ }
86
+ const ketMatch = content.match(/^\|([a-zA-Z_][a-zA-Z0-9_-]*)\s*([^>]*?)>\s*(.*)/);
87
+ if (ketMatch) {
88
+ return {
89
+ indent,
90
+ type: "ket",
91
+ tag: ketMatch[1],
92
+ attrs: ketMatch[2].trim() || void 0,
93
+ text: ketMatch[3] || void 0,
94
+ raw
95
+ };
96
+ }
97
+ return {
98
+ indent,
99
+ type: "text",
100
+ text: content,
101
+ raw
102
+ };
103
+ }
104
+ /**
105
+ * Convert bra-ket attribute syntax to XML
106
+ * Examples:
107
+ * name=value → name="value"
108
+ * x=5 y=10 → x="5" y="10"
109
+ * select=@* → select="@*"
110
+ */
111
+ convertAttributes(attrs) {
112
+ if (!attrs) return "";
113
+ const parts = [];
114
+ let current = "";
115
+ let inQuotes = false;
116
+ let quoteChar = "";
117
+ for (let i = 0; i < attrs.length; i++) {
118
+ const char = attrs[i];
119
+ if ((char === '"' || char === "'") && (i === 0 || attrs[i - 1] !== "\\")) {
120
+ if (!inQuotes) {
121
+ inQuotes = true;
122
+ quoteChar = char;
123
+ current += char;
124
+ } else if (char === quoteChar) {
125
+ inQuotes = false;
126
+ current += char;
127
+ } else {
128
+ current += char;
129
+ }
130
+ } else if (char === " " && !inQuotes) {
131
+ if (current.trim()) {
132
+ parts.push(current.trim());
133
+ current = "";
134
+ }
135
+ } else {
136
+ current += char;
137
+ }
138
+ }
139
+ if (current.trim()) {
140
+ parts.push(current.trim());
141
+ }
142
+ return parts.map((part) => {
143
+ const match = part.match(/^([a-zA-Z_][a-zA-Z0-9_-]*)=(.+)$/);
144
+ if (!match) return part;
145
+ const [, name, value] = match;
146
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
147
+ return `${name}=${value}`;
148
+ }
149
+ return `${name}="${value}"`;
150
+ }).join(" ");
151
+ }
152
+ /**
153
+ * Convert inline kets within text content
154
+ * Example: "Hello |variable name=x> world" → "Hello <variable name="x"/> world"
155
+ */
156
+ convertInlineKets(text) {
157
+ return text.replace(/\|([a-zA-Z_][a-zA-Z0-9_-]*)\s*([^>]*?)>/g, (match, tag, attrs) => {
158
+ const attrStr = attrs.trim() ? ` ${this.convertAttributes(attrs.trim())}` : "";
159
+ return `<${tag}${attrStr}/>`;
160
+ });
161
+ }
162
+ };
163
+
164
+ export {
165
+ BraKetParser
166
+ };
package/dist/cli.js CHANGED
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ BraKetParser
4
+ } from "./chunk-DRPHX3WX.js";
2
5
  import {
3
6
  execute
4
7
  } from "./chunk-4LLFMVOW.js";
@@ -13,7 +16,7 @@ import "dotenv/config";
13
16
  // package.json
14
17
  var package_default = {
15
18
  name: "dirac-lang",
16
- version: "0.1.33",
19
+ version: "0.1.35",
17
20
  description: "LLM-Augmented Declarative Execution",
18
21
  type: "module",
19
22
  main: "dist/index.js",
@@ -63,175 +66,14 @@ var package_default = {
63
66
  import fs from "fs";
64
67
  import yaml from "js-yaml";
65
68
  import { resolve, extname } from "path";
66
-
67
- // src/runtime/braket-parser.ts
68
- var BraKetParser = class {
69
- lines = [];
70
- currentLine = 0;
71
- /**
72
- * Parse bra-ket notation and compile to XML
73
- */
74
- parse(source) {
75
- this.lines = source.split("\n");
76
- this.currentLine = 0;
77
- const xml = ["<dirac>"];
78
- this.parseBlock(xml, -1);
79
- xml.push("</dirac>");
80
- return xml.join("\n");
81
- }
82
- /**
83
- * Parse a block of lines at a given indentation level
84
- */
85
- parseBlock(output, parentIndent) {
86
- while (this.currentLine < this.lines.length) {
87
- const line = this.parseLine(this.lines[this.currentLine]);
88
- if (line.type === "empty") {
89
- this.currentLine++;
90
- continue;
91
- }
92
- if (line.indent <= parentIndent) {
93
- break;
94
- }
95
- if (line.type === "bra") {
96
- const attrs = line.attrs ? ` ${this.convertAttributes(line.attrs)}` : "";
97
- output.push(`${" ".repeat(line.indent)}<subroutine name="${line.tag}"${attrs}>`);
98
- this.currentLine++;
99
- this.parseBlock(output, line.indent);
100
- output.push(`${" ".repeat(line.indent)}</subroutine>`);
101
- continue;
102
- }
103
- if (line.type === "ket") {
104
- const indent = " ".repeat(line.indent);
105
- const attrs = line.attrs ? ` ${this.convertAttributes(line.attrs)}` : "";
106
- const nextLine = this.currentLine + 1 < this.lines.length ? this.parseLine(this.lines[this.currentLine + 1]) : null;
107
- if (nextLine && nextLine.indent > line.indent && nextLine.type !== "empty") {
108
- output.push(`${indent}<${line.tag}${attrs}>`);
109
- this.currentLine++;
110
- this.parseBlock(output, line.indent);
111
- output.push(`${indent}</${line.tag}>`);
112
- } else {
113
- if (line.text) {
114
- const content = this.convertInlineKets(line.text);
115
- output.push(`${indent}<${line.tag}${attrs}>${content}</${line.tag}>`);
116
- } else {
117
- output.push(`${indent}<${line.tag}${attrs}/>`);
118
- }
119
- this.currentLine++;
120
- }
121
- continue;
122
- }
123
- if (line.type === "text") {
124
- const indent = " ".repeat(line.indent);
125
- const content = this.convertInlineKets(line.text || "");
126
- output.push(`${indent}${content}`);
127
- this.currentLine++;
128
- continue;
129
- }
130
- }
131
- }
132
- /**
133
- * Parse a single line into structured form
134
- */
135
- parseLine(raw) {
136
- const match = raw.match(/^(\s*)(.*)/);
137
- const indent = match ? Math.floor(match[1].length / 2) : 0;
138
- const content = match ? match[2] : "";
139
- if (!content.trim()) {
140
- return { indent, type: "empty", raw };
141
- }
142
- const braMatch = content.match(/^<([a-zA-Z_][a-zA-Z0-9_-]*)\s*([^|]*)\|$/);
143
- if (braMatch) {
144
- return {
145
- indent,
146
- type: "bra",
147
- tag: braMatch[1],
148
- attrs: braMatch[2].trim() || void 0,
149
- raw
150
- };
151
- }
152
- const ketMatch = content.match(/^\|([a-zA-Z_][a-zA-Z0-9_-]*)\s*([^>]*?)>\s*(.*)/);
153
- if (ketMatch) {
154
- return {
155
- indent,
156
- type: "ket",
157
- tag: ketMatch[1],
158
- attrs: ketMatch[2].trim() || void 0,
159
- text: ketMatch[3] || void 0,
160
- raw
161
- };
162
- }
163
- return {
164
- indent,
165
- type: "text",
166
- text: content,
167
- raw
168
- };
169
- }
170
- /**
171
- * Convert bra-ket attribute syntax to XML
172
- * Examples:
173
- * name=value → name="value"
174
- * x=5 y=10 → x="5" y="10"
175
- * select=@* → select="@*"
176
- */
177
- convertAttributes(attrs) {
178
- if (!attrs) return "";
179
- const parts = [];
180
- let current = "";
181
- let inQuotes = false;
182
- let quoteChar = "";
183
- for (let i = 0; i < attrs.length; i++) {
184
- const char = attrs[i];
185
- if ((char === '"' || char === "'") && (i === 0 || attrs[i - 1] !== "\\")) {
186
- if (!inQuotes) {
187
- inQuotes = true;
188
- quoteChar = char;
189
- current += char;
190
- } else if (char === quoteChar) {
191
- inQuotes = false;
192
- current += char;
193
- } else {
194
- current += char;
195
- }
196
- } else if (char === " " && !inQuotes) {
197
- if (current.trim()) {
198
- parts.push(current.trim());
199
- current = "";
200
- }
201
- } else {
202
- current += char;
203
- }
204
- }
205
- if (current.trim()) {
206
- parts.push(current.trim());
207
- }
208
- return parts.map((part) => {
209
- const match = part.match(/^([a-zA-Z_][a-zA-Z0-9_-]*)=(.+)$/);
210
- if (!match) return part;
211
- const [, name, value] = match;
212
- if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
213
- return `${name}=${value}`;
214
- }
215
- return `${name}="${value}"`;
216
- }).join(" ");
217
- }
218
- /**
219
- * Convert inline kets within text content
220
- * Example: "Hello |variable name=x> world" → "Hello <variable name="x"/> world"
221
- */
222
- convertInlineKets(text) {
223
- return text.replace(/\|([a-zA-Z_][a-zA-Z0-9_-]*)\s*([^>]*?)>/g, (match, tag, attrs) => {
224
- const attrStr = attrs.trim() ? ` ${this.convertAttributes(attrs.trim())}` : "";
225
- return `<${tag}${attrStr}/>`;
226
- });
227
- }
228
- };
229
-
230
- // src/cli.ts
231
69
  async function main() {
232
70
  const args = process.argv.slice(2);
233
71
  if (args.includes("--help") || args.includes("-h")) {
234
72
  console.log("Usage: dirac <file.di|file.bk>");
73
+ console.log(" dirac shell [options]");
74
+ console.log("");
75
+ console.log("Commands:");
76
+ console.log(" shell Start interactive shell (REPL)");
235
77
  console.log("");
236
78
  console.log("File formats:");
237
79
  console.log(" .di XML notation (verbose)");
@@ -245,14 +87,51 @@ async function main() {
245
87
  console.log(" --model <name> Set default LLM model");
246
88
  console.log(" --max-llm <n> Maximum LLM calls (default: 100)");
247
89
  console.log(" --max-depth <n> Maximum recursion depth (default: 50)");
90
+ console.log(" -f, --config <path> Path to config.yml file");
248
91
  process.exit(0);
249
92
  }
250
93
  if (args.includes("--version") || args.includes("-v")) {
251
94
  console.log(package_default.version);
252
95
  process.exit(0);
253
96
  }
97
+ if (args[0] === "shell") {
98
+ const { DiracShell } = await import("./shell-6ANKVL77.js");
99
+ const shellConfig = { debug: false };
100
+ for (let i = 1; i < args.length; i++) {
101
+ const arg = args[i];
102
+ if (arg === "--debug") {
103
+ shellConfig.debug = true;
104
+ } else if ((arg === "-f" || arg === "--config") && i + 1 < args.length) {
105
+ const configPath = resolve(args[++i]);
106
+ if (fs.existsSync(configPath)) {
107
+ const configData = yaml.load(fs.readFileSync(configPath, "utf-8"));
108
+ Object.assign(shellConfig, {
109
+ llmProvider: configData.llmProvider,
110
+ llmModel: configData.llmModel,
111
+ customLLMUrl: configData.customLLMUrl
112
+ });
113
+ }
114
+ }
115
+ }
116
+ if (!shellConfig.llmProvider) {
117
+ const defaultConfigPath = resolve(process.cwd(), "config.yml");
118
+ if (fs.existsSync(defaultConfigPath)) {
119
+ try {
120
+ const configData = yaml.load(fs.readFileSync(defaultConfigPath, "utf-8"));
121
+ shellConfig.llmProvider = shellConfig.llmProvider || configData.llmProvider;
122
+ shellConfig.llmModel = shellConfig.llmModel || configData.llmModel;
123
+ shellConfig.customLLMUrl = shellConfig.customLLMUrl || configData.customLLMUrl;
124
+ } catch (err) {
125
+ }
126
+ }
127
+ }
128
+ const shell = new DiracShell(shellConfig);
129
+ shell.start();
130
+ return;
131
+ }
254
132
  if (args.length === 0) {
255
133
  console.error("Usage: dirac <file.di|file.bk>");
134
+ console.error(" dirac shell [options]");
256
135
  console.error("Try dirac --help for more information.");
257
136
  process.exit(1);
258
137
  }
@@ -0,0 +1,303 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ BraKetParser
4
+ } from "./chunk-DRPHX3WX.js";
5
+ import {
6
+ integrate
7
+ } from "./chunk-HPGONBNW.js";
8
+ import {
9
+ DiracParser
10
+ } from "./chunk-HRHAMPOB.js";
11
+ import "./chunk-4QLTSCDG.js";
12
+ import {
13
+ createSession
14
+ } from "./chunk-GLXVY235.js";
15
+
16
+ // src/shell.ts
17
+ import * as readline from "readline";
18
+ import * as fs from "fs";
19
+ import * as path from "path";
20
+ import * as os from "os";
21
+ import yaml from "js-yaml";
22
+ var HISTORY_FILE = path.join(os.homedir(), ".dirac_history");
23
+ var MAX_HISTORY = 1e3;
24
+ var DiracShell = class {
25
+ session;
26
+ braketParser;
27
+ xmlParser;
28
+ rl;
29
+ inputBuffer = [];
30
+ baseIndent = null;
31
+ currentIndent = 0;
32
+ config;
33
+ constructor(config = {}) {
34
+ this.config = config;
35
+ this.session = createSession(config);
36
+ this.braketParser = new BraKetParser();
37
+ this.xmlParser = new DiracParser();
38
+ this.rl = readline.createInterface({
39
+ input: process.stdin,
40
+ output: process.stdout,
41
+ prompt: "> ",
42
+ historySize: MAX_HISTORY
43
+ });
44
+ this.loadHistory();
45
+ this.setupHandlers();
46
+ }
47
+ loadHistory() {
48
+ try {
49
+ if (fs.existsSync(HISTORY_FILE)) {
50
+ const history = fs.readFileSync(HISTORY_FILE, "utf-8").split("\n").filter((line) => line.trim()).slice(-MAX_HISTORY);
51
+ this.rl.history = history.reverse();
52
+ }
53
+ } catch (err) {
54
+ }
55
+ }
56
+ saveHistory() {
57
+ try {
58
+ const history = this.rl.history.slice().reverse().join("\n");
59
+ fs.writeFileSync(HISTORY_FILE, history, "utf-8");
60
+ } catch (err) {
61
+ }
62
+ }
63
+ setupHandlers() {
64
+ this.rl.on("line", async (input) => {
65
+ await this.handleInput(input);
66
+ });
67
+ this.rl.on("close", () => {
68
+ this.saveHistory();
69
+ console.log("\nGoodbye!");
70
+ process.exit(0);
71
+ });
72
+ this.rl.on("SIGINT", () => {
73
+ if (this.inputBuffer.length > 0) {
74
+ this.inputBuffer = [];
75
+ this.baseIndent = null;
76
+ this.currentIndent = 0;
77
+ console.log("\n(Input cancelled)");
78
+ this.rl.setPrompt("> ");
79
+ this.rl.prompt();
80
+ } else {
81
+ this.rl.close();
82
+ }
83
+ });
84
+ }
85
+ async handleInput(input) {
86
+ if (!this.inputBuffer.length && input.trim().startsWith(":")) {
87
+ await this.handleCommand(input.trim());
88
+ this.rl.prompt();
89
+ return;
90
+ }
91
+ const indent = this.getIndent(input);
92
+ if (this.inputBuffer.length === 0) {
93
+ this.inputBuffer.push(input);
94
+ this.baseIndent = indent;
95
+ if (this.needsContinuation(input)) {
96
+ this.currentIndent = (this.baseIndent || 0) + 2;
97
+ this.rl.setPrompt("... ");
98
+ console.log(` (Indent with ${this.currentIndent} spaces, or press Enter on empty line to execute)`);
99
+ this.rl.prompt();
100
+ return;
101
+ }
102
+ } else {
103
+ if (input.trim() === "") {
104
+ await this.executeBuffer();
105
+ this.currentIndent = 0;
106
+ this.rl.setPrompt("> ");
107
+ this.rl.prompt();
108
+ return;
109
+ }
110
+ let processedInput = input;
111
+ if (this.currentIndent > 0 && indent < this.currentIndent) {
112
+ processedInput = " ".repeat(this.currentIndent) + input;
113
+ }
114
+ this.inputBuffer.push(processedInput);
115
+ const trimmed = input.trim();
116
+ const currentLineIndent = this.getIndent(processedInput);
117
+ if (trimmed.match(/^<[a-zA-Z_][a-zA-Z0-9_-]*.*\|$/) || trimmed.match(/^\|[a-zA-Z_][a-zA-Z0-9_-]*\s*[^>]*?>$/) && !trimmed.match(/>\s*.+$/)) {
118
+ this.currentIndent = currentLineIndent + 2;
119
+ } else {
120
+ this.currentIndent = currentLineIndent;
121
+ }
122
+ this.rl.setPrompt("... ");
123
+ this.rl.prompt();
124
+ return;
125
+ }
126
+ await this.executeBuffer();
127
+ this.rl.prompt();
128
+ }
129
+ getIndent(line) {
130
+ const match = line.match(/^(\s*)/);
131
+ return match ? match[1].length : 0;
132
+ }
133
+ needsContinuation(line) {
134
+ const trimmed = line.trim();
135
+ if (trimmed.match(/^<[a-zA-Z_][a-zA-Z0-9_-]*.*\|$/)) {
136
+ return true;
137
+ }
138
+ const ketMatch = trimmed.match(/^\|([a-zA-Z_][a-zA-Z0-9_-]*)\s*([^>]*?)>\s*(.*)$/);
139
+ if (ketMatch && !ketMatch[3]) {
140
+ return true;
141
+ }
142
+ return false;
143
+ }
144
+ async executeBuffer() {
145
+ if (this.inputBuffer.length === 0) return;
146
+ const input = this.inputBuffer.join("\n");
147
+ this.inputBuffer = [];
148
+ this.baseIndent = null;
149
+ try {
150
+ this.session.output = [];
151
+ const xml = this.braketParser.parse(input);
152
+ if (this.config.debug) {
153
+ console.log("[Debug] Generated XML:\n", xml);
154
+ }
155
+ const ast = this.xmlParser.parse(xml);
156
+ await integrate(this.session, ast);
157
+ if (this.session.output.length > 0) {
158
+ console.log(this.session.output.join(""));
159
+ }
160
+ } catch (error) {
161
+ console.error("Error:", error instanceof Error ? error.message : String(error));
162
+ if (this.config.debug && error instanceof Error && error.stack) {
163
+ console.error(error.stack);
164
+ }
165
+ }
166
+ }
167
+ async handleCommand(cmd) {
168
+ const parts = cmd.slice(1).split(/\s+/);
169
+ const command = parts[0];
170
+ const args = parts.slice(1);
171
+ switch (command) {
172
+ case "help":
173
+ console.log(`
174
+ Dirac Shell - Interactive REPL
175
+
176
+ Commands:
177
+ :help Show this help
178
+ :vars List all variables
179
+ :subs List all subroutines
180
+ :clear Clear session (reset variables and subroutines)
181
+ :debug Toggle debug mode
182
+ :config Show current configuration
183
+ :exit Exit shell
184
+
185
+ Syntax:
186
+ |tag attrs>text Ket notation (most tags)
187
+ <name| Bra notation (subroutine definitions)
188
+ |output>content Indented children
189
+
190
+ Multi-line Input:
191
+ - Type a line that needs continuation (like <greeting| or |llm>)
192
+ - Shell switches to '...' prompt and shows expected indent level
193
+ - You can type spaces manually, or just type content (shell adds spaces)
194
+ - Press ENTER on an empty line to execute
195
+ - Or press Ctrl+C to cancel
196
+
197
+ Examples:
198
+ |output>Hello World
199
+ |defvar name=count value=5>
200
+ |llm>create a greeting subroutine
201
+ <greeting| name=String
202
+ |output>Hello |variable name=name>
203
+ |greeting name=World>
204
+ `);
205
+ break;
206
+ case "vars":
207
+ if (this.session.variables.length === 0) {
208
+ console.log("No variables defined");
209
+ } else {
210
+ console.log("Variables:");
211
+ for (const v of this.session.variables) {
212
+ if (v.visible) {
213
+ console.log(` ${v.name} = ${JSON.stringify(v.value)}`);
214
+ }
215
+ }
216
+ }
217
+ break;
218
+ case "subs":
219
+ if (this.session.subroutines.length === 0) {
220
+ console.log("No subroutines defined");
221
+ } else {
222
+ console.log("Subroutines:");
223
+ for (const s of this.session.subroutines) {
224
+ const params = s.parameters?.map((p) => p.name).join(", ") || "";
225
+ console.log(` ${s.name}(${params})`);
226
+ if (s.description) {
227
+ console.log(` ${s.description}`);
228
+ }
229
+ }
230
+ }
231
+ break;
232
+ case "clear":
233
+ this.session.variables = [];
234
+ this.session.subroutines = [];
235
+ this.session.varBoundary = 0;
236
+ this.session.subBoundary = 0;
237
+ console.log("Session cleared");
238
+ break;
239
+ case "debug":
240
+ this.config.debug = !this.config.debug;
241
+ this.session.debug = this.config.debug;
242
+ console.log(`Debug mode: ${this.config.debug ? "ON" : "OFF"}`);
243
+ break;
244
+ case "config":
245
+ console.log("Configuration:");
246
+ console.log(` LLM Provider: ${this.config.llmProvider || "none"}`);
247
+ console.log(` LLM Model: ${this.config.llmModel || "default"}`);
248
+ console.log(` Debug: ${this.config.debug ? "ON" : "OFF"}`);
249
+ if (this.config.customLLMUrl) {
250
+ console.log(` Custom LLM URL: ${this.config.customLLMUrl}`);
251
+ }
252
+ break;
253
+ case "exit":
254
+ case "quit":
255
+ this.rl.close();
256
+ break;
257
+ default:
258
+ console.log(`Unknown command: ${command}. Type :help for available commands.`);
259
+ }
260
+ }
261
+ start() {
262
+ console.log("Dirac Shell v0.1.0");
263
+ console.log("Type :help for commands, :exit to quit\n");
264
+ if (this.config.llmProvider) {
265
+ console.log(`LLM: ${this.config.llmProvider} (${this.config.llmModel || "default"})
266
+ `);
267
+ } else {
268
+ console.log("Warning: No LLM provider configured. Set LLM_PROVIDER environment variable.\n");
269
+ }
270
+ this.rl.prompt();
271
+ }
272
+ };
273
+ async function main() {
274
+ let config = {
275
+ debug: process.env.DEBUG === "1"
276
+ };
277
+ const configPath = path.join(process.cwd(), "config.yml");
278
+ if (fs.existsSync(configPath)) {
279
+ try {
280
+ const configData = yaml.load(fs.readFileSync(configPath, "utf-8"));
281
+ config = {
282
+ ...config,
283
+ llmProvider: configData.llmProvider || process.env.LLM_PROVIDER,
284
+ llmModel: configData.llmModel || process.env.LLM_MODEL,
285
+ customLLMUrl: configData.customLLMUrl || process.env.CUSTOM_LLM_URL
286
+ };
287
+ } catch (err) {
288
+ console.error("Warning: Could not load config.yml");
289
+ }
290
+ } else {
291
+ config.llmProvider = process.env.LLM_PROVIDER;
292
+ config.llmModel = process.env.LLM_MODEL;
293
+ config.customLLMUrl = process.env.CUSTOM_LLM_URL;
294
+ }
295
+ const shell = new DiracShell(config);
296
+ shell.start();
297
+ }
298
+ if (import.meta.url === `file://${process.argv[1]}`) {
299
+ main();
300
+ }
301
+ export {
302
+ DiracShell
303
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dirac-lang",
3
- "version": "0.1.33",
3
+ "version": "0.1.35",
4
4
  "description": "LLM-Augmented Declarative Execution",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",