zam-core 0.5.3 → 0.6.0
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 +1316 -22
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +97 -1
- package/dist/index.js +452 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -900,6 +900,102 @@ declare function findTokens(db: Database, query: string): Promise<ScoredToken[]>
|
|
|
900
900
|
* Results are ordered by bloom_level then slug.
|
|
901
901
|
*/
|
|
902
902
|
declare function listTokens(db: Database, options?: ListTokensOptions): Promise<Token[]>;
|
|
903
|
+
interface PersonalCard {
|
|
904
|
+
tokenId: string;
|
|
905
|
+
slug: string;
|
|
906
|
+
concept: string;
|
|
907
|
+
domain: string;
|
|
908
|
+
bloomLevel: BloomLevel$1;
|
|
909
|
+
context: string;
|
|
910
|
+
symbiosisMode: SymbiosisMode | null;
|
|
911
|
+
sourceLink: string | null;
|
|
912
|
+
question: string | null;
|
|
913
|
+
createdAt: string;
|
|
914
|
+
updatedAt: string;
|
|
915
|
+
cardId: string | null;
|
|
916
|
+
state: CardState$1 | null;
|
|
917
|
+
dueAt: string | null;
|
|
918
|
+
stability: number | null;
|
|
919
|
+
difficulty: number | null;
|
|
920
|
+
reps: number | null;
|
|
921
|
+
lapses: number | null;
|
|
922
|
+
elapsedDays: number | null;
|
|
923
|
+
scheduledDays: number | null;
|
|
924
|
+
blocked: number | null;
|
|
925
|
+
}
|
|
926
|
+
declare function slugify(text: string): string;
|
|
927
|
+
declare function generateTokenSlug(db: Database, domain: string, concept: string, question?: string | null): Promise<string>;
|
|
928
|
+
declare function listPersonalCards(db: Database, userId: string, options?: {
|
|
929
|
+
query?: string;
|
|
930
|
+
domain?: string;
|
|
931
|
+
}): Promise<PersonalCard[]>;
|
|
932
|
+
interface CurriculumCardInput {
|
|
933
|
+
question: string;
|
|
934
|
+
concept: string;
|
|
935
|
+
domain: string;
|
|
936
|
+
source_link?: string | null;
|
|
937
|
+
context?: string;
|
|
938
|
+
bloom_level?: number;
|
|
939
|
+
symbiosis_mode?: string | null;
|
|
940
|
+
}
|
|
941
|
+
interface ImportCurriculumResult {
|
|
942
|
+
createdCount: number;
|
|
943
|
+
ensuredCount: number;
|
|
944
|
+
}
|
|
945
|
+
/**
|
|
946
|
+
* Import curriculum cards in a single transaction.
|
|
947
|
+
* Reuses existing tokens on slug match and ensures FSRS cards exist.
|
|
948
|
+
*/
|
|
949
|
+
declare function importCurriculumCards(db: Database, userId: string, cards: CurriculumCardInput[]): Promise<ImportCurriculumResult>;
|
|
950
|
+
interface SplitProposalInput {
|
|
951
|
+
question: string;
|
|
952
|
+
concept: string;
|
|
953
|
+
domain: string;
|
|
954
|
+
context?: string;
|
|
955
|
+
bloom_level?: number;
|
|
956
|
+
symbiosis_mode?: string | null;
|
|
957
|
+
source_link?: string | null;
|
|
958
|
+
}
|
|
959
|
+
/**
|
|
960
|
+
* Confirm a card split transaction.
|
|
961
|
+
* Creates proposal cards, links them as prerequisites to the original card,
|
|
962
|
+
* and either blocks the original card (surfacing proposals) or deletes it.
|
|
963
|
+
*/
|
|
964
|
+
declare function confirmCardSplit(db: Database, userId: string, originalSlug: string, action: "block" | "remove", originalQuestion: string, originalConcept: string, proposals: SplitProposalInput[]): Promise<ImportCurriculumResult>;
|
|
965
|
+
interface FoundationProposalInput {
|
|
966
|
+
question: string;
|
|
967
|
+
concept: string;
|
|
968
|
+
domain: string;
|
|
969
|
+
context?: string;
|
|
970
|
+
bloom_level?: number;
|
|
971
|
+
symbiosis_mode?: string | null;
|
|
972
|
+
source_link?: string | null;
|
|
973
|
+
exists: boolean;
|
|
974
|
+
slug?: string | null;
|
|
975
|
+
}
|
|
976
|
+
interface ConfirmFoundationsResult {
|
|
977
|
+
createdCount: number;
|
|
978
|
+
linkedCount: number;
|
|
979
|
+
}
|
|
980
|
+
/**
|
|
981
|
+
* Confirm foundations import.
|
|
982
|
+
* Reuses existing tokens or creates new ones, then links them as prerequisites to the original card.
|
|
983
|
+
*/
|
|
984
|
+
declare function confirmFoundations(db: Database, userId: string, originalSlug: string, proposals: FoundationProposalInput[]): Promise<ConfirmFoundationsResult>;
|
|
985
|
+
interface SourceProposalInput {
|
|
986
|
+
question: string;
|
|
987
|
+
concept: string;
|
|
988
|
+
domain: string;
|
|
989
|
+
bloom_level: number;
|
|
990
|
+
symbiosis_mode: string;
|
|
991
|
+
excerpt: string;
|
|
992
|
+
page_number?: string | null;
|
|
993
|
+
}
|
|
994
|
+
/**
|
|
995
|
+
* Confirm source import transaction.
|
|
996
|
+
* Saves tokens, maps them to the source in token_sources, and ensures cards exist for the user.
|
|
997
|
+
*/
|
|
998
|
+
declare function confirmSourceImport(db: Database, userId: string, sourceId: string, proposals: SourceProposalInput[]): Promise<ConfirmFoundationsResult>;
|
|
903
999
|
|
|
904
1000
|
/**
|
|
905
1001
|
* Monitor log analyzer — maps observed shell commands to token ratings.
|
|
@@ -1957,4 +2053,4 @@ declare function resolveAllBeliefPaths(db: Database): Promise<string[]>;
|
|
|
1957
2053
|
*/
|
|
1958
2054
|
declare function resolveAllGoalPaths(db: Database): Promise<string[]>;
|
|
1959
2055
|
|
|
1960
|
-
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 ConnectionOptions, type CreateAgentSkillInput, type CreateGoalInput, type CreateReviewInput, type CreateSessionInput, type CreateTokenInput, type Credentials, 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 EvaluateInput, type EvaluateResult, type ExecuteReviewActionInput, type ExecutionContext, type FSRSParameters, type Goal, type GoalFrontmatter, type GoalStatus, type GoalSummary, HOMEBREW_CASK, 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 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 Statement, type SupportedLocale, type SymbiosisMode, type SynthesisConfidence, type SystemProfile, type Token, type TokenDeleteImpact, 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, buildReviewQueue, buildUiSynthesisCandidates, cascadeBlock, clearADOCredentials, clearProviderApiKey, clearReviewContextCache, clearTursoCredentials, compareVersions, createAgentSkill, createFSRS, createGoal, createToken, decidePostCapture, decidePreCapture, decideUpdate, deleteCardForUser, deleteSetting, deleteToken, deprecateToken, detectSyncProvider, detectSystemLocale, discoverSkills, distributeGlobalSkills, endSession, ensureCard, ensureMonitorDir, ensureUiObserverDir, evaluateRating, executeReviewAction, exportSnapshot, extractTasks, extractTokenRefs, fetchActiveWorkItems, findTokens, generateBashHooks, generateBashUnhooks, generateConceptFreeCue, generatePowerShellHooks, generatePowerShellUnhooks, generatePrompt, generateZshHooks, generateZshUnhooks, getADOCredentials, getActiveWorkspace, getActiveWorkspaceId, getAgentSkill, getAllSettings, getAllSettingsDetailed, getBlockedCards, getCard, getCardById, getCardDeletionImpact, getConfiguredWorkspaces, getDatabaseTargetInfo, getDefaultDbPath, getDependents, getDomainCompetence, getDueCards, getGoal, getGoalTree, getInstallChannel, getInstallMode, getMachineAiConfig, getMonitorDir, getMonitorLogStats, getMonitorPath, getPackageSkillPath, getPrerequisites, getProviderApiKey, getRepoPaths, getReviewsForCard, getReviewsForUser, getSessionSummary, getSessionSynthesisRecords, getSetting, getSystemProfile, getTokenById, getTokenBySlug, getTokenDeleteImpact, getTokenNeighborhood, getTursoCredentials, getUiObservationPath, getUiObserverDir, getUserStats, hasCommand, importSnapshot, injectShellHooks, installFastFlowLM, installOllama, installOpenCode, interleave, isObserverPolicyConfigured, isUiObservationReport, listAgentSkills, listGoals, listProviderApiKeyRefs, listTokens, 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, resolveReference, resolveRepoPath, resolveReviewContext, saveConfiguredWorkspaces, saveCredentials, saveInstallConfig, saveMachineAiConfig, serializeGoal, setADOCredentials, setActiveWorkspaceId, setInstallChannel, setInstallMode, setProviderApiKey, setSetting, setTursoCredentials, startSession, syncObserverSidecarPolicy, t, toSidecarPrivacyPolicy, uiObservationLogExists, uiObservationTimeSpan, unblockReady, updateCard, updateGoalStatus, updateToken, upsertConfiguredWorkspace, verifySnapshot, wouldCreateCycle, writeMonitorEvent };
|
|
2056
|
+
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 EvaluateInput, type EvaluateResult, type ExecuteReviewActionInput, type ExecutionContext, type FSRSParameters, type FoundationProposalInput, type Goal, type GoalFrontmatter, type GoalStatus, type GoalSummary, HOMEBREW_CASK, 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 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 SupportedLocale, type SymbiosisMode, type SynthesisConfidence, type SystemProfile, type Token, type TokenDeleteImpact, 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, buildReviewQueue, buildUiSynthesisCandidates, cascadeBlock, clearADOCredentials, clearProviderApiKey, clearReviewContextCache, clearTursoCredentials, compareVersions, confirmCardSplit, confirmFoundations, confirmSourceImport, createAgentSkill, createFSRS, createGoal, createToken, decidePostCapture, decidePreCapture, decideUpdate, deleteCardForUser, deleteSetting, deleteToken, deprecateToken, detectSyncProvider, detectSystemLocale, discoverSkills, distributeGlobalSkills, 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, getGoal, getGoalTree, getInstallChannel, getInstallMode, getMachineAiConfig, getMonitorDir, getMonitorLogStats, getMonitorPath, getPackageSkillPath, getPrerequisites, getProviderApiKey, getRepoPaths, getReviewsForCard, getReviewsForUser, getSessionSummary, getSessionSynthesisRecords, getSetting, getSystemProfile, getTokenById, getTokenBySlug, getTokenDeleteImpact, getTokenNeighborhood, getTursoCredentials, getUiObservationPath, getUiObserverDir, getUserStats, hasCommand, importCurriculumCards, importSnapshot, injectShellHooks, installFastFlowLM, installOllama, installOpenCode, interleave, isObserverPolicyConfigured, isUiObservationReport, listAgentSkills, listGoals, listPersonalCards, listProviderApiKeyRefs, listTokens, 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, resolveReference, resolveRepoPath, resolveReviewContext, saveConfiguredWorkspaces, saveCredentials, saveInstallConfig, saveMachineAiConfig, serializeGoal, setADOCredentials, setActiveWorkspaceId, setInstallChannel, setInstallMode, setProviderApiKey, setSetting, setTursoCredentials, slugify, startSession, syncObserverSidecarPolicy, t, toSidecarPrivacyPolicy, uiObservationLogExists, uiObservationTimeSpan, unblockReady, updateCard, updateGoalStatus, updateToken, upsertConfiguredWorkspace, verifySnapshot, wouldCreateCycle, writeMonitorEvent };
|
package/dist/index.js
CHANGED
|
@@ -616,6 +616,24 @@ CREATE TABLE IF NOT EXISTS session_syntheses (
|
|
|
616
616
|
PRIMARY KEY (session_id, token_id)
|
|
617
617
|
);
|
|
618
618
|
|
|
619
|
+
-- Sources: textbook files, web links, or scan paths
|
|
620
|
+
CREATE TABLE IF NOT EXISTS sources (
|
|
621
|
+
id TEXT PRIMARY KEY,
|
|
622
|
+
type TEXT NOT NULL CHECK (type IN ('file', 'web', 'scan')),
|
|
623
|
+
uri TEXT NOT NULL UNIQUE,
|
|
624
|
+
content TEXT,
|
|
625
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
626
|
+
);
|
|
627
|
+
|
|
628
|
+
-- Token sources: mapping between tokens and their sources
|
|
629
|
+
CREATE TABLE IF NOT EXISTS token_sources (
|
|
630
|
+
token_id TEXT NOT NULL REFERENCES tokens(id) ON DELETE CASCADE,
|
|
631
|
+
source_id TEXT NOT NULL REFERENCES sources(id) ON DELETE CASCADE,
|
|
632
|
+
excerpt TEXT NOT NULL DEFAULT '',
|
|
633
|
+
page_number TEXT,
|
|
634
|
+
PRIMARY KEY (token_id, source_id)
|
|
635
|
+
);
|
|
636
|
+
|
|
619
637
|
-- User configuration
|
|
620
638
|
CREATE TABLE IF NOT EXISTS user_config (
|
|
621
639
|
key TEXT PRIMARY KEY,
|
|
@@ -943,6 +961,24 @@ async function runMigrations(db) {
|
|
|
943
961
|
PRIMARY KEY (session_id, token_id)
|
|
944
962
|
)
|
|
945
963
|
`);
|
|
964
|
+
await db.exec(`
|
|
965
|
+
CREATE TABLE IF NOT EXISTS sources (
|
|
966
|
+
id TEXT PRIMARY KEY,
|
|
967
|
+
type TEXT NOT NULL CHECK (type IN ('file', 'web', 'scan')),
|
|
968
|
+
uri TEXT NOT NULL UNIQUE,
|
|
969
|
+
content TEXT,
|
|
970
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
971
|
+
)
|
|
972
|
+
`);
|
|
973
|
+
await db.exec(`
|
|
974
|
+
CREATE TABLE IF NOT EXISTS token_sources (
|
|
975
|
+
token_id TEXT NOT NULL REFERENCES tokens(id) ON DELETE CASCADE,
|
|
976
|
+
source_id TEXT NOT NULL REFERENCES sources(id) ON DELETE CASCADE,
|
|
977
|
+
excerpt TEXT NOT NULL DEFAULT '',
|
|
978
|
+
page_number TEXT,
|
|
979
|
+
PRIMARY KEY (token_id, source_id)
|
|
980
|
+
)
|
|
981
|
+
`);
|
|
946
982
|
}
|
|
947
983
|
|
|
948
984
|
// src/kernel/db/snapshot.ts
|
|
@@ -1646,6 +1682,415 @@ async function listTokens(db, options) {
|
|
|
1646
1682
|
"SELECT * FROM tokens WHERE deprecated_at IS NULL ORDER BY bloom_level, domain, slug"
|
|
1647
1683
|
).all();
|
|
1648
1684
|
}
|
|
1685
|
+
function slugify(text) {
|
|
1686
|
+
return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
|
|
1687
|
+
}
|
|
1688
|
+
async function generateTokenSlug(db, domain, concept, question) {
|
|
1689
|
+
const baseText = question && question.trim().length > 0 ? question : concept;
|
|
1690
|
+
const cleanDomain = slugify(domain || "");
|
|
1691
|
+
const cleanBase = slugify(baseText);
|
|
1692
|
+
let baseSlug = cleanDomain ? `${cleanDomain}-${cleanBase}` : cleanBase;
|
|
1693
|
+
if (baseSlug.length > 60) {
|
|
1694
|
+
baseSlug = baseSlug.slice(0, 60).replace(/-$/, "");
|
|
1695
|
+
}
|
|
1696
|
+
if (!baseSlug) {
|
|
1697
|
+
baseSlug = "token";
|
|
1698
|
+
}
|
|
1699
|
+
let slug = baseSlug;
|
|
1700
|
+
let counter = 1;
|
|
1701
|
+
while (true) {
|
|
1702
|
+
const existing = await db.prepare("SELECT id FROM tokens WHERE slug = ?").get(slug);
|
|
1703
|
+
if (!existing) {
|
|
1704
|
+
return slug;
|
|
1705
|
+
}
|
|
1706
|
+
const suffix = `-${counter}`;
|
|
1707
|
+
slug = baseSlug.slice(0, 60 - suffix.length).replace(/-$/, "") + suffix;
|
|
1708
|
+
counter++;
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
async function listPersonalCards(db, userId, options) {
|
|
1712
|
+
let sql = `
|
|
1713
|
+
SELECT
|
|
1714
|
+
t.id AS tokenId,
|
|
1715
|
+
t.slug,
|
|
1716
|
+
t.concept,
|
|
1717
|
+
t.domain,
|
|
1718
|
+
t.bloom_level AS bloomLevel,
|
|
1719
|
+
t.context,
|
|
1720
|
+
t.symbiosis_mode AS symbiosisMode,
|
|
1721
|
+
t.source_link AS sourceLink,
|
|
1722
|
+
t.question,
|
|
1723
|
+
t.created_at AS createdAt,
|
|
1724
|
+
t.updated_at AS updatedAt,
|
|
1725
|
+
c.id AS cardId,
|
|
1726
|
+
c.state,
|
|
1727
|
+
c.due_at AS dueAt,
|
|
1728
|
+
c.stability,
|
|
1729
|
+
c.difficulty,
|
|
1730
|
+
c.reps,
|
|
1731
|
+
c.lapses,
|
|
1732
|
+
c.elapsed_days AS elapsedDays,
|
|
1733
|
+
c.scheduled_days AS scheduledDays,
|
|
1734
|
+
c.blocked
|
|
1735
|
+
FROM tokens t
|
|
1736
|
+
INNER JOIN cards c ON c.token_id = t.id AND c.user_id = ?
|
|
1737
|
+
WHERE t.deprecated_at IS NULL
|
|
1738
|
+
`;
|
|
1739
|
+
const values = [userId];
|
|
1740
|
+
if (options?.domain) {
|
|
1741
|
+
sql += " AND t.domain = ?";
|
|
1742
|
+
values.push(options.domain);
|
|
1743
|
+
}
|
|
1744
|
+
if (options?.query) {
|
|
1745
|
+
const terms = options.query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
1746
|
+
for (const term of terms) {
|
|
1747
|
+
sql += ` AND (lower(t.slug) LIKE ? OR lower(t.concept) LIKE ? OR lower(t.domain) LIKE ? OR lower(t.question) LIKE ?)`;
|
|
1748
|
+
const pattern = `%${term}%`;
|
|
1749
|
+
values.push(pattern, pattern, pattern, pattern);
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
sql += " ORDER BY t.created_at DESC";
|
|
1753
|
+
const rows = await db.prepare(sql).all(...values);
|
|
1754
|
+
return rows;
|
|
1755
|
+
}
|
|
1756
|
+
async function importCurriculumCards(db, userId, cards) {
|
|
1757
|
+
let createdCount = 0;
|
|
1758
|
+
let ensuredCount = 0;
|
|
1759
|
+
await db.transaction(async (tx) => {
|
|
1760
|
+
for (const card of cards) {
|
|
1761
|
+
const bloom = card.bloom_level !== void 0 ? card.bloom_level : 1;
|
|
1762
|
+
if (bloom < 1 || bloom > 5) {
|
|
1763
|
+
throw new Error(`bloom_level must be between 1 and 5, got ${bloom}`);
|
|
1764
|
+
}
|
|
1765
|
+
let symbiosisMode = null;
|
|
1766
|
+
if (card.symbiosis_mode) {
|
|
1767
|
+
if (!["shadowing", "copilot", "autonomy", "none"].includes(
|
|
1768
|
+
card.symbiosis_mode
|
|
1769
|
+
)) {
|
|
1770
|
+
throw new Error(`Invalid symbiosis_mode: ${card.symbiosis_mode}`);
|
|
1771
|
+
}
|
|
1772
|
+
symbiosisMode = card.symbiosis_mode === "none" ? null : card.symbiosis_mode;
|
|
1773
|
+
}
|
|
1774
|
+
const baseText = card.question && card.question.trim().length > 0 ? card.question : card.concept;
|
|
1775
|
+
const cleanDomain = slugify(card.domain || "");
|
|
1776
|
+
const cleanBase = slugify(baseText);
|
|
1777
|
+
let baseSlug = cleanDomain ? `${cleanDomain}-${cleanBase}` : cleanBase;
|
|
1778
|
+
if (baseSlug.length > 60) {
|
|
1779
|
+
baseSlug = baseSlug.slice(0, 60).replace(/-$/, "");
|
|
1780
|
+
}
|
|
1781
|
+
if (!baseSlug) {
|
|
1782
|
+
baseSlug = "token";
|
|
1783
|
+
}
|
|
1784
|
+
let token = await getTokenBySlug(tx, baseSlug);
|
|
1785
|
+
if (!token) {
|
|
1786
|
+
const finalSlug = await generateTokenSlug(
|
|
1787
|
+
tx,
|
|
1788
|
+
card.domain,
|
|
1789
|
+
card.concept,
|
|
1790
|
+
card.question
|
|
1791
|
+
);
|
|
1792
|
+
token = await createToken(tx, {
|
|
1793
|
+
slug: finalSlug,
|
|
1794
|
+
concept: card.concept,
|
|
1795
|
+
domain: card.domain,
|
|
1796
|
+
bloom_level: bloom,
|
|
1797
|
+
context: card.context || "",
|
|
1798
|
+
symbiosis_mode: symbiosisMode,
|
|
1799
|
+
source_link: card.source_link || null,
|
|
1800
|
+
question: card.question || null
|
|
1801
|
+
});
|
|
1802
|
+
createdCount++;
|
|
1803
|
+
}
|
|
1804
|
+
const existingCard = await getCard(tx, token.id, userId);
|
|
1805
|
+
if (!existingCard) {
|
|
1806
|
+
await ensureCard(tx, token.id, userId);
|
|
1807
|
+
ensuredCount++;
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
});
|
|
1811
|
+
return { createdCount, ensuredCount };
|
|
1812
|
+
}
|
|
1813
|
+
async function confirmCardSplit(db, userId, originalSlug, action, originalQuestion, originalConcept, proposals) {
|
|
1814
|
+
if (action !== "block" && action !== "remove") {
|
|
1815
|
+
throw new Error(`Invalid split action: ${action}`);
|
|
1816
|
+
}
|
|
1817
|
+
if (proposals.length < 2 || proposals.length > 4) {
|
|
1818
|
+
throw new Error("A card split requires between 2 and 4 proposals");
|
|
1819
|
+
}
|
|
1820
|
+
const originalToken = await getTokenBySlug(db, originalSlug);
|
|
1821
|
+
if (!originalToken) {
|
|
1822
|
+
throw new Error(`Original token not found: ${originalSlug}`);
|
|
1823
|
+
}
|
|
1824
|
+
let createdCount = 0;
|
|
1825
|
+
let ensuredCount = 0;
|
|
1826
|
+
await db.transaction(async (tx) => {
|
|
1827
|
+
const originalCard = await getCard(tx, originalToken.id, userId);
|
|
1828
|
+
if (!originalCard) {
|
|
1829
|
+
throw new Error(
|
|
1830
|
+
`Card not found for token ${originalSlug} and user ${userId}`
|
|
1831
|
+
);
|
|
1832
|
+
}
|
|
1833
|
+
const proposalTokens = [];
|
|
1834
|
+
for (const card of proposals) {
|
|
1835
|
+
const bloom = card.bloom_level !== void 0 ? card.bloom_level : 1;
|
|
1836
|
+
if (bloom < 1 || bloom > 5) {
|
|
1837
|
+
throw new Error(`bloom_level must be between 1 and 5, got ${bloom}`);
|
|
1838
|
+
}
|
|
1839
|
+
let symbiosisMode = null;
|
|
1840
|
+
if (card.symbiosis_mode) {
|
|
1841
|
+
if (!["shadowing", "copilot", "autonomy", "none"].includes(
|
|
1842
|
+
card.symbiosis_mode
|
|
1843
|
+
)) {
|
|
1844
|
+
throw new Error(`Invalid symbiosis_mode: ${card.symbiosis_mode}`);
|
|
1845
|
+
}
|
|
1846
|
+
symbiosisMode = card.symbiosis_mode === "none" ? null : card.symbiosis_mode;
|
|
1847
|
+
}
|
|
1848
|
+
const baseText = card.question && card.question.trim().length > 0 ? card.question : card.concept;
|
|
1849
|
+
const cleanDomain = slugify(card.domain || "");
|
|
1850
|
+
const cleanBase = slugify(baseText);
|
|
1851
|
+
let baseSlug = cleanDomain ? `${cleanDomain}-${cleanBase}` : cleanBase;
|
|
1852
|
+
if (baseSlug.length > 60) {
|
|
1853
|
+
baseSlug = baseSlug.slice(0, 60).replace(/-$/, "");
|
|
1854
|
+
}
|
|
1855
|
+
if (!baseSlug) {
|
|
1856
|
+
baseSlug = "token";
|
|
1857
|
+
}
|
|
1858
|
+
let token = await getTokenBySlug(tx, baseSlug);
|
|
1859
|
+
if (!token) {
|
|
1860
|
+
const finalSlug = await generateTokenSlug(
|
|
1861
|
+
tx,
|
|
1862
|
+
card.domain,
|
|
1863
|
+
card.concept,
|
|
1864
|
+
card.question
|
|
1865
|
+
);
|
|
1866
|
+
token = await createToken(tx, {
|
|
1867
|
+
slug: finalSlug,
|
|
1868
|
+
concept: card.concept,
|
|
1869
|
+
domain: card.domain,
|
|
1870
|
+
bloom_level: bloom,
|
|
1871
|
+
context: card.context || "",
|
|
1872
|
+
symbiosis_mode: symbiosisMode,
|
|
1873
|
+
source_link: card.source_link || originalToken.source_link || null,
|
|
1874
|
+
question: card.question || null
|
|
1875
|
+
});
|
|
1876
|
+
createdCount++;
|
|
1877
|
+
}
|
|
1878
|
+
if (token.id === originalToken.id) {
|
|
1879
|
+
throw new Error("A token cannot be a prerequisite of itself");
|
|
1880
|
+
}
|
|
1881
|
+
await assertPrerequisiteDoesNotCreateCycle(
|
|
1882
|
+
tx,
|
|
1883
|
+
originalToken.id,
|
|
1884
|
+
token.id
|
|
1885
|
+
);
|
|
1886
|
+
proposalTokens.push(token);
|
|
1887
|
+
const existingCard = await getCard(tx, token.id, userId);
|
|
1888
|
+
if (!existingCard) {
|
|
1889
|
+
await ensureCard(tx, token.id, userId);
|
|
1890
|
+
ensuredCount++;
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
if (action === "block") {
|
|
1894
|
+
await tx.prepare(
|
|
1895
|
+
"UPDATE tokens SET question = ?, concept = ?, updated_at = ? WHERE id = ?"
|
|
1896
|
+
).run(
|
|
1897
|
+
originalQuestion || null,
|
|
1898
|
+
originalConcept,
|
|
1899
|
+
(/* @__PURE__ */ new Date()).toISOString(),
|
|
1900
|
+
originalToken.id
|
|
1901
|
+
);
|
|
1902
|
+
for (const propToken of proposalTokens) {
|
|
1903
|
+
await tx.prepare(
|
|
1904
|
+
"INSERT OR IGNORE INTO prerequisites (token_id, requires_id) VALUES (?, ?)"
|
|
1905
|
+
).run(originalToken.id, propToken.id);
|
|
1906
|
+
}
|
|
1907
|
+
await tx.prepare(
|
|
1908
|
+
"UPDATE cards SET blocked = 1 WHERE token_id = ? AND user_id = ?"
|
|
1909
|
+
).run(originalToken.id, userId);
|
|
1910
|
+
for (const propToken of proposalTokens) {
|
|
1911
|
+
const card = await ensureCard(tx, propToken.id, userId);
|
|
1912
|
+
if (card.blocked === 1) {
|
|
1913
|
+
const prereqOfPrereq = await tx.prepare(
|
|
1914
|
+
"SELECT COUNT(*) as n FROM prerequisites WHERE token_id = ?"
|
|
1915
|
+
).get(propToken.id);
|
|
1916
|
+
if (prereqOfPrereq.n === 0) {
|
|
1917
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1918
|
+
await tx.prepare("UPDATE cards SET blocked = 0, due_at = ? WHERE id = ?").run(now, card.id);
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
} else if (action === "remove") {
|
|
1923
|
+
await deleteCardForUser(tx, originalToken.id, userId);
|
|
1924
|
+
}
|
|
1925
|
+
});
|
|
1926
|
+
return { createdCount, ensuredCount };
|
|
1927
|
+
}
|
|
1928
|
+
async function confirmFoundations(db, userId, originalSlug, proposals) {
|
|
1929
|
+
const originalToken = await getTokenBySlug(db, originalSlug);
|
|
1930
|
+
if (!originalToken) {
|
|
1931
|
+
throw new Error(`Original token not found: ${originalSlug}`);
|
|
1932
|
+
}
|
|
1933
|
+
let createdCount = 0;
|
|
1934
|
+
let linkedCount = 0;
|
|
1935
|
+
await db.transaction(async (tx) => {
|
|
1936
|
+
const originalCard = await getCard(tx, originalToken.id, userId);
|
|
1937
|
+
if (!originalCard) {
|
|
1938
|
+
throw new Error(
|
|
1939
|
+
`Card not found for token ${originalSlug} and user ${userId}`
|
|
1940
|
+
);
|
|
1941
|
+
}
|
|
1942
|
+
for (const card of proposals) {
|
|
1943
|
+
let targetTokenId;
|
|
1944
|
+
if (card.exists && card.slug) {
|
|
1945
|
+
const existingToken = await getTokenBySlug(tx, card.slug);
|
|
1946
|
+
if (!existingToken) {
|
|
1947
|
+
throw new Error(`Prerequisite token not found by slug: ${card.slug}`);
|
|
1948
|
+
}
|
|
1949
|
+
targetTokenId = existingToken.id;
|
|
1950
|
+
const existingCard = await getCard(tx, existingToken.id, userId);
|
|
1951
|
+
if (!existingCard) {
|
|
1952
|
+
await ensureCard(tx, existingToken.id, userId);
|
|
1953
|
+
}
|
|
1954
|
+
linkedCount++;
|
|
1955
|
+
} else {
|
|
1956
|
+
const bloom = card.bloom_level !== void 0 ? card.bloom_level : 1;
|
|
1957
|
+
if (bloom < 1 || bloom > 5) {
|
|
1958
|
+
throw new Error(`bloom_level must be between 1 and 5, got ${bloom}`);
|
|
1959
|
+
}
|
|
1960
|
+
let symbiosisMode = null;
|
|
1961
|
+
if (card.symbiosis_mode) {
|
|
1962
|
+
if (!["shadowing", "copilot", "autonomy", "none"].includes(
|
|
1963
|
+
card.symbiosis_mode
|
|
1964
|
+
)) {
|
|
1965
|
+
throw new Error(`Invalid symbiosis_mode: ${card.symbiosis_mode}`);
|
|
1966
|
+
}
|
|
1967
|
+
symbiosisMode = card.symbiosis_mode === "none" ? null : card.symbiosis_mode;
|
|
1968
|
+
}
|
|
1969
|
+
const baseText = card.question && card.question.trim().length > 0 ? card.question : card.concept;
|
|
1970
|
+
const cleanDomain = slugify(card.domain || "");
|
|
1971
|
+
const cleanBase = slugify(baseText);
|
|
1972
|
+
let baseSlug = cleanDomain ? `${cleanDomain}-${cleanBase}` : cleanBase;
|
|
1973
|
+
if (baseSlug.length > 60) {
|
|
1974
|
+
baseSlug = baseSlug.slice(0, 60).replace(/-$/, "");
|
|
1975
|
+
}
|
|
1976
|
+
if (!baseSlug) {
|
|
1977
|
+
baseSlug = "token";
|
|
1978
|
+
}
|
|
1979
|
+
let token = await getTokenBySlug(tx, baseSlug);
|
|
1980
|
+
if (!token) {
|
|
1981
|
+
const finalSlug = await generateTokenSlug(
|
|
1982
|
+
tx,
|
|
1983
|
+
card.domain,
|
|
1984
|
+
card.concept,
|
|
1985
|
+
card.question
|
|
1986
|
+
);
|
|
1987
|
+
token = await createToken(tx, {
|
|
1988
|
+
slug: finalSlug,
|
|
1989
|
+
concept: card.concept,
|
|
1990
|
+
domain: card.domain,
|
|
1991
|
+
bloom_level: bloom,
|
|
1992
|
+
context: card.context || "",
|
|
1993
|
+
symbiosis_mode: symbiosisMode,
|
|
1994
|
+
source_link: card.source_link || originalToken.source_link || null,
|
|
1995
|
+
question: card.question || null
|
|
1996
|
+
});
|
|
1997
|
+
createdCount++;
|
|
1998
|
+
}
|
|
1999
|
+
targetTokenId = token.id;
|
|
2000
|
+
const existingCard = await getCard(tx, token.id, userId);
|
|
2001
|
+
if (!existingCard) {
|
|
2002
|
+
await ensureCard(tx, token.id, userId);
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
if (targetTokenId === originalToken.id) {
|
|
2006
|
+
throw new Error("A token cannot be a prerequisite of itself");
|
|
2007
|
+
}
|
|
2008
|
+
await assertPrerequisiteDoesNotCreateCycle(
|
|
2009
|
+
tx,
|
|
2010
|
+
originalToken.id,
|
|
2011
|
+
targetTokenId
|
|
2012
|
+
);
|
|
2013
|
+
await tx.prepare(
|
|
2014
|
+
"INSERT OR IGNORE INTO prerequisites (token_id, requires_id) VALUES (?, ?)"
|
|
2015
|
+
).run(originalToken.id, targetTokenId);
|
|
2016
|
+
}
|
|
2017
|
+
});
|
|
2018
|
+
return { createdCount, linkedCount };
|
|
2019
|
+
}
|
|
2020
|
+
async function confirmSourceImport(db, userId, sourceId, proposals) {
|
|
2021
|
+
let createdCount = 0;
|
|
2022
|
+
let linkedCount = 0;
|
|
2023
|
+
await db.transaction(async (tx) => {
|
|
2024
|
+
const source = await tx.prepare("SELECT id FROM sources WHERE id = ?").get(sourceId);
|
|
2025
|
+
if (!source) {
|
|
2026
|
+
throw new Error(`Source not found: ${sourceId}`);
|
|
2027
|
+
}
|
|
2028
|
+
for (const card of proposals) {
|
|
2029
|
+
const baseText = card.question && card.question.trim().length > 0 ? card.question : card.concept;
|
|
2030
|
+
const cleanDomain = slugify(card.domain || "");
|
|
2031
|
+
const cleanBase = slugify(baseText);
|
|
2032
|
+
let baseSlug = cleanDomain ? `${cleanDomain}-${cleanBase}` : cleanBase;
|
|
2033
|
+
if (baseSlug.length > 60) {
|
|
2034
|
+
baseSlug = baseSlug.slice(0, 60).replace(/-$/, "");
|
|
2035
|
+
}
|
|
2036
|
+
if (!baseSlug) {
|
|
2037
|
+
baseSlug = "token";
|
|
2038
|
+
}
|
|
2039
|
+
let token = await getTokenBySlug(tx, baseSlug);
|
|
2040
|
+
if (!token) {
|
|
2041
|
+
const finalSlug = await generateTokenSlug(
|
|
2042
|
+
tx,
|
|
2043
|
+
card.domain,
|
|
2044
|
+
card.concept,
|
|
2045
|
+
card.question
|
|
2046
|
+
);
|
|
2047
|
+
const bloom = card.bloom_level !== void 0 ? card.bloom_level : 1;
|
|
2048
|
+
let symbiosisMode = null;
|
|
2049
|
+
if (card.symbiosis_mode && card.symbiosis_mode !== "none") {
|
|
2050
|
+
symbiosisMode = card.symbiosis_mode;
|
|
2051
|
+
}
|
|
2052
|
+
token = await createToken(tx, {
|
|
2053
|
+
slug: finalSlug,
|
|
2054
|
+
concept: card.concept,
|
|
2055
|
+
domain: card.domain,
|
|
2056
|
+
bloom_level: bloom,
|
|
2057
|
+
context: card.excerpt || "",
|
|
2058
|
+
symbiosis_mode: symbiosisMode,
|
|
2059
|
+
question: card.question || null
|
|
2060
|
+
});
|
|
2061
|
+
createdCount++;
|
|
2062
|
+
} else {
|
|
2063
|
+
linkedCount++;
|
|
2064
|
+
}
|
|
2065
|
+
const existingCard = await getCard(tx, token.id, userId);
|
|
2066
|
+
if (!existingCard) {
|
|
2067
|
+
await ensureCard(tx, token.id, userId);
|
|
2068
|
+
}
|
|
2069
|
+
await tx.prepare(
|
|
2070
|
+
`INSERT INTO token_sources (token_id, source_id, excerpt, page_number)
|
|
2071
|
+
VALUES (?, ?, ?, ?)
|
|
2072
|
+
ON CONFLICT(token_id, source_id) DO UPDATE SET
|
|
2073
|
+
excerpt = excluded.excerpt,
|
|
2074
|
+
page_number = excluded.page_number`
|
|
2075
|
+
).run(token.id, sourceId, card.excerpt || "", card.page_number || null);
|
|
2076
|
+
}
|
|
2077
|
+
});
|
|
2078
|
+
return { createdCount, linkedCount };
|
|
2079
|
+
}
|
|
2080
|
+
async function assertPrerequisiteDoesNotCreateCycle(db, tokenId, prerequisiteId) {
|
|
2081
|
+
const cycleCheck = await db.prepare(
|
|
2082
|
+
`WITH RECURSIVE dependents(token_id) AS (
|
|
2083
|
+
SELECT token_id FROM prerequisites WHERE requires_id = ?
|
|
2084
|
+
UNION
|
|
2085
|
+
SELECT p.token_id FROM prerequisites p
|
|
2086
|
+
JOIN dependents d ON p.requires_id = d.token_id
|
|
2087
|
+
)
|
|
2088
|
+
SELECT COUNT(*) as n FROM dependents WHERE token_id = ?`
|
|
2089
|
+
).get(tokenId, prerequisiteId);
|
|
2090
|
+
if (cycleCheck.n > 0) {
|
|
2091
|
+
throw new Error("Cannot add prerequisite: would create a cycle");
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
1649
2094
|
|
|
1650
2095
|
// src/kernel/models/prerequisite.ts
|
|
1651
2096
|
async function buildAncestorMap(db) {
|
|
@@ -5094,6 +5539,9 @@ export {
|
|
|
5094
5539
|
clearReviewContextCache,
|
|
5095
5540
|
clearTursoCredentials,
|
|
5096
5541
|
compareVersions,
|
|
5542
|
+
confirmCardSplit,
|
|
5543
|
+
confirmFoundations,
|
|
5544
|
+
confirmSourceImport,
|
|
5097
5545
|
createAgentSkill,
|
|
5098
5546
|
createFSRS,
|
|
5099
5547
|
createGoal,
|
|
@@ -5126,6 +5574,7 @@ export {
|
|
|
5126
5574
|
generatePowerShellHooks,
|
|
5127
5575
|
generatePowerShellUnhooks,
|
|
5128
5576
|
generatePrompt,
|
|
5577
|
+
generateTokenSlug,
|
|
5129
5578
|
generateZshHooks,
|
|
5130
5579
|
generateZshUnhooks,
|
|
5131
5580
|
getADOCredentials,
|
|
@@ -5171,6 +5620,7 @@ export {
|
|
|
5171
5620
|
getUiObserverDir,
|
|
5172
5621
|
getUserStats,
|
|
5173
5622
|
hasCommand,
|
|
5623
|
+
importCurriculumCards,
|
|
5174
5624
|
importSnapshot,
|
|
5175
5625
|
injectShellHooks,
|
|
5176
5626
|
installFastFlowLM,
|
|
@@ -5181,6 +5631,7 @@ export {
|
|
|
5181
5631
|
isUiObservationReport,
|
|
5182
5632
|
listAgentSkills,
|
|
5183
5633
|
listGoals,
|
|
5634
|
+
listPersonalCards,
|
|
5184
5635
|
listProviderApiKeyRefs,
|
|
5185
5636
|
listTokens,
|
|
5186
5637
|
loadADOConfig,
|
|
@@ -5229,6 +5680,7 @@ export {
|
|
|
5229
5680
|
setProviderApiKey,
|
|
5230
5681
|
setSetting,
|
|
5231
5682
|
setTursoCredentials,
|
|
5683
|
+
slugify,
|
|
5232
5684
|
startSession,
|
|
5233
5685
|
syncObserverSidecarPolicy,
|
|
5234
5686
|
t,
|