@mindstudio-ai/local-model-tunnel 0.5.48 → 0.5.50
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.
- package/dist/{chunk-XGPRYHAD.js → chunk-FEZRTRFM.js} +142 -78
- package/dist/chunk-FEZRTRFM.js.map +1 -0
- package/dist/{chunk-QQMZXAO7.js → chunk-MSDRYKC7.js} +71 -42
- package/dist/chunk-MSDRYKC7.js.map +1 -0
- package/dist/{chunk-QWAWB3RX.js → chunk-W37GNVL6.js} +2 -2
- package/dist/cli.js +1 -1
- package/dist/headless.js +2 -2
- package/dist/index.js +3 -3
- package/dist/{tui-5XTJVE4K.js → tui-RAX5GOMA.js} +6 -6
- package/package.json +14 -16
- package/dist/chunk-QQMZXAO7.js.map +0 -1
- package/dist/chunk-XGPRYHAD.js.map +0 -1
- /package/dist/{chunk-QWAWB3RX.js.map → chunk-W37GNVL6.js.map} +0 -0
- /package/dist/{tui-5XTJVE4K.js.map → tui-RAX5GOMA.js.map} +0 -0
|
@@ -274,6 +274,7 @@ var ApiError = class extends Error {
|
|
|
274
274
|
this.statusCode = statusCode;
|
|
275
275
|
this.name = "ApiError";
|
|
276
276
|
}
|
|
277
|
+
statusCode;
|
|
277
278
|
};
|
|
278
279
|
var DevPollError = class extends Error {
|
|
279
280
|
constructor(message, statusCode) {
|
|
@@ -281,6 +282,7 @@ var DevPollError = class extends Error {
|
|
|
281
282
|
this.statusCode = statusCode;
|
|
282
283
|
this.name = "DevPollError";
|
|
283
284
|
}
|
|
285
|
+
statusCode;
|
|
284
286
|
};
|
|
285
287
|
|
|
286
288
|
// src/dev/logging/ndjson-log.ts
|
|
@@ -293,6 +295,10 @@ var NdjsonLog = class {
|
|
|
293
295
|
this.keepLines = keepLines;
|
|
294
296
|
this.maxBytes = maxBytes;
|
|
295
297
|
}
|
|
298
|
+
filename;
|
|
299
|
+
maxLines;
|
|
300
|
+
keepLines;
|
|
301
|
+
maxBytes;
|
|
296
302
|
fd = null;
|
|
297
303
|
logPath = null;
|
|
298
304
|
lineCount = 0;
|
|
@@ -534,6 +540,7 @@ import { build } from "esbuild";
|
|
|
534
540
|
var Transpiler = class {
|
|
535
541
|
projectRoot;
|
|
536
542
|
outputFiles = /* @__PURE__ */ new Set();
|
|
543
|
+
outDir = null;
|
|
537
544
|
constructor(projectRoot) {
|
|
538
545
|
this.projectRoot = projectRoot;
|
|
539
546
|
this.cleanupOrphans();
|
|
@@ -564,6 +571,7 @@ var Transpiler = class {
|
|
|
564
571
|
}
|
|
565
572
|
const outDir = join3(nodeModulesDir, ".cache", "mindstudio-dev");
|
|
566
573
|
await mkdir(outDir, { recursive: true });
|
|
574
|
+
this.outDir = outDir;
|
|
567
575
|
const outfile = join3(outDir, `${name}.__ms_dev__.mjs`);
|
|
568
576
|
await build({
|
|
569
577
|
entryPoints: [absolutePath],
|
|
@@ -580,6 +588,15 @@ var Transpiler = class {
|
|
|
580
588
|
log.info("transpiler", "Method transpiled", { duration: Date.now() - start, methodPath, outfile });
|
|
581
589
|
return outfile;
|
|
582
590
|
}
|
|
591
|
+
/**
|
|
592
|
+
* Get the output directory where transpiled files and the worker script
|
|
593
|
+
* are written. Returns null if no method has been transpiled yet.
|
|
594
|
+
* This is inside node_modules/.cache/mindstudio-dev/ — Node's module
|
|
595
|
+
* resolution can find @mindstudio-ai/agent from here.
|
|
596
|
+
*/
|
|
597
|
+
getOutputDir() {
|
|
598
|
+
return this.outDir;
|
|
599
|
+
}
|
|
583
600
|
/**
|
|
584
601
|
* Clean up all transpiled output files.
|
|
585
602
|
*/
|
|
@@ -620,9 +637,9 @@ function findNearestNodeModules(startDir) {
|
|
|
620
637
|
|
|
621
638
|
// src/dev/execution/executor.ts
|
|
622
639
|
import { fork } from "child_process";
|
|
623
|
-
import { writeFile, unlink as unlink2 } from "fs/promises";
|
|
640
|
+
import { writeFile, unlink as unlink2, mkdir as mkdir2 } from "fs/promises";
|
|
624
641
|
import { readFileSync } from "fs";
|
|
625
|
-
import { join as join4 } from "path";
|
|
642
|
+
import { join as join4, dirname as dirname2 } from "path";
|
|
626
643
|
import { tmpdir } from "os";
|
|
627
644
|
import { randomBytes } from "crypto";
|
|
628
645
|
var EXECUTION_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
@@ -701,6 +718,34 @@ console.error = (...args) => {
|
|
|
701
718
|
// Track secret keys so we can clean up between requests
|
|
702
719
|
let _activeSecretKeys = [];
|
|
703
720
|
|
|
721
|
+
// ---------------------------------------------------------------------------
|
|
722
|
+
// Single flush loop for all active requests
|
|
723
|
+
// ---------------------------------------------------------------------------
|
|
724
|
+
// One interval sweeps all tracked requests instead of one interval per
|
|
725
|
+
// request. This stays efficient even with thousands of concurrent requests.
|
|
726
|
+
|
|
727
|
+
const BACKGROUND_TIMEOUT = 30 * 60 * 1000; // 30 minutes after method returns
|
|
728
|
+
|
|
729
|
+
const activeRequests = new Map();
|
|
730
|
+
|
|
731
|
+
setInterval(() => {
|
|
732
|
+
const now = Date.now();
|
|
733
|
+
for (const [id, req] of activeRequests) {
|
|
734
|
+
if (req.stdout.length > req.flushed) {
|
|
735
|
+
const lines = req.stdout.slice(req.flushed);
|
|
736
|
+
req.flushed = req.stdout.length;
|
|
737
|
+
try {
|
|
738
|
+
process.send({ type: req.done ? 'background-stdout' : 'stdout', id, lines });
|
|
739
|
+
} catch {}
|
|
740
|
+
} else if (req.done && now - req.doneAt > BACKGROUND_TIMEOUT) {
|
|
741
|
+
activeRequests.delete(id);
|
|
742
|
+
try { process.send({ type: 'stdout-end', id }); } catch {}
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}, 1000);
|
|
746
|
+
|
|
747
|
+
// ---------------------------------------------------------------------------
|
|
748
|
+
|
|
704
749
|
process.on('message', async (msg) => {
|
|
705
750
|
const { id, transpiledPath, methodExport, input, auth, databases, authorizationToken, apiBaseUrl, streamId, secrets } = msg;
|
|
706
751
|
|
|
@@ -717,36 +762,15 @@ process.on('message', async (msg) => {
|
|
|
717
762
|
streamId: streamId ?? undefined,
|
|
718
763
|
};
|
|
719
764
|
|
|
720
|
-
const
|
|
721
|
-
|
|
722
|
-
let done = false;
|
|
723
|
-
|
|
724
|
-
// Flush new stdout lines every 1s while the method is running.
|
|
725
|
-
// After the method returns, switches to background-stdout type.
|
|
726
|
-
const flushInterval = setInterval(() => {
|
|
727
|
-
if (stdout.length > flushed) {
|
|
728
|
-
const lines = stdout.slice(flushed);
|
|
729
|
-
flushed = stdout.length;
|
|
730
|
-
try {
|
|
731
|
-
process.send({ type: done ? 'background-stdout' : 'stdout', id, lines });
|
|
732
|
-
} catch {}
|
|
733
|
-
idleTicks = 0;
|
|
734
|
-
} else if (done) {
|
|
735
|
-
idleTicks++;
|
|
736
|
-
if (idleTicks >= 2) {
|
|
737
|
-
clearInterval(flushInterval);
|
|
738
|
-
try { process.send({ type: 'stdout-end', id }); } catch {}
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
}, 1000);
|
|
742
|
-
let idleTicks = 0;
|
|
765
|
+
const req = { stdout: [], flushed: 0, done: false, doneAt: 0 };
|
|
766
|
+
activeRequests.set(id, req);
|
|
743
767
|
|
|
744
768
|
process.send({ type: 'start', id });
|
|
745
769
|
|
|
746
770
|
const startTime = Date.now();
|
|
747
771
|
|
|
748
772
|
try {
|
|
749
|
-
const returnValue = await consoleAls.run(stdout, () =>
|
|
773
|
+
const returnValue = await consoleAls.run(req.stdout, () =>
|
|
750
774
|
runWithContext(ctx, async () => {
|
|
751
775
|
const mod = await import(transpiledPath + '?t=' + Date.now());
|
|
752
776
|
const fn = mod[methodExport];
|
|
@@ -759,22 +783,24 @@ process.on('message', async (msg) => {
|
|
|
759
783
|
const stats = { memoryUsedBytes: process.memoryUsage().heapUsed, executionTimeMs: Date.now() - startTime };
|
|
760
784
|
|
|
761
785
|
// Final flush of any remaining lines before sending result
|
|
762
|
-
if (stdout.length > flushed) {
|
|
763
|
-
try { process.send({ type: 'stdout', id, lines: stdout.slice(flushed) }); } catch {}
|
|
764
|
-
flushed = stdout.length;
|
|
786
|
+
if (req.stdout.length > req.flushed) {
|
|
787
|
+
try { process.send({ type: 'stdout', id, lines: req.stdout.slice(req.flushed) }); } catch {}
|
|
788
|
+
req.flushed = req.stdout.length;
|
|
765
789
|
}
|
|
766
790
|
|
|
767
|
-
done = true;
|
|
791
|
+
req.done = true;
|
|
792
|
+
req.doneAt = Date.now();
|
|
768
793
|
process.send({ id, success: true, output: returnValue, stats });
|
|
769
794
|
} catch (err) {
|
|
770
795
|
const stats = { memoryUsedBytes: process.memoryUsage().heapUsed, executionTimeMs: Date.now() - startTime };
|
|
771
796
|
|
|
772
|
-
if (stdout.length > flushed) {
|
|
773
|
-
try { process.send({ type: 'stdout', id, lines: stdout.slice(flushed) }); } catch {}
|
|
774
|
-
flushed = stdout.length;
|
|
797
|
+
if (req.stdout.length > req.flushed) {
|
|
798
|
+
try { process.send({ type: 'stdout', id, lines: req.stdout.slice(req.flushed) }); } catch {}
|
|
799
|
+
req.flushed = req.stdout.length;
|
|
775
800
|
}
|
|
776
801
|
|
|
777
|
-
done = true;
|
|
802
|
+
req.done = true;
|
|
803
|
+
req.doneAt = Date.now();
|
|
778
804
|
process.send({ id, success: false, error: serializeError(err), stats });
|
|
779
805
|
}
|
|
780
806
|
});
|
|
@@ -845,18 +871,24 @@ process.on('message', async (msg) => {
|
|
|
845
871
|
process.send({ type: 'ready' });
|
|
846
872
|
`;
|
|
847
873
|
}
|
|
848
|
-
function detectAlsSupport(
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
const
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
874
|
+
function detectAlsSupport(scriptDir) {
|
|
875
|
+
let dir = scriptDir;
|
|
876
|
+
while (true) {
|
|
877
|
+
const candidate = join4(dir, "node_modules", "@mindstudio-ai", "agent", "package.json");
|
|
878
|
+
try {
|
|
879
|
+
const pkg = JSON.parse(readFileSync(candidate, "utf-8"));
|
|
880
|
+
const parts = (pkg.version || "").split(".").map(Number);
|
|
881
|
+
const [major = 0, minor = 0, patch = 0] = parts;
|
|
882
|
+
return major > 0 || minor > 1 || minor === 1 && patch >= 46;
|
|
883
|
+
} catch {
|
|
884
|
+
}
|
|
885
|
+
const parent = join4(dir, "..");
|
|
886
|
+
if (parent === dir) break;
|
|
887
|
+
dir = parent;
|
|
857
888
|
}
|
|
889
|
+
return false;
|
|
858
890
|
}
|
|
859
|
-
async function ensureWorker(projectRoot) {
|
|
891
|
+
async function ensureWorker(projectRoot, scriptDir) {
|
|
860
892
|
if (worker?.connected && workerProjectRoot === projectRoot) {
|
|
861
893
|
return worker;
|
|
862
894
|
}
|
|
@@ -874,10 +906,14 @@ async function ensureWorker(projectRoot) {
|
|
|
874
906
|
});
|
|
875
907
|
workerScriptPath = null;
|
|
876
908
|
}
|
|
877
|
-
workerSupportsAls = detectAlsSupport(
|
|
878
|
-
log.info("executor", "SDK context support", { als: workerSupportsAls });
|
|
909
|
+
workerSupportsAls = scriptDir ? detectAlsSupport(scriptDir) : false;
|
|
910
|
+
log.info("executor", "SDK context support", { als: workerSupportsAls, scriptDir: scriptDir ?? null });
|
|
911
|
+
const workerDir = workerSupportsAls && scriptDir ? scriptDir : tmpdir();
|
|
912
|
+
if (workerDir !== tmpdir()) {
|
|
913
|
+
await mkdir2(workerDir, { recursive: true });
|
|
914
|
+
}
|
|
879
915
|
const scriptPath = join4(
|
|
880
|
-
|
|
916
|
+
workerDir,
|
|
881
917
|
`ms-dev-worker-${randomBytes(4).toString("hex")}.mjs`
|
|
882
918
|
);
|
|
883
919
|
const script = workerSupportsAls ? buildAlsWorkerScript() : buildLegacyWorkerScript();
|
|
@@ -955,8 +991,8 @@ function executeMethod(opts) {
|
|
|
955
991
|
return enqueue(() => executeMethodInWorker(opts));
|
|
956
992
|
}
|
|
957
993
|
async function executeMethodInWorker(opts) {
|
|
958
|
-
const w = await ensureWorker(opts.projectRoot);
|
|
959
|
-
const id =
|
|
994
|
+
const w = await ensureWorker(opts.projectRoot, dirname2(opts.transpiledPath));
|
|
995
|
+
const id = opts.requestId;
|
|
960
996
|
log.debug("executor", "Sending method to execution process", { id, methodExport: opts.methodExport });
|
|
961
997
|
return new Promise((resolve3) => {
|
|
962
998
|
const timer = setTimeout(() => {
|
|
@@ -1195,7 +1231,7 @@ function formatErrorForDisplay(error) {
|
|
|
1195
1231
|
|
|
1196
1232
|
// src/dev/interfaces/agent-config.ts
|
|
1197
1233
|
import { readFileSync as readFileSync4 } from "fs";
|
|
1198
|
-
import { join as join6, dirname as
|
|
1234
|
+
import { join as join6, dirname as dirname4 } from "path";
|
|
1199
1235
|
|
|
1200
1236
|
// src/dev/interfaces/schema/extract.ts
|
|
1201
1237
|
import ts3 from "typescript";
|
|
@@ -1204,7 +1240,7 @@ import { readFileSync as readFileSync3 } from "fs";
|
|
|
1204
1240
|
// src/dev/interfaces/schema/type-map.ts
|
|
1205
1241
|
import ts from "typescript";
|
|
1206
1242
|
import { readFileSync as readFileSync2 } from "fs";
|
|
1207
|
-
import { dirname as
|
|
1243
|
+
import { dirname as dirname3 } from "path";
|
|
1208
1244
|
|
|
1209
1245
|
// src/dev/interfaces/schema/resolve-import.ts
|
|
1210
1246
|
import { existsSync as existsSync2 } from "fs";
|
|
@@ -1241,7 +1277,7 @@ function collectTypeMap(filePath) {
|
|
|
1241
1277
|
function collectFromFile(sourceFile, filePath, typeMap, visited) {
|
|
1242
1278
|
if (visited.has(filePath)) return;
|
|
1243
1279
|
visited.add(filePath);
|
|
1244
|
-
const dir =
|
|
1280
|
+
const dir = dirname3(filePath);
|
|
1245
1281
|
for (const stmt of sourceFile.statements) {
|
|
1246
1282
|
if (ts.isTypeAliasDeclaration(stmt)) {
|
|
1247
1283
|
typeMap.set(stmt.name.text, stmt.type);
|
|
@@ -1410,7 +1446,7 @@ function readAgentConfig(projectRoot, appConfig) {
|
|
|
1410
1446
|
}
|
|
1411
1447
|
const parsed = JSON.parse(raw);
|
|
1412
1448
|
const config2 = parsed.agent ?? parsed;
|
|
1413
|
-
const agentDir =
|
|
1449
|
+
const agentDir = dirname4(configPath);
|
|
1414
1450
|
const systemPromptPath = join6(agentDir, config2.systemPrompt);
|
|
1415
1451
|
let systemPrompt;
|
|
1416
1452
|
try {
|
|
@@ -1502,6 +1538,9 @@ var DevRunner = class {
|
|
|
1502
1538
|
this.projectRoot = projectRoot;
|
|
1503
1539
|
this.startOpts = startOpts;
|
|
1504
1540
|
}
|
|
1541
|
+
appId;
|
|
1542
|
+
projectRoot;
|
|
1543
|
+
startOpts;
|
|
1505
1544
|
isRunning = false;
|
|
1506
1545
|
session = null;
|
|
1507
1546
|
transpiler = null;
|
|
@@ -1612,6 +1651,7 @@ var DevRunner = class {
|
|
|
1612
1651
|
roleAssignments: roles.map((roleName) => ({ userId, roleName }))
|
|
1613
1652
|
} : { ...this.session.auth, userId };
|
|
1614
1653
|
const result = await executeMethod({
|
|
1654
|
+
requestId,
|
|
1615
1655
|
transpiledPath,
|
|
1616
1656
|
methodExport: opts.methodExport,
|
|
1617
1657
|
input: opts.input,
|
|
@@ -1677,9 +1717,10 @@ var DevRunner = class {
|
|
|
1677
1717
|
if (!this.session || !this.transpiler) {
|
|
1678
1718
|
return { success: false, databases: [], error: "Session not started" };
|
|
1679
1719
|
}
|
|
1720
|
+
const requestId = randomBytes2(8).toString("hex");
|
|
1680
1721
|
const startTime = Date.now();
|
|
1681
1722
|
const scenarioName = scenario.name ?? scenario.export;
|
|
1682
|
-
log.info("runner", "Scenario starting", { id: scenario.id, name: scenarioName });
|
|
1723
|
+
log.info("runner", "Scenario starting", { requestId, id: scenario.id, name: scenarioName });
|
|
1683
1724
|
try {
|
|
1684
1725
|
if (!opts?.skipTruncate) {
|
|
1685
1726
|
log.debug("runner", "Resetting database for scenario");
|
|
@@ -1691,6 +1732,7 @@ var DevRunner = class {
|
|
|
1691
1732
|
const authorizationToken = await fetchCallbackToken(this.appId, this.session.sessionId);
|
|
1692
1733
|
log.debug("runner", "Running scenario seed function", { export: scenario.export });
|
|
1693
1734
|
const result = await executeMethod({
|
|
1735
|
+
requestId,
|
|
1694
1736
|
transpiledPath,
|
|
1695
1737
|
methodExport: scenario.export,
|
|
1696
1738
|
input: {},
|
|
@@ -1828,6 +1870,7 @@ var DevRunner = class {
|
|
|
1828
1870
|
roleAssignments: overrideRoles ? overrideRoles.map((roleName) => ({ userId, roleName })) : request.roleAssignments ?? []
|
|
1829
1871
|
};
|
|
1830
1872
|
const result = await executeMethod({
|
|
1873
|
+
requestId: request.requestId,
|
|
1831
1874
|
transpiledPath,
|
|
1832
1875
|
methodExport: method.export,
|
|
1833
1876
|
input: request.input,
|
|
@@ -2160,6 +2203,15 @@ var ClientRegistry = class {
|
|
|
2160
2203
|
}
|
|
2161
2204
|
};
|
|
2162
2205
|
|
|
2206
|
+
// src/dev/stdin-commands/types.ts
|
|
2207
|
+
var CommandError = class extends Error {
|
|
2208
|
+
constructor(message, code) {
|
|
2209
|
+
super(message);
|
|
2210
|
+
this.code = code;
|
|
2211
|
+
}
|
|
2212
|
+
code;
|
|
2213
|
+
};
|
|
2214
|
+
|
|
2163
2215
|
// src/dev/proxy/proxy.ts
|
|
2164
2216
|
var DevProxy = class _DevProxy {
|
|
2165
2217
|
constructor(upstreamPort, clientContext, appId, bindAddress = "127.0.0.1", browserAgentUrl) {
|
|
@@ -2169,6 +2221,11 @@ var DevProxy = class _DevProxy {
|
|
|
2169
2221
|
this.bindAddress = bindAddress;
|
|
2170
2222
|
this.browserAgentUrl = browserAgentUrl;
|
|
2171
2223
|
}
|
|
2224
|
+
upstreamPort;
|
|
2225
|
+
clientContext;
|
|
2226
|
+
appId;
|
|
2227
|
+
bindAddress;
|
|
2228
|
+
browserAgentUrl;
|
|
2172
2229
|
server = null;
|
|
2173
2230
|
proxyPort = null;
|
|
2174
2231
|
wss = null;
|
|
@@ -2202,9 +2259,7 @@ var DevProxy = class _DevProxy {
|
|
|
2202
2259
|
dispatchBrowserCommand(steps, timeoutMs = 12e4) {
|
|
2203
2260
|
if (!this.clients.hasConnected()) {
|
|
2204
2261
|
return Promise.reject(
|
|
2205
|
-
new
|
|
2206
|
-
"No browser connected, please refresh the MindStudio preview"
|
|
2207
|
-
)
|
|
2262
|
+
new CommandError("No browser connected", "NO_BROWSER")
|
|
2208
2263
|
);
|
|
2209
2264
|
}
|
|
2210
2265
|
const id = randomBytes4(4).toString("hex");
|
|
@@ -2229,6 +2284,13 @@ var DevProxy = class _DevProxy {
|
|
|
2229
2284
|
* Try to send the next queued command to an available client.
|
|
2230
2285
|
*/
|
|
2231
2286
|
drainCommandQueue() {
|
|
2287
|
+
if (!this.clients.hasConnected() && this.commandQueue.length > 0) {
|
|
2288
|
+
const orphaned = this.commandQueue.splice(0);
|
|
2289
|
+
for (const cmd of orphaned) {
|
|
2290
|
+
cmd.reject(new CommandError("No browser connected", "NO_BROWSER"));
|
|
2291
|
+
}
|
|
2292
|
+
return;
|
|
2293
|
+
}
|
|
2232
2294
|
while (this.commandQueue.length > 0) {
|
|
2233
2295
|
const target = this.clients.getCommandTarget();
|
|
2234
2296
|
if (!target) break;
|
|
@@ -2250,10 +2312,10 @@ var DevProxy = class _DevProxy {
|
|
|
2250
2312
|
id,
|
|
2251
2313
|
pendingCount: this.pendingResults.size
|
|
2252
2314
|
});
|
|
2253
|
-
reject(new
|
|
2315
|
+
reject(new CommandError("Browser command timed out", "BROWSER_TIMEOUT"));
|
|
2254
2316
|
this.drainCommandQueue();
|
|
2255
2317
|
}, timeoutMs);
|
|
2256
|
-
this.pendingResults.set(id, { resolve: resolve3, timeout, clientId: target.id });
|
|
2318
|
+
this.pendingResults.set(id, { resolve: resolve3, reject, timeout, clientId: target.id });
|
|
2257
2319
|
target.activeCommandId = id;
|
|
2258
2320
|
try {
|
|
2259
2321
|
target.ws.send(JSON.stringify({ type: "command", id, steps }));
|
|
@@ -2265,7 +2327,7 @@ var DevProxy = class _DevProxy {
|
|
|
2265
2327
|
id,
|
|
2266
2328
|
clientId: target.id
|
|
2267
2329
|
});
|
|
2268
|
-
reject(new
|
|
2330
|
+
reject(new CommandError("Failed to send command to browser", "BROWSER_SEND_FAILED"));
|
|
2269
2331
|
}
|
|
2270
2332
|
}
|
|
2271
2333
|
}
|
|
@@ -2358,13 +2420,13 @@ var DevProxy = class _DevProxy {
|
|
|
2358
2420
|
this.server = null;
|
|
2359
2421
|
this.proxyPort = null;
|
|
2360
2422
|
}
|
|
2361
|
-
for (const [
|
|
2423
|
+
for (const [, pending2] of this.pendingResults) {
|
|
2362
2424
|
clearTimeout(pending2.timeout);
|
|
2363
|
-
pending2.
|
|
2425
|
+
pending2.reject(new CommandError("Proxy stopped", "INFRASTRUCTURE"));
|
|
2364
2426
|
}
|
|
2365
2427
|
this.pendingResults.clear();
|
|
2366
2428
|
for (const queued of this.commandQueue) {
|
|
2367
|
-
queued.reject(new
|
|
2429
|
+
queued.reject(new CommandError("Proxy stopped", "INFRASTRUCTURE"));
|
|
2368
2430
|
}
|
|
2369
2431
|
this.commandQueue.length = 0;
|
|
2370
2432
|
}
|
|
@@ -2469,13 +2531,14 @@ var DevProxy = class _DevProxy {
|
|
|
2469
2531
|
if (clientId) {
|
|
2470
2532
|
const client = this.clients.remove(clientId);
|
|
2471
2533
|
if (client?.activeCommandId) {
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
{
|
|
2476
|
-
commandId
|
|
2534
|
+
const commandId = client.activeCommandId;
|
|
2535
|
+
log.debug("proxy", "Browser disconnected with active command", { commandId });
|
|
2536
|
+
setTimeout(() => {
|
|
2537
|
+
if (this.pendingResults.has(commandId) && !this.clients.findByCommandId(commandId)) {
|
|
2538
|
+
this.rejectPendingCommand(commandId, new CommandError("Browser disconnected", "BROWSER_DISCONNECTED"));
|
|
2539
|
+
this.drainCommandQueue();
|
|
2477
2540
|
}
|
|
2478
|
-
);
|
|
2541
|
+
}, 1e4);
|
|
2479
2542
|
}
|
|
2480
2543
|
}
|
|
2481
2544
|
});
|
|
@@ -2509,13 +2572,13 @@ var DevProxy = class _DevProxy {
|
|
|
2509
2572
|
);
|
|
2510
2573
|
}
|
|
2511
2574
|
}
|
|
2512
|
-
rejectPendingCommand(commandId,
|
|
2575
|
+
rejectPendingCommand(commandId, error) {
|
|
2513
2576
|
const pending2 = this.pendingResults.get(commandId);
|
|
2514
2577
|
if (pending2) {
|
|
2515
2578
|
clearTimeout(pending2.timeout);
|
|
2516
2579
|
this.pendingResults.delete(commandId);
|
|
2517
|
-
pending2.
|
|
2518
|
-
log.warn("proxy", "Pending command rejected", { id: commandId, reason });
|
|
2580
|
+
pending2.reject(error);
|
|
2581
|
+
log.warn("proxy", "Pending command rejected", { id: commandId, code: error.code, reason: error.message });
|
|
2519
2582
|
this.drainCommandQueue();
|
|
2520
2583
|
}
|
|
2521
2584
|
}
|
|
@@ -2529,7 +2592,7 @@ var DevProxy = class _DevProxy {
|
|
|
2529
2592
|
if (activeCommandId) {
|
|
2530
2593
|
this.rejectPendingCommand(
|
|
2531
2594
|
activeCommandId,
|
|
2532
|
-
"Browser client timed out"
|
|
2595
|
+
new CommandError("Browser client timed out", "BROWSER_DISCONNECTED")
|
|
2533
2596
|
);
|
|
2534
2597
|
}
|
|
2535
2598
|
}
|
|
@@ -3087,7 +3150,7 @@ ${agentScript}`;
|
|
|
3087
3150
|
|
|
3088
3151
|
// src/dev/config/app-config.ts
|
|
3089
3152
|
import { readFileSync as readFileSync6, existsSync as existsSync3 } from "fs";
|
|
3090
|
-
import { join as join8, dirname as
|
|
3153
|
+
import { join as join8, dirname as dirname5 } from "path";
|
|
3091
3154
|
function detectAppConfig(cwd = process.cwd()) {
|
|
3092
3155
|
const appJsonPath = join8(cwd, "mindstudio.json");
|
|
3093
3156
|
if (!existsSync3(appJsonPath)) return null;
|
|
@@ -3155,7 +3218,7 @@ function getWebProjectDir(appConfig, cwd = process.cwd()) {
|
|
|
3155
3218
|
if (!webInterface) {
|
|
3156
3219
|
return null;
|
|
3157
3220
|
}
|
|
3158
|
-
return
|
|
3221
|
+
return dirname5(join8(cwd, webInterface.path));
|
|
3159
3222
|
}
|
|
3160
3223
|
function readTableSources(appConfig, cwd = process.cwd()) {
|
|
3161
3224
|
const results = [];
|
|
@@ -3224,7 +3287,7 @@ function detectGitBranch() {
|
|
|
3224
3287
|
|
|
3225
3288
|
// src/dev/config/table-watcher.ts
|
|
3226
3289
|
import { watch } from "chokidar";
|
|
3227
|
-
import { join as join9, dirname as
|
|
3290
|
+
import { join as join9, dirname as dirname6, basename as basename2 } from "path";
|
|
3228
3291
|
function watchTableFiles(tables, cwd, onChanged) {
|
|
3229
3292
|
if (tables.length === 0) return () => {
|
|
3230
3293
|
};
|
|
@@ -3242,7 +3305,7 @@ function watchTableFiles(tables, cwd, onChanged) {
|
|
|
3242
3305
|
const dirToFiles = /* @__PURE__ */ new Map();
|
|
3243
3306
|
for (const table of tables) {
|
|
3244
3307
|
const absPath = join9(cwd, table.path);
|
|
3245
|
-
const dir =
|
|
3308
|
+
const dir = dirname6(absPath);
|
|
3246
3309
|
const file = basename2(absPath);
|
|
3247
3310
|
if (!dirToFiles.has(dir)) dirToFiles.set(dir, /* @__PURE__ */ new Set());
|
|
3248
3311
|
dirToFiles.get(dir).add(file);
|
|
@@ -3319,6 +3382,7 @@ export {
|
|
|
3319
3382
|
DevRunner,
|
|
3320
3383
|
initBrowserLog,
|
|
3321
3384
|
closeBrowserLog,
|
|
3385
|
+
CommandError,
|
|
3322
3386
|
DevProxy,
|
|
3323
3387
|
detectAppConfig,
|
|
3324
3388
|
getWebInterfaceConfig,
|
|
@@ -3330,4 +3394,4 @@ export {
|
|
|
3330
3394
|
watchTableFiles,
|
|
3331
3395
|
watchConfigFile
|
|
3332
3396
|
};
|
|
3333
|
-
//# sourceMappingURL=chunk-
|
|
3397
|
+
//# sourceMappingURL=chunk-FEZRTRFM.js.map
|