@unson/brainbase-mcp 0.10.7 → 0.10.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unson/brainbase-mcp",
3
- "version": "0.10.7",
3
+ "version": "0.10.9",
4
4
  "description": "Local-first Brainbase judgment OS that lets supported AI agents reuse a user's approved goals, priorities, decisions, and judgment criteria.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -336,5 +336,5 @@
336
336
  "engines": {
337
337
  "node": ">=20"
338
338
  },
339
- "gitHead": "9b53aa137dac5126a8bd43b7a58b21b135244c88"
339
+ "gitHead": "56b00ab769c11319de73f799e8be90a95a81b7f0"
340
340
  }
@@ -1,22 +1,13 @@
1
1
  /* Shared project knowledge workspace. Load after graph-view-shared.css. */
2
2
 
3
3
  .bb-pkw {
4
- --bb-color-ink: var(--bb-color-project-ink);
5
- --bb-color-muted: var(--bb-color-project-muted);
6
- --bb-color-border: var(--bb-color-project-border);
7
- --bb-color-border-strong: var(--bb-color-project-border-strong);
8
- --bb-color-surface: var(--bb-color-panel);
9
- --bb-color-accent: var(--bb-color-project-accent);
10
- --bb-color-accent-strong: var(--bb-color-project-accent-strong);
11
4
  display: grid;
12
5
  gap: var(--bb-space-4);
13
6
  min-width: 0;
14
7
  margin-top: var(--bb-space-6);
15
- border: 1px solid var(--bb-color-border);
16
- border-radius: var(--bb-radius-md);
17
- padding: var(--bb-space-5);
8
+ padding: 0;
18
9
  color: var(--bb-color-ink);
19
- background: var(--bb-color-panel);
10
+ background: transparent;
20
11
  font-family: var(--bb-font-sans);
21
12
  }
22
13
 
@@ -36,7 +27,7 @@
36
27
 
37
28
  .bb-pkw-header {
38
29
  display: grid;
39
- gap: var(--bb-space-2);
30
+ gap: 12px;
40
31
  min-width: 0;
41
32
  }
42
33
 
@@ -50,9 +41,12 @@
50
41
  }
51
42
 
52
43
  .bb-pkw-header h2 {
53
- font-size: clamp(22px, 2.6vw, 32px);
54
- letter-spacing: -.04em;
55
- overflow-wrap: anywhere;
44
+ font-size: clamp(32px, 3.5vw, 44px);
45
+ font-weight: 760;
46
+ line-height: 1.1;
47
+ letter-spacing: -.055em;
48
+ word-break: keep-all;
49
+ overflow-wrap: break-word;
56
50
  }
57
51
 
58
52
  .bb-pkw-lead,
@@ -63,6 +57,10 @@
63
57
  line-height: 1.65;
64
58
  }
65
59
 
60
+ .bb-pkw-lead {
61
+ max-width: 720px;
62
+ }
63
+
66
64
  .bb-pkw-meta {
67
65
  display: flex;
68
66
  flex-wrap: wrap;
@@ -203,15 +201,15 @@
203
201
  font: inherit;
204
202
  font-weight: 720;
205
203
  text-align: left;
206
- text-decoration: underline;
207
- text-decoration-color: color-mix(in srgb, var(--bb-color-accent) 35%, transparent);
208
- text-underline-offset: 3px;
204
+ text-decoration: none;
209
205
  cursor: pointer;
210
206
  }
211
207
 
212
208
  .bb-pkw-record-link:hover {
213
209
  color: var(--bb-color-accent);
210
+ text-decoration: underline;
214
211
  text-decoration-color: currentColor;
212
+ text-underline-offset: 3px;
215
213
  }
216
214
 
217
215
  .bb-pkw-people-list p,
@@ -220,6 +218,120 @@
220
218
  flex-basis: 100%;
221
219
  }
222
220
 
