* Single tick body. Runs the global memory embedding sweep once, then * iterates every registered project for its per-directory work.
(origin: "startup" | "interval")
| 215 | * iterates every registered project for its per-directory work. |
| 216 | */ |
| 217 | function runTick(origin: "startup" | "interval"): void { |
| 218 | log(`[dreamer] timer tick (${origin}) — projects=${registeredProjects.size}`); |
| 219 | void (async () => { |
| 220 | try { |
| 221 | const db = openTimerDatabaseOrNull("maintenance tick"); |
| 222 | if (!db) return; |
| 223 | // Per-project work — git commit indexing, dream schedule check, |
| 224 | // dream queue processing. We iterate all registered projects so |
| 225 | // Desktop's "open all projects at once" workflow indexes every one, |
| 226 | // not just whichever project happened to register the timer first. |
| 227 | for (const reg of registeredProjects.values()) { |
| 228 | await reg.ensureRegistered(reg.directory, db); |
| 229 | const memorySnapshot = getProjectEmbeddingSnapshot(reg.projectIdentity); |
| 230 | if (memorySnapshot?.enabled) { |
| 231 | const embeddedCount = await embedUnembeddedMemoriesForProject( |
| 232 | db, |
| 233 | reg.projectIdentity, |
| 234 | ); |
| 235 | if (embeddedCount > 0) { |
| 236 | log( |
| 237 | `[magic-context] proactively embedded ${embeddedCount} ${embeddedCount === 1 ? "memory" : "memories"} for project ${reg.projectIdentity}`, |
| 238 | ); |
| 239 | } |
| 240 | // Compartment-chunk backfill is NOT driven from the timer: a |
| 241 | // bounded batch per tick is a slow, bursty trickle that hammers |
| 242 | // local embedding endpoints. New compartments embed on publish; |
| 243 | // historical backfill runs on demand via /ctx-embed-history. |
| 244 | } |
| 245 | |
| 246 | await sweepProject(reg, origin, db); |
| 247 | } |
| 248 | // Refresh planner stats once per tick (after per-project work). |
| 249 | // Self-gating: a no-op unless a table's row count drifted enough to |
| 250 | // warrant re-ANALYZE, and analysis_limit bounds any work it does. |
| 251 | runSqliteOptimize(db); |
| 252 | } catch (error) { |
| 253 | log("[magic-context] timer-triggered maintenance check failed:", error); |
| 254 | } |
| 255 | })(); |
| 256 | } |
| 257 | |
| 258 | /** |
| 259 | * Run all per-project maintenance for one registration: git commit indexing |
no test coverage detected