everything-dev 0.3.3 → 1.3.3

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 (313) 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 +287 -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 +279 -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/internal/manifest-normalizer.cjs +140 -0
  123. package/dist/internal/manifest-normalizer.cjs.map +1 -0
  124. package/dist/internal/manifest-normalizer.mjs +138 -0
  125. package/dist/internal/manifest-normalizer.mjs.map +1 -0
  126. package/dist/mf.cjs +77 -0
  127. package/dist/mf.cjs.map +1 -0
  128. package/dist/mf.d.cts +19 -0
  129. package/dist/mf.d.cts.map +1 -0
  130. package/dist/mf.d.mts +19 -0
  131. package/dist/mf.d.mts.map +1 -0
  132. package/dist/mf.mjs +71 -0
  133. package/dist/mf.mjs.map +1 -0
  134. package/dist/near-cli.cjs +196 -0
  135. package/dist/near-cli.cjs.map +1 -0
  136. package/dist/near-cli.mjs +193 -0
  137. package/dist/near-cli.mjs.map +1 -0
  138. package/dist/network.cjs +9 -0
  139. package/dist/network.cjs.map +1 -0
  140. package/dist/network.mjs +8 -0
  141. package/dist/network.mjs.map +1 -0
  142. package/dist/orchestrator.cjs +441 -0
  143. package/dist/orchestrator.cjs.map +1 -0
  144. package/dist/orchestrator.d.cts +40 -0
  145. package/dist/orchestrator.d.cts.map +1 -0
  146. package/dist/orchestrator.d.mts +40 -0
  147. package/dist/orchestrator.d.mts.map +1 -0
  148. package/dist/orchestrator.mjs +436 -0
  149. package/dist/orchestrator.mjs.map +1 -0
  150. package/dist/plugin.cjs +830 -0
  151. package/dist/plugin.cjs.map +1 -0
  152. package/dist/plugin.d.cts +347 -0
  153. package/dist/plugin.d.cts.map +1 -0
  154. package/dist/plugin.d.mts +348 -0
  155. package/dist/plugin.d.mts.map +1 -0
  156. package/dist/plugin.mjs +827 -0
  157. package/dist/plugin.mjs.map +1 -0
  158. package/dist/process-registry.cjs +120 -0
  159. package/dist/process-registry.cjs.map +1 -0
  160. package/dist/process-registry.d.cts +25 -0
  161. package/dist/process-registry.d.cts.map +1 -0
  162. package/dist/process-registry.d.mts +25 -0
  163. package/dist/process-registry.d.mts.map +1 -0
  164. package/dist/process-registry.mjs +119 -0
  165. package/dist/process-registry.mjs.map +1 -0
  166. package/dist/sdk.cjs +61 -0
  167. package/dist/sdk.d.cts +5 -0
  168. package/dist/sdk.d.mts +5 -0
  169. package/dist/sdk.mjs +6 -0
  170. package/dist/shared.cjs +143 -0
  171. package/dist/shared.cjs.map +1 -0
  172. package/dist/shared.d.cts +33 -0
  173. package/dist/shared.d.cts.map +1 -0
  174. package/dist/shared.d.mts +33 -0
  175. package/dist/shared.d.mts.map +1 -0
  176. package/dist/shared.mjs +140 -0
  177. package/dist/shared.mjs.map +1 -0
  178. package/dist/types.cjs +160 -0
  179. package/dist/types.cjs.map +1 -0
  180. package/dist/types.d.cts +269 -0
  181. package/dist/types.d.cts.map +1 -0
  182. package/dist/types.d.mts +269 -0
  183. package/dist/types.d.mts.map +1 -0
  184. package/dist/types.mjs +144 -0
  185. package/dist/types.mjs.map +1 -0
  186. package/dist/ui/head.cjs +67 -0
  187. package/dist/ui/head.cjs.map +1 -0
  188. package/dist/ui/head.d.cts +19 -0
  189. package/dist/ui/head.d.cts.map +1 -0
  190. package/dist/ui/head.d.mts +19 -0
  191. package/dist/ui/head.d.mts.map +1 -0
  192. package/dist/ui/head.mjs +61 -0
  193. package/dist/ui/head.mjs.map +1 -0
  194. package/dist/ui/index.cjs +32 -0
  195. package/dist/ui/index.d.cts +7 -0
  196. package/dist/ui/index.d.mts +7 -0
  197. package/dist/ui/index.mjs +6 -0
  198. package/dist/ui/metadata.cjs +106 -0
  199. package/dist/ui/metadata.cjs.map +1 -0
  200. package/dist/ui/metadata.d.cts +35 -0
  201. package/dist/ui/metadata.d.cts.map +1 -0
  202. package/dist/ui/metadata.d.mts +35 -0
  203. package/dist/ui/metadata.d.mts.map +1 -0
  204. package/dist/ui/metadata.mjs +100 -0
  205. package/dist/ui/metadata.mjs.map +1 -0
  206. package/dist/ui/router.cjs +56 -0
  207. package/dist/ui/router.cjs.map +1 -0
  208. package/dist/ui/router.d.cts +11 -0
  209. package/dist/ui/router.d.cts.map +1 -0
  210. package/dist/ui/router.d.mts +11 -0
  211. package/dist/ui/router.d.mts.map +1 -0
  212. package/dist/ui/router.mjs +51 -0
  213. package/dist/ui/router.mjs.map +1 -0
  214. package/dist/ui/runtime.cjs +65 -0
  215. package/dist/ui/runtime.cjs.map +1 -0
  216. package/dist/ui/runtime.d.cts +29 -0
  217. package/dist/ui/runtime.d.cts.map +1 -0
  218. package/dist/ui/runtime.d.mts +29 -0
  219. package/dist/ui/runtime.d.mts.map +1 -0
  220. package/dist/ui/runtime.mjs +53 -0
  221. package/dist/ui/runtime.mjs.map +1 -0
  222. package/dist/ui/types.cjs +0 -0
  223. package/dist/ui/types.d.cts +52 -0
  224. package/dist/ui/types.d.cts.map +1 -0
  225. package/dist/ui/types.d.mts +52 -0
  226. package/dist/ui/types.d.mts.map +1 -0
  227. package/dist/ui/types.mjs +1 -0
  228. package/dist/utils/banner.cjs +24 -0
  229. package/dist/utils/banner.cjs.map +1 -0
  230. package/dist/utils/banner.mjs +23 -0
  231. package/dist/utils/banner.mjs.map +1 -0
  232. package/dist/utils/linkify.cjs +15 -0
  233. package/dist/utils/linkify.cjs.map +1 -0
  234. package/dist/utils/linkify.mjs +14 -0
  235. package/dist/utils/linkify.mjs.map +1 -0
  236. package/dist/utils/run.cjs +40 -0
  237. package/dist/utils/run.cjs.map +1 -0
  238. package/dist/utils/run.mjs +39 -0
  239. package/dist/utils/run.mjs.map +1 -0
  240. package/dist/utils/theme.cjs +44 -0
  241. package/dist/utils/theme.cjs.map +1 -0
  242. package/dist/utils/theme.mjs +37 -0
  243. package/dist/utils/theme.mjs.map +1 -0
  244. package/package.json +269 -80
  245. package/src/api-contract.ts +309 -0
  246. package/src/api.ts +181 -0
  247. package/src/app.ts +346 -0
  248. package/src/cli/catalog.ts +49 -0
  249. package/src/cli/help.ts +13 -0
  250. package/src/cli/init.ts +386 -0
  251. package/src/cli/parse.ts +130 -0
  252. package/src/cli/prompts.ts +64 -0
  253. package/src/cli.ts +203 -1507
  254. package/src/components/dev-view.tsx +307 -255
  255. package/src/components/streaming-view.ts +164 -128
  256. package/src/config.ts +462 -532
  257. package/src/contract.meta.ts +96 -0
  258. package/src/contract.ts +164 -561
  259. package/src/dev-logs.ts +85 -0
  260. package/src/dev-session.ts +318 -0
  261. package/src/fastkv.ts +153 -0
  262. package/src/federation.server.ts +43 -0
  263. package/src/host.ts +526 -0
  264. package/src/index.ts +6 -3
  265. package/src/integrity.ts +54 -0
  266. package/src/internal/manifest-normalizer.ts +251 -0
  267. package/src/mf.ts +105 -0
  268. package/src/near-cli.ts +284 -0
  269. package/src/network.ts +3 -0
  270. package/src/orchestrator.ts +648 -0
  271. package/src/plugin.ts +1130 -2311
  272. package/src/process-registry.ts +154 -0
  273. package/src/scripts/sync-api-contract.ts +24 -0
  274. package/src/sdk.ts +14 -0
  275. package/src/shared.ts +206 -0
  276. package/src/types.ts +152 -206
  277. package/src/ui/head.ts +34 -27
  278. package/src/ui/index.ts +3 -3
  279. package/src/ui/metadata.ts +95 -0
  280. package/src/ui/router.ts +22 -6
  281. package/src/ui/runtime.ts +55 -6
  282. package/src/ui/types.ts +24 -11
  283. package/src/utils/banner.ts +10 -6
  284. package/src/utils/run.ts +26 -27
  285. package/src/utils/theme.ts +3 -66
  286. package/src/components/monitor-view.tsx +0 -475
  287. package/src/components/status-view.tsx +0 -173
  288. package/src/lib/env.ts +0 -109
  289. package/src/lib/near-cli.ts +0 -289
  290. package/src/lib/nova.ts +0 -266
  291. package/src/lib/orchestrator.ts +0 -276
  292. package/src/lib/process-registry.ts +0 -166
  293. package/src/lib/process.ts +0 -550
  294. package/src/lib/resource-monitor/assertions.ts +0 -234
  295. package/src/lib/resource-monitor/command.ts +0 -283
  296. package/src/lib/resource-monitor/diff.ts +0 -157
  297. package/src/lib/resource-monitor/errors.ts +0 -127
  298. package/src/lib/resource-monitor/index.ts +0 -305
  299. package/src/lib/resource-monitor/platform/darwin.ts +0 -306
  300. package/src/lib/resource-monitor/platform/index.ts +0 -35
  301. package/src/lib/resource-monitor/platform/linux.ts +0 -332
  302. package/src/lib/resource-monitor/platform/windows.ts +0 -298
  303. package/src/lib/resource-monitor/snapshot.ts +0 -217
  304. package/src/lib/resource-monitor/types.ts +0 -74
  305. package/src/lib/session-recorder/errors.ts +0 -102
  306. package/src/lib/session-recorder/flows/login.ts +0 -210
  307. package/src/lib/session-recorder/index.ts +0 -361
  308. package/src/lib/session-recorder/playwright.ts +0 -257
  309. package/src/lib/session-recorder/report.ts +0 -353
  310. package/src/lib/session-recorder/server.ts +0 -268
  311. package/src/lib/session-recorder/types.ts +0 -115
  312. package/src/lib/sync.ts +0 -1
  313. 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
+ }