@puzzmo/cli 1.0.37 → 1.0.39
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/lib/commands/game/create.js +187 -71
- package/lib/commands/game/create.js.map +1 -1
- package/lib/commands/upload.d.ts +1 -1
- package/lib/commands/upload.js +143 -64
- package/lib/commands/upload.js.map +1 -1
- package/lib/commands/validate.d.ts +1 -1
- package/lib/commands/validate.js +24 -31
- package/lib/commands/validate.js.map +1 -1
- package/lib/index.js +4 -8
- package/lib/index.js.map +1 -1
- package/lib/skills/runner.d.ts +2 -0
- package/lib/skills/runner.js +33 -0
- package/lib/skills/runner.js.map +1 -1
- package/lib/util/api.d.ts +8 -0
- package/lib/util/api.js +22 -3
- package/lib/util/api.js.map +1 -1
- package/lib/util/createGame.d.ts +13 -0
- package/lib/util/createGame.js +36 -0
- package/lib/util/createGame.js.map +1 -0
- package/lib/util/discoverGames.d.ts +25 -0
- package/lib/util/discoverGames.js +181 -0
- package/lib/util/discoverGames.js.map +1 -0
- package/lib/util/validatePuzzmoFile.d.ts +1 -1
- package/lib/util/validatePuzzmoFile.js +2 -2
- package/lib/util/validatePuzzmoFile.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/game/create.ts +186 -74
- package/src/commands/upload.ts +171 -61
- package/src/commands/validate.ts +23 -30
- package/src/index.ts +6 -8
- package/src/skills/runner.ts +35 -0
- package/src/util/api.ts +32 -9
- package/src/util/createGame.ts +60 -0
- package/src/util/discoverGames.ts +203 -0
- package/src/util/validatePuzzmoFile.ts +2 -2
- package/templates/minesweeper/README.md +13 -0
- package/templates/minesweeper/fixtures/puzzles/easy/9x9.json +16 -0
- package/templates/minesweeper/fixtures/puzzles/hard/16x16.json +46 -0
- package/templates/minesweeper/index.html +19 -0
- package/templates/minesweeper/package.json +17 -0
- package/templates/minesweeper/puzzmo.json +11 -0
- package/templates/minesweeper/src/appBundle.ts +122 -0
- package/templates/minesweeper/src/main.ts +236 -0
- package/templates/minesweeper/src/style.css +160 -0
- package/templates/minesweeper/tsconfig.json +14 -0
- package/templates/minesweeper/vite.config.ts +10 -0
package/lib/commands/upload.js
CHANGED
|
@@ -2,10 +2,12 @@ import { execSync } from "node:child_process";
|
|
|
2
2
|
import crypto from "node:crypto";
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
|
-
import
|
|
5
|
+
import * as p from "@clack/prompts";
|
|
6
|
+
import { GameNotFoundError, uploadFiles } from "../util/api.js";
|
|
6
7
|
import { getAPIURL, getToken } from "../util/config.js";
|
|
7
|
-
import {
|
|
8
|
-
|
|
8
|
+
import { createUserGame } from "../util/createGame.js";
|
|
9
|
+
import { discoverGames } from "../util/discoverGames.js";
|
|
10
|
+
/** Uploads game build artifacts to Puzzmo by discovering puzzmo.json files in `dir` */
|
|
9
11
|
export const upload = async (dir, options = {}) => {
|
|
10
12
|
const { verbose = false } = options;
|
|
11
13
|
const token = getToken();
|
|
@@ -13,70 +15,110 @@ export const upload = async (dir, options = {}) => {
|
|
|
13
15
|
console.error("Not logged in. Run `puzzmo login <token>` or set PUZZMO_TOKEN.");
|
|
14
16
|
process.exit(1);
|
|
15
17
|
}
|
|
16
|
-
const
|
|
17
|
-
if (!fs.existsSync(
|
|
18
|
+
const rootDir = path.resolve(dir);
|
|
19
|
+
if (!fs.existsSync(rootDir)) {
|
|
18
20
|
console.error(`Directory not found: ${dir}`);
|
|
19
21
|
process.exit(1);
|
|
20
22
|
}
|
|
21
|
-
const
|
|
22
|
-
if (!
|
|
23
|
-
console.error(`
|
|
24
|
-
process.exit(1);
|
|
25
|
-
}
|
|
26
|
-
// Require and validate puzzmo.json
|
|
27
|
-
const puzzmoJsonPath = path.join(distDir, "puzzmo.json");
|
|
28
|
-
if (!fs.existsSync(puzzmoJsonPath)) {
|
|
29
|
-
console.error(`Missing puzzmo.json in ${dir}`);
|
|
30
|
-
console.error("Every game upload must include a puzzmo.json file.");
|
|
31
|
-
process.exit(1);
|
|
32
|
-
}
|
|
33
|
-
let parsed;
|
|
34
|
-
try {
|
|
35
|
-
parsed = JSON.parse(fs.readFileSync(puzzmoJsonPath, "utf-8"));
|
|
36
|
-
}
|
|
37
|
-
catch (e) {
|
|
38
|
-
console.error(`Invalid puzzmo.json: ${e instanceof Error ? e.message : e}`);
|
|
39
|
-
process.exit(1);
|
|
40
|
-
}
|
|
41
|
-
const validation = await validatePuzzmoJson(parsed);
|
|
42
|
-
if (!validation.valid) {
|
|
43
|
-
console.error(`Invalid puzzmo.json:\n`);
|
|
44
|
-
for (const err of validation.errors)
|
|
45
|
-
console.error(` ${err}`);
|
|
23
|
+
const { games, errors: discoveryErrors } = await discoverGames(rootDir);
|
|
24
|
+
if (!games.length && !discoveryErrors.length) {
|
|
25
|
+
console.error(`No puzzmo.json files found under ${rootDir}`);
|
|
46
26
|
process.exit(1);
|
|
47
27
|
}
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
28
|
+
console.log(`Found ${games.length} game(s) under ${rootDir}`);
|
|
29
|
+
for (const game of games) {
|
|
30
|
+
console.log(` - ${game.puzzmoFile.game.slug} (${path.relative(rootDir, game.distDir) || "."})`);
|
|
31
|
+
}
|
|
32
|
+
if (discoveryErrors.length) {
|
|
33
|
+
console.log(`\n${discoveryErrors.length} puzzmo.json file(s) could not be loaded:`);
|
|
34
|
+
for (const err of discoveryErrors) {
|
|
35
|
+
console.log(` - ${err.slug ?? path.relative(rootDir, err.puzzmoJsonPath)}`);
|
|
36
|
+
for (const e of err.errors)
|
|
37
|
+
console.log(` ${e}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const sha = getGitSHA(rootDir) || hashGames(games);
|
|
41
|
+
const description = getGitMessage(rootDir);
|
|
42
|
+
const repoURL = getGitRepoURL(rootDir);
|
|
56
43
|
if (description)
|
|
57
|
-
console.log(
|
|
44
|
+
console.log(`\nMessage: ${description}`);
|
|
58
45
|
if (repoURL)
|
|
59
46
|
console.log(`Repo: ${repoURL}`);
|
|
60
|
-
console.log("");
|
|
61
|
-
let totalBytes = 0;
|
|
62
|
-
for (const file of files) {
|
|
63
|
-
const size = fs.statSync(file).size;
|
|
64
|
-
totalBytes += size;
|
|
65
|
-
const rel = path.relative(distDir, file);
|
|
66
|
-
console.log(` ${rel} (${formatBytes(size)})`);
|
|
67
|
-
}
|
|
68
47
|
const apiURL = getAPIURL();
|
|
69
48
|
const defaultURL = "https://api.puzzmo.com";
|
|
70
|
-
console.log(`\n${files.length} file(s), ${formatBytes(totalBytes)} total`);
|
|
71
49
|
if (apiURL !== defaultURL)
|
|
72
|
-
console.log(`
|
|
73
|
-
|
|
74
|
-
|
|
50
|
+
console.log(`API: ${apiURL}`);
|
|
51
|
+
const results = [];
|
|
52
|
+
for (const err of discoveryErrors) {
|
|
53
|
+
results.push({ ok: false, slug: err.slug ?? path.relative(rootDir, err.puzzmoJsonPath), error: err.errors.join("; ") });
|
|
54
|
+
}
|
|
55
|
+
for (let i = 0; i < games.length; i++) {
|
|
56
|
+
const game = games[i];
|
|
57
|
+
console.log(`\n[${i + 1}/${games.length}] Uploading ${game.puzzmoFile.game.slug}`);
|
|
58
|
+
try {
|
|
59
|
+
let result;
|
|
60
|
+
try {
|
|
61
|
+
result = await uploadOneGame(game, { token, sha, description, repoURL, verbose, rootDir });
|
|
62
|
+
}
|
|
63
|
+
catch (e) {
|
|
64
|
+
if (!(e instanceof GameNotFoundError))
|
|
65
|
+
throw e;
|
|
66
|
+
const created = await maybeCreateMissingGame(e, game, { teamAccessToken: token });
|
|
67
|
+
if (!created)
|
|
68
|
+
throw e;
|
|
69
|
+
result = await uploadOneGame(game, { token, sha, description, repoURL, verbose, rootDir });
|
|
70
|
+
}
|
|
71
|
+
results.push(result);
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
75
|
+
console.error(` Failed: ${message}`);
|
|
76
|
+
results.push({ ok: false, slug: game.puzzmoFile.game.slug, error: message });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
printReport(results);
|
|
80
|
+
const anyFailed = results.some((r) => !r.ok);
|
|
81
|
+
if (anyFailed)
|
|
82
|
+
process.exit(1);
|
|
83
|
+
};
|
|
84
|
+
/** Uploads a single discovered game; throws on failure */
|
|
85
|
+
const uploadOneGame = async (game, opts) => {
|
|
86
|
+
const { token, sha, description, repoURL, verbose, rootDir } = opts;
|
|
87
|
+
const { puzzmoFile, distDir } = game;
|
|
88
|
+
const gameSlug = puzzmoFile.game.slug;
|
|
89
|
+
const files = collectFiles(distDir);
|
|
90
|
+
if (!files.length)
|
|
91
|
+
throw new Error(`Dist folder is empty: ${distDir}`);
|
|
92
|
+
console.log(` Directory: ${path.relative(rootDir, distDir) || distDir}`);
|
|
93
|
+
let totalBytes = 0;
|
|
94
|
+
for (const file of files)
|
|
95
|
+
totalBytes += fs.statSync(file).size;
|
|
96
|
+
console.log(` ${files.length} file(s), ${formatBytes(totalBytes)} total (sha ${sha.slice(0, 8)})`);
|
|
75
97
|
const result = await uploadFiles(token, gameSlug, sha, files, distDir, puzzmoFile, (batch, totalBatches, uploaded) => {
|
|
76
|
-
console.log(`
|
|
98
|
+
console.log(` Batch ${batch}/${totalBatches} done (${uploaded} file(s) uploaded)`);
|
|
77
99
|
}, { verbose, description, repoURL });
|
|
78
|
-
console.log(
|
|
79
|
-
|
|
100
|
+
console.log(` Done - ${result.versionID}`);
|
|
101
|
+
return {
|
|
102
|
+
ok: true,
|
|
103
|
+
slug: gameSlug,
|
|
104
|
+
fileCount: files.length,
|
|
105
|
+
totalBytes,
|
|
106
|
+
versionID: result.versionID,
|
|
107
|
+
assetsBase: result.assetsBase,
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
/** Prints a final summary of every game's outcome */
|
|
111
|
+
const printReport = (results) => {
|
|
112
|
+
console.log(`\nUpload report (${results.length} game${results.length === 1 ? "" : "s"})`);
|
|
113
|
+
const successes = results.filter((r) => r.ok);
|
|
114
|
+
const failures = results.filter((r) => !r.ok);
|
|
115
|
+
for (const r of successes) {
|
|
116
|
+
console.log(` OK ${r.slug.padEnd(24)} ${formatBytes(r.totalBytes).padStart(8)} ${r.versionID}`);
|
|
117
|
+
}
|
|
118
|
+
for (const r of failures) {
|
|
119
|
+
console.log(` FAIL ${r.slug.padEnd(24)} ${r.error}`);
|
|
120
|
+
}
|
|
121
|
+
console.log(`\n${successes.length} succeeded, ${failures.length} failed`);
|
|
80
122
|
};
|
|
81
123
|
/** Collects all files in a directory recursively */
|
|
82
124
|
const collectFiles = (dir) => {
|
|
@@ -92,27 +134,27 @@ const collectFiles = (dir) => {
|
|
|
92
134
|
return files;
|
|
93
135
|
};
|
|
94
136
|
/** Tries to get the shortest unique git SHA, returns null if not in a git repo */
|
|
95
|
-
const getGitSHA = () => {
|
|
137
|
+
const getGitSHA = (cwd) => {
|
|
96
138
|
try {
|
|
97
|
-
return execSync("git rev-parse --short HEAD", { encoding: "utf-8" }).trim();
|
|
139
|
+
return execSync("git rev-parse --short HEAD", { encoding: "utf-8", cwd }).trim();
|
|
98
140
|
}
|
|
99
141
|
catch {
|
|
100
142
|
return null;
|
|
101
143
|
}
|
|
102
144
|
};
|
|
103
145
|
/** Gets the subject line of the latest commit, or null if not in a git repo */
|
|
104
|
-
const getGitMessage = () => {
|
|
146
|
+
const getGitMessage = (cwd) => {
|
|
105
147
|
try {
|
|
106
|
-
return execSync("git log -1 --pretty=%s", { encoding: "utf-8" }).trim() || null;
|
|
148
|
+
return execSync("git log -1 --pretty=%s", { encoding: "utf-8", cwd }).trim() || null;
|
|
107
149
|
}
|
|
108
150
|
catch {
|
|
109
151
|
return null;
|
|
110
152
|
}
|
|
111
153
|
};
|
|
112
154
|
/** Gets the origin remote URL normalized to https, or null if unavailable */
|
|
113
|
-
const getGitRepoURL = () => {
|
|
155
|
+
const getGitRepoURL = (cwd) => {
|
|
114
156
|
try {
|
|
115
|
-
const raw = execSync("git config --get remote.origin.url", { encoding: "utf-8" }).trim();
|
|
157
|
+
const raw = execSync("git config --get remote.origin.url", { encoding: "utf-8", cwd }).trim();
|
|
116
158
|
return raw ? normalizeRepoURL(raw) : null;
|
|
117
159
|
}
|
|
118
160
|
catch {
|
|
@@ -134,14 +176,51 @@ const normalizeRepoURL = (url) => {
|
|
|
134
176
|
normalized = normalized.replace(/^git:\/\//, "https://");
|
|
135
177
|
return normalized.replace(/\.git$/, "");
|
|
136
178
|
};
|
|
137
|
-
/** Hashes
|
|
138
|
-
const
|
|
179
|
+
/** Hashes the dist contents of every game to produce a deterministic SHA across all uploads */
|
|
180
|
+
const hashGames = (games) => {
|
|
139
181
|
const hash = crypto.createHash("sha256");
|
|
140
|
-
for (const
|
|
141
|
-
|
|
182
|
+
for (const game of games) {
|
|
183
|
+
for (const file of collectFiles(game.distDir).sort()) {
|
|
184
|
+
hash.update(file);
|
|
185
|
+
hash.update(fs.readFileSync(file));
|
|
186
|
+
}
|
|
142
187
|
}
|
|
143
188
|
return hash.digest("hex").slice(0, 12);
|
|
144
189
|
};
|
|
190
|
+
/**
|
|
191
|
+
* When a game can't be uploaded because it doesn't exist on the user's account,
|
|
192
|
+
* offer to create it interactively. Returns true if the game was created and the
|
|
193
|
+
* caller can retry the upload. Returns false otherwise (non-interactive shell or
|
|
194
|
+
* user declined).
|
|
195
|
+
*/
|
|
196
|
+
const maybeCreateMissingGame = async (err, game, opts) => {
|
|
197
|
+
const slug = err.slug;
|
|
198
|
+
const displayName = game.puzzmoFile.game.displayName;
|
|
199
|
+
if (!process.stdin.isTTY) {
|
|
200
|
+
console.error(` Game "${slug}" not found on your account. Re-run interactively to create it.`);
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
const consent = await p.confirm({
|
|
204
|
+
message: `Game "${slug}" doesn't exist on your account. Create it now (displayName: "${displayName}")?`,
|
|
205
|
+
initialValue: true,
|
|
206
|
+
});
|
|
207
|
+
if (p.isCancel(consent) || !consent)
|
|
208
|
+
return false;
|
|
209
|
+
try {
|
|
210
|
+
const created = await createUserGame({ displayName, teamAccessToken: opts.teamAccessToken });
|
|
211
|
+
console.log(` Created game ${created.slug} (${created.id})`);
|
|
212
|
+
if (created.slug !== slug) {
|
|
213
|
+
console.warn(` Server picked slug "${created.slug}" but your puzzmo.json uses "${slug}". Update puzzmo.json before re-uploading.`);
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
catch (e) {
|
|
219
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
220
|
+
console.error(` Could not create game: ${message}`);
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
};
|
|
145
224
|
/** Formats a byte count as a human-readable string */
|
|
146
225
|
const formatBytes = (bytes) => {
|
|
147
226
|
if (bytes < 1024)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/** CLI command: puzzmo validate [dir] */
|
|
1
|
+
/** CLI command: puzzmo validate [dir] — discovers every puzzmo.json under dir and validates each */
|
|
2
2
|
export declare const validate: (dir: string) => Promise<void>;
|
package/lib/commands/validate.js
CHANGED
|
@@ -1,43 +1,36 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import {
|
|
4
|
-
/** CLI command: puzzmo validate [dir] */
|
|
3
|
+
import { discoverGames } from "../util/discoverGames.js";
|
|
4
|
+
/** CLI command: puzzmo validate [dir] — discovers every puzzmo.json under dir and validates each */
|
|
5
5
|
export const validate = async (dir) => {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
console.error(`No puzzmo.json found in ${dir}`);
|
|
6
|
+
const rootDir = path.resolve(dir);
|
|
7
|
+
if (!fs.existsSync(rootDir)) {
|
|
8
|
+
console.error(`Directory not found: ${dir}`);
|
|
10
9
|
process.exit(1);
|
|
11
10
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
catch (e) {
|
|
17
|
-
console.error(`Could not read puzzmo.json: ${e instanceof Error ? e.message : e}`);
|
|
11
|
+
const { games, errors } = await discoverGames(rootDir);
|
|
12
|
+
if (!games.length && !errors.length) {
|
|
13
|
+
console.error(`No puzzmo.json files found under ${rootDir}`);
|
|
18
14
|
process.exit(1);
|
|
19
15
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
for (const game of games) {
|
|
17
|
+
const rel = path.relative(rootDir, game.puzzmoJsonPath) || game.puzzmoJsonPath;
|
|
18
|
+
const integrations = game.puzzmoFile.integrations ? Object.keys(game.puzzmoFile.integrations) : [];
|
|
19
|
+
const distRel = path.relative(rootDir, game.distDir) || game.distDir;
|
|
20
|
+
console.log(`OK ${game.puzzmoFile.game.slug.padEnd(24)} (${rel})`);
|
|
21
|
+
console.log(` dist: ${distRel}`);
|
|
22
|
+
if (integrations.length)
|
|
23
|
+
console.log(` integrations: ${integrations.join(", ")}`);
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
for (const err of errors) {
|
|
26
|
+
const rel = path.relative(rootDir, err.puzzmoJsonPath) || err.puzzmoJsonPath;
|
|
27
|
+
const label = err.slug ?? rel;
|
|
28
|
+
console.error(`FAIL ${label.padEnd(24)} (${rel})`);
|
|
29
|
+
for (const e of err.errors)
|
|
30
|
+
console.error(` ${e}`);
|
|
27
31
|
}
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
console.error(`puzzmo.json has ${result.errors.length} error(s):\n`);
|
|
31
|
-
for (const err of result.errors)
|
|
32
|
-
console.error(` ${err}`);
|
|
32
|
+
console.log(`\n${games.length} valid, ${errors.length} invalid`);
|
|
33
|
+
if (errors.length)
|
|
33
34
|
process.exit(1);
|
|
34
|
-
}
|
|
35
|
-
const { data: puzzmoFile } = result;
|
|
36
|
-
console.log(`Valid puzzmo.json for "${puzzmoFile.game.displayName}" (${puzzmoFile.game.slug})`);
|
|
37
|
-
if (puzzmoFile.integrations) {
|
|
38
|
-
const keys = Object.keys(puzzmoFile.integrations);
|
|
39
|
-
if (keys.length)
|
|
40
|
-
console.log(`Integrations: ${keys.join(", ")}`);
|
|
41
|
-
}
|
|
42
35
|
};
|
|
43
36
|
//# sourceMappingURL=validate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAExD,sGAAoG;AACpG,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,EAAE,GAAW,EAAE,EAAE,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACjC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAA;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,CAAA;IAEtD,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACpC,OAAO,CAAC,KAAK,CAAC,oCAAoC,OAAO,EAAE,CAAC,CAAA;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,cAAc,CAAA;QAC9E,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAClG,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAA;QACpE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,CAAA;QACpE,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,EAAE,CAAC,CAAA;QACpC,IAAI,YAAY,CAAC,MAAM;YAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACvF,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,cAAc,CAAA;QAC5E,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAA;QAC7B,OAAO,CAAC,KAAK,CAAC,QAAQ,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,CAAA;QAClD,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM;YAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IACxD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,WAAW,MAAM,CAAC,MAAM,UAAU,CAAC,CAAA;IAChE,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAAA,CACnC,CAAA"}
|
package/lib/index.js
CHANGED
|
@@ -11,8 +11,8 @@ const printUsage = () => {
|
|
|
11
11
|
puzzmo login <token> Save a CLI auth token
|
|
12
12
|
puzzmo game create [token] Create a new Puzzmo game project
|
|
13
13
|
|
|
14
|
-
puzzmo upload
|
|
15
|
-
puzzmo validate [dir]
|
|
14
|
+
puzzmo upload [dir] [-v] Discover puzzmo.json files in [dir] (default: .) and upload each game's build. -v/--verbose prints request URLs and full error bodies. If a game does not exist on your account and stdin is a TTY, you'll be asked whether to create it (using your saved CLI token).
|
|
15
|
+
puzzmo validate [dir] Discover and validate every puzzmo.json under [dir] (default: .)
|
|
16
16
|
puzzmo migrate List and select migration skills from dev.puzzmo.com`);
|
|
17
17
|
};
|
|
18
18
|
const run = async () => {
|
|
@@ -28,11 +28,7 @@ const run = async () => {
|
|
|
28
28
|
}
|
|
29
29
|
case "upload": {
|
|
30
30
|
const verbose = args.includes("--verbose") || args.includes("-v");
|
|
31
|
-
const dir = args.find((a) => !a.startsWith("-"));
|
|
32
|
-
if (!dir) {
|
|
33
|
-
console.error("Usage: puzzmo upload <dir> [-v|--verbose]");
|
|
34
|
-
process.exit(1);
|
|
35
|
-
}
|
|
31
|
+
const dir = args.find((a) => !a.startsWith("-")) ?? ".";
|
|
36
32
|
await upload(dir, { verbose });
|
|
37
33
|
break;
|
|
38
34
|
}
|
|
@@ -42,7 +38,7 @@ const run = async () => {
|
|
|
42
38
|
await gameCreate(subArgs);
|
|
43
39
|
}
|
|
44
40
|
else {
|
|
45
|
-
console.error("Usage: puzzmo game create [
|
|
41
|
+
console.error("Usage: puzzmo game create [--strategy <import|blank|prompt>] [--prompt <text>] [--name <name>] [--url <url>] [--agent <agent>] [--token <token>] [--pm <npm|yarn|pnpm>]");
|
|
46
42
|
process.exit(1);
|
|
47
43
|
}
|
|
48
44
|
break;
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAE/C,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AAEhD,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC;IACvB,OAAO,CAAC,GAAG,CAAC;;;;;;uFAMyE,CAAC,CAAA;AAAA,CACvF,CAAA;AAED,MAAM,GAAG,GAAG,KAAK,IAAI,EAAE,CAAC;IACtB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,OAAO,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;YACrB,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAA;gBAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;YACD,KAAK,CAAC,KAAK,CAAC,CAAA;YACZ,MAAK;QACP,CAAC;QACD,KAAK,QAAQ,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;YACjE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/skills/runner.d.ts
CHANGED
|
@@ -2,3 +2,5 @@
|
|
|
2
2
|
export declare const runSkillsPipeline: (agent: string, gameDir: string, repoContext: string) => Promise<void>;
|
|
3
3
|
/** Runs the skills pipeline with a split-pane TUI */
|
|
4
4
|
export declare const runSkillsPipelineTUI: (agent: string, gameDir: string, repoContext: string) => Promise<void>;
|
|
5
|
+
/** Runs a single agent invocation, verifies the build, and commits. Used by one-shot prompt-driven flows. */
|
|
6
|
+
export declare const runAgentWithBuildLoop: (agent: string, prompt: string, gameDir: string, label: string) => boolean;
|
package/lib/skills/runner.js
CHANGED
|
@@ -70,4 +70,37 @@ export const runSkillsPipeline = async (agent, gameDir, repoContext) => {
|
|
|
70
70
|
export const runSkillsPipelineTUI = async (agent, gameDir, repoContext) => {
|
|
71
71
|
await runPipelineTUI(agent, gameDir, repoContext);
|
|
72
72
|
};
|
|
73
|
+
/** Runs a single agent invocation, verifies the build, and commits. Used by one-shot prompt-driven flows. */
|
|
74
|
+
export const runAgentWithBuildLoop = (agent, prompt, gameDir, label) => {
|
|
75
|
+
console.log(`Running agent: ${label}`);
|
|
76
|
+
let result = invokeAgent(agent, prompt, gameDir);
|
|
77
|
+
if (!result.success) {
|
|
78
|
+
console.log(` Agent failed, retrying...`);
|
|
79
|
+
result = invokeAgent(agent, prompt, gameDir);
|
|
80
|
+
if (!result.success) {
|
|
81
|
+
console.error(` Agent failed after retry. Stopping.`);
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const buildResult = verifyBuild(gameDir);
|
|
86
|
+
if (!buildResult.success) {
|
|
87
|
+
console.log(` Build failed, asking agent to fix...`);
|
|
88
|
+
const fixPrompt = `The vite build failed after the "${label}" step. Fix the build errors:\n\n${buildResult.error}`;
|
|
89
|
+
invokeAgent(agent, fixPrompt, gameDir);
|
|
90
|
+
const retry = verifyBuild(gameDir);
|
|
91
|
+
if (!retry.success) {
|
|
92
|
+
console.error(` Build still failing after fix attempt.`);
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
runCommand("git add -A", { cwd: gameDir });
|
|
98
|
+
gitCommit(`step: ${label}`, { cwd: gameDir });
|
|
99
|
+
console.log(` Committed.`);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
console.log(` No changes to commit.`);
|
|
103
|
+
}
|
|
104
|
+
return true;
|
|
105
|
+
};
|
|
73
106
|
//# sourceMappingURL=runner.js.map
|
package/lib/skills/runner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/skills/runner.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/skills/runner.ts"],"names":[],"mappings":"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"}
|
package/lib/util/api.d.ts
CHANGED
|
@@ -6,7 +6,15 @@ export type PuzzmoFile = {
|
|
|
6
6
|
teamID: string;
|
|
7
7
|
};
|
|
8
8
|
integrations?: Record<string, unknown>;
|
|
9
|
+
output?: {
|
|
10
|
+
dir: string;
|
|
11
|
+
};
|
|
9
12
|
};
|
|
13
|
+
/** Thrown when /cliUpload init returns a 404 because the game slug isn't registered yet. */
|
|
14
|
+
export declare class GameNotFoundError extends Error {
|
|
15
|
+
readonly slug: string;
|
|
16
|
+
constructor(slug: string, message: string);
|
|
17
|
+
}
|
|
10
18
|
type CompleteResponse = {
|
|
11
19
|
assetsBase: string;
|
|
12
20
|
versionID: string;
|
package/lib/util/api.js
CHANGED
|
@@ -2,6 +2,15 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { getAPIURL } from "./config.js";
|
|
4
4
|
const BATCH_SIZE = 10;
|
|
5
|
+
/** Thrown when /cliUpload init returns a 404 because the game slug isn't registered yet. */
|
|
6
|
+
export class GameNotFoundError extends Error {
|
|
7
|
+
slug;
|
|
8
|
+
constructor(slug, message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.slug = slug;
|
|
11
|
+
this.name = "GameNotFoundError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
5
14
|
/** Wraps fetch to surface the underlying network cause (DNS, ECONNREFUSED, TLS, etc.) */
|
|
6
15
|
const fetchWithContext = async (url, init, step, verbose) => {
|
|
7
16
|
if (verbose)
|
|
@@ -35,9 +44,11 @@ const readResponse = async (res, url, step, verbose) => {
|
|
|
35
44
|
throw new Error(`Invalid JSON response during ${step} (${url}): ${verbose ? text : text.slice(0, 200)}`);
|
|
36
45
|
}
|
|
37
46
|
if (!res.ok) {
|
|
38
|
-
const
|
|
47
|
+
const body = json;
|
|
48
|
+
const serverMsg = body.error || res.statusText || "Unknown error";
|
|
49
|
+
const validation = body.validationErrors?.length ? `\n - ${body.validationErrors.join("\n - ")}` : "";
|
|
39
50
|
const detail = verbose ? `\n${JSON.stringify(json, null, 2)}` : "";
|
|
40
|
-
throw new Error(`Server error during ${step} (${res.status} from ${url}): ${serverMsg}${detail}`);
|
|
51
|
+
throw new Error(`Server error during ${step} (${res.status} from ${url}): ${serverMsg}${validation}${detail}`);
|
|
41
52
|
}
|
|
42
53
|
return json;
|
|
43
54
|
};
|
|
@@ -73,7 +84,15 @@ export const uploadFiles = async (token, gameSlug, sha, filePaths, baseDir, puzz
|
|
|
73
84
|
if (verbose)
|
|
74
85
|
console.log(` API URL: ${apiURL}`);
|
|
75
86
|
// Step 1: Init session (includes puzzmo.json metadata)
|
|
76
|
-
|
|
87
|
+
let init;
|
|
88
|
+
try {
|
|
89
|
+
init = (await jsonPost(`${apiURL}/cliUpload`, token, { gameSlug, sha, puzzmoFile, description, repoURL }, "upload init", verbose));
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
if (e instanceof Error && e.message.includes("Game not found:"))
|
|
93
|
+
throw new GameNotFoundError(gameSlug, e.message);
|
|
94
|
+
throw e;
|
|
95
|
+
}
|
|
77
96
|
if (verbose)
|
|
78
97
|
console.log(` session: ${init.sessionID}`);
|
|
79
98
|
// Step 2: Upload files in concurrent batches
|
package/lib/util/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/util/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/util/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type CreateUserGameOptions = {
|
|
2
|
+
/** A teamAccessToken (the same token saved by `puzzmo login`). The mutation uses it to identify the team. */
|
|
3
|
+
teamAccessToken: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
};
|
|
6
|
+
export type CreatedGame = {
|
|
7
|
+
id: string;
|
|
8
|
+
slug: string;
|
|
9
|
+
displayName: string;
|
|
10
|
+
newAccessToken: string | null;
|
|
11
|
+
};
|
|
12
|
+
/** Calls the createUserGame mutation using a teamAccessToken for auth. */
|
|
13
|
+
export declare const createUserGame: (options: CreateUserGameOptions) => Promise<CreatedGame>;
|