Skip to content

feat(desktop): replace PNG persona export with JSON format - #144

Merged
wesbillman merged 4 commits into
mainfrom
feat/export-persona-json
Mar 21, 2026
Merged

feat(desktop): replace PNG persona export with JSON format#144
wesbillman merged 4 commits into
mainfrom
feat/export-persona-json

Conversation

@wesbillman

@wesbillman wesbillman commented Mar 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

Replace the PNG-based persona export/import format with a clean JSON format for better compatibility with other tools when sharing persona files.

Exported .persona.json format

{
  "version": 1,
  "displayName": "Researcher",
  "systemPrompt": "You are a research agent...",
  "avatarUrl": "https://example.com/avatar.png"
}

The avatarUrl field supports three scenarios:

  • Regular URL: "https://example.com/avatar.png"
  • Base64 data URI: "data:image/png;base64,iVBORw0KGgo..." (inline image, round-trips through export → import)
  • No avatar: field is omitted entirely

What changed

Export: Personas now export as .persona.json files instead of .persona.png. Avatars (including base64 data URIs) are preserved in the avatarUrl field.

Import: Accepts .persona.json, .persona.png (backwards compat), and .zip (containing either format). JSON import reads avatarUrl and populates the avatar on the imported persona.

Removed: PNG encoding pipeline (encode_persona_png, generate_placeholder_png, hsl_to_rgb, chara card encoding). PNG decoding kept for backwards-compatible import of old .persona.png files.

Changes (9 files, +232/-249)

Rust backend:

  • persona_card.rs: Added parse_json_persona() (with avatarUrl support), encode_persona_json(), extracted shared extract_sprout_fields() helper, updated ZIP parser for .json entries, removed PNG encoding functions
  • commands/personas.rs: Replaced export_persona_to_png with export_persona_to_json, updated parse_persona_files for JSON detection
  • lib.rs: Updated command registration

TypeScript frontend:

  • Single "Export" button (JSON only) replaces "Export PNG"
  • Drag-and-drop accepts .persona.json, .persona.png, and .zip
  • Updated API layer, hooks, and test harness

Testing

  • 49 unit tests pass (8 new JSON-specific tests, including avatar round-trip scenarios)
  • Full CI green: fmt, clippy, desktop-check, desktop-build, rust-tests
  • Backwards compat: old .persona.png files still importable

- Add encode_persona_json() and parse_json_persona() for the new
  .persona.json file format (version 1 schema)
- Replace export_persona_to_png Tauri command with export_persona_to_json
- Remove PNG encoding path: encode_persona_png, generate_placeholder_png,
  hsl_to_rgb, and chara card encoding
- Keep PNG/chara import path for backwards compatibility with existing
  .persona.png files
- Update ZIP parser to accept both .json and .png entries
- Update parse_persona_files to detect and handle JSON input
- Frontend: single 'Export' button (JSON only), remove PNG export UI
- Update drag-and-drop import to accept .persona.json files
- Add comprehensive tests for JSON round-trip, validation, and mixed
  ZIP archives
- Update e2eBridge test harness for new command name
- Extract shared extract_sprout_fields() helper to deduplicate validation
  logic between parse_json_persona() and parse_sprout_payload()
- Rename JSON_MAGIC ([u8; 1] array) to JSON_OPEN_BRACE (u8 scalar) for
  clarity and consistency with the frontend's JSON_FIRST_BYTE pattern
parse_json_persona() now reads the avatarUrl field from the JSON file
and passes it through as avatar_data_url in the preview. This ensures
base64 data-URI avatars and regular URL avatars survive the
export/import round-trip.

Adds tests for avatar round-trip with URL, data URI, and no-avatar cases.
Skip __MACOSX/._ entries during ZIP parsing instead of treating them
as persona files and reporting confusing parse errors.
@wesbillman
wesbillman merged commit cba19f8 into main Mar 21, 2026
8 checks passed
@wesbillman
wesbillman deleted the feat/export-persona-json branch March 21, 2026 00:02
tlongwell-block added a commit that referenced this pull request Mar 21, 2026
…tocol

* origin/main:
  feat: remote agent backend providers (#134)
  feat(desktop): replace PNG persona export with JSON format (#144)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant