esque-bridge 0.6.2 → 0.6.3

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.
Files changed (2) hide show
  1. package/index.js +33 -6
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -709,22 +709,26 @@ const PREVIEW_RE = /^[ \t>*`-]*ESQUE_PREVIEW:\s*(.+?)\s*@\s*(\d+)\s*`?[ \t]*$/im
709
709
 
710
710
  // If the agent's reply declares a preview, start it (bridge-owned) and
711
711
  // swap the marker line for the public URL the phone can open.
712
+ // Returns { text, buildError }. `buildError` is the short failure summary when
713
+ // the declared preview started but its web bundle didn't compile (else null) —
714
+ // the caller uses it to drive the auto-fix loop.
712
715
  async function applyPreview(text) {
713
- if (!text) return text;
716
+ if (!text) return { text, buildError: null };
714
717
  const m = text.match(PREVIEW_RE);
715
- if (!m) return text;
718
+ if (!m) return { text, buildError: null };
716
719
  const cmd = m[1].trim();
717
720
  const port = Number(m[2]);
718
721
  let result = null;
719
722
  try { result = await startPreview(cmd, port); } catch (e) { console.error('[preview] error:', e.message); }
720
723
  let replacement;
724
+ let buildError = null;
721
725
  if (!result) {
722
726
  replacement = `(Couldn't auto-start the preview — run \`${cmd}\` in ${WORKDIR} yourself.)`;
723
727
  } else if (result.buildError) {
728
+ buildError = result.buildError;
724
729
  // Surface the failure as plain text WITHOUT the URL — the app turns any
725
730
  // URL in a message into a "Preview Build" pill, and we don't want a pill
726
- // that just opens a blank page. The error tells the user (and the agent,
727
- // who sees this reply) exactly what to fix.
731
+ // that just opens a blank page.
728
732
  replacement =
729
733
  `⚠️ Preview build failed — the web bundle didn't compile:\n\n` +
730
734
  `${result.buildError}\n\n` +
@@ -732,12 +736,35 @@ async function applyPreview(text) {
732
736
  } else {
733
737
  replacement = `🔗 Live preview: ${result.url}`;
734
738
  }
735
- return text.replace(PREVIEW_RE, replacement);
739
+ return { text: text.replace(PREVIEW_RE, replacement), buildError };
736
740
  }
737
741
 
738
742
  async function runAgentWithPreview(prompt, sessionId) {
739
743
  const result = await runAgent(prompt, sessionId);
740
- if (result && result.text) result.text = await applyPreview(result.text);
744
+ if (!result || !result.text) return result;
745
+
746
+ const applied = await applyPreview(result.text);
747
+ result.text = applied.text;
748
+
749
+ // Auto-fix (one retry): the agent's own session history never saw our
750
+ // rewritten reply, so if the preview failed to build we hand the error back
751
+ // to the agent — same session (--resume), so it has full context — and let
752
+ // it fix the cause and re-emit the marker. Bounded at a single retry so a
753
+ // stubborn error can't loop.
754
+ if (applied.buildError) {
755
+ console.log('[preview] build failed — handing the error back to the agent (1 retry)');
756
+ const fixPrompt =
757
+ `The live preview you just started failed to build with this error:\n\n` +
758
+ `${applied.buildError}\n\n` +
759
+ `Fix the root cause in the code, then re-emit the ESQUE_PREVIEW marker on ` +
760
+ `its own line. Keep the explanation brief — make the fix and output the marker.`;
761
+ let fix = null;
762
+ try { fix = await runAgent(fixPrompt, sessionId); } catch (e) { console.error('[preview] auto-fix run failed:', e.message); }
763
+ if (fix && fix.text) {
764
+ const fixApplied = await applyPreview(fix.text);
765
+ result.text = `${applied.text}\n\n— Auto-fix attempt —\n${fixApplied.text}`;
766
+ }
767
+ }
741
768
  return result;
742
769
  }
743
770
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "esque-bridge",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "Desktop-side receiver for the Esque Agent mobile app. Pairs your phone with a local coding-agent CLI (Claude Code, Codex, Aider, or any custom command) via a tunnel + QR code, so prompts run through your subscription instead of per-token API billing.",
5
5
  "bin": {
6
6
  "esque-bridge": "index.js"