Merge pull request 'feat/log-period-report-skill' (#14) from feat/log-period-report-skill into develop

Reviewed-on: #14
This commit was merged in pull request #14.
This commit is contained in:
2026-08-26 02:51:27 +00:00
12 changed files with 388 additions and 4 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "jsc-log", "name": "jsc-log",
"version": "0.0.9", "version": "0.1.0",
"description": "工作日誌(LOG_{HASH} wiki 頁)、技能使用統計與教訓紀錄(LEARN_{HASH} wiki 頁)", "description": "工作日誌(LOG_{HASH} wiki 頁)、技能使用統計與教訓紀錄(LEARN_{HASH} wiki 頁)",
"skills": "./skills", "skills": "./skills",
"author": { "author": {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "jsc-log", "name": "jsc-log",
"version": "0.0.9", "version": "0.1.0",
"description": "工作日誌(LOG_{HASH} wiki 頁)、技能使用統計與教訓紀錄(LEARN_{HASH} wiki 頁)", "description": "工作日誌(LOG_{HASH} wiki 頁)、技能使用統計與教訓紀錄(LEARN_{HASH} wiki 頁)",
"skills": "./skills" "skills": "./skills"
} }
+14 -1
View File
@@ -25,6 +25,8 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/meta.git),安
| `tools/usage-stats.sh` | 聚合 `$JSC_HOME/usage/*.jsonl`:`skills` 列技能使用次數、`chains` 列呼叫鏈次數(皆降冪),`--cli <name>` 過濾 | | `tools/usage-stats.sh` | 聚合 `$JSC_HOME/usage/*.jsonl`:`skills` 列技能使用次數、`chains` 列呼叫鏈次數(皆降冪),`--cli <name>` 過濾 |
| `tools/worklog-target.sh` | 接收已由 `jsc-gitea/tools/hash-id` 算好的 `HASH`,組出 `LOG_{HASH}`、`LOG_CONTENTS`(本身不再計算 SHA-1) | | `tools/worklog-target.sh` | 接收已由 `jsc-gitea/tools/hash-id` 算好的 `HASH`,組出 `LOG_{HASH}`、`LOG_CONTENTS`(本身不再計算 SHA-1) |
| `tools/worklog-pending.sh` | 待寫入日誌的暫存區,存放於 `$JSC_HOME/worklog-pending/{HASH}/`。`add {HASH} {檔案}` 存一段內容(`jsc-sdlc` 的階段回報發現沒寫日誌時會呼叫),`cat {HASH}` 依時間印出全部、`list` 列路徑、`clear` 清除。結束碼 `3` 代表沒有暫存內容。**寫進 wiki 成功之後才 clear**,先清再寫會兩邊都沒有 | | `tools/worklog-pending.sh` | 待寫入日誌的暫存區,存放於 `$JSC_HOME/worklog-pending/{HASH}/`。`add {HASH} {檔案}` 存一段內容(`jsc-sdlc` 的階段回報發現沒寫日誌時會呼叫),`cat {HASH}` 依時間印出全部、`list` 列路徑、`clear` 清除。結束碼 `3` 代表沒有暫存內容。**寫進 wiki 成功之後才 clear**,先清再寫會兩邊都沒有 |
| `tools/report-range.sh` | 算報表期間:`report-range.sh {daily\|weekly\|monthly\|yearly} [yyyy-MM-dd]` 印出「起<TAB>訖<TAB>標籤<TAB>期間」,含頭含尾。週採 ISO-8601(週一起算),標籤如 `2026-W35`。日期運算交給系統的 `date`,不自己算閏年 |
| `tools/report-template.sh` | 解析報表範本位置:`resolve {period}` 印出「路徑<TAB>project\|skill」,`list` 一次列四種期間。工作目錄的 `.jsc/templates/report-{period}.md` 優先於技能自帶的 `templates/` |
| `tools/token-usage.sh` | 讀單一 CLI 這次工作的 token 用量,印出「input(tab)output」;來源讀不到就印「N/A(tab)N/A」並正常結束。第二個參數傳 session id,就只讀該階段的 transcript,數字才會跟花費時間對得上。各 CLI 的取得方式寫在腳本開頭註解 | | `tools/token-usage.sh` | 讀單一 CLI 這次工作的 token 用量,印出「input(tab)output」;來源讀不到就印「N/A(tab)N/A」並正常結束。第二個參數傳 session id,就只讀該階段的 transcript,數字才會跟花費時間對得上。各 CLI 的取得方式寫在腳本開頭註解 |
## Skills 目錄 ## Skills 目錄
@@ -45,6 +47,10 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/meta.git),安
技能執行後把教訓(日期、技能、CLI、情境、教訓、下次做法)附加到 `LEARN_{HASH}` 並更新 `LEARN_CONTENTS`;技能執行前查閱同兩頁,套用相符的「下次做法」。 技能執行後把教訓(日期、技能、CLI、情境、教訓、下次做法)附加到 `LEARN_{HASH}` 並更新 `LEARN_CONTENTS`;技能執行前查閱同兩頁,套用相符的「下次做法」。
### `report`
把工作日誌總結成年報、月報、週報或日報。期間由 `tools/report-range.sh` 算出(週次採 ISO-8601),範本由 `tools/report-template.sh` 解析——工作目錄的 `.jsc/templates/report-{period}.md` 優先,沒有才用技能自帶的那份。讀 `LOG_CONTENTS` 列出的所有日誌頁,取工作日期落在期間內的條目,統計條目數、涵蓋存取庫、花費時間、token 用量、困難與未結項目,填進範本後寫入 wiki `REPORT_{HASH}`(`HASH` 取 `{owner}/{repo}/{期間}`),同一期間重跑只換掉那一節。單筆工作紀錄請用 `worklog`。
<!-- JSC-SKILLS:END --> <!-- JSC-SKILLS:END -->
## 範本 ## 範本
@@ -55,10 +61,17 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/meta.git),安
| `templates/log-contents.md` | 日誌目錄 `LOG_CONTENTS` | | `templates/log-contents.md` | 日誌目錄 `LOG_CONTENTS` |
| `templates/learn-page.md` | 教訓紀錄頁 `LEARN_{HASH}`(六欄表格,逐列附加) | | `templates/learn-page.md` | 教訓紀錄頁 `LEARN_{HASH}`(六欄表格,逐列附加) |
| `templates/learn-contents.md` | 教訓目錄 `LEARN_CONTENTS` | | `templates/learn-contents.md` | 教訓目錄 `LEARN_CONTENTS` |
| `templates/report-daily.md` | 日報:當天產出、卡住的地方、明天接著做 |
| `templates/report-weekly.md` | 週報:本週產出、用時分布、困難與解法、滾到下週的項目 |
| `templates/report-monthly.md` | 月報:本月成果、逐週推進、重複出現的困難、月底未結 |
| `templates/report-yearly.md` | 年報:全年總覽、逐月推進、里程碑、全年教訓、年底未結 |
| `templates/report-contents.md` | 報表目錄 `REPORT_CONTENTS` |
工作目錄放一份同名的 `.jsc/templates/report-{period}.md`,就會蓋過技能自帶的範本,不必改技能。
## 環境變數 ## 環境變數
Wiki 位置:日誌頁用 `JSC_WIKI_REPO_LOG`、教訓頁用 `JSC_WIKI_REPO_LEARN`,未設定退回 `JSC_WIKI_REPO`,再未設定就詢問(見 `jsc-gitea`)。先讀目前 shell 繼承的環境變數,缺值才詢問。 Wiki 位置:日誌頁用 `JSC_WIKI_REPO_LOG`、教訓頁用 `JSC_WIKI_REPO_LEARN`、報表頁用 `JSC_WIKI_REPO_REPORT`,未設定退回 `JSC_WIKI_REPO`,再未設定就詢問(見 `jsc-gitea`)。先讀目前 shell 繼承的環境變數,缺值才詢問。
## 相關 domain ## 相關 domain
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "jsc-log", "name": "jsc-log",
"version": "0.0.9", "version": "0.1.0",
"description": "工作日誌(LOG_{HASH} wiki 頁)、技能使用統計與教訓紀錄(LEARN_{HASH} wiki 頁)", "description": "工作日誌(LOG_{HASH} wiki 頁)、技能使用統計與教訓紀錄(LEARN_{HASH} wiki 頁)",
"skills": "./skills/" "skills": "./skills/"
} }
+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.
+7
View File
@@ -0,0 +1,7 @@
# 報表目錄
> 由 `jsc-log:report` 維護。年、月、週、日各一頁;`HASH` 取 `{owner}/{repo}/{期間}`,算法與其他頁面共用。
| 報表頁 | 期間 | 最新一期 | 期數 | 最後更新 |
| --- | --- | --- | --- | --- |
| [[REPORT_{HASH}]] | {daily、weekly、monthly、yearly 四選一} | {最新一期的標籤} | {n} | {yyyy-MM-dd HH:mm} |
+27
View File
@@ -0,0 +1,27 @@
# 日報 {yyyy-MM-dd}
> 由 `jsc-log:report` 產生。資料來源:`LOG_CONTENTS` 列出的所有工作日誌頁,取工作日期落在 {yyyy-MM-dd} 當天的條目。
> 專案要自訂格式,在工作目錄放一份 `.jsc/templates/report-daily.md` 就會蓋過這一份。
- 期間:{yyyy-MM-dd}(含)
- 條目數:{n}
- 涵蓋存取庫:{n}
- 花費時間合計:{h} 小時 {m} 分
## 今天做完什麼
| 存取庫 | 工作包 | 摘要 | 狀態 | 花費時間 |
| --- | --- | --- | --- | --- |
| {owner}/{repo} | [WP-{編號}]({ANALYZE 頁絕對網址}#wp-{編號}) | {一句話} | {完成、部分完成、阻塞} | {h}h{m}m |
## 卡住的地方
| 存取庫 | 困難 | 目前處置 | 還缺什麼 |
| --- | --- | --- | --- |
| {owner}/{repo} | {困難} | {已做的處置} | {待解} |
> 沒有阻塞項目時,整張表寫一列「無」。
## 明天接著做
- {下一步,取自未完成條目的剩餘 todo}
+48
View File
@@ -0,0 +1,48 @@
# 月報 {yyyy-MM}
> 由 `jsc-log:report` 產生。資料來源:`LOG_CONTENTS` 列出的所有工作日誌頁,取工作日期落在 {start} 到 {end} 之間的條目。
> 專案要自訂格式,在工作目錄放一份 `.jsc/templates/report-monthly.md` 就會蓋過這一份。
- 期間:{start} 到 {end}
- 條目數:{n}
- 涵蓋存取庫:{n}
- 花費時間合計:{h} 小時 {m} 分
- token 用量合計:{CLI}: {input}/{output}
## 本月成果
| 存取庫 | 完成工作包 | 部分完成 | 阻塞 | 花費時間 |
| --- | --- | --- | --- | --- |
| {owner}/{repo} | {n} | {n} | {n} | {h}h{m}m |
## 逐週推進
```mermaid
xychart-beta
title "每週花費時間(小時)"
x-axis [{yyyy}-W{ww}, {yyyy}-W{ww}, {yyyy}-W{ww}, {yyyy}-W{ww}]
y-axis "小時" 0 --> {上限}
bar [{h}, {h}, {h}, {h}]
```
| 週次 | 條目數 | 完成 | 花費時間 | 主要進展 |
| --- | --- | --- | --- | --- |
| {yyyy}-W{ww} | {n} | {n} | {h}h{m}m | {一句話} |
## 重複出現的困難
> 同一類困難出現兩次以上才列進來。只出現一次的留在週報,不往上滾。
| 困難 | 出現次數 | 影響存取庫 | 根因 | 對策 |
| --- | --- | --- | --- | --- |
| {困難} | {n} | {owner}/{repo} | {根因} | {對策} |
## 月底未結
| 存取庫 | 工作包 | 狀態 | 卡多久 | 下一步 |
| --- | --- | --- | --- | --- |
| {owner}/{repo} | WP-{編號} | {部分完成、阻塞} | {n} 天 | {下一步} |
## 下月重點
- {下一批工作包或維護項目}
+39
View File
@@ -0,0 +1,39 @@
# 週報 {yyyy}-W{ww}
> 由 `jsc-log:report` 產生。資料來源:`LOG_CONTENTS` 列出的所有工作日誌頁,取工作日期落在 {start} 到 {end} 之間的條目。
> 週次採 ISO-8601,週一起算、週日結束。專案要自訂格式,在工作目錄放一份 `.jsc/templates/report-weekly.md` 就會蓋過這一份。
- 期間:{start} 到 {end}
- 條目數:{n}
- 涵蓋存取庫:{n}
- 花費時間合計:{h} 小時 {m} 分
- token 用量合計:{CLI}: {input}/{output}
## 本週產出
| 存取庫 | 工作包 | 摘要 | 狀態 | 花費時間 | PR |
| --- | --- | --- | --- | --- | --- |
| {owner}/{repo} | [WP-{編號}]({ANALYZE 頁絕對網址}#wp-{編號}) | {一句話} | {完成、部分完成、阻塞} | {h}h{m}m | [{base 分支}]({PR URL}) |
## 各存取庫用時分布
```mermaid
pie title 本週花費時間(分鐘)
"{owner}/{repo}" : {分鐘}
```
## 困難與解法
| 困難 | 解決方式 | 是否已解 |
| --- | --- | --- |
| {困難} | {解法} | {是、否} |
## 未完成,滾到下週
| 存取庫 | 工作包 | 剩下什麼 | 阻塞原因 |
| --- | --- | --- | --- |
| {owner}/{repo} | WP-{編號} | {剩餘 todo} | {原因,無阻塞寫「無」} |
## 下週重點
- {取自未完成條目與計畫頁的下一批工作包}
+54
View File
@@ -0,0 +1,54 @@
# 年報 {yyyy}
> 由 `jsc-log:report` 產生。資料來源:`LOG_CONTENTS` 列出的所有工作日誌頁,取工作日期落在 {start} 到 {end} 之間的條目。
> 專案要自訂格式,在工作目錄放一份 `.jsc/templates/report-yearly.md` 就會蓋過這一份。
- 期間:{start} 到 {end}
- 條目數:{n}
- 涵蓋存取庫:{n}
- 花費時間合計:{h} 小時
- token 用量合計:{CLI}: {input}/{output}
## 全年總覽
| 存取庫 | 完成工作包 | 花費時間 | 佔比 | 最後一次動工 |
| --- | --- | --- | --- | --- |
| {owner}/{repo} | {n} | {h}h | {n}% | {yyyy-MM-dd} |
## 逐月推進
```mermaid
xychart-beta
title "每月完成工作包數"
x-axis [01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12]
y-axis "工作包" 0 --> {上限}
bar [{n}, {n}, {n}, {n}, {n}, {n}, {n}, {n}, {n}, {n}, {n}, {n}]
```
| 月份 | 條目數 | 完成 | 花費時間 | 主要里程碑 |
| --- | --- | --- | --- | --- |
| {yyyy-MM} | {n} | {n} | {h}h | {一句話} |
## 全年里程碑
| 日期 | 存取庫 | 里程碑 | 交付文件 |
| --- | --- | --- | --- |
| {yyyy-MM-dd} | {owner}/{repo} | {里程碑} | [{DELIVER 頁名}]({絕對網址}) |
## 全年教訓
> 取自 `LEARN_CONTENTS` 的教訓頁,只列同類重複三次以上、或造成整批工作停擺的那幾條。
| 教訓 | 出現次數 | 已改成什麼做法 |
| --- | --- | --- |
| {教訓} | {n} | {現行做法} |
## 年底未結
| 存取庫 | 工作包 | 狀態 | 卡多久 | 打算怎麼處理 |
| --- | --- | --- | --- | --- |
| {owner}/{repo} | WP-{編號} | {部分完成、阻塞} | {n} 天 | {處理方式} |
## 明年方向
- {取自計畫頁尚未動工的使用者故事}
+75
View File
@@ -0,0 +1,75 @@
#!/usr/bin/env sh
# report-range.sh — 算出報表期間的起訖日期與標籤(供 jsc-log:report 呼叫)。
# 用法:
# report-range.sh {daily|weekly|monthly|yearly} [基準日期 yyyy-MM-dd]
# 基準日期省略時用今天。輸出一行 TSV:
# {start}<TAB>{end}<TAB>{label}<TAB>{period}
# start、end 皆為 yyyy-MM-dd,含頭含尾。
# label:daily=2026-08-26、weekly=2026-W35、monthly=2026-08、yearly=2026
#
# 週的定義採 ISO-8601:週一起算、週日結束,標籤用 ISO 週次。worklog 頁內以工作週的
# 週五整理內容,週次與那個週五落在同一週,兩邊對得起來。
#
# 日期運算優先用 GNU date -d,退回 BSD date -v。兩者都不支援就 exit 4,不自己算閏年:
# 手刻日期運算出錯的方式很安靜,報表會少算一天而沒有人發現。
#
# 結束碼: 0=成功 2=用法錯誤 4=系統的 date 不支援日期運算
set -eu
usage() {
echo "用法:report-range.sh {daily|weekly|monthly|yearly} [yyyy-MM-dd]" >&2
exit 2
}
period="${1:-}"
case "$period" in daily|weekly|monthly|yearly) ;; *) usage ;; esac
base="${2:-}"
if [ -z "$base" ]; then
base=$(date +%Y-%m-%d)
else
case "$base" in
[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]) ;;
*) echo "基準日期格式要是 yyyy-MM-dd:$base" >&2; exit 2 ;;
esac
fi
# $1=基準日 $2=偏移(例 -3 days、+1 month)$3=輸出格式
shift_date() {
if date -d "$1 $2" "+$3" >/dev/null 2>&1; then
date -d "$1 $2" "+$3"
return 0
fi
# BSD:偏移寫法不同(-v-3d),只轉換這裡真的用到的幾種
_bsd=$(printf '%s' "$2" | sed 's/ days\{0,1\}/d/; s/ months\{0,1\}/m/; s/ years\{0,1\}/y/; s/^+/+/')
if date -j -f %Y-%m-%d -v"$_bsd" "$1" "+$3" >/dev/null 2>&1; then
date -j -f %Y-%m-%d -v"$_bsd" "$1" "+$3"
return 0
fi
echo "系統的 date 不支援日期運算,算不出報表期間" >&2
exit 4
}
fmt() { shift_date "$1" "+0 days" "$2"; }
case "$period" in
daily)
start="$base"; end="$base"
label=$(fmt "$base" %Y-%m-%d) ;;
weekly)
# ISO 週:週一為第 1 天。%u 給 1(週一)到 7(週日)。
dow=$(fmt "$base" %u)
start=$(shift_date "$base" "-$((dow - 1)) days" %Y-%m-%d)
end=$(shift_date "$start" "+6 days" %Y-%m-%d)
label=$(fmt "$base" %G-W%V) ;;
monthly)
start=$(fmt "$base" %Y-%m-01)
end=$(shift_date "$(shift_date "$start" "+1 month" %Y-%m-%d)" "-1 day" %Y-%m-%d)
label=$(fmt "$base" %Y-%m) ;;
yearly)
start=$(fmt "$base" %Y-01-01)
end=$(fmt "$base" %Y-12-31)
label=$(fmt "$base" %Y) ;;
esac
printf '%s\t%s\t%s\t%s\n' "$start" "$end" "$label" "$period"
+62
View File
@@ -0,0 +1,62 @@
#!/usr/bin/env sh
# report-template.sh — 解析報表範本的位置(供 jsc-log:report 呼叫)。
# 用法:
# report-template.sh resolve {daily|weekly|monthly|yearly} [起始目錄]
# report-template.sh list [起始目錄]
#
# 解析順序:工作目錄的 .jsc/templates/report-{period}.md 優先,沒有才用技能自帶的
# templates/report-{period}.md。專案要自訂報表格式時,放一份同名檔案就換掉範本,
# 不必改技能。起始目錄省略時用目前工作目錄。
#
# 輸出(resolve):{絕對路徑}<TAB>{project|skill}
# 輸出(list):每種期間一行 {period}<TAB>{絕對路徑}<TAB>{project|skill}
#
# 結束碼: 0=找到 2=用法錯誤 3=兩處都找不到範本(技能自帶的那份被刪了)
set -eu
HERE=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
SKILL_TPL=$(CDPATH= cd -- "$HERE/.." && pwd)/templates
TAB=$(printf '\t')
usage() {
echo "用法:report-template.sh {resolve {daily|weekly|monthly|yearly} [起始目錄]|list [起始目錄]}" >&2
exit 2
}
resolve_one() { # $1=period $2=起始目錄
_p="$1"; _d="$2"
_proj="$_d/.jsc/templates/report-$_p.md"
if [ -f "$_proj" ]; then
printf '%s%s%s\n' "$_proj" "$TAB" project
return 0
fi
_skill="$SKILL_TPL/report-$_p.md"
if [ -f "$_skill" ]; then
printf '%s%s%s\n' "$_skill" "$TAB" skill
return 0
fi
return 3
}
cmd="${1:-}"
case "$cmd" in
resolve)
period="${2:-}"
case "$period" in daily|weekly|monthly|yearly) ;; *) usage ;; esac
dir="${3:-$PWD}"
dir=$(CDPATH= cd -- "$dir" 2>/dev/null && pwd) || { echo "找不到目錄:${3:-$PWD}" >&2; exit 2; }
resolve_one "$period" "$dir" || {
echo "找不到 report-$period.md:$dir/.jsc/templates/ 與 $SKILL_TPL 都沒有" >&2
exit 3
} ;;
list)
dir="${2:-$PWD}"
dir=$(CDPATH= cd -- "$dir" 2>/dev/null && pwd) || { echo "找不到目錄:${2:-$PWD}" >&2; exit 2; }
rc=0
for p in daily weekly monthly yearly; do
out=$(resolve_one "$p" "$dir") || { printf '%s\t-\tmissing\n' "$p"; rc=3; continue; }
printf '%s\t%s\n' "$p" "$out"
done
exit "$rc" ;;
*) usage ;;
esac