@gobing-ai/knowledge-kit 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/dist/board/collect/index.js +744 -1107
- package/dist/board/daily-voice/index.js +741 -107
- package/dist/board/itc/index.js +32 -6
- package/dist/index.js +1793 -103
- package/package.json +1 -1
- package/plugins/ingestions/horizon-ingest/dist/index.js +24 -1
- package/plugins/ingestions/horizon-ingest/src/index.ts +34 -0
- package/plugins/kk/config.example.yaml +8 -0
- package/plugins/kk/decisions/extract/ai-news.yaml +7 -1
- package/plugins/kk/plugin.json +1 -1
- package/plugins/kk/publish-presets/daily-ai-voice.json +123 -0
- package/plugins/kk/schedules/kk-daily-publish3-cn-peak.cron.tmpl +20 -0
- package/plugins/kk/schedules/kk-daily-publish3-overseas.cron.tmpl +17 -0
- package/plugins/kk/scripts/daily-stages.ts +664 -83
- package/plugins/kk/scripts/kk-workflow-stages.ts +11 -1
- package/plugins/kk/scripts/topic-boundary.json +18 -83
- package/plugins/kk/workflows/kk-collect.yaml +2 -0
- package/plugins/kk/workflows/kk-daily-ai-voice2.yaml +82 -8
- package/plugins/kk/workflows/kk-daily-ai-voice3.yaml +842 -0
- package/plugins/kk/workflows/kk-daily-publish3.yaml +282 -0
- package/plugins/publishings/podcast-pub/README.md +65 -0
- package/plugins/publishings/podcast-pub/dist/index.js +1709 -274
- package/plugins/publishings/podcast-pub/plugin.json +1 -1
- package/plugins/publishings/podcast-pub/src/backfill.ts +465 -0
- package/plugins/publishings/podcast-pub/src/index.ts +211 -34
- package/plugins/publishings/podcast-pub/src/microfeed-client.ts +32 -3
- package/plugins/publishings/podcast-pub/src/seo.ts +1081 -0
- package/plugins/publishings/podcast-pub/src/show-notes.ts +71 -6
- package/plugins/publishings/surfdash-pub/dist/index.js +66 -5
- package/plugins/publishings/surfdash-pub/src/index.ts +94 -10
- package/plugins/publishings/wechatmp-pub/dist/index.js +54 -30
- package/plugins/publishings/wechatmp-pub/dist/profile-check.js +8 -3
- package/plugins/publishings/wechatmp-pub/src/enrich.ts +58 -38
- package/plugins/publishings/wechatmp-pub/src/flow.ts +18 -1
- package/plugins/publishings/wechatmp-pub/src/profile-check.ts +7 -1
|
@@ -37,6 +37,14 @@ function storeSelectionsQueryString(query) {
|
|
|
37
37
|
}
|
|
38
38
|
return params.toString();
|
|
39
39
|
}
|
|
40
|
+
function storeChannelsQueryString(query) {
|
|
41
|
+
const params = new URLSearchParams({
|
|
42
|
+
from: String(query.fromMs),
|
|
43
|
+
until: String(query.untilMs),
|
|
44
|
+
page: String(query.page)
|
|
45
|
+
});
|
|
46
|
+
return params.toString();
|
|
47
|
+
}
|
|
40
48
|
var DEFAULT_READER_ORIGIN = "http://127.0.0.1:4340";
|
|
41
49
|
function readerOriginFrom(search, defaultOrigin = DEFAULT_READER_ORIGIN) {
|
|
42
50
|
const override = new URLSearchParams(search).get("kkApi");
|
|
@@ -67,6 +75,19 @@ function isLoopbackHttpOrigin(origin) {
|
|
|
67
75
|
return false;
|
|
68
76
|
return url.hostname === "127.0.0.1" || url.hostname === "localhost" || url.hostname === "[::1]";
|
|
69
77
|
}
|
|
78
|
+
function isHttpOrigin(origin) {
|
|
79
|
+
let url;
|
|
80
|
+
try {
|
|
81
|
+
url = new URL(origin);
|
|
82
|
+
} catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
if (url.protocol !== "http:" && url.protocol !== "https:")
|
|
86
|
+
return false;
|
|
87
|
+
if (url.username !== "" || url.password !== "")
|
|
88
|
+
return false;
|
|
89
|
+
return url.pathname === "/" && url.search === "" && url.hash === "";
|
|
90
|
+
}
|
|
70
91
|
function origin(base) {
|
|
71
92
|
return base.replace(/\/+$/, "");
|
|
72
93
|
}
|
|
@@ -90,16 +111,20 @@ function parseSpurDbRows(pageData) {
|
|
|
90
111
|
});
|
|
91
112
|
}
|
|
92
113
|
function createBoardClient(options) {
|
|
93
|
-
|
|
114
|
+
const reader = origin(options.readerOrigin);
|
|
115
|
+
const board = origin(options.boardOrigin);
|
|
116
|
+
const isNativeSpur = reader === board;
|
|
117
|
+
if (!isHttpOrigin(options.boardOrigin)) {
|
|
118
|
+
throw new Error(`board origin must be an http origin, got '${options.boardOrigin}'`);
|
|
119
|
+
}
|
|
120
|
+
if (!isNativeSpur && !isLoopbackHttpOrigin(options.readerOrigin)) {
|
|
94
121
|
throw new Error(`reader origin must be loopback http, got '${options.readerOrigin}'`);
|
|
95
122
|
}
|
|
96
|
-
|
|
97
|
-
|
|
123
|
+
const aggregateReader = origin(options.aggregateReaderOrigin ?? DEFAULT_READER_ORIGIN);
|
|
124
|
+
if (!isLoopbackHttpOrigin(options.aggregateReaderOrigin ?? DEFAULT_READER_ORIGIN)) {
|
|
125
|
+
throw new Error(`aggregate reader origin must be loopback http, got '${options.aggregateReaderOrigin}'`);
|
|
98
126
|
}
|
|
99
|
-
const reader = origin(options.readerOrigin);
|
|
100
|
-
const board = origin(options.boardOrigin);
|
|
101
127
|
const doFetch = options.fetchImpl ?? fetch;
|
|
102
|
-
const isNativeSpur = reader === board;
|
|
103
128
|
async function getJson(url) {
|
|
104
129
|
const response = await doFetch(url, { headers: { accept: "application/json" } });
|
|
105
130
|
if (!response.ok) {
|
|
@@ -493,11 +518,190 @@ function createBoardClient(options) {
|
|
|
493
518
|
return getJson(path);
|
|
494
519
|
},
|
|
495
520
|
storeSelections: (query = {}) => isNativeSpur ? nativeStoreSelections(query) : getJson(`${reader}/api/workflows/kk-collect/store/selections?${storeSelectionsQueryString(query)}`),
|
|
521
|
+
storeChannels: (query) => getJson(`${aggregateReader}/api/workflows/kk-collect/store/channels?${storeChannelsQueryString(query)}`),
|
|
496
522
|
runDetail: (runId) => getJson(`${board}/api/runs/${encodeURIComponent(runId)}`),
|
|
497
523
|
progress: (runId) => getJson(`${board}/api/runs/${encodeURIComponent(runId)}/progress`)
|
|
498
524
|
};
|
|
499
525
|
}
|
|
500
526
|
|
|
527
|
+
// ../board/src/shared/channel-yield.tsx
|
|
528
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
529
|
+
function localDayKey(ms, timeZone) {
|
|
530
|
+
return new Intl.DateTimeFormat("en-CA", {
|
|
531
|
+
timeZone,
|
|
532
|
+
year: "numeric",
|
|
533
|
+
month: "2-digit",
|
|
534
|
+
day: "2-digit"
|
|
535
|
+
}).format(ms);
|
|
536
|
+
}
|
|
537
|
+
function isLocalMidnight(ms, timeZone) {
|
|
538
|
+
return new Intl.DateTimeFormat("en-GB", {
|
|
539
|
+
timeZone,
|
|
540
|
+
hour: "2-digit",
|
|
541
|
+
minute: "2-digit",
|
|
542
|
+
second: "2-digit",
|
|
543
|
+
hour12: false
|
|
544
|
+
}).format(ms) === "00:00:00";
|
|
545
|
+
}
|
|
546
|
+
function isPartialDay(day, data) {
|
|
547
|
+
const fromDay = localDayKey(data.fromMs, data.timeZone);
|
|
548
|
+
const untilDay = localDayKey(Math.max(data.fromMs, data.untilMs - 1), data.timeZone);
|
|
549
|
+
if (day === fromDay && !isLocalMidnight(data.fromMs, data.timeZone))
|
|
550
|
+
return true;
|
|
551
|
+
if (day === untilDay && !isLocalMidnight(data.untilMs, data.timeZone))
|
|
552
|
+
return true;
|
|
553
|
+
return false;
|
|
554
|
+
}
|
|
555
|
+
function lastPositiveLabel(at) {
|
|
556
|
+
return at === null ? "unknown" : `${new Date(at).toLocaleString()} (${new Date(at).toISOString()})`;
|
|
557
|
+
}
|
|
558
|
+
function ChannelYieldTable({ data }) {
|
|
559
|
+
const { sources, byDay, bySource } = data;
|
|
560
|
+
if (byDay.length === 0) {
|
|
561
|
+
return /* @__PURE__ */ jsx("p", {
|
|
562
|
+
className: "kk-board-state",
|
|
563
|
+
children: "No new items in this range."
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
const grandTotal = sources.reduce((sum, source) => sum + (bySource[source] ?? 0), 0);
|
|
567
|
+
return /* @__PURE__ */ jsxs("table", {
|
|
568
|
+
className: "kk-table kk-channel-yield-table",
|
|
569
|
+
children: [
|
|
570
|
+
/* @__PURE__ */ jsx("thead", {
|
|
571
|
+
children: /* @__PURE__ */ jsxs("tr", {
|
|
572
|
+
children: [
|
|
573
|
+
/* @__PURE__ */ jsx("th", {
|
|
574
|
+
scope: "col",
|
|
575
|
+
children: "Day"
|
|
576
|
+
}),
|
|
577
|
+
sources.map((source) => /* @__PURE__ */ jsx("th", {
|
|
578
|
+
scope: "col",
|
|
579
|
+
children: source
|
|
580
|
+
}, source)),
|
|
581
|
+
/* @__PURE__ */ jsx("th", {
|
|
582
|
+
scope: "col",
|
|
583
|
+
children: "Total"
|
|
584
|
+
})
|
|
585
|
+
]
|
|
586
|
+
})
|
|
587
|
+
}),
|
|
588
|
+
/* @__PURE__ */ jsxs("tbody", {
|
|
589
|
+
children: [
|
|
590
|
+
byDay.map((day) => /* @__PURE__ */ jsxs("tr", {
|
|
591
|
+
children: [
|
|
592
|
+
/* @__PURE__ */ jsxs("td", {
|
|
593
|
+
children: [
|
|
594
|
+
day.day,
|
|
595
|
+
isPartialDay(day.day, data) ? " (partial)" : ""
|
|
596
|
+
]
|
|
597
|
+
}),
|
|
598
|
+
sources.map((source) => /* @__PURE__ */ jsx("td", {
|
|
599
|
+
children: day.sources[source] ?? 0
|
|
600
|
+
}, source)),
|
|
601
|
+
/* @__PURE__ */ jsx("td", {
|
|
602
|
+
children: day.total
|
|
603
|
+
})
|
|
604
|
+
]
|
|
605
|
+
}, day.day)),
|
|
606
|
+
/* @__PURE__ */ jsxs("tr", {
|
|
607
|
+
className: "kk-table-total",
|
|
608
|
+
children: [
|
|
609
|
+
/* @__PURE__ */ jsx("td", {
|
|
610
|
+
children: "Total"
|
|
611
|
+
}),
|
|
612
|
+
sources.map((source) => /* @__PURE__ */ jsx("td", {
|
|
613
|
+
children: bySource[source] ?? 0
|
|
614
|
+
}, source)),
|
|
615
|
+
/* @__PURE__ */ jsx("td", {
|
|
616
|
+
children: grandTotal
|
|
617
|
+
})
|
|
618
|
+
]
|
|
619
|
+
})
|
|
620
|
+
]
|
|
621
|
+
})
|
|
622
|
+
]
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
function PluginRunTable({ data }) {
|
|
626
|
+
const { plugins, runsByDay, lastPositiveAt } = data;
|
|
627
|
+
if (runsByDay.length === 0) {
|
|
628
|
+
return /* @__PURE__ */ jsx("p", {
|
|
629
|
+
className: "kk-board-state",
|
|
630
|
+
children: "No collection ticks in this range."
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
634
|
+
className: "kk-plugin-run",
|
|
635
|
+
children: [
|
|
636
|
+
/* @__PURE__ */ jsxs("table", {
|
|
637
|
+
className: "kk-table kk-plugin-run-table",
|
|
638
|
+
children: [
|
|
639
|
+
/* @__PURE__ */ jsx("caption", {
|
|
640
|
+
className: "kk-plugin-run-caption",
|
|
641
|
+
children: "Zero recorded contributions — plugin invocation health unknown."
|
|
642
|
+
}),
|
|
643
|
+
/* @__PURE__ */ jsx("thead", {
|
|
644
|
+
children: /* @__PURE__ */ jsxs("tr", {
|
|
645
|
+
children: [
|
|
646
|
+
/* @__PURE__ */ jsx("th", {
|
|
647
|
+
scope: "col",
|
|
648
|
+
children: "Day"
|
|
649
|
+
}),
|
|
650
|
+
/* @__PURE__ */ jsx("th", {
|
|
651
|
+
scope: "col",
|
|
652
|
+
children: "Runs"
|
|
653
|
+
}),
|
|
654
|
+
plugins.map((plugin) => /* @__PURE__ */ jsx("th", {
|
|
655
|
+
scope: "col",
|
|
656
|
+
children: plugin
|
|
657
|
+
}, plugin))
|
|
658
|
+
]
|
|
659
|
+
})
|
|
660
|
+
}),
|
|
661
|
+
/* @__PURE__ */ jsx("tbody", {
|
|
662
|
+
children: runsByDay.map((day) => {
|
|
663
|
+
const pluginCounts = day.plugins;
|
|
664
|
+
return /* @__PURE__ */ jsxs("tr", {
|
|
665
|
+
children: [
|
|
666
|
+
/* @__PURE__ */ jsx("td", {
|
|
667
|
+
children: day.day
|
|
668
|
+
}),
|
|
669
|
+
/* @__PURE__ */ jsx("td", {
|
|
670
|
+
children: day.runs
|
|
671
|
+
}),
|
|
672
|
+
pluginCounts === null ? /* @__PURE__ */ jsx("td", {
|
|
673
|
+
colSpan: plugins.length,
|
|
674
|
+
className: "kk-board-state",
|
|
675
|
+
children: "unknown"
|
|
676
|
+
}) : plugins.map((plugin) => /* @__PURE__ */ jsx("td", {
|
|
677
|
+
children: pluginCounts[plugin] ?? 0
|
|
678
|
+
}, plugin))
|
|
679
|
+
]
|
|
680
|
+
}, day.day);
|
|
681
|
+
})
|
|
682
|
+
})
|
|
683
|
+
]
|
|
684
|
+
}),
|
|
685
|
+
/* @__PURE__ */ jsx("dl", {
|
|
686
|
+
className: "kk-board-facts",
|
|
687
|
+
children: plugins.map((plugin) => /* @__PURE__ */ jsxs("div", {
|
|
688
|
+
children: [
|
|
689
|
+
/* @__PURE__ */ jsxs("dt", {
|
|
690
|
+
children: [
|
|
691
|
+
"Last positive ",
|
|
692
|
+
plugin
|
|
693
|
+
]
|
|
694
|
+
}),
|
|
695
|
+
/* @__PURE__ */ jsx("dd", {
|
|
696
|
+
children: lastPositiveLabel(lastPositiveAt[plugin] ?? null)
|
|
697
|
+
})
|
|
698
|
+
]
|
|
699
|
+
}, plugin))
|
|
700
|
+
})
|
|
701
|
+
]
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
|
|
501
705
|
// ../board/src/shared/format.ts
|
|
502
706
|
function availabilityLabel(availability) {
|
|
503
707
|
switch (availability) {
|
|
@@ -568,6 +772,10 @@ function artifactViews(results, readerOrigin) {
|
|
|
568
772
|
var ACTIVE_POLL_MS = 5000;
|
|
569
773
|
var HISTORY_POLL_MS = 30000;
|
|
570
774
|
var MAX_BACKOFF_MS = 30000;
|
|
775
|
+
function requestSequence() {
|
|
776
|
+
let newest = 0;
|
|
777
|
+
return { begin: () => ++newest, isCurrent: (token) => token === newest };
|
|
778
|
+
}
|
|
571
779
|
function initialRefresh(intervalMs) {
|
|
572
780
|
return { pending: false, failures: 0, backoffMs: intervalMs, lastSuccessAt: null, failingSince: null };
|
|
573
781
|
}
|
|
@@ -836,9 +1044,79 @@ function dailySummaryFacts(results, now) {
|
|
|
836
1044
|
];
|
|
837
1045
|
return facts;
|
|
838
1046
|
}
|
|
1047
|
+
var GATE_NAMES = {
|
|
1048
|
+
"episode-duration": "Duration floor refusal",
|
|
1049
|
+
script: "Script refusal",
|
|
1050
|
+
"qc-floor": "QC floor refusal",
|
|
1051
|
+
"empty-pool": "Empty pool",
|
|
1052
|
+
"qc-empty": "QC emptied the pool",
|
|
1053
|
+
unknown: "unknown — no gate proven"
|
|
1054
|
+
};
|
|
1055
|
+
function isFunnelGate(value) {
|
|
1056
|
+
return value === "episode-duration" || value === "script" || value === "qc-floor" || value === "empty-pool" || value === "qc-empty" || value === "unknown";
|
|
1057
|
+
}
|
|
1058
|
+
function funnelView(value) {
|
|
1059
|
+
const record = asRecord(value);
|
|
1060
|
+
const gate = isFunnelGate(record?.gate) ? record.gate : null;
|
|
1061
|
+
return {
|
|
1062
|
+
poolCount: asNumber(record?.poolCount),
|
|
1063
|
+
annotatedCount: asNumber(record?.annotatedCount),
|
|
1064
|
+
qcRejectedCount: asNumber(record?.qcRejectedCount),
|
|
1065
|
+
topicKeptCount: asNumber(record?.topicKeptCount),
|
|
1066
|
+
dedupKeptCount: asNumber(record?.dedupKeptCount),
|
|
1067
|
+
plannedCount: asNumber(record?.plannedCount),
|
|
1068
|
+
estimatedMinutes: asNumber(record?.estimatedMinutes),
|
|
1069
|
+
measuredMinutes: asNumber(record?.measuredMinutes),
|
|
1070
|
+
minMinutes: asNumber(record?.minMinutes),
|
|
1071
|
+
maxMinutes: asNumber(record?.maxMinutes),
|
|
1072
|
+
gate,
|
|
1073
|
+
gateName: gate === null ? "not applicable — a content run has no gate" : GATE_NAMES[gate],
|
|
1074
|
+
exclusions: Array.isArray(record?.exclusions) ? record.exclusions.map((entry) => {
|
|
1075
|
+
const row = asRecord(entry);
|
|
1076
|
+
return row === null || typeof row.rule !== "string" ? null : { rule: row.rule, matched: typeof row.matched === "string" ? row.matched : "" };
|
|
1077
|
+
}).filter((row) => row !== null) : [],
|
|
1078
|
+
evidence: record === null ? {} : Object.fromEntries(Object.entries(record.evidence ?? {}).filter((entry) => typeof entry[1] === "string")),
|
|
1079
|
+
diagnostics: Array.isArray(record?.diagnostics) ? record.diagnostics.map((entry) => {
|
|
1080
|
+
const row = asRecord(entry);
|
|
1081
|
+
return row === null ? null : { code: String(row.code ?? ""), message: String(row.message ?? "") };
|
|
1082
|
+
}).filter((row) => row !== null) : []
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
var WINDOW_UNITS = {
|
|
1086
|
+
s: 1000,
|
|
1087
|
+
m: 60000,
|
|
1088
|
+
h: 3600000,
|
|
1089
|
+
d: 86400000
|
|
1090
|
+
};
|
|
1091
|
+
function parseWindowMs(raw) {
|
|
1092
|
+
if (raw === null || raw === undefined)
|
|
1093
|
+
return null;
|
|
1094
|
+
const match = /^(\d+)([smhd])$/.exec(raw.trim());
|
|
1095
|
+
if (match === null)
|
|
1096
|
+
return null;
|
|
1097
|
+
const [, amountText, unitText] = match;
|
|
1098
|
+
const unit = unitText === "s" || unitText === "m" || unitText === "h" || unitText === "d" ? unitText : null;
|
|
1099
|
+
if (amountText === undefined || unit === null)
|
|
1100
|
+
return null;
|
|
1101
|
+
const milliseconds = Number(amountText) * WINDOW_UNITS[unit];
|
|
1102
|
+
return milliseconds > 0 ? milliseconds : null;
|
|
1103
|
+
}
|
|
1104
|
+
function supplyContextOf(windowSetting, startedAt) {
|
|
1105
|
+
const windowMs = parseWindowMs(windowSetting);
|
|
1106
|
+
const started = startedAt === null || startedAt === undefined ? null : Date.parse(startedAt);
|
|
1107
|
+
if (windowMs === null || started === null || !Number.isFinite(started))
|
|
1108
|
+
return null;
|
|
1109
|
+
return {
|
|
1110
|
+
windowMs,
|
|
1111
|
+
fromMs: started - windowMs,
|
|
1112
|
+
untilMs: started,
|
|
1113
|
+
fromLabel: formatTimestamp(new Date(started - windowMs).toISOString()),
|
|
1114
|
+
untilLabel: formatTimestamp(new Date(started).toISOString())
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
839
1117
|
|
|
840
1118
|
// ../board/src/daily-voice/index.tsx
|
|
841
|
-
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
1119
|
+
import { jsx as jsx2, jsxs as jsxs2, Fragment } from "react/jsx-runtime";
|
|
842
1120
|
var WORKFLOW = "kk-daily-ai-voice2";
|
|
843
1121
|
var MODULE_PATH = "/board/modules/kk-daily-ai-voice2";
|
|
844
1122
|
var TAB_LABELS = {
|
|
@@ -850,6 +1128,9 @@ var TAB_LABELS = {
|
|
|
850
1128
|
function messageOf(error) {
|
|
851
1129
|
return error instanceof Error ? error.message : String(error);
|
|
852
1130
|
}
|
|
1131
|
+
function isOfflineError(message) {
|
|
1132
|
+
return message.includes("Failed to fetch") || message.includes("NetworkError") || message.includes("ECONNREFUSED");
|
|
1133
|
+
}
|
|
853
1134
|
function usePolling(loader, intervalMs, refresh) {
|
|
854
1135
|
const loaderRef = useRef(loader);
|
|
855
1136
|
loaderRef.current = loader;
|
|
@@ -874,20 +1155,30 @@ function usePolling(loader, intervalMs, refresh) {
|
|
|
874
1155
|
function DailyVoiceModule() {
|
|
875
1156
|
const [link] = useState(() => parseDeepLink(window.location.search));
|
|
876
1157
|
const [reader] = useState(() => readerOriginFrom(window.location.search));
|
|
1158
|
+
const [aggregateReader] = useState(() => readerOriginFrom(window.location.search, DEFAULT_READER_ORIGIN));
|
|
877
1159
|
const readerOrigin = reader.origin;
|
|
878
|
-
const client = useMemo(() => createBoardClient({
|
|
1160
|
+
const client = useMemo(() => createBoardClient({
|
|
1161
|
+
readerOrigin,
|
|
1162
|
+
aggregateReaderOrigin: aggregateReader.origin,
|
|
1163
|
+
boardOrigin: window.location.origin
|
|
1164
|
+
}), [readerOrigin, aggregateReader.origin]);
|
|
879
1165
|
const [rows, setRows] = useState([]);
|
|
880
1166
|
const [cursor, setCursor] = useState(null);
|
|
881
1167
|
const [selection, setSelection] = useState({ runId: link.runId ?? null, tab: link.tab ?? "summary" });
|
|
882
1168
|
const [diagnostics, setDiagnostics] = useState(() => [
|
|
883
1169
|
...link.diagnostics,
|
|
884
|
-
...reader.diagnostic === null ? [] : [reader.diagnostic]
|
|
1170
|
+
...reader.diagnostic === null ? [] : [reader.diagnostic],
|
|
1171
|
+
...aggregateReader.diagnostic === null ? [] : [aggregateReader.diagnostic]
|
|
885
1172
|
]);
|
|
886
1173
|
const [historyRefresh, setHistoryRefresh] = useState(() => initialRefresh(HISTORY_POLL_MS));
|
|
887
1174
|
const [readerRefresh, setReaderRefresh] = useState(() => initialRefresh(ACTIVE_POLL_MS));
|
|
888
1175
|
const [results, setResults] = useState(null);
|
|
889
1176
|
const [config, setConfig] = useState(null);
|
|
890
1177
|
const [filterQuery, setFilterQuery] = useState("");
|
|
1178
|
+
const [supply, setSupply] = useState(null);
|
|
1179
|
+
const [storeOffline, setStoreOffline] = useState(false);
|
|
1180
|
+
const supplyRequests = useRef(requestSequence());
|
|
1181
|
+
const supplyKeyRef = useRef(null);
|
|
891
1182
|
const historyBusy = useRef(false);
|
|
892
1183
|
const readerBusy = useRef(false);
|
|
893
1184
|
const selectionRef = useRef(selection);
|
|
@@ -920,15 +1211,24 @@ function DailyVoiceModule() {
|
|
|
920
1211
|
return;
|
|
921
1212
|
readerBusy.current = true;
|
|
922
1213
|
setReaderRefresh((state) => tick(state));
|
|
1214
|
+
let stale = false;
|
|
923
1215
|
try {
|
|
924
1216
|
const [nextResults, nextConfig] = await Promise.all([
|
|
925
1217
|
client.results(WORKFLOW, runId),
|
|
926
1218
|
client.config(WORKFLOW, runId)
|
|
927
1219
|
]);
|
|
1220
|
+
if (selectionRef.current.runId !== runId) {
|
|
1221
|
+
stale = true;
|
|
1222
|
+
return;
|
|
1223
|
+
}
|
|
928
1224
|
setResults(nextResults);
|
|
929
1225
|
setConfig(nextConfig);
|
|
930
1226
|
setReaderRefresh(() => succeeded(Date.now(), ACTIVE_POLL_MS));
|
|
931
1227
|
} catch (error) {
|
|
1228
|
+
if (selectionRef.current.runId !== runId) {
|
|
1229
|
+
stale = true;
|
|
1230
|
+
return;
|
|
1231
|
+
}
|
|
932
1232
|
setDiagnostics((existing) => [
|
|
933
1233
|
...existing,
|
|
934
1234
|
{ code: "board.reader.unavailable", message: messageOf(error) }
|
|
@@ -936,6 +1236,8 @@ function DailyVoiceModule() {
|
|
|
936
1236
|
setReaderRefresh((state) => failed(state, Date.now()));
|
|
937
1237
|
} finally {
|
|
938
1238
|
readerBusy.current = false;
|
|
1239
|
+
if (stale)
|
|
1240
|
+
loadReader();
|
|
939
1241
|
}
|
|
940
1242
|
}, [client]);
|
|
941
1243
|
usePolling(loadHistory, HISTORY_POLL_MS, historyRefresh);
|
|
@@ -952,6 +1254,42 @@ function DailyVoiceModule() {
|
|
|
952
1254
|
const now = Date.now();
|
|
953
1255
|
const summary = results === null ? null : dailySummary(results);
|
|
954
1256
|
const facts = results === null ? [] : dailySummaryFacts(results, now);
|
|
1257
|
+
const funnel = funnelView(results?.summary.funnel);
|
|
1258
|
+
const context = supplyContextOf(config?.settings.window ?? null, summary?.startedAt ?? null);
|
|
1259
|
+
useEffect(() => {
|
|
1260
|
+
const bounds = tab === "summary" && context !== null ? context : null;
|
|
1261
|
+
const key = bounds === null ? null : `${selection.runId}:${bounds.fromMs}:${bounds.untilMs}`;
|
|
1262
|
+
if (key === supplyKeyRef.current)
|
|
1263
|
+
return;
|
|
1264
|
+
supplyKeyRef.current = key;
|
|
1265
|
+
if (bounds === null) {
|
|
1266
|
+
setSupply(null);
|
|
1267
|
+
return;
|
|
1268
|
+
}
|
|
1269
|
+
const token = supplyRequests.current.begin();
|
|
1270
|
+
let cancelled = false;
|
|
1271
|
+
(async () => {
|
|
1272
|
+
try {
|
|
1273
|
+
const page = await client.storeChannels({ fromMs: bounds.fromMs, untilMs: bounds.untilMs, page: 1 });
|
|
1274
|
+
if (cancelled || !supplyRequests.current.isCurrent(token))
|
|
1275
|
+
return;
|
|
1276
|
+
setSupply(page);
|
|
1277
|
+
setStoreOffline(false);
|
|
1278
|
+
} catch (error) {
|
|
1279
|
+
if (cancelled || !supplyRequests.current.isCurrent(token))
|
|
1280
|
+
return;
|
|
1281
|
+
setSupply(null);
|
|
1282
|
+
const message = messageOf(error);
|
|
1283
|
+
if (isOfflineError(message))
|
|
1284
|
+
setStoreOffline(true);
|
|
1285
|
+
else
|
|
1286
|
+
setDiagnostics((existing) => [...existing, { code: "board.store.channels-unavailable", message }]);
|
|
1287
|
+
}
|
|
1288
|
+
})();
|
|
1289
|
+
return () => {
|
|
1290
|
+
cancelled = true;
|
|
1291
|
+
};
|
|
1292
|
+
}, [client, tab, context, selection.runId]);
|
|
955
1293
|
const artifacts = results === null ? [] : artifactViews(results, readerOrigin);
|
|
956
1294
|
const selectedRow = rows.find((row) => row.id === selection.runId);
|
|
957
1295
|
const filteredRows = useMemo(() => {
|
|
@@ -960,31 +1298,31 @@ function DailyVoiceModule() {
|
|
|
960
1298
|
return rows;
|
|
961
1299
|
return rows.filter((r) => r.id.toLowerCase().includes(q) || r.status.toLowerCase().includes(q));
|
|
962
1300
|
}, [rows, filterQuery]);
|
|
963
|
-
return /* @__PURE__ */
|
|
1301
|
+
return /* @__PURE__ */ jsxs2("div", {
|
|
964
1302
|
className: "kk-board kk-board-daily-voice",
|
|
965
1303
|
children: [
|
|
966
|
-
/* @__PURE__ */
|
|
1304
|
+
/* @__PURE__ */ jsxs2("header", {
|
|
967
1305
|
className: "kk-board-header",
|
|
968
1306
|
children: [
|
|
969
|
-
/* @__PURE__ */
|
|
1307
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
970
1308
|
className: "kk-board-header-left",
|
|
971
1309
|
children: [
|
|
972
|
-
/* @__PURE__ */
|
|
1310
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
973
1311
|
className: "kk-board-header-title-row",
|
|
974
1312
|
children: [
|
|
975
|
-
/* @__PURE__ */
|
|
1313
|
+
/* @__PURE__ */ jsx2("h1", {
|
|
976
1314
|
children: "Daily AI Voice"
|
|
977
1315
|
}),
|
|
978
|
-
selectedRow ? /* @__PURE__ */
|
|
1316
|
+
selectedRow ? /* @__PURE__ */ jsx2("span", {
|
|
979
1317
|
className: `kk-badge ${selectedRow.status === "done" ? "kk-badge-success" : selectedRow.status === "failed" ? "kk-badge-failed" : "kk-badge-running"}`,
|
|
980
1318
|
children: selectedRow.status
|
|
981
1319
|
}) : null
|
|
982
1320
|
]
|
|
983
1321
|
}),
|
|
984
|
-
/* @__PURE__ */
|
|
1322
|
+
/* @__PURE__ */ jsxs2("p", {
|
|
985
1323
|
children: [
|
|
986
1324
|
"Run ",
|
|
987
|
-
/* @__PURE__ */
|
|
1325
|
+
/* @__PURE__ */ jsx2("code", {
|
|
988
1326
|
children: selection.runId ?? "none selected"
|
|
989
1327
|
}),
|
|
990
1328
|
" · ",
|
|
@@ -994,13 +1332,13 @@ function DailyVoiceModule() {
|
|
|
994
1332
|
})
|
|
995
1333
|
]
|
|
996
1334
|
}),
|
|
997
|
-
/* @__PURE__ */
|
|
1335
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
998
1336
|
className: "kk-board-header-right",
|
|
999
1337
|
children: [
|
|
1000
|
-
/* @__PURE__ */
|
|
1338
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
1001
1339
|
className: "kk-board-run-filter-group",
|
|
1002
1340
|
children: [
|
|
1003
|
-
/* @__PURE__ */
|
|
1341
|
+
/* @__PURE__ */ jsx2("input", {
|
|
1004
1342
|
type: "text",
|
|
1005
1343
|
className: "kk-board-run-filter-input",
|
|
1006
1344
|
placeholder: "Filter runs...",
|
|
@@ -1008,19 +1346,19 @@ function DailyVoiceModule() {
|
|
|
1008
1346
|
onChange: (e) => setFilterQuery(e.target.value),
|
|
1009
1347
|
"aria-label": "Filter runs"
|
|
1010
1348
|
}),
|
|
1011
|
-
/* @__PURE__ */
|
|
1349
|
+
/* @__PURE__ */ jsxs2("label", {
|
|
1012
1350
|
className: "kk-board-run-selector",
|
|
1013
1351
|
children: [
|
|
1014
1352
|
"Run",
|
|
1015
|
-
/* @__PURE__ */
|
|
1353
|
+
/* @__PURE__ */ jsxs2("select", {
|
|
1016
1354
|
value: selection.runId ?? "",
|
|
1017
1355
|
onChange: (event) => setSelection((state) => ({ ...state, runId: event.target.value || null })),
|
|
1018
1356
|
children: [
|
|
1019
|
-
/* @__PURE__ */
|
|
1357
|
+
/* @__PURE__ */ jsx2("option", {
|
|
1020
1358
|
value: "",
|
|
1021
1359
|
children: rows.length === 0 ? "No runs recorded" : filteredRows.length === 0 ? "No matching runs" : "Select a run"
|
|
1022
1360
|
}),
|
|
1023
|
-
filteredRows.map((row) => /* @__PURE__ */
|
|
1361
|
+
filteredRows.map((row) => /* @__PURE__ */ jsxs2("option", {
|
|
1024
1362
|
value: row.id,
|
|
1025
1363
|
children: [
|
|
1026
1364
|
row.id,
|
|
@@ -1034,13 +1372,13 @@ function DailyVoiceModule() {
|
|
|
1034
1372
|
})
|
|
1035
1373
|
]
|
|
1036
1374
|
}),
|
|
1037
|
-
/* @__PURE__ */
|
|
1375
|
+
/* @__PURE__ */ jsx2("button", {
|
|
1038
1376
|
type: "button",
|
|
1039
1377
|
onClick: () => void loadReader(),
|
|
1040
1378
|
title: "Refresh run data",
|
|
1041
1379
|
children: "↻ Refresh"
|
|
1042
1380
|
}),
|
|
1043
|
-
selection.runId === null ? null : /* @__PURE__ */
|
|
1381
|
+
selection.runId === null ? null : /* @__PURE__ */ jsx2("a", {
|
|
1044
1382
|
href: selectionPath(selection, window.location.search, MODULE_PATH),
|
|
1045
1383
|
className: "kk-btn-action",
|
|
1046
1384
|
title: "Permanent link",
|
|
@@ -1050,53 +1388,58 @@ function DailyVoiceModule() {
|
|
|
1050
1388
|
})
|
|
1051
1389
|
]
|
|
1052
1390
|
}),
|
|
1053
|
-
/* @__PURE__ */
|
|
1391
|
+
/* @__PURE__ */ jsx2("nav", {
|
|
1054
1392
|
className: "kk-board-tabs",
|
|
1055
1393
|
"aria-label": "Daily AI Voice tabs",
|
|
1056
|
-
children: BOARD_TABS.map((candidate) => /* @__PURE__ */
|
|
1394
|
+
children: BOARD_TABS.map((candidate) => /* @__PURE__ */ jsx2("button", {
|
|
1057
1395
|
type: "button",
|
|
1058
1396
|
"aria-current": candidate === tab ? "page" : undefined,
|
|
1059
1397
|
onClick: () => setSelection((state) => ({ ...state, tab: candidate })),
|
|
1060
1398
|
children: TAB_LABELS[candidate]
|
|
1061
1399
|
}, candidate))
|
|
1062
1400
|
}),
|
|
1063
|
-
rows.length === 0 ? /* @__PURE__ */
|
|
1401
|
+
rows.length === 0 ? /* @__PURE__ */ jsxs2("p", {
|
|
1064
1402
|
className: "kk-board-empty",
|
|
1065
1403
|
children: [
|
|
1066
1404
|
"No runs recorded for kk-daily-ai-voice2. Configure the workflow in",
|
|
1067
1405
|
" ",
|
|
1068
|
-
/* @__PURE__ */
|
|
1406
|
+
/* @__PURE__ */ jsx2("a", {
|
|
1069
1407
|
href: "/board/settings/workflows",
|
|
1070
1408
|
children: "Settings → Workflows"
|
|
1071
1409
|
}),
|
|
1072
1410
|
"."
|
|
1073
1411
|
]
|
|
1074
1412
|
}) : null,
|
|
1075
|
-
tab === "summary" ? /* @__PURE__ */
|
|
1413
|
+
tab === "summary" ? /* @__PURE__ */ jsx2(SummaryPanel, {
|
|
1076
1414
|
facts,
|
|
1077
|
-
results
|
|
1415
|
+
results,
|
|
1416
|
+
funnel,
|
|
1417
|
+
artifacts,
|
|
1418
|
+
context,
|
|
1419
|
+
supply,
|
|
1420
|
+
storeOffline
|
|
1078
1421
|
}) : null,
|
|
1079
|
-
tab === "results" ? /* @__PURE__ */
|
|
1422
|
+
tab === "results" ? /* @__PURE__ */ jsx2(ResultsPanel, {
|
|
1080
1423
|
artifacts,
|
|
1081
1424
|
channels: summary?.channels ?? []
|
|
1082
1425
|
}) : null,
|
|
1083
|
-
tab === "progress" ? /* @__PURE__ */
|
|
1426
|
+
tab === "progress" ? /* @__PURE__ */ jsx2(ProgressPanel, {
|
|
1084
1427
|
progress: summary?.progress ?? null
|
|
1085
1428
|
}) : null,
|
|
1086
|
-
tab === "config" ? /* @__PURE__ */
|
|
1429
|
+
tab === "config" ? /* @__PURE__ */ jsx2(ConfigPanel, {
|
|
1087
1430
|
config
|
|
1088
1431
|
}) : null,
|
|
1089
|
-
dedupeDiagnostics([...diagnostics, ...results?.diagnostics ?? []]).map((diagnostic) => /* @__PURE__ */
|
|
1432
|
+
dedupeDiagnostics([...diagnostics, ...results?.diagnostics ?? []]).map((diagnostic) => /* @__PURE__ */ jsx2("p", {
|
|
1090
1433
|
role: "status",
|
|
1091
1434
|
className: "kk-board-diagnostic",
|
|
1092
1435
|
children: diagnosticLine(diagnostic)
|
|
1093
1436
|
}, diagnostic.code)),
|
|
1094
|
-
cursor === null ? null : /* @__PURE__ */
|
|
1437
|
+
cursor === null ? null : /* @__PURE__ */ jsx2("button", {
|
|
1095
1438
|
type: "button",
|
|
1096
1439
|
onClick: () => void loadHistory(),
|
|
1097
1440
|
children: "Load more runs"
|
|
1098
1441
|
}),
|
|
1099
|
-
/* @__PURE__ */
|
|
1442
|
+
/* @__PURE__ */ jsxs2("p", {
|
|
1100
1443
|
className: "kk-board-footnote",
|
|
1101
1444
|
children: [
|
|
1102
1445
|
"Run history every ",
|
|
@@ -1109,44 +1452,52 @@ function DailyVoiceModule() {
|
|
|
1109
1452
|
]
|
|
1110
1453
|
});
|
|
1111
1454
|
}
|
|
1112
|
-
function SummaryPanel({
|
|
1455
|
+
function SummaryPanel({
|
|
1456
|
+
facts,
|
|
1457
|
+
results,
|
|
1458
|
+
funnel,
|
|
1459
|
+
artifacts,
|
|
1460
|
+
context,
|
|
1461
|
+
supply,
|
|
1462
|
+
storeOffline
|
|
1463
|
+
}) {
|
|
1113
1464
|
if (results === null)
|
|
1114
|
-
return /* @__PURE__ */
|
|
1465
|
+
return /* @__PURE__ */ jsx2("p", {
|
|
1115
1466
|
children: "No captured results for the selected run."
|
|
1116
1467
|
});
|
|
1117
1468
|
const summary = dailySummary(results);
|
|
1118
1469
|
const liveChannels = summary.channels.filter((c) => c.state === "live").length;
|
|
1119
|
-
return /* @__PURE__ */
|
|
1470
|
+
return /* @__PURE__ */ jsxs2("div", {
|
|
1120
1471
|
style: { display: "flex", flexDirection: "column", gap: "0.875rem" },
|
|
1121
1472
|
children: [
|
|
1122
|
-
/* @__PURE__ */
|
|
1473
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
1123
1474
|
className: "kk-stat-grid",
|
|
1124
1475
|
children: [
|
|
1125
|
-
/* @__PURE__ */
|
|
1476
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
1126
1477
|
className: "kk-stat-card",
|
|
1127
1478
|
children: [
|
|
1128
|
-
/* @__PURE__ */
|
|
1479
|
+
/* @__PURE__ */ jsx2("span", {
|
|
1129
1480
|
className: "kk-stat-label",
|
|
1130
1481
|
children: "Episode Outcome"
|
|
1131
1482
|
}),
|
|
1132
|
-
/* @__PURE__ */
|
|
1483
|
+
/* @__PURE__ */ jsx2("span", {
|
|
1133
1484
|
className: "kk-stat-value",
|
|
1134
1485
|
children: summary.outcome ?? "—"
|
|
1135
1486
|
}),
|
|
1136
|
-
/* @__PURE__ */
|
|
1487
|
+
/* @__PURE__ */ jsx2("span", {
|
|
1137
1488
|
className: "kk-stat-sub",
|
|
1138
1489
|
children: summary.articleTitle ? summary.articleTitle.slice(0, 32) : "Daily podcast"
|
|
1139
1490
|
})
|
|
1140
1491
|
]
|
|
1141
1492
|
}),
|
|
1142
|
-
/* @__PURE__ */
|
|
1493
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
1143
1494
|
className: "kk-stat-card",
|
|
1144
1495
|
children: [
|
|
1145
|
-
/* @__PURE__ */
|
|
1496
|
+
/* @__PURE__ */ jsx2("span", {
|
|
1146
1497
|
className: "kk-stat-label",
|
|
1147
1498
|
children: "Distribution"
|
|
1148
1499
|
}),
|
|
1149
|
-
/* @__PURE__ */
|
|
1500
|
+
/* @__PURE__ */ jsxs2("span", {
|
|
1150
1501
|
className: "kk-stat-value",
|
|
1151
1502
|
children: [
|
|
1152
1503
|
liveChannels,
|
|
@@ -1154,41 +1505,41 @@ function SummaryPanel({ facts, results }) {
|
|
|
1154
1505
|
summary.channels.length
|
|
1155
1506
|
]
|
|
1156
1507
|
}),
|
|
1157
|
-
/* @__PURE__ */
|
|
1508
|
+
/* @__PURE__ */ jsx2("span", {
|
|
1158
1509
|
className: "kk-stat-sub",
|
|
1159
1510
|
children: "Channels published live"
|
|
1160
1511
|
})
|
|
1161
1512
|
]
|
|
1162
1513
|
}),
|
|
1163
|
-
/* @__PURE__ */
|
|
1514
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
1164
1515
|
className: "kk-stat-card",
|
|
1165
1516
|
children: [
|
|
1166
|
-
/* @__PURE__ */
|
|
1517
|
+
/* @__PURE__ */ jsx2("span", {
|
|
1167
1518
|
className: "kk-stat-label",
|
|
1168
1519
|
children: "Quality Score"
|
|
1169
1520
|
}),
|
|
1170
|
-
/* @__PURE__ */
|
|
1521
|
+
/* @__PURE__ */ jsx2("span", {
|
|
1171
1522
|
className: "kk-stat-value",
|
|
1172
1523
|
children: summary.quality?.overallScore ?? "—"
|
|
1173
1524
|
}),
|
|
1174
|
-
/* @__PURE__ */
|
|
1525
|
+
/* @__PURE__ */ jsx2("span", {
|
|
1175
1526
|
className: "kk-stat-sub",
|
|
1176
1527
|
children: summary.quality?.passed ? "Passed QC standard" : "Under evaluation"
|
|
1177
1528
|
})
|
|
1178
1529
|
]
|
|
1179
1530
|
}),
|
|
1180
|
-
/* @__PURE__ */
|
|
1531
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
1181
1532
|
className: "kk-stat-card",
|
|
1182
1533
|
children: [
|
|
1183
|
-
/* @__PURE__ */
|
|
1534
|
+
/* @__PURE__ */ jsx2("span", {
|
|
1184
1535
|
className: "kk-stat-label",
|
|
1185
1536
|
children: "Safety Verdict"
|
|
1186
1537
|
}),
|
|
1187
|
-
/* @__PURE__ */
|
|
1538
|
+
/* @__PURE__ */ jsx2("span", {
|
|
1188
1539
|
className: "kk-stat-value",
|
|
1189
1540
|
children: summary.safety?.verdict ?? "—"
|
|
1190
1541
|
}),
|
|
1191
|
-
/* @__PURE__ */
|
|
1542
|
+
/* @__PURE__ */ jsxs2("span", {
|
|
1192
1543
|
className: "kk-stat-sub",
|
|
1193
1544
|
children: [
|
|
1194
1545
|
"Confidence: ",
|
|
@@ -1199,18 +1550,18 @@ function SummaryPanel({ facts, results }) {
|
|
|
1199
1550
|
})
|
|
1200
1551
|
]
|
|
1201
1552
|
}),
|
|
1202
|
-
/* @__PURE__ */
|
|
1553
|
+
/* @__PURE__ */ jsx2("dl", {
|
|
1203
1554
|
className: "kk-board-facts",
|
|
1204
|
-
children: facts.map((fact) => /* @__PURE__ */
|
|
1555
|
+
children: facts.map((fact) => /* @__PURE__ */ jsxs2("div", {
|
|
1205
1556
|
children: [
|
|
1206
|
-
/* @__PURE__ */
|
|
1557
|
+
/* @__PURE__ */ jsx2("dt", {
|
|
1207
1558
|
children: fact.label
|
|
1208
1559
|
}),
|
|
1209
|
-
/* @__PURE__ */
|
|
1560
|
+
/* @__PURE__ */ jsxs2("dd", {
|
|
1210
1561
|
children: [
|
|
1211
1562
|
fact.value,
|
|
1212
1563
|
" ",
|
|
1213
|
-
/* @__PURE__ */
|
|
1564
|
+
/* @__PURE__ */ jsx2("span", {
|
|
1214
1565
|
className: "kk-board-state",
|
|
1215
1566
|
children: fact.availability
|
|
1216
1567
|
})
|
|
@@ -1218,25 +1569,308 @@ function SummaryPanel({ facts, results }) {
|
|
|
1218
1569
|
})
|
|
1219
1570
|
]
|
|
1220
1571
|
}, fact.label))
|
|
1572
|
+
}),
|
|
1573
|
+
/* @__PURE__ */ jsx2(FunnelPanel, {
|
|
1574
|
+
funnel,
|
|
1575
|
+
artifacts
|
|
1576
|
+
}),
|
|
1577
|
+
/* @__PURE__ */ jsx2(SupplyPanel, {
|
|
1578
|
+
context,
|
|
1579
|
+
supply,
|
|
1580
|
+
storeOffline
|
|
1581
|
+
})
|
|
1582
|
+
]
|
|
1583
|
+
});
|
|
1584
|
+
}
|
|
1585
|
+
function funnelCount(value) {
|
|
1586
|
+
return value === null ? "unavailable" : String(value);
|
|
1587
|
+
}
|
|
1588
|
+
function funnelMinutes(value) {
|
|
1589
|
+
return value === null ? "unavailable" : `${value.toFixed(1)} min`;
|
|
1590
|
+
}
|
|
1591
|
+
function EvidenceChip({
|
|
1592
|
+
field,
|
|
1593
|
+
funnel,
|
|
1594
|
+
artifacts
|
|
1595
|
+
}) {
|
|
1596
|
+
const evidenceId = funnel.evidence[field];
|
|
1597
|
+
if (evidenceId === undefined)
|
|
1598
|
+
return /* @__PURE__ */ jsx2("span", {
|
|
1599
|
+
className: "kk-board-state",
|
|
1600
|
+
children: "no evidence"
|
|
1601
|
+
});
|
|
1602
|
+
if (evidenceId === "captured-settings")
|
|
1603
|
+
return /* @__PURE__ */ jsx2("code", {
|
|
1604
|
+
children: "captured-settings"
|
|
1605
|
+
});
|
|
1606
|
+
const artifact = artifacts.find((candidate) => candidate.id === evidenceId);
|
|
1607
|
+
return artifact === undefined || artifact.href === null ? /* @__PURE__ */ jsxs2("code", {
|
|
1608
|
+
children: [
|
|
1609
|
+
evidenceId,
|
|
1610
|
+
" (",
|
|
1611
|
+
artifact?.state ?? "missing",
|
|
1612
|
+
")"
|
|
1613
|
+
]
|
|
1614
|
+
}) : /* @__PURE__ */ jsx2("a", {
|
|
1615
|
+
href: artifact.href,
|
|
1616
|
+
children: /* @__PURE__ */ jsx2("code", {
|
|
1617
|
+
children: evidenceId
|
|
1618
|
+
})
|
|
1619
|
+
});
|
|
1620
|
+
}
|
|
1621
|
+
function FunnelPanel({ funnel, artifacts }) {
|
|
1622
|
+
const rows = [
|
|
1623
|
+
{ label: "1 · Episode pool", value: funnelCount(funnel.poolCount), field: "poolCount" },
|
|
1624
|
+
{ label: "2 · Annotated", value: funnelCount(funnel.annotatedCount), field: "annotatedCount" },
|
|
1625
|
+
{ label: "3 · Topic filter kept", value: funnelCount(funnel.topicKeptCount), field: "topicKeptCount" },
|
|
1626
|
+
{ label: "4 · QC rejected", value: funnelCount(funnel.qcRejectedCount), field: "qcRejectedCount" },
|
|
1627
|
+
{
|
|
1628
|
+
label: "5 · Post-dedup survivors",
|
|
1629
|
+
value: funnel.dedupKeptCount === null && (funnel.gate === "episode-duration" || funnel.gate === "script" || funnel.gate === "qc-floor") ? "unknown — cleared by the refusal" : funnel.dedupKeptCount === null && funnel.plannedCount !== null ? "unknown — plan recorded" : funnelCount(funnel.dedupKeptCount),
|
|
1630
|
+
field: "dedupKeptCount"
|
|
1631
|
+
},
|
|
1632
|
+
{ label: "6 · Episode plan", value: funnelCount(funnel.plannedCount), field: "plannedCount" }
|
|
1633
|
+
];
|
|
1634
|
+
return /* @__PURE__ */ jsxs2("section", {
|
|
1635
|
+
className: "kk-card kk-daily-funnel",
|
|
1636
|
+
children: [
|
|
1637
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
1638
|
+
className: "kk-card-header",
|
|
1639
|
+
children: [
|
|
1640
|
+
/* @__PURE__ */ jsx2("h2", {
|
|
1641
|
+
children: "Episode funnel"
|
|
1642
|
+
}),
|
|
1643
|
+
/* @__PURE__ */ jsx2("span", {
|
|
1644
|
+
className: "kk-stat-sub",
|
|
1645
|
+
children: "artifact-backed by this run"
|
|
1646
|
+
})
|
|
1647
|
+
]
|
|
1648
|
+
}),
|
|
1649
|
+
/* @__PURE__ */ jsxs2("dl", {
|
|
1650
|
+
children: [
|
|
1651
|
+
rows.map((row) => /* @__PURE__ */ jsxs2("div", {
|
|
1652
|
+
children: [
|
|
1653
|
+
/* @__PURE__ */ jsx2("dt", {
|
|
1654
|
+
children: row.label
|
|
1655
|
+
}),
|
|
1656
|
+
/* @__PURE__ */ jsxs2("dd", {
|
|
1657
|
+
children: [
|
|
1658
|
+
row.value,
|
|
1659
|
+
" · evidence",
|
|
1660
|
+
" ",
|
|
1661
|
+
/* @__PURE__ */ jsx2(EvidenceChip, {
|
|
1662
|
+
field: row.field,
|
|
1663
|
+
funnel,
|
|
1664
|
+
artifacts
|
|
1665
|
+
})
|
|
1666
|
+
]
|
|
1667
|
+
})
|
|
1668
|
+
]
|
|
1669
|
+
}, row.label)),
|
|
1670
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
1671
|
+
children: [
|
|
1672
|
+
/* @__PURE__ */ jsx2("dt", {
|
|
1673
|
+
children: "Duration ladder"
|
|
1674
|
+
}),
|
|
1675
|
+
/* @__PURE__ */ jsxs2("dd", {
|
|
1676
|
+
children: [
|
|
1677
|
+
"measured ",
|
|
1678
|
+
funnelMinutes(funnel.measuredMinutes),
|
|
1679
|
+
" · estimated",
|
|
1680
|
+
" ",
|
|
1681
|
+
funnelMinutes(funnel.estimatedMinutes),
|
|
1682
|
+
" · floor ",
|
|
1683
|
+
funnelMinutes(funnel.minMinutes),
|
|
1684
|
+
" · ceiling",
|
|
1685
|
+
" ",
|
|
1686
|
+
funnelMinutes(funnel.maxMinutes)
|
|
1687
|
+
]
|
|
1688
|
+
})
|
|
1689
|
+
]
|
|
1690
|
+
}, "minutes"),
|
|
1691
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
1692
|
+
children: [
|
|
1693
|
+
/* @__PURE__ */ jsx2("dt", {
|
|
1694
|
+
children: "No-content gate"
|
|
1695
|
+
}),
|
|
1696
|
+
/* @__PURE__ */ jsxs2("dd", {
|
|
1697
|
+
children: [
|
|
1698
|
+
funnel.gateName,
|
|
1699
|
+
" · evidence ",
|
|
1700
|
+
/* @__PURE__ */ jsx2(EvidenceChip, {
|
|
1701
|
+
field: "gate",
|
|
1702
|
+
funnel,
|
|
1703
|
+
artifacts
|
|
1704
|
+
})
|
|
1705
|
+
]
|
|
1706
|
+
})
|
|
1707
|
+
]
|
|
1708
|
+
}, "gate")
|
|
1709
|
+
]
|
|
1710
|
+
}),
|
|
1711
|
+
funnel.exclusions.length === 0 ? null : /* @__PURE__ */ jsxs2("div", {
|
|
1712
|
+
children: [
|
|
1713
|
+
/* @__PURE__ */ jsx2("h3", {
|
|
1714
|
+
children: "Topic-filter exclusions"
|
|
1715
|
+
}),
|
|
1716
|
+
/* @__PURE__ */ jsx2("ul", {
|
|
1717
|
+
className: "kk-board-channels",
|
|
1718
|
+
children: funnel.exclusions.map((exclusion) => /* @__PURE__ */ jsxs2("li", {
|
|
1719
|
+
children: [
|
|
1720
|
+
/* @__PURE__ */ jsx2("strong", {
|
|
1721
|
+
children: exclusion.rule
|
|
1722
|
+
}),
|
|
1723
|
+
exclusion.matched === "" ? null : ` — matched “${exclusion.matched}”`
|
|
1724
|
+
]
|
|
1725
|
+
}, `${exclusion.rule}::${exclusion.matched}`))
|
|
1726
|
+
})
|
|
1727
|
+
]
|
|
1728
|
+
}),
|
|
1729
|
+
funnel.diagnostics.length === 0 ? null : /* @__PURE__ */ jsx2("ul", {
|
|
1730
|
+
children: funnel.diagnostics.map((diagnostic) => /* @__PURE__ */ jsxs2("li", {
|
|
1731
|
+
role: "status",
|
|
1732
|
+
className: "kk-board-diagnostic",
|
|
1733
|
+
children: [
|
|
1734
|
+
diagnostic.code,
|
|
1735
|
+
": ",
|
|
1736
|
+
diagnostic.message
|
|
1737
|
+
]
|
|
1738
|
+
}, diagnostic.code))
|
|
1739
|
+
})
|
|
1740
|
+
]
|
|
1741
|
+
});
|
|
1742
|
+
}
|
|
1743
|
+
function SupplyPanel({
|
|
1744
|
+
context,
|
|
1745
|
+
supply,
|
|
1746
|
+
storeOffline
|
|
1747
|
+
}) {
|
|
1748
|
+
return /* @__PURE__ */ jsxs2("section", {
|
|
1749
|
+
className: "kk-card kk-daily-supply",
|
|
1750
|
+
children: [
|
|
1751
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
1752
|
+
className: "kk-card-header",
|
|
1753
|
+
children: [
|
|
1754
|
+
/* @__PURE__ */ jsx2("h2", {
|
|
1755
|
+
children: "Supply context (configured)"
|
|
1756
|
+
}),
|
|
1757
|
+
/* @__PURE__ */ jsx2("span", {
|
|
1758
|
+
className: "kk-stat-sub",
|
|
1759
|
+
children: "read from the kk-collect store"
|
|
1760
|
+
})
|
|
1761
|
+
]
|
|
1762
|
+
}),
|
|
1763
|
+
context === null ? /* @__PURE__ */ jsx2("p", {
|
|
1764
|
+
children: "The configured supply interval is unknown — no captured window setting or run start was recorded, so no store query was issued."
|
|
1765
|
+
}) : /* @__PURE__ */ jsxs2("p", {
|
|
1766
|
+
children: [
|
|
1767
|
+
"Window ",
|
|
1768
|
+
/* @__PURE__ */ jsx2("code", {
|
|
1769
|
+
children: context.fromLabel
|
|
1770
|
+
}),
|
|
1771
|
+
" → ",
|
|
1772
|
+
/* @__PURE__ */ jsx2("code", {
|
|
1773
|
+
children: context.untilLabel
|
|
1774
|
+
}),
|
|
1775
|
+
supply === null ? "" : ` · time zone ${supply.timeZone}`,
|
|
1776
|
+
" — configured context; the effective extraction window (ladder bounds) is unknown, not persisted."
|
|
1777
|
+
]
|
|
1778
|
+
}),
|
|
1779
|
+
storeOffline ? /* @__PURE__ */ jsx2("p", {
|
|
1780
|
+
children: "The store reader is offline; supply counts are unavailable."
|
|
1781
|
+
}) : null,
|
|
1782
|
+
supply !== null && supply.availability === "unavailable" ? /* @__PURE__ */ jsx2("p", {
|
|
1783
|
+
children: "The store could not be read for this window; no counts are shown."
|
|
1784
|
+
}) : null,
|
|
1785
|
+
supply !== null && supply.availability === "unavailable" && supply.diagnostics.length > 0 ? /* @__PURE__ */ jsx2("ul", {
|
|
1786
|
+
children: supply.diagnostics.map((diagnostic) => /* @__PURE__ */ jsxs2("li", {
|
|
1787
|
+
className: "kk-board-diagnostic",
|
|
1788
|
+
children: [
|
|
1789
|
+
diagnostic.code,
|
|
1790
|
+
": ",
|
|
1791
|
+
diagnostic.message
|
|
1792
|
+
]
|
|
1793
|
+
}, diagnostic.code))
|
|
1794
|
+
}) : null,
|
|
1795
|
+
supply !== null && supply.availability === "available" ? /* @__PURE__ */ jsxs2("div", {
|
|
1796
|
+
className: "kk-summary-grids",
|
|
1797
|
+
children: [
|
|
1798
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
1799
|
+
className: "kk-card",
|
|
1800
|
+
children: [
|
|
1801
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
1802
|
+
className: "kk-card-header",
|
|
1803
|
+
children: [
|
|
1804
|
+
/* @__PURE__ */ jsx2("h2", {
|
|
1805
|
+
children: "New items by day and source"
|
|
1806
|
+
}),
|
|
1807
|
+
/* @__PURE__ */ jsxs2("span", {
|
|
1808
|
+
className: "kk-stat-sub",
|
|
1809
|
+
children: [
|
|
1810
|
+
supply.sources.length,
|
|
1811
|
+
" sources"
|
|
1812
|
+
]
|
|
1813
|
+
})
|
|
1814
|
+
]
|
|
1815
|
+
}),
|
|
1816
|
+
/* @__PURE__ */ jsx2("div", {
|
|
1817
|
+
className: "kk-table-container",
|
|
1818
|
+
children: /* @__PURE__ */ jsx2(ChannelYieldTable, {
|
|
1819
|
+
data: supply
|
|
1820
|
+
})
|
|
1821
|
+
})
|
|
1822
|
+
]
|
|
1823
|
+
}),
|
|
1824
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
1825
|
+
className: "kk-card",
|
|
1826
|
+
children: [
|
|
1827
|
+
/* @__PURE__ */ jsxs2("div", {
|
|
1828
|
+
className: "kk-card-header",
|
|
1829
|
+
children: [
|
|
1830
|
+
/* @__PURE__ */ jsx2("h2", {
|
|
1831
|
+
children: "Collection ticks and plugin contributions"
|
|
1832
|
+
}),
|
|
1833
|
+
/* @__PURE__ */ jsxs2("span", {
|
|
1834
|
+
className: "kk-stat-sub",
|
|
1835
|
+
children: [
|
|
1836
|
+
supply.plugins.length,
|
|
1837
|
+
" plugins"
|
|
1838
|
+
]
|
|
1839
|
+
})
|
|
1840
|
+
]
|
|
1841
|
+
}),
|
|
1842
|
+
/* @__PURE__ */ jsx2("div", {
|
|
1843
|
+
className: "kk-table-container",
|
|
1844
|
+
children: /* @__PURE__ */ jsx2(PluginRunTable, {
|
|
1845
|
+
data: supply
|
|
1846
|
+
})
|
|
1847
|
+
})
|
|
1848
|
+
]
|
|
1849
|
+
})
|
|
1850
|
+
]
|
|
1851
|
+
}) : null,
|
|
1852
|
+
/* @__PURE__ */ jsx2("p", {
|
|
1853
|
+
className: "kk-board-footnote",
|
|
1854
|
+
children: "A source absent from this window recorded 0 contributions; its health is unknown. The episode funnel above stays artifact-backed — supply here is context, not the run’s consumption record."
|
|
1221
1855
|
})
|
|
1222
1856
|
]
|
|
1223
1857
|
});
|
|
1224
1858
|
}
|
|
1225
1859
|
function ChannelList({ channels }) {
|
|
1226
1860
|
if (channels.length === 0)
|
|
1227
|
-
return /* @__PURE__ */
|
|
1861
|
+
return /* @__PURE__ */ jsx2("p", {
|
|
1228
1862
|
children: "No channel outcomes recorded for the selected run."
|
|
1229
1863
|
});
|
|
1230
|
-
return /* @__PURE__ */
|
|
1864
|
+
return /* @__PURE__ */ jsx2("ul", {
|
|
1231
1865
|
className: "kk-board-channels",
|
|
1232
|
-
children: channels.map((channel) => /* @__PURE__ */
|
|
1866
|
+
children: channels.map((channel) => /* @__PURE__ */ jsxs2("li", {
|
|
1233
1867
|
children: [
|
|
1234
|
-
/* @__PURE__ */
|
|
1868
|
+
/* @__PURE__ */ jsx2("strong", {
|
|
1235
1869
|
children: channel.label
|
|
1236
1870
|
}),
|
|
1237
1871
|
" — ",
|
|
1238
1872
|
channel.state,
|
|
1239
|
-
channel.detail === null ? null : /* @__PURE__ */
|
|
1873
|
+
channel.detail === null ? null : /* @__PURE__ */ jsxs2("span", {
|
|
1240
1874
|
className: "kk-board-state",
|
|
1241
1875
|
children: [
|
|
1242
1876
|
" (",
|
|
@@ -1244,10 +1878,10 @@ function ChannelList({ channels }) {
|
|
|
1244
1878
|
")"
|
|
1245
1879
|
]
|
|
1246
1880
|
}),
|
|
1247
|
-
channel.url === null ? null : /* @__PURE__ */
|
|
1881
|
+
channel.url === null ? null : /* @__PURE__ */ jsxs2(Fragment, {
|
|
1248
1882
|
children: [
|
|
1249
1883
|
" ",
|
|
1250
|
-
/* @__PURE__ */
|
|
1884
|
+
/* @__PURE__ */ jsx2("a", {
|
|
1251
1885
|
href: channel.url,
|
|
1252
1886
|
rel: "noreferrer",
|
|
1253
1887
|
children: "open"
|
|
@@ -1263,30 +1897,30 @@ function ResultsPanel({
|
|
|
1263
1897
|
channels
|
|
1264
1898
|
}) {
|
|
1265
1899
|
if (artifacts.length === 0)
|
|
1266
|
-
return /* @__PURE__ */
|
|
1900
|
+
return /* @__PURE__ */ jsx2("p", {
|
|
1267
1901
|
children: "No artifact evidence for the selected run."
|
|
1268
1902
|
});
|
|
1269
1903
|
const media = artifacts.filter((artifact) => artifact.kind === "image" || artifact.kind === "audio");
|
|
1270
1904
|
const files = artifacts.filter((artifact) => artifact.kind !== "image" && artifact.kind !== "audio");
|
|
1271
|
-
return /* @__PURE__ */
|
|
1905
|
+
return /* @__PURE__ */ jsxs2("div", {
|
|
1272
1906
|
className: "kk-board-results",
|
|
1273
1907
|
children: [
|
|
1274
|
-
media.map((artifact) => artifact.href === null ? /* @__PURE__ */
|
|
1908
|
+
media.map((artifact) => artifact.href === null ? /* @__PURE__ */ jsxs2("p", {
|
|
1275
1909
|
children: [
|
|
1276
1910
|
artifact.label,
|
|
1277
1911
|
" — ",
|
|
1278
1912
|
artifact.state
|
|
1279
1913
|
]
|
|
1280
|
-
}, artifact.id) : artifact.kind === "audio" ? /* @__PURE__ */
|
|
1914
|
+
}, artifact.id) : artifact.kind === "audio" ? /* @__PURE__ */ jsxs2("p", {
|
|
1281
1915
|
children: [
|
|
1282
|
-
/* @__PURE__ */
|
|
1916
|
+
/* @__PURE__ */ jsx2("audio", {
|
|
1283
1917
|
controls: true,
|
|
1284
1918
|
src: artifact.href,
|
|
1285
|
-
children: /* @__PURE__ */
|
|
1919
|
+
children: /* @__PURE__ */ jsx2("track", {
|
|
1286
1920
|
kind: "captions"
|
|
1287
1921
|
})
|
|
1288
1922
|
}),
|
|
1289
|
-
/* @__PURE__ */
|
|
1923
|
+
/* @__PURE__ */ jsxs2("a", {
|
|
1290
1924
|
href: artifact.href,
|
|
1291
1925
|
download: true,
|
|
1292
1926
|
children: [
|
|
@@ -1298,9 +1932,9 @@ function ResultsPanel({
|
|
|
1298
1932
|
"— ",
|
|
1299
1933
|
artifact.state
|
|
1300
1934
|
]
|
|
1301
|
-
}, artifact.id) : /* @__PURE__ */
|
|
1935
|
+
}, artifact.id) : /* @__PURE__ */ jsxs2("p", {
|
|
1302
1936
|
children: [
|
|
1303
|
-
/* @__PURE__ */
|
|
1937
|
+
/* @__PURE__ */ jsx2("img", {
|
|
1304
1938
|
src: artifact.href,
|
|
1305
1939
|
alt: artifact.label
|
|
1306
1940
|
}),
|
|
@@ -1310,16 +1944,16 @@ function ResultsPanel({
|
|
|
1310
1944
|
artifact.state
|
|
1311
1945
|
]
|
|
1312
1946
|
}, artifact.id)),
|
|
1313
|
-
/* @__PURE__ */
|
|
1947
|
+
/* @__PURE__ */ jsx2("ul", {
|
|
1314
1948
|
className: "kk-board-artifacts",
|
|
1315
|
-
children: files.map((artifact) => /* @__PURE__ */
|
|
1316
|
-
children: artifact.href === null ? /* @__PURE__ */
|
|
1949
|
+
children: files.map((artifact) => /* @__PURE__ */ jsx2("li", {
|
|
1950
|
+
children: artifact.href === null ? /* @__PURE__ */ jsxs2("span", {
|
|
1317
1951
|
children: [
|
|
1318
1952
|
artifact.label,
|
|
1319
1953
|
" — ",
|
|
1320
1954
|
artifact.state
|
|
1321
1955
|
]
|
|
1322
|
-
}) : /* @__PURE__ */
|
|
1956
|
+
}) : /* @__PURE__ */ jsxs2("a", {
|
|
1323
1957
|
href: artifact.href,
|
|
1324
1958
|
children: [
|
|
1325
1959
|
artifact.label,
|
|
@@ -1329,7 +1963,7 @@ function ResultsPanel({
|
|
|
1329
1963
|
})
|
|
1330
1964
|
}, artifact.id))
|
|
1331
1965
|
}),
|
|
1332
|
-
/* @__PURE__ */
|
|
1966
|
+
/* @__PURE__ */ jsx2(ChannelList, {
|
|
1333
1967
|
channels
|
|
1334
1968
|
})
|
|
1335
1969
|
]
|
|
@@ -1337,24 +1971,24 @@ function ResultsPanel({
|
|
|
1337
1971
|
}
|
|
1338
1972
|
function ProgressPanel({ progress }) {
|
|
1339
1973
|
if (progress === null || progress.nodes.length === 0) {
|
|
1340
|
-
return /* @__PURE__ */
|
|
1974
|
+
return /* @__PURE__ */ jsx2("p", {
|
|
1341
1975
|
children: "Recorded progress is unavailable for the selected run."
|
|
1342
1976
|
});
|
|
1343
1977
|
}
|
|
1344
|
-
return /* @__PURE__ */
|
|
1978
|
+
return /* @__PURE__ */ jsxs2("div", {
|
|
1345
1979
|
className: "kk-board-progress",
|
|
1346
1980
|
children: [
|
|
1347
|
-
/* @__PURE__ */
|
|
1348
|
-
children: progress.nodes.map((node) => /* @__PURE__ */
|
|
1981
|
+
/* @__PURE__ */ jsx2("ul", {
|
|
1982
|
+
children: progress.nodes.map((node) => /* @__PURE__ */ jsxs2("li", {
|
|
1349
1983
|
children: [
|
|
1350
|
-
/* @__PURE__ */
|
|
1984
|
+
/* @__PURE__ */ jsx2("strong", {
|
|
1351
1985
|
children: node.id
|
|
1352
1986
|
}),
|
|
1353
1987
|
" — ",
|
|
1354
1988
|
node.status,
|
|
1355
1989
|
" · ",
|
|
1356
1990
|
node.timing,
|
|
1357
|
-
node.attempts > 1 ? /* @__PURE__ */
|
|
1991
|
+
node.attempts > 1 ? /* @__PURE__ */ jsxs2("span", {
|
|
1358
1992
|
className: "kk-board-state",
|
|
1359
1993
|
children: [
|
|
1360
1994
|
" ",
|
|
@@ -1365,30 +1999,30 @@ function ProgressPanel({ progress }) {
|
|
|
1365
1999
|
]
|
|
1366
2000
|
}, node.id))
|
|
1367
2001
|
}),
|
|
1368
|
-
progress.edgesKnown && progress.edges !== null ? /* @__PURE__ */
|
|
2002
|
+
progress.edgesKnown && progress.edges !== null ? /* @__PURE__ */ jsx2("ul", {
|
|
1369
2003
|
className: "kk-board-edges",
|
|
1370
|
-
children: progress.edges.map((edge) => /* @__PURE__ */
|
|
2004
|
+
children: progress.edges.map((edge) => /* @__PURE__ */ jsxs2("li", {
|
|
1371
2005
|
children: [
|
|
1372
2006
|
edge.from,
|
|
1373
2007
|
" → ",
|
|
1374
2008
|
edge.to
|
|
1375
2009
|
]
|
|
1376
2010
|
}, `${edge.from}->${edge.to}`))
|
|
1377
|
-
}) : /* @__PURE__ */
|
|
2011
|
+
}) : /* @__PURE__ */ jsxs2("p", {
|
|
1378
2012
|
children: [
|
|
1379
2013
|
"Dependency edges are unknown — no digest-verified topology was captured. See",
|
|
1380
2014
|
" ",
|
|
1381
|
-
/* @__PURE__ */
|
|
2015
|
+
/* @__PURE__ */ jsx2("a", {
|
|
1382
2016
|
href: "/board/settings/workflows",
|
|
1383
2017
|
children: "Settings → Workflows"
|
|
1384
2018
|
}),
|
|
1385
2019
|
" for the current graph."
|
|
1386
2020
|
]
|
|
1387
2021
|
}),
|
|
1388
|
-
progress.childRunId === null ? null : /* @__PURE__ */
|
|
2022
|
+
progress.childRunId === null ? null : /* @__PURE__ */ jsxs2("p", {
|
|
1389
2023
|
children: [
|
|
1390
2024
|
"Nested safety run: ",
|
|
1391
|
-
/* @__PURE__ */
|
|
2025
|
+
/* @__PURE__ */ jsx2("code", {
|
|
1392
2026
|
children: progress.childRunId
|
|
1393
2027
|
})
|
|
1394
2028
|
]
|
|
@@ -1398,44 +2032,44 @@ function ProgressPanel({ progress }) {
|
|
|
1398
2032
|
}
|
|
1399
2033
|
function ConfigPanel({ config }) {
|
|
1400
2034
|
if (config === null)
|
|
1401
|
-
return /* @__PURE__ */
|
|
2035
|
+
return /* @__PURE__ */ jsx2("p", {
|
|
1402
2036
|
children: "No captured configuration for the selected run."
|
|
1403
2037
|
});
|
|
1404
2038
|
const entries = Object.entries(config.settings);
|
|
1405
|
-
return /* @__PURE__ */
|
|
2039
|
+
return /* @__PURE__ */ jsxs2("div", {
|
|
1406
2040
|
className: "kk-board-config",
|
|
1407
2041
|
children: [
|
|
1408
|
-
/* @__PURE__ */
|
|
2042
|
+
/* @__PURE__ */ jsxs2("p", {
|
|
1409
2043
|
children: [
|
|
1410
2044
|
"Captured ",
|
|
1411
2045
|
formatTimestamp(config.capturedAt)
|
|
1412
2046
|
]
|
|
1413
2047
|
}),
|
|
1414
|
-
entries.length === 0 ? /* @__PURE__ */
|
|
2048
|
+
entries.length === 0 ? /* @__PURE__ */ jsx2("p", {
|
|
1415
2049
|
children: "Recorded configuration unavailable for this run."
|
|
1416
2050
|
}) : null,
|
|
1417
|
-
/* @__PURE__ */
|
|
1418
|
-
children: entries.map(([key, value]) => /* @__PURE__ */
|
|
2051
|
+
/* @__PURE__ */ jsx2("dl", {
|
|
2052
|
+
children: entries.map(([key, value]) => /* @__PURE__ */ jsxs2("div", {
|
|
1419
2053
|
children: [
|
|
1420
|
-
/* @__PURE__ */
|
|
2054
|
+
/* @__PURE__ */ jsx2("dt", {
|
|
1421
2055
|
children: key
|
|
1422
2056
|
}),
|
|
1423
|
-
/* @__PURE__ */
|
|
2057
|
+
/* @__PURE__ */ jsx2("dd", {
|
|
1424
2058
|
children: value
|
|
1425
2059
|
})
|
|
1426
2060
|
]
|
|
1427
2061
|
}, key))
|
|
1428
2062
|
}),
|
|
1429
|
-
config.unavailableKeys.length === 0 ? null : /* @__PURE__ */
|
|
2063
|
+
config.unavailableKeys.length === 0 ? null : /* @__PURE__ */ jsxs2("p", {
|
|
1430
2064
|
children: [
|
|
1431
2065
|
"Uncaptured keys: ",
|
|
1432
2066
|
config.unavailableKeys.join(", ")
|
|
1433
2067
|
]
|
|
1434
2068
|
}),
|
|
1435
|
-
/* @__PURE__ */
|
|
2069
|
+
/* @__PURE__ */ jsxs2("p", {
|
|
1436
2070
|
children: [
|
|
1437
2071
|
"Current definitions and defaults live in ",
|
|
1438
|
-
/* @__PURE__ */
|
|
2072
|
+
/* @__PURE__ */ jsx2("a", {
|
|
1439
2073
|
href: "/board/settings/workflows",
|
|
1440
2074
|
children: "Settings → Workflows"
|
|
1441
2075
|
}),
|