Appendice · Bonus track

Taskwarrior per un freelance che sviluppa per il web

Un'appendice pratica: come configurare e usare Taskwarrior nello scenario reale di chi fattura a ore, gestisce più clienti in parallelo, vive di richieste che arrivano via mail e Slack, e ha bisogno di sapere a fine mese dove sono andate le sue ore. Cinque scenari concreti più un setup di partenza.

00
Setup · Configurazione una tantum

Modellare la realtà di un freelance web

Prima dei task, l'impalcatura: come strutturare progetti, contesti, UDA e tag in modo che il sistema rispecchi davvero il modo in cui lavori.

Le scelte sotto sono una proposta concreta, non un dogma. L'idea è darti una base ragionevole su cui partire e che puoi raffinare nelle settimane successive.

Progetti — uno per cliente, sottoprogetti per ingaggio. Il punto come separatore gerarchico ti permette di filtrare a qualsiasi livello.

struttura-progetti
# Tre clienti attivi, ciascuno con uno o più ingaggi cliente.acme.sitoshop # e-commerce in corso cliente.acme.manutenzione # retainer mensile cliente.beta.landing cliente.gamma.api # E poi i progetti "studio", che non sono di nessun cliente studio.amministrazione # fatturazione, tasse, contratti studio.marketing # sito proprio, portfolio, newsletter studio.formazione # corsi, libri, sperimentazioni

Contesti — separare lavoro retribuito da tutto il resto. Due contesti bastano. Eventualmente un terzo per la vita personale.

~/contesti-freelance
$task context define billable project.startswith:cliente $task context define studio project.startswith:studio $task context define personal project.startswith:personale # Al mattino, durante le ore "produttive" $task context billable # Il venerdì pomeriggio, quando fatturi $task context studio

UDA — i campi che ti servono davvero come freelance. Tre UDA cambiano l'esperienza:

~/.taskrc · UDA freelance
# Tempo stimato per il task (in ore, numerico) uda.estimate.type=numeric uda.estimate.label=Est(h) # Tariffa oraria del task (alcuni clienti hanno tariffe diverse) uda.rate.type=numeric uda.rate.label=€/h # Tipo di attività: utile per i report fine mese uda.kind.type=string uda.kind.label=Kind uda.kind.values=dev,design,meeting,review,deploy,admin

Tag operativi. Pochi, ma usati con disciplina:

01
Scenario · Onboarding

Arriva un nuovo ingaggio: trasformare un preventivo in task

Hai appena firmato un'offerta per un sito vetrina a 6 sezioni. 40 ore preventivate, 45 €/h, consegna tra 4 settimane. Come la fai entrare in Taskwarrior in modo che si "gestisca da sola"?

~/nuovo-ingaggio
# Setup del progetto + macro-task $task add "Kickoff e briefing" project:cliente.delta.vetrina \ rate:45 kind:meeting estimate:1.5 due:tomorrow $task add "Design — wireframe + moodboard" project:cliente.delta.vetrina \ rate:45 kind:design estimate:6 due:1week $task add "Setup repo + CI" project:cliente.delta.vetrina \ rate:45 kind:dev estimate:2 +chore $task add "Dev — 6 sezioni del sito" project:cliente.delta.vetrina \ rate:45 kind:dev estimate:24 +feature $task add "Deploy + handover" project:cliente.delta.vetrina \ rate:45 kind:deploy estimate:3 due:2026-06-12 # Le dipendenze: dev dopo design, deploy dopo dev $task project:cliente.delta.vetrina list # annota gli ID $task 22 modify depends:21 # dev dipende dal design $task 23 modify depends:22 # deploy dipende dal dev

Risultato: in due minuti hai un progetto pienamente strutturato. Le ore preventivate (estimate) ti permetteranno di confrontarle col tempo reale tracciato da Timewarrior (vedi scenario 3). I tag e i kind ti permetteranno di sezionare il consuntivo ("quante ore di design vs dev su questo ingaggio?").

