{"id":47766924,"url":"https://github.com/00sapo/taskcheck","last_synced_at":"2026-04-03T07:30:47.501Z","repository":{"id":261263544,"uuid":"883783146","full_name":"00sapo/taskcheck","owner":"00sapo","description":"A non-AI automatic scheduler for taskwarrior (i.e. alternative to skedpal/timehero/flowsavvy/reclaim/trevor/motion)","archived":false,"fork":false,"pushed_at":"2025-06-07T09:01:23.000Z","size":253,"stargazers_count":18,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-07T10:18:02.471Z","etag":null,"topics":["taskwarrior"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/00sapo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-11-05T15:06:35.000Z","updated_at":"2025-06-07T09:01:26.000Z","dependencies_parsed_at":"2025-03-04T18:24:57.701Z","dependency_job_id":"048e14a2-68e6-4147-b72b-b4d29f66cb6f","html_url":"https://github.com/00sapo/taskcheck","commit_stats":null,"previous_names":["00sapo/taskcheck"],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/00sapo/taskcheck","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/00sapo%2Ftaskcheck","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/00sapo%2Ftaskcheck/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/00sapo%2Ftaskcheck/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/00sapo%2Ftaskcheck/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/00sapo","download_url":"https://codeload.github.com/00sapo/taskcheck/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/00sapo%2Ftaskcheck/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31342111,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T06:57:30.245Z","status":"ssl_error","status_checked_at":"2026-04-03T06:57:29.849Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["taskwarrior"],"created_at":"2026-04-03T07:30:47.442Z","updated_at":"2026-04-03T07:30:47.492Z","avatar_url":"https://github.com/00sapo.png","language":"Python","readme":"\u003cdiv align=\"center\"\u003e\n  \n```\n########    ###     ######  ##    ##  ######  ##     ## ########  ######  ##    ## \n   ##      ## ##   ##    ## ##   ##  ##    ## ##     ## ##       ##    ## ##   ##  \n   ##     ##   ##  ##       ##  ##   ##       ##     ## ##       ##       ##  ##   \n   ##    ##     ##  ######  #####    ##       ######### ######   ##       #####    \n   ##    #########       ## ##  ##   ##       ##     ## ##       ##       ##  ##   \n   ##    ##     ## ##    ## ##   ##  ##    ## ##     ## ##       ##    ## ##   ##  \n   ##    ##     ##  ######  ##    ##  ######  ##     ## ########  ######  ##    ## \n```\n\n\u003e _A non-AI automatic scheduler for taskwarrior (i.e. alternative to skedpal / timehero / flowsavvy / reclaim / trevor / motion)_\n\n  ![immagine](https://github.com/user-attachments/assets/27b83bb1-7a50-4923-a453-0a958fbe11ed)\n\n\u003c/div\u003e\n\nThis is a taskwarrior extension that automatically schedules your tasks based on your working hours,\nestimated time, and calendar events, finding an optimal time to work on each task and match all your\ndeadlines.\n\n\u003e [!IMPORTANT]\n\u003e Due to the new synchronization method of TaskWarrior and to the lack of simple Android integration, I have moved to Super Productivity.\n\u003e I won't develop this software anymore, but it is pretty stable, as I used it for about 1 year.\n\u003e\n\u003e I moved this same idea in a Super Productivity plugin: https://github.com/00sapo/sp-autoplan\n\n## Features\n\n- [x] **Use arbitrarily complex time maps for working hours**\n- [x] Block scheduling time using iCal calendars (meetings, vacations, holidays, etc.)\n- [x] **Parallel scheduling algorithm for multiple tasks, considering urgency and dependencies**\n- [x] Dry-run mode: preview scheduling without modifying your Taskwarrior database\n- [x] Custom urgency weighting for scheduling (via CLI or config)\n- [x] **Auto-fix scheduling to match due dates**\n- [x] Force update of iCal calendars, bypassing cache\n- [x] Simple, customizable reports for planned and unplanned tasks\n- [x] Emoji and attribute customization in reports\n- [ ] Use Google API to access calendars\n- [ ] Export tasks to iCal calendar and API calendars\n\n## Install\n\n1. `pipx install taskcheck`\n2. `taskcheck --install`\n\n## How does it work\n\nThis extension parses your pending and waiting tasks sorted decreasingly by urgency and tries to schedule them in the future.\nIt considers their estimated time to schedule all tasks starting from the most urgent one.\n\n#### UDAs\n\nTaskcheck leverages two UDAs, `estimated` and `time_map`. The `estimated` attribute is\nthe expected time to complete the task in hours. The `time_map` is a comma-separated list of strings\nthat indicates the hours per day in which you will work on a task (e.g. `work`, `weekend`, etc.).\nThe exact correspondence between the `time_map` and the hours of the day is defined in the configuration\nfile of taskcheck. For instance:\n\n```toml\n[time_maps]\n# get an error)\n[time_maps.work]\nmonday = [[9, 12.30], [14, 17]]\ntuesday = [[9, 12.30], [14, 17]]\n# ...\n```\n\n#### They say it's an \"AI\"\n\nTaskcheck will also parse online iCal calendars (Google, Apple, etc.) and will match them with your time maps.\nIt will then modify the Taskwarrior tasks by adding the `completion_date` attribute with the expected\ndate of completion and the `scheduled` attribute with the date in which the task is expected to\nstart.\n\nIt will also print a red line for every task whose `completion_date` is after its `due_date`.\n\nIn general, it is recommended to run taskcheck rather frequently and at least once at the beginning\nof your working day.\n\n#### Reports\n\nYou can also print simple reports that exploit the `scheduling` UDA filled by Taskcheck to grasp\nhow much time you have to work on which task in which day. For\ninstance:\n\n- `taskcheck -r today` will show the tasks planned for today\n- `taskcheck -r 1w` will show the tasks planned for the next week\n\n## Configuration\n\n`taskcheck --install` allows you to create required and recommended configurations for\nTaskwarrior. It will also generate a default configuration file for taskcheck.\n\nBelow is an example of a taskcheck configuration file, with all relevant options:\n\n```toml\n[time_maps]\n# Define your working hours for each named time map (in 24h format, e.g. 9.5 = 9:30)\n[time_maps.work]\nmonday = [[9, 12.30], [14, 17]]\ntuesday = [[9, 12.30], [14, 17]]\nwednesday = [[9, 12.30], [14, 17]]\nthursday = [[9, 12.30], [14, 17]]\nfriday = [[9, 12.30], [14, 17]]\n\n[time_maps.weekend]\nsaturday = [[9, 12.30]]\nsunday = [[9, 12.30]]\n\n[scheduler]\ndays_ahead = 1000         # How far to go with the schedule (lower values = faster computation)\nweight_urgency = 1.0      # Default weight for urgency in scheduling (overridable via CLI)\n# if weight_urgency is set to 0, only due urgency is considered\n# by default, this factor is automatically reduced if some task cannot be scheduled in time,\n# leading to tasks with due dates being prioritized (see --no-auto-adjust-urgency)\n\n[calendars]\n# iCal calendars can be used to block your time and make the scheduling more precise\n[calendars.1]\nurl = \"https://your/url/to/calendar.ics\"\nexpiration = 0.08         # In hours (0.08 hours ≈ 5 minutes)\ntimezone = \"Europe/Rome\"  # If set, force timezone for this calendar (see TZ database)\n\n[calendars.holidays]\nurl = \"https://www.officeholidays.com/ics-clean/italy/milan\"\nevent_all_day_is_blocking = true\nexpiration = 720          # In hours (720 hours = 30 days)\n\n[report]\ninclude_unplanned = true\nadditional_attributes = [\"estimated\", \"due\", \"urgency\"]           # Extra attributes to show in the report\nadditional_attributes_unplanned = [\"due\", \"urgency\"]               # Extra attributes for unplanned tasks\nemoji_keywords = {\"meet\"=\":busts_in_silhouette:\", \"review\"=\":mag_right:\"} # Map keywords to emoji\n```\n\n### Configuration Options\n\n- **[scheduler]**\n  - `days_ahead`: How many days ahead to schedule tasks.\n  - `weight_urgency`: Default weight for urgency in scheduling (0.0 to 1.0). Can be overridden with `--urgency-weight`.\n- **[calendars]**\n  - `url`: iCal URL to block time.\n  - `expiration`: Cache expiration in hours.\n  - `timezone`: (Optional) Force a timezone for this calendar.\n  - `event_all_day_is_blocking`: (Optional, bool) Treat all-day events as blocking.\n- **[report]**\n  - `include_unplanned`: Show unplanned tasks in a separate section.\n  - `additional_attributes`: Extra columns to show in the report.\n  - `additional_attributes_unplanned`: Extra columns for unplanned tasks.\n  - `emoji_keywords`: Map keywords in task descriptions to emoji.\n\n## Algorithm\n\nThe algorithm simulates what happens if you work on a task for a certain time on a given day.\n\nFor each day X starting from today, it sorts the tasks by decreasing urgency.\nIt start from the most urgent tasks that can be allocated on day X depending on the task's\n`time_map` and on your calendars. It allocates a few number of hours to the task,\nthen recomputes the urgencies exactly as Taskwarrior would do\nif it was running on day X. Having recomputed the urgencies, it restarts.\n\nIf after 2 hours a long task has decreased its urgency, it will be noticed and the newer most urgent\ntask will get scheduled in its place.\n\nFor `today`, taskcheck will skip the hours in the past -- i.e. if you're running at 12 pm, it will\nskip all the available slots until 12 pm.\n\nThe maximum time that is allocated at each attempt is by default 2 hours\n(or less if the task is shorter), but you can change it by tuning the Taskwarrior UDA `min_block`.\n\nAfter the scheduling is done, if any task has a `completion_date` after its `due_date`, the\n`weight_urgency` factor is reduced by 0.1 and the scheduling is repeated, until all tasks\nare scheduled before their due dates or the `weight_urgency` factor reaches 0.\n\n## Tips and Tricks\n\n- You can exclude a task from being scheduled by removing the `time_map` or `estimated` attributes.\n- You can see tasks that you can execute now with the `task ready` report.\n\n## CLI Options\n\n```\nusage: __main__.py [-h] [-v] [-i] [-r REPORT] [-s] [-f] [--taskrc TASKRC] [--urgency-weight URGENCY_WEIGHT] [--dry-run] [--no-auto-adjust-urgency]\n\noptions:\n  -h, --help            show this help message and exit\n  -v, --verbose         Increase output verbosity.\n  -i, --install         Install the UDAs, required settings, and default config file.\n  -r REPORT, --report REPORT\n                        Generate a report of the tasks based on the scheduling; can be any Taskwarrior datetime specification (e.g. today, tomorrow, eom, som, 1st, 2nd, etc.). It is considered as `by`, meaning that the report will be\n                        generated for all the days until the specified date and including it.\n  -s, --schedule        Perform the scheduling algorithm, giving a schedule and a scheduling UDA and alerting for not completable tasks\n  -f, --force-update    Force update of all ical calendars by ignoring cache expiration\n  --taskrc TASKRC       Set custom TASKRC directory for debugging purposes\n  --urgency-weight URGENCY_WEIGHT\n                        Weight for urgency in scheduling (0.0 to 1.0), overrides config value. When 1.0, the whole Taskwarrior urgency is used for scheduling. When 0.0, the Taskwarrior urgency is reduced to only due urgency.\n  --dry-run             Perform scheduling without modifying the Taskwarrior database, useful for testing\n  --no-auto-adjust-urgency\n                        Disable automatic reduction of urgency weight … (default: enabled)\n```\n\n### Examples\n\n- `taskcheck --schedule`  \n  Run the scheduler and update your Taskwarrior tasks.\n- `taskcheck --schedule --dry-run`  \n  Preview the schedule without modifying your database.\n- `taskcheck --schedule --urgency-weight 0.5`  \n  Use a custom urgency weighting for this run.\n- `taskcheck --schedule --no-auto-adjust-urgency`  \n  Avoid the automatically reduction of urgency weight if tasks can't be scheduled before their due dates.\n- `taskcheck --report today`  \n  Show the schedule for today.\n- `taskcheck --report 1w`  \n  Show the schedule for the next week.\n- `taskcheck --force-update`  \n  Force refresh of all iCal calendars, ignoring cache.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F00sapo%2Ftaskcheck","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F00sapo%2Ftaskcheck","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F00sapo%2Ftaskcheck/lists"}