@nwire/cli 0.9.2 → 0.10.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 (201) hide show
  1. package/dist/cache-runner.d.ts +0 -1
  2. package/dist/cache-runner.js +107 -9
  3. package/dist/cli.d.ts +3 -6
  4. package/dist/cli.js +3 -6
  5. package/dist/commands/bench.d.ts +0 -1
  6. package/dist/commands/bench.js +0 -1
  7. package/dist/commands/build.d.ts +0 -1
  8. package/dist/commands/build.js +0 -1
  9. package/dist/commands/cache.d.ts +0 -1
  10. package/dist/commands/cache.js +0 -1
  11. package/dist/commands/check.d.ts +0 -1
  12. package/dist/commands/check.js +0 -1
  13. package/dist/commands/dev.d.ts +0 -1
  14. package/dist/commands/dev.js +0 -1
  15. package/dist/commands/doctor.d.ts +1 -2
  16. package/dist/commands/doctor.js +14 -15
  17. package/dist/commands/fmt.d.ts +0 -1
  18. package/dist/commands/fmt.js +0 -1
  19. package/dist/commands/greeting.d.ts +0 -1
  20. package/dist/commands/greeting.js +0 -1
  21. package/dist/commands/infra.d.ts +0 -1
  22. package/dist/commands/infra.js +0 -1
  23. package/dist/commands/lint.d.ts +0 -1
  24. package/dist/commands/lint.js +0 -1
  25. package/dist/commands/logs.d.ts +0 -1
  26. package/dist/commands/logs.js +0 -1
  27. package/dist/commands/ls.d.ts +0 -1
  28. package/dist/commands/ls.js +0 -1
  29. package/dist/commands/mcp.d.ts +0 -1
  30. package/dist/commands/mcp.js +0 -1
  31. package/dist/commands/please.d.ts +0 -1
  32. package/dist/commands/please.js +0 -1
  33. package/dist/commands/ps.d.ts +0 -1
  34. package/dist/commands/ps.js +0 -1
  35. package/dist/commands/replay.d.ts +0 -1
  36. package/dist/commands/replay.js +0 -1
  37. package/dist/commands/run.d.ts +0 -1
  38. package/dist/commands/run.js +0 -1
  39. package/dist/commands/studio.d.ts +0 -1
  40. package/dist/commands/studio.js +16 -6
  41. package/dist/commands/test.d.ts +0 -1
  42. package/dist/commands/test.js +0 -1
  43. package/dist/commands/trace.d.ts +0 -1
  44. package/dist/commands/trace.js +0 -1
  45. package/dist/commands/watch.d.ts +0 -1
  46. package/dist/commands/watch.js +0 -1
  47. package/dist/index.d.ts +0 -1
  48. package/dist/index.js +0 -1
  49. package/dist/lib/colors.d.ts +0 -1
  50. package/dist/lib/colors.js +0 -1
  51. package/dist/lib/dev-entry.d.ts +0 -1
  52. package/dist/lib/dev-entry.js +0 -1
  53. package/dist/lib/ensure-scan.d.ts +0 -1
  54. package/dist/lib/ensure-scan.js +0 -1
  55. package/dist/lib/exec.d.ts +0 -1
  56. package/dist/lib/exec.js +0 -1
  57. package/dist/lib/layout.d.ts +0 -1
  58. package/dist/lib/layout.js +0 -1
  59. package/dist/lib/package-manager.d.ts +0 -1
  60. package/dist/lib/package-manager.js +0 -1
  61. package/dist/lib/process-state.d.ts +0 -1
  62. package/dist/lib/process-state.js +0 -1
  63. package/dist/lib/project.d.ts +0 -1
  64. package/dist/lib/project.js +0 -1
  65. package/dist/lib/run-task.d.ts +0 -1
  66. package/dist/lib/run-task.js +0 -1
  67. package/dist/lib/scan-cache.d.ts +0 -1
  68. package/dist/lib/scan-cache.js +0 -1
  69. package/dist/lib/script-runner.d.ts +0 -1
  70. package/dist/lib/script-runner.js +0 -1
  71. package/dist/lib/sse.d.ts +0 -1
  72. package/dist/lib/sse.js +0 -1
  73. package/dist/lib/version.d.ts +0 -1
  74. package/dist/lib/version.js +0 -1
  75. package/dist/lib/vite-node.d.ts +0 -1
  76. package/dist/lib/vite-node.js +0 -1
  77. package/dist/lib/wire-discovery.d.ts +0 -1
  78. package/dist/lib/wire-discovery.js +0 -1
  79. package/dist/load-config.d.ts +0 -1
  80. package/dist/load-config.js +0 -1
  81. package/dist/ls-runner.d.ts +0 -1
  82. package/dist/ls-runner.js +0 -1
  83. package/dist/ui/dev-dashboard.d.ts +0 -1
  84. package/dist/ui/dev-dashboard.js +0 -1
  85. package/dist/ui/greeting.d.ts +0 -1
  86. package/dist/ui/greeting.js +0 -1
  87. package/dist/ui/process-table.d.ts +0 -1
  88. package/dist/ui/process-table.js +0 -1
  89. package/package.json +5 -6
  90. package/dist/__tests__/bench.test.d.ts +0 -2
  91. package/dist/__tests__/bench.test.d.ts.map +0 -1
  92. package/dist/__tests__/bench.test.js +0 -94
  93. package/dist/__tests__/bench.test.js.map +0 -1
  94. package/dist/__tests__/doctor.test.d.ts +0 -10
  95. package/dist/__tests__/doctor.test.d.ts.map +0 -1
  96. package/dist/__tests__/doctor.test.js +0 -105
  97. package/dist/__tests__/doctor.test.js.map +0 -1
  98. package/dist/__tests__/replay.test.d.ts +0 -2
  99. package/dist/__tests__/replay.test.d.ts.map +0 -1
  100. package/dist/__tests__/replay.test.js +0 -203
  101. package/dist/__tests__/replay.test.js.map +0 -1
  102. package/dist/__tests__/trace.test.d.ts +0 -2
  103. package/dist/__tests__/trace.test.d.ts.map +0 -1
  104. package/dist/__tests__/trace.test.js +0 -136
  105. package/dist/__tests__/trace.test.js.map +0 -1
  106. package/dist/__tests__/watch.test.d.ts +0 -2
  107. package/dist/__tests__/watch.test.d.ts.map +0 -1
  108. package/dist/__tests__/watch.test.js +0 -110
  109. package/dist/__tests__/watch.test.js.map +0 -1
  110. package/dist/cache-runner.d.ts.map +0 -1
  111. package/dist/cache-runner.js.map +0 -1
  112. package/dist/cli.d.ts.map +0 -1
  113. package/dist/cli.js.map +0 -1
  114. package/dist/commands/bench.d.ts.map +0 -1
  115. package/dist/commands/bench.js.map +0 -1
  116. package/dist/commands/build.d.ts.map +0 -1
  117. package/dist/commands/build.js.map +0 -1
  118. package/dist/commands/cache.d.ts.map +0 -1
  119. package/dist/commands/cache.js.map +0 -1
  120. package/dist/commands/check.d.ts.map +0 -1
  121. package/dist/commands/check.js.map +0 -1
  122. package/dist/commands/dev.d.ts.map +0 -1
  123. package/dist/commands/dev.js.map +0 -1
  124. package/dist/commands/doctor.d.ts.map +0 -1
  125. package/dist/commands/doctor.js.map +0 -1
  126. package/dist/commands/fmt.d.ts.map +0 -1
  127. package/dist/commands/fmt.js.map +0 -1
  128. package/dist/commands/greeting.d.ts.map +0 -1
  129. package/dist/commands/greeting.js.map +0 -1
  130. package/dist/commands/infra.d.ts.map +0 -1
  131. package/dist/commands/infra.js.map +0 -1
  132. package/dist/commands/lint.d.ts.map +0 -1
  133. package/dist/commands/lint.js.map +0 -1
  134. package/dist/commands/logs.d.ts.map +0 -1
  135. package/dist/commands/logs.js.map +0 -1
  136. package/dist/commands/ls.d.ts.map +0 -1
  137. package/dist/commands/ls.js.map +0 -1
  138. package/dist/commands/mcp.d.ts.map +0 -1
  139. package/dist/commands/mcp.js.map +0 -1
  140. package/dist/commands/please.d.ts.map +0 -1
  141. package/dist/commands/please.js.map +0 -1
  142. package/dist/commands/ps.d.ts.map +0 -1
  143. package/dist/commands/ps.js.map +0 -1
  144. package/dist/commands/replay.d.ts.map +0 -1
  145. package/dist/commands/replay.js.map +0 -1
  146. package/dist/commands/run.d.ts.map +0 -1
  147. package/dist/commands/run.js.map +0 -1
  148. package/dist/commands/studio.d.ts.map +0 -1
  149. package/dist/commands/studio.js.map +0 -1
  150. package/dist/commands/test.d.ts.map +0 -1
  151. package/dist/commands/test.js.map +0 -1
  152. package/dist/commands/trace.d.ts.map +0 -1
  153. package/dist/commands/trace.js.map +0 -1
  154. package/dist/commands/watch.d.ts.map +0 -1
  155. package/dist/commands/watch.js.map +0 -1
  156. package/dist/index.d.ts.map +0 -1
  157. package/dist/index.js.map +0 -1
  158. package/dist/kernel-instance.d.ts +0 -8
  159. package/dist/kernel-instance.d.ts.map +0 -1
  160. package/dist/kernel-instance.js +0 -13
  161. package/dist/kernel-instance.js.map +0 -1
  162. package/dist/lib/colors.d.ts.map +0 -1
  163. package/dist/lib/colors.js.map +0 -1
  164. package/dist/lib/dev-entry.d.ts.map +0 -1
  165. package/dist/lib/dev-entry.js.map +0 -1
  166. package/dist/lib/ensure-scan.d.ts.map +0 -1
  167. package/dist/lib/ensure-scan.js.map +0 -1
  168. package/dist/lib/exec.d.ts.map +0 -1
  169. package/dist/lib/exec.js.map +0 -1
  170. package/dist/lib/layout.d.ts.map +0 -1
  171. package/dist/lib/layout.js.map +0 -1
  172. package/dist/lib/package-manager.d.ts.map +0 -1
  173. package/dist/lib/package-manager.js.map +0 -1
  174. package/dist/lib/process-state.d.ts.map +0 -1
  175. package/dist/lib/process-state.js.map +0 -1
  176. package/dist/lib/project.d.ts.map +0 -1
  177. package/dist/lib/project.js.map +0 -1
  178. package/dist/lib/run-task.d.ts.map +0 -1
  179. package/dist/lib/run-task.js.map +0 -1
  180. package/dist/lib/scan-cache.d.ts.map +0 -1
  181. package/dist/lib/scan-cache.js.map +0 -1
  182. package/dist/lib/script-runner.d.ts.map +0 -1
  183. package/dist/lib/script-runner.js.map +0 -1
  184. package/dist/lib/sse.d.ts.map +0 -1
  185. package/dist/lib/sse.js.map +0 -1
  186. package/dist/lib/version.d.ts.map +0 -1
  187. package/dist/lib/version.js.map +0 -1
  188. package/dist/lib/vite-node.d.ts.map +0 -1
  189. package/dist/lib/vite-node.js.map +0 -1
  190. package/dist/lib/wire-discovery.d.ts.map +0 -1
  191. package/dist/lib/wire-discovery.js.map +0 -1
  192. package/dist/load-config.d.ts.map +0 -1
  193. package/dist/load-config.js.map +0 -1
  194. package/dist/ls-runner.d.ts.map +0 -1
  195. package/dist/ls-runner.js.map +0 -1
  196. package/dist/ui/dev-dashboard.d.ts.map +0 -1
  197. package/dist/ui/dev-dashboard.js.map +0 -1
  198. package/dist/ui/greeting.d.ts.map +0 -1
  199. package/dist/ui/greeting.js.map +0 -1
  200. package/dist/ui/process-table.d.ts.map +0 -1
  201. package/dist/ui/process-table.js.map +0 -1
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=cache-runner.d.ts.map
@@ -31,10 +31,21 @@ async function main() {
31
31
  // "App" means either:
32
32
  // - `AppDefinition` (legacy `defineApp(name, { modules })`)
33
33
  // - bootable `App` (modern `createApp({ modules })`)
34
- // Both expose `modules: ModuleDefinition[]` which is all the scanner
35
- // needs we normalize them into the AppDefinition shape buildCache
36
- // expects.
34
+ // Resolve the app(s). 0.10 createApp returns an App marked with
35
+ // `$nwireApp: true`. Recognized export names:
36
+ // - allApps: App[] | apps: App[]
37
+ // - default: App | App[]
38
+ // - app: App
39
+ // - buildApp(): App | Promise<App> ← 0.10 factory pattern
40
+ // - bootstrap(): { app: App, ... } ← test-bootstrap pattern
41
+ // - bootstrap(opts): { app: App, ... }
42
+ //
43
+ // Factory results that boot the App themselves (bootstrap functions
44
+ // that call .start() and run an endpoint) are also accepted — we
45
+ // pull the App handle off the return value and skip the start/stop
46
+ // dance.
37
47
  let apps = [];
48
+ let appsAlreadyBooted = false;
38
49
  if (Array.isArray(mod.allApps))
39
50
  apps = mod.allApps;
40
51
  else if (Array.isArray(mod.apps))
@@ -45,26 +56,100 @@ async function main() {
45
56
  apps = [mod.default];
46
57
  else if (isAppLike(mod.app))
47
58
  apps = [mod.app];
48
- else {
59
+ else if (typeof mod.buildApp === "function") {
60
+ const built = await mod.buildApp();
61
+ const candidate = isAppLike(built) ? built : findAppInResult(built);
62
+ if (isAppLike(candidate))
63
+ apps = [candidate];
64
+ }
65
+ else if (typeof mod.bootstrap === "function") {
66
+ // Bootstrap usually starts the App and runs an endpoint. We try
67
+ // common signatures: `bootstrap({port,test})`, `bootstrap(port?)`.
68
+ // Returned shape is anything from { app, running } to { nest, nwireApp }
69
+ // to a bare App — we duck-find the first $nwireApp value in the result.
70
+ //
71
+ // 10s watchdog: some bootstrap functions never resolve (e.g. they
72
+ // wait on Nest's signal-driven lifecycle). The scanner falls back to
73
+ // "no apps found" rather than hanging the build pipeline.
74
+ const callWithTimeout = async (fn) => {
75
+ return await Promise.race([
76
+ fn(),
77
+ new Promise((_, reject) => setTimeout(() => reject(new Error("bootstrap watchdog (10s)")), 10_000)),
78
+ ]);
79
+ };
80
+ let result;
81
+ try {
82
+ result = await callWithTimeout(() => mod.bootstrap({ port: 0, test: true }));
83
+ }
84
+ catch {
85
+ try {
86
+ result = await callWithTimeout(() => mod.bootstrap(0));
87
+ }
88
+ catch {
89
+ /* unscannable — leave apps empty */
90
+ }
91
+ }
92
+ const candidate = isAppLike(result) ? result : findAppInResult(result);
93
+ if (isAppLike(candidate)) {
94
+ apps = [candidate];
95
+ appsAlreadyBooted = true;
96
+ // Tear down the endpoint the bootstrap opened — we only need the
97
+ // App's runtime state for the scan.
98
+ const r = result;
99
+ if (typeof r?.running?.shutdown === "function") {
100
+ try {
101
+ await r.running.shutdown("scan");
102
+ }
103
+ catch {
104
+ /* ignore */
105
+ }
106
+ }
107
+ }
108
+ }
109
+ if (apps.length === 0) {
49
110
  apps = Object.values(mod).filter(isAppLike);
50
111
  }
51
112
  if (apps.length === 0) {
52
113
  console.error(`nwire cache: no apps found in ${appsPath}.\n` +
53
- `Expected: exported \`app\`, \`apps\`, or \`allApps\` either an AppDefinition (\`defineApp\`) or a runnable App (\`createApp\`).\n` +
114
+ `Expected one of: exported \`app\`, \`apps\`, \`allApps\`, or a \`buildApp()\` factory returning an App from createApp.\n` +
54
115
  `Optional: nwire.config.ts with { appsEntry: "..." } to point at a custom location.`);
55
116
  process.exit(1);
56
117
  }
118
+ // The forge plugin registers handlers/actors/projections/queries on the
119
+ // dispatcher during the AppBooting hook — so the dispatcher is only
120
+ // populated AFTER `app.start()`. Boot each app for the scan (unless the
121
+ // bootstrap factory already did), then stop it.
122
+ if (!appsAlreadyBooted) {
123
+ for (const a of apps) {
124
+ const app = a;
125
+ if (app.$nwireApp && typeof app.start === "function") {
126
+ await app.start();
127
+ }
128
+ }
129
+ }
57
130
  const normalized = apps.map(toAppDefinitionShape);
58
- // Route bindings are declared at the app layer via `httpInterface().wire()`
59
- // and surface in Studio through the running wire's `/_nwire/*` introspection
60
- // mount, not through the cache. The scan is module-domain-only.
61
131
  const cache = buildCache(normalized);
132
+ for (const a of apps) {
133
+ const app = a;
134
+ if (app.$nwireApp && typeof app.stop === "function") {
135
+ try {
136
+ await app.stop();
137
+ }
138
+ catch {
139
+ /* ignore — the bootstrap may have already torn things down */
140
+ }
141
+ }
142
+ }
62
143
  const outDir = resolve(cwd, config.cacheDir ?? ".nwire");
63
144
  await writeCache(cache, outDir);
64
145
  // eslint-disable-next-line no-console
65
146
  console.log(`nwire cache: wrote ${cache.apps.length} apps, ${cache.modules.length} modules, ` +
66
147
  `${cache.actions.length} actions, ${cache.events.length} events, ` +
67
148
  `${cache.resolvers.length} resolvers to ${outDir}/`);
149
+ // Some bootstrap functions leave foreign-framework servers (Nest,
150
+ // Fastify) listening even after we tear down the Nwire side. Force
151
+ // process exit so the scan doesn't hang the CI pipeline.
152
+ process.exit(0);
68
153
  }
69
154
  function isAppLike(x) {
70
155
  if (typeof x !== "object" || x === null)
@@ -72,6 +157,20 @@ function isAppLike(x) {
72
157
  const a = x;
73
158
  return a.$kind === "app-definition" || a.$nwireApp === true;
74
159
  }
160
+ /**
161
+ * Bootstrap/factory functions return wrapper objects in many shapes —
162
+ * `{ app, running }`, `{ nest, nwireApp }`, `{ app, close }`, etc.
163
+ * Find the first property whose value is App-like.
164
+ */
165
+ function findAppInResult(result) {
166
+ if (typeof result !== "object" || result === null)
167
+ return undefined;
168
+ for (const value of Object.values(result)) {
169
+ if (isAppLike(value))
170
+ return value;
171
+ }
172
+ return undefined;
173
+ }
75
174
  /**
76
175
  * Normalize either flavor of "app" into the AppDefinition shape the
77
176
  * scanner reads. `createApp` returns an `App` with `appName` + the
@@ -103,4 +202,3 @@ main().catch((err) => {
103
202
  console.error(err);
104
203
  process.exit(1);
105
204
  });
106
- //# sourceMappingURL=cache-runner.js.map
package/dist/cli.d.ts CHANGED
@@ -2,15 +2,12 @@
2
2
  /**
3
3
  * `nwire` — the umbrella CLI. Built on citty: one root command, one
4
4
  * subcommand per file under `commands/`. The CLI is intentionally thin —
5
- * every command delegates to either the kernel (long-lived processes,
6
- * future cross-surface dispatch) or a small set of execution helpers
7
- * (`viteNode`, `spawnInteractive`).
5
+ * every command delegates to a small set of execution helpers
6
+ * (`viteNode`, `spawnInteractive`) and, where needed, an in-tree
7
+ * RunnerSupervisor for long-lived processes.
8
8
  *
9
9
  * Adding a new command:
10
10
  * 1. write packages/nwire-cli/src/commands/<name>.ts using `defineCommand`
11
11
  * 2. import + register it below
12
- * 3. (later) when it should be reachable from Studio/MCP, also
13
- * `kernel.router.register("<name>", handler)` in kernel-instance.ts
14
12
  */
15
13
  export {};
16
- //# sourceMappingURL=cli.d.ts.map
package/dist/cli.js CHANGED
@@ -2,15 +2,13 @@
2
2
  /**
3
3
  * `nwire` — the umbrella CLI. Built on citty: one root command, one
4
4
  * subcommand per file under `commands/`. The CLI is intentionally thin —
5
- * every command delegates to either the kernel (long-lived processes,
6
- * future cross-surface dispatch) or a small set of execution helpers
7
- * (`viteNode`, `spawnInteractive`).
5
+ * every command delegates to a small set of execution helpers
6
+ * (`viteNode`, `spawnInteractive`) and, where needed, an in-tree
7
+ * RunnerSupervisor for long-lived processes.
8
8
  *
9
9
  * Adding a new command:
10
10
  * 1. write packages/nwire-cli/src/commands/<name>.ts using `defineCommand`
11
11
  * 2. import + register it below
12
- * 3. (later) when it should be reachable from Studio/MCP, also
13
- * `kernel.router.register("<name>", handler)` in kernel-instance.ts
14
12
  */
15
13
  import { defineCommand, runMain } from "citty";
16
14
  import { benchCommand } from "./commands/bench.js";
@@ -75,4 +73,3 @@ if (userArgs.length === 0) {
75
73
  else {
76
74
  void runMain(main);
77
75
  }
78
- //# sourceMappingURL=cli.js.map
@@ -100,4 +100,3 @@ export declare const benchCommand: import("citty").CommandDef<{
100
100
  };
101
101
  }>;
102
102
  export {};
103
- //# sourceMappingURL=bench.d.ts.map
@@ -202,4 +202,3 @@ export const benchCommand = defineCommand({
202
202
  process.exit(0);
203
203
  },
204
204
  });
205
- //# sourceMappingURL=bench.js.map
@@ -10,4 +10,3 @@ export declare const buildCommand: import("citty").CommandDef<{
10
10
  description: string;
11
11
  };
12
12
  }>;
13
- //# sourceMappingURL=build.d.ts.map
@@ -68,4 +68,3 @@ export const buildCommand = defineCommand({
68
68
  process.exit(await runTaskList(tasks));
69
69
  },
70
70
  });
