{"id":51854083,"url":"https://github.com/marcoarnulfo/clickup-cli","last_synced_at":"2026-07-26T01:00:32.671Z","repository":{"id":372491889,"uuid":"1307703019","full_name":"marcoarnulfo/clickup-cli","owner":"marcoarnulfo","description":"Terminal TUI for ClickUp time tracking \u0026 billing: monthly hours reports (self + team), per-list rates, billable amounts, and CSV/JSON/Markdown export. Written in Go.","archived":false,"fork":false,"pushed_at":"2026-07-24T23:24:34.000Z","size":4704,"stargazers_count":6,"open_issues_count":62,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-25T00:18:58.613Z","etag":null,"topics":["billing","bubbletea","charmbracelet","cli","clickup","go","go-cli","terminal","time-tracking","tui"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcoarnulfo.png","metadata":{"files":{"readme":"README.it.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.it.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-21T12:56:10.000Z","updated_at":"2026-07-24T16:25:07.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/marcoarnulfo/clickup-cli","commit_stats":null,"previous_names":["marcoarnulfo/clickup-cli"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/marcoarnulfo/clickup-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcoarnulfo%2Fclickup-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcoarnulfo%2Fclickup-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcoarnulfo%2Fclickup-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcoarnulfo%2Fclickup-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcoarnulfo","download_url":"https://codeload.github.com/marcoarnulfo/clickup-cli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcoarnulfo%2Fclickup-cli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35897093,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-25T02:00:06.922Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["billing","bubbletea","charmbracelet","cli","clickup","go","go-cli","terminal","time-tracking","tui"],"created_at":"2026-07-23T23:00:23.291Z","updated_at":"2026-07-26T01:00:32.652Z","avatar_url":"https://github.com/marcoarnulfo.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[English](README.md) · **Italiano**\n\n# clup — ClickUp Hours CLI\n\n[![CI](https://github.com/marcoarnulfo/clickup-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/marcoarnulfo/clickup-cli/actions/workflows/ci.yml)\n[![Ultima release](https://img.shields.io/github/v/release/marcoarnulfo/clickup-cli)](https://github.com/marcoarnulfo/clickup-cli/releases)\n[![Versione Go](https://img.shields.io/github/go-mod/go-version/marcoarnulfo/clickup-cli)](go.mod)\n[![Licenza: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![PR benvenute](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.it.md)\n\n\u003e TUI da terminale, veloce e colorata, per tirare giù le tue **ore mensili di ClickUp** — self o team — calcolare l'**importo da fatturare** e registrare tempo su ClickUp. Libera e open-source (MIT).\n\n## Funzionalità\n\n- 📊 **Report ore mensile** (self o intero team), raggruppabile per totale / task / lista / giorno / membro / tag.\n- 💶 **Motore di fatturazione**: tariffe orarie di default, per-lista, per-membro e per-(lista,membro), split billable/non billable, arrotondamento configurabile e subtotali per valuta (multi-valuta, senza FX).\n- 🎯 **Budget per lista** con vista burn-down, per vedere a colpo d'occhio quanto budget di ogni progetto è già fatturato.\n- ⏱️ **Log ore** su ClickUp dalla TUI: guidato (lista → task), da ID/URL del task, o con timer start/stop.\n- ⏲️ **Timer live e gestione delle voci**: un indicatore live nella home per il timer in corso, e un browser per modificare, cancellare, modificare i tag o consultare lo storico delle voci passate.\n- 📤 **Export** in CSV / JSON / Markdown / HTML self-contained (stampabile in PDF) / fattura CSV riga per riga.\n- ⌨️ TUI interattiva, guidata da tastiera (basata su [Charm](https://charm.sh) bubbletea).\n- 🔒 Il token resta in locale (file di config o variabile `CLICKUP_TOKEN`).\n\n## Demo\n\n![clup demo](docs/demo.gif)\n\nProvala senza account ClickUp: **`CLICKUP_DEMO=1 clup`** avvia una modalità demo con dati\nfittizi — che include anche il modello di fatturazione: split billable/non billable, due\nvalute di fatturazione, voci taggate e un budget per lista. Il GIF è registrato con\n[vhs](https://github.com/charmbracelet/vhs) da [`docs/demo.tape`](docs/demo.tape) (lancia\n`vhs docs/demo.tape` per rigenerarlo).\n\n## Requisiti\n\n- **[Go](https://go.dev/dl/) 1.26 o superiore** — serve solo per installare/compilare da sorgente.\n  - macOS: `brew install go` · Linux: [install ufficiale](https://go.dev/doc/install) · verifica con `go version`.\n- Un **token API personale ClickUp** (ClickUp → Settings → Apps → API Token).\n\n## Installazione\n\n### Binari precompilati\n\nScarica l'archivio per il tuo OS/arch dalla\n[latest release](https://github.com/marcoarnulfo/clickup-cli/releases/latest)\n(darwin/linux/windows × amd64/arm64), estrailo e metti `clup` nel `PATH`.\n\nOgni release include `checksums.txt`, firmato con cosign keyless — verifica con:\n\n```bash\ncosign verify-blob --bundle checksums.txt.sigstore.json checksums.txt\n```\n\n### Homebrew (macOS/Linux)\n\n```bash\nbrew install marcoarnulfo/tap/clup\n```\n\n### Scoop (Windows)\n\n```powershell\nscoop bucket add clup https://github.com/marcoarnulfo/scoop-bucket\nscoop install clup\n```\n\n### AUR (Arch Linux)\n\n```bash\nyay -S clup-bin   # o il tuo AUR helper preferito\n```\n\n_in attesa della registrazione della chiave AUR da parte del maintainer, tracciato in\n[#103](https://github.com/marcoarnulfo/clickup-cli/issues/103) — nel frattempo usa\nun binario precompilato._\n\n### go install (da sorgente)\n\nRichiede Go 1.26+:\n\n```bash\ngo install github.com/marcoarnulfo/clickup-cli/cmd/clup@latest\n```\n\nInstalla il binario `clup` in `$(go env GOPATH)/bin` (assicurati che sia nel `PATH`).\n\n\u003cdetails\u003e\n\u003csummary\u003eCompilare da sorgente\u003c/summary\u003e\n\n```bash\ngit clone https://github.com/marcoarnulfo/clickup-cli.git\ncd clickup-cli\ngo build -o clup ./cmd/clup\n./clup\n```\n\u003c/details\u003e\n\n## Avvio rapido\n\n1. **Installa** (vedi sopra) e lancia `clup`.\n2. Al primo avvio, il **wizard di setup** chiede token API, workspace, tariffa oraria opzionale e valuta — salvati nel file di config (vedi [Configurazione](#configurazione) per il percorso esatto).\n3. Scegli un **periodo** (`d`) e lo **scope** (`me`/`team`) nella home, premi `Enter` → il report. Premi `n` per loggare ore, `e` per esportare, `p` per le impostazioni di fatturazione (tariffe, valute, budget, arrotondamento), `b` per la vista burn-down dei budget.\n\n## Uso\n\nLancia `clup`. Al primo avvio parte un wizard di setup che chiede, in\nsequenza: il token API personale (lo trovi in ClickUp → Settings → Apps →\nAPI Token), il workspace da usare (scelto tra quelli visibili al token),\nuna tariffa oraria opzionale e la valuta (default `EUR`). Il risultato viene\nsalvato nel file di config (vedi [Configurazione](#configurazione)) e\nriusato ai lanci successivi.\n\nDalla home scegli un periodo e lo scope, poi `Enter` genera il report. Il report non\nè più limitato a un mese di calendario: premi `d` nella home per aprire il\n**selettore del periodo**, che offre preset (questo mese, mese scorso, ultimi 7\ngiorni, ultimi 30 giorni, questa settimana) più un periodo **personalizzato**\n`From`/`To` (date in formato `YYYY-MM-DD`). Nel report puoi\ncambiare raggruppamento, riesportare o tornare alla home. Se il token risulta\ninvalido o revocato durante l'uso, la TUI ripropone automaticamente il wizard\ndi setup.\n\n### Comandi nella TUI\n\n| Tasto | Schermata | Azione |\n|---|---|---|\n| `d` | Home | Apre il **selettore del periodo** (preset + personalizzato from/to) |\n| `◂` / `▸` (frecce sin/dx, anche `h`/`l`) | Home | Cambia mese (solo mentre il periodo `this month` è attivo) |\n| `w` | Home | Alterna la settimana ISO corrente |\n| `t` | Home | Alterna scope `me` / `team` |\n| `f` | Home | Apre la **selezione membri** (scope team): multiselezione dei membri inclusi nel report |\n| `Enter` | Home | Genera il report per il periodo/scope selezionati |\n| `g` | Report | Cicla il raggruppamento: totale → task → lista → giorno → tag → membro (team) → totale |\n| `e` | Report | Apre il menu di export (CSV/JSON/Markdown/HTML/fattura CSV) |\n| `m` / `s` | Report | Torna alla home per cambiare range/scope |\n| `r` | Report | Ricarica le voci ore dall'API per lo stesso periodo/scope |\n| `p` | Report | Apre la schermata **Impostazioni di fatturazione** (tariffe, valute, budget, arrotondamento, timezone) |\n| `b` | Report | Apre la vista **Burn-down budget** |\n| `f` | Report | Apre la schermata **Filtri** (lista/tag/status/billable) |\n| `v` | Report | Apre il **browser delle voci ore** (edit/delete/tag/history) |\n| `n` | Home / Report | Apre la schermata **Log ore** (registra tempo su ClickUp) |\n| `c` | Home | Salta al timer in corso (visibile solo quando un timer è attivo) |\n| `↑`/`↓` (anche `k`/`j`) | Export | Seleziona il formato |\n| `Enter` | Export | Salva `clickup-report-\u003cperiodo\u003e.\u003cext\u003e` nella cwd (la fattura CSV viene salvata come `clickup-invoice-\u003cperiodo\u003e.csv`; `\u003cperiodo\u003e` è `YYYY-MM` per un mese di calendario, oppure `YYYY-MM-DD_YYYY-MM-DD` per un periodo personalizzato) |\n| `Esc` | Export | Torna al report senza esportare |\n| `q` | Ovunque tranne setup / rates / range / browser liste / log ore / voci ore | Esce dall'applicazione |\n| `Ctrl+C` | Sempre | Esce dall'applicazione |\n\nNelle schermate setup, rates, range, browser liste, log ore e voci ore non è previsto\n`q` per uscire, per evitare di premerlo per errore mentre si sta scrivendo (un token,\nuna tariffa, una nota, un ID task, ...): usa `Ctrl+C`.\n\n#### Schermata Impostazioni di fatturazione\n\nDalla schermata del report, premendo `p` si apre la schermata **Impostazioni di\nfatturazione**, con quattro tab (`Tab`/`Shift+Tab` per cambiare): **Lists** (tariffa,\nvaluta e budget per lista), **Members** (tariffa per membro), **Overrides** (tariffa\nper coppia lista,membro — il livello più specifico della precedenza) e **Rules**\n(valuta di default, arrotondamento increment/mode/scope, e timezone). Precedenza\ndelle tariffe, dalla più specifica: **(lista, membro) \u003e membro \u003e lista \u003e default**.\nComandi disponibili:\n\n- `Tab` / `Shift+Tab`: cambia tab\n- `↑` / `↓` (anche `k` / `j`): naviga tra le righe\n- `Enter`: modifica la tariffa della riga selezionata (in Rules: modifica il campo, o\n  ne alterna il valore per mode/scope dell'arrotondamento)\n- `c` (Lists): modifica la valuta della lista; `g` (Lists): modifica il budget della\n  lista (invia un valore vuoto per cancellare entrambi)\n- `n` (Overrides): crea un nuovo override (lista,membro) — scegli la lista, poi il\n  membro, poi digita la tariffa\n- `d`: cancella il valore selezionato, tornando al livello successivo della\n  precedenza (una valuta o un budget di lista si cancellano invece riaprendo il\n  proprio campo con `c`/`g` e inviando un valore vuoto)\n- Digitare `0` per una tariffa è un'azione diversa dal cancellarla: `0` fattura la\n  lista, il membro o la coppia a zero, mentre `d` cancella l'override e fa\n  applicare la tariffa ereditata. Un budget di `0` non ha questo significato e\n  resta rifiutato.\n- `b` (Lists): apre il **browser workspace liste** per aggiungere una lista non\n  ancora tracciata\n- `s`: salva le modifiche e torna al report\n- `Esc`: annulla (scarta le modifiche non salvate) e torna al report\n\nDalla v1.1, ogni importo è calcolato dalla durata esatta fatturata moltiplicata per la\ntariffa effettiva, mai da un valore di ore già arrotondato — vedi\n[Come vengono calcolati gli importi fatturati](#come-vengono-calcolati-gli-importi-fatturati)\nper la regola completa.\n\n#### Vista burn-down budget\n\nPremendo `b` dalla schermata del report si apre la vista **Burn-down budget**: una\nbarra di progresso testuale per ogni lista con un budget configurato in\n`billing.budgets`, ordinate dalla più consumata. Ogni barra mostra l'importo\nfatturato rispetto al budget, nella valuta della lista (importo, non ore). Premi\n`b` o `Esc` per tornare al report.\n\n#### Schermata Filtri\n\nDalla schermata del report, premendo `f` si apre la schermata **Filtri**, con quattro\nsezioni: Liste, Tag, Status e Billable. Le prime tre elencano i valori distinti\npresenti nelle voci caricate; selezionando uno o più valori in una sezione si\nmantengono solo le voci corrispondenti (OR all'interno della sezione, AND tra sezioni\ndiverse); lasciare una sezione vuota equivale a \"nessun filtro\" per quella dimensione.\nBillable è diversa — un toggle a scelta singola (**All** / **Billable only** /\n**Non-billable only**), un solo valore attivo alla volta. Gli status dei task non\nfanno parte del caricamento iniziale dall'API, quindi la prima volta che apri Filtri\nin una sessione l'app recupera lo status corrente di ogni task caricato da ClickUp\n(mostrando \"Loading statuses…\"); da quel momento resta in cache per il resto della\nsessione. I filtri si compongono con la selezione membri e con il periodo attivo:\nrestringono solo ciò che è già stato caricato. Quando il periodo cambia, le selezioni\ndei filtri si adattano automaticamente alle nuove voci: ogni valore selezionato che\nnon compare più viene scartato, così il report non resta mai bloccato vuoto per un\nfiltro ormai obsoleto. Comandi disponibili:\n\n- `Tab` / `Shift+Tab`: cambia sezione\n- `↑` / `↓` (anche `k` / `j`): naviga all'interno della sezione\n- `Space`: attiva/disattiva il valore evidenziato\n- `a`: seleziona/deseleziona tutti i valori della sezione\n- `Enter`: applica il filtro e torna al report\n- `Esc`: scarta le modifiche e torna al report\n\n#### Timer live e gestione delle voci\n\nQuando un timer è in corso (avviato da **Log ore**, vedi sotto), la home mostra\nun indicatore live che ticchetta — `⏱  running on \u003ctask\u003e — HH:MM:SS  (X.XXh)` —\nindipendentemente da quale schermata l'ha avviato, così non lo perdi mai di\nvista. Premi `c` sulla home per saltarci direttamente e fermarlo.\n\nDalla schermata del report, premendo `v` si apre il **browser delle voci ore**:\nle voci del periodo corrente, dalla più recente, navigabili con `↑`/`↓` (anche\n`k`/`j`). Comandi disponibili:\n\n- `e`: modifica la durata, data/ora, nota e flag billable della voce\n  evidenziata — **solo sulle tue voci**\n- `x`: cancella la voce evidenziata, con conferma `[y/N]` — **solo sulle tue\n  voci**\n- `t`: modifica i **tag** della voce evidenziata — **solo sulle tue voci**.\n  Sono i tag propri della voce ore (mostrati come `#focus #client-A` nella\n  riga), distinti dai tag del task. Apre un picker: `↑`/`↓` per muoversi,\n  `space` per attivare/disattivare un tag, `n` per crearne uno nuovo, `Enter`\n  per salvare, `Esc` per annullare\n- `h`: consulta lo storico delle modifiche della voce (sola lettura) —\n  disponibile su **qualsiasi** voce, non solo le tue\n- `Esc`: torna al report\n\nModifica, cancellazione e tag sono vincolati alla proprietà: una voce\nregistrata da un collega compare nel browser (scope team) ma `e`/`x`/`t` non\nfanno nulla su di essa — funziona solo `h`.\n\n#### Schermata Log ore\n\nPremendo `n` (dalla Home o dal Report) si apre **Log ore**, per registrare tempo\nsui propri task ClickUp. Tre modalità:\n\n1. **Guidato** — scegli una lista tra quelle note (report corrente ∪ config), poi\n   un task della lista, poi compili il form. Il selettore di lista comprende una voce\n   \"**Esplora tutte le liste workspace…**\" che apre il browser workspace liste,\n   permettendoti di navigare tutti gli spazi, cartelle e liste nel tuo workspace\n   (non solo quelli recenti o configurati).\n2. **Task ID/URL** — incolli l'ID del task o un URL ClickUp (es. `.../t/86abc`) e\n   vai diretto al form.\n3. **Timer** — avvii un cronometro sul task scelto (guidato o ID); premendo `s` lo\n   fermi e ClickUp registra la time entry. Se all'apertura c'è già un timer in\n   corso, viene mostrato e puoi fermarlo subito.\n\nNel form la **durata** accetta formati flessibili: `2h30`, `2h30m`, `1.5h`, `1,5h`,\n`90m`, `45` (numero nudo = ore). La **data** default è oggi (`YYYY-MM-DD`, editabile)\ne la **nota** è opzionale. Infine scegli se la voce è **billable** (`Y`/`n`, default sì).\nDopo il salvataggio puoi premere `r` per ricaricare il report e vedere subito le nuove\nore. Si registrano sempre **le proprie** ore.\n\n#### Browser workspace liste\n\nIl browser workspace liste (aperto dalla modalità **Log ore** guidata o dalla schermata\n**Impostazioni di fatturazione**) mostra tutti gli spazi, le cartelle e le liste del tuo workspace\ncome navigazione gerarchica drill-down: parti dalla radice del workspace → seleziona uno\nspazio → naviga nelle cartelle di quello spazio → scegli una lista. I contenuti di ogni\nspazio (cartelle e liste) sono caricati al primo accesso e messi in cache per la sessione;\nl'apertura di una cartella non richiede altre richieste (le sue liste arrivano inline).\nComandi disponibili:\n\n- `↑` / `↓` (anche `k` / `j`): naviga su/giù nel livello corrente\n- `Enter`: entra/espandi lo spazio o cartella evidenziata; seleziona la lista evidenziata\n- `Esc`: torna indietro di un livello (o ritorna alla schermata di origine al livello radice)\n\n### Scope team\n\nPer lo scope `team` il token deve avere permessi Owner/Admin sul workspace:\nsenza questi permessi la chiamata API fallisce e l'errore viene mostrato\nnella schermata d'errore. Lo scope `team` aggrega le ore dei membri del\nworkspace; di default sono inclusi **tutti** i membri, ma puoi premere `f`\ndalla Home per aprire la schermata di selezione membri e sceglierne alcuni\nin particolare (una selezione parziale mostra una nota `(k/n members)` nel\ntitolo del report).\n\n### Report headless\n\n`clup report` stampa un report ore su stdout senza avviare la TUI — pensato per script,\ncron job e agent. Riusa la stessa logica di periodo/scope/raggruppamento/fatturazione\ndel report interattivo, ma non tocca mai l'interfaccia a terminale.\n\n```sh\nclup report --month 2026-06 --scope me --format json\nclup report --week 2026-W30 --billable --format csv-invoice \u003e invoice.csv\n```\n\nFlag:\n\n- `--month YYYY-MM` — report su un mese di calendario (default: mese corrente se non viene dato nessun altro flag di periodo).\n- `--week YYYY-Www` — report su una settimana ISO-8601 (es. `2026-W30`); rifiuta un\n  valore malformato o un numero di settimana fuori da 1–53.\n- `--from YYYY-MM-DD --to YYYY-MM-DD` — periodo personalizzato, inclusivo (da usare insieme).\n- `--preset this_month|last_month|last_7d|last_30d|this_week` — gli stessi preset del selettore periodo della TUI.\n- Priorità del periodo quando ne viene passato più di uno: `--month` \u003e `--week` \u003e\n  `--from`/`--to` \u003e `--preset` \u003e mese corrente (default).\n- `--scope me|team` (default `me`).\n- `--group total|task|list|day|member|tag` (default `total`).\n- `--billable` — filtra solo le voci billable; passa `--billable=false` per tenere\n  solo le voci non billable. Se il flag non viene passato non applica nessun filtro.\n- `--tag TAG` — filtra le voci che portano questo tag; ripetibile (`--tag a --tag b`\n  seleziona le voci che portano *uno qualsiasi* dei tag dati).\n- `--tz IANA` — timezone per i confini del periodo e per il campo `timezone` del\n  report (default: la `timezone` della config, altrimenti UTC — vedi\n  [Configurazione](#configurazione)).\n- `--format json|csv|md|html|csv-invoice` (default `json`).\n\nTutti i formati scrivono su stdout — usa la redirezione della shell per salvare\n(es. `clup report --format csv \u003e report.csv`).\n\nNota: `CLICKUP_DEMO=1` viene **ignorato** da `report` — carica sempre la config reale e\nchiama la vera API; la demo mode è solo per la TUI.\n\nL'output di `--format json` è uno **schema di scripting stabile** (chiavi snake_case,\ntimestamp RFC3339) — parsabile in sicurezza con `jq` e fissabile negli script. È\nadditivo e non-breaking: i campi pre-v1.7 `rate` e `currency` restano, ora\n**deprecati**, insieme alle aggiunte v1.7 `schema_version`, `timezone`,\n`currency_subtotals`, `billable_hours`, `non_billable_hours`, `billed_hours` e\n`lines` (le righe fattura per singola unità di fatturazione). I nuovi script\ndovrebbero leggere `currency_subtotals`/`lines` invece dei campi singolo-valore\ndeprecati `rate`/`currency`.\n\n`--format html` scrive un report self-contained: CSS inline, nessun foglio di\nstile, font, script o immagine esterna. Aprilo in un browser e stampalo in PDF\nper un documento condivisibile.\n\n`--format csv-invoice` scrive una riga per ogni unità di fatturazione (non per\nbucket), con le colonne\n`date, list_id, client, user, description, qty_hours, rate, amount, currency, billable`\n— `client` contiene il nome della lista ClickUp (l'equivalente più vicino a un campo\ncliente/progetto che uno strumento basato su liste possa avere). `qty_hours` è\nespresso con 6 decimali di proposito, così che `qty_hours × rate` di ogni riga\nriconcili con `amount` alla precisione del centesimo — un'unità di 20 minuti a 30/h\nfattura esattamente 10.00, non 9.90.\n\n## Configurazione\n\nLa configurazione persiste sotto `os.UserConfigDir()` (quindi rispetta\n`XDG_CONFIG_HOME` su Linux): `~/Library/Application Support/clup/config.yml`\nsu macOS, `~/.config/clup/config.yml` su Linux. Se quel file non esiste ancora,\nviene letto come fallback il percorso legacy pre-rebrand\n(`~/.config/clickup-cli/config.yml` e il suo equivalente per-OS), così\nl'aggiornamento da una vecchia installazione `clickup` non perde le\nimpostazioni.\n\n```yaml\nschema_version: 2\ntoken: pk_xxx...\nworkspace_id: \"123456\"\ncurrency: EUR\nrate: 45\nrates:\n  \"111\": 60\n  \"222\": 30\ntimezone: Europe/Rome\nbilling:\n  default_currency: EUR\n  rates_by_member:\n    42: 60\n  rate_overrides:\n    - list: \"111\"\n      member: 42\n      rate: 70\n  currencies:\n    \"111\": EUR\n    \"222\": USD\n  budgets:\n    \"111\": 2000\n  rounding:\n    increment: 15m\n    mode: up\n    scope: day\n```\n\n- `token`: token API personale ClickUp.\n- `workspace_id`: id del workspace (team ClickUp) scelto in fase di setup.\n- `currency`: valuta usata nel report e negli export.\n- `rate`: tariffa oraria di default usata per calcolare l'importo da fatturare.\n- `rates` (opzionale): mappa `list_id: tariffa` con tariffe orarie specifiche per\n  singola lista. Le liste non elencate usano la tariffa di default `rate`. La mappa\n  si compila comodamente dalla schermata **Impostazioni di fatturazione** della TUI\n  (`p` nella schermata del report). Una tariffa di `0` (qui o in `rates_by_member`/\n  `rate_overrides` più sotto) significa che la lista/membro/coppia fattura a zero —\n  un valore deliberato, diverso dall'omettere la voce (che ricade sul livello\n  successivo della precedenza).\n- `schema_version`: scritto automaticamente al salvataggio — non va mai modificato a\n  mano. Un file di config precedente alla v1.7 (schema v1) viene comunque letto\n  così com'è, con i valori esistenti di `rate`/`rates`/`currency` intatti, e viene\n  aggiornato a v2 al salvataggio successivo.\n- `timezone` (opzionale): nome di zona IANA (es. `Europe/Rome`) che ancora i confini\n  di giorno/settimana/mese del report. Due binari: la **TUI** la usa, ricadendo sulla\n  zona locale della macchina se non impostata (e in quel caso mostra la propria zona\n  come `Local`, non come nome IANA); il `clup report` headless usa sempre **UTC** di\n  default, a meno che non venga sovrascritto da `--tz` o da questo campo. È\n  consigliato impostarla esplicitamente; è modificabile anche dalla schermata\n  **Impostazioni di fatturazione** della TUI.\n- `billing` (opzionale, v1.7): additivo rispetto a `rate`/`rates`/`currency` sopra —\n  nessuno di quei campi cambia significato.\n  - `default_currency`: valuta ISO di fallback per le liste non presenti in\n    `currencies` (ricade ulteriormente sulla `currency` di primo livello se non\n    impostata).\n  - `rates_by_member`: `user_id: tariffa` — una tariffa oraria per membro.\n  - `rate_overrides`: una lista di `{list, member, rate}` — la tariffa più specifica,\n    per un membro su una lista. Precedenza delle tariffe, dalla più specifica:\n    **(lista, membro) \u003e membro \u003e lista \u003e default**.\n  - `currencies`: `list_id: codice ISO` — fattura ogni lista nella sua valuta. I\n    subtotali sono sempre per valuta e non vengono mai sommati tra valute diverse\n    (nessun FX); un totale complessivo unico viene mostrato solo quando una sola\n    valuta porta importi (le altre possono comunque comparire con sole ore non\n    fatturabili).\n  - `budgets`: `list_id: importo` — un budget in valuta per lista, confrontato con\n    gli **importi fatturati** (non le ore) e mostrato come barra burn-down nella TUI\n    (`b` dalla schermata del report).\n  - `rounding`: arrotonda le ore billable prima della fatturazione; le ore non\n    billable non vengono mai arrotondate.\n    - `increment`: una durata in formato umano (`15m`, `1h`, `2h30`); vuoto (default)\n      significa arrotondamento disattivato. **Un valore non vuoto che non si riesce a\n      interpretare è un errore bloccante**, non un \"disattivato\" silenzioso — un\n      refuso qui non deve mai sotto-arrotondare in silenzio e sovra-fatturare.\n    - `mode`: `up` arrotonda per eccesso; qualsiasi altro valore (incluso\n      vuoto/omesso) arrotonda al valore più vicino.\n    - `scope`: `day` arrotonda il totale per (giorno, lista, membro) invece che per\n      singola voce; qualsiasi altro valore arrotonda ogni voce singolarmente.\n- `update_check` (opzionale): impostare `false` per disattivare il controllo\n  aggiornamenti descritto più sotto. Omettere la chiave (o impostare `true`) lo\n  lascia attivo.\n\n### Come vengono calcolati gli importi fatturati\n\nL'importo di un'unità di fatturazione — una voce billable, oppure un gruppo\n(giorno, lista, membro) quando `rounding.scope: day` — è arrotondato a 2 decimali a\npartire dalla sua durata fatturata *esatta* moltiplicata per la tariffa, mai da un\nvalore di ore già arrotondato. Ogni totale (un bucket, un subtotale valuta, una riga\nfattura) è poi la somma di importi di unità già arrotondati, così il CSV fattura, i\n`currency_subtotals` del JSON e l'export HTML concordano sempre al centesimo. L'unico\ncaso in cui questo non vale è un report raggruppato più *fine* dell'unità di\nfatturazione (es. per-task con arrotondamento per giorno): l'importo di un bucket in\nquel caso è una ripartizione proporzionale **indicativa** delle sue unità e può\nscostarsi di qualche centesimo — i subtotali valuta e le righe fattura\n(`--format csv-invoice`, o il campo `lines` nell'output JSON) restano sempre gli\nimporti autoritativi.\n\nLa variabile d'ambiente `CLICKUP_TOKEN`, se impostata, sovrascrive sempre il\n`token` letto dal file di config (comodo per CI o per non salvare il token su\ndisco):\n\n```bash\nCLICKUP_TOKEN=pk_xxx clup\n```\n\n### Controllo aggiornamenti\n\nUna volta al giorno, `clup` chiede a GitHub se esiste una release più recente e, in\ncaso affermativo, mostra un breve avviso. È deliberatamente circoscritto in ciò che\nfa:\n\n- **Anonimo.** È una singola chiamata GET, con timeout di 2 secondi, all'endpoint\n  pubblico `https://api.github.com/repos/marcoarnulfo/clickup-cli/releases/latest`,\n  con i soli header `Accept` e `User-Agent`. Non c'è alcun header `Authorization` —\n  il tuo token ClickUp non viaggia mai verso GitHub.\n- **Nessun self-update.** `clup` non scarica né sostituisce mai il proprio binario;\n  l'avviso si limita a segnalare che esiste una versione più recente e a indicare\n  `go install github.com/marcoarnulfo/clickup-cli/cmd/clup@latest`.\n- **In cache.** Il risultato è salvato in `os.UserCacheDir()/clup/update.json` e\n  riusato per 24 ore, così la maggior parte delle esecuzioni non fa alcuna chiamata\n  di rete.\n- **La maggior parte delle build da sorgente sono esenti.** Se hai compilato\n  `clup` tu stesso con un semplice `go build`, il binario riporta una\n  pseudo-version anziché una release numerata e il controllo non parte mai —\n  a meno che il checkout non sia pulito e posizionato esattamente su un tag di\n  release, nel qual caso riporta esattamente quella versione e il controllo si\n  comporta come per qualsiasi build di release. A tenerlo silenzioso sono i\n  commit successivi al tag, oppure un albero sporco (`+dirty`).\n- **Dove compare:** come riga aggiuntiva nella home della TUI e, per `clup report`,\n  come riga su **stderr** stampata dopo il corpo del report — mai su stdout, così\n  `clup report --format json` resta interpretabile dagli strumenti a valle.\n- **Disattivarlo** con `CLUP_NO_UPDATE_CHECK=1` (qualsiasi valore non vuoto) o con\n  `update_check: false` nel config; la variabile d'ambiente vince sempre sul\n  config. Omettere la chiave lascia il controllo attivo. Anche la modalità demo\n  (`CLICKUP_DEMO=1`) lo disattiva — ma **solo per la TUI**; `clup report` ignora\n  `CLICKUP_DEMO` e controlla come in qualsiasi altra esecuzione.\n\n## Contribuire\n\nI contributi sono benvenuti — è un progetto libero e open-source. Vedi\n**[CONTRIBUTING.it.md](CONTRIBUTING.it.md)** per come preparare l'ambiente di sviluppo,\nlanciare i test e aprire una PR. Sei alle prime armi? Cerca la label\n[`good first issue`](https://github.com/marcoarnulfo/clickup-cli/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22).\nLeggi anche il [Codice di Condotta](CODE_OF_CONDUCT.md).\n\n## Roadmap\n\nLa stella polare è far crescere il progetto da tool di report ore mensile a **client ClickUp\nda terminale completo e bello** — mantenendo **time tracking e fatturazione come funzione di\npunta** (nessun altro tool offre tariffe per-lista/membro, budget ed export del report in una TUI).\n\nIl piano completo vive nelle **[GitHub Issues](https://github.com/marcoarnulfo/clickup-cli/issues)**,\ntracciato dall'**[epic Roadmap 🗺️ #33](https://github.com/marcoarnulfo/clickup-cli/issues/33)**\ne organizzato in milestone:\n\n| Milestone | Focus |\n|---|---|\n| [v1.6 — Rebrand \u0026 fondamenta](https://github.com/marcoarnulfo/clickup-cli/milestone/4) | rebrand a `clup`, service layer, rate limiter, `report --json` |\n| [v1.7 — Billing depth](https://github.com/marcoarnulfo/clickup-cli/milestone/5) | split billable, tariffe per-membro e per-coppia, arrotondamento, multi-valuta, budget \u0026 burn-down, export HTML/fattura CSV |\n| [v1.8 — Live time tracking](https://github.com/marcoarnulfo/clickup-cli/milestone/6) | timer live, edit/delete entry |\n| [v1.9 — TUI design system](https://github.com/marcoarnulfo/clickup-cli/milestone/7) | temi, tabelle, command palette, accessibilità |\n| [v1.10 — Task context \u0026 account](https://github.com/marcoarnulfo/clickup-cli/milestone/8) | search, my-tasks, dettaglio task, keychain, profili |\n| [v1.11 — Task management](https://github.com/marcoarnulfo/clickup-cli/milestone/9) | crea/aggiorna task, commenti, checklist |\n| [v1.12 — Navigation, views \u0026 preset](https://github.com/marcoarnulfo/clickup-cli/milestone/10) | spaces/liste, view salvate, preset report |\n| [v1.13 — Docs, Goals \u0026 Sprints](https://github.com/marcoarnulfo/clickup-cli/milestone/11) | ClickUp Docs, goals, sprint |\n| [v2.0 — Git \u0026 AI](https://github.com/marcoarnulfo/clickup-cli/milestone/3) | git integration, `--jq`/`--template`, MCP, skill file |\n| [Distribution \u0026 packaging](https://github.com/marcoarnulfo/clickup-cli/milestone/12) | goreleaser, Homebrew, completions, man page |\n| [Docs \u0026 website](https://github.com/marcoarnulfo/clickup-cli/milestone/13) | landing page, docs site, screenshot |\n\n**Fuori scope:** fatturazione fiscale (IVA, numerazione, PDF legale) — troppo dipendente dal\npaese; il tool produce invece report pre-fattura condivisibili.\n\n## Licenza\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcoarnulfo%2Fclickup-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcoarnulfo%2Fclickup-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcoarnulfo%2Fclickup-cli/lists"}