@bitmagic/cli 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,140 @@
1
+ # @bitmagic/cli
2
+
3
+ Build Bitmagic games from your own agent tool (Claude Code, Codex, OpenCode, ...) instead of the
4
+ web Creator UI. `bitmagic init` scaffolds a project with the engine vendored in as source, your
5
+ agent edits `src/work/`, and `bitmagic verify` / `bitmagic publish` take it to bitmagic.ai — no
6
+ web project or per-session pod required.
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npm install -g @bitmagic/cli
12
+ bitmagic --version
13
+ ```
14
+
15
+ ## Quick start
16
+
17
+ ```bash
18
+ bitmagic login # device-code auth in your browser
19
+ bitmagic init my-game # scaffold a new project into ./my-game
20
+ cd my-game
21
+ bitmagic check # typecheck against the vendored engine
22
+ bitmagic dev # build, then serve with live rebuilds
23
+ bitmagic verify # boot the game in a real browser and report what broke
24
+ bitmagic publish # verify-gate, build, and ship — private by default
25
+ ```
26
+
27
+ ## Commands
28
+
29
+ | Command | What it does |
30
+ |---|---|
31
+ | `bitmagic login [--env <env>]` | Device-code auth against Auth0; stores credentials per environment. |
32
+ | `bitmagic logout [--env <env>]` | Remove stored credentials for an environment. |
33
+ | `bitmagic whoami [--env <env>]` | Show the identity the CLI is authenticated as. |
34
+ | `bitmagic init [dir] [--template <id>] [--name <name>] [--env <env>] [--force]` | Scaffold a new project: mints a game, downloads the vendored engine, writes `AGENTS.md` and templates. |
35
+ | `bitmagic check` | Typecheck (`tsc --noEmit`) against the vendored engine. Fast; does not prove the game runs. |
36
+ | `bitmagic dev [--port <port>]` | Build, then serve with `tsc --watch` + `vite`, default port 3010. |
37
+ | `bitmagic verify [--timeout <ms>]` | Build, boot the game in a headless browser, and report what broke. Writes the artifacts the publish gate reads (see below). |
38
+ | `bitmagic build` | Bundle the game into one self-contained `.bitmagic/build/index.html`. Rarely needs to be run by hand — `publish` builds automatically when the project changed. |
39
+ | `bitmagic publish [--visibility public\|private] [--name <name>] [--description <desc>] [--force]` | Verify-gate, build if needed, and upload straight to GCS. **Private unless `--visibility public` is passed.** |
40
+ | `bitmagic upgrade [--engine <version>] [--force]` | Refresh vendored platform files to the currently published engine. Refuses a dirty git tree unless `--force`. |
41
+ | `bitmagic generate <skybox\|sound\|image\|character\|animation> ...` | Generate one asset directly into `src/work/world.json`. Costs sparks. |
42
+ | `bitmagic forge --prompt "..." [--city\|--dungeon\|--platformer\|--freeform] [--name <name>] [--resume <jobId>]` | Design and bake a whole playable level into `world.json`. Slow and expensive; supports `--resume`. |
43
+
44
+ Every command exits non-zero on failure with a single-line message (no stack trace) and, where a
45
+ distinction is useful to an automated caller, a specific exit code — see **Exit codes** below.
46
+
47
+ ## Environments
48
+
49
+ `--env` accepts `dev`, `prod`, or `local`. The environment used at `login` becomes the stored
50
+ default for subsequent commands until you log in to a different one.
51
+
52
+ ## Project layout and artifacts
53
+
54
+ ```
55
+ my-game/
56
+ src/work/ # your game — Game.ts, game.json, world.json
57
+ engine/ # vendored engine, read-only, replaced wholesale by `bitmagic upgrade`
58
+ AGENTS.md # guidance for the agent editing this project
59
+ .bitmagic/
60
+ build/
61
+ index.html # bitmagic build's output bundle
62
+ manifest.json # engineVersion, fingerprint, bytes, sha256, builtAt
63
+ verify/
64
+ result.json # bitmagic verify's verdict — ok, failures, warnings, fingerprint, at
65
+ screenshot.png # becomes the publish thumbnail
66
+ console.log # captured browser console output
67
+ ```
68
+
69
+ ## Publishing
70
+
71
+ `bitmagic publish` is two gated steps in one command:
72
+
73
+ 1. **The verify gate.** Publish refuses to run unless `.bitmagic/verify/result.json` records a
74
+ passing run of the **current** project state. "Current" is decided by a content fingerprint —
75
+ a hash of your project's files — not a timestamp: editing any file after verifying makes the
76
+ record stale immediately, while an unmodified project stays fresh no matter how much time has
77
+ passed. There is no way to check freshness except running `bitmagic verify` again.
78
+ `.git/`, `node_modules/`, `dist/`, `.bitmagic/` and `.vite-cache/` are excluded, so committing
79
+ between `bitmagic verify` and `bitmagic publish` does **not** invalidate the verify.
80
+ 2. **The build.** If the project has changed since the last `.bitmagic/build/manifest.json`,
81
+ publish rebuilds automatically; a prior manual `bitmagic build` is never required, only useful
82
+ if you want to inspect `.bitmagic/build/index.html` before it ships.
83
+
84
+ **Publishing does not make a game public.** Every `bitmagic publish` uploads and registers the
85
+ game, but by default `visibility` is `private` — reachable by URL, not listed anywhere on
86
+ bitmagic.ai. You must pass `--visibility public` explicitly, every time you want the game listed;
87
+ omitting it on a later publish makes it private again — and takes the game's `/play/` page out of
88
+ service, so a previously-public game re-published bare is gone from bitmagic.ai until you publish
89
+ publicly again.
90
+
91
+ `--force` overrides a **stale or failed** verify verdict. It does **not** override a missing
92
+ verify record — publish's thumbnail comes from the verify screenshot, so `bitmagic verify` must
93
+ have produced at least one `.bitmagic/verify/screenshot.png`, ever, before `--force` has anything
94
+ to work with.
95
+
96
+ `--name` and `--description` apply to that one publish call only. They are never written back to
97
+ `src/work/game.json`, so pass them again on every future `bitmagic publish` if you want them to
98
+ stick — and note that writing them into `game.json` yourself would change the fingerprint and
99
+ invalidate the verify you just checked.
100
+
101
+ ### Exit codes
102
+
103
+ `bitmagic publish` uses these to let a script or agent branch without parsing the message:
104
+
105
+ | Code | Meaning |
106
+ |---|---|
107
+ | 1 | Build failed |
108
+ | 2 | Not logged in |
109
+ | 3 | Verify missing, stale, or failed |
110
+ | 4 | Engine below the publish floor |
111
+ | 5 | Not the game's owner, or the account/game is banned |
112
+ | 6 | Upload or finalize failed — usually transient (network/storage), but also covers permanent failures such as an unknown game or a rejected request. Retry once; if it fails identically, stop and report it. |
113
+
114
+ `bitmagic build` alone exits 1 on a build failure and 0 on success.
115
+
116
+ ## Upgrading
117
+
118
+ `bitmagic upgrade` refreshes the vendored `engine/`, the generated config files, and `index.html`
119
+ to the currently published engine version. It never touches `src/`, `world.json`, `game.json`,
120
+ `package.json`, or the agent guidance files (`AGENTS.md`, `CLAUDE.md`, `.claude/skills/`) — those
121
+ are yours. It refuses to run against a dirty git working tree unless `--force`, so the upgrade
122
+ always shows up as its own reviewable diff.
123
+
124
+ `upgrade` **reports** missing or outdated dependencies rather than installing them — it prints the
125
+ exact install command to run, using your project's own package manager (detected from
126
+ `pnpm-lock.yaml` / `yarn.lock`, defaulting to npm). A project scaffolded before a dependency was
127
+ added needs that command run once before `bitmagic build` (and therefore `bitmagic publish`) will
128
+ work.
129
+
130
+ A project scaffolded before `vite.publish.config.js` existed cannot be bundled at all: `bitmagic
131
+ build` stops with a message naming `bitmagic upgrade`, which vendors the file without touching
132
+ your game code. Run the printed install command afterwards if `upgrade` reports missing
133
+ dependencies too.
134
+
135
+ ## Development
136
+
137
+ ```bash
138
+ pnpm run check # lint + typecheck (from cli/, or from the repo root for every project)
139
+ pnpm test # jest
140
+ ```
@@ -6,7 +6,7 @@ const EXPIRY_SKEW_MS = 60_000;
6
6
  export async function getAccessToken(environment, clientId, deps, baseDir = defaultBaseDir()) {
7
7
  const stored = readCredentials(environment.name, baseDir);
8
8
  if (!stored) {
9
- throw new CliError(`You are not logged in to the "${environment.name}" environment. Run \`bitmagic login\`.`);
9
+ throw new CliError(`You are not logged in to the "${environment.name}" environment. Run \`bitmagic login\`.`, 2);
10
10
  }
