@mindstudio-ai/local-model-tunnel 0.5.27 → 0.5.29

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.
@@ -977,6 +977,63 @@ function formatErrorForDisplay(error) {
977
977
  return parts.join("\n");
978
978
  }
979
979
 
980
+ // src/dev/execution/agent-config.ts
981
+ import { readFileSync } from "fs";
982
+ import { join as join5, dirname as dirname2 } from "path";
983
+ function readAgentConfig(projectRoot, appConfig) {
984
+ const agentInterface = appConfig.interfaces.find(
985
+ (i) => i.type === "agent" && i.enabled !== false
986
+ );
987
+ if (!agentInterface) {
988
+ throw new Error("No agent interface configured in mindstudio.json");
989
+ }
990
+ const configPath = join5(projectRoot, agentInterface.path);
991
+ let raw;
992
+ try {
993
+ raw = readFileSync(configPath, "utf-8");
994
+ } catch {
995
+ throw new Error(
996
+ `Agent config not found at ${agentInterface.path} \u2014 run your build command`
997
+ );
998
+ }
999
+ const parsed = JSON.parse(raw);
1000
+ const config2 = parsed.agent ?? parsed;
1001
+ const agentDir = dirname2(configPath);
1002
+ const systemPromptPath = join5(agentDir, config2.systemPrompt);
1003
+ let systemPrompt;
1004
+ try {
1005
+ systemPrompt = readFileSync(systemPromptPath, "utf-8");
1006
+ } catch {
1007
+ throw new Error(
1008
+ `Agent system prompt not found at ${config2.systemPrompt} \u2014 run your build command`
1009
+ );
1010
+ }
1011
+ const tools = (config2.tools ?? []).map(
1012
+ (tool) => {
1013
+ const descPath = join5(agentDir, tool.description);
1014
+ let description;
1015
+ try {
1016
+ description = readFileSync(descPath, "utf-8");
1017
+ } catch {
1018
+ throw new Error(
1019
+ `Agent tool description not found at ${tool.description} for method "${tool.method}" \u2014 run your build command`
1020
+ );
1021
+ }
1022
+ return {
1023
+ name: tool.method,
1024
+ description
1025
+ };
1026
+ }
1027
+ );
1028
+ return {
1029
+ model: config2.model,
1030
+ temperature: config2.temperature,
1031
+ maxTokens: config2.maxTokens,
1032
+ systemPrompt,
1033
+ tools
1034
+ };
1035
+ }
1036
+
980
1037
  // src/dev/execution/runner.ts
