@aayambansal/squint 0.7.2 → 0.8.0

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 (29) hide show
  1. package/README.md +3 -2
  2. package/dist/{App-W2U3EUM6.js → App-I2MB7S6W.js} +10 -10
  3. package/dist/{cdp-V47GTLXG.js → cdp-DV4D6PUL.js} +5 -3
  4. package/dist/{checks-2XOF2K3L.js → checks-4OK5YYGW.js} +1 -1
  5. package/dist/{chrome-CAN7TVH6.js → chrome-BQ4WOCOH.js} +2 -2
  6. package/dist/{chunk-PZV2FJE5.js → chunk-55JZKI2M.js} +1 -1
  7. package/dist/{chunk-GDGKEMBS.js → chunk-7FSHVRBS.js} +1 -1
  8. package/dist/{chunk-ZNV63ZIK.js → chunk-GAWQ7YXC.js} +2 -2
  9. package/dist/{chunk-S7LDOWMS.js → chunk-HFQZDT65.js} +48 -4
  10. package/dist/{chunk-DABIMOMV.js → chunk-HIUQ4FXO.js} +36 -2
  11. package/dist/{chunk-AM7WBP3P.js → chunk-ODSCWVBX.js} +13 -12
  12. package/dist/{chunk-W72LUSYS.js → chunk-OSKYU4PM.js} +1 -1
  13. package/dist/{chunk-GE6UL6C7.js → chunk-PC45PRK3.js} +5 -5
  14. package/dist/{chunk-JGBWTFU6.js → chunk-USAZFY36.js} +2 -2
  15. package/dist/{chunk-CGOFK6EM.js → chunk-WOPJFP4M.js} +2 -2
  16. package/dist/{chunk-KNPLVGZB.js → chunk-YKEAKVIS.js} +3 -3
  17. package/dist/{chunk-DOWWBLX2.js → chunk-Z7TPFGGR.js} +3 -2
  18. package/dist/cli.js +29 -29
  19. package/dist/{flows-SYDNB5IW.js → flows-XORMW4DA.js} +1 -1
  20. package/dist/{preview-NPLDCOP6.js → preview-CDSJ5WBQ.js} +5 -5
  21. package/dist/{receipts-MCEUXL6I.js → receipts-HMBEL7NM.js} +1 -1
  22. package/dist/{registry-ZCCZVXSX.js → registry-GYWEHK4R.js} +1 -1
  23. package/dist/{remote-TDNUUOUN.js → remote-WLUNMQRO.js} +10 -10
  24. package/dist/{run-IAA2C5LM.js → run-QZA57WPI.js} +2 -2
  25. package/dist/{server-QSU4H564.js → server-PSXRO2XN.js} +11 -10
  26. package/dist/shots-MZXB7VQT.js +13 -0
  27. package/dist/{variants-WBRY2U37.js → variants-RJPANXPH.js} +3 -3
  28. package/package.json +1 -1
  29. package/dist/shots-HDHPCENU.js +0 -13
package/README.md CHANGED
@@ -104,8 +104,9 @@ From source: `git clone https://github.com/aayambansal/squint.git && cd squint &
104
104
  | Codex CLI | `codex` | `npm i -g @openai/codex` |
105
105
  | Codex (app-server) | `codex-app` | same binary — drives the published JSON-RPC protocol |
106
106
  | Gemini CLI | `gemini` | `npm i -g @google/gemini-cli` |
107
+ | Antigravity CLI | `antigravity` | `curl -fsSL https://antigravity.google/cli/install.sh \| bash` |
107
108
  | OpenCode | `opencode` | `npm i -g opencode-ai` |
108
- | Amp | `amp` | `npm i -g @sourcegraph/amp` |
109
+ | Amp | `amp` | `npm i -g @ampcode/cli` |
109
110
  | Cursor CLI | `cursor` | `curl https://cursor.com/install -fsS \| bash` |
110
111
  | Copilot CLI | `copilot` | `npm i -g @github/copilot` |
111
112
  | Aider | `aider` | `pip install aider-install && aider-install` |
@@ -244,7 +245,7 @@ and an avoid-list tuned to that family's failure modes. Plain markdown, made to
244
245
  | stream | | headless screenshots |
245
246
  +------+-------+ +-------------------------+
246
247
  |
