From c9e8f0fbb05bbbc66e4195133c806e3d75d7947a Mon Sep 17 00:00:00 2001 From: maogeigei Date: Mon, 12 Oct 2026 10:26:05 +0800 Subject: [PATCH] =?UTF-8?q?session-mechanism=EF=BC=9Ainit=5Fworkspace=20?= =?UTF-8?q?=E4=B8=A4=E5=A4=84=E6=9C=AC=E6=9C=BA=E9=80=82=E9=85=8D=E5=9B=9E?= =?UTF-8?q?=E8=A1=A5=EF=BC=88=E5=89=AF=E6=9C=AC=E5=9C=BA=E6=99=AF=E8=B5=B7?= =?UTF-8?q?=E4=B8=8D=E6=9D=A5=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景:这两处 2026-10-09 已在某台机器的工作副本上验证通过,但没随仓发布; 2026-10-12 那台机器按「以仓库为准」覆盖本地后,修复丢失。现按仓规补回仓库版。 一、副本场景 SK 回落技能源 原:SK = Path(__file__).resolve().parent ⇒ 副本(<工作区>/.workbuddy/collab/)下 没有 hooks/ ⇒ ⑤ 自检加载 hooks/_env.py 直接 FileNotFoundError,整段自检作废。 现:加 _resolve_skill_dir(),先判 /hooks/_env.py 在不在;不在就依次到 CODEBUDDY_CONFIG_DIR 与 ~/.workbuddy 下的 skills/session-mechanism/scripts 找, 取第一个命中;两处都没有 ⇒ 原样返回,让报错照常暴露(不静默跳过)。 只拼相对片段,不写盘符字面量(与「脚本是脚本、配置是配置」相容)。 二、collabd --where 归属判据认反斜杠 原:_ws_ok = ("COLLABD_CONFIG" in 输出) or (ws_s in 输出) ⇒ 恒为 False: ① 输出里没有 COLLABD_CONFIG 字样(它写「配置来源」); ② 输出全反斜杠,而 ws_s 是正斜杠形态。 结果这条自检永远打印 ⛔(即便工作区其实认得)。 现:改「两端都认」—— 正斜杠原样 / 反斜杠形态 / 反斜杠形态经 normcase 归一后 出现在同样归一的输出里,任一命中即通过。 验证(本机实跑,改动前后各一次) · 副本场景 e2e:改前 ⑤ 打印「⚠️ 自检跑不了:FileNotFoundError」; 改后 ⑤ 全量跑通,`collabd --where` 认这个工作区 = ✅(rc=0)。 · 对照脚本:改前 SK=副本目录、hooks/_env.py 不存在、加载 FileNotFoundError; 改后 SK=技能源、加载 OK。判据 旧=False / 新=True。 · scripts/selftest.py:改前 110/0、改后 110/0(无回归)。 · install.py --manifest:77 份文件,语法失败 0。 --- session-mechanism/scripts/init_workspace.py | 46 ++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/session-mechanism/scripts/init_workspace.py b/session-mechanism/scripts/init_workspace.py index afc862f..9ef733b 100644 --- a/session-mechanism/scripts/init_workspace.py +++ b/session-mechanism/scripts/init_workspace.py @@ -32,6 +32,40 @@ SK = Path(__file__).resolve().parent DEFAULT_TITLE = "检查会话协作是否运行正常 + 协作机制问题排查与修复" +def _resolve_skill_dir(sk: Path) -> Path: + """🔴 副本场景 ⇒ **回落找技能源**(2026-10-12 补)。 + + 为什么需要:本脚本会被 `deploy_code.py` 分发成**各工作区的副本** + (`<工作区>/.workbuddy/collab/init_workspace.py`),而副本目录里**只有脚本、没有 `hooks/`** + ⇒ ⑤ 自检要加载 `hooks/_env.py` 时直接 `FileNotFoundError`(整段自检作废)。 + + 判据:先看 `/hooks/_env.py` 在不在 —— 不在就依次到下面两处找, + 取**第一个命中**的目录当技能源: + ① `CODEBUDDY_CONFIG_DIR` 下的 `skills/session-mechanism/scripts` + (机制里由 `supervise-launch.py` 在进程内设,故副本被常驻拉起时必然命中) + ② `~/.workbuddy` 下的 `skills/session-mechanism/scripts` + 两处都不命中 ⇒ **原样返回**,让报错照常暴露出来(⛔ 不静默跳过)。 + + ⚠️ 只拼**相对片段**,⛔ 不写任何盘符字面量(2026-10-11 起「脚本是脚本、配置是配置」, + 本机专属路径归各技能包自己的 `env/`)。 + """ + if (sk / "hooks" / "_env.py").is_file(): + return sk + _cands = [] + _cfg = os.environ.get("CODEBUDDY_CONFIG_DIR") + if _cfg: + _cands.append(Path(_cfg) / "skills" / "session-mechanism" / "scripts") + _cands.append(Path(os.path.expanduser("~/.workbuddy")) / "skills" / "session-mechanism" / "scripts") + for _c in _cands: + if (_c / "hooks" / "_env.py").is_file(): + return _c + return sk + + +# 🔴 副本场景回落到技能源(理由见 `_resolve_skill_dir` 的 docstring) +SK = _resolve_skill_dir(SK) + + @@ -349,7 +383,17 @@ def main() -> int: _r2 = subprocess.run([a.python, str(_cd), "--where"], env=env, cwd=str(ws), capture_output=True, timeout=120) _o2 = _r2.stdout.decode("utf-8", "replace") - _ws_ok = ("COLLABD_CONFIG" in _o2) or (ws_s in _o2) + # 🔴 2026-10-12 修:原判据的两个条件在本机**恒为 False** —— + # ① `collabd --where` 的输出里**没有** `COLLABD_CONFIG` 字样(它写的是「配置来源」); + # ② 输出里全是**反斜杠**,而 `ws_s` 是**正斜杠**形态。 + # ⇒ 自检永远打印 ⛔(即便这个工作区其实**认得**),是本条自检的假阴性。 + # 现改为**两端都认**,满足任一条即算通过:正斜杠原样出现;反斜杠形态出现; + # 该反斜杠形态经 `normcase` 归一后出现在**同样归一过**的输出里 + # (Windows 下 `normcase` 同时折大小写与斜杠 ⇒ 兜住大小写/斜杠两种差异)。 + _ws_bs = ws_s.replace("/", "\\") + _ws_ok = (("COLLABD_CONFIG" in _o2) or (ws_s in _o2) + or (_ws_bs in _o2) + or (os.path.normcase(_ws_bs) in os.path.normcase(_o2))) print(" `collabd --where` 认这个工作区 = %s(rc=%s)" % ("✅" if _ws_ok else "⛔", _r2.returncode)) # 🔴🔴 2026-10-06 收敛(P0-74):载体从 `start-supervise.ps1` 换成 **`supervise-launch.py`**。 # ⇒ 自检一并改:**不再验 ps1、不再验 UTF-8 BOM、不再验模板变量填完没** ——