@danypops/papyrus 0.52.1 → 0.53.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/package.json +2 -2
- package/src/daemon/daemon-state.ts +33 -1
- package/src/daemon/daemon.ts +13 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danypops/papyrus",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.53.0",
|
|
4
4
|
"description": "Daemon-backed graph artifacts, evidence-bearing tasks, rules, skills, and native TUI workflows for Pi",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@danypops/vehicle-client": "^0.6.1",
|
|
37
37
|
"@danypops/vehicle-core": "^0.12.3",
|
|
38
|
-
"@danypops/vehicle-server": "^0.
|
|
38
|
+
"@danypops/vehicle-server": "^0.22.0",
|
|
39
39
|
"@stricli/core": "^1.3.0"
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -2,7 +2,7 @@ import { randomBytes } from "node:crypto";
|
|
|
2
2
|
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
-
import { LOOPBACK_HOST, removeDaemonHandle, writeDaemonHandle } from "@danypops/vehicle-server/paths";
|
|
5
|
+
import { LOOPBACK_HOST, removeDaemonHandle, resolveSharedVehicleHandlePath, writeDaemonHandle } from "@danypops/vehicle-server/paths";
|
|
6
6
|
import {
|
|
7
7
|
DAEMON_DIR_ENV,
|
|
8
8
|
DAEMON_HANDLE_FILE,
|
|
@@ -69,6 +69,38 @@ export function clearVehicleHandle(dir: string): void {
|
|
|
69
69
|
removeDaemonHandle(vehicleHandlePath(dir));
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
/** Where the private auth token lives -- passed as SharedVehicleHandleEntry.tokenPath so a broker-mode discoverer with read access to it can authenticate against Papyrus. */
|
|
73
|
+
export function tokenPath(dir: string): string {
|
|
74
|
+
return join(dir, DAEMON_TOKEN_FILE);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Papyrus's own stable identity name in the shared Vehicle Handle Directory (see @danypops/vehicle-server's resolveSharedVehicleHandlePath) -- must match the ownVehicleName Vehicle Shell broker mode is registered under. */
|
|
78
|
+
export const PAPYRUS_VEHICLE_NAME = "papyrus";
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Writes Papyrus's entry into the shared, cross-package Vehicle Handle Directory (independent of
|
|
82
|
+
* writeVehicleHandle's own private per-package handle file above) -- the seam a broker-mode
|
|
83
|
+
* tools_list/tools_man discovery scan reads without needing to already know Papyrus's own
|
|
84
|
+
* daemonStateDir convention in advance. env is injectable for tests; defaults to process.env.
|
|
85
|
+
*/
|
|
86
|
+
export function writeSharedVehicleHandle(
|
|
87
|
+
port: number,
|
|
88
|
+
tokenFilePath: string,
|
|
89
|
+
pid: number = process.pid,
|
|
90
|
+
env: Record<string, string | undefined> = process.env,
|
|
91
|
+
): void {
|
|
92
|
+
writeDaemonHandle(resolveSharedVehicleHandlePath(PAPYRUS_VEHICLE_NAME, { env }), {
|
|
93
|
+
host: LOOPBACK_HOST,
|
|
94
|
+
port,
|
|
95
|
+
pid,
|
|
96
|
+
tokenPath: tokenFilePath,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function clearSharedVehicleHandle(env: Record<string, string | undefined> = process.env): void {
|
|
101
|
+
removeDaemonHandle(resolveSharedVehicleHandlePath(PAPYRUS_VEHICLE_NAME, { env }));
|
|
102
|
+
}
|
|
103
|
+
|
|
72
104
|
export function readDaemonHandle(dir: string): DaemonHandle | undefined {
|
|
73
105
|
try {
|
|
74
106
|
const token = readFileSync(join(dir, DAEMON_TOKEN_FILE), "utf8").trim();
|
package/src/daemon/daemon.ts
CHANGED
|
@@ -10,11 +10,14 @@ import { logEvent, vehicleLogger } from "../log/log.ts";
|
|
|
10
10
|
import { createApp, createPapyrusService } from "../service.ts";
|
|
11
11
|
import {
|
|
12
12
|
clearDaemonPort,
|
|
13
|
+
clearSharedVehicleHandle,
|
|
13
14
|
clearVehicleHandle,
|
|
14
15
|
daemonStateDir,
|
|
15
16
|
lifecyclePath,
|
|
16
17
|
loadOrCreateToken,
|
|
18
|
+
tokenPath,
|
|
17
19
|
writeDaemonPort,
|
|
20
|
+
writeSharedVehicleHandle,
|
|
18
21
|
writeVehicleHandle,
|
|
19
22
|
} from "./daemon-state.ts";
|
|
20
23
|
|
|
@@ -92,6 +95,11 @@ export async function serveMain(): Promise<void> {
|
|
|
92
95
|
}
|
|
93
96
|
writeDaemonPort(stateDir, server.port);
|
|
94
97
|
writeVehicleHandle(stateDir, server.port);
|
|
98
|
+
try {
|
|
99
|
+
writeSharedVehicleHandle(server.port, tokenPath(stateDir));
|
|
100
|
+
} catch (error) {
|
|
101
|
+
logEvent("error", "shared_vehicle_handle_write_failed", { message: error instanceof Error ? error.message : String(error) });
|
|
102
|
+
}
|
|
95
103
|
const checkpointTimer = setInterval(() => {
|
|
96
104
|
try {
|
|
97
105
|
service.checkpoint();
|
|
@@ -137,6 +145,11 @@ export async function serveMain(): Promise<void> {
|
|
|
137
145
|
clearInterval(purgeTrashTimer);
|
|
138
146
|
clearDaemonPort(stateDir);
|
|
139
147
|
clearVehicleHandle(stateDir);
|
|
148
|
+
try {
|
|
149
|
+
clearSharedVehicleHandle();
|
|
150
|
+
} catch (error) {
|
|
151
|
+
logEvent("error", "shared_vehicle_handle_remove_failed", { message: error instanceof Error ? error.message : String(error) });
|
|
152
|
+
}
|
|
140
153
|
releaseDaemonLock(lockPath);
|
|
141
154
|
service.close();
|
|
142
155
|
// .finally() re-throws rather than handling a rejection -- catching it first turns a bare
|