zam-core 0.9.1 → 0.9.3
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/README.md +87 -129
- package/dist/cli/app.js +47 -27
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/commands/mcp.js +46 -26
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +46 -26
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1479,6 +1479,9 @@ declare function cascadeBlock(db: Database, userId: string, tokenSlug: string):
|
|
|
1479
1479
|
* If a blocked card has no prerequisites at all, it is unblocked immediately
|
|
1480
1480
|
* (it was likely blocked in error or its prerequisites were removed).
|
|
1481
1481
|
*
|
|
1482
|
+
* Unblocking cascades: when unblocking a card satisfies the last unmet
|
|
1483
|
+
* prerequisite of another blocked card, that card unblocks in the same call.
|
|
1484
|
+
*
|
|
1482
1485
|
* @param db - Database connection
|
|
1483
1486
|
* @param userId - The user whose blocked cards to check
|
|
1484
1487
|
* @returns List of cards that were unblocked
|
package/dist/index.js
CHANGED
|
@@ -1705,6 +1705,18 @@ async function getTokenBySlug(db, slug) {
|
|
|
1705
1705
|
parseTokenFallback(token);
|
|
1706
1706
|
return token;
|
|
1707
1707
|
}
|
|
1708
|
+
async function getTokensBySlugs(db, slugs) {
|
|
1709
|
+
const tokens = /* @__PURE__ */ new Map();
|
|
1710
|
+
const unique = [...new Set(slugs)];
|
|
1711
|
+
if (unique.length === 0) return tokens;
|
|
1712
|
+
const placeholders = unique.map(() => "?").join(",");
|
|
1713
|
+
const rows = await db.prepare(`SELECT * FROM tokens WHERE slug IN (${placeholders})`).all(...unique);
|
|
1714
|
+
for (const token of rows) {
|
|
1715
|
+
parseTokenFallback(token);
|
|
1716
|
+
tokens.set(token.slug, token);
|
|
1717
|
+
}
|
|
1718
|
+
return tokens;
|
|
1719
|
+
}
|
|
1708
1720
|
async function getTokenById(db, id) {
|
|
1709
1721
|
const token = await db.prepare("SELECT * FROM tokens WHERE id = ?").get(id);
|
|
1710
1722
|
parseTokenFallback(token);
|
|
@@ -3769,25 +3781,29 @@ async function cascadeBlock(db, userId, tokenSlug) {
|
|
|
3769
3781
|
};
|
|
3770
3782
|
}
|
|
3771
3783
|
async function unblockReady(db, userId) {
|
|
3772
|
-
const blockedCards = await db.prepare(
|
|
3773
|
-
`SELECT c.token_id, t.slug, t.concept
|
|
3774
|
-
FROM cards c
|
|
3775
|
-
JOIN tokens t ON t.id = c.token_id
|
|
3776
|
-
WHERE c.user_id = ? AND c.blocked = 1`
|
|
3777
|
-
).all(userId);
|
|
3778
3784
|
const unblocked = [];
|
|
3779
|
-
for (
|
|
3780
|
-
const
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
JOIN
|
|
3784
|
-
WHERE
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3785
|
+
for (; ; ) {
|
|
3786
|
+
const readyCards = await db.prepare(
|
|
3787
|
+
`SELECT c.token_id, t.slug, t.concept
|
|
3788
|
+
FROM cards c
|
|
3789
|
+
JOIN tokens t ON t.id = c.token_id
|
|
3790
|
+
WHERE c.user_id = ? AND c.blocked = 1
|
|
3791
|
+
AND (SELECT COUNT(*) FROM prerequisites p
|
|
3792
|
+
WHERE p.token_id = c.token_id) =
|
|
3793
|
+
(SELECT COUNT(*) FROM prerequisites p
|
|
3794
|
+
JOIN cards pc ON pc.token_id = p.requires_id
|
|
3795
|
+
AND pc.user_id = c.user_id
|
|
3796
|
+
WHERE p.token_id = c.token_id
|
|
3797
|
+
AND pc.reps >= 1 AND pc.blocked = 0)`
|
|
3798
|
+
).all(userId);
|
|
3799
|
+
if (readyCards.length === 0) break;
|
|
3800
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3801
|
+
const placeholders = readyCards.map(() => "?").join(",");
|
|
3802
|
+
await db.prepare(
|
|
3803
|
+
`UPDATE cards SET blocked = 0, due_at = ?
|
|
3804
|
+
WHERE user_id = ? AND token_id IN (${placeholders})`
|
|
3805
|
+
).run(now, userId, ...readyCards.map((card) => card.token_id));
|
|
3806
|
+
for (const card of readyCards) {
|
|
3791
3807
|
unblocked.push({ slug: card.slug, concept: card.concept });
|
|
3792
3808
|
}
|
|
3793
3809
|
}
|
|
@@ -3949,10 +3965,14 @@ async function prepareSessionSynthesis(db, input) {
|
|
|
3949
3965
|
await buildSkillPatterns(db),
|
|
3950
3966
|
input.explicitPatterns ?? []
|
|
3951
3967
|
);
|
|
3968
|
+
const patternTokens = await getTokensBySlugs(
|
|
3969
|
+
db,
|
|
3970
|
+
patterns.map((pattern) => pattern.slug)
|
|
3971
|
+
);
|
|
3952
3972
|
const validPatterns = [];
|
|
3953
3973
|
const tokens = /* @__PURE__ */ new Map();
|
|
3954
3974
|
for (const pattern of patterns) {
|
|
3955
|
-
const token =
|
|
3975
|
+
const token = patternTokens.get(pattern.slug);
|
|
3956
3976
|
if (!token || token.deprecated_at) continue;
|
|
3957
3977
|
validPatterns.push(pattern);
|
|
3958
3978
|
tokens.set(pattern.slug, token);
|
|
@@ -3965,13 +3985,13 @@ async function prepareSessionSynthesis(db, input) {
|
|
|
3965
3985
|
const minConfidence = input.minConfidence ?? "medium";
|
|
3966
3986
|
if (session.execution_context === "ui") {
|
|
3967
3987
|
const reports = readUiObservationLog(input.sessionId);
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3988
|
+
const candidateTokens = await getTokensBySlugs(
|
|
3989
|
+
db,
|
|
3990
|
+
reports.flatMap((report) => report.candidateTokens).map((candidate) => candidate.slug).filter((slug) => !tokens.has(slug))
|
|
3991
|
+
);
|
|
3992
|
+
for (const [slug, token] of candidateTokens) {
|
|
3993
|
+
if (!token.deprecated_at) {
|
|
3994
|
+
tokens.set(slug, token);
|
|
3975
3995
|
}
|
|
3976
3996
|
}
|
|
3977
3997
|
const { candidates: candidates2, skippedLowConfidence: skippedLowConfidence2 } = buildUiSynthesisCandidates(
|