71
- //# sourceMappingURL=build.js.map
@@ -4,4 +4,3 @@
4
4
  * fingerprint cheap-path and always re-runs the cache builder.
5
5
  */
6
6
  export declare const cacheCommand: import("citty").CommandDef<import("citty").ArgsDef>;
7
- //# sourceMappingURL=cache.d.ts.map
@@ -15,4 +15,3 @@ export const cacheCommand = defineCommand({
15
15
  process.exit(rebuilt ? 0 : 1);
16
16
  },
17
17
  });
18
- //# sourceMappingURL=cache.js.map
@@ -11,4 +11,3 @@
11
11
  * `node_modules/.bin`.
12
12
  */
13
13
  export declare const checkCommand: import("citty").CommandDef<import("citty").ArgsDef>;
14
- //# sourceMappingURL=check.d.ts.map
@@ -43,4 +43,3 @@ export const checkCommand = defineCommand({
43
43
  process.exit(code);
44
44
  },
45
45
  });
46
- //# sourceMappingURL=check.js.map
@@ -8,4 +8,3 @@
8
8
  * sees the dev session from any other shell.
9
9
  */
10
10
  export declare const devCommand: import("citty").CommandDef<import("citty").ArgsDef>;
11
- //# sourceMappingURL=dev.d.ts.map
@@ -173,4 +173,3 @@ export const devCommand = defineCommand({
173
173
  process.exit(exitCode);
174
174
  },
175
175
  });
