@mindstudio-ai/remy 0.1.175 → 0.1.177
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/headless.js +356 -157
- package/dist/index.js +391 -175
- package/dist/prompt/compiled/interfaces.md +48 -3
- package/dist/prompt/static/coding.md +3 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -55,14 +55,14 @@ function initLoggerHeadless(level = "info") {
|
|
|
55
55
|
}
|
|
56
56
|
function initLoggerInteractive(level = "error") {
|
|
57
57
|
currentLevel = LEVELS[level];
|
|
58
|
-
let
|
|
58
|
+
let fd2 = null;
|
|
59
59
|
writeFn = (line) => {
|
|
60
60
|
try {
|
|
61
|
-
if (
|
|
61
|
+
if (fd2 === null) {
|
|
62
62
|
fs.mkdirSync(".logs", { recursive: true });
|
|
63
|
-
|
|
63
|
+
fd2 = fs.openSync(".logs/agent.ndjson", "a");
|
|
64
64
|
}
|
|
65
|
-
fs.writeSync(
|
|
65
|
+
fs.writeSync(fd2, line + "\n");
|
|
66
66
|
} catch {
|
|
67
67
|
}
|
|
68
68
|
};
|
|
@@ -209,8 +209,10 @@ async function* streamChat(params) {
|
|
|
209
209
|
...subAgentId && { subAgentId },
|
|
210
210
|
durationMs: elapsed,
|
|
211
211
|
stopReason: event.stopReason,
|
|
212
|
+
modelId: event.modelId,
|
|
212
213
|
inputTokens: event.usage.inputTokens,
|
|
213
|
-
outputTokens: event.usage.outputTokens
|
|
214
|
+
outputTokens: event.usage.outputTokens,
|
|
215
|
+
cost: event.cost
|
|
214
216
|
});
|
|
215
217
|
} else if (event.type === "error") {
|
|
216
218
|
log.error("SSE error event", {
|
|
@@ -296,6 +298,7 @@ async function generateBackgroundAck(params) {
|
|
|
296
298
|
Authorization: `Bearer ${params.apiConfig.apiKey}`
|
|
297
299
|
},
|
|
298
300
|
body: JSON.stringify({
|
|
301
|
+
appId: params.apiConfig.appId,
|
|
299
302
|
agentName: params.agentName,
|
|
300
303
|
task: params.task
|
|
301
304
|
}),
|
|
@@ -1237,12 +1240,127 @@ var init_sdkConsultant = __esm({
|
|
|
1237
1240
|
}
|
|
1238
1241
|
});
|
|
1239
1242
|
|
|
1243
|
+
// src/usageLedger.ts
|
|
1244
|
+
import fs8 from "fs";
|
|
1245
|
+
function nanoToDollars(nano) {
|
|
1246
|
+
return typeof nano === "number" ? nano / 1e9 : void 0;
|
|
1247
|
+
}
|
|
1248
|
+
function recordUsage(entry) {
|
|
1249
|
+
try {
|
|
1250
|
+
if (fd === null) {
|
|
1251
|
+
fs8.mkdirSync(".logs", { recursive: true });
|
|
1252
|
+
fd = fs8.openSync(LEDGER_FILE, "a");
|
|
1253
|
+
}
|
|
1254
|
+
fs8.writeSync(fd, JSON.stringify(entry) + "\n");
|
|
1255
|
+
} catch {
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
var LEDGER_FILE, fd;
|
|
1259
|
+
var init_usageLedger = __esm({
|
|
1260
|
+
"src/usageLedger.ts"() {
|
|
1261
|
+
"use strict";
|
|
1262
|
+
LEDGER_FILE = ".logs/usage.ndjson";
|
|
1263
|
+
fd = null;
|
|
1264
|
+
}
|
|
1265
|
+
});
|
|
1266
|
+
|
|
1267
|
+
// src/subagents/common/runMindstudioCli.ts
|
|
1268
|
+
function stripFlags(args2) {
|
|
1269
|
+
const out = [];
|
|
1270
|
+
for (let i = 0; i < args2.length; i++) {
|
|
1271
|
+
const arg = args2[i];
|
|
1272
|
+
if (arg === "--no-meta") {
|
|
1273
|
+
continue;
|
|
1274
|
+
}
|
|
1275
|
+
if (arg === "--output-key") {
|
|
1276
|
+
i++;
|
|
1277
|
+
continue;
|
|
1278
|
+
}
|
|
1279
|
+
out.push(arg);
|
|
1280
|
+
}
|
|
1281
|
+
return out;
|
|
1282
|
+
}
|
|
1283
|
+
async function runMindstudioCli(args2, options) {
|
|
1284
|
+
const cleanArgs = stripFlags(args2);
|
|
1285
|
+
const cliAction = args2[0];
|
|
1286
|
+
const agentName = options?.caller ?? "mindstudio-cli";
|
|
1287
|
+
const start = Date.now();
|
|
1288
|
+
const raw = await runCli("mindstudio", cleanArgs, options);
|
|
1289
|
+
let envelope;
|
|
1290
|
+
try {
|
|
1291
|
+
envelope = JSON.parse(raw);
|
|
1292
|
+
} catch {
|
|
1293
|
+
return raw;
|
|
1294
|
+
}
|
|
1295
|
+
if (envelope && typeof envelope === "object" && Array.isArray(envelope.results)) {
|
|
1296
|
+
const durationMs = Date.now() - start;
|
|
1297
|
+
for (const step of envelope.results) {
|
|
1298
|
+
if (typeof step?.billingCost === "number") {
|
|
1299
|
+
recordUsage({
|
|
1300
|
+
ts: Date.now(),
|
|
1301
|
+
agentName,
|
|
1302
|
+
cliAction: `${cliAction}:${step.stepType ?? "step"}`,
|
|
1303
|
+
cost: nanoToDollars(step.billingCost),
|
|
1304
|
+
inputTokens: 0,
|
|
1305
|
+
outputTokens: 0,
|
|
1306
|
+
durationMs,
|
|
1307
|
+
toolNames: []
|
|
1308
|
+
});
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
return JSON.stringify(envelope.results);
|
|
1312
|
+
}
|
|
1313
|
+
if (typeof envelope?.$billingCost === "number") {
|
|
1314
|
+
recordUsage({
|
|
1315
|
+
ts: Date.now(),
|
|
1316
|
+
agentName,
|
|
1317
|
+
cliAction,
|
|
1318
|
+
cost: nanoToDollars(envelope.$billingCost),
|
|
1319
|
+
billingEvents: envelope.$billingEvents,
|
|
1320
|
+
// CLI billing isn't expressed as input/output tokens for most actions
|
|
1321
|
+
// (image gen is per-image, scrape per-page, etc). `numUnits` inside each
|
|
1322
|
+
// billingEvent carries the per-event unit count.
|
|
1323
|
+
inputTokens: 0,
|
|
1324
|
+
outputTokens: 0,
|
|
1325
|
+
durationMs: Date.now() - start,
|
|
1326
|
+
toolNames: []
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1329
|
+
if (options?.outputKey) {
|
|
1330
|
+
const v = envelope?.[options.outputKey];
|
|
1331
|
+
if (v === void 0 || v === null) {
|
|
1332
|
+
return JSON.stringify(stripDollarKeys(envelope));
|
|
1333
|
+
}
|
|
1334
|
+
return typeof v === "string" ? v : JSON.stringify(v);
|
|
1335
|
+
}
|
|
1336
|
+
return JSON.stringify(stripDollarKeys(envelope));
|
|
1337
|
+
}
|
|
1338
|
+
function stripDollarKeys(envelope) {
|
|
1339
|
+
if (!envelope || typeof envelope !== "object" || Array.isArray(envelope)) {
|
|
1340
|
+
return envelope;
|
|
1341
|
+
}
|
|
1342
|
+
const out = {};
|
|
1343
|
+
for (const [k, v] of Object.entries(envelope)) {
|
|
1344
|
+
if (!k.startsWith("$")) {
|
|
1345
|
+
out[k] = v;
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
return out;
|
|
1349
|
+
}
|
|
1350
|
+
var init_runMindstudioCli = __esm({
|
|
1351
|
+
"src/subagents/common/runMindstudioCli.ts"() {
|
|
1352
|
+
"use strict";
|
|
1353
|
+
init_runCli();
|
|
1354
|
+
init_usageLedger();
|
|
1355
|
+
}
|
|
1356
|
+
});
|
|
1357
|
+
|
|
1240
1358
|
// src/tools/common/searchGoogle.ts
|
|
1241
1359
|
var searchGoogleTool;
|
|
1242
1360
|
var init_searchGoogle = __esm({
|
|
1243
1361
|
"src/tools/common/searchGoogle.ts"() {
|
|
1244
1362
|
"use strict";
|
|
1245
|
-
|
|
1363
|
+
init_runMindstudioCli();
|
|
1246
1364
|
searchGoogleTool = {
|
|
1247
1365
|
clearable: false,
|
|
1248
1366
|
definition: {
|
|
@@ -1261,19 +1379,9 @@ var init_searchGoogle = __esm({
|
|
|
1261
1379
|
},
|
|
1262
1380
|
async execute(input, context) {
|
|
1263
1381
|
const query = input.query;
|
|
1264
|
-
return
|
|
1265
|
-
"
|
|
1266
|
-
|
|
1267
|
-
"search-google",
|
|
1268
|
-
"--query",
|
|
1269
|
-
query,
|
|
1270
|
-
"--export-type",
|
|
1271
|
-
"json",
|
|
1272
|
-
"--output-key",
|
|
1273
|
-
"results",
|
|
1274
|
-
"--no-meta"
|
|
1275
|
-
],
|
|
1276
|
-
{ maxBuffer: 512 * 1024, onLog: context?.onLog }
|
|
1382
|
+
return runMindstudioCli(
|
|
1383
|
+
["search-google", "--query", query, "--export-type", "json"],
|
|
1384
|
+
{ outputKey: "results", maxBuffer: 512 * 1024, onLog: context?.onLog }
|
|
1277
1385
|
);
|
|
1278
1386
|
}
|
|
1279
1387
|
};
|
|
@@ -1320,12 +1428,12 @@ var init_setProjectMetadata = __esm({
|
|
|
1320
1428
|
});
|
|
1321
1429
|
|
|
1322
1430
|
// src/assets.ts
|
|
1323
|
-
import
|
|
1431
|
+
import fs9 from "fs";
|
|
1324
1432
|
import path3 from "path";
|
|
1325
1433
|
function findRoot(start) {
|
|
1326
1434
|
let dir = start;
|
|
1327
1435
|
while (dir !== path3.dirname(dir)) {
|
|
1328
|
-
if (
|
|
1436
|
+
if (fs9.existsSync(path3.join(dir, "package.json"))) {
|
|
1329
1437
|
return dir;
|
|
1330
1438
|
}
|
|
1331
1439
|
dir = path3.dirname(dir);
|
|
@@ -1338,7 +1446,7 @@ function assetPath(...segments) {
|
|
|
1338
1446
|
function readAsset(...segments) {
|
|
1339
1447
|
const full = assetPath(...segments);
|
|
1340
1448
|
try {
|
|
1341
|
-
return
|
|
1449
|
+
return fs9.readFileSync(full, "utf-8").trim();
|
|
1342
1450
|
} catch {
|
|
1343
1451
|
throw new Error(`Required asset missing: ${full}`);
|
|
1344
1452
|
}
|
|
@@ -1346,7 +1454,7 @@ function readAsset(...segments) {
|
|
|
1346
1454
|
function readJsonAsset(fallback, ...segments) {
|
|
1347
1455
|
const full = assetPath(...segments);
|
|
1348
1456
|
try {
|
|
1349
|
-
return JSON.parse(
|
|
1457
|
+
return JSON.parse(fs9.readFileSync(full, "utf-8"));
|
|
1350
1458
|
} catch {
|
|
1351
1459
|
return fallback;
|
|
1352
1460
|
}
|
|
@@ -1358,7 +1466,7 @@ var init_assets = __esm({
|
|
|
1358
1466
|
ROOT = findRoot(
|
|
1359
1467
|
import.meta.dirname ?? path3.dirname(new URL(import.meta.url).pathname)
|
|
1360
1468
|
);
|
|
1361
|
-
ASSETS_BASE =
|
|
1469
|
+
ASSETS_BASE = fs9.existsSync(path3.join(ROOT, "dist", "prompt")) ? path3.join(ROOT, "dist") : path3.join(ROOT, "src");
|
|
1362
1470
|
}
|
|
1363
1471
|
});
|
|
1364
1472
|
|
|
@@ -1571,6 +1679,7 @@ async function generateSummary(apiConfig, name, compactionPrompt, messagesToSumm
|
|
|
1571
1679
|
Conversation to summarize:
|
|
1572
1680
|
|
|
1573
1681
|
${serialized}` : serialized;
|
|
1682
|
+
const iterStart = Date.now();
|
|
1574
1683
|
for await (const event of streamChat({
|
|
1575
1684
|
...apiConfig,
|
|
1576
1685
|
subAgentId: "conversationSummarizer",
|
|
@@ -1580,6 +1689,20 @@ ${serialized}` : serialized;
|
|
|
1580
1689
|
})) {
|
|
1581
1690
|
if (event.type === "text") {
|
|
1582
1691
|
summaryText += event.text;
|
|
1692
|
+
} else if (event.type === "done") {
|
|
1693
|
+
recordUsage({
|
|
1694
|
+
ts: Date.now(),
|
|
1695
|
+
agentName: "conversationSummarizer",
|
|
1696
|
+
modelId: event.modelId,
|
|
1697
|
+
inputTokens: event.usage.inputTokens,
|
|
1698
|
+
outputTokens: event.usage.outputTokens,
|
|
1699
|
+
cacheCreationTokens: event.usage.cacheCreationTokens,
|
|
1700
|
+
cacheReadTokens: event.usage.cacheReadTokens,
|
|
1701
|
+
cost: nanoToDollars(event.cost),
|
|
1702
|
+
billingEvents: event.billingEvents,
|
|
1703
|
+
durationMs: Date.now() - iterStart,
|
|
1704
|
+
toolNames: []
|
|
1705
|
+
});
|
|
1583
1706
|
} else if (event.type === "error") {
|
|
1584
1707
|
log2.error("Summary generation failed", { name, error: event.error });
|
|
1585
1708
|
return null;
|
|
@@ -1599,6 +1722,7 @@ var init_compaction = __esm({
|
|
|
1599
1722
|
init_api();
|
|
1600
1723
|
init_assets();
|
|
1601
1724
|
init_logger();
|
|
1725
|
+
init_usageLedger();
|
|
1602
1726
|
log2 = createLogger("compaction");
|
|
1603
1727
|
CONVERSATION_SUMMARY_PROMPT = readAsset("compaction", "conversation.md");
|
|
1604
1728
|
SUBAGENT_SUMMARY_PROMPT = readAsset("compaction", "subagent.md");
|
|
@@ -1608,11 +1732,11 @@ var init_compaction = __esm({
|
|
|
1608
1732
|
});
|
|
1609
1733
|
|
|
1610
1734
|
// src/prompt/static/projectContext.ts
|
|
1611
|
-
import
|
|
1735
|
+
import fs10 from "fs";
|
|
1612
1736
|
import path4 from "path";
|
|
1613
1737
|
function loadProjectManifest() {
|
|
1614
1738
|
try {
|
|
1615
|
-
const manifest =
|
|
1739
|
+
const manifest = fs10.readFileSync("mindstudio.json", "utf-8");
|
|
1616
1740
|
return `
|
|
1617
1741
|
## Project Manifest (mindstudio.json)
|
|
1618
1742
|
\`\`\`json
|
|
@@ -1653,7 +1777,7 @@ ${entries.join("\n")}`;
|
|
|
1653
1777
|
function walkMdFiles(dir) {
|
|
1654
1778
|
const results = [];
|
|
1655
1779
|
try {
|
|
1656
|
-
const entries =
|
|
1780
|
+
const entries = fs10.readdirSync(dir, { withFileTypes: true });
|
|
1657
1781
|
for (const entry of entries) {
|
|
1658
1782
|
const full = path4.join(dir, entry.name);
|
|
1659
1783
|
if (entry.isDirectory()) {
|
|
@@ -1668,7 +1792,7 @@ function walkMdFiles(dir) {
|
|
|
1668
1792
|
}
|
|
1669
1793
|
function parseFrontmatter(filePath) {
|
|
1670
1794
|
try {
|
|
1671
|
-
const content =
|
|
1795
|
+
const content = fs10.readFileSync(filePath, "utf-8");
|
|
1672
1796
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
1673
1797
|
if (!match) {
|
|
1674
1798
|
return { name: "", description: "", type: "" };
|
|
@@ -1684,7 +1808,7 @@ function parseFrontmatter(filePath) {
|
|
|
1684
1808
|
}
|
|
1685
1809
|
function loadPlanStatus() {
|
|
1686
1810
|
try {
|
|
1687
|
-
const content =
|
|
1811
|
+
const content = fs10.readFileSync(".remy-plan.md", "utf-8");
|
|
1688
1812
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
1689
1813
|
const status = match?.[1]?.match(/^status:\s*(.+)$/m)?.[1]?.trim();
|
|
1690
1814
|
if (status === "pending") {
|
|
@@ -1706,7 +1830,7 @@ The user has approved your implementation plan in .remy-plan.md. You may referen
|
|
|
1706
1830
|
}
|
|
1707
1831
|
function loadProjectFileListing() {
|
|
1708
1832
|
try {
|
|
1709
|
-
const entries =
|
|
1833
|
+
const entries = fs10.readdirSync(".", { withFileTypes: true });
|
|
1710
1834
|
const listing = entries.filter((e) => e.name !== ".git" && e.name !== "node_modules").sort((a, b) => {
|
|
1711
1835
|
if (a.isDirectory() && !b.isDirectory()) {
|
|
1712
1836
|
return -1;
|
|
@@ -1961,7 +2085,7 @@ var init_compactConversation = __esm({
|
|
|
1961
2085
|
});
|
|
1962
2086
|
|
|
1963
2087
|
// src/tools/code/readFile.ts
|
|
1964
|
-
import
|
|
2088
|
+
import fs11 from "fs/promises";
|
|
1965
2089
|
function isBinary(buffer) {
|
|
1966
2090
|
const sample = buffer.subarray(0, 8192);
|
|
1967
2091
|
for (let i = 0; i < sample.length; i++) {
|
|
@@ -2002,7 +2126,7 @@ var init_readFile = __esm({
|
|
|
2002
2126
|
},
|
|
2003
2127
|
async execute(input) {
|
|
2004
2128
|
try {
|
|
2005
|
-
const buffer = await
|
|
2129
|
+
const buffer = await fs11.readFile(input.path);
|
|
2006
2130
|
if (isBinary(buffer)) {
|
|
2007
2131
|
const size = buffer.length;
|
|
2008
2132
|
const unit = size > 1024 * 1024 ? `${(size / (1024 * 1024)).toFixed(1)}MB` : `${(size / 1024).toFixed(1)}KB`;
|
|
@@ -2038,7 +2162,7 @@ var init_readFile = __esm({
|
|
|
2038
2162
|
});
|
|
2039
2163
|
|
|
2040
2164
|
// src/tools/code/writeFile.ts
|
|
2041
|
-
import
|
|
2165
|
+
import fs12 from "fs/promises";
|
|
2042
2166
|
import path5 from "path";
|
|
2043
2167
|
var writeFileTool;
|
|
2044
2168
|
var init_writeFile = __esm({
|
|
@@ -2082,7 +2206,7 @@ var init_writeFile = __esm({
|
|
|
2082
2206
|
lastNewlineCount = newlineCount;
|
|
2083
2207
|
const lastNewline = partial.content.lastIndexOf("\n");
|
|
2084
2208
|
const completeContent = partial.content.substring(0, lastNewline + 1);
|
|
2085
|
-
const oldContent = await
|
|
2209
|
+
const oldContent = await fs12.readFile(partial.path, "utf-8").catch(() => "");
|
|
2086
2210
|
return `Writing ${partial.path} (${newlineCount} lines)
|
|
2087
2211
|
${unifiedDiff(partial.path, oldContent, completeContent)}`;
|
|
2088
2212
|
}
|
|
@@ -2091,13 +2215,13 @@ ${unifiedDiff(partial.path, oldContent, completeContent)}`;
|
|
|
2091
2215
|
async execute(input) {
|
|
2092
2216
|
const release = await acquireFileLock(input.path);
|
|
2093
2217
|
try {
|
|
2094
|
-
await
|
|
2218
|
+
await fs12.mkdir(path5.dirname(input.path), { recursive: true });
|
|
2095
2219
|
let oldContent = null;
|
|
2096
2220
|
try {
|
|
2097
|
-
oldContent = await
|
|
2221
|
+
oldContent = await fs12.readFile(input.path, "utf-8");
|
|
2098
2222
|
} catch {
|
|
2099
2223
|
}
|
|
2100
|
-
await
|
|
2224
|
+
await fs12.writeFile(input.path, input.content, "utf-8");
|
|
2101
2225
|
const lineCount = input.content.split("\n").length;
|
|
2102
2226
|
const label = oldContent !== null ? "Wrote" : "Created";
|
|
2103
2227
|
return `${label} ${input.path} (${lineCount} lines)
|
|
@@ -2197,7 +2321,7 @@ var init_helpers2 = __esm({
|
|
|
2197
2321
|
});
|
|
2198
2322
|
|
|
2199
2323
|
// src/tools/code/editFile/index.ts
|
|
2200
|
-
import
|
|
2324
|
+
import fs13 from "fs/promises";
|
|
2201
2325
|
var editFileTool;
|
|
2202
2326
|
var init_editFile = __esm({
|
|
2203
2327
|
"src/tools/code/editFile/index.ts"() {
|
|
@@ -2236,7 +2360,7 @@ var init_editFile = __esm({
|
|
|
2236
2360
|
async execute(input) {
|
|
2237
2361
|
const release = await acquireFileLock(input.path);
|
|
2238
2362
|
try {
|
|
2239
|
-
const content = await
|
|
2363
|
+
const content = await fs13.readFile(input.path, "utf-8");
|
|
2240
2364
|
const { old_string, new_string, replace_all } = input;
|
|
2241
2365
|
const occurrences = findOccurrences(content, old_string);
|
|
2242
2366
|
if (replace_all) {
|
|
@@ -2252,7 +2376,7 @@ var init_editFile = __esm({
|
|
|
2252
2376
|
new_string
|
|
2253
2377
|
);
|
|
2254
2378
|
}
|
|
2255
|
-
await
|
|
2379
|
+
await fs13.writeFile(input.path, updated, "utf-8");
|
|
2256
2380
|
return `Replaced ${occurrences.length} occurrence${occurrences.length > 1 ? "s" : ""} in ${input.path}
|
|
2257
2381
|
${unifiedDiff(input.path, content, updated)}`;
|
|
2258
2382
|
}
|
|
@@ -2263,7 +2387,7 @@ ${unifiedDiff(input.path, content, updated)}`;
|
|
|
2263
2387
|
old_string.length,
|
|
2264
2388
|
new_string
|
|
2265
2389
|
);
|
|
2266
|
-
await
|
|
2390
|
+
await fs13.writeFile(input.path, updated, "utf-8");
|
|
2267
2391
|
return `Updated ${input.path}
|
|
2268
2392
|
${unifiedDiff(input.path, content, updated)}`;
|
|
2269
2393
|
}
|
|
@@ -2279,7 +2403,7 @@ ${unifiedDiff(input.path, content, updated)}`;
|
|
|
2279
2403
|
flex.matchedText.length,
|
|
2280
2404
|
new_string
|
|
2281
2405
|
);
|
|
2282
|
-
await
|
|
2406
|
+
await fs13.writeFile(input.path, updated, "utf-8");
|
|
2283
2407
|
return `Updated ${input.path} (matched with flexible whitespace at line ${flex.line})
|
|
2284
2408
|
${unifiedDiff(input.path, content, updated)}`;
|
|
2285
2409
|
}
|
|
@@ -2531,10 +2655,10 @@ var init_glob = __esm({
|
|
|
2531
2655
|
});
|
|
2532
2656
|
|
|
2533
2657
|
// src/tools/code/listDir.ts
|
|
2534
|
-
import
|
|
2658
|
+
import fs14 from "fs/promises";
|
|
2535
2659
|
import path6 from "path";
|
|
2536
2660
|
async function readAndSort(dirPath) {
|
|
2537
|
-
const entries = await
|
|
2661
|
+
const entries = await fs14.readdir(dirPath, { withFileTypes: true });
|
|
2538
2662
|
return entries.filter((e) => !EXCLUDE.has(e.name)).sort((a, b) => {
|
|
2539
2663
|
if (a.isDirectory() && !b.isDirectory()) {
|
|
2540
2664
|
return -1;
|
|
@@ -2575,7 +2699,7 @@ function formatSize(bytes) {
|
|
|
2575
2699
|
}
|
|
2576
2700
|
async function formatFile(dirPath, name, indent) {
|
|
2577
2701
|
try {
|
|
2578
|
-
const stat = await
|
|
2702
|
+
const stat = await fs14.stat(path6.join(dirPath, name));
|
|
2579
2703
|
return `${indent}${name}${" ".repeat(Math.max(1, 30 - indent.length - name.length))}${formatSize(stat.size)}`;
|
|
2580
2704
|
} catch {
|
|
2581
2705
|
return `${indent}${name}`;
|
|
@@ -2940,8 +3064,7 @@ var init_queryDatabase = __esm({
|
|
|
2940
3064
|
// src/subagents/common/analyzeImage.ts
|
|
2941
3065
|
async function analyzeImage(params) {
|
|
2942
3066
|
const { prompt, imageUrl, timeout = 2e5, onLog } = params;
|
|
2943
|
-
return
|
|
2944
|
-
"mindstudio",
|
|
3067
|
+
return runMindstudioCli(
|
|
2945
3068
|
[
|
|
2946
3069
|
"analyze-image",
|
|
2947
3070
|
"--prompt",
|
|
@@ -2949,19 +3072,16 @@ async function analyzeImage(params) {
|
|
|
2949
3072
|
"--image-url",
|
|
2950
3073
|
imageUrl,
|
|
2951
3074
|
"--vision-model-override",
|
|
2952
|
-
JSON.stringify(VISION_MODEL_OVERRIDE)
|
|
2953
|
-
"--output-key",
|
|
2954
|
-
"analysis",
|
|
2955
|
-
"--no-meta"
|
|
3075
|
+
JSON.stringify(VISION_MODEL_OVERRIDE)
|
|
2956
3076
|
],
|
|
2957
|
-
{ timeout, onLog }
|
|
3077
|
+
{ outputKey: "analysis", timeout, onLog }
|
|
2958
3078
|
);
|
|
2959
3079
|
}
|
|
2960
3080
|
var VISION_MODEL, VISION_MODEL_OVERRIDE;
|
|
2961
3081
|
var init_analyzeImage = __esm({
|
|
2962
3082
|
"src/subagents/common/analyzeImage.ts"() {
|
|
2963
3083
|
"use strict";
|
|
2964
|
-
|
|
3084
|
+
init_runMindstudioCli();
|
|
2965
3085
|
VISION_MODEL = "claude-4-6-sonnet";
|
|
2966
3086
|
VISION_MODEL_OVERRIDE = {
|
|
2967
3087
|
model: VISION_MODEL,
|
|
@@ -3006,11 +3126,11 @@ async function captureAndAnalyzeScreenshot(promptOrOptions) {
|
|
|
3006
3126
|
let prompt;
|
|
3007
3127
|
let existingUrl;
|
|
3008
3128
|
let onLog;
|
|
3009
|
-
let
|
|
3129
|
+
let path13;
|
|
3010
3130
|
if (typeof promptOrOptions === "object" && promptOrOptions !== null) {
|
|
3011
3131
|
prompt = promptOrOptions.prompt;
|
|
3012
3132
|
existingUrl = promptOrOptions.imageUrl;
|
|
3013
|
-
|
|
3133
|
+
path13 = promptOrOptions.path;
|
|
3014
3134
|
onLog = promptOrOptions.onLog;
|
|
3015
3135
|
} else {
|
|
3016
3136
|
prompt = promptOrOptions;
|
|
@@ -3022,7 +3142,7 @@ async function captureAndAnalyzeScreenshot(promptOrOptions) {
|
|
|
3022
3142
|
} else {
|
|
3023
3143
|
const ssResult = await sidecarRequest(
|
|
3024
3144
|
"/screenshot-full-page",
|
|
3025
|
-
|
|
3145
|
+
path13 ? { path: path13 } : void 0,
|
|
3026
3146
|
{ timeout: 12e4 }
|
|
3027
3147
|
);
|
|
3028
3148
|
url = ssResult?.url || ssResult?.screenshotUrl;
|
|
@@ -3097,7 +3217,7 @@ function startStatusWatcher(config) {
|
|
|
3097
3217
|
"Content-Type": "application/json",
|
|
3098
3218
|
Authorization: `Bearer ${apiConfig.apiKey}`
|
|
3099
3219
|
},
|
|
3100
|
-
body: JSON.stringify({ context }),
|
|
3220
|
+
body: JSON.stringify({ appId: apiConfig.appId, context }),
|
|
3101
3221
|
signal
|
|
3102
3222
|
});
|
|
3103
3223
|
if (!res.ok || stopped) {
|
|
@@ -3299,8 +3419,14 @@ ${content}` : attachmentHeader;
|
|
|
3299
3419
|
const text = blocks.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
3300
3420
|
const toolCalls = blocks.filter((b) => b.type === "tool").map((b) => ({ id: b.id, name: b.name, input: b.input }));
|
|
3301
3421
|
const thinking = blocks.filter(
|
|
3302
|
-
(b) => b.type === "thinking"
|
|
3303
|
-
).map(
|
|
3422
|
+
(b) => b.type === "thinking" || b.type === "redacted_thinking"
|
|
3423
|
+
).map(
|
|
3424
|
+
(b) => b.type === "thinking" ? {
|
|
3425
|
+
type: "thinking",
|
|
3426
|
+
thinking: b.thinking,
|
|
3427
|
+
signature: b.signature
|
|
3428
|
+
} : { type: "redacted_thinking", data: b.data }
|
|
3429
|
+
);
|
|
3304
3430
|
const cleaned2 = {
|
|
3305
3431
|
role: msg.role,
|
|
3306
3432
|
content: text
|
|
@@ -3395,10 +3521,13 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
3395
3521
|
if (signal?.aborted) {
|
|
3396
3522
|
return abortResult([]);
|
|
3397
3523
|
}
|
|
3524
|
+
const iterStart = Date.now();
|
|
3398
3525
|
const contentBlocks = [];
|
|
3399
3526
|
let thinkingStartedAt = 0;
|
|
3527
|
+
let lastThinkingRelatedStartedAt;
|
|
3400
3528
|
let stopReason = "end_turn";
|
|
3401
3529
|
let currentToolNames = "";
|
|
3530
|
+
let lastUsage;
|
|
3402
3531
|
const statusWatcher = startStatusWatcher({
|
|
3403
3532
|
apiConfig,
|
|
3404
3533
|
getContext: () => {
|
|
@@ -3437,7 +3566,7 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
3437
3566
|
{
|
|
3438
3567
|
onRetry: (attempt) => emit({
|
|
3439
3568
|
type: "status",
|
|
3440
|
-
message: `Lost connection, retrying (attempt ${attempt + 2} of 3)
|
|
3569
|
+
message: `Lost connection, retrying (attempt ${attempt + 2} of 3)`
|
|
3441
3570
|
})
|
|
3442
3571
|
}
|
|
3443
3572
|
)) {
|
|
@@ -3473,8 +3602,20 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
3473
3602
|
startedAt: thinkingStartedAt,
|
|
3474
3603
|
completedAt: event.ts
|
|
3475
3604
|
});
|
|
3605
|
+
lastThinkingRelatedStartedAt = thinkingStartedAt;
|
|
3476
3606
|
thinkingStartedAt = 0;
|
|
3477
3607
|
break;
|
|
3608
|
+
case "redacted_thinking_complete": {
|
|
3609
|
+
const startedAt = lastThinkingRelatedStartedAt !== void 0 ? lastThinkingRelatedStartedAt + 1 : event.ts;
|
|
3610
|
+
contentBlocks.push({
|
|
3611
|
+
type: "redacted_thinking",
|
|
3612
|
+
data: event.data,
|
|
3613
|
+
startedAt,
|
|
3614
|
+
completedAt: event.ts
|
|
3615
|
+
});
|
|
3616
|
+
lastThinkingRelatedStartedAt = startedAt;
|
|
3617
|
+
break;
|
|
3618
|
+
}
|
|
3478
3619
|
case "tool_use":
|
|
3479
3620
|
contentBlocks.push({
|
|
3480
3621
|
type: "tool",
|
|
@@ -3492,6 +3633,30 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
3492
3633
|
break;
|
|
3493
3634
|
case "done":
|
|
3494
3635
|
stopReason = event.stopReason;
|
|
3636
|
+
lastUsage = {
|
|
3637
|
+
inputTokens: event.usage.inputTokens,
|
|
3638
|
+
outputTokens: event.usage.outputTokens,
|
|
3639
|
+
cacheCreationTokens: event.usage.cacheCreationTokens,
|
|
3640
|
+
cacheReadTokens: event.usage.cacheReadTokens,
|
|
3641
|
+
llmCalls: 1
|
|
3642
|
+
};
|
|
3643
|
+
recordUsage({
|
|
3644
|
+
ts: Date.now(),
|
|
3645
|
+
requestId,
|
|
3646
|
+
agentName: subAgentId || "sub-agent",
|
|
3647
|
+
parentToolId,
|
|
3648
|
+
modelId: event.modelId,
|
|
3649
|
+
inputTokens: event.usage.inputTokens,
|
|
3650
|
+
outputTokens: event.usage.outputTokens,
|
|
3651
|
+
cacheCreationTokens: event.usage.cacheCreationTokens,
|
|
3652
|
+
cacheReadTokens: event.usage.cacheReadTokens,
|
|
3653
|
+
cost: nanoToDollars(event.cost),
|
|
3654
|
+
billingEvents: event.billingEvents,
|
|
3655
|
+
durationMs: Date.now() - iterStart,
|
|
3656
|
+
toolNames: contentBlocks.filter(
|
|
3657
|
+
(b) => b.type === "tool"
|
|
3658
|
+
).map((b) => b.name)
|
|
3659
|
+
});
|
|
3495
3660
|
break;
|
|
3496
3661
|
case "error":
|
|
3497
3662
|
return {
|
|
@@ -3511,7 +3676,8 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
3511
3676
|
}
|
|
3512
3677
|
messages.push({
|
|
3513
3678
|
role: "assistant",
|
|
3514
|
-
content: contentBlocks
|
|
3679
|
+
content: contentBlocks,
|
|
3680
|
+
...lastUsage ? { usage: lastUsage } : {}
|
|
3515
3681
|
});
|
|
3516
3682
|
const toolCalls = contentBlocks.filter(
|
|
3517
3683
|
(b) => b.type === "tool"
|
|
@@ -3708,6 +3874,7 @@ var init_runner = __esm({
|
|
|
3708
3874
|
"use strict";
|
|
3709
3875
|
init_api();
|
|
3710
3876
|
init_logger();
|
|
3877
|
+
init_usageLedger();
|
|
3711
3878
|
init_statusWatcher();
|
|
3712
3879
|
init_cleanMessages();
|
|
3713
3880
|
log5 = createLogger("sub-agent");
|
|
@@ -3854,10 +4021,10 @@ var init_tools = __esm({
|
|
|
3854
4021
|
});
|
|
3855
4022
|
|
|
3856
4023
|
// src/subagents/browserAutomation/prompt.ts
|
|
3857
|
-
import
|
|
4024
|
+
import fs15 from "fs";
|
|
3858
4025
|
function getBrowserAutomationPrompt() {
|
|
3859
4026
|
try {
|
|
3860
|
-
const appSpec =
|
|
4027
|
+
const appSpec = fs15.readFileSync("src/app.md", "utf-8").trim();
|
|
3861
4028
|
return `${BASE_PROMPT}
|
|
3862
4029
|
|
|
3863
4030
|
<!-- cache_breakpoint -->
|
|
@@ -3889,7 +4056,7 @@ var init_browserAutomation = __esm({
|
|
|
3889
4056
|
init_sidecar();
|
|
3890
4057
|
init_browserLock();
|
|
3891
4058
|
init_screenshot();
|
|
3892
|
-
|
|
4059
|
+
init_runMindstudioCli();
|
|
3893
4060
|
init_analyzeImage();
|
|
3894
4061
|
init_logger();
|
|
3895
4062
|
log6 = createLogger("browser-automation");
|
|
@@ -3977,10 +4144,9 @@ var init_browserAutomation = __esm({
|
|
|
3977
4144
|
visionModelOverride: VISION_MODEL_OVERRIDE
|
|
3978
4145
|
}
|
|
3979
4146
|
}));
|
|
3980
|
-
const batchResult = await
|
|
3981
|
-
"
|
|
3982
|
-
|
|
3983
|
-
{ timeout: 2e5 }
|
|
4147
|
+
const batchResult = await runMindstudioCli(
|
|
4148
|
+
["batch", JSON.stringify(batchInput)],
|
|
4149
|
+
{ timeout: 2e5, caller: "browserAutomation" }
|
|
3984
4150
|
);
|
|
3985
4151
|
try {
|
|
3986
4152
|
const analyses = JSON.parse(batchResult);
|
|
@@ -4205,26 +4371,16 @@ __export(searchGoogle_exports, {
|
|
|
4205
4371
|
execute: () => execute
|
|
4206
4372
|
});
|
|
4207
4373
|
async function execute(input, onLog) {
|
|
4208
|
-
return
|
|
4209
|
-
"
|
|
4210
|
-
|
|
4211
|
-
"search-google",
|
|
4212
|
-
"--query",
|
|
4213
|
-
input.query,
|
|
4214
|
-
"--export-type",
|
|
4215
|
-
"json",
|
|
4216
|
-
"--output-key",
|
|
4217
|
-
"results",
|
|
4218
|
-
"--no-meta"
|
|
4219
|
-
],
|
|
4220
|
-
{ onLog }
|
|
4374
|
+
return runMindstudioCli(
|
|
4375
|
+
["search-google", "--query", input.query, "--export-type", "json"],
|
|
4376
|
+
{ outputKey: "results", onLog, caller: "designExpert" }
|
|
4221
4377
|
);
|
|
4222
4378
|
}
|
|
4223
4379
|
var definition;
|
|
4224
4380
|
var init_searchGoogle2 = __esm({
|
|
4225
4381
|
"src/subagents/designExpert/tools/searchGoogle.ts"() {
|
|
4226
4382
|
"use strict";
|
|
4227
|
-
|
|
4383
|
+
init_runMindstudioCli();
|
|
4228
4384
|
definition = {
|
|
4229
4385
|
clearable: false,
|
|
4230
4386
|
name: "searchGoogle",
|
|
@@ -4254,24 +4410,22 @@ async function execute2(input, onLog) {
|
|
|
4254
4410
|
if (input.screenshot) {
|
|
4255
4411
|
pageOptions.screenshot = true;
|
|
4256
4412
|
}
|
|
4257
|
-
return
|
|
4258
|
-
"mindstudio",
|
|
4413
|
+
return runMindstudioCli(
|
|
4259
4414
|
[
|
|
4260
4415
|
"scrape-url",
|
|
4261
4416
|
"--url",
|
|
4262
4417
|
input.url,
|
|
4263
4418
|
"--page-options",
|
|
4264
|
-
JSON.stringify(pageOptions)
|
|
4265
|
-
"--no-meta"
|
|
4419
|
+
JSON.stringify(pageOptions)
|
|
4266
4420
|
],
|
|
4267
|
-
{ onLog }
|
|
4421
|
+
{ onLog, caller: "designExpert" }
|
|
4268
4422
|
);
|
|
4269
4423
|
}
|
|
4270
4424
|
var definition2;
|
|
4271
4425
|
var init_scrapeWebUrl = __esm({
|
|
4272
4426
|
"src/subagents/designExpert/tools/scrapeWebUrl.ts"() {
|
|
4273
4427
|
"use strict";
|
|
4274
|
-
|
|
4428
|
+
init_runMindstudioCli();
|
|
4275
4429
|
definition2 = {
|
|
4276
4430
|
clearable: false,
|
|
4277
4431
|
name: "scrapeWebUrl",
|
|
@@ -4302,8 +4456,7 @@ async function execute3(input, onLog) {
|
|
|
4302
4456
|
const isImageUrl = /\.(png|jpe?g|webp|gif|svg|avif)(\?|$)/i.test(url);
|
|
4303
4457
|
let imageUrl = url;
|
|
4304
4458
|
if (!isImageUrl) {
|
|
4305
|
-
const ssUrl = await
|
|
4306
|
-
"mindstudio",
|
|
4459
|
+
const ssUrl = await runMindstudioCli(
|
|
4307
4460
|
[
|
|
4308
4461
|
"screenshot-url",
|
|
4309
4462
|
"--url",
|
|
@@ -4313,12 +4466,14 @@ async function execute3(input, onLog) {
|
|
|
4313
4466
|
"--width",
|
|
4314
4467
|
"1440",
|
|
4315
4468
|
"--delay",
|
|
4316
|
-
"2000"
|
|
4317
|
-
"--output-key",
|
|
4318
|
-
"screenshotUrl",
|
|
4319
|
-
"--no-meta"
|
|
4469
|
+
"2000"
|
|
4320
4470
|
],
|
|
4321
|
-
{
|
|
4471
|
+
{
|
|
4472
|
+
outputKey: "screenshotUrl",
|
|
4473
|
+
timeout: 12e4,
|
|
4474
|
+
onLog,
|
|
4475
|
+
caller: "designExpert"
|
|
4476
|
+
}
|
|
4322
4477
|
);
|
|
4323
4478
|
if (ssUrl.startsWith("Error")) {
|
|
4324
4479
|
return `Could not screenshot ${url}: ${ssUrl}`;
|
|
@@ -4336,7 +4491,7 @@ var DESIGN_REFERENCE_PROMPT, definition3;
|
|
|
4336
4491
|
var init_analyzeDesign = __esm({
|
|
4337
4492
|
"src/subagents/designExpert/tools/analyzeDesign.ts"() {
|
|
4338
4493
|
"use strict";
|
|
4339
|
-
|
|
4494
|
+
init_runMindstudioCli();
|
|
4340
4495
|
init_analyzeImage();
|
|
4341
4496
|
DESIGN_REFERENCE_PROMPT = `
|
|
4342
4497
|
You are analyzing a screenshot of a real website or app for a designer's personal technique/inspiration reference notes.
|
|
@@ -4528,19 +4683,15 @@ ${context}
|
|
|
4528
4683
|
<brief>
|
|
4529
4684
|
${brief}
|
|
4530
4685
|
</brief>`;
|
|
4531
|
-
const enhanced = await
|
|
4532
|
-
"mindstudio",
|
|
4686
|
+
const enhanced = await runMindstudioCli(
|
|
4533
4687
|
[
|
|
4534
4688
|
"generate-text",
|
|
4535
4689
|
"--message",
|
|
4536
4690
|
message,
|
|
4537
4691
|
"--model-override",
|
|
4538
|
-
JSON.stringify(MODEL_OVERRIDE)
|
|
4539
|
-
"--output-key",
|
|
4540
|
-
"content",
|
|
4541
|
-
"--no-meta"
|
|
4692
|
+
JSON.stringify(MODEL_OVERRIDE)
|
|
4542
4693
|
],
|
|
4543
|
-
{ timeout: 6e4, onLog }
|
|
4694
|
+
{ outputKey: "content", timeout: 6e4, onLog, caller: "designExpert" }
|
|
4544
4695
|
);
|
|
4545
4696
|
return enhanced.trim();
|
|
4546
4697
|
}
|
|
@@ -4548,7 +4699,7 @@ var ENHANCE_MODEL, MODEL_OVERRIDE, SYSTEM_PROMPT;
|
|
|
4548
4699
|
var init_enhancePrompt = __esm({
|
|
4549
4700
|
"src/subagents/designExpert/tools/images/enhancePrompt.ts"() {
|
|
4550
4701
|
"use strict";
|
|
4551
|
-
|
|
4702
|
+
init_runMindstudioCli();
|
|
4552
4703
|
init_assets();
|
|
4553
4704
|
ENHANCE_MODEL = "claude-4-6-sonnet";
|
|
4554
4705
|
MODEL_OVERRIDE = {
|
|
@@ -4591,11 +4742,14 @@ async function generateImageAssets(opts) {
|
|
|
4591
4742
|
config
|
|
4592
4743
|
}
|
|
4593
4744
|
});
|
|
4594
|
-
const url = await
|
|
4595
|
-
"
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4745
|
+
const url = await runMindstudioCli(["generate-image"], {
|
|
4746
|
+
outputKey: "imageUrl",
|
|
4747
|
+
jsonLogs: true,
|
|
4748
|
+
timeout: 2e5,
|
|
4749
|
+
onLog,
|
|
4750
|
+
stdin: step,
|
|
4751
|
+
caller: "designExpert"
|
|
4752
|
+
});
|
|
4599
4753
|
imageUrls = [url];
|
|
4600
4754
|
} else {
|
|
4601
4755
|
const steps = enhancedPrompts.map((prompt) => ({
|
|
@@ -4608,11 +4762,12 @@ async function generateImageAssets(opts) {
|
|
|
4608
4762
|
}
|
|
4609
4763
|
}
|
|
4610
4764
|
}));
|
|
4611
|
-
const batchResult = await
|
|
4765
|
+
const batchResult = await runMindstudioCli(["batch"], {
|
|
4612
4766
|
jsonLogs: true,
|
|
4613
4767
|
timeout: 2e5,
|
|
4614
4768
|
onLog,
|
|
4615
|
-
stdin: JSON.stringify(steps)
|
|
4769
|
+
stdin: JSON.stringify(steps),
|
|
4770
|
+
caller: "designExpert"
|
|
4616
4771
|
});
|
|
4617
4772
|
try {
|
|
4618
4773
|
const parsed = JSON.parse(batchResult);
|
|
@@ -4629,17 +4784,14 @@ async function generateImageAssets(opts) {
|
|
|
4629
4784
|
if (url.startsWith("Error")) {
|
|
4630
4785
|
return url;
|
|
4631
4786
|
}
|
|
4632
|
-
const result = await
|
|
4633
|
-
"
|
|
4634
|
-
|
|
4635
|
-
"
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
"
|
|
4639
|
-
|
|
4640
|
-
"--no-meta"
|
|
4641
|
-
],
|
|
4642
|
-
{ timeout: 2e5, onLog }
|
|
4787
|
+
const result = await runMindstudioCli(
|
|
4788
|
+
["remove-background-from-image", "--image-url", url],
|
|
4789
|
+
{
|
|
4790
|
+
outputKey: "imageUrl",
|
|
4791
|
+
timeout: 2e5,
|
|
4792
|
+
onLog,
|
|
4793
|
+
caller: "designExpert"
|
|
4794
|
+
}
|
|
4643
4795
|
);
|
|
4644
4796
|
return result.startsWith("Error") ? url : result;
|
|
4645
4797
|
})
|
|
@@ -4675,7 +4827,7 @@ var ANALYZE_PROMPT;
|
|
|
4675
4827
|
var init_imageGenerator = __esm({
|
|
4676
4828
|
"src/subagents/designExpert/tools/images/imageGenerator.ts"() {
|
|
4677
4829
|
"use strict";
|
|
4678
|
-
|
|
4830
|
+
init_runMindstudioCli();
|
|
4679
4831
|
init_analyzeImage();
|
|
4680
4832
|
init_enhancePrompt();
|
|
4681
4833
|
ANALYZE_PROMPT = 'You are reviewing this image for a visual designer sourcing assets for a project. Describe: what the image depicts, the mood and color palette, how the lighting and composition work, any text present in the image, whether there are any issues (artifacts, distortions), and how it could be used in a layout for an app or website. Be concise and practical. Respond only with your analysis as Markdown (starting with the title "Asset Review") and absolutely no other text. Do not use emojis - use unicode if you need symbols.';
|
|
@@ -4835,12 +4987,12 @@ var init_tools3 = __esm({
|
|
|
4835
4987
|
});
|
|
4836
4988
|
|
|
4837
4989
|
// src/subagents/common/context.ts
|
|
4838
|
-
import
|
|
4990
|
+
import fs16 from "fs";
|
|
4839
4991
|
import path7 from "path";
|
|
4840
4992
|
function walkMdFiles2(dir, skip) {
|
|
4841
4993
|
const files = [];
|
|
4842
4994
|
try {
|
|
4843
|
-
for (const entry of
|
|
4995
|
+
for (const entry of fs16.readdirSync(dir, { withFileTypes: true })) {
|
|
4844
4996
|
const full = path7.join(dir, entry.name);
|
|
4845
4997
|
if (entry.isDirectory()) {
|
|
4846
4998
|
if (!skip?.has(entry.name)) {
|
|
@@ -4856,7 +5008,7 @@ function walkMdFiles2(dir, skip) {
|
|
|
4856
5008
|
}
|
|
4857
5009
|
function parseFrontmatter2(filePath) {
|
|
4858
5010
|
try {
|
|
4859
|
-
const content =
|
|
5011
|
+
const content = fs16.readFileSync(filePath, "utf-8");
|
|
4860
5012
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
4861
5013
|
if (!match) {
|
|
4862
5014
|
return {};
|
|
@@ -4902,7 +5054,7 @@ function loadRoadmapIndex() {
|
|
|
4902
5054
|
const parts = [];
|
|
4903
5055
|
try {
|
|
4904
5056
|
const indexJson = JSON.parse(
|
|
4905
|
-
|
|
5057
|
+
fs16.readFileSync("src/roadmap/index.json", "utf-8")
|
|
4906
5058
|
);
|
|
4907
5059
|
if (indexJson.lanes?.length > 0) {
|
|
4908
5060
|
const laneLines = indexJson.lanes.map(
|
|
@@ -5010,7 +5162,7 @@ var init_context = __esm({
|
|
|
5010
5162
|
});
|
|
5011
5163
|
|
|
5012
5164
|
// src/subagents/designExpert/data/sampleCache.ts
|
|
5013
|
-
import
|
|
5165
|
+
import fs17 from "fs";
|
|
5014
5166
|
function generateIndices(poolSize, sampleSize) {
|
|
5015
5167
|
const n = Math.min(sampleSize, poolSize);
|
|
5016
5168
|
const indices = Array.from({ length: poolSize }, (_, i) => i);
|
|
@@ -5022,14 +5174,14 @@ function generateIndices(poolSize, sampleSize) {
|
|
|
5022
5174
|
}
|
|
5023
5175
|
function load() {
|
|
5024
5176
|
try {
|
|
5025
|
-
return JSON.parse(
|
|
5177
|
+
return JSON.parse(fs17.readFileSync(SAMPLE_FILE, "utf-8"));
|
|
5026
5178
|
} catch {
|
|
5027
5179
|
return null;
|
|
5028
5180
|
}
|
|
5029
5181
|
}
|
|
5030
5182
|
function save(indices) {
|
|
5031
5183
|
try {
|
|
5032
|
-
|
|
5184
|
+
fs17.writeFileSync(SAMPLE_FILE, JSON.stringify(indices));
|
|
5033
5185
|
} catch {
|
|
5034
5186
|
}
|
|
5035
5187
|
}
|
|
@@ -5426,7 +5578,7 @@ var init_tools4 = __esm({
|
|
|
5426
5578
|
});
|
|
5427
5579
|
|
|
5428
5580
|
// src/subagents/productVision/executor.ts
|
|
5429
|
-
import
|
|
5581
|
+
import fs18 from "fs";
|
|
5430
5582
|
import path8 from "path";
|
|
5431
5583
|
function resolve(filePath) {
|
|
5432
5584
|
return path8.join(ROADMAP_DIR, filePath);
|
|
@@ -5436,13 +5588,13 @@ async function executeVisionTool(name, input, context) {
|
|
|
5436
5588
|
case "writeFile": {
|
|
5437
5589
|
const filePath = resolve(input.path);
|
|
5438
5590
|
try {
|
|
5439
|
-
|
|
5591
|
+
fs18.mkdirSync(ROADMAP_DIR, { recursive: true });
|
|
5440
5592
|
let oldContent = null;
|
|
5441
5593
|
try {
|
|
5442
|
-
oldContent =
|
|
5594
|
+
oldContent = fs18.readFileSync(filePath, "utf-8");
|
|
5443
5595
|
} catch {
|
|
5444
5596
|
}
|
|
5445
|
-
|
|
5597
|
+
fs18.writeFileSync(filePath, input.content, "utf-8");
|
|
5446
5598
|
const lineCount = input.content.split("\n").length;
|
|
5447
5599
|
const label = oldContent !== null ? "Wrote" : "Created";
|
|
5448
5600
|
return `${label} ${filePath} (${lineCount} lines)
|
|
@@ -5454,11 +5606,11 @@ ${unifiedDiff(filePath, oldContent ?? "", input.content)}`;
|
|
|
5454
5606
|
case "deleteFile": {
|
|
5455
5607
|
const filePath = resolve(input.path);
|
|
5456
5608
|
try {
|
|
5457
|
-
if (!
|
|
5609
|
+
if (!fs18.existsSync(filePath)) {
|
|
5458
5610
|
return `Error: ${filePath} does not exist`;
|
|
5459
5611
|
}
|
|
5460
|
-
const oldContent =
|
|
5461
|
-
|
|
5612
|
+
const oldContent = fs18.readFileSync(filePath, "utf-8");
|
|
5613
|
+
fs18.unlinkSync(filePath);
|
|
5462
5614
|
return `Deleted ${filePath}
|
|
5463
5615
|
${unifiedDiff(filePath, oldContent, "")}`;
|
|
5464
5616
|
} catch (err) {
|
|
@@ -5471,8 +5623,8 @@ ${unifiedDiff(filePath, oldContent, "")}`;
|
|
|
5471
5623
|
}
|
|
5472
5624
|
const filePath = resolve("pitch.html");
|
|
5473
5625
|
try {
|
|
5474
|
-
|
|
5475
|
-
const existing =
|
|
5626
|
+
fs18.mkdirSync(ROADMAP_DIR, { recursive: true });
|
|
5627
|
+
const existing = fs18.existsSync(filePath) ? fs18.readFileSync(filePath, "utf-8").trim() : "";
|
|
5476
5628
|
const currentDeck = existing || PITCH_DECK_SHELL;
|
|
5477
5629
|
const task = `
|
|
5478
5630
|
<pitch_content>${input.task}</pitch_content>
|
|
@@ -5497,7 +5649,7 @@ Respond only with the complete HTML file and absolutely no other text. Your resp
|
|
|
5497
5649
|
/```(?:html|wireframe)\n([\s\S]*?)```/
|
|
5498
5650
|
);
|
|
5499
5651
|
const html = htmlMatch ? htmlMatch[1].trim() : result;
|
|
5500
|
-
|
|
5652
|
+
fs18.writeFileSync(filePath, html, "utf-8");
|
|
5501
5653
|
return `Pitch deck written successfully.`;
|
|
5502
5654
|
} catch (err) {
|
|
5503
5655
|
return `Error generating pitch deck: ${err.message}`;
|
|
@@ -5746,7 +5898,7 @@ var scrapeWebUrlTool;
|
|
|
5746
5898
|
var init_scrapeWebUrl2 = __esm({
|
|
5747
5899
|
"src/tools/common/scrapeWebUrl.ts"() {
|
|
5748
5900
|
"use strict";
|
|
5749
|
-
|
|
5901
|
+
init_runMindstudioCli();
|
|
5750
5902
|
scrapeWebUrlTool = {
|
|
5751
5903
|
clearable: false,
|
|
5752
5904
|
definition: {
|
|
@@ -5774,15 +5926,13 @@ var init_scrapeWebUrl2 = __esm({
|
|
|
5774
5926
|
if (screenshot) {
|
|
5775
5927
|
pageOptions.screenshot = true;
|
|
5776
5928
|
}
|
|
5777
|
-
return
|
|
5778
|
-
"mindstudio",
|
|
5929
|
+
return runMindstudioCli(
|
|
5779
5930
|
[
|
|
5780
5931
|
"scrape-url",
|
|
5781
5932
|
"--url",
|
|
5782
5933
|
url,
|
|
5783
5934
|
"--page-options",
|
|
5784
|
-
JSON.stringify(pageOptions)
|
|
5785
|
-
"--no-meta"
|
|
5935
|
+
JSON.stringify(pageOptions)
|
|
5786
5936
|
],
|
|
5787
5937
|
{ onLog: context?.onLog }
|
|
5788
5938
|
);
|
|
@@ -5892,10 +6042,11 @@ var init_tools6 = __esm({
|
|
|
5892
6042
|
});
|
|
5893
6043
|
|
|
5894
6044
|
// src/session.ts
|
|
5895
|
-
import
|
|
6045
|
+
import fs19 from "fs";
|
|
6046
|
+
import path9 from "path";
|
|
5896
6047
|
function loadSession(state) {
|
|
5897
6048
|
try {
|
|
5898
|
-
const raw =
|
|
6049
|
+
const raw = fs19.readFileSync(SESSION_FILE, "utf-8");
|
|
5899
6050
|
const data = JSON.parse(raw);
|
|
5900
6051
|
if (Array.isArray(data.messages) && data.messages.length > 0) {
|
|
5901
6052
|
state.messages = sanitizeMessages(data.messages);
|
|
@@ -5944,7 +6095,7 @@ function sanitizeMessages(messages) {
|
|
|
5944
6095
|
}
|
|
5945
6096
|
function saveSession(state) {
|
|
5946
6097
|
try {
|
|
5947
|
-
|
|
6098
|
+
fs19.writeFileSync(
|
|
5948
6099
|
SESSION_FILE,
|
|
5949
6100
|
JSON.stringify({ messages: state.messages }, null, 2),
|
|
5950
6101
|
"utf-8"
|
|
@@ -5957,17 +6108,31 @@ function saveSession(state) {
|
|
|
5957
6108
|
function clearSession(state) {
|
|
5958
6109
|
state.messages = [];
|
|
5959
6110
|
try {
|
|
5960
|
-
|
|
5961
|
-
|
|
6111
|
+
if (fs19.existsSync(SESSION_FILE)) {
|
|
6112
|
+
fs19.mkdirSync(ARCHIVE_DIR, { recursive: true });
|
|
6113
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
6114
|
+
const dest = path9.join(ARCHIVE_DIR, `cleared-${ts}.json`);
|
|
6115
|
+
fs19.renameSync(SESSION_FILE, dest);
|
|
6116
|
+
log7.info("Session archived on clear", { dest });
|
|
6117
|
+
}
|
|
6118
|
+
} catch (err) {
|
|
6119
|
+
log7.warn("Session archive on clear failed, deleting instead", {
|
|
6120
|
+
error: err.message
|
|
6121
|
+
});
|
|
6122
|
+
try {
|
|
6123
|
+
fs19.unlinkSync(SESSION_FILE);
|
|
6124
|
+
} catch {
|
|
6125
|
+
}
|
|
5962
6126
|
}
|
|
5963
6127
|
}
|
|
5964
|
-
var log7, SESSION_FILE;
|
|
6128
|
+
var log7, SESSION_FILE, ARCHIVE_DIR;
|
|
5965
6129
|
var init_session = __esm({
|
|
5966
6130
|
"src/session.ts"() {
|
|
5967
6131
|
"use strict";
|
|
5968
6132
|
init_logger();
|
|
5969
6133
|
log7 = createLogger("session");
|
|
5970
6134
|
SESSION_FILE = ".remy-session.json";
|
|
6135
|
+
ARCHIVE_DIR = ".logs/sessions";
|
|
5971
6136
|
}
|
|
5972
6137
|
});
|
|
5973
6138
|
|
|
@@ -6177,8 +6342,8 @@ var init_errors = __esm({
|
|
|
6177
6342
|
});
|
|
6178
6343
|
|
|
6179
6344
|
// src/brandExtraction/index.ts
|
|
6180
|
-
import
|
|
6181
|
-
import
|
|
6345
|
+
import fs20 from "fs";
|
|
6346
|
+
import path10 from "path";
|
|
6182
6347
|
import { createHash } from "crypto";
|
|
6183
6348
|
async function runExtraction(apiConfig) {
|
|
6184
6349
|
const inputHash = computeInputHash();
|
|
@@ -6200,7 +6365,7 @@ async function runExtraction(apiConfig) {
|
|
|
6200
6365
|
function computeInputHash() {
|
|
6201
6366
|
const entries = [];
|
|
6202
6367
|
for (const filePath of walkMdFiles3("src")) {
|
|
6203
|
-
if (filePath ===
|
|
6368
|
+
if (filePath === path10.join("src", "app.md")) {
|
|
6204
6369
|
entries.push({ path: filePath, content: readSafe(filePath) });
|
|
6205
6370
|
continue;
|
|
6206
6371
|
}
|
|
@@ -6222,7 +6387,7 @@ function sha256(input) {
|
|
|
6222
6387
|
}
|
|
6223
6388
|
function readSafe(filePath) {
|
|
6224
6389
|
try {
|
|
6225
|
-
return
|
|
6390
|
+
return fs20.readFileSync(filePath, "utf-8");
|
|
6226
6391
|
} catch {
|
|
6227
6392
|
return "";
|
|
6228
6393
|
}
|
|
@@ -6230,9 +6395,9 @@ function readSafe(filePath) {
|
|
|
6230
6395
|
function walkMdFiles3(dir) {
|
|
6231
6396
|
const results = [];
|
|
6232
6397
|
try {
|
|
6233
|
-
const entries =
|
|
6398
|
+
const entries = fs20.readdirSync(dir, { withFileTypes: true });
|
|
6234
6399
|
for (const entry of entries) {
|
|
6235
|
-
const full =
|
|
6400
|
+
const full = path10.join(dir, entry.name);
|
|
6236
6401
|
if (entry.isDirectory()) {
|
|
6237
6402
|
results.push(...walkMdFiles3(full));
|
|
6238
6403
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -6245,7 +6410,7 @@ function walkMdFiles3(dir) {
|
|
|
6245
6410
|
}
|
|
6246
6411
|
function parseFrontmatter3(filePath) {
|
|
6247
6412
|
try {
|
|
6248
|
-
const content =
|
|
6413
|
+
const content = fs20.readFileSync(filePath, "utf-8");
|
|
6249
6414
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
6250
6415
|
if (!match) {
|
|
6251
6416
|
return { type: "" };
|
|
@@ -6264,6 +6429,7 @@ async function extractBrand(apiConfig) {
|
|
|
6264
6429
|
return { version: 1 };
|
|
6265
6430
|
}
|
|
6266
6431
|
let responseText = "";
|
|
6432
|
+
const iterStart = Date.now();
|
|
6267
6433
|
try {
|
|
6268
6434
|
for await (const event of streamChat({
|
|
6269
6435
|
...apiConfig,
|
|
@@ -6274,6 +6440,20 @@ async function extractBrand(apiConfig) {
|
|
|
6274
6440
|
})) {
|
|
6275
6441
|
if (event.type === "text") {
|
|
6276
6442
|
responseText += event.text;
|
|
6443
|
+
} else if (event.type === "done") {
|
|
6444
|
+
recordUsage({
|
|
6445
|
+
ts: Date.now(),
|
|
6446
|
+
agentName: "brandExtractor",
|
|
6447
|
+
modelId: event.modelId,
|
|
6448
|
+
inputTokens: event.usage.inputTokens,
|
|
6449
|
+
outputTokens: event.usage.outputTokens,
|
|
6450
|
+
cacheCreationTokens: event.usage.cacheCreationTokens,
|
|
6451
|
+
cacheReadTokens: event.usage.cacheReadTokens,
|
|
6452
|
+
cost: nanoToDollars(event.cost),
|
|
6453
|
+
billingEvents: event.billingEvents,
|
|
6454
|
+
durationMs: Date.now() - iterStart,
|
|
6455
|
+
toolNames: []
|
|
6456
|
+
});
|
|
6277
6457
|
} else if (event.type === "error") {
|
|
6278
6458
|
log8.error("Brand extraction stream error", { error: event.error });
|
|
6279
6459
|
return null;
|
|
@@ -6408,14 +6588,14 @@ function pickFont(raw) {
|
|
|
6408
6588
|
}
|
|
6409
6589
|
function persistBrand(brand, inputHash) {
|
|
6410
6590
|
const tmp = `${BRAND_FILE}.tmp`;
|
|
6411
|
-
|
|
6412
|
-
|
|
6591
|
+
fs20.writeFileSync(tmp, JSON.stringify(brand, null, 2), "utf-8");
|
|
6592
|
+
fs20.renameSync(tmp, BRAND_FILE);
|
|
6413
6593
|
const cache = { inputHash, generatedAt: Date.now() };
|
|
6414
|
-
|
|
6594
|
+
fs20.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2), "utf-8");
|
|
6415
6595
|
}
|
|
6416
6596
|
function readCache() {
|
|
6417
6597
|
try {
|
|
6418
|
-
const raw =
|
|
6598
|
+
const raw = fs20.readFileSync(CACHE_FILE, "utf-8");
|
|
6419
6599
|
const parsed = JSON.parse(raw);
|
|
6420
6600
|
if (parsed && typeof parsed.inputHash === "string" && typeof parsed.generatedAt === "number") {
|
|
6421
6601
|
return parsed;
|
|
@@ -6432,6 +6612,7 @@ var init_brandExtraction = __esm({
|
|
|
6432
6612
|
init_api();
|
|
6433
6613
|
init_assets();
|
|
6434
6614
|
init_logger();
|
|
6615
|
+
init_usageLedger();
|
|
6435
6616
|
log8 = createLogger("brandExtraction");
|
|
6436
6617
|
EXTRACT_PROMPT = readAsset("brandExtraction", "extract.md");
|
|
6437
6618
|
BRAND_FILE = ".remy-brand.json";
|
|
@@ -6563,9 +6744,11 @@ async function runTurn(params) {
|
|
|
6563
6744
|
saveSession(state);
|
|
6564
6745
|
return;
|
|
6565
6746
|
}
|
|
6747
|
+
const iterStart = Date.now();
|
|
6566
6748
|
const contentBlocks = [];
|
|
6567
6749
|
const thinkingBlockStartTimes = [];
|
|
6568
6750
|
let thinkingCompleteCount = 0;
|
|
6751
|
+
let lastThinkingRelatedStartedAt;
|
|
6569
6752
|
let textBlockOpen = false;
|
|
6570
6753
|
const toolInputAccumulators = /* @__PURE__ */ new Map();
|
|
6571
6754
|
let stopReason = "end_turn";
|
|
@@ -6666,7 +6849,7 @@ async function runTurn(params) {
|
|
|
6666
6849
|
onRetry: (attempt) => {
|
|
6667
6850
|
onEvent({
|
|
6668
6851
|
type: "status",
|
|
6669
|
-
message: `Lost connection, retrying (attempt ${attempt + 2} of 3)
|
|
6852
|
+
message: `Lost connection, retrying (attempt ${attempt + 2} of 3)`
|
|
6670
6853
|
});
|
|
6671
6854
|
}
|
|
6672
6855
|
}
|
|
@@ -6697,16 +6880,30 @@ async function runTurn(params) {
|
|
|
6697
6880
|
}
|
|
6698
6881
|
onEvent({ type: "thinking", text: event.text });
|
|
6699
6882
|
break;
|
|
6700
|
-
case "thinking_complete":
|
|
6883
|
+
case "thinking_complete": {
|
|
6884
|
+
const startedAt = thinkingBlockStartTimes[thinkingCompleteCount] ?? event.ts;
|
|
6701
6885
|
contentBlocks.push({
|
|
6702
6886
|
type: "thinking",
|
|
6703
6887
|
thinking: event.thinking,
|
|
6704
6888
|
signature: event.signature,
|
|
6705
|
-
startedAt
|
|
6889
|
+
startedAt,
|
|
6706
6890
|
completedAt: event.ts
|
|
6707
6891
|
});
|
|
6708
6892
|
thinkingCompleteCount++;
|
|
6893
|
+
lastThinkingRelatedStartedAt = startedAt;
|
|
6894
|
+
break;
|
|
6895
|
+
}
|
|
6896
|
+
case "redacted_thinking_complete": {
|
|
6897
|
+
const startedAt = lastThinkingRelatedStartedAt !== void 0 ? lastThinkingRelatedStartedAt + 1 : event.ts;
|
|
6898
|
+
contentBlocks.push({
|
|
6899
|
+
type: "redacted_thinking",
|
|
6900
|
+
data: event.data,
|
|
6901
|
+
startedAt,
|
|
6902
|
+
completedAt: event.ts
|
|
6903
|
+
});
|
|
6904
|
+
lastThinkingRelatedStartedAt = startedAt;
|
|
6709
6905
|
break;
|
|
6906
|
+
}
|
|
6710
6907
|
case "tool_input_delta": {
|
|
6711
6908
|
const acc = getOrCreateAccumulator2(event.id, event.name);
|
|
6712
6909
|
acc.json += event.delta;
|
|
@@ -6760,6 +6957,22 @@ async function runTurn(params) {
|
|
|
6760
6957
|
turnOutputTokens += event.usage.outputTokens;
|
|
6761
6958
|
turnCacheCreation += lastCallCacheCreation;
|
|
6762
6959
|
turnCacheRead += lastCallCacheRead;
|
|
6960
|
+
recordUsage({
|
|
6961
|
+
ts: Date.now(),
|
|
6962
|
+
requestId,
|
|
6963
|
+
agentName: "parent",
|
|
6964
|
+
modelId: event.modelId,
|
|
6965
|
+
inputTokens: event.usage.inputTokens,
|
|
6966
|
+
outputTokens: event.usage.outputTokens,
|
|
6967
|
+
cacheCreationTokens: event.usage.cacheCreationTokens,
|
|
6968
|
+
cacheReadTokens: event.usage.cacheReadTokens,
|
|
6969
|
+
cost: nanoToDollars(event.cost),
|
|
6970
|
+
billingEvents: event.billingEvents,
|
|
6971
|
+
durationMs: Date.now() - iterStart,
|
|
6972
|
+
toolNames: contentBlocks.filter(
|
|
6973
|
+
(b) => b.type === "tool"
|
|
6974
|
+
).map((b) => b.name)
|
|
6975
|
+
});
|
|
6763
6976
|
break;
|
|
6764
6977
|
case "error":
|
|
6765
6978
|
onEvent({ type: "error", error: friendlyError(event.error) });
|
|
@@ -7006,6 +7219,7 @@ var init_agent = __esm({
|
|
|
7006
7219
|
init_tools6();
|
|
7007
7220
|
init_session();
|
|
7008
7221
|
init_logger();
|
|
7222
|
+
init_usageLedger();
|
|
7009
7223
|
init_parsePartialJson();
|
|
7010
7224
|
init_statusWatcher();
|
|
7011
7225
|
init_errors();
|
|
@@ -7035,12 +7249,12 @@ var init_agent = __esm({
|
|
|
7035
7249
|
});
|
|
7036
7250
|
|
|
7037
7251
|
// src/config.ts
|
|
7038
|
-
import
|
|
7039
|
-
import
|
|
7252
|
+
import fs21 from "fs";
|
|
7253
|
+
import path11 from "path";
|
|
7040
7254
|
import os from "os";
|
|
7041
7255
|
function loadConfigFile() {
|
|
7042
7256
|
try {
|
|
7043
|
-
const raw =
|
|
7257
|
+
const raw = fs21.readFileSync(CONFIG_PATH, "utf-8");
|
|
7044
7258
|
log11.debug("Loaded config file", { path: CONFIG_PATH });
|
|
7045
7259
|
return JSON.parse(raw);
|
|
7046
7260
|
} catch (err) {
|
|
@@ -7057,6 +7271,7 @@ function resolveConfig(flags2) {
|
|
|
7057
7271
|
const env = file.environments?.[activeEnv];
|
|
7058
7272
|
const apiKey = flags2?.apiKey || process.env.MINDSTUDIO_API_KEY || env?.apiKey || "";
|
|
7059
7273
|
const baseUrl2 = flags2?.baseUrl || process.env.MINDSTUDIO_BASE_URL || env?.apiBaseUrl || DEFAULT_BASE_URL;
|
|
7274
|
+
const appId = process.env.MINDSTUDIO_APP_ID || void 0;
|
|
7060
7275
|
if (!apiKey) {
|
|
7061
7276
|
log11.error("No API key found");
|
|
7062
7277
|
throw new Error(
|
|
@@ -7067,9 +7282,10 @@ function resolveConfig(flags2) {
|
|
|
7067
7282
|
log11.info("Config resolved", {
|
|
7068
7283
|
baseUrl: baseUrl2,
|
|
7069
7284
|
keySource,
|
|
7070
|
-
environment: activeEnv
|
|
7285
|
+
environment: activeEnv,
|
|
7286
|
+
appId
|
|
7071
7287
|
});
|
|
7072
|
-
return { apiKey, baseUrl: baseUrl2 };
|
|
7288
|
+
return { apiKey, baseUrl: baseUrl2, appId };
|
|
7073
7289
|
}
|
|
7074
7290
|
var log11, CONFIG_PATH, DEFAULT_BASE_URL;
|
|
7075
7291
|
var init_config = __esm({
|
|
@@ -7077,7 +7293,7 @@ var init_config = __esm({
|
|
|
7077
7293
|
"use strict";
|
|
7078
7294
|
init_logger();
|
|
7079
7295
|
log11 = createLogger("config");
|
|
7080
|
-
CONFIG_PATH =
|
|
7296
|
+
CONFIG_PATH = path11.join(
|
|
7081
7297
|
os.homedir(),
|
|
7082
7298
|
".mindstudio-local-tunnel",
|
|
7083
7299
|
"config.json"
|
|
@@ -8323,8 +8539,8 @@ var init_headless = __esm({
|
|
|
8323
8539
|
// src/index.tsx
|
|
8324
8540
|
import { render } from "ink";
|
|
8325
8541
|
import os2 from "os";
|
|
8326
|
-
import
|
|
8327
|
-
import
|
|
8542
|
+
import fs22 from "fs";
|
|
8543
|
+
import path12 from "path";
|
|
8328
8544
|
|
|
8329
8545
|
// src/tui/App.tsx
|
|
8330
8546
|
import { useState as useState2, useCallback, useRef } from "react";
|
|
@@ -8642,8 +8858,8 @@ for (let i = 0; i < args.length; i++) {
|
|
|
8642
8858
|
var startupLog = createLogger("startup");
|
|
8643
8859
|
function printDebugInfo(config) {
|
|
8644
8860
|
const pkg = JSON.parse(
|
|
8645
|
-
|
|
8646
|
-
|
|
8861
|
+
fs22.readFileSync(
|
|
8862
|
+
path12.join(import.meta.dirname, "..", "package.json"),
|
|
8647
8863
|
"utf-8"
|
|
8648
8864
|
)
|
|
8649
8865
|
);
|