@bitmagic/cli 0.1.35 → 0.1.37

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.
@@ -1,3 +1,4 @@
1
+ import type { ForgeProgressSnapshot } from '../forge/progress.js';
1
2
  /** Which command is running. Shown as-is in the dev view, so these are creator-facing words. */
2
3
  export type JobKind = 'skybox' | 'sound' | 'image' | 'character' | 'animation' | 'prop' | 'vehicle' | 'forge' | 'cover' | 'hq';
3
4
  export interface JobRecord {
@@ -10,6 +11,16 @@ export interface JobRecord {
10
11
  status: 'running' | 'failed';
11
12
  /** The generation's most recent progress line. See `withJobRecord`. */
12
13
  message: string;
14
+ /**
15
+ * Structured progress, for the one kind that has any: a forge's five steps, how far through the
16
+ * current one is, and what the level being built contains.
17
+ *
18
+ * Optional because it is a forge-only enrichment of {@link message}, never a replacement for it —
19
+ * every other kind has a single sentence and nothing more to say, and a reader (a `bitmagic dev`
20
+ * from an older install, or the creator's agent reading this directory by hand) must still make
21
+ * sense of a record without it.
22
+ */
23
+ progress?: ForgeProgressSnapshot;
13
24
  pid: number;
14
25
  startedAt: string;
15
26
  updatedAt: string;
@@ -26,6 +37,18 @@ export declare function jobsDirPath(root: string): string;
26
37
  * not worth failing a read that also carries five healthy ones.
27
38
  */
28
39
  export declare function readJobs(root: string): JobRecord[];
40
+ /**
41
+ * What the dev view shows: the generations still working.
42
+ *
43
+ * A failed job leaves the panel exactly the way a successful one does — by disappearing — and the
44
+ * difference between them shows up where it means something to the person seeing it. The creator
45
+ * gets an asset, or does not; the agent gets the reason, on the terminal where it can act on it.
46
+ * See the header for why the reason does not belong in both places.
47
+ *
48
+ * Dead `running` records drop out here too, because `readJobs` reports them as failed. That is what
49
+ * stops a SIGKILLed generation spinning in the panel for the rest of the session.
50
+ */
51
+ export declare function readRunningJobs(root: string): JobRecord[];
29
52
  /**
30
53
  * Drop failed records older than a day. Called by `dev` at startup rather than on a timer: this is
31
54
  * housekeeping, and the moment someone opens the dev view is the moment a day-old failure stops
@@ -36,7 +59,11 @@ export interface JobHandle {
36
59
  readonly jobId: string;
37
60
  /** Record the latest progress line. */
38
61
  update(message: string): void;
62
+ /** Record structured progress alongside the line. Only a forge has any; see {@link JobRecord}. */
63
+ setProgress(progress: ForgeProgressSnapshot): void;
39
64
  }
65
+ /** What a body reports structured progress through. A no-op when the record could not be started. */
66
+ export type JobProgressReporter = (progress: ForgeProgressSnapshot) => void;
40
67
  export interface StartJobOptions {
41
68
  root: string;
42
69
  kind: JobKind;
@@ -53,6 +80,12 @@ export declare function startJob(options: StartJobOptions): JobHandle;
53
80
  * way since it shipped, and it means a command gains live progress in the dev view without a single
54
81
  * new call site inside it.
55
82
  *
83
+ * The SECOND argument is for the one command that has more than a sentence to say. A forge runs
84
+ * for half an hour across five steps on two machines, and a line-at-a-time record can only ever
85
+ * show the most recent one — so `forge` also reports a snapshot of all five (see
86
+ * `forge/progress.ts`). Every other caller ignores this parameter, which is the point: the log tap
87
+ * above stays the default, and structured progress is opt-in for the kind that needs it.
88
+ *
56
89
  * **Never fails the generation it is watching.** Bookkeeping that breaks a paid, minutes-long
57
90
  * generation would be a far worse bug than the missing progress line it is trying to provide, so
58
91
  * every filesystem error here is swallowed. The body's own errors propagate untouched, after being
@@ -60,7 +93,7 @@ export declare function startJob(options: StartJobOptions): JobHandle;
60
93
  */
61
94
  export declare function withJobRecord<T>(options: StartJobOptions & {
62
95
  log: (message: string) => void;
63
- }, body: (log: (message: string) => void) => Promise<T>): Promise<T>;
96
+ }, body: (log: (message: string) => void, report: JobProgressReporter) => Promise<T>): Promise<T>;
64
97
  /** Success: the asset is in world.json, and that is the record. */
65
98
  export declare function removeJob(root: string, jobId: string): void;
