# Design ![[tsk.db]] ![[tsk.sqbpro]] Tasks are a capped stack, the cap is configurable via a config file. ![[Tsk Home 2024-01-03 17.58.13.excalidraw]] Tasks have only a few fields, all of which are either automatically generated or completely optional. Example [[Rust]] struct: ```rust enum TaskStatus { Todo, InProgress, Complete, Cancelled, } type Tag = String; struct Task { // This tasks unique identifier id: u64, // used to generate a TSK-<id> // This tasks state status: TaskStatus, // The required title of this task title: String, // The additional text body of this task. Arbitrary text body: Optional<String>, // Optional tags associated with this task. // These should be stored as de-duplicated relationships // in the backend tags: Vec<Tag>, // An optional link associated with the task. This is // primarily to support quick navigation via a shortcut // to the link. Additional links may be included in // the `body` field. link: Optional<Url>, // Arbitrary relationships between tasks represented with // an arbitrary tag. relationships: Vec<(Task, Tag, Task)>, } ``` Commands differ based on mode and are documented below ## Main Mode > [!NOTE] Title > Commands use `[]` to denote optional text and `<text>` to denote arguments. Everything else is a literal. - `P[USH] <task title>` creates a task with the provided title to the top of the stack (highest priority) - `E[DIT] <task id>` opens the details pane for a task with the provided id (ex. `123`) - `N[EW] <task title>` creates a task with lowest priority - `S[TART]` marks the task at the top of the priority stack as "in progress", denoted with a `[-]` - `C[OMPLETE]` marks the task at the top of the priority stack as "complete", denoted with a `[x]` and removing the task from the priority stack - `U[NDO]` undoes the previous operation - History should be retained for at least program lifetime, but *may* be persisted to non-volatile storage - `B[ACKLOG]` switches to the backlog pane, where all todo and in-progress tasks are displayed in order - `T[ODO] <task id>` puts a task back in the todo status. This is how you "reopen" a task - `C[ONNECT] <task id> <tag> <task id>` defines a relationship between 2 tasks - The relationship is an arbitrary tag, however the tag must already be defined - Autocomplete is a high priority feature - `M[AKE] <tag>` defines a tag - `Q[UERY] (#<tag>|lt;status>|"arbitrary text")*, ...` finds tasks with a given filter. `#` is used to delimit a tag filter and a `
is used to delimit a status filter - Multiple filters may be defined using a `,` separator - Executing this command takes you to a filtered backlog pane - Results are ordered in ascending order by filter order - Prepending a `-` before a query - `L[INK] [task id]` opens the link associated with a task. If a task id is supplied, the URL for that task is used, otherwise the task at the top of the stack is used - `DROP [task id]` marks a task as cancelled. If a task ID is supplied, that task's stated is changed, otherwise it drops the task at the top of the stack - `ROT` "rotates" the 3rd item on the stack into the top position ( 1 2 3 -> 2 3 1) - `-ROT` "rotates" the top item of the stack into the 2nd position (1 2 3 -> 3 1 2) - `SWAP` / `W` swaps the top 2 items of the stack ( 1 2 -> 2 1) - `REP n` re-prioritizes an arbitrary task relative to the top of the stack to the top of the stack - Example: `REP 3` will move the 3rd stack element to the top (4 3 2 1 -> 4 3 1 3) - `DEP n` re-prioritizes the task at the top of the stack to be an arbitrarily low priority, shifting the task it replaces (if any) *up* - `Q[UIT]` exits the application. The *esc* key can do the same thing ## Details Mode Details mode is accessed by running the `E[DIT]` command in main mode. It presents a screen with the extended fields for a task and allows editing most of them directly. Commands in this mode differ slightly from the main mode: - `N[AME]` lets you edit the title of the ticket - `D[ETAILS]` lets you edit the detailed text of the ticket - `L[INK]` lets you edit the link - `X` opens the link if one is set - *Esc* key or `H[OME]` will return to the main screen - `T[AG] <tag>` adds a tag binding to this task Additionally, several commands behave the same as in the main mode: - `B[ACKLOG]` - `S[TART]`, implicitly modifies current task - `C[OMPLETE]`, implicitly modifies current task - `D[ROP]`, implicitly modifies current task - `T[ODO]`, implicitly modifies current task - `C[ONNECT]` - `M[AKE]` - `Q[UERY]` ## Query Mode Query mode is access via the `Q[UERY]` command. It shows every task that meets the query criteria. `B[ACKLOG]` is a special-case of query mode with a predefined query. Most commands for query mode are identical to main mode, with one key addition: `F[ILTER] <query>`: This command has the same syntax as `Q[UERY]` but filters an existing query down further. ## Keyboard Shortcuts # Open Questions Should I limit the size of details? Titles? ## Multiple task logs syncing I'd like to support collaborative management of tasks # Dev Log I have some super basic command parsing at this point, though lacking the ability to parse arguments. Some things that I really want to support are: - Auto-complete when it's applicable - Tab complete for command shorthand (ex. `p` becomes `push` when space is pressed) - Extremely fast (minimal typing) common case of modifying most common task dealing cases - Creating task that is top priority - Modify the the "current" (top) task's state - start -> complete / cancelled -> todo - Edit/add details to a task - Connect tasks semantically - `child-of`, `blocks`, `requires` - See tab completion Some ideas I'm still toying with: - Mail-based synchronization/task passing - SSH-based TUI for centralized management It's not that hard to get command parsing working, but semi-intelligent suggestions are tedious to add. I've also realized that I did not have a layout in mind for the home screen, or rather the vision I had didn't actually account for the density of the terminal output. I currently use a list of dumb text with a `format!` to produce tasks, but I think I should switch to a table-based view. Further, the `TextView` library that I'm using isn't exactly what I need, especially as I need `Span`s for properly formatting of hints and errors. To account for this, I think I should create multiple pains, 3 in total (if there's room). The first additional pane is "recently completed" and includes any tasks that have been marked as completed in the last 24 hours. The second will be the "INBOX" which will show both when there is space, and when remove/sync is enabled. ## SQL Notes Recursive query using linked-list style prioritization: ```sql WITH RECURSIVE priority_task(id, title, created, next) AS ( SELECT id, title, created, next FROM TASK WHERE ID = 0 UNION SELECT task.id, task.title, task.created, task.NEXT FROM TASK, priority_task WHERE task.id = priority_task.next LIMIT 21 ) SELECT * FROM priority_task WHERE ID > 0; ``` This will return the top 20 tasks by priority