@rajat-rastogi/maestro 0.7.0 → 0.7.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.
@@ -589,8 +589,12 @@ class AgentConnectionPool {
589
589
  entry.ready = true;
590
590
  entry.queue.forEach((cb) => cb(ws));
591
591
  entry.queue = [];
592
+ console.log(`[AgentPool] heartbeat started for "${tunnelId}" (60s interval)`);
592
593
  entry.heartbeat = setInterval(() => {
593
- if (ws.readyState !== WebSocket.OPEN) return;
594
+ if (ws.readyState !== WebSocket.OPEN) {
595
+ console.log(`[AgentPool] heartbeat skip for "${tunnelId}" — ws not open (state: ${ws.readyState})`);
596
+ return;
597
+ }
594
598
  let gotPong = false;
595
599
  const handler = (data) => {
596
600
  try {
@@ -1476,16 +1480,15 @@ class AgentPtyAdapter {
1476
1480
  lastRows = 30;
1477
1481
  async handleConnectionLost() {
1478
1482
  if (this.dead) return;
1479
- if (this.reconnectAttempts < 3) {
1480
- this.reconnectAttempts++;
1481
- console.log(`[AgentPty] ${this.sessionId.slice(0, 8)} reconnecting (attempt ${this.reconnectAttempts}/3)...`);
1483
+ for (let attempt = 1; attempt <= 3; attempt++) {
1484
+ console.log(`[AgentPty] ${this.sessionId.slice(0, 8)} reconnecting (attempt ${attempt}/3)...`);
1482
1485
  if (this.dataCallback) {
1483
1486
  this.dataCallback(`\r
1484
- \x1B[1;33m[Maestro] Connection lost — reconnecting (${this.reconnectAttempts}/3)...\x1B[0m\r
1487
+ \x1B[1;33m[Maestro] Connection lost — reconnecting (${attempt}/3)...\x1B[0m\r
1485
1488
  `);
1486
1489
  }
1487
1490
  AgentConnectionPool.getInstance().releaseOne(this.tunnelId);
1488
- await new Promise((r) => setTimeout(r, 2e3 * this.reconnectAttempts));
1491
+ await new Promise((r) => setTimeout(r, 2e3 * attempt));
1489
1492
  try {
1490
1493
  this.ws = await AgentConnectionPool.getInstance().getConnection(this.tunnelId);
1491
1494
  if (this.messageHandler) {
@@ -1506,14 +1509,13 @@ class AgentPtyAdapter {
1506
1509
  cols: this.lastCols,
1507
1510
  rows: this.lastRows
1508
1511
  }));
1509
- this.reconnectAttempts = 0;
1510
1512
  console.log(`[AgentPty] ${this.sessionId.slice(0, 8)} reconnected successfully`);
1511
1513
  if (this.dataCallback) {
1512
1514
  this.dataCallback("\r\n\x1B[1;32m[Maestro] Reconnected to remote agent.\x1B[0m\r\n");
1513
1515
  }
1514
1516
  return;
1515
1517
  } catch (err) {
1516
- console.log(`[AgentPty] ${this.sessionId.slice(0, 8)} reconnect failed: ${err instanceof Error ? err.message : String(err)}`);
1518
+ console.log(`[AgentPty] ${this.sessionId.slice(0, 8)} reconnect attempt ${attempt} failed: ${err instanceof Error ? err.message : String(err)}`);
1517
1519
  }
1518
1520
  }
1519
1521
  this.dead = true;
@@ -1620,7 +1622,7 @@ class StateMonitor {
1620
1622
  if (this.copilotReady && data.length >= 20) {
1621
1623
  if (data.includes("Enter to select")) {
1622
1624
  this.emitState("permission", "heuristic", '"Enter to select" — input required');
1623
- } else if (data.includes("Esc to cancel") || data.includes("Esc to stop")) {
1625
+ } else if ((data.includes("Esc to cancel") || data.includes("Esc to stop")) && !this.lastEmittedState?.startsWith("permission")) {
1624
1626
  this.emitState("working", "heuristic", '"Esc to cancel/stop" — copilot working');
1625
1627
  } else if (data.includes("for shortcuts") || data.includes("Describe a task") || data.includes("to get started")) {
1626
1628
  this.emitState("waiting", "heuristic", "copilot prompt detected — at prompt");
@@ -9507,35 +9507,37 @@ function ConfigView() {
9507
9507
  spellCheck: false
9508
9508
  }
9509
9509
  ) }),
9510
- /* @__PURE__ */ jsxRuntimeExports.jsx(GuiSettingsPanel, {}),
9511
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$f.content, children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$f.loading, children: "Loading configuration…" }) : state ? /* @__PURE__ */ jsxRuntimeExports.jsx(
9512
- ConfigEditor,
9513
- {
9514
- state,
9515
- target,
9516
- dirtyValues,
9517
- searchQuery: search,
9518
- expandAll,
9519
- onExpandAllApplied: () => setExpandAll(null),
9520
- onChange: (key, value) => {
9521
- setDirtyValues((prev) => {
9522
- const next = { ...prev };
9523
- const mergedVal = state.merged[key];
9524
- const equal = Array.isArray(mergedVal) && Array.isArray(value) ? JSON.stringify(mergedVal) === JSON.stringify(value) : mergedVal === value;
9525
- if (equal) delete next[key];
9526
- else next[key] = value;
9527
- return next;
9528
- });
9529
- },
9530
- onReset: (key) => {
9531
- setDirtyValues((prev) => {
9532
- const next = { ...prev };
9533
- next[key] = state.defaults[key];
9534
- return next;
9535
- });
9510
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$f.content, children: [
9511
+ /* @__PURE__ */ jsxRuntimeExports.jsx(GuiSettingsSection, {}),
9512
+ loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$f.loading, children: "Loading configuration…" }) : state ? /* @__PURE__ */ jsxRuntimeExports.jsx(
9513
+ ConfigEditor,
9514
+ {
9515
+ state,
9516
+ target,
9517
+ dirtyValues,
9518
+ searchQuery: search,
9519
+ expandAll,
9520
+ onExpandAllApplied: () => setExpandAll(null),
9521
+ onChange: (key, value) => {
9522
+ setDirtyValues((prev) => {
9523
+ const next = { ...prev };
9524
+ const mergedVal = state.merged[key];
9525
+ const equal = Array.isArray(mergedVal) && Array.isArray(value) ? JSON.stringify(mergedVal) === JSON.stringify(value) : mergedVal === value;
9526
+ if (equal) delete next[key];
9527
+ else next[key] = value;
9528
+ return next;
9529
+ });
9530
+ },
9531
+ onReset: (key) => {
9532
+ setDirtyValues((prev) => {
9533
+ const next = { ...prev };
9534
+ next[key] = state.defaults[key];
9535
+ return next;
9536
+ });
9537
+ }
9536
9538
  }
9537
- }
9538
- ) : null }),
9539
+ ) : null
9540
+ ] }),
9539
9541
  toast && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: {
9540
9542
  ...styles$f.toast,
9541
9543
  borderColor: toast.isError ? "var(--red)" : "var(--green)",
@@ -9544,23 +9546,36 @@ function ConfigView() {
9544
9546
  }, children: toast.msg })