11
11
  const now = deps.now ?? Date.now;
12
12
  if (stored.expiresAt - EXPIRY_SKEW_MS > now()) {
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC7F,OAAO,EAAE,kBAAkB,EAAuB,MAAM,kBAAkB,CAAC;AAE3E,oEAAoE;AACpE,MAAM,cAAc,GAAG,MAAM,CAAC;AAE9B,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,WAAwB,EACxB,QAAgB,EAChB,IAAoB,EACpB,UAAkB,cAAc,EAAE;IAElC,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,QAAQ,CAChB,iCAAiC,WAAW,CAAC,IAAI,wCAAwC,CAC1F,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACjC,IAAI,MAAM,CAAC,SAAS,GAAG,cAAc,GAAG,GAAG,EAAE,EAAE,CAAC;QAC9C,OAAO,MAAM,CAAC,WAAW,CAAC;IAC5B,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAC7F,gBAAgB,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACvD,OAAO,SAAS,CAAC,WAAW,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC7F,OAAO,EAAE,kBAAkB,EAAuB,MAAM,kBAAkB,CAAC;AAE3E,oEAAoE;AACpE,MAAM,cAAc,GAAG,MAAM,CAAC;AAE9B,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,WAAwB,EACxB,QAAgB,EAChB,IAAoB,EACpB,UAAkB,cAAc,EAAE;IAElC,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,QAAQ,CAChB,iCAAiC,WAAW,CAAC,IAAI,wCAAwC,EACzF,CAAC,CACF,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACjC,IAAI,MAAM,CAAC,SAAS,GAAG,cAAc,GAAG,GAAG,EAAE,EAAE,CAAC;QAC9C,OAAO,MAAM,CAAC,WAAW,CAAC;IAC5B,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAC7F,gBAAgB,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACvD,OAAO,SAAS,CAAC,WAAW,CAAC;AAC/B,CAAC"}
package/dist/cli.d.ts CHANGED
@@ -104,6 +104,24 @@ declare const rawCommands: {
104
104
  readonly description: "Build a custom place (arena, fortress, camp).";
105
105
  };
106
106
  }>;
107
+ publish: CommandDef<{
108
+ readonly visibility: {
109
+ readonly type: "string";
110
+ readonly description: "\"public\" or \"private\" (default). Public also requires an unbanned profile.";
111
+ };
112
+ readonly name: {
113
+ readonly type: "string";
114
+ readonly description: "Override the published name for this publish only — never written to game.json.";
115
+ };
116
+ readonly description: {
117
+ readonly type: "string";
118
+ readonly description: "Override the published description for this publish only — never written to game.json.";
119
+ };
120
+ readonly force: {
121
+ readonly type: "boolean";
122
+ readonly description: "Publish despite a stale or failed verify. Does NOT bypass a missing verify record.";
123
+ };
124
+ }>;
107
125
  };
108
126
  type CommandName = keyof typeof rawCommands;
109
127
  export declare const subCommands: Record<CommandName, CommandDef<ArgsDef>>;
package/dist/cli.js CHANGED
@@ -11,6 +11,7 @@ import { verifyCommand } from './commands/verify.js';
11
11
  import { buildCommand } from './commands/build.js';
12
12
  import { generateCommand } from './commands/generate.js';
13
13
  import { forgeCommand } from './commands/forge.js';
14
+ import { publishCommand } from './commands/publish.js';
14
15
  // citty's runMain() catches every error thrown from a command's `run()` internally and calls
15
16
  // process.exit() itself — it never rejects the promise it returns, so the `.catch()` below
16
17
  // never runs for those. For anything that isn't citty's own internal CLIError class, its catch
@@ -96,6 +97,7 @@ const rawCommands = {
96
97
  build: buildCommand,
97
98
  generate: generateCommand,
98
99
  forge: forgeCommand,
100
+ publish: publishCommand,
99
101
  };
100
102
  export const subCommands = Object.fromEntries(Object.entries(rawCommands).map(([name, command]) => [name, withCleanErrors(command)]));
