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 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('.');\""
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "castle-web-cli",
3
- "version": "0.4.10",
3
+ "version": "0.4.11",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "castle-web": "./dist/index.js"