@lordierclaw/bluenote 0.4.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/LICENSE +201 -0
- package/README.md +217 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +10 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +37 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/daemon.d.ts +2 -0
- package/dist/commands/daemon.js +163 -0
- package/dist/commands/daemon.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +113 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/help.d.ts +3 -0
- package/dist/commands/help.js +25 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/tui.d.ts +2 -0
- package/dist/commands/tui.js +63 -0
- package/dist/commands/tui.js.map +1 -0
- package/dist/commands/version.d.ts +2 -0
- package/dist/commands/version.js +17 -0
- package/dist/commands/version.js.map +1 -0
- package/dist/commands/web.d.ts +2 -0
- package/dist/commands/web.js +63 -0
- package/dist/commands/web.js.map +1 -0
- package/dist/daemon/paths.d.ts +3 -0
- package/dist/daemon/paths.js +29 -0
- package/dist/daemon/paths.js.map +1 -0
- package/dist/daemon/router.d.ts +38 -0
- package/dist/daemon/router.js +107 -0
- package/dist/daemon/router.js.map +1 -0
- package/dist/daemon/server.d.ts +13 -0
- package/dist/daemon/server.js +78 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/daemon/token.d.ts +1 -0
- package/dist/daemon/token.js +11 -0
- package/dist/daemon/token.js.map +1 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/command-discovery.d.ts +31 -0
- package/dist/utils/command-discovery.js +162 -0
- package/dist/utils/command-discovery.js.map +1 -0
- package/dist/utils/daemon-state.d.ts +21 -0
- package/dist/utils/daemon-state.js +99 -0
- package/dist/utils/daemon-state.js.map +1 -0
- package/dist/utils/lazy-import.d.ts +1 -0
- package/dist/utils/lazy-import.js +10 -0
- package/dist/utils/lazy-import.js.map +1 -0
- package/dist/utils/package-info.d.ts +15 -0
- package/dist/utils/package-info.js +49 -0
- package/dist/utils/package-info.js.map +1 -0
- package/dist/utils/runtime-requirements.d.ts +8 -0
- package/dist/utils/runtime-requirements.js +26 -0
- package/dist/utils/runtime-requirements.js.map +1 -0
- package/dist/utils/write.d.ts +1 -0
- package/dist/utils/write.js +9 -0
- package/dist/utils/write.js.map +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.runDoctor = runDoctor;
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const os_1 = __importDefault(require("os"));
|
|
9
|
+
const paths_1 = require("../daemon/paths");
|
|
10
|
+
const command_discovery_1 = require("../utils/command-discovery");
|
|
11
|
+
const daemon_state_1 = require("../utils/daemon-state");
|
|
12
|
+
const package_info_1 = require("../utils/package-info");
|
|
13
|
+
const runtime_requirements_1 = require("../utils/runtime-requirements");
|
|
14
|
+
const write_1 = require("../utils/write");
|
|
15
|
+
const OPTIONAL_CLIENTS = ["bluenote-webui", "bluenote-term"];
|
|
16
|
+
function isWindowsShellCommand(commandPath, platform) {
|
|
17
|
+
return platform === "win32" && /\.(cmd|bat)$/i.test(commandPath);
|
|
18
|
+
}
|
|
19
|
+
function runClientCheck(commandPath, args, io, platform, env) {
|
|
20
|
+
const spawnSync = io.spawnSync || child_process_1.spawnSync;
|
|
21
|
+
const result = spawnSync(commandPath, args, {
|
|
22
|
+
encoding: "utf8",
|
|
23
|
+
env,
|
|
24
|
+
shell: isWindowsShellCommand(commandPath, platform),
|
|
25
|
+
timeout: 5000,
|
|
26
|
+
});
|
|
27
|
+
return {
|
|
28
|
+
ok: !result.error && result.status === 0,
|
|
29
|
+
stdout: String(result.stdout || ""),
|
|
30
|
+
stderr: String(result.stderr || ""),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function firstLine(value) {
|
|
34
|
+
return value.split(/\r?\n/).map((line) => line.trim()).find(Boolean);
|
|
35
|
+
}
|
|
36
|
+
function checkBun(io) {
|
|
37
|
+
const spawnSync = io.spawnSync || child_process_1.spawnSync;
|
|
38
|
+
const result = spawnSync("bun", ["--version"], { encoding: "utf8", env: io.env || process.env });
|
|
39
|
+
if (result.error || result.status !== 0)
|
|
40
|
+
return { available: false };
|
|
41
|
+
return { available: true, version: String(result.stdout || "").trim() };
|
|
42
|
+
}
|
|
43
|
+
async function runDoctor(args = [], io = {}) {
|
|
44
|
+
const stdout = io.stdout || process.stdout;
|
|
45
|
+
const stderr = io.stderr || process.stderr;
|
|
46
|
+
const env = io.env || process.env;
|
|
47
|
+
const parsedClientMode = (0, command_discovery_1.parseClientModeArgs)(args, env);
|
|
48
|
+
if (!parsedClientMode.ok) {
|
|
49
|
+
(0, write_1.write)(stderr, parsedClientMode.message);
|
|
50
|
+
return 1;
|
|
51
|
+
}
|
|
52
|
+
const nodeVersion = io.nodeVersion || process.versions.node;
|
|
53
|
+
const platform = io.platform || process.platform;
|
|
54
|
+
const supportedNode = (0, runtime_requirements_1.isSupportedNodeVersion)(nodeVersion);
|
|
55
|
+
const ownPackage = (0, package_info_1.readOwnPackageInfo)();
|
|
56
|
+
(0, write_1.write)(stdout, "BlueNote doctor\n\n");
|
|
57
|
+
(0, write_1.write)(stdout, "Distribution\n");
|
|
58
|
+
(0, write_1.write)(stdout, " command: ok\n");
|
|
59
|
+
(0, write_1.write)(stdout, ` version: ${ownPackage.version}\n`);
|
|
60
|
+
(0, write_1.write)(stdout, ` platform: ${platform} (${os_1.default.arch()})\n`);
|
|
61
|
+
(0, write_1.write)(stdout, ` node: ${supportedNode ? "ok" : "unsupported"} (${nodeVersion}; requires ${(0, runtime_requirements_1.nodeRequirementText)()})\n`);
|
|
62
|
+
(0, write_1.write)(stdout, `Node status: ${supportedNode ? "ok" : "unsupported"}\n`);
|
|
63
|
+
const daemon = await (0, daemon_state_1.readDaemonStatus)(env);
|
|
64
|
+
(0, write_1.write)(stdout, "\nDaemon\n");
|
|
65
|
+
(0, write_1.write)(stdout, ` status: ${daemon.state}\n`);
|
|
66
|
+
(0, write_1.write)(stdout, ` endpoint: ${daemon.metadata ? daemon.metadata.url : "unavailable"}\n`);
|
|
67
|
+
(0, write_1.write)(stdout, ` pid: ${daemon.metadata?.pid || "unavailable"}\n`);
|
|
68
|
+
(0, write_1.write)(stdout, ` token: ${daemon.metadata?.token ? "present" : "missing"}\n`);
|
|
69
|
+
(0, write_1.write)(stdout, ` health: ${daemon.healthOk ? "ok" : daemon.state === "stopped" ? "not checked" : "failed"}\n`);
|
|
70
|
+
(0, write_1.write)(stdout, "\nClients\n");
|
|
71
|
+
let builtTuiAvailable = false;
|
|
72
|
+
for (const client of OPTIONAL_CLIENTS) {
|
|
73
|
+
const resolution = (0, command_discovery_1.resolveClientCommand)(client, { env, clientMode: parsedClientMode.mode, platform, pathext: env.PATHEXT });
|
|
74
|
+
if (!resolution) {
|
|
75
|
+
(0, write_1.write)(stdout, ` ${client}: missing\n`);
|
|
76
|
+
(0, write_1.write)(stdout, " version: unavailable\n");
|
|
77
|
+
(0, write_1.write)(stdout, " daemon handshake: not checked\n");
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const clientEnv = { ...env };
|
|
81
|
+
if (daemon.state === "running" && daemon.metadata) {
|
|
82
|
+
clientEnv.BLUENOTE_DAEMON_URL = daemon.metadata.url;
|
|
83
|
+
clientEnv.BLUENOTE_DAEMON_TOKEN = daemon.metadata.token;
|
|
84
|
+
}
|
|
85
|
+
const version = runClientCheck(resolution.path, ["--version"], io, platform, clientEnv);
|
|
86
|
+
const handshake = daemon.state === "running" && daemon.metadata
|
|
87
|
+
? runClientCheck(resolution.path, ["--check-daemon"], io, platform, clientEnv)
|
|
88
|
+
: undefined;
|
|
89
|
+
const status = version.ok && (!handshake || handshake.ok) ? resolution.mode : "broken";
|
|
90
|
+
if (client === "bluenote-term" && resolution.mode === "built" && status === "built")
|
|
91
|
+
builtTuiAvailable = true;
|
|
92
|
+
(0, write_1.write)(stdout, ` ${client}: ${status}\n`);
|
|
93
|
+
(0, write_1.write)(stdout, ` path: ${resolution.path}\n`);
|
|
94
|
+
(0, write_1.write)(stdout, ` version: ${version.ok ? firstLine(version.stdout) || "available" : "unavailable"}\n`);
|
|
95
|
+
(0, write_1.write)(stdout, ` daemon handshake: ${handshake ? handshake.ok ? "ok" : "failed" : "not checked"}\n`);
|
|
96
|
+
}
|
|
97
|
+
if (builtTuiAvailable) {
|
|
98
|
+
(0, write_1.write)(stdout, " Bun for source TUI: not required for built TUI\n");
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
const bun = checkBun(io);
|
|
102
|
+
(0, write_1.write)(stdout, ` Bun for source TUI: ${bun.available ? `available${bun.version ? ` (${bun.version})` : ""}` : "not found; install Bun for source/development TUI usage"}\n`);
|
|
103
|
+
}
|
|
104
|
+
(0, write_1.write)(stdout, "\nConfig\n");
|
|
105
|
+
(0, write_1.write)(stdout, ` config dir: ${(0, paths_1.getBluenoteStateDir)(env)}\n`);
|
|
106
|
+
(0, write_1.write)(stdout, ` daemon state: ${(0, paths_1.getDaemonStatePath)(env)}\n`);
|
|
107
|
+
(0, write_1.write)(stdout, ` daemon endpoint: ${daemon.metadata ? daemon.metadata.url : "unavailable"}\n`);
|
|
108
|
+
(0, write_1.write)(stdout, "\nAI\n");
|
|
109
|
+
(0, write_1.write)(stdout, " provider: not configured\n");
|
|
110
|
+
(0, write_1.write)(stdout, " secrets: not printed\n");
|
|
111
|
+
return supportedNode ? 0 : 1;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":";;;;;AAiDA,8BA4EC;AA7HD,iDAA6D;AAC7D,4CAAmB;AAGnB,2CAAyE;AACzE,kEAAsF;AACtF,wDAAwD;AACxD,wDAA0D;AAC1D,wEAA2F;AAC3F,0CAAsC;AAEtC,MAAM,gBAAgB,GAAG,CAAC,gBAAgB,EAAE,eAAe,CAAU,CAAA;AAErE,SAAS,qBAAqB,CAAC,WAAmB,EAAE,QAAyB;IAC3E,OAAO,QAAQ,KAAK,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;AAClE,CAAC;AAED,SAAS,cAAc,CACrB,WAAmB,EACnB,IAAc,EACd,EAAa,EACb,QAAyB,EACzB,GAAsB;IAEtB,MAAM,SAAS,GAAG,EAAE,CAAC,SAAS,IAAI,yBAAgB,CAAA;IAClD,MAAM,MAAM,GAAG,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE;QAC1C,QAAQ,EAAE,MAAM;QAChB,GAAG;QACH,KAAK,EAAE,qBAAqB,CAAC,WAAW,EAAE,QAAQ,CAAC;QACnD,OAAO,EAAE,IAAK;KACf,CAAC,CAAA;IACF,OAAO;QACL,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QACxC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;QACnC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;KACpC,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AACtE,CAAC;AAED,SAAS,QAAQ,CAAC,EAAa;IAC7B,MAAM,SAAS,GAAG,EAAE,CAAC,SAAS,IAAI,yBAAgB,CAAA;IAClD,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;IAChG,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAA;IACpE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;AACzE,CAAC;AAEM,KAAK,UAAU,SAAS,CAAC,OAAiB,EAAE,EAAE,KAAgB,EAAE;IACrE,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAA;IAC1C,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAA;IAC1C,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAA;IACjC,MAAM,gBAAgB,GAAG,IAAA,uCAAmB,EAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IACvD,IAAI,CAAC,gBAAgB,CAAC,EAAE,EAAE,CAAC;QACzB,IAAA,aAAK,EAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAA;QACvC,OAAO,CAAC,CAAA;IACV,CAAC;IACD,MAAM,WAAW,GAAG,EAAE,CAAC,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAA;IAC3D,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAA;IAChD,MAAM,aAAa,GAAG,IAAA,6CAAsB,EAAC,WAAW,CAAC,CAAA;IACzD,MAAM,UAAU,GAAG,IAAA,iCAAkB,GAAE,CAAA;IAEvC,IAAA,aAAK,EAAC,MAAM,EAAE,qBAAqB,CAAC,CAAA;IACpC,IAAA,aAAK,EAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IAC/B,IAAA,aAAK,EAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;IAChC,IAAA,aAAK,EAAC,MAAM,EAAE,cAAc,UAAU,CAAC,OAAO,IAAI,CAAC,CAAA;IACnD,IAAA,aAAK,EAAC,MAAM,EAAE,eAAe,QAAQ,KAAK,YAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IACzD,IAAA,aAAK,EAAC,MAAM,EAAE,WAAW,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,KAAK,WAAW,cAAc,IAAA,0CAAmB,GAAE,KAAK,CAAC,CAAA;IACtH,IAAA,aAAK,EAAC,MAAM,EAAE,gBAAgB,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAA;IAEvE,MAAM,MAAM,GAAG,MAAM,IAAA,+BAAgB,EAAC,GAAG,CAAC,CAAA;IAC1C,IAAA,aAAK,EAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IAC3B,IAAA,aAAK,EAAC,MAAM,EAAE,aAAa,MAAM,CAAC,KAAK,IAAI,CAAC,CAAA;IAC5C,IAAA,aAAK,EAAC,MAAM,EAAE,eAAe,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAA;IACvF,IAAA,aAAK,EAAC,MAAM,EAAE,UAAU,MAAM,CAAC,QAAQ,EAAE,GAAG,IAAI,aAAa,IAAI,CAAC,CAAA;IAClE,IAAA,aAAK,EAAC,MAAM,EAAE,YAAY,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAA;IAC7E,IAAA,aAAK,EAAC,MAAM,EAAE,aAAa,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAA;IAE9G,IAAA,aAAK,EAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IAC5B,IAAI,iBAAiB,GAAG,KAAK,CAAA;IAC7B,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;QACtC,MAAM,UAAU,GAAG,IAAA,wCAAoB,EAAC,MAAM,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;QAC3H,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,IAAA,aAAK,EAAC,MAAM,EAAE,KAAK,MAAM,aAAa,CAAC,CAAA;YACvC,IAAA,aAAK,EAAC,MAAM,EAAE,4BAA4B,CAAC,CAAA;YAC3C,IAAA,aAAK,EAAC,MAAM,EAAE,qCAAqC,CAAC,CAAA;YACpD,SAAQ;QACV,CAAC;QAED,MAAM,SAAS,GAAG,EAAE,GAAG,GAAG,EAAE,CAAA;QAC5B,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YAClD,SAAS,CAAC,mBAAmB,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAA;YACnD,SAAS,CAAC,qBAAqB,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAA;QACzD,CAAC;QACD,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAA;QACvF,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ;YAC7D,CAAC,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,gBAAgB,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,CAAC;YAC9E,CAAC,CAAC,SAAS,CAAA;QACb,MAAM,MAAM,GAAG,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAA;QACtF,IAAI,MAAM,KAAK,eAAe,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,KAAK,OAAO;YAAE,iBAAiB,GAAG,IAAI,CAAA;QAE7G,IAAA,aAAK,EAAC,MAAM,EAAE,KAAK,MAAM,KAAK,MAAM,IAAI,CAAC,CAAA;QACzC,IAAA,aAAK,EAAC,MAAM,EAAE,aAAa,UAAU,CAAC,IAAI,IAAI,CAAC,CAAA;QAC/C,IAAA,aAAK,EAAC,MAAM,EAAE,gBAAgB,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAA;QACxG,IAAA,aAAK,EAAC,MAAM,EAAE,yBAAyB,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAA;IACxG,CAAC;IAED,IAAI,iBAAiB,EAAE,CAAC;QACtB,IAAA,aAAK,EAAC,MAAM,EAAE,oDAAoD,CAAC,CAAA;IACrE,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;QACxB,IAAA,aAAK,EAAC,MAAM,EAAE,yBAAyB,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,yDAAyD,IAAI,CAAC,CAAA;IAC9K,CAAC;IAED,IAAA,aAAK,EAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IAC3B,IAAA,aAAK,EAAC,MAAM,EAAE,iBAAiB,IAAA,2BAAmB,EAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC5D,IAAA,aAAK,EAAC,MAAM,EAAE,mBAAmB,IAAA,0BAAkB,EAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC7D,IAAA,aAAK,EAAC,MAAM,EAAE,sBAAsB,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAA;IAE9F,IAAA,aAAK,EAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IACvB,IAAA,aAAK,EAAC,MAAM,EAAE,8BAA8B,CAAC,CAAA;IAC7C,IAAA,aAAK,EAAC,MAAM,EAAE,0BAA0B,CAAC,CAAA;IAEzC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAC9B,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CommandIo } from "../types";
|
|
2
|
+
export declare const HELP_TEXT = "BlueNote distribution CLI\n\nUsage: bluenote <command> [options]\n bn <command> [options]\n\nCommands:\n tui [...args] Launch the terminal interface via bluenote-term\n web [...args] Launch the local WebUI via bluenote-webui\n daemon start|status|stop Manage the local BlueNote daemon\n doctor Check runtime, daemon, and optional clients\n version Print package versions\n\nOptions:\n -h, --help Show this help message\n";
|
|
3
|
+
export declare function runHelp(_args?: string[], io?: CommandIo): number;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HELP_TEXT = void 0;
|
|
4
|
+
exports.runHelp = runHelp;
|
|
5
|
+
const write_1 = require("../utils/write");
|
|
6
|
+
exports.HELP_TEXT = `BlueNote distribution CLI
|
|
7
|
+
|
|
8
|
+
Usage: bluenote <command> [options]
|
|
9
|
+
bn <command> [options]
|
|
10
|
+
|
|
11
|
+
Commands:
|
|
12
|
+
tui [...args] Launch the terminal interface via bluenote-term
|
|
13
|
+
web [...args] Launch the local WebUI via bluenote-webui
|
|
14
|
+
daemon start|status|stop Manage the local BlueNote daemon
|
|
15
|
+
doctor Check runtime, daemon, and optional clients
|
|
16
|
+
version Print package versions
|
|
17
|
+
|
|
18
|
+
Options:
|
|
19
|
+
-h, --help Show this help message
|
|
20
|
+
`;
|
|
21
|
+
function runHelp(_args = [], io = {}) {
|
|
22
|
+
(0, write_1.write)(io.stdout || process.stdout, exports.HELP_TEXT);
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=help.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/commands/help.ts"],"names":[],"mappings":";;;AAmBA,0BAGC;AAtBD,0CAAsC;AAGzB,QAAA,SAAS,GAAG;;;;;;;;;;;;;;CAcxB,CAAA;AAED,SAAgB,OAAO,CAAC,QAAkB,EAAE,EAAE,KAAgB,EAAE;IAC9D,IAAA,aAAK,EAAC,EAAE,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,iBAAS,CAAC,CAAA;IAC7C,OAAO,CAAC,CAAA;AACV,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runTui = runTui;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const command_discovery_1 = require("../utils/command-discovery");
|
|
6
|
+
const daemon_state_1 = require("../utils/daemon-state");
|
|
7
|
+
const write_1 = require("../utils/write");
|
|
8
|
+
function daemonNotRunning(io) {
|
|
9
|
+
(0, write_1.write)(io.stderr || process.stderr, "BlueNote daemon is not running.\nRun: bluenote daemon start\n");
|
|
10
|
+
return 1;
|
|
11
|
+
}
|
|
12
|
+
function missingClient(io, command, mode) {
|
|
13
|
+
if (mode === "built") {
|
|
14
|
+
(0, write_1.write)(io.stderr || process.stderr, `Built client ${command} was not found in BLUENOTE_BUILT_CLIENT_DIR. Install the BlueNote built client artifact, set BLUENOTE_BUILT_CLIENT_DIR to its directory, or retry with --client-mode path for PATH discovery.\n`);
|
|
15
|
+
return 1;
|
|
16
|
+
}
|
|
17
|
+
(0, write_1.write)(io.stderr || process.stderr, `Optional client ${command} was not found on PATH. Install it with npm install -g ${command} and retry.\n`);
|
|
18
|
+
return 1;
|
|
19
|
+
}
|
|
20
|
+
async function runTui(args = [], io = {}) {
|
|
21
|
+
const env = io.env || process.env;
|
|
22
|
+
const daemon = await (0, daemon_state_1.readDaemonStatus)(env);
|
|
23
|
+
if (daemon.state !== "running" || !daemon.metadata)
|
|
24
|
+
return daemonNotRunning(io);
|
|
25
|
+
const metadata = daemon.metadata;
|
|
26
|
+
const parsed = (0, command_discovery_1.parseClientModeArgs)(args, env);
|
|
27
|
+
if (!parsed.ok) {
|
|
28
|
+
(0, write_1.write)(io.stderr || process.stderr, parsed.message);
|
|
29
|
+
return 1;
|
|
30
|
+
}
|
|
31
|
+
const resolution = (0, command_discovery_1.resolveClientCommand)("bluenote-term", { env, clientMode: parsed.mode, platform: io.platform || process.platform, pathext: env.PATHEXT });
|
|
32
|
+
if (!resolution)
|
|
33
|
+
return missingClient(io, "bluenote-term", parsed.mode);
|
|
34
|
+
const spawn = io.spawn || child_process_1.spawn;
|
|
35
|
+
return await new Promise((resolve) => {
|
|
36
|
+
let child;
|
|
37
|
+
try {
|
|
38
|
+
child = spawn(resolution.path, parsed.args, {
|
|
39
|
+
stdio: ["inherit", "inherit", "inherit"],
|
|
40
|
+
shell: (io.platform || process.platform) === "win32" && /\.(cmd|bat)$/i.test(resolution.path),
|
|
41
|
+
env: {
|
|
42
|
+
...env,
|
|
43
|
+
BLUENOTE_DAEMON_URL: metadata.url,
|
|
44
|
+
BLUENOTE_DAEMON_TOKEN: metadata.token,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
50
|
+
(0, write_1.write)(io.stderr || process.stderr, `Unable to launch bluenote-term: ${message}\n`);
|
|
51
|
+
resolve(1);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
child.on("error", (error) => {
|
|
55
|
+
(0, write_1.write)(io.stderr || process.stderr, `Unable to launch bluenote-term: ${error.message}\n`);
|
|
56
|
+
resolve(1);
|
|
57
|
+
});
|
|
58
|
+
child.on("exit", (code) => {
|
|
59
|
+
resolve(code === null ? 1 : code);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=tui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tui.js","sourceRoot":"","sources":["../../src/commands/tui.ts"],"names":[],"mappings":";;AAqBA,wBA0CC;AA/DD,iDAAqD;AAGrD,kEAAsF;AACtF,wDAAwD;AACxD,0CAAsC;AAEtC,SAAS,gBAAgB,CAAC,EAAa;IACrC,IAAA,aAAK,EAAC,EAAE,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,+DAA+D,CAAC,CAAA;IACnG,OAAO,CAAC,CAAA;AACV,CAAC;AAED,SAAS,aAAa,CAAC,EAAa,EAAE,OAAe,EAAE,IAAY;IACjE,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,IAAA,aAAK,EAAC,EAAE,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,gBAAgB,OAAO,iMAAiM,CAAC,CAAA;QAC5P,OAAO,CAAC,CAAA;IACV,CAAC;IACD,IAAA,aAAK,EAAC,EAAE,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,mBAAmB,OAAO,0DAA0D,OAAO,eAAe,CAAC,CAAA;IAC9I,OAAO,CAAC,CAAA;AACV,CAAC;AAEM,KAAK,UAAU,MAAM,CAAC,OAAiB,EAAE,EAAE,KAAgB,EAAE;IAClE,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAA;IACjC,MAAM,MAAM,GAAG,MAAM,IAAA,+BAAgB,EAAC,GAAG,CAAC,CAAA;IAC1C,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ;QAAE,OAAO,gBAAgB,CAAC,EAAE,CAAC,CAAA;IAC/E,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;IAChC,MAAM,MAAM,GAAG,IAAA,uCAAmB,EAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAC7C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,IAAA,aAAK,EAAC,EAAE,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;QAClD,OAAO,CAAC,CAAA;IACV,CAAC;IAED,MAAM,UAAU,GAAG,IAAA,wCAAoB,EAAC,eAAe,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;IAC3J,IAAI,CAAC,UAAU;QAAE,OAAO,aAAa,CAAC,EAAE,EAAE,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;IAEvE,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,IAAI,qBAAY,CAAA;IACtC,OAAO,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;QAC3C,IAAI,KAAK,CAAA;QACT,IAAI,CAAC;YACH,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE;gBAC1C,KAAK,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC;gBACxC,KAAK,EAAE,CAAC,EAAE,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBAC7F,GAAG,EAAE;oBACH,GAAG,GAAG;oBACN,mBAAmB,EAAE,QAAQ,CAAC,GAAG;oBACjC,qBAAqB,EAAE,QAAQ,CAAC,KAAK;iBACtC;aACF,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACtE,IAAA,aAAK,EAAC,EAAE,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,mCAAmC,OAAO,IAAI,CAAC,CAAA;YAClF,OAAO,CAAC,CAAC,CAAC,CAAA;YACV,OAAM;QACR,CAAC;QAED,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC1B,IAAA,aAAK,EAAC,EAAE,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,mCAAmC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAA;YACxF,OAAO,CAAC,CAAC,CAAC,CAAA;QACZ,CAAC,CAAC,CAAA;QACF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACnC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runVersion = runVersion;
|
|
4
|
+
const package_info_1 = require("../utils/package-info");
|
|
5
|
+
const write_1 = require("../utils/write");
|
|
6
|
+
const RUNTIME_PACKAGES = ["@lordierclaw/bluenote-core"];
|
|
7
|
+
function runVersion(_args = [], io = {}) {
|
|
8
|
+
const own = (0, package_info_1.readOwnPackageInfo)();
|
|
9
|
+
const lines = [`${own.name} ${own.version}`];
|
|
10
|
+
for (const packageName of RUNTIME_PACKAGES) {
|
|
11
|
+
const resolution = (0, package_info_1.resolvePackageJson)(packageName);
|
|
12
|
+
lines.push(`${packageName} ${resolution.version || (resolution.resolved ? "version unavailable" : "not installed")}`);
|
|
13
|
+
}
|
|
14
|
+
(0, write_1.write)(io.stdout || process.stdout, `${lines.join("\n")}\n`);
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/commands/version.ts"],"names":[],"mappings":";;AAMA,gCAWC;AAhBD,wDAA8E;AAC9E,0CAAsC;AAEtC,MAAM,gBAAgB,GAAG,CAAC,4BAA4B,CAAC,CAAA;AAEvD,SAAgB,UAAU,CAAC,QAAkB,EAAE,EAAE,KAAgB,EAAE;IACjE,MAAM,GAAG,GAAG,IAAA,iCAAkB,GAAE,CAAA;IAChC,MAAM,KAAK,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;IAE5C,KAAK,MAAM,WAAW,IAAI,gBAAgB,EAAE,CAAC;QAC3C,MAAM,UAAU,GAAG,IAAA,iCAAkB,EAAC,WAAW,CAAC,CAAA;QAClD,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,IAAI,UAAU,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,CAAA;IACvH,CAAC;IAED,IAAA,aAAK,EAAC,EAAE,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3D,OAAO,CAAC,CAAA;AACV,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runWeb = runWeb;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const command_discovery_1 = require("../utils/command-discovery");
|
|
6
|
+
const daemon_state_1 = require("../utils/daemon-state");
|
|
7
|
+
const write_1 = require("../utils/write");
|
|
8
|
+
function daemonNotRunning(io) {
|
|
9
|
+
(0, write_1.write)(io.stderr || process.stderr, "BlueNote daemon is not running.\nRun: bluenote daemon start\n");
|
|
10
|
+
return 1;
|
|
11
|
+
}
|
|
12
|
+
function missingClient(io, command, mode) {
|
|
13
|
+
if (mode === "built") {
|
|
14
|
+
(0, write_1.write)(io.stderr || process.stderr, `Built client ${command} was not found in BLUENOTE_BUILT_CLIENT_DIR. Install the BlueNote built client artifact, set BLUENOTE_BUILT_CLIENT_DIR to its directory, or retry with --client-mode path for PATH discovery.\n`);
|
|
15
|
+
return 1;
|
|
16
|
+
}
|
|
17
|
+
(0, write_1.write)(io.stderr || process.stderr, `Optional client ${command} was not found on PATH. Install it with npm install -g ${command} and retry.\n`);
|
|
18
|
+
return 1;
|
|
19
|
+
}
|
|
20
|
+
async function runWeb(args = [], io = {}) {
|
|
21
|
+
const env = io.env || process.env;
|
|
22
|
+
const daemon = await (0, daemon_state_1.readDaemonStatus)(env);
|
|
23
|
+
if (daemon.state !== "running" || !daemon.metadata)
|
|
24
|
+
return daemonNotRunning(io);
|
|
25
|
+
const metadata = daemon.metadata;
|
|
26
|
+
const parsed = (0, command_discovery_1.parseClientModeArgs)(args, env);
|
|
27
|
+
if (!parsed.ok) {
|
|
28
|
+
(0, write_1.write)(io.stderr || process.stderr, parsed.message);
|
|
29
|
+
return 1;
|
|
30
|
+
}
|
|
31
|
+
const resolution = (0, command_discovery_1.resolveClientCommand)("bluenote-webui", { env, clientMode: parsed.mode, platform: io.platform || process.platform, pathext: env.PATHEXT });
|
|
32
|
+
if (!resolution)
|
|
33
|
+
return missingClient(io, "bluenote-webui", parsed.mode);
|
|
34
|
+
const spawn = io.spawn || child_process_1.spawn;
|
|
35
|
+
return await new Promise((resolve) => {
|
|
36
|
+
let child;
|
|
37
|
+
try {
|
|
38
|
+
child = spawn(resolution.path, parsed.args, {
|
|
39
|
+
stdio: ["inherit", "inherit", "inherit"],
|
|
40
|
+
shell: (io.platform || process.platform) === "win32" && /\.(cmd|bat)$/i.test(resolution.path),
|
|
41
|
+
env: {
|
|
42
|
+
...env,
|
|
43
|
+
BLUENOTE_DAEMON_URL: metadata.url,
|
|
44
|
+
BLUENOTE_DAEMON_TOKEN: metadata.token,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
50
|
+
(0, write_1.write)(io.stderr || process.stderr, `Unable to launch bluenote-webui: ${message}\n`);
|
|
51
|
+
resolve(1);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
child.on("error", (error) => {
|
|
55
|
+
(0, write_1.write)(io.stderr || process.stderr, `Unable to launch bluenote-webui: ${error.message}\n`);
|
|
56
|
+
resolve(1);
|
|
57
|
+
});
|
|
58
|
+
child.on("exit", (code) => {
|
|
59
|
+
resolve(code === null ? 1 : code);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/commands/web.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getBluenoteStateDir = getBluenoteStateDir;
|
|
7
|
+
exports.getDaemonStatePath = getDaemonStatePath;
|
|
8
|
+
exports.ensureParentDir = ensureParentDir;
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const os_1 = __importDefault(require("os"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
function getBluenoteStateDir(env = process.env) {
|
|
13
|
+
if (env.BLUENOTE_DAEMON_STATE)
|
|
14
|
+
return path_1.default.dirname(env.BLUENOTE_DAEMON_STATE);
|
|
15
|
+
if (env.BLUENOTE_CONFIG_HOME)
|
|
16
|
+
return path_1.default.join(env.BLUENOTE_CONFIG_HOME, "bluenote");
|
|
17
|
+
if (env.XDG_CONFIG_HOME)
|
|
18
|
+
return path_1.default.join(env.XDG_CONFIG_HOME, "bluenote");
|
|
19
|
+
return path_1.default.join(os_1.default.homedir(), ".config", "bluenote");
|
|
20
|
+
}
|
|
21
|
+
function getDaemonStatePath(env = process.env) {
|
|
22
|
+
if (env.BLUENOTE_DAEMON_STATE)
|
|
23
|
+
return env.BLUENOTE_DAEMON_STATE;
|
|
24
|
+
return path_1.default.join(getBluenoteStateDir(env), "daemon.json");
|
|
25
|
+
}
|
|
26
|
+
function ensureParentDir(filePath) {
|
|
27
|
+
fs_1.default.mkdirSync(path_1.default.dirname(filePath), { recursive: true });
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/daemon/paths.ts"],"names":[],"mappings":";;;;;AAIA,kDAKC;AAED,gDAGC;AAED,0CAEC;AAlBD,4CAAmB;AACnB,4CAAmB;AACnB,gDAAuB;AAEvB,SAAgB,mBAAmB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACtE,IAAI,GAAG,CAAC,qBAAqB;QAAE,OAAO,cAAI,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAA;IAC7E,IAAI,GAAG,CAAC,oBAAoB;QAAE,OAAO,cAAI,CAAC,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAA;IACpF,IAAI,GAAG,CAAC,eAAe;QAAE,OAAO,cAAI,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;IAC1E,OAAO,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;AACvD,CAAC;AAED,SAAgB,kBAAkB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACrE,IAAI,GAAG,CAAC,qBAAqB;QAAE,OAAO,GAAG,CAAC,qBAAqB,CAAA;IAC/D,OAAO,cAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC,CAAA;AAC3D,CAAC;AAED,SAAgB,eAAe,CAAC,QAAgB;IAC9C,YAAE,CAAC,SAAS,CAAC,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;AAC3D,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import http from "http";
|
|
2
|
+
export type ApiErrorBody = {
|
|
3
|
+
error: {
|
|
4
|
+
code: string;
|
|
5
|
+
message: string;
|
|
6
|
+
hint?: string;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
export type DaemonRequestContext = {
|
|
10
|
+
request: http.IncomingMessage;
|
|
11
|
+
response: http.ServerResponse;
|
|
12
|
+
url: URL;
|
|
13
|
+
};
|
|
14
|
+
export type DaemonRouteHandler = (context: DaemonRequestContext) => void | Promise<void>;
|
|
15
|
+
export type DaemonRouteOptions = {
|
|
16
|
+
auth?: boolean;
|
|
17
|
+
};
|
|
18
|
+
export declare class HttpError extends Error {
|
|
19
|
+
readonly statusCode: number;
|
|
20
|
+
readonly code: string;
|
|
21
|
+
readonly hint?: string;
|
|
22
|
+
constructor(statusCode: number, code: string, message: string, hint?: string);
|
|
23
|
+
}
|
|
24
|
+
export declare function writeJson(response: http.ServerResponse, statusCode: number, body: unknown): void;
|
|
25
|
+
export declare function toApiErrorBody(error: unknown): {
|
|
26
|
+
statusCode: number;
|
|
27
|
+
body: ApiErrorBody;
|
|
28
|
+
};
|
|
29
|
+
export declare function isBearerAuthorized(request: http.IncomingMessage, token: string): boolean;
|
|
30
|
+
export declare function requireBearerAuth(request: http.IncomingMessage, token: string): void;
|
|
31
|
+
export declare function readRequestBody(request: http.IncomingMessage, limitBytes?: number): Promise<string>;
|
|
32
|
+
export type DaemonRouter = {
|
|
33
|
+
get(path: string, handler: DaemonRouteHandler, options?: DaemonRouteOptions): void;
|
|
34
|
+
post(path: string, handler: DaemonRouteHandler, options?: DaemonRouteOptions): void;
|
|
35
|
+
register(method: string, path: string, handler: DaemonRouteHandler, options?: DaemonRouteOptions): void;
|
|
36
|
+
handle(request: http.IncomingMessage, response: http.ServerResponse): void;
|
|
37
|
+
};
|
|
38
|
+
export declare function createDaemonRouter(token: string): DaemonRouter;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HttpError = void 0;
|
|
4
|
+
exports.writeJson = writeJson;
|
|
5
|
+
exports.toApiErrorBody = toApiErrorBody;
|
|
6
|
+
exports.isBearerAuthorized = isBearerAuthorized;
|
|
7
|
+
exports.requireBearerAuth = requireBearerAuth;
|
|
8
|
+
exports.readRequestBody = readRequestBody;
|
|
9
|
+
exports.createDaemonRouter = createDaemonRouter;
|
|
10
|
+
class HttpError extends Error {
|
|
11
|
+
constructor(statusCode, code, message, hint) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.statusCode = statusCode;
|
|
14
|
+
this.code = code;
|
|
15
|
+
this.hint = hint;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.HttpError = HttpError;
|
|
19
|
+
function writeJson(response, statusCode, body) {
|
|
20
|
+
const text = JSON.stringify(body);
|
|
21
|
+
response.writeHead(statusCode, {
|
|
22
|
+
"content-type": "application/json; charset=utf-8",
|
|
23
|
+
"content-length": Buffer.byteLength(text),
|
|
24
|
+
});
|
|
25
|
+
response.end(text);
|
|
26
|
+
}
|
|
27
|
+
function toApiErrorBody(error) {
|
|
28
|
+
if (error instanceof HttpError) {
|
|
29
|
+
return {
|
|
30
|
+
statusCode: error.statusCode,
|
|
31
|
+
body: {
|
|
32
|
+
error: {
|
|
33
|
+
code: error.code,
|
|
34
|
+
message: error.message,
|
|
35
|
+
...(error.hint ? { hint: error.hint } : {}),
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
statusCode: 500,
|
|
42
|
+
body: { error: { code: "internal_error", message: "Unexpected daemon error" } },
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function isBearerAuthorized(request, token) {
|
|
46
|
+
const authorization = request.headers.authorization || "";
|
|
47
|
+
return authorization === `Bearer ${token}`;
|
|
48
|
+
}
|
|
49
|
+
function requireBearerAuth(request, token) {
|
|
50
|
+
if (!isBearerAuthorized(request, token)) {
|
|
51
|
+
throw new HttpError(401, "unauthorized", "Missing or invalid daemon token");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async function readRequestBody(request, limitBytes = 1024 * 1024) {
|
|
55
|
+
const chunks = [];
|
|
56
|
+
let totalBytes = 0;
|
|
57
|
+
for await (const chunk of request) {
|
|
58
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
|
|
59
|
+
totalBytes += buffer.byteLength;
|
|
60
|
+
if (totalBytes > limitBytes) {
|
|
61
|
+
throw new HttpError(400, "request_too_large", "Request body is too large");
|
|
62
|
+
}
|
|
63
|
+
chunks.push(buffer);
|
|
64
|
+
}
|
|
65
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
66
|
+
}
|
|
67
|
+
function createDaemonRouter(token) {
|
|
68
|
+
const routes = [];
|
|
69
|
+
function register(method, path, handler, options = {}) {
|
|
70
|
+
routes.push({ method: method.toUpperCase(), path, handler, auth: options.auth !== false });
|
|
71
|
+
}
|
|
72
|
+
function handle(request, response) {
|
|
73
|
+
const url = new URL(request.url || "/", "http://127.0.0.1");
|
|
74
|
+
const method = request.method || "GET";
|
|
75
|
+
const route = routes.find((candidate) => candidate.method === method && candidate.path === url.pathname);
|
|
76
|
+
Promise.resolve()
|
|
77
|
+
.then(async () => {
|
|
78
|
+
if (!route) {
|
|
79
|
+
requireBearerAuth(request, token);
|
|
80
|
+
throw new HttpError(404, "not_found", "Route not found");
|
|
81
|
+
}
|
|
82
|
+
if (route.auth) {
|
|
83
|
+
requireBearerAuth(request, token);
|
|
84
|
+
}
|
|
85
|
+
await route.handler({ request, response, url });
|
|
86
|
+
})
|
|
87
|
+
.catch((error) => {
|
|
88
|
+
if (response.headersSent || response.writableEnded) {
|
|
89
|
+
response.end();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const { statusCode, body } = toApiErrorBody(error);
|
|
93
|
+
writeJson(response, statusCode, body);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
get(path, handler, options) {
|
|
98
|
+
register("GET", path, handler, options);
|
|
99
|
+
},
|
|
100
|
+
post(path, handler, options) {
|
|
101
|
+
register("POST", path, handler, options);
|
|
102
|
+
},
|
|
103
|
+
register,
|
|
104
|
+
handle,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/daemon/router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type DaemonMetadata = {
|
|
2
|
+
pid: number;
|
|
3
|
+
url: string;
|
|
4
|
+
token: string;
|
|
5
|
+
startedAt: string;
|
|
6
|
+
version: string;
|
|
7
|
+
};
|
|
8
|
+
export type DaemonServerOptions = {
|
|
9
|
+
statePath: string;
|
|
10
|
+
token: string;
|
|
11
|
+
version: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function startDaemonServer(options: DaemonServerOptions): Promise<void>;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.startDaemonServer = startDaemonServer;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const http_1 = __importDefault(require("http"));
|
|
9
|
+
const paths_1 = require("./paths");
|
|
10
|
+
const router_1 = require("./router");
|
|
11
|
+
const BLUENOTE_DAEMON_API_VERSION = "1";
|
|
12
|
+
async function startDaemonServer(options) {
|
|
13
|
+
const router = (0, router_1.createDaemonRouter)(options.token);
|
|
14
|
+
const server = http_1.default.createServer((request, response) => router.handle(request, response));
|
|
15
|
+
router.get("/health", ({ response }) => {
|
|
16
|
+
(0, router_1.writeJson)(response, 200, { ok: true, name: "bluenote-daemon", version: options.version });
|
|
17
|
+
}, { auth: false });
|
|
18
|
+
router.get("/capabilities", ({ response }) => {
|
|
19
|
+
(0, router_1.writeJson)(response, 200, {
|
|
20
|
+
ok: true,
|
|
21
|
+
name: "bluenote-daemon",
|
|
22
|
+
version: options.version,
|
|
23
|
+
mode: "local-only",
|
|
24
|
+
apiVersion: BLUENOTE_DAEMON_API_VERSION,
|
|
25
|
+
workspaceApi: true,
|
|
26
|
+
notesApi: false,
|
|
27
|
+
aiApi: false,
|
|
28
|
+
clients: {
|
|
29
|
+
web: { daemonEnvironment: true },
|
|
30
|
+
tui: { daemonEnvironment: true },
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
router.post("/shutdown", ({ response }) => {
|
|
35
|
+
(0, router_1.writeJson)(response, 200, { ok: true });
|
|
36
|
+
server.close(() => {
|
|
37
|
+
try {
|
|
38
|
+
fs_1.default.rmSync(options.statePath, { force: true });
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
await new Promise((resolve, reject) => {
|
|
46
|
+
server.once("error", reject);
|
|
47
|
+
server.listen(0, "127.0.0.1", () => resolve());
|
|
48
|
+
});
|
|
49
|
+
const address = server.address();
|
|
50
|
+
const metadata = {
|
|
51
|
+
pid: process.pid,
|
|
52
|
+
url: `http://127.0.0.1:${address.port}`,
|
|
53
|
+
token: options.token,
|
|
54
|
+
startedAt: new Date().toISOString(),
|
|
55
|
+
version: options.version,
|
|
56
|
+
};
|
|
57
|
+
(0, paths_1.ensureParentDir)(options.statePath);
|
|
58
|
+
fs_1.default.rmSync(options.statePath, { force: true });
|
|
59
|
+
fs_1.default.writeFileSync(options.statePath, `${JSON.stringify(metadata, null, 2)}\n`, { mode: 0o600 });
|
|
60
|
+
fs_1.default.chmodSync(options.statePath, 0o600);
|
|
61
|
+
const cleanup = () => {
|
|
62
|
+
try {
|
|
63
|
+
fs_1.default.rmSync(options.statePath, { force: true });
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// best effort
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
process.once("SIGTERM", () => {
|
|
70
|
+
cleanup();
|
|
71
|
+
process.exit(0);
|
|
72
|
+
});
|
|
73
|
+
process.once("SIGINT", () => {
|
|
74
|
+
cleanup();
|
|
75
|
+
process.exit(0);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function createDaemonToken(): string;
|