@unson/brainbase-mcp 0.41.1 → 0.41.2

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.
@@ -134,6 +134,11 @@ function normalizeLimit(value, max = MAX_LIMIT) {
134
134
  }
135
135
  return limit;
136
136
  }
137
+ // Optional list filters are only sent to the repository when they carry a value.
138
+ // An empty value must mean "no filter", never "match IS NULL".
139
+ function optionalFilter(key, value) {
140
+ return value == null ? {} : { [key]: value };
141
+ }
137
142
  function normalizeCursor(value) {
138
143
  return normalizeString(value, 'cursor', { max: 500 });
139
144
  }
@@ -885,7 +890,7 @@ export class CanonicalTaskService {
885
890
  return patch;
886
891
  }
887
892
  normalizeListFilters(filters) {
888
- const { status: _status, priority: _priority, projectCode: _projectCode, project_code: _project_code, ...canonicalFilters } = filters;
893
+ const { status: _status, priority: _priority, projectCode: _projectCode, project_code: _project_code, assigneePersonId: _assigneePersonId, dueAfter: _dueAfter, dueBefore: _dueBefore, cursor: _cursor, ...canonicalFilters } = filters;
889
894
  const statuses = normalizeCollection(filters.statuses ?? filters.status, 'statuses');
890
895
  const priorities = normalizeCollection(filters.priorities ?? filters.priority, 'priorities');
891
896
  const projectCodes = normalizeProjectCodes(filters.projectCodes ?? filters.projectCode ?? filters.project_code);
@@ -894,11 +899,11 @@ export class CanonicalTaskService {
894
899
  statuses,
895
900
  priorities,
896
901
  projectCodes,
897
- assigneePersonId: normalizeString(filters.assigneePersonId, 'assigneePersonId', { max: 200 }),
898
- dueAfter: normalizeIsoDate(filters.dueAfter, 'dueAfter'),
899
- dueBefore: normalizeIsoDate(filters.dueBefore, 'dueBefore'),
902
+ ...optionalFilter('assigneePersonId', normalizeString(filters.assigneePersonId, 'assigneePersonId', { max: 200 })),
903
+ ...optionalFilter('dueAfter', normalizeIsoDate(filters.dueAfter, 'dueAfter')),
904
+ ...optionalFilter('dueBefore', normalizeIsoDate(filters.dueBefore, 'dueBefore')),
900
905
  limit: normalizeLimit(filters.limit),
901
- cursor: normalizeCursor(filters.cursor),
906
+ ...optionalFilter('cursor', normalizeCursor(filters.cursor)),
902
907
  };
903
908
  }
904
909
  normalizeSearchFilters(filters) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unson/brainbase-mcp",
3
- "version": "0.41.1",
3
+ "version": "0.41.2",
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",
@@ -481,5 +481,5 @@
481
481
  "engines": {
482
482
  "node": ">=20"
483
483
  },
484
- "gitHead": "d89de84f6d437c564f843ee06dcdf5836a154d36"
484
+ "gitHead": "193d1d1fea9d177b04a3c6b01069aef202979526"
485
485
  }
