@bitmagic/cli 0.1.46-dev.1 → 0.1.46-dev.3
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/LICENSE.md +204 -0
- package/README.md +28 -3
- package/dist/auth/subscribe-flow.d.ts +29 -6
- package/dist/auth/subscribe-flow.js +64 -29
- package/dist/auth/subscribe-flow.js.map +1 -1
- package/dist/cli.d.ts +19 -1
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/init.js +6 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.js +11 -5
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/reset-account.d.ts +90 -0
- package/dist/commands/reset-account.js +211 -0
- package/dist/commands/reset-account.js.map +1 -0
- package/dist/commands/subscribe.d.ts +1 -1
- package/dist/commands/subscribe.js +10 -7
- package/dist/commands/subscribe.js.map +1 -1
- package/dist/scaffold/claude-settings.js +21 -10
- package/dist/scaffold/claude-settings.js.map +1 -1
- package/dist/scaffold/engine-download.js +15 -1
- package/dist/scaffold/engine-download.js.map +1 -1
- package/dist/scaffold/project-files.d.ts +18 -0
- package/dist/scaffold/project-files.js +94 -36
- package/dist/scaffold/project-files.js.map +1 -1
- package/dist/scaffold/project.d.ts +10 -0
- package/dist/scaffold/project.js +16 -0
- package/dist/scaffold/project.js.map +1 -1
- package/dist/scaffold/upgrade-project.js +10 -1
- package/dist/scaffold/upgrade-project.js.map +1 -1
- package/package.json +8 -5
package/dist/commands/login.js
CHANGED
|
@@ -44,6 +44,12 @@ export const loginCommand = defineCommand({
|
|
|
44
44
|
// subscribed yet — otherwise the first thing a new creator would meet is a 403.
|
|
45
45
|
const me = await fetchWhoami(environment, credentials.accessToken, defaultSubscribeDeps);
|
|
46
46
|
output.info(`Logged in to ${environment.name} as ${me.userId}.`);
|
|
47
|
+
// The terms notice. Placed here rather than behind a prompt on purpose: logging in IS the
|
|
48
|
+
// assenting act (api-server records which terms version this account accepted, keyed to the
|
|
49
|
+
// date on the page), so what this line owes the creator is notice, not another keystroke.
|
|
50
|
+
// The engine licence lives in section 5 of those terms and ships in full as engine/LICENSE.md.
|
|
51
|
+
// See docs/engine-license.md.
|
|
52
|
+
output.info('By using Bitmagic you agree to the terms at https://bitmagic.ai/terms-of-service');
|
|
47
53
|
if (me.pro) {
|
|
48
54
|
// Says "renews on X" — or warns when it will not, which is the only
|
|
49
55
|
// chance to mention that before a command is refused mid-work.
|
|
@@ -58,10 +64,10 @@ export const loginCommand = defineCommand({
|
|
|
58
64
|
// greeted as though they had never subscribed.
|
|
59
65
|
if (me.proUntil)
|
|
60
66
|
output.info(describeProStatus(me));
|
|
61
|
-
// Not subscribed: carry straight on
|
|
62
|
-
// error the creator has to decode. They are already in a
|
|
63
|
-
// just approved a device code in one.
|
|
64
|
-
const subscribed = await runSubscribeFlow(environment, credentials.accessToken, output, {
|
|
67
|
+
// Not subscribed: carry straight on to the Bitmagic Pro storefront rather
|
|
68
|
+
// than ending on an error the creator has to decode. They are already in a
|
|
69
|
+
// browser — they just approved a device code in one.
|
|
70
|
+
const subscribed = await runSubscribeFlow(environment, credentials.accessToken, me, output, {
|
|
65
71
|
noOpen: args.json === true,
|
|
66
72
|
});
|
|
67
73
|
output.result({
|
|
@@ -70,7 +76,7 @@ export const loginCommand = defineCommand({
|
|
|
70
76
|
userId: me.userId,
|
|
71
77
|
roles: me.roles,
|
|
72
78
|
pro: subscribed.pro,
|
|
73
|
-
...(subscribed.
|
|
79
|
+
...(subscribed.subscribeUrl ? { subscribeUrl: subscribed.subscribeUrl } : {}),
|
|
74
80
|
});
|
|
75
81
|
},
|
|
76
82
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAC9F,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,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;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAAC;IACxC,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,8CAA8C,EAAE;IACpF,IAAI,EAAE;QACJ,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8CAA8C,EAAE;QACpF,IAAI,EAAE;YACJ,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,kEAAkE;SAChF;KACF;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QAChB,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAChD,MAAM,SAAS,GAAG,2BAA2B,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACtE,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC;QAC1C,MAAM,QAAQ,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;QAEnD,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QAEnE,4FAA4F;QAC5F,sFAAsF;QACtF,wEAAwE;QACxE,MAAM,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,uBAAuB,EAAE,CAAC,CAAC;QACvD,MAAM,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAErC,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC3E,gBAAgB,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAChD,4FAA4F;QAC5F,8FAA8F;QAC9F,6FAA6F;QAC7F,+FAA+F;QAC/F,2FAA2F;QAC3F,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS;YAAE,uBAAuB,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAE9E,wFAAwF;QACxF,4FAA4F;QAC5F,wFAAwF;QACxF,gFAAgF;QAChF,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC,WAAW,EAAE,WAAW,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;QACzF,MAAM,CAAC,IAAI,CAAC,gBAAgB,WAAW,CAAC,IAAI,OAAO,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAC9F,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,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;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAAC;IACxC,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,8CAA8C,EAAE;IACpF,IAAI,EAAE;QACJ,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8CAA8C,EAAE;QACpF,IAAI,EAAE;YACJ,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,kEAAkE;SAChF;KACF;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QAChB,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAChD,MAAM,SAAS,GAAG,2BAA2B,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACtE,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC;QAC1C,MAAM,QAAQ,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;QAEnD,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QAEnE,4FAA4F;QAC5F,sFAAsF;QACtF,wEAAwE;QACxE,MAAM,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,uBAAuB,EAAE,CAAC,CAAC;QACvD,MAAM,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAErC,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC3E,gBAAgB,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAChD,4FAA4F;QAC5F,8FAA8F;QAC9F,6FAA6F;QAC7F,+FAA+F;QAC/F,2FAA2F;QAC3F,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS;YAAE,uBAAuB,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAE9E,wFAAwF;QACxF,4FAA4F;QAC5F,wFAAwF;QACxF,gFAAgF;QAChF,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC,WAAW,EAAE,WAAW,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;QACzF,MAAM,CAAC,IAAI,CAAC,gBAAgB,WAAW,CAAC,IAAI,OAAO,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;QACjE,0FAA0F;QAC1F,4FAA4F;QAC5F,0FAA0F;QAC1F,+FAA+F;QAC/F,8BAA8B;QAC9B,MAAM,CAAC,IAAI,CAAC,kFAAkF,CAAC,CAAC;QAEhG,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC;YACX,oEAAoE;YACpE,+DAA+D;YAC/D,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC;YACnC,MAAM,CAAC,MAAM,CAAC;gBACZ,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK;gBAC3E,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE,iBAAiB,EAAE,EAAE,CAAC,iBAAiB,IAAI,KAAK;aACnF,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,uEAAuE;QACvE,+CAA+C;QAC/C,IAAI,EAAE,CAAC,QAAQ;YAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC;QAEpD,0EAA0E;QAC1E,2EAA2E;QAC3E,qDAAqD;QACrD,MAAM,UAAU,GAAG,MAAM,gBAAgB,CAAC,WAAW,EAAE,WAAW,CAAC,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE;YAC1F,MAAM,EAAE,IAAI,CAAC,IAAI,KAAK,IAAI;SAC3B,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC;YACZ,EAAE,EAAE,IAAI;YACR,WAAW,EAAE,WAAW,CAAC,IAAI;YAC7B,MAAM,EAAE,EAAE,CAAC,MAAM;YACjB,KAAK,EAAE,EAAE,CAAC,KAAK;YACf,GAAG,EAAE,UAAU,CAAC,GAAG;YACnB,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9E,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { type Output } from '../output.js';
|
|
2
|
+
/**
|
|
3
|
+
* `bitmagic reset-account` — put your own account back to never-seen-before, so
|
|
4
|
+
* the first-run path can be walked again.
|
|
5
|
+
*
|
|
6
|
+
* Everything a new creator meets happens exactly once per identity: the device
|
|
7
|
+
* code, the terms notice, "no Bitmagic Pro subscription", Stripe checkout, the
|
|
8
|
+
* first `bitmagic init` and its 500 sparks. Testing a change to any of it used
|
|
9
|
+
* to mean finding a fresh Auth0 account. This deletes the account server-side
|
|
10
|
+
* instead, so the next `bitmagic login` provisions it from scratch.
|
|
11
|
+
*
|
|
12
|
+
* ── Why this cannot touch prod ──────────────────────────────────────────────
|
|
13
|
+
*
|
|
14
|
+
* The endpoint behind it is not registered on the production api-server at all,
|
|
15
|
+
* so the path does not exist there. This command refuses `--env prod` before it
|
|
16
|
+
* opens a socket anyway: the server would answer with a status code, and a
|
|
17
|
+
* sentence is a better thing to read than a 404.
|
|
18
|
+
*
|
|
19
|
+
* ── Why it asks ─────────────────────────────────────────────────────────────
|
|
20
|
+
*
|
|
21
|
+
* The confirmation wants the ENVIRONMENT NAME typed back, not a y/n. The whole
|
|
22
|
+
* hazard here is running the right command against the wrong environment, and
|
|
23
|
+
* "y" is the same keystroke whichever one you are pointed at. `--yes` skips it
|
|
24
|
+
* for scripts, and a non-interactive shell must pass `--yes` explicitly rather
|
|
25
|
+
* than have the prompt silently pass — an agent should not be able to delete a
|
|
26
|
+
* creator's account by running a command it read in a doc.
|
|
27
|
+
*/
|
|
28
|
+
/** What the api-server says a reset would destroy. */
|
|
29
|
+
export interface ResetPreview {
|
|
30
|
+
userId: string;
|
|
31
|
+
email: string;
|
|
32
|
+
publicId: string | null;
|
|
33
|
+
games: number;
|
|
34
|
+
sparkBalance: number;
|
|
35
|
+
hasProSubscription: boolean;
|
|
36
|
+
stripeSubscriptionId: string | null;
|
|
37
|
+
hasProGrant: boolean;
|
|
38
|
+
/** vip_users is keyed by email and survives the reset — worth saying out loud. */
|
|
39
|
+
vip: boolean;
|
|
40
|
+
}
|
|
41
|
+
export interface ResetAccountDeps {
|
|
42
|
+
fetch: typeof globalThis.fetch;
|
|
43
|
+
sleep: (ms: number) => Promise<void>;
|
|
44
|
+
/** Whether a human is at the keyboard; injected so the rule is testable. */
|
|
45
|
+
interactive: () => boolean;
|
|
46
|
+
/** Reads one line of confirmation. */
|
|
47
|
+
ask: (question: string) => Promise<string>;
|
|
48
|
+
/** Removes the globally installed CLI. Returns false if it could not. */
|
|
49
|
+
uninstall: () => boolean;
|
|
50
|
+
}
|
|
51
|
+
export declare const defaultResetDeps: ResetAccountDeps;
|
|
52
|
+
/** PURE. The lines shown before the confirmation. */
|
|
53
|
+
export declare function formatResetPreview(preview: ResetPreview, environmentName: string): string;
|
|
54
|
+
export interface ResetAccountOptions {
|
|
55
|
+
env?: string;
|
|
56
|
+
yes?: boolean;
|
|
57
|
+
uninstall?: boolean;
|
|
58
|
+
deps?: ResetAccountDeps;
|
|
59
|
+
/** Test-only credentials-directory override, matching the rest of the CLI. */
|
|
60
|
+
baseDir?: string;
|
|
61
|
+
}
|
|
62
|
+
export interface ResetAccountResult {
|
|
63
|
+
environment: string;
|
|
64
|
+
userId: string;
|
|
65
|
+
stripeSubscriptionCanceled: boolean;
|
|
66
|
+
deleted: Record<string, number>;
|
|
67
|
+
credentialsCleared: boolean;
|
|
68
|
+
cliUninstalled: boolean;
|
|
69
|
+
}
|
|
70
|
+
export declare function runResetAccount(options: ResetAccountOptions, output: Output): Promise<ResetAccountResult>;
|
|
71
|
+
/** PURE. What to do next, given what the reset just did. */
|
|
72
|
+
export declare function formatNextSteps(result: ResetAccountResult): string;
|
|
73
|
+
export declare const resetAccountCommand: import("citty").CommandDef<{
|
|
74
|
+
readonly env: {
|
|
75
|
+
readonly type: "string";
|
|
76
|
+
readonly description: "Environment to reset in (dev, local). Never prod.";
|
|
77
|
+
};
|
|
78
|
+
readonly yes: {
|
|
79
|
+
readonly type: "boolean";
|
|
80
|
+
readonly description: "Skip the confirmation. Required in a non-interactive shell.";
|
|
81
|
+
};
|
|
82
|
+
readonly uninstall: {
|
|
83
|
+
readonly type: "boolean";
|
|
84
|
+
readonly description: "Also `npm uninstall -g @bitmagic/cli` afterwards, so the next run starts at the install.";
|
|
85
|
+
};
|
|
86
|
+
readonly json: {
|
|
87
|
+
readonly type: "boolean";
|
|
88
|
+
readonly description: "Print the result as JSON on stdout; all progress goes to stderr.";
|
|
89
|
+
};
|
|
90
|
+
}>;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { defineCommand } from 'citty';
|
|
2
|
+
import { spawnSync } from 'child_process';
|
|
3
|
+
import { createInterface } from 'readline/promises';
|
|
4
|
+
import { selectEnvironmentForCommand, resolveAuth0ClientId } from '../config/environments.js';
|
|
5
|
+
import { clearCredentials } from '../config/credentials.js';
|
|
6
|
+
import { getAccessToken } from '../auth/session.js';
|
|
7
|
+
import { createOutput } from '../output.js';
|
|
8
|
+
import { CliError } from '../errors.js';
|
|
9
|
+
async function askOnStdin(question) {
|
|
10
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
11
|
+
try {
|
|
12
|
+
return (await rl.question(question)).trim();
|
|
13
|
+
}
|
|
14
|
+
finally {
|
|
15
|
+
rl.close();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function uninstallGlobally() {
|
|
19
|
+
const result = spawnSync('npm', ['uninstall', '-g', '@bitmagic/cli'], { stdio: 'inherit' });
|
|
20
|
+
return !result.error && result.status === 0;
|
|
21
|
+
}
|
|
22
|
+
export const defaultResetDeps = {
|
|
23
|
+
fetch: globalThis.fetch,
|
|
24
|
+
sleep: (ms) => new Promise((r) => setTimeout(r, ms)),
|
|
25
|
+
interactive: () => process.stdin.isTTY === true,
|
|
26
|
+
ask: askOnStdin,
|
|
27
|
+
uninstall: uninstallGlobally,
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* This command does NOT go through http/client.ts, and that is deliberate.
|
|
31
|
+
*
|
|
32
|
+
* Its shared mapping turns 503 into "this feature is unavailable in this
|
|
33
|
+
* environment" and everything else into "api-server returned HTTP n" — fine for
|
|
34
|
+
* the twenty routes that only ever fail one way, useless for this one, whose
|
|
35
|
+
* three interesting failures each need their own sentence: the endpoint is not
|
|
36
|
+
* deployed here, Stripe could not be reached so NOTHING was deleted, and Stripe
|
|
37
|
+
* is not configured so the subscription cannot be cancelled. The server sends
|
|
38
|
+
* the reason in the body; this reads it.
|
|
39
|
+
*/
|
|
40
|
+
async function resetRequest(environment, path, token, method, deps) {
|
|
41
|
+
let response;
|
|
42
|
+
try {
|
|
43
|
+
response = await deps.fetch(`${environment.apiUrl}${path}`, {
|
|
44
|
+
method,
|
|
45
|
+
headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' },
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
throw new CliError(`Cannot reach api-server at ${environment.apiUrl}.`);
|
|
50
|
+
}
|
|
51
|
+
if (response.ok)
|
|
52
|
+
return (await response.json());
|
|
53
|
+
let serverMessage = null;
|
|
54
|
+
try {
|
|
55
|
+
const body = (await response.json());
|
|
56
|
+
if (typeof body.error === 'string')
|
|
57
|
+
serverMessage = body.error;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// No body, or not JSON. The status alone still has to produce a sentence.
|
|
61
|
+
}
|
|
62
|
+
if (response.status === 401) {
|
|
63
|
+
throw new CliError('Your session has expired. Run `bitmagic login`.');
|
|
64
|
+
}
|
|
65
|
+
if (response.status === 404) {
|
|
66
|
+
// Two very different things share this status: the account is already gone
|
|
67
|
+
// (the server says so in the body) or the route was never mounted, which is
|
|
68
|
+
// what production looks like from out here.
|
|
69
|
+
if (serverMessage)
|
|
70
|
+
throw new CliError(serverMessage);
|
|
71
|
+
throw new CliError(`The "${environment.name}" api-server has no account-reset endpoint. It exists only outside ` +
|
|
72
|
+
'production, and only on api-servers new enough to have it.');
|
|
73
|
+
}
|
|
74
|
+
if (response.status === 403) {
|
|
75
|
+
throw new CliError(`The "${environment.name}" api-server refused the reset. It exists only outside production.`);
|
|
76
|
+
}
|
|
77
|
+
throw new CliError(serverMessage ?? `api-server returned HTTP ${response.status} for ${path}. Nothing was deleted.`);
|
|
78
|
+
}
|
|
79
|
+
/** PURE. The lines shown before the confirmation. */
|
|
80
|
+
export function formatResetPreview(preview, environmentName) {
|
|
81
|
+
const lines = [
|
|
82
|
+
`This DELETES your Bitmagic account on ${environmentName}.`,
|
|
83
|
+
'',
|
|
84
|
+
` account ${preview.userId} (${preview.email})`,
|
|
85
|
+
` games ${preview.games}`,
|
|
86
|
+
` sparks ${preview.sparkBalance.toLocaleString('en-US')}`,
|
|
87
|
+
];
|
|
88
|
+
if (preview.hasProSubscription) {
|
|
89
|
+
lines.push(' pro subscription — WILL BE CANCELLED IN STRIPE, then deleted');
|
|
90
|
+
}
|
|
91
|
+
else if (preview.hasProGrant) {
|
|
92
|
+
lines.push(' pro comped grant — deleted');
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
lines.push(' pro none');
|
|
96
|
+
}
|
|
97
|
+
lines.push('');
|
|
98
|
+
lines.push('Also removed: your profile, terms acceptance, XP, likes, follows, comments and');
|
|
99
|
+
lines.push('published game entries. Your next `bitmagic login` starts over from nothing.');
|
|
100
|
+
if (preview.vip) {
|
|
101
|
+
// Says so up front rather than letting it read as a failed reset later.
|
|
102
|
+
lines.push('');
|
|
103
|
+
lines.push('NOTE: this email is on the VIP list, which is keyed by email and is NOT reset.');
|
|
104
|
+
lines.push(' The new account will not start on the free tier.');
|
|
105
|
+
}
|
|
106
|
+
return lines.join('\n');
|
|
107
|
+
}
|
|
108
|
+
export async function runResetAccount(options, output) {
|
|
109
|
+
const deps = options.deps ?? defaultResetDeps;
|
|
110
|
+
const { environment } = selectEnvironmentForCommand({
|
|
111
|
+
explicit: options.env,
|
|
112
|
+
...(options.baseDir !== undefined ? { baseDir: options.baseDir } : {}),
|
|
113
|
+
});
|
|
114
|
+
// Before anything else, including reading a token: pointing this at prod is
|
|
115
|
+
// the mistake worth catching with a sentence rather than a status code.
|
|
116
|
+
if (environment.name === 'prod') {
|
|
117
|
+
throw new CliError('There is no account reset on prod — the endpoint is not deployed there. ' +
|
|
118
|
+
'Run this against dev or local (`bitmagic reset-account --env dev`).');
|
|
119
|
+
}
|
|
120
|
+
const clientId = resolveAuth0ClientId(environment);
|
|
121
|
+
const token = await getAccessToken(environment, clientId, deps, options.baseDir);
|
|
122
|
+
const { preview } = await resetRequest(environment, '/api/cli/v1/account/reset/preview', token, 'GET', deps);
|
|
123
|
+
output.info(formatResetPreview(preview, environment.name));
|
|
124
|
+
output.info('');
|
|
125
|
+
if (options.yes !== true) {
|
|
126
|
+
if (!deps.interactive()) {
|
|
127
|
+
throw new CliError('Deleting an account has to be confirmed by a person, and this shell has no terminal. ' +
|
|
128
|
+
'Run it yourself, or pass --yes if you meant it.');
|
|
129
|
+
}
|
|
130
|
+
// The environment name, not y/n: the hazard is doing the right thing to the
|
|
131
|
+
// wrong environment, and "y" reads identically whichever one you are on.
|
|
132
|
+
const answer = await deps.ask(`Type "${environment.name}" to confirm: `);
|
|
133
|
+
if (answer !== environment.name) {
|
|
134
|
+
throw new CliError('Not confirmed — nothing was deleted.');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const result = await resetRequest(environment, '/api/cli/v1/account/reset', token, 'POST', deps);
|
|
138
|
+
if (result.stripeSubscriptionCanceled)
|
|
139
|
+
output.info('Cancelled the Bitmagic Pro subscription in Stripe.');
|
|
140
|
+
output.info(`Deleted the account on ${environment.name}.`);
|
|
141
|
+
// A cached access token outliving the user row would leave the CLI looking
|
|
142
|
+
// logged in as an account that no longer exists — and the first command to
|
|
143
|
+
// notice would fail somewhere unrelated.
|
|
144
|
+
clearCredentials(environment.name, options.baseDir);
|
|
145
|
+
output.info(`Cleared the stored ${environment.name} credentials.`);
|
|
146
|
+
// Last, because it removes the code this process is running from. Safe where
|
|
147
|
+
// it matters: every module is already loaded by the time this line runs, and
|
|
148
|
+
// nothing after it does a dynamic import — only already-resident code and Node
|
|
149
|
+
// builtins. Do not add an `await import()` below this point.
|
|
150
|
+
let cliUninstalled = false;
|
|
151
|
+
if (options.uninstall === true) {
|
|
152
|
+
cliUninstalled = deps.uninstall();
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
environment: environment.name,
|
|
156
|
+
userId: result.userId,
|
|
157
|
+
stripeSubscriptionCanceled: result.stripeSubscriptionCanceled,
|
|
158
|
+
deleted: result.deleted,
|
|
159
|
+
credentialsCleared: true,
|
|
160
|
+
cliUninstalled,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/** PURE. What to do next, given what the reset just did. */
|
|
164
|
+
export function formatNextSteps(result) {
|
|
165
|
+
const lines = [
|
|
166
|
+
'',
|
|
167
|
+
'Next:',
|
|
168
|
+
];
|
|
169
|
+
if (result.cliUninstalled) {
|
|
170
|
+
// The full first run starts at the install, which is why --uninstall exists.
|
|
171
|
+
lines.push(' npm install -g @bitmagic/cli');
|
|
172
|
+
}
|
|
173
|
+
lines.push(` bitmagic login${result.environment === 'dev' ? '' : ` --env ${result.environment}`}`);
|
|
174
|
+
lines.push(' bitmagic init <a new directory>');
|
|
175
|
+
lines.push('');
|
|
176
|
+
lines.push('Any project you scaffolded earlier still names a gameId that no longer exists —');
|
|
177
|
+
lines.push('nothing on disk was touched, so start the fresh run in a new directory.');
|
|
178
|
+
return lines.join('\n');
|
|
179
|
+
}
|
|
180
|
+
export const resetAccountCommand = defineCommand({
|
|
181
|
+
meta: {
|
|
182
|
+
name: 'reset-account',
|
|
183
|
+
description: 'Delete your account on dev or local so the first-run experience can be tested again.',
|
|
184
|
+
},
|
|
185
|
+
args: {
|
|
186
|
+
env: { type: 'string', description: 'Environment to reset in (dev, local). Never prod.' },
|
|
187
|
+
yes: { type: 'boolean', description: 'Skip the confirmation. Required in a non-interactive shell.' },
|
|
188
|
+
uninstall: {
|
|
189
|
+
type: 'boolean',
|
|
190
|
+
description: 'Also `npm uninstall -g @bitmagic/cli` afterwards, so the next run starts at the install.',
|
|
191
|
+
},
|
|
192
|
+
json: {
|
|
193
|
+
type: 'boolean',
|
|
194
|
+
description: 'Print the result as JSON on stdout; all progress goes to stderr.',
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
async run({ args }) {
|
|
198
|
+
const output = createOutput(args.json === true);
|
|
199
|
+
const result = await runResetAccount({ env: args.env, yes: args.yes === true, uninstall: args.uninstall === true }, output);
|
|
200
|
+
output.info(formatNextSteps(result));
|
|
201
|
+
output.result({ ok: true, ...result });
|
|
202
|
+
if (args.uninstall === true && !result.cliUninstalled) {
|
|
203
|
+
// A warning, not a failure: the account IS reset, and the JSON document
|
|
204
|
+
// above already said so. Only the last step did not happen.
|
|
205
|
+
output.info('');
|
|
206
|
+
output.info('Warning: `npm uninstall -g @bitmagic/cli` did not succeed. If you installed the CLI with ' +
|
|
207
|
+
'pnpm, yarn or npx, remove it the same way you added it.');
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
//# sourceMappingURL=reset-account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reset-account.js","sourceRoot":"","sources":["../../src/commands/reset-account.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@ export declare const subscribeCommand: import("citty").CommandDef<{
|
|
|
5
5
|
};
|
|
6
6
|
readonly 'no-wait': {
|
|
7
7
|
readonly type: "boolean";
|
|
8
|
-
readonly description: "Open
|
|
8
|
+
readonly description: "Open the Bitmagic Pro page and exit instead of waiting for it to complete.";
|
|
9
9
|
};
|
|
10
10
|
readonly json: {
|
|
11
11
|
readonly type: "boolean";
|
|
@@ -7,17 +7,20 @@ import { createOutput } from '../output.js';
|
|
|
7
7
|
* `bitmagic subscribe` — start (or finish) a Bitmagic Pro subscription.
|
|
8
8
|
*
|
|
9
9
|
* `login` already runs this flow for a creator who has not subscribed, so this
|
|
10
|
-
* command exists for the second attempt: someone who closed the
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* command exists for the second attempt: someone who closed the tab, whose card
|
|
11
|
+
* was declined, or whose subscription has since lapsed. Same code path, so the
|
|
12
|
+
* recovery looks exactly like the first run rather than being a differently-worded
|
|
13
|
+
* special case.
|
|
14
|
+
*
|
|
15
|
+
* It opens the Bitmagic Pro storefront, which sells a subscription AND redeems a
|
|
16
|
+
* Pro voucher — so this is the command to reach for with a comped-Pro code too.
|
|
14
17
|
*/
|
|
15
18
|
const deviceFlowDeps = { fetch: globalThis.fetch, sleep: (ms) => new Promise((r) => setTimeout(r, ms)) };
|
|
16
19
|
export const subscribeCommand = defineCommand({
|
|
17
20
|
meta: { name: 'subscribe', description: 'Start a Bitmagic Pro subscription, which the CLI requires.' },
|
|
18
21
|
args: {
|
|
19
22
|
env: { type: 'string', description: 'Environment to subscribe in (dev, prod, local).' },
|
|
20
|
-
'no-wait': { type: 'boolean', description: 'Open
|
|
23
|
+
'no-wait': { type: 'boolean', description: 'Open the Bitmagic Pro page and exit instead of waiting for it to complete.' },
|
|
21
24
|
json: {
|
|
22
25
|
type: 'boolean',
|
|
23
26
|
description: 'Print the result as JSON on stdout; all progress goes to stderr.',
|
|
@@ -40,7 +43,7 @@ export const subscribeCommand = defineCommand({
|
|
|
40
43
|
if (me.proUntil) {
|
|
41
44
|
output.info(`Your previous Bitmagic Pro subscription ended on ${me.proUntil.slice(0, 10)}.`);
|
|
42
45
|
}
|
|
43
|
-
const result = await runSubscribeFlow(environment, token, output, {
|
|
46
|
+
const result = await runSubscribeFlow(environment, token, me, output, {
|
|
44
47
|
noOpen: args.json === true,
|
|
45
48
|
noWait: args['no-wait'] === true,
|
|
46
49
|
});
|
|
@@ -48,7 +51,7 @@ export const subscribeCommand = defineCommand({
|
|
|
48
51
|
ok: true,
|
|
49
52
|
pro: result.pro,
|
|
50
53
|
userId: me.userId,
|
|
51
|
-
...(result.
|
|
54
|
+
...(result.subscribeUrl ? { subscribeUrl: result.subscribeUrl } : {}),
|
|
52
55
|
...(result.reason ? { reason: result.reason } : {}),
|
|
53
56
|
});
|
|
54
57
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subscribe.js","sourceRoot":"","sources":["../../src/commands/subscribe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAC/F,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C
|
|
1
|
+
{"version":3,"file":"subscribe.js","sourceRoot":"","sources":["../../src/commands/subscribe.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,17 +36,23 @@ function reloadMatcher() {
|
|
|
36
36
|
/**
|
|
37
37
|
* The `bitmagic` commands a new project pre-approves, so the agent is not prompted for them.
|
|
38
38
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
39
|
+
* The local, idempotent ones are here because AGENTS.md tells the agent to run them repeatedly —
|
|
40
|
+
* `check` after each edit, `reload` at the end of each turn, `verify` before declaring anything
|
|
41
|
+
* done. A prompt on those is pure friction.
|
|
42
42
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
43
|
+
* `generate`, `cover` and `forge` are here for a different reason: they are funded by the rolling
|
|
44
|
+
* spark allowance the creator already bought with Bitmagic Pro, and prompting per asset does not
|
|
45
|
+
* protect them from a bill — it just produces a game full of placeholders instead of the assets
|
|
46
|
+
* they are paying to have generated. The boundary worth defending is the SPILL past that allowance
|
|
47
|
+
* into their purchased spark balance, and that one is enforced in code rather than in prose:
|
|
48
|
+
* `bitmagic allowance --allow-sparks` refuses without a TTY, so an agent cannot self-authorise it
|
|
49
|
+
* (see `../commands/allowance.ts`, and `docs/pro-subscription.md` on why a doc rule saying "the
|
|
50
|
+
* agent must not run this" does not survive an agent that reads the exact command in a refusal).
|
|
51
|
+
*
|
|
52
|
+
* What remains deliberately ABSENT: `publish`, because `--visibility public` lists the game on
|
|
53
|
+
* bitmagic.ai; `upgrade`, because it replaces `engine/` wholesale and the creator should see that
|
|
54
|
+
* coming; `subscribe` and `allowance`, which are money and consent. A blanket `Bash(bitmagic:*)`
|
|
55
|
+
* would swallow all four, so the list stays explicit.
|
|
50
56
|
*/
|
|
51
57
|
const ALLOWED_COMMANDS = [
|
|
52
58
|
'Bash(bitmagic check:*)',
|
|
@@ -59,6 +65,11 @@ const ALLOWED_COMMANDS = [
|
|
|
59
65
|
// to run WITHOUT interrupting the human — the whole point is checking what
|
|
60
66
|
// something will cost before committing to it.
|
|
61
67
|
'Bash(bitmagic usage:*)',
|
|
68
|
+
// Allowance-funded content generation. See the note above: the gate that
|
|
69
|
+
// matters is the TTY-only `allowance --allow-sparks`, not a prompt per asset.
|
|
70
|
+
'Bash(bitmagic generate:*)',
|
|
71
|
+
'Bash(bitmagic cover:*)',
|
|
72
|
+
'Bash(bitmagic forge:*)',
|
|
62
73
|
];
|
|
63
74
|
/**
|
|
64
75
|
* The settings a project with no `.claude/settings.json` at all gets.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-settings.js","sourceRoot":"","sources":["../../src/scaffold/claude-settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,uBAAuB,CAAC;AAE5D,yFAAyF;AACzF,MAAM,CAAC,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AAkBrD,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,SAAS,CAAC,QAAiB;IAClC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AAClD,CAAC;AAED,8CAA8C;AAC9C,SAAS,aAAa;IACpB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC,EAAE,CAAC;AACxE,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"claude-settings.js","sourceRoot":"","sources":["../../src/scaffold/claude-settings.ts"],"names":[],"mappings":"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"}
|
|
@@ -38,6 +38,18 @@ export async function downloadAndVerify(tarballUrl, expectedSha256, targetPath,
|
|
|
38
38
|
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
39
39
|
fs.writeFileSync(targetPath, body);
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Tarball entries that are single files sitting directly under `game/` rather than inside one of
|
|
43
|
+
* the vendored directories. They share `game/agent-docs/`'s strip depth, so they ride its pass.
|
|
44
|
+
*
|
|
45
|
+
* `sw-cache-buster.js` is a runtime file the scaffolder later moves to the project root, and the
|
|
46
|
+
* two licence files are the terms the engine ships under (see docs/engine-license.md).
|
|
47
|
+
*/
|
|
48
|
+
const ENGINE_ROOT_FILES = [
|
|
49
|
+
'game/sw-cache-buster.js',
|
|
50
|
+
'game/LICENSE.md',
|
|
51
|
+
'game/THIRD-PARTY-NOTICES.md',
|
|
52
|
+
];
|
|
41
53
|
/**
|
|
42
54
|
* The tarball stores three prefixes at different depths — game/src/<root>, game/agent-docs (plus
|
|
43
55
|
* the sibling game/sw-cache-buster.js, which shares its strip depth) and templates — so it takes
|
|
@@ -67,11 +79,13 @@ export async function extractEngine(tarballPath, engineDir, templatesDir) {
|
|
|
67
79
|
// engine-api/ signature digest and samples/ subdirectories.
|
|
68
80
|
// game/sw-cache-buster.js -> <engineDir>/sw-cache-buster.js (rides this pass because it needs
|
|
69
81
|
// the same strip depth as game/agent-docs/, even though it isn't under it)
|
|
82
|
+
// game/LICENSE.md and game/THIRD-PARTY-NOTICES.md ride it for the same reason, and land next to
|
|
83
|
+
// the code they license as <engineDir>/LICENSE.md and <engineDir>/THIRD-PARTY-NOTICES.md.
|
|
70
84
|
await tar.extract({
|
|
71
85
|
file: tarballPath,
|
|
72
86
|
cwd: engineDir,
|
|
73
87
|
strip: 1,
|
|
74
|
-
filter: (entryPath) => entryPath.startsWith('game/agent-docs/') || entryPath
|
|
88
|
+
filter: (entryPath) => entryPath.startsWith('game/agent-docs/') || ENGINE_ROOT_FILES.includes(entryPath),
|
|
75
89
|
});
|
|
76
90
|
// templates/index.json -> <templatesDir>/index.json
|
|
77
91
|
await tar.extract({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine-download.js","sourceRoot":"","sources":["../../src/scaffold/engine-download.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"engine-download.js","sourceRoot":"","sources":["../../src/scaffold/engine-download.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,MAAM,EAAgB,MAAM,mBAAmB,CAAC;AAczD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,WAAwB,EACxB,WAAmB,EACnB,IAAa;IAEb,OAAO,MAAM,CAAiB,WAAW,EAAE,6BAA6B,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;AAC/F,CAAC;AAMD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,UAAkB,EAClB,cAAsB,EACtB,UAAkB,EAClB,IAAkB;IAElB,IAAI,QAAuB,CAAC;IAC5B,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,QAAQ,CAAC,4DAA4D,CAAC,CAAC;IACnF,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,QAAQ,CAAC,2CAA2C,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IACpF,CAAC;IAED,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,QAAQ,CAChB,0GAA0G,CAC3G,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtE,IAAI,MAAM,KAAK,cAAc,EAAE,CAAC;QAC9B,MAAM,IAAI,QAAQ,CAChB,0EAA0E;YACxE,iEAAiE,CACpE,CAAC;IACJ,CAAC;IAED,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,iBAAiB,GAAG;IACxB,yBAAyB;IACzB,iBAAiB;IACjB,6BAA6B;CAC9B,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,WAAmB,EACnB,SAAiB,EACjB,YAAoB;IAEpB,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhD,kDAAkD;IAClD,MAAM,GAAG,CAAC,OAAO,CAAC;QAChB,IAAI,EAAE,WAAW;QACjB,GAAG,EAAE,SAAS;QACd,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,WAAW,CAAC;KACjE,CAAC,CAAC;IAEH,8FAA8F;IAC9F,4DAA4D;IAC5D,8FAA8F;IAC9F,2EAA2E;IAC3E,gGAAgG;IAChG,0FAA0F;IAC1F,MAAM,GAAG,CAAC,OAAO,CAAC;QAChB,IAAI,EAAE,WAAW;QACjB,GAAG,EAAE,SAAS;QACd,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC,SAAiB,EAAE,EAAE,CAC5B,SAAS,CAAC,UAAU,CAAC,kBAAkB,CAAC,IAAI,iBAAiB,CAAC,QAAQ,CAAC,SAAS,CAAC;KACpF,CAAC,CAAC;IAEH,oDAAoD;IACpD,MAAM,GAAG,CAAC,OAAO,CAAC;QAChB,IAAI,EAAE,WAAW;QACjB,GAAG,EAAE,YAAY;QACjB,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,YAAY,CAAC;KAClE,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
import type { EnvironmentName } from '../config/environments.js';
|
|
2
|
+
/**
|
|
3
|
+
* The legal notice stamped into every game this project publishes.
|
|
4
|
+
*
|
|
5
|
+
* **A licence obligation, not decoration.** A published game is one file with the engine and its
|
|
6
|
+
* third-party dependencies inlined, so distributing a game distributes part of the engine.
|
|
7
|
+
* PolyForm Shield's Notices section requires that anyone receiving any part of the software also
|
|
8
|
+
* receives the terms and every `Required Notice:` line; MIT and ISC require their copyright and
|
|
9
|
+
* permission notices to travel with copies; Apache-2.0 section 4 requires the licence to accompany
|
|
10
|
+
* derivative distributions. One banner satisfies all of them. See `engine/LICENSE.md`.
|
|
11
|
+
*
|
|
12
|
+
* This is a second copy of `game/publish-notice.js` — deliberately, because a scaffolded project
|
|
13
|
+
* on a creator's machine cannot import from the Bitmagic monorepo. `__tests__/publish-notice.test.ts`
|
|
14
|
+
* holds it to the content that actually has to be there.
|
|
15
|
+
*
|
|
16
|
+
* Kept small on purpose: `ENGINE_BUILD_MARKERS` in `@bitmagic/asset-core/publish-source` are
|
|
17
|
+
* matched only in a published bundle's first 64KB, and everything here pushes the import map down.
|
|
18
|
+
*/
|
|
19
|
+
export declare const PUBLISHED_BUNDLE_BANNER = "/*!\n * Made with Bitmagic \u2014 https://bitmagic.ai\n *\n * This bundle includes the Bitmagic engine.\n * Required Notice: Copyright Bitmagic Oy (https://bitmagic.ai)\n * Licensed under the PolyForm Shield License 1.0.0\n * <https://polyformproject.org/licenses/shield/1.0.0>, with an additional permission\n * granting the right to build, modify, sell and distribute games. Full terms:\n * https://bitmagic.ai/terms-of-service\n *\n * Third-party software included in this bundle:\n * three.js \u2014 MIT \u2014 Copyright (c) 2010-2026 three.js authors\n * @dimforge/rapier2d-compat, @dimforge/rapier3d-compat \u2014 Apache License 2.0\n * @msgpack/msgpack \u2014 ISC \u2014 Copyright 2019 The MessagePack Community\n * fflate \u2014 MIT \u2014 Copyright (c) 2023 Arjun Barrett\n * i18next, i18next-browser-languagedetector \u2014 MIT \u2014 Copyright (c) 2025 i18next\n * JSZip \u2014 MIT (elected) \u2014 Copyright (c) 2009-2016 Stuart Knightley and contributors\n * Full licence texts: THIRD-PARTY-NOTICES.md in the Bitmagic engine distribution.\n */";
|
|
2
20
|
/**
|
|
3
21
|
* Mirrors game/package.json so the pro lane resolves exactly what CI builds against.
|
|
4
22
|
*
|