@unson/brainbase-mcp 0.10.8 → 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 +2 -2
- package/ui/project-workspace.css +114 -0
- package/ui/project-workspace.js +51 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unson/brainbase-mcp",
|
|
3
|
-
"version": "0.10.
|
|
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": "
|
|
339
|
+
"gitHead": "56b00ab769c11319de73f799e8be90a95a81b7f0"
|
|
340
340
|
}
|
package/ui/project-workspace.css
CHANGED
|
@@ -218,6 +218,120 @@
|
|
|
218
218
|
flex-basis: 100%;
|
|
219
219
|
}
|
|
220
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
|
+
|
|
221
335
|
.bb-pkw-info-grid {
|
|
222
336
|
display: grid;
|
|
223
337
|
grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
|
package/ui/project-workspace.js
CHANGED
|
@@ -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
|
|
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
|
|
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);
|