beads-ui 0.6.0 → 0.7.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/CHANGES.md +20 -0
- package/app/main.bundle.js +232 -203
- package/app/main.bundle.js.map +3 -3
- package/app/protocol.js +5 -2
- package/app/styles.css +64 -0
- package/package.json +1 -1
- package/server/bd.js +32 -0
- package/server/ws.js +73 -1
package/app/protocol.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* - Server can also send unsolicited events (e.g., subscription `snapshot`).
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
/** @typedef {'list-issues'|'update-status'|'edit-text'|'update-priority'|'create-issue'|'list-ready'|'dep-add'|'dep-remove'|'epic-status'|'update-assignee'|'label-add'|'label-remove'|'subscribe-list'|'unsubscribe-list'|'snapshot'|'upsert'|'delete'} MessageType */
|
|
12
|
+
/** @typedef {'list-issues'|'update-status'|'edit-text'|'update-priority'|'create-issue'|'list-ready'|'dep-add'|'dep-remove'|'epic-status'|'update-assignee'|'label-add'|'label-remove'|'subscribe-list'|'unsubscribe-list'|'snapshot'|'upsert'|'delete'|'get-comments'|'add-comment'} MessageType */
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* @typedef {Object} RequestEnvelope
|
|
@@ -53,7 +53,10 @@ export const MESSAGE_TYPES = /** @type {const} */ ([
|
|
|
53
53
|
// vNext per-subscription full-issue push events
|
|
54
54
|
'snapshot',
|
|
55
55
|
'upsert',
|
|
56
|
-
'delete'
|
|
56
|
+
'delete',
|
|
57
|
+
// Comments
|
|
58
|
+
'get-comments',
|
|
59
|
+
'add-comment'
|
|
57
60
|
]);
|
|
58
61
|
|
|
59
62
|
/**
|
package/app/styles.css
CHANGED
|
@@ -1656,3 +1656,67 @@ html[data-theme='dark'] {
|
|
|
1656
1656
|
grid-template-columns: 1fr;
|
|
1657
1657
|
}
|
|
1658
1658
|
}
|
|
1659
|
+
|
|
1660
|
+
/* Comments section */
|
|
1661
|
+
.comments {
|
|
1662
|
+
margin-top: 24px;
|
|
1663
|
+
padding-top: 16px;
|
|
1664
|
+
border-top: 1px solid var(--border);
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
.comment-item {
|
|
1668
|
+
padding: 12px;
|
|
1669
|
+
margin-bottom: 8px;
|
|
1670
|
+
background: color-mix(in srgb, var(--panel-bg) 95%, transparent);
|
|
1671
|
+
border: 1px solid var(--border);
|
|
1672
|
+
border-radius: 4px;
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
.comment-header {
|
|
1676
|
+
display: flex;
|
|
1677
|
+
justify-content: space-between;
|
|
1678
|
+
align-items: center;
|
|
1679
|
+
margin-bottom: 6px;
|
|
1680
|
+
font-size: 12px;
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
.comment-author {
|
|
1684
|
+
font-weight: 600;
|
|
1685
|
+
color: var(--fg);
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
.comment-date {
|
|
1689
|
+
color: var(--muted);
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
.comment-text {
|
|
1693
|
+
font-size: 14px;
|
|
1694
|
+
line-height: 1.5;
|
|
1695
|
+
white-space: pre-wrap;
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
.comment-input {
|
|
1699
|
+
margin-top: 12px;
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1702
|
+
.comment-input textarea {
|
|
1703
|
+
width: 100%;
|
|
1704
|
+
min-height: 60px;
|
|
1705
|
+
padding: 8px;
|
|
1706
|
+
border: 1px solid var(--control-border);
|
|
1707
|
+
border-radius: 4px;
|
|
1708
|
+
background: var(--control-bg);
|
|
1709
|
+
color: var(--fg);
|
|
1710
|
+
font-family: inherit;
|
|
1711
|
+
font-size: 14px;
|
|
1712
|
+
resize: vertical;
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
.comment-input textarea:focus {
|
|
1716
|
+
outline: none;
|
|
1717
|
+
border-color: var(--link);
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
.comment-input button {
|
|
1721
|
+
margin-top: 8px;
|
|
1722
|
+
}
|
package/package.json
CHANGED
package/server/bd.js
CHANGED
|
@@ -4,6 +4,38 @@ import { debug } from './logging.js';
|
|
|
4
4
|
|
|
5
5
|
const log = debug('bd');
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Get the git user name from git config.
|
|
9
|
+
*
|
|
10
|
+
* @param {{ cwd?: string }} [options]
|
|
11
|
+
* @returns {Promise<string>}
|
|
12
|
+
*/
|
|
13
|
+
export async function getGitUserName(options = {}) {
|
|
14
|
+
return new Promise((resolve) => {
|
|
15
|
+
const child = spawn('git', ['config', 'user.name'], {
|
|
16
|
+
cwd: options.cwd || process.cwd(),
|
|
17
|
+
shell: false
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
/** @type {string[]} */
|
|
21
|
+
const chunks = [];
|
|
22
|
+
|
|
23
|
+
if (child.stdout) {
|
|
24
|
+
child.stdout.setEncoding('utf8');
|
|
25
|
+
child.stdout.on('data', (chunk) => chunks.push(String(chunk)));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
child.on('error', () => resolve(''));
|
|
29
|
+
child.on('close', (code) => {
|
|
30
|
+
if (code !== 0) {
|
|
31
|
+
resolve('');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
resolve(chunks.join('').trim());
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
7
39
|
/**
|
|
8
40
|
* Resolve the bd executable path.
|
|
9
41
|
*
|
package/server/ws.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { WebSocketServer } from 'ws';
|
|
7
7
|
import { isRequest, makeError, makeOk } from '../app/protocol.js';
|
|
8
|
-
import { runBd, runBdJson } from './bd.js';
|
|
8
|
+
import { getGitUserName, runBd, runBdJson } from './bd.js';
|
|
9
9
|
import { fetchListForSubscription } from './list-adapters.js';
|
|
10
10
|
import { debug } from './logging.js';
|
|
11
11
|
import { keyOf, registry } from './subscriptions.js';
|
|
@@ -1081,6 +1081,78 @@ export async function handleMessage(ws, data) {
|
|
|
1081
1081
|
return;
|
|
1082
1082
|
}
|
|
1083
1083
|
|
|
1084
|
+
// get-comments: payload { id: string }
|
|
1085
|
+
if (req.type === 'get-comments') {
|
|
1086
|
+
const { id } = /** @type {any} */ (req.payload || {});
|
|
1087
|
+
if (typeof id !== 'string' || id.length === 0) {
|
|
1088
|
+
ws.send(
|
|
1089
|
+
JSON.stringify(
|
|
1090
|
+
makeError(req, 'bad_request', 'payload requires { id: string }')
|
|
1091
|
+
)
|
|
1092
|
+
);
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
1095
|
+
const res = await runBdJson(['comments', id, '--json']);
|
|
1096
|
+
if (res.code !== 0) {
|
|
1097
|
+
ws.send(
|
|
1098
|
+
JSON.stringify(makeError(req, 'bd_error', res.stderr || 'bd failed'))
|
|
1099
|
+
);
|
|
1100
|
+
return;
|
|
1101
|
+
}
|
|
1102
|
+
ws.send(JSON.stringify(makeOk(req, res.stdoutJson || [])));
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
// add-comment: payload { id: string, text: string }
|
|
1107
|
+
if (req.type === 'add-comment') {
|
|
1108
|
+
const { id, text } = /** @type {any} */ (req.payload || {});
|
|
1109
|
+
if (
|
|
1110
|
+
typeof id !== 'string' ||
|
|
1111
|
+
id.length === 0 ||
|
|
1112
|
+
typeof text !== 'string' ||
|
|
1113
|
+
text.trim().length === 0
|
|
1114
|
+
) {
|
|
1115
|
+
ws.send(
|
|
1116
|
+
JSON.stringify(
|
|
1117
|
+
makeError(
|
|
1118
|
+
req,
|
|
1119
|
+
'bad_request',
|
|
1120
|
+
'payload requires { id: string, text: non-empty string }'
|
|
1121
|
+
)
|
|
1122
|
+
)
|
|
1123
|
+
);
|
|
1124
|
+
return;
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
// Get git user name for author attribution
|
|
1128
|
+
const author = await getGitUserName();
|
|
1129
|
+
const args = ['comment', id, text.trim()];
|
|
1130
|
+
if (author) {
|
|
1131
|
+
args.push('--author', author);
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
const res = await runBd(args);
|
|
1135
|
+
if (res.code !== 0) {
|
|
1136
|
+
ws.send(
|
|
1137
|
+
JSON.stringify(makeError(req, 'bd_error', res.stderr || 'bd failed'))
|
|
1138
|
+
);
|
|
1139
|
+
return;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
// Return updated comments list
|
|
1143
|
+
const comments = await runBdJson(['comments', id, '--json']);
|
|
1144
|
+
if (comments.code !== 0) {
|
|
1145
|
+
ws.send(
|
|
1146
|
+
JSON.stringify(
|
|
1147
|
+
makeError(req, 'bd_error', comments.stderr || 'bd failed')
|
|
1148
|
+
)
|
|
1149
|
+
);
|
|
1150
|
+
return;
|
|
1151
|
+
}
|
|
1152
|
+
ws.send(JSON.stringify(makeOk(req, comments.stdoutJson || [])));
|
|
1153
|
+
return;
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1084
1156
|
// Unknown type
|
|
1085
1157
|
const err = makeError(
|
|
1086
1158
|
req,
|