221
+ .bb-pkw-context-task-list {
222
+ gap: 0;
223
+ border-top: 1px solid var(--bb-color-border);
224
+ }
225
+
226
+ .bb-pkw-context-list .bb-pkw-context-task-row {
227
+ display: grid;
228
+ grid-template-columns: 28px minmax(0, 2.4fr) minmax(112px, .75fr) 92px minmax(100px, .9fr);
229
+ align-items: center;
230
+ gap: 0;
231
+ min-height: 54px;
232
+ border-bottom: 1px solid var(--bb-color-border);
233
+ padding: 0;
234
+ font-size: 12px;
235
+ }
236
+
237
+ .bb-pkw-context-list .bb-pkw-context-task-row:last-child {
238
+ border-bottom: 1px solid var(--bb-color-border);
239
+ }
240
+
241
+ .bb-pkw-context-task-row > * {
242
+ min-width: 0;
243
+ padding: 8px 10px;
244
+ }
245
+
246
+ .bb-pkw-context-task-row .bb-pkw-context-task-state {
247
+ width: 9px;
248
+ height: 9px;
249
+ margin: auto;
250
+ padding: 0;
251
+ border: 1.5px solid var(--bb-color-muted);
252
+ border-radius: 50%;
253
+ }
254
+
255
+ .bb-pkw-context-task-row .bb-pkw-context-task-state.bb-pkw-context-task-wait {
256
+ border-color: var(--bb-color-warning);
257
+ background: var(--bb-color-warning);
258
+ }
259
+
260
+ .bb-pkw-context-task-row .bb-pkw-context-task-state.bb-pkw-context-task-fail {
261
+ border-color: var(--bb-color-danger);
262
+ background: var(--bb-color-danger);
263
+ }
264
+
265
+ .bb-pkw-context-task-row .bb-pkw-context-task-state.bb-pkw-context-task-ok {
266
+ border-color: var(--bb-color-accent);
267
+ background: var(--bb-color-accent);
268
+ }
269
+
270
+ .bb-pkw-context-task-row .bb-pkw-context-task-title {
271
+ width: 100%;
272
+ overflow: hidden;
273
+ border: 0;
274
+ background: transparent;
275
+ color: var(--bb-color-ink);
276
+ font: inherit;
277
+ font-size: 14px;
278
+ font-weight: 690;
279
+ text-align: left;
280
+ text-overflow: ellipsis;
281
+ white-space: nowrap;
282
+ }
283
+
284
+ button.bb-pkw-context-task-title { cursor: pointer; }
285
+ button.bb-pkw-context-task-title:hover { color: var(--bb-color-accent-strong); text-decoration: underline; }
286
+ button.bb-pkw-context-task-title:focus-visible { outline: 3px solid var(--bb-color-focus); outline-offset: -2px; }
287
+
288
+ .bb-pkw-context-task-owner {
289
+ color: var(--bb-color-muted);
290
+ overflow-wrap: anywhere;
291
+ }
292
+
293
+ .bb-pkw-context-task-due {
294
+ white-space: nowrap;
295
+ }
296
+
297
+ .bb-pkw-context-task-due.bb-pkw-context-task-overdue {
298
+ color: var(--bb-color-danger);
299
+ font-weight: 740;
300
+ }
301
+
302
+ .bb-pkw-context-task-stage {
303
+ display: flex;
304
+ align-items: center;
305
+ gap: 7px;
306
+ color: var(--bb-color-muted);
307
+ }
308
+
309
+ .bb-pkw-context-task-stage::before {
310
+ width: 6px;
311
+ height: 6px;
312
+ flex: 0 0 auto;
313
+ border-radius: 50%;
314
+ background: var(--bb-color-muted);
315
+ content: '';
316
+ }
317
+
318
+ .bb-pkw-context-task-stage.bb-pkw-context-task-wait::before { background: var(--bb-color-warning); }
319
+ .bb-pkw-context-task-stage.bb-pkw-context-task-fail::before { background: var(--bb-color-danger); }
320
+ .bb-pkw-context-task-stage.bb-pkw-context-task-ok::before { background: var(--bb-color-accent); }
321
+
322
+ @media (max-width: 760px) {
323
+ .bb-pkw-context-list .bb-pkw-context-task-row {
324
+ grid-template-columns: 28px minmax(0, 1fr) auto;
325
+ grid-template-areas: 'state title stage' '. owner due';
326
+ }
327
+
328
+ .bb-pkw-context-task-state { grid-area: state; }
329
+ .bb-pkw-context-task-title { grid-area: title; }
330
+ .bb-pkw-context-task-owner { grid-area: owner; }
331
+ .bb-pkw-context-task-due { grid-area: due; }
332
+ .bb-pkw-context-task-stage { grid-area: stage; }
333
+ }
334
+
223
335
  .bb-pkw-info-grid {
224
336
  display: grid;
225
337
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
@@ -228,10 +340,9 @@
228
340
 
229
341
  .bb-pkw-object {
230
342
  min-width: 0;
231
- border: 1px solid var(--bb-color-border);
232
- border-radius: var(--bb-radius-sm);
233
- padding: var(--bb-space-3);
234
- background: var(--bb-color-surface);
343
+ border-top: 1px solid var(--bb-color-border);
344
+ padding: var(--bb-space-3) 0 0;
345
+ background: transparent;
235
346
  }
236
347
 
237
348
  .bb-pkw-object h4 {
@@ -474,7 +585,7 @@
474
585
 
475
586
  @media (max-width: 760px) {
476
587
  .bb-pkw {
477
- padding: var(--bb-space-4);
588
+ padding: 0;
478
589
  }
479
590
 
480
591
  .bb-pkw-columns {
@@ -540,7 +651,7 @@
540
651
  entry point; rows and details carry the long form. */
541
652
  .bb-pkw-dense-overview {
542
653
  display: grid;
543
- gap: var(--bb-space-4);
654
+ gap: 0;
544
655
  }
545
656
 
546
657
  .bb-pkw-dense-intro {
@@ -569,17 +680,25 @@
569
680
  .bb-pkw-dense-metrics {
570
681
  display: grid;
571
682
  grid-template-columns: repeat(4, minmax(0, 1fr));
572
- gap: var(--bb-space-2);
683
+ gap: 0;
684
+ margin: 0 0 var(--bb-space-5);
685
+ border-block: 1px solid var(--bb-color-border);
573
686
  }
574
687
 
575
688
  .bb-pkw-dense-metric {
576
689
  display: grid;
577
690
  gap: 3px;
578
691
  min-width: 0;
579
- border: 1px solid var(--bb-color-border);
580
- border-radius: var(--bb-radius-sm);
581
- padding: 8px 12px;
582
- background: var(--bb-color-panel);
692
+ border-right: 1px solid var(--bb-color-border);
693
+ padding: 20px 24px;
694
+ }
695
+
696
+ .bb-pkw-dense-metric:first-child {
697
+ padding-left: 0;
698
+ }
699
+
700
+ .bb-pkw-dense-metric:last-child {
701
+ border-right: 0;
583
702
  }
584
703
 
585
704
  .bb-pkw-dense-metric-label {
@@ -589,31 +708,34 @@
589
708
  }
590
709
 
591
710
  .bb-pkw-dense-metric-value {
711
+ display: block;
592
712
  min-width: 0;
593
713
  overflow-wrap: anywhere;
594
714
  color: var(--bb-color-ink);
595
- font-size: 20px;
715
+ font-size: 30px;
716
+ font-weight: 760;
717
+ line-height: 1.1;
596
718
  letter-spacing: -.03em;
597
719
  }
598
720
 
599
721
  .bb-pkw-dense-grid {
600
722
  display: grid;
601
723
  grid-template-columns: minmax(0, 1fr);
602
- gap: var(--bb-space-3);
724
+ gap: 0;
603
725
  }
604
726
 
605
727
  .bb-pkw-dense-supporting-grid {
606
728
  grid-template-columns: repeat(2, minmax(0, 1fr));
729
+ gap: var(--bb-space-5);
607
730
  }
608
731
 
609
732
  .bb-pkw-dense-card {
610
733
  display: grid;
611
- gap: 6px;
734
+ gap: var(--bb-space-3);
612
735
  min-width: 0;
613
- border: 1px solid var(--bb-color-border);
614
- border-radius: var(--bb-radius-sm);
615
- padding: 10px 14px;
616
- background: var(--bb-color-panel);
736
+ border-top: 1px solid var(--bb-color-border-strong);
737
+ padding: var(--bb-space-4) 0 0;
738
+ background: transparent;
617
739
  }
618
740
 
619
741
  .bb-pkw-dense-card-wide {
@@ -660,7 +782,7 @@
660
782
  .bb-pkw-dense-list,
661
783
  .bb-pkw-dense-record-list {
662
784
  display: grid;
663
- gap: var(--bb-space-2);
785
+ gap: 0;
664
786
  margin: 0;
665
787
  padding: 0;
666
788
  list-style: none;
@@ -671,7 +793,11 @@
671
793
  gap: 4px;
672
794
  min-width: 0;
673
795
  border-bottom: 1px solid var(--bb-color-border);
674
- padding-bottom: var(--bb-space-2);
796
+ padding: var(--bb-space-2) 0;
797
+ }
798
+
799
+ .bb-pkw-dense-item:first-child {
800
+ padding-top: 0;
675
801
  }
676
802
 
677
803
  .bb-pkw-dense-item:last-child {
@@ -693,15 +819,15 @@
693
819
  font: inherit;
694
820
  font-weight: 720;
695
821
  text-align: left;
696
- text-decoration: underline;
697
- text-decoration-color: color-mix(in srgb, var(--bb-color-accent) 35%, transparent);
698
- text-underline-offset: 3px;
822
+ text-decoration: none;
699
823
  cursor: pointer;
700
824
  }
701
825
 
702
826
  .bb-pkw-dense-link:hover {
703
827
  color: var(--bb-color-accent);
828
+ text-decoration: underline;
704
829
  text-decoration-color: currentColor;
830
+ text-underline-offset: 3px;
705
831
  }
706
832
 
707
833
  .bb-pkw-dense-item-facts {
@@ -793,8 +919,12 @@
793
919
  margin: 0;
794
920
  overflow-wrap: anywhere;
795
921
  color: var(--bb-color-ink);
796
- font-size: clamp(18px, 2vw, 26px);
797
- letter-spacing: -.03em;
922
+ font-size: clamp(28px, 3vw, 36px);
923
+ font-weight: 760;
924
+ line-height: 1.1;
925
+ letter-spacing: -.05em;
926
+ word-break: keep-all;
927
+ overflow-wrap: break-word;
798
928
  }
799
929
 
800
930
  .bb-pkw-work-controls {
@@ -902,10 +1032,40 @@
902
1032
  }
903
1033
 
904
1034
  @media (max-width: 760px) {
1035
+ .bb-pkw {
1036
+ margin-top: var(--bb-space-5);
1037
+ }
1038
+
1039
+ .bb-pkw-header h2 {
1040
+ font-size: 34px;
1041
+ }
1042
+
905
1043
  .bb-pkw-dense-metrics {
906
1044
  grid-template-columns: repeat(2, minmax(0, 1fr));
907
1045
  }
908
1046
 
1047
+ .bb-pkw-dense-metric,
1048
+ .bb-pkw-dense-metric:first-child {
1049
+ padding: 14px 12px;
1050
+ }
1051
+
1052
+ .bb-pkw-dense-metric:nth-child(odd) {
1053
+ padding-left: 0;
1054
+ }
1055
+
1056
+ .bb-pkw-dense-metric:nth-child(even) {
1057
+ border-right: 0;
1058
+ padding-right: 0;
1059
+ }
1060
+
1061
+ .bb-pkw-dense-metric:nth-child(-n + 2) {
1062
+ border-bottom: 1px solid var(--bb-color-border);
1063
+ }
1064
+
1065
+ .bb-pkw-dense-metric:last-child {
1066
+ border-bottom: 0;
1067
+ }
1068
+
909
1069
  .bb-pkw-dense-grid,
910
1070
  .bb-pkw-detail-columns {
911
1071
  grid-template-columns: minmax(0, 1fr);
@@ -62,7 +62,7 @@ function normalizeContextItem(item) {
62
62
  const title = cleanName(item.title, item.name);
63
63
  if (!id || !title) return null;
64
64
  const normalized = { id, title };
65
- for (const key of ['kind', 'status', 'priority', 'summary', 'owner', 'assignee', 'dueAt', 'updatedAt', 'eventAt', 'body', 'description', 'sourceRecordId', 'relatedRecordId', 'relatedTaskId', 'sourcePath', 'provenance']) {
65
+ for (const key of ['kind', 'status', 'statusKind', 'priority', 'summary', 'owner', 'assignee', 'dueAt', 'updatedAt', 'eventAt', 'body', 'description', 'sourceRecordId', 'relatedRecordId', 'relatedTaskId', 'sourcePath', 'provenance']) {
66
66
  const value = textOrNull(item[key]);
67
67
  if (value) normalized[key] = value;
68
68
  }
@@ -338,7 +338,46 @@ function contextSectionSkeleton(doc, { title = null, message = null } = {}) {
338
338
  return group;
339
339
  }
340
340
 
341
- function renderProjectContextGroup(doc, item) {
341
+ function contextTaskDue(value) {
342
+ if (!value) return '未確認';
343
+ const date = new Date(value);
344
+ return Number.isNaN(date.getTime())
345
+ ? value
346
+ : new Intl.DateTimeFormat('ja-JP', { month: 'numeric', day: 'numeric' }).format(date);
347
+ }
348
+
349
+ function contextTaskOverdue(value, statusKind) {
350
+ if (!value || ['ok', 'fail'].includes(statusKind)) return false;
351
+ const date = new Date(value);
352
+ if (Number.isNaN(date.getTime())) return false;
353
+ const today = new Date();
354
+ date.setHours(0, 0, 0, 0);
355
+ today.setHours(0, 0, 0, 0);
356
+ return date < today;
357
+ }
358
+
359
+ function renderProjectContextTaskRow(doc, entry, onTaskOpen) {
360
+ const status = entry.status ?? '未確認';
361
+ const kind = ['ok', 'wait', 'fail'].includes(entry.statusKind) ? entry.statusKind : '';
362
+ const row = makeElement(doc, 'li', { className: 'bb-pkw-context-task-row' });
363
+ row.append(makeElement(doc, 'span', {
364
+ className: `bb-pkw-context-task-state${kind ? ` bb-pkw-context-task-${kind}` : ''}`,
365
+ attrs: { 'aria-hidden': 'true' },
366
+ }));
367
+ row.append(typeof onTaskOpen === 'function'
368
+ ? denseButton(doc, entry.title, 'bb-pkw-context-task-title', () => onTaskOpen(entry.id), { title: entry.title, 'data-item-id': entry.id })
369
+ : makeElement(doc, 'strong', { className: 'bb-pkw-context-task-title', text: entry.title, attrs: { title: entry.title } }));
370
+ row.append(makeElement(doc, 'span', { className: 'bb-pkw-context-task-owner', text: entry.owner ?? entry.assignee ?? '担当者を確認できていない' }));
371
+ row.append(makeElement(doc, 'time', {
372
+ className: `bb-pkw-context-task-due${contextTaskOverdue(entry.dueAt, kind) ? ' bb-pkw-context-task-overdue' : ''}`,
373
+ text: contextTaskDue(entry.dueAt),
374
+ attrs: entry.dueAt ? { datetime: entry.dueAt } : {},
375
+ }));
376
+ row.append(makeElement(doc, 'span', { className: `bb-pkw-context-task-stage${kind ? ` bb-pkw-context-task-${kind}` : ''}`, text: status }));
377
+ return row;
378
+ }
379
+
380
+ function renderProjectContextGroup(doc, item, onTaskOpen) {
342
381
  const group = makeElement(doc, 'section', {
343
382
  className: `bb-pkw-context-group${item.state === 'loading' ? ' bb-pkw-context-group-loading' : ''}`,
344
383
  attrs: { 'aria-label': item.title, ...(item.state === 'loading' ? { 'aria-busy': 'true' } : {}) },
@@ -357,8 +396,13 @@ function renderProjectContextGroup(doc, item) {
357
396
  } else if (item.state === 'unknown') {
358
397
  group.append(workspaceNotice(doc, { label: '未確認', text: item.message ?? 'このセクションの取得状態は確認できません。', tone: 'warning' }));
359
398
  } else if (item.items.length > 0) {
360
- const list = makeElement(doc, 'ul', { className: 'bb-pkw-context-list' });
399
+ const taskList = item.items.every((entry) => entry.kind === 'task');
400
+ const list = makeElement(doc, 'ul', { className: `bb-pkw-context-list${taskList ? ' bb-pkw-context-task-list' : ''}` });
361
401
  for (const entry of item.items) {
402
+ if (entry.kind === 'task') {
403
+ list.append(renderProjectContextTaskRow(doc, entry, onTaskOpen));
404
+ continue;
405
+ }
362
406
  const row = makeElement(doc, 'li');
363
407
  row.append(makeElement(doc, 'strong', { text: entry.title }));
364
408
  if (entry.status) row.append(badge(doc, entry.status, 'muted'));
@@ -385,6 +429,7 @@ export function renderProjectContext(doc, context, {
385
429
  sections: selectedSections = null,
386
430
  includeStatus = true,
387
431
  includeHeading = true,
432
+ onTaskOpen = null,
388
433
  } = {}) {
389
434
  if (!context) return null;
390
435
  const sections = Array.isArray(selectedSections)
@@ -407,7 +452,7 @@ export function renderProjectContext(doc, context, {
407
452
  section.append(makeElement(doc, 'p', { className: 'bb-pkw-muted', text: '補足情報のセクションはありません。' }));
408
453
  return section;
409
454
  }
410
- for (const item of sections) section.append(renderProjectContextGroup(doc, item));
455
+ for (const item of sections) section.append(renderProjectContextGroup(doc, item, onTaskOpen));
411
456
  return section;
412
457
  }
413
458
 
@@ -850,7 +895,7 @@ function renderOverview(doc, detail, context, edges, entities, onSelect, onConte
850
895
  columns.append(people);
851
896
  panel.append(columns);
852
897
 
853
- const contextBlock = renderProjectContext(doc, context);
898
+ const contextBlock = renderProjectContext(doc, context, { onTaskOpen: actions.openWorkDetail });
854
899
  if (contextBlock) {
855
900
  panel.append(contextBlock);
856
901
  if (typeof onContext === 'function') onContext(contextBlock, null);
@@ -1250,7 +1295,7 @@ export function createProjectKnowledgeWorkspace({
1250
1295
  render();
1251
1296
  return;
1252
1297
  }
1253
- const nextBlock = renderProjectContext(doc, currentContext);
1298
+ const nextBlock = renderProjectContext(doc, currentContext, { onTaskOpen: openWorkDetail });
1254
1299
  if (!nextBlock) {
1255
1300
  if (contextBlock?.parentNode && typeof contextBlock.parentNode.replaceChild === 'function') {
1256
1301
  const nextAnchor = projectContextInsertionAnchor(doc);