ticketpro-auto-setup 1.0.0

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 (39) hide show
  1. package/dist/cli.d.ts +5 -0
  2. package/dist/cli.js +119 -0
  3. package/dist/index.d.ts +7 -0
  4. package/dist/index.js +11 -0
  5. package/dist/installers/claude-code.d.ts +14 -0
  6. package/dist/installers/claude-code.js +73 -0
  7. package/dist/installers/code-abyss.d.ts +13 -0
  8. package/dist/installers/code-abyss.js +79 -0
  9. package/dist/installers/codex-cli.d.ts +18 -0
  10. package/dist/installers/codex-cli.js +122 -0
  11. package/dist/installers/grok-search.d.ts +10 -0
  12. package/dist/installers/grok-search.js +112 -0
  13. package/dist/installers/helloagents.d.ts +6 -0
  14. package/dist/installers/helloagents.js +148 -0
  15. package/dist/installers/jshook-skill.d.ts +6 -0
  16. package/dist/installers/jshook-skill.js +68 -0
  17. package/dist/pages/api-config.d.ts +6 -0
  18. package/dist/pages/api-config.js +65 -0
  19. package/dist/pages/claude-setup.d.ts +6 -0
  20. package/dist/pages/claude-setup.js +75 -0
  21. package/dist/pages/cleanup.d.ts +5 -0
  22. package/dist/pages/cleanup.js +74 -0
  23. package/dist/pages/codex-setup.d.ts +6 -0
  24. package/dist/pages/codex-setup.js +93 -0
  25. package/dist/pages/welcome.d.ts +6 -0
  26. package/dist/pages/welcome.js +35 -0
  27. package/dist/types/index.d.ts +58 -0
  28. package/dist/types/index.js +19 -0
  29. package/dist/utils/backup.d.ts +9 -0
  30. package/dist/utils/backup.js +79 -0
  31. package/dist/utils/banner.d.ts +9 -0
  32. package/dist/utils/banner.js +41 -0
  33. package/dist/utils/logger.d.ts +16 -0
  34. package/dist/utils/logger.js +40 -0
  35. package/dist/utils/platform.d.ts +9 -0
  36. package/dist/utils/platform.js +55 -0
  37. package/dist/utils/shell.d.ts +27 -0
  38. package/dist/utils/shell.js +77 -0
  39. package/package.json +49 -0
