@procedures/server 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/README.md +18 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/module.d.ts +24 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +29 -0
- package/dist/module.js.map +1 -0
- package/dist/procedures/server.start.d.ts +17 -0
- package/dist/procedures/server.start.d.ts.map +1 -0
- package/dist/procedures/server.start.js +183 -0
- package/dist/procedures/server.start.js.map +1 -0
- package/dist/procedures/server.status.d.ts +15 -0
- package/dist/procedures/server.status.d.ts.map +1 -0
- package/dist/procedures/server.status.js +118 -0
- package/dist/procedures/server.status.js.map +1 -0
- package/dist/procedures/server.stop.d.ts +14 -0
- package/dist/procedures/server.stop.d.ts.map +1 -0
- package/dist/procedures/server.stop.js +98 -0
- package/dist/procedures/server.stop.js.map +1 -0
- package/dist/register.d.ts +7 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +9 -0
- package/dist/register.js.map +1 -0
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +5 -2
- package/dist/run.js.map +1 -1
- package/dist/schemas.d.ts +19 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +48 -0
- package/dist/schemas.js.map +1 -0
- package/dist/types.d.ts +58 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +19 -5
- package/src/index.ts +26 -1
- package/src/module.ts +33 -0
- package/src/procedures/server.start.ts +213 -0
- package/src/procedures/server.status.ts +141 -0
- package/src/procedures/server.stop.ts +123 -0
- package/src/register.ts +11 -0
- package/src/run.ts +5 -2
- package/src/schemas.ts +69 -0
- package/src/types.ts +76 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Procedure: server.status
|
|
3
|
+
* Gets the current CLI server status
|
|
4
|
+
*
|
|
5
|
+
* The procedure came from `@procedures/peer`: it belongs to the host.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
import * as os from "node:os";
|
|
10
|
+
import { createProcedure, zodAdapter, type Effects, type Procedure } from "@procedures/client";
|
|
11
|
+
import { checkServer, readAllLockfiles, readLockfileForPort, removeLockfileForPort, type LockfileData } from "@procedures/peer/lockfile";
|
|
12
|
+
import { ServerStatusOutputSchema, serverStatusInputSchema } from "../schemas.js";
|
|
13
|
+
import type { ServerStatusInput, ServerStatusOutput } from "../types.js";
|
|
14
|
+
|
|
15
|
+
const MARK_DIR = path.join(os.homedir(), ".mark");
|
|
16
|
+
const LOG_PATH = path.join(MARK_DIR, "server.log");
|
|
17
|
+
|
|
18
|
+
const serverStatusOutputSchema = zodAdapter<ServerStatusOutput>(ServerStatusOutputSchema);
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Format uptime as human-readable string
|
|
26
|
+
*/
|
|
27
|
+
function formatUptime(startedAt: string): string {
|
|
28
|
+
const start = new Date(startedAt).getTime();
|
|
29
|
+
const now = Date.now();
|
|
30
|
+
const diff = Math.floor((now - start) / 1000);
|
|
31
|
+
|
|
32
|
+
if (diff < 60) {
|
|
33
|
+
return `${diff}s`;
|
|
34
|
+
}
|
|
35
|
+
if (diff < 3600) {
|
|
36
|
+
const mins = Math.floor(diff / 60);
|
|
37
|
+
const secs = diff % 60;
|
|
38
|
+
return `${mins}m ${secs}s`;
|
|
39
|
+
}
|
|
40
|
+
if (diff < 86400) {
|
|
41
|
+
const hours = Math.floor(diff / 3600);
|
|
42
|
+
const mins = Math.floor((diff % 3600) / 60);
|
|
43
|
+
return `${hours}h ${mins}m`;
|
|
44
|
+
}
|
|
45
|
+
const days = Math.floor(diff / 86400);
|
|
46
|
+
const hours = Math.floor((diff % 86400) / 3600);
|
|
47
|
+
return `${days}d ${hours}h`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const serverStatusProcedure: Procedure<
|
|
51
|
+
ServerStatusInput,
|
|
52
|
+
ServerStatusOutput,
|
|
53
|
+
{ description: string; effects: Effects; output: string }
|
|
54
|
+
> = createProcedure()
|
|
55
|
+
.path(["server", "status"])
|
|
56
|
+
.input(serverStatusInputSchema)
|
|
57
|
+
.output(serverStatusOutputSchema)
|
|
58
|
+
.meta({
|
|
59
|
+
description: "Get CLI server status",
|
|
60
|
+
// It deletes the lockfile of a server that does not answer
|
|
61
|
+
effects: { reads: ["fs", "server"], writes: ["fs"], idempotent: true },
|
|
62
|
+
args: [],
|
|
63
|
+
shorts: { port: "p" },
|
|
64
|
+
output: "text",
|
|
65
|
+
})
|
|
66
|
+
.handler(async (input: ServerStatusInput): Promise<ServerStatusOutput> => {
|
|
67
|
+
// Get target servers
|
|
68
|
+
let targets: LockfileData[];
|
|
69
|
+
if (input.port !== undefined) {
|
|
70
|
+
const lockfile = readLockfileForPort(input.port);
|
|
71
|
+
targets = lockfile ? [lockfile] : [];
|
|
72
|
+
} else {
|
|
73
|
+
targets = readAllLockfiles();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (targets.length === 0) {
|
|
77
|
+
return {
|
|
78
|
+
running: false,
|
|
79
|
+
message: input.port
|
|
80
|
+
? `No server found on port ${input.port}`
|
|
81
|
+
: "No servers running",
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// For single server, return detailed info
|
|
86
|
+
if (targets.length === 1) {
|
|
87
|
+
const lockfile = targets[0]!;
|
|
88
|
+
const { pid, port, endpoint, startedAt, transport } = lockfile;
|
|
89
|
+
|
|
90
|
+
if ((await checkServer(lockfile)) !== "alive") {
|
|
91
|
+
removeLockfileForPort(port);
|
|
92
|
+
return {
|
|
93
|
+
running: false,
|
|
94
|
+
message: "Server is not running (cleaned up stale lockfile)",
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const uptime = formatUptime(startedAt);
|
|
99
|
+
return {
|
|
100
|
+
running: true,
|
|
101
|
+
pid,
|
|
102
|
+
port,
|
|
103
|
+
endpoint,
|
|
104
|
+
transport,
|
|
105
|
+
startedAt,
|
|
106
|
+
uptime,
|
|
107
|
+
logFile: LOG_PATH,
|
|
108
|
+
message: `Server running (PID ${pid}, port ${port}, uptime ${uptime})`,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Multiple servers - summarize
|
|
113
|
+
const lines: string[] = [];
|
|
114
|
+
let anyRunning = false;
|
|
115
|
+
|
|
116
|
+
for (const lockfile of targets) {
|
|
117
|
+
const { pid, port, endpoint, startedAt } = lockfile;
|
|
118
|
+
if ((await checkServer(lockfile)) !== "alive") {
|
|
119
|
+
removeLockfileForPort(port);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
anyRunning = true;
|
|
123
|
+
const uptime = formatUptime(startedAt);
|
|
124
|
+
lines.push(` Port ${port}: PID ${pid}, uptime ${uptime}, ${endpoint}`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (!anyRunning) {
|
|
128
|
+
return {
|
|
129
|
+
running: false,
|
|
130
|
+
message: "No servers running (cleaned up stale lockfiles)",
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
running: true,
|
|
136
|
+
message: `${lines.length} server(s) running:\n${lines.join("\n")}`,
|
|
137
|
+
};
|
|
138
|
+
})
|
|
139
|
+
.build();
|
|
140
|
+
|
|
141
|
+
export type { ServerStatusInput, ServerStatusOutput };
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Procedure: server.stop
|
|
3
|
+
* Stops the running CLI server daemon
|
|
4
|
+
*
|
|
5
|
+
* The procedure came from `@procedures/peer`: it belongs to the host.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createProcedure, zodAdapter, type Effects, type Procedure } from "@procedures/client";
|
|
9
|
+
import { checkServer, readAllLockfiles, readLockfileForPort, removeLockfileForPort, type LockfileData } from "@procedures/peer/lockfile";
|
|
10
|
+
import { ServerStopOutputSchema, serverStopInputSchema } from "../schemas.js";
|
|
11
|
+
import type { ServerStopInput, ServerStopOutput } from "../types.js";
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
const serverStopOutputSchema = zodAdapter<ServerStopOutput>(ServerStopOutputSchema);
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Kill process by PID
|
|
22
|
+
*/
|
|
23
|
+
function killProcess(pid: number, signal: NodeJS.Signals = "SIGTERM"): boolean {
|
|
24
|
+
try {
|
|
25
|
+
process.kill(pid, signal);
|
|
26
|
+
return true;
|
|
27
|
+
} catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const serverStopProcedure: Procedure<
|
|
33
|
+
ServerStopInput,
|
|
34
|
+
ServerStopOutput,
|
|
35
|
+
{ description: string; effects: Effects }
|
|
36
|
+
> = createProcedure()
|
|
37
|
+
.path(["server", "stop"])
|
|
38
|
+
.input(serverStopInputSchema)
|
|
39
|
+
.output(serverStopOutputSchema)
|
|
40
|
+
.meta({
|
|
41
|
+
description: "Stop running CLI server",
|
|
42
|
+
// It stops the servers of the lockfiles and deletes their lockfiles
|
|
43
|
+
effects: { reads: ["fs", "server"], writes: ["fs", "server"], idempotent: true },
|
|
44
|
+
args: [],
|
|
45
|
+
shorts: { port: "p" },
|
|
46
|
+
})
|
|
47
|
+
.handler(async (input: ServerStopInput): Promise<ServerStopOutput> => {
|
|
48
|
+
const force = input.force ?? false;
|
|
49
|
+
const signal: NodeJS.Signals = force ? "SIGKILL" : "SIGTERM";
|
|
50
|
+
|
|
51
|
+
// Get target servers
|
|
52
|
+
let targets: LockfileData[];
|
|
53
|
+
if (input.port !== undefined) {
|
|
54
|
+
const lockfile = readLockfileForPort(input.port);
|
|
55
|
+
targets = lockfile ? [lockfile] : [];
|
|
56
|
+
} else {
|
|
57
|
+
targets = readAllLockfiles();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (targets.length === 0) {
|
|
61
|
+
return {
|
|
62
|
+
success: false,
|
|
63
|
+
message: input.port
|
|
64
|
+
? `No server found on port ${input.port}`
|
|
65
|
+
: "No servers running",
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const results: string[] = [];
|
|
70
|
+
let allSuccess = true;
|
|
71
|
+
|
|
72
|
+
for (const lockfile of targets) {
|
|
73
|
+
const { pid, port } = lockfile;
|
|
74
|
+
|
|
75
|
+
// Signal the PID only when the server answers as the peer of this lockfile: Windows reuses
|
|
76
|
+
// PIDs, and before, a stale lockfile made this kill an unrelated process (deep dive CLI-4)
|
|
77
|
+
const state = await checkServer(lockfile);
|
|
78
|
+
if (state !== "alive") {
|
|
79
|
+
removeLockfileForPort(port);
|
|
80
|
+
results.push(
|
|
81
|
+
state === "dead"
|
|
82
|
+
? `Port ${port}: cleaned up stale lockfile`
|
|
83
|
+
: `Port ${port}: another process answers on this port; nothing stopped (stale lockfile removed)`
|
|
84
|
+
);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const sent = killProcess(pid, signal);
|
|
89
|
+
if (!sent) {
|
|
90
|
+
allSuccess = false;
|
|
91
|
+
results.push(`Port ${port}: failed to send ${signal} to PID ${pid}`);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Wait for process to die
|
|
96
|
+
const maxWait = force ? 500 : 5000;
|
|
97
|
+
const startTime = Date.now();
|
|
98
|
+
let stopped = false;
|
|
99
|
+
|
|
100
|
+
while (Date.now() - startTime < maxWait) {
|
|
101
|
+
if ((await checkServer(lockfile, 300)) === "dead") {
|
|
102
|
+
removeLockfileForPort(port);
|
|
103
|
+
results.push(`Port ${port}: stopped (PID ${pid})`);
|
|
104
|
+
stopped = true;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!stopped) {
|
|
111
|
+
allSuccess = false;
|
|
112
|
+
results.push(`Port ${port}: PID ${pid} did not stop${force ? "" : " (try --force)"}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
success: allSuccess,
|
|
118
|
+
message: results.join("\n"),
|
|
119
|
+
};
|
|
120
|
+
})
|
|
121
|
+
.build();
|
|
122
|
+
|
|
123
|
+
export type { ServerStopInput, ServerStopOutput };
|
package/src/register.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Importing this file registers the procedures of @procedures/server in the global registry:
|
|
3
|
+
* `import "@procedures/server/register"`. The package root and the `./module` entry register
|
|
4
|
+
* nothing (ARCHITECTURE-PROPOSALS-2026-10, P9).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { registerServerProcedures } from "./module.js";
|
|
8
|
+
|
|
9
|
+
export * from "./module.js";
|
|
10
|
+
|
|
11
|
+
registerServerProcedures();
|
package/src/run.ts
CHANGED
|
@@ -23,8 +23,9 @@ import {
|
|
|
23
23
|
type ProcedureRegistry,
|
|
24
24
|
} from "@procedures/client";
|
|
25
25
|
import { createPeer, type Peer, type PeerEndpoint } from "@procedures/peer";
|
|
26
|
-
import
|
|
26
|
+
import peerModule from "@procedures/peer/module";
|
|
27
27
|
import { parseConfig } from "./config.js";
|
|
28
|
+
import { serverModule } from "./module.js";
|
|
28
29
|
import type { ServerConfig } from "./types.js";
|
|
29
30
|
import { seconds } from "@procedures/client";
|
|
30
31
|
|
|
@@ -134,7 +135,9 @@ export async function startServer(
|
|
|
134
135
|
log: (line: string) => void = console.log,
|
|
135
136
|
options: ServerRunOptions = {}
|
|
136
137
|
): Promise<RunningServer> {
|
|
137
|
-
|
|
138
|
+
// The server.* procedures: those of the peer package (server.create, server.call and the
|
|
139
|
+
// others), and server.start, server.stop and server.status of this package
|
|
140
|
+
const modules: ProcedureModule[] = [peerModule, serverModule];
|
|
138
141
|
for (const spec of config.procedures) {
|
|
139
142
|
if (config.verbose) log(` Loading: ${spec}`);
|
|
140
143
|
try {
|
package/src/schemas.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The input and output schemas of `server.start`, `server.stop` and `server.status`.
|
|
3
|
+
*
|
|
4
|
+
* The three procedures came from `@procedures/peer`: they manage the background server of the
|
|
5
|
+
* `mark` CLI, and this package holds the host. The input schemas validate each field, so the
|
|
6
|
+
* help of `mark server start` lists the options, and the port "abc" fails before the
|
|
7
|
+
* handler. The output schemas are loose objects: a field that a schema does not name stays in
|
|
8
|
+
* the result.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
import { zodAdapter, type ZodLikeSchema } from "@procedures/client";
|
|
13
|
+
import type {
|
|
14
|
+
ServerStartInput,
|
|
15
|
+
ServerStartOutput,
|
|
16
|
+
ServerStatusInput,
|
|
17
|
+
ServerStatusOutput,
|
|
18
|
+
ServerStopInput,
|
|
19
|
+
ServerStopOutput,
|
|
20
|
+
} from "./types.js";
|
|
21
|
+
|
|
22
|
+
const port = z.number().int().min(1).max(65535);
|
|
23
|
+
|
|
24
|
+
export const serverStartInputSchema: ZodLikeSchema<ServerStartInput> = zodAdapter<ServerStartInput>(
|
|
25
|
+
z.object({
|
|
26
|
+
port: port.optional().describe("The port to listen on (default: 3000)"),
|
|
27
|
+
host: z.string().min(1).optional().describe("The host to bind to (default: 127.0.0.1)"),
|
|
28
|
+
transport: z.enum(["http", "websocket", "both"]).optional().describe("The transport (default: http)"),
|
|
29
|
+
})
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
export const serverStopInputSchema: ZodLikeSchema<ServerStopInput> = zodAdapter<ServerStopInput>(
|
|
33
|
+
z.object({
|
|
34
|
+
port: port.optional().describe("The port of the server to stop (default: all servers)"),
|
|
35
|
+
force: z.boolean().optional().describe("Stop with SIGKILL instead of SIGTERM"),
|
|
36
|
+
})
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
export const serverStatusInputSchema: ZodLikeSchema<ServerStatusInput> = zodAdapter<ServerStatusInput>(
|
|
40
|
+
z.object({
|
|
41
|
+
port: port.optional().describe("The port of the server (default: all servers)"),
|
|
42
|
+
})
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
export const ServerStartOutputSchema: z.ZodType<ServerStartOutput> = z.looseObject({
|
|
46
|
+
success: z.boolean().describe("True when the server started"),
|
|
47
|
+
pid: z.number().optional().describe("The process id of the server"),
|
|
48
|
+
port: z.number().optional().describe("The port of the server"),
|
|
49
|
+
endpoint: z.string().optional().describe("The URL of the server"),
|
|
50
|
+
logFile: z.string().optional().describe("The log file of the server"),
|
|
51
|
+
message: z.string().describe("A message about the result"),
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
export const ServerStopOutputSchema: z.ZodType<ServerStopOutput> = z.looseObject({
|
|
55
|
+
success: z.boolean().describe("True when the server stopped"),
|
|
56
|
+
message: z.string().describe("A message about the result"),
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
export const ServerStatusOutputSchema: z.ZodType<ServerStatusOutput> = z.looseObject({
|
|
60
|
+
running: z.boolean().describe("True when a server runs"),
|
|
61
|
+
pid: z.number().optional().describe("The process id of the server"),
|
|
62
|
+
port: z.number().optional().describe("The port of the server"),
|
|
63
|
+
endpoint: z.string().optional().describe("The URL of the server"),
|
|
64
|
+
transport: z.string().optional().describe("The transport of the server"),
|
|
65
|
+
startedAt: z.string().optional().describe("The start time (ISO 8601)"),
|
|
66
|
+
uptime: z.string().optional().describe("The time since the start, as text"),
|
|
67
|
+
logFile: z.string().optional().describe("The log file of the server"),
|
|
68
|
+
message: z.string().describe("A message about the result"),
|
|
69
|
+
});
|
package/src/types.ts
CHANGED
|
@@ -30,3 +30,79 @@ export interface ServerCreateResult {
|
|
|
30
30
|
endpoints: Array<{ type: string; address: string }>;
|
|
31
31
|
procedureCount: number;
|
|
32
32
|
}
|
|
33
|
+
|
|
34
|
+
// =============================================================================
|
|
35
|
+
// server.start Types (from @procedures/peer)
|
|
36
|
+
// =============================================================================
|
|
37
|
+
|
|
38
|
+
export interface ServerStartInput {
|
|
39
|
+
/** Port to listen on */
|
|
40
|
+
port?: number | undefined;
|
|
41
|
+
/** Host to bind to */
|
|
42
|
+
host?: string | undefined;
|
|
43
|
+
/** Transport type */
|
|
44
|
+
transport?: "http" | "websocket" | "both" | undefined;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface ServerStartOutput {
|
|
48
|
+
/** Whether start succeeded */
|
|
49
|
+
success: boolean;
|
|
50
|
+
/** Process ID of server */
|
|
51
|
+
pid?: number | undefined;
|
|
52
|
+
/** Port server is running on */
|
|
53
|
+
port?: number | undefined;
|
|
54
|
+
/** Endpoint URL */
|
|
55
|
+
endpoint?: string | undefined;
|
|
56
|
+
/** Log file path */
|
|
57
|
+
logFile?: string | undefined;
|
|
58
|
+
/** Status message */
|
|
59
|
+
message: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// =============================================================================
|
|
63
|
+
// server.stop Types (from @procedures/peer)
|
|
64
|
+
// =============================================================================
|
|
65
|
+
|
|
66
|
+
export interface ServerStopInput {
|
|
67
|
+
/** Port of server to stop (stops all if omitted) */
|
|
68
|
+
port?: number | undefined;
|
|
69
|
+
/** Force kill with SIGKILL instead of SIGTERM */
|
|
70
|
+
force?: boolean | undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface ServerStopOutput {
|
|
74
|
+
/** Whether stop succeeded */
|
|
75
|
+
success: boolean;
|
|
76
|
+
/** Status message */
|
|
77
|
+
message: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// =============================================================================
|
|
81
|
+
// server.status Types (from @procedures/peer)
|
|
82
|
+
// =============================================================================
|
|
83
|
+
|
|
84
|
+
export interface ServerStatusInput {
|
|
85
|
+
/** Port to check (shows all if omitted) */
|
|
86
|
+
port?: number | undefined;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface ServerStatusOutput {
|
|
90
|
+
/** Whether server is running */
|
|
91
|
+
running: boolean;
|
|
92
|
+
/** Process ID */
|
|
93
|
+
pid?: number | undefined;
|
|
94
|
+
/** Port */
|
|
95
|
+
port?: number | undefined;
|
|
96
|
+
/** Endpoint URL */
|
|
97
|
+
endpoint?: string | undefined;
|
|
98
|
+
/** Transport type */
|
|
99
|
+
transport?: string | undefined;
|
|
100
|
+
/** When server started (ISO string) */
|
|
101
|
+
startedAt?: string | undefined;
|
|
102
|
+
/** Human-readable uptime */
|
|
103
|
+
uptime?: string | undefined;
|
|
104
|
+
/** Log file path */
|
|
105
|
+
logFile?: string | undefined;
|
|
106
|
+
/** Status message */
|
|
107
|
+
message: string;
|
|
108
|
+
}
|