Schema 0.x - Breaking changes expected. Not yet stable.

Collection Format (.brfc)

Bundle multiple .brfr files into a single shareable package.

A .brfc file is a ZIP archive containing multiple .brfr files with shared metadata and search indexing. It represents a folder of briefs as a single distributable unit.

File Structure

my-folder.brfc (ZIP archive)
+-- collection.json       # Required: metadata, brief index
+-- briefs/               # Required: folder containing .brfr files
|   +-- brief-01.brfr
|   +-- brief-02.brfr
|   +-- brief-03.brfr
+-- cover.jpg             # Optional: folder thumbnail (max 512x512)

collection.json Schema

{
  "version": "1.0.0",
  "title": "New Hire Training",
  "description": "Complete onboarding documentation for EVS staff",
  "author": "Jordan Reyes",
  "created": "2026-01-15T10:00:00Z",
  "modified": "2026-01-20T14:30:00Z",
  "cover": "cover.jpg",
  "briefs": [
    {
      "file": "briefs/brief-01.brfr",
      "id": "original-brief-uuid",
      "title": "Welcome & Safety",
      "stepCount": 5,
      "searchText": "welcome safety orientation ppe gloves...",
      "thumbnail": "data:image/jpeg;base64,..."
    },
    {
      "file": "briefs/brief-02.brfr",
      "id": "original-brief-uuid-2",
      "title": "Equipment Overview",
      "stepCount": 8,
      "searchText": "equipment floor scrubber vacuum mop...",
      "thumbnail": "data:image/jpeg;base64,..."
    }
  ]
}

Root Fields

FieldTypeRequiredDescription
versionstringYesFormat version ("1.0.0")
titlestringYesFolder name at time of export
descriptionstringNoOptional description
authorstringNoCreator's name
createdstringNoISO 8601 timestamp
modifiedstringNoMost recent brief modification
coverstringNoPath to cover image in archive
briefsarrayYesOrdered array of brief entries

Brief Entry Fields

FieldTypeRequiredDescription
filestringYesPath to .brfr file within archive
idstringYesOriginal brief ID (for deduplication)
titlestringYesBrief title
stepCountnumberNoNumber of steps (for display)
searchTextstringNoPre-computed search text
thumbnailstringNoBase64 data URL for preview

Constraints

Use Cases

searchText Generation

The searchText field enables fast filtering without parsing each .brfr file. It's computed by extracting all text content:

function extractSearchableText(manifest) {
  const parts = [];
  if (manifest.title) parts.push(manifest.title);
  for (const step of (manifest.steps || [])) {
    for (const el of (step.elements || [])) {
      if (el.type === 'text' && el.content) parts.push(el.content);
      if (el.type === 'image' && el.alt) parts.push(el.alt);
      if (el.type === 'row' && el.items) {
        for (const item of el.items) {
          if (item.type === 'text' && item.content) parts.push(item.content);
        }
      }
    }
  }
  return parts.join(' ').replace(/\s+/g, ' ').trim().toLowerCase();
}