@pattern-js/runtime-node 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +70 -0
  3. package/dist/bin/pattern.d.ts +20 -0
  4. package/dist/bin/pattern.d.ts.map +1 -0
  5. package/dist/bin/pattern.js +365 -0
  6. package/dist/bin/pattern.js.map +1 -0
  7. package/dist/cli.d.ts +21 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +75 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/filesystem.d.ts +38 -0
  12. package/dist/filesystem.d.ts.map +1 -0
  13. package/dist/filesystem.js +59 -0
  14. package/dist/filesystem.js.map +1 -0
  15. package/dist/http.d.ts +94 -0
  16. package/dist/http.d.ts.map +1 -0
  17. package/dist/http.js +799 -0
  18. package/dist/http.js.map +1 -0
  19. package/dist/index.d.ts +21 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +23 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/load/generator.d.ts +19 -0
  24. package/dist/load/generator.d.ts.map +1 -0
  25. package/dist/load/generator.js +94 -0
  26. package/dist/load/generator.js.map +1 -0
  27. package/dist/load/index.d.ts +43 -0
  28. package/dist/load/index.d.ts.map +1 -0
  29. package/dist/load/index.js +87 -0
  30. package/dist/load/index.js.map +1 -0
  31. package/dist/load/recorder.d.ts +36 -0
  32. package/dist/load/recorder.d.ts.map +1 -0
  33. package/dist/load/recorder.js +106 -0
  34. package/dist/load/recorder.js.map +1 -0
  35. package/dist/load/report.d.ts +28 -0
  36. package/dist/load/report.d.ts.map +1 -0
  37. package/dist/load/report.js +84 -0
  38. package/dist/load/report.js.map +1 -0
  39. package/dist/load/types.d.ts +85 -0
  40. package/dist/load/types.d.ts.map +1 -0
  41. package/dist/load/types.js +51 -0
  42. package/dist/load/types.js.map +1 -0
  43. package/dist/mods.d.ts +23 -0
  44. package/dist/mods.d.ts.map +1 -0
  45. package/dist/mods.js +48 -0
  46. package/dist/mods.js.map +1 -0
  47. package/dist/project.d.ts +94 -0
  48. package/dist/project.d.ts.map +1 -0
  49. package/dist/project.js +168 -0
  50. package/dist/project.js.map +1 -0
  51. package/dist/schedule.d.ts +33 -0
  52. package/dist/schedule.d.ts.map +1 -0
  53. package/dist/schedule.js +132 -0
  54. package/dist/schedule.js.map +1 -0
  55. package/dist/trace/index.d.ts +32 -0
  56. package/dist/trace/index.d.ts.map +1 -0
  57. package/dist/trace/index.js +48 -0
  58. package/dist/trace/index.js.map +1 -0
  59. package/dist/trace/memory.d.ts +83 -0
  60. package/dist/trace/memory.d.ts.map +1 -0
  61. package/dist/trace/memory.js +260 -0
  62. package/dist/trace/memory.js.map +1 -0
  63. package/dist/trace/sqlite.d.ts +80 -0
  64. package/dist/trace/sqlite.d.ts.map +1 -0
  65. package/dist/trace/sqlite.js +344 -0
  66. package/dist/trace/sqlite.js.map +1 -0
  67. package/dist/worker/entry.d.ts +16 -0
  68. package/dist/worker/entry.d.ts.map +1 -0
  69. package/dist/worker/entry.js +135 -0
  70. package/dist/worker/entry.js.map +1 -0
  71. package/dist/worker-pool.d.ts +49 -0
  72. package/dist/worker-pool.d.ts.map +1 -0
  73. package/dist/worker-pool.js +203 -0
  74. package/dist/worker-pool.js.map +1 -0
  75. package/dist/ws-registry.d.ts +39 -0
  76. package/dist/ws-registry.d.ts.map +1 -0
  77. package/dist/ws-registry.js +99 -0
  78. package/dist/ws-registry.js.map +1 -0
  79. package/dist/ws.d.ts +72 -0
  80. package/dist/ws.d.ts.map +1 -0
  81. package/dist/ws.js +236 -0
  82. package/dist/ws.js.map +1 -0
  83. package/package.json +60 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pattern contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # @pattern-js/runtime-node
