@bytetrue/byspace 0.14.5 → 0.15.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 (59) hide show
  1. package/dist/commands/daemon/index.js +16 -0
  2. package/dist/commands/daemon/install-service.d.ts +15 -0
  3. package/dist/commands/daemon/install-service.js +69 -0
  4. package/dist/commands/daemon/local-daemon.d.ts +1 -0
  5. package/dist/commands/daemon/local-daemon.js +1 -1
  6. package/dist/commands/daemon/service/backend.d.ts +16 -0
  7. package/dist/commands/daemon/service/backend.js +50 -0
  8. package/dist/commands/daemon/service/launchd.d.ts +15 -0
  9. package/dist/commands/daemon/service/launchd.js +101 -0
  10. package/dist/commands/daemon/service/service-spec.d.ts +54 -0
  11. package/dist/commands/daemon/service/service-spec.js +95 -0
  12. package/dist/commands/daemon/service/service-status.d.ts +28 -0
  13. package/dist/commands/daemon/service/service-status.js +32 -0
  14. package/dist/commands/daemon/service/systemd.d.ts +22 -0
  15. package/dist/commands/daemon/service/systemd.js +90 -0
  16. package/dist/commands/daemon/service/windows-task.d.ts +12 -0
  17. package/dist/commands/daemon/service/windows-task.js +75 -0
  18. package/dist/commands/daemon/service-status.d.ts +13 -0
  19. package/dist/commands/daemon/service-status.js +30 -0
  20. package/dist/commands/daemon/uninstall-service.d.ts +11 -0
  21. package/dist/commands/daemon/uninstall-service.js +53 -0
  22. package/node_modules/@bytetrue/client/package.json +3 -3
  23. package/node_modules/@bytetrue/highlight/package.json +1 -1
  24. package/node_modules/@bytetrue/protocol/dist/generated/validation/ws-outbound.aot.js +10901 -10861
  25. package/node_modules/@bytetrue/protocol/dist/messages.d.ts +231 -92
  26. package/node_modules/@bytetrue/protocol/dist/messages.js +29 -0
  27. package/node_modules/@bytetrue/protocol/dist/validation/ws-outbound-schema-metadata.d.ts +44 -22
  28. package/node_modules/@bytetrue/protocol/package.json +1 -1
  29. package/node_modules/@bytetrue/relay/package.json +1 -1
  30. package/node_modules/@bytetrue/server/dist/server/server/daemon-config-store.d.ts +11 -0
  31. package/node_modules/@bytetrue/server/dist/server/server/daemon-config-store.js +71 -1
  32. package/node_modules/@bytetrue/server/dist/server/server/session/daemon/daemon-service-install.d.ts +25 -0
  33. package/node_modules/@bytetrue/server/dist/server/server/session/daemon/daemon-service-install.js +182 -0
  34. package/node_modules/@bytetrue/server/dist/server/server/session/daemon/daemon-service-manager.d.ts +21 -0
  35. package/node_modules/@bytetrue/server/dist/server/server/session/daemon/daemon-service-manager.js +154 -0
  36. package/node_modules/@bytetrue/server/dist/server/server/websocket-server.js +2 -0
  37. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/{index-a02b4240e2d16a2b83c35c3942514c67.js → index-1e1ff7510a612ab12641e5e07e0a7208.js} +62 -61
  38. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/index-1e1ff7510a612ab12641e5e07e0a7208.js.br +0 -0
  39. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/index-1e1ff7510a612ab12641e5e07e0a7208.js.gz +0 -0
  40. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/{indexeddb-attachment-store-d61d5dd974e90216cec99e62c343ffc7.js → indexeddb-attachment-store-1e67472b9640c869a55ff6915d1f7afb.js} +1 -1
  41. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/{indexeddb-attachment-store-d61d5dd974e90216cec99e62c343ffc7.js.br → indexeddb-attachment-store-1e67472b9640c869a55ff6915d1f7afb.js.br} +0 -0
  42. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-1e67472b9640c869a55ff6915d1f7afb.js.gz +0 -0
  43. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/{native-file-attachment-store-df0c0ebe8d233a5a74eddb59a110f00b.js → native-file-attachment-store-63659fda781a1cc594f259795f1cc29f.js} +3 -3
  44. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/{native-file-attachment-store-df0c0ebe8d233a5a74eddb59a110f00b.js.br → native-file-attachment-store-63659fda781a1cc594f259795f1cc29f.js.br} +0 -0
  45. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-63659fda781a1cc594f259795f1cc29f.js.gz +0 -0
  46. package/node_modules/@bytetrue/server/dist/server/web-ui/index.html +1 -1
  47. package/node_modules/@bytetrue/server/dist/server/web-ui/index.html.br +0 -0
  48. package/node_modules/@bytetrue/server/dist/server/web-ui/index.html.gz +0 -0
  49. package/node_modules/@bytetrue/server/dist/src/server/daemon-config-store.js +71 -1
  50. package/node_modules/@bytetrue/server/dist/src/server/session/daemon/daemon-service-install.js +182 -0
  51. package/node_modules/@bytetrue/server/dist/src/server/session/daemon/daemon-service-manager.js +154 -0
  52. package/node_modules/@bytetrue/server/dist/src/server/session/daemon/install-origin.js +64 -0
  53. package/node_modules/@bytetrue/server/dist/src/server/session/daemon/npm-global-cli.js +98 -0
  54. package/node_modules/@bytetrue/server/package.json +15 -5
  55. package/package.json +7 -7
  56. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/index-a02b4240e2d16a2b83c35c3942514c67.js.br +0 -0
  57. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/index-a02b4240e2d16a2b83c35c3942514c67.js.gz +0 -0
  58. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-d61d5dd974e90216cec99e62c343ffc7.js.gz +0 -0
  59. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-df0c0ebe8d233a5a74eddb59a110f00b.js.gz +0 -0