176
- //# sourceMappingURL=dev.js.map
@@ -6,7 +6,7 @@
6
6
  * failures (warnings still allow boot), 1 otherwise.
7
7
  *
8
8
  * Born from the Phase F dev-loop bugs: lightship port collisions, missing
9
- * `api.inspect(app)`, stale `.nwire/` cache, wrong probe paths. Each
9
+ * httpKoa inspect mount, stale `.nwire/` cache, wrong probe paths. Each
10
10
  * check here exists because Alex hit the bug live; the doctor exists so
11
11
  * the next team member doesn't.
12
12
  *
@@ -56,4 +56,3 @@ export declare const doctorCommand: import("citty").CommandDef<{
56
56
  description: string;
57
57
  };
58
58
  }>;
59
- //# sourceMappingURL=doctor.d.ts.map
@@ -6,7 +6,7 @@
6
6
  * failures (warnings still allow boot), 1 otherwise.
7
7
  *
8
8
  * Born from the Phase F dev-loop bugs: lightship port collisions, missing
9
- * `api.inspect(app)`, stale `.nwire/` cache, wrong probe paths. Each
9
+ * httpKoa inspect mount, stale `.nwire/` cache, wrong probe paths. Each
10
10
  * check here exists because Alex hit the bug live; the doctor exists so
