@aayambansal/squint 0.5.2 → 0.6.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.
Files changed (26) hide show
  1. package/dist/{App-QTB6FIJM.js → App-54M5DS3T.js} +9 -9
  2. package/dist/{cdp-FKFCV2B5.js → cdp-IGPGFMC6.js} +1 -1
  3. package/dist/{chrome-EEXJCG6W.js → chrome-CAN7TVH6.js} +2 -2
  4. package/dist/{chunk-DRMVCSUG.js → chunk-3XO3GF5X.js} +2 -2
  5. package/dist/{chunk-W5ZGF5JQ.js → chunk-5MQOJYUC.js} +19 -13
  6. package/dist/{chunk-GV2HAALP.js → chunk-DABIMOMV.js} +136 -1
  7. package/dist/{chunk-6NPUVPQD.js → chunk-DOWWBLX2.js} +1 -1
  8. package/dist/{chunk-J7ITMK6X.js → chunk-GDGKEMBS.js} +1 -1
  9. package/dist/{chunk-2I3YHT6P.js → chunk-KNPLVGZB.js} +3 -3
  10. package/dist/{chunk-YRANCWY6.js → chunk-N7YEWQGZ.js} +41 -5
  11. package/dist/{chunk-PYC53J7D.js → chunk-PZV2FJE5.js} +1 -1
  12. package/dist/{chunk-NCEEMDD6.js → chunk-SKNZ2PJF.js} +1 -1
  13. package/dist/{chunk-HSQ7XLD2.js → chunk-UMDV4ITQ.js} +6 -6
  14. package/dist/{chunk-LBQDTQ5A.js → chunk-ZG3XQDUW.js} +1 -1
  15. package/dist/cli.js +28 -28
  16. package/dist/{flows-OAQYGH77.js → flows-OY4BSCKD.js} +1 -1
  17. package/dist/{preview-XWPCSQFT.js → preview-4OF6JB5B.js} +4 -4
  18. package/dist/{receipts-Z55AHONO.js → receipts-JEOMBMFI.js} +1 -1
  19. package/dist/{registry-JBP7J3JB.js → registry-ZCCZVXSX.js} +1 -1
  20. package/dist/{remote-QNRB5APU.js → remote-LOQ5WKAS.js} +9 -9
  21. package/dist/{run-GDDIYEBP.js → run-IAA2C5LM.js} +2 -2
  22. package/dist/{server-AROYCMDF.js → server-N2PGAV2C.js} +6 -6
  23. package/dist/shots-HDHPCENU.js +13 -0
  24. package/dist/{variants-VURXVIQO.js → variants-WBRY2U37.js} +3 -3
  25. package/package.json +1 -1
  26. package/dist/shots-6DRTXFDI.js +0 -13
@@ -1,24 +1,24 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  App
4
- } from "./chunk-LBQDTQ5A.js";
4
+ } from "./chunk-ZG3XQDUW.js";
5
5
  import "./chunk-3GHZOVAA.js";
6
- import "./chunk-W5ZGF5JQ.js";
6
+ import "./chunk-5MQOJYUC.js";
7
7
  import "./chunk-UBADCBPT.js";
8
8
  import "./chunk-IEQGTVWN.js";
9
9
  import "./chunk-AUJJGMZG.js";
10
10
  import "./chunk-YHRAOBI2.js";
11
- import "./chunk-2I3YHT6P.js";
12
- import "./chunk-J7ITMK6X.js";
13
- import "./chunk-6NPUVPQD.js";
11
+ import "./chunk-KNPLVGZB.js";
12
+ import "./chunk-GDGKEMBS.js";
13
+ import "./chunk-DOWWBLX2.js";
14
14
  import "./chunk-K5QJMSJH.js";
15
15
  import "./chunk-WAJXATCO.js";
16
16
  import "./chunk-62JNF5M2.js";
17
- import "./chunk-HSQ7XLD2.js";
17
+ import "./chunk-UMDV4ITQ.js";
18
18
  import "./chunk-7CAGWFAQ.js";
19
- import "./chunk-YRANCWY6.js";
20
- import "./chunk-PYC53J7D.js";
21
- import "./chunk-GV2HAALP.js";
19
+ import "./chunk-N7YEWQGZ.js";
20
+ import "./chunk-PZV2FJE5.js";
21
+ import "./chunk-DABIMOMV.js";
22
22
  export {
23
23
  App
24
24
  };
@@ -5,7 +5,7 @@ import {
5
5
  pixelDiffAttributed,
6
6
  pixelDiffPct,
7
7
  runFlow
8
- } from "./chunk-YRANCWY6.js";
8
+ } from "./chunk-N7YEWQGZ.js";
9
9
  export {
10
10
  cdpCapture,
11
11
  hasWebSocket,
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  findChrome,
4
4
  screenshot
5
- } from "./chunk-PYC53J7D.js";
6
- import "./chunk-GV2HAALP.js";
5
+ } from "./chunk-PZV2FJE5.js";
6
+ import "./chunk-DABIMOMV.js";
7
7
  export {
8
8
  findChrome,
9
9
  screenshot
@@ -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-FKFCV2B5.js");
147
- const { loadRoutes } = await import("./preview-XWPCSQFT.js");
146
+ const { cdpCapture } = await import("./cdp-IGPGFMC6.js");
147
+ const { loadRoutes } = await import("./preview-4OF6JB5B.js");
148
148
  const dir = path2.join(cwd, ".squint", "flows");
149
149
  fs2.mkdirSync(dir, { recursive: true });
150
150
  const created = [];
@@ -25,16 +25,16 @@ import {
25
25
  buildFixPrompt,
26
26
  detectDevCommand,
27
27
  screenshotVariants
28
- } from "./chunk-2I3YHT6P.js";
28
+ } from "./chunk-KNPLVGZB.js";
29
29
  import {
30
30
  applyVariant,
31
31
  cleanVariants,
32
32
  listVariants,
33
33
  runVariants
34
- } from "./chunk-J7ITMK6X.js";
34
+ } from "./chunk-GDGKEMBS.js";
35
35
  import {
36
36
  runAgent
37
- } from "./chunk-6NPUVPQD.js";
37
+ } from "./chunk-DOWWBLX2.js";
38
38
  import {
39
39
  composePrompt
40
40
  } from "./chunk-WAJXATCO.js";
