@12ui/design 0.2.12 → 0.2.13

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.
Files changed (54) hide show
  1. package/README.md +9 -0
  2. package/dist/cli-arguments.d.ts.map +1 -1
  3. package/dist/cli-arguments.js +1 -0
  4. package/dist/cli-arguments.js.map +1 -1
  5. package/dist/cli-image-batch-command.d.ts.map +1 -1
  6. package/dist/cli-image-batch-command.js +104 -53
  7. package/dist/cli-image-batch-command.js.map +1 -1
  8. package/dist/cli-image-batch-materialize.d.ts +27 -0
  9. package/dist/cli-image-batch-materialize.d.ts.map +1 -0
  10. package/dist/cli-image-batch-materialize.js +41 -0
  11. package/dist/cli-image-batch-materialize.js.map +1 -0
  12. package/dist/cli-image-batch-resume.d.ts +27 -0
  13. package/dist/cli-image-batch-resume.d.ts.map +1 -0
  14. package/dist/cli-image-batch-resume.js +158 -0
  15. package/dist/cli-image-batch-resume.js.map +1 -0
  16. package/dist/cli-image-command.d.ts.map +1 -1
  17. package/dist/cli-image-command.js +14 -2
  18. package/dist/cli-image-command.js.map +1 -1
  19. package/dist/cli.js +1 -1
  20. package/dist/image-generation-batch-attempt.d.ts +28 -0
  21. package/dist/image-generation-batch-attempt.d.ts.map +1 -0
  22. package/dist/image-generation-batch-attempt.js +48 -0
  23. package/dist/image-generation-batch-attempt.js.map +1 -0
  24. package/dist/image-generation-completion.d.ts +43 -0
  25. package/dist/image-generation-completion.d.ts.map +1 -0
  26. package/dist/image-generation-completion.js +54 -0
  27. package/dist/image-generation-completion.js.map +1 -0
  28. package/dist/image-generation-fs.d.ts +3 -0
  29. package/dist/image-generation-fs.d.ts.map +1 -0
  30. package/dist/image-generation-fs.js +23 -0
  31. package/dist/image-generation-fs.js.map +1 -0
  32. package/dist/image-generation-request.d.ts +13 -3
  33. package/dist/image-generation-request.d.ts.map +1 -1
  34. package/dist/image-generation-request.js +21 -19
  35. package/dist/image-generation-request.js.map +1 -1
  36. package/dist/image-generation-resume.d.ts +36 -0
  37. package/dist/image-generation-resume.d.ts.map +1 -0
  38. package/dist/image-generation-resume.js +83 -0
  39. package/dist/image-generation-resume.js.map +1 -0
  40. package/dist/image-generation-run.d.ts +11 -0
  41. package/dist/image-generation-run.d.ts.map +1 -1
  42. package/dist/image-generation-run.js +23 -9
  43. package/dist/image-generation-run.js.map +1 -1
  44. package/dist/image-generation-staging.d.ts +25 -0
  45. package/dist/image-generation-staging.d.ts.map +1 -0
  46. package/dist/image-generation-staging.js +80 -0
  47. package/dist/image-generation-staging.js.map +1 -0
  48. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  49. package/dist/legacy-skill-catalog.js +18 -0
  50. package/dist/legacy-skill-catalog.js.map +1 -1
  51. package/package.json +1 -1
  52. package/skills/design/SKILL.md +49 -8
  53. package/skills/design/references/selection-contract.md +16 -0
  54. package/skills/design-convert/SKILL.md +17 -1
package/README.md CHANGED
@@ -99,6 +99,15 @@ PNG output, and one stable idempotency key. Per-candidate and batch evidence
99
99
  records provider-start and completion times. It never retries a candidate or
100
100
  switches providers after dispatch.
101
101
 
102
+ Candidates are written into a hidden staging directory and moved into place only
103
+ once the batch is terminal, so a caller listing the output directory can never
104
+ observe a half-written batch. Completion is published as a
105
+ `generation.complete.json` sentinel beside the candidates, carrying each
106
+ candidate's status, sha256, and byte count. `--resume` recovers an interrupted
107
+ batch: it delivers candidates that were already generated and re-requests only
108
+ those the provider provably never billed, so it can never buy a candidate twice,
109
+ and it refuses a batch that already completed.
110
+
102
111
  The single-candidate `image generate` command remains available. Both commands
103
112
  resolve authenticated Codex first, then `OPENAI_API_KEY` from the process or
104
113
  exactly `<project-root>/.env`. They refuse a Git-tracked `.env`, never store or
