Adds ivona (invoice-checker, timesheet-checker) and timesheet (check-my-timesheet, invoice-prep) as new plugins, plus invoice-prep-test — a one-off experiment that requests the Tempo API token via plugin userConfig at install time instead of a .env file, to check whether that value actually reaches the skill's script. Also adds the root LICENSE (MIT) referenced from the README.
8.2 KiB
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:
cp .claude/skills/timesheet-checker/.env.example .claude/skills/timesheet-checker/.env
Windows (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 → 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:
cp -r src/timesheet-checker .claude/skills/
Windows (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):
- Create a new Project in Claude.ai.
- In Project Instructions, paste the full contents of
SKILL.md. - Upload
references/employees.mdandreferences/output-format.mdto the Project knowledge.
Each time you run:
- Set all four credentials in your shell, then run the pre-processor locally:
The script will usepython3 $SKILL_DIR/scripts/preprocess.py \ --period last-week \ --output-dir ./timesheet-output./employees.mdif it exists, otherwise$SKILL_DIR/references/employees.md. - Upload
timesheet_data.jsonto the Project conversation. - Ask Claude to summarise and present the results.
- Run the post-processor locally to generate the formatted report:
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:
employees.mdin the current working directory — place it here for a project-specific listreferences/employees.mdin the skill folder — the default shipped with the skill
To use a project-specific list, copy the sample and edit it:
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 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:
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_holidaysfunction inpreprocess.pyneeds updating. - Tempo Cloud API v4 only. Tempo Server / Data Center may require a different base URL and authentication method.