@yefengr/remote-pi 0.7.16 → 0.9.0
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 +44 -95
- package/dist/actions/handlers.js +1 -1
- package/dist/actions/handlers.js.map +1 -1
- package/dist/actions/registry.d.ts +1 -1
- package/dist/actions/registry.js +1 -1
- package/dist/{daemon/commands.d.ts → commands.d.ts} +3 -4
- package/dist/{daemon/commands.js → commands.js} +8 -151
- package/dist/commands.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +20 -38
- package/dist/index.js.map +1 -1
- package/dist/pairing/storage.js +4 -4
- package/dist/pairing/storage.js.map +1 -1
- package/dist/protocol/v2/schemas.d.ts +64 -7
- package/dist/protocol/v2/schemas.js +6 -3
- package/dist/protocol/v2/schemas.js.map +1 -1
- package/dist/session/local_config.d.ts +0 -5
- package/dist/session/local_config.js +6 -29
- package/dist/session/local_config.js.map +1 -1
- package/dist/timeline/history.d.ts +3 -6
- package/dist/timeline/history.js +113 -249
- package/dist/timeline/history.js.map +1 -1
- package/dist/timeline/runtime.js +29 -37
- package/dist/timeline/runtime.js.map +1 -1
- package/dist/timeline/sequence.d.ts +7 -0
- package/dist/timeline/sequence.js +16 -0
- package/dist/timeline/sequence.js.map +1 -0
- package/dist/timeline/v2_service.js +3 -1
- package/dist/timeline/v2_service.js.map +1 -1
- package/dist/transport/relay_client.js.map +1 -1
- package/package.json +1 -8
- package/dist/bin/supervisord.d.ts +0 -2
- package/dist/bin/supervisord.js +0 -78
- package/dist/bin/supervisord.js.map +0 -1
- package/dist/daemon/cli-links.d.ts +0 -30
- package/dist/daemon/cli-links.js +0 -134
- package/dist/daemon/cli-links.js.map +0 -1
- package/dist/daemon/client.d.ts +0 -20
- package/dist/daemon/client.js +0 -131
- package/dist/daemon/client.js.map +0 -1
- package/dist/daemon/commands.js.map +0 -1
- package/dist/daemon/control_protocol.d.ts +0 -198
- package/dist/daemon/control_protocol.js +0 -40
- package/dist/daemon/control_protocol.js.map +0 -1
- package/dist/daemon/cron_log.d.ts +0 -24
- package/dist/daemon/cron_log.js +0 -57
- package/dist/daemon/cron_log.js.map +0 -1
- package/dist/daemon/cron_registry.d.ts +0 -43
- package/dist/daemon/cron_registry.js +0 -149
- package/dist/daemon/cron_registry.js.map +0 -1
- package/dist/daemon/install-runtime.d.ts +0 -10
- package/dist/daemon/install-runtime.js +0 -81
- package/dist/daemon/install-runtime.js.map +0 -1
- package/dist/daemon/install.d.ts +0 -110
- package/dist/daemon/install.js +0 -263
- package/dist/daemon/install.js.map +0 -1
- package/dist/daemon/registry.d.ts +0 -51
- package/dist/daemon/registry.js +0 -207
- package/dist/daemon/registry.js.map +0 -1
- package/dist/daemon/rpc_child.d.ts +0 -135
- package/dist/daemon/rpc_child.js +0 -472
- package/dist/daemon/rpc_child.js.map +0 -1
- package/dist/daemon/status.d.ts +0 -45
- package/dist/daemon/status.js +0 -87
- package/dist/daemon/status.js.map +0 -1
- package/dist/daemon/supervisor-ipc.d.ts +0 -2
- package/dist/daemon/supervisor-ipc.js +0 -20
- package/dist/daemon/supervisor-ipc.js.map +0 -1
- package/dist/daemon/supervisor.d.ts +0 -70
- package/dist/daemon/supervisor.js +0 -637
- package/dist/daemon/supervisor.js.map +0 -1
- package/dist/session/ipc.d.ts +0 -6
- package/dist/session/ipc.js +0 -15
- package/dist/session/ipc.js.map +0 -1
- package/docs/daemon.md +0 -175
- package/service-templates/launchd.plist.template +0 -35
- package/service-templates/systemd.service.template +0 -19
- package/service-templates/task-launcher.vbs.template +0 -10
- package/service-templates/task-scheduler.xml.template +0 -38
package/dist/daemon/install.js
DELETED
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { homedir, platform, userInfo } from "node:os";
|
|
3
|
-
import { dirname, join, resolve } from "node:path";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { execCommand as _exec, execElevatedWindows as _execElevatedWindows, tryExecCommand as _tryExec } from "./install-runtime.js";
|
|
6
|
-
export { buildElevatedCmd } from "./install-runtime.js";
|
|
7
|
-
export { buildCmdShim, isOnPath, linkCliBinaries, unlinkCliBinaries, userLocalBinDir, } from "./cli-links.js";
|
|
8
|
-
export function detectPlatform() {
|
|
9
|
-
switch (platform()) {
|
|
10
|
-
case "darwin": return "macos";
|
|
11
|
-
case "linux": return "linux";
|
|
12
|
-
case "win32": return "windows";
|
|
13
|
-
default: return "unsupported";
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
// ── Path resolution ────────────────────────────────────────────────────────
|
|
17
|
-
/**
|
|
18
|
-
* Absolute path to the supervisor's compiled entry. We resolve from
|
|
19
|
-
* `import.meta.url` (this file's location) since wherever the daemon
|
|
20
|
-
* module lives, `bin/supervisord.js` is a sibling of `daemon/` under
|
|
21
|
-
* `dist/`.
|
|
22
|
-
*
|
|
23
|
-
* After build: `dist/daemon/install.js` → `dist/bin/supervisord.js`.
|
|
24
|
-
* In dev (`tsx`): same path resolution still lands inside `src/`, which
|
|
25
|
-
* isn't directly runnable by `node` — dev install isn't expected.
|
|
26
|
-
*/
|
|
27
|
-
export function findSupervisorScript() {
|
|
28
|
-
const here = fileURLToPath(import.meta.url); // dist/daemon/install.js
|
|
29
|
-
const daemonDir = dirname(here); // dist/daemon
|
|
30
|
-
const distRoot = dirname(daemonDir); // dist
|
|
31
|
-
return resolve(distRoot, "bin/supervisord.js");
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Absolute path to the extension's CLI entry (`dist/index.js`). This is
|
|
35
|
-
* the file we symlink to `~/.local/bin/remote-pi` so the user can run
|
|
36
|
-
* `remote-pi <subcommand>` from any shell after installing the extension
|
|
37
|
-
* through Pi (`pi install npm:@yefengr/remote-pi`).
|
|
38
|
-
*
|
|
39
|
-
* Same resolution strategy as `findSupervisorScript`: from
|
|
40
|
-
* `dist/daemon/install.js` → `dist/index.js`.
|
|
41
|
-
*/
|
|
42
|
-
export function findRemotePiScript() {
|
|
43
|
-
const here = fileURLToPath(import.meta.url); // dist/daemon/install.js
|
|
44
|
-
const daemonDir = dirname(here); // dist/daemon
|
|
45
|
-
const distRoot = dirname(daemonDir); // dist
|
|
46
|
-
return resolve(distRoot, "index.js");
|
|
47
|
-
}
|
|
48
|
-
export function findNodeBinary() {
|
|
49
|
-
// `process.execPath` is always absolute and points at the current Node
|
|
50
|
-
// binary. Embedding it in the service unit means the user gets the
|
|
51
|
-
// exact same Node version they invoked `remote-pi install` with — no
|
|
52
|
-
// PATH ambiguity at boot time.
|
|
53
|
-
return process.execPath;
|
|
54
|
-
}
|
|
55
|
-
export function findTemplate(name) {
|
|
56
|
-
// Templates ship next to the compiled `dist/` (via `files` in package.json).
|
|
57
|
-
// From `dist/daemon/install.js` go up two levels and into
|
|
58
|
-
// `service-templates/`. In the published npm tarball the layout is the
|
|
59
|
-
// same — `service-templates/` is sibling to `dist/`.
|
|
60
|
-
const here = fileURLToPath(import.meta.url); // dist/daemon/install.js
|
|
61
|
-
const pkgRoot = resolve(dirname(dirname(dirname(here)))); // package root
|
|
62
|
-
const file = name === "systemd" ? "systemd.service.template" :
|
|
63
|
-
name === "launchd" ? "launchd.plist.template" :
|
|
64
|
-
name === "vbs-launcher" ? "task-launcher.vbs.template" :
|
|
65
|
-
"task-scheduler.xml.template";
|
|
66
|
-
return resolve(pkgRoot, "service-templates", file);
|
|
67
|
-
}
|
|
68
|
-
// ── Service paths ──────────────────────────────────────────────────────────
|
|
69
|
-
export function systemdUnitPath() {
|
|
70
|
-
return join(homedir(), ".config", "systemd", "user", "remote-pi-supervisord.service");
|
|
71
|
-
}
|
|
72
|
-
export function launchdPlistPath() {
|
|
73
|
-
return join(homedir(), "Library", "LaunchAgents", "dev.remotepi.supervisord.plist");
|
|
74
|
-
}
|
|
75
|
-
export const LAUNCHD_LABEL = "dev.remotepi.supervisord";
|
|
76
|
-
/** systemd --user unit name (with `.service`) for the supervisor. */
|
|
77
|
-
export const SYSTEMD_UNIT = "remote-pi-supervisord.service";
|
|
78
|
-
/** Windows Task Scheduler task name (plan/40). */
|
|
79
|
-
export const WINDOWS_TASK_NAME = "RemotePiSupervisor";
|
|
80
|
-
/** Path of the rendered Task Scheduler XML (input to `schtasks /Create /XML`). */
|
|
81
|
-
export function taskXmlPath() {
|
|
82
|
-
return join(homedir(), ".pi", "remote", "RemotePiSupervisor.xml");
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Path of the rendered VBScript launcher the Task Scheduler action invokes
|
|
86
|
-
* via `wscript.exe` (plan/40, Windows). Launching node through this hidden
|
|
87
|
-
* wrapper is what keeps the supervisor from flashing a console window.
|
|
88
|
-
*/
|
|
89
|
-
export function vbsLauncherPath() {
|
|
90
|
-
return join(homedir(), ".pi", "remote", "RemotePiSupervisorLauncher.vbs");
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Combined stdout/stderr log for the Windows supervisor. The Task Scheduler
|
|
94
|
-
* launches it hidden via wscript, so without this redirect its output (and the
|
|
95
|
-
* forwarded daemon-child stderr) would vanish — mirrors launchd/systemd, which
|
|
96
|
-
* already log to `~/.pi/remote/supervisord.log`.
|
|
97
|
-
*/
|
|
98
|
-
export function supervisordLogPath() {
|
|
99
|
-
return join(homedir(), ".pi", "remote", "supervisord.log");
|
|
100
|
-
}
|
|
101
|
-
export function defaultRenderVars() {
|
|
102
|
-
return {
|
|
103
|
-
node: findNodeBinary(),
|
|
104
|
-
supervisor: findSupervisorScript(),
|
|
105
|
-
home: homedir(),
|
|
106
|
-
user: userInfo().username,
|
|
107
|
-
path: process.env["PATH"] ?? "/usr/local/bin:/usr/bin:/bin",
|
|
108
|
-
vbs: vbsLauncherPath(),
|
|
109
|
-
logPath: supervisordLogPath(),
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
/** Replace `{NODE}` / `{SUPERVISOR}` / `{USER}` / `{HOME}` / `{PATH}` / `{VBS}` / `{LOG}`. */
|
|
113
|
-
export function renderTemplate(template, vars) {
|
|
114
|
-
return template
|
|
115
|
-
.replace(/\{NODE\}/g, vars.node)
|
|
116
|
-
.replace(/\{SUPERVISOR\}/g, vars.supervisor)
|
|
117
|
-
.replace(/\{USER\}/g, vars.user)
|
|
118
|
-
.replace(/\{HOME\}/g, vars.home)
|
|
119
|
-
.replace(/\{PATH\}/g, vars.path)
|
|
120
|
-
.replace(/\{VBS\}/g, vars.vbs)
|
|
121
|
-
.replace(/\{LOG\}/g, vars.logPath);
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Writes the unit/plist, runs the platform's activation command. Throws
|
|
125
|
-
* on unsupported OS or when the supervisor script isn't found.
|
|
126
|
-
*
|
|
127
|
-
* Idempotent: re-running re-writes the unit (paths could have changed)
|
|
128
|
-
* and re-activates via the platform tool's idempotent flag.
|
|
129
|
-
*/
|
|
130
|
-
export function installService(vars = defaultRenderVars()) {
|
|
131
|
-
const plat = detectPlatform();
|
|
132
|
-
const log = [];
|
|
133
|
-
if (plat === "unsupported") {
|
|
134
|
-
throw new Error(`unsupported platform: ${platform()}. Only macOS, Linux, and Windows.`);
|
|
135
|
-
}
|
|
136
|
-
// Sanity: supervisor script must exist on disk.
|
|
137
|
-
if (!existsSync(vars.supervisor)) {
|
|
138
|
-
throw new Error(`supervisor script not found at ${vars.supervisor}. ` +
|
|
139
|
-
"Run `pnpm build` (dev) or `npm install -g @yefengr/remote-pi` (prod) first.");
|
|
140
|
-
}
|
|
141
|
-
const templateName = plat === "macos" ? "launchd" : plat === "linux" ? "systemd" : "taskscheduler";
|
|
142
|
-
const templatePath = findTemplate(templateName);
|
|
143
|
-
if (!existsSync(templatePath)) {
|
|
144
|
-
throw new Error(`service template missing: ${templatePath}`);
|
|
145
|
-
}
|
|
146
|
-
const tpl = readFileSync(templatePath, "utf8");
|
|
147
|
-
const rendered = renderTemplate(tpl, vars);
|
|
148
|
-
const unitPath = plat === "macos" ? launchdPlistPath() : plat === "linux" ? systemdUnitPath() : taskXmlPath();
|
|
149
|
-
mkdirSync(dirname(unitPath), { recursive: true });
|
|
150
|
-
if (plat === "windows") {
|
|
151
|
-
// `schtasks /Create /XML` requires UTF-16LE + BOM. A UTF-8 file fails with
|
|
152
|
-
// "(1,40)::ERROR: unable to switch the encoding" — the bytes must match the
|
|
153
|
-
// template's `encoding="UTF-16"` declaration. (plan/40 risk #5.)
|
|
154
|
-
const bom = Buffer.from([0xff, 0xfe]); // UTF-16LE byte-order mark
|
|
155
|
-
writeFileSync(unitPath, Buffer.concat([bom, Buffer.from(rendered, "utf16le")]));
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
writeFileSync(unitPath, rendered); // launchd/systemd → UTF-8
|
|
159
|
-
}
|
|
160
|
-
log.push(`wrote ${unitPath}`);
|
|
161
|
-
if (plat === "macos") {
|
|
162
|
-
// Unload first in case a stale entry exists from a prior install —
|
|
163
|
-
// `launchctl bootstrap` errors out otherwise. `bootout` is the modern
|
|
164
|
-
// API; `unload` is the legacy fallback. Either may fail silently.
|
|
165
|
-
const uid = userInfo().uid;
|
|
166
|
-
_tryExec("launchctl", ["bootout", `gui/${uid}`, unitPath], log);
|
|
167
|
-
_tryExec("launchctl", ["unload", unitPath], log);
|
|
168
|
-
_exec("launchctl", ["bootstrap", `gui/${uid}`, unitPath], log);
|
|
169
|
-
log.push(`activated via launchctl bootstrap gui/${uid}`);
|
|
170
|
-
}
|
|
171
|
-
else if (plat === "linux") {
|
|
172
|
-
_exec("systemctl", ["--user", "daemon-reload"], log);
|
|
173
|
-
_exec("systemctl", ["--user", "enable", "--now", "remote-pi-supervisord.service"], log);
|
|
174
|
-
log.push("activated via systemctl --user enable --now");
|
|
175
|
-
}
|
|
176
|
-
else {
|
|
177
|
-
// windows — Task Scheduler (plan/40). The action runs `wscript.exe
|
|
178
|
-
// <launcher.vbs>` (not node directly) so the supervisor starts hidden,
|
|
179
|
-
// with no console window. Render + write that launcher first.
|
|
180
|
-
const vbsTpl = findTemplate("vbs-launcher");
|
|
181
|
-
if (!existsSync(vbsTpl))
|
|
182
|
-
throw new Error(`vbs launcher template missing: ${vbsTpl}`);
|
|
183
|
-
const vbsPath = vars.vbs;
|
|
184
|
-
writeFileSync(vbsPath, renderTemplate(readFileSync(vbsTpl, "utf8"), vars));
|
|
185
|
-
log.push(`wrote ${vbsPath}`);
|
|
186
|
-
// Only `schtasks /Create` modifies the root task store → that single op
|
|
187
|
-
// needs admin (elevate it via UAC). `/End` (stop a prior instance) and
|
|
188
|
-
// `/Run` (start it) act on a task we already own and work un-elevated — the
|
|
189
|
-
// very ops `remote-pi restart-supervisor` runs without elevation. Keeping
|
|
190
|
-
// them un-elevated narrows the admin surface to the one operation that
|
|
191
|
-
// truly requires it.
|
|
192
|
-
_tryExec("schtasks", ["/End", "/TN", WINDOWS_TASK_NAME], log);
|
|
193
|
-
_execElevatedWindows([
|
|
194
|
-
`schtasks /Create /XML "${unitPath}" /TN ${WINDOWS_TASK_NAME} /F`,
|
|
195
|
-
], log);
|
|
196
|
-
_exec("schtasks", ["/Run", "/TN", WINDOWS_TASK_NAME], log);
|
|
197
|
-
log.push(`activated via schtasks /Create (elevated) + /Run (${WINDOWS_TASK_NAME})`);
|
|
198
|
-
}
|
|
199
|
-
return { platform: plat, unitPath, log };
|
|
200
|
-
}
|
|
201
|
-
export function uninstallService() {
|
|
202
|
-
const plat = detectPlatform();
|
|
203
|
-
const log = [];
|
|
204
|
-
if (plat === "unsupported") {
|
|
205
|
-
throw new Error(`unsupported platform: ${platform()}. Only macOS, Linux, and Windows.`);
|
|
206
|
-
}
|
|
207
|
-
const unitPath = plat === "macos" ? launchdPlistPath() : plat === "linux" ? systemdUnitPath() : taskXmlPath();
|
|
208
|
-
if (plat === "macos") {
|
|
209
|
-
const uid = userInfo().uid;
|
|
210
|
-
_tryExec("launchctl", ["bootout", `gui/${uid}`, unitPath], log);
|
|
211
|
-
_tryExec("launchctl", ["unload", unitPath], log);
|
|
212
|
-
log.push("deactivated via launchctl bootout");
|
|
213
|
-
}
|
|
214
|
-
else if (plat === "linux") {
|
|
215
|
-
_tryExec("systemctl", ["--user", "disable", "--now", "remote-pi-supervisord.service"], log);
|
|
216
|
-
log.push("deactivated via systemctl --user disable --now");
|
|
217
|
-
}
|
|
218
|
-
else {
|
|
219
|
-
// windows — Task Scheduler (plan/40): stop + delete the task. Only
|
|
220
|
-
// `/Delete` modifies the root task store → that's the op that needs admin.
|
|
221
|
-
// `/End` stops the running task and works un-elevated (own task), like
|
|
222
|
-
// restart-supervisor. `exit /b 0` keeps uninstall best-effort: a missing
|
|
223
|
-
// task (already removed) is success, not an error.
|
|
224
|
-
_tryExec("schtasks", ["/End", "/TN", WINDOWS_TASK_NAME], log);
|
|
225
|
-
_execElevatedWindows([
|
|
226
|
-
`schtasks /Delete /TN ${WINDOWS_TASK_NAME} /F`,
|
|
227
|
-
`exit /b 0`,
|
|
228
|
-
], log);
|
|
229
|
-
log.push(`deactivated via elevated schtasks /Delete (${WINDOWS_TASK_NAME})`);
|
|
230
|
-
}
|
|
231
|
-
let removed = false;
|
|
232
|
-
if (existsSync(unitPath)) {
|
|
233
|
-
try {
|
|
234
|
-
unlinkSync(unitPath);
|
|
235
|
-
removed = true;
|
|
236
|
-
log.push(`removed ${unitPath}`);
|
|
237
|
-
}
|
|
238
|
-
catch (e) {
|
|
239
|
-
log.push(`failed to remove ${unitPath}: ${String(e)}`);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
// Windows: also drop the hidden VBScript launcher we wrote alongside the XML.
|
|
243
|
-
if (plat === "windows") {
|
|
244
|
-
const vbsPath = vbsLauncherPath();
|
|
245
|
-
if (existsSync(vbsPath)) {
|
|
246
|
-
try {
|
|
247
|
-
unlinkSync(vbsPath);
|
|
248
|
-
log.push(`removed ${vbsPath}`);
|
|
249
|
-
}
|
|
250
|
-
catch (e) {
|
|
251
|
-
log.push(`failed to remove ${vbsPath}: ${String(e)}`);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
if (plat === "linux") {
|
|
256
|
-
_tryExec("systemctl", ["--user", "daemon-reload"], log);
|
|
257
|
-
}
|
|
258
|
-
// Hint about the label for users that want to verify manually.
|
|
259
|
-
if (plat === "macos")
|
|
260
|
-
log.push(`(label: ${LAUNCHD_LABEL})`);
|
|
261
|
-
return { platform: plat, unitPath, removed, log };
|
|
262
|
-
}
|
|
263
|
-
//# sourceMappingURL=install.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/daemon/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/** Persisted desired lifecycle for a daemon registration. */
|
|
2
|
-
export type DesiredState = "running" | "stopped";
|
|
3
|
-
/** Versioned daemon registry v2. Do not silently coerce an older shape. */
|
|
4
|
-
export interface DaemonEntry {
|
|
5
|
-
/** Stable opaque endpoint identity. Never derived from cwd. */
|
|
6
|
-
id: string;
|
|
7
|
-
/** Absolute filesystem realpath captured at registration time. */
|
|
8
|
-
cwd: string;
|
|
9
|
-
name: string;
|
|
10
|
-
desired_state: DesiredState;
|
|
11
|
-
/** Epoch milliseconds. */
|
|
12
|
-
created_at: number;
|
|
13
|
-
}
|
|
14
|
-
export interface DaemonRegistry {
|
|
15
|
-
version: 2;
|
|
16
|
-
daemons: DaemonEntry[];
|
|
17
|
-
}
|
|
18
|
-
export type RegistryErrorCode = "registry_schema_invalid" | "registry_schema_unsupported";
|
|
19
|
-
/**
|
|
20
|
-
* A malformed or old registry is an operator-visible error, not an empty
|
|
21
|
-
* registry. Treating it as empty could overwrite valid registrations on the
|
|
22
|
-
* next save, which is destructive.
|
|
23
|
-
*/
|
|
24
|
-
export declare class RegistrySchemaError extends Error {
|
|
25
|
-
readonly code: RegistryErrorCode;
|
|
26
|
-
constructor(code: RegistryErrorCode, message: string);
|
|
27
|
-
}
|
|
28
|
-
/** Canonicalizes a supplied cwd and rejects nonexistent paths. */
|
|
29
|
-
export declare function normalizeCwd(input: string): string;
|
|
30
|
-
/** Missing file is empty v2; every existing file must be valid v2. */
|
|
31
|
-
export declare function loadRegistry(): DaemonRegistry;
|
|
32
|
-
/** Validates before atomically replacing the on-disk registry. */
|
|
33
|
-
export declare function saveRegistry(registry: DaemonRegistry): void;
|
|
34
|
-
/** Explicit registration always starts in the desired running state. */
|
|
35
|
-
export declare function addDaemon(rawCwd: string, name?: string): DaemonEntry;
|
|
36
|
-
export declare function removeDaemon(id: string): {
|
|
37
|
-
removed: boolean;
|
|
38
|
-
cwd?: string;
|
|
39
|
-
};
|
|
40
|
-
/** Finds a registration by canonical cwd for external lifecycle integrations. */
|
|
41
|
-
export declare function findDaemonByCwd(rawCwd: string): DaemonEntry | undefined;
|
|
42
|
-
/** Persists intended lifecycle independently from process state. */
|
|
43
|
-
export declare function setDaemonDesiredState(id: string, desiredState: DesiredState): DaemonEntry | undefined;
|
|
44
|
-
/** Returns v2 entries in insertion order. */
|
|
45
|
-
export declare function listDaemons(): DaemonEntry[];
|
|
46
|
-
/**
|
|
47
|
-
* Backward compatible export name only. v2 deliberately has no in-place
|
|
48
|
-
* migration: an old registry must be explicitly replaced by its operator.
|
|
49
|
-
*/
|
|
50
|
-
export declare function migrateRegistryNames(): number;
|
|
51
|
-
export declare function registryPath(): string;
|
package/dist/daemon/registry.js
DELETED
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, realpathSync, renameSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { randomUUID } from "node:crypto";
|
|
3
|
-
import { homedir } from "node:os";
|
|
4
|
-
import { dirname, isAbsolute, join, resolve as resolvePath } from "node:path";
|
|
5
|
-
import { defaultAgentName } from "../session/local_config.js";
|
|
6
|
-
/**
|
|
7
|
-
* A malformed or old registry is an operator-visible error, not an empty
|
|
8
|
-
* registry. Treating it as empty could overwrite valid registrations on the
|
|
9
|
-
* next save, which is destructive.
|
|
10
|
-
*/
|
|
11
|
-
export class RegistrySchemaError extends Error {
|
|
12
|
-
code;
|
|
13
|
-
constructor(code, message) {
|
|
14
|
-
super(message);
|
|
15
|
-
this.code = code;
|
|
16
|
-
this.name = "RegistrySchemaError";
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
function registryPathInternal() {
|
|
20
|
-
const root = process.env["REMOTE_PI_HOME"] || homedir();
|
|
21
|
-
return join(root, ".pi", "remote", "daemons.json");
|
|
22
|
-
}
|
|
23
|
-
function emptyRegistry() {
|
|
24
|
-
return { version: 2, daemons: [] };
|
|
25
|
-
}
|
|
26
|
-
/** Canonicalizes a supplied cwd and rejects nonexistent paths. */
|
|
27
|
-
export function normalizeCwd(input) {
|
|
28
|
-
if (!input || !input.trim())
|
|
29
|
-
throw new Error("cwd is required");
|
|
30
|
-
let path = input.trim();
|
|
31
|
-
if (path === "~")
|
|
32
|
-
path = homedir();
|
|
33
|
-
else if (path.startsWith("~/"))
|
|
34
|
-
path = join(homedir(), path.slice(2));
|
|
35
|
-
if (!isAbsolute(path))
|
|
36
|
-
path = resolvePath(process.cwd(), path);
|
|
37
|
-
return realpathSync(path);
|
|
38
|
-
}
|
|
39
|
-
function registryError(message, code = "registry_schema_invalid") {
|
|
40
|
-
throw new RegistrySchemaError(code, message);
|
|
41
|
-
}
|
|
42
|
-
function isOpaqueId(value) {
|
|
43
|
-
// UUID is generated by this registry. Accept UUID variants to keep the
|
|
44
|
-
// persisted identifier opaque without coupling validation to a display form.
|
|
45
|
-
return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
|
|
46
|
-
}
|
|
47
|
-
function parseEntry(value, index) {
|
|
48
|
-
if (!value || typeof value !== "object")
|
|
49
|
-
registryError(`registry daemon[${index}] must be an object`);
|
|
50
|
-
const entry = value;
|
|
51
|
-
if (!isOpaqueId(entry["id"]))
|
|
52
|
-
registryError(`registry daemon[${index}].id must be an opaque UUID`);
|
|
53
|
-
if (typeof entry["cwd"] !== "string" || !isAbsolute(entry["cwd"]) || entry["cwd"].length === 0) {
|
|
54
|
-
registryError(`registry daemon[${index}].cwd must be an absolute path`);
|
|
55
|
-
}
|
|
56
|
-
// A vanished cwd stays loadable long enough for supervisor reconcile to
|
|
57
|
-
// remove it. Existing paths must already be their canonical realpath.
|
|
58
|
-
if (existsSync(entry["cwd"]) && realpathSync(entry["cwd"]) !== entry["cwd"]) {
|
|
59
|
-
registryError(`registry daemon[${index}].cwd must be a filesystem realpath`);
|
|
60
|
-
}
|
|
61
|
-
if (typeof entry["name"] !== "string" || entry["name"].trim().length === 0) {
|
|
62
|
-
registryError(`registry daemon[${index}].name must be a non-empty string`);
|
|
63
|
-
}
|
|
64
|
-
if (entry["desired_state"] !== "running" && entry["desired_state"] !== "stopped") {
|
|
65
|
-
registryError(`registry daemon[${index}].desired_state must be running or stopped`);
|
|
66
|
-
}
|
|
67
|
-
if (typeof entry["created_at"] !== "number" || !Number.isFinite(entry["created_at"]) || entry["created_at"] < 0) {
|
|
68
|
-
registryError(`registry daemon[${index}].created_at must be an epoch timestamp`);
|
|
69
|
-
}
|
|
70
|
-
return {
|
|
71
|
-
id: entry["id"],
|
|
72
|
-
cwd: entry["cwd"],
|
|
73
|
-
name: entry["name"].trim(),
|
|
74
|
-
desired_state: entry["desired_state"],
|
|
75
|
-
created_at: entry["created_at"],
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
function validateRegistry(value) {
|
|
79
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
80
|
-
registryError("registry root must be an object");
|
|
81
|
-
}
|
|
82
|
-
const root = value;
|
|
83
|
-
if (root["version"] !== 2) {
|
|
84
|
-
const code = root["version"] === undefined || root["version"] === 1
|
|
85
|
-
? "registry_schema_unsupported"
|
|
86
|
-
: "registry_schema_invalid";
|
|
87
|
-
registryError(`unsupported daemon registry version ${String(root["version"])}; remove or replace ~/.pi/remote/daemons.json before registering daemons`, code);
|
|
88
|
-
}
|
|
89
|
-
if (!Array.isArray(root["daemons"]))
|
|
90
|
-
registryError("registry.daemons must be an array");
|
|
91
|
-
const daemons = root["daemons"].map((entry, index) => parseEntry(entry, index));
|
|
92
|
-
const ids = new Set();
|
|
93
|
-
const cwds = new Set();
|
|
94
|
-
for (const entry of daemons) {
|
|
95
|
-
if (ids.has(entry.id))
|
|
96
|
-
registryError(`registry contains duplicate id ${entry.id}`);
|
|
97
|
-
if (cwds.has(entry.cwd))
|
|
98
|
-
registryError(`registry contains duplicate cwd ${entry.cwd}`);
|
|
99
|
-
ids.add(entry.id);
|
|
100
|
-
cwds.add(entry.cwd);
|
|
101
|
-
}
|
|
102
|
-
return { version: 2, daemons };
|
|
103
|
-
}
|
|
104
|
-
/** Missing file is empty v2; every existing file must be valid v2. */
|
|
105
|
-
export function loadRegistry() {
|
|
106
|
-
const path = registryPathInternal();
|
|
107
|
-
if (!existsSync(path))
|
|
108
|
-
return emptyRegistry();
|
|
109
|
-
let raw;
|
|
110
|
-
try {
|
|
111
|
-
raw = readFileSync(path, "utf8");
|
|
112
|
-
}
|
|
113
|
-
catch (error) {
|
|
114
|
-
throw new RegistrySchemaError("registry_schema_invalid", `cannot read daemon registry: ${String(error)}`);
|
|
115
|
-
}
|
|
116
|
-
let parsed;
|
|
117
|
-
try {
|
|
118
|
-
parsed = JSON.parse(raw);
|
|
119
|
-
}
|
|
120
|
-
catch (error) {
|
|
121
|
-
throw new RegistrySchemaError("registry_schema_invalid", `invalid daemon registry JSON: ${String(error)}`);
|
|
122
|
-
}
|
|
123
|
-
return validateRegistry(parsed);
|
|
124
|
-
}
|
|
125
|
-
/** Validates before atomically replacing the on-disk registry. */
|
|
126
|
-
export function saveRegistry(registry) {
|
|
127
|
-
const valid = validateRegistry(registry);
|
|
128
|
-
const path = registryPathInternal();
|
|
129
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
130
|
-
const temp = `${path}.${process.pid}.${randomUUID()}.tmp`;
|
|
131
|
-
try {
|
|
132
|
-
writeFileSync(temp, JSON.stringify(valid, null, 2) + "\n", "utf8");
|
|
133
|
-
renameSync(temp, path);
|
|
134
|
-
}
|
|
135
|
-
catch (error) {
|
|
136
|
-
throw new Error(`failed to save daemon registry: ${String(error)}`);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
/** Explicit registration always starts in the desired running state. */
|
|
140
|
-
export function addDaemon(rawCwd, name) {
|
|
141
|
-
const cwd = normalizeCwd(rawCwd);
|
|
142
|
-
const registry = loadRegistry();
|
|
143
|
-
if (registry.daemons.some((entry) => entry.cwd === cwd)) {
|
|
144
|
-
throw new Error(`Daemon already registered for cwd: ${cwd}`);
|
|
145
|
-
}
|
|
146
|
-
const entry = {
|
|
147
|
-
id: randomUUID(),
|
|
148
|
-
cwd,
|
|
149
|
-
name: name?.trim() || defaultAgentName(cwd),
|
|
150
|
-
desired_state: "running",
|
|
151
|
-
created_at: Date.now(),
|
|
152
|
-
};
|
|
153
|
-
registry.daemons.push(entry);
|
|
154
|
-
saveRegistry(registry);
|
|
155
|
-
return entry;
|
|
156
|
-
}
|
|
157
|
-
export function removeDaemon(id) {
|
|
158
|
-
const registry = loadRegistry();
|
|
159
|
-
const index = registry.daemons.findIndex((entry) => entry.id === id);
|
|
160
|
-
if (index === -1)
|
|
161
|
-
return { removed: false };
|
|
162
|
-
const [removed] = registry.daemons.splice(index, 1);
|
|
163
|
-
saveRegistry(registry);
|
|
164
|
-
return { removed: true, cwd: removed.cwd };
|
|
165
|
-
}
|
|
166
|
-
/** Finds a registration by canonical cwd for external lifecycle integrations. */
|
|
167
|
-
export function findDaemonByCwd(rawCwd) {
|
|
168
|
-
let cwd;
|
|
169
|
-
try {
|
|
170
|
-
cwd = normalizeCwd(rawCwd);
|
|
171
|
-
}
|
|
172
|
-
catch {
|
|
173
|
-
let path = rawCwd.trim();
|
|
174
|
-
if (path === "~")
|
|
175
|
-
path = homedir();
|
|
176
|
-
else if (path.startsWith("~/"))
|
|
177
|
-
path = join(homedir(), path.slice(2));
|
|
178
|
-
cwd = isAbsolute(path) ? resolvePath(path) : resolvePath(process.cwd(), path);
|
|
179
|
-
}
|
|
180
|
-
return loadRegistry().daemons.find((entry) => entry.cwd === cwd);
|
|
181
|
-
}
|
|
182
|
-
/** Persists intended lifecycle independently from process state. */
|
|
183
|
-
export function setDaemonDesiredState(id, desiredState) {
|
|
184
|
-
const registry = loadRegistry();
|
|
185
|
-
const entry = registry.daemons.find((item) => item.id === id);
|
|
186
|
-
if (!entry)
|
|
187
|
-
return undefined;
|
|
188
|
-
entry.desired_state = desiredState;
|
|
189
|
-
saveRegistry(registry);
|
|
190
|
-
return entry;
|
|
191
|
-
}
|
|
192
|
-
/** Returns v2 entries in insertion order. */
|
|
193
|
-
export function listDaemons() {
|
|
194
|
-
return loadRegistry().daemons;
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Backward compatible export name only. v2 deliberately has no in-place
|
|
198
|
-
* migration: an old registry must be explicitly replaced by its operator.
|
|
199
|
-
*/
|
|
200
|
-
export function migrateRegistryNames() {
|
|
201
|
-
loadRegistry();
|
|
202
|
-
return 0;
|
|
203
|
-
}
|
|
204
|
-
export function registryPath() {
|
|
205
|
-
return registryPathInternal();
|
|
206
|
-
}
|
|
207
|
-
//# sourceMappingURL=registry.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/daemon/registry.ts"],"names":[],"mappings":"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"}
|