@bitmagic/cli 0.1.32 → 0.1.33
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 +1 -1
- package/dist/cli.d.ts +2 -2
- package/dist/commands/init.d.ts +2 -2
- package/dist/commands/init.js +57 -4
- package/dist/commands/init.js.map +1 -1
- package/dist/scaffold/project.d.ts +33 -0
- package/dist/scaffold/project.js +41 -6
- package/dist/scaffold/project.js.map +1 -1
- package/dist/scaffold/suggest-template.d.ts +31 -0
- package/dist/scaffold/suggest-template.js +41 -0
- package/dist/scaffold/suggest-template.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ browser reloads itself on every change and the assets panel shows each generatio
|
|
|
37
37
|
| `bitmagic login [--env <env>]` | Device-code auth against Auth0; stores credentials per environment. |
|
|
38
38
|
| `bitmagic logout [--env <env>]` | Remove stored credentials for an environment. |
|
|
39
39
|
| `bitmagic whoami [--env <env>]` | Show the identity the CLI is authenticated as. |
|
|
40
|
-
| `bitmagic init [dir] [--template <id>] [--name <name>] [--idea "<pitch>"] [--env <env>] [--force]` | Scaffold a new project: mints a game, downloads the vendored engine, writes `AGENTS.md`, `GAME-DESIGN.md` and templates. `--idea` seeds the design doc's pitch. |
|
|
40
|
+
| `bitmagic init [dir] [--template <id>] [--name <name>] [--idea "<pitch>"] [--env <env>] [--force]` | Scaffold a new project: mints a game, downloads the vendored engine, writes `AGENTS.md`, `GAME-DESIGN.md` and templates. Starts from `empty-3d` unless told otherwise. `--idea` seeds the design doc's pitch **and** picks the template whose camera and controls fit it — "a doom-like corridor shooter" scaffolds `first-person`, "jump between floating islands" scaffolds `sidescroller`. `--template` overrides both; a suggestion that fails for any reason falls back to `empty-3d` rather than failing the scaffold. |
|
|
41
41
|
| `bitmagic check` | Typecheck (`tsc --noEmit`) against the vendored engine. Fast; does not prove the game runs. |
|
|
42
42
|
| `bitmagic dev [--port <port>] [--editor-port <port>] [--no-open]` | Build, then serve everything and keep it running: `tsc --watch`, `vite` on 3010, and a **Game / Editor** view on 3011 that reloads itself when the project changes. Opens the view in your browser; `--no-open` (or `BITMAGIC_NO_OPEN=1`) skips that. The one command to leave open. See **The dev view** below. |
|
|
43
43
|
| `bitmagic reload [--port <port>]` | Tell a running `bitmagic dev` to reload the browser now. For agents: run it when you finish a round of edits. Exits 0 and does nothing when no dev server is running. |
|
package/dist/cli.d.ts
CHANGED
|
@@ -46,7 +46,7 @@ declare const rawCommands: {
|
|
|
46
46
|
};
|
|
47
47
|
readonly template: {
|
|
48
48
|
readonly type: "string";
|
|
49
|
-
readonly description: "Template id (see templates in the engine bundle).";
|
|
49
|
+
readonly description: "Template id (see templates in the engine bundle). Defaults to empty-3d, or to whatever --idea suggests.";
|
|
50
50
|
};
|
|
51
51
|
readonly name: {
|
|
52
52
|
readonly type: "string";
|
|
@@ -54,7 +54,7 @@ declare const rawCommands: {
|
|
|
54
54
|
};
|
|
55
55
|
readonly idea: {
|
|
56
56
|
readonly type: "string";
|
|
57
|
-
readonly description: "One-line pitch
|
|
57
|
+
readonly description: "One-line pitch. Seeds GAME-DESIGN.md and picks the template whose camera and controls fit it. Optional — you can write it yourself.";
|
|
58
58
|
};
|
|
59
59
|
readonly env: {
|
|
60
60
|
readonly type: "string";
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export declare const initCommand: import("citty").CommandDef<{
|
|
|
6
6
|
};
|
|
7
7
|
readonly template: {
|
|
8
8
|
readonly type: "string";
|
|
9
|
-
readonly description: "Template id (see templates in the engine bundle).";
|
|
9
|
+
readonly description: "Template id (see templates in the engine bundle). Defaults to empty-3d, or to whatever --idea suggests.";
|
|
10
10
|
};
|
|
11
11
|
readonly name: {
|
|
12
12
|
readonly type: "string";
|
|
@@ -14,7 +14,7 @@ export declare const initCommand: import("citty").CommandDef<{
|
|
|
14
14
|
};
|
|
15
15
|
readonly idea: {
|
|
16
16
|
readonly type: "string";
|
|
17
|
-
readonly description: "One-line pitch
|
|
17
|
+
readonly description: "One-line pitch. Seeds GAME-DESIGN.md and picks the template whose camera and controls fit it. Optional — you can write it yourself.";
|
|
18
18
|
};
|
|
19
19
|
readonly env: {
|
|
20
20
|
readonly type: "string";
|
package/dist/commands/init.js
CHANGED
|
@@ -10,7 +10,8 @@ import { readDefaultEnvironment } from '../config/credentials.js';
|
|
|
10
10
|
import { getAccessToken } from '../auth/session.js';
|
|
11
11
|
import { apiPost } from '../http/client.js';
|
|
12
12
|
import { fetchEngineManifest, downloadAndVerify, extractEngine } from '../scaffold/engine-download.js';
|
|
13
|
-
import { resolveTemplate, scaffoldProject } from '../scaffold/project.js';
|
|
13
|
+
import { DEFAULT_TEMPLATE_ID, SUGGESTION_EXCLUDED_TEMPLATE_IDS, readTemplateIndex, resolveTemplate, scaffoldProject, } from '../scaffold/project.js';
|
|
14
|
+
import { suggestTemplate } from '../scaffold/suggest-template.js';
|
|
14
15
|
const deps = {
|
|
15
16
|
fetch: globalThis.fetch,
|
|
16
17
|
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
@@ -85,15 +86,64 @@ function printNextSteps(output, dir, gameId, installSucceeded, hasIdea) {
|
|
|
85
86
|
output.info(' bitmagic cover');
|
|
86
87
|
output.info(' bitmagic check');
|
|
87
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Decide which template to scaffold from.
|
|
91
|
+
*
|
|
92
|
+
* `--template` wins outright and skips the model call entirely: someone who named a template has
|
|
93
|
+
* already made the decision this function otherwise makes for them.
|
|
94
|
+
*
|
|
95
|
+
* With `--idea` and no `--template`, the pitch names a camera and control scheme far more often
|
|
96
|
+
* than not ("a doom-like corridor shooter" is first-person; "jump between floating islands" is a
|
|
97
|
+
* sidescroller), so it is worth one small model call to start from the right controls rather than
|
|
98
|
+
* making the creator's agent rewrite them. A suggestion that fails for ANY reason falls through to
|
|
99
|
+
* the default — the creator gets a working scaffold and a one-line note, never a failed `init`.
|
|
100
|
+
*/
|
|
101
|
+
async function chooseTemplate(templatesDir, args, environment, token, output) {
|
|
102
|
+
if (args.template !== undefined) {
|
|
103
|
+
return { template: resolveTemplate(templatesDir, args.template), source: 'explicit' };
|
|
104
|
+
}
|
|
105
|
+
const fallback = resolveTemplate(templatesDir);
|
|
106
|
+
if (args.idea === undefined) {
|
|
107
|
+
return { template: fallback, source: 'default' };
|
|
108
|
+
}
|
|
109
|
+
const candidates = readTemplateIndex(templatesDir).filter((t) => !SUGGESTION_EXCLUDED_TEMPLATE_IDS.includes(t.id));
|
|
110
|
+
// Nothing left to choose between — don't spend a round trip to be told so.
|
|
111
|
+
if (candidates.length === 0) {
|
|
112
|
+
return { template: fallback, source: 'default' };
|
|
113
|
+
}
|
|
114
|
+
output.info('Matching your idea to a template…');
|
|
115
|
+
const suggestion = await suggestTemplate({
|
|
116
|
+
environment,
|
|
117
|
+
token,
|
|
118
|
+
idea: args.idea,
|
|
119
|
+
templates: candidates,
|
|
120
|
+
defaultTemplateId: DEFAULT_TEMPLATE_ID,
|
|
121
|
+
deps: { fetch: globalThis.fetch },
|
|
122
|
+
});
|
|
123
|
+
if (!suggestion) {
|
|
124
|
+
output.info(`Could not match your idea to a template — starting from "${fallback.id}".`);
|
|
125
|
+
return { template: fallback, source: 'default' };
|
|
126
|
+
}
|
|
127
|
+
// Safe by construction: suggestTemplate only returns an id it found in the list it was given,
|
|
128
|
+
// which is the same index resolveTemplate reads.
|
|
129
|
+
const template = resolveTemplate(templatesDir, suggestion.templateId);
|
|
130
|
+
output.info(suggestion.reason
|
|
131
|
+
? `Using template "${template.id}" — ${suggestion.reason}.`
|
|
132
|
+
: `Using template "${template.id}".`);
|
|
133
|
+
return { template, source: 'idea' };
|
|
134
|
+
}
|
|
88
135
|
export const initCommand = defineCommand({
|
|
89
136
|
meta: { name: 'init', description: 'Scaffold a new Bitmagic game project.' },
|
|
90
137
|
args: {
|
|
91
138
|
dir: { type: 'positional', required: false, description: 'Directory to create the project in.' },
|
|
92
|
-
template: {
|
|
139
|
+
template: {
|
|
140
|
+
type: 'string',
|
|
141
|
+
description: `Template id (see templates in the engine bundle). Defaults to ${DEFAULT_TEMPLATE_ID}, or to whatever --idea suggests.`,
|
|
142
|
+
},
|
|
93
143
|
name: { type: 'string', description: 'Game name.' },
|
|
94
144
|
idea: {
|
|
95
145
|
type: 'string',
|
|
96
|
-
description: 'One-line pitch
|
|
146
|
+
description: 'One-line pitch. Seeds GAME-DESIGN.md and picks the template whose camera and controls fit it. Optional — you can write it yourself.',
|
|
97
147
|
},
|
|
98
148
|
env: { type: 'string', description: 'Environment (dev, prod, local).' },
|
|
99
149
|
force: { type: 'boolean', description: 'Scaffold into a non-empty directory.' },
|
|
@@ -124,7 +174,7 @@ export const initCommand = defineCommand({
|
|
|
124
174
|
const extracted = path.join(workDir, 'extracted');
|
|
125
175
|
const templatesDir = path.join(workDir, 'templates');
|
|
126
176
|
await extractEngine(tarballPath, extracted, templatesDir);
|
|
127
|
-
const template =
|
|
177
|
+
const { template, source: templateSource } = await chooseTemplate(templatesDir, args, environment, token, output);
|
|
128
178
|
// Minted only after the engine is in hand: a failed download must not leave an orphaned,
|
|
129
179
|
// unreachable game row behind.
|
|
130
180
|
const projectName = args.name ?? path.basename(targetDir);
|
|
@@ -150,6 +200,9 @@ export const initCommand = defineCommand({
|
|
|
150
200
|
gameId: created.gameId,
|
|
151
201
|
root: targetDir,
|
|
152
202
|
template: template.id,
|
|
203
|
+
// 'explicit' (--template), 'idea' (matched from --idea) or 'default'. An agent driving
|
|
204
|
+
// --json needs to know whether the template was chosen or merely fallen back to.
|
|
205
|
+
templateSource,
|
|
153
206
|
genre: template.genre,
|
|
154
207
|
engineVersion: manifest.version,
|
|
155
208
|
// An agent needs to know whether to run the install itself before anything else works.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,YAAY,EAAe,MAAM,cAAc,CAAC;AACzD,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,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACvG,OAAO,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,8 +2,34 @@ import { type ProjectMetadata } from './project-files.js';
|
|
|
2
2
|
export interface TemplateEntry {
|
|
3
3
|
id: string;
|
|
4
4
|
genre: string;
|
|
5
|
+
/** Both optional: only the suggester reads them, and an older bundle's index may omit either. */
|
|
6
|
+
name?: string;
|
|
7
|
+
description?: string;
|
|
5
8
|
recommended?: boolean;
|
|
6
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* The CLI's default, deliberately NOT the index's `recommended` entry.
|
|
12
|
+
*
|
|
13
|
+
* `recommended` is standard-3d, a scene pre-populated with demo objects — the right first impression
|
|
14
|
+
* in the web Creator, where someone wants something to look at immediately. In the CLI lane a coding
|
|
15
|
+
* agent builds the scene from GAME-DESIGN.md, so those objects are furniture it has to delete first.
|
|
16
|
+
* Same third-person controller, empty world.
|
|
17
|
+
*
|
|
18
|
+
* `recommended` stays where it is: flipping it in templates/index.json would also move the Creator UI
|
|
19
|
+
* and the lab's `loadRecommendedTemplateId`.
|
|
20
|
+
*/
|
|
21
|
+
export declare const DEFAULT_TEMPLATE_ID = "empty-3d";
|
|
22
|
+
/**
|
|
23
|
+
* Templates `--idea` may not be matched to, though `--template` still scaffolds them.
|
|
24
|
+
*
|
|
25
|
+
* standard-3d IS the default template plus demo objects — same genre, same third-person controller.
|
|
26
|
+
* Offering both to the suggester asks it to choose on a difference that does not matter here (the
|
|
27
|
+
* creator's agent builds the scene either way) and, observed live, it picks standard-3d for ordinary
|
|
28
|
+
* third-person ideas on the strength of its name and "the default Bitmagic scene template"
|
|
29
|
+
* description. Withholding it makes the choice purely about camera and controls, which is the only
|
|
30
|
+
* thing the templates really differ on.
|
|
31
|
+
*/
|
|
32
|
+
export declare const SUGGESTION_EXCLUDED_TEMPLATE_IDS: string[];
|
|
7
33
|
/**
|
|
8
34
|
* Directories moved out of the extracted tree into the project's vendored engine/.
|
|
9
35
|
*
|
|
@@ -61,6 +87,13 @@ export declare const OPTIONAL_VENDORED_DIRS: string[];
|
|
|
61
87
|
* `upgrade` didn't exist yet.
|
|
62
88
|
*/
|
|
63
89
|
export declare const PLATFORM_GENERATED_FILES: Array<[string, () => string]>;
|
|
90
|
+
/**
|
|
91
|
+
* Every template the downloaded bundle carries, in index order.
|
|
92
|
+
*
|
|
93
|
+
* Separate from `resolveTemplate` so `init` can hand the list to the template suggester without
|
|
94
|
+
* parsing the file a second time — and so the two "this bundle is unusable" errors stay in one place.
|
|
95
|
+
*/
|
|
96
|
+
export declare function readTemplateIndex(templatesDir: string): TemplateEntry[];
|
|
64
97
|
export declare function resolveTemplate(templatesDir: string, requestedId?: string): TemplateEntry;
|
|
65
98
|
export interface ScaffoldOptions {
|
|
66
99
|
targetDir: string;
|
package/dist/scaffold/project.js
CHANGED
|
@@ -5,6 +5,29 @@ import { aliasSourceDir } from './aliases.js';
|
|
|
5
5
|
import { renderPackageJson, renderTsconfig, renderIndexHtml, renderViteConfig, renderVitePublishConfig, renderGitignore, renderBitmagicJson, renderAgentsMd, renderGameDesignMd, renderClaudeMd, renderSkillsReadme, renderGenerateSkill, renderPlanningSkill, renderEngineApiSkill, } from './project-files.js';
|
|
6
6
|
import { hashAgentsMd } from './agents-md.js';
|
|
7
7
|
import { CLAUDE_SETTINGS_FILE, renderClaudeSettings } from './claude-settings.js';
|
|
8
|
+
/**
|
|
9
|
+
* The CLI's default, deliberately NOT the index's `recommended` entry.
|
|
10
|
+
*
|
|
11
|
+
* `recommended` is standard-3d, a scene pre-populated with demo objects — the right first impression
|
|
12
|
+
* in the web Creator, where someone wants something to look at immediately. In the CLI lane a coding
|
|
13
|
+
* agent builds the scene from GAME-DESIGN.md, so those objects are furniture it has to delete first.
|
|
14
|
+
* Same third-person controller, empty world.
|
|
15
|
+
*
|
|
16
|
+
* `recommended` stays where it is: flipping it in templates/index.json would also move the Creator UI
|
|
17
|
+
* and the lab's `loadRecommendedTemplateId`.
|
|
18
|
+
*/
|
|
19
|
+
export const DEFAULT_TEMPLATE_ID = 'empty-3d';
|
|
20
|
+
/**
|
|
21
|
+
* Templates `--idea` may not be matched to, though `--template` still scaffolds them.
|
|
22
|
+
*
|
|
23
|
+
* standard-3d IS the default template plus demo objects — same genre, same third-person controller.
|
|
24
|
+
* Offering both to the suggester asks it to choose on a difference that does not matter here (the
|
|
25
|
+
* creator's agent builds the scene either way) and, observed live, it picks standard-3d for ordinary
|
|
26
|
+
* third-person ideas on the strength of its name and "the default Bitmagic scene template"
|
|
27
|
+
* description. Withholding it makes the choice purely about camera and controls, which is the only
|
|
28
|
+
* thing the templates really differ on.
|
|
29
|
+
*/
|
|
30
|
+
export const SUGGESTION_EXCLUDED_TEMPLATE_IDS = ['standard-3d'];
|
|
8
31
|
/**
|
|
9
32
|
* Directories moved out of the extracted tree into the project's vendored engine/.
|
|
10
33
|
*
|
|
@@ -80,7 +103,13 @@ export const PLATFORM_GENERATED_FILES = [
|
|
|
80
103
|
['.claude/skills/planning-a-game/SKILL.md', renderPlanningSkill],
|
|
81
104
|
['.claude/skills/finding-engine-apis/SKILL.md', renderEngineApiSkill],
|
|
82
105
|
];
|
|
83
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Every template the downloaded bundle carries, in index order.
|
|
108
|
+
*
|
|
109
|
+
* Separate from `resolveTemplate` so `init` can hand the list to the template suggester without
|
|
110
|
+
* parsing the file a second time — and so the two "this bundle is unusable" errors stay in one place.
|
|
111
|
+
*/
|
|
112
|
+
export function readTemplateIndex(templatesDir) {
|
|
84
113
|
const indexPath = path.join(templatesDir, 'index.json');
|
|
85
114
|
let raw;
|
|
86
115
|
try {
|
|
@@ -91,14 +120,20 @@ export function resolveTemplate(templatesDir, requestedId) {
|
|
|
91
120
|
}
|
|
92
121
|
const parsed = JSON.parse(raw);
|
|
93
122
|
const templates = parsed?.templates ?? [];
|
|
94
|
-
|
|
95
|
-
// doubles as the fallback for the no-id case below.
|
|
96
|
-
const [first] = templates;
|
|
97
|
-
if (!first) {
|
|
123
|
+
if (templates.length === 0) {
|
|
98
124
|
throw new CliError('The engine bundle lists no templates.');
|
|
99
125
|
}
|
|
126
|
+
return templates;
|
|
127
|
+
}
|
|
128
|
+
export function resolveTemplate(templatesDir, requestedId) {
|
|
129
|
+
const templates = readTemplateIndex(templatesDir);
|
|
100
130
|
if (requestedId === undefined) {
|
|
101
|
-
|
|
131
|
+
// Two fallbacks deep on purpose: an engine bundle predating empty-3d still resolves through
|
|
132
|
+
// `recommended`, and an index where nothing is marked recommended still resolves through the
|
|
133
|
+
// first entry. Neither is a reason to refuse to scaffold.
|
|
134
|
+
return (templates.find((t) => t.id === DEFAULT_TEMPLATE_ID) ??
|
|
135
|
+
templates.find((t) => t.recommended) ??
|
|
136
|
+
templates[0]);
|
|
102
137
|
}
|
|
103
138
|
const match = templates.find((t) => t.id === requestedId);
|
|
104
139
|
if (!match) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/scaffold/project.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,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,uBAAuB,EACvB,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,GAErB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/scaffold/project.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Environment } from '../config/environments.js';
|
|
2
|
+
import { type ApiDeps } from '../http/client.js';
|
|
3
|
+
import type { TemplateEntry } from './project.js';
|
|
4
|
+
export interface SuggestTemplateOptions {
|
|
5
|
+
environment: Environment;
|
|
6
|
+
token: string;
|
|
7
|
+
/** The creator's `--idea` pitch. */
|
|
8
|
+
idea: string;
|
|
9
|
+
/** Every template this engine bundle carries — the model may only choose from these. */
|
|
10
|
+
templates: TemplateEntry[];
|
|
11
|
+
defaultTemplateId: string;
|
|
12
|
+
deps: ApiDeps;
|
|
13
|
+
}
|
|
14
|
+
export interface TemplateSuggestion {
|
|
15
|
+
templateId: string;
|
|
16
|
+
/** One short clause for the creator; may be empty if the model omitted it. */
|
|
17
|
+
reason: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Ask api-server which template fits the creator's idea, or null if it cannot say.
|
|
21
|
+
*
|
|
22
|
+
* **This function never throws.** Template selection is a convenience on top of a default that is
|
|
23
|
+
* already a working answer, so nothing here — being offline, an expired feature flag, a model that
|
|
24
|
+
* invents an id — is allowed to fail `bitmagic init`. Every failure path returns null and the
|
|
25
|
+
* caller scaffolds the default template.
|
|
26
|
+
*
|
|
27
|
+
* The template list travels in the request because api-server has no copy of the bundle the CLI
|
|
28
|
+
* just downloaded, and because validating the reply against the ids we SENT is what makes a
|
|
29
|
+
* hallucinated id harmless rather than a scaffold from a directory that does not exist.
|
|
30
|
+
*/
|
|
31
|
+
export declare function suggestTemplate(options: SuggestTemplateOptions): Promise<TemplateSuggestion | null>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { apiPost } from '../http/client.js';
|
|
2
|
+
/**
|
|
3
|
+
* Ask api-server which template fits the creator's idea, or null if it cannot say.
|
|
4
|
+
*
|
|
5
|
+
* **This function never throws.** Template selection is a convenience on top of a default that is
|
|
6
|
+
* already a working answer, so nothing here — being offline, an expired feature flag, a model that
|
|
7
|
+
* invents an id — is allowed to fail `bitmagic init`. Every failure path returns null and the
|
|
8
|
+
* caller scaffolds the default template.
|
|
9
|
+
*
|
|
10
|
+
* The template list travels in the request because api-server has no copy of the bundle the CLI
|
|
11
|
+
* just downloaded, and because validating the reply against the ids we SENT is what makes a
|
|
12
|
+
* hallucinated id harmless rather than a scaffold from a directory that does not exist.
|
|
13
|
+
*/
|
|
14
|
+
export async function suggestTemplate(options) {
|
|
15
|
+
const { environment, token, idea, templates, defaultTemplateId, deps } = options;
|
|
16
|
+
let response;
|
|
17
|
+
try {
|
|
18
|
+
response = await apiPost(environment, '/api/cli/v1/templates/suggest', token, {
|
|
19
|
+
idea,
|
|
20
|
+
defaultTemplateId,
|
|
21
|
+
templates: templates.map((t) => ({
|
|
22
|
+
id: t.id,
|
|
23
|
+
name: t.name ?? t.id,
|
|
24
|
+
description: t.description ?? '',
|
|
25
|
+
genre: t.genre,
|
|
26
|
+
})),
|
|
27
|
+
}, deps);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const { templateId } = response;
|
|
33
|
+
if (typeof templateId !== 'string' || !templates.some((t) => t.id === templateId)) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
templateId,
|
|
38
|
+
reason: typeof response.reason === 'string' ? response.reason.trim() : '',
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=suggest-template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggest-template.js","sourceRoot":"","sources":["../../src/scaffold/suggest-template.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAgB,MAAM,mBAAmB,CAAC;AAyB1D;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAA+B;IAE/B,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,iBAAiB,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAEjF,IAAI,QAAyB,CAAC;IAC9B,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,OAAO,CACtB,WAAW,EACX,+BAA+B,EAC/B,KAAK,EACL;YACE,IAAI;YACJ,iBAAiB;YACjB,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC/B,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE;gBACpB,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE;gBAChC,KAAK,EAAE,CAAC,CAAC,KAAK;aACf,CAAC,CAAC;SACJ,EACD,IAAI,CACL,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC;IAChC,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC,EAAE,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,UAAU;QACV,MAAM,EAAE,OAAO,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;KAC1E,CAAC;AACJ,CAAC"}
|