@citadel-labs/beads-ui 2.4.0 → 2.5.0
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 +6 -3
- package/bin/beads-board.js +173 -183
- package/package.json +2 -2
- package/server/__tests__/api.test.js +241 -2
- package/server/__tests__/pidfile.test.js +99 -0
- package/server/__tests__/terminal.test.js +339 -0
- package/server/dist/assets/index-Dm1YZe0A.css +1 -0
- package/server/dist/assets/index-G6bcoKqz.js +232 -0
- package/server/dist/index.html +2 -2
- package/server/handlers.js +167 -57
- package/server/index.js +5 -26
- package/server/pidfile.js +71 -0
- package/server/terminal-sessions.js +149 -0
- package/server/terminal.js +132 -31
- package/terminal-session-01-initial.png +0 -0
- package/terminal-session-02-before-refresh.png +0 -0
- package/terminal-session-03-after-refresh.png +0 -0
- package/.claude/worktrees/agent-a7b97047/LICENSE +0 -21
- package/.claude/worktrees/agent-a7b97047/README.md +0 -63
- package/.claude/worktrees/agent-a7b97047/bin/beads-board.js +0 -183
- package/.claude/worktrees/agent-a7b97047/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/.claude/worktrees/agent-a7b97047/package-lock.json +0 -1752
- package/.claude/worktrees/agent-a7b97047/package.json +0 -43
- package/.claude/worktrees/agent-a7b97047/server/__tests__/api.test.js +0 -206
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/angular-html-DA-rfuFy.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/angular-ts-BrjP3tb8.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/c-BIGW1oBm.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/cpp-BRuaLJcg.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/csharp-COcwbKMJ.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/css-CLj8gQPS.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/dockerfile-BcOcwvcX.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/dotenv-Da5cRb03.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/github-dark-DHJKELXO.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/go-C27-OAKa.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/graphql-ChdNCCLP.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/html-derivative-C6UeqQa8.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/html-pp8916En.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/http-l_GQhCeT.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/index-BBBYE21N.css +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/index-cZFE6wf9.js +0 -231
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/ini-BEwlwnbL.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/java-CylS5w8V.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/javascript-wDzz0qaB.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/json-Cp-IABpG.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/jsonc-Des-eS-w.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/jsonl-DcaNXYhu.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/jsx-g9-lgVsj.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/kotlin-BdnUsdx6.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/kusto-wEQ09or8.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/latex-DdMFrP5M.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/markdown-Cvjx9yec.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/mdc-Dz5ISc6g.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/mdx-Cmh6b_Ma.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/mermaid-mWjccvbQ.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/php-R6g_5hLQ.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/powershell-Dpen1YoG.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/python-B6aJPvgy.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/ruby-AcS3PBV-.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/rust-B1yitclQ.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/sass-Cj5Yp3dK.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/scss-D5BDwBP9.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/shellscript-DfDnw5Jg.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/sql-BLtJtn59.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/svelte-DR4MIrkg.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/swift-D82vCrfD.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/toml-vGWfd6FD.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/tsx-COt5Ahok.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/typescript-BPQ3VLAy.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/vue-CJgBXYWu.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/xml-sdJ4AIDG.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/yaml-Buea-lGh.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/assets/zig-VOosw3JB.js +0 -1
- package/.claude/worktrees/agent-a7b97047/server/dist/favicon.svg +0 -103
- package/.claude/worktrees/agent-a7b97047/server/dist/index.html +0 -14
- package/.claude/worktrees/agent-a7b97047/server/dist/vite.svg +0 -1
- package/.claude/worktrees/agent-a7b97047/server/handlers.js +0 -357
- package/.claude/worktrees/agent-a7b97047/server/index.js +0 -88
- package/.claude/worktrees/agent-a7b97047/server/terminal.js +0 -103
- package/.claude/worktrees/agent-a7b97047/vitest.config.mjs +0 -8
- package/.claude/worktrees/agent-a952bde8/LICENSE +0 -21
- package/.claude/worktrees/agent-a952bde8/README.md +0 -63
- package/.claude/worktrees/agent-a952bde8/bin/beads-board.js +0 -183
- package/.claude/worktrees/agent-a952bde8/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/.claude/worktrees/agent-a952bde8/package-lock.json +0 -1752
- package/.claude/worktrees/agent-a952bde8/package.json +0 -43
- package/.claude/worktrees/agent-a952bde8/server/__tests__/api.test.js +0 -122
- package/.claude/worktrees/agent-a952bde8/server/dist/assets/index-BsWRmNbj.js +0 -79
- package/.claude/worktrees/agent-a952bde8/server/dist/assets/index-C7JKZkTD.css +0 -1
- package/.claude/worktrees/agent-a952bde8/server/dist/favicon.svg +0 -103
- package/.claude/worktrees/agent-a952bde8/server/dist/index.html +0 -14
- package/.claude/worktrees/agent-a952bde8/server/dist/vite.svg +0 -1
- package/.claude/worktrees/agent-a952bde8/server/handlers.js +0 -269
- package/.claude/worktrees/agent-a952bde8/server/index.js +0 -88
- package/.claude/worktrees/agent-a952bde8/server/terminal.js +0 -103
- package/.claude/worktrees/agent-a952bde8/vitest.config.mjs +0 -8
- package/server/dist/assets/index-DOFQi_E1.js +0 -231
- package/server/dist/assets/index-DeppoR8O.css +0 -1
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@citadel-labs/beads-ui",
|
|
3
|
-
"version": "2.3.0",
|
|
4
|
-
"description": "Kanban dashboard and git log viewer for Beads",
|
|
5
|
-
"bin": {
|
|
6
|
-
"bdui": "bin/beads-board.js"
|
|
7
|
-
},
|
|
8
|
-
"scripts": {
|
|
9
|
-
"build": "cd ui && npm run build",
|
|
10
|
-
"start": "node server/index.js",
|
|
11
|
-
"test": "vitest run && npm --prefix ui test",
|
|
12
|
-
"test:server": "vitest run",
|
|
13
|
-
"test:ui": "npm --prefix ui test",
|
|
14
|
-
"test:watch": "vitest",
|
|
15
|
-
"test:coverage": "vitest run --coverage",
|
|
16
|
-
"publish:patch": "npm version patch && git push && git push --tags && npm publish --access public",
|
|
17
|
-
"publish:minor": "npm version minor && git push && git push --tags && npm publish --access public",
|
|
18
|
-
"publish:major": "npm version major && git push && git push --tags && npm publish --access public"
|
|
19
|
-
},
|
|
20
|
-
"keywords": [
|
|
21
|
-
"beads",
|
|
22
|
-
"kanban",
|
|
23
|
-
"dashboard",
|
|
24
|
-
"git",
|
|
25
|
-
"cli",
|
|
26
|
-
"bdui"
|
|
27
|
-
],
|
|
28
|
-
"repository": {
|
|
29
|
-
"type": "git",
|
|
30
|
-
"url": "https://github.com/srimel/beads-board.git"
|
|
31
|
-
},
|
|
32
|
-
"homepage": "https://github.com/srimel/beads-board",
|
|
33
|
-
"author": "Stuart Rimel <stuart.rimel@gmail.com>",
|
|
34
|
-
"license": "MIT",
|
|
35
|
-
"dependencies": {
|
|
36
|
-
"node-pty": "^1.1.0",
|
|
37
|
-
"ws": "^8.19.0"
|
|
38
|
-
},
|
|
39
|
-
"devDependencies": {
|
|
40
|
-
"@vitest/coverage-v8": "^4.0.18",
|
|
41
|
-
"vitest": "^4.0.18"
|
|
42
|
-
}
|
|
43
|
-
}
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeAll, afterAll, afterEach } from 'vitest';
|
|
2
|
-
import http from 'node:http';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
|
|
6
|
-
import { createRequestHandler, setExecFile } from '../handlers.js';
|
|
7
|
-
|
|
8
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
-
const DIST_DIR = path.join(__dirname, '..', 'dist');
|
|
10
|
-
const PROJECT_DIR = path.join(__dirname, '..', '..');
|
|
11
|
-
|
|
12
|
-
let server;
|
|
13
|
-
let baseUrl;
|
|
14
|
-
const mockFn = vi.fn();
|
|
15
|
-
|
|
16
|
-
// Helper: mock execFile to return specific output for bd/git commands
|
|
17
|
-
function mockExecFile(fn) {
|
|
18
|
-
mockFn.mockImplementation((cmd, args, opts, cb) => {
|
|
19
|
-
const result = fn(cmd, args);
|
|
20
|
-
if (result instanceof Error) {
|
|
21
|
-
cb(result, '', result.message);
|
|
22
|
-
} else {
|
|
23
|
-
cb(null, result, '');
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
beforeAll(async () => {
|
|
29
|
-
// Replace the real execFile with our mock
|
|
30
|
-
setExecFile(mockFn);
|
|
31
|
-
const handler = createRequestHandler(PROJECT_DIR, DIST_DIR);
|
|
32
|
-
server = http.createServer(handler);
|
|
33
|
-
await new Promise((resolve) => {
|
|
34
|
-
server.listen(0, () => {
|
|
35
|
-
const addr = server.address();
|
|
36
|
-
baseUrl = `http://localhost:${addr.port}`;
|
|
37
|
-
resolve();
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
afterAll(async () => {
|
|
43
|
-
await new Promise((resolve) => server.close(resolve));
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
afterEach(() => {
|
|
47
|
-
mockFn.mockReset();
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
async function get(urlPath) {
|
|
51
|
-
const r = await fetch(`${baseUrl}${urlPath}`);
|
|
52
|
-
const text = await r.text();
|
|
53
|
-
let data = null;
|
|
54
|
-
try { data = JSON.parse(text); } catch {}
|
|
55
|
-
return { status: r.status, data, text };
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
describe('API endpoints', () => {
|
|
59
|
-
it('GET /api/issues returns JSON array', async () => {
|
|
60
|
-
mockExecFile((cmd, args) => {
|
|
61
|
-
return JSON.stringify([{ id: 'test-1', title: 'Test', issue_type: 'task' }]);
|
|
62
|
-
});
|
|
63
|
-
const res = await get('/api/issues');
|
|
64
|
-
expect(res.status).toBe(200);
|
|
65
|
-
expect(Array.isArray(res.data)).toBe(true);
|
|
66
|
-
expect(res.data[0]).toHaveProperty('id', 'test-1');
|
|
67
|
-
expect(res.data[0]).toHaveProperty('type', 'task'); // normalizeIssue applied
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('GET /api/issue/:id returns issue data for valid ID', async () => {
|
|
71
|
-
mockExecFile((cmd, args) => {
|
|
72
|
-
if (cmd === 'bd') return JSON.stringify({ id: 'beads-board-abc', title: 'Test Issue' });
|
|
73
|
-
return '';
|
|
74
|
-
});
|
|
75
|
-
const res = await get('/api/issue/beads-board-abc');
|
|
76
|
-
expect(res.status).toBe(200);
|
|
77
|
-
expect(res.data).toHaveProperty('title', 'Test Issue');
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('GET /api/issue/:id accepts dotted IDs', async () => {
|
|
81
|
-
mockExecFile((cmd, args) => {
|
|
82
|
-
if (cmd === 'bd') return JSON.stringify({ id: 'beads-board-abc.1', title: 'Sub-task' });
|
|
83
|
-
return '';
|
|
84
|
-
});
|
|
85
|
-
const res = await get('/api/issue/beads-board-abc.1');
|
|
86
|
-
expect(res.status).toBe(200);
|
|
87
|
-
expect(res.data).toHaveProperty('id', 'beads-board-abc.1');
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it('GET /api/issue/:id returns 400 for invalid ID', async () => {
|
|
91
|
-
const res = await get('/api/issue/invalid;id');
|
|
92
|
-
expect(res.status).toBe(400);
|
|
93
|
-
expect(res.data).toHaveProperty('error', 'Invalid issue ID');
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it('GET /api/ready returns JSON array', async () => {
|
|
97
|
-
mockExecFile((cmd, args) => {
|
|
98
|
-
if (cmd === 'bd') return JSON.stringify([{ id: 'test-2', title: 'Ready', issue_type: 'bug' }]);
|
|
99
|
-
return '';
|
|
100
|
-
});
|
|
101
|
-
const res = await get('/api/ready');
|
|
102
|
-
expect(res.status).toBe(200);
|
|
103
|
-
expect(Array.isArray(res.data)).toBe(true);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('GET /api/blocked returns JSON array', async () => {
|
|
107
|
-
mockExecFile((cmd, args) => {
|
|
108
|
-
if (cmd === 'bd') return JSON.stringify([]);
|
|
109
|
-
return '';
|
|
110
|
-
});
|
|
111
|
-
const res = await get('/api/blocked');
|
|
112
|
-
expect(res.status).toBe(200);
|
|
113
|
-
expect(Array.isArray(res.data)).toBe(true);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
it('GET / serves index.html', async () => {
|
|
117
|
-
// No mock needed — this reads from dist/
|
|
118
|
-
const res = await fetch(`${baseUrl}/`);
|
|
119
|
-
expect(res.status).toBe(200);
|
|
120
|
-
expect(res.headers.get('content-type')).toContain('text/html');
|
|
121
|
-
});
|
|
122
|
-
});
|