@@ -0,0 +1,148 @@
1
+ /**
2
+ * helloagents 安装逻辑
3
+ */
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import ora from 'ora';
7
+ import { execCommand } from '../utils/shell.js';
8
+ import { getPlatform, getCodexDir } from '../utils/platform.js';
9
+ import { log } from '../utils/logger.js';
10
+ /**
11
+ * 安装 helloagents(自主智能 Agent 伙伴)
12
+ */
13
+ export async function installHelloAgents() {
14
+ const spinner = ora('Installing helloagents (自主智能Agent伙伴)...').start();
15
+ const { isWindows, gitCmd } = getPlatform();
16
+ const codexDir = getCodexDir();
17
+ // 临时克隆目录
18
+ const tmpDir = isWindows
19
+ ? path.join(process.env.TEMP ?? 'C:\\Temp', 'helloagents')
20
+ : '/tmp/helloagents';
21
+ try {
22
+ // 清理临时目录
23
+ if (fs.existsSync(tmpDir)) {
24
+ fs.rmSync(tmpDir, { recursive: true, force: true });
25
+ }
26
+ // git clone
27
+ spinner.text = 'Cloning helloagents repository...';
28
+ const cloneResult = execCommand(`${gitCmd} clone https://github.com/hellowind777/helloagents.git "${tmpDir}"`, { timeout: 120_000 });
29
+ if (!cloneResult.success) {
30
+ spinner.fail('helloagents: git clone failed');
31
+ log.dim('请手动执行: git clone https://github.com/hellowind777/helloagents.git');
32
+ return { name: 'helloagents', success: false, error: 'git clone failed' };
33
+ }
34
+ // 确保 codex 目录存在
35
+ fs.mkdirSync(codexDir, { recursive: true });
36
+ // 尝试执行安装脚本
37
+ spinner.text = 'Running helloagents install script...';
38
+ if (isWindows) {
39
+ // Windows: 尝试 install.ps1
40
+ const ps1Path = path.join(tmpDir, 'install.ps1');
41
+ if (fs.existsSync(ps1Path)) {
42
+ const result = execCommand(`powershell -ExecutionPolicy Bypass -File "${ps1Path}"`, { timeout: 120_000 });
43
+ if (result.success) {
44
+ spinner.succeed('helloagents installed via install.ps1');
45
+ cleanup(tmpDir);
46
+ return { name: 'helloagents', success: true };
47
+ }
48
+ }
49
+ }
50
+ else {
51
+ // Unix: 尝试 install.sh
52
+ const shPath = path.join(tmpDir, 'install.sh');
53
+ if (fs.existsSync(shPath)) {
54
+ execCommand(`chmod +x "${shPath}"`);
55
+ const result = execCommand(`"${shPath}"`, { timeout: 120_000 });
56
+ if (result.success) {
57
+ spinner.succeed('helloagents installed via install.sh');
58
+ cleanup(tmpDir);
59
+ return { name: 'helloagents', success: true };
60
+ }
61
+ }
62
+ }
63
+ // Fallback: 手动复制文件
64
+ spinner.text = 'Install script not found/failed, copying files manually...';
65
+ const manualResult = manualInstall(tmpDir, codexDir);
66
+ if (manualResult) {
67
+ spinner.succeed('helloagents installed (manual copy)');
68
+ }
69
+ else {
70
+ spinner.warn('helloagents partially installed');
71
+ }
72
+ cleanup(tmpDir);
73
+ return { name: 'helloagents', success: manualResult };
74
+ }
75
+ catch (err) {
76
+ spinner.fail('helloagents installation failed');
77
+ cleanup(tmpDir);
78
+ return { name: 'helloagents', success: false, error: err.message };
79
+ }
80
+ }
81
+ /**
82
+ * 手动安装:复制关键文件到 ~/.codex/
83
+ */
84
+ function manualInstall(srcDir, codexDir) {
85
+ try {
86
+ // 复制 AGENTS.md(若存在)
87
+ const agentsMd = path.join(srcDir, 'AGENTS.md');
88
+ if (fs.existsSync(agentsMd)) {
89
+ fs.copyFileSync(agentsMd, path.join(codexDir, 'AGENTS.md'));
90
+ log.success('Copied AGENTS.md to ~/.codex/');
91
+ }
92
+ // 复制 instructions.md(若存在)
93
+ const instructionsMd = path.join(srcDir, 'instructions.md');
94
+ if (fs.existsSync(instructionsMd)) {
95
+ fs.copyFileSync(instructionsMd, path.join(codexDir, 'instructions.md'));
96
+ log.success('Copied instructions.md to ~/.codex/');
97
+ }
98
+ // 复制 skills 目录(若存在)
99
+ const skillsSrc = path.join(srcDir, 'skills');
100
+ const skillsDest = path.join(codexDir, 'skills');
101
+ if (fs.existsSync(skillsSrc)) {
102
+ copyDirRecursive(skillsSrc, skillsDest);
103
+ log.success('Copied skills/ to ~/.codex/skills/');
104
+ }
105
+ // 复制 agents 目录(若存在)
106
+ const agentsSrc = path.join(srcDir, 'agents');
107
+ const agentsDest = path.join(codexDir, 'agents');
108
+ if (fs.existsSync(agentsSrc)) {
109
+ copyDirRecursive(agentsSrc, agentsDest);
110
+ log.success('Copied agents/ to ~/.codex/agents/');
111
+ }
112
+ return true;
113
+ }
114
+ catch {
115
+ return false;
116
+ }
117
+ }
118
+ /**
119
+ * 递归复制目录
120
+ */
121
+ function copyDirRecursive(src, dest) {
122
+ fs.mkdirSync(dest, { recursive: true });
123
+ const entries = fs.readdirSync(src, { withFileTypes: true });
124
+ for (const entry of entries) {
125
+ const srcPath = path.join(src, entry.name);
126
+ const destPath = path.join(dest, entry.name);
127
+ if (entry.isDirectory()) {
128
+ copyDirRecursive(srcPath, destPath);
129
+ }
130
+ else {
131
+ fs.copyFileSync(srcPath, destPath);
132
+ }
133
+ }
134
+ }
135
+ /**
136
+ * 清理临时目录
137
+ */
138
+ function cleanup(dir) {
139
+ try {
140
+ if (fs.existsSync(dir)) {
141
+ fs.rmSync(dir, { recursive: true, force: true });
142
+ }
143
+ }
144
+ catch {
145
+ // 静默失败
146
+ }
147
+ }
148
+ //# sourceMappingURL=helloagents.js.map
@@ -0,0 +1,6 @@
1
+ import type { StepResult } from '../types/index.js';
2
+ /**
3
+ * 安装 jshook-skill(JS逆向工程技能)
4
+ */
5
+ export declare function installJshookSkill(): Promise<StepResult>;
6
+ //# sourceMappingURL=jshook-skill.d.ts.map
@@ -0,0 +1,68 @@
1
+ /**
2
+ * jshook-skill 安装逻辑
3
+ * 仓库: https://github.com/wuji66dde/jshook-skill
4
+ * 包名: jshook-reverse-skill (有 npm install + build 流程)
5
+ */
6
+ import fs from 'node:fs';
7
+ import path from 'node:path';
8
+ import ora from 'ora';
9
+ import { execCommand } from '../utils/shell.js';
10
+ import { getPlatform, getClaudeDir } from '../utils/platform.js';
11
+ import { log } from '../utils/logger.js';
12
+ /** jshook-skill 的真实 GitHub 仓库地址 */
13
+ const JSHOOK_REPO = 'https://github.com/wuji66dde/jshook-skill.git';
14
+ /**
15
+ * 安装 jshook-skill(JS逆向工程技能)
16
+ */
17
+ export async function installJshookSkill() {
18
+ const spinner = ora('Installing jshook-skill (JS逆向工程技能)...').start();
19
+ const claudeDir = getClaudeDir();
20
+ const skillDir = path.join(claudeDir, 'skills', 'jshook-skill');
21
+ const { gitCmd, npmCmd } = getPlatform();
22
+ try {
23
+ // 确保 skills 目录存在
24
+ fs.mkdirSync(path.join(claudeDir, 'skills'), { recursive: true });
25
+ // 如果已存在,先删除
26
+ if (fs.existsSync(skillDir)) {
27
+ fs.rmSync(skillDir, { recursive: true, force: true });
28
+ }
29
+ // git clone
30
+ spinner.text = 'Cloning jshook-skill repository...';
31
+ const cloneResult = execCommand(`${gitCmd} clone ${JSHOOK_REPO} "${skillDir}"`, { timeout: 120_000 });
32
+ if (!cloneResult.success) {
33
+ spinner.fail('jshook-skill: git clone failed');
34
+ log.dim(`请手动执行: git clone ${JSHOOK_REPO} ~/.claude/skills/jshook-skill`);
35
+ log.dim(`Error: ${cloneResult.stderr}`);
36
+ return { name: 'jshook-skill', success: false, error: 'git clone failed' };
37
+ }
38
+ // npm install
39
+ spinner.text = 'Installing jshook-skill dependencies...';
40
+ const installResult = execCommand(`${npmCmd} install`, { cwd: skillDir, timeout: 120_000 });
41
+ if (!installResult.success) {
42
+ spinner.warn('jshook-skill: npm install had issues (continuing)');
43
+ log.dim(installResult.stderr);
44
+ }
45
+ // npm run build
46
+ spinner.text = 'Building jshook-skill...';
47
+ const buildResult = execCommand(`${npmCmd} run build`, { cwd: skillDir, timeout: 120_000 });
48
+ if (!buildResult.success) {
49
+ spinner.warn('jshook-skill: build had issues (continuing)');
50
+ log.dim(buildResult.stderr);
51
+ }
52
+ // 验证关键文件
53
+ const skillMd = path.join(skillDir, 'SKILL.md');
54
+ const hasSkillMd = fs.existsSync(skillMd);
55
+ if (hasSkillMd) {
56
+ spinner.succeed('jshook-skill installed (SKILL.md found)');
57
+ }
58
+ else {
59
+ spinner.succeed('jshook-skill installed');
60
+ }
61
+ return { name: 'jshook-skill', success: true };
62
+ }
63
+ catch (err) {
64
+ spinner.fail('jshook-skill installation failed');
65
+ return { name: 'jshook-skill', success: false, error: err.message };
66
+ }
67
+ }
68
+ //# sourceMappingURL=jshook-skill.js.map
@@ -0,0 +1,6 @@
1
+ import type { SetupState } from '../types/index.js';
2
+ /**
3
+ * 工具选择 + API Key 输入 + 安装 + 配置
4
+ */
5
+ export declare function apiConfigPage(state: SetupState): Promise<void>;
6
+ //# sourceMappingURL=api-config.d.ts.map
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Page 1 — 工具选择 + API 配置
3
+ */
4
+ import { select, password } from '@inquirer/prompts';
5
+ import { installClaudeCode, configureClaudeCode } from '../installers/claude-code.js';
6
+ import { installCodexCli, configureCodexCli } from '../installers/codex-cli.js';
7
+ import { log } from '../utils/logger.js';
8
+ /**
9
+ * 工具选择 + API Key 输入 + 安装 + 配置
10
+ */
11
+ export async function apiConfigPage(state) {
12
+ log.section('📦 工具选择与 API 配置');
13
+ // 1. 选择工具
14
+ const toolChoice = await select({
15
+ message: '选择要安装的工具:',
16
+ choices: [
17
+ { value: 'both', name: 'Claude Code + Codex CLI(推荐)' },
18
+ { value: 'claude-only', name: '仅 Claude Code CLI' },
19
+ { value: 'codex-only', name: '仅 Codex CLI' },
20
+ ],
21
+ });
22
+ state.toolChoice = toolChoice;
23
+ state.installClaude = toolChoice === 'both' || toolChoice === 'claude-only';
24
+ state.installCodex = toolChoice === 'both' || toolChoice === 'codex-only';
25
+ // 2. 输入 API Key
26
+ console.log();
27
+ const apiKey = await password({
28
+ message: '输入中转站 API Key:',
29
+ mask: '*',
30
+ });
31
+ if (!apiKey || apiKey.trim().length === 0) {
32
+ log.error('API Key 不能为空!');
33
+ process.exit(1);
34
+ }
35
+ state.apiKey = apiKey.trim();
36
+ // 3. 显示中转站配置
37
+ console.log();
38
+ log.info('中转站配置(自动填写):');
39
+ if (state.installClaude) {
40
+ log.kv('Claude Code', state.claudeBaseUrl);
41
+ }
42
+ if (state.installCodex) {
43
+ log.kv('Codex CLI', state.codexBaseUrl);
44
+ }
45
+ console.log();
46
+ // 4. 安装 CLI 工具
47
+ if (state.installClaude) {
48
+ const result = await installClaudeCode();
49
+ state.results.push(result);
50
+ if (result.success) {
51
+ const configResult = configureClaudeCode(state);
52
+ state.results.push(configResult);
53
+ }
54
+ }
55
+ if (state.installCodex) {
56
+ const result = await installCodexCli();
57
+ state.results.push(result);
58
+ if (result.success) {
59
+ const configResult = configureCodexCli(state);
60
+ state.results.push(configResult);
61
+ }
62
+ }
63
+ console.log();
64
+ }
65
+ //# sourceMappingURL=api-config.js.map
@@ -0,0 +1,6 @@
1
+ import type { SetupState } from '../types/index.js';
2
+ /**
3
+ * Claude Code 扩展选择与安装
4
+ */
5
+ export declare function claudeSetupPage(state: SetupState): Promise<void>;
6
+ //# sourceMappingURL=claude-setup.d.ts.map
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Page 2 — Claude Code 插件/技能/MCP 选择与安装
3
+ */
4
+ import { checkbox, input, password } from '@inquirer/prompts';
5
+ import { installCodeAbyss } from '../installers/code-abyss.js';
6
+ import { installJshookSkill } from '../installers/jshook-skill.js';
7
+ import { installGrokSearchForClaude } from '../installers/grok-search.js';
8
+ import { log } from '../utils/logger.js';
9
+ /**
10
+ * Claude Code 扩展选择与安装
11
+ */
12
+ export async function claudeSetupPage(state) {
13
+ if (!state.installClaude)
14
+ return;
15
+ log.section('🔌 Claude Code 扩展配置');
16
+ // 选择扩展
17
+ const extensions = await checkbox({
18
+ message: '选择要安装的 Claude Code 扩展:(空格选择,回车确认)',
19
+ choices: [
20
+ {
21
+ value: 'code-abyss',
22
+ name: 'code-abyss — 邪修道统 · 56安全工程技能',
23
+ checked: true,
24
+ },
25
+ {
26
+ value: 'jshook-skill',
27
+ name: 'jshook-skill — JS逆向工程技能',
28
+ checked: true,
29
+ },
30
+ {
31
+ value: 'grok-search',
32
+ name: 'GrokSearch MCP — Grok搜索引擎',
33
+ checked: true,
34
+ },
35
+ ],
36
+ });
37
+ state.claudeExtensions = extensions;
38
+ console.log();
39
+ // 安装 code-abyss
40
+ if (extensions.includes('code-abyss')) {
41
+ const result = await installCodeAbyss('claude');
42
+ state.results.push(result);
43
+ }
44
+ // 安装 jshook-skill
45
+ if (extensions.includes('jshook-skill')) {
46
+ const result = await installJshookSkill();
47
+ state.results.push(result);
48
+ }
49
+ // 配置 GrokSearch
50
+ if (extensions.includes('grok-search')) {
51
+ console.log();
52
+ log.info('GrokSearch MCP 配置:');
53
+ const grokUrl = await input({
54
+ message: '输入 Grok API URL:',
55
+ default: 'https://api.x.ai/v1',
56
+ });
57
+ const grokKey = await password({
58
+ message: '输入 Grok API Key (XAI_API_KEY):',
59
+ mask: '*',
60
+ });
61
+ if (grokKey && grokKey.trim().length > 0) {
62
+ state.grokConfig = {
63
+ apiUrl: grokUrl.trim(),
64
+ apiKey: grokKey.trim(),
65
+ };
66
+ const result = await installGrokSearchForClaude(state.grokConfig);
67
+ state.results.push(result);
68
+ }
69
+ else {
70
+ log.warn('GrokSearch API Key 为空,跳过配置');
71
+ }
72
+ }
73
+ console.log();
74
+ }
75
+ //# sourceMappingURL=claude-setup.js.map
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 执行清理:备份 + 卸载 + 删除
3
+ */
4
+ export declare function performCleanup(): Promise<void>;
5
+ //# sourceMappingURL=cleanup.d.ts.map
@@ -0,0 +1,74 @@
1
+ /**
2
+ * 清理页 — 备份 + 卸载
3
+ */
4
+ import fs from 'node:fs';
5
+ import ora from 'ora';
6
+ import { getClaudeDir, getCodexDir } from '../utils/platform.js';
7
+ import { backupDirectory, removeDirectory } from '../utils/backup.js';
8
+ import { uninstallClaudeCode } from '../installers/claude-code.js';
9
+ import { uninstallCodexCli } from '../installers/codex-cli.js';
10
+ import { log } from '../utils/logger.js';
11
+ /**
12
+ * 执行清理:备份 + 卸载 + 删除
13
+ */
14
+ export async function performCleanup() {
15
+ log.section('🧹 清理环境');
16
+ const claudeDir = getClaudeDir();
17
+ const codexDir = getCodexDir();
18
+ // 1. 备份
19
+ const spinner = ora('Backing up existing configurations...').start();
20
+ if (fs.existsSync(claudeDir)) {
21
+ const backupPath = backupDirectory(claudeDir);
22
+ if (backupPath) {
23
+ log.success(`~/.claude backed up to ${backupPath}`);
24
+ }
25
+ else {
26
+ log.warn('Failed to backup ~/.claude');
27
+ }
28
+ }
29
+ else {
30
+ log.dim('~/.claude not found, skip backup');
31
+ }
32
+ if (fs.existsSync(codexDir)) {
33
+ const backupPath = backupDirectory(codexDir);
34
+ if (backupPath) {
35
+ log.success(`~/.codex backed up to ${backupPath}`);
36
+ }
37
+ else {
38
+ log.warn('Failed to backup ~/.codex');
39
+ }
40
+ }
41
+ else {
42
+ log.dim('~/.codex not found, skip backup');
43
+ }
44
+ spinner.succeed('Backup complete');
45
+ // 2. 卸载全局包
46
+ const uninstallSpinner = ora('Uninstalling existing CLI tools...').start();
47
+ uninstallClaudeCode();
48
+ uninstallCodexCli();
49
+ uninstallSpinner.succeed('Existing CLI tools uninstalled');
50
+ // 3. 删除配置目录
51
+ const cleanSpinner = ora('Cleaning configuration directories...').start();
52
+ if (fs.existsSync(claudeDir)) {
53
+ removeDirectory(claudeDir);
54
+ log.dim('~/.claude removed');
55
+ }
56
+ if (fs.existsSync(codexDir)) {
57
+ removeDirectory(codexDir);
58
+ log.dim('~/.codex removed');
59
+ }
60
+ // 4. 清理当前项目目录下的 .claude / .codex
61
+ const projectClaude = '.claude';
62
+ const projectCodex = '.codex';
63
+ if (fs.existsSync(projectClaude)) {
64
+ removeDirectory(projectClaude);
65
+ log.dim('Project .claude/ removed');
66
+ }
67
+ if (fs.existsSync(projectCodex)) {
68
+ removeDirectory(projectCodex);
69
+ log.dim('Project .codex/ removed');
70
+ }
71
+ cleanSpinner.succeed('Environment cleaned');
72
+ console.log();
73
+ }
74
+ //# sourceMappingURL=cleanup.js.map
@@ -0,0 +1,6 @@
1
+ import type { SetupState } from '../types/index.js';
2
+ /**
3
+ * Codex CLI 扩展选择与安装
4
+ */
5
+ export declare function codexSetupPage(state: SetupState): Promise<void>;
6
+ //# sourceMappingURL=codex-setup.d.ts.map
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Page 3 — Codex CLI 插件/技能/MCP 选择与安装
3
+ */
4
+ import { checkbox, input, password } from '@inquirer/prompts';
5
+ import { installCodeAbyss } from '../installers/code-abyss.js';
6
+ import { installGrokSearchForCodex } from '../installers/grok-search.js';
7
+ import { installHelloAgents } from '../installers/helloagents.js';
8
+ import { log } from '../utils/logger.js';
9
+ /**
10
+ * Codex CLI 扩展选择与安装
11
+ */
12
+ export async function codexSetupPage(state) {
13
+ if (!state.installCodex)
14
+ return;
15
+ log.section('🔌 Codex CLI 扩展配置');
16
+ // 选择扩展
17
+ const extensions = await checkbox({
18
+ message: '选择要安装的 Codex 扩展:(空格选择,回车确认)',
19
+ choices: [
20
+ {
21
+ value: 'code-abyss',
22
+ name: 'code-abyss — 邪修道统 · 安全工程技能',
23
+ checked: true,
24
+ },
25
+ {
26
+ value: 'grok-search',
27
+ name: 'GrokSearch MCP — Grok搜索引擎',
28
+ checked: true,
29
+ },
30
+ {
31
+ value: 'helloagents',
32
+ name: 'helloagents — 自主智能Agent伙伴',
33
+ checked: true,
34
+ },
35
+ ],
36
+ });
37
+ state.codexExtensions = extensions;
38
+ console.log();
39
+ // 安装 code-abyss(Codex 版)
40
+ if (extensions.includes('code-abyss')) {
41
+ // 检查是否已在 Claude Code 安装过
42
+ const alreadyInstalled = state.claudeExtensions.includes('code-abyss');
43
+ if (alreadyInstalled) {
44
+ log.info('code-abyss 已在 Claude Code 中安装,Codex 将共享配置');
45
+ state.results.push({ name: 'code-abyss (Codex)', success: true });
46
+ }
47
+ else {
48
+ const result = await installCodeAbyss('codex');
49
+ result.name = 'code-abyss (Codex)';
50
+ state.results.push(result);
51
+ }
52
+ }
53
+ // 配置 GrokSearch
54
+ if (extensions.includes('grok-search')) {
55
+ if (state.grokConfig) {
56
+ // 复用 Page 2 的配置
57
+ log.success('GrokSearch 将复用 Claude Code 的 API 配置');
58
+ const result = await installGrokSearchForCodex(state.grokConfig);
59
+ state.results.push(result);
60
+ }
61
+ else {
62
+ // 需要新输入
63
+ console.log();
64
+ log.info('GrokSearch MCP 配置:');
65
+ const grokUrl = await input({
66
+ message: '输入 Grok API URL:',
67
+ default: 'https://api.x.ai/v1',
68
+ });
69
+ const grokKey = await password({
70
+ message: '输入 Grok API Key (XAI_API_KEY):',
71
+ mask: '*',
72
+ });
73
+ if (grokKey && grokKey.trim().length > 0) {
74
+ state.grokConfig = {
75
+ apiUrl: grokUrl.trim(),
76
+ apiKey: grokKey.trim(),
77
+ };
78
+ const result = await installGrokSearchForCodex(state.grokConfig);
79
+ state.results.push(result);
80
+ }
81
+ else {
82
+ log.warn('GrokSearch API Key 为空,跳过配置');
83
+ }
84
+ }
85
+ }
86
+ // 安装 helloagents
87
+ if (extensions.includes('helloagents')) {
88
+ const result = await installHelloAgents();
89
+ state.results.push(result);
90
+ }
91
+ console.log();
92
+ }
93
+ //# sourceMappingURL=codex-setup.js.map
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 显示欢迎页并确认继续
3
+ * @returns true 继续, false 取消
4
+ */
5
+ export declare function showWelcomePage(): Promise<boolean>;
6
+ //# sourceMappingURL=welcome.d.ts.map
@@ -0,0 +1,35 @@
1
+ /**
2
+ * 欢迎页 — ASCII art + 版本 + 免责声明
3
+ */
4
+ import { confirm } from '@inquirer/prompts';
5
+ import chalk from 'chalk';
6
+ import { generateBanner } from '../utils/banner.js';
7
+ import { log } from '../utils/logger.js';
8
+ /**
9
+ * 显示欢迎页并确认继续
10
+ * @returns true 继续, false 取消
11
+ */
12
+ export async function showWelcomePage() {
13
+ // ASCII Banner
14
+ console.log(generateBanner());
15
+ console.log(chalk.dim(' Auto Setup Wizard v1.0.0'));
16
+ console.log(chalk.dim(' 一键配置 Claude Code CLI / Codex CLI'));
17
+ console.log();
18
+ // 免责声明
19
+ log.section('⚠️ 重要提示');
20
+ console.log(chalk.yellow(' 本工具将执行以下操作:'));
21
+ console.log();
22
+ console.log(' 1. 备份现有 ~/.claude 和 ~/.codex 目录到 .bak');
23
+ console.log(' 2. 卸载已安装的 @anthropic-ai/claude-code 和 @openai/codex');
24
+ console.log(' 3. 删除 ~/.claude 和 ~/.codex 目录');
25
+ console.log(' 4. 重新安装并配置所选工具');
26
+ console.log();
27
+ console.log(chalk.dim(' 备份将保留在 .bak 目录中,可随时恢复。'));
28
+ console.log();
29
+ const proceed = await confirm({
30
+ message: '是否继续?',
31
+ default: true,
32
+ });
33
+ return proceed;
34
+ }
35
+ //# sourceMappingURL=welcome.js.map
@@ -0,0 +1,58 @@
1
+ /**
2
+ * TicketPro Auto Setup — Type Definitions
3
+ */
4
+ /** 用户选择的工具 */
5
+ export type ToolChoice = 'both' | 'claude-only' | 'codex-only';
6
+ /** Claude Code 扩展选项 */
7
+ export type ClaudeExtension = 'code-abyss' | 'jshook-skill' | 'grok-search';
8
+ /** Codex 扩展选项 */
9
+ export type CodexExtension = 'code-abyss' | 'grok-search' | 'helloagents';
10
+ /** 安装步骤结果 */
11
+ export interface StepResult {
12
+ name: string;
13
+ success: boolean;
14
+ version?: string;
15
+ error?: string;
16
+ }
17
+ /** GrokSearch 配置 */
18
+ export interface GrokConfig {
19
+ apiUrl: string;
20
+ apiKey: string;
21
+ }
22
+ /** 全局状态 — 贯穿整个安装流程 */
23
+ export interface SetupState {
24
+ /** 选择的工具 */
25
+ toolChoice: ToolChoice;
26
+ /** 中转站 API Key */
27
+ apiKey: string;
28
+ /** Claude Code 基础 URL */
29
+ claudeBaseUrl: string;
30
+ /** Codex 基础 URL */
31
+ codexBaseUrl: string;
32
+ /** 是否安装 Claude Code */
33
+ installClaude: boolean;
34
+ /** 是否安装 Codex */
35
+ installCodex: boolean;
36
+ /** Claude Code 扩展选择 */
37
+ claudeExtensions: ClaudeExtension[];
38
+ /** Codex 扩展选择 */
39
+ codexExtensions: CodexExtension[];
40
+ /** GrokSearch 配置(复用) */
41
+ grokConfig?: GrokConfig;
42
+ /** 各步骤结果 */
43
+ results: StepResult[];
44
+ }
45
+ /** 平台信息 */
46
+ export interface PlatformInfo {
47
+ isWindows: boolean;
48
+ isMac: boolean;
49
+ isLinux: boolean;
50
+ homeDir: string;
51
+ shell: 'powershell' | 'bash' | 'zsh' | 'sh';
52
+ npmCmd: string;
53
+ npxCmd: string;
54
+ gitCmd: string;
55
+ }
56
+ /** 创建默认状态 */
57
+ export declare function createDefaultState(): SetupState;
58
+ //# sourceMappingURL=index.d.ts.map