惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
Google Developers Blog
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
Recent Announcements
Recent Announcements
阮一峰的网络日志
阮一峰的网络日志
IT之家
IT之家
A
About on SuperTechFans
量子位
Engineering at Meta
Engineering at Meta
B
Blog
The Cloudflare Blog
博客园 - 【当耐特】
Hugging Face - Blog
Hugging Face - Blog
Y
Y Combinator Blog
J
Java Code Geeks
D
DataBreaches.Net
aimingoo的专栏
aimingoo的专栏
T
Tailwind CSS Blog
H
Help Net Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
V2EX
Stack Overflow Blog
Stack Overflow Blog
C
Check Point Blog
酷 壳 – CoolShell
酷 壳 – CoolShell

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
How to organize your daily task with Task Warrior
julio · 2026-05-07 · via DEV Community

Have some months that I am trying to organize my daily tasks, and the first thing that I tried was to create a time board, where I put what I wanted to do on my day.

First I started with 50 minutes of computer science where I studied things like Data Structures, Algorithms, etc.

Then after that I reserve 50 minutes to learn about Hacking, things like how can I secure systems, the basics things, like network, tools, etc.

For improve my english and speaking skills I read a book for 30 minutes, in high voice.

Another important things is to make exercises for improve my body and mind, then some push-ups, squat, etc.

I decided too to make some networking in Linkedin, but I need to confess that I don't do it any time yet, but I will.

But, you know the problem with it? the time that I reserved for each thing, although is good to have a time limit, sometimes I was very focused studding about computer science and then the alarm trigger and I lost all the focus, or sometimes I am not focused and then the alarm trigger and I see that i lost the 50 minutes thinking about another thing or doing another thing.

Then I decided to stop using timers and start finishing tasks and subtasks, basically instead of read 30 minutes every day, I will read 5 pages per day, instead of 50 minutes of computer science I will choose one or two topics and study.

But where I will organize those tasks? Currently my full setup is in the terminal, my code editor (nvim), my git (lazygit), my code agent (opencode), docker (lazydocker).

And I discovered a tool called Task Warrior, that is a simple task organizer but I have a problem, creating tasks and subtasks in the Task Warrior is king boring, then why not create an automation for it?

Basically we have two scripts, one in Bash and the other in Python.

The script in Bash will do the following:

  1. Read a MD file
  2. Get check-boxes and convert in Tasks
  3. Case the checkbox is a sub checkbox then it is a child or subtask.
  4. In the end I need to know which task was added then I put a logic for insert the UUID from the Task into the markdown line of the task
#!/usr/bin/env bash

set -euo pipefail

if ! command -v awk >/dev/null; then
  echo "awk is required"
  exit 1
fi

if [ $# -lt 1 ]; then
  echo "Usage: $0 <markdown-file> <project-name>"
  exit 1
fi

FILE="$1"

if [ ! -f "$FILE" ]; then
  echo "File not found: $FILE"
  exit 1
fi

PROJECT="${2:-}"

echo "=== Taskwarrior Markdown Importer ==="

if [ -z "$PROJECT" ]; then
  while true; do
    read -rp "Project name: " INPUT_PROJECT

    if [ ! -z "$INPUT_PROJECT" ]; then
      PROJECT="$INPUT_PROJECT"
      break
    fi
  done
fi

echo "Project: $PROJECT, File: $FILE"

get_task() {
  awk -v line="$1" '
    BEGIN {
      gsub(/\r/, "", line)
      gsub(/\t/, "    ", line)

      match(line, /^ */)
      indent = int(RLENGTH / 4)

      trimmed = substr(line, RLENGTH + 1)

      checked = "false"

      if (match(trimmed, /^[-*+][[:space:]]*\[([xX ])\][[:space:]]*/)) {
        if (substr(trimmed, RSTART+2, 3) ~ /[xX]/) {
          checked = "true"
        }

        trimmed = substr(trimmed, RLENGTH + 1)

        while (match(trimmed, /\[\[[^]]+\]\]/)) {
          link = substr(trimmed, RSTART + 2, RLENGTH - 4)  # content inside [[ ]]
          n = split(link, tmp, /\|/)
          replacement = tmp[n]  # last part (after | if exists)

          trimmed = substr(trimmed, 1, RSTART - 1) replacement substr(trimmed, RSTART + RLENGTH)
        }

        gsub(/  +/, " ", trimmed)

        n = split(trimmed, parts, /;;/)

        description = parts[1]
        priority = (n >= 2 && parts[2] != "" ? parts[2] : "L")
        due = (n >= 3 && parts[3] != "" ? parts[3] : "today")

        printf "%d\x1f%s\x1f%s\x1f%s\x1f%s\n",
        indent, checked, description, priority, due
      }
    }'
}

