annals#

annals: an in-tray for AI agents. Publish documents and media to a private page; get a link.

Agents call annals.tools.publish() (or annals publish file.md from a shell) and hand the printed URL to their human, who opens it on a phone. The documents are plain files in a directory, local or on another machine over ssh; annals.api.mk_app() serves that directory as a private page with search, sort, groups and a recycle bin.

Functions

configure(*[, target, base_url])

Write the publisher config (where to publish, what link to print) and show it.

group(title, doc_ids, *[, target, base_url])

Make a group (one URL for a set of documents) from existing document ids.

groups(*[, target, base_url])

List groups, newest first.

load_settings(*[, target, base_url, config_path])

Resolve settings: arguments, then env, then the config file, then local defaults.

ls([q, trash, limit, target, base_url])

List documents (newest first), optionally filtered by words or showing the bin.

parse_target(spec)

host:/path becomes an SshTarget; anything else a LocalTarget.

publish(paths, *[, title, tags, group, ...])

Publish one document and print its link; several paths become several documents.

restore(doc_ids, *[, target])

Bring documents back from the recycle bin.

show(doc_id, *[, target, base_url])

A document's metadata and link.

trash(doc_ids, *[, target])

Move documents to the recycle bin (restorable).

Classes

DocStore(target)

Publish, list, read, trash, restore and group documents on a Target.

LocalTarget(root)

A directory on this machine.

Settings(target, base_url[, configured])

Where to publish and what link to print.

SshTarget(host, root)

host:path on another machine, via the system ssh and rsync in batch mode.

class annals.DocStore(target)[source]#

Bases: object

Publish, list, read, trash, restore and group documents on a Target.

add_to_group(gid, doc_ids)[source]#

Append ids to an existing group, keeping order and skipping duplicates.

Return type:

dict

group(gid)[source]#

One group, by id.

Return type:

dict

list(*, trash=False)[source]#

Every document’s meta, newest first (ids sort by time; created breaks ties).

Return type:

list[dict]

list_groups()[source]#

Every group, newest first.

Return type:

list[dict]

make_group(title, doc_ids, *, gid=None)[source]#

Create (or overwrite) a group: a titled, ordered list of document ids.

Return type:

dict

meta(doc_id)[source]#

One document’s meta; in_trash says which side of the bin it is on.

Return type:

dict

publish(*sources, title=None, tags=(), source=None, text=None, filename='document.md', exclude=('.*', '__pycache__', '*.pyc', '*.pyo'))[source]#

Publish files (or a directory, or text) as ONE document; return its meta.

One markdown or html file is the common case. A directory is published whole, with index.html (or the first renderable file) as the page shown. text publishes a string as filename instead of reading sources. exclude lists glob patterns skipped inside a directory (hidden files and caches by default; () keeps all).

Return type:

dict

purge(doc_id)[source]#

Delete a document that is in the bin. Refuses one that is not.

Return type:

None

read_text(doc_id, rel=None)[source]#

A document’s main file (or one of its files) as text.

Return type:

str

restore(doc_id)[source]#

Move a document out of the bin (idempotent).

Return type:

dict

search(query, *, trash=False)[source]#

Case-insensitive match of every query word against title, tags, excerpt, source.

Return type:

list[dict]

trash(doc_id)[source]#

Move a document into the bin (idempotent).

Return type:

dict

class annals.LocalTarget(root)[source]#

Bases: object

A directory on this machine.

local_path(rel)[source]#

rel under the root, resolved; None if it escapes the root (a symlink).

Return type:

Path | None

class annals.Settings(target, base_url, configured=True)[source]#

Bases: object

Where to publish and what link to print. See the module docstring for precedence.

as_dict()[source]#

Plain dict, for the CLI and MCP surfaces.

Return type:

dict

configured: bool = True#

publishing then lands in the local data dir and the link points at a local server, which is rarely meant

Type:

False when nothing (argument, env, config file) named a target

class annals.SshTarget(host, root)[source]#

Bases: object

host:path on another machine, via the system ssh and rsync in batch mode.

annals.configure(*, target=None, base_url=None)[source]#

Write the publisher config (where to publish, what link to print) and show it.

Return type:

dict

Example

annals configure --target tw:/root/.local/share/annals --base-url https://apps.example.com/annals. With no arguments, shows the resolved settings without writing.

annals.group(title, doc_ids, *, target=None, base_url=None)[source]#

Make a group (one URL for a set of documents) from existing document ids.

Return type:

dict

annals.groups(*, target=None, base_url=None)[source]#

List groups, newest first.

Return type:

dict

annals.load_settings(*, target=None, base_url=None, config_path=None)[source]#

Resolve settings: arguments, then env, then the config file, then local defaults.

Return type:

Settings

annals.ls(q='', *, trash=False, limit=50, target=None, base_url=None)[source]#

List documents (newest first), optionally filtered by words or showing the bin.

Return type:

dict

annals.parse_target(spec)[source]#

host:/path becomes an SshTarget; anything else a LocalTarget.

Return type:

Target

annals.publish(paths, *, title=None, tags='', group=None, add_to=None, session=None, all_files=False, target=None, base_url=None)[source]#

Publish one document and print its link; several paths become several documents.

paths: files of any kind (markdown, html, images, video, audio, pdf, text), a directory (one document: an index.html or single page with its assets, else a gallery of everything in it), or - for stdin (markdown). tags is comma separated. group names a group to create from the published documents; the reply then carries group_url too. add_to appends them to an existing group instead (its id, as printed in a group link), so a second batch lands under the link the owner already has. session records who published (the source shown on the page). A directory skips hidden files and caches (.*, __pycache__, *.pyc) unless all_files.

Return type:

dict

annals.restore(doc_ids, *, target=None)[source]#

Bring documents back from the recycle bin.

Return type:

dict

annals.show(doc_id, *, target=None, base_url=None)[source]#

A document’s metadata and link.

Return type:

dict

annals.trash(doc_ids, *, target=None)[source]#

Move documents to the recycle bin (restorable).

Return type:

dict

Modules

auth

The auth seam: who may read the annals.

config

Settings: where documents are published and what link to print.

mcp

MCP surface: the same operations as the CLI, from annals.tools, via py2mcp.

store

The document store: a flat set of documents, tags, groups and a recycle bin, as plain files.

target

The transport seam: a document tree lands in a directory, here or on another machine.

tools

The operations, as plain functions: JSON-able arguments in, JSON-able dicts out.