chore(release): 放行技能組稽核修正到預設分支 #23
+24
-6
@@ -10,8 +10,8 @@ Close the loop on skill runs: record what a run taught you, consult it before th
|
||||
## Target pages
|
||||
|
||||
- Directory page: `LEARN_CONTENTS`. Content page: `LEARN_{HASH}`, one page per repository.
|
||||
- Compute `{HASH}` from `{owner}/{repo}` with `jsc-gitea/tools/hash-id`.
|
||||
- Wiki repo resolution: `JSC_WIKI_REPO_LEARN` first, then `JSC_WIKI_REPO`. Inspect the inherited shell environment variables first; ask the user per the `jsc-ask:ask` rules only when neither resolves. Never borrow another type's `JSC_WIKI_REPO_{TYPE}`.
|
||||
- Compute `{HASH}` from `{owner}/{repo}` with `jsc-gitea/tools/hash-id`. Exit 1 means no SHA-1 helper on this machine: stop and report that `sha1sum` or `shasum` has to be installed, and never hand-compute the hash.
|
||||
- Wiki repo: run `jsc-gitea/tools/gitea.sh wiki-repo LEARN`. Exit 3 hands the question to `jsc-gitea:wiki`, which owns the resolution order and the wording; exit 2 means the type argument was misspelled, so fix it and rerun.
|
||||
- All wiki reads and writes go through `jsc-gitea:wiki`.
|
||||
|
||||
## Mode: record
|
||||
@@ -31,14 +31,32 @@ Run after a skill run that produced a reusable lesson.
|
||||
|
||||
2. Resolve `{owner}/{repo}` from `git remote get-url origin` and compute `{HASH}` with `jsc-gitea/tools/hash-id`. Done when the page name `LEARN_{HASH}` is known.
|
||||
3. Write the entry. This step MUST run as a sub agent; the main agent only confirms the write succeeded.
|
||||
- Read `LEARN_{HASH}` via `jsc-gitea:wiki`. If it does not exist, create it from `templates/learn-page.md`; otherwise APPEND the new row at the end of the table. Never overwrite existing rows.
|
||||
- Update `LEARN_CONTENTS` in the same pass (apply `templates/learn-contents.md`; add the repo row if missing, otherwise refresh its 最後更新時間).
|
||||
- Done when the sub agent reports both pages written and the main agent has confirmed the row exists on `LEARN_{HASH}`.
|
||||
- Read `LEARN_{HASH}` via `jsc-gitea:wiki` and branch on the exit code the underlying `gitea.sh wiki-get` returned. **Only exit 4 means the page is not there yet**; creating the page from the template on any other code appends this one row to a blank table and drops every lesson already recorded.
|
||||
|
||||
| Exit | Do |
|
||||
| --- | --- |
|
||||
| 0 | The table is in hand. APPEND the new row at the end of it and overwrite no existing row. Never rebuild the page from the template on this code |
|
||||
| 4 | The page really is absent. Create it from `templates/learn-page.md`, then add the row |
|
||||
| 7 | The token is invalid or lacks permission, so the old rows are unknown. Stop and report the token problem, and create no page |
|
||||
| 8 | Some other API failure. Stop and report that status, and create no page |
|
||||
|
||||
- Update `LEARN_CONTENTS` in the same pass (apply `templates/learn-contents.md`; add the repo row if missing, otherwise refresh its 最後更新時間), branching on its read exactly as above: only exit 4 creates the directory page from the template, while 7 and 8 stop the run instead of rebuilding a directory whose other repos' rows were never read. Touch no row that belongs to another repository.
|
||||
- A failed `jsc-gitea:wiki` write on either page: retry once. Still failing, stop and report which page was not written (`LEARN_{HASH}` or `LEARN_CONTENTS`) together with the row content that was meant to go in, so the lesson is not lost. Never report a page as written when it was not.
|
||||
- Done when the sub agent reports both pages written, the main agent has confirmed the row exists on `LEARN_{HASH}`, and the rows that were there before are still there.
|
||||
|
||||
## Mode: consult
|
||||
|
||||
Run before a skill run, to apply past lessons.
|
||||
|
||||
1. Resolve `{owner}/{repo}` and compute `{HASH}` as in record mode. Done when `LEARN_{HASH}` is known.
|
||||
2. Read `LEARN_CONTENTS` and the repo's `LEARN_{HASH}` via `jsc-gitea:wiki`. When either page is missing (exit 4), report 「無教訓紀錄」 and let the caller proceed. Done when both pages are read or reported missing.
|
||||
2. Read `LEARN_CONTENTS` and the repo's `LEARN_{HASH}` via `jsc-gitea:wiki`, and branch on the exit code `jsc-gitea/tools/gitea.sh` returned. Only 4 means the page is absent; every other failure code means the read never happened, so an empty page must never be inferred from it.
|
||||
|
||||
| Exit | Do |
|
||||
| --- | --- |
|
||||
| 4 | The page does not exist. Report 「無教訓紀錄」 for that page and let the caller proceed |
|
||||
| 5 | The page carries no `html_url`. Stop and report it; never assemble the URL by hand and never read it as an empty page |
|
||||
| 7 | The Gitea token is invalid or lacks permission (HTTP 401/403). Stop and report that the token has to be fixed. Reading this as 「無教訓紀錄」 is exactly the misread `gitea.sh` separates 7 from 4 to prevent |
|
||||
| 8 | Some other API failure, with the HTTP status in the message. Stop and report that status; retry only after the API is back |
|
||||
|
||||
Done when both pages are read, or reported missing under exit 4, or the run stopped on 5, 7 or 8.
|
||||
3. Surface every row whose 技能 matches the skill about to run, and summarize each matched 下次做法 for the caller to apply. Done when the matched rows (or 「無相符教訓」) are reported.
|
||||
|
||||
+60
-28
@@ -11,49 +11,81 @@ Reading and aggregating the log pages **MUST run as a sub agent**: it reads ever
|
||||
|
||||
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.
|
||||
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.
|
||||
| Exit | Meaning | Do |
|
||||
| --- | --- | --- |
|
||||
| 0 | Range printed | Read start, end and label out of the four fields |
|
||||
| 2 | Period name or base date rejected | Ask per the `jsc-ask:ask` rules which of the four periods was meant, or fix the `yyyy-MM-dd` base date, then rerun |
|
||||
| 4 | This machine's `date` does no date arithmetic | Stop and report that the range cannot be computed here. 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
|
||||
## 2. Resolve and collect
|
||||
|
||||
Run `tools/report-template.sh resolve {period}` from the working directory. It prints `{path}<TAB>{project|skill}`.
|
||||
Run these four lines of work in parallel — none of them consumes another's output, and the log pages are the slow one:
|
||||
|
||||
`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.
|
||||
1. **Template.** `tools/report-template.sh resolve {period}` from the working directory prints `{path}<TAB>{project|skill}`.
|
||||
2. **Log pages.** `jsc-gitea/tools/gitea.sh wiki-repo LOG`, then read `LOG_CONTENTS` through `jsc-gitea:wiki`, then read **every** log page it lists, one sub agent per page.
|
||||
3. **Lessons (yearly only).** `gitea.sh wiki-repo LEARN`, then read `LEARN_CONTENTS` through `jsc-gitea:wiki` for the 全年教訓 section. Resolve `JSC_WIKI_REPO_LEARN` on its own: the LOG repo resolved in line 2 never stands in for it, and LOG and LEARN pages routinely live in different wiki repos. Other periods skip this line.
|
||||
4. **Report repo.** `gitea.sh wiki-repo REPORT`, so step 3 has its target ready.
|
||||
|
||||
Exit branches for the external calls above:
|
||||
|
||||
| Call | Exit | Do |
|
||||
| --- | --- | --- |
|
||||
| `report-template.sh resolve` | 0 | Use the path; name the `project` or `skill` source in the final report. `project` means the working directory holds `.jsc/templates/report-{period}.md` and that file wins — the same period rendered from two templates has to be traceable to the file that shaped it |
|
||||
| `report-template.sh resolve` | 2 | Period name or start directory rejected. Rerun from the working directory with the period from step 1 |
|
||||
| `report-template.sh resolve` | 3 | Neither the project copy nor the skill's own copy exists. Stop and report that `templates/report-{period}.md` is missing from the plugin; do not invent a layout |
|
||||
| `gitea.sh wiki-repo LOG` | 3 | Stop and report that no wiki repo is configured for LOG, naming `JSC_WIKI_REPO_LOG` and `JSC_WIKI_REPO`. Ask per the `jsc-ask:ask` rules, then rerun. Without log pages there is nothing to summarise |
|
||||
| `gitea.sh wiki-repo LEARN` | 3 | Fill the 全年教訓 section with 無 and say the LEARN wiki repo is unset. The rest of the yearly report still stands |
|
||||
| `gitea.sh wiki-repo REPORT` | 3 | Carry on collecting; step 3 handles the skipped write |
|
||||
| `gitea.sh wiki-repo` any type | 2 | The page type was misspelled. Fix the argument and rerun |
|
||||
| `jsc-gitea:wiki` read | 4 | The page is genuinely absent. **Only this code** lets `LOG_CONTENTS` or a listed log page count as zero entries; name it in the close-out |
|
||||
| `jsc-gitea:wiki` read | 7 | The token is invalid or lacks permission. Stop and report the token problem. Counting this as zero entries publishes a report that says a period held no work when the work is sitting on a page nobody managed to read |
|
||||
| `jsc-gitea:wiki` read | 8 | Some other API failure. Stop and report that status; a page that failed to load must never be counted as an empty page |
|
||||
|
||||
Then aggregate. Save the collected page contents to files and run:
|
||||
|
||||
`tools/log-aggregate.sh {start} {end} {page file} ...`
|
||||
|
||||
It prints `ENTRIES=`, `REPOS=`, one `REPO=` line per repository, `ELAPSED_MINUTES=`, `ELAPSED_ENTRIES=`, `ELAPSED_MISSING=`, one `TOKEN=` line per CLI, `TOKEN_MISSING=` and one `STATUS=` line per status. It enforces the no-estimate rule in code: an entry with no 花費時間 stays out of the total and lands in `ELAPSED_MISSING`, and a range where nothing carried a time prints `ELAPSED_MINUTES=無資料` rather than `0`.
|
||||
|
||||
| Exit | Meaning | Do |
|
||||
| --- | --- | --- |
|
||||
| 0 | Aggregates printed | Carry the printed values into the template unchanged. Never recompute or round them by hand |
|
||||
| 2 | Dates rejected, or start later than end | Rerun with the step 1 values |
|
||||
| 3 | Zero entries inside the range; the zero-filled aggregate is still printed | Produce the report anyway, with counts of 0 and a line naming the empty range. A silent "no report" cannot be told apart from a failure |
|
||||
| 4 | A page file is unreadable | Stop and report which file, rather than reporting a smaller total |
|
||||
|
||||
Blockers and unfinished work packages come from the 任務狀態 and 遇到的困難與解決方式 parts of the surviving entries; the sub agent lists them verbatim.
|
||||
|
||||
Done when the template path, its source, the aggregate lines and the blocker list are all in hand.
|
||||
|
||||
## 3. Write
|
||||
|
||||
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`.
|
||||
- Repo: the REPORT repo from step 2, line 4.
|
||||
- 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.
|
||||
- Read the page first and branch on the exit code the underlying `gitea.sh wiki-get` returned. **Only exit 4 means the page is not there yet** and may be built from scratch. On exit 0 the existing sections are in hand, so append into them. On exit 7 the token is invalid or lacks permission, and on exit 8 the API failed some other way: both leave the earlier periods unknown, so stop, report the status and write nothing — a page rebuilt on top of an unread read loses every period already on it.
|
||||
- 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`.
|
||||
- Refresh the page's row in `REPORT_CONTENTS` from `templates/report-contents.md`: add the row if missing, otherwise refresh its 最新一期、期數 and 最後更新. Its read branches the same way — only exit 4 creates the directory page from the template, while 7 and 8 stop the run. Touch no row that belongs to another report page.
|
||||
|
||||
`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.
|
||||
| Call | Exit | Do |
|
||||
| --- | --- | --- |
|
||||
| `gitea.sh wiki-repo REPORT` | 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 |
|
||||
| `gitea.sh hash-id` | 1 | No SHA-1 helper on this machine. Stop and report that `sha1sum` or `shasum` has to be installed. Never hand-compute the hash |
|
||||
| `jsc-gitea:wiki` write | failure | Retry once. Still failing, stop and report the page name that was not written, and print the report body so the work is not lost. Never report a page as written when it was not |
|
||||
|
||||
Done when the page URL is reported, or the skipped write is reported with its reason.
|
||||
Write the content page before its row in `REPORT_CONTENTS`, never the two at once: a directory row pointing at a page whose write failed is worse than a missing row.
|
||||
|
||||
## 5. Close
|
||||
Done when the page URL is reported, or the skipped write is reported with its reason, or the run stopped on a read that returned 7 or 8 and that status was reported.
|
||||
|
||||
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.
|
||||
## 4. Close
|
||||
|
||||
Done when those five facts and the carry-over list are stated.
|
||||
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. State `ELAPSED_MISSING` and `TOKEN_MISSING` whenever either is above 0, so a small total is read as missing data rather than a light week.
|
||||
|
||||
Done when those five facts, the carry-over list and the two missing-data counts are stated.
|
||||
|
||||
@@ -17,5 +17,11 @@ Data is recorded continuously by `jsc-hooks/hooks/skill-usage.sh` under `$JSC_HO
|
||||
|
||||
## Reporting
|
||||
|
||||
1. Run the tool directly and present the output as a table. Done when every line the tool printed appears as one table row.
|
||||
2. When the tool prints no rows, explain that `jsc-hooks` must be installed and wired first via `jsc-hooks:hooks-install`. Done when that instruction is reported and no table is shown.
|
||||
1. Run the tool directly and branch on its exit code — never read the printed lines without it.
|
||||
|
||||
| Exit | Do |
|
||||
| --- | --- |
|
||||
| 0 | Present every printed line as one table row. No line printed is still exit 0: the data file under `$JSC_HOME/usage/` does not exist yet, which is a count of zero, not a failure — say the counts are zero and that `jsc-hooks` has to be installed and wired via `jsc-hooks:hooks-install` before anything is recorded, and show no table |
|
||||
| 2 | The subcommand or the `--cli` argument was rejected — the subcommand is neither `skills` nor `chains`, or `--cli` came with no value. Fix the argument and rerun. Never rerun the same command unchanged, and never report the counts as zero: nothing was read |
|
||||
|
||||
Done when the exit code was read and the branch it names was taken.
|
||||
|
||||
+41
-12
@@ -21,13 +21,15 @@ Guardrail: append entries at the end of the page and leave the existing ones unt
|
||||
|
||||
## Items to collect
|
||||
|
||||
Rows 3, 4, 5 and 6 each hit a different source and none of them reads another's output, so **fetch the four in parallel**. Rows 1 and 2 are two local `git` reads that join the same batch.
|
||||
|
||||
| # | Item | Source |
|
||||
| --- | --- | --- |
|
||||
| 1 | Repository name | Parse `{owner}/{repo}` from `git remote get-url origin`. This is the code repo — never pass it to `wiki-url`, which takes the wiki-hosting repo |
|
||||
| 2 | Branch name | `git branch --show-current` |
|
||||
| 3 | Plan name | Absolute link to the plan page: `[PLAN_{HASH}](<url>)`. Resolve the hosting repo with `jsc-gitea/tools/gitea.sh wiki-repo PLAN`, then take `<url>` from `gitea.sh wiki-url <that repo> PLAN_{HASH}` — PLAN and LOG may live in different wiki repos, and `[[...]]` only resolves inside one wiki. `wiki-repo` exit 3 (no wiki repo configured for that type) or `wiki-url` exit 4 (page not found) → fill the literal 「無」 for this row and carry on; a `worklog` run triggered from `maintain` normally has no plan page |
|
||||
| 4 | Work package id | Absolute link to the work package heading: `[WP-xx](<url>#wp-xx)`. Resolve the hosting repo with `gitea.sh wiki-repo ANALYZE`, then take `<url>` from `gitea.sh wiki-url <that repo> ANALYZE_{HASH}`. A comment-fix round links to the same work package it belongs to. Same fallback as row 3: `wiki-repo` exit 3 or `wiki-url` exit 4 → fill 「無」 and carry on |
|
||||
| 5 | Elapsed time | `jsc-hooks/hooks/session-timer.sh report {session_id}` (seconds; convert to h/m). Count only this task, so read it at the moment the task ends |
|
||||
| 3 | Plan name | Absolute link to the plan page: `[PLAN_{HASH}](<url>)`. Resolve the hosting repo with `jsc-gitea/tools/gitea.sh wiki-repo PLAN`, then take `<url>` from `gitea.sh wiki-url <that repo> PLAN_{HASH}` — PLAN and LOG may live in different wiki repos, and `[[...]]` only resolves inside one wiki. `wiki-repo` exit 3 (no wiki repo configured for that type) or `wiki-url` exit 4 (page not found) → fill the literal 「無」 for this row and carry on; a `worklog` run triggered from `maintain` normally has no plan page. `wiki-url` exit 5 → stop and report that the page carries no `html_url`; never assemble the URL by hand. `wiki-url` exit 7 (token invalid or no permission, HTTP 401/403) or exit 8 (other API failure) → stop and report the token or API status; never fill 「無」, because that records a page that exists as a page that does not |
|
||||
| 4 | Work package id | Absolute link to the work package heading: `[WP-xx](<url>#wp-xx)`. Resolve the hosting repo with `gitea.sh wiki-repo ANALYZE`, then take `<url>` from `gitea.sh wiki-url <that repo> ANALYZE_{HASH}`. A comment-fix round links to the same work package it belongs to. Same branching as row 3: `wiki-repo` exit 3 or `wiki-url` exit 4 → fill 「無」 and carry on; `wiki-url` exit 5 → stop and report that the page carries no `html_url`, never assemble the URL by hand; `wiki-url` exit 7 or 8 → stop and report the token or API status, never fill 「無」 |
|
||||
| 5 | Elapsed time | `jsc-hooks/hooks/session-timer.sh report {session_id}` prints `{sid} {seconds}` and always exits 0. Convert the seconds to h/m and read it at the moment the task ends, so it counts only this task. `0` means the timer holds no start record for that session, not a task that took no time: fill the literal 「無資料」 and say the timer had no record. Never estimate the duration from the transcript |
|
||||
| 6 | Token usage | `tools/token-usage.sh <cli> {session_id}` per CLI that ran; it prints `input<TAB>output`. Pass the same `{session_id}` as row 5 so the elapsed time and the token count describe one task. Fill `N/A` in both columns when it prints `N/A`; exit 2 means the CLI name is not one of claude / codex / copilot / antigravity / kiro, so fix the name and rerun |
|
||||
| 7 | Task status | One of the literal values 「完成」, 「部分完成」, 「阻塞」 (with reason when blocked). Derive it from the session when the session shows it; otherwise ask via `jsc-ask:ask`, offering those three literals as the options and stating each option's impact scope (「完成」 closes the task, 「部分完成」 leaves the remainder open for the next run, 「阻塞」 records the blocker and hands it back to the operator) |
|
||||
| 8 | Details and outputs | One line per changed file or produced page: what changed there and why. A round that changed nothing says what was tried and why it was dropped |
|
||||
@@ -38,12 +40,39 @@ The `{HASH}` in every page name above is computed with `jsc-gitea/tools/hash-id`
|
||||
|
||||
## Write the entry
|
||||
|
||||
1. Resolve the wiki repo hosting LOG pages with `gitea.sh wiki-repo LOG`: it reads `JSC_WIKI_REPO_LOG` first and falls back to `JSC_WIKI_REPO` only when that one is unset. Inspect the inherited shell environment first, and ask the user per the `jsc-ask:ask` rules when neither resolves. Keep to the LOG variable — another page type's `JSC_WIKI_REPO_{TYPE}` never stands in for it. Done when the hosting `{owner}/{repo}` is known.
|
||||
2. Compute `{HASH}` from the code repo's `{owner}/{repo}` with `jsc-gitea/tools/hash-id`. Done when the 8-character `{HASH}` is known.
|
||||
3. Run `tools/worklog-target.sh "{HASH}" all`. Use `PAGE` for `LOG_{HASH}` and `CONTENTS` for `LOG_CONTENTS`. Done when both page names are known.
|
||||
4. Fix the work week: the Friday of the current work week drives the page content and the row dates. Done when that Friday is fixed as a `yyyy-MM-dd` date.
|
||||
5. Fill `templates/log-entry.md` with the ten facts of this one task and save it to a file. Done when that file holds exactly one entry.
|
||||
6. Run `tools/worklog-pending.sh merge {HASH} {entry file}`. It prints `MERGED=` (pending content in time order, then this task's entry), `CLAIM=` (the pending files it took) and `PENDING=` (how many). Pending content was written by an earlier stage that ended without a work log, so it belongs in **this** write. Done when `MERGED` and `CLAIM` are known.
|
||||
7. Read `PAGE` via `jsc-gitea:wiki`. Create it from the structure in `templates/log-entry.md` when it does not exist, then append the whole `MERGED` content at the end. Done when every entry in `MERGED` exists on `PAGE`.
|
||||
8. Update `CONTENTS` in the same pass (apply `templates/log-contents.md`; add the row if missing, otherwise refresh its 條目數 and 最後更新). Done when the row for `PAGE` carries this week's Friday date.
|
||||
9. Close the pending area on the result of steps 7 and 8: `tools/worklog-pending.sh commit {HASH} {CLAIM}` after both succeeded, or `tools/worklog-pending.sh abort {HASH} {CLAIM}` after either failed. `abort` keeps every pending file for the retry, so keep the entry file too and rerun from step 6. Done when one of the two ran and printed its count.
|
||||
1. Resolve the LOG wiki repo and the entry's `{HASH}` **in parallel** — neither needs the other.
|
||||
- Repo: `gitea.sh wiki-repo LOG`. Exit 3 means no LOG wiki repo is configured; hand that to `jsc-gitea:wiki`, which owns the resolution order and the question to ask. Exit 2 means the type argument was misspelled, so fix it and rerun.
|
||||
- Hash: `jsc-gitea/tools/hash-id "{owner}/{repo}"` on the code repo from row 1. Exit 1 means this machine has no SHA-1 helper: stop and report that `sha1sum` or `shasum` has to be installed, and never hand-compute the hash.
|
||||
|
||||
Done when the hosting `{owner}/{repo}` and the 8-character `{HASH}` are both known.
|
||||
2. Run `tools/worklog-target.sh "{HASH}" all` and `tools/worklog-target.sh friday` in parallel. `all` prints `PAGE=LOG_{HASH}` and `CONTENTS=LOG_CONTENTS`; `friday` prints the Friday of the current work week as `yyyy-MM-dd`, which drives the page content and the row dates. Exit 2 means the arguments were rejected, so fix them and rerun. Exit 4 from `friday` means this machine's `date` does no date arithmetic: stop and report it, because a hand-picked Friday is exactly what goes wrong across a month or year boundary. Done when both page names and that Friday date are known.
|
||||
3. Fill `templates/log-entry.md` with the ten facts of this one task and save it to a file. Done when that file holds exactly one entry.
|
||||
4. Run `tools/worklog-pending.sh merge {HASH} {entry file}`. It prints `MERGED=` (pending content in time order, then this task's entry), `CLAIM=` (the pending files it took) and `PENDING=` (how many). Pending content was written by an earlier stage that ended without a work log, so it belongs in **this** write.
|
||||
|
||||
| Exit | Do |
|
||||
| --- | --- |
|
||||
| 0 | Carry on with `MERGED` and `CLAIM`. `PENDING=0` is normal and still exit 0 |
|
||||
| 1 | A read or write under `$JSC_HOME/worklog-pending` failed. Stop and report the path from the message; nothing was deleted, so a rerun loses nothing |
|
||||
| 2 | The `{HASH}` is not 8 uppercase alphanumerics, or the entry file argument is missing. Fix the argument and rerun from step 1 |
|
||||
|
||||
Done when `MERGED` and `CLAIM` are known.
|
||||
5. Read `PAGE` via `jsc-gitea:wiki`, and branch on the exit code the underlying `gitea.sh wiki-get` returned. **Only exit 4 means the page is not there yet.** Reading any other code as "it does not exist" builds a fresh page from `templates/log-entry.md` and appends to that — which replaces the whole existing work log with this one entry, and no entry on it can be recovered from the wiki afterwards.
|
||||
|
||||
| Exit | Do |
|
||||
| --- | --- |
|
||||
| 0 | The existing content is in hand. Append the whole `MERGED` content at the end of it, and leave every existing entry byte for byte as it was. Never rebuild the page from the template on this code |
|
||||
| 4 | The page really is absent. Create it from the structure in `templates/log-entry.md`, then append `MERGED` |
|
||||
| 7 | The key is invalid or lacks permission, so the old content is unknown. Stop and report the key problem, write nothing and create no page — a page created here would take the place of a log that is still on the server |
|
||||
| 8 | Some other API failure. Stop and report that status, write nothing and create no page. Retry only after the API is back |
|
||||
|
||||
A failed write stops the run and goes to step 7 as a failure — never report the page as written when it was not. Done when every entry in `MERGED` is on `PAGE`, every entry that was already there is still there, and any 4 / 7 / 8 branch was followed as stated.
|
||||
6. Update `CONTENTS` in the same pass (apply `templates/log-contents.md`; add the row if missing, otherwise refresh its 條目數 and 最後更新). Its read branches exactly as step 5 does: only exit 4 creates the directory page from the template, while 7 and 8 stop the run rather than rebuild a directory whose other rows were never read. Touch no row that belongs to another page. Done when the row for `PAGE` carries this week's Friday date from step 2 and every other row is unchanged.
|
||||
7. Close the pending area on the result of steps 5 and 6: `tools/worklog-pending.sh commit {HASH} {CLAIM}` after both succeeded, or `tools/worklog-pending.sh abort {HASH} {CLAIM}` after either failed. `abort` keeps every pending file for the retry, so keep the entry file too and rerun from step 4.
|
||||
|
||||
| Exit | Do |
|
||||
| --- | --- |
|
||||
| 0 | Report the printed count. This is the only ending that clears pending content |
|
||||
| 1 | A pending file or the claim list could not be removed. Report the path and say the pending area still holds content, so the next run will merge it again — duplicate entries on `PAGE` are the thing to watch for |
|
||||
| 2 | The claim path is not the one `merge` produced, or it points outside this `{HASH}`'s pending directory. Rerun from step 4 with the `CLAIM` value that `merge` printed; never pass a hand-written path |
|
||||
|
||||
Done when one of the two ran and its exit code was reported.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# 教訓目錄
|
||||
|
||||
> 由 `jsc-log:learn` 維護。這是教訓目錄頁 `LEARN_CONTENTS`。每個存取庫一列;`LEARN_{HASH}` 的 `{HASH}` 依共用 wiki hash 規則產生:先取 `{owner}/{repo}` 的 SHA-1 前 8 碼並轉成大寫;首碼若是 `0-9`、`A`、`B`、`C`,改用 `H` 加上原前 7 碼,總長維持 8 碼。
|
||||
> 寫入語意:一列代表一個存取庫。先讀整頁,找得到該存取庫既有的那一列就更新那一列,找不到才新增一列。
|
||||
> 禁止整頁覆蓋,也不得改動別人的列。
|
||||
|
||||
| 存取庫名稱 | 教訓紀錄 | 最後更新時間 |
|
||||
| --- | --- | --- |
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# 日誌目錄
|
||||
|
||||
> 由 `jsc-log:worklog` 維護。每個日誌頁一列;頁名使用共享 `HASH` 規則,頁內仍依該週五日期整理。
|
||||
> 寫入語意:一列代表一個日誌頁。先讀整頁,找得到該頁既有的那一列就更新那一列,找不到才新增一列。
|
||||
> 禁止整頁覆蓋,也不得改動別人的列。
|
||||
|
||||
| 日誌頁 | 週五日期 | 條目數 | 最後更新 |
|
||||
| --- | --- | --- | --- |
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# 報表目錄
|
||||
|
||||
> 由 `jsc-log:report` 維護。年、月、週、日各一頁;`HASH` 取 `{owner}/{repo}/{期間}`,算法與其他頁面共用。
|
||||
> 寫入語意:一列代表一個報表頁,也就是一個存取庫的一種期間。先讀整頁,找得到該報表頁既有的那一列就更新那一列,找不到才新增一列。
|
||||
> 禁止整頁覆蓋,也不得改動別人的列。
|
||||
|
||||
| 報表頁 | 期間 | 最新一期 | 期數 | 最後更新 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
|
||||
+13
-3
@@ -4,13 +4,23 @@
|
||||
# usage-stats.sh skills [--cli <name>] # 每個 skill 的使用次數(降冪)
|
||||
# usage-stats.sh chains [--cli <name>] # 每條 from -> to 呼叫鏈的次數(降冪)
|
||||
# 資料: $JSC_HOME/usage/skills.jsonl、chains.jsonl(預設 $HOME/.jsc)
|
||||
#
|
||||
# 結束碼: 0=成功(資料檔不存在也算成功,印不出任何一行)2=用法錯誤(沒給子命令、
|
||||
# 子命令不認得、--cli 沒帶值)
|
||||
# 資料檔不存在為什麼算成功: hook 還沒記過任何一次用量就是這個狀態,那是「零次」,不是故障。
|
||||
set -u
|
||||
JSC_HOME="${JSC_HOME:-$HOME/.jsc}"
|
||||
cmd="${1:?usage: usage-stats.sh skills|chains [--cli <name>]}"; shift
|
||||
usage() {
|
||||
echo '用法:usage-stats.sh skills|chains [--cli <name>]' >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
cmd="${1:-}"; [ -n "$cmd" ] || usage
|
||||
shift
|
||||
cli=""
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--cli) cli="${2:?--cli needs a value}"; shift 2 ;;
|
||||
--cli) cli="${2:-}"; [ -n "$cli" ] || usage; shift 2 ;;
|
||||
*) shift ;;
|
||||
esac
|
||||
done
|
||||
@@ -28,5 +38,5 @@ case "$cmd" in
|
||||
f="$JSC_HOME/usage/chains.jsonl"; [ -f "$f" ] || exit 0
|
||||
by_cli < "$f" | sed -n 's/.*"from":"\([^"]*\)".*"to":"\([^"]*\)".*/\1 -> \2/p' | rank ;;
|
||||
*)
|
||||
echo "unknown command: $cmd" >&2; exit 2 ;;
|
||||
echo "不認得的子命令:$cmd" >&2; usage ;;
|
||||
esac
|
||||
|
||||
Reference in New Issue
Block a user