11
11
  * the next team member doesn't.
12
12
  *
@@ -79,7 +79,7 @@ const workspaceCheck = {
79
79
  return {
80
80
  status: "warn",
81
81
  message: "no apps/, src/, or nwire.config.ts",
82
- hint: "if this is a L1/L2 starter that's fine; for L4 add apps/<name>/main.ts",
82
+ hint: "single-folder starters use app/main.ts; multi-bounded-context layouts use apps/<name>/main.ts",
83
83
  };
84
84
  }
85
85
  return { status: "pass", message: `apps:${hasApps} src:${hasSrc} config:${hasConfig}` };
@@ -164,11 +164,11 @@ const composeCollisionCheck = {
164
164
  };
165
165
  const inspectMountCheck = {
166
166
  name: "inspect-mount",
167
- description: "Every L4 example calls `api.inspect(app)`",
167
+ description: "Every entry boots `httpKoa({ inspect: true })` for Studio",
168
168
  run: (ctx) => {
169
- // Scan apps/*/main.ts (or apps/*/<name>/main.ts) for createApp + missing .inspect().
170
- // Best-effort grep — produces warnings not failures, since not every app
171
- // wants the introspection surface in production wires.
169
+ // Scan apps/*/main.ts (or apps/*/<name>/main.ts) for httpKoa missing
170
+ // inspect. Best-effort grep — produces warnings not failures, since
171
+ // production wires usually want inspect gated by auth middleware.
172
172
  const appsDir = join(ctx.cwd, "apps");
173
173
  if (!existsSync(appsDir))
174
174
  return { status: "info", message: "no apps/ folder" };
@@ -177,17 +177,17 @@ const inspectMountCheck = {
177
177
  if (!entry.endsWith("main.ts") && !entry.endsWith("main.js"))
178
178
  continue;
179
179
  const text = readFileSync(entry, "utf8");
180
- const looksLikeL4 = /createApp|app\.start\(\)/.test(text);
181
- const hasInspect = /\.inspect\(/.test(text);
182
- if (looksLikeL4 && !hasInspect) {
180
+ const usesKoa = /\bhttpKoa\s*\(/.test(text);
181
+ const hasInspect = /inspect\s*:\s*(true|\{)/.test(text);
182
+ if (usesKoa && !hasInspect) {
183
183
  offenders.push(relative(ctx.cwd, entry));
184
184
  }
185
185
  }
186
186
  if (offenders.length === 0)
187
- return { status: "pass", message: "all L4 mains mount inspect" };
187
+ return { status: "pass", message: "all entries mount inspect" };
188
188
  return {
189
189
  status: "warn",
190
- message: `${offenders.length} app${offenders.length === 1 ? "" : "s"} missing api.inspect(app)`,
190
+ message: `${offenders.length} entr${offenders.length === 1 ? "y" : "ies"} missing httpKoa({inspect:true})`,
191
191
  hint: `Studio's Live/Trace pages will 404 against:\n - ${offenders.join("\n - ")}`,
192
192
  };
193
193
  },
@@ -251,9 +251,9 @@ const templatesCheck = {
251
251
  // This check exists so users running `nwire doctor` see what they can
252
252
  // scaffold without leaving the terminal.
253
253
  const available = [
254
- "L1minimal (httpInterface + endpoint; folder-organized routes/)",
255
- "L2service (resources/errors/middleware/store/routes folders; in-memory CRUD)",
256
- "L4enterprise (modules/<bc>/{events,actions,workflows,projections,routes})",
254
+ "minimalcreateApp + httpKoa; one folder, no DI",
255
+ "servicecontainer plugin, structured errors, route middleware, in-memory store",
256
+ "enterpriseforge: actions + events + actors + workflow + projection",
257
257
  ];
258
258
  return {
259
259
  status: "info",
@@ -420,4 +420,3 @@ export const doctorCommand = defineCommand({
420
420
  process.exit(hasFail ? 1 : 0);
421
421
  },
422
422
  });
423
- //# sourceMappingURL=doctor.js.map
@@ -15,4 +15,3 @@ export declare const fmtCommand: import("citty").CommandDef<{
15
15
  default: false;
16
16
  };
17
17
  }>;
18
- //# sourceMappingURL=fmt.d.ts.map
@@ -54,4 +54,3 @@ export const fmtCommand = defineCommand({
54
54
  process.exit(code);
55
55
  },
56
56
  });
57
- //# sourceMappingURL=fmt.js.map
@@ -3,4 +3,3 @@
3
3
  * ink so the panel is a single declarative tree we can grow over time.
4
4
  */
5
5
  export declare const greetingCommand: import("citty").CommandDef<import("citty").ArgsDef>;
6
- //# sourceMappingURL=greeting.d.ts.map
@@ -22,4 +22,3 @@ export const greetingCommand = defineCommand({
22
22
  await waitUntilExit().catch(() => { });
23
23
  },
24
24
  });
25
- //# sourceMappingURL=greeting.js.map
@@ -11,4 +11,3 @@
11
11
  * nwire infra logs <svc> # tail one service's logs
12
12
  */
13
13
  export declare const infraCommand: import("citty").CommandDef<import("citty").ArgsDef>;
14
- //# sourceMappingURL=infra.d.ts.map
@@ -150,4 +150,3 @@ export const infraCommand = defineCommand({
150
150
  }
151
151
  },
152
152
  });
153
- //# sourceMappingURL=infra.js.map
@@ -14,4 +14,3 @@ export declare const lintCommand: import("citty").CommandDef<{
14
14
  default: false;
15
15
  };
16
16
  }>;