2
+
3
+ The Node runtime adapter for [Pattern](../../README.md). Thin by design — it binds
4
+ external sources to boundary triggers and provides isolation. All platform code
5
+ lives here so `@pattern-js/core` stays runtime-neutral.
6
+
7
+ ```bash
8
+ npm install @pattern-js/core @pattern-js/runtime-node
9
+ ```
10
+
11
+ ## Project loader (recommended)
12
+
13
+ ```ts
14
+ import { loadProject } from "@pattern-js/runtime-node";
15
+
16
+ const { engine, start } = await loadProject(); // reads pattern.config.json
17
+ const { ports } = await start(); // derives routes from workflows
18
+ ```
19
+
20
+ `loadProject` installs mods, loads workflow `.json` files, and returns a ready
21
+ HTTP host. See [projects & mods](../mod-docs/docs/guides/projects-and-mods.md).
22
+
23
+ ## Hosts
24
+
25
+ Routing is **declarative**: the HTTP host derives routes from the
26
+ `boundary.http.request` nodes of registered workflows (method/path/port/cors/
27
+ body+query JSON-Schema all in config). No programmatic route table.
28
+
29
+ ```ts
30
+ import { Engine } from "@pattern-js/core";
31
+ import { createHttpHost } from "@pattern-js/runtime-node";
32
+
33
+ const engine = new Engine();
34
+ engine.registerWorkflow(api); // route declared inside the workflow
35
+ const host = createHttpHost(engine, { defaultPort: 3000 });
36
+ const { ports } = await host.start(); // re-derives live as workflows change
37
+ ```
38
+
39
+ | Host | Binds | Out-gate |
40
+ |------|-------|----------|
41
+ | `createHttpHost` | `boundary.http.request` (declarative routes) | `boundary.http.response` (`buffered`/`sse`/`chunked`) |
42
+ | `createWsHost` | `boundary.ws.message` / `open` / `close` | `boundary.ws.send` |
43
+ | `runCli` | `boundary.cli` | `boundary.cli.exit` |
44
+ | `createScheduleHost` | `boundary.schedule` (interval or 5-field cron) | result discarded/traced |
45
+
46
+ ## Isolation: worker-thread pool
47
+
48
+ A `RunTransport` that runs each workflow on a `node:worker_threads` worker — a
49
+ drop-in for the in-process transport. Streamed out-gate results are reconstructed
50
+ on the host; cancellation crosses the seam.
51
+
52
+ ```ts
53
+ import { WorkerPoolTransport } from "@pattern-js/runtime-node";
54
+ const engine = new Engine({ transport: new WorkerPoolTransport({ size: 4 }) });
55
+ ```
56
+
57
+ ## Also here
58
+
59
+ - **`NodeConnectionRegistry`** — `ConnectionRegistry` bound to live WebSocket sockets (rooms, broadcast, streamed sends).
60
+ - **Trace sinks** — `jsonlTraceSink(path)` and `sqliteTraceSink(path)` for persistence (core only emits).
61
+ - **`loadMods(engine, specifiers)`** — load external plugin mods by module specifier.
62
+ - **`pattern` CLI** — `pattern graph|validate|dev`.
63
+
64
+ ## CLI
65
+
66
+ ```bash
67
+ pattern graph workflow.json # render the graph in the terminal
68
+ pattern validate workflow.json # located, human-readable validation errors
69
+ pattern dev [entry] # run an entry with file-watch hot-reload
70
+ ```
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `pattern` — the dev CLI (§15).
4
+ *
5
+ * pattern ops [query] List/inspect every op the project can use.
6
+ * pattern graph <file.json> Validate a workflow and print its graph.
7
+ * pattern validate <file> Validate a workflow document; report issues.
8
+ * pattern dev [entry] Run an entry with file-watch hot-reload.
9
+ *
10
+ * `ops`/`graph`/`validate` are **project-aware**: when a `pattern.config.json`
11
+ * is present in the cwd its mods are loaded first, so app-local and npm mod ops
12
+ * (`app.*`, `admin.*`, …) resolve exactly as they will at runtime. This is the
13
+ * terminal ground truth — coding agents are told to consult it instead of
14
+ * guessing op names (see the scaffolded AGENTS.md).
15
+ *
16
+ * `dev` shells out to `node --watch` (Node ≥20 runs .ts via type-stripping on
17
+ * recent versions).
18
+ */
19
+ export {};
20
+ //# sourceMappingURL=pattern.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern.d.ts","sourceRoot":"","sources":["../../src/bin/pattern.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;GAgBG"}
@@ -0,0 +1,365 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `pattern` — the dev CLI (§15).
4
+ *
5
+ * pattern ops [query] List/inspect every op the project can use.
6
+ * pattern graph <file.json> Validate a workflow and print its graph.
7
+ * pattern validate <file> Validate a workflow document; report issues.
8
+ * pattern dev [entry] Run an entry with file-watch hot-reload.
9
+ *
10
+ * `ops`/`graph`/`validate` are **project-aware**: when a `pattern.config.json`
11
+ * is present in the cwd its mods are loaded first, so app-local and npm mod ops
12
+ * (`app.*`, `admin.*`, …) resolve exactly as they will at runtime. This is the
13
+ * terminal ground truth — coding agents are told to consult it instead of
14
+ * guessing op names (see the scaffolded AGENTS.md).
15
+ *
16
+ * `dev` shells out to `node --watch` (Node ≥20 runs .ts via type-stripping on
17
+ * recent versions).
18
+ */
19
+ import { readFileSync, existsSync } from "node:fs";
20
+ import { resolve } from "node:path";
21
+ import { spawn } from "node:child_process";
22
+ import { Engine, formatGraph, collectIssues, resolvePorts, resolveControlOuts, z, } from "@pattern-js/core";
23
+ import { loadMods } from "../mods.js";
24
+ import { loadWorkflowDir, loadDotEnv } from "../project.js";
25
+ import { runCli } from "../cli.js";
26
+ import { createTraceStore } from "../trace/index.js";
27
+ const pc = {
28
+ bold: (s) => `\x1b[1m${s}\x1b[0m`,
29
+ dim: (s) => `\x1b[2m${s}\x1b[0m`,
30
+ red: (s) => `\x1b[31m${s}\x1b[0m`,
31
+ green: (s) => `\x1b[32m${s}\x1b[0m`,
32
+ cyan: (s) => `\x1b[36m${s}\x1b[0m`,
33
+ magenta: (s) => `\x1b[35m${s}\x1b[0m`,
34
+ yellow: (s) => `\x1b[33m${s}\x1b[0m`,
35
+ };
36
+ async function main() {
37
+ const [cmd, ...rest] = process.argv.slice(2);
38
+ switch (cmd) {
39
+ case "ops":
40
+ return cmdOps(rest[0]);
41
+ case "graph":
42
+ return cmdGraph(rest[0]);
43
+ case "validate":
44
+ return cmdValidate(rest[0]);
45
+ case "run":
46
+ return cmdRun(rest);
47
+ case "dev":
48
+ return cmdDev(rest[0]);
49
+ case "load":
50
+ return cmdLoad(rest);
51
+ case undefined:
52
+ case "help":
53
+ case "--help":
54
+ case "-h":
55
+ return usage();
56
+ default:
57
+ console.error(pc.red(`unknown command "${cmd}"`));
58
+ usage();
59
+ process.exit(1);
60
+ }
61
+ }
62
+ function usage() {
63
+ console.log(`${pc.bold("pattern")} — workflow dev CLI
64
+
65
+ ${pc.cyan("pattern ops")} list every available op (project mods included)
66
+ ${pc.cyan("pattern ops")} <query> filter by prefix, or full detail on an exact type
67
+ ${pc.cyan("pattern graph")} <file.json> print a workflow's graph
68
+ ${pc.cyan("pattern validate")} <file.json> validate a workflow document
69
+ ${pc.cyan("pattern run")} <file.json|id> [-- args] run a boundary.cli workflow once by file or id (records to the trace store)
70
+ ${pc.cyan("pattern dev")} [entry] run an entry with --watch hot-reload
71
+ ${pc.cyan("pattern load")} <scenario.json> open-loop load test with engine flight-recording
72
+ ${pc.dim("--sweep find max sustainable rps --url <u> target a running server")}
73
+ ${pc.dim("--out <file> write the JSON report --p99 <ms> sweep knee budget")}
74
+ `);
75
+ }
76
+ /**
77
+ * Build an engine the way the project will at runtime: the project's `.env`
78
+ * loaded (so mod setup — the vault reading PATTERN_VAULT_KEY, agents reading
79
+ * OPENAI_API_KEY — and `$env` config see it, just like `loadProject`), then core
80
+ * ops + every mod declared in `pattern.config.json` (when present). Workflows are
81
+ * *not* registered and no server starts — this is introspection (+ `pattern run`).
82
+ */
83
+ async function projectEngine() {
84
+ loadDotEnv(process.cwd());
85
+ const engine = new Engine({ env: process.env });
86
+ if (existsSync("pattern.config.json")) {
87
+ try {
88
+ const config = JSON.parse(readFileSync("pattern.config.json", "utf8"));
89
+ if (config.mods?.length)
90
+ await loadMods(engine, config.mods, { baseDir: process.cwd() });
91
+ }
92
+ catch (err) {
93
+ console.error(pc.yellow(`! could not load project mods: ${err.message}`));
94
+ }
95
+ }
96
+ return engine;
97
+ }
98
+ function loadWorkflow(file) {
99
+ if (!file) {
100
+ console.error(pc.red("expected a workflow file path"));
101
+ process.exit(1);
102
+ }
103
+ if (!existsSync(file)) {
104
+ console.error(pc.red(`file not found: ${file}`));
105
+ process.exit(1);
106
+ }
107
+ return JSON.parse(readFileSync(file, "utf8"));
108
+ }
109
+ async function cmdGraph(file) {
110
+ const doc = loadWorkflow(file);
111
+ const engine = await projectEngine();
112
+ const { ok, workflow, issues } = collectIssues(doc, engine.ops);
113
+ if (workflow)
114
+ console.log(formatGraph(workflow, engine.ops));
115
+ if (!ok) {
116
+ console.log("");
117
+ console.log(pc.red(`${issues.length} validation issue(s):`));
118
+ for (const i of issues)
119
+ console.log(` ${pc.red("•")} ${i.message}`);
120
+ process.exit(1);
121
+ }
122
+ }
123
+ async function cmdValidate(file) {
124
+ const doc = loadWorkflow(file);
125
+ const engine = await projectEngine();
126
+ const { ok, issues } = collectIssues(doc, engine.ops);
127
+ const warnings = issues.filter((i) => i.severity === "warning");
128
+ const errors = issues.filter((i) => i.severity !== "warning");
129
+ const line = (i, mark) => {
130
+ const loc = [i.nodeId && `node "${i.nodeId}"`, i.port && `port "${i.port}"`].filter(Boolean).join(", ");
131
+ console.log(` ${mark} ${i.message}${loc ? pc.dim(` (${loc})`) : ""}`);
132
+ };
133
+ if (ok) {
134
+ console.log(warnings.length ? pc.green("✓ valid ") + pc.yellow(`(${warnings.length} warning(s))`) : pc.green("✓ workflow is valid"));
135
+ for (const i of warnings)
136
+ line(i, pc.yellow("⚠"));
137
+ return;
138
+ }
139
+ console.log(pc.red(`✗ ${errors.length} error(s)`) + (warnings.length ? pc.yellow(` + ${warnings.length} warning(s)`) : "") + ":");
140
+ for (const i of errors)
141
+ line(i, pc.red("•"));
142
+ for (const i of warnings)
143
+ line(i, pc.yellow("⚠"));
144
+ process.exit(1);
145
+ }
146
+ /**
147
+ * `pattern run <file.json|id> [-- args]` — run a `boundary.cli` workflow once.
148
+ * The target is an explicit workflow file, OR the **id** of a registered
149
+ * workflow — including one authored in the admin (those load from `.pattern`
150
+ * when the project's mods install) and file workflows under `./workflows`. Loads
151
+ * the project (so app/npm ops + stored workflows resolve), attaches the durable
152
+ * trace store so the run shows up in the admin like any other, runs it (args
153
+ * after `--` reach `args`/`parsed`/stdin), and exits with the CLI exit code.
154
+ */
155
+ async function cmdRun(rest) {
156
+ const dash = rest.indexOf("--");
157
+ const target = dash >= 0 ? rest.slice(0, dash).find((a) => !a.startsWith("-")) : rest[0];
158
+ const argv = dash >= 0 ? rest.slice(dash + 1) : rest.slice(1);
159
+ if (!target) {
160
+ console.error(pc.red("expected a workflow file or id: pattern run <file.json|id> [-- args]"));
161
+ process.exit(1);
162
+ }
163
+ // Loads the mods → the admin's control plane registers stored (admin-authored)
164
+ // workflows from `.pattern` during its `ready` hook.
165
+ const engine = await projectEngine();
166
+ // CLI runs are one-shot and interactive — sample I/O so their replay has data.
167
+ engine.setIoSampling(true);
168
+ // Also register file-based workflows so `pattern run <id>` resolves those too.
169
+ for (const wf of await loadWorkflowDir(resolve(process.cwd(), "workflows"))) {
170
+ if (!engine.workflows.has(wf.id))
171
+ await engine.registerWorkflowAsync(wf).catch(() => { });
172
+ }
173
+ // Resolve the target: an explicit file path wins; otherwise it's a workflow id.
174
+ let doc;
175
+ if (existsSync(target)) {
176
+ try {
177
+ doc = JSON.parse(readFileSync(target, "utf8"));
178
+ await engine.registerWorkflowAsync(doc);
179
+ }
180
+ catch (err) {
181
+ console.error(pc.red(`✗ ${err.message}`));
182
+ process.exit(1);
183
+ }
184
+ }
185
+ else {
186
+ doc = engine.workflows.get(target);
187
+ if (!doc) {
188
+ console.error(pc.red(`no workflow file "${target}", and no registered workflow with id "${target}".`));
189
+ console.error(pc.dim(" Admin-authored workflows load from .pattern — make sure @pattern-js/mod-admin is in your mods."));
190
+ console.error(pc.dim(" `pattern ops` and the admin's Workflows list show what's available."));
191
+ process.exit(1);
192
+ }
193
+ }
194
+ const store = await createTraceStore({ kind: "sqlite", path: resolve(process.cwd(), ".pattern/traces.db") });
195
+ engine.onTrace(store);
196
+ let code = 0;
197
+ try {
198
+ code = await runCli(engine, doc, { argv });
199
+ }
200
+ catch (err) {
201
+ // The most common case: the workflow has no `boundary.cli` trigger.
202
+ console.error(pc.red(`✗ ${err.message}`));
203
+ code = 1;
204
+ }
205
+ finally {
206
+ await store.close();
207
+ }
208
+ process.exit(code);
209
+ }
210
+ // ── pattern ops ──────────────────────────────────────────────────────────────
211
+ function firstLine(s) {
212
+ return (s ?? "").split("\n")[0] ?? "";
213
+ }
214
+ /** "core.string.template" → "core.string"; "boundary.http.request" → "boundary"; "app.shout" → "app". */
215
+ function groupOf(type) {
216
+ const parts = type.split(".");
217
+ if (parts[0] === "core")
218
+ return parts.slice(0, 2).join(".");
219
+ return parts[0] ?? "misc";
220
+ }
221
+ function portLine(name, spec, dir) {
222
+ const arrow = dir === "in" ? pc.cyan("→") : pc.magenta("←");
223
+ const kind = spec.kind === "value" ? "value" : spec.kind === "stream" ? pc.magenta("stream") : pc.yellow("control");
224
+ const req = spec.required ? pc.yellow(" required") : "";
225
+ const desc = spec.description ? pc.dim(` ${firstLine(spec.description)}`) : "";
226
+ return ` ${arrow} ${pc.bold(name)} ${pc.dim(kind)}${req}${desc}`;
227
+ }
228
+ /** Render a zod config schema's top-level fields (type, default, required). */
229
+ function configLines(schema) {
230
+ if (!schema)
231
+ return [];
232
+ let json;
233
+ try {
234
+ json = z.toJSONSchema(schema, { unrepresentable: "any" });
235
+ }
236
+ catch {
237
+ return [pc.dim(" (config schema not representable as JSON Schema)")];
238
+ }
239
+ if (!json.properties)
240
+ return [];
241
+ const requiredKeys = new Set(json.required ?? []);
242
+ return Object.entries(json.properties).map(([key, prop]) => {
243
+ const type = typeof prop.type === "string" ? prop.type : Array.isArray(prop.enum) ? `enum(${prop.enum.join("|")})` : "any";
244
+ const def = prop.default !== undefined ? pc.dim(` = ${JSON.stringify(prop.default)}`) : "";
245
+ const req = requiredKeys.has(key) && prop.default === undefined ? pc.yellow(" required") : "";
246
+ return ` ${pc.bold(key)} ${pc.dim(type)}${def}${req}`;
247
+ });
248
+ }
249
+ function printOpDetail(engine, op) {
250
+ console.log("");
251
+ console.log(` ${pc.bold(pc.cyan(op.type))}${op.boundary ? ` ${pc.yellow(`[${op.boundary}]`)}` : ""}`);
252
+ if (op.description)
253
+ console.log(` ${pc.dim(op.description)}`);
254
+ if (op.pair)
255
+ console.log(` ${pc.dim("pairs with")} ${pc.cyan(op.pair)}`);
256
+ const configInputs = op.configInputs ? Object.entries(resolvePorts(op.configInputs, {})) : [];
257
+ const inputs = Object.entries(resolvePorts(op.inputs, {}));
258
+ const outputs = Object.entries(resolvePorts(op.outputs, {}));
259
+ const controlOuts = resolveControlOuts(op, {});
260
+ if (inputs.length || configInputs.length) {
261
+ console.log(` ${pc.dim("inputs:")}`);
262
+ for (const [name, spec] of configInputs)
263
+ console.log(portLine(name, spec, "in") + pc.dim(" (config port)"));
264
+ for (const [name, spec] of inputs)
265
+ console.log(portLine(name, spec, "in"));
266
+ }
267
+ if (outputs.length) {
268
+ console.log(` ${pc.dim("outputs:")}`);
269
+ for (const [name, spec] of outputs)
270
+ console.log(portLine(name, spec, "out"));
271
+ }
272
+ if (controlOuts.length)
273
+ console.log(` ${pc.dim("control-outs:")} ${controlOuts.map((c) => pc.yellow(c)).join(", ")}`);
274
+ const config = configLines(op.config);
275
+ if (config.length) {
276
+ console.log(` ${pc.dim("config:")}`);
277
+ for (const line of config)
278
+ console.log(line);
279
+ }
280
+ console.log("");
281
+ }
282
+ async function cmdOps(query) {
283
+ const engine = await projectEngine();
284
+ const all = engine.ops.list().sort((a, b) => a.type.localeCompare(b.type));
285
+ // Exact type → full detail.
286
+ const exact = query && engine.ops.get(query);
287
+ if (exact)
288
+ return printOpDetail(engine, exact);
289
+ const q = (query ?? "").toLowerCase();
290
+ const matched = q ? all.filter((op) => op.type.toLowerCase().includes(q)) : all;
291
+ if (!matched.length) {
292
+ console.error(pc.red(`no op matches "${query}"`));
293
+ process.exit(1);
294
+ }
295
+ // Single match on a fuzzy query → treat as detail too.
296
+ if (q && matched.length === 1)
297
+ return printOpDetail(engine, matched[0]);
298
+ const groups = new Map();
299
+ for (const op of matched) {
300
+ const g = groupOf(op.type);
301
+ groups.set(g, [...(groups.get(g) ?? []), op]);
302
+ }
303
+ const width = Math.max(...matched.map((op) => op.type.length)) + 2;
304
+ console.log("");
305
+ for (const [group, ops] of [...groups.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {
306
+ console.log(` ${pc.bold(group)} ${pc.dim(`(${ops.length})`)}`);
307
+ for (const op of ops) {
308
+ const badge = op.boundary === "trigger" ? pc.yellow("▸ ") : op.boundary === "outgate" ? pc.yellow("◂ ") : " ";
309
+ console.log(` ${badge}${pc.cyan(op.type.padEnd(width))}${pc.dim(firstLine(op.description))}`);
310
+ }
311
+ console.log("");
312
+ }
313
+ console.log(pc.dim(` ${matched.length} ops — \`pattern ops <type>\` for ports + config.\n`));
314
+ }
315
+ // ── pattern load ─────────────────────────────────────────────────────────────
316
+ async function cmdLoad(args) {
317
+ const { loadScenario, runLoad, resolveScenario } = await import("../load/index.js");
318
+ const flag = (name) => {
319
+ const i = args.indexOf(name);
320
+ return i >= 0 ? args[i + 1] : undefined;
321
+ };
322
+ const file = args.find((a) => !a.startsWith("-") && a !== flag("--url") && a !== flag("--out") && a !== flag("--p99"));
323
+ if (!file) {
324
+ console.error(pc.red("expected a scenario file: pattern load <scenario.json>"));
325
+ process.exit(1);
326
+ }
327
+ let scenario;
328
+ try {
329
+ scenario = loadScenario(resolveScenario(file));
330
+ }
331
+ catch (err) {
332
+ console.error(pc.red(`✗ ${err.message}`));
333
+ process.exit(1);
334
+ }
335
+ const sweep = args.includes("--sweep");
336
+ const out = flag("--out");
337
+ const url = flag("--url");
338
+ const p99 = flag("--p99");
339
+ console.log(`${pc.bold("pattern load")} ${pc.dim(file)}${sweep ? pc.yellow(" (saturation sweep)") : ""}`);
340
+ const startedAt = Date.now();
341
+ const report = await runLoad(scenario, { sweep, out, baseUrl: url, p99BudgetMs: p99 ? Number(p99) : undefined }, startedAt);
342
+ report.scenario = file;
343
+ if (out) {
344
+ const { writeFileSync } = await import("node:fs");
345
+ writeFileSync(out, JSON.stringify(report, null, 2));
346
+ console.log(`\n ${pc.green("✓")} report written to ${pc.cyan(out)}`);
347
+ }
348
+ const anyErrors = report.stages.some((s) => s.errors > 0);
349
+ console.log("");
350
+ process.exit(anyErrors ? 1 : 0);
351
+ }
352
+ function cmdDev(entryArg) {
353
+ const candidates = entryArg ? [entryArg] : ["src/index.ts", "src/main.ts", "src/index.js", "index.js"];
354
+ const entry = candidates.find((c) => existsSync(c));
355
+ if (!entry) {
356
+ console.error(pc.red(`no entry found (looked for: ${candidates.join(", ")})`));
357
+ process.exit(1);
358
+ }
359
+ console.log(pc.dim(`pattern dev — watching & running ${entry}`));
360
+ const child = spawn(process.execPath, ["--watch", entry], { stdio: "inherit", env: process.env });
361
+ child.on("exit", (code) => process.exit(code ?? 0));
362
+ process.on("SIGINT", () => child.kill("SIGINT"));
363
+ }
364
+ void main();
365
+ //# sourceMappingURL=pattern.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern.js","sourceRoot":"","sources":["../../src/bin/pattern.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @pattern-js/runtime-node — CLI host (§6, §7).
3
+ *
4
+ * Binds a process invocation to a `boundary.cli` trigger and writes the
5
+ * `boundary.cli.exit` out-gate result to stdout/stderr + exit code. CLI is
6
+ * intrinsically host-local — acceptable per the spec.
7
+ */
8
+ import type { Engine, Workflow } from "@pattern-js/core";
9
+ export interface CliHostOptions {
10
+ /** Argument vector (defaults to process.argv.slice(2)). */
11
+ argv?: string[];
12
+ /** The `boundary.cli` trigger node id (inferred if omitted). */
13
+ trigger?: string;
14
+ /** Optional structured arg parser → `parsed` output port. */
15
+ parse?: (argv: string[]) => Record<string, unknown>;
16
+ /** Provide stdin as a web stream (defaults to process.stdin). */
17
+ stdin?: ReadableStream<Uint8Array>;
18
+ }
19
+ /** Run a CLI workflow once; returns the process exit code. Does not call process.exit. */
20
+ export declare function runCli(engine: Engine, workflowOrId: Workflow | string, opts?: CliHostOptions): Promise<number>;
21
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAa,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEpE,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD,iEAAiE;IACjE,KAAK,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;CACpC;AASD,0FAA0F;AAC1F,wBAAsB,MAAM,CAC1B,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,QAAQ,GAAG,MAAM,EAC/B,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,MAAM,CAAC,CAoDjB"}
package/dist/cli.js ADDED
@@ -0,0 +1,75 @@
1
+ /**
2
+ * @pattern-js/runtime-node — CLI host (§6, §7).
3
+ *
4
+ * Binds a process invocation to a `boundary.cli` trigger and writes the
5
+ * `boundary.cli.exit` out-gate result to stdout/stderr + exit code. CLI is
6
+ * intrinsically host-local — acceptable per the spec.
7
+ */
8
+ import { Readable } from "node:stream";
9
+ /** Run a CLI workflow once; returns the process exit code. Does not call process.exit. */
10
+ export async function runCli(engine, workflowOrId, opts = {}) {
11
+ const workflow = typeof workflowOrId === "string" ? engine.workflows.get(workflowOrId) : workflowOrId;
12
+ if (!workflow)
13
+ throw new Error(`workflow "${String(workflowOrId)}" not registered`);
14
+ const triggerId = opts.trigger ?? workflow.nodes.find((n) => n.op === "boundary.cli")?.id;
15
+ if (!triggerId)
16
+ throw new Error("no boundary.cli trigger");
17
+ const argv = opts.argv ?? process.argv.slice(2);
18
+ const stdin = opts.stdin ?? Readable.toWeb(process.stdin);
19
+ const input = {
20
+ args: argv,
21
+ parsed: opts.parse ? opts.parse(argv) : {},
22
+ stdin,
23
+ env: { ...process.env },
24
+ };
25
+ let result;
26
+ try {
27
+ result = await engine.runFrom(workflow, triggerId, input, { kind: "anonymous" });
28
+ }
29
+ catch (err) {
30
+ process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
31
+ return 1;
32
+ }
33
+ if (result.status === "error") {
34
+ process.stderr.write(`${result.error?.message ?? String(result.error)}\n`);
35
+ return 1;
36
+ }
37
+ const payload = firstExit(result, workflow);
38
+ if (!payload)
39
+ return 0;
40
+ if (payload.stdoutStream instanceof ReadableStream) {
41
+ const reader = payload.stdoutStream.getReader();
42
+ let last = "";
43
+ for (;;) {
44
+ const { done, value } = await reader.read();
45
+ if (done)
46
+ break;
47
+ const chunk = value instanceof Uint8Array ? Buffer.from(value) : String(value);
48
+ process.stdout.write(chunk);
49
+ last = typeof chunk === "string" ? chunk : chunk.toString("utf8");
50
+ }
51
+ // A streamed result that doesn't end in a newline leaves a partial line:
52
+ // zsh/bash mark it (and it can look like the output "vanished" on exit).
53
+ // Terminate it like the value-stdout path does.
54
+ if (last && !last.endsWith("\n"))
55
+ process.stdout.write("\n");
56
+ }
57
+ else if (payload.stdout != null) {
58
+ const out = payload.stdout;
59
+ process.stdout.write(out instanceof Uint8Array ? Buffer.from(out) : typeof out === "string" ? out : JSON.stringify(out));
60
+ if (typeof out === "string" && !out.endsWith("\n"))
61
+ process.stdout.write("\n");
62
+ }
63
+ if (payload.stderr)
64
+ process.stderr.write(String(payload.stderr));
65
+ return payload.code ?? 0;
66
+ }
67
+ function firstExit(result, workflow) {
68
+ for (const [nodeId, payload] of Object.entries(result.outputs)) {
69
+ const node = workflow.nodes.find((n) => n.id === nodeId);
70
+ if (node?.op === "boundary.cli.exit")
71
+ return payload;
72
+ }
73
+ return Object.values(result.outputs)[0];
74
+ }
75
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}