101
103
  // This module only builds `main` and exports it (along with `subCommands` and `withCleanErrors`)
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { type BuildManifest } from '../publish/bundle.js';
2
+ /** `'public' | 'private'`, defaulting to private — a typo is rejected rather than silently
3
+ * coerced, matching the server's own asymmetric contract (see cli-publish.ts). */
4
+ export declare function resolveVisibility(raw: string | undefined): 'public' | 'private';
5
+ export interface PublishRunDeps {
6
+ fetch: typeof globalThis.fetch;
7
+ sleep: (ms: number) => Promise<void>;
8
+ /** Test-only override; production omits it and loadProjectContext walks up from process.cwd(). */
9
+ startDir?: string;
10
+ /** Test-only override; production omits it and the credential helpers read ~/.bitmagic. */
11
+ baseDir?: string;
12
+ log: (message: string) => void;
13
+ /** Injectable so a test can assert reuse-vs-rebuild without a real tsc/vite toolchain. */
14
+ runBuild: (root: string, engineVersion: string) => BuildManifest;
15
+ readBuildManifest: (root: string) => BuildManifest | null;
16
+ }
17
+ export interface PublishArgs {
18
+ visibility?: string;
19
+ name?: string;
20
+ description?: string;
21
+ force?: boolean;
22
+ }
23
+ /**
24
+ * The whole command. See the file header for why the order below cannot be reshuffled.
25
+ */
26
+ export declare function runPublish(args: PublishArgs, deps?: PublishRunDeps): Promise<void>;
27
+ export declare const publishCommand: import("citty").CommandDef<{
28
+ readonly visibility: {
29
+ readonly type: "string";
30
+ readonly description: "\"public\" or \"private\" (default). Public also requires an unbanned profile.";
31
+ };
32
+ readonly name: {
33
+ readonly type: "string";
34
+ readonly description: "Override the published name for this publish only — never written to game.json.";
35
+ };
36
+ readonly description: {
37
+ readonly type: "string";
38
+ readonly description: "Override the published description for this publish only — never written to game.json.";
39
+ };
40
+ readonly force: {
41
+ readonly type: "boolean";
42
+ readonly description: "Publish despite a stale or failed verify. Does NOT bypass a missing verify record.";
43
+ };
44
+ }>;
@@ -0,0 +1,202 @@
1
+ /**
2
+ * `bitmagic publish` — build, verify-gate, and ship one self-contained bundle straight to GCS.
3
+ *
4
+ * Two-phase, matching api-server's split (see `api-server/src/cli/cli-publish.ts`):
5
+ *
6
+ * 1. `POST /api/cli/v1/publish/begin` authorizes the publish, allocates a version, mints a
7
+ * signed PUT URL, and issues the exact meta-tag block the bundle must carry.
8
+ * 2. This process PUTs the bundle straight to GCS — the multi-MB HTML never passes through
9
+ * api-server.
10
+ * 3. `POST /api/cli/v1/publish/complete` verifies what actually landed and writes the row.
11
+ *
12
+ * The order below is load-bearing, not incidental:
13
+ *
14
+ * - The verify gate runs BEFORE the build, because a stale or failing verify means there is
15
+ * nothing worth building yet, and `bitmagic build` on top of a broken game just wastes time.
16
+ * - The thumbnail — the verify screenshot, uploaded through the same signed-upload lane
17
+ * `forge/upload-proxy.ts` bridges for the browser — is uploaded BEFORE `begin`, because
18
+ * `begin` needs its public URL to render the meta block.
19
+ * - The bundle is PUT to GCS BEFORE `complete`, because `complete` range-reads the object to
20
+ * confirm it carries the meta block `begin` issued — there is nothing to confirm yet.
21
+ *
22
+ * `--force` overrides the verdict and staleness `checkVerifyGate` checks, never the existence of
23
+ * a record: the thumbnail comes from the verify screenshot, so with no verify there is nothing to
24
+ * publish a thumbnail from. `--name`/`--description` are sent on the wire for THIS publish only —
25
+ * they are never written back into the project's own `game.json`, which would change the
26
+ * fingerprint and invalidate the very verify this command just checked.
27
+ */
28
+ import { defineCommand } from 'citty';
29
+ import { Buffer } from 'buffer';
30
+ import { createHash } from 'crypto';
31
+ import * as fs from 'fs';
32
+ import * as path from 'path';
33
+ import { CliError } from '../errors.js';
34
+ import { loadProjectContext } from '../project/context.js';
35
+ import { resolveEnvironment, resolveAuth0ClientId } from '../config/environments.js';
36
+ import { readDefaultEnvironment } from '../config/credentials.js';
37
+ import { getAccessToken } from '../auth/session.js';
38
+ import { computeFingerprint } from '../publish/fingerprint.js';
39
+ import { readVerifyRecord } from '../verify/result.js';
40
+ import { checkVerifyGate, injectMetaBlock } from '../publish/meta-block.js';
41
+ import { runBuild as runBuildImpl, readBuildManifest as readBuildManifestImpl, buildBundlePaths, } from '../publish/bundle.js';
42
+ import { beginPublish, completePublish, putBundle, requestThumbnailUploadUrl, putThumbnail, } from '../publish/client.js';
43
+ /** Where `bitmagic verify` writes its record and screenshot — see `commands/verify.ts`. */
44
+ function verifyArtifactDir(root) {
45
+ return path.join(root, '.bitmagic', 'verify');
46
+ }
47
+ /** `'public' | 'private'`, defaulting to private — a typo is rejected rather than silently
48
+ * coerced, matching the server's own asymmetric contract (see cli-publish.ts). */
49
+ export function resolveVisibility(raw) {
50
+ if (raw === undefined)
51
+ return 'private';
52
+ if (raw === 'public' || raw === 'private')
53
+ return raw;
54
+ throw new CliError(`--visibility must be "public" or "private", got ${JSON.stringify(raw)}.`);
55
+ }
56
+ function defaultDeps() {
57
+ return {
58
+ fetch: globalThis.fetch,
59
+ sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
60
+ log: (message) => console.log(message),
61
+ runBuild: runBuildImpl,
62
+ readBuildManifest: readBuildManifestImpl,
63
+ };
64
+ }
65
+ /**
66
+ * Upload the last verify run's screenshot as this publish's thumbnail, and return its public URL.
67
+ *
68
+ * There is no other source: this lane has no image generator of its own, and the verify gate
69
+ * above already guarantees a record exists — which is what the screenshot alongside it is for.
70
+ */
71
+ async function uploadThumbnail(context, environment, token, apiDeps) {
72
+ const screenshotPath = path.join(verifyArtifactDir(context.root), 'screenshot.png');
73
+ let bytes;
74
+ try {
75
+ bytes = fs.readFileSync(screenshotPath);
76
+ }
77
+ catch {
78
+ // Exit 3, not 6: the record passed the verify gate above, but there is nothing to publish a
79
+ // thumbnail FROM — the same remedy as every other exit-3 case ("run bitmagic verify"), not an
80
+ // upload failure.
81
+ throw new CliError(`No verify screenshot found at ${screenshotPath}. Run \`bitmagic verify\` before publishing.`, 3);
82
+ }
83
+ const contentType = 'image/png';
84
+ const signed = await requestThumbnailUploadUrl(environment, token, { gameId: context.metadata.gameId, filename: 'thumbnail.png', contentType }, apiDeps);
85
+ await putThumbnail(signed, bytes, contentType, apiDeps);
86
+ return signed.publicUrl;
87
+ }
88
+ /**
89
+ * The whole command. See the file header for why the order below cannot be reshuffled.
90
+ */
91
+ export async function runPublish(args, deps = defaultDeps()) {
92
+ const visibility = resolveVisibility(args.visibility);
93
+ const force = args.force === true;
94
+ const context = loadProjectContext(deps.startDir);
95
+ const fingerprint = computeFingerprint(context.root);
96
+ const gate = checkVerifyGate(readVerifyRecord(verifyArtifactDir(context.root)), fingerprint, force);
97
+ if (!gate.ok)
98
+ throw new CliError(gate.message, 3);
99
+ // Reuse: same inputs, same bundle — skip the rebuild. `manifest.bytes`/`manifest.sha256`
100
+ // themselves are never read past this point: what's actually PUT and what `complete` validates
101
+ // is the bundle AFTER the meta block is injected below, which this pre-injection manifest
102
+ // cannot describe either way.
103
+ const existing = deps.readBuildManifest(context.root);
104
+ if (existing?.fingerprint !== fingerprint) {
105
+ deps.runBuild(context.root, context.metadata.engineVersion);
106
+ }
107
+ const environment = resolveEnvironment({ storedDefault: readDefaultEnvironment(deps.baseDir) });
108
+ const clientId = resolveAuth0ClientId(environment);
109
+ const token = await getAccessToken(environment, clientId, { fetch: deps.fetch, sleep: deps.sleep }, deps.baseDir);
110
+ const apiDeps = { fetch: deps.fetch };
111
+ const thumbnailUrl = await uploadThumbnail(context, environment, token, apiDeps);
112
+ // No bundleBytes/sha256 sent here — see BeginPublishRequest's doc comment in publish/client.ts.
113
+ // The only honest number for those fields is the size/hash of the bundle AFTER the meta block
114
+ // below is injected, and that block (and the publishVersion inside it) isn't known until THIS
115
+ // call returns.
116
+ const begun = await beginPublish(environment, token, {
117
+ gameId: context.metadata.gameId,
118
+ visibility,
119
+ ...(args.name !== undefined ? { name: args.name } : {}),
120
+ ...(args.description !== undefined ? { description: args.description } : {}),
121
+ engineVersion: context.metadata.engineVersion,
122
+ thumbnailUrl,
123
+ }, apiDeps);
124
+ const htmlPath = buildBundlePaths(context.root).htmlPath;
125
+ let builtHtml;
126
+ try {
127
+ builtHtml = fs.readFileSync(htmlPath, 'utf-8');
128
+ }
129
+ catch {
130
+ // A reused build's manifest can outlive its own bundle file (e.g. `.bitmagic/build/` cleaned
131
+ // by hand) — report that plainly rather than letting the raw filesystem error (ENOENT, with
132
+ // its own stack) escape uncaught past citty's clean-error wrapper.
133
+ throw new CliError(`The built bundle at ${htmlPath} is missing. Run \`bitmagic build\` again, then publish.`, 1);
134
+ }
135
+ // Computed from the INJECTED bundle, not `manifest.bytes`/`manifest.sha256` — those describe
136
+ // the bundle BEFORE the meta block below is added, and `complete` (cli-publish.ts) 409s the
137
+ // instant `bundleBytes` doesn't match what's actually sitting in GCS: the object it heads is the
138
+ // injected one. Sending the pre-injection numbers would 409 every single publish.
139
+ const publishedHtml = injectMetaBlock(builtHtml, begun.metaBlock);
140
+ const publishedBytes = Buffer.byteLength(publishedHtml, 'utf-8');
141
+ const publishedSha256 = createHash('sha256').update(publishedHtml, 'utf-8').digest('hex');
142
+ // The PUT must send `Cache-Control: no-cache` — `begin` binds that header into the signed
143
+ // URL's signature (so the published entry HTML is never served stale), and GCS rejects a
144
+ // signed PUT whose headers don't match what was signed. Omitting it does not produce a stale
145
+ // cache — it produces a 403 on upload. `cli-uploads.ts` established the same pattern.
146
+ await putBundle(begun.signedUrl, publishedHtml, begun.cacheControl, apiDeps);
147
+ // `visibility`, `name`, `description`, and `thumbnailUrl` are all re-sent, not implied.
148
+ // `complete` re-authorizes against its OWN body — `begin` writes nothing, so nothing it
149
+ // validated is bound — and an absent visibility defaults to private. Omitting them here would
150
+ // make `--visibility public` pass the ban gate at `begin` and then silently publish as
151
+ // private, would overwrite a stored name with a default, and (for thumbnailUrl specifically)
152
+ // would make `complete`'s own meta-block recomputation diverge from what `begin` actually
153
+ // rendered — see `CompletePublishRequest`'s doc comment in publish/client.ts.
154
+ const done = await completePublish(environment, token, {
155
+ gameId: context.metadata.gameId,
156
+ key: begun.key,
157
+ publishVersion: begun.publishVersion,
158
+ visibility,
159
+ ...(args.name !== undefined ? { name: args.name } : {}),
160
+ ...(args.description !== undefined ? { description: args.description } : {}),
161
+ thumbnailUrl,
162
+ bundleBytes: publishedBytes,
163
+ sha256: publishedSha256,
164
+ // The spec's audit trail: engineVersion + fingerprint + sha256, recorded together against
165
+ // the publish that actually landed. See CompletePublishRequest's doc comment for why these
166
+ // are declarative (logged, never verified) and why engineVersion here is not a second gate.
167
+ engineVersion: context.metadata.engineVersion,
168
+ fingerprint,
169
+ }, apiDeps);
170
+ deps.log(`Published ${done.visibility}: ${done.url}`);
171
+ if (done.visibility === 'private') {
172
+ deps.log('Not listed. Publish with --visibility public when you are ready.');
173
+ }
174
+ }
175
+ export const publishCommand = defineCommand({
176
+ meta: {
177
+ name: 'publish',
178
+ description: 'Build, verify-gate, and publish the game — private unless --visibility public.',
179
+ },
180
+ args: {
181
+ visibility: {
182
+ type: 'string',
183
+ description: '"public" or "private" (default). Public also requires an unbanned profile.',
184
+ },
185
+ name: {
186
+ type: 'string',
187
+ description: 'Override the published name for this publish only — never written to game.json.',
188
+ },
189
+ description: {
190
+ type: 'string',
191
+ description: 'Override the published description for this publish only — never written to game.json.',
192
+ },
193
+ force: {
194
+ type: 'boolean',
195
+ description: 'Publish despite a stale or failed verify. Does NOT bypass a missing verify record.',
196
+ },
197
+ },
198
+ async run({ args }) {
199
+ await runPublish(args);
200
+ },
201
+ });
202
+ //# sourceMappingURL=publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,21 @@ export interface GitStatus {
9
9
  * git call that produces `status`, so it is reachable from a test with no real repo involved.
