@aayambansal/squint 0.7.0 → 0.7.2
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/{App-OHKGQTDL.js → App-W2U3EUM6.js} +6 -5
- package/dist/{cdp-IGPGFMC6.js → cdp-V47GTLXG.js} +1 -1
- package/dist/checks-2XOF2K3L.js +9 -0
- package/dist/{chunk-7PKIVVRB.js → chunk-AM7WBP3P.js} +20 -20
- package/dist/{chunk-3XO3GF5X.js → chunk-CGOFK6EM.js} +2 -2
- package/dist/{chunk-UMDV4ITQ.js → chunk-GE6UL6C7.js} +11 -36
- package/dist/{chunk-ORJPNSTE.js → chunk-JGBWTFU6.js} +17 -1
- package/dist/{chunk-N7YEWQGZ.js → chunk-S7LDOWMS.js} +1 -1
- package/dist/{chunk-6OFUO3UT.js → chunk-W72LUSYS.js} +3 -3
- package/dist/chunk-ZNV63ZIK.js +60 -0
- package/dist/cli.js +21 -20
- package/dist/{flows-OY4BSCKD.js → flows-SYDNB5IW.js} +1 -1
- package/dist/{init-YB2IMA4N.js → init-FASBBKC6.js} +14 -0
- package/dist/{preview-4OF6JB5B.js → preview-NPLDCOP6.js} +3 -2
- package/dist/{receipts-EFFO3NYZ.js → receipts-MCEUXL6I.js} +1 -1
- package/dist/{remote-TOZNJWGE.js → remote-TDNUUOUN.js} +6 -5
- package/dist/{sentinel-4SKSSCXX.js → sentinel-VR44TKIC.js} +0 -0
- package/dist/{server-N2PGAV2C.js → server-QSU4H564.js} +45 -9
- package/package.json +1 -1
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
App
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-W72LUSYS.js";
|
|
5
|
+
import "./chunk-AM7WBP3P.js";
|
|
6
|
+
import "./chunk-KNPLVGZB.js";
|
|
5
7
|
import "./chunk-LNJ7O5O4.js";
|
|
6
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-GE6UL6C7.js";
|
|
7
9
|
import "./chunk-UBADCBPT.js";
|
|
8
10
|
import "./chunk-IEQGTVWN.js";
|
|
9
11
|
import "./chunk-AUJJGMZG.js";
|
|
10
12
|
import "./chunk-YHRAOBI2.js";
|
|
11
|
-
import "./chunk-KNPLVGZB.js";
|
|
12
13
|
import "./chunk-GDGKEMBS.js";
|
|
13
14
|
import "./chunk-DOWWBLX2.js";
|
|
14
15
|
import "./chunk-K5QJMSJH.js";
|
|
15
16
|
import "./chunk-WAJXATCO.js";
|
|
16
17
|
import "./chunk-62JNF5M2.js";
|
|
17
|
-
import "./chunk-UMDV4ITQ.js";
|
|
18
18
|
import "./chunk-7CAGWFAQ.js";
|
|
19
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-S7LDOWMS.js";
|
|
20
20
|
import "./chunk-PZV2FJE5.js";
|
|
21
21
|
import "./chunk-DABIMOMV.js";
|
|
22
|
+
import "./chunk-ZNV63ZIK.js";
|
|
22
23
|
export {
|
|
23
24
|
App
|
|
24
25
|
};
|
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
DevServer,
|
|
4
|
+
buildFixPrompt,
|
|
5
|
+
detectDevCommand,
|
|
6
|
+
screenshotVariants
|
|
7
|
+
} from "./chunk-KNPLVGZB.js";
|
|
8
|
+
import {
|
|
9
|
+
buildReviewPrompt,
|
|
10
|
+
buildRuntimeFixPrompt,
|
|
11
|
+
captureViewports,
|
|
12
|
+
comparePulseAttributed,
|
|
13
|
+
probeRuntime,
|
|
14
|
+
runtimeSummary
|
|
15
|
+
} from "./chunk-GE6UL6C7.js";
|
|
2
16
|
import {
|
|
3
17
|
enrich
|
|
4
18
|
} from "./chunk-UBADCBPT.js";
|
|
@@ -20,12 +34,6 @@ import {
|
|
|
20
34
|
restoreSnapshot,
|
|
21
35
|
takeSnapshot
|
|
22
36
|
} from "./chunk-YHRAOBI2.js";
|
|
23
|
-
import {
|
|
24
|
-
DevServer,
|
|
25
|
-
buildFixPrompt,
|
|
26
|
-
detectDevCommand,
|
|
27
|
-
screenshotVariants
|
|
28
|
-
} from "./chunk-KNPLVGZB.js";
|
|
29
37
|
import {
|
|
30
38
|
applyVariant,
|
|
31
39
|
cleanVariants,
|
|
@@ -44,14 +52,6 @@ import {
|
|
|
44
52
|
detectGates,
|
|
45
53
|
runGates
|
|
46
54
|
} from "./chunk-62JNF5M2.js";
|
|
47
|
-
import {
|
|
48
|
-
buildReviewPrompt,
|
|
49
|
-
buildRuntimeFixPrompt,
|
|
50
|
-
captureViewports,
|
|
51
|
-
comparePulseAttributed,
|
|
52
|
-
probeRuntime,
|
|
53
|
-
runtimeSummary
|
|
54
|
-
} from "./chunk-UMDV4ITQ.js";
|
|
55
55
|
import {
|
|
56
56
|
clearState,
|
|
57
57
|
loadState,
|
|
@@ -517,7 +517,7 @@ ${driftSummary(drift)}`);
|
|
|
517
517
|
} catch {
|
|
518
518
|
}
|
|
519
519
|
try {
|
|
520
|
-
const { scanEvasion, sentinelSummary } = await import("./sentinel-
|
|
520
|
+
const { scanEvasion, sentinelSummary } = await import("./sentinel-VR44TKIC.js");
|
|
521
521
|
const evasions = scanEvasion(this.execCwd(), checkpoint.snapshot.stashHash ?? "HEAD");
|
|
522
522
|
if (evasions.length > 0) {
|
|
523
523
|
this.push("error", `\u26A0 sentinel: ${evasions.length} gate-evasion pattern(s) this turn
|
|
@@ -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-
|
|
815
|
+
const { previewDir } = await import("./preview-NPLDCOP6.js");
|
|
816
816
|
const diff = await comparePulseAttributed(
|
|
817
817
|
previous,
|
|
818
818
|
current,
|
|
@@ -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-
|
|
1193
|
+
const { suggestFlows } = await import("./flows-SYDNB5IW.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-
|
|
1203
|
+
const { loadFlows } = await import("./flows-SYDNB5IW.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-
|
|
1215
|
-
const { previewDir } = await import("./preview-
|
|
1214
|
+
const { runFlow } = await import("./cdp-V47GTLXG.js");
|
|
1215
|
+
const { previewDir } = await import("./preview-NPLDCOP6.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 = [];
|
|
@@ -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-
|
|
147
|
-
const { loadRoutes } = await import("./preview-
|
|
146
|
+
const { cdpCapture } = await import("./cdp-V47GTLXG.js");
|
|
147
|
+
const { loadRoutes } = await import("./preview-NPLDCOP6.js");
|
|
148
148
|
const dir = path2.join(cwd, ".squint", "flows");
|
|
149
149
|
fs2.mkdirSync(dir, { recursive: true });
|
|
150
150
|
const created = [];
|
|
@@ -5,44 +5,19 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
cdpCapture,
|
|
7
7
|
hasWebSocket
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-S7LDOWMS.js";
|
|
9
9
|
import {
|
|
10
10
|
findChrome,
|
|
11
11
|
screenshot
|
|
12
12
|
} from "./chunk-PZV2FJE5.js";
|
|
13
|
+
import {
|
|
14
|
+
loadChecks
|
|
15
|
+
} from "./chunk-ZNV63ZIK.js";
|
|
13
16
|
|
|
14
17
|
// src/preview/preview.ts
|
|
15
|
-
import fs2 from "fs";
|
|
16
|
-
import os from "os";
|
|
17
|
-
import path2 from "path";
|
|
18
|
-
|
|
19
|
-
// src/preview/checks.ts
|
|
20
18
|
import fs from "fs";
|
|
19
|
+
import os from "os";
|
|
21
20
|
import path from "path";
|
|
22
|
-
var MAX_CHECKS = 20;
|
|
23
|
-
var MAX_BYTES = 1e4;
|
|
24
|
-
function loadChecks(cwd, context = "audit") {
|
|
25
|
-
const dir = path.join(cwd, ".squint", "checks");
|
|
26
|
-
let entries;
|
|
27
|
-
try {
|
|
28
|
-
entries = fs.readdirSync(dir).filter((f) => f.endsWith(".js"));
|
|
29
|
-
} catch {
|
|
30
|
-
return [];
|
|
31
|
-
}
|
|
32
|
-
const checks = [];
|
|
33
|
-
for (const entry of entries.sort().slice(0, MAX_CHECKS)) {
|
|
34
|
-
try {
|
|
35
|
-
const source = fs.readFileSync(path.join(dir, entry), "utf8");
|
|
36
|
-
if (source.trim().length === 0 || Buffer.byteLength(source) > MAX_BYTES) continue;
|
|
37
|
-
const pragma = /^\s*\/\/\s*squint-trigger:\s*(turn|audit)/.exec(source);
|
|
38
|
-
checks.push({ name: entry.replace(/\.js$/, ""), source, trigger: pragma?.[1] === "audit" ? "audit" : "turn" });
|
|
39
|
-
} catch {
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return context === "audit" ? checks : checks.filter((c) => c.trigger === "turn");
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// src/preview/preview.ts
|
|
46
21
|
var VIEWPORTS = [
|
|
47
22
|
{ name: "mobile", width: 390, height: 844 },
|
|
48
23
|
{ name: "tablet", width: 768, height: 1024 },
|
|
@@ -51,7 +26,7 @@ var VIEWPORTS = [
|
|
|
51
26
|
function loadRoutes(cwd) {
|
|
52
27
|
let lines = [];
|
|
53
28
|
try {
|
|
54
|
-
lines =
|
|
29
|
+
lines = fs.readFileSync(path.join(cwd, ".squint", "routes"), "utf8").split("\n").map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#"));
|
|
55
30
|
} catch {
|
|
56
31
|
}
|
|
57
32
|
const routes = ["/", ...lines.filter((l) => l !== "/")];
|
|
@@ -62,8 +37,8 @@ function routeShotName(route) {
|
|
|
62
37
|
return clean.length > 0 ? clean : "root";
|
|
63
38
|
}
|
|
64
39
|
function previewDir(cwd) {
|
|
65
|
-
const dir =
|
|
66
|
-
|
|
40
|
+
const dir = path.join(cwd, ".squint", "preview");
|
|
41
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
67
42
|
ensureSquintIgnore(cwd);
|
|
68
43
|
return dir;
|
|
69
44
|
}
|
|
@@ -98,7 +73,7 @@ async function captureViewports(cwd, url) {
|
|
|
98
73
|
const shots = [];
|
|
99
74
|
const errors = [];
|
|
100
75
|
for (const viewport of VIEWPORTS) {
|
|
101
|
-
const outPath =
|
|
76
|
+
const outPath = path.join(dir, `${viewport.name}.png`);
|
|
102
77
|
const result = await screenshot(chrome, url, outPath, {
|
|
103
78
|
width: viewport.width,
|
|
104
79
|
height: viewport.height
|
|
@@ -164,13 +139,13 @@ async function probeRuntime(url, cwd) {
|
|
|
164
139
|
async function comparePulse(previous, current) {
|
|
165
140
|
const chrome = findChrome();
|
|
166
141
|
if (!chrome || !hasWebSocket()) return null;
|
|
167
|
-
const { pixelDiffPct } = await import("./cdp-
|
|
142
|
+
const { pixelDiffPct } = await import("./cdp-V47GTLXG.js");
|
|
168
143
|
return pixelDiffPct(chrome, previous, current);
|
|
169
144
|
}
|
|
170
145
|
async function comparePulseAttributed(previous, current, url, outPath) {
|
|
171
146
|
const chrome = findChrome();
|
|
172
147
|
if (!chrome || !hasWebSocket()) return null;
|
|
173
|
-
const { pixelDiffAttributed } = await import("./cdp-
|
|
148
|
+
const { pixelDiffAttributed } = await import("./cdp-V47GTLXG.js");
|
|
174
149
|
return pixelDiffAttributed(chrome, previous, current, url, outPath);
|
|
175
150
|
}
|
|
176
151
|
function buildRuntimeFixPrompt(report) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
Session
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-AM7WBP3P.js";
|
|
5
5
|
|
|
6
6
|
// src/daemon/client.ts
|
|
7
7
|
import net from "net";
|
|
@@ -117,6 +117,21 @@ function startDaemon(opts) {
|
|
|
117
117
|
socket.on("close", drop);
|
|
118
118
|
socket.on("error", drop);
|
|
119
119
|
});
|
|
120
|
+
const lastRun = /* @__PURE__ */ new Map();
|
|
121
|
+
const sweep = setInterval(async () => {
|
|
122
|
+
const state = session.getState();
|
|
123
|
+
if (!state.devUrl || state.running) return;
|
|
124
|
+
try {
|
|
125
|
+
const { runIntervalSweep } = await import("./checks-2XOF2K3L.js");
|
|
126
|
+
const failures = await runIntervalSweep(opts.cwd, state.devUrl, lastRun);
|
|
127
|
+
if (failures.length > 0) {
|
|
128
|
+
session.note(`\u23F0 interval check(s) failing:
|
|
129
|
+
${failures.join("\n")}`);
|
|
130
|
+
}
|
|
131
|
+
} catch {
|
|
132
|
+
}
|
|
133
|
+
}, opts.intervalSweepMs ?? 6e4);
|
|
134
|
+
sweep.unref?.();
|
|
120
135
|
const unsubscribe = session.subscribe(() => {
|
|
121
136
|
const payload = serialize();
|
|
122
137
|
for (const client of clients) {
|
|
@@ -130,6 +145,7 @@ function startDaemon(opts) {
|
|
|
130
145
|
session,
|
|
131
146
|
clientCount: () => clients.length,
|
|
132
147
|
close: () => {
|
|
148
|
+
clearInterval(sweep);
|
|
133
149
|
unsubscribe();
|
|
134
150
|
for (const client of clients) client.destroy();
|
|
135
151
|
server.close();
|
|
@@ -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-
|
|
182
|
+
const { stepExpression } = await import("./flows-SYDNB5IW.js");
|
|
183
183
|
const { child, wsUrl, profileDir } = await launchChrome(chromePath);
|
|
184
184
|
const shots = [];
|
|
185
185
|
let connection = null;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
Session
|
|
4
|
+
} from "./chunk-AM7WBP3P.js";
|
|
2
5
|
import {
|
|
3
6
|
completeCommand
|
|
4
7
|
} from "./chunk-LNJ7O5O4.js";
|
|
5
|
-
import {
|
|
6
|
-
Session
|
|
7
|
-
} from "./chunk-7PKIVVRB.js";
|
|
8
8
|
|
|
9
9
|
// src/tui/App.tsx
|
|
10
10
|
import { Box as Box3, Static, Text as Text3, useApp, useInput } from "ink";
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/preview/checks.ts
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
var MAX_CHECKS = 20;
|
|
7
|
+
var MAX_BYTES = 1e4;
|
|
8
|
+
function loadChecks(cwd, context = "audit") {
|
|
9
|
+
const dir = path.join(cwd, ".squint", "checks");
|
|
10
|
+
let entries;
|
|
11
|
+
try {
|
|
12
|
+
entries = fs.readdirSync(dir).filter((f) => f.endsWith(".js"));
|
|
13
|
+
} catch {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const checks = [];
|
|
17
|
+
for (const entry of entries.sort().slice(0, MAX_CHECKS)) {
|
|
18
|
+
try {
|
|
19
|
+
const source = fs.readFileSync(path.join(dir, entry), "utf8");
|
|
20
|
+
if (source.trim().length === 0 || Buffer.byteLength(source) > MAX_BYTES) continue;
|
|
21
|
+
const pragma = /^\s*\/\/\s*squint-trigger:\s*(turn|audit|interval)(?::(\d+))?/.exec(source);
|
|
22
|
+
const trigger = pragma?.[1] === "audit" ? "audit" : pragma?.[1] === "interval" ? "interval" : "turn";
|
|
23
|
+
checks.push({
|
|
24
|
+
name: entry.replace(/\.js$/, ""),
|
|
25
|
+
source,
|
|
26
|
+
trigger,
|
|
27
|
+
intervalSec: trigger === "interval" ? Number.parseInt(pragma?.[2] ?? "300", 10) : void 0
|
|
28
|
+
});
|
|
29
|
+
} catch {
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (context === "audit") return checks.filter((c) => c.trigger !== "interval");
|
|
33
|
+
if (context === "interval") return checks.filter((c) => c.trigger === "interval");
|
|
34
|
+
return checks.filter((c) => c.trigger === "turn");
|
|
35
|
+
}
|
|
36
|
+
async function runIntervalSweep(cwd, url, lastRun) {
|
|
37
|
+
const now = Date.now();
|
|
38
|
+
const due = loadChecks(cwd, "interval").filter(
|
|
39
|
+
(c) => now - (lastRun.get(c.name) ?? 0) >= (c.intervalSec ?? 300) * 1e3
|
|
40
|
+
);
|
|
41
|
+
if (due.length === 0) return [];
|
|
42
|
+
for (const check of due) lastRun.set(check.name, now);
|
|
43
|
+
const { findChrome } = await import("./chrome-CAN7TVH6.js");
|
|
44
|
+
const chrome = findChrome();
|
|
45
|
+
if (!chrome) return [];
|
|
46
|
+
const os = await import("os");
|
|
47
|
+
const { cdpCapture } = await import("./cdp-V47GTLXG.js");
|
|
48
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "squint-interval-"));
|
|
49
|
+
try {
|
|
50
|
+
const result = await cdpCapture(chrome, url, tmp, [], 800, false, due);
|
|
51
|
+
return result.checkFailures;
|
|
52
|
+
} finally {
|
|
53
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export {
|
|
58
|
+
loadChecks,
|
|
59
|
+
runIntervalSweep
|
|
60
|
+
};
|
package/dist/cli.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
App
|
|
4
|
-
} from "./chunk-6OFUO3UT.js";
|
|
5
|
-
import "./chunk-LNJ7O5O4.js";
|
|
6
2
|
import {
|
|
7
3
|
connectDaemon,
|
|
8
4
|
socketPath,
|
|
9
5
|
startDaemon
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import
|
|
6
|
+
} from "./chunk-JGBWTFU6.js";
|
|
7
|
+
import {
|
|
8
|
+
App
|
|
9
|
+
} from "./chunk-W72LUSYS.js";
|
|
10
|
+
import "./chunk-AM7WBP3P.js";
|
|
11
|
+
import "./chunk-KNPLVGZB.js";
|
|
12
|
+
import "./chunk-LNJ7O5O4.js";
|
|
13
|
+
import "./chunk-GE6UL6C7.js";
|
|
12
14
|
import "./chunk-UBADCBPT.js";
|
|
13
15
|
import "./chunk-IEQGTVWN.js";
|
|
14
16
|
import "./chunk-AUJJGMZG.js";
|
|
15
17
|
import "./chunk-YHRAOBI2.js";
|
|
16
|
-
import "./chunk-KNPLVGZB.js";
|
|
17
18
|
import "./chunk-GDGKEMBS.js";
|
|
18
19
|
import {
|
|
19
20
|
runAgent
|
|
@@ -23,14 +24,14 @@ import {
|
|
|
23
24
|
composePrompt
|
|
24
25
|
} from "./chunk-WAJXATCO.js";
|
|
25
26
|
import "./chunk-62JNF5M2.js";
|
|
26
|
-
import "./chunk-UMDV4ITQ.js";
|
|
27
27
|
import "./chunk-7CAGWFAQ.js";
|
|
28
|
-
import "./chunk-
|
|
28
|
+
import "./chunk-S7LDOWMS.js";
|
|
29
29
|
import "./chunk-PZV2FJE5.js";
|
|
30
30
|
import {
|
|
31
31
|
detectEngines,
|
|
32
32
|
getEngine
|
|
33
33
|
} from "./chunk-DABIMOMV.js";
|
|
34
|
+
import "./chunk-ZNV63ZIK.js";
|
|
34
35
|
|
|
35
36
|
// src/cli.tsx
|
|
36
37
|
import { Command } from "commander";
|
|
@@ -187,18 +188,18 @@ function registerDaemon(program2) {
|
|
|
187
188
|
process.on("SIGTERM", stop);
|
|
188
189
|
});
|
|
189
190
|
program2.command("mcp").description("serve the gates as MCP tools over stdio (check, shot, flows, context)").action(async () => {
|
|
190
|
-
const { runMcpServer } = await import("./server-
|
|
191
|
+
const { runMcpServer } = await import("./server-QSU4H564.js");
|
|
191
192
|
runMcpServer(process.cwd());
|
|
192
193
|
});
|
|
193
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) => {
|
|
194
195
|
const cwd = process.cwd();
|
|
195
196
|
if (!opts.plain) {
|
|
196
197
|
try {
|
|
197
|
-
const { RemoteSession } = await import("./remote-
|
|
198
|
+
const { RemoteSession } = await import("./remote-TDNUUOUN.js");
|
|
198
199
|
const remote = await RemoteSession.connect(cwd);
|
|
199
200
|
const config = loadConfig(defaultPaths(cwd));
|
|
200
201
|
const { render: render2 } = await import("ink");
|
|
201
|
-
const { App: App2 } = await import("./App-
|
|
202
|
+
const { App: App2 } = await import("./App-W2U3EUM6.js");
|
|
202
203
|
const React = await import("react");
|
|
203
204
|
render2(
|
|
204
205
|
React.createElement(App2, {
|
|
@@ -315,7 +316,7 @@ function registerEnv(program2) {
|
|
|
315
316
|
}
|
|
316
317
|
}
|
|
317
318
|
const { findChrome } = await import("./chrome-CAN7TVH6.js");
|
|
318
|
-
const { hasWebSocket } = await import("./cdp-
|
|
319
|
+
const { hasWebSocket } = await import("./cdp-V47GTLXG.js");
|
|
319
320
|
const chrome = findChrome();
|
|
320
321
|
console.log(
|
|
321
322
|
chrome ? `${pc3.green("\u2713")} Chrome ${pc3.dim(chrome)}` : `${pc3.yellow("\u25CB")} Chrome ${pc3.dim("\u2014 screenshots and runtime probing disabled")}`
|
|
@@ -551,7 +552,7 @@ function registerQuality(program2) {
|
|
|
551
552
|
report.gates = gateResults.map((r) => ({ id: r.gate.id, ok: r.ok, durationMs: r.durationMs, outputTail: r.ok ? void 0 : r.outputTail }));
|
|
552
553
|
if (gateResults.some((r) => !r.ok)) failed = true;
|
|
553
554
|
if (opts.url) {
|
|
554
|
-
const { captureViewports, runtimeSummary, previewDir } = await import("./preview-
|
|
555
|
+
const { captureViewports, runtimeSummary, previewDir } = await import("./preview-NPLDCOP6.js");
|
|
555
556
|
const capture = await captureViewports(cwd, opts.url);
|
|
556
557
|
if (!capture) {
|
|
557
558
|
console.log(pc5.red("\u2717 audit: capture failed (Chrome missing or URL unreachable)"));
|
|
@@ -583,14 +584,14 @@ function registerQuality(program2) {
|
|
|
583
584
|
console.log(`${pc5.green("\u2713")} audit ${pc5.dim(`(${advisories.a11y.length} a11y, ${advisories.slop.length} slop, ${advisories.jank.length} jank advisories)`)}`);
|
|
584
585
|
}
|
|
585
586
|
}
|
|
586
|
-
const { loadFlows } = await import("./flows-
|
|
587
|
+
const { loadFlows } = await import("./flows-SYDNB5IW.js");
|
|
587
588
|
const flows = loadFlows(cwd);
|
|
588
589
|
if (flows.length > 0) {
|
|
589
590
|
const { findChrome } = await import("./chrome-CAN7TVH6.js");
|
|
590
591
|
const chrome = findChrome();
|
|
591
592
|
const flowReport = [];
|
|
592
593
|
if (chrome) {
|
|
593
|
-
const { runFlow } = await import("./cdp-
|
|
594
|
+
const { runFlow } = await import("./cdp-V47GTLXG.js");
|
|
594
595
|
for (const flow of flows) {
|
|
595
596
|
const result = await runFlow(chrome, opts.url, flow, previewDir(cwd));
|
|
596
597
|
flowReport.push({ name: flow.name, ok: result.ok, detail: result.ok ? void 0 : `step ${result.failedStep}: ${result.detail}` });
|
|
@@ -604,7 +605,7 @@ function registerQuality(program2) {
|
|
|
604
605
|
report.ok = !failed;
|
|
605
606
|
report.finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
606
607
|
try {
|
|
607
|
-
const { writeReceipt } = await import("./receipts-
|
|
608
|
+
const { writeReceipt } = await import("./receipts-MCEUXL6I.js");
|
|
608
609
|
console.log(pc5.dim(`receipt \u2192 ${writeReceipt(cwd, report)}`));
|
|
609
610
|
} catch {
|
|
610
611
|
}
|
|
@@ -616,7 +617,7 @@ function registerQuality(program2) {
|
|
|
616
617
|
if (failed) process.exitCode = 1;
|
|
617
618
|
});
|
|
618
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) => {
|
|
619
|
-
const { captureViewports } = await import("./preview-
|
|
620
|
+
const { captureViewports } = await import("./preview-NPLDCOP6.js");
|
|
620
621
|
const result = await captureViewports(process.cwd(), url);
|
|
621
622
|
if (!result) {
|
|
622
623
|
console.error(pc5.red("\u2717 no Chrome/Chromium found"));
|
|
@@ -709,7 +710,7 @@ function registerRun(program2) {
|
|
|
709
710
|
import pc7 from "picocolors";
|
|
710
711
|
function registerScaffold(program2) {
|
|
711
712
|
program2.command("init").description("Scaffold a new Vite + React + TS + Tailwind app with token-first CSS").argument("[dir]", "target directory", ".").option("--force", "write into a non-empty directory").option("--no-install", "skip npm install").action(async (dir, options) => {
|
|
712
|
-
const { installDependencies, writeTemplate } = await import("./init-
|
|
713
|
+
const { installDependencies, writeTemplate } = await import("./init-FASBBKC6.js");
|
|
713
714
|
let result;
|
|
714
715
|
try {
|
|
715
716
|
result = writeTemplate(dir, { force: options.force });
|
|
@@ -803,7 +804,7 @@ function registerTui(program2) {
|
|
|
803
804
|
}
|
|
804
805
|
|
|
805
806
|
// src/cli.tsx
|
|
806
|
-
var VERSION = true ? "0.7.
|
|
807
|
+
var VERSION = true ? "0.7.2" : "0.0.0-dev";
|
|
807
808
|
var program = new Command();
|
|
808
809
|
program.name("squint").description("Lovable for your terminal \u2014 a frontend harness on top of Claude Code, Codex, and friends.").version(VERSION);
|
|
809
810
|
registerRun(program);
|
|
@@ -145,6 +145,20 @@ dist/
|
|
|
145
145
|
goto /
|
|
146
146
|
expect Ready
|
|
147
147
|
shot home
|
|
148
|
+
`,
|
|
149
|
+
".squint/checks/root-renders.js": `// The starter check: replayed against the live page after every turn.
|
|
150
|
+
// Contract: this file evaluates IN THE PAGE to an array of failure
|
|
151
|
+
// strings \u2014 empty means pass. First-line pragmas move a check to full
|
|
152
|
+
// audits (// squint-trigger: audit) or the daemon's clock (interval:300).
|
|
153
|
+
(() => {
|
|
154
|
+
const root = document.querySelector('#root');
|
|
155
|
+
if (!root) return ['#root is missing from the page'];
|
|
156
|
+
if (root.children.length === 0) return ['#root rendered empty \u2014 the app did not mount'];
|
|
157
|
+
return [];
|
|
158
|
+
})()
|
|
159
|
+
`,
|
|
160
|
+
".squint/rules.md": `Build from the design tokens in src/index.css \u2014 never hardcode a color a token covers.
|
|
161
|
+
Keep every interactive element reachable by keyboard with a visible focus state.
|
|
148
162
|
`
|
|
149
163
|
};
|
|
150
164
|
}
|
|
@@ -11,11 +11,12 @@ import {
|
|
|
11
11
|
probeRuntime,
|
|
12
12
|
routeShotName,
|
|
13
13
|
runtimeSummary
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-GE6UL6C7.js";
|
|
15
15
|
import "./chunk-7CAGWFAQ.js";
|
|
16
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-S7LDOWMS.js";
|
|
17
17
|
import "./chunk-PZV2FJE5.js";
|
|
18
18
|
import "./chunk-DABIMOMV.js";
|
|
19
|
+
import "./chunk-ZNV63ZIK.js";
|
|
19
20
|
export {
|
|
20
21
|
VIEWPORTS,
|
|
21
22
|
buildReviewPrompt,
|
|
@@ -2,23 +2,24 @@
|
|
|
2
2
|
import {
|
|
3
3
|
connectDaemon,
|
|
4
4
|
socketPath
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-JGBWTFU6.js";
|
|
6
|
+
import "./chunk-AM7WBP3P.js";
|
|
7
|
+
import "./chunk-KNPLVGZB.js";
|
|
8
|
+
import "./chunk-GE6UL6C7.js";
|
|
7
9
|
import "./chunk-UBADCBPT.js";
|
|
8
10
|
import "./chunk-IEQGTVWN.js";
|
|
9
11
|
import "./chunk-AUJJGMZG.js";
|
|
10
12
|
import "./chunk-YHRAOBI2.js";
|
|
11
|
-
import "./chunk-KNPLVGZB.js";
|
|
12
13
|
import "./chunk-GDGKEMBS.js";
|
|
13
14
|
import "./chunk-DOWWBLX2.js";
|
|
14
15
|
import "./chunk-K5QJMSJH.js";
|
|
15
16
|
import "./chunk-WAJXATCO.js";
|
|
16
17
|
import "./chunk-62JNF5M2.js";
|
|
17
|
-
import "./chunk-UMDV4ITQ.js";
|
|
18
18
|
import "./chunk-7CAGWFAQ.js";
|
|
19
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-S7LDOWMS.js";
|
|
20
20
|
import "./chunk-PZV2FJE5.js";
|
|
21
21
|
import "./chunk-DABIMOMV.js";
|
|
22
|
+
import "./chunk-ZNV63ZIK.js";
|
|
22
23
|
|
|
23
24
|
// src/daemon/remote.ts
|
|
24
25
|
var noteId = 0;
|
|
Binary file
|
|
@@ -3,6 +3,11 @@ import {
|
|
|
3
3
|
contextReport,
|
|
4
4
|
formatContextReport
|
|
5
5
|
} from "./chunk-LESZB7DT.js";
|
|
6
|
+
import {
|
|
7
|
+
captureViewports,
|
|
8
|
+
previewDir,
|
|
9
|
+
runtimeSummary
|
|
10
|
+
} from "./chunk-GE6UL6C7.js";
|
|
6
11
|
import "./chunk-UBADCBPT.js";
|
|
7
12
|
import "./chunk-IEQGTVWN.js";
|
|
8
13
|
import "./chunk-WAJXATCO.js";
|
|
@@ -10,20 +15,16 @@ import {
|
|
|
10
15
|
detectGates,
|
|
11
16
|
runGates
|
|
12
17
|
} from "./chunk-62JNF5M2.js";
|
|
18
|
+
import "./chunk-7CAGWFAQ.js";
|
|
13
19
|
import {
|
|
14
20
|
loadFlows
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import
|
|
17
|
-
captureViewports,
|
|
18
|
-
previewDir,
|
|
19
|
-
runtimeSummary
|
|
20
|
-
} from "./chunk-UMDV4ITQ.js";
|
|
21
|
-
import "./chunk-7CAGWFAQ.js";
|
|
22
|
-
import "./chunk-N7YEWQGZ.js";
|
|
21
|
+
} from "./chunk-CGOFK6EM.js";
|
|
22
|
+
import "./chunk-S7LDOWMS.js";
|
|
23
23
|
import {
|
|
24
24
|
findChrome
|
|
25
25
|
} from "./chunk-PZV2FJE5.js";
|
|
26
26
|
import "./chunk-DABIMOMV.js";
|
|
27
|
+
import "./chunk-ZNV63ZIK.js";
|
|
27
28
|
|
|
28
29
|
// src/mcp/server.ts
|
|
29
30
|
import readline from "readline";
|
|
@@ -75,7 +76,7 @@ ${list.join("\n")}`);
|
|
|
75
76
|
if (flows.length === 0) return "no flows declared \u2014 add .squint/flows/<name>.flow";
|
|
76
77
|
const chrome = findChrome();
|
|
77
78
|
if (!chrome) return "no Chrome/Chromium found";
|
|
78
|
-
const { runFlow } = await import("./cdp-
|
|
79
|
+
const { runFlow } = await import("./cdp-V47GTLXG.js");
|
|
79
80
|
const lines = [];
|
|
80
81
|
for (const flow of flows) {
|
|
81
82
|
const result = await runFlow(chrome, url, flow, previewDir(cwd));
|
|
@@ -86,6 +87,41 @@ ${list.join("\n")}`);
|
|
|
86
87
|
return lines.join("\n");
|
|
87
88
|
}
|
|
88
89
|
},
|
|
90
|
+
{
|
|
91
|
+
name: "squint_flow_suggest",
|
|
92
|
+
description: "Draft a smoke flow per declared route (.squint/routes) from the live page's own headings \u2014 goto/expect/shot files in .squint/flows/, existing flows untouched.",
|
|
93
|
+
inputSchema: { type: "object", properties: { url: { type: "string" } }, required: ["url"] },
|
|
94
|
+
async run(args, cwd) {
|
|
95
|
+
const chrome = findChrome();
|
|
96
|
+
if (!chrome) return "no Chrome/Chromium found";
|
|
97
|
+
const { suggestFlows } = await import("./flows-SYDNB5IW.js");
|
|
98
|
+
const { created, skipped } = await suggestFlows(cwd, String(args.url ?? ""), chrome);
|
|
99
|
+
return [
|
|
100
|
+
created.length > 0 ? `drafted: ${created.join(", ")}` : "nothing drafted",
|
|
101
|
+
skipped.length > 0 ? `kept existing: ${skipped.join(", ")}` : ""
|
|
102
|
+
].filter(Boolean).join("\n");
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: "squint_receipt_verify",
|
|
107
|
+
description: "Verify a .squint/receipts/*.json verification receipt: recompute its digest and report whether the report or screenshots were edited after sealing.",
|
|
108
|
+
inputSchema: { type: "object", properties: { path: { type: "string" } }, required: ["path"] },
|
|
109
|
+
async run(args, cwd) {
|
|
110
|
+
const fs = await import("fs");
|
|
111
|
+
const path = await import("path");
|
|
112
|
+
const { verifyReceipt } = await import("./receipts-MCEUXL6I.js");
|
|
113
|
+
const file = path.isAbsolute(String(args.path)) ? String(args.path) : path.join(cwd, String(args.path));
|
|
114
|
+
let receipt;
|
|
115
|
+
try {
|
|
116
|
+
receipt = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
117
|
+
} catch (error) {
|
|
118
|
+
return `unreadable receipt: ${error instanceof Error ? error.message : String(error)}`;
|
|
119
|
+
}
|
|
120
|
+
const intact = verifyReceipt(receipt);
|
|
121
|
+
const ok = receipt.report?.ok;
|
|
122
|
+
return intact ? `digest intact \u2014 this receipt is what squint sealed (run ok: ${ok}, git ${receipt.gitHead ?? "n/a"}, squint ${receipt.version})` : "DIGEST MISMATCH \u2014 this receipt was edited after sealing; do not trust it";
|
|
123
|
+
}
|
|
124
|
+
},
|
|
89
125
|
{
|
|
90
126
|
name: "squint_context",
|
|
91
127
|
description: "Itemize what squint injects into engine asks \u2014 token cost per source with staleness warnings (stale locks, generic skill triggers, oversized always-on context).",
|
package/package.json
CHANGED