rollipop 1.0.0-alpha.21 → 1.0.0-alpha.23

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 (161) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/{chunk-DEq-mXcV.js → _virtual/_rolldown/runtime.js} +1 -1
  3. package/dist/commands.d.ts +2 -4
  4. package/dist/commands.js +10 -3957
  5. package/dist/common/code.js +21 -0
  6. package/dist/common/constants.js +5 -0
  7. package/dist/common/env.js +33 -0
  8. package/dist/common/logger.d.ts +34 -0
  9. package/dist/common/logger.js +82 -0
  10. package/dist/common/logo.js +54 -0
  11. package/dist/common/progress-bar.js +167 -0
  12. package/dist/common/transformer.js +13 -0
  13. package/dist/common/types.d.ts +10 -0
  14. package/dist/config/compose-override.js +18 -0
  15. package/dist/config/defaults.d.ts +74 -0
  16. package/dist/config/defaults.js +74 -0
  17. package/dist/config/define-config.d.ts +13 -0
  18. package/dist/config/define-config.js +6 -0
  19. package/dist/config/index.d.ts +5 -0
  20. package/dist/config/index.js +5 -0
  21. package/dist/config/load-config.d.ts +19 -0
  22. package/dist/config/load-config.js +73 -0
  23. package/dist/config/merge-config.d.ts +12 -0
  24. package/dist/config/merge-config.js +20 -0
  25. package/dist/config/types.d.ts +452 -0
  26. package/dist/constants.d.ts +35 -0
  27. package/dist/constants.js +146 -0
  28. package/dist/core/assets.d.ts +91 -0
  29. package/dist/core/assets.js +244 -0
  30. package/dist/core/bundler.d.ts +15 -0
  31. package/dist/core/bundler.js +80 -0
  32. package/dist/core/env.d.ts +11 -0
  33. package/dist/core/env.js +36 -0
  34. package/dist/core/fs/data.js +9 -0
  35. package/dist/core/fs/storage.d.ts +15 -0
  36. package/dist/core/fs/storage.js +31 -0
  37. package/dist/core/plugins/babel-plugin.d.ts +22 -0
  38. package/dist/core/plugins/babel-plugin.js +74 -0
  39. package/dist/core/plugins/context.d.ts +10 -0
  40. package/dist/core/plugins/context.js +24 -0
  41. package/dist/core/plugins/dev-server-plugin.d.ts +13 -0
  42. package/dist/core/plugins/dev-server-plugin.js +27 -0
  43. package/dist/core/plugins/index.d.ts +13 -0
  44. package/dist/core/plugins/index.js +18 -0
  45. package/dist/core/plugins/prelude-plugin.d.ts +10 -0
  46. package/dist/core/plugins/prelude-plugin.js +23 -0
  47. package/dist/core/plugins/react-native-plugin.d.ts +36 -0
  48. package/dist/core/plugins/react-native-plugin.js +81 -0
  49. package/dist/core/plugins/reporter-plugin.d.ts +11 -0
  50. package/dist/core/plugins/reporter-plugin.js +87 -0
  51. package/dist/core/plugins/shared/filters.js +5 -0
  52. package/dist/core/plugins/swc-plugin.d.ts +26 -0
  53. package/dist/core/plugins/swc-plugin.js +108 -0
  54. package/dist/core/plugins/types.d.ts +18 -0
  55. package/dist/core/plugins/utils/source.js +10 -0
  56. package/dist/core/plugins/utils/transform-utils.js +56 -0
  57. package/dist/core/rolldown.js +313 -0
  58. package/dist/core/settings.js +19 -0
  59. package/dist/core/types.d.ts +83 -0
  60. package/dist/filter.d.ts +1 -0
  61. package/dist/filter.js +2 -0
  62. package/dist/hmr-runtime.iife.js +5 -5
  63. package/dist/index.d.ts +24 -1221
  64. package/dist/index.js +19 -4029
  65. package/dist/internal/react-native.js +24 -0
  66. package/dist/logger.js +5 -0
  67. package/dist/node/cli-utils.d.ts +10 -0
  68. package/dist/node/cli-utils.js +28 -0
  69. package/dist/node/cli.d.ts +6 -0
  70. package/dist/node/cli.js +23 -0
  71. package/dist/node/commands/agent/action.js +91 -0
  72. package/dist/node/commands/agent/command.js +10 -0
  73. package/dist/node/commands/agent/index.js +2 -0
  74. package/dist/node/commands/bundle/action.js +33 -0
  75. package/dist/node/commands/bundle/command.js +96 -0
  76. package/dist/node/commands/bundle/index.js +2 -0
  77. package/dist/node/commands/start/action.js +37 -0
  78. package/dist/node/commands/start/command.js +93 -0
  79. package/dist/node/commands/start/debugger.js +79 -0
  80. package/dist/node/commands/start/index.js +2 -0
  81. package/dist/node/commands/start/setup-interactive-mode.d.ts +20 -0
  82. package/dist/node/commands/start/setup-interactive-mode.js +107 -0
  83. package/dist/node/constants.js +4 -0
  84. package/dist/node/logger.js +5 -0
  85. package/dist/node/types.d.ts +23 -0
  86. package/dist/node/utils.js +23 -0
  87. package/dist/package.js +4 -0
  88. package/dist/runtime.js +1 -1
  89. package/dist/server/bundle.d.ts +12 -0
  90. package/dist/server/bundle.js +55 -0
  91. package/dist/server/bundler-pool.d.ts +51 -0
  92. package/dist/server/bundler-pool.js +197 -0
  93. package/dist/server/common/schema.js +19 -0
  94. package/dist/server/constants.d.ts +6 -0
  95. package/dist/server/constants.js +6 -0
  96. package/dist/server/create-dev-server.d.ts +6 -0
  97. package/dist/server/create-dev-server.js +185 -0
  98. package/dist/server/error.js +9 -0
  99. package/dist/server/events/event-bus.d.ts +12 -0
  100. package/dist/server/events/event-bus.js +16 -0
  101. package/dist/server/events/types.d.ts +37 -0
  102. package/dist/server/events/types.js +6 -0
  103. package/dist/server/index.d.ts +3 -0
  104. package/dist/server/index.js +3 -0
  105. package/dist/server/logger.js +33 -0
  106. package/dist/server/mcp/context.js +14 -0
  107. package/dist/server/mcp/server.js +86 -0
  108. package/dist/server/mcp/tools/app-log-diagnostics.js +37 -0
  109. package/dist/server/mcp/tools/build-diagnostics.js +97 -0
  110. package/dist/server/mcp/tools/build-info.js +33 -0
  111. package/dist/server/mcp/tools/device-diagnostics.js +52 -0
  112. package/dist/server/mcp/tools/index.js +277 -0
  113. package/dist/server/middlewares/request-logger.js +15 -0
  114. package/dist/server/middlewares/serve-assets.js +49 -0
  115. package/dist/server/middlewares/serve-bundle.js +72 -0
  116. package/dist/server/middlewares/sse.js +34 -0
  117. package/dist/server/middlewares/symbolicate.js +71 -0
  118. package/dist/server/sse/adapter.js +74 -0
  119. package/dist/server/sse/event-bus.js +26 -0
  120. package/dist/server/symbolicate.js +93 -0
  121. package/dist/server/types.d.ts +125 -0
  122. package/dist/server/wss/hmr-server.js +209 -0
  123. package/dist/server/wss/server.d.ts +9 -0
  124. package/dist/server/wss/server.js +70 -0
  125. package/dist/{runtime.d.cts → types/hmr.d.ts} +1 -12
  126. package/dist/types.d.ts +78 -0
  127. package/dist/utils/babel.js +11 -0
  128. package/dist/utils/build-options.js +17 -0
  129. package/dist/utils/bundle.js +6 -0
  130. package/dist/utils/config.d.ts +5 -0
  131. package/dist/utils/config.js +32 -0
  132. package/dist/utils/dev-server.js +51 -0
  133. package/dist/utils/env.js +7 -0
  134. package/dist/utils/errors.js +9 -0
  135. package/dist/utils/hash.js +8 -0
  136. package/dist/utils/id.js +28 -0
  137. package/dist/utils/node-resolve.js +42 -0
  138. package/dist/utils/promise.js +15 -0
  139. package/dist/utils/reporters.js +120 -0
  140. package/dist/utils/reset-cache.d.ts +8 -0
  141. package/dist/utils/reset-cache.js +25 -0
  142. package/dist/utils/response.js +91 -0
  143. package/dist/utils/run-build.d.ts +8 -0
  144. package/dist/utils/run-build.js +7 -0
  145. package/dist/utils/run-server.d.ts +6 -0
  146. package/dist/utils/run-server.js +20 -0
  147. package/dist/utils/runtime-target.js +9 -0
  148. package/dist/utils/serialize.js +10 -0
  149. package/dist/utils/server.js +6 -0
  150. package/dist/utils/storage.js +6 -0
  151. package/dist/utils/string.js +6 -0
  152. package/dist/utils/swc.js +10 -0
  153. package/dist/utils/terminal.js +86 -0
  154. package/dist/utils/url.js +23 -0
  155. package/package.json +56 -68
  156. package/dist/commands.cjs +0 -4008
  157. package/dist/commands.d.cts +0 -5
  158. package/dist/pluginutils.d.ts +0 -1
  159. package/dist/pluginutils.js +0 -2
  160. package/dist/runtime.cjs +0 -34
  161. /package/dist/{chunk-DXpK5_cz.js → chunk-DJV587Yu.js} +0 -0
