@mindstudio-ai/local-model-tunnel 0.5.44 → 0.5.46
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-XUR5YLIV.js → chunk-UKMKZQKQ.js} +311 -158
- package/dist/chunk-UKMKZQKQ.js.map +1 -0
- package/dist/{chunk-7DD5SY5V.js → chunk-W73NWEHI.js} +2 -2
- package/dist/{chunk-ZGL74JCA.js → chunk-ZATLZQ4W.js} +2 -2
- package/dist/cli.js +1 -1
- package/dist/headless.js +2 -2
- package/dist/index.js +3 -3
- package/dist/{tui-KMZKN5LC.js → tui-A6OF3NH3.js} +6 -6
- package/package.json +3 -3
- package/dist/chunk-XUR5YLIV.js.map +0 -1
- /package/dist/{chunk-7DD5SY5V.js.map → chunk-W73NWEHI.js.map} +0 -0
- /package/dist/{chunk-ZGL74JCA.js.map → chunk-ZATLZQ4W.js.map} +0 -0
- /package/dist/{tui-KMZKN5LC.js.map → tui-A6OF3NH3.js.map} +0 -0
|
@@ -890,11 +890,11 @@ async function ensureWorker(projectRoot) {
|
|
|
890
890
|
stdio: ["ignore", "pipe", "pipe", "ipc"],
|
|
891
891
|
env: { ...process.env }
|
|
892
892
|
});
|
|
893
|
-
await new Promise((
|
|
893
|
+
await new Promise((resolve3, reject) => {
|
|
894
894
|
const onMessage = (msg) => {
|
|
895
895
|
if (msg?.type === "ready") {
|
|
896
896
|
child.off("message", onMessage);
|
|
897
|
-
|
|
897
|
+
resolve3();
|
|
898
898
|
}
|
|
899
899
|
};
|
|
900
900
|
child.on("message", onMessage);
|
|
@@ -958,16 +958,16 @@ async function executeMethodInWorker(opts) {
|
|
|
958
958
|
const w = await ensureWorker(opts.projectRoot);
|
|
959
959
|
const id = randomBytes(8).toString("hex");
|
|
960
960
|
log.debug("executor", "Sending method to execution process", { id, methodExport: opts.methodExport });
|
|
961
|
-
return new Promise((
|
|
961
|
+
return new Promise((resolve3) => {
|
|
962
962
|
const timer = setTimeout(() => {
|
|
963
963
|
pending.delete(id);
|
|
964
964
|
log.warn("executor", "Method execution timed out", { id, methodExport: opts.methodExport });
|
|
965
|
-
|
|
965
|
+
resolve3({
|
|
966
966
|
success: false,
|
|
967
967
|
error: { message: "Method execution timed out after 30m" }
|
|
968
968
|
});
|
|
969
969
|
}, EXECUTION_TIMEOUT_MS);
|
|
970
|
-
pending.set(id, { resolve:
|
|
970
|
+
pending.set(id, { resolve: resolve3, timer });
|
|
971
971
|
if (opts.sessionId) {
|
|
972
972
|
requestMeta.set(id, { sessionId: opts.sessionId, method: opts.methodExport, input: opts.input });
|
|
973
973
|
}
|
|
@@ -1167,8 +1167,6 @@ async function disconnectHeartbeat() {
|
|
|
1167
1167
|
}
|
|
1168
1168
|
|
|
1169
1169
|
// src/dev/execution/runner.ts
|
|
1170
|
-
import { readFileSync as readFileSync3 } from "fs";
|
|
1171
|
-
import { join as join6 } from "path";
|
|
1172
1170
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
1173
1171
|
|
|
1174
1172
|
// src/dev/execution/format-error.ts
|
|
@@ -1195,9 +1193,205 @@ function formatErrorForDisplay(error) {
|
|
|
1195
1193
|
return parts.join("\n");
|
|
1196
1194
|
}
|
|
1197
1195
|
|
|
1198
|
-
// src/dev/
|
|
1196
|
+
// src/dev/interfaces/agent-config.ts
|
|
1197
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
1198
|
+
import { join as join6, dirname as dirname3 } from "path";
|
|
1199
|
+
|
|
1200
|
+
// src/dev/interfaces/schema/extract.ts
|
|
1201
|
+
import ts3 from "typescript";
|
|
1202
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
1203
|
+
|
|
1204
|
+
// src/dev/interfaces/schema/type-map.ts
|
|
1205
|
+
import ts from "typescript";
|
|
1199
1206
|
import { readFileSync as readFileSync2 } from "fs";
|
|
1200
|
-
import {
|
|
1207
|
+
import { dirname as dirname2 } from "path";
|
|
1208
|
+
|
|
1209
|
+
// src/dev/interfaces/schema/resolve-import.ts
|
|
1210
|
+
import { existsSync as existsSync2 } from "fs";
|
|
1211
|
+
import { resolve as resolve2 } from "path";
|
|
1212
|
+
var EXTENSIONS = [".ts", ".tsx", "/index.ts", "/index.tsx"];
|
|
1213
|
+
function resolveImportPath(specifier, fromDir) {
|
|
1214
|
+
if (!specifier.startsWith("./") && !specifier.startsWith("../")) {
|
|
1215
|
+
return null;
|
|
1216
|
+
}
|
|
1217
|
+
const base = resolve2(fromDir, specifier);
|
|
1218
|
+
if (existsSync2(base) && !base.endsWith("/")) return base;
|
|
1219
|
+
for (const ext of EXTENSIONS) {
|
|
1220
|
+
const candidate = base + ext;
|
|
1221
|
+
if (existsSync2(candidate)) return candidate;
|
|
1222
|
+
}
|
|
1223
|
+
return null;
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
// src/dev/interfaces/schema/type-map.ts
|
|
1227
|
+
function collectTypeMap(filePath) {
|
|
1228
|
+
const typeMap = /* @__PURE__ */ new Map();
|
|
1229
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1230
|
+
const source = readFileSync2(filePath, "utf-8");
|
|
1231
|
+
const sourceFile = ts.createSourceFile(
|
|
1232
|
+
filePath,
|
|
1233
|
+
source,
|
|
1234
|
+
ts.ScriptTarget.Latest,
|
|
1235
|
+
true,
|
|
1236
|
+
ts.ScriptKind.TS
|
|
1237
|
+
);
|
|
1238
|
+
collectFromFile(sourceFile, filePath, typeMap, visited);
|
|
1239
|
+
return { typeMap, sourceFile };
|
|
1240
|
+
}
|
|
1241
|
+
function collectFromFile(sourceFile, filePath, typeMap, visited) {
|
|
1242
|
+
if (visited.has(filePath)) return;
|
|
1243
|
+
visited.add(filePath);
|
|
1244
|
+
const dir = dirname2(filePath);
|
|
1245
|
+
for (const stmt of sourceFile.statements) {
|
|
1246
|
+
if (ts.isTypeAliasDeclaration(stmt)) {
|
|
1247
|
+
typeMap.set(stmt.name.text, stmt.type);
|
|
1248
|
+
}
|
|
1249
|
+
if (ts.isInterfaceDeclaration(stmt)) {
|
|
1250
|
+
const typeLiteral = ts.factory.createTypeLiteralNode(
|
|
1251
|
+
stmt.members.filter(ts.isPropertySignature)
|
|
1252
|
+
);
|
|
1253
|
+
typeMap.set(stmt.name.text, typeLiteral);
|
|
1254
|
+
}
|
|
1255
|
+
if (ts.isImportDeclaration(stmt) && stmt.moduleSpecifier && ts.isStringLiteral(stmt.moduleSpecifier)) {
|
|
1256
|
+
const specifier = stmt.moduleSpecifier.text;
|
|
1257
|
+
const resolved = resolveImportPath(specifier, dir);
|
|
1258
|
+
if (!resolved) continue;
|
|
1259
|
+
try {
|
|
1260
|
+
const importSource = readFileSync2(resolved, "utf-8");
|
|
1261
|
+
const importFile = ts.createSourceFile(
|
|
1262
|
+
resolved,
|
|
1263
|
+
importSource,
|
|
1264
|
+
ts.ScriptTarget.Latest,
|
|
1265
|
+
true,
|
|
1266
|
+
ts.ScriptKind.TS
|
|
1267
|
+
);
|
|
1268
|
+
collectFromFile(importFile, resolved, typeMap, visited);
|
|
1269
|
+
} catch {
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
// src/dev/interfaces/schema/convert.ts
|
|
1276
|
+
import ts2 from "typescript";
|
|
1277
|
+
var STRING_FALLBACK = { type: "string" };
|
|
1278
|
+
function convertTypeNode(node, typeMap, sourceFile) {
|
|
1279
|
+
if (ts2.isTypeLiteralNode(node)) {
|
|
1280
|
+
return convertTypeLiteral(node, typeMap, sourceFile);
|
|
1281
|
+
}
|
|
1282
|
+
if (node.kind === ts2.SyntaxKind.StringKeyword) return { type: "string" };
|
|
1283
|
+
if (node.kind === ts2.SyntaxKind.NumberKeyword) return { type: "number" };
|
|
1284
|
+
if (node.kind === ts2.SyntaxKind.BooleanKeyword) return { type: "boolean" };
|
|
1285
|
+
if (node.kind === ts2.SyntaxKind.AnyKeyword) return { type: "object" };
|
|
1286
|
+
if (node.kind === ts2.SyntaxKind.UnknownKeyword) return { type: "object" };
|
|
1287
|
+
if (ts2.isArrayTypeNode(node)) {
|
|
1288
|
+
const items = convertTypeNode(node.elementType, typeMap, sourceFile);
|
|
1289
|
+
return { type: "array", items };
|
|
1290
|
+
}
|
|
1291
|
+
if (ts2.isTypeReferenceNode(node) && ts2.isIdentifier(node.typeName) && node.typeName.text === "Array" && node.typeArguments?.length === 1) {
|
|
1292
|
+
const items = convertTypeNode(node.typeArguments[0], typeMap, sourceFile);
|
|
1293
|
+
return { type: "array", items };
|
|
1294
|
+
}
|
|
1295
|
+
if (ts2.isTypeReferenceNode(node) && ts2.isIdentifier(node.typeName) && node.typeName.text === "Record" && node.typeArguments?.length === 2) {
|
|
1296
|
+
const valueSchema = convertTypeNode(node.typeArguments[1], typeMap, sourceFile);
|
|
1297
|
+
return { type: "object", additionalProperties: valueSchema };
|
|
1298
|
+
}
|
|
1299
|
+
if (ts2.isUnionTypeNode(node)) {
|
|
1300
|
+
const allStringLiterals = node.types.every(
|
|
1301
|
+
(t) => ts2.isLiteralTypeNode(t) && ts2.isStringLiteral(t.literal)
|
|
1302
|
+
);
|
|
1303
|
+
if (allStringLiterals) {
|
|
1304
|
+
const enumValues = node.types.map(
|
|
1305
|
+
(t) => t.literal.text
|
|
1306
|
+
);
|
|
1307
|
+
return { type: "string", enum: enumValues };
|
|
1308
|
+
}
|
|
1309
|
+
return STRING_FALLBACK;
|
|
1310
|
+
}
|
|
1311
|
+
if (ts2.isParenthesizedTypeNode(node)) {
|
|
1312
|
+
return convertTypeNode(node.type, typeMap, sourceFile);
|
|
1313
|
+
}
|
|
1314
|
+
if (ts2.isIntersectionTypeNode(node)) {
|
|
1315
|
+
const merged = { type: "object", properties: {}, required: [] };
|
|
1316
|
+
for (const member of node.types) {
|
|
1317
|
+
const sub = convertTypeNode(member, typeMap, sourceFile);
|
|
1318
|
+
if (sub.properties) {
|
|
1319
|
+
Object.assign(merged.properties, sub.properties);
|
|
1320
|
+
if (sub.required) merged.required.push(...sub.required);
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
if (merged.required.length === 0) delete merged.required;
|
|
1324
|
+
if (Object.keys(merged.properties).length === 0) delete merged.properties;
|
|
1325
|
+
return merged;
|
|
1326
|
+
}
|
|
1327
|
+
if (ts2.isTypeReferenceNode(node) && ts2.isIdentifier(node.typeName)) {
|
|
1328
|
+
const resolved = typeMap.get(node.typeName.text);
|
|
1329
|
+
if (resolved) return convertTypeNode(resolved, typeMap, sourceFile);
|
|
1330
|
+
}
|
|
1331
|
+
return STRING_FALLBACK;
|
|
1332
|
+
}
|
|
1333
|
+
function convertTypeLiteral(node, typeMap, sourceFile) {
|
|
1334
|
+
const properties = {};
|
|
1335
|
+
const required = [];
|
|
1336
|
+
for (const member of node.members) {
|
|
1337
|
+
if (!ts2.isPropertySignature(member) || !member.name) continue;
|
|
1338
|
+
const name = member.name.getText(sourceFile);
|
|
1339
|
+
const optional = !!member.questionToken;
|
|
1340
|
+
if (member.type) {
|
|
1341
|
+
properties[name] = convertTypeNode(member.type, typeMap, sourceFile);
|
|
1342
|
+
if (!optional) required.push(name);
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
const schema = { type: "object", properties };
|
|
1346
|
+
if (required.length > 0) schema.required = required;
|
|
1347
|
+
return schema;
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
// src/dev/interfaces/schema/types.ts
|
|
1351
|
+
var EMPTY_OBJECT_SCHEMA = { type: "object", properties: {} };
|
|
1352
|
+
|
|
1353
|
+
// src/dev/interfaces/schema/extract.ts
|
|
1354
|
+
function extractInputSchema(filePath, exportName) {
|
|
1355
|
+
let source;
|
|
1356
|
+
try {
|
|
1357
|
+
source = readFileSync3(filePath, "utf-8");
|
|
1358
|
+
} catch {
|
|
1359
|
+
return EMPTY_OBJECT_SCHEMA;
|
|
1360
|
+
}
|
|
1361
|
+
const { typeMap, sourceFile } = collectTypeMap(filePath);
|
|
1362
|
+
const fn = findExportedFunction(sourceFile, exportName);
|
|
1363
|
+
if (!fn || fn.parameters.length === 0) return EMPTY_OBJECT_SCHEMA;
|
|
1364
|
+
const param = fn.parameters[0];
|
|
1365
|
+
if (!param.type) return EMPTY_OBJECT_SCHEMA;
|
|
1366
|
+
return convertTypeNode(param.type, typeMap, sourceFile);
|
|
1367
|
+
}
|
|
1368
|
+
function findExportedFunction(sourceFile, name) {
|
|
1369
|
+
for (const stmt of sourceFile.statements) {
|
|
1370
|
+
if (ts3.isFunctionDeclaration(stmt) && stmt.name?.text === name && hasExportModifier(stmt)) {
|
|
1371
|
+
return stmt;
|
|
1372
|
+
}
|
|
1373
|
+
if (ts3.isVariableStatement(stmt) && hasExportModifier(stmt)) {
|
|
1374
|
+
for (const decl of stmt.declarationList.declarations) {
|
|
1375
|
+
if (ts3.isIdentifier(decl.name) && decl.name.text === name && decl.initializer) {
|
|
1376
|
+
if (ts3.isArrowFunction(decl.initializer)) {
|
|
1377
|
+
return decl.initializer;
|
|
1378
|
+
}
|
|
1379
|
+
if (ts3.isFunctionExpression(decl.initializer)) {
|
|
1380
|
+
return decl.initializer;
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
return void 0;
|
|
1387
|
+
}
|
|
1388
|
+
function hasExportModifier(node) {
|
|
1389
|
+
return ts3.canHaveModifiers(node) && (ts3.getModifiers(node) ?? []).some(
|
|
1390
|
+
(m) => m.kind === ts3.SyntaxKind.ExportKeyword
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
// src/dev/interfaces/agent-config.ts
|
|
1201
1395
|
function readAgentConfig(projectRoot, appConfig) {
|
|
1202
1396
|
const agentInterface = appConfig.interfaces.find(
|
|
1203
1397
|
(i) => i.type === "agent" && i.enabled !== false
|
|
@@ -1205,10 +1399,10 @@ function readAgentConfig(projectRoot, appConfig) {
|
|
|
1205
1399
|
if (!agentInterface) {
|
|
1206
1400
|
throw new Error("No agent interface configured in mindstudio.json");
|
|
1207
1401
|
}
|
|
1208
|
-
const configPath =
|
|
1402
|
+
const configPath = join6(projectRoot, agentInterface.path);
|
|
1209
1403
|
let raw;
|
|
1210
1404
|
try {
|
|
1211
|
-
raw =
|
|
1405
|
+
raw = readFileSync4(configPath, "utf-8");
|
|
1212
1406
|
} catch {
|
|
1213
1407
|
throw new Error(
|
|
1214
1408
|
`Agent config not found at ${agentInterface.path} \u2014 run your build command`
|
|
@@ -1216,11 +1410,11 @@ function readAgentConfig(projectRoot, appConfig) {
|
|
|
1216
1410
|
}
|
|
1217
1411
|
const parsed = JSON.parse(raw);
|
|
1218
1412
|
const config2 = parsed.agent ?? parsed;
|
|
1219
|
-
const agentDir =
|
|
1220
|
-
const systemPromptPath =
|
|
1413
|
+
const agentDir = dirname3(configPath);
|
|
1414
|
+
const systemPromptPath = join6(agentDir, config2.systemPrompt);
|
|
1221
1415
|
let systemPrompt;
|
|
1222
1416
|
try {
|
|
1223
|
-
systemPrompt =
|
|
1417
|
+
systemPrompt = readFileSync4(systemPromptPath, "utf-8");
|
|
1224
1418
|
} catch {
|
|
1225
1419
|
throw new Error(
|
|
1226
1420
|
`Agent system prompt not found at ${config2.systemPrompt} \u2014 run your build command`
|
|
@@ -1228,19 +1422,23 @@ function readAgentConfig(projectRoot, appConfig) {
|
|
|
1228
1422
|
}
|
|
1229
1423
|
const tools = (config2.tools ?? []).map(
|
|
1230
1424
|
(tool) => {
|
|
1231
|
-
const descPath =
|
|
1425
|
+
const descPath = join6(agentDir, tool.description);
|
|
1232
1426
|
let description;
|
|
1233
1427
|
try {
|
|
1234
|
-
description =
|
|
1428
|
+
description = readFileSync4(descPath, "utf-8");
|
|
1235
1429
|
} catch {
|
|
1236
1430
|
throw new Error(
|
|
1237
1431
|
`Agent tool description not found at ${tool.description} for method "${tool.method}" \u2014 run your build command`
|
|
1238
1432
|
);
|
|
1239
1433
|
}
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
}
|
|
1434
|
+
let inputSchema;
|
|
1435
|
+
if (tool.inputSchema) {
|
|
1436
|
+
inputSchema = tool.inputSchema;
|
|
1437
|
+
} else {
|
|
1438
|
+
const method = appConfig.methods.find((m) => m.id === tool.method);
|
|
1439
|
+
inputSchema = method ? extractInputSchema(join6(projectRoot, method.path), method.export) : EMPTY_OBJECT_SCHEMA;
|
|
1440
|
+
}
|
|
1441
|
+
return { name: tool.method, description, inputSchema };
|
|
1244
1442
|
}
|
|
1245
1443
|
);
|
|
1246
1444
|
return {
|
|
@@ -1252,6 +1450,51 @@ function readAgentConfig(projectRoot, appConfig) {
|
|
|
1252
1450
|
};
|
|
1253
1451
|
}
|
|
1254
1452
|
|
|
1453
|
+
// src/dev/interfaces/api-config.ts
|
|
1454
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
1455
|
+
import { join as join7 } from "path";
|
|
1456
|
+
function readApiConfig(projectRoot, appConfig) {
|
|
1457
|
+
const apiInterface = appConfig.interfaces.find(
|
|
1458
|
+
(i) => i.type === "api" && i.enabled !== false
|
|
1459
|
+
);
|
|
1460
|
+
if (!apiInterface) {
|
|
1461
|
+
throw new Error("No API interface config found");
|
|
1462
|
+
}
|
|
1463
|
+
const apiJsonPath = join7(projectRoot, apiInterface.path);
|
|
1464
|
+
const raw = readFileSync5(apiJsonPath, "utf-8");
|
|
1465
|
+
const parsed = JSON.parse(raw);
|
|
1466
|
+
if (!parsed.api) {
|
|
1467
|
+
throw new Error("No API interface config found");
|
|
1468
|
+
}
|
|
1469
|
+
return parsed.api;
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
// src/dev/interfaces/read-config.ts
|
|
1473
|
+
function readConfig(projectRoot, appConfig) {
|
|
1474
|
+
let agent = null;
|
|
1475
|
+
try {
|
|
1476
|
+
agent = readAgentConfig(projectRoot, appConfig);
|
|
1477
|
+
} catch (err) {
|
|
1478
|
+
log.debug("config", "Agent config not available", {
|
|
1479
|
+
error: err instanceof Error ? err.message : String(err)
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
let api = null;
|
|
1483
|
+
try {
|
|
1484
|
+
api = readApiConfig(projectRoot, appConfig);
|
|
1485
|
+
} catch (err) {
|
|
1486
|
+
log.debug("config", "API config not available", {
|
|
1487
|
+
error: err instanceof Error ? err.message : String(err)
|
|
1488
|
+
});
|
|
1489
|
+
}
|
|
1490
|
+
return {
|
|
1491
|
+
name: appConfig.name,
|
|
1492
|
+
auth: appConfig.auth ?? null,
|
|
1493
|
+
agent,
|
|
1494
|
+
api
|
|
1495
|
+
};
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1255
1498
|
// src/dev/execution/runner.ts
|
|
1256
1499
|
var DevRunner = class {
|
|
1257
1500
|
constructor(appId, projectRoot, startOpts = {}) {
|
|
@@ -1547,16 +1790,8 @@ var DevRunner = class {
|
|
|
1547
1790
|
}
|
|
1548
1791
|
}
|
|
1549
1792
|
async handleRequest(request) {
|
|
1550
|
-
if (request.type === "get-
|
|
1551
|
-
await this.
|
|
1552
|
-
return;
|
|
1553
|
-
}
|
|
1554
|
-
if (request.type === "get-auth-config") {
|
|
1555
|
-
await this.handleGetAuthConfig(request);
|
|
1556
|
-
return;
|
|
1557
|
-
}
|
|
1558
|
-
if (request.type === "get-api-config") {
|
|
1559
|
-
await this.handleGetApiConfig(request);
|
|
1793
|
+
if (request.type === "get-config") {
|
|
1794
|
+
await this.handleGetConfig(request);
|
|
1560
1795
|
return;
|
|
1561
1796
|
}
|
|
1562
1797
|
const startTime = Date.now();
|
|
@@ -1697,122 +1932,40 @@ var DevRunner = class {
|
|
|
1697
1932
|
});
|
|
1698
1933
|
}
|
|
1699
1934
|
}
|
|
1700
|
-
async
|
|
1701
|
-
|
|
1702
|
-
log.info("runner", "Agent config requested", { requestId: request.requestId, sessionId: this.session.sessionId });
|
|
1703
|
-
try {
|
|
1704
|
-
if (!this.appConfig) {
|
|
1705
|
-
throw new Error("App config not available");
|
|
1706
|
-
}
|
|
1707
|
-
const bundle = readAgentConfig(this.projectRoot, this.appConfig);
|
|
1708
|
-
await submitDevResult(
|
|
1709
|
-
this.appId,
|
|
1710
|
-
this.session.sessionId,
|
|
1711
|
-
request.requestId,
|
|
1712
|
-
{
|
|
1713
|
-
type: "get-agent-config",
|
|
1714
|
-
success: true,
|
|
1715
|
-
output: bundle
|
|
1716
|
-
}
|
|
1717
|
-
);
|
|
1718
|
-
log.info("runner", "Agent config sent", { requestId: request.requestId, duration: Date.now() - startTime });
|
|
1719
|
-
} catch (err) {
|
|
1720
|
-
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1721
|
-
log.error("runner", "Agent config failed", { requestId: request.requestId, error: message });
|
|
1722
|
-
try {
|
|
1723
|
-
await submitDevResult(
|
|
1724
|
-
this.appId,
|
|
1725
|
-
this.session.sessionId,
|
|
1726
|
-
request.requestId,
|
|
1727
|
-
{
|
|
1728
|
-
type: "get-agent-config",
|
|
1729
|
-
success: false,
|
|
1730
|
-
error: { message }
|
|
1731
|
-
}
|
|
1732
|
-
);
|
|
1733
|
-
} catch (submitErr) {
|
|
1734
|
-
log.error("runner", "Failed to report agent config error to platform", { error: submitErr instanceof Error ? submitErr.message : String(submitErr) });
|
|
1735
|
-
}
|
|
1736
|
-
}
|
|
1737
|
-
}
|
|
1738
|
-
async handleGetAuthConfig(request) {
|
|
1739
|
-
log.info("runner", "Auth config requested", { requestId: request.requestId, sessionId: this.session.sessionId });
|
|
1935
|
+
async handleGetConfig(request) {
|
|
1936
|
+
log.info("runner", "Config requested", { requestId: request.requestId, sessionId: this.session.sessionId });
|
|
1740
1937
|
try {
|
|
1741
1938
|
if (!this.appConfig) {
|
|
1742
1939
|
throw new Error("App config not available");
|
|
1743
1940
|
}
|
|
1941
|
+
const config2 = readConfig(this.projectRoot, this.appConfig);
|
|
1744
1942
|
await submitDevResult(
|
|
1745
1943
|
this.appId,
|
|
1746
1944
|
this.session.sessionId,
|
|
1747
1945
|
request.requestId,
|
|
1748
1946
|
{
|
|
1749
|
-
type: "get-
|
|
1750
|
-
success: true,
|
|
1751
|
-
output: { auth: this.appConfig.auth ?? null, name: this.appConfig.name }
|
|
1752
|
-
}
|
|
1753
|
-
);
|
|
1754
|
-
log.info("runner", "Auth config sent", { requestId: request.requestId });
|
|
1755
|
-
} catch (err) {
|
|
1756
|
-
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1757
|
-
log.error("runner", "Auth config failed", { requestId: request.requestId, error: message });
|
|
1758
|
-
try {
|
|
1759
|
-
await submitDevResult(
|
|
1760
|
-
this.appId,
|
|
1761
|
-
this.session.sessionId,
|
|
1762
|
-
request.requestId,
|
|
1763
|
-
{
|
|
1764
|
-
type: "get-auth-config",
|
|
1765
|
-
success: false,
|
|
1766
|
-
error: { message }
|
|
1767
|
-
}
|
|
1768
|
-
);
|
|
1769
|
-
} catch (submitErr) {
|
|
1770
|
-
log.error("runner", "Failed to report auth config error to platform", { error: submitErr instanceof Error ? submitErr.message : String(submitErr) });
|
|
1771
|
-
}
|
|
1772
|
-
}
|
|
1773
|
-
}
|
|
1774
|
-
async handleGetApiConfig(request) {
|
|
1775
|
-
log.info("runner", "API config requested", { requestId: request.requestId, sessionId: this.session.sessionId });
|
|
1776
|
-
try {
|
|
1777
|
-
const apiInterface = this.appConfig?.interfaces.find(
|
|
1778
|
-
(i) => i.type === "api" && i.enabled !== false
|
|
1779
|
-
);
|
|
1780
|
-
if (!apiInterface) {
|
|
1781
|
-
throw new Error("No API interface config found");
|
|
1782
|
-
}
|
|
1783
|
-
const apiJsonPath = join6(this.projectRoot, apiInterface.path);
|
|
1784
|
-
const raw = readFileSync3(apiJsonPath, "utf-8");
|
|
1785
|
-
const parsed = JSON.parse(raw);
|
|
1786
|
-
if (!parsed.api) {
|
|
1787
|
-
throw new Error("No API interface config found");
|
|
1788
|
-
}
|
|
1789
|
-
await submitDevResult(
|
|
1790
|
-
this.appId,
|
|
1791
|
-
this.session.sessionId,
|
|
1792
|
-
request.requestId,
|
|
1793
|
-
{
|
|
1794
|
-
type: "get-api-config",
|
|
1947
|
+
type: "get-config",
|
|
1795
1948
|
success: true,
|
|
1796
|
-
output:
|
|
1949
|
+
output: config2
|
|
1797
1950
|
}
|
|
1798
1951
|
);
|
|
1799
|
-
log.info("runner", "
|
|
1952
|
+
log.info("runner", "Config sent", { requestId: request.requestId });
|
|
1800
1953
|
} catch (err) {
|
|
1801
1954
|
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1802
|
-
log.error("runner", "
|
|
1955
|
+
log.error("runner", "Config failed", { requestId: request.requestId, error: message });
|
|
1803
1956
|
try {
|
|
1804
1957
|
await submitDevResult(
|
|
1805
1958
|
this.appId,
|
|
1806
1959
|
this.session.sessionId,
|
|
1807
1960
|
request.requestId,
|
|
1808
1961
|
{
|
|
1809
|
-
type: "get-
|
|
1962
|
+
type: "get-config",
|
|
1810
1963
|
success: false,
|
|
1811
1964
|
error: { message }
|
|
1812
1965
|
}
|
|
1813
1966
|
);
|
|
1814
1967
|
} catch (submitErr) {
|
|
1815
|
-
log.error("runner", "Failed to report
|
|
1968
|
+
log.error("runner", "Failed to report config error to platform", { error: submitErr instanceof Error ? submitErr.message : String(submitErr) });
|
|
1816
1969
|
}
|
|
1817
1970
|
}
|
|
1818
1971
|
}
|
|
@@ -1861,7 +2014,7 @@ var DevRunner = class {
|
|
|
1861
2014
|
}
|
|
1862
2015
|
}
|
|
1863
2016
|
sleep(ms) {
|
|
1864
|
-
return new Promise((
|
|
2017
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
1865
2018
|
}
|
|
1866
2019
|
};
|
|
1867
2020
|
|
|
@@ -2055,12 +2208,12 @@ var DevProxy = class _DevProxy {
|
|
|
2055
2208
|
);
|
|
2056
2209
|
}
|
|
2057
2210
|
const id = randomBytes4(4).toString("hex");
|
|
2058
|
-
return new Promise((
|
|
2211
|
+
return new Promise((resolve3, reject) => {
|
|
2059
2212
|
this.commandQueue.push({
|
|
2060
2213
|
id,
|
|
2061
2214
|
steps,
|
|
2062
2215
|
timeoutMs,
|
|
2063
|
-
resolve:
|
|
2216
|
+
resolve: resolve3,
|
|
2064
2217
|
reject,
|
|
2065
2218
|
queuedAt: Date.now()
|
|
2066
2219
|
});
|
|
@@ -2080,7 +2233,7 @@ var DevProxy = class _DevProxy {
|
|
|
2080
2233
|
const target = this.clients.getCommandTarget();
|
|
2081
2234
|
if (!target) break;
|
|
2082
2235
|
const queued = this.commandQueue.shift();
|
|
2083
|
-
const { id, steps, timeoutMs, resolve:
|
|
2236
|
+
const { id, steps, timeoutMs, resolve: resolve3, reject } = queued;
|
|
2084
2237
|
log.info("proxy", "Browser command sent", {
|
|
2085
2238
|
id,
|
|
2086
2239
|
clientId: target.id,
|
|
@@ -2100,7 +2253,7 @@ var DevProxy = class _DevProxy {
|
|
|
2100
2253
|
reject(new Error("Browser command timed out"));
|
|
2101
2254
|
this.drainCommandQueue();
|
|
2102
2255
|
}, timeoutMs);
|
|
2103
|
-
this.pendingResults.set(id, { resolve:
|
|
2256
|
+
this.pendingResults.set(id, { resolve: resolve3, timeout, clientId: target.id });
|
|
2104
2257
|
target.activeCommandId = id;
|
|
2105
2258
|
try {
|
|
2106
2259
|
target.ws.send(JSON.stringify({ type: "command", id, steps }));
|
|
@@ -2168,7 +2321,7 @@ var DevProxy = class _DevProxy {
|
|
|
2168
2321
|
throw new Error("Failed to start proxy server");
|
|
2169
2322
|
}
|
|
2170
2323
|
listenOnPort(server, port) {
|
|
2171
|
-
return new Promise((
|
|
2324
|
+
return new Promise((resolve3, reject) => {
|
|
2172
2325
|
const onError = (err) => {
|
|
2173
2326
|
server.removeListener("error", onError);
|
|
2174
2327
|
reject(err);
|
|
@@ -2181,7 +2334,7 @@ var DevProxy = class _DevProxy {
|
|
|
2181
2334
|
reject(new Error("Failed to get proxy server address"));
|
|
2182
2335
|
return;
|
|
2183
2336
|
}
|
|
2184
|
-
|
|
2337
|
+
resolve3(addr.port);
|
|
2185
2338
|
});
|
|
2186
2339
|
});
|
|
2187
2340
|
}
|
|
@@ -2834,7 +2987,7 @@ var DevProxy = class _DevProxy {
|
|
|
2834
2987
|
if (releaseId) url.searchParams.set("releaseId", releaseId);
|
|
2835
2988
|
const isHttps = url.protocol === "https:";
|
|
2836
2989
|
const httpModule = isHttps ? https : http;
|
|
2837
|
-
return new Promise((
|
|
2990
|
+
return new Promise((resolve3) => {
|
|
2838
2991
|
const req = httpModule.request(
|
|
2839
2992
|
{
|
|
2840
2993
|
hostname: url.hostname,
|
|
@@ -2853,24 +3006,24 @@ var DevProxy = class _DevProxy {
|
|
|
2853
3006
|
try {
|
|
2854
3007
|
const body = JSON.parse(Buffer.concat(chunks).toString("utf-8"));
|
|
2855
3008
|
if (body.user && body.token) {
|
|
2856
|
-
|
|
3009
|
+
resolve3({
|
|
2857
3010
|
user: body.user,
|
|
2858
3011
|
token: body.token,
|
|
2859
3012
|
methods: body.methods ?? {}
|
|
2860
3013
|
});
|
|
2861
3014
|
} else {
|
|
2862
|
-
|
|
3015
|
+
resolve3(null);
|
|
2863
3016
|
}
|
|
2864
3017
|
} catch {
|
|
2865
|
-
|
|
3018
|
+
resolve3(null);
|
|
2866
3019
|
}
|
|
2867
3020
|
});
|
|
2868
3021
|
}
|
|
2869
3022
|
);
|
|
2870
|
-
req.on("error", () =>
|
|
3023
|
+
req.on("error", () => resolve3(null));
|
|
2871
3024
|
req.setTimeout(3e3, () => {
|
|
2872
3025
|
req.destroy();
|
|
2873
|
-
|
|
3026
|
+
resolve3(null);
|
|
2874
3027
|
});
|
|
2875
3028
|
req.end();
|
|
2876
3029
|
});
|
|
@@ -2933,13 +3086,13 @@ ${agentScript}`;
|
|
|
2933
3086
|
};
|
|
2934
3087
|
|
|
2935
3088
|
// src/dev/config/app-config.ts
|
|
2936
|
-
import { readFileSync as
|
|
2937
|
-
import { join as
|
|
3089
|
+
import { readFileSync as readFileSync6, existsSync as existsSync3 } from "fs";
|
|
3090
|
+
import { join as join8, dirname as dirname4 } from "path";
|
|
2938
3091
|
function detectAppConfig(cwd = process.cwd()) {
|
|
2939
|
-
const appJsonPath =
|
|
2940
|
-
if (!
|
|
3092
|
+
const appJsonPath = join8(cwd, "mindstudio.json");
|
|
3093
|
+
if (!existsSync3(appJsonPath)) return null;
|
|
2941
3094
|
try {
|
|
2942
|
-
const raw =
|
|
3095
|
+
const raw = readFileSync6(appJsonPath, "utf-8");
|
|
2943
3096
|
const parsed = JSON.parse(raw);
|
|
2944
3097
|
if (!parsed.name || !Array.isArray(parsed.methods)) {
|
|
2945
3098
|
return null;
|
|
@@ -2976,12 +3129,12 @@ function getWebInterfaceConfig(appConfig, cwd = process.cwd()) {
|
|
|
2976
3129
|
if (!webInterface) {
|
|
2977
3130
|
return null;
|
|
2978
3131
|
}
|
|
2979
|
-
const configPath =
|
|
2980
|
-
if (!
|
|
3132
|
+
const configPath = join8(cwd, webInterface.path);
|
|
3133
|
+
if (!existsSync3(configPath)) {
|
|
2981
3134
|
return null;
|
|
2982
3135
|
}
|
|
2983
3136
|
try {
|
|
2984
|
-
const raw =
|
|
3137
|
+
const raw = readFileSync6(configPath, "utf-8");
|
|
2985
3138
|
const parsed = JSON.parse(raw);
|
|
2986
3139
|
const web = parsed.web;
|
|
2987
3140
|
if (!web || typeof web !== "object") {
|
|
@@ -3002,18 +3155,18 @@ function getWebProjectDir(appConfig, cwd = process.cwd()) {
|
|
|
3002
3155
|
if (!webInterface) {
|
|
3003
3156
|
return null;
|
|
3004
3157
|
}
|
|
3005
|
-
return
|
|
3158
|
+
return dirname4(join8(cwd, webInterface.path));
|
|
3006
3159
|
}
|
|
3007
3160
|
function readTableSources(appConfig, cwd = process.cwd()) {
|
|
3008
3161
|
const results = [];
|
|
3009
3162
|
for (const table of appConfig.tables) {
|
|
3010
|
-
const filePath =
|
|
3011
|
-
if (!
|
|
3163
|
+
const filePath = join8(cwd, table.path);
|
|
3164
|
+
if (!existsSync3(filePath)) {
|
|
3012
3165
|
log.warn("config", "Table source file not found", { table: table.export, path: table.path });
|
|
3013
3166
|
continue;
|
|
3014
3167
|
}
|
|
3015
3168
|
try {
|
|
3016
|
-
const source =
|
|
3169
|
+
const source = readFileSync6(filePath, "utf-8");
|
|
3017
3170
|
const name = table.export;
|
|
3018
3171
|
results.push({ name, source });
|
|
3019
3172
|
} catch (err) {
|
|
@@ -3031,9 +3184,9 @@ function findDirsNeedingInstall(appConfig, cwd = process.cwd()) {
|
|
|
3031
3184
|
const firstMethodPath = appConfig.methods[0].path;
|
|
3032
3185
|
const parts = firstMethodPath.split("/");
|
|
3033
3186
|
for (let i = parts.length - 1; i >= 1; i--) {
|
|
3034
|
-
const candidate =
|
|
3035
|
-
if (
|
|
3036
|
-
if (!
|
|
3187
|
+
const candidate = join8(cwd, ...parts.slice(0, i));
|
|
3188
|
+
if (existsSync3(join8(candidate, "package.json"))) {
|
|
3189
|
+
if (!existsSync3(join8(candidate, "node_modules"))) {
|
|
3037
3190
|
dirs.push(candidate);
|
|
3038
3191
|
}
|
|
3039
3192
|
break;
|
|
@@ -3041,8 +3194,8 @@ function findDirsNeedingInstall(appConfig, cwd = process.cwd()) {
|
|
|
3041
3194
|
}
|
|
3042
3195
|
}
|
|
3043
3196
|
const webProjectDir = getWebProjectDir(appConfig, cwd);
|
|
3044
|
-
if (webProjectDir &&
|
|
3045
|
-
if (!
|
|
3197
|
+
if (webProjectDir && existsSync3(join8(webProjectDir, "package.json"))) {
|
|
3198
|
+
if (!existsSync3(join8(webProjectDir, "node_modules"))) {
|
|
3046
3199
|
dirs.push(webProjectDir);
|
|
3047
3200
|
}
|
|
3048
3201
|
}
|
|
@@ -3071,11 +3224,11 @@ function detectGitBranch() {
|
|
|
3071
3224
|
|
|
3072
3225
|
// src/dev/config/table-watcher.ts
|
|
3073
3226
|
import { watch } from "chokidar";
|
|
3074
|
-
import { join as
|
|
3227
|
+
import { join as join9, dirname as dirname5, basename as basename2 } from "path";
|
|
3075
3228
|
function watchTableFiles(tables, cwd, onChanged) {
|
|
3076
3229
|
if (tables.length === 0) return () => {
|
|
3077
3230
|
};
|
|
3078
|
-
const filePaths = tables.map((t) =>
|
|
3231
|
+
const filePaths = tables.map((t) => join9(cwd, t.path));
|
|
3079
3232
|
let syncTimer;
|
|
3080
3233
|
const watcher = watch(filePaths, {
|
|
3081
3234
|
ignoreInitial: true,
|
|
@@ -3088,8 +3241,8 @@ function watchTableFiles(tables, cwd, onChanged) {
|
|
|
3088
3241
|
});
|
|
3089
3242
|
const dirToFiles = /* @__PURE__ */ new Map();
|
|
3090
3243
|
for (const table of tables) {
|
|
3091
|
-
const absPath =
|
|
3092
|
-
const dir =
|
|
3244
|
+
const absPath = join9(cwd, table.path);
|
|
3245
|
+
const dir = dirname5(absPath);
|
|
3093
3246
|
const file = basename2(absPath);
|
|
3094
3247
|
if (!dirToFiles.has(dir)) dirToFiles.set(dir, /* @__PURE__ */ new Set());
|
|
3095
3248
|
dirToFiles.get(dir).add(file);
|
|
@@ -3106,9 +3259,9 @@ function watchTableFiles(tables, cwd, onChanged) {
|
|
|
3106
3259
|
|
|
3107
3260
|
// src/dev/config/config-watcher.ts
|
|
3108
3261
|
import { watch as watch2 } from "chokidar";
|
|
3109
|
-
import { join as
|
|
3262
|
+
import { join as join10 } from "path";
|
|
3110
3263
|
function watchConfigFile(cwd, onChanged) {
|
|
3111
|
-
const configPath =
|
|
3264
|
+
const configPath = join10(cwd, "mindstudio.json");
|
|
3112
3265
|
let debounceTimer;
|
|
3113
3266
|
const watcher = watch2(configPath, {
|
|
3114
3267
|
ignoreInitial: true,
|
|
@@ -3177,4 +3330,4 @@ export {
|
|
|
3177
3330
|
watchTableFiles,
|
|
3178
3331
|
watchConfigFile
|
|
3179
3332
|
};
|
|
3180
|
-
//# sourceMappingURL=chunk-
|
|
3333
|
+
//# sourceMappingURL=chunk-UKMKZQKQ.js.map
|