@validation-os/dashboard 0.8.0 → 0.10.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/index.d.ts +193 -11
- package/dist/index.js +1156 -572
- package/dist/index.js.map +1 -1
- package/dist/styles.css +255 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/dashboard-app.tsx
|
|
4
|
-
import { useCallback as useCallback5, useEffect as useEffect6, useState as
|
|
4
|
+
import { useCallback as useCallback5, useEffect as useEffect6, useState as useState14 } from "react";
|
|
5
5
|
|
|
6
6
|
// src/labels.ts
|
|
7
7
|
var REGISTER_LABEL = {
|
|
@@ -49,14 +49,63 @@ var REGISTER_GROUPS = [
|
|
|
49
49
|
];
|
|
50
50
|
var WORKFLOW_NAV = [
|
|
51
51
|
{ route: "next", label: "Next move", icon: "\u25C8", isDefault: true },
|
|
52
|
-
{ route: "
|
|
52
|
+
{ route: "stage-grid", label: "Lens \xD7 Stage", icon: "\u25A6" },
|
|
53
|
+
{ route: "pipeline", label: "Pipeline", icon: "\u25A4" }
|
|
53
54
|
];
|
|
54
55
|
|
|
55
56
|
// src/next-move.ts
|
|
56
57
|
import {
|
|
57
58
|
isConcluded
|
|
58
59
|
} from "@validation-os/core/derivation";
|
|
59
|
-
|
|
60
|
+
|
|
61
|
+
// src/derived-views.ts
|
|
62
|
+
var KILL_ZONE = -50;
|
|
63
|
+
function readingBeliefs(r) {
|
|
64
|
+
return Array.isArray(r.beliefs) ? r.beliefs : [];
|
|
65
|
+
}
|
|
66
|
+
function readingBeliefFor(r, assumptionId) {
|
|
67
|
+
return readingBeliefs(r).find((b) => b.assumptionId === assumptionId);
|
|
68
|
+
}
|
|
69
|
+
function readingGrades(r, assumptionId) {
|
|
70
|
+
return readingBeliefFor(r, assumptionId) !== void 0;
|
|
71
|
+
}
|
|
72
|
+
function isArchivedExperiment(e) {
|
|
73
|
+
return str(e.Status) === "Archived";
|
|
74
|
+
}
|
|
75
|
+
function liveExperiments(experiments) {
|
|
76
|
+
return experiments.filter((e) => !isArchivedExperiment(e));
|
|
77
|
+
}
|
|
78
|
+
function str(v) {
|
|
79
|
+
return typeof v === "string" && v !== "" ? v : null;
|
|
80
|
+
}
|
|
81
|
+
function derivedNum(r, key) {
|
|
82
|
+
const v = r.derived?.[key];
|
|
83
|
+
return typeof v === "number" ? v : null;
|
|
84
|
+
}
|
|
85
|
+
function strList(v) {
|
|
86
|
+
return Array.isArray(v) ? v.filter((x) => typeof x === "string") : [];
|
|
87
|
+
}
|
|
88
|
+
function testsAssumption(exp, assumptionId) {
|
|
89
|
+
const bars = exp.barLines;
|
|
90
|
+
if (bars?.some((b) => b.assumptionId === assumptionId)) return true;
|
|
91
|
+
return strList(exp.barLineAssumptionIds).includes(assumptionId);
|
|
92
|
+
}
|
|
93
|
+
function hasOpenBarOn(exp, assumptionId) {
|
|
94
|
+
const bars = exp.barLines;
|
|
95
|
+
return bars?.some((b) => b.assumptionId === assumptionId && b.barVerdict == null) ?? false;
|
|
96
|
+
}
|
|
97
|
+
function inKillLane(a) {
|
|
98
|
+
return str(a.Status) === "Live" && (derivedNum(a, "confidence") ?? 0) <= KILL_ZONE;
|
|
99
|
+
}
|
|
100
|
+
function isTesting(a, experiments) {
|
|
101
|
+
if (str(a.Status) !== "Live") return false;
|
|
102
|
+
return experiments.some(
|
|
103
|
+
(e) => str(e.Status) === "Running" && hasOpenBarOn(e, a.id)
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// src/next-move.ts
|
|
108
|
+
function str2(record, key) {
|
|
60
109
|
const v = record[key];
|
|
61
110
|
return typeof v === "string" ? v : null;
|
|
62
111
|
}
|
|
@@ -71,13 +120,11 @@ function idList(record, key) {
|
|
|
71
120
|
function toNextMoveInput(records) {
|
|
72
121
|
const concludedByAssumption = /* @__PURE__ */ new Map();
|
|
73
122
|
for (const r of records.readings) {
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
const result = str(r, "Result");
|
|
77
|
-
if (result && isConcluded(result)) {
|
|
123
|
+
for (const b of readingBeliefs(r)) {
|
|
124
|
+
if (!b.assumptionId || !isConcluded(b.Result)) continue;
|
|
78
125
|
concludedByAssumption.set(
|
|
79
|
-
assumptionId,
|
|
80
|
-
(concludedByAssumption.get(assumptionId) ?? 0) + 1
|
|
126
|
+
b.assumptionId,
|
|
127
|
+
(concludedByAssumption.get(b.assumptionId) ?? 0) + 1
|
|
81
128
|
);
|
|
82
129
|
}
|
|
83
130
|
}
|
|
@@ -86,8 +133,8 @@ function toNextMoveInput(records) {
|
|
|
86
133
|
const derived = a.derived && typeof a.derived === "object" ? a.derived : {};
|
|
87
134
|
return {
|
|
88
135
|
id: a.id,
|
|
89
|
-
title:
|
|
90
|
-
status:
|
|
136
|
+
title: str2(a, "Title") ?? a.id,
|
|
137
|
+
status: str2(a, "Status") ?? "",
|
|
91
138
|
impact: numOrNull(a, "Impact"),
|
|
92
139
|
moot: a.moot === true,
|
|
93
140
|
risk: typeof derived.risk === "number" ? derived.risk : 0,
|
|
@@ -96,12 +143,12 @@ function toNextMoveInput(records) {
|
|
|
96
143
|
};
|
|
97
144
|
}),
|
|
98
145
|
experiments: records.experiments.map((e) => ({
|
|
99
|
-
status:
|
|
100
|
-
feasibility:
|
|
146
|
+
status: str2(e, "Status") ?? "",
|
|
147
|
+
feasibility: str2(e, "Feasibility") ?? null,
|
|
101
148
|
assumptionIds: idList(e, "barLineAssumptionIds")
|
|
102
149
|
})),
|
|
103
150
|
decisions: records.decisions.map((d) => ({
|
|
104
|
-
status:
|
|
151
|
+
status: str2(d, "Status") ?? "",
|
|
105
152
|
assumptionIds: [...idList(d, "basedOnIds"), ...idList(d, "resolvesIds")]
|
|
106
153
|
}))
|
|
107
154
|
};
|
|
@@ -292,7 +339,7 @@ function sparklineY(value, height, lo, hi) {
|
|
|
292
339
|
// src/pipeline.ts
|
|
293
340
|
import {
|
|
294
341
|
assumptionCompleteness,
|
|
295
|
-
|
|
342
|
+
readingBeliefInputs
|
|
296
343
|
} from "@validation-os/core";
|
|
297
344
|
import {
|
|
298
345
|
beliefRisk,
|
|
@@ -306,7 +353,7 @@ function num(v) {
|
|
|
306
353
|
const n = Number(v);
|
|
307
354
|
return Number.isFinite(n) ? n : 0;
|
|
308
355
|
}
|
|
309
|
-
function
|
|
356
|
+
function str3(v) {
|
|
310
357
|
return typeof v === "string" ? v : "";
|
|
311
358
|
}
|
|
312
359
|
function derivedOf(rec) {
|
|
@@ -346,7 +393,9 @@ function nextMove(stage, killZone) {
|
|
|
346
393
|
}
|
|
347
394
|
}
|
|
348
395
|
function buildPipeline(assumptions, experiments) {
|
|
349
|
-
const tests = beliefTestMeters(
|
|
396
|
+
const tests = beliefTestMeters(
|
|
397
|
+
liveExperiments(experiments).map(toStageExperimentInput)
|
|
398
|
+
);
|
|
350
399
|
const rows = [];
|
|
351
400
|
const resolved = [];
|
|
352
401
|
const portfolioInput = [];
|
|
@@ -367,7 +416,7 @@ function buildPipeline(assumptions, experiments) {
|
|
|
367
416
|
resolvedRetired += retired;
|
|
368
417
|
resolved.push({
|
|
369
418
|
id: a.id,
|
|
370
|
-
statement:
|
|
419
|
+
statement: str3(a.Title),
|
|
371
420
|
kind,
|
|
372
421
|
retired
|
|
373
422
|
});
|
|
@@ -382,7 +431,7 @@ function buildPipeline(assumptions, experiments) {
|
|
|
382
431
|
const stage = deriveBeliefStage({ framed, confidence: d.confidence, test });
|
|
383
432
|
rows.push({
|
|
384
433
|
id: a.id,
|
|
385
|
-
statement:
|
|
434
|
+
statement: str3(a.Title),
|
|
386
435
|
impact: d.derivedImpact,
|
|
387
436
|
risk: d.risk,
|
|
388
437
|
riskTone: riskLevel(d.risk),
|
|
@@ -407,28 +456,27 @@ function buildPipeline(assumptions, experiments) {
|
|
|
407
456
|
}
|
|
408
457
|
function weekOverWeekDelta(assumptions, readings, now) {
|
|
409
458
|
const anyDated = readings.some((r) => {
|
|
410
|
-
const t2 = Date.parse(
|
|
459
|
+
const t2 = Date.parse(str3(r.Date));
|
|
411
460
|
return !Number.isNaN(t2);
|
|
412
461
|
});
|
|
413
462
|
if (!anyDated) return null;
|
|
414
463
|
const cutoff = now.getTime() - 7 * 24 * 60 * 60 * 1e3;
|
|
415
464
|
const byAssumption = /* @__PURE__ */ new Map();
|
|
416
|
-
for (const
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
else byAssumption.set(id, [r]);
|
|
465
|
+
for (const input of readings.flatMap(readingBeliefInputs)) {
|
|
466
|
+
if (!input.assumptionId) continue;
|
|
467
|
+
const arr = byAssumption.get(input.assumptionId);
|
|
468
|
+
if (arr) arr.push(input);
|
|
469
|
+
else byAssumption.set(input.assumptionId, [input]);
|
|
422
470
|
}
|
|
423
471
|
const percentAsOf = (limit) => {
|
|
424
472
|
const inputs = assumptions.map((a) => {
|
|
425
473
|
const d = derivedOf(a);
|
|
426
|
-
const mine = (byAssumption.get(a.id) ?? []).filter((
|
|
474
|
+
const mine = (byAssumption.get(a.id) ?? []).filter((i) => {
|
|
427
475
|
if (limit === null) return true;
|
|
428
|
-
const t2 = Date.parse(
|
|
476
|
+
const t2 = Date.parse(i.date ?? "");
|
|
429
477
|
return !Number.isNaN(t2) && t2 <= limit;
|
|
430
478
|
});
|
|
431
|
-
const conf = confidence(mine
|
|
479
|
+
const conf = confidence(mine);
|
|
432
480
|
return {
|
|
433
481
|
id: a.id,
|
|
434
482
|
derivedImpact: d.derivedImpact,
|
|
@@ -514,16 +562,6 @@ var num2 = (key, label, range = {}) => ({
|
|
|
514
562
|
...range
|
|
515
563
|
});
|
|
516
564
|
var sel = (key, label, options, nullable = false) => ({ key, label, kind: "select", options, nullable });
|
|
517
|
-
var READING_RUNGS = [
|
|
518
|
-
"Opinion",
|
|
519
|
-
"Pitch-deck reaction",
|
|
520
|
-
"Anecdotal",
|
|
521
|
-
"Desk research",
|
|
522
|
-
"Survey at scale",
|
|
523
|
-
"Prototype usage",
|
|
524
|
-
"Signed intent",
|
|
525
|
-
"Paying users"
|
|
526
|
-
];
|
|
527
565
|
var SOURCE_QUALITY = ["1", "0.7", "0.5"];
|
|
528
566
|
var EDITORS = {
|
|
529
567
|
assumptions: [
|
|
@@ -562,12 +600,14 @@ var EDITORS = {
|
|
|
562
600
|
readings: [
|
|
563
601
|
t("Title", "Reading"),
|
|
564
602
|
t("Source", "Source"),
|
|
565
|
-
|
|
566
|
-
|
|
603
|
+
// Rung / Result / Magnitude band / Grading justification are PER BELIEF now
|
|
604
|
+
// (OPS-1305) — they live in each entry of `beliefs[]`, not on the row, so
|
|
605
|
+
// they are deliberately absent here rather than writing dead row-level
|
|
606
|
+
// fields. Editing a reading's per-belief scores is a deferred follow-up (a
|
|
607
|
+
// `beliefs[]` editor); this form edits only the row-level fields that remain.
|
|
567
608
|
sel("Representativeness", "Representativeness", SOURCE_QUALITY),
|
|
568
609
|
sel("Credibility", "Credibility", SOURCE_QUALITY),
|
|
569
|
-
|
|
570
|
-
area("Grading justification", "Grading justification"),
|
|
610
|
+
area("body", "Quote"),
|
|
571
611
|
t("Date", "Date")
|
|
572
612
|
],
|
|
573
613
|
decisions: [
|
|
@@ -1062,14 +1102,16 @@ var COLUMNS = {
|
|
|
1062
1102
|
],
|
|
1063
1103
|
readings: [
|
|
1064
1104
|
{ key: "Title", header: "Reading" },
|
|
1065
|
-
{ key: "
|
|
1066
|
-
{ key: "
|
|
1105
|
+
{ key: "Source", header: "Source" },
|
|
1106
|
+
{ key: "Date", header: "Date" },
|
|
1107
|
+
// The row's per-belief Result / Rung / Strength are gone (OPS-1305) — they
|
|
1108
|
+
// live in the reading detail's per-belief verdict list. The table instead
|
|
1109
|
+
// previews the quote (`body`) so a row is legible at a glance; assumption
|
|
1110
|
+
// chips (see `readingAssumptionChips`) disambiguate same-titled readings.
|
|
1067
1111
|
{
|
|
1068
|
-
key: "
|
|
1069
|
-
header: "
|
|
1070
|
-
|
|
1071
|
-
derived: true,
|
|
1072
|
-
accessor: derivedField("strength")
|
|
1112
|
+
key: "body",
|
|
1113
|
+
header: "Quote",
|
|
1114
|
+
accessor: (r) => bodyPreview(r.body)
|
|
1073
1115
|
}
|
|
1074
1116
|
],
|
|
1075
1117
|
decisions: [
|
|
@@ -1084,6 +1126,16 @@ var COLUMNS = {
|
|
|
1084
1126
|
function columnsFor(register) {
|
|
1085
1127
|
return COLUMNS[register];
|
|
1086
1128
|
}
|
|
1129
|
+
function bodyPreview(value, max = 80) {
|
|
1130
|
+
if (typeof value !== "string") return "";
|
|
1131
|
+
const oneLine = value.replace(/\s+/g, " ").trim();
|
|
1132
|
+
if (oneLine.length <= max) return oneLine;
|
|
1133
|
+
return `${oneLine.slice(0, max - 1).trimEnd()}\u2026`;
|
|
1134
|
+
}
|
|
1135
|
+
function readingAssumptionChips(record, titleById = /* @__PURE__ */ new Map()) {
|
|
1136
|
+
const ids = Array.isArray(record.assumptionIds) ? record.assumptionIds.filter((x) => typeof x === "string") : [];
|
|
1137
|
+
return ids.map((id) => titleById.get(id) ?? id);
|
|
1138
|
+
}
|
|
1087
1139
|
function cellValue(column, record) {
|
|
1088
1140
|
return column.accessor ? column.accessor(record) : record[column.key];
|
|
1089
1141
|
}
|
|
@@ -1120,7 +1172,9 @@ var FIELD_LABEL = {
|
|
|
1120
1172
|
contradictsIds: "Contradicts",
|
|
1121
1173
|
readingIds: "Readings",
|
|
1122
1174
|
assumptionId: "Assumption",
|
|
1123
|
-
|
|
1175
|
+
assumptionIds: "Beliefs",
|
|
1176
|
+
experimentId: "Evidence plan",
|
|
1177
|
+
body: "Quote",
|
|
1124
1178
|
contextLinks: "Context links",
|
|
1125
1179
|
basedOnIds: "Based on",
|
|
1126
1180
|
resolvesIds: "Resolves",
|
|
@@ -1148,13 +1202,22 @@ var META_FIELDS = /* @__PURE__ */ new Set([
|
|
|
1148
1202
|
"updatedAt",
|
|
1149
1203
|
"derived"
|
|
1150
1204
|
]);
|
|
1151
|
-
var SUPPRESSED_FIELDS = /* @__PURE__ */ new Set([
|
|
1205
|
+
var SUPPRESSED_FIELDS = /* @__PURE__ */ new Set([
|
|
1206
|
+
"barLineAssumptionIds",
|
|
1207
|
+
// A reading's `beliefs[]` is rendered as the richer per-belief verdict list
|
|
1208
|
+
// (OPS-1305), never as raw JSON in the generic row list.
|
|
1209
|
+
"beliefs",
|
|
1210
|
+
// `body` (a reading's quote / an experiment's narrative) renders as Markdown
|
|
1211
|
+
// in its own block, not as a raw-text row.
|
|
1212
|
+
"body"
|
|
1213
|
+
]);
|
|
1152
1214
|
var RELATION_TARGET = {
|
|
1153
1215
|
dependsOnIds: "assumptions",
|
|
1154
1216
|
enablesIds: "assumptions",
|
|
1155
1217
|
contradictsIds: "assumptions",
|
|
1156
1218
|
readingIds: "readings",
|
|
1157
1219
|
assumptionId: "assumptions",
|
|
1220
|
+
assumptionIds: "assumptions",
|
|
1158
1221
|
experimentId: "experiments",
|
|
1159
1222
|
basedOnIds: "assumptions",
|
|
1160
1223
|
resolvesIds: "assumptions"
|
|
@@ -1203,7 +1266,13 @@ function detailRows(register, record, related = {}) {
|
|
|
1203
1266
|
const label = fieldLabel(key);
|
|
1204
1267
|
const target = RELATION_TARGET[key];
|
|
1205
1268
|
if (target) {
|
|
1206
|
-
|
|
1269
|
+
let items = idsOf(value).map((id) => resolveItem(related, target, id));
|
|
1270
|
+
if (target === "experiments") {
|
|
1271
|
+
const archived = new Set(
|
|
1272
|
+
(related.experiments ?? []).filter((e) => isArchivedExperiment(e)).map((e) => e.id)
|
|
1273
|
+
);
|
|
1274
|
+
items = items.filter((it) => !archived.has(it.id));
|
|
1275
|
+
}
|
|
1207
1276
|
return { key, label, kind: "relation", items };
|
|
1208
1277
|
}
|
|
1209
1278
|
if (OWNER_FIELDS.has(key)) {
|
|
@@ -1436,7 +1505,7 @@ function TermLink({
|
|
|
1436
1505
|
// src/journey.ts
|
|
1437
1506
|
import {
|
|
1438
1507
|
assumptionCompleteness as assumptionCompleteness2,
|
|
1439
|
-
|
|
1508
|
+
readingBeliefInputs as readingBeliefInputs3
|
|
1440
1509
|
} from "@validation-os/core";
|
|
1441
1510
|
import {
|
|
1442
1511
|
assembleJourney,
|
|
@@ -1446,51 +1515,20 @@ import {
|
|
|
1446
1515
|
rankNextMoves
|
|
1447
1516
|
} from "@validation-os/core/derivation";
|
|
1448
1517
|
|
|
1449
|
-
// src/derived-views.ts
|
|
1450
|
-
var KILL_ZONE = -50;
|
|
1451
|
-
function str3(v) {
|
|
1452
|
-
return typeof v === "string" && v !== "" ? v : null;
|
|
1453
|
-
}
|
|
1454
|
-
function derivedNum(r, key) {
|
|
1455
|
-
const v = r.derived?.[key];
|
|
1456
|
-
return typeof v === "number" ? v : null;
|
|
1457
|
-
}
|
|
1458
|
-
function strList(v) {
|
|
1459
|
-
return Array.isArray(v) ? v.filter((x) => typeof x === "string") : [];
|
|
1460
|
-
}
|
|
1461
|
-
function testsAssumption(exp, assumptionId) {
|
|
1462
|
-
const bars = exp.barLines;
|
|
1463
|
-
if (bars?.some((b) => b.assumptionId === assumptionId)) return true;
|
|
1464
|
-
return strList(exp.barLineAssumptionIds).includes(assumptionId);
|
|
1465
|
-
}
|
|
1466
|
-
function hasOpenBarOn(exp, assumptionId) {
|
|
1467
|
-
const bars = exp.barLines;
|
|
1468
|
-
return bars?.some((b) => b.assumptionId === assumptionId && b.barVerdict == null) ?? false;
|
|
1469
|
-
}
|
|
1470
|
-
function inKillLane(a) {
|
|
1471
|
-
return str3(a.Status) === "Live" && (derivedNum(a, "confidence") ?? 0) <= KILL_ZONE;
|
|
1472
|
-
}
|
|
1473
|
-
function isTesting(a, experiments) {
|
|
1474
|
-
if (str3(a.Status) !== "Live") return false;
|
|
1475
|
-
return experiments.some(
|
|
1476
|
-
(e) => str3(e.Status) === "Running" && hasOpenBarOn(e, a.id)
|
|
1477
|
-
);
|
|
1478
|
-
}
|
|
1479
|
-
|
|
1480
1518
|
// src/cycles.ts
|
|
1481
1519
|
import {
|
|
1482
|
-
|
|
1520
|
+
readingBeliefInputs as readingBeliefInputs2
|
|
1483
1521
|
} from "@validation-os/core";
|
|
1484
1522
|
import { confidenceAttribution } from "@validation-os/core/derivation";
|
|
1485
1523
|
var DIRECT_CYCLE_KEY = "direct";
|
|
1486
1524
|
function readingDate(r) {
|
|
1487
|
-
return
|
|
1525
|
+
return str(r.Date);
|
|
1488
1526
|
}
|
|
1489
|
-
function toCycleReading(r) {
|
|
1527
|
+
function toCycleReading(r, assumptionId) {
|
|
1490
1528
|
return {
|
|
1491
1529
|
id: r.id,
|
|
1492
1530
|
date: readingDate(r),
|
|
1493
|
-
result: r
|
|
1531
|
+
result: readingBeliefFor(r, assumptionId)?.Result ?? null
|
|
1494
1532
|
};
|
|
1495
1533
|
}
|
|
1496
1534
|
function sortByDate(readings) {
|
|
@@ -1507,13 +1545,14 @@ function barVerdictFor(exp, assumptionId) {
|
|
|
1507
1545
|
return line?.barVerdict ?? null;
|
|
1508
1546
|
}
|
|
1509
1547
|
function buildCycles(assumptionId, readings, experiments) {
|
|
1510
|
-
const mine = readings.filter((r) => r
|
|
1511
|
-
const
|
|
1548
|
+
const mine = readings.filter((r) => readingGrades(r, assumptionId));
|
|
1549
|
+
const inputs = readings.flatMap(readingBeliefInputs2).filter((i) => i.assumptionId === assumptionId);
|
|
1550
|
+
const { movers } = confidenceAttribution(inputs);
|
|
1512
1551
|
const moverByKey = new Map(movers.map((m) => [m.key, m]));
|
|
1513
1552
|
const byExperiment = /* @__PURE__ */ new Map();
|
|
1514
1553
|
const direct = [];
|
|
1515
1554
|
for (const r of mine) {
|
|
1516
|
-
const expId =
|
|
1555
|
+
const expId = str(r.experimentId);
|
|
1517
1556
|
if (expId) {
|
|
1518
1557
|
const bucket = byExperiment.get(expId) ?? [];
|
|
1519
1558
|
bucket.push(r);
|
|
@@ -1524,19 +1563,24 @@ function buildCycles(assumptionId, readings, experiments) {
|
|
|
1524
1563
|
}
|
|
1525
1564
|
const experimentsById = new Map(experiments.map((e) => [e.id, e]));
|
|
1526
1565
|
const experimentIds = /* @__PURE__ */ new Set([
|
|
1527
|
-
...experiments.filter((e) => testsAssumption(e, assumptionId)).map((e) => e.id),
|
|
1528
|
-
...byExperiment.keys()
|
|
1566
|
+
...liveExperiments(experiments).filter((e) => testsAssumption(e, assumptionId)).map((e) => e.id),
|
|
1567
|
+
...[...byExperiment.keys()].filter((id) => {
|
|
1568
|
+
const e = experimentsById.get(id);
|
|
1569
|
+
return !e || !isArchivedExperiment(e);
|
|
1570
|
+
})
|
|
1529
1571
|
]);
|
|
1530
1572
|
const cycles = [...experimentIds].map((id) => {
|
|
1531
1573
|
const exp = experimentsById.get(id);
|
|
1532
|
-
const readingViews = sortByDate(
|
|
1574
|
+
const readingViews = sortByDate(
|
|
1575
|
+
(byExperiment.get(id) ?? []).map((r) => toCycleReading(r, assumptionId))
|
|
1576
|
+
);
|
|
1533
1577
|
const mover = moverByKey.get(id);
|
|
1534
|
-
const date = (exp ?
|
|
1578
|
+
const date = (exp ? str(exp.Date) : null) ?? readingViews[0]?.date ?? null;
|
|
1535
1579
|
return {
|
|
1536
1580
|
key: id,
|
|
1537
1581
|
kind: "experiment",
|
|
1538
|
-
title: exp ?
|
|
1539
|
-
status: exp ?
|
|
1582
|
+
title: exp ? str(exp.Title) : null,
|
|
1583
|
+
status: exp ? str(exp.Status) : null,
|
|
1540
1584
|
date,
|
|
1541
1585
|
barVerdict: exp ? barVerdictFor(exp, assumptionId) : null,
|
|
1542
1586
|
readings: readingViews,
|
|
@@ -1545,7 +1589,9 @@ function buildCycles(assumptionId, readings, experiments) {
|
|
|
1545
1589
|
};
|
|
1546
1590
|
});
|
|
1547
1591
|
if (direct.length > 0) {
|
|
1548
|
-
const readingViews = sortByDate(
|
|
1592
|
+
const readingViews = sortByDate(
|
|
1593
|
+
direct.map((r) => toCycleReading(r, assumptionId))
|
|
1594
|
+
);
|
|
1549
1595
|
const mover = moverByKey.get(DIRECT_CYCLE_KEY);
|
|
1550
1596
|
cycles.push({
|
|
1551
1597
|
key: DIRECT_CYCLE_KEY,
|
|
@@ -1620,21 +1666,18 @@ function buildJourney(assumptionId, records, now) {
|
|
|
1620
1666
|
if (!belief2) return null;
|
|
1621
1667
|
const derived = belief2.derived && typeof belief2.derived === "object" ? belief2.derived : {};
|
|
1622
1668
|
const confidence2 = typeof derived.confidence === "number" ? derived.confidence : 0;
|
|
1623
|
-
const
|
|
1624
|
-
|
|
1625
|
-
) ?? emptyTestMeter();
|
|
1669
|
+
const live = liveExperiments(records.experiments);
|
|
1670
|
+
const test = beliefTestMeters2(live.map(toStageExperimentInput)).get(assumptionId) ?? emptyTestMeter();
|
|
1626
1671
|
const framed = assumptionCompleteness2(belief2);
|
|
1627
1672
|
const stage = deriveBeliefStage2({ framed, confidence: confidence2, test });
|
|
1628
|
-
const
|
|
1629
|
-
|
|
1630
|
-
);
|
|
1631
|
-
const myExperiments = records.experiments.filter((e) => testsAssumption(e, assumptionId)).map((e) => ({ id: e.id, date: str4(e.Date) || str4(e.createdAt) || null }));
|
|
1673
|
+
const myReadingInputs = records.readings.flatMap(readingBeliefInputs3).filter((i) => i.assumptionId === assumptionId);
|
|
1674
|
+
const myExperiments = live.filter((e) => testsAssumption(e, assumptionId)).map((e) => ({ id: e.id, date: str4(e.Date) || str4(e.createdAt) || null }));
|
|
1632
1675
|
const events = assembleJourney({
|
|
1633
1676
|
belief: {
|
|
1634
1677
|
createdAt: str4(belief2.createdAt) || null,
|
|
1635
1678
|
impactScored: belief2.Impact != null
|
|
1636
1679
|
},
|
|
1637
|
-
readings:
|
|
1680
|
+
readings: myReadingInputs,
|
|
1638
1681
|
experiments: myExperiments,
|
|
1639
1682
|
now
|
|
1640
1683
|
}).map((event) => ({ ...event, label: labelFor(event) }));
|
|
@@ -2221,7 +2264,7 @@ function StatTile({
|
|
|
2221
2264
|
|
|
2222
2265
|
// src/understanding.ts
|
|
2223
2266
|
import {
|
|
2224
|
-
|
|
2267
|
+
readingBeliefInputs as readingBeliefInputs4
|
|
2225
2268
|
} from "@validation-os/core";
|
|
2226
2269
|
import {
|
|
2227
2270
|
confidenceAttribution as confidenceAttribution2,
|
|
@@ -2230,26 +2273,28 @@ import {
|
|
|
2230
2273
|
isConcluded as isConcluded2
|
|
2231
2274
|
} from "@validation-os/core/derivation";
|
|
2232
2275
|
function buildUnderstanding(assumption, readings, experiments) {
|
|
2233
|
-
const
|
|
2234
|
-
const inputs = mine.map(toReadingInput4);
|
|
2276
|
+
const inputs = readings.flatMap(readingBeliefInputs4).filter((i) => i.assumptionId === assumption.id);
|
|
2235
2277
|
const { confidence: confidence2, movers } = confidenceAttribution2(inputs);
|
|
2236
2278
|
const experimentsById = new Map(experiments.map((e) => [e.id, e]));
|
|
2237
2279
|
const moverByExperiment = new Map(
|
|
2238
2280
|
movers.filter((m) => m.kind === "experiment").map((m) => [m.experimentId, m])
|
|
2239
2281
|
);
|
|
2240
2282
|
const experimentIds = /* @__PURE__ */ new Set([
|
|
2241
|
-
...experiments.filter((e) => testsAssumption(e, assumption.id)).map((e) => e.id),
|
|
2242
|
-
...moverByExperiment.keys()
|
|
2283
|
+
...liveExperiments(experiments).filter((e) => testsAssumption(e, assumption.id)).map((e) => e.id),
|
|
2284
|
+
...[...moverByExperiment.keys()].filter((id) => {
|
|
2285
|
+
const e = experimentsById.get(id);
|
|
2286
|
+
return !e || !isArchivedExperiment(e);
|
|
2287
|
+
})
|
|
2243
2288
|
]);
|
|
2244
2289
|
const experimentViews = [...experimentIds].map((id) => {
|
|
2245
2290
|
const exp = experimentsById.get(id);
|
|
2246
2291
|
const mover = moverByExperiment.get(id);
|
|
2247
2292
|
const bars = exp?.barLines ?? [];
|
|
2248
2293
|
const progress = bars.length ? experimentProgress(bars) : null;
|
|
2249
|
-
const status = exp ?
|
|
2294
|
+
const status = exp ? str(exp.Status) : null;
|
|
2250
2295
|
return {
|
|
2251
2296
|
experimentId: id,
|
|
2252
|
-
title: exp ?
|
|
2297
|
+
title: exp ? str(exp.Title) : null,
|
|
2253
2298
|
status,
|
|
2254
2299
|
contribution: mover?.contribution ?? 0,
|
|
2255
2300
|
magnitude: mover?.magnitude ?? 0,
|
|
@@ -2726,42 +2771,43 @@ function JourneyColdCard({
|
|
|
2726
2771
|
}
|
|
2727
2772
|
|
|
2728
2773
|
// src/list-surface.ts
|
|
2774
|
+
function hasConcludedBelief(r) {
|
|
2775
|
+
return readingBeliefs(r).some((b) => b.Result !== "Inconclusive");
|
|
2776
|
+
}
|
|
2729
2777
|
function isProven(a, ctx) {
|
|
2730
|
-
if (
|
|
2731
|
-
const
|
|
2732
|
-
|
|
2778
|
+
if (str(a.Status) !== "Live") return false;
|
|
2779
|
+
const scores = (ctx.readings ?? []).map((r) => readingBeliefFor(r, a.id)).filter((b) => b != null && b.Result !== "Inconclusive");
|
|
2780
|
+
if (scores.length === 0) return false;
|
|
2781
|
+
const strongest = scores.reduce(
|
|
2782
|
+
(best, b) => Math.abs(b.derived?.strength ?? 0) > Math.abs(best.derived?.strength ?? 0) ? b : best
|
|
2733
2783
|
);
|
|
2734
|
-
|
|
2735
|
-
const strongest = mine.reduce(
|
|
2736
|
-
(best, r) => Math.abs(derivedNum(r, "strength") ?? 0) > Math.abs(derivedNum(best, "strength") ?? 0) ? r : best
|
|
2737
|
-
);
|
|
2738
|
-
return str3(strongest.Result) === "Validated";
|
|
2784
|
+
return strongest.Result === "Validated";
|
|
2739
2785
|
}
|
|
2740
2786
|
function isOverdue(e, ctx) {
|
|
2741
|
-
const deadline =
|
|
2742
|
-
if (!ctx.asOf || !deadline ||
|
|
2787
|
+
const deadline = str(e.Deadline);
|
|
2788
|
+
if (!ctx.asOf || !deadline || str(e.Status) !== "Running") return false;
|
|
2743
2789
|
return deadline < ctx.asOf;
|
|
2744
2790
|
}
|
|
2745
2791
|
function inTension(d, ctx) {
|
|
2746
|
-
if (
|
|
2792
|
+
if (str(d.Status) !== "Active") return false;
|
|
2747
2793
|
const based = strList(d.basedOnIds);
|
|
2748
2794
|
if (based.length === 0) return false;
|
|
2749
2795
|
const byId = new Map((ctx.assumptions ?? []).map((a) => [a.id, a]));
|
|
2750
2796
|
return based.some((id) => {
|
|
2751
2797
|
const a = byId.get(id);
|
|
2752
2798
|
if (!a) return false;
|
|
2753
|
-
return
|
|
2799
|
+
return str(a.Status) === "Invalidated" || inKillLane(a);
|
|
2754
2800
|
});
|
|
2755
2801
|
}
|
|
2756
2802
|
var ALWAYS = () => true;
|
|
2757
|
-
var byStatus = (...values) => (r) => values.includes(
|
|
2803
|
+
var byStatus = (...values) => (r) => values.includes(str(r.Status) ?? "");
|
|
2758
2804
|
var TAB_CATALOGUE = {
|
|
2759
2805
|
assumptions: [
|
|
2760
2806
|
{
|
|
2761
2807
|
id: "live",
|
|
2762
2808
|
label: "Live",
|
|
2763
2809
|
isDefault: true,
|
|
2764
|
-
predicate: (r) =>
|
|
2810
|
+
predicate: (r) => str(r.Status) === "Live" && r.moot !== true,
|
|
2765
2811
|
defaultSort: { key: "risk", dir: "desc" }
|
|
2766
2812
|
},
|
|
2767
2813
|
{
|
|
@@ -2814,12 +2860,12 @@ var TAB_CATALOGUE = {
|
|
|
2814
2860
|
{
|
|
2815
2861
|
id: "concluded",
|
|
2816
2862
|
label: "\xB1 Concluded",
|
|
2817
|
-
predicate: (r) =>
|
|
2863
|
+
predicate: (r) => hasConcludedBelief(r)
|
|
2818
2864
|
},
|
|
2819
2865
|
{
|
|
2820
2866
|
id: "inconclusive",
|
|
2821
2867
|
label: "Inconclusive",
|
|
2822
|
-
predicate: (r) =>
|
|
2868
|
+
predicate: (r) => !hasConcludedBelief(r)
|
|
2823
2869
|
}
|
|
2824
2870
|
],
|
|
2825
2871
|
decisions: [
|
|
@@ -2908,7 +2954,7 @@ function groupRecords(records, axis) {
|
|
|
2908
2954
|
if (values.length === 0) push(emptyLabel, r);
|
|
2909
2955
|
else for (const v of values) push(v, r);
|
|
2910
2956
|
} else {
|
|
2911
|
-
push(
|
|
2957
|
+
push(str(r[axis]) ?? emptyLabel, r);
|
|
2912
2958
|
}
|
|
2913
2959
|
}
|
|
2914
2960
|
return order.map((key) => ({ key, label: key, records: buckets.get(key) }));
|
|
@@ -2917,7 +2963,7 @@ function filterRecords(records, query) {
|
|
|
2917
2963
|
const q = query.trim().toLowerCase();
|
|
2918
2964
|
if (!q) return records;
|
|
2919
2965
|
return records.filter((r) => {
|
|
2920
|
-
const hay = `${
|
|
2966
|
+
const hay = `${str(r.Title) ?? ""} ${str(r.Description) ?? ""} ${str(r.Source) ?? ""}`.toLowerCase();
|
|
2921
2967
|
return hay.includes(q);
|
|
2922
2968
|
});
|
|
2923
2969
|
}
|
|
@@ -2943,11 +2989,11 @@ function sortRecords(records, sort) {
|
|
|
2943
2989
|
}).map((x) => x.r);
|
|
2944
2990
|
}
|
|
2945
2991
|
function nestReadingsByPlan(readings, experiments) {
|
|
2946
|
-
const titleById = new Map(experiments.map((e) => [e.id,
|
|
2992
|
+
const titleById = new Map(experiments.map((e) => [e.id, str(e.Title)]));
|
|
2947
2993
|
const order = [];
|
|
2948
2994
|
const groups = /* @__PURE__ */ new Map();
|
|
2949
2995
|
for (const r of readings) {
|
|
2950
|
-
const key =
|
|
2996
|
+
const key = str(r.experimentId);
|
|
2951
2997
|
if (!groups.has(key)) {
|
|
2952
2998
|
groups.set(key, []);
|
|
2953
2999
|
order.push(key);
|
|
@@ -2991,6 +3037,149 @@ function needsHumanCounts(ctx) {
|
|
|
2991
3037
|
};
|
|
2992
3038
|
}
|
|
2993
3039
|
|
|
3040
|
+
// src/markdown.tsx
|
|
3041
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
3042
|
+
function Markdown({ text }) {
|
|
3043
|
+
const trimmed = (text ?? "").trim();
|
|
3044
|
+
if (!trimmed) return null;
|
|
3045
|
+
return /* @__PURE__ */ jsx9("div", { className: "vos-md", children: renderBlocks(trimmed) });
|
|
3046
|
+
}
|
|
3047
|
+
function renderBlocks(text) {
|
|
3048
|
+
const lines = text.replace(/\r\n?/g, "\n").split("\n");
|
|
3049
|
+
const out = [];
|
|
3050
|
+
let i = 0;
|
|
3051
|
+
let key = 0;
|
|
3052
|
+
while (i < lines.length) {
|
|
3053
|
+
const line = lines[i];
|
|
3054
|
+
if (line.trim() === "") {
|
|
3055
|
+
i += 1;
|
|
3056
|
+
continue;
|
|
3057
|
+
}
|
|
3058
|
+
const fence = line.match(/^```/);
|
|
3059
|
+
if (fence) {
|
|
3060
|
+
const body = [];
|
|
3061
|
+
i += 1;
|
|
3062
|
+
while (i < lines.length && !/^```/.test(lines[i])) {
|
|
3063
|
+
body.push(lines[i]);
|
|
3064
|
+
i += 1;
|
|
3065
|
+
}
|
|
3066
|
+
i += 1;
|
|
3067
|
+
out.push(
|
|
3068
|
+
/* @__PURE__ */ jsx9("pre", { className: "vos-md-pre", children: /* @__PURE__ */ jsx9("code", { children: body.join("\n") }) }, key++)
|
|
3069
|
+
);
|
|
3070
|
+
continue;
|
|
3071
|
+
}
|
|
3072
|
+
const heading = line.match(/^(#{1,6})\s+(.*)$/);
|
|
3073
|
+
if (heading) {
|
|
3074
|
+
const level = heading[1].length;
|
|
3075
|
+
const Tag = `h${Math.min(level + 2, 6)}`;
|
|
3076
|
+
out.push(/* @__PURE__ */ jsx9(Tag, { children: renderInline(heading[2]) }, key++));
|
|
3077
|
+
i += 1;
|
|
3078
|
+
continue;
|
|
3079
|
+
}
|
|
3080
|
+
if (/^>\s?/.test(line)) {
|
|
3081
|
+
const quote = [];
|
|
3082
|
+
while (i < lines.length && /^>\s?/.test(lines[i])) {
|
|
3083
|
+
quote.push(lines[i].replace(/^>\s?/, ""));
|
|
3084
|
+
i += 1;
|
|
3085
|
+
}
|
|
3086
|
+
out.push(
|
|
3087
|
+
/* @__PURE__ */ jsx9("blockquote", { className: "vos-md-quote", children: renderBlocks(quote.join("\n")) }, key++)
|
|
3088
|
+
);
|
|
3089
|
+
continue;
|
|
3090
|
+
}
|
|
3091
|
+
if (/^[-*+]\s+/.test(line)) {
|
|
3092
|
+
const items = [];
|
|
3093
|
+
while (i < lines.length && /^[-*+]\s+/.test(lines[i])) {
|
|
3094
|
+
items.push(lines[i].replace(/^[-*+]\s+/, ""));
|
|
3095
|
+
i += 1;
|
|
3096
|
+
}
|
|
3097
|
+
out.push(
|
|
3098
|
+
/* @__PURE__ */ jsx9("ul", { className: "vos-md-ul", children: items.map((it, n) => /* @__PURE__ */ jsx9("li", { children: renderInline(it) }, n)) }, key++)
|
|
3099
|
+
);
|
|
3100
|
+
continue;
|
|
3101
|
+
}
|
|
3102
|
+
if (/^\d+\.\s+/.test(line)) {
|
|
3103
|
+
const items = [];
|
|
3104
|
+
while (i < lines.length && /^\d+\.\s+/.test(lines[i])) {
|
|
3105
|
+
items.push(lines[i].replace(/^\d+\.\s+/, ""));
|
|
3106
|
+
i += 1;
|
|
3107
|
+
}
|
|
3108
|
+
out.push(
|
|
3109
|
+
/* @__PURE__ */ jsx9("ol", { className: "vos-md-ol", children: items.map((it, n) => /* @__PURE__ */ jsx9("li", { children: renderInline(it) }, n)) }, key++)
|
|
3110
|
+
);
|
|
3111
|
+
continue;
|
|
3112
|
+
}
|
|
3113
|
+
const para = [];
|
|
3114
|
+
while (i < lines.length && lines[i].trim() !== "" && !/^```|^#{1,6}\s|^>\s?|^[-*+]\s+|^\d+\.\s+/.test(lines[i])) {
|
|
3115
|
+
para.push(lines[i]);
|
|
3116
|
+
i += 1;
|
|
3117
|
+
}
|
|
3118
|
+
out.push(/* @__PURE__ */ jsx9("p", { children: renderInline(para.join(" ")) }, key++));
|
|
3119
|
+
}
|
|
3120
|
+
return out;
|
|
3121
|
+
}
|
|
3122
|
+
function safeHref(href) {
|
|
3123
|
+
if (/^(https?:\/\/|mailto:)/i.test(href)) return href;
|
|
3124
|
+
if (/^[#/]/.test(href)) return href;
|
|
3125
|
+
return null;
|
|
3126
|
+
}
|
|
3127
|
+
var INLINE_RULES = [
|
|
3128
|
+
// Inline code first — its contents are literal.
|
|
3129
|
+
{
|
|
3130
|
+
re: /`([^`]+)`/,
|
|
3131
|
+
render: (m, key) => /* @__PURE__ */ jsx9("code", { className: "vos-md-code", children: m[1] }, key),
|
|
3132
|
+
recurse: false
|
|
3133
|
+
},
|
|
3134
|
+
// Links: [text](href)
|
|
3135
|
+
{
|
|
3136
|
+
re: /\[([^\]]+)\]\(([^)\s]+)\)/,
|
|
3137
|
+
render: (m, key) => {
|
|
3138
|
+
const href = safeHref(m[2]);
|
|
3139
|
+
if (!href) return /* @__PURE__ */ jsx9("span", { children: m[1] }, key);
|
|
3140
|
+
return /* @__PURE__ */ jsx9("a", { href, target: "_blank", rel: "noopener noreferrer", children: m[1] }, key);
|
|
3141
|
+
},
|
|
3142
|
+
recurse: false
|
|
3143
|
+
},
|
|
3144
|
+
// Bold: **text** or __text__
|
|
3145
|
+
{
|
|
3146
|
+
re: /\*\*([^*]+)\*\*|__([^_]+)__/,
|
|
3147
|
+
render: (m, key) => /* @__PURE__ */ jsx9("strong", { children: renderInline(m[1] ?? m[2] ?? "") }, key),
|
|
3148
|
+
recurse: true,
|
|
3149
|
+
inner: (m) => m[1] ?? m[2] ?? ""
|
|
3150
|
+
},
|
|
3151
|
+
// Italic: *text* or _text_
|
|
3152
|
+
{
|
|
3153
|
+
re: /\*([^*]+)\*|_([^_]+)_/,
|
|
3154
|
+
render: (m, key) => /* @__PURE__ */ jsx9("em", { children: renderInline(m[1] ?? m[2] ?? "") }, key),
|
|
3155
|
+
recurse: true,
|
|
3156
|
+
inner: (m) => m[1] ?? m[2] ?? ""
|
|
3157
|
+
}
|
|
3158
|
+
];
|
|
3159
|
+
function renderInline(text) {
|
|
3160
|
+
const nodes = [];
|
|
3161
|
+
let rest = text;
|
|
3162
|
+
let key = 0;
|
|
3163
|
+
while (rest.length > 0) {
|
|
3164
|
+
let best = null;
|
|
3165
|
+
for (const rule2 of INLINE_RULES) {
|
|
3166
|
+
const m2 = new RegExp(rule2.re).exec(rest);
|
|
3167
|
+
if (m2 && (best === null || m2.index < best.m.index)) {
|
|
3168
|
+
best = { rule: rule2, m: m2 };
|
|
3169
|
+
}
|
|
3170
|
+
}
|
|
3171
|
+
if (!best) {
|
|
3172
|
+
nodes.push(rest);
|
|
3173
|
+
break;
|
|
3174
|
+
}
|
|
3175
|
+
const { rule, m } = best;
|
|
3176
|
+
if (m.index > 0) nodes.push(rest.slice(0, m.index));
|
|
3177
|
+
nodes.push(rule.render(m, key++));
|
|
3178
|
+
rest = rest.slice(m.index + m[0].length);
|
|
3179
|
+
}
|
|
3180
|
+
return nodes;
|
|
3181
|
+
}
|
|
3182
|
+
|
|
2994
3183
|
// src/record-view.ts
|
|
2995
3184
|
import { experimentProgress as experimentProgress2 } from "@validation-os/core/derivation";
|
|
2996
3185
|
function byIds(records, ids) {
|
|
@@ -2999,7 +3188,7 @@ function byIds(records, ids) {
|
|
|
2999
3188
|
}
|
|
3000
3189
|
function headerPills(register, record, related = {}, options = {}) {
|
|
3001
3190
|
const pills = [];
|
|
3002
|
-
const status =
|
|
3191
|
+
const status = str(record.Status);
|
|
3003
3192
|
if (status) pills.push({ label: status, tone: statusTone(status) });
|
|
3004
3193
|
if (register === "assumptions") {
|
|
3005
3194
|
if (record.moot === true) pills.push({ label: "Moot", tone: "neutral" });
|
|
@@ -3009,7 +3198,7 @@ function headerPills(register, record, related = {}, options = {}) {
|
|
|
3009
3198
|
} else if (register === "experiments") {
|
|
3010
3199
|
if (status === "Draft") pills.push({ label: "Test-next", tone: "accent" });
|
|
3011
3200
|
if (status === "Closed") pills.push({ label: "Concluded", tone: "good" });
|
|
3012
|
-
const deadline =
|
|
3201
|
+
const deadline = str(record.Deadline);
|
|
3013
3202
|
if (options.asOf && deadline && status === "Running" && deadline < options.asOf)
|
|
3014
3203
|
pills.push({ label: "Overdue", tone: "crit" });
|
|
3015
3204
|
} else if (register === "decisions") {
|
|
@@ -3050,15 +3239,6 @@ function leadingMeters(register, record) {
|
|
|
3050
3239
|
];
|
|
3051
3240
|
case "readings":
|
|
3052
3241
|
return [
|
|
3053
|
-
{
|
|
3054
|
-
key: "strength",
|
|
3055
|
-
label: "Strength",
|
|
3056
|
-
kind: "signed",
|
|
3057
|
-
value: derivedNum(record, "strength"),
|
|
3058
|
-
tone: "neutral",
|
|
3059
|
-
min: -100,
|
|
3060
|
-
max: 100
|
|
3061
|
-
},
|
|
3062
3242
|
{
|
|
3063
3243
|
key: "sourceQuality",
|
|
3064
3244
|
label: "Source quality",
|
|
@@ -3067,13 +3247,6 @@ function leadingMeters(register, record) {
|
|
|
3067
3247
|
value: derivedNum(record, "sourceQuality") === null ? null : Math.round((derivedNum(record, "sourceQuality") ?? 0) * 100),
|
|
3068
3248
|
tone: "neutral",
|
|
3069
3249
|
max: 100
|
|
3070
|
-
},
|
|
3071
|
-
{
|
|
3072
|
-
key: "Result",
|
|
3073
|
-
label: "Result",
|
|
3074
|
-
kind: "pill",
|
|
3075
|
-
value: str3(record.Result),
|
|
3076
|
-
tone: statusTone(str3(record.Result) ?? "")
|
|
3077
3250
|
}
|
|
3078
3251
|
];
|
|
3079
3252
|
case "experiments": {
|
|
@@ -3092,7 +3265,7 @@ function leadingMeters(register, record) {
|
|
|
3092
3265
|
key: "Feasibility",
|
|
3093
3266
|
label: "Feasibility",
|
|
3094
3267
|
kind: "pill",
|
|
3095
|
-
value:
|
|
3268
|
+
value: str(record.Feasibility),
|
|
3096
3269
|
tone: "neutral"
|
|
3097
3270
|
}
|
|
3098
3271
|
];
|
|
@@ -3103,8 +3276,8 @@ function leadingMeters(register, record) {
|
|
|
3103
3276
|
key: "Status",
|
|
3104
3277
|
label: "Status",
|
|
3105
3278
|
kind: "pill",
|
|
3106
|
-
value:
|
|
3107
|
-
tone: statusTone(
|
|
3279
|
+
value: str(record.Status),
|
|
3280
|
+
tone: statusTone(str(record.Status) ?? "")
|
|
3108
3281
|
}
|
|
3109
3282
|
];
|
|
3110
3283
|
case "glossary":
|
|
@@ -3113,8 +3286,8 @@ function leadingMeters(register, record) {
|
|
|
3113
3286
|
key: "Status",
|
|
3114
3287
|
label: "Status",
|
|
3115
3288
|
kind: "pill",
|
|
3116
|
-
value:
|
|
3117
|
-
tone: statusTone(
|
|
3289
|
+
value: str(record.Status),
|
|
3290
|
+
tone: statusTone(str(record.Status) ?? "")
|
|
3118
3291
|
}
|
|
3119
3292
|
];
|
|
3120
3293
|
}
|
|
@@ -3133,7 +3306,24 @@ var HUMAN_FIELDS = {
|
|
|
3133
3306
|
]
|
|
3134
3307
|
};
|
|
3135
3308
|
function humanInputFields(register, record) {
|
|
3136
|
-
return HUMAN_FIELDS[register].map((f) => ({ key: f.key, label: f.label, text:
|
|
3309
|
+
return HUMAN_FIELDS[register].map((f) => ({ key: f.key, label: f.label, text: str(record[f.key]) ?? "" })).filter((f) => f.text !== "");
|
|
3310
|
+
}
|
|
3311
|
+
function readingBeliefVerdicts(reading, assumptions = []) {
|
|
3312
|
+
const byId = new Map(assumptions.map((a) => [a.id, a]));
|
|
3313
|
+
return readingBeliefs(reading).map((b) => {
|
|
3314
|
+
const hit = byId.get(b.assumptionId);
|
|
3315
|
+
const strength = b.derived && typeof b.derived.strength === "number" ? b.derived.strength : null;
|
|
3316
|
+
return {
|
|
3317
|
+
assumptionId: b.assumptionId,
|
|
3318
|
+
title: hit ? primaryLabel(hit) : b.assumptionId,
|
|
3319
|
+
linked: hit != null,
|
|
3320
|
+
rung: b.Rung ?? null,
|
|
3321
|
+
result: b.Result ?? null,
|
|
3322
|
+
strength,
|
|
3323
|
+
magnitudeBand: b.magnitudeBand ?? null,
|
|
3324
|
+
justification: typeof b["Grading justification"] === "string" ? b["Grading justification"] : ""
|
|
3325
|
+
};
|
|
3326
|
+
});
|
|
3137
3327
|
}
|
|
3138
3328
|
function scoreChip(register, record) {
|
|
3139
3329
|
if (register === "assumptions") {
|
|
@@ -3141,14 +3331,14 @@ function scoreChip(register, record) {
|
|
|
3141
3331
|
return { label: "Confidence", value: formatSigned(c), tone: confidenceTone(c) };
|
|
3142
3332
|
}
|
|
3143
3333
|
if (register === "readings") {
|
|
3144
|
-
const
|
|
3334
|
+
const sq = derivedNum(record, "sourceQuality");
|
|
3145
3335
|
return {
|
|
3146
|
-
label: "
|
|
3147
|
-
value:
|
|
3336
|
+
label: "Source quality",
|
|
3337
|
+
value: sq === null ? "\u2014" : String(Math.round(sq * 100)),
|
|
3148
3338
|
tone: "neutral"
|
|
3149
3339
|
};
|
|
3150
3340
|
}
|
|
3151
|
-
const status =
|
|
3341
|
+
const status = str(record.Status) ?? "\u2014";
|
|
3152
3342
|
return { label: "Status", value: status, tone: statusTone(status) };
|
|
3153
3343
|
}
|
|
3154
3344
|
var PANELS = {
|
|
@@ -3157,7 +3347,7 @@ var PANELS = {
|
|
|
3157
3347
|
id: "readings",
|
|
3158
3348
|
label: "Readings",
|
|
3159
3349
|
register: "readings",
|
|
3160
|
-
resolve: (r, rel) => (rel.readings ?? []).filter((x) => x
|
|
3350
|
+
resolve: (r, rel) => (rel.readings ?? []).filter((x) => readingGrades(x, r.id))
|
|
3161
3351
|
},
|
|
3162
3352
|
{
|
|
3163
3353
|
id: "depends-on",
|
|
@@ -3181,7 +3371,10 @@ var PANELS = {
|
|
|
3181
3371
|
id: "tested-by",
|
|
3182
3372
|
label: "Tested by",
|
|
3183
3373
|
register: "experiments",
|
|
3184
|
-
|
|
3374
|
+
// Archived plans never surface as a relation (OPS-1305) — live plans only.
|
|
3375
|
+
resolve: (r, rel) => liveExperiments(rel.experiments ?? []).filter(
|
|
3376
|
+
(e) => testsAssumption(e, r.id)
|
|
3377
|
+
)
|
|
3185
3378
|
},
|
|
3186
3379
|
{
|
|
3187
3380
|
id: "decisions-based",
|
|
@@ -3199,15 +3392,20 @@ var PANELS = {
|
|
|
3199
3392
|
readings: [
|
|
3200
3393
|
{
|
|
3201
3394
|
id: "assumption",
|
|
3202
|
-
label: "
|
|
3395
|
+
label: "Beliefs",
|
|
3203
3396
|
register: "assumptions",
|
|
3204
|
-
|
|
3397
|
+
// A reading grades several beliefs now (OPS-1305) — resolve them all.
|
|
3398
|
+
resolve: (r, rel) => byIds(rel.assumptions, strList(r.assumptionIds))
|
|
3205
3399
|
},
|
|
3206
3400
|
{
|
|
3207
3401
|
id: "experiment",
|
|
3208
3402
|
label: "Evidence plan",
|
|
3209
3403
|
register: "experiments",
|
|
3210
|
-
|
|
3404
|
+
// Only ever surface a NON-archived plan (OPS-1305): an archived origin
|
|
3405
|
+
// reads as no plan at all, never a leaked backlink.
|
|
3406
|
+
resolve: (r, rel) => byIds(rel.experiments, [str(r.experimentId) ?? ""].filter(Boolean)).filter(
|
|
3407
|
+
(e) => !isArchivedExperiment(e)
|
|
3408
|
+
)
|
|
3211
3409
|
}
|
|
3212
3410
|
],
|
|
3213
3411
|
experiments: [
|
|
@@ -3276,8 +3474,49 @@ function buildRecordPage(register, record, related = {}, options = {}) {
|
|
|
3276
3474
|
};
|
|
3277
3475
|
}
|
|
3278
3476
|
|
|
3477
|
+
// src/belief-verdicts.tsx
|
|
3478
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
3479
|
+
function resultClass(result) {
|
|
3480
|
+
if (result === "Validated") return "vos-pill vos-pill-good";
|
|
3481
|
+
if (result === "Invalidated") return "vos-pill vos-pill-crit";
|
|
3482
|
+
return "vos-pill vos-pill-neutral";
|
|
3483
|
+
}
|
|
3484
|
+
function BeliefVerdicts({
|
|
3485
|
+
reading,
|
|
3486
|
+
assumptions,
|
|
3487
|
+
onOpenRecord
|
|
3488
|
+
}) {
|
|
3489
|
+
const verdicts = readingBeliefVerdicts(reading, assumptions);
|
|
3490
|
+
if (verdicts.length === 0) {
|
|
3491
|
+
return /* @__PURE__ */ jsx10("p", { className: "vos-hint", children: "This reading grades no beliefs yet." });
|
|
3492
|
+
}
|
|
3493
|
+
return /* @__PURE__ */ jsx10("ul", { className: "vos-verdicts", children: verdicts.map((v) => /* @__PURE__ */ jsxs9("li", { className: "vos-verdict", children: [
|
|
3494
|
+
/* @__PURE__ */ jsxs9("div", { className: "vos-verdict-head", children: [
|
|
3495
|
+
v.linked && onOpenRecord ? /* @__PURE__ */ jsx10(
|
|
3496
|
+
"button",
|
|
3497
|
+
{
|
|
3498
|
+
type: "button",
|
|
3499
|
+
className: "vos-inline-link",
|
|
3500
|
+
onClick: () => onOpenRecord(v.assumptionId),
|
|
3501
|
+
children: v.title
|
|
3502
|
+
}
|
|
3503
|
+
) : /* @__PURE__ */ jsx10("span", { className: "vos-verdict-title", children: v.title }),
|
|
3504
|
+
/* @__PURE__ */ jsx10("span", { className: resultClass(v.result), children: v.result ?? "\u2014" })
|
|
3505
|
+
] }),
|
|
3506
|
+
/* @__PURE__ */ jsxs9("div", { className: "vos-verdict-meta", children: [
|
|
3507
|
+
v.rung ? /* @__PURE__ */ jsx10("span", { className: "vos-chip vos-pill vos-pill-neutral", children: v.rung }) : null,
|
|
3508
|
+
v.magnitudeBand ? /* @__PURE__ */ jsx10("span", { className: "vos-chip vos-pill vos-pill-neutral", children: v.magnitudeBand }) : null,
|
|
3509
|
+
v.strength !== null ? /* @__PURE__ */ jsxs9("span", { className: "vos-verdict-strength", children: [
|
|
3510
|
+
"Strength ",
|
|
3511
|
+
formatSigned(v.strength)
|
|
3512
|
+
] }) : null
|
|
3513
|
+
] }),
|
|
3514
|
+
v.justification ? /* @__PURE__ */ jsx10("p", { className: "vos-verdict-why", children: v.justification }) : null
|
|
3515
|
+
] }, v.assumptionId)) });
|
|
3516
|
+
}
|
|
3517
|
+
|
|
3279
3518
|
// src/record-page.tsx
|
|
3280
|
-
import { Fragment as Fragment8, jsx as
|
|
3519
|
+
import { Fragment as Fragment8, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3281
3520
|
var TAB_LABEL = {
|
|
3282
3521
|
overview: "Overview",
|
|
3283
3522
|
evidence: "Evidence",
|
|
@@ -3398,9 +3637,9 @@ function RecordPage({
|
|
|
3398
3637
|
onReload: reloadLatest,
|
|
3399
3638
|
onField: setField
|
|
3400
3639
|
};
|
|
3401
|
-
return /* @__PURE__ */
|
|
3402
|
-
/* @__PURE__ */
|
|
3403
|
-
/* @__PURE__ */
|
|
3640
|
+
return /* @__PURE__ */ jsxs10("div", { children: [
|
|
3641
|
+
/* @__PURE__ */ jsxs10("nav", { className: "vos-crumbs", "aria-label": "Breadcrumb", children: [
|
|
3642
|
+
/* @__PURE__ */ jsx11(
|
|
3404
3643
|
"button",
|
|
3405
3644
|
{
|
|
3406
3645
|
type: "button",
|
|
@@ -3408,14 +3647,14 @@ function RecordPage({
|
|
|
3408
3647
|
children: REGISTER_LABEL[register ?? backRegister]
|
|
3409
3648
|
}
|
|
3410
3649
|
),
|
|
3411
|
-
/* @__PURE__ */
|
|
3412
|
-
/* @__PURE__ */
|
|
3650
|
+
/* @__PURE__ */ jsx11("span", { "aria-hidden": "true", children: "\u203A" }),
|
|
3651
|
+
/* @__PURE__ */ jsx11("span", { className: "vos-rid", children: record ? formatValue(record.Title) : recordId })
|
|
3413
3652
|
] }),
|
|
3414
|
-
anyLoading ? /* @__PURE__ */
|
|
3653
|
+
anyLoading ? /* @__PURE__ */ jsx11("p", { className: "vos-muted", children: "Loading record\u2026" }) : !record || !register ? /* @__PURE__ */ jsxs10("div", { className: "vos-empty", children: [
|
|
3415
3654
|
"Couldn't find a record with id ",
|
|
3416
|
-
/* @__PURE__ */
|
|
3655
|
+
/* @__PURE__ */ jsx11("b", { children: recordId }),
|
|
3417
3656
|
"."
|
|
3418
|
-
] }) : /* @__PURE__ */
|
|
3657
|
+
] }) : /* @__PURE__ */ jsx11(
|
|
3419
3658
|
RecordBody,
|
|
3420
3659
|
{
|
|
3421
3660
|
register,
|
|
@@ -3455,20 +3694,21 @@ function RecordBody({
|
|
|
3455
3694
|
const page = buildRecordPage(register, record, related, { asOf });
|
|
3456
3695
|
const activeTab = page.tabs.includes(tab) ? tab : "overview";
|
|
3457
3696
|
const description = typeof record.Description === "string" ? record.Description : "";
|
|
3697
|
+
const bodyText = typeof record.body === "string" ? record.body : "";
|
|
3458
3698
|
const hasErrors = Object.keys(edit.errors).length > 0;
|
|
3459
|
-
return /* @__PURE__ */
|
|
3460
|
-
/* @__PURE__ */
|
|
3461
|
-
/* @__PURE__ */
|
|
3462
|
-
/* @__PURE__ */
|
|
3463
|
-
/* @__PURE__ */
|
|
3464
|
-
/* @__PURE__ */
|
|
3699
|
+
return /* @__PURE__ */ jsxs10(Fragment8, { children: [
|
|
3700
|
+
/* @__PURE__ */ jsxs10("div", { className: "vos-head vos-record-head", children: [
|
|
3701
|
+
/* @__PURE__ */ jsxs10("div", { children: [
|
|
3702
|
+
/* @__PURE__ */ jsx11("p", { className: "vos-drawer-eyebrow", children: REGISTER_SINGULAR[register] }),
|
|
3703
|
+
/* @__PURE__ */ jsx11("h1", { children: page.title }),
|
|
3704
|
+
/* @__PURE__ */ jsx11("div", { className: "vos-pill-row", children: page.pills.map((p, i) => /* @__PURE__ */ jsx11(PillView, { pill: p }, i)) })
|
|
3465
3705
|
] }),
|
|
3466
|
-
/* @__PURE__ */
|
|
3467
|
-
/* @__PURE__ */
|
|
3706
|
+
/* @__PURE__ */ jsx11("div", { className: "vos-spacer" }),
|
|
3707
|
+
/* @__PURE__ */ jsxs10("span", { className: "vos-verbadge", children: [
|
|
3468
3708
|
"v",
|
|
3469
3709
|
formatValue(record.version)
|
|
3470
3710
|
] }),
|
|
3471
|
-
!edit.editing ? /* @__PURE__ */
|
|
3711
|
+
!edit.editing ? /* @__PURE__ */ jsx11(
|
|
3472
3712
|
"button",
|
|
3473
3713
|
{
|
|
3474
3714
|
type: "button",
|
|
@@ -3478,7 +3718,7 @@ function RecordBody({
|
|
|
3478
3718
|
}
|
|
3479
3719
|
) : null
|
|
3480
3720
|
] }),
|
|
3481
|
-
/* @__PURE__ */
|
|
3721
|
+
/* @__PURE__ */ jsx11("div", { className: "vos-tabs", role: "tablist", "aria-label": "Record sections", children: page.tabs.map((t2) => /* @__PURE__ */ jsx11(
|
|
3482
3722
|
"button",
|
|
3483
3723
|
{
|
|
3484
3724
|
type: "button",
|
|
@@ -3490,8 +3730,8 @@ function RecordBody({
|
|
|
3490
3730
|
},
|
|
3491
3731
|
t2
|
|
3492
3732
|
)) }),
|
|
3493
|
-
activeTab === "overview" ? /* @__PURE__ */
|
|
3494
|
-
/* @__PURE__ */
|
|
3733
|
+
activeTab === "overview" ? /* @__PURE__ */ jsxs10("div", { className: "vos-record-cols", children: [
|
|
3734
|
+
/* @__PURE__ */ jsx11("section", { className: "vos-meter-grid", children: page.meters.map((m) => /* @__PURE__ */ jsx11(
|
|
3495
3735
|
MeterView,
|
|
3496
3736
|
{
|
|
3497
3737
|
meter: m,
|
|
@@ -3500,11 +3740,11 @@ function RecordBody({
|
|
|
3500
3740
|
},
|
|
3501
3741
|
m.key
|
|
3502
3742
|
)) }),
|
|
3503
|
-
edit.editing ? /* @__PURE__ */
|
|
3504
|
-
/* @__PURE__ */
|
|
3505
|
-
edit.conflict ? /* @__PURE__ */
|
|
3506
|
-
edit.saveError ? /* @__PURE__ */
|
|
3507
|
-
/* @__PURE__ */
|
|
3743
|
+
edit.editing ? /* @__PURE__ */ jsxs10("section", { className: "vos-record-editor", children: [
|
|
3744
|
+
/* @__PURE__ */ jsx11("h3", { className: "vos-section-title", children: "Edit" }),
|
|
3745
|
+
edit.conflict ? /* @__PURE__ */ jsx11(ConflictBanner, { message: edit.conflict, onReload: edit.onReload }) : null,
|
|
3746
|
+
edit.saveError ? /* @__PURE__ */ jsx11("p", { role: "alert", className: "vos-error", children: edit.saveError }) : null,
|
|
3747
|
+
/* @__PURE__ */ jsx11(
|
|
3508
3748
|
EditFields,
|
|
3509
3749
|
{
|
|
3510
3750
|
register,
|
|
@@ -3513,8 +3753,8 @@ function RecordBody({
|
|
|
3513
3753
|
onField: edit.onField
|
|
3514
3754
|
}
|
|
3515
3755
|
),
|
|
3516
|
-
/* @__PURE__ */
|
|
3517
|
-
/* @__PURE__ */
|
|
3756
|
+
/* @__PURE__ */ jsxs10("footer", { className: "vos-drawer-footer", children: [
|
|
3757
|
+
/* @__PURE__ */ jsx11(
|
|
3518
3758
|
"button",
|
|
3519
3759
|
{
|
|
3520
3760
|
type: "button",
|
|
@@ -3524,7 +3764,7 @@ function RecordBody({
|
|
|
3524
3764
|
children: "Cancel"
|
|
3525
3765
|
}
|
|
3526
3766
|
),
|
|
3527
|
-
/* @__PURE__ */
|
|
3767
|
+
/* @__PURE__ */ jsx11(
|
|
3528
3768
|
"button",
|
|
3529
3769
|
{
|
|
3530
3770
|
type: "button",
|
|
@@ -3536,10 +3776,10 @@ function RecordBody({
|
|
|
3536
3776
|
}
|
|
3537
3777
|
)
|
|
3538
3778
|
] })
|
|
3539
|
-
] }) : /* @__PURE__ */
|
|
3540
|
-
description ? /* @__PURE__ */
|
|
3541
|
-
/* @__PURE__ */
|
|
3542
|
-
/* @__PURE__ */
|
|
3779
|
+
] }) : /* @__PURE__ */ jsxs10(Fragment8, { children: [
|
|
3780
|
+
description ? /* @__PURE__ */ jsxs10("section", { className: "vos-record-prose", children: [
|
|
3781
|
+
/* @__PURE__ */ jsx11("h3", { className: "vos-section-title", children: "Description" }),
|
|
3782
|
+
/* @__PURE__ */ jsx11("p", { children: /* @__PURE__ */ jsx11(
|
|
3543
3783
|
GlossaryText,
|
|
3544
3784
|
{
|
|
3545
3785
|
text: description,
|
|
@@ -3549,14 +3789,29 @@ function RecordBody({
|
|
|
3549
3789
|
}
|
|
3550
3790
|
) })
|
|
3551
3791
|
] }) : null,
|
|
3552
|
-
|
|
3553
|
-
/* @__PURE__ */
|
|
3792
|
+
bodyText ? /* @__PURE__ */ jsxs10("section", { className: "vos-record-prose", children: [
|
|
3793
|
+
/* @__PURE__ */ jsx11("h3", { className: "vos-section-title", children: register === "readings" ? "Quote" : "Narrative" }),
|
|
3794
|
+
/* @__PURE__ */ jsx11(Markdown, { text: bodyText })
|
|
3795
|
+
] }) : null,
|
|
3796
|
+
register === "readings" ? /* @__PURE__ */ jsxs10("section", { className: "vos-record-prose", children: [
|
|
3797
|
+
/* @__PURE__ */ jsx11("h3", { className: "vos-section-title", children: "Per-belief verdicts" }),
|
|
3798
|
+
/* @__PURE__ */ jsx11(
|
|
3799
|
+
BeliefVerdicts,
|
|
3800
|
+
{
|
|
3801
|
+
reading: record,
|
|
3802
|
+
assumptions: related.assumptions ?? [],
|
|
3803
|
+
onOpenRecord
|
|
3804
|
+
}
|
|
3805
|
+
)
|
|
3806
|
+
] }) : null,
|
|
3807
|
+
page.humanText.length ? /* @__PURE__ */ jsxs10("section", { className: "vos-record-prose", children: [
|
|
3808
|
+
/* @__PURE__ */ jsxs10("h3", { className: "vos-section-title", children: [
|
|
3554
3809
|
"From a human ",
|
|
3555
|
-
/* @__PURE__ */
|
|
3810
|
+
/* @__PURE__ */ jsx11("span", { className: "vos-hint", children: "\u2014 not computed" })
|
|
3556
3811
|
] }),
|
|
3557
|
-
page.humanText.map((h) => /* @__PURE__ */
|
|
3558
|
-
/* @__PURE__ */
|
|
3559
|
-
/* @__PURE__ */
|
|
3812
|
+
page.humanText.map((h) => /* @__PURE__ */ jsxs10("div", { className: "vos-human-field", children: [
|
|
3813
|
+
/* @__PURE__ */ jsx11("div", { className: "vos-detail-k", children: h.label }),
|
|
3814
|
+
/* @__PURE__ */ jsx11("p", { children: /* @__PURE__ */ jsx11(
|
|
3560
3815
|
GlossaryText,
|
|
3561
3816
|
{
|
|
3562
3817
|
text: h.text,
|
|
@@ -3569,7 +3824,7 @@ function RecordBody({
|
|
|
3569
3824
|
] }) : null
|
|
3570
3825
|
] })
|
|
3571
3826
|
] }) : null,
|
|
3572
|
-
activeTab === "evidence" ? /* @__PURE__ */
|
|
3827
|
+
activeTab === "evidence" ? /* @__PURE__ */ jsx11(
|
|
3573
3828
|
EvidenceTab,
|
|
3574
3829
|
{
|
|
3575
3830
|
register,
|
|
@@ -3579,25 +3834,25 @@ function RecordBody({
|
|
|
3579
3834
|
basePath
|
|
3580
3835
|
}
|
|
3581
3836
|
) : null,
|
|
3582
|
-
activeTab === "connections" ? /* @__PURE__ */
|
|
3583
|
-
activeTab === "history" ? /* @__PURE__ */
|
|
3584
|
-
/* @__PURE__ */
|
|
3585
|
-
/* @__PURE__ */
|
|
3586
|
-
/* @__PURE__ */
|
|
3837
|
+
activeTab === "connections" ? /* @__PURE__ */ jsx11("div", { className: "vos-panels", children: page.panels.map((panel) => /* @__PURE__ */ jsx11(PanelView, { panel, onOpenRecord }, panel.id)) }) : null,
|
|
3838
|
+
activeTab === "history" ? /* @__PURE__ */ jsxs10("section", { className: "vos-detail-list", children: [
|
|
3839
|
+
/* @__PURE__ */ jsxs10("div", { className: "vos-detail-row", children: [
|
|
3840
|
+
/* @__PURE__ */ jsx11("span", { className: "vos-detail-k", children: "Created" }),
|
|
3841
|
+
/* @__PURE__ */ jsx11("span", { className: "vos-detail-v", children: formatValue(record.createdAt) })
|
|
3587
3842
|
] }),
|
|
3588
|
-
/* @__PURE__ */
|
|
3589
|
-
/* @__PURE__ */
|
|
3590
|
-
/* @__PURE__ */
|
|
3843
|
+
/* @__PURE__ */ jsxs10("div", { className: "vos-detail-row", children: [
|
|
3844
|
+
/* @__PURE__ */ jsx11("span", { className: "vos-detail-k", children: "Last updated" }),
|
|
3845
|
+
/* @__PURE__ */ jsx11("span", { className: "vos-detail-v", children: formatValue(record.updatedAt) })
|
|
3591
3846
|
] }),
|
|
3592
|
-
/* @__PURE__ */
|
|
3593
|
-
/* @__PURE__ */
|
|
3594
|
-
/* @__PURE__ */
|
|
3847
|
+
/* @__PURE__ */ jsxs10("div", { className: "vos-detail-row", children: [
|
|
3848
|
+
/* @__PURE__ */ jsx11("span", { className: "vos-detail-k", children: "Version" }),
|
|
3849
|
+
/* @__PURE__ */ jsx11("span", { className: "vos-detail-v", children: formatValue(record.version) })
|
|
3595
3850
|
] }),
|
|
3596
|
-
/* @__PURE__ */
|
|
3851
|
+
/* @__PURE__ */ jsx11("p", { className: "vos-hint", children: "The full change trail lands here as the API exposes version history; this absorbs the retired provenance prose." })
|
|
3597
3852
|
] }) : null,
|
|
3598
|
-
page.hasJourney && journey ? /* @__PURE__ */
|
|
3599
|
-
/* @__PURE__ */
|
|
3600
|
-
/* @__PURE__ */
|
|
3853
|
+
page.hasJourney && journey ? /* @__PURE__ */ jsxs10("section", { className: "vos-journey-host", children: [
|
|
3854
|
+
/* @__PURE__ */ jsx11("h3", { className: "vos-section-title", children: "Validation journey" }),
|
|
3855
|
+
/* @__PURE__ */ jsx11(
|
|
3601
3856
|
BeliefJourney,
|
|
3602
3857
|
{
|
|
3603
3858
|
journey,
|
|
@@ -3607,22 +3862,22 @@ function RecordBody({
|
|
|
3607
3862
|
onChanged: onJourneyChanged
|
|
3608
3863
|
}
|
|
3609
3864
|
)
|
|
3610
|
-
] }) : page.hasJourney ? /* @__PURE__ */
|
|
3611
|
-
/* @__PURE__ */
|
|
3612
|
-
/* @__PURE__ */
|
|
3865
|
+
] }) : page.hasJourney ? /* @__PURE__ */ jsxs10("section", { className: "vos-journey-host", children: [
|
|
3866
|
+
/* @__PURE__ */ jsx11("h3", { className: "vos-section-title", children: "Validation journey" }),
|
|
3867
|
+
/* @__PURE__ */ jsx11("p", { className: "vos-hint", children: "The per-belief journey (Framed \u2192 Planned \u2192 Tested \u2192 Known) mounts here \u2014 built by the workflow-first map (OPS-1289). This page is its host." })
|
|
3613
3868
|
] }) : null
|
|
3614
3869
|
] });
|
|
3615
3870
|
}
|
|
3616
3871
|
function PillView({ pill }) {
|
|
3617
|
-
return /* @__PURE__ */
|
|
3872
|
+
return /* @__PURE__ */ jsx11("span", { className: PILL_CLASS3[pill.tone], children: pill.label });
|
|
3618
3873
|
}
|
|
3619
3874
|
function ConflictBanner({
|
|
3620
3875
|
message,
|
|
3621
3876
|
onReload
|
|
3622
3877
|
}) {
|
|
3623
|
-
return /* @__PURE__ */
|
|
3624
|
-
/* @__PURE__ */
|
|
3625
|
-
/* @__PURE__ */
|
|
3878
|
+
return /* @__PURE__ */ jsxs10("div", { role: "alert", className: "vos-banner vos-banner-warn", children: [
|
|
3879
|
+
/* @__PURE__ */ jsx11("div", { className: "vos-banner-body", children: /* @__PURE__ */ jsx11("span", { children: message }) }),
|
|
3880
|
+
/* @__PURE__ */ jsx11("button", { type: "button", onClick: onReload, children: "Review the latest" })
|
|
3626
3881
|
] });
|
|
3627
3882
|
}
|
|
3628
3883
|
function MeterView({
|
|
@@ -3632,10 +3887,10 @@ function MeterView({
|
|
|
3632
3887
|
}) {
|
|
3633
3888
|
const [why, setWhy] = useState5(false);
|
|
3634
3889
|
const textTone = meter.tone === "crit" ? "vos-text-crit" : meter.tone === "warn" ? "vos-text-warn" : "";
|
|
3635
|
-
return /* @__PURE__ */
|
|
3636
|
-
/* @__PURE__ */
|
|
3637
|
-
/* @__PURE__ */
|
|
3638
|
-
meter.hasWhy && assumption ? /* @__PURE__ */
|
|
3890
|
+
return /* @__PURE__ */ jsxs10("div", { className: "vos-meter", children: [
|
|
3891
|
+
/* @__PURE__ */ jsxs10("div", { className: "vos-meter-head", children: [
|
|
3892
|
+
/* @__PURE__ */ jsx11("span", { className: "vos-meter-label", children: meter.label }),
|
|
3893
|
+
meter.hasWhy && assumption ? /* @__PURE__ */ jsxs10(
|
|
3639
3894
|
"button",
|
|
3640
3895
|
{
|
|
3641
3896
|
type: "button",
|
|
@@ -3649,12 +3904,12 @@ function MeterView({
|
|
|
3649
3904
|
}
|
|
3650
3905
|
) : null
|
|
3651
3906
|
] }),
|
|
3652
|
-
meter.value === null ? /* @__PURE__ */
|
|
3653
|
-
/* @__PURE__ */
|
|
3654
|
-
/* @__PURE__ */
|
|
3655
|
-
] }) : /* @__PURE__ */
|
|
3656
|
-
/* @__PURE__ */
|
|
3657
|
-
/* @__PURE__ */
|
|
3907
|
+
meter.value === null ? /* @__PURE__ */ jsx11("div", { className: "vos-meter-val vos-muted", children: "\u2014" }) : meter.kind === "pill" ? /* @__PURE__ */ jsx11("span", { className: PILL_CLASS3[meter.tone], children: meter.value }) : meter.kind === "signed" ? /* @__PURE__ */ jsxs10(Fragment8, { children: [
|
|
3908
|
+
/* @__PURE__ */ jsx11("div", { className: `vos-meter-val ${textTone}`, children: formatSigned(Number(meter.value)) }),
|
|
3909
|
+
/* @__PURE__ */ jsx11("span", { className: "vos-track vos-signed", children: /* @__PURE__ */ jsx11(SignedFill, { value: Number(meter.value), min: meter.min ?? -100, max: meter.max ?? 100 }) })
|
|
3910
|
+
] }) : /* @__PURE__ */ jsxs10(Fragment8, { children: [
|
|
3911
|
+
/* @__PURE__ */ jsx11("div", { className: `vos-meter-val ${textTone}`, children: Math.round(Number(meter.value)) }),
|
|
3912
|
+
/* @__PURE__ */ jsx11("span", { className: "vos-risk-bar", children: /* @__PURE__ */ jsx11(
|
|
3658
3913
|
"i",
|
|
3659
3914
|
{
|
|
3660
3915
|
className: meter.tone === "crit" ? "vos-fill-crit" : meter.tone === "warn" ? "vos-fill-warn" : "vos-fill-good",
|
|
@@ -3662,7 +3917,7 @@ function MeterView({
|
|
|
3662
3917
|
}
|
|
3663
3918
|
) })
|
|
3664
3919
|
] }),
|
|
3665
|
-
why && assumption ? /* @__PURE__ */
|
|
3920
|
+
why && assumption ? /* @__PURE__ */ jsx11("div", { className: "vos-why-panel", children: /* @__PURE__ */ jsx11(UnderstandingPanel, { assumption, basePath }) }) : null
|
|
3666
3921
|
] });
|
|
3667
3922
|
}
|
|
3668
3923
|
function SignedFill({ value, min, max }) {
|
|
@@ -3670,34 +3925,34 @@ function SignedFill({ value, min, max }) {
|
|
|
3670
3925
|
const width = Math.round(Math.min(Math.abs(value), span) / span * 50);
|
|
3671
3926
|
const up = value >= 0;
|
|
3672
3927
|
const style = up ? { left: "50%", width: `${width}%`, background: "var(--vos-good)" } : { right: "50%", width: `${width}%`, background: "var(--vos-crit)" };
|
|
3673
|
-
return width > 0 ? /* @__PURE__ */
|
|
3928
|
+
return width > 0 ? /* @__PURE__ */ jsx11("i", { style }) : null;
|
|
3674
3929
|
}
|
|
3675
3930
|
function PanelView({
|
|
3676
3931
|
panel,
|
|
3677
3932
|
onOpenRecord
|
|
3678
3933
|
}) {
|
|
3679
|
-
return /* @__PURE__ */
|
|
3680
|
-
/* @__PURE__ */
|
|
3934
|
+
return /* @__PURE__ */ jsxs10("section", { className: "vos-panel", children: [
|
|
3935
|
+
/* @__PURE__ */ jsxs10("h3", { className: "vos-panel-head", children: [
|
|
3681
3936
|
panel.label,
|
|
3682
|
-
/* @__PURE__ */
|
|
3937
|
+
/* @__PURE__ */ jsx11("span", { className: "vos-group-n", children: panel.items.length })
|
|
3683
3938
|
] }),
|
|
3684
|
-
panel.items.length === 0 ? /* @__PURE__ */
|
|
3939
|
+
panel.items.length === 0 ? /* @__PURE__ */ jsx11("p", { className: "vos-hint", children: "None yet." }) : /* @__PURE__ */ jsx11("ul", { className: "vos-backlinks", children: panel.items.map((item) => /* @__PURE__ */ jsx11(BacklinkRow, { item, onOpenRecord }, item.id)) })
|
|
3685
3940
|
] });
|
|
3686
3941
|
}
|
|
3687
3942
|
function BacklinkRow({
|
|
3688
3943
|
item,
|
|
3689
3944
|
onOpenRecord
|
|
3690
3945
|
}) {
|
|
3691
|
-
return /* @__PURE__ */
|
|
3946
|
+
return /* @__PURE__ */ jsx11("li", { children: /* @__PURE__ */ jsxs10(
|
|
3692
3947
|
"button",
|
|
3693
3948
|
{
|
|
3694
3949
|
type: "button",
|
|
3695
3950
|
className: "vos-backlink",
|
|
3696
3951
|
onClick: () => onOpenRecord(item.id),
|
|
3697
3952
|
children: [
|
|
3698
|
-
/* @__PURE__ */
|
|
3699
|
-
/* @__PURE__ */
|
|
3700
|
-
/* @__PURE__ */
|
|
3953
|
+
/* @__PURE__ */ jsx11("span", { className: "vos-backlink-title", children: item.title }),
|
|
3954
|
+
/* @__PURE__ */ jsxs10("span", { className: `vos-chip ${PILL_CLASS3[item.chip.tone]}`, children: [
|
|
3955
|
+
/* @__PURE__ */ jsx11("span", { className: "vos-chip-k", children: item.chip.label }),
|
|
3701
3956
|
item.chip.value
|
|
3702
3957
|
] })
|
|
3703
3958
|
]
|
|
@@ -3712,7 +3967,7 @@ function EvidenceTab({
|
|
|
3712
3967
|
basePath
|
|
3713
3968
|
}) {
|
|
3714
3969
|
if (register === "assumptions") {
|
|
3715
|
-
return /* @__PURE__ */
|
|
3970
|
+
return /* @__PURE__ */ jsx11("section", { className: "vos-why-panel", children: /* @__PURE__ */ jsx11(UnderstandingPanel, { assumption: record, basePath }) });
|
|
3716
3971
|
}
|
|
3717
3972
|
const bars = resolveBarLines(
|
|
3718
3973
|
record.barLines ?? [],
|
|
@@ -3720,12 +3975,12 @@ function EvidenceTab({
|
|
|
3720
3975
|
);
|
|
3721
3976
|
const mine = (related.readings ?? []).filter((r) => r.experimentId === record.id);
|
|
3722
3977
|
const nested = nestReadingsByPlan(mine, [record]);
|
|
3723
|
-
return /* @__PURE__ */
|
|
3724
|
-
/* @__PURE__ */
|
|
3725
|
-
/* @__PURE__ */
|
|
3726
|
-
bars.length === 0 ? /* @__PURE__ */
|
|
3727
|
-
/* @__PURE__ */
|
|
3728
|
-
b.assumption ? /* @__PURE__ */
|
|
3978
|
+
return /* @__PURE__ */ jsxs10("div", { className: "vos-record-cols", children: [
|
|
3979
|
+
/* @__PURE__ */ jsxs10("section", { children: [
|
|
3980
|
+
/* @__PURE__ */ jsx11("h3", { className: "vos-section-title", children: "Bar lines" }),
|
|
3981
|
+
bars.length === 0 ? /* @__PURE__ */ jsx11("p", { className: "vos-hint", children: "No pre-registered bars." }) : /* @__PURE__ */ jsx11("ul", { className: "vos-bars", children: bars.map((b, i) => /* @__PURE__ */ jsxs10("li", { className: "vos-bar-line", children: [
|
|
3982
|
+
/* @__PURE__ */ jsx11("span", { className: "vos-bar-if", children: b.rightIf || "\u2014" }),
|
|
3983
|
+
b.assumption ? /* @__PURE__ */ jsx11(
|
|
3729
3984
|
"button",
|
|
3730
3985
|
{
|
|
3731
3986
|
type: "button",
|
|
@@ -3734,7 +3989,7 @@ function EvidenceTab({
|
|
|
3734
3989
|
children: b.assumption.title
|
|
3735
3990
|
}
|
|
3736
3991
|
) : null,
|
|
3737
|
-
/* @__PURE__ */
|
|
3992
|
+
/* @__PURE__ */ jsx11(
|
|
3738
3993
|
"span",
|
|
3739
3994
|
{
|
|
3740
3995
|
className: b.barVerdict ? "vos-pill vos-pill-good" : "vos-pill vos-pill-neutral",
|
|
@@ -3743,17 +3998,21 @@ function EvidenceTab({
|
|
|
3743
3998
|
)
|
|
3744
3999
|
] }, i)) })
|
|
3745
4000
|
] }),
|
|
3746
|
-
/* @__PURE__ */
|
|
3747
|
-
/* @__PURE__ */
|
|
3748
|
-
nested.length === 0 ? /* @__PURE__ */
|
|
4001
|
+
/* @__PURE__ */ jsxs10("section", { children: [
|
|
4002
|
+
/* @__PURE__ */ jsx11("h3", { className: "vos-section-title", children: "Readings" }),
|
|
4003
|
+
nested.length === 0 ? /* @__PURE__ */ jsx11("p", { className: "vos-hint", children: "No readings logged yet." }) : /* @__PURE__ */ jsx11("ul", { className: "vos-backlinks", children: nested[0].readings.map((r) => /* @__PURE__ */ jsx11("li", { children: /* @__PURE__ */ jsxs10(
|
|
3749
4004
|
"button",
|
|
3750
4005
|
{
|
|
3751
4006
|
type: "button",
|
|
3752
4007
|
className: "vos-backlink",
|
|
3753
4008
|
onClick: () => onOpenRecord(r.id),
|
|
3754
4009
|
children: [
|
|
3755
|
-
/* @__PURE__ */
|
|
3756
|
-
/* @__PURE__ */
|
|
4010
|
+
/* @__PURE__ */ jsx11("span", { className: "vos-backlink-title", children: formatValue(r.Title) }),
|
|
4011
|
+
/* @__PURE__ */ jsxs10("span", { className: "vos-chip vos-pill vos-pill-neutral", children: [
|
|
4012
|
+
readingBeliefs(r).length,
|
|
4013
|
+
" belief",
|
|
4014
|
+
readingBeliefs(r).length === 1 ? "" : "s"
|
|
4015
|
+
] })
|
|
3757
4016
|
]
|
|
3758
4017
|
}
|
|
3759
4018
|
) }, r.id)) })
|
|
@@ -3765,19 +4024,20 @@ function EvidenceTab({
|
|
|
3765
4024
|
import { useMemo as useMemo4, useState as useState10 } from "react";
|
|
3766
4025
|
|
|
3767
4026
|
// src/register-table.tsx
|
|
3768
|
-
import { jsx as
|
|
4027
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3769
4028
|
function RegisterTable({
|
|
3770
4029
|
register,
|
|
3771
4030
|
records,
|
|
3772
4031
|
onRowClick,
|
|
3773
|
-
selectedId
|
|
4032
|
+
selectedId,
|
|
4033
|
+
assumptionTitles
|
|
3774
4034
|
}) {
|
|
3775
4035
|
const columns = columnsFor(register);
|
|
3776
4036
|
if (records.length === 0) {
|
|
3777
|
-
return /* @__PURE__ */
|
|
4037
|
+
return /* @__PURE__ */ jsx12("p", { className: "vos-empty", children: "No records yet." });
|
|
3778
4038
|
}
|
|
3779
|
-
return /* @__PURE__ */
|
|
3780
|
-
/* @__PURE__ */
|
|
4039
|
+
return /* @__PURE__ */ jsx12("div", { className: "vos-card vos-table-scroll", children: /* @__PURE__ */ jsxs11("table", { className: "vos-table", children: [
|
|
4040
|
+
/* @__PURE__ */ jsx12("thead", { children: /* @__PURE__ */ jsx12("tr", { children: columns.map((c) => /* @__PURE__ */ jsx12(
|
|
3781
4041
|
"th",
|
|
3782
4042
|
{
|
|
3783
4043
|
scope: "col",
|
|
@@ -3786,9 +4046,9 @@ function RegisterTable({
|
|
|
3786
4046
|
},
|
|
3787
4047
|
c.key
|
|
3788
4048
|
)) }) }),
|
|
3789
|
-
/* @__PURE__ */
|
|
4049
|
+
/* @__PURE__ */ jsx12("tbody", { children: records.map((record) => {
|
|
3790
4050
|
const isSelected = record.id === selectedId;
|
|
3791
|
-
return /* @__PURE__ */
|
|
4051
|
+
return /* @__PURE__ */ jsx12(
|
|
3792
4052
|
"tr",
|
|
3793
4053
|
{
|
|
3794
4054
|
onClick: () => onRowClick?.(record.id),
|
|
@@ -3801,11 +4061,19 @@ function RegisterTable({
|
|
|
3801
4061
|
tabIndex: onRowClick ? 0 : void 0,
|
|
3802
4062
|
"aria-selected": isSelected,
|
|
3803
4063
|
className: isSelected ? "is-selected" : void 0,
|
|
3804
|
-
children: columns.map((c, i) => /* @__PURE__ */
|
|
4064
|
+
children: columns.map((c, i) => /* @__PURE__ */ jsx12(
|
|
3805
4065
|
"td",
|
|
3806
4066
|
{
|
|
3807
4067
|
className: c.align === "right" ? "vos-r" : void 0,
|
|
3808
|
-
children: /* @__PURE__ */
|
|
4068
|
+
children: /* @__PURE__ */ jsx12(
|
|
4069
|
+
Cell,
|
|
4070
|
+
{
|
|
4071
|
+
column: c,
|
|
4072
|
+
record,
|
|
4073
|
+
headline: i === 0,
|
|
4074
|
+
chips: i === 0 && register === "readings" ? readingAssumptionChips(record, assumptionTitles) : void 0
|
|
4075
|
+
}
|
|
4076
|
+
)
|
|
3809
4077
|
},
|
|
3810
4078
|
c.key
|
|
3811
4079
|
))
|
|
@@ -3818,25 +4086,32 @@ function RegisterTable({
|
|
|
3818
4086
|
function Cell({
|
|
3819
4087
|
column,
|
|
3820
4088
|
record,
|
|
3821
|
-
headline
|
|
4089
|
+
headline,
|
|
4090
|
+
chips
|
|
3822
4091
|
}) {
|
|
3823
4092
|
const raw = cellValue(column, record);
|
|
3824
4093
|
if (column.kind === "status") {
|
|
3825
|
-
return /* @__PURE__ */
|
|
4094
|
+
return /* @__PURE__ */ jsx12(StatusPill, { status: raw == null ? null : String(raw) });
|
|
3826
4095
|
}
|
|
3827
4096
|
if (column.kind === "risk") {
|
|
3828
|
-
return typeof raw === "number" ? /* @__PURE__ */
|
|
4097
|
+
return typeof raw === "number" ? /* @__PURE__ */ jsx12(RiskBar, { risk: raw }) : /* @__PURE__ */ jsx12("span", { className: "vos-muted", children: "\u2014" });
|
|
3829
4098
|
}
|
|
3830
4099
|
if (column.kind === "confidence") {
|
|
3831
|
-
return typeof raw === "number" ? /* @__PURE__ */
|
|
4100
|
+
return typeof raw === "number" ? /* @__PURE__ */ jsx12(ConfidenceCell, { confidence: raw }) : /* @__PURE__ */ jsx12("span", { className: "vos-muted", children: "\u2014" });
|
|
3832
4101
|
}
|
|
3833
4102
|
const text = headline && (raw === null || raw === void 0 || raw === "") ? primaryLabel(record) : formatValue(raw);
|
|
3834
|
-
|
|
4103
|
+
if (headline && chips && chips.length > 0) {
|
|
4104
|
+
return /* @__PURE__ */ jsxs11("span", { className: "vos-ttl-wrap", children: [
|
|
4105
|
+
/* @__PURE__ */ jsx12("span", { className: "vos-ttl", children: text }),
|
|
4106
|
+
/* @__PURE__ */ jsx12("span", { className: "vos-reading-chips", children: chips.map((chip, n) => /* @__PURE__ */ jsx12("span", { className: "vos-chip vos-pill vos-pill-neutral", children: chip }, n)) })
|
|
4107
|
+
] });
|
|
4108
|
+
}
|
|
4109
|
+
return /* @__PURE__ */ jsx12("span", { className: headline ? "vos-ttl" : void 0, children: text });
|
|
3835
4110
|
}
|
|
3836
4111
|
|
|
3837
4112
|
// src/record-drawer.tsx
|
|
3838
4113
|
import { useEffect as useEffect3, useState as useState6 } from "react";
|
|
3839
|
-
import { Fragment as Fragment9, jsx as
|
|
4114
|
+
import { Fragment as Fragment9, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3840
4115
|
var DERIVED_SUB = {
|
|
3841
4116
|
confidence: "Signed average of concluded readings",
|
|
3842
4117
|
risk: "Impact \xD7 (1 \u2212 Confidence\u207A/100)",
|
|
@@ -3909,23 +4184,23 @@ function RecordDrawer({
|
|
|
3909
4184
|
const setField = (key, value) => setDraft((d) => ({ ...d, [key]: value }));
|
|
3910
4185
|
const errors = editing ? draftErrors(register, draft) : {};
|
|
3911
4186
|
const hasErrors = Object.keys(errors).length > 0;
|
|
3912
|
-
return /* @__PURE__ */
|
|
4187
|
+
return /* @__PURE__ */ jsxs12(
|
|
3913
4188
|
DrawerShell,
|
|
3914
4189
|
{
|
|
3915
4190
|
open,
|
|
3916
4191
|
onClose,
|
|
3917
4192
|
ariaLabel: `${REGISTER_LABEL[register]} record`,
|
|
3918
4193
|
children: [
|
|
3919
|
-
/* @__PURE__ */
|
|
3920
|
-
/* @__PURE__ */
|
|
3921
|
-
/* @__PURE__ */
|
|
3922
|
-
/* @__PURE__ */
|
|
4194
|
+
/* @__PURE__ */ jsxs12("header", { className: "vos-drawer-header", children: [
|
|
4195
|
+
/* @__PURE__ */ jsxs12("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
4196
|
+
/* @__PURE__ */ jsx13("p", { className: "vos-drawer-eyebrow", children: REGISTER_LABEL[register] }),
|
|
4197
|
+
/* @__PURE__ */ jsx13("h2", { className: "vos-drawer-title", children: record ? primaryLabel(record) : loading ? "Loading\u2026" : "\u2014" })
|
|
3923
4198
|
] }),
|
|
3924
|
-
record ? /* @__PURE__ */
|
|
4199
|
+
record ? /* @__PURE__ */ jsxs12("span", { className: "vos-verbadge", children: [
|
|
3925
4200
|
"v",
|
|
3926
4201
|
formatValue(record.version)
|
|
3927
4202
|
] }) : null,
|
|
3928
|
-
record && !editing && onOpenFull ? /* @__PURE__ */
|
|
4203
|
+
record && !editing && onOpenFull ? /* @__PURE__ */ jsx13(
|
|
3929
4204
|
"button",
|
|
3930
4205
|
{
|
|
3931
4206
|
type: "button",
|
|
@@ -3934,7 +4209,7 @@ function RecordDrawer({
|
|
|
3934
4209
|
children: "Full page \u2197"
|
|
3935
4210
|
}
|
|
3936
4211
|
) : null,
|
|
3937
|
-
record && !editing ? /* @__PURE__ */
|
|
4212
|
+
record && !editing ? /* @__PURE__ */ jsx13(
|
|
3938
4213
|
"button",
|
|
3939
4214
|
{
|
|
3940
4215
|
type: "button",
|
|
@@ -3943,7 +4218,7 @@ function RecordDrawer({
|
|
|
3943
4218
|
children: "Edit"
|
|
3944
4219
|
}
|
|
3945
4220
|
) : null,
|
|
3946
|
-
/* @__PURE__ */
|
|
4221
|
+
/* @__PURE__ */ jsx13(
|
|
3947
4222
|
"button",
|
|
3948
4223
|
{
|
|
3949
4224
|
type: "button",
|
|
@@ -3954,14 +4229,14 @@ function RecordDrawer({
|
|
|
3954
4229
|
}
|
|
3955
4230
|
)
|
|
3956
4231
|
] }),
|
|
3957
|
-
/* @__PURE__ */
|
|
3958
|
-
derived ? /* @__PURE__ */
|
|
3959
|
-
/* @__PURE__ */
|
|
3960
|
-
/* @__PURE__ */
|
|
4232
|
+
/* @__PURE__ */ jsx13("div", { className: "vos-drawer-body", children: loading ? /* @__PURE__ */ jsx13("p", { className: "vos-muted", children: "Loading record\u2026" }) : error ? /* @__PURE__ */ jsx13("p", { className: "vos-error", children: error }) : !record ? /* @__PURE__ */ jsx13("p", { className: "vos-muted", children: "No record." }) : /* @__PURE__ */ jsxs12(Fragment9, { children: [
|
|
4233
|
+
derived ? /* @__PURE__ */ jsxs12("div", { children: [
|
|
4234
|
+
/* @__PURE__ */ jsxs12("div", { className: "vos-derived", children: [
|
|
4235
|
+
/* @__PURE__ */ jsxs12("div", { className: "vos-derived-head", children: [
|
|
3961
4236
|
"Derived",
|
|
3962
|
-
/* @__PURE__ */
|
|
4237
|
+
/* @__PURE__ */ jsx13("span", { className: "vos-lock", children: "\u{1F512} computed on write \u2014 not editable" })
|
|
3963
4238
|
] }),
|
|
3964
|
-
/* @__PURE__ */
|
|
4239
|
+
/* @__PURE__ */ jsx13("div", { className: "vos-dgrid", children: Object.entries(derived).map(([key, value]) => /* @__PURE__ */ jsx13(
|
|
3965
4240
|
DerivedCell,
|
|
3966
4241
|
{
|
|
3967
4242
|
field: key,
|
|
@@ -3973,11 +4248,11 @@ function RecordDrawer({
|
|
|
3973
4248
|
key
|
|
3974
4249
|
)) })
|
|
3975
4250
|
] }),
|
|
3976
|
-
"confidence" in derived && why ? /* @__PURE__ */
|
|
4251
|
+
"confidence" in derived && why ? /* @__PURE__ */ jsx13("div", { className: "vos-why-panel", children: /* @__PURE__ */ jsx13(UnderstandingPanel, { assumption: record, basePath }) }) : null
|
|
3977
4252
|
] }) : null,
|
|
3978
|
-
conflict ? /* @__PURE__ */
|
|
3979
|
-
saveError ? /* @__PURE__ */
|
|
3980
|
-
editing ? /* @__PURE__ */
|
|
4253
|
+
conflict ? /* @__PURE__ */ jsx13(ConflictBanner2, { message: conflict, onReload: reloadLatest }) : null,
|
|
4254
|
+
saveError ? /* @__PURE__ */ jsx13("p", { role: "alert", className: "vos-banner vos-banner-crit", children: saveError }) : null,
|
|
4255
|
+
editing ? /* @__PURE__ */ jsx13(
|
|
3981
4256
|
EditFields,
|
|
3982
4257
|
{
|
|
3983
4258
|
register,
|
|
@@ -3985,18 +4260,35 @@ function RecordDrawer({
|
|
|
3985
4260
|
errors,
|
|
3986
4261
|
onField: setField
|
|
3987
4262
|
}
|
|
3988
|
-
) : /* @__PURE__ */
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
4263
|
+
) : /* @__PURE__ */ jsxs12(Fragment9, { children: [
|
|
4264
|
+
/* @__PURE__ */ jsx13("div", { className: "vos-detail-list", children: rows.map((row) => /* @__PURE__ */ jsx13(
|
|
4265
|
+
DetailRowView,
|
|
4266
|
+
{
|
|
4267
|
+
row,
|
|
4268
|
+
onOpenRecord
|
|
4269
|
+
},
|
|
4270
|
+
row.key
|
|
4271
|
+
)) }),
|
|
4272
|
+
typeof record.body === "string" && record.body.trim() ? /* @__PURE__ */ jsxs12("section", { className: "vos-record-prose", children: [
|
|
4273
|
+
/* @__PURE__ */ jsx13("div", { className: "vos-detail-k", children: register === "readings" ? "Quote" : "Narrative" }),
|
|
4274
|
+
/* @__PURE__ */ jsx13(Markdown, { text: record.body })
|
|
4275
|
+
] }) : null,
|
|
4276
|
+
register === "readings" ? /* @__PURE__ */ jsxs12("section", { className: "vos-record-prose", children: [
|
|
4277
|
+
/* @__PURE__ */ jsx13("div", { className: "vos-detail-k", children: "Per-belief verdicts" }),
|
|
4278
|
+
/* @__PURE__ */ jsx13(
|
|
4279
|
+
BeliefVerdicts,
|
|
4280
|
+
{
|
|
4281
|
+
reading: record,
|
|
4282
|
+
assumptions: related?.assumptions ?? [],
|
|
4283
|
+
onOpenRecord
|
|
4284
|
+
}
|
|
4285
|
+
)
|
|
4286
|
+
] }) : null
|
|
4287
|
+
] })
|
|
3996
4288
|
] }) }),
|
|
3997
4289
|
record && !loading && !error && !editing ? children : null,
|
|
3998
|
-
record && editing ? /* @__PURE__ */
|
|
3999
|
-
/* @__PURE__ */
|
|
4290
|
+
record && editing ? /* @__PURE__ */ jsxs12("footer", { className: "vos-drawer-footer", children: [
|
|
4291
|
+
/* @__PURE__ */ jsx13(
|
|
4000
4292
|
"button",
|
|
4001
4293
|
{
|
|
4002
4294
|
type: "button",
|
|
@@ -4006,7 +4298,7 @@ function RecordDrawer({
|
|
|
4006
4298
|
children: "Cancel"
|
|
4007
4299
|
}
|
|
4008
4300
|
),
|
|
4009
|
-
/* @__PURE__ */
|
|
4301
|
+
/* @__PURE__ */ jsx13(
|
|
4010
4302
|
"button",
|
|
4011
4303
|
{
|
|
4012
4304
|
type: "button",
|
|
@@ -4017,7 +4309,7 @@ function RecordDrawer({
|
|
|
4017
4309
|
children: saving ? "Saving\u2026" : "Save"
|
|
4018
4310
|
}
|
|
4019
4311
|
)
|
|
4020
|
-
] }) : record ? /* @__PURE__ */
|
|
4312
|
+
] }) : record ? /* @__PURE__ */ jsxs12("footer", { className: "vos-drawer-footer", children: [
|
|
4021
4313
|
record.id,
|
|
4022
4314
|
" \xB7 updated ",
|
|
4023
4315
|
formatValue(record.updatedAt)
|
|
@@ -4030,11 +4322,11 @@ function DetailRowView({
|
|
|
4030
4322
|
row,
|
|
4031
4323
|
onOpenRecord
|
|
4032
4324
|
}) {
|
|
4033
|
-
return /* @__PURE__ */
|
|
4034
|
-
/* @__PURE__ */
|
|
4035
|
-
/* @__PURE__ */
|
|
4036
|
-
/* @__PURE__ */
|
|
4037
|
-
b.assumption ? /* @__PURE__ */
|
|
4325
|
+
return /* @__PURE__ */ jsxs12("div", { className: "vos-detail-row", children: [
|
|
4326
|
+
/* @__PURE__ */ jsx13("span", { className: "vos-detail-k", children: row.label }),
|
|
4327
|
+
/* @__PURE__ */ jsx13("span", { className: "vos-detail-v", children: row.kind === "relation" ? row.items && row.items.length ? /* @__PURE__ */ jsx13(RelationLinks, { items: row.items, onOpenRecord }) : "\u2014" : row.kind === "owner" ? row.names && row.names.length ? row.names.join(", ") : "\u2014" : row.kind === "bar-lines" ? row.bars && row.bars.length ? /* @__PURE__ */ jsx13("ul", { className: "vos-bars", children: row.bars.map((b, i) => /* @__PURE__ */ jsxs12("li", { className: "vos-bar-line", children: [
|
|
4328
|
+
/* @__PURE__ */ jsx13("span", { className: "vos-bar-if", children: b.rightIf || "\u2014" }),
|
|
4329
|
+
b.assumption ? /* @__PURE__ */ jsx13(
|
|
4038
4330
|
InlineLink,
|
|
4039
4331
|
{
|
|
4040
4332
|
id: b.assumption.id,
|
|
@@ -4042,7 +4334,7 @@ function DetailRowView({
|
|
|
4042
4334
|
onOpenRecord
|
|
4043
4335
|
}
|
|
4044
4336
|
) : null,
|
|
4045
|
-
/* @__PURE__ */
|
|
4337
|
+
/* @__PURE__ */ jsx13(
|
|
4046
4338
|
"span",
|
|
4047
4339
|
{
|
|
4048
4340
|
className: b.barVerdict ? "vos-pill vos-pill-good" : "vos-pill vos-pill-neutral",
|
|
@@ -4056,9 +4348,9 @@ function RelationLinks({
|
|
|
4056
4348
|
items,
|
|
4057
4349
|
onOpenRecord
|
|
4058
4350
|
}) {
|
|
4059
|
-
return /* @__PURE__ */
|
|
4351
|
+
return /* @__PURE__ */ jsx13("span", { className: "vos-detail-links", children: items.map((item, i) => /* @__PURE__ */ jsxs12("span", { children: [
|
|
4060
4352
|
i > 0 ? ", " : null,
|
|
4061
|
-
/* @__PURE__ */
|
|
4353
|
+
/* @__PURE__ */ jsx13(InlineLink, { id: item.id, title: item.title, onOpenRecord })
|
|
4062
4354
|
] }, item.id)) });
|
|
4063
4355
|
}
|
|
4064
4356
|
function InlineLink({
|
|
@@ -4066,7 +4358,7 @@ function InlineLink({
|
|
|
4066
4358
|
title,
|
|
4067
4359
|
onOpenRecord
|
|
4068
4360
|
}) {
|
|
4069
|
-
return onOpenRecord ? /* @__PURE__ */
|
|
4361
|
+
return onOpenRecord ? /* @__PURE__ */ jsx13(
|
|
4070
4362
|
"button",
|
|
4071
4363
|
{
|
|
4072
4364
|
type: "button",
|
|
@@ -4074,7 +4366,7 @@ function InlineLink({
|
|
|
4074
4366
|
onClick: () => onOpenRecord(id),
|
|
4075
4367
|
children: title
|
|
4076
4368
|
}
|
|
4077
|
-
) : /* @__PURE__ */
|
|
4369
|
+
) : /* @__PURE__ */ jsx13("span", { children: title });
|
|
4078
4370
|
}
|
|
4079
4371
|
function DerivedCell({
|
|
4080
4372
|
field,
|
|
@@ -4090,10 +4382,10 @@ function DerivedCell({
|
|
|
4090
4382
|
toneClass = heroToneClass(derivedTone(field, num3));
|
|
4091
4383
|
display = field === "confidence" ? formatSigned(num3) : String(Math.round(num3));
|
|
4092
4384
|
}
|
|
4093
|
-
return /* @__PURE__ */
|
|
4094
|
-
/* @__PURE__ */
|
|
4385
|
+
return /* @__PURE__ */ jsxs12("div", { className: "vos-dcell", children: [
|
|
4386
|
+
/* @__PURE__ */ jsxs12("div", { className: "vos-dcell-k", children: [
|
|
4095
4387
|
derivedLabel(field),
|
|
4096
|
-
showWhy ? /* @__PURE__ */
|
|
4388
|
+
showWhy ? /* @__PURE__ */ jsxs12(
|
|
4097
4389
|
"button",
|
|
4098
4390
|
{
|
|
4099
4391
|
type: "button",
|
|
@@ -4107,17 +4399,17 @@ function DerivedCell({
|
|
|
4107
4399
|
}
|
|
4108
4400
|
) : null
|
|
4109
4401
|
] }),
|
|
4110
|
-
/* @__PURE__ */
|
|
4111
|
-
DERIVED_SUB[field] ? /* @__PURE__ */
|
|
4402
|
+
/* @__PURE__ */ jsx13("div", { className: `vos-dcell-v ${toneClass}`, children: display }),
|
|
4403
|
+
DERIVED_SUB[field] ? /* @__PURE__ */ jsx13("div", { className: "vos-dcell-sub", children: DERIVED_SUB[field] }) : null
|
|
4112
4404
|
] });
|
|
4113
4405
|
}
|
|
4114
4406
|
function ConflictBanner2({
|
|
4115
4407
|
message,
|
|
4116
4408
|
onReload
|
|
4117
4409
|
}) {
|
|
4118
|
-
return /* @__PURE__ */
|
|
4119
|
-
/* @__PURE__ */
|
|
4120
|
-
/* @__PURE__ */
|
|
4410
|
+
return /* @__PURE__ */ jsxs12("div", { role: "alert", className: "vos-banner vos-banner-warn", children: [
|
|
4411
|
+
/* @__PURE__ */ jsx13("div", { className: "vos-banner-body", children: /* @__PURE__ */ jsx13("span", { children: message }) }),
|
|
4412
|
+
/* @__PURE__ */ jsx13("button", { type: "button", onClick: onReload, children: "Review the latest" })
|
|
4121
4413
|
] });
|
|
4122
4414
|
}
|
|
4123
4415
|
|
|
@@ -4125,20 +4417,13 @@ function ConflictBanner2({
|
|
|
4125
4417
|
import { useMemo as useMemo2, useState as useState7 } from "react";
|
|
4126
4418
|
|
|
4127
4419
|
// src/form-fields.ts
|
|
4128
|
-
import {
|
|
4129
|
-
MARKET_RUNG_VALUES,
|
|
4130
|
-
TESTING_RUNGS
|
|
4131
|
-
} from "@validation-os/core";
|
|
4132
4420
|
var ASSUMPTION_STATUS = ["Draft", "Live", "Invalidated"];
|
|
4133
4421
|
var EXPERIMENT_STATUS = ["Draft", "Running", "Closed"];
|
|
4134
4422
|
var CLOSURE_REASON = ["Completed", "Early-stop", "Kill"];
|
|
4135
4423
|
var EXPERIMENT_OUTCOME = ["Achieved", "Missed", "Dropped"];
|
|
4136
4424
|
var DECISION_STATUS2 = ["Active", "Provisional", "Superseded", "Reversed"];
|
|
4137
4425
|
var GLOSSARY_STATUS = ["Active", "Provisional", "Superseded"];
|
|
4138
|
-
var RESULT = ["Validated", "Invalidated", "Inconclusive"];
|
|
4139
|
-
var MAGNITUDE = ["Low", "Typical", "High"];
|
|
4140
4426
|
var FEASIBILITY = ["High", "Medium", "Low"];
|
|
4141
|
-
var RUNGS = [...TESTING_RUNGS, ...MARKET_RUNG_VALUES];
|
|
4142
4427
|
var QUALITY = ["1", "0.7", "0.5"];
|
|
4143
4428
|
var FIELDS = {
|
|
4144
4429
|
assumptions: [
|
|
@@ -4171,8 +4456,10 @@ var FIELDS = {
|
|
|
4171
4456
|
readings: [
|
|
4172
4457
|
{ key: "Title", label: "Reading", kind: "text", required: true },
|
|
4173
4458
|
{ key: "Source", label: "Source", kind: "text" },
|
|
4174
|
-
|
|
4175
|
-
|
|
4459
|
+
// Rung / Result / Magnitude band / Grading justification are PER BELIEF now
|
|
4460
|
+
// (OPS-1305) — carried in `beliefs[]`, not on the row. They are omitted here
|
|
4461
|
+
// so the create form can never write a dead row-level field; grading a
|
|
4462
|
+
// reading's beliefs is a deferred follow-up (a `beliefs[]` editor).
|
|
4176
4463
|
{
|
|
4177
4464
|
key: "Representativeness",
|
|
4178
4465
|
label: "Representativeness",
|
|
@@ -4187,17 +4474,7 @@ var FIELDS = {
|
|
|
4187
4474
|
options: QUALITY,
|
|
4188
4475
|
coerce: "number"
|
|
4189
4476
|
},
|
|
4190
|
-
{
|
|
4191
|
-
key: "magnitudeBand",
|
|
4192
|
-
label: "Magnitude band",
|
|
4193
|
-
kind: "select",
|
|
4194
|
-
options: MAGNITUDE
|
|
4195
|
-
},
|
|
4196
|
-
{
|
|
4197
|
-
key: "Grading justification",
|
|
4198
|
-
label: "Grading justification",
|
|
4199
|
-
kind: "textarea"
|
|
4200
|
-
},
|
|
4477
|
+
{ key: "body", label: "Quote", kind: "textarea" },
|
|
4201
4478
|
{ key: "Date", label: "Date", kind: "text", placeholder: "YYYY-MM-DD" }
|
|
4202
4479
|
],
|
|
4203
4480
|
decisions: [
|
|
@@ -4239,7 +4516,7 @@ function toCreatePayload(register, draft) {
|
|
|
4239
4516
|
}
|
|
4240
4517
|
|
|
4241
4518
|
// src/record-form.tsx
|
|
4242
|
-
import { jsx as
|
|
4519
|
+
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
4243
4520
|
function RecordForm({
|
|
4244
4521
|
register,
|
|
4245
4522
|
basePath,
|
|
@@ -4262,9 +4539,9 @@ function RecordForm({
|
|
|
4262
4539
|
} catch {
|
|
4263
4540
|
}
|
|
4264
4541
|
};
|
|
4265
|
-
return /* @__PURE__ */
|
|
4266
|
-
/* @__PURE__ */
|
|
4267
|
-
fields.map((field) => /* @__PURE__ */
|
|
4542
|
+
return /* @__PURE__ */ jsxs13("form", { onSubmit, className: "vos-form", children: [
|
|
4543
|
+
/* @__PURE__ */ jsxs13("div", { className: "vos-form-body", children: [
|
|
4544
|
+
fields.map((field) => /* @__PURE__ */ jsx14(
|
|
4268
4545
|
Field,
|
|
4269
4546
|
{
|
|
4270
4547
|
field,
|
|
@@ -4273,11 +4550,11 @@ function RecordForm({
|
|
|
4273
4550
|
},
|
|
4274
4551
|
field.key
|
|
4275
4552
|
)),
|
|
4276
|
-
error ? /* @__PURE__ */
|
|
4553
|
+
error ? /* @__PURE__ */ jsx14("p", { className: "vos-error", children: error }) : null
|
|
4277
4554
|
] }),
|
|
4278
|
-
/* @__PURE__ */
|
|
4279
|
-
/* @__PURE__ */
|
|
4280
|
-
/* @__PURE__ */
|
|
4555
|
+
/* @__PURE__ */ jsxs13("footer", { className: "vos-drawer-footer", children: [
|
|
4556
|
+
/* @__PURE__ */ jsx14("button", { type: "button", onClick: onCancel, className: "vos-btn vos-btn-ghost vos-btn-sm", children: "Cancel" }),
|
|
4557
|
+
/* @__PURE__ */ jsx14(
|
|
4281
4558
|
"button",
|
|
4282
4559
|
{
|
|
4283
4560
|
type: "submit",
|
|
@@ -4296,12 +4573,12 @@ function Field({
|
|
|
4296
4573
|
onChange
|
|
4297
4574
|
}) {
|
|
4298
4575
|
const id = `field-${field.key}`;
|
|
4299
|
-
return /* @__PURE__ */
|
|
4300
|
-
/* @__PURE__ */
|
|
4576
|
+
return /* @__PURE__ */ jsxs13("div", { className: "vos-field", children: [
|
|
4577
|
+
/* @__PURE__ */ jsxs13("label", { htmlFor: id, className: FIELD_LABEL_CLASS, children: [
|
|
4301
4578
|
field.label,
|
|
4302
|
-
field.required ? /* @__PURE__ */
|
|
4579
|
+
field.required ? /* @__PURE__ */ jsx14("span", { className: "vos-req", children: " *" }) : null
|
|
4303
4580
|
] }),
|
|
4304
|
-
field.kind === "textarea" ? /* @__PURE__ */
|
|
4581
|
+
field.kind === "textarea" ? /* @__PURE__ */ jsx14(
|
|
4305
4582
|
"textarea",
|
|
4306
4583
|
{
|
|
4307
4584
|
id,
|
|
@@ -4311,7 +4588,7 @@ function Field({
|
|
|
4311
4588
|
onChange: (e) => onChange(e.target.value),
|
|
4312
4589
|
className: FIELD_CONTROL_CLASS
|
|
4313
4590
|
}
|
|
4314
|
-
) : field.kind === "select" ? /* @__PURE__ */
|
|
4591
|
+
) : field.kind === "select" ? /* @__PURE__ */ jsxs13(
|
|
4315
4592
|
"select",
|
|
4316
4593
|
{
|
|
4317
4594
|
id,
|
|
@@ -4319,11 +4596,11 @@ function Field({
|
|
|
4319
4596
|
onChange: (e) => onChange(e.target.value),
|
|
4320
4597
|
className: FIELD_CONTROL_CLASS,
|
|
4321
4598
|
children: [
|
|
4322
|
-
/* @__PURE__ */
|
|
4323
|
-
field.options?.map((opt) => /* @__PURE__ */
|
|
4599
|
+
/* @__PURE__ */ jsx14("option", { value: "", children: "\u2014" }),
|
|
4600
|
+
field.options?.map((opt) => /* @__PURE__ */ jsx14("option", { value: opt, children: opt }, opt))
|
|
4324
4601
|
]
|
|
4325
4602
|
}
|
|
4326
|
-
) : /* @__PURE__ */
|
|
4603
|
+
) : /* @__PURE__ */ jsx14(
|
|
4327
4604
|
"input",
|
|
4328
4605
|
{
|
|
4329
4606
|
id,
|
|
@@ -4359,7 +4636,7 @@ function linkChoicesFrom(register) {
|
|
|
4359
4636
|
}
|
|
4360
4637
|
|
|
4361
4638
|
// src/relation-editor.tsx
|
|
4362
|
-
import { jsx as
|
|
4639
|
+
import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4363
4640
|
function RelationEditor({
|
|
4364
4641
|
register,
|
|
4365
4642
|
recordId,
|
|
@@ -4393,10 +4670,10 @@ function RelationEditor({
|
|
|
4393
4670
|
} catch {
|
|
4394
4671
|
}
|
|
4395
4672
|
};
|
|
4396
|
-
return /* @__PURE__ */
|
|
4397
|
-
/* @__PURE__ */
|
|
4398
|
-
/* @__PURE__ */
|
|
4399
|
-
/* @__PURE__ */
|
|
4673
|
+
return /* @__PURE__ */ jsxs14("section", { className: "vos-relation", children: [
|
|
4674
|
+
/* @__PURE__ */ jsx15("h3", { className: "vos-sectitle", children: "Link a record" }),
|
|
4675
|
+
/* @__PURE__ */ jsxs14("div", { className: "vos-field-stack", children: [
|
|
4676
|
+
/* @__PURE__ */ jsxs14(
|
|
4400
4677
|
"select",
|
|
4401
4678
|
{
|
|
4402
4679
|
"aria-label": "Relation",
|
|
@@ -4407,12 +4684,12 @@ function RelationEditor({
|
|
|
4407
4684
|
},
|
|
4408
4685
|
className: FIELD_CONTROL_CLASS,
|
|
4409
4686
|
children: [
|
|
4410
|
-
/* @__PURE__ */
|
|
4411
|
-
choices.map((c) => /* @__PURE__ */
|
|
4687
|
+
/* @__PURE__ */ jsx15("option", { value: "", children: "Choose a relation\u2026" }),
|
|
4688
|
+
choices.map((c) => /* @__PURE__ */ jsx15("option", { value: c.relation, children: c.label }, c.relation))
|
|
4412
4689
|
]
|
|
4413
4690
|
}
|
|
4414
4691
|
),
|
|
4415
|
-
active ? /* @__PURE__ */
|
|
4692
|
+
active ? /* @__PURE__ */ jsxs14(
|
|
4416
4693
|
"select",
|
|
4417
4694
|
{
|
|
4418
4695
|
"aria-label": "Target record",
|
|
@@ -4420,13 +4697,13 @@ function RelationEditor({
|
|
|
4420
4697
|
onChange: (e) => setTargetId(e.target.value),
|
|
4421
4698
|
className: FIELD_CONTROL_CLASS,
|
|
4422
4699
|
children: [
|
|
4423
|
-
/* @__PURE__ */
|
|
4424
|
-
targets.map((r) => /* @__PURE__ */
|
|
4700
|
+
/* @__PURE__ */ jsx15("option", { value: "", children: "Choose a record\u2026" }),
|
|
4701
|
+
targets.map((r) => /* @__PURE__ */ jsx15("option", { value: r.id, children: primaryLabel(r) }, r.id))
|
|
4425
4702
|
]
|
|
4426
4703
|
}
|
|
4427
4704
|
) : null,
|
|
4428
|
-
error ? /* @__PURE__ */
|
|
4429
|
-
/* @__PURE__ */
|
|
4705
|
+
error ? /* @__PURE__ */ jsx15("p", { className: "vos-error", children: error }) : null,
|
|
4706
|
+
/* @__PURE__ */ jsx15(
|
|
4430
4707
|
"button",
|
|
4431
4708
|
{
|
|
4432
4709
|
type: "button",
|
|
@@ -4493,7 +4770,7 @@ function useSavedViews(register) {
|
|
|
4493
4770
|
}
|
|
4494
4771
|
|
|
4495
4772
|
// src/register-browser.tsx
|
|
4496
|
-
import { jsx as
|
|
4773
|
+
import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4497
4774
|
function contextNeeds(register) {
|
|
4498
4775
|
return {
|
|
4499
4776
|
experiments: register === "assumptions" || register === "readings",
|
|
@@ -4557,6 +4834,9 @@ function RegisterBrowser({
|
|
|
4557
4834
|
readings: ctx.readings,
|
|
4558
4835
|
decisions: ctx.decisions
|
|
4559
4836
|
};
|
|
4837
|
+
const assumptionTitles = new Map(
|
|
4838
|
+
(ctx.assumptions ?? []).map((a) => [a.id, primaryLabel(a)])
|
|
4839
|
+
);
|
|
4560
4840
|
const patch = (p) => setDescriptor((d) => ({ ...d, ...p }));
|
|
4561
4841
|
const saveCurrentView = () => {
|
|
4562
4842
|
if (typeof window === "undefined") return;
|
|
@@ -4568,14 +4848,14 @@ function RegisterBrowser({
|
|
|
4568
4848
|
void _name;
|
|
4569
4849
|
setDescriptor(rest);
|
|
4570
4850
|
};
|
|
4571
|
-
return /* @__PURE__ */
|
|
4572
|
-
/* @__PURE__ */
|
|
4573
|
-
/* @__PURE__ */
|
|
4574
|
-
/* @__PURE__ */
|
|
4575
|
-
subtitle ? /* @__PURE__ */
|
|
4851
|
+
return /* @__PURE__ */ jsxs15("div", { children: [
|
|
4852
|
+
/* @__PURE__ */ jsxs15("div", { className: "vos-head", children: [
|
|
4853
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
4854
|
+
/* @__PURE__ */ jsx16("h1", { children: REGISTER_LABEL[register] }),
|
|
4855
|
+
subtitle ? /* @__PURE__ */ jsx16("p", { children: subtitle }) : null
|
|
4576
4856
|
] }),
|
|
4577
|
-
/* @__PURE__ */
|
|
4578
|
-
/* @__PURE__ */
|
|
4857
|
+
/* @__PURE__ */ jsx16("div", { className: "vos-spacer" }),
|
|
4858
|
+
/* @__PURE__ */ jsx16(
|
|
4579
4859
|
"button",
|
|
4580
4860
|
{
|
|
4581
4861
|
type: "button",
|
|
@@ -4584,7 +4864,7 @@ function RegisterBrowser({
|
|
|
4584
4864
|
children: "\u21BB Refresh"
|
|
4585
4865
|
}
|
|
4586
4866
|
),
|
|
4587
|
-
/* @__PURE__ */
|
|
4867
|
+
/* @__PURE__ */ jsxs15(
|
|
4588
4868
|
"button",
|
|
4589
4869
|
{
|
|
4590
4870
|
type: "button",
|
|
@@ -4597,10 +4877,10 @@ function RegisterBrowser({
|
|
|
4597
4877
|
}
|
|
4598
4878
|
)
|
|
4599
4879
|
] }),
|
|
4600
|
-
/* @__PURE__ */
|
|
4880
|
+
/* @__PURE__ */ jsx16("div", { className: "vos-tabs", role: "tablist", "aria-label": "Views", children: shaped.tabs.map((tab) => {
|
|
4601
4881
|
const active = tab.id === shaped.activeTabId;
|
|
4602
4882
|
const badge = badgeFor(tab);
|
|
4603
|
-
return /* @__PURE__ */
|
|
4883
|
+
return /* @__PURE__ */ jsxs15(
|
|
4604
4884
|
"button",
|
|
4605
4885
|
{
|
|
4606
4886
|
type: "button",
|
|
@@ -4610,13 +4890,13 @@ function RegisterBrowser({
|
|
|
4610
4890
|
onClick: () => patch({ tabId: tab.id }),
|
|
4611
4891
|
children: [
|
|
4612
4892
|
tab.label,
|
|
4613
|
-
badge !== null ? /* @__PURE__ */
|
|
4893
|
+
badge !== null ? /* @__PURE__ */ jsx16("span", { className: "vos-tab-badge", children: badge }) : null
|
|
4614
4894
|
]
|
|
4615
4895
|
},
|
|
4616
4896
|
tab.id
|
|
4617
4897
|
);
|
|
4618
4898
|
}) }),
|
|
4619
|
-
/* @__PURE__ */
|
|
4899
|
+
/* @__PURE__ */ jsx16(
|
|
4620
4900
|
ViewControls,
|
|
4621
4901
|
{
|
|
4622
4902
|
register,
|
|
@@ -4627,10 +4907,10 @@ function RegisterBrowser({
|
|
|
4627
4907
|
onQuery: (query) => patch({ query })
|
|
4628
4908
|
}
|
|
4629
4909
|
),
|
|
4630
|
-
/* @__PURE__ */
|
|
4631
|
-
/* @__PURE__ */
|
|
4632
|
-
savedViews.views.length === 0 ? /* @__PURE__ */
|
|
4633
|
-
/* @__PURE__ */
|
|
4910
|
+
/* @__PURE__ */ jsxs15("div", { className: "vos-saved-views", children: [
|
|
4911
|
+
/* @__PURE__ */ jsx16("span", { className: "vos-saved-label", children: "Saved views" }),
|
|
4912
|
+
savedViews.views.length === 0 ? /* @__PURE__ */ jsx16("span", { className: "vos-hint", children: "none yet" }) : savedViews.views.map((v) => /* @__PURE__ */ jsxs15("span", { className: "vos-saved-view", children: [
|
|
4913
|
+
/* @__PURE__ */ jsx16(
|
|
4634
4914
|
"button",
|
|
4635
4915
|
{
|
|
4636
4916
|
type: "button",
|
|
@@ -4639,7 +4919,7 @@ function RegisterBrowser({
|
|
|
4639
4919
|
children: v.name
|
|
4640
4920
|
}
|
|
4641
4921
|
),
|
|
4642
|
-
/* @__PURE__ */
|
|
4922
|
+
/* @__PURE__ */ jsx16(
|
|
4643
4923
|
"button",
|
|
4644
4924
|
{
|
|
4645
4925
|
type: "button",
|
|
@@ -4650,7 +4930,7 @@ function RegisterBrowser({
|
|
|
4650
4930
|
}
|
|
4651
4931
|
)
|
|
4652
4932
|
] }, v.name)),
|
|
4653
|
-
/* @__PURE__ */
|
|
4933
|
+
/* @__PURE__ */ jsx16(
|
|
4654
4934
|
"button",
|
|
4655
4935
|
{
|
|
4656
4936
|
type: "button",
|
|
@@ -4660,20 +4940,21 @@ function RegisterBrowser({
|
|
|
4660
4940
|
}
|
|
4661
4941
|
)
|
|
4662
4942
|
] }),
|
|
4663
|
-
loading && !records ? /* @__PURE__ */
|
|
4943
|
+
loading && !records ? /* @__PURE__ */ jsxs15("p", { className: "vos-muted", children: [
|
|
4664
4944
|
"Loading ",
|
|
4665
4945
|
REGISTER_LABEL[register].toLowerCase(),
|
|
4666
4946
|
"\u2026"
|
|
4667
|
-
] }) : error ? /* @__PURE__ */
|
|
4947
|
+
] }) : error ? /* @__PURE__ */ jsx16("p", { className: "vos-error", children: error }) : /* @__PURE__ */ jsx16(
|
|
4668
4948
|
ShapedBody,
|
|
4669
4949
|
{
|
|
4670
4950
|
register,
|
|
4671
4951
|
shaped,
|
|
4672
4952
|
onRowClick: setOpenId,
|
|
4673
|
-
selectedId: openId
|
|
4953
|
+
selectedId: openId,
|
|
4954
|
+
assumptionTitles
|
|
4674
4955
|
}
|
|
4675
4956
|
),
|
|
4676
|
-
/* @__PURE__ */
|
|
4957
|
+
/* @__PURE__ */ jsx16(
|
|
4677
4958
|
RecordDrawer,
|
|
4678
4959
|
{
|
|
4679
4960
|
register,
|
|
@@ -4690,7 +4971,7 @@ function RegisterBrowser({
|
|
|
4690
4971
|
refreshRecord();
|
|
4691
4972
|
refreshList();
|
|
4692
4973
|
},
|
|
4693
|
-
children: openId ? /* @__PURE__ */
|
|
4974
|
+
children: openId ? /* @__PURE__ */ jsx16(
|
|
4694
4975
|
RelationEditor,
|
|
4695
4976
|
{
|
|
4696
4977
|
register,
|
|
@@ -4704,18 +4985,18 @@ function RegisterBrowser({
|
|
|
4704
4985
|
) : null
|
|
4705
4986
|
}
|
|
4706
4987
|
),
|
|
4707
|
-
/* @__PURE__ */
|
|
4988
|
+
/* @__PURE__ */ jsxs15(
|
|
4708
4989
|
DrawerShell,
|
|
4709
4990
|
{
|
|
4710
4991
|
open: creating,
|
|
4711
4992
|
onClose: () => setCreating(false),
|
|
4712
4993
|
ariaLabel: `New ${REGISTER_SINGULAR[register]} record`,
|
|
4713
4994
|
children: [
|
|
4714
|
-
/* @__PURE__ */
|
|
4715
|
-
/* @__PURE__ */
|
|
4716
|
-
/* @__PURE__ */
|
|
4995
|
+
/* @__PURE__ */ jsx16("header", { className: "vos-drawer-header", children: /* @__PURE__ */ jsxs15("div", { children: [
|
|
4996
|
+
/* @__PURE__ */ jsx16("p", { className: "vos-drawer-eyebrow", children: "New" }),
|
|
4997
|
+
/* @__PURE__ */ jsx16("h2", { className: "vos-drawer-title", children: REGISTER_SINGULAR[register] })
|
|
4717
4998
|
] }) }),
|
|
4718
|
-
/* @__PURE__ */
|
|
4999
|
+
/* @__PURE__ */ jsx16(
|
|
4719
5000
|
RecordForm,
|
|
4720
5001
|
{
|
|
4721
5002
|
register,
|
|
@@ -4743,8 +5024,8 @@ function ViewControls({
|
|
|
4743
5024
|
}) {
|
|
4744
5025
|
const sortable = columnsFor(register);
|
|
4745
5026
|
const sort = descriptor.sort ?? null;
|
|
4746
|
-
return /* @__PURE__ */
|
|
4747
|
-
/* @__PURE__ */
|
|
5027
|
+
return /* @__PURE__ */ jsxs15("div", { className: "vos-view-controls", children: [
|
|
5028
|
+
/* @__PURE__ */ jsx16(
|
|
4748
5029
|
"input",
|
|
4749
5030
|
{
|
|
4750
5031
|
type: "search",
|
|
@@ -4755,24 +5036,24 @@ function ViewControls({
|
|
|
4755
5036
|
"aria-label": "Filter records"
|
|
4756
5037
|
}
|
|
4757
5038
|
),
|
|
4758
|
-
axes.length ? /* @__PURE__ */
|
|
4759
|
-
/* @__PURE__ */
|
|
4760
|
-
/* @__PURE__ */
|
|
5039
|
+
axes.length ? /* @__PURE__ */ jsxs15("label", { className: "vos-control", children: [
|
|
5040
|
+
/* @__PURE__ */ jsx16("span", { children: "Group" }),
|
|
5041
|
+
/* @__PURE__ */ jsxs15(
|
|
4761
5042
|
"select",
|
|
4762
5043
|
{
|
|
4763
5044
|
className: "vos-input",
|
|
4764
5045
|
value: descriptor.groupBy ?? "",
|
|
4765
5046
|
onChange: (e) => onGroupBy(e.target.value || null),
|
|
4766
5047
|
children: [
|
|
4767
|
-
/* @__PURE__ */
|
|
4768
|
-
axes.map((axis) => /* @__PURE__ */
|
|
5048
|
+
/* @__PURE__ */ jsx16("option", { value: "", children: "None" }),
|
|
5049
|
+
axes.map((axis) => /* @__PURE__ */ jsx16("option", { value: axis, children: axis }, axis))
|
|
4769
5050
|
]
|
|
4770
5051
|
}
|
|
4771
5052
|
)
|
|
4772
5053
|
] }) : null,
|
|
4773
|
-
/* @__PURE__ */
|
|
4774
|
-
/* @__PURE__ */
|
|
4775
|
-
/* @__PURE__ */
|
|
5054
|
+
/* @__PURE__ */ jsxs15("label", { className: "vos-control", children: [
|
|
5055
|
+
/* @__PURE__ */ jsx16("span", { children: "Sort" }),
|
|
5056
|
+
/* @__PURE__ */ jsxs15(
|
|
4776
5057
|
"select",
|
|
4777
5058
|
{
|
|
4778
5059
|
className: "vos-input",
|
|
@@ -4781,13 +5062,13 @@ function ViewControls({
|
|
|
4781
5062
|
e.target.value ? { key: e.target.value, dir: sort?.dir ?? "desc" } : null
|
|
4782
5063
|
),
|
|
4783
5064
|
children: [
|
|
4784
|
-
/* @__PURE__ */
|
|
4785
|
-
sortable.map((c) => /* @__PURE__ */
|
|
5065
|
+
/* @__PURE__ */ jsx16("option", { value: "", children: "Default" }),
|
|
5066
|
+
sortable.map((c) => /* @__PURE__ */ jsx16("option", { value: c.key, children: c.header }, c.key))
|
|
4786
5067
|
]
|
|
4787
5068
|
}
|
|
4788
5069
|
)
|
|
4789
5070
|
] }),
|
|
4790
|
-
sort ? /* @__PURE__ */
|
|
5071
|
+
sort ? /* @__PURE__ */ jsx16(
|
|
4791
5072
|
"button",
|
|
4792
5073
|
{
|
|
4793
5074
|
type: "button",
|
|
@@ -4803,53 +5084,57 @@ function ShapedBody({
|
|
|
4803
5084
|
register,
|
|
4804
5085
|
shaped,
|
|
4805
5086
|
onRowClick,
|
|
4806
|
-
selectedId
|
|
5087
|
+
selectedId,
|
|
5088
|
+
assumptionTitles
|
|
4807
5089
|
}) {
|
|
4808
5090
|
if (shaped.nested) {
|
|
4809
5091
|
if (shaped.nested.length === 0)
|
|
4810
|
-
return /* @__PURE__ */
|
|
4811
|
-
return /* @__PURE__ */
|
|
4812
|
-
/* @__PURE__ */
|
|
5092
|
+
return /* @__PURE__ */ jsx16("p", { className: "vos-empty", children: "No readings in this view." });
|
|
5093
|
+
return /* @__PURE__ */ jsx16("div", { className: "vos-groups", children: shaped.nested.map((group) => /* @__PURE__ */ jsxs15("section", { className: "vos-group", children: [
|
|
5094
|
+
/* @__PURE__ */ jsxs15("h3", { className: "vos-group-head", children: [
|
|
4813
5095
|
group.label,
|
|
4814
|
-
/* @__PURE__ */
|
|
5096
|
+
/* @__PURE__ */ jsx16("span", { className: "vos-group-n", children: group.readings.length })
|
|
4815
5097
|
] }),
|
|
4816
|
-
/* @__PURE__ */
|
|
5098
|
+
/* @__PURE__ */ jsx16(
|
|
4817
5099
|
RegisterTable,
|
|
4818
5100
|
{
|
|
4819
5101
|
register,
|
|
4820
5102
|
records: group.readings,
|
|
4821
5103
|
onRowClick,
|
|
4822
|
-
selectedId
|
|
5104
|
+
selectedId,
|
|
5105
|
+
assumptionTitles
|
|
4823
5106
|
}
|
|
4824
5107
|
)
|
|
4825
5108
|
] }, group.experimentId ?? "__none__")) });
|
|
4826
5109
|
}
|
|
4827
5110
|
if (shaped.groups) {
|
|
4828
5111
|
if (shaped.groups.length === 0)
|
|
4829
|
-
return /* @__PURE__ */
|
|
4830
|
-
return /* @__PURE__ */
|
|
4831
|
-
/* @__PURE__ */
|
|
5112
|
+
return /* @__PURE__ */ jsx16("p", { className: "vos-empty", children: "No records in this view." });
|
|
5113
|
+
return /* @__PURE__ */ jsx16("div", { className: "vos-groups", children: shaped.groups.map((group) => /* @__PURE__ */ jsxs15("section", { className: "vos-group", children: [
|
|
5114
|
+
/* @__PURE__ */ jsxs15("h3", { className: "vos-group-head", children: [
|
|
4832
5115
|
group.label,
|
|
4833
|
-
/* @__PURE__ */
|
|
5116
|
+
/* @__PURE__ */ jsx16("span", { className: "vos-group-n", children: group.records.length })
|
|
4834
5117
|
] }),
|
|
4835
|
-
/* @__PURE__ */
|
|
5118
|
+
/* @__PURE__ */ jsx16(
|
|
4836
5119
|
RegisterTable,
|
|
4837
5120
|
{
|
|
4838
5121
|
register,
|
|
4839
5122
|
records: group.records,
|
|
4840
5123
|
onRowClick,
|
|
4841
|
-
selectedId
|
|
5124
|
+
selectedId,
|
|
5125
|
+
assumptionTitles
|
|
4842
5126
|
}
|
|
4843
5127
|
)
|
|
4844
5128
|
] }, group.key)) });
|
|
4845
5129
|
}
|
|
4846
|
-
return /* @__PURE__ */
|
|
5130
|
+
return /* @__PURE__ */ jsx16(
|
|
4847
5131
|
RegisterTable,
|
|
4848
5132
|
{
|
|
4849
5133
|
register,
|
|
4850
5134
|
records: shaped.rows,
|
|
4851
5135
|
onRowClick,
|
|
4852
|
-
selectedId
|
|
5136
|
+
selectedId,
|
|
5137
|
+
assumptionTitles
|
|
4853
5138
|
}
|
|
4854
5139
|
);
|
|
4855
5140
|
}
|
|
@@ -4857,7 +5142,7 @@ function ShapedBody({
|
|
|
4857
5142
|
// src/next-move-surface.tsx
|
|
4858
5143
|
import { useMemo as useMemo5, useState as useState11 } from "react";
|
|
4859
5144
|
import { rankNextMoves as rankNextMoves2 } from "@validation-os/core/derivation";
|
|
4860
|
-
import { Fragment as Fragment10, jsx as
|
|
5145
|
+
import { Fragment as Fragment10, jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4861
5146
|
var STAGES = ["Framed", "Planned", "Tested", "Known"];
|
|
4862
5147
|
var MOVE_STAGE = {
|
|
4863
5148
|
"score-impact": 0,
|
|
@@ -4915,12 +5200,12 @@ function NextMoveSurface({ basePath, onNavigate }) {
|
|
|
4915
5200
|
});
|
|
4916
5201
|
};
|
|
4917
5202
|
if (loading) {
|
|
4918
|
-
return /* @__PURE__ */
|
|
5203
|
+
return /* @__PURE__ */ jsx17(NextMoveFrame, { children: /* @__PURE__ */ jsx17("div", { className: "vos-empty", children: "Reading your beliefs\u2026" }) });
|
|
4919
5204
|
}
|
|
4920
5205
|
if (error) {
|
|
4921
|
-
return /* @__PURE__ */
|
|
4922
|
-
/* @__PURE__ */
|
|
4923
|
-
/* @__PURE__ */
|
|
5206
|
+
return /* @__PURE__ */ jsx17(NextMoveFrame, { children: /* @__PURE__ */ jsx17("div", { className: "vos-banner vos-banner-crit", children: /* @__PURE__ */ jsxs16("div", { className: "vos-banner-body", children: [
|
|
5207
|
+
/* @__PURE__ */ jsx17("b", { children: "Couldn't load the workflow." }),
|
|
5208
|
+
/* @__PURE__ */ jsx17("span", { children: error })
|
|
4924
5209
|
] }) }) });
|
|
4925
5210
|
}
|
|
4926
5211
|
if (moves.length === 0) {
|
|
@@ -4932,13 +5217,13 @@ function NextMoveSurface({ basePath, onNavigate }) {
|
|
|
4932
5217
|
};
|
|
4933
5218
|
const cold = coldStartFor(records);
|
|
4934
5219
|
if (cold.cold) {
|
|
4935
|
-
return /* @__PURE__ */
|
|
4936
|
-
/* @__PURE__ */
|
|
4937
|
-
/* @__PURE__ */
|
|
4938
|
-
/* @__PURE__ */
|
|
4939
|
-
/* @__PURE__ */
|
|
4940
|
-
/* @__PURE__ */
|
|
4941
|
-
/* @__PURE__ */
|
|
5220
|
+
return /* @__PURE__ */ jsxs16(NextMoveFrame, { children: [
|
|
5221
|
+
/* @__PURE__ */ jsx17("div", { className: "vos-firstrun", children: FIRST_RUN_LINE }),
|
|
5222
|
+
/* @__PURE__ */ jsxs16("div", { className: "vos-card vos-cold vos-cold-next", children: [
|
|
5223
|
+
/* @__PURE__ */ jsx17("span", { className: "vos-cold-eyebrow", children: cold.next.eyebrow }),
|
|
5224
|
+
/* @__PURE__ */ jsx17("h2", { className: "vos-cold-headline", children: cold.next.headline }),
|
|
5225
|
+
/* @__PURE__ */ jsx17("p", { className: "vos-cold-body", children: cold.next.body }),
|
|
5226
|
+
/* @__PURE__ */ jsx17(
|
|
4942
5227
|
"button",
|
|
4943
5228
|
{
|
|
4944
5229
|
type: "button",
|
|
@@ -4950,10 +5235,10 @@ function NextMoveSurface({ basePath, onNavigate }) {
|
|
|
4950
5235
|
] })
|
|
4951
5236
|
] });
|
|
4952
5237
|
}
|
|
4953
|
-
return /* @__PURE__ */
|
|
5238
|
+
return /* @__PURE__ */ jsx17(NextMoveFrame, { children: /* @__PURE__ */ jsxs16("div", { className: "vos-empty", children: [
|
|
4954
5239
|
"Nothing needs your attention right now \u2014 every belief is either resting on a decision or waiting on a test. Add a new belief from",
|
|
4955
5240
|
" ",
|
|
4956
|
-
/* @__PURE__ */
|
|
5241
|
+
/* @__PURE__ */ jsx17(
|
|
4957
5242
|
"button",
|
|
4958
5243
|
{
|
|
4959
5244
|
type: "button",
|
|
@@ -4971,11 +5256,11 @@ function NextMoveSurface({ basePath, onNavigate }) {
|
|
|
4971
5256
|
const onDeck = rest.filter((m) => m.assumptionId !== top.assumptionId).slice(0, 3);
|
|
4972
5257
|
const topPres = movePresentation(top.move);
|
|
4973
5258
|
const topTone = riskLevel(top.risk);
|
|
4974
|
-
return /* @__PURE__ */
|
|
4975
|
-
killMoves.length > 0 && !top.killLane ? /* @__PURE__ */
|
|
4976
|
-
/* @__PURE__ */
|
|
4977
|
-
/* @__PURE__ */
|
|
4978
|
-
/* @__PURE__ */
|
|
5259
|
+
return /* @__PURE__ */ jsxs16(NextMoveFrame, { children: [
|
|
5260
|
+
killMoves.length > 0 && !top.killLane ? /* @__PURE__ */ jsx17(KillBanner, { count: killMoves.length, onReview: () => startStepIn(killMoves[0]) }) : null,
|
|
5261
|
+
/* @__PURE__ */ jsxs16("div", { className: `vos-hero vos-card${top.killLane ? " vos-hero-kill" : ""}`, children: [
|
|
5262
|
+
/* @__PURE__ */ jsx17("span", { className: "vos-hero-eyebrow", children: top.killLane ? "Kill lane \u2014 turning against you" : "Your next move" }),
|
|
5263
|
+
/* @__PURE__ */ jsx17(
|
|
4979
5264
|
"button",
|
|
4980
5265
|
{
|
|
4981
5266
|
type: "button",
|
|
@@ -4985,23 +5270,23 @@ function NextMoveSurface({ basePath, onNavigate }) {
|
|
|
4985
5270
|
children: top.title
|
|
4986
5271
|
}
|
|
4987
5272
|
),
|
|
4988
|
-
/* @__PURE__ */
|
|
4989
|
-
/* @__PURE__ */
|
|
5273
|
+
/* @__PURE__ */ jsxs16("div", { className: "vos-riskchip", "aria-label": `Risk: ${RISK_PHRASE[topTone]}`, children: [
|
|
5274
|
+
/* @__PURE__ */ jsx17("span", { className: "vos-risk-bar", "aria-hidden": "true", children: /* @__PURE__ */ jsx17(
|
|
4990
5275
|
"i",
|
|
4991
5276
|
{
|
|
4992
5277
|
className: `vos-fill-${topTone}`,
|
|
4993
5278
|
style: { width: `${riskFraction(top.risk) * 100}%` }
|
|
4994
5279
|
}
|
|
4995
5280
|
) }),
|
|
4996
|
-
/* @__PURE__ */
|
|
5281
|
+
/* @__PURE__ */ jsx17("span", { className: `vos-riskchip-label vos-text-${topTone}`, children: top.killLane ? "Confidence has turned negative" : RISK_PHRASE[topTone] })
|
|
4997
5282
|
] }),
|
|
4998
|
-
/* @__PURE__ */
|
|
4999
|
-
/* @__PURE__ */
|
|
5283
|
+
/* @__PURE__ */ jsx17(ActButton, { move: top, onStepIn: () => startStepIn(top), onReview: () => openRecord(top.assumptionId) }),
|
|
5284
|
+
/* @__PURE__ */ jsx17("button", { type: "button", className: "vos-why", onClick: () => setWhy((w) => !w), children: why ? "Hide details" : "Why this?" })
|
|
5000
5285
|
] }),
|
|
5001
|
-
why ? /* @__PURE__ */
|
|
5002
|
-
onDeck.length > 0 ? /* @__PURE__ */
|
|
5003
|
-
/* @__PURE__ */
|
|
5004
|
-
onDeck.map((m) => /* @__PURE__ */
|
|
5286
|
+
why ? /* @__PURE__ */ jsx17(WhyPanel, { top, ranked: moves }) : null,
|
|
5287
|
+
onDeck.length > 0 ? /* @__PURE__ */ jsxs16("section", { className: "vos-ondeck", children: [
|
|
5288
|
+
/* @__PURE__ */ jsx17("h3", { className: "vos-sectitle", children: "On deck" }),
|
|
5289
|
+
onDeck.map((m) => /* @__PURE__ */ jsx17(
|
|
5005
5290
|
OnDeckRow,
|
|
5006
5291
|
{
|
|
5007
5292
|
move: m,
|
|
@@ -5011,7 +5296,7 @@ function NextMoveSurface({ basePath, onNavigate }) {
|
|
|
5011
5296
|
m.assumptionId
|
|
5012
5297
|
))
|
|
5013
5298
|
] }) : null,
|
|
5014
|
-
/* @__PURE__ */
|
|
5299
|
+
/* @__PURE__ */ jsx17(
|
|
5015
5300
|
"button",
|
|
5016
5301
|
{
|
|
5017
5302
|
type: "button",
|
|
@@ -5020,7 +5305,7 @@ function NextMoveSurface({ basePath, onNavigate }) {
|
|
|
5020
5305
|
children: "Act on a different belief \u2192"
|
|
5021
5306
|
}
|
|
5022
5307
|
),
|
|
5023
|
-
stepIn?.form === "score-impact" ? /* @__PURE__ */
|
|
5308
|
+
stepIn?.form === "score-impact" ? /* @__PURE__ */ jsx17(
|
|
5024
5309
|
ScoreImpactForm,
|
|
5025
5310
|
{
|
|
5026
5311
|
assumption: stepIn.assumption,
|
|
@@ -5032,7 +5317,7 @@ function NextMoveSurface({ basePath, onNavigate }) {
|
|
|
5032
5317
|
onCancel: () => setStepIn(null)
|
|
5033
5318
|
}
|
|
5034
5319
|
) : null,
|
|
5035
|
-
stepIn?.form === "write-decision" ? /* @__PURE__ */
|
|
5320
|
+
stepIn?.form === "write-decision" ? /* @__PURE__ */ jsx17(
|
|
5036
5321
|
WriteDecisionForm,
|
|
5037
5322
|
{
|
|
5038
5323
|
assumption: stepIn.assumption,
|
|
@@ -5048,12 +5333,12 @@ function NextMoveSurface({ basePath, onNavigate }) {
|
|
|
5048
5333
|
] });
|
|
5049
5334
|
}
|
|
5050
5335
|
function NextMoveFrame({ children }) {
|
|
5051
|
-
return /* @__PURE__ */
|
|
5052
|
-
/* @__PURE__ */
|
|
5053
|
-
/* @__PURE__ */
|
|
5054
|
-
/* @__PURE__ */
|
|
5336
|
+
return /* @__PURE__ */ jsxs16("div", { children: [
|
|
5337
|
+
/* @__PURE__ */ jsx17("div", { className: "vos-head", children: /* @__PURE__ */ jsxs16("div", { children: [
|
|
5338
|
+
/* @__PURE__ */ jsx17("h1", { children: "Next move" }),
|
|
5339
|
+
/* @__PURE__ */ jsx17("p", { children: "The single next move to make \u2014 and what's on deck." })
|
|
5055
5340
|
] }) }),
|
|
5056
|
-
/* @__PURE__ */
|
|
5341
|
+
/* @__PURE__ */ jsx17("div", { className: "vos-next", children })
|
|
5057
5342
|
] });
|
|
5058
5343
|
}
|
|
5059
5344
|
function ActButton({
|
|
@@ -5063,20 +5348,20 @@ function ActButton({
|
|
|
5063
5348
|
}) {
|
|
5064
5349
|
const pres = movePresentation(move.move);
|
|
5065
5350
|
if (pres.steppable) {
|
|
5066
|
-
return /* @__PURE__ */
|
|
5351
|
+
return /* @__PURE__ */ jsx17("button", { type: "button", className: "vos-btn vos-hero-act", onClick: onStepIn, children: pres.cta });
|
|
5067
5352
|
}
|
|
5068
|
-
return /* @__PURE__ */
|
|
5069
|
-
/* @__PURE__ */
|
|
5070
|
-
/* @__PURE__ */
|
|
5353
|
+
return /* @__PURE__ */ jsxs16("div", { className: "vos-hero-agent", children: [
|
|
5354
|
+
/* @__PURE__ */ jsx17("span", { className: "vos-agent-note", children: "\u{1F916} Claude Code runs this off the dashboard" }),
|
|
5355
|
+
/* @__PURE__ */ jsx17("button", { type: "button", className: "vos-btn vos-btn-ghost vos-hero-act", onClick: onReview, children: "Review on the record \u2192" })
|
|
5071
5356
|
] });
|
|
5072
5357
|
}
|
|
5073
5358
|
function KillBanner({ count, onReview }) {
|
|
5074
|
-
return /* @__PURE__ */
|
|
5075
|
-
/* @__PURE__ */
|
|
5076
|
-
/* @__PURE__ */
|
|
5077
|
-
/* @__PURE__ */
|
|
5359
|
+
return /* @__PURE__ */ jsxs16("div", { className: "vos-banner vos-banner-crit", children: [
|
|
5360
|
+
/* @__PURE__ */ jsxs16("div", { className: "vos-banner-body", children: [
|
|
5361
|
+
/* @__PURE__ */ jsx17("b", { children: count === 1 ? "A belief has fallen into the kill lane" : `${count} beliefs have fallen into the kill lane` }),
|
|
5362
|
+
/* @__PURE__ */ jsx17("span", { children: "Confidence \u2264 \u221250 \u2014 the evidence is against it. Kill it or test it again." })
|
|
5078
5363
|
] }),
|
|
5079
|
-
/* @__PURE__ */
|
|
5364
|
+
/* @__PURE__ */ jsx17("button", { type: "button", onClick: onReview, children: "Review" })
|
|
5080
5365
|
] });
|
|
5081
5366
|
}
|
|
5082
5367
|
function OnDeckRow({
|
|
@@ -5086,47 +5371,47 @@ function OnDeckRow({
|
|
|
5086
5371
|
}) {
|
|
5087
5372
|
const pres = movePresentation(move.move);
|
|
5088
5373
|
const tone = riskLevel(move.risk);
|
|
5089
|
-
return /* @__PURE__ */
|
|
5090
|
-
/* @__PURE__ */
|
|
5091
|
-
/* @__PURE__ */
|
|
5092
|
-
/* @__PURE__ */
|
|
5374
|
+
return /* @__PURE__ */ jsxs16("div", { className: "vos-ondeck-row", children: [
|
|
5375
|
+
/* @__PURE__ */ jsx17("span", { className: "vos-risk-bar", "aria-hidden": "true", children: /* @__PURE__ */ jsx17("i", { className: `vos-fill-${tone}`, style: { width: `${riskFraction(move.risk) * 100}%` } }) }),
|
|
5376
|
+
/* @__PURE__ */ jsx17("button", { type: "button", className: "vos-ondeck-title", onClick: onOpen, children: move.title }),
|
|
5377
|
+
/* @__PURE__ */ jsx17("button", { type: "button", className: "vos-pill vos-pill-accent vos-ondeck-act", onClick: onAct, children: pres.pill })
|
|
5093
5378
|
] });
|
|
5094
5379
|
}
|
|
5095
5380
|
function WhyPanel({ top, ranked }) {
|
|
5096
|
-
return /* @__PURE__ */
|
|
5097
|
-
/* @__PURE__ */
|
|
5098
|
-
/* @__PURE__ */
|
|
5099
|
-
/* @__PURE__ */
|
|
5100
|
-
/* @__PURE__ */
|
|
5381
|
+
return /* @__PURE__ */ jsxs16("div", { className: "vos-why-panel vos-next-why", children: [
|
|
5382
|
+
/* @__PURE__ */ jsx17("p", { className: "vos-why-reason", children: top.reason }),
|
|
5383
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
5384
|
+
/* @__PURE__ */ jsx17("div", { className: "vos-why-section-title", children: "Where it sits" }),
|
|
5385
|
+
/* @__PURE__ */ jsx17(StageStepper, { move: top.move })
|
|
5101
5386
|
] }),
|
|
5102
|
-
/* @__PURE__ */
|
|
5103
|
-
/* @__PURE__ */
|
|
5104
|
-
/* @__PURE__ */
|
|
5387
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
5388
|
+
/* @__PURE__ */ jsx17("div", { className: "vos-why-section-title", children: "Why it's on top" }),
|
|
5389
|
+
/* @__PURE__ */ jsxs16("p", { className: "vos-why-formula", children: [
|
|
5105
5390
|
"Ranked by ",
|
|
5106
|
-
/* @__PURE__ */
|
|
5391
|
+
/* @__PURE__ */ jsx17("b", { children: "Feasibility \xD7 Risk" }),
|
|
5107
5392
|
" \u2014 Risk ",
|
|
5108
|
-
/* @__PURE__ */
|
|
5109
|
-
top.feasibility ? /* @__PURE__ */
|
|
5393
|
+
/* @__PURE__ */ jsx17("b", { children: Math.round(top.risk) }),
|
|
5394
|
+
top.feasibility ? /* @__PURE__ */ jsxs16(Fragment10, { children: [
|
|
5110
5395
|
" ",
|
|
5111
5396
|
"\xD7 Feasibility ",
|
|
5112
|
-
/* @__PURE__ */
|
|
5113
|
-
] }) : /* @__PURE__ */
|
|
5397
|
+
/* @__PURE__ */ jsx17("b", { children: top.feasibility })
|
|
5398
|
+
] }) : /* @__PURE__ */ jsx17(Fragment10, { children: " (no test planned yet \u2014 neutral feasibility)" }),
|
|
5114
5399
|
top.killLane ? " \xB7 in the kill lane, so it jumps the queue" : null,
|
|
5115
5400
|
"."
|
|
5116
5401
|
] })
|
|
5117
5402
|
] }),
|
|
5118
|
-
/* @__PURE__ */
|
|
5119
|
-
/* @__PURE__ */
|
|
5120
|
-
/* @__PURE__ */
|
|
5121
|
-
/* @__PURE__ */
|
|
5122
|
-
/* @__PURE__ */
|
|
5403
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
5404
|
+
/* @__PURE__ */ jsx17("div", { className: "vos-why-section-title", children: "The ranking" }),
|
|
5405
|
+
/* @__PURE__ */ jsx17("ol", { className: "vos-why-rank", children: ranked.slice(0, 6).map((m) => /* @__PURE__ */ jsxs16("li", { className: m.assumptionId === top.assumptionId ? "vos-why-rank-top" : "", children: [
|
|
5406
|
+
/* @__PURE__ */ jsx17("span", { className: "vos-why-rank-title", children: m.title }),
|
|
5407
|
+
/* @__PURE__ */ jsx17("span", { className: "vos-why-rank-score", children: Math.round(m.score) })
|
|
5123
5408
|
] }, m.assumptionId)) })
|
|
5124
5409
|
] })
|
|
5125
5410
|
] });
|
|
5126
5411
|
}
|
|
5127
5412
|
function StageStepper({ move }) {
|
|
5128
5413
|
const at = MOVE_STAGE[move];
|
|
5129
|
-
return /* @__PURE__ */
|
|
5414
|
+
return /* @__PURE__ */ jsx17("div", { className: "vos-stepper", "aria-label": `Stage: ${STAGES[at]}`, children: STAGES.map((label, i) => /* @__PURE__ */ jsx17(
|
|
5130
5415
|
"span",
|
|
5131
5416
|
{
|
|
5132
5417
|
className: `vos-step${i === at ? " vos-step-at" : ""}${i < at ? " vos-step-done" : ""}`,
|
|
@@ -5136,6 +5421,290 @@ function StageStepper({ move }) {
|
|
|
5136
5421
|
)) });
|
|
5137
5422
|
}
|
|
5138
5423
|
|
|
5424
|
+
// src/stage-grid-surface.tsx
|
|
5425
|
+
import { useMemo as useMemo6, useState as useState12 } from "react";
|
|
5426
|
+
|
|
5427
|
+
// src/stage-grid-model.ts
|
|
5428
|
+
var STAGE_ORDER = [
|
|
5429
|
+
"Discovery",
|
|
5430
|
+
"Validation",
|
|
5431
|
+
"Scale",
|
|
5432
|
+
"Maturity"
|
|
5433
|
+
];
|
|
5434
|
+
var STAGE_GLOSS = {
|
|
5435
|
+
Discovery: "Problem-solution fit \u2014 will they engage, care, disclose?",
|
|
5436
|
+
Validation: "Product-market fit \u2014 will they pay, sign, stay?",
|
|
5437
|
+
Scale: "Growth \u2014 can we acquire efficiently, does CAC<LTV hold at volume?",
|
|
5438
|
+
Maturity: "Defense \u2014 will incumbents respond, will regulators accept?"
|
|
5439
|
+
};
|
|
5440
|
+
var NO_LENS = "\u2014";
|
|
5441
|
+
var NO_STAGE = "\u2014";
|
|
5442
|
+
function stageOf(record) {
|
|
5443
|
+
const v = str(record.Stage);
|
|
5444
|
+
if (!v) return null;
|
|
5445
|
+
return STAGE_ORDER.includes(v) ? v : null;
|
|
5446
|
+
}
|
|
5447
|
+
function rankByRisk(records) {
|
|
5448
|
+
return [...records].map((r) => ({ r, risk: derivedNum(r, "risk") ?? 0 })).sort(
|
|
5449
|
+
(a, b) => a.risk !== b.risk ? b.risk - a.risk : a.r.id.localeCompare(b.r.id)
|
|
5450
|
+
).map((x) => x.r);
|
|
5451
|
+
}
|
|
5452
|
+
function buildStageGrid(assumptions) {
|
|
5453
|
+
const lensOrder = [];
|
|
5454
|
+
const seenLens = /* @__PURE__ */ new Set();
|
|
5455
|
+
const pushLens = (lens) => {
|
|
5456
|
+
if (!seenLens.has(lens)) {
|
|
5457
|
+
seenLens.add(lens);
|
|
5458
|
+
lensOrder.push(lens);
|
|
5459
|
+
}
|
|
5460
|
+
};
|
|
5461
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
5462
|
+
const ensureLens = (lens) => {
|
|
5463
|
+
let m = buckets.get(lens);
|
|
5464
|
+
if (!m) {
|
|
5465
|
+
m = /* @__PURE__ */ new Map();
|
|
5466
|
+
buckets.set(lens, m);
|
|
5467
|
+
}
|
|
5468
|
+
return m;
|
|
5469
|
+
};
|
|
5470
|
+
let hasNoLens = false;
|
|
5471
|
+
let hasNoStage = false;
|
|
5472
|
+
for (const a of assumptions) {
|
|
5473
|
+
const lens = str(a.Lens) ?? NO_LENS;
|
|
5474
|
+
const stage = stageOf(a) ?? NO_STAGE;
|
|
5475
|
+
if (lens === NO_LENS) hasNoLens = true;
|
|
5476
|
+
if (stage === NO_STAGE) hasNoStage = true;
|
|
5477
|
+
pushLens(lens);
|
|
5478
|
+
const byStage = ensureLens(lens);
|
|
5479
|
+
let list = byStage.get(stage);
|
|
5480
|
+
if (!list) {
|
|
5481
|
+
list = [];
|
|
5482
|
+
byStage.set(stage, list);
|
|
5483
|
+
}
|
|
5484
|
+
list.push(a);
|
|
5485
|
+
}
|
|
5486
|
+
if (hasNoLens) {
|
|
5487
|
+
lensOrder.splice(lensOrder.indexOf(NO_LENS), 1);
|
|
5488
|
+
lensOrder.push(NO_LENS);
|
|
5489
|
+
} else {
|
|
5490
|
+
const idx = lensOrder.indexOf(NO_LENS);
|
|
5491
|
+
if (idx >= 0) lensOrder.splice(idx, 1);
|
|
5492
|
+
}
|
|
5493
|
+
const stageOrder = [...STAGE_ORDER];
|
|
5494
|
+
if (hasNoStage) stageOrder.push(NO_STAGE);
|
|
5495
|
+
const cells = [];
|
|
5496
|
+
let maxCellCount = 0;
|
|
5497
|
+
let total = 0;
|
|
5498
|
+
for (const lens of lensOrder) {
|
|
5499
|
+
const byStage = buckets.get(lens) ?? /* @__PURE__ */ new Map();
|
|
5500
|
+
for (const stage of stageOrder) {
|
|
5501
|
+
const records = byStage.get(stage) ?? [];
|
|
5502
|
+
const ranked = rankByRisk(records);
|
|
5503
|
+
const count = ranked.length;
|
|
5504
|
+
maxCellCount = Math.max(maxCellCount, count);
|
|
5505
|
+
total += count;
|
|
5506
|
+
cells.push({
|
|
5507
|
+
lens,
|
|
5508
|
+
stage,
|
|
5509
|
+
count,
|
|
5510
|
+
assumptions: ranked,
|
|
5511
|
+
// density filled in a second pass once maxCellCount is known.
|
|
5512
|
+
density: 0
|
|
5513
|
+
});
|
|
5514
|
+
}
|
|
5515
|
+
}
|
|
5516
|
+
const norm2 = maxCellCount > 0 ? 1 / maxCellCount : 0;
|
|
5517
|
+
for (const cell of cells) {
|
|
5518
|
+
cell.density = cell.count * norm2;
|
|
5519
|
+
}
|
|
5520
|
+
return {
|
|
5521
|
+
lenses: lensOrder,
|
|
5522
|
+
stages: [...STAGE_ORDER],
|
|
5523
|
+
cells,
|
|
5524
|
+
maxCellCount,
|
|
5525
|
+
total
|
|
5526
|
+
};
|
|
5527
|
+
}
|
|
5528
|
+
function cellAt(view, lens, stage) {
|
|
5529
|
+
return view.cells.find((c) => c.lens === lens && c.stage === stage) ?? null;
|
|
5530
|
+
}
|
|
5531
|
+
|
|
5532
|
+
// src/stage-grid-surface.tsx
|
|
5533
|
+
import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
5534
|
+
function StageGridSurface({ basePath, onNavigate }) {
|
|
5535
|
+
const assumptions = useList("assumptions", basePath);
|
|
5536
|
+
const loading = assumptions.loading;
|
|
5537
|
+
const error = assumptions.error;
|
|
5538
|
+
const [open, setOpen] = useState12(null);
|
|
5539
|
+
const view = useMemo6(
|
|
5540
|
+
() => buildStageGrid(assumptions.records ?? []),
|
|
5541
|
+
[assumptions.records]
|
|
5542
|
+
);
|
|
5543
|
+
const refresh = () => assumptions.refresh();
|
|
5544
|
+
const openRecord = (id) => onNavigate({ name: "record", id });
|
|
5545
|
+
if (loading && !assumptions.records) {
|
|
5546
|
+
return /* @__PURE__ */ jsx18(StageGridFrame, { children: /* @__PURE__ */ jsx18("div", { className: "vos-empty", children: "Reading where your bets cluster\u2026" }) });
|
|
5547
|
+
}
|
|
5548
|
+
if (error) {
|
|
5549
|
+
return /* @__PURE__ */ jsx18(StageGridFrame, { children: /* @__PURE__ */ jsx18("div", { className: "vos-banner vos-banner-crit", children: /* @__PURE__ */ jsxs17("div", { className: "vos-banner-body", children: [
|
|
5550
|
+
/* @__PURE__ */ jsx18("b", { children: "Couldn't load the grid." }),
|
|
5551
|
+
/* @__PURE__ */ jsx18("span", { children: error })
|
|
5552
|
+
] }) }) });
|
|
5553
|
+
}
|
|
5554
|
+
const cold = coldStartFor({
|
|
5555
|
+
assumptions: assumptions.records ?? [],
|
|
5556
|
+
experiments: [],
|
|
5557
|
+
readings: [],
|
|
5558
|
+
decisions: []
|
|
5559
|
+
});
|
|
5560
|
+
if (cold.cold) {
|
|
5561
|
+
return /* @__PURE__ */ jsxs17(StageGridFrame, { children: [
|
|
5562
|
+
/* @__PURE__ */ jsx18("div", { className: "vos-firstrun", children: FIRST_RUN_LINE }),
|
|
5563
|
+
/* @__PURE__ */ jsxs17("div", { className: "vos-card vos-cold vos-cold-stage-grid", children: [
|
|
5564
|
+
/* @__PURE__ */ jsx18("span", { className: "vos-cold-eyebrow", children: "No bets yet" }),
|
|
5565
|
+
/* @__PURE__ */ jsx18("p", { className: "vos-cold-body", children: "The Lens \xD7 Stage grid reads your business state off where your bets cluster. Write your first belief and the grid fills in \u2014 the densest cell per row is where that part of the business is." }),
|
|
5566
|
+
/* @__PURE__ */ jsx18(
|
|
5567
|
+
"button",
|
|
5568
|
+
{
|
|
5569
|
+
type: "button",
|
|
5570
|
+
className: "vos-btn",
|
|
5571
|
+
onClick: () => onNavigate({ name: "records", register: "assumptions" }),
|
|
5572
|
+
children: "Write your first bet"
|
|
5573
|
+
}
|
|
5574
|
+
)
|
|
5575
|
+
] })
|
|
5576
|
+
] });
|
|
5577
|
+
}
|
|
5578
|
+
return /* @__PURE__ */ jsxs17(StageGridFrame, { total: view.total, onRefresh: refresh, children: [
|
|
5579
|
+
/* @__PURE__ */ jsxs17("div", { className: "vos-card vos-stage-grid-card", children: [
|
|
5580
|
+
/* @__PURE__ */ jsx18("div", { className: "vos-stage-grid-scroll", children: /* @__PURE__ */ jsxs17("table", { className: "vos-stage-grid", role: "grid", "aria-label": "Lens \xD7 Stage heatmap", children: [
|
|
5581
|
+
/* @__PURE__ */ jsx18("thead", { children: /* @__PURE__ */ jsxs17("tr", { children: [
|
|
5582
|
+
/* @__PURE__ */ jsx18("th", { scope: "col", className: "vos-stage-grid-corner", children: "Lens \u2193 / Stage \u2192" }),
|
|
5583
|
+
view.stages.map((stage) => /* @__PURE__ */ jsxs17("th", { scope: "col", className: "vos-stage-grid-col", children: [
|
|
5584
|
+
/* @__PURE__ */ jsx18("span", { className: "vos-stage-grid-stagename", children: stage }),
|
|
5585
|
+
/* @__PURE__ */ jsx18("span", { className: "vos-stage-grid-stagegloss", children: STAGE_GLOSS[stage] })
|
|
5586
|
+
] }, stage))
|
|
5587
|
+
] }) }),
|
|
5588
|
+
/* @__PURE__ */ jsx18("tbody", { children: view.lenses.map((lens) => /* @__PURE__ */ jsxs17("tr", { children: [
|
|
5589
|
+
/* @__PURE__ */ jsx18("th", { scope: "row", className: "vos-stage-grid-rowhead", children: lens }),
|
|
5590
|
+
view.stages.map((stage) => {
|
|
5591
|
+
const cell = cellAt(view, lens, stage);
|
|
5592
|
+
return /* @__PURE__ */ jsx18(
|
|
5593
|
+
StageCell,
|
|
5594
|
+
{
|
|
5595
|
+
cell,
|
|
5596
|
+
onClick: () => setOpen(cell)
|
|
5597
|
+
},
|
|
5598
|
+
stage
|
|
5599
|
+
);
|
|
5600
|
+
})
|
|
5601
|
+
] }, lens)) })
|
|
5602
|
+
] }) }),
|
|
5603
|
+
/* @__PURE__ */ jsx18("p", { className: "vos-hint vos-stage-grid-foot", children: "The densest cell per row is where that part of the business is \u2014 no flag, no declaration, the density tells you. Click a cell to drill into its assumptions, ranked by Risk. Thin/empty cells are gaps: Consumer \xD7 Maturity is honestly 0 (consumers don't drive defense bets); a thin Commercial \xD7 Scale row is under-tracking scale." })
|
|
5604
|
+
] }),
|
|
5605
|
+
/* @__PURE__ */ jsx18(
|
|
5606
|
+
CellDrawer,
|
|
5607
|
+
{
|
|
5608
|
+
cell: open,
|
|
5609
|
+
onClose: () => setOpen(null),
|
|
5610
|
+
onOpenRecord: openRecord
|
|
5611
|
+
}
|
|
5612
|
+
)
|
|
5613
|
+
] });
|
|
5614
|
+
}
|
|
5615
|
+
function StageGridFrame({
|
|
5616
|
+
total,
|
|
5617
|
+
onRefresh,
|
|
5618
|
+
children
|
|
5619
|
+
}) {
|
|
5620
|
+
return /* @__PURE__ */ jsxs17("div", { children: [
|
|
5621
|
+
/* @__PURE__ */ jsxs17("div", { className: "vos-head", children: [
|
|
5622
|
+
/* @__PURE__ */ jsxs17("div", { children: [
|
|
5623
|
+
/* @__PURE__ */ jsx18("h1", { children: "Lens \xD7 Stage \u2014 where your bets cluster" }),
|
|
5624
|
+
/* @__PURE__ */ jsx18("p", { children: "Every belief cross-tabbed by the actor it's about (Lens) and the kind of response it tests (Stage). The grid is the filter; Risk is the rank." })
|
|
5625
|
+
] }),
|
|
5626
|
+
/* @__PURE__ */ jsx18("div", { className: "vos-spacer" }),
|
|
5627
|
+
total !== void 0 ? /* @__PURE__ */ jsxs17("span", { className: "vos-hint vos-stage-grid-total", children: [
|
|
5628
|
+
total,
|
|
5629
|
+
" ",
|
|
5630
|
+
total === 1 ? "belief" : "beliefs"
|
|
5631
|
+
] }) : null,
|
|
5632
|
+
onRefresh ? /* @__PURE__ */ jsx18(
|
|
5633
|
+
"button",
|
|
5634
|
+
{
|
|
5635
|
+
type: "button",
|
|
5636
|
+
className: "vos-btn vos-btn-ghost",
|
|
5637
|
+
onClick: onRefresh,
|
|
5638
|
+
children: "\u21BB Refresh"
|
|
5639
|
+
}
|
|
5640
|
+
) : null
|
|
5641
|
+
] }),
|
|
5642
|
+
/* @__PURE__ */ jsx18("div", { className: "vos-stage-grid-host", children })
|
|
5643
|
+
] });
|
|
5644
|
+
}
|
|
5645
|
+
function StageCell({
|
|
5646
|
+
cell,
|
|
5647
|
+
onClick
|
|
5648
|
+
}) {
|
|
5649
|
+
const empty = cell.count === 0;
|
|
5650
|
+
const style = empty ? void 0 : {
|
|
5651
|
+
// Heatmap fill: opacity 0.08 → 0.92 across the density range, on the
|
|
5652
|
+
// accent token. Keeps the grid readable in both themes.
|
|
5653
|
+
"--vos-cell-alpha": (0.08 + cell.density * 0.84).toFixed(3)
|
|
5654
|
+
};
|
|
5655
|
+
return /* @__PURE__ */ jsx18(
|
|
5656
|
+
"td",
|
|
5657
|
+
{
|
|
5658
|
+
className: `vos-stage-grid-cell${empty ? " vos-stage-grid-cell-empty" : ""}`,
|
|
5659
|
+
style,
|
|
5660
|
+
children: /* @__PURE__ */ jsx18(
|
|
5661
|
+
"button",
|
|
5662
|
+
{
|
|
5663
|
+
type: "button",
|
|
5664
|
+
className: "vos-stage-grid-btn",
|
|
5665
|
+
onClick,
|
|
5666
|
+
"aria-label": `${cell.lens} \xD7 ${cell.stage}: ${cell.count} ${cell.count === 1 ? "belief" : "beliefs"}`,
|
|
5667
|
+
title: empty ? "No beliefs in this cell" : `Riskiest: ${cell.assumptions[0]?.Title ?? "\u2014"}`,
|
|
5668
|
+
children: /* @__PURE__ */ jsx18("span", { className: "vos-stage-grid-count vos-num", children: cell.count })
|
|
5669
|
+
}
|
|
5670
|
+
)
|
|
5671
|
+
}
|
|
5672
|
+
);
|
|
5673
|
+
}
|
|
5674
|
+
function CellDrawer({
|
|
5675
|
+
cell,
|
|
5676
|
+
onClose,
|
|
5677
|
+
onOpenRecord
|
|
5678
|
+
}) {
|
|
5679
|
+
return /* @__PURE__ */ jsxs17(
|
|
5680
|
+
DrawerShell,
|
|
5681
|
+
{
|
|
5682
|
+
open: cell !== null,
|
|
5683
|
+
onClose,
|
|
5684
|
+
ariaLabel: cell ? `${cell.lens} \xD7 ${cell.stage} \u2014 ${cell.count} ${cell.count === 1 ? "belief" : "beliefs"}` : "Cell drill-through",
|
|
5685
|
+
children: [
|
|
5686
|
+
/* @__PURE__ */ jsx18("header", { className: "vos-drawer-header", children: /* @__PURE__ */ jsxs17("div", { children: [
|
|
5687
|
+
/* @__PURE__ */ jsx18("p", { className: "vos-drawer-eyebrow", children: "Lens \xD7 Stage" }),
|
|
5688
|
+
/* @__PURE__ */ jsxs17("h2", { className: "vos-drawer-title", children: [
|
|
5689
|
+
cell?.lens,
|
|
5690
|
+
" \xD7 ",
|
|
5691
|
+
cell?.stage
|
|
5692
|
+
] }),
|
|
5693
|
+
/* @__PURE__ */ jsx18("p", { className: "vos-hint", children: cell && cell.count > 0 ? `${cell.count} ${cell.count === 1 ? "belief" : "beliefs"}, ranked by Risk \u2014 riskiest first.` : "No beliefs in this cell." })
|
|
5694
|
+
] }) }),
|
|
5695
|
+
cell && cell.count > 0 ? /* @__PURE__ */ jsx18("div", { className: "vos-stage-grid-drawer-body", children: /* @__PURE__ */ jsx18(
|
|
5696
|
+
RegisterTable,
|
|
5697
|
+
{
|
|
5698
|
+
register: "assumptions",
|
|
5699
|
+
records: cell.assumptions,
|
|
5700
|
+
onRowClick: onOpenRecord
|
|
5701
|
+
}
|
|
5702
|
+
) }) : cell ? /* @__PURE__ */ jsx18("p", { className: "vos-empty", style: { margin: 16 }, children: "No beliefs in this cell \u2014 a gap, not a bug." }) : null
|
|
5703
|
+
]
|
|
5704
|
+
}
|
|
5705
|
+
);
|
|
5706
|
+
}
|
|
5707
|
+
|
|
5139
5708
|
// src/route.ts
|
|
5140
5709
|
var DEFAULT_ROUTE = { name: "next" };
|
|
5141
5710
|
function parseRoute(hash, registers) {
|
|
@@ -5145,6 +5714,7 @@ function parseRoute(hash, registers) {
|
|
|
5145
5714
|
const head = parts[0] ?? "";
|
|
5146
5715
|
if (head === "next") return { name: "next" };
|
|
5147
5716
|
if (head === "pipeline") return { name: "pipeline" };
|
|
5717
|
+
if (head === "stage-grid") return { name: "stage-grid" };
|
|
5148
5718
|
if (head === "record") {
|
|
5149
5719
|
const id = parts.slice(1).join("/");
|
|
5150
5720
|
return id ? { name: "record", id } : DEFAULT_ROUTE;
|
|
@@ -5166,7 +5736,7 @@ function formatRoute(route) {
|
|
|
5166
5736
|
}
|
|
5167
5737
|
|
|
5168
5738
|
// src/sidebar-nav.tsx
|
|
5169
|
-
import { jsx as
|
|
5739
|
+
import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
5170
5740
|
function SidebarNav({
|
|
5171
5741
|
route,
|
|
5172
5742
|
onNavigate,
|
|
@@ -5175,12 +5745,12 @@ function SidebarNav({
|
|
|
5175
5745
|
registers
|
|
5176
5746
|
}) {
|
|
5177
5747
|
const activeRegister = route.name === "records" ? route.register : null;
|
|
5178
|
-
return /* @__PURE__ */
|
|
5179
|
-
/* @__PURE__ */
|
|
5180
|
-
/* @__PURE__ */
|
|
5748
|
+
return /* @__PURE__ */ jsxs18("nav", { className: "vos-nav", "aria-label": "Navigation", children: [
|
|
5749
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
5750
|
+
/* @__PURE__ */ jsx19("div", { className: "vos-nav-group", children: "Workflow" }),
|
|
5181
5751
|
WORKFLOW_NAV.map((item) => {
|
|
5182
5752
|
const active = route.name === item.route;
|
|
5183
|
-
return /* @__PURE__ */
|
|
5753
|
+
return /* @__PURE__ */ jsxs18(
|
|
5184
5754
|
"button",
|
|
5185
5755
|
{
|
|
5186
5756
|
type: "button",
|
|
@@ -5188,20 +5758,20 @@ function SidebarNav({
|
|
|
5188
5758
|
"aria-current": active ? "page" : void 0,
|
|
5189
5759
|
onClick: () => onNavigate({ name: item.route }),
|
|
5190
5760
|
children: [
|
|
5191
|
-
/* @__PURE__ */
|
|
5761
|
+
/* @__PURE__ */ jsx19("span", { className: "vos-nav-ic", "aria-hidden": "true", children: item.icon }),
|
|
5192
5762
|
item.label,
|
|
5193
|
-
item.isDefault ? /* @__PURE__ */
|
|
5763
|
+
item.isDefault ? /* @__PURE__ */ jsx19("span", { className: "vos-nav-default", children: "home" }) : null
|
|
5194
5764
|
]
|
|
5195
5765
|
},
|
|
5196
5766
|
item.route
|
|
5197
5767
|
);
|
|
5198
5768
|
})
|
|
5199
5769
|
] }),
|
|
5200
|
-
/* @__PURE__ */
|
|
5201
|
-
/* @__PURE__ */
|
|
5770
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
5771
|
+
/* @__PURE__ */ jsx19("div", { className: "vos-nav-group", children: "Records" }),
|
|
5202
5772
|
registers.map((register) => {
|
|
5203
5773
|
const active = register === activeRegister;
|
|
5204
|
-
return /* @__PURE__ */
|
|
5774
|
+
return /* @__PURE__ */ jsxs18(
|
|
5205
5775
|
"button",
|
|
5206
5776
|
{
|
|
5207
5777
|
type: "button",
|
|
@@ -5209,9 +5779,9 @@ function SidebarNav({
|
|
|
5209
5779
|
"aria-current": active ? "page" : void 0,
|
|
5210
5780
|
onClick: () => onNavigate({ name: "records", register }),
|
|
5211
5781
|
children: [
|
|
5212
|
-
/* @__PURE__ */
|
|
5782
|
+
/* @__PURE__ */ jsx19("span", { className: "vos-nav-ic", "aria-hidden": "true", children: REGISTER_ICON[register] }),
|
|
5213
5783
|
REGISTER_LABEL[register],
|
|
5214
|
-
needsHuman?.[register] ? /* @__PURE__ */
|
|
5784
|
+
needsHuman?.[register] ? /* @__PURE__ */ jsx19(
|
|
5215
5785
|
"span",
|
|
5216
5786
|
{
|
|
5217
5787
|
className: "vos-nav-alert",
|
|
@@ -5219,7 +5789,7 @@ function SidebarNav({
|
|
|
5219
5789
|
children: formatCount(needsHuman[register] ?? 0)
|
|
5220
5790
|
}
|
|
5221
5791
|
) : null,
|
|
5222
|
-
/* @__PURE__ */
|
|
5792
|
+
/* @__PURE__ */ jsx19("span", { className: "vos-nav-count vos-num", children: counts?.[register] !== void 0 ? formatCount(counts[register] ?? 0) : "\xB7" })
|
|
5223
5793
|
]
|
|
5224
5794
|
},
|
|
5225
5795
|
register
|
|
@@ -5230,12 +5800,12 @@ function SidebarNav({
|
|
|
5230
5800
|
}
|
|
5231
5801
|
|
|
5232
5802
|
// src/use-counts.ts
|
|
5233
|
-
import { useCallback as useCallback4, useEffect as useEffect5, useMemo as
|
|
5803
|
+
import { useCallback as useCallback4, useEffect as useEffect5, useMemo as useMemo7, useState as useState13 } from "react";
|
|
5234
5804
|
function useCounts(basePath = "/api") {
|
|
5235
|
-
const [counts, setCounts] =
|
|
5236
|
-
const [loading, setLoading] =
|
|
5237
|
-
const [error, setError] =
|
|
5238
|
-
const [tick, setTick] =
|
|
5805
|
+
const [counts, setCounts] = useState13(null);
|
|
5806
|
+
const [loading, setLoading] = useState13(true);
|
|
5807
|
+
const [error, setError] = useState13(null);
|
|
5808
|
+
const [tick, setTick] = useState13(0);
|
|
5239
5809
|
useEffect5(() => {
|
|
5240
5810
|
let live = true;
|
|
5241
5811
|
setLoading(true);
|
|
@@ -5263,8 +5833,8 @@ function useNeedsHuman(basePath = "/api") {
|
|
|
5263
5833
|
const assumptions = useList("assumptions", basePath);
|
|
5264
5834
|
const experiments = useList("experiments", basePath);
|
|
5265
5835
|
const decisions = useList("decisions", basePath);
|
|
5266
|
-
const [asOf] =
|
|
5267
|
-
return
|
|
5836
|
+
const [asOf] = useState13(() => (/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
|
|
5837
|
+
return useMemo7(() => {
|
|
5268
5838
|
const counts = needsHumanCounts({
|
|
5269
5839
|
asOf,
|
|
5270
5840
|
assumptions: assumptions.records ?? [],
|
|
@@ -5280,7 +5850,7 @@ function useNeedsHuman(basePath = "/api") {
|
|
|
5280
5850
|
}
|
|
5281
5851
|
|
|
5282
5852
|
// src/dashboard-app.tsx
|
|
5283
|
-
import { jsx as
|
|
5853
|
+
import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
5284
5854
|
function initialsOf(name) {
|
|
5285
5855
|
const parts = name.trim().split(/\s+/);
|
|
5286
5856
|
const first = parts[0]?.[0] ?? "";
|
|
@@ -5296,7 +5866,7 @@ function ValidationOSDashboard({ config = {} }) {
|
|
|
5296
5866
|
user,
|
|
5297
5867
|
registers = REGISTER_ORDER
|
|
5298
5868
|
} = config;
|
|
5299
|
-
const [route, setRoute] =
|
|
5869
|
+
const [route, setRoute] = useState14(
|
|
5300
5870
|
() => typeof window === "undefined" ? { name: "next" } : parseRoute(window.location.hash, registers)
|
|
5301
5871
|
);
|
|
5302
5872
|
const { counts } = useCounts(basePath);
|
|
@@ -5322,33 +5892,33 @@ function ValidationOSDashboard({ config = {} }) {
|
|
|
5322
5892
|
}, []);
|
|
5323
5893
|
const brandName = branding?.name ?? "Validation-OS";
|
|
5324
5894
|
const brandMark = branding?.initials ?? "V";
|
|
5325
|
-
return /* @__PURE__ */
|
|
5326
|
-
/* @__PURE__ */
|
|
5327
|
-
/* @__PURE__ */
|
|
5895
|
+
return /* @__PURE__ */ jsxs19("div", { className: "vos-app", children: [
|
|
5896
|
+
/* @__PURE__ */ jsxs19("div", { className: "vos-brand", children: [
|
|
5897
|
+
/* @__PURE__ */ jsx20("span", { className: "vos-brand-dot", children: branding?.logoUrl ? /* @__PURE__ */ jsx20("img", { src: branding.logoUrl, alt: "" }) : brandMark }),
|
|
5328
5898
|
" ",
|
|
5329
5899
|
brandName
|
|
5330
5900
|
] }),
|
|
5331
|
-
/* @__PURE__ */
|
|
5332
|
-
backendLabel ? /* @__PURE__ */
|
|
5333
|
-
/* @__PURE__ */
|
|
5901
|
+
/* @__PURE__ */ jsxs19("div", { className: "vos-topbar", children: [
|
|
5902
|
+
backendLabel ? /* @__PURE__ */ jsxs19("div", { className: "vos-backend", children: [
|
|
5903
|
+
/* @__PURE__ */ jsx20("span", { className: "vos-live-dot" }),
|
|
5334
5904
|
" Backend: ",
|
|
5335
|
-
/* @__PURE__ */
|
|
5905
|
+
/* @__PURE__ */ jsx20("b", { children: backendLabel })
|
|
5336
5906
|
] }) : null,
|
|
5337
|
-
agentLabel ? /* @__PURE__ */
|
|
5907
|
+
agentLabel ? /* @__PURE__ */ jsxs19("span", { className: "vos-hint", children: [
|
|
5338
5908
|
"Agent: ",
|
|
5339
|
-
/* @__PURE__ */
|
|
5909
|
+
/* @__PURE__ */ jsx20("b", { style: { color: "var(--vos-text)" }, children: agentLabel })
|
|
5340
5910
|
] }) : null,
|
|
5341
|
-
/* @__PURE__ */
|
|
5342
|
-
/* @__PURE__ */
|
|
5343
|
-
user?.name ? /* @__PURE__ */
|
|
5344
|
-
/* @__PURE__ */
|
|
5345
|
-
/* @__PURE__ */
|
|
5346
|
-
/* @__PURE__ */
|
|
5347
|
-
user.caption ? /* @__PURE__ */
|
|
5911
|
+
/* @__PURE__ */ jsx20("div", { className: "vos-spacer" }),
|
|
5912
|
+
/* @__PURE__ */ jsx20("button", { type: "button", className: "vos-iconbtn", onClick: toggleTheme, children: "\u25D0 Theme" }),
|
|
5913
|
+
user?.name ? /* @__PURE__ */ jsxs19("div", { className: "vos-user", children: [
|
|
5914
|
+
/* @__PURE__ */ jsx20("span", { className: "vos-avatar", children: initialsOf(user.name) }),
|
|
5915
|
+
/* @__PURE__ */ jsxs19("div", { children: [
|
|
5916
|
+
/* @__PURE__ */ jsx20("span", { className: "vos-user-name", children: user.name }),
|
|
5917
|
+
user.caption ? /* @__PURE__ */ jsx20("small", { children: user.caption }) : null
|
|
5348
5918
|
] })
|
|
5349
5919
|
] }) : null
|
|
5350
5920
|
] }),
|
|
5351
|
-
/* @__PURE__ */
|
|
5921
|
+
/* @__PURE__ */ jsx20(
|
|
5352
5922
|
SidebarNav,
|
|
5353
5923
|
{
|
|
5354
5924
|
route,
|
|
@@ -5358,7 +5928,7 @@ function ValidationOSDashboard({ config = {} }) {
|
|
|
5358
5928
|
registers
|
|
5359
5929
|
}
|
|
5360
5930
|
),
|
|
5361
|
-
/* @__PURE__ */
|
|
5931
|
+
/* @__PURE__ */ jsx20("main", { className: "vos-main", children: route.name === "records" ? /* @__PURE__ */ jsx20(
|
|
5362
5932
|
RegisterBrowser,
|
|
5363
5933
|
{
|
|
5364
5934
|
register: route.register,
|
|
@@ -5367,7 +5937,7 @@ function ValidationOSDashboard({ config = {} }) {
|
|
|
5367
5937
|
onOpenRecord: (id) => navigate({ name: "record", id })
|
|
5368
5938
|
},
|
|
5369
5939
|
route.register
|
|
5370
|
-
) : route.name === "record" ? /* @__PURE__ */
|
|
5940
|
+
) : route.name === "record" ? /* @__PURE__ */ jsx20(
|
|
5371
5941
|
RecordPage,
|
|
5372
5942
|
{
|
|
5373
5943
|
recordId: route.id,
|
|
@@ -5376,7 +5946,7 @@ function ValidationOSDashboard({ config = {} }) {
|
|
|
5376
5946
|
basePath
|
|
5377
5947
|
},
|
|
5378
5948
|
route.id
|
|
5379
|
-
) : route.name === "pipeline" ? /* @__PURE__ */
|
|
5949
|
+
) : route.name === "pipeline" ? /* @__PURE__ */ jsx20(PipelineSurface, { basePath, onNavigate: navigate }, "pipeline") : route.name === "stage-grid" ? /* @__PURE__ */ jsx20(StageGridSurface, { basePath, onNavigate: navigate }, "stage-grid") : /* @__PURE__ */ jsx20(NextMoveSurface, { basePath, onNavigate: navigate }, "next") })
|
|
5380
5950
|
] });
|
|
5381
5951
|
}
|
|
5382
5952
|
|
|
@@ -5406,15 +5976,15 @@ function composeConnectCommand(input) {
|
|
|
5406
5976
|
}
|
|
5407
5977
|
|
|
5408
5978
|
// src/connect-claude-code.tsx
|
|
5409
|
-
import { useState as
|
|
5410
|
-
import { jsx as
|
|
5979
|
+
import { useState as useState15 } from "react";
|
|
5980
|
+
import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
5411
5981
|
function ConnectClaudeCode({
|
|
5412
5982
|
apiBaseUrl,
|
|
5413
5983
|
tokenEnv,
|
|
5414
5984
|
mintToken
|
|
5415
5985
|
}) {
|
|
5416
|
-
const [state, setState] =
|
|
5417
|
-
const [copied, setCopied] =
|
|
5986
|
+
const [state, setState] = useState15({ phase: "idle" });
|
|
5987
|
+
const [copied, setCopied] = useState15(false);
|
|
5418
5988
|
async function generate() {
|
|
5419
5989
|
setState({ phase: "minting" });
|
|
5420
5990
|
setCopied(false);
|
|
@@ -5436,21 +6006,21 @@ function ConnectClaudeCode({
|
|
|
5436
6006
|
} catch {
|
|
5437
6007
|
}
|
|
5438
6008
|
}
|
|
5439
|
-
return /* @__PURE__ */
|
|
5440
|
-
/* @__PURE__ */
|
|
5441
|
-
/* @__PURE__ */
|
|
5442
|
-
/* @__PURE__ */
|
|
6009
|
+
return /* @__PURE__ */ jsxs20("div", { children: [
|
|
6010
|
+
/* @__PURE__ */ jsx21("div", { className: "vos-head", children: /* @__PURE__ */ jsxs20("div", { children: [
|
|
6011
|
+
/* @__PURE__ */ jsx21("h1", { children: "Connect Claude Code" }),
|
|
6012
|
+
/* @__PURE__ */ jsx21("p", { children: "Run the validation skills against this register from your own Claude Code \u2014 no repo, no keys to hunt down." })
|
|
5443
6013
|
] }) }),
|
|
5444
|
-
/* @__PURE__ */
|
|
5445
|
-
/* @__PURE__ */
|
|
5446
|
-
/* @__PURE__ */
|
|
5447
|
-
/* @__PURE__ */
|
|
6014
|
+
/* @__PURE__ */ jsxs20("ol", { className: "vos-hint", style: { lineHeight: 1.8 }, children: [
|
|
6015
|
+
/* @__PURE__ */ jsx21("li", { children: "Generate your personal connection command below." }),
|
|
6016
|
+
/* @__PURE__ */ jsx21("li", { children: "Paste it into a terminal in the workspace you'll run the skills in." }),
|
|
6017
|
+
/* @__PURE__ */ jsxs20("li", { children: [
|
|
5448
6018
|
"The command carries a token tied to ",
|
|
5449
|
-
/* @__PURE__ */
|
|
6019
|
+
/* @__PURE__ */ jsx21("strong", { children: "you" }),
|
|
5450
6020
|
" \u2014 anything you write lands under your name. Don't share it."
|
|
5451
6021
|
] })
|
|
5452
6022
|
] }),
|
|
5453
|
-
state.phase !== "ready" ? /* @__PURE__ */
|
|
6023
|
+
state.phase !== "ready" ? /* @__PURE__ */ jsx21(
|
|
5454
6024
|
"button",
|
|
5455
6025
|
{
|
|
5456
6026
|
type: "button",
|
|
@@ -5460,11 +6030,11 @@ function ConnectClaudeCode({
|
|
|
5460
6030
|
children: state.phase === "minting" ? "Generating\u2026" : "Generate connection command"
|
|
5461
6031
|
}
|
|
5462
6032
|
) : null,
|
|
5463
|
-
state.phase === "error" ? /* @__PURE__ */
|
|
5464
|
-
state.phase === "ready" ? /* @__PURE__ */
|
|
5465
|
-
/* @__PURE__ */
|
|
5466
|
-
/* @__PURE__ */
|
|
5467
|
-
/* @__PURE__ */
|
|
6033
|
+
state.phase === "error" ? /* @__PURE__ */ jsx21("p", { className: "vos-hint", role: "alert", children: state.message }) : null,
|
|
6034
|
+
state.phase === "ready" ? /* @__PURE__ */ jsxs20("div", { children: [
|
|
6035
|
+
/* @__PURE__ */ jsx21("pre", { className: "vos-code", "aria-label": "Connection command", children: state.command }),
|
|
6036
|
+
/* @__PURE__ */ jsxs20("div", { style: { display: "flex", gap: 8 }, children: [
|
|
6037
|
+
/* @__PURE__ */ jsx21(
|
|
5468
6038
|
"button",
|
|
5469
6039
|
{
|
|
5470
6040
|
type: "button",
|
|
@@ -5473,31 +6043,31 @@ function ConnectClaudeCode({
|
|
|
5473
6043
|
children: copied ? "Copied" : "Copy command"
|
|
5474
6044
|
}
|
|
5475
6045
|
),
|
|
5476
|
-
/* @__PURE__ */
|
|
6046
|
+
/* @__PURE__ */ jsx21("button", { type: "button", className: "vos-btn-ghost", onClick: generate, children: "Regenerate" })
|
|
5477
6047
|
] }),
|
|
5478
|
-
/* @__PURE__ */
|
|
6048
|
+
/* @__PURE__ */ jsx21("p", { className: "vos-hint", style: { marginTop: 12 }, children: "Generating again revokes nothing on its own \u2014 remove old keys from your account settings when you rotate." })
|
|
5479
6049
|
] }) : null
|
|
5480
6050
|
] });
|
|
5481
6051
|
}
|
|
5482
6052
|
|
|
5483
6053
|
// src/surface-placeholder.tsx
|
|
5484
|
-
import { jsx as
|
|
6054
|
+
import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
5485
6055
|
function SurfacePlaceholder({
|
|
5486
6056
|
title,
|
|
5487
6057
|
subtitle,
|
|
5488
6058
|
detail
|
|
5489
6059
|
}) {
|
|
5490
|
-
return /* @__PURE__ */
|
|
5491
|
-
/* @__PURE__ */
|
|
5492
|
-
/* @__PURE__ */
|
|
5493
|
-
/* @__PURE__ */
|
|
6060
|
+
return /* @__PURE__ */ jsxs21("div", { children: [
|
|
6061
|
+
/* @__PURE__ */ jsx22("div", { className: "vos-head", children: /* @__PURE__ */ jsxs21("div", { children: [
|
|
6062
|
+
/* @__PURE__ */ jsx22("h1", { children: title }),
|
|
6063
|
+
/* @__PURE__ */ jsx22("p", { children: subtitle })
|
|
5494
6064
|
] }) }),
|
|
5495
|
-
/* @__PURE__ */
|
|
6065
|
+
/* @__PURE__ */ jsx22("div", { className: "vos-empty", children: detail })
|
|
5496
6066
|
] });
|
|
5497
6067
|
}
|
|
5498
6068
|
|
|
5499
6069
|
// src/register-counts.tsx
|
|
5500
|
-
import { jsx as
|
|
6070
|
+
import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
5501
6071
|
function RegisterCounts({
|
|
5502
6072
|
counts,
|
|
5503
6073
|
caption,
|
|
@@ -5507,8 +6077,8 @@ function RegisterCounts({
|
|
|
5507
6077
|
const registers = REGISTER_ORDER.filter(
|
|
5508
6078
|
(r) => counts[r] !== void 0
|
|
5509
6079
|
);
|
|
5510
|
-
return /* @__PURE__ */
|
|
5511
|
-
/* @__PURE__ */
|
|
6080
|
+
return /* @__PURE__ */ jsxs22("section", { "aria-label": "Register counts", children: [
|
|
6081
|
+
/* @__PURE__ */ jsx23("div", { className: "vos-tile-grid", children: registers.map((register) => /* @__PURE__ */ jsx23(
|
|
5512
6082
|
StatTile,
|
|
5513
6083
|
{
|
|
5514
6084
|
label: REGISTER_LABEL[register],
|
|
@@ -5518,11 +6088,12 @@ function RegisterCounts({
|
|
|
5518
6088
|
},
|
|
5519
6089
|
register
|
|
5520
6090
|
)) }),
|
|
5521
|
-
caption ? /* @__PURE__ */
|
|
6091
|
+
caption ? /* @__PURE__ */ jsx23("p", { className: "vos-hint", style: { marginTop: 16 }, children: caption }) : null
|
|
5522
6092
|
] });
|
|
5523
6093
|
}
|
|
5524
6094
|
export {
|
|
5525
6095
|
BeliefJourney,
|
|
6096
|
+
BeliefVerdicts,
|
|
5526
6097
|
CONFLICT_MESSAGE,
|
|
5527
6098
|
ConfidenceCell,
|
|
5528
6099
|
ConnectClaudeCode,
|
|
@@ -5533,6 +6104,9 @@ export {
|
|
|
5533
6104
|
FIRST_RUN_LINE,
|
|
5534
6105
|
FieldInput,
|
|
5535
6106
|
GlossaryText,
|
|
6107
|
+
Markdown,
|
|
6108
|
+
NO_LENS,
|
|
6109
|
+
NO_STAGE,
|
|
5536
6110
|
NextMoveSurface,
|
|
5537
6111
|
PipelineSurface,
|
|
5538
6112
|
REGISTER_GROUPS,
|
|
@@ -5551,9 +6125,12 @@ export {
|
|
|
5551
6125
|
RegisterTable,
|
|
5552
6126
|
RelationEditor,
|
|
5553
6127
|
RiskBar,
|
|
6128
|
+
STAGE_GLOSS,
|
|
6129
|
+
STAGE_ORDER,
|
|
5554
6130
|
ScoreImpactForm,
|
|
5555
6131
|
SidebarNav,
|
|
5556
6132
|
Sparkline,
|
|
6133
|
+
StageGridSurface,
|
|
5557
6134
|
StatTile,
|
|
5558
6135
|
StatusPill,
|
|
5559
6136
|
SurfacePlaceholder,
|
|
@@ -5561,12 +6138,15 @@ export {
|
|
|
5561
6138
|
ValidationOSDashboard,
|
|
5562
6139
|
WriteDecisionForm,
|
|
5563
6140
|
backlinkPanels,
|
|
6141
|
+
bodyPreview,
|
|
5564
6142
|
buildCycles,
|
|
5565
6143
|
buildJourney,
|
|
5566
6144
|
buildPatch,
|
|
5567
6145
|
buildPipeline,
|
|
5568
6146
|
buildRecordPage,
|
|
6147
|
+
buildStageGrid,
|
|
5569
6148
|
buildUnderstanding,
|
|
6149
|
+
cellAt,
|
|
5570
6150
|
cellValue,
|
|
5571
6151
|
coldStartFor,
|
|
5572
6152
|
columnsFor,
|
|
@@ -5604,6 +6184,9 @@ export {
|
|
|
5604
6184
|
ownerNames,
|
|
5605
6185
|
parseRoute,
|
|
5606
6186
|
primaryLabel,
|
|
6187
|
+
rankByRisk,
|
|
6188
|
+
readingAssumptionChips,
|
|
6189
|
+
readingBeliefVerdicts,
|
|
5607
6190
|
resolveBarLines,
|
|
5608
6191
|
riskBand,
|
|
5609
6192
|
riskFraction,
|
|
@@ -5613,6 +6196,7 @@ export {
|
|
|
5613
6196
|
sortRecords,
|
|
5614
6197
|
sparklinePath,
|
|
5615
6198
|
stageMeters,
|
|
6199
|
+
stageOf,
|
|
5616
6200
|
statusTone,
|
|
5617
6201
|
tabsFor,
|
|
5618
6202
|
toCreatePayload,
|