10
10
  */
11
11
  export declare function assertCleanTree(status: GitStatus, force: boolean): void;
12
+ /**
13
+ * The other half of "package.json is never rewritten": upgradeProject leaves it untouched even
14
+ * when the vendored engine now needs a dependency it doesn't have (e.g. vite-plugin-singlefile,
15
+ * which every pre-Task-3 project's package.json predates) — silently doing nothing here would
16
+ * mean `upgrade` reports success while `bitmagic build` still fails later with an opaque
17
+ * module-resolution error. Prints the exact install command instead; never writes the file.
18
+ *
19
+ * The command names the project's OWN package manager (`detectPackageManager`), not a hardcoded
20
+ * npm: a creator on pnpm who runs the printed `npm install` gets a tree npm linked and a second,
21
+ * far less obvious failure on the next build.
22
+ *
23
+ * Exported for its test — the detection helpers can be unit-tested on their own, but only
24
+ * calling this proves the printed line actually uses them.
25
+ */
26
+ export declare function printDependencyReport(root: string): void;
12
27
  export declare const upgradeCommand: import("citty").CommandDef<{
13
28
  readonly engine: {
14
29
  readonly type: "string";
@@ -12,6 +12,7 @@ import { upgradeProject } from '../scaffold/upgrade-project.js';
12
12
  import { diffDependencies } from '../scaffold/dependency-diff.js';
13
13
  import { DEPENDENCIES, DEV_DEPENDENCIES } from '../scaffold/project-files.js';
14
14
  import { loadProjectContext } from '../project/context.js';
15
+ import { addCommand, detectPackageManager } from '../project/package-manager.js';
15
16
  const deps = {
16
17
  fetch: globalThis.fetch,
17
18
  sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
@@ -78,8 +79,15 @@ function isStringRecord(value) {
78
79
  * which every pre-Task-3 project's package.json predates) — silently doing nothing here would
79
80
  * mean `upgrade` reports success while `bitmagic build` still fails later with an opaque
80
81
  * module-resolution error. Prints the exact install command instead; never writes the file.
82
+ *
83
+ * The command names the project's OWN package manager (`detectPackageManager`), not a hardcoded
84
+ * npm: a creator on pnpm who runs the printed `npm install` gets a tree npm linked and a second,
85
+ * far less obvious failure on the next build.
86
+ *
87
+ * Exported for its test — the detection helpers can be unit-tested on their own, but only
88
+ * calling this proves the printed line actually uses them.
81
89
  */
82
- function printDependencyReport(root) {
90
+ export function printDependencyReport(root) {
83
91
  const mismatches = diffDependencies(readPackageJsonDeps(root), {
84
92
  dependencies: DEPENDENCIES,
85
93
  devDependencies: DEV_DEPENDENCIES,
@@ -89,13 +97,14 @@ function printDependencyReport(root) {
89
97
  console.log('');
90
98
  console.log("package.json is not touched by upgrade, and it is missing or outdated on dependencies the " +
91
99
  'vendored engine now needs. Run:');
100
+ const manager = detectPackageManager(root);
92
101
  const deps = mismatches.filter((m) => m.kind === 'dependency');
93
102
  const devDeps = mismatches.filter((m) => m.kind === 'devDependency');
94
103
  if (deps.length > 0) {
95
- console.log(` npm install ${deps.map((m) => `${m.name}@${m.required}`).join(' ')}`);
104
+ console.log(` ${addCommand(manager, false, deps.map((m) => `${m.name}@${m.required}`))}`);
96
105
  }
97
106
  if (devDeps.length > 0) {
98
- console.log(` npm install --save-dev ${devDeps.map((m) => `${m.name}@${m.required}`).join(' ')}`);
107
+ console.log(` ${addCommand(manager, true, devDeps.map((m) => `${m.name}@${m.required}`))}`);
99
108
  }
100
109
  }
101
110
  export const upgradeCommand = defineCommand({
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACvG,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAwB,MAAM,gCAAgC,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,KAAK,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;CAC/E,CAAC;AAMF;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,MAAiB,EAAE,KAAc;IAC/D,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,QAAQ,CAChB,4FAA4F;YAC1F,mEAAmE,CACtE,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IACxG,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC1B,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;AACpD,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,IAAY;IACvC,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IACvD,MAAM,GAAG,GAAG,GAA8B,CAAC;IAC3C,OAAO;QACL,YAAY,EAAE,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;QAC7E,eAAe,EAAE,cAAc,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS;KACvF,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CACjE,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,qBAAqB,CAAC,IAAY;IACzC,MAAM,UAAU,GAAG,gBAAgB,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE;QAC7D,YAAY,EAAE,YAAY;QAC1B,eAAe,EAAE,gBAAgB;KAClC,CAAC,CAAC;IACH,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEpC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CACT,4FAA4F;QAC1F,iCAAiC,CACpC,CAAC;IACF,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC;IACrE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,4BAA4B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrG,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC;IAC1C,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,8FAA8F;KAC5G;IACD,IAAI,EAAE;QACJ,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qEAAqE,EAAE;QAC9G,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,4DAA4D,EAAE;KACtG;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QAChB,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;QACrC,eAAe,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC;QAEjE,MAAM,WAAW,GAAG,kBAAkB,CAAC,EAAE,aAAa,EAAE,sBAAsB,EAAE,EAAE,CAAC,CAAC;QACpF,MAAM,QAAQ,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QAEhE,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;QAE5F,6FAA6F;QAC7F,8FAA8F;QAC9F,wFAAwF;QACxF,gFAAgF;QAChF,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,OAAO,CAAC;QACtD,IAAI,aAAa,KAAK,QAAQ,CAAC,OAAO,EAAE,CAAC;YACvC,MAAM,IAAI,QAAQ,CAChB,4BAA4B,aAAa,mDAAmD;gBAC1F,YAAY,QAAQ,CAAC,OAAO,mCAAmC,CAClE,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAC5E,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;YACxD,OAAO,CAAC,GAAG,CAAC,sBAAsB,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC;YACvD,MAAM,iBAAiB,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;YAExG,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAClD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YACrD,MAAM,aAAa,CAAC,WAAW,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;YAE1D,MAAM,MAAM,GAAG,cAAc,CAAC;gBAC5B,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,kBAAkB,EAAE,SAAS;gBAC7B,aAAa,EAAE,QAAQ,CAAC,OAAO;aAChC,CAAC,CAAC;YAEH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,IAAI,MAAM,CAAC,qBAAqB,KAAK,MAAM,CAAC,aAAa,EAAE,CAAC;gBAC1D,qFAAqF;gBACrF,qFAAqF;gBACrF,2EAA2E;gBAC3E,OAAO,CAAC,GAAG,CAAC,qBAAqB,MAAM,CAAC,aAAa,wCAAwC,CAAC,CAAC;YACjG,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,qBAAqB,OAAO,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;YAC7F,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACzB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACnC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YAC3B,CAAC;YACD,qBAAqB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;CACF,CAAC,CAAC"}
1
+ {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
3
  import { CliError } from '../errors.js';
4
+ import { detectPackageManager, installAllCommand } from './package-manager.js';
4
5
  const MARKER = 'bitmagic.json';
5
6
  const REQUIRED_STRING_FIELDS = [
6
7
  'gameId',
@@ -60,7 +61,11 @@ export function loadProjectContext(startDir = process.cwd()) {
60
61
  export function projectBin(root, name) {
61
62
  const binary = path.join(root, 'node_modules', '.bin', name);
62
63
  if (!fs.existsSync(binary)) {
63
- throw new CliError(`Cannot find \`${name}\` in this project's dependencies. Run \`npm install\` in ${root} first.`);
64
+ // Names the project's OWN package manager: telling a pnpm project to run `npm install`
65
+ // installs the tree under a different linker, and the next build fails on module
66
+ // resolution instead — a worse failure than the one this message is trying to fix.
67
+ throw new CliError(`Cannot find \`${name}\` in this project's dependencies. `
68
+ + `Run \`${installAllCommand(detectPackageManager(root))}\` in ${root} first.`);
64
69
  }
65
70
  return binary;
66
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/project/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAcxC,MAAM,MAAM,GAAG,eAAe,CAAC;AAE/B,MAAM,sBAAsB,GAA8B;IACxD,QAAQ;IACR,eAAe;IACf,OAAO;IACP,UAAU;CACX,CAAC;AAEF;;;;;;GAMG;AACH,SAAS,gBAAgB,CAAC,KAA8B;IACtD,OAAO,sBAAsB,CAAC,IAAI,CAChC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,QAAQ,IAAK,KAAK,CAAC,KAAK,CAAY,CAAC,MAAM,KAAK,CAAC,CACrF,CAAC;AACJ,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,eAAe,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IAC9D,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,SAAS,CAAC;QACR,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,MAAM,IAAI,QAAQ,CAChB,MAAM,MAAM,aAAa,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,4BAA4B;gBACzE,8EAA8E,CACjF,CAAC;QACJ,CAAC;QACD,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IACjE,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,4FAA4F;QAC5F,kDAAkD;QAClD,MAAM,IAAI,QAAQ,CAAC,GAAG,IAAI,yDAAyD,CAAC,CAAC;IACvF,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,MAAM,IAAI,QAAQ,CAAC,GAAG,IAAI,qCAAqC,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,YAAY,GAAG,gBAAgB,CAAC,MAAiC,CAAC,CAAC;IACzE,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,IAAI,QAAQ,CAAC,GAAG,IAAI,eAAe,YAAY,GAAG,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAyB,EAAE,CAAC;AACvD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,IAAY;IACnD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IAC7D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,QAAQ,CAChB,iBAAiB,IAAI,6DAA6D,IAAI,SAAS,CAChG,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/project/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export type PackageManager = 'pnpm' | 'yarn' | 'npm';
2
+ /**
3
+ * Decide from the project's lockfile. npm is the fallback: it is what the scaffold's own docs
4
+ * use and what ships with Node, so it is the right guess when there is no lockfile at all.
5
+ *
6
+ * Checked most-specific-first — a repo can carry both a `pnpm-lock.yaml` and a leftover
7
+ * `package-lock.json`, and pnpm is the one actually in use there.
8
+ */
9
+ export declare function detectPackageManager(root: string): PackageManager;
10
+ /**
11
+ * The command that adds `specs` as (dev) dependencies. yarn's syntax differs from npm's and
12
+ * pnpm's (`yarn add --dev`, not `--save-dev`), which is why this is a function rather than a
13
+ * template string at each call site.
14
+ */
15
+ export declare function addCommand(manager: PackageManager, dev: boolean, specs: string[]): string;
16
+ /** The command that installs everything already declared in package.json. */
17
+ export declare function installAllCommand(manager: PackageManager): string;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Which package manager a scaffolded project is installed with, and the command lines that
3
+ * follow from it.
4
+ *
5
+ * Every command that tells a creator to install something prints a line meant to be run
6
+ * verbatim — by a person or by the agent driving this CLI. Naming the wrong manager is not
7
+ * cosmetic: running `npm install` in a pnpm project rewrites the tree under a different linker,
8
+ * and the very next `bitmagic build` fails on module resolution. That turns one clear instruction
9
+ * into a second, far more opaque failure — precisely the trap `bitmagic upgrade`'s dependency
10
+ * report and `projectBin`'s missing-binary error both exist to keep creators out of.
11
+ *
12
+ * Kept in `project/` rather than inside a command, because both `commands/upgrade.ts` and
13
+ * `project/context.ts` need it and a command module must not be imported from `project/`.
14
+ */
15
+ import * as fs from 'fs';
16
+ import * as path from 'path';
17
+ /**
18
+ * Decide from the project's lockfile. npm is the fallback: it is what the scaffold's own docs
19
+ * use and what ships with Node, so it is the right guess when there is no lockfile at all.
20
+ *
21
+ * Checked most-specific-first — a repo can carry both a `pnpm-lock.yaml` and a leftover
22
+ * `package-lock.json`, and pnpm is the one actually in use there.
23
+ */
24
+ export function detectPackageManager(root) {
25
+ if (fs.existsSync(path.join(root, 'pnpm-lock.yaml')))
26
+ return 'pnpm';
27
+ if (fs.existsSync(path.join(root, 'yarn.lock')))
28
+ return 'yarn';
29
+ return 'npm';
30
+ }
31
+ /**
32
+ * The command that adds `specs` as (dev) dependencies. yarn's syntax differs from npm's and
33
+ * pnpm's (`yarn add --dev`, not `--save-dev`), which is why this is a function rather than a
34
+ * template string at each call site.
35
+ */
36
+ export function addCommand(manager, dev, specs) {
37
+ const joined = specs.join(' ');
38
+ if (manager === 'yarn')
39
+ return `yarn add ${dev ? '--dev ' : ''}${joined}`;
40
+ if (manager === 'pnpm')
41
+ return `pnpm add ${dev ? '--save-dev ' : ''}${joined}`;
42
+ return `npm install ${dev ? '--save-dev ' : ''}${joined}`;
43
+ }
44
+ /** The command that installs everything already declared in package.json. */
45
+ export function installAllCommand(manager) {
46
+ return `${manager} install`;
47
+ }
48
+ //# sourceMappingURL=package-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-manager.js","sourceRoot":"","sources":["../../src/project/package-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAI7B;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACpE,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAC/D,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,OAAuB,EAAE,GAAY,EAAE,KAAe;IAC/E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,YAAY,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC;IAC1E,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,YAAY,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC;IAC/E,OAAO,eAAe,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC;AAC5D,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,iBAAiB,CAAC,OAAuB;IACvD,OAAO,GAAG,OAAO,UAAU,CAAC;AAC9B,CAAC"}
@@ -27,5 +27,11 @@ export declare function readBuildManifest(root: string): BuildManifest | null;
27
27
  *
28
28
  * Exit code 1 on failure, matching the table in the spec: a build failure is the creator's own
29
29
  * code, and the compiler's output has already been printed.
30
+ *
31
+ * The pre-flight below runs BEFORE `tsc`, not after: a project scaffolded before
32
+ * `vite.publish.config.js` existed has no config for vite to load, and without this check the
33
+ * creator pays a full type-check and then reads a raw vite "config not found" that names no
34
+ * remedy. `bitmagic upgrade` is the remedy — it vendors the file without touching game code —
35
+ * so the error says so.
30
36
  */
31
37
  export declare function runBuild(root: string, engineVersion: string): BuildManifest;
@@ -41,8 +41,19 @@ export function readBuildManifest(root) {
41
41
  *
42
42
  * Exit code 1 on failure, matching the table in the spec: a build failure is the creator's own
43
43
  * code, and the compiler's output has already been printed.
44
+ *
45
+ * The pre-flight below runs BEFORE `tsc`, not after: a project scaffolded before
46
+ * `vite.publish.config.js` existed has no config for vite to load, and without this check the
47
+ * creator pays a full type-check and then reads a raw vite "config not found" that names no
48
+ * remedy. `bitmagic upgrade` is the remedy — it vendors the file without touching game code —
49
+ * so the error says so.
44
50
  */
45
51
  export function runBuild(root, engineVersion) {
52
+ if (!fs.existsSync(path.join(root, VITE_PUBLISH_CONFIG))) {
53
+ throw new CliError(`This project has no ${VITE_PUBLISH_CONFIG}, which \`bitmagic build\` needs to bundle it. ` +
54
+ 'It was added to the scaffold after this project was created — run `bitmagic upgrade` to ' +
55
+ 'vendor it (your game code is not touched), then build again.', 1);
56
+ }
46
57
  const tsc = projectBin(root, 'tsc');
47
58
  const compile = spawnSync(tsc, [], { cwd: root, stdio: 'inherit' });
48
59
  if (compile.error)
@@ -1 +1 @@
1
- {"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/publish/bundle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/publish/bundle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ import type { Environment } from '../config/environments.js';
2
+ export interface ApiDeps {
3
+ fetch: typeof globalThis.fetch;
4
+ }
5
+ /**
6
+ * One status→exit-code mapping for both publish calls.
7
+ *
8
+ * The distinction that matters is 4 vs 5: "your engine is too old" is self-serve
9
+ * (`bitmagic upgrade`), while a ban or an ownership mismatch is not. An agent that cannot
10
+ * tell them apart will either loop on upgrade or give up on a fixable problem.
11
+ */
12
+ export declare function publishExitCode(status: number, body: {
13
+ code?: string;
14
+ }): number;
15
+ export interface BeginPublishRequest {
16
+ gameId: string;
17
+ visibility: 'public' | 'private';
18
+ name?: string;
19
+ description?: string;
20
+ engineVersion: string;
21
+ thumbnailUrl: string;
22
+ }
23
+ export interface BeginPublishResponse {
24
+ signedUrl: string;
25
+ key: string;
26
+ publishVersion: number;
27
+ metaBlock: string;
28
+ cacheControl: string;
29
+ }
30
+ export declare function beginPublish(environment: Environment, accessToken: string, body: BeginPublishRequest, deps: ApiDeps): Promise<BeginPublishResponse>;
31
+ export interface CompletePublishRequest {
32
+ gameId: string;
33
+ key: string;
34
+ publishVersion: number;
35
+ visibility: 'public' | 'private';
36
+ name?: string;
37
+ description?: string;
38
+ thumbnailUrl: string;
39
+ bundleBytes: number;
40
+ sha256: string;
41
+ /**
42
+ * The audit trail the spec calls for: `engineVersion`, `fingerprint` and `sha256` recorded
43
+ * together for the publish that actually landed. All three are declarative — the server logs
44
+ * them, it does not verify them (there is no column for any of them today, and verifying the
45
+ * hash would mean reading bytes this design deliberately never reads).
46
+ *
47
+ * `engineVersion` is NOT a second floor gate. It cannot be: `begin` is the only step that
48
+ * mints the signed URL, so its floor check is already unavoidable, and a value re-declared
49
+ * here proves nothing about what the bundle was built with. It is sent so the log line that
50
+ * records a publish says which engine produced it — without it, the only record of a bundle's
51
+ * engine is a `begin` log entry that may belong to an abandoned attempt.
52
+ *
53
+ * `fingerprint` is the same hash `verify` recorded and `publish` gated on, so a support
54
+ * question about a published bundle can be tied back to the exact project state that produced
55
+ * it. Nothing else on the wire identifies the source.
56
+ */
57
+ engineVersion: string;
58
+ fingerprint: string;
59
+ }
60
+ export interface CompletePublishResponse {
61
+ url: string;
62
+ publishVersion: number;
63
+ visibility: 'public' | 'private';
64
+ }
65
+ export declare function completePublish(environment: Environment, accessToken: string, body: CompletePublishRequest, deps: ApiDeps): Promise<CompletePublishResponse>;
66
+ /**
67
+ * `begin` always signs `text/html` for the entry HTML (cli-publish.ts's `getSignedUrl` call) but
68
+ * does not echo a `contentType` field back in its response — there is nothing to echo, so this
69
+ * fixed value is the one Content-Type that can ever be correct for the PUT.
70
+ */
71
+ export declare const PUBLISH_BUNDLE_CONTENT_TYPE = "text/html";
72
+ /** PUT the built (and meta-block-injected) bundle to the signed URL `begin` minted. */
73
+ export declare function putBundle(signedUrl: string, html: string, cacheControl: string, deps: ApiDeps): Promise<void>;
74
+ export interface ThumbnailUploadRequest {
75
+ gameId: string;
76
+ filename: string;
77
+ contentType: string;
78
+ }
79
+ /** `cli-uploads.ts`'s `generateUploadSignedUrl` response shape, the fields this lane uses. */
80
+ export interface ThumbnailUploadUrl {
81
+ signedUrl: string;
82
+ publicUrl: string;
83
+ cacheControl: string;
84
+ contentEncoding?: string;
85
+ }
86
+ export declare function requestThumbnailUploadUrl(environment: Environment, accessToken: string, body: ThumbnailUploadRequest, deps: ApiDeps): Promise<ThumbnailUploadUrl>;
87
+ /**
88
+ * PUT the thumbnail bytes to the signed URL `requestThumbnailUploadUrl` minted. `contentType` is
89
+ * the SAME value this lane requested (the server never echoes it back — see
90
+ * `PUBLISH_BUNDLE_CONTENT_TYPE`'s doc comment for why that is fine: the caller already knows it),
91
+ * while `cacheControl` and `contentEncoding` are read back from the signed-URL response, because
92
+ * the server — not this lane — decides both.
93
+ */
94
+ export declare function putThumbnail(signed: ThumbnailUploadUrl, bytes: Uint8Array, contentType: string, deps: ApiDeps): Promise<void>;
@@ -0,0 +1,150 @@
1
+ /**
2
+ * The HTTP client for `bitmagic publish`: the two authorizing calls to api-server
3
+ * (`publish/begin`, `publish/complete`), the thumbnail's signed-upload lane
4
+ * (`uploads/signed-url`, the same route `forge/upload-proxy.ts` bridges for the browser), and the
5
+ * two raw PUTs against the signed GCS URLs those calls mint.
6
+ *
7
+ * `publishExitCode` is the one status→exit-code mapping every call above shares, so `publish.ts`
8
+ * never has to duplicate the 401/403/409 distinctions per call site.
9
+ */
10
+ import { CliError } from '../errors.js';
11
+ function isRecord(value) {
12
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
13
+ }
14
+ function stringField(value) {
15
+ return typeof value === 'string' ? value : undefined;
16
+ }
17
+ async function readJsonBody(response) {
18
+ try {
19
+ const parsed = await response.json();
20
+ return isRecord(parsed) ? parsed : {};
21
+ }
22
+ catch {
23
+ return {};
24
+ }
25
+ }
26
+ /**
27
+ * One status→exit-code mapping for both publish calls.
28
+ *
29
+ * The distinction that matters is 4 vs 5: "your engine is too old" is self-serve
30
+ * (`bitmagic upgrade`), while a ban or an ownership mismatch is not. An agent that cannot
31
+ * tell them apart will either loop on upgrade or give up on a fixable problem.
32
+ */
33
+ export function publishExitCode(status, body) {
34
+ if (status === 401)
35
+ return 2;
36
+ if (status === 403)
37
+ return 5;
38
+ if (status === 409 && body.code === 'engine-below-floor')
39
+ return 4;
40
+ return 6;
41
+ }
42
+ /**
43
+ * POST `path` as JSON with a bearer token, and map a non-2xx response through `publishExitCode`.
44
+ * Shared by every authenticated JSON call this module makes — begin, complete, and the thumbnail
45
+ * signed-URL mint — so the three cannot drift on how a failure is reported.
46
+ */
47
+ async function postJson(url, accessToken, body, deps) {
48
+ let response;
49
+ try {
50
+ response = await deps.fetch(url, {
51
+ method: 'POST',
52
+ headers: {
53
+ Authorization: `Bearer ${accessToken}`,
54
+ Accept: 'application/json',
55
+ 'Content-Type': 'application/json',
56
+ },
57
+ body: JSON.stringify(body),
58
+ });
59
+ }
60
+ catch {
61
+ // A transport failure and an error status send people to very different places.
62
+ throw new CliError(`Cannot reach api-server at ${url}.`, 6);
63
+ }
64
+ // A 2xx response MUST parse as a JSON object — this is the one branch that feeds its result
65
+ // straight back to the caller as `T` with no further validation (`beginPublish`'s `signedUrl`,
66
+ // `completePublish`'s `url`, ...). Falling back to `{}` here the way the error branch below
67
+ // does would silently turn a malformed 200 into every field of `T` being `undefined` — e.g. a
68
+ // PUT sent to the literal string `"undefined"` — instead of a clear failure at the point the
69
+ // bad response actually arrived.
70
+ if (response.ok) {
71
+ let parsed;
72
+ try {
73
+ parsed = await response.json();
74
+ }
75
+ catch {
76
+ throw new CliError(`api-server returned a ${response.status} from ${url} with a body that is not valid JSON.`, 6);
77
+ }
78
+ if (!isRecord(parsed)) {
79
+ throw new CliError(`api-server returned an unexpected response shape from ${url}.`, 6);
80
+ }
81
+ return parsed;
82
+ }
83
+ // The error path can tolerate an unparsable/absent body — the fallback is just a generic
84
+ // message, not a value silently flowing on to become someone else's `undefined`.
85
+ const parsedError = await readJsonBody(response);
86
+ const code = stringField(parsedError.code);
87
+ const message = stringField(parsedError.error) ?? `api-server returned HTTP ${response.status} for ${url}.`;
88
+ throw new CliError(message, publishExitCode(response.status, { code }));
89
+ }
90
+ /**
91
+ * Raw PUT of already-prepared bytes to a GCS V4 signed URL.
92
+ *
93
+ * `headers` must match exactly what the URL's signature bound (Cache-Control, and — for the
94
+ * thumbnail lane — Content-Encoding when the server chose to gzip). A mismatch is a 403 from GCS,
95
+ * not a stale-cache symptom; see cli-publish.ts's and cli-uploads.ts's own doc comments for why.
96
+ */
97
+ async function putSignedUrl(url, body, headers, deps) {
98
+ let response;
99
+ try {
100
+ // `@types/node`'s ambient `Uint8Array` (generic over `ArrayBufferLike` since TS 5.7) does not
101
+ // structurally match this project's `BodyInit` (this tsconfig's `"DOM"` lib pulls in lib.dom's
102
+ // own copy, which `@types/node`'s conditional global-augmentation defers to whenever DOM
103
+ // globals are present — see node_modules/@types/node/web-globals/fetch.d.ts). Deriving the
104
+ // body type from `Parameters<typeof fetch>[1]` instead of naming `BodyInit` was tried and hits
105
+ // the identical mismatch, because it resolves to the same lib.dom type in THIS project. Both a
106
+ // `string` and a `Uint8Array` are valid `fetch` bodies at runtime regardless.
107
+ response = await deps.fetch(url, { method: 'PUT', headers, body: body });
108
+ }
109
+ catch (error) {
110
+ const message = error instanceof Error ? error.message : String(error);
111
+ throw new CliError(`Could not upload to storage: ${message}`, 6);
112
+ }
113
+ if (!response.ok) {
114
+ const text = await response.text().catch(() => '');
115
+ throw new CliError(`Upload to storage failed: HTTP ${response.status}${text ? ` — ${text.slice(0, 200)}` : ''}`, 6);
116
+ }
117
+ }
118
+ export async function beginPublish(environment, accessToken, body, deps) {
119
+ return postJson(`${environment.apiUrl}/api/cli/v1/publish/begin`, accessToken, body, deps);
120
+ }
121
+ export async function completePublish(environment, accessToken, body, deps) {
122
+ return postJson(`${environment.apiUrl}/api/cli/v1/publish/complete`, accessToken, body, deps);
123
+ }
124
+ /**
125
+ * `begin` always signs `text/html` for the entry HTML (cli-publish.ts's `getSignedUrl` call) but
126
+ * does not echo a `contentType` field back in its response — there is nothing to echo, so this
127
+ * fixed value is the one Content-Type that can ever be correct for the PUT.
128
+ */
129
+ export const PUBLISH_BUNDLE_CONTENT_TYPE = 'text/html';
130
+ /** PUT the built (and meta-block-injected) bundle to the signed URL `begin` minted. */
131
+ export async function putBundle(signedUrl, html, cacheControl, deps) {
132
+ await putSignedUrl(signedUrl, html, { 'Content-Type': PUBLISH_BUNDLE_CONTENT_TYPE, 'Cache-Control': cacheControl }, deps);
133
+ }
134
+ export async function requestThumbnailUploadUrl(environment, accessToken, body, deps) {
135
+ return postJson(`${environment.apiUrl}/api/cli/v1/uploads/signed-url`, accessToken, body, deps);
136
+ }
137
+ /**
138
+ * PUT the thumbnail bytes to the signed URL `requestThumbnailUploadUrl` minted. `contentType` is
139
+ * the SAME value this lane requested (the server never echoes it back — see
140
+ * `PUBLISH_BUNDLE_CONTENT_TYPE`'s doc comment for why that is fine: the caller already knows it),
141
+ * while `cacheControl` and `contentEncoding` are read back from the signed-URL response, because
142
+ * the server — not this lane — decides both.
143
+ */
144
+ export async function putThumbnail(signed, bytes, contentType, deps) {
145
+ const headers = { 'Content-Type': contentType, 'Cache-Control': signed.cacheControl };
146
+ if (signed.contentEncoding)
147
+ headers['Content-Encoding'] = signed.contentEncoding;
148
+ await putSignedUrl(signed.signedUrl, bytes, headers, deps);
149
+ }
150
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/publish/client.ts"],"names":[],"mappings":"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"}
@@ -4,10 +4,28 @@ import * as path from 'path';
4
4
  /**
5
5
  * Directories whose contents never change what the bundle contains: our own artifacts
6
6
  * (`.bitmagic/`, `dist/`), the dependency tree (`node_modules/` — pinned by the lockfile the
7
- * scaffold writes), and vite's cache. Including any of them would make the fingerprint change
8
- * on every build, which would make the staleness gate reject every publish.
7
+ * scaffold writes), vite's cache, and git's object store. Including any of them would make the
8
+ * fingerprint change on something other than an edit, which would make the staleness gate reject
9
+ * a publish of an unchanged project.
10
+ *
11
+ * `.git` is the one that bit in practice. Hashing it means an EMPTY `git commit` — no source
12
+ * change at all — flips the fingerprint, because the commit writes new objects, a new ref value
13
+ * and a new reflog entry. That turns the ordinary `bitmagic verify` → `git commit` →
14
+ * `bitmagic publish` sequence into exit 3 ("The project has changed since it was last verified"),
15
+ * and `bitmagic upgrade` actively pushes creators into git by refusing a dirty tree. The
16
+ * scaffolded AGENTS.md's "do not edit any tracked file between verifying and publishing" cannot
17
+ * prevent it either: committing is not editing. It also made every publish rebuild, since the
18
+ * build manifest's own recorded fingerprint could never still match by the time publish ran.
19
+ *
20
+ * `.DS_Store` is excluded for the same reason at file granularity: on macOS, Finder writes it
21
+ * merely for opening the project folder, and no build tool ever reads it — so it is another way
22
+ * to flip the fingerprint without editing anything. It is the only excluded FILE; the list is
23
+ * deliberately not a general ignore mechanism, because a false "fresh" ships an unverified
24
+ * bundle while a false "stale" only costs one `bitmagic verify`.
9
25
  */
10
- const EXCLUDED_DIRS = new Set(['.bitmagic', 'node_modules', 'dist', '.vite-cache']);
26
+ const EXCLUDED_DIRS = new Set(['.bitmagic', 'node_modules', 'dist', '.vite-cache', '.git']);
27
+ /** See EXCLUDED_DIRS: tool-written files that can never change what the bundle contains. */
28
+ const EXCLUDED_FILES = new Set(['.DS_Store']);
11
29
  /**
12
30
  * A relative path as the fingerprint hashes it: always forward-slashed.
13
31
  *
@@ -27,6 +45,8 @@ function walk(dir, root, out) {
27
45
  walk(path.join(dir, entry.name), root, out);
28
46
  }
29
47
  else if (entry.isFile()) {
48
+ if (EXCLUDED_FILES.has(entry.name))
49
+ continue;
30
50
  const relPath = path.relative(root, path.join(dir, entry.name));
31
51
  out.push(toPosixPath(relPath));
32
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../src/publish/fingerprint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;;;;GAKG;AACH,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;AAEpF;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,YAAoB,EAAE,MAAc,IAAI,CAAC,GAAG;IACtE,OAAO,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,IAAI,CAAC,GAAW,EAAE,IAAY,EAAE,GAAa;IACpD,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC5C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAChE,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IACxB,KAAK,CAAC,IAAI,EAAE,CAAC;IAEb,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC"}
1
+ {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../src/publish/fingerprint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5F,4FAA4F;AAC5F,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,YAAoB,EAAE,MAAc,IAAI,CAAC,GAAG;IACtE,OAAO,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,IAAI,CAAC,GAAW,EAAE,IAAY,EAAE,GAAa;IACpD,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC5C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,IAAI,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAChE,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IACxB,KAAK,CAAC,IAAI,EAAE,CAAC;IAEb,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { VerifyRunRecord } from '../verify/result.js';
2
+ /**
3
+ * Put the server-issued block immediately after `<head>`, matching where the web lane puts its
4
+ * own meta tags — and close enough to the start of the file that the server's 64KB range read
5
+ * always covers it.
6
+ *
7
+ * String insertion, not DOM parsing: this HTML carries the whole inlined engine.
8
+ */
9
+ export declare function injectMetaBlock(html: string, block: string): string;
10
+ export type VerifyGate = {
11
+ ok: true;
12
+ } | {
13
+ ok: false;
14
+ message: string;
15
+ };
16
+ /**
17
+ * May this project be published?
18
+ *
19
+ * Three distinct answers, deliberately: "never verified", "verified then edited", and "verified
20
+ * and broken" have three different fixes, and collapsing them into "run verify" is how an agent
21
+ * ends up looping verify against a game that is genuinely broken.
22
+ *
23
+ * `force` overrides the VERDICT and STALENESS, not the existence of a record: the thumbnail comes
24
+ * from the verify screenshot, so with no verify there is nothing to publish a thumbnail from.
25
+ */
26
+ export declare function checkVerifyGate(record: VerifyRunRecord | null, fingerprint: string, force: boolean): VerifyGate;
@@ -0,0 +1,48 @@
1
+ import { CliError } from '../errors.js';
2
+ const HEAD_OPEN = '<head>';
3
+ /**
4
+ * Put the server-issued block immediately after `<head>`, matching where the web lane puts its
5
+ * own meta tags — and close enough to the start of the file that the server's 64KB range read
6
+ * always covers it.
7
+ *
8
+ * String insertion, not DOM parsing: this HTML carries the whole inlined engine.
9
+ */
10
+ export function injectMetaBlock(html, block) {
11
+ if (html.includes('<!--bitmagic:meta:v1-->')) {
12
+ throw new CliError('This bundle already carries a meta block. Run `bitmagic build` again.', 6);
13
+ }
14
+ const at = html.indexOf(HEAD_OPEN);
15
+ if (at === -1) {
16
+ throw new CliError('The built bundle has no <head> to inject into.', 1);
17
+ }
18
+ const cut = at + HEAD_OPEN.length;
19
+ return html.slice(0, cut) + block + html.slice(cut);
20
+ }
21
+ /**
22
+ * May this project be published?
23
+ *
24
+ * Three distinct answers, deliberately: "never verified", "verified then edited", and "verified
25
+ * and broken" have three different fixes, and collapsing them into "run verify" is how an agent
26
+ * ends up looping verify against a game that is genuinely broken.
27
+ *
28
+ * `force` overrides the VERDICT and STALENESS, not the existence of a record: the thumbnail comes
29
+ * from the verify screenshot, so with no verify there is nothing to publish a thumbnail from.
30
+ */
31
+ export function checkVerifyGate(record, fingerprint, force) {
32
+ if (record === null) {
33
+ return { ok: false, message: 'This game has not been verified. Run `bitmagic verify` first.' };
34
+ }
35
+ if (force)
36
+ return { ok: true };
37
+ if (record.fingerprint !== fingerprint) {
38
+ return { ok: false, message: 'The project has changed since it was last verified. Run `bitmagic verify` again.' };
39
+ }
40
+ if (!record.ok) {
41
+ return {
42
+ ok: false,
43
+ message: `The last verify failed:\n${record.failures.map((f) => ` ✗ ${f}`).join('\n')}\nFix these, or publish with --force.`,
44
+ };
45
+ }
46
+ return { ok: true };
47
+ }
48
+ //# sourceMappingURL=meta-block.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta-block.js","sourceRoot":"","sources":["../../src/publish/meta-block.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAGxC,MAAM,SAAS,GAAG,QAAQ,CAAC;AAE3B;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,KAAa;IACzD,IAAI,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,QAAQ,CAAC,uEAAuE,EAAE,CAAC,CAAC,CAAC;IACjG,CAAC;IACD,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACnC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;QACd,MAAM,IAAI,QAAQ,CAAC,gDAAgD,EAAE,CAAC,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM,GAAG,GAAG,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC;IAClC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACtD,CAAC;AAID;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAC7B,MAA8B,EAC9B,WAAmB,EACnB,KAAc;IAEd,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,+DAA+D,EAAE,CAAC;IACjG,CAAC;IACD,IAAI,KAAK;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAC/B,IAAI,MAAM,CAAC,WAAW,KAAK,WAAW,EAAE,CAAC;QACvC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,kFAAkF,EAAE,CAAC;IACpH,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE,4BAA4B,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,uCAAuC;SAC9H,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC"}
@@ -326,6 +326,54 @@ compile that dies on load — a missing asset, a bad \`world.json\` value, a nul
326
326
  \`bitmagic verify\` after a change you cannot eyeball: it loads the game in a headless browser and
327
327
  fails with what actually broke, leaving a console log and a screenshot in \`.bitmagic/verify/\`.
328
328
 
329
+ ## Publishing
330
+
331
+ \`\`\`
332
+ bitmagic build # bundle into .bitmagic/build/index.html + .bitmagic/build/manifest.json
333
+ bitmagic publish # verify-gate, build if needed, and ship to bitmagic.ai
334
+ \`\`\`
335
+
336
+ Follow this order; \`publish\` enforces it and refuses otherwise:
337
+
338
+ 1. Run \`bitmagic verify\` and get it passing. It writes \`.bitmagic/verify/result.json\`,
339
+ \`.bitmagic/verify/screenshot.png\` (becomes the publish thumbnail) and
340
+ \`.bitmagic/verify/console.log\`.
341
+ 2. Do not edit any tracked file between verifying and publishing. Staleness is decided by a
342
+ content fingerprint of every tracked file, not a clock — one edit after verifying invalidates
343
+ it immediately, and an untouched project stays fresh no matter how long it has been. There is
344
+ no way to check freshness except running \`bitmagic verify\` again. Git operations are safe:
345
+ \`.git/\` is excluded from the fingerprint, so committing (or branching, or stashing) between
346
+ verifying and publishing changes nothing. So are \`node_modules/\`, \`dist/\`, \`.bitmagic/\`
347
+ and \`.vite-cache/\`.
348
+ 3. Run \`bitmagic publish\`. It rebuilds automatically if the project changed since the last
349
+ build, so a manual \`bitmagic build\` first is optional.
350
+
351
+ **A bare \`bitmagic publish\` does not make the game public.** Every publish uploads and
352
+ registers the game, but \`visibility\` defaults to \`private\` — reachable by URL, not listed on
353
+ bitmagic.ai. Pass \`--visibility public\` explicitly, on that call, to list it; omit it on a later
354
+ publish and the game goes back to private — its \`/play/\` page stops serving too, so a public
355
+ game you re-publish bare disappears from bitmagic.ai entirely until the next
356
+ \`--visibility public\`.
357
+
358
+ \`--force\` overrides a **stale or failed** verify verdict, never a **missing** one — the
359
+ thumbnail comes from the verify screenshot, so \`bitmagic verify\` must have produced one at least
360
+ once before \`--force\` has anything to publish from.
361
+
362
+ \`--name\`/\`--description\` apply to that one publish call only; they are never written back to
363
+ \`src/work/game.json\` (doing so by hand would change the fingerprint and invalidate the verify
364
+ you just checked).
365
+
366
+ If \`bitmagic publish\` exits non-zero, branch on the exit code rather than parsing the message:
367
+
368
+ | Code | Meaning | Fix |
369
+ |---|---|---|
370
+ | 1 | Build failed | Run \`bitmagic check\` to see the error, fix it. If the message says \`vite.publish.config.js\` is missing, this project predates it — run \`bitmagic upgrade\` |
371
+ | 2 | Not logged in | \`bitmagic login\` |
372
+ | 3 | Verify missing, stale, or failed | \`bitmagic verify\` (then publish again, or add \`--force\` for a stale/failed record) |
373
+ | 4 | Engine below the publish floor | \`bitmagic upgrade\` |
374
+ | 5 | Not this game's owner, or the account/game is banned | Not self-serve — stop and report it |
375
+ | 6 | Upload or finalize failed | Usually transient (network/storage). Retry once; if it fails identically, stop and report it — this code also covers permanent failures such as an unknown game or a rejected request |
376
+
329
377
  ## Generating assets
330
378
 
331
379
  You can create game content from here — no web editor needed:
@@ -1 +1 @@
1
- {"version":3,"file":"project-files.js","sourceRoot":"","sources":["../../src/scaffold/project-files.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project-files.js","sourceRoot":"","sources":["../../src/scaffold/project-files.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitmagic/cli",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Build Bitmagic games from your own agent tool",
5
5
  "type": "module",
6
6
  "bin": {