@bitmagic/cli 0.1.65-dev.9 → 0.1.65
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 +101 -15
- package/dist/assets/materials.d.ts +9 -0
- package/dist/assets/materials.js +10 -2
- package/dist/assets/materials.js.map +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/character.d.ts +18 -0
- package/dist/commands/character.js +268 -0
- package/dist/commands/character.js.map +1 -0
- package/dist/commands/forge.js +7 -1
- package/dist/commands/forge.js.map +1 -1
- package/dist/commands/generate.d.ts +31 -13
- package/dist/commands/generate.js +48 -56
- package/dist/commands/generate.js.map +1 -1
- package/dist/editor/animation-preview-page.js +88 -1
- package/dist/editor/animation-preview-page.js.map +1 -1
- package/dist/editor/asset-detail-panel.d.ts +2 -2
- package/dist/editor/asset-detail-panel.js +21 -0
- package/dist/editor/asset-detail-panel.js.map +1 -1
- package/dist/editor/asset-viewer.js +31 -8
- package/dist/editor/asset-viewer.js.map +1 -1
- package/dist/editor/shell-page.js +63 -1
- package/dist/editor/shell-page.js.map +1 -1
- package/dist/forge/prune-store.d.ts +46 -0
- package/dist/forge/prune-store.js +86 -0
- package/dist/forge/prune-store.js.map +1 -0
- package/dist/generate/character-body.d.ts +79 -0
- package/dist/generate/character-body.js +100 -0
- package/dist/generate/character-body.js.map +1 -0
- package/dist/mobile/asset-hosts.d.ts +7 -9
- package/dist/mobile/asset-hosts.js +7 -16
- package/dist/mobile/asset-hosts.js.map +1 -1
- package/dist/project/character-search.d.ts +30 -0
- package/dist/project/character-search.js +82 -0
- package/dist/project/character-search.js.map +1 -0
- package/dist/scaffold/asset-pipeline-skill-files.d.ts +42 -0
- package/dist/scaffold/asset-pipeline-skill-files.js +207 -0
- package/dist/scaffold/asset-pipeline-skill-files.js.map +1 -0
- package/dist/scaffold/blender-level-skill-files.js +3 -2
- package/dist/scaffold/blender-level-skill-files.js.map +1 -1
- package/dist/scaffold/claude-settings.js +4 -0
- package/dist/scaffold/claude-settings.js.map +1 -1
- package/dist/scaffold/project-files.js +18 -12
- package/dist/scaffold/project-files.js.map +1 -1
- package/dist/scaffold/project.js +2 -0
- package/dist/scaffold/project.js.map +1 -1
- package/dist/scaffold/skill-files.js +5 -4
- package/dist/scaffold/skill-files.js.map +1 -1
- package/dist/telemetry/creator-prompt.d.ts +18 -2
- package/dist/telemetry/creator-prompt.js +24 -3
- package/dist/telemetry/creator-prompt.js.map +1 -1
- package/dist/telemetry/report.js +31 -16
- package/dist/telemetry/report.js.map +1 -1
- package/package.json +4 -4
|
@@ -52,8 +52,9 @@ export function withParent(body) {
|
|
|
52
52
|
return 'creatorPrompt' in field ? { ...body, ...field } : body;
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
|
-
* The creator's ask as an opaque, stable dedupe key — what
|
|
56
|
-
*
|
|
55
|
+
* The creator's ask as an opaque, stable dedupe key — what a game's "Built with N prompts" is
|
|
56
|
+
* counted on, so the COUNT never depends on storing anybody's words. (The beacon also carries the
|
|
57
|
+
* words themselves in {@link creatorAskText}, for a channel that shows them and stores nothing.)
|
|
57
58
|
*
|
|
58
59
|
* The CLI is the ONLY producer of this value. api-server stores it and compares it to other
|
|
59
60
|
* values from this same function; it never recomputes one from text, so the two sides cannot
|
|
@@ -68,9 +69,29 @@ export function withParent(body) {
|
|
|
68
69
|
* `--original-prompt` produces — the count is a floor, never an overcount.
|
|
69
70
|
*/
|
|
70
71
|
export function creatorAskDigest(override) {
|
|
72
|
+
const text = creatorAskText(override);
|
|
73
|
+
if (text === undefined)
|
|
74
|
+
return undefined;
|
|
75
|
+
return createHash('sha256').update(text).digest('hex').slice(0, 16);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The creator's ask as TEXT, bounded for a wire that has a body limit.
|
|
79
|
+
*
|
|
80
|
+
* The beacon carries this so the live-prompts Slack channel can show what an
|
|
81
|
+
* agent is being asked for on the commands that send no prompt anywhere else —
|
|
82
|
+
* `build`, `verify`, `dev`, `reload`, `publish` — which are most of what
|
|
83
|
+
* building a GDK project consists of. api-server posts it and never stores it:
|
|
84
|
+
* the count still runs on {@link creatorAskDigest}, and no prompt text reaches
|
|
85
|
+
* Postgres.
|
|
86
|
+
*
|
|
87
|
+
* Capped by the same rule the digest hashes under, so the two always describe
|
|
88
|
+
* the same words. `DO_NOT_TRACK` drops it upstream in `beginCommand`, like
|
|
89
|
+
* every other field here.
|
|
90
|
+
*/
|
|
91
|
+
export function creatorAskText(override) {
|
|
71
92
|
const field = creatorPromptField(override);
|
|
72
93
|
if (!('creatorPrompt' in field))
|
|
73
94
|
return undefined;
|
|
74
|
-
return
|
|
95
|
+
return field.creatorPrompt.slice(0, MAX_ASK_CHARS);
|
|
75
96
|
}
|
|
76
97
|
//# sourceMappingURL=creator-prompt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"creator-prompt.js","sourceRoot":"","sources":["../../src/telemetry/creator-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,sGAAsG;AACtG,MAAM,aAAa,GAAG,IAAI,CAAC;AAE3B,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,oFAAoF;UAC7F,iEAAiE;CAC7D,CAAC;AAEX;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAkB;IACnD,MAAM,KAAK,GAAG,QAAQ,IAAI,cAAc,EAAE,EAAE,aAAa,CAAC;IAC1D,oFAAoF;IACpF,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACrG,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,UAAU,CAAC,IAA6B;IACtD,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;IACnC,gGAAgG;IAChG,8FAA8F;IAC9F,OAAO,eAAe,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACjE,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"creator-prompt.js","sourceRoot":"","sources":["../../src/telemetry/creator-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,sGAAsG;AACtG,MAAM,aAAa,GAAG,IAAI,CAAC;AAE3B,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,oFAAoF;UAC7F,iEAAiE;CAC7D,CAAC;AAEX;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAkB;IACnD,MAAM,KAAK,GAAG,QAAQ,IAAI,cAAc,EAAE,EAAE,aAAa,CAAC;IAC1D,oFAAoF;IACpF,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACrG,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,UAAU,CAAC,IAA6B;IACtD,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;IACnC,gGAAgG;IAChG,8FAA8F;IAC9F,OAAO,eAAe,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACjE,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAkB;IACjD,MAAM,IAAI,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACzC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACtE,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAAC,QAAkB;IAC/C,MAAM,KAAK,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAC3C,IAAI,CAAC,CAAC,eAAe,IAAI,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAClD,OAAO,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;AACrD,CAAC"}
|
package/dist/telemetry/report.js
CHANGED
|
@@ -16,11 +16,19 @@
|
|
|
16
16
|
* bounded to {@link REPORT_TIMEOUT_MS} per request so a finished command is
|
|
17
17
|
* never held open by a sulking network (the same reasoning as
|
|
18
18
|
* update/check.ts). It never prints.
|
|
19
|
-
* 2.
|
|
20
|
-
* exit code, a `CliError.code`, and a duration. A message can name a
|
|
21
|
-
* that does not belong in an analytics event. The
|
|
22
|
-
*
|
|
23
|
-
*
|
|
19
|
+
* 2. Its ANALYTICS are categories, never messages: the command name, ok/failed,
|
|
20
|
+
* the exit code, a `CliError.code`, and a duration. A message can name a
|
|
21
|
+
* path; that does not belong in an analytics event. The game id keeps the
|
|
22
|
+
* rule (it is an id we minted) and so does the ask DIGEST (opaque by
|
|
23
|
+
* construction), and neither reaches GA4.
|
|
24
|
+
*
|
|
25
|
+
* `creatorPrompt` is the one field that carries words, and it is not
|
|
26
|
+
* analytics: api-server posts it to an internal Slack channel and stores it
|
|
27
|
+
* nowhere — not GA4, not Postgres, not BigQuery. It is here because the
|
|
28
|
+
* commands that send prompt text to a route are the generators, and an
|
|
29
|
+
* agent building a GDK project spends most of its commands on the offline
|
|
30
|
+
* ones. `DO_NOT_TRACK` drops it with everything else. See
|
|
31
|
+
* {@link CommandProvenance}.
|
|
24
32
|
* 3. It is authenticated with the creator's own token, so the server can key
|
|
25
33
|
* the event to the account and look up their real Pro state. No token, no
|
|
26
34
|
* report — an anonymous beacon would be a spammable endpoint for nothing.
|
|
@@ -32,7 +40,7 @@ import { resolveAuth0ClientId } from '../config/environments.js';
|
|
|
32
40
|
import { getAccessToken } from '../auth/session.js';
|
|
33
41
|
import { readProjectGameIdOrNull } from '../project/context.js';
|
|
34
42
|
import { apiServerHeaders } from './request-headers.js';
|
|
35
|
-
import { creatorAskDigest } from './creator-prompt.js';
|
|
43
|
+
import { creatorAskDigest, creatorAskText } from './creator-prompt.js';
|
|
36
44
|
import { currentCommand, isTelemetryDisabled } from './command-context.js';
|
|
37
45
|
// Re-exported because this is where the opt-out is enforced for a report that is already
|
|
38
46
|
// under way; `beginCommand` consults the same predicate to skip collecting anything at all.
|
|
@@ -85,21 +93,28 @@ function defaultDeps() {
|
|
|
85
93
|
return { fetch: globalThis.fetch, env: process.env };
|
|
86
94
|
}
|
|
87
95
|
/**
|
|
88
|
-
* The game and the ask, when this command has either.
|
|
89
|
-
*
|
|
90
|
-
*
|
|
96
|
+
* The game and the ask, when this command has either. Keys are omitted rather than sent as null:
|
|
97
|
+
* api-server validates the body strictly, and an absent key is how "nothing to say" is spelled
|
|
98
|
+
* everywhere else on this wire.
|
|
99
|
+
*
|
|
100
|
+
* Nothing is present unless the command declared `--original-prompt` AND the agent passed it —
|
|
101
|
+
* `creatorAskDigest` reads the value `beginCommand` captured, which is also where `DO_NOT_TRACK`
|
|
102
|
+
* already dropped it.
|
|
91
103
|
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
104
|
+
* `gameId` and `askDigest` are only sent TOGETHER: a digest with no game cannot be counted, and a
|
|
105
|
+
* game with no digest is not an ask. `creatorPrompt` is independent of that pair, because the
|
|
106
|
+
* channel it feeds wants the ask from a command run before a game exists just as much — the pair
|
|
107
|
+
* is about counting, and counting needs a game to count against.
|
|
96
108
|
*/
|
|
97
109
|
function provenance(deps) {
|
|
98
|
-
const
|
|
99
|
-
if (
|
|
110
|
+
const creatorPrompt = creatorAskText();
|
|
111
|
+
if (creatorPrompt === undefined)
|
|
100
112
|
return {};
|
|
101
113
|
const gameId = readProjectGameIdOrNull(deps.cwd);
|
|
102
|
-
|
|
114
|
+
const askDigest = creatorAskDigest();
|
|
115
|
+
if (gameId === undefined || askDigest === undefined)
|
|
116
|
+
return { creatorPrompt };
|
|
117
|
+
return { creatorPrompt, gameId, askDigest };
|
|
103
118
|
}
|
|
104
119
|
/**
|
|
105
120
|
* Report the running command's `report` to api-server. Resolves when the report
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/telemetry/report.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/telemetry/report.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.65
|
|
3
|
+
"version": "0.1.65",
|
|
4
4
|
"description": "Build Bitmagic games from your own agent tool",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"author": "Bitmagic Oy",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"playwright-core": "^1.59.1",
|
|
26
26
|
"tar": "^7.4.3",
|
|
27
27
|
"ws": "^8.21.3",
|
|
28
|
-
"@bitmagic/animation-forger": "0.1.20
|
|
29
|
-
"@bitmagic/asset-core": "0.2.20
|
|
30
|
-
"@bitmagic/world-forger": "0.1.25
|
|
28
|
+
"@bitmagic/animation-forger": "0.1.20",
|
|
29
|
+
"@bitmagic/asset-core": "0.2.20",
|
|
30
|
+
"@bitmagic/world-forger": "0.1.25"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@eslint/js": "^9.38.0",
|