9545
9547
  ] });
9546
9548
  }
9547
- function GuiSettingsPanel() {
9549
+ function GuiSettingsSection() {
9548
9550
  const { statusToasts, setStatusToasts } = useGuiSettings();
9549
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$f.guiSettings, children: [
9550
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$f.guiSettingsTitle, children: "GUI Settings" }),
9551
- /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { style: styles$f.guiToggle, children: [
9552
- /* @__PURE__ */ jsxRuntimeExports.jsx(
9553
- "input",
9554
- {
9555
- type: "checkbox",
9556
- checked: statusToasts,
9557
- onChange: (e) => setStatusToasts(e.target.checked),
9558
- style: { accentColor: "var(--accent)", cursor: "pointer", margin: 0 }
9559
- }
9560
- ),
9561
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Status change notifications" }),
9562
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$f.guiToggleHint, children: "Show toast when a terminal changes state (Working Waiting, etc.)" })
9563
- ] })
9551
+ const [collapsed, setCollapsed] = React$2.useState(false);
9552
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { marginBottom: "2px" }, children: [
9553
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
9554
+ "div",
9555
+ {
9556
+ style: styles$f.guiSectionHeader,
9557
+ onClick: () => setCollapsed((v2) => !v2),
9558
+ children: [
9559
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { fontSize: "10px", color: "var(--text-muted)" }, children: collapsed ? "▶" : "▼" }),
9560
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { flex: 1, fontSize: "13px", fontWeight: 600 }, children: "GUI Settings" })
9561
+ ]
9562
+ }
9563
+ ),
9564
+ !collapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$f.guiSectionBody, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$f.guiFieldRow, children: [
9565
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$f.guiFieldLabel, children: "Status change notifications" }),
9566
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { style: styles$f.guiFieldControl, children: [
9567
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
9568
+ "input",
9569
+ {
9570
+ type: "checkbox",
9571
+ checked: statusToasts,
9572
+ onChange: (e) => setStatusToasts(e.target.checked),
9573
+ style: { accentColor: "var(--accent)", cursor: "pointer", margin: 0 }
9574
+ }
9575
+ ),
9576
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { fontSize: "12px", color: "var(--text-secondary)" }, children: "Show toast when a terminal changes state" })
9577
+ ] })
9578
+ ] }) })
9564
9579
  ] });
