@unson/brainbase-mcp 0.19.0 → 0.21.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/dist/canonical-task-service.d.ts +4 -0
- package/dist/canonical-task-service.js +14 -0
- package/dist/local-web-host.js +1 -0
- package/dist/world-extension.d.ts +1 -1
- package/dist/world-extension.js +10 -1
- package/dist/world-work.d.ts +248 -0
- package/dist/world-work.js +558 -0
- package/package.json +3 -2
- package/ui/project-overview.js +263 -0
- package/ui/project-workspace.css +175 -0
- package/ui/project-workspace.js +38 -3
- package/ui/world/world-district.js +642 -0
- package/ui/world/world-placement.js +60 -0
- package/ui/world/world-view.css +237 -0
- package/ui/world/world-view.js +546 -47
- package/ui/world/world-work-rail.js +337 -0
|
@@ -133,3 +133,63 @@ export function changesSince(lastVisit, businesses, judgmentsByBusiness, rows) {
|
|
|
133
133
|
const plaza = (rows ?? []).filter((row) => newer(row.latest_recorded_at)).map((row) => row.key);
|
|
134
134
|
return { since: new Date(since).toISOString(), cities, plaza };
|
|
135
135
|
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* The lots inside a district (story-world-work-sites-and-gaps-v1, AC-12, AC-16, AC-17): a main street along
|
|
139
|
+
* z, a back street on each side, and lots facing them in four columns. Work with the same `purpose_label`
|
|
140
|
+
* stands in one block (a street of its own); blocks run from the hall toward the gate in the order of their
|
|
141
|
+
* oldest task, and work with no label stands last, by the gate. Inside a block the lots fill in order of
|
|
142
|
+
* creation (`created_at`, then id), row by row: left front, right front, left back, right back. So a new
|
|
143
|
+
* task never moves an older one and a change of state never moves any; only when a block's rows are full do
|
|
144
|
+
* the blocks after it shift one row toward the gate. A cross street separates the blocks.
|
|
145
|
+
* Returns `{ lots: { [taskId]: { x, z, facing, street } }, streets: [{ key, label, count, z_from, z_to }],
|
|
146
|
+
* rows, length }`, `facing` being +1 when the lot's front looks toward +x, `label` null for the unlabelled.
|
|
147
|
+
*/
|
|
148
|
+
export const DISTRICT_STREETS = Object.freeze({ main: 2, frontLot: 4, backStreet: 7, backLot: 10, lot: 2.8, row: 3.4, cross: 2.6 });
|
|
149
|
+
|
|
150
|
+
const LOT_COLUMNS = Object.freeze([
|
|
151
|
+
{ x: -DISTRICT_STREETS.frontLot, facing: 1 },
|
|
152
|
+
{ x: DISTRICT_STREETS.frontLot, facing: -1 },
|
|
153
|
+
{ x: -DISTRICT_STREETS.backLot, facing: 1 },
|
|
154
|
+
{ x: DISTRICT_STREETS.backLot, facing: -1 },
|
|
155
|
+
]);
|
|
156
|
+
|
|
157
|
+
function byCreation(a, b) {
|
|
158
|
+
const at = String(a.created_at ?? '').localeCompare(String(b.created_at ?? ''));
|
|
159
|
+
return at !== 0 ? at : String(a.task_id).localeCompare(String(b.task_id));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export function districtStreetLots(sites, { minRows = 4 } = {}) {
|
|
163
|
+
const groups = new Map();
|
|
164
|
+
for (const site of sites ?? []) {
|
|
165
|
+
const label = typeof site.purpose_label === 'string' && site.purpose_label.trim() ? site.purpose_label.trim() : null;
|
|
166
|
+
const key = label ?? '';
|
|
167
|
+
if (!groups.has(key)) groups.set(key, { key, label, sites: [] });
|
|
168
|
+
groups.get(key).sites.push(site);
|
|
169
|
+
}
|
|
170
|
+
const blocks = [...groups.values()].map((group) => ({ ...group, sites: group.sites.sort(byCreation) }));
|
|
171
|
+
blocks.sort((a, b) => {
|
|
172
|
+
if ((a.label === null) !== (b.label === null)) return a.label === null ? 1 : -1;
|
|
173
|
+
const first = byCreation(a.sites[0], b.sites[0]);
|
|
174
|
+
return first !== 0 ? first : a.key.localeCompare(b.key);
|
|
175
|
+
});
|
|
176
|
+
const rowsOf = (block) => Math.max(1, Math.ceil(block.sites.length / LOT_COLUMNS.length));
|
|
177
|
+
const rows = blocks.reduce((sum, block) => sum + rowsOf(block), 0);
|
|
178
|
+
const used = rows * DISTRICT_STREETS.row + Math.max(0, blocks.length - 1) * DISTRICT_STREETS.cross;
|
|
179
|
+
const length = Math.max(used, minRows * DISTRICT_STREETS.row);
|
|
180
|
+
const round = (value) => Math.round(value * 100) / 100;
|
|
181
|
+
const lots = {};
|
|
182
|
+
const streets = [];
|
|
183
|
+
let cursor = -used / 2;
|
|
184
|
+
for (const block of blocks) {
|
|
185
|
+
const blockRows = rowsOf(block);
|
|
186
|
+
block.sites.forEach((site, index) => {
|
|
187
|
+
const row = Math.floor(index / LOT_COLUMNS.length);
|
|
188
|
+
const column = LOT_COLUMNS[index % LOT_COLUMNS.length];
|
|
189
|
+
lots[site.task_id] = { x: column.x, z: round(cursor + (row + 0.5) * DISTRICT_STREETS.row), facing: column.facing, street: block.key };
|
|
190
|
+
});
|
|
191
|
+
streets.push({ key: block.key, label: block.label, count: block.sites.length, z_from: round(cursor), z_to: round(cursor + blockRows * DISTRICT_STREETS.row) });
|
|
192
|
+
cursor += blockRows * DISTRICT_STREETS.row + DISTRICT_STREETS.cross;
|
|
193
|
+
}
|
|
194
|
+
return { lots, streets, rows, length };
|
|
195
|
+
}
|
package/ui/world/world-view.css
CHANGED
|
@@ -149,6 +149,20 @@
|
|
|
149
149
|
border-color: var(--bb-color-rail-border);
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
+
.bb-world-label.is-street {
|
|
153
|
+
font-weight: 700;
|
|
154
|
+
background: #2f6e4f;
|
|
155
|
+
border-color: #255a40;
|
|
156
|
+
color: #ffffff;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.bb-world-label.is-street.is-unlabelled {
|
|
160
|
+
background: #f1ece1;
|
|
161
|
+
border-style: dashed;
|
|
162
|
+
border-color: #8a8270;
|
|
163
|
+
color: #5c5546;
|
|
164
|
+
}
|
|
165
|
+
|
|
152
166
|
.bb-world-label.is-engagement {
|
|
153
167
|
font-size: 11px;
|
|
154
168
|
color: var(--bb-color-muted);
|
|
@@ -232,3 +246,226 @@
|
|
|
232
246
|
text-decoration: underline;
|
|
233
247
|
text-underline-offset: 2px;
|
|
234
248
|
}
|
|
249
|
+
|
|
250
|
+
/* --- the work inside a city (story-world-work-sites-and-gaps-v1) --------- */
|
|
251
|
+
.bb-world-legend.is-work {
|
|
252
|
+
bottom: calc(var(--bb-space-3) + 34px);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.bb-world-legend[hidden] {
|
|
256
|
+
display: none;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.bb-world-chip.is-work-waiting::before { background: #7a6a9e; }
|
|
260
|
+
.bb-world-chip.is-work-in_progress::before { background: #2f7d86; }
|
|
261
|
+
.bb-world-chip.is-work-pending::before { background: #8d979e; }
|
|
262
|
+
.bb-world-chip.is-sign::before { background: #e3a21a; }
|
|
263
|
+
.bb-world-chip.is-ring::before { background: transparent; border: 2px dashed #5b4a8a; border-radius: 50%; width: 8px; height: 8px; }
|
|
264
|
+
.bb-world-chip.is-road::before { background: #1261ad; height: 3px; width: 14px; border-radius: 0; }
|
|
265
|
+
|
|
266
|
+
.bb-world-badge {
|
|
267
|
+
display: inline-block;
|
|
268
|
+
margin-left: 6px;
|
|
269
|
+
padding: 0 6px;
|
|
270
|
+
border-radius: 999px;
|
|
271
|
+
font-size: 11px;
|
|
272
|
+
font-weight: 700;
|
|
273
|
+
line-height: 1.5;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.bb-world-badge.is-check {
|
|
277
|
+
background: #fbe7bd;
|
|
278
|
+
color: #7a5200;
|
|
279
|
+
border: 1px solid #e3a21a;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.bb-world-badge.is-unreadable {
|
|
283
|
+
background: #eceeef;
|
|
284
|
+
color: #4b524e;
|
|
285
|
+
border: 1px dashed #8a9096;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.bb-world-label.is-site {
|
|
289
|
+
font-size: 10px;
|
|
290
|
+
padding: 1px 5px;
|
|
291
|
+
color: var(--bb-color-muted);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.bb-world-label.is-site.is-check {
|
|
295
|
+
border-color: #e3a21a;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.bb-world-label.is-link {
|
|
299
|
+
font-size: 11px;
|
|
300
|
+
background: rgb(255 255 255 / 92%);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.bb-world-label.is-link.is-recorded {
|
|
304
|
+
border-color: #1261ad;
|
|
305
|
+
color: #0d4a85;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.bb-world-label.is-link.is-inferred {
|
|
309
|
+
border-style: dashed;
|
|
310
|
+
border-color: #7a6a9e;
|
|
311
|
+
color: #4d3f75;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.bb-world-rail-list.is-plain,
|
|
315
|
+
.bb-world-rail-list.is-links {
|
|
316
|
+
list-style: none;
|
|
317
|
+
padding-left: 0;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.bb-world-link {
|
|
321
|
+
display: grid;
|
|
322
|
+
grid-template-columns: 1.4em 1fr;
|
|
323
|
+
column-gap: 4px;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.bb-world-link .bb-world-rail-note {
|
|
327
|
+
grid-column: 2;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
.bb-world-link-mark {
|
|
331
|
+
font-weight: 700;
|
|
332
|
+
color: #1261ad;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.bb-world-link.is-inferred .bb-world-link-mark { color: #7a6a9e; }
|
|
336
|
+
.bb-world-link.is-unreadable .bb-world-link-mark { color: #8a9096; }
|
|
337
|
+
.bb-world-link.is-unreadable > span:not(.bb-world-link-mark) { color: var(--bb-color-muted); }
|
|
338
|
+
|
|
339
|
+
.bb-world-rail-pick {
|
|
340
|
+
font: inherit;
|
|
341
|
+
font-size: 13px;
|
|
342
|
+
text-align: left;
|
|
343
|
+
padding: 2px 0;
|
|
344
|
+
border: 0;
|
|
345
|
+
background: none;
|
|
346
|
+
color: var(--bb-color-accent);
|
|
347
|
+
text-decoration: underline;
|
|
348
|
+
text-underline-offset: 2px;
|
|
349
|
+
cursor: pointer;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.bb-world-rail-pick:disabled {
|
|
353
|
+
color: var(--bb-color-ink);
|
|
354
|
+
text-decoration: none;
|
|
355
|
+
cursor: default;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.bb-world-rail-pick.is-gap {
|
|
359
|
+
color: #7a5200;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.bb-world-swatch {
|
|
363
|
+
display: inline-block;
|
|
364
|
+
width: 10px;
|
|
365
|
+
height: 10px;
|
|
366
|
+
margin-right: 6px;
|
|
367
|
+
border-radius: 3px;
|
|
368
|
+
background: var(--bb-color-quiet);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
.bb-world-swatch.is-waiting { background: #7a6a9e; }
|
|
372
|
+
.bb-world-swatch.is-in_progress { background: #2f7d86; }
|
|
373
|
+
.bb-world-swatch.is-pending { background: #8d979e; }
|
|
374
|
+
.bb-world-swatch.is-completed { background: #6f9a68; }
|
|
375
|
+
.bb-world-swatch.is-cancelled { background: #b9b2a5; }
|
|
376
|
+
|
|
377
|
+
.bb-world-rail-sub {
|
|
378
|
+
margin: var(--bb-space-2) 0 4px;
|
|
379
|
+
font-size: 12px;
|
|
380
|
+
color: var(--bb-color-muted);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
.bb-world-rail-caveat.is-quiet {
|
|
384
|
+
color: var(--bb-color-muted);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.bb-world-gap {
|
|
388
|
+
padding: 8px 10px;
|
|
389
|
+
margin-bottom: 8px;
|
|
390
|
+
border-left: 3px solid #e3a21a;
|
|
391
|
+
background: rgb(251 231 189 / 35%);
|
|
392
|
+
border-radius: 4px;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.bb-world-gap h4 {
|
|
396
|
+
margin: 0 0 4px;
|
|
397
|
+
font-size: 13px;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
.bb-world-original p {
|
|
401
|
+
white-space: pre-wrap;
|
|
402
|
+
font-size: 12px;
|
|
403
|
+
color: var(--bb-color-muted);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.bb-world-hud[hidden] {
|
|
407
|
+
display: none;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/* --- inside a district (AC-11〜15) ---------------------------------------- */
|
|
411
|
+
.bb-world-canvas[hidden],
|
|
412
|
+
.bb-world-labels[hidden] {
|
|
413
|
+
display: none;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.bb-world-district-legend {
|
|
417
|
+
position: absolute;
|
|
418
|
+
left: var(--bb-space-3);
|
|
419
|
+
bottom: var(--bb-space-3);
|
|
420
|
+
z-index: 3;
|
|
421
|
+
width: min(600px, calc(100% - 2 * var(--bb-space-3)));
|
|
422
|
+
box-sizing: border-box;
|
|
423
|
+
padding: 6px 10px;
|
|
424
|
+
border: 1px solid var(--bb-color-border);
|
|
425
|
+
border-radius: 8px;
|
|
426
|
+
background: rgb(255 255 255 / 92%);
|
|
427
|
+
font-size: 12px;
|
|
428
|
+
color: var(--bb-color-ink);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
.bb-world-district-legend[hidden] {
|
|
432
|
+
display: none;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.bb-world-district-legend summary {
|
|
436
|
+
cursor: pointer;
|
|
437
|
+
font-weight: 700;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
.bb-world-district-legend ul {
|
|
441
|
+
margin: 6px 0 0;
|
|
442
|
+
padding: 0;
|
|
443
|
+
list-style: none;
|
|
444
|
+
display: grid;
|
|
445
|
+
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
|
|
446
|
+
gap: 2px 14px;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
.bb-world-district-legend li.is-ambience {
|
|
450
|
+
grid-column: 1 / -1;
|
|
451
|
+
color: var(--bb-color-muted);
|
|
452
|
+
margin-top: 4px;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.bb-world-district-notice {
|
|
456
|
+
position: absolute;
|
|
457
|
+
top: var(--bb-space-3);
|
|
458
|
+
left: 50%;
|
|
459
|
+
transform: translateX(-50%);
|
|
460
|
+
z-index: 3;
|
|
461
|
+
margin: 0;
|
|
462
|
+
padding: 8px 14px;
|
|
463
|
+
border-radius: 8px;
|
|
464
|
+
background: rgb(255 240 199 / 95%);
|
|
465
|
+
border-left: 3px solid var(--bb-color-warning);
|
|
466
|
+
font-size: 13px;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
.bb-world-district-notice[hidden] {
|
|
470
|
+
display: none;
|
|
471
|
+
}
|