17
- //# sourceMappingURL=lint.d.ts.map
@@ -51,4 +51,3 @@ export const lintCommand = defineCommand({
51
51
  process.exit(code);
52
52
  },
53
53
  });
54
- //# sourceMappingURL=lint.js.map
@@ -18,4 +18,3 @@ export declare const logsCommand: import("citty").CommandDef<{
18
18
  default: false;
19
19
  };
20
20
  }>;
21
- //# sourceMappingURL=logs.d.ts.map
@@ -123,4 +123,3 @@ export const logsCommand = defineCommand({
123
123
  process.on("SIGTERM", stop);
124
124
  },
125
125
  });
126
- //# sourceMappingURL=logs.js.map
@@ -3,4 +3,3 @@
3
3
  * Runs an incremental scan first so the manifest is fresh.
4
4
  */
5
5
  export declare const lsCommand: import("citty").CommandDef<import("citty").ArgsDef>;
6
- //# sourceMappingURL=ls.d.ts.map
@@ -26,4 +26,3 @@ export const lsCommand = defineCommand({
26
26
  process.exit(viteNode(builderPath, rawArgs));
27
27
  },
28
28
  });
29
- //# sourceMappingURL=ls.js.map
@@ -2,4 +2,3 @@
2
2
  * `nwire mcp` — start the MCP server on stdio for Claude / Cursor clients.
