zam-core 0.9.2 → 0.9.4
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/cli/app.js +106 -40
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/commands/mcp.js +105 -39
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +90 -33
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -864,6 +864,11 @@ declare function deleteSetting(db: Database, key: string): Promise<boolean>;
|
|
|
864
864
|
|
|
865
865
|
type BloomLevel$1 = 1 | 2 | 3 | 4 | 5;
|
|
866
866
|
type SymbiosisMode = "shadowing" | "copilot" | "autonomy";
|
|
867
|
+
/**
|
|
868
|
+
* Who authored a token's current recall question. LLM healing only
|
|
869
|
+
* overwrites questions whose source is not 'manual'.
|
|
870
|
+
*/
|
|
871
|
+
type QuestionSource = "manual" | "llm" | "template";
|
|
867
872
|
interface Token {
|
|
868
873
|
id: string;
|
|
869
874
|
slug: string;
|
|
@@ -875,6 +880,7 @@ interface Token {
|
|
|
875
880
|
symbiosis_mode: SymbiosisMode | null;
|
|
876
881
|
source_link: string | null;
|
|
877
882
|
question: string | null;
|
|
883
|
+
question_source: QuestionSource;
|
|
878
884
|
created_at: string;
|
|
879
885
|
updated_at: string;
|
|
880
886
|
deprecated_at: string | null;
|
|
@@ -891,6 +897,7 @@ interface CreateTokenInput {
|
|
|
891
897
|
symbiosis_mode?: SymbiosisMode | null;
|
|
892
898
|
source_link?: string | null;
|
|
893
899
|
question?: string | null;
|
|
900
|
+
question_source?: QuestionSource;
|
|
894
901
|
provider?: string | null;
|
|
895
902
|
topic_id?: string | null;
|
|
896
903
|
}
|
|
@@ -903,6 +910,7 @@ interface UpdateTokenInput {
|
|
|
903
910
|
symbiosis_mode?: SymbiosisMode | null;
|
|
904
911
|
source_link?: string | null;
|
|
905
912
|
question?: string | null;
|
|
913
|
+
question_source?: QuestionSource;
|
|
906
914
|
provider?: string | null;
|
|
907
915
|
topic_id?: string | null;
|
|
908
916
|
}
|
|
@@ -1479,6 +1487,9 @@ declare function cascadeBlock(db: Database, userId: string, tokenSlug: string):
|
|
|
1479
1487
|
* If a blocked card has no prerequisites at all, it is unblocked immediately
|
|
1480
1488
|
* (it was likely blocked in error or its prerequisites were removed).
|
|
1481
1489
|
*
|
|
1490
|
+
* Unblocking cascades: when unblocking a card satisfies the last unmet
|
|
1491
|
+
* prerequisite of another blocked card, that card unblocks in the same call.
|
|
1492
|
+
*
|
|
1482
1493
|
* @param db - Database connection
|
|
1483
1494
|
* @param userId - The user whose blocked cards to check
|
|
1484
1495
|
* @returns List of cards that were unblocked
|
|
@@ -1960,6 +1971,7 @@ interface ReviewQueueItem {
|
|
|
1960
1971
|
dueAt: string;
|
|
1961
1972
|
sourceLink: string | null;
|
|
1962
1973
|
question: string | null;
|
|
1974
|
+
questionSource: string;
|
|
1963
1975
|
}
|
|
1964
1976
|
interface ReviewQueue {
|
|
1965
1977
|
items: ReviewQueueItem[];
|
|
@@ -2334,4 +2346,4 @@ declare function resolveAllBeliefPaths(db: Database): Promise<string[]>;
|
|
|
2334
2346
|
*/
|
|
2335
2347
|
declare function resolveAllGoalPaths(db: Database): Promise<string[]>;
|
|
2336
2348
|
|
|
2337
|
-
export { type ADOConfig, type ADOCredentials, type AgentSkill, type AnalysisResult, type ApplySessionSynthesisInput, type ApplySessionSynthesisResult, BUILT_IN_SENSITIVE_MATCHERS, type BloomLevel$1 as BloomLevel, type CaptureDecision, type CaptureDenialReason, type CaptureRequest, type Card, type CardDeletionImpact, type CardState$1 as CardState, type CascadeBlockResult, type CommandRecord, type CommandSequence, type ConfirmFoundationsResult, type ConnectionOptions, type CreateAgentSkillInput, type CreateGoalInput, type CreateKnowledgeContextInput, type CreateReviewInput, type CreateSessionInput, type CreateTokenInput, type Credentials, type CurriculumCardInput, DEFAULT_OBSERVER_POLICY, DEFAULT_REVIEW_CONTEXT_MAX_CHARS, type Database, type DatabaseProvider, type DatabaseTargetInfo, type DatabaseValue, type DeleteCardResult, type DeleteTokenResult, type DiscoveryOptions, type DomainCompetence, type EmbeddedTokenRow, type EmbeddingCoverage, type EmbeddingStaleness, type EvaluateInput, type EvaluateResult, type ExecuteReviewActionInput, type ExecutionContext, type FSRSParameters, type FoundationProposalInput, type FoundationSuggestion, type Goal, type GoalFrontmatter, type GoalStatus, type GoalSummary, HOMEBREW_CASK, type HybridScoredToken, type HybridSearchOptions, type ImportCurriculumResult, type ImportResult, type InstallChannel, type InstallConfig, type InstallMode, type InstallPlan, type InstallResult, type KnowledgeContext, type ListTokensOptions, type LocalLLMRunner, type LogStepInput, type MachineAiConfig, type MachineProviderRecord, type MachineRoleBinding, type MonitorEvent, type Neighborhood, type NeighborhoodToken, OBSERVER_POLICY_UNSET_HINT, OBSERVER_POLICY_VERSION, type ObservationRating, type ObserverConsent, type ObserverPolicy, type ObserverRetention, type ObserverScope, type ObserverSettingKey, type OllamaDetectionOptions, type PersonalCard, type PrepareSessionSynthesisInput, type Prerequisite, type PrerequisiteWithToken, type PromptInput, REVIEW_CONTEXT_CACHE_TTL_MS, type Rating, type RecallPrompt, type RemoteDatabaseOptions, type RepoPaths, type ResolvedCaptureTarget, type ResolvedReference, type ReviewActionResult, type ReviewActionType, type ReviewContext, type ReviewLog, type ReviewQueue, type ReviewQueueItem, type ReviewQueueOptions, type RunResult, SIDECAR_POLICY_FILE, SNAPSHOT_VERSION, type SchedulingCard, type Session, type SessionStep, type SessionSummary, type SessionSynthesisCandidate, type SessionSynthesisEvidence, type SessionSynthesisPreview, type SessionSynthesisRecord, type SidecarPrivacyPolicy, type SkillProposal, type SkillSource, type SnapshotManifest, type SourceProposalInput, type SplitProposalInput, type Statement, type SuggestFoundationsOptions, type SupportedLocale, type SymbiosisMode, type SynthesisConfidence, type SystemProfile, type Token, type TokenDeleteImpact, type TokenEmbedding, type TokenNeedingEmbedding, type TokenPattern, type TranslationKey, type TursoCredentials, UI_OBSERVATION_PROTOCOL_VERSION, type UiActionType, type UiApplicationContext, type UiCandidateToken, type UiEvidenceRef, type UiEvidenceType, type UiObservationKind, type UiObservationReport, type UiObservedAction, type UnblockResult, type UpdateActionKind, type UpdateCardInput, type UpdateDecision, type UpdateKnowledgeContextInput, type UpdateStep, type UpdateStepKind, type UpdateTokenInput, type UserSetting, type UserStats, WINGET_PACKAGE_ID, type WorkItem, type WorkspaceConfig, type WorkspaceKind, type WorkspaceSourceControl, addPrerequisite, analyzeObservation, appendUiObservationReport, applySessionSynthesis, assignTokenToContext, buildAncestorMap, buildReviewQueue, buildUiSynthesisCandidates, cascadeBlock, clearADOCredentials, clearProviderApiKey, clearReviewContextCache, clearTursoCredentials, compareVersions, computeContentHash, confirmCardSplit, confirmFoundations, confirmSourceImport, cosineSimilarity, createAgentSkill, createFSRS, createGoal, createKnowledgeContext, createToken, decidePostCapture, decidePreCapture, decideUpdate, decodeEmbedding, deleteCardForUser, deleteKnowledgeContext, deleteSetting, deleteToken, deprecateToken, detectSyncProvider, detectSystemLocale, discoverSkills, distributeGlobalSkills, embeddingContentForToken, encodeEmbedding, endSession, ensureCard, ensureMonitorDir, ensureUiObserverDir, evaluateRating, executeReviewAction, exportSnapshot, extractTasks, extractTokenRefs, fetchActiveWorkItems, findTokens, generateBashHooks, generateBashUnhooks, generateConceptFreeCue, generatePowerShellHooks, generatePowerShellUnhooks, generatePrompt, generateTokenSlug, generateZshHooks, generateZshUnhooks, getADOCredentials, getActiveWorkspace, getActiveWorkspaceContext, getActiveWorkspaceId, getAgentSkill, getAllSettings, getAllSettingsDetailed, getBlockedCards, getCard, getCardById, getCardDeletionImpact, getConfiguredWorkspaces, getDatabaseTargetInfo, getDefaultDbPath, getDependents, getDisplayTitle, getDomainCompetence, getDueCards, getEmbeddingCoverage, getGoal, getGoalTree, getInstallChannel, getInstallMode, getKnowledgeContextById, getKnowledgeContextByName, getMachineAiConfig, getMonitorDir, getMonitorLogStats, getMonitorPath, getPackageSkillPath, getPrerequisites, getProviderApiKey, getRepoPaths, getReviewsForCard, getReviewsForUser, getSessionSummary, getSessionSynthesisRecords, getSetting, getShortSlug, getSystemProfile, getTokenById, getTokenBySlug, getTokenDeleteImpact, getTokenEmbedding, getTokenNeighborhood, getTursoCredentials, getUiObservationPath, getUiObserverDir, getUserStats, hasCommand, importCurriculumCards, importSnapshot, injectShellHooks, installFastFlowLM, installOllama, installOpenCode, interleave, isObserverPolicyConfigured, isOllamaInstalled, isUiObservationReport, listAgentSkills, listContextsForToken, listEmbeddedTokens, listGoals, listKnowledgeContexts, listPersonalCards, listProviderApiKeyRefs, listTokens, listTokensNeedingEmbedding, loadADOConfig, loadCredentials, loadInstallConfig, logReview, logStep, matchBuiltInSensitive, matchDenylist, matchesFilePath, monitorLogExists, normalizeLocale, normalizePath, openDatabase, openDatabaseWithSync, openRemoteDatabase, pairCommands, parseGoalFile, parseMonitorLog, parseObserverList, parseObserverPolicy, parseSnapshot, parseUiObservationLog, planOpenCodeInstall, planUpdate, prepareLocalModel, prepareSessionSynthesis, readMonitorLog, readUiObservationLog, removeConfiguredWorkspace, resolveAllBeliefPaths, resolveAllGoalPaths, resolveObserverPolicy, resolveOllamaCommand, resolveReference, resolveRepoPath, resolveReviewContext, saveConfiguredWorkspaces, saveCredentials, saveInstallConfig, saveMachineAiConfig, searchTokensHybrid, serializeGoal, setADOCredentials, setActiveWorkspaceContext, setActiveWorkspaceId, setInstallChannel, setInstallMode, setProviderApiKey, setSetting, setTursoCredentials, slugify, startSession, suggestFoundations, syncObserverSidecarPolicy, t, toSidecarPrivacyPolicy, uiObservationLogExists, uiObservationTimeSpan, unassignTokenFromContext, unblockReady, updateCard, updateGoalStatus, updateKnowledgeContext, updateToken, upsertConfiguredWorkspace, upsertTokenEmbedding, verifySnapshot, wouldCreateCycle, writeMonitorEvent };
|
|
2349
|
+
export { type ADOConfig, type ADOCredentials, type AgentSkill, type AnalysisResult, type ApplySessionSynthesisInput, type ApplySessionSynthesisResult, BUILT_IN_SENSITIVE_MATCHERS, type BloomLevel$1 as BloomLevel, type CaptureDecision, type CaptureDenialReason, type CaptureRequest, type Card, type CardDeletionImpact, type CardState$1 as CardState, type CascadeBlockResult, type CommandRecord, type CommandSequence, type ConfirmFoundationsResult, type ConnectionOptions, type CreateAgentSkillInput, type CreateGoalInput, type CreateKnowledgeContextInput, type CreateReviewInput, type CreateSessionInput, type CreateTokenInput, type Credentials, type CurriculumCardInput, DEFAULT_OBSERVER_POLICY, DEFAULT_REVIEW_CONTEXT_MAX_CHARS, type Database, type DatabaseProvider, type DatabaseTargetInfo, type DatabaseValue, type DeleteCardResult, type DeleteTokenResult, type DiscoveryOptions, type DomainCompetence, type EmbeddedTokenRow, type EmbeddingCoverage, type EmbeddingStaleness, type EvaluateInput, type EvaluateResult, type ExecuteReviewActionInput, type ExecutionContext, type FSRSParameters, type FoundationProposalInput, type FoundationSuggestion, type Goal, type GoalFrontmatter, type GoalStatus, type GoalSummary, HOMEBREW_CASK, type HybridScoredToken, type HybridSearchOptions, type ImportCurriculumResult, type ImportResult, type InstallChannel, type InstallConfig, type InstallMode, type InstallPlan, type InstallResult, type KnowledgeContext, type ListTokensOptions, type LocalLLMRunner, type LogStepInput, type MachineAiConfig, type MachineProviderRecord, type MachineRoleBinding, type MonitorEvent, type Neighborhood, type NeighborhoodToken, OBSERVER_POLICY_UNSET_HINT, OBSERVER_POLICY_VERSION, type ObservationRating, type ObserverConsent, type ObserverPolicy, type ObserverRetention, type ObserverScope, type ObserverSettingKey, type OllamaDetectionOptions, type PersonalCard, type PrepareSessionSynthesisInput, type Prerequisite, type PrerequisiteWithToken, type PromptInput, type QuestionSource, REVIEW_CONTEXT_CACHE_TTL_MS, type Rating, type RecallPrompt, type RemoteDatabaseOptions, type RepoPaths, type ResolvedCaptureTarget, type ResolvedReference, type ReviewActionResult, type ReviewActionType, type ReviewContext, type ReviewLog, type ReviewQueue, type ReviewQueueItem, type ReviewQueueOptions, type RunResult, SIDECAR_POLICY_FILE, SNAPSHOT_VERSION, type SchedulingCard, type Session, type SessionStep, type SessionSummary, type SessionSynthesisCandidate, type SessionSynthesisEvidence, type SessionSynthesisPreview, type SessionSynthesisRecord, type SidecarPrivacyPolicy, type SkillProposal, type SkillSource, type SnapshotManifest, type SourceProposalInput, type SplitProposalInput, type Statement, type SuggestFoundationsOptions, type SupportedLocale, type SymbiosisMode, type SynthesisConfidence, type SystemProfile, type Token, type TokenDeleteImpact, type TokenEmbedding, type TokenNeedingEmbedding, type TokenPattern, type TranslationKey, type TursoCredentials, UI_OBSERVATION_PROTOCOL_VERSION, type UiActionType, type UiApplicationContext, type UiCandidateToken, type UiEvidenceRef, type UiEvidenceType, type UiObservationKind, type UiObservationReport, type UiObservedAction, type UnblockResult, type UpdateActionKind, type UpdateCardInput, type UpdateDecision, type UpdateKnowledgeContextInput, type UpdateStep, type UpdateStepKind, type UpdateTokenInput, type UserSetting, type UserStats, WINGET_PACKAGE_ID, type WorkItem, type WorkspaceConfig, type WorkspaceKind, type WorkspaceSourceControl, addPrerequisite, analyzeObservation, appendUiObservationReport, applySessionSynthesis, assignTokenToContext, buildAncestorMap, buildReviewQueue, buildUiSynthesisCandidates, cascadeBlock, clearADOCredentials, clearProviderApiKey, clearReviewContextCache, clearTursoCredentials, compareVersions, computeContentHash, confirmCardSplit, confirmFoundations, confirmSourceImport, cosineSimilarity, createAgentSkill, createFSRS, createGoal, createKnowledgeContext, createToken, decidePostCapture, decidePreCapture, decideUpdate, decodeEmbedding, deleteCardForUser, deleteKnowledgeContext, deleteSetting, deleteToken, deprecateToken, detectSyncProvider, detectSystemLocale, discoverSkills, distributeGlobalSkills, embeddingContentForToken, encodeEmbedding, endSession, ensureCard, ensureMonitorDir, ensureUiObserverDir, evaluateRating, executeReviewAction, exportSnapshot, extractTasks, extractTokenRefs, fetchActiveWorkItems, findTokens, generateBashHooks, generateBashUnhooks, generateConceptFreeCue, generatePowerShellHooks, generatePowerShellUnhooks, generatePrompt, generateTokenSlug, generateZshHooks, generateZshUnhooks, getADOCredentials, getActiveWorkspace, getActiveWorkspaceContext, getActiveWorkspaceId, getAgentSkill, getAllSettings, getAllSettingsDetailed, getBlockedCards, getCard, getCardById, getCardDeletionImpact, getConfiguredWorkspaces, getDatabaseTargetInfo, getDefaultDbPath, getDependents, getDisplayTitle, getDomainCompetence, getDueCards, getEmbeddingCoverage, getGoal, getGoalTree, getInstallChannel, getInstallMode, getKnowledgeContextById, getKnowledgeContextByName, getMachineAiConfig, getMonitorDir, getMonitorLogStats, getMonitorPath, getPackageSkillPath, getPrerequisites, getProviderApiKey, getRepoPaths, getReviewsForCard, getReviewsForUser, getSessionSummary, getSessionSynthesisRecords, getSetting, getShortSlug, getSystemProfile, getTokenById, getTokenBySlug, getTokenDeleteImpact, getTokenEmbedding, getTokenNeighborhood, getTursoCredentials, getUiObservationPath, getUiObserverDir, getUserStats, hasCommand, importCurriculumCards, importSnapshot, injectShellHooks, installFastFlowLM, installOllama, installOpenCode, interleave, isObserverPolicyConfigured, isOllamaInstalled, isUiObservationReport, listAgentSkills, listContextsForToken, listEmbeddedTokens, listGoals, listKnowledgeContexts, listPersonalCards, listProviderApiKeyRefs, listTokens, listTokensNeedingEmbedding, loadADOConfig, loadCredentials, loadInstallConfig, logReview, logStep, matchBuiltInSensitive, matchDenylist, matchesFilePath, monitorLogExists, normalizeLocale, normalizePath, openDatabase, openDatabaseWithSync, openRemoteDatabase, pairCommands, parseGoalFile, parseMonitorLog, parseObserverList, parseObserverPolicy, parseSnapshot, parseUiObservationLog, planOpenCodeInstall, planUpdate, prepareLocalModel, prepareSessionSynthesis, readMonitorLog, readUiObservationLog, removeConfiguredWorkspace, resolveAllBeliefPaths, resolveAllGoalPaths, resolveObserverPolicy, resolveOllamaCommand, resolveReference, resolveRepoPath, resolveReviewContext, saveConfiguredWorkspaces, saveCredentials, saveInstallConfig, saveMachineAiConfig, searchTokensHybrid, serializeGoal, setADOCredentials, setActiveWorkspaceContext, setActiveWorkspaceId, setInstallChannel, setInstallMode, setProviderApiKey, setSetting, setTursoCredentials, slugify, startSession, suggestFoundations, syncObserverSidecarPolicy, t, toSidecarPrivacyPolicy, uiObservationLogExists, uiObservationTimeSpan, unassignTokenFromContext, unblockReady, updateCard, updateGoalStatus, updateKnowledgeContext, updateToken, upsertConfiguredWorkspace, upsertTokenEmbedding, verifySnapshot, wouldCreateCycle, writeMonitorEvent };
|
package/dist/index.js
CHANGED
|
@@ -542,7 +542,12 @@ CREATE TABLE IF NOT EXISTS tokens (
|
|
|
542
542
|
deprecated_at TEXT,
|
|
543
543
|
question TEXT,
|
|
544
544
|
provider TEXT,
|
|
545
|
-
topic_id TEXT
|
|
545
|
+
topic_id TEXT,
|
|
546
|
+
-- Who authored the current question ('manual' | 'llm' | 'template');
|
|
547
|
+
-- validated in code, not via CHECK. Column default is 'llm' so unlabeled
|
|
548
|
+
-- writes (pre-M013 rows, old snapshot restores) count as LLM-era content;
|
|
549
|
+
-- createToken() defaults to 'manual' for API callers instead.
|
|
550
|
+
question_source TEXT NOT NULL DEFAULT 'llm'
|
|
546
551
|
);
|
|
547
552
|
|
|
548
553
|
-- Prerequisite dependency graph: "to learn A, first know B"
|
|
@@ -1058,6 +1063,11 @@ async function runMigrations(db) {
|
|
|
1058
1063
|
await db.exec(`
|
|
1059
1064
|
CREATE INDEX IF NOT EXISTS idx_token_contexts_context ON token_contexts(context_id)
|
|
1060
1065
|
`);
|
|
1066
|
+
if (tokenCols.length > 0 && !tokenCols.some((c) => c.name === "question_source")) {
|
|
1067
|
+
await db.exec(
|
|
1068
|
+
`ALTER TABLE tokens ADD COLUMN question_source TEXT NOT NULL DEFAULT 'llm'`
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1061
1071
|
}
|
|
1062
1072
|
|
|
1063
1073
|
// src/kernel/db/snapshot.ts
|
|
@@ -1074,7 +1084,11 @@ var SNAPSHOT_TABLES = [
|
|
|
1074
1084
|
"review_logs",
|
|
1075
1085
|
"session_syntheses",
|
|
1076
1086
|
"user_config",
|
|
1077
|
-
"agent_skills"
|
|
1087
|
+
"agent_skills",
|
|
1088
|
+
"sources",
|
|
1089
|
+
"token_sources",
|
|
1090
|
+
"contexts",
|
|
1091
|
+
"token_contexts"
|
|
1078
1092
|
];
|
|
1079
1093
|
function quoteValue(value) {
|
|
1080
1094
|
if (value === null || value === void 0) return "NULL";
|
|
@@ -1660,6 +1674,14 @@ async function listContextsForToken(db, tokenId) {
|
|
|
1660
1674
|
|
|
1661
1675
|
// src/kernel/models/token.ts
|
|
1662
1676
|
import { ulid as ulid4 } from "ulid";
|
|
1677
|
+
var VALID_QUESTION_SOURCES = ["manual", "llm", "template"];
|
|
1678
|
+
function validateQuestionSource(value) {
|
|
1679
|
+
if (!VALID_QUESTION_SOURCES.includes(value)) {
|
|
1680
|
+
throw new Error(
|
|
1681
|
+
`Invalid question_source: ${value} (expected one of ${VALID_QUESTION_SOURCES.join(", ")})`
|
|
1682
|
+
);
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1663
1685
|
async function createToken(db, input) {
|
|
1664
1686
|
const id = ulid4();
|
|
1665
1687
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -1668,9 +1690,11 @@ async function createToken(db, input) {
|
|
|
1668
1690
|
throw new Error(`bloom_level must be between 1 and 5, got ${bloom}`);
|
|
1669
1691
|
}
|
|
1670
1692
|
const title = input.title ?? "";
|
|
1693
|
+
const questionSource = input.question_source ?? "manual";
|
|
1694
|
+
validateQuestionSource(questionSource);
|
|
1671
1695
|
await db.prepare(`
|
|
1672
|
-
INSERT INTO tokens (id, slug, title, concept, domain, bloom_level, context, symbiosis_mode, source_link, question, provider, topic_id, created_at, updated_at)
|
|
1673
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1696
|
+
INSERT INTO tokens (id, slug, title, concept, domain, bloom_level, context, symbiosis_mode, source_link, question, question_source, provider, topic_id, created_at, updated_at)
|
|
1697
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1674
1698
|
`).run(
|
|
1675
1699
|
id,
|
|
1676
1700
|
input.slug,
|
|
@@ -1682,6 +1706,7 @@ async function createToken(db, input) {
|
|
|
1682
1706
|
input.symbiosis_mode ?? null,
|
|
1683
1707
|
input.source_link ?? null,
|
|
1684
1708
|
input.question ?? null,
|
|
1709
|
+
questionSource,
|
|
1685
1710
|
input.provider ?? null,
|
|
1686
1711
|
input.topic_id ?? null,
|
|
1687
1712
|
now,
|
|
@@ -1705,6 +1730,18 @@ async function getTokenBySlug(db, slug) {
|
|
|
1705
1730
|
parseTokenFallback(token);
|
|
1706
1731
|
return token;
|
|
1707
1732
|
}
|
|
1733
|
+
async function getTokensBySlugs(db, slugs) {
|
|
1734
|
+
const tokens = /* @__PURE__ */ new Map();
|
|
1735
|
+
const unique = [...new Set(slugs)];
|
|
1736
|
+
if (unique.length === 0) return tokens;
|
|
1737
|
+
const placeholders = unique.map(() => "?").join(",");
|
|
1738
|
+
const rows = await db.prepare(`SELECT * FROM tokens WHERE slug IN (${placeholders})`).all(...unique);
|
|
1739
|
+
for (const token of rows) {
|
|
1740
|
+
parseTokenFallback(token);
|
|
1741
|
+
tokens.set(token.slug, token);
|
|
1742
|
+
}
|
|
1743
|
+
return tokens;
|
|
1744
|
+
}
|
|
1708
1745
|
async function getTokenById(db, id) {
|
|
1709
1746
|
const token = await db.prepare("SELECT * FROM tokens WHERE id = ?").get(id);
|
|
1710
1747
|
parseTokenFallback(token);
|
|
@@ -1758,6 +1795,12 @@ async function updateToken(db, slug, updates) {
|
|
|
1758
1795
|
fields.push("question = ?");
|
|
1759
1796
|
values.push(updates.question);
|
|
1760
1797
|
}
|
|
1798
|
+
const questionSource = updates.question_source ?? (updates.question !== void 0 ? "manual" : void 0);
|
|
1799
|
+
if (questionSource !== void 0) {
|
|
1800
|
+
validateQuestionSource(questionSource);
|
|
1801
|
+
fields.push("question_source = ?");
|
|
1802
|
+
values.push(questionSource);
|
|
1803
|
+
}
|
|
1761
1804
|
if (updates.provider !== void 0) {
|
|
1762
1805
|
fields.push("provider = ?");
|
|
1763
1806
|
values.push(updates.provider);
|
|
@@ -2086,6 +2129,9 @@ async function importCurriculumCards(db, userId, cards) {
|
|
|
2086
2129
|
symbiosis_mode: symbiosisMode,
|
|
2087
2130
|
source_link: card.source_link || null,
|
|
2088
2131
|
question: card.question || null,
|
|
2132
|
+
// Curriculum cards are LLM-extracted; their questions are LLM
|
|
2133
|
+
// inventions, not human-authored content.
|
|
2134
|
+
question_source: "llm",
|
|
2089
2135
|
provider: card.provider || null,
|
|
2090
2136
|
topic_id: card.topic_id || null
|
|
2091
2137
|
});
|
|
@@ -3769,25 +3815,29 @@ async function cascadeBlock(db, userId, tokenSlug) {
|
|
|
3769
3815
|
};
|
|
3770
3816
|
}
|
|
3771
3817
|
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
3818
|
const unblocked = [];
|
|
3779
|
-
for (
|
|
3780
|
-
const
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
JOIN
|
|
3784
|
-
WHERE
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3819
|
+
for (; ; ) {
|
|
3820
|
+
const readyCards = await db.prepare(
|
|
3821
|
+
`SELECT c.token_id, t.slug, t.concept
|
|
3822
|
+
FROM cards c
|
|
3823
|
+
JOIN tokens t ON t.id = c.token_id
|
|
3824
|
+
WHERE c.user_id = ? AND c.blocked = 1
|
|
3825
|
+
AND (SELECT COUNT(*) FROM prerequisites p
|
|
3826
|
+
WHERE p.token_id = c.token_id) =
|
|
3827
|
+
(SELECT COUNT(*) FROM prerequisites p
|
|
3828
|
+
JOIN cards pc ON pc.token_id = p.requires_id
|
|
3829
|
+
AND pc.user_id = c.user_id
|
|
3830
|
+
WHERE p.token_id = c.token_id
|
|
3831
|
+
AND pc.reps >= 1 AND pc.blocked = 0)`
|
|
3832
|
+
).all(userId);
|
|
3833
|
+
if (readyCards.length === 0) break;
|
|
3834
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3835
|
+
const placeholders = readyCards.map(() => "?").join(",");
|
|
3836
|
+
await db.prepare(
|
|
3837
|
+
`UPDATE cards SET blocked = 0, due_at = ?
|
|
3838
|
+
WHERE user_id = ? AND token_id IN (${placeholders})`
|
|
3839
|
+
).run(now, userId, ...readyCards.map((card) => card.token_id));
|
|
3840
|
+
for (const card of readyCards) {
|
|
3791
3841
|
unblocked.push({ slug: card.slug, concept: card.concept });
|
|
3792
3842
|
}
|
|
3793
3843
|
}
|
|
@@ -3949,10 +3999,14 @@ async function prepareSessionSynthesis(db, input) {
|
|
|
3949
3999
|
await buildSkillPatterns(db),
|
|
3950
4000
|
input.explicitPatterns ?? []
|
|
3951
4001
|
);
|
|
4002
|
+
const patternTokens = await getTokensBySlugs(
|
|
4003
|
+
db,
|
|
4004
|
+
patterns.map((pattern) => pattern.slug)
|
|
4005
|
+
);
|
|
3952
4006
|
const validPatterns = [];
|
|
3953
4007
|
const tokens = /* @__PURE__ */ new Map();
|
|
3954
4008
|
for (const pattern of patterns) {
|
|
3955
|
-
const token =
|
|
4009
|
+
const token = patternTokens.get(pattern.slug);
|
|
3956
4010
|
if (!token || token.deprecated_at) continue;
|
|
3957
4011
|
validPatterns.push(pattern);
|
|
3958
4012
|
tokens.set(pattern.slug, token);
|
|
@@ -3965,13 +4019,13 @@ async function prepareSessionSynthesis(db, input) {
|
|
|
3965
4019
|
const minConfidence = input.minConfidence ?? "medium";
|
|
3966
4020
|
if (session.execution_context === "ui") {
|
|
3967
4021
|
const reports = readUiObservationLog(input.sessionId);
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
4022
|
+
const candidateTokens = await getTokensBySlugs(
|
|
4023
|
+
db,
|
|
4024
|
+
reports.flatMap((report) => report.candidateTokens).map((candidate) => candidate.slug).filter((slug) => !tokens.has(slug))
|
|
4025
|
+
);
|
|
4026
|
+
for (const [slug, token] of candidateTokens) {
|
|
4027
|
+
if (!token.deprecated_at) {
|
|
4028
|
+
tokens.set(slug, token);
|
|
3975
4029
|
}
|
|
3976
4030
|
}
|
|
3977
4031
|
const { candidates: candidates2, skippedLowConfidence: skippedLowConfidence2 } = buildUiSynthesisCandidates(
|
|
@@ -4881,7 +4935,8 @@ async function buildReviewQueue(db, options) {
|
|
|
4881
4935
|
c.state AS state,
|
|
4882
4936
|
c.due_at AS due_at,
|
|
4883
4937
|
t.source_link AS source_link,
|
|
4884
|
-
t.question AS question
|
|
4938
|
+
t.question AS question,
|
|
4939
|
+
t.question_source AS question_source
|
|
4885
4940
|
FROM cards c
|
|
4886
4941
|
JOIN tokens t ON t.id = c.token_id
|
|
4887
4942
|
WHERE c.user_id = ?
|
|
@@ -4911,7 +4966,8 @@ async function buildReviewQueue(db, options) {
|
|
|
4911
4966
|
c.state AS state,
|
|
4912
4967
|
c.due_at AS due_at,
|
|
4913
4968
|
t.source_link AS source_link,
|
|
4914
|
-
t.question AS question
|
|
4969
|
+
t.question AS question,
|
|
4970
|
+
t.question_source AS question_source
|
|
4915
4971
|
FROM cards c
|
|
4916
4972
|
JOIN tokens t ON t.id = c.token_id
|
|
4917
4973
|
WHERE c.user_id = ?
|
|
@@ -4980,7 +5036,8 @@ function rowToItem(row) {
|
|
|
4980
5036
|
state: row.state,
|
|
4981
5037
|
dueAt: row.due_at,
|
|
4982
5038
|
sourceLink: row.source_link,
|
|
4983
|
-
question: row.question
|
|
5039
|
+
question: row.question,
|
|
5040
|
+
questionSource: row.question_source
|
|
4984
5041
|
};
|
|
4985
5042
|
}
|
|
4986
5043
|
function intersperseNew(reviews, newCards, interval) {
|