@procedures/mark 0.10.0 → 0.12.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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 2,
3
- "fingerprint": "a963be959df087dca9e09bd58381789bd4f3d2e56266fe0af21b77c7383511d1",
4
- "generatedAt": "2026-10-18T10:51:31.999Z",
3
+ "fingerprint": "d0a268ba7459be40878ac11e5e6f62ee37eaef3d75991b3f0631123691c62b94",
4
+ "generatedAt": "2026-10-18T13:18:37.646Z",
5
5
  "commands": [
6
6
  {
7
7
  "path": [
@@ -5,7 +5,13 @@
5
5
  * via HTTP. The server has the registry of mark (the module of each package, roadmap 3.1) and
6
6
  * the host policy of the core (roadmap 2.3): the token in the lockfile, and the topics of
7
7
  * `--events`. With `--fs-root`, each procedure keeps its paths in the root, or the root refuses it.
8
+ *
9
+ * The server is the background host of `mark` (decision D17): it runs under `run()` of
10
+ * `@mark1russell7/service` through `runProcedureHost()`, with the profile `daemon` (CLI-8). The
11
+ * runner owns the signals, the stop in stages and the exit. The lockfile is a dependency of the
12
+ * service: its connect writes it, and its close removes it after the listeners close.
8
13
  */
14
+ import type { ProcedureHostRunConfig } from "@procedures/server";
9
15
  export interface ServerModeOptions {
10
16
  port: number;
11
17
  host?: string;
@@ -20,9 +26,10 @@ export interface ServerModeOptions {
20
26
  fsRoot?: string | undefined;
21
27
  }
22
28
  /**
23
- * Start CLI in server mode
29
+ * Start CLI in server mode. The promise ends when the lifecycle of the server ends. `run` gives
30
+ * the options of `run()`, for a test: a process port and a clock.
24
31
  */
25
- export declare function startServerMode(options: ServerModeOptions): Promise<void>;
32
+ export declare function startServerMode(options: ServerModeOptions, run?: ProcedureHostRunConfig["run"]): Promise<void>;
26
33
  /**
27
34
  * The port number of a `--port` value. An invalid port is an error (before, it became 3000:
28
35
  * deep dive CLI-16).
@@ -1 +1 @@
1
- {"version":3,"file":"server-mode.d.ts","sourceRoot":"","sources":["../src/server-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IACvC,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AA6CD;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyG/E;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED,2CAA2C;AAC3C,eAAO,MAAM,iBAAiB,YAAI,MAAM,EAAE,WAAW,EAAE,MAAM,CAAU,CAAC;AAExE;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAM3E;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAUzD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAWzD"}
1
+ {"version":3,"file":"server-mode.d.ts","sourceRoot":"","sources":["../src/server-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAMjE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IACvC,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAuCD;;;GAGG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,CAAC,EAAE,sBAAsB,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAqFpH;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED,2CAA2C;AAC3C,eAAO,MAAM,iBAAiB,YAAI,MAAM,EAAE,WAAW,EAAE,MAAM,CAAU,CAAC;AAExE;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAM3E;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAUzD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAWzD"}
@@ -5,12 +5,16 @@
5
5
  * via HTTP. The server has the registry of mark (the module of each package, roadmap 3.1) and
6
6
  * the host policy of the core (roadmap 2.3): the token in the lockfile, and the topics of
7
7
  * `--events`. With `--fs-root`, each procedure keeps its paths in the root, or the root refuses it.
8
+ *
9
+ * The server is the background host of `mark` (decision D17): it runs under `run()` of
10
+ * `@mark1russell7/service` through `runProcedureHost()`, with the profile `daemon` (CLI-8). The
11
+ * runner owns the signals, the stop in stages and the exit. The lockfile is a dependency of the
12
+ * service: its connect writes it, and its close removes it after the listeners close.
8
13
  */
9
14
  import { print } from "./print.js";
10
15
  import { loadEcosystemRegistry } from "./ecosystem.js";
11
16
  import { randomBytes } from "node:crypto";
12
- import { writeLockfile, removeLockfileForPort, getLockfilePath, currentBuild } from "./lockfile.js";
13
- import { seconds } from "@procedures/client";
17
+ import { getLockfilePath, currentBuild } from "./lockfile.js";
14
18
  /**
15
19
  * Build transport configuration array
16
20
  */
@@ -38,9 +42,10 @@ function buildTransports(options) {
38
42
  return transports;
39
43
  }
40
44
  /**
41
- * Start CLI in server mode
45
+ * Start CLI in server mode. The promise ends when the lifecycle of the server ends. `run` gives
46
+ * the options of `run()`, for a test: a process port and a clock.
42
47
  */
43
- export async function startServerMode(options) {
48
+ export async function startServerMode(options, run) {
44
49
  const { port = 3000, verbose = false } = options;
45
50
  print.info("Starting CLI server mode...");
46
51
  // The registry of mark (roadmap 3.1): the module of each workspace package, with the server
@@ -66,42 +71,49 @@ export async function startServerMode(options) {
66
71
  // The bus is the global bus, which is also the ctx.bus of the procedures.
67
72
  const events = [...(options.events ?? [])];
68
73
  const { hostPolicy } = await import("@procedures/client");
69
- const { createPeer } = await import("@procedures/peer");
70
- const peer = await createPeer({
71
- id: `peer-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
72
- transports,
73
- registry,
74
- policy: hostPolicy({ token, events: { topics: events } }),
75
- });
76
- await peer.start();
77
- const result = {
78
- serverId: peer.id,
79
- endpoints: peer.getEndpoints(),
80
- procedureCount: peer.getServer().procedureCount,
81
- };
82
- // Write lockfile for client discovery. A client uses this server only from the same folder,
83
- // with the same build of mark, and when the health endpoint answers with this peer id.
84
- await writeLockfile({
85
- pid: process.pid,
86
- port,
87
- transport: options.transport ?? "http",
88
- endpoint: result.endpoints[0]?.address ?? `http://127.0.0.1:${port}/api`,
89
- startedAt: new Date().toISOString(),
90
- token,
91
- cwd: process.cwd(),
92
- build: currentBuild(),
93
- peerId: result.serverId,
94
- // A client uses this server only with the same --fs-root (or none)
95
- ...(fsRoot !== undefined ? { fsRoot } : {}),
74
+ const { peerHostOptions } = await import("@procedures/peer");
75
+ const { runProcedureHost } = await import("@procedures/server");
76
+ const id = `peer-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
77
+ // The lockfile for client discovery. A client uses this server only from the same folder,
78
+ // with the same build of mark, and when host.info answers its token with this peer id.
79
+ const shown = host === "0.0.0.0" ? "localhost" : host;
80
+ const endpoint = options.transport === "websocket" ? `ws://${shown}:${port}/ws` : `http://${shown}:${port}/api`;
81
+ const running = await runProcedureHost({
82
+ name: "mark-server",
83
+ mode: "background",
84
+ host: peerHostOptions({ id, transports, registry, policy: hostPolicy({ token, events: { topics: events } }) }, "procedures"),
85
+ lockfile: {
86
+ pid: process.pid,
87
+ port,
88
+ transport: options.transport ?? "http",
89
+ endpoint,
90
+ startedAt: new Date().toISOString(),
91
+ token,
92
+ cwd: process.cwd(),
93
+ build: currentBuild(),
94
+ peerId: id,
95
+ // A client uses this server only with the same --fs-root (or none)
96
+ ...(fsRoot !== undefined ? { fsRoot } : {}),
97
+ },
98
+ log: (line) => print.info(line),
99
+ ...(run ? { run } : {}),
96
100
  });
101
+ if (running.life.state !== "running") {
102
+ // The startup failed: the lifecycle stops the parts that started, and the process exits with 1
103
+ print.error("The server did not start:");
104
+ for (const error of running.life.errors)
105
+ print.error(` ${error}`);
106
+ await running.life.done;
107
+ return;
108
+ }
97
109
  print.success("\nCLI Server running!");
98
110
  print.info(` PID: ${process.pid}`);
99
- print.info(` Server ID: ${result.serverId}`);
100
- print.info(` Procedures: ${result.procedureCount}`);
111
+ print.info(` Server ID: ${running.host.id}`);
112
+ print.info(` Procedures: ${running.host.server.procedureCount}`);
101
113
  print.info(` Lockfile: ${getLockfilePath()}`);
102
114
  print.info("\nEndpoints:");
103
- for (const endpoint of result.endpoints) {
104
- print.info(` [${endpoint.type}] ${endpoint.address}`);
115
+ for (const each of running.host.info.endpoints()) {
116
+ print.info(` [${each.type}] ${each.address}`);
105
117
  }
106
118
  print.info(events.length > 0 ? `\nEvent topics (events.subscribe): ${events.join(", ")}` : "\nEvent topics: none (--events adds them)");
107
119
  if (fsRoot !== undefined) {
@@ -109,34 +121,8 @@ export async function startServerMode(options) {
109
121
  print.info(` Refused under the root: ${refusedUnderRoot?.length ?? 0} procedures that the root cannot confine`);
110
122
  }
111
123
  print.info("\nPress Ctrl+C to stop.");
112
- // Handle shutdown: the peer stops (its requests end and its ports close) before the process
113
- // exits, with a limit of 10 seconds. A second signal exits at once. Before, the process exited
114
- // without a stop (roadmap R5).
115
- let stopping = false;
116
- const cleanup = async () => {
117
- if (stopping)
118
- process.exit(1);
119
- stopping = true;
120
- print.info("\nStopping server...");
121
- removeLockfileForPort(port);
122
- const limit = setTimeout(() => process.exit(1), 10_000);
123
- limit.unref();
124
- try {
125
- // The calls in flight have 5 seconds to end (roadmap R14)
126
- await peer.stop({ grace: seconds(5) });
127
- process.exit(0);
128
- }
129
- catch (error) {
130
- print.error(`The server did not stop cleanly: ${error instanceof Error ? error.message : String(error)}`);
131
- process.exit(1);
132
- }
133
- };
134
- process.on("SIGINT", cleanup);
135
- process.on("SIGTERM", cleanup);
136
- // Keep the process alive
137
- await new Promise(() => {
138
- // Never resolves - keeps process running
139
- });
124
+ // A signal starts the stop in stages, and the runner ends the process (CLI-8)
125
+ await running.life.done;
140
126
  }
141
127
  /**
142
128
  * The port number of a `--port` value. An invalid port is an error (before, it became 3000:
@@ -1 +1 @@
1
- {"version":3,"file":"server-mode.js","sourceRoot":"","sources":["../src/server-mode.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server-mode.js","sourceRoot":"","sources":["../src/server-mode.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@procedures/mark",
4
- "version": "0.10.0",
4
+ "version": "0.12.0",
5
5
  "description": "mark: one CLI for every procedure package. It finds the procedures, parses flags by their Zod types, runs local or through a fast warm server, and asks for missing arguments.",
6
6
  "keywords": [
7
7
  "cli",
@@ -52,16 +52,16 @@
52
52
  },
53
53
  "dependencies": {
54
54
  "@clack/prompts": "^0.7.0",
55
- "@procedures/cli-run": "0.10.0",
56
- "@procedures/client": "0.10.0",
57
- "@procedures/lib": "0.10.0",
58
- "@procedures/mcp-dev-tools": "0.10.0",
59
- "@procedures/peer": "0.10.0",
60
- "@procedures/pnpm": "0.10.0",
61
- "@procedures/procedure": "0.10.0",
62
- "@procedures/server": "0.10.0",
63
- "@procedures/shell": "0.10.0",
64
- "@procedures/vitest": "0.10.0",
55
+ "@procedures/cli-run": "0.12.0",
56
+ "@procedures/client": "0.12.0",
57
+ "@procedures/lib": "0.12.0",
58
+ "@procedures/mcp-dev-tools": "0.12.0",
59
+ "@procedures/peer": "0.12.0",
60
+ "@procedures/pnpm": "0.12.0",
61
+ "@procedures/procedure": "0.12.0",
62
+ "@procedures/server": "0.12.0",
63
+ "@procedures/shell": "0.12.0",
64
+ "@procedures/vitest": "0.12.0",
65
65
  "chalk": "^5.3.0",
66
66
  "cli-table3": "^0.6.5",
67
67
  "ora": "^8.0.0",
@@ -70,44 +70,44 @@
70
70
  },
71
71
  "devDependencies": {
72
72
  "@mark1russell7/cue": "^1.0.0",
73
- "@procedures/archive": "0.10.0",
74
- "@procedures/bundle-assistant": "0.10.0",
75
- "@procedures/bundle-dev": "0.10.0",
76
- "@procedures/bundle-mcp": "0.10.0",
77
- "@procedures/claude-cli": "0.10.0",
78
- "@procedures/compiler": "0.10.0",
79
- "@procedures/cue": "0.10.0",
80
- "@procedures/dag": "0.10.0",
81
- "@procedures/docker": "0.10.0",
82
- "@procedures/env": "0.10.0",
83
- "@procedures/exif": "0.10.0",
84
- "@procedures/fs": "0.10.0",
85
- "@procedures/geo": "0.10.0",
86
- "@procedures/gh": "0.10.0",
87
- "@procedures/git": "0.10.0",
88
- "@procedures/http": "0.10.0",
89
- "@procedures/ics": "0.10.0",
90
- "@procedures/ios-backup": "0.10.0",
91
- "@procedures/json": "0.10.0",
92
- "@procedures/llm": "0.10.0",
93
- "@procedures/mail": "0.10.0",
94
- "@procedures/mongo": "0.10.0",
95
- "@procedures/node": "0.10.0",
96
- "@procedures/notify": "0.10.0",
97
- "@procedures/npm": "0.10.0",
98
- "@procedures/pdf": "0.10.0",
99
- "@procedures/privacy-scan": "0.10.0",
100
- "@procedures/restic": "0.10.0",
101
- "@procedures/s3": "0.10.0",
102
- "@procedures/schedule": "0.10.0",
103
- "@procedures/snapshot": "0.10.0",
104
- "@procedures/splay": "0.10.0",
105
- "@procedures/sqlite": "0.10.0",
106
- "@procedures/store": "0.10.0",
107
- "@procedures/systems": "0.10.0",
108
- "@procedures/tailscale": "0.10.0",
109
- "@procedures/vite": "0.10.0",
110
- "@procedures/weather": "0.10.0",
73
+ "@procedures/archive": "0.12.0",
74
+ "@procedures/bundle-assistant": "0.12.0",
75
+ "@procedures/bundle-dev": "0.12.0",
76
+ "@procedures/bundle-mcp": "0.12.0",
77
+ "@procedures/claude-cli": "0.12.0",
78
+ "@procedures/compiler": "0.12.0",
79
+ "@procedures/cue": "0.12.0",
80
+ "@procedures/dag": "0.12.0",
81
+ "@procedures/docker": "0.12.0",
82
+ "@procedures/env": "0.12.0",
83
+ "@procedures/exif": "0.12.0",
84
+ "@procedures/fs": "0.12.0",
85
+ "@procedures/geo": "0.12.0",
86
+ "@procedures/gh": "0.12.0",
87
+ "@procedures/git": "0.12.0",
88
+ "@procedures/http": "0.12.0",
89
+ "@procedures/ics": "0.12.0",
90
+ "@procedures/ios-backup": "0.12.0",
91
+ "@procedures/json": "0.12.0",
92
+ "@procedures/llm": "0.12.0",
93
+ "@procedures/mail": "0.12.0",
94
+ "@procedures/mongo": "0.12.0",
95
+ "@procedures/node": "0.12.0",
96
+ "@procedures/notify": "0.12.0",
97
+ "@procedures/npm": "0.12.0",
98
+ "@procedures/pdf": "0.12.0",
99
+ "@procedures/privacy-scan": "0.12.0",
100
+ "@procedures/restic": "0.12.0",
101
+ "@procedures/s3": "0.12.0",
102
+ "@procedures/schedule": "0.12.0",
103
+ "@procedures/snapshot": "0.12.0",
104
+ "@procedures/splay": "0.12.0",
105
+ "@procedures/sqlite": "0.12.0",
106
+ "@procedures/store": "0.12.0",
107
+ "@procedures/systems": "0.12.0",
108
+ "@procedures/tailscale": "0.12.0",
109
+ "@procedures/vite": "0.12.0",
110
+ "@procedures/weather": "0.12.0",
111
111
  "@types/node": "^22.0.0",
112
112
  "fast-check": "^4.10.2",
113
113
  "typescript": "^7.0.2",
@@ -5,13 +5,18 @@
5
5
  * via HTTP. The server has the registry of mark (the module of each package, roadmap 3.1) and
6
6
  * the host policy of the core (roadmap 2.3): the token in the lockfile, and the topics of
7
7
  * `--events`. With `--fs-root`, each procedure keeps its paths in the root, or the root refuses it.
8
+ *
9
+ * The server is the background host of `mark` (decision D17): it runs under `run()` of
10
+ * `@mark1russell7/service` through `runProcedureHost()`, with the profile `daemon` (CLI-8). The
11
+ * runner owns the signals, the stop in stages and the exit. The lockfile is a dependency of the
12
+ * service: its connect writes it, and its close removes it after the listeners close.
8
13
  */
9
14
 
15
+ import type { ProcedureHostRunConfig } from "@procedures/server";
10
16
  import { print } from "./print.js";
11
17
  import { loadEcosystemRegistry } from "./ecosystem.js";
12
18
  import { randomBytes } from "node:crypto";
13
- import { writeLockfile, removeLockfileForPort, getLockfilePath, currentBuild } from "./lockfile.js";
14
- import { seconds } from "@procedures/client";
19
+ import { getLockfilePath, currentBuild } from "./lockfile.js";
15
20
 
16
21
  export interface ServerModeOptions {
17
22
  port: number;
@@ -27,12 +32,6 @@ export interface ServerModeOptions {
27
32
  fsRoot?: string | undefined;
28
33
  }
29
34
 
30
- interface ServerCreateResult {
31
- serverId: string;
32
- endpoints: Array<{ type: string; address: string }>;
33
- procedureCount: number;
34
- }
35
-
36
35
  /**
37
36
  * Build transport configuration array
38
37
  */
@@ -71,9 +70,10 @@ function buildTransports(options: ServerModeOptions) {
71
70
  }
72
71
 
73
72
  /**
74
- * Start CLI in server mode
73
+ * Start CLI in server mode. The promise ends when the lifecycle of the server ends. `run` gives
74
+ * the options of `run()`, for a test: a process port and a clock.
75
75
  */
76
- export async function startServerMode(options: ServerModeOptions): Promise<void> {
76
+ export async function startServerMode(options: ServerModeOptions, run?: ProcedureHostRunConfig["run"]): Promise<void> {
77
77
  const { port = 3000, verbose = false } = options;
78
78
 
79
79
  print.info("Starting CLI server mode...");
@@ -104,44 +104,50 @@ export async function startServerMode(options: ServerModeOptions): Promise<void>
104
104
  // The bus is the global bus, which is also the ctx.bus of the procedures.
105
105
  const events = [...(options.events ?? [])];
106
106
  const { hostPolicy } = await import("@procedures/client");
107
- const { createPeer } = await import("@procedures/peer");
108
- const peer = await createPeer({
109
- id: `peer-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
110
- transports,
111
- registry,
112
- policy: hostPolicy({ token, events: { topics: events } }),
113
- });
114
- await peer.start();
115
- const result: ServerCreateResult = {
116
- serverId: peer.id,
117
- endpoints: peer.getEndpoints(),
118
- procedureCount: peer.getServer().procedureCount,
119
- };
120
-
121
- // Write lockfile for client discovery. A client uses this server only from the same folder,
122
- // with the same build of mark, and when the health endpoint answers with this peer id.
123
- await writeLockfile({
124
- pid: process.pid,
125
- port,
126
- transport: options.transport ?? "http",
127
- endpoint: result.endpoints[0]?.address ?? `http://127.0.0.1:${port}/api`,
128
- startedAt: new Date().toISOString(),
129
- token,
130
- cwd: process.cwd(),
131
- build: currentBuild(),
132
- peerId: result.serverId,
133
- // A client uses this server only with the same --fs-root (or none)
134
- ...(fsRoot !== undefined ? { fsRoot } : {}),
107
+ const { peerHostOptions } = await import("@procedures/peer");
108
+ const { runProcedureHost } = await import("@procedures/server");
109
+ const id = `peer-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
110
+
111
+ // The lockfile for client discovery. A client uses this server only from the same folder,
112
+ // with the same build of mark, and when host.info answers its token with this peer id.
113
+ const shown = host === "0.0.0.0" ? "localhost" : host;
114
+ const endpoint = options.transport === "websocket" ? `ws://${shown}:${port}/ws` : `http://${shown}:${port}/api`;
115
+ const running = await runProcedureHost({
116
+ name: "mark-server",
117
+ mode: "background",
118
+ host: peerHostOptions({ id, transports, registry, policy: hostPolicy({ token, events: { topics: events } }) }, "procedures"),
119
+ lockfile: {
120
+ pid: process.pid,
121
+ port,
122
+ transport: options.transport ?? "http",
123
+ endpoint,
124
+ startedAt: new Date().toISOString(),
125
+ token,
126
+ cwd: process.cwd(),
127
+ build: currentBuild(),
128
+ peerId: id,
129
+ // A client uses this server only with the same --fs-root (or none)
130
+ ...(fsRoot !== undefined ? { fsRoot } : {}),
131
+ },
132
+ log: (line) => print.info(line),
133
+ ...(run ? { run } : {}),
135
134
  });
135
+ if (running.life.state !== "running") {
136
+ // The startup failed: the lifecycle stops the parts that started, and the process exits with 1
137
+ print.error("The server did not start:");
138
+ for (const error of running.life.errors) print.error(` ${error}`);
139
+ await running.life.done;
140
+ return;
141
+ }
136
142
 
137
143
  print.success("\nCLI Server running!");
138
144
  print.info(` PID: ${process.pid}`);
139
- print.info(` Server ID: ${result.serverId}`);
140
- print.info(` Procedures: ${result.procedureCount}`);
145
+ print.info(` Server ID: ${running.host.id}`);
146
+ print.info(` Procedures: ${running.host.server.procedureCount}`);
141
147
  print.info(` Lockfile: ${getLockfilePath()}`);
142
148
  print.info("\nEndpoints:");
143
- for (const endpoint of result.endpoints) {
144
- print.info(` [${endpoint.type}] ${endpoint.address}`);
149
+ for (const each of running.host.info.endpoints()) {
150
+ print.info(` [${each.type}] ${each.address}`);
145
151
  }
146
152
  print.info(events.length > 0 ? `\nEvent topics (events.subscribe): ${events.join(", ")}` : "\nEvent topics: none (--events adds them)");
147
153
  if (fsRoot !== undefined) {
@@ -150,34 +156,8 @@ export async function startServerMode(options: ServerModeOptions): Promise<void>
150
156
  }
151
157
  print.info("\nPress Ctrl+C to stop.");
152
158
 
153
- // Handle shutdown: the peer stops (its requests end and its ports close) before the process
154
- // exits, with a limit of 10 seconds. A second signal exits at once. Before, the process exited
155
- // without a stop (roadmap R5).
156
- let stopping = false;
157
- const cleanup = async () => {
158
- if (stopping) process.exit(1);
159
- stopping = true;
160
- print.info("\nStopping server...");
161
- removeLockfileForPort(port);
162
- const limit = setTimeout(() => process.exit(1), 10_000);
163
- limit.unref();
164
- try {
165
- // The calls in flight have 5 seconds to end (roadmap R14)
166
- await peer.stop({ grace: seconds(5) });
167
- process.exit(0);
168
- } catch (error) {
169
- print.error(`The server did not stop cleanly: ${error instanceof Error ? error.message : String(error)}`);
170
- process.exit(1);
171
- }
172
- };
173
-
174
- process.on("SIGINT", cleanup);
175
- process.on("SIGTERM", cleanup);
176
-
177
- // Keep the process alive
178
- await new Promise(() => {
179
- // Never resolves - keeps process running
180
- });
159
+ // A signal starts the stop in stages, and the runner ends the process (CLI-8)
160
+ await running.life.done;
181
161
  }
182
162
 
183
163
  /**