peerllm-host-cli 0.1.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.
Files changed (190) hide show
  1. package/LICENSE +19 -0
  2. package/README.md +83 -0
  3. package/dist/cli/commands/agreement.d.ts +3 -0
  4. package/dist/cli/commands/agreement.d.ts.map +1 -0
  5. package/dist/cli/commands/agreement.js +151 -0
  6. package/dist/cli/commands/agreement.js.map +1 -0
  7. package/dist/cli/commands/config.d.ts +3 -0
  8. package/dist/cli/commands/config.d.ts.map +1 -0
  9. package/dist/cli/commands/config.js +163 -0
  10. package/dist/cli/commands/config.js.map +1 -0
  11. package/dist/cli/commands/diagnostics.d.ts +3 -0
  12. package/dist/cli/commands/diagnostics.d.ts.map +1 -0
  13. package/dist/cli/commands/diagnostics.js +131 -0
  14. package/dist/cli/commands/diagnostics.js.map +1 -0
  15. package/dist/cli/commands/doctor.d.ts +3 -0
  16. package/dist/cli/commands/doctor.d.ts.map +1 -0
  17. package/dist/cli/commands/doctor.js +349 -0
  18. package/dist/cli/commands/doctor.js.map +1 -0
  19. package/dist/cli/commands/events.d.ts +3 -0
  20. package/dist/cli/commands/events.d.ts.map +1 -0
  21. package/dist/cli/commands/events.js +51 -0
  22. package/dist/cli/commands/events.js.map +1 -0
  23. package/dist/cli/commands/host.d.ts +3 -0
  24. package/dist/cli/commands/host.d.ts.map +1 -0
  25. package/dist/cli/commands/host.js +252 -0
  26. package/dist/cli/commands/host.js.map +1 -0
  27. package/dist/cli/commands/login.d.ts +3 -0
  28. package/dist/cli/commands/login.d.ts.map +1 -0
  29. package/dist/cli/commands/login.js +51 -0
  30. package/dist/cli/commands/login.js.map +1 -0
  31. package/dist/cli/commands/logout.d.ts +3 -0
  32. package/dist/cli/commands/logout.d.ts.map +1 -0
  33. package/dist/cli/commands/logout.js +28 -0
  34. package/dist/cli/commands/logout.js.map +1 -0
  35. package/dist/cli/commands/logs.d.ts +3 -0
  36. package/dist/cli/commands/logs.d.ts.map +1 -0
  37. package/dist/cli/commands/logs.js +157 -0
  38. package/dist/cli/commands/logs.js.map +1 -0
  39. package/dist/cli/commands/models.d.ts +3 -0
  40. package/dist/cli/commands/models.d.ts.map +1 -0
  41. package/dist/cli/commands/models.js +227 -0
  42. package/dist/cli/commands/models.js.map +1 -0
  43. package/dist/cli/commands/register.d.ts +3 -0
  44. package/dist/cli/commands/register.d.ts.map +1 -0
  45. package/dist/cli/commands/register.js +48 -0
  46. package/dist/cli/commands/register.js.map +1 -0
  47. package/dist/cli/commands/restart.d.ts +3 -0
  48. package/dist/cli/commands/restart.d.ts.map +1 -0
  49. package/dist/cli/commands/restart.js +66 -0
  50. package/dist/cli/commands/restart.js.map +1 -0
  51. package/dist/cli/commands/service.d.ts +3 -0
  52. package/dist/cli/commands/service.d.ts.map +1 -0
  53. package/dist/cli/commands/service.js +194 -0
  54. package/dist/cli/commands/service.js.map +1 -0
  55. package/dist/cli/commands/setup.d.ts +3 -0
  56. package/dist/cli/commands/setup.d.ts.map +1 -0
  57. package/dist/cli/commands/setup.js +242 -0
  58. package/dist/cli/commands/setup.js.map +1 -0
  59. package/dist/cli/commands/start.d.ts +3 -0
  60. package/dist/cli/commands/start.d.ts.map +1 -0
  61. package/dist/cli/commands/start.js +125 -0
  62. package/dist/cli/commands/start.js.map +1 -0
  63. package/dist/cli/commands/status.d.ts +3 -0
  64. package/dist/cli/commands/status.d.ts.map +1 -0
  65. package/dist/cli/commands/status.js +76 -0
  66. package/dist/cli/commands/status.js.map +1 -0
  67. package/dist/cli/commands/stop.d.ts +3 -0
  68. package/dist/cli/commands/stop.d.ts.map +1 -0
  69. package/dist/cli/commands/stop.js +46 -0
  70. package/dist/cli/commands/stop.js.map +1 -0
  71. package/dist/cli/commands/subscription.d.ts +3 -0
  72. package/dist/cli/commands/subscription.d.ts.map +1 -0
  73. package/dist/cli/commands/subscription.js +342 -0
  74. package/dist/cli/commands/subscription.js.map +1 -0
  75. package/dist/cli/exit-codes.d.ts +12 -0
  76. package/dist/cli/exit-codes.d.ts.map +1 -0
  77. package/dist/cli/exit-codes.js +11 -0
  78. package/dist/cli/exit-codes.js.map +1 -0
  79. package/dist/cli/format.d.ts +8 -0
  80. package/dist/cli/format.d.ts.map +1 -0
  81. package/dist/cli/format.js +22 -0
  82. package/dist/cli/format.js.map +1 -0
  83. package/dist/cli/index.d.ts +3 -0
  84. package/dist/cli/index.d.ts.map +1 -0
  85. package/dist/cli/index.js +88 -0
  86. package/dist/cli/index.js.map +1 -0
  87. package/dist/cli/ipc-client.d.ts +20 -0
  88. package/dist/cli/ipc-client.d.ts.map +1 -0
  89. package/dist/cli/ipc-client.js +101 -0
  90. package/dist/cli/ipc-client.js.map +1 -0
  91. package/dist/cli/prompts.d.ts +5 -0
  92. package/dist/cli/prompts.d.ts.map +1 -0
  93. package/dist/cli/prompts.js +68 -0
  94. package/dist/cli/prompts.js.map +1 -0
  95. package/dist/cli/services.d.ts +18 -0
  96. package/dist/cli/services.d.ts.map +1 -0
  97. package/dist/cli/services.js +16 -0
  98. package/dist/cli/services.js.map +1 -0
  99. package/dist/core/auth.d.ts +24 -0
  100. package/dist/core/auth.d.ts.map +1 -0
  101. package/dist/core/auth.js +111 -0
  102. package/dist/core/auth.js.map +1 -0
  103. package/dist/core/backend-client.d.ts +33 -0
  104. package/dist/core/backend-client.d.ts.map +1 -0
  105. package/dist/core/backend-client.js +79 -0
  106. package/dist/core/backend-client.js.map +1 -0
  107. package/dist/core/config.d.ts +21 -0
  108. package/dist/core/config.d.ts.map +1 -0
  109. package/dist/core/config.js +98 -0
  110. package/dist/core/config.js.map +1 -0
  111. package/dist/core/events.d.ts +23 -0
  112. package/dist/core/events.d.ts.map +1 -0
  113. package/dist/core/events.js +15 -0
  114. package/dist/core/events.js.map +1 -0
  115. package/dist/core/fs-lock.d.ts +13 -0
  116. package/dist/core/fs-lock.d.ts.map +1 -0
  117. package/dist/core/fs-lock.js +52 -0
  118. package/dist/core/fs-lock.js.map +1 -0
  119. package/dist/core/jsonrpc.d.ts +55 -0
  120. package/dist/core/jsonrpc.d.ts.map +1 -0
  121. package/dist/core/jsonrpc.js +59 -0
  122. package/dist/core/jsonrpc.js.map +1 -0
  123. package/dist/core/logger.d.ts +28 -0
  124. package/dist/core/logger.d.ts.map +1 -0
  125. package/dist/core/logger.js +80 -0
  126. package/dist/core/logger.js.map +1 -0
  127. package/dist/core/model-info.d.ts +11 -0
  128. package/dist/core/model-info.d.ts.map +1 -0
  129. package/dist/core/model-info.js +137 -0
  130. package/dist/core/model-info.js.map +1 -0
  131. package/dist/core/models-fs.d.ts +6 -0
  132. package/dist/core/models-fs.d.ts.map +1 -0
  133. package/dist/core/models-fs.js +21 -0
  134. package/dist/core/models-fs.js.map +1 -0
  135. package/dist/core/orchestrator.d.ts +42 -0
  136. package/dist/core/orchestrator.d.ts.map +1 -0
  137. package/dist/core/orchestrator.js +304 -0
  138. package/dist/core/orchestrator.js.map +1 -0
  139. package/dist/core/paths.d.ts +17 -0
  140. package/dist/core/paths.d.ts.map +1 -0
  141. package/dist/core/paths.js +51 -0
  142. package/dist/core/paths.js.map +1 -0
  143. package/dist/core/redact.d.ts +3 -0
  144. package/dist/core/redact.d.ts.map +1 -0
  145. package/dist/core/redact.js +27 -0
  146. package/dist/core/redact.js.map +1 -0
  147. package/dist/core/secrets.d.ts +12 -0
  148. package/dist/core/secrets.d.ts.map +1 -0
  149. package/dist/core/secrets.js +66 -0
  150. package/dist/core/secrets.js.map +1 -0
  151. package/dist/core/shared-runner.d.ts +70 -0
  152. package/dist/core/shared-runner.d.ts.map +1 -0
  153. package/dist/core/shared-runner.js +450 -0
  154. package/dist/core/shared-runner.js.map +1 -0
  155. package/dist/core/subscription.d.ts +53 -0
  156. package/dist/core/subscription.d.ts.map +1 -0
  157. package/dist/core/subscription.js +117 -0
  158. package/dist/core/subscription.js.map +1 -0
  159. package/dist/daemon/index.d.ts +3 -0
  160. package/dist/daemon/index.d.ts.map +1 -0
  161. package/dist/daemon/index.js +22 -0
  162. package/dist/daemon/index.js.map +1 -0
  163. package/dist/daemon/ipc-server.d.ts +33 -0
  164. package/dist/daemon/ipc-server.d.ts.map +1 -0
  165. package/dist/daemon/ipc-server.js +202 -0
  166. package/dist/daemon/ipc-server.js.map +1 -0
  167. package/dist/daemon/methods.d.ts +17 -0
  168. package/dist/daemon/methods.d.ts.map +1 -0
  169. package/dist/daemon/methods.js +68 -0
  170. package/dist/daemon/methods.js.map +1 -0
  171. package/dist/daemon/pid-lock.d.ts +10 -0
  172. package/dist/daemon/pid-lock.d.ts.map +1 -0
  173. package/dist/daemon/pid-lock.js +45 -0
  174. package/dist/daemon/pid-lock.js.map +1 -0
  175. package/dist/daemon/run.d.ts +19 -0
  176. package/dist/daemon/run.d.ts.map +1 -0
  177. package/dist/daemon/run.js +182 -0
  178. package/dist/daemon/run.js.map +1 -0
  179. package/dist/shared/config-types.d.ts +27 -0
  180. package/dist/shared/config-types.d.ts.map +1 -0
  181. package/dist/shared/config-types.js +13 -0
  182. package/dist/shared/config-types.js.map +1 -0
  183. package/dist/shared/protocol.d.ts +43 -0
  184. package/dist/shared/protocol.d.ts.map +1 -0
  185. package/dist/shared/protocol.js +11 -0
  186. package/dist/shared/protocol.js.map +1 -0
  187. package/package.json +70 -0
  188. package/templates/launchd/com.peerllm.host.plist +25 -0
  189. package/templates/systemd/peerllm-host.service +17 -0
  190. package/templates/windows/install-service.ps1 +29 -0