@@ -51,7 +51,7 @@ import {
51
51
  comparePulseAttributed,
52
52
  probeRuntime,
53
53
  runtimeSummary
54
- } from "./chunk-HSQ7XLD2.js";
54
+ } from "./chunk-UMDV4ITQ.js";
55
55
  import {
56
56
  clearState,
57
57
  loadState,
@@ -59,10 +59,10 @@ import {
59
59
  } from "./chunk-7CAGWFAQ.js";
60
60
  import {
61
61
  findChrome
62
- } from "./chunk-PYC53J7D.js";
62
+ } from "./chunk-PZV2FJE5.js";
63
63
  import {
64
64
  getEngine
65
- } from "./chunk-GV2HAALP.js";
65
+ } from "./chunk-DABIMOMV.js";
66
66
 
67
67
  // src/session/engine.ts
68
68
  import fs2 from "fs";
@@ -769,7 +769,13 @@ squint verifies every turn \u2014 gates, runtime probe, page audits. Do not decl
769
769
  this.push("image", pulsePath);
770
770
  return null;
771
771
  }
772
- const diff = await comparePulseAttributed(previous, current, this.state.devUrl ?? void 0);
772
+ const { previewDir } = await import("./preview-4OF6JB5B.js");
773
+ const diff = await comparePulseAttributed(
774
+ previous,
775
+ current,
776
+ this.state.devUrl ?? void 0,
777
+ (await import("path")).join(previewDir(this.opts.cwd), "triptych.png")
778
+ );
773
779
  if (diff === null) return null;
774
780
  const pct = diff.pct;
775
781
  this.push(
@@ -778,7 +784,7 @@ squint verifies every turn \u2014 gates, runtime probe, page audits. Do not decl
778
784
  ${diff.sentences.map((s) => ` ${s}`).join("\n")}` : ""}`
779
785
  );
780
786
  runHook(this.opts.cwd, "on-pulse-diff", { pct: pct.toFixed(1) });
781
- if (pct >= 0.5) this.push("image", pulsePath);
787
+ if (pct >= 0.5) this.push("image", diff.triptychPath ?? pulsePath);
782
788
  return pct;
783
789
  }
784
790
  /** Screenshot the running app (and watch its runtime where CDP is available). */
@@ -873,7 +879,7 @@ They are objective defects, not style preferences.`
873
879
  const arg = rest.join(" ").trim();
874
880
  switch (name) {
875
881
  case "engines": {
876
- void import("./registry-JBP7J3JB.js").then(({ detectEngines }) => {
882
+ void import("./registry-ZCCZVXSX.js").then(({ detectEngines }) => {
877
883
  const lines = detectEngines().map(({ engine, path: binaryPath }) => {
878
884
  const mark = binaryPath ? "\u2713" : "\u2717";
879
885
  const traits = [engine.createParser ? "stream" : "text", engine.supportsResume ? "resume" : null].filter(Boolean).join(" \xB7 ");
@@ -1129,7 +1135,7 @@ every ask now carries it; auto-fix presses to ${MAX_GOAL_FIX_ATTEMPTS} attempts
1129
1135
  this.push("error", "no Chrome/Chromium found");
1130
1136
  return;
1131
1137
  }
1132
- const { suggestFlows } = await import("./flows-OAQYGH77.js");
1138
+ const { suggestFlows } = await import("./flows-OY4BSCKD.js");
1133
1139
  this.push("status", "drafting flows from the live routes\u2026");
1134
1140
  const { created, skipped } = await suggestFlows(this.opts.cwd, this.state.devUrl, chrome);
1135
1141
  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`);
@@ -1139,7 +1145,7 @@ every ask now carries it; auto-fix presses to ${MAX_GOAL_FIX_ATTEMPTS} attempts
1139
1145
  break;
1140
1146
  }
