auramaxx 0.1.2 → 0.1.4
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 +4 -0
- package/bin/auramaxx.js +135 -12
- package/package.json +3 -1
- package/src/server/cli/commands/fork.ts +81 -0
- package/src/server/cli/commands/make.ts +90 -0
- package/src/server/cli/commands/play.ts +45 -3
- package/src/server/cli/commands/publish.ts +60 -1
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# AuraJS
|
|
2
2
|
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
|
|
3
5
|
Write JavaScript 2D and 3D games, compile to native.
|
|
4
6
|
Create, play, and publish from your terminal.
|
|
5
7
|
|
|
@@ -37,6 +39,8 @@ auramaxx play auracraft
|
|
|
37
39
|
npx auracraft play
|
|
38
40
|
```
|
|
39
41
|
|
|
42
|
+

|
|
43
|
+
|
|
40
44
|
## Fork a Game
|
|
41
45
|
|
|
42
46
|
```bash
|
package/bin/auramaxx.js
CHANGED
|
@@ -49,8 +49,21 @@ const COMMANDS = {
|
|
|
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
51
|
create: 'Scaffold a new AuraJS game (2d/3d/multiplayer) via AuraJS CLI',
|
|
52
|
+
dev: 'Run the AuraJS local dev loop in the current project',
|
|
53
|
+
build: 'Build the current AuraJS project',
|
|
52
54
|
make: 'Generate authored AuraJS project files via AuraJS CLI',
|
|
55
|
+
explain: 'Explain the current AuraJS project surface',
|
|
56
|
+
check: 'Validate the current AuraJS project surface',
|
|
53
57
|
publish: 'Publish current AuraJS game package to npm with guided prompts',
|
|
58
|
+
'external-assets': 'Stage self-hosted external asset manifests for the current AuraJS project',
|
|
59
|
+
run: 'Run the current AuraJS project with lower-level launch/session control',
|
|
60
|
+
clean: 'Clean generated AuraJS project output',
|
|
61
|
+
test: 'Run AuraJS project tests',
|
|
62
|
+
conformance: 'Run AuraJS project conformance checks',
|
|
63
|
+
state: 'Run AuraJS project state tools',
|
|
64
|
+
inspect: 'Run AuraJS project inspect tools',
|
|
65
|
+
action: 'Run AuraJS project action tools',
|
|
66
|
+
session: 'Run AuraJS project session tools',
|
|
54
67
|
// diary: 'Append daily diary entries via authenticated CLI path', // Temporarily disabled at root CLI.
|
|
55
68
|
// apikey: 'List/validate/set/delete API keys', // Temporarily disabled at root CLI.
|
|
56
69
|
// quickhack: 'Generate random tutorial secret, run set+inject, and print copyable commands', // Temporarily disabled at root CLI.
|
|
@@ -122,7 +135,26 @@ const SHORTCUT_COMMANDS = [];
|
|
|
122
135
|
// ];
|
|
123
136
|
|
|
124
137
|
const DEFAULT_ADMIN = ['start', 'status', 'init', 'mcp', 'skill', 'auth'];
|
|
125
|
-
const AURAJS_COMMANDS = [
|
|
138
|
+
const AURAJS_COMMANDS = [
|
|
139
|
+
'create',
|
|
140
|
+
'dev',
|
|
141
|
+
'build',
|
|
142
|
+
'play',
|
|
143
|
+
'make',
|
|
144
|
+
'explain',
|
|
145
|
+
'check',
|
|
146
|
+
'publish',
|
|
147
|
+
'external-assets',
|
|
148
|
+
'run',
|
|
149
|
+
'clean',
|
|
150
|
+
'test',
|
|
151
|
+
'conformance',
|
|
152
|
+
'state',
|
|
153
|
+
'inspect',
|
|
154
|
+
'action',
|
|
155
|
+
'session',
|
|
156
|
+
'fork',
|
|
157
|
+
];
|
|
126
158
|
const HIDDEN_HELP_COMMANDS = new Set(['wallet']);
|
|
127
159
|
|
|
128
160
|
const COMMON_EXAMPLES = [
|
|
@@ -131,6 +163,8 @@ const COMMON_EXAMPLES = [
|
|
|
131
163
|
{ cmd: 'aura skill --doctor', note: 'Check skill installation status' },
|
|
132
164
|
{ cmd: 'aura mcp --install', note: 'Install MCP config for supported clients' },
|
|
133
165
|
{ cmd: 'auramaxx make scene Scene1', note: 'Generate a scene in the current AuraJS project' },
|
|
166
|
+
{ cmd: 'auramaxx check', note: 'Validate the current AuraJS project from any project subdirectory' },
|
|
167
|
+
{ cmd: 'auramaxx external-assets generate --public-base-url https://cdn.example.com/my-game', note: 'Stage self-hosted asset manifests for the current AuraJS project' },
|
|
134
168
|
{ cmd: 'auramaxx fork aurasu ./aurasu-local', note: 'Fork a published AuraJS game into a local editable project' },
|
|
135
169
|
// { cmd: 'aura diary write --entry "heartbeat ok"', note: 'Append a daily diary entry (auth-aware)' }, // Temporarily disabled at root CLI.
|
|
136
170
|
// { cmd: 'aura get OURSECRET', note: 'Read a credential' }, // Temporarily disabled at root CLI.
|
|
@@ -673,10 +707,18 @@ function getUpdateCachePath() {
|
|
|
673
707
|
return path.join(dataDir, `update-check-${key}.json`);
|
|
674
708
|
}
|
|
675
709
|
|
|
710
|
+
function resolveNpmCommand() {
|
|
711
|
+
return process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
function resolveAuramaxxCommand() {
|
|
715
|
+
return process.platform === 'win32' ? 'auramaxx.cmd' : 'auramaxx';
|
|
716
|
+
}
|
|
717
|
+
|
|
676
718
|
function getGlobalInstalledAuramaxxVersion() {
|
|
677
719
|
const timeoutMs = Number(process.env.AURA_UPDATE_CHECK_TIMEOUT_MS || '1200');
|
|
678
720
|
try {
|
|
679
|
-
const out = execFileSync(
|
|
721
|
+
const out = execFileSync(resolveNpmCommand(), ['list', '-g', 'auramaxx', '--json'], {
|
|
680
722
|
cwd: root,
|
|
681
723
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
682
724
|
timeout: timeoutMs,
|
|
@@ -705,7 +747,7 @@ function formatUpdateAvailableLine(current, latest) {
|
|
|
705
747
|
return `⚠️ Update available: aura${normalizedCurrent} → aura${normalizedLatest}`;
|
|
706
748
|
}
|
|
707
749
|
|
|
708
|
-
function
|
|
750
|
+
function resolveUpdateNoticeState() {
|
|
709
751
|
if (process.env.AURA_NO_UPDATE_CHECK === '1' || process.env.CI === 'true') return;
|
|
710
752
|
|
|
711
753
|
const now = Date.now();
|
|
@@ -736,10 +778,9 @@ function maybePrintUpdateNotice() {
|
|
|
736
778
|
}
|
|
737
779
|
|
|
738
780
|
if (cachedLatest && compareVersions(cachedLatest, effectiveCurrent || '') > 0) {
|
|
739
|
-
|
|
740
|
-
console.log(' Run: npm i -g auramaxx --foreground-scripts (fallback: npx --yes auramaxx@latest start)\n');
|
|
781
|
+
return { current: effectiveCurrent, latest: cachedLatest };
|
|
741
782
|
}
|
|
742
|
-
return;
|
|
783
|
+
return null;
|
|
743
784
|
}
|
|
744
785
|
|
|
745
786
|
let latest = process.env.AURA_UPDATE_CHECK_MOCK_LATEST || null;
|
|
@@ -747,18 +788,18 @@ function maybePrintUpdateNotice() {
|
|
|
747
788
|
|
|
748
789
|
if (!latest) {
|
|
749
790
|
try {
|
|
750
|
-
const out = execFileSync(
|
|
791
|
+
const out = execFileSync(resolveNpmCommand(), ['view', 'auramaxx', 'version', '--json'], {
|
|
751
792
|
cwd: root,
|
|
752
793
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
753
794
|
timeout: Number(process.env.AURA_UPDATE_CHECK_TIMEOUT_MS || '1200'),
|
|
754
795
|
}).toString('utf8').trim();
|
|
755
796
|
latest = JSON.parse(out);
|
|
756
797
|
} catch {
|
|
757
|
-
return;
|
|
798
|
+
return null;
|
|
758
799
|
}
|
|
759
800
|
}
|
|
760
801
|
latest = normalizeVersionString(latest);
|
|
761
|
-
if (!latest) return;
|
|
802
|
+
if (!latest) return null;
|
|
762
803
|
|
|
763
804
|
try {
|
|
764
805
|
fs.mkdirSync(path.dirname(cachePath), { recursive: true });
|
|
@@ -766,9 +807,91 @@ function maybePrintUpdateNotice() {
|
|
|
766
807
|
} catch {}
|
|
767
808
|
|
|
768
809
|
if (latest && compareVersions(latest, current) > 0) {
|
|
769
|
-
|
|
770
|
-
console.log(' Run: npm i -g auramaxx --foreground-scripts (fallback: npx --yes auramaxx@latest start)\n');
|
|
810
|
+
return { current, latest };
|
|
771
811
|
}
|
|
812
|
+
|
|
813
|
+
return null;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
function reinstallLatestAuramaxx() {
|
|
817
|
+
try {
|
|
818
|
+
execFileSync(resolveNpmCommand(), ['uninstall', '-g', 'auramaxx'], {
|
|
819
|
+
stdio: 'inherit',
|
|
820
|
+
timeout: 120000,
|
|
821
|
+
});
|
|
822
|
+
} catch {
|
|
823
|
+
// Ignore uninstall failures for missing or partially-installed global packages.
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
execFileSync(resolveNpmCommand(), ['install', '-g', 'auramaxx@latest', '--foreground-scripts'], {
|
|
827
|
+
stdio: 'inherit',
|
|
828
|
+
timeout: 180000,
|
|
829
|
+
});
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
function relaunchUpdatedAuramaxx(argv, latestVersion) {
|
|
833
|
+
const installedVersion = normalizeVersionString(getGlobalInstalledAuramaxxVersion()) || 'unknown';
|
|
834
|
+
const useNpxLatest = installedVersion === 'unknown' || compareVersions(latestVersion, installedVersion) > 0;
|
|
835
|
+
const command = useNpxLatest ? 'npx' : resolveAuramaxxCommand();
|
|
836
|
+
const args = useNpxLatest
|
|
837
|
+
? ['--yes', 'auramaxx@latest', ...argv]
|
|
838
|
+
: argv;
|
|
839
|
+
|
|
840
|
+
execFileSync(command, args, {
|
|
841
|
+
stdio: 'inherit',
|
|
842
|
+
env: {
|
|
843
|
+
...process.env,
|
|
844
|
+
AURA_NO_UPDATE_CHECK: '1',
|
|
845
|
+
},
|
|
846
|
+
});
|
|
847
|
+
process.exit(0);
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
async function maybeHandleUpdateNotice() {
|
|
851
|
+
const update = resolveUpdateNoticeState();
|
|
852
|
+
if (!update) return;
|
|
853
|
+
|
|
854
|
+
const noticeLine = formatUpdateAvailableLine(update.current, update.latest);
|
|
855
|
+
if (!canPromptForInput()) {
|
|
856
|
+
console.log(`\n${noticeLine}`);
|
|
857
|
+
console.log(' Run: npm uninstall -g auramaxx && npm install -g auramaxx --foreground-scripts (fallback: npx --yes auramaxx@latest start)\n');
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
console.log(`\n${noticeLine}`);
|
|
862
|
+
const choice = await promptSelect(
|
|
863
|
+
'Update AuraMaxx now?',
|
|
864
|
+
[
|
|
865
|
+
{ value: 'continue', label: 'No, continue', aliases: ['n', 'no', 'continue', '2'] },
|
|
866
|
+
{ value: 'update', label: 'Yes, update and relaunch', aliases: ['y', 'yes', 'update', '1'] },
|
|
867
|
+
],
|
|
868
|
+
'continue',
|
|
869
|
+
);
|
|
870
|
+
|
|
871
|
+
if (choice !== 'update') {
|
|
872
|
+
console.log('');
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
console.log('');
|
|
877
|
+
console.log(' Reinstalling latest AuraMaxx...');
|
|
878
|
+
console.log('');
|
|
879
|
+
|
|
880
|
+
try {
|
|
881
|
+
reinstallLatestAuramaxx();
|
|
882
|
+
} catch (error) {
|
|
883
|
+
console.log('');
|
|
884
|
+
console.error(` Failed to update AuraMaxx automatically: ${error?.message || String(error)}`);
|
|
885
|
+
console.error(' Manual fallback: npm uninstall -g auramaxx && npm install -g auramaxx --foreground-scripts');
|
|
886
|
+
console.error(' Fallback: npx --yes auramaxx@latest start');
|
|
887
|
+
console.log('');
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
console.log('');
|
|
892
|
+
console.log(' [ok] AuraMaxx updated. Relaunching command...');
|
|
893
|
+
console.log('');
|
|
894
|
+
relaunchUpdatedAuramaxx(process.argv.slice(2), update.latest);
|
|
772
895
|
}
|
|
773
896
|
|
|
774
897
|
function buildRunner(commandName, commandArgs = []) {
|
|
@@ -1383,7 +1506,7 @@ async function main() {
|
|
|
1383
1506
|
}
|
|
1384
1507
|
}
|
|
1385
1508
|
|
|
1386
|
-
|
|
1509
|
+
await maybeHandleUpdateNotice();
|
|
1387
1510
|
maybeAutoInstallAuraAlias();
|
|
1388
1511
|
maybeAutoInstallSkills();
|
|
1389
1512
|
maybeAutoInstallMcp();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "auramaxx",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "AuraJS CLI for creating, playing, and publishing JavaScript-first games.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"aurajs",
|
|
@@ -26,6 +26,8 @@
|
|
|
26
26
|
"src/lib/startBannerQuotes.ts",
|
|
27
27
|
"src/server/cli/commands/onboard.ts",
|
|
28
28
|
"src/server/cli/commands/create.ts",
|
|
29
|
+
"src/server/cli/commands/fork.ts",
|
|
30
|
+
"src/server/cli/commands/make.ts",
|
|
29
31
|
"src/server/cli/commands/play.ts",
|
|
30
32
|
"src/server/cli/commands/publish.ts",
|
|
31
33
|
"src/server/cli/lib/published-game-integrity.ts",
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { execFileSync } from 'child_process';
|
|
2
|
+
import { rmSync } from 'fs';
|
|
3
|
+
import { pathToFileURL } from 'url';
|
|
4
|
+
|
|
5
|
+
import { printBanner, printSection, paint, ANSI } from '../lib/theme';
|
|
6
|
+
import {
|
|
7
|
+
buildPublishedGameLaunchEnv,
|
|
8
|
+
installVerifiedGamePackage,
|
|
9
|
+
parseArgs,
|
|
10
|
+
resolveGameBin,
|
|
11
|
+
resolvePackageName,
|
|
12
|
+
} from './play';
|
|
13
|
+
|
|
14
|
+
export interface ForkCommandPlan {
|
|
15
|
+
help: boolean;
|
|
16
|
+
name: string | null;
|
|
17
|
+
gameArgs: string[];
|
|
18
|
+
gameBin: string | null;
|
|
19
|
+
packageName: string | null;
|
|
20
|
+
forwardedArgs: string[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function buildForkPlan(argv: string[]): ForkCommandPlan {
|
|
24
|
+
const parsed = parseArgs(argv);
|
|
25
|
+
return {
|
|
26
|
+
...parsed,
|
|
27
|
+
gameBin: parsed.name ? resolveGameBin(parsed.name) : null,
|
|
28
|
+
packageName: parsed.name ? resolvePackageName(parsed.name) : null,
|
|
29
|
+
forwardedArgs: ['fork', ...parsed.gameArgs],
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function main(argv: string[] = process.argv.slice(2)) {
|
|
34
|
+
const plan = buildForkPlan(argv);
|
|
35
|
+
|
|
36
|
+
if (plan.help || !plan.name) {
|
|
37
|
+
printBanner('FORK');
|
|
38
|
+
console.log(` ${paint('Usage:', ANSI.bold)} auramaxx fork <game> [destination|wrapper fork options]`);
|
|
39
|
+
console.log('');
|
|
40
|
+
console.log(` ${paint('Examples:', ANSI.dim)}`);
|
|
41
|
+
console.log(' auramaxx fork aurasu');
|
|
42
|
+
console.log(' auramaxx fork aurasu ./aurasu-local');
|
|
43
|
+
console.log(' auramaxx fork @auraindustry/chess-dev-cli@1.2.3 --dest ./chess-local');
|
|
44
|
+
console.log('');
|
|
45
|
+
console.log(` ${paint('Runs:', ANSI.dim)} verified signed temporary install -> local game wrapper fork`);
|
|
46
|
+
console.log('');
|
|
47
|
+
if (!plan.name && !plan.help) {
|
|
48
|
+
console.error(' Missing game name.');
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
printBanner(plan.name.toUpperCase());
|
|
55
|
+
printSection(plan.name, 'Forking editable package into local project...');
|
|
56
|
+
|
|
57
|
+
let install: Awaited<ReturnType<typeof installVerifiedGamePackage>> | null = null;
|
|
58
|
+
try {
|
|
59
|
+
install = await installVerifiedGamePackage(plan);
|
|
60
|
+
const env = buildPublishedGameLaunchEnv(process.env);
|
|
61
|
+
execFileSync(process.execPath, [install.binAbsolutePath, ...plan.forwardedArgs], {
|
|
62
|
+
stdio: 'inherit',
|
|
63
|
+
cwd: install.packageRoot,
|
|
64
|
+
env,
|
|
65
|
+
});
|
|
66
|
+
} finally {
|
|
67
|
+
if (install?.installRoot) {
|
|
68
|
+
rmSync(install.installRoot, { recursive: true, force: true });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
74
|
+
main().catch((err) => {
|
|
75
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
76
|
+
const status = (err as { status?: number; exitCode?: number })?.status
|
|
77
|
+
?? (err as { status?: number; exitCode?: number })?.exitCode
|
|
78
|
+
?? 1;
|
|
79
|
+
process.exit(Number.isInteger(status) ? status : 1);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { execFileSync } from 'child_process';
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { printBanner, paint, ANSI } from '../lib/theme';
|
|
6
|
+
|
|
7
|
+
const COMMAND_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const LOCAL_AURAJS_CLI = path.resolve(
|
|
9
|
+
COMMAND_DIR,
|
|
10
|
+
'../../../../../packages/aurascript/src/cli/src/cli.mjs',
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
function parseArgs(argv: string[]) {
|
|
14
|
+
for (const arg of argv) {
|
|
15
|
+
if (arg === '--help' || arg === '-h') {
|
|
16
|
+
return { help: true, passthrough: [] as string[] };
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
help: false,
|
|
21
|
+
passthrough: [...argv],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function resolveInvocationCwd(): string {
|
|
26
|
+
const forwardedCwd = process.env.AURA_INVOKE_CWD;
|
|
27
|
+
if (forwardedCwd && path.isAbsolute(forwardedCwd)) {
|
|
28
|
+
return forwardedCwd;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const shellPwd = process.env.PWD;
|
|
32
|
+
if (shellPwd && path.isAbsolute(shellPwd)) {
|
|
33
|
+
return shellPwd;
|
|
34
|
+
}
|
|
35
|
+
return process.cwd();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function main() {
|
|
39
|
+
const parsed = parseArgs(process.argv.slice(2));
|
|
40
|
+
|
|
41
|
+
if (parsed.help) {
|
|
42
|
+
printBanner('MAKE');
|
|
43
|
+
console.log(` ${paint('Usage:', ANSI.bold)} auramaxx make [kind] [name] [--role <custom|enemy|pickup|player|world>]`);
|
|
44
|
+
console.log('');
|
|
45
|
+
console.log(' Public wrapper around AuraJS project file generation.');
|
|
46
|
+
console.log(' Run it from inside an AuraJS game project.');
|
|
47
|
+
console.log(` ${paint('Examples:', ANSI.dim)}`);
|
|
48
|
+
console.log(' auramaxx make');
|
|
49
|
+
console.log(' auramaxx make scene Scene1');
|
|
50
|
+
console.log(' auramaxx make ui-screen PauseMenu');
|
|
51
|
+
console.log(' auramaxx make prefab EnemyShip --role enemy');
|
|
52
|
+
console.log(' auramaxx make list');
|
|
53
|
+
console.log('');
|
|
54
|
+
console.log(' When no arguments are passed in a TTY, AuraJS opens an interactive make flow.');
|
|
55
|
+
console.log('');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const invocationCwd = resolveInvocationCwd();
|
|
60
|
+
const auraArgs = ['make', ...parsed.passthrough];
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
if (existsSync(LOCAL_AURAJS_CLI)) {
|
|
64
|
+
execFileSync(process.execPath, [LOCAL_AURAJS_CLI, ...auraArgs], {
|
|
65
|
+
cwd: invocationCwd,
|
|
66
|
+
stdio: 'inherit',
|
|
67
|
+
env: process.env,
|
|
68
|
+
});
|
|
69
|
+
} else {
|
|
70
|
+
execFileSync(
|
|
71
|
+
'npm',
|
|
72
|
+
['exec', '--yes', '--package', '@auraindustry/aurajs', '--', 'aura', ...auraArgs],
|
|
73
|
+
{
|
|
74
|
+
cwd: invocationCwd,
|
|
75
|
+
stdio: 'inherit',
|
|
76
|
+
env: process.env,
|
|
77
|
+
},
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
} catch (error: unknown) {
|
|
81
|
+
const status = (error as { status?: number }).status;
|
|
82
|
+
if (status) process.exit(status);
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
main().catch((err) => {
|
|
88
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
89
|
+
process.exit(1);
|
|
90
|
+
});
|
|
@@ -6,6 +6,7 @@ import { pathToFileURL } from 'url';
|
|
|
6
6
|
import { printBanner, printSection, paint, ANSI, createProgressDisplay, printComplete } from '../lib/theme';
|
|
7
7
|
import { promptSelect } from '../lib/prompt';
|
|
8
8
|
import { PublishedGameIntegrityError } from '../lib/published-game-integrity';
|
|
9
|
+
import { resolveAuraJsProjectRoot, resolveInvocationCwd, delegateToAuraJsCommand } from '../lib/aurajs-project';
|
|
9
10
|
import {
|
|
10
11
|
assertPublishedGameBinIntegrity,
|
|
11
12
|
buildPublishedGameLaunchEnv,
|
|
@@ -114,6 +115,27 @@ function resolveAuramaxxCommand(): string {
|
|
|
114
115
|
return process.platform === 'win32' ? 'auramaxx.cmd' : 'auramaxx';
|
|
115
116
|
}
|
|
116
117
|
|
|
118
|
+
function resolveInstalledGlobalAuramaxxVersion(): string | null {
|
|
119
|
+
try {
|
|
120
|
+
const root = execFileSync(resolveNpmCommand(), ['root', '-g'], {
|
|
121
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
122
|
+
encoding: 'utf8',
|
|
123
|
+
timeout: 30000,
|
|
124
|
+
}).trim();
|
|
125
|
+
if (!root) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
const packageJsonPath = join(root, 'auramaxx', 'package.json');
|
|
129
|
+
if (!existsSync(packageJsonPath)) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as { version?: unknown };
|
|
133
|
+
return typeof pkg.version === 'string' && pkg.version.trim().length > 0 ? pkg.version.trim() : null;
|
|
134
|
+
} catch {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
117
139
|
function normalizeRelativePath(pathLike: string): string {
|
|
118
140
|
return String(pathLike || '')
|
|
119
141
|
.trim()
|
|
@@ -212,12 +234,26 @@ async function promptUpgradeAuramaxx(expectedAurajsVersion: string): Promise<boo
|
|
|
212
234
|
|
|
213
235
|
function installLatestAuramaxx(): void {
|
|
214
236
|
console.log('');
|
|
215
|
-
console.log(` ${paint('
|
|
237
|
+
console.log(` ${paint('Reinstalling latest AuraMaxx...', ANSI.bold)}`);
|
|
216
238
|
console.log('');
|
|
239
|
+
try {
|
|
240
|
+
execFileSync(resolveNpmCommand(), ['uninstall', '-g', 'auramaxx'], {
|
|
241
|
+
stdio: 'inherit',
|
|
242
|
+
timeout: 120000,
|
|
243
|
+
});
|
|
244
|
+
} catch {
|
|
245
|
+
// Ignore missing-package uninstall failures and continue with a clean install.
|
|
246
|
+
}
|
|
217
247
|
execFileSync(resolveNpmCommand(), ['install', '-g', 'auramaxx@latest', '--foreground-scripts'], {
|
|
218
248
|
stdio: 'inherit',
|
|
219
|
-
timeout:
|
|
249
|
+
timeout: 180000,
|
|
220
250
|
});
|
|
251
|
+
|
|
252
|
+
const installedVersion = resolveInstalledGlobalAuramaxxVersion();
|
|
253
|
+
if (installedVersion) {
|
|
254
|
+
console.log('');
|
|
255
|
+
console.log(` ${paint(`Installed AuraMaxx ${installedVersion}`, ANSI.dim)}`);
|
|
256
|
+
}
|
|
221
257
|
}
|
|
222
258
|
|
|
223
259
|
function relaunchWithUpdatedAuramaxx(argv: string[]): never {
|
|
@@ -330,6 +366,12 @@ function describeForwardedCommand(command: string): string {
|
|
|
330
366
|
|
|
331
367
|
export async function main(argv: string[] = process.argv.slice(2)) {
|
|
332
368
|
const plan = buildPlayPlan(argv);
|
|
369
|
+
const invocationCwd = resolveInvocationCwd();
|
|
370
|
+
const auraJsProjectRoot = resolveAuraJsProjectRoot(invocationCwd);
|
|
371
|
+
|
|
372
|
+
if (!plan.name && auraJsProjectRoot) {
|
|
373
|
+
delegateToAuraJsCommand(['play', ...argv], auraJsProjectRoot);
|
|
374
|
+
}
|
|
333
375
|
|
|
334
376
|
if (plan.help || !plan.name) {
|
|
335
377
|
printBanner('PLAY');
|
|
@@ -400,7 +442,7 @@ if (import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
|
400
442
|
? updateError.message
|
|
401
443
|
: String(updateError),
|
|
402
444
|
);
|
|
403
|
-
console.error(' Manual fallback: npm install -g auramaxx@latest');
|
|
445
|
+
console.error(' Manual fallback: npm uninstall -g auramaxx && npm install -g auramaxx@latest');
|
|
404
446
|
process.exit(1);
|
|
405
447
|
}
|
|
406
448
|
})().catch((promptError) => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { execFileSync } from 'child_process';
|
|
2
2
|
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
4
5
|
import { printBanner, printSection, printStatus, paint, ANSI } from '../lib/theme';
|
|
5
6
|
import { promptInput, promptSelect } from '../lib/prompt';
|
|
6
7
|
|
|
@@ -19,6 +20,11 @@ interface ParsedArgs {
|
|
|
19
20
|
const SEMVER_RE = /^v?(\d+)\.(\d+)\.(\d+)(-[0-9A-Za-z-.]+)?$/;
|
|
20
21
|
const SCOPED_PACKAGE_RE = /^@[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._-]*$/;
|
|
21
22
|
const UNSCOPED_PACKAGE_RE = /^[a-z0-9][a-z0-9._-]*$/;
|
|
23
|
+
const COMMAND_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
24
|
+
const LOCAL_AURAJS_CLI = path.resolve(
|
|
25
|
+
COMMAND_DIR,
|
|
26
|
+
'../../../../../packages/aurascript/src/cli/src/cli.mjs',
|
|
27
|
+
);
|
|
22
28
|
|
|
23
29
|
function parseArgs(argv: string[]): ParsedArgs {
|
|
24
30
|
const parsed: ParsedArgs = {
|
|
@@ -100,6 +106,52 @@ function resolveInvocationCwd(): string {
|
|
|
100
106
|
return process.cwd();
|
|
101
107
|
}
|
|
102
108
|
|
|
109
|
+
function resolveAuraJsProjectRoot(startDir: string): string | null {
|
|
110
|
+
let current = path.resolve(startDir);
|
|
111
|
+
|
|
112
|
+
while (true) {
|
|
113
|
+
const auraConfigPath = path.join(current, 'aura.config.json');
|
|
114
|
+
const packageJsonPath = path.join(current, 'package.json');
|
|
115
|
+
if (existsSync(auraConfigPath) && existsSync(packageJsonPath)) {
|
|
116
|
+
return current;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const parent = path.dirname(current);
|
|
120
|
+
if (parent === current) break;
|
|
121
|
+
current = parent;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function delegateToAuraJsPublish(rawArgs: string[], projectRoot: string): never {
|
|
128
|
+
const auraArgs = ['publish', ...rawArgs];
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
if (existsSync(LOCAL_AURAJS_CLI)) {
|
|
132
|
+
execFileSync(process.execPath, [LOCAL_AURAJS_CLI, ...auraArgs], {
|
|
133
|
+
cwd: projectRoot,
|
|
134
|
+
stdio: 'inherit',
|
|
135
|
+
env: process.env,
|
|
136
|
+
});
|
|
137
|
+
} else {
|
|
138
|
+
execFileSync(
|
|
139
|
+
'npm',
|
|
140
|
+
['exec', '--yes', '--package', '@auraindustry/aurajs', '--', 'aura', ...auraArgs],
|
|
141
|
+
{
|
|
142
|
+
cwd: projectRoot,
|
|
143
|
+
stdio: 'inherit',
|
|
144
|
+
env: process.env,
|
|
145
|
+
},
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
process.exit(0);
|
|
149
|
+
} catch (error: unknown) {
|
|
150
|
+
const status = (error as { status?: number }).status;
|
|
151
|
+
process.exit(status || 1);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
103
155
|
function sanitizePackageSlug(value: string): string {
|
|
104
156
|
const compact = String(value || '')
|
|
105
157
|
.trim()
|
|
@@ -253,8 +305,15 @@ async function resolveVersion(options: {
|
|
|
253
305
|
}
|
|
254
306
|
|
|
255
307
|
async function main() {
|
|
256
|
-
const parsed = parseArgs(process.argv.slice(2));
|
|
257
308
|
const invocationCwd = resolveInvocationCwd();
|
|
309
|
+
const rawArgs = process.argv.slice(2);
|
|
310
|
+
const auraJsProjectRoot = resolveAuraJsProjectRoot(invocationCwd);
|
|
311
|
+
|
|
312
|
+
if (auraJsProjectRoot) {
|
|
313
|
+
delegateToAuraJsPublish(rawArgs, auraJsProjectRoot);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const parsed = parseArgs(rawArgs);
|
|
258
317
|
const packageJsonPath = path.join(invocationCwd, 'package.json');
|
|
259
318
|
|
|
260
319
|
if (parsed.help) {
|