@@ -0,0 +1,154 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { BYSPACE_CLI_PACKAGE } from "./npm-global-cli.js";
4
+ import path from "node:path";
5
+ import { validateDaemonInstallOrigin, daemonInstallOriginRuntime } from "./install-origin.js";
6
+ /**
7
+ * Daemon-side OS service management (issue 043). The daemon manages its own service
8
+ * registration because install requires the daemon's install-origin context — the
9
+ * npm-global verification and the runner entry resolution live in this process.
10
+ *
11
+ * KeepAlive/Restart is deliberately not "always": `byspace daemon stop` must stay a
12
+ * real stop. The supervisor's own crash-restart handles worker failures.
13
+ */
14
+ export const DAEMON_SERVICE_LABEL = "cc.cd.byspace.daemon";
15
+ function launchdProbe(home) {
16
+ const plistPath = path.join(home, "Library", "LaunchAgents", `${DAEMON_SERVICE_LABEL}.plist`);
17
+ return {
18
+ definitionExists: () => existsSync(plistPath),
19
+ servicePid: () => {
20
+ try {
21
+ const uid = process.getuid?.();
22
+ if (uid === undefined)
23
+ return null;
24
+ const output = execFileSync("launchctl", ["print", `gui/${uid}/${DAEMON_SERVICE_LABEL}`], {
25
+ encoding: "utf8",
26
+ timeout: 10000,
27
+ });
28
+ const match = output.match(/^\s*pid\s*=\s*(\d+)/m);
29
+ return match ? Number(match[1]) : null;
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ },
35
+ viewFlags: () => ({}),
36
+ };
37
+ }
38
+ function systemdProbe() {
39
+ const configHome = process.env.XDG_CONFIG_HOME ?? path.join(process.env.HOME ?? "", ".config");
40
+ const unitPath = path.join(configHome, "systemd", "user", `${DAEMON_SERVICE_LABEL}.service`);
41
+ return {
42
+ definitionExists: () => existsSync(unitPath),
43
+ servicePid: () => {
44
+ try {
45
+ const output = execFileSync("systemctl", ["--user", "show", `${DAEMON_SERVICE_LABEL}.service`, "--property", "MainPID"], { encoding: "utf8", timeout: 10000 });
46
+ const match = output.match(/^MainPID=(\d+)$/m);
47
+ const pid = match ? Number(match[1]) : 0;
48
+ return pid > 0 ? pid : null;
49
+ }
50
+ catch {
51
+ return null;
52
+ }
53
+ },
54
+ viewFlags: () => {
55
+ try {
56
+ const output = execFileSync("loginctl", ["show-user", process.env.USER ?? "", "--property", "Linger"], { encoding: "utf8", timeout: 10000 });
57
+ return { linger: /Linger=yes/.test(output) };
58
+ }
59
+ catch {
60
+ return {};
61
+ }
62
+ },
63
+ };
64
+ }
65
+ function windowsProbe() {
66
+ return {
67
+ definitionExists: () => {
68
+ try {
69
+ const output = execFileSync("powershell.exe", [
70
+ "-NoProfile",
71
+ "-NonInteractive",
72
+ "-Command",
73
+ `(Get-ScheduledTask -TaskPath '\\BySpace\\' -TaskName '${DAEMON_SERVICE_LABEL}' -ErrorAction SilentlyContinue) -ne $null`,
74
+ ], { encoding: "utf8", timeout: 15000 });
75
+ return output.trim() === "True";
76
+ }
77
+ catch {
78
+ return false;
79
+ }
80
+ },
81
+ servicePid: () => null,
82
+ viewFlags: () => ({}),
83
+ };
84
+ }
85
+ function probeForPlatform() {
86
+ switch (process.platform) {
87
+ case "darwin":
88
+ return launchdProbe(resolveBySpaceHomeForService());
89
+ case "linux":
90
+ return systemdProbe();
91
+ case "win32":
92
+ return windowsProbe();
93
+ default:
94
+ return null;
95
+ }
96
+ }
97
+ function resolveBySpaceHomeForService() {
98
+ return process.env.BYSPACE_HOME ?? path.join(process.env.HOME ?? "", ".byspace");
99
+ }
100
+ /** Guard: only a daemon from the published npm global install may self-register. */
101
+ export function validateServiceOriginSync() {
102
+ if (existsSync("/.dockerenv") || existsSync("/run/.containerenv")) {
103
+ return "Registering a service is not supported inside Docker. Use the container runtime's restart policy instead.";
104
+ }
105
+ // The npm -g listing is the authoritative origin: it proves the published install
106
+ // exists on this host. validateDaemonInstallOrigin then checks that THIS daemon
107
+ // process actually runs from it — a dev checkout parses fine but fails the
108
+ // package-root containment check, which is exactly the guard that matters here.
109
+ try {
110
+ const npmPrefix = execFileSync("npm", ["prefix", "-g"], {
111
+ encoding: "utf8",
112
+ timeout: 15000,
113
+ }).trim();
114
+ const packagePath = path.join(npmPrefix, "lib", "node_modules", "@bytetrue", "byspace");
115
+ const pkgJsonPath = path.join(packagePath, "package.json");
116
+ if (!existsSync(pkgJsonPath)) {
117
+ return `${BYSPACE_CLI_PACKAGE} is not installed with npm -g on this host`;
118
+ }
119
+ const version = JSON.parse(readFileSync(pkgJsonPath, "utf8")).version ?? "";
120
+ const install = {
121
+ version,
122
+ packagePath,
123
+ globalRootPath: npmPrefix,
124
+ isLinked: false,
125
+ };
126
+ return validateDaemonInstallOrigin(install, process.env.npm_package_version ?? version, daemonInstallOriginRuntime);
127
+ }
128
+ catch (error) {
129
+ return error instanceof Error ? error.message : String(error);
130
+ }
131
+ }
132
+ /** Query the current service view. Never caches: each call re-probes the manager. */
133
+ export function queryDaemonServiceView() {
134
+ const probe = probeForPlatform();
135
+ if (!probe) {
136
+ return { state: "unknown", label: DAEMON_SERVICE_LABEL };
137
+ }
138
+ if (!probe.definitionExists()) {
139
+ return { state: "not-installed", label: DAEMON_SERVICE_LABEL, ...probe.viewFlags() };
140
+ }
141
+ const servicePid = probe.servicePid();
142
+ if (servicePid === null) {
143
+ return { state: "installed-stopped", label: DAEMON_SERVICE_LABEL, ...probe.viewFlags() };
144
+ }
145
+ if (servicePid === process.pid) {
146
+ return { state: "managed-by-service", label: DAEMON_SERVICE_LABEL, ...probe.viewFlags() };
147
+ }
148
+ return {
149
+ state: "installed-running-not-this-process",
150
+ label: DAEMON_SERVICE_LABEL,
151
+ ...probe.viewFlags(),
152
+ };
153
+ }
154
+ //# sourceMappingURL=daemon-service-manager.js.map
@@ -1170,6 +1170,8 @@ export class DaemonWebSocketServer {
1170
1170
  agentConfigApply: true,
1171
1171
  // COMPAT(daemonNetworkConfig): added in v0.14.3, remove gate after 2027-07-14.
1172
1172
  daemonNetworkConfig: true,
1173
+ // COMPAT(daemonServiceInstall): added in v0.14.7, remove gate after 2027-09-20.
1174
+ daemonServiceInstall: true,
1173
1175
  },
1174
1176
  };
1175
1177
  }