zam-core 0.7.1 → 0.7.2
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/index.js +912 -113
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +31 -2
- package/dist/index.js +80 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -562,6 +562,7 @@ interface Prerequisite {
|
|
|
562
562
|
/** A prerequisite row joined with the token it points to. */
|
|
563
563
|
interface PrerequisiteWithToken extends Prerequisite {
|
|
564
564
|
slug: string;
|
|
565
|
+
title: string;
|
|
565
566
|
concept: string;
|
|
566
567
|
domain: string;
|
|
567
568
|
bloom_level: number;
|
|
@@ -603,6 +604,7 @@ declare function getDependents(db: Database, tokenId: string): Promise<Prerequis
|
|
|
603
604
|
interface NeighborhoodToken {
|
|
604
605
|
id: string;
|
|
605
606
|
slug: string;
|
|
607
|
+
title: string;
|
|
606
608
|
concept: string;
|
|
607
609
|
domain: string;
|
|
608
610
|
bloom_level: number;
|
|
@@ -802,6 +804,7 @@ type SymbiosisMode = "shadowing" | "copilot" | "autonomy";
|
|
|
802
804
|
interface Token {
|
|
803
805
|
id: string;
|
|
804
806
|
slug: string;
|
|
807
|
+
title: string;
|
|
805
808
|
concept: string;
|
|
806
809
|
domain: string;
|
|
807
810
|
bloom_level: BloomLevel$1;
|
|
@@ -817,6 +820,7 @@ interface Token {
|
|
|
817
820
|
}
|
|
818
821
|
interface CreateTokenInput {
|
|
819
822
|
slug: string;
|
|
823
|
+
title?: string;
|
|
820
824
|
concept: string;
|
|
821
825
|
domain?: string;
|
|
822
826
|
bloom_level?: BloomLevel$1;
|
|
@@ -828,6 +832,7 @@ interface CreateTokenInput {
|
|
|
828
832
|
topic_id?: string | null;
|
|
829
833
|
}
|
|
830
834
|
interface UpdateTokenInput {
|
|
835
|
+
title?: string | null;
|
|
831
836
|
concept?: string;
|
|
832
837
|
domain?: string;
|
|
833
838
|
bloom_level?: BloomLevel$1;
|
|
@@ -840,6 +845,11 @@ interface UpdateTokenInput {
|
|
|
840
845
|
}
|
|
841
846
|
interface ListTokensOptions {
|
|
842
847
|
domain?: string;
|
|
848
|
+
/**
|
|
849
|
+
* Filter by domain prefix using `/` as separator (e.g. "docuware-cops").
|
|
850
|
+
* Matches exact or startsWith(prefix + "/").
|
|
851
|
+
*/
|
|
852
|
+
domainPrefix?: string;
|
|
843
853
|
}
|
|
844
854
|
interface TokenDeleteImpact {
|
|
845
855
|
cards: number;
|
|
@@ -915,6 +925,7 @@ declare function listTokens(db: Database, options?: ListTokensOptions): Promise<
|
|
|
915
925
|
interface PersonalCard {
|
|
916
926
|
tokenId: string;
|
|
917
927
|
slug: string;
|
|
928
|
+
title: string;
|
|
918
929
|
concept: string;
|
|
919
930
|
domain: string;
|
|
920
931
|
bloomLevel: BloomLevel$1;
|
|
@@ -938,6 +949,18 @@ interface PersonalCard {
|
|
|
938
949
|
topicId: string | null;
|
|
939
950
|
}
|
|
940
951
|
declare function slugify(text: string): string;
|
|
952
|
+
/**
|
|
953
|
+
* Strip domain prefix (using / separator) from slug for display.
|
|
954
|
+
*/
|
|
955
|
+
declare function getShortSlug(slug: string, domainPrefix?: string | null): string;
|
|
956
|
+
/**
|
|
957
|
+
* Primary display name for a token: human title if present, else short slug.
|
|
958
|
+
* Never falls back to concept (which is a spoiler).
|
|
959
|
+
*/
|
|
960
|
+
declare function getDisplayTitle(t: {
|
|
961
|
+
title?: string | null;
|
|
962
|
+
slug: string;
|
|
963
|
+
}, activeDomainScope?: string | null): string;
|
|
941
964
|
declare function generateTokenSlug(db: Database, domain: string, concept: string, question?: string | null): Promise<string>;
|
|
942
965
|
declare function listPersonalCards(db: Database, userId: string, options?: {
|
|
943
966
|
query?: string;
|
|
@@ -946,6 +969,7 @@ declare function listPersonalCards(db: Database, userId: string, options?: {
|
|
|
946
969
|
interface CurriculumCardInput {
|
|
947
970
|
question: string;
|
|
948
971
|
concept: string;
|
|
972
|
+
title?: string;
|
|
949
973
|
domain: string;
|
|
950
974
|
source_link?: string | null;
|
|
951
975
|
context?: string;
|
|
@@ -982,6 +1006,7 @@ interface FoundationProposalInput {
|
|
|
982
1006
|
question: string;
|
|
983
1007
|
concept: string;
|
|
984
1008
|
domain: string;
|
|
1009
|
+
title?: string;
|
|
985
1010
|
context?: string;
|
|
986
1011
|
bloom_level?: number;
|
|
987
1012
|
symbiosis_mode?: string | null;
|
|
@@ -1002,6 +1027,7 @@ interface SourceProposalInput {
|
|
|
1002
1027
|
question: string;
|
|
1003
1028
|
concept: string;
|
|
1004
1029
|
domain: string;
|
|
1030
|
+
title?: string;
|
|
1005
1031
|
bloom_level: number;
|
|
1006
1032
|
symbiosis_mode: string;
|
|
1007
1033
|
excerpt: string;
|
|
@@ -1054,7 +1080,9 @@ interface EmbeddedTokenRow {
|
|
|
1054
1080
|
* vector derives from exactly this string — never the slug, which is an
|
|
1055
1081
|
* identifier, not meaning.
|
|
1056
1082
|
*/
|
|
1057
|
-
declare function embeddingContentForToken(t: Pick<Token, "concept" | "question" | "domain">
|
|
1083
|
+
declare function embeddingContentForToken(t: Pick<Token, "concept" | "question" | "domain"> & {
|
|
1084
|
+
title?: string | null;
|
|
1085
|
+
}): string;
|
|
1058
1086
|
declare function computeContentHash(text: string): string;
|
|
1059
1087
|
/**
|
|
1060
1088
|
* Encode a vector as a little-endian float32 BLOB. Builds a fresh buffer (no
|
|
@@ -1855,6 +1883,7 @@ interface ReviewQueueItem {
|
|
|
1855
1883
|
cardId: string;
|
|
1856
1884
|
tokenId: string;
|
|
1857
1885
|
slug: string;
|
|
1886
|
+
title: string;
|
|
1858
1887
|
concept: string;
|
|
1859
1888
|
domain: string;
|
|
1860
1889
|
bloomLevel: number;
|
|
@@ -2233,4 +2262,4 @@ declare function resolveAllBeliefPaths(db: Database): Promise<string[]>;
|
|
|
2233
2262
|
*/
|
|
2234
2263
|
declare function resolveAllGoalPaths(db: Database): Promise<string[]>;
|
|
2235
2264
|
|
|
2236
|
-
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 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 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 UpdateStep, type UpdateStepKind, type UpdateTokenInput, type UserSetting, type UserStats, WINGET_PACKAGE_ID, type WorkItem, type WorkspaceConfig, type WorkspaceKind, type WorkspaceSourceControl, addPrerequisite, analyzeObservation, appendUiObservationReport, applySessionSynthesis, buildAncestorMap, buildReviewQueue, buildUiSynthesisCandidates, cascadeBlock, clearADOCredentials, clearProviderApiKey, clearReviewContextCache, clearTursoCredentials, compareVersions, computeContentHash, confirmCardSplit, confirmFoundations, confirmSourceImport, cosineSimilarity, createAgentSkill, createFSRS, createGoal, createToken, decidePostCapture, decidePreCapture, decideUpdate, decodeEmbedding, deleteCardForUser, 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, getActiveWorkspaceId, getAgentSkill, getAllSettings, getAllSettingsDetailed, getBlockedCards, getCard, getCardById, getCardDeletionImpact, getConfiguredWorkspaces, getDatabaseTargetInfo, getDefaultDbPath, getDependents, getDomainCompetence, getDueCards, getEmbeddingCoverage, getGoal, getGoalTree, getInstallChannel, getInstallMode, getMachineAiConfig, getMonitorDir, getMonitorLogStats, getMonitorPath, getPackageSkillPath, getPrerequisites, getProviderApiKey, getRepoPaths, getReviewsForCard, getReviewsForUser, getSessionSummary, getSessionSynthesisRecords, getSetting, getSystemProfile, getTokenById, getTokenBySlug, getTokenDeleteImpact, getTokenEmbedding, getTokenNeighborhood, getTursoCredentials, getUiObservationPath, getUiObserverDir, getUserStats, hasCommand, importCurriculumCards, importSnapshot, injectShellHooks, installFastFlowLM, installOllama, installOpenCode, interleave, isObserverPolicyConfigured, isOllamaInstalled, isUiObservationReport, listAgentSkills, listEmbeddedTokens, listGoals, 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, setActiveWorkspaceId, setInstallChannel, setInstallMode, setProviderApiKey, setSetting, setTursoCredentials, slugify, startSession, suggestFoundations, syncObserverSidecarPolicy, t, toSidecarPrivacyPolicy, uiObservationLogExists, uiObservationTimeSpan, unblockReady, updateCard, updateGoalStatus, updateToken, upsertConfiguredWorkspace, upsertTokenEmbedding, verifySnapshot, wouldCreateCycle, writeMonitorEvent };
|
|
2265
|
+
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 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 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 UpdateStep, type UpdateStepKind, type UpdateTokenInput, type UserSetting, type UserStats, WINGET_PACKAGE_ID, type WorkItem, type WorkspaceConfig, type WorkspaceKind, type WorkspaceSourceControl, addPrerequisite, analyzeObservation, appendUiObservationReport, applySessionSynthesis, buildAncestorMap, buildReviewQueue, buildUiSynthesisCandidates, cascadeBlock, clearADOCredentials, clearProviderApiKey, clearReviewContextCache, clearTursoCredentials, compareVersions, computeContentHash, confirmCardSplit, confirmFoundations, confirmSourceImport, cosineSimilarity, createAgentSkill, createFSRS, createGoal, createToken, decidePostCapture, decidePreCapture, decideUpdate, decodeEmbedding, deleteCardForUser, 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, getActiveWorkspaceId, getAgentSkill, getAllSettings, getAllSettingsDetailed, getBlockedCards, getCard, getCardById, getCardDeletionImpact, getConfiguredWorkspaces, getDatabaseTargetInfo, getDefaultDbPath, getDependents, getDisplayTitle, getDomainCompetence, getDueCards, getEmbeddingCoverage, getGoal, getGoalTree, getInstallChannel, getInstallMode, 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, listEmbeddedTokens, listGoals, 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, setActiveWorkspaceId, setInstallChannel, setInstallMode, setProviderApiKey, setSetting, setTursoCredentials, slugify, startSession, suggestFoundations, syncObserverSidecarPolicy, t, toSidecarPrivacyPolicy, uiObservationLogExists, uiObservationTimeSpan, unblockReady, updateCard, updateGoalStatus, updateToken, upsertConfiguredWorkspace, upsertTokenEmbedding, verifySnapshot, wouldCreateCycle, writeMonitorEvent };
|
package/dist/index.js
CHANGED
|
@@ -530,6 +530,7 @@ var SCHEMA = `
|
|
|
530
530
|
CREATE TABLE IF NOT EXISTS tokens (
|
|
531
531
|
id TEXT PRIMARY KEY,
|
|
532
532
|
slug TEXT UNIQUE NOT NULL,
|
|
533
|
+
title TEXT NOT NULL DEFAULT '',
|
|
533
534
|
concept TEXT NOT NULL,
|
|
534
535
|
domain TEXT NOT NULL DEFAULT '',
|
|
535
536
|
bloom_level INTEGER NOT NULL DEFAULT 1 CHECK (bloom_level BETWEEN 1 AND 5),
|
|
@@ -678,6 +679,8 @@ CREATE INDEX IF NOT EXISTS idx_cards_token_user ON cards(token_id, user_id);
|
|
|
678
679
|
CREATE INDEX IF NOT EXISTS idx_review_logs_card ON review_logs(card_id);
|
|
679
680
|
CREATE INDEX IF NOT EXISTS idx_review_logs_user ON review_logs(user_id, reviewed_at);
|
|
680
681
|
CREATE INDEX IF NOT EXISTS idx_session_steps_session ON session_steps(session_id);
|
|
682
|
+
CREATE INDEX IF NOT EXISTS idx_tokens_title ON tokens(title);
|
|
683
|
+
CREATE INDEX IF NOT EXISTS idx_tokens_domain ON tokens(domain);
|
|
681
684
|
`;
|
|
682
685
|
|
|
683
686
|
// src/kernel/db/sync-adapter.ts
|
|
@@ -1011,6 +1014,15 @@ async function runMigrations(db) {
|
|
|
1011
1014
|
embedded_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
1012
1015
|
)
|
|
1013
1016
|
`);
|
|
1017
|
+
if (!tokenCols.some((c) => c.name === "title")) {
|
|
1018
|
+
await db.exec(
|
|
1019
|
+
`ALTER TABLE tokens ADD COLUMN title TEXT NOT NULL DEFAULT ''`
|
|
1020
|
+
);
|
|
1021
|
+
}
|
|
1022
|
+
await db.exec(`CREATE INDEX IF NOT EXISTS idx_tokens_title ON tokens(title)`);
|
|
1023
|
+
await db.exec(
|
|
1024
|
+
`CREATE INDEX IF NOT EXISTS idx_tokens_domain ON tokens(domain)`
|
|
1025
|
+
);
|
|
1014
1026
|
}
|
|
1015
1027
|
|
|
1016
1028
|
// src/kernel/db/snapshot.ts
|
|
@@ -1512,12 +1524,14 @@ async function createToken(db, input) {
|
|
|
1512
1524
|
if (bloom < 1 || bloom > 5) {
|
|
1513
1525
|
throw new Error(`bloom_level must be between 1 and 5, got ${bloom}`);
|
|
1514
1526
|
}
|
|
1527
|
+
const title = input.title ?? "";
|
|
1515
1528
|
await db.prepare(`
|
|
1516
|
-
INSERT INTO tokens (id, slug, concept, domain, bloom_level, context, symbiosis_mode, source_link, question, provider, topic_id, created_at, updated_at)
|
|
1517
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1529
|
+
INSERT INTO tokens (id, slug, title, concept, domain, bloom_level, context, symbiosis_mode, source_link, question, provider, topic_id, created_at, updated_at)
|
|
1530
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1518
1531
|
`).run(
|
|
1519
1532
|
id,
|
|
1520
1533
|
input.slug,
|
|
1534
|
+
title,
|
|
1521
1535
|
input.concept,
|
|
1522
1536
|
input.domain ?? "",
|
|
1523
1537
|
bloom,
|
|
@@ -1560,6 +1574,10 @@ async function updateToken(db, slug, updates) {
|
|
|
1560
1574
|
}
|
|
1561
1575
|
const fields = [];
|
|
1562
1576
|
const values = [];
|
|
1577
|
+
if (updates.title !== void 0) {
|
|
1578
|
+
fields.push("title = ?");
|
|
1579
|
+
values.push(updates.title ?? "");
|
|
1580
|
+
}
|
|
1563
1581
|
if (updates.concept !== void 0) {
|
|
1564
1582
|
fields.push("concept = ?");
|
|
1565
1583
|
values.push(updates.concept);
|
|
@@ -1665,13 +1683,14 @@ async function deleteToken(db, slug) {
|
|
|
1665
1683
|
await db.transaction(async (tx) => {
|
|
1666
1684
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1667
1685
|
const skillRows = await tx.prepare("SELECT id, token_slugs FROM agent_skills").all();
|
|
1686
|
+
const skillUpdateStmt = tx.prepare(
|
|
1687
|
+
"UPDATE agent_skills SET token_slugs = ?, updated_at = ? WHERE id = ?"
|
|
1688
|
+
);
|
|
1668
1689
|
for (const row of skillRows) {
|
|
1669
1690
|
const tokenSlugs = JSON.parse(row.token_slugs);
|
|
1670
1691
|
const filtered = tokenSlugs.filter((tokenSlug) => tokenSlug !== slug);
|
|
1671
1692
|
if (filtered.length !== tokenSlugs.length) {
|
|
1672
|
-
await
|
|
1673
|
-
"UPDATE agent_skills SET token_slugs = ?, updated_at = ? WHERE id = ?"
|
|
1674
|
-
).run(JSON.stringify(filtered), now, row.id);
|
|
1693
|
+
await skillUpdateStmt.run(JSON.stringify(filtered), now, row.id);
|
|
1675
1694
|
}
|
|
1676
1695
|
}
|
|
1677
1696
|
await tx.prepare("DELETE FROM tokens WHERE id = ?").run(token.id);
|
|
@@ -1685,10 +1704,16 @@ async function findTokens(db, query) {
|
|
|
1685
1704
|
const shortTerms = searchTokens.filter((t2) => t2.length <= 2);
|
|
1686
1705
|
const longTerms = searchTokens.filter((t2) => t2.length > 2);
|
|
1687
1706
|
const scoreMap = /* @__PURE__ */ new Map();
|
|
1688
|
-
const likeSQL = `SELECT * FROM tokens WHERE deprecated_at IS NULL AND (lower(slug) LIKE ? OR lower(concept) LIKE ? OR lower(domain) LIKE ?)`;
|
|
1707
|
+
const likeSQL = `SELECT * FROM tokens WHERE deprecated_at IS NULL AND (lower(slug) LIKE ? OR lower(title) LIKE ? OR lower(concept) LIKE ? OR lower(domain) LIKE ?)`;
|
|
1708
|
+
const likeStmt = db.prepare(likeSQL);
|
|
1689
1709
|
for (const term of longTerms) {
|
|
1690
1710
|
const pattern = `%${term}%`;
|
|
1691
|
-
const rows = await
|
|
1711
|
+
const rows = await likeStmt.all(
|
|
1712
|
+
pattern,
|
|
1713
|
+
pattern,
|
|
1714
|
+
pattern,
|
|
1715
|
+
pattern
|
|
1716
|
+
);
|
|
1692
1717
|
for (const row of rows) {
|
|
1693
1718
|
const entry = scoreMap.get(row.id);
|
|
1694
1719
|
if (entry) {
|
|
@@ -1701,7 +1726,7 @@ async function findTokens(db, query) {
|
|
|
1701
1726
|
if (shortTerms.length > 0 || longTerms.length === 0) {
|
|
1702
1727
|
const allTokens = await db.prepare("SELECT * FROM tokens WHERE deprecated_at IS NULL").all();
|
|
1703
1728
|
for (const token of allTokens) {
|
|
1704
|
-
const words = `${token.slug} ${token.concept} ${token.domain}`.toLowerCase().split(/[\s,.\-_/\\:;!?()[\]{}]+/).filter(Boolean);
|
|
1729
|
+
const words = `${token.slug} ${token.title} ${token.concept} ${token.domain}`.toLowerCase().split(/[\s,.\-_/\\:;!?()[\]{}]+/).filter(Boolean);
|
|
1705
1730
|
let matchCount = 0;
|
|
1706
1731
|
for (const term of shortTerms.length > 0 ? shortTerms : searchTokens) {
|
|
1707
1732
|
for (const w of words) {
|
|
@@ -1735,6 +1760,11 @@ async function listTokens(db, options) {
|
|
|
1735
1760
|
tokens = await db.prepare(
|
|
1736
1761
|
"SELECT * FROM tokens WHERE domain = ? AND deprecated_at IS NULL ORDER BY bloom_level, slug"
|
|
1737
1762
|
).all(options.domain);
|
|
1763
|
+
} else if (options?.domainPrefix) {
|
|
1764
|
+
const prefix = options.domainPrefix;
|
|
1765
|
+
tokens = await db.prepare(
|
|
1766
|
+
`SELECT * FROM tokens WHERE (domain = ? OR domain LIKE ?) AND deprecated_at IS NULL ORDER BY bloom_level, slug`
|
|
1767
|
+
).all(prefix, `${prefix}/%`);
|
|
1738
1768
|
} else {
|
|
1739
1769
|
tokens = await db.prepare(
|
|
1740
1770
|
"SELECT * FROM tokens WHERE deprecated_at IS NULL ORDER BY bloom_level, domain, slug"
|
|
@@ -1746,7 +1776,20 @@ async function listTokens(db, options) {
|
|
|
1746
1776
|
return tokens;
|
|
1747
1777
|
}
|
|
1748
1778
|
function slugify(text) {
|
|
1749
|
-
return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
|
|
1779
|
+
return text.toLowerCase().replace(/ä/g, "ae").replace(/ö/g, "oe").replace(/ü/g, "ue").replace(/ß/g, "ss").replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
|
|
1780
|
+
}
|
|
1781
|
+
function getShortSlug(slug, domainPrefix) {
|
|
1782
|
+
if (domainPrefix) {
|
|
1783
|
+
const folded = domainPrefix.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
1784
|
+
if (folded && slug.startsWith(`${folded}-`)) {
|
|
1785
|
+
return slug.substring(folded.length + 1);
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
return slug;
|
|
1789
|
+
}
|
|
1790
|
+
function getDisplayTitle(t2, activeDomainScope) {
|
|
1791
|
+
if (t2.title?.trim()) return t2.title.trim();
|
|
1792
|
+
return getShortSlug(t2.slug, activeDomainScope);
|
|
1750
1793
|
}
|
|
1751
1794
|
async function generateTokenSlug(db, domain, concept, question) {
|
|
1752
1795
|
const baseText = question && question.trim().length > 0 ? question : concept;
|
|
@@ -1776,6 +1819,7 @@ async function listPersonalCards(db, userId, options) {
|
|
|
1776
1819
|
SELECT
|
|
1777
1820
|
t.id AS tokenId,
|
|
1778
1821
|
t.slug,
|
|
1822
|
+
t.title,
|
|
1779
1823
|
t.concept,
|
|
1780
1824
|
t.domain,
|
|
1781
1825
|
t.bloom_level AS bloomLevel,
|
|
@@ -1877,6 +1921,7 @@ async function importCurriculumCards(db, userId, cards) {
|
|
|
1877
1921
|
);
|
|
1878
1922
|
token = await createToken(tx, {
|
|
1879
1923
|
slug: finalSlug,
|
|
1924
|
+
title: card.title,
|
|
1880
1925
|
concept: card.concept,
|
|
1881
1926
|
domain: card.domain,
|
|
1882
1927
|
bloom_level: bloom,
|
|
@@ -1994,23 +2039,28 @@ async function confirmCardSplit(db, userId, originalSlug, action, originalQuesti
|
|
|
1994
2039
|
(/* @__PURE__ */ new Date()).toISOString(),
|
|
1995
2040
|
originalToken.id
|
|
1996
2041
|
);
|
|
2042
|
+
const insertPrereqStmt = tx.prepare(
|
|
2043
|
+
"INSERT OR IGNORE INTO prerequisites (token_id, requires_id) VALUES (?, ?)"
|
|
2044
|
+
);
|
|
1997
2045
|
for (const propToken of proposalTokens) {
|
|
1998
|
-
await
|
|
1999
|
-
"INSERT OR IGNORE INTO prerequisites (token_id, requires_id) VALUES (?, ?)"
|
|
2000
|
-
).run(originalToken.id, propToken.id);
|
|
2046
|
+
await insertPrereqStmt.run(originalToken.id, propToken.id);
|
|
2001
2047
|
}
|
|
2002
2048
|
await tx.prepare(
|
|
2003
2049
|
"UPDATE cards SET blocked = 1 WHERE token_id = ? AND user_id = ?"
|
|
2004
2050
|
).run(originalToken.id, userId);
|
|
2051
|
+
const checkPrereqsStmt = tx.prepare(
|
|
2052
|
+
"SELECT COUNT(*) as n FROM prerequisites WHERE token_id = ?"
|
|
2053
|
+
);
|
|
2054
|
+
const unblockCardStmt = tx.prepare(
|
|
2055
|
+
"UPDATE cards SET blocked = 0, due_at = ? WHERE id = ?"
|
|
2056
|
+
);
|
|
2005
2057
|
for (const propToken of proposalTokens) {
|
|
2006
2058
|
const card = await ensureCard(tx, propToken.id, userId);
|
|
2007
2059
|
if (card.blocked === 1) {
|
|
2008
|
-
const prereqOfPrereq = await
|
|
2009
|
-
"SELECT COUNT(*) as n FROM prerequisites WHERE token_id = ?"
|
|
2010
|
-
).get(propToken.id);
|
|
2060
|
+
const prereqOfPrereq = await checkPrereqsStmt.get(propToken.id);
|
|
2011
2061
|
if (prereqOfPrereq.n === 0) {
|
|
2012
2062
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2013
|
-
await
|
|
2063
|
+
await unblockCardStmt.run(now, card.id);
|
|
2014
2064
|
}
|
|
2015
2065
|
}
|
|
2016
2066
|
}
|
|
@@ -2081,6 +2131,7 @@ async function confirmFoundations(db, userId, originalSlug, proposals) {
|
|
|
2081
2131
|
);
|
|
2082
2132
|
token = await createToken(tx, {
|
|
2083
2133
|
slug: finalSlug,
|
|
2134
|
+
title: card.title,
|
|
2084
2135
|
concept: card.concept,
|
|
2085
2136
|
domain: card.domain,
|
|
2086
2137
|
bloom_level: bloom,
|
|
@@ -2147,6 +2198,7 @@ async function confirmSourceImport(db, userId, sourceId, proposals) {
|
|
|
2147
2198
|
}
|
|
2148
2199
|
token = await createToken(tx, {
|
|
2149
2200
|
slug: finalSlug,
|
|
2201
|
+
title: card.title,
|
|
2150
2202
|
concept: card.concept,
|
|
2151
2203
|
domain: card.domain,
|
|
2152
2204
|
bloom_level: bloom,
|
|
@@ -2249,7 +2301,7 @@ async function addPrerequisite(db, tokenId, requiresId) {
|
|
|
2249
2301
|
}
|
|
2250
2302
|
async function getPrerequisites(db, tokenId) {
|
|
2251
2303
|
return await db.prepare(
|
|
2252
|
-
`SELECT p.token_id, p.requires_id, t.slug, t.concept, t.domain, t.bloom_level
|
|
2304
|
+
`SELECT p.token_id, p.requires_id, t.slug, t.title, t.concept, t.domain, t.bloom_level
|
|
2253
2305
|
FROM prerequisites p
|
|
2254
2306
|
JOIN tokens t ON t.id = p.requires_id
|
|
2255
2307
|
WHERE p.token_id = ?`
|
|
@@ -2257,7 +2309,7 @@ async function getPrerequisites(db, tokenId) {
|
|
|
2257
2309
|
}
|
|
2258
2310
|
async function getDependents(db, tokenId) {
|
|
2259
2311
|
return await db.prepare(
|
|
2260
|
-
`SELECT p.token_id, p.requires_id, t.slug, t.concept, t.domain, t.bloom_level
|
|
2312
|
+
`SELECT p.token_id, p.requires_id, t.slug, t.title, t.concept, t.domain, t.bloom_level
|
|
2261
2313
|
FROM prerequisites p
|
|
2262
2314
|
JOIN tokens t ON t.id = p.token_id
|
|
2263
2315
|
WHERE p.requires_id = ?`
|
|
@@ -2288,6 +2340,7 @@ async function getTokenNeighborhood(db, tokenId, userId) {
|
|
|
2288
2340
|
const toNode = (t2, card) => ({
|
|
2289
2341
|
id: t2.id,
|
|
2290
2342
|
slug: t2.slug,
|
|
2343
|
+
title: t2.title ?? t2.slug,
|
|
2291
2344
|
concept: t2.concept,
|
|
2292
2345
|
domain: t2.domain,
|
|
2293
2346
|
bloom_level: t2.bloom_level,
|
|
@@ -2307,6 +2360,7 @@ async function getTokenNeighborhood(db, tokenId, userId) {
|
|
|
2307
2360
|
{
|
|
2308
2361
|
id: p.requires_id,
|
|
2309
2362
|
slug: p.slug,
|
|
2363
|
+
title: p.title,
|
|
2310
2364
|
concept: p.concept,
|
|
2311
2365
|
domain: p.domain,
|
|
2312
2366
|
bloom_level: p.bloom_level
|
|
@@ -2319,6 +2373,7 @@ async function getTokenNeighborhood(db, tokenId, userId) {
|
|
|
2319
2373
|
{
|
|
2320
2374
|
id: d.token_id,
|
|
2321
2375
|
slug: d.slug,
|
|
2376
|
+
title: d.title,
|
|
2322
2377
|
concept: d.concept,
|
|
2323
2378
|
domain: d.domain,
|
|
2324
2379
|
bloom_level: d.bloom_level
|
|
@@ -2478,7 +2533,8 @@ import { createHash as createHash2 } from "crypto";
|
|
|
2478
2533
|
function embeddingContentForToken(t2) {
|
|
2479
2534
|
return `${t2.concept}
|
|
2480
2535
|
${t2.question ?? ""}
|
|
2481
|
-
${t2.domain}
|
|
2536
|
+
${t2.domain}
|
|
2537
|
+
${t2.title ?? ""}`;
|
|
2482
2538
|
}
|
|
2483
2539
|
function computeContentHash(text) {
|
|
2484
2540
|
return createHash2("sha256").update(text, "utf8").digest("hex");
|
|
@@ -4662,6 +4718,7 @@ async function buildReviewQueue(db, options) {
|
|
|
4662
4718
|
c.id AS card_id,
|
|
4663
4719
|
c.token_id AS token_id,
|
|
4664
4720
|
t.slug AS slug,
|
|
4721
|
+
t.title AS title,
|
|
4665
4722
|
t.concept AS concept,
|
|
4666
4723
|
t.domain AS domain,
|
|
4667
4724
|
t.bloom_level AS bloom_level,
|
|
@@ -4683,6 +4740,7 @@ async function buildReviewQueue(db, options) {
|
|
|
4683
4740
|
c.id AS card_id,
|
|
4684
4741
|
c.token_id AS token_id,
|
|
4685
4742
|
t.slug AS slug,
|
|
4743
|
+
t.title AS title,
|
|
4686
4744
|
t.concept AS concept,
|
|
4687
4745
|
t.domain AS domain,
|
|
4688
4746
|
t.bloom_level AS bloom_level,
|
|
@@ -4742,6 +4800,7 @@ function rowToItem(row) {
|
|
|
4742
4800
|
cardId: row.card_id,
|
|
4743
4801
|
tokenId: row.token_id,
|
|
4744
4802
|
slug: row.slug,
|
|
4803
|
+
title: getDisplayTitle(row),
|
|
4745
4804
|
concept: row.concept,
|
|
4746
4805
|
domain: row.domain,
|
|
4747
4806
|
bloomLevel: row.bloom_level,
|
|
@@ -6005,6 +6064,7 @@ export {
|
|
|
6005
6064
|
getDatabaseTargetInfo,
|
|
6006
6065
|
getDefaultDbPath,
|
|
6007
6066
|
getDependents,
|
|
6067
|
+
getDisplayTitle,
|
|
6008
6068
|
getDomainCompetence,
|
|
6009
6069
|
getDueCards,
|
|
6010
6070
|
getEmbeddingCoverage,
|
|
@@ -6025,6 +6085,7 @@ export {
|
|
|
6025
6085
|
getSessionSummary,
|
|
6026
6086
|
getSessionSynthesisRecords,
|
|
6027
6087
|
getSetting,
|
|
6088
|
+
getShortSlug,
|
|
6028
6089
|
getSystemProfile,
|
|
6029
6090
|
getTokenById,
|
|
6030
6091
|
getTokenBySlug,
|