phewsh 0.15.78 → 0.15.79

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.
Files changed (2) hide show
  1. package/commands/serve.js +36 -2
  2. package/package.json +1 -1
package/commands/serve.js CHANGED
@@ -12,7 +12,7 @@
12
12
  // phewsh serve --port 8080 Start on custom port
13
13
 
14
14
  const http = require('http');
15
- const { execSync, spawn } = require('child_process');
15
+ const { execFileSync, spawn } = require('child_process');
16
16
  const crypto = require('crypto');
17
17
  const os = require('os');
18
18
  const path = require('path');
@@ -35,6 +35,18 @@ function getPort() {
35
35
  return 7483;
36
36
  }
37
37
 
38
+ // The project this worker serves = the directory it was started in. The
39
+ // normalized origin remote is the identity the claim path already verifies
40
+ // against (task.js repo-match); name alone is display, remote is truth.
41
+ function currentProject() {
42
+ let remote = null;
43
+ try {
44
+ remote = execFileSync('git', ['remote', 'get-url', 'origin'], { stdio: ['ignore', 'pipe', 'ignore'] })
45
+ .toString().trim() || null;
46
+ } catch { /* not a git repo, or no origin — worker still serves the directory */ }
47
+ return { name: path.basename(process.cwd()), remote };
48
+ }
49
+
38
50
  // ─── Runtime Detection ─────────────────────────────────────────────────────
39
51
 
40
52
  // Harness runners — shared table in lib/harnesses.js. PHEWSH is not a
@@ -245,10 +257,12 @@ function main() {
245
257
  return;
246
258
  }
247
259
 
248
- // Health check
260
+ // Health check — includes which project this worker is serving, so the
261
+ // web can say "worker online — <project>" instead of an anonymous dot.
249
262
  if (url.pathname === '/health' && req.method === 'GET') {
250
263
  return json(req, res, {
251
264
  status: 'ok',
265
+ project: currentProject(),
252
266
  runtimes: detectRuntimes(),
253
267
  version: require('../package.json').version,
254
268
  uptime: process.uptime(),
@@ -351,6 +365,26 @@ function main() {
351
365
 
352
366
  const server = http.createServer(handleRequest);
353
367
 
368
+ // One worker per machine (per port) for now. A second `phewsh serve` used to
369
+ // die with a raw EADDRINUSE stack — say what's true and how to proceed instead.
370
+ server.on('error', (err) => {
371
+ if (err.code === 'EADDRINUSE') {
372
+ console.log('');
373
+ console.log(` ${yellow('●')} A phewsh worker is already running on port ${port}.`);
374
+ console.log('');
375
+ console.log(` ${g('One worker per machine for now — the running worker serves the project')}`);
376
+ console.log(` ${g('directory it was started in. To serve a different project:')}`);
377
+ console.log(` ${g('· stop the other worker (Ctrl+C) and start this one, or')}`);
378
+ console.log(` ${g('· run on another port:')} ${w(`phewsh serve --port ${port + 1}`)}`);
379
+ console.log(` ${g('(note: phewsh.com currently discovers port 7483 only)')}`);
380
+ console.log('');
381
+ console.log(` ${g('A one-worker-many-projects registry is the planned next step.')}`);
382
+ console.log('');
383
+ process.exit(1);
384
+ }
385
+ throw err;
386
+ });
387
+
354
388
  server.listen(port, '127.0.0.1', () => {
355
389
  const mirror = http.createServer(handleRequest);
356
390
  mirror.on('error', () => { /* IPv6 unavailable or already bound */ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phewsh",
3
- "version": "0.15.78",
3
+ "version": "0.15.79",
4
4
  "description": "One mission. Many AI tools. No lost context. PHEWSH keeps your project's intent, decisions, and working context aligned across Claude Code, Codex, Cursor, Gemini and your team — so the next AI knows what the last one learned.",
5
5
  "bin": {
6
6
  "phewsh": "bin/phewsh.js"