everything-dev 0.3.2 → 1.3.2

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 (308) hide show
  1. package/README.md +64 -0
  2. package/cli.js +10 -0
  3. package/dist/_virtual/_rolldown/runtime.cjs +29 -0
  4. package/dist/api-contract.cjs +172 -0
  5. package/dist/api-contract.cjs.map +1 -0
  6. package/dist/api-contract.mjs +171 -0
  7. package/dist/api-contract.mjs.map +1 -0
  8. package/dist/api.cjs +124 -0
  9. package/dist/api.cjs.map +1 -0
  10. package/dist/api.d.cts +36 -0
  11. package/dist/api.d.cts.map +1 -0
  12. package/dist/api.d.mts +36 -0
  13. package/dist/api.d.mts.map +1 -0
  14. package/dist/api.mjs +119 -0
  15. package/dist/api.mjs.map +1 -0
  16. package/dist/app.cjs +156 -0
  17. package/dist/app.cjs.map +1 -0
  18. package/dist/app.mjs +153 -0
  19. package/dist/app.mjs.map +1 -0
  20. package/dist/cli/catalog.cjs +30 -0
  21. package/dist/cli/catalog.cjs.map +1 -0
  22. package/dist/cli/catalog.mjs +29 -0
  23. package/dist/cli/catalog.mjs.map +1 -0
  24. package/dist/cli/help.cjs +16 -0
  25. package/dist/cli/help.cjs.map +1 -0
  26. package/dist/cli/help.mjs +16 -0
  27. package/dist/cli/help.mjs.map +1 -0
  28. package/dist/cli/init.cjs +317 -0
  29. package/dist/cli/init.cjs.map +1 -0
  30. package/dist/cli/init.d.cts +36 -0
  31. package/dist/cli/init.d.cts.map +1 -0
  32. package/dist/cli/init.d.mts +36 -0
  33. package/dist/cli/init.d.mts.map +1 -0
  34. package/dist/cli/init.mjs +309 -0
  35. package/dist/cli/init.mjs.map +1 -0
  36. package/dist/cli/parse.cjs +96 -0
  37. package/dist/cli/parse.cjs.map +1 -0
  38. package/dist/cli/parse.mjs +95 -0
  39. package/dist/cli/parse.mjs.map +1 -0
  40. package/dist/cli/prompts.cjs +42 -0
  41. package/dist/cli/prompts.cjs.map +1 -0
  42. package/dist/cli/prompts.mjs +41 -0
  43. package/dist/cli/prompts.mjs.map +1 -0
  44. package/dist/cli.cjs +167 -0
  45. package/dist/cli.cjs.map +1 -0
  46. package/dist/cli.d.cts +1 -0
  47. package/dist/cli.d.mts +1 -0
  48. package/dist/cli.mjs +166 -0
  49. package/dist/cli.mjs.map +1 -0
  50. package/dist/components/dev-view.cjs +307 -0
  51. package/dist/components/dev-view.cjs.map +1 -0
  52. package/dist/components/dev-view.mjs +306 -0
  53. package/dist/components/dev-view.mjs.map +1 -0
  54. package/dist/components/streaming-view.cjs +146 -0
  55. package/dist/components/streaming-view.cjs.map +1 -0
  56. package/dist/components/streaming-view.mjs +144 -0
  57. package/dist/components/streaming-view.mjs.map +1 -0
  58. package/dist/config.cjs +280 -0
  59. package/dist/config.cjs.map +1 -0
  60. package/dist/config.d.cts +35 -0
  61. package/dist/config.d.cts.map +1 -0
  62. package/dist/config.d.mts +35 -0
  63. package/dist/config.d.mts.map +1 -0
  64. package/dist/config.mjs +266 -0
  65. package/dist/config.mjs.map +1 -0
  66. package/dist/contract.cjs +209 -0
  67. package/dist/contract.cjs.map +1 -0
  68. package/dist/contract.d.cts +490 -0
  69. package/dist/contract.d.cts.map +1 -0
  70. package/dist/contract.d.mts +490 -0
  71. package/dist/contract.d.mts.map +1 -0
  72. package/dist/contract.meta.cjs +104 -0
  73. package/dist/contract.meta.cjs.map +1 -0
  74. package/dist/contract.meta.d.cts +141 -0
  75. package/dist/contract.meta.d.cts.map +1 -0
  76. package/dist/contract.meta.d.mts +141 -0
  77. package/dist/contract.meta.d.mts.map +1 -0
  78. package/dist/contract.meta.mjs +102 -0
  79. package/dist/contract.meta.mjs.map +1 -0
  80. package/dist/contract.mjs +186 -0
  81. package/dist/contract.mjs.map +1 -0
  82. package/dist/dev-logs.cjs +53 -0
  83. package/dist/dev-logs.cjs.map +1 -0
  84. package/dist/dev-logs.mjs +51 -0
  85. package/dist/dev-logs.mjs.map +1 -0
  86. package/dist/dev-session.cjs +195 -0
  87. package/dist/dev-session.cjs.map +1 -0
  88. package/dist/dev-session.mjs +194 -0
  89. package/dist/dev-session.mjs.map +1 -0
  90. package/dist/fastkv.cjs +89 -0
  91. package/dist/fastkv.cjs.map +1 -0
  92. package/dist/fastkv.d.cts +11 -0
  93. package/dist/fastkv.d.cts.map +1 -0
  94. package/dist/fastkv.d.mts +11 -0
  95. package/dist/fastkv.d.mts.map +1 -0
  96. package/dist/fastkv.mjs +82 -0
  97. package/dist/fastkv.mjs.map +1 -0
  98. package/dist/federation.server.cjs +27 -0
  99. package/dist/federation.server.cjs.map +1 -0
  100. package/dist/federation.server.mjs +27 -0
  101. package/dist/federation.server.mjs.map +1 -0
  102. package/dist/host.cjs +367 -0
  103. package/dist/host.cjs.map +1 -0
  104. package/dist/host.d.cts +22 -0
  105. package/dist/host.d.cts.map +1 -0
  106. package/dist/host.d.mts +22 -0
  107. package/dist/host.d.mts.map +1 -0
  108. package/dist/host.mjs +364 -0
  109. package/dist/host.mjs.map +1 -0
  110. package/dist/index.cjs +122 -0
  111. package/dist/index.d.cts +7 -0
  112. package/dist/index.d.mts +7 -0
  113. package/dist/index.mjs +9 -0
  114. package/dist/integrity.cjs +39 -0
  115. package/dist/integrity.cjs.map +1 -0
  116. package/dist/integrity.d.cts +7 -0
  117. package/dist/integrity.d.cts.map +1 -0
  118. package/dist/integrity.d.mts +7 -0
  119. package/dist/integrity.d.mts.map +1 -0
  120. package/dist/integrity.mjs +35 -0
  121. package/dist/integrity.mjs.map +1 -0
  122. package/dist/mf.cjs +77 -0
  123. package/dist/mf.cjs.map +1 -0
  124. package/dist/mf.d.cts +19 -0
  125. package/dist/mf.d.cts.map +1 -0
  126. package/dist/mf.d.mts +19 -0
  127. package/dist/mf.d.mts.map +1 -0
  128. package/dist/mf.mjs +71 -0
  129. package/dist/mf.mjs.map +1 -0
  130. package/dist/near-cli.cjs +196 -0
  131. package/dist/near-cli.cjs.map +1 -0
  132. package/dist/near-cli.mjs +193 -0
  133. package/dist/near-cli.mjs.map +1 -0
  134. package/dist/network.cjs +9 -0
  135. package/dist/network.cjs.map +1 -0
  136. package/dist/network.mjs +8 -0
  137. package/dist/network.mjs.map +1 -0
  138. package/dist/orchestrator.cjs +441 -0
  139. package/dist/orchestrator.cjs.map +1 -0
  140. package/dist/orchestrator.d.cts +40 -0
  141. package/dist/orchestrator.d.cts.map +1 -0
  142. package/dist/orchestrator.d.mts +40 -0
  143. package/dist/orchestrator.d.mts.map +1 -0
  144. package/dist/orchestrator.mjs +436 -0
  145. package/dist/orchestrator.mjs.map +1 -0
  146. package/dist/plugin.cjs +825 -0
  147. package/dist/plugin.cjs.map +1 -0
  148. package/dist/plugin.d.cts +347 -0
  149. package/dist/plugin.d.cts.map +1 -0
  150. package/dist/plugin.d.mts +348 -0
  151. package/dist/plugin.d.mts.map +1 -0
  152. package/dist/plugin.mjs +822 -0
  153. package/dist/plugin.mjs.map +1 -0
  154. package/dist/process-registry.cjs +120 -0
  155. package/dist/process-registry.cjs.map +1 -0
  156. package/dist/process-registry.d.cts +25 -0
  157. package/dist/process-registry.d.cts.map +1 -0
  158. package/dist/process-registry.d.mts +25 -0
  159. package/dist/process-registry.d.mts.map +1 -0
  160. package/dist/process-registry.mjs +119 -0
  161. package/dist/process-registry.mjs.map +1 -0
  162. package/dist/sdk.cjs +61 -0
  163. package/dist/sdk.d.cts +5 -0
  164. package/dist/sdk.d.mts +5 -0
  165. package/dist/sdk.mjs +6 -0
  166. package/dist/shared.cjs +143 -0
  167. package/dist/shared.cjs.map +1 -0
  168. package/dist/shared.d.cts +33 -0
  169. package/dist/shared.d.cts.map +1 -0
  170. package/dist/shared.d.mts +33 -0
  171. package/dist/shared.d.mts.map +1 -0
  172. package/dist/shared.mjs +140 -0
  173. package/dist/shared.mjs.map +1 -0
  174. package/dist/types.cjs +160 -0
  175. package/dist/types.cjs.map +1 -0
  176. package/dist/types.d.cts +269 -0
  177. package/dist/types.d.cts.map +1 -0
  178. package/dist/types.d.mts +269 -0
  179. package/dist/types.d.mts.map +1 -0
  180. package/dist/types.mjs +144 -0
  181. package/dist/types.mjs.map +1 -0
  182. package/dist/ui/head.cjs +67 -0
  183. package/dist/ui/head.cjs.map +1 -0
  184. package/dist/ui/head.d.cts +19 -0
  185. package/dist/ui/head.d.cts.map +1 -0
  186. package/dist/ui/head.d.mts +19 -0
  187. package/dist/ui/head.d.mts.map +1 -0
  188. package/dist/ui/head.mjs +61 -0
  189. package/dist/ui/head.mjs.map +1 -0
  190. package/dist/ui/index.cjs +32 -0
  191. package/dist/ui/index.d.cts +7 -0
  192. package/dist/ui/index.d.mts +7 -0
  193. package/dist/ui/index.mjs +6 -0
  194. package/dist/ui/metadata.cjs +106 -0
  195. package/dist/ui/metadata.cjs.map +1 -0
  196. package/dist/ui/metadata.d.cts +35 -0
  197. package/dist/ui/metadata.d.cts.map +1 -0
  198. package/dist/ui/metadata.d.mts +35 -0
  199. package/dist/ui/metadata.d.mts.map +1 -0
  200. package/dist/ui/metadata.mjs +100 -0
  201. package/dist/ui/metadata.mjs.map +1 -0
  202. package/dist/ui/router.cjs +56 -0
  203. package/dist/ui/router.cjs.map +1 -0
  204. package/dist/ui/router.d.cts +11 -0
  205. package/dist/ui/router.d.cts.map +1 -0
  206. package/dist/ui/router.d.mts +11 -0
  207. package/dist/ui/router.d.mts.map +1 -0
  208. package/dist/ui/router.mjs +51 -0
  209. package/dist/ui/router.mjs.map +1 -0
  210. package/dist/ui/runtime.cjs +65 -0
  211. package/dist/ui/runtime.cjs.map +1 -0
  212. package/dist/ui/runtime.d.cts +29 -0
  213. package/dist/ui/runtime.d.cts.map +1 -0
  214. package/dist/ui/runtime.d.mts +29 -0
  215. package/dist/ui/runtime.d.mts.map +1 -0
  216. package/dist/ui/runtime.mjs +53 -0
  217. package/dist/ui/runtime.mjs.map +1 -0
  218. package/dist/ui/types.cjs +0 -0
  219. package/dist/ui/types.d.cts +52 -0
  220. package/dist/ui/types.d.cts.map +1 -0
  221. package/dist/ui/types.d.mts +52 -0
  222. package/dist/ui/types.d.mts.map +1 -0
  223. package/dist/ui/types.mjs +1 -0
  224. package/dist/utils/banner.cjs +24 -0
  225. package/dist/utils/banner.cjs.map +1 -0
  226. package/dist/utils/banner.mjs +23 -0
  227. package/dist/utils/banner.mjs.map +1 -0
  228. package/dist/utils/linkify.cjs +15 -0
  229. package/dist/utils/linkify.cjs.map +1 -0
  230. package/dist/utils/linkify.mjs +14 -0
  231. package/dist/utils/linkify.mjs.map +1 -0
  232. package/dist/utils/run.cjs +40 -0
  233. package/dist/utils/run.cjs.map +1 -0
  234. package/dist/utils/run.mjs +39 -0
  235. package/dist/utils/run.mjs.map +1 -0
  236. package/dist/utils/theme.cjs +44 -0
  237. package/dist/utils/theme.cjs.map +1 -0
  238. package/dist/utils/theme.mjs +37 -0
  239. package/dist/utils/theme.mjs.map +1 -0
  240. package/package.json +269 -80
  241. package/src/api-contract.ts +309 -0
  242. package/src/api.ts +181 -0
  243. package/src/app.ts +346 -0
  244. package/src/cli/catalog.ts +49 -0
  245. package/src/cli/help.ts +13 -0
  246. package/src/cli/init.ts +415 -0
  247. package/src/cli/parse.ts +130 -0
  248. package/src/cli/prompts.ts +64 -0
  249. package/src/cli.ts +203 -1507
  250. package/src/components/dev-view.tsx +104 -41
  251. package/src/components/streaming-view.ts +89 -22
  252. package/src/config.ts +462 -532
  253. package/src/contract.meta.ts +96 -0
  254. package/src/contract.ts +164 -561
  255. package/src/dev-logs.ts +85 -0
  256. package/src/dev-session.ts +318 -0
  257. package/src/fastkv.ts +153 -0
  258. package/src/federation.server.ts +43 -0
  259. package/src/host.ts +526 -0
  260. package/src/index.ts +6 -3
  261. package/src/integrity.ts +54 -0
  262. package/src/mf.ts +105 -0
  263. package/src/near-cli.ts +284 -0
  264. package/src/network.ts +3 -0
  265. package/src/orchestrator.ts +648 -0
  266. package/src/plugin.ts +1116 -2303
  267. package/src/process-registry.ts +154 -0
  268. package/src/scripts/sync-api-contract.ts +24 -0
  269. package/src/sdk.ts +14 -0
  270. package/src/shared.ts +206 -0
  271. package/src/types.ts +152 -206
  272. package/src/ui/head.ts +34 -27
  273. package/src/ui/index.ts +3 -3
  274. package/src/ui/metadata.ts +95 -0
  275. package/src/ui/router.ts +22 -6
  276. package/src/ui/runtime.ts +55 -6
  277. package/src/ui/types.ts +24 -11
  278. package/src/utils/banner.ts +10 -6
  279. package/src/utils/run.ts +26 -27
  280. package/src/utils/theme.ts +3 -66
  281. package/src/components/monitor-view.tsx +0 -475
  282. package/src/components/status-view.tsx +0 -173
  283. package/src/lib/env.ts +0 -109
  284. package/src/lib/near-cli.ts +0 -289
  285. package/src/lib/nova.ts +0 -266
  286. package/src/lib/orchestrator.ts +0 -276
  287. package/src/lib/process-registry.ts +0 -166
  288. package/src/lib/process.ts +0 -549
  289. package/src/lib/resource-monitor/assertions.ts +0 -234
  290. package/src/lib/resource-monitor/command.ts +0 -283
  291. package/src/lib/resource-monitor/diff.ts +0 -157
  292. package/src/lib/resource-monitor/errors.ts +0 -127
  293. package/src/lib/resource-monitor/index.ts +0 -305
  294. package/src/lib/resource-monitor/platform/darwin.ts +0 -306
  295. package/src/lib/resource-monitor/platform/index.ts +0 -35
  296. package/src/lib/resource-monitor/platform/linux.ts +0 -332
  297. package/src/lib/resource-monitor/platform/windows.ts +0 -298
  298. package/src/lib/resource-monitor/snapshot.ts +0 -217
  299. package/src/lib/resource-monitor/types.ts +0 -74
  300. package/src/lib/session-recorder/errors.ts +0 -102
  301. package/src/lib/session-recorder/flows/login.ts +0 -210
  302. package/src/lib/session-recorder/index.ts +0 -361
  303. package/src/lib/session-recorder/playwright.ts +0 -257
  304. package/src/lib/session-recorder/report.ts +0 -353
  305. package/src/lib/session-recorder/server.ts +0 -267
  306. package/src/lib/session-recorder/types.ts +0 -115
  307. package/src/lib/sync.ts +0 -1
  308. package/src/ui/files.ts +0 -134
