@hupan56/wlkj 2.2.1 → 2.2.2

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.
Files changed (2) hide show
  1. package/bin/cli.js +76 -6
  2. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -337,6 +337,8 @@ function doHelp() {
337
337
  console.log("=== 环境安装 (什么都没装时先跑这个) ===");
338
338
  console.log(" npx @hupan56/wlkj install-env 检测+自动装 Node/Python/git");
339
339
  console.log(" npx @hupan56/wlkj install-env --check 只检测不装");
340
+ console.log(" npx @hupan56/wlkj install-env --location D:\\wldev 指定安装目录");
341
+ console.log(" npx @hupan56/wlkj add-path D:\\wldev\\nodejs 把目录加到系统 PATH");
340
342
  console.log("");
341
343
  console.log("=== 一键安装 (装好环境后) ===");
342
344
  console.log(" npx @hupan56/wlkj init [你的名字] 安装完整引擎 + 自动初始化");
@@ -364,9 +366,20 @@ function doHelp() {
364
366
  console.log("");
365
367
  }
366
368
 
367
- function doInstallEnv(checkOnly = false) {
369
+ function doInstallEnv(checkOnly = false, location = null) {
368
370
  const { execSync } = require("child_process");
371
+ const isWin = process.platform === "win32";
372
+ const isMac = process.platform === "darwin";
373
+
374
+ // 解析 --location(CLI 入口已提取,这里兜底)
369
375
  console.log("\n=== 环境检测 ===\n");
376
+ if (location) {
377
+ console.log(` 安装位置: ${location}${isWin ? "" : " (仅 Windows winget 支持指定目录)"}`);
378
+ // Windows: 预建目录
379
+ if (isWin) {
380
+ try { fs.mkdirSync(location, { recursive: true }); } catch { /* */ }
381
+ }
382
+ }
370
383
 
371
384
  // 检测函数
372
385
  function check(cmd) {
@@ -377,15 +390,25 @@ function doInstallEnv(checkOnly = false) {
377
390
  try { execSync(`where ${cmd}`, { encoding: "utf-8", timeout: 3000, stdio: "pipe" }); return true; }
378
391
  catch { try { execSync(`which ${cmd}`, { encoding: "utf-8", timeout: 3000, stdio: "pipe" }); return true; } catch { return false; } }
379
392
  }
393
+ // Windows: 把目录加到用户 PATH(幂等,已存在不重复加)
394
+ function addToPathWin(dir) {
395
+ if (!isWin) return false;
396
+ try {
397
+ // 用 setx 会截断超长 PATH,改用 PowerShell 读 User PATH 追加
398
+ const ps = `powershell -NoProfile -Command "$p=[Environment]::GetEnvironmentVariable('Path','User'); if($p -notlike '*{dir}*'){[Environment]::SetEnvironmentVariable('Path',$p.TrimEnd(';')+';{dir}','User')}"`.replace(/{dir}/g, dir.replace(/\\/g, "\\\\"));
399
+ execSync(ps, { stdio: "pipe", timeout: 15000 });
400
+ return true;
401
+ } catch (e) { console.log(` [WARN] 加 PATH 失败(可手动加): ${dir}`); return false; }
402
+ }
380
403
  function install(name, wingetId, brewPkg) {
381
404
  if (checkOnly) return false;
382
- const isWin = process.platform === "win32";
383
- const isMac = process.platform === "darwin";
384
405
  try {
385
406
  if (isWin && has("winget")) {
386
407
  console.log(` 用 winget 装 ${name}...`);
387
- execSync(`winget install --id ${wingetId} -e --source winget --accept-source-agreements --accept-package-agreements`,
388
- { stdio: "inherit", timeout: 300000 });
408
+ // winget --location 不一定被安装包尊重,但先传上
409
+ let cmd = `winget install --id ${wingetId} -e --source winget --accept-source-agreements --accept-package-agreements`;
410
+ if (location) cmd += ` --location "${location}"`;
411
+ execSync(cmd, { stdio: "inherit", timeout: 300000 });
389
412
  return true;
390
413
  } else if (isMac && has("brew")) {
391
414
  console.log(` 用 brew 装 ${name}...`);
@@ -435,6 +458,20 @@ function doInstallEnv(checkOnly = false) {
435
458
  else { need.push("git (手动: https://git-scm.com, 可选)"); }
436
459
  }
437
460
 
461
+ // --location 模式: 提示用户验证安装位置 + 手动加 PATH
462
+ // (winget 的 --location 对 Node/Python 不一定生效,需用户确认)
463
+ if (location && isWin) {
464
+ console.log(`\n--- 安装位置确认 ---`);
465
+ console.log(` 你指定了: ${location}`);
466
+ console.log(` 注意: winget 的 --location 对 Node.js/Python 不一定生效`);
467
+ console.log(` (取决于安装包是否支持自定义路径)`);
468
+ console.log(` 请检查实际装到哪了:`);
469
+ console.log(` 重新打开终端后跑: node --version python --version git --version`);
470
+ console.log(` 如果某软件没进 PATH, 手动把它加进去:`);
471
+ console.log(` 设置 → 系统 → 关于 → 高级系统设置 → 环境变量 → Path → 新建`);
472
+ console.log(` 或用命令: npx @hupan56/wlkj add-path "D:\\wldev\\nodejs"`);
473
+ }
474
+
438
475
  console.log("\n=== 结果 ===");
439
476
  if (need.length === 0) {
440
477
  console.log(" 环境就绪! 下一步: npx @hupan56/wlkj init");
@@ -445,13 +482,46 @@ function doInstallEnv(checkOnly = false) {
445
482
  }
446
483
  }
447
484
 
485
+ // add-path: 把目录加到 Windows 用户 PATH(幂等)
486
+ function doAddPath(dir) {
487
+ if (!dir) { console.log("用法: npx @hupan56/wlkj add-path <目录>"); return; }
488
+ if (process.platform !== "win32") {
489
+ console.log("add-path 仅支持 Windows。Mac/Linux 请手动加到 ~/.zshrc 或 ~/.bashrc");
490
+ return;
491
+ }
492
+ const abs = path.resolve(dir);
493
+ if (!fs.existsSync(abs)) {
494
+ console.log(`[警告] 目录不存在: ${abs}(仍会加到 PATH)`);
495
+ }
496
+ try {
497
+ const ps = `powershell -NoProfile -Command "$p=[Environment]::GetEnvironmentVariable('Path','User'); if($p -notlike '*${abs.replace(/\\/g,"\\\\")}*'){[Environment]::SetEnvironmentVariable('Path',$p.TrimEnd(';')+';${abs.replace(/\\/g,"\\\\")}','User'); Write-Output 'ADDED'} else { Write-Output 'EXISTS' }"`;
498
+ const out = execSync(ps, { encoding: "utf-8", timeout: 15000 }).trim();
499
+ console.log(` ${out === "ADDED" ? "已加入" : "已存在(无需重复加)"}: ${abs}`);
500
+ console.log(` ⚠ 需要重新打开终端才生效`);
501
+ } catch (e) {
502
+ console.log(` 失败: ${(e.message || "").slice(0, 100)}`);
503
+ console.log(` 手动加: 设置 → 系统 → 关于 → 高级系统设置 → 环境变量 → Path → 新建 → ${abs}`);
504
+ }
505
+ }
506
+
448
507
  const [,, cmd, ...rest] = process.argv;
449
508
  const mapped = rest.map(a => a === "-p" ? "--priority" : a);
450
509
 
451
510
  switch (cmd) {
452
511
  case "init": doInit(rest[0]); break;
453
512
  case "update": case "upgrade": doUpdate(); break;
454
- case "install-env": doInstallEnv(rest[0] === "--check"); break;
513
+ case "install-env": {
514
+ const checkOnly = rest.includes("--check");
515
+ // 提取 --location <dir> 或 --location=<dir>
516
+ let loc = null;
517
+ const li = rest.indexOf("--location");
518
+ if (li !== -1 && rest[li + 1]) loc = rest[li + 1];
519
+ const eq = rest.find(a => a.startsWith("--location="));
520
+ if (eq) loc = eq.slice("--location=".length);
521
+ doInstallEnv(checkOnly, loc);
522
+ break;
523
+ }
524
+ case "add-path": doAddPath(rest[0]); break;
455
525
  case "task": process.stdout.write(py("task.py", mapped)); break;
456
526
  case "status": doStatus(); break;
457
527
  case "session": process.stdout.write(py("add_session.py", rest)); break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hupan56/wlkj",
3
- "version": "2.2.1",
3
+ "version": "2.2.2",
4
4
  "description": "AI Product R&D Workflow - PRD/Prototype/Search/Task/Report",
5
5
  "bin": {
6
6
  "wlkj": "bin/cli.js"