@@ -1 +1 @@
1
- {"version":3,"file":"cli-arguments.d.ts","sourceRoot":"","sources":["../src/cli-arguments.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;AAYrD,eAAO,MAAM,iBAAiB,GAC5B,MAAM,MAAM,EAAE,KACb;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAqBtC,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,OAAO,QAAQ,EAAE,MAAM,MAAM,KAAG,MAAM,GAAG,SAGnE,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,OAAO,QAAQ,EAAE,MAAM,MAAM,KAAG,OAA+B,CAAC"}
1
+ {"version":3,"file":"cli-arguments.d.ts","sourceRoot":"","sources":["../src/cli-arguments.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;AAarD,eAAO,MAAM,iBAAiB,GAC5B,MAAM,MAAM,EAAE,KACb;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAqBtC,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,OAAO,QAAQ,EAAE,MAAM,MAAM,KAAG,MAAM,GAAG,SAGnE,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,OAAO,QAAQ,EAAE,MAAM,MAAM,KAAG,OAA+B,CAAC"}
@@ -4,6 +4,7 @@ const booleanFlags = new Set([
4
4
  'help',
5
5
  'json',
6
6
  'quiet',
7
+ 'resume',
7
8
  'skip-auth',
8
9
  'version',
9
10
  ]);
@@ -1 +1 @@
1
- {"version":3,"file":"cli-arguments.js","sourceRoot":"","sources":["../src/cli-arguments.ts"],"names":[],"mappings":"AAEA,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,QAAQ;IACR,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,WAAW;IACX,SAAS;CACV,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,IAAc,EAC0B,EAAE;IAC1C,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,IAAI,KAAK;gBAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/B,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACjD,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;YACnB,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,KAAK,IAAI,mBAAmB,CAAC,CAAC;QAClF,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACnB,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAe,EAAE,IAAY,EAAsB,EAAE;IAC9E,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAe,EAAE,IAAY,EAAW,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC"}
1
+ {"version":3,"file":"cli-arguments.js","sourceRoot":"","sources":["../src/cli-arguments.ts"],"names":[],"mappings":"AAEA,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,QAAQ;IACR,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,QAAQ;IACR,WAAW;IACX,SAAS;CACV,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,IAAc,EAC0B,EAAE;IAC1C,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,IAAI,KAAK;gBAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/B,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACjD,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;YACnB,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,KAAK,IAAI,mBAAmB,CAAC,CAAC;QAClF,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACnB,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAe,EAAE,IAAY,EAAsB,EAAE;IAC9E,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAe,EAAE,IAAY,EAAW,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"cli-image-batch-command.d.ts","sourceRoot":"","sources":["../src/cli-image-batch-command.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAsB/D,OAAO,EACL,sBAAsB,EAEvB,MAAM,+BAA+B,CAAC;AA4DvC,eAAO,MAAM,oBAAoB,GAC/B,OAAO,QAAQ,EACf,eAAc;IACZ,QAAQ,CAAC,EAAE,OAAO,aAAa,CAAC;IAChC,SAAS,CAAC,EAAE,OAAO,sBAAsB,CAAC;CACtC,KACL,OAAO,CAAC,IAAI,CAiHd,CAAC"}
1
+ {"version":3,"file":"cli-image-batch-command.d.ts","sourceRoot":"","sources":["../src/cli-image-batch-command.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAA2B,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAoC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AA+CvE,eAAO,MAAM,oBAAoB,GAC/B,OAAO,QAAQ,EACf,eAAc;IACZ,QAAQ,CAAC,EAAE,OAAO,aAAa,CAAC;IAChC,SAAS,CAAC,EAAE,OAAO,sBAAsB,CAAC;CACtC,KACL,OAAO,CAAC,IAAI,CA8Kd,CAAC"}
@@ -1,57 +1,86 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { mkdir, rename, rm, writeFile } from 'node:fs/promises';
3
1
  import path from 'node:path';
4
- import { stringFlag } from './cli-arguments.js';
2
+ import { booleanFlag, stringFlag } from './cli-arguments.js';
3
+ import { materializeImageBatch, publishImageBatchCompletion, } from './cli-image-batch-materialize.js';
4
+ import { describeBatchRecovery, resumeImageBatchCommand } from './cli-image-batch-resume.js';
5
+ import { imageBatchAttemptPath, readBatchAttempt, writeBatchAttempt, } from './image-generation-batch-attempt.js';
5
6
  import { readImageGenerationBatchManifest, resolveImageGenerationBatchRequests, } from './image-generation-batch-manifest.js';
7
+ import { imageGenerationPathExists } from './image-generation-fs.js';
8
+ import { classifyImageGenerationResume, resumeStateSummary, } from './image-generation-resume.js';
6
9
  import { dispatchImageGeneration, failImageGenerationBeforeDispatch, markImageGenerationDispatched, reserveImageGeneration, } from './image-generation-run.js';
7
- import { imageGenerationPathExists, imageGenerationSha256, prepareImageGenerationRequest, } from './image-generation-request.js';
8
- import { summarizeImageGenerationUsage, } from './image-generation-usage.js';
9
- import { preflightImageProvider, } from './image-provider-preflight.js';
10
- const writeBatchAttempt = async (file, attempt, exclusive = false) => {
11
- await mkdir(path.dirname(file), { recursive: true });
12
- if (exclusive) {
13
- await writeFile(file, `${JSON.stringify(attempt, null, 2)}\n`, {
14
- encoding: 'utf8',
15
- flag: 'wx',
16
- mode: 0o600,
17
- });
18
- return;
19
- }
20
- const temporary = `${file}.${randomUUID()}.tmp`;
21
- try {
22
- await writeFile(temporary, `${JSON.stringify(attempt, null, 2)}\n`, {
23
- encoding: 'utf8',
24
- flag: 'wx',
25
- mode: 0o600,
26
- });
27
- await rename(temporary, file);
28
- }
29
- finally {
30
- await rm(temporary, { force: true });
31
- }
32
- };
10
+ import { imageGenerationSha256, prepareImageGenerationRequest, } from './image-generation-request.js';
11
+ import { summarizeImageGenerationUsage } from './image-generation-usage.js';
12
+ import { preflightImageProvider } from './image-provider-preflight.js';
33
13
  const errorMessage = (error) => (error instanceof Error ? error.message : String(error));
34
14
  const failReserved = async (reserved, message) => {
35
15
  await Promise.allSettled(reserved.map((item) => failImageGenerationBeforeDispatch(item, message)));
36
16
  };
17
+ const identities = (requests) => requests.map((request) => ({
18
+ ...(request.candidateId ? { candidateId: request.candidateId } : {}),
19
+ outputPath: request.outputPath,
20
+ idempotencyKey: request.idempotencyKey,
21
+ }));
22
+ /**
23
+ * Explain what the existing evidence permits instead of stopping at "evidence
24
+ * exists". A refusal that names no recovery is what turned a finished batch
25
+ * into a dead end for eleven benchmark runs.
26
+ */
27
+ const existingEvidenceRefusal = async (args) => {
28
+ const states = await Promise.all(args.requests.map((request) => classifyImageGenerationResume({
29
+ outputPath: request.outputPath,
30
+ ...(request.candidateId ? { candidateId: request.candidateId } : {}),
31
+ })));
32
+ const summary = resumeStateSummary(states);
33
+ const recoverable = summary.stageable + summary.redispatchable;
34
+ const guidance = recoverable > 0
35
+ ? `Re-run the same command with --resume to recover ${recoverable} candidate(s) with no new`
36
+ + ' spend; it never re-buys a candidate.'
37
+ : summary.unrecoverable > 0
38
+ ? 'Nothing can be recovered without new spend; give the affected candidates a new output'
39
+ + ' path and idempotency key if you accept buying them again.'
40
+ : 'Every candidate is already on disk — read them rather than generating again.';
41
+ return `Image batch attempt evidence already exists at ${args.batchAttemptFile}.`
42
+ + ` ${describeBatchRecovery(states)}. ${guidance}`;
43
+ };
37
44
  export const runImageBatchCommand = async (flags, dependencies = {}) => {
38
45
  const manifestFlag = stringFlag(flags, 'manifest')?.trim();
39
46
  if (!manifestFlag) {
40
- throw new Error('Usage: 12ui image generate-batch --manifest <batch.json>');
47
+ throw new Error('Usage: 12ui image generate-batch --manifest <batch.json> [--resume]');
41
48
  }
42
49
  const manifestPath = path.resolve(manifestFlag);
43
- const batchAttemptFile = `${manifestPath}.attempt.json`;
44
- if (await imageGenerationPathExists(batchAttemptFile)) {
45
- throw new Error(`Image batch attempt evidence already exists at ${batchAttemptFile}`);
46
- }
50
+ const batchAttemptFile = imageBatchAttemptPath(manifestPath);
51
+ const resumeRequested = booleanFlag(flags, 'resume');
47
52
  const { manifest, source } = await readImageGenerationBatchManifest(manifestPath);
48
53
  const requests = resolveImageGenerationBatchRequests({ manifest, manifestPath });
49
- const prepared = await Promise.all(requests.map(prepareImageGenerationRequest));
54
+ const manifestSha256 = imageGenerationSha256(source);
55
+ const existingBatchAttempt = await readBatchAttempt(batchAttemptFile);
56
+ if (await imageGenerationPathExists(batchAttemptFile)) {
57
+ if (!resumeRequested) {
58
+ throw new Error(await existingEvidenceRefusal({ batchAttemptFile, requests }));
59
+ }
60
+ if (!existingBatchAttempt) {
61
+ throw new Error(`Image batch attempt evidence at ${batchAttemptFile} is unreadable, so no candidate can be`
62
+ + ' proved unbilled. Inspect it before resuming.');
63
+ }
64
+ if (existingBatchAttempt.manifestSha256 !== manifestSha256) {
65
+ throw new Error(`Refusing to resume: ${manifestPath} has changed since the batch was dispatched`
66
+ + ` (${existingBatchAttempt.manifestSha256} then, ${manifestSha256} now). A resume must`
67
+ + ' replay the same candidate identities.');
68
+ }
69
+ await resumeImageBatchCommand({
70
+ manifestPath,
71
+ manifestSha256,
72
+ batchAttemptFile,
73
+ batchAttempt: existingBatchAttempt,
74
+ requests,
75
+ dependencies,
76
+ });
77
+ return;
78
+ }
79
+ const prepared = await Promise.all(requests.map((request) => (prepareImageGenerationRequest(request))));
50
80
  const preflight = await (dependencies.preflight ?? preflightImageProvider)({
51
81
  provider: manifest.provider,
52
82
  projectRoot: prepared[0].projectRoot,
53
83
  });
54
- const manifestSha256 = imageGenerationSha256(source);
55
84
  const attempt = {
56
85
  version: 2,
57
86
  status: 'prepared',
@@ -67,6 +96,28 @@ export const runImageBatchCommand = async (flags, dependencies = {}) => {
67
96
  preparedAt: new Date().toISOString(),
68
97
  };
69
98
  await writeBatchAttempt(batchAttemptFile, attempt, true);
99
+ const candidates = identities(prepared);
100
+ const terminate = async (args) => {
101
+ if (args.materialize)
102
+ await materializeImageBatch(candidates);
103
+ const { completionPath } = await publishImageBatchCompletion({
104
+ manifestPath,
105
+ manifestSha256,
106
+ batchAttemptFile,
107
+ provider: attempt.provider,
108
+ model: attempt.model,
109
+ resumed: false,
110
+ status: args.status,
111
+ candidates,
112
+ });
113
+ attempt.status = args.status;
114
+ attempt.completedAt = new Date().toISOString();
115
+ attempt.completionPath = completionPath;
116
+ if (args.errors)
117
+ attempt.errors = args.errors;
118
+ await writeBatchAttempt(batchAttemptFile, attempt);
119
+ return completionPath;
120
+ };
70
121
  const reservations = await Promise.allSettled(prepared.map((request) => (reserveImageGeneration({
71
122
  request,
72
123
  preflight,
@@ -81,11 +132,12 @@ export const runImageBatchCommand = async (flags, dependencies = {}) => {
81
132
  if (reservationErrors.length > 0) {
82
133
  const message = 'Batch reservation failed before any provider request was started';
83
134
  await failReserved(reserved, message);
84
- attempt.status = 'failed';
85
- attempt.completedAt = new Date().toISOString();
86
- attempt.errors = reservationErrors;
87
- await writeBatchAttempt(batchAttemptFile, attempt);
88
- throw new AggregateError(reservationErrors, `${message}. Evidence: ${batchAttemptFile}`);
135
+ const completionPath = await terminate({
136
+ status: 'failed',
137
+ errors: reservationErrors,
138
+ materialize: false,
139
+ });
140
+ throw new AggregateError(reservationErrors, `${message}. Evidence: ${batchAttemptFile}. Completion sentinel: ${completionPath}`);
89
141
  }
90
142
  attempt.status = 'dispatched';
91
143
  attempt.dispatchedAt = new Date().toISOString();
@@ -95,32 +147,31 @@ export const runImageBatchCommand = async (flags, dependencies = {}) => {
95
147
  if (markErrors.length > 0) {
96
148
  const message = 'Batch evidence preparation failed before any provider request was started';
97
149
  await failReserved(reserved, message);
98
- attempt.status = 'failed';
99
- attempt.completedAt = new Date().toISOString();
100
- attempt.errors = markErrors;
101
- await writeBatchAttempt(batchAttemptFile, attempt);
102
- throw new AggregateError(markErrors, `${message}. Evidence: ${batchAttemptFile}`);
150
+ const completionPath = await terminate({
151
+ status: 'failed',
152
+ errors: markErrors,
153
+ materialize: false,
154
+ });
155
+ throw new AggregateError(markErrors, `${message}. Evidence: ${batchAttemptFile}. Completion sentinel: ${completionPath}`);
103
156
  }
104
157
  const settled = await Promise.allSettled(reserved.map((item) => (dispatchImageGeneration(item, { generate: dependencies.generate }))));
105
158
  const results = settled.flatMap((result) => (result.status === 'fulfilled' ? [result.value] : []));
106
159
  const errors = settled.flatMap((result) => (result.status === 'rejected' ? [errorMessage(result.reason)] : []));
107
- attempt.completedAt = new Date().toISOString();
108
160
  attempt.results = results;
109
161
  attempt.accounting = summarizeImageGenerationUsage(reserved.map((item) => item.attempt.usage), preflight.provider);
110
162
  if (errors.length > 0) {
111
- attempt.status = 'failed';
112
- attempt.errors = errors;
113
- await writeBatchAttempt(batchAttemptFile, attempt);
163
+ const completionPath = await terminate({ status: 'failed', errors, materialize: true });
114
164
  throw new AggregateError(errors, `Image batch finished with ${errors.length} failed candidate(s); no retries or provider`
115
- + ` fallback were attempted. Evidence: ${batchAttemptFile}`);
165
+ + ` fallback were attempted. Evidence: ${batchAttemptFile}.`
166
+ + ` Completion sentinel: ${completionPath}`);
116
167
  }
117
- attempt.status = 'succeeded';
118
- await writeBatchAttempt(batchAttemptFile, attempt);
168
+ const completionPath = await terminate({ status: 'succeeded', materialize: true });
119
169
  console.log(JSON.stringify({
120
170
  provider: attempt.provider,
121
171
  model: attempt.model,
122
172
  manifestPath,
123
173
  batchAttemptFile,
174
+ completionPath,
124
175
  accounting: attempt.accounting,
125
176
  candidates: results,
126
177
  }, null, 2));
@@ -1 +1 @@
1
- {"version":3,"file":"cli-image-batch-command.js","sourceRoot":"","sources":["../src/cli-image-batch-command.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli-image-batch-command.js","sourceRoot":"","sources":["../src/cli-image-batch-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { type ImageBatchCompletion } from './image-generation-completion.js';
2
+ export type ImageBatchCandidateIdentity = {
3
+ candidateId?: string;
4
+ outputPath: string;
5
+ idempotencyKey: string;
6
+ };
7
+ /**
8
+ * Move every candidate the provider settled — succeeded or failed — out of the
9
+ * hidden staging directory in one pass. Nothing is delivered mid-flight, so the
10
+ * candidates directory goes from empty to complete rather than through a
11
+ * half-written state that reads as failure.
12
+ */
13
+ export declare const materializeImageBatch: (candidates: readonly ImageBatchCandidateIdentity[]) => Promise<void>;
14
+ export declare const publishImageBatchCompletion: (args: {
15
+ manifestPath: string;
16
+ manifestSha256: string;
17
+ batchAttemptFile: string;
18
+ provider: string;
19
+ model: string;
20
+ resumed: boolean;
21
+ status: "succeeded" | "failed";
22
+ candidates: readonly ImageBatchCandidateIdentity[];
23
+ }) => Promise<{
24
+ completionPath: string;
25
+ completion: ImageBatchCompletion;
26
+ }>;
27
+ //# sourceMappingURL=cli-image-batch-materialize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-image-batch-materialize.d.ts","sourceRoot":"","sources":["../src/cli-image-batch-materialize.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,kCAAkC,CAAC;AAG1C,MAAM,MAAM,2BAA2B,GAAG;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAMF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAChC,YAAY,SAAS,2BAA2B,EAAE,KACjD,OAAO,CAAC,IAAI,CAId,CAAC;AAEF,eAAO,MAAM,2BAA2B,GAAU,MAAM;IACtD,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,UAAU,EAAE,SAAS,2BAA2B,EAAE,CAAC;CACpD,KAAG,OAAO,CAAC;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,oBAAoB,CAAA;CAAE,CA2BvE,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { imageBatchCompletionPath, summarizeImageBatchCandidates, writeImageBatchCompletion, } from './image-generation-completion.js';
2
+ import { materializeImageGeneration } from './image-generation-staging.js';
3
+ const identityId = (candidate, index) => (candidate.candidateId ?? String(index + 1));
4
+ /**
5
+ * Move every candidate the provider settled — succeeded or failed — out of the
6
+ * hidden staging directory in one pass. Nothing is delivered mid-flight, so the
7
+ * candidates directory goes from empty to complete rather than through a
8
+ * half-written state that reads as failure.
9
+ */
10
+ export const materializeImageBatch = async (candidates) => {
11
+ await Promise.all(candidates.map((candidate) => (materializeImageGeneration(candidate.outputPath))));
12
+ };
13
+ export const publishImageBatchCompletion = async (args) => {
14
+ const completionPath = imageBatchCompletionPath({
15
+ manifestPath: args.manifestPath,
16
+ outputPaths: args.candidates.map((candidate) => candidate.outputPath),
17
+ });
18
+ const candidates = await summarizeImageBatchCandidates(args.candidates.map((candidate, index) => ({
19
+ id: identityId(candidate, index),
20
+ outputPath: candidate.outputPath,
21
+ idempotencyKey: candidate.idempotencyKey,
22
+ })));
23
+ const completion = {
24
+ version: 1,
25
+ status: args.status,
26
+ manifestPath: args.manifestPath,
27
+ manifestSha256: args.manifestSha256,
28
+ batchAttemptFile: args.batchAttemptFile,
29
+ provider: args.provider,
30
+ model: args.model,
31
+ resumed: args.resumed,
32
+ completedAt: new Date().toISOString(),
33
+ candidateCount: candidates.length,
34
+ succeededCount: candidates.filter((candidate) => candidate.status === 'succeeded').length,
35
+ failedCount: candidates.filter((candidate) => candidate.status !== 'succeeded').length,
36
+ candidates,
37
+ };
38
+ await writeImageBatchCompletion(completionPath, completion);
39
+ return { completionPath, completion };
40
+ };
41
+ //# sourceMappingURL=cli-image-batch-materialize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-image-batch-materialize.js","sourceRoot":"","sources":["../src/cli-image-batch-materialize.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,6BAA6B,EAC7B,yBAAyB,GAE1B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAQ3E,MAAM,UAAU,GAAG,CAAC,SAAsC,EAAE,KAAa,EAAU,EAAE,CAAC,CACpF,SAAS,CAAC,WAAW,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAC3C,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EACxC,UAAkD,EACnC,EAAE;IACjB,MAAM,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAC9C,0BAA0B,CAAC,SAAS,CAAC,UAAU,CAAC,CACjD,CAAC,CAAC,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG,KAAK,EAAE,IASjD,EAAyE,EAAE;IAC1E,MAAM,cAAc,GAAG,wBAAwB,CAAC;QAC9C,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC;KACtE,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,MAAM,6BAA6B,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAChG,EAAE,EAAE,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC;QAChC,UAAU,EAAE,SAAS,CAAC,UAAU;QAChC,cAAc,EAAE,SAAS,CAAC,cAAc;KACzC,CAAC,CAAC,CAAC,CAAC;IACL,MAAM,UAAU,GAAyB;QACvC,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;QACvC,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,cAAc,EAAE,UAAU,CAAC,MAAM;QACjC,cAAc,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM;QACzF,WAAW,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM;QACtF,UAAU;KACX,CAAC;IACF,MAAM,yBAAyB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IAC5D,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC;AACxC,CAAC,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { ensembleImage } from '@just-every/ensemble';
2
+ import { type ImageBatchAttempt } from './image-generation-batch-attempt.js';
3
+ import type { ImageGenerationRequest } from './image-generation-request.js';
4
+ import { type ImageGenerationResumeState } from './image-generation-resume.js';
5
+ import { preflightImageProvider } from './image-provider-preflight.js';
6
+ export declare const describeBatchRecovery: (states: readonly ImageGenerationResumeState[]) => string;
7
+ /**
8
+ * Recover a batch whose candidates were dispatched but never delivered.
9
+ *
10
+ * Every candidate is classified from its own durable ledger entry first. Work
11
+ * that was already bought is delivered from staging; work that provably was not
12
+ * bought, or that the provider will return again for free under the recorded
13
+ * idempotency key, is re-requested under that same identity. Anything else is
14
+ * refused rather than bought a second time.
15
+ */
16
+ export declare const resumeImageBatchCommand: (args: {
17
+ manifestPath: string;
18
+ manifestSha256: string;
19
+ batchAttemptFile: string;
20
+ batchAttempt: ImageBatchAttempt;
21
+ requests: ImageGenerationRequest[];
22
+ dependencies: {
23
+ generate?: typeof ensembleImage;
24
+ preflight?: typeof preflightImageProvider;
25
+ };
26
+ }) => Promise<void>;
27
+ //# sourceMappingURL=cli-image-batch-resume.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-image-batch-resume.d.ts","sourceRoot":"","sources":["../src/cli-image-batch-resume.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAOrD,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E,OAAO,EAIL,KAAK,0BAA0B,EAChC,MAAM,8BAA8B,CAAC;AAStC,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAcvE,eAAO,MAAM,qBAAqB,GAChC,QAAQ,SAAS,0BAA0B,EAAE,KAC5C,MASF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,GAAU,MAAM;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,iBAAiB,CAAC;IAChC,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,YAAY,EAAE;QACZ,QAAQ,CAAC,EAAE,OAAO,aAAa,CAAC;QAChC,SAAS,CAAC,EAAE,OAAO,sBAAsB,CAAC;KAC3C,CAAC;CACH,KAAG,OAAO,CAAC,IAAI,CA8If,CAAC"}
@@ -0,0 +1,158 @@
1
+ import { materializeImageBatch, publishImageBatchCompletion, } from './cli-image-batch-materialize.js';
2
+ import { writeBatchAttempt, } from './image-generation-batch-attempt.js';
3
+ import { prepareImageGenerationRequest } from './image-generation-request.js';
4
+ import { classifyImageGenerationResume, describeResumeState, resumeStateSummary, } from './image-generation-resume.js';
5
+ import { dispatchImageGeneration, markImageGenerationDispatched, resumeReservedImageGeneration, } from './image-generation-run.js';
6
+ import { materializeImageGeneration } from './image-generation-staging.js';
7
+ import { summarizeImageGenerationUsage } from './image-generation-usage.js';
8
+ import { preflightImageProvider } from './image-provider-preflight.js';
9
+ const errorMessage = (error) => (error instanceof Error ? error.message : String(error));
10
+ const identities = (requests) => requests.map((request) => ({
11
+ ...(request.candidateId ? { candidateId: request.candidateId } : {}),
12
+ outputPath: request.outputPath,
13
+ idempotencyKey: request.idempotencyKey,
14
+ }));
15
+ export const describeBatchRecovery = (states) => {
16
+ const summary = resumeStateSummary(states);
17
+ const parts = [
18
+ `${summary.materialized} already on disk`,
19
+ `${summary.stageable} generated and awaiting delivery`,
20
+ `${summary.redispatchable} recoverable without new spend`,
21
+ `${summary.unrecoverable} unrecoverable`,
22
+ ];
23
+ return `${states.length} candidate(s): ${parts.join(', ')}`;
24
+ };
25
+ /**
26
+ * Recover a batch whose candidates were dispatched but never delivered.
27
+ *
28
+ * Every candidate is classified from its own durable ledger entry first. Work
29
+ * that was already bought is delivered from staging; work that provably was not
30
+ * bought, or that the provider will return again for free under the recorded
31
+ * idempotency key, is re-requested under that same identity. Anything else is
32
+ * refused rather than bought a second time.
33
+ */
34
+ export const resumeImageBatchCommand = async (args) => {
35
+ const { batchAttempt, batchAttemptFile, manifestPath, manifestSha256, requests } = args;
36
+ const states = await Promise.all(requests.map((request) => classifyImageGenerationResume({
37
+ outputPath: request.outputPath,
38
+ ...(request.candidateId ? { candidateId: request.candidateId } : {}),
39
+ })));
40
+ const summary = resumeStateSummary(states);
41
+ const candidates = identities(requests);
42
+ if (summary.stageable === 0 && summary.redispatchable === 0 && summary.unrecoverable === 0) {
43
+ // Nothing is outstanding. This is the state the eleven benchmark runs were
44
+ // actually in when they gave up: the batch had finished. Republish the
45
+ // sentinel so the caller can read what it already owns, then refuse — a
46
+ // completed batch is never re-run, because that would be a second purchase.
47
+ const { completionPath, completion } = await publishImageBatchCompletion({
48
+ manifestPath,
49
+ manifestSha256,
50
+ batchAttemptFile,
51
+ provider: batchAttempt.provider,
52
+ model: batchAttempt.model,
53
+ resumed: true,
54
+ status: 'succeeded',
55
+ candidates,
56
+ });
57
+ throw new Error(`Image batch already completed; every candidate is on disk and nothing can be resumed.`
58
+ + ` Re-running it would be a second paid call. Candidates: ${completion.candidates
59
+ .map((candidate) => `${candidate.id} ${candidate.outputPath}`
60
+ + ` sha256=${candidate.sha256 ?? 'unknown'} bytes=${candidate.bytes ?? 0}`)
61
+ .join('; ')}. Completion sentinel: ${completionPath}`);
62
+ }
63
+ const delivered = states.filter((state) => state.disposition === 'stageable');
64
+ await Promise.all(delivered.map((state) => materializeImageGeneration(state.outputPath)));
65
+ const redispatch = states.filter((state) => state.disposition === 'redispatchable');
66
+ const results = [];
67
+ const errors = [];
68
+ if (redispatch.length > 0) {
69
+ const outstanding = new Map(redispatch.map((state) => [state.outputPath, state]));
70
+ const pending = requests.filter((request) => outstanding.has(request.outputPath));
71
+ const preflight = await (args.dependencies.preflight ?? preflightImageProvider)({
72
+ provider: batchAttempt.requestedProvider,
73
+ projectRoot: batchAttempt.projectRoot,
74
+ });
75
+ if (preflight.provider !== batchAttempt.provider) {
76
+ throw new Error(`Refusing to resume with ${preflight.provider} because the batch was dispatched to`
77
+ + ` ${batchAttempt.provider}; switching providers after dispatch is never a resume.`);
78
+ }
79
+ const prepared = await Promise.all(pending.map((request) => (prepareImageGenerationRequest(request, { mode: 'resume' }))));
80
+ const reserved = prepared.map((request) => resumeReservedImageGeneration({
81
+ request,
82
+ preflight,
83
+ attempt: outstanding.get(request.outputPath)?.attempt ?? {
84
+ schemaVersion: 4,
85
+ status: 'prepared',
86
+ idempotencyKey: request.idempotencyKey,
87
+ provider: preflight.provider,
88
+ model: preflight.model,
89
+ providerIdempotencyEnforced: preflight.provider === 'openai',
90
+ providerEvidence: preflight.provider === 'codex'
91
+ ? { codexVersion: preflight.codexVersion }
92
+ : { keySource: preflight.keySource },
93
+ prompt: request.prompt,
94
+ promptSource: request.promptSource,
95
+ promptSha256: request.promptSha256,
96
+ reference: { path: request.reference.path, sha256: request.reference.sha256 },
97
+ referenceMode: request.referenceMode,
98
+ outputPath: request.outputPath,
99
+ preparedAt: new Date().toISOString(),
100
+ },
101
+ }));
102
+ await Promise.all(reserved.map((item) => markImageGenerationDispatched(item)));
103
+ const settled = await Promise.allSettled(reserved.map((item) => (dispatchImageGeneration(item, { generate: args.dependencies.generate }))));
104
+ for (const outcome of settled) {
105
+ if (outcome.status === 'fulfilled')
106
+ results.push(outcome.value);
107
+ else
108
+ errors.push(errorMessage(outcome.reason));
109
+ }
110
+ batchAttempt.accounting = summarizeImageGenerationUsage(reserved.map((item) => item.attempt.usage), preflight.provider);
111
+ }
112
+ await materializeImageBatch(candidates);
113
+ const unrecoverable = states.filter((state) => state.disposition === 'unrecoverable');
114
+ const failed = errors.length > 0 || unrecoverable.length > 0;
115
+ const { completionPath, completion } = await publishImageBatchCompletion({
116
+ manifestPath,
117
+ manifestSha256,
118
+ batchAttemptFile,
119
+ provider: batchAttempt.provider,
120
+ model: batchAttempt.model,
121
+ resumed: true,
122
+ status: failed ? 'failed' : 'succeeded',
123
+ candidates,
124
+ });
125
+ batchAttempt.status = failed ? 'failed' : 'succeeded';
126
+ batchAttempt.completedAt = new Date().toISOString();
127
+ batchAttempt.completionPath = completionPath;
128
+ batchAttempt.resumedAt = [...batchAttempt.resumedAt ?? [], new Date().toISOString()];
129
+ if (results.length > 0)
130
+ batchAttempt.results = [...batchAttempt.results ?? [], ...results];
131
+ if (failed) {
132
+ batchAttempt.errors = [
133
+ ...errors,
134
+ ...unrecoverable.map((state) => describeResumeState(state)),
135
+ ];
136
+ }
137
+ await writeBatchAttempt(batchAttemptFile, batchAttempt);
138
+ if (failed) {
139
+ throw new AggregateError(batchAttempt.errors ?? [], `Image batch resume recovered ${completion.succeededCount} of ${completion.candidateCount}`
140
+ + ` candidate(s) without new spend, and cannot recover the rest.`
141
+ + ` ${describeBatchRecovery(states)}. Give any unrecoverable candidate a new output path and`
142
+ + ` idempotency key to buy it again. Evidence: ${batchAttemptFile}.`
143
+ + ` Completion sentinel: ${completionPath}`);
144
+ }
145
+ console.log(JSON.stringify({
146
+ provider: batchAttempt.provider,
147
+ model: batchAttempt.model,
148
+ manifestPath,
149
+ batchAttemptFile,
150
+ completionPath,
151
+ resumed: true,
152
+ deliveredFromStaging: delivered.length,
153
+ redispatchedWithoutNewSpend: results.length,
154
+ accounting: batchAttempt.accounting,
155
+ candidates: completion.candidates,
156
+ }, null, 2));
157
+ };
158
+ //# sourceMappingURL=cli-image-batch-resume.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-image-batch-resume.js","sourceRoot":"","sources":["../src/cli-image-batch-resume.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"cli-image-command.d.ts","sourceRoot":"","sources":["../src/cli-image-command.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAgB/D,OAAO,EAGL,sBAAsB,EACvB,MAAM,+BAA+B,CAAC;AAoCvC,eAAO,MAAM,eAAe,GAC1B,QAAQ,MAAM,GAAG,SAAS,EAC1B,OAAO,QAAQ,EACf,eAAc;IACZ,QAAQ,CAAC,EAAE,OAAO,aAAa,CAAC;IAChC,SAAS,CAAC,EAAE,OAAO,sBAAsB,CAAC;CACtC,KACL,OAAO,CAAC,IAAI,CA0Dd,CAAC"}
1
+ {"version":3,"file":"cli-image-command.d.ts","sourceRoot":"","sources":["../src/cli-image-command.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAiB/D,OAAO,EAGL,sBAAsB,EACvB,MAAM,+BAA+B,CAAC;AAoCvC,eAAO,MAAM,eAAe,GAC1B,QAAQ,MAAM,GAAG,SAAS,EAC1B,OAAO,QAAQ,EACf,eAAc;IACZ,QAAQ,CAAC,EAAE,OAAO,aAAa,CAAC;IAChC,SAAS,CAAC,EAAE,OAAO,sBAAsB,CAAC;CACtC,KACL,OAAO,CAAC,IAAI,CAoEd,CAAC"}
@@ -3,6 +3,7 @@ import path from 'node:path';
3
3
  import { stringFlag } from './cli-arguments.js';
4
4
  import { dispatchImageGeneration, markImageGenerationDispatched, reserveImageGeneration, } from './image-generation-run.js';
5
5
  import { IMAGE_GENERATION_ASPECTS, IMAGE_GENERATION_REFERENCE_MODES, isImageGenerationAspect, isImageGenerationReferenceMode, prepareImageGenerationRequest, } from './image-generation-request.js';
6
+ import { materializeImageGeneration } from './image-generation-staging.js';
6
7
  import { IMAGE_GENERATION_PROVIDERS, isImageGenerationProvider, preflightImageProvider, } from './image-provider-preflight.js';
7
8
  import { normalizeOptionalIdempotencyKey } from './idempotency-key.js';
8
9
  const referenceFlag = (flags) => {
@@ -86,7 +87,18 @@ export const runImageCommand = async (action, flags, dependencies = {}) => {
86
87
  });
87
88
  const reserved = await reserveImageGeneration({ request, preflight });
88
89
  await markImageGenerationDispatched(reserved);
89
- const result = await dispatchImageGeneration(reserved, { generate: dependencies.generate });
90
- console.log(JSON.stringify(result, null, 2));
90
+ try {
91
+ const result = await dispatchImageGeneration(reserved, { generate: dependencies.generate });
92
+ // The PNG and its completed ledger entry appear together. Until this
93
+ // returns, the destination directory holds neither.
94
+ await materializeImageGeneration(outputPath);
95
+ console.log(JSON.stringify(result, null, 2));
96
+ }
97
+ catch (error) {
98
+ // Terminal failures still owe the caller their evidence at the documented
99
+ // path, even though there is no image to deliver.
100
+ await materializeImageGeneration(outputPath).catch(() => undefined);
101
+ throw error;
102
+ }
91
103
  };
92
104
  //# sourceMappingURL=cli-image-command.js.map