()
| 250 | * a fresh partner can sit in the bootstrap dead zone for days. |
| 251 | */ |
| 252 | export async function startTeamMemoryWatcher(): Promise<void> { |
| 253 | if (!feature('TEAMMEM')) { |
| 254 | return |
| 255 | } |
| 256 | if (!isTeamMemoryEnabled() || !isTeamMemorySyncAvailable()) { |
| 257 | return |
| 258 | } |
| 259 | const repoSlug = await getGithubRepo() |
| 260 | if (!repoSlug) { |
| 261 | logForDebugging( |
| 262 | 'team-memory-watcher: no github.com remote, skipping sync', |
| 263 | { level: 'debug' }, |
| 264 | ) |
| 265 | return |
| 266 | } |
| 267 | |
| 268 | syncState = createSyncState() |
| 269 | |
| 270 | // Initial pull from server (runs before the watcher starts, so its disk |
| 271 | // writes won't trigger schedulePush) |
| 272 | let initialPullSuccess = false |
| 273 | let initialFilesPulled = 0 |
| 274 | let serverHasContent = false |
| 275 | try { |
| 276 | const pullResult = await pullTeamMemory(syncState) |
| 277 | initialPullSuccess = pullResult.success |
| 278 | serverHasContent = pullResult.entryCount > 0 |
| 279 | if (pullResult.success && pullResult.filesWritten > 0) { |
| 280 | initialFilesPulled = pullResult.filesWritten |
| 281 | logForDebugging( |
| 282 | `team-memory-watcher: initial pull got ${pullResult.filesWritten} files`, |
| 283 | { level: 'info' }, |
| 284 | ) |
| 285 | } |
| 286 | } catch (e) { |
| 287 | logForDebugging( |
| 288 | `team-memory-watcher: initial pull failed: ${errorMessage(e)}`, |
| 289 | { level: 'warn' }, |
| 290 | ) |
| 291 | } |
| 292 | |
| 293 | // Always start the watcher. Watching an empty dir is cheap, |
| 294 | // and the alternative (lazy start on notifyTeamMemoryWrite) creates |
| 295 | // a bootstrap dead zone for fresh repos. |
| 296 | await startFileWatcher(getTeamMemPath()) |
| 297 | |
| 298 | logEvent('tengu_team_mem_sync_started', { |
| 299 | initial_pull_success: initialPullSuccess, |
| 300 | initial_files_pulled: initialFilesPulled, |
| 301 | // Kept for dashboard continuity; now always true when this event fires. |
| 302 | watcher_started: true, |
| 303 | server_has_content: serverHasContent, |
| 304 | }) |
| 305 | } |
| 306 | |
| 307 | /** |
| 308 | * Call this when a team memory file is written (e.g. from PostToolUse hooks). |
nothing calls this directly
no test coverage detected