981
1038
  var DevRunner = class {
982
1039
  constructor(appId, projectRoot, startOpts = {}) {
@@ -991,6 +1048,7 @@ var DevRunner = class {
991
1048
  hadConnectionWarning = false;
992
1049
  proxyUrl;
993
1050
  proxy = null;
1051
+ appConfig = null;
994
1052
  roleOverride = null;
995
1053
  // proxyUrl is sent on every poll request so the platform dashboard can
996
1054
  // show the developer's preview URL. Also included in the start request
@@ -1002,6 +1060,9 @@ var DevRunner = class {
1002
1060
  setProxy(proxy) {
1003
1061
  this.proxy = proxy;
1004
1062
  }
1063
+ setAppConfig(appConfig) {
1064
+ this.appConfig = appConfig;
1065
+ }
1005
1066
  async start() {
1006
1067
  if (this.isRunning) {
1007
1068
  throw new Error("DevRunner is already running");
@@ -1263,16 +1324,35 @@ var DevRunner = class {
1263
1324
  }
1264
1325
  }
1265
1326
  async handleRequest(request) {
1327
+ if (request.type === "get-agent-config") {
1328
+ await this.handleGetAgentConfig(request);
1329
+ return;
1330
+ }
1266
1331
  const startTime = Date.now();
1332
+ const method = this.appConfig?.methods.find((m) => m.id === request.methodId);
1333
+ if (!method) {
1334
+ const message = `Unknown method ID: ${request.methodId}`;
1335
+ log.error("runner", message, { requestId: request.requestId, sessionId: this.session.sessionId });
1336
+ try {
1337
+ await submitDevResult(this.appId, this.session.sessionId, request.requestId, {
1338
+ type: "execute",
1339
+ success: false,
1340
+ error: { message }
1341
+ });
1342
+ } catch {
1343
+ }
1344
+ devRequestEvents.emitComplete({ id: request.requestId, success: false, duration: 0, error: message });
1345
+ return;
1346
+ }
1267
1347
  devRequestEvents.emitStart({
1268
1348
  id: request.requestId,
1269
1349
  type: request.type,
1270
- method: request.methodExport,
1350
+ method: method.export,
1271
1351
  timestamp: startTime
1272
1352
  });
1273
- log.info("runner", "Method received", { requestId: request.requestId, method: request.methodExport, source: "poll", sessionId: this.session.sessionId });
1353
+ log.info("runner", "Method received", { requestId: request.requestId, method: method.export, source: "poll", sessionId: this.session.sessionId });
1274
1354
  try {
1275
- const transpiledPath = await this.transpiler.transpile(request.methodPath);
1355
+ const transpiledPath = await this.transpiler.transpile(method.path);
1276
1356
  const auth = request.roleOverride ? {
1277
1357
  userId: this.session.auth.userId,
1278
1358
  roleAssignments: request.roleOverride.map((roleName) => ({
@@ -1282,7 +1362,7 @@ var DevRunner = class {
1282
1362
  } : this.session.auth;
1283
1363
  const result = await executeMethod({
1284
1364
  transpiledPath,
1285
- methodExport: request.methodExport,
1365
+ methodExport: method.export,
1286
1366
  input: request.input,
1287
1367
  auth,
1288
1368
  databases: this.session.databases,
@@ -1307,11 +1387,11 @@ var DevRunner = class {
1307
1387
  );
1308
1388
  const duration = Date.now() - startTime;
1309
1389
  if (result.success) {
1310
- log.info("runner", "Method complete", { requestId: request.requestId, method: request.methodExport, duration, sessionId: this.session.sessionId });
1390
+ log.info("runner", "Method complete", { requestId: request.requestId, method: method.export, duration, sessionId: this.session.sessionId });
1311
1391
  } else {
1312
1392
  log.warn("runner", "Method failed", {
1313
1393
  requestId: request.requestId,
1314
- method: request.methodExport,
1394
+ method: method.export,
1315
1395
  duration,
1316
1396
  error: result.error ? formatErrorForDisplay(result.error) : void 0,
1317
1397
  sessionId: this.session.sessionId
@@ -1320,8 +1400,8 @@ var DevRunner = class {
1320
1400
  logMethodExecution({
1321
1401
  requestId: request.requestId,
1322
1402
  sessionId: this.session.sessionId,
1323
- methodExport: request.methodExport,
1324
- methodPath: request.methodPath,
1403
+ methodExport: method.export,
1404
+ methodPath: method.path,
1325
1405
  input: request.input,
1326
1406
  roleOverride: request.roleOverride,
1327
1407
  authorizationToken: request.authorizationToken,
@@ -1338,7 +1418,7 @@ var DevRunner = class {
1338
1418
  } catch (error) {
1339
1419
  const message = error instanceof Error ? error.message : "Unknown error";
1340
1420
  const duration = Date.now() - startTime;
1341
- log.error("runner", "Method execution error", { requestId: request.requestId, method: request.methodExport, duration, error: message, sessionId: this.session.sessionId });
1421
+ log.error("runner", "Method execution error", { requestId: request.requestId, method: method.export, duration, error: message, sessionId: this.session.sessionId });
1342
1422
  try {
1343
1423
  await submitDevResult(
1344
1424
  this.appId,
@@ -1356,8 +1436,8 @@ var DevRunner = class {
1356
1436
  logMethodExecution({
1357
1437
  requestId: request.requestId,
1358
1438
  sessionId: this.session.sessionId,
1359
- methodExport: request.methodExport,
1360
- methodPath: request.methodPath,
1439
+ methodExport: method.export,
1440
+ methodPath: method.path,
1361
1441
  input: request.input,
1362
1442
  roleOverride: request.roleOverride,
1363
1443
  authorizationToken: request.authorizationToken,
@@ -1373,6 +1453,44 @@ var DevRunner = class {
1373
1453
  });
1374
1454
  }
1375
1455
  }
1456
+ async handleGetAgentConfig(request) {
1457
+ const startTime = Date.now();
1458
+ log.info("runner", "Agent config requested", { requestId: request.requestId, sessionId: this.session.sessionId });
1459
+ try {
1460
+ if (!this.appConfig) {
1461
+ throw new Error("App config not available");
1462
+ }
1463
+ const bundle = readAgentConfig(this.projectRoot, this.appConfig);
1464
+ await submitDevResult(
1465
+ this.appId,
1466
+ this.session.sessionId,
1467
+ request.requestId,
1468
+ {
1469
+ type: "get-agent-config",
1470
+ success: true,
1471
+ output: bundle
1472
+ }
1473
+ );
1474
+ log.info("runner", "Agent config sent", { requestId: request.requestId, duration: Date.now() - startTime });
1475
+ } catch (err) {
1476
+ const message = err instanceof Error ? err.message : "Unknown error";
1477
+ log.error("runner", "Agent config failed", { requestId: request.requestId, error: message });
1478
+ try {
1479
+ await submitDevResult(
1480
+ this.appId,
1481
+ this.session.sessionId,
1482
+ request.requestId,
1483
+ {
1484
+ type: "get-agent-config",
1485
+ success: false,
1486
+ error: { message }
1487
+ }
1488
+ );
1489
+ } catch (submitErr) {
1490
+ log.error("runner", "Failed to report agent config error to platform", { error: submitErr instanceof Error ? submitErr.message : String(submitErr) });
1491
+ }
1492
+ }
1493
+ }
1376
1494
  /**
1377
1495
  * Attempt to refresh expired auth credentials via the device auth flow.
1378
1496
  * Opens the browser for the user to re-authorize, polls for the new token.
@@ -1450,6 +1568,7 @@ function closeBrowserLog() {
1450
1568
 
1451
1569
  // src/dev/proxy/proxy.ts
1452
1570
  import http from "http";
1571
+ import https from "https";
1453
1572
  import { randomBytes as randomBytes4 } from "crypto";
1454
1573
  import { WebSocketServer } from "ws";
1455
1574
 
@@ -1492,11 +1611,16 @@ var ClientRegistry = class {
1492
1611
  let fallback = null;
1493
1612
  for (const client of this.clients.values()) {
1494
1613
  if (client.activeCommandId) continue;
1614
+ if (client.mode === "mirror") continue;
1495
1615
  if (client.mode === "iframe") return client;
1496
1616
  if (!fallback) fallback = client;
1497
1617
  }
1498
1618
  return fallback;
1499
1619
  }
1620
+ /** Get all connected mirror-mode clients (for relaying mirror events). */
1621
+ getMirrorClients() {
1622
+ return [...this.clients.values()].filter((c) => c.mode === "mirror");
1623
+ }
1500
1624
  getAll() {
1501
1625
  return [...this.clients.values()];
1502
1626
  }
@@ -1544,9 +1668,10 @@ var ClientRegistry = class {
1544
1668
 
1545
1669
  // src/dev/proxy/proxy.ts
1546
1670
  var DevProxy = class _DevProxy {
1547
- constructor(upstreamPort, clientContext, bindAddress = "127.0.0.1", browserAgentUrl) {
1671
+ constructor(upstreamPort, clientContext, appId, bindAddress = "127.0.0.1", browserAgentUrl) {
1548
1672
  this.upstreamPort = upstreamPort;
1549
1673
  this.clientContext = clientContext;
1674
+ this.appId = appId;
1550
1675
  this.bindAddress = bindAddress;
1551
1676
  this.browserAgentUrl = browserAgentUrl;
1552
1677
  }
@@ -1777,7 +1902,7 @@ var DevProxy = class _DevProxy {
1777
1902
  return;
1778
1903
  }
1779
1904
  clearTimeout(helloTimeout);
1780
- const mode = msg.mode === "iframe" ? "iframe" : "standalone";
1905
+ const mode = msg.mode === "iframe" ? "iframe" : msg.mode === "mirror" ? "mirror" : "standalone";
1781
1906
  const viewport = msg.viewport || {
1782
1907
  w: 0,
1783
1908
  h: 0
@@ -1799,6 +1924,9 @@ var DevProxy = class _DevProxy {
1799
1924
  appendBrowserLogEntries(msg.entries);
1800
1925
  }
1801
1926
  break;
1927
+ case "mirror":
1928
+ this.relayMirrorEvents(data.toString());
1929
+ break;
1802
1930
  }
1803
1931
  });
1804
1932
  ws.on("pong", () => {
@@ -1950,6 +2078,10 @@ var DevProxy = class _DevProxy {
1950
2078
  this.handleFontProxy(clientReq, clientRes);
1951
2079
  return;
1952
2080
  }
2081
+ if (clientReq.url === "/__mindstudio_dev__/mirror" && clientReq.method === "GET") {
2082
+ this.serveMirrorPage(clientRes);
2083
+ return;
2084
+ }
1953
2085
  }
1954
2086
  if (clientReq.method === "OPTIONS" && clientReq.headers.origin) {
1955
2087
  clientRes.writeHead(204, {
@@ -1960,9 +2092,58 @@ var DevProxy = class _DevProxy {
1960
2092
  clientRes.end();
1961
2093
  return;
1962
2094
  }
2095
+ if (clientReq.url?.startsWith("/_/")) {
2096
+ this.forwardToApi(clientReq, clientRes);
2097
+ return;
2098
+ }
1963
2099
  this.forwardToUpstream(clientReq, clientRes);
1964
2100
  }
1965
2101
  // ---------------------------------------------------------------------------
2102
+ // API forwarding (/_/ same-origin routes)
2103
+ // ---------------------------------------------------------------------------
2104
+ forwardToApi(clientReq, clientRes) {
2105
+ const cors = this.corsHeaders(clientReq);
2106
+ const originalPath = clientReq.url;
2107
+ const rest = originalPath.slice(3);
2108
+ const apiPath = `/_internal/v2/apps/${this.appId}/${rest}`;
2109
+ const apiBaseUrl = getApiBaseUrl();
2110
+ const target = new URL(apiPath, apiBaseUrl);
2111
+ const isHttps = target.protocol === "https:";
2112
+ const httpModule = isHttps ? https : http;
2113
+ const headers = {
2114
+ ...clientReq.headers,
2115
+ host: target.host
2116
+ };
2117
+ delete headers["connection"];
2118
+ delete headers["accept-encoding"];
2119
+ const proxyReq = httpModule.request(
2120
+ {
2121
+ hostname: target.hostname,
2122
+ port: target.port || (isHttps ? 443 : 80),
2123
+ path: target.pathname + target.search,
2124
+ method: clientReq.method,
2125
+ headers
2126
+ },
2127
+ (proxyRes) => {
2128
+ const responseHeaders = { ...proxyRes.headers, ...cors };
2129
+ responseHeaders["cache-control"] = "no-store";
2130
+ clientRes.writeHead(proxyRes.statusCode ?? 502, responseHeaders);
2131
+ proxyRes.pipe(clientRes);
2132
+ }
2133
+ );
2134
+ proxyReq.on("error", (err) => {
2135
+ log.warn("proxy", "API proxy error", {
2136
+ path: originalPath,
2137
+ error: err.message
2138
+ });
2139
+ if (!clientRes.headersSent) {
2140
+ clientRes.writeHead(502, cors);
2141
+ clientRes.end(`API proxy error: ${err.message}`);
2142
+ }
2143
+ });
2144
+ clientReq.pipe(proxyReq);
2145
+ }
2146
+ // ---------------------------------------------------------------------------
1966
2147
  // Upstream forwarding
1967
2148
  // ---------------------------------------------------------------------------
1968
2149
  forwardToUpstream(clientReq, clientRes) {
@@ -2040,6 +2221,91 @@ var DevProxy = class _DevProxy {
2040
2221
  clientRes.end();
2041
2222
  });
2042
2223
  }
2224
+ /** Relay a raw mirror message (already JSON-stringified) to all mirror viewers. */
2225
+ relayMirrorEvents(raw) {
2226
+ const mirrors = this.clients.getMirrorClients();
2227
+ for (const client of mirrors) {
2228
+ try {
2229
+ client.ws.send(raw);
2230
+ } catch {
2231
+ }
2232
+ }
2233
+ }
2234
+ /** Serve the mirror replay page — an rrweb Replayer in live mode. */
2235
+ serveMirrorPage(res) {
2236
+ const html = `<!DOCTYPE html>
2237
+ <html>
2238
+ <head>
2239
+ <meta charset="utf-8">
2240
+ <meta name="viewport" content="width=device-width, initial-scale=1">
2241
+ <title>Mobile Mirror</title>
2242
+ <style>
2243
+ * { margin: 0; padding: 0; box-sizing: border-box; }
2244
+ html, body { height: 100%; background: #111; overflow: hidden; }
2245
+ #player { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; }
2246
+ .replayer-wrapper { box-shadow: 0 0 40px rgba(0,0,0,0.5); border-radius: 4px; overflow: hidden; }
2247
+ #status { position: fixed; bottom: 16px; left: 50%; transform: translateX(-50%); color: #666; font-family: -apple-system, system-ui, sans-serif; font-size: 13px; }
2248
+ </style>
2249
+ </head>
2250
+ <body>
2251
+ <div id="player"></div>
2252
+ <div id="status">Waiting for mobile device...</div>
2253
+ <script src="https://cdn.jsdelivr.net/npm/rrweb@2.0.0-alpha.13/dist/rrweb.umd.cjs.js"></script>
2254
+ <script>
2255
+ (function() {
2256
+ var proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
2257
+ var ws = new WebSocket(proto + '//' + location.host + '/__mindstudio_dev__/ws');
2258
+ var replayer = null;
2259
+ var status = document.getElementById('status');
2260
+
2261
+ ws.onopen = function() {
2262
+ ws.send(JSON.stringify({
2263
+ type: 'hello',
2264
+ mode: 'mirror',
2265
+ url: location.href,
2266
+ viewport: { w: window.innerWidth, h: window.innerHeight }
2267
+ }));
2268
+ };
2269
+
2270
+ ws.onmessage = function(e) {
2271
+ var msg;
2272
+ try { msg = JSON.parse(e.data); } catch(e) { return; }
2273
+
2274
+ if (msg.type !== 'mirror' || !Array.isArray(msg.events)) return;
2275
+
2276
+ for (var i = 0; i < msg.events.length; i++) {
2277
+ var event = msg.events[i];
2278
+ if (!replayer) {
2279
+ replayer = new rrweb.Replayer([], {
2280
+ root: document.getElementById('player'),
2281
+ liveMode: true,
2282
+ insertStyleRules: [
2283
+ '.replayer-wrapper { position: relative !important; }',
2284
+ ],
2285
+ });
2286
+ replayer.startLive(Date.now() - 500);
2287
+ status.textContent = 'Connected';
2288
+ setTimeout(function() { status.style.opacity = '0'; }, 2000);
2289
+ }
2290
+ replayer.addEvent(event);
2291
+ }
2292
+ };
2293
+
2294
+ ws.onclose = function() {
2295
+ status.style.opacity = '1';
2296
+ status.textContent = 'Disconnected \u2014 reconnecting...';
2297
+ setTimeout(function() { location.reload(); }, 2000);
2298
+ };
2299
+ })();
2300
+ </script>
2301
+ </body>
2302
+ </html>`;
2303
+ res.writeHead(200, {
2304
+ "content-type": "text/html; charset=utf-8",
2305
+ "cache-control": "no-store"
2306
+ });
2307
+ res.end(html);
2308
+ }
2043
2309
  /**
2044
2310
  * Proxy a cross-origin font stylesheet or font file through our server,
2045
2311
  * adding CORS headers so the browser agent can read the @font-face rules.
@@ -2143,13 +2409,13 @@ ${agentScript}`;
2143
2409
  };
2144
2410
 
2145
2411
  // src/dev/config/app-config.ts
2146
- import { readFileSync, existsSync as existsSync2 } from "fs";
2147
- import { join as join5, dirname as dirname2 } from "path";
2412
+ import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
2413
+ import { join as join6, dirname as dirname3 } from "path";
2148
2414
  function detectAppConfig(cwd = process.cwd()) {
2149
- const appJsonPath = join5(cwd, "mindstudio.json");
2415
+ const appJsonPath = join6(cwd, "mindstudio.json");
2150
2416
  if (!existsSync2(appJsonPath)) return null;
2151
2417
  try {
2152
- const raw = readFileSync(appJsonPath, "utf-8");
2418
+ const raw = readFileSync2(appJsonPath, "utf-8");
2153
2419
  const parsed = JSON.parse(raw);
2154
2420
  if (!parsed.name || !Array.isArray(parsed.methods)) {
2155
2421
  return null;
@@ -2185,12 +2451,12 @@ function getWebInterfaceConfig(appConfig, cwd = process.cwd()) {
2185
2451
  if (!webInterface) {
2186
2452
  return null;
2187
2453
  }
2188
- const configPath = join5(cwd, webInterface.path);
2454
+ const configPath = join6(cwd, webInterface.path);
2189
2455
  if (!existsSync2(configPath)) {
2190
2456
  return null;
2191
2457
  }
2192
2458
  try {
2193
- const raw = readFileSync(configPath, "utf-8");
2459
+ const raw = readFileSync2(configPath, "utf-8");
2194
2460
  const parsed = JSON.parse(raw);
2195
2461
  const web = parsed.web;
2196
2462
  if (!web || typeof web !== "object") {
@@ -2211,18 +2477,18 @@ function getWebProjectDir(appConfig, cwd = process.cwd()) {
2211
2477
  if (!webInterface) {
2212
2478
  return null;
2213
2479
  }
2214
- return dirname2(join5(cwd, webInterface.path));
2480
+ return dirname3(join6(cwd, webInterface.path));
2215
2481
  }
2216
2482
  function readTableSources(appConfig, cwd = process.cwd()) {
2217
2483
  const results = [];
2218
2484
  for (const table of appConfig.tables) {
2219
- const filePath = join5(cwd, table.path);
2485
+ const filePath = join6(cwd, table.path);
2220
2486
  if (!existsSync2(filePath)) {
2221
2487
  log.warn("config", "Table source file not found", { table: table.export, path: table.path });
2222
2488
  continue;
2223
2489
  }
2224
2490
  try {
2225
- const source = readFileSync(filePath, "utf-8");
2491
+ const source = readFileSync2(filePath, "utf-8");
2226
2492
  const name = table.export;
2227
2493
  results.push({ name, source });
2228
2494
  } catch (err) {
@@ -2240,9 +2506,9 @@ function findDirsNeedingInstall(appConfig, cwd = process.cwd()) {
2240
2506
  const firstMethodPath = appConfig.methods[0].path;
2241
2507
  const parts = firstMethodPath.split("/");
2242
2508
  for (let i = parts.length - 1; i >= 1; i--) {
2243
- const candidate = join5(cwd, ...parts.slice(0, i));
2244
- if (existsSync2(join5(candidate, "package.json"))) {
2245
- if (!existsSync2(join5(candidate, "node_modules"))) {
2509
+ const candidate = join6(cwd, ...parts.slice(0, i));
2510
+ if (existsSync2(join6(candidate, "package.json"))) {
2511
+ if (!existsSync2(join6(candidate, "node_modules"))) {
2246
2512
  dirs.push(candidate);
2247
2513
  }
2248
2514
  break;
@@ -2250,8 +2516,8 @@ function findDirsNeedingInstall(appConfig, cwd = process.cwd()) {
2250
2516
  }
2251
2517
  }
2252
2518
  const webProjectDir = getWebProjectDir(appConfig, cwd);
2253
- if (webProjectDir && existsSync2(join5(webProjectDir, "package.json"))) {
2254
- if (!existsSync2(join5(webProjectDir, "node_modules"))) {
2519
+ if (webProjectDir && existsSync2(join6(webProjectDir, "package.json"))) {
2520
+ if (!existsSync2(join6(webProjectDir, "node_modules"))) {
2255
2521
  dirs.push(webProjectDir);
2256
2522
  }
2257
2523
  }
@@ -2280,11 +2546,11 @@ function detectGitBranch() {
2280
2546
 
2281
2547
  // src/dev/config/table-watcher.ts
2282
2548
  import { watch } from "chokidar";
2283
- import { join as join6, dirname as dirname3, basename as basename2 } from "path";
2549
+ import { join as join7, dirname as dirname4, basename as basename2 } from "path";
2284
2550
  function watchTableFiles(tables, cwd, onChanged) {
2285
2551
  if (tables.length === 0) return () => {
2286
2552
  };
2287
- const filePaths = tables.map((t) => join6(cwd, t.path));
2553
+ const filePaths = tables.map((t) => join7(cwd, t.path));
2288
2554
  let syncTimer;
2289
2555
  const watcher = watch(filePaths, {
2290
2556
  ignoreInitial: true,
@@ -2297,8 +2563,8 @@ function watchTableFiles(tables, cwd, onChanged) {
2297
2563
  });
2298
2564
  const dirToFiles = /* @__PURE__ */ new Map();
2299
2565
  for (const table of tables) {
2300
- const absPath = join6(cwd, table.path);
2301
- const dir = dirname3(absPath);
2566
+ const absPath = join7(cwd, table.path);
2567
+ const dir = dirname4(absPath);
2302
2568
  const file = basename2(absPath);
2303
2569
  if (!dirToFiles.has(dir)) dirToFiles.set(dir, /* @__PURE__ */ new Set());
2304
2570
  dirToFiles.get(dir).add(file);
@@ -2315,9 +2581,9 @@ function watchTableFiles(tables, cwd, onChanged) {
2315
2581
 
2316
2582
  // src/dev/config/config-watcher.ts
2317
2583
  import { watch as watch2 } from "chokidar";
2318
- import { join as join7 } from "path";
2584
+ import { join as join8 } from "path";
2319
2585
  function watchConfigFile(cwd, onChanged) {
2320
- const configPath = join7(cwd, "mindstudio.json");
2586
+ const configPath = join8(cwd, "mindstudio.json");
2321
2587
  let debounceTimer;
2322
2588
  const watcher = watch2(configPath, {
2323
2589
  ignoreInitial: true,
@@ -2384,4 +2650,4 @@ export {
2384
2650
  watchTableFiles,
2385
2651
  watchConfigFile
2386
2652
  };
2387
- //# sourceMappingURL=chunk-JRLMRABX.js.map
2653
+ //# sourceMappingURL=chunk-XPXEBWOW.js.map