247
- claude . codex . codex-app . gemini . opencode . amp . cursor . copilot . aider
248
+ claude . codex . codex-app . gemini . antigravity . opencode . amp . cursor . copilot . aider
248
249
  ```
249
250
 
250
251
  Engines are dumb translators: build a headless invocation, parse the stream into one
@@ -1,25 +1,25 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  App
4
- } from "./chunk-W72LUSYS.js";
5
- import "./chunk-AM7WBP3P.js";
6
- import "./chunk-KNPLVGZB.js";
4
+ } from "./chunk-OSKYU4PM.js";
5
+ import "./chunk-ODSCWVBX.js";
6
+ import "./chunk-YKEAKVIS.js";
7
7
  import "./chunk-LNJ7O5O4.js";
8
- import "./chunk-GE6UL6C7.js";
8
+ import "./chunk-PC45PRK3.js";
9
9
  import "./chunk-UBADCBPT.js";
10
10
  import "./chunk-IEQGTVWN.js";
11
11
  import "./chunk-AUJJGMZG.js";
12
12
  import "./chunk-YHRAOBI2.js";
13
- import "./chunk-GDGKEMBS.js";
14
- import "./chunk-DOWWBLX2.js";
13
+ import "./chunk-7FSHVRBS.js";
14
+ import "./chunk-Z7TPFGGR.js";
15
15
  import "./chunk-K5QJMSJH.js";
16
16
  import "./chunk-WAJXATCO.js";
17
17
  import "./chunk-62JNF5M2.js";
18
18
  import "./chunk-7CAGWFAQ.js";
19
- import "./chunk-S7LDOWMS.js";
20
- import "./chunk-PZV2FJE5.js";
21
- import "./chunk-DABIMOMV.js";
22
- import "./chunk-ZNV63ZIK.js";
19
+ import "./chunk-HFQZDT65.js";
20
+ import "./chunk-55JZKI2M.js";
21
+ import "./chunk-HIUQ4FXO.js";
22
+ import "./chunk-GAWQ7YXC.js";
23
23
  export {
24
24
  App
25
25
  };
@@ -4,12 +4,14 @@ import {
4
4
  hasWebSocket,
5
5
  pixelDiffAttributed,
6
6
  pixelDiffPct,
7
- runFlow
8
- } from "./chunk-S7LDOWMS.js";
7
+ runFlow,
8
+ summarizeSoftNav
9
+ } from "./chunk-HFQZDT65.js";
9
10
  export {
10
11
  cdpCapture,
11
12
  hasWebSocket,
12
13
  pixelDiffAttributed,
13
14
  pixelDiffPct,
14
- runFlow
15
+ runFlow,
16
+ summarizeSoftNav
15
17
  };
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  loadChecks,
4
4
  runIntervalSweep
5
- } from "./chunk-ZNV63ZIK.js";
5
+ } from "./chunk-GAWQ7YXC.js";
6
6
  export {
7
7
  loadChecks,
8
8
  runIntervalSweep
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  findChrome,
4
4
  screenshot
5
- } from "./chunk-PZV2FJE5.js";
6
- import "./chunk-DABIMOMV.js";
5
+ } from "./chunk-55JZKI2M.js";
6
+ import "./chunk-HIUQ4FXO.js";
7
7
  export {
8
8
  findChrome,
9
9
  screenshot
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  findBinary
4
- } from "./chunk-DABIMOMV.js";
4
+ } from "./chunk-HIUQ4FXO.js";
5
5
 
6
6
  // src/preview/chrome.ts
7
7
  import { spawn } from "child_process";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runAgent
4
- } from "./chunk-DOWWBLX2.js";
4
+ } from "./chunk-Z7TPFGGR.js";
5
5
  import {
6
6
  FAMILIES,
7
7
  renderFamilyBrief
@@ -40,11 +40,11 @@ async function runIntervalSweep(cwd, url, lastRun) {
40
40
  );
41
41
  if (due.length === 0) return [];
42
42
  for (const check of due) lastRun.set(check.name, now);
43
- const { findChrome } = await import("./chrome-CAN7TVH6.js");
43
+ const { findChrome } = await import("./chrome-BQ4WOCOH.js");
44
44
  const chrome = findChrome();
45
45
  if (!chrome) return [];
46
46
  const os = await import("os");
47
- const { cdpCapture } = await import("./cdp-V47GTLXG.js");
47
+ const { cdpCapture } = await import("./cdp-DV4D6PUL.js");
48
48
  const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "squint-interval-"));
49
49
  try {
50
50
  const result = await cdpCapture(chrome, url, tmp, [], 800, false, due);
@@ -178,10 +178,43 @@ var describe = (value) => {
178
178
  }
179
179
  return String(value);
180
180
  };
181
+ var SOFTNAV_SHIM = `(() => {
182
+ window.__squintSoftNav = [];
183
+ const push = (type, e) => window.__squintSoftNav.push({
184
+ type,
185
+ navigationId: e.navigationId || '',
186
+ start: Math.round(e.startTime),
187
+ value: Math.round(e.renderTime || e.duration || 0),
188
+ url: e.name || '',
189
+ });
190
+ try {
191
+ new PerformanceObserver((l) => l.getEntries().forEach((e) => push('soft-navigation', e)))
192
+ .observe({ type: 'soft-navigation', buffered: true });
193
+ new PerformanceObserver((l) => l.getEntries().forEach((e) => push('icp', e)))
194
+ .observe({ type: 'interaction-contentful-paint', buffered: true });
195
+ } catch {}
196
+ })()`;
197
+ function summarizeSoftNav(entries) {
198
+ const byNav = /* @__PURE__ */ new Map();
199
+ for (const entry of entries) {
200
+ if (entry.type === "soft-navigation") {
201
+ byNav.set(entry.navigationId, { url: entry.url, start: entry.start, ...byNav.get(entry.navigationId) });
202
+ } else if (entry.type === "icp" && entry.navigationId) {
203
+ const nav = byNav.get(entry.navigationId) ?? { url: "", start: 0 };
204
+ nav.icp = Math.max(nav.icp ?? 0, entry.value);
205
+ byNav.set(entry.navigationId, nav);
206
+ }
207
+ }
208
+ return [...byNav.values()].sort((a, b) => a.start - b.start).map((nav) => {
209
+ const route = nav.url ? new URL(nav.url, "http://x").pathname : "?";
210
+ return `soft-nav \u2192 ${route}${nav.icp !== void 0 ? ` \xB7 ICP ${nav.icp}ms` : ""}`;
211
+ });
212
+ }
181
213
  async function runFlow(chromePath, baseUrl, flow, outDir) {
182
- const { stepExpression } = await import("./flows-SYDNB5IW.js");
214
+ const { stepExpression } = await import("./flows-XORMW4DA.js");
183
215
  const { child, wsUrl, profileDir } = await launchChrome(chromePath);
184
216
  const shots = [];
217
+ let transitions = [];
185
218
  let connection = null;
186
219
  try {
187
220
  connection = await CdpConnection.connect(wsUrl, 1e4);
@@ -190,6 +223,7 @@ async function runFlow(chromePath, baseUrl, flow, outDir) {
190
223
  await connection.send("Page.enable", {}, sessionId);
191
224
  await connection.send("Page.addScriptToEvaluateOnNewDocument", { source: WEBMCP_SHIM }, sessionId).catch(() => null);
192
225
  await connection.send("Page.addScriptToEvaluateOnNewDocument", { source: LOAF_SHIM }, sessionId).catch(() => null);
226
+ await connection.send("Page.addScriptToEvaluateOnNewDocument", { source: SOFTNAV_SHIM }, sessionId).catch(() => null);
193
227
  await connection.send(
194
228
  "Emulation.setDeviceMetricsOverride",
195
229
  { width: 1280, height: 800, deviceScaleFactor: 1, mobile: false },
@@ -225,13 +259,22 @@ async function runFlow(chromePath, baseUrl, flow, outDir) {
225
259
  );
226
260
  const value = result?.value;
227
261
  if (!value?.ok) {
228
- return { ok: false, failedStep: stepNumber, detail: value?.detail ?? "step failed", shots };
262
+ return { ok: false, failedStep: stepNumber, detail: value?.detail ?? "step failed", shots, transitions };
229
263
  }
230
264
  await new Promise((resolve) => setTimeout(resolve, 300));
231
265
  }
232
- return { ok: true, shots };
266
+ try {
267
+ const { result } = await connection.send(
268
+ "Runtime.evaluate",
269
+ { expression: "window.__squintSoftNav || []", returnByValue: true },
270
+ sessionId
271
+ );
272
+ if (Array.isArray(result?.value)) transitions = summarizeSoftNav(result.value);
273
+ } catch {
274
+ }
275
+ return { ok: true, shots, transitions };
233
276
  } catch (err) {
234
- return { ok: false, detail: err instanceof Error ? err.message : String(err), shots };
277
+ return { ok: false, detail: err instanceof Error ? err.message : String(err), shots, transitions };
235
278
  } finally {
236
279
  connection?.close();
237
280
  child.kill("SIGKILL");
@@ -963,6 +1006,7 @@ async function cdpCapture(chromePath, url, outDir, viewports, settleMs = 2500, a
963
1006
 
964
1007
  export {
965
1008
  hasWebSocket,
1009
+ summarizeSoftNav,
966
1010
  runFlow,
967
1011
  pixelDiffAttributed,
968
1012
  pixelDiffPct,
@@ -131,7 +131,7 @@ var amp = {
131
131
  id: "amp",
132
132
  name: "Amp",
133
133
  binary: "amp",
134
- install: "npm install -g @sourcegraph/amp",
134
+ install: "npm install -g @ampcode/cli",
135
135
  supportsResume: true,
136
136
  buildArgs(opts) {
137
137
  const args = opts.sessionId ? ["threads", "continue", "--execute", opts.prompt, "--stream-json"] : ["-x", opts.prompt, "--stream-json"];
@@ -141,6 +141,40 @@ var amp = {
141
141
  createParser: () => createClaudeStreamParser("amp")
142
142
  };
143
143
 
144
+ // src/engines/antigravity.ts
145
+ var ANSI_RE = /\x1b\[[0-9;?]*[a-zA-Z]|\x1b\][^\x07]*\x07|\x1b[()][0-9A-B]/g;
146
+ var shellQuote = (arg) => `'${arg.replace(/'/g, `'\\''`)}'`;
147
+ var antigravity = {
148
+ id: "antigravity",
149
+ name: "Antigravity CLI",
150
+ binary: "agy",
151
+ install: "curl -fsSL https://antigravity.google/cli/install.sh | bash",
152
+ supportsResume: true,
153
+ buildArgs(opts) {
154
+ const args = ["-p", opts.prompt];
155
+ if (opts.mode === "plan") args.push("--sandbox");
156
+ if (opts.mode === "yolo") args.push("--dangerously-skip-permissions");
157
+ if (opts.model) args.push("-m", opts.model);
158
+ if (opts.sessionId) args.push("--conversation", opts.sessionId);
159
+ return args;
160
+ },
161
+ wrapCommand(binaryPath, args) {
162
+ if (process.platform === "darwin") {
163
+ return { binary: "script", args: ["-q", "/dev/null", binaryPath, ...args] };
164
+ }
165
+ const command = [binaryPath, ...args].map(shellQuote).join(" ");
166
+ return { binary: "script", args: ["-qec", command, "/dev/null"] };
167
+ },
168
+ createParser() {
169
+ return (line) => {
170
+ const clean = line.replace(ANSI_RE, "").replace(/\r/g, "").trimEnd();
171
+ if (clean.trim().length === 0) return [];
172
+ if (/^[⠁⠂⠄⡀⢀⠠⠐⠈▐▌│┃⣿]+$/.test(clean.trim())) return [];
173
+ return [{ type: "text", text: clean }];
174
+ };
175
+ }
176
+ };
177
+
144
178
  // src/engines/claude.ts