package/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2026 Hassan Habib / BestBytes AI LLC. All rights reserved.
2
+
3
+ This package is published on npm so that PeerLLM operators can install and
4
+ run a host on their machines. Source code is currently proprietary.
5
+
6
+ You may:
7
+ - Install and run this CLI to operate a PeerLLM host.
8
+ - Inspect the published JavaScript for security or compliance purposes.
9
+
10
+ You may not, without prior written permission:
11
+ - Redistribute this package or modified copies of it.
12
+ - Use the source code in another product.
13
+ - Re-publish this package under a different name.
14
+
15
+ This LICENSE will be updated to a standard open-source license (MIT or
16
+ Apache 2.0) before the 1.0 public release. Until then, treat the source
17
+ as proprietary.
18
+
19
+ Contact: hassan@bestbytes.ai
package/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # peerllm-host-cli
2
+
3
+ Command-line PeerLLM host. Serve decentralized AI compute from a headless
4
+ machine — same protocol and economics as the desktop app, no GUI required.
5
+
6
+ > **Status:** pre-release. See `SPEC.md` for the full implementation plan
7
+ > and `RELEASING.md` for the release process.
8
+
9
+ ## Install
10
+
11
+ ```
12
+ npm i -g peerllm-host-cli
13
+ ```
14
+
15
+ Supported on Windows 10/11, macOS 13+, Debian 12+, Arch (current).
16
+ Node ≥ 20.
17
+
18
+ ## Quickstart
19
+
20
+ ```
21
+ peerllm-host setup # interactive: login + agreement + host + subscription
22
+ peerllm-host start # serves traffic in the foreground
23
+ peerllm-host status
24
+ peerllm-host stop
25
+ ```
26
+
27
+ For headless servers:
28
+
29
+ ```
30
+ peerllm-host setup \
31
+ --email you@example.com \
32
+ --password-stdin \
33
+ --accept-agreement \
34
+ --host-create \
35
+ --yes < /run/secrets/peerllm_password
36
+
37
+ peerllm-host service install # systemd / launchd / Scheduled Task
38
+ peerllm-host start --detach
39
+ ```
40
+
41
+ See `peerllm-host help` and `peerllm-host help <command>` for the full
42
+ command reference.
43
+
44
+ ## Verify your install
45
+
46
+ ```
47
+ peerllm-host doctor # ✓/⚠/✗ for every preflight check
48
+ ```
49
+
50
+ ## Repo layout
51
+
52
+ ```
53
+ src/
54
+ cli/ control CLI (peerllm-host)
55
+ daemon/ long-running daemon (peerllm-hostd)
56
+ core/ framework-agnostic business logic (auth, orchestrator,
57
+ LLM runner, subscription, config, paths, …)
58
+ shared/ types shared between CLI + daemon
59
+ templates/ systemd / launchd / Windows service templates
60
+ scripts/ cross-platform smoke-test scripts
61
+ .github/ CI + publish workflows
62
+ SPEC.md product spec + release plan
63
+ RELEASING.md how to cut a release
64
+ ```
65
+
66
+ ## Contributing
67
+
68
+ ```
69
+ npm install
70
+ npm run typecheck
71
+ npm run test
72
+ npm run lint
73
+ npm run build
74
+ bash scripts/smoke-test.sh # full pack + global install + run loop
75
+ ```
76
+
77
+ CI runs the same matrix you see on GitHub Actions (Ubuntu / macOS Intel
78
+ + Apple Silicon / Windows / Arch container) × Node 20 + Node 22 before
79
+ any merge.
80
+
81
+ ## License
82
+
83
+ UNLICENSED (private). Will switch to MIT/Apache before the public release.
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function makeAgreementCommand(): Command;
3
+ //# sourceMappingURL=agreement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agreement.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/agreement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwKpC,wBAAgB,oBAAoB,IAAI,OAAO,CAK9C"}
@@ -0,0 +1,151 @@
1
+ import { Command } from "commander";
2
+ import { NotAuthenticatedError } from "../../core/backend-client.js";
3
+ import { EXIT } from "../exit-codes.js";
4
+ import { printError } from "../format.js";
5
+ import { promptYesNo } from "../prompts.js";
6
+ import { buildClientServices } from "../services.js";
7
+ function stripHtml(html) {
8
+ // Normalize whitespace inside tag content first so the structural
9
+ // replacements below produce clean blank lines.
10
+ let text = html
11
+ .replace(/\r\n/g, "\n")
12
+ .replace(/[ \t]*\n[ \t]*/g, " ")
13
+ .replace(/\s{2,}/g, " ");
14
+ text = text
15
+ .replace(/<br\s*\/?>/gi, "\n")
16
+ .replace(/<\/p>/gi, "\n\n")
17
+ .replace(/<\/?h[1-6][^>]*>/gi, "\n\n")
18
+ .replace(/<li[^>]*>/gi, " • ")
19
+ .replace(/<\/li>/gi, "\n")
20
+ .replace(/<\/(ul|ol)>/gi, "\n")
21
+ .replace(/<[^>]+>/g, "")
22
+ .replace(/&nbsp;/g, " ")
23
+ .replace(/&amp;/g, "&")
24
+ .replace(/&quot;/g, '"')
25
+ .replace(/&#39;/g, "'")
26
+ .replace(/&lt;/g, "<")
27
+ .replace(/&gt;/g, ">");
28
+ return text
29
+ .split("\n")
30
+ .map((line) => line.trim())
31
+ .join("\n")
32
+ .replace(/\n{3,}/g, "\n\n")
33
+ .trim();
34
+ }
35
+ function makeShow() {
36
+ return new Command("show")
37
+ .description("Print the latest host agreement")
38
+ .option("--config-dir <path>", "override config directory")
39
+ .option("--json", "machine-readable JSON output")
40
+ .action(async (opts) => {
41
+ const services = buildClientServices({ configDir: opts.configDir });
42
+ try {
43
+ const agreement = await services.backend.request({
44
+ method: "GET",
45
+ path: "/host-agreements/latest",
46
+ });
47
+ if (opts.json) {
48
+ process.stdout.write(JSON.stringify(agreement, null, 2) + "\n");
49
+ }
50
+ else {
51
+ process.stdout.write(`${agreement.title ?? "PeerLLM Host Agreement"}\n`);
52
+ process.stdout.write(`Version: ${agreement.version ?? "?"}\n`);
53
+ process.stdout.write(`Id: ${agreement.id}\n`);
54
+ if (agreement.publishedAt) {
55
+ process.stdout.write(`Published: ${agreement.publishedAt}\n`);
56
+ }
57
+ if (agreement.contentHtml) {
58
+ process.stdout.write("\n");
59
+ process.stdout.write(stripHtml(agreement.contentHtml) + "\n");
60
+ }
61
+ }
62
+ process.exit(EXIT.ok);
63
+ }
64
+ catch (err) {
65
+ const e = err;
66
+ printError(e.message || "failed to fetch agreement", { json: opts.json });
67
+ process.exit(EXIT.runtimeError);
68
+ }
69
+ });
70
+ }
71
+ function makeAccept() {
72
+ return new Command("accept")
73
+ .description("Accept the latest host agreement")
74
+ .option("--yes", "skip the interactive confirmation prompt")
75
+ .option("--config-dir <path>", "override config directory")
76
+ .option("--json", "machine-readable JSON output")
77
+ .action(async (opts) => {
78
+ const services = buildClientServices({ configDir: opts.configDir });
79
+ let agreement;
80
+ try {
81
+ agreement = await services.backend.request({
82
+ method: "GET",
83
+ path: "/host-agreements/latest",
84
+ });
85
+ }
86
+ catch (err) {
87
+ printError(err.message, { json: opts.json });
88
+ process.exit(EXIT.runtimeError);
89
+ }
90
+ if (!opts.yes) {
91
+ process.stdout.write(`Agreement v${agreement.version ?? "?"} (${agreement.id})\n`);
92
+ process.stdout.write(`Run 'peerllm-host agreement show' to see the full text.\n`);
93
+ const confirmed = await promptYesNo("Do you accept the agreement?", false);
94
+ if (!confirmed) {
95
+ printError("agreement not accepted", { json: opts.json });
96
+ process.exit(EXIT.userError);
97
+ }
98
+ }
99
+ const accessToken = await services.auth.getValidAccessToken();
100
+ if (!accessToken) {
101
+ printError("not authenticated", {
102
+ json: opts.json,
103
+ hint: "Log in first: peerllm-host login",
104
+ });
105
+ process.exit(EXIT.notAuthenticated);
106
+ }
107
+ try {
108
+ await services.backend.request({
109
+ method: "POST",
110
+ path: "/host-agreements/accept",
111
+ body: { agreementId: agreement.id, acceptedVia: "cli" },
112
+ bearerToken: accessToken,
113
+ });
114
+ await services.config.update((c) => ({
115
+ ...c,
116
+ agreementAccepted: true,
117
+ agreementId: agreement.id,
118
+ agreementVersion: agreement.version,
119
+ }));
120
+ if (opts.json) {
121
+ process.stdout.write(JSON.stringify({
122
+ accepted: true,
123
+ agreementId: agreement.id,
124
+ version: agreement.version,
125
+ }) + "\n");
126
+ }
127
+ else {
128
+ process.stdout.write(` accepted v${agreement.version ?? "?"}\n`);
129
+ }
130
+ process.exit(EXIT.ok);
131
+ }
132
+ catch (err) {
133
+ if (err instanceof NotAuthenticatedError) {
134
+ printError("not authenticated", {
135
+ json: opts.json,
136
+ hint: "Log in first: peerllm-host login",
137
+ });
138
+ process.exit(EXIT.notAuthenticated);
139
+ }
140
+ printError(err.message, { json: opts.json });
141
+ process.exit(EXIT.runtimeError);
142
+ }
143
+ });
144
+ }
145
+ export function makeAgreementCommand() {
146
+ return new Command("agreement")
147
+ .description("View and accept the host agreement")
148
+ .addCommand(makeShow())
149
+ .addCommand(makeAccept());
150
+ }
151
+ //# sourceMappingURL=agreement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agreement.js","sourceRoot":"","sources":["../../../src/cli/commands/agreement.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function makeConfigCommand(): Command;
3
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuKpC,wBAAgB,iBAAiB,IAAI,OAAO,CAO3C"}
@@ -0,0 +1,163 @@
1
+ import { Command } from "commander";
2
+ import { redact } from "../../core/redact.js";
3
+ import { METHOD } from "../../shared/protocol.js";
4
+ import { EXIT } from "../exit-codes.js";
5
+ import { printError } from "../format.js";
6
+ import { DaemonUnreachableError, IpcClient } from "../ipc-client.js";
7
+ import { buildClientServices } from "../services.js";
8
+ const WRITABLE_KEYS = [
9
+ "hostName",
10
+ "orchestratorUrl",
11
+ "selectedGpuIndex",
12
+ "llmLocation",
13
+ "computeMode",
14
+ "gpuLayers",
15
+ "restServerPort",
16
+ "restServerEnabled",
17
+ "networkHostUrl",
18
+ "schedulingEnabled",
19
+ "scheduleStartTime",
20
+ "scheduleEndTime",
21
+ "manualOffline",
22
+ ];
23
+ function coerce(key, raw) {
24
+ switch (key) {
25
+ case "selectedGpuIndex":
26
+ case "gpuLayers":
27
+ case "restServerPort":
28
+ return parseIntOrThrow(key, raw);
29
+ case "restServerEnabled":
30
+ case "schedulingEnabled":
31
+ case "manualOffline":
32
+ return parseBool(key, raw);
33
+ case "computeMode": {
34
+ const allowed = ["gpu", "cpu", "dynamic", "custom"];
35
+ if (!allowed.includes(raw)) {
36
+ throw new Error(`computeMode must be one of: ${allowed.join(", ")}`);
37
+ }
38
+ return raw;
39
+ }
40
+ default:
41
+ return raw;
42
+ }
43
+ }
44
+ function parseIntOrThrow(key, raw) {
45
+ const n = Number.parseInt(raw, 10);
46
+ if (!Number.isFinite(n))
47
+ throw new Error(`${key} must be an integer`);
48
+ return n;
49
+ }
50
+ function parseBool(key, raw) {
51
+ const v = raw.toLowerCase();
52
+ if (v === "true" || v === "1" || v === "yes" || v === "on")
53
+ return true;
54
+ if (v === "false" || v === "0" || v === "no" || v === "off")
55
+ return false;
56
+ throw new Error(`${key} must be true/false`);
57
+ }
58
+ function makeShow() {
59
+ return new Command("show")
60
+ .description("Print the current config (secrets redacted by default)")
61
+ .option("--include-secrets", "do not redact token-shaped fields (use with care)")
62
+ .option("--config-dir <path>", "override config directory")
63
+ .option("--json", "machine-readable JSON output")
64
+ .action(async (opts) => {
65
+ const services = buildClientServices({ configDir: opts.configDir });
66
+ const cfg = await services.config.load();
67
+ const payload = opts.includeSecrets ? cfg : redact(cfg);
68
+ if (opts.json) {
69
+ process.stdout.write(JSON.stringify(payload, null, 2) + "\n");
70
+ }
71
+ else {
72
+ for (const [k, v] of Object.entries(payload)) {
73
+ const formatted = typeof v === "string" ? v : JSON.stringify(v);
74
+ process.stdout.write(`${k.padEnd(20)} ${formatted}\n`);
75
+ }
76
+ }
77
+ process.exit(EXIT.ok);
78
+ });
79
+ }
80
+ function makeGet() {
81
+ return new Command("get")
82
+ .description("Print a single config field")
83
+ .argument("<key>")
84
+ .option("--config-dir <path>", "override config directory")
85
+ .action(async (key, opts) => {
86
+ const services = buildClientServices({ configDir: opts.configDir });
87
+ const cfg = await services.config.load();
88
+ const value = cfg[key];
89
+ if (value === undefined) {
90
+ printError(`config key not set: ${key}`);
91
+ process.exit(EXIT.userError);
92
+ }
93
+ process.stdout.write(typeof value === "string" ? value + "\n" : JSON.stringify(value) + "\n");
94
+ process.exit(EXIT.ok);
95
+ });
96
+ }
97
+ function makeSet() {
98
+ return new Command("set")
99
+ .description("Set a config field")
100
+ .argument("<key>")
101
+ .argument("<value>")
102
+ .option("--config-dir <path>", "override config directory")
103
+ .option("--json", "machine-readable JSON output")
104
+ .action(async (key, value, opts) => {
105
+ if (!WRITABLE_KEYS.includes(key)) {
106
+ printError(`config key not writable: ${key}`, {
107
+ json: opts.json,
108
+ hint: `Writable keys: ${WRITABLE_KEYS.join(", ")}`,
109
+ });
110
+ process.exit(EXIT.userError);
111
+ }
112
+ const services = buildClientServices({ configDir: opts.configDir });
113
+ let coerced;
114
+ try {
115
+ coerced = coerce(key, value);
116
+ }
117
+ catch (err) {
118
+ printError(err.message, { json: opts.json });
119
+ process.exit(EXIT.userError);
120
+ }
121
+ await services.config.update((c) => ({ ...c, [key]: coerced }));
122
+ // Notify daemon if it's up so it picks up the new value.
123
+ const client = new IpcClient(services.paths.ipcEndpoint);
124
+ try {
125
+ await client.connect(500);
126
+ await client.call(METHOD.configReload);
127
+ }
128
+ catch (err) {
129
+ if (!(err instanceof DaemonUnreachableError)) {
130
+ // Non-fatal: write succeeded; daemon notification failed.
131
+ }
132
+ }
133
+ finally {
134
+ client.close();
135
+ }
136
+ if (opts.json) {
137
+ process.stdout.write(JSON.stringify({ set: true, key, value: coerced }) + "\n");
138
+ }
139
+ else {
140
+ process.stdout.write(` ${key} = ${JSON.stringify(coerced)}\n`);
141
+ }
142
+ process.exit(EXIT.ok);
143
+ });
144
+ }
145
+ function makePath() {
146
+ return new Command("path")
147
+ .description("Print the config file path")
148
+ .option("--config-dir <path>", "override config directory")
149
+ .action(async (opts) => {
150
+ const services = buildClientServices({ configDir: opts.configDir });
151
+ process.stdout.write(services.paths.configFile + "\n");
152
+ process.exit(EXIT.ok);
153
+ });
154
+ }
155
+ export function makeConfigCommand() {
156
+ return new Command("config")
157
+ .description("Inspect and modify config")
158
+ .addCommand(makeShow())
159
+ .addCommand(makeGet())
160
+ .addCommand(makeSet())
161
+ .addCommand(makePath());
162
+ }
163
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/cli/commands/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function makeDiagnosticsCommand(): Command;
3
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/diagnostics.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmFpC,wBAAgB,sBAAsB,IAAI,OAAO,CAqEhD"}
@@ -0,0 +1,131 @@
1
+ import { createWriteStream, existsSync, readFileSync, readdirSync, statSync, } from "node:fs";
2
+ import { mkdir } from "node:fs/promises";
3
+ import { arch as osArch, homedir, platform as osPlatform, release } from "node:os";
4
+ import { dirname, join } from "node:path";
5
+ import { createGzip } from "node:zlib";
6
+ import { Command } from "commander";
7
+ import { redact, redactString } from "../../core/redact.js";
8
+ import { EXIT } from "../exit-codes.js";
9
+ import { printError } from "../format.js";
10
+ import { buildClientServices } from "../services.js";
11
+ function padOctal(value, length) {
12
+ return value.toString(8).padStart(length - 1, "0") + "\0";
13
+ }
14
+ function writeTarHeader(entry) {
15
+ // ustar tar header, 512 bytes. Sufficient for files <8 GiB and ASCII names.
16
+ const buf = Buffer.alloc(512);
17
+ buf.write(entry.name.slice(0, 100), 0, 100, "utf8");
18
+ buf.write(padOctal(0o600, 8), 100, "ascii");
19
+ buf.write(padOctal(0, 8), 108, "ascii");
20
+ buf.write(padOctal(0, 8), 116, "ascii");
21
+ buf.write(padOctal(entry.size, 12), 124, "ascii");
22
+ buf.write(padOctal(Math.floor(Date.now() / 1000), 12), 136, "ascii");
23
+ buf.write(" ", 148, 8, "ascii"); // checksum placeholder
24
+ buf.write("0", 156, "ascii"); // type: regular file
25
+ buf.write("ustar\0", 257, 6, "ascii");
26
+ buf.write("00", 263, 2, "ascii");
27
+ let checksum = 0;
28
+ for (let i = 0; i < 512; i++)
29
+ checksum += buf[i] ?? 0;
30
+ buf.write(checksum.toString(8).padStart(6, "0") + "\0 ", 148, 8, "ascii");
31
+ return buf;
32
+ }
33
+ function writeTarEnd() {
34
+ return Buffer.alloc(1024);
35
+ }
36
+ async function writeTarball(outPath, entries) {
37
+ await mkdir(dirname(outPath), { recursive: true });
38
+ return new Promise((resolve, reject) => {
39
+ const out = createWriteStream(outPath);
40
+ const gzip = createGzip();
41
+ gzip.pipe(out);
42
+ for (const entry of entries) {
43
+ gzip.write(writeTarHeader(entry));
44
+ const body = Buffer.isBuffer(entry.content)
45
+ ? entry.content
46
+ : Buffer.from(entry.content, "utf8");
47
+ gzip.write(body);
48
+ const pad = 512 - (body.length % 512);
49
+ if (pad !== 512)
50
+ gzip.write(Buffer.alloc(pad));
51
+ }
52
+ gzip.end(writeTarEnd());
53
+ out.on("finish", () => resolve());
54
+ out.on("error", reject);
55
+ gzip.on("error", reject);
56
+ });
57
+ }
58
+ function recentLogs(logsDir, days) {
59
+ if (!existsSync(logsDir))
60
+ return [];
61
+ const cutoff = Date.now() - days * 24 * 60 * 60 * 1000;
62
+ const entries = [];
63
+ for (const fname of readdirSync(logsDir)) {
64
+ const full = join(logsDir, fname);
65
+ const stat = statSync(full);
66
+ if (stat.mtimeMs < cutoff)
67
+ continue;
68
+ const raw = readFileSync(full, "utf8");
69
+ entries.push({
70
+ name: `logs/${fname}`,
71
+ content: redactString(raw),
72
+ size: Buffer.byteLength(redactString(raw), "utf8"),
73
+ });
74
+ }
75
+ return entries;
76
+ }
77
+ export function makeDiagnosticsCommand() {
78
+ return new Command("diagnostics")
79
+ .description("Local-only diagnostic tools")
80
+ .addCommand(new Command("collect")
81
+ .description("Build a redacted local support bundle")
82
+ .option("--out <path>", "output tarball path")
83
+ .option("--days <n>", "include logs from the last N days", "7")
84
+ .option("--config-dir <path>", "override config directory")
85
+ .action(async (opts) => {
86
+ const services = buildClientServices({ configDir: opts.configDir });
87
+ const days = Number.parseInt(opts.days, 10);
88
+ if (!Number.isFinite(days) || days < 0) {
89
+ printError("--days must be a non-negative integer");
90
+ process.exit(EXIT.userError);
91
+ }
92
+ const cfg = await services.config.load();
93
+ const redactedConfig = JSON.stringify(redact(cfg), null, 2);
94
+ const platformInfo = JSON.stringify({
95
+ platform: osPlatform(),
96
+ arch: osArch(),
97
+ osRelease: release(),
98
+ node: process.versions.node,
99
+ cli: "0.1.0",
100
+ generatedAt: new Date().toISOString(),
101
+ }, null, 2);
102
+ const entries = [
103
+ {
104
+ name: "platform.json",
105
+ content: platformInfo,
106
+ size: Buffer.byteLength(platformInfo, "utf8"),
107
+ },
108
+ {
109
+ name: "config-redacted.json",
110
+ content: redactedConfig,
111
+ size: Buffer.byteLength(redactedConfig, "utf8"),
112
+ },
113
+ ...recentLogs(services.paths.logsDir, days),
114
+ ];
115
+ const stamp = new Date().toISOString().replace(/[:.]/g, "-").replace("T", "_");
116
+ const out = opts.out ?? join(homedir(), "PeerLLM", `peerllm-diagnostics-${stamp}.tar.gz`);
117
+ try {
118
+ await writeTarball(out, entries);
119
+ }
120
+ catch (err) {
121
+ printError(err.message);
122
+ process.exit(EXIT.runtimeError);
123
+ }
124
+ const totalBytes = entries.reduce((s, e) => s + e.size, 0);
125
+ process.stdout.write(` bundled ${entries.length} files (${totalBytes} bytes)\n`);
126
+ process.stdout.write(` ${out}\n`);
127
+ process.stdout.write(` redacted: refresh tokens, passwords, API keys, authorization headers\n`);
128
+ process.exit(EXIT.ok);
129
+ }));
130
+ }
131
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../../src/cli/commands/diagnostics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function makeDoctorCommand(): Command;
3
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+UpC,wBAAgB,iBAAiB,IAAI,OAAO,CAsC3C"}