3
3
  */
4
4
  export declare const mcpCommand: import("citty").CommandDef<import("citty").ArgsDef>;
5
- //# sourceMappingURL=mcp.d.ts.map
@@ -16,4 +16,3 @@ export const mcpCommand = defineCommand({
16
16
  });
17
17
  },
18
18
  });
19
- //# sourceMappingURL=mcp.js.map
@@ -10,4 +10,3 @@ export declare const pleaseCommand: import("citty").CommandDef<{
10
10
  description: string;
11
11
  };
12
12
  }>;
13
- //# sourceMappingURL=please.d.ts.map
@@ -43,4 +43,3 @@ export const pleaseCommand = defineCommand({
43
43
  process.exit(viteNode(pleasePath, rawArgs));
44
44
  },
45
45
  });
46
- //# sourceMappingURL=please.js.map
@@ -3,4 +3,3 @@
3
3
  * record under `.nwire/processes/*.json` and renders an ink table.
4
4
  */
5
5
  export declare const psCommand: import("citty").CommandDef<import("citty").ArgsDef>;
6
- //# sourceMappingURL=ps.d.ts.map
@@ -18,4 +18,3 @@ export const psCommand = defineCommand({
18
18
  await waitUntilExit();
19
19
  },
20
20
  });
21
- //# sourceMappingURL=ps.js.map
@@ -42,4 +42,3 @@ export declare const replayCommand: import("citty").CommandDef<{
42
42
  };