1141
1147
  void (async () => {
1142
- const { loadFlows } = await import("./flows-OAQYGH77.js");
1148
+ const { loadFlows } = await import("./flows-OY4BSCKD.js");
1143
1149
  const flows = loadFlows(this.opts.cwd);
1144
1150
  if (flows.length === 0) {
1145
1151
  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");
@@ -1150,8 +1156,8 @@ every ask now carries it; auto-fix presses to ${MAX_GOAL_FIX_ATTEMPTS} attempts
1150
1156
  this.push("error", "no Chrome/Chromium found for flows");
1151
1157
  return;
1152
1158
  }
1153
- const { runFlow } = await import("./cdp-FKFCV2B5.js");
1154
- const { previewDir } = await import("./preview-XWPCSQFT.js");
1159
+ const { runFlow } = await import("./cdp-IGPGFMC6.js");
1160
+ const { previewDir } = await import("./preview-4OF6JB5B.js");
1155
1161
  this.push("status", `replaying ${flows.length} flow(s)\u2026`);
1156
1162
  this.notify({ running: true, runStartedAt: Date.now() });
1157
1163
  const failures = [];
@@ -271,6 +271,141 @@ function itemToEvents(item, phase) {
271
271
  }
272
272
  }
273
273
 
274
+ // src/engines/codexApp.ts
275
+ var DRIVER_SOURCE = String.raw`
276
+ const { spawn } = require('node:child_process');
277
+ const opts = JSON.parse(process.argv[1]);
278
+ const bin = process.env.SQUINT_CODEX_BIN || 'codex';
279
+ const child = spawn(bin, ['app-server'], { stdio: ['pipe', 'pipe', 'pipe'], cwd: opts.cwd });
280
+ const emit = (obj) => process.stdout.write(JSON.stringify(obj) + '\n');
281
+ const send = (msg) => child.stdin.write(JSON.stringify(msg) + '\n');
282
+ let threadId = opts.resume || null;
283
+ let done = false;
284
+ const finish = (ok, error) => {
285
+ if (done) return;
286
+ done = true;
287
+ emit({ kind: 'result', ok, sessionId: threadId || undefined, error });
288
+ try { child.kill(); } catch {}
289
+ process.exit(ok ? 0 : 1);
290
+ };
291
+ process.on('SIGTERM', () => finish(false, 'interrupted'));
292
+ process.on('SIGINT', () => finish(false, 'interrupted'));
293
+ setTimeout(() => finish(false, 'app-server timeout'), 30 * 60 * 1000).unref();
294
+ child.on('exit', () => finish(false, 'app-server exited early'));
295
+ child.stderr.on('data', () => {});
296
+ let buf = '';
297
+ child.stdout.on('data', (chunk) => {
298
+ buf += chunk.toString();
299
+ let idx;
300
+ while ((idx = buf.indexOf('\n')) >= 0) {
301
+ const line = buf.slice(0, idx);
302
+ buf = buf.slice(idx + 1);
303
+ if (!line.trim()) continue;
304
+ let msg;
305
+ try { msg = JSON.parse(line); } catch { continue; }
306
+ if (msg.error && msg.id !== undefined) return finish(false, String(msg.error.message || 'app-server error'));
307
+ if (msg.id === 1 && msg.result !== undefined) {
308
+ send({ jsonrpc: '2.0', method: 'initialized' });
309
+ if (threadId) send({ jsonrpc: '2.0', id: 2, method: 'thread/resume', params: { threadId } });
310
+ else send({ jsonrpc: '2.0', id: 2, method: 'thread/start', params: {
311
+ cwd: opts.cwd, sandbox: opts.sandbox, approvalPolicy: 'never', model: opts.model || null,
312
+ } });
313
+ continue;
314
+ }
315
+ if (msg.id === 2 && msg.result !== undefined) {
316
+ threadId = (msg.result.thread && msg.result.thread.id) || msg.result.threadId || threadId;
317
+ send({ jsonrpc: '2.0', id: 3, method: 'turn/start', params: {
318
+ threadId, input: [{ type: 'text', text: opts.prompt }],
319
+ model: opts.model || null, sandboxPolicy: null, cwd: opts.cwd,
320
+ } });
321
+ continue;
322
+ }
323
+ switch (msg.method) {
324
+ case 'item/agentMessage/delta':
325
+ emit({ kind: 'delta', text: msg.params.delta });
326
+ break;
327
+ case 'item/reasoning/summaryTextDelta':
328
+ case 'item/reasoning/textDelta':
329
+ emit({ kind: 'thinking' });
330
+ break;
331
+ case 'item/started': {
332
+ const item = msg.params.item || {};
333
+ if (item.type === 'commandExecution') emit({ kind: 'tool', name: 'shell', detail: item.command });
334
+ else if (item.type === 'fileChange') emit({ kind: 'tool', name: 'edit', detail: item.path });
335
+ else if (item.type === 'mcpToolCall') emit({ kind: 'tool', name: item.tool || 'mcp' });
336
+ else if (item.type === 'webSearch') emit({ kind: 'tool', name: 'search' });
337
+ break;
338
+ }
339
+ case 'item/completed': {
340
+ const item = msg.params.item || {};
341
+ if (item.type === 'agentMessage' && item.text) emit({ kind: 'message', text: item.text });
342
+ break;
343
+ }
344
+ case 'error':
345
+ emit({ kind: 'note', text: String((msg.params && msg.params.message) || 'error') });
346
+ break;
347
+ case 'turn/completed': {
348
+ const status = msg.params && msg.params.turn && msg.params.turn.status;
349
+ finish(status === 'completed', status === 'completed' ? undefined : String(status));
350
+ break;
351
+ }
352
+ }
353
+ }
354
+ });
355
+ send({ jsonrpc: '2.0', id: 1, method: 'initialize', params: { clientInfo: { name: 'squint', title: 'squint', version: '0' } } });
356
+ `;
357
+ var codexApp = {
358
+ id: "codex-app",
359
+ name: "Codex (app-server)",
360
+ binary: "node",
361
+ install: "npm install -g @openai/codex (requires codex on PATH)",
362
+ supportsResume: true,
363
+ env: {},
364
+ buildArgs(opts) {
365
+ const sandbox = opts.mode === "plan" ? "read-only" : opts.mode === "yolo" ? "danger-full-access" : "workspace-write";
366
+ const payload = {
367
+ prompt: opts.prompt,
368
+ cwd: opts.cwd,
369
+ model: opts.model,
370
+ sandbox,
371
+ resume: opts.sessionId
372
+ };
373
+ return ["-e", DRIVER_SOURCE, JSON.stringify(payload)];
374
+ },
375
+ createParser() {
376
+ let streamed = false;
377
+ return (line) => {
378
+ let data;
379
+ try {
380
+ data = JSON.parse(line);
381
+ } catch {
382
+ return [];
383
+ }
384
+ switch (data.kind) {
385
+ case "delta":
386
+ streamed = true;
387
+ return [{ type: "delta", text: data.text ?? "" }];
388
+ case "message":
389
+ if (streamed) {
390
+ streamed = false;
391
+ return [{ type: "text", text: data.text ?? "", streamed: true }];
392
+ }
393
+ return [{ type: "text", text: data.text ?? "" }];
394
+ case "thinking":
395
+ return [{ type: "thinking", text: "" }];
396
+ case "tool":
397
+ return [{ type: "tool", name: data.detail ? `${data.name}: ${truncate(data.detail, 80)}` : data.name ?? "tool" }];
398
+ case "note":
399
+ return [{ type: "status", text: data.text ?? "" }];
400
+ case "result":
401
+ return [{ type: "result", ok: data.ok === true, sessionId: data.sessionId, summary: data.error }];
402
+ default:
403
+ return [];
404
+ }
405
+ };
406
+ }
407
+ };
408
+
274
409
  // src/engines/copilot.ts
275
410
  var copilot = {
276
411
  id: "copilot",
@@ -419,7 +554,7 @@ var opencode = {
419
554
  };
420
555
 
421
556
  // src/engines/registry.ts
422
- var engines = [claude, codex, gemini, opencode, amp, cursor, copilot, aider];
557
+ var engines = [claude, codex, codexApp, gemini, opencode, amp, cursor, copilot, aider];
423
558
  function getEngine(id) {
424
559
  const engine = engines.find((e) => e.id === id);
425
560
  if (!engine) {
@@ -3,7 +3,7 @@ import {
3
3
  findEngineBinary,
4
4
  lineSplitter,
5
5
  truncate
6
- } from "./chunk-GV2HAALP.js";
6
+ } from "./chunk-DABIMOMV.js";
7
7
 
8
8
  // src/runner/run.ts
9
9
  import { spawn } from "child_process";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runAgent
4
- } from "./chunk-6NPUVPQD.js";
4
+ } from "./chunk-DOWWBLX2.js";
5
5
  import {
6
6
  FAMILIES,
7
7
  renderFamilyBrief
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  variantsRoot
4
- } from "./chunk-J7ITMK6X.js";
4
+ } from "./chunk-GDGKEMBS.js";
5
5
  import {
6
6
  findChrome,
7
7
  screenshot
8
- } from "./chunk-PYC53J7D.js";
8
+ } from "./chunk-PZV2FJE5.js";
9
9
  import {
10
10
  lineSplitter
11
- } from "./chunk-GV2HAALP.js";
11
+ } from "./chunk-DABIMOMV.js";
12
12
 
