@procedures/mark 0.2.2 → 0.3.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 +1 @@
1
- {"version":3,"file":"server-mode.d.ts","sourceRoot":"","sources":["../src/server-mode.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,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;CACnB;AA6CD;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiF/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;;;;;;GAMG;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;CACnB;AA6CD;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+F/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"}
@@ -9,6 +9,7 @@ import { print } from "./print.js";
9
9
  import { loadEcosystemRegistry } from "./ecosystem.js";
10
10
  import { randomBytes } from "node:crypto";
11
11
  import { writeLockfile, removeLockfileForPort, getLockfilePath, currentBuild } from "./lockfile.js";
12
+ import { seconds } from "@procedures/client";
12
13
  /**
13
14
  * Build transport configuration array
14
15
  */
@@ -97,11 +98,27 @@ export async function startServerMode(options) {
97
98
  print.info(` [${endpoint.type}] ${endpoint.address}`);
98
99
  }
99
100
  print.info("\nPress Ctrl+C to stop.");
100
- // Handle shutdown
101
+ // Handle shutdown: the peer stops (its requests end and its ports close) before the process
102
+ // exits, with a limit of 10 seconds. A second signal exits at once. Before, the process exited
103
+ // without a stop (roadmap R5).
104
+ let stopping = false;
101
105
  const cleanup = async () => {
106
+ if (stopping)
107
+ process.exit(1);
108
+ stopping = true;
102
109
  print.info("\nStopping server...");
103
110
  removeLockfileForPort(port);
104
- process.exit(0);
111
+ const limit = setTimeout(() => process.exit(1), 10_000);
112
+ limit.unref();
113
+ try {
114
+ // The calls in flight have 5 seconds to end (roadmap R14)
115
+ await peer.stop({ grace: seconds(5) });
116
+ process.exit(0);
117
+ }
118
+ catch (error) {
119
+ print.error(`The server did not stop cleanly: ${error instanceof Error ? error.message : String(error)}`);
120
+ process.exit(1);
121
+ }
105
122
  };
106
123
  process.on("SIGINT", cleanup);
107
124
  process.on("SIGTERM", cleanup);
@@ -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.2.2",
4
+ "version": "0.3.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,39 +52,59 @@
52
52
  },
53
53
  "dependencies": {
54
54
  "@clack/prompts": "^0.7.0",
55
- "@procedures/client": "0.2.2",
56
- "@procedures/cli-run": "0.2.2",
57
- "@procedures/lib": "0.2.2",
58
- "@procedures/pnpm": "0.2.2",
59
- "@procedures/procedure": "0.2.2",
60
- "@procedures/peer": "0.2.2",
61
- "@procedures/shell": "0.2.2",
62
- "@procedures/vitest": "0.2.2",
55
+ "@procedures/cli-run": "0.3.0",
56
+ "@procedures/client": "0.3.0",
57
+ "@procedures/lib": "0.3.0",
58
+ "@procedures/mcp-dev-tools": "0.3.0",
59
+ "@procedures/peer": "0.3.0",
60
+ "@procedures/pnpm": "0.3.0",
61
+ "@procedures/procedure": "0.3.0",
62
+ "@procedures/server": "0.3.0",
63
+ "@procedures/shell": "0.3.0",
64
+ "@procedures/vitest": "0.3.0",
63
65
  "chalk": "^5.3.0",
64
66
  "cli-table3": "^0.6.5",
65
67
  "ora": "^8.0.0",
66
68
  "tslib": "^2.8.1",
67
- "zod": "^4.6.5",
68
- "@procedures/server": "0.2.2",
69
- "@procedures/mcp-dev-tools": "0.2.2"
69
+ "zod": "^4.6.5"
70
70
  },