145
179
  var claude = {
146
180
  id: "claude",
@@ -554,7 +588,7 @@ var opencode = {
554
588
  };
555
589
 
556
590
  // src/engines/registry.ts
557
- var engines = [claude, codex, codexApp, gemini, opencode, amp, cursor, copilot, aider];
591
+ var engines = [claude, codex, codexApp, gemini, antigravity, opencode, amp, cursor, copilot, aider];
558
592
  function getEngine(id) {
559
593
  const engine = engines.find((e) => e.id === id);
560
594
  if (!engine) {
@@ -4,7 +4,7 @@ import {
4
4
  buildFixPrompt,
5
5
  detectDevCommand,
6
6
  screenshotVariants
7
- } from "./chunk-KNPLVGZB.js";
7
+ } from "./chunk-YKEAKVIS.js";
8
8
  import {
9
9
  buildReviewPrompt,
10
10
  buildRuntimeFixPrompt,
@@ -12,7 +12,7 @@ import {
12
12
  comparePulseAttributed,
13
13
  probeRuntime,
14
14
  runtimeSummary
15
- } from "./chunk-GE6UL6C7.js";
15
+ } from "./chunk-PC45PRK3.js";
16
16
  import {
17
17
  enrich
18
18
  } from "./chunk-UBADCBPT.js";
@@ -39,10 +39,10 @@ import {
39
39
  cleanVariants,
40
40
  listVariants,
41
41
  runVariants
42
- } from "./chunk-GDGKEMBS.js";
42
+ } from "./chunk-7FSHVRBS.js";
43
43
  import {
44
44
  runAgent
45
- } from "./chunk-DOWWBLX2.js";
45
+ } from "./chunk-Z7TPFGGR.js";
46
46
  import {
47
47
  composePrompt
48
48
  } from "./chunk-WAJXATCO.js";
@@ -59,10 +59,10 @@ import {
59
59
  } from "./chunk-7CAGWFAQ.js";
60
60
  import {
61
61
  findChrome
62
- } from "./chunk-PZV2FJE5.js";
62
+ } from "./chunk-55JZKI2M.js";
63
63
  import {
64
64
  getEngine
65
- } from "./chunk-DABIMOMV.js";
65
+ } from "./chunk-HIUQ4FXO.js";
66
66
 