13
13
  // src/variants/shots.ts
14
14
  import path2 from "path";
@@ -179,7 +179,7 @@ var describe = (value) => {
179
179
  return String(value);
180
180
  };
181
181
  async function runFlow(chromePath, baseUrl, flow, outDir) {
182
- const { stepExpression } = await import("./flows-OAQYGH77.js");
182
+ const { stepExpression } = await import("./flows-OY4BSCKD.js");
183
183
  const { child, wsUrl, profileDir } = await launchChrome(chromePath);
184
184
  const shots = [];
185
185
  let connection = null;
@@ -238,7 +238,7 @@ async function runFlow(chromePath, baseUrl, flow, outDir) {
238
238
  setTimeout(() => fs.rmSync(profileDir, { recursive: true, force: true }), 500).unref?.();
239
239
  }
240
240
  }
241
- async function pixelDiffAttributed(chromePath, pngA, pngB, url) {
241
+ async function pixelDiffAttributed(chromePath, pngA, pngB, url, outPath) {
242
242
  const { child, wsUrl, profileDir } = await launchChrome(chromePath);
243
243
  let connection = null;
244
244
  try {
@@ -312,7 +312,35 @@ async function pixelDiffAttributed(chromePath, pngA, pngB, url) {
312
312
  }
313
313
  regions.sort((p, q) => q.cells - p.cells);
314
314
  const sizePenalty = (a.width !== b.width || a.height !== b.height) ? 1 : 0;
315
- return { pct: Math.min(100, (differ / total) * 100 + sizePenalty), regions: regions.slice(0, 5), w, h };
315
+ const pct = Math.min(100, (differ / total) * 100 + sizePenalty);
316
+ let triptych = null;
317
+ if (pct >= 0.5) {
318
+ // before | after | heatmap, half scale, labeled.
319
+ const panelW = Math.round(w / 2), panelH = Math.round(h / 2), gap = 6;
320
+ const c = document.createElement('canvas');
321
+ c.width = panelW * 3 + gap * 2; c.height = panelH + 22;
322
+ const ctx = c.getContext('2d');
323
+ ctx.fillStyle = '#111'; ctx.fillRect(0, 0, c.width, c.height);
324
+ ctx.drawImage(a, 0, 22, panelW, panelH);
325
+ ctx.drawImage(b, panelW + gap, 22, panelW, panelH);
326
+ ctx.globalAlpha = 0.3;
327
+ ctx.drawImage(b, (panelW + gap) * 2, 22, panelW, panelH);
328
+ ctx.globalAlpha = 1;
329
+ ctx.fillStyle = 'rgba(255,60,40,0.75)';
330
+ const sx = panelW / w, sy = panelH / h;
331
+ for (let cy = 0; cy < gh; cy++) {
332
+ for (let cx = 0; cx < gw; cx++) {
333
+ if (!marked[cy * gw + cx]) continue;
334
+ ctx.fillRect((panelW + gap) * 2 + cx * CELL * sx, 22 + cy * CELL * sy, CELL * sx, CELL * sy);
335
+ }
336
+ }
337
+ ctx.fillStyle = '#ddd'; ctx.font = '12px system-ui';
338
+ ctx.fillText('before', 2, 14);
339
+ ctx.fillText('after', panelW + gap + 2, 14);
340
+ ctx.fillText('changed ' + pct.toFixed(1) + '%', (panelW + gap) * 2 + 2, 14);
341
+ triptych = c.toDataURL('image/png');
342
+ }
343
+ return { pct, regions: regions.slice(0, 5), w, h, triptych };
316
344
  })()`;
317
345
  const { result } = await connection.send(
318
346
  "Runtime.evaluate",
@@ -321,7 +349,15 @@ async function pixelDiffAttributed(chromePath, pngA, pngB, url) {
321
349
  );
322
350
  const value = result?.value;
323
351
  if (!value || typeof value.pct !== "number") return null;
324
- if (!url || value.regions.length === 0 || value.pct < 0.5) return { pct: value.pct, sentences: [] };
352
+ let triptychPath;
353
+ if (value.triptych && outPath) {
354
+ try {
355
+ fs.writeFileSync(outPath, Buffer.from(value.triptych.split(",")[1] ?? "", "base64"));
356
+ triptychPath = outPath;
357
+ } catch {
358
+ }
359
+ }
360
+ if (!url || value.regions.length === 0 || value.pct < 0.5) return { pct: value.pct, sentences: [], triptychPath };
325
361
  let sentences = [];
326
362
  try {
327
363
  const page = await connection.send("Target.createTarget", { url: "about:blank" });
@@ -368,7 +404,7 @@ async function pixelDiffAttributed(chromePath, pngA, pngB, url) {
368
404
  if (Array.isArray(hit.result?.value)) sentences = hit.result.value.map(String);
369
405
  } catch {
370
406
  }
371
- return { pct: value.pct, sentences };
407
+ return { pct: value.pct, sentences, triptychPath };
372
408
  } catch {
373
409
  return null;
374
410
  } finally {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  findBinary
4
- } from "./chunk-GV2HAALP.js";
4
+ } from "./chunk-DABIMOMV.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
  Session
4
- } from "./chunk-W5ZGF5JQ.js";
4
+ } from "./chunk-5MQOJYUC.js";
5
5
 
6
6
  // src/daemon/client.ts
7
7
  import net from "net";
@@ -5,11 +5,11 @@ import {
5
5
  import {
6
6
  cdpCapture,
7
7
  hasWebSocket
8
- } from "./chunk-YRANCWY6.js";
8
+ } from "./chunk-N7YEWQGZ.js";
9
9
  import {
10
10
  findChrome,
11
11
  screenshot
12
- } from "./chunk-PYC53J7D.js";
12
+ } from "./chunk-PZV2FJE5.js";
13
13
 
14
14
  // src/preview/preview.ts
15
15
  import fs2 from "fs";
@@ -164,14 +164,14 @@ async function probeRuntime(url, cwd) {
164
164
  async function comparePulse(previous, current) {
165
165
  const chrome = findChrome();
166
166
  if (!chrome || !hasWebSocket()) return null;
167
- const { pixelDiffPct } = await import("./cdp-FKFCV2B5.js");
167
+ const { pixelDiffPct } = await import("./cdp-IGPGFMC6.js");
168
168
  return pixelDiffPct(chrome, previous, current);
169
169
  }
170
- async function comparePulseAttributed(previous, current, url) {
170
+ async function comparePulseAttributed(previous, current, url, outPath) {
171
171
  const chrome = findChrome();
172
172
  if (!chrome || !hasWebSocket()) return null;
173
- const { pixelDiffAttributed } = await import("./cdp-FKFCV2B5.js");
174
- return pixelDiffAttributed(chrome, previous, current, url);
173
+ const { pixelDiffAttributed } = await import("./cdp-IGPGFMC6.js");
174
+ return pixelDiffAttributed(chrome, previous, current, url, outPath);
175
175
  }
176
176
  function buildRuntimeFixPrompt(report) {
177
177
  return `The running app has runtime problems.${runtimeSection(report)}
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-3GHZOVAA.js";
5
5
  import {
6
6
  Session
7
- } from "./chunk-W5ZGF5JQ.js";
7
+ } from "./chunk-5MQOJYUC.js";
8
8
 
