@hupan56/wlkj 2.7.10 → 2.7.12

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/bin/cli.js CHANGED
@@ -563,10 +563,41 @@ function doUpdate() {
563
563
 
564
564
  // === 2.5. git pull 拉最新团队数据 (kg.duckdb/kg_db.duckdb/PRD等在git里) ===
565
565
  // git pull 失败会导致 kg.duckdb 拿不到 → kg MCP 无数据(但仍能连)。
566
- // 失败原因常见: 未配 git 身份 / 远程仓库需要认证 / 网络问题。
566
+ // 失败原因常见: 未配 git 身份 / 远程仓库需要认证 / 网络问题 / 分支没tracking。
567
567
  // 这里给出清晰诊断, 不让"git pull 失败"变成无声的静默跳过。
568
+ // 前置: 自愈分支 tracking (老版 init 配了 remote 但没 set-upstream, pull 会报
569
+ // "no tracking information"。这里检测到就补上, 老用户 update 也能自动修)
568
570
  try {
569
571
  const { execSync: _es } = require("child_process");
572
+ // 先看当前分支有没有 upstream
573
+ let _trackOk = false;
574
+ try {
575
+ _es("git rev-parse --abbrev-ref --symbolic-full-name @{u}", { cwd, encoding: "utf-8", timeout: 5000, stdio: "pipe" });
576
+ _trackOk = true; // 有 upstream, 正常
577
+ } catch {
578
+ // 没 tracking — 尝试补设 (有 origin remote 的前提下)
579
+ try {
580
+ const _remote = _es("git remote", { cwd, encoding: "utf-8", timeout: 5000, stdio: "pipe" }).trim();
581
+ if (_remote.split(/\s+/).includes("origin")) {
582
+ _es("git fetch origin", { cwd, encoding: "utf-8", timeout: 30000, stdio: "pipe" });
583
+ // 确定本地分支名
584
+ const _branch = _es("git rev-parse --abbrev-ref HEAD", { cwd, encoding: "utf-8", timeout: 5000, stdio: "pipe" }).trim();
585
+ // 远程用 master 还是 main
586
+ let _remoteBranch = null;
587
+ for (const _c of ["master", "main"]) {
588
+ try {
589
+ _es(`git rev-parse --verify remotes/origin/${_c}`, { cwd, encoding: "utf-8", timeout: 5000, stdio: "pipe" });
590
+ _remoteBranch = _c; break;
591
+ } catch { /* 该分支不存在, 试下一个 */ }
592
+ }
593
+ if (_remoteBranch) {
594
+ _es(`git branch --set-upstream-to=origin/${_remoteBranch} ${_branch}`, { cwd, encoding: "utf-8", timeout: 5000, stdio: "pipe" });
595
+ console.log(` git: 已自动设置上游 tracking (origin/${_remoteBranch})`);
596
+ _trackOk = true;
597
+ }
598
+ }
599
+ } catch { /* 补 tracking 失败, 走下面的 pull 诊断 */ }
600
+ }
570
601
  const pullR = _es("git pull --no-rebase 2>&1", { cwd, encoding: "utf-8", timeout: 30000 });
571
602
  if (pullR.includes("Already up to date") || pullR.includes("已经是最新")) {
572
603
  console.log(` git: 已是最新`);
@@ -576,20 +607,32 @@ function doUpdate() {
576
607
  console.log(` git: 已拉取最新`);
577
608
  }
578
609
  } catch (e) {
579
- // git pull 失败诊断: 区分"没配git身份"/"远程要认证"/"网络问题"
610
+ // git pull 失败诊断: 区分"没配git身份"/"远程要认证"/"网络问题"/"非git仓库"
611
+ // node execSync 抛异常时, git 的真实报错在 e.stderr/e.stdout, 不能只看 e.message
580
612
  const errMsg = String(e.message || "");
581
- const stdout = String(e.stdout || "");
582
- const combined = errMsg + " " + stdout;
583
- if (combined.includes("Authentication failed") || combined.includes("Permission denied") ||
584
- combined.includes("could not read Username") || combined.includes("不支持密码")) {
613
+ const stdout = String((e.stdout || "") + " " + (e.stderr || ""));
614
+ const combined = (errMsg + " " + stdout).toLowerCase();
615
+ if (combined.includes("authentication failed") || combined.includes("permission denied") ||
616
+ combined.includes("could not read username") || combined.includes("不支持密码") ||
617
+ combined.includes("credentials") || combined.includes("403") || combined.includes("401")) {
585
618
  console.log(` git: ⚠️ 认证失败 — kg.duckdb 等团队数据拉不到`);
586
619
  console.log(` 原因: git 身份/凭证未配。MCP 能连但无数据。`);
587
620
  console.log(` 修复: npx @hupan56/wlkj init <你的名字> (交互式配 git 账号)`);
588
- } else if (combined.includes("not a git repository") || combined.includes("not a git dir")) {
589
- console.log(` git: 非git仓库 team_sync 拉团队数据`);
590
- console.log(` 修复: npx @hupan56/wlkj init <你的名字>`);
621
+ } else if (combined.includes("not a git repository") || combined.includes("not a git dir") ||
622
+ combined.includes("unknown revision") || combined.includes("does not have any commits")) {
623
+ console.log(` git: ⚠️ 非git仓库或空仓库 团队数据拉不到`);
624
+ console.log(` 原因: 此目录不是 git clone 来的, 或没有 remote。`);
625
+ console.log(` 修复: npx @hupan56/wlkj init <你的名字> (会配团队远程仓库)`);
626
+ } else if (combined.includes("timed out") || combined.includes("timeout") ||
627
+ combined.includes("could not resolve host") || combined.includes("connection refused") ||
628
+ combined.includes("network is unreachable")) {
629
+ console.log(` git: ⚠️ 网络问题 — 连不上远程仓库`);
630
+ console.log(` 原因: ${stdout.trim().slice(0, 80) || "网络超时/无法解析主机"}`);
631
+ console.log(` (kg.duckdb 拉不到, MCP 能连但搜索无结果)`);
591
632
  } else {
592
- console.log(` git: 跳过 ${(errMsg).slice(0, 60)}`);
633
+ // 兜底: 显示 git 的真实报错, 不再笼统说 "Command failed"
634
+ const realErr = stdout.trim() || errMsg;
635
+ console.log(` git: ⚠️ 拉取失败 — ${realErr.slice(0, 100)}`);
593
636
  console.log(` (kg.duckdb 拉不到, MCP 能连但搜索无结果)`);
594
637
  }
595
638
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hupan56/wlkj",
3
- "version": "2.7.10",
3
+ "version": "2.7.12",
4
4
  "description": "AI Product R&D Workflow - PRD/Prototype/Search/Task/Report",
5
5
  "bin": {
6
6
  "wlkj": "bin/cli.js"
@@ -420,6 +420,37 @@ def _write_team_remote_to_config(url):
420
420
  pass
421
421
 
422
422
 
423
+ def _setup_tracking(base):
424
+ """git remote add 之后调: fetch 远程 + 设置当前分支的上游 tracking。
425
+ 没这步, git pull 会报 "no tracking information for the current branch"。
426
+ fetch 可能因网络/认证失败 — 失败只警告, 不阻塞 (remote 至少配上了)。
427
+ """
428
+ # fetch 远程分支
429
+ r = run(['git', 'fetch', 'origin'], cwd=str(base))
430
+ if r.returncode != 0:
431
+ err = (r.stderr or '').strip()
432
+ # 常见的非阻塞情况: 远程是空仓库(还没 push 过)、网络问题
433
+ if 'empty' in err.lower() or 'warning' in err.lower():
434
+ pass # 空仓库正常, 之后 push 了就有
435
+ else:
436
+ warn('git fetch 失败 (不阻塞, 之后 /wl-init 时重试): ' + err[:80])
437
+ return
438
+ # 确定本地当前分支名
439
+ br_r = run(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], cwd=str(base))
440
+ local_branch = br_r.stdout.strip() if br_r.returncode == 0 else 'master'
441
+ # 远程有 master 还是 main? 优先 master (团队约定), fallback main
442
+ remote_branch = None
443
+ for cand in ('master', 'main'):
444
+ check = run(['git', 'rev-parse', '--verify', f'remotes/origin/{cand}'], cwd=str(base))
445
+ if check.returncode == 0:
446
+ remote_branch = cand
447
+ break
448
+ if not remote_branch:
449
+ return # 远程没分支(空仓库), 没法设 tracking, 等 push 后再说
450
+ # 设置上游 tracking
451
+ run(['git', 'branch', f'--set-upstream-to=origin/{remote_branch}', local_branch], cwd=str(base))
452
+
453
+
423
454
  def configure_team_remote():
424
455
  """配置团队协作仓库的 git remote (workspace/ 产出往这里 push)。
425
456
 
@@ -439,6 +470,11 @@ def configure_team_remote():
439
470
  url_r = run(['git', 'remote', 'get-url', 'origin'], cwd=str(BASE))
440
471
  url = url_r.stdout.strip() if url_r.returncode == 0 else '?'
441
472
  ok(f'团队仓库已配置: origin -> {url}')
473
+ # 即使 origin 已配, 也要检查 tracking 是否设好 (修复历史 init 的遗漏)
474
+ track_r = run(['git', 'rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'], cwd=str(BASE))
475
+ if track_r.returncode != 0:
476
+ print(' (当前分支未设上游, 补设 tracking...)')
477
+ _setup_tracking(BASE)
442
478
  return
443
479
 
444
480
  # 3. 没有 origin — 从 config.yaml 读 team_remote (如果有)
@@ -448,6 +484,7 @@ def configure_team_remote():
448
484
  r = run(['git', 'remote', 'add', 'origin', team_url], cwd=str(BASE))
449
485
  if r.returncode == 0:
450
486
  ok(f'团队仓库已配置: origin -> {team_url}')
487
+ _setup_tracking(BASE) # fetch + 设上游, 让 git pull 能用
451
488
  else:
452
489
  warn('remote add 失败: ' + (r.stderr or '').strip()[:100])
453
490
  return
@@ -468,6 +505,7 @@ def configure_team_remote():
468
505
  r = run(['git', 'remote', 'add', 'origin', url], cwd=str(BASE))
469
506
  if r.returncode == 0:
470
507
  ok(f'团队仓库已配置: origin -> {url}')
508
+ _setup_tracking(BASE) # fetch + 设上游, 让 git pull 能用
471
509
  _write_team_remote_to_config(url) # 顺手写 config 供团队复用
472
510
  else:
473
511
  warn('remote add 失败: ' + (r.stderr or '').strip()[:100])