@vue-skuilder/db 0.2.15 → 0.2.17
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/core/index.d.cts +48 -1
- package/dist/core/index.d.ts +48 -1
- package/dist/core/index.js +112 -6
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +109 -6
- package/dist/core/index.mjs.map +1 -1
- package/dist/impl/couch/index.js +106 -6
- package/dist/impl/couch/index.js.map +1 -1
- package/dist/impl/couch/index.mjs +106 -6
- package/dist/impl/couch/index.mjs.map +1 -1
- package/dist/impl/static/index.js +106 -6
- package/dist/impl/static/index.js.map +1 -1
- package/dist/impl/static/index.mjs +106 -6
- package/dist/impl/static/index.mjs.map +1 -1
- package/dist/index.d.cts +5 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.js +175 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +172 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/core/navigators/StrategyPressureDebugger.ts +76 -0
- package/src/core/navigators/generators/prescribed.ts +122 -7
- package/src/core/navigators/index.ts +12 -0
- package/src/study/SessionController.ts +7 -1
- package/src/study/SessionDebugger.ts +2 -0
- package/src/study/SessionOverlay.ts +113 -0
- package/src/study/services/CardHydrationService.ts +9 -1
|
@@ -1446,6 +1446,30 @@ var init_SrsDebugger = __esm({
|
|
|
1446
1446
|
}
|
|
1447
1447
|
});
|
|
1448
1448
|
|
|
1449
|
+
// src/core/navigators/StrategyPressureDebugger.ts
|
|
1450
|
+
var StrategyPressureDebugger_exports = {};
|
|
1451
|
+
__export(StrategyPressureDebugger_exports, {
|
|
1452
|
+
captureStrategyPressure: () => captureStrategyPressure,
|
|
1453
|
+
clearStrategyPressureDebug: () => clearStrategyPressureDebug,
|
|
1454
|
+
getStrategyPressureDebug: () => getStrategyPressureDebug
|
|
1455
|
+
});
|
|
1456
|
+
function captureStrategyPressure(snapshot) {
|
|
1457
|
+
snapshots2.set(`${snapshot.source}:${snapshot.courseId}`, snapshot);
|
|
1458
|
+
}
|
|
1459
|
+
function getStrategyPressureDebug() {
|
|
1460
|
+
return [...snapshots2.values()].sort((a, b) => b.timestamp - a.timestamp);
|
|
1461
|
+
}
|
|
1462
|
+
function clearStrategyPressureDebug() {
|
|
1463
|
+
snapshots2.clear();
|
|
1464
|
+
}
|
|
1465
|
+
var snapshots2;
|
|
1466
|
+
var init_StrategyPressureDebugger = __esm({
|
|
1467
|
+
"src/core/navigators/StrategyPressureDebugger.ts"() {
|
|
1468
|
+
"use strict";
|
|
1469
|
+
snapshots2 = /* @__PURE__ */ new Map();
|
|
1470
|
+
}
|
|
1471
|
+
});
|
|
1472
|
+
|
|
1449
1473
|
// src/core/navigators/generators/CompositeGenerator.ts
|
|
1450
1474
|
var CompositeGenerator_exports = {};
|
|
1451
1475
|
__export(CompositeGenerator_exports, {
|
|
@@ -1810,6 +1834,13 @@ function shuffleInPlace(arr) {
|
|
|
1810
1834
|
[arr[i], arr[j]] = [arr[j], arr[i]];
|
|
1811
1835
|
}
|
|
1812
1836
|
}
|
|
1837
|
+
function formatAge(ms) {
|
|
1838
|
+
const minutes = Math.max(0, Math.round(ms / 6e4));
|
|
1839
|
+
if (minutes < 60) return `${minutes}m`;
|
|
1840
|
+
const hours = Math.round(minutes / 60);
|
|
1841
|
+
if (hours < 24) return `${hours}h`;
|
|
1842
|
+
return `${Math.round(hours / 24)}d`;
|
|
1843
|
+
}
|
|
1813
1844
|
function pickTopByScore(cards, limit) {
|
|
1814
1845
|
return [...cards].sort((a, b) => b.score - a.score || a.cardId.localeCompare(b.cardId)).slice(0, limit);
|
|
1815
1846
|
}
|
|
@@ -1818,6 +1849,7 @@ var init_prescribed = __esm({
|
|
|
1818
1849
|
"src/core/navigators/generators/prescribed.ts"() {
|
|
1819
1850
|
"use strict";
|
|
1820
1851
|
init_navigators();
|
|
1852
|
+
init_StrategyPressureDebugger();
|
|
1821
1853
|
init_logger();
|
|
1822
1854
|
DEFAULT_FRESHNESS_WINDOW = 3;
|
|
1823
1855
|
DEFAULT_MAX_DIRECT_PER_RUN = 3;
|
|
@@ -1894,6 +1926,7 @@ var init_prescribed = __esm({
|
|
|
1894
1926
|
const groupRuntimes = [];
|
|
1895
1927
|
const priorPracticeDebt = progress.practiceDebt ?? {};
|
|
1896
1928
|
const nextPracticeDebt = {};
|
|
1929
|
+
const practiceDebtsByGroup = /* @__PURE__ */ new Map();
|
|
1897
1930
|
for (const group of this.config.groups) {
|
|
1898
1931
|
const runtime = this.buildGroupRuntimeState({
|
|
1899
1932
|
group,
|
|
@@ -1942,7 +1975,7 @@ var init_prescribed = __esm({
|
|
|
1942
1975
|
courseId,
|
|
1943
1976
|
emittedIds
|
|
1944
1977
|
);
|
|
1945
|
-
const
|
|
1978
|
+
const practice = this.buildPracticeCards({
|
|
1946
1979
|
group,
|
|
1947
1980
|
courseId,
|
|
1948
1981
|
emittedIds,
|
|
@@ -1955,7 +1988,8 @@ var init_prescribed = __esm({
|
|
|
1955
1988
|
priorPracticeDebt,
|
|
1956
1989
|
nextPracticeDebt
|
|
1957
1990
|
});
|
|
1958
|
-
|
|
1991
|
+
practiceDebtsByGroup.set(group.id, practice.debts);
|
|
1992
|
+
emitted.push(...directCards, ...supportCards, ...discoveredSupportCards, ...practice.cards);
|
|
1959
1993
|
}
|
|
1960
1994
|
nextState.practiceDebt = nextPracticeDebt;
|
|
1961
1995
|
const hintSummary = this.buildSupportHintSummary(groupRuntimes);
|
|
@@ -1971,6 +2005,7 @@ var init_prescribed = __esm({
|
|
|
1971
2005
|
} else {
|
|
1972
2006
|
logger.info("[Prescribed] No hints to emit (no blocked targets or no support tags)");
|
|
1973
2007
|
}
|
|
2008
|
+
this.capturePressureSnapshot(courseId, groupRuntimes, practiceDebtsByGroup, emitted, hints);
|
|
1974
2009
|
if (emitted.length === 0) {
|
|
1975
2010
|
logger.info(
|
|
1976
2011
|
"[Prescribed] 0 cards emitted (all targets blocked, authored/discovered support candidates exhausted)" + (hints ? " \u2014 boost hints emitted but may not survive filters" : "")
|
|
@@ -2032,6 +2067,60 @@ var init_prescribed = __esm({
|
|
|
2032
2067
|
supportTags: [...supportTags].sort()
|
|
2033
2068
|
};
|
|
2034
2069
|
}
|
|
2070
|
+
/**
|
|
2071
|
+
* Translate this run's per-group runtimes and practice debts into gauges on
|
|
2072
|
+
* the generic strategy-pressure debug channel (rendered by the live session
|
|
2073
|
+
* overlay's "strategy backpressure" section).
|
|
2074
|
+
*/
|
|
2075
|
+
capturePressureSnapshot(courseId, groupRuntimes, practiceDebtsByGroup, emitted, hints) {
|
|
2076
|
+
const now = Date.now();
|
|
2077
|
+
const gauges = [];
|
|
2078
|
+
for (const runtime of groupRuntimes) {
|
|
2079
|
+
const group = runtime.group;
|
|
2080
|
+
const window2 = group.freshnessWindowSessions ?? DEFAULT_FRESHNESS_WINDOW;
|
|
2081
|
+
gauges.push({
|
|
2082
|
+
id: `group:${group.id}:target`,
|
|
2083
|
+
label: `${group.id} targets`,
|
|
2084
|
+
multiplier: runtime.pressureMultiplier,
|
|
2085
|
+
max: MAX_TARGET_MULTIPLIER,
|
|
2086
|
+
detail: `${runtime.pendingTargets.length} pending (${runtime.surfaceableTargets.length} surfaceable, ${runtime.blockedTargets.length} blocked) \xB7 sinceSurfaced ${runtime.sessionsSinceSurfaced}/${window2}`,
|
|
2087
|
+
items: runtime.blockedTargets.map((cardId) => ({ label: cardId, value: "blocked" }))
|
|
2088
|
+
});
|
|
2089
|
+
if (runtime.blockedTargets.length > 0) {
|
|
2090
|
+
const mode = runtime.supportCandidates.length > 0 ? "direct-support" : runtime.discoveredSupportCandidates.length > 0 ? "inserted-support" : "boost-only";
|
|
2091
|
+
gauges.push({
|
|
2092
|
+
id: `group:${group.id}:support`,
|
|
2093
|
+
label: `${group.id} support`,
|
|
2094
|
+
multiplier: runtime.supportMultiplier,
|
|
2095
|
+
max: MAX_SUPPORT_MULTIPLIER,
|
|
2096
|
+
detail: `mode=${mode} \xB7 ${runtime.supportTags.length} support tag(s)`,
|
|
2097
|
+
items: runtime.supportTags.map((tag) => ({ label: tag }))
|
|
2098
|
+
});
|
|
2099
|
+
}
|
|
2100
|
+
const debts = practiceDebtsByGroup.get(group.id) ?? [];
|
|
2101
|
+
if (debts.length > 0) {
|
|
2102
|
+
gauges.push({
|
|
2103
|
+
id: `group:${group.id}:practice-debt`,
|
|
2104
|
+
label: `${group.id} practice debt`,
|
|
2105
|
+
multiplier: Math.max(...debts.map((d) => d.multiplier)),
|
|
2106
|
+
max: MAX_PRACTICE_MULTIPLIER,
|
|
2107
|
+
detail: `${debts.length} under-practiced skill(s)`,
|
|
2108
|
+
items: debts.map((d) => ({
|
|
2109
|
+
label: d.tag,
|
|
2110
|
+
value: `\xD7${d.multiplier.toFixed(2)} \xB7 open ${formatAge(now - new Date(d.firstOwedAt).getTime())}`
|
|
2111
|
+
}))
|
|
2112
|
+
});
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
captureStrategyPressure({
|
|
2116
|
+
source: "prescribed",
|
|
2117
|
+
courseId,
|
|
2118
|
+
gauges,
|
|
2119
|
+
topScore: emitted.length > 0 ? Math.max(...emitted.map((c) => c.score)) : null,
|
|
2120
|
+
hintsLabel: hints?._label,
|
|
2121
|
+
timestamp: now
|
|
2122
|
+
});
|
|
2123
|
+
}
|
|
2035
2124
|
parseConfig(serializedData) {
|
|
2036
2125
|
try {
|
|
2037
2126
|
const parsed = JSON.parse(serializedData);
|
|
@@ -2188,6 +2277,7 @@ var init_prescribed = __esm({
|
|
|
2188
2277
|
supportTags: [...supportTags],
|
|
2189
2278
|
pressureMultiplier,
|
|
2190
2279
|
supportMultiplier,
|
|
2280
|
+
sessionsSinceSurfaced,
|
|
2191
2281
|
debugVersion: PRESCRIBED_DEBUG_VERSION
|
|
2192
2282
|
};
|
|
2193
2283
|
}
|
|
@@ -2320,13 +2410,13 @@ var init_prescribed = __esm({
|
|
|
2320
2410
|
nextPracticeDebt
|
|
2321
2411
|
} = args;
|
|
2322
2412
|
const patterns = group.practiceTagPatterns ?? [];
|
|
2323
|
-
if (patterns.length === 0) return [];
|
|
2413
|
+
if (patterns.length === 0) return { cards: [], debts: [] };
|
|
2324
2414
|
const practiceMinCount = group.practiceMinCount ?? DEFAULT_PRACTICE_MIN_COUNT;
|
|
2325
2415
|
const maxPractice = group.maxPracticeCardsPerRun ?? DEFAULT_MAX_PRACTICE_PER_RUN;
|
|
2326
2416
|
const practiceTags = [...cardsByTag.keys()].filter(
|
|
2327
2417
|
(tag) => patterns.some((p) => matchesTagPattern(tag, p)) && this.isUnlockedGatedSkill(tag, hierarchyConfigs, userTagElo, userGlobalElo) && (userTagElo[tag]?.count ?? 0) < practiceMinCount
|
|
2328
2418
|
);
|
|
2329
|
-
if (practiceTags.length === 0) return [];
|
|
2419
|
+
if (practiceTags.length === 0) return { cards: [], debts: [] };
|
|
2330
2420
|
const now = Date.now();
|
|
2331
2421
|
const DAY_MS = 24 * 60 * 60 * 1e3;
|
|
2332
2422
|
const tagMultiplier = /* @__PURE__ */ new Map();
|
|
@@ -2341,6 +2431,11 @@ var init_prescribed = __esm({
|
|
|
2341
2431
|
);
|
|
2342
2432
|
tagMultiplier.set(tag, mult);
|
|
2343
2433
|
}
|
|
2434
|
+
const debts = practiceTags.map((tag) => ({
|
|
2435
|
+
tag,
|
|
2436
|
+
multiplier: tagMultiplier.get(tag) ?? PRACTICE_BASE_MULT,
|
|
2437
|
+
firstOwedAt: nextPracticeDebt[tag]
|
|
2438
|
+
})).sort((a, b) => b.multiplier - a.multiplier || a.tag.localeCompare(b.tag));
|
|
2344
2439
|
const practiceCardIds = this.findDiscoveredSupportCards({
|
|
2345
2440
|
supportTags: practiceTags,
|
|
2346
2441
|
cardsByTag,
|
|
@@ -2349,7 +2444,7 @@ var init_prescribed = __esm({
|
|
|
2349
2444
|
excludedIds: emittedIds,
|
|
2350
2445
|
limit: maxPractice
|
|
2351
2446
|
});
|
|
2352
|
-
if (practiceCardIds.length === 0) return [];
|
|
2447
|
+
if (practiceCardIds.length === 0) return { cards: [], debts };
|
|
2353
2448
|
logger.info(
|
|
2354
2449
|
`[Prescribed] Group '${group.id}' practice: ${practiceTags.length} unlocked under-practiced skill(s), emitting ${practiceCardIds.length} drill card(s)`
|
|
2355
2450
|
);
|
|
@@ -2379,7 +2474,7 @@ var init_prescribed = __esm({
|
|
|
2379
2474
|
]
|
|
2380
2475
|
});
|
|
2381
2476
|
}
|
|
2382
|
-
return cards;
|
|
2477
|
+
return { cards, debts };
|
|
2383
2478
|
}
|
|
2384
2479
|
/**
|
|
2385
2480
|
* True for a skill that was *gated and is now reached*: it has at least one
|
|
@@ -4810,6 +4905,7 @@ var init_3 = __esm({
|
|
|
4810
4905
|
"./PipelineAssembler.ts": () => Promise.resolve().then(() => (init_PipelineAssembler(), PipelineAssembler_exports)),
|
|
4811
4906
|
"./PipelineDebugger.ts": () => Promise.resolve().then(() => (init_PipelineDebugger(), PipelineDebugger_exports)),
|
|
4812
4907
|
"./SrsDebugger.ts": () => Promise.resolve().then(() => (init_SrsDebugger(), SrsDebugger_exports)),
|
|
4908
|
+
"./StrategyPressureDebugger.ts": () => Promise.resolve().then(() => (init_StrategyPressureDebugger(), StrategyPressureDebugger_exports)),
|
|
4813
4909
|
"./defaults.ts": () => Promise.resolve().then(() => (init_defaults(), defaults_exports)),
|
|
4814
4910
|
"./diversityRerank.ts": () => Promise.resolve().then(() => (init_diversityRerank(), diversityRerank_exports)),
|
|
4815
4911
|
"./filters/WeightedFilter.ts": () => Promise.resolve().then(() => (init_WeightedFilter(), WeightedFilter_exports)),
|
|
@@ -4842,7 +4938,9 @@ __export(navigators_exports, {
|
|
|
4842
4938
|
NavigatorRole: () => NavigatorRole,
|
|
4843
4939
|
NavigatorRoles: () => NavigatorRoles,
|
|
4844
4940
|
Navigators: () => Navigators,
|
|
4941
|
+
captureStrategyPressure: () => captureStrategyPressure,
|
|
4845
4942
|
clearSrsBacklogDebug: () => clearSrsBacklogDebug,
|
|
4943
|
+
clearStrategyPressureDebug: () => clearStrategyPressureDebug,
|
|
4846
4944
|
diversityRerank: () => diversityRerank,
|
|
4847
4945
|
getActivePipeline: () => getActivePipeline,
|
|
4848
4946
|
getCardOrigin: () => getCardOrigin,
|
|
@@ -4850,6 +4948,7 @@ __export(navigators_exports, {
|
|
|
4850
4948
|
getRegisteredNavigatorNames: () => getRegisteredNavigatorNames,
|
|
4851
4949
|
getRegisteredNavigatorRole: () => getRegisteredNavigatorRole,
|
|
4852
4950
|
getSrsBacklogDebug: () => getSrsBacklogDebug,
|
|
4951
|
+
getStrategyPressureDebug: () => getStrategyPressureDebug,
|
|
4853
4952
|
hasRegisteredNavigator: () => hasRegisteredNavigator,
|
|
4854
4953
|
initializeNavigatorRegistry: () => initializeNavigatorRegistry,
|
|
4855
4954
|
isFilter: () => isFilter,
|
|
@@ -4932,6 +5031,7 @@ var init_navigators = __esm({
|
|
|
4932
5031
|
init_diversityRerank();
|
|
4933
5032
|
init_PipelineDebugger();
|
|
4934
5033
|
init_SrsDebugger();
|
|
5034
|
+
init_StrategyPressureDebugger();
|
|
4935
5035
|
init_logger();
|
|
4936
5036
|
init_();
|
|
4937
5037
|
init_2();
|