@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/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((resolve4) => {
831
+ () => new Promise((resolve5) => {
832
832
  this.terminal.write(data, () => {
833
833
  this.refreshSnapshot(cursor);
834
- resolve4();
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((resolve4) => {
853
- this.terminal.write(snapshot.data, resolve4);
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((resolve4, reject) => {
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
- resolve4({ code: codeMatch[1], url: urlMatch[1] });
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(path19, args) {
3311
+ function runGit2(path20, args) {
3312
3312
  return execFileSync6("git", args, {
3313
- cwd: path19,
3313
+ cwd: path20,
3314
3314
  encoding: "utf8",
3315
3315
  stdio: ["ignore", "pipe", "pipe"]
3316
3316
  }).trim();
3317
3317
  }
3318
- function tryRunGit(path19, args) {
3318
+ function tryRunGit(path20, args) {
3319
3319
  try {
3320
- return { ok: true, output: runGit2(path19, args) };
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(path19, currentBranch) {
3432
- const upstream = tryRunGit(path19, ["rev-parse", "--abbrev-ref", "@{upstream}"]);
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(path19, ["show-ref", "--verify", "--quiet", originBranch]);
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(path19, ref) {
3444
- return tryRunGit(path19, ["show-ref", "--verify", "--quiet", ref]).ok;
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 resolve4 = () => void 0;
3602
+ let resolve5 = () => void 0;
3603
3603
  const promise = new Promise((innerResolve) => {
3604
- resolve4 = innerResolve;
3604
+ resolve5 = innerResolve;
3605
3605
  });
3606
- return { promise, resolve: resolve4 };
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 resolve4 = rt.resolveExit;
3694
+ const resolve5 = rt.resolveExit;
3695
3695
  rt.resolveExit = null;
3696
- resolve4?.();
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 DeploymentReleaseInfo = z.object({
4372
- tag: z.string(),
4373
- name: z.string().nullable(),
4374
- url: z.string().nullable(),
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 DeploymentRedeployResponse = z.object({
4383
+ var MaestroUpdateTriggerResponse = z.object({
4390
4384
  accepted: z.boolean(),
4391
- targetVersion: z.string().nullable(),
4392
- message: z.string()
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/services/deployment-updater.ts
6814
- function getUpdaterConfig() {
6815
- const url = process.env.UPDATER_URL?.trim();
6816
- const token = process.env.UPDATER_TOKEN?.trim();
6817
- if (!url) {
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
- async function requestUpdater(path19, init) {
6839
- const config = getUpdaterConfig();
6840
- if (!config) {
6841
- throw new Error("Deployment updater is not configured");
6842
- }
6843
- const res = await fetch(`${config.url}${path19}`, {
6844
- ...init,
6845
- headers: {
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
- async function getDeploymentUpdateStatus() {
6861
- const config = getUpdaterConfig();
6862
- if (!config) {
6863
- return getDisabledStatus(
6864
- "Set UPDATER_URL on the Maestro server to enable release redeploys. UPDATER_TOKEN is optional on the internal network."
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 await requestUpdater("/status");
6869
- } catch (error) {
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
- configured: true,
6872
- currentVersion: null,
6873
- latestVersion: null,
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: null,
6877
- lastUpdatedAt: null,
6878
- lastError: error instanceof Error ? error.message : "Failed to reach the deployment updater",
6879
- latestRelease: null
6921
+ lastCheckedAt: state2.lastCheckedAt,
6922
+ lastUpdatedAt: state2.lastUpdatedAt,
6923
+ lastError: state2.lastError
6880
6924
  };
6881
6925
  }
6882
- }
6883
- async function checkDeploymentUpdateStatus() {
6884
- const config = getUpdaterConfig();
6885
- if (!config) {
6886
- return getDisabledStatus(
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
- async function triggerDeploymentRedeploy(tag) {
6895
- return requestUpdater("/redeploy", {
6896
- method: "POST",
6897
- body: JSON.stringify(tag ? { tag } : {}),
6898
- timeoutMs: 3e4
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
- // ../server/src/routes/deployment-routes.ts
6903
- async function registerDeploymentRoutes(app) {
6904
- app.get("/api/deployment/update-status", async () => {
6905
- return getDeploymentUpdateStatus();
6906
- });
6907
- app.post("/api/deployment/check", async () => {
6908
- return checkDeploymentUpdateStatus();
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
- app.post("/api/deployment/redeploy", async (req, reply) => {
6911
- try {
6912
- const body = req.body;
6913
- return await triggerDeploymentRedeploy(body?.tag);
6914
- } catch (error) {
6915
- const message = error instanceof Error ? error.message : "Failed to trigger redeploy";
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/main.ts
6923
- init_auth_status_checker();
6924
-
6925
- // ../server/src/routes/setup-routes.ts
6926
- async function registerSetupRoutes(app) {
6927
- app.get("/api/setup/status", async () => ({
6928
- needsSetup: false,
6929
- running: false
6930
- }));
6931
- app.post("/api/setup/reset", async () => {
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 os9 from "os";
6999
- import * as path16 from "path";
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 = path16.join(os9.homedir(), ".maestro");
7008
- var AUTH_DIR = path16.join(DATA_DIR, "whatsapp-auth");
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 fs15 from "fs";
7163
- import * as os10 from "os";
7164
- import * as path17 from "path";
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 = path17.join(os10.homedir(), ".maestro");
7168
- fs15.mkdirSync(DATA_DIR2, { recursive: true });
7169
- var dbPath2 = path17.join(DATA_DIR2, "pi.sqlite");
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 nowIso2() {
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 = nowIso2();
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 nowIso3() {
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((resolve4, reject) => {
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
- resolve4(responseText.trim() || "Agent completed without text output.");
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: nowIso3() });
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: nowIso3()
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: nowIso3()
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 fs16 from "fs";
7585
- import * as os11 from "os";
7586
- import * as path18 from "path";
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 = path18.join(os11.homedir(), ".maestro");
7590
- fs16.mkdirSync(DATA_DIR3, { recursive: true });
7591
- var dbPath3 = path18.join(DATA_DIR3, "pi.sqlite");
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 nowIso4() {
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 = nowIso4();
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 nowIso5() {
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((resolve4, reject) => {
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
- resolve4(responseText.trim() || "Agent completed without text output.");
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: nowIso5() });
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: nowIso5()
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: nowIso5()
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 registerDeploymentRoutes(app);
8033
+ await registerMaestroUpdateRoutes(app);
7928
8034
  await registerSetupRoutes(app);
7929
8035
  await registerWhatsAppRoutes(app, io3);
7930
8036
  await registerTelegramRoutes(app, io3, () => getSettings().telegramBotToken);