9
9
  // src/tui/App.tsx
10
10
  import { Box as Box3, Static, Text as Text3, useApp, useInput } from "ink";
package/dist/cli.js CHANGED
@@ -1,36 +1,36 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  App
4
- } from "./chunk-LBQDTQ5A.js";
4
+ } from "./chunk-ZG3XQDUW.js";
5
5
  import "./chunk-3GHZOVAA.js";
6
6
  import {
7
7
  connectDaemon,
8
8
  socketPath,
9
9
  startDaemon
10
- } from "./chunk-NCEEMDD6.js";
11
- import "./chunk-W5ZGF5JQ.js";
10
+ } from "./chunk-SKNZ2PJF.js";
11
+ import "./chunk-5MQOJYUC.js";
12
12
  import "./chunk-UBADCBPT.js";
13
13
  import "./chunk-IEQGTVWN.js";
14
14
  import "./chunk-AUJJGMZG.js";
15
15
  import "./chunk-YHRAOBI2.js";
16
- import "./chunk-2I3YHT6P.js";
17
- import "./chunk-J7ITMK6X.js";
16
+ import "./chunk-KNPLVGZB.js";
17
+ import "./chunk-GDGKEMBS.js";
18
18
  import {
19
19
  runAgent
20
- } from "./chunk-6NPUVPQD.js";
20
+ } from "./chunk-DOWWBLX2.js";
21
21
  import "./chunk-K5QJMSJH.js";