43
43
  }>;
44
44
  export {};
45
- //# sourceMappingURL=replay.d.ts.map
@@ -155,4 +155,3 @@ export const replayCommand = defineCommand({
155
155
  }
156
156
  },
157
157
  });
158
- //# sourceMappingURL=replay.js.map
@@ -16,4 +16,3 @@ export declare const runCommand: import("citty").CommandDef<{
16
16
  description: string;
17
17
  };
18
18
  }>;
19
- //# sourceMappingURL=run.d.ts.map
@@ -119,4 +119,3 @@ export const runCommand = defineCommand({
119
119
  process.exit(exitCode);
120
120
  },
121
121
  });
122
- //# sourceMappingURL=run.js.map
@@ -6,4 +6,3 @@
6
6
  * right `.nwire/` and `apps/topologies/`.
7
7
  */
8
8
  export declare const studioCommand: import("citty").CommandDef<import("citty").ArgsDef>;
9
- //# sourceMappingURL=studio.d.ts.map
@@ -11,18 +11,29 @@ import { resolve, dirname } from "node:path";
11
11
  import { existsSync } from "node:fs";
12
12
  import { palette } from "../lib/colors.js";
13
13
  import { spawnInteractive } from "../lib/exec.js";
14
- const localRequire = createRequire(import.meta.url);
15
14
  export const studioCommand = defineCommand({
16
15
  meta: {
17
16
  name: "studio",
18
17
  description: "Boot Nwire Studio (Vue + Vite UI)",
19
18
  },
20
19
  async run({ rawArgs }) {
20
+ // Try resolving @nwire/studio from the consumer's cwd first (so a
21
+ // dev-deps install in their project works), then from the CLI's own
22
+ // location (covers the framework workspace + `pnpm dlx` flows).
21
23
  let studioDir;
22
- try {
23
- studioDir = dirname(localRequire.resolve("@nwire/studio/package.json"));
24
- }
25
- catch {
24
+ const tryResolveFrom = (basePath) => {
25
+ try {
26
+ const req = createRequire(basePath);
27
+ return dirname(req.resolve("@nwire/studio/package.json"));
28
+ }
29
+ catch {
30
+ return undefined;
31
+ }
32
+ };
33
+ studioDir =
34
+ tryResolveFrom(resolve(process.cwd(), "package.json")) ??
35
+ tryResolveFrom(import.meta.url);
36
+ if (!studioDir) {
26
37
  // eslint-disable-next-line no-console
27
38
  console.error(palette.err("nwire studio:") +
28
39
  " @nwire/studio not installed. `pnpm add -D @nwire/studio` first.");
@@ -49,4 +60,3 @@ export const studioCommand = defineCommand({
49
60
  process.exit(await done);
50
61
  },
51
62
  });
52
- //# sourceMappingURL=studio.js.map
@@ -23,4 +23,3 @@ export declare const testCommand: import("citty").CommandDef<{
23
23
  default: false;
24
24
  };
25
25
  }>;
26
- //# sourceMappingURL=test.d.ts.map
@@ -143,4 +143,3 @@ export const testCommand = defineCommand({
143
143
  process.exit(await runTaskList(tasks));
144
144
  },
145
145
  });
146
- //# sourceMappingURL=test.js.map
@@ -37,4 +37,3 @@ export declare const traceCommand: import("citty").CommandDef<{
37
37
  };
38
38
  }>;
39
39
  export {};
40
- //# sourceMappingURL=trace.d.ts.map
@@ -195,4 +195,3 @@ function sleep(ms, signal) {
195
195
  }, { once: true });