Promemoria amministrativi del progetto. Aggiungi anche i task non operativi ma fondamentali:

~/admin-progetto
$task add "Inviare fattura acconto 30% — Delta" \ project:studio.amministrazione due:today +blocca-fattura $task add "Inviare fattura saldo — Delta" \ project:studio.amministrazione wait:2026-06-12 due:2026-06-15 $task add "Chiedere review/testimonial al cliente Delta" \ project:studio.marketing wait:2026-06-19 # una settimana dopo il deploy

Il wait: qui è fondamentale: la fattura di saldo non deve comparire nelle viste prima del deploy, e la richiesta di testimonial deve spuntare automaticamente una settimana dopo. Hai appena creato tre promemoria che arriveranno da soli al momento giusto.

02
Scenario · Cattura veloce

Bug report che arriva da Slack alle 16:47

Un cliente ti scrive che il form di contatto non invia. Hai bisogno di catturare in 5 secondi, senza perdere il flusso, e di poter riprendere il task quando avrai finito quello in corso.

Il pattern: cattura subito, classifica dopo. Una riga e via.

~/cattura-veloce
$task add "Form contatto non invia — Acme" +bug pri:H \ project:cliente.acme.sitoshop Created task 42. # Annota il link al messaggio Slack senza interrompere il flusso $task 42 annotate "https://acme.slack.com/archives/C123/p1747234..." $task 42 annotate "Marco dice: dal 14/05 il form sembra muto, niente mail in arrivo"

Adesso un alias di shell dedicato a questa cattura per ridurre l'attrito a zero. Aggiungilo a .zshrc o .bashrc:

~/.zshrc
# Cattura bug: bug "descrizione" cliente bug() { task add "$1" +bug pri:H project:cliente.$2 } # Ora dal terminale: bug "Form contatto muto" acme.sitoshop

Il triage al ritorno. Quando finisci il task in corso, rivedi i bug accumulati e decidi quando attaccarli:

~/triage
$task +bug status:pending ready # vedi tutti i bug attivi non bloccati, ordinati per urgenza # Stimi 1 ora e decidi di farlo domani mattina $task 42 modify estimate:1 scheduled:tomorrow due:tomorrow+1day
03
Scenario · Tempo fatturabile

"Quante ore ho fatto per Acme questo mese?"

La domanda più importante per chi fattura a ore. Con l'integrazione Taskwarrior + Timewarrior, la risposta è un comando.

Prerequisito: aver installato Timewarrior e copiato l'hook ufficiale on-modify.timewarrior in ~/.task/hooks/ (vedi lezione 10). Da quel momento ogni task start avvia anche il timer.

~/giornata-tipo
# Inizio a lavorare sul bug del form $task 42 start Started task 42. Timewarrior is now tracking. # Pausa pranzo — fermo entrambi $task 42 stop # Pomeriggio: lo finisco $task 42 start $# ...due ore di lavoro... $task 42 done Completed task 42. Timewarrior stopped.

Report di fine mese per cliente. Timewarrior eredita automaticamente tag e progetto dal task, quindi puoi interrogarlo per cliente:

~/report-mensile
# Sommario del mese per Acme $timew summary :month cliente.acme.sitoshop Wk Date Day Tags Total W19 2026-05-04 Mon cliente.acme.sitoshop, +bug 2:34:12 W19 2026-05-06 Wed cliente.acme.sitoshop, +feature 4:12:00 ... 27:48:30 # Ripartito per "kind" — quanto design vs dev? $timew summary :month cliente.acme.sitoshop :ids

Confronto stima vs consuntivo. Una piccola query Taskwarrior + un calcolo: per ogni task chiuso ti dice quanto avevi stimato. L'ora reale la prendi da Timewarrior. Dopo 3-4 progetti vedrai un pattern, e potrai correggere le stime future di un coefficiente realistico (di solito tra 1.4× e 2× per chi inizia).

04
Scenario · Palla in mano al cliente

Mando una mail di richiesta feedback — e poi me ne dimentico

