feat(cli): 部署收尾產生更新與移除指引,並掛上部署後重啟閘門 #27
1 Participants
Notifications
Due Date
No due date set.
Depends on
#33 feat(hooks): 新增部署後強制重啟閘門,接線與冒煙同步到八支 hook
plugins/hooks
Reference: plugins/cli#27
Reference in New Issue
Block a user
feat(cli): 部署收尾產生更新與移除指引,並掛上部署後重啟閘門
摘要
jsc-cli的落地,共兩條。R9deploy安裝或更新完要產生更新指引與移除指引,寫成本機檔案$JSC_HOME/update-guide.md與$JSC_HOME/remove-guide.md;R15 部署後強制重啟,狀態檔$JSC_HOME/restart-required由部署收尾寫入,判讀與逃生門JSC_RESTART_GATE=off在jsc-hooks。另補登設定規格表漏列的既有設定。決策紀錄在 wikiknowledges/QUESTION的QUESTION_FB8DF0B5。變更內容
tools/write-guides.shdeploy.sh -n的輸出tools/deploy.shmark_restart(),轉呼叫jsc-hooks的restart-gate.sh require,並多印一行restart<TAB>{狀態檔路徑}skills/deploy/SKILL.mdwrite-guides.sh)與第 9 步(固定字句的重啟指示,並講出兩份指引的路徑)tools/config-spec.tsvREADME.mdwrite-guides.sh工具列、JSC_HOME與JSC_RESTART_GATE兩個環境變數列,以及「部署留在機器上的檔案」一節plugin.json、.claude-plugin/plugin.json、.codex-plugin/plugin.json設計重點
mark_restart()轉呼叫jsc-hooks的restart-gate.sh require,路徑、格式與判讀全留在那一支。這裡一開始自己寫四欄 TSV、hooks 那端讀key=value,狀態檔存在卻解不出欄位,正是兩邊各拼一份格式的下場;改成轉呼叫才對得上。找腳本的順序比照jsc-sdlc的wp-gate.sh:環境變數JSC_HOOKS_DIR優先,再找並排的工作樹,最後找 plugin 快取。restart-gate.sh就不掛閘門,也不自己補寫一份。 印note行據實回報「這次沒有掛上重啟閘門」。閘門本來就由jsc-hooks判讀,它不在就沒有判定點,寫下去只是留一個沒人讀的檔案,還會讓下一輪誤以為閘門掛上了。deploy.sh的職責是「對單一 CLI 部署」,一輪部署會逐個 CLI 呼叫它;指引寫的是整台機器的樣貌,只該產生一次,跟著 CLI 跑就會被覆寫成最後一支的內容。併進deploy.sh還會與deploy.sh -n形成雙向遞迴。detect-clis.sh,每支 CLI 的指令字面直接取自deploy.sh -n,所以指引寫的就是真正會跑的指令。各 CLI 的差異只有deploy.sh一個真實來源,再抄一份就會有兩套指令,改了一邊忘了另一邊,指引就開始騙人。kiro 走不走本地複製退路也讀deploy.sh的note行判斷。uninstall兩件事都不做。 不產生指引(指引描述的是裝好的技能組)、不寫重啟狀態檔(技能移除後沒有新內容要載入)。dry-run 也一律不寫、不建目錄。none。$JSC_HOME/restart-required不存在是正常狀態,標成必要項會讓體檢把「沒有待重啟的部署」誤判成缺失。測試結果
tools/ste100-lint.sh對本存取庫全綠;三份 manifest 版本一致為 0.1.9。write-guides.sh -n update {domain}...:只印兩行plan,不寫入任何檔案。write-guides.sh update {domain}...:兩份指引都印出wrote行並實際產出,內容含五支 CLI 的實際指令;產出的兩份指引本身再送一次ste100-lint.sh,全綠。deploy.sh:install與update會掛上閘門並印出restart行,uninstall不寫,dry-run 不建目錄。deploy.sh update經restart-gate.sh require寫出的狀態檔是key=value四欄(at、mode、domains、cli),jsc-hooks的restart-gate.sh讀得懂並正確以 exit 2 擋下非豁免技能。修正前這裡自己寫四欄 TSV、hooks 讀key=value,兩邊對不上,改成轉呼叫後才通過。config-spec.tsv:所有列的欄位數一致為 8;scan-config.sh orphans零回報。前置 Push Request
What:新增 `tools/write-guides.sh`(`write-guides.sh [-n] {install|update} {domain}...`),產生 `$JSC_HOME/update-guide.md` 與 `$JSC_HOME/remove-guide.md` 兩份指引,兩份都整份覆寫。輸出 TSV 四種行別:`cli`(偵測到的 CLI)、`plan`(dry-run 時會寫入的檔案)、`wrote`(實際寫入的檔案)、`note`(非致命說明);結束碼 0 寫成、2 參數錯誤、4 目錄或檔案寫不進去。 Why:更新與移除這兩件事原本只存在於技能內文裡。CLI 壞掉、沒有工作階段、或是換人接手的時候,機器上找不到任何一份寫著「這台機器要怎麼更新、怎麼移除」的東西,只能回頭讀技能。指引落成本機檔案,不開工作階段也照著走得完。 How:內容一律依實際偵測結果生成,不寫死。CLI 清單來自 `detect-clis.sh`;每支 CLI 的指令字面直接取自 `deploy.sh -n` 的輸出,所以指引寫的就是 `deploy.sh` 真正會跑的指令——各 CLI 的差異只有 `deploy.sh` 一個真實來源,這裡再抄一份就會有兩套指令,改了一邊忘了另一邊,指引就開始騙人。kiro 走不走本地複製退路,也是讀 `deploy.sh` 的 `note` 行判斷,不自己再探測一次。獨立成一支腳本、不併進 `deploy.sh`:`deploy.sh` 的職責是「對單一 CLI 部署」,一輪部署會逐個 CLI 呼叫它,而指引寫的是整台機器的樣貌,只該產生一次;併進去還會與 `deploy.sh -n` 形成雙向遞迴。寫檔走暫存檔再 `mv`,寫一半不會留下半份指引。移除指引另外列出 plugin 指令管不到的殘留物(`$JSC_HOME`、本地 clone、kiro 技能目錄、rc 檔的 `# jsc-config` 段落)與各自清掉的影響。 Who:`/jsc-cli:deploy` 的 install 與 update 收尾,以及日後要手動更新或整組移除的操作者。What:`tools/deploy.sh` 新增 `restart_gate_sh()` 與 `mark_restart()` 兩個函式,並在全部指令成功、印出 `result` 之前呼叫 `mark_restart`。`install` 與 `update` 會轉呼叫 `jsc-hooks` 的 `hooks/restart-gate.sh require {模式} {domain}...` 掛上重啟閘門,成功就多印一行 `restart<TAB>{狀態檔路徑}`;`uninstall` 與 dry-run 不寫。輸出行別表與檔頭的環境變數說明同步補上。 Why:部署換掉的是磁碟上的技能檔,目前工作階段載入的還是舊版。這段落差期間跑技能,改動看起來沒生效,人會以為部署失敗又重跑一次。要有一個「這台機器有一輪部署還沒重啟」的證據留在檔案上,判定那一端才擋得下來。 How:狀態檔的路徑、格式與判讀全留在 `jsc-hooks` 的 `restart-gate.sh`,這裡只轉呼叫它的 `require` 子命令,比照 `jsc-sdlc` 轉呼叫 `sdlc-gate.sh wp-lock` 的慣例。兩邊各拼一份格式就會對不上:這裡一開始自己寫四欄 TSV,而 hooks 那端讀的是 `key=value`,狀態檔存在卻解不出欄位,改成轉呼叫才修好,格式只能有一個真實來源。找腳本的順序比照 `jsc-sdlc` 的 `wp-gate.sh`:環境變數 `JSC_HOOKS_DIR` 優先,再找並排的工作樹,最後找 plugin 快取;找不到就印 `note` 行據實說「這次沒有掛上重啟閘門」,不自己補寫一份——閘門本來就由 `jsc-hooks` 判讀,它不在就沒有判定點,寫下去只是留一個沒人讀的檔案,還會讓下一輪誤以為閘門掛上了。`require` 一律接 `</dev/null`:它不讀標準輸入,但這裡的標準輸入是宿主餵進來的管線,不關掉會卡住。 Who:`/jsc-cli:deploy` 的 install 與 update 收尾,與 `jsc-hooks` 的部署後重啟閘門對接。What:`skills/deploy/SKILL.md` 新增兩個步驟並改寫 `description`。新的第 7 步:install 或 update 在所有 CLI 跑完之後,整台機器跑一次 `tools/write-guides.sh {mode} {domain}...`,完成條件是兩份指引都印出 `wrote` 行;原本的回報順延為第 8 步;新的第 9 步:收尾一律印出重啟指示「請關閉目前的工作階段並重新啟動,新的技能內容才會載入」,並把兩份指引的路徑講出來。 Why:兩份指引與重啟提示都是部署收尾的一部分,腳本做得到、技能流程沒寫,就等於沒人會跑。重啟這件事尤其要在收尾講清楚:`deploy.sh` 已經把這一輪記進 `$JSC_HOME/restart-required`,使用者不知道要重啟就會繼續用舊版技能,然後以為部署沒生效。 How:指引那一步明寫「整台機器跑一次」,排在每個 CLI 都跑完之後——第 5 步是一個 CLI 一個子代理,指引寫的卻是整台機器的樣貌,跟著 CLI 跑就會被覆寫成最後一支的內容。`uninstall` 跳過這一步:指引描述的是裝好的技能組。重啟指示用固定字句,不讓每次回報各講一套;`JSC_RESTART_GATE=off` 作為逃生門一併寫出,判讀在 `jsc-hooks`。 Who:`/jsc-cli:deploy` 技能的執行流程與收尾回報。