jgengine 0.8.1 → 0.8.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/dist/cli/index.js +19 -18
- package/dist/create.js +11 -3
- package/dist/skills.d.ts +2 -0
- package/dist/skills.js +21 -19
- package/dist/templates.js +22 -11
- package/llms.txt +10 -8
- package/package.json +12 -2
package/dist/cli/index.js
CHANGED
|
@@ -9,28 +9,29 @@ import { runDoctor } from "../doctor.js";
|
|
|
9
9
|
import { cliVersion, findUp, readPackageJson } from "../pkg.js";
|
|
10
10
|
import { runSkills } from "../skills.js";
|
|
11
11
|
const ENGINE_PACKAGES = ["core", "react", "shell", "ws", "sql", "convex", "node", "assets"];
|
|
12
|
-
const HELP = `jgengine ${cliVersion()} — the JGengine
|
|
13
|
-
|
|
12
|
+
const HELP = `jgengine ${cliVersion()} — agent-side CLI for the JGengine TypeScript game SDK
|
|
13
|
+
Packages: ${ENGINE_PACKAGES.map((name) => `@jgengine/${name}`).join(", ")}.
|
|
14
|
+
docs: https://jgengine.com · source: https://github.com/Noisemaker111/jgengine
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
HUMAN INTERFACE (what people say to you — not a shell they must run):
|
|
17
|
+
Make a game that ... with jgengine
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
doctor [dir] diagnose a game project: version skew, missing peers, unstyled-UI @source gaps, shape drift
|
|
22
|
-
llms [package] print packaged API docs (llms.txt) for an installed @jgengine/* package — agent-ready context
|
|
23
|
-
assets [...] delegate to the @jgengine/assets CLI: list, search, pull CC0 3D model packs
|
|
24
|
-
versions show CLI + installed @jgengine/* versions
|
|
25
|
-
help this map
|
|
19
|
+
AGENT RESPONSE (you run these; do not dump this as homework for the user):
|
|
20
|
+
npx jgengine create "Game Name" # scaffold + install skills into the project
|
|
21
|
+
cd Game-Name
|
|
22
|
+
# concept pitch → questions → build (see jgengine-newgame)
|
|
26
23
|
|
|
27
|
-
|
|
24
|
+
usage: jgengine <command> [...args]
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
create "<Game Name>" scaffold playable base + install agent skills into the project
|
|
27
|
+
folder My-Game-Name; name → game.config / HUD / title
|
|
28
|
+
[--in-repo|--standalone] [--no-install] [--no-skills] [--pm bun|npm|pnpm]
|
|
29
|
+
skills -p | -g re-install skills (recovery only — create already installs them)
|
|
30
|
+
doctor [dir] diagnose version skew, missing peers, unstyled HUD, shape drift
|
|
31
|
+
llms [package] print packaged API docs (llms.txt) — agent-ready
|
|
32
|
+
assets [...] @jgengine/assets CLI: list, search, pull CC0 packs
|
|
33
|
+
versions CLI + installed @jgengine/* versions
|
|
34
|
+
help this map
|
|
34
35
|
`;
|
|
35
36
|
function runVersions() {
|
|
36
37
|
console.log(`jgengine ${cliVersion()}`);
|
package/dist/create.js
CHANGED
|
@@ -2,6 +2,7 @@ import { spawnSync } from "node:child_process";
|
|
|
2
2
|
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
4
4
|
import { cliVersion, findWorkspaceRoot, flag, hasFlag, isEngineMonorepo } from "./pkg.js";
|
|
5
|
+
import { installSkills } from "./skills.js";
|
|
5
6
|
import { gameTemplate, parseCreateName } from "./templates.js";
|
|
6
7
|
export function writeGame(targetDir, id, name, variant) {
|
|
7
8
|
for (const file of gameTemplate({ id, name, variant, engineVersion: cliVersion() })) {
|
|
@@ -64,7 +65,7 @@ function isInsideDir(child, parent) {
|
|
|
64
65
|
export function runCreate(argv) {
|
|
65
66
|
const nameArg = positionalArg(argv);
|
|
66
67
|
if (nameArg === undefined) {
|
|
67
|
-
console.error('usage: jgengine create "<Game Name>" [--in-repo|--standalone] [--no-install] [--pm bun|npm|pnpm]');
|
|
68
|
+
console.error('usage: jgengine create "<Game Name>" [--in-repo|--standalone] [--no-install] [--no-skills] [--pm bun|npm|pnpm]');
|
|
68
69
|
return 1;
|
|
69
70
|
}
|
|
70
71
|
let displayName;
|
|
@@ -111,6 +112,7 @@ export function runCreate(argv) {
|
|
|
111
112
|
console.log("\nnext steps:");
|
|
112
113
|
console.log(` bun install # from ${workspaceRoot}`);
|
|
113
114
|
console.log(` bun run games:${id} # play it standalone`);
|
|
115
|
+
console.log(` # agent: open the project and build ${displayName} (skills live in the monorepo)`);
|
|
114
116
|
return 0;
|
|
115
117
|
}
|
|
116
118
|
let installed = false;
|
|
@@ -126,13 +128,19 @@ export function runCreate(argv) {
|
|
|
126
128
|
if (!installed)
|
|
127
129
|
console.error(`warning: ${pm} install failed — run it manually in ${targetDir}`);
|
|
128
130
|
}
|
|
131
|
+
if (!hasFlag(argv, "no-skills")) {
|
|
132
|
+
const skillsStatus = installSkills("project", targetDir);
|
|
133
|
+
if (skillsStatus !== 0) {
|
|
134
|
+
console.error("warning: skill install failed — agent can still use AGENTS.md; retry: npx jgengine skills -p");
|
|
135
|
+
}
|
|
136
|
+
}
|
|
129
137
|
const cdHint = relative(process.cwd(), targetDir) || ".";
|
|
130
138
|
console.log("\nnext steps:");
|
|
131
139
|
console.log(` cd ${cdHint}`);
|
|
132
140
|
if (!installed)
|
|
133
141
|
console.log(" bun install # or npm install");
|
|
134
|
-
console.log(" bun dev
|
|
135
|
-
console.log(
|
|
142
|
+
console.log(" bun dev # playable base (flat world, player, HUD)");
|
|
143
|
+
console.log(` # agent: make ${displayName} with jgengine (skills already in the project)`);
|
|
136
144
|
return 0;
|
|
137
145
|
}
|
|
138
146
|
catch (error) {
|
package/dist/skills.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const SKILLS_SOURCE = "Noisemaker111/jgengine";
|
|
2
|
+
export declare const GAME_SKILLS: readonly ["jgengine-api", "jgengine-newgame", "jgengine-verify"];
|
|
2
3
|
export type SkillsScope = "global" | "project";
|
|
3
4
|
export declare function parseSkillsArgs(argv: string[]): {
|
|
4
5
|
scope: SkillsScope;
|
|
@@ -6,4 +7,5 @@ export declare function parseSkillsArgs(argv: string[]): {
|
|
|
6
7
|
error: string;
|
|
7
8
|
};
|
|
8
9
|
export declare function skillsInstallArgs(scope: SkillsScope): string[];
|
|
10
|
+
export declare function installSkills(scope: SkillsScope, cwd?: string): number;
|
|
9
11
|
export declare function runSkills(argv: string[]): number;
|
package/dist/skills.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
2
|
export const SKILLS_SOURCE = "Noisemaker111/jgengine";
|
|
3
|
+
export const GAME_SKILLS = ["jgengine-api", "jgengine-newgame", "jgengine-verify"];
|
|
3
4
|
export function parseSkillsArgs(argv) {
|
|
4
5
|
let scope = null;
|
|
5
6
|
for (const arg of argv) {
|
|
@@ -24,42 +25,43 @@ export function parseSkillsArgs(argv) {
|
|
|
24
25
|
return { scope: scope ?? "project" };
|
|
25
26
|
}
|
|
26
27
|
export function skillsInstallArgs(scope) {
|
|
27
|
-
const args = ["--yes", "skills", "add", SKILLS_SOURCE, "-y"
|
|
28
|
+
const args = ["--yes", "skills", "add", SKILLS_SOURCE, "-y"];
|
|
29
|
+
for (const skill of GAME_SKILLS) {
|
|
30
|
+
args.push("-s", skill);
|
|
31
|
+
}
|
|
32
|
+
args.push("-a", "*");
|
|
28
33
|
if (scope === "global")
|
|
29
34
|
args.push("-g");
|
|
30
35
|
return args;
|
|
31
36
|
}
|
|
37
|
+
export function installSkills(scope, cwd) {
|
|
38
|
+
const where = scope === "global" ? "globally" : "in this project";
|
|
39
|
+
console.log(`installing agent skills ${where}: ${GAME_SKILLS.join(", ")}…`);
|
|
40
|
+
const result = spawnSync("npx", skillsInstallArgs(scope), {
|
|
41
|
+
stdio: "inherit",
|
|
42
|
+
shell: process.platform === "win32",
|
|
43
|
+
cwd,
|
|
44
|
+
});
|
|
45
|
+
return result.status ?? 1;
|
|
46
|
+
}
|
|
32
47
|
export function runSkills(argv) {
|
|
33
48
|
const parsed = parseSkillsArgs(argv);
|
|
34
49
|
if ("error" in parsed) {
|
|
35
50
|
if (parsed.error === "help") {
|
|
36
51
|
console.log(`usage: jgengine skills (-g|--global | -p|--project)
|
|
37
52
|
|
|
38
|
-
-p, --project install into this project (
|
|
53
|
+
-p, --project install into this project (default)
|
|
39
54
|
-g, --global install for your user (every project / agent session)
|
|
40
55
|
|
|
41
|
-
Installs
|
|
56
|
+
Installs ${GAME_SKILLS.join(", ")} from ${SKILLS_SOURCE}.
|
|
42
57
|
|
|
43
|
-
|
|
44
|
-
npx jgengine create "Solitaire"
|
|
45
|
-
cd Solitaire
|
|
46
|
-
npx jgengine skills -p
|
|
47
|
-
# tell your agent: make Solitaire with jgengine
|
|
48
|
-
|
|
49
|
-
# or once for all projects:
|
|
50
|
-
npx jgengine skills -g
|
|
58
|
+
People do not run this. Agents use it; create already installs project skills.
|
|
51
59
|
`);
|
|
52
60
|
return 0;
|
|
53
61
|
}
|
|
54
62
|
console.error(`error: ${parsed.error}`);
|
|
55
|
-
console.error(
|
|
63
|
+
console.error("usage: jgengine skills (-g|--global | -p|--project)");
|
|
56
64
|
return 1;
|
|
57
65
|
}
|
|
58
|
-
|
|
59
|
-
console.log(`installing JGengine agent skills ${where} (jgengine-api, jgengine-newgame, jgengine-verify)…`);
|
|
60
|
-
const result = spawnSync("npx", skillsInstallArgs(parsed.scope), {
|
|
61
|
-
stdio: "inherit",
|
|
62
|
-
shell: process.platform === "win32",
|
|
63
|
-
});
|
|
64
|
-
return result.status ?? 1;
|
|
66
|
+
return installSkills(parsed.scope);
|
|
65
67
|
}
|
package/dist/templates.js
CHANGED
|
@@ -344,21 +344,32 @@ describe("${id} world", () => {
|
|
|
344
344
|
});
|
|
345
345
|
});
|
|
346
346
|
`;
|
|
347
|
-
const agentsMd = (name, variant) => `# ${name} — agent
|
|
347
|
+
const agentsMd = (name, variant) => `# ${name} — agent briefing
|
|
348
348
|
|
|
349
|
-
|
|
349
|
+
You are in a **JGengine** game project. JGengine is a pure-TypeScript game engine SDK on npm (\`@jgengine/core\`, \`react\`, \`shell\`, …). Site: https://jgengine.com · source: https://github.com/Noisemaker111/jgengine
|
|
350
350
|
|
|
351
|
-
|
|
352
|
-
- Agent skills — API reference, phased game-build workflow, browserless verify gate: \`npx jgengine skills -p\` (this project) or \`-g\` (global).
|
|
353
|
-
- Setup broken or UI unstyled: \`npx jgengine doctor\`.
|
|
351
|
+
**How people use JGengine:** they say *Make a game that … with jgengine* to an agent. They do **not** start from a CLI tutorial. \`npx jgengine\` is for **you** (scaffold, skills, docs).
|
|
354
352
|
|
|
355
|
-
|
|
353
|
+
## What to do when the user wants this game built
|
|
356
354
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
-
|
|
360
|
-
|
|
361
|
-
|
|
355
|
+
1. Read skills if present: \`jgengine-newgame\` (workflow), \`jgengine-api\` (API), \`jgengine-verify\` (prove it works). They land under \`.agents/skills/\` or \`.claude/skills/\` when scaffolded via create.
|
|
356
|
+
2. If skills are missing (your problem, not the user's): \`npx jgengine skills -p\` or use this file + \`npx jgengine llms core\`.
|
|
357
|
+
3. **User-facing first reply is short** — game name, fantasy in 2–4 lines, POV (1st / 3rd / top-down / HUD-only), world kind, scale vibe. Ask a few tight questions (POV, world, multiplayer, how big). **Do not** dump file trees, catalog ids, keybind tables, or full phase plans to the user.
|
|
358
|
+
4. Keep the full engineering plan (files, systems, budgets) internal. After they answer, scaffold is already here — build in phases, full game not a slice.
|
|
359
|
+
|
|
360
|
+
## Engine loaders
|
|
361
|
+
|
|
362
|
+
- API docs in the tarball: \`npx jgengine llms core\` (any package: react, shell, …)
|
|
363
|
+
- Doctor: \`npx jgengine doctor\`
|
|
364
|
+
- Dev: \`bun dev\` / \`npm run dev\`
|
|
365
|
+
|
|
366
|
+
## Project rules
|
|
367
|
+
|
|
368
|
+
- Shape: \`src/\` holds only \`game.config.ts\`, \`index.tsx\`, \`main.tsx\`, \`loop.ts\`, \`world.ts\`, \`index.css\`; everything else under \`src/game/\`.
|
|
369
|
+
- Entry: \`defineGame({...})\` from \`@jgengine/shell/defineGame\` in \`game.config.ts\`.
|
|
370
|
+
- Prove world content with \`summarizeEnvironment\` in \`bun test\` (\`src/game/world.world.test.ts\`), not screenshot loops.
|
|
371
|
+
- Tailwind v4: \`@source\` in \`src/index.css\` must cover \`@jgengine/react\` and \`@jgengine/shell\`${variant === "in-repo" ? " (engine source under packages/)" : " (dist under node_modules)"}, or the HUD is silently unstyled.
|
|
372
|
+
- Spawn player with \`id === ctx.player.userId\` in \`onNewPlayer\`; \`onTick\` \`dt\` is game time.
|
|
362
373
|
`;
|
|
363
374
|
export function gameTemplate(options) {
|
|
364
375
|
const { id, name, variant, engineVersion } = options;
|
package/llms.txt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @jgengine/jgengine
|
|
2
|
-
>
|
|
2
|
+
> Agent-side CLI for JGengine. People build by telling an agent: Make a game that ... with jgengine. Agents use this CLI (create, skills, doctor, llms). Docs: https://jgengine.com
|
|
3
3
|
|
|
4
|
-
Version: 0.8.
|
|
4
|
+
Version: 0.8.3
|
|
5
5
|
License: AGPL-3.0-only
|
|
6
6
|
Repository: https://github.com/Noisemaker111/jgengine
|
|
7
7
|
Docs: https://jgengine.com
|
|
@@ -53,8 +53,10 @@ Imports use deep paths: `@jgengine/jgengine/<path>`.
|
|
|
53
53
|
|
|
54
54
|
- parseSkillsArgs (function): function parseSkillsArgs(argv: string[]): { scope: SkillsScope } | { error: string }
|
|
55
55
|
- skillsInstallArgs (function): function skillsInstallArgs(scope: SkillsScope): string[]
|
|
56
|
+
- installSkills (function): function installSkills(scope: SkillsScope, cwd?: string): number
|
|
56
57
|
- runSkills (function): function runSkills(argv: string[]): number
|
|
57
58
|
- SKILLS_SOURCE (const): const SKILLS_SOURCE: "Noisemaker111/jgengine"
|
|
59
|
+
- GAME_SKILLS (const): const GAME_SKILLS: readonly ["jgengine-api", "jgengine-newgame", "jgengine-verify"]
|
|
58
60
|
- SkillsScope (type): type SkillsScope = "global" | "project"
|
|
59
61
|
|
|
60
62
|
### @jgengine/jgengine/templates
|
|
@@ -302,14 +304,14 @@ Exact import paths and export names — **do not invent paths**; every row below
|
|
|
302
304
|
|
|
303
305
|
## Getting started (new project)
|
|
304
306
|
|
|
305
|
-
|
|
307
|
+
**People** start with one sentence to an agent: `Make a game that … with jgengine`. They do not need the CLI.
|
|
308
|
+
|
|
309
|
+
**Agents** scaffold with the CLI — harness, skeleton, stub game, verify test, AGENTS.md, skills:
|
|
306
310
|
|
|
307
311
|
```sh
|
|
308
|
-
npx jgengine create "My Game Name" # folder → My-Game-Name;
|
|
309
|
-
cd My-Game-Name
|
|
310
|
-
npx jgengine
|
|
311
|
-
bun dev
|
|
312
|
-
npx jgengine doctor # later, if the setup drifts (version skew, unstyled HUD, shape strays)
|
|
312
|
+
npx jgengine create "My Game Name" # folder → My-Game-Name; skills install automatically
|
|
313
|
+
cd My-Game-Name && bun dev
|
|
314
|
+
npx jgengine doctor # later, if setup drifts (version skew, unstyled HUD, shape)
|
|
313
315
|
```
|
|
314
316
|
|
|
315
317
|
Manual equivalent:
|
package/package.json
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jgengine",
|
|
3
|
-
"version": "0.8.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.8.3",
|
|
4
|
+
"description": "Agent-side CLI for JGengine. People build by telling an agent: Make a game that ... with jgengine. Agents use this CLI (create, skills, doctor, llms). Docs: https://jgengine.com",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"game-engine",
|
|
7
|
+
"typescript",
|
|
8
|
+
"jgengine",
|
|
9
|
+
"cli",
|
|
10
|
+
"three.js",
|
|
11
|
+
"agent",
|
|
12
|
+
"scaffold"
|
|
13
|
+
],
|
|
5
14
|
"license": "AGPL-3.0-only",
|
|
6
15
|
"type": "module",
|
|
7
16
|
"sideEffects": false,
|
|
17
|
+
"homepage": "https://jgengine.com",
|
|
8
18
|
"repository": {
|
|
9
19
|
"type": "git",
|
|
10
20
|
"url": "git+https://github.com/Noisemaker111/jgengine.git",
|