jgengine 0.8.1 → 0.8.2
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 +16 -18
- package/dist/create.js +11 -3
- package/dist/skills.d.ts +2 -0
- package/dist/skills.js +21 -19
- package/dist/templates.js +20 -11
- package/llms.txt +7 -7
- package/package.json +12 -2
package/dist/cli/index.js
CHANGED
|
@@ -9,28 +9,26 @@ 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()} —
|
|
13
|
-
|
|
12
|
+
const HELP = `jgengine ${cliVersion()} — pure-TypeScript game engine SDK + agent entry
|
|
13
|
+
Packages: ${ENGINE_PACKAGES.map((name) => `@jgengine/${name}`).join(", ")}.
|
|
14
|
+
docs: https://jgengine.com · source: https://github.com/Noisemaker111/jgengine
|
|
15
|
+
|
|
16
|
+
ENTRY (agents: run this when the user says "use jgengine" / "make a game with npx jgengine"):
|
|
17
|
+
npx jgengine create "Game Name"
|
|
18
|
+
cd Game-Name
|
|
19
|
+
# skills install automatically · AGENTS.md briefs you · then build the game
|
|
14
20
|
|
|
15
21
|
usage: jgengine <command> [...args]
|
|
16
22
|
|
|
17
|
-
create "<Game Name>" scaffold
|
|
18
|
-
folder
|
|
19
|
-
[--in-repo|--standalone] [--no-install] [--pm bun|npm|pnpm]
|
|
20
|
-
skills -p | -g install
|
|
21
|
-
doctor [dir] diagnose
|
|
22
|
-
llms [package] print packaged API docs (llms.txt)
|
|
23
|
-
assets [...]
|
|
24
|
-
versions
|
|
23
|
+
create "<Game Name>" scaffold playable base + install agent skills into the project
|
|
24
|
+
folder My-Game-Name; name → game.config / HUD / title
|
|
25
|
+
[--in-repo|--standalone] [--no-install] [--no-skills] [--pm bun|npm|pnpm]
|
|
26
|
+
skills -p | -g re-install skills only if create was run with --no-skills
|
|
27
|
+
doctor [dir] diagnose version skew, missing peers, unstyled HUD, shape drift
|
|
28
|
+
llms [package] print packaged API docs (llms.txt) — agent-ready
|
|
29
|
+
assets [...] @jgengine/assets CLI: list, search, pull CC0 packs
|
|
30
|
+
versions CLI + installed @jgengine/* versions
|
|
25
31
|
help this map
|
|
26
|
-
|
|
27
|
-
docs: https://jgengine.com · source: https://github.com/Noisemaker111/jgengine
|
|
28
|
-
|
|
29
|
-
entry (any directory, no monorepo needed):
|
|
30
|
-
npx jgengine create "Solitaire"
|
|
31
|
-
cd Solitaire
|
|
32
|
-
npx jgengine skills -p # or: npx jgengine skills -g (once, for every project)
|
|
33
|
-
# then: make Solitaire with jgengine
|
|
34
32
|
`;
|
|
35
33
|
function runVersions() {
|
|
36
34
|
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
|
+
create already installs project skills for you — you usually never need this command.
|
|
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,30 @@ 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\`, …). The CLI is \`npx jgengine\`. 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
|
+
## What to do when the user wants this game built
|
|
354
352
|
|
|
355
|
-
|
|
353
|
+
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 \`npx jgengine create\`.
|
|
354
|
+
2. If skills are missing: \`npx jgengine skills -p\` (or use this file + \`npx jgengine llms core\`).
|
|
355
|
+
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.
|
|
356
|
+
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.
|
|
356
357
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
-
|
|
360
|
-
-
|
|
361
|
-
- \`
|
|
358
|
+
## Engine loaders
|
|
359
|
+
|
|
360
|
+
- API docs in the tarball: \`npx jgengine llms core\` (any package: react, shell, …)
|
|
361
|
+
- Doctor: \`npx jgengine doctor\`
|
|
362
|
+
- Dev: \`bun dev\` / \`npm run dev\`
|
|
363
|
+
|
|
364
|
+
## Project rules
|
|
365
|
+
|
|
366
|
+
- Shape: \`src/\` holds only \`game.config.ts\`, \`index.tsx\`, \`main.tsx\`, \`loop.ts\`, \`world.ts\`, \`index.css\`; everything else under \`src/game/\`.
|
|
367
|
+
- Entry: \`defineGame({...})\` from \`@jgengine/shell/defineGame\` in \`game.config.ts\`.
|
|
368
|
+
- Prove world content with \`summarizeEnvironment\` in \`bun test\` (\`src/game/world.world.test.ts\`), not screenshot loops.
|
|
369
|
+
- 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.
|
|
370
|
+
- Spawn player with \`id === ctx.player.userId\` in \`onNewPlayer\`; \`onTick\` \`dt\` is game time.
|
|
362
371
|
`;
|
|
363
372
|
export function gameTemplate(options) {
|
|
364
373
|
const { id, name, variant, engineVersion } = options;
|
package/llms.txt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @jgengine/jgengine
|
|
2
|
-
>
|
|
2
|
+
> JGengine CLI — pure-TypeScript game engine entry for humans and agents. Run: npx jgengine create "My Game Name" (scaffolds a playable base and installs agent skills). Then build the game. Docs: https://jgengine.com
|
|
3
3
|
|
|
4
|
-
Version: 0.8.
|
|
4
|
+
Version: 0.8.2
|
|
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
|
|
@@ -305,11 +307,9 @@ Exact import paths and export names — **do not invent paths**; every row below
|
|
|
305
307
|
Fastest path — the `jgengine` CLI scaffolds the entire canonical shape below (harness, skeleton, stub game, verify test, AGENTS.md) as a booting game:
|
|
306
308
|
|
|
307
309
|
```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)
|
|
310
|
+
npx jgengine create "My Game Name" # folder → My-Game-Name; skills install automatically
|
|
311
|
+
cd My-Game-Name && bun dev
|
|
312
|
+
npx jgengine doctor # later, if setup drifts (version skew, unstyled HUD, shape)
|
|
313
313
|
```
|
|
314
314
|
|
|
315
315
|
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.2",
|
|
4
|
+
"description": "JGengine CLI — pure-TypeScript game engine entry for humans and agents. Run: npx jgengine create \"My Game Name\" (scaffolds a playable base and installs agent skills). Then build the game. 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",
|