@bookedsolid/reagent 0.12.2 → 0.13.1
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/README.md +373 -943
- package/dist/cli/commands/init/index.d.ts.map +1 -1
- package/dist/cli/commands/init/index.js +45 -35
- package/dist/cli/commands/init/index.js.map +1 -1
- package/dist/cli/commands/init/mcp-config.d.ts +11 -0
- package/dist/cli/commands/init/mcp-config.d.ts.map +1 -0
- package/dist/cli/commands/init/mcp-config.js +64 -0
- package/dist/cli/commands/init/mcp-config.js.map +1 -0
- package/dist/cli/commands/init/policy.d.ts +1 -1
- package/dist/cli/commands/init/policy.d.ts.map +1 -1
- package/dist/cli/commands/init/policy.js +2 -2
- package/dist/cli/commands/init/policy.js.map +1 -1
- package/dist/cli/index.js +2 -11
- package/dist/cli/index.js.map +1 -1
- package/hooks/_lib/common.sh +18 -0
- package/hooks/settings-protection.sh +5 -3
- package/package.json +2 -9
- package/profiles/astro/hooks/astro-ssr-guard.sh +1 -0
- package/profiles/drupal/hooks/drupal-coding-standards.sh +1 -0
- package/profiles/drupal/hooks/hook-update-guard.sh +1 -0
- package/profiles/lit-wc/hooks/cem-integrity-gate.sh +1 -0
- package/profiles/lit-wc/hooks/shadow-dom-guard.sh +1 -0
- package/profiles/nextjs/hooks/server-component-drift.sh +1 -0
- package/dist/cli/commands/daemon/eject.d.ts +0 -13
- package/dist/cli/commands/daemon/eject.d.ts.map +0 -1
- package/dist/cli/commands/daemon/eject.js +0 -74
- package/dist/cli/commands/daemon/eject.js.map +0 -1
- package/dist/cli/commands/daemon/index.d.ts +0 -5
- package/dist/cli/commands/daemon/index.d.ts.map +0 -1
- package/dist/cli/commands/daemon/index.js +0 -64
- package/dist/cli/commands/daemon/index.js.map +0 -1
- package/dist/cli/commands/daemon/restart.d.ts +0 -10
- package/dist/cli/commands/daemon/restart.d.ts.map +0 -1
- package/dist/cli/commands/daemon/restart.js +0 -20
- package/dist/cli/commands/daemon/restart.js.map +0 -1
- package/dist/cli/commands/daemon/start.d.ts +0 -2
- package/dist/cli/commands/daemon/start.d.ts.map +0 -1
- package/dist/cli/commands/daemon/start.js +0 -143
- package/dist/cli/commands/daemon/start.js.map +0 -1
- package/dist/cli/commands/daemon/status.d.ts +0 -2
- package/dist/cli/commands/daemon/status.d.ts.map +0 -1
- package/dist/cli/commands/daemon/status.js +0 -90
- package/dist/cli/commands/daemon/status.js.map +0 -1
- package/dist/cli/commands/daemon/stop.d.ts +0 -2
- package/dist/cli/commands/daemon/stop.d.ts.map +0 -1
- package/dist/cli/commands/daemon/stop.js +0 -73
- package/dist/cli/commands/daemon/stop.js.map +0 -1
- package/dist/config/daemon-loader.d.ts +0 -16
- package/dist/config/daemon-loader.d.ts.map +0 -1
- package/dist/config/daemon-loader.js +0 -76
- package/dist/config/daemon-loader.js.map +0 -1
- package/dist/types/daemon.d.ts +0 -45
- package/dist/types/daemon.d.ts.map +0 -1
- package/dist/types/daemon.js +0 -2
- package/dist/types/daemon.js.map +0 -1
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { runDaemonStart } from './start.js';
|
|
2
|
-
import { runDaemonStop } from './stop.js';
|
|
3
|
-
import { runDaemonStatus } from './status.js';
|
|
4
|
-
import { runDaemonRestart } from './restart.js';
|
|
5
|
-
import { runDaemonEject } from './eject.js';
|
|
6
|
-
/**
|
|
7
|
-
* Entry point for `reagent daemon <subcommand> [options]`.
|
|
8
|
-
*/
|
|
9
|
-
export function runDaemon(args) {
|
|
10
|
-
const [sub, ...rest] = args;
|
|
11
|
-
if (!sub || sub === 'help' || sub === '--help' || sub === '-h') {
|
|
12
|
-
printDaemonHelp();
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
switch (sub) {
|
|
16
|
-
case 'start':
|
|
17
|
-
runDaemonStart(rest);
|
|
18
|
-
break;
|
|
19
|
-
case 'stop':
|
|
20
|
-
runDaemonStop(rest);
|
|
21
|
-
break;
|
|
22
|
-
case 'status':
|
|
23
|
-
runDaemonStatus(rest);
|
|
24
|
-
break;
|
|
25
|
-
case 'restart':
|
|
26
|
-
runDaemonRestart(rest);
|
|
27
|
-
break;
|
|
28
|
-
case 'eject':
|
|
29
|
-
runDaemonEject(rest);
|
|
30
|
-
break;
|
|
31
|
-
default:
|
|
32
|
-
console.error(`\nUnknown daemon subcommand: ${sub}`);
|
|
33
|
-
printDaemonHelp();
|
|
34
|
-
process.exit(1);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
function printDaemonHelp() {
|
|
38
|
-
console.log(`
|
|
39
|
-
reagent daemon — persistent HTTP/SSE multi-project MCP gateway
|
|
40
|
-
|
|
41
|
-
Usage:
|
|
42
|
-
reagent daemon <subcommand> [options]
|
|
43
|
-
|
|
44
|
-
Subcommands:
|
|
45
|
-
start Start the daemon in the background
|
|
46
|
-
stop Stop the running daemon
|
|
47
|
-
status Show daemon health and active sessions
|
|
48
|
-
restart Gracefully restart the daemon
|
|
49
|
-
eject Nuclear kill — SIGKILL daemon and sweep orphans (last resort)
|
|
50
|
-
|
|
51
|
-
Options for start:
|
|
52
|
-
--port <port> Override the listen port (default: 3737)
|
|
53
|
-
--bind <addr> Override the bind address (default: 127.0.0.1)
|
|
54
|
-
--foreground Run in foreground instead of backgrounding
|
|
55
|
-
|
|
56
|
-
Examples:
|
|
57
|
-
reagent daemon start
|
|
58
|
-
reagent daemon start --port 8888
|
|
59
|
-
reagent daemon status
|
|
60
|
-
reagent daemon stop
|
|
61
|
-
reagent daemon restart
|
|
62
|
-
`);
|
|
63
|
-
}
|
|
64
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/cli/commands/daemon/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAE5B,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC/D,eAAe,EAAE,CAAC;QAClB,OAAO;IACT,CAAC;IAED,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,OAAO;YACV,cAAc,CAAC,IAAI,CAAC,CAAC;YACrB,MAAM;QACR,KAAK,MAAM;YACT,aAAa,CAAC,IAAI,CAAC,CAAC;YACpB,MAAM;QACR,KAAK,QAAQ;YACX,eAAe,CAAC,IAAI,CAAC,CAAC;YACtB,MAAM;QACR,KAAK,SAAS;YACZ,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACvB,MAAM;QACR,KAAK,OAAO;YACV,cAAc,CAAC,IAAI,CAAC,CAAC;YACrB,MAAM;QACR;YACE,OAAO,CAAC,KAAK,CAAC,gCAAgC,GAAG,EAAE,CAAC,CAAC;YACrD,eAAe,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;CAwBb,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Graceful restart: stop the running daemon (SIGTERM + poll for exit),
|
|
3
|
-
* then start a fresh instance once the process has actually exited.
|
|
4
|
-
*
|
|
5
|
-
* runDaemonStop accepts an onDone callback that fires only after the daemon
|
|
6
|
-
* process is confirmed dead, preventing the new instance from racing the old
|
|
7
|
-
* one for the port binding.
|
|
8
|
-
*/
|
|
9
|
-
export declare function runDaemonRestart(args: string[]): void;
|
|
10
|
-
//# sourceMappingURL=restart.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"restart.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/daemon/restart.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAQrD"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { runDaemonStop } from './stop.js';
|
|
2
|
-
import { runDaemonStart } from './start.js';
|
|
3
|
-
/**
|
|
4
|
-
* Graceful restart: stop the running daemon (SIGTERM + poll for exit),
|
|
5
|
-
* then start a fresh instance once the process has actually exited.
|
|
6
|
-
*
|
|
7
|
-
* runDaemonStop accepts an onDone callback that fires only after the daemon
|
|
8
|
-
* process is confirmed dead, preventing the new instance from racing the old
|
|
9
|
-
* one for the port binding.
|
|
10
|
-
*/
|
|
11
|
-
export function runDaemonRestart(args) {
|
|
12
|
-
console.log('\nRestarting reagent daemon...');
|
|
13
|
-
runDaemonStop([], () => {
|
|
14
|
-
// Brief pause so the OS can release the port binding before re-launch.
|
|
15
|
-
setTimeout(() => {
|
|
16
|
-
runDaemonStart(args);
|
|
17
|
-
}, 200);
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
//# sourceMappingURL=restart.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"restart.js","sourceRoot":"","sources":["../../../../src/cli/commands/daemon/restart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAc;IAC7C,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAC9C,aAAa,CAAC,EAAE,EAAE,GAAG,EAAE;QACrB,uEAAuE;QACvE,UAAU,CAAC,GAAG,EAAE;YACd,cAAc,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/daemon/start.ts"],"names":[],"mappings":"AAiFA,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA4FnD"}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import os from 'node:os';
|
|
4
|
-
import { spawn } from 'node:child_process';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import { parseFlag } from '../../utils.js';
|
|
7
|
-
import { loadDaemonConfig } from '../../../config/daemon-loader.js';
|
|
8
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
-
const __dirname = path.dirname(__filename);
|
|
10
|
-
/** Path to the PID file written when the daemon starts. */
|
|
11
|
-
function getPidFilePath() {
|
|
12
|
-
return path.join(os.homedir(), '.reagent', 'daemon.pid');
|
|
13
|
-
}
|
|
14
|
-
/** Resolve the compiled Rust daemon binary path relative to the package root. */
|
|
15
|
-
function resolveDaemonBinary() {
|
|
16
|
-
// Walk up from dist/cli/commands/daemon/ to find the package root, then
|
|
17
|
-
// look for the platform binary in bin/reagent-daemon-<platform>
|
|
18
|
-
const pkgRoot = path.join(__dirname, '..', '..', '..', '..');
|
|
19
|
-
const platform = process.platform;
|
|
20
|
-
const arch = process.arch;
|
|
21
|
-
// Map Node.js platform/arch to the binary name convention used by the
|
|
22
|
-
// Rust build and npm optional dependency packages
|
|
23
|
-
const platformMap = {
|
|
24
|
-
'darwin-arm64': 'reagent-daemon-darwin-arm64',
|
|
25
|
-
'darwin-x64': 'reagent-daemon-darwin-x64',
|
|
26
|
-
'linux-x64': 'reagent-daemon-linux-x64',
|
|
27
|
-
};
|
|
28
|
-
const key = `${platform}-${arch}`;
|
|
29
|
-
const binaryName = platformMap[key] ?? 'reagent-daemon';
|
|
30
|
-
// Check platform-specific optional package first (npm distribution)
|
|
31
|
-
const optionalPkgBin = path.join(pkgRoot, 'node_modules', `@bookedsolid/${binaryName}`, 'bin', binaryName);
|
|
32
|
-
if (fs.existsSync(optionalPkgBin)) {
|
|
33
|
-
return optionalPkgBin;
|
|
34
|
-
}
|
|
35
|
-
// Fall back to local build output (development)
|
|
36
|
-
const localBin = path.join(pkgRoot, 'daemon', 'target', 'release', 'reagent-daemon');
|
|
37
|
-
if (fs.existsSync(localBin)) {
|
|
38
|
-
return localBin;
|
|
39
|
-
}
|
|
40
|
-
throw new Error(`reagent daemon binary not found for platform ${key}.\n` +
|
|
41
|
-
` Looked for: ${optionalPkgBin}\n` +
|
|
42
|
-
` : ${localBin}\n` +
|
|
43
|
-
` Run \`cargo build --release\` inside daemon/ to build locally, or ensure the\n` +
|
|
44
|
-
` @bookedsolid/${binaryName} optional package is installed.`);
|
|
45
|
-
}
|
|
46
|
-
/** Read the existing PID file and check if the process is alive. */
|
|
47
|
-
function getRunningPid() {
|
|
48
|
-
const pidPath = getPidFilePath();
|
|
49
|
-
if (!fs.existsSync(pidPath))
|
|
50
|
-
return null;
|
|
51
|
-
const raw = fs.readFileSync(pidPath, 'utf8').trim();
|
|
52
|
-
const pid = parseInt(raw, 10);
|
|
53
|
-
if (isNaN(pid))
|
|
54
|
-
return null;
|
|
55
|
-
// Send signal 0 to check if the process exists without affecting it
|
|
56
|
-
try {
|
|
57
|
-
process.kill(pid, 0);
|
|
58
|
-
return pid;
|
|
59
|
-
}
|
|
60
|
-
catch {
|
|
61
|
-
// Process not found — stale PID file
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
export function runDaemonStart(args) {
|
|
66
|
-
const foreground = args.includes('--foreground');
|
|
67
|
-
const portOverride = parseFlag(args, '--port');
|
|
68
|
-
const bindOverride = parseFlag(args, '--bind');
|
|
69
|
-
// Check if already running
|
|
70
|
-
const existingPid = getRunningPid();
|
|
71
|
-
if (existingPid !== null) {
|
|
72
|
-
console.log(`\nreagent daemon is already running (PID ${existingPid})`);
|
|
73
|
-
console.log(` Run \`reagent daemon status\` to inspect it.`);
|
|
74
|
-
console.log(` Run \`reagent daemon restart\` to restart it.\n`);
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
// Load config (falls back to defaults if ~/.reagent/daemon.yaml absent)
|
|
78
|
-
let config;
|
|
79
|
-
try {
|
|
80
|
-
config = loadDaemonConfig();
|
|
81
|
-
}
|
|
82
|
-
catch (err) {
|
|
83
|
-
console.error(`[reagent] Failed to load daemon config: ${err instanceof Error ? err.message : err}`);
|
|
84
|
-
process.exit(1);
|
|
85
|
-
}
|
|
86
|
-
const port = portOverride ? parseInt(portOverride, 10) : config.port;
|
|
87
|
-
const bind = bindOverride ?? config.bind;
|
|
88
|
-
if (isNaN(port) || port < 1 || port > 65535) {
|
|
89
|
-
console.error(`[reagent] Invalid port: ${portOverride}`);
|
|
90
|
-
process.exit(1);
|
|
91
|
-
}
|
|
92
|
-
// Resolve binary
|
|
93
|
-
let binaryPath;
|
|
94
|
-
try {
|
|
95
|
-
binaryPath = resolveDaemonBinary();
|
|
96
|
-
}
|
|
97
|
-
catch (err) {
|
|
98
|
-
console.error(`[reagent] ${err instanceof Error ? err.message : err}`);
|
|
99
|
-
process.exit(1);
|
|
100
|
-
}
|
|
101
|
-
const env = {
|
|
102
|
-
...process.env,
|
|
103
|
-
RUST_LOG: config.log_level,
|
|
104
|
-
REAGENT_DAEMON_PORT: String(port),
|
|
105
|
-
REAGENT_DAEMON_BIND: bind,
|
|
106
|
-
REAGENT_DAEMON_SESSION_TTL: String(config.session_ttl_minutes),
|
|
107
|
-
};
|
|
108
|
-
if (foreground) {
|
|
109
|
-
console.log(`\nStarting reagent daemon on ${bind}:${port} (foreground)`);
|
|
110
|
-
console.log(` Binary: ${binaryPath}\n`);
|
|
111
|
-
const child = spawn(binaryPath, [], { env, stdio: 'inherit' });
|
|
112
|
-
child.on('exit', (code) => {
|
|
113
|
-
process.exit(code ?? 0);
|
|
114
|
-
});
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
// Background mode: detach child process and write PID file
|
|
118
|
-
const logDir = path.join(os.homedir(), '.reagent');
|
|
119
|
-
if (!fs.existsSync(logDir)) {
|
|
120
|
-
fs.mkdirSync(logDir, { recursive: true });
|
|
121
|
-
}
|
|
122
|
-
const logFile = path.join(logDir, 'daemon.log');
|
|
123
|
-
const logFd = fs.openSync(logFile, 'a');
|
|
124
|
-
const child = spawn(binaryPath, [], {
|
|
125
|
-
env,
|
|
126
|
-
stdio: ['ignore', logFd, logFd],
|
|
127
|
-
detached: true,
|
|
128
|
-
});
|
|
129
|
-
child.unref();
|
|
130
|
-
if (child.pid === undefined) {
|
|
131
|
-
console.error('[reagent] Failed to obtain daemon PID after spawn — daemon may not be running');
|
|
132
|
-
process.exit(1);
|
|
133
|
-
}
|
|
134
|
-
const pidPath = getPidFilePath();
|
|
135
|
-
fs.writeFileSync(pidPath, String(child.pid), 'utf8');
|
|
136
|
-
console.log(`\nreagent daemon started`);
|
|
137
|
-
console.log(` PID: ${child.pid}`);
|
|
138
|
-
console.log(` Address: http://${bind}:${port}`);
|
|
139
|
-
console.log(` Log: ${logFile}`);
|
|
140
|
-
console.log(` PID file: ${pidPath}`);
|
|
141
|
-
console.log(`\n Run \`reagent daemon status\` to confirm it is healthy.\n`);
|
|
142
|
-
}
|
|
143
|
-
//# sourceMappingURL=start.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../../../src/cli/commands/daemon/start.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/daemon/status.ts"],"names":[],"mappings":"AAmBA,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmEpE"}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import os from 'node:os';
|
|
4
|
-
import { loadDaemonConfig } from '../../../config/daemon-loader.js';
|
|
5
|
-
/** Path to the PID file written by `reagent daemon start`. */
|
|
6
|
-
function getPidFilePath() {
|
|
7
|
-
return path.join(os.homedir(), '.reagent', 'daemon.pid');
|
|
8
|
-
}
|
|
9
|
-
async function fetchJson(url) {
|
|
10
|
-
const res = await fetch(url);
|
|
11
|
-
if (!res.ok) {
|
|
12
|
-
throw new Error(`HTTP ${res.status} from ${url}`);
|
|
13
|
-
}
|
|
14
|
-
return res.json();
|
|
15
|
-
}
|
|
16
|
-
export async function runDaemonStatus(_args) {
|
|
17
|
-
const pidPath = getPidFilePath();
|
|
18
|
-
// Check PID file
|
|
19
|
-
let pid = null;
|
|
20
|
-
if (fs.existsSync(pidPath)) {
|
|
21
|
-
const raw = fs.readFileSync(pidPath, 'utf8').trim();
|
|
22
|
-
const parsed = parseInt(raw, 10);
|
|
23
|
-
if (!isNaN(parsed)) {
|
|
24
|
-
// Verify the process is alive
|
|
25
|
-
try {
|
|
26
|
-
process.kill(parsed, 0);
|
|
27
|
-
pid = parsed;
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
// Stale PID
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
const config = loadDaemonConfig();
|
|
35
|
-
const baseUrl = `http://${config.bind}:${config.port}`;
|
|
36
|
-
console.log(`\nreagent daemon status`);
|
|
37
|
-
console.log(` Address: ${baseUrl}`);
|
|
38
|
-
if (pid !== null) {
|
|
39
|
-
console.log(` PID: ${pid} (running)`);
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
console.log(` PID: not running`);
|
|
43
|
-
}
|
|
44
|
-
// Try to hit /health
|
|
45
|
-
let health = null;
|
|
46
|
-
try {
|
|
47
|
-
health = await fetchJson(`${baseUrl}/health`);
|
|
48
|
-
console.log(` Status: ${health.status}`);
|
|
49
|
-
console.log(` Version: ${health.version}`);
|
|
50
|
-
console.log(` Uptime: ${formatUptime(health.uptime_seconds)}`);
|
|
51
|
-
console.log(` Sessions: ${health.sessions}`);
|
|
52
|
-
}
|
|
53
|
-
catch {
|
|
54
|
-
console.log(` Status: unreachable (daemon may not be running or still starting)`);
|
|
55
|
-
console.log('');
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
// Fetch sessions if any are active
|
|
59
|
-
if (health.sessions > 0) {
|
|
60
|
-
try {
|
|
61
|
-
const sessionsResp = await fetchJson(`${baseUrl}/sessions`);
|
|
62
|
-
console.log(`\n Active sessions:`);
|
|
63
|
-
for (const session of sessionsResp.sessions) {
|
|
64
|
-
const elapsed = session.last_activity_elapsed_secs;
|
|
65
|
-
const elapsedStr = elapsed < 60
|
|
66
|
-
? `${elapsed}s ago`
|
|
67
|
-
: elapsed < 3600
|
|
68
|
-
? `${Math.floor(elapsed / 60)}m ago`
|
|
69
|
-
: `${Math.floor(elapsed / 3600)}h ago`;
|
|
70
|
-
console.log(` [${session.session_id.slice(0, 8)}] ${session.project_root}`);
|
|
71
|
-
console.log(` Last activity: ${elapsedStr}`);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
catch {
|
|
75
|
-
// Non-fatal — health already printed session count
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
console.log('');
|
|
79
|
-
}
|
|
80
|
-
function formatUptime(seconds) {
|
|
81
|
-
const h = Math.floor(seconds / 3600);
|
|
82
|
-
const m = Math.floor((seconds % 3600) / 60);
|
|
83
|
-
const s = seconds % 60;
|
|
84
|
-
if (h > 0)
|
|
85
|
-
return `${h}h ${m}m ${s}s`;
|
|
86
|
-
if (m > 0)
|
|
87
|
-
return `${m}m ${s}s`;
|
|
88
|
-
return `${s}s`;
|
|
89
|
-
}
|
|
90
|
-
//# sourceMappingURL=status.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../../src/cli/commands/daemon/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAGpE,8DAA8D;AAC9D,SAAS,cAAc;IACrB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;AAC3D,CAAC;AAED,KAAK,UAAU,SAAS,CAAI,GAAW;IACrC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,EAAgB,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAe;IACnD,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IAEjC,iBAAiB;IACjB,IAAI,GAAG,GAAkB,IAAI,CAAC;IAC9B,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YACnB,8BAA8B;YAC9B,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBACxB,GAAG,GAAG,MAAM,CAAC;YACf,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY;YACd,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,MAAM,OAAO,GAAG,UAAU,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;IAEvD,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC;IAErC,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,YAAY,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACxC,CAAC;IAED,qBAAqB;IACrB,IAAI,MAAM,GAAgC,IAAI,CAAC;IAC/C,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,SAAS,CAAuB,GAAG,OAAO,SAAS,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,cAAc,YAAY,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,sEAAsE,CAAC,CAAC;QACpF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IAED,mCAAmC;IACnC,IAAI,MAAM,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,MAAM,SAAS,CAAyB,GAAG,OAAO,WAAW,CAAC,CAAC;YACpF,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;YACpC,KAAK,MAAM,OAAO,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC;gBAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,0BAA0B,CAAC;gBACnD,MAAM,UAAU,GACd,OAAO,GAAG,EAAE;oBACV,CAAC,CAAC,GAAG,OAAO,OAAO;oBACnB,CAAC,CAAC,OAAO,GAAG,IAAI;wBACd,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,OAAO;wBACpC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;gBAC7C,OAAO,CAAC,GAAG,CAAC,QAAQ,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;gBAC/E,OAAO,CAAC,GAAG,CAAC,wBAAwB,UAAU,EAAE,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,mDAAmD;QACrD,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,YAAY,CAAC,OAAe;IACnC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACrC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC5C,MAAM,CAAC,GAAG,OAAO,GAAG,EAAE,CAAC;IACvB,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;IACtC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;IAChC,OAAO,GAAG,CAAC,GAAG,CAAC;AACjB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/daemon/stop.ts"],"names":[],"mappings":"AASA,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI,CA4ExE"}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import os from 'node:os';
|
|
4
|
-
/** Path to the PID file written by `reagent daemon start`. */
|
|
5
|
-
function getPidFilePath() {
|
|
6
|
-
return path.join(os.homedir(), '.reagent', 'daemon.pid');
|
|
7
|
-
}
|
|
8
|
-
export function runDaemonStop(_args, onDone) {
|
|
9
|
-
const pidPath = getPidFilePath();
|
|
10
|
-
if (!fs.existsSync(pidPath)) {
|
|
11
|
-
console.log(`\nreagent daemon is not running (no PID file at ${pidPath})\n`);
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
const raw = fs.readFileSync(pidPath, 'utf8').trim();
|
|
15
|
-
const pid = parseInt(raw, 10);
|
|
16
|
-
if (isNaN(pid)) {
|
|
17
|
-
console.error(`[reagent] PID file contains invalid value: ${JSON.stringify(raw)}`);
|
|
18
|
-
console.error(` Remove it manually: ${pidPath}`);
|
|
19
|
-
process.exit(1);
|
|
20
|
-
}
|
|
21
|
-
// Verify the process is alive before sending SIGTERM
|
|
22
|
-
let alive = true;
|
|
23
|
-
try {
|
|
24
|
-
process.kill(pid, 0);
|
|
25
|
-
}
|
|
26
|
-
catch {
|
|
27
|
-
alive = false;
|
|
28
|
-
}
|
|
29
|
-
if (!alive) {
|
|
30
|
-
console.log(`\nreagent daemon (PID ${pid}) is not running — removing stale PID file.`);
|
|
31
|
-
fs.unlinkSync(pidPath);
|
|
32
|
-
onDone?.();
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
console.log(`\nSending SIGTERM to reagent daemon (PID ${pid})...`);
|
|
36
|
-
try {
|
|
37
|
-
process.kill(pid, 'SIGTERM');
|
|
38
|
-
}
|
|
39
|
-
catch (err) {
|
|
40
|
-
console.error(`[reagent] Failed to send SIGTERM to PID ${pid}: ${err instanceof Error ? err.message : err}`);
|
|
41
|
-
process.exit(1);
|
|
42
|
-
}
|
|
43
|
-
// Poll for up to 10 seconds to confirm the process exited
|
|
44
|
-
const deadline = Date.now() + 10_000;
|
|
45
|
-
const pollIntervalMs = 250;
|
|
46
|
-
const poll = () => {
|
|
47
|
-
let still_alive = true;
|
|
48
|
-
try {
|
|
49
|
-
process.kill(pid, 0);
|
|
50
|
-
}
|
|
51
|
-
catch {
|
|
52
|
-
still_alive = false;
|
|
53
|
-
}
|
|
54
|
-
if (!still_alive) {
|
|
55
|
-
// Remove stale PID file — daemon removes it on clean exit, but handle
|
|
56
|
-
// the case where it didn't
|
|
57
|
-
if (fs.existsSync(pidPath)) {
|
|
58
|
-
fs.unlinkSync(pidPath);
|
|
59
|
-
}
|
|
60
|
-
console.log(` Daemon stopped.\n`);
|
|
61
|
-
onDone?.();
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
if (Date.now() >= deadline) {
|
|
65
|
-
console.error(`[reagent] Daemon (PID ${pid}) did not exit within 10 seconds.`);
|
|
66
|
-
console.error(` Send SIGKILL manually: kill -9 ${pid}`);
|
|
67
|
-
process.exit(1);
|
|
68
|
-
}
|
|
69
|
-
setTimeout(poll, pollIntervalMs);
|
|
70
|
-
};
|
|
71
|
-
setTimeout(poll, pollIntervalMs);
|
|
72
|
-
}
|
|
73
|
-
//# sourceMappingURL=stop.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stop.js","sourceRoot":"","sources":["../../../../src/cli/commands/daemon/stop.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { DaemonConfig } from '../types/daemon.js';
|
|
2
|
-
/**
|
|
3
|
-
* Async daemon config loader.
|
|
4
|
-
*
|
|
5
|
-
* Reads ~/.reagent/daemon.yaml and returns a validated DaemonConfig.
|
|
6
|
-
* Falls back to defaults if the file is absent — the daemon does not require
|
|
7
|
-
* the config file to exist.
|
|
8
|
-
*/
|
|
9
|
-
export declare function loadDaemonConfigAsync(): Promise<DaemonConfig>;
|
|
10
|
-
/**
|
|
11
|
-
* Synchronous daemon config loader — for CLI startup paths that must be sync.
|
|
12
|
-
*
|
|
13
|
-
* Falls back to defaults if ~/.reagent/daemon.yaml is absent.
|
|
14
|
-
*/
|
|
15
|
-
export declare function loadDaemonConfig(): DaemonConfig;
|
|
16
|
-
//# sourceMappingURL=daemon-loader.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"daemon-loader.d.ts","sourceRoot":"","sources":["../../src/config/daemon-loader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA+CvD;;;;;;GAMG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,YAAY,CAAC,CAYnE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,CAS/C"}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import fsPromises from 'node:fs/promises';
|
|
3
|
-
import os from 'node:os';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import { parse as parseYaml } from 'yaml';
|
|
6
|
-
import { z } from 'zod';
|
|
7
|
-
/** Path to the global daemon config: ~/.reagent/daemon.yaml */
|
|
8
|
-
function getDaemonConfigPath() {
|
|
9
|
-
return path.join(os.homedir(), '.reagent', 'daemon.yaml');
|
|
10
|
-
}
|
|
11
|
-
const DaemonAuthSchema = z.object({
|
|
12
|
-
api_keys: z.array(z.string()).optional(),
|
|
13
|
-
});
|
|
14
|
-
const DaemonConfigSchema = z.object({
|
|
15
|
-
port: z.number().int().min(1).max(65535).default(7777),
|
|
16
|
-
bind: z.string().default('127.0.0.1'),
|
|
17
|
-
session_ttl_minutes: z.number().int().min(1).default(30),
|
|
18
|
-
log_level: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
|
|
19
|
-
auth: DaemonAuthSchema.optional(),
|
|
20
|
-
});
|
|
21
|
-
/** Default config used when ~/.reagent/daemon.yaml is absent. */
|
|
22
|
-
const DAEMON_DEFAULTS = {
|
|
23
|
-
port: 7777,
|
|
24
|
-
bind: '127.0.0.1',
|
|
25
|
-
session_ttl_minutes: 30,
|
|
26
|
-
log_level: 'info',
|
|
27
|
-
};
|
|
28
|
-
function parseRawDaemonConfig(raw, configPath) {
|
|
29
|
-
let parsed;
|
|
30
|
-
try {
|
|
31
|
-
parsed = parseYaml(raw);
|
|
32
|
-
}
|
|
33
|
-
catch (yamlErr) {
|
|
34
|
-
throw new Error(`Failed to parse daemon YAML at ${configPath}: ${yamlErr instanceof Error ? yamlErr.message : yamlErr}`);
|
|
35
|
-
}
|
|
36
|
-
try {
|
|
37
|
-
// parseYaml returns null for an empty file — treat as empty object so defaults apply
|
|
38
|
-
return DaemonConfigSchema.parse(parsed ?? {});
|
|
39
|
-
}
|
|
40
|
-
catch (zodErr) {
|
|
41
|
-
throw new Error(`Invalid daemon config schema at ${configPath}: ${zodErr instanceof Error ? zodErr.message : zodErr}`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Async daemon config loader.
|
|
46
|
-
*
|
|
47
|
-
* Reads ~/.reagent/daemon.yaml and returns a validated DaemonConfig.
|
|
48
|
-
* Falls back to defaults if the file is absent — the daemon does not require
|
|
49
|
-
* the config file to exist.
|
|
50
|
-
*/
|
|
51
|
-
export async function loadDaemonConfigAsync() {
|
|
52
|
-
const configPath = getDaemonConfigPath();
|
|
53
|
-
let raw;
|
|
54
|
-
try {
|
|
55
|
-
raw = await fsPromises.readFile(configPath, 'utf8');
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
// File absent — return defaults
|
|
59
|
-
return { ...DAEMON_DEFAULTS };
|
|
60
|
-
}
|
|
61
|
-
return parseRawDaemonConfig(raw, configPath);
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Synchronous daemon config loader — for CLI startup paths that must be sync.
|
|
65
|
-
*
|
|
66
|
-
* Falls back to defaults if ~/.reagent/daemon.yaml is absent.
|
|
67
|
-
*/
|
|
68
|
-
export function loadDaemonConfig() {
|
|
69
|
-
const configPath = getDaemonConfigPath();
|
|
70
|
-
if (!fs.existsSync(configPath)) {
|
|
71
|
-
return { ...DAEMON_DEFAULTS };
|
|
72
|
-
}
|
|
73
|
-
const raw = fs.readFileSync(configPath, 'utf8');
|
|
74
|
-
return parseRawDaemonConfig(raw, configPath);
|
|
75
|
-
}
|
|
76
|
-
//# sourceMappingURL=daemon-loader.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"daemon-loader.js","sourceRoot":"","sources":["../../src/config/daemon-loader.ts"],"names":[],"mappings":"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"}
|
package/dist/types/daemon.d.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DaemonConfig — global daemon settings loaded from ~/.reagent/daemon.yaml.
|
|
3
|
-
*
|
|
4
|
-
* This file is the source of truth for daemon configuration shape on the
|
|
5
|
-
* TypeScript side. The Rust daemon reads the same YAML file; keep field names
|
|
6
|
-
* in sync with daemon/src/config.rs.
|
|
7
|
-
*/
|
|
8
|
-
export interface DaemonConfig {
|
|
9
|
-
/** TCP port the daemon listens on. Default: 7777 */
|
|
10
|
-
port: number;
|
|
11
|
-
/** Bind address. Default: '127.0.0.1' */
|
|
12
|
-
bind: string;
|
|
13
|
-
/** Idle session TTL in minutes. Default: 30 */
|
|
14
|
-
session_ttl_minutes: number;
|
|
15
|
-
/** Log verbosity passed to the Rust daemon via RUST_LOG. Default: 'info' */
|
|
16
|
-
log_level: 'debug' | 'info' | 'warn' | 'error';
|
|
17
|
-
/** Optional API key authentication for the daemon HTTP surface. */
|
|
18
|
-
auth?: DaemonAuth;
|
|
19
|
-
}
|
|
20
|
-
export interface DaemonAuth {
|
|
21
|
-
/** List of accepted bearer tokens. If empty or absent, auth is disabled. */
|
|
22
|
-
api_keys?: readonly string[];
|
|
23
|
-
}
|
|
24
|
-
/** Represents a single active session as returned by GET /sessions.
|
|
25
|
-
*
|
|
26
|
-
* Field names match the Rust SessionSummary struct in daemon/src/session.rs.
|
|
27
|
-
*/
|
|
28
|
-
export interface DaemonSession {
|
|
29
|
-
session_id: string;
|
|
30
|
-
project_root: string;
|
|
31
|
-
/** Seconds elapsed since last MCP activity on this session. */
|
|
32
|
-
last_activity_elapsed_secs: number;
|
|
33
|
-
}
|
|
34
|
-
/** Shape of GET /health response body. */
|
|
35
|
-
export interface DaemonHealthResponse {
|
|
36
|
-
status: 'ok';
|
|
37
|
-
version: string;
|
|
38
|
-
sessions: number;
|
|
39
|
-
uptime_seconds: number;
|
|
40
|
-
}
|
|
41
|
-
/** Shape of GET /sessions response body. */
|
|
42
|
-
export interface DaemonSessionsResponse {
|
|
43
|
-
sessions: readonly DaemonSession[];
|
|
44
|
-
}
|
|
45
|
-
//# sourceMappingURL=daemon.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/types/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,mBAAmB,EAAE,MAAM,CAAC;IAC5B,4EAA4E;IAC5E,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC/C,mEAAmE;IACnE,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,0BAA0B,EAAE,MAAM,CAAC;CACpC;AAED,0CAA0C;AAC1C,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,IAAI,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,4CAA4C;AAC5C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;CACpC"}
|
package/dist/types/daemon.js
DELETED
package/dist/types/daemon.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/types/daemon.ts"],"names":[],"mappings":""}
|