mktask
A work task prioritizer built on mkio (config-driven microservice backend) and mkui (config-driven Web Components workspace with dockable panes).
Tasks live in a local SQLite database and show up in a live-updating blotter you can sort, filter, and arrange however you like. Each task carries an importance and an urgency (1–5); the blotter derives a score from them so the most pressing work floats to the top.
A task can be split into child tasks, and a child can be split again, to any depth. The blotter nests children under their parent, each level sorted by score, with carets to fold a subtree away. Completing a task completes everything split from it; reopening a child reopens its ancestors; deleting a task deletes its whole subtree — permanently, and it is the one thing here that cannot be undone.
Move re-files a task: pick a new parent, or — Top level — to make it a top-level task again. Everything split from it comes along. The picker offers every open task except the ones under the task being moved, and a move that would land a linked task in its own tree is refused, naming the links to remove first.
A task can be assigned to someone. Assigned To is a dropdown: pick a name, pick — New name — and type one — a name typed there joins the list and is offered from then on — or pick the blank first entry, which means nobody. The dropdown opens on whoever the task is assigned to, so leaving it alone changes nothing, and splitting a task opens on the parent's name, so a child usually needs no picking at all.
The list itself is yours to keep, under Configure › Assignees: add a name before anyone is assigned to it, fix a spelling, or take a name off it when someone leaves. Taking a name off the list changes the list and nothing else — every task already assigned to that name keeps it, and the name still shows in the dropdown of a task that carries it, so editing that task cannot lose it by accident. Renaming works the same way: it changes what the picker offers next time, not what any task says.
Every task gets a Task ID like TKMA00000042: TK, two letters from
the username the server runs as (--user), and a sequence number that
starts at 00000001, never repeats, and grows past eight digits rather than
wrapping (TKMA100000000 follows TKMA99999999).
A task carries references: the things to refer back to while working on
it. A reference is a URL (including mailto: and mail-client links), a
pasted text snippet (an email, a chat exchange), a file (a screenshot, a
PDF), or a link to another task with a relation. The References
pane's Add URL, Add Text, and Add Link buttons add one each, and the Detail
pane has the same three. Each dialog opens on a Task picker already set
to the task selected in the blotter — change it to file the reference on
another task, or pick one when nothing is selected — with the label
suggested from the URL or the first line of the text; once added, the
blotter selects the task it went to, so the new reference is on show
whichever task that was. Files are added from the Detail pane instead:
select a task and drop, paste, or pick a file there; an image pastes
straight from the clipboard, a pasted URL becomes a URL reference, pasted
text a snippet. The Detail pane opens with
the task itself — its status, importance, urgency, score, due date, who it is
assigned to, and notes — and lists every reference of the selected task the moment it is selected,
and every reference of the tasks split from it — a section per relation ("Blocks",
"Blocked by"), then the snippets, images, files, and URLs, each section
counted, and a reference a child owns tagged with its Task ID. Images show
as a grid of thumbnails; clicking one opens it full size under the grid, and
clicking a snippet or a URL opens it where it stands. The subtree comes from
the tasks themselves, not from what the blotter is showing, so a completed
child's references stay with its ancestor.
The Detail pane edits what it shows. It has its own toolbar — Add URL, Add Text, and Add Link are the References pane's add buttons — and one cursor: click the task block or click a reference. Edit opens the dialog that matches — the same Edit dialog the blotter opens for a task, the same one the References pane opens for a reference — and Delete removes a reference (a task is deleted from the blotter, where the row being deleted is the row that was picked). An edit shows up here the moment the server announces it.
The References pane follows the selected tasks (mkui table linking; clear the selection to see every reference), each reference beside its task's Task ID and title (the title is joined in live: renaming the task updates the column), with URLs and files as links; selecting one there opens and marks the same line in the Detail pane, and a reference the Detail pane does not list leaves it alone. A task link shows on both tasks, worded from each side, and Go to selects the linked task in the blotter, so the Detail and References panes follow it (a linked task the current filter hides is revealed first). Only tasks from different trees can be linked; tasks that share a root are already related by splitting.
Relations are yours to define under Configure › Relations: each is a pair
of wordings, one from this task to that one ("blocks") and one back
("blocked by"), or a single wording that reads the same both ways ("relates
to"). A new database starts with those two. Renaming a relation rewrites
every link that uses it; a relation in use cannot be deleted. Uploaded
files live beside the database in <db>.files/, named by content hash;
deleting the last reference to a file, or its task, removes the file.
Each task also shows its Last Event — the most recent thing to have happened to it, in words: Created, Split into Wire the pane, Attached a file: shot.png, Linked: blocks TKMA00000002, Moved under TKMA00000007.
Every change is kept. Tasks and references carry a version number, shown as a column, and every version of every row is recorded. Adding, editing or removing a reference makes a version of the task that owns it — both sides of a link — so a task's history covers its references as well as its own fields, and each version says what it was about. History on the Tasks or References pane — or in the Detail pane, for whatever its cursor is on — opens that record: the versions as a table you can sort and search, a Diff of what changed between any two, and Blame for which version last set each field.
Undo and Redo step a record back and forth along those versions, from the same panes. They step the whole action, not one row: undoing a completion reopens the subtree it completed, undoing a link removes both halves, undoing a move puts back the ancestors it reopened. A confirmation says what is about to change. Undoing the creation of a task removes it, and redo brings it back. Editing a task after undoing it discards what was undone, the way typing after an undo does in an editor. There is no keyboard shortcut on purpose — this writes to data everyone on the server shares.
Undo and redo are refused rather than half-applied when they would strand something: a task that has since been split, a parent or a linked task that has since been deleted, or a row another change has moved past.
Activity (under the Tasks menu) is the other half: a plain list of what happened to the selected task — created, split from, split to, edited, moved, completed, reopened, references added, edited and deleted, and every undo and redo. It follows the blotter's selection like the References pane, and unlike the version record it is never rewritten.
Quick start
pip install mktask
mktask # http://127.0.0.1:8080/
Everything installs via pip; nothing is fetched at runtime.
CLI
mktask [config] [-p PORT] [--host HOST] [-d PATH] [-u USER] [--files DIR] [--version]
config— path to amktask.toml. Defaults to./mktask.tomlif present, otherwise the one bundled with the package.-p, --port— override the listening port (default 8080).--host— override the listening host (default127.0.0.1).-d, --db— database file;.dbis appended when there is no extension.:memory:runs without persistence.-u, --user— the username whose first two alphanumeric characters, uppercased, prefix new Task IDs (mark→TKMA…; a one-character name is padded withX). Defaults to the OS login name.--files— directory for uploaded reference files, served at/files. Defaults to<db>.filesbeside the database (mktask.db.files/), a temporary directory for:memory:.
The server prints the URL to open once it is listening. If the port is already taken it exits immediately with an error instead of starting.
Customizing
Copy the bundled config out and edit it:
python -c "import mktask, pathlib; print(pathlib.Path(mktask.__file__).parent / 'mktask.toml')"
mktask.toml declares the SQLite tables, the mkio services, and the static
routes (keep relations.json, the seed for the relations table, beside a
copied config); static/app.json next to it declares the UI (menus, panes,
frames, dialogs). Both are plain config — see the mkio and mkui READMEs for the
formats. The one piece of code is mktask/services.py, which the tasks
service points at: it assigns Task IDs, runs the complete, reopen, and
delete cascades, re-parents a task on a move (refusing a cycle or a move
that would swallow a task link), and manages references and relations (task links are
written as a mirrored pair, labels follow the linked task's title, a
renamed relation rewrites its links, orphaned files are removed).
static/refs.js is the one custom widget and the whole Detail body: the
toolbar, the task block, the drop box, the reference list of the selected
task and its descendants (its own live queries), and Go to. Its Edit and
Delete open the dialogs the Tasks and References panes already declare,
borrowed from app.json by pane and button name rather than copied.
Upgrading
Until 1.0, a release may change the database schema without migrating an
older database. 0.2.0 did (Task IDs, splitting, and complete replacing
done): delete a 0.1.0 mktask.db before starting a newer version. 0.3.0
only adds the task_refs table, which auto_migrate creates in an existing
database, so a 0.2.0 database carries over as is. 0.3.1 changes no schema.
0.4.0 adds the relations table (created and seeded on first start) and
stores a link's relation as its wording ("blocked by") rather than a key
(blocked_by): links made before 0.4.0 must be removed and re-added. 0.5.0
changes no schema — the Detail pane's new reference list reads the tables
0.4.0 already had, and neither does 0.6.0: moving a task rewrites one
existing column. 0.7.0 changes no schema either: the Detail pane's toolbar
sends the ops that were already there. 0.8.0 adds a last_event column, the
task_events table, and a recorded history of tasks and task_refs — all
of which an existing database picks up on first start: auto_migrate adds
the column and the tables, and every row already there is recorded as its
own version 1 so it can be stepped back to. Nothing has to be deleted. 0.9.0
adds an assigned_to column and the assignees table behind the Assigned To
dropdown, both of which auto_migrate adds to an existing database on first
start; every task starts unassigned and the list starts empty. 0.10.0
changes no schema: the Add URL / Add Text / Add Link dialogs read a new
lookup service over the tables that were already there. 0.11.0 changes no
schema either: the References pane's Task Title is joined in by the
task_refs query, which mkio 0.8.0 keeps live, so nothing new is stored.
0.12.0 changes no schema: it only takes the Show Open Only / Show All /
Expand All / Collapse All entries off the Tasks menu. 0.13.0 changes no
schema: the statusbar now shows the server's version beside the name,
read from the same reply that checks the server is mktask. It is also the
first release to require mkio and mkui 1.x (pip install --upgrade mktask
brings them in); a 0.12.0 database carries over as is. 0.13.1 changes no
schema: it is the Windows release, and raises the mkio floor to 1.0.1.
0.13.2 changes no schema: it raises the floor to mkio 1.1.0, whose
server runs on asyncio's selector loop on Windows, so the connections a
browser opens ahead of a page load and drops no longer print a
ConnectionResetError traceback each.
0.13.3 raises it to mkio 1.1.1, whose Windows loop lets Ctrl+C stop the
server at once instead of waiting for the next timer or packet.
Development
pip install -e '.[test]'
mktask -d :memory:
python -m pytest
The tests cover the CLI and config loading, Task ID formatting, a real
server over HTTP and WebSocket (every task op, splitting and the cascades,
moving a task to another parent or the top level, the Task ID sequence
across restarts and past eight digits, references and task links with their
validation, the same-tree rule, and cascades,
user-defined relations (seeding, uniqueness, rename rewriting links in both
directions, a swap flipping them, delete refused in use), file upload,
dedupe, and cleanup, live delete announcements, the query filter, saved
layouts, the port, host, user, and files flags), the port probe on a
fake Windows, what only breaks on Windows (every text read names its
encoding, LF pinned), and the static integrity of
app.json against mktask.toml and refs.js (every column, dialog field,
service, and state path a pane names, the Detail pane's task block and the
dialogs its toolbar borrows, and the reference sections against the kinds
the server accepts).
Runs on Linux, macOS and Windows with the standard CPython 3.11+
interpreter; Windows needs mkio 1.1.1 or later, which pip install
brings in. On Windows, Ctrl+C stops the server the same way as elsewhere.
The Task ID prefix comes from the account name's first two ASCII letters
or digits, so a name starting with a space or a non-ASCII letter still
yields a valid one.
License
Apache License 2.0. See LICENSE.
Release files for mktask 0.13.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mktask-0.13.3.tar.gz | 121.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mktask-0.13.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 176.5 kB
Release files / mktask-0.13.3.tar.gz
| Download URL | mktask-0.13.3.tar.gz |
|---|---|
| Size | 121.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
87ca507eed9f527ec71a4d60d498ca472f4ddf0766bba93fe7c2ecd6fe9ad769
|
|
BLAKE2b-256 checksum How to use checksums |
1e19c0347eebf7bf99dd7b86c2507c2e220758fecb17788b8ba6ab4856b83718
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Release files / mktask-0.13.3-py3-none-any.whl
| Download URL | mktask-0.13.3-py3-none-any.whl |
|---|---|
| Size | 55.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9623a5596729367d25f18b636f22fbd0b3bc04b978d2cac3d455420cc1419154
|
|
BLAKE2b-256 checksum How to use checksums |
6169ccc64e836599fb60884bb03bd1861db11c20ed2b70ddd086da78a1cf1464
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|