taskuary 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. taskuary-0.2.0/LICENSE +21 -0
  2. taskuary-0.2.0/PKG-INFO +424 -0
  3. taskuary-0.2.0/README.md +376 -0
  4. taskuary-0.2.0/pyproject.toml +63 -0
  5. taskuary-0.2.0/setup.cfg +4 -0
  6. taskuary-0.2.0/taskuary/__init__.py +2 -0
  7. taskuary-0.2.0/taskuary/agents.py +218 -0
  8. taskuary-0.2.0/taskuary/artifacts.py +209 -0
  9. taskuary-0.2.0/taskuary/aws.py +226 -0
  10. taskuary-0.2.0/taskuary/azure.py +334 -0
  11. taskuary-0.2.0/taskuary/blackboard.py +150 -0
  12. taskuary-0.2.0/taskuary/channels.py +768 -0
  13. taskuary-0.2.0/taskuary/ci.py +237 -0
  14. taskuary-0.2.0/taskuary/cli.py +47 -0
  15. taskuary-0.2.0/taskuary/coder.py +132 -0
  16. taskuary-0.2.0/taskuary/config.py +62 -0
  17. taskuary-0.2.0/taskuary/db.py +63 -0
  18. taskuary-0.2.0/taskuary/desktop.py +72 -0
  19. taskuary-0.2.0/taskuary/devtools.py +352 -0
  20. taskuary-0.2.0/taskuary/digest.py +104 -0
  21. taskuary-0.2.0/taskuary/docsync.py +124 -0
  22. taskuary-0.2.0/taskuary/github.py +136 -0
  23. taskuary-0.2.0/taskuary/histgen.py +220 -0
  24. taskuary-0.2.0/taskuary/imapmail.py +150 -0
  25. taskuary-0.2.0/taskuary/ingest.py +344 -0
  26. taskuary-0.2.0/taskuary/learn.py +181 -0
  27. taskuary-0.2.0/taskuary/llm.py +175 -0
  28. taskuary-0.2.0/taskuary/logs.py +17 -0
  29. taskuary-0.2.0/taskuary/mcp.py +78 -0
  30. taskuary-0.2.0/taskuary/messengers.py +205 -0
  31. taskuary-0.2.0/taskuary/mssql.py +64 -0
  32. taskuary-0.2.0/taskuary/outbound.py +221 -0
  33. taskuary-0.2.0/taskuary/phone.py +88 -0
  34. taskuary-0.2.0/taskuary/pm.py +310 -0
  35. taskuary-0.2.0/taskuary/policy.py +59 -0
  36. taskuary-0.2.0/taskuary/proof.py +194 -0
  37. taskuary-0.2.0/taskuary/proposals.py +132 -0
  38. taskuary-0.2.0/taskuary/reports.py +508 -0
  39. taskuary-0.2.0/taskuary/reshape.py +201 -0
  40. taskuary-0.2.0/taskuary/responder.py +199 -0
  41. taskuary-0.2.0/taskuary/routing.py +115 -0
  42. taskuary-0.2.0/taskuary/scopes.py +88 -0
  43. taskuary-0.2.0/taskuary/server.py +1506 -0
  44. taskuary-0.2.0/taskuary/store.py +711 -0
  45. taskuary-0.2.0/taskuary/templates/coder.md +35 -0
  46. taskuary-0.2.0/taskuary/templates/digest.md +5 -0
  47. taskuary-0.2.0/taskuary/templates/learned.md +31 -0
  48. taskuary-0.2.0/taskuary/templates/soul.md +44 -0
  49. taskuary-0.2.0/taskuary/templates/style.md +14 -0
  50. taskuary-0.2.0/taskuary/templates/triage.md +22 -0
  51. taskuary-0.2.0/taskuary/terminal.py +971 -0
  52. taskuary-0.2.0/taskuary/toil.py +57 -0
  53. taskuary-0.2.0/taskuary/triage.py +123 -0
  54. taskuary-0.2.0/taskuary/verdicts.py +73 -0
  55. taskuary-0.2.0/taskuary/web/assets/index-6GBZ9nXN.css +32 -0
  56. taskuary-0.2.0/taskuary/web/assets/index-Cjj87C2X.js +401 -0
  57. taskuary-0.2.0/taskuary/web/favicon.ico +0 -0
  58. taskuary-0.2.0/taskuary/web/favicon.png +0 -0
  59. taskuary-0.2.0/taskuary/web/index.html +25 -0
  60. taskuary-0.2.0/taskuary/whatsapp/bridge.mjs +101 -0
  61. taskuary-0.2.0/taskuary/whatsapp/package.json +11 -0
  62. taskuary-0.2.0/taskuary.egg-info/PKG-INFO +424 -0
  63. taskuary-0.2.0/taskuary.egg-info/SOURCES.txt +98 -0
  64. taskuary-0.2.0/taskuary.egg-info/dependency_links.txt +1 -0
  65. taskuary-0.2.0/taskuary.egg-info/entry_points.txt +3 -0
  66. taskuary-0.2.0/taskuary.egg-info/requires.txt +34 -0
  67. taskuary-0.2.0/taskuary.egg-info/top_level.txt +1 -0
  68. taskuary-0.2.0/tests/test_answers.py +157 -0
  69. taskuary-0.2.0/tests/test_api.py +1002 -0
  70. taskuary-0.2.0/tests/test_blackboard.py +133 -0
  71. taskuary-0.2.0/tests/test_cloud.py +140 -0
  72. taskuary-0.2.0/tests/test_cloud_sources.py +253 -0
  73. taskuary-0.2.0/tests/test_config.py +32 -0
  74. taskuary-0.2.0/tests/test_core.py +839 -0
  75. taskuary-0.2.0/tests/test_desktop.py +26 -0
  76. taskuary-0.2.0/tests/test_devtools.py +211 -0
  77. taskuary-0.2.0/tests/test_diff_review.py +123 -0
  78. taskuary-0.2.0/tests/test_docs_and_llm.py +498 -0
  79. taskuary-0.2.0/tests/test_harvest.py +107 -0
  80. taskuary-0.2.0/tests/test_histgen.py +94 -0
  81. taskuary-0.2.0/tests/test_imapmail.py +160 -0
  82. taskuary-0.2.0/tests/test_mark_read.py +106 -0
  83. taskuary-0.2.0/tests/test_mcp.py +32 -0
  84. taskuary-0.2.0/tests/test_messengers.py +244 -0
  85. taskuary-0.2.0/tests/test_mssql.py +77 -0
  86. taskuary-0.2.0/tests/test_not_coding.py +124 -0
  87. taskuary-0.2.0/tests/test_pm.py +228 -0
  88. taskuary-0.2.0/tests/test_poll_overlap.py +64 -0
  89. taskuary-0.2.0/tests/test_poll_sources.py +52 -0
  90. taskuary-0.2.0/tests/test_proof_ci_proposals.py +285 -0
  91. taskuary-0.2.0/tests/test_reply_channels.py +98 -0
  92. taskuary-0.2.0/tests/test_reply_voice.py +94 -0
  93. taskuary-0.2.0/tests/test_reviews.py +56 -0
  94. taskuary-0.2.0/tests/test_scopes.py +68 -0
  95. taskuary-0.2.0/tests/test_sync_clock.py +74 -0
  96. taskuary-0.2.0/tests/test_task_identity.py +108 -0
  97. taskuary-0.2.0/tests/test_terminal.py +860 -0
  98. taskuary-0.2.0/tests/test_toil.py +29 -0
  99. taskuary-0.2.0/tests/test_vision.py +179 -0
  100. taskuary-0.2.0/tests/test_watermark.py +88 -0
