beads-ui 0.12.1 → 0.12.3

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 CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changes
2
2
 
3
+ ## 0.12.3
4
+
5
+ - [`cee1d6d`](https://github.com/mantoni/beads-ui/commit/cee1d6d945828e33eebaf7ca76604fe8a457a772)
6
+ fix(list): remove the silent 50-issue list limit (#99) (Inconceivable Labs)
7
+ >
8
+ > Pass --limit 0 for all-issues and in-progress subscriptions so the UI does not silently truncate bd results.
9
+ - [`04c78e3`](https://github.com/mantoni/beads-ui/commit/04c78e352fb6c0af0616962701a39e42bc938cb3)
10
+ fix(ws): pin bd invocations to the active workspace cwd (#88) (Inconceivable Labs)
11
+ >
12
+ > Ensure every bd mutation and follow-up read runs in the active workspace, and centralize non-zero bd exit logging.
13
+
14
+ _Released by gprocunier on 2026-07-17._
15
+
16
+ ## 0.12.2
17
+
18
+ - [`92b80f9`](https://github.com/mantoni/beads-ui/commit/92b80f90339a7619dc0d8f7a10046b023658004d)
19
+ fix: use 'bd comments add' so --author is accepted (#97) (Jim C)
20
+ >
21
+ > Fixes #67 and #74.
22
+ - [`bc972a2`](https://github.com/mantoni/beads-ui/commit/bc972a2af68c0ae6fcab9b6c0613a28543fea5ec)
23
+ fix(detail): request --include-dependents so children render (#94) (Nick Veenhof)
24
+ >
25
+ > Fixes #93.
26
+
27
+ _Released by gprocunier on 2026-07-10._
28
+
3
29
  ## 0.12.1
4
30
 
5
31
  - [`dee0ffa`](https://github.com/mantoni/beads-ui/commit/dee0ffac6a5635c6761a4c97e3878157f2131f6b)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beads-ui",
3
- "version": "0.12.1",
3
+ "version": "0.12.3",
4
4
  "description": "Local UI for Beads — Collaborate on issues with your coding agent.",
5
5
  "keywords": [
6
6
  "agent",
package/server/bd.js CHANGED
@@ -146,6 +146,17 @@ function runBdUnlocked(args, options = {}) {
146
146
  finish(127);
147
147
  });
148
148
  child.on('close', (code) => {
149
+ const exit_code = Number(code || 0);
150
+ if (exit_code !== 0) {
151
+ // Mirror the logging runBdJson already does so non-JSON callers
152
+ // (mutation handlers) leave a debug trace on failure.
153
+ log(
154
+ 'bd exited with code %d (args=%o) stderr=%s',
155
+ exit_code,
156
+ final_args,
157
+ err_chunks.join('')
158
+ );
159
+ }
149
160
  finish(code);
150
161
  });
151
162
  });
@@ -207,12 +218,7 @@ async function withBdRunQueue(operation) {
207
218
  export async function runBdJson(args, options = {}) {
208
219
  const result = await runBd(args, options);
209
220
  if (result.code !== 0) {
210
- log(
211
- 'bd exited with code %d (args=%o) stderr=%s',
212
- result.code,
213
- args,
214
- result.stderr
215
- );
221
+ // Non-zero exits are logged centrally in runBdUnlocked's child.on('close').
216
222
  return { code: result.code, stderr: result.stderr };
217
223
  }
218
224
  /** @type {unknown} */
@@ -14,7 +14,8 @@ export function mapSubscriptionToBdArgs(spec) {
14
14
  const t = String(spec.type);
15
15
  switch (t) {
16
16
  case 'all-issues': {
17
- return ['list', '--json', '--tree=false'];
17
+ // `--limit 0` = unlimited. Without it, `bd list` caps at its default 50.
18
+ return ['list', '--json', '--tree=false', '--limit', '0'];
18
19
  }
19
20
  case 'epics': {
20
21
  return ['epic', 'status', '--json'];
@@ -26,7 +27,16 @@ export function mapSubscriptionToBdArgs(spec) {
26
27
  return ['ready', '--limit', '1000', '--json'];
27
28
  }
28
29
  case 'in-progress-issues': {
29
- return ['list', '--json', '--tree=false', '--status', 'in_progress'];
30
+ // `--limit 0` = unlimited. Without it, `bd list` caps at its default 50.
31
+ return [
32
+ 'list',
33
+ '--json',
34
+ '--tree=false',
35
+ '--status',
36
+ 'in_progress',
37
+ '--limit',
38
+ '0'
39
+ ];
30
40
  }
31
41
  case 'closed-issues': {
32
42
  return [
@@ -45,7 +55,7 @@ export function mapSubscriptionToBdArgs(spec) {
45
55
  if (id.length === 0) {
46
56
  throw badRequest('Missing param: params.id');
47
57
  }
48
- return ['show', id, '--json'];
58
+ return ['show', id, '--json', '--include-dependents'];
49
59
  }
50
60
  default: {
51
61
  throw badRequest(`Unknown subscription type: ${t}`);
package/server/ws.js CHANGED
@@ -597,6 +597,12 @@ export async function handleMessage(ws, data) {
597
597
 
598
598
  const req = json;
599
599
 
600
+ // Pin every bd invocation made during this message to the active workspace.
601
+ // Without this, runBd/runBdJson fall back to process.cwd() and bd reports
602
+ // "no beads database found" for any workspace selected via set-workspace.
603
+ // See mantoni/beads-ui#87.
604
+ const bd_options = { cwd: CURRENT_WORKSPACE?.root_dir };
605
+
600
606
  // Dispatch known types here as we implement them. For now, only a ping utility.
601
607
  if (req.type === /** @type {MessageType} */ ('ping')) {
602
608
  ws.send(JSON.stringify(makeOk(req, { ts: Date.now() })));
@@ -749,14 +755,14 @@ export async function handleMessage(ws, data) {
749
755
  return;
750
756
  }
751
757
  // Pass empty string to clear assignee when requested
752
- const res = await runBd(['update', id, '--assignee', assignee]);
758
+ const res = await runBd(['update', id, '--assignee', assignee], bd_options);
753
759
  if (res.code !== 0) {
754
760
  ws.send(
755
761
  JSON.stringify(makeError(req, 'bd_error', res.stderr || 'bd failed'))
756
762
  );
757
763
  return;
758
764
  }
759
- const shown = await runBdJson(['show', id, '--json']);
765
+ const shown = await runBdJson(['show', id, '--json'], bd_options);
760
766
  if (shown.code !== 0) {
761
767
  ws.send(
762
768
  JSON.stringify(makeError(req, 'bd_error', shown.stderr || 'bd failed'))
@@ -794,14 +800,14 @@ export async function handleMessage(ws, data) {
794
800
  );
795
801
  return;
796
802
  }
797
- const res = await runBd(['update', id, '--status', status]);
803
+ const res = await runBd(['update', id, '--status', status], bd_options);
798
804
  if (res.code !== 0) {
799
805
  ws.send(
800
806
  JSON.stringify(makeError(req, 'bd_error', res.stderr || 'bd failed'))
801
807
  );
802
808
  return;
803
809
  }
804
- const shown = await runBdJson(['show', id, '--json']);
810
+ const shown = await runBdJson(['show', id, '--json'], bd_options);
805
811
  if (shown.code !== 0) {
806
812
  ws.send(
807
813
  JSON.stringify(makeError(req, 'bd_error', shown.stderr || 'bd failed'))
@@ -840,14 +846,17 @@ export async function handleMessage(ws, data) {
840
846
  );
841
847
  return;
842
848
  }
843
- const res = await runBd(['update', id, '--priority', String(priority)]);
849
+ const res = await runBd(
850
+ ['update', id, '--priority', String(priority)],
851
+ bd_options
852
+ );
844
853
  if (res.code !== 0) {
845
854
  ws.send(
846
855
  JSON.stringify(makeError(req, 'bd_error', res.stderr || 'bd failed'))
847
856
  );
848
857
  return;
849
858
  }
850
- const shown = await runBdJson(['show', id, '--json']);
859
+ const shown = await runBdJson(['show', id, '--json'], bd_options);
851
860
  if (shown.code !== 0) {
852
861
  ws.send(
853
862
  JSON.stringify(makeError(req, 'bd_error', shown.stderr || 'bd failed'))
@@ -904,14 +913,14 @@ export async function handleMessage(ws, data) {
904
913
  : field === 'notes'
905
914
  ? '--notes'
906
915
  : '--design';
907
- const res = await runBd(['update', id, flag, value]);
916
+ const res = await runBd(['update', id, flag, value], bd_options);
908
917
  if (res.code !== 0) {
909
918
  ws.send(
910
919
  JSON.stringify(makeError(req, 'bd_error', res.stderr || 'bd failed'))
911
920
  );
912
921
  return;
913
922
  }
914
- const shown = await runBdJson(['show', id, '--json']);
923
+ const shown = await runBdJson(['show', id, '--json'], bd_options);
915
924
  if (shown.code !== 0) {
916
925
  ws.send(
917
926
  JSON.stringify(makeError(req, 'bd_error', shown.stderr || 'bd failed'))
@@ -962,7 +971,7 @@ export async function handleMessage(ws, data) {
962
971
  if (typeof description === 'string' && description.length > 0) {
963
972
  args.push('-d', description);
964
973
  }
965
- const res = await runBd(args);
974
+ const res = await runBd(args, bd_options);
966
975
  if (res.code !== 0) {
967
976
  ws.send(
968
977
  JSON.stringify(makeError(req, 'bd_error', res.stderr || 'bd failed'))
@@ -1000,7 +1009,7 @@ export async function handleMessage(ws, data) {
1000
1009
  );
1001
1010
  return;
1002
1011
  }
1003
- const res = await runBd(['dep', 'add', a, b]);
1012
+ const res = await runBd(['dep', 'add', a, b], bd_options);
1004
1013
  if (res.code !== 0) {
1005
1014
  ws.send(
1006
1015
  JSON.stringify(makeError(req, 'bd_error', res.stderr || 'bd failed'))
@@ -1008,7 +1017,7 @@ export async function handleMessage(ws, data) {
1008
1017
  return;
1009
1018
  }
1010
1019
  const id = typeof view_id === 'string' && view_id.length > 0 ? view_id : a;
1011
- const shown = await runBdJson(['show', id, '--json']);
1020
+ const shown = await runBdJson(['show', id, '--json'], bd_options);
1012
1021
  if (shown.code !== 0) {
1013
1022
  ws.send(
1014
1023
  JSON.stringify(makeError(req, 'bd_error', shown.stderr || 'bd failed'))
@@ -1044,7 +1053,7 @@ export async function handleMessage(ws, data) {
1044
1053
  );
1045
1054
  return;
1046
1055
  }
1047
- const res = await runBd(['dep', 'remove', a, b]);
1056
+ const res = await runBd(['dep', 'remove', a, b], bd_options);
1048
1057
  if (res.code !== 0) {
1049
1058
  ws.send(
1050
1059
  JSON.stringify(makeError(req, 'bd_error', res.stderr || 'bd failed'))
@@ -1052,7 +1061,7 @@ export async function handleMessage(ws, data) {
1052
1061
  return;
1053
1062
  }
1054
1063
  const id = typeof view_id === 'string' && view_id.length > 0 ? view_id : a;
1055
- const shown = await runBdJson(['show', id, '--json']);
1064
+ const shown = await runBdJson(['show', id, '--json'], bd_options);
1056
1065
  if (shown.code !== 0) {
1057
1066
  ws.send(
1058
1067
  JSON.stringify(makeError(req, 'bd_error', shown.stderr || 'bd failed'))
@@ -1088,14 +1097,14 @@ export async function handleMessage(ws, data) {
1088
1097
  );
1089
1098
  return;
1090
1099
  }
1091
- const res = await runBd(['label', 'add', id, label.trim()]);
1100
+ const res = await runBd(['label', 'add', id, label.trim()], bd_options);
1092
1101
  if (res.code !== 0) {
1093
1102
  ws.send(
1094
1103
  JSON.stringify(makeError(req, 'bd_error', res.stderr || 'bd failed'))
1095
1104
  );
1096
1105
  return;
1097
1106
  }
1098
- const shown = await runBdJson(['show', id, '--json']);
1107
+ const shown = await runBdJson(['show', id, '--json'], bd_options);
1099
1108
  if (shown.code !== 0) {
1100
1109
  ws.send(
1101
1110
  JSON.stringify(makeError(req, 'bd_error', shown.stderr || 'bd failed'))
@@ -1131,14 +1140,14 @@ export async function handleMessage(ws, data) {
1131
1140
  );
1132
1141
  return;
1133
1142
  }
1134
- const res = await runBd(['label', 'remove', id, label.trim()]);
1143
+ const res = await runBd(['label', 'remove', id, label.trim()], bd_options);
1135
1144
  if (res.code !== 0) {
1136
1145
  ws.send(
1137
1146
  JSON.stringify(makeError(req, 'bd_error', res.stderr || 'bd failed'))
1138
1147
  );
1139
1148
  return;
1140
1149
  }
1141
- const shown = await runBdJson(['show', id, '--json']);
1150
+ const shown = await runBdJson(['show', id, '--json'], bd_options);
1142
1151
  if (shown.code !== 0) {
1143
1152
  ws.send(
1144
1153
  JSON.stringify(makeError(req, 'bd_error', shown.stderr || 'bd failed'))
@@ -1165,7 +1174,7 @@ export async function handleMessage(ws, data) {
1165
1174
  );
1166
1175
  return;
1167
1176
  }
1168
- const res = await runBdJson(['comments', id, '--json']);
1177
+ const res = await runBdJson(['comments', id, '--json'], bd_options);
1169
1178
  if (res.code !== 0) {
1170
1179
  ws.send(
1171
1180
  JSON.stringify(makeError(req, 'bd_error', res.stderr || 'bd failed'))
@@ -1199,12 +1208,12 @@ export async function handleMessage(ws, data) {
1199
1208
 
1200
1209
  // Get git user name for author attribution
1201
1210
  const author = await getGitUserName();
1202
- const args = ['comment', id, text.trim()];
1211
+ const args = ['comments', 'add', id, text.trim()];
1203
1212
  if (author) {
1204
1213
  args.push('--author', author);
1205
1214
  }
1206
1215
 
1207
- const res = await runBd(args);
1216
+ const res = await runBd(args, bd_options);
1208
1217
  if (res.code !== 0) {
1209
1218
  ws.send(
1210
1219
  JSON.stringify(makeError(req, 'bd_error', res.stderr || 'bd failed'))
@@ -1213,7 +1222,7 @@ export async function handleMessage(ws, data) {
1213
1222
  }
1214
1223
 
1215
1224
  // Return updated comments list
1216
- const comments = await runBdJson(['comments', id, '--json']);
1225
+ const comments = await runBdJson(['comments', id, '--json'], bd_options);
1217
1226
  if (comments.code !== 0) {
1218
1227
  ws.send(
1219
1228
  JSON.stringify(
@@ -1237,7 +1246,7 @@ export async function handleMessage(ws, data) {
1237
1246
  );
1238
1247
  return;
1239
1248
  }
1240
- const res = await runBd(['delete', id, '--force']);
1249
+ const res = await runBd(['delete', id, '--force'], bd_options);
1241
1250
  if (res.code !== 0) {
1242
1251
  ws.send(
1243
1252
  JSON.stringify(