jig-ui 0.17.0 → 0.17.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.
- package/CHANGELOG.md +13 -0
- package/dist/index.js +35 -3
- package/package.json +1 -1
- package/templates/COMMAND.md.tmpl +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.17.1
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **The gate judges the critiques a session touched, not every critique.**
|
|
8
|
+
A spec for one page could not finish because another page's critique
|
|
9
|
+
predated 0.17.0, whose new rules that critique had never judged, and a
|
|
10
|
+
record the project had set aside still failed for screenshots it no longer
|
|
11
|
+
had. The gate now checks a critique with a file changed since the session
|
|
12
|
+
began, and the current spec's surface after `critique`. A folder whose name
|
|
13
|
+
starts with `_` is set aside and never judged. With no transcript, as when
|
|
14
|
+
the gate is run by hand, it checks every critique as before.
|
|
15
|
+
|
|
3
16
|
## 0.17.0
|
|
4
17
|
|
|
5
18
|
Thirteen more tells of a generated page, ten of them caught by `check`, and a
|
package/dist/index.js
CHANGED
|
@@ -6159,7 +6159,7 @@ async function ensureProbes(opts) {
|
|
|
6159
6159
|
function critiquedSurfaces(projectRoot) {
|
|
6160
6160
|
const root = join32(projectRoot, ".jig", "critique");
|
|
6161
6161
|
if (!existsSync19(root)) return [];
|
|
6162
|
-
return readdirSync12(root).filter((surface) => existsSync19(join32(root, surface, "screen.json")) || existsSync19(join32(root, surface, "code.json")));
|
|
6162
|
+
return readdirSync12(root).filter((surface) => !surface.startsWith("_") && (existsSync19(join32(root, surface, "screen.json")) || existsSync19(join32(root, surface, "code.json"))));
|
|
6163
6163
|
}
|
|
6164
6164
|
|
|
6165
6165
|
// src/probe/check.ts
|
|
@@ -6575,7 +6575,7 @@ function verifyVerdicts(opts) {
|
|
|
6575
6575
|
}
|
|
6576
6576
|
|
|
6577
6577
|
// src/commands/gate.ts
|
|
6578
|
-
import { existsSync as existsSync24, mkdirSync as mkdirSync8, readdirSync as readdirSync15, readFileSync as readFileSync30, writeFileSync as writeFileSync7 } from "fs";
|
|
6578
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync8, readdirSync as readdirSync15, readFileSync as readFileSync30, statSync as statSync4, writeFileSync as writeFileSync7 } from "fs";
|
|
6579
6579
|
import { createHash as createHash2 } from "crypto";
|
|
6580
6580
|
import { join as join37 } from "path";
|
|
6581
6581
|
var MAX_BLOCKS = 3;
|
|
@@ -6624,6 +6624,37 @@ function asksOwner(text) {
|
|
|
6624
6624
|
return /\?(?=[\s)\]"'*_]|$)/.test(prose);
|
|
6625
6625
|
}
|
|
6626
6626
|
var ASKS_THE_OWNER = /* @__PURE__ */ new Set(["decide", "spec", "mockup"]);
|
|
6627
|
+
function sessionStart(transcriptPath) {
|
|
6628
|
+
if (!transcriptPath || !existsSync24(transcriptPath)) return void 0;
|
|
6629
|
+
try {
|
|
6630
|
+
for (const line of readFileSync30(transcriptPath, "utf8").split("\n")) {
|
|
6631
|
+
const m = /"timestamp"\s*:\s*"([^"]+)"/.exec(line);
|
|
6632
|
+
if (m) {
|
|
6633
|
+
const t = Date.parse(m[1]);
|
|
6634
|
+
if (!Number.isNaN(t)) return t;
|
|
6635
|
+
}
|
|
6636
|
+
}
|
|
6637
|
+
} catch {
|
|
6638
|
+
}
|
|
6639
|
+
return void 0;
|
|
6640
|
+
}
|
|
6641
|
+
function newestMtime(dir) {
|
|
6642
|
+
let newest = 0;
|
|
6643
|
+
for (const name of readdirSync15(dir, { withFileTypes: true })) {
|
|
6644
|
+
const path = join37(dir, name.name);
|
|
6645
|
+
newest = Math.max(newest, name.isDirectory() ? newestMtime(path) : statSync4(path).mtimeMs);
|
|
6646
|
+
}
|
|
6647
|
+
return newest;
|
|
6648
|
+
}
|
|
6649
|
+
function surfacesInPlay(root, command, transcriptPath) {
|
|
6650
|
+
const critiqueDir = join37(root, ".jig", "critique");
|
|
6651
|
+
if (!existsSync24(critiqueDir)) return [];
|
|
6652
|
+
const all = readdirSync15(critiqueDir, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith("_") && !d.name.startsWith(".")).map((d) => d.name);
|
|
6653
|
+
const start = sessionStart(transcriptPath);
|
|
6654
|
+
if (start === void 0) return all;
|
|
6655
|
+
const current = command === "critique" ? /^\s*surface\s*:\s*(.+)$/im.exec(newestSpec(root)?.body.split(/^---\s*$/m)[1] ?? "")?.[1]?.trim().replace(/^["']|["']$/g, "") : void 0;
|
|
6656
|
+
return all.filter((s) => s === current || newestMtime(join37(critiqueDir, s)) >= start - 1e3);
|
|
6657
|
+
}
|
|
6627
6658
|
function commandProblems(root, command) {
|
|
6628
6659
|
const problems = [];
|
|
6629
6660
|
const spec = newestSpec(root);
|
|
@@ -6715,7 +6746,7 @@ function gate(opts) {
|
|
|
6715
6746
|
problems.push(...verdictGuard(root, command));
|
|
6716
6747
|
const critiqueDir = join37(root, ".jig", "critique");
|
|
6717
6748
|
if (existsSync24(critiqueDir)) {
|
|
6718
|
-
for (const surface of
|
|
6749
|
+
for (const surface of surfacesInPlay(root, command, opts.input.transcript_path)) {
|
|
6719
6750
|
const dir = join37(critiqueDir, surface);
|
|
6720
6751
|
if (!existsSync24(join37(dir, "screen.json")) && !existsSync24(join37(dir, "code.json"))) continue;
|
|
6721
6752
|
const v = verifyVerdicts({ projectRoot: root, surface });
|
|
@@ -6780,6 +6811,7 @@ function verdictGuard(root, command) {
|
|
|
6780
6811
|
if (!existsSync24(critiqueDir)) return [];
|
|
6781
6812
|
const problems = [];
|
|
6782
6813
|
for (const surface of readdirSync15(critiqueDir)) {
|
|
6814
|
+
if (surface.startsWith("_")) continue;
|
|
6783
6815
|
const dir = join37(critiqueDir, surface);
|
|
6784
6816
|
const now = verdictChecksum(dir);
|
|
6785
6817
|
if (!now) continue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jig-ui",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"description": "A design system for coding agents. 143 numbered UI rules, brand x mode design tokens, and an installer for Claude Code, Codex, Cursor and opencode.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -1191,6 +1191,12 @@ blocking. It also refuses when a critique's verdict files changed after `critiqu
|
|
|
1191
1191
|
wrote them, in a session that did not run `critique`: a fix is judged by the next
|
|
1192
1192
|
review, never by the builder editing the last one.
|
|
1193
1193
|
|
|
1194
|
+
It judges the critiques this session touched: any with a file changed since the
|
|
1195
|
+
session began, and the current spec's surface when you ran `critique`. Another
|
|
1196
|
+
page's older critique does not hold you back. To set a critique aside for good,
|
|
1197
|
+
rename its folder with a leading underscore (`.jig/critique/_old-catalog`); the
|
|
1198
|
+
gate never judges it.
|
|
1199
|
+
|
|
1194
1200
|
A warning you are sure is right as it stands, because the detector guessed and the
|
|
1195
1201
|
guess is wrong here, is waived on its own line or the line above, in the file's
|
|
1196
1202
|
comment syntax: `jig-allow <ID>: <why>`. The reason is what the user reads, so write
|