zam-core 0.3.3 → 0.3.5
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/{.gemini → .agent}/skills/zam/SKILL.md +361 -335
- package/.agents/skills/zam/SKILL.md +364 -0
- package/.claude/skills/zam/SKILL.md +331 -331
- package/LICENSE +199 -199
- package/README.de.md +127 -86
- package/README.md +147 -86
- package/dist/cli/index.js +6367 -2467
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +823 -547
- package/dist/index.js +2738 -1322
- package/dist/index.js.map +1 -1
- package/package.json +57 -56
package/dist/index.d.ts
CHANGED
|
@@ -1,163 +1,299 @@
|
|
|
1
1
|
import { Database } from 'libsql';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Learning Analytics
|
|
5
|
+
*
|
|
6
|
+
* Progress statistics, competence tracking, and session summaries.
|
|
7
|
+
* Ported from PoC's `stats` command with additions for FSRS and symbiosis modes.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
interface UserStats {
|
|
11
|
+
userId: string;
|
|
12
|
+
totalTokens: number;
|
|
13
|
+
cardsInDeck: number;
|
|
14
|
+
dueToday: number;
|
|
15
|
+
blocked: number;
|
|
16
|
+
mature: number;
|
|
17
|
+
avgStability: number | null;
|
|
18
|
+
totalSessions: number;
|
|
19
|
+
lastSession: string | null;
|
|
20
|
+
}
|
|
21
|
+
interface DomainCompetence {
|
|
22
|
+
domain: string;
|
|
23
|
+
totalCards: number;
|
|
24
|
+
matureCards: number;
|
|
25
|
+
avgStability: number;
|
|
26
|
+
retentionRate: number;
|
|
27
|
+
suggestedMode: "shadowing" | "copilot" | "autonomy";
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get overall learning stats for a user (ported from PoC's `stats` command).
|
|
31
|
+
*/
|
|
32
|
+
declare function getUserStats(db: Database, userId: string): UserStats;
|
|
33
|
+
/**
|
|
34
|
+
* Get competence per domain for a user.
|
|
35
|
+
* Used to suggest symbiosis mode transitions.
|
|
36
|
+
*/
|
|
37
|
+
declare function getDomainCompetence(db: Database, userId: string): DomainCompetence[];
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Azure DevOps connector — fetches work items from ADO boards.
|
|
41
|
+
*/
|
|
42
|
+
interface ADOConfig {
|
|
43
|
+
orgUrl: string;
|
|
44
|
+
project: string;
|
|
45
|
+
pat: string;
|
|
46
|
+
}
|
|
47
|
+
interface WorkItem {
|
|
48
|
+
id: number;
|
|
49
|
+
title: string;
|
|
50
|
+
state: string;
|
|
51
|
+
type: string;
|
|
52
|
+
assignedTo: string;
|
|
53
|
+
}
|
|
54
|
+
/** Load ADO config from credentials file. Returns null if not configured. */
|
|
55
|
+
declare function loadADOConfig(): ADOConfig | null;
|
|
56
|
+
/**
|
|
57
|
+
* Fetch active work items assigned to the current user.
|
|
58
|
+
* Uses WIQL to query, then batch-fetches work item details.
|
|
59
|
+
*/
|
|
60
|
+
declare function fetchActiveWorkItems(config: ADOConfig): Promise<WorkItem[]>;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Credential store — reads/writes ~/.zam/credentials.json
|
|
64
|
+
*
|
|
65
|
+
* Connector secrets (Turso URL/token, ADO PAT, etc.) live here instead of
|
|
66
|
+
* inside the SQLite database. This ensures credentials survive db deletion,
|
|
67
|
+
* which is required when migrating from plain SQLite to a libsql embedded
|
|
68
|
+
* replica (Turso cloud sync).
|
|
69
|
+
*/
|
|
70
|
+
interface TursoCredentials {
|
|
71
|
+
url: string;
|
|
72
|
+
token: string;
|
|
73
|
+
}
|
|
74
|
+
interface ADOCredentials {
|
|
75
|
+
org_url: string;
|
|
76
|
+
project: string;
|
|
77
|
+
pat: string;
|
|
78
|
+
}
|
|
79
|
+
interface Credentials {
|
|
80
|
+
turso?: Partial<TursoCredentials>;
|
|
81
|
+
ado?: Partial<ADOCredentials>;
|
|
82
|
+
}
|
|
83
|
+
/** Load credentials from ~/.zam/credentials.json. Returns empty object if missing. */
|
|
84
|
+
declare function loadCredentials(path?: string): Credentials;
|
|
85
|
+
/** Save credentials to ~/.zam/credentials.json. */
|
|
86
|
+
declare function saveCredentials(creds: Credentials, path?: string): void;
|
|
87
|
+
/** Get complete Turso credentials, or null if incomplete. */
|
|
88
|
+
declare function getTursoCredentials(path?: string): TursoCredentials | null;
|
|
89
|
+
/** Set Turso credentials. */
|
|
90
|
+
declare function setTursoCredentials(url: string, token: string, path?: string): void;
|
|
91
|
+
/** Clear Turso credentials. */
|
|
92
|
+
declare function clearTursoCredentials(path?: string): void;
|
|
93
|
+
/** Get complete ADO credentials, or null if incomplete. */
|
|
94
|
+
declare function getADOCredentials(path?: string): ADOCredentials | null;
|
|
95
|
+
/** Set ADO credentials. */
|
|
96
|
+
declare function setADOCredentials(orgUrl: string, project: string, pat: string, path?: string): void;
|
|
97
|
+
/** Clear ADO credentials. */
|
|
98
|
+
declare function clearADOCredentials(path?: string): void;
|
|
99
|
+
|
|
3
100
|
interface ConnectionOptions {
|
|
4
101
|
/** Path to the SQLite database file. Defaults to ~/.zam/zam.db */
|
|
5
102
|
dbPath?: string;
|
|
6
103
|
/** If true, create the directory and run schema migrations on open */
|
|
7
104
|
initialize?: boolean;
|
|
8
|
-
/** Turso sync URL for
|
|
105
|
+
/** Turso sync URL for embedded replica mode (e.g. libsql://db-name.turso.io) */
|
|
9
106
|
syncUrl?: string;
|
|
10
|
-
/** Turso auth token for
|
|
107
|
+
/** Turso auth token for direct remote or embedded replica access */
|
|
11
108
|
authToken?: string;
|
|
109
|
+
/** If false, ignore ~/.zam/credentials.json and force the local/default database. */
|
|
110
|
+
useConfiguredCloud?: boolean;
|
|
12
111
|
}
|
|
13
112
|
/**
|
|
14
113
|
* Open (or create) the ZAM database.
|
|
15
|
-
* Uses
|
|
16
|
-
*
|
|
114
|
+
* Uses configured Turso credentials for the default database when present.
|
|
115
|
+
* Falls back to local SQLite and WAL mode when no cloud credentials exist.
|
|
116
|
+
* When syncUrl is provided explicitly, enables embedded replica sync with Turso.
|
|
17
117
|
*/
|
|
18
118
|
declare function openDatabase(options?: ConnectionOptions): Database;
|
|
19
119
|
/**
|
|
20
|
-
* Open the database with Turso cloud
|
|
21
|
-
*
|
|
22
|
-
*
|
|
120
|
+
* Open the database with Turso cloud credentials auto-detected.
|
|
121
|
+
* Credentials live in ~/.zam/credentials.json (NOT in the db), so a fresh
|
|
122
|
+
* machine only has to collect missing secrets instead of bootstrapping local
|
|
123
|
+
* state first.
|
|
23
124
|
*/
|
|
24
125
|
declare function openDatabaseWithSync(options?: Omit<ConnectionOptions, "syncUrl" | "authToken">): Database;
|
|
25
126
|
/** Get the default database path */
|
|
26
127
|
declare function getDefaultDbPath(): string;
|
|
27
128
|
|
|
28
129
|
/**
|
|
29
|
-
*
|
|
130
|
+
* Goal file parser — reads markdown files with YAML-style frontmatter.
|
|
30
131
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
132
|
+
* Goals are persisted as markdown files in the personal repo.
|
|
133
|
+
* Each file has simple key: value frontmatter (no nested structures)
|
|
134
|
+
* and a markdown body with description, tasks, and token references.
|
|
33
135
|
*/
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
type SymbiosisMode = "shadowing" | "copilot" | "autonomy";
|
|
37
|
-
interface Token {
|
|
38
|
-
id: string;
|
|
39
|
-
slug: string;
|
|
40
|
-
concept: string;
|
|
41
|
-
domain: string;
|
|
42
|
-
bloom_level: BloomLevel$1;
|
|
43
|
-
context: string;
|
|
44
|
-
symbiosis_mode: SymbiosisMode | null;
|
|
45
|
-
created_at: string;
|
|
46
|
-
updated_at: string;
|
|
47
|
-
deprecated_at: string | null;
|
|
48
|
-
}
|
|
49
|
-
interface CreateTokenInput {
|
|
136
|
+
type GoalStatus = "active" | "completed" | "paused" | "abandoned";
|
|
137
|
+
interface Goal {
|
|
50
138
|
slug: string;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
domain?: string;
|
|
139
|
+
title: string;
|
|
140
|
+
status: GoalStatus;
|
|
141
|
+
parent: string | null;
|
|
142
|
+
created: string;
|
|
143
|
+
updated: string;
|
|
144
|
+
body: string;
|
|
145
|
+
filePath: string;
|
|
59
146
|
}
|
|
60
|
-
interface
|
|
61
|
-
|
|
147
|
+
interface GoalFrontmatter {
|
|
148
|
+
title?: string;
|
|
149
|
+
status?: string;
|
|
150
|
+
parent?: string;
|
|
151
|
+
created?: string;
|
|
152
|
+
updated?: string;
|
|
62
153
|
}
|
|
63
154
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
*
|
|
75
|
-
*
|
|
155
|
+
* Parse a goal markdown file into a Goal object.
|
|
156
|
+
*
|
|
157
|
+
* Expected format:
|
|
158
|
+
* ```
|
|
159
|
+
* ---
|
|
160
|
+
* title: Learn Rust fundamentals
|
|
161
|
+
* status: active
|
|
162
|
+
* parent: become-systems-programmer
|
|
163
|
+
* created: 2026-03-28
|
|
164
|
+
* updated: 2026-03-28
|
|
165
|
+
* ---
|
|
166
|
+
*
|
|
167
|
+
* ## Description
|
|
168
|
+
* ...
|
|
169
|
+
* ```
|
|
170
|
+
*
|
|
171
|
+
* @param content - Raw file content
|
|
172
|
+
* @param slug - Goal slug (derived from filename by caller)
|
|
173
|
+
* @param filePath - Absolute path to the file
|
|
76
174
|
*/
|
|
77
|
-
declare function
|
|
175
|
+
declare function parseGoalFile(content: string, slug: string, filePath: string): Goal;
|
|
78
176
|
/**
|
|
79
|
-
*
|
|
80
|
-
* and search results but are not deleted — they can still be consulted.
|
|
81
|
-
*
|
|
82
|
-
* Throws if the token does not exist or is already deprecated.
|
|
177
|
+
* Serialize a Goal back to markdown with frontmatter.
|
|
83
178
|
*/
|
|
84
|
-
declare function
|
|
179
|
+
declare function serializeGoal(goal: Goal): string;
|
|
85
180
|
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* Ported from the PoC's find-token command: splits the query into word
|
|
89
|
-
* tokens, scores each database token by word overlap plus a substring
|
|
90
|
-
* bonus on the concept field, and returns all matches sorted by score
|
|
91
|
-
* descending.
|
|
181
|
+
* Extract tasks (checklist items) from goal body.
|
|
182
|
+
* Returns items like { text: "Complete Rustlings", done: false }.
|
|
92
183
|
*/
|
|
93
|
-
declare function
|
|
184
|
+
declare function extractTasks(body: string): Array<{
|
|
185
|
+
text: string;
|
|
186
|
+
done: boolean;
|
|
187
|
+
}>;
|
|
94
188
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
189
|
+
* Extract token references from goal body.
|
|
190
|
+
* Looks for lines like `- token/slug` under a "## Tokens" section.
|
|
97
191
|
*/
|
|
98
|
-
declare function
|
|
192
|
+
declare function extractTokenRefs(body: string): string[];
|
|
99
193
|
|
|
100
194
|
/**
|
|
101
|
-
*
|
|
195
|
+
* Goal Engine — manages goal lifecycle via markdown files.
|
|
102
196
|
*
|
|
103
|
-
*
|
|
197
|
+
* Goals live as markdown files in a directory (typically the personal repo's
|
|
198
|
+
* goals/ folder). The engine reads, creates, and updates these files.
|
|
199
|
+
* It does not depend on the database — goals are git-tracked, not DB-tracked.
|
|
104
200
|
*/
|
|
105
201
|
|
|
106
|
-
interface
|
|
107
|
-
|
|
108
|
-
|
|
202
|
+
interface GoalSummary {
|
|
203
|
+
slug: string;
|
|
204
|
+
title: string;
|
|
205
|
+
status: GoalStatus;
|
|
206
|
+
parent: string | null;
|
|
207
|
+
taskCount: number;
|
|
208
|
+
tasksDone: number;
|
|
209
|
+
tokenCount: number;
|
|
109
210
|
}
|
|
110
|
-
|
|
111
|
-
interface PrerequisiteWithToken extends Prerequisite {
|
|
211
|
+
interface CreateGoalInput {
|
|
112
212
|
slug: string;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
213
|
+
title: string;
|
|
214
|
+
status?: GoalStatus;
|
|
215
|
+
parent?: string;
|
|
216
|
+
description?: string;
|
|
116
217
|
}
|
|
117
218
|
/**
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
* Idempotent — silently ignores duplicate edges.
|
|
121
|
-
* Throws if either token ID does not exist (FK constraint).
|
|
122
|
-
* Throws if a token is declared as its own prerequisite.
|
|
219
|
+
* List all goals in the goals directory.
|
|
220
|
+
* Returns summaries sorted by status (active first) then title.
|
|
123
221
|
*/
|
|
124
|
-
declare function
|
|
222
|
+
declare function listGoals(goalsDir: string): GoalSummary[];
|
|
125
223
|
/**
|
|
126
|
-
* Get
|
|
127
|
-
*
|
|
128
|
-
* Returns prerequisite rows joined with the required token's details.
|
|
224
|
+
* Get a single goal by slug (filename without .md).
|
|
225
|
+
* Returns undefined if the file doesn't exist.
|
|
129
226
|
*/
|
|
130
|
-
declare function
|
|
227
|
+
declare function getGoal(goalsDir: string, slug: string): Goal | undefined;
|
|
131
228
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* Returns prerequisite rows joined with the dependent token's details.
|
|
229
|
+
* Create a new goal file. Throws if a goal with this slug already exists.
|
|
135
230
|
*/
|
|
136
|
-
declare function
|
|
231
|
+
declare function createGoal(goalsDir: string, input: CreateGoalInput): Goal;
|
|
232
|
+
/**
|
|
233
|
+
* Update a goal's status. Writes the updated file back to disk.
|
|
234
|
+
*/
|
|
235
|
+
declare function updateGoalStatus(goalsDir: string, slug: string, status: GoalStatus): Goal;
|
|
236
|
+
/**
|
|
237
|
+
* Get the goal tree — goals organized by parent relationships.
|
|
238
|
+
* Returns root goals (no parent) with nested children.
|
|
239
|
+
*/
|
|
240
|
+
declare function getGoalTree(goalsDir: string): Array<GoalSummary & {
|
|
241
|
+
children: GoalSummary[];
|
|
242
|
+
}>;
|
|
137
243
|
|
|
138
244
|
/**
|
|
139
|
-
*
|
|
245
|
+
* Agent skills: task recipes the agent learns from user guidance.
|
|
140
246
|
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
247
|
+
* When the agent cannot execute a step, it admits it, asks for guidance,
|
|
248
|
+
* and saves the successful approach here. Skills are linked to tokens so
|
|
249
|
+
* FSRS decay naturally resurfaces them for review — automation ≠ retention.
|
|
143
250
|
*/
|
|
144
251
|
|
|
145
|
-
type
|
|
146
|
-
interface
|
|
252
|
+
type SkillSource = "learned" | "builtin";
|
|
253
|
+
interface AgentSkill {
|
|
147
254
|
id: string;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
255
|
+
slug: string;
|
|
256
|
+
description: string;
|
|
257
|
+
steps: string[];
|
|
258
|
+
token_slugs: string[];
|
|
259
|
+
source: SkillSource;
|
|
260
|
+
created_at: string;
|
|
261
|
+
updated_at: string;
|
|
262
|
+
}
|
|
263
|
+
interface CreateAgentSkillInput {
|
|
264
|
+
slug: string;
|
|
265
|
+
description: string;
|
|
266
|
+
steps: string[];
|
|
267
|
+
token_slugs?: string[];
|
|
268
|
+
source?: SkillSource;
|
|
269
|
+
}
|
|
270
|
+
declare function createAgentSkill(db: Database, input: CreateAgentSkillInput): AgentSkill;
|
|
271
|
+
declare function getAgentSkill(db: Database, slug: string): AgentSkill | undefined;
|
|
272
|
+
declare function listAgentSkills(db: Database): AgentSkill[];
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Card repository — typed wrappers around the cards table.
|
|
276
|
+
*
|
|
277
|
+
* Each card tracks one user's scheduling state for one token,
|
|
278
|
+
* using FSRS fields (stability, difficulty, elapsed_days, etc.).
|
|
279
|
+
*/
|
|
280
|
+
|
|
281
|
+
type CardState$1 = "new" | "learning" | "review" | "relearning";
|
|
282
|
+
interface Card {
|
|
283
|
+
id: string;
|
|
284
|
+
token_id: string;
|
|
285
|
+
user_id: string;
|
|
286
|
+
stability: number;
|
|
287
|
+
difficulty: number;
|
|
288
|
+
elapsed_days: number;
|
|
289
|
+
scheduled_days: number;
|
|
290
|
+
reps: number;
|
|
291
|
+
lapses: number;
|
|
292
|
+
state: CardState$1;
|
|
293
|
+
due_at: string;
|
|
294
|
+
last_review_at: string | null;
|
|
295
|
+
blocked: number;
|
|
296
|
+
}
|
|
161
297
|
interface UpdateCardInput {
|
|
162
298
|
stability?: number;
|
|
163
299
|
difficulty?: number;
|
|
@@ -170,6 +306,13 @@ interface UpdateCardInput {
|
|
|
170
306
|
last_review_at?: string | null;
|
|
171
307
|
blocked?: number;
|
|
172
308
|
}
|
|
309
|
+
interface CardDeletionImpact {
|
|
310
|
+
review_logs: number;
|
|
311
|
+
}
|
|
312
|
+
interface DeleteCardResult {
|
|
313
|
+
card: Card;
|
|
314
|
+
impact: CardDeletionImpact;
|
|
315
|
+
}
|
|
173
316
|
/** A due card joined with its token details. */
|
|
174
317
|
interface DueCard extends Card {
|
|
175
318
|
slug: string;
|
|
@@ -197,6 +340,10 @@ declare function ensureCard(db: Database, tokenId: string, userId: string): Card
|
|
|
197
340
|
* Get a card by token+user. Returns undefined if no card exists.
|
|
198
341
|
*/
|
|
199
342
|
declare function getCard(db: Database, tokenId: string, userId: string): Card | undefined;
|
|
343
|
+
/**
|
|
344
|
+
* Get a card by its ULID.
|
|
345
|
+
*/
|
|
346
|
+
declare function getCardById(db: Database, cardId: string): Card | undefined;
|
|
200
347
|
/**
|
|
201
348
|
* Update a card's scheduling fields.
|
|
202
349
|
*
|
|
@@ -204,6 +351,14 @@ declare function getCard(db: Database, tokenId: string, userId: string): Card |
|
|
|
204
351
|
* does not exist.
|
|
205
352
|
*/
|
|
206
353
|
declare function updateCard(db: Database, cardId: string, updates: UpdateCardInput): Card;
|
|
354
|
+
/**
|
|
355
|
+
* Preview the review-log rows that will be removed when deleting a user's card.
|
|
356
|
+
*/
|
|
357
|
+
declare function getCardDeletionImpact(db: Database, tokenId: string, userId: string): CardDeletionImpact;
|
|
358
|
+
/**
|
|
359
|
+
* Delete one user's card for a token. Review logs cascade via FK.
|
|
360
|
+
*/
|
|
361
|
+
declare function deleteCardForUser(db: Database, tokenId: string, userId: string): DeleteCardResult;
|
|
207
362
|
/**
|
|
208
363
|
* Get all cards that are due for review.
|
|
209
364
|
*
|
|
@@ -222,6 +377,44 @@ declare function getDueCards(db: Database, userId: string, now?: string): DueCar
|
|
|
222
377
|
*/
|
|
223
378
|
declare function getBlockedCards(db: Database, userId: string): BlockedCard[];
|
|
224
379
|
|
|
380
|
+
/**
|
|
381
|
+
* Prerequisite repository — typed wrappers around the prerequisites table.
|
|
382
|
+
*
|
|
383
|
+
* Models the dependency graph: "to learn token A, first know token B."
|
|
384
|
+
*/
|
|
385
|
+
|
|
386
|
+
interface Prerequisite {
|
|
387
|
+
token_id: string;
|
|
388
|
+
requires_id: string;
|
|
389
|
+
}
|
|
390
|
+
/** A prerequisite row joined with the token it points to. */
|
|
391
|
+
interface PrerequisiteWithToken extends Prerequisite {
|
|
392
|
+
slug: string;
|
|
393
|
+
concept: string;
|
|
394
|
+
domain: string;
|
|
395
|
+
bloom_level: number;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Add a prerequisite edge: tokenId requires requiresId.
|
|
399
|
+
*
|
|
400
|
+
* Idempotent — silently ignores duplicate edges.
|
|
401
|
+
* Throws if either token ID does not exist (FK constraint).
|
|
402
|
+
* Throws if a token is declared as its own prerequisite.
|
|
403
|
+
*/
|
|
404
|
+
declare function addPrerequisite(db: Database, tokenId: string, requiresId: string): void;
|
|
405
|
+
/**
|
|
406
|
+
* Get the direct prerequisites of a token — "what does token X require?"
|
|
407
|
+
*
|
|
408
|
+
* Returns prerequisite rows joined with the required token's details.
|
|
409
|
+
*/
|
|
410
|
+
declare function getPrerequisites(db: Database, tokenId: string): PrerequisiteWithToken[];
|
|
411
|
+
/**
|
|
412
|
+
* Get the direct dependents of a token — "what depends on token X?"
|
|
413
|
+
*
|
|
414
|
+
* Returns prerequisite rows joined with the dependent token's details.
|
|
415
|
+
*/
|
|
416
|
+
declare function getDependents(db: Database, tokenId: string): PrerequisiteWithToken[];
|
|
417
|
+
|
|
225
418
|
/**
|
|
226
419
|
* Review log repository — typed wrappers around the review_logs table.
|
|
227
420
|
*
|
|
@@ -356,36 +549,6 @@ declare function logStep(db: Database, input: LogStepInput): SessionStep;
|
|
|
356
549
|
*/
|
|
357
550
|
declare function getSessionSummary(db: Database, sessionId: string): SessionSummary;
|
|
358
551
|
|
|
359
|
-
/**
|
|
360
|
-
* Agent skills: task recipes the agent learns from user guidance.
|
|
361
|
-
*
|
|
362
|
-
* When the agent cannot execute a step, it admits it, asks for guidance,
|
|
363
|
-
* and saves the successful approach here. Skills are linked to tokens so
|
|
364
|
-
* FSRS decay naturally resurfaces them for review — automation ≠ retention.
|
|
365
|
-
*/
|
|
366
|
-
|
|
367
|
-
type SkillSource = "learned" | "builtin";
|
|
368
|
-
interface AgentSkill {
|
|
369
|
-
id: string;
|
|
370
|
-
slug: string;
|
|
371
|
-
description: string;
|
|
372
|
-
steps: string[];
|
|
373
|
-
token_slugs: string[];
|
|
374
|
-
source: SkillSource;
|
|
375
|
-
created_at: string;
|
|
376
|
-
updated_at: string;
|
|
377
|
-
}
|
|
378
|
-
interface CreateAgentSkillInput {
|
|
379
|
-
slug: string;
|
|
380
|
-
description: string;
|
|
381
|
-
steps: string[];
|
|
382
|
-
token_slugs?: string[];
|
|
383
|
-
source?: SkillSource;
|
|
384
|
-
}
|
|
385
|
-
declare function createAgentSkill(db: Database, input: CreateAgentSkillInput): AgentSkill;
|
|
386
|
-
declare function getAgentSkill(db: Database, slug: string): AgentSkill | undefined;
|
|
387
|
-
declare function listAgentSkills(db: Database): AgentSkill[];
|
|
388
|
-
|
|
389
552
|
/**
|
|
390
553
|
* User settings — key/value store backed by the user_config table.
|
|
391
554
|
*/
|
|
@@ -407,56 +570,299 @@ declare function setSetting(db: Database, key: string, value: string): void;
|
|
|
407
570
|
declare function deleteSetting(db: Database, key: string): boolean;
|
|
408
571
|
|
|
409
572
|
/**
|
|
410
|
-
*
|
|
573
|
+
* Token repository — typed wrappers around the tokens table.
|
|
411
574
|
*
|
|
412
|
-
*
|
|
413
|
-
*
|
|
414
|
-
|
|
575
|
+
* Tokens are atomic knowledge concepts with Bloom taxonomy levels
|
|
576
|
+
* and optional symbiosis modes (shadowing / copilot / autonomy).
|
|
577
|
+
*/
|
|
578
|
+
|
|
579
|
+
type BloomLevel$1 = 1 | 2 | 3 | 4 | 5;
|
|
580
|
+
type SymbiosisMode = "shadowing" | "copilot" | "autonomy";
|
|
581
|
+
interface Token {
|
|
582
|
+
id: string;
|
|
583
|
+
slug: string;
|
|
584
|
+
concept: string;
|
|
585
|
+
domain: string;
|
|
586
|
+
bloom_level: BloomLevel$1;
|
|
587
|
+
context: string;
|
|
588
|
+
symbiosis_mode: SymbiosisMode | null;
|
|
589
|
+
source_link: string | null;
|
|
590
|
+
question: string | null;
|
|
591
|
+
created_at: string;
|
|
592
|
+
updated_at: string;
|
|
593
|
+
deprecated_at: string | null;
|
|
594
|
+
}
|
|
595
|
+
interface CreateTokenInput {
|
|
596
|
+
slug: string;
|
|
597
|
+
concept: string;
|
|
598
|
+
domain?: string;
|
|
599
|
+
bloom_level?: BloomLevel$1;
|
|
600
|
+
context?: string;
|
|
601
|
+
symbiosis_mode?: SymbiosisMode | null;
|
|
602
|
+
source_link?: string | null;
|
|
603
|
+
question?: string | null;
|
|
604
|
+
}
|
|
605
|
+
interface UpdateTokenInput {
|
|
606
|
+
concept?: string;
|
|
607
|
+
domain?: string;
|
|
608
|
+
bloom_level?: BloomLevel$1;
|
|
609
|
+
context?: string;
|
|
610
|
+
symbiosis_mode?: SymbiosisMode | null;
|
|
611
|
+
source_link?: string | null;
|
|
612
|
+
question?: string | null;
|
|
613
|
+
}
|
|
614
|
+
interface ListTokensOptions {
|
|
615
|
+
domain?: string;
|
|
616
|
+
}
|
|
617
|
+
interface TokenDeleteImpact {
|
|
618
|
+
cards: number;
|
|
619
|
+
review_logs: number;
|
|
620
|
+
prerequisite_edges_from_token: number;
|
|
621
|
+
prerequisite_edges_to_token: number;
|
|
622
|
+
session_steps: number;
|
|
623
|
+
sessions_touched: number;
|
|
624
|
+
agent_skills: number;
|
|
625
|
+
}
|
|
626
|
+
interface DeleteTokenResult {
|
|
627
|
+
token: Token;
|
|
628
|
+
impact: TokenDeleteImpact;
|
|
629
|
+
}
|
|
630
|
+
interface ScoredToken extends Token {
|
|
631
|
+
score: number;
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Create a new knowledge token.
|
|
635
|
+
* Throws if a token with the same slug already exists.
|
|
636
|
+
*/
|
|
637
|
+
declare function createToken(db: Database, input: CreateTokenInput): Token;
|
|
638
|
+
/**
|
|
639
|
+
* Look up a token by its unique slug.
|
|
640
|
+
* Returns undefined if not found.
|
|
641
|
+
*/
|
|
642
|
+
declare function getTokenBySlug(db: Database, slug: string): Token | undefined;
|
|
643
|
+
/**
|
|
644
|
+
* Look up a token by its ULID.
|
|
645
|
+
* Returns undefined if not found.
|
|
646
|
+
*/
|
|
647
|
+
declare function getTokenById(db: Database, id: string): Token | undefined;
|
|
648
|
+
/**
|
|
649
|
+
* Update mutable fields on a token.
|
|
415
650
|
*
|
|
416
|
-
*
|
|
651
|
+
* Slug is intentionally immutable in v1 because it is referenced by other
|
|
652
|
+
* parts of the system (for example agent skill metadata).
|
|
417
653
|
*/
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
654
|
+
declare function updateToken(db: Database, slug: string, updates: UpdateTokenInput): Token;
|
|
655
|
+
/**
|
|
656
|
+
* Mark a token as deprecated. Deprecated tokens are excluded from review queues
|
|
657
|
+
* and search results but are not deleted — they can still be consulted.
|
|
658
|
+
*
|
|
659
|
+
* Throws if the token does not exist or is already deprecated.
|
|
660
|
+
*/
|
|
661
|
+
declare function deprecateToken(db: Database, slug: string): Token;
|
|
662
|
+
/**
|
|
663
|
+
* Preview the rows that will be removed or updated when deleting a token.
|
|
664
|
+
*/
|
|
665
|
+
declare function getTokenDeleteImpact(db: Database, slug: string): TokenDeleteImpact;
|
|
666
|
+
/**
|
|
667
|
+
* Hard-delete a token and clean up non-FK references that point at its slug.
|
|
668
|
+
*/
|
|
669
|
+
declare function deleteToken(db: Database, slug: string): DeleteTokenResult;
|
|
670
|
+
/**
|
|
671
|
+
* Fuzzy search for tokens by keyword query.
|
|
672
|
+
*
|
|
673
|
+
* Ported from the PoC's find-token command: splits the query into word
|
|
674
|
+
* tokens, scores each database token by word overlap plus a substring
|
|
675
|
+
* bonus on the concept field, and returns all matches sorted by score
|
|
676
|
+
* descending.
|
|
677
|
+
*/
|
|
678
|
+
declare function findTokens(db: Database, query: string): ScoredToken[];
|
|
679
|
+
/**
|
|
680
|
+
* List all tokens, optionally filtered by domain.
|
|
681
|
+
* Results are ordered by bloom_level then slug.
|
|
682
|
+
*/
|
|
683
|
+
declare function listTokens(db: Database, options?: ListTokensOptions): Token[];
|
|
684
|
+
|
|
685
|
+
/**
|
|
686
|
+
* Monitor log analyzer — maps observed shell commands to token ratings.
|
|
687
|
+
*
|
|
688
|
+
* Pure functions, no DB or filesystem access. Takes parsed command records
|
|
689
|
+
* and a token-to-pattern mapping, returns ratings with evidence.
|
|
690
|
+
*/
|
|
691
|
+
interface MonitorEvent {
|
|
692
|
+
type: "command_start" | "command_end" | "monitor_meta";
|
|
693
|
+
ts: string;
|
|
694
|
+
seq?: number;
|
|
695
|
+
pid?: number;
|
|
696
|
+
command?: string;
|
|
697
|
+
cwd?: string;
|
|
698
|
+
exit_code?: number;
|
|
699
|
+
event?: "start" | "stop";
|
|
700
|
+
session_id?: string;
|
|
701
|
+
shell?: string;
|
|
440
702
|
}
|
|
441
|
-
interface
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
703
|
+
interface CommandRecord {
|
|
704
|
+
seq: number;
|
|
705
|
+
pid: number;
|
|
706
|
+
command: string;
|
|
707
|
+
cwd: string;
|
|
708
|
+
startedAt: string;
|
|
709
|
+
endedAt: string | null;
|
|
710
|
+
durationMs: number | null;
|
|
711
|
+
exitCode: number | null;
|
|
446
712
|
}
|
|
447
|
-
interface
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
713
|
+
interface TokenPattern {
|
|
714
|
+
slug: string;
|
|
715
|
+
patterns: string[];
|
|
716
|
+
}
|
|
717
|
+
interface ObservationRating {
|
|
718
|
+
tokenSlug: string;
|
|
719
|
+
rating: 1 | 2 | 3 | 4 | null;
|
|
720
|
+
confidence: "high" | "medium" | "low";
|
|
721
|
+
evidence: {
|
|
722
|
+
matchedCommands: number;
|
|
723
|
+
helpSeeking: boolean;
|
|
724
|
+
errorCount: number;
|
|
725
|
+
selfCorrections: number;
|
|
726
|
+
medianGapMs: number | null;
|
|
727
|
+
thinkingGapMs: number | null;
|
|
728
|
+
};
|
|
729
|
+
matchedCommandTexts: string[];
|
|
730
|
+
}
|
|
731
|
+
interface AnalysisResult {
|
|
732
|
+
ratings: ObservationRating[];
|
|
733
|
+
unmatchedCommands: string[];
|
|
734
|
+
timeSpan: {
|
|
735
|
+
start: string;
|
|
736
|
+
end: string;
|
|
737
|
+
durationMs: number;
|
|
738
|
+
} | null;
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Parse a JSONL string into MonitorEvent objects.
|
|
742
|
+
* Skips malformed lines silently.
|
|
743
|
+
*/
|
|
744
|
+
declare function parseMonitorLog(jsonl: string): MonitorEvent[];
|
|
745
|
+
/**
|
|
746
|
+
* Pair command_start and command_end events by (pid, seq) into CommandRecords.
|
|
747
|
+
*/
|
|
748
|
+
declare function pairCommands(events: MonitorEvent[]): CommandRecord[];
|
|
749
|
+
/**
|
|
750
|
+
* Analyze observed commands against token patterns and produce ratings.
|
|
751
|
+
*/
|
|
752
|
+
declare function analyzeObservation(commands: CommandRecord[], tokenPatterns: TokenPattern[]): AnalysisResult;
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* Monitor I/O — read/write JSONL files for shell observation.
|
|
756
|
+
*
|
|
757
|
+
* Monitor logs live at ~/.zam/monitor/<session-id>.jsonl.
|
|
758
|
+
* Separated from analyzer.ts so the analyzer remains pure-function testable.
|
|
759
|
+
*/
|
|
760
|
+
|
|
761
|
+
/** Get the monitor directory path. */
|
|
762
|
+
declare function getMonitorDir(): string;
|
|
763
|
+
/** Get the JSONL file path for a session. */
|
|
764
|
+
declare function getMonitorPath(sessionId: string): string;
|
|
765
|
+
/** Ensure the monitor directory exists (mode 0700 for privacy). */
|
|
766
|
+
declare function ensureMonitorDir(): void;
|
|
767
|
+
/** Append a single event to the session's JSONL file. */
|
|
768
|
+
declare function writeMonitorEvent(sessionId: string, event: MonitorEvent): void;
|
|
769
|
+
/** Read and parse all events from a session's monitor log. */
|
|
770
|
+
declare function readMonitorLog(sessionId: string): MonitorEvent[];
|
|
771
|
+
/** Check if a monitor log exists for a session. */
|
|
772
|
+
declare function monitorLogExists(sessionId: string): boolean;
|
|
773
|
+
/** Get basic stats about a monitor log without full parsing. */
|
|
774
|
+
declare function getMonitorLogStats(sessionId: string): {
|
|
775
|
+
exists: boolean;
|
|
776
|
+
sizeBytes: number;
|
|
777
|
+
lineCount: number;
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* Shell hook code generation for zsh, bash, and PowerShell.
|
|
782
|
+
*
|
|
783
|
+
* Pure functions that return shell code strings. The CLI command
|
|
784
|
+
* `zam monitor start/stop` calls these and prints to stdout.
|
|
785
|
+
*/
|
|
786
|
+
/**
|
|
787
|
+
* Generate zsh hooks that capture commands to a JSONL file.
|
|
788
|
+
* Uses $EPOCHREALTIME for sub-second timestamp precision.
|
|
789
|
+
*/
|
|
790
|
+
declare function generateZshHooks(monitorFile: string, sessionId: string): string;
|
|
791
|
+
/**
|
|
792
|
+
* Generate bash hooks that capture commands to a JSONL file.
|
|
793
|
+
* Uses DEBUG trap for preexec, PROMPT_COMMAND for precmd.
|
|
794
|
+
*/
|
|
795
|
+
declare function generateBashHooks(monitorFile: string, sessionId: string): string;
|
|
796
|
+
/**
|
|
797
|
+
* Generate PowerShell hooks that capture completed commands to a JSONL file.
|
|
798
|
+
* PowerShell has no zsh-style preexec hook, so this records the most recent
|
|
799
|
+
* history item from the prompt function after each command completes.
|
|
800
|
+
*/
|
|
801
|
+
declare function generatePowerShellHooks(monitorFile: string, sessionId: string): string;
|
|
802
|
+
/** Generate zsh code to remove monitor hooks. */
|
|
803
|
+
declare function generateZshUnhooks(): string;
|
|
804
|
+
/** Generate bash code to remove monitor hooks. */
|
|
805
|
+
declare function generateBashUnhooks(): string;
|
|
806
|
+
/** Generate PowerShell code to remove monitor hooks. */
|
|
807
|
+
declare function generatePowerShellUnhooks(): string;
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* Skill Discovery — identifies recurring non-standard command patterns
|
|
811
|
+
* across multiple sessions and proposes them as minimal reusable skills.
|
|
812
|
+
*
|
|
813
|
+
* The key insight from Increment 2: "The human's demonstrated competence
|
|
814
|
+
* is the gate for automation — not the other way around." A pattern must
|
|
815
|
+
* appear consistently across sessions before being proposed as a skill.
|
|
816
|
+
*
|
|
817
|
+
* Pure functions — no DB access. Callers provide command records and
|
|
818
|
+
* existing skills; this module returns proposed skills.
|
|
819
|
+
*/
|
|
820
|
+
|
|
821
|
+
interface CommandSequence {
|
|
822
|
+
/** The ordered command prefixes forming the pattern (e.g., ["git checkout", "npm install", "npm run build"]) */
|
|
823
|
+
steps: string[];
|
|
824
|
+
/** How many sessions contained this sequence */
|
|
825
|
+
sessionCount: number;
|
|
826
|
+
/** Total occurrences across all sessions */
|
|
827
|
+
totalOccurrences: number;
|
|
828
|
+
/** Example full commands from the most recent occurrence */
|
|
829
|
+
examples: string[];
|
|
830
|
+
}
|
|
831
|
+
interface SkillProposal {
|
|
832
|
+
/** Suggested slug for the skill */
|
|
833
|
+
slug: string;
|
|
834
|
+
/** Human-readable description of what the pattern does */
|
|
835
|
+
description: string;
|
|
836
|
+
/** The command steps forming the skill */
|
|
837
|
+
steps: string[];
|
|
838
|
+
/** How many sessions demonstrated this pattern */
|
|
839
|
+
sessionCount: number;
|
|
840
|
+
/** Confidence that this is a real, repeatable skill */
|
|
841
|
+
confidence: "high" | "medium" | "low";
|
|
842
|
+
/** Example commands from actual usage */
|
|
843
|
+
examples: string[];
|
|
844
|
+
}
|
|
845
|
+
interface DiscoveryOptions {
|
|
846
|
+
/** Minimum number of sessions a pattern must appear in (default: 2) */
|
|
847
|
+
minSessions?: number;
|
|
848
|
+
/** Minimum sequence length to consider (default: 2) */
|
|
849
|
+
minSequenceLength?: number;
|
|
850
|
+
/** Maximum sequence length to consider (default: 5) */
|
|
851
|
+
maxSequenceLength?: number;
|
|
852
|
+
/** Existing skill slugs to exclude from proposals */
|
|
853
|
+
existingSkillSlugs?: string[];
|
|
452
854
|
}
|
|
453
855
|
/**
|
|
454
|
-
*
|
|
856
|
+
* Discover recurring command patterns across multiple sessions.
|
|
455
857
|
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
858
|
+
* Takes a map of session ID → command records, finds command sequences
|
|
859
|
+
* that appear in multiple sessions, and proposes them as skills.
|
|
860
|
+
*
|
|
861
|
+
* @param sessionCommands - Map of session ID to that session's commands
|
|
862
|
+
* @param options - Discovery configuration
|
|
863
|
+
* @returns Array of skill proposals, sorted by confidence then session count
|
|
458
864
|
*/
|
|
459
|
-
declare function
|
|
865
|
+
declare function discoverSkills(sessionCommands: Map<string, CommandRecord[]>, options?: DiscoveryOptions): SkillProposal[];
|
|
460
866
|
|
|
461
867
|
/**
|
|
462
868
|
* Cascade Block & Unblock — prerequisite-aware blocking logic.
|
|
@@ -513,104 +919,56 @@ declare function cascadeBlock(db: Database, userId: string, tokenSlug: string):
|
|
|
513
919
|
declare function unblockReady(db: Database, userId: string): UnblockResult;
|
|
514
920
|
|
|
515
921
|
/**
|
|
516
|
-
*
|
|
517
|
-
*
|
|
518
|
-
* Algorithm: group items by domain, then round-robin across domain groups.
|
|
519
|
-
* Each round picks one item from each non-exhausted domain. Within a domain,
|
|
520
|
-
* the original order is preserved (so urgency sorting survives).
|
|
521
|
-
*
|
|
522
|
-
* If a domain has more items than others, its extras will appear after all
|
|
523
|
-
* other domains are exhausted — but the `maxConsecutive` cap is still
|
|
524
|
-
* respected by inserting items from the largest remaining domains first.
|
|
922
|
+
* FSRS-5 — Free Spaced Repetition Scheduler (v5)
|
|
525
923
|
*
|
|
526
|
-
*
|
|
527
|
-
*
|
|
528
|
-
*
|
|
529
|
-
*/
|
|
530
|
-
declare function interleave<T extends {
|
|
531
|
-
domain: string;
|
|
532
|
-
}>(items: T[], maxConsecutive?: number): T[];
|
|
533
|
-
|
|
534
|
-
/**
|
|
535
|
-
* Review Queue Builder — assembles a session's review queue.
|
|
924
|
+
* Pure-function implementation of the FSRS algorithm that replaces
|
|
925
|
+
* the PoC's SM-2 scheduler. This is the mathematical heart of ZAM's
|
|
926
|
+
* spaced-repetition engine.
|
|
536
927
|
*
|
|
537
|
-
*
|
|
538
|
-
* and cross-domain interleaving into a single ready-to-review queue.
|
|
928
|
+
* Reference: https://github.com/open-spaced-repetition/fsrs4anki/wiki/The-Algorithm
|
|
539
929
|
*/
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
930
|
+
/** 1 = Again (forgot), 2 = Hard, 3 = Good, 4 = Easy */
|
|
931
|
+
type Rating = 1 | 2 | 3 | 4;
|
|
932
|
+
type CardState = "new" | "learning" | "review" | "relearning";
|
|
933
|
+
interface SchedulingCard {
|
|
934
|
+
/** Memory stability in days — expected half-life of recall probability. */
|
|
935
|
+
stability: number;
|
|
936
|
+
/** Intrinsic difficulty on a 1–10 scale. */
|
|
937
|
+
difficulty: number;
|
|
938
|
+
/** Days elapsed since the last review. */
|
|
939
|
+
elapsedDays: number;
|
|
940
|
+
/** Currently scheduled interval in days. */
|
|
941
|
+
scheduledDays: number;
|
|
942
|
+
/** Count of successful consecutive reviews. */
|
|
943
|
+
reps: number;
|
|
944
|
+
/** Times the card was forgotten (rated Again). */
|
|
945
|
+
lapses: number;
|
|
946
|
+
/** Current learning state. */
|
|
947
|
+
state: CardState;
|
|
948
|
+
/** When the card is next due. */
|
|
949
|
+
dueAt: Date;
|
|
950
|
+
/** When the card was last reviewed (null for new cards). */
|
|
951
|
+
lastReviewAt: Date | null;
|
|
546
952
|
}
|
|
547
|
-
interface
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
domain: string;
|
|
553
|
-
bloomLevel: number;
|
|
554
|
-
state: string;
|
|
555
|
-
dueAt: string;
|
|
953
|
+
interface FSRSParameters {
|
|
954
|
+
/** 19 optimised weight parameters (w0 – w18). */
|
|
955
|
+
w: number[];
|
|
956
|
+
/** Target retention rate, e.g. 0.9 means we aim for 90% recall. */
|
|
957
|
+
requestRetention: number;
|
|
556
958
|
}
|
|
557
|
-
interface
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
totalDomains: string[];
|
|
959
|
+
interface FSRS {
|
|
960
|
+
/** Return a fully updated card after applying a rating. Pure function. */
|
|
961
|
+
schedule(card: SchedulingCard, rating: Rating, now?: Date): SchedulingCard;
|
|
962
|
+
/** The parameters baked into this instance. */
|
|
963
|
+
readonly params: Readonly<FSRSParameters>;
|
|
563
964
|
}
|
|
564
965
|
/**
|
|
565
|
-
*
|
|
566
|
-
*
|
|
567
|
-
* The queue is assembled in stages:
|
|
568
|
-
* 1. Fetch all due cards (not blocked, due_at <= now, state in review/relearning/learning)
|
|
569
|
-
* 2. Fetch new cards (state = 'new', not blocked) up to maxNew
|
|
570
|
-
* 3. Sort overdue cards by urgency — most overdue first
|
|
571
|
-
* 4. Apply cross-domain interleaving to prevent same-domain streaks
|
|
572
|
-
* 5. Intersperse new cards at regular intervals (every 5th position)
|
|
573
|
-
* 6. Cap total at maxReviews
|
|
574
|
-
*
|
|
575
|
-
* @param db - Database connection
|
|
576
|
-
* @param options - Queue building options
|
|
577
|
-
* @returns The assembled review queue with metadata
|
|
578
|
-
*/
|
|
579
|
-
declare function buildReviewQueue(db: Database, options: ReviewQueueOptions): ReviewQueue;
|
|
580
|
-
|
|
581
|
-
/**
|
|
582
|
-
* Active Recall Prompt Generation
|
|
966
|
+
* Create an FSRS scheduler instance.
|
|
583
967
|
*
|
|
584
|
-
*
|
|
585
|
-
*
|
|
586
|
-
* it's template-based prompt assembly for the CLI and bridge.
|
|
587
|
-
*/
|
|
588
|
-
type BloomLevel = 1 | 2 | 3 | 4 | 5;
|
|
589
|
-
interface RecallPrompt {
|
|
590
|
-
cardId: string;
|
|
591
|
-
tokenId: string;
|
|
592
|
-
slug: string;
|
|
593
|
-
question: string;
|
|
594
|
-
concept: string;
|
|
595
|
-
domain: string;
|
|
596
|
-
bloomLevel: BloomLevel;
|
|
597
|
-
bloomVerb: string;
|
|
598
|
-
hints: string[];
|
|
599
|
-
}
|
|
600
|
-
interface PromptInput {
|
|
601
|
-
cardId: string;
|
|
602
|
-
tokenId: string;
|
|
603
|
-
slug: string;
|
|
604
|
-
concept: string;
|
|
605
|
-
domain: string;
|
|
606
|
-
bloomLevel: BloomLevel;
|
|
607
|
-
}
|
|
608
|
-
/**
|
|
609
|
-
* Generate a recall prompt for a token at its Bloom level.
|
|
610
|
-
* When called from the CLI, the prompt is rendered in the terminal.
|
|
611
|
-
* When called from the AI bridge, the JSON is returned for the AI to present conversationally.
|
|
968
|
+
* All scheduling is done through pure functions — no side effects,
|
|
969
|
+
* no database access, no mutation of the input card.
|
|
612
970
|
*/
|
|
613
|
-
declare function
|
|
971
|
+
declare function createFSRS(params?: Partial<FSRSParameters>): FSRS;
|
|
614
972
|
|
|
615
973
|
/**
|
|
616
974
|
* Rating Evaluator
|
|
@@ -645,354 +1003,272 @@ interface EvaluateResult {
|
|
|
645
1003
|
*/
|
|
646
1004
|
declare function evaluateRating(db: Database, input: EvaluateInput): EvaluateResult;
|
|
647
1005
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
* Progress statistics, competence tracking, and session summaries.
|
|
652
|
-
* Ported from PoC's `stats` command with additions for FSRS and symbiosis modes.
|
|
653
|
-
*/
|
|
654
|
-
|
|
655
|
-
interface UserStats {
|
|
1006
|
+
type ReviewActionType = "rate" | "skip" | "edit-token" | "deprecate-token" | "delete-token" | "delete-card" | "stop";
|
|
1007
|
+
interface ExecuteReviewActionInput {
|
|
1008
|
+
cardId: string;
|
|
656
1009
|
userId: string;
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
blocked: number;
|
|
661
|
-
mature: number;
|
|
662
|
-
avgStability: number | null;
|
|
663
|
-
totalSessions: number;
|
|
664
|
-
lastSession: string | null;
|
|
1010
|
+
action: ReviewActionType;
|
|
1011
|
+
rating?: Rating;
|
|
1012
|
+
tokenUpdates?: UpdateTokenInput;
|
|
665
1013
|
}
|
|
666
|
-
interface
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
1014
|
+
interface ReviewActionResult {
|
|
1015
|
+
action: ReviewActionType;
|
|
1016
|
+
token: Token;
|
|
1017
|
+
evaluation?: EvaluateResult;
|
|
1018
|
+
blocked?: CascadeBlockResult;
|
|
1019
|
+
updatedToken?: Token;
|
|
1020
|
+
deletedToken?: DeleteTokenResult;
|
|
1021
|
+
deletedCard?: DeleteCardResult;
|
|
1022
|
+
skipped?: boolean;
|
|
1023
|
+
stopped?: boolean;
|
|
673
1024
|
}
|
|
674
|
-
|
|
675
|
-
* Get overall learning stats for a user (ported from PoC's `stats` command).
|
|
676
|
-
*/
|
|
677
|
-
declare function getUserStats(db: Database, userId: string): UserStats;
|
|
678
|
-
/**
|
|
679
|
-
* Get competence per domain for a user.
|
|
680
|
-
* Used to suggest symbiosis mode transitions.
|
|
681
|
-
*/
|
|
682
|
-
declare function getDomainCompetence(db: Database, userId: string): DomainCompetence[];
|
|
1025
|
+
declare function executeReviewAction(db: Database, input: ExecuteReviewActionInput): ReviewActionResult;
|
|
683
1026
|
|
|
684
1027
|
/**
|
|
685
|
-
*
|
|
1028
|
+
* Active Recall Prompt Generation
|
|
686
1029
|
*
|
|
687
|
-
*
|
|
688
|
-
*
|
|
1030
|
+
* Generates review prompts from tokens, adapting the question style
|
|
1031
|
+
* to the token's Bloom taxonomy level. This is NOT an LLM call —
|
|
1032
|
+
* it's template-based prompt assembly for the CLI and bridge.
|
|
689
1033
|
*/
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
pid?: number;
|
|
695
|
-
command?: string;
|
|
696
|
-
cwd?: string;
|
|
697
|
-
exit_code?: number;
|
|
698
|
-
event?: "start" | "stop";
|
|
699
|
-
session_id?: string;
|
|
700
|
-
shell?: string;
|
|
701
|
-
}
|
|
702
|
-
interface CommandRecord {
|
|
703
|
-
seq: number;
|
|
704
|
-
pid: number;
|
|
705
|
-
command: string;
|
|
706
|
-
cwd: string;
|
|
707
|
-
startedAt: string;
|
|
708
|
-
endedAt: string | null;
|
|
709
|
-
durationMs: number | null;
|
|
710
|
-
exitCode: number | null;
|
|
711
|
-
}
|
|
712
|
-
interface TokenPattern {
|
|
1034
|
+
type BloomLevel = 1 | 2 | 3 | 4 | 5;
|
|
1035
|
+
interface RecallPrompt {
|
|
1036
|
+
cardId: string;
|
|
1037
|
+
tokenId: string;
|
|
713
1038
|
slug: string;
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
matchedCommands: number;
|
|
722
|
-
helpSeeking: boolean;
|
|
723
|
-
errorCount: number;
|
|
724
|
-
selfCorrections: number;
|
|
725
|
-
medianGapMs: number | null;
|
|
726
|
-
thinkingGapMs: number | null;
|
|
727
|
-
};
|
|
728
|
-
matchedCommandTexts: string[];
|
|
1039
|
+
question: string;
|
|
1040
|
+
concept: string;
|
|
1041
|
+
domain: string;
|
|
1042
|
+
bloomLevel: BloomLevel;
|
|
1043
|
+
bloomVerb: string;
|
|
1044
|
+
hints: string[];
|
|
1045
|
+
sourceLink?: string | null;
|
|
729
1046
|
}
|
|
730
|
-
interface
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
1047
|
+
interface PromptInput {
|
|
1048
|
+
cardId: string;
|
|
1049
|
+
tokenId: string;
|
|
1050
|
+
slug: string;
|
|
1051
|
+
concept: string;
|
|
1052
|
+
domain: string;
|
|
1053
|
+
bloomLevel: BloomLevel;
|
|
1054
|
+
sourceLink?: string | null;
|
|
1055
|
+
question?: string | null;
|
|
738
1056
|
}
|
|
739
1057
|
/**
|
|
740
|
-
*
|
|
741
|
-
* Skips malformed lines silently.
|
|
1058
|
+
* Generate a template-based concept-free recall cue using the slug and domain.
|
|
742
1059
|
*/
|
|
743
|
-
declare function
|
|
1060
|
+
declare function generateConceptFreeCue(bloomLevel: BloomLevel, slug: string, _domain: string): string;
|
|
744
1061
|
/**
|
|
745
|
-
*
|
|
1062
|
+
* Generate a recall prompt for a token at its Bloom level.
|
|
1063
|
+
* When called from the CLI, the prompt is rendered in the terminal.
|
|
1064
|
+
* When called from the AI bridge, the JSON is returned for the AI to present conversationally.
|
|
746
1065
|
*/
|
|
747
|
-
declare function
|
|
1066
|
+
declare function generatePrompt(input: PromptInput): RecallPrompt;
|
|
1067
|
+
|
|
1068
|
+
interface ResolvedReference {
|
|
1069
|
+
sourceType: "local" | "remote_web" | "dynamic_search";
|
|
1070
|
+
content: string;
|
|
1071
|
+
filePath?: string;
|
|
1072
|
+
url?: string;
|
|
1073
|
+
}
|
|
748
1074
|
/**
|
|
749
|
-
*
|
|
1075
|
+
* A source reference resolved and bounded for inclusion in a review payload.
|
|
1076
|
+
* Same shape as ResolvedReference plus the originating link and a truncation flag.
|
|
750
1077
|
*/
|
|
751
|
-
|
|
752
|
-
|
|
1078
|
+
interface ReviewContext {
|
|
1079
|
+
sourceLink: string;
|
|
1080
|
+
sourceType: ResolvedReference["sourceType"];
|
|
1081
|
+
content: string;
|
|
1082
|
+
filePath?: string;
|
|
1083
|
+
url?: string;
|
|
1084
|
+
truncated: boolean;
|
|
1085
|
+
}
|
|
1086
|
+
/** Default cap on resolved content length, so bridge JSON / terminal output stays bounded. */
|
|
1087
|
+
declare const DEFAULT_REVIEW_CONTEXT_MAX_CHARS = 6000;
|
|
753
1088
|
/**
|
|
754
|
-
*
|
|
755
|
-
*
|
|
756
|
-
* Monitor logs live at ~/.zam/monitor/<session-id>.jsonl.
|
|
757
|
-
* Separated from analyzer.ts so the analyzer remains pure-function testable.
|
|
1089
|
+
* Resolves a given token's source_link into readable textual content.
|
|
758
1090
|
*/
|
|
759
|
-
|
|
760
|
-
/** Get the monitor directory path. */
|
|
761
|
-
declare function getMonitorDir(): string;
|
|
762
|
-
/** Get the JSONL file path for a session. */
|
|
763
|
-
declare function getMonitorPath(sessionId: string): string;
|
|
764
|
-
/** Ensure the monitor directory exists (mode 0700 for privacy). */
|
|
765
|
-
declare function ensureMonitorDir(): void;
|
|
766
|
-
/** Append a single event to the session's JSONL file. */
|
|
767
|
-
declare function writeMonitorEvent(sessionId: string, event: MonitorEvent): void;
|
|
768
|
-
/** Read and parse all events from a session's monitor log. */
|
|
769
|
-
declare function readMonitorLog(sessionId: string): MonitorEvent[];
|
|
770
|
-
/** Check if a monitor log exists for a session. */
|
|
771
|
-
declare function monitorLogExists(sessionId: string): boolean;
|
|
772
|
-
/** Get basic stats about a monitor log without full parsing. */
|
|
773
|
-
declare function getMonitorLogStats(sessionId: string): {
|
|
774
|
-
exists: boolean;
|
|
775
|
-
sizeBytes: number;
|
|
776
|
-
lineCount: number;
|
|
777
|
-
};
|
|
778
|
-
|
|
1091
|
+
declare function resolveReference(sourceLink: string): Promise<ResolvedReference>;
|
|
779
1092
|
/**
|
|
780
|
-
*
|
|
1093
|
+
* Resolve a token's source_link into bounded, review-ready context.
|
|
781
1094
|
*
|
|
782
|
-
*
|
|
783
|
-
*
|
|
784
|
-
*
|
|
1095
|
+
* Wraps {@link resolveReference} for the review/bridge flow: returns `null`
|
|
1096
|
+
* for empty links and caps content length so the surrounding payload (bridge
|
|
1097
|
+
* JSON or terminal output) stays manageable, flagging when truncation occurred.
|
|
785
1098
|
*/
|
|
1099
|
+
declare function resolveReviewContext(sourceLink: string | null | undefined, opts?: {
|
|
1100
|
+
maxChars?: number;
|
|
1101
|
+
}): Promise<ReviewContext | null>;
|
|
786
1102
|
/**
|
|
787
|
-
*
|
|
788
|
-
* Uses $EPOCHREALTIME for sub-second timestamp precision.
|
|
1103
|
+
* Normalizes a path, stripping anchors and converting separators.
|
|
789
1104
|
*/
|
|
790
|
-
declare function
|
|
1105
|
+
declare function normalizePath(p: string): string;
|
|
791
1106
|
/**
|
|
792
|
-
*
|
|
793
|
-
* Uses DEBUG trap for preexec, PROMPT_COMMAND for precmd.
|
|
1107
|
+
* Checks if a token's source_link references a changed file.
|
|
794
1108
|
*/
|
|
795
|
-
declare function
|
|
796
|
-
/** Generate zsh code to remove monitor hooks. */
|
|
797
|
-
declare function generateZshUnhooks(): string;
|
|
798
|
-
/** Generate bash code to remove monitor hooks. */
|
|
799
|
-
declare function generateBashUnhooks(): string;
|
|
1109
|
+
declare function matchesFilePath(sourceLink: string | null, changedFile: string): boolean;
|
|
800
1110
|
|
|
801
1111
|
/**
|
|
802
|
-
*
|
|
803
|
-
* across multiple sessions and proposes them as minimal reusable skills.
|
|
804
|
-
*
|
|
805
|
-
* The key insight from Increment 2: "The human's demonstrated competence
|
|
806
|
-
* is the gate for automation — not the other way around." A pattern must
|
|
807
|
-
* appear consistently across sessions before being proposed as a skill.
|
|
1112
|
+
* Reorder items so no domain appears more than `maxConsecutive` times in a row.
|
|
808
1113
|
*
|
|
809
|
-
*
|
|
810
|
-
*
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
interface CommandSequence {
|
|
814
|
-
/** The ordered command prefixes forming the pattern (e.g., ["git checkout", "npm install", "npm run build"]) */
|
|
815
|
-
steps: string[];
|
|
816
|
-
/** How many sessions contained this sequence */
|
|
817
|
-
sessionCount: number;
|
|
818
|
-
/** Total occurrences across all sessions */
|
|
819
|
-
totalOccurrences: number;
|
|
820
|
-
/** Example full commands from the most recent occurrence */
|
|
821
|
-
examples: string[];
|
|
822
|
-
}
|
|
823
|
-
interface SkillProposal {
|
|
824
|
-
/** Suggested slug for the skill */
|
|
825
|
-
slug: string;
|
|
826
|
-
/** Human-readable description of what the pattern does */
|
|
827
|
-
description: string;
|
|
828
|
-
/** The command steps forming the skill */
|
|
829
|
-
steps: string[];
|
|
830
|
-
/** How many sessions demonstrated this pattern */
|
|
831
|
-
sessionCount: number;
|
|
832
|
-
/** Confidence that this is a real, repeatable skill */
|
|
833
|
-
confidence: "high" | "medium" | "low";
|
|
834
|
-
/** Example commands from actual usage */
|
|
835
|
-
examples: string[];
|
|
836
|
-
}
|
|
837
|
-
interface DiscoveryOptions {
|
|
838
|
-
/** Minimum number of sessions a pattern must appear in (default: 2) */
|
|
839
|
-
minSessions?: number;
|
|
840
|
-
/** Minimum sequence length to consider (default: 2) */
|
|
841
|
-
minSequenceLength?: number;
|
|
842
|
-
/** Maximum sequence length to consider (default: 5) */
|
|
843
|
-
maxSequenceLength?: number;
|
|
844
|
-
/** Existing skill slugs to exclude from proposals */
|
|
845
|
-
existingSkillSlugs?: string[];
|
|
846
|
-
}
|
|
847
|
-
/**
|
|
848
|
-
* Discover recurring command patterns across multiple sessions.
|
|
1114
|
+
* Algorithm: group items by domain, then round-robin across domain groups.
|
|
1115
|
+
* Each round picks one item from each non-exhausted domain. Within a domain,
|
|
1116
|
+
* the original order is preserved (so urgency sorting survives).
|
|
849
1117
|
*
|
|
850
|
-
*
|
|
851
|
-
*
|
|
1118
|
+
* If a domain has more items than others, its extras will appear after all
|
|
1119
|
+
* other domains are exhausted — but the `maxConsecutive` cap is still
|
|
1120
|
+
* respected by inserting items from the largest remaining domains first.
|
|
852
1121
|
*
|
|
853
|
-
* @param
|
|
854
|
-
* @param
|
|
855
|
-
* @returns
|
|
1122
|
+
* @param items - Array of items to interleave. Not mutated.
|
|
1123
|
+
* @param maxConsecutive - Max consecutive items from the same domain. Defaults to 2.
|
|
1124
|
+
* @returns A new array with the same items in interleaved order.
|
|
856
1125
|
*/
|
|
857
|
-
declare function
|
|
1126
|
+
declare function interleave<T extends {
|
|
1127
|
+
domain: string;
|
|
1128
|
+
}>(items: T[], maxConsecutive?: number): T[];
|
|
858
1129
|
|
|
859
1130
|
/**
|
|
860
|
-
*
|
|
1131
|
+
* Review Queue Builder — assembles a session's review queue.
|
|
861
1132
|
*
|
|
862
|
-
*
|
|
863
|
-
*
|
|
864
|
-
* and a markdown body with description, tasks, and token references.
|
|
1133
|
+
* Combines due-card fetching, new-card selection, urgency sorting,
|
|
1134
|
+
* and cross-domain interleaving into a single ready-to-review queue.
|
|
865
1135
|
*/
|
|
866
|
-
|
|
867
|
-
interface
|
|
1136
|
+
|
|
1137
|
+
interface ReviewQueueOptions {
|
|
1138
|
+
userId: string;
|
|
1139
|
+
maxNew?: number;
|
|
1140
|
+
maxReviews?: number;
|
|
1141
|
+
now?: Date;
|
|
1142
|
+
}
|
|
1143
|
+
interface ReviewQueueItem {
|
|
1144
|
+
cardId: string;
|
|
1145
|
+
tokenId: string;
|
|
868
1146
|
slug: string;
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
1147
|
+
concept: string;
|
|
1148
|
+
domain: string;
|
|
1149
|
+
bloomLevel: number;
|
|
1150
|
+
state: string;
|
|
1151
|
+
dueAt: string;
|
|
1152
|
+
sourceLink: string | null;
|
|
1153
|
+
question: string | null;
|
|
876
1154
|
}
|
|
877
|
-
interface
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
1155
|
+
interface ReviewQueue {
|
|
1156
|
+
items: ReviewQueueItem[];
|
|
1157
|
+
newCount: number;
|
|
1158
|
+
reviewCount: number;
|
|
1159
|
+
relearnCount: number;
|
|
1160
|
+
totalDomains: string[];
|
|
883
1161
|
}
|
|
884
1162
|
/**
|
|
885
|
-
*
|
|
886
|
-
*
|
|
887
|
-
* Expected format:
|
|
888
|
-
* ```
|
|
889
|
-
* ---
|
|
890
|
-
* title: Learn Rust fundamentals
|
|
891
|
-
* status: active
|
|
892
|
-
* parent: become-systems-programmer
|
|
893
|
-
* created: 2026-03-28
|
|
894
|
-
* updated: 2026-03-28
|
|
895
|
-
* ---
|
|
1163
|
+
* Build a review queue for a user's study session.
|
|
896
1164
|
*
|
|
897
|
-
*
|
|
898
|
-
*
|
|
899
|
-
*
|
|
1165
|
+
* The queue is assembled in stages:
|
|
1166
|
+
* 1. Fetch all due cards (not blocked, due_at <= now, state in review/relearning/learning)
|
|
1167
|
+
* 2. Fetch new cards (state = 'new', not blocked) up to maxNew
|
|
1168
|
+
* 3. Sort overdue cards by urgency — most overdue first
|
|
1169
|
+
* 4. Apply cross-domain interleaving to prevent same-domain streaks
|
|
1170
|
+
* 5. Intersperse new cards at regular intervals (every 5th position)
|
|
1171
|
+
* 6. Cap total at maxReviews
|
|
900
1172
|
*
|
|
901
|
-
* @param
|
|
902
|
-
* @param
|
|
903
|
-
* @
|
|
1173
|
+
* @param db - Database connection
|
|
1174
|
+
* @param options - Queue building options
|
|
1175
|
+
* @returns The assembled review queue with metadata
|
|
904
1176
|
*/
|
|
905
|
-
declare function
|
|
1177
|
+
declare function buildReviewQueue(db: Database, options: ReviewQueueOptions): ReviewQueue;
|
|
1178
|
+
|
|
906
1179
|
/**
|
|
907
|
-
*
|
|
1180
|
+
* Get the path to ZAM's internal package SKILL.md.
|
|
908
1181
|
*/
|
|
909
|
-
declare function
|
|
1182
|
+
declare function getPackageSkillPath(agent?: "default" | "claude" | "codex"): string;
|
|
910
1183
|
/**
|
|
911
|
-
*
|
|
912
|
-
*
|
|
1184
|
+
* Distribute the ZAM active-recall training skill globally.
|
|
1185
|
+
* Copies SKILL.md into global directories for supported coding agents.
|
|
913
1186
|
*/
|
|
914
|
-
declare function
|
|
915
|
-
|
|
916
|
-
|
|
1187
|
+
declare function distributeGlobalSkills(home?: string): Array<{
|
|
1188
|
+
name: string;
|
|
1189
|
+
path: string;
|
|
1190
|
+
success: boolean;
|
|
917
1191
|
}>;
|
|
918
1192
|
/**
|
|
919
|
-
*
|
|
920
|
-
*
|
|
1193
|
+
* Inject the ZAM shell observation hook into user profile scripts so monitoring
|
|
1194
|
+
* is automatically initialized on startup.
|
|
921
1195
|
*/
|
|
922
|
-
declare function
|
|
1196
|
+
declare function injectShellHooks(): Array<{
|
|
1197
|
+
shell: string;
|
|
1198
|
+
file: string;
|
|
1199
|
+
success: boolean;
|
|
1200
|
+
alreadyHooked: boolean;
|
|
1201
|
+
}>;
|
|
923
1202
|
|
|
1203
|
+
type SupportedLocale = "en" | "de" | "es" | "fr" | "pt" | "zh" | "ja";
|
|
924
1204
|
/**
|
|
925
|
-
*
|
|
926
|
-
*
|
|
927
|
-
* Goals live as markdown files in a directory (typically the personal repo's
|
|
928
|
-
* goals/ folder). The engine reads, creates, and updates these files.
|
|
929
|
-
* It does not depend on the database — goals are git-tracked, not DB-tracked.
|
|
1205
|
+
* Clean and map raw locale string (e.g., "de_DE.UTF-8" or "en-US") to SupportedLocale.
|
|
930
1206
|
*/
|
|
931
|
-
|
|
932
|
-
interface GoalSummary {
|
|
933
|
-
slug: string;
|
|
934
|
-
title: string;
|
|
935
|
-
status: GoalStatus;
|
|
936
|
-
parent: string | null;
|
|
937
|
-
taskCount: number;
|
|
938
|
-
tasksDone: number;
|
|
939
|
-
tokenCount: number;
|
|
940
|
-
}
|
|
941
|
-
interface CreateGoalInput {
|
|
942
|
-
slug: string;
|
|
943
|
-
title: string;
|
|
944
|
-
status?: GoalStatus;
|
|
945
|
-
parent?: string;
|
|
946
|
-
description?: string;
|
|
947
|
-
}
|
|
1207
|
+
declare function normalizeLocale(raw: string): SupportedLocale;
|
|
948
1208
|
/**
|
|
949
|
-
*
|
|
950
|
-
* Returns summaries sorted by status (active first) then title.
|
|
1209
|
+
* Detect the operating system's active language code dynamically.
|
|
951
1210
|
*/
|
|
952
|
-
declare function
|
|
1211
|
+
declare function detectSystemLocale(): SupportedLocale;
|
|
1212
|
+
|
|
1213
|
+
type TranslationKey = "welcome" | "new_review_relearn" | "domains" | "instruction" | "quit_hint" | "offline_warning" | "offline_instruction" | "nothing_due" | "evaluating" | "generating_question" | "translating" | "prompt_answer" | "session_ended" | "session_complete" | "cards_rated" | "avg_rating" | "forgot" | "feedback_title" | "answer_title" | "keep_waiting" | "local_ai_working" | "wait_warning" | "wait_info" | "keep_waiting_llm" | "proceeding_offline" | "eval_skipped";
|
|
953
1214
|
/**
|
|
954
|
-
*
|
|
955
|
-
* Returns undefined if the file doesn't exist.
|
|
1215
|
+
* Format and interpolate a translation string with key-value params.
|
|
956
1216
|
*/
|
|
957
|
-
declare function
|
|
1217
|
+
declare function t(locale: SupportedLocale, key: TranslationKey, params?: Record<string, string | number>): string;
|
|
1218
|
+
|
|
1219
|
+
interface InstallResult {
|
|
1220
|
+
success: boolean;
|
|
1221
|
+
message: string;
|
|
1222
|
+
}
|
|
958
1223
|
/**
|
|
959
|
-
*
|
|
1224
|
+
* Check if a command is executable on the system.
|
|
960
1225
|
*/
|
|
961
|
-
declare function
|
|
1226
|
+
declare function hasCommand(cmd: string): boolean;
|
|
962
1227
|
/**
|
|
963
|
-
*
|
|
1228
|
+
* Install FastFlowLM via winget on Windows.
|
|
964
1229
|
*/
|
|
965
|
-
declare function
|
|
1230
|
+
declare function installFastFlowLM(): InstallResult;
|
|
966
1231
|
/**
|
|
967
|
-
*
|
|
968
|
-
* Returns root goals (no parent) with nested children.
|
|
1232
|
+
* Install Ollama via Homebrew on macOS.
|
|
969
1233
|
*/
|
|
970
|
-
declare function
|
|
971
|
-
children: GoalSummary[];
|
|
972
|
-
}>;
|
|
1234
|
+
declare function installOllama(): InstallResult;
|
|
973
1235
|
|
|
1236
|
+
interface SystemProfile {
|
|
1237
|
+
os: "windows" | "macos" | "linux" | "unknown";
|
|
1238
|
+
arch: "x64" | "arm64" | "unknown";
|
|
1239
|
+
hasRyzenNPU: boolean;
|
|
1240
|
+
hasAppleSilicon: boolean;
|
|
1241
|
+
recommendedRunner: "fastflowlm" | "ollama" | "generic";
|
|
1242
|
+
recommendedModel: string;
|
|
1243
|
+
}
|
|
974
1244
|
/**
|
|
975
|
-
*
|
|
1245
|
+
* Profile the active system hardware and software capabilities.
|
|
976
1246
|
*/
|
|
1247
|
+
declare function getSystemProfile(): SystemProfile;
|
|
977
1248
|
|
|
978
|
-
interface
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
1249
|
+
interface RepoPaths {
|
|
1250
|
+
personal: string | null;
|
|
1251
|
+
team: string | null;
|
|
1252
|
+
org: string | null;
|
|
982
1253
|
}
|
|
983
|
-
interface WorkItem {
|
|
984
|
-
id: number;
|
|
985
|
-
title: string;
|
|
986
|
-
state: string;
|
|
987
|
-
type: string;
|
|
988
|
-
assignedTo: string;
|
|
989
|
-
}
|
|
990
|
-
/** Load ADO config from user settings. Returns null if not configured. */
|
|
991
|
-
declare function loadADOConfig(db: Database): ADOConfig | null;
|
|
992
1254
|
/**
|
|
993
|
-
*
|
|
994
|
-
*
|
|
1255
|
+
* Resolve absolute paths for personal, team, and organization repositories.
|
|
1256
|
+
* Personal falls back to personal.workspace_dir if repo.personal is not set.
|
|
995
1257
|
*/
|
|
996
|
-
declare function
|
|
1258
|
+
declare function getRepoPaths(db: Database): RepoPaths;
|
|
1259
|
+
/**
|
|
1260
|
+
* Resolve a specific repo's path, or null if not configured.
|
|
1261
|
+
*/
|
|
1262
|
+
declare function resolveRepoPath(db: Database, type: "personal" | "team" | "org"): string | null;
|
|
1263
|
+
/**
|
|
1264
|
+
* Resolve paths to all existing "/beliefs" directories in the hierarchy,
|
|
1265
|
+
* sorted from most specific (personal) to most general (org).
|
|
1266
|
+
*/
|
|
1267
|
+
declare function resolveAllBeliefPaths(db: Database): string[];
|
|
1268
|
+
/**
|
|
1269
|
+
* Resolve paths to all existing "/goals" directories in the hierarchy,
|
|
1270
|
+
* sorted from most specific (personal) to most general (org).
|
|
1271
|
+
*/
|
|
1272
|
+
declare function resolveAllGoalPaths(db: Database): string[];
|
|
997
1273
|
|
|
998
|
-
export { type ADOConfig, type AgentSkill, type AnalysisResult, type BloomLevel$1 as BloomLevel, type Card, type CardState$1 as CardState, type CascadeBlockResult, type CommandRecord, type CommandSequence, type CreateAgentSkillInput, type CreateGoalInput, type CreateReviewInput, type CreateSessionInput, type CreateTokenInput, type DiscoveryOptions, type DomainCompetence, type EvaluateInput, type EvaluateResult, type ExecutionContext, type FSRSParameters, type Goal, type GoalFrontmatter, type GoalStatus, type GoalSummary, type LogStepInput, type MonitorEvent, type ObservationRating, type Prerequisite, type PrerequisiteWithToken, type PromptInput, type Rating, type RecallPrompt, type ReviewLog, type ReviewQueue, type ReviewQueueItem, type ReviewQueueOptions, type SchedulingCard, type Session, type SessionStep, type SessionSummary, type SkillProposal, type SkillSource, type SymbiosisMode, type Token, type TokenPattern, type UnblockResult, type UpdateCardInput, type UserSetting, type UserStats, type WorkItem, addPrerequisite, analyzeObservation, buildReviewQueue, cascadeBlock, createAgentSkill, createFSRS, createGoal, createToken, deleteSetting, deprecateToken, discoverSkills, endSession, ensureCard, ensureMonitorDir, evaluateRating, extractTasks, extractTokenRefs, fetchActiveWorkItems, findTokens, generateBashHooks, generateBashUnhooks, generatePrompt, generateZshHooks, generateZshUnhooks, getAgentSkill, getAllSettings, getAllSettingsDetailed, getBlockedCards, getCard, getDefaultDbPath, getDependents, getDomainCompetence, getDueCards, getGoal, getGoalTree, getMonitorDir, getMonitorLogStats, getMonitorPath, getPrerequisites, getReviewsForCard, getReviewsForUser, getSessionSummary, getSetting, getTokenById, getTokenBySlug, getUserStats, interleave, listAgentSkills, listGoals, listTokens, loadADOConfig, logReview, logStep, monitorLogExists, openDatabase, openDatabaseWithSync, pairCommands, parseGoalFile, parseMonitorLog, readMonitorLog, serializeGoal, setSetting, startSession, unblockReady, updateCard, updateGoalStatus, writeMonitorEvent };
|
|
1274
|
+
export { type ADOConfig, type ADOCredentials, type AgentSkill, type AnalysisResult, type BloomLevel$1 as BloomLevel, type Card, type CardDeletionImpact, type CardState$1 as CardState, type CascadeBlockResult, type CommandRecord, type CommandSequence, type CreateAgentSkillInput, type CreateGoalInput, type CreateReviewInput, type CreateSessionInput, type CreateTokenInput, type Credentials, DEFAULT_REVIEW_CONTEXT_MAX_CHARS, 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, type InstallResult, type LogStepInput, type MonitorEvent, type ObservationRating, type Prerequisite, type PrerequisiteWithToken, type PromptInput, type Rating, type RecallPrompt, type RepoPaths, type ResolvedReference, type ReviewActionResult, type ReviewActionType, type ReviewContext, type ReviewLog, type ReviewQueue, type ReviewQueueItem, type ReviewQueueOptions, type SchedulingCard, type Session, type SessionStep, type SessionSummary, type SkillProposal, type SkillSource, type SupportedLocale, type SymbiosisMode, type SystemProfile, type Token, type TokenDeleteImpact, type TokenPattern, type TranslationKey, type TursoCredentials, type UnblockResult, type UpdateCardInput, type UpdateTokenInput, type UserSetting, type UserStats, type WorkItem, addPrerequisite, analyzeObservation, buildReviewQueue, cascadeBlock, clearADOCredentials, clearTursoCredentials, createAgentSkill, createFSRS, createGoal, createToken, deleteCardForUser, deleteSetting, deleteToken, deprecateToken, detectSystemLocale, discoverSkills, distributeGlobalSkills, endSession, ensureCard, ensureMonitorDir, evaluateRating, executeReviewAction, extractTasks, extractTokenRefs, fetchActiveWorkItems, findTokens, generateBashHooks, generateBashUnhooks, generateConceptFreeCue, generatePowerShellHooks, generatePowerShellUnhooks, generatePrompt, generateZshHooks, generateZshUnhooks, getADOCredentials, getAgentSkill, getAllSettings, getAllSettingsDetailed, getBlockedCards, getCard, getCardById, getCardDeletionImpact, getDefaultDbPath, getDependents, getDomainCompetence, getDueCards, getGoal, getGoalTree, getMonitorDir, getMonitorLogStats, getMonitorPath, getPackageSkillPath, getPrerequisites, getRepoPaths, getReviewsForCard, getReviewsForUser, getSessionSummary, getSetting, getSystemProfile, getTokenById, getTokenBySlug, getTokenDeleteImpact, getTursoCredentials, getUserStats, hasCommand, injectShellHooks, installFastFlowLM, installOllama, interleave, listAgentSkills, listGoals, listTokens, loadADOConfig, loadCredentials, logReview, logStep, matchesFilePath, monitorLogExists, normalizeLocale, normalizePath, openDatabase, openDatabaseWithSync, pairCommands, parseGoalFile, parseMonitorLog, readMonitorLog, resolveAllBeliefPaths, resolveAllGoalPaths, resolveReference, resolveRepoPath, resolveReviewContext, saveCredentials, serializeGoal, setADOCredentials, setSetting, setTursoCredentials, startSession, t, unblockReady, updateCard, updateGoalStatus, updateToken, writeMonitorEvent };
|