feat(learn): 教訓目錄頁改成一個存取庫一個大標題區塊
教訓目錄頁的版面從 markdown 表格換成「大標題加條列」:一個存取庫一個大標題 區塊,標題就是那個存取庫教訓頁的實際頁名,存取庫名稱、教訓紀錄連結、最後 更新時間改成標題底下的一層條列。範本與 learn 技能的寫入敘述一起跟上。 表格的欄位組合是整頁共用的,一頁上卻有很多存取庫各自的紀錄,每一輪只重寫 自己那一列。欄位一增減,舊列的格數與表頭就對不上,而目錄頁不能整頁覆蓋—— 覆蓋等於刪掉別人的紀錄。條列一筆一個區塊,欄位各自獨立,加一條只動到自己 那一個區塊。 比對鍵從存取庫名稱那一格改成大標題本身,標題寫成教訓頁的實際頁名。頁名只由 存取庫的擁有者與名稱決定,換主機位址、改存取庫或頁名編碼有差都動不到它。 欄號那個參數配合線上實際欄位改成教訓紀錄那一欄:轉檔時取那一格的文字當 標題,格子寫成連結就只取顯示文字。欄號填錯的話,轉出來的標題跟鍵對不上, 既有那一筆會被當成新的附加上去,同一個存取庫變兩個區塊。 範圍是教訓紀錄的目錄頁與 learn 技能。
This commit is contained in:
+16
-15
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: learn
|
||||
description: Record a lesson learned after a skill run to wiki LEARN_{HASH} plus LEARN_CONTENTS, or consult past lessons before a skill run. Each entry is one table row with date, skill, CLI, situation, lesson, and next-time approach. HASH is the full 40-character uppercase SHA-1 of {owner}/{repo}; LEARN_{HASH} sits in the LEARN wiki repo while LEARN_CONTENTS sits in the separate CONTENTS repo, so the directory row goes through jsc-gitea/tools/wiki-contents.sh upsert and links the lesson page by its absolute wiki-url. Use when a skill run produced a reusable lesson, or before running a skill to consult past lessons; not for work-time logs (see worklog).
|
||||
description: Record a lesson learned after a skill run to wiki LEARN_{HASH} plus LEARN_CONTENTS, or consult past lessons before a skill run. Each entry is one table row with date, skill, CLI, situation, lesson, and next-time approach. HASH is the full 40-character uppercase SHA-1 of {owner}/{repo}; LEARN_{HASH} sits in the LEARN wiki repo while LEARN_CONTENTS sits in the separate CONTENTS repo, so the directory entry goes through jsc-gitea/tools/wiki-contents.sh upsert as one H2 block keyed by the page name LEARN_{HASH}, with a bullet per field and the lesson page linked by its absolute wiki-url. Use when a skill run produced a reusable lesson, or before running a skill to consult past lessons; not for work-time logs (see worklog).
|
||||
---
|
||||
|
||||
# learn — lessons learned
|
||||
@@ -11,10 +11,11 @@ Close the loop on skill runs: record what a run taught you, consult it before th
|
||||
|
||||
- Directory page: `LEARN_CONTENTS`. Content page: `LEARN_{HASH}`, one page per repository.
|
||||
- The two pages live in different wikis. `LEARN_{HASH}` goes to `jsc-gitea/tools/gitea.sh wiki-repo LEARN`; `LEARN_CONTENTS` goes to `gitea.sh wiki-repo CONTENTS` (`JSC_WIKI_REPO_CONTENTS`, then `JSC_WIKI_REPO`, then exit 3), which never falls back to the LEARN repo. Exit 3 on either 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.
|
||||
- Every link this skill writes takes the shape `[{text}]({absolute URL})`. The directory row links the lesson page as `[LEARN_{HASH}](<url>)`, with `<url>` from `gitea.sh wiki-url <LEARN repo> LEARN_{HASH}` — never assembled by hand, and never the same-wiki `[[...]]` form, which resolves inside one wiki only and dead-links from the directory without reporting an error. `wiki-url` exit 4 means the lesson page is not written yet, so write it first; exit 5 means the page carries no `html_url`, so stop and report it and never assemble the URL by hand; exit 7 or 8 means the token or the API failed, so stop and report that status.
|
||||
- Every link this skill writes takes the shape `[{text}]({absolute URL})`. The directory block's 教訓紀錄 bullet links the lesson page as `[LEARN_{HASH}](<url>)`, with `<url>` from `gitea.sh wiki-url <LEARN repo> LEARN_{HASH}` — never assembled by hand, and never the same-wiki `[[...]]` form, which resolves inside one wiki only and dead-links from the directory without reporting an error. `wiki-url` exit 4 means the lesson page is not written yet, so write it first; exit 5 means the page carries no `html_url`, so stop and report it and never assemble the URL by hand; exit 7 or 8 means the token or the API failed, so stop and report that status.
|
||||
- Check every link before it reaches a page: `jsc-gitea/tools/link-check.sh {url}...`. Only exit 0 permits the write.
|
||||
- Compute `{HASH}` from `{owner}/{repo}` with `jsc-gitea/tools/hash-id`. It prints the full 40-character uppercase SHA-1 — no truncation and no prefix rewrite, so never shorten it. 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. Exit 2 means the input was empty, so fix the `{owner}/{repo}` parse and rerun.
|
||||
- All wiki reads and writes go through `jsc-gitea:wiki`, except the `LEARN_CONTENTS` row, which goes through `jsc-gitea/tools/wiki-contents.sh`.
|
||||
- All wiki reads and writes go through `jsc-gitea:wiki`, except the `LEARN_CONTENTS` block, which goes through `jsc-gitea/tools/wiki-contents.sh`.
|
||||
- The two pages carry different shapes. `LEARN_{HASH}` stays a markdown table, one row per lesson. `LEARN_CONTENTS` is a list page: `# 教訓目錄`, a `>` preamble, then one H2 block per repository whose heading is that repository's lesson page name.
|
||||
|
||||
## Mode: record
|
||||
|
||||
@@ -46,37 +47,37 @@ Run after a skill run that produced a reusable lesson.
|
||||
|
||||
| Exit | Do |
|
||||
| --- | --- |
|
||||
| 0 | Every link answered. Write the row |
|
||||
| 0 | Every link answered. Write the row and the directory block |
|
||||
| 1 | At least one link is DEAD. Write nothing and report the DEAD lines to the caller |
|
||||
| 2 | No URL reached the script. Pass the URLs and rerun |
|
||||
| 3 | The list holds a Gitea URL but `GITEA_HOST` is unset. Set it and rerun; never skip the check |
|
||||
| 7 | The Gitea token was rejected (HTTP 401/403). Stop and report the token problem. A rejected token makes live pages look missing, and one batch judged on that answer wipes out links that still work |
|
||||
|
||||
- Update `LEARN_CONTENTS` in the same pass, and let `jsc-gitea/tools/wiki-contents.sh` do the row work — never hand-edit the directory page. Build one file holding the single row from `templates/learn-contents.md` (the repository name, the absolute link from `gitea.sh wiki-url <LEARN repo> LEARN_{HASH}`, and the update time), then run:
|
||||
- Update `LEARN_CONTENTS` in the same pass, and let `jsc-gitea/tools/wiki-contents.sh` do the block work — never hand-edit the directory page. Build one file holding the single H2 block from `templates/learn-contents.md` — the `## LEARN_{HASH}` heading, a blank line, then one `- {欄位名}:{值}` bullet per field in the template's order: the repository name, the absolute link from `gitea.sh wiki-url <LEARN repo> LEARN_{HASH}`, and the update time. Then run:
|
||||
|
||||
`jsc-gitea/tools/wiki-contents.sh upsert LEARN 1 "{owner}/{repo}" {row file} templates/learn-contents.md`
|
||||
`jsc-gitea/tools/wiki-contents.sh upsert LEARN 2 "LEARN_{HASH}" {block file} templates/learn-contents.md`
|
||||
|
||||
Column 1 is the repository name, so the key stays the same string across every run and one repository keeps exactly one row. The script reads the whole page, replaces the matching row and appends when none matches, so every row that belongs to another repository stays as it was.
|
||||
The key is the H2 heading itself, the content page name `LEARN_{HASH}`, so it stays the same string across every run and one repository keeps exactly one block. The 教訓紀錄 bullet carries that same page as a link, and that link is what must not be the key: it embeds the host and the encoded page name, so one change of `GITEA_HOST`, one move of `JSC_WIKI_REPO_LEARN`, or one difference in how Gitea encodes the page name makes the match fail and appends a second block for the same repository. The page name depends only on `{owner}/{repo}`. The `2` is `<key-col>`, which the script uses only while the directory page is still an old markdown table — it names the column whose cell text (the link text alone) becomes the H2 heading, and a page already in list shape ignores it. The script reads the whole page, replaces the matching block and appends when none matches, so every block that belongs to another repository stays as it was.
|
||||
|
||||
| Exit | Do |
|
||||
| --- | --- |
|
||||
| 0 | The row is in place. It prints `updated` or `added` plus the page it wrote |
|
||||
| 1 | The write failed, or the directory page holds no markdown table. Report `LEARN_CONTENTS` as not written, together with the row content |
|
||||
| 0 | The block is in place. It prints `updated` or `added` plus the page it wrote |
|
||||
| 1 | The page content could not be assembled, or the write failed. Report `LEARN_CONTENTS` as not written, together with the block content. A page with no matching block is not this code: the block is appended instead |
|
||||
| 2 | An argument was rejected. Fix the argument and rerun this bullet; nothing was written |
|
||||
| 3 | No CONTENTS wiki repo is configured. Report `JSC_WIKI_REPO_CONTENTS` and `JSC_WIKI_REPO` as the two variables to set. The lesson itself is on `LEARN_{HASH}` and stays there |
|
||||
| 4 | The directory page is absent and the script received no template. The call above always passes one, so this code means `templates/learn-contents.md` is not at that path — a partial plugin install, not a missing argument. Stop and report the path; rerunning the same command changes nothing. Reinstall the plugin, confirm the file is there, then rerun. A mistyped template path exits 2, not 4 |
|
||||
| 7 | The token is invalid or lacks permission, so the other repositories' rows are unknown. Stop and report the token problem; the script wrote nothing, which is what keeps those rows alive |
|
||||
| 7 | The token is invalid or lacks permission, so the other repositories' blocks are unknown. Stop and report the token problem; the script wrote nothing, which is what keeps those blocks alive |
|
||||
| 8 | Some other API failure. Stop and report that status and retry only after the API is back |
|
||||
|
||||
- A failed 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.
|
||||
- A failed 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 or block 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 block on `LEARN_CONTENTS`, and every row and block that was there before is 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` from the CONTENTS repo and the repo's `LEARN_{HASH}` from the LEARN repo via `jsc-gitea:wiki` — two `wiki-repo` calls, two different wikis — 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. The rows on `LEARN_CONTENTS` point at lesson pages by absolute URL, and rows for other repositories point outside the LEARN repo resolved here, so follow each link as given rather than treating the page name as local.
|
||||
2. Read `LEARN_CONTENTS` from the CONTENTS repo and the repo's `LEARN_{HASH}` from the LEARN repo via `jsc-gitea:wiki` — two `wiki-repo` calls, two different wikis — 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. The blocks on `LEARN_CONTENTS` point at lesson pages by absolute URL, and blocks for other repositories point outside the LEARN repo resolved here, so follow each link as given rather than treating the H2 heading as a page in this wiki.
|
||||
|
||||
| Exit | Do |
|
||||
| --- | --- |
|
||||
@@ -98,9 +99,9 @@ Resolve that path the way this file already resolves `jsc-gitea/tools/hash-id` a
|
||||
|
||||
| status | This skill's case |
|
||||
| --- | --- |
|
||||
| `ok` | record — both pages carry the new row and every row that was there before is still there. consult — both pages were read, or a page was reported absent under exit 4, and the matched 下次做法 lines reached the caller |
|
||||
| `ok` | record — `LEARN_{HASH}` carries the new row and `LEARN_CONTENTS` this repository's block, and everything that was there before is still there. consult — both pages were read, or a page was reported absent under exit 4, and the matched 下次做法 lines reached the caller |
|
||||
| `blocked` | The run never reached a page: `hash-id` exit 1 (no SHA-1 helper), `wiki-repo LEARN` or `wiki-repo CONTENTS` exit 3 (no wiki repo configured for that page type), or `link-check.sh` exit 3 (`GITEA_HOST` unset) |
|
||||
| `degraded` | record — the lesson row is on `LEARN_{HASH}` but `wiki-contents.sh upsert` did not land the directory row (exit 1, 3, 7 or 8), so the lesson is on the wiki and nothing points at it. consult — one of the two pages was read and the other stopped the run, so the caller got part of the lesson set and knows it |
|
||||
| `degraded` | record — the lesson row is on `LEARN_{HASH}` but `wiki-contents.sh upsert` did not land the directory block (exit 1, 3, 7 or 8), so the lesson is on the wiki and nothing points at it. consult — one of the two pages was read and the other stopped the run, so the caller got part of the lesson set and knows it |
|
||||
| `failed` | An API call answered with something unexpected after the work started: `link-check.sh` exit 1 on a DEAD link, a `wiki-get` that came back 7 or 8, or a page write that failed its retry as well. Nothing reached `LEARN_{HASH}` |
|
||||
| `aborted` | The user stopped the run, or record mode was called with nothing reusable to record, so the six facts never formed an entry and no write was attempted |
|
||||
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
# 教訓目錄
|
||||
|
||||
> 由 `jsc-log:learn` 維護。這是教訓目錄頁 `LEARN_CONTENTS`。每個存取庫一列;`LEARN_{HASH}` 的 `{HASH}` 依共用 wiki hash 規則產生:取 `{owner}/{repo}` 的完整 SHA-1 四十碼,a-f 轉大寫,不截短、不加前綴。
|
||||
> 由 `jsc-log:learn` 維護。這是教訓目錄頁 `LEARN_CONTENTS`。每個存取庫一個區塊;`LEARN_{HASH}` 的 `{HASH}` 依共用 wiki hash 規則產生:取 `{owner}/{repo}` 的完整 SHA-1 四十碼,a-f 轉大寫,不截短、不加前綴。
|
||||
> 本頁落在 `JSC_WIKI_REPO_CONTENTS` 解出的專用存取庫,教訓頁 `LEARN_{HASH}` 落在 `JSC_WIKI_REPO_LEARN` 的存取庫,兩者分屬不同 wiki。
|
||||
> 連結寫法:教訓紀錄那一欄寫成 `[{頁名}]({絕對網址})`,網址取自 `jsc-gitea/tools/gitea.sh wiki-url`,不用 `[[...]]`。兩頁分屬不同存取庫,`[[...]]` 連不過去,畫面上還看不出壞掉。
|
||||
> 連結寫法:教訓紀錄那一條寫成 `[{頁名}]({絕對網址})`,網址取自 `jsc-gitea/tools/gitea.sh wiki-url`,不用 `[[...]]`。兩頁分屬不同存取庫,`[[...]]` 連不過去,畫面上還看不出壞掉。
|
||||
> 連結驗證:每個要寫進本頁的連結先交給 `jsc-gitea/tools/link-check.sh`,退出碼 0 才寫入。出現 DEAD 就不寫,把連不到的那幾筆回報給呼叫端。
|
||||
> 寫入語意:一列代表一個存取庫。一律用 `jsc-gitea/tools/wiki-contents.sh upsert LEARN 1 {owner}/{repo} {列檔} {本範本}` 單列整頁寫回——它讀整頁、找得到該存取庫既有的那一列就換掉那一列,找不到才附加。
|
||||
> 鍵取第 1 欄的存取庫名稱,不取第 2 欄的連結。存取庫名稱每一輪都一樣,連結會隨主機名與頁名編碼變動。
|
||||
> 禁止整頁覆蓋,也不得改動別人的列。
|
||||
> 寫入語意:一個區塊代表一個存取庫。一律用 `jsc-gitea/tools/wiki-contents.sh upsert LEARN 2 LEARN_{HASH} {區塊檔} {本範本}` 單一區塊整頁寫回——它讀整頁、找得到該存取庫既有的那個區塊就換掉,找不到才附加到頁尾。
|
||||
> 參數語意:`<key-col>` 的 `2` 只在舊頁還是表格時用得到,代表轉檔時取第 2 欄格子的文字當 H2 標題,格子是 `[文字](網址)` 就只取文字;頁面已經是條列格式就完全忽略它。`<key>` 是 H2 標題文字,也就是內容頁頁名 `LEARN_{HASH}`。第四個參數是區塊檔,內容是 `## {key}` 那一行加空行加各條欄位,不是一列表格。
|
||||
> 鍵是 H2 標題的頁名,不是連結。頁名只由 `{owner}/{repo}` 決定,換主機名、改存取庫、頁名編碼有差都動不到它;連結帶著主機名與存取庫名,一變就比不到鍵,同一個存取庫會多出第二個區塊。
|
||||
> 禁止整頁覆蓋,也不得改動別人的區塊。
|
||||
|
||||
| 存取庫名稱 | 教訓紀錄 | 最後更新時間 |
|
||||
| --- | --- | --- |
|
||||
| {owner}/{repo} | [LEARN_{HASH}]({教訓頁絕對網址}) | {yyyy-MM-dd HH:mm} |
|
||||
## LEARN_{HASH}
|
||||
|
||||
- 存取庫名稱:{owner}/{repo}
|
||||
- 教訓紀錄:[LEARN_{HASH}]({教訓頁絕對網址})
|
||||
- 最後更新時間:{yyyy-MM-dd HH:mm}
|
||||
|
||||
Reference in New Issue
Block a user