mirror of
https://github.com/block/buzz.git
synced 2026-11-13 21:01:53 +00:00
When a persona pack is installed as a symlink, edits to the pack source files are never reflected in the running app — import_persona_pack() snapshots data into personas.json at install time and all runtime reads go through that snapshot exclusively. Add sync_packs_from_dir() / sync_one_pack() (pure, testable) and a thin sync_symlinked_packs() AppHandle wrapper. The sync step is inserted into load_personas() after merge_personas(), reusing the existing read → reconcile → write-back pattern. The frontend's 30s poll on usePersonasQuery() becomes the refresh trigger with zero new infrastructure. Key design decisions: - Mtime short-circuit: stat the symlink target dir before calling resolve_pack(). Unchanged mtime = skip. Common case pays one stat() per symlinked pack instead of a full re-parse. - Quick pre-scan in the AppHandle wrapper: if no symlinked packs exist, managed_agents.json is never loaded (Thufir's concern about the hot path loading two JSON files on every poll). - Removal safety gate: when a persona is removed from the source pack but a managed agent still references it by persona_id UUID, deactivate (is_active = false) rather than delete to avoid orphaning running agents. managed_agents.json is only loaded when removals are detected. - Non-symlinked packs are completely unaffected. - Broken symlinks (canonicalize fails) log a warning and are skipped. - name_pool is always Vec::new() for pack personas (matches existing import_persona_pack() behavior).