67
67
  // src/session/engine.ts
68
68
  import fs2 from "fs";
@@ -812,7 +812,7 @@ squint verifies every turn \u2014 gates, runtime probe, page audits. Do not decl
812
812
  this.push("image", pulsePath);
813
813
  return null;
814
814
  }
815
- const { previewDir } = await import("./preview-NPLDCOP6.js");
815
+ const { previewDir } = await import("./preview-CDSJ5WBQ.js");
816
816
  const diff = await comparePulseAttributed(
817
817
  previous,
818
818
  current,
@@ -922,7 +922,7 @@ They are objective defects, not style preferences.`
922
922
  const arg = rest.join(" ").trim();
923
923
  switch (name) {
924
924
  case "engines": {
925
- void import("./registry-ZCCZVXSX.js").then(({ detectEngines }) => {
925
+ void import("./registry-GYWEHK4R.js").then(({ detectEngines }) => {
926
926
  const lines = detectEngines().map(({ engine, path: binaryPath }) => {
927
927
  const mark = binaryPath ? "\u2713" : "\u2717";
928
928
  const traits = [engine.createParser ? "stream" : "text", engine.supportsResume ? "resume" : null].filter(Boolean).join(" \xB7 ");
@@ -1190,7 +1190,7 @@ every ask now carries it; auto-fix presses to ${MAX_GOAL_FIX_ATTEMPTS} attempts
1190
1190
  this.push("error", "no Chrome/Chromium found");
1191
1191
  return;
1192
1192
  }
1193
- const { suggestFlows } = await import("./flows-SYDNB5IW.js");
1193
+ const { suggestFlows } = await import("./flows-XORMW4DA.js");
1194
1194
  this.push("status", "drafting flows from the live routes\u2026");
1195
1195
  const { created, skipped } = await suggestFlows(this.opts.cwd, this.state.devUrl, chrome);
1196
1196
  if (created.length > 0) this.push("status", `drafted ${created.length} flow(s): ${created.join(", ")} \u2014 edit .squint/flows/*.flow or ask the engine to deepen them`);
@@ -1200,7 +1200,7 @@ every ask now carries it; auto-fix presses to ${MAX_GOAL_FIX_ATTEMPTS} attempts
1200
1200
  break;
1201
1201
  }
1202
1202
  void (async () => {
1203
- const { loadFlows } = await import("./flows-SYDNB5IW.js");
1203
+ const { loadFlows } = await import("./flows-XORMW4DA.js");
1204
1204
  const flows = loadFlows(this.opts.cwd);
1205
1205
  if (flows.length === 0) {
1206
1206
  this.push("status", "no flows \u2014 add .squint/flows/<name>.flow (goto/click/fill/press/expect/shot lines), or ask the engine to write one");
@@ -1211,8 +1211,8 @@ every ask now carries it; auto-fix presses to ${MAX_GOAL_FIX_ATTEMPTS} attempts
1211
1211
  this.push("error", "no Chrome/Chromium found for flows");
1212
1212
  return;
1213
1213
  }
1214
- const { runFlow } = await import("./cdp-V47GTLXG.js");
1215
- const { previewDir } = await import("./preview-NPLDCOP6.js");
1214
+ const { runFlow } = await import("./cdp-DV4D6PUL.js");
1215
+ const { previewDir } = await import("./preview-CDSJ5WBQ.js");
1216
1216
  this.push("status", `replaying ${flows.length} flow(s)\u2026`);
1217
1217
  this.notify({ running: true, runStartedAt: Date.now() });
1218
1218
  const failures = [];
@@ -1222,6 +1222,7 @@ every ask now carries it; auto-fix presses to ${MAX_GOAL_FIX_ATTEMPTS} attempts
1222
1222
  const result = await runFlow(chrome, this.state.devUrl, flow, previewDir(this.opts.cwd));
1223
1223
  if (result.ok) {
1224
1224
  this.push("status", `\u2713 flow ${flow.name} \xB7 ${flow.steps.length} steps${result.shots.length > 0 ? ` \xB7 ${result.shots.length} shot(s)` : ""}`);
1225
+ if (result.transitions.length > 0) this.push("status", result.transitions.map((t) => ` ${t}`).join("\n"));
1225
1226
  for (const shot of result.shots) this.push("image", shot);
1226
1227
  } else {
1227
1228
  const where = result.failedStep ? ` at step ${result.failedStep}` : "";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  Session
4
- } from "./chunk-AM7WBP3P.js";
4
+ } from "./chunk-ODSCWVBX.js";
5
5
  import {
6
6
  completeCommand
7
7
  } from "./chunk-LNJ7O5O4.js";
@@ -5,14 +5,14 @@ import {
5
5
  import {
6
6
  cdpCapture,
7
7
  hasWebSocket
8
- } from "./chunk-S7LDOWMS.js";
8
+ } from "./chunk-HFQZDT65.js";
9
9
  import {
10
10
  findChrome,
11
11
  screenshot
12
- } from "./chunk-PZV2FJE5.js";
12
+ } from "./chunk-55JZKI2M.js";
13
13
  import {
14
14
  loadChecks
15
- } from "./chunk-ZNV63ZIK.js";
15
+ } from "./chunk-GAWQ7YXC.js";
16
16
 
17
17
  // src/preview/preview.ts
18
18
  import fs from "fs";
@@ -139,13 +139,13 @@ async function probeRuntime(url, cwd) {
139
139
  async function comparePulse(previous, current) {
140
140
  const chrome = findChrome();
141
141
  if (!chrome || !hasWebSocket()) return null;
142
- const { pixelDiffPct } = await import("./cdp-V47GTLXG.js");
142
+ const { pixelDiffPct } = await import("./cdp-DV4D6PUL.js");
143
143
  return pixelDiffPct(chrome, previous, current);
144
144
  }
145
145
  async function comparePulseAttributed(previous, current, url, outPath) {
146
146
  const chrome = findChrome();
147
147
  if (!chrome || !hasWebSocket()) return null;
148
- const { pixelDiffAttributed } = await import("./cdp-V47GTLXG.js");
148
+ const { pixelDiffAttributed } = await import("./cdp-DV4D6PUL.js");
149
149
  return pixelDiffAttributed(chrome, previous, current, url, outPath);
150
150
  }
151
151
  function buildRuntimeFixPrompt(report) {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  Session
4
- } from "./chunk-AM7WBP3P.js";
4
+ } from "./chunk-ODSCWVBX.js";
5
5
 
6
6
  // src/daemon/client.ts
7
7
  import net from "net";
@@ -122,7 +122,7 @@ function startDaemon(opts) {
122
122
  const state = session.getState();
123
123
  if (!state.devUrl || state.running) return;
124
124
  try {
125
- const { runIntervalSweep } = await import("./checks-2XOF2K3L.js");
125
+ const { runIntervalSweep } = await import("./checks-4OK5YYGW.js");
126
126
  const failures = await runIntervalSweep(opts.cwd, state.devUrl, lastRun);
127
127
  if (failures.length > 0) {
128
128
  session.note(`\u23F0 interval check(s) failing:
@@ -143,8 +143,8 @@ function stepExpression(step) {
143
143
  async function suggestFlows(cwd, baseUrl, chromePath) {
144
144
  const fs2 = await import("fs");
145
145
  const path2 = await import("path");
146
- const { cdpCapture } = await import("./cdp-V47GTLXG.js");
147
- const { loadRoutes } = await import("./preview-NPLDCOP6.js");
146
+ const { cdpCapture } = await import("./cdp-DV4D6PUL.js");
147
+ const { loadRoutes } = await import("./preview-CDSJ5WBQ.js");
148
148
  const dir = path2.join(cwd, ".squint", "flows");
149
149
  fs2.mkdirSync(dir, { recursive: true });
150
150
  const created = [];
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  variantsRoot
4
- } from "./chunk-GDGKEMBS.js";
4
+ } from "./chunk-7FSHVRBS.js";
5
5
  import {
6
6
  findChrome,
7
7
  screenshot
8
- } from "./chunk-PZV2FJE5.js";
8
+ } from "./chunk-55JZKI2M.js";
9
9
  import {
10
10
  lineSplitter
11
- } from "./chunk-DABIMOMV.js";
11
+ } from "./chunk-HIUQ4FXO.js";
12
12
 
13
13
  // src/variants/shots.ts
14
14
  import path2 from "path";
@@ -3,7 +3,7 @@ import {
3
3
  findEngineBinary,
4
4
  lineSplitter,
5
5
  truncate
6
- } from "./chunk-DABIMOMV.js";
6
+ } from "./chunk-HIUQ4FXO.js";
7
7
 
8
8
  // src/runner/run.ts
9
9
  import { spawn } from "child_process";
@@ -19,7 +19,8 @@ function runAgent(engine, opts, onEvent, signal) {
19
19
  const startedAt = Date.now();
20
20
  let result = null;
21
21
  let stderrTail = "";
22
- const child = spawn(binaryPath, engine.buildArgs(opts), {
22
+ const command = engine.wrapCommand ? engine.wrapCommand(binaryPath, engine.buildArgs(opts)) : { binary: binaryPath, args: engine.buildArgs(opts) };
23
+ const child = spawn(command.binary, command.args, {
23
24
  cwd: opts.cwd,
24
25
  env: { ...process.env, ...engine.env },
25
26
  stdio: ["ignore", "pipe", "pipe"]
package/dist/cli.js CHANGED
@@ -3,35 +3,35 @@ import {
3
3
  connectDaemon,
4
4
  socketPath,
5
5
  startDaemon
6
- } from "./chunk-JGBWTFU6.js";
6
+ } from "./chunk-USAZFY36.js";
7
7
  import {
8
8
  App
9
- } from "./chunk-W72LUSYS.js";
10
- import "./chunk-AM7WBP3P.js";
11
- import "./chunk-KNPLVGZB.js";
9
+ } from "./chunk-OSKYU4PM.js";
10
+ import "./chunk-ODSCWVBX.js";
11
+ import "./chunk-YKEAKVIS.js";
12
12
  import "./chunk-LNJ7O5O4.js";
13
- import "./chunk-GE6UL6C7.js";
13
+ import "./chunk-PC45PRK3.js";
14
14
  import "./chunk-UBADCBPT.js";
15
15
  import "./chunk-IEQGTVWN.js";
16
16
  import "./chunk-AUJJGMZG.js";
17
17
  import "./chunk-YHRAOBI2.js";
18
- import "./chunk-GDGKEMBS.js";
18
+ import "./chunk-7FSHVRBS.js";
19
19
  import {
20
20
  runAgent
21
- } from "./chunk-DOWWBLX2.js";
21
+ } from "./chunk-Z7TPFGGR.js";
22
22
  import "./chunk-K5QJMSJH.js";
23
23
  import {
24
24
  composePrompt
25
25
  } from "./chunk-WAJXATCO.js";
26
26
  import "./chunk-62JNF5M2.js";
27
27
  import "./chunk-7CAGWFAQ.js";
28
- import "./chunk-S7LDOWMS.js";
29
- import "./chunk-PZV2FJE5.js";
28
+ import "./chunk-HFQZDT65.js";
29
+ import "./chunk-55JZKI2M.js";
30
30
  import {
31
31
  detectEngines,
32
32
  getEngine
33
- } from "./chunk-DABIMOMV.js";
34
- import "./chunk-ZNV63ZIK.js";
33
+ } from "./chunk-HIUQ4FXO.js";
34
+ import "./chunk-GAWQ7YXC.js";
35
35
 
36
36
  // src/cli.tsx
37
37
  import { Command } from "commander";
@@ -188,18 +188,18 @@ function registerDaemon(program2) {
188
188
  process.on("SIGTERM", stop);
189
189
  });
190
190
  program2.command("mcp").description("serve the gates as MCP tools over stdio (check, shot, flows, context)").action(async () => {
191
- const { runMcpServer } = await import("./server-QSU4H564.js");
191
+ const { runMcpServer } = await import("./server-PSXRO2XN.js");
192
192
  runMcpServer(process.cwd());
193
193
  });
194
194
  program2.command("attach").description("attach this terminal to a running squint daemon (full TUI; --plain for line mode)").option("--plain", "line-mode attach instead of the full TUI").action(async (opts) => {
195
195
  const cwd = process.cwd();
196
196
  if (!opts.plain) {
197
197
  try {
198
- const { RemoteSession } = await import("./remote-TDNUUOUN.js");
198
+ const { RemoteSession } = await import("./remote-WLUNMQRO.js");
199
199
  const remote = await RemoteSession.connect(cwd);
200
200
  const config = loadConfig(defaultPaths(cwd));
201
201
  const { render: render2 } = await import("ink");
202
- const { App: App2 } = await import("./App-W2U3EUM6.js");
202
+ const { App: App2 } = await import("./App-I2MB7S6W.js");
203
203
  const React = await import("react");
204
204
  render2(
205
205
  React.createElement(App2, {
@@ -293,7 +293,7 @@ function registerEnv(program2) {
293
293
  console.log(`${status} ${engine.name}${binaryPath ? "" : pc3.dim(` \u2014 install: ${engine.install}`)}`);
294
294
  }
295
295
  if (options.probe) {
296
- const { runAgent: runAgent2 } = await import("./run-IAA2C5LM.js");
296
+ const { runAgent: runAgent2 } = await import("./run-QZA57WPI.js");
297
297
  console.log(pc3.dim("\nprobing engines with a one-word prompt (verifies auth end to end)\u2026"));
298
298
  for (const { engine, path: binaryPath } of detected) {
299
299
  if (!binaryPath) continue;
@@ -315,8 +315,8 @@ function registerEnv(program2) {
315
315
  );
316
316
  }
317
317
  }
318
- const { findChrome } = await import("./chrome-CAN7TVH6.js");
319
- const { hasWebSocket } = await import("./cdp-V47GTLXG.js");
318
+ const { findChrome } = await import("./chrome-BQ4WOCOH.js");
319
+ const { hasWebSocket } = await import("./cdp-DV4D6PUL.js");
320
320
  const chrome = findChrome();
321
321
  console.log(
322
322
  chrome ? `${pc3.green("\u2713")} Chrome ${pc3.dim(chrome)}` : `${pc3.yellow("\u25CB")} Chrome ${pc3.dim("\u2014 screenshots and runtime probing disabled")}`
@@ -457,7 +457,7 @@ function registerProject(program2) {
457
457
  process.exitCode = 1;
458
458
  return;
459
459
  }
460
- const { runVariants, cleanVariants } = await import("./variants-WBRY2U37.js");
460
+ const { runVariants, cleanVariants } = await import("./variants-RJPANXPH.js");
461
461
  const config = loadConfig(defaultPaths(cwd));
462
462
  const engineId = resolveEngineId(config, options.engine);
463
463
  const engine = getEngine(engineId);
@@ -475,7 +475,7 @@ function registerProject(program2) {
475
475
  );
476
476
  const succeeded = runs.filter((r) => r.result.ok);
477
477
  if (options.shots && succeeded.length > 0) {
478
- const { screenshotVariants } = await import("./shots-HDHPCENU.js");
478
+ const { screenshotVariants } = await import("./shots-MZXB7VQT.js");
479
479
  console.log(pc4.dim("capturing screenshots\u2026"));
480
480
  const shots = await screenshotVariants(cwd, succeeded.map((r) => r.variant));
481
481
  for (const shot of shots) {
@@ -490,7 +490,7 @@ ${succeeded.length}/${runs.length} variants ready in .squint/variants/ \u2014 `
490
490
  }
491
491
  );
492
492
  variantsCommand.command("list").description("List generated variants").action(async () => {
493
- const { listVariants } = await import("./variants-WBRY2U37.js");
493
+ const { listVariants } = await import("./variants-RJPANXPH.js");
494
494
  const ids = listVariants(process.cwd());
495
495
  if (ids.length === 0) {
496
496
  console.log(pc4.dim('no variants \u2014 squint variants gen <n> "<ask>"'));
@@ -499,7 +499,7 @@ ${succeeded.length}/${runs.length} variants ready in .squint/variants/ \u2014 `
499
499
  for (const id of ids) console.log(id);
500
500
  });
501
501
  variantsCommand.command("apply").description("Apply one variant\u2019s changes to the main tree and discard the rest").argument("<id>", "family id of the winning variant").action(async (id) => {
502
- const { applyVariant, cleanVariants } = await import("./variants-WBRY2U37.js");
502
+ const { applyVariant, cleanVariants } = await import("./variants-RJPANXPH.js");
503
503
  const cwd = process.cwd();
504
504
  const result = applyVariant(cwd, id);
505
505
  if (!result.ok) {
@@ -511,7 +511,7 @@ ${succeeded.length}/${runs.length} variants ready in .squint/variants/ \u2014 `
511
511
  console.log(pc4.green(`\u2713 applied ${id} to the working tree`) + pc4.dim(" \u2014 review with git diff"));
512
512
  });
513
513
  variantsCommand.command("clean").description("Discard all variants").action(async () => {
514
- const { cleanVariants } = await import("./variants-WBRY2U37.js");
514
+ const { cleanVariants } = await import("./variants-RJPANXPH.js");
515
515
  const count = cleanVariants(process.cwd());
516
516
  console.log(pc4.dim(`removed ${count} variant(s)`));
517
517
  });
@@ -552,7 +552,7 @@ function registerQuality(program2) {
552
552
  report.gates = gateResults.map((r) => ({ id: r.gate.id, ok: r.ok, durationMs: r.durationMs, outputTail: r.ok ? void 0 : r.outputTail }));
553
553
  if (gateResults.some((r) => !r.ok)) failed = true;
554
554
  if (opts.url) {
555
- const { captureViewports, runtimeSummary, previewDir } = await import("./preview-NPLDCOP6.js");
555
+ const { captureViewports, runtimeSummary, previewDir } = await import("./preview-CDSJ5WBQ.js");
556
556
  const capture = await captureViewports(cwd, opts.url);
557
557
  if (!capture) {
558
558
  console.log(pc5.red("\u2717 audit: capture failed (Chrome missing or URL unreachable)"));
@@ -584,14 +584,14 @@ function registerQuality(program2) {
584
584
  console.log(`${pc5.green("\u2713")} audit ${pc5.dim(`(${advisories.a11y.length} a11y, ${advisories.slop.length} slop, ${advisories.jank.length} jank advisories)`)}`);
585
585
  }
586
586
  }
587
- const { loadFlows } = await import("./flows-SYDNB5IW.js");
587
+ const { loadFlows } = await import("./flows-XORMW4DA.js");
588
588
  const flows = loadFlows(cwd);
589
589
  if (flows.length > 0) {
590
- const { findChrome } = await import("./chrome-CAN7TVH6.js");
590
+ const { findChrome } = await import("./chrome-BQ4WOCOH.js");
591
591
  const chrome = findChrome();
592
592
  const flowReport = [];
593
593
  if (chrome) {
594
- const { runFlow } = await import("./cdp-V47GTLXG.js");
594
+ const { runFlow } = await import("./cdp-DV4D6PUL.js");
595
595
  for (const flow of flows) {
596
596
  const result = await runFlow(chrome, opts.url, flow, previewDir(cwd));
597
597
  flowReport.push({ name: flow.name, ok: result.ok, detail: result.ok ? void 0 : `step ${result.failedStep}: ${result.detail}` });
@@ -605,7 +605,7 @@ function registerQuality(program2) {
605
605
  report.ok = !failed;
606
606
  report.finishedAt = (/* @__PURE__ */ new Date()).toISOString();