22
22
  import {
23
23
  composePrompt
24
24
  } from "./chunk-WAJXATCO.js";
25
25
  import "./chunk-62JNF5M2.js";
26
- import "./chunk-HSQ7XLD2.js";
26
+ import "./chunk-UMDV4ITQ.js";
27
27
  import "./chunk-7CAGWFAQ.js";
28
- import "./chunk-YRANCWY6.js";
29
- import "./chunk-PYC53J7D.js";
28
+ import "./chunk-N7YEWQGZ.js";
29
+ import "./chunk-PZV2FJE5.js";
30
30
  import {
31
31
  detectEngines,
32
32
  getEngine
33
- } from "./chunk-GV2HAALP.js";
33
+ } from "./chunk-DABIMOMV.js";
34
34
 
35
35
  // src/cli.tsx
36
36
  import { Command } from "commander";
@@ -187,18 +187,18 @@ function registerDaemon(program2) {
187
187
  process.on("SIGTERM", stop);
188
188
  });
189
189
  program2.command("mcp").description("serve the gates as MCP tools over stdio (check, shot, flows, context)").action(async () => {
190
- const { runMcpServer } = await import("./server-AROYCMDF.js");
190
+ const { runMcpServer } = await import("./server-N2PGAV2C.js");
191
191
  runMcpServer(process.cwd());
192
192
  });