66
99
  /** Failure: nothing else records it, so the record stays and carries the reason. */
@@ -19,14 +19,21 @@
19
19
  * `cat` this directory to see what it has in flight. The dev sidecar watches the directory, so the
20
20
  * latency is a filesystem event, not a poll.
21
21
  *
22
- * ── Removed on success, kept on failure ──────────────────────────────────────────────────────
22
+ * ── Removed on success, kept on failure — and a failure is for the agent, not the creator ────
23
23
  *
24
24
  * A finished asset is in `world.json`, and that IS the completion record — the browser reloads
25
25
  * because the file changed, and the asset appears in the panel. A record left behind saying "done"
26
26
  * would be a second, staler source of truth for the same fact.
27
27
  *
28
- * A failure is the opposite: nothing else records it. `world.json` is untouched, so the panel would
29
- * simply show a job vanishing with no asset ever appearing. The record stays, carrying the error.
28
+ * A failed record is kept, but the dev view does not render it. What a generation fails with is a
29
+ * tool diagnostic `Unknown preset "?". Valid: SEDAN, HATCHBACK, …` addressed to whoever chose
30
+ * the arguments, actionable only by them, and already printed on their terminal by the command that
31
+ * exited non-zero. In an agent-driven session that reader is the agent. Repeating the same text as a
32
+ * red card beside the creator's game hands them an enum list they can do nothing with, in the one
33
+ * window that is supposed to be about the game rather than the toolchain.
34
+ *
35
+ * So `readRunningJobs` is what the sidecar serves, and the record stays on disk for the agent to
36
+ * `cat` and for `pruneJobs` to age out.
30
37
  *
31
38
  * ── Staleness is the reader's problem ────────────────────────────────────────────────────────
32
39
  *
@@ -43,7 +50,7 @@ import * as fs from 'fs';
43
50
  import * as path from 'path';
44
51
  import { isProcessAlive, readDevHandle } from './dev-handle.js';
45
52
  export const JOBS_DIR = path.join('.bitmagic', 'jobs');
46
- /** Failed records are kept so the creator can see why nothing appeared — but not forever. */
53
+ /** Failed records are kept for the agent to read back — but not forever. */
47
54
  const FAILED_RECORD_TTL_MS = 24 * 60 * 60 * 1000;