taskuary-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ldbumble
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,424 @@
1
+ Metadata-Version: 2.4
2
+ Name: taskuary
3
+ Version: 0.2.0
4
+ Summary: Automate your job - the local-first operating system for your work: AI triage in, coding agents out.
5
+ License: MIT
6
+ Project-URL: Homepage, https://github.com/ldbumble/taskuary
7
+ Project-URL: Repository, https://github.com/ldbumble/taskuary
8
+ Project-URL: Issues, https://github.com/ldbumble/taskuary/issues
9
+ Project-URL: Changelog, https://github.com/ldbumble/taskuary/releases
10
+ Keywords: ai,agents,automation,claude,coding-agent,email,local-first,task-management
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Office/Business :: Scheduling
19
+ Classifier: Topic :: Software Development :: Build Tools
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: fastapi>=0.100
24
+ Requires-Dist: uvicorn>=0.23
25
+ Requires-Dist: pydantic>=2
26
+ Requires-Dist: requests>=2.28
27
+ Requires-Dist: loguru>=0.7
28
+ Requires-Dist: anthropic>=0.69
29
+ Requires-Dist: tomli>=2; python_version < "3.11"
30
+ Requires-Dist: websockets>=12
31
+ Requires-Dist: pywinpty>=2; sys_platform == "win32"
32
+ Requires-Dist: pyte>=0.8
33
+ Provides-Extra: mssql
34
+ Requires-Dist: pyodbc>=4; extra == "mssql"
35
+ Provides-Extra: db
36
+ Requires-Dist: sqlalchemy>=2; extra == "db"
37
+ Provides-Extra: aws
38
+ Requires-Dist: boto3>=1.28; extra == "aws"
39
+ Provides-Extra: desktop
40
+ Requires-Dist: pywebview>=4; extra == "desktop"
41
+ Provides-Extra: build
42
+ Requires-Dist: pyinstaller>=6; extra == "build"
43
+ Provides-Extra: dev
44
+ Requires-Dist: pytest>=7; extra == "dev"
45
+ Requires-Dist: httpx>=0.24; extra == "dev"
46
+ Requires-Dist: openpyxl>=3; extra == "dev"
47
+ Dynamic: license-file
48
+
49
+ # Taskuary
50
+
51
+ [![CI](https://github.com/ldbumble/taskuary/actions/workflows/ci.yml/badge.svg)](https://github.com/ldbumble/taskuary/actions/workflows/ci.yml)
52
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
53
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-3776ab.svg)](https://github.com/ldbumble/taskuary)
54
+ [![PRs welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)
55
+ [![GitHub stars](https://img.shields.io/github/stars/ldbumble/taskuary?style=social)](https://github.com/ldbumble/taskuary/stargazers)
56
+
57
+ ## Automate your job.
58
+
59
+ **Your inbox and your coding agents in one place.** Email, Teams, Slack, GitHub issues and
60
+ scheduled reports land on one timeline; AI triage says what is real work; the coding CLI
61
+ you already use does it; you approve the result. Runs entirely on your machine.
62
+
63
+ ![Taskuary in use: the timeline of email, chats and scheduled reports; a mail opened to show why triage made it a task and the AI reply drafted for approval; a scheduled report landing with its bar chart and spreadsheet; the Reports pipeline list; and the agent board with live sessions and the note one agent left the next](docs/hero.gif)
64
+
65
+ <sub>Real app, real data — a mail triaged and its reply drafted for your approval, then a scheduled SQL report landing on the same rail with its chart and spreadsheet. Nothing sends without you.</sub>
66
+
67
+ **Where it is:** early — **v0.2.0**, and moving fast. The funnel, the review queue, the agent
68
+ sessions and the reports pipeline are all real and in daily use on my own inbox; the edges are
69
+ still being knocked off, and breaking changes are possible before 1.0. Issues get answered.
70
+ [Full status and roadmap ↓](#status--roadmap)
71
+
72
+ > ⭐ **Useful to you? Star the repo.** Stars are how other people find Taskuary — and the
73
+ > clearest signal of what to keep building.
74
+
75
+ ## Why
76
+
77
+ Work arrives as messages, but work *is* tasks — and you are the translation layer. You
78
+ read the mail, decide what it means, open the ticket, do the thing, and write back. The
79
+ first and last steps are where the day goes.
80
+
81
+ Taskuary automates the ends and leaves you the middle. Triage reads everything and files
82
+ the noise. Real work becomes a task and goes to your agent, which works in your repos and
83
+ reports back with the diff. Replies come back as drafts. Nothing sends, closes, or ships
84
+ without you — and nothing leaves your machine except the calls you configured.
85
+
86
+ ## It learns your job
87
+
88
+ Every verdict you give teaches it. Edit a draft before sending — it learns your voice.
89
+ Reject one — it learns what should never have been drafted. Say **"Not our task"** — it
90
+ learns where your job ends, and that one sticks immediately as a standing note on that
91
+ sender (yours to review under Settings → Agent memory).
92
+
93
+ The general lessons take a stricter road, so one odd Tuesday never becomes a rule:
94
+
95
+ ![Your verdicts become a hypothesis with score s:2; agreeing verdicts add a point and contradictions remove one; at s:4 with proof from two or more people it is promoted into LEARNED.md, which then rides into every triage, draft and agent run](docs/learning-loop.svg)
96
+
97
+ **How the memory works, concretely.** Each lesson is one line in `LEARNED.md` (Docs tab) —
98
+ a guess with a score. Say you strip the greeting off three drafts this week; the file soon
99
+ carries:
100
+
101
+ ```
102
+ - John drops greetings and signs off in one word. [s:4 | ev: rv12,rv15,rv31 | seen: 2026-08-19]
103
+ ```
104
+
105
+ Read the tag left to right: **s:4** is the score — how often the guess has held. It starts
106
+ at 2, gains a point every verdict that agrees, loses one every verdict that contradicts; at
107
+ **4** the line is promoted and starts steering triage and drafts, at **0** it's deleted.
108
+ **ev:** is the receipts — the exact verdicts that taught it (`rv12` = your decision on
109
+ review #12), so you can see *why* it believes something. **seen:** is the last day it held.
110
+ Delete the line and the lesson is gone; lines you write yourself carry no tag and are never
111
+ touched. Two more guardrails: a rule that would *hide* mail (never a task, auto-file) waits
112
+ for your explicit OK instead of promoting itself, and `SOUL.md` — the rules you write —
113
+ always outranks the learned file. One switch in Settings turns the whole loop off.
114
+
115
+ **And it can learn the job you had *before* it.** Verdicts take weeks to accumulate; your
116
+ mailbox already holds months of them. **Docs → TRIAGE.md or STYLE.md → Generate from
117
+ history** reads your last three months of mail (sent + inbox, straight from the mailbox),
118
+ pairs every inbound thread with whether *you answered it*, and writes the distilled
119
+ guidance into a marked block of the doc — regenerate any time, your own lines outside the
120
+ markers always survive. What each one feeds from then on:
121
+
122
+ - `TRIAGE.md` + its history block → **every triage verdict**: what kinds of asks you
123
+ actually answer, which senders and domains matter (backed by a per-domain answer-rate
124
+ roll-up), what's reliably ignorable;
125
+ - `STYLE.md` + its history block → **every reply draft**: your greeting and sign-off, tone
126
+ and length, characteristic phrasing, how you push back — distilled from the replies you
127
+ yourself sent.
128
+
129
+ ## Get started
130
+
131
+ ```bash
132
+ pip install git+https://github.com/ldbumble/taskuary
133
+ taskuary # opens http://127.0.0.1:7787
134
+ ```
135
+
136
+ Python 3.10+ is all you need.
137
+
138
+ > **Which OS?** CI runs the full test matrix on Windows, Linux and macOS, and the app runs on
139
+ > all three — but it is *developed* on Windows, so that is where the terminal, the desktop
140
+ > shell and the agent presets get the most real use. On macOS and Linux expect the core to
141
+ > work and the occasional rough edge; [open an issue](https://github.com/ldbumble/taskuary/issues)
142
+ > and it gets fixed. The single-file prebuilt `.exe` is Windows-only.
143
+
144
+ Then, in **Connectors** — a minute or two each:
145
+
146
+ 1. **AI** — paste an Anthropic / OpenAI / Azure OpenAI / OpenRouter key — or no key at
147
+ all: the **Ollama** card runs triage on a local open-source model. Triage is now on.
148
+ (A small, cheap model is the right pick here; the expensive one goes in step 3.)
149
+ 2. **A channel** — Outlook, Gmail/IMAP, Teams, Slack, Telegram, WhatsApp or Discord. Mail
150
+ starts landing on the Timeline — and Jira/Asana/Monday/ClickUp/Todoist/Linear/Trello/
151
+ GitLab/Azure DevOps items assigned to you, Sentry errors and PagerDuty incidents ride
152
+ the same funnel.
153
+ 3. **Your coding CLI** — pick a preset (Claude Code, Codex, Gemini, Cursor, Copilot), Save,
154
+ Test. Add a GitHub PAT and repos are discovered for you.
155
+ 4. **Reports** (optional) — point at SQL Server, any database by connection string, AWS,
156
+ Azure, Prometheus, Datadog, MCP, REST or RSS and schedule a query with an AI prompt; the
157
+ summary lands on your Timeline. One ships ready-made: the **Morning digest**, a daily
158
+ brief of your own funnel — edit its prompt to taste, or delete it.
159
+
160
+ No cloud key at all? Set **Settings → Triage & routing → Triage brain** to your CLI agent
161
+ and skip step 1 — one brain does everything, slower and pricier per message. See
162
+ [One brain or two](#one-brain-or-two).
163
+
164
+ Prefer a desktop app? `pip install "taskuary[desktop] @ git+https://github.com/ldbumble/taskuary"`
165
+ then `taskuary-desktop` — the same UI in a native window. A prebuilt single-file
166
+ `Taskuary.exe` is attached to every CI run.
167
+
168
+ ## The workspace
169
+
170
+ One tab per question, two lines each; the details live in the app's own help text.
171
+
172
+ - **Timeline** — everything inbound on one day-grouped rail, chips saying what each row IS
173
+ and whether it needs you. Click a row: the whole message (stored whole, not a preview),
174
+ its attachments drawn inline — half of "see below" mail is the screenshot — and every way
175
+ out: approve the drafted reply, send it to a coding agent, hand it to a person, split or
176
+ merge, "not our task" (which teaches triage for next time).
177
+ - **Board** — the agent kanban: Queued / Working / Waiting on you / Done, by what is TRUE
178
+ right now — a live session counts as working, and a session gone quiet moves its card to
179
+ *waiting on you* with the question showing. Cards working now show a live peephole and
180
+ the files their agent has modified so far; a queued card says whom it waits behind (see
181
+ [Many agents, one repo](#many-agents-one-repo--no-stepping-on-each-other)).
182
+ - **Tasks** — **the page is a terminal**: your CLI in the task's repo, prompt typed in and
183
+ sent, and you keep talking. Taskuary picks the checkout from the SOUL.md repo map (one
184
+ click to override); the prompt carries the ask, the mail, the files and the rules, so the
185
+ agent never re-fetches what it was handed. **Done — wrap it up** reads the transcript,
186
+ writes the report and drafts the reply — the agent is asked nothing, and both still work
187
+ after the terminal itself is long gone. Pause keeps a handover note the next session is
188
+ seeded with. The kind is a control: *"this is not a coding task"* is one dropdown, and
189
+ saying `reply` routes it into Review instead of a repo.
190
+ - **Review** — the decision queue. **Approve & send** sends whatever is in the box on the
191
+ channel it arrived on, in-thread; a refused send says so right there and keeps the text.
192
+ A reply drafted before an agent looked at the problem waits as *held* and comes back
193
+ rewritten from what the agent actually found.
194
+ - **Reports** — sources at the top (SQL, REST, MCP…), one AI prompt at the bottom, a
195
+ schedule. The rows come back as an **.xlsx** and a **bar chart** the summarizing model
196
+ itself chose the columns for; capped slices are named as capped so the AI never calls a
197
+ truncated slice "all of them". Preview runs the whole pipeline first. The **Morning
198
+ digest** ships as one of these — your own funnel as the data source, the daily brief on
199
+ the Timeline — so every install starts with a working example.
200
+ - **Connectors** — a catalog with a wizard per card. Every connection has **roles** you
201
+ choose: *trigger* (inbound work), *feed* (shown, never triaged), *report*, *tool* (agents
202
+ may use it), *notify* (Taskuary pushes pings TO it). Nothing is polled without a role.
203
+ - **Docs** — the six plain-markdown documents that steer everything (see
204
+ [The six documents](#the-six-documents)); they maintain themselves as connectors and
205
+ repos appear, and two can generate themselves from your mail history. Your name lives
206
+ in ONE field here and fills every `{{owner}}` mention.
207
+ - **Settings** — triage knobs with plain-English help, deterministic routing policies that
208
+ no model confidence can override, the learned memory, notification level, and one-click
209
+ audit-chain verification.
210
+
211
+ Two principles hold everywhere: **nothing sends or ships without your approval**, and
212
+ **agents work where you can watch** — a real terminal, never a hidden run. Out of the box
213
+ it works the mail (auto-dispatch + auto-draft, both switchable); triage is AI-gated, so
214
+ with no AI connected messages file visibly instead of heuristics spraying tasks.
215
+
216
+ ## Many agents, one repo — no stepping on each other
217
+
218
+ ![Two agents share one checkout: each working card shows the files ITS agent has modified (claude in the theme files, codex in the report code and its tests), and a third task waits in Queued with the reason written on the card — waiting on TQ-0009, both would modify ReportsView.jsx, starts by itself when it can](docs/screenshot-board.png)
219
+
220
+ Auto-dispatch can put several CLIs to work at once — and the board keeps them out of each
221
+ other's way with three light moves. No locks, no worktrees, no manager agent:
222
+
223
+ - **Affinity routing** — before a task auto-starts, Taskuary asks the triage brain one cheap
224
+ question: would it likely modify the same files as something already running in that
225
+ checkout? Likely yes → the task **queues behind** the running one — the ⏳ chip on the card
226
+ says behind whom and why (hover it) — and starts by itself the moment that agent finishes.
227
+ A full house (every session slot busy) queues the same way. Wrong guesses are cheap by
228
+ design: a wrong *yes* waits some minutes, a wrong *no* is caught by the next move.
229
+ - **The blackboard** — the board itself is what agents know about each other. Every working
230
+ card shows the files its agent has **actually modified so far** — read off git (dirty
231
+ files minus what was already dirty when the session opened) and the run trace, never off
232
+ a plan, because agents predicting their own scope get it wrong and their tracks do not.
233
+ An agent starting in the same checkout gets exactly that picture in its opening prompt:
234
+ who else is here, on which task, in which files.
235
+ - **First in has control** — and the newcomer is told so, plainly: those files are the other
236
+ agent's; never edit, revert, stash or commit them; no `git add -A` / `commit -a`; stage
237
+ only what you yourself changed. Agents in *other* repos are deliberately never mentioned —
238
+ awareness costs prompt tokens, so they are spent only where a collision is physically
239
+ possible.
240
+
241
+ ## One brain or two
242
+
243
+ Two different jobs, two very different price tags: **triage** reads one message and answers
244
+ in a line (thousands of times a month), **coding** rewrites your repositories (a few times a
245
+ day). Taskuary lets you split them or tier them:
246
+
247
+ | setup | triage / drafts / summaries | coding sessions | when |
248
+ |---|---|---|---|
249
+ | **Two brains** (recommended) | a small cloud model — Anthropic / OpenAI / Azure OpenAI / OpenRouter connector, fractions of a cent per message | your CLI agent, its full model | you have (or can get) one cheap API key |
250
+ | **One brain, two gears** | the same CLI, downshifted to its **light model** (set it on the agent: `haiku`, `gemini-2.5-flash`…) | the same CLI, its main model | one subscription, no API key — Claude Max, Codex |
251
+ | **One brain, one gear** | the CLI at full model | the CLI at full model | works, but every newsletter costs a frontier-model run |
252
+ | **Local brain** | an open-source model on your own machine — the Ollama connector, or any OpenAI-compatible server (LM Studio, llama.cpp, vLLM) | your CLI agent, or a CLI wrapping the same local model | no key, no cloud, no mail leaving the box |
253
+
254
+ Suggested setup: connect an **Anthropic** key with `claude-haiku-4-5` as the triage brain
255
+ (Settings → Triage & routing), keep `claude` as the coder with its default model — or, with
256
+ no API key at all, set the coder's **light model** to `haiku` (Connectors → AI CLI agents →
257
+ Edit) and point the triage brain at `cli: coder`. Either way the expensive model only ever
258
+ runs when there is real work in a real repository, and the cheap one handles the reading:
259
+ intent triage, reply drafts, report summaries, the morning digest, the lessons distilled
260
+ into LEARNED.md.
261
+
262
+ ## The six documents
263
+
264
+ Plain markdown, all on the Docs tab, all yours to edit. Three you write, two write
265
+ themselves, and two can **bootstrap themselves from your mail history** (`TRIAGE.md` and
266
+ `STYLE.md` — the Generate from history button). Each feeds exactly the calls it belongs in.
267
+
268
+ ![TRIAGE.md, STYLE.md, SOUL.md and LEARNED.md feed triage and replies on the cheap model; SOUL.md, CODER.md and LEARNED.md feed coding agents on your CLI; DIGEST.md is your own morning read — and TRIAGE.md and STYLE.md can be generated from three months of your own mail](docs/six-docs.svg)
269
+
270
+ | document | what it is | who reads it |
271
+ |---|---|---|
272
+ | `TRIAGE.md` | the classifier's instructions — what makes a task, a question, or FYI; ships as a default, edit it to reshape every verdict — **Generate from history** adds what 3 months of your answered-vs-ignored mail says matters | triage (cheap model) |
273
+ | `STYLE.md` | how you write replies — greeting, tone, length, phrasing; write it, or let **Generate from history** distill it from 3 months of your sent mail | reply drafts |
274
+ | `SOUL.md` | the constitution: your rules, voice, escalation lines, the repo map | triage, replies, coding agents |
275
+ | `CODER.md` | how the coding agent works and closes out | coding agents (your CLI) |
276
+ | `LEARNED.md` | your profile, learned from your verdicts — `SOUL.md` outranks it | triage, replies, coding agents |
277
+ | `DIGEST.md` | your morning brief: what's in flight, who waits on whom — written by the **Morning digest** report (Reports tab), whose prompt decides what goes in | you — it lands on your Timeline daily; delete the report to turn it off |
278
+
279
+ Standing notes (Settings → Agent memory) ride alongside: sender-scoped verdicts injected
280
+ into triage and replies — the specific layer under `LEARNED.md`'s general one.
281
+
282
+ ## Bring your own agent — and pick its model
283
+
284
+ Every run surface (Board dialog, task page, "send to coding agent") asks two questions:
285
+ **which CLI** works it, and **which model** that CLI runs. The model list comes from the
286
+ CLI — `opus` / `sonnet` / `haiku` and the full `claude-*` ids for Claude Code, the
287
+ `gpt-5-codex` family for Codex, and so on — and "the agent's default model" leaves it to
288
+ the profile. Under the hood it is one flag appended to the command (`--model` by default,
289
+ `model_arg` if your CLI spells it differently), so a per-run choice never edits your saved
290
+ profile.
291
+
292
+ Any CLI that reads a prompt on stdin works. The presets ship the right headless flags —
293
+ the important one being the auto-approve flag (`--dangerously-skip-permissions`,
294
+ `--full-auto`, `--yolo`, …): without it a headless agent hangs waiting for an approval
295
+ click that never comes. The built-in **Test** runs one tiny prompt through your CLI to
296
+ prove the wiring before it goes live. Claude Code's JSON output is parsed natively,
297
+ which enables resumable message-the-agent sessions; plain-text CLIs work too.
298
+
299
+ ## Integrations
300
+
301
+ | type | status | notes |
302
+ |------|--------|-------|
303
+ | `outlook` / `teams` / `slack` | ✅ | inbound channels → Timeline through AI triage |
304
+ | `gmail` / `imap` | ✅ | any mailbox that speaks IMAP — Gmail (App Password), a domain.com address, Yahoo, an ISP. In through triage, approved replies back over the provider's own SMTP, in-thread |
305
+ | `telegram` | ✅ | a bot token from @BotFather and nothing else — chats in through triage (photos reach the vision triage), approved replies back **into the same chat**. Approve-first: a new chat registers OFF under Sources with its chat id, and only the ones you flip on become work — a public bot can be messaged by anyone. With the *notify* role it also pings your phone with what's waiting on you ("the work is done, the reply is drafted in Review") |
306
+ | `whatsapp` | ✅ | your own account, via a small Baileys bridge that runs beside the app (`cd taskuary/whatsapp && npm install && node bridge.mjs`, pair once by QR or code) — asks in through triage, approved answers back into the chat, *notify* role pushes pings out. The heavy dependency deliberately lives in the bridge, not Taskuary — unofficial protocol, use a number you'd risk |
307
+ | `github` | ✅ | PAT → auto repo discovery, issue loop, repo map in SOUL.md; optional inbound trigger (new issues/PRs → Timeline → triage). Tasks born from a PR or issue carry the card's editable standing prompt — the PR default says judge it (useful? safe? minimal?), run the tests, report a verdict, never merge |
308
+ | `jira` / `asana` / `monday` | ✅ | items **assigned to you** land on the Timeline through triage, linking back — "assigned in Jira" and "asked by email" end up in the one funnel. Read-only; each card takes an optional standing agent prompt |
309
+ | `gitlab` | ✅ | issues + merge requests **assigned to you** → Timeline through triage — gitlab.com or your own instance. Read-only |
310
+ | `azdo` (Azure DevOps) | ✅ | work items **assigned to you** (WIQL `@Me`) → Timeline through triage. Read-only |
311
+ | `linear` / `trello` / `notion` | ✅ | Linear issues and Trello cards assigned to you flow through triage; Notion pages shared with the integration surface as a feed when they change |
312
+ | `discord` | ✅ | watch channels with a bot — messages in through triage, approved replies post back **into the channel** |
313
+ | `sentry` / `pagerduty` | ✅ | new unresolved errors and open incidents land on the Timeline through triage — production breakage joins the same funnel as the mail about it |
314
+ | `anthropic` / `openai` / `azure_openai` | ✅ | AI for triage + report summaries |
315
+ | `openrouter` | ✅ | one key, the whole catalog — open-weights Llama / Qwen / Mistral and every closed model, as the triage brain |
316
+ | `ollama` | ✅ | local open-source models, no key and no cloud — Ollama out of the box, `base_url` reaches LM Studio / llama.cpp / vLLM |
317
+ | `mssql` | ✅ | connect once; build AI-summarized reports on the Reports tab |
318
+ | `database` | ✅ | **any engine by connection string** — postgres / mysql / snowflake / oracle URLs via SQLAlchemy, raw ODBC strings via pyodbc; write `{password}` in the string and the real one stays write-only |
319
+ | `aws` | ✅ | **Test & discover lists what your keys can reach** — every S3 bucket and CloudWatch log group — and each object picks its own job: *report* (default, nothing polled), *feed*, *tasks*, or *off*. Plus **any service call** as a report or agent tool. IAM keys or the server's own credential chain |
320
+ | `azure` | ✅ | same discovery for blob containers and Log Analytics workspaces across the subscriptions your app can see, each with its own report/feed/tasks picker — plus **any ARM path**. Reuses the Outlook card's app registration automatically; it just needs RBAC roles |
321
+ | `entra_*` | ✅ | **Entra ID on the same app registration**: people (with `accountEnabled`, so a disabled account never reads as active), a group's *transitive* members, sign-in activity, and licence SKUs with seats consumed vs spare — the unused-seat report. Test names which of these the app is actually permitted |
322
+ | `prometheus` / `datadog` | ✅ | PromQL instant queries (each series = a row of labels + value); Datadog monitor states, trouble sorted first — reports and agent tools |
323
+ | `winrm` | ✅ | run PowerShell on any machine you can RDP into; output → Timeline |
324
+ | `mcp` | ✅ | any MCP server's tool as a scheduled report |
325
+ | `sqlite` / `rest` / `rss` | ✅ | scheduled reports, AI summaries optional |
326
+ | `sharepoint_list` `google_sheets` `graphql` `smb_file` | 🗺 planned | one ~15-line executor away — PRs welcome |
327
+
328
+ Anything can also **push** items in: `POST /api/ingest/push` with
329
+ `{subject, body, from_email, channel}` — cron jobs, webhooks, other apps. The full API is
330
+ browsable at `/api/docs` while the server runs.
331
+
332
+ ## Development
333
+
334
+ ```bash
335
+ git clone https://github.com/ldbumble/taskuary && cd taskuary
336
+ pip install -e .[dev,mssql,desktop]
337
+ taskuary --debug # verbose console; every run also logs to ~/.taskuary/taskuary.log
338
+
339
+ pytest -q # 300 tests, no network or credentials needed
340
+
341
+ cd website # the React UI (React 18 + MUI, Vite)
342
+ npm install
343
+ npm run dev # dev server, proxies /api to a running taskuary on :7787
344
+ npm run build # emits taskuary/web/ (committed - pip installs need no node)
345
+
346
+ # the README hero: drive a seeded demo through the funnel, then assemble the GIF
347
+ npm i --no-save puppeteer-core
348
+ python seed_demo.py # with TASKUARY_HOME pointed at a scratch dir
349
+ node hero_frames.mjs http://127.0.0.1:PORT # frames + per-frame delays
350
+ python hero_gif.py # -> docs/hero.gif (Pillow; no ffmpeg needed)
351
+
352
+ pip install -e .[build]
353
+ pyinstaller taskuary.spec # dist/Taskuary.exe - single-file desktop build
354
+ ```
355
+
356
+ Data lives in `~/.taskuary/` (override with `TASKUARY_HOME`): `taskuary.db` (SQLite),
357
+ `config.toml`, `taskuary.log`. For LAN use set `[server].token` in config and send it as
358
+ the `X-Taskuary-Token` header. CI runs the test matrix on Windows / Linux / macOS ×
359
+ py3.10 / 3.12 on every push and pull request, plus the web build. The single-file
360
+ exe is built on push to master.
361
+
362
+ ## Status / roadmap
363
+
364
+ Early (v0.2.0) and moving fast — said up top too, because it should not be something you find
365
+ out at the bottom.
366
+
367
+ - [x] AI-gated triage, review queue, resumable agent sessions, hash-chained audit
368
+ - [x] Reports tab: source → query → AI summary → Timeline pipelines
369
+ - [x] Connectors catalog with setup wizards: channels, AI, GitHub, SQL Server
370
+ - [x] Agent presets (Claude Code, Codex, Gemini, Cursor, Copilot) with one-click Test
371
+ - [x] Desktop app + single-file Windows exe
372
+ - [x] Interactive agent terminal (pty + websocket + xterm.js) and hand-anything-to-an-agent
373
+ - [x] Per-connection roles (trigger / report / tool) and **authority** (read / write / admin) over what agents may do through one
374
+ - [x] GitHub issues as an inbound trigger
375
+ - [x] Configurable triage brain — a cloud key or your CLI agent — and `/api/tools/run`
376
+ - [x] Self-learning triage: LEARNED.md distilled from your verdicts, with strength + evidence per line
377
+ - [x] Generate from history: TRIAGE.md and STYLE.md bootstrapped from 3 months of your own mailbox
378
+ - [x] Data connections: any database by connection string, AWS, Azure, Prometheus, Datadog
379
+ - [x] Developer inboxes: GitLab, Azure DevOps, Linear, Trello, Notion, Discord, Sentry, PagerDuty
380
+ - [x] Board inboxes: Jira, Asana, Monday.com, ClickUp, Todoist
381
+ - [x] The round trip: answers typed into the working agent's session; reviews decided from your phone
382
+ - [x] Automation ideas: a weekly report mining your own funnel for the next thing worth automating
383
+ - [x] Proof of work on every review: files changed, the tests that actually ran, CI, attempts — and what is *not* evidenced
384
+ - [x] Closed git loop: a draft PR **or a direct push to the default branch** (your call), CI watched either way, a red build handed back to the agent that wrote the code
385
+ - [x] Safe outputs: agents *propose* high-impact actions (PR, public comment, close, tool run); code validates, you approve
386
+ - [ ] Follow-ups — track what YOU are owed: a sent reply or hand-off that asked a question starts a quiet timer; no answer in N days surfaces a "nudge?" with the follow-up drafted
387
+ - [ ] Earned autonomy — auto-answer offered per pattern once your unedited approvals prove the draft (with the receipts, revocable per rule); today auto_answer is a policy you write by hand
388
+ - [ ] Teams as a phone-approvals channel (Telegram and WhatsApp carry it today)
389
+ - [ ] Remaining report connectors (table above)
390
+ - [ ] Tray + notifications for the desktop shell
391
+
392
+ ## Contributing
393
+
394
+ The single best first PR is a **report connector — ~15 lines** turns any system
395
+ (Postgres, Google Sheets, Jira, Prometheus…) into an AI-summarized Timeline report.
396
+ [CONTRIBUTING.md](CONTRIBUTING.md) has the recipe, the repo map, and the dev setup;
397
+ [good first issues](https://github.com/ldbumble/taskuary/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
398
+ are seeded and waiting. Tests run offline in ~2 seconds — no credentials needed to hack
399
+ on the funnel. Please read the [Code of Conduct](CODE_OF_CONDUCT.md); security issues go
400
+ through [SECURITY.md](SECURITY.md), not a public issue.
401
+
402
+ ## Looking for collaborators
403
+
404
+ Taskuary is early and I'd rather build it with people than alone. I'm looking for a few
405
+ regulars, not one-off drive-bys — though a single good PR is very welcome too.
406
+
407
+ **Where help goes furthest right now:**
408
+
409
+ - **Connectors** — every row marked 🗺 in the table above, plus whatever system runs *your*
410
+ day. One executor function and you own that integration.
411
+ - **Non-Windows polish** — see the note by the install instructions: development happens on
412
+ Windows. macOS and Linux users who hit rough edges (and fix them) are gold.
413
+ - **Agent CLIs beyond the presets** — if your CLI needs different flags to run headless,
414
+ that's a preset PR and a paragraph in the README.
415
+ - **Design and UX** — this was built by one person with strong opinions and no designer.
416
+ Argue with them.
417
+ - **Real-world war stories** — run it on your own inbox for a week and open an issue about
418
+ what broke, what felt wrong, or what you kept doing by hand anyway. That feedback shapes
419
+ the roadmap more than feature requests do.
420
+
421
+ Want a bigger piece? Say so in an issue — follow-up tracking, a notifications/tray shell,
422
+ and a plugin API for connectors are all on the roadmap and all up for grabs. Interested in
423
+ maintaining an area long-term? Open an issue titled `maintainer: <area>` and let's talk.
424
+