| name | tempo-report |
|---|---|
| description | Use when user asks for a Tempo time report, worklog summary, daily work report, or says "tempo report", "tempo:report", "отчёт tempo", "покажи что я делал", "что я залогировал". Works with Jira worklogs, Activity Streams, Git commits, changelog/comments, and local activity sources. |
| license | MIT |
| compatibility | Requires bash and python3 for bundled scripts. Optional richer reports use git, jq, curl, Jira tools when available, or Jira HTTP access via JIRA_URL and JIRA_PERSONAL_TOKEN. Tests require jq. |
| tags | jiratempoworklogreportingproductivity |
| owners | redickowii |
| metadata | {"author":"redickowii","version":"1.0"} |
Tempo Report
Build a Tempo worklog recommendation for one day or a short date range. Use Jira worklogs, Jira activity, comments, Git commits, and configured local activity folders. Keep sources separate: Worklog, Git, Changelog, Comments, Local.
Core rules:
- Report generation is read-only. Never add Jira/Tempo worklogs unless the user explicitly asks for writes.
- Dry-run or validation prompts must not perform real Jira writes, save reports, import configs, or mutate files.
- Never print secrets, token values, full env dumps, or local file contents.
- Never pad time to
minDailyHours; show shortfall honestly.
##Trigger
Use when the user asks for a Tempo report, worklog summary, daily time report, or asks what they did/logged. Examples: tempo за вчера, tempo report 2026-05-20, отчёт tempo, покажи что я делал.
Help triggers (?, help, --help, usage, помощь, как пользоваться) mean show usage only.
##Data Backends
- Required: bundled script
scripts/tempo-data.shinside the installed skill directory. - Jira data can come from any available backend: shell-provided Jira tools, MCP-backed Jira tools, Jira CLI, or Jira HTTP/API access. Do not require MCP.
- Optional shell tools for richer reports:
git,jq,curl. - Optional env for Jira HTTP/API and Activity Streams:
JIRA_PERSONAL_TOKEN,JIRA_URL. - Optional Jira tool names, when provided by the current shell:
jira_search,jira_get_issue,jira_get_worklog; optionaljira_add_worklogfor writing time.
Never print secret values.
##Config Resolution
Use shell-neutral config shared by OpenCode, Claude, Pi, Warm, and other shells:
global: ~/.config/tempo-report/config.json
project: ${PROJECT_ROOT}/.tempo-report.jsonProject config overrides global config. If any canonical config exists, use only canonical config and do not inspect legacy config.
If no canonical config exists, check known legacy configs only as import candidates:
Claude Code global: ~/.claude/tempo-report.json
Claude Code project: ${PROJECT_ROOT}/.claude/commands/tempo-report.json
OpenCode global: ~/.config/opencode/tempo-report.json
OpenCode project: ${PROJECT_ROOT}/.opencode/tempo-report.jsonLegacy configs are not fallback configs. Import requires user confirmation and target confirmation before writing. If no canonical or legacy config exists, default creation target is project config ${PROJECT_ROOT}/.tempo-report.json; global config is optional. After import, offer to remove legacy config; default answer is No.
.agents/skills/... is skill installation only, not runtime settings.
Set the installed skill directory before running bundled scripts from another project. Path depends on shell/install location:
TEMPO_SKILL_DIR="/path/to/installed/tempo-report"Useful commands:
bash "$TEMPO_SKILL_DIR/scripts/tempo-data.sh" config-paths
bash "$TEMPO_SKILL_DIR/scripts/tempo-data.sh" load-config [CONFIG_PATH]
bash "$TEMPO_SKILL_DIR/scripts/tempo-data.sh" import-config [SOURCE_PATH] SCOPE # SCOPE: global|projectImport/create rules:
load-configmay reportneedsSetupand legacy candidates, but must not import automatically.- Ask before creating canonical config or importing legacy config; confirm target scope/path.
- After import, ask before deleting legacy config; default answer is No.
##Config Fields
{
"currentUser": {
"jiraLogin": "username",
"jiraKey": "JIRAUSER123",
"gitEmails": ["user@example.com"]
},
"projectsPath": "../projects",
"reportsSubdir": "tempo",
"autoSave": "self",
"eveningHour": 18,
"minDailyHours": 6.75,
"localActivitySources": ["~/work/docs"],
"userMappings": {}
}gitEmail string is legacy; normalize to gitEmails array. Arrays in project config replace global arrays.
localActivitySources is generic: docs, logs, exports, temp files, diagrams, snapshots, or any configured folders. Paths are user/project-specific and must stay in config.
##Workflow
###1. Resolve date and user
bash "$TEMPO_SKILL_DIR/scripts/tempo-data.sh" get-date [YYYY-MM-DD] [YYYY-MM-DD] [EVENING_HOUR]
bash "$TEMPO_SKILL_DIR/scripts/tempo-data.sh" check-env
bash "$TEMPO_SKILL_DIR/scripts/tempo-data.sh" load-configNo args means auto date: today after eveningHour, otherwise yesterday. Weekend auto mode suggests Friday unless date is explicit. Text after date can override user; otherwise use currentUser.
###2. Collect candidate issues
Use union of all sources. Never iterate issue keys manually.
Candidate sources:
| Source | Method |
|---|---|
| Worklog | worklogAuthor = "LOGIN" AND worklogDate = "DATE" |
| Assignee | assignee = "LOGIN" AND updated >= "DATE" |
| Code Reviewer | "Code Reviewer" = "LOGIN" AND updated >= "DATE" |
| Activity Streams | bash "$TEMPO_SKILL_DIR/scripts/tempo-data.sh" activity-streams DATE LOGIN JIRA_URL |
| Git commits | Extract issue keys from commit messages |
| Comments | Fetch comments for all candidate issues |
Use JQL with fields="key,summary,status", not *all.
Coverage requirement:
- Final candidate set is the union of every source above.
- Fetch changelog and comments for every candidate issue, including issues that already have worklogs.
- If batch changelog fails, fall back to per-issue fetch; do not skip silently.
- Before final report, list any unprocessed candidates with reason.
###3. Fetch worklogs
For each candidate issue:
Use current Jira backend to fetch worklogs for each candidate issue. If shell Jira tools exist, jira_get_worklog(issue_key="KEY") is acceptable; otherwise use Jira CLI or Jira HTTP/API equivalent.
Filter by started date and author. started is the date time was logged for; created is only when the entry was created.
###4. Fetch changelog and comments
Fetch changelog for all candidate tasks, even if worklog exists. Batch if available; otherwise fetch each issue with expand=changelog. Comments are separate from changelog and must be fetched separately with fields="comment".
Filter activity by user and target day. Exclude worklog bookkeeping fields: WorklogId, timeestimate, timespent.
Do not mix categories:
- Worklog is explicit logged time only.
- Changelog is field/status/assignee activity only.
- Comments are not in changelog; fetch and estimate separately.
- Worklog bookkeeping fields are not activity.
Estimate Jira activity:
| Activity | Estimate |
|---|---|
| Status transition / code-review transition | 15m |
| Assignee change | 5m |
| Short comment | 5-10m |
| Medium discussion | 10-20m |
| Detailed code review / bug triage | 30-60m |
###5. Fetch Git commits
Always fetch Git, even if worklogs cover the day.
bash "$TEMPO_SKILL_DIR/scripts/tempo-data.sh" git-commits DATE EMAIL PROJECTS_PATH
bash "$TEMPO_SKILL_DIR/scripts/tempo-data.sh" git-diff HASH REPO_PATH
bash "$TEMPO_SKILL_DIR/scripts/tempo-data.sh" estimate-time INTERVAL_SEC ADDED REMOVED TYPESearch every git repo under projectsPath and every email in gitEmails. The script checks CommitDate when AuthorDate is outside target day, so rebased/amended/cherry-picked commits are still counted when relevant.
###6. Fetch local activity
If localActivitySources exists, fetch local activity:
bash "$TEMPO_SKILL_DIR/scripts/tempo-data.sh" local-activity DATE [CONFIG_PATH]Rules:
- Use metadata for all files.
- Read content only for safe text extensions and size limits.
- Never print file contents.
- Extract task keys from path, filename, and safe text content.
- Prefer a concrete content issue over a parent folder issue.
- Group file events by source, task key, and time proximity.
- Deduplicate with Jira/Git when clearly same work.
###6a. Optional chronological calculation
Use this when user asks for chronology/timeline, when source totals overlap heavily, or when normal summing looks misleading.
Process:
- Build one timeline from Git commit
time, Jira changelogcreated, worklogstarted, commentscreated, and local activity timestamps. - Sort by time; assign intervals to the previous active task.
- Exclude breaks over 30m unless evidence says work continued.
- Treat merge commits as 15m flat unless there is clear work beyond merge handling.
- Split intervals for commits/comments that clearly mention multiple tasks.
- Still show source columns separately; use chronology only to avoid double count in unique work.
###7. Format report
Show full report in chat first, then save when autoSave allows. If saved, final answer must include the same summary table and totals as the saved file.
# Tempo Report — YYYY-MM-DD
| Задача | Название | Worklog | Git | Changelog | Comments | Local | Рекомендация |
|--------|----------|---------|-----|-----------|----------|-------|--------------|
| EDS-123 | Summary text | 3h | 30m | — | — | — | 3h 30m |
| EDS-456 | Local work | — | — | — | — | 2h | 2h |
**Итого Worklog:** Xh Ym
**Итого Git:** Xh Ym
**Итого Changelog:** Xh Ym
**Итого Comments:** Xh Ym
**Итого Local:** Xh Ym
**Уникальная работа (без пересечений):** Xh YmRules:
- Worklog = explicitly logged time.
- Changelog = Jira field activity, not comments and not worklog bookkeeping.
- Comments = user comments/reviews/discussions.
- Local = configured local file activity.
- Do not adjust time to reach
minDailyHours; show the shortfall honestly. - Manual adjustments only when user asks.
- Escape
|in summaries. - Use
—for zero time. - Show all source columns even when empty.
- If total unique work is below
minDailyHours, show the shortfall; do not invent time.
autoSave modes:
| Mode | Behavior |
|---|---|
off | Ask before saving |
self | Save own reports only |
self+specified | Save own reports and explicitly named users |
all | Save every report |
If saved, final chat response must still include the full saved table and totals. Saving is not a substitute for showing the report.
###8. Save report
Path:
${PROJECT_ROOT}/${reportsSubdir}/YYYY-MM-DD.md
${PROJECT_ROOT}/${reportsSubdir}/YYYY-MM-DD_login.md # other userAfter saving, re-read or otherwise verify the saved report before saying it was saved.
###9. Add Tempo worklogs only on request
If user asks to write worklogs, first confirm a write-capable Jira backend is available. If unavailable, stop and tell user what is missing. If the same prompt asks for a report and says to immediately log missing hours, build/show the report first, then ask separate confirmation before any write call.
Use format:
write worklog via available backend, for example jira_add_worklog(
issue_key="KEY",
time_spent="1h 30m",
started="YYYY-MM-DDTHH:MM:SS.000+0300"
)Do not pass comment to jira_add_worklog; that tool can fail with it. For other backends, follow backend requirements. Verify by fetching worklogs back.
##Dry-Run Acceptance Checks
For a prompt like tempo за вчера, expected behavior:
- Activate this skill and do not ask for date clarification.
- Resolve yesterday via
get-dateor direct date calculation. - Load config through canonical resolution rules.
- Collect Worklog, Git, Changelog, Comments, and Local as separate sources.
- Filter worklogs by
started, notcreated. - Use candidate searches; never manually iterate issue keys.
- Do not print secrets or local file contents.
- Do not write Jira worklogs unless separately requested and confirmed.
- Do not save/import config outside the rules above.
Fail patterns:
- Immediately calling
jira_add_worklogduring report generation. - Mixing Worklog and Changelog totals.
- Using worklog
createddate as the report date. - Padding recommendations to reach
minDailyHours. - Performing real bash/Jira calls in an explicit dry-run/test-only request.
##Error Handling
| Situation | Action |
|---|---|
| No Jira read backend | Stop and tell user which backend/env/tool is missing |
| No Jira write backend | Do not attempt writes; ask user to enable it |
| Canonical config missing | If legacy candidates exist, ask whether to import; otherwise ask to create project config |
| Activity Streams fails | Notify user and fall back to Jira/JQL sources |
| Changelog batch fails | Fetch per issue |
| Worklog issue has too many entries | Warn and skip that issue's worklogs |
| No Git commits | Keep Git column empty and note it |
User notifications:
- Retryable failure:
⚠️ <action> failed: <reason>. Retrying... - Retry recovered:
✓ <action> recovered on retry - Permanent partial failure:
⚠️ <action> permanently failed: <reason>. Proceeding without it.
##Installation
fs-skills install tempo-report
export TEMPO_SKILL_DIR="/path/to/installed/tempo-report"
chmod +x "$TEMPO_SKILL_DIR/scripts/tempo-data.sh"
cd "$TEMPO_SKILL_DIR" && bash tests/test-config-resolution.sh && bash tests/test-local-activity.shTests require jq.