# Timesheet Checker Checks whether employees have completed their timesheets for a given period by pulling Tempo worklogs. Compares against each employee's country calendar (public holidays fetched from date.nager.at) and a configurable minimum of hours per day. Produces a completion report ranked by missing hours. --- ## Prerequisites The skill needs four credentials. The easiest setup is a `.env` file — copy the template and fill it in once: macOS / Linux: ```bash cp .claude/skills/timesheet-checker/.env.example .claude/skills/timesheet-checker/.env ``` Windows (PowerShell): ```powershell Copy-Item .claude\skills\timesheet-checker\.env.example .claude\skills\timesheet-checker\.env ``` Or copy the file manually in Explorer / Finder — rename `.env.example` to `.env` in the skill folder. Then open `.env` and fill in your values: ``` TEMPO_API_TOKEN=your_tempo_token JIRA_BASE_URL=https://your-company.atlassian.net JIRA_EMAIL=your.email@company.com JIRA_API_TOKEN=your_jira_token ``` The script looks for `.env` in the **working directory first**, then the skill folder as a fallback. This means you can also place a `.env` in your project root if you prefer one file for all skills. Environment variables set via `export` always take priority over `.env` values, so both approaches work side-by-side. The `.env` file is gitignored — credentials are never committed. | Variable | What it is | Where to get it | |---|---|---| | `TEMPO_API_TOKEN` | Tempo read token | Tempo → Settings → API Integration | | `JIRA_BASE_URL` | Your Atlassian URL | The URL you use to open Jira | | `JIRA_EMAIL` | Your Jira login email | Your Atlassian account email | | `JIRA_API_TOKEN` | Jira personal API token | [id.atlassian.com](https://id.atlassian.com) → Security → API tokens | If any credential is missing from both `.env` and the environment, the script stops with a clear error listing exactly what is needed. --- ## How to use in Claude Code Claude Code runs as a CLI, desktop app, web app (claude.ai/code), or IDE extension. **Claude Code runs the full pipeline automatically — no manual script steps.** **Install** — copy the skill folder into your project's Claude skills directory: macOS / Linux: ```bash cp -r src/timesheet-checker .claude/skills/ ``` Windows (PowerShell): ```powershell Copy-Item -Recurse -Path src\timesheet-checker -Destination .claude\skills\ ``` **Use:** Just describe what you want — Claude will pick up the skill automatically: ``` Check if timesheets are complete for last week ``` ``` Timesheet completion for last month ``` ``` Check logged hours for 2026-06-01 to 2026-06-30 ``` Claude fetches Polish public holidays, pulls Tempo worklogs, computes completion per employee, generates the report, and shows you the results. Output files land in `./timesheet-output/`. --- ## How to use in the Claude.ai app > Full automation (no manual script running) requires Claude Code. In the Claude.ai app, the Python steps must be run locally. **Set up once (Project approach):** 1. Create a new Project in Claude.ai. 2. In **Project Instructions**, paste the full contents of `SKILL.md`. 3. Upload `references/employees.md` and `references/output-format.md` to the Project knowledge. **Each time you run:** 1. Set all four credentials in your shell, then run the pre-processor locally: ```bash python3 $SKILL_DIR/scripts/preprocess.py \ --period last-week \ --output-dir ./timesheet-output ``` The script will use `./employees.md` if it exists, otherwise `$SKILL_DIR/references/employees.md`. 2. Upload `timesheet_data.json` to the Project conversation. 3. Ask Claude to summarise and present the results. 4. Run the post-processor locally to generate the formatted report: ```bash python3 $SKILL_DIR/scripts/postprocess.py \ --data ./timesheet-output/timesheet_data.json \ --output-dir ./timesheet-output ``` **Without Projects:** Paste the contents of `SKILL.md` at the start of a new conversation, attach the two reference files, then follow the same steps. --- ## What is included | File | Description | |---|---| | `SKILL.md` | Orchestrating skill — instructions for Claude | | `references/employees.md` | Editable list of employees and their Tempo account IDs | | `references/output-format.md` | Structure of `timesheet_data.json` and the final report | | `scripts/preprocess.py` | Fetches Tempo worklogs + Polish holidays, computes completion | | `scripts/postprocess.py` | Formats `timesheet_data.json` into the markdown report | | `sample/employees_sample.md` | Sample employees file with placeholder account IDs | ## Outputs (in `./timesheet-output/`) | File | Description | |---|---| | `timesheet_data.json` | Computed stats per employee + period + summary | | `timesheet_report.md` | Manager-readable report ranked by missing hours | --- ## Configuring employees The script looks for the employees file in this order: 1. `employees.md` in the **current working directory** — place it here for a project-specific list 2. `references/employees.md` in the **skill folder** — the default shipped with the skill To use a project-specific list, copy the sample and edit it: ```bash cp .claude/skills/timesheet-checker/sample/employees_sample.md ./employees.md ``` The file has two tables: **Defaults** — applies to every employee unless overridden: | setting | value | |---|---| | `country` | ISO 3166-1 alpha-2 country code (e.g. `PL`, `GB`, `DE`). Used for public holiday lookup. | | `expected_hours_per_day` | Minimum hours per working day | **Employees** — one row per person. Leave any column blank to inherit the default. | Column | What it controls | |---|---| | `name` | Display name in the report | | `email` | Work email address (used to look up the Jira account ID automatically) | | `country` | Override the default country for this employee | | `expected_hours_per_day` | Override the default hours for this employee | | `start_date` | First working day — leave blank if employed for the full period | --- ## Period formats | Input | Meaning | End date | |---|---|---| | `last-week` | Previous Monday–Friday | Last Friday | | `last-month` | Previous calendar month | Last day of that month | | `last-year` | Previous calendar year | 31 December | | `yesterday` | Yesterday only | Yesterday | | `current-week` | Monday of this week to yesterday | Yesterday | | `current-month` | 1st of this month to yesterday | Yesterday | | `current-year` | 1st January of this year to yesterday | Yesterday | | `YYYY-MM-DD:YYYY-MM-DD` | Explicit date range | As specified | For `current-*` periods the current in-progress day is always excluded — end date is yesterday. If today is the first day of the period (e.g. `current-week` on a Monday), the period contains no past working days and the report will show 0 expected hours. In Claude Code, you can also use natural language ("last week", "this month", "yesterday", "June 2026") and Claude converts it automatically. --- ## How working days are calculated The script fetches Polish public holidays from the [date.nager.at](https://date.nager.at) public API (no authentication needed). It then excludes weekends and those holidays from the period. This runs live each time — holiday data is never hardcoded. --- ## Integration This skill connects to **Tempo Cloud** (`api.tempo.io/4`) by default. For self-hosted Tempo (Jira Data Center), pass the correct base URL: ```bash python3 $SKILL_DIR/scripts/preprocess.py \ --tempo-base-url https://your-jira.company.com/rest/tempo-timesheets/4 \ ... ``` Or in Claude Code: ``` Check timesheets for last week, Tempo is at https://jira.company.com/rest/tempo-timesheets/4 ``` --- ## Limits - Requires `TEMPO_API_TOKEN` — the script stops immediately with a clear error if it is missing. - Employees with 0 hours may be on leave; the tool does not distinguish between missing logs and approved absence. Review these manually. - If the period end date is today or in the future, the period is still open and data will be partial. - Polish holidays only. If your team uses a different country calendar, the `get_polish_holidays` function in `preprocess.py` needs updating. - Tempo Cloud API v4 only. Tempo Server / Data Center may require a different base URL and authentication method.