castle-web-cli 0.4.10 → 0.4.11
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/init.js +0 -1
- package/dist/serve.js +44 -0
- package/kits/basic-2d/package.json +0 -1
- package/package.json +1 -1
package/dist/init.js
CHANGED
|
@@ -70,7 +70,6 @@ function makePackageJson(projectDir) {
|
|
|
70
70
|
private: true,
|
|
71
71
|
type: 'module',
|
|
72
72
|
scripts: {
|
|
73
|
-
serve: `node ${cliEntry} serve . --open`,
|
|
74
73
|
restart: `node ${cliEntry} restart .`,
|
|
75
74
|
screenshot: `node ${cliEntry} screenshot .`,
|
|
76
75
|
'save-deck': `node ${cliEntry} save-deck .`,
|
package/dist/serve.js
CHANGED
|
@@ -74,6 +74,38 @@ function readDeckContext(projectDir) {
|
|
|
74
74
|
}
|
|
75
75
|
const DEFAULT_PORT = 5757;
|
|
76
76
|
const SCREENSHOT_REQUEST_TTL_MS = 15_000;
|
|
77
|
+
function readServeJson(projectDir) {
|
|
78
|
+
try {
|
|
79
|
+
const raw = fs.readFileSync(path.join(projectDir, '.castle', 'serve.json'), 'utf8');
|
|
80
|
+
const info = JSON.parse(raw);
|
|
81
|
+
if (typeof info.port !== 'number' || typeof info.wsPort !== 'number' || typeof info.pid !== 'number')
|
|
82
|
+
return null;
|
|
83
|
+
return { port: info.port, wsPort: info.wsPort, pid: info.pid };
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function isPidAlive(pid) {
|
|
90
|
+
try {
|
|
91
|
+
process.kill(pid, 0);
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Return the live serve already owning this deck, if any. Lets repeated
|
|
99
|
+
// `castle-web serve`/`npm run serve` calls become idempotent instead of
|
|
100
|
+
// piling up independent vite instances on adjacent ports.
|
|
101
|
+
function existingServe(projectDir) {
|
|
102
|
+
const info = readServeJson(projectDir);
|
|
103
|
+
if (!info)
|
|
104
|
+
return null;
|
|
105
|
+
if (!isPidAlive(info.pid))
|
|
106
|
+
return null;
|
|
107
|
+
return info;
|
|
108
|
+
}
|
|
77
109
|
export async function serve(dir, options = {}) {
|
|
78
110
|
const projectDir = path.resolve(dir);
|
|
79
111
|
if (!fs.existsSync(projectDir)) {
|
|
@@ -84,6 +116,18 @@ export async function serve(dir, options = {}) {
|
|
|
84
116
|
console.error(`No index.html found in ${projectDir}`);
|
|
85
117
|
process.exit(1);
|
|
86
118
|
}
|
|
119
|
+
// If a live serve is already running for this deck, reuse it. Skip the
|
|
120
|
+
// dedup when --port / --host are passed (caller wants those specifics, so
|
|
121
|
+
// start a fresh serve even if another is up).
|
|
122
|
+
if (!options.port && !options.host) {
|
|
123
|
+
const existing = existingServe(projectDir);
|
|
124
|
+
if (existing) {
|
|
125
|
+
console.log(`Serve already running for ${projectDir}`);
|
|
126
|
+
console.log(`URL: http://localhost:${existing.port}`);
|
|
127
|
+
console.log(`PID: ${existing.pid}`);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
87
131
|
// --detach is kept for back-compat. Agent evals (and any harness running
|
|
88
132
|
// castle-web in a context that can't manage a foreground process) should
|
|
89
133
|
// prefer the CASTLE_WEB_CLI_DETACH=1 env var instead.
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
"private": true,
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
|
-
"serve": "node ../../cli/dist/index.js serve . --open",
|
|
7
6
|
"restart": "node ../../cli/dist/index.js restart .",
|
|
8
7
|
"screenshot": "node ../../cli/dist/index.js screenshot .",
|
|
9
8
|
"check": "eslint . && jscpd && node --input-type=module -e \"const { bundleProject } = await import('../../cli/dist/bundle.js'); await bundleProject('.');\""
|