Hai inviato le mockup, hai chiesto l'OK al cliente, e adesso che cosa? Il follow-up è la zona grigia che fa morire la metà dei progetti freelance.

Il pattern: ogni volta che la palla passa al cliente, crei subito un task di follow-up con wait: sulla data in cui ricomincerai a rompergli le scatole se non risponde.

~/follow-up
# Marco il task come in attesa $task 21 modify +attesa-cliente $task 21 annotate "Mail inviata 14/05 ore 11:30 — chiesto OK su 3 mockup" # Promemoria attivo: tra 3 giorni lavorativi se non hanno risposto $task add "Follow-up mockup Beta se nessuna risposta" \ project:cliente.beta.landing wait:3days due:5days

Un report dedicato ai task che stagnano. Aggiungi questo al .taskrc:

~/.taskrc · report "limbo"
report.limbo.description=Task in attesa di risposta cliente report.limbo.columns=id,project,tags,entry.age,description report.limbo.labels=ID,Cliente,Tags,Da,Descrizione report.limbo.filter=status:pending and +attesa-cliente report.limbo.sort=entry+ # i più vecchi in cima # Lunedì mattina: $task limbo ID Cliente Tags Da Descrizione 21 cliente.beta.landing +attesa-cliente 9d Mockup home — 3 varianti 35 cliente.acme.sitoshop +attesa-cliente 14d Logo finale alta risoluzione

Vedere "14 giorni" vicino a un task è il momento in cui decidi se insistere, sollecitare per telefono, o mettere il progetto in pausa ufficialmente. La cosa importante è che non te ne dimentichi.

05
Scenario · Pianificazione

Il rito del venerdì pomeriggio (e del lunedì mattina)

Due abitudini brevi cambiano completamente la sensazione di controllo sui progetti. Una review chiude la settimana, un plan la apre.

Venerdì — review. Cosa è stato chiuso? Cosa è in ritardo? Cosa si è insabbiato?

~/.taskrc · report "review"
report.review.description=Bilancio della settimana report.review.columns=id,project,kind,description,end.relative report.review.labels=ID,Cliente,Tipo,Descrizione,Chiuso report.review.filter=status:completed and end.after:7days-ago report.review.sort=project+,end+
~/rito-del-venerdi
$task review # Cosa ho chiuso questa settimana — utile per la nota fatture e per autocompiacersi $task overdue # Cosa sto trascinando: decido di rischedulare o ammettere che lo lascio andare $task limbo # Chi devo sollecitare lunedì mattina

Lunedì — plan. Una "morning view" pensata per un freelance: cosa è già scaduto (panico controllato), cosa devo fare oggi, cosa ho in attesa di risposta, e i prossimi 3 task per urgenza.

~/.zshrc
alias day='clear && \ echo "═══ RITARDI ═══" && task overdue 2>/dev/null; \ echo "\n═══ OGGI ═══" && task due.before:tomorrow status:pending; \ echo "\n═══ ATTESA CLIENTI ═══" && task limbo 2>/dev/null; \ echo "\n═══ PROSSIMI 3 ═══" && task next limit:3' # Il rito di apertura della giornata, in un comando $day

Quattro blocchi, tre minuti di lettura, e sai esattamente come deve essere costruita la giornata. È poco, ma fatto ogni lunedì cambia letteralmente quanto bene riesci a tenere insieme tre o quattro clienti in parallelo senza che nessuno si senta abbandonato.

$ task done corso-completo

I cinque scenari coprono il 90% della giornata di un freelance che sviluppa per il web: onboarding, cattura veloce, tracking del tempo, follow-up clienti, rito settimanale. Tutto il resto sono varianti.

Non importa quanto sia raffinato il setup il primo giorno. Importa che parta — e che ogni mese aggiungi una piccola cosa: un alias che ti serviva, un report che ti faceva comodo, un hook che ti toglie un click. In sei mesi avrai uno strumento che sembra costruito sulla tua testa, perché lo è.