1 Commits
Author SHA1 Message Date
sneak c997a5c7c2 README.md rewritten sentence by sentence (closes #219)
check / check (push) Canceled after 0s
The old text served as the list of what a reader needs covered. The new
text leads with what quak is, what it is for and how to use it. Every
command, option, exit code and file layout follows in reference sections,
then the library reference, then design, entrypoints and development.
Every statement was checked against the code on next; where the old text
disagreed, the pull request lists it. No sentence runs past about 30
words, every table is now a list, and no issue links or project history
remain in text meant for users. Two code comments that named README
sections now name the new ones; a third no longer cites the README.

Model: fable-5-1
2026-10-26 14:54:59 +00:00
2 changed files with 24 additions and 29 deletions
+17 -19
View File
@@ -692,10 +692,10 @@ Update times are in microseconds, as Ente records them.
The JSON also holds the machine-learning data Ente computed for the photo, as
`mlData`. Ente's apps detect faces in each photo and compute a CLIP embedding
for it, a list of 512 numbers that describes what the photo shows. `mlData`
holds everything but the `clip` block, which holds that embedding. In its place
the JSON holds `keywords`, derived from the embedding as described under
"Keywords". A file with no machine-learning data has neither field. A file whose
data holds no usable embedding has no `keywords`.
holds everything but that embedding. In its place the JSON holds `keywords`,
derived from the embedding as described under "Keywords". A file with no
machine-learning data has neither field. A file whose data holds no usable
embedding has no `keywords`.
The backup waits for the library's fetch of machine-learning data to finish
before it writes the JSON files. When a file's data cannot be fetched,
@@ -748,11 +748,11 @@ derives a file's keywords the way the app sorts it. The categories are:
Each category has a query, and a text embedding of that query from Ente's CLIP
text model. A file's score for a category is the cosine similarity of the file's
embedding and the category's. That is a number from -1 to 1; the more alike the
two embeddings are, the higher it is. The file falls in the category when its
score reaches the category's minimum score. The keywords are the titles of the
categories the file falls in, highest score first. A video never falls in a
category marked "no videos", as in the app.
embedding and the category's: a number from -1 to 1, higher the more alike the
two embeddings are. The file falls in the category when its score reaches the
category's minimum score. The keywords are the titles of the categories the file
falls in, highest score first. A video never falls in a category marked "no
videos", as in the app.
#### Collection directories
@@ -775,10 +775,9 @@ ignoring case, each gets its ID added: two albums named `Trip` become
`Trip (10)/` and `Trip (11)/`. Two files in one collection whose titles match,
ignoring case, get their IDs added before the extension: `IMG_0001 (12345).JPG`
and `IMG_0001 (12346).JPG`. A collection named like another collection's JSON
file, such as `Trip.json` beside `Trip`, also gets its ID added. A file name
longer than 255 bytes, the limit on most file systems, gets its ID added too. So
does a collection name longer than 250 bytes, which leaves room for `.json`.
Either name is then cut short before the ID, just far enough to fit. IDs never
file, such as `Trip.json` beside `Trip`, also gets its ID added. A name too long
for a file name, which most file systems limit to 255 bytes, gets its ID added
too. It is then cut short before the ID, just far enough to fit. IDs never
change, so a name stays the same from run to run until such a clash appears or
goes away.
@@ -835,8 +834,7 @@ Each entry holds:
- `fileID` and `title`;
- `classification`: the kind of failure;
- `attempts`: how many runs in a row have failed the file;
- `lastTriedAt`: when the run that last tried it finished its refresh, as a Unix
time in milliseconds;
- `lastTriedAt`: when it was last tried, as a Unix time in milliseconds;
- `error`: the error, as quak printed it.
The kinds are:
@@ -1079,10 +1077,10 @@ cached, so the next fetch asks for it again. The reasons are kept in memory
only.
`lib.close()` stops the background timer. It can be called more than once. A
refresh in flight is left to finish, with its write to the cache. `close()`
returns a promise. It resolves once that refresh, the machine-learning fetch and
the background downloads already running have all finished. The cache directory
can then be removed. After `close()`, `fresh()`, `freshCollections()`,
refresh in flight is left to finish, with its write to the cache. The promise
`close()` returns resolves once that refresh, the machine-learning fetch and the
background downloads already running have all finished. The cache directory can
then be removed. After `close()`, `fresh()`, `freshCollections()`,
`freshFiles()` and `lib.backup()` reject with `the library is closed`.
### Default reads and fresh reads
+7 -10
View File
@@ -1,18 +1,15 @@
// The CLI's log level, and the one function the commands write stderr lines
// through.
//
// Every line quak logs goes to stderr, at one of six levels, from the
// quietest: fatal, error, warning, info, debug, trace. A run prints the lines
// at its own level and at every quieter one. Its level is info unless `-v` or
// `-q` asks for another (see "What quak prints" in the README). A command that
// runs and exits non-zero logs a fatal line saying why, so even `-q`, which
// prints only fatal lines, never leaves such an exit unexplained. An error
// Every line quak prints on stderr is a log line at one of six levels, from
// the quietest: fatal, error, warning, info, debug, trace. A run prints the
// lines at its own level and at every quieter one. Its level is info unless
// `-v` or `-q` asks for another (see "What quak prints" in the README). Every
// command that exits non-zero logs a fatal line saying why, so even `-q`, which
// prints only fatal lines, never leaves a non-zero exit unexplained. An error
// line reports something that failed, such as a file or an album, and a
// warning something that did not fail but needs the user's attention. stdout
// carries a command's output and the prompts of `login`, and is not a log.
// Two things on stderr are not log lines: the `error:` message for a
// command line that quak cannot parse, and the usage printed when no command
// is given.
// carries only a command's output and is not a log.
//
// The library itself writes no lines: its layers report through callbacks, and
// the CLI logs what they report. `logRequests` gives the API client options