@vue-skuilder/db 0.2.16 → 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 +174 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +171 -7
- 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
|
@@ -1470,6 +1470,30 @@ var init_SrsDebugger = __esm({
|
|
|
1470
1470
|
}
|
|
1471
1471
|
});
|
|
1472
1472
|
|
|
1473
|
+
// src/core/navigators/StrategyPressureDebugger.ts
|
|
1474
|
+
var StrategyPressureDebugger_exports = {};
|
|
1475
|
+
__export(StrategyPressureDebugger_exports, {
|
|
1476
|
+
captureStrategyPressure: () => captureStrategyPressure,
|
|
1477
|
+
clearStrategyPressureDebug: () => clearStrategyPressureDebug,
|
|
1478
|
+
getStrategyPressureDebug: () => getStrategyPressureDebug
|
|
1479
|
+
});
|
|
1480
|
+
function captureStrategyPressure(snapshot) {
|
|
1481
|
+
snapshots2.set(`${snapshot.source}:${snapshot.courseId}`, snapshot);
|
|
1482
|
+
}
|
|
1483
|
+
function getStrategyPressureDebug() {
|
|
1484
|
+
return [...snapshots2.values()].sort((a, b) => b.timestamp - a.timestamp);
|
|
1485
|
+
}
|
|
1486
|
+
function clearStrategyPressureDebug() {
|
|
1487
|
+
snapshots2.clear();
|
|
1488
|
+
}
|
|
1489
|
+
var snapshots2;
|
|
1490
|
+
var init_StrategyPressureDebugger = __esm({
|
|
1491
|
+
"src/core/navigators/StrategyPressureDebugger.ts"() {
|
|
1492
|
+
"use strict";
|
|
1493
|
+
snapshots2 = /* @__PURE__ */ new Map();
|
|
1494
|
+
}
|
|
1495
|
+
});
|
|
1496
|
+
|
|
1473
1497
|
// src/core/navigators/generators/CompositeGenerator.ts
|
|
1474
1498
|
var CompositeGenerator_exports = {};
|
|
1475
1499
|
__export(CompositeGenerator_exports, {
|
|
@@ -1834,6 +1858,13 @@ function shuffleInPlace(arr) {
|
|
|
1834
1858
|
[arr[i], arr[j]] = [arr[j], arr[i]];
|
|
1835
1859
|
}
|
|
1836
1860
|
}
|
|
1861
|
+
function formatAge(ms) {
|
|
1862
|
+
const minutes = Math.max(0, Math.round(ms / 6e4));
|
|
1863
|
+
if (minutes < 60) return `${minutes}m`;
|
|
1864
|
+
const hours = Math.round(minutes / 60);
|
|
1865
|
+
if (hours < 24) return `${hours}h`;
|
|
1866
|
+
return `${Math.round(hours / 24)}d`;
|
|
1867
|
+
}
|
|
1837
1868
|
function pickTopByScore(cards, limit) {
|
|
1838
1869
|
return [...cards].sort((a, b) => b.score - a.score || a.cardId.localeCompare(b.cardId)).slice(0, limit);
|
|
1839
1870
|
}
|
|
@@ -1842,6 +1873,7 @@ var init_prescribed = __esm({
|
|
|
1842
1873
|
"src/core/navigators/generators/prescribed.ts"() {
|
|
1843
1874
|
"use strict";
|
|
1844
1875
|
init_navigators();
|
|
1876
|
+
init_StrategyPressureDebugger();
|
|
1845
1877
|
init_logger();
|
|
1846
1878
|
DEFAULT_FRESHNESS_WINDOW = 3;
|
|
1847
1879
|
DEFAULT_MAX_DIRECT_PER_RUN = 3;
|
|
@@ -1918,6 +1950,7 @@ var init_prescribed = __esm({
|
|
|
1918
1950
|
const groupRuntimes = [];
|
|
1919
1951
|
const priorPracticeDebt = progress.practiceDebt ?? {};
|
|
1920
1952
|
const nextPracticeDebt = {};
|
|
1953
|
+
const practiceDebtsByGroup = /* @__PURE__ */ new Map();
|
|
1921
1954
|
for (const group of this.config.groups) {
|
|
1922
1955
|
const runtime = this.buildGroupRuntimeState({
|
|
1923
1956
|
group,
|
|
@@ -1966,7 +1999,7 @@ var init_prescribed = __esm({
|
|
|
1966
1999
|
courseId,
|
|
1967
2000
|
emittedIds
|
|
1968
2001
|
);
|
|
1969
|
-
const
|
|
2002
|
+
const practice = this.buildPracticeCards({
|
|
1970
2003
|
group,
|
|
1971
2004
|
courseId,
|
|
1972
2005
|
emittedIds,
|
|
@@ -1979,7 +2012,8 @@ var init_prescribed = __esm({
|
|
|
1979
2012
|
priorPracticeDebt,
|
|
1980
2013
|
nextPracticeDebt
|
|
1981
2014
|
});
|
|
1982
|
-
|
|
2015
|
+
practiceDebtsByGroup.set(group.id, practice.debts);
|
|
2016
|
+
emitted.push(...directCards, ...supportCards, ...discoveredSupportCards, ...practice.cards);
|
|
1983
2017
|
}
|
|
1984
2018
|
nextState.practiceDebt = nextPracticeDebt;
|
|
1985
2019
|
const hintSummary = this.buildSupportHintSummary(groupRuntimes);
|
|
@@ -1995,6 +2029,7 @@ var init_prescribed = __esm({
|
|
|
1995
2029
|
} else {
|
|
1996
2030
|
logger.info("[Prescribed] No hints to emit (no blocked targets or no support tags)");
|
|
1997
2031
|
}
|
|
2032
|
+
this.capturePressureSnapshot(courseId, groupRuntimes, practiceDebtsByGroup, emitted, hints);
|
|
1998
2033
|
if (emitted.length === 0) {
|
|
1999
2034
|
logger.info(
|
|
2000
2035
|
"[Prescribed] 0 cards emitted (all targets blocked, authored/discovered support candidates exhausted)" + (hints ? " \u2014 boost hints emitted but may not survive filters" : "")
|
|
@@ -2056,6 +2091,60 @@ var init_prescribed = __esm({
|
|
|
2056
2091
|
supportTags: [...supportTags].sort()
|
|
2057
2092
|
};
|
|
2058
2093
|
}
|
|
2094
|
+
/**
|
|
2095
|
+
* Translate this run's per-group runtimes and practice debts into gauges on
|
|
2096
|
+
* the generic strategy-pressure debug channel (rendered by the live session
|
|
2097
|
+
* overlay's "strategy backpressure" section).
|
|
2098
|
+
*/
|
|
2099
|
+
capturePressureSnapshot(courseId, groupRuntimes, practiceDebtsByGroup, emitted, hints) {
|
|
2100
|
+
const now = Date.now();
|
|
2101
|
+
const gauges = [];
|
|
2102
|
+
for (const runtime of groupRuntimes) {
|
|
2103
|
+
const group = runtime.group;
|
|
2104
|
+
const window2 = group.freshnessWindowSessions ?? DEFAULT_FRESHNESS_WINDOW;
|
|
2105
|
+
gauges.push({
|
|
2106
|
+
id: `group:${group.id}:target`,
|
|
2107
|
+
label: `${group.id} targets`,
|
|
2108
|
+
multiplier: runtime.pressureMultiplier,
|
|
2109
|
+
max: MAX_TARGET_MULTIPLIER,
|
|
2110
|
+
detail: `${runtime.pendingTargets.length} pending (${runtime.surfaceableTargets.length} surfaceable, ${runtime.blockedTargets.length} blocked) \xB7 sinceSurfaced ${runtime.sessionsSinceSurfaced}/${window2}`,
|
|
2111
|
+
items: runtime.blockedTargets.map((cardId) => ({ label: cardId, value: "blocked" }))
|
|
2112
|
+
});
|
|
2113
|
+
if (runtime.blockedTargets.length > 0) {
|
|
2114
|
+
const mode = runtime.supportCandidates.length > 0 ? "direct-support" : runtime.discoveredSupportCandidates.length > 0 ? "inserted-support" : "boost-only";
|
|
2115
|
+
gauges.push({
|
|
2116
|
+
id: `group:${group.id}:support`,
|
|
2117
|
+
label: `${group.id} support`,
|
|
2118
|
+
multiplier: runtime.supportMultiplier,
|
|
2119
|
+
max: MAX_SUPPORT_MULTIPLIER,
|
|
2120
|
+
detail: `mode=${mode} \xB7 ${runtime.supportTags.length} support tag(s)`,
|
|
2121
|
+
items: runtime.supportTags.map((tag) => ({ label: tag }))
|
|
2122
|
+
});
|
|
2123
|
+
}
|
|
2124
|
+
const debts = practiceDebtsByGroup.get(group.id) ?? [];
|
|
2125
|
+
if (debts.length > 0) {
|
|
2126
|
+
gauges.push({
|
|
2127
|
+
id: `group:${group.id}:practice-debt`,
|
|
2128
|
+
label: `${group.id} practice debt`,
|
|
2129
|
+
multiplier: Math.max(...debts.map((d) => d.multiplier)),
|
|
2130
|
+
max: MAX_PRACTICE_MULTIPLIER,
|
|
2131
|
+
detail: `${debts.length} under-practiced skill(s)`,
|
|
2132
|
+
items: debts.map((d) => ({
|
|
2133
|
+
label: d.tag,
|
|
2134
|
+
value: `\xD7${d.multiplier.toFixed(2)} \xB7 open ${formatAge(now - new Date(d.firstOwedAt).getTime())}`
|
|
2135
|
+
}))
|
|
2136
|
+
});
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2139
|
+
captureStrategyPressure({
|
|
2140
|
+
source: "prescribed",
|
|
2141
|
+
courseId,
|
|
2142
|
+
gauges,
|
|
2143
|
+
topScore: emitted.length > 0 ? Math.max(...emitted.map((c) => c.score)) : null,
|
|
2144
|
+
hintsLabel: hints?._label,
|
|
2145
|
+
timestamp: now
|
|
2146
|
+
});
|
|
2147
|
+
}
|
|
2059
2148
|
parseConfig(serializedData) {
|
|
2060
2149
|
try {
|
|
2061
2150
|
const parsed = JSON.parse(serializedData);
|
|
@@ -2212,6 +2301,7 @@ var init_prescribed = __esm({
|
|
|
2212
2301
|
supportTags: [...supportTags],
|
|
2213
2302
|
pressureMultiplier,
|
|
2214
2303
|
supportMultiplier,
|
|
2304
|
+
sessionsSinceSurfaced,
|
|
2215
2305
|
debugVersion: PRESCRIBED_DEBUG_VERSION
|
|
2216
2306
|
};
|
|
2217
2307
|
}
|
|
@@ -2344,13 +2434,13 @@ var init_prescribed = __esm({
|
|
|
2344
2434
|
nextPracticeDebt
|
|
2345
2435
|
} = args;
|
|
2346
2436
|
const patterns = group.practiceTagPatterns ?? [];
|
|
2347
|
-
if (patterns.length === 0) return [];
|
|
2437
|
+
if (patterns.length === 0) return { cards: [], debts: [] };
|
|
2348
2438
|
const practiceMinCount = group.practiceMinCount ?? DEFAULT_PRACTICE_MIN_COUNT;
|
|
2349
2439
|
const maxPractice = group.maxPracticeCardsPerRun ?? DEFAULT_MAX_PRACTICE_PER_RUN;
|
|
2350
2440
|
const practiceTags = [...cardsByTag.keys()].filter(
|
|
2351
2441
|
(tag) => patterns.some((p) => matchesTagPattern(tag, p)) && this.isUnlockedGatedSkill(tag, hierarchyConfigs, userTagElo, userGlobalElo) && (userTagElo[tag]?.count ?? 0) < practiceMinCount
|
|
2352
2442
|
);
|
|
2353
|
-
if (practiceTags.length === 0) return [];
|
|
2443
|
+
if (practiceTags.length === 0) return { cards: [], debts: [] };
|
|
2354
2444
|
const now = Date.now();
|
|
2355
2445
|
const DAY_MS = 24 * 60 * 60 * 1e3;
|
|
2356
2446
|
const tagMultiplier = /* @__PURE__ */ new Map();
|
|
@@ -2365,6 +2455,11 @@ var init_prescribed = __esm({
|
|
|
2365
2455
|
);
|
|
2366
2456
|
tagMultiplier.set(tag, mult);
|
|
2367
2457
|
}
|
|
2458
|
+
const debts = practiceTags.map((tag) => ({
|
|
2459
|
+
tag,
|
|
2460
|
+
multiplier: tagMultiplier.get(tag) ?? PRACTICE_BASE_MULT,
|
|
2461
|
+
firstOwedAt: nextPracticeDebt[tag]
|
|
2462
|
+
})).sort((a, b) => b.multiplier - a.multiplier || a.tag.localeCompare(b.tag));
|
|
2368
2463
|
const practiceCardIds = this.findDiscoveredSupportCards({
|
|
2369
2464
|
supportTags: practiceTags,
|
|
2370
2465
|
cardsByTag,
|
|
@@ -2373,7 +2468,7 @@ var init_prescribed = __esm({
|
|
|
2373
2468
|
excludedIds: emittedIds,
|
|
2374
2469
|
limit: maxPractice
|
|
2375
2470
|
});
|
|
2376
|
-
if (practiceCardIds.length === 0) return [];
|
|
2471
|
+
if (practiceCardIds.length === 0) return { cards: [], debts };
|
|
2377
2472
|
logger.info(
|
|
2378
2473
|
`[Prescribed] Group '${group.id}' practice: ${practiceTags.length} unlocked under-practiced skill(s), emitting ${practiceCardIds.length} drill card(s)`
|
|
2379
2474
|
);
|
|
@@ -2403,7 +2498,7 @@ var init_prescribed = __esm({
|
|
|
2403
2498
|
]
|
|
2404
2499
|
});
|
|
2405
2500
|
}
|
|
2406
|
-
return cards;
|
|
2501
|
+
return { cards, debts };
|
|
2407
2502
|
}
|
|
2408
2503
|
/**
|
|
2409
2504
|
* True for a skill that was *gated and is now reached*: it has at least one
|
|
@@ -4834,6 +4929,7 @@ var init_3 = __esm({
|
|
|
4834
4929
|
"./PipelineAssembler.ts": () => Promise.resolve().then(() => (init_PipelineAssembler(), PipelineAssembler_exports)),
|
|
4835
4930
|
"./PipelineDebugger.ts": () => Promise.resolve().then(() => (init_PipelineDebugger(), PipelineDebugger_exports)),
|
|
4836
4931
|
"./SrsDebugger.ts": () => Promise.resolve().then(() => (init_SrsDebugger(), SrsDebugger_exports)),
|
|
4932
|
+
"./StrategyPressureDebugger.ts": () => Promise.resolve().then(() => (init_StrategyPressureDebugger(), StrategyPressureDebugger_exports)),
|
|
4837
4933
|
"./defaults.ts": () => Promise.resolve().then(() => (init_defaults(), defaults_exports)),
|
|
4838
4934
|
"./diversityRerank.ts": () => Promise.resolve().then(() => (init_diversityRerank(), diversityRerank_exports)),
|
|
4839
4935
|
"./filters/WeightedFilter.ts": () => Promise.resolve().then(() => (init_WeightedFilter(), WeightedFilter_exports)),
|
|
@@ -4866,7 +4962,9 @@ __export(navigators_exports, {
|
|
|
4866
4962
|
NavigatorRole: () => NavigatorRole,
|
|
4867
4963
|
NavigatorRoles: () => NavigatorRoles,
|
|
4868
4964
|
Navigators: () => Navigators,
|
|
4965
|
+
captureStrategyPressure: () => captureStrategyPressure,
|
|
4869
4966
|
clearSrsBacklogDebug: () => clearSrsBacklogDebug,
|
|
4967
|
+
clearStrategyPressureDebug: () => clearStrategyPressureDebug,
|
|
4870
4968
|
diversityRerank: () => diversityRerank,
|
|
4871
4969
|
getActivePipeline: () => getActivePipeline,
|
|
4872
4970
|
getCardOrigin: () => getCardOrigin,
|
|
@@ -4874,6 +4972,7 @@ __export(navigators_exports, {
|
|
|
4874
4972
|
getRegisteredNavigatorNames: () => getRegisteredNavigatorNames,
|
|
4875
4973
|
getRegisteredNavigatorRole: () => getRegisteredNavigatorRole,
|
|
4876
4974
|
getSrsBacklogDebug: () => getSrsBacklogDebug,
|
|
4975
|
+
getStrategyPressureDebug: () => getStrategyPressureDebug,
|
|
4877
4976
|
hasRegisteredNavigator: () => hasRegisteredNavigator,
|
|
4878
4977
|
initializeNavigatorRegistry: () => initializeNavigatorRegistry,
|
|
4879
4978
|
isFilter: () => isFilter,
|
|
@@ -4956,6 +5055,7 @@ var init_navigators = __esm({
|
|
|
4956
5055
|
init_diversityRerank();
|
|
4957
5056
|
init_PipelineDebugger();
|
|
4958
5057
|
init_SrsDebugger();
|
|
5058
|
+
init_StrategyPressureDebugger();
|
|
4959
5059
|
init_logger();
|
|
4960
5060
|
init_();
|
|
4961
5061
|
init_2();
|