dirac-lang 0.1.60 → 0.1.62
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/agent-3VQNLFHO.js +227 -0
- package/dist/{chunk-ZAA6R2TC.js → chunk-BAO2WV34.js} +15 -14
- package/dist/{chunk-BMKPKK7M.js → chunk-SVB7OJDA.js} +1 -1
- package/dist/chunk-WPEAYK2Q.js +208 -0
- package/dist/cli.js +107 -4
- package/dist/{cron-BQIWLGQY.js → cron-SUYXFAW7.js} +1 -1
- package/dist/index.js +2 -2
- package/dist/{interpreter-NPXTWPHN.js → interpreter-UFWRGTCM.js} +1 -1
- package/dist/{run-at-KDJYTEOD.js → run-at-BBMPAVED.js} +1 -1
- package/dist/{schedule-QZ5U3YBS.js → schedule-F7JHVWEV.js} +1 -1
- package/dist/session-client-3VTC5MLO.js +177 -0
- package/dist/session-server-BQH56RCK.js +14 -0
- package/dist/{shell-WFLXZW3I.js → shell-KGS3I6WX.js} +103 -34
- package/dist/test-runner.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SessionServer,
|
|
3
|
+
getSocketPath,
|
|
4
|
+
isSessionRunning
|
|
5
|
+
} from "./chunk-WPEAYK2Q.js";
|
|
6
|
+
import "./chunk-BAO2WV34.js";
|
|
7
|
+
import "./chunk-HRHAMPOB.js";
|
|
8
|
+
import "./chunk-NKA6ZJDV.js";
|
|
9
|
+
import "./chunk-3UW6GWYQ.js";
|
|
10
|
+
|
|
11
|
+
// src/agent.ts
|
|
12
|
+
import fs from "fs";
|
|
13
|
+
import path from "path";
|
|
14
|
+
import os from "os";
|
|
15
|
+
import { spawn } from "child_process";
|
|
16
|
+
var AGENT_DIR = path.join(os.homedir(), ".dirac");
|
|
17
|
+
var PID_FILE = path.join(AGENT_DIR, "session.pid");
|
|
18
|
+
var LOG_FILE = path.join(AGENT_DIR, "agent.log");
|
|
19
|
+
var AgentCLI = class {
|
|
20
|
+
async start() {
|
|
21
|
+
if (isSessionRunning()) {
|
|
22
|
+
console.log("Agent is already running");
|
|
23
|
+
const pid = this.getRunningPid();
|
|
24
|
+
if (pid) {
|
|
25
|
+
console.log(`PID: ${pid}`);
|
|
26
|
+
console.log(`Socket: ${getSocketPath()}`);
|
|
27
|
+
console.log(`Logs: ${LOG_FILE}`);
|
|
28
|
+
}
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (!fs.existsSync(AGENT_DIR)) {
|
|
32
|
+
fs.mkdirSync(AGENT_DIR, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
console.log("Starting DIRAC agent...");
|
|
35
|
+
const logFd = fs.openSync(LOG_FILE, "a");
|
|
36
|
+
const child = spawn(
|
|
37
|
+
process.argv[0],
|
|
38
|
+
// node executable
|
|
39
|
+
[process.argv[1], "agent", "daemon"],
|
|
40
|
+
// dirac agent daemon
|
|
41
|
+
{
|
|
42
|
+
detached: true,
|
|
43
|
+
stdio: ["ignore", logFd, logFd],
|
|
44
|
+
// Redirect stdout/stderr to log file
|
|
45
|
+
cwd: process.cwd()
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
fs.closeSync(logFd);
|
|
49
|
+
child.unref();
|
|
50
|
+
let attempts = 0;
|
|
51
|
+
const maxAttempts = 10;
|
|
52
|
+
while (attempts < maxAttempts) {
|
|
53
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
54
|
+
if (isSessionRunning()) {
|
|
55
|
+
console.log("\u2713 Agent started successfully");
|
|
56
|
+
console.log(` PID: ${child.pid}`);
|
|
57
|
+
console.log(` Socket: ${getSocketPath()}`);
|
|
58
|
+
console.log(` Logs: ${LOG_FILE}`);
|
|
59
|
+
console.log("");
|
|
60
|
+
console.log("Connect with: dirac shell --agent");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
attempts++;
|
|
64
|
+
}
|
|
65
|
+
console.error("\u2717 Failed to start agent");
|
|
66
|
+
console.error("Check logs:", LOG_FILE);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
async stop() {
|
|
70
|
+
const pid = this.getRunningPid();
|
|
71
|
+
if (!pid) {
|
|
72
|
+
console.log("Agent is not running");
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
console.log(`Stopping agent (PID: ${pid})...`);
|
|
76
|
+
try {
|
|
77
|
+
process.kill(pid, "SIGTERM");
|
|
78
|
+
let attempts = 0;
|
|
79
|
+
while (attempts < 10) {
|
|
80
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
81
|
+
try {
|
|
82
|
+
process.kill(pid, 0);
|
|
83
|
+
attempts++;
|
|
84
|
+
} catch {
|
|
85
|
+
console.log("\u2713 Agent stopped");
|
|
86
|
+
this.cleanup();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
console.log("Agent did not stop gracefully, forcing...");
|
|
91
|
+
process.kill(pid, "SIGKILL");
|
|
92
|
+
this.cleanup();
|
|
93
|
+
console.log("\u2713 Agent stopped (forced)");
|
|
94
|
+
} catch (error) {
|
|
95
|
+
if (error.code === "ESRCH") {
|
|
96
|
+
console.log("Agent was not running");
|
|
97
|
+
this.cleanup();
|
|
98
|
+
} else {
|
|
99
|
+
console.error("Error stopping agent:", error.message);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async status() {
|
|
105
|
+
const pid = this.getRunningPid();
|
|
106
|
+
if (!pid) {
|
|
107
|
+
console.log("Status: NOT RUNNING");
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
process.kill(pid, 0);
|
|
112
|
+
console.log("Status: RUNNING");
|
|
113
|
+
console.log(`PID: ${pid}`);
|
|
114
|
+
console.log(`Socket: ${getSocketPath()}`);
|
|
115
|
+
console.log(`Logs: ${LOG_FILE}`);
|
|
116
|
+
if (fs.existsSync(PID_FILE)) {
|
|
117
|
+
const stats = fs.statSync(PID_FILE);
|
|
118
|
+
const uptime = Date.now() - stats.mtimeMs;
|
|
119
|
+
console.log(`Uptime: ${this.formatUptime(uptime)}`);
|
|
120
|
+
}
|
|
121
|
+
} catch (error) {
|
|
122
|
+
if (error.code === "ESRCH") {
|
|
123
|
+
console.log("Status: NOT RUNNING (stale PID file)");
|
|
124
|
+
this.cleanup();
|
|
125
|
+
} else {
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async restart() {
|
|
131
|
+
console.log("Restarting agent...");
|
|
132
|
+
await this.stop();
|
|
133
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
134
|
+
await this.start();
|
|
135
|
+
}
|
|
136
|
+
async logs(follow = false) {
|
|
137
|
+
if (!fs.existsSync(LOG_FILE)) {
|
|
138
|
+
console.log("No logs found");
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (follow) {
|
|
142
|
+
const { spawn: spawn2 } = await import("child_process");
|
|
143
|
+
const tail = spawn2("tail", ["-f", LOG_FILE], {
|
|
144
|
+
stdio: "inherit"
|
|
145
|
+
});
|
|
146
|
+
process.on("SIGINT", () => {
|
|
147
|
+
tail.kill();
|
|
148
|
+
process.exit(0);
|
|
149
|
+
});
|
|
150
|
+
} else {
|
|
151
|
+
const content = fs.readFileSync(LOG_FILE, "utf-8");
|
|
152
|
+
const lines = content.split("\n");
|
|
153
|
+
const lastLines = lines.slice(-50);
|
|
154
|
+
console.log(lastLines.join("\n"));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
getRunningPid() {
|
|
158
|
+
if (!fs.existsSync(PID_FILE)) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
const pidStr = fs.readFileSync(PID_FILE, "utf-8").trim();
|
|
163
|
+
return parseInt(pidStr, 10);
|
|
164
|
+
} catch {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
cleanup() {
|
|
169
|
+
if (fs.existsSync(PID_FILE)) {
|
|
170
|
+
fs.unlinkSync(PID_FILE);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
formatUptime(ms) {
|
|
174
|
+
const seconds = Math.floor(ms / 1e3);
|
|
175
|
+
const minutes = Math.floor(seconds / 60);
|
|
176
|
+
const hours = Math.floor(minutes / 60);
|
|
177
|
+
const days = Math.floor(hours / 24);
|
|
178
|
+
if (days > 0) return `${days}d ${hours % 24}h`;
|
|
179
|
+
if (hours > 0) return `${hours}h ${minutes % 60}m`;
|
|
180
|
+
if (minutes > 0) return `${minutes}m`;
|
|
181
|
+
return `${seconds}s`;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
async function runAgentDaemon() {
|
|
185
|
+
console.log(`[${(/* @__PURE__ */ new Date()).toISOString()}] Starting DIRAC agent daemon`);
|
|
186
|
+
let config = {};
|
|
187
|
+
try {
|
|
188
|
+
const fs2 = await import("fs");
|
|
189
|
+
const path2 = await import("path");
|
|
190
|
+
const yaml = await import("js-yaml");
|
|
191
|
+
const configPath = path2.default.resolve(process.cwd(), "config.yml");
|
|
192
|
+
if (fs2.default.existsSync(configPath)) {
|
|
193
|
+
const configData = yaml.default.load(fs2.default.readFileSync(configPath, "utf-8"));
|
|
194
|
+
config = {
|
|
195
|
+
llmProvider: configData.llmProvider,
|
|
196
|
+
llmModel: configData.llmModel,
|
|
197
|
+
customLLMUrl: configData.customLLMUrl,
|
|
198
|
+
initScript: configData.initScript,
|
|
199
|
+
libraryPaths: configData.libraryPaths
|
|
200
|
+
};
|
|
201
|
+
console.log(`[${(/* @__PURE__ */ new Date()).toISOString()}] Loaded config: LLM=${config.llmProvider}/${config.llmModel}`);
|
|
202
|
+
}
|
|
203
|
+
} catch (err) {
|
|
204
|
+
console.log(`[${(/* @__PURE__ */ new Date()).toISOString()}] No config.yml found, using defaults`);
|
|
205
|
+
}
|
|
206
|
+
const server = new SessionServer(config);
|
|
207
|
+
try {
|
|
208
|
+
await server.start();
|
|
209
|
+
console.log(`[${(/* @__PURE__ */ new Date()).toISOString()}] Agent daemon started successfully`);
|
|
210
|
+
const shutdown = async () => {
|
|
211
|
+
console.log(`[${(/* @__PURE__ */ new Date()).toISOString()}] Shutting down agent daemon`);
|
|
212
|
+
await server.shutdown();
|
|
213
|
+
process.exit(0);
|
|
214
|
+
};
|
|
215
|
+
process.on("SIGTERM", shutdown);
|
|
216
|
+
process.on("SIGINT", shutdown);
|
|
217
|
+
await new Promise(() => {
|
|
218
|
+
});
|
|
219
|
+
} catch (error) {
|
|
220
|
+
console.error(`[${(/* @__PURE__ */ new Date()).toISOString()}] Failed to start agent:`, error);
|
|
221
|
+
process.exit(1);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
export {
|
|
225
|
+
AgentCLI,
|
|
226
|
+
runAgentDaemon
|
|
227
|
+
};
|
|
@@ -474,12 +474,12 @@ async function executeIf(session, element) {
|
|
|
474
474
|
const condition = await evaluatePredicate(session, conditionElement);
|
|
475
475
|
if (condition) {
|
|
476
476
|
if (thenElement) {
|
|
477
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
477
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-UFWRGTCM.js");
|
|
478
478
|
await integrateChildren2(session, thenElement);
|
|
479
479
|
}
|
|
480
480
|
} else {
|
|
481
481
|
if (elseElement) {
|
|
482
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
482
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-UFWRGTCM.js");
|
|
483
483
|
await integrateChildren2(session, elseElement);
|
|
484
484
|
}
|
|
485
485
|
}
|
|
@@ -492,7 +492,7 @@ async function evaluatePredicate(session, predicateElement) {
|
|
|
492
492
|
return await evaluateCondition(session, predicateElement);
|
|
493
493
|
}
|
|
494
494
|
const outputLengthBefore = session.output.length;
|
|
495
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
495
|
+
const { integrate: integrate2 } = await import("./interpreter-UFWRGTCM.js");
|
|
496
496
|
await integrate2(session, predicateElement);
|
|
497
497
|
const newOutputChunks = session.output.slice(outputLengthBefore);
|
|
498
498
|
const result = newOutputChunks.join("").trim();
|
|
@@ -515,11 +515,11 @@ async function evaluateCondition(session, condElement) {
|
|
|
515
515
|
}
|
|
516
516
|
const outputLengthBefore = session.output.length;
|
|
517
517
|
const args = [];
|
|
518
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
518
|
+
const { integrate: integrate2 } = await import("./interpreter-UFWRGTCM.js");
|
|
519
519
|
for (const child of condElement.children) {
|
|
520
520
|
if (child.tag.toLowerCase() === "arg") {
|
|
521
521
|
const argOutputStart = session.output.length;
|
|
522
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
522
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-UFWRGTCM.js");
|
|
523
523
|
await integrateChildren2(session, child);
|
|
524
524
|
const newChunks = session.output.slice(argOutputStart);
|
|
525
525
|
const argValue = newChunks.join("");
|
|
@@ -833,9 +833,10 @@ async function executeLLM(session, element) {
|
|
|
833
833
|
example = example.replace(/"/g, '"').replace(/:/g, ":");
|
|
834
834
|
systemPrompt += ">" + example + "</" + sub.name + ">";
|
|
835
835
|
}
|
|
836
|
-
|
|
836
|
+
dialogHistory.push({ role: "system", content: systemPrompt });
|
|
837
|
+
currentUserPrompt = userPrompt;
|
|
837
838
|
if (session.debug || process.env.DIRAC_LOG_PROMPT === "1") {
|
|
838
|
-
console.error("[LLM] Continuing dialog with updated subroutines\n");
|
|
839
|
+
console.error("[LLM] Continuing dialog with updated subroutines (as system message)\n");
|
|
839
840
|
}
|
|
840
841
|
} else {
|
|
841
842
|
systemPrompt = `Dirac is a XML-based language. To define a subroutine with parameters:
|
|
@@ -1685,7 +1686,7 @@ async function executeTagCheck(session, element) {
|
|
|
1685
1686
|
const executeTag = correctedTag || tagName;
|
|
1686
1687
|
console.error(`[tag-check] Executing <${executeTag}/> as all checks passed and execute=true.`);
|
|
1687
1688
|
const elementToExecute = correctedTag ? { ...child, tag: correctedTag } : child;
|
|
1688
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
1689
|
+
const { integrate: integrate2 } = await import("./interpreter-UFWRGTCM.js");
|
|
1689
1690
|
await integrate2(session, elementToExecute);
|
|
1690
1691
|
}
|
|
1691
1692
|
}
|
|
@@ -1694,7 +1695,7 @@ async function executeTagCheck(session, element) {
|
|
|
1694
1695
|
// src/tags/throw.ts
|
|
1695
1696
|
async function executeThrow(session, element) {
|
|
1696
1697
|
const exceptionName = element.attributes?.name || "exception";
|
|
1697
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1698
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-UFWRGTCM.js");
|
|
1698
1699
|
const exceptionDom = {
|
|
1699
1700
|
tag: "exception-content",
|
|
1700
1701
|
attributes: { name: exceptionName },
|
|
@@ -1707,7 +1708,7 @@ async function executeThrow(session, element) {
|
|
|
1707
1708
|
// src/tags/try.ts
|
|
1708
1709
|
async function executeTry(session, element) {
|
|
1709
1710
|
setExceptionBoundary(session);
|
|
1710
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1711
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-UFWRGTCM.js");
|
|
1711
1712
|
await integrateChildren2(session, element);
|
|
1712
1713
|
unsetExceptionBoundary(session);
|
|
1713
1714
|
}
|
|
@@ -1717,7 +1718,7 @@ async function executeCatch(session, element) {
|
|
|
1717
1718
|
const exceptionName = element.attributes?.name || "exception";
|
|
1718
1719
|
const caughtCount = lookupException(session, exceptionName);
|
|
1719
1720
|
if (caughtCount > 0) {
|
|
1720
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1721
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-UFWRGTCM.js");
|
|
1721
1722
|
await integrateChildren2(session, element);
|
|
1722
1723
|
}
|
|
1723
1724
|
flushCurrentException(session);
|
|
@@ -1726,7 +1727,7 @@ async function executeCatch(session, element) {
|
|
|
1726
1727
|
// src/tags/exception.ts
|
|
1727
1728
|
async function executeException(session, element) {
|
|
1728
1729
|
const exceptions = getCurrentExceptions(session);
|
|
1729
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1730
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-UFWRGTCM.js");
|
|
1730
1731
|
for (const exceptionDom of exceptions) {
|
|
1731
1732
|
await integrateChildren2(session, exceptionDom);
|
|
1732
1733
|
}
|
|
@@ -2194,7 +2195,7 @@ async function executeLoadContext(session, element) {
|
|
|
2194
2195
|
query = element.text.trim();
|
|
2195
2196
|
}
|
|
2196
2197
|
if (!query && element.children.length > 0) {
|
|
2197
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
2198
|
+
const { integrate: integrate2 } = await import("./interpreter-UFWRGTCM.js");
|
|
2198
2199
|
const beforeOutput = session.output.length;
|
|
2199
2200
|
for (const child of element.children) {
|
|
2200
2201
|
await integrate2(session, child);
|
|
@@ -2447,7 +2448,7 @@ async function executeForeach(session, element) {
|
|
|
2447
2448
|
const parser2 = new DiracParser2();
|
|
2448
2449
|
try {
|
|
2449
2450
|
const fromElement = parser2.parse(fromAttr);
|
|
2450
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
2451
|
+
const { integrate: integrate2 } = await import("./interpreter-UFWRGTCM.js");
|
|
2451
2452
|
await integrate2(session, fromElement);
|
|
2452
2453
|
} catch (e) {
|
|
2453
2454
|
session.output = savedOutput;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import {
|
|
2
|
+
integrate
|
|
3
|
+
} from "./chunk-BAO2WV34.js";
|
|
4
|
+
import {
|
|
5
|
+
DiracParser
|
|
6
|
+
} from "./chunk-HRHAMPOB.js";
|
|
7
|
+
import {
|
|
8
|
+
createSession
|
|
9
|
+
} from "./chunk-3UW6GWYQ.js";
|
|
10
|
+
|
|
11
|
+
// src/session-server.ts
|
|
12
|
+
import net from "net";
|
|
13
|
+
import fs from "fs";
|
|
14
|
+
import path from "path";
|
|
15
|
+
import os from "os";
|
|
16
|
+
var SOCKET_DIR = path.join(os.homedir(), ".dirac");
|
|
17
|
+
var SOCKET_PATH = path.join(SOCKET_DIR, "session.sock");
|
|
18
|
+
var PID_PATH = path.join(SOCKET_DIR, "session.pid");
|
|
19
|
+
var SessionServer = class {
|
|
20
|
+
server;
|
|
21
|
+
session;
|
|
22
|
+
clients = /* @__PURE__ */ new Map();
|
|
23
|
+
clientIdCounter = 0;
|
|
24
|
+
constructor(config) {
|
|
25
|
+
this.session = createSession(config || {});
|
|
26
|
+
this.server = net.createServer(this.handleConnection.bind(this));
|
|
27
|
+
}
|
|
28
|
+
async start() {
|
|
29
|
+
if (!fs.existsSync(SOCKET_DIR)) {
|
|
30
|
+
fs.mkdirSync(SOCKET_DIR, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
if (fs.existsSync(SOCKET_PATH)) {
|
|
33
|
+
fs.unlinkSync(SOCKET_PATH);
|
|
34
|
+
}
|
|
35
|
+
return new Promise((resolve, reject) => {
|
|
36
|
+
this.server.listen(SOCKET_PATH, () => {
|
|
37
|
+
console.log(`[session-server] Listening on ${SOCKET_PATH}`);
|
|
38
|
+
fs.writeFileSync(PID_PATH, process.pid.toString());
|
|
39
|
+
fs.chmodSync(SOCKET_PATH, 384);
|
|
40
|
+
resolve();
|
|
41
|
+
});
|
|
42
|
+
this.server.on("error", (error) => {
|
|
43
|
+
console.error("[session-server] Error:", error);
|
|
44
|
+
reject(error);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
handleConnection(socket) {
|
|
49
|
+
const clientId = `client-${++this.clientIdCounter}`;
|
|
50
|
+
const client = { id: clientId, socket };
|
|
51
|
+
this.clients.set(clientId, client);
|
|
52
|
+
console.log(`[session-server] Client connected: ${clientId}`);
|
|
53
|
+
let buffer = "";
|
|
54
|
+
socket.on("data", async (data) => {
|
|
55
|
+
buffer += data.toString();
|
|
56
|
+
const lines = buffer.split("\n");
|
|
57
|
+
buffer = lines.pop() || "";
|
|
58
|
+
for (const line of lines) {
|
|
59
|
+
if (!line.trim()) continue;
|
|
60
|
+
try {
|
|
61
|
+
const message = JSON.parse(line);
|
|
62
|
+
await this.handleMessage(client, message);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
this.sendError(client, `Invalid message: ${error}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
socket.on("end", () => {
|
|
69
|
+
console.log(`[session-server] Client disconnected: ${clientId}`);
|
|
70
|
+
this.clients.delete(clientId);
|
|
71
|
+
});
|
|
72
|
+
socket.on("error", (error) => {
|
|
73
|
+
console.error(`[session-server] Client error (${clientId}):`, error);
|
|
74
|
+
this.clients.delete(clientId);
|
|
75
|
+
});
|
|
76
|
+
this.sendResponse(client, {
|
|
77
|
+
type: "welcome",
|
|
78
|
+
sessionId: clientId,
|
|
79
|
+
message: "Connected to DIRAC session"
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async handleMessage(client, message) {
|
|
83
|
+
const { type, data } = message;
|
|
84
|
+
switch (type) {
|
|
85
|
+
case "execute":
|
|
86
|
+
await this.executeCommand(client, data.command);
|
|
87
|
+
break;
|
|
88
|
+
case "getVars":
|
|
89
|
+
this.sendResponse(client, {
|
|
90
|
+
type: "vars",
|
|
91
|
+
data: Object.keys(this.session.variables)
|
|
92
|
+
});
|
|
93
|
+
break;
|
|
94
|
+
case "getState":
|
|
95
|
+
this.sendResponse(client, {
|
|
96
|
+
type: "state",
|
|
97
|
+
data: {
|
|
98
|
+
variables: this.session.variables,
|
|
99
|
+
subroutines: this.session.subroutines,
|
|
100
|
+
varBoundary: this.session.varBoundary,
|
|
101
|
+
subBoundary: this.session.subBoundary
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
break;
|
|
105
|
+
case "shutdown":
|
|
106
|
+
this.sendResponse(client, {
|
|
107
|
+
type: "shutdown",
|
|
108
|
+
message: "Server shutting down"
|
|
109
|
+
});
|
|
110
|
+
await this.shutdown();
|
|
111
|
+
break;
|
|
112
|
+
default:
|
|
113
|
+
this.sendError(client, `Unknown message type: ${type}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async executeCommand(client, command) {
|
|
117
|
+
try {
|
|
118
|
+
this.session.output = [];
|
|
119
|
+
const parser = new DiracParser();
|
|
120
|
+
const ast = parser.parse(command);
|
|
121
|
+
await integrate(this.session, ast);
|
|
122
|
+
const output = this.session.output.join("");
|
|
123
|
+
this.sendResponse(client, {
|
|
124
|
+
type: "output",
|
|
125
|
+
data: output
|
|
126
|
+
});
|
|
127
|
+
} catch (error) {
|
|
128
|
+
this.sendError(client, error.message);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
sendResponse(client, response) {
|
|
132
|
+
try {
|
|
133
|
+
client.socket.write(JSON.stringify(response) + "\n");
|
|
134
|
+
} catch (error) {
|
|
135
|
+
console.error(`[session-server] Failed to send response:`, error);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
sendError(client, message) {
|
|
139
|
+
this.sendResponse(client, {
|
|
140
|
+
type: "error",
|
|
141
|
+
message
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
async shutdown() {
|
|
145
|
+
console.log("[session-server] Shutting down...");
|
|
146
|
+
for (const client of this.clients.values()) {
|
|
147
|
+
client.socket.end();
|
|
148
|
+
}
|
|
149
|
+
this.clients.clear();
|
|
150
|
+
return new Promise((resolve) => {
|
|
151
|
+
this.server.close(() => {
|
|
152
|
+
if (fs.existsSync(SOCKET_PATH)) {
|
|
153
|
+
fs.unlinkSync(SOCKET_PATH);
|
|
154
|
+
}
|
|
155
|
+
if (fs.existsSync(PID_PATH)) {
|
|
156
|
+
fs.unlinkSync(PID_PATH);
|
|
157
|
+
}
|
|
158
|
+
console.log("[session-server] Shutdown complete");
|
|
159
|
+
resolve();
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
function isSessionRunning() {
|
|
165
|
+
if (!fs.existsSync(PID_PATH)) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
try {
|
|
169
|
+
const pid = parseInt(fs.readFileSync(PID_PATH, "utf-8").trim(), 10);
|
|
170
|
+
process.kill(pid, 0);
|
|
171
|
+
return true;
|
|
172
|
+
} catch (error) {
|
|
173
|
+
if (fs.existsSync(PID_PATH)) fs.unlinkSync(PID_PATH);
|
|
174
|
+
try {
|
|
175
|
+
if (fs.existsSync(SOCKET_PATH)) fs.unlinkSync(SOCKET_PATH);
|
|
176
|
+
} catch (e) {
|
|
177
|
+
}
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function getSocketPath() {
|
|
182
|
+
return SOCKET_PATH;
|
|
183
|
+
}
|
|
184
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
185
|
+
const server = new SessionServer();
|
|
186
|
+
server.start().then(() => {
|
|
187
|
+
console.log("[session-server] Server started successfully");
|
|
188
|
+
process.on("SIGINT", async () => {
|
|
189
|
+
console.log("\n[session-server] Received SIGINT, shutting down...");
|
|
190
|
+
await server.shutdown();
|
|
191
|
+
process.exit(0);
|
|
192
|
+
});
|
|
193
|
+
process.on("SIGTERM", async () => {
|
|
194
|
+
console.log("\n[session-server] Received SIGTERM, shutting down...");
|
|
195
|
+
await server.shutdown();
|
|
196
|
+
process.exit(0);
|
|
197
|
+
});
|
|
198
|
+
}).catch((error) => {
|
|
199
|
+
console.error("[session-server] Failed to start:", error);
|
|
200
|
+
process.exit(1);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export {
|
|
205
|
+
SessionServer,
|
|
206
|
+
isSessionRunning,
|
|
207
|
+
getSocketPath
|
|
208
|
+
};
|
package/dist/cli.js
CHANGED
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
} from "./chunk-AJSYOXXZ.js";
|
|
5
5
|
import {
|
|
6
6
|
execute
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-SVB7OJDA.js";
|
|
8
|
+
import "./chunk-BAO2WV34.js";
|
|
9
9
|
import "./chunk-HRHAMPOB.js";
|
|
10
10
|
import "./chunk-NKA6ZJDV.js";
|
|
11
11
|
import "./chunk-3UW6GWYQ.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.61",
|
|
20
20
|
description: "LLM-Augmented Declarative Execution",
|
|
21
21
|
type: "module",
|
|
22
22
|
main: "dist/index.js",
|
|
@@ -75,9 +75,22 @@ async function main() {
|
|
|
75
75
|
if (args.includes("--help") || args.includes("-h")) {
|
|
76
76
|
console.log("Usage: dirac <file.di|file.bk>");
|
|
77
77
|
console.log(" dirac shell [options]");
|
|
78
|
+
console.log(" dirac agent <command>");
|
|
78
79
|
console.log("");
|
|
79
80
|
console.log("Commands:");
|
|
80
81
|
console.log(" shell Start interactive shell (REPL)");
|
|
82
|
+
console.log(" shell --agent Connect shell to running agent daemon");
|
|
83
|
+
console.log(" agent start Start persistent agent daemon");
|
|
84
|
+
console.log(" agent stop Stop agent daemon");
|
|
85
|
+
console.log(" agent status Check agent status");
|
|
86
|
+
console.log(" agent restart Restart agent daemon");
|
|
87
|
+
console.log(" agent logs Show agent logs");
|
|
88
|
+
console.log(" shell --daemon Start shell with persistent daemon (experimental)");
|
|
89
|
+
console.log("");
|
|
90
|
+
console.log("Shell tips:");
|
|
91
|
+
console.log(" Press Ctrl-Z to suspend shell, then `bg` to run in background");
|
|
92
|
+
console.log(" Use `fg` to bring it back to foreground");
|
|
93
|
+
console.log(" Cron jobs and run-at tasks continue running in background");
|
|
81
94
|
console.log("");
|
|
82
95
|
console.log("File formats:");
|
|
83
96
|
console.log(" .di XML notation (verbose)");
|
|
@@ -98,13 +111,54 @@ async function main() {
|
|
|
98
111
|
console.log(package_default.version);
|
|
99
112
|
process.exit(0);
|
|
100
113
|
}
|
|
114
|
+
if (args[0] === "agent") {
|
|
115
|
+
const subcommand = args[1];
|
|
116
|
+
if (subcommand === "daemon") {
|
|
117
|
+
const { runAgentDaemon } = await import("./agent-3VQNLFHO.js");
|
|
118
|
+
await runAgentDaemon();
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const { AgentCLI } = await import("./agent-3VQNLFHO.js");
|
|
122
|
+
const agent = new AgentCLI();
|
|
123
|
+
switch (subcommand) {
|
|
124
|
+
case "start":
|
|
125
|
+
await agent.start();
|
|
126
|
+
break;
|
|
127
|
+
case "stop":
|
|
128
|
+
await agent.stop();
|
|
129
|
+
break;
|
|
130
|
+
case "status":
|
|
131
|
+
await agent.status();
|
|
132
|
+
break;
|
|
133
|
+
case "restart":
|
|
134
|
+
await agent.restart();
|
|
135
|
+
break;
|
|
136
|
+
case "logs":
|
|
137
|
+
const follow = args.includes("-f") || args.includes("--follow");
|
|
138
|
+
await agent.logs(follow);
|
|
139
|
+
break;
|
|
140
|
+
default:
|
|
141
|
+
console.error("Unknown agent command:", subcommand);
|
|
142
|
+
console.error("Available commands: start, stop, status, restart, logs");
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
101
147
|
if (args[0] === "shell") {
|
|
102
|
-
const { DiracShell } = await import("./shell-
|
|
148
|
+
const { DiracShell } = await import("./shell-KGS3I6WX.js");
|
|
149
|
+
const { SessionServer, isSessionRunning, getSocketPath } = await import("./session-server-BQH56RCK.js");
|
|
150
|
+
const { SessionClient } = await import("./session-client-3VTC5MLO.js");
|
|
151
|
+
const daemonMode = args.includes("--daemon") || args.includes("-d");
|
|
152
|
+
const agentMode = args.includes("--agent") || args.includes("-a");
|
|
103
153
|
const shellConfig = { debug: false };
|
|
104
154
|
for (let i = 1; i < args.length; i++) {
|
|
105
155
|
const arg = args[i];
|
|
106
156
|
if (arg === "--debug") {
|
|
107
157
|
shellConfig.debug = true;
|
|
158
|
+
} else if (arg === "--daemon" || arg === "-d") {
|
|
159
|
+
continue;
|
|
160
|
+
} else if (arg === "--agent" || arg === "-a") {
|
|
161
|
+
continue;
|
|
108
162
|
} else if ((arg === "-f" || arg === "--config") && i + 1 < args.length) {
|
|
109
163
|
const configPath = resolve(args[++i]);
|
|
110
164
|
if (fs.existsSync(configPath)) {
|
|
@@ -131,10 +185,59 @@ async function main() {
|
|
|
131
185
|
}
|
|
132
186
|
}
|
|
133
187
|
}
|
|
188
|
+
if (agentMode) {
|
|
189
|
+
if (!isSessionRunning()) {
|
|
190
|
+
console.error("Error: No agent is running");
|
|
191
|
+
console.error("Start the agent first with: dirac agent start");
|
|
192
|
+
process.exit(1);
|
|
193
|
+
}
|
|
194
|
+
console.log("Connecting to agent...");
|
|
195
|
+
const client = new SessionClient({ socketPath: getSocketPath() });
|
|
196
|
+
client.on("error", (error) => {
|
|
197
|
+
console.error("Agent error:", error);
|
|
198
|
+
});
|
|
199
|
+
try {
|
|
200
|
+
await client.connect();
|
|
201
|
+
console.log("Connected to agent at", getSocketPath());
|
|
202
|
+
console.log("Session state is persistent across disconnects");
|
|
203
|
+
console.log("");
|
|
204
|
+
const shell2 = new DiracShell(shellConfig);
|
|
205
|
+
shell2.setClient(client);
|
|
206
|
+
process.on("SIGINT", async () => {
|
|
207
|
+
await client.disconnect();
|
|
208
|
+
process.exit(0);
|
|
209
|
+
});
|
|
210
|
+
await shell2.start();
|
|
211
|
+
} catch (error) {
|
|
212
|
+
console.error("Failed to connect to agent:", error);
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (daemonMode) {
|
|
218
|
+
console.log("Note: Daemon mode is under development.");
|
|
219
|
+
console.log("For now, use Ctrl-Z + bg to background the shell.");
|
|
220
|
+
console.log("");
|
|
221
|
+
}
|
|
134
222
|
const shell = new DiracShell(shellConfig);
|
|
135
223
|
await shell.start();
|
|
136
224
|
return;
|
|
137
225
|
}
|
|
226
|
+
if (args[0] === "daemon") {
|
|
227
|
+
const { SessionServer } = await import("./session-server-BQH56RCK.js");
|
|
228
|
+
const server = new SessionServer();
|
|
229
|
+
await server.start();
|
|
230
|
+
console.log("Session daemon started");
|
|
231
|
+
process.on("SIGINT", async () => {
|
|
232
|
+
await server.shutdown();
|
|
233
|
+
process.exit(0);
|
|
234
|
+
});
|
|
235
|
+
process.on("SIGTERM", async () => {
|
|
236
|
+
await server.shutdown();
|
|
237
|
+
process.exit(0);
|
|
238
|
+
});
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
138
241
|
if (args.length === 0) {
|
|
139
242
|
console.error("Usage: dirac <file.di|file.bk>");
|
|
140
243
|
console.error(" dirac shell [options]");
|
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-SVB7OJDA.js";
|
|
6
6
|
import {
|
|
7
7
|
integrate
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-BAO2WV34.js";
|
|
9
9
|
import {
|
|
10
10
|
DiracParser
|
|
11
11
|
} from "./chunk-HRHAMPOB.js";
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// src/session-client.ts
|
|
2
|
+
import net from "net";
|
|
3
|
+
import { EventEmitter } from "events";
|
|
4
|
+
var SessionClient = class extends EventEmitter {
|
|
5
|
+
socket = null;
|
|
6
|
+
buffer = "";
|
|
7
|
+
connected = false;
|
|
8
|
+
options;
|
|
9
|
+
constructor(options) {
|
|
10
|
+
super();
|
|
11
|
+
this.options = {
|
|
12
|
+
autoReconnect: false,
|
|
13
|
+
reconnectDelay: 1e3,
|
|
14
|
+
...options
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
async connect() {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
this.socket = net.connect(this.options.socketPath);
|
|
20
|
+
this.socket.on("connect", () => {
|
|
21
|
+
this.emit("socket-connected");
|
|
22
|
+
});
|
|
23
|
+
this.socket.on("data", (data) => {
|
|
24
|
+
this.buffer += data.toString();
|
|
25
|
+
const lines = this.buffer.split("\n");
|
|
26
|
+
this.buffer = lines.pop() || "";
|
|
27
|
+
for (const line of lines) {
|
|
28
|
+
if (!line.trim()) continue;
|
|
29
|
+
try {
|
|
30
|
+
const message = JSON.parse(line);
|
|
31
|
+
this.handleMessage(message);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
this.emit("error", new Error(`Invalid message: ${error}`));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
this.socket.on("end", () => {
|
|
38
|
+
this.connected = false;
|
|
39
|
+
this.emit("disconnected");
|
|
40
|
+
if (this.options.autoReconnect) {
|
|
41
|
+
setTimeout(() => this.connect(), this.options.reconnectDelay);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
this.socket.on("error", (error) => {
|
|
45
|
+
this.connected = false;
|
|
46
|
+
reject(error);
|
|
47
|
+
this.emit("error", error);
|
|
48
|
+
});
|
|
49
|
+
this.once("welcome", () => {
|
|
50
|
+
this.connected = true;
|
|
51
|
+
resolve();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
handleMessage(message) {
|
|
56
|
+
const { type, data, message: msg } = message;
|
|
57
|
+
switch (type) {
|
|
58
|
+
case "welcome":
|
|
59
|
+
this.emit("welcome", msg);
|
|
60
|
+
break;
|
|
61
|
+
case "output":
|
|
62
|
+
this.emit("output", data);
|
|
63
|
+
break;
|
|
64
|
+
case "error":
|
|
65
|
+
this.emit("error", new Error(msg || data));
|
|
66
|
+
break;
|
|
67
|
+
case "vars":
|
|
68
|
+
this.emit("vars", data);
|
|
69
|
+
break;
|
|
70
|
+
case "state":
|
|
71
|
+
this.emit("state", data);
|
|
72
|
+
break;
|
|
73
|
+
case "shutdown":
|
|
74
|
+
this.emit("shutdown");
|
|
75
|
+
break;
|
|
76
|
+
default:
|
|
77
|
+
this.emit("message", message);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async execute(command) {
|
|
81
|
+
return new Promise((resolve, reject) => {
|
|
82
|
+
if (!this.socket) {
|
|
83
|
+
reject(new Error("Not connected to session: socket is null"));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (!this.connected) {
|
|
87
|
+
reject(new Error("Not connected to session: connected flag is false"));
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
this.send({ type: "execute", data: { command } });
|
|
91
|
+
const timeout = setTimeout(() => {
|
|
92
|
+
reject(new Error("Execution timeout"));
|
|
93
|
+
}, 3e4);
|
|
94
|
+
const onOutput = (output) => {
|
|
95
|
+
clearTimeout(timeout);
|
|
96
|
+
this.off("error", onError);
|
|
97
|
+
resolve(output);
|
|
98
|
+
};
|
|
99
|
+
const onError = (error) => {
|
|
100
|
+
clearTimeout(timeout);
|
|
101
|
+
this.off("output", onOutput);
|
|
102
|
+
reject(error);
|
|
103
|
+
};
|
|
104
|
+
this.once("output", onOutput);
|
|
105
|
+
this.once("error", onError);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
async getVars() {
|
|
109
|
+
return new Promise((resolve, reject) => {
|
|
110
|
+
if (!this.connected || !this.socket) {
|
|
111
|
+
reject(new Error("Not connected to session"));
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
this.send({ type: "getVars" });
|
|
115
|
+
const timeout = setTimeout(() => {
|
|
116
|
+
reject(new Error("Timeout getting variables"));
|
|
117
|
+
}, 5e3);
|
|
118
|
+
const onVars = (vars) => {
|
|
119
|
+
clearTimeout(timeout);
|
|
120
|
+
resolve(vars);
|
|
121
|
+
};
|
|
122
|
+
this.once("vars", onVars);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
async getState() {
|
|
126
|
+
return new Promise((resolve, reject) => {
|
|
127
|
+
if (!this.socket) {
|
|
128
|
+
reject(new Error("Not connected to session: socket is null"));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (!this.connected) {
|
|
132
|
+
reject(new Error("Not connected to session: connected flag is false"));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
this.send({ type: "getState" });
|
|
136
|
+
const timeout = setTimeout(() => {
|
|
137
|
+
reject(new Error("Timeout getting state"));
|
|
138
|
+
}, 5e3);
|
|
139
|
+
const onState = (state) => {
|
|
140
|
+
clearTimeout(timeout);
|
|
141
|
+
resolve(state);
|
|
142
|
+
};
|
|
143
|
+
this.once("state", onState);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
async shutdown() {
|
|
147
|
+
return new Promise((resolve) => {
|
|
148
|
+
if (!this.connected || !this.socket) {
|
|
149
|
+
resolve();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
this.send({ type: "shutdown" });
|
|
153
|
+
this.once("shutdown", () => {
|
|
154
|
+
resolve();
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
send(message) {
|
|
159
|
+
if (!this.socket || !this.connected) {
|
|
160
|
+
throw new Error("Not connected to session");
|
|
161
|
+
}
|
|
162
|
+
this.socket.write(JSON.stringify(message) + "\n");
|
|
163
|
+
}
|
|
164
|
+
disconnect() {
|
|
165
|
+
if (this.socket) {
|
|
166
|
+
this.socket.end();
|
|
167
|
+
this.socket = null;
|
|
168
|
+
}
|
|
169
|
+
this.connected = false;
|
|
170
|
+
}
|
|
171
|
+
isConnected() {
|
|
172
|
+
return this.connected;
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
export {
|
|
176
|
+
SessionClient
|
|
177
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SessionServer,
|
|
3
|
+
getSocketPath,
|
|
4
|
+
isSessionRunning
|
|
5
|
+
} from "./chunk-WPEAYK2Q.js";
|
|
6
|
+
import "./chunk-BAO2WV34.js";
|
|
7
|
+
import "./chunk-HRHAMPOB.js";
|
|
8
|
+
import "./chunk-NKA6ZJDV.js";
|
|
9
|
+
import "./chunk-3UW6GWYQ.js";
|
|
10
|
+
export {
|
|
11
|
+
SessionServer,
|
|
12
|
+
getSocketPath,
|
|
13
|
+
isSessionRunning
|
|
14
|
+
};
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-AJSYOXXZ.js";
|
|
5
5
|
import {
|
|
6
6
|
integrate
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-BAO2WV34.js";
|
|
8
8
|
import {
|
|
9
9
|
DiracParser
|
|
10
10
|
} from "./chunk-HRHAMPOB.js";
|
|
@@ -23,6 +23,9 @@ var HISTORY_FILE = path.join(os.homedir(), ".dirac_history");
|
|
|
23
23
|
var MAX_HISTORY = 1e3;
|
|
24
24
|
var DiracShell = class {
|
|
25
25
|
session;
|
|
26
|
+
client = null;
|
|
27
|
+
cachedSubroutines = [];
|
|
28
|
+
// Cache for agent mode tab completion
|
|
26
29
|
braketParser;
|
|
27
30
|
xmlParser;
|
|
28
31
|
rl;
|
|
@@ -45,12 +48,31 @@ var DiracShell = class {
|
|
|
45
48
|
this.loadHistory();
|
|
46
49
|
this.setupHandlers();
|
|
47
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Set client for daemon mode
|
|
53
|
+
*/
|
|
54
|
+
setClient(client) {
|
|
55
|
+
this.client = client;
|
|
56
|
+
this.updateCachedSubroutines();
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Update cached subroutines from agent
|
|
60
|
+
*/
|
|
61
|
+
async updateCachedSubroutines() {
|
|
62
|
+
if (!this.client) return;
|
|
63
|
+
try {
|
|
64
|
+
const state = await this.client.getState();
|
|
65
|
+
this.cachedSubroutines = state.subroutines || [];
|
|
66
|
+
} catch (error) {
|
|
67
|
+
}
|
|
68
|
+
}
|
|
48
69
|
completer(line) {
|
|
70
|
+
const subroutines = this.client ? this.cachedSubroutines : this.session.subroutines;
|
|
49
71
|
const attrMatch = line.match(/\|([a-z0-9_-]+)\s+.*?([a-z0-9_-]*)$/i);
|
|
50
72
|
if (attrMatch) {
|
|
51
73
|
const tagName = attrMatch[1];
|
|
52
74
|
const attrPartial = attrMatch[2];
|
|
53
|
-
const subroutine =
|
|
75
|
+
const subroutine = subroutines.find((sub) => sub.name === tagName);
|
|
54
76
|
if (subroutine && subroutine.parameters && subroutine.parameters.length > 0) {
|
|
55
77
|
const matches = subroutine.parameters.filter(
|
|
56
78
|
(p) => p.name.toLowerCase().startsWith(attrPartial.toLowerCase())
|
|
@@ -75,7 +97,7 @@ var DiracShell = class {
|
|
|
75
97
|
const tagCompleteMatch = line.match(/\|([a-z0-9_-]+)$/i);
|
|
76
98
|
if (tagCompleteMatch) {
|
|
77
99
|
const tagName = tagCompleteMatch[1];
|
|
78
|
-
const subroutine =
|
|
100
|
+
const subroutine = subroutines.find((sub) => sub.name === tagName);
|
|
79
101
|
if (subroutine && subroutine.parameters && subroutine.parameters.length > 0) {
|
|
80
102
|
console.log("\n");
|
|
81
103
|
subroutine.parameters.forEach((p) => {
|
|
@@ -91,13 +113,13 @@ var DiracShell = class {
|
|
|
91
113
|
const paramSuggestions = subroutine.parameters.map((p) => `${p.name}=`);
|
|
92
114
|
return [paramSuggestions, ""];
|
|
93
115
|
}
|
|
94
|
-
const subroutineNames =
|
|
116
|
+
const subroutineNames = subroutines.map((sub) => sub.name);
|
|
95
117
|
const matches = subroutineNames.filter(
|
|
96
118
|
(name) => name.toLowerCase().startsWith(tagName.toLowerCase())
|
|
97
119
|
);
|
|
98
120
|
if (matches.length > 0) {
|
|
99
121
|
const completions = matches.map((name) => {
|
|
100
|
-
const sub =
|
|
122
|
+
const sub = subroutines.find((s) => s.name === name);
|
|
101
123
|
const hasParams = sub && sub.parameters && sub.parameters.length > 0;
|
|
102
124
|
return hasParams ? `|${name} ` : `|${name}>`;
|
|
103
125
|
});
|
|
@@ -150,7 +172,10 @@ var DiracShell = class {
|
|
|
150
172
|
});
|
|
151
173
|
this.rl.on("close", () => {
|
|
152
174
|
this.saveHistory();
|
|
153
|
-
|
|
175
|
+
if (this.client) {
|
|
176
|
+
this.client.disconnect();
|
|
177
|
+
}
|
|
178
|
+
import("./schedule-F7JHVWEV.js").then(({ stopAllScheduledTasks }) => {
|
|
154
179
|
stopAllScheduledTasks();
|
|
155
180
|
console.log("\nGoodbye!");
|
|
156
181
|
process.exit(0);
|
|
@@ -249,6 +274,18 @@ var DiracShell = class {
|
|
|
249
274
|
this.inputBuffer = [];
|
|
250
275
|
this.baseIndent = null;
|
|
251
276
|
try {
|
|
277
|
+
if (this.client) {
|
|
278
|
+
const xml2 = this.braketParser.parse(input);
|
|
279
|
+
if (this.config.debug) {
|
|
280
|
+
console.log("[Debug] Sending to agent:\n", xml2);
|
|
281
|
+
}
|
|
282
|
+
const output = await this.client.execute(xml2);
|
|
283
|
+
if (output) {
|
|
284
|
+
console.log(output);
|
|
285
|
+
}
|
|
286
|
+
await this.updateCachedSubroutines();
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
252
289
|
this.session.output = [];
|
|
253
290
|
const xml = this.braketParser.parse(input);
|
|
254
291
|
if (this.config.debug) {
|
|
@@ -321,29 +358,56 @@ Examples:
|
|
|
321
358
|
`);
|
|
322
359
|
break;
|
|
323
360
|
case "vars":
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
361
|
+
try {
|
|
362
|
+
let variables;
|
|
363
|
+
if (this.client) {
|
|
364
|
+
const state = await this.client.getState();
|
|
365
|
+
variables = state.variables || [];
|
|
366
|
+
} else {
|
|
367
|
+
variables = this.session.variables;
|
|
368
|
+
}
|
|
369
|
+
if (variables.length === 0) {
|
|
370
|
+
console.log("No variables defined");
|
|
371
|
+
} else {
|
|
372
|
+
console.log("Variables:");
|
|
373
|
+
for (const v of variables) {
|
|
374
|
+
if (v.visible) {
|
|
375
|
+
console.log(` ${v.name} = ${JSON.stringify(v.value)}`);
|
|
376
|
+
}
|
|
331
377
|
}
|
|
332
378
|
}
|
|
379
|
+
} catch (error) {
|
|
380
|
+
console.error("Error getting variables:", error instanceof Error ? error.message : String(error));
|
|
333
381
|
}
|
|
334
382
|
break;
|
|
335
383
|
case "subs":
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
384
|
+
try {
|
|
385
|
+
let subroutines;
|
|
386
|
+
if (this.client) {
|
|
387
|
+
const state = await this.client.getState();
|
|
388
|
+
console.log("State received:", JSON.stringify(state, null, 2).substring(0, 500));
|
|
389
|
+
subroutines = state.subroutines || [];
|
|
390
|
+
} else {
|
|
391
|
+
subroutines = this.session.subroutines;
|
|
392
|
+
}
|
|
393
|
+
if (!Array.isArray(subroutines)) {
|
|
394
|
+
console.error("Error: subroutines is not an array, it is:", typeof subroutines);
|
|
395
|
+
break;
|
|
396
|
+
}
|
|
397
|
+
if (subroutines.length === 0) {
|
|
398
|
+
console.log("No subroutines defined");
|
|
399
|
+
} else {
|
|
400
|
+
console.log("Subroutines:");
|
|
401
|
+
for (const s of subroutines) {
|
|
402
|
+
const params = s.parameters?.map((p) => p.name).join(", ") || "";
|
|
403
|
+
console.log(` ${s.name}(${params})`);
|
|
404
|
+
if (s.description) {
|
|
405
|
+
console.log(` ${s.description}`);
|
|
406
|
+
}
|
|
345
407
|
}
|
|
346
408
|
}
|
|
409
|
+
} catch (error) {
|
|
410
|
+
console.error("Error getting subroutines:", error instanceof Error ? error.message : String(error));
|
|
347
411
|
}
|
|
348
412
|
break;
|
|
349
413
|
case "clear":
|
|
@@ -477,7 +541,7 @@ Examples:
|
|
|
477
541
|
break;
|
|
478
542
|
case "tasks":
|
|
479
543
|
try {
|
|
480
|
-
const { listScheduledTasks } = await import("./schedule-
|
|
544
|
+
const { listScheduledTasks } = await import("./schedule-F7JHVWEV.js");
|
|
481
545
|
const tasks = listScheduledTasks();
|
|
482
546
|
if (tasks.length === 0) {
|
|
483
547
|
console.log("No scheduled tasks running.");
|
|
@@ -496,7 +560,7 @@ Examples:
|
|
|
496
560
|
console.log("Usage: :stop <task-name>");
|
|
497
561
|
} else {
|
|
498
562
|
try {
|
|
499
|
-
const { stopScheduledTask } = await import("./schedule-
|
|
563
|
+
const { stopScheduledTask } = await import("./schedule-F7JHVWEV.js");
|
|
500
564
|
const taskName = args[0];
|
|
501
565
|
const stopped = stopScheduledTask(taskName);
|
|
502
566
|
if (stopped) {
|
|
@@ -511,7 +575,7 @@ Examples:
|
|
|
511
575
|
break;
|
|
512
576
|
case "stopall":
|
|
513
577
|
try {
|
|
514
|
-
const { stopAllScheduledTasks } = await import("./schedule-
|
|
578
|
+
const { stopAllScheduledTasks } = await import("./schedule-F7JHVWEV.js");
|
|
515
579
|
stopAllScheduledTasks();
|
|
516
580
|
console.log("All scheduled tasks stopped.");
|
|
517
581
|
} catch (error) {
|
|
@@ -520,7 +584,7 @@ Examples:
|
|
|
520
584
|
break;
|
|
521
585
|
case "crons":
|
|
522
586
|
try {
|
|
523
|
-
const { listCronJobs } = await import("./cron-
|
|
587
|
+
const { listCronJobs } = await import("./cron-SUYXFAW7.js");
|
|
524
588
|
const jobs = listCronJobs();
|
|
525
589
|
if (jobs.length === 0) {
|
|
526
590
|
console.log("No cron jobs running.");
|
|
@@ -540,7 +604,7 @@ Examples:
|
|
|
540
604
|
console.log("Usage: :stopcron <job-name>");
|
|
541
605
|
} else {
|
|
542
606
|
try {
|
|
543
|
-
const { stopCronJob } = await import("./cron-
|
|
607
|
+
const { stopCronJob } = await import("./cron-SUYXFAW7.js");
|
|
544
608
|
const jobName = args[0];
|
|
545
609
|
const stopped = stopCronJob(jobName);
|
|
546
610
|
if (stopped) {
|
|
@@ -555,7 +619,7 @@ Examples:
|
|
|
555
619
|
break;
|
|
556
620
|
case "stopallcrons":
|
|
557
621
|
try {
|
|
558
|
-
const { stopAllCronJobs } = await import("./cron-
|
|
622
|
+
const { stopAllCronJobs } = await import("./cron-SUYXFAW7.js");
|
|
559
623
|
stopAllCronJobs();
|
|
560
624
|
console.log("All cron jobs stopped.");
|
|
561
625
|
} catch (error) {
|
|
@@ -564,7 +628,7 @@ Examples:
|
|
|
564
628
|
break;
|
|
565
629
|
case "scheduled":
|
|
566
630
|
try {
|
|
567
|
-
const { listScheduledRuns } = await import("./run-at-
|
|
631
|
+
const { listScheduledRuns } = await import("./run-at-BBMPAVED.js");
|
|
568
632
|
const runs = listScheduledRuns();
|
|
569
633
|
if (runs.length === 0) {
|
|
570
634
|
console.log("No scheduled runs pending.");
|
|
@@ -584,7 +648,7 @@ Examples:
|
|
|
584
648
|
console.log("Usage: :cancel <run-name>");
|
|
585
649
|
} else {
|
|
586
650
|
try {
|
|
587
|
-
const { cancelScheduledRun } = await import("./run-at-
|
|
651
|
+
const { cancelScheduledRun } = await import("./run-at-BBMPAVED.js");
|
|
588
652
|
const runName = args[0];
|
|
589
653
|
const cancelled = cancelScheduledRun(runName);
|
|
590
654
|
if (cancelled) {
|
|
@@ -599,7 +663,7 @@ Examples:
|
|
|
599
663
|
break;
|
|
600
664
|
case "cancelall":
|
|
601
665
|
try {
|
|
602
|
-
const { cancelAllScheduledRuns } = await import("./run-at-
|
|
666
|
+
const { cancelAllScheduledRuns } = await import("./run-at-BBMPAVED.js");
|
|
603
667
|
cancelAllScheduledRuns();
|
|
604
668
|
console.log("All scheduled runs cancelled.");
|
|
605
669
|
} catch (error) {
|
|
@@ -709,9 +773,14 @@ Examples:
|
|
|
709
773
|
}
|
|
710
774
|
console.log(`Loading init script: ${scriptPath}`);
|
|
711
775
|
const scriptContent = fs.readFileSync(resolvedPath, "utf-8");
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
776
|
+
if (this.client) {
|
|
777
|
+
const xml = this.braketParser.parse(scriptContent);
|
|
778
|
+
await this.client.execute(xml);
|
|
779
|
+
} else {
|
|
780
|
+
const xml = this.braketParser.parse(scriptContent);
|
|
781
|
+
const ast = this.xmlParser.parse(xml);
|
|
782
|
+
await integrate(this.session, ast);
|
|
783
|
+
}
|
|
715
784
|
console.log(`Init script loaded.
|
|
716
785
|
`);
|
|
717
786
|
} catch (err) {
|
package/dist/test-runner.js
CHANGED