@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
package/dist/impl/couch/index.js
CHANGED
|
@@ -1588,6 +1588,30 @@ var init_SrsDebugger = __esm({
|
|
|
1588
1588
|
}
|
|
1589
1589
|
});
|
|
1590
1590
|
|
|
1591
|
+
// src/core/navigators/StrategyPressureDebugger.ts
|
|
1592
|
+
var StrategyPressureDebugger_exports = {};
|
|
1593
|
+
__export(StrategyPressureDebugger_exports, {
|
|
1594
|
+
captureStrategyPressure: () => captureStrategyPressure,
|
|
1595
|
+
clearStrategyPressureDebug: () => clearStrategyPressureDebug,
|
|
1596
|
+
getStrategyPressureDebug: () => getStrategyPressureDebug
|
|
1597
|
+
});
|
|
1598
|
+
function captureStrategyPressure(snapshot) {
|
|
1599
|
+
snapshots2.set(`${snapshot.source}:${snapshot.courseId}`, snapshot);
|
|
1600
|
+
}
|
|
1601
|
+
function getStrategyPressureDebug() {
|
|
1602
|
+
return [...snapshots2.values()].sort((a, b) => b.timestamp - a.timestamp);
|
|
1603
|
+
}
|
|
1604
|
+
function clearStrategyPressureDebug() {
|
|
1605
|
+
snapshots2.clear();
|
|
1606
|
+
}
|
|
1607
|
+
var snapshots2;
|
|
1608
|
+
var init_StrategyPressureDebugger = __esm({
|
|
1609
|
+
"src/core/navigators/StrategyPressureDebugger.ts"() {
|
|
1610
|
+
"use strict";
|
|
1611
|
+
snapshots2 = /* @__PURE__ */ new Map();
|
|
1612
|
+
}
|
|
1613
|
+
});
|
|
1614
|
+
|
|
1591
1615
|
// src/core/navigators/generators/CompositeGenerator.ts
|
|
1592
1616
|
var CompositeGenerator_exports = {};
|
|
1593
1617
|
__export(CompositeGenerator_exports, {
|
|
@@ -1952,6 +1976,13 @@ function shuffleInPlace(arr) {
|
|
|
1952
1976
|
[arr[i], arr[j]] = [arr[j], arr[i]];
|
|
1953
1977
|
}
|
|
1954
1978
|
}
|
|
1979
|
+
function formatAge(ms) {
|
|
1980
|
+
const minutes = Math.max(0, Math.round(ms / 6e4));
|
|
1981
|
+
if (minutes < 60) return `${minutes}m`;
|
|
1982
|
+
const hours = Math.round(minutes / 60);
|
|
1983
|
+
if (hours < 24) return `${hours}h`;
|
|
1984
|
+
return `${Math.round(hours / 24)}d`;
|
|
1985
|
+
}
|
|
1955
1986
|
function pickTopByScore(cards, limit) {
|
|
1956
1987
|
return [...cards].sort((a, b) => b.score - a.score || a.cardId.localeCompare(b.cardId)).slice(0, limit);
|
|
1957
1988
|
}
|
|
@@ -1960,6 +1991,7 @@ var init_prescribed = __esm({
|
|
|
1960
1991
|
"src/core/navigators/generators/prescribed.ts"() {
|
|
1961
1992
|
"use strict";
|
|
1962
1993
|
init_navigators();
|
|
1994
|
+
init_StrategyPressureDebugger();
|
|
1963
1995
|
init_logger();
|
|
1964
1996
|
DEFAULT_FRESHNESS_WINDOW = 3;
|
|
1965
1997
|
DEFAULT_MAX_DIRECT_PER_RUN = 3;
|
|
@@ -2036,6 +2068,7 @@ var init_prescribed = __esm({
|
|
|
2036
2068
|
const groupRuntimes = [];
|
|
2037
2069
|
const priorPracticeDebt = progress.practiceDebt ?? {};
|
|
2038
2070
|
const nextPracticeDebt = {};
|
|
2071
|
+
const practiceDebtsByGroup = /* @__PURE__ */ new Map();
|
|
2039
2072
|
for (const group of this.config.groups) {
|
|
2040
2073
|
const runtime = this.buildGroupRuntimeState({
|
|
2041
2074
|
group,
|
|
@@ -2084,7 +2117,7 @@ var init_prescribed = __esm({
|
|
|
2084
2117
|
courseId,
|
|
2085
2118
|
emittedIds
|
|
2086
2119
|
);
|
|
2087
|
-
const
|
|
2120
|
+
const practice = this.buildPracticeCards({
|
|
2088
2121
|
group,
|
|
2089
2122
|
courseId,
|
|
2090
2123
|
emittedIds,
|
|
@@ -2097,7 +2130,8 @@ var init_prescribed = __esm({
|
|
|
2097
2130
|
priorPracticeDebt,
|
|
2098
2131
|
nextPracticeDebt
|
|
2099
2132
|
});
|
|
2100
|
-
|
|
2133
|
+
practiceDebtsByGroup.set(group.id, practice.debts);
|
|
2134
|
+
emitted.push(...directCards, ...supportCards, ...discoveredSupportCards, ...practice.cards);
|
|
2101
2135
|
}
|
|
2102
2136
|
nextState.practiceDebt = nextPracticeDebt;
|
|
2103
2137
|
const hintSummary = this.buildSupportHintSummary(groupRuntimes);
|
|
@@ -2113,6 +2147,7 @@ var init_prescribed = __esm({
|
|
|
2113
2147
|
} else {
|
|
2114
2148
|
logger.info("[Prescribed] No hints to emit (no blocked targets or no support tags)");
|
|
2115
2149
|
}
|
|
2150
|
+
this.capturePressureSnapshot(courseId, groupRuntimes, practiceDebtsByGroup, emitted, hints);
|
|
2116
2151
|
if (emitted.length === 0) {
|
|
2117
2152
|
logger.info(
|
|
2118
2153
|
"[Prescribed] 0 cards emitted (all targets blocked, authored/discovered support candidates exhausted)" + (hints ? " \u2014 boost hints emitted but may not survive filters" : "")
|
|
@@ -2174,6 +2209,60 @@ var init_prescribed = __esm({
|
|
|
2174
2209
|
supportTags: [...supportTags].sort()
|
|
2175
2210
|
};
|
|
2176
2211
|
}
|
|
2212
|
+
/**
|
|
2213
|
+
* Translate this run's per-group runtimes and practice debts into gauges on
|
|
2214
|
+
* the generic strategy-pressure debug channel (rendered by the live session
|
|
2215
|
+
* overlay's "strategy backpressure" section).
|
|
2216
|
+
*/
|
|
2217
|
+
capturePressureSnapshot(courseId, groupRuntimes, practiceDebtsByGroup, emitted, hints) {
|
|
2218
|
+
const now = Date.now();
|
|
2219
|
+
const gauges = [];
|
|
2220
|
+
for (const runtime of groupRuntimes) {
|
|
2221
|
+
const group = runtime.group;
|
|
2222
|
+
const window2 = group.freshnessWindowSessions ?? DEFAULT_FRESHNESS_WINDOW;
|
|
2223
|
+
gauges.push({
|
|
2224
|
+
id: `group:${group.id}:target`,
|
|
2225
|
+
label: `${group.id} targets`,
|
|
2226
|
+
multiplier: runtime.pressureMultiplier,
|
|
2227
|
+
max: MAX_TARGET_MULTIPLIER,
|
|
2228
|
+
detail: `${runtime.pendingTargets.length} pending (${runtime.surfaceableTargets.length} surfaceable, ${runtime.blockedTargets.length} blocked) \xB7 sinceSurfaced ${runtime.sessionsSinceSurfaced}/${window2}`,
|
|
2229
|
+
items: runtime.blockedTargets.map((cardId) => ({ label: cardId, value: "blocked" }))
|
|
2230
|
+
});
|
|
2231
|
+
if (runtime.blockedTargets.length > 0) {
|
|
2232
|
+
const mode = runtime.supportCandidates.length > 0 ? "direct-support" : runtime.discoveredSupportCandidates.length > 0 ? "inserted-support" : "boost-only";
|
|
2233
|
+
gauges.push({
|
|
2234
|
+
id: `group:${group.id}:support`,
|
|
2235
|
+
label: `${group.id} support`,
|
|
2236
|
+
multiplier: runtime.supportMultiplier,
|
|
2237
|
+
max: MAX_SUPPORT_MULTIPLIER,
|
|
2238
|
+
detail: `mode=${mode} \xB7 ${runtime.supportTags.length} support tag(s)`,
|
|
2239
|
+
items: runtime.supportTags.map((tag) => ({ label: tag }))
|
|
2240
|
+
});
|
|
2241
|
+
}
|
|
2242
|
+
const debts = practiceDebtsByGroup.get(group.id) ?? [];
|
|
2243
|
+
if (debts.length > 0) {
|
|
2244
|
+
gauges.push({
|
|
2245
|
+
id: `group:${group.id}:practice-debt`,
|
|
2246
|
+
label: `${group.id} practice debt`,
|
|
2247
|
+
multiplier: Math.max(...debts.map((d) => d.multiplier)),
|
|
2248
|
+
max: MAX_PRACTICE_MULTIPLIER,
|
|
2249
|
+
detail: `${debts.length} under-practiced skill(s)`,
|
|
2250
|
+
items: debts.map((d) => ({
|
|
2251
|
+
label: d.tag,
|
|
2252
|
+
value: `\xD7${d.multiplier.toFixed(2)} \xB7 open ${formatAge(now - new Date(d.firstOwedAt).getTime())}`
|
|
2253
|
+
}))
|
|
2254
|
+
});
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
captureStrategyPressure({
|
|
2258
|
+
source: "prescribed",
|
|
2259
|
+
courseId,
|
|
2260
|
+
gauges,
|
|
2261
|
+
topScore: emitted.length > 0 ? Math.max(...emitted.map((c) => c.score)) : null,
|
|
2262
|
+
hintsLabel: hints?._label,
|
|
2263
|
+
timestamp: now
|
|
2264
|
+
});
|
|
2265
|
+
}
|
|
2177
2266
|
parseConfig(serializedData) {
|
|
2178
2267
|
try {
|
|
2179
2268
|
const parsed = JSON.parse(serializedData);
|
|
@@ -2330,6 +2419,7 @@ var init_prescribed = __esm({
|
|
|
2330
2419
|
supportTags: [...supportTags],
|
|
2331
2420
|
pressureMultiplier,
|
|
2332
2421
|
supportMultiplier,
|
|
2422
|
+
sessionsSinceSurfaced,
|
|
2333
2423
|
debugVersion: PRESCRIBED_DEBUG_VERSION
|
|
2334
2424
|
};
|
|
2335
2425
|
}
|
|
@@ -2462,13 +2552,13 @@ var init_prescribed = __esm({
|
|
|
2462
2552
|
nextPracticeDebt
|
|
2463
2553
|
} = args;
|
|
2464
2554
|
const patterns = group.practiceTagPatterns ?? [];
|
|
2465
|
-
if (patterns.length === 0) return [];
|
|
2555
|
+
if (patterns.length === 0) return { cards: [], debts: [] };
|
|
2466
2556
|
const practiceMinCount = group.practiceMinCount ?? DEFAULT_PRACTICE_MIN_COUNT;
|
|
2467
2557
|
const maxPractice = group.maxPracticeCardsPerRun ?? DEFAULT_MAX_PRACTICE_PER_RUN;
|
|
2468
2558
|
const practiceTags = [...cardsByTag.keys()].filter(
|
|
2469
2559
|
(tag) => patterns.some((p) => matchesTagPattern(tag, p)) && this.isUnlockedGatedSkill(tag, hierarchyConfigs, userTagElo, userGlobalElo) && (userTagElo[tag]?.count ?? 0) < practiceMinCount
|
|
2470
2560
|
);
|
|
2471
|
-
if (practiceTags.length === 0) return [];
|
|
2561
|
+
if (practiceTags.length === 0) return { cards: [], debts: [] };
|
|
2472
2562
|
const now = Date.now();
|
|
2473
2563
|
const DAY_MS = 24 * 60 * 60 * 1e3;
|
|
2474
2564
|
const tagMultiplier = /* @__PURE__ */ new Map();
|
|
@@ -2483,6 +2573,11 @@ var init_prescribed = __esm({
|
|
|
2483
2573
|
);
|
|
2484
2574
|
tagMultiplier.set(tag, mult);
|
|
2485
2575
|
}
|
|
2576
|
+
const debts = practiceTags.map((tag) => ({
|
|
2577
|
+
tag,
|
|
2578
|
+
multiplier: tagMultiplier.get(tag) ?? PRACTICE_BASE_MULT,
|
|
2579
|
+
firstOwedAt: nextPracticeDebt[tag]
|
|
2580
|
+
})).sort((a, b) => b.multiplier - a.multiplier || a.tag.localeCompare(b.tag));
|
|
2486
2581
|
const practiceCardIds = this.findDiscoveredSupportCards({
|
|
2487
2582
|
supportTags: practiceTags,
|
|
2488
2583
|
cardsByTag,
|
|
@@ -2491,7 +2586,7 @@ var init_prescribed = __esm({
|
|
|
2491
2586
|
excludedIds: emittedIds,
|
|
2492
2587
|
limit: maxPractice
|
|
2493
2588
|
});
|
|
2494
|
-
if (practiceCardIds.length === 0) return [];
|
|
2589
|
+
if (practiceCardIds.length === 0) return { cards: [], debts };
|
|
2495
2590
|
logger.info(
|
|
2496
2591
|
`[Prescribed] Group '${group.id}' practice: ${practiceTags.length} unlocked under-practiced skill(s), emitting ${practiceCardIds.length} drill card(s)`
|
|
2497
2592
|
);
|
|
@@ -2521,7 +2616,7 @@ var init_prescribed = __esm({
|
|
|
2521
2616
|
]
|
|
2522
2617
|
});
|
|
2523
2618
|
}
|
|
2524
|
-
return cards;
|
|
2619
|
+
return { cards, debts };
|
|
2525
2620
|
}
|
|
2526
2621
|
/**
|
|
2527
2622
|
* True for a skill that was *gated and is now reached*: it has at least one
|
|
@@ -4952,6 +5047,7 @@ var init_3 = __esm({
|
|
|
4952
5047
|
"./PipelineAssembler.ts": () => Promise.resolve().then(() => (init_PipelineAssembler(), PipelineAssembler_exports)),
|
|
4953
5048
|
"./PipelineDebugger.ts": () => Promise.resolve().then(() => (init_PipelineDebugger(), PipelineDebugger_exports)),
|
|
4954
5049
|
"./SrsDebugger.ts": () => Promise.resolve().then(() => (init_SrsDebugger(), SrsDebugger_exports)),
|
|
5050
|
+
"./StrategyPressureDebugger.ts": () => Promise.resolve().then(() => (init_StrategyPressureDebugger(), StrategyPressureDebugger_exports)),
|
|
4955
5051
|
"./defaults.ts": () => Promise.resolve().then(() => (init_defaults(), defaults_exports)),
|
|
4956
5052
|
"./diversityRerank.ts": () => Promise.resolve().then(() => (init_diversityRerank(), diversityRerank_exports)),
|
|
4957
5053
|
"./filters/WeightedFilter.ts": () => Promise.resolve().then(() => (init_WeightedFilter(), WeightedFilter_exports)),
|
|
@@ -4984,7 +5080,9 @@ __export(navigators_exports, {
|
|
|
4984
5080
|
NavigatorRole: () => NavigatorRole,
|
|
4985
5081
|
NavigatorRoles: () => NavigatorRoles,
|
|
4986
5082
|
Navigators: () => Navigators,
|
|
5083
|
+
captureStrategyPressure: () => captureStrategyPressure,
|
|
4987
5084
|
clearSrsBacklogDebug: () => clearSrsBacklogDebug,
|
|
5085
|
+
clearStrategyPressureDebug: () => clearStrategyPressureDebug,
|
|
4988
5086
|
diversityRerank: () => diversityRerank,
|
|
4989
5087
|
getActivePipeline: () => getActivePipeline,
|
|
4990
5088
|
getCardOrigin: () => getCardOrigin,
|
|
@@ -4992,6 +5090,7 @@ __export(navigators_exports, {
|
|
|
4992
5090
|
getRegisteredNavigatorNames: () => getRegisteredNavigatorNames,
|
|
4993
5091
|
getRegisteredNavigatorRole: () => getRegisteredNavigatorRole,
|
|
4994
5092
|
getSrsBacklogDebug: () => getSrsBacklogDebug,
|
|
5093
|
+
getStrategyPressureDebug: () => getStrategyPressureDebug,
|
|
4995
5094
|
hasRegisteredNavigator: () => hasRegisteredNavigator,
|
|
4996
5095
|
initializeNavigatorRegistry: () => initializeNavigatorRegistry,
|
|
4997
5096
|
isFilter: () => isFilter,
|
|
@@ -5074,6 +5173,7 @@ var init_navigators = __esm({
|
|
|
5074
5173
|
init_diversityRerank();
|
|
5075
5174
|
init_PipelineDebugger();
|
|
5076
5175
|
init_SrsDebugger();
|
|
5176
|
+
init_StrategyPressureDebugger();
|
|
5077
5177
|
init_logger();
|
|
5078
5178
|
init_();
|
|
5079
5179
|
init_2();
|