48
55
  export function jobsDirPath(root) {
49
56
  return path.join(root, JOBS_DIR);
@@ -76,6 +83,40 @@ function writeRecord(root, record) {
76
83
  function isRecord(value) {
77
84
  return typeof value === 'object' && value !== null && !Array.isArray(value);
78
85
  }
86
+ /**
87
+ * Read a progress snapshot off a record, or `undefined` when there is not a well-formed one.
88
+ *
89
+ * These files cross a process boundary and a VERSION boundary — the writer is whichever
90
+ * `bitmagic` binary started the generation, the reader is whichever `bitmagic dev` happens to be
91
+ * running — so the field is treated as untrusted input rather than as something this build wrote.
92
+ * Dropping it is the right degradation and matches the rest of this file: the record still carries
93
+ * its `message`, so a reader that cannot make sense of the steps falls back to the sentence.
94
+ *
95
+ * `summary` is passed through unshaped on purpose. It is display-only, every field is optional,
96
+ * and its contents are the pipeline's schema, not this file's — re-deriving that shape here would
97
+ * be a second copy to keep in step for no invariant worth protecting.
98
+ */
99
+ function parseProgress(value) {
100
+ if (!isRecord(value) || !Array.isArray(value.steps))
101
+ return undefined;
102
+ const steps = value.steps.filter((step) => isRecord(step) && typeof step.key === 'string' && typeof step.label === 'string'
103
+ && (step.status === 'pending' || step.status === 'running' || step.status === 'done'));
104
+ if (steps.length === 0)
105
+ return undefined;
106
+ return {
107
+ steps: steps.map((step) => ({
108
+ key: step.key,
109
+ label: step.label,
110
+ status: step.status,
111
+ ...(typeof step.durationMs === 'number' ? { durationMs: step.durationMs } : {}),
112
+ ...(typeof step.completed === 'number' ? { completed: step.completed } : {}),
113
+ ...(typeof step.total === 'number' ? { total: step.total } : {}),
114
+ ...(typeof step.detail === 'string' ? { detail: step.detail } : {}),
115
+ ...(step.resumed === true ? { resumed: true } : {}),
116
+ })),
117
+ ...(isRecord(value.summary) ? { summary: value.summary } : {}),
118
+ };
119
+ }
79
120
  function parseRecord(raw) {
80
121
  let parsed;
81
122
  try {
@@ -89,6 +130,7 @@ function parseRecord(raw) {
89
130
  const { jobId, kind, label, status, message, pid, startedAt, updatedAt } = parsed;
90
131
  if (typeof jobId !== 'string' || typeof kind !== 'string' || typeof pid !== 'number')
91
132
  return null;
133
+ const progress = parseProgress(parsed.progress);
92
134
  return {
93
135
  jobId,
94
136
  kind: kind,
@@ -96,6 +138,7 @@ function parseRecord(raw) {
96
138
  ...(typeof parsed.assetId === 'string' ? { assetId: parsed.assetId } : {}),
97
139
  status: status === 'failed' ? 'failed' : 'running',
98
140
  message: typeof message === 'string' ? message : '',
141
+ ...(progress ? { progress } : {}),
99
142
  pid,
100
143
  startedAt: typeof startedAt === 'string' ? startedAt : '',
101
144
  updatedAt: typeof updatedAt === 'string' ? updatedAt : '',
@@ -144,6 +187,20 @@ export function readJobs(root) {
144
187
  }
145
188
  return jobs.sort((a, b) => b.startedAt.localeCompare(a.startedAt));
146
189
  }
190
+ /**
191
+ * What the dev view shows: the generations still working.
192
+ *
193
+ * A failed job leaves the panel exactly the way a successful one does — by disappearing — and the
194
+ * difference between them shows up where it means something to the person seeing it. The creator
195
+ * gets an asset, or does not; the agent gets the reason, on the terminal where it can act on it.
196
+ * See the header for why the reason does not belong in both places.
197
+ *
198
+ * Dead `running` records drop out here too, because `readJobs` reports them as failed. That is what
199
+ * stops a SIGKILLed generation spinning in the panel for the rest of the session.
200
+ */
201
+ export function readRunningJobs(root) {
202
+ return readJobs(root).filter((job) => job.status === 'running');
203
+ }
147
204
  /**
148
205
  * Drop failed records older than a day. Called by `dev` at startup rather than on a timer: this is
149
206
  * housekeeping, and the moment someone opens the dev view is the moment a day-old failure stops
@@ -227,12 +284,19 @@ export function startJob(options) {
227
284
  updatedAt: now,
228
285
  };
229
286
  writeRecord(options.root, record);
287
+ const touch = () => {
288
+ record.updatedAt = new Date().toISOString();
289
+ writeRecord(options.root, record);
290
+ };
230
291
  return {
231
292
  jobId: record.jobId,
232
293
  update: (message) => {
233
294
  record.message = message;
234
- record.updatedAt = new Date().toISOString();
235
- writeRecord(options.root, record);
295
+ touch();
296
+ },
297
+ setProgress: (progress) => {
298
+ record.progress = progress;
299
+ touch();
236
300
  },
237
301
  };
238
302
  }
@@ -245,6 +309,12 @@ export function startJob(options) {
245
309
  * way since it shipped, and it means a command gains live progress in the dev view without a single
246
310
  * new call site inside it.
247
311
  *
312
+ * The SECOND argument is for the one command that has more than a sentence to say. A forge runs
313
+ * for half an hour across five steps on two machines, and a line-at-a-time record can only ever
314
+ * show the most recent one — so `forge` also reports a snapshot of all five (see
315
+ * `forge/progress.ts`). Every other caller ignores this parameter, which is the point: the log tap
316
+ * above stays the default, and structured progress is opt-in for the kind that needs it.
317
+ *
248
318
  * **Never fails the generation it is watching.** Bookkeeping that breaks a paid, minutes-long
249
319
  * generation would be a far worse bug than the missing progress line it is trying to provide, so
250
320
  * every filesystem error here is swallowed. The body's own errors propagate untouched, after being
@@ -268,8 +338,16 @@ export async function withJobRecord(options, body) {
268
338
  // Same.
269
339
  }
270
340
  };
341
+ const report = (progress) => {
342
+ try {
343
+ handle?.setProgress(progress);
344
+ }
345
+ catch {
346
+ // Same.
347
+ }
348
+ };
271
349
  try {
272
- const result = await body(log);
350
+ const result = await body(log, report);
273
351
  if (handle)
274
352
  removeJob(options.root, handle.jobId);
275
353
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../src/project/jobs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../src/project/jobs.ts"],"names":[],"mappings":"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"}
@@ -554,12 +554,12 @@ alone:
554
554
  - **An image pasted into the conversation is probably a frame from their running game.** The dev
555
555
  view has a Screenshot button that copies the current frame to the clipboard, so "look at this"
556
556
  usually means the game as it is right now — not a reference or a mock-up.
557
- - **They can watch your generations happen.** Every \`bitmagic generate\` and \`bitmagic forge\`
558
- records itself in \`.bitmagic/jobs/\` while it runs, and the dev view lists those with your
559
- progress lines and the prompt you used. So "what is it doing now?" already has an answer on their
560
- screen, and a prompt you would not want read aloud is not a good prompt. The same files are
561
- readable by you: check \`.bitmagic/jobs/\` before starting a second expensive generation, because
562
- a forge and a prop each want a headless browser and will fight over one.
557
+ - **They can watch your generations happen — but not your failures.** Every \`bitmagic generate\`
558
+ and \`bitmagic forge\` records itself in \`.bitmagic/jobs/\` while it runs, and the dev view lists
559
+ those with your progress lines and the prompt you used. One that FAILS simply drops off that list,
560
+ with the error reaching your terminal and nowhere else so a failure you do not mention is one
561
+ they never learn about. Those files are yours to read too: check them before starting a second
562
+ expensive generation, because a forge and a prop each want a headless browser and will fight over one.
563
563
  - Prefer changing the entries you mean to change over regenerating \`environmentObjects\`
564
564
  wholesale, so their placements survive your edit.
565
565
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitmagic/cli",
3
- "version": "0.1.35",
3
+ "version": "0.1.37",
4
4
  "description": "Build Bitmagic games from your own agent tool",
5
5
  "type": "module",
6
6
  "bin": {
@@ -19,8 +19,8 @@
19
19
  "citty": "^0.2.2",
20
20
  "playwright-core": "^1.59.1",
21
21
  "tar": "^7.4.3",
22
- "@bitmagic/world-forger": "0.1.3",
23
- "@bitmagic/asset-core": "0.1.2"
22
+ "@bitmagic/asset-core": "0.1.2",
23
+ "@bitmagic/world-forger": "0.1.4"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@eslint/js": "^9.38.0",
@@ -1,44 +0,0 @@
1
- /**
2
- * Terminal progress for the level bake.
3
- *
4
- * The bake is the one step that can legitimately run for many minutes, and its transport wait is
5
- * an IDLE timeout of 20 minutes (`VOXELIZE_TIMEOUT_MS`) — per-chunk progress re-arms the timer but
6
- * is otherwise consumed silently inside the transport. Without a printed line a creator watching a
7
- * still terminal concludes the command has hung and kills it mid-bake, losing the whole step. So
8
- * the command subscribes to the page's own `VOXELIZE_GLB_AS_LEVEL_PROGRESS` messages
9
- * (`game/src/engine/template/VoxelMessageHandlers.ts`) and prints them.
10
- *
11
- * Throttled, because the engine emits one message per chunk and a large level has thousands: an
12
- * unthrottled relay would bury every other line of output. The formatter and the throttle are pure
13
- * and separate from the subscription so both are testable without a browser.
14
- */
15
- /** The engine's per-chunk progress payload. `chunkIndex: -1` marks the post-bake upload phase. */
16
- export interface BakeProgress {
17
- chunkIndex: number;
18
- totalChunks: number;
19
- nonEmptyChunks?: number;
20
- label?: string;
21
- }
22
- export declare const BAKE_PROGRESS_TYPE = "VOXELIZE_GLB_AS_LEVEL_PROGRESS";
23
- /** Minimum gap between printed bake lines. Long enough not to flood, short enough that the
24
- * terminal never looks frozen. */
25
- export declare const BAKE_PROGRESS_MIN_INTERVAL_MS = 3000;
26
- /** Read a bake-progress payload off a page message, or null if it is not one. */
27
- export declare function asBakeProgress(message: unknown): BakeProgress | null;
28
- /**
29
- * The line to print for one progress message.
30
- *
31
- * `chunkIndex: -1` / `totalChunks: -1` is the engine's sentinel for the upload phase that follows
32
- * the chunk loop; it carries a label instead of a count, so it is rendered as that label rather
33
- * than as a nonsensical "chunk -1 of -1".
34
- */
35
- export declare function formatBakeProgress(progress: BakeProgress): string;
36
- /**
37
- * A printer that emits at most one line per `minIntervalMs` — except for the final chunk and the
38
- * label-only phases, which always print. The last chunk is what tells a creator the loop finished
39
- * rather than stalled, so dropping it to a throttle would remove the single most informative line.
40
- */
41
- export declare function createBakeProgressPrinter(log: (message: string) => void, options?: {
42
- minIntervalMs?: number;
43
- now?: () => number;
44
- }): (message: unknown) => void;
@@ -1,77 +0,0 @@
1
- /**
2
- * Terminal progress for the level bake.
3
- *
4
- * The bake is the one step that can legitimately run for many minutes, and its transport wait is
5
- * an IDLE timeout of 20 minutes (`VOXELIZE_TIMEOUT_MS`) — per-chunk progress re-arms the timer but
6
- * is otherwise consumed silently inside the transport. Without a printed line a creator watching a
7
- * still terminal concludes the command has hung and kills it mid-bake, losing the whole step. So
8
- * the command subscribes to the page's own `VOXELIZE_GLB_AS_LEVEL_PROGRESS` messages
9
- * (`game/src/engine/template/VoxelMessageHandlers.ts`) and prints them.
10
- *
11
- * Throttled, because the engine emits one message per chunk and a large level has thousands: an
12
- * unthrottled relay would bury every other line of output. The formatter and the throttle are pure
13
- * and separate from the subscription so both are testable without a browser.
14
- */
15
- export const BAKE_PROGRESS_TYPE = 'VOXELIZE_GLB_AS_LEVEL_PROGRESS';
16
- /** Minimum gap between printed bake lines. Long enough not to flood, short enough that the
17
- * terminal never looks frozen. */
18
- export const BAKE_PROGRESS_MIN_INTERVAL_MS = 3000;
19
- function isRecord(value) {
20
- return typeof value === 'object' && value !== null;
21
- }
22
- /** Read a bake-progress payload off a page message, or null if it is not one. */
23
- export function asBakeProgress(message) {
24
- if (!isRecord(message) || message.type !== BAKE_PROGRESS_TYPE)
25
- return null;
26
- const { chunkIndex, totalChunks } = message;
27
- if (typeof chunkIndex !== 'number' || typeof totalChunks !== 'number')
28
- return null;
29
- return {
30
- chunkIndex,
31
- totalChunks,
32
- ...(typeof message.nonEmptyChunks === 'number' ? { nonEmptyChunks: message.nonEmptyChunks } : {}),
33
- ...(typeof message.label === 'string' ? { label: message.label } : {}),
34
- };
35
- }
36
- /**
37
- * The line to print for one progress message.
38
- *
39
- * `chunkIndex: -1` / `totalChunks: -1` is the engine's sentinel for the upload phase that follows
40
- * the chunk loop; it carries a label instead of a count, so it is rendered as that label rather
41
- * than as a nonsensical "chunk -1 of -1".
42
- */
43
- export function formatBakeProgress(progress) {
44
- if (progress.totalChunks <= 0) {
45
- return ` bake: ${progress.label ?? 'working…'}`;
46
- }
47
- const percent = Math.floor(((progress.chunkIndex + 1) / progress.totalChunks) * 100);
48
- const filled = progress.nonEmptyChunks !== undefined ? `, ${progress.nonEmptyChunks} non-empty` : '';
49
- const label = progress.label ? ` — ${progress.label}` : '';
50
- return ` bake: chunk ${progress.chunkIndex + 1}/${progress.totalChunks} (${percent}%${filled})${label}`;
51
- }
52
- /**
53
- * A printer that emits at most one line per `minIntervalMs` — except for the final chunk and the
54
- * label-only phases, which always print. The last chunk is what tells a creator the loop finished
55
- * rather than stalled, so dropping it to a throttle would remove the single most informative line.
56
- */
57
- export function createBakeProgressPrinter(log, options = {}) {
58
- const minIntervalMs = options.minIntervalMs ?? BAKE_PROGRESS_MIN_INTERVAL_MS;
59
- const now = options.now ?? (() => Date.now());
60
- // -Infinity, not 0: the FIRST message must always print. A zero start throttles it whenever
61
- // `now()` begins near zero — which a monotonic clock does, and which is exactly the moment the
62
- // creator most needs to see that the bake has begun.
63
- let lastAt = -Infinity;
64
- return (message) => {
65
- const progress = asBakeProgress(message);
66
- if (progress === null)
67
- return;
68
- const isFinalChunk = progress.totalChunks > 0 && progress.chunkIndex + 1 >= progress.totalChunks;
69
- const isPhaseLabel = progress.totalChunks <= 0;
70
- const at = now();
71
- if (!isFinalChunk && !isPhaseLabel && at - lastAt < minIntervalMs)
72
- return;
73
- lastAt = at;
74
- log(formatBakeProgress(progress));
75
- };
76
- }
77
- //# sourceMappingURL=bake-progress.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bake-progress.js","sourceRoot":"","sources":["../../src/forge/bake-progress.ts"],"names":[],"mappings":"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"}