diff --git a/references/branch.md b/references/branch.md index d1e4b11..db6787a 100644 --- a/references/branch.md +++ b/references/branch.md @@ -37,6 +37,48 @@ - 新分支名稱要可讀且不覆蓋既有分支;本地或遠端已存在同名分支時,換一個時間戳或短 hash。 - 切換或建立分支屬不可忽略的狀態變更,要在輸出中講清楚原因與結果分支名稱。 +## 實作一律在 worktree 內進行 + +`implement` 動任何程式碼之前,先從**分析頁記錄的來源分支**建立 git worktree。所有修改都在 worktree 內,主工作目錄的分支與工作區完全不動。 + +### 路徑 + +``` +{工作目錄}/.worktree/{分析頁 HASH}/{repo} +``` + +- `{分析頁 HASH}`:`ANALYZE_{HASH}` 的 HASH 部分,不含 `ANALYZE_` 前綴。 +- `{repo}`:存取庫名稱,不含 owner(`HP/WebService.Buy` → `WebService.Buy`)。不同 owner 的同名存取庫同時出現時,才改用 `{owner}-{repo}` 避免蓋掉,並在輸出中說明。 +- 一份分析涉及多個存取庫時,每個存取庫各一個 worktree,並列在同一個 HASH 目錄下。 + +### 建立前先問分支怎麼處理 + +依 `jsc-ask:ask` 的決策樹詢問,每個選項標明影響範圍。固定兩個選項: + +| 選項 | 指令 | 影響 | +| --- | --- | --- | +| 以來源分支為基準開新工作分支 | `git worktree add -b {工作分支} {路徑} {來源分支}` | commit 落在新分支,來源分支不動 | +| 直接簽出來源分支 | `git worktree add {路徑} {來源分支}` | commit 直接進來源分支;同一分支不能同時簽出於兩處 | + +**不得自行預設**,也不得跳過詢問。 + +### 建立時的鐵則 + +- **分支名與路徑一律加引號**:來源分支可能含中文、空白或多層斜線(例如 `feat/一址通/查地址/完整版/P2`),不加引號會被切斷。 +- 找不到該存取庫的本地 clone → **停下來問使用者路徑**,不自行 clone、不臆測位置。 +- 目標路徑已存在 → 不覆蓋。先確認它是不是同一份工作的 worktree(`git worktree list`),是就沿用,不是就回報並停止。 +- 把 `.worktree/` 加進該存取庫的 `.git/info/exclude`(不動使用者的 `.gitignore`,那是專案共用檔)。 +- 建立後在輸出中明確列出:worktree 路徑、簽出的分支、來源分支。 + +### 移除時機 + +**PR 建立成功後自動移除**:`git worktree remove {路徑}`。 + +- 只有 `jsc-git:pr` 回報 PR 建立成功才移除;PR 失敗就保留,讓使用者能接手處理。 +- worktree 內還有未提交變更時**不移除**,回報並停止——那些變更沒有進 PR,移除等於丟掉。 +- 移除後順手 `git worktree prune` 清掉殘留記錄。 +- 同一份分析的多個 worktree 全部移除後,若 `.worktree/{HASH}/` 已空就一併刪掉那層目錄。 + ## 不破壞既有工作 - 工作區有未提交變更時,先提醒使用者 commit 或備份,**絕不**強制丟棄。 diff --git a/skills/implement/SKILL.md b/skills/implement/SKILL.md index 1a12b72..5286232 100644 --- a/skills/implement/SKILL.md +++ b/skills/implement/SKILL.md @@ -1,6 +1,6 @@ --- name: implement -description: SDLC implementation stage. Gate on capability tags enforced in code by sdlc-gate (implement requires coding), confirm the target branch before writing any file, then claim a ready work package from ANALYZE_CONTENTS with a work ticket and complete its TDD todos one by one, updating the wiki after every item. A delivery package confirms its content type (API document or user-defined) before its first todo. Ends with jsc-review code-review, then always asks which delivery-document format to produce (DELIVER_{HASH} wiki page or Gitea issue comment) before an optional MAINTAIN_CONTENTS entry. Use when analysis is done and code must be written; not for planning or analysis. +description: SDLC implementation stage. Gate on capability tags enforced in code by sdlc-gate (implement requires coding), confirm the target branch before writing any file, then claim a ready work package from ANALYZE_CONTENTS with a work ticket, create a worktree from the analysis page's source branch under .worktree/{分析頁 HASH}/{repo}, and complete its TDD todos one by one inside it, updating the wiki after every item. A delivery package confirms its content type (API document or user-defined) before its first todo. Ends with jsc-review code-review, opens the PR and only then removes the worktree, asks which delivery-document format to produce (DELIVER_{HASH} wiki page or Gitea issue comment), and optionally registers the project in MAINTAIN_CONTENTS. Use when analysis is done and code must be written; not for planning or analysis. --- # implement @@ -29,18 +29,31 @@ All wiki reads and writes go through `jsc-gitea:wiki`. 2. Chose API 文件 → follow `references/deliver-formats.md`: all parameters listed (not just the main ones), each with name, type, required flag, example, data source and new-versus-existing status; sample values take real sources first and are labelled `真實:{來源}` or `推論:無來源`; **an existing endpoint must mark new versus old parameters both ways** — the status column (🆕 新增 / ⚠️ 變更 / ❌ 移除 / blank for untouched) and a `diff` code block for colour. HTML `style` attributes get filtered by the wiki, so never rely on them. 3. Chose 由使用者輸入 → produce exactly what the user described; do not force the API document layout onto it. 4. Record the confirmed type in the analysis page's 交付型別 column and save it before starting the todos. -7. List every open item of the work package and implement them **one at a time**: +7. **Create the worktree — before touching any code**. Full rules in `references/branch.md`: + 1. Read the **source branch** and the repositories involved from the analysis page. Every code change happens inside the worktree; the main working directory's branch and working tree stay untouched. + 2. Path: `{工作目錄}/.worktree/{分析頁 HASH}/{repo}` — the HASH without the `ANALYZE_` prefix, the repo name without its owner. One worktree per repository, all under the same HASH directory. + 3. **Ask per `jsc-ask:ask` rules how to handle the branch**, with the two fixed options: create a new working branch off the source branch (`git worktree add -b {工作分支} {路徑} {來源分支}`), or check the source branch out directly (`git worktree add {路徑} {來源分支}`). State the impact scope on each. **Never assume, never skip the question.** + 4. **Quote every branch name and path**: source branches carry Chinese characters, spaces and multiple slashes (for example `feat/一址通/查地址/完整版/P2`), and an unquoted argument gets split. + 5. No local clone of that repository → stop and ask the user for its path; never clone on your own initiative and never guess the location. + 6. Add `.worktree/` to that repository's `.git/info/exclude` — never edit the user's shared `.gitignore`. + 7. Report the worktree path, the checked-out branch and the source branch. Completion condition: every involved repository has a worktree and you have reported all of them. +8. List every open item of the work package and implement them **one at a time**, **inside the worktree**: - Follow the TDD loop: red before green, one slice at a time; rules and anti-patterns in `references/tdd.md` (refactoring belongs to the review stage). - After each item, flip its `[ ]` to `[x]` on the analysis page and save to the wiki before starting the next item. -8. When all items are done, call `jsc-review:code-review` and wait for the review; on failure, fix and re-review until it passes. -9. **Delivery document** — a finished work package is a delivery, so **always ask before producing it; never pick a format silently and never skip this step**: +9. When all items are done, call `jsc-review:code-review` and wait for the review; on failure, fix and re-review until it passes. +10. **Open the PR, then remove the worktree** — in that order, never the reverse: + 1. Call `jsc-git:pr` with the target branch confirmed in step 2. Commits come from inside the worktree. + 2. **Only after `jsc-git:pr` reports the PR was created successfully**, run `git worktree remove {路徑}` for each worktree, then `git worktree prune`. PR creation failed → keep the worktree so the user can take over. + 3. Uncommitted changes still inside a worktree → **do not remove it**; report and stop. Those changes never reached the PR, and removing would throw them away. + 4. Once every worktree of this analysis is gone and `.worktree/{HASH}/` is empty, delete that directory too. +11. **Delivery document** — a finished work package is a delivery, so **always ask before producing it; never pick a format silently and never skip this step**: 1. Ask per `jsc-ask:ask` rules which format to produce. The options are fixed: **a `DELIVER_{HASH}` wiki page** or **a Gitea issue comment**. State the impact scope on each (the wiki page lives beside the plan and analysis pages; the issue comment reaches whoever follows that issue). 2. Both formats use the same structure — `templates/deliver-page.md`, in Traditional Chinese. Only the destination differs. 3. Wiki page: write `DELIVER_{HASH}` through `jsc-gitea:wiki`, where `{HASH}` comes from `jsc-gitea/tools/hash-id` over `{owner}/{repo}` plus the work package number (for example `plugins/sdlc#WP-01`), so each work package gets its own page instead of overwriting the previous one. A new page is added to `DELIVER_CONTENTS` per `templates/deliver-contents.md`. 4. Issue comment: confirm the issue number with the user (propose the one referenced by the work package or the PR; never guess), then post via `gitea/tools/gitea.sh api POST /repos/{owner}/{repo}/issues/{n}/comments` with the body passed in as a UTF-8 file — real newlines, never a literal `\n`. 5. Sample values follow the analysis page's 資料來源 column: `真實:{來源}` for real sources, `推論:無來源` for reasoned ones. Personal data never goes in — keep the field and format, drop the value. 6. Completion condition: the chosen format has actually been produced, and you have reported where it landed (wiki page name, or the comment URL). -10. Ask per `jsc-ask:ask` rules whether to register this project for maintenance: append to `MAINTAIN_CONTENTS` with `templates/maintain-contents.md`. Required: repository `{owner}/{repo}`, maintenance method, start date. Optional: end date (NULL = maintain forever), last-maintained time. +12. Ask per `jsc-ask:ask` rules whether to register this project for maintenance: append to `MAINTAIN_CONTENTS` with `templates/maintain-contents.md`. Required: repository `{owner}/{repo}`, maintenance method, start date. Optional: end date (NULL = maintain forever), last-maintained time. ## Rules