607
607
  try {
608
- const { writeReceipt } = await import("./receipts-MCEUXL6I.js");
608
+ const { writeReceipt } = await import("./receipts-HMBEL7NM.js");
609
609
  console.log(pc5.dim(`receipt \u2192 ${writeReceipt(cwd, report)}`));
610
610
  } catch {
611
611
  }
@@ -617,7 +617,7 @@ function registerQuality(program2) {
617
617
  if (failed) process.exitCode = 1;
618
618
  });
619
619
  program2.command("shot").description("Screenshot a running app at mobile/tablet/desktop viewports (+ .squint/routes)").argument("<url>", "URL of the running app (e.g. http://localhost:5173)").action(async (url) => {
620
- const { captureViewports } = await import("./preview-NPLDCOP6.js");
620
+ const { captureViewports } = await import("./preview-CDSJ5WBQ.js");
621
621
  const result = await captureViewports(process.cwd(), url);
622
622
  if (!result) {
623
623
  console.error(pc5.red("\u2717 no Chrome/Chromium found"));
@@ -804,7 +804,7 @@ function registerTui(program2) {
804
804
  }
805
805
 
806
806
  // src/cli.tsx
807
- var VERSION = true ? "0.7.2" : "0.0.0-dev";
807
+ var VERSION = true ? "0.8.0" : "0.0.0-dev";
808
808
  var program = new Command();
809
809
  program.name("squint").description("Lovable for your terminal \u2014 a frontend harness on top of Claude Code, Codex, and friends.").version(VERSION);
810
810
  registerRun(program);
@@ -4,7 +4,7 @@ import {
4
4
  parseFlow,
5
5
  stepExpression,
6
6
  suggestFlows
7
- } from "./chunk-CGOFK6EM.js";
7
+ } from "./chunk-WOPJFP4M.js";
8
8
  export {
9
9
  loadFlows,
10
10
  parseFlow,
@@ -11,12 +11,12 @@ import {
11
11
  probeRuntime,
12
12
  routeShotName,
13
13
  runtimeSummary
14
- } from "./chunk-GE6UL6C7.js";
14
+ } from "./chunk-PC45PRK3.js";
15
15
  import "./chunk-7CAGWFAQ.js";
16
- import "./chunk-S7LDOWMS.js";
17
- import "./chunk-PZV2FJE5.js";
18
- import "./chunk-DABIMOMV.js";
19
- import "./chunk-ZNV63ZIK.js";
16
+ import "./chunk-HFQZDT65.js";
17
+ import "./chunk-55JZKI2M.js";
18
+ import "./chunk-HIUQ4FXO.js";
19
+ import "./chunk-GAWQ7YXC.js";
20
20
  export {
21
21
  VIEWPORTS,
22
22
  buildReviewPrompt,
@@ -31,7 +31,7 @@ function buildReceipt(cwd, report) {
31
31
  }
32
32
  }
33
33
  const unsigned = {
34
- version: true ? "0.7.2" : "0.0.0-dev",
34
+ version: true ? "0.8.0" : "0.0.0-dev",
35
35
  node: process.version,
36
36
  gitHead,
37
37
  report,
@@ -5,7 +5,7 @@ import {
5
5
  findBinary,
6
6
  findEngineBinary,
7
7
  getEngine
8
- } from "./chunk-DABIMOMV.js";
8
+ } from "./chunk-HIUQ4FXO.js";
9
9
  export {
10
10
  detectEngines,
11
11
  engines,
@@ -2,24 +2,24 @@
2
2
  import {
3
3
  connectDaemon,
4
4
  socketPath
5
- } from "./chunk-JGBWTFU6.js";
6
- import "./chunk-AM7WBP3P.js";
7
- import "./chunk-KNPLVGZB.js";
8
- import "./chunk-GE6UL6C7.js";
5
+ } from "./chunk-USAZFY36.js";
6
+ import "./chunk-ODSCWVBX.js";
7
+ import "./chunk-YKEAKVIS.js";
8
+ import "./chunk-PC45PRK3.js";
9
9
  import "./chunk-UBADCBPT.js";
10
10
  import "./chunk-IEQGTVWN.js";
11
11
  import "./chunk-AUJJGMZG.js";
12
12
  import "./chunk-YHRAOBI2.js";
13
- import "./chunk-GDGKEMBS.js";
14
- import "./chunk-DOWWBLX2.js";
13
+ import "./chunk-7FSHVRBS.js";
14
+ import "./chunk-Z7TPFGGR.js";
15
15
  import "./chunk-K5QJMSJH.js";
16
16
  import "./chunk-WAJXATCO.js";
17
17
  import "./chunk-62JNF5M2.js";
18
18
  import "./chunk-7CAGWFAQ.js";
19
- import "./chunk-S7LDOWMS.js";
20
- import "./chunk-PZV2FJE5.js";
21
- import "./chunk-DABIMOMV.js";
22
- import "./chunk-ZNV63ZIK.js";
19
+ import "./chunk-HFQZDT65.js";
20
+ import "./chunk-55JZKI2M.js";
21
+ import "./chunk-HIUQ4FXO.js";
22
+ import "./chunk-GAWQ7YXC.js";
23
23
 
24
24
  // src/daemon/remote.ts
25
25
  var noteId = 0;
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runAgent
4
- } from "./chunk-DOWWBLX2.js";
5
- import "./chunk-DABIMOMV.js";
4
+ } from "./chunk-Z7TPFGGR.js";
5
+ import "./chunk-HIUQ4FXO.js";
6
6
  export {
7
7
  runAgent
8
8
  };
