coxpit 2.1.0 → 2.1.2

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/README.md CHANGED
@@ -31,9 +31,13 @@ External tools are spawned, never vendored: `git`, `tmux`, your agent CLI. No ed
31
31
  Requirements: Node 20+, git, tmux, an agent CLI on PATH (e.g. `claude`).
32
32
 
33
33
  ```bash
34
+ # fastest — straight from npm
35
+ COXPIT_AUTH_DISABLED=1 npx coxpit # → http://127.0.0.1:8210
36
+
37
+ # or from source
34
38
  npm install
35
39
  cp .env.example .env # set COXPIT_AUTH_PASS (or COXPIT_AUTH_DISABLED=1 locally)
36
- npm run dev # → http://127.0.0.1:8210
40
+ npm run dev
37
41
  ```
38
42
 
39
43
  Open the board, register a repo (absolute path), write a task, hit **Run fleet**.
package/bin/coxpit.js CHANGED
@@ -2,13 +2,50 @@
2
2
  // coxpit CLI — boots the daemon. Ships TS sources and runs them via tsx
3
3
  // (no build step, no ESM extension rewrites).
4
4
  import { spawn } from 'node:child_process';
5
- import { fileURLToPath } from 'node:url';
5
+ import { createRequire } from 'node:module';
6
+ import { fileURLToPath, pathToFileURL } from 'node:url';
6
7
  import { dirname, join } from 'node:path';
8
+ import { readFileSync } from 'node:fs';
7
9
 
8
10
  const root = dirname(dirname(fileURLToPath(import.meta.url)));
9
11
  const entry = join(root, 'src', 'index.ts');
10
12
 
11
- const child = spawn(process.execPath, ['--import', 'tsx', entry, ...process.argv.slice(2)], {
13
+ const args = process.argv.slice(2);
14
+
15
+ if (args.includes('--version') || args.includes('-v')) {
16
+ const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
17
+ console.log(pkg.version);
18
+ process.exit(0);
19
+ }
20
+
21
+ if (args.includes('--help') || args.includes('-h')) {
22
+ console.log(`coxpit — self-hosted cockpit for a fleet of AI coding agents
23
+
24
+ Usage:
25
+ coxpit start the daemon (board at http://<host>:<port>)
26
+ coxpit --version, -v print version
27
+ coxpit --help, -h show this help
28
+
29
+ Configuration is env-only (a .env file in the cwd is loaded):
30
+ COXPIT_HOST bind host (default 127.0.0.1)
31
+ COXPIT_PORT bind port (default 8210)
32
+ COXPIT_DB SQLite (libSQL) file (default ./coxpit.db)
33
+ COXPIT_AUTH_USER basic auth user (default admin)
34
+ COXPIT_AUTH_PASS basic auth password (empty = open; set it)
35
+ COXPIT_AUTH_DISABLED 1 disables auth (local dev only)
36
+ COXPIT_SSH_KEY private key for remote machines (else ssh defaults/agent)
37
+ COXPIT_AGENT_REAL 1 = real agent CLI by default (credits!)
38
+ COXPIT_AGENT_BIN agent command (default claude)
39
+ COXPIT_AGENT_PERM headless permission mode (default acceptEdits)`);
40
+ process.exit(0);
41
+ }
42
+
43
+ // --import 의 bare 'tsx' 는 사용자 cwd 기준으로 해석돼 npx 실행에서 깨진다 —
44
+ // 패키지 루트 기준으로 절대경로 해석해 넘긴다.
45
+ const require_ = createRequire(join(root, 'package.json'));
46
+ const tsxEntry = pathToFileURL(require_.resolve('tsx')).href;
47
+
48
+ const child = spawn(process.execPath, ['--import', tsxEntry, entry, ...process.argv.slice(2)], {
12
49
  stdio: 'inherit',
13
50
  env: process.env,
14
51
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coxpit",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "description": "Self-hosted cockpit for running a fleet of AI coding agents across your own machines — parallel worktree runs, live board, compare & merge, web terminal, design capture.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/server.ts CHANGED
@@ -29,7 +29,7 @@ export async function buildServer(): Promise<FastifyInstance> {
29
29
  app.addHook('onRequest', authGate);
30
30
 
31
31
  // 무인증 헬스(외부 감시용)
32
- app.get('/api/health', async () => ({ ok: true, name: 'coxpit', version: '2.1.0' }));
32
+ app.get('/api/health', async () => ({ ok: true, name: 'coxpit', version: '2.1.2' }));
33
33
 
34
34
  // 플릿 보드(단일 페이지). 인증 게이트 적용됨.
35
35
  app.get('/', async (_req, reply) => reply.type('text/html').send(BOARD_HTML));
@@ -354,7 +354,7 @@ export async function buildServer(): Promise<FastifyInstance> {
354
354
  // 라이브 스트림 좌석 — 오케스트레이터가 run/event 를 여기로 broadcast.
355
355
  app.get('/ws', { websocket: true }, (socket) => {
356
356
  addSink(socket);
357
- socket.send(JSON.stringify({ type: 'hello', name: 'coxpit-fleet', version: '2.1.0' }));
357
+ socket.send(JSON.stringify({ type: 'hello', name: 'coxpit-fleet', version: '2.1.2' }));
358
358
  socket.on('close', () => removeSink(socket));
359
359
  });
360
360