@isarai/maestro 0.1.4 → 0.1.6
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/README.md +2 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +2 -2
- package/dist/server.js +273 -167
- package/dist/server.js.map +4 -4
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -828,10 +828,10 @@ var init_terminal_replica = __esm({
|
|
|
828
828
|
}
|
|
829
829
|
write(data, cursor) {
|
|
830
830
|
return this.enqueue(
|
|
831
|
-
() => new Promise((
|
|
831
|
+
() => new Promise((resolve5) => {
|
|
832
832
|
this.terminal.write(data, () => {
|
|
833
833
|
this.refreshSnapshot(cursor);
|
|
834
|
-
|
|
834
|
+
resolve5();
|
|
835
835
|
});
|
|
836
836
|
})
|
|
837
837
|
);
|
|
@@ -849,8 +849,8 @@ var init_terminal_replica = __esm({
|
|
|
849
849
|
this.terminal.resize(snapshot.cols, snapshot.rows);
|
|
850
850
|
}
|
|
851
851
|
if (snapshot.data) {
|
|
852
|
-
await new Promise((
|
|
853
|
-
this.terminal.write(snapshot.data,
|
|
852
|
+
await new Promise((resolve5) => {
|
|
853
|
+
this.terminal.write(snapshot.data, resolve5);
|
|
854
854
|
});
|
|
855
855
|
}
|
|
856
856
|
this.refreshSnapshot(cursor);
|
|
@@ -1493,7 +1493,7 @@ function startCodexDeviceAuth() {
|
|
|
1493
1493
|
activeCodexPty.kill();
|
|
1494
1494
|
activeCodexPty = null;
|
|
1495
1495
|
}
|
|
1496
|
-
return new Promise((
|
|
1496
|
+
return new Promise((resolve5, reject) => {
|
|
1497
1497
|
const proc = pty2.spawn("codex", ["login", "--device-auth"], {
|
|
1498
1498
|
name: "xterm-256color",
|
|
1499
1499
|
cols: 120,
|
|
@@ -1510,7 +1510,7 @@ function startCodexDeviceAuth() {
|
|
|
1510
1510
|
const codeMatch = clean.match(/one-time code[^\n]*\n\s+([A-Z0-9]+-[A-Z0-9]+)/i);
|
|
1511
1511
|
if (codeMatch && urlMatch && !resolved) {
|
|
1512
1512
|
resolved = true;
|
|
1513
|
-
|
|
1513
|
+
resolve5({ code: codeMatch[1], url: urlMatch[1] });
|
|
1514
1514
|
}
|
|
1515
1515
|
});
|
|
1516
1516
|
proc.onExit(({ exitCode }) => {
|
|
@@ -3308,16 +3308,16 @@ function readCommandError(error, fallback) {
|
|
|
3308
3308
|
}
|
|
3309
3309
|
return error instanceof Error && error.message ? error.message : fallback;
|
|
3310
3310
|
}
|
|
3311
|
-
function runGit2(
|
|
3311
|
+
function runGit2(path20, args) {
|
|
3312
3312
|
return execFileSync6("git", args, {
|
|
3313
|
-
cwd:
|
|
3313
|
+
cwd: path20,
|
|
3314
3314
|
encoding: "utf8",
|
|
3315
3315
|
stdio: ["ignore", "pipe", "pipe"]
|
|
3316
3316
|
}).trim();
|
|
3317
3317
|
}
|
|
3318
|
-
function tryRunGit(
|
|
3318
|
+
function tryRunGit(path20, args) {
|
|
3319
3319
|
try {
|
|
3320
|
-
return { ok: true, output: runGit2(
|
|
3320
|
+
return { ok: true, output: runGit2(path20, args) };
|
|
3321
3321
|
} catch (error) {
|
|
3322
3322
|
return {
|
|
3323
3323
|
ok: false,
|
|
@@ -3428,20 +3428,20 @@ function decideAutoWorktreeStartPoint(input) {
|
|
|
3428
3428
|
reason: "Using local HEAD in a fresh worktree because no remote tracking branch was available."
|
|
3429
3429
|
};
|
|
3430
3430
|
}
|
|
3431
|
-
function resolveUpstreamRef(
|
|
3432
|
-
const upstream = tryRunGit(
|
|
3431
|
+
function resolveUpstreamRef(path20, currentBranch) {
|
|
3432
|
+
const upstream = tryRunGit(path20, ["rev-parse", "--abbrev-ref", "@{upstream}"]);
|
|
3433
3433
|
if (upstream.ok && upstream.output) {
|
|
3434
3434
|
return upstream.output;
|
|
3435
3435
|
}
|
|
3436
3436
|
const originBranch = `refs/remotes/origin/${currentBranch}`;
|
|
3437
|
-
const remoteBranch = tryRunGit(
|
|
3437
|
+
const remoteBranch = tryRunGit(path20, ["show-ref", "--verify", "--quiet", originBranch]);
|
|
3438
3438
|
if (remoteBranch.ok) {
|
|
3439
3439
|
return `origin/${currentBranch}`;
|
|
3440
3440
|
}
|
|
3441
3441
|
return null;
|
|
3442
3442
|
}
|
|
3443
|
-
function hasGitRef(
|
|
3444
|
-
return tryRunGit(
|
|
3443
|
+
function hasGitRef(path20, ref) {
|
|
3444
|
+
return tryRunGit(path20, ["show-ref", "--verify", "--quiet", ref]).ok;
|
|
3445
3445
|
}
|
|
3446
3446
|
async function resolveAutoWorktreeStartPoint(input) {
|
|
3447
3447
|
const project = resolveProjectRecord(input);
|
|
@@ -3599,11 +3599,11 @@ function shouldDeleteTerminalDuringRestore(terminal) {
|
|
|
3599
3599
|
);
|
|
3600
3600
|
}
|
|
3601
3601
|
function createExitWaiter() {
|
|
3602
|
-
let
|
|
3602
|
+
let resolve5 = () => void 0;
|
|
3603
3603
|
const promise = new Promise((innerResolve) => {
|
|
3604
|
-
|
|
3604
|
+
resolve5 = innerResolve;
|
|
3605
3605
|
});
|
|
3606
|
-
return { promise, resolve:
|
|
3606
|
+
return { promise, resolve: resolve5 };
|
|
3607
3607
|
}
|
|
3608
3608
|
function getRuntime(terminalId) {
|
|
3609
3609
|
let rt = agentRuntimes.get(terminalId);
|
|
@@ -3691,9 +3691,9 @@ function prepareExitWaiter(rt) {
|
|
|
3691
3691
|
rt.resolveExit = waiter.resolve;
|
|
3692
3692
|
}
|
|
3693
3693
|
function resolveExitWaiter(rt) {
|
|
3694
|
-
const
|
|
3694
|
+
const resolve5 = rt.resolveExit;
|
|
3695
3695
|
rt.resolveExit = null;
|
|
3696
|
-
|
|
3696
|
+
resolve5?.();
|
|
3697
3697
|
}
|
|
3698
3698
|
function scheduleHistoryFlush(terminalId, rt) {
|
|
3699
3699
|
if (rt.historyFlushTimer || !terminalCanUseRuntime(terminalId, rt)) {
|
|
@@ -4368,28 +4368,22 @@ var UpdateStatus = z.object({
|
|
|
4368
4368
|
updating: z.boolean(),
|
|
4369
4369
|
lastError: z.string().nullable()
|
|
4370
4370
|
});
|
|
4371
|
-
var
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
publishedAt: z.string().nullable(),
|
|
4376
|
-
notes: z.string().nullable()
|
|
4377
|
-
});
|
|
4378
|
-
var DeploymentUpdateStatus = z.object({
|
|
4379
|
-
configured: z.boolean(),
|
|
4371
|
+
var MaestroInstallMode = z.enum(["npm", "container", "unknown"]);
|
|
4372
|
+
var MaestroUpdateStatus = z.object({
|
|
4373
|
+
supported: z.boolean(),
|
|
4374
|
+
installMode: MaestroInstallMode,
|
|
4380
4375
|
currentVersion: z.string().nullable(),
|
|
4381
4376
|
latestVersion: z.string().nullable(),
|
|
4382
4377
|
updateAvailable: z.boolean(),
|
|
4383
4378
|
updating: z.boolean(),
|
|
4384
4379
|
lastCheckedAt: z.string().nullable(),
|
|
4385
4380
|
lastUpdatedAt: z.string().nullable(),
|
|
4386
|
-
lastError: z.string().nullable()
|
|
4387
|
-
latestRelease: DeploymentReleaseInfo.nullable()
|
|
4381
|
+
lastError: z.string().nullable()
|
|
4388
4382
|
});
|
|
4389
|
-
var
|
|
4383
|
+
var MaestroUpdateTriggerResponse = z.object({
|
|
4390
4384
|
accepted: z.boolean(),
|
|
4391
|
-
|
|
4392
|
-
|
|
4385
|
+
message: z.string(),
|
|
4386
|
+
targetVersion: z.string().nullable()
|
|
4393
4387
|
});
|
|
4394
4388
|
|
|
4395
4389
|
// ../wire/src/agent.ts
|
|
@@ -6810,126 +6804,238 @@ async function registerSettingsRoutes(app) {
|
|
|
6810
6804
|
});
|
|
6811
6805
|
}
|
|
6812
6806
|
|
|
6813
|
-
// ../server/src/
|
|
6814
|
-
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
|
|
6807
|
+
// ../server/src/main.ts
|
|
6808
|
+
init_auth_status_checker();
|
|
6809
|
+
|
|
6810
|
+
// ../server/src/routes/setup-routes.ts
|
|
6811
|
+
async function registerSetupRoutes(app) {
|
|
6812
|
+
app.get("/api/setup/status", async () => ({
|
|
6813
|
+
needsSetup: false,
|
|
6814
|
+
running: false
|
|
6815
|
+
}));
|
|
6816
|
+
app.post("/api/setup/reset", async () => {
|
|
6817
|
+
return { ok: true };
|
|
6818
|
+
});
|
|
6819
|
+
}
|
|
6820
|
+
|
|
6821
|
+
// ../server/src/services/maestro-updater.ts
|
|
6822
|
+
init_files();
|
|
6823
|
+
import * as fs15 from "node:fs";
|
|
6824
|
+
import * as os9 from "node:os";
|
|
6825
|
+
import * as path16 from "node:path";
|
|
6826
|
+
import { execFileSync as execFileSync8, spawn as spawn4 } from "node:child_process";
|
|
6827
|
+
var UPDATE_STATE_PATH = path16.join(os9.homedir(), ".maestro", "maestro-update-state.json");
|
|
6828
|
+
var LOG_PATH = path16.join(os9.homedir(), ".maestro", "server.log");
|
|
6829
|
+
var DEFAULT_STATE = {
|
|
6830
|
+
updating: false,
|
|
6831
|
+
lastCheckedAt: null,
|
|
6832
|
+
lastUpdatedAt: null,
|
|
6833
|
+
latestVersion: null,
|
|
6834
|
+
lastError: null
|
|
6835
|
+
};
|
|
6836
|
+
function readState() {
|
|
6837
|
+
return readJsonFile(UPDATE_STATE_PATH, DEFAULT_STATE);
|
|
6838
|
+
}
|
|
6839
|
+
function writeState(patch) {
|
|
6840
|
+
const next = { ...readState(), ...patch };
|
|
6841
|
+
writeJsonFile(UPDATE_STATE_PATH, next, { mode: 384 });
|
|
6842
|
+
return next;
|
|
6843
|
+
}
|
|
6844
|
+
function nowIso2() {
|
|
6845
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
6846
|
+
}
|
|
6847
|
+
function getInstallRoot() {
|
|
6848
|
+
const raw = process.env.MAESTRO_INSTALL_ROOT;
|
|
6849
|
+
if (!raw) return null;
|
|
6850
|
+
const resolved = path16.resolve(raw);
|
|
6851
|
+
return fs15.existsSync(path16.join(resolved, "package.json")) ? resolved : null;
|
|
6852
|
+
}
|
|
6853
|
+
function isContainerManagedInstall() {
|
|
6854
|
+
return fs15.existsSync("/.dockerenv") || Boolean(process.env.KUBERNETES_SERVICE_HOST);
|
|
6855
|
+
}
|
|
6856
|
+
function getNpmCommand() {
|
|
6857
|
+
return process.platform === "win32" ? "npm.cmd" : "npm";
|
|
6858
|
+
}
|
|
6859
|
+
function readPackageMeta(installRoot) {
|
|
6860
|
+
try {
|
|
6861
|
+
return JSON.parse(fs15.readFileSync(path16.join(installRoot, "package.json"), "utf8"));
|
|
6862
|
+
} catch {
|
|
6818
6863
|
return null;
|
|
6819
6864
|
}
|
|
6820
|
-
return {
|
|
6821
|
-
url: url.replace(/\/+$/g, ""),
|
|
6822
|
-
token: token || null
|
|
6823
|
-
};
|
|
6824
|
-
}
|
|
6825
|
-
function getDisabledStatus(message) {
|
|
6826
|
-
return {
|
|
6827
|
-
configured: false,
|
|
6828
|
-
currentVersion: null,
|
|
6829
|
-
latestVersion: null,
|
|
6830
|
-
updateAvailable: false,
|
|
6831
|
-
updating: false,
|
|
6832
|
-
lastCheckedAt: null,
|
|
6833
|
-
lastUpdatedAt: null,
|
|
6834
|
-
lastError: message ?? null,
|
|
6835
|
-
latestRelease: null
|
|
6836
|
-
};
|
|
6837
6865
|
}
|
|
6838
|
-
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
...config.token ? { Authorization: `Bearer ${config.token}` } : {},
|
|
6847
|
-
...init?.body != null ? { "Content-Type": "application/json" } : {},
|
|
6848
|
-
...init?.headers
|
|
6849
|
-
},
|
|
6850
|
-
signal: AbortSignal.timeout(init?.timeoutMs ?? 15e3)
|
|
6851
|
-
});
|
|
6852
|
-
const body = await res.json().catch(() => ({}));
|
|
6853
|
-
if (!res.ok) {
|
|
6854
|
-
throw new Error(
|
|
6855
|
-
typeof body.error === "string" ? body.error : `Updater request failed (${res.status})`
|
|
6856
|
-
);
|
|
6866
|
+
function getGlobalNpmRoot(npmCommand) {
|
|
6867
|
+
try {
|
|
6868
|
+
return execFileSync8(npmCommand, ["root", "-g"], {
|
|
6869
|
+
encoding: "utf8",
|
|
6870
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
6871
|
+
}).trim();
|
|
6872
|
+
} catch {
|
|
6873
|
+
return null;
|
|
6857
6874
|
}
|
|
6858
|
-
return body;
|
|
6859
6875
|
}
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6876
|
+
function detectInstallMode() {
|
|
6877
|
+
if (isContainerManagedInstall()) {
|
|
6878
|
+
return { installMode: "container", installRoot: null, meta: null };
|
|
6879
|
+
}
|
|
6880
|
+
const installRoot = getInstallRoot();
|
|
6881
|
+
const meta = installRoot ? readPackageMeta(installRoot) : null;
|
|
6882
|
+
if (!installRoot || !meta) {
|
|
6883
|
+
return { installMode: "unknown", installRoot: null, meta: null };
|
|
6866
6884
|
}
|
|
6885
|
+
const globalRoot = getGlobalNpmRoot(getNpmCommand());
|
|
6886
|
+
if (!globalRoot) {
|
|
6887
|
+
return { installMode: "unknown", installRoot, meta };
|
|
6888
|
+
}
|
|
6889
|
+
const expectedRoot = path16.resolve(globalRoot, meta.name);
|
|
6890
|
+
if (path16.resolve(installRoot) !== expectedRoot) {
|
|
6891
|
+
return { installMode: "unknown", installRoot, meta };
|
|
6892
|
+
}
|
|
6893
|
+
return { installMode: "npm", installRoot, meta };
|
|
6894
|
+
}
|
|
6895
|
+
function getLatestVersion2(packageName) {
|
|
6867
6896
|
try {
|
|
6868
|
-
return
|
|
6869
|
-
|
|
6897
|
+
return execFileSync8(getNpmCommand(), ["view", `${packageName}@latest`, "version"], {
|
|
6898
|
+
encoding: "utf8",
|
|
6899
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
6900
|
+
timeout: 6e4
|
|
6901
|
+
}).trim() || null;
|
|
6902
|
+
} catch {
|
|
6903
|
+
return null;
|
|
6904
|
+
}
|
|
6905
|
+
}
|
|
6906
|
+
async function checkForMaestroUpdates() {
|
|
6907
|
+
const install = detectInstallMode();
|
|
6908
|
+
if (install.installMode !== "npm" || !install.meta) {
|
|
6909
|
+
const state2 = writeState({
|
|
6910
|
+
updating: false,
|
|
6911
|
+
lastCheckedAt: nowIso2(),
|
|
6912
|
+
lastError: install.installMode === "container" ? "Maestro is container-managed. Redeploy the image instead of using self-update." : "Maestro self-update is only available for the published global npm install."
|
|
6913
|
+
});
|
|
6870
6914
|
return {
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
6915
|
+
supported: false,
|
|
6916
|
+
installMode: install.installMode,
|
|
6917
|
+
currentVersion: install.meta?.version ?? null,
|
|
6918
|
+
latestVersion: state2.latestVersion,
|
|
6874
6919
|
updateAvailable: false,
|
|
6875
6920
|
updating: false,
|
|
6876
|
-
lastCheckedAt:
|
|
6877
|
-
lastUpdatedAt:
|
|
6878
|
-
lastError:
|
|
6879
|
-
latestRelease: null
|
|
6921
|
+
lastCheckedAt: state2.lastCheckedAt,
|
|
6922
|
+
lastUpdatedAt: state2.lastUpdatedAt,
|
|
6923
|
+
lastError: state2.lastError
|
|
6880
6924
|
};
|
|
6881
6925
|
}
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
"Set UPDATER_URL on the Maestro server to enable release redeploys. UPDATER_TOKEN is optional on the internal network."
|
|
6888
|
-
);
|
|
6889
|
-
}
|
|
6890
|
-
return requestUpdater("/check", {
|
|
6891
|
-
method: "POST"
|
|
6926
|
+
const latestVersion = getLatestVersion2(install.meta.name);
|
|
6927
|
+
const state = writeState({
|
|
6928
|
+
lastCheckedAt: nowIso2(),
|
|
6929
|
+
latestVersion,
|
|
6930
|
+
lastError: latestVersion ? null : `Failed to query the latest published version for ${install.meta.name}.`
|
|
6892
6931
|
});
|
|
6932
|
+
return {
|
|
6933
|
+
supported: true,
|
|
6934
|
+
installMode: "npm",
|
|
6935
|
+
currentVersion: install.meta.version,
|
|
6936
|
+
latestVersion: state.latestVersion,
|
|
6937
|
+
updateAvailable: state.latestVersion !== null && state.latestVersion !== install.meta.version,
|
|
6938
|
+
updating: state.updating,
|
|
6939
|
+
lastCheckedAt: state.lastCheckedAt,
|
|
6940
|
+
lastUpdatedAt: state.lastUpdatedAt,
|
|
6941
|
+
lastError: state.lastError
|
|
6942
|
+
};
|
|
6893
6943
|
}
|
|
6894
|
-
|
|
6895
|
-
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
|
|
6944
|
+
function getMaestroUpdateStatus() {
|
|
6945
|
+
const install = detectInstallMode();
|
|
6946
|
+
let state = readState();
|
|
6947
|
+
const currentVersion = install.meta?.version ?? null;
|
|
6948
|
+
if (state.updating && install.installMode === "npm" && currentVersion !== null && state.latestVersion !== null && currentVersion === state.latestVersion) {
|
|
6949
|
+
state = writeState({
|
|
6950
|
+
updating: false,
|
|
6951
|
+
lastUpdatedAt: state.lastUpdatedAt ?? nowIso2(),
|
|
6952
|
+
lastError: null
|
|
6953
|
+
});
|
|
6954
|
+
}
|
|
6955
|
+
return {
|
|
6956
|
+
supported: install.installMode === "npm",
|
|
6957
|
+
installMode: install.installMode,
|
|
6958
|
+
currentVersion,
|
|
6959
|
+
latestVersion: state.latestVersion,
|
|
6960
|
+
updateAvailable: install.installMode === "npm" && currentVersion !== null && state.latestVersion !== null && currentVersion !== state.latestVersion,
|
|
6961
|
+
updating: state.updating,
|
|
6962
|
+
lastCheckedAt: state.lastCheckedAt,
|
|
6963
|
+
lastUpdatedAt: state.lastUpdatedAt,
|
|
6964
|
+
lastError: state.lastError
|
|
6965
|
+
};
|
|
6900
6966
|
}
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6967
|
+
async function triggerMaestroUpdate() {
|
|
6968
|
+
const status = await checkForMaestroUpdates();
|
|
6969
|
+
if (!status.supported) {
|
|
6970
|
+
return {
|
|
6971
|
+
accepted: false,
|
|
6972
|
+
message: status.lastError ?? "Maestro self-update is only available for the published global npm install.",
|
|
6973
|
+
targetVersion: null
|
|
6974
|
+
};
|
|
6975
|
+
}
|
|
6976
|
+
if (status.updating) {
|
|
6977
|
+
return {
|
|
6978
|
+
accepted: false,
|
|
6979
|
+
message: "Maestro update already in progress.",
|
|
6980
|
+
targetVersion: status.latestVersion
|
|
6981
|
+
};
|
|
6982
|
+
}
|
|
6983
|
+
if (!status.updateAvailable || !status.latestVersion) {
|
|
6984
|
+
return {
|
|
6985
|
+
accepted: false,
|
|
6986
|
+
message: "Maestro is already up to date.",
|
|
6987
|
+
targetVersion: status.currentVersion
|
|
6988
|
+
};
|
|
6989
|
+
}
|
|
6990
|
+
const installRoot = getInstallRoot();
|
|
6991
|
+
if (!installRoot) {
|
|
6992
|
+
return {
|
|
6993
|
+
accepted: false,
|
|
6994
|
+
message: "Failed to locate the installed Maestro CLI root.",
|
|
6995
|
+
targetVersion: null
|
|
6996
|
+
};
|
|
6997
|
+
}
|
|
6998
|
+
const cliEntry = path16.join(installRoot, "dist", "index.js");
|
|
6999
|
+
if (!fs15.existsSync(cliEntry)) {
|
|
7000
|
+
return {
|
|
7001
|
+
accepted: false,
|
|
7002
|
+
message: `Maestro CLI entrypoint not found at ${cliEntry}.`,
|
|
7003
|
+
targetVersion: null
|
|
7004
|
+
};
|
|
7005
|
+
}
|
|
7006
|
+
fs15.mkdirSync(path16.dirname(LOG_PATH), { recursive: true });
|
|
7007
|
+
const out = fs15.openSync(LOG_PATH, "a");
|
|
7008
|
+
writeState({
|
|
7009
|
+
updating: true,
|
|
7010
|
+
lastUpdatedAt: nowIso2(),
|
|
7011
|
+
lastError: null
|
|
6909
7012
|
});
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
const status = /not configured/i.test(message) || /missing/i.test(message) ? 400 : 502;
|
|
6917
|
-
return reply.status(status).send({ error: message });
|
|
7013
|
+
const child = spawn4(process.execPath, [cliEntry, "update"], {
|
|
7014
|
+
detached: true,
|
|
7015
|
+
stdio: ["ignore", out, out],
|
|
7016
|
+
env: {
|
|
7017
|
+
...process.env,
|
|
7018
|
+
MAESTRO_SELF_UPDATE_DELAY_MS: "1000"
|
|
6918
7019
|
}
|
|
6919
7020
|
});
|
|
7021
|
+
child.unref();
|
|
7022
|
+
return {
|
|
7023
|
+
accepted: true,
|
|
7024
|
+
message: `Started Maestro update to ${status.latestVersion}. The server connection will drop briefly while it restarts.`,
|
|
7025
|
+
targetVersion: status.latestVersion
|
|
7026
|
+
};
|
|
6920
7027
|
}
|
|
6921
7028
|
|
|
6922
|
-
// ../server/src/
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
app.
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
6932
|
-
return { ok: true };
|
|
7029
|
+
// ../server/src/routes/maestro-update-routes.ts
|
|
7030
|
+
async function registerMaestroUpdateRoutes(app) {
|
|
7031
|
+
app.get("/api/maestro/update-status", async () => {
|
|
7032
|
+
return getMaestroUpdateStatus();
|
|
7033
|
+
});
|
|
7034
|
+
app.post("/api/maestro/check", async () => {
|
|
7035
|
+
return checkForMaestroUpdates();
|
|
7036
|
+
});
|
|
7037
|
+
app.post("/api/maestro/update", async () => {
|
|
7038
|
+
return triggerMaestroUpdate();
|
|
6933
7039
|
});
|
|
6934
7040
|
}
|
|
6935
7041
|
|
|
@@ -6995,8 +7101,8 @@ You are a friendly, conversational AI assistant. You communicate via messaging (
|
|
|
6995
7101
|
}
|
|
6996
7102
|
|
|
6997
7103
|
// ../pi/src/channels/whatsapp/whatsapp.ts
|
|
6998
|
-
import * as
|
|
6999
|
-
import * as
|
|
7104
|
+
import * as os10 from "os";
|
|
7105
|
+
import * as path17 from "path";
|
|
7000
7106
|
import makeWASocket, {
|
|
7001
7107
|
useMultiFileAuthState,
|
|
7002
7108
|
DisconnectReason,
|
|
@@ -7004,8 +7110,8 @@ import makeWASocket, {
|
|
|
7004
7110
|
makeCacheableSignalKeyStore
|
|
7005
7111
|
} from "@whiskeysockets/baileys";
|
|
7006
7112
|
import * as QRCode from "qrcode";
|
|
7007
|
-
var DATA_DIR =
|
|
7008
|
-
var AUTH_DIR =
|
|
7113
|
+
var DATA_DIR = path17.join(os10.homedir(), ".maestro");
|
|
7114
|
+
var AUTH_DIR = path17.join(DATA_DIR, "whatsapp-auth");
|
|
7009
7115
|
var sock = null;
|
|
7010
7116
|
var io = null;
|
|
7011
7117
|
var connectionStatus = "disconnected";
|
|
@@ -7159,14 +7265,14 @@ import {
|
|
|
7159
7265
|
} from "@mariozechner/pi-coding-agent";
|
|
7160
7266
|
|
|
7161
7267
|
// ../pi/src/channels/whatsapp/store.ts
|
|
7162
|
-
import * as
|
|
7163
|
-
import * as
|
|
7164
|
-
import * as
|
|
7268
|
+
import * as fs16 from "fs";
|
|
7269
|
+
import * as os11 from "os";
|
|
7270
|
+
import * as path18 from "path";
|
|
7165
7271
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
7166
7272
|
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
7167
|
-
var DATA_DIR2 =
|
|
7168
|
-
|
|
7169
|
-
var dbPath2 =
|
|
7273
|
+
var DATA_DIR2 = path18.join(os11.homedir(), ".maestro");
|
|
7274
|
+
fs16.mkdirSync(DATA_DIR2, { recursive: true });
|
|
7275
|
+
var dbPath2 = path18.join(DATA_DIR2, "pi.sqlite");
|
|
7170
7276
|
var db2 = new DatabaseSync2(dbPath2);
|
|
7171
7277
|
db2.exec(`
|
|
7172
7278
|
CREATE TABLE IF NOT EXISTS whatsapp_messages (
|
|
@@ -7185,7 +7291,7 @@ db2.exec(`
|
|
|
7185
7291
|
CREATE INDEX IF NOT EXISTS idx_wa_status ON whatsapp_messages(status);
|
|
7186
7292
|
CREATE INDEX IF NOT EXISTS idx_wa_chat ON whatsapp_messages(chat_jid, created_at);
|
|
7187
7293
|
`);
|
|
7188
|
-
function
|
|
7294
|
+
function nowIso3() {
|
|
7189
7295
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
7190
7296
|
}
|
|
7191
7297
|
function toWhatsAppMessage(row) {
|
|
@@ -7205,7 +7311,7 @@ function toWhatsAppMessage(row) {
|
|
|
7205
7311
|
}
|
|
7206
7312
|
function insertWhatsAppMessage(input) {
|
|
7207
7313
|
const id = randomUUID5();
|
|
7208
|
-
const now =
|
|
7314
|
+
const now = nowIso3();
|
|
7209
7315
|
const status = input.status ?? "queued";
|
|
7210
7316
|
db2.prepare(`
|
|
7211
7317
|
INSERT INTO whatsapp_messages (id, chat_jid, message_id, direction, sender_name, body, status, created_at)
|
|
@@ -7270,7 +7376,7 @@ var session = null;
|
|
|
7270
7376
|
var isProcessing = false;
|
|
7271
7377
|
var PI_PROJECT_PATH = process.env.PI_PROJECT_PATH || "/tmp/maestro-whatsapp";
|
|
7272
7378
|
var PI_TIMEOUT_MS = parseInt(process.env.PI_TIMEOUT_MS || "300000", 10);
|
|
7273
|
-
function
|
|
7379
|
+
function nowIso4() {
|
|
7274
7380
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
7275
7381
|
}
|
|
7276
7382
|
async function ensureSession() {
|
|
@@ -7304,7 +7410,7 @@ async function ensureSession() {
|
|
|
7304
7410
|
return s;
|
|
7305
7411
|
}
|
|
7306
7412
|
function sendPrompt(s, message) {
|
|
7307
|
-
return new Promise((
|
|
7413
|
+
return new Promise((resolve5, reject) => {
|
|
7308
7414
|
let responseText = "";
|
|
7309
7415
|
let done = false;
|
|
7310
7416
|
const timer4 = setTimeout(() => {
|
|
@@ -7328,7 +7434,7 @@ function sendPrompt(s, message) {
|
|
|
7328
7434
|
reject(new Error(lastAssistant.errorMessage));
|
|
7329
7435
|
return;
|
|
7330
7436
|
}
|
|
7331
|
-
|
|
7437
|
+
resolve5(responseText.trim() || "Agent completed without text output.");
|
|
7332
7438
|
}
|
|
7333
7439
|
});
|
|
7334
7440
|
s.prompt(message).catch((err) => {
|
|
@@ -7378,7 +7484,7 @@ async function processNext() {
|
|
|
7378
7484
|
if (msg.body.trim().toLowerCase() === "reset") {
|
|
7379
7485
|
await s.newSession();
|
|
7380
7486
|
await sendWhatsAppMessage(msg.chatJid, "Session reset.");
|
|
7381
|
-
updateWhatsAppMessage(msg.id, { status: "completed", responseText: "Session reset.", processedAt:
|
|
7487
|
+
updateWhatsAppMessage(msg.id, { status: "completed", responseText: "Session reset.", processedAt: nowIso4() });
|
|
7382
7488
|
console.log("[whatsapp-queue] Session reset by user");
|
|
7383
7489
|
return;
|
|
7384
7490
|
}
|
|
@@ -7395,7 +7501,7 @@ async function processNext() {
|
|
|
7395
7501
|
updateWhatsAppMessage(msg.id, {
|
|
7396
7502
|
status: "completed",
|
|
7397
7503
|
responseText,
|
|
7398
|
-
processedAt:
|
|
7504
|
+
processedAt: nowIso4()
|
|
7399
7505
|
});
|
|
7400
7506
|
console.log(`[whatsapp-queue] Completed message ${msg.id}`);
|
|
7401
7507
|
} catch (error) {
|
|
@@ -7404,7 +7510,7 @@ async function processNext() {
|
|
|
7404
7510
|
updateWhatsAppMessage(msg.id, {
|
|
7405
7511
|
status: "failed",
|
|
7406
7512
|
error: errMsg,
|
|
7407
|
-
processedAt:
|
|
7513
|
+
processedAt: nowIso4()
|
|
7408
7514
|
});
|
|
7409
7515
|
} finally {
|
|
7410
7516
|
isProcessing = false;
|
|
@@ -7581,14 +7687,14 @@ import {
|
|
|
7581
7687
|
} from "@mariozechner/pi-coding-agent";
|
|
7582
7688
|
|
|
7583
7689
|
// ../pi/src/channels/telegram/store.ts
|
|
7584
|
-
import * as
|
|
7585
|
-
import * as
|
|
7586
|
-
import * as
|
|
7690
|
+
import * as fs17 from "fs";
|
|
7691
|
+
import * as os12 from "os";
|
|
7692
|
+
import * as path19 from "path";
|
|
7587
7693
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
7588
7694
|
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
7589
|
-
var DATA_DIR3 =
|
|
7590
|
-
|
|
7591
|
-
var dbPath3 =
|
|
7695
|
+
var DATA_DIR3 = path19.join(os12.homedir(), ".maestro");
|
|
7696
|
+
fs17.mkdirSync(DATA_DIR3, { recursive: true });
|
|
7697
|
+
var dbPath3 = path19.join(DATA_DIR3, "pi.sqlite");
|
|
7592
7698
|
var db3 = new DatabaseSync3(dbPath3);
|
|
7593
7699
|
db3.exec(`
|
|
7594
7700
|
CREATE TABLE IF NOT EXISTS telegram_messages (
|
|
@@ -7607,7 +7713,7 @@ db3.exec(`
|
|
|
7607
7713
|
CREATE INDEX IF NOT EXISTS idx_tg_status ON telegram_messages(status);
|
|
7608
7714
|
CREATE INDEX IF NOT EXISTS idx_tg_chat ON telegram_messages(chat_id, created_at);
|
|
7609
7715
|
`);
|
|
7610
|
-
function
|
|
7716
|
+
function nowIso5() {
|
|
7611
7717
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
7612
7718
|
}
|
|
7613
7719
|
function toTelegramMessage(row) {
|
|
@@ -7627,7 +7733,7 @@ function toTelegramMessage(row) {
|
|
|
7627
7733
|
}
|
|
7628
7734
|
function insertTelegramMessage(input) {
|
|
7629
7735
|
const id = randomUUID6();
|
|
7630
|
-
const now =
|
|
7736
|
+
const now = nowIso5();
|
|
7631
7737
|
const status = input.status ?? "queued";
|
|
7632
7738
|
db3.prepare(`
|
|
7633
7739
|
INSERT INTO telegram_messages (id, chat_id, message_id, direction, sender_name, body, status, created_at)
|
|
@@ -7692,7 +7798,7 @@ var session2 = null;
|
|
|
7692
7798
|
var isProcessing2 = false;
|
|
7693
7799
|
var PI_PROJECT_PATH2 = process.env.PI_PROJECT_PATH || "/tmp/maestro-telegram";
|
|
7694
7800
|
var PI_TIMEOUT_MS2 = parseInt(process.env.PI_TIMEOUT_MS || "300000", 10);
|
|
7695
|
-
function
|
|
7801
|
+
function nowIso6() {
|
|
7696
7802
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
7697
7803
|
}
|
|
7698
7804
|
async function ensureSession2() {
|
|
@@ -7726,7 +7832,7 @@ async function ensureSession2() {
|
|
|
7726
7832
|
return s;
|
|
7727
7833
|
}
|
|
7728
7834
|
function sendPrompt2(s, message) {
|
|
7729
|
-
return new Promise((
|
|
7835
|
+
return new Promise((resolve5, reject) => {
|
|
7730
7836
|
let responseText = "";
|
|
7731
7837
|
let done = false;
|
|
7732
7838
|
const timer4 = setTimeout(() => {
|
|
@@ -7750,7 +7856,7 @@ function sendPrompt2(s, message) {
|
|
|
7750
7856
|
reject(new Error(lastAssistant.errorMessage));
|
|
7751
7857
|
return;
|
|
7752
7858
|
}
|
|
7753
|
-
|
|
7859
|
+
resolve5(responseText.trim() || "Agent completed without text output.");
|
|
7754
7860
|
}
|
|
7755
7861
|
});
|
|
7756
7862
|
s.prompt(message).catch((err) => {
|
|
@@ -7800,7 +7906,7 @@ async function processNext2() {
|
|
|
7800
7906
|
if (msg.body.trim().toLowerCase() === "reset") {
|
|
7801
7907
|
await s.newSession();
|
|
7802
7908
|
await sendTelegramMessage(msg.chatId, "Session reset.");
|
|
7803
|
-
updateTelegramMessage(msg.id, { status: "completed", responseText: "Session reset.", processedAt:
|
|
7909
|
+
updateTelegramMessage(msg.id, { status: "completed", responseText: "Session reset.", processedAt: nowIso6() });
|
|
7804
7910
|
console.log("[telegram-queue] Session reset by user");
|
|
7805
7911
|
return;
|
|
7806
7912
|
}
|
|
@@ -7817,7 +7923,7 @@ async function processNext2() {
|
|
|
7817
7923
|
updateTelegramMessage(msg.id, {
|
|
7818
7924
|
status: "completed",
|
|
7819
7925
|
responseText,
|
|
7820
|
-
processedAt:
|
|
7926
|
+
processedAt: nowIso6()
|
|
7821
7927
|
});
|
|
7822
7928
|
console.log(`[telegram-queue] Completed message ${msg.id}`);
|
|
7823
7929
|
} catch (error) {
|
|
@@ -7826,7 +7932,7 @@ async function processNext2() {
|
|
|
7826
7932
|
updateTelegramMessage(msg.id, {
|
|
7827
7933
|
status: "failed",
|
|
7828
7934
|
error: errMsg,
|
|
7829
|
-
processedAt:
|
|
7935
|
+
processedAt: nowIso6()
|
|
7830
7936
|
});
|
|
7831
7937
|
} finally {
|
|
7832
7938
|
isProcessing2 = false;
|
|
@@ -7924,7 +8030,7 @@ async function main() {
|
|
|
7924
8030
|
await registerGitHubIntegrationRoutes(app);
|
|
7925
8031
|
await registerWebhookRoutes(app, io3);
|
|
7926
8032
|
await registerSettingsRoutes(app);
|
|
7927
|
-
await
|
|
8033
|
+
await registerMaestroUpdateRoutes(app);
|
|
7928
8034
|
await registerSetupRoutes(app);
|
|
7929
8035
|
await registerWhatsAppRoutes(app, io3);
|
|
7930
8036
|
await registerTelegramRoutes(app, io3, () => getSettings().telegramBotToken);
|