package/src/app.ts ADDED
@@ -0,0 +1,346 @@
1
+ import { existsSync } from "node:fs";
2
+ import { createConnection } from "node:net";
3
+ import { join } from "node:path";
4
+ import { Effect } from "effect";
5
+ import {
6
+ getProjectRoot,
7
+ isLocalDevelopmentTarget,
8
+ parsePort,
9
+ resolveLocalDevelopmentPath,
10
+ } from "./config";
11
+ import { getNetworkIdForAccount } from "./network";
12
+ import { makeDevProcess, type ProcessCallbacks, type ProcessHandle } from "./orchestrator";
13
+ import type { ProcessRegistry } from "./process-registry";
14
+ import type { BosConfig, RuntimeConfig, RuntimePluginConfig } from "./types";
15
+
16
+ export interface AppOrchestrator {
17
+ packages: string[];
18
+ env: Record<string, string>;
19
+ description: string;
20
+ bosConfig: BosConfig;
21
+ runtimeConfig: RuntimeConfig;
22
+ port?: number;
23
+ interactive?: boolean;
24
+ }
25
+
26
+ const STARTUP_ORDER = ["ui-ssr", "ui", "api", "plugin", "host-build", "host"];
27
+ const DEFAULT_HOST_PORT = 3000;
28
+ const DEFAULT_UI_PORT = 3002;
29
+ const DEFAULT_API_PORT = 3014;
30
+ const DEFAULT_PLUGIN_PORT_START = 3021;
31
+
32
+ const sortByOrder = (packages: string[]): string[] => {
33
+ return [...packages].sort((a, b) => {
34
+ const aIdx = a.startsWith("plugin:")
35
+ ? STARTUP_ORDER.indexOf("plugin")
36
+ : STARTUP_ORDER.indexOf(a);
37
+ const bIdx = b.startsWith("plugin:")
38
+ ? STARTUP_ORDER.indexOf("plugin")
39
+ : STARTUP_ORDER.indexOf(b);
40
+ if (aIdx === -1 && bIdx === -1) return 0;
41
+ if (aIdx === -1) return 1;
42
+ if (bIdx === -1) return -1;
43
+ return aIdx - bIdx;
44
+ });
45
+ };
46
+
47
+ // Note: log filtering and persistence lives at the CLI layer.
48
+
49
+ export interface DevServersHandle {
50
+ handles: ProcessHandle[];
51
+ shutdown: Effect.Effect<void>;
52
+ }
53
+
54
+ export const startDevServers = (
55
+ orchestrator: AppOrchestrator,
56
+ callbacks: ProcessCallbacks,
57
+ registry?: ProcessRegistry,
58
+ ) => {
59
+ const run = Effect.gen(function* () {
60
+ const orderedPackages = sortByOrder(orchestrator.packages);
61
+ const handles: ProcessHandle[] = [];
62
+
63
+ const startProcess = (pkg: string) => {
64
+ const portOverride = pkg === "host" ? orchestrator.port : undefined;
65
+ return makeDevProcess(
66
+ pkg,
67
+ orchestrator.env,
68
+ callbacks,
69
+ portOverride,
70
+ orchestrator.bosConfig,
71
+ orchestrator.runtimeConfig,
72
+ registry,
73
+ );
74
+ };
75
+
76
+ const startGroup = (packages: string[]) =>
77
+ Effect.forEach(packages, startProcess, { concurrency: "unbounded" });
78
+
79
+ const awaitReady = (pkg: string, handle: ProcessHandle) =>
80
+ Effect.race(
81
+ handle.waitForReady,
82
+ Effect.sleep("30 seconds").pipe(
83
+ Effect.andThen(
84
+ Effect.sync(() => {
85
+ callbacks.onLog(pkg, "Timeout waiting for ready, continuing...", true);
86
+ }),
87
+ ),
88
+ ),
89
+ );
90
+
91
+ const nonHostPackages = orderedPackages.filter((pkg) => pkg !== "host");
92
+ const hostPackages = orderedPackages.filter((pkg) => pkg === "host");
93
+
94
+ const nonHostHandles = yield* startGroup(nonHostPackages);
95
+ handles.push(...nonHostHandles);
96
+
97
+ yield* Effect.forEach(
98
+ nonHostHandles.map((handle, index) => ({
99
+ handle,
100
+ pkg: nonHostPackages[index] ?? handle.name,
101
+ })),
102
+ ({ handle, pkg }) => awaitReady(pkg, handle),
103
+ { concurrency: "unbounded" },
104
+ );
105
+
106
+ const hostHandles = yield* startGroup(hostPackages);
107
+ handles.push(...hostHandles);
108
+
109
+ yield* Effect.forEach(
110
+ hostHandles.map((handle, index) => ({ handle, pkg: hostPackages[index] ?? handle.name })),
111
+ ({ handle, pkg }) => awaitReady(pkg, handle),
112
+ { concurrency: "unbounded" },
113
+ );
114
+
115
+ const shutdown = Effect.gen(function* () {
116
+ const reversed = [...handles].reverse();
117
+ for (const handle of reversed) {
118
+ yield* Effect.tryPromise({
119
+ try: () => handle.kill(),
120
+ catch: () => null,
121
+ }).pipe(Effect.ignore);
122
+ }
123
+ });
124
+
125
+ return { handles, shutdown } satisfies DevServersHandle;
126
+ });
127
+
128
+ return run;
129
+ };
130
+
131
+ export function detectLocalPackages(
132
+ bosConfig?: BosConfig,
133
+ runtimeConfig?: RuntimeConfig,
134
+ ): string[] {
135
+ const packages: string[] = [];
136
+ const configDir = getProjectRoot();
137
+
138
+ const uiLocalPath =
139
+ runtimeConfig?.ui.localPath ??
140
+ resolveLocalDevelopmentPath(bosConfig?.app.ui.development, configDir);
141
+ if (uiLocalPath && existsSync(join(uiLocalPath, "package.json"))) {
142
+ packages.push("ui");
143
+ }
144
+
145
+ const apiLocalPath =
146
+ runtimeConfig?.api.localPath ??
147
+ resolveLocalDevelopmentPath(bosConfig?.app.api.development, configDir);
148
+ if (apiLocalPath && existsSync(join(apiLocalPath, "package.json"))) {
149
+ packages.push("api");
150
+ }
151
+
152
+ const hostLocalPath = resolveLocalDevelopmentPath(bosConfig?.app.host.development, configDir);
153
+ if (hostLocalPath && existsSync(join(hostLocalPath, "package.json"))) {
154
+ packages.push("host");
155
+ } else if (existsSync(join(configDir, "host", "package.json"))) {
156
+ packages.push("host");
157
+ }
158
+
159
+ for (const [pluginId, pluginConfig] of Object.entries(runtimeConfig?.plugins ?? {})) {
160
+ if (pluginConfig.localPath && existsSync(join(pluginConfig.localPath, "package.json"))) {
161
+ packages.push(`plugin:${pluginId}`);
162
+ }
163
+ }
164
+
165
+ return packages;
166
+ }
167
+
168
+ export function buildRuntimeConfig(
169
+ bosConfig: BosConfig,
170
+ options: {
171
+ uiSource?: "local" | "remote";
172
+ apiSource?: "local" | "remote";
173
+ hostUrl: string;
174
+ proxy?: string;
175
+ env?: "development" | "production";
176
+ plugins?: Record<string, RuntimePluginConfig>;
177
+ },
178
+ ): RuntimeConfig {
179
+ const configDir = getProjectRoot();
180
+ const uiConfig = bosConfig.app.ui;
181
+ const apiConfig = bosConfig.app.api;
182
+ const uiSource = options.uiSource ?? "local";
183
+ const apiSource = options.apiSource ?? "local";
184
+ const uiLocalPath = resolveLocalDevelopmentPath(uiConfig.development, configDir);
185
+ const apiLocalPath = resolveLocalDevelopmentPath(apiConfig.development, configDir);
186
+ const uiLocalUrl =
187
+ !uiLocalPath && uiConfig.development && !isLocalDevelopmentTarget(uiConfig.development)
188
+ ? uiConfig.development
189
+ : "";
190
+ const apiLocalUrl =
191
+ !apiLocalPath && apiConfig.development && !isLocalDevelopmentTarget(apiConfig.development)
192
+ ? apiConfig.development
193
+ : "";
194
+
195
+ return {
196
+ env: options.env ?? "development",
197
+ account: bosConfig.account,
198
+ domain: bosConfig.domain,
199
+ networkId: getNetworkIdForAccount(bosConfig.account),
200
+ hostUrl: options.hostUrl,
201
+ shared: bosConfig.shared,
202
+ ui: uiConfig
203
+ ? {
204
+ name: uiConfig.name,
205
+ url: uiSource === "remote" ? (uiConfig.production ?? "") : uiLocalUrl,
206
+ entry:
207
+ uiSource === "remote"
208
+ ? `${uiConfig.production ?? ""}/mf-manifest.json`
209
+ : uiLocalUrl
210
+ ? `${uiLocalUrl}/mf-manifest.json`
211
+ : "/mf-manifest.json",
212
+ localPath: uiSource === "local" ? (uiLocalPath ?? undefined) : undefined,
213
+ port: uiSource === "local" && uiLocalUrl ? parsePort(uiLocalUrl) : undefined,
214
+ ssrUrl: uiSource === "remote" ? uiConfig.ssr : undefined,
215
+ ssrIntegrity: uiSource === "remote" ? uiConfig.ssrIntegrity : undefined,
216
+ integrity: uiSource === "remote" ? uiConfig.productionIntegrity : undefined,
217
+ source: uiSource === "local" ? (uiLocalPath ? "local" : "remote") : "remote",
218
+ }
219
+ : {
220
+ name: "ui",
221
+ url: "",
222
+ entry: "/mf-manifest.json",
223
+ source: uiSource,
224
+ },
225
+ api: apiConfig
226
+ ? {
227
+ name: apiConfig.name,
228
+ url: apiSource === "remote" ? (apiConfig.production ?? "") : apiLocalUrl,
229
+ entry:
230
+ apiSource === "remote"
231
+ ? `${apiConfig.production ?? ""}/mf-manifest.json`
232
+ : apiLocalUrl
233
+ ? `${apiLocalUrl}/mf-manifest.json`
234
+ : "/mf-manifest.json",
235
+ localPath: apiSource === "local" ? (apiLocalPath ?? undefined) : undefined,
236
+ port: apiSource === "local" && apiLocalUrl ? parsePort(apiLocalUrl) : undefined,
237
+ source: apiSource === "local" ? (apiLocalPath ? "local" : "remote") : "remote",
238
+ proxy: options.proxy ?? apiConfig.proxy,
239
+ variables: apiConfig.variables,
240
+ secrets: apiConfig.secrets,
241
+ integrity: apiSource === "remote" ? apiConfig.productionIntegrity : undefined,
242
+ }
243
+ : {
244
+ name: "api",
245
+ url: "",
246
+ entry: "/mf-manifest.json",
247
+ source: apiSource,
248
+ },
249
+ plugins: options.plugins,
250
+ };
251
+ }
252
+
253
+ function probeTcpOpen(port: number, timeoutMs = 250): Promise<boolean> {
254
+ return new Promise((resolve) => {
255
+ const socket = createConnection({ host: "127.0.0.1", port });
256
+ const timer = setTimeout(() => {
257
+ socket.destroy();
258
+ resolve(false);
259
+ }, timeoutMs);
260
+
261
+ socket.once("connect", () => {
262
+ clearTimeout(timer);
263
+ socket.destroy();
264
+ resolve(true);
265
+ });
266
+
267
+ socket.once("error", () => {
268
+ clearTimeout(timer);
269
+ resolve(false);
270
+ });
271
+ });
272
+ }
273
+
274
+ async function pickAvailablePort(preferred: number, usedPorts: Set<number>): Promise<number> {
275
+ let port = preferred;
276
+ while (usedPorts.has(port) || (await probeTcpOpen(port))) {
277
+ port += 1;
278
+ }
279
+ usedPorts.add(port);
280
+ return port;
281
+ }
282
+
283
+ function withLocalRuntimeUrl<
284
+ T extends { url: string; entry: string; port?: number; localPath?: string },
285
+ >(entry: T, port: number): T {
286
+ const url = `http://localhost:${port}`;
287
+ return {
288
+ ...entry,
289
+ url,
290
+ entry: `${url}/mf-manifest.json`,
291
+ port,
292
+ };
293
+ }
294
+
295
+ export async function prepareDevelopmentRuntimeConfig(
296
+ runtimeConfig: RuntimeConfig,
297
+ options?: { hostPort?: number; ssr?: boolean },
298
+ ): Promise<RuntimeConfig> {
299
+ const usedPorts = new Set<number>();
300
+ const hostPort = await pickAvailablePort(
301
+ options?.hostPort ??
302
+ (runtimeConfig.hostUrl ? parsePort(runtimeConfig.hostUrl) : DEFAULT_HOST_PORT),
303
+ usedPorts,
304
+ );
305
+
306
+ const next: RuntimeConfig = {
307
+ ...runtimeConfig,
308
+ hostUrl: `http://localhost:${hostPort}`,
309
+ ui: { ...runtimeConfig.ui },
310
+ api: { ...runtimeConfig.api },
311
+ plugins: runtimeConfig.plugins ? { ...runtimeConfig.plugins } : undefined,
312
+ };
313
+
314
+ if (next.ui.source === "local" && next.ui.localPath) {
315
+ const uiPort = await pickAvailablePort(next.ui.port ?? DEFAULT_UI_PORT, usedPorts);
316
+ next.ui = withLocalRuntimeUrl(next.ui, uiPort);
317
+ if (options?.ssr) {
318
+ const ssrPort = await pickAvailablePort(uiPort + 1, usedPorts);
319
+ next.ui.ssrUrl = `http://localhost:${ssrPort}`;
320
+ } else {
321
+ next.ui.ssrUrl = undefined;
322
+ }
323
+ }
324
+
325
+ if (next.api.source === "local" && next.api.localPath) {
326
+ const apiPort = await pickAvailablePort(next.api.port ?? DEFAULT_API_PORT, usedPorts);
327
+ next.api = withLocalRuntimeUrl(next.api, apiPort);
328
+ }
329
+
330
+ if (next.plugins) {
331
+ const entries = Object.entries(next.plugins).sort(([a], [b]) => a.localeCompare(b));
332
+ let pluginBasePort = DEFAULT_PLUGIN_PORT_START;
333
+
334
+ for (const [pluginId, plugin] of entries) {
335
+ if (plugin.source !== "local" || !plugin.localPath) {
336
+ continue;
337
+ }
338
+
339
+ const pluginPort = await pickAvailablePort(plugin.port ?? pluginBasePort, usedPorts);
340
+ next.plugins[pluginId] = withLocalRuntimeUrl(plugin, pluginPort);
341
+ pluginBasePort = pluginPort + 1;
342
+ }
343
+ }
344
+
345
+ return next;
346
+ }
@@ -0,0 +1,49 @@
1
+ import { bosContract } from "../contract";
2
+ import { type CliCommandMeta, cliCommandMeta } from "../contract.meta";
3
+
4
+ export type CommandDescriptor = {
5
+ key: keyof typeof bosContract;
6
+ commandPath: string[];
7
+ summary: string;
8
+ meta: CliCommandMeta;
9
+ procedure: (typeof bosContract)[keyof typeof bosContract];
10
+ };
11
+
12
+ function splitCamelCase(value: string): string[] {
13
+ return value
14
+ .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
15
+ .split(/\s+/)
16
+ .map((part) => part.trim())
17
+ .filter(Boolean)
18
+ .map((part) => part.toLowerCase());
19
+ }
20
+
21
+ export const commandCatalog: CommandDescriptor[] = (
22
+ Object.entries(bosContract) as Array<
23
+ [keyof typeof bosContract, (typeof bosContract)[keyof typeof bosContract]]
24
+ >
25
+ ).map(([key, procedure]) => {
26
+ const meta = cliCommandMeta[key as keyof typeof cliCommandMeta] ?? {
27
+ summary: splitCamelCase(String(key)).join(" "),
28
+ };
29
+ return {
30
+ key,
31
+ commandPath: meta.commandPath ?? splitCamelCase(String(key)),
32
+ summary: meta.summary,
33
+ meta,
34
+ procedure,
35
+ };
36
+ });
37
+
38
+ export function findCommandDescriptor(
39
+ args: string[],
40
+ ): { descriptor: CommandDescriptor; consumed: number } | null {
41
+ const sorted = [...commandCatalog].sort((a, b) => b.commandPath.length - a.commandPath.length);
42
+ for (const descriptor of sorted) {
43
+ const parts = args.slice(0, descriptor.commandPath.length).map((part) => part.toLowerCase());
44
+ if (parts.join(" ") === descriptor.commandPath.join(" ")) {
45
+ return { descriptor, consumed: descriptor.commandPath.length };
46
+ }
47
+ }
48
+ return null;
49
+ }
@@ -0,0 +1,13 @@
1
+ import { commandCatalog } from "./catalog";
2
+
3
+ export function printHelp() {
4
+ process.stdout.write(`everything-dev commands\n\n`);
5
+
6
+ for (const command of commandCatalog) {
7
+ process.stdout.write(` everything-dev ${command.commandPath.join(" ")}`);
8
+ process.stdout.write(command.meta.longRunning ? " (long running)" : "");
9
+ process.stdout.write(`\n ${command.summary}\n`);
10
+ }
11
+
12
+ process.stdout.write(`\n'bos' is an alias for 'everything-dev'.\n`);
13
+ }