insert_uuid_on_file() {
  local file="$1"
  local lineno="$2"
  local uuid="$3"

  local short="${uuid:0:8}"

  if sed -n "${lineno}p" "$file" | grep -q "task:"; then
    return
  fi

  sed -i "${lineno}s|\$| <!-- task:${short} -->|" "$file"
}

IGNORED=()

PCHECKED="false"
PID=""
CID=""
UUID=""

tmp=$(mktemp)
cp "$FILE" "$tmp"

i=0

while IFS= read -r line; do
  ((i += 1))

  task=$(get_task "$line")

  IFS=$'\x1f' read -r indent checked description priority due <<<"$task"

  if [[ -z "${description// /}" ]]; then
    continue
  fi

  child="false"

  if [[ "$indent" -gt 0 ]]; then
    child="true"
  else
    PCHECKED="$checked"
  fi

  if [[ $checked = "true" || $child = "true" && $PCHECKED = "true" || "$line" =~ task: ]]; then
    IGNORED+=("$description|$priority|$due")

    continue
  fi

  ID=$(task add "$description" project:"$PROJECT" priority:"$priority" due:"$due" mdfile:"$FILE" |
    grep -oP 'Created task \K[0-9]+')

  if [[ "$child" = "false" ]]; then
    PID="$ID"
  else
    CID="$ID"

    task "$CID" modify +P"$PID" >/dev/null

    task "$PID" modify depends:"$CID" >/dev/null
  fi

  UUID=$(task _get "$ID".uuid)

  insert_uuid_on_file "$FILE" "$i" "$UUID"

  # echo "$indent|$checked|$description|$priority|$due"
done <"$tmp"

rm "$tmp"

echo "=== IGNORED ==="
printf "%s\n" "${IGNORED[@]}"
echo "=== === === ==="

Enter fullscreen mode Exit fullscreen mode

You need awk installed for use it, and I this only work in Linux and MacOS.

And you can run with ./taskmd.sh <path/to/file.md> <project_name (optional)>

In my case I created a function in my fish shell for execute this script, then I don't need to put the path to the script, maybe it can be a alias in the terminal too.

And the Python is not really necessary in this logic, cause it only do a simple logic of when I finish some task in the Task Warrior this script will be executed as a hook, and It will check the checkbox in the Markdown file.

#!/usr/bin/env python3

import json
import re
import sys
from pathlib import Path

def update_line(line: str, uuid: str, status: str):
    if f"task:{uuid}" not in line:
        return line, False

    # line = re.sub(r"\s*<!--\s*task:" + re.escape(uuid) + r"\s*-->", "", line)

    if status in ("completed", "deleted"):
        line = re.sub(r"\[\s\]", "[x]", line)
    else:
        line = re.sub(r"\[[xX]\]", "[ ]", line)
    return line, True

def main():
    _ = json.loads(sys.stdin.readline())
    new_task = json.loads(sys.stdin.readline())

    status = new_task.get("status", "")

    if status not in ("completed", "deleted"):
        print(json.dumps(new_task))
        return

    uuid = new_task.get("uuid", "")
    if not uuid:
        print(json.dumps(new_task))
        return

    uuid_short = uuid[:8]

    mdfile = new_task.get("mdfile")
    if not mdfile:
        print(json.dumps(new_task))
        return

    path = Path(mdfile)
    if not path.exists():
        print(json.dumps(new_task))
        return

    lines = path.read_text().splitlines()
    changed = False

    for i, line in enumerate(lines):
        new_line, matched = update_line(line, uuid_short, new_task.get("status"))
        if matched:
            lines[i] = new_line
            changed = True
            break

    if changed:
        path.write_text("\n".join(lines) + "\n")

    print(json.dumps(new_task))

if __name__ == "__main__":
    main()

Enter fullscreen mode Exit fullscreen mode

This python script need to stay in ~/.task/hooks with name like on-modify.<anyname>.pyon Linux case, you need to verify in Windows where this paste need to be.

And you need to add those lines in the .taskrc file, that on Linux, will stay in the ~ directory.

uda.mdfile.type=string
uda.mdfile.label=File

Enter fullscreen mode Exit fullscreen mode

In that way I can convert markdown files, that is very simple to create in tasks on my Task Warrior.

The task warrior you can download here and I recommend to use the Task Warrior TUI for have a better visualization in the terminal.

Is that, have a nice day, and see you soon :)