@simonyea/holysheep-cli 1.7.4 → 1.7.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simonyea/holysheep-cli",
3
- "version": "1.7.4",
3
+ "version": "1.7.6",
4
4
  "description": "Claude Code/Cursor/Cline API relay for China — ¥1=$1, WeChat/Alipay payment, no credit card, no VPN. One command setup for all AI coding tools.",
5
5
  "keywords": [
6
6
  "openai-china",
@@ -6,16 +6,16 @@ const chalk = require('chalk')
6
6
  const ora = require('ora')
7
7
  const { execSync, spawnSync } = require('child_process')
8
8
  const { saveConfig, getApiKey, BASE_URL_ANTHROPIC, BASE_URL_OPENAI, SHOP_URL } = require('../utils/config')
9
- const { writeEnvToShell } = require('../utils/shell')
9
+ const { writeEnvToShell, ensureWindowsUserPathHasNpmBin } = require('../utils/shell')
10
10
  const TOOLS = require('../tools')
11
11
 
12
12
  // 工具的自动安装命令(npm/pip)
13
13
  const AUTO_INSTALL = {
14
14
  'claude-code': {
15
15
  cmd: process.platform === 'win32'
16
- ? 'powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://claude.ai/install.ps1 | iex"'
16
+ ? 'powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "irm https://claude.ai/install.ps1 | iex"'
17
17
  : 'curl -fsSL https://claude.ai/install.sh | bash',
18
- mgr: process.platform === 'win32' ? 'powershell' : 'bash',
18
+ mgr: process.platform === 'win32' ? 'powershell.exe' : 'bash',
19
19
  },
20
20
  'codex': { cmd: 'npm install -g @openai/codex', mgr: 'npm' },
21
21
  'gemini-cli': { cmd: 'npm install -g @google/gemini-cli', mgr: 'npm' },
@@ -55,7 +55,11 @@ async function tryAutoInstall(tool) {
55
55
 
56
56
  // 检查 npm/pip 是否可用
57
57
  try {
58
- execSync(`${info.mgr} --version`, { stdio: 'ignore' })
58
+ if (process.platform === 'win32' && info.mgr.toLowerCase() === 'powershell.exe') {
59
+ execSync('where powershell.exe', { stdio: 'ignore' })
60
+ } else {
61
+ execSync(`${info.mgr} --version`, { stdio: 'ignore' })
62
+ }
59
63
  } catch {
60
64
  console.log(chalk.red(` ✗ 未找到 ${info.mgr},无法自动安装 ${tool.name}`))
61
65
  return false
@@ -75,6 +79,7 @@ async function tryAutoInstall(tool) {
75
79
  console.log(chalk.yellow(` ⚠ 安装后未检测到命令,尝试直接配置...`))
76
80
  }
77
81
  if (process.platform === 'win32') {
82
+ ensureWindowsUserPathHasNpmBin()
78
83
  tool._winJustInstalled = true // 标记为 Windows 刚装的,摘要里特殊处理
79
84
  }
80
85
  return true // 安装成功就视为可配置
package/src/index.js CHANGED
@@ -50,6 +50,7 @@ function printBanner() {
50
50
 
51
51
  program
52
52
  .name('hs')
53
+ .enablePositionalOptions()
53
54
  .description('一键配置所有 AI 编程工具接入 HolySheep API')
54
55
  .version(pkg.version, '-v, --version')
55
56
  .addHelpText('before', `
@@ -4,6 +4,7 @@
4
4
  const fs = require('fs')
5
5
  const path = require('path')
6
6
  const os = require('os')
7
+ const { execSync } = require('child_process')
7
8
 
8
9
  const MARKER_START = '# >>> holysheep-cli managed >>>'
9
10
  const MARKER_END = '# <<< holysheep-cli managed <<<'
@@ -70,10 +71,47 @@ function buildEnvBlock(envVars, isFish = false) {
70
71
  return '\n' + lines.join('\n') + '\n'
71
72
  }
72
73
 
74
+ function ensureWindowsUserPathHasNpmBin() {
75
+ if (process.platform !== 'win32') return []
76
+
77
+ const appData = process.env.APPDATA
78
+ if (!appData) return []
79
+
80
+ const npmBin = path.join(appData, 'npm')
81
+ let currentPath = ''
82
+ try {
83
+ currentPath = execSync(
84
+ 'powershell.exe -NoProfile -Command "[Environment]::GetEnvironmentVariable(\'Path\', \'User\')"',
85
+ { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }
86
+ ).trim()
87
+ } catch {
88
+ currentPath = process.env.PATH || ''
89
+ }
90
+
91
+ const parts = currentPath
92
+ .split(';')
93
+ .map((item) => item.trim())
94
+ .filter(Boolean)
95
+
96
+ const hasNpmBin = parts.some((item) => item.toLowerCase() === npmBin.toLowerCase())
97
+ if (hasNpmBin) return []
98
+
99
+ const nextPath = [...parts, npmBin].join(';')
100
+ try {
101
+ const escapedPath = nextPath.replace(/'/g, "''")
102
+ execSync(
103
+ `powershell.exe -NoProfile -Command "[Environment]::SetEnvironmentVariable('Path', '${escapedPath}', 'User')"`,
104
+ { stdio: 'ignore' }
105
+ )
106
+ return ['[用户 PATH] %APPDATA%\\npm']
107
+ } catch {
108
+ return []
109
+ }
110
+ }
111
+
73
112
  function writeEnvToShell(envVars) {
74
113
  // Windows: 用 setx 写入用户级环境变量(需重启终端生效)
75
114
  if (process.platform === 'win32') {
76
- const { execSync } = require('child_process')
77
115
  const written = []
78
116
  for (const [k, v] of Object.entries(envVars)) {
79
117
  try {
@@ -81,6 +119,7 @@ function writeEnvToShell(envVars) {
81
119
  written.push(`[系统环境变量] ${k}`)
82
120
  } catch {}
83
121
  }
122
+ written.push(...ensureWindowsUserPathHasNpmBin())
84
123
  if (written.length > 0) {
85
124
  const chalk = require('chalk')
86
125
  console.log(chalk.yellow('\n ⚠️ Windows 环境变量已写入,需要重启终端后生效'))
@@ -135,4 +174,4 @@ function escapeRegex(s) {
135
174
  return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
136
175
  }
137
176
 
138
- module.exports = { getShellRcFiles, writeEnvToShell, removeEnvFromShell }
177
+ module.exports = { getShellRcFiles, writeEnvToShell, removeEnvFromShell, ensureWindowsUserPathHasNpmBin }