taskrat
v0.2.0
Published
File-based task manager with a background scheduler, CLI, and TUI.
Downloads
309
Readme
taskrat
A file-based personal task manager: a background scheduler, a CLI, and a read-only TUI,
all reading and writing plain markdown-with-frontmatter task files. One directory is the
database; one .md file is one task.
Extracted from ratnest, which runs the scheduler as a supervised child process (taskrat serve) and receives its notifications over HTTP. taskrat has no dependency on ratnest — the coupling is one-way, across a process boundary.
Layout
src/
schema.mts task shape, validation, dates, recurrence (TypeBox)
io.mts markdown+frontmatter parse/serialize, filesystem store
scheduler.mts TaskManager — polls the store and POSTs due/deadline notifications
notification.mts the notification wire-format taskrat POSTs to its host
log-client.mts structural logging interface the host supplies
index.mts public library API
cli/ taskrat — the CLI (stricli)
tui/ taskrat-tui — the read-only browser (opentui, needs Bun)Use
npm install
npm test # tsc --noEmit && eslint . && vitest run
npm run build # compile bin/taskrat and bin/taskrat-tui (needs Bun)The library (scheduler, schema, storage) runs under plain Node. The taskrat and
taskrat-tui bins ship as .mts source with a Bun shebang and require Bun (the TUI
also needs Bun's native OpenTUI bindings); compile them to standalone binaries with
npm run build. The task store is tasks/ in the current working directory, or
$TASKRAT_DIR if set.
taskrat add --title "Call vet" --due 2026-07-15T10:00 --priority 2
taskrat list
taskrat-tui # interactive browserAs a daemon
taskrat serve --notify http://127.0.0.1:8080/notification [--interval 60]Runs the scheduler in the foreground: polls the task store every --interval seconds and
POSTs a JSON notification to --notify for each task whose due/remind or deadline time was
crossed since the last poll. Recurring tasks are advanced on disk. Stops cleanly on
SIGINT/SIGTERM. Delivery is fire-and-forget — a failed POST is logged and dropped — so run
the daemon under the same supervision as its receiver.
As a library
npm install taskratimport { TaskManager } from "taskrat";
const manager = new TaskManager(tasksDir, notificationUrl, logClient);
manager.start(); // polls every 60s; POSTs a notification when a task comes dueThe published package ships compiled JavaScript + type declarations in dist/, so it
imports under plain Node with no build step or loader. import resolves to
dist/index.mjs; the .mts sources are shipped too (used to compile the bins).
