yam-flow 0.1.4 → 0.1.6
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 +28 -0
- package/COMMANDS.md +4 -2
- package/README.md +8 -3
- package/dist/bin/yam.js +133 -14
- package/dist/lib/trust-kernel.d.ts +56 -1
- package/dist/lib/trust-kernel.js +149 -2
- package/package.json +2 -2
- package/references/trust-kernel.md +3 -0
- package/references/ueye-proof.md +79 -2
- package/references/ueye.md +44 -4
- package/skills/ueye/SKILL.md +29 -8
- package/src/bin/yam.ts +134 -12
- package/src/lib/trust-kernel.ts +208 -3
- package/templates/ueye-comparison.md +71 -0
- package/templates/ueye-review.md +71 -0
- package/yam.manifest.json +2 -2
package/src/bin/yam.ts
CHANGED
|
@@ -14,8 +14,10 @@ import {
|
|
|
14
14
|
buildMissionPatchEnvelope,
|
|
15
15
|
buildRollbackHint,
|
|
16
16
|
buildRuntimeBackendEvidence,
|
|
17
|
+
buildUeyeDesignCompletionGate,
|
|
17
18
|
buildUeyeVisualProvenance,
|
|
18
19
|
buildUeyeRunReport,
|
|
20
|
+
buildUeyeSurfaceContext,
|
|
19
21
|
buildYamCompletionProof,
|
|
20
22
|
detectDbSafetyText as detectTrustDbSafetyText,
|
|
21
23
|
isTruthStatus
|
|
@@ -139,7 +141,7 @@ Usage:
|
|
|
139
141
|
yam proof write [dir] [--format json|md] [--out file] [--route route] [--truth status] [--command text]
|
|
140
142
|
yam ueye capture --url URL --out screenshot.png [--viewport 1440x900] [--full-page] [--json]
|
|
141
143
|
yam ueye compare --reference ref.png --actual screenshot.png [--json]
|
|
142
|
-
yam ueye report [--reference ref.png] [--actual screenshot.png] [--json]
|
|
144
|
+
yam ueye report [--reference ref.png] [--actual screenshot.png] [--provider-context local] [--execution-surface in-app-browser] [--json]
|
|
143
145
|
yam media proof [--requested] [--attempted] [--output file] [--json]
|
|
144
146
|
yam runtime evidence [--backend terminal|in-app-browser|playwright|tmux|zellij] [--claim observed|started|stopped|cleanup-verified] [--json]
|
|
145
147
|
yam mission queue [--agent-id id] [--scope text] [--changed file] [--verification-hint text] [--json]
|
|
@@ -808,7 +810,7 @@ function toolsDoctorNextActionDetails({ pack, rows, riskNotes, frameworkChecklis
|
|
|
808
810
|
if (rows.some((row) => row.name === 'Yam skills' && row.status !== 'ready')) actions.push(nextActionDetail('install-skills', 'warning', 'skill install state is incomplete', 'run `yam install` and restart Codex before relying on installed skills', 'yam install'));
|
|
809
811
|
if (riskNotes.some((note) => note.level === 'danger')) actions.push(nextActionDetail('deep-safety', 'error', 'destructive database or production write signal detected', 'use $deep before claiming destructive database or production write safety', 'yam safety "<command or SQL>"'));
|
|
810
812
|
if (frameworkChecklist?.detected && !commands?.build && !commands?.typecheck) actions.push(nextActionDetail('verification-command', 'warning', 'build/typecheck command not detected', 'add or document a small build/typecheck command for implementation verification', 'yam pack .'));
|
|
811
|
-
if (frameworkChecklist?.uiLike) actions.push(nextActionDetail('ueye-evidence', 'info', 'UI-like project detected', 'for Ueye verified claims, record reference, actual screenshot, and
|
|
813
|
+
if (frameworkChecklist?.uiLike) actions.push(nextActionDetail('ueye-evidence', 'info', 'UI-like project detected', 'for Ueye verified claims, record reference, actual screenshot, comparison result, and surface context', 'yam ueye report --reference ref.png --actual shot.png --provider-context local --execution-surface in-app-browser --json'));
|
|
812
814
|
return uniqueNextActionDetails(actions);
|
|
813
815
|
}
|
|
814
816
|
|
|
@@ -1348,18 +1350,18 @@ Opt-in visual evidence helpers. Ueye stays one skill: fast by default, capture/c
|
|
|
1348
1350
|
Usage:
|
|
1349
1351
|
yam ueye capture --url URL --out screenshot.png [--viewport 1440x900] [--full-page] [--json]
|
|
1350
1352
|
yam ueye compare --reference ref.png --actual screenshot.png [--json]
|
|
1351
|
-
yam ueye report [--reference ref.png] [--actual screenshot.png] [--review-session-id id] [--similar text] [--different text] [--missing text] [--resolved text] [--new-finding text] [--still-open text] [--regression text] [--viewport 1440x900] [--state default] [--design-quality pass|needs-polish|fails|not-checked] [--json]
|
|
1353
|
+
yam ueye report [--reference ref.png] [--actual screenshot.png] [--review-session-id id] [--provider-context local] [--execution-surface in-app-browser] [--app-surface codex-app] [--browser-surface in-app-browser] [--control-mode manual|automated] [--preserved-state] [--preserved-url URL] [--completion-claim draft|needs-polish|done] [--strict] [--design-score n] [--p0 text] [--p1 text] [--states-checked] [--mobile-checked] [--contrast-checked] [--similar text] [--different text] [--missing text] [--resolved text] [--new-finding text] [--still-open text] [--regression text] [--viewport 1440x900] [--state default] [--design-quality pass|needs-polish|fails|not-checked] [--json]
|
|
1352
1354
|
|
|
1353
1355
|
Notes:
|
|
1354
1356
|
capture uses a locally available Playwright install when present. It does not download browsers or install dependencies.
|
|
1355
1357
|
compare uses local files only and reports sha256, dimensions, comparison_result, and proof-ready visual provenance.
|
|
1356
|
-
report produces a proof-ready Ueye visual run report and continuity/comparison record without requiring a new capture.
|
|
1358
|
+
report produces a proof-ready Ueye visual run report, design completion gate, and continuity/comparison record without requiring a new capture.
|
|
1357
1359
|
`);
|
|
1358
1360
|
}
|
|
1359
1361
|
|
|
1360
1362
|
async function ueyeCapture(args = []) {
|
|
1361
1363
|
if (args[0] === 'help' || args[0] === '--help' || args[0] === '-h') return ueyeUsage();
|
|
1362
|
-
const flags = parseSimpleFlags(args, new Set(['url', 'out', 'viewport', 'wait-until', 'timeout', 'full-page', 'json']));
|
|
1364
|
+
const flags = parseSimpleFlags(args, new Set(['url', 'out', 'viewport', 'wait-until', 'timeout', 'full-page', 'provider-context', 'provider-badge', 'execution-surface', 'app-surface', 'browser-surface', 'control-mode', 'preserved-state', 'preserved-url', 'evidence-id', 'screenshot-id', 'json']));
|
|
1363
1365
|
const url = String(flags.url || '');
|
|
1364
1366
|
const out = String(flags.out || '');
|
|
1365
1367
|
if (!url || !out) {
|
|
@@ -1384,6 +1386,24 @@ async function ueyeCapture(args = []) {
|
|
|
1384
1386
|
await page.goto(url, { waitUntil, timeout });
|
|
1385
1387
|
await page.screenshot({ path: target, fullPage: Boolean(flags.full_page) });
|
|
1386
1388
|
const info = await imageFileInfo(target);
|
|
1389
|
+
const surfaceContext = buildUeyeSurfaceContext({
|
|
1390
|
+
provider_context: String(flags.provider_context || 'local-playwright'),
|
|
1391
|
+
provider_badge: String(flags.provider_badge || flags.provider_context || 'local-playwright'),
|
|
1392
|
+
execution_surface: String(flags.execution_surface || 'browser-capture'),
|
|
1393
|
+
app_surface: String(flags.app_surface || 'local-project'),
|
|
1394
|
+
browser_surface: String(flags.browser_surface || 'playwright'),
|
|
1395
|
+
control_mode: String(flags.control_mode || 'automated-capture'),
|
|
1396
|
+
route: 'ueye',
|
|
1397
|
+
mode: 'capture',
|
|
1398
|
+
url,
|
|
1399
|
+
viewport: `${viewport.width}x${viewport.height}`,
|
|
1400
|
+
screenshot_id: String(flags.screenshot_id || path.basename(target)),
|
|
1401
|
+
evidence_id: String(flags.evidence_id || `ueye-capture-${timestampId()}`),
|
|
1402
|
+
preserved_state: Boolean(flags.preserved_state),
|
|
1403
|
+
preserved_url: String(flags.preserved_url || url),
|
|
1404
|
+
local_only: true,
|
|
1405
|
+
truth_status: 'verified'
|
|
1406
|
+
});
|
|
1387
1407
|
const result = {
|
|
1388
1408
|
schema: 'yam.ueye-capture.v1',
|
|
1389
1409
|
status: 'verified',
|
|
@@ -1393,6 +1413,7 @@ async function ueyeCapture(args = []) {
|
|
|
1393
1413
|
full_page: Boolean(flags.full_page),
|
|
1394
1414
|
sha256: info.sha256,
|
|
1395
1415
|
dimensions: info.dimensions,
|
|
1416
|
+
surface_context: surfaceContext,
|
|
1396
1417
|
visual_evidence: `browser screenshot captured: ${target} (${info.dimensions}, sha256:${info.sha256})`
|
|
1397
1418
|
};
|
|
1398
1419
|
printJsonOrHuman(result, Boolean(flags.json), 'Ueye capture');
|
|
@@ -1415,7 +1436,7 @@ async function ueyeCapture(args = []) {
|
|
|
1415
1436
|
|
|
1416
1437
|
async function ueyeCompare(args = []) {
|
|
1417
1438
|
if (args[0] === 'help' || args[0] === '--help' || args[0] === '-h') return ueyeUsage();
|
|
1418
|
-
const flags = parseSimpleFlags(args, new Set(['reference', 'ref', 'actual', 'screenshot', 'json', 'reference-id', 'screenshot-id']));
|
|
1439
|
+
const flags = parseSimpleFlags(args, new Set(['reference', 'ref', 'actual', 'screenshot', 'json', 'reference-id', 'screenshot-id', 'provider-context', 'provider-badge', 'execution-surface', 'app-surface', 'browser-surface', 'control-mode', 'preserved-state', 'preserved-url', 'url', 'viewport', 'evidence-id']));
|
|
1419
1440
|
const reference = String(flags.reference || flags.ref || '');
|
|
1420
1441
|
const actual = String(flags.actual || flags.screenshot || '');
|
|
1421
1442
|
if (!reference || !actual) {
|
|
@@ -1436,12 +1457,35 @@ async function ueyeCompare(args = []) {
|
|
|
1436
1457
|
const sameDimensions = referenceInfo.dimensions === actualInfo.dimensions;
|
|
1437
1458
|
const comparisonResult = exactMatch ? 'matched' : 'different';
|
|
1438
1459
|
const truthStatus = exactMatch ? 'verified' : 'partial';
|
|
1460
|
+
const surfaceContext = buildUeyeSurfaceContext({
|
|
1461
|
+
provider_context: String(flags.provider_context || 'local-file'),
|
|
1462
|
+
provider_badge: String(flags.provider_badge || flags.provider_context || 'local-file'),
|
|
1463
|
+
execution_surface: String(flags.execution_surface || 'local-file-compare'),
|
|
1464
|
+
app_surface: String(flags.app_surface || 'local-project'),
|
|
1465
|
+
browser_surface: String(flags.browser_surface || 'not-used'),
|
|
1466
|
+
control_mode: String(flags.control_mode || 'local-compare'),
|
|
1467
|
+
route: 'ueye',
|
|
1468
|
+
mode: 'compare',
|
|
1469
|
+
url: String(flags.url || ''),
|
|
1470
|
+
viewport: String(flags.viewport || ''),
|
|
1471
|
+
screenshot_id: String(flags.screenshot_id || path.basename(actualPath)),
|
|
1472
|
+
evidence_id: String(flags.evidence_id || `ueye-compare-${timestampId()}`),
|
|
1473
|
+
preserved_state: Boolean(flags.preserved_state),
|
|
1474
|
+
preserved_url: String(flags.preserved_url || flags.url || ''),
|
|
1475
|
+
local_only: true,
|
|
1476
|
+
truth_status: truthStatus
|
|
1477
|
+
});
|
|
1439
1478
|
const provenance = buildUeyeVisualProvenance({
|
|
1440
1479
|
source_kind: 'implementation_screenshot',
|
|
1441
1480
|
source_path: actualPath,
|
|
1442
1481
|
source_hash: actualInfo.sha256,
|
|
1443
1482
|
reference_id: String(flags.reference_id || path.basename(referencePath)),
|
|
1444
1483
|
screenshot_id: String(flags.screenshot_id || path.basename(actualPath)),
|
|
1484
|
+
provider_context: surfaceContext.provider_context,
|
|
1485
|
+
provider_badge: surfaceContext.provider_badge,
|
|
1486
|
+
execution_surface: surfaceContext.execution_surface,
|
|
1487
|
+
app_surface: surfaceContext.app_surface,
|
|
1488
|
+
browser_surface: surfaceContext.browser_surface,
|
|
1445
1489
|
local_only: true,
|
|
1446
1490
|
redacted: false,
|
|
1447
1491
|
operator_provided: false,
|
|
@@ -1456,6 +1500,7 @@ async function ueyeCompare(args = []) {
|
|
|
1456
1500
|
same_dimensions: sameDimensions,
|
|
1457
1501
|
reference: referenceInfo,
|
|
1458
1502
|
actual: actualInfo,
|
|
1503
|
+
surface_context: surfaceContext,
|
|
1459
1504
|
visual_evidence: `browser/local screenshot comparison executed: reference=${referencePath}, actual=${actualPath}, result=${comparisonResult}`,
|
|
1460
1505
|
visual_provenance: provenance,
|
|
1461
1506
|
proof_hint: `yam proof --route ueye --truth ${truthStatus} --visual "browser/local screenshot comparison executed: ${comparisonResult}" --visual-provenance '${JSON.stringify(provenance)}' --require-visual`
|
|
@@ -1476,7 +1521,7 @@ async function ueyeCompare(args = []) {
|
|
|
1476
1521
|
|
|
1477
1522
|
async function ueyeReport(args = []) {
|
|
1478
1523
|
if (args[0] === 'help' || args[0] === '--help' || args[0] === '-h') return ueyeUsage();
|
|
1479
|
-
const flags = parseSimpleFlags(args, new Set(['reference', 'ref', 'actual', 'screenshot', 'capture-backend', 'compare-backend', 'design-quality', 'blocked-reason', 'next-action', 'next-visual-action', 'review-session-id', 'reference-id', 'screenshot-id', 'previous-screenshot-id', 'current-screenshot-id', 'previous-report', 'comparison-notes', 'similar', 'different', 'missing', 'resolved', 'new-finding', 'still-open', 'regression', 'viewport', 'state', 'json']));
|
|
1524
|
+
const flags = parseSimpleFlags(args, new Set(['reference', 'ref', 'actual', 'screenshot', 'capture-backend', 'compare-backend', 'design-quality', 'blocked-reason', 'next-action', 'next-visual-action', 'review-session-id', 'reference-id', 'screenshot-id', 'previous-screenshot-id', 'current-screenshot-id', 'previous-report', 'comparison-notes', 'similar', 'different', 'missing', 'resolved', 'new-finding', 'still-open', 'regression', 'viewport', 'state', 'provider-context', 'provider-badge', 'execution-surface', 'app-surface', 'browser-surface', 'control-mode', 'preserved-state', 'preserved-url', 'url', 'evidence-id', 'completion-claim', 'completion-status', 'gate-mode', 'strict', 'design-score', 'min-design-score', 'p0', 'p1', 'open-p0', 'open-p1', 'states-checked', 'mobile-checked', 'responsive-checked', 'contrast-checked', 'accessibility-checked', 'cta-checked', 'direction-locked', 'reference-read', 'comparison-result', 'json']));
|
|
1480
1525
|
const reference = String(flags.reference || flags.ref || '');
|
|
1481
1526
|
const actual = String(flags.actual || flags.screenshot || '');
|
|
1482
1527
|
const referenceSources = [];
|
|
@@ -1485,6 +1530,24 @@ async function ueyeReport(args = []) {
|
|
|
1485
1530
|
let blockedReason = String(flags.blocked_reason || '');
|
|
1486
1531
|
const reviewSessionId = String(flags.review_session_id || `ueye-${timestampId()}`);
|
|
1487
1532
|
const previousReport = await readPreviousUeyeReport(flags.previous_report);
|
|
1533
|
+
const surfaceContext = buildUeyeSurfaceContext({
|
|
1534
|
+
provider_context: String(flags.provider_context || 'not-recorded'),
|
|
1535
|
+
provider_badge: String(flags.provider_badge || flags.provider_context || 'not-recorded'),
|
|
1536
|
+
execution_surface: String(flags.execution_surface || flags.capture_backend || 'not-recorded'),
|
|
1537
|
+
app_surface: String(flags.app_surface || 'not-recorded'),
|
|
1538
|
+
browser_surface: String(flags.browser_surface || flags.capture_backend || 'not-recorded'),
|
|
1539
|
+
control_mode: String(flags.control_mode || 'not-recorded'),
|
|
1540
|
+
route: 'ueye',
|
|
1541
|
+
mode: 'report',
|
|
1542
|
+
url: String(flags.url || flags.preserved_url || ''),
|
|
1543
|
+
viewport: String(flags.viewport || ''),
|
|
1544
|
+
screenshot_id: String(flags.current_screenshot_id || flags.screenshot_id || ''),
|
|
1545
|
+
evidence_id: String(flags.evidence_id || reviewSessionId),
|
|
1546
|
+
preserved_state: Boolean(flags.preserved_state),
|
|
1547
|
+
preserved_url: String(flags.preserved_url || flags.url || ''),
|
|
1548
|
+
local_only: true,
|
|
1549
|
+
truth_status: actual ? 'partial' : 'assumed'
|
|
1550
|
+
});
|
|
1488
1551
|
|
|
1489
1552
|
try {
|
|
1490
1553
|
if (reference) {
|
|
@@ -1494,6 +1557,11 @@ async function ueyeReport(args = []) {
|
|
|
1494
1557
|
source_path: info.path,
|
|
1495
1558
|
source_hash: info.sha256,
|
|
1496
1559
|
reference_id: String(flags.reference_id || path.basename(info.path)),
|
|
1560
|
+
provider_context: surfaceContext.provider_context,
|
|
1561
|
+
provider_badge: surfaceContext.provider_badge,
|
|
1562
|
+
execution_surface: surfaceContext.execution_surface,
|
|
1563
|
+
app_surface: surfaceContext.app_surface,
|
|
1564
|
+
browser_surface: surfaceContext.browser_surface,
|
|
1497
1565
|
local_only: true,
|
|
1498
1566
|
operator_provided: true,
|
|
1499
1567
|
comparison_result: 'reference-recorded',
|
|
@@ -1508,13 +1576,20 @@ async function ueyeReport(args = []) {
|
|
|
1508
1576
|
source_hash: info.sha256,
|
|
1509
1577
|
reference_id: String(flags.reference_id || referenceSources[0]?.reference_id || ''),
|
|
1510
1578
|
screenshot_id: String(flags.current_screenshot_id || flags.screenshot_id || path.basename(info.path)),
|
|
1579
|
+
provider_context: surfaceContext.provider_context,
|
|
1580
|
+
provider_badge: surfaceContext.provider_badge,
|
|
1581
|
+
execution_surface: surfaceContext.execution_surface,
|
|
1582
|
+
app_surface: surfaceContext.app_surface,
|
|
1583
|
+
browser_surface: surfaceContext.browser_surface,
|
|
1511
1584
|
local_only: true,
|
|
1512
1585
|
operator_provided: false,
|
|
1513
1586
|
comparison_result: 'implementation-recorded',
|
|
1514
1587
|
truth_status: 'partial'
|
|
1515
1588
|
}));
|
|
1516
1589
|
}
|
|
1517
|
-
if (
|
|
1590
|
+
if (flags.comparison_result) {
|
|
1591
|
+
comparisonResult = normalizeUeyeComparisonResult(flags.comparison_result);
|
|
1592
|
+
} else if (reference && actual && referenceSources[0]?.source_hash === implementationSources[0]?.source_hash) {
|
|
1518
1593
|
comparisonResult = 'matched';
|
|
1519
1594
|
} else if (reference && actual) {
|
|
1520
1595
|
comparisonResult = 'different';
|
|
@@ -1526,8 +1601,29 @@ async function ueyeReport(args = []) {
|
|
|
1526
1601
|
const report = buildUeyeRunReport({
|
|
1527
1602
|
reference_sources: referenceSources,
|
|
1528
1603
|
implementation_sources: implementationSources,
|
|
1604
|
+
surface_context: {
|
|
1605
|
+
...surfaceContext,
|
|
1606
|
+
screenshot_id: surfaceContext.screenshot_id || String(flags.current_screenshot_id || flags.screenshot_id || implementationSources[0]?.screenshot_id || ''),
|
|
1607
|
+
truth_status: blockedReason ? 'blocked' : implementationSources.length ? 'partial' : 'assumed'
|
|
1608
|
+
},
|
|
1529
1609
|
comparison_result: comparisonResult,
|
|
1530
1610
|
design_quality: String(flags.design_quality || 'not-checked'),
|
|
1611
|
+
design_completion_gate: {
|
|
1612
|
+
mode: flags.strict || flags.gate_mode === 'strict' ? 'strict' : 'fast',
|
|
1613
|
+
completion_claim: flags.completion_claim || flags.completion_status || 'draft',
|
|
1614
|
+
design_score: numberOrNull(flags.design_score),
|
|
1615
|
+
min_design_score: numberOrNull(flags.min_design_score) ?? 8,
|
|
1616
|
+
p0: [...arrayFlag(flags.p0), ...arrayFlag(flags.open_p0)],
|
|
1617
|
+
p1: [...arrayFlag(flags.p1), ...arrayFlag(flags.open_p1)],
|
|
1618
|
+
states_checked: Boolean(flags.states_checked),
|
|
1619
|
+
mobile_checked: Boolean(flags.mobile_checked),
|
|
1620
|
+
responsive_checked: Boolean(flags.responsive_checked),
|
|
1621
|
+
contrast_checked: Boolean(flags.contrast_checked),
|
|
1622
|
+
accessibility_checked: Boolean(flags.accessibility_checked),
|
|
1623
|
+
cta_checked: Boolean(flags.cta_checked),
|
|
1624
|
+
direction_locked: Boolean(flags.direction_locked),
|
|
1625
|
+
reference_read: Boolean(flags.reference_read)
|
|
1626
|
+
},
|
|
1531
1627
|
blocked_reason: blockedReason,
|
|
1532
1628
|
next_action: String(flags.next_visual_action || flags.next_action || '')
|
|
1533
1629
|
});
|
|
@@ -1536,6 +1632,8 @@ async function ueyeReport(args = []) {
|
|
|
1536
1632
|
previousReport,
|
|
1537
1633
|
referenceSources,
|
|
1538
1634
|
implementationSources,
|
|
1635
|
+
surfaceContext: report.surface_context,
|
|
1636
|
+
designCompletionGate: report.design_completion_gate,
|
|
1539
1637
|
comparisonResult,
|
|
1540
1638
|
designQuality: String(flags.design_quality || 'not-checked'),
|
|
1541
1639
|
similar: arrayFlag(flags.similar),
|
|
@@ -1593,6 +1691,8 @@ function buildUeyeComparisonReport({
|
|
|
1593
1691
|
previousReport,
|
|
1594
1692
|
referenceSources,
|
|
1595
1693
|
implementationSources,
|
|
1694
|
+
surfaceContext,
|
|
1695
|
+
designCompletionGate,
|
|
1596
1696
|
comparisonResult,
|
|
1597
1697
|
designQuality,
|
|
1598
1698
|
similar,
|
|
@@ -1633,6 +1733,8 @@ function buildUeyeComparisonReport({
|
|
|
1633
1733
|
reference_count: referenceSources.length,
|
|
1634
1734
|
implementation_count: implementationSources.length
|
|
1635
1735
|
},
|
|
1736
|
+
surface_context: surfaceContext || buildUeyeSurfaceContext(),
|
|
1737
|
+
design_completion_gate: designCompletionGate || null,
|
|
1636
1738
|
comparison_result: comparisonResult,
|
|
1637
1739
|
design_quality: designQuality,
|
|
1638
1740
|
similar,
|
|
@@ -1652,6 +1754,12 @@ function buildUeyeComparisonReport({
|
|
|
1652
1754
|
};
|
|
1653
1755
|
}
|
|
1654
1756
|
|
|
1757
|
+
function normalizeUeyeComparisonResult(value = '') {
|
|
1758
|
+
const text = String(value || '').toLowerCase();
|
|
1759
|
+
if (['matched', 'similar', 'different', 'not-verified', 'not-applicable'].includes(text)) return text;
|
|
1760
|
+
return 'not-verified';
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1655
1763
|
async function media(args = []) {
|
|
1656
1764
|
const subcommand = args[0] || 'help';
|
|
1657
1765
|
if (subcommand === 'help' || subcommand === '--help' || subcommand === '-h') return mediaUsage();
|
|
@@ -1935,7 +2043,7 @@ function parseSimpleFlags(args = [], allowed = new Set<string>()) {
|
|
|
1935
2043
|
const key = rawKey.slice(2);
|
|
1936
2044
|
if (allowed.size && !allowed.has(key)) continue;
|
|
1937
2045
|
const normalizedKey = key.replace(/-/g, '_');
|
|
1938
|
-
if (['json', 'full-page', 'requested', 'attempted', 'available', 'wait-loop', 'cleanup-checked'].includes(key)) {
|
|
2046
|
+
if (['json', 'full-page', 'requested', 'attempted', 'available', 'wait-loop', 'cleanup-checked', 'strict', 'preserved-state', 'states-checked', 'mobile-checked', 'responsive-checked', 'contrast-checked', 'accessibility-checked', 'cta-checked', 'direction-locked', 'reference-read'].includes(key)) {
|
|
1939
2047
|
flags[normalizedKey] = true;
|
|
1940
2048
|
continue;
|
|
1941
2049
|
}
|
|
@@ -2085,6 +2193,7 @@ async function proof(args = []) {
|
|
|
2085
2193
|
printProofList('Mission patch envelope', summary.missionEnvelope || []);
|
|
2086
2194
|
printProofList('Rollback hint', summary.rollbackHint || []);
|
|
2087
2195
|
printProofList('Media proof', summary.mediaProof || []);
|
|
2196
|
+
printProofList('Design completion', summary.designCompletion || []);
|
|
2088
2197
|
printProofList('Changed surfaces', summary.changed);
|
|
2089
2198
|
printProofList('Skipped', summary.skipped);
|
|
2090
2199
|
printProofList('Blocked', summary.blocked);
|
|
@@ -2180,6 +2289,10 @@ function buildProofSummary(parsed, artifact) {
|
|
|
2180
2289
|
...structuredEvidenceList(artifact.mediaProof),
|
|
2181
2290
|
...structuredEvidenceList(parsed.flags.media_proof)
|
|
2182
2291
|
],
|
|
2292
|
+
designCompletion: [
|
|
2293
|
+
...structuredEvidenceList(artifact.designCompletion),
|
|
2294
|
+
...structuredEvidenceList(parsed.flags.design_completion)
|
|
2295
|
+
],
|
|
2183
2296
|
cleanup: parsed.flags.cleanup || artifact.cleanup || '',
|
|
2184
2297
|
changed: [...artifact.changed, ...arrayFlag(parsed.flags.changed)],
|
|
2185
2298
|
skipped: [...artifact.skipped, ...arrayFlag(parsed.flags.skipped)],
|
|
@@ -2245,6 +2358,9 @@ function renderProofMarkdown(summary) {
|
|
|
2245
2358
|
'## Media proof',
|
|
2246
2359
|
...renderProofMarkdownList(summary.mediaProof || []),
|
|
2247
2360
|
'',
|
|
2361
|
+
'## Design completion',
|
|
2362
|
+
...renderProofMarkdownList(summary.designCompletion || []),
|
|
2363
|
+
'',
|
|
2248
2364
|
'## Changed surfaces',
|
|
2249
2365
|
...renderProofMarkdownList(summary.changed),
|
|
2250
2366
|
'',
|
|
@@ -2277,7 +2393,7 @@ function renderProofMarkdownList(values) {
|
|
|
2277
2393
|
function parseProofArgs(args = []) {
|
|
2278
2394
|
const flags: AnyRecord = {};
|
|
2279
2395
|
const positionals: string[] = [];
|
|
2280
|
-
const aliases = new Set(['goal', 'route', 'truth', 'command', 'evidence', 'visual', 'runtime', 'runtime-backend', 'runtime-claim', 'runtime-evidence-id', 'runtime-command', 'cleanup-checked', 'runtime-note', 'runtime-backend-evidence', 'visual-provenance', 'mission-envelope', 'rollback-hint', 'media-proof', 'cleanup', 'changed', 'skipped', 'blocked', 'assumed', 'assumption', 'unverified', 'from', 'format', 'out', 'file', 'json', 'require-runtime', 'require-real-runtime', 'require-tmux', 'require-visual']);
|
|
2396
|
+
const aliases = new Set(['goal', 'route', 'truth', 'command', 'evidence', 'visual', 'runtime', 'runtime-backend', 'runtime-claim', 'runtime-evidence-id', 'runtime-command', 'cleanup-checked', 'runtime-note', 'runtime-backend-evidence', 'visual-provenance', 'mission-envelope', 'rollback-hint', 'media-proof', 'design-completion', 'cleanup', 'changed', 'skipped', 'blocked', 'assumed', 'assumption', 'unverified', 'from', 'format', 'out', 'file', 'json', 'require-runtime', 'require-real-runtime', 'require-tmux', 'require-visual']);
|
|
2281
2397
|
for (let index = 0; index < args.length; index += 1) {
|
|
2282
2398
|
const arg = args[index];
|
|
2283
2399
|
if (arg.startsWith('--')) {
|
|
@@ -2291,7 +2407,7 @@ function parseProofArgs(args = []) {
|
|
|
2291
2407
|
}
|
|
2292
2408
|
const value = inlineValue ?? args[index + 1] ?? '';
|
|
2293
2409
|
if (inlineValue === undefined) index += 1;
|
|
2294
|
-
if (['command', 'evidence', 'visual', 'runtime', 'runtime-backend-evidence', 'visual-provenance', 'mission-envelope', 'rollback-hint', 'media-proof', 'changed', 'skipped', 'blocked', 'assumed', 'assumption', 'unverified'].includes(key)) {
|
|
2410
|
+
if (['command', 'evidence', 'visual', 'runtime', 'runtime-backend-evidence', 'visual-provenance', 'mission-envelope', 'rollback-hint', 'media-proof', 'design-completion', 'changed', 'skipped', 'blocked', 'assumed', 'assumption', 'unverified'].includes(key)) {
|
|
2295
2411
|
flags[normalizedKey] = [...arrayFlag(flags[normalizedKey]), value];
|
|
2296
2412
|
} else {
|
|
2297
2413
|
flags[normalizedKey] = value;
|
|
@@ -2334,6 +2450,7 @@ function emptyProofArtifact() {
|
|
|
2334
2450
|
missionEnvelope: [],
|
|
2335
2451
|
rollbackHint: [],
|
|
2336
2452
|
mediaProof: [],
|
|
2453
|
+
designCompletion: [],
|
|
2337
2454
|
cleanup: '',
|
|
2338
2455
|
changed: [],
|
|
2339
2456
|
skipped: [],
|
|
@@ -2361,6 +2478,7 @@ async function parseProofJson(file, empty) {
|
|
|
2361
2478
|
missionEnvelope: structuredEvidenceList(data.missionEnvelope || data.mission_envelope),
|
|
2362
2479
|
rollbackHint: structuredEvidenceList(data.rollbackHint || data.rollback_hint),
|
|
2363
2480
|
mediaProof: structuredEvidenceList(data.mediaProof || data.media_proof),
|
|
2481
|
+
designCompletion: structuredEvidenceList(data.designCompletion || data.design_completion),
|
|
2364
2482
|
cleanup: String(data.cleanup || data.cleanupStatus || ''),
|
|
2365
2483
|
changed: arrayFlag(data.changed || data.files),
|
|
2366
2484
|
skipped: arrayFlag(data.skipped),
|
|
@@ -2391,6 +2509,7 @@ async function parseProofMarkdown(file, empty) {
|
|
|
2391
2509
|
missionEnvelope: readProofList(text, 'Mission patch envelope'),
|
|
2392
2510
|
rollbackHint: readProofList(text, 'Rollback hint'),
|
|
2393
2511
|
mediaProof: readProofList(text, 'Media proof'),
|
|
2512
|
+
designCompletion: readProofList(text, 'Design completion'),
|
|
2394
2513
|
cleanup: readProofField(text, 'Cleanup') || readProofField(text, 'Cleanup status'),
|
|
2395
2514
|
changed: firstProofList(text, ['Changed surfaces', 'Files']),
|
|
2396
2515
|
skipped: readProofList(text, 'Skipped'),
|
|
@@ -2476,6 +2595,9 @@ function formatStructuredEvidence(value) {
|
|
|
2476
2595
|
if (data.schema === 'yam.media-generation-proof.v1' || data.generation_requested || data.output_hash) {
|
|
2477
2596
|
return JSON.stringify(buildMediaGenerationProof(data));
|
|
2478
2597
|
}
|
|
2598
|
+
if (data.schema === 'yam.ueye-design-completion-gate.v1' || data.completion_claim || data.ready_to_claim_done !== undefined) {
|
|
2599
|
+
return JSON.stringify(buildUeyeDesignCompletionGate(data));
|
|
2600
|
+
}
|
|
2479
2601
|
return JSON.stringify(data);
|
|
2480
2602
|
} catch {
|
|
2481
2603
|
return text;
|
|
@@ -2484,7 +2606,7 @@ function formatStructuredEvidence(value) {
|
|
|
2484
2606
|
|
|
2485
2607
|
function hasProofEvidence(parsed) {
|
|
2486
2608
|
const flags = parsed.flags || {};
|
|
2487
|
-
return ['command', 'evidence', 'visual', 'runtime', 'runtime_backend_evidence', 'visual_provenance', 'mission_envelope', 'rollback_hint', 'media_proof', 'changed', 'skipped', 'blocked'].some((key) => arrayFlag(flags[key]).length > 0) || Boolean(flags.cleanup || flags.runtime_backend || flags.runtime_claim);
|
|
2609
|
+
return ['command', 'evidence', 'visual', 'runtime', 'runtime_backend_evidence', 'visual_provenance', 'mission_envelope', 'rollback_hint', 'media_proof', 'design_completion', 'changed', 'skipped', 'blocked'].some((key) => arrayFlag(flags[key]).length > 0) || Boolean(flags.cleanup || flags.runtime_backend || flags.runtime_claim);
|
|
2488
2610
|
}
|
|
2489
2611
|
|
|
2490
2612
|
function printProofList(label, values) {
|