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 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()} — the JGengine command line
13
- Pure-TypeScript, genre-agnostic game engine SDK. Packages: ${ENGINE_PACKAGES.map((name) => `@jgengine/${name}`).join(", ")}.
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 a playable base flat world, spawned player, HUD, verify test.
18
- folder becomes My-Game-Name; name lands in game.config / HUD / title.
19
- [--in-repo|--standalone] [--no-install] [--pm bun|npm|pnpm]
20
- skills -p | -g install agent skills (api, newgame, verify). -p this project (default), -g global
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
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 # or npm run dev — flat world, spawned player, working HUD");
135
- console.log(" npx jgengine skills -p # agent skills in this project (-g for global)");
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", "--all"];
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 (.claude/skills) — default
53
+ -p, --project install into this project (default)
39
54
  -g, --global install for your user (every project / agent session)
40
55
 
41
- Installs jgengine-api, jgengine-newgame, and jgengine-verify from ${SKILLS_SOURCE}.
56
+ Installs ${GAME_SKILLS.join(", ")} from ${SKILLS_SOURCE}.
42
57
 
43
- entry:
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('usage: jgengine skills (-g|--global | -p|--project)');
63
+ console.error("usage: jgengine skills (-g|--global | -p|--project)");
56
64
  return 1;
57
65
  }
58
- const where = parsed.scope === "global" ? "globally" : "in this project";
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 notes
347
+ const agentsMd = (name, variant) => `# ${name} — agent briefing
348
348
 
349
- This is a JGengine game (pure-TypeScript engine SDK, \`@jgengine/*\` on npm). Load context before writing code:
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
- - Engine API surface: \`npx jgengine llms core\` (any package name works) prints the packaged API docs.
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
- Rules this project follows:
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
- - Shape: \`src/\` holds only \`game.config.ts\`, \`index.tsx\`, \`main.tsx\`, \`loop.ts\`, \`world.ts\`, \`index.css\`; every game-specific module, UI component, and test lives under \`src/game/\`.
358
- - \`game.config.ts\` is the single entry — \`defineGame({...})\` from \`@jgengine/shell/defineGame\`.
359
- - Scene and world changes are proven with \`summarizeEnvironment\` assertions in \`bun test src\` (see \`src/game/world.world.test.ts\`), never by screenshots as the inner loop.
360
- - HUD styling is Tailwind v4: the \`@source\` entries in \`src/index.css\` must cover \`@jgengine/react\` and \`@jgengine/shell\`${variant === "in-repo" ? " (engine source dirs in this monorepo)" : " (their dist dirs in node_modules)"}, or engine UI classes are silently not generated and the HUD renders unstyled.
361
- - \`onNewPlayer\` spawns the player entity with \`id === ctx.player.userId\`; \`onTick\`'s \`dt\` is game time, never wall-clock.
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
- > The JGengine command line scaffold a playable game, diagnose a broken setup, and load engine docs and agent skills into any project. Start with `npx jgengine create "My Game Name"`.
2
+ > JGengine CLIpure-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.1
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; name lands in game.config / HUD / title
309
- cd My-Game-Name
310
- npx jgengine skills -p # agent skills here; use -g once for global
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.1",
4
- "description": "The JGengine command line scaffold a playable game, diagnose a broken setup, and load engine docs and agent skills into any project. Start with `npx jgengine create \"My Game Name\"`.",
3
+ "version": "0.8.2",
4
+ "description": "JGengine CLIpure-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",