@12ui/design 0.2.55 → 0.2.57
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/SKILL.md +1 -1
- package/dist/branch-client.d.ts +2 -0
- package/dist/branch-client.d.ts.map +1 -1
- package/dist/branch-client.js +1 -0
- package/dist/branch-client.js.map +1 -1
- package/dist/cli-arguments.d.ts.map +1 -1
- package/dist/cli-arguments.js +2 -0
- package/dist/cli-arguments.js.map +1 -1
- package/dist/cli-conversion-derivation.d.ts +2 -1
- package/dist/cli-conversion-derivation.d.ts.map +1 -1
- package/dist/cli-conversion-derivation.js +9 -1
- package/dist/cli-conversion-derivation.js.map +1 -1
- package/dist/cli-convert-command.d.ts.map +1 -1
- package/dist/cli-convert-command.js +111 -16
- package/dist/cli-convert-command.js.map +1 -1
- package/dist/cli-corpus-command.d.ts.map +1 -1
- package/dist/cli-corpus-command.js +5 -2
- package/dist/cli-corpus-command.js.map +1 -1
- package/dist/cli-corpus-evidence.d.ts.map +1 -1
- package/dist/cli-corpus-evidence.js +2 -1
- package/dist/cli-corpus-evidence.js.map +1 -1
- package/dist/cli-corpus-reference-downloads.d.ts +1 -0
- package/dist/cli-corpus-reference-downloads.d.ts.map +1 -1
- package/dist/cli-corpus-reference-downloads.js +13 -3
- package/dist/cli-corpus-reference-downloads.js.map +1 -1
- package/dist/cli-corpus-types.d.ts +2 -0
- package/dist/cli-corpus-types.d.ts.map +1 -1
- package/dist/cli-draft-command.d.ts +11 -0
- package/dist/cli-draft-command.d.ts.map +1 -1
- package/dist/cli-draft-command.js +10 -1
- package/dist/cli-draft-command.js.map +1 -1
- package/dist/cli-help/design.d.ts +2 -2
- package/dist/cli-help/design.d.ts.map +1 -1
- package/dist/cli-help/design.js +12 -2
- package/dist/cli-help/design.js.map +1 -1
- package/dist/cli-help/index.d.ts +2 -2
- package/dist/cli-improve-command.d.ts.map +1 -1
- package/dist/cli-improve-command.js +317 -70
- package/dist/cli-improve-command.js.map +1 -1
- package/dist/cli-next-command.d.ts.map +1 -1
- package/dist/cli-next-command.js +44 -4
- package/dist/cli-next-command.js.map +1 -1
- package/dist/cli-usage.js +2 -2
- package/dist/concept-input.d.ts +21 -0
- package/dist/concept-input.d.ts.map +1 -1
- package/dist/concept-input.js +32 -10
- package/dist/concept-input.js.map +1 -1
- package/dist/conversion-client.d.ts +39 -1
- package/dist/conversion-client.d.ts.map +1 -1
- package/dist/conversion-client.js +205 -3
- package/dist/conversion-client.js.map +1 -1
- package/dist/corpus-client.d.ts +7 -1
- package/dist/corpus-client.d.ts.map +1 -1
- package/dist/corpus-client.js +6 -2
- package/dist/corpus-client.js.map +1 -1
- package/dist/corpus-reference-download-retry.d.ts +68 -0
- package/dist/corpus-reference-download-retry.d.ts.map +1 -0
- package/dist/corpus-reference-download-retry.js +123 -0
- package/dist/corpus-reference-download-retry.js.map +1 -0
- package/dist/corpus-request-error.d.ts +17 -0
- package/dist/corpus-request-error.d.ts.map +1 -0
- package/dist/corpus-request-error.js +21 -0
- package/dist/corpus-request-error.js.map +1 -0
- package/dist/draft-run.d.ts +9 -0
- package/dist/draft-run.d.ts.map +1 -1
- package/dist/draft-run.js +22 -5
- package/dist/draft-run.js.map +1 -1
- package/dist/draft-workspace.d.ts +2 -1
- package/dist/draft-workspace.d.ts.map +1 -1
- package/dist/draft-workspace.js.map +1 -1
- package/dist/hosted-draft-identity.d.ts +1 -0
- package/dist/hosted-draft-identity.d.ts.map +1 -1
- package/dist/hosted-draft-identity.js +1 -0
- package/dist/hosted-draft-identity.js.map +1 -1
- package/dist/improve-added-specs.d.ts +9 -0
- package/dist/improve-added-specs.d.ts.map +1 -1
- package/dist/improve-added-specs.js +28 -7
- package/dist/improve-added-specs.js.map +1 -1
- package/dist/improve-bootstrap-secret.d.ts +35 -0
- package/dist/improve-bootstrap-secret.d.ts.map +1 -0
- package/dist/improve-bootstrap-secret.js +61 -0
- package/dist/improve-bootstrap-secret.js.map +1 -0
- package/dist/improve-capture-redirect.d.ts +46 -0
- package/dist/improve-capture-redirect.d.ts.map +1 -0
- package/dist/improve-capture-redirect.js +68 -0
- package/dist/improve-capture-redirect.js.map +1 -0
- package/dist/improve-concept.d.ts +14 -1
- package/dist/improve-concept.d.ts.map +1 -1
- package/dist/improve-concept.js +29 -8
- package/dist/improve-concept.js.map +1 -1
- package/dist/improve-conversion-attempts.d.ts +96 -0
- package/dist/improve-conversion-attempts.d.ts.map +1 -0
- package/dist/improve-conversion-attempts.js +93 -0
- package/dist/improve-conversion-attempts.js.map +1 -0
- package/dist/improve-conversion-stage.d.ts +14 -0
- package/dist/improve-conversion-stage.d.ts.map +1 -1
- package/dist/improve-conversion-stage.js +254 -70
- package/dist/improve-conversion-stage.js.map +1 -1
- package/dist/improve-convert-progress.d.ts +36 -0
- package/dist/improve-convert-progress.d.ts.map +1 -0
- package/dist/improve-convert-progress.js +43 -0
- package/dist/improve-convert-progress.js.map +1 -0
- package/dist/improve-convert-resilience.d.ts +116 -0
- package/dist/improve-convert-resilience.d.ts.map +1 -1
- package/dist/improve-convert-resilience.js +158 -1
- package/dist/improve-convert-resilience.js.map +1 -1
- package/dist/improve-delivery-stages.d.ts.map +1 -1
- package/dist/improve-delivery-stages.js +5 -0
- package/dist/improve-delivery-stages.js.map +1 -1
- package/dist/improve-dom-diff.d.ts +2 -0
- package/dist/improve-dom-diff.d.ts.map +1 -1
- package/dist/improve-dom-diff.js +7 -0
- package/dist/improve-dom-diff.js.map +1 -1
- package/dist/improve-dom-gate.d.ts +7 -0
- package/dist/improve-dom-gate.d.ts.map +1 -1
- package/dist/improve-dom-gate.js +13 -0
- package/dist/improve-dom-gate.js.map +1 -1
- package/dist/improve-generation-stages.d.ts +3 -0
- package/dist/improve-generation-stages.d.ts.map +1 -1
- package/dist/improve-generation-stages.js +56 -10
- package/dist/improve-generation-stages.js.map +1 -1
- package/dist/improve-icon-svg.d.ts +47 -0
- package/dist/improve-icon-svg.d.ts.map +1 -0
- package/dist/improve-icon-svg.js +83 -0
- package/dist/improve-icon-svg.js.map +1 -0
- package/dist/improve-kit-assets.d.ts +129 -0
- package/dist/improve-kit-assets.d.ts.map +1 -0
- package/dist/improve-kit-assets.js +333 -0
- package/dist/improve-kit-assets.js.map +1 -0
- package/dist/improve-kit-ignore.d.ts +32 -0
- package/dist/improve-kit-ignore.d.ts.map +1 -0
- package/dist/improve-kit-ignore.js +111 -0
- package/dist/improve-kit-ignore.js.map +1 -0
- package/dist/improve-kit-readme.d.ts +11 -2
- package/dist/improve-kit-readme.d.ts.map +1 -1
- package/dist/improve-kit-readme.js +282 -26
- package/dist/improve-kit-readme.js.map +1 -1
- package/dist/improve-kit-stall.d.ts +113 -0
- package/dist/improve-kit-stall.d.ts.map +1 -0
- package/dist/improve-kit-stall.js +311 -0
- package/dist/improve-kit-stall.js.map +1 -0
- package/dist/improve-kit-status.d.ts +105 -0
- package/dist/improve-kit-status.d.ts.map +1 -0
- package/dist/improve-kit-status.js +215 -0
- package/dist/improve-kit-status.js.map +1 -0
- package/dist/improve-options.d.ts +16 -1
- package/dist/improve-options.d.ts.map +1 -1
- package/dist/improve-options.js +65 -15
- package/dist/improve-options.js.map +1 -1
- package/dist/improve-plan-annotated-render.d.ts +45 -0
- package/dist/improve-plan-annotated-render.d.ts.map +1 -0
- package/dist/improve-plan-annotated-render.js +196 -0
- package/dist/improve-plan-annotated-render.js.map +1 -0
- package/dist/improve-plan-annotator.d.ts +7 -1
- package/dist/improve-plan-annotator.d.ts.map +1 -1
- package/dist/improve-plan-annotator.js +22 -45
- package/dist/improve-plan-annotator.js.map +1 -1
- package/dist/improve-raster-layers-section.d.ts +21 -0
- package/dist/improve-raster-layers-section.d.ts.map +1 -0
- package/dist/improve-raster-layers-section.js +45 -0
- package/dist/improve-raster-layers-section.js.map +1 -0
- package/dist/improve-reset.d.ts +122 -0
- package/dist/improve-reset.d.ts.map +1 -0
- package/dist/improve-reset.js +141 -0
- package/dist/improve-reset.js.map +1 -0
- package/dist/improve-run-summary.d.ts +35 -0
- package/dist/improve-run-summary.d.ts.map +1 -0
- package/dist/improve-run-summary.js +180 -0
- package/dist/improve-run-summary.js.map +1 -0
- package/dist/improve-stage-shared.d.ts +44 -1
- package/dist/improve-stage-shared.d.ts.map +1 -1
- package/dist/improve-stage-shared.js +80 -3
- package/dist/improve-stage-shared.js.map +1 -1
- package/dist/improve-stop-handler.d.ts +73 -0
- package/dist/improve-stop-handler.d.ts.map +1 -0
- package/dist/improve-stop-handler.js +126 -0
- package/dist/improve-stop-handler.js.map +1 -0
- package/dist/improve-terminal-event.d.ts +118 -0
- package/dist/improve-terminal-event.d.ts.map +1 -0
- package/dist/improve-terminal-event.js +87 -0
- package/dist/improve-terminal-event.js.map +1 -0
- package/dist/improve-token-patch.d.ts +2 -0
- package/dist/improve-token-patch.d.ts.map +1 -1
- package/dist/improve-token-patch.js +23 -5
- package/dist/improve-token-patch.js.map +1 -1
- package/dist/improve-workspace.d.ts +94 -2
- package/dist/improve-workspace.d.ts.map +1 -1
- package/dist/improve-workspace.js +19 -1
- package/dist/improve-workspace.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/legacy-skill-catalog.d.ts.map +1 -1
- package/dist/legacy-skill-catalog.js +143 -0
- package/dist/legacy-skill-catalog.js.map +1 -1
- package/dist/mcp-tool-definitions.js +1 -1
- package/dist/mcp-tool-definitions.js.map +1 -1
- package/dist/mcp-tool-handler.d.ts.map +1 -1
- package/dist/mcp-tool-handler.js +3 -0
- package/dist/mcp-tool-handler.js.map +1 -1
- package/dist/redesign-capture.d.ts +17 -0
- package/dist/redesign-capture.d.ts.map +1 -1
- package/dist/redesign-capture.js +55 -3
- package/dist/redesign-capture.js.map +1 -1
- package/dist/responsive-alternative-materializer.d.ts +19 -0
- package/dist/responsive-alternative-materializer.d.ts.map +1 -0
- package/dist/responsive-alternative-materializer.js +76 -0
- package/dist/responsive-alternative-materializer.js.map +1 -0
- package/dist/run-journal-unfinished.d.ts +56 -0
- package/dist/run-journal-unfinished.d.ts.map +1 -0
- package/dist/run-journal-unfinished.js +126 -0
- package/dist/run-journal-unfinished.js.map +1 -0
- package/dist/run-journal.d.ts +25 -1
- package/dist/run-journal.d.ts.map +1 -1
- package/dist/run-journal.js +15 -1
- package/dist/run-journal.js.map +1 -1
- package/open-design.json +2 -2
- package/package.json +1 -1
- package/skills/12ui-design/SKILL.md +9 -1
- package/skills/12ui-design/improve.md +83 -6
- package/skills/12ui-design/inspire.md +1 -1
|
@@ -10,7 +10,7 @@ export declare const DESIGN_HELP: {
|
|
|
10
10
|
readonly summary: "Search the Design Corpus and download validated visual references.";
|
|
11
11
|
readonly sections: readonly [{
|
|
12
12
|
readonly heading: "Behavior";
|
|
13
|
-
readonly items: readonly ["Runs in the foreground and writes an attempt record before the metered search, then a manifest, evidence, receipts, and downloaded references.", "Defaults to four references in balanced mode; --count accepts 1–48.", "--reference-image conditions retrieval on an existing PNG, JPEG, or WebP."];
|
|
13
|
+
readonly items: readonly ["Runs in the foreground and writes an attempt record before the metered search, then a manifest, evidence, receipts, and downloaded references.", "Defaults to four references in balanced mode; --count accepts 1–48 (hedge: 4–12).", "--reference-image conditions retrieval on an existing PNG, JPEG, or WebP."];
|
|
14
14
|
}, {
|
|
15
15
|
readonly heading: "Modes";
|
|
16
16
|
readonly items: readonly ["direct stays closest to the literal query.", "balanced is the default relevance, quality, and variety trade-off.", "adventurer keeps a relevant head while exploring less expected directions."];
|
|
@@ -84,7 +84,7 @@ export declare const DESIGN_HELP: {
|
|
|
84
84
|
readonly summary: "Improve one live interface or screenshot and produce a replayable implementation kit.";
|
|
85
85
|
readonly sections: readonly [{
|
|
86
86
|
readonly heading: "Behavior";
|
|
87
|
-
readonly items: readonly ["Five stages run in order: local capture, hosted draft candidates retaining layout and content, explicit pick, fused LayerDoc and responsive HTML conversion, then a local implementation plan.", "URL input uses one Playwright context for repeated --bootstrap actions, screenshot capture, and selector-verified DOM extraction. Image input normalizes the source locally.", "The kit keeps every candidate, winner, target, plan, assets, and improve.json replay record. Repeating a settled stage reuses it; --from pick --pick <slot> invalidates only the old target and plan.", "--responsive-quality selects standard or pro responsive export. If that export fails or reaches the improve deadline after LayerDoc materialization, improve derives fixed HTML free and continues to plan with a warning.", "--
|
|
87
|
+
readonly items: readonly ["Five stages run in order: local capture, hosted draft candidates retaining layout and content, explicit pick, fused LayerDoc and responsive HTML conversion, then a local implementation plan.", "The pick is explicit and has no default. With no --pick and no pick already recorded, the run stops after the draw, prints where the candidates are and the exact command that continues (--from pick --pick <slot>), and buys no conversion: converting a candidate nobody chose spends money on a guess that cannot be cancelled. --target supplies the design instead and skips draft and pick.", "URL input uses one Playwright context for repeated --bootstrap actions, screenshot capture, and selector-verified DOM extraction. Image input normalizes the source locally.", string, "The kit keeps every candidate, winner, target, plan, assets, and improve.json replay record. Repeating a settled stage reuses it; --from pick --pick <slot> invalidates only the old target and plan.", "--responsive-quality selects standard or pro responsive export. If that export fails or reaches the improve deadline after LayerDoc materialization, improve derives fixed HTML free and continues to plan with a warning.", "--convert-stall-seconds bounds every hosted wait the convert stage makes, including the free fixed-layout derivation (default: twice the model's typical wall, 480s standard and pro, 300s fast; refused below one typical wall). If a wait ends with no LayerDoc on disk there is nothing to derive, so improve records the abandoned conversion and dispatches exactly ONE fresh one; a second stall writes plan/STALL.md and exits non-zero. The retry budget belongs to the kit: a resume re-attaches to the newest conversion already bought, a kit that has spent its retry refuses to dispatch again, and a pro conversion is never retried automatically because no measured wall justifies it. Stopping the wait does not stop the conversion: there is no cancel, so an abandoned run keeps billing.", "--fresh re-buys ONE conversion of the same settled winner under a new idempotency key: it records the abandoned conversion identity and reuses capture, draft and pick untouched. --redraw is the one that buys new candidates — it discards draft, pick, convert and plan, moves the old draw to candidates.previous, records any conversion it drops, and runs the draft stage again; it is also the one path allowed to change --direction, --candidates or --retain against the record. A temporarily unavailable stage retries once after 30 seconds.", "--target brings your own design image or LayerDoc, skips draft and pick, converts an image when needed, and aligns the plan to the captured URL DOM."];
|
|
88
88
|
}, {
|
|
89
89
|
readonly heading: "Planning";
|
|
90
90
|
readonly items: readonly ["URL plans require at least 60% plausible DOM-side coverage; a blocked gate writes GATE.md while target HTML and LayerDoc remain authoritative sidecars.", "Image plans are target-only by default. --plan-source-convert buys one source LayerDoc conversion for an unanchored LayerDoc comparison.", "--repo adds evidence-ranked src/ TSX, JSX, and CSS file hints to a URL plan. The command never applies code.", "--dry-run prints exact catalog price ceilings for every stage and makes no network request."];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"design.d.ts","sourceRoot":"","sources":["../../src/cli-help/design.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"design.d.ts","sourceRoot":"","sources":["../../src/cli-help/design.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwOW,CAAC"}
|
package/dist/cli-help/design.js
CHANGED
|
@@ -16,7 +16,7 @@ export const DESIGN_HELP = {
|
|
|
16
16
|
heading: 'Behavior',
|
|
17
17
|
items: [
|
|
18
18
|
'Runs in the foreground and writes an attempt record before the metered search, then a manifest, evidence, receipts, and downloaded references.',
|
|
19
|
-
'Defaults to four references in balanced mode; --count accepts 1–48.',
|
|
19
|
+
'Defaults to four references in balanced mode; --count accepts 1–48 (hedge: 4–12).',
|
|
20
20
|
'--reference-image conditions retrieval on an existing PNG, JPEG, or WebP.',
|
|
21
21
|
],
|
|
22
22
|
},
|
|
@@ -168,10 +168,20 @@ export const DESIGN_HELP = {
|
|
|
168
168
|
heading: 'Behavior',
|
|
169
169
|
items: [
|
|
170
170
|
'Five stages run in order: local capture, hosted draft candidates retaining layout and content, explicit pick, fused LayerDoc and responsive HTML conversion, then a local implementation plan.',
|
|
171
|
+
'The pick is explicit and has no default. With no --pick and no pick already recorded, the run stops after the draw, prints where the candidates are and the exact command that continues (--from pick --pick <slot>), and buys no conversion: converting a candidate nobody chose spends money on a guess that cannot be cancelled. --target supplies the design instead and skips draft and pick.',
|
|
171
172
|
'URL input uses one Playwright context for repeated --bootstrap actions, screenshot capture, and selector-verified DOM extraction. Image input normalizes the source locally.',
|
|
173
|
+
"--bootstrap takes ONE quoted pipe-separated triple, not three alternatives:"
|
|
174
|
+
+ " '<url>|<click-selector>|<wait-url>'. Any field may be empty and the flag repeats, so"
|
|
175
|
+
+ " --bootstrap '|button[data-test=sign-in]|**/dashboard' clicks and then waits. A value"
|
|
176
|
+
+ ' with no pipe is read as a click selector unless it starts with http:// or https://.'
|
|
177
|
+
+ ' A magic-link triple carries a live session token, so improve.json records only a'
|
|
178
|
+
+ ' redacted form of it (query values and fragment replaced) plus a sha256; the live'
|
|
179
|
+
+ ' value is never written to disk, and a resume that has to capture again asks for'
|
|
180
|
+
+ ' --bootstrap once more.',
|
|
172
181
|
'The kit keeps every candidate, winner, target, plan, assets, and improve.json replay record. Repeating a settled stage reuses it; --from pick --pick <slot> invalidates only the old target and plan.',
|
|
173
182
|
'--responsive-quality selects standard or pro responsive export. If that export fails or reaches the improve deadline after LayerDoc materialization, improve derives fixed HTML free and continues to plan with a warning.',
|
|
174
|
-
|
|
183
|
+
"--convert-stall-seconds bounds every hosted wait the convert stage makes, including the free fixed-layout derivation (default: twice the model's typical wall, 480s standard and pro, 300s fast; refused below one typical wall). If a wait ends with no LayerDoc on disk there is nothing to derive, so improve records the abandoned conversion and dispatches exactly ONE fresh one; a second stall writes plan/STALL.md and exits non-zero. The retry budget belongs to the kit: a resume re-attaches to the newest conversion already bought, a kit that has spent its retry refuses to dispatch again, and a pro conversion is never retried automatically because no measured wall justifies it. Stopping the wait does not stop the conversion: there is no cancel, so an abandoned run keeps billing.",
|
|
184
|
+
'--fresh re-buys ONE conversion of the same settled winner under a new idempotency key: it records the abandoned conversion identity and reuses capture, draft and pick untouched. --redraw is the one that buys new candidates — it discards draft, pick, convert and plan, moves the old draw to candidates.previous, records any conversion it drops, and runs the draft stage again; it is also the one path allowed to change --direction, --candidates or --retain against the record. A temporarily unavailable stage retries once after 30 seconds.',
|
|
175
185
|
'--target brings your own design image or LayerDoc, skips draft and pick, converts an image when needed, and aligns the plan to the captured URL DOM.',
|
|
176
186
|
],
|
|
177
187
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"design.js","sourceRoot":"","sources":["../../src/cli-help/design.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,MAAM,EAAE;QACN,OAAO,EAAE,2EAA2E;QACpF,QAAQ,EAAE,CAAC;gBACT,OAAO,EAAE,SAAS;gBAClB,KAAK,EAAE;oBACL,yEAAyE;oBACzE,wEAAwE;iBACzE;aACF,CAAC;KACH;IACD,gBAAgB,EAAE;QAChB,OAAO,EAAE,oEAAoE;QAC7E,QAAQ,EAAE;YACR;gBACE,OAAO,EAAE,UAAU;gBACnB,KAAK,EAAE;oBACL,gJAAgJ;oBAChJ,
|
|
1
|
+
{"version":3,"file":"design.js","sourceRoot":"","sources":["../../src/cli-help/design.ts"],"names":[],"mappings":"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"}
|
package/dist/cli-help/index.d.ts
CHANGED
|
@@ -70,7 +70,7 @@ export declare const CLI_HELP_CONTEXTS: {
|
|
|
70
70
|
readonly summary: "Search the Design Corpus and download validated visual references.";
|
|
71
71
|
readonly sections: readonly [{
|
|
72
72
|
readonly heading: "Behavior";
|
|
73
|
-
readonly items: readonly ["Runs in the foreground and writes an attempt record before the metered search, then a manifest, evidence, receipts, and downloaded references.", "Defaults to four references in balanced mode; --count accepts 1–48.", "--reference-image conditions retrieval on an existing PNG, JPEG, or WebP."];
|
|
73
|
+
readonly items: readonly ["Runs in the foreground and writes an attempt record before the metered search, then a manifest, evidence, receipts, and downloaded references.", "Defaults to four references in balanced mode; --count accepts 1–48 (hedge: 4–12).", "--reference-image conditions retrieval on an existing PNG, JPEG, or WebP."];
|
|
74
74
|
}, {
|
|
75
75
|
readonly heading: "Modes";
|
|
76
76
|
readonly items: readonly ["direct stays closest to the literal query.", "balanced is the default relevance, quality, and variety trade-off.", "adventurer keeps a relevant head while exploring less expected directions."];
|
|
@@ -144,7 +144,7 @@ export declare const CLI_HELP_CONTEXTS: {
|
|
|
144
144
|
readonly summary: "Improve one live interface or screenshot and produce a replayable implementation kit.";
|
|
145
145
|
readonly sections: readonly [{
|
|
146
146
|
readonly heading: "Behavior";
|
|
147
|
-
readonly items: readonly ["Five stages run in order: local capture, hosted draft candidates retaining layout and content, explicit pick, fused LayerDoc and responsive HTML conversion, then a local implementation plan.", "URL input uses one Playwright context for repeated --bootstrap actions, screenshot capture, and selector-verified DOM extraction. Image input normalizes the source locally.", "The kit keeps every candidate, winner, target, plan, assets, and improve.json replay record. Repeating a settled stage reuses it; --from pick --pick <slot> invalidates only the old target and plan.", "--responsive-quality selects standard or pro responsive export. If that export fails or reaches the improve deadline after LayerDoc materialization, improve derives fixed HTML free and continues to plan with a warning.", "--
|
|
147
|
+
readonly items: readonly ["Five stages run in order: local capture, hosted draft candidates retaining layout and content, explicit pick, fused LayerDoc and responsive HTML conversion, then a local implementation plan.", "The pick is explicit and has no default. With no --pick and no pick already recorded, the run stops after the draw, prints where the candidates are and the exact command that continues (--from pick --pick <slot>), and buys no conversion: converting a candidate nobody chose spends money on a guess that cannot be cancelled. --target supplies the design instead and skips draft and pick.", "URL input uses one Playwright context for repeated --bootstrap actions, screenshot capture, and selector-verified DOM extraction. Image input normalizes the source locally.", string, "The kit keeps every candidate, winner, target, plan, assets, and improve.json replay record. Repeating a settled stage reuses it; --from pick --pick <slot> invalidates only the old target and plan.", "--responsive-quality selects standard or pro responsive export. If that export fails or reaches the improve deadline after LayerDoc materialization, improve derives fixed HTML free and continues to plan with a warning.", "--convert-stall-seconds bounds every hosted wait the convert stage makes, including the free fixed-layout derivation (default: twice the model's typical wall, 480s standard and pro, 300s fast; refused below one typical wall). If a wait ends with no LayerDoc on disk there is nothing to derive, so improve records the abandoned conversion and dispatches exactly ONE fresh one; a second stall writes plan/STALL.md and exits non-zero. The retry budget belongs to the kit: a resume re-attaches to the newest conversion already bought, a kit that has spent its retry refuses to dispatch again, and a pro conversion is never retried automatically because no measured wall justifies it. Stopping the wait does not stop the conversion: there is no cancel, so an abandoned run keeps billing.", "--fresh re-buys ONE conversion of the same settled winner under a new idempotency key: it records the abandoned conversion identity and reuses capture, draft and pick untouched. --redraw is the one that buys new candidates — it discards draft, pick, convert and plan, moves the old draw to candidates.previous, records any conversion it drops, and runs the draft stage again; it is also the one path allowed to change --direction, --candidates or --retain against the record. A temporarily unavailable stage retries once after 30 seconds.", "--target brings your own design image or LayerDoc, skips draft and pick, converts an image when needed, and aligns the plan to the captured URL DOM."];
|
|
148
148
|
}, {
|
|
149
149
|
readonly heading: "Planning";
|
|
150
150
|
readonly items: readonly ["URL plans require at least 60% plausible DOM-side coverage; a blocked gate writes GATE.md while target HTML and LayerDoc remain authoritative sidecars.", "Image plans are target-only by default. --plan-source-convert buys one source LayerDoc conversion for an unanchored LayerDoc comparison.", "--repo adds evidence-ranked src/ TSX, JSX, and CSS file hints to a URL plan. The command never applies code.", "--dry-run prints exact catalog price ceilings for every stage and makes no network request."];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-improve-command.d.ts","sourceRoot":"","sources":["../src/cli-improve-command.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli-improve-command.d.ts","sourceRoot":"","sources":["../src/cli-improve-command.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AA4BnD,OAAO,EAQL,KAAK,0BAA0B,EAChC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,wBAAwB,CAAC;AAyGhC,eAAO,MAAM,iBAAiB,GAC5B,SAAS,SAAS,MAAM,EAAE,EAC1B,OAAO,QAAQ,EACf,eAAc,0BAA+B,KAC5C,OAAO,CAAC,aAAa,CA2VvB,CAAC"}
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import { createHash, randomUUID } from 'node:crypto';
|
|
2
2
|
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
3
4
|
import { CliRefusal } from './cli-refusal.js';
|
|
4
5
|
import { prepareOutputDirectory } from './cli-output-paths.js';
|
|
5
6
|
import { parseImproveOptions } from './improve-options.js';
|
|
6
7
|
import { buildImprovePricingPlan } from './improve-pricing-plan.js';
|
|
7
|
-
import {
|
|
8
|
+
import { assertImproveCaptureNotRedirected } from './improve-capture-redirect.js';
|
|
9
|
+
import { improveBootstrapDigest, improveBootstrapRecordFields, redactImproveBootstrap, } from './improve-bootstrap-secret.js';
|
|
10
|
+
import { improveStalled, retryImproveTemporarilyUnavailable } from './improve-convert-resilience.js';
|
|
11
|
+
import { ensureImproveKitIgnored } from './improve-kit-ignore.js';
|
|
12
|
+
import { resolveImproveStall, writeImproveFallbackStall, writeImproveStallReport, } from './improve-kit-stall.js';
|
|
13
|
+
import { readImproveKitStatus } from './improve-kit-status.js';
|
|
14
|
+
import { resetImproveDraw } from './improve-reset.js';
|
|
15
|
+
import { awaitingImprovePick, buildImproveRunSummary, improveStallErrorWithSummary, } from './improve-run-summary.js';
|
|
16
|
+
import { markImproveStageStalled } from './improve-stage-shared.js';
|
|
17
|
+
import { registerImproveStopHandler } from './improve-stop-handler.js';
|
|
18
|
+
import { noteImproveTerminalEvent } from './improve-terminal-event.js';
|
|
8
19
|
import { runImproveCaptureStage, runImproveConvertStage, runImproveDraftStage, markImproveStageSkipped, runImprovePickStage, runImprovePlanStage, writeImproveReadme, } from './improve-stage-runners.js';
|
|
9
20
|
import { IMPROVE_STAGES, readImproveRecord, writeImproveRecord, } from './improve-workspace.js';
|
|
10
21
|
/**
|
|
@@ -13,11 +24,34 @@ import { IMPROVE_STAGES, readImproveRecord, writeImproveRecord, } from './improv
|
|
|
13
24
|
* modules. No server route or billing path is introduced here.
|
|
14
25
|
*/
|
|
15
26
|
const same = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
27
|
+
/**
|
|
28
|
+
* A mismatch refusal that names neither value is a dead end: the reader knows
|
|
29
|
+
* the flag disagrees with the record and has to open `improve.json` to find out
|
|
30
|
+
* what it holds. `--bootstrap` is the case that cost a run — its recorded value
|
|
31
|
+
* is a quoted triple nobody remembers typing.
|
|
32
|
+
*/
|
|
33
|
+
const describeRecordedValue = (value) => {
|
|
34
|
+
if (value === undefined || value === null)
|
|
35
|
+
return 'nothing';
|
|
36
|
+
if (Array.isArray(value)) {
|
|
37
|
+
return value.length === 0 ? 'nothing' : value.map((entry) => `'${String(entry)}'`).join(', ');
|
|
38
|
+
}
|
|
39
|
+
if (typeof value === 'object')
|
|
40
|
+
return JSON.stringify(value);
|
|
41
|
+
return `'${String(value)}'`;
|
|
42
|
+
};
|
|
16
43
|
const assertCompatibleRecord = async (args) => {
|
|
17
44
|
if (!same(args.record.input.kind, args.parsed.input.kind)
|
|
18
45
|
|| !same(args.record.input.value, args.parsed.input.value)) {
|
|
19
46
|
throw new CliRefusal('This improve directory belongs to a different input', 'improve_record_mismatch');
|
|
20
47
|
}
|
|
48
|
+
// `--redraw` throws the draw away and buys another one, so the three flags
|
|
49
|
+
// that describe a draw are the ones it is entitled to change. Refusing them
|
|
50
|
+
// made the documented redraw command — the one that passes a new
|
|
51
|
+
// `--direction` — impossible to run, and sent the reader to a fresh
|
|
52
|
+
// `--out-dir`, which re-buys the capture too. Everything else still has to
|
|
53
|
+
// match: a redraw does not license a different model or a different page.
|
|
54
|
+
const drawFlags = new Set(args.parsed.redraw ? ['direction', 'candidates', 'retain'] : []);
|
|
21
55
|
const explicitChecks = [
|
|
22
56
|
['direction', args.record.direction, args.parsed.direction],
|
|
23
57
|
['candidates', args.record.candidates, args.parsed.candidates],
|
|
@@ -26,14 +60,31 @@ const assertCompatibleRecord = async (args) => {
|
|
|
26
60
|
['responsive-quality', args.record.responsiveQuality, args.parsed.responsiveQuality],
|
|
27
61
|
['viewport', args.record.viewport, args.parsed.viewport],
|
|
28
62
|
['full-page', args.record.fullPage, args.parsed.fullPage],
|
|
29
|
-
['bootstrap', args.record.bootstrap, args.parsed.bootstrapValues],
|
|
30
63
|
['repo', args.record.repo, args.parsed.repo],
|
|
31
64
|
['plan-source-convert', args.record.planSourceConvert, args.parsed.planSourceConvert],
|
|
32
65
|
['target', args.record.target && { kind: args.record.target.kind, value: args.record.target.value }, args.parsed.target],
|
|
33
66
|
];
|
|
67
|
+
// `--bootstrap` compares by digest, because the record deliberately holds no
|
|
68
|
+
// live value to compare against (F31), and neither side of the refusal may
|
|
69
|
+
// print the secret.
|
|
70
|
+
if (args.flags.bootstrap !== undefined
|
|
71
|
+
&& !same(args.record.bootstrapSha256 ?? [], args.parsed.bootstrapValues.map(improveBootstrapDigest))) {
|
|
72
|
+
throw new CliRefusal('--bootstrap does not match the durable improve record.'
|
|
73
|
+
+ ` The record holds ${describeRecordedValue(args.record.bootstrap)}`
|
|
74
|
+
+ ' (query values redacted; the live value is never stored);'
|
|
75
|
+
+ ` this run asked for ${describeRecordedValue(args.parsed.bootstrapValues.map(redactImproveBootstrap))}.`
|
|
76
|
+
+ ' Drop --bootstrap to reuse what the record already captured,'
|
|
77
|
+
+ ' or pass a fresh --out-dir to start over with the changed input.', 'improve_record_mismatch');
|
|
78
|
+
}
|
|
34
79
|
for (const [flag, recorded, requested] of explicitChecks) {
|
|
80
|
+
if (drawFlags.has(flag))
|
|
81
|
+
continue;
|
|
35
82
|
if (args.flags[flag] !== undefined && !same(recorded, requested)) {
|
|
36
|
-
throw new CliRefusal(`--${flag} does not match the durable improve record
|
|
83
|
+
throw new CliRefusal(`--${flag} does not match the durable improve record.`
|
|
84
|
+
+ ` The record holds ${describeRecordedValue(recorded)};`
|
|
85
|
+
+ ` this run asked for ${describeRecordedValue(requested)}.`
|
|
86
|
+
+ ` Drop --${flag} to reuse what the record already captured,`
|
|
87
|
+
+ ' or pass a fresh --out-dir to start over with the changed input.', 'improve_record_mismatch');
|
|
37
88
|
}
|
|
38
89
|
}
|
|
39
90
|
if (args.record.input.kind === 'image' && args.record.input.sha256) {
|
|
@@ -95,7 +146,7 @@ export const runImproveCommand = async (command, flags, dependencies = {}) => {
|
|
|
95
146
|
responsiveQuality: parsed.responsiveQuality,
|
|
96
147
|
viewport: parsed.viewport,
|
|
97
148
|
fullPage: parsed.fullPage,
|
|
98
|
-
|
|
149
|
+
...improveBootstrapRecordFields(parsed.bootstrapValues),
|
|
99
150
|
...(parsed.repo ? { repo: parsed.repo } : {}),
|
|
100
151
|
planSourceConvert: parsed.planSourceConvert,
|
|
101
152
|
stages: {},
|
|
@@ -122,92 +173,288 @@ export const runImproveCommand = async (command, flags, dependencies = {}) => {
|
|
|
122
173
|
responsiveQuality: parsed.responsiveQuality,
|
|
123
174
|
viewport: parsed.viewport,
|
|
124
175
|
fullPage: parsed.fullPage,
|
|
125
|
-
|
|
176
|
+
...improveBootstrapRecordFields(parsed.bootstrapValues),
|
|
126
177
|
...(parsed.repo ? { repo: parsed.repo } : {}),
|
|
127
178
|
planSourceConvert: parsed.planSourceConvert,
|
|
128
179
|
stages: {},
|
|
129
180
|
};
|
|
181
|
+
// A kit written inside the repository it improves is ~100 MB of paid
|
|
182
|
+
// artifacts one `git add -A` away from someone's history (F17). Decided every
|
|
183
|
+
// run, because the repository's own `.gitignore` can change between them.
|
|
184
|
+
const kitIgnore = await ensureImproveKitIgnored({ outDir: parsed.paths.runDir });
|
|
185
|
+
record = { ...record, ...(kitIgnore ? { kitIgnore } : {}) };
|
|
130
186
|
await writeImproveRecord(parsed.paths.record, record);
|
|
131
187
|
const write = dependencies.write ?? ((line) => { process.stdout.write(`${line}\n`); });
|
|
132
188
|
write(parsed.paths.runDir);
|
|
133
189
|
dependencies.onRunDirectory?.(parsed.paths.runDir);
|
|
134
190
|
dependencies.journal?.note({ workspace: parsed.paths.runDir, writes: [parsed.paths.record] });
|
|
191
|
+
// The kit describes itself after every stage, not only at the end. It derives
|
|
192
|
+
// from the record plus what is on disk, so writing it repeatedly is cheap and
|
|
193
|
+
// idempotent — and a run that dies between stages still leaves a front door.
|
|
194
|
+
const refreshReadme = async () => writeImproveReadme(record, { requestedTo: parsed.to });
|
|
135
195
|
const index = (stage) => IMPROVE_STAGES.indexOf(stage);
|
|
136
196
|
const within = (stage) => index(stage) >= index(parsed.from) && index(stage) <= index(parsed.to);
|
|
137
197
|
const needed = (stage) => index(stage) <= index(parsed.to);
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
198
|
+
// The stage this invocation is INSIDE, which is what tells a stop mid-flight
|
|
199
|
+
// apart from a signal after completion. The record cannot: `--fresh` clears
|
|
200
|
+
// convert and plan from the durable record inside the convert stage, and
|
|
201
|
+
// `record` here is only reassigned when that stage returns.
|
|
202
|
+
let liveStage;
|
|
203
|
+
const runStage = async (stage, action) => {
|
|
204
|
+
liveStage = stage;
|
|
205
|
+
try {
|
|
206
|
+
return await retryImproveTemporarilyUnavailable({
|
|
207
|
+
stage,
|
|
208
|
+
action,
|
|
209
|
+
...(dependencies.sleep ? { sleep: dependencies.sleep } : {}),
|
|
210
|
+
...(dependencies.warn ? { warn: dependencies.warn } : {}),
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
finally {
|
|
214
|
+
liveStage = undefined;
|
|
215
|
+
}
|
|
216
|
+
};
|
|
144
217
|
const freshConversionNonce = parsed.fresh ? randomUUID() : undefined;
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
218
|
+
// A stalled or killed stage still owes the reader a kit that says what is
|
|
219
|
+
// missing and how to recover, and owes every other shell a terminal journal
|
|
220
|
+
// line. Without them a lane reads an empty `target/` and hand-authors the
|
|
221
|
+
// design in CSS — which is what happened on the pipedrive landing, and that
|
|
222
|
+
// lane was KILLED, not stalled, so it threw nothing the catch below could
|
|
223
|
+
// have seen. The handler is armed here, before the first stage, because a
|
|
224
|
+
// kill during capture, draft or pick used to leave nothing at all.
|
|
225
|
+
// A signal wrote this kit's `plan/STALL.md` during this very invocation, so
|
|
226
|
+
// nothing later in it may resolve that file away: in production the handler
|
|
227
|
+
// exits the process, and a harness that lets the stage unwind must not answer
|
|
228
|
+
// the signal by declaring the run fine (F21).
|
|
229
|
+
let stopped = false;
|
|
230
|
+
const disarmStop = registerImproveStopHandler({
|
|
231
|
+
getRecord: () => record,
|
|
232
|
+
onStopped: () => { stopped = true; },
|
|
233
|
+
getLiveStage: () => liveStage,
|
|
234
|
+
write,
|
|
235
|
+
requestedTo: parsed.to,
|
|
236
|
+
...(dependencies.journal ? { journal: dependencies.journal } : {}),
|
|
237
|
+
...(dependencies.stopTarget ? { target: dependencies.stopTarget } : {}),
|
|
238
|
+
...(dependencies.exit ? { exit: dependencies.exit } : {}),
|
|
239
|
+
});
|
|
240
|
+
try {
|
|
241
|
+
// `--redraw` is the flag `--fresh` was being mistaken for. `--fresh` rotates
|
|
242
|
+
// the conversion key and re-buys ONE conversion of the SAME settled winner;
|
|
243
|
+
// it never touches the draw. A caller who wanted different candidates had no
|
|
244
|
+
// flag at all. This one empties draft, pick, convert and plan, renames the
|
|
245
|
+
// old draw aside rather than deleting it, and lets the normal stage order buy
|
|
246
|
+
// a new one — announced, because it is the most expensive thing improve does.
|
|
247
|
+
if (parsed.redraw) {
|
|
248
|
+
const hadDraw = Boolean(record.draft || record.pick);
|
|
249
|
+
// Only the flags this run actually passed reach the record. A redraw that
|
|
250
|
+
// reset `--candidates` to the default because the flag was absent would
|
|
251
|
+
// buy a draw nobody asked for.
|
|
252
|
+
const reset = await resetImproveDraw({
|
|
253
|
+
record,
|
|
254
|
+
draw: {
|
|
255
|
+
...(flags.direction !== undefined
|
|
256
|
+
? { direction: parsed.direction, concept: parsed.concept }
|
|
257
|
+
: {}),
|
|
258
|
+
...(flags.candidates !== undefined ? { candidates: parsed.candidates } : {}),
|
|
259
|
+
...(flags.retain !== undefined
|
|
260
|
+
? { retain: parsed.retain, retainFlag: parsed.retainFlag }
|
|
261
|
+
: {}),
|
|
262
|
+
},
|
|
263
|
+
...(dependencies.warn ? { warn: dependencies.warn } : {}),
|
|
264
|
+
});
|
|
265
|
+
record = reset.record;
|
|
266
|
+
await writeImproveRecord(parsed.paths.record, record);
|
|
267
|
+
if (hadDraw) {
|
|
268
|
+
write(`--redraw: the previous draw moved to ${parsed.paths.candidatesDir}.previous;`
|
|
269
|
+
+ ` buying ${record.candidates} new candidates.`);
|
|
270
|
+
dependencies.journal?.note({ degradations: ['improve_draw_discarded'] });
|
|
271
|
+
}
|
|
272
|
+
// A settled conversion the redraw threw away is paid work, and there is
|
|
273
|
+
// no cancel. It belongs in the same ledger `--fresh` and a re-pick write.
|
|
274
|
+
if (reset.abandonedId) {
|
|
275
|
+
dependencies.journal?.note({ degradations: ['improve_redraw_abandoned_conversion'] });
|
|
276
|
+
}
|
|
156
277
|
}
|
|
157
|
-
|
|
158
|
-
if (within('
|
|
159
|
-
record = await runStage('
|
|
160
|
-
record, options: parsed,
|
|
278
|
+
if (needed('capture')) {
|
|
279
|
+
if (within('capture'))
|
|
280
|
+
record = await runStage('capture', () => runImproveCaptureStage({
|
|
281
|
+
record, options: parsed, dependencies, price: price.get('capture') ?? 0,
|
|
161
282
|
}));
|
|
162
|
-
if (!record.
|
|
163
|
-
missingStage('
|
|
283
|
+
if (!record.capture)
|
|
284
|
+
missingStage('capture', parsed.paths.runDir);
|
|
285
|
+
await refreshReadme();
|
|
286
|
+
// Free, deterministic, and BEFORE the draft purchase: the captured page
|
|
287
|
+
// and the requested one have to be the same page, or nothing is bought
|
|
288
|
+
// (F27). The capture and the README above are already on disk, so the
|
|
289
|
+
// refusal costs a reader nothing and the next run replays them.
|
|
290
|
+
assertImproveCaptureNotRedirected({
|
|
291
|
+
record, allowRedirect: parsed.allowRedirect, runDir: parsed.paths.runDir,
|
|
292
|
+
});
|
|
164
293
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
294
|
+
if (needed('draft')) {
|
|
295
|
+
if (record.target) {
|
|
296
|
+
record = await markImproveStageSkipped(record, 'draft');
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
if (within('draft'))
|
|
300
|
+
record = await runStage('draft', () => runImproveDraftStage({
|
|
301
|
+
record, options: parsed, flags, dependencies, price: price.get('draft') ?? 0,
|
|
302
|
+
}));
|
|
303
|
+
if (!record.draft)
|
|
304
|
+
missingStage('draft', parsed.paths.runDir);
|
|
305
|
+
}
|
|
306
|
+
await refreshReadme();
|
|
169
307
|
}
|
|
170
|
-
|
|
171
|
-
if (
|
|
172
|
-
record = await
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
308
|
+
if (needed('pick')) {
|
|
309
|
+
if (record.target) {
|
|
310
|
+
record = await markImproveStageSkipped(record, 'pick');
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
// DISPATCH DISCIPLINE. A draw is alternatives; converting one of them
|
|
314
|
+
// before anyone has looked spends money on a guess. `--pick` used to
|
|
315
|
+
// default to A and the convert stage ran straight on, so notion bought
|
|
316
|
+
// a conversion of candidate A four milliseconds after the draft
|
|
317
|
+
// settled — and then a second process converted D, the one actually
|
|
318
|
+
// chosen. With no `--pick` and no recorded pick, the run stops here.
|
|
319
|
+
const chosen = parsed.pick ?? record.pick?.slot;
|
|
320
|
+
if (within('pick')) {
|
|
321
|
+
// Nothing to settle and nobody to ask: stop, and print the one
|
|
322
|
+
// command that continues. A range that starts AFTER pick asked to
|
|
323
|
+
// skip this stage, so it falls through to the honest refusal below
|
|
324
|
+
// rather than quietly stopping where it was told not to.
|
|
325
|
+
if (!chosen) {
|
|
326
|
+
await refreshReadme();
|
|
327
|
+
write(awaitingImprovePick({ record, options: parsed }));
|
|
328
|
+
dependencies.journal?.note({
|
|
329
|
+
workspace: parsed.paths.runDir,
|
|
330
|
+
artifacts: [parsed.paths.record, parsed.paths.readme],
|
|
331
|
+
purchased: record.draft ? [record.draft.runId] : [],
|
|
332
|
+
terminal: false,
|
|
333
|
+
});
|
|
334
|
+
console.log(JSON.stringify({ from: parsed.from, to: parsed.to, ...record }, null, 2));
|
|
335
|
+
return record;
|
|
336
|
+
}
|
|
337
|
+
record = await runStage('pick', () => runImprovePickStage({
|
|
338
|
+
record, options: parsed, pick: chosen, dependencies, price: price.get('pick') ?? 0,
|
|
339
|
+
}));
|
|
340
|
+
}
|
|
341
|
+
if (!record.pick)
|
|
342
|
+
missingStage('pick', parsed.paths.runDir);
|
|
343
|
+
}
|
|
344
|
+
await refreshReadme();
|
|
177
345
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
346
|
+
try {
|
|
347
|
+
if (needed('convert')) {
|
|
348
|
+
if (within('convert'))
|
|
349
|
+
record = await runStage('convert', () => runImproveConvertStage({
|
|
350
|
+
record,
|
|
351
|
+
options: parsed,
|
|
352
|
+
dependencies,
|
|
353
|
+
price: price.get('convert') ?? 0,
|
|
354
|
+
...(freshConversionNonce ? { freshConversionNonce } : {}),
|
|
355
|
+
}));
|
|
356
|
+
if (!record.convert)
|
|
357
|
+
missingStage('convert', parsed.paths.runDir);
|
|
358
|
+
await refreshReadme();
|
|
359
|
+
}
|
|
360
|
+
if (needed('plan')) {
|
|
361
|
+
if (within('plan'))
|
|
362
|
+
record = await runStage('plan', () => runImprovePlanStage({
|
|
363
|
+
record, options: parsed, dependencies, price: price.get('plan') ?? 0,
|
|
364
|
+
}));
|
|
365
|
+
if (!record.plan)
|
|
366
|
+
missingStage('plan', parsed.paths.runDir);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
catch (error) {
|
|
370
|
+
// The durable record is the truth here: a stage that failed still wrote
|
|
371
|
+
// down what it abandoned before it threw, and the in-memory copy this
|
|
372
|
+
// function holds predates that.
|
|
373
|
+
record = await readImproveRecord(parsed.paths.record) ?? record;
|
|
374
|
+
const stalledStage = record.convert ? 'plan' : 'convert';
|
|
375
|
+
// A stall closes the record itself, before the recovery files, so a
|
|
376
|
+
// reader never sees a run whose last line is a progress entry. A stage
|
|
377
|
+
// that failed for a reason the journal can already classify — an auth
|
|
378
|
+
// failure, a refusal — keeps that classification: `withRunJournal` ends
|
|
379
|
+
// it on the way out and the throw below is what gets there.
|
|
380
|
+
const stalled = improveStalled(error);
|
|
381
|
+
// The durable record has to say the paid call never came back. `outcome`
|
|
382
|
+
// is the one field a supervisor or a parser reads, and it stayed
|
|
383
|
+
// `dispatched` — which reads as "in flight" long after the run ended (F28).
|
|
384
|
+
const marked = markImproveStageStalled({ record, stage: stalledStage, stalled });
|
|
385
|
+
if (marked !== record) {
|
|
386
|
+
record = marked;
|
|
387
|
+
await writeImproveRecord(parsed.paths.record, record);
|
|
388
|
+
}
|
|
389
|
+
if (stalled) {
|
|
390
|
+
// Everything the record is owed goes in HERE. The session refuses to
|
|
391
|
+
// write after its end line, so the note that used to follow this call
|
|
392
|
+
// was dropped in silence and `improve_<stage>_stalled` never reached a
|
|
393
|
+
// single stalled record.
|
|
394
|
+
await noteImproveTerminalEvent({
|
|
395
|
+
record,
|
|
396
|
+
stage: stalledStage,
|
|
397
|
+
kind: 'stalled',
|
|
398
|
+
error,
|
|
399
|
+
writes: [path.join(parsed.paths.planDir, 'STALL.md'), parsed.paths.readme],
|
|
400
|
+
degradations: [`improve_${stalledStage}_stalled`],
|
|
401
|
+
...(dependencies.journal ? { journal: dependencies.journal } : {}),
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
const stall = await writeImproveStallReport({
|
|
405
|
+
record, stage: stalledStage, error, requestedTo: parsed.to,
|
|
406
|
+
});
|
|
407
|
+
const readme = await refreshReadme();
|
|
408
|
+
// A failure the journal can already classify — an auth failure, a refusal
|
|
409
|
+
// — has an open session still, and `withRunJournal` ends it on the way
|
|
410
|
+
// out; this is the last chance to name what it produced.
|
|
411
|
+
if (!stalled) {
|
|
412
|
+
dependencies.journal?.note({
|
|
413
|
+
workspace: parsed.paths.runDir,
|
|
414
|
+
artifacts: [parsed.paths.record, readme, stall],
|
|
415
|
+
degradations: [`improve_${stalledStage}_stalled`],
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
throw improveStallErrorWithSummary(error, await buildImproveRunSummary({ record, requestedTo: parsed.to }));
|
|
419
|
+
}
|
|
420
|
+
// A run that fell back to fixed layout finished, but something stalled on
|
|
421
|
+
// the way. It gets the same `plan/STALL.md` a dead run gets — written after
|
|
422
|
+
// the plan, so it can say the plan was built from the derivation — and the
|
|
423
|
+
// README, written next, links to it (F8).
|
|
424
|
+
const fallbackStall = await writeImproveFallbackStall({ record, requestedTo: parsed.to });
|
|
425
|
+
// And a run that SETTLED what an earlier one stalled on replaces the file
|
|
426
|
+
// that earlier one left. Freshdesk shipped a settled plan under a README
|
|
427
|
+
// saying "settled" beside a STALL.md saying "INCOMPLETE — no plan"; the
|
|
428
|
+
// reader had no way to tell which was current (F21).
|
|
429
|
+
const resolvedStall = fallbackStall || stopped
|
|
430
|
+
? undefined
|
|
431
|
+
: await resolveImproveStall({
|
|
182
432
|
record,
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
433
|
+
status: await readImproveKitStatus({ record, requestedTo: parsed.to }),
|
|
434
|
+
});
|
|
435
|
+
const stallFile = fallbackStall ?? resolvedStall;
|
|
436
|
+
const readme = await refreshReadme();
|
|
437
|
+
dependencies.journal?.note({
|
|
438
|
+
workspace: parsed.paths.runDir,
|
|
439
|
+
artifacts: [
|
|
440
|
+
parsed.paths.record,
|
|
441
|
+
readme,
|
|
442
|
+
...(stallFile ? [stallFile] : []),
|
|
443
|
+
...(record.plan?.artifacts ?? []),
|
|
444
|
+
],
|
|
445
|
+
purchased: [
|
|
446
|
+
...(record.draft ? [record.draft.runId] : []),
|
|
447
|
+
...(record.convert?.purchaseIds ?? []),
|
|
448
|
+
...(record.sourceConvert?.purchaseIds ?? []),
|
|
449
|
+
],
|
|
450
|
+
terminal: parsed.to === 'plan',
|
|
451
|
+
});
|
|
452
|
+
console.log(JSON.stringify({ from: parsed.from, to: parsed.to, ...record }, null, 2));
|
|
453
|
+
write(await buildImproveRunSummary({ record, requestedTo: parsed.to }));
|
|
454
|
+
return record;
|
|
190
455
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
record = await runStage('plan', () => runImprovePlanStage({
|
|
194
|
-
record, options: parsed, dependencies, price: price.get('plan') ?? 0,
|
|
195
|
-
}));
|
|
196
|
-
if (!record.plan)
|
|
197
|
-
missingStage('plan', parsed.paths.runDir);
|
|
456
|
+
finally {
|
|
457
|
+
disarmStop();
|
|
198
458
|
}
|
|
199
|
-
const readme = await writeImproveReadme(record);
|
|
200
|
-
dependencies.journal?.note({
|
|
201
|
-
workspace: parsed.paths.runDir,
|
|
202
|
-
artifacts: [parsed.paths.record, readme, ...(record.plan?.artifacts ?? [])],
|
|
203
|
-
purchased: [
|
|
204
|
-
...(record.draft ? [record.draft.runId] : []),
|
|
205
|
-
...(record.convert?.purchaseIds ?? []),
|
|
206
|
-
...(record.sourceConvert?.purchaseIds ?? []),
|
|
207
|
-
],
|
|
208
|
-
terminal: parsed.to === 'plan',
|
|
209
|
-
});
|
|
210
|
-
console.log(JSON.stringify({ from: parsed.from, to: parsed.to, ...record }, null, 2));
|
|
211
|
-
return record;
|
|
212
459
|
};
|
|
213
460
|
//# sourceMappingURL=cli-improve-command.js.map
|