71
71
  "devDependencies": {
72
- "@procedures/bundle-dev": "0.2.2",
73
- "@procedures/bundle-mcp": "0.2.2",
74
- "@procedures/cue": "0.2.2",
75
- "@procedures/docker": "0.2.2",
76
- "@procedures/fs": "0.2.2",
77
- "@procedures/git": "0.2.2",
78
- "@procedures/mongo": "0.2.2",
79
- "@procedures/node": "0.2.2",
80
- "@procedures/s3": "0.2.2",
81
- "@procedures/snapshot": "0.2.2",
82
- "@procedures/splay": "0.2.2",
83
- "@procedures/sqlite": "0.2.2",
84
- "@procedures/store": "0.2.2",
85
- "@procedures/vite": "0.2.2",
86
72
  "@mark1russell7/cue": "^1.0.0",
73
+ "@procedures/archive": "0.3.0",
74
+ "@procedures/bundle-assistant": "0.3.0",
75
+ "@procedures/bundle-dev": "0.3.0",
76
+ "@procedures/bundle-mcp": "0.3.0",
77
+ "@procedures/compiler": "0.3.0",
78
+ "@procedures/cue": "0.3.0",
79
+ "@procedures/docker": "0.3.0",
80
+ "@procedures/env": "0.3.0",
81
+ "@procedures/exif": "0.3.0",
82
+ "@procedures/fs": "0.3.0",
83
+ "@procedures/geo": "0.3.0",
84
+ "@procedures/gh": "0.3.0",
85
+ "@procedures/git": "0.3.0",
86
+ "@procedures/http": "0.3.0",
87
+ "@procedures/ics": "0.3.0",
88
+ "@procedures/json": "0.3.0",
89
+ "@procedures/llm": "0.3.0",
90
+ "@procedures/mail": "0.3.0",
91
+ "@procedures/mongo": "0.3.0",
92
+ "@procedures/node": "0.3.0",
93
+ "@procedures/notify": "0.3.0",
94
+ "@procedures/npm": "0.3.0",
95
+ "@procedures/restic": "0.3.0",
96
+ "@procedures/s3": "0.3.0",
97
+ "@procedures/schedule": "0.3.0",
98
+ "@procedures/snapshot": "0.3.0",
99
+ "@procedures/splay": "0.3.0",
100
+ "@procedures/sqlite": "0.3.0",
101
+ "@procedures/store": "0.3.0",
102
+ "@procedures/systems": "0.3.0",
103
+ "@procedures/tailscale": "0.3.0",
104
+ "@procedures/vite": "0.3.0",
105
+ "@procedures/weather": "0.3.0",
87
106
  "@types/node": "^22.0.0",
107
+ "fast-check": "^4.10.2",
88
108
  "typescript": "^7.0.2",
89
109
  "vitest": "^5.0.3"
90
110
  },
package/src/cli.ts CHANGED
@@ -169,6 +169,21 @@ export interface ExecuteOptions {
169
169
  ask?: Asker;
170
170
  }
171
171
 