@@ -7,7 +7,7 @@ import {
7
7
  captureViewports,
8
8
  previewDir,
9
9
  runtimeSummary
10
- } from "./chunk-GE6UL6C7.js";
10
+ } from "./chunk-PC45PRK3.js";
11
11
  import "./chunk-UBADCBPT.js";
12
12
  import "./chunk-IEQGTVWN.js";
13
13
  import "./chunk-WAJXATCO.js";
@@ -18,13 +18,13 @@ import {
18
18
  import "./chunk-7CAGWFAQ.js";
19
19
  import {
20
20
  loadFlows
21
- } from "./chunk-CGOFK6EM.js";
22
- import "./chunk-S7LDOWMS.js";
21
+ } from "./chunk-WOPJFP4M.js";
22
+ import "./chunk-HFQZDT65.js";
23
23
  import {
24
24
  findChrome
25
- } from "./chunk-PZV2FJE5.js";
26
- import "./chunk-DABIMOMV.js";
27
- import "./chunk-ZNV63ZIK.js";
25
+ } from "./chunk-55JZKI2M.js";
26
+ import "./chunk-HIUQ4FXO.js";
27
+ import "./chunk-GAWQ7YXC.js";
28
28
 
29
29
  // src/mcp/server.ts
30
30
  import readline from "readline";
