@monotykamary/localterm 0.0.15

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 (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +66 -0
  3. package/bin/localterm.mjs +2 -0
  4. package/dist/commands/restart.d.ts +7 -0
  5. package/dist/commands/restart.d.ts.map +1 -0
  6. package/dist/commands/restart.js +43 -0
  7. package/dist/commands/restart.js.map +1 -0
  8. package/dist/commands/start.d.ts +9 -0
  9. package/dist/commands/start.d.ts.map +1 -0
  10. package/dist/commands/start.js +168 -0
  11. package/dist/commands/start.js.map +1 -0
  12. package/dist/commands/status.d.ts +2 -0
  13. package/dist/commands/status.d.ts.map +1 -0
  14. package/dist/commands/status.js +34 -0
  15. package/dist/commands/status.js.map +1 -0
  16. package/dist/commands/stop.d.ts +2 -0
  17. package/dist/commands/stop.d.ts.map +1 -0
  18. package/dist/commands/stop.js +48 -0
  19. package/dist/commands/stop.js.map +1 -0
  20. package/dist/constants.d.ts +26 -0
  21. package/dist/constants.d.ts.map +1 -0
  22. package/dist/constants.js +26 -0
  23. package/dist/constants.js.map +1 -0
  24. package/dist/errors.d.ts +101 -0
  25. package/dist/errors.d.ts.map +1 -0
  26. package/dist/errors.js +164 -0
  27. package/dist/errors.js.map +1 -0
  28. package/dist/index.d.ts +2 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +59 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/paths.d.ts +5 -0
  33. package/dist/paths.d.ts.map +1 -0
  34. package/dist/paths.js +7 -0
  35. package/dist/paths.js.map +1 -0
  36. package/dist/state.d.ts +8 -0
  37. package/dist/state.d.ts.map +1 -0
  38. package/dist/state.js +58 -0
  39. package/dist/state.js.map +1 -0
  40. package/dist/utils/build-daemon-args.d.ts +7 -0
  41. package/dist/utils/build-daemon-args.d.ts.map +1 -0
  42. package/dist/utils/build-daemon-args.js +7 -0
  43. package/dist/utils/build-daemon-args.js.map +1 -0
  44. package/dist/utils/cli-entry.d.ts +2 -0
  45. package/dist/utils/cli-entry.d.ts.map +1 -0
  46. package/dist/utils/cli-entry.js +5 -0
  47. package/dist/utils/cli-entry.js.map +1 -0
  48. package/dist/utils/parse-port-option.d.ts +2 -0
  49. package/dist/utils/parse-port-option.d.ts.map +1 -0
  50. package/dist/utils/parse-port-option.js +14 -0
  51. package/dist/utils/parse-port-option.js.map +1 -0
  52. package/dist/utils/poll-for-daemon-ready.d.ts +20 -0
  53. package/dist/utils/poll-for-daemon-ready.d.ts.map +1 -0
  54. package/dist/utils/poll-for-daemon-ready.js +20 -0
  55. package/dist/utils/poll-for-daemon-ready.js.map +1 -0
  56. package/dist/utils/read-package-version.d.ts +2 -0
  57. package/dist/utils/read-package-version.d.ts.map +1 -0
  58. package/dist/utils/read-package-version.js +12 -0
  59. package/dist/utils/read-package-version.js.map +1 -0
  60. package/dist/utils/report-cli-error.d.ts +3 -0
  61. package/dist/utils/report-cli-error.d.ts.map +1 -0
  62. package/dist/utils/report-cli-error.js +19 -0
  63. package/dist/utils/report-cli-error.js.map +1 -0
  64. package/dist/utils/run-start-preflight.d.ts +3 -0
  65. package/dist/utils/run-start-preflight.d.ts.map +1 -0
  66. package/dist/utils/run-start-preflight.js +16 -0
  67. package/dist/utils/run-start-preflight.js.map +1 -0
  68. package/dist/utils/sleep.d.ts +2 -0
  69. package/dist/utils/sleep.d.ts.map +1 -0
  70. package/dist/utils/sleep.js +2 -0
  71. package/dist/utils/sleep.js.map +1 -0
  72. package/dist/utils/spawn-daemon.d.ts +9 -0
  73. package/dist/utils/spawn-daemon.d.ts.map +1 -0
  74. package/dist/utils/spawn-daemon.js +13 -0
  75. package/dist/utils/spawn-daemon.js.map +1 -0
  76. package/dist/utils/verify-pid-is-localterm.d.ts +2 -0
  77. package/dist/utils/verify-pid-is-localterm.d.ts.map +1 -0
  78. package/dist/utils/verify-pid-is-localterm.js +37 -0
  79. package/dist/utils/verify-pid-is-localterm.js.map +1 -0
  80. package/package.json +67 -0
  81. package/terminal/assets/geist-mono-cyrillic-400-normal-BPBWmzPh.woff +0 -0
  82. package/terminal/assets/geist-mono-cyrillic-400-normal-Ce5q_31Z.woff2 +0 -0
  83. package/terminal/assets/geist-mono-cyrillic-500-normal-CJBLNVQT.woff2 +0 -0
  84. package/terminal/assets/geist-mono-cyrillic-500-normal-mNhfPmgl.woff +0 -0
  85. package/terminal/assets/geist-mono-cyrillic-600-normal-CGND36d7.woff2 +0 -0
  86. package/terminal/assets/geist-mono-cyrillic-600-normal-DrylrLu6.woff +0 -0
  87. package/terminal/assets/geist-mono-latin-400-normal-CoULgQGM.woff +0 -0
  88. package/terminal/assets/geist-mono-latin-400-normal-LC9RFr9I.woff2 +0 -0
  89. package/terminal/assets/geist-mono-latin-500-normal-D3o2eNa9.woff2 +0 -0
  90. package/terminal/assets/geist-mono-latin-500-normal-DOxI7kZ4.woff +0 -0
  91. package/terminal/assets/geist-mono-latin-600-normal-DQQBcVN0.woff2 +0 -0
  92. package/terminal/assets/geist-mono-latin-600-normal-DsVeri3b.woff +0 -0
  93. package/terminal/assets/geist-mono-latin-ext-400-normal-Cgks_Qgx.woff2 +0 -0
  94. package/terminal/assets/geist-mono-latin-ext-400-normal-CxNRRMGd.woff +0 -0
  95. package/terminal/assets/geist-mono-latin-ext-500-normal-CQcGuCNt.woff2 +0 -0
  96. package/terminal/assets/geist-mono-latin-ext-500-normal-diTenJ8L.woff +0 -0
  97. package/terminal/assets/geist-mono-latin-ext-600-normal-CJwYYto2.woff2 +0 -0
  98. package/terminal/assets/geist-mono-latin-ext-600-normal-EvIRCXgu.woff +0 -0
  99. package/terminal/assets/index-CL-BwH94.css +1 -0
  100. package/terminal/assets/index-D_Pz_NsG.js +240 -0
  101. package/terminal/assets/index-D_Pz_NsG.js.map +1 -0
  102. package/terminal/index.html +31 -0
  103. package/terminal/manifest.webmanifest +20 -0
package/dist/errors.js ADDED
@@ -0,0 +1,164 @@
1
+ import { EXIT_FAILURE, EXIT_OK, EXIT_USAGE_ERROR, STOP_COMMAND, getFriendlyUrl, } from "./constants.js";
2
+ export const cliError = {
3
+ invalidPort: (raw, reason) => ({
4
+ kind: "invalid-port",
5
+ code: "E_LT_CLI_INVALID_PORT",
6
+ severity: "error",
7
+ raw,
8
+ reason,
9
+ }),
10
+ invalidHost: (host) => ({
11
+ kind: "invalid-host",
12
+ code: "E_LT_CLI_INVALID_HOST",
13
+ severity: "error",
14
+ host,
15
+ }),
16
+ alreadyRunning: (pid, port) => ({
17
+ kind: "already-running",
18
+ code: "E_LT_CLI_ALREADY_RUNNING",
19
+ severity: "warning",
20
+ pid,
21
+ port,
22
+ }),
23
+ stalePortFile: (pid) => ({
24
+ kind: "stale-port-file",
25
+ code: "E_LT_CLI_STALE_PORT_FILE",
26
+ severity: "warning",
27
+ pid,
28
+ }),
29
+ daemonSpawnFailed: (execPath, logPath) => ({
30
+ kind: "daemon-spawn-failed",
31
+ code: "E_LT_CLI_DAEMON_SPAWN_FAILED",
32
+ severity: "error",
33
+ execPath,
34
+ logPath,
35
+ }),
36
+ daemonDied: (pid, logPath) => ({
37
+ kind: "daemon-died",
38
+ code: "E_LT_CLI_DAEMON_DIED",
39
+ severity: "error",
40
+ pid,
41
+ logPath,
42
+ }),
43
+ daemonReadyTimeout: (pid, waitedMs, logPath) => ({
44
+ kind: "daemon-ready-timeout",
45
+ code: "E_LT_CLI_DAEMON_READY_TIMEOUT",
46
+ severity: "warning",
47
+ pid,
48
+ waitedMs,
49
+ logPath,
50
+ }),
51
+ serverStartFailed: (cause) => ({
52
+ kind: "server-start-failed",
53
+ code: "E_LT_CLI_SERVER_START_FAILED",
54
+ severity: "error",
55
+ cause,
56
+ }),
57
+ pidNotOurs: (pid) => ({
58
+ kind: "pid-not-ours",
59
+ code: "E_LT_CLI_PID_NOT_OURS",
60
+ severity: "warning",
61
+ pid,
62
+ }),
63
+ signalFailed: (pid, cause) => ({
64
+ kind: "signal-failed",
65
+ code: "E_LT_CLI_SIGNAL_FAILED",
66
+ severity: "error",
67
+ pid,
68
+ cause,
69
+ }),
70
+ healthCheckFailed: (pid, port, cause) => ({
71
+ kind: "health-check-failed",
72
+ code: "E_LT_CLI_HEALTH_CHECK_FAILED",
73
+ severity: "warning",
74
+ pid,
75
+ port,
76
+ cause,
77
+ }),
78
+ };
79
+ const exhaustivenessGuard = (impossible) => {
80
+ throw new Error(`unhandled CliError variant: ${JSON.stringify(impossible)}`);
81
+ };
82
+ export const formatCliError = (error) => {
83
+ switch (error.kind) {
84
+ case "invalid-port":
85
+ return `invalid --port '${error.raw}': ${error.reason}`;
86
+ case "invalid-host":
87
+ return `refusing to bind '${error.host}'. localterm accepts loopback hosts (127.0.0.1, localhost, *.localhost, ::1) or explicit network addresses (0.0.0.0).`;
88
+ case "already-running":
89
+ return `localterm is already running (pid ${error.pid}, port ${error.port}).`;
90
+ case "stale-port-file":
91
+ return `localterm pid ${error.pid} is alive but the port file is missing.`;
92
+ case "daemon-spawn-failed":
93
+ return `failed to spawn ${error.execPath} — check that node is on PATH.`;
94
+ case "daemon-died":
95
+ return `daemon died during startup.`;
96
+ case "daemon-ready-timeout":
97
+ return `daemon spawned (pid ${error.pid}) but didn't bind a port within ${error.waitedMs}ms.`;
98
+ case "server-start-failed":
99
+ return `failed to start: ${error.cause.message}`;
100
+ case "pid-not-ours":
101
+ return `pid ${error.pid} is alive but does not look like a localterm process. refusing to signal an unrelated process.`;
102
+ case "signal-failed":
103
+ return `failed to signal pid ${error.pid}: ${error.cause.message}`;
104
+ case "health-check-failed":
105
+ return `pid ${error.pid} is alive but health check failed: ${error.cause.message}`;
106
+ default:
107
+ return exhaustivenessGuard(error);
108
+ }
109
+ };
110
+ export const hintForCliError = (error) => {
111
+ switch (error.kind) {
112
+ case "already-running":
113
+ return `Open ${getFriendlyUrl(error.port)} or run \`${STOP_COMMAND}\`.`;
114
+ case "stale-port-file":
115
+ return `Run \`localterm stop\` and try again.`;
116
+ case "daemon-spawn-failed":
117
+ return `tail logs: ${error.logPath}`;
118
+ case "daemon-died":
119
+ return `tail logs: ${error.logPath}`;
120
+ case "daemon-ready-timeout":
121
+ return `tail logs: ${error.logPath}`;
122
+ case "invalid-port":
123
+ case "invalid-host":
124
+ case "server-start-failed":
125
+ case "pid-not-ours":
126
+ case "signal-failed":
127
+ case "health-check-failed":
128
+ return null;
129
+ default:
130
+ return exhaustivenessGuard(error);
131
+ }
132
+ };
133
+ export const exitCodeForCliError = (error) => {
134
+ switch (error.kind) {
135
+ case "invalid-port":
136
+ case "invalid-host":
137
+ return EXIT_USAGE_ERROR;
138
+ case "already-running":
139
+ case "stale-port-file":
140
+ case "pid-not-ours":
141
+ return EXIT_OK;
142
+ case "daemon-spawn-failed":
143
+ case "daemon-died":
144
+ case "daemon-ready-timeout":
145
+ case "server-start-failed":
146
+ case "signal-failed":
147
+ case "health-check-failed":
148
+ return EXIT_FAILURE;
149
+ default:
150
+ return exhaustivenessGuard(error);
151
+ }
152
+ };
153
+ export class CliErrorException extends Error {
154
+ error;
155
+ constructor(error) {
156
+ super(formatCliError(error), {
157
+ cause: "cause" in error ? error.cause : undefined,
158
+ });
159
+ this.name = "CliErrorException";
160
+ this.error = error;
161
+ }
162
+ }
163
+ export const isCliErrorException = (value) => value instanceof CliErrorException;
164
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,59 @@
1
+ import { DEFAULT_HOST, DEFAULT_PORT } from "@monotykamary/localterm-server";
2
+ import { Command } from "commander";
3
+ import { runRestart } from "./commands/restart.js";
4
+ import { runStart } from "./commands/start.js";
5
+ import { runStatus } from "./commands/status.js";
6
+ import { runStop } from "./commands/stop.js";
7
+ import { parsePortOption } from "./utils/parse-port-option.js";
8
+ import { readPackageVersion } from "./utils/read-package-version.js";
9
+ const initialPort = parsePortOption(process.env.PORT ?? String(DEFAULT_PORT));
10
+ const program = new Command();
11
+ program
12
+ .name("localterm")
13
+ .description("local browser-based terminal hub")
14
+ .version(readPackageVersion());
15
+ program
16
+ .command("start")
17
+ .description("start the localterm server (daemonizes by default)")
18
+ .option("-p, --port <port>", "port to bind", parsePortOption, initialPort)
19
+ .option("-H, --host <host>", "host to bind", DEFAULT_HOST)
20
+ .option("--open", "open browser on start")
21
+ .option("-F, --foreground", "stay attached to this terminal (do not daemonize)", false)
22
+ .action(async (options) => {
23
+ await runStart({
24
+ port: options.port,
25
+ host: options.host,
26
+ open: options.open,
27
+ foreground: options.foreground,
28
+ });
29
+ });
30
+ program
31
+ .command("stop")
32
+ .description("stop the localterm server")
33
+ .action(async () => {
34
+ await runStop();
35
+ });
36
+ program
37
+ .command("status")
38
+ .description("show server status")
39
+ .action(async () => {
40
+ await runStatus();
41
+ });
42
+ program
43
+ .command("restart")
44
+ .description("restart the localterm server")
45
+ .option("-p, --port <port>", "port to bind", parsePortOption, initialPort)
46
+ .option("-H, --host <host>", "host to bind", DEFAULT_HOST)
47
+ .option("--open", "open browser on restart")
48
+ .action(async (options) => {
49
+ await runRestart({
50
+ port: options.port,
51
+ host: options.host,
52
+ open: options.open,
53
+ });
54
+ });
55
+ program.parseAsync().catch((error) => {
56
+ console.error(error instanceof Error ? error.message : error);
57
+ process.exit(1);
58
+ });
59
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAErE,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;AAE9E,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAC9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,kCAAkC,CAAC;KAC/C,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;AAEjC,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,oDAAoD,CAAC;KACjE,MAAM,CAAC,mBAAmB,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,CAAC;KACzE,MAAM,CAAC,mBAAmB,EAAE,cAAc,EAAE,YAAY,CAAC;KACzD,MAAM,CAAC,QAAQ,EAAE,uBAAuB,CAAC;KACzC,MAAM,CAAC,kBAAkB,EAAE,mDAAmD,EAAE,KAAK,CAAC;KACtF,MAAM,CAAC,KAAK,EAAE,OAA2E,EAAE,EAAE;IAC5F,MAAM,QAAQ,CAAC;QACb,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,UAAU,EAAE,OAAO,CAAC,UAAU;KAC/B,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,2BAA2B,CAAC;KACxC,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,OAAO,EAAE,CAAC;AAClB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,oBAAoB,CAAC;KACjC,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,SAAS,EAAE,CAAC;AACpB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,8BAA8B,CAAC;KAC3C,MAAM,CAAC,mBAAmB,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,CAAC;KACzE,MAAM,CAAC,mBAAmB,EAAE,cAAc,EAAE,YAAY,CAAC;KACzD,MAAM,CAAC,QAAQ,EAAE,yBAAyB,CAAC;KAC3C,MAAM,CAAC,KAAK,EAAE,OAAsD,EAAE,EAAE;IACvE,MAAM,UAAU,CAAC;QACf,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC5C,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare const getStateDirectory: () => string;
2
+ export declare const getPidFile: () => string;
3
+ export declare const getPortFile: () => string;
4
+ export declare const getLogFile: () => string;
5
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,iBAAiB,QAAO,MAA+C,CAAC;AACrF,eAAO,MAAM,UAAU,QAAO,MAAsD,CAAC;AACrF,eAAO,MAAM,WAAW,QAAO,MAAuD,CAAC;AACvF,eAAO,MAAM,UAAU,QAAO,MAAsD,CAAC"}
package/dist/paths.js ADDED
@@ -0,0 +1,7 @@
1
+ import os from "node:os";
2
+ import path from "node:path";
3
+ export const getStateDirectory = () => path.join(os.homedir(), ".localterm");
4
+ export const getPidFile = () => path.join(getStateDirectory(), "server.pid");
5
+ export const getPortFile = () => path.join(getStateDirectory(), "server.port");
6
+ export const getLogFile = () => path.join(getStateDirectory(), "server.log");
7
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AACrF,MAAM,CAAC,MAAM,UAAU,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,YAAY,CAAC,CAAC;AACrF,MAAM,CAAC,MAAM,WAAW,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,aAAa,CAAC,CAAC;AACvF,MAAM,CAAC,MAAM,UAAU,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,YAAY,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare const ensureStateDirectory: () => void;
2
+ export declare const ensureLogFile: () => string;
3
+ export declare const writePid: (pid: number, port: number) => void;
4
+ export declare const clearPid: () => void;
5
+ export declare const readPid: () => number | null;
6
+ export declare const readPort: () => number | null;
7
+ export declare const isAlive: (pid: number) => boolean;
8
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,oBAAoB,QAAO,IAKvC,CAAC;AAEF,eAAO,MAAM,aAAa,QAAO,MAOhC,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,KAAK,MAAM,EAAE,MAAM,MAAM,KAAG,IAIpD,CAAC;AAEF,eAAO,MAAM,QAAQ,QAAO,IAQ3B,CAAC;AAEF,eAAO,MAAM,OAAO,QAAO,MAAM,GAAG,IAMnC,CAAC;AAEF,eAAO,MAAM,QAAQ,QAAO,MAAM,GAAG,IAMpC,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,KAAK,MAAM,KAAG,OAOrC,CAAC"}
package/dist/state.js ADDED
@@ -0,0 +1,58 @@
1
+ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
2
+ import { getLogFile, getPidFile, getPortFile, getStateDirectory } from "./paths.js";
3
+ export const ensureStateDirectory = () => {
4
+ const stateDirectory = getStateDirectory();
5
+ if (!existsSync(stateDirectory)) {
6
+ mkdirSync(stateDirectory, { recursive: true });
7
+ }
8
+ };
9
+ export const ensureLogFile = () => {
10
+ ensureStateDirectory();
11
+ const logFile = getLogFile();
12
+ if (!existsSync(logFile)) {
13
+ writeFileSync(logFile, "", "utf8");
14
+ }
15
+ return logFile;
16
+ };
17
+ export const writePid = (pid, port) => {
18
+ ensureStateDirectory();
19
+ writeFileSync(getPidFile(), String(pid), "utf8");
20
+ writeFileSync(getPortFile(), String(port), "utf8");
21
+ };
22
+ export const clearPid = () => {
23
+ for (const file of [getPidFile(), getPortFile()]) {
24
+ try {
25
+ if (existsSync(file))
26
+ unlinkSync(file);
27
+ }
28
+ catch {
29
+ /* file may have been removed by another process between existsSync and unlink */
30
+ }
31
+ }
32
+ };
33
+ export const readPid = () => {
34
+ const pidFile = getPidFile();
35
+ if (!existsSync(pidFile))
36
+ return null;
37
+ const raw = readFileSync(pidFile, "utf8").trim();
38
+ const parsed = Number(raw);
39
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
40
+ };
41
+ export const readPort = () => {
42
+ const portFile = getPortFile();
43
+ if (!existsSync(portFile))
44
+ return null;
45
+ const raw = readFileSync(portFile, "utf8").trim();
46
+ const parsed = Number(raw);
47
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
48
+ };
49
+ export const isAlive = (pid) => {
50
+ try {
51
+ process.kill(pid, 0);
52
+ return true;
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ };
58
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface DaemonStartArgsInput {
2
+ port: number;
3
+ host: string;
4
+ open: boolean;
5
+ }
6
+ export declare const buildDaemonStartArgs: (input: DaemonStartArgsInput) => string[];
7
+ //# sourceMappingURL=build-daemon-args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-daemon-args.d.ts","sourceRoot":"","sources":["../../src/utils/build-daemon-args.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;CACf;AAED,eAAO,MAAM,oBAAoB,GAAI,OAAO,oBAAoB,KAAG,MAAM,EAIxE,CAAC"}
@@ -0,0 +1,7 @@
1
+ export const buildDaemonStartArgs = (input) => {
2
+ const args = ["start", "--port", String(input.port), "--host", input.host];
3
+ if (input.open)
4
+ args.push("--open");
5
+ return args;
6
+ };
7
+ //# sourceMappingURL=build-daemon-args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-daemon-args.js","sourceRoot":"","sources":["../../src/utils/build-daemon-args.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAA2B,EAAY,EAAE;IAC5E,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3E,IAAI,KAAK,CAAC,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC;AACd,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const cliEntry: string;
2
+ //# sourceMappingURL=cli-entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-entry.d.ts","sourceRoot":"","sources":["../../src/utils/cli-entry.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,QAAQ,QAAyC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
4
+ export const cliEntry = path.resolve(moduleDir, "../index.js");
5
+ //# sourceMappingURL=cli-entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-entry.js","sourceRoot":"","sources":["../../src/utils/cli-entry.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE/D,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const parsePortOption: (raw: string) => number;
2
+ //# sourceMappingURL=parse-port-option.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-port-option.d.ts","sourceRoot":"","sources":["../../src/utils/parse-port-option.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,GAAI,KAAK,MAAM,KAAG,MAe7C,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { InvalidArgumentError } from "commander";
2
+ import { MAX_TCP_PORT, MIN_TCP_PORT } from "../constants.js";
3
+ import { cliError, formatCliError } from "../errors.js";
4
+ export const parsePortOption = (raw) => {
5
+ if (!/^\d+$/.test(raw)) {
6
+ throw new InvalidArgumentError(formatCliError(cliError.invalidPort(raw, "expected an integer port number")));
7
+ }
8
+ const port = Number.parseInt(raw, 10);
9
+ if (port < MIN_TCP_PORT || port > MAX_TCP_PORT) {
10
+ throw new InvalidArgumentError(formatCliError(cliError.invalidPort(raw, `must be between ${MIN_TCP_PORT} and ${MAX_TCP_PORT}`)));
11
+ }
12
+ return port;
13
+ };
14
+ //# sourceMappingURL=parse-port-option.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-port-option.js","sourceRoot":"","sources":["../../src/utils/parse-port-option.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAExD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAW,EAAU,EAAE;IACrD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,oBAAoB,CAC5B,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE,iCAAiC,CAAC,CAAC,CAC7E,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACtC,IAAI,IAAI,GAAG,YAAY,IAAI,IAAI,GAAG,YAAY,EAAE,CAAC;QAC/C,MAAM,IAAI,oBAAoB,CAC5B,cAAc,CACZ,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE,mBAAmB,YAAY,QAAQ,YAAY,EAAE,CAAC,CACjF,CACF,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { type CliError } from "../errors.js";
2
+ export type DaemonReadyResult = {
3
+ ok: true;
4
+ port: number;
5
+ } | {
6
+ ok: false;
7
+ error: CliError;
8
+ };
9
+ export interface DaemonProbeOptions {
10
+ childPid: number;
11
+ initialPort: number | null;
12
+ intervalMs: number;
13
+ maxWaitMs: number;
14
+ logPath: string;
15
+ isAlive: (pid: number) => boolean;
16
+ readPort: () => number | null;
17
+ sleep: (durationMs: number) => Promise<void>;
18
+ }
19
+ export declare const pollForDaemonReady: (options: DaemonProbeOptions) => Promise<DaemonReadyResult>;
20
+ //# sourceMappingURL=poll-for-daemon-ready.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poll-for-daemon-ready.d.ts","sourceRoot":"","sources":["../../src/utils/poll-for-daemon-ready.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,cAAc,CAAC;AAEvD,MAAM,MAAM,iBAAiB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAAC;AAE5F,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAClC,QAAQ,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AAED,eAAO,MAAM,kBAAkB,GAC7B,SAAS,kBAAkB,KAC1B,OAAO,CAAC,iBAAiB,CAiB3B,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { cliError } from "../errors.js";
2
+ export const pollForDaemonReady = async (options) => {
3
+ let waited = 0;
4
+ while (waited < options.maxWaitMs) {
5
+ await options.sleep(options.intervalMs);
6
+ waited += options.intervalMs;
7
+ if (!options.isAlive(options.childPid)) {
8
+ return { ok: false, error: cliError.daemonDied(options.childPid, options.logPath) };
9
+ }
10
+ const observedPort = options.readPort();
11
+ if (observedPort !== null && observedPort !== options.initialPort) {
12
+ return { ok: true, port: observedPort };
13
+ }
14
+ }
15
+ return {
16
+ ok: false,
17
+ error: cliError.daemonReadyTimeout(options.childPid, options.maxWaitMs, options.logPath),
18
+ };
19
+ };
20
+ //# sourceMappingURL=poll-for-daemon-ready.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poll-for-daemon-ready.js","sourceRoot":"","sources":["../../src/utils/poll-for-daemon-ready.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,QAAQ,EAAE,MAAM,cAAc,CAAC;AAevD,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EACrC,OAA2B,EACC,EAAE;IAC9B,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OAAO,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;QAClC,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,IAAI,OAAO,CAAC,UAAU,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACtF,CAAC;QACD,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;QACxC,IAAI,YAAY,KAAK,IAAI,IAAI,YAAY,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC;YAClE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;QAC1C,CAAC;IACH,CAAC;IACD,OAAO;QACL,EAAE,EAAE,KAAK;QACT,KAAK,EAAE,QAAQ,CAAC,kBAAkB,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC;KACzF,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const readPackageVersion: () => string;
2
+ //# sourceMappingURL=read-package-version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-package-version.d.ts","sourceRoot":"","sources":["../../src/utils/read-package-version.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,kBAAkB,QAAO,MAGrC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { readFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { z } from "zod";
5
+ const packageJsonSchema = z.object({ version: z.string().min(1) });
6
+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
7
+ const packageJsonPath = path.resolve(moduleDir, "../../package.json");
8
+ export const readPackageVersion = () => {
9
+ const parsed = packageJsonSchema.parse(JSON.parse(readFileSync(packageJsonPath, "utf8")));
10
+ return parsed.version;
11
+ };
12
+ //# sourceMappingURL=read-package-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-package-version.js","sourceRoot":"","sources":["../../src/utils/read-package-version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAEnE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC;AAEtE,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAW,EAAE;IAC7C,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1F,OAAO,MAAM,CAAC,OAAO,CAAC;AACxB,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type CliError } from "../errors.js";
2
+ export declare const reportCliError: (error: CliError) => void;
3
+ //# sourceMappingURL=report-cli-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-cli-error.d.ts","sourceRoot":"","sources":["../../src/utils/report-cli-error.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAmC,MAAM,cAAc,CAAC;AAW9E,eAAO,MAAM,cAAc,GAAI,OAAO,QAAQ,KAAG,IAMhD,CAAC"}
@@ -0,0 +1,19 @@
1
+ import kleur from "kleur";
2
+ import { formatCliError, hintForCliError } from "../errors.js";
3
+ const colorForSeverity = (severity) => {
4
+ switch (severity) {
5
+ case "error":
6
+ return kleur.red;
7
+ case "warning":
8
+ return kleur.yellow;
9
+ }
10
+ };
11
+ export const reportCliError = (error) => {
12
+ const colored = colorForSeverity(error.severity);
13
+ const prefix = error.severity === "error" ? "✗ " : "";
14
+ console.log(colored(`${prefix}${formatCliError(error)}`));
15
+ const hint = hintForCliError(error);
16
+ if (hint !== null)
17
+ console.log(hint);
18
+ };
19
+ //# sourceMappingURL=report-cli-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-cli-error.js","sourceRoot":"","sources":["../../src/utils/report-cli-error.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAiB,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE9E,MAAM,gBAAgB,GAAG,CAAC,QAA8B,EAA+B,EAAE;IACvF,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,OAAO;YACV,OAAO,KAAK,CAAC,GAAG,CAAC;QACnB,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,MAAM,CAAC;IACxB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAe,EAAQ,EAAE;IACtD,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type CliError } from "../errors.js";
2
+ export declare const runStartPreflight: () => CliError | null;
3
+ //# sourceMappingURL=run-start-preflight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-start-preflight.d.ts","sourceRoot":"","sources":["../../src/utils/run-start-preflight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,cAAc,CAAC;AAGvD,eAAO,MAAM,iBAAiB,QAAO,QAAQ,GAAG,IAW/C,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { cliError } from "../errors.js";
2
+ import { clearPid, isAlive, readPid, readPort } from "../state.js";
3
+ export const runStartPreflight = () => {
4
+ const existingPid = readPid();
5
+ if (existingPid && isAlive(existingPid)) {
6
+ const existingPort = readPort();
7
+ if (existingPort === null) {
8
+ return cliError.stalePortFile(existingPid);
9
+ }
10
+ return cliError.alreadyRunning(existingPid, existingPort);
11
+ }
12
+ if (existingPid)
13
+ clearPid();
14
+ return null;
15
+ };
16
+ //# sourceMappingURL=run-start-preflight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-start-preflight.js","sourceRoot":"","sources":["../../src/utils/run-start-preflight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,QAAQ,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEnE,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAoB,EAAE;IACrD,MAAM,WAAW,GAAG,OAAO,EAAE,CAAC;IAC9B,IAAI,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QACxC,MAAM,YAAY,GAAG,QAAQ,EAAE,CAAC;QAChC,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,QAAQ,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,QAAQ,CAAC,cAAc,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAC5D,CAAC;IACD,IAAI,WAAW;QAAE,QAAQ,EAAE,CAAC;IAC5B,OAAO,IAAI,CAAC;AACd,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const sleep: (durationMs: number) => Promise<void>;
2
+ //# sourceMappingURL=sleep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sleep.d.ts","sourceRoot":"","sources":["../../src/utils/sleep.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK,GAAI,YAAY,MAAM,KAAG,OAAO,CAAC,IAAI,CACI,CAAC"}
@@ -0,0 +1,2 @@
1
+ export const sleep = (durationMs) => new Promise((resolve) => setTimeout(resolve, durationMs));
2
+ //# sourceMappingURL=sleep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sleep.js","sourceRoot":"","sources":["../../src/utils/sleep.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,UAAkB,EAAiB,EAAE,CACzD,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface SpawnDaemonInput {
2
+ args: string[];
3
+ logFd: number;
4
+ }
5
+ export interface SpawnedDaemonHandle {
6
+ pid: number | undefined;
7
+ }
8
+ export declare const spawnDaemon: (input: SpawnDaemonInput) => SpawnedDaemonHandle;
9
+ //# sourceMappingURL=spawn-daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn-daemon.d.ts","sourceRoot":"","sources":["../../src/utils/spawn-daemon.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;CACzB;AAED,eAAO,MAAM,WAAW,GAAI,OAAO,gBAAgB,KAAG,mBAQrD,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { spawn } from "node:child_process";
2
+ import { DAEMON_CHILD_ENV_FLAG } from "../constants.js";
3
+ import { cliEntry } from "./cli-entry.js";
4
+ export const spawnDaemon = (input) => {
5
+ const child = spawn(process.execPath, [cliEntry, ...input.args], {
6
+ detached: true,
7
+ stdio: ["ignore", input.logFd, input.logFd],
8
+ env: { ...process.env, [DAEMON_CHILD_ENV_FLAG]: "1" },
9
+ });
10
+ child.unref();
11
+ return { pid: child.pid };
12
+ };
13
+ //# sourceMappingURL=spawn-daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn-daemon.js","sourceRoot":"","sources":["../../src/utils/spawn-daemon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAW1C,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAuB,EAAuB,EAAE;IAC1E,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE;QAC/D,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;QAC3C,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,EAAE,GAAG,EAAE;KACtD,CAAC,CAAC;IACH,KAAK,CAAC,KAAK,EAAE,CAAC;IACd,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC;AAC5B,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const verifyPidIsLocalterm: (pid: number) => Promise<boolean>;
2
+ //# sourceMappingURL=verify-pid-is-localterm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-pid-is-localterm.d.ts","sourceRoot":"","sources":["../../src/utils/verify-pid-is-localterm.ts"],"names":[],"mappings":"AA6BA,eAAO,MAAM,oBAAoB,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,OAAO,CAKvE,CAAC"}