193
193
  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) => {
194
194
  const cwd = process.cwd();
195
195
  if (!opts.plain) {
196
196
  try {
197
- const { RemoteSession } = await import("./remote-QNRB5APU.js");
197
+ const { RemoteSession } = await import("./remote-LOQ5WKAS.js");
198
198
  const remote = await RemoteSession.connect(cwd);
199
199
  const config = loadConfig(defaultPaths(cwd));
200
200
  const { render: render2 } = await import("ink");
201
- const { App: App2 } = await import("./App-QTB6FIJM.js");
201
+ const { App: App2 } = await import("./App-54M5DS3T.js");
202
202
  const React = await import("react");
203
203
  render2(
204
204
  React.createElement(App2, {
@@ -292,7 +292,7 @@ function registerEnv(program2) {
292
292
  console.log(`${status} ${engine.name}${binaryPath ? "" : pc3.dim(` \u2014 install: ${engine.install}`)}`);
293
293
  }
294
294
  if (options.probe) {
295
- const { runAgent: runAgent2 } = await import("./run-GDDIYEBP.js");
295
+ const { runAgent: runAgent2 } = await import("./run-IAA2C5LM.js");
296
296
  console.log(pc3.dim("\nprobing engines with a one-word prompt (verifies auth end to end)\u2026"));
297
297
  for (const { engine, path: binaryPath } of detected) {
298
298
  if (!binaryPath) continue;
@@ -314,8 +314,8 @@ function registerEnv(program2) {
314
314
  );
315
315
  }
316
316
  }
317
- const { findChrome } = await import("./chrome-EEXJCG6W.js");
318
- const { hasWebSocket } = await import("./cdp-FKFCV2B5.js");
317
+ const { findChrome } = await import("./chrome-CAN7TVH6.js");
318
+ const { hasWebSocket } = await import("./cdp-IGPGFMC6.js");
319
319
  const chrome = findChrome();
320
320
  console.log(
321
321
  chrome ? `${pc3.green("\u2713")} Chrome ${pc3.dim(chrome)}` : `${pc3.yellow("\u25CB")} Chrome ${pc3.dim("\u2014 screenshots and runtime probing disabled")}`
@@ -456,7 +456,7 @@ function registerProject(program2) {
456
456
  process.exitCode = 1;
457
457
  return;
458
458
  }
459
- const { runVariants, cleanVariants } = await import("./variants-VURXVIQO.js");
459
+ const { runVariants, cleanVariants } = await import("./variants-WBRY2U37.js");
460
460
  const config = loadConfig(defaultPaths(cwd));
461
461
  const engineId = resolveEngineId(config, options.engine);
462
462
  const engine = getEngine(engineId);
@@ -474,7 +474,7 @@ function registerProject(program2) {
474
474
  );
475
475
  const succeeded = runs.filter((r) => r.result.ok);
476
476
  if (options.shots && succeeded.length > 0) {
477
- const { screenshotVariants } = await import("./shots-6DRTXFDI.js");
477
+ const { screenshotVariants } = await import("./shots-HDHPCENU.js");
478
478
  console.log(pc4.dim("capturing screenshots\u2026"));
479
479
  const shots = await screenshotVariants(cwd, succeeded.map((r) => r.variant));
480
480
  for (const shot of shots) {
@@ -489,7 +489,7 @@ ${succeeded.length}/${runs.length} variants ready in .squint/variants/ \u2014 `
489
489
  }
490
490
  );
491
491
  variantsCommand.command("list").description("List generated variants").action(async () => {
492
- const { listVariants } = await import("./variants-VURXVIQO.js");
492
+ const { listVariants } = await import("./variants-WBRY2U37.js");
493
493
  const ids = listVariants(process.cwd());
494
494
  if (ids.length === 0) {
495
495
  console.log(pc4.dim('no variants \u2014 squint variants gen <n> "<ask>"'));
@@ -498,7 +498,7 @@ ${succeeded.length}/${runs.length} variants ready in .squint/variants/ \u2014 `
498
498
  for (const id of ids) console.log(id);
499
499
  });
500
500
  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) => {
501
- const { applyVariant, cleanVariants } = await import("./variants-VURXVIQO.js");
501
+ const { applyVariant, cleanVariants } = await import("./variants-WBRY2U37.js");
502
502
  const cwd = process.cwd();
503
503
  const result = applyVariant(cwd, id);
504
504
  if (!result.ok) {
@@ -510,7 +510,7 @@ ${succeeded.length}/${runs.length} variants ready in .squint/variants/ \u2014 `
510
510
  console.log(pc4.green(`\u2713 applied ${id} to the working tree`) + pc4.dim(" \u2014 review with git diff"));
511
511
  });
512
512
  variantsCommand.command("clean").description("Discard all variants").action(async () => {
513
- const { cleanVariants } = await import("./variants-VURXVIQO.js");
513
+ const { cleanVariants } = await import("./variants-WBRY2U37.js");
514
514
  const count = cleanVariants(process.cwd());
515
515
  console.log(pc4.dim(`removed ${count} variant(s)`));
516
516
  });
@@ -551,7 +551,7 @@ function registerQuality(program2) {
551
551
  report.gates = gateResults.map((r) => ({ id: r.gate.id, ok: r.ok, durationMs: r.durationMs, outputTail: r.ok ? void 0 : r.outputTail }));
552
552
  if (gateResults.some((r) => !r.ok)) failed = true;
553
553
  if (opts.url) {
554
- const { captureViewports, runtimeSummary, previewDir } = await import("./preview-XWPCSQFT.js");
554
+ const { captureViewports, runtimeSummary, previewDir } = await import("./preview-4OF6JB5B.js");
555
555
  const capture = await captureViewports(cwd, opts.url);
556
556
  if (!capture) {
557
557
  console.log(pc5.red("\u2717 audit: capture failed (Chrome missing or URL unreachable)"));
@@ -583,14 +583,14 @@ function registerQuality(program2) {
583
583
  console.log(`${pc5.green("\u2713")} audit ${pc5.dim(`(${advisories.a11y.length} a11y, ${advisories.slop.length} slop, ${advisories.jank.length} jank advisories)`)}`);
584
584
  }
585
585
  }
586
- const { loadFlows } = await import("./flows-OAQYGH77.js");
586
+ const { loadFlows } = await import("./flows-OY4BSCKD.js");
587
587
  const flows = loadFlows(cwd);
588
588
  if (flows.length > 0) {
589
- const { findChrome } = await import("./chrome-EEXJCG6W.js");
589
+ const { findChrome } = await import("./chrome-CAN7TVH6.js");
590
590
  const chrome = findChrome();
591
591
  const flowReport = [];
592
592
  if (chrome) {
593
- const { runFlow } = await import("./cdp-FKFCV2B5.js");
593
+ const { runFlow } = await import("./cdp-IGPGFMC6.js");
594
594
  for (const flow of flows) {
595
595
  const result = await runFlow(chrome, opts.url, flow, previewDir(cwd));
596
596
  flowReport.push({ name: flow.name, ok: result.ok, detail: result.ok ? void 0 : `step ${result.failedStep}: ${result.detail}` });
@@ -604,7 +604,7 @@ function registerQuality(program2) {
604
604
  report.ok = !failed;
605
605
  report.finishedAt = (/* @__PURE__ */ new Date()).toISOString();
606
606
  try {
607
- const { writeReceipt } = await import("./receipts-Z55AHONO.js");
607
+ const { writeReceipt } = await import("./receipts-JEOMBMFI.js");
608
608
  console.log(pc5.dim(`receipt \u2192 ${writeReceipt(cwd, report)}`));
609
609
  } catch {
610
610
  }
@@ -616,7 +616,7 @@ function registerQuality(program2) {
616
616
  if (failed) process.exitCode = 1;
617
617
  });
618
618
  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) => {
619
- const { captureViewports } = await import("./preview-XWPCSQFT.js");
619
+ const { captureViewports } = await import("./preview-4OF6JB5B.js");
620
620
  const result = await captureViewports(process.cwd(), url);
621
621
  if (!result) {
622
622
  console.error(pc5.red("\u2717 no Chrome/Chromium found"));
@@ -803,7 +803,7 @@ function registerTui(program2) {
803
803
  }
804
804
 
805
805
  // src/cli.tsx
806
- var VERSION = true ? "0.5.2" : "0.0.0-dev";
806
+ var VERSION = true ? "0.6.1" : "0.0.0-dev";
807
807
  var program = new Command();
808
808
  program.name("squint").description("Lovable for your terminal \u2014 a frontend harness on top of Claude Code, Codex, and friends.").version(VERSION);
809
809
  registerRun(program);
@@ -4,7 +4,7 @@ import {
4
4
  parseFlow,
5
5
  stepExpression,
6
6
  suggestFlows
7
- } from "./chunk-DRMVCSUG.js";
7
+ } from "./chunk-3XO3GF5X.js";
8
8
  export {
9
9
  loadFlows,
10
10
  parseFlow,
@@ -11,11 +11,11 @@ import {
11
11
  probeRuntime,
12
12
  routeShotName,
13
13
  runtimeSummary
14
- } from "./chunk-HSQ7XLD2.js";
14
+ } from "./chunk-UMDV4ITQ.js";
15
15
  import "./chunk-7CAGWFAQ.js";
16
- import "./chunk-YRANCWY6.js";
17
- import "./chunk-PYC53J7D.js";
18
- import "./chunk-GV2HAALP.js";
16
+ import "./chunk-N7YEWQGZ.js";
17
+ import "./chunk-PZV2FJE5.js";
18
+ import "./chunk-DABIMOMV.js";
19
19
  export {
20
20
  VIEWPORTS,
21
21
  buildReviewPrompt,
@@ -31,7 +31,7 @@ function buildReceipt(cwd, report) {
31
31
  }
32
32
  }
33
33
  const unsigned = {
34
- version: true ? "0.5.2" : "0.0.0-dev",
34
+ version: true ? "0.6.1" : "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-GV2HAALP.js";
8
+ } from "./chunk-DABIMOMV.js";
9
9
  export {
10
10
  detectEngines,
11
11
  engines,
@@ -2,23 +2,23 @@
2
2
  import {
3
3
  connectDaemon,
4
4
  socketPath
5
- } from "./chunk-NCEEMDD6.js";
6
- import "./chunk-W5ZGF5JQ.js";
5
+ } from "./chunk-SKNZ2PJF.js";
6
+ import "./chunk-5MQOJYUC.js";
7
7
  import "./chunk-UBADCBPT.js";
8
8
  import "./chunk-IEQGTVWN.js";
9
9
  import "./chunk-AUJJGMZG.js";
10
10
  import "./chunk-YHRAOBI2.js";
11
- import "./chunk-2I3YHT6P.js";
12
- import "./chunk-J7ITMK6X.js";
13
- import "./chunk-6NPUVPQD.js";
11
+ import "./chunk-KNPLVGZB.js";
12
+ import "./chunk-GDGKEMBS.js";
13
+ import "./chunk-DOWWBLX2.js";
14
14
  import "./chunk-K5QJMSJH.js";
15
15
  import "./chunk-WAJXATCO.js";
16
16
  import "./chunk-62JNF5M2.js";
17
- import "./chunk-HSQ7XLD2.js";
17
+ import "./chunk-UMDV4ITQ.js";
18
18
  import "./chunk-7CAGWFAQ.js";
19
- import "./chunk-YRANCWY6.js";
20
- import "./chunk-PYC53J7D.js";
21
- import "./chunk-GV2HAALP.js";
19
+ import "./chunk-N7YEWQGZ.js";
20
+ import "./chunk-PZV2FJE5.js";
21
+ import "./chunk-DABIMOMV.js";
22
22
 
23
23
  // src/daemon/remote.ts
24
24
  var noteId = 0;
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runAgent
4
- } from "./chunk-6NPUVPQD.js";
5
- import "./chunk-GV2HAALP.js";
4
+ } from "./chunk-DOWWBLX2.js";
5
+ import "./chunk-DABIMOMV.js";
6
6
  export {
7
7
  runAgent
8
8
  };
@@ -12,18 +12,18 @@ import {
12
12
  } from "./chunk-62JNF5M2.js";
13
13
  import {
14
14
  loadFlows
15
- } from "./chunk-DRMVCSUG.js";
15
+ } from "./chunk-3XO3GF5X.js";
16
16
  import {
17
17
  captureViewports,
18
18
  previewDir,
19
19
  runtimeSummary
20
- } from "./chunk-HSQ7XLD2.js";
20
+ } from "./chunk-UMDV4ITQ.js";
21
21
  import "./chunk-7CAGWFAQ.js";
22
- import "./chunk-YRANCWY6.js";
22
+ import "./chunk-N7YEWQGZ.js";
23
23
  import {
24
24
  findChrome
25
- } from "./chunk-PYC53J7D.js";
26
- import "./chunk-GV2HAALP.js";
25
+ } from "./chunk-PZV2FJE5.js";
26
+ import "./chunk-DABIMOMV.js";
27
27
 
28
28
  // src/mcp/server.ts
29
29
  import readline from "readline";
@@ -75,7 +75,7 @@ ${list.join("\n")}`);
75
75
  if (flows.length === 0) return "no flows declared \u2014 add .squint/flows/<name>.flow";
76
76
  const chrome = findChrome();
77
77
  if (!chrome) return "no Chrome/Chromium found";
78
- const { runFlow } = await import("./cdp-FKFCV2B5.js");
78
+ const { runFlow } = await import("./cdp-IGPGFMC6.js");
79
79
  const lines = [];
80
80
  for (const flow of flows) {
81
81
  const result = await runFlow(chrome, url, flow, previewDir(cwd));
@@ -0,0 +1,13 @@
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
+ };
@@ -9,11 +9,11 @@ import {
9
9
  runVariants,
10
10
  variantPrompt,
11
11
  variantsRoot
12
- } from "./chunk-J7ITMK6X.js";
13
- import "./chunk-6NPUVPQD.js";
12
+ } from "./chunk-GDGKEMBS.js";
13
+ import "./chunk-DOWWBLX2.js";
14
14
  import "./chunk-K5QJMSJH.js";
15
15
  import "./chunk-WAJXATCO.js";
16
- import "./chunk-GV2HAALP.js";
16
+ import "./chunk-DABIMOMV.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.5.2",
3
+ "version": "0.6.1",
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-2I3YHT6P.js";
5
- import "./chunk-J7ITMK6X.js";
6
- import "./chunk-6NPUVPQD.js";
7
- import "./chunk-K5QJMSJH.js";
8
- import "./chunk-WAJXATCO.js";
9
- import "./chunk-PYC53J7D.js";
10
- import "./chunk-GV2HAALP.js";
11
- export {
12
- screenshotVariants
13
- };