@@ -11,7 +11,6 @@ import {
11
11
  workspaceButton,
12
12
  workspaceDefinition,
13
13
  workspaceLedger,
14
- workspaceMetrics,
15
14
  workspaceNotice,
16
15
  workspacePageHeader,
17
16
  workspaceSectionTitle,
@@ -718,11 +717,6 @@ export function renderFoundationOverview(root, state, {
718
717
  surface.append(recordContexts
719
718
  ? makeElement(doc, 'p', { className: 'bb-fov-recorded-notice', text: '記録上の現状は保存時点の記述です。登録状態と検証状態を分けて読みます。' })
720
719
  : workspaceNotice(doc, { label: '読み方', text: '登録は達成・採用・検証済みを意味しません。記録上の現状は保存時点の記述です。' }));
721
- surface.append(workspaceMetrics(doc, [
722
- { label: '目的', value: catalog.objectives.length, note: partial ? '取得済みの定義(全体は未確認)' : '登録された定義' },
723
- { label: '哲学', value: catalog.philosophies.length, note: partial ? '取得済みの版(全体は未確認)' : '登録された版' },
724
- { label: '世界モデル', value: catalog.models.length, note: partial ? '取得済みの検索対象(全体は未確認)' : '検索対象' },
725
- ], { ariaLabel: 'Foundationの登録数' }));
726
720
  surface.append(renderObjectives(doc, catalog, viewState, callbacks, recordContexts));
727
721
  surface.append(renderPhilosophies(doc, catalog, recordContexts));
728
722
  surface.append(renderModels(doc, catalog, viewState, callbacks, recordContexts));
@@ -14,7 +14,6 @@ import {
14
14
  workspaceDefinition,
15
15
  workspaceDetailEmpty,
16
16
  workspaceLedger,
17
- workspaceMetrics,
18
17
  workspaceNotice,
19
18
  workspacePageHeader,
20
19
  workspaceRailBlock,
@@ -1721,22 +1720,6 @@ export function createJudgmentHistoryUI({
1721
1720
  ? `保存された判断の理由、当時の参照、案、実行と結果を表示しています。参照の本文は現在の権限で確認できる場合だけ開きます。${normalSourceSummary ? ` 取得元: ${normalSourceSummary}` : ''}`
1722
1721
  : '判断に残った参照だけを表示しています。実行結果の証拠は参照件数に含めません。',
1723
1722
  }));
1724
- const stats = aggregate.stats ?? {};
1725
- const metricCount = (value, suffix) => value === null || value === undefined ? '未確認' : `${value}${suffix}`;
1726
- wrapper.append(workspaceMetrics(doc, normalMode() ? [
1727
- {
1728
- label: aggregate.query ? '表示対象' : aggregate.countComplete ? '判断件数' : '取得済み',
1729
- value: metricCount(aggregate.countComplete ? stats.judgments : aggregate.retrievedCount, '件'),
1730
- note: aggregate.countComplete ? 'この期間・絞り込みの全件数'
1731
- : aggregate.query ? '取得済み履歴の検索結果・全件数未確認' : '全件数未確認',
1732
- },
1733
- { label: '使った参照', value: metricCount(stats.references, '件'), note: '当時の記録にある一意の参照' },
1734
- { label: '確認済みの結果', value: metricCount(stats.confirmedOutcomes, '件'), note: '成果が確認済みと記録された判断' },
1735
- ] : [
1736
- { label: 'Brainbaseが代わりに判断した件数', value: metricCount(stats.judgments, '件'), note: 'この期間の履歴' },
1737
- { label: 'そこで使った参照', value: metricCount(stats.references, '件'), note: '代理判断に含まれる一意の参照' },
1738
- { label: '判断回数にすると', value: metricCount(stats.equivalent, '回分相当'), note: '代理判断1件を1回分として表示' },
1739
- ], { ariaLabel: '判断履歴の集計' }));
1740
1723
  const emptyText = state.home?.status === 'partial' || (normalMode() && !aggregate.countComplete)
1741
1724
  ? 'この期間に取得できた判断履歴はありません。全件数が未確認のため0件とは確認できません。'
1742
1725
  : 'この期間の判断履歴はありません。';
@@ -216,6 +216,11 @@
216
216
  .knowledge-outcome .knowledge-form-actions,
217
217
  .knowledge-outcome .knowledge-detail-actions,
218
218
  .knowledge-outcome .knowledge-lifecycle-actions { display: flex; flex-wrap: wrap; gap: .45rem; align-items: center; }
219
+ .knowledge-outcome .knowledge-lifecycle-actions > .knowledge-revision-details {
220
+ flex: 1 1 100%;
221
+ min-width: 0;
222
+ }
223
+ .knowledge-outcome .knowledge-revision-details .knowledge-lifecycle-form { width: 100%; }
219
224
  .knowledge-outcome .knowledge-filter-actions {
220
225
  grid-column: 1 / -1;
221
226
  align-self: end;
@@ -1168,7 +1168,7 @@ export function renderLifecycle(root, item, callbacks = {}) {
1168
1168
  if (canEdit && callbacks.onRevision) {
1169
1169
  const revisionDraft = callbacks.revisionDraft && typeof callbacks.revisionDraft === 'object' ? callbacks.revisionDraft : null;
1170
1170
  const draftValue = (key, fallback) => revisionDraft && Object.prototype.hasOwnProperty.call(revisionDraft, key) ? revisionDraft[key] : fallback;
1171
- const revisionDetails = makeElement('details', { className: 'knowledge-action-details' });
1171
+ const revisionDetails = makeElement('details', { className: 'knowledge-action-details knowledge-revision-details' });
1172
1172
  const summary = makeElement('summary', { text: 'この判断を改訂' });
1173
1173
  const form = makeElement('form', { className: 'knowledge-lifecycle-form' });
1174
1174
  const title = makeElement('input', { className: 'knowledge-control', value: draftValue('title', item.title ?? ''), attrs: { name: 'title', maxlength: '240', required: 'required' } });
@@ -1017,10 +1017,18 @@ export function createDistrictView({ doc, stage, reducedMotion = false, focusSel
1017
1017
  }
1018
1018
 
1019
1019
  let running = true;
1020
+ let lastSkyMinute = -1;
1020
1021
  function frame(time) {
1021
1022
  if (!running) return;
1022
1023
  requestAnimationFrame(frame);
1023
1024
  if (!open) return;
1025
+ // Use wall time so an open district also catches up after a suspended tab.
1026
+ const now = new Date();
1027
+ const minute = Math.floor(now.getTime() / 60_000);
1028
+ if (skyMode === 'auto' && minute !== lastSkyMinute) {
1029
+ if (skyAt(now.getHours(), 'auto').phase !== sky.phase) applySky();
1030
+ lastSkyMinute = minute;
1031
+ }
1024
1032
  if (flight) {
1025
1033
  flight.started ??= time;
1026
1034
  const t = Math.min((time - flight.started) / flight.duration, 1);