172
+ /**
173
+ * A signal that aborts on the first Ctrl+C while a command runs in this process (roadmap R14):
174
+ * the procedure gets the abort (a shell command stops its process tree). A second Ctrl+C exits
175
+ * at once. `release()` removes the listener when the command ends.
176
+ */
177
+ function interruptSignal(): { signal: AbortSignal; release: () => void } {
178
+ const controller = new AbortController();
179
+ const onInterrupt = (): void => {
180
+ if (controller.signal.aborted) process.exit(130);
181
+ controller.abort();
182
+ };
183
+ process.on("SIGINT", onInterrupt);
184
+ return { signal: controller.signal, release: () => process.off("SIGINT", onInterrupt) };
185
+ }
186
+
172
187
  /**
173
188
  * Initialize the CLI context (load ecosystem, create client)
174
189
  * This is the expensive part (~4s). Call once, reuse many times.
@@ -269,15 +284,18 @@ export async function executeArgs(
269
284
  fail('--json needs a procedure reference: an object with "$proc".');
270
285
  return;
271
286
  }
287
+ const interrupt = interruptSignal();
272
288
  try {
273
289
  const { client } = await local();
274
- const result = await client.exec(parsedJson as Parameters<typeof client.exec>[0]);
290
+ const result = await client.exec(parsedJson as Parameters<typeof client.exec>[0], undefined, { signal: interrupt.signal });
275
291
  formatOutput(print as unknown as Print, result, "json");
276
292
  if (failureOf(result)) {
277
293
  process.exitCode = 1;
278
294
  }
279
295
  } catch (error) {
280
296
  fail(`Error: ${error instanceof Error ? error.message : String(error)}`);
297
+ } finally {
298
+ interrupt.release();
281
299
  }
282
300
  return;
283
301
  }
@@ -399,10 +417,15 @@ export async function executeArgs(
399
417
  // A streaming procedure gives many items: print each one when it arrives. A
400
418
  // request/response procedure gives one item, so its output does not change.
401
419
  let items = 0;
402
- for await (const item of client.stream(method, validated)) {
403
- if (spinner && items === 0) spinner.stop();
404
- items++;
405
- printItem(item);
420
+ const interrupt = interruptSignal();
421
+ try {
422
+ for await (const item of client.stream(method, validated, { signal: interrupt.signal })) {
423
+ if (spinner && items === 0) spinner.stop();
424
+ items++;
425
+ printItem(item);
426
+ }
427
+ } finally {
428
+ interrupt.release();
406
429
  }
407
430
 
408
431
  if (spinner) {
@@ -420,7 +443,8 @@ export async function executeArgs(
420
443
 
421
444
  const MCP_HELP = `Usage: mark mcp [options]
422
445
 
423
- Start the dev-tools MCP server over stdio (the server of Claude Code's MCP configuration).
446
+ Start the dev-tools MCP server over stdio (the server of Claude Code's MCP configuration), or
447
+ over Streamable HTTP with --http.
424
448
  It has a registry of its own, from the modules of its bundles, and the host policy of an MCP
425
449
  server: only the tools of the bundles, strict nested calls, and a time limit for each call.
426
450
 
@@ -428,6 +452,9 @@ Options:
428
452
  --bundles <list> Comma-separated bundles (default: MCP_BUNDLES, or @procedures/bundle-mcp)
429
453
  --tool-timeout <ms> The time limit of each tool call (default: MCP_TOOL_TIMEOUT_MS, or 600000)
430
454
  --read-only Only the tools that change nothing (default: MCP_READ_ONLY)
455
+ --http <port> Serve over Streamable HTTP on this port, not over stdio (MCP_HTTP_PORT)
456
+ --host <host> The address of --http (default: 127.0.0.1, only this computer)
457
+ --token <token> A secret that each HTTP request must send as a bearer token
431
458
  --debug Write debug lines to stderr
432
459
  -h, --help Show this help
433
460
 
@@ -461,6 +488,14 @@ async function startMcp(args: string[]): Promise<void> {
461
488
  config.toolTimeoutMs = ms;
462
489
  } else if (name === "--read-only") {
463
490
  config.readOnly = true;
491
+ } else if (name === "--http") {
492
+ const port = Number(value());
493
+ if (!Number.isInteger(port) || port < 0 || port > 65535) throw new Error("--http needs a port number");
494
+ config.http = { ...config.http, port };
495
+ } else if (name === "--host") {
496
+ config.http = { port: config.http?.port ?? 3003, ...config.http, host: value() };
497
+ } else if (name === "--token") {
498
+ config.http = { port: config.http?.port ?? 3003, ...config.http, token: value() };
464
499
  } else if (name === "--debug") {
465
500
  config.debug = true;
466
501
  } else {
@@ -530,7 +565,8 @@ async function run(argv: string[]): Promise<void> {
530
565
  await runServer(commandArgs, { resolveFrom: [process.cwd(), markDir] });
531
566
  return;
532
567
  }
533
- if (command === "mcp" && commandArgs.every((arg) => arg.startsWith("-"))) {
568
+ // `mark mcp` and `mark mcp --option value`: the server. `mark mcp <procedure>`: an mcp.* command.
569
+ if (command === "mcp" && (commandArgs.length === 0 || commandArgs[0]!.startsWith("-"))) {
534
570
  await startMcp(commandArgs);
535
571
  return;
536
572
  }
package/src/manifest.ts CHANGED
@@ -17,7 +17,7 @@ import { createHash } from "node:crypto";
17
17
  import * as fs from "node:fs";
18
18
  import * as path from "node:path";
19
19
  import { fileURLToPath } from "node:url";
20
- import { jsonSchemaOf, type AnyProcedure } from "@procedures/client";
20
+ import { describeProcedureEntry, jsonSchemaOf, type AnyProcedure, type ProcedureEntry } from "@procedures/client";
21
21
  import { discoverFromEcosystem, findWorkspaceRoot } from "./ecosystem.js";
22
22
  import { extractSchemaFields, resultFieldsOfSchema, type CLIMeta, type SchemaFieldInfo } from "./parse.js";
23
23
 
@@ -96,26 +96,30 @@ export function computeFingerprint(root: string | null = findWorkspaceRoot(), ma
96
96
  return createHash("sha256").update(parts.join("\n")).digest("hex");
97
97
  }
98
98
 
99
- /** The CLI metadata of a procedure: only the fields that mark reads, so the manifest is plain JSON */
100
- function cliMetadata(procedure: AnyProcedure): CLIMeta {
101
- const meta = (procedure.metadata ?? {}) as Record<string, unknown>;
99
+ /**
100
+ * The CLI metadata of a procedure: only the fields that mark reads, so the manifest is plain JSON.
101
+ * It comes from the one description of the core (roadmap R17).
102
+ */
103
+ function cliMetadata(entry: ProcedureEntry): CLIMeta {
102
104
  const result: CLIMeta = {};
103
- if (typeof meta["description"] === "string") result.description = meta["description"];
104
- if (Array.isArray(meta["args"])) result.args = (meta["args"] as unknown[]).filter((arg): arg is string => typeof arg === "string");
105
- if (meta["shorts"] && typeof meta["shorts"] === "object") result.shorts = { ...(meta["shorts"] as Record<string, string>) };
106
- if (typeof meta["output"] === "string") result.output = meta["output"] as NonNullable<CLIMeta["output"]>;
107
- if (typeof meta["interactive"] === "boolean") result.interactive = meta["interactive"];
105
+ if (entry.description !== undefined) result.description = entry.description;
106
+ if (entry.cli?.args) result.args = entry.cli.args.filter((arg): arg is string => typeof arg === "string");
107
+ if (entry.cli?.shorts) result.shorts = { ...entry.cli.shorts };
108
+ if (entry.cli?.output !== undefined) result.output = entry.cli.output as NonNullable<CLIMeta["output"]>;
109
+ if (entry.cli?.interactive !== undefined) result.interactive = entry.cli.interactive;
108
110
  return result;
109
111
  }
110
112
 
111
113
  /** The commands of the manifest, from the procedures of the registry */
112
114
  export async function commandsOf(procedures: readonly AnyProcedure[]): Promise<ManifestCommand[]> {
113
115
  return procedures.map((procedure) => {
114
- // One JSON Schema for each command: the fields come from it too (roadmap 2.1)
116
+ // One JSON Schema for each command: the fields come from it too (roadmap 2.1). The schema and
117
+ // the CLI metadata come from the one manifest type of the core (roadmap R17).
118
+ const entry = describeProcedureEntry(procedure, { schemas: false });
115
119
  const inputSchema = jsonSchemaOf(procedure.input) ?? {};
116
120
  return {
117
121
  path: [...procedure.path],
118
- metadata: cliMetadata(procedure),
122
+ metadata: cliMetadata(entry),
119
123
  fields: extractSchemaFields(inputSchema),
120
124
  inputSchema,
121
125
  resultFields: resultFieldsOfSchema(procedure.output),
@@ -10,6 +10,7 @@ import { print } from "./print.js";
10
10
  import { loadEcosystemRegistry } from "./ecosystem.js";
11
11
  import { randomBytes } from "node:crypto";
12
12
  import { writeLockfile, removeLockfileForPort, getLockfilePath, currentBuild } from "./lockfile.js";
13
+ import { seconds } from "@procedures/client";
13
14
 
14
15
  export interface ServerModeOptions {
15
16
  port: number;
@@ -131,11 +132,25 @@ export async function startServerMode(options: ServerModeOptions): Promise<void>
131
132
  }
132
133
  print.info("\nPress Ctrl+C to stop.");
133
134
 
134
- // Handle shutdown
135
+ // Handle shutdown: the peer stops (its requests end and its ports close) before the process
136
+ // exits, with a limit of 10 seconds. A second signal exits at once. Before, the process exited
137
+ // without a stop (roadmap R5).
138
+ let stopping = false;
135
139
  const cleanup = async () => {
140
+ if (stopping) process.exit(1);
141
+ stopping = true;
136
142
  print.info("\nStopping server...");
137
143
  removeLockfileForPort(port);
138
- process.exit(0);
144
+ const limit = setTimeout(() => process.exit(1), 10_000);
145
+ limit.unref();
146
+ try {
147
+ // The calls in flight have 5 seconds to end (roadmap R14)
148
+ await peer.stop({ grace: seconds(5) });
149
+ process.exit(0);
150
+ } catch (error) {
151
+ print.error(`The server did not stop cleanly: ${error instanceof Error ? error.message : String(error)}`);
152
+ process.exit(1);
153
+ }
139
154
  };
140
155
 
141
156
  process.on("SIGINT", cleanup);