@@ -76,12 +76,13 @@ ${list.join("\n")}`);
76
76
  if (flows.length === 0) return "no flows declared \u2014 add .squint/flows/<name>.flow";
77
77
  const chrome = findChrome();
78
78
  if (!chrome) return "no Chrome/Chromium found";
79
- const { runFlow } = await import("./cdp-V47GTLXG.js");
79
+ const { runFlow } = await import("./cdp-DV4D6PUL.js");
80
80
  const lines = [];
81
81
  for (const flow of flows) {
82
82
  const result = await runFlow(chrome, url, flow, previewDir(cwd));
83
83
  lines.push(
84
- result.ok ? `\u2713 ${flow.name} (${flow.steps.length} steps)` : `\u2717 ${flow.name} at step ${result.failedStep}: ${result.detail}`
84
+ result.ok ? `\u2713 ${flow.name} (${flow.steps.length} steps)${result.transitions.length > 0 ? `
85
+ ${result.transitions.map((t) => ` ${t}`).join("\n")}` : ""}` : `\u2717 ${flow.name} at step ${result.failedStep}: ${result.detail}`
85
86
  );
86
87
  }
87
88
  return lines.join("\n");
@@ -94,7 +95,7 @@ ${list.join("\n")}`);
94
95
  async run(args, cwd) {
95
96
  const chrome = findChrome();
96
97
  if (!chrome) return "no Chrome/Chromium found";
97
- const { suggestFlows } = await import("./flows-SYDNB5IW.js");
98
+ const { suggestFlows } = await import("./flows-XORMW4DA.js");
98
99
  const { created, skipped } = await suggestFlows(cwd, String(args.url ?? ""), chrome);
99
100
  return [
100
101
  created.length > 0 ? `drafted: ${created.join(", ")}` : "nothing drafted",
@@ -109,7 +110,7 @@ ${list.join("\n")}`);
109
110
  async run(args, cwd) {
110
111
  const fs = await import("fs");
111
112
  const path = await import("path");
112
- const { verifyReceipt } = await import("./receipts-MCEUXL6I.js");
113
+ const { verifyReceipt } = await import("./receipts-HMBEL7NM.js");
113
114
  const file = path.isAbsolute(String(args.path)) ? String(args.path) : path.join(cwd, String(args.path));
114
115
  let receipt;
115
116
  try {
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ screenshotVariants
4
+ } from "./chunk-YKEAKVIS.js";
5
+ import "./chunk-7FSHVRBS.js";
6
+ import "./chunk-Z7TPFGGR.js";
7
+ import "./chunk-K5QJMSJH.js";
8
+ import "./chunk-WAJXATCO.js";
9
+ import "./chunk-55JZKI2M.js";
10
+ import "./chunk-HIUQ4FXO.js";
11
+ export {
12
+ screenshotVariants
13
+ };
@@ -9,11 +9,11 @@ import {
9
9
  runVariants,
10
10
  variantPrompt,
11
11
  variantsRoot
12
- } from "./chunk-GDGKEMBS.js";
13
- import "./chunk-DOWWBLX2.js";
12
+ } from "./chunk-7FSHVRBS.js";
13
+ import "./chunk-Z7TPFGGR.js";
14
14
  import "./chunk-K5QJMSJH.js";
15
15
  import "./chunk-WAJXATCO.js";
16
- import "./chunk-DABIMOMV.js";
16
+ import "./chunk-HIUQ4FXO.js";
17
17
  export {
18
18
  MAX_VARIANTS,
19
19
  applyVariant,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aayambansal/squint",
3
- "version": "0.7.2",
3
+ "version": "0.8.0",
4
4
  "description": "Lovable for your terminal \u2014 a frontend harness on top of Claude Code, Codex, and other coding agents.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,13 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- screenshotVariants
4
- } from "./chunk-KNPLVGZB.js";
5
- import "./chunk-GDGKEMBS.js";
6
- import "./chunk-DOWWBLX2.js";
7
- import "./chunk-K5QJMSJH.js";
8
- import "./chunk-WAJXATCO.js";
9
- import "./chunk-PZV2FJE5.js";
10
- import "./chunk-DABIMOMV.js";
11
- export {
12
- screenshotVariants
13
- };