9565
9580
  }
9566
9581
  const styles$f = {
@@ -9571,34 +9586,37 @@ const styles$f = {
9571
9586
  overflow: "hidden",
9572
9587
  background: "var(--bg-base)"
9573
9588
  },
9574
- guiSettings: {
9589
+ guiSectionHeader: {
9575
9590
  display: "flex",
9576
9591
  alignItems: "center",
9577
- gap: "12px",
9578
- padding: "8px 14px",
9579
- background: "var(--bg-surface)",
9580
- borderBottom: "1px solid var(--border-subtle)",
9581
- flexShrink: 0
9592
+ gap: "6px",
9593
+ padding: "7px 10px",
9594
+ background: "var(--bg-elevated)",
9595
+ cursor: "pointer",
9596
+ userSelect: "none",
9597
+ borderBottom: "1px solid var(--border-subtle)"
9598
+ },
9599
+ guiSectionBody: {
9600
+ padding: "2px 0"
9601
+ },
9602
+ guiFieldRow: {
9603
+ display: "grid",
9604
+ gridTemplateColumns: "200px 1fr",
9605
+ alignItems: "center",
9606
+ padding: "6px 10px",
9607
+ gap: "8px"
9582
9608
  },
9583
- guiSettingsTitle: {
9609
+ guiFieldLabel: {
9584
9610
  fontSize: "12px",
9585
- fontWeight: 600,
9586
- color: "var(--text-secondary)",
9587
- flexShrink: 0
9611
+ fontWeight: 500,
9612
+ color: "var(--text-primary)"
9588
9613
  },
9589
- guiToggle: {
9614
+ guiFieldControl: {
9590
9615
  display: "flex",
9591
9616
  alignItems: "center",
9592
9617
  gap: "6px",
9593
- fontSize: "12px",
9594
- color: "var(--text-primary)",
9595
9618
  cursor: "pointer"
9596
9619
  },
9597
- guiToggleHint: {
9598
- fontSize: "11px",
9599
- color: "var(--text-muted)",
9600
- marginLeft: "4px"
9601
- },
9602
9620
  header: {
9603
9621
  display: "flex",
9604
9622
  alignItems: "center",
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src http://localhost:*" />
7
7
  <title>Maestro</title>
8
- <script type="module" crossorigin src="./assets/index-Qk1FvqkV.js"></script>
8
+ <script type="module" crossorigin src="./assets/index-DZMXfRx7.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="./assets/index-DBLgxEKP.css">
10
10
  </head>
11
11
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rajat-rastogi/maestro",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Conduct your codebase — autonomous AI coding orchestrator",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",