@minonl/dia 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -4313,6 +4313,7 @@ function registryCandidates() {
4313
4313
  out.push(process.env.DIA_PLATFORMS_FILE);
4314
4314
  const install = installDir();
4315
4315
  out.push(join18(install, "registry", "platforms.json"));
4316
+ out.push(join18(install, "docs", "platforms", "registry.json"));
4316
4317
  out.push(join18(process.cwd(), "docs", "platforms", "registry.json"));
4317
4318
  return out;
4318
4319
  }
@@ -4402,6 +4403,7 @@ function candidates() {
4402
4403
  out.push(process.env.DIA_DEPS_FILE);
4403
4404
  const install = installDir();
4404
4405
  out.push(join19(install, "registry", "deps.jsonl"));
4406
+ out.push(join19(install, "docs", "deps.jsonl"));
4405
4407
  out.push(join19(process.cwd(), "docs", "deps.jsonl"));
4406
4408
  return out;
4407
4409
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minonl/dia",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "type": "module",
5
5
  "description": "dia (嗲) — lightweight agent framework: knowledge index, audit, session ingest",
6
6
  "bin": {
@@ -461,7 +461,7 @@ cmd_prune_merged() {
461
461
  local -a roots=()
462
462
  [ -n "$dr" ] && [ -d "$dr/repos" ] && roots+=("$dr/repos")
463
463
  [ -d "$rr" ] && roots+=("$rr")
464
- [ ${#roots[@]} -gt 0 ] || die "--all:未找到仓根(数据根 repos/ 与 ${rr})"
464
+ [ ${#roots[@]} -gt 0 ] || { echo "usage: dia wt adopt --all(未找到仓根:${rr})" >&2; exit 2; }
465
465
  local root sub
466
466
  for root in "${roots[@]}"; do
467
467
  for sub in "$root"/*; do
@@ -779,7 +779,7 @@ cmd_check() {
779
779
  rr="${DIA_WT_REPOS_ROOT:-$HOME/repos/leyan}"
780
780
  [ -n "$dr" ] && [ -d "$dr/repos" ] && roots+=("$dr/repos")
781
781
  [ -d "$rr" ] && roots+=("$rr")
782
- [ ${#roots[@]} -gt 0 ] || die "--all:未找到仓根(数据根 repos/ 与 ${rr})"
782
+ [ ${#roots[@]} -gt 0 ] || { echo "usage: dia wt adopt --all(未找到仓根:${rr})" >&2; exit 2; }
783
783
  local root sub
784
784
  for root in "${roots[@]}"; do
785
785
  for sub in "$root"/*; do
@@ -1243,8 +1243,10 @@ PYGT
1243
1243
  }
1244
1244
 
1245
1245
  cmd_adopt() {
1246
- local repo="" mode="dry" template="" def="" json=0
1246
+ local repo="" mode="dry" template="" def="" json=0 all=0
1247
+ local -a orig=("$@")
1247
1248
  while [ $# -gt 0 ]; do case "$1" in
1249
+ --all) all=1; shift ;;
1248
1250
  --apply) mode="apply"; shift ;;
1249
1251
  --check) mode="check"; shift ;;
1250
1252
  --revert) mode="revert"; shift ;;
@@ -1257,7 +1259,41 @@ cmd_adopt() {
1257
1259
  -*) die "未知参数:$1" ;;
1258
1260
  *) repo="$1"; shift ;;
1259
1261
  esac; done
1260
- [ -n "$repo" ] || die "用法: dia wt adopt <repo> [--apply|--check|--revert] [--template T] [--default-branch B] [--json]"
1262
+ if [ "$all" = 1 ]; then
1263
+ [ -z "$repo" ] || die "--all 不能与 <repo> 同时给(要么单个仓,要么全量)"
1264
+ local -a roots=() repos=()
1265
+ local dr rr
1266
+ dr="$(dia_wt_data_root 2>/dev/null || true)"
1267
+ rr="${DIA_WT_REPOS_ROOT:-$HOME/repos}"
1268
+ [ -n "$dr" ] && [ -d "$dr/repos" ] && roots+=("$dr/repos")
1269
+ [ -d "$rr" ] && roots+=("$rr")
1270
+ [ ${#roots[@]} -gt 0 ] || { echo "usage: dia wt adopt --all(未找到仓根:${rr})" >&2; exit 2; }
1271
+ local root sub gd cd_
1272
+ for root in "${roots[@]}"; do
1273
+ while IFS= read -r -d '' gd; do
1274
+ sub="$(dirname "$gd")"
1275
+ case "$(basename "$sub")" in *-worktree--*) continue ;; esac
1276
+ cd_="$(git -C "$sub" rev-parse --git-common-dir 2>/dev/null || true)"
1277
+ # 统一物理路径(macOS /tmp → /private/tmp),否则等式比较会假失败
1278
+ gd="$(cd "$sub" 2>/dev/null && cd "$gd" 2>/dev/null && pwd -P)"
1279
+ cd_="$(cd "$sub" 2>/dev/null && cd "$cd_" 2>/dev/null && pwd -P)"
1280
+ [ -n "$gd" ] && [ "$gd" = "$cd_" ] || continue # 只处理主 checkout
1281
+ repos+=("$sub")
1282
+ done < <(find "$root" -maxdepth 3 -name .git -type d -print0 2>/dev/null)
1283
+ done
1284
+ [ ${#repos[@]} -gt 0 ] || { echo "usage: dia wt adopt --all(未匹配到任何主 checkout)" >&2; exit 2; }
1285
+ local -a pass=()
1286
+ local a
1287
+ for a in "${orig[@]}"; do [ "$a" = "--all" ] && continue; pass+=("$a"); done
1288
+ local okc=0 badc=0 r
1289
+ for r in "${repos[@]}"; do
1290
+ if cmd_adopt "$r" "${pass[@]}"; then okc=$((okc+1)); else badc=$((badc+1)); echo "FAIL $r" >&2; fi
1291
+ done
1292
+ [ "$json" = 1 ] && python3 -c 'import json,sys;print(json.dumps({"repos":int(sys.argv[1]),"ok":int(sys.argv[2]),"fail":int(sys.argv[3])},separators=(",",":")))' "${#repos[@]}" "$okc" "$badc"
1293
+ [ "$badc" = 0 ] || return 1
1294
+ return 0
1295
+ fi
1296
+ [ -n "$repo" ] || die "用法: dia wt adopt <repo>|--all [--apply|--check|--revert] [--template T] [--default-branch B] [--json]"
1261
1297
  [ -d "$repo" ] || die "目录不存在:$repo"
1262
1298
  git -C "$repo" rev-parse --git-dir >/dev/null 2>&1 || die "不是 git 仓库:$repo"
1263
1299
 
@@ -1343,6 +1379,11 @@ data = {
1343
1379
  }
1344
1380
  json.dump(data, open(cfg, "w"), ensure_ascii=False, indent=1)
1345
1381
  PY
1382
+ # 提示:simple-git-hooks / husky 的 postinstall 会重写 core.hooksPath 下的钩子,
1383
+ # 每次 `pnpm/npm install` 后可能把守卫冲掉 → 用 `dia wt doctor --fix` 或重跑 adopt --apply 修复。
1384
+ if grep -qs '"simple-git-hooks"\|"husky"\|lefthook' "$repo/package.json" "$repo/.lefthook.yml" 2>/dev/null; then
1385
+ echo "[dia-wt] 注意:该仓使用 hook manager(simple-git-hooks/husky/lefthook),install 后若守卫被重写,跑 dia wt doctor --fix" >&2
1386
+ fi
1346
1387
  wt_write_hook "$hooksdir" pre-commit "$def" "$chain"
1347
1388
  wt_write_hook "$hooksdir" pre-push "$def" "$chain"
1348
1389
  wt_write_hook "$hooksdir" post-checkout "$def" "$chain"
@@ -1351,11 +1392,12 @@ PY
1351
1392
  }
1352
1393
 
1353
1394
  cmd_doctor() {
1354
- local json=0 all=0 repos=()
1395
+ local json=0 all=0 fix=0 repos=()
1355
1396
  while [ $# -gt 0 ]; do case "$1" in
1356
1397
  --json) json=1; shift ;;
1357
1398
  --all) all=1; shift ;;
1358
- --strict|--fix) shift ;;
1399
+ --fix) fix=1; shift ;;
1400
+ --strict) shift ;;
1359
1401
  -*) die "未知参数:$1" ;;
1360
1402
  *) repos+=("$1"); shift ;;
1361
1403
  esac; done
@@ -1378,6 +1420,19 @@ cmd_doctor() {
1378
1420
  def="$(python3 -c 'import json,sys;print(json.load(open(sys.argv[1])).get("defaultBranch") or "")' "$cfg" 2>/dev/null || true)"
1379
1421
  fi
1380
1422
  [ -n "$def" ] || def="$(wt_default_branch "$repo")"
1423
+ # --fix:无损修复(重写三个守卫钩子 + hooksPath 绝对路径)。只对已 adopt 的仓生效。
1424
+ if [ "$fix" = 1 ] && [ -f "$cfg" ]; then
1425
+ local fixChain=""
1426
+ fixChain="$(python3 -c 'import json,sys;print(json.load(open(sys.argv[1])).get("hooksChain") or "")' "$cfg" 2>/dev/null || true)"
1427
+ [ -n "$fixChain" ] || fixChain="$common/hooks"
1428
+ mkdir -p "$hooksdir"
1429
+ wt_write_hook "$hooksdir" pre-commit "$def" "$fixChain"
1430
+ wt_write_hook "$hooksdir" pre-push "$def" "$fixChain"
1431
+ wt_write_hook "$hooksdir" post-checkout "$def" "$fixChain"
1432
+ [ "$prev" = "$hooksdir" ] || git -C "$repo" config --local core.hooksPath "$hooksdir"
1433
+ prev="$hooksdir"
1434
+ [ "$json" = 0 ] && echo "FIX $repo 钩子已重装(chain=$fixChain)"
1435
+ fi
1381
1436
  local bad=0
1382
1437
  [ -f "$cfg" ] || { echo "FAIL D01 $repo 未 adopt"; bad=1; }
1383
1438
  case "$prev" in /*) ;; *) echo "FAIL D02 $repo hooksPath 非绝对($prev)"; bad=1 ;; esac
@@ -1462,10 +1517,11 @@ dia wt —— worktree 目录形式选型 + 创建(唯一实现)
1462
1517
  dia wt status [repo-path] # ★ 清理前必查:唯一工作副本 + 改动重叠(只读)
1463
1518
  dia wt check [<repo>...] [--all] [--deep] [--quiet]
1464
1519
  # ★ 依赖体检(R20):软链/逃逸/悬空;--all 扫全部仓
1465
- dia wt adopt <repo> [--apply|--check|--revert] [--template T] [--default-branch B] [--json]
1466
- # 配置路径模板 + 守卫钩子(默认 dry-run)
1520
+ dia wt adopt <repo>|--all [--apply|--check|--revert] [--template T] [--default-branch B] [--json]
1521
+ # 配置路径模板 + 守卫钩子(默认 dry-run;--all 扫仓根)
1467
1522
  # 守卫含推送前敏感扫描(DIA_WT_GUARD_SCAN=0 可临时关闭)
1468
- dia wt doctor [<repo>...] [--all] [--json] # 巡检:配置/钩子/探针/主 checkout/worktree 卫生
1523
+ dia wt doctor [<repo>...] [--all] [--json] [--fix]
1524
+ # 巡检:配置/钩子/探针/主 checkout/worktree 卫生;--fix 重装守卫钩子
1469
1525
  dia wt gate <repo> <feature> # 提交 MR 前:check + doctor + 干净 + ahead>0
1470
1526
  dia wt route <repo-path> # ★ 开工前必查:走 MR 还是直推(R1.7,配置驱动)
1471
1527
  dia wt scope <repo|worktree> [--feature <slug>] [--session <id>] # ★ 产出作用域声明(设计 §4.5)
@@ -140,6 +140,35 @@ git -C "$TD/repo7-worktree--y" commit -qm feat-y >/dev/null 2>&1
140
140
  bash "$WT" adopt "$R7" --revert >/dev/null 2>&1
141
141
  [ "$(git -C "$R7" config --get core.hooksPath)" = ".githooks" ] && ok "revert 还原原 hooksPath(相对)" || bad "revert 未还原 .githooks"
142
142
 
143
+ # ── adopt --all:批量主 checkout,跳过 worktree 目录 ─────────────────────────
144
+ AR="$TD/allroot"; mkdir -p "$AR/a" "$AR/b"
145
+ for r in a b; do
146
+ git -C "$AR/$r" init -q -b main
147
+ git -C "$AR/$r" config user.email t@example.com; git -C "$AR/$r" config user.name t
148
+ echo x > "$AR/$r/x.txt"; git -C "$AR/$r" add -A; git -C "$AR/$r" commit -qm init --no-verify
149
+ done
150
+ git -C "$AR/a" worktree add -q -b feat/w "$AR/a-worktree--w" main
151
+ out="$(DIA_WT_REPOS_ROOT="$AR" DIA_WT_DATA_ROOT="$TD/dr2" bash "$WT" adopt --all --apply --json 2>&1)"
152
+ printf '%s' "$out" | grep -q '"repos":2,"ok":2,"fail":0' && ok "adopt --all 覆盖 2 个主 checkout" || bad "adopt --all: $out"
153
+ for r in a b; do
154
+ [ -n "$(git -C "$AR/$r" config --get core.hooksPath || true)" ] && ok "adopt --all: $r 已配 hooksPath" || bad "adopt --all: $r 未配置"
155
+ done
156
+ [ ! -d "$AR/a-worktree--w/.git/dia" ] && ok "adopt --all 跳过 worktree 目录" || bad "adopt --all 误改 worktree"
157
+ DIA_WT_REPOS_ROOT="$TD/empty-root" DIA_WT_DATA_ROOT="$TD/dr3" bash "$WT" adopt --all >/dev/null 2>&1
158
+ [ $? = 2 ] && ok "adopt --all 空结果 exit 2" || bad "adopt --all 空结果未 exit 2"
159
+
160
+ # ── doctor --fix:钩子被覆盖后能无损重建 ────────────────────────────────────
161
+ R8="$TD/repo8"; mkdir -p "$R8"; git -C "$R8" init -q -b main
162
+ git -C "$R8" config user.email t@example.com; git -C "$R8" config user.name t
163
+ echo a > "$R8/a.txt"; git -C "$R8" add -A; git -C "$R8" commit -qm init --no-verify
164
+ bash "$WT" adopt "$R8" --apply >/dev/null 2>&1
165
+ rm -f "$R8/.git/dia/hooks/post-checkout"
166
+ printf '#!/bin/sh\nexit 0\n' > "$R8/.git/dia/hooks/pre-commit"; chmod +x "$R8/.git/dia/hooks/pre-commit"
167
+ if bash "$WT" doctor "$R8" >/dev/null 2>&1; then bad "钩子被覆盖后 doctor 仍通过"; else ok "钩子被覆盖后 doctor 报失败"; fi
168
+ bash "$WT" doctor "$R8" --fix >/dev/null 2>&1 || bad "doctor --fix 失败"
169
+ bash "$WT" doctor "$R8" >/dev/null 2>&1 && ok "doctor --fix 后恢复 ok" || bad "doctor --fix 后仍失败"
170
+ [ -x "$R8/.git/dia/hooks/post-checkout" ] && ok "doctor --fix 补回 post-checkout" || bad "post-checkout 未补回"
171
+
143
172
  # ── gate:成功 / 失败(P1-3 精确匹配)────────────────────────────────────────
144
173
  bash "$WT" gate "$R5" x >/dev/null 2>&1 && ok "gate 成功" || bad "gate 失败"
145
174
  if bash "$WT" gate "$R5" xb >/dev/null 2>&1; then bad "gate 子串误匹配(x 命中 xb)"; else ok "gate 精确匹配 feature"; fi