ticketpro-auto-setup 1.1.0 → 1.1.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.
package/dist/cli.js
CHANGED
|
@@ -62,7 +62,9 @@ function showSummary(state) {
|
|
|
62
62
|
lines.push(formatResultLine('Auto-Compact: 155K (78%)', claudeConfigResult?.success ?? false));
|
|
63
63
|
// 扩展结果
|
|
64
64
|
for (const ext of state.claudeExtensions) {
|
|
65
|
-
const result = state.results.find(r => r.name === ext ||
|
|
65
|
+
const result = state.results.find(r => r.name === ext ||
|
|
66
|
+
r.name.startsWith(ext) ||
|
|
67
|
+
(ext === 'grok-search' && r.name.startsWith('GrokSearch')));
|
|
66
68
|
const label = ext === 'code-abyss' ? 'code-abyss 技能'
|
|
67
69
|
: ext === 'jshook-skill' ? 'jshook-skill 技能'
|
|
68
70
|
: ext === 'grok-search' ? 'GrokSearch MCP'
|
|
@@ -5,7 +5,7 @@ import fs from 'node:fs';
|
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import ora from 'ora';
|
|
7
7
|
import { execCommand, execAsync } from '../utils/shell.js';
|
|
8
|
-
import { getPlatform, getClaudeDir } from '../utils/platform.js';
|
|
8
|
+
import { getPlatform, getClaudeDir, getClaudeJsonPath } from '../utils/platform.js';
|
|
9
9
|
import { log } from '../utils/logger.js';
|
|
10
10
|
/**
|
|
11
11
|
* 安装 Claude Code CLI
|
|
@@ -32,6 +32,7 @@ export async function installClaudeCode() {
|
|
|
32
32
|
*/
|
|
33
33
|
export function configureClaudeCode(state) {
|
|
34
34
|
const claudeDir = getClaudeDir();
|
|
35
|
+
const claudeJsonPath = getClaudeJsonPath();
|
|
35
36
|
try {
|
|
36
37
|
// 确保目录存在
|
|
37
38
|
fs.mkdirSync(claudeDir, { recursive: true });
|
|
@@ -55,6 +56,20 @@ export function configureClaudeCode(state) {
|
|
|
55
56
|
};
|
|
56
57
|
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf-8');
|
|
57
58
|
log.success(`Claude Code config written to ${settingsPath}`);
|
|
59
|
+
// 写入 ~/.claude.json 以跳过首次 onboarding 登录提示
|
|
60
|
+
// 保留用户已有字段,只覆盖 hasCompletedOnboarding
|
|
61
|
+
let claudeMeta = {};
|
|
62
|
+
if (fs.existsSync(claudeJsonPath)) {
|
|
63
|
+
try {
|
|
64
|
+
claudeMeta = JSON.parse(fs.readFileSync(claudeJsonPath, 'utf-8'));
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
claudeMeta = {};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
claudeMeta.hasCompletedOnboarding = true;
|
|
71
|
+
fs.writeFileSync(claudeJsonPath, JSON.stringify(claudeMeta, null, 2), 'utf-8');
|
|
72
|
+
log.success(`Claude onboarding bypass configured at ${claudeJsonPath}`);
|
|
58
73
|
return { name: 'Claude Code Config', success: true };
|
|
59
74
|
}
|
|
60
75
|
catch (err) {
|
|
@@ -80,10 +80,14 @@ function spawnCodeAbyss(command, args) {
|
|
|
80
80
|
return new Promise((resolve) => {
|
|
81
81
|
const { isWindows } = getPlatform();
|
|
82
82
|
const timeout = 300_000; // 5 min
|
|
83
|
-
|
|
83
|
+
// 用 shell -c 拼接命令字符串,避免 DEP0190 警告
|
|
84
|
+
// (spawn 同时传 args + shell: true 会触发 Node 弃用警告)
|
|
85
|
+
const shell = isWindows ? 'cmd.exe' : '/bin/bash';
|
|
86
|
+
const shellArg = isWindows ? '/c' : '-c';
|
|
87
|
+
const fullCmd = [command, ...args].join(' ');
|
|
88
|
+
const child = spawn(shell, [shellArg, fullCmd], {
|
|
84
89
|
env: { ...process.env, CI: 'true', FORCE_COLOR: '0' },
|
|
85
90
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
86
|
-
shell: isWindows ? 'cmd.exe' : '/bin/bash',
|
|
87
91
|
});
|
|
88
92
|
let killed = false;
|
|
89
93
|
// 超时保护
|
|
@@ -8,19 +8,62 @@ import { execAsync, commandExists } from '../utils/shell.js';
|
|
|
8
8
|
import { getClaudeDir } from '../utils/platform.js';
|
|
9
9
|
import { appendToCodexConfig } from './codex-cli.js';
|
|
10
10
|
import { log } from '../utils/logger.js';
|
|
11
|
+
/**
|
|
12
|
+
* 检测 Python 环境并确保 uvx 可用
|
|
13
|
+
* 流程:
|
|
14
|
+
* 1. uvx 已存在 → 直接返回 true
|
|
15
|
+
* 2. uvx 不存在 → 尝试 pip install uv / pip3 install uv
|
|
16
|
+
* 3. pip/pip3 都不存在 → 报错返回 false(终止 GrokSearch 安装)
|
|
17
|
+
*/
|
|
18
|
+
async function ensureUvx() {
|
|
19
|
+
// uvx 已可用,直接通过
|
|
20
|
+
if (commandExists('uvx'))
|
|
21
|
+
return true;
|
|
22
|
+
log.warn('uvx 未找到,GrokSearch 需要 Python uv 工具链。');
|
|
23
|
+
// 检测 pip / pip3
|
|
24
|
+
const hasPip3 = commandExists('pip3');
|
|
25
|
+
const hasPip = commandExists('pip');
|
|
26
|
+
if (!hasPip3 && !hasPip) {
|
|
27
|
+
log.error('未检测到 Python / pip!无法安装 uvx。');
|
|
28
|
+
log.error('GrokSearch MCP 需要 Python 环境,请先安装 Python:');
|
|
29
|
+
log.dim(' Ubuntu/Debian: sudo apt install python3 python3-pip');
|
|
30
|
+
log.dim(' macOS: brew install python3');
|
|
31
|
+
log.dim(' Windows: https://www.python.org/downloads/');
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
const pipCmd = hasPip3 ? 'pip3' : 'pip';
|
|
35
|
+
log.info(`正在通过 ${pipCmd} 安装 uv...`);
|
|
36
|
+
const spinner = ora(`${pipCmd} install uv...`).start();
|
|
37
|
+
const result = await execAsync(`${pipCmd} install uv --break-system-packages 2>/dev/null || ${pipCmd} install uv`, { timeout: 120_000 });
|
|
38
|
+
if (!result.success) {
|
|
39
|
+
spinner.fail('uv 安装失败');
|
|
40
|
+
log.error('请手动安装 uv: pip install uv');
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
spinner.succeed('uv 安装成功');
|
|
44
|
+
// 安装后再验证 uvx 是否可用
|
|
45
|
+
if (commandExists('uvx'))
|
|
46
|
+
return true;
|
|
47
|
+
// uvx 可能在 ~/.local/bin 等非 PATH 路径,尝试直接用 `uv tool run`
|
|
48
|
+
log.warn('uvx 命令不在 PATH 中,但 uv 已安装。');
|
|
49
|
+
log.dim('请执行: export PATH="$HOME/.local/bin:$PATH" 并重启终端');
|
|
50
|
+
// 仍返回 true,配置文件已写入,uvx 修复 PATH 后即可使用
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
11
53
|
/**
|
|
12
54
|
* 为 Claude Code 安装 GrokSearch MCP
|
|
13
55
|
*/
|
|
14
56
|
export async function installGrokSearchForClaude(config) {
|
|
15
57
|
const spinner = ora('Configuring GrokSearch MCP for Claude Code...').start();
|
|
58
|
+
spinner.stop(); // 暂停 spinner,先做 Python 检测
|
|
59
|
+
// 确保 uvx 可用
|
|
60
|
+
const uvxOk = await ensureUvx();
|
|
61
|
+
if (!uvxOk) {
|
|
62
|
+
log.error('跳过 GrokSearch 配置(缺少 Python 环境)');
|
|
63
|
+
return { name: 'GrokSearch (Claude)', success: false, error: 'Python/pip not found' };
|
|
64
|
+
}
|
|
65
|
+
spinner.start('Configuring GrokSearch MCP for Claude Code...');
|
|
16
66
|
try {
|
|
17
|
-
// 检查 uvx 是否可用
|
|
18
|
-
const hasUvx = commandExists('uvx');
|
|
19
|
-
if (!hasUvx) {
|
|
20
|
-
spinner.warn('uvx not found. GrokSearch requires Python uv/uvx.');
|
|
21
|
-
log.dim('Install: pip install uv or https://docs.astral.sh/uv/');
|
|
22
|
-
log.dim('Will configure anyway — please install uvx before using.');
|
|
23
|
-
}
|
|
24
67
|
// 构建 MCP 配置 JSON
|
|
25
68
|
const mcpConfig = JSON.stringify({
|
|
26
69
|
type: 'stdio',
|
|
@@ -57,6 +100,14 @@ export async function installGrokSearchForClaude(config) {
|
|
|
57
100
|
*/
|
|
58
101
|
export async function installGrokSearchForCodex(config) {
|
|
59
102
|
const spinner = ora('Configuring GrokSearch MCP for Codex CLI...').start();
|
|
103
|
+
spinner.stop();
|
|
104
|
+
// 确保 uvx 可用
|
|
105
|
+
const uvxOk = await ensureUvx();
|
|
106
|
+
if (!uvxOk) {
|
|
107
|
+
log.error('跳过 GrokSearch 配置(缺少 Python 环境)');
|
|
108
|
+
return { name: 'GrokSearch (Codex)', success: false, error: 'Python/pip not found' };
|
|
109
|
+
}
|
|
110
|
+
spinner.start('Configuring GrokSearch MCP for Codex CLI...');
|
|
60
111
|
try {
|
|
61
112
|
const toml = `
|
|
62
113
|
[[mcp_servers]]
|
package/dist/utils/platform.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import type { PlatformInfo } from '../types/index.js';
|
|
|
2
2
|
export declare function getPlatform(): PlatformInfo;
|
|
3
3
|
/** 获取 ~/.claude 路径 */
|
|
4
4
|
export declare function getClaudeDir(): string;
|
|
5
|
+
/** 获取 ~/.claude.json 路径(onboarding 状态文件,在 home 目录下,非 .claude/ 目录内) */
|
|
6
|
+
export declare function getClaudeJsonPath(): string;
|
|
5
7
|
/** 获取 ~/.codex 路径 */
|
|
6
8
|
export declare function getCodexDir(): string;
|
|
7
9
|
/** 获取 shell profile 文件路径 */
|
package/dist/utils/platform.js
CHANGED
|
@@ -36,6 +36,10 @@ export function getPlatform() {
|
|
|
36
36
|
export function getClaudeDir() {
|
|
37
37
|
return path.join(getPlatform().homeDir, '.claude');
|
|
38
38
|
}
|
|
39
|
+
/** 获取 ~/.claude.json 路径(onboarding 状态文件,在 home 目录下,非 .claude/ 目录内) */
|
|
40
|
+
export function getClaudeJsonPath() {
|
|
41
|
+
return path.join(getPlatform().homeDir, '.claude.json');
|
|
42
|
+
}
|
|
39
43
|
/** 获取 ~/.codex 路径 */
|
|
40
44
|
export function getCodexDir() {
|
|
41
45
|
return path.join(getPlatform().homeDir, '.codex');
|