castle-web-cli 0.4.5 → 0.4.6
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/index.js +4 -1
- package/dist/init.d.ts +2 -1
- package/dist/init.js +27 -3
- package/dist/serve.js +4 -1
- package/kits/basic-2d/CLAUDE.md +4 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25,6 +25,9 @@ function getFlagValue(flag) {
|
|
|
25
25
|
const idx = args.indexOf(flag);
|
|
26
26
|
return idx >= 0 ? args[idx + 1] : undefined;
|
|
27
27
|
}
|
|
28
|
+
function hasFlag(flag) {
|
|
29
|
+
return args.includes(flag);
|
|
30
|
+
}
|
|
28
31
|
function readServeWsPort(dir) {
|
|
29
32
|
try {
|
|
30
33
|
const serveJson = JSON.parse(fs.readFileSync(path.join(path.resolve(dir), '.castle', 'serve.json'), 'utf-8'));
|
|
@@ -70,7 +73,7 @@ async function main() {
|
|
|
70
73
|
process.exit(1);
|
|
71
74
|
}
|
|
72
75
|
const kit = getFlagValue('--kit');
|
|
73
|
-
init(dir, { kit });
|
|
76
|
+
await init(dir, { kit, serve: !hasFlag('--no-serve') });
|
|
74
77
|
break;
|
|
75
78
|
}
|
|
76
79
|
case 'serve': {
|
package/dist/init.d.ts
CHANGED
package/dist/init.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
1
2
|
import * as fs from 'fs';
|
|
2
3
|
import * as path from 'path';
|
|
3
4
|
import { getCliEntryPath, getKitsDir, getRepoRoot, getSdkPackagePath, toPosixPath } from './localPaths.js';
|
|
5
|
+
import { serve } from './serve.js';
|
|
4
6
|
const INDEX_HTML = `<!DOCTYPE html>
|
|
5
7
|
<html>
|
|
6
8
|
<head>
|
|
@@ -187,7 +189,7 @@ function scaffoldFromKit(kit, projectDir) {
|
|
|
187
189
|
}
|
|
188
190
|
ensureAgentsSymlink(projectDir);
|
|
189
191
|
}
|
|
190
|
-
export function init(dir, opts = {}) {
|
|
192
|
+
export async function init(dir, opts = {}) {
|
|
191
193
|
const projectDir = path.resolve(dir);
|
|
192
194
|
if (fs.existsSync(projectDir) && fs.readdirSync(projectDir).length > 0) {
|
|
193
195
|
console.error(`Directory "${dir}" is not empty.`);
|
|
@@ -202,10 +204,32 @@ export function init(dir, opts = {}) {
|
|
|
202
204
|
scaffoldFromKit(kit, projectDir);
|
|
203
205
|
}
|
|
204
206
|
console.log(`Created project in ${projectDir}/${bare ? '' : ` (from kit "${kit}")`}`);
|
|
207
|
+
// Auto-run npm install + serve so the page is up the moment the
|
|
208
|
+
// agent / user starts editing. Pass --no-serve to skip.
|
|
209
|
+
const autoServe = opts.serve !== false;
|
|
210
|
+
if (autoServe) {
|
|
211
|
+
console.log('');
|
|
212
|
+
console.log('Installing deps + serving (pass --no-serve to skip)...');
|
|
213
|
+
try {
|
|
214
|
+
execSync('npm install --no-audit --no-fund --loglevel=error', {
|
|
215
|
+
cwd: projectDir,
|
|
216
|
+
stdio: 'inherit',
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
console.error('npm install failed; skipping serve. Re-run yourself with `npm install && castle-web serve .` (& in your shell to background it).');
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
// Call serve() with detach so init returns once the server is up. serve()
|
|
224
|
+
// handles the background spawn internally; init doesn't shell out.
|
|
225
|
+
// Bind all interfaces by default so a tailnet / LAN browser can reach
|
|
226
|
+
// the served page; users can override host on a subsequent serve call.
|
|
227
|
+
await serve(projectDir, { host: '0.0.0.0', detach: true });
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
205
230
|
console.log('');
|
|
206
231
|
console.log('Next steps:');
|
|
207
232
|
console.log(` cd ${dir}`);
|
|
208
233
|
console.log(' npm install');
|
|
209
|
-
console.log('
|
|
210
|
-
console.log(' npm run save-deck');
|
|
234
|
+
console.log(' castle-web serve . # & in your shell to background it');
|
|
211
235
|
}
|
package/dist/serve.js
CHANGED
|
@@ -84,7 +84,10 @@ export async function serve(dir, options = {}) {
|
|
|
84
84
|
console.error(`No index.html found in ${projectDir}`);
|
|
85
85
|
process.exit(1);
|
|
86
86
|
}
|
|
87
|
-
|
|
87
|
+
// --detach is kept for back-compat. Agent evals (and any harness running
|
|
88
|
+
// castle-web in a context that can't manage a foreground process) should
|
|
89
|
+
// prefer the CASTLE_WEB_CLI_DETACH=1 env var instead.
|
|
90
|
+
if (options.detach || process.env.CASTLE_WEB_CLI_DETACH === '1') {
|
|
88
91
|
await serveDetached(projectDir, options);
|
|
89
92
|
return;
|
|
90
93
|
}
|
package/kits/basic-2d/CLAUDE.md
CHANGED
|
@@ -12,9 +12,10 @@ Write the smallest game that satisfies what the user asked for. No sound, partic
|
|
|
12
12
|
|
|
13
13
|
## Workflow
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
The deck is already serving when you start (`castle-web init` set that up; see `.castle/serve.json` for the URL). The user is watching that page right now. Your job is to make it interesting incrementally:
|
|
16
|
+
|
|
17
|
+
1. **Build incrementally.** Start with the smallest playable thing (one mechanic, one scene change), `npm run restart`, then add the next piece. Do NOT write the whole game in one shot.
|
|
18
|
+
2. **After every edit:** `npm run restart` (no hot reload). The served page refreshes and the user sees the change.
|
|
18
19
|
|
|
19
20
|
Card size is **500 wide × 700 tall** (origin top-left, +y is down).
|
|
20
21
|
|