196
196
  });
197
197
  }
198
- //# sourceMappingURL=trace.js.map
@@ -30,4 +30,3 @@ export declare const watchCommand: import("citty").CommandDef<{
30
30
  };
31
31
  }>;
32
32
  export {};
33
- //# sourceMappingURL=watch.d.ts.map
@@ -152,4 +152,3 @@ function sleep(ms, signal) {
152
152
  }, { once: true });
153
153
  });
154
154
  }
155
- //# sourceMappingURL=watch.js.map
package/dist/index.d.ts CHANGED
@@ -8,4 +8,3 @@
8
8
  * export default defineConfig({ appsEntry: "./src/app.ts" })
9
9
  */
10
10
  export { defineConfig, type NwireConfig } from "./load-config.js";
11
- //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -8,4 +8,3 @@
8
8
  * export default defineConfig({ appsEntry: "./src/app.ts" })
9
9
  */
10
10
  export { defineConfig } from "./load-config.js";
11
- //# sourceMappingURL=index.js.map
@@ -16,4 +16,3 @@ export declare const palette: {
16
16
  bold: import("picocolors/types").Formatter;
17
17
  hint: import("picocolors/types").Formatter;
18
18
  };
19
- //# sourceMappingURL=colors.d.ts.map
@@ -15,4 +15,3 @@ export const palette = {
15
15
  bold: pc.bold,
16
16
  hint: pc.gray,
17
17
  };
18
- //# sourceMappingURL=colors.js.map
@@ -36,4 +36,3 @@ export type DevEntry = {
36
36
  export declare function resolveDevEntry(cwd: string): DevEntry | undefined;
37
37
  /** Same fallback list rendered for the "no dev entry found" error message. */
38
38
  export declare function devEntryCandidates(): readonly string[];
39
- //# sourceMappingURL=dev-entry.d.ts.map
@@ -99,4 +99,3 @@ function relPath(cwd, abs) {
99
99
  const rel = relative(cwd, abs);
100
100
  return rel === "" ? abs : rel;
101
101
  }
102
- //# sourceMappingURL=dev-entry.js.map
@@ -26,4 +26,3 @@ export interface EnsureScanResult {
26
26
  readonly fingerprint: string;
27
27
  }
28
28
  export declare function ensureScanFresh(cwd?: string, opts?: EnsureScanOptions): EnsureScanResult;
29
- //# sourceMappingURL=ensure-scan.d.ts.map
@@ -39,4 +39,3 @@ export function ensureScanFresh(cwd = process.cwd(), opts = {}) {
39
39
  writeFingerprint(cwd, fp);
40
40
  return { rebuilt: true, fingerprint: fp };
41
41
  }
42
- //# sourceMappingURL=ensure-scan.js.map
@@ -34,4 +34,3 @@ export declare function spawnInteractive(cmd: string, args: readonly string[], o
34
34
  child: ChildProcess;
35
35
  done: Promise<number>;
36
36
  };
37
- //# sourceMappingURL=exec.d.ts.map