@12ui/design 0.2.13 → 0.2.15
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/README.md +35 -9
- package/dist/bounded-concurrency.d.ts +13 -0
- package/dist/bounded-concurrency.d.ts.map +1 -0
- package/dist/bounded-concurrency.js +43 -0
- package/dist/bounded-concurrency.js.map +1 -0
- package/dist/branch-client.d.ts +155 -0
- package/dist/branch-client.d.ts.map +1 -0
- package/dist/branch-client.js +179 -0
- package/dist/branch-client.js.map +1 -0
- package/dist/branch-completion.d.ts +37 -0
- package/dist/branch-completion.d.ts.map +1 -0
- package/dist/branch-completion.js +137 -0
- package/dist/branch-completion.js.map +1 -0
- package/dist/branch-dispatch-loop.d.ts +84 -0
- package/dist/branch-dispatch-loop.d.ts.map +1 -0
- package/dist/branch-dispatch-loop.js +206 -0
- package/dist/branch-dispatch-loop.js.map +1 -0
- package/dist/branch-downloads.d.ts +53 -0
- package/dist/branch-downloads.d.ts.map +1 -0
- package/dist/branch-downloads.js +114 -0
- package/dist/branch-downloads.js.map +1 -0
- package/dist/branch-execution-types.d.ts +54 -0
- package/dist/branch-execution-types.d.ts.map +1 -0
- package/dist/branch-execution-types.js +2 -0
- package/dist/branch-execution-types.js.map +1 -0
- package/dist/branch-execution.d.ts +20 -0
- package/dist/branch-execution.d.ts.map +1 -0
- package/dist/branch-execution.js +380 -0
- package/dist/branch-execution.js.map +1 -0
- package/dist/branch-identity.d.ts +71 -0
- package/dist/branch-identity.d.ts.map +1 -0
- package/dist/branch-identity.js +72 -0
- package/dist/branch-identity.js.map +1 -0
- package/dist/branch-materialize.d.ts +33 -0
- package/dist/branch-materialize.d.ts.map +1 -0
- package/dist/branch-materialize.js +64 -0
- package/dist/branch-materialize.js.map +1 -0
- package/dist/branch-page-conversion.d.ts +127 -0
- package/dist/branch-page-conversion.d.ts.map +1 -0
- package/dist/branch-page-conversion.js +382 -0
- package/dist/branch-page-conversion.js.map +1 -0
- package/dist/branch-plan.d.ts +63 -0
- package/dist/branch-plan.d.ts.map +1 -0
- package/dist/branch-plan.js +95 -0
- package/dist/branch-plan.js.map +1 -0
- package/dist/branch-progress.d.ts +99 -0
- package/dist/branch-progress.d.ts.map +1 -0
- package/dist/branch-progress.js +188 -0
- package/dist/branch-progress.js.map +1 -0
- package/dist/branch-run-record.d.ts +164 -0
- package/dist/branch-run-record.d.ts.map +1 -0
- package/dist/branch-run-record.js +94 -0
- package/dist/branch-run-record.js.map +1 -0
- package/dist/branch-schedule.d.ts +74 -0
- package/dist/branch-schedule.d.ts.map +1 -0
- package/dist/branch-schedule.js +130 -0
- package/dist/branch-schedule.js.map +1 -0
- package/dist/branch-status.d.ts +11 -0
- package/dist/branch-status.d.ts.map +1 -0
- package/dist/branch-status.js +118 -0
- package/dist/branch-status.js.map +1 -0
- package/dist/branch-viewport-normalization.d.ts +74 -0
- package/dist/branch-viewport-normalization.d.ts.map +1 -0
- package/dist/branch-viewport-normalization.js +120 -0
- package/dist/branch-viewport-normalization.js.map +1 -0
- package/dist/cli-arguments.d.ts.map +1 -1
- package/dist/cli-arguments.js +5 -0
- package/dist/cli-arguments.js.map +1 -1
- package/dist/cli-branch-command.d.ts +55 -0
- package/dist/cli-branch-command.d.ts.map +1 -0
- package/dist/cli-branch-command.js +475 -0
- package/dist/cli-branch-command.js.map +1 -0
- package/dist/cli-capabilities.d.ts +51 -0
- package/dist/cli-capabilities.d.ts.map +1 -1
- package/dist/cli-capabilities.js +52 -1
- package/dist/cli-capabilities.js.map +1 -1
- package/dist/cli-create-command.d.ts +21 -0
- package/dist/cli-create-command.d.ts.map +1 -0
- package/dist/cli-create-command.js +319 -0
- package/dist/cli-create-command.js.map +1 -0
- package/dist/cli-detach.d.ts +62 -0
- package/dist/cli-detach.d.ts.map +1 -0
- package/dist/cli-detach.js +123 -0
- package/dist/cli-detach.js.map +1 -0
- package/dist/cli-draft-command.d.ts +63 -0
- package/dist/cli-draft-command.d.ts.map +1 -0
- package/dist/cli-draft-command.js +220 -0
- package/dist/cli-draft-command.js.map +1 -0
- package/dist/cli-export-command.d.ts.map +1 -1
- package/dist/cli-export-command.js +2 -3
- package/dist/cli-export-command.js.map +1 -1
- package/dist/cli-image-batch-command.d.ts +21 -0
- package/dist/cli-image-batch-command.d.ts.map +1 -1
- package/dist/cli-image-batch-command.js +65 -4
- package/dist/cli-image-batch-command.js.map +1 -1
- package/dist/cli-image-batch-resume.d.ts +7 -0
- package/dist/cli-image-batch-resume.d.ts.map +1 -1
- package/dist/cli-image-batch-resume.js +19 -2
- package/dist/cli-image-batch-resume.js.map +1 -1
- package/dist/cli-package-command.d.ts +29 -0
- package/dist/cli-package-command.d.ts.map +1 -0
- package/dist/cli-package-command.js +128 -0
- package/dist/cli-package-command.js.map +1 -0
- package/dist/cli-progress.d.ts +137 -0
- package/dist/cli-progress.d.ts.map +1 -1
- package/dist/cli-progress.js +156 -0
- package/dist/cli-progress.js.map +1 -1
- package/dist/cli-select-command.d.ts +12 -0
- package/dist/cli-select-command.d.ts.map +1 -0
- package/dist/cli-select-command.js +66 -0
- package/dist/cli-select-command.js.map +1 -0
- package/dist/cli.js +150 -7
- package/dist/cli.js.map +1 -1
- package/dist/conversion-receipt.d.ts +127 -0
- package/dist/conversion-receipt.d.ts.map +1 -0
- package/dist/conversion-receipt.js +184 -0
- package/dist/conversion-receipt.js.map +1 -0
- package/dist/create-identity.d.ts +25 -0
- package/dist/create-identity.d.ts.map +1 -0
- package/dist/create-identity.js +0 -0
- package/dist/create-identity.js.map +1 -0
- package/dist/draft-identity.d.ts +30 -0
- package/dist/draft-identity.d.ts.map +1 -0
- package/dist/draft-identity.js +0 -0
- package/dist/draft-identity.js.map +1 -0
- package/dist/draft-prompts.d.ts +35 -0
- package/dist/draft-prompts.d.ts.map +1 -0
- package/dist/draft-prompts.js +51 -0
- package/dist/draft-prompts.js.map +1 -0
- package/dist/draft-run.d.ts +32 -0
- package/dist/draft-run.d.ts.map +1 -0
- package/dist/draft-run.js +152 -0
- package/dist/draft-run.js.map +1 -0
- package/dist/draft-workspace.d.ts +90 -0
- package/dist/draft-workspace.d.ts.map +1 -0
- package/dist/draft-workspace.js +64 -0
- package/dist/draft-workspace.js.map +1 -0
- package/dist/image-batch-status.d.ts +42 -0
- package/dist/image-batch-status.d.ts.map +1 -0
- package/dist/image-batch-status.js +142 -0
- package/dist/image-batch-status.js.map +1 -0
- package/dist/image-dimensions.d.ts +12 -0
- package/dist/image-dimensions.d.ts.map +1 -0
- package/dist/image-dimensions.js +14 -0
- package/dist/image-dimensions.js.map +1 -0
- package/dist/image-generation-resume.d.ts +13 -0
- package/dist/image-generation-resume.d.ts.map +1 -1
- package/dist/image-generation-resume.js +13 -0
- package/dist/image-generation-resume.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy-skill-catalog.d.ts.map +1 -1
- package/dist/legacy-skill-catalog.js +140 -0
- package/dist/legacy-skill-catalog.js.map +1 -1
- package/dist/package-client.d.ts +28 -0
- package/dist/package-client.d.ts.map +1 -1
- package/dist/package-client.js +21 -1
- package/dist/package-client.js.map +1 -1
- package/dist/package-manifest-file.d.ts +21 -0
- package/dist/package-manifest-file.d.ts.map +1 -0
- package/dist/package-manifest-file.js +119 -0
- package/dist/package-manifest-file.js.map +1 -0
- package/dist/package-manifest-template.d.ts +23 -0
- package/dist/package-manifest-template.d.ts.map +1 -0
- package/dist/package-manifest-template.js +60 -0
- package/dist/package-manifest-template.js.map +1 -0
- package/dist/package-source-refusal.d.ts +17 -0
- package/dist/package-source-refusal.d.ts.map +1 -0
- package/dist/package-source-refusal.js +61 -0
- package/dist/package-source-refusal.js.map +1 -0
- package/dist/package-submission.d.ts +134 -0
- package/dist/package-submission.d.ts.map +1 -0
- package/dist/package-submission.js +196 -0
- package/dist/package-submission.js.map +1 -0
- package/dist/selection-record.d.ts +95 -0
- package/dist/selection-record.d.ts.map +1 -0
- package/dist/selection-record.js +121 -0
- package/dist/selection-record.js.map +1 -0
- package/package.json +1 -1
- package/skills/design/SKILL.md +43 -266
- package/skills/design-branch/SKILL.md +37 -116
- package/skills/design-convert/SKILL.md +62 -148
- package/skills/design-draft/SKILL.md +71 -135
- package/skills/design-search/SKILL.md +29 -78
- package/skills/design/references/continuation-contract.md +0 -60
- package/skills/design/references/selection-contract.md +0 -112
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { BranchRunEnvelope, BranchScreenStatus } from './branch-client.js';
|
|
2
|
+
import type { BranchScope } from './branch-identity.js';
|
|
3
|
+
/**
|
|
4
|
+
* Plan normalisation. The wire envelope keeps ordering and per-screen facts in
|
|
5
|
+
* two different places — `plan.pages[].slots` and `candidates[]` — so this is
|
|
6
|
+
* the one module that joins them back into the page/viewport structure the
|
|
7
|
+
* scheduler, the downloads, and the package manifests all read.
|
|
8
|
+
*
|
|
9
|
+
* The approved winner is NOT a slot. The server plans continuations of the
|
|
10
|
+
* source page starting at `viewportOrdinal` 2; ordinal 1 of that page is the
|
|
11
|
+
* image the run branched from. Additional pages start at ordinal 1 because
|
|
12
|
+
* every one of their viewports is generated.
|
|
13
|
+
*/
|
|
14
|
+
export type BranchPlannedScreen = {
|
|
15
|
+
slot: string;
|
|
16
|
+
pageIndex: number;
|
|
17
|
+
viewportOrdinal: number;
|
|
18
|
+
status: BranchScreenStatus;
|
|
19
|
+
direction: string;
|
|
20
|
+
header: boolean | null;
|
|
21
|
+
footer: boolean | null;
|
|
22
|
+
pageEndsHere: boolean;
|
|
23
|
+
dependsOnSlot: string | null;
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
content?: string;
|
|
27
|
+
error?: {
|
|
28
|
+
code: string;
|
|
29
|
+
message: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export type BranchPlannedPage = {
|
|
33
|
+
index: number;
|
|
34
|
+
id: string;
|
|
35
|
+
kind: 'source' | 'additional';
|
|
36
|
+
title: string;
|
|
37
|
+
pageType: string;
|
|
38
|
+
surfaceType: string;
|
|
39
|
+
purpose: string;
|
|
40
|
+
/** True when viewport 1 of this page is the approved winner, not a slot. */
|
|
41
|
+
startsFromWinner: boolean;
|
|
42
|
+
slots: string[];
|
|
43
|
+
};
|
|
44
|
+
export type BranchNormalizedPlan = {
|
|
45
|
+
runId: string;
|
|
46
|
+
concept: string;
|
|
47
|
+
aspect: string;
|
|
48
|
+
scope: BranchScope;
|
|
49
|
+
sitePurpose: string;
|
|
50
|
+
statusUpdate: string;
|
|
51
|
+
approvedScreenSummary: string;
|
|
52
|
+
pages: BranchPlannedPage[];
|
|
53
|
+
screens: BranchPlannedScreen[];
|
|
54
|
+
};
|
|
55
|
+
/** Stable, filesystem-safe, and self-describing: `p0-pricing`, `p2`. */
|
|
56
|
+
export declare const branchPageId: (index: number, title: string) => string;
|
|
57
|
+
export declare const normalizeBranchPlan: (envelope: BranchRunEnvelope, options: {
|
|
58
|
+
scope: BranchScope;
|
|
59
|
+
maxScreens?: number;
|
|
60
|
+
}) => BranchNormalizedPlan;
|
|
61
|
+
/** Refresh statuses from a later envelope without re-deriving the structure. */
|
|
62
|
+
export declare const applyBranchEnvelope: (plan: BranchNormalizedPlan, envelope: BranchRunEnvelope) => BranchNormalizedPlan;
|
|
63
|
+
//# sourceMappingURL=branch-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-plan.d.ts","sourceRoot":"","sources":["../src/branch-plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAEjB,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,GAAG,YAAY,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,gBAAgB,EAAE,OAAO,CAAC;IAC1B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAChC,CAAC;AASF,wEAAwE;AACxE,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,EAAE,OAAO,MAAM,KAAG,MAQ3D,CAAC;AAqBF,eAAO,MAAM,mBAAmB,GAC9B,UAAU,iBAAiB,EAC3B,SAAS;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,KACnD,oBA0DF,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,mBAAmB,GAC9B,MAAM,oBAAoB,EAC1B,UAAU,iBAAiB,KAC1B,oBAWF,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
const PAGE_TITLE_LIMIT = 200;
|
|
2
|
+
const PAGE_PURPOSE_LIMIT = 1_000;
|
|
3
|
+
const clamp = (value, limit) => (value.length <= limit ? value : `${value.slice(0, limit - 1)}…`);
|
|
4
|
+
/** Stable, filesystem-safe, and self-describing: `p0-pricing`, `p2`. */
|
|
5
|
+
export const branchPageId = (index, title) => {
|
|
6
|
+
const slug = title
|
|
7
|
+
.toLowerCase()
|
|
8
|
+
.replace(/[^a-z0-9]+/gu, '-')
|
|
9
|
+
.replace(/^-+|-+$/gu, '')
|
|
10
|
+
.slice(0, 40)
|
|
11
|
+
.replace(/-+$/u, '');
|
|
12
|
+
return slug ? `p${index}-${slug}` : `p${index}`;
|
|
13
|
+
};
|
|
14
|
+
const screenFor = (candidate) => {
|
|
15
|
+
if (candidate.pageIndex === undefined || candidate.viewportOrdinal === undefined)
|
|
16
|
+
return null;
|
|
17
|
+
return {
|
|
18
|
+
slot: candidate.slot,
|
|
19
|
+
pageIndex: candidate.pageIndex,
|
|
20
|
+
viewportOrdinal: candidate.viewportOrdinal,
|
|
21
|
+
status: candidate.status,
|
|
22
|
+
direction: candidate.direction,
|
|
23
|
+
header: candidate.header ?? null,
|
|
24
|
+
footer: candidate.footer ?? null,
|
|
25
|
+
pageEndsHere: candidate.pageEndsHere ?? false,
|
|
26
|
+
dependsOnSlot: candidate.dependsOnSlot ?? null,
|
|
27
|
+
width: candidate.width,
|
|
28
|
+
height: candidate.height,
|
|
29
|
+
...(candidate.content ? { content: candidate.content } : {}),
|
|
30
|
+
...(candidate.error ? { error: candidate.error } : {}),
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
export const normalizeBranchPlan = (envelope, options) => {
|
|
34
|
+
const plan = envelope.plan;
|
|
35
|
+
if (!plan || !Array.isArray(plan.pages)) {
|
|
36
|
+
throw new Error(`Run ${envelope.id} carries no build plan. Only a run started with source "build" can be`
|
|
37
|
+
+ ' branched.');
|
|
38
|
+
}
|
|
39
|
+
const bySlot = new Map(envelope.candidates.map((candidate) => [candidate.slot, candidate]));
|
|
40
|
+
// Plan order is page order then viewport order, which is also slot order.
|
|
41
|
+
// Everything downstream — the footer seed, the dependency chains, the
|
|
42
|
+
// `--max-screens` trim — depends on keeping exactly that sequence.
|
|
43
|
+
const orderedSlots = plan.pages.flatMap((page) => ((page.slots ?? []).filter((slot) => bySlot.has(slot))));
|
|
44
|
+
const scopedPages = options.scope === 'page'
|
|
45
|
+
? plan.pages.filter((page) => page.kind === 'source')
|
|
46
|
+
: plan.pages;
|
|
47
|
+
const scopedSlots = new Set(scopedPages.flatMap((page) => page.slots ?? []));
|
|
48
|
+
const trimmed = options.maxScreens === undefined
|
|
49
|
+
? null
|
|
50
|
+
: new Set(orderedSlots.filter((slot) => scopedSlots.has(slot)).slice(0, options.maxScreens));
|
|
51
|
+
const keeps = (slot) => (scopedSlots.has(slot) && (trimmed === null || trimmed.has(slot)));
|
|
52
|
+
const pages = scopedPages.map((page) => ({
|
|
53
|
+
index: page.index,
|
|
54
|
+
id: branchPageId(page.index, page.title ?? ''),
|
|
55
|
+
kind: page.kind,
|
|
56
|
+
title: clamp(page.title ?? `Page ${page.index}`, PAGE_TITLE_LIMIT),
|
|
57
|
+
pageType: page.pageType ?? 'other',
|
|
58
|
+
surfaceType: page.surfaceType ?? 'web_page',
|
|
59
|
+
purpose: clamp(page.purpose ?? '', PAGE_PURPOSE_LIMIT),
|
|
60
|
+
startsFromWinner: page.kind === 'source',
|
|
61
|
+
slots: (page.slots ?? []).filter(keeps),
|
|
62
|
+
}));
|
|
63
|
+
const screens = orderedSlots
|
|
64
|
+
.filter(keeps)
|
|
65
|
+
.flatMap((slot) => {
|
|
66
|
+
const screen = screenFor(bySlot.get(slot));
|
|
67
|
+
return screen ? [screen] : [];
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
runId: envelope.id,
|
|
71
|
+
concept: envelope.concept,
|
|
72
|
+
aspect: envelope.aspect,
|
|
73
|
+
scope: options.scope,
|
|
74
|
+
sitePurpose: plan.sitePurpose ?? '',
|
|
75
|
+
statusUpdate: plan.statusUpdate ?? '',
|
|
76
|
+
approvedScreenSummary: plan.approvedScreenSummary ?? '',
|
|
77
|
+
pages,
|
|
78
|
+
screens,
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
/** Refresh statuses from a later envelope without re-deriving the structure. */
|
|
82
|
+
export const applyBranchEnvelope = (plan, envelope) => {
|
|
83
|
+
const bySlot = new Map(envelope.candidates.map((candidate) => [candidate.slot, candidate]));
|
|
84
|
+
return {
|
|
85
|
+
...plan,
|
|
86
|
+
screens: plan.screens.map((screen) => {
|
|
87
|
+
const candidate = bySlot.get(screen.slot);
|
|
88
|
+
if (!candidate)
|
|
89
|
+
return screen;
|
|
90
|
+
const next = screenFor(candidate);
|
|
91
|
+
return next ? { ...screen, ...next } : screen;
|
|
92
|
+
}),
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=branch-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-plan.js","sourceRoot":"","sources":["../src/branch-plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { BranchNormalizedPlan } from './branch-plan.js';
|
|
2
|
+
import type { BranchCompletion } from './branch-run-record.js';
|
|
3
|
+
/**
|
|
4
|
+
* The motion surface. A long command that answers a poll with bare absence is
|
|
5
|
+
* the measured trigger for a caller deciding the process stalled and improvising
|
|
6
|
+
* around it, so every observation of a branch run — the command's own streamed
|
|
7
|
+
* lines and `12ui branch status` from another session — reports what changed,
|
|
8
|
+
* how long each screen has been running against its typical duration, and what
|
|
9
|
+
* to do next.
|
|
10
|
+
*/
|
|
11
|
+
export declare const BRANCH_PROGRESS_FILENAME = "branch.progress.json";
|
|
12
|
+
export type BranchProgressPhase = 'claiming' | 'dispatching' | 'downloading' | 'converting' | 'terminal';
|
|
13
|
+
export type BranchProgressScreen = {
|
|
14
|
+
slot: string;
|
|
15
|
+
status: 'pending' | 'dispatched' | 'succeeded' | 'failed' | 'blocked';
|
|
16
|
+
pageIndex: number;
|
|
17
|
+
viewportOrdinal: number;
|
|
18
|
+
dispatchedAt?: string;
|
|
19
|
+
waitingOn?: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* One page's package conversion, as last published by the server.
|
|
23
|
+
*
|
|
24
|
+
* `12ui branch status` is the command a second session is told to poll, and
|
|
25
|
+
* until now it carried per-screen state only — so the entire second half of a
|
|
26
|
+
* run, the half that takes the longest, answered every poll with the same
|
|
27
|
+
* sentence. These are the per-page facts that make it report motion.
|
|
28
|
+
*/
|
|
29
|
+
export type BranchProgressPackage = {
|
|
30
|
+
pageId: string;
|
|
31
|
+
stage: string;
|
|
32
|
+
percent?: number;
|
|
33
|
+
completed?: number;
|
|
34
|
+
total?: number;
|
|
35
|
+
running?: number;
|
|
36
|
+
stageSince?: string;
|
|
37
|
+
pagesAvailable?: number;
|
|
38
|
+
updatedAt: string;
|
|
39
|
+
};
|
|
40
|
+
export type BranchProgressRecord = {
|
|
41
|
+
version: 1;
|
|
42
|
+
runId: string;
|
|
43
|
+
phase: BranchProgressPhase;
|
|
44
|
+
startedAt: string;
|
|
45
|
+
updatedAt: string;
|
|
46
|
+
screens: BranchProgressScreen[];
|
|
47
|
+
/** Absent until the first page starts converting. */
|
|
48
|
+
packages?: BranchProgressPackage[];
|
|
49
|
+
};
|
|
50
|
+
export declare const branchProgressPath: (outDir: string) => string;
|
|
51
|
+
export declare const writeBranchProgress: (file: string, record: BranchProgressRecord) => Promise<void>;
|
|
52
|
+
export declare const readBranchProgress: (file: string) => Promise<BranchProgressRecord | undefined>;
|
|
53
|
+
export declare const branchProgressScreens: (plan: BranchNormalizedPlan, dispatchedAt: Readonly<Record<string, string>>) => BranchProgressScreen[];
|
|
54
|
+
export type BranchStatusCounts = {
|
|
55
|
+
total: number;
|
|
56
|
+
complete: number;
|
|
57
|
+
generating: number;
|
|
58
|
+
waiting: number;
|
|
59
|
+
blocked: number;
|
|
60
|
+
failed: number;
|
|
61
|
+
};
|
|
62
|
+
export type BranchStatusReport = {
|
|
63
|
+
outDir: string;
|
|
64
|
+
runId?: string;
|
|
65
|
+
phase: BranchProgressPhase;
|
|
66
|
+
complete: boolean;
|
|
67
|
+
counts: BranchStatusCounts;
|
|
68
|
+
screens: BranchProgressScreen[];
|
|
69
|
+
/** Always populated: what is moving, and how long it has been moving. */
|
|
70
|
+
narrative: string;
|
|
71
|
+
/** Per-page package progress, once any page has started converting. */
|
|
72
|
+
packages?: BranchProgressPackage[];
|
|
73
|
+
/** Present only while work remains. A finished run has no next action. */
|
|
74
|
+
nextAction?: string;
|
|
75
|
+
startedAt?: string;
|
|
76
|
+
updatedAt?: string;
|
|
77
|
+
elapsedSeconds?: number;
|
|
78
|
+
completionPath?: string;
|
|
79
|
+
planPath?: string;
|
|
80
|
+
pages?: BranchCompletion['pages'];
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* One line of motion plus, while anything remains, one line of instruction.
|
|
84
|
+
* A terminal report carries neither: there is nothing in flight to narrate and
|
|
85
|
+
* nothing left to check.
|
|
86
|
+
*/
|
|
87
|
+
export declare const summarizeBranchProgress: (args: {
|
|
88
|
+
outDir: string;
|
|
89
|
+
runId?: string;
|
|
90
|
+
phase: BranchProgressPhase;
|
|
91
|
+
screens: readonly BranchProgressScreen[];
|
|
92
|
+
packages?: readonly BranchProgressPackage[];
|
|
93
|
+
startedAt?: string;
|
|
94
|
+
updatedAt?: string;
|
|
95
|
+
completion?: BranchCompletion;
|
|
96
|
+
statusCommand?: string;
|
|
97
|
+
now?: number;
|
|
98
|
+
}) => BranchStatusReport;
|
|
99
|
+
//# sourceMappingURL=branch-progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-progress.d.ts","sourceRoot":"","sources":["../src/branch-progress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { BRANCH_PAGE_CONCURRENCY_DEFAULT, OPERATION_DURATION_HINTS, elapsedAgainstTypical, formatDuration, narrateCounts, nextActionLine, packageProgressLine, secondsSince, } from './cli-progress.js';
|
|
5
|
+
import { branchBlockedSlots } from './branch-schedule.js';
|
|
6
|
+
/**
|
|
7
|
+
* The motion surface. A long command that answers a poll with bare absence is
|
|
8
|
+
* the measured trigger for a caller deciding the process stalled and improvising
|
|
9
|
+
* around it, so every observation of a branch run — the command's own streamed
|
|
10
|
+
* lines and `12ui branch status` from another session — reports what changed,
|
|
11
|
+
* how long each screen has been running against its typical duration, and what
|
|
12
|
+
* to do next.
|
|
13
|
+
*/
|
|
14
|
+
export const BRANCH_PROGRESS_FILENAME = 'branch.progress.json';
|
|
15
|
+
export const branchProgressPath = (outDir) => (path.join(outDir, BRANCH_PROGRESS_FILENAME));
|
|
16
|
+
export const writeBranchProgress = async (file, record) => {
|
|
17
|
+
await mkdir(path.dirname(file), { recursive: true });
|
|
18
|
+
const temporary = `${file}.${randomUUID()}.tmp`;
|
|
19
|
+
try {
|
|
20
|
+
await writeFile(temporary, `${JSON.stringify(record, null, 2)}\n`, {
|
|
21
|
+
encoding: 'utf8',
|
|
22
|
+
flag: 'wx',
|
|
23
|
+
mode: 0o600,
|
|
24
|
+
});
|
|
25
|
+
await rename(temporary, file);
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
await rm(temporary, { force: true });
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
export const readBranchProgress = async (file) => {
|
|
32
|
+
try {
|
|
33
|
+
return JSON.parse(await readFile(file, 'utf8'));
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
export const branchProgressScreens = (plan, dispatchedAt) => {
|
|
40
|
+
const blocked = new Map(branchBlockedSlots(plan.screens.map((screen) => ({
|
|
41
|
+
slot: screen.slot,
|
|
42
|
+
status: screen.status,
|
|
43
|
+
footer: screen.footer,
|
|
44
|
+
dependsOnSlot: screen.dependsOnSlot,
|
|
45
|
+
}))).map((entry) => [entry.slot, entry]));
|
|
46
|
+
return plan.screens.map((screen) => {
|
|
47
|
+
const block = blocked.get(screen.slot);
|
|
48
|
+
return {
|
|
49
|
+
slot: screen.slot,
|
|
50
|
+
status: block ? 'blocked' : screen.status,
|
|
51
|
+
pageIndex: screen.pageIndex,
|
|
52
|
+
viewportOrdinal: screen.viewportOrdinal,
|
|
53
|
+
...(dispatchedAt[screen.slot] ? { dispatchedAt: dispatchedAt[screen.slot] } : {}),
|
|
54
|
+
...(block
|
|
55
|
+
? { waitingOn: block.waitingOn }
|
|
56
|
+
: screen.status === 'pending' && screen.dependsOnSlot
|
|
57
|
+
? { waitingOn: screen.dependsOnSlot }
|
|
58
|
+
: {}),
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
const countScreens = (screens) => ({
|
|
63
|
+
total: screens.length,
|
|
64
|
+
complete: screens.filter((screen) => screen.status === 'succeeded').length,
|
|
65
|
+
generating: screens.filter((screen) => screen.status === 'dispatched').length,
|
|
66
|
+
waiting: screens.filter((screen) => screen.status === 'pending').length,
|
|
67
|
+
blocked: screens.filter((screen) => screen.status === 'blocked').length,
|
|
68
|
+
failed: screens.filter((screen) => screen.status === 'failed').length,
|
|
69
|
+
});
|
|
70
|
+
const generatingDetail = (screens, now) => {
|
|
71
|
+
const running = screens
|
|
72
|
+
.filter((screen) => screen.status === 'dispatched')
|
|
73
|
+
.map((screen) => secondsSince(screen.dispatchedAt, now))
|
|
74
|
+
.filter((seconds) => seconds !== undefined);
|
|
75
|
+
if (running.length === 0)
|
|
76
|
+
return undefined;
|
|
77
|
+
return elapsedAgainstTypical(Math.max(...running), OPERATION_DURATION_HINTS.branchScreen);
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* `p0-home converting viewports 32% — 1 of 3 viewports, 2 running, 1m 20s in
|
|
81
|
+
* stage`. One line per page still converting, so a poll during the longest half
|
|
82
|
+
* of the run reports advancing facts rather than one unchanging sentence.
|
|
83
|
+
*/
|
|
84
|
+
const packageDetail = (packages, now) => {
|
|
85
|
+
if (packages.length === 0)
|
|
86
|
+
return undefined;
|
|
87
|
+
// A settled page has nothing left to narrate, so it becomes a tally and the
|
|
88
|
+
// detail stays on the pages that are still moving.
|
|
89
|
+
const converted = packages.filter((entry) => entry.stage === 'succeeded').length;
|
|
90
|
+
const failed = packages.filter((entry) => entry.stage === 'failed').length;
|
|
91
|
+
const moving = packages.filter((entry) => entry.stage !== 'succeeded' && entry.stage !== 'failed');
|
|
92
|
+
return [
|
|
93
|
+
...(converted > 0 ? [`${converted} converted`] : []),
|
|
94
|
+
...(failed > 0 ? [`${failed} failed`] : []),
|
|
95
|
+
...moving.map((entry) => `${entry.pageId} ${packageProgressLine(entry, now)}`),
|
|
96
|
+
].join('; ');
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* One line of motion plus, while anything remains, one line of instruction.
|
|
100
|
+
* A terminal report carries neither: there is nothing in flight to narrate and
|
|
101
|
+
* nothing left to check.
|
|
102
|
+
*/
|
|
103
|
+
export const summarizeBranchProgress = (args) => {
|
|
104
|
+
const now = args.now ?? Date.now();
|
|
105
|
+
const packages = args.packages ?? [];
|
|
106
|
+
const counts = countScreens(args.screens);
|
|
107
|
+
const complete = args.phase === 'terminal' || Boolean(args.completion);
|
|
108
|
+
const elapsedSeconds = secondsSince(args.startedAt, now);
|
|
109
|
+
const statusCommand = args.statusCommand ?? `12ui branch status --out-dir ${args.outDir}`;
|
|
110
|
+
if (complete) {
|
|
111
|
+
const settled = args.completion;
|
|
112
|
+
const narrative = settled
|
|
113
|
+
? `Branch run ${settled.runId} finished ${settled.status}:`
|
|
114
|
+
+ ` ${settled.succeededCount} of ${settled.screenCount} screen(s) generated,`
|
|
115
|
+
+ ` ${settled.failedCount} failed, ${settled.blockedCount} blocked.`
|
|
116
|
+
+ ` Screens and pages are on disk under ${settled.outDir}.`
|
|
117
|
+
: `Branch run ${args.runId ?? '(unclaimed)'} is finished; read the completion sentinel.`;
|
|
118
|
+
return {
|
|
119
|
+
outDir: args.outDir,
|
|
120
|
+
...(args.runId ? { runId: args.runId } : {}),
|
|
121
|
+
phase: 'terminal',
|
|
122
|
+
complete: true,
|
|
123
|
+
counts,
|
|
124
|
+
screens: [...args.screens],
|
|
125
|
+
narrative,
|
|
126
|
+
...(args.startedAt ? { startedAt: args.startedAt } : {}),
|
|
127
|
+
...(args.updatedAt ? { updatedAt: args.updatedAt } : {}),
|
|
128
|
+
...(elapsedSeconds === undefined ? {} : { elapsedSeconds: Math.round(elapsedSeconds) }),
|
|
129
|
+
...(settled ? { pages: settled.pages } : {}),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const converting = args.phase === 'converting'
|
|
133
|
+
? `Converting each whole page as one package, up to ${BRANCH_PAGE_CONCURRENCY_DEFAULT} at a`
|
|
134
|
+
+ ` time (${formatDuration(OPERATION_DURATION_HINTS.branchPackage)} typical per page).`
|
|
135
|
+
: null;
|
|
136
|
+
const phaseNarrative = args.phase === 'claiming'
|
|
137
|
+
? `Planning the screens (${elapsedAgainstTypical(elapsedSeconds ?? 0, OPERATION_DURATION_HINTS.branchClaim)}); no image bought yet.`
|
|
138
|
+
: args.phase === 'downloading'
|
|
139
|
+
? `Screens settled; downloading ${counts.complete} image(s).`
|
|
140
|
+
: converting
|
|
141
|
+
? converting
|
|
142
|
+
: `screens: ${narrateCounts([
|
|
143
|
+
{ label: 'complete', count: counts.complete },
|
|
144
|
+
{
|
|
145
|
+
label: 'generating',
|
|
146
|
+
count: counts.generating,
|
|
147
|
+
...(generatingDetail(args.screens, now) ? { detail: generatingDetail(args.screens, now) } : {}),
|
|
148
|
+
},
|
|
149
|
+
{ label: 'waiting on dependencies', count: counts.waiting },
|
|
150
|
+
{ label: 'blocked', count: counts.blocked },
|
|
151
|
+
{ label: 'failed', count: counts.failed },
|
|
152
|
+
])}`;
|
|
153
|
+
const typicalSeconds = args.phase === 'claiming'
|
|
154
|
+
? OPERATION_DURATION_HINTS.branchClaim
|
|
155
|
+
: args.phase === 'converting'
|
|
156
|
+
? OPERATION_DURATION_HINTS.branchPackage
|
|
157
|
+
: OPERATION_DURATION_HINTS.branchScreen;
|
|
158
|
+
// Pages convert as their own screens land, so package motion belongs on a
|
|
159
|
+
// dispatching report too — that is exactly when the two overlap.
|
|
160
|
+
const detail = packageDetail(packages, now);
|
|
161
|
+
const narrated = detail ? `${phaseNarrative} pages: ${detail}` : phaseNarrative;
|
|
162
|
+
return {
|
|
163
|
+
outDir: args.outDir,
|
|
164
|
+
...(args.runId ? { runId: args.runId } : {}),
|
|
165
|
+
phase: args.phase,
|
|
166
|
+
complete: false,
|
|
167
|
+
counts,
|
|
168
|
+
screens: [...args.screens],
|
|
169
|
+
...(packages.length > 0 ? { packages: [...packages] } : {}),
|
|
170
|
+
narrative: elapsedSeconds === undefined
|
|
171
|
+
? narrated
|
|
172
|
+
: `${narrated} — ${formatDuration(elapsedSeconds)} into the run`,
|
|
173
|
+
nextAction: nextActionLine({
|
|
174
|
+
what: args.phase === 'converting'
|
|
175
|
+
? 'A page conversion'
|
|
176
|
+
: args.phase === 'claiming'
|
|
177
|
+
? 'The plan call'
|
|
178
|
+
: 'Each screen',
|
|
179
|
+
typicalSeconds,
|
|
180
|
+
statusCommand,
|
|
181
|
+
waitHint: 'or leave `12ui branch execute` running, which blocks until the whole run finishes',
|
|
182
|
+
}),
|
|
183
|
+
...(args.startedAt ? { startedAt: args.startedAt } : {}),
|
|
184
|
+
...(args.updatedAt ? { updatedAt: args.updatedAt } : {}),
|
|
185
|
+
...(elapsedSeconds === undefined ? {} : { elapsedSeconds: Math.round(elapsedSeconds) }),
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
//# sourceMappingURL=branch-progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-progress.js","sourceRoot":"","sources":["../src/branch-progress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import type { BranchScope } from './branch-identity.js';
|
|
2
|
+
import type { BranchNormalizedPlan } from './branch-plan.js';
|
|
3
|
+
/**
|
|
4
|
+
* The two durable records of a branch run.
|
|
5
|
+
*
|
|
6
|
+
* `branch.attempt.json` is written BEFORE any spend, exclusively, so a plain
|
|
7
|
+
* re-run in the same directory refuses instead of buying a second run; only
|
|
8
|
+
* `--resume` may proceed. `branch.complete.json` is the sentinel: written once,
|
|
9
|
+
* atomically, only at a terminal state. Its ABSENCE means the run is still
|
|
10
|
+
* going — never that it failed. It is deliberately not named
|
|
11
|
+
* `generation.complete.json`, which is `image generate-batch`'s record and a
|
|
12
|
+
* different thing entirely.
|
|
13
|
+
*/
|
|
14
|
+
export declare const BRANCH_ATTEMPT_FILENAME = "branch.attempt.json";
|
|
15
|
+
export declare const BRANCH_COMPLETION_FILENAME = "branch.complete.json";
|
|
16
|
+
export declare const BRANCH_PLAN_FILENAME = "branch.plan.json";
|
|
17
|
+
export declare const BRANCH_SCREENS_DIRECTORY = "screens";
|
|
18
|
+
export declare const BRANCH_PAGES_DIRECTORY = "pages";
|
|
19
|
+
export type BranchAttemptStatus = 'claiming' | 'dispatching' | 'downloading' | 'converting' | 'succeeded' | 'partial' | 'failed';
|
|
20
|
+
export type BranchAttempt = {
|
|
21
|
+
version: 1;
|
|
22
|
+
status: BranchAttemptStatus;
|
|
23
|
+
runKey: string;
|
|
24
|
+
runId?: string;
|
|
25
|
+
origin: string;
|
|
26
|
+
scope: BranchScope;
|
|
27
|
+
concept: string;
|
|
28
|
+
conceptSha256: string;
|
|
29
|
+
winner: {
|
|
30
|
+
kind: 'run';
|
|
31
|
+
runId: string;
|
|
32
|
+
slot: string;
|
|
33
|
+
} | {
|
|
34
|
+
kind: 'image';
|
|
35
|
+
imagePath: string;
|
|
36
|
+
sha256: string;
|
|
37
|
+
mediaType: 'image/png' | 'image/jpeg' | 'image/webp';
|
|
38
|
+
};
|
|
39
|
+
aspect?: string;
|
|
40
|
+
maxScreens?: number;
|
|
41
|
+
convert?: {
|
|
42
|
+
output: 'html';
|
|
43
|
+
model: string;
|
|
44
|
+
responsiveQuality?: string;
|
|
45
|
+
};
|
|
46
|
+
sourceConversionId?: string;
|
|
47
|
+
createdAt: string;
|
|
48
|
+
resumedAt?: string[];
|
|
49
|
+
completionPath?: string;
|
|
50
|
+
completedAt?: string;
|
|
51
|
+
errors?: string[];
|
|
52
|
+
};
|
|
53
|
+
export declare const branchAttemptPath: (outDir: string) => string;
|
|
54
|
+
export declare const branchCompletionPath: (outDir: string) => string;
|
|
55
|
+
export declare const branchPlanPath: (outDir: string) => string;
|
|
56
|
+
export declare const writeBranchAttempt: (file: string, attempt: BranchAttempt, exclusive?: boolean) => Promise<void>;
|
|
57
|
+
export declare const readBranchAttempt: (file: string) => Promise<BranchAttempt | undefined>;
|
|
58
|
+
export declare const writeBranchPlanRecord: (file: string, plan: BranchNormalizedPlan) => Promise<void>;
|
|
59
|
+
export type BranchCompletionScreen = {
|
|
60
|
+
slot: string;
|
|
61
|
+
pageIndex: number;
|
|
62
|
+
pageId: string;
|
|
63
|
+
viewportOrdinal: number;
|
|
64
|
+
/** `blocked` is a screen a FAILED dependency put permanently out of reach. */
|
|
65
|
+
status: 'succeeded' | 'failed' | 'blocked';
|
|
66
|
+
direction: string;
|
|
67
|
+
path?: string;
|
|
68
|
+
sha256?: string;
|
|
69
|
+
bytes?: number;
|
|
70
|
+
width?: number;
|
|
71
|
+
height?: number;
|
|
72
|
+
dependsOnSlot?: string;
|
|
73
|
+
footer?: boolean;
|
|
74
|
+
blockedBy?: string;
|
|
75
|
+
blockedReason?: 'dependency' | 'footer-seed';
|
|
76
|
+
error?: {
|
|
77
|
+
code: string;
|
|
78
|
+
message: string;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
export type BranchCompletionPage = {
|
|
82
|
+
index: number;
|
|
83
|
+
id: string;
|
|
84
|
+
kind: 'source' | 'additional';
|
|
85
|
+
title: string;
|
|
86
|
+
slots: string[];
|
|
87
|
+
/** Viewport 1 of a source page is the approved winner, not a generated slot. */
|
|
88
|
+
startsFromWinner: boolean;
|
|
89
|
+
conversion?: {
|
|
90
|
+
status: 'succeeded' | 'failed' | 'skipped';
|
|
91
|
+
reason?: string;
|
|
92
|
+
packageId?: string;
|
|
93
|
+
idempotencyKey?: string;
|
|
94
|
+
conversionId?: string;
|
|
95
|
+
output?: string;
|
|
96
|
+
outFile?: string;
|
|
97
|
+
sha256?: string;
|
|
98
|
+
bytes?: number;
|
|
99
|
+
error?: string;
|
|
100
|
+
/** The width every viewport of this page was reconciled to. */
|
|
101
|
+
canonicalWidth?: number;
|
|
102
|
+
/**
|
|
103
|
+
* Reuse claims the server refused at admission, which this page then bought
|
|
104
|
+
* fresh under the same key. A page that silently paid for a screen it
|
|
105
|
+
* expected to attach is exactly what an operator needs to see, and the
|
|
106
|
+
* refusal detail is the server's own reason.
|
|
107
|
+
*/
|
|
108
|
+
disprovenReuse?: {
|
|
109
|
+
viewportId: string;
|
|
110
|
+
conversionId: string;
|
|
111
|
+
detail: string;
|
|
112
|
+
}[];
|
|
113
|
+
/**
|
|
114
|
+
* Viewports resized to reach it, with both digests. The winner comes from a
|
|
115
|
+
* different canvas than the server's screens, and a page only stitches when
|
|
116
|
+
* they share a width, so the resize is recorded rather than silent.
|
|
117
|
+
*/
|
|
118
|
+
normalizedViewports?: {
|
|
119
|
+
id: string;
|
|
120
|
+
fromWidth: number;
|
|
121
|
+
fromHeight: number;
|
|
122
|
+
fromSha256: string;
|
|
123
|
+
toWidth: number;
|
|
124
|
+
toHeight: number;
|
|
125
|
+
toSha256: string;
|
|
126
|
+
}[];
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
export type BranchCompletion = {
|
|
130
|
+
version: 1;
|
|
131
|
+
/** `partial` means some screens or pages are missing and were reported. */
|
|
132
|
+
status: 'succeeded' | 'partial' | 'failed';
|
|
133
|
+
runId: string;
|
|
134
|
+
runKey: string;
|
|
135
|
+
workflowRevision: string;
|
|
136
|
+
scope: BranchScope;
|
|
137
|
+
concept: string;
|
|
138
|
+
conceptSha256: string;
|
|
139
|
+
origin: string;
|
|
140
|
+
outDir: string;
|
|
141
|
+
attemptPath: string;
|
|
142
|
+
planPath: string;
|
|
143
|
+
startedAt: string;
|
|
144
|
+
completedAt: string;
|
|
145
|
+
screenCount: number;
|
|
146
|
+
succeededCount: number;
|
|
147
|
+
failedCount: number;
|
|
148
|
+
blockedCount: number;
|
|
149
|
+
/** The approved design the run branched from: viewport 1 of the source page. */
|
|
150
|
+
winner?: {
|
|
151
|
+
path: string;
|
|
152
|
+
sha256: string;
|
|
153
|
+
bytes: number;
|
|
154
|
+
width: number;
|
|
155
|
+
height: number;
|
|
156
|
+
sourceConversionId?: string;
|
|
157
|
+
};
|
|
158
|
+
screens: BranchCompletionScreen[];
|
|
159
|
+
pages: BranchCompletionPage[];
|
|
160
|
+
notes?: string[];
|
|
161
|
+
};
|
|
162
|
+
export declare const writeBranchCompletion: (file: string, completion: BranchCompletion) => Promise<void>;
|
|
163
|
+
export declare const readBranchCompletion: (file: string) => Promise<BranchCompletion | undefined>;
|
|
164
|
+
//# sourceMappingURL=branch-run-record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-run-record.d.ts","sourceRoot":"","sources":["../src/branch-run-record.ts"],"names":[],"mappings":"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"}
|