Manifest types
Every type in a .tintero manifest: the root and the 77 it reaches, with the 677 fields they declare, extracted from the interfaces the app serialises.
Every type in a .tintero manifest, resolved from Project outwards
until nothing new turns up, so this is the whole file rather than the parts somebody
remembered to list. The names, the types, the optionality and the descriptions all come out
of the interfaces the app serialises, which means the page cannot describe a field that no
longer exists or miss one that just appeared.
Before you read one
Three things are worth having in mind before the tables below make sense, and each has a page of its own because they are about the container rather than the types:
- A project is a folder, not a file, and the manifest sits in it beside the text and the assets. See project structure.
- There is no format version anywhere. An optional field is optional forever, and its absence means an older project rather than a damaged one.
- None of the writing is in here. Every entry's text is a separate file of
ProseMirror JSON, found through the entry's
location.
The shareable form of a project is a .tint archive, which holds the same manifest under a different name.
Timestamps
Nearly every timestamp is a number, milliseconds since 1970. The exceptions are typed
Date in the source, which means JSON.stringify writes them out as
ISO-8601 strings instead:
ImagesModel.createdAt AudioAsset.createdAt PdfAsset.createdAt
Nothing in the file marks them out, so a reader that expects numbers everywhere gets a string on exactly these fields. This list is read from the source, not from memory. A field that changes type in Tintero moves in or out of it on the next sync.
The manifest root
The top level of a .tintero file. The required fields are in every project. The
optional ones are missing from projects made before that feature existed.
Project #
The root of the .tintero manifest.
There is no serialiser between this object and the file: the manifest is a plain
JSON.stringify of it, so this declaration is the file format. Two consequences worth
knowing before reading one. Optional fields are optional forever, because a feature added
later shows up as a field that older projects simply do not have, and there is no version
number anywhere to tell you which release wrote the file. And the writing itself is never
in here: every chapter, doc, note and saved version keeps its text in its own file under
files/, addressed by the entry's location.
Importing rebuilds this object field by field from an allow list in ProjectFactory, so
keys of your own survive ordinary saving and vanish the first time a project is imported.
images ? ImagesModel [] Images stored under the project's images/ folder. Undefined in projects with none.
coverImageId ? string | null The project's cover: the id of one of the in images. Undefined or
null means no cover, and the welcome screen draws a placeholder seeded from id instead.
Resolved to a URL or data URL on demand. The image itself is deliberately not inlined
here, to keep the manifest small.
id string Stable identifier, a UUID. Also the name of the manifest file: <id>.tintero.
name string Title as the writer typed it. Not unique and not an identifier.
description string | null Free text shown on the project card. Null when never filled in.
path string Where the project folder sits, as the platform writes paths. Used to reopen it.
createdAt number When the project was created, epoch milliseconds.
lastModified number When anything in the project last changed, epoch milliseconds.
baseLastModified ? number The If-Match value of a v1 upload: the lastModified this client last saw on the SERVER.
Set transiently just before uploading, and compared by the server against its stored value
so an upload from a stale base is rejected with a 409 instead of overwriting somebody
else's work. It is never persisted and takes no part in the local model, since every
upload overwrites it. It is not in the file.
folders ProjectFolder [] The folder tree. Folders hold no content of their own, only a place in the hierarchy.
files ProjectFile [] Manuscript entries, the chapters and scenes that make up the book itself.
docs ProjectDoc [] Documents: the writer's own material that is not part of the manuscript.
notes NotesModel [] Notes, which are documents with their own panel rather than a place in the tree.
worldbuilding ? WorldbuildingElement [] Every worldbuilding element, of every type, in one array. Undefined means none.
customWorldbuildingTemplates ? CustomWorldbuildingTemplate [] Element types the writer defined themselves, beyond the built-in ones.
characters CharacterModel [] The cast. Characters are their own type rather than a worldbuilding element.
cardboardGrids ? CardboardGrid [] Corkboards: freeform grids of cards. Undefined in projects that never opened one.
plotGrids ? PlotGrid [] Plot grids: the structured table view of the story.
tags string[] Project-level tags, used for filtering on the welcome screen.
collections ? Collection [] Collections: named groupings of entries that cut across the folder tree.
wordCountLog ? WordCountLog [] Daily word counts, one entry per day the writer worked.
syncVersion ? number Which sync protocol wrote this: 1 for the full upload, 2 for incremental live sync.
writingGoals ? WritingGoal [] Writing targets. Undefined means a project older than the feature, which triggers a migration from the old trophy settings the first time it is opened.
writingMinutesLog ? WritingMinutesLog [] Minutes written per day, fed by the timer, for goals counted in minutes.
timelines ? TimelineData [] Timelines: events placed on an axis, in lanes.
flowMaps ? FlowMap [] Flowmaps: nodes and arrows for mapping how the story connects.
bookmarks ? Bookmark [] The index of manuscript bookmarks. The anchors themselves live in the document text as
bookmark nodes; this side holds their number, label and file. Undefined means a project
older than the feature.
audioAssets ? AudioAsset [] Narrations rendered to audio files. Undefined in projects with no audio.
pdfAssets ? PdfAsset [] PDFs kept alongside the project for reference. Undefined in projects with none.
src/app/domain/project/models/project.interface.ts
Every type in the manifest
The 76 other types the root reaches. They were found by following the interfaces outwards rather than by somebody listing them, so this is the whole file and not a summary of it. 5 of them are classes rather than interfaces, marked as such, because their constructors fill in defaults a field list cannot show, and one of them quietly upgrades older character data on the way in.
AudioAsset #
A generated narration stored in the project, parallel to .
The bytes live on disk under the project's audio/ folder (written via
IOIntegrationInterface.saveAudioToProject); this object is the metadata that
travels inside Project.audioAssets.
id string Stable identifier, a UUID.
title string The name shown to the writer.
fileName string The file's name inside audio/, extension included.
relativePath string Path under the project, normally audio/<fileName>. For a pack, the first clip.
size number File size in bytes.
mimeType string MIME type of the stored bytes, for example audio/mpeg.
format ? AudioFormat Container/codec, e.g. 'mp3' | 'wav'.
durationMs ? number Playback length in milliseconds, when known.
lang ? string ISO language the text was synthesized in.
voice ? string Voice id used to synthesize (provider voice id or native engine voice name).
origin ? AudioAssetOrigin OS-native engine or a cloud API.
provider ? string Provider that produced an api-origin asset (e.g. 'openai', 'elevenlabs').
sourceDocId ? string Id of the project doc/file this audio narrates, when generated from one.
treePath ? string Location in the file tree (parent path + name). Set when the audio lives in the tree.
createdAt Date When the narration was generated. Typed Date, so it serialises as ISO-8601.
hash ? string Content hash, used to tell whether the narration still matches its text.
segments ? AudioSegment [] When present, this asset is a PACK: an ordered sequence of clips played/mixed
gapless. A simple asset (single file) has no segments; relativePath/fileName
then point at the lone clip. For a pack they point at the first clip (compat).
src/app/domain/project/models/audio-asset.model.ts
AudioAssetOrigin #
Where an audio file came from.
'native' | 'api' | 'import' src/app/domain/project/models/audio-asset.model.ts
AudioSegment #
One clip within a pack (TINT-214). A pack is an ordered list
of clips played/mixed sequentially with silences between them, never stitched
into a single byte stream until export. Each clip's bytes live on disk under the
project's audio/ folder, just like a simple asset; this is the metadata.
id string Stable identifier of the clip, a UUID.
relativePath string Path of the clip's bytes under the project (audio/<id>.<format>).
durationMs number Clip length in milliseconds (derived once on synthesis, not re-decoded).
format ? AudioFormat Container/codec the engine ACTUALLY produced for this clip. Not always what was asked for:
the native engine ignores the requested format (macOS always yields m4a/AAC), so the pack's
own format is derived from this rather than from the request.
gapBeforeMs number Silence (ms) inserted BEFORE this clip when playing or mixing, which is how a pause is rendered.
sourceRange ? { from: number; to: number; docId: string } Source text range in the annotated doc this clip was synthesized from.
voice ? string Voice id used (catalog id or native engine voice name).
emotion ? TtsEmotion Emotion the clip was synthesized with, matching the ttsEmotion mark in the text.
params ? { speed?: number; pitch?: number; stability?: number; style?: number } Expressive params used, kept for incremental regeneration.
soundTags ? TtsSoundTagName[] Sound tags applied to the clip, matching the ttsSoundTag nodes in the text.
hash string Content hash (text + voice + emotion + params) for incremental regeneration.
src/app/domain/project/models/audio-asset.model.ts
BaseWorldbuildingElement #
What every worldbuilding element has, whatever kind it is.
All of them live together in one Project.worldbuilding array, so type is the only
thing telling a location from a deity. That makes this the discriminated union's tag, and
an unknown value in it means an element from a newer version of the app rather than a
damaged one.
A word on the fields of the element types that extend this. A field named somethingId or
somethingIds holds the id of another element, and so do the relationship fields the app
fills from a picker (allies, enemies, languages and a few more). Everything else is
text the writer typed, including the arrays: terrain, goals and their kind are lists of
words, not references to anything.
id string Stable identifier, a UUID. What other elements refer to it by.
name string The element's name, and what the app matches against when it highlights the prose.
type string Which kind of element this is. The tag that decides which interface applies.
description ? string Free text description, the main body of the element.
portrait ? string The element's portrait image, as a fileName or relativePath into images/.
landscape ? string The element's banner image, as a fileName or relativePath into images/.
tags ? string[] Tags the writer attached, used for filtering.
color ? string Colour chosen for the element, as CSS. Also used to highlight it in the text.
createdAt number When the element was created, epoch milliseconds.
updatedAt ? number When the element last changed, epoch milliseconds.
notes ? string The writer's own notes about the element, kept apart from description.
extraFields ? ExtraField [] Fields the writer added to this element alone. See .
isFavorite ? boolean Whether the writer pinned it to the top of the list.
src/app/domain/project/models/worldbuilding/base-worldbuilding.interface.ts
Bookmark #
A navigation bookmark in the manuscript.
The anchor itself, the actual position, is an inline node in the document JSON
(bookmark-node.ts). This is only the project's index of them, adding the file, the
number and the label. It lives inside Project so it syncs between devices without a
table of its own.
id string The same value as the data-bookmark-id of the node in the document.
fileId string The entry whose text holds the anchor.
number ? number Quick access slot, 0 to 9. Absent means a bookmark with no shortcut.
label ? string What the writer called it. Absent means the panel shows a generated label.
pos ? number | null A cache of where the node is, refreshed when the file is saved. It orders the panel and makes next and previous work without opening files. The document node is always the truth. Undefined means not reconciled yet. Null means reconciled and no node was found, so the bookmark is unresolved: it is shown marked as such and never deleted on its own.
lastModified number Epoch milliseconds. Required by the most-recent-wins merge in sync.
deletedAt ? number | null Soft delete. Without it the sync merge resurrects deleted bookmarks, because merging never removes: an item present on only one side is kept.
src/app/domain/project/models/bookmark.interface.ts
CardboardAxisHeader #
A label on one row or one column of a corkboard.
index number Which row or column it labels, zero based.
label string What it says.
color ? string Colour of the header, as CSS.
src/app/domain/project/models/cardboard.interface.ts
CardboardCell #
One cell of a corkboard.
Cells carry their own coordinates rather than sitting in a two-dimensional array, so the
cells list is sparse: an empty square of the board has no entry at all.
id string Stable identifier of the cell.
type string What the cell holds, one of the values.
referenceId ? string Id of the thing the cell stands for, when its type points at one.
position { row: number; col: number; } Where the cell sits on the board, zero based.
content ? string The cell's text.
imageUrl ? string Project asset (tintero-image://<key>) or a plain remote URL typed by the user.
audioAssetId ? string AudioAsset.id in Project.audioAssets. Audio is always a project asset, never a remote URL.
pdfAssetId ? string PdfAsset.id in Project.pdfAssets.
color ? string Colour of the cell, as CSS.
checked ? boolean For a checkbox cell, whether it is ticked.
title ? string A heading for the cell.
references ? CellReference [] Links from this cell to elsewhere in the project. See .
tags ? string[] Tags on the cell, used for filtering the board.
status ? string The cell's status, matching one of the project's configured statuses.
inlineNotes ? InlineNote [] Notes pinned inside the cell. See .
src/app/domain/project/models/cardboard.interface.ts
CardboardCellType #
| 'unassigned' | 'sticky-note' | 'chapter-note' | 'note' | 'character' | 'image' | 'audio' | 'pdf' | 'checkbox' | 'multi' src/app/domain/project/models/cardboard.interface.ts
CardboardGrid #
A corkboard: a grid of cards the writer arranges however they like.
id string Stable identifier, a UUID.
name string What the writer called this board.
rows number How many rows the board has.
cols number How many columns the board has.
cells CardboardCell [] The cells that hold something. Empty squares are simply absent.
createdAt number When the board was created, epoch milliseconds.
lastModified number When the board last changed, epoch milliseconds.
rowHeaders ? CardboardAxisHeader [] Labels down the side of the board.
colHeaders ? CardboardAxisHeader [] Labels across the top of the board.
showHeaders ? boolean Whether headers are shown at all. The two per-axis flags below override it.
showColHeaders ? boolean Whether the column headers are shown. Undefined falls back to showHeaders.
showRowHeaders ? boolean Whether the row headers are shown. Undefined falls back to showHeaders.
firstColumnSticky ? boolean Whether the first column stays put while the board scrolls sideways.
cellTypeWhitelist ? CardboardCellType [] When set, the only cell types this board allows.
preset ? CardboardPreset Which kind of board it is: freeform, or shaped like a plot grid.
src/app/domain/project/models/cardboard.interface.ts
CardboardPreset #
'free' | 'plotgrid' src/app/domain/project/models/cardboard.interface.ts
CardboardReferenceType #
| 'chapter' | 'doc' | 'character' | 'worldbuilding' src/app/domain/project/models/cardboard.interface.ts
CellReference #
A link from a corkboard cell to something else in the project.
id string Stable identifier of the reference itself, not of what it points at.
Which array of the project to look targetId up in.
targetId string Id of the chapter, doc, character or worldbuilding element being pointed at.
src/app/domain/project/models/cardboard.interface.ts
CharacterInterface #
Also has every field of BaseWorldbuildingElement .
A character seen as a worldbuilding element.
Characters live in Project.characters, not in Project.worldbuilding, but the pickers
and the element union treat them as one of the kinds. This is the shape they take when
they do. The real record is .
id string Id of the this stands for.
name string The character's name.
type 'character' Always character, which is what puts it in the element union.
src/app/domain/project/models/character.model.ts
CharacterModel #
A character.
A class rather than an interface, which matters when reading the file: the constructor
fills in defaults a field list cannot show, and it quietly upgrades older data. A
character saved before the worldbuilding links existed gets worldbuilding built for it
out of the three legacy fields the first time the app loads it.
The three legacy fields are still written and still read. They are not removed on
migration, so an old project holds the same fact twice.
id string Stable identifier, a UUID. Fixed once the character exists.
name string The name the character is known by, and what the app matches against in the prose.
firstName ? string Given name, when the writer split the name up.
lastName ? string Family name, when the writer split the name up.
pronouns ? string[] The character's pronouns, as the writer wrote them.
aka ? string[] Other names they go by, which are also matched against the prose.
description ? { physical?: string; psychological?: string; } The old two-part description. Superseded by physicalDescription and
psychologicalDescription and kept only so older projects still read. New code writes
the two flat fields.
physicalDescription ? string What the character looks like, as one block of text.
portrait string | undefined The character's portrait, as a fileName or relativePath into images/.
landscape string | undefined The character's banner image, as a fileName or relativePath into images/.
folderPath string | undefined Where the character sits in the characters panel's own folder tree.
position number | undefined Sort order within its folder, ascending.
psychologicalDescription ? string What the character is like inside, as one block of text.
color ? string Colour used for the character, as CSS. Also what highlights them in the text.
gender ? string Gender, as free text rather than a fixed set.
age ? string Age, as text, since a world may not count years the way ours does.
birthdate ? string When they were born, in the world's own calendar, so free text.
birthplace ? string Where they were born, as text. Migrated into worldbuilding.locations as well.
occupation ? string Their trade, as a plain name. Superseded by worldbuilding.occupations, which holds
ids, and still written alongside it.
species ? string Their species, as a plain name. Superseded by worldbuilding.species.
faction ? string Their faction, as a plain name. Superseded by worldbuilding.factions.
worldbuilding ? CharacterWorldbuilding Every tie between this character and the world. See .
traits ? string[] What they are like, as short pieces of text.
goals ? string[] What they want, as text.
fears ? string[] What they are afraid of, as text.
backstory ? string Where they come from, as one block of text.
notes ? string The writer's own notes about them, kept apart from the description.
tags ? string[] Tags the writer attached, used for filtering.
createdAt number When the character was created, epoch milliseconds. Fixed once set.
updatedAt ? number When the character last changed, epoch milliseconds.
relationships ? Relationship [] Ties to other characters. See .
variants ? CharacterVariant [] Other versions of this character. See .
src/app/domain/project/models/character.model.ts
CharacterVariant #
A version of a character: an alias, a disguise, who they become in act three.
A variant is a patch, not a copy. overrides holds only the fields that differ, so
reading one means starting from the character and laying these on top.
id string Stable identifier of the variant within its character.
name string What the writer calls this version.
description ? string What makes it different, in the writer's words.
position ? number Where it sits in the list of variants, ascending.
overrides Partial<Omit< CharacterModel , 'id' | 'variants'>> The fields that differ from the character. Everything absent is inherited unchanged.
createdAt number When the variant was created, epoch milliseconds.
updatedAt ? number When the variant last changed, epoch milliseconds.
src/app/domain/project/models/character.model.ts
CharacterWorldbuilding #
How a character is tied into the world, one array of element ids per kind of tie.
Thirty-eight ways of being connected to something, all of them optional and all of them
holding ids from Project.worldbuilding. One exception is worth knowing about when
reading old projects: a character migrated from the three legacy fields
(CharacterModel.species, occupation, faction) gets the plain NAME the writer typed
pushed into species, occupations, factions or locations instead of an id, and
nothing marks the difference. Resolve by id first and fall back to matching on name.
species ? string[] Ids of the elements this character belongs to.
factions ? string[] Ids of the elements they belong to.
occupations ? string[] Ids of the elements they hold.
locations ? string[] Ids of the elements tied to them.
religions ? string[] Ids of the elements they follow.
magicSystems ? string[] Ids of the elements they can use.
languages ? string[] Ids of the elements they speak.
technologies ? string[] Ids of the elements they use.
groupMember ? string[] Ids of the groups they belong to.
groupLeader ? string[] Ids of the groups they lead.
groupFounder ? string[] Ids of the groups they founded.
groupExMember ? string[] Ids of the groups they used to belong to.
groupExLeader ? string[] Ids of the groups they used to lead.
deityFollower ? string[] Ids of the deities they follow.
deityChampion ? string[] Ids of the deities they act for.
deityClergy ? string[] Ids of the deities they serve as clergy.
deityEnemy ? string[] Ids of the deities that oppose them.
deityBlessed ? string[] Ids of the deities that have blessed them.
deityCursed ? string[] Ids of the deities that have cursed them.
deityExFollower ? string[] Ids of the deities they used to follow.
creatureTamed ? string[] Ids of the creatures they have tamed.
creatureHunted ? string[] Ids of the creatures they hunt.
creatureProtected ? string[] Ids of the creatures they protect.
creatureEncountered ? string[] Ids of the creatures they have met.
creatureCompanion ? string[] Ids of the creatures that travel with them.
creatureFamiliar ? string[] Ids of the creatures bound to them.
itemOwner ? string[] Ids of the items they own.
itemCreator ? string[] Ids of the items they made.
itemDiscovered ? string[] Ids of the items they found.
itemGuardian ? string[] Ids of the items they guard.
itemExOwner ? string[] Ids of the items they used to own.
itemSeeker ? string[] Ids of the items they are looking for.
eventParticipant ? string[] Ids of the events they took part in.
eventKeyFigure ? string[] Ids of the events they were central to.
eventCausedBy ? string[] Ids of the events they brought about.
eventWitness ? string[] Ids of the events they saw.
eventVictim ? string[] Ids of the events done to them.
eventHero ? string[] Ids of the events they came out of well.
src/app/domain/project/models/character.model.ts
Collection #
A named grouping of entries that cuts across the folder tree.
An entry can be in any number of collections and stays exactly where it is in the tree.
Nothing on the entry itself records the membership: it exists only in items here.
id string Stable identifier, a UUID.
name string What the writer called the collection.
createdAt number When the collection was created, epoch milliseconds.
lastModified number When the collection last changed, epoch milliseconds.
items CollectionItem [] Its members, in the order the writer arranged them.
src/app/domain/project/models/colletions.interface.ts
CollectionItem #
One entry inside a , and which array of the project to find it in.
id string Id of the or .
type 'file' | 'doc' Which of the two it is, since ids alone do not say.
src/app/domain/project/models/colletions.interface.ts
Creature #
Also has every field of BaseWorldbuildingElement .
A beast, a monster or anything else alive that is not a of people.
habitat and habitatIds are the usual pair: the first is what the writer typed, the
second is the locations they picked.
type 'creature' Always creature. The tag that says which interface applies to this element.
creatureType ? 'beast' | 'monster' | 'mythical' | 'domesticated' | 'magical' | 'undead' | 'elemental' | 'other' What sort of creature it is.
behavior ? 'friendly' | 'hostile' | 'neutral' | 'varies' | 'territorial' | 'protective' How it acts towards people.
intelligence ? 'animal' | 'low' | 'moderate' | 'high' | 'genius' How much it understands.
lifespan ? string How long it lives, as text.
habitat ? string[] Where it lives, as text.
habitatIds ? string[] Ids of the elements where it lives.
diet ? 'carnivore' | 'herbivore' | 'omnivore' | 'magical' | 'parasitic' | 'energy' What it eats.
rarity ? 'common' | 'uncommon' | 'rare' | 'legendary' | 'unique' | 'extinct' How often it is met, extinct included.
physicalTraits ? string[] How it looks, as text.
abilities ? string[] What it can do, as text.
weaknesses ? string[] What it cannot stand, as text.
size ? 'tiny' | 'small' | 'medium' | 'large' | 'huge' | 'colossal' Roughly how big it is.
domesticatable ? boolean Whether it can be tamed at all.
magicalProperties ? string[] What is unusual about it, as text.
relationshipWithSpecies ? { speciesId: string; relationshipType: 'domesticated' | 'feared' | 'worshipped' | 'hunted' | 'symbiotic' | 'neutral'; description?: string; }[] How each species in the project regards it.
knownLocations ? string[] Where it has been seen, as text.
knownLocationIds ? string[] Ids of the elements where it has been seen.
culturalSignificance ? string What it means to the people of the world, as one block of text.
averageSize ? string Typical size, as text, alongside the coarse size band.
socialStructure ? string How they live together, as one block of text.
encounteredBy ? string[] Who has met it, as text.
tamedBy ? string[] Who has tamed it, as text.
huntedBy ? string[] Who hunts it, as text.
protectedBy ? string[] Who protects it, as text.
src/app/domain/project/models/worldbuilding/creature.interface.ts
CustomField #
One field in a .
id string Stable identifier, and the key the value is stored under in customFields.
name string Internal name of the field.
label string What the writer sees beside the input.
type CustomFieldType What kind of input it is, which decides what the stored value looks like.
placeholder ? string Grey text shown in the empty input.
description ? string Help text shown under the input.
defaultValue ? any What a new element starts with in this field.
validation ? CustomFieldValidation Rules the value is checked against.
relationshipConfig ? RelationshipConfig For a relationship field, what it may point at.
order ? number Where the field sits in the form, ascending.
src/app/domain/project/models/worldbuilding/custom-field.interface.ts
CustomFieldType #
'text' | 'textarea' | 'checkbox' | 'relationship' src/app/domain/project/models/worldbuilding/custom-field.interface.ts
CustomFieldValidation #
The rules a is checked against as the writer fills it in.
required ? boolean Whether the field has to be filled in.
minLength ? number Shortest accepted value.
maxLength ? number Longest accepted value.
pattern ? string A regular expression the value has to match, as a string.
src/app/domain/project/models/worldbuilding/custom-field.interface.ts
CustomWorldbuildingElement #
Also has every field of BaseWorldbuildingElement .
An element of a kind the writer invented, described by one of the project's
s.
The template says which fields exist; this holds what was put in them. A reader that does
not know the template still gets the values, keyed by field id, and can look the labels up
in Project.customWorldbuildingTemplates.
type string Not one of the built-in kinds. Holds the template's own type string.
customType string Id of the this element follows.
customTypeName string The template's name, copied here so the element reads on its own.
customTypeIcon ? string The template's icon, copied here.
customTypeColor ? string The template's colour, copied here.
customFields { [fieldId: string]: any } The values, keyed by the id of the in the template.
src/app/domain/project/models/worldbuilding/custom-worldbuilding.interface.ts
CustomWorldbuildingTemplate #
A kind of worldbuilding element the writer defined themselves.
The template is the schema and holds the data. They are
stored apart, in Project.customWorldbuildingTemplates and Project.worldbuilding, so a
tool reading one needs the other to put labels on the values.
id string Stable identifier, and what an element's customType points at.
name string What the writer called this kind of element.
description ? string What it is for, in the writer's words.
icon string Icon shown for elements of this kind.
color string Colour used for elements of this kind, as CSS.
fields CustomField [] The fields elements of this kind have. See .
createdAt number When the template was created, epoch milliseconds.
updatedAt number When the template last changed, epoch milliseconds.
archived ? boolean Archived templates stay in the file so their elements keep their labels.
tags ? string[] Tags on the template itself, not on its elements.
version ? number Bumped when the field list changes, so older elements can be recognised as older.
src/app/domain/project/models/worldbuilding/custom-worldbuilding-template.interface.ts
Deity #
Also has every field of BaseWorldbuildingElement .
A god, or something close enough to be worshipped.
Several things here come in pairs: temples beside templeIds, followers beside
followerIds. The plain one is what the writer typed and the Ids one is what they
picked from the project. Both can hold something at once and neither is derived from the
other, so a reader that wants everything has to look at both.
type 'deity' Always deity. The tag that says which interface applies to this element.
deityType ? 'god' | 'goddess' | 'demigod' | 'titan' | 'spirit' | 'angel' | 'demon' | 'ancestor' | 'elemental' | 'other' What sort of divine being it is.
domains ? string[] What it is the god of, as text.
alignment ? 'good' | 'neutral' | 'evil' | 'chaotic' | 'lawful' | 'balanced' | 'unknown' Where it stands morally.
powerLevel ? 'lesser' | 'intermediate' | 'greater' | 'overdeity' | 'quasi-deity' How much power it has, relative to the rest of the pantheon.
physicalDescription ? string What it looks like when it appears, as one block of text.
symbols ? string[] Its symbols, as text.
holyDays ? { name: string; date?: string; significance?: string; rituals?: string[]; }[] The dates in its calendar that matter.
followers ? string[] Its followers, as text.
followerIds ? string[] Ids of the elements that follow it.
clergy ? string[] Its clergy, as text.
clergyIds ? string[] Ids of the elements that serve as its clergy.
temples ? string[] Its temples, as text.
templeIds ? string[] Ids of the elements that are its temples.
artifacts ? string[] Objects tied to it, as text.
artifactIds ? string[] Ids of the elements tied to it.
enemies ? string[] Who it opposes, as text.
allies ? string[] Who stands with it, as text.
parentDeity ? string Id of the deity it descends from, which is how a pantheon's family tree is built.
childrenDeities ? string[] Ids of the deities that descend from it.
worshippedBy ? string[] Who worships it, as text.
worshippedByIds ? string[] Ids of the elements that worship it.
religionIds ? string[] Ids of the elements it belongs to.
myths ? string[] The stories told about it, as text.
prayers ? string[] What is said to it, as text.
offerings ? string[] What is given to it, as text.
manifestations ? string[] How it shows itself in the world, as text.
intervention ? 'active' | 'passive' | 'dormant' | 'dead' | 'unknown' How involved it is in mortal affairs.
moralCode ? string[] What it demands of its followers, as text.
champions ? string[] Who acts in its name, as text.
enemies_deities ? string[] Ids of the deities it is at odds with, as picked from the project.
allies_deities ? string[] Ids of the deities it is allied with, as picked from the project.
src/app/domain/project/models/worldbuilding/deity.interface.ts
ExtraField #
A field the writer added to one element by hand, without defining a template for it.
id string Stable identifier of the field within its element.
label string What the writer called it.
value string What they put in it, always as text.
type 'text' | 'textarea' Whether it is shown as a single line or a box.
src/app/domain/project/models/worldbuilding/base-worldbuilding.interface.ts
Faction #
Also has every field of BaseWorldbuildingElement .
An organised group with an agenda: a party, an order, a guild, a syndicate.
type 'faction' Always faction. The tag that says which interface applies to this element.
factionType ? 'political' | 'religious' | 'military' | 'economic' | 'criminal' | 'academic' | 'other' What kind of faction it is.
ideology ? string What it believes, as text.
goals ? string[] What it is trying to achieve, as text.
structure ? 'hierarchy' | 'democracy' | 'council' | 'anarchy' | 'other' How it is organised internally.
territory ? string[] What it holds, as text.
resources ? string[] What it can draw on, as text.
allies ? string[] Ids of the factions it is allied with.
enemies ? string[] Ids of the factions it is at odds with.
leaderIds ? string[] Ids of the characters or elements who lead it.
memberIds ? string[] Ids of the characters or elements who belong to it.
foundedDate ? string When it was founded, in the world's own calendar, so free text.
status ? 'active' | 'disbanded' | 'dormant' | 'unknown' Whether it still exists.
influence ? 'local' | 'regional' | 'national' | 'continental' | 'global' | 'interplanetary' How far its reach goes.
src/app/domain/project/models/worldbuilding/faction.interface.ts
FileSnapshot #
A saved version of a chapter or document.
A snapshot is a full copy of the text at a moment in time, kept in its own file next to
every other content file. Nothing about it says which entry it came from: that link exists
only in the snapshots array it is listed in.
id string Stable identifier, a UUID.
location string Where the saved text is: files/<location>.json, alongside live content.
name string What the writer called this version, or the automatic label it was given.
createdAt number When the version was taken, epoch milliseconds.
writingMode ? WritingMode The writing mode the text was in when it was saved.
src/app/domain/project/models/file-snapshot.interface.ts
FlowMap #
A flowmap: nodes and arrows on a free canvas, for mapping how the story connects.
id string Stable identifier, a UUID.
name string What the writer called this flowmap.
nodes FlowMapNode [] Its nodes. Position is on the node itself, so the order here means nothing.
connections FlowMapConnection [] The arrows between them.
createdAt number When the flowmap was created, epoch milliseconds.
lastModified number When the flowmap last changed, epoch milliseconds.
src/app/domain/project/models/flowmap.interface.ts
FlowMapArrowType #
'simple' | 'bidirectional' | 'unidirectional-forward' | 'unidirectional-backward' | 'dotted' src/app/domain/project/models/flowmap.interface.ts
FlowMapConnection #
An arrow between two flowmap nodes.
id string Stable identifier of the connection.
fromNodeId string Id of the the arrow leaves.
toNodeId string Id of the the arrow reaches.
arrowType FlowMapArrowType What the arrow looks like, and which way it points.
label ? string Text drawn on the arrow.
startEdgePosition ? number Where on the source node's edge the arrow starts.
endEdgePosition ? number Where on the target node's edge the arrow lands.
color ? string Colour of the arrow, as CSS.
src/app/domain/project/models/flowmap.interface.ts
FlowMapNode #
A box on a flowmap.
id string Stable identifier, and what a connection's fromNodeId and toNodeId point at.
label string The text in the node.
x number Horizontal position on the canvas, in pixels.
y number Vertical position on the canvas, in pixels.
type FlowMapNodeType What shape the node is drawn as. Not a fixed set: a custom string is allowed.
color string Colour of the node, as CSS.
title ? string A small label above the node's text ("DECISION", "ACT II"). The writer types it. It sits
where the shape's type name used to be drawn, which told nobody anything. Without it the
node shows only label.
padding ? number Padding inside the node, in pixels, chosen by hand. Without it the shape's own padding applies, set in SCSS: every shape needs its own, since a circle has to keep its text off the curve, but the value that suits three words smothers one.
extendedText ? string Longer text kept with the node and shown when it is opened.
noteColor ? string Colour key for a note node: yellow, green and the rest, rather than CSS.
linkedDocument ? string Id of the project document tied to this node.
linkedCharacterId ? string Id of the project character tied to this node.
linkedWorldbuildingId ? string Id of the project worldbuilding element tied to this node.
todoList ? { id: string; text: string; done: boolean }[] For a todo-list node, its items.
width ? number Node width in pixels, when the writer resized it.
height ? number Node height in pixels, when the writer resized it.
customData ? any Anything a node type keeps that has no field of its own. Shape depends on type.
src/app/domain/project/models/flowmap.interface.ts
FlowMapNodeType #
'circle' | 'square' | 'rounded' | 'document' | 'todo-list' | 'simple-list' | 'diamond' | string src/app/domain/project/models/flowmap.interface.ts
Group #
Also has every field of BaseWorldbuildingElement .
A smaller body of people than a : a family, a guild, a coven, a crew.
Like , some things come in pairs. territory is what the writer typed and
territoryIds is what they picked from the project's locations.
type 'group' Always group. The tag that says which interface applies to this element.
groupType ? 'family' | 'guild' | 'clan' | 'cult' | 'gang' | 'tribe' | 'order' | 'circle' | 'brotherhood' | 'society' | 'other' What sort of group it is.
size ? number How many belong to it.
parentFaction ? string Id of the it sits under, when it is part of a larger body.
leadership ? string How it is led, as one block of text.
leaderIds ? string[] Ids of the elements that lead it.
memberIds ? string[] Ids of the elements that belong to it.
requirements ? string[] What it takes to join, as text.
benefits ? string[] What members get out of it, as text.
traditions ? string[] What it always does, as text.
meetingPlace ? string Where it meets, as text.
meetingPlaceId ? string Id of the where it meets.
foundedDate ? string When it was founded, in the world's own calendar, so free text.
status ? 'active' | 'disbanded' | 'dormant' | 'secret' | 'unknown' Whether it still exists, and whether anyone knows.
influence ? 'local' | 'regional' | 'widespread' | 'limited' How far its reach goes.
goals ? string[] What it is trying to achieve, as text.
rituals ? string[] What it does together, as text.
hierarchy ? string How rank works inside it, as one block of text.
territory ? string[] What it holds, as text.
territoryIds ? string[] Ids of the elements it holds.
resources ? string[] What it can draw on, as text.
allies ? string[] Ids of the groups it is allied with.
enemies ? string[] Ids of the groups it is at odds with.
secrets ? string[] What it keeps quiet, as text.
initiationProcess ? string How somebody gets in, as one block of text.
socialStatus ? 'respected' | 'feared' | 'neutral' | 'outcast' | 'unknown' How the world at large regards it.
relatedFactions ? string[] Ids of the elements it is connected to.
homeBase ? string Where it is based, as text.
src/app/domain/project/models/worldbuilding/group.interface.ts
ImagesModel #
An image stored in the project.
The bytes are a file under the project's images/ folder. This object is the metadata
that travels in the manifest, and it is deliberately the only thing that does: nothing
here is base64, so a project with a hundred illustrations still has a small manifest.
id string Stable identifier, a UUID.
title string The name shown to the writer, which is not the file name on disk.
fileName string The file's name inside images/, extension included.
relativePath string Path under the project, normally images/<fileName>. See imageStorageKey.
size number File size in bytes.
mimeType string MIME type of the stored bytes, for example image/png.
width ? number Pixel width, when it was measured.
height ? number Pixel height, when it was measured.
createdAt Date When the image was added. Typed Date, which means JSON.stringify writes it as an
ISO-8601 string rather than the epoch milliseconds used almost everywhere else.
hash ? string Hash of the bytes, used to spot a real change.
lastModified ? number When the image metadata last changed, epoch milliseconds.
treePath ? string Position in the file tree, the parent's path plus the name, mirroring
AudioAsset.treePath. Undefined means the image has no place of its own and shows up
in the fixed Images folder.
src/app/domain/project/models/images.model.ts
InlineNote #
A small note pinned inside a corkboard cell, alongside whatever the cell already holds.
id string Stable identifier of the note within its cell.
kind InlineNoteKind What the note is, which decides which of the fields below carry anything.
content ? string The note's text.
title ? string A heading for the note.
color ? string Colour of the note, as CSS.
checked ? boolean For a checkbox note, whether it is ticked.
imageUrl ? string Project asset (tintero-image://<key>) or a plain remote URL typed by the user.
audioAssetId ? string AudioAsset.id in Project.audioAssets. Audio is always a project asset, never a remote URL.
pdfAssetId ? string PdfAsset.id in Project.pdfAssets.
src/app/domain/project/models/cardboard.interface.ts
InlineNoteKind #
'sticky' | 'checkbox' | 'image' | 'audio' | 'pdf' src/app/domain/project/models/cardboard.interface.ts
Item #
Also has every field of BaseWorldbuildingElement .
An object that matters to the story: a sword, a letter, a crown, a key.
The where-and-whose fields come in pairs. currentOwner is the name the writer typed and
currentOwnerId is the element they picked, and the two are kept independently.
type 'item' Always item. The tag that says which interface applies to this element.
itemType ? 'weapon' | 'armor' | 'tool' | 'jewelry' | 'document' | 'artifact' | 'clothing' | 'consumable' | 'currency' | 'key' | 'book' | 'other' What sort of object it is.
rarity ? 'common' | 'uncommon' | 'rare' | 'legendary' | 'unique' | 'cursed' How rare it is, cursed included, since that is how the writer thinks of it.
value ? string What it is worth, as text, since worlds do not agree on currency.
properties ? string[] What it does, as text.
magicalProperties ? string[] What it does that is not ordinary, as text.
origin ? string Where it came from, as one block of text.
currentLocation ? string Where it is now, as text.
currentLocationId ? string Id of the it is in now.
currentOwner ? string Who has it now, as text.
currentOwnerId ? string Id of the element that has it now.
previousOwners ? string[] Who had it before, as text.
previousOwnerIds ? string[] Ids of the elements that had it before.
condition ? 'pristine' | 'excellent' | 'good' | 'worn' | 'damaged' | 'broken' | 'destroyed' What state it is in.
materials ? string[] What it is made of, as text.
weight ? string What it weighs, as text.
dimensions ? string How big it is, as text.
requirements ? string[] What it takes to use it, as text.
effects ? string[] What happens when it is used, as text.
limitations ? string[] What it cannot do, as text.
culturalSignificance ? string What it means to the people of the world, as one block of text.
historicalEvents ? { eventName: string; date?: string; description?: string; }[] Things that happened to it, written inline rather than linked to event elements.
relatedItems ? string[] Ids of the items connected to it.
associatedFactions ? string[] Ids of the elements connected to it.
associatedGroups ? string[] Ids of the elements connected to it.
createdBy ? string Who made it, as text.
discoveredBy ? string Who found it, as text.
src/app/domain/project/models/worldbuilding/item.interface.ts
Language #
Also has every field of BaseWorldbuildingElement .
A language spoken in the world.
type 'language' Always language. The tag that says which interface applies to this element.
speakers ? string[] Who speaks it, as text.
speakerCount ? number How many speakers it has.
writingSystem ? string How it is written down, as text.
familyGroup ? string The family it belongs to, as text.
dialects ? string[] Its dialects, as text.
commonPhrases ? { phrase: string; meaning: string; context?: string; }[] A small phrasebook the writer keeps with the language.
culturalSignificance ? string What the language means to the people who speak it, as one block of text.
status ? 'thriving' | 'declining' | 'dead' | 'ceremonial' Whether it is still in use.
relatedLanguages ? string[] Nearby languages, as text.
src/app/domain/project/models/worldbuilding/language.interface.ts
Location #
Also has every field of BaseWorldbuildingElement .
A place in the world, from a room to a planet.
type 'location' Always location. The tag that says which interface applies to this element.
locationType ? 'city' | 'village' | 'region' | 'country' | 'continent' | 'planet' | 'building' | 'landmark' | 'other' What scale of place it is.
parentLocationId ? string Id of the location this one sits inside, which is how the place hierarchy is built.
climate ? string The climate, as text.
terrain ? string[] Terrain types, as words the writer typed.
population ? number How many people live there.
governmentType ? string How the place is governed, as text.
rulerIds ? string[] Ids of the characters or elements who rule it.
notableFeatures ? string[] Things worth mentioning about the place, as text.
economy ? string[] What the place lives on, as text.
defenses ? string[] How it is defended, as text.
threats ? string[] What threatens it, as text.
history ? string The place's history, as one block of text.
culturalNotes ? string Notes on its culture, as one block of text.
languages ? string[] Ids of the elements spoken there.
currency ? string What they use for money, as text.
importantEvents ? { eventName: string; date?: string; description?: string; }[] Things that happened here, written inline rather than linked to event elements.
src/app/domain/project/models/worldbuilding/location.interface.ts
MagicSystem #
Also has every field of BaseWorldbuildingElement .
How magic works in this world: where it comes from and what it takes.
type 'magicSystem' Always magicSystem. The tag that says which interface applies to this element.
sourceOfPower ? string Where the power comes from, as one block of text.
limitations ? string[] What it cannot do, as text.
costs ? string[] What using it costs, as text.
practitioners ? string[] Who can use it, as text.
schools ? { name?: string; focus?: string; commonSpells?: string[]; }[] The traditions within the system, written inline.
artifacts ? string[] Objects tied to the system, as text.
forbiddenMagic ? string[] What is off limits, as text.
socialAcceptance ? 'accepted' | 'feared' | 'regulated' | 'forbidden' How the world at large treats it.
learningMethod ? 'innate' | 'study' | 'training' | 'bloodline' | 'divine' | 'other' How somebody comes to be able to use it.
src/app/domain/project/models/worldbuilding/magic-system.interface.ts
NotesModel #
A sticky note.
Notes are not part of the tree. A note either floats free in the project or is pinned to
one chapter through fileId, and its text lives in its own file like everything else.
id string Stable identifier, a UUID.
fileId string | null The chapter this note is pinned to, or null for a note that belongs to the project.
type string The note's colour, which is also what the writer sorts and filters them by.
location string Where the note's text is: files/<location>.json.
textAssociated string | null The passage the note was attached to, kept so the note survives the text moving.
hash ? string SHA-256 of the note's content file, used by sync.
lastModified ? number When the note last changed, epoch milliseconds.
src/app/domain/project/models/notes.model.ts
Occupation #
Also has every field of BaseWorldbuildingElement .
A trade or role somebody in the world can hold.
type 'occupation' Always occupation. The tag that says which interface applies to this element.
category ? 'combat' | 'crafting' | 'scholarly' | 'service' | 'leadership' | 'artistic' | 'spiritual' | 'other' What sort of work it is.
requiredSkills ? string[] What it takes to do the job, as text.
commonTraits ? string[] What the people who do it tend to be like, as text.
socialStatus ? 'low' | 'middle' | 'high' | 'varies' Where it puts a person socially.
averageIncome ? string What it pays, as text.
workingConditions ? string What the work is like, as one block of text.
trainingRequired ? string What training it needs, as one block of text.
advancementPath ? string[] Where the job leads, as text.
relatedOccupations ? string[] Nearby trades, as text.
typicalEmployers ? string[] Who tends to employ them, as text.
commonSpecies ? string[] Which species tend to do it, as text.
src/app/domain/project/models/worldbuilding/occupation.interface.ts
PdfAsset #
A PDF document attached to the project (research, contracts, style guides, proofs…),
parallel to / . The bytes live on disk under the
project's pdfs/ folder (written via IOIntegrationInterface.savePdfToProject); this
object is the metadata that travels inside Project.pdfAssets.
id string Stable identifier, a UUID.
title string The name shown to the writer.
fileName string The file's name inside pdfs/, extension included.
relativePath string Path under the project, normally pdfs/<fileName>.
size number File size in bytes.
mimeType string MIME type of the stored bytes, in practice application/pdf.
pageCount ? number Page count, when known. Filled in lazily the first time the PDF is rendered.
createdAt Date When the PDF was attached. Typed Date, so it serialises as an ISO-8601 string.
hash ? string Hash of the bytes, used to spot a real change.
treePath ? string Position in the file tree, the parent's path plus the name, mirroring
AudioAsset.treePath. Undefined means the PDF shows up in the fixed PDFs folder.
src/app/domain/project/models/pdf-asset.model.ts
PlotGrid #
A plot grid: the story laid out as a table, one column per strand.
id string Stable identifier, a UUID.
name string What the writer called this grid.
columns PlotGridColumn [] Its columns, in the order they are shown.
rowCount number How many rows the grid has. Cells beyond this are not shown.
cells PlotGridCell [] The cells that hold something. Empty ones are simply absent.
createdAt number When the grid was created, epoch milliseconds.
lastModified number When the grid last changed, epoch milliseconds.
rowNotes ? PlotGridRowNote [] Banners across whole rows. Absent in grids made before they existed.
src/app/domain/project/models/plotgrid.interface.ts
PlotGridCell #
One cell of a plot grid. Addressed by column id and row number rather than by a pair of indices, so reordering the columns does not touch the cells. Empty cells are simply absent from the list.
id string Stable identifier of the cell.
type PlotGridCellType What the cell holds: nothing yet, a chapter, or a note.
columnId string Id of the the cell sits in.
rowIndex number Which row the cell sits in, zero based.
referenceId ? string Id of the chapter the cell stands for, when its type is chapter.
content ? string The cell's text.
color ? string Colour of the cell, as CSS.
src/app/domain/project/models/plotgrid.interface.ts
PlotGridCellType #
'unassigned' | 'chapter' | 'note' src/app/domain/project/models/plotgrid.interface.ts
PlotGridColumn #
A column of a plot grid: a strand of the story, or whatever the writer decides.
id string Stable identifier, and what a cell's columnId points at.
name string What the writer called the column.
position number Where the column sits, left to right, ascending.
src/app/domain/project/models/plotgrid.interface.ts
PlotGridRowNote #
A banner across a whole row of a plot grid. It marks something that belongs to the plot rather than to one cell: the start of an arc, an act break, an event that touches every strand at once.
id string Stable identifier of the banner.
rowIndex number Which row it sits ABOVE, zero based. A value equal to the grid's rowCount puts it at
the very bottom, under the last row.
content string What the banner says.
color ? string Colour of the banner, as CSS.
height ? number How tall the banner is, in pixels. Absent means the default of 34.
src/app/domain/project/models/plotgrid.interface.ts
ProjectDoc #
Also has every field of ProjectFileBase .
A document: everything the writer keeps that is not the manuscript itself.
Outlines, research, notes to self. Same shape as a and stored the same
way, in files/<location>.json. What separates the two is the array it is listed in, so a
reader cannot tell a chapter from a research note by looking at the entry alone.
The fields it redeclares are inherited from and repeated here.
id string Stable identifier, a UUID.
name string The name shown in the tree.
title string Display title. Usually the same as name.
location string Where the text is: files/<location>.json.
treePath string Position in the sidebar tree, a slash separated path of names.
createdAt number When the document was created, epoch milliseconds.
lastModified number When the document last changed, epoch milliseconds.
snapshots ? FileSnapshot [] Saved versions. Optional here and temporary in practice, since a document picks them up mainly when live sync has to keep the server's copy of a conflict around.
src/app/domain/project/models/project-doc.interface.ts
ProjectFile #
Also has every field of ProjectFileBase .
A manuscript entry: a chapter, or a piece of one. This is the half of the project that becomes the book. Everything the writer keeps alongside it, research, outlines, character sheets, is a instead. The distinction is not in the shape, it is which array of the manifest the entry sits in.
summary ? string Short summary of the chapter, written by the writer.
synopsis ? string Longer synopsis, kept separately from summary and shown in the outline views.
order ? number | null Place in the reading order of the manuscript, ascending. Null or undefined sorts last.
Separate from position, which orders the tree: the two can disagree on purpose.
snapshots FileSnapshot [] Saved versions of this chapter. Each one keeps its own text under files/.
charactersManuallyExcluded ? string[] Character ids the writer took off the detected list for this chapter.
charactersManuallyIncluded ? string[] Character ids the writer added to the detected list for this chapter.
charactersIncluded ? string[] The character ids that end up counted as appearing here, after both manual lists.
status ? string | null Editorial status, matching one of the project's configured statuses.
bookRole ? string | null Role in the exported book (a BookRole). Null or undefined means an ordinary chapter.
readOrder ? boolean False takes the chapter out of the reading order without deleting it.
scenes ? Scene [] Scenes marked inside the chapter's text, mirroring its scene nodes.
src/app/domain/project/models/project-file.interface.ts
ProjectFileBase #
What every entry in the tree has, whether it is a chapter or a document.
The entry is metadata only. Its text lives in a separate file addressed by location,
which is the single most important thing to know when reading a project from outside:
nothing here contains a word the writer typed.
id string Stable identifier, a UUID. What every other part of the project refers to it by.
name string The name shown in the tree, and the one the writer edits when they rename it.
title string Display title. Usually the same as name.
location string Where the text is: files/<location>.json, holding ProseMirror JSON. In practice this
holds the same value as id, but it is the field to follow rather than the id, since
nothing guarantees they stay equal.
treePath string Position in the sidebar tree as a slash separated path of names, built from the parent's
path plus this entry's name. A node at the root is just its own name. The fixed panels
prefix theirs with *characters* or *worldbuilding*.
createdAt number When the entry was created, epoch milliseconds.
lastModified number When the entry or its text last changed, epoch milliseconds.
statusHistory ? StatusHistory [] The trail of editorial statuses this entry has been through, newest last.
links ? string[] Ids of other entries linked from this one.
hash string SHA-256 of the content file, used by sync to tell a real change from a rewrite.
color ? string Colour chosen for the tree row, as CSS. Undefined means the theme decides.
customIcon ? string Icon chosen for the tree row. Undefined means the default for the entry type.
wordNumber ? number Cached word count of the content file. A cache, so it can lag behind the text.
keywords ? string[] Keywords the writer attached to the entry.
customMetadata ? Record<string, string> Metadata fields the writer defined and filled in themselves.
systemMetadata ? Record<string, string> Metadata the app writes about the entry, session and writing metrics among it. Never
editable by the writer, unlike customMetadata. See system-metadata.util.ts.
writingMode ? WritingMode Which editor this entry opens in: prose, screenplay or theatre.
position ? number Sort order among its siblings in the tree.
src/app/domain/project/models/project-file.base.interface.ts
ProjectFolder #
A folder in the sidebar tree.
It holds nothing. What is inside it is worked out from the treePath of the entries,
not from a list of children here, so moving a folder means rewriting the paths of
everything under it.
id string Stable identifier, a UUID.
title string The folder's name, as shown in the tree.
treePath string Its own path in the tree, which every entry inside it is prefixed with.
color ? string Colour chosen for the tree row, as CSS.
customIcon ? string Icon chosen for the tree row.
lastModified ? number When the folder last changed, epoch milliseconds.
position ? number Sort order among its siblings.
src/app/domain/project/models/project-folder.interface.ts
Relationship #
A tie from one character to another.
Stored on one side only. When isBidirectional is set, the other character's side of it
is worked out from inverseType rather than written down again, so a reader walking the
cast will see each pair once and has to mirror it themselves.
characterId string Id of the on the other end.
type string What this character is to them, in the writer's own words: "brother", "rival".
description ? string The detail behind the tie.
isBidirectional ? boolean Whether the tie also holds in the other direction.
inverseType ? string What the other character is to this one, when the tie runs both ways.
src/app/domain/project/models/character.model.ts
RelationshipConfig #
What a relationship field is allowed to point at.
allowedTypes string[] Which element types can be picked, by their type tag.
multiple ? boolean Whether more than one can be picked.
src/app/domain/project/models/worldbuilding/custom-field.interface.ts
Religion #
Also has every field of BaseWorldbuildingElement .
A faith: what is believed, who is worshipped and what is done about it.
type 'religion' Always religion. The tag that says which interface applies to this element.
deityIds ? string[] Ids of the elements it worships.
beliefs ? string[] What it holds to be true, as text.
practices ? string[] What its followers do, as text.
holyTexts ? string[] Its scriptures, as text.
clergy ? { rank: string; responsibilities?: string[]; requirements?: string[]; }[] Its ranks of clergy, written inline rather than as elements of their own.
temples ? string[] Ids of the elements that serve as its temples.
holyDays ? { name: string; date?: string; significance?: string; }[] The dates in its calendar that matter.
followersCount ? number How many follow it.
influence ? 'local' | 'regional' | 'widespread' | 'dominant' How far its reach goes.
relationshipWithOtherReligions ? { religionId: string; relationship: 'allied' | 'neutral' | 'competitive' | 'hostile'; description?: string; }[] Where it stands with the other faiths in the project.
src/app/domain/project/models/worldbuilding/religion.interface.ts
Scene #
A scene marked inside a chapter.
Two halves that have to agree. The text carries a scene node whose sceneId attribute
points here, and this entry carries everything about the scene that is not text. Reading a
project from outside, the node tells you where a scene starts and ends and this tells you
what it is.
id string Stable identifier, matching the sceneId attribute of the node in the text.
name ? string What the writer called the scene. Absent means it is shown by its position.
povCharacterId string | null The character whose point of view the scene is written from, or null for none.
charactersInScene ? string[] | null Ids of the characters who appear in the scene.
objectsInScene ? string[] | null Ids of the worldbuilding elements that appear in the scene.
type SceneType What kind of scene it is, which is also what colours it in the editor.
locationId string | null The worldbuilding location the scene happens in, or null for none.
createdAt number When the scene was created, epoch milliseconds.
updatedAt number When the scene last changed, epoch milliseconds.
startOffset ? number Cached start position of the scene node in the document. The node is the truth.
endOffset ? number Cached end position of the scene node in the document. The node is the truth.
notes ? string The writer's notes about the scene, as plain text.
src/app/domain/project/models/scene.interface.ts
SceneType #
MAIN_CONTINUITY FLASHBACK DREAM VISION MEMORY PROLOGUE EPILOGUE INTERLUDE MONTAGE
src/app/domain/project/models/scene.interface.ts
Species #
Also has every field of BaseWorldbuildingElement .
A kind of people or being that the world is populated with.
type 'species' Always species. The tag that says which interface applies to this element.
physicalTraits ? string[] How they look, as text.
abilities ? string[] What they can do, as text.
lifespan ? string How long they live, as text.
homeworld ? string Where they come from, as text.
culture ? string Their culture, as one block of text.
language ? string[] Ids of the elements they speak.
dietType ? 'omnivore' | 'carnivore' | 'herbivore' | 'other' What they eat.
averageHeight ? string Typical height, as text, since worlds do not agree on units.
socialStructure ? string How they organise themselves, as one block of text.
commonOccupations ? string[] Ids of the elements common among them.
alliedSpecies ? string[] Ids of the species they are allied with.
neutralSpecies ? string[] Ids of the species they are neutral towards.
hostileSpecies ? string[] Ids of the species they are hostile to.
src/app/domain/project/models/worldbuilding/species.interface.ts
StatusHistory #
One step in an entry's editorial life: what it became, and when.
status string The status it moved to, matching one of the project's configured statuses.
dateTimestamp number When it moved, epoch milliseconds.
src/app/domain/project/models/status-history.interface.ts
Technology #
Also has every field of BaseWorldbuildingElement .
A piece of technology, from a plough to a jump drive.
type 'technology' Always technology. The tag that says which interface applies to this element.
techLevel ? 'primitive' | 'medieval' | 'renaissance' | 'industrial' | 'modern' | 'futuristic' | 'mixed' Roughly what era it belongs to.
category ? 'transportation' | 'communication' | 'warfare' | 'medicine' | 'agriculture' | 'energy' | 'other' What it is for.
functionality ? string What it does, as one block of text.
creators ? string[] Who made it, as text.
users ? string[] Who uses it, as text.
rarity ? 'common' | 'uncommon' | 'rare' | 'legendary' | 'unique' How rare it is.
requirements ? string[] What it needs to work, as text.
sideEffects ? string[] What it does that nobody intended, as text.
relatedTechnologies ? string[] Nearby technologies, as text.
src/app/domain/project/models/worldbuilding/technology.interface.ts
TimelineAxisMetric #
How a timeline labels its axis. Labels only: none of this is a real date.
unit ? string What goes before the number: "Year", "Day", "Chapter". Empty means just the number.
start number The value of the first column.
step number How much each column adds.
src/app/domain/project/models/timeline.interface.ts
TimelineBlockData #
One bar on a timeline lane, standing for a chapter or for an event.
id string Stable identifier of the block.
kind ? 'document' | 'event' What the block stands for. Absent means document, which is what every block created
before this field existed is, so nothing had to be migrated.
fileId ? string Id of the manuscript entry. Required when kind is document.
sceneId ? string Id of the inside that entry, when the block is one scene rather than all of it.
eventId ? string Id of a worldbuilding element of type event. Required when kind is event. Half the
structure of a novel is things that happen and are written in no chapter. The event
already exists in the project, with its date and duration, and this is what lets it be
placed on the line.
childTimelineId ? string Id of a timeline that drills into this block.
startCol number Which column the block starts at.
spanCols number How many columns it covers.
color ? string Colour of the block, as CSS.
characterId ? string Id of the project character tied to this block.
worldbuildingId ? string Id of the project worldbuilding element tied to this block.
src/app/domain/project/models/timeline.interface.ts
TimelineData #
A timeline: the story laid out along an axis, in lanes.
The axis is not made of dates. A column is a unit of pace the writer chooses, and
axisMetric only says how to label it, so nothing here can be read as a calendar.
id string Stable identifier, a UUID.
name string What the writer called this timeline.
parentId ? string Id of the timeline this one hangs off, when a block on that one drills into this.
lanes TimelineLaneData [] The lanes, top to bottom.
milestones ? TimelineMilestoneData [] Milestones of the whole story. A first turning point or a climax does not belong to one strand, so its line crosses every lane. The per-lane still exist for marking something inside one lane, which is now the exception rather than the rule.
segments ? TimelineSegmentData [] Named stretches of the axis: acts, parts, seasons, whatever the writer decides. They turn a bare grid into something readable without forcing a column to be a date.
axisMetric ? TimelineAxisMetric How the axis is labelled. Absent means columns numbered from 1, which is what timelines had before this existed. These are not real dates: the writer picks the metric ("year 8123 to 9123", "day 1 to 40", "session 1 to 12"), which is why a starting value and a step are all it takes.
unassignedNotes TimelineNoteData [] Notes that have not been put on a lane yet.
customWidth ? number Column width in pixels, when the writer set one.
createdAt number When the timeline was created, epoch milliseconds.
lastModified number When the timeline last changed, epoch milliseconds.
src/app/domain/project/models/timeline.interface.ts
TimelineLaneData #
One horizontal strand of a timeline.
id string Stable identifier of the lane.
name string What the writer called the lane.
collapsed boolean Whether the lane is folded shut.
customHeight ? number Lane height in pixels, when the writer set one.
blocks TimelineBlockData [] The blocks on this lane.
notes TimelineNoteData [] Notes pinned to this lane.
milestones TimelineMilestoneData [] Milestones that belong to this lane alone, rather than to the whole story.
src/app/domain/project/models/timeline.interface.ts
TimelineMilestoneData #
A marked moment on a timeline, drawn as a line down the lanes it applies to.
id string Stable identifier of the milestone.
text string What the milestone says.
color string Colour of the line, as CSS.
position number Which column it sits at.
src/app/domain/project/models/timeline.interface.ts
TimelineNoteData #
A note pinned to a timeline, either on a lane or waiting to be put on one.
id string Stable identifier of the note.
text string What the note says.
color string Colour of the note, as CSS.
position number Which column it sits at.
src/app/domain/project/models/timeline.interface.ts
TimelineSegmentData #
A named stretch of a timeline's axis: an act, a part, a season.
id string Stable identifier of the segment.
name string What the writer called it.
startCol number Which column it starts at.
spanCols number How many columns it covers.
color ? string Colour of the segment, as CSS.
src/app/domain/project/models/timeline.interface.ts
WordCountLog #
One day of writing, as the statistics and the goals read it.
dayTimestamp number The day this row is for, epoch milliseconds at the start of that day.
count number Words written that day.
objective number The daily target in force that day, kept so past days are not rescored later.
src/app/domain/project/models/WordCountLog.ts
WorldbuildingElement #
| Species | Faction | Occupation | Location | Religion | MagicSystem | Technology | Language | WorldbuildingEvent | Creature | Item | Group | CharacterInterface | Deity | CustomWorldbuildingElement src/app/domain/project/models/worldbuilding/worldbuilding-event.interface.ts
WorldbuildingEvent #
Also has every field of BaseWorldbuildingElement .
Something that happened in the world's history.
type 'event' Always event. The tag that says which interface applies to this element.
eventType ? 'war' | 'disaster' | 'discovery' | 'political' | 'religious' | 'social' | 'personal' | 'other' What kind of event it was.
date ? string When it happened, in the world's own calendar, so free text rather than a date.
duration ? string How long it lasted, as text.
locationIds ? string[] Ids of the elements where it happened.
participantIds ? string[] Ids of the elements that took part in it.
causes ? string[] What led to it, as text.
consequences ? string[] What came of it, as text.
keyFigures ? string[] Who mattered in it, as text rather than as ids.
relatedEvents ? string[] Other events it connects to, as text rather than as ids.
historicalSignificance ? string Why it matters to the world, as one block of text.
publicKnowledge ? 'widely-known' | 'limited-knowledge' | 'secret' | 'forgotten' How much of the world knows about it, which is a plot fact rather than a historical one.
src/app/domain/project/models/worldbuilding/worldbuilding-event.interface.ts
WritingGoal #
A writing target the writer set for themselves.
It lives inside Project, like wordCountLog, so it syncs between devices without a
backend of its own. Progress is NOT stored: it is worked out from the logs every time, in
GoalProgressService, so nothing here can disagree with the record of what was written.
id string Stable identifier, a UUID.
type WritingGoalType What is being counted: words, chapters, characters, streak days and so on.
cadence WritingGoalCadence Over what period it is counted.
target number How many of type count as meeting the goal in one cadence.
title ? string The writer's own title. When absent the interface builds one from the other fields.
createdAt number When the goal was created, epoch milliseconds.
lastModified ? number The sync clock, updated on every change. Goals written before this existed fall back to
createdAt. Incremental pull spots changes by timestamp, so a goal without one is
invisible to it.
archivedAt ? number | null Soft delete. Archived goals are kept so a sync merge does not resurrect them.
src/app/domain/project/models/writing-goal.interface.ts
WritingGoalCadence #
'daily' | 'weekly' | 'monthly' | 'total' src/app/domain/project/models/writing-goal.interface.ts
WritingGoalType #
| 'words' | 'chapters' | 'chaptersCreated' | 'characters' | 'worldbuilding' | 'streak' | 'minutes' src/app/domain/project/models/writing-goal.interface.ts
WritingMinutesLog #
One day of time spent writing, fed by the timer rather than by counting words.
dayTimestamp number The day this row is for, epoch milliseconds at the start of that day.
minutes number Minutes written that day.
src/app/domain/project/models/WritingMinutesLog.ts
WritingMode #
Which editor an entry opens in, and which nodes its text is allowed to use.
PROSE SCREENPLAY THEATRE
src/app/domain/project/models/project-file.interface.ts