@citadel-labs/beads-ui 2.1.0 → 2.4.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.
Files changed (147) hide show
  1. package/.claude/worktrees/agent-a7b97047/LICENSE +21 -0
  2. package/.claude/worktrees/agent-a7b97047/README.md +63 -0
  3. package/.claude/worktrees/agent-a7b97047/bin/beads-board.js +183 -0
  4. package/.claude/worktrees/agent-a7b97047/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  5. package/.claude/worktrees/agent-a7b97047/package-lock.json +1752 -0
  6. package/.claude/worktrees/agent-a7b97047/package.json +43 -0
  7. package/.claude/worktrees/agent-a7b97047/server/__tests__/api.test.js +206 -0
  8. package/.claude/worktrees/agent-a7b97047/server/dist/assets/angular-html-DA-rfuFy.js +1 -0
  9. package/.claude/worktrees/agent-a7b97047/server/dist/assets/angular-ts-BrjP3tb8.js +1 -0
  10. package/.claude/worktrees/agent-a7b97047/server/dist/assets/c-BIGW1oBm.js +1 -0
  11. package/.claude/worktrees/agent-a7b97047/server/dist/assets/cpp-BRuaLJcg.js +1 -0
  12. package/.claude/worktrees/agent-a7b97047/server/dist/assets/csharp-COcwbKMJ.js +1 -0
  13. package/.claude/worktrees/agent-a7b97047/server/dist/assets/css-CLj8gQPS.js +1 -0
  14. package/.claude/worktrees/agent-a7b97047/server/dist/assets/dockerfile-BcOcwvcX.js +1 -0
  15. package/.claude/worktrees/agent-a7b97047/server/dist/assets/dotenv-Da5cRb03.js +1 -0
  16. package/.claude/worktrees/agent-a7b97047/server/dist/assets/github-dark-DHJKELXO.js +1 -0
  17. package/.claude/worktrees/agent-a7b97047/server/dist/assets/go-C27-OAKa.js +1 -0
  18. package/.claude/worktrees/agent-a7b97047/server/dist/assets/graphql-ChdNCCLP.js +1 -0
  19. package/.claude/worktrees/agent-a7b97047/server/dist/assets/html-derivative-C6UeqQa8.js +1 -0
  20. package/.claude/worktrees/agent-a7b97047/server/dist/assets/html-pp8916En.js +1 -0
  21. package/.claude/worktrees/agent-a7b97047/server/dist/assets/http-l_GQhCeT.js +1 -0
  22. package/.claude/worktrees/agent-a7b97047/server/dist/assets/index-BBBYE21N.css +1 -0
  23. package/.claude/worktrees/agent-a7b97047/server/dist/assets/index-cZFE6wf9.js +231 -0
  24. package/.claude/worktrees/agent-a7b97047/server/dist/assets/ini-BEwlwnbL.js +1 -0
  25. package/.claude/worktrees/agent-a7b97047/server/dist/assets/java-CylS5w8V.js +1 -0
  26. package/.claude/worktrees/agent-a7b97047/server/dist/assets/javascript-wDzz0qaB.js +1 -0
  27. package/.claude/worktrees/agent-a7b97047/server/dist/assets/json-Cp-IABpG.js +1 -0
  28. package/.claude/worktrees/agent-a7b97047/server/dist/assets/jsonc-Des-eS-w.js +1 -0
  29. package/.claude/worktrees/agent-a7b97047/server/dist/assets/jsonl-DcaNXYhu.js +1 -0
  30. package/.claude/worktrees/agent-a7b97047/server/dist/assets/jsx-g9-lgVsj.js +1 -0
  31. package/.claude/worktrees/agent-a7b97047/server/dist/assets/kotlin-BdnUsdx6.js +1 -0
  32. package/.claude/worktrees/agent-a7b97047/server/dist/assets/kusto-wEQ09or8.js +1 -0
  33. package/.claude/worktrees/agent-a7b97047/server/dist/assets/latex-DdMFrP5M.js +1 -0
  34. package/.claude/worktrees/agent-a7b97047/server/dist/assets/markdown-Cvjx9yec.js +1 -0
  35. package/.claude/worktrees/agent-a7b97047/server/dist/assets/mdc-Dz5ISc6g.js +1 -0
  36. package/.claude/worktrees/agent-a7b97047/server/dist/assets/mdx-Cmh6b_Ma.js +1 -0
  37. package/.claude/worktrees/agent-a7b97047/server/dist/assets/mermaid-mWjccvbQ.js +1 -0
  38. package/.claude/worktrees/agent-a7b97047/server/dist/assets/php-R6g_5hLQ.js +1 -0
  39. package/.claude/worktrees/agent-a7b97047/server/dist/assets/powershell-Dpen1YoG.js +1 -0
  40. package/.claude/worktrees/agent-a7b97047/server/dist/assets/python-B6aJPvgy.js +1 -0
  41. package/.claude/worktrees/agent-a7b97047/server/dist/assets/ruby-AcS3PBV-.js +1 -0
  42. package/.claude/worktrees/agent-a7b97047/server/dist/assets/rust-B1yitclQ.js +1 -0
  43. package/.claude/worktrees/agent-a7b97047/server/dist/assets/sass-Cj5Yp3dK.js +1 -0
  44. package/.claude/worktrees/agent-a7b97047/server/dist/assets/scss-D5BDwBP9.js +1 -0
  45. package/.claude/worktrees/agent-a7b97047/server/dist/assets/shellscript-DfDnw5Jg.js +1 -0
  46. package/.claude/worktrees/agent-a7b97047/server/dist/assets/sql-BLtJtn59.js +1 -0
  47. package/.claude/worktrees/agent-a7b97047/server/dist/assets/svelte-DR4MIrkg.js +1 -0
  48. package/.claude/worktrees/agent-a7b97047/server/dist/assets/swift-D82vCrfD.js +1 -0
  49. package/.claude/worktrees/agent-a7b97047/server/dist/assets/toml-vGWfd6FD.js +1 -0
  50. package/.claude/worktrees/agent-a7b97047/server/dist/assets/tsx-COt5Ahok.js +1 -0
  51. package/.claude/worktrees/agent-a7b97047/server/dist/assets/typescript-BPQ3VLAy.js +1 -0
  52. package/.claude/worktrees/agent-a7b97047/server/dist/assets/vue-CJgBXYWu.js +1 -0
  53. package/.claude/worktrees/agent-a7b97047/server/dist/assets/xml-sdJ4AIDG.js +1 -0
  54. package/.claude/worktrees/agent-a7b97047/server/dist/assets/yaml-Buea-lGh.js +1 -0
  55. package/.claude/worktrees/agent-a7b97047/server/dist/assets/zig-VOosw3JB.js +1 -0
  56. package/.claude/worktrees/agent-a7b97047/server/dist/favicon.svg +103 -0
  57. package/.claude/worktrees/agent-a7b97047/server/dist/index.html +14 -0
  58. package/.claude/worktrees/agent-a7b97047/server/dist/vite.svg +1 -0
  59. package/.claude/worktrees/agent-a7b97047/server/handlers.js +357 -0
  60. package/.claude/worktrees/agent-a7b97047/server/index.js +88 -0
  61. package/.claude/worktrees/agent-a7b97047/server/terminal.js +103 -0
  62. package/.claude/worktrees/agent-a7b97047/vitest.config.mjs +8 -0
  63. package/.claude/worktrees/agent-a952bde8/LICENSE +21 -0
  64. package/.claude/worktrees/agent-a952bde8/README.md +63 -0
  65. package/.claude/worktrees/agent-a952bde8/bin/beads-board.js +183 -0
  66. package/.claude/worktrees/agent-a952bde8/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  67. package/.claude/worktrees/agent-a952bde8/package-lock.json +1752 -0
  68. package/.claude/worktrees/agent-a952bde8/package.json +43 -0
  69. package/.claude/worktrees/agent-a952bde8/server/__tests__/api.test.js +122 -0
  70. package/.claude/worktrees/agent-a952bde8/server/dist/assets/index-BsWRmNbj.js +79 -0
  71. package/.claude/worktrees/agent-a952bde8/server/dist/assets/index-C7JKZkTD.css +1 -0
  72. package/.claude/worktrees/agent-a952bde8/server/dist/favicon.svg +103 -0
  73. package/.claude/worktrees/agent-a952bde8/server/dist/index.html +14 -0
  74. package/.claude/worktrees/agent-a952bde8/server/dist/vite.svg +1 -0
  75. package/.claude/worktrees/agent-a952bde8/server/handlers.js +269 -0
  76. package/.claude/worktrees/agent-a952bde8/server/index.js +88 -0
  77. package/.claude/worktrees/agent-a952bde8/server/terminal.js +103 -0
  78. package/.claude/worktrees/agent-a952bde8/vitest.config.mjs +8 -0
  79. package/README.md +2 -1
  80. package/coverage/base.css +224 -0
  81. package/coverage/block-navigation.js +87 -0
  82. package/coverage/clover.xml +153 -0
  83. package/coverage/coverage-final.json +2 -0
  84. package/coverage/favicon.png +0 -0
  85. package/coverage/handlers.js.html +892 -0
  86. package/coverage/index.html +116 -0
  87. package/coverage/prettify.css +1 -0
  88. package/coverage/prettify.js +2 -0
  89. package/coverage/sort-arrow-sprite.png +0 -0
  90. package/coverage/sorter.js +210 -0
  91. package/package.json +43 -34
  92. package/server/__tests__/api.test.js +261 -0
  93. package/server/dist/assets/angular-html-DA-rfuFy.js +1 -0
  94. package/server/dist/assets/angular-ts-BrjP3tb8.js +1 -0
  95. package/server/dist/assets/c-BIGW1oBm.js +1 -0
  96. package/server/dist/assets/cpp-BRuaLJcg.js +1 -0
  97. package/server/dist/assets/csharp-COcwbKMJ.js +1 -0
  98. package/server/dist/assets/css-CLj8gQPS.js +1 -0
  99. package/server/dist/assets/dockerfile-BcOcwvcX.js +1 -0
  100. package/server/dist/assets/dotenv-Da5cRb03.js +1 -0
  101. package/server/dist/assets/github-dark-DHJKELXO.js +1 -0
  102. package/server/dist/assets/go-C27-OAKa.js +1 -0
  103. package/server/dist/assets/graphql-ChdNCCLP.js +1 -0
  104. package/server/dist/assets/html-derivative-C6UeqQa8.js +1 -0
  105. package/server/dist/assets/html-pp8916En.js +1 -0
  106. package/server/dist/assets/http-l_GQhCeT.js +1 -0
  107. package/server/dist/assets/index-DOFQi_E1.js +231 -0
  108. package/server/dist/assets/index-DeppoR8O.css +1 -0
  109. package/server/dist/assets/ini-BEwlwnbL.js +1 -0
  110. package/server/dist/assets/java-CylS5w8V.js +1 -0
  111. package/server/dist/assets/javascript-wDzz0qaB.js +1 -0
  112. package/server/dist/assets/json-Cp-IABpG.js +1 -0
  113. package/server/dist/assets/jsonc-Des-eS-w.js +1 -0
  114. package/server/dist/assets/jsonl-DcaNXYhu.js +1 -0
  115. package/server/dist/assets/jsx-g9-lgVsj.js +1 -0
  116. package/server/dist/assets/kotlin-BdnUsdx6.js +1 -0
  117. package/server/dist/assets/kusto-wEQ09or8.js +1 -0
  118. package/server/dist/assets/latex-DdMFrP5M.js +1 -0
  119. package/server/dist/assets/markdown-Cvjx9yec.js +1 -0
  120. package/server/dist/assets/mdc-Dz5ISc6g.js +1 -0
  121. package/server/dist/assets/mdx-Cmh6b_Ma.js +1 -0
  122. package/server/dist/assets/mermaid-mWjccvbQ.js +1 -0
  123. package/server/dist/assets/php-R6g_5hLQ.js +1 -0
  124. package/server/dist/assets/powershell-Dpen1YoG.js +1 -0
  125. package/server/dist/assets/python-B6aJPvgy.js +1 -0
  126. package/server/dist/assets/ruby-AcS3PBV-.js +1 -0
  127. package/server/dist/assets/rust-B1yitclQ.js +1 -0
  128. package/server/dist/assets/sass-Cj5Yp3dK.js +1 -0
  129. package/server/dist/assets/scss-D5BDwBP9.js +1 -0
  130. package/server/dist/assets/shellscript-DfDnw5Jg.js +1 -0
  131. package/server/dist/assets/sql-BLtJtn59.js +1 -0
  132. package/server/dist/assets/svelte-DR4MIrkg.js +1 -0
  133. package/server/dist/assets/swift-D82vCrfD.js +1 -0
  134. package/server/dist/assets/toml-vGWfd6FD.js +1 -0
  135. package/server/dist/assets/tsx-COt5Ahok.js +1 -0
  136. package/server/dist/assets/typescript-BPQ3VLAy.js +1 -0
  137. package/server/dist/assets/vue-CJgBXYWu.js +1 -0
  138. package/server/dist/assets/xml-sdJ4AIDG.js +1 -0
  139. package/server/dist/assets/yaml-Buea-lGh.js +1 -0
  140. package/server/dist/assets/zig-VOosw3JB.js +1 -0
  141. package/server/dist/index.html +2 -2
  142. package/server/handlers.js +356 -0
  143. package/server/index.js +2 -242
  144. package/server/terminal.js +2 -4
  145. package/vitest.config.mjs +8 -0
  146. package/server/dist/assets/index-BNjM8bEC.css +0 -1
  147. package/server/dist/assets/index-BU8XOdEX.js +0 -75
@@ -0,0 +1,43 @@
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
+ }
@@ -0,0 +1,122 @@
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
+ });