auramaxx 0.1.0 → 0.1.1

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 CHANGED
@@ -27,15 +27,34 @@ npx auramaxx
27
27
  Inside a scaffolded game, use the shorter `auramaxx` alias or the generated
28
28
  `npm run ...` scripts for local engine commands.
29
29
 
30
- Play an example:
30
+ ## Play an Example
31
31
 
32
32
  ```bash
33
- auramaxx play aurasu
33
+ npm install -g auramaxx
34
+ auramaxx play auracraft
34
35
 
35
36
  # or run a published game wrapper directly
36
- npx aurasu play
37
+ npx auracraft play
38
+ ```
39
+
40
+ ## Fork a Game
41
+
42
+ ```bash
43
+ npm install -g auramaxx
44
+ auramaxx fork auramon
37
45
  ```
38
46
 
47
+ ## Working With AI Agent
48
+
49
+ Inside your codebase:
50
+
51
+ ```bash
52
+ cd <your-codebase>
53
+ npx -y skills add Aura-Industry/auramaxx
54
+ ```
55
+
56
+ Then use <https://www.aurajs.gg/docs> for engine docs and API references.
57
+
39
58
  ## Multiplayer TL;DR
40
59
 
41
60
  ```bash
@@ -52,7 +71,7 @@ Keep that same flow and add internet-backed rooms with either:
52
71
  - `aura.config.json -> multiplayer.relay = "relay.aurajs.gg"`
53
72
  - or `AURA_MULTIPLAYER_RELAY_HOST=relay.aurajs.gg`
54
73
 
55
- Use [`packages/aurascript/docs/external/game-dev-api/multiplayer-quickstart.md`](./packages/aurascript/docs/external/game-dev-api/multiplayer-quickstart.md) for the short multiplayer doc, or [`packages/aurascript/examples/multiplayer-party/README.md`](./packages/aurascript/examples/multiplayer-party/README.md) for the same-project example with diagnostics and room chat.
74
+ Use [Multiplayer Quickstart](https://www.aurajs.gg/docs/multiplayer-quickstart) for the short multiplayer doc, or [Multiplayer Party Example](./packages/aurascript/examples/multiplayer-party/README.md) for the same-project example with diagnostics and room chat.
56
75
 
57
76
  ## Feature Set
58
77
 
@@ -80,13 +99,13 @@ Use [`packages/aurascript/docs/external/game-dev-api/multiplayer-quickstart.md`]
80
99
 
81
100
  ## Docs
82
101
 
83
- - [`packages/aurascript/README.md`](./packages/aurascript/README.md) - AuraJS overview and public docs entrypoint
84
- - [`docs/external/game-dev-api/README.md`](./docs/external/game-dev-api/README.md) - game developer handbook
85
- - [`docs/external/game-dev-api/multiplayer-quickstart.md`](./packages/aurascript/docs/external/game-dev-api/multiplayer-quickstart.md) - shortest multiplayer setup path
86
- - [`docs/api-contract.md`](./docs/api-contract.md) - frozen core API contract
87
- - [`docs/api-contract-3d.md`](./docs/api-contract-3d.md) - frozen 3D API contract
88
- - [`docs/reference/README.md`](./docs/reference/README.md) - exact reference index
89
- - [`docs/external/api-contract-complete.md`](./docs/external/api-contract-complete.md) - combined public reference
102
+ - [AuraJS README](https://www.aurajs.gg/docs) - AuraJS overview and public docs entrypoint
103
+ - [Game Developer Handbook](https://www.aurajs.gg/docs/handbook) - game developer handbook
104
+ - [Multiplayer Quickstart](https://www.aurajs.gg/docs/multiplayer-quickstart) - shortest multiplayer setup path
105
+ - [Core API Contract](https://www.aurajs.gg/docs/api-contract) - frozen core API contract
106
+ - [3D API Contract](https://www.aurajs.gg/docs/api-contract-3d) - frozen 3D API contract
107
+ - [Exact Reference Index](https://www.aurajs.gg/docs/reference) - exact reference index
108
+ - [Combined Public Reference](https://www.aurajs.gg/docs/reference) - combined public reference
90
109
 
91
110
  Live docs:
92
111
 
package/bin/auramaxx.js CHANGED
@@ -48,7 +48,7 @@ const COMMANDS = {
48
48
  'shell-hook': 'Auto-load .aura env vars on cd (like direnv)',
49
49
  play: 'Play an AuraJS game from npm (auramaxx play <game>)',
50
50
  fork: 'Fork a published AuraJS game into a local editable project (auramaxx fork <game>)',
51
- create: 'Scaffold a new AuraJS game (2d/3d/blank) via AuraJS CLI',
51
+ create: 'Scaffold a new AuraJS game (2d/3d/multiplayer) via AuraJS CLI',
52
52
  make: 'Generate authored AuraJS project files via AuraJS CLI',
53
53
  publish: 'Publish current AuraJS game package to npm with guided prompts',
54
54
  // diary: 'Append daily diary entries via authenticated CLI path', // Temporarily disabled at root CLI.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auramaxx",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "AuraJS CLI for creating, playing, and publishing JavaScript-first games.",
5
5
  "keywords": [
6
6
  "aurajs",
@@ -6,23 +6,21 @@ import { printBanner, printSection, paint, ANSI } from '../lib/theme';
6
6
  import { promptInput, promptSelect } from '../lib/prompt';
7
7
 
8
8
  const TEMPLATE_OPTIONS = [
9
- { value: '2d-shooter', label: '[2D] Shooter', aliases: ['1', '2', '2d', 'shooter', '2d shooter'] },
10
- { value: '3d-platformer', label: '[3D] Platformer', aliases: ['3', '3d', 'platformer', 'platformers', '3d platformer'] },
11
- { value: 'blank', label: 'Blank', aliases: ['b'] },
9
+ { value: '2d', label: '[2D] Adventure', aliases: ['1', '2', '2d', '2d-adventure', 'adventure-2d'] },
10
+ { value: '3d', label: '[3D] Adventure', aliases: ['3', '3d', '3d-adventure', 'adventure-3d'] },
11
+ { value: 'multiplayer', label: '[MP] Multiplayer', aliases: ['4', 'mp', 'multiplayer', 'room', 'room-code', 'local-multiplayer'] },
12
12
  ];
13
-
14
- const VALID_TEMPLATES = new Set(TEMPLATE_OPTIONS.map((option) => option.value));
15
13
  const TEMPLATE_ALIASES: Record<string, string> = {
16
- '2d': '2d-shooter',
17
- 'shooter': '2d-shooter',
18
- '2d shooter': '2d-shooter',
19
- '2d-shooter': '2d-shooter',
20
- '3d': '3d-platformer',
21
- 'platformer': '3d-platformer',
22
- 'platformers': '3d-platformer',
23
- '3d platformer': '3d-platformer',
24
- '3d-platformer': '3d-platformer',
25
- 'blank': 'blank',
14
+ '2d': '2d',
15
+ '2d-adventure': '2d',
16
+ 'adventure-2d': '2d',
17
+ '3d': '3d',
18
+ '3d-adventure': '3d',
19
+ 'adventure-3d': '3d',
20
+ 'multiplayer': 'multiplayer',
21
+ 'local-multiplayer': 'multiplayer',
22
+ 'room-code': 'multiplayer',
23
+ 'room': 'multiplayer',
26
24
  };
27
25
  const COMMAND_DIR = path.dirname(fileURLToPath(import.meta.url));
28
26
  const LOCAL_AURAJS_CLI = path.resolve(
@@ -98,15 +96,10 @@ async function resolveGameName(initialName: string | null): Promise<string> {
98
96
 
99
97
  async function resolveTemplate(initialTemplate: string | null): Promise<string> {
100
98
  const normalized = normalizeTemplate(initialTemplate);
101
- if (normalized && VALID_TEMPLATES.has(normalized)) {
99
+ if (normalized) {
102
100
  return normalized;
103
101
  }
104
-
105
- if (normalized && !VALID_TEMPLATES.has(normalized)) {
106
- console.log(` Unknown template "${normalized}"; choose one below.`);
107
- }
108
-
109
- return promptSelect(' Starter template', TEMPLATE_OPTIONS, '2d-shooter');
102
+ return promptSelect(' Starter template', TEMPLATE_OPTIONS, '2d');
110
103
  }
111
104
 
112
105
  async function main() {
@@ -114,10 +107,13 @@ async function main() {
114
107
 
115
108
  if (parsed.help) {
116
109
  printBanner('CREATE');
117
- console.log(` ${paint('Usage:', ANSI.bold)} auramaxx create [name] [--template <2d-shooter|3d-platformer|blank>] [--skip-install]`);
110
+ console.log(` ${paint('Usage:', ANSI.bold)} auramaxx create [name] [--template <2d|3d|multiplayer>] [--skip-install]`);
118
111
  console.log('');
119
112
  console.log(' Styled wrapper around AuraJS create scaffolding.');
120
- console.log(` ${paint('Example:', ANSI.dim)} auramaxx create my-game --template 3d-platformer`);
113
+ console.log(` ${paint('Examples:', ANSI.dim)}`);
114
+ console.log(' auramaxx create my-game --template 2d');
115
+ console.log(' auramaxx create my-game --template 3d');
116
+ console.log(' auramaxx create my-room-game --template multiplayer');
121
117
  console.log('');
122
118
  return;
123
119
  }
@@ -3,7 +3,7 @@ import { existsSync, mkdtempSync, readFileSync, rmSync } from 'fs';
3
3
  import { homedir, tmpdir } from 'os';
4
4
  import { join, resolve } from 'path';
5
5
  import { pathToFileURL } from 'url';
6
- import { printBanner, printSection, paint, ANSI } from '../lib/theme';
6
+ import { printBanner, printSection, paint, ANSI, createProgressDisplay } from '../lib/theme';
7
7
  import {
8
8
  assertPublishedGameBinIntegrity,
9
9
  buildPublishedGameLaunchEnv,
@@ -185,17 +185,21 @@ export async function installVerifiedGamePackage(
185
185
  {
186
186
  execFileSyncImpl = execFileSync,
187
187
  env = process.env,
188
+ onProgress,
188
189
  }: {
189
190
  execFileSyncImpl?: typeof execFileSync;
190
191
  env?: NodeJS.ProcessEnv;
192
+ onProgress?: (step: number, label: string, detail?: string) => void;
191
193
  } = {},
192
194
  ) {
193
195
  if (!plan.name || !plan.packageName) {
194
196
  throw new Error('installVerifiedGamePackage requires a resolved package spec.');
195
197
  }
196
198
 
199
+ onProgress?.(1, 'Resolving package', plan.packageName);
197
200
  const installRoot = mkdtempSync(join(tmpdir(), 'auramaxx-play-'));
198
201
  try {
202
+ onProgress?.(2, 'Installing verified wrapper', plan.name);
199
203
  execFileSyncImpl(resolveNpmCommand(), buildSecureInstallArgs(plan.name, installRoot), {
200
204
  stdio: ['ignore', 'pipe', 'pipe'],
201
205
  env: {
@@ -212,6 +216,7 @@ export async function installVerifiedGamePackage(
212
216
 
213
217
  const gamePackage = readInstalledPackageJson(packageRoot);
214
218
  const dependencySpec = String(gamePackage?.dependencies?.['@auraindustry/aurajs'] || '').trim();
219
+ onProgress?.(3, 'Verifying package integrity', dependencySpec || plan.packageName);
215
220
  const integrity = assertPublishedGameBinIntegrity({
216
221
  packageRoot,
217
222
  projectPackage: gamePackage,
@@ -296,14 +301,20 @@ export async function main(argv: string[] = process.argv.slice(2)) {
296
301
 
297
302
  printBanner(plan.name.toUpperCase());
298
303
  printSection(plan.name, describeForwardedCommand(plan.forwardedArgs[0] || 'play'));
304
+ const progress = createProgressDisplay(4);
299
305
 
300
306
  let install: Awaited<ReturnType<typeof installVerifiedGamePackage>> | null = null;
301
307
  try {
302
- install = await installVerifiedGamePackage(plan);
308
+ install = await installVerifiedGamePackage(plan, {
309
+ onProgress(step, label, detail) {
310
+ progress.update(step, label, detail);
311
+ },
312
+ });
303
313
  const env = buildPublishedGameLaunchEnv(
304
314
  process.env,
305
315
  plan.forwardedArgs[0] === 'join' ? { AURA_GAME_JOIN_MODE: 'play' } : {},
306
316
  );
317
+ progress.update(4, 'Launching game', plan.forwardedArgs[0] || 'play');
307
318
  execFileSync(process.execPath, [install.binAbsolutePath, ...plan.forwardedArgs], {
308
319
  stdio: 'inherit',
309
320
  cwd: install.packageRoot,
@@ -221,6 +221,64 @@ export function printComplete(message: string): void {
221
221
  console.log('');
222
222
  }
223
223
 
224
+ function stripAnsi(text: string): string {
225
+ return text.replace(/\x1b\[[0-9;]*m/g, '');
226
+ }
227
+
228
+ function formatProgressBar(current: number, total: number, width: number): string {
229
+ const safeTotal = Math.max(1, total);
230
+ const clamped = Math.max(0, Math.min(current, safeTotal));
231
+ const filled = Math.round((clamped / safeTotal) * width);
232
+ const active = paint('/'.repeat(filled), ANSI.fgAccent, ANSI.bold);
233
+ const pending = paint('-'.repeat(Math.max(0, width - filled)), ANSI.dim);
234
+ return `[${active}${pending}]`;
235
+ }
236
+
237
+ export interface ProgressDisplay {
238
+ update(step: number, label: string, detail?: string): void;
239
+ complete(label?: string, detail?: string): void;
240
+ }
241
+
242
+ export function createProgressDisplay(totalSteps: number, width = 24): ProgressDisplay {
243
+ const stdout = process.stdout;
244
+ const interactive = stdout.isTTY;
245
+ let renderedLineCount = 0;
246
+
247
+ function draw(step: number, label: string, detail?: string) {
248
+ const safeStep = Math.max(0, Math.min(step, totalSteps));
249
+ const titleLine = ` ${paint('//', ANSI.fgAccent, ANSI.bold)} ${paint(label, ANSI.bold)} ${paint(`${safeStep}/${totalSteps}`, ANSI.dim)} ${formatProgressBar(safeStep, totalSteps, width)}`;
250
+ const lines = detail ? [titleLine, ` ${paint(detail, ANSI.dim)}`] : [titleLine];
251
+
252
+ if (interactive && renderedLineCount > 0) {
253
+ stdout.write(`\u001b[${renderedLineCount}A`);
254
+ for (let index = 0; index < renderedLineCount; index += 1) {
255
+ stdout.write('\u001b[2K');
256
+ stdout.write('\u001b[1B');
257
+ }
258
+ stdout.write(`\u001b[${renderedLineCount}A`);
259
+ }
260
+
261
+ for (const line of lines) {
262
+ if (interactive) {
263
+ stdout.write('\u001b[2K');
264
+ stdout.write(`${line}\n`);
265
+ } else {
266
+ console.log(stripAnsi(line));
267
+ }
268
+ }
269
+ renderedLineCount = lines.length;
270
+ }
271
+
272
+ return {
273
+ update(step: number, label: string, detail?: string) {
274
+ draw(step, label, detail);
275
+ },
276
+ complete(label = 'Ready', detail?: string) {
277
+ draw(totalSteps, label, detail);
278
+ },
279
+ };
280
+ }
281
+
224
282
  // ── Seed phrase box (security-critical) ──────────────────────
225
283
 
226
284
  /**