@isarai/maestro 0.1.0 → 0.1.1
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/server.js +176 -159
- package/dist/server.js.map +4 -4
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -461,7 +461,6 @@ function findCoveringSelfMount(requestedPath) {
|
|
|
461
461
|
return best;
|
|
462
462
|
}
|
|
463
463
|
function getSharedAgentPaths(home) {
|
|
464
|
-
const maestroDir = path.join(home, ".maestro");
|
|
465
464
|
const codexDir = path.join(home, ".codex");
|
|
466
465
|
const claudeDir = path.join(home, ".claude");
|
|
467
466
|
const claudeProjectsDir = path.join(claudeDir, "projects");
|
|
@@ -469,11 +468,10 @@ function getSharedAgentPaths(home) {
|
|
|
469
468
|
const gitconfig = path.join(home, ".gitconfig");
|
|
470
469
|
const ghConfigDir = path.join(home, ".config", "gh");
|
|
471
470
|
return {
|
|
472
|
-
//
|
|
473
|
-
//
|
|
474
|
-
//
|
|
475
|
-
|
|
476
|
-
readwrite: [maestroDir, codexDir, claudeDir, claudeProjectsDir, claudeJson, ghConfigDir].filter(fs.existsSync),
|
|
471
|
+
// Keep only CLI/runtime config writable here. Maestro's own server state
|
|
472
|
+
// stays outside the generic sandbox mount set and terminal sandboxes use
|
|
473
|
+
// a dedicated isolated HOME under ~/.maestro/sandboxes/terminals/<id>.
|
|
474
|
+
readwrite: [codexDir, claudeDir, claudeProjectsDir, claudeJson, ghConfigDir].filter(fs.existsSync),
|
|
477
475
|
readonly: [gitconfig].filter(fs.existsSync)
|
|
478
476
|
};
|
|
479
477
|
}
|
|
@@ -1191,27 +1189,76 @@ var init_terminal_replica = __esm({
|
|
|
1191
1189
|
}
|
|
1192
1190
|
});
|
|
1193
1191
|
|
|
1194
|
-
// ../server/src/
|
|
1192
|
+
// ../server/src/state/files.ts
|
|
1195
1193
|
import * as fs4 from "fs";
|
|
1196
1194
|
import * as os4 from "os";
|
|
1197
1195
|
import * as path4 from "path";
|
|
1196
|
+
function ensureDataDir() {
|
|
1197
|
+
fs4.mkdirSync(MAESTRO_DATA_DIR, { recursive: true });
|
|
1198
|
+
return MAESTRO_DATA_DIR;
|
|
1199
|
+
}
|
|
1200
|
+
function ensureDir(dirPath) {
|
|
1201
|
+
fs4.mkdirSync(dirPath, { recursive: true });
|
|
1202
|
+
return dirPath;
|
|
1203
|
+
}
|
|
1204
|
+
function readJsonFile(filePath, fallback) {
|
|
1205
|
+
try {
|
|
1206
|
+
if (!fs4.existsSync(filePath)) {
|
|
1207
|
+
return fallback;
|
|
1208
|
+
}
|
|
1209
|
+
const raw = fs4.readFileSync(filePath, "utf-8");
|
|
1210
|
+
return JSON.parse(raw);
|
|
1211
|
+
} catch {
|
|
1212
|
+
return fallback;
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
function writeJsonFile(filePath, value, options) {
|
|
1216
|
+
ensureDir(path4.dirname(filePath));
|
|
1217
|
+
const tempPath = `${filePath}.tmp`;
|
|
1218
|
+
fs4.writeFileSync(tempPath, `${JSON.stringify(value, null, 2)}
|
|
1219
|
+
`, {
|
|
1220
|
+
mode: options?.mode
|
|
1221
|
+
});
|
|
1222
|
+
fs4.renameSync(tempPath, filePath);
|
|
1223
|
+
if (options?.mode != null) {
|
|
1224
|
+
fs4.chmodSync(filePath, options.mode);
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
function nowIso() {
|
|
1228
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
1229
|
+
}
|
|
1230
|
+
var MAESTRO_DATA_DIR, MAESTRO_PROJECTS_DIR, MAESTRO_SANDBOXES_DIR, MAESTRO_SANDBOX_TERMINALS_DIR, MAESTRO_SANDBOX_WORKTREES_DIR;
|
|
1231
|
+
var init_files = __esm({
|
|
1232
|
+
"../server/src/state/files.ts"() {
|
|
1233
|
+
"use strict";
|
|
1234
|
+
MAESTRO_DATA_DIR = path4.join(os4.homedir(), ".maestro");
|
|
1235
|
+
MAESTRO_PROJECTS_DIR = path4.join(MAESTRO_DATA_DIR, "projects");
|
|
1236
|
+
MAESTRO_SANDBOXES_DIR = path4.join(MAESTRO_DATA_DIR, "sandboxes");
|
|
1237
|
+
MAESTRO_SANDBOX_TERMINALS_DIR = path4.join(MAESTRO_SANDBOXES_DIR, "terminals");
|
|
1238
|
+
MAESTRO_SANDBOX_WORKTREES_DIR = path4.join(MAESTRO_SANDBOXES_DIR, "worktrees");
|
|
1239
|
+
}
|
|
1240
|
+
});
|
|
1241
|
+
|
|
1242
|
+
// ../server/src/agents/worktree.ts
|
|
1243
|
+
import * as fs5 from "fs";
|
|
1244
|
+
import * as path5 from "path";
|
|
1198
1245
|
import { execSync as execSync2 } from "child_process";
|
|
1199
1246
|
function createTerminalWorktree(projectPath, terminalId, startPoint = "HEAD") {
|
|
1200
|
-
const worktreeDir =
|
|
1247
|
+
const worktreeDir = path5.join(WORKTREE_BASE, terminalId);
|
|
1201
1248
|
const branchName = `agent/${terminalId}`;
|
|
1202
|
-
|
|
1249
|
+
fs5.mkdirSync(WORKTREE_BASE, { recursive: true });
|
|
1203
1250
|
try {
|
|
1204
1251
|
execSync2("git worktree prune", { cwd: projectPath, stdio: "ignore" });
|
|
1205
1252
|
} catch {
|
|
1206
1253
|
}
|
|
1207
|
-
if (
|
|
1254
|
+
if (fs5.existsSync(worktreeDir)) {
|
|
1208
1255
|
try {
|
|
1209
1256
|
execSync2(`git worktree remove --force ${JSON.stringify(worktreeDir)}`, {
|
|
1210
1257
|
cwd: projectPath,
|
|
1211
1258
|
stdio: "ignore"
|
|
1212
1259
|
});
|
|
1213
1260
|
} catch {
|
|
1214
|
-
|
|
1261
|
+
fs5.rmSync(worktreeDir, { recursive: true, force: true });
|
|
1215
1262
|
}
|
|
1216
1263
|
}
|
|
1217
1264
|
try {
|
|
@@ -1231,16 +1278,16 @@ function createTerminalWorktree(projectPath, terminalId, startPoint = "HEAD") {
|
|
|
1231
1278
|
return worktreeDir;
|
|
1232
1279
|
}
|
|
1233
1280
|
function removeTerminalWorktree(projectPath, terminalId) {
|
|
1234
|
-
const worktreeDir =
|
|
1281
|
+
const worktreeDir = path5.join(WORKTREE_BASE, terminalId);
|
|
1235
1282
|
const branchName = `agent/${terminalId}`;
|
|
1236
|
-
if (
|
|
1283
|
+
if (fs5.existsSync(worktreeDir)) {
|
|
1237
1284
|
try {
|
|
1238
1285
|
execSync2(
|
|
1239
1286
|
`git worktree remove --force ${JSON.stringify(worktreeDir)}`,
|
|
1240
1287
|
{ cwd: projectPath, stdio: "ignore" }
|
|
1241
1288
|
);
|
|
1242
1289
|
} catch {
|
|
1243
|
-
|
|
1290
|
+
fs5.rmSync(worktreeDir, { recursive: true, force: true });
|
|
1244
1291
|
}
|
|
1245
1292
|
}
|
|
1246
1293
|
try {
|
|
@@ -1271,82 +1318,82 @@ var DEFAULT_WORKTREE_BASE, WORKTREE_BASE;
|
|
|
1271
1318
|
var init_worktree = __esm({
|
|
1272
1319
|
"../server/src/agents/worktree.ts"() {
|
|
1273
1320
|
"use strict";
|
|
1274
|
-
|
|
1321
|
+
init_files();
|
|
1322
|
+
DEFAULT_WORKTREE_BASE = MAESTRO_SANDBOX_WORKTREES_DIR;
|
|
1275
1323
|
WORKTREE_BASE = process.env.MAESTRO_WORKTREE_BASE?.trim() || DEFAULT_WORKTREE_BASE;
|
|
1276
1324
|
}
|
|
1277
1325
|
});
|
|
1278
1326
|
|
|
1279
1327
|
// ../server/src/agents/terminal-isolation.ts
|
|
1280
|
-
import * as
|
|
1328
|
+
import * as fs6 from "fs";
|
|
1329
|
+
import * as path6 from "path";
|
|
1281
1330
|
import * as os5 from "os";
|
|
1282
|
-
import * as path5 from "path";
|
|
1283
1331
|
function getGlobalHome() {
|
|
1284
1332
|
return os5.homedir();
|
|
1285
1333
|
}
|
|
1286
1334
|
function getTerminalIsolationPaths(terminalId) {
|
|
1287
|
-
const rootDir =
|
|
1335
|
+
const rootDir = path6.join(TERMINAL_STATE_BASE, terminalId);
|
|
1288
1336
|
return {
|
|
1289
1337
|
rootDir,
|
|
1290
|
-
homeDir:
|
|
1338
|
+
homeDir: path6.join(rootDir, "home")
|
|
1291
1339
|
};
|
|
1292
1340
|
}
|
|
1293
1341
|
function copyPathIfPresent(source, target) {
|
|
1294
|
-
if (!
|
|
1342
|
+
if (!fs6.existsSync(source) || fs6.existsSync(target)) {
|
|
1295
1343
|
return;
|
|
1296
1344
|
}
|
|
1297
|
-
const stat =
|
|
1298
|
-
|
|
1345
|
+
const stat = fs6.statSync(source);
|
|
1346
|
+
fs6.mkdirSync(path6.dirname(target), { recursive: true });
|
|
1299
1347
|
if (stat.isDirectory()) {
|
|
1300
|
-
|
|
1348
|
+
fs6.cpSync(source, target, {
|
|
1301
1349
|
recursive: true,
|
|
1302
1350
|
errorOnExist: false
|
|
1303
1351
|
});
|
|
1304
1352
|
return;
|
|
1305
1353
|
}
|
|
1306
|
-
|
|
1354
|
+
fs6.copyFileSync(source, target);
|
|
1307
1355
|
}
|
|
1308
1356
|
function bootstrapTerminalHome(homeDir) {
|
|
1309
|
-
const markerPath =
|
|
1310
|
-
if (
|
|
1357
|
+
const markerPath = path6.join(homeDir, BOOTSTRAP_MARKER);
|
|
1358
|
+
if (fs6.existsSync(markerPath)) {
|
|
1311
1359
|
return;
|
|
1312
1360
|
}
|
|
1313
1361
|
const globalHome = getGlobalHome();
|
|
1314
1362
|
const copies = [
|
|
1315
|
-
[
|
|
1316
|
-
[
|
|
1317
|
-
[
|
|
1318
|
-
[
|
|
1319
|
-
[
|
|
1363
|
+
[path6.join(globalHome, ".gitconfig"), path6.join(homeDir, ".gitconfig")],
|
|
1364
|
+
[path6.join(globalHome, ".claude.json"), path6.join(homeDir, ".claude.json")],
|
|
1365
|
+
[path6.join(globalHome, ".config", "gh"), path6.join(homeDir, ".config", "gh")],
|
|
1366
|
+
[path6.join(globalHome, ".claude"), path6.join(homeDir, ".claude")],
|
|
1367
|
+
[path6.join(globalHome, ".codex"), path6.join(homeDir, ".codex")]
|
|
1320
1368
|
];
|
|
1321
1369
|
for (const [source, target] of copies) {
|
|
1322
1370
|
copyPathIfPresent(source, target);
|
|
1323
1371
|
}
|
|
1324
|
-
|
|
1325
|
-
|
|
1372
|
+
fs6.writeFileSync(path6.join(homeDir, ".bash_history"), "", { flag: "a" });
|
|
1373
|
+
fs6.writeFileSync(markerPath, (/* @__PURE__ */ new Date()).toISOString());
|
|
1326
1374
|
}
|
|
1327
1375
|
function ensureTerminalIsolationHome(terminalId) {
|
|
1328
1376
|
const paths = getTerminalIsolationPaths(terminalId);
|
|
1329
|
-
|
|
1377
|
+
fs6.mkdirSync(paths.homeDir, { recursive: true });
|
|
1330
1378
|
bootstrapTerminalHome(paths.homeDir);
|
|
1331
1379
|
return paths;
|
|
1332
1380
|
}
|
|
1333
1381
|
function removeTerminalIsolationState(terminalId) {
|
|
1334
1382
|
const paths = getTerminalIsolationPaths(terminalId);
|
|
1335
|
-
|
|
1383
|
+
fs6.rmSync(paths.rootDir, { recursive: true, force: true });
|
|
1336
1384
|
}
|
|
1337
1385
|
var DEFAULT_TERMINAL_STATE_BASE, TERMINAL_STATE_BASE, BOOTSTRAP_MARKER;
|
|
1338
1386
|
var init_terminal_isolation = __esm({
|
|
1339
1387
|
"../server/src/agents/terminal-isolation.ts"() {
|
|
1340
1388
|
"use strict";
|
|
1341
|
-
|
|
1389
|
+
init_files();
|
|
1390
|
+
DEFAULT_TERMINAL_STATE_BASE = MAESTRO_SANDBOX_TERMINALS_DIR;
|
|
1342
1391
|
TERMINAL_STATE_BASE = process.env.MAESTRO_TERMINAL_STATE_BASE?.trim() || DEFAULT_TERMINAL_STATE_BASE;
|
|
1343
1392
|
BOOTSTRAP_MARKER = ".bootstrap-complete";
|
|
1344
1393
|
}
|
|
1345
1394
|
});
|
|
1346
1395
|
|
|
1347
1396
|
// ../server/src/agents/dind.ts
|
|
1348
|
-
import * as os6 from "os";
|
|
1349
|
-
import * as path6 from "path";
|
|
1350
1397
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
1351
1398
|
function getTerminalDockerResourceSuffix(terminalId) {
|
|
1352
1399
|
return terminalId.toLowerCase().replace(/[^a-z0-9_.-]/g, "-");
|
|
@@ -1369,8 +1416,8 @@ function getTerminalDockerRuntime(terminalId) {
|
|
|
1369
1416
|
}
|
|
1370
1417
|
function getSharedTerminalRuntimeMounts() {
|
|
1371
1418
|
const requestedPaths = [
|
|
1372
|
-
|
|
1373
|
-
|
|
1419
|
+
MAESTRO_SANDBOXES_DIR,
|
|
1420
|
+
MAESTRO_PROJECTS_DIR
|
|
1374
1421
|
];
|
|
1375
1422
|
return requestedPaths.flatMap((requestedPath) => {
|
|
1376
1423
|
const mount = resolveDockerMountForPath(requestedPath, false);
|
|
@@ -1496,6 +1543,7 @@ var DEFAULT_DIND_IMAGE, DEFAULT_DIND_READY_TIMEOUT_MS, DIND_SOCKET_DIR, DIND_SOC
|
|
|
1496
1543
|
var init_dind = __esm({
|
|
1497
1544
|
"../server/src/agents/dind.ts"() {
|
|
1498
1545
|
"use strict";
|
|
1546
|
+
init_files();
|
|
1499
1547
|
init_sandbox();
|
|
1500
1548
|
DEFAULT_DIND_IMAGE = process.env.MAESTRO_DIND_IMAGE || "docker:29-dind";
|
|
1501
1549
|
DEFAULT_DIND_READY_TIMEOUT_MS = Number(
|
|
@@ -1507,8 +1555,8 @@ var init_dind = __esm({
|
|
|
1507
1555
|
});
|
|
1508
1556
|
|
|
1509
1557
|
// ../server/src/integrations/cli-auth.ts
|
|
1510
|
-
import * as
|
|
1511
|
-
import * as
|
|
1558
|
+
import * as fs7 from "node:fs";
|
|
1559
|
+
import * as os6 from "node:os";
|
|
1512
1560
|
import * as path7 from "node:path";
|
|
1513
1561
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
1514
1562
|
import * as pty2 from "node-pty";
|
|
@@ -1518,7 +1566,7 @@ function stripAnsi(text) {
|
|
|
1518
1566
|
function getCredentialHomes() {
|
|
1519
1567
|
const candidates = [
|
|
1520
1568
|
process.env.HOME,
|
|
1521
|
-
|
|
1569
|
+
os6.homedir(),
|
|
1522
1570
|
"/root",
|
|
1523
1571
|
"/home/sandbox"
|
|
1524
1572
|
];
|
|
@@ -1570,13 +1618,13 @@ function getClaudeAuthStatusFromCredentials() {
|
|
|
1570
1618
|
let bestExpiresAt = -Infinity;
|
|
1571
1619
|
for (const home of getClaudeCredentialHomes()) {
|
|
1572
1620
|
const credentialsPath = path7.join(home, ".claude", ".credentials.json");
|
|
1573
|
-
if (!
|
|
1621
|
+
if (!fs7.existsSync(credentialsPath)) {
|
|
1574
1622
|
logClaudeAuth(`credentials file not found at ${credentialsPath}`);
|
|
1575
1623
|
continue;
|
|
1576
1624
|
}
|
|
1577
1625
|
logClaudeAuth(`found credentials file at ${credentialsPath}`);
|
|
1578
1626
|
try {
|
|
1579
|
-
const raw =
|
|
1627
|
+
const raw = fs7.readFileSync(credentialsPath, "utf8");
|
|
1580
1628
|
const data = JSON.parse(raw);
|
|
1581
1629
|
const oauth = data.claudeAiOauth;
|
|
1582
1630
|
if (!oauth?.accessToken) {
|
|
@@ -1684,9 +1732,9 @@ function getCodexAuthStatusFromFile() {
|
|
|
1684
1732
|
let bestScore = -Infinity;
|
|
1685
1733
|
for (const home of getCredentialHomes()) {
|
|
1686
1734
|
const authPath = path7.join(home, ".codex", "auth.json");
|
|
1687
|
-
if (!
|
|
1735
|
+
if (!fs7.existsSync(authPath)) continue;
|
|
1688
1736
|
try {
|
|
1689
|
-
const raw =
|
|
1737
|
+
const raw = fs7.readFileSync(authPath, "utf8");
|
|
1690
1738
|
const data = JSON.parse(raw);
|
|
1691
1739
|
const apiKey = data.OPENAI_API_KEY?.trim();
|
|
1692
1740
|
const tokens = data.tokens;
|
|
@@ -1808,55 +1856,9 @@ var init_cli_auth = __esm({
|
|
|
1808
1856
|
}
|
|
1809
1857
|
});
|
|
1810
1858
|
|
|
1811
|
-
// ../server/src/state/files.ts
|
|
1812
|
-
import * as fs7 from "fs";
|
|
1813
|
-
import * as os8 from "os";
|
|
1814
|
-
import * as path8 from "path";
|
|
1815
|
-
function ensureDataDir() {
|
|
1816
|
-
fs7.mkdirSync(MAESTRO_DATA_DIR, { recursive: true });
|
|
1817
|
-
return MAESTRO_DATA_DIR;
|
|
1818
|
-
}
|
|
1819
|
-
function ensureDir(dirPath) {
|
|
1820
|
-
fs7.mkdirSync(dirPath, { recursive: true });
|
|
1821
|
-
return dirPath;
|
|
1822
|
-
}
|
|
1823
|
-
function readJsonFile(filePath, fallback) {
|
|
1824
|
-
try {
|
|
1825
|
-
if (!fs7.existsSync(filePath)) {
|
|
1826
|
-
return fallback;
|
|
1827
|
-
}
|
|
1828
|
-
const raw = fs7.readFileSync(filePath, "utf-8");
|
|
1829
|
-
return JSON.parse(raw);
|
|
1830
|
-
} catch {
|
|
1831
|
-
return fallback;
|
|
1832
|
-
}
|
|
1833
|
-
}
|
|
1834
|
-
function writeJsonFile(filePath, value, options) {
|
|
1835
|
-
ensureDir(path8.dirname(filePath));
|
|
1836
|
-
const tempPath = `${filePath}.tmp`;
|
|
1837
|
-
fs7.writeFileSync(tempPath, `${JSON.stringify(value, null, 2)}
|
|
1838
|
-
`, {
|
|
1839
|
-
mode: options?.mode
|
|
1840
|
-
});
|
|
1841
|
-
fs7.renameSync(tempPath, filePath);
|
|
1842
|
-
if (options?.mode != null) {
|
|
1843
|
-
fs7.chmodSync(filePath, options.mode);
|
|
1844
|
-
}
|
|
1845
|
-
}
|
|
1846
|
-
function nowIso() {
|
|
1847
|
-
return (/* @__PURE__ */ new Date()).toISOString();
|
|
1848
|
-
}
|
|
1849
|
-
var MAESTRO_DATA_DIR;
|
|
1850
|
-
var init_files = __esm({
|
|
1851
|
-
"../server/src/state/files.ts"() {
|
|
1852
|
-
"use strict";
|
|
1853
|
-
MAESTRO_DATA_DIR = path8.join(os8.homedir(), ".maestro");
|
|
1854
|
-
}
|
|
1855
|
-
});
|
|
1856
|
-
|
|
1857
1859
|
// ../server/src/integrations/github.ts
|
|
1858
1860
|
import * as fs8 from "fs";
|
|
1859
|
-
import * as
|
|
1861
|
+
import * as path8 from "path";
|
|
1860
1862
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
1861
1863
|
function readStoredGitHubConnection() {
|
|
1862
1864
|
const record = readJsonFile(
|
|
@@ -2048,7 +2050,7 @@ var init_github = __esm({
|
|
|
2048
2050
|
"../server/src/integrations/github.ts"() {
|
|
2049
2051
|
"use strict";
|
|
2050
2052
|
init_files();
|
|
2051
|
-
GITHUB_CONNECTION_PATH =
|
|
2053
|
+
GITHUB_CONNECTION_PATH = path8.join(ensureDataDir(), "github-connection.json");
|
|
2052
2054
|
}
|
|
2053
2055
|
});
|
|
2054
2056
|
|
|
@@ -2110,7 +2112,7 @@ var init_auth_status_checker = __esm({
|
|
|
2110
2112
|
});
|
|
2111
2113
|
|
|
2112
2114
|
// ../server/src/state/sqlite.ts
|
|
2113
|
-
import * as
|
|
2115
|
+
import * as path9 from "path";
|
|
2114
2116
|
import { randomUUID } from "crypto";
|
|
2115
2117
|
import { DatabaseSync } from "node:sqlite";
|
|
2116
2118
|
function parseJson(value, fallback) {
|
|
@@ -2431,7 +2433,7 @@ var init_sqlite = __esm({
|
|
|
2431
2433
|
"../server/src/state/sqlite.ts"() {
|
|
2432
2434
|
"use strict";
|
|
2433
2435
|
init_files();
|
|
2434
|
-
dbPath =
|
|
2436
|
+
dbPath = path9.join(ensureDataDir(), "state.sqlite");
|
|
2435
2437
|
db = new DatabaseSync(dbPath);
|
|
2436
2438
|
db.exec(`
|
|
2437
2439
|
CREATE TABLE IF NOT EXISTS scheduled_tasks (
|
|
@@ -2626,7 +2628,7 @@ var init_auto_spawn_provider = __esm({
|
|
|
2626
2628
|
|
|
2627
2629
|
// ../server/src/state/terminals.ts
|
|
2628
2630
|
import * as fs9 from "fs";
|
|
2629
|
-
import * as
|
|
2631
|
+
import * as path10 from "path";
|
|
2630
2632
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
2631
2633
|
function readTerminals() {
|
|
2632
2634
|
return readJsonFile(TERMINALS_PATH, []);
|
|
@@ -2635,13 +2637,13 @@ function writeTerminals(terminals) {
|
|
|
2635
2637
|
writeJsonFile(TERMINALS_PATH, terminals);
|
|
2636
2638
|
}
|
|
2637
2639
|
function terminalDir(terminalId) {
|
|
2638
|
-
return ensureDir(
|
|
2640
|
+
return ensureDir(path10.join(TERMINAL_HISTORY_DIR, terminalId));
|
|
2639
2641
|
}
|
|
2640
2642
|
function terminalSnapshotPath(terminalId) {
|
|
2641
|
-
return
|
|
2643
|
+
return path10.join(terminalDir(terminalId), "snapshot.json");
|
|
2642
2644
|
}
|
|
2643
2645
|
function syncTerminalMeta(terminal) {
|
|
2644
|
-
writeJsonFile(
|
|
2646
|
+
writeJsonFile(path10.join(terminalDir(terminal.id), "meta.json"), terminal);
|
|
2645
2647
|
}
|
|
2646
2648
|
function listTerminalRecords() {
|
|
2647
2649
|
return readTerminals().sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
|
@@ -2689,7 +2691,7 @@ function deleteTerminalState(terminalId) {
|
|
|
2689
2691
|
fs9.rmSync(terminalDir(terminalId), { recursive: true, force: true });
|
|
2690
2692
|
}
|
|
2691
2693
|
async function appendTerminalHistoryBatch(terminalId, data) {
|
|
2692
|
-
const historyPath =
|
|
2694
|
+
const historyPath = path10.join(terminalDir(terminalId), "transcript.log");
|
|
2693
2695
|
await fs9.promises.appendFile(historyPath, data);
|
|
2694
2696
|
}
|
|
2695
2697
|
function readTerminalSnapshot(terminalId) {
|
|
@@ -2714,7 +2716,7 @@ function trimPartialTerminalTail(content) {
|
|
|
2714
2716
|
return content.slice(firstNewline + 1);
|
|
2715
2717
|
}
|
|
2716
2718
|
function readTerminalHistory(terminalId, maxBytes = 2 * 1024 * 1024) {
|
|
2717
|
-
const historyPath =
|
|
2719
|
+
const historyPath = path10.join(terminalDir(terminalId), "transcript.log");
|
|
2718
2720
|
if (!fs9.existsSync(historyPath)) return "";
|
|
2719
2721
|
const stat = fs9.statSync(historyPath);
|
|
2720
2722
|
if (stat.size === 0) return "";
|
|
@@ -2732,13 +2734,13 @@ var init_terminals = __esm({
|
|
|
2732
2734
|
"../server/src/state/terminals.ts"() {
|
|
2733
2735
|
"use strict";
|
|
2734
2736
|
init_files();
|
|
2735
|
-
TERMINALS_PATH =
|
|
2736
|
-
TERMINAL_HISTORY_DIR =
|
|
2737
|
+
TERMINALS_PATH = path10.join(ensureDataDir(), "agents.json");
|
|
2738
|
+
TERMINAL_HISTORY_DIR = path10.join(ensureDataDir(), "agents");
|
|
2737
2739
|
}
|
|
2738
2740
|
});
|
|
2739
2741
|
|
|
2740
2742
|
// ../server/src/state/projects.ts
|
|
2741
|
-
import * as
|
|
2743
|
+
import * as path11 from "path";
|
|
2742
2744
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
2743
2745
|
function readProjects() {
|
|
2744
2746
|
return readJsonFile(PROJECTS_PATH, []);
|
|
@@ -2801,14 +2803,14 @@ var init_projects = __esm({
|
|
|
2801
2803
|
"../server/src/state/projects.ts"() {
|
|
2802
2804
|
"use strict";
|
|
2803
2805
|
init_files();
|
|
2804
|
-
PROJECTS_PATH =
|
|
2806
|
+
PROJECTS_PATH = path11.join(ensureDataDir(), "projects.json");
|
|
2805
2807
|
}
|
|
2806
2808
|
});
|
|
2807
2809
|
|
|
2808
2810
|
// ../server/src/state/kanban.ts
|
|
2809
2811
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
2810
2812
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
2811
|
-
import * as
|
|
2813
|
+
import * as path12 from "path";
|
|
2812
2814
|
function readOverlays() {
|
|
2813
2815
|
return readJsonFile(TASK_OVERLAYS_PATH, {});
|
|
2814
2816
|
}
|
|
@@ -3575,8 +3577,8 @@ var init_kanban = __esm({
|
|
|
3575
3577
|
init_projects();
|
|
3576
3578
|
init_github();
|
|
3577
3579
|
init_terminals();
|
|
3578
|
-
TASK_OVERLAYS_PATH =
|
|
3579
|
-
LOCAL_TASKS_PATH =
|
|
3580
|
+
TASK_OVERLAYS_PATH = path12.join(ensureDataDir(), "kanban-overlays.json");
|
|
3581
|
+
LOCAL_TASKS_PATH = path12.join(ensureDataDir(), "local-kanban-tasks.json");
|
|
3580
3582
|
STATUS_LABELS = {
|
|
3581
3583
|
planned: "maestro:planned",
|
|
3582
3584
|
ongoing: "maestro:ongoing",
|
|
@@ -3613,16 +3615,16 @@ function readCommandError(error, fallback) {
|
|
|
3613
3615
|
}
|
|
3614
3616
|
return error instanceof Error && error.message ? error.message : fallback;
|
|
3615
3617
|
}
|
|
3616
|
-
function runGit2(
|
|
3618
|
+
function runGit2(path19, args) {
|
|
3617
3619
|
return execFileSync6("git", args, {
|
|
3618
|
-
cwd:
|
|
3620
|
+
cwd: path19,
|
|
3619
3621
|
encoding: "utf8",
|
|
3620
3622
|
stdio: ["ignore", "pipe", "pipe"]
|
|
3621
3623
|
}).trim();
|
|
3622
3624
|
}
|
|
3623
|
-
function tryRunGit(
|
|
3625
|
+
function tryRunGit(path19, args) {
|
|
3624
3626
|
try {
|
|
3625
|
-
return { ok: true, output: runGit2(
|
|
3627
|
+
return { ok: true, output: runGit2(path19, args) };
|
|
3626
3628
|
} catch (error) {
|
|
3627
3629
|
return {
|
|
3628
3630
|
ok: false,
|
|
@@ -3733,20 +3735,20 @@ function decideAutoWorktreeStartPoint(input) {
|
|
|
3733
3735
|
reason: "Using local HEAD in a fresh worktree because no remote tracking branch was available."
|
|
3734
3736
|
};
|
|
3735
3737
|
}
|
|
3736
|
-
function resolveUpstreamRef(
|
|
3737
|
-
const upstream = tryRunGit(
|
|
3738
|
+
function resolveUpstreamRef(path19, currentBranch) {
|
|
3739
|
+
const upstream = tryRunGit(path19, ["rev-parse", "--abbrev-ref", "@{upstream}"]);
|
|
3738
3740
|
if (upstream.ok && upstream.output) {
|
|
3739
3741
|
return upstream.output;
|
|
3740
3742
|
}
|
|
3741
3743
|
const originBranch = `refs/remotes/origin/${currentBranch}`;
|
|
3742
|
-
const remoteBranch = tryRunGit(
|
|
3744
|
+
const remoteBranch = tryRunGit(path19, ["show-ref", "--verify", "--quiet", originBranch]);
|
|
3743
3745
|
if (remoteBranch.ok) {
|
|
3744
3746
|
return `origin/${currentBranch}`;
|
|
3745
3747
|
}
|
|
3746
3748
|
return null;
|
|
3747
3749
|
}
|
|
3748
|
-
function hasGitRef(
|
|
3749
|
-
return tryRunGit(
|
|
3750
|
+
function hasGitRef(path19, ref) {
|
|
3751
|
+
return tryRunGit(path19, ["show-ref", "--verify", "--quiet", ref]).ok;
|
|
3750
3752
|
}
|
|
3751
3753
|
async function resolveAutoWorktreeStartPoint(input) {
|
|
3752
3754
|
const project = resolveProjectRecord(input);
|
|
@@ -5180,8 +5182,8 @@ async function registerTerminalRoutes(app) {
|
|
|
5180
5182
|
init_terminal_manager();
|
|
5181
5183
|
init_github();
|
|
5182
5184
|
import * as fs12 from "fs";
|
|
5183
|
-
import * as
|
|
5184
|
-
import * as
|
|
5185
|
+
import * as os7 from "os";
|
|
5186
|
+
import * as path13 from "path";
|
|
5185
5187
|
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
5186
5188
|
|
|
5187
5189
|
// ../server/src/scheduler/scheduler.ts
|
|
@@ -5270,7 +5272,9 @@ init_terminals();
|
|
|
5270
5272
|
init_kanban();
|
|
5271
5273
|
init_projects();
|
|
5272
5274
|
init_sqlite();
|
|
5273
|
-
|
|
5275
|
+
init_files();
|
|
5276
|
+
var LEGACY_MANAGED_PROJECTS_DIR = path13.join(os7.homedir(), "maestro-projects");
|
|
5277
|
+
var MANAGED_PROJECTS_DIR = MAESTRO_PROJECTS_DIR;
|
|
5274
5278
|
function slugify(input) {
|
|
5275
5279
|
return input.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "project";
|
|
5276
5280
|
}
|
|
@@ -5317,11 +5321,26 @@ function getUniqueSlug(name) {
|
|
|
5317
5321
|
}
|
|
5318
5322
|
return slug;
|
|
5319
5323
|
}
|
|
5324
|
+
function ensureManagedProjectsDir() {
|
|
5325
|
+
if (fs12.existsSync(MANAGED_PROJECTS_DIR)) {
|
|
5326
|
+
return MANAGED_PROJECTS_DIR;
|
|
5327
|
+
}
|
|
5328
|
+
if (fs12.existsSync(LEGACY_MANAGED_PROJECTS_DIR)) {
|
|
5329
|
+
fs12.mkdirSync(path13.dirname(MANAGED_PROJECTS_DIR), { recursive: true });
|
|
5330
|
+
fs12.renameSync(LEGACY_MANAGED_PROJECTS_DIR, MANAGED_PROJECTS_DIR);
|
|
5331
|
+
console.log(
|
|
5332
|
+
`Migrated managed projects directory from ${LEGACY_MANAGED_PROJECTS_DIR} to ${MANAGED_PROJECTS_DIR}`
|
|
5333
|
+
);
|
|
5334
|
+
return MANAGED_PROJECTS_DIR;
|
|
5335
|
+
}
|
|
5336
|
+
fs12.mkdirSync(MANAGED_PROJECTS_DIR, { recursive: true });
|
|
5337
|
+
return MANAGED_PROJECTS_DIR;
|
|
5338
|
+
}
|
|
5320
5339
|
function deriveLocalPath(localPath, name) {
|
|
5321
5340
|
if (localPath?.trim()) {
|
|
5322
|
-
return
|
|
5341
|
+
return path13.resolve(localPath.trim());
|
|
5323
5342
|
}
|
|
5324
|
-
return
|
|
5343
|
+
return path13.join(ensureManagedProjectsDir(), slugify(name));
|
|
5325
5344
|
}
|
|
5326
5345
|
function runGitCommand(args) {
|
|
5327
5346
|
try {
|
|
@@ -5354,7 +5373,7 @@ function cloneRepository(repo, localPath, defaultBranch) {
|
|
|
5354
5373
|
if (!repo.repoUrl) {
|
|
5355
5374
|
return;
|
|
5356
5375
|
}
|
|
5357
|
-
const parentDir =
|
|
5376
|
+
const parentDir = path13.dirname(localPath);
|
|
5358
5377
|
fs12.mkdirSync(parentDir, { recursive: true });
|
|
5359
5378
|
ensureProjectPathAvailable(localPath);
|
|
5360
5379
|
const branch = defaultBranch?.trim();
|
|
@@ -5650,17 +5669,17 @@ init_terminal_manager();
|
|
|
5650
5669
|
|
|
5651
5670
|
// ../server/src/setup/setup-manager.ts
|
|
5652
5671
|
import * as fs13 from "fs";
|
|
5653
|
-
import * as
|
|
5654
|
-
import * as
|
|
5672
|
+
import * as path14 from "path";
|
|
5673
|
+
import * as os8 from "os";
|
|
5655
5674
|
import * as pty3 from "node-pty";
|
|
5656
|
-
var FLAG_DIR =
|
|
5657
|
-
var FLAG_FILE =
|
|
5675
|
+
var FLAG_DIR = path14.join(os8.homedir(), ".maestro");
|
|
5676
|
+
var FLAG_FILE = path14.join(FLAG_DIR, "setup-complete");
|
|
5658
5677
|
var SENTINEL = "__MAESTRO_SETUP_DONE__";
|
|
5659
5678
|
var URL_RE = /https?:\/\/[^\s"'<>]+/g;
|
|
5660
5679
|
var ANSI_RE2 = /\x1b(?:\][^\x07\x1b]*(?:\x07|\x1b\\)?|\[[0-9;]*[A-Za-z])/g;
|
|
5661
5680
|
var STEP_BOUNDARY_RE = /(?:Running:|Checking|Do you want|Enter|Paste|Token)/i;
|
|
5662
5681
|
var INSTALL_ROOT = process.env.MAESTRO_INSTALL_ROOT?.trim();
|
|
5663
|
-
var SCRIPT_PATH = INSTALL_ROOT ?
|
|
5682
|
+
var SCRIPT_PATH = INSTALL_ROOT ? path14.resolve(INSTALL_ROOT, "assets/setup.sh") : path14.resolve(
|
|
5664
5683
|
import.meta.dirname ?? __dirname,
|
|
5665
5684
|
"../../scripts/setup.sh"
|
|
5666
5685
|
);
|
|
@@ -5701,7 +5720,7 @@ function startSetupPty(io3, cols, rows) {
|
|
|
5701
5720
|
name: "xterm-256color",
|
|
5702
5721
|
cols: cols ?? 120,
|
|
5703
5722
|
rows: rows ?? 30,
|
|
5704
|
-
cwd:
|
|
5723
|
+
cwd: os8.homedir(),
|
|
5705
5724
|
env: process.env
|
|
5706
5725
|
});
|
|
5707
5726
|
console.log(`[setup] PTY spawned, pid: ${activePty.pid}`);
|
|
@@ -6424,19 +6443,17 @@ function renderTemplate(template, item) {
|
|
|
6424
6443
|
}
|
|
6425
6444
|
|
|
6426
6445
|
// ../server/src/auth/auth.ts
|
|
6446
|
+
init_files();
|
|
6427
6447
|
import * as crypto2 from "crypto";
|
|
6428
6448
|
import * as fs14 from "fs";
|
|
6429
|
-
import * as
|
|
6430
|
-
import * as path16 from "path";
|
|
6449
|
+
import * as path15 from "path";
|
|
6431
6450
|
import jwt from "jsonwebtoken";
|
|
6432
|
-
var MAESTRO_DIR =
|
|
6433
|
-
var SECRET_PATH =
|
|
6434
|
-
var TOKEN_PATH =
|
|
6451
|
+
var MAESTRO_DIR = MAESTRO_DATA_DIR;
|
|
6452
|
+
var SECRET_PATH = path15.join(MAESTRO_DIR, "jwt-secret");
|
|
6453
|
+
var TOKEN_PATH = path15.join(MAESTRO_DIR, "api-token");
|
|
6435
6454
|
var jwtSecret;
|
|
6436
6455
|
function initAuth() {
|
|
6437
|
-
|
|
6438
|
-
fs14.mkdirSync(MAESTRO_DIR, { recursive: true });
|
|
6439
|
-
}
|
|
6456
|
+
ensureDataDir();
|
|
6440
6457
|
if (fs14.existsSync(SECRET_PATH)) {
|
|
6441
6458
|
jwtSecret = fs14.readFileSync(SECRET_PATH, "utf-8").trim();
|
|
6442
6459
|
} else {
|
|
@@ -6928,11 +6945,11 @@ function stopAutoUpdater() {
|
|
|
6928
6945
|
}
|
|
6929
6946
|
|
|
6930
6947
|
// ../server/src/services/ollama.ts
|
|
6931
|
-
import { mkdirSync as
|
|
6932
|
-
import { join as
|
|
6933
|
-
import { homedir as
|
|
6948
|
+
import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync5, readFileSync as readFileSync6, existsSync as existsSync15 } from "node:fs";
|
|
6949
|
+
import { join as join16 } from "node:path";
|
|
6950
|
+
import { homedir as homedir9 } from "node:os";
|
|
6934
6951
|
var OLLAMA_HOST = process.env.OLLAMA_HOST || "http://localhost:11434";
|
|
6935
|
-
var PI_MODELS_PATH =
|
|
6952
|
+
var PI_MODELS_PATH = join16(homedir9(), ".pi", "agent", "models.json");
|
|
6936
6953
|
async function getOllamaStatus() {
|
|
6937
6954
|
try {
|
|
6938
6955
|
const res = await fetch(`${OLLAMA_HOST}/api/version`);
|
|
@@ -7022,8 +7039,8 @@ async function pullOllamaModel(modelName) {
|
|
|
7022
7039
|
}
|
|
7023
7040
|
}
|
|
7024
7041
|
function writePiModelsConfig(modelId) {
|
|
7025
|
-
const dir =
|
|
7026
|
-
|
|
7042
|
+
const dir = join16(homedir9(), ".pi", "agent");
|
|
7043
|
+
mkdirSync6(dir, { recursive: true });
|
|
7027
7044
|
let existing = {};
|
|
7028
7045
|
if (existsSync15(PI_MODELS_PATH)) {
|
|
7029
7046
|
try {
|
|
@@ -7111,12 +7128,12 @@ function getDisabledStatus(message) {
|
|
|
7111
7128
|
latestRelease: null
|
|
7112
7129
|
};
|
|
7113
7130
|
}
|
|
7114
|
-
async function requestUpdater(
|
|
7131
|
+
async function requestUpdater(path19, init) {
|
|
7115
7132
|
const config = getUpdaterConfig();
|
|
7116
7133
|
if (!config) {
|
|
7117
7134
|
throw new Error("Deployment updater is not configured");
|
|
7118
7135
|
}
|
|
7119
|
-
const res = await fetch(`${config.url}${
|
|
7136
|
+
const res = await fetch(`${config.url}${path19}`, {
|
|
7120
7137
|
...init,
|
|
7121
7138
|
headers: {
|
|
7122
7139
|
...config.token ? { Authorization: `Bearer ${config.token}` } : {},
|
|
@@ -7271,8 +7288,8 @@ You are a friendly, conversational AI assistant. You communicate via messaging (
|
|
|
7271
7288
|
}
|
|
7272
7289
|
|
|
7273
7290
|
// ../pi/src/channels/whatsapp/whatsapp.ts
|
|
7274
|
-
import * as
|
|
7275
|
-
import * as
|
|
7291
|
+
import * as os9 from "os";
|
|
7292
|
+
import * as path16 from "path";
|
|
7276
7293
|
import makeWASocket, {
|
|
7277
7294
|
useMultiFileAuthState,
|
|
7278
7295
|
DisconnectReason,
|
|
@@ -7280,8 +7297,8 @@ import makeWASocket, {
|
|
|
7280
7297
|
makeCacheableSignalKeyStore
|
|
7281
7298
|
} from "@whiskeysockets/baileys";
|
|
7282
7299
|
import * as QRCode from "qrcode";
|
|
7283
|
-
var DATA_DIR =
|
|
7284
|
-
var AUTH_DIR =
|
|
7300
|
+
var DATA_DIR = path16.join(os9.homedir(), ".maestro");
|
|
7301
|
+
var AUTH_DIR = path16.join(DATA_DIR, "whatsapp-auth");
|
|
7285
7302
|
var sock = null;
|
|
7286
7303
|
var io = null;
|
|
7287
7304
|
var connectionStatus = "disconnected";
|
|
@@ -7436,13 +7453,13 @@ import {
|
|
|
7436
7453
|
|
|
7437
7454
|
// ../pi/src/channels/whatsapp/store.ts
|
|
7438
7455
|
import * as fs15 from "fs";
|
|
7439
|
-
import * as
|
|
7440
|
-
import * as
|
|
7456
|
+
import * as os10 from "os";
|
|
7457
|
+
import * as path17 from "path";
|
|
7441
7458
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
7442
7459
|
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
7443
|
-
var DATA_DIR2 =
|
|
7460
|
+
var DATA_DIR2 = path17.join(os10.homedir(), ".maestro");
|
|
7444
7461
|
fs15.mkdirSync(DATA_DIR2, { recursive: true });
|
|
7445
|
-
var dbPath2 =
|
|
7462
|
+
var dbPath2 = path17.join(DATA_DIR2, "pi.sqlite");
|
|
7446
7463
|
var db2 = new DatabaseSync2(dbPath2);
|
|
7447
7464
|
db2.exec(`
|
|
7448
7465
|
CREATE TABLE IF NOT EXISTS whatsapp_messages (
|
|
@@ -7858,13 +7875,13 @@ import {
|
|
|
7858
7875
|
|
|
7859
7876
|
// ../pi/src/channels/telegram/store.ts
|
|
7860
7877
|
import * as fs16 from "fs";
|
|
7861
|
-
import * as
|
|
7862
|
-
import * as
|
|
7878
|
+
import * as os11 from "os";
|
|
7879
|
+
import * as path18 from "path";
|
|
7863
7880
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
7864
7881
|
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
7865
|
-
var DATA_DIR3 =
|
|
7882
|
+
var DATA_DIR3 = path18.join(os11.homedir(), ".maestro");
|
|
7866
7883
|
fs16.mkdirSync(DATA_DIR3, { recursive: true });
|
|
7867
|
-
var dbPath3 =
|
|
7884
|
+
var dbPath3 = path18.join(DATA_DIR3, "pi.sqlite");
|
|
7868
7885
|
var db3 = new DatabaseSync3(dbPath3);
|
|
7869
7886
|
db3.exec(`
|
|
7870
7887
|
CREATE TABLE IF NOT EXISTS telegram_messages (
|