@@ -0,0 +1,185 @@
1
+ import { createPluginContext } from "../core/plugins/context.js";
2
+ import { DevServerLogger, logger } from "./logger.js";
3
+ import { assertDevServerStatus } from "../utils/dev-server.js";
4
+ import { BundlerPool } from "./bundler-pool.js";
5
+ import { DEFAULT_HOST, DEFAULT_PORT } from "./constants.js";
6
+ import { errorHandler } from "./error.js";
7
+ import { ServerEventBus } from "./events/event-bus.js";
8
+ import { toSSEEvent } from "./sse/adapter.js";
9
+ import { plugin } from "./mcp/server.js";
10
+ import { requestLogger } from "./middlewares/request-logger.js";
11
+ import { plugin as plugin$1 } from "./middlewares/serve-assets.js";
12
+ import { plugin as plugin$2 } from "./middlewares/serve-bundle.js";
13
+ import { SSEEventPublisher } from "./sse/event-bus.js";
14
+ import { plugin as plugin$3 } from "./middlewares/sse.js";
15
+ import { plugin as plugin$4 } from "./middlewares/symbolicate.js";
16
+ import { getWebSocketUpgradeHandler } from "./wss/server.js";
17
+ import { HMRServer } from "./wss/hmr-server.js";
18
+ import url from "url";
19
+ import { createDevServerMiddleware } from "@react-native-community/cli-server-api";
20
+ import { createDevMiddleware } from "@react-native/dev-middleware";
21
+ import Fastify from "fastify";
22
+ import mitt from "mitt";
23
+ //#region src/server/create-dev-server.ts
24
+ async function createDevServer(config, options) {
25
+ const projectRoot = config.root;
26
+ const { port = DEFAULT_PORT, host = DEFAULT_HOST, https = false } = options ?? {};
27
+ if (https) throw new Error("HTTPS is not supported yet");
28
+ const serverBaseUrl = url.format({
29
+ protocol: https ? "https" : "http",
30
+ hostname: host,
31
+ port
32
+ });
33
+ await assertDevServerStatus({
34
+ devServerUrl: serverBaseUrl,
35
+ projectRoot,
36
+ port
37
+ });
38
+ const emitter = mitt();
39
+ const fastify = Fastify({
40
+ loggerInstance: new DevServerLogger(),
41
+ disableRequestLogging: true
42
+ });
43
+ const eventBus = new ServerEventBus();
44
+ const bundlerPool = new BundlerPool(config, {
45
+ host,
46
+ port
47
+ }, eventBus);
48
+ const ssePublisher = new SSEEventPublisher();
49
+ const reporter = config.reporter;
50
+ eventBus.subscribe((event) => {
51
+ const sseEvent = toSSEEvent(event);
52
+ if (sseEvent != null) ssePublisher.publish(sseEvent);
53
+ });
54
+ const { middleware: communityMiddleware, websocketEndpoints: communityWebsocketEndpoints, messageSocketEndpoint: { server: messageServer, broadcast }, eventsSocketEndpoint: { server: eventsServer, reportEvent } } = createDevServerMiddleware({
55
+ port,
56
+ host,
57
+ watchFolders: []
58
+ });
59
+ eventBus.subscribe((event) => {
60
+ switch (event.type) {
61
+ case "bundle_build_started":
62
+ case "bundle_build_done":
63
+ case "bundle_build_failed":
64
+ case "hmr_failed":
65
+ case "build_log":
66
+ case "build_error":
67
+ case "transform":
68
+ case "watch_change":
69
+ reporter?.update(event);
70
+ break;
71
+ case "client_log":
72
+ reportEvent?.(event);
73
+ reporter?.update(event);
74
+ break;
75
+ case "device_connected":
76
+ emitter.emit("device.connected", { client: event.client });
77
+ break;
78
+ case "device_message":
79
+ emitter.emit("device.message", {
80
+ client: event.client,
81
+ data: event.data
82
+ });
83
+ break;
84
+ case "device_error":
85
+ emitter.emit("device.error", {
86
+ client: event.client,
87
+ error: event.error
88
+ });
89
+ break;
90
+ case "device_disconnected":
91
+ emitter.emit("device.disconnected", { client: event.client });
92
+ break;
93
+ }
94
+ });
95
+ const { middleware: devMiddleware, websocketEndpoints } = createDevMiddleware({
96
+ serverBaseUrl,
97
+ logger: {
98
+ info(...args) {
99
+ if (args[0].includes("JavaScript logs have moved")) return;
100
+ logger.info(...args);
101
+ },
102
+ warn: logger.warn.bind(logger),
103
+ error: logger.error.bind(logger)
104
+ },
105
+ unstable_experiments: {
106
+ enableNetworkInspector: true,
107
+ enableStandaloneFuseboxShell: true
108
+ }
109
+ });
110
+ const hmrServer = new HMRServer({
111
+ bundlerPool,
112
+ eventBus
113
+ }).on("connection", (client) => eventBus.emit({
114
+ type: "device_connected",
115
+ client
116
+ })).on("message", (client, data) => eventBus.emit({
117
+ type: "device_message",
118
+ client,
119
+ data
120
+ })).on("error", (client, error) => eventBus.emit({
121
+ type: "device_error",
122
+ client,
123
+ error
124
+ })).on("close", (client) => eventBus.emit({
125
+ type: "device_disconnected",
126
+ client
127
+ }));
128
+ await fastify.register(import("@fastify/middie"));
129
+ const context = {
130
+ serverBaseUrl,
131
+ config: Object.freeze(config),
132
+ options: Object.freeze(options ?? {}),
133
+ bundlerPool,
134
+ eventBus,
135
+ message: Object.assign(messageServer, { broadcast }),
136
+ events: Object.assign(eventsServer, { reportEvent }),
137
+ hot: Object.assign(hmrServer.server, {
138
+ send: (client, eventName, payload) => {
139
+ hmrServer.send(client, JSON.stringify({
140
+ type: eventName,
141
+ payload
142
+ }));
143
+ },
144
+ sendAll: (eventName, payload) => {
145
+ hmrServer.sendAll(JSON.stringify({
146
+ type: eventName,
147
+ payload
148
+ }));
149
+ }
150
+ })
151
+ };
152
+ const devServer = {
153
+ ...context,
154
+ ...emitter,
155
+ instance: fastify,
156
+ middlewares: { use: fastify.use.bind(fastify) }
157
+ };
158
+ const { invokePostConfigureServer } = await invokeConfigureServer(devServer, config.plugins ?? []);
159
+ fastify.use(requestLogger).use(communityMiddleware).use(devMiddleware).register(plugin$4, { context }).register(plugin$2, { context }).register(plugin$1, { context }).register(plugin$3, { context }).register(plugin, { context }).setErrorHandler(errorHandler);
160
+ fastify.server.on("upgrade", getWebSocketUpgradeHandler({
161
+ ...communityWebsocketEndpoints,
162
+ ...websocketEndpoints,
163
+ "/hot": hmrServer.server
164
+ }));
165
+ await invokePostConfigureServer();
166
+ eventBus.emit({
167
+ type: "server_ready",
168
+ host,
169
+ port
170
+ });
171
+ return devServer;
172
+ }
173
+ async function invokeConfigureServer(server, plugins) {
174
+ const postConfigureServerHandlers = [];
175
+ for (const plugin of plugins) {
176
+ const context = createPluginContext(plugin.name);
177
+ const result = await plugin.configureServer?.call(context, server);
178
+ if (typeof result === "function") postConfigureServerHandlers.push(result);
179
+ }
180
+ return { invokePostConfigureServer: async () => {
181
+ for (const handler of postConfigureServerHandlers) await handler();
182
+ } };
183
+ }
184
+ //#endregion
185
+ export { createDevServer };
@@ -0,0 +1,9 @@
1
+ import { logger } from "./logger.js";
2
+ //#region src/server/error.ts
3
+ function errorHandler(error, request, reply) {
4
+ logger.error(`An error occurred while processing the request (${request.method} ${request.url}):`, error.message);
5
+ logger.debug(error);
6
+ reply.status(500).send("Internal Server Error");
7
+ }
8
+ //#endregion
9
+ export { errorHandler };
@@ -0,0 +1,12 @@
1
+ import { ServerEvent } from "./types.js";
2
+
3
+ //#region src/server/events/event-bus.d.ts
4
+ type EventListener<Event> = (event: Event) => void;
5
+ declare class EventBus<Event> {
6
+ private listeners;
7
+ emit(event: Event): void;
8
+ subscribe(listener: EventListener<Event>): () => void;
9
+ }
10
+ declare class ServerEventBus extends EventBus<ServerEvent> {}
11
+ //#endregion
12
+ export { ServerEventBus };
@@ -0,0 +1,16 @@
1
+ //#region src/server/events/event-bus.ts
2
+ var EventBus = class {
3
+ listeners = /* @__PURE__ */ new Set();
4
+ emit(event) {
5
+ for (const listener of this.listeners) listener(event);
6
+ }
7
+ subscribe(listener) {
8
+ this.listeners.add(listener);
9
+ return () => {
10
+ this.listeners.delete(listener);
11
+ };
12
+ }
13
+ };
14
+ var ServerEventBus = class extends EventBus {};
15
+ //#endregion
16
+ export { ServerEventBus };
@@ -0,0 +1,37 @@
1
+ import { MetroCompatibleClientLogEvent, ReportableEvent } from "../../types.js";
2
+ import { WebSocketClient } from "../wss/server.js";
3
+ import * as rolldownExperimental from "@rollipop/rolldown/experimental";
4
+ import * as ws from "ws";
5
+
6
+ //#region src/server/events/types.d.ts
7
+ type IdentifiedReportableEvent = ReportableEvent & {
8
+ bundlerId: string;
9
+ };
10
+ type BundlerEvent = IdentifiedReportableEvent | {
11
+ type: 'hmr_updates';
12
+ bundlerId: string;
13
+ updates: rolldownExperimental.BindingClientHmrUpdate[];
14
+ };
15
+ type ServerEvent = BundlerEvent | MetroCompatibleClientLogEvent | {
16
+ type: 'device_connected';
17
+ client: WebSocketClient;
18
+ } | {
19
+ type: 'device_message';
20
+ client: WebSocketClient;
21
+ data: ws.RawData;
22
+ } | {
23
+ type: 'device_error';
24
+ client: WebSocketClient;
25
+ error: Error;
26
+ } | {
27
+ type: 'device_disconnected';
28
+ client: WebSocketClient;
29
+ } | {
30
+ type: 'server_ready';
31
+ host: string;
32
+ port: number;
33
+ } | {
34
+ type: 'cache_reset';
35
+ };
36
+ //#endregion
37
+ export { ServerEvent };
@@ -0,0 +1,6 @@
1
+ //#region src/server/events/types.ts
2
+ function isBundlerEventForId(event, bundlerId) {
3
+ return "bundlerId" in event && event.bundlerId === bundlerId;
4
+ }
5
+ //#endregion
6
+ export { isBundlerEventForId };
@@ -0,0 +1,3 @@
1
+ import { BundleDetails, DevServer, DevServerContext, DevServerEvents, FastifyInstance, FormattedError, Middlewares, ServerOptions } from "./types.js";
2
+ import { createDevServer } from "./create-dev-server.js";
3
+ import { DEFAULT_HOST, DEFAULT_PORT, DEV_SERVER_ASSET_PATH } from "./constants.js";
@@ -0,0 +1,3 @@
1
+ import "./constants.js";
2
+ import "./create-dev-server.js";
3
+ export {};
@@ -0,0 +1,33 @@
1
+ import { Logger } from "../common/logger.js";
2
+ import chalk from "chalk";
3
+ //#region src/server/logger.ts
4
+ const logger = new Logger("dev-server");
5
+ var DevServerLogger = class {
6
+ level = "trace";
7
+ trace(...args) {
8
+ logger.trace(...args);
9
+ }
10
+ debug(...args) {
11
+ logger.debug(...args);
12
+ }
13
+ info(...args) {
14
+ logger.info(...args);
15
+ }
16
+ warn(...args) {
17
+ logger.warn(...args);
18
+ }
19
+ error(...args) {
20
+ logger.error(...args);
21
+ }
22
+ silent(...args) {
23
+ logger.trace(chalk.gray("(silent)"), ...args);
24
+ }
25
+ fatal(...args) {
26
+ logger.error(chalk.magenta("(fatal)"), ...args);
27
+ }
28
+ child(_bindings) {
29
+ return this;
30
+ }
31
+ };
32
+ //#endregion
33
+ export { DevServerLogger, logger };
@@ -0,0 +1,14 @@
1
+ import { AppLogDiagnostics } from "./tools/app-log-diagnostics.js";
2
+ import { BuildDiagnostics } from "./tools/build-diagnostics.js";
3
+ import { DeviceDiagnostics } from "./tools/device-diagnostics.js";
4
+ //#region src/server/mcp/context.ts
5
+ function createMcpToolContext(context) {
6
+ return {
7
+ context,
8
+ appLogDiagnostics: new AppLogDiagnostics(context),
9
+ buildDiagnostics: new BuildDiagnostics(context),
10
+ deviceDiagnostics: new DeviceDiagnostics(context)
11
+ };
12
+ }
13
+ //#endregion
14
+ export { createMcpToolContext };
@@ -0,0 +1,86 @@
1
+ import { createMcpToolContext } from "./context.js";
2
+ import { registerTools } from "./tools/index.js";
3
+ import { randomUUID } from "node:crypto";
4
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
6
+ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
7
+ import fp from "fastify-plugin";
8
+ //#region src/server/mcp/server.ts
9
+ function createMcpServer(options) {
10
+ const server = new McpServer({
11
+ name: "rollipop",
12
+ version: "1.0.0-alpha.23"
13
+ }, { capabilities: { logging: {} } });
14
+ registerTools(server, options);
15
+ return server;
16
+ }
17
+ const plugin = fp((fastify, options) => {
18
+ const { context } = options;
19
+ if (context.options.mcp !== true) {
20
+ fastify.all("/mcp", async (_request, reply) => {
21
+ return reply.status(503).send({ error: {
22
+ code: "MCP_DISABLED",
23
+ message: "MCP server is disabled. Start Rollipop with --mcp to enable it."
24
+ } });
25
+ });
26
+ return;
27
+ }
28
+ const toolContext = createMcpToolContext(context);
29
+ const sessions = /* @__PURE__ */ new Map();
30
+ fastify.addContentTypeParser("application/json", { parseAs: "string" }, (_req, body, done) => {
31
+ try {
32
+ done(null, JSON.parse(body));
33
+ } catch (error) {
34
+ done(error, void 0);
35
+ }
36
+ });
37
+ fastify.post("/mcp", async (request, reply) => {
38
+ const sessionId = request.headers["mcp-session-id"];
39
+ if (sessionId && sessions.has(sessionId)) {
40
+ const { transport } = sessions.get(sessionId);
41
+ await transport.handleRequest(request.raw, reply.raw, request.body);
42
+ return reply;
43
+ }
44
+ if (!sessionId && isInitializeRequest(request.body)) {
45
+ const transport = new StreamableHTTPServerTransport({
46
+ sessionIdGenerator: () => randomUUID(),
47
+ onsessioninitialized: (sid) => {
48
+ sessions.set(sid, {
49
+ transport,
50
+ server
51
+ });
52
+ }
53
+ });
54
+ transport.onclose = () => {
55
+ const sid = transport.sessionId;
56
+ if (sid) sessions.delete(sid);
57
+ };
58
+ const server = createMcpServer(toolContext);
59
+ await server.connect(transport);
60
+ await transport.handleRequest(request.raw, reply.raw, request.body);
61
+ return reply;
62
+ }
63
+ return reply.status(400).send({
64
+ jsonrpc: "2.0",
65
+ error: {
66
+ code: -32e3,
67
+ message: "Bad Request: invalid or missing session"
68
+ },
69
+ id: null
70
+ });
71
+ });
72
+ fastify.get("/mcp", async (request, reply) => {
73
+ const sessionId = request.headers["mcp-session-id"];
74
+ if (!sessionId || !sessions.has(sessionId)) return reply.status(400).send("Missing or invalid session ID");
75
+ await sessions.get(sessionId).transport.handleRequest(request.raw, reply.raw);
76
+ return reply;
77
+ });
78
+ fastify.delete("/mcp", async (request, reply) => {
79
+ const sessionId = request.headers["mcp-session-id"];
80
+ if (!sessionId || !sessions.has(sessionId)) return reply.status(404).send("Session not found");
81
+ await sessions.get(sessionId).transport.handleRequest(request.raw, reply.raw);
82
+ return reply;
83
+ });
84
+ }, { name: "mcp" });
85
+ //#endregion
86
+ export { plugin };
@@ -0,0 +1,37 @@
1
+ //#region src/server/mcp/tools/app-log-diagnostics.ts
2
+ const MAX_DIAGNOSTIC_ENTRIES = 500;
3
+ var AppLogDiagnostics = class {
4
+ logs = [];
5
+ nextLogId = 0;
6
+ constructor(context) {
7
+ context.eventBus.subscribe((event) => {
8
+ if (event.type !== "client_log") return;
9
+ this.logs.push({
10
+ id: ++this.nextLogId,
11
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
12
+ source: "client_log",
13
+ level: event.level,
14
+ args: event.data,
15
+ ...event.bundlerId != null ? { bundlerId: event.bundlerId } : {}
16
+ });
17
+ trimArray(this.logs, MAX_DIAGNOSTIC_ENTRIES);
18
+ });
19
+ }
20
+ getConsoleLogs(options) {
21
+ return filterByBundlerId(this.logs, options?.bundlerId).slice(-(options?.limit ?? 100));
22
+ }
23
+ clearConsoleLogs(options) {
24
+ this.logs = filterOutBundlerId(this.logs, options?.bundlerId);
25
+ }
26
+ };
27
+ function trimArray(entries, maxEntries) {
28
+ if (entries.length > maxEntries) entries.splice(0, entries.length - maxEntries);
29
+ }
30
+ function filterByBundlerId(entries, bundlerId) {
31
+ return bundlerId == null ? entries : entries.filter((entry) => entry.bundlerId === bundlerId);
32
+ }
33
+ function filterOutBundlerId(entries, bundlerId) {
34
+ return bundlerId == null ? [] : entries.filter((entry) => entry.bundlerId !== bundlerId);
35
+ }
36
+ //#endregion
37
+ export { AppLogDiagnostics };
@@ -0,0 +1,97 @@
1
+ //#region src/server/mcp/tools/build-diagnostics.ts
2
+ const MAX_DIAGNOSTIC_ENTRIES = 500;
3
+ var BuildDiagnostics = class {
4
+ buildLogs = [];
5
+ buildErrors = [];
6
+ nextBuildLogId = 0;
7
+ nextBuildErrorId = 0;
8
+ constructor(context) {
9
+ context.eventBus.subscribe((event) => {
10
+ switch (event.type) {
11
+ case "build_log":
12
+ this.pushBuildLog({
13
+ source: "rolldown",
14
+ level: event.level,
15
+ bundlerId: event.bundlerId,
16
+ log: event.log
17
+ });
18
+ break;
19
+ case "build_error":
20
+ this.pushBuildError({
21
+ source: "rolldown",
22
+ level: event.level,
23
+ bundlerId: event.bundlerId,
24
+ log: event.log
25
+ });
26
+ break;
27
+ case "bundle_build_failed":
28
+ this.pushBuildError({
29
+ source: "build",
30
+ level: "error",
31
+ bundlerId: event.bundlerId,
32
+ error: serializeError(event.error)
33
+ });
34
+ break;
35
+ case "hmr_failed":
36
+ this.pushBuildError({
37
+ source: "hmr",
38
+ level: "error",
39
+ bundlerId: event.bundlerId,
40
+ error: serializeError(event.error)
41
+ });
42
+ break;
43
+ }
44
+ });
45
+ }
46
+ getBuildLogs(options) {
47
+ return filterByBundlerId(this.buildLogs, options?.bundlerId).slice(-(options?.limit ?? 100));
48
+ }
49
+ getBuildErrors(options) {
50
+ return filterByBundlerId(this.buildErrors, options?.bundlerId).slice(-(options?.limit ?? 100));
51
+ }
52
+ clearBuildLogs(options) {
53
+ this.buildLogs = filterOutBundlerId(this.buildLogs, options?.bundlerId);
54
+ }
55
+ clearBuildErrors(options) {
56
+ this.buildErrors = filterOutBundlerId(this.buildErrors, options?.bundlerId);
57
+ }
58
+ clearBuildDiagnostics(options) {
59
+ this.clearBuildLogs(options);
60
+ this.clearBuildErrors(options);
61
+ }
62
+ pushBuildLog(log) {
63
+ this.buildLogs.push({
64
+ id: ++this.nextBuildLogId,
65
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
66
+ ...log
67
+ });
68
+ trimArray(this.buildLogs, MAX_DIAGNOSTIC_ENTRIES);
69
+ }
70
+ pushBuildError(error) {
71
+ this.buildErrors.push({
72
+ id: ++this.nextBuildErrorId,
73
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
74
+ ...error
75
+ });
76
+ trimArray(this.buildErrors, MAX_DIAGNOSTIC_ENTRIES);
77
+ }
78
+ };
79
+ function serializeError(error) {
80
+ if (error instanceof Error) return {
81
+ name: error.name,
82
+ message: error.message,
83
+ stack: error.stack
84
+ };
85
+ return { message: String(error) };
86
+ }
87
+ function trimArray(entries, maxEntries) {
88
+ if (entries.length > maxEntries) entries.splice(0, entries.length - maxEntries);
89
+ }
90
+ function filterByBundlerId(entries, bundlerId) {
91
+ return bundlerId == null ? entries : entries.filter((entry) => entry.bundlerId === bundlerId);
92
+ }
93
+ function filterOutBundlerId(entries, bundlerId) {
94
+ return bundlerId == null ? [] : entries.filter((entry) => entry.bundlerId !== bundlerId);
95
+ }
96
+ //#endregion
97
+ export { BuildDiagnostics };
@@ -0,0 +1,33 @@
1
+ import { loadEnv } from "../../../core/env.js";
2
+ //#region src/server/mcp/tools/build-info.ts
3
+ function getBuildInfo(config) {
4
+ return toJsonSafe({
5
+ ...config,
6
+ env: loadEnv(config)
7
+ });
8
+ }
9
+ function toJsonSafe(value, seen = /* @__PURE__ */ new WeakSet()) {
10
+ if (value == null) return value;
11
+ switch (typeof value) {
12
+ case "string":
13
+ case "number":
14
+ case "boolean": return value;
15
+ case "bigint":
16
+ case "symbol": return String(value);
17
+ case "function": return `[Function ${value.name || "anonymous"}]`;
18
+ }
19
+ if (value instanceof Date) return value.toISOString();
20
+ if (value instanceof Error) return {
21
+ name: value.name,
22
+ message: value.message,
23
+ stack: value.stack
24
+ };
25
+ if (seen.has(value)) return "[Circular]";
26
+ seen.add(value);
27
+ if (Array.isArray(value)) return value.map((item) => toJsonSafe(item, seen));
28
+ if (value instanceof Map) return Object.fromEntries(Array.from(value.entries()).map(([key, item]) => [String(key), toJsonSafe(item, seen)]));
29
+ if (value instanceof Set) return Array.from(value.values()).map((item) => toJsonSafe(item, seen));
30
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, toJsonSafe(item, seen)]));
31
+ }
32
+ //#endregion
33
+ export { getBuildInfo };
@@ -0,0 +1,52 @@
1
+ //#region src/server/mcp/tools/device-diagnostics.ts
2
+ var DeviceDiagnostics = class {
3
+ devices = /* @__PURE__ */ new Map();
4
+ constructor(context) {
5
+ context.eventBus.subscribe((event) => {
6
+ switch (event.type) {
7
+ case "device_connected":
8
+ this.devices.set(event.client.id, {
9
+ id: event.client.id,
10
+ connected: true,
11
+ connectedAt: (/* @__PURE__ */ new Date()).toISOString()
12
+ });
13
+ break;
14
+ case "device_message":
15
+ this.updateDeviceFromMessage(event.client.id, event.data);
16
+ break;
17
+ case "device_disconnected": {
18
+ const device = this.devices.get(event.client.id);
19
+ if (device != null) this.devices.set(event.client.id, {
20
+ ...device,
21
+ connected: false,
22
+ disconnectedAt: (/* @__PURE__ */ new Date()).toISOString()
23
+ });
24
+ break;
25
+ }
26
+ }
27
+ });
28
+ }
29
+ getDevices() {
30
+ return Array.from(this.devices.values());
31
+ }
32
+ updateDeviceFromMessage(clientId, data) {
33
+ const device = this.devices.get(clientId);
34
+ if (device == null) return;
35
+ try {
36
+ const message = JSON.parse(rawDataToString(data));
37
+ if (message.type !== "hmr:connected") return;
38
+ this.devices.set(clientId, {
39
+ ...device,
40
+ platform: message.platform,
41
+ bundleEntry: message.bundleEntry
42
+ });
43
+ } catch {}
44
+ }
45
+ };
46
+ function rawDataToString(data) {
47
+ if (Buffer.isBuffer(data)) return data.toString("utf8");
48
+ if (Array.isArray(data)) return Buffer.concat(data).toString("utf8");
49
+ return Buffer.from(data).toString("utf8");
50
+ }
51
+ //#endregion
52
+ export { DeviceDiagnostics };