Before copying any files, Kopia Desk writes a journal toDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Pachanga12/Kopia_Desk_Beta_1/llms.txt
Use this file to discover all available pages before exploring further.
.kopia-data/journal/ on the destination drive. The journal is an append-only JSONL file: its first line is a JSON header listing every file that is planned to be copied; each subsequent line records one file path the moment it is successfully written. On a clean backup finish the journal file is deleted. If the app crashes, the OS shuts down, or the drive is disconnected mid-copy, the journal persists — and on the next run peekJournals detects it, warns the user, and checkJournals removes any files that were only partially written before handing control back to backup:copy-files.
Journal file format
Each journal is a.jsonl file named backup_<ISO-timestamp>.jsonl inside the journal directory. The first line is always the header object; every line that follows records one completed relative destination path:
img1.jpg was fully written and recorded as done; img2.jpg appears in planned but has no corresponding done-line, so it is treated as a partial file to be cleaned up.
Journal lifecycle
Start
startJournal(journalDirPath, tasks) creates the journal directory and
writes the header line with startedAt and the full planned array. The
returned file path is kept in memory for the duration of the copy run.Append per file
After each successful
fs.promises.copyFile, appendJournalDone(journalPath, relativeDest)
appends one JSON string line to the journal. Files not yet recorded are
implicitly pending.Clean finish
When
backup:copy-files completes with zero errors, finishJournal(journalPath)
deletes the journal file. No journal → no interrupted backup on the next run.Crash / disconnect
If the process is killed or the drive ejected, the journal file stays on
disk. The done-lines written so far reflect exactly which files were fully
copied.
Peek (read-only check)
Next time the user selects the same destination,
peekJournals(journalDirPath)
is called via the journal:peek IPC channel. It counts pending files and
returns the interrupted timestamp so the UI can display a warning — without
deleting or modifying anything.startJournal(journalDirPath, tasks)
Creates the journal directory if it does not exist, then writes the JSONL header line containing the planned file list.
Parameters
Absolute path to the journal directory, typically
<destRoot>/.kopia-data/journal/. Created with { recursive: true } if
absent.Array of copy tasks. Each task’s
relativeDest is written into the
planned array of the journal header.Return value
The absolute path to the newly created
.jsonl file, or null if tasks
is empty (no journal is written for a no-op run).appendJournalDone(journalPath, relativeDest)
Appends a single JSON string line to the journal file immediately after a file is copied. Persisting completions one-by-one (rather than rewriting the whole journal periodically) ensures that only files not yet recorded are treated as partial if an interruption occurs.
Parameters
The file path returned by
startJournal.The relative destination path of the file that was just successfully written
(e.g.
'KopiaDesk_Backup/Fotos/img1.jpg').Return value
Returns nothing. Any
fs.appendFileSync error is silently swallowed — the
journal is best-effort and its failure must never abort the backup itself.finishJournal(journalPath)
Deletes the journal file on a clean backup completion. No journal file means no interrupted backup for the next peekJournals call to detect.
Parameters
The file path returned by
startJournal. If the file no longer exists (e.g.
manually deleted), the error is silently ignored.Return value
Returns nothing.
peekJournals(journalDirPath)
Reads all .jsonl (and legacy .json) files in the journal directory and reports how many files are pending — without deleting or modifying anything. Used by the journal:peek IPC channel to build the warning shown to the user before any cleanup is performed.
Parameters
Absolute path to the journal directory. If the directory does not exist,
returns zeroed values immediately without throwing.
Return value
Number of journal files found (
.jsonl + .json).Total number of files across all journals that appear in
planned but have
no corresponding done-line.ISO 8601 timestamp from the
startedAt field of the most recently processed
journal header, or null if no journals were found.checkJournals(journalDirPath, destRoot)
Reads all journal files, deletes every pending partial file from the destination root using safePath before each fs.unlinkSync, and then deletes the journal files themselves. Called only after the user confirms the “Continuar y limpiar” prompt.
Parameters
Absolute path to the journal directory. If the directory does not exist,
returns zeroed values without throwing.
The backup root directory (e.g.
D:\KopiaDesk_Backup). Every pending
relativeDest is resolved with safePath(destRoot, relativeDest) before
deletion — invalid or escaping paths are silently skipped.Return value
Number of journal files processed.
Number of partial files successfully deleted from
destRoot.ISO 8601 timestamp from the most recently processed journal’s
startedAt
field, or null if no journals were found.peekJournals and checkJournals accept the same directory path but have
very different effects. peekJournals is read-only — it never deletes
files or journals, and it is safe to call at any time (including at app
startup). checkJournals performs the actual cleanup and should only be
called after the user has explicitly confirmed the recovery prompt in the UI.
Calling checkJournals without user confirmation would silently discard
files the user might still want to inspect.