@nwire/cli 0.7.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/LICENSE +21 -0
- package/README.md +50 -0
- package/dist/__tests__/doctor.test.d.ts +10 -0
- package/dist/__tests__/doctor.test.d.ts.map +1 -0
- package/dist/__tests__/doctor.test.js +105 -0
- package/dist/__tests__/doctor.test.js.map +1 -0
- package/dist/cache-runner.d.ts +2 -0
- package/dist/cache-runner.d.ts.map +1 -0
- package/dist/cache-runner.js +58 -0
- package/dist/cache-runner.js.map +1 -0
- package/dist/cli.d.ts +16 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +67 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/build.d.ts +13 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +74 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/cache.d.ts +6 -0
- package/dist/commands/cache.d.ts.map +1 -0
- package/dist/commands/cache.js +27 -0
- package/dist/commands/cache.js.map +1 -0
- package/dist/commands/check.d.ts +6 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +21 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/dev.d.ts +11 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +165 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/doctor.d.ts +59 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +399 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/fmt.d.ts +13 -0
- package/dist/commands/fmt.d.ts.map +1 -0
- package/dist/commands/fmt.js +33 -0
- package/dist/commands/fmt.js.map +1 -0
- package/dist/commands/greeting.d.ts +6 -0
- package/dist/commands/greeting.d.ts.map +1 -0
- package/dist/commands/greeting.js +25 -0
- package/dist/commands/greeting.js.map +1 -0
- package/dist/commands/infra.d.ts +14 -0
- package/dist/commands/infra.d.ts.map +1 -0
- package/dist/commands/infra.js +146 -0
- package/dist/commands/infra.js.map +1 -0
- package/dist/commands/lint.d.ts +12 -0
- package/dist/commands/lint.d.ts.map +1 -0
- package/dist/commands/lint.js +32 -0
- package/dist/commands/lint.js.map +1 -0
- package/dist/commands/logs.d.ts +21 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +73 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/ls.d.ts +5 -0
- package/dist/commands/ls.d.ts.map +1 -0
- package/dist/commands/ls.js +26 -0
- package/dist/commands/ls.js.map +1 -0
- package/dist/commands/please.d.ts +13 -0
- package/dist/commands/please.d.ts.map +1 -0
- package/dist/commands/please.js +46 -0
- package/dist/commands/please.js.map +1 -0
- package/dist/commands/ps.d.ts +6 -0
- package/dist/commands/ps.d.ts.map +1 -0
- package/dist/commands/ps.js +21 -0
- package/dist/commands/ps.js.map +1 -0
- package/dist/commands/run.d.ts +19 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +112 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/studio.d.ts +9 -0
- package/dist/commands/studio.d.ts.map +1 -0
- package/dist/commands/studio.js +46 -0
- package/dist/commands/studio.js.map +1 -0
- package/dist/commands/test.d.ts +26 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +143 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/kernel-instance.d.ts +8 -0
- package/dist/kernel-instance.d.ts.map +1 -0
- package/dist/kernel-instance.js +13 -0
- package/dist/kernel-instance.js.map +1 -0
- package/dist/lib/colors.d.ts +19 -0
- package/dist/lib/colors.d.ts.map +1 -0
- package/dist/lib/colors.js +18 -0
- package/dist/lib/colors.js.map +1 -0
- package/dist/lib/exec.d.ts +30 -0
- package/dist/lib/exec.d.ts.map +1 -0
- package/dist/lib/exec.js +58 -0
- package/dist/lib/exec.js.map +1 -0
- package/dist/lib/process-state.d.ts +30 -0
- package/dist/lib/process-state.d.ts.map +1 -0
- package/dist/lib/process-state.js +68 -0
- package/dist/lib/process-state.js.map +1 -0
- package/dist/lib/project.d.ts +15 -0
- package/dist/lib/project.d.ts.map +1 -0
- package/dist/lib/project.js +52 -0
- package/dist/lib/project.js.map +1 -0
- package/dist/lib/run-task.d.ts +32 -0
- package/dist/lib/run-task.d.ts.map +1 -0
- package/dist/lib/run-task.js +70 -0
- package/dist/lib/run-task.js.map +1 -0
- package/dist/lib/vite-node.d.ts +10 -0
- package/dist/lib/vite-node.d.ts.map +1 -0
- package/dist/lib/vite-node.js +14 -0
- package/dist/lib/vite-node.js.map +1 -0
- package/dist/load-config.d.ts +27 -0
- package/dist/load-config.d.ts.map +1 -0
- package/dist/load-config.js +38 -0
- package/dist/load-config.js.map +1 -0
- package/dist/ls-runner.d.ts +2 -0
- package/dist/ls-runner.d.ts.map +1 -0
- package/dist/ls-runner.js +55 -0
- package/dist/ls-runner.js.map +1 -0
- package/dist/ui/dev-dashboard.d.ts +23 -0
- package/dist/ui/dev-dashboard.d.ts.map +1 -0
- package/dist/ui/dev-dashboard.js +53 -0
- package/dist/ui/dev-dashboard.js.map +1 -0
- package/dist/ui/greeting.d.ts +16 -0
- package/dist/ui/greeting.d.ts.map +1 -0
- package/dist/ui/greeting.js +16 -0
- package/dist/ui/greeting.js.map +1 -0
- package/dist/ui/process-table.d.ts +13 -0
- package/dist/ui/process-table.d.ts.map +1 -0
- package/dist/ui/process-table.js +26 -0
- package/dist/ui/process-table.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nwire run <wire>` — boot one wire by name with stdio passthrough.
|
|
3
|
+
*
|
|
4
|
+
* nwire run main → apps/main/{run,main}.ts
|
|
5
|
+
* nwire run main.please → apps/main/run.please.ts
|
|
6
|
+
*
|
|
7
|
+
* Prints a branded banner so the user sees what's starting, then hands
|
|
8
|
+
* stdio straight through to the child (runApp's boot banner shows the
|
|
9
|
+
* actual port, docs URL, etc.). Same banner UX as `nwire dev`; only
|
|
10
|
+
* difference is `dev` adds `--watch` and reloads on change.
|
|
11
|
+
*/
|
|
12
|
+
import { defineCommand } from "citty";
|
|
13
|
+
import { resolve } from "node:path";
|
|
14
|
+
import { existsSync } from "node:fs";
|
|
15
|
+
import { spawn } from "node:child_process";
|
|
16
|
+
import { palette } from "../lib/colors.js";
|
|
17
|
+
export const runCommand = defineCommand({
|
|
18
|
+
meta: {
|
|
19
|
+
name: "run",
|
|
20
|
+
description: "Run a wire by name (apps/<name>/{run,main}.ts or run.<variant>.ts)",
|
|
21
|
+
},
|
|
22
|
+
args: {
|
|
23
|
+
wire: {
|
|
24
|
+
type: "positional",
|
|
25
|
+
required: true,
|
|
26
|
+
description: "Wire name, e.g. `main` or `main.please`",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
async run({ args, rawArgs }) {
|
|
30
|
+
const cwd = process.cwd();
|
|
31
|
+
const [appName, ...variantParts] = String(args.wire).split(".");
|
|
32
|
+
if (!appName) {
|
|
33
|
+
// eslint-disable-next-line no-console
|
|
34
|
+
console.error(palette.err("nwire run:") + " wire name required");
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
const appDir = resolve(cwd, "apps", appName);
|
|
38
|
+
if (!existsSync(appDir)) {
|
|
39
|
+
// eslint-disable-next-line no-console
|
|
40
|
+
console.error(palette.err("nwire run:") + ` no app folder at ${appDir}`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
const variant = variantParts.length > 0 ? `.${variantParts.join(".")}` : "";
|
|
44
|
+
const candidates = [resolve(appDir, `run${variant}.ts`), resolve(appDir, `main${variant}.ts`)];
|
|
45
|
+
const entry = candidates.find((p) => existsSync(p));
|
|
46
|
+
if (!entry) {
|
|
47
|
+
// eslint-disable-next-line no-console
|
|
48
|
+
console.error(palette.err("nwire run:") +
|
|
49
|
+
` no entry file in ${appDir} for wire "${args.wire}" (looked for ${candidates
|
|
50
|
+
.map((p) => p.split("/").pop())
|
|
51
|
+
.join(", ")})`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
const entryRel = entry.replace(cwd + "/", "");
|
|
55
|
+
const passthrough = rawArgs.slice(rawArgs.indexOf(String(args.wire)) + 1);
|
|
56
|
+
// ── Banner ──────────────────────────────────────────────────────
|
|
57
|
+
// eslint-disable-next-line no-console
|
|
58
|
+
console.log([
|
|
59
|
+
"",
|
|
60
|
+
` ${palette.brand(palette.bold("Nwire run"))} ${palette.dim(String(args.wire))}`,
|
|
61
|
+
` ${palette.dim("entry ")} ${entryRel}`,
|
|
62
|
+
` ${palette.dim("Ctrl+C ")} stop`,
|
|
63
|
+
"",
|
|
64
|
+
].join("\n"));
|
|
65
|
+
// ── Stdio passthrough ──────────────────────────────────────────
|
|
66
|
+
// The child writes directly to the user's terminal. runApp() emits
|
|
67
|
+
// its own banner (ports, docs, openapi paths) so the user gets
|
|
68
|
+
// immediate feedback once the wire is listening.
|
|
69
|
+
const child = spawn("pnpm", ["exec", "vite-node", entry, ...passthrough], {
|
|
70
|
+
stdio: "inherit",
|
|
71
|
+
cwd,
|
|
72
|
+
});
|
|
73
|
+
let stopping = false;
|
|
74
|
+
const stop = (signal) => {
|
|
75
|
+
if (stopping)
|
|
76
|
+
return;
|
|
77
|
+
stopping = true;
|
|
78
|
+
try {
|
|
79
|
+
child.kill(signal);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// gone
|
|
83
|
+
}
|
|
84
|
+
setTimeout(() => {
|
|
85
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
86
|
+
try {
|
|
87
|
+
child.kill("SIGKILL");
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// gone
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}, 4000).unref();
|
|
94
|
+
};
|
|
95
|
+
process.on("SIGINT", () => stop("SIGINT"));
|
|
96
|
+
process.on("SIGTERM", () => stop("SIGTERM"));
|
|
97
|
+
const exitCode = await new Promise((resolveExit) => {
|
|
98
|
+
child.on("exit", (code, signal) => {
|
|
99
|
+
if (stopping || signal === "SIGINT" || signal === "SIGTERM") {
|
|
100
|
+
resolveExit(0);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
resolveExit(code ?? 0);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
// eslint-disable-next-line no-console
|
|
108
|
+
console.log(palette.dim("\nStopped."));
|
|
109
|
+
process.exit(exitCode);
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nwire studio` — boots Nwire Studio (Vue 3 + Vite) pointed at the
|
|
3
|
+
* consumer's project. Bypasses pnpm-filter to avoid the
|
|
4
|
+
* ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL noise on Ctrl+C; spawns Studio's own
|
|
5
|
+
* vite binary directly with NWIRE_CWD set so the middleware reads the
|
|
6
|
+
* right `.nwire/` and `apps/topologies/`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const studioCommand: import("citty").CommandDef<import("citty").ArgsDef>;
|
|
9
|
+
//# sourceMappingURL=studio.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"studio.d.ts","sourceRoot":"","sources":["../../src/commands/studio.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH,eAAO,MAAM,aAAa,qDAkCxB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nwire studio` — boots Nwire Studio (Vue 3 + Vite) pointed at the
|
|
3
|
+
* consumer's project. Bypasses pnpm-filter to avoid the
|
|
4
|
+
* ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL noise on Ctrl+C; spawns Studio's own
|
|
5
|
+
* vite binary directly with NWIRE_CWD set so the middleware reads the
|
|
6
|
+
* right `.nwire/` and `apps/topologies/`.
|
|
7
|
+
*/
|
|
8
|
+
import { defineCommand } from "citty";
|
|
9
|
+
import { createRequire } from "node:module";
|
|
10
|
+
import { resolve, dirname } from "node:path";
|
|
11
|
+
import { existsSync } from "node:fs";
|
|
12
|
+
import { palette } from "../lib/colors.js";
|
|
13
|
+
import { spawnInteractive } from "../lib/exec.js";
|
|
14
|
+
const localRequire = createRequire(import.meta.url);
|
|
15
|
+
export const studioCommand = defineCommand({
|
|
16
|
+
meta: {
|
|
17
|
+
name: "studio",
|
|
18
|
+
description: "Boot Nwire Studio (Vue + Vite UI)",
|
|
19
|
+
},
|
|
20
|
+
async run({ rawArgs }) {
|
|
21
|
+
let studioDir;
|
|
22
|
+
try {
|
|
23
|
+
studioDir = dirname(localRequire.resolve("@nwire/studio/package.json"));
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// eslint-disable-next-line no-console
|
|
27
|
+
console.error(palette.err("nwire studio:") +
|
|
28
|
+
" @nwire/studio not installed. `pnpm add -D @nwire/studio` first.");
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
const viteBin = resolve(studioDir, "node_modules", ".bin", "vite");
|
|
32
|
+
if (!existsSync(viteBin)) {
|
|
33
|
+
// eslint-disable-next-line no-console
|
|
34
|
+
console.error(palette.err("nwire studio:") +
|
|
35
|
+
` vite binary missing at ${viteBin} — run \`pnpm install\` in ${studioDir}`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
const { done } = spawnInteractive(viteBin, rawArgs, {
|
|
39
|
+
cwd: studioDir,
|
|
40
|
+
env: { NWIRE_CWD: process.cwd() },
|
|
41
|
+
stoppedMessage: "Studio stopped.",
|
|
42
|
+
});
|
|
43
|
+
process.exit(await done);
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=studio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"studio.js","sourceRoot":"","sources":["../../src/commands/studio.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,YAAY,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEpD,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IACzC,IAAI,EAAE;QACJ,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,mCAAmC;KACjD;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE;QACnB,IAAI,SAAiB,CAAC;QACtB,IAAI,CAAC;YACH,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC,CAAC;QAC1E,CAAC;QAAC,MAAM,CAAC;YACP,sCAAsC;YACtC,OAAO,CAAC,KAAK,CACX,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;gBAC1B,kEAAkE,CACrE,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACnE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,sCAAsC;YACtC,OAAO,CAAC,KAAK,CACX,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;gBAC1B,2BAA2B,OAAO,8BAA8B,SAAS,EAAE,CAC9E,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE;YAClD,GAAG,EAAE,SAAS;YACd,GAAG,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE;YACjC,cAAc,EAAE,iBAAiB;SAClC,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;IAC3B,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nwire test [layer?]` — unified vitest runner.
|
|
3
|
+
*
|
|
4
|
+
* Auto-discovers test layers from the canonical `__tests__/<layer>/`
|
|
5
|
+
* convention (units, integration, e2e, bdd) and runs each as a separate
|
|
6
|
+
* vitest invocation wrapped in a listr2 task. With no arg, runs every
|
|
7
|
+
* detected layer in sequence. With `nwire test units` (etc.) runs just
|
|
8
|
+
* that one.
|
|
9
|
+
*
|
|
10
|
+
* Layer detection: walks the project for any `**\/__tests__/<layer>/`
|
|
11
|
+
* directories that contain test files, picks them up. Layers with no
|
|
12
|
+
* tests are silently skipped.
|
|
13
|
+
*/
|
|
14
|
+
export declare const testCommand: import("citty").CommandDef<{
|
|
15
|
+
layer: {
|
|
16
|
+
type: "positional";
|
|
17
|
+
required: false;
|
|
18
|
+
description: string;
|
|
19
|
+
};
|
|
20
|
+
watch: {
|
|
21
|
+
type: "boolean";
|
|
22
|
+
description: string;
|
|
23
|
+
default: false;
|
|
24
|
+
};
|
|
25
|
+
}>;
|
|
26
|
+
//# sourceMappingURL=test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAmEH,eAAO,MAAM,WAAW;;;;;;;;;;;EAyEtB,CAAC"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nwire test [layer?]` — unified vitest runner.
|
|
3
|
+
*
|
|
4
|
+
* Auto-discovers test layers from the canonical `__tests__/<layer>/`
|
|
5
|
+
* convention (units, integration, e2e, bdd) and runs each as a separate
|
|
6
|
+
* vitest invocation wrapped in a listr2 task. With no arg, runs every
|
|
7
|
+
* detected layer in sequence. With `nwire test units` (etc.) runs just
|
|
8
|
+
* that one.
|
|
9
|
+
*
|
|
10
|
+
* Layer detection: walks the project for any `**\/__tests__/<layer>/`
|
|
11
|
+
* directories that contain test files, picks them up. Layers with no
|
|
12
|
+
* tests are silently skipped.
|
|
13
|
+
*/
|
|
14
|
+
import { defineCommand } from "citty";
|
|
15
|
+
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
16
|
+
import { resolve, join, relative } from "node:path";
|
|
17
|
+
import { palette } from "../lib/colors.js";
|
|
18
|
+
import { runTaskList } from "../lib/run-task.js";
|
|
19
|
+
const LAYERS = ["units", "integration", "e2e", "bdd"];
|
|
20
|
+
/** Walk `cwd` looking for `__tests__/<layer>/` dirs that contain test files. */
|
|
21
|
+
function findLayerDirs(cwd, layer, prune) {
|
|
22
|
+
const hits = [];
|
|
23
|
+
function walk(dir) {
|
|
24
|
+
let entries;
|
|
25
|
+
try {
|
|
26
|
+
entries = readdirSync(dir);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
if (prune.has(entry))
|
|
33
|
+
continue;
|
|
34
|
+
const full = join(dir, entry);
|
|
35
|
+
let stat;
|
|
36
|
+
try {
|
|
37
|
+
stat = statSync(full);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (!stat.isDirectory())
|
|
43
|
+
continue;
|
|
44
|
+
if (entry === "__tests__") {
|
|
45
|
+
const layerPath = join(full, layer);
|
|
46
|
+
if (existsSync(layerPath) && statSync(layerPath).isDirectory()) {
|
|
47
|
+
hits.push(layerPath);
|
|
48
|
+
}
|
|
49
|
+
continue; // never recurse INTO __tests__
|
|
50
|
+
}
|
|
51
|
+
walk(full);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
walk(cwd);
|
|
55
|
+
return hits;
|
|
56
|
+
}
|
|
57
|
+
/** True if `dir` (or any subdir) contains a `*.test.ts` or `.spec.ts` file. */
|
|
58
|
+
function containsTests(dir) {
|
|
59
|
+
try {
|
|
60
|
+
const entries = readdirSync(dir);
|
|
61
|
+
for (const entry of entries) {
|
|
62
|
+
const full = join(dir, entry);
|
|
63
|
+
const stat = statSync(full);
|
|
64
|
+
if (stat.isDirectory()) {
|
|
65
|
+
if (containsTests(full))
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
else if (/\.(test|spec)\.ts$/.test(entry)) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// ignore unreadable dirs
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
const PRUNE = new Set(["node_modules", "dist", ".nwire", ".turbo", "coverage"]);
|
|
79
|
+
export const testCommand = defineCommand({
|
|
80
|
+
meta: {
|
|
81
|
+
name: "test",
|
|
82
|
+
description: "Run vitest layers (units, integration, e2e, bdd)",
|
|
83
|
+
},
|
|
84
|
+
args: {
|
|
85
|
+
layer: {
|
|
86
|
+
type: "positional",
|
|
87
|
+
required: false,
|
|
88
|
+
description: "Run only one layer (units | integration | e2e | bdd); omit for all",
|
|
89
|
+
},
|
|
90
|
+
watch: {
|
|
91
|
+
type: "boolean",
|
|
92
|
+
description: "Run in watch mode (one layer only)",
|
|
93
|
+
default: false,
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
async run({ args }) {
|
|
97
|
+
const cwd = process.cwd();
|
|
98
|
+
const requested = args.layer ? [String(args.layer)] : LAYERS;
|
|
99
|
+
if (args.layer && !LAYERS.includes(args.layer)) {
|
|
100
|
+
// eslint-disable-next-line no-console
|
|
101
|
+
console.error(palette.err("nwire test:") + ` unknown layer "${args.layer}". One of: ${LAYERS.join(", ")}`);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
const tasks = [];
|
|
105
|
+
for (const layer of requested) {
|
|
106
|
+
const dirs = findLayerDirs(cwd, layer, PRUNE).filter(containsTests);
|
|
107
|
+
if (dirs.length === 0)
|
|
108
|
+
continue;
|
|
109
|
+
const relPaths = dirs.map((d) => relative(cwd, d));
|
|
110
|
+
const vitestArgs = args.watch ? ["watch", ...relPaths] : ["run", ...relPaths];
|
|
111
|
+
tasks.push({
|
|
112
|
+
title: `${layer} ${palette.dim(`(${dirs.length} dir${dirs.length === 1 ? "" : "s"})`)}`,
|
|
113
|
+
command: "pnpm",
|
|
114
|
+
args: ["exec", "vitest", ...vitestArgs],
|
|
115
|
+
cwd,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
if (tasks.length === 0) {
|
|
119
|
+
// eslint-disable-next-line no-console
|
|
120
|
+
console.log(palette.dim(args.layer
|
|
121
|
+
? `nwire test: no tests found for layer "${args.layer}".`
|
|
122
|
+
: "nwire test: no tests found. Add tests under `**/__tests__/{units,integration,e2e,bdd}/`."));
|
|
123
|
+
process.exit(0);
|
|
124
|
+
}
|
|
125
|
+
// Watch mode forwards to vitest as a single passthrough (listr can't
|
|
126
|
+
// host a long-lived watcher). Pick the first task and exec it.
|
|
127
|
+
if (args.watch) {
|
|
128
|
+
const t = tasks[0];
|
|
129
|
+
// eslint-disable-next-line no-console
|
|
130
|
+
console.log(palette.dim(`watching ${t.title}…`));
|
|
131
|
+
const { spawnSync } = await import("node:child_process");
|
|
132
|
+
const result = spawnSync(t.command, t.args, {
|
|
133
|
+
stdio: "inherit",
|
|
134
|
+
cwd: t.cwd,
|
|
135
|
+
});
|
|
136
|
+
process.exit(result.status ?? 0);
|
|
137
|
+
}
|
|
138
|
+
// Resolve absolute path for the runner (so cwd doesn't matter).
|
|
139
|
+
resolve(cwd);
|
|
140
|
+
process.exit(await runTaskList(tasks));
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
//# sourceMappingURL=test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@nwire/cli` public surface — anything importable. The `nwire` binary
|
|
3
|
+
* lives at `bin/nwire` (resolves to `dist/cli.js`); this entry is for
|
|
4
|
+
* consumers writing `nwire.config.ts` files.
|
|
5
|
+
*
|
|
6
|
+
* // nwire.config.ts
|
|
7
|
+
* import { defineConfig } from "@nwire/cli"
|
|
8
|
+
* export default defineConfig({ appsEntry: "./src/app.ts" })
|
|
9
|
+
*/
|
|
10
|
+
export { defineConfig, type NwireConfig } from "./load-config.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@nwire/cli` public surface — anything importable. The `nwire` binary
|
|
3
|
+
* lives at `bin/nwire` (resolves to `dist/cli.js`); this entry is for
|
|
4
|
+
* consumers writing `nwire.config.ts` files.
|
|
5
|
+
*
|
|
6
|
+
* // nwire.config.ts
|
|
7
|
+
* import { defineConfig } from "@nwire/cli"
|
|
8
|
+
* export default defineConfig({ appsEntry: "./src/app.ts" })
|
|
9
|
+
*/
|
|
10
|
+
export { defineConfig } from "./load-config.js";
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAoB,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CLI's lazy kernel singleton. Commands register their handlers here
|
|
3
|
+
* once at import time; `runCommand` dispatches through the kernel so
|
|
4
|
+
* Studio and MCP eventually share the same routing.
|
|
5
|
+
*/
|
|
6
|
+
import { type Kernel } from "@nwire/kernel";
|
|
7
|
+
export declare function kernel(): Kernel;
|
|
8
|
+
//# sourceMappingURL=kernel-instance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kernel-instance.d.ts","sourceRoot":"","sources":["../src/kernel-instance.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AAI1D,wBAAgB,MAAM,IAAI,MAAM,CAG/B"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CLI's lazy kernel singleton. Commands register their handlers here
|
|
3
|
+
* once at import time; `runCommand` dispatches through the kernel so
|
|
4
|
+
* Studio and MCP eventually share the same routing.
|
|
5
|
+
*/
|
|
6
|
+
import { createKernel } from "@nwire/kernel";
|
|
7
|
+
let instance;
|
|
8
|
+
export function kernel() {
|
|
9
|
+
if (!instance)
|
|
10
|
+
instance = createKernel();
|
|
11
|
+
return instance;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=kernel-instance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kernel-instance.js","sourceRoot":"","sources":["../src/kernel-instance.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAe,MAAM,eAAe,CAAC;AAE1D,IAAI,QAA4B,CAAC;AAEjC,MAAM,UAAU,MAAM;IACpB,IAAI,CAAC,QAAQ;QAAE,QAAQ,GAAG,YAAY,EAAE,CAAC;IACzC,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized color palette. One file so every command speaks the same
|
|
3
|
+
* visual language — keep adding to the named palette, never let raw ANSI
|
|
4
|
+
* codes or random chalk imports leak into command files.
|
|
5
|
+
*/
|
|
6
|
+
export declare const c: import("picocolors/types").Colors & {
|
|
7
|
+
createColors: (enabled?: boolean) => import("picocolors/types").Colors;
|
|
8
|
+
};
|
|
9
|
+
export declare const palette: {
|
|
10
|
+
brand: import("picocolors/types").Formatter;
|
|
11
|
+
accent: import("picocolors/types").Formatter;
|
|
12
|
+
ok: import("picocolors/types").Formatter;
|
|
13
|
+
warn: import("picocolors/types").Formatter;
|
|
14
|
+
err: import("picocolors/types").Formatter;
|
|
15
|
+
dim: import("picocolors/types").Formatter;
|
|
16
|
+
bold: import("picocolors/types").Formatter;
|
|
17
|
+
hint: import("picocolors/types").Formatter;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=colors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../src/lib/colors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,eAAO,MAAM,CAAC;0BANG,CAAC;CAMC,CAAC;AAEpB,eAAO,MAAM,OAAO;;;;;;;;;CASnB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized color palette. One file so every command speaks the same
|
|
3
|
+
* visual language — keep adding to the named palette, never let raw ANSI
|
|
4
|
+
* codes or random chalk imports leak into command files.
|
|
5
|
+
*/
|
|
6
|
+
import pc from "picocolors";
|
|
7
|
+
export const c = pc;
|
|
8
|
+
export const palette = {
|
|
9
|
+
brand: pc.cyan,
|
|
10
|
+
accent: pc.magenta,
|
|
11
|
+
ok: pc.green,
|
|
12
|
+
warn: pc.yellow,
|
|
13
|
+
err: pc.red,
|
|
14
|
+
dim: pc.dim,
|
|
15
|
+
bold: pc.bold,
|
|
16
|
+
hint: pc.gray,
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=colors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colors.js","sourceRoot":"","sources":["../../src/lib/colors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;AAEpB,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,KAAK,EAAE,EAAE,CAAC,IAAI;IACd,MAAM,EAAE,EAAE,CAAC,OAAO;IAClB,EAAE,EAAE,EAAE,CAAC,KAAK;IACZ,IAAI,EAAE,EAAE,CAAC,MAAM;IACf,GAAG,EAAE,EAAE,CAAC,GAAG;IACX,GAAG,EAAE,EAAE,CAAC,GAAG;IACX,IAAI,EAAE,EAAE,CAAC,IAAI;IACb,IAAI,EAAE,EAAE,CAAC,IAAI;CACd,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared process helpers. Commands invoke external tools (vite-node,
|
|
3
|
+
* vite, oxlint, oxfmt, vitest) through here so signal handling, stdio,
|
|
4
|
+
* and exit semantics are uniform everywhere.
|
|
5
|
+
*/
|
|
6
|
+
import { type ChildProcess } from "node:child_process";
|
|
7
|
+
export interface ExecOptions {
|
|
8
|
+
readonly cwd?: string;
|
|
9
|
+
readonly env?: Readonly<Record<string, string | undefined>>;
|
|
10
|
+
/** When true, suppress stdout/stderr inheritance (capture instead). */
|
|
11
|
+
readonly quiet?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** Synchronous run; returns the exit code (null → 0). For one-shot ops. */
|
|
14
|
+
export declare function execSync(cmd: string, args: readonly string[], opts?: ExecOptions): number;
|
|
15
|
+
/**
|
|
16
|
+
* Long-lived spawn that forwards SIGINT/SIGTERM to the child and escalates
|
|
17
|
+
* to SIGKILL if the child doesn't exit within `gracePeriodMs`. Resolves
|
|
18
|
+
* with the exit code when the child finally exits.
|
|
19
|
+
*/
|
|
20
|
+
export interface SpawnInteractiveOptions extends ExecOptions {
|
|
21
|
+
/** Logged once when the child exits via Ctrl+C — defaults to "Stopped." */
|
|
22
|
+
readonly stoppedMessage?: string;
|
|
23
|
+
/** Milliseconds before SIGKILL escalation. Default 4000. */
|
|
24
|
+
readonly gracePeriodMs?: number;
|
|
25
|
+
}
|
|
26
|
+
export declare function spawnInteractive(cmd: string, args: readonly string[], opts?: SpawnInteractiveOptions): {
|
|
27
|
+
child: ChildProcess;
|
|
28
|
+
done: Promise<number>;
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=exec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/lib/exec.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIzE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAC5D,uEAAuE;IACvE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,GAAE,WAAgB,GAAG,MAAM,CAO7F;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAwB,SAAQ,WAAW;IAC1D,2EAA2E;IAC3E,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,4DAA4D;IAC5D,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,IAAI,GAAE,uBAA4B,GACjC;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,CAyChD"}
|
package/dist/lib/exec.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared process helpers. Commands invoke external tools (vite-node,
|
|
3
|
+
* vite, oxlint, oxfmt, vitest) through here so signal handling, stdio,
|
|
4
|
+
* and exit semantics are uniform everywhere.
|
|
5
|
+
*/
|
|
6
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
7
|
+
import { palette } from "./colors.js";
|
|
8
|
+
/** Synchronous run; returns the exit code (null → 0). For one-shot ops. */
|
|
9
|
+
export function execSync(cmd, args, opts = {}) {
|
|
10
|
+
const result = spawnSync(cmd, args, {
|
|
11
|
+
stdio: opts.quiet ? "pipe" : "inherit",
|
|
12
|
+
cwd: opts.cwd,
|
|
13
|
+
env: opts.env ? { ...process.env, ...opts.env } : process.env,
|
|
14
|
+
});
|
|
15
|
+
return result.status ?? 0;
|
|
16
|
+
}
|
|
17
|
+
export function spawnInteractive(cmd, args, opts = {}) {
|
|
18
|
+
const child = spawn(cmd, args, {
|
|
19
|
+
stdio: "inherit",
|
|
20
|
+
cwd: opts.cwd,
|
|
21
|
+
env: opts.env ? { ...process.env, ...opts.env } : process.env,
|
|
22
|
+
});
|
|
23
|
+
let shuttingDown = false;
|
|
24
|
+
const forward = (signal) => {
|
|
25
|
+
shuttingDown = true;
|
|
26
|
+
try {
|
|
27
|
+
child.kill(signal);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// already gone
|
|
31
|
+
}
|
|
32
|
+
setTimeout(() => {
|
|
33
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
34
|
+
try {
|
|
35
|
+
child.kill("SIGKILL");
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// gone
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}, opts.gracePeriodMs ?? 4000).unref();
|
|
42
|
+
};
|
|
43
|
+
process.on("SIGINT", () => forward("SIGINT"));
|
|
44
|
+
process.on("SIGTERM", () => forward("SIGTERM"));
|
|
45
|
+
const done = new Promise((resolve) => {
|
|
46
|
+
child.on("exit", (code, signal) => {
|
|
47
|
+
if (shuttingDown || signal === "SIGINT" || signal === "SIGTERM") {
|
|
48
|
+
// eslint-disable-next-line no-console
|
|
49
|
+
console.log(`\n${palette.dim(opts.stoppedMessage ?? "Stopped.")}`);
|
|
50
|
+
resolve(0);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
resolve(code ?? 0);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
return { child, done };
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/lib/exec.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,SAAS,EAAqB,MAAM,oBAAoB,CAAC;AAEzE,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AASnC,2EAA2E;AAC3E,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,IAAuB,EAAE,OAAoB,EAAE;IACnF,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE;QAClC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;QACtC,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG;KAC9D,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;AAC5B,CAAC;AAcD,MAAM,UAAU,gBAAgB,CAC9B,GAAW,EACX,IAAuB,EACvB,OAAgC,EAAE;IAElC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;QAC7B,KAAK,EAAE,SAAS;QAChB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG;KAC9D,CAAC,CAAC;IAEH,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,MAAM,OAAO,GAAG,CAAC,MAAsB,EAAE,EAAE;QACzC,YAAY,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;QACD,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gBACzD,IAAI,CAAC;oBACH,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACxB,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO;gBACT,CAAC;YACH,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;IACzC,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhD,MAAM,IAAI,GAAG,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;QAC3C,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;YAChC,IAAI,YAAY,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBAChE,sCAAsC;gBACtC,OAAO,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;gBACnE,OAAO,CAAC,CAAC,CAAC,CAAC;gBACX,OAAO;YACT,CAAC;YACD,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-process state files under `.nwire/processes/`.
|
|
3
|
+
*
|
|
4
|
+
* Long-running CLI commands (`dev`, `run` once it shells through kernel)
|
|
5
|
+
* write one JSON record per child process they manage. `nwire ps` reads
|
|
6
|
+
* every record back to render a live table; `nwire logs <id>` reads the
|
|
7
|
+
* companion `.log` file. State files are NOT crash-safe — they're a
|
|
8
|
+
* developer convenience, not a queue.
|
|
9
|
+
*/
|
|
10
|
+
export type ProcessStatus = "starting" | "running" | "stopping" | "exited" | "crashed";
|
|
11
|
+
export interface ProcessRecord {
|
|
12
|
+
readonly id: string;
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly pid: number;
|
|
15
|
+
readonly status: ProcessStatus;
|
|
16
|
+
readonly port?: number;
|
|
17
|
+
readonly startedAt: string;
|
|
18
|
+
readonly cwd: string;
|
|
19
|
+
readonly command: string;
|
|
20
|
+
readonly logPath: string;
|
|
21
|
+
readonly lastUpdated: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function recordPath(cwd: string, id: string): string;
|
|
24
|
+
export declare function logPath(cwd: string, id: string): string;
|
|
25
|
+
export declare function ensureDir(cwd: string): void;
|
|
26
|
+
export declare function writeRecord(cwd: string, record: ProcessRecord): void;
|
|
27
|
+
export declare function readRecord(cwd: string, id: string): ProcessRecord | undefined;
|
|
28
|
+
export declare function listRecords(cwd: string): ProcessRecord[];
|
|
29
|
+
export declare function removeRecord(cwd: string, id: string): void;
|
|
30
|
+
//# sourceMappingURL=process-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-state.d.ts","sourceRoot":"","sources":["../../src/lib/process-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEvF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAMD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE3C;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAGpE;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAO7E;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,EAAE,CAmBxD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAM1D"}
|