feat(report): 新增工作日誌總結技能

What: 新增 jsc-log:report,把工作日誌總結成年報、月報、週報或日報,寫進 wiki REPORT_{HASH}。另加 tools/report-range.sh 算期間、tools/report-template.sh 解析範本,以及四份報表範本與報表目錄範本。
Why: worklog 只記單筆工作,累積起來沒有工具看得出一週或一個月做了什麼、什麼在卡。要總結只能自己翻頁面加總。
How: 期間換算交給系統的 date,不自己算閏年與週界;週次採 ISO-8601。範本解析採工作目錄優先,.jsc/templates/report-{period}.md 蓋過技能自帶的那份,專案要換格式不必改技能。資料讀 LOG_CONTENTS 列出的所有日誌頁,取工作日期落在期間內的條目,只加總條目真的寫了的數字。
Who: 工作日誌的期間總結。
This commit is contained in:
2026-08-26 10:47:07 +08:00
parent b1baaf1546
commit e6fafd4132
12 changed files with 388 additions and 4 deletions
+59
View File
@@ -0,0 +1,59 @@
---
name: report
description: Summarise work logs into a yearly, monthly, weekly or daily report. Resolve the period with tools/report-range.sh, resolve the template with tools/report-template.sh - a project's .jsc/templates/report-{period}.md wins over the skill's own copy - then read every log page listed in LOG_CONTENTS and keep the entries dated inside the range. Fill the template with real aggregates (entry count, repositories, elapsed time, token usage, blockers, carry-overs) and write it to wiki REPORT_{HASH}, hashed from {owner}/{repo}/{period}, appending the period as a new section. Use when someone asks for a work summary over a period; not for recording a single work package, which is jsc-log:worklog.
---
# report — summarise work logs by period
Reading and aggregating the log pages **MUST run as a sub agent**: it reads every page in `LOG_CONTENTS` and only a handful of entries survive the date filter. Report content is written in Traditional Chinese (STE100).
## 1. Period
Ask for the period per the `jsc-ask:ask` rules when the caller did not name one: `daily`, `weekly`, `monthly`, `yearly`. Each option states what it covers.
Run `tools/report-range.sh {period} [yyyy-MM-dd]` — it prints `{start}<TAB>{end}<TAB>{label}<TAB>{period}`, both dates inclusive. The base date defaults to today; pass one to re-run an earlier period.
Never work the dates out by hand. Week boundaries and month lengths are exactly where a hand-rolled range quietly loses a day.
Done when start, end and label are known.
## 2. Template
Run `tools/report-template.sh resolve {period}` from the working directory. It prints `{path}<TAB>{project|skill}`.
`project` means the working directory holds `.jsc/templates/report-{period}.md` and that file wins. Say which source was used in the final report — the same period rendered from two different templates has to be traceable to the file that shaped it.
Follow the template's headings and tables exactly, including ones with no data: an empty section stated as 無 is information, a silently dropped section is not.
Done when the template path and its source are known.
## 3. Collect
Read `LOG_CONTENTS` through `jsc-gitea:wiki` (repo from `jsc-gitea/tools/gitea.sh wiki-repo LOG`), then read every log page it lists. Entries start with `## {yyyy-MM-dd HH:mm}`; keep those whose date falls within start and end.
Aggregate from the entry tables: entry count, distinct repositories, elapsed time, token usage per CLI, task status counts, blockers, unfinished work packages. Sum only what the entries state — an entry with no 花費時間 stays out of the total and is reported as 無資料 rather than estimated.
A yearly report also reads `LEARN_CONTENTS` for its 全年教訓 section; other periods skip it.
Zero entries in range → produce the report anyway, with counts of 0 and a line saying which range came back empty. A silent "no report" cannot be told apart from a failure.
Done when every log page in the directory has been read and the aggregates are computed.
## 4. Write
Write through `jsc-gitea:wiki`:
- Repo: `gitea.sh wiki-repo REPORT`.
- Page: `REPORT_` plus `gitea.sh hash-id "{owner}/{repo}/{period}"`, where `{owner}/{repo}` is the REPORT wiki repo. Year, month, week and day each get their own page.
- Append this period as a new section, newest first. Rerunning the same period replaces that period's section only, leaving the other periods untouched.
- Refresh the page's row in `REPORT_CONTENTS` from `templates/report-contents.md`.
`wiki-repo` exit 3 → print the finished report and say the write was skipped because no wiki repo is configured for REPORT. The report itself is still the deliverable.
Done when the page URL is reported, or the skipped write is reported with its reason.
## 5. Close
State the period label, entry count, repositories covered, template source, and the page URL. Name every unfinished work package that carried over — that list is what the next period starts from.
Done when those five facts and the carry-over list are stated.