@12ui/design 0.2.56 → 0.2.58
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/artifact-materializer.d.ts.map +1 -1
- package/dist/artifact-materializer.js +4 -1
- package/dist/artifact-materializer.js.map +1 -1
- package/dist/branch-client.d.ts +86 -2
- package/dist/branch-client.d.ts.map +1 -1
- package/dist/branch-client.js +31 -0
- package/dist/branch-client.js.map +1 -1
- package/dist/cli-arguments.d.ts.map +1 -1
- package/dist/cli-arguments.js +3 -1
- package/dist/cli-arguments.js.map +1 -1
- package/dist/cli-capabilities.d.ts +1 -1
- package/dist/cli-conversion-derivation.js +2 -2
- package/dist/cli-conversion-derivation.js.map +1 -1
- package/dist/cli-convert-command.d.ts +2 -0
- package/dist/cli-convert-command.d.ts.map +1 -1
- package/dist/cli-convert-command.js +176 -38
- package/dist/cli-convert-command.js.map +1 -1
- package/dist/cli-corpus-command.js +2 -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 +9 -0
- package/dist/cli-draft-command.d.ts.map +1 -1
- package/dist/cli-draft-command.js +26 -1
- package/dist/cli-draft-command.js.map +1 -1
- package/dist/cli-help/design.d.ts +7 -4
- package/dist/cli-help/design.d.ts.map +1 -1
- package/dist/cli-help/design.js +23 -6
- package/dist/cli-help/design.js.map +1 -1
- package/dist/cli-help/index.d.ts +9 -6
- package/dist/cli-help/index.d.ts.map +1 -1
- package/dist/cli-help/meta.d.ts +2 -2
- package/dist/cli-help/meta.d.ts.map +1 -1
- package/dist/cli-help/meta.js +4 -1
- package/dist/cli-help/meta.js.map +1 -1
- package/dist/cli-improve-command.d.ts.map +1 -1
- package/dist/cli-improve-command.js +273 -28
- package/dist/cli-improve-command.js.map +1 -1
- package/dist/cli-redesign-command.d.ts.map +1 -1
- package/dist/cli-redesign-command.js +97 -24
- package/dist/cli-redesign-command.js.map +1 -1
- package/dist/cli-run.d.ts.map +1 -1
- package/dist/cli-run.js +13 -3
- package/dist/cli-run.js.map +1 -1
- package/dist/cli-spend-command.d.ts +12 -1
- package/dist/cli-spend-command.d.ts.map +1 -1
- package/dist/cli-spend-command.js +94 -2
- package/dist/cli-spend-command.js.map +1 -1
- package/dist/cli-usage.js +5 -5
- package/dist/cli-usage.js.map +1 -1
- package/dist/concept-input.d.ts +6 -56
- package/dist/concept-input.d.ts.map +1 -1
- package/dist/concept-input.js +6 -65
- package/dist/concept-input.js.map +1 -1
- package/dist/conversion-client.d.ts +92 -3
- package/dist/conversion-client.d.ts.map +1 -1
- package/dist/conversion-client.js +317 -23
- 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 +3 -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 +15 -0
- package/dist/draft-run.d.ts.map +1 -1
- package/dist/draft-run.js +32 -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 +9 -0
- package/dist/hosted-draft-identity.d.ts.map +1 -1
- package/dist/hosted-draft-identity.js +2 -0
- package/dist/hosted-draft-identity.js.map +1 -1
- package/dist/improve-added-specs.d.ts +12 -31
- package/dist/improve-added-specs.d.ts.map +1 -1
- package/dist/improve-added-specs.js +64 -152
- package/dist/improve-added-specs.js.map +1 -1
- package/dist/improve-artifact-writer.d.ts +13 -0
- package/dist/improve-artifact-writer.d.ts.map +1 -0
- package/dist/improve-artifact-writer.js +27 -0
- package/dist/improve-artifact-writer.js.map +1 -0
- package/dist/improve-bootstrap-history.d.ts +21 -0
- package/dist/improve-bootstrap-history.d.ts.map +1 -0
- package/dist/improve-bootstrap-history.js +43 -0
- package/dist/improve-bootstrap-history.js.map +1 -0
- 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-branch-stage.d.ts +10 -0
- package/dist/improve-branch-stage.d.ts.map +1 -0
- package/dist/improve-branch-stage.js +325 -0
- package/dist/improve-branch-stage.js.map +1 -0
- package/dist/improve-capture-redirect.d.ts +65 -0
- package/dist/improve-capture-redirect.d.ts.map +1 -0
- package/dist/improve-capture-redirect.js +85 -0
- package/dist/improve-capture-redirect.js.map +1 -0
- package/dist/improve-capture-words.d.ts +43 -0
- package/dist/improve-capture-words.d.ts.map +1 -0
- package/dist/improve-capture-words.js +25 -0
- package/dist/improve-capture-words.js.map +1 -0
- package/dist/improve-concept.d.ts +6 -7
- package/dist/improve-concept.d.ts.map +1 -1
- package/dist/improve-concept.js +12 -38
- package/dist/improve-concept.js.map +1 -1
- package/dist/improve-conversion-attempts.d.ts +21 -9
- package/dist/improve-conversion-attempts.d.ts.map +1 -1
- package/dist/improve-conversion-attempts.js +6 -1
- package/dist/improve-conversion-attempts.js.map +1 -1
- package/dist/improve-conversion-stage.d.ts +20 -2
- package/dist/improve-conversion-stage.d.ts.map +1 -1
- package/dist/improve-conversion-stage.js +386 -178
- package/dist/improve-conversion-stage.js.map +1 -1
- package/dist/improve-convert-progress.d.ts +44 -0
- package/dist/improve-convert-progress.d.ts.map +1 -0
- package/dist/improve-convert-progress.js +47 -0
- package/dist/improve-convert-progress.js.map +1 -0
- package/dist/improve-convert-resilience.d.ts +96 -58
- package/dist/improve-convert-resilience.d.ts.map +1 -1
- package/dist/improve-convert-resilience.js +128 -72
- package/dist/improve-convert-resilience.js.map +1 -1
- package/dist/improve-core/concept-input.d.ts +80 -0
- package/dist/improve-core/concept-input.d.ts.map +1 -0
- package/dist/improve-core/concept-input.js +92 -0
- package/dist/improve-core/concept-input.js.map +1 -0
- package/dist/improve-core/improve-added-specs.d.ts +62 -0
- package/dist/improve-core/improve-added-specs.d.ts.map +1 -0
- package/dist/improve-core/improve-added-specs.js +160 -0
- package/dist/improve-core/improve-added-specs.js.map +1 -0
- package/dist/improve-core/improve-artifacts.d.ts +18 -0
- package/dist/improve-core/improve-artifacts.d.ts.map +1 -0
- package/dist/improve-core/improve-artifacts.js +4 -0
- package/dist/improve-core/improve-artifacts.js.map +1 -0
- package/dist/improve-core/improve-concept.d.ts +7 -0
- package/dist/improve-core/improve-concept.d.ts.map +1 -0
- package/dist/improve-core/improve-concept.js +185 -0
- package/dist/improve-core/improve-concept.js.map +1 -0
- package/dist/improve-core/improve-discovery.d.ts +84 -0
- package/dist/improve-core/improve-discovery.d.ts.map +1 -0
- package/dist/improve-core/improve-discovery.js +154 -0
- package/dist/improve-core/improve-discovery.js.map +1 -0
- package/dist/improve-core/improve-dom-anchor.d.ts.map +1 -0
- package/dist/{improve-dom-anchor.js → improve-core/improve-dom-anchor.js} +2 -0
- package/dist/improve-core/improve-dom-anchor.js.map +1 -0
- package/dist/improve-core/improve-dom-diff.d.ts +59 -0
- package/dist/improve-core/improve-dom-diff.d.ts.map +1 -0
- package/dist/improve-core/improve-dom-diff.js +151 -0
- package/dist/improve-core/improve-dom-diff.js.map +1 -0
- package/dist/improve-core/improve-dom-extract.d.ts.map +1 -0
- package/dist/{improve-dom-extract.js → improve-core/improve-dom-extract.js} +2 -0
- package/dist/improve-core/improve-dom-extract.js.map +1 -0
- package/dist/improve-core/improve-dom-gate.d.ts +49 -0
- package/dist/improve-core/improve-dom-gate.d.ts.map +1 -0
- package/dist/improve-core/improve-dom-gate.js +99 -0
- package/dist/improve-core/improve-dom-gate.js.map +1 -0
- package/dist/improve-core/improve-dom-neighbour.d.ts.map +1 -0
- package/dist/{improve-dom-neighbour.js → improve-core/improve-dom-neighbour.js} +2 -0
- package/dist/improve-core/improve-dom-neighbour.js.map +1 -0
- package/dist/improve-core/improve-dom-scale.d.ts.map +1 -0
- package/dist/{improve-dom-scale.js → improve-core/improve-dom-scale.js} +2 -0
- package/dist/improve-core/improve-dom-scale.js.map +1 -0
- package/dist/improve-core/improve-icon-svg.d.ts +29 -0
- package/dist/improve-core/improve-icon-svg.d.ts.map +1 -0
- package/dist/improve-core/improve-icon-svg.js +85 -0
- package/dist/improve-core/improve-icon-svg.js.map +1 -0
- package/dist/improve-core/improve-kit-asset-model.d.ts +177 -0
- package/dist/improve-core/improve-kit-asset-model.d.ts.map +1 -0
- package/dist/improve-core/improve-kit-asset-model.js +269 -0
- package/dist/improve-core/improve-kit-asset-model.js.map +1 -0
- package/dist/improve-core/improve-layerdoc-diff.d.ts.map +1 -0
- package/dist/{improve-layerdoc-diff.js → improve-core/improve-layerdoc-diff.js} +2 -0
- package/dist/improve-core/improve-layerdoc-diff.js.map +1 -0
- package/dist/{improve-layerdoc-types.d.ts → improve-core/improve-layerdoc-types.d.ts} +9 -0
- package/dist/improve-core/improve-layerdoc-types.d.ts.map +1 -0
- package/dist/improve-core/improve-layerdoc-types.js +4 -0
- package/dist/improve-core/improve-layerdoc-types.js.map +1 -0
- package/dist/improve-core/improve-page-words.d.ts +180 -0
- package/dist/improve-core/improve-page-words.d.ts.map +1 -0
- package/dist/improve-core/improve-page-words.js +303 -0
- package/dist/improve-core/improve-page-words.js.map +1 -0
- package/dist/{improve-plan-annotated-render.d.ts → improve-core/improve-plan-annotated-render.d.ts} +19 -2
- package/dist/improve-core/improve-plan-annotated-render.d.ts.map +1 -0
- package/dist/{improve-plan-annotated-render.js → improve-core/improve-plan-annotated-render.js} +77 -28
- package/dist/improve-core/improve-plan-annotated-render.js.map +1 -0
- package/dist/improve-core/improve-plan-annotator.d.ts +34 -0
- package/dist/improve-core/improve-plan-annotator.d.ts.map +1 -0
- package/dist/improve-core/improve-plan-annotator.js +52 -0
- package/dist/improve-core/improve-plan-annotator.js.map +1 -0
- package/dist/{improve-plan-render.d.ts → improve-core/improve-plan-render.d.ts} +2 -1
- package/dist/improve-core/improve-plan-render.d.ts.map +1 -0
- package/dist/{improve-plan-render.js → improve-core/improve-plan-render.js} +7 -1
- package/dist/improve-core/improve-plan-render.js.map +1 -0
- package/dist/improve-core/improve-plan-vector-keep.d.ts +29 -0
- package/dist/improve-core/improve-plan-vector-keep.d.ts.map +1 -0
- package/dist/improve-core/improve-plan-vector-keep.js +68 -0
- package/dist/improve-core/improve-plan-vector-keep.js.map +1 -0
- package/dist/{improve-raster-layers-section.d.ts → improve-core/improve-raster-layers-section.d.ts} +9 -1
- package/dist/improve-core/improve-raster-layers-section.d.ts.map +1 -0
- package/dist/{improve-raster-layers-section.js → improve-core/improve-raster-layers-section.js} +5 -2
- package/dist/improve-core/improve-raster-layers-section.js.map +1 -0
- package/dist/improve-core/improve-refusal.d.ts +6 -0
- package/dist/improve-core/improve-refusal.d.ts.map +1 -0
- package/dist/improve-core/improve-refusal.js +27 -0
- package/dist/improve-core/improve-refusal.js.map +1 -0
- package/dist/improve-core/improve-retain.d.ts +121 -0
- package/dist/improve-core/improve-retain.d.ts.map +1 -0
- package/dist/improve-core/improve-retain.js +115 -0
- package/dist/improve-core/improve-retain.js.map +1 -0
- package/dist/improve-core/improve-site-plan.d.ts +75 -0
- package/dist/improve-core/improve-site-plan.d.ts.map +1 -0
- package/dist/improve-core/improve-site-plan.js +135 -0
- package/dist/improve-core/improve-site-plan.js.map +1 -0
- package/dist/improve-core/improve-site-shell.d.ts +56 -0
- package/dist/improve-core/improve-site-shell.d.ts.map +1 -0
- package/dist/improve-core/improve-site-shell.js +152 -0
- package/dist/improve-core/improve-site-shell.js.map +1 -0
- package/dist/improve-core/improve-site-tokens.d.ts +44 -0
- package/dist/improve-core/improve-site-tokens.d.ts.map +1 -0
- package/dist/improve-core/improve-site-tokens.js +87 -0
- package/dist/improve-core/improve-site-tokens.js.map +1 -0
- package/dist/improve-core/improve-source-hints.d.ts +25 -0
- package/dist/improve-core/improve-source-hints.d.ts.map +1 -0
- package/dist/improve-core/improve-source-hints.js +17 -0
- package/dist/improve-core/improve-source-hints.js.map +1 -0
- package/dist/{improve-token-patch.d.ts → improve-core/improve-token-patch.d.ts} +2 -0
- package/dist/improve-core/improve-token-patch.d.ts.map +1 -0
- package/dist/{improve-token-patch.js → improve-core/improve-token-patch.js} +25 -5
- package/dist/improve-core/improve-token-patch.js.map +1 -0
- package/dist/improve-core/index.d.ts +47 -0
- package/dist/improve-core/index.d.ts.map +1 -0
- package/dist/improve-core/index.js +49 -0
- package/dist/improve-core/index.js.map +1 -0
- package/dist/improve-delivery-stages.d.ts +6 -0
- package/dist/improve-delivery-stages.d.ts.map +1 -1
- package/dist/improve-delivery-stages.js +91 -6
- package/dist/improve-delivery-stages.js.map +1 -1
- package/dist/improve-dom-diff.d.ts +8 -24
- package/dist/improve-dom-diff.d.ts.map +1 -1
- package/dist/improve-dom-diff.js +23 -123
- package/dist/improve-dom-diff.js.map +1 -1
- package/dist/improve-dom-gate.d.ts +1 -18
- package/dist/improve-dom-gate.d.ts.map +1 -1
- package/dist/improve-dom-gate.js +1 -46
- package/dist/improve-dom-gate.js.map +1 -1
- package/dist/improve-generation-stages.d.ts +0 -2
- package/dist/improve-generation-stages.d.ts.map +1 -1
- package/dist/improve-generation-stages.js +191 -15
- package/dist/improve-generation-stages.js.map +1 -1
- package/dist/improve-kit-assets.d.ts +8 -116
- package/dist/improve-kit-assets.d.ts.map +1 -1
- package/dist/improve-kit-assets.js +9 -229
- package/dist/improve-kit-assets.js.map +1 -1
- 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 +4 -0
- package/dist/improve-kit-readme.d.ts.map +1 -1
- package/dist/improve-kit-readme.js +155 -24
- package/dist/improve-kit-readme.js.map +1 -1
- package/dist/improve-kit-stall.d.ts +51 -3
- package/dist/improve-kit-stall.d.ts.map +1 -1
- package/dist/improve-kit-stall.js +205 -21
- package/dist/improve-kit-stall.js.map +1 -1
- package/dist/improve-kit-status.d.ts +36 -0
- package/dist/improve-kit-status.d.ts.map +1 -1
- package/dist/improve-kit-status.js +82 -7
- package/dist/improve-kit-status.js.map +1 -1
- package/dist/improve-options.d.ts +14 -0
- package/dist/improve-options.d.ts.map +1 -1
- package/dist/improve-options.js +95 -12
- package/dist/improve-options.js.map +1 -1
- package/dist/improve-passthrough-flags.d.ts +8 -0
- package/dist/improve-passthrough-flags.d.ts.map +1 -0
- package/dist/improve-passthrough-flags.js +11 -0
- package/dist/improve-passthrough-flags.js.map +1 -0
- package/dist/improve-plan-annotator.d.ts +13 -2
- package/dist/improve-plan-annotator.d.ts.map +1 -1
- package/dist/improve-plan-annotator.js +35 -37
- package/dist/improve-plan-annotator.js.map +1 -1
- package/dist/improve-pricing-plan.d.ts +3 -0
- package/dist/improve-pricing-plan.d.ts.map +1 -1
- package/dist/improve-pricing-plan.js +33 -5
- package/dist/improve-pricing-plan.js.map +1 -1
- package/dist/improve-recheck.d.ts +9 -0
- package/dist/improve-recheck.d.ts.map +1 -0
- package/dist/improve-recheck.js +200 -0
- package/dist/improve-recheck.js.map +1 -0
- package/dist/improve-reset.d.ts.map +1 -1
- package/dist/improve-reset.js +11 -0
- package/dist/improve-reset.js.map +1 -1
- package/dist/improve-run-summary.d.ts +6 -0
- package/dist/improve-run-summary.d.ts.map +1 -1
- package/dist/improve-run-summary.js +77 -7
- package/dist/improve-run-summary.js.map +1 -1
- package/dist/improve-site-plan.d.ts +57 -0
- package/dist/improve-site-plan.d.ts.map +1 -0
- package/dist/improve-site-plan.js +79 -0
- package/dist/improve-site-plan.js.map +1 -0
- package/dist/improve-site-shell.d.ts +11 -0
- package/dist/improve-site-shell.d.ts.map +1 -0
- package/dist/improve-site-shell.js +24 -0
- package/dist/improve-site-shell.js.map +1 -0
- package/dist/improve-site-stage.d.ts +10 -0
- package/dist/improve-site-stage.d.ts.map +1 -0
- package/dist/improve-site-stage.js +84 -0
- package/dist/improve-site-stage.js.map +1 -0
- package/dist/improve-site-tokens.d.ts +9 -0
- package/dist/improve-site-tokens.d.ts.map +1 -0
- package/dist/improve-site-tokens.js +17 -0
- package/dist/improve-site-tokens.js.map +1 -0
- package/dist/improve-source-hints.d.ts +3 -12
- package/dist/improve-source-hints.d.ts.map +1 -1
- package/dist/improve-source-hints.js +4 -5
- package/dist/improve-source-hints.js.map +1 -1
- package/dist/improve-spend-ledger.d.ts +69 -0
- package/dist/improve-spend-ledger.d.ts.map +1 -0
- package/dist/improve-spend-ledger.js +118 -0
- package/dist/improve-spend-ledger.js.map +1 -0
- package/dist/improve-stage-runners.d.ts +5 -2
- package/dist/improve-stage-runners.d.ts.map +1 -1
- package/dist/improve-stage-runners.js +5 -2
- package/dist/improve-stage-runners.js.map +1 -1
- package/dist/improve-stage-shared.d.ts +49 -2
- 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 +15 -0
- package/dist/improve-stop-handler.d.ts.map +1 -1
- package/dist/improve-stop-handler.js +74 -3
- package/dist/improve-stop-handler.js.map +1 -1
- package/dist/improve-terminal-event.d.ts.map +1 -1
- package/dist/improve-terminal-event.js +13 -4
- package/dist/improve-terminal-event.js.map +1 -1
- package/dist/improve-workspace.d.ts +282 -9
- package/dist/improve-workspace.d.ts.map +1 -1
- package/dist/improve-workspace.js +250 -78
- 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 +202 -0
- package/dist/legacy-skill-catalog.js.map +1 -1
- package/dist/mcp-convert.js +1 -1
- package/dist/mcp-convert.js.map +1 -1
- package/dist/redesign-capture.d.ts +146 -15
- package/dist/redesign-capture.d.ts.map +1 -1
- package/dist/redesign-capture.js +182 -65
- package/dist/redesign-capture.js.map +1 -1
- package/dist/redesign-workspace.d.ts +13 -0
- package/dist/redesign-workspace.d.ts.map +1 -1
- package/dist/redesign-workspace.js +14 -0
- package/dist/redesign-workspace.js.map +1 -1
- package/dist/responsive-alternative-materializer.d.ts +24 -0
- package/dist/responsive-alternative-materializer.d.ts.map +1 -0
- package/dist/responsive-alternative-materializer.js +93 -0
- package/dist/responsive-alternative-materializer.js.map +1 -0
- package/dist/result-integrity.d.ts +38 -0
- package/dist/result-integrity.d.ts.map +1 -0
- package/dist/result-integrity.js +46 -0
- package/dist/result-integrity.js.map +1 -0
- package/dist/review-edit-source.d.ts.map +1 -1
- package/dist/review-edit-source.js +6 -2
- package/dist/review-edit-source.js.map +1 -1
- package/dist/review-edit.js +2 -2
- package/dist/review-edit.js.map +1 -1
- package/dist/review-prototype-gap.js +1 -1
- package/dist/review-prototype-gap.js.map +1 -1
- package/dist/spend-run-filter.d.ts +21 -0
- package/dist/spend-run-filter.d.ts.map +1 -0
- package/dist/spend-run-filter.js +65 -0
- package/dist/spend-run-filter.js.map +1 -0
- package/dist/spend-scoped-report-lines.d.ts +4 -0
- package/dist/spend-scoped-report-lines.d.ts.map +1 -0
- package/dist/spend-scoped-report-lines.js +46 -0
- package/dist/spend-scoped-report-lines.js.map +1 -0
- package/dist/spend-scoped-report.d.ts +28 -0
- package/dist/spend-scoped-report.d.ts.map +1 -0
- package/dist/spend-scoped-report.js +45 -0
- package/dist/spend-scoped-report.js.map +1 -0
- package/open-design.json +2 -2
- package/package.json +5 -5
- package/skills/12ui-design/SKILL.md +14 -4
- package/skills/12ui-design/improve.md +67 -5
- package/skills/12ui-design/inspire.md +1 -1
- package/dist/improve-dom-anchor.d.ts.map +0 -1
- package/dist/improve-dom-anchor.js.map +0 -1
- package/dist/improve-dom-extract.d.ts.map +0 -1
- package/dist/improve-dom-extract.js.map +0 -1
- package/dist/improve-dom-neighbour.d.ts.map +0 -1
- package/dist/improve-dom-neighbour.js.map +0 -1
- package/dist/improve-dom-scale.d.ts.map +0 -1
- package/dist/improve-dom-scale.js.map +0 -1
- package/dist/improve-layerdoc-diff.d.ts.map +0 -1
- package/dist/improve-layerdoc-diff.js.map +0 -1
- package/dist/improve-layerdoc-types.d.ts.map +0 -1
- package/dist/improve-layerdoc-types.js +0 -2
- package/dist/improve-layerdoc-types.js.map +0 -1
- package/dist/improve-plan-annotated-render.d.ts.map +0 -1
- package/dist/improve-plan-annotated-render.js.map +0 -1
- package/dist/improve-plan-render.d.ts.map +0 -1
- package/dist/improve-plan-render.js.map +0 -1
- package/dist/improve-raster-layers-section.d.ts.map +0 -1
- package/dist/improve-raster-layers-section.js.map +0 -1
- package/dist/improve-token-patch.d.ts.map +0 -1
- package/dist/improve-token-patch.js.map +0 -1
- /package/dist/{improve-dom-anchor.d.ts → improve-core/improve-dom-anchor.d.ts} +0 -0
- /package/dist/{improve-dom-extract.d.ts → improve-core/improve-dom-extract.d.ts} +0 -0
- /package/dist/{improve-dom-neighbour.d.ts → improve-core/improve-dom-neighbour.d.ts} +0 -0
- /package/dist/{improve-dom-scale.d.ts → improve-core/improve-dom-scale.d.ts} +0 -0
- /package/dist/{improve-layerdoc-diff.d.ts → improve-core/improve-layerdoc-diff.d.ts} +0 -0
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { copyFile, cp, readFile, stat } from 'node:fs/promises';
|
|
2
2
|
import sharp from 'sharp';
|
|
3
3
|
import { runConversionCommand } from './cli-convert-command.js';
|
|
4
|
+
import { formatDuration } from './cli-progress.js';
|
|
5
|
+
import { createImproveConvertProgress, } from './improve-convert-progress.js';
|
|
4
6
|
import { CliRefusal } from './cli-refusal.js';
|
|
5
7
|
import { prepareOutputDirectory } from './cli-output-paths.js';
|
|
6
|
-
import { fixedImproveHtml, improveConversionIdFromText, improveConvertRetryKey, improveConvertStallCount,
|
|
8
|
+
import { fixedImproveHtml, improveConversionIdFromText, improveConvertRetryKey, improveConvertStallCount, improveConvertStallHalted, improveErrorText, improveStalled, IMPROVE_FRESH_ABANDON_REASON, prepareImproveTargetAttempt, responsiveFallbackReason, } from './improve-convert-resilience.js';
|
|
9
|
+
import { createConcurrencyLimiter } from './bounded-concurrency.js';
|
|
7
10
|
import { improveFreshConversionKey, noteImproveConversionAttemptId, openImproveConversionAttempt, settleImproveConversionAttempt, startImproveConversionAttempt, } from './improve-conversion-attempts.js';
|
|
8
|
-
import { canvasOfDoc } from './improve-
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
11
|
+
import { canvasOfDoc } from './improve-core/index.js';
|
|
12
|
+
import { trackImproveDurableWrite } from './improve-stop-handler.js';
|
|
13
|
+
import { abandonImproveConversion, noteAbandonedAttempts, withoutImproveStages, } from './improve-reset.js';
|
|
14
|
+
import { improveSha256, noteImproveStage, noteImproveStageDispatched, } from './improve-stage-shared.js';
|
|
15
|
+
import { improvePagePaths, readImproveRecord, writeImproveRecord, } from './improve-workspace.js';
|
|
12
16
|
export const runImproveConversion = async (args) => {
|
|
13
17
|
const artifacts = [];
|
|
14
18
|
const purchaseIds = [];
|
|
@@ -18,25 +22,33 @@ export const runImproveConversion = async (args) => {
|
|
|
18
22
|
artifacts.push(...(facts.artifacts ?? []));
|
|
19
23
|
purchaseIds.push(...(facts.purchased ?? []));
|
|
20
24
|
if (facts.runId) {
|
|
21
|
-
if (!runIds.includes(facts.runId))
|
|
25
|
+
if (!runIds.includes(facts.runId)) {
|
|
22
26
|
args.onConversionId?.(facts.runId);
|
|
27
|
+
args.progress?.noteConversionId(facts.runId);
|
|
28
|
+
}
|
|
23
29
|
runIds.push(facts.runId);
|
|
24
30
|
}
|
|
25
31
|
args.journal?.note(facts);
|
|
26
32
|
},
|
|
27
|
-
heartbeat: (progress) => {
|
|
33
|
+
heartbeat: (progress) => {
|
|
34
|
+
args.journal?.heartbeat(progress);
|
|
35
|
+
args.progress?.heartbeat(progress);
|
|
36
|
+
},
|
|
28
37
|
};
|
|
29
38
|
const flags = {
|
|
39
|
+
...args.passthrough,
|
|
30
40
|
output: args.output,
|
|
31
41
|
...(args.model ? { model: args.model } : {}),
|
|
32
42
|
...(args.responsiveQuality ? { 'responsive-quality': args.responsiveQuality } : {}),
|
|
33
|
-
...(args.timeoutMs === undefined ? {} : { 'timeout-ms': String(args.timeoutMs) }),
|
|
34
43
|
'out-dir': args.outDir,
|
|
35
44
|
'idempotency-key': args.key,
|
|
36
45
|
quiet: true,
|
|
37
46
|
};
|
|
38
47
|
try {
|
|
39
|
-
await args.runner(['convert', args.input], flags, collector, {
|
|
48
|
+
await args.runner(['convert', args.input], flags, collector, {
|
|
49
|
+
writeResult: () => undefined,
|
|
50
|
+
...(args.stallTimeoutMs === undefined ? {} : { stallTimeoutMs: args.stallTimeoutMs }),
|
|
51
|
+
});
|
|
40
52
|
}
|
|
41
53
|
catch (error) {
|
|
42
54
|
throw new ImproveConvertAttemptError(error, {
|
|
@@ -71,7 +83,7 @@ const recordFreshConversion = async (args) => {
|
|
|
71
83
|
reason: IMPROVE_FRESH_ABANDON_REASON,
|
|
72
84
|
warn: args.dependencies.warn ?? ((line) => { console.warn(line); }),
|
|
73
85
|
});
|
|
74
|
-
const record = withoutImproveStages(abandoned.record, ['convert', 'plan']);
|
|
86
|
+
const record = withoutImproveStages(abandoned.record, ['convert', 'plan', 'site']);
|
|
75
87
|
await writeImproveRecord(args.options.paths.record, record);
|
|
76
88
|
return record;
|
|
77
89
|
};
|
|
@@ -129,14 +141,14 @@ export const runImproveConvertStage = async (args) => {
|
|
|
129
141
|
throw new Error('Improve has no design image to convert');
|
|
130
142
|
const targetIdentity = improveSha256(Buffer.from(`${inputSha}:${args.record.conversionModel}:${args.options.responsiveQuality}`)).slice(0, 32);
|
|
131
143
|
const baseKey = `improve-target:v2:${targetIdentity}`;
|
|
132
|
-
// How many conversions of this winner
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
//
|
|
137
|
-
//
|
|
138
|
-
|
|
139
|
-
|
|
144
|
+
// How many conversions of this winner a PRE-F19 kit bought and abandoned to a
|
|
145
|
+
// stall, and which of them to wait on now. A resume re-attaches to the NEWEST
|
|
146
|
+
// one — it is bought, it is still running, and it is the only way to get
|
|
147
|
+
// anything back for it — instead of rebuilding the base key and waiting out
|
|
148
|
+
// the whole bound on the first, oldest conversion. Nothing adds to this count
|
|
149
|
+
// any more; a stall no longer abandons anything.
|
|
150
|
+
const bought = args.options.fresh ? 0 : improveConvertStallCount(recordBeforeConvert);
|
|
151
|
+
const index = Math.max(1, bought);
|
|
140
152
|
// WHICH CONVERSION THIS INVOCATION IS ABOUT TO WAIT ON. The attempt ledger
|
|
141
153
|
// decides, because it holds the exact key: a `--fresh` or retry attempt that
|
|
142
154
|
// was stopped mid-flight is reachable only through the key it was dispatched
|
|
@@ -147,13 +159,15 @@ export const runImproveConvertStage = async (args) => {
|
|
|
147
159
|
// kits written before the ledger.
|
|
148
160
|
//
|
|
149
161
|
// Only an attempt minted for THIS winner counts: every recorded key is the
|
|
150
|
-
// base key plus a suffix, so the prefix is what says
|
|
151
|
-
// is of the design this run is converting. A redraw
|
|
152
|
-
// closes its attempts (`abandonImproveConversions`);
|
|
153
|
-
// on that door, because re-attaching to a conversion
|
|
154
|
-
// would deliver the wrong page and read as a replay.
|
|
162
|
+
// base key itself or the base key plus a suffix, so the prefix is what says
|
|
163
|
+
// the conversion behind it is of the design this run is converting. A redraw
|
|
164
|
+
// or a re-pick already closes its attempts (`abandonImproveConversions`);
|
|
165
|
+
// this is the second lock on that door, because re-attaching to a conversion
|
|
166
|
+
// of a discarded design would deliver the wrong page and read as a replay.
|
|
155
167
|
const open = args.options.fresh ? undefined : openImproveConversionAttempt(recordBeforeConvert);
|
|
156
|
-
const resumed = open
|
|
168
|
+
const resumed = open && (open.key === baseKey || open.key.startsWith(`${baseKey}:`))
|
|
169
|
+
? open
|
|
170
|
+
: undefined;
|
|
157
171
|
const nonce = args.freshConversionNonce;
|
|
158
172
|
if (args.options.fresh && !nonce) {
|
|
159
173
|
throw new Error('improve --fresh needs a per-invocation conversion nonce, so the conversion it dispatches'
|
|
@@ -162,9 +176,9 @@ export const runImproveConvertStage = async (args) => {
|
|
|
162
176
|
const key = args.options.fresh && nonce
|
|
163
177
|
? improveFreshConversionKey(baseKey, nonce)
|
|
164
178
|
: resumed?.key ?? (index === 1 ? baseKey : improveConvertRetryKey(baseKey, index));
|
|
165
|
-
// The transaction is taken ONCE
|
|
166
|
-
//
|
|
167
|
-
//
|
|
179
|
+
// The transaction is taken ONCE: a second `prepareImproveTargetAttempt`
|
|
180
|
+
// while the first backup exists would delete the previous good target
|
|
181
|
+
// instead of preserving it.
|
|
168
182
|
const transaction = await prepareImproveTargetAttempt(args.options.paths.targetDir);
|
|
169
183
|
const warn = args.dependencies.warn ?? ((line) => { console.warn(line); });
|
|
170
184
|
try {
|
|
@@ -174,6 +188,14 @@ export const runImproveConvertStage = async (args) => {
|
|
|
174
188
|
// the ordinary base-key path writes nothing extra. The writes are chained
|
|
175
189
|
// and drained before the stage writes the record itself: a stamp landing
|
|
176
190
|
// after the settled record would write a record that has no convert block.
|
|
191
|
+
//
|
|
192
|
+
// The id arrives on a callback that cannot be awaited, so the write is the
|
|
193
|
+
// one durable fact of this stage that is NOT on disk before it is needed.
|
|
194
|
+
// Both ends of the stage therefore drain it — the ordinary end below, and
|
|
195
|
+
// the signal path, which is why each link is also handed to
|
|
196
|
+
// `trackImproveDurableWrite`. A SIGTERM used to exit with this write still
|
|
197
|
+
// in flight, leaving a kit that had paid for a conversion, was still being
|
|
198
|
+
// billed for it, and could not name it.
|
|
177
199
|
let pendingLedgerWrite = Promise.resolve();
|
|
178
200
|
const rememberConversionId = (attemptKey, id) => {
|
|
179
201
|
const noted = noteImproveConversionAttemptId(recordBeforeConvert, {
|
|
@@ -189,165 +211,171 @@ export const runImproveConvertStage = async (args) => {
|
|
|
189
211
|
warn(`[ledger] convert: could not record conversion ${id} against its key:`
|
|
190
212
|
+ ` ${improveErrorText(error)}`);
|
|
191
213
|
});
|
|
214
|
+
trackImproveDurableWrite(pendingLedgerWrite);
|
|
192
215
|
};
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
?? improveConversionIdFromText(improveErrorText(error));
|
|
211
|
-
const layerDocPresent = (await stat(args.options.paths.targetLayerDoc).catch(() => undefined))?.isFile();
|
|
212
|
-
const assetsPresent = (await stat(`${args.options.paths.targetLayerDoc}.assets`).catch(() => undefined))?.isDirectory();
|
|
213
|
-
if (!warning || !sourceConversionId || !layerDocPresent || !assetsPresent)
|
|
214
|
-
throw error;
|
|
215
|
-
(args.dependencies.warn ?? console.warn)(`Responsive HTML was unavailable; deriving fixed-layout HTML free from ${sourceConversionId}`);
|
|
216
|
-
// The derivation is free, not unbounded. Passing no timeout dropped it
|
|
217
|
-
// through to waitForOperation's twenty-minute default while the docs
|
|
218
|
-
// promised `--convert-stall-seconds` bounds the conversion wait, so a
|
|
219
|
-
// wedged derivation hung the run for twenty minutes with no STALL.md —
|
|
220
|
-
// the pipedrive shape, on the one path the reader was told was bounded.
|
|
221
|
-
const fixed = await runImproveConversion({
|
|
222
|
-
input: sourceConversionId,
|
|
216
|
+
const bound = args.options.convertStallSeconds;
|
|
217
|
+
// Progress goes where every other 12ui progress stream goes — stderr, via
|
|
218
|
+
// the same channel the fallback line uses — so stdout stays the record.
|
|
219
|
+
const tick = args.dependencies.warn ?? ((line) => { console.warn(line); });
|
|
220
|
+
const attemptConversion = async (attemptKey) => {
|
|
221
|
+
// The wait a lane actually sits through, ticked once a minute so the
|
|
222
|
+
// terminal never goes silent (F8). The client applies `bound` only to a
|
|
223
|
+
// stretch with no newly observed live stage or active lane; a healthy
|
|
224
|
+
// tall conversion remains attached to this exact idempotent purchase.
|
|
225
|
+
const startedAt = Date.now();
|
|
226
|
+
const progress = createImproveConvertProgress({
|
|
227
|
+
label: 'responsive export',
|
|
228
|
+
boundSeconds: bound,
|
|
229
|
+
write: tick,
|
|
230
|
+
});
|
|
231
|
+
return runImproveConversion({
|
|
232
|
+
input,
|
|
223
233
|
outDir: args.options.paths.targetDir,
|
|
224
|
-
output: '
|
|
225
|
-
|
|
226
|
-
|
|
234
|
+
output: 'html',
|
|
235
|
+
model: args.record.conversionModel,
|
|
236
|
+
responsiveQuality: args.options.responsiveQuality,
|
|
237
|
+
stallTimeoutMs: args.options.convertStallSeconds * 1_000,
|
|
238
|
+
key: attemptKey,
|
|
239
|
+
passthrough: args.options.passthrough,
|
|
227
240
|
runner: args.dependencies.runConvert ?? runConversionCommand,
|
|
228
241
|
journal: args.dependencies.journal,
|
|
242
|
+
onConversionId: (id) => { rememberConversionId(attemptKey, id); },
|
|
243
|
+
progress,
|
|
244
|
+
}).catch(async (error) => {
|
|
245
|
+
const attempt = error instanceof ImproveConvertAttemptError
|
|
246
|
+
? error.attempt
|
|
247
|
+
: { artifacts: [], purchaseIds: [], runIds: [] };
|
|
248
|
+
// The stage the SERVICE declared decides the sentence, not the shape of
|
|
249
|
+
// the error text (F34).
|
|
250
|
+
const fallbackReason = responsiveFallbackReason(error, {
|
|
251
|
+
...(progress.serviceStage() ? { serviceStage: progress.serviceStage() } : {}),
|
|
252
|
+
});
|
|
253
|
+
const sourceConversionId = attempt.runIds[0]
|
|
254
|
+
?? improveConversionIdFromText(improveErrorText(error));
|
|
255
|
+
const layerDocPresent = (await stat(args.options.paths.targetLayerDoc).catch(() => undefined))?.isFile();
|
|
256
|
+
const assetsPresent = (await stat(`${args.options.paths.targetLayerDoc}.assets`).catch(() => undefined))?.isDirectory();
|
|
257
|
+
if (!fallbackReason || !sourceConversionId || !layerDocPresent || !assetsPresent)
|
|
258
|
+
throw error;
|
|
259
|
+
const waitedSeconds = Math.round(progress.waitedSeconds() ?? (Date.now() - startedAt) / 1_000);
|
|
260
|
+
(args.dependencies.warn ?? console.warn)(`${fallbackReason.warning} After ${formatDuration(waitedSeconds)}`
|
|
261
|
+
+ ` (bound ${formatDuration(bound)});`
|
|
262
|
+
+ ` deriving fixed-layout HTML free from ${sourceConversionId}`);
|
|
263
|
+
// The derivation is free, but it still stops after the same period
|
|
264
|
+
// without a newly observed live service fact. It therefore cannot
|
|
265
|
+
// quietly use the conversion client's generic twenty-minute wall.
|
|
266
|
+
const fixed = await runImproveConversion({
|
|
267
|
+
input: sourceConversionId,
|
|
268
|
+
outDir: args.options.paths.targetDir,
|
|
269
|
+
output: 'html_fixed',
|
|
270
|
+
stallTimeoutMs: args.options.convertStallSeconds * 1_000,
|
|
271
|
+
key: `improve-fixed:v1:${sourceConversionId}`,
|
|
272
|
+
passthrough: args.options.passthrough,
|
|
273
|
+
runner: args.dependencies.runConvert ?? runConversionCommand,
|
|
274
|
+
journal: args.dependencies.journal,
|
|
275
|
+
progress: createImproveConvertProgress({
|
|
276
|
+
label: 'fixed-layout derivation',
|
|
277
|
+
boundSeconds: bound,
|
|
278
|
+
write: tick,
|
|
279
|
+
}),
|
|
280
|
+
});
|
|
281
|
+
const fixedOutput = await fixedImproveHtml(args.options.paths.targetDir);
|
|
282
|
+
args.dependencies.journal?.note({ degradations: ['improve_fixed_layout_fallback'] });
|
|
283
|
+
return {
|
|
284
|
+
artifacts: [...new Set([
|
|
285
|
+
...attempt.artifacts,
|
|
286
|
+
...fixed.artifacts,
|
|
287
|
+
args.options.paths.targetLayerDoc,
|
|
288
|
+
`${args.options.paths.targetLayerDoc}.assets`,
|
|
289
|
+
fixedOutput.html,
|
|
290
|
+
fixedOutput.assets,
|
|
291
|
+
])],
|
|
292
|
+
purchaseIds: [...new Set([...attempt.purchaseIds, ...fixed.purchaseIds])],
|
|
293
|
+
runIds: [...new Set([sourceConversionId, ...attempt.runIds, ...fixed.runIds])],
|
|
294
|
+
fallback: {
|
|
295
|
+
html: fixedOutput.html,
|
|
296
|
+
warning: fallbackReason.warning,
|
|
297
|
+
outcome: fallbackReason.outcome,
|
|
298
|
+
waitedSeconds,
|
|
299
|
+
},
|
|
300
|
+
};
|
|
229
301
|
});
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
return {
|
|
233
|
-
artifacts: [...new Set([
|
|
234
|
-
...attempt.artifacts,
|
|
235
|
-
...fixed.artifacts,
|
|
236
|
-
args.options.paths.targetLayerDoc,
|
|
237
|
-
`${args.options.paths.targetLayerDoc}.assets`,
|
|
238
|
-
fixedOutput.html,
|
|
239
|
-
fixedOutput.assets,
|
|
240
|
-
])],
|
|
241
|
-
purchaseIds: [...new Set([...attempt.purchaseIds, ...fixed.purchaseIds])],
|
|
242
|
-
runIds: [...new Set([sourceConversionId, ...attempt.runIds, ...fixed.runIds])],
|
|
243
|
-
fallback: { html: fixedOutput.html, warning },
|
|
244
|
-
};
|
|
245
|
-
});
|
|
246
|
-
// ONE retry, and only for the stall with nothing to derive: the wait ended,
|
|
247
|
-
// no LayerDoc reached disk, so no fixed-layout fallback is possible and the
|
|
248
|
-
// stage has nothing at all. The guard is the LayerDoc on disk rather than
|
|
249
|
-
// the error text — if the conversion delivered, re-dispatching is pure
|
|
250
|
-
// waste of a second paid conversion.
|
|
302
|
+
};
|
|
303
|
+
// ONE DISPATCH PER INVOCATION, ALWAYS (F19, CLAUDE.md item 3).
|
|
251
304
|
//
|
|
252
|
-
//
|
|
253
|
-
// the model's typical
|
|
254
|
-
//
|
|
255
|
-
//
|
|
256
|
-
//
|
|
257
|
-
//
|
|
305
|
+
// A stall used to buy a second parent conversion of the same winner. The
|
|
306
|
+
// justification was that the bound sits outside the model's typical window,
|
|
307
|
+
// so it could not fire on healthy work — a bound, never a measurement. What
|
|
308
|
+
// it produced on pipedrive was one operator command, two parent conversions,
|
|
309
|
+
// four conversion ids, and an abandoned-conversion list the CLI wrote
|
|
310
|
+
// against itself while the first conversion kept running and kept billing.
|
|
311
|
+
//
|
|
312
|
+
// So there is no retry, no abandonment, and no second key. A stall that left
|
|
313
|
+
// a LayerDoc derives the free fixed-layout fallback from the conversion that
|
|
314
|
+
// is already running (inside `attemptConversion`); a stall that left nothing
|
|
315
|
+
// ends the invocation with the conversion still open in the ledger, so
|
|
316
|
+
// `plan/STALL.md` and `--from convert` both re-attach to it.
|
|
258
317
|
//
|
|
259
|
-
// The budget belongs to the KIT, not to this process. Both the retry's
|
|
260
|
-
// identity and its count come from the durable ledgers, so a resume
|
|
261
|
-
// attaches to the conversion the retry actually dispatched instead of to
|
|
262
|
-
// the first, known-stalled one, and a kit that has already retried refuses
|
|
263
|
-
// to buy a third rather than dispatching one per resume forever.
|
|
264
|
-
let converted;
|
|
265
|
-
let convertedKey;
|
|
266
|
-
const retries = bought === 0 && improveConvertStallRetryAllowed(args.record.conversionModel)
|
|
267
|
-
? IMPROVE_CONVERT_STALL_ATTEMPTS - 1
|
|
268
|
-
: 0;
|
|
269
318
|
// Why an attempt is being dispatched, which is what the ledger records it
|
|
270
319
|
// as. A resume of a recorded attempt re-declares the reason it was opened
|
|
271
|
-
// with and dedupes to a no-op
|
|
272
|
-
const
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
await pendingLedgerWrite;
|
|
307
|
-
break;
|
|
308
|
-
}
|
|
309
|
-
catch (error) {
|
|
310
|
-
await pendingLedgerWrite;
|
|
311
|
-
const layerDocPresent = (await stat(args.options.paths.targetLayerDoc)
|
|
312
|
-
.catch(() => undefined))?.isFile();
|
|
313
|
-
if (layerDocPresent || !improveStalled(error))
|
|
314
|
-
throw error;
|
|
315
|
-
// The stalled attempt knows its own id even when the record does not:
|
|
316
|
-
// nothing settled, so `recordedImproveConversionId` has nowhere to look.
|
|
317
|
-
const stalledId = (error instanceof ImproveConvertAttemptError
|
|
318
|
-
? error.attempt.runIds[0]
|
|
319
|
-
: undefined) ?? improveConversionIdFromText(improveErrorText(error));
|
|
320
|
-
// The attempt ledger closes with the conversion, by key: the run this
|
|
321
|
-
// key reaches is dead, and a later resume must not rebuild it.
|
|
322
|
-
const abandoned = await abandonImproveConversions({
|
|
323
|
-
record: recordBeforeConvert,
|
|
324
|
-
reason: improveConvertStallReason(args.options.convertStallSeconds),
|
|
325
|
-
...(stalledId ? { id: stalledId } : {}),
|
|
326
|
-
warn,
|
|
327
|
-
});
|
|
328
|
-
recordBeforeConvert = abandoned.record;
|
|
329
|
-
await writeImproveRecord(args.options.paths.record, recordBeforeConvert);
|
|
330
|
-
// The ledger is the source of truth, and it cannot record a stall whose
|
|
331
|
-
// id nothing reported. Taking the larger of the two keeps the next key
|
|
332
|
-
// distinct in that case without ever going backwards.
|
|
333
|
-
bought = Math.max(bought + 1, improveConvertStallCount(recordBeforeConvert));
|
|
334
|
-
index = bought + 1;
|
|
335
|
-
if (attempt >= retries) {
|
|
336
|
-
throw improveConvertStallExhausted({
|
|
337
|
-
seconds: args.options.convertStallSeconds,
|
|
338
|
-
bought,
|
|
339
|
-
model: args.record.conversionModel,
|
|
340
|
-
cause: error,
|
|
341
|
-
});
|
|
342
|
-
}
|
|
343
|
-
args.dependencies.journal?.note({ degradations: ['improve_convert_stall_retry'] });
|
|
344
|
-
warn(`[stall] convert: nothing materialized in ${args.options.convertStallSeconds}s;`
|
|
345
|
-
+ ' dispatching one fresh conversion of the same winner');
|
|
346
|
-
await resetImproveTargetAttempt(args.options.paths.targetDir);
|
|
347
|
-
}
|
|
320
|
+
// with and dedupes to a no-op.
|
|
321
|
+
const reason = args.options.fresh
|
|
322
|
+
? 'fresh'
|
|
323
|
+
: resumed?.reason ?? (index === 1 ? 'primary' : 'stall-retry');
|
|
324
|
+
// BEFORE THE DISPATCH, because a conversion nothing wrote down before it
|
|
325
|
+
// started is a conversion a stop cannot leave resumable — and because a
|
|
326
|
+
// price nobody wrote down is a paid call with no receipt. `--fresh` also
|
|
327
|
+
// walks away here from whatever attempt this kit still had open: it is
|
|
328
|
+
// buying a replacement for it, and an attempt left open would send the
|
|
329
|
+
// next resume back to the run this one supersedes.
|
|
330
|
+
const started = startImproveConversionAttempt(recordBeforeConvert, {
|
|
331
|
+
key,
|
|
332
|
+
reason,
|
|
333
|
+
priceCeilingUsd: args.price,
|
|
334
|
+
...(args.options.fresh ? { supersedes: IMPROVE_FRESH_ABANDON_REASON } : {}),
|
|
335
|
+
});
|
|
336
|
+
if (started.record !== recordBeforeConvert) {
|
|
337
|
+
recordBeforeConvert = noteAbandonedAttempts({
|
|
338
|
+
record: started.record,
|
|
339
|
+
attempts: started.superseded,
|
|
340
|
+
reason: IMPROVE_FRESH_ABANDON_REASON,
|
|
341
|
+
warn,
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
// The stage's own priced entry, written now rather than on settlement: a
|
|
345
|
+
// kit that stalled had no `convert` entry at all, so its recorded ceiling
|
|
346
|
+
// was the draft's and a lane converting a page twice could not say so.
|
|
347
|
+
recordBeforeConvert = noteImproveStageDispatched({
|
|
348
|
+
record: recordBeforeConvert, stage: 'convert', priceCeilingUsd: args.price,
|
|
349
|
+
});
|
|
350
|
+
await writeImproveRecord(args.options.paths.record, recordBeforeConvert);
|
|
351
|
+
let converted;
|
|
352
|
+
try {
|
|
353
|
+
converted = await attemptConversion(key);
|
|
354
|
+
await pendingLedgerWrite;
|
|
348
355
|
}
|
|
349
|
-
|
|
350
|
-
|
|
356
|
+
catch (error) {
|
|
357
|
+
await pendingLedgerWrite;
|
|
358
|
+
if (!improveStalled(error))
|
|
359
|
+
throw error;
|
|
360
|
+
// The stalled attempt knows its own id even when the record does not:
|
|
361
|
+
// nothing settled, so `recordedImproveConversionId` has nowhere to look.
|
|
362
|
+
// It stays OPEN in the ledger — it is running, it is paid for, and the
|
|
363
|
+
// resume this error prints is the only way to get anything back for it.
|
|
364
|
+
const stalledId = (error instanceof ImproveConvertAttemptError
|
|
365
|
+
? error.attempt.runIds[0]
|
|
366
|
+
: undefined) ?? improveConversionIdFromText(improveErrorText(error));
|
|
367
|
+
warn(`[stall] convert: nothing settled in ${args.options.convertStallSeconds}s;`
|
|
368
|
+
+ `${stalledId ? ` conversion ${stalledId}` : ' the conversion'} is still running,`
|
|
369
|
+
+ ' and improve is not buying another');
|
|
370
|
+
throw improveConvertStallHalted({
|
|
371
|
+
seconds: args.options.convertStallSeconds,
|
|
372
|
+
...(stalledId ? { conversionId: stalledId } : {}),
|
|
373
|
+
input: args.record.input.value,
|
|
374
|
+
runDir: args.options.paths.runDir,
|
|
375
|
+
cause: error,
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
const convertedKey = key;
|
|
351
379
|
const html = converted.fallback ? converted.fallback.html : args.options.paths.targetHtml;
|
|
352
380
|
for (const expected of [args.options.paths.targetLayerDoc, html]) {
|
|
353
381
|
if (!(await stat(expected).catch(() => undefined))?.isFile()) {
|
|
@@ -361,11 +389,28 @@ export const runImproveConvertStage = async (args) => {
|
|
|
361
389
|
html,
|
|
362
390
|
layout: converted.fallback ? 'fixed' : 'responsive',
|
|
363
391
|
...(converted.runIds[0] ? { sourceConversionId: converted.runIds[0] } : {}),
|
|
364
|
-
...(converted.fallback
|
|
392
|
+
...(converted.fallback
|
|
393
|
+
? {
|
|
394
|
+
responsiveWarning: converted.fallback.warning,
|
|
395
|
+
responsiveOutcome: converted.fallback.outcome,
|
|
396
|
+
}
|
|
397
|
+
: {}),
|
|
398
|
+
// What the responsive half did before the derivation replaced it, kept
|
|
399
|
+
// durably so `plan/STALL.md`, the README and the run summary all read
|
|
400
|
+
// one account of the same wait rather than three (F8).
|
|
401
|
+
...(converted.fallback && converted.runIds[0]
|
|
402
|
+
? {
|
|
403
|
+
responsiveStall: {
|
|
404
|
+
conversionId: converted.runIds[0],
|
|
405
|
+
waitedSeconds: converted.fallback.waitedSeconds,
|
|
406
|
+
boundSeconds: bound,
|
|
407
|
+
},
|
|
408
|
+
}
|
|
409
|
+
: {}),
|
|
365
410
|
artifacts: converted.artifacts,
|
|
366
411
|
purchaseIds: converted.purchaseIds,
|
|
367
412
|
},
|
|
368
|
-
}, {
|
|
413
|
+
}, { key: convertedKey });
|
|
369
414
|
record = await noteImproveStage({
|
|
370
415
|
record, stage: 'convert', priceCeilingUsd: args.price, replayed: false, write: false,
|
|
371
416
|
});
|
|
@@ -378,4 +423,167 @@ export const runImproveConvertStage = async (args) => {
|
|
|
378
423
|
throw error;
|
|
379
424
|
}
|
|
380
425
|
};
|
|
426
|
+
const fileExists = async (file) => ((await stat(file).catch(() => undefined))?.isFile() ?? false);
|
|
427
|
+
const directoryExists = async (directory) => ((await stat(directory).catch(() => undefined))?.isDirectory() ?? false);
|
|
428
|
+
const mergeConvertAttempts = (...attempts) => ({
|
|
429
|
+
artifacts: [...new Set(attempts.flatMap((attempt) => attempt.artifacts))],
|
|
430
|
+
purchaseIds: [...new Set(attempts.flatMap((attempt) => attempt.purchaseIds))],
|
|
431
|
+
runIds: [...new Set(attempts.flatMap((attempt) => attempt.runIds))],
|
|
432
|
+
});
|
|
433
|
+
const convertImproveTarget = async (args) => {
|
|
434
|
+
const transaction = await prepareImproveTargetAttempt(args.outDir);
|
|
435
|
+
try {
|
|
436
|
+
let attempt;
|
|
437
|
+
let responsiveWarning;
|
|
438
|
+
let responsiveOutcome;
|
|
439
|
+
try {
|
|
440
|
+
attempt = await runImproveConversion({
|
|
441
|
+
input: args.input,
|
|
442
|
+
outDir: args.outDir,
|
|
443
|
+
output: 'html',
|
|
444
|
+
model: args.model,
|
|
445
|
+
responsiveQuality: args.responsiveQuality,
|
|
446
|
+
stallTimeoutMs: args.stallTimeoutMs,
|
|
447
|
+
key: args.key,
|
|
448
|
+
passthrough: args.passthrough,
|
|
449
|
+
runner: args.runner,
|
|
450
|
+
journal: args.journal,
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
catch (error) {
|
|
454
|
+
const layerDocPresent = await fileExists(args.targetLayerDoc);
|
|
455
|
+
const fallback = responsiveFallbackReason(error);
|
|
456
|
+
if (!fallback || !layerDocPresent)
|
|
457
|
+
throw error;
|
|
458
|
+
responsiveWarning = fallback.warning;
|
|
459
|
+
responsiveOutcome = fallback.outcome;
|
|
460
|
+
attempt = error instanceof ImproveConvertAttemptError
|
|
461
|
+
? error.attempt
|
|
462
|
+
: { artifacts: [], purchaseIds: [], runIds: [] };
|
|
463
|
+
const conversionId = attempt.runIds[0]
|
|
464
|
+
?? improveConversionIdFromText(improveErrorText(error));
|
|
465
|
+
if (conversionId) {
|
|
466
|
+
attempt = mergeConvertAttempts(attempt, {
|
|
467
|
+
artifacts: [], purchaseIds: [], runIds: [conversionId],
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
if (!(await fileExists(args.targetLayerDoc))) {
|
|
472
|
+
throw new Error(`Improve conversion completed without ${args.targetLayerDoc}`);
|
|
473
|
+
}
|
|
474
|
+
const responsiveHtmlPresent = await fileExists(args.targetHtml);
|
|
475
|
+
if (!responsiveHtmlPresent && !responsiveWarning) {
|
|
476
|
+
responsiveWarning = 'Responsive HTML was not generated; the LayerDoc remains available for planning.';
|
|
477
|
+
}
|
|
478
|
+
let html = responsiveHtmlPresent ? args.targetHtml : '';
|
|
479
|
+
let layout = responsiveHtmlPresent ? 'responsive' : 'document';
|
|
480
|
+
const sourceConversionId = attempt.runIds[0];
|
|
481
|
+
if (!responsiveHtmlPresent && sourceConversionId) {
|
|
482
|
+
(args.warn ?? console.warn)(`Responsive HTML was unavailable; deriving fixed-layout HTML free from ${sourceConversionId}`);
|
|
483
|
+
try {
|
|
484
|
+
const fixedAttempt = await runImproveConversion({
|
|
485
|
+
input: sourceConversionId,
|
|
486
|
+
outDir: args.outDir,
|
|
487
|
+
output: 'html_fixed',
|
|
488
|
+
stallTimeoutMs: args.stallTimeoutMs,
|
|
489
|
+
key: `improve-fixed:v1:${sourceConversionId}`,
|
|
490
|
+
passthrough: args.passthrough,
|
|
491
|
+
runner: args.runner,
|
|
492
|
+
journal: args.journal,
|
|
493
|
+
});
|
|
494
|
+
attempt = mergeConvertAttempts(attempt, fixedAttempt);
|
|
495
|
+
const fixed = await fixedImproveHtml(args.outDir);
|
|
496
|
+
attempt = mergeConvertAttempts(attempt, {
|
|
497
|
+
artifacts: [args.targetLayerDoc, fixed.html, fixed.assets],
|
|
498
|
+
purchaseIds: [],
|
|
499
|
+
runIds: [],
|
|
500
|
+
});
|
|
501
|
+
html = fixed.html;
|
|
502
|
+
layout = 'fixed';
|
|
503
|
+
args.journal?.note({ degradations: ['improve_fixed_layout_fallback'] });
|
|
504
|
+
}
|
|
505
|
+
catch (error) {
|
|
506
|
+
if (error instanceof ImproveConvertAttemptError) {
|
|
507
|
+
attempt = mergeConvertAttempts(attempt, error.attempt);
|
|
508
|
+
}
|
|
509
|
+
(args.warn ?? console.warn)(`Fixed-layout derivation was unavailable; retaining the LayerDoc only: ${improveErrorText(error)}`);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
if (!responsiveHtmlPresent) {
|
|
513
|
+
const layerDocAssets = `${args.targetLayerDoc}.assets`;
|
|
514
|
+
attempt = mergeConvertAttempts(attempt, {
|
|
515
|
+
artifacts: [
|
|
516
|
+
args.targetLayerDoc,
|
|
517
|
+
...((await directoryExists(layerDocAssets)) ? [layerDocAssets] : []),
|
|
518
|
+
],
|
|
519
|
+
purchaseIds: [],
|
|
520
|
+
runIds: [],
|
|
521
|
+
});
|
|
522
|
+
args.journal?.note({ degradations: ['improve_responsive_html_unavailable'] });
|
|
523
|
+
}
|
|
524
|
+
const converted = {
|
|
525
|
+
layerDoc: args.targetLayerDoc,
|
|
526
|
+
html,
|
|
527
|
+
layout,
|
|
528
|
+
...(sourceConversionId ? { sourceConversionId } : {}),
|
|
529
|
+
...(responsiveWarning ? { responsiveWarning } : {}),
|
|
530
|
+
...(responsiveOutcome ? { responsiveOutcome } : {}),
|
|
531
|
+
artifacts: attempt.artifacts,
|
|
532
|
+
purchaseIds: attempt.purchaseIds,
|
|
533
|
+
};
|
|
534
|
+
await transaction.commit();
|
|
535
|
+
return converted;
|
|
536
|
+
}
|
|
537
|
+
catch (error) {
|
|
538
|
+
await transaction.restore();
|
|
539
|
+
throw error;
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
export const runImproveSiteConvertStage = async (args) => {
|
|
543
|
+
const complete = !args.options.fresh
|
|
544
|
+
&& Boolean(args.record.convert)
|
|
545
|
+
&& args.record.pages.length > 0
|
|
546
|
+
&& args.record.pages.every((page) => page.branch?.status === 'failed' || page.convert);
|
|
547
|
+
if (complete)
|
|
548
|
+
return noteImproveStage({
|
|
549
|
+
record: args.record, stage: 'convert', priceCeilingUsd: args.price, replayed: true, write: true,
|
|
550
|
+
});
|
|
551
|
+
let record = args.record.convert && !args.options.fresh
|
|
552
|
+
? args.record
|
|
553
|
+
: await runImproveConvertStage(args);
|
|
554
|
+
const limiter = createConcurrencyLimiter(args.options.pageConcurrency);
|
|
555
|
+
const convertedPages = await Promise.all(record.pages.map((page) => limiter(async () => {
|
|
556
|
+
if (page.branch?.status === 'failed')
|
|
557
|
+
return page;
|
|
558
|
+
if (page.convert)
|
|
559
|
+
return page;
|
|
560
|
+
if (page.branch?.status !== 'succeeded' || !page.branch.sha256 || !page.branch.imagePath) {
|
|
561
|
+
throw new Error(`Cannot convert site page ${page.id} before branch succeeds`);
|
|
562
|
+
}
|
|
563
|
+
const paths = improvePagePaths(record.runDir, page.id);
|
|
564
|
+
const targetIdentity = improveSha256(Buffer.from(`${page.branch.sha256}:${record.conversionModel}:${args.options.responsiveQuality}`)).slice(0, 32);
|
|
565
|
+
const baseKey = `improve-page-target:v2:${targetIdentity}`;
|
|
566
|
+
const key = args.options.fresh
|
|
567
|
+
? `${baseKey}:fresh:${args.freshConversionNonce}`
|
|
568
|
+
: baseKey;
|
|
569
|
+
const converted = await convertImproveTarget({
|
|
570
|
+
input: page.branch.imagePath,
|
|
571
|
+
outDir: paths.targetDir,
|
|
572
|
+
targetLayerDoc: paths.targetLayerDoc,
|
|
573
|
+
targetHtml: paths.targetHtml,
|
|
574
|
+
model: record.conversionModel,
|
|
575
|
+
responsiveQuality: args.options.responsiveQuality,
|
|
576
|
+
key,
|
|
577
|
+
stallTimeoutMs: args.options.convertStallSeconds * 1_000,
|
|
578
|
+
passthrough: args.options.passthrough,
|
|
579
|
+
runner: args.dependencies.runConvert ?? runConversionCommand,
|
|
580
|
+
journal: args.dependencies.journal,
|
|
581
|
+
warn: args.dependencies.warn,
|
|
582
|
+
});
|
|
583
|
+
return { ...page, convert: converted };
|
|
584
|
+
})));
|
|
585
|
+
record = { ...record, pages: convertedPages };
|
|
586
|
+
await writeImproveRecord(args.options.paths.record, record);
|
|
587
|
+
return record;
|
|
588
|
+
};
|
|
381
589
|
//# sourceMappingURL=improve-conversion-stage.js.map
|