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,19 @@
1
+ /**
2
+ * TicketPro Auto Setup — Type Definitions
3
+ */
4
+ /** 创建默认状态 */
5
+ export function createDefaultState() {
6
+ return {
7
+ toolChoice: 'both',
8
+ apiKey: '',
9
+ claudeBaseUrl: 'https://api.ticketpro.cc',
10
+ codexBaseUrl: 'https://api.ticketpro.cc/v1',
11
+ installClaude: true,
12
+ installCodex: true,
13
+ claudeExtensions: [],
14
+ codexExtensions: [],
15
+ grokConfig: undefined,
16
+ results: [],
17
+ };
18
+ }
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 备份目录到 .bak(若已存在 .bak 则追加日期)
3
+ */
4
+ export declare function backupDirectory(dirPath: string): string | null;
5
+ /**
6
+ * 删除目录
7
+ */
8
+ export declare function removeDirectory(dirPath: string): boolean;
9
+ //# sourceMappingURL=backup.d.ts.map
@@ -0,0 +1,79 @@
1
+ /**
2
+ * 备份工具 — 备份/恢复目录
3
+ */
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import { execCommand } from './shell.js';
7
+ import { getPlatform } from './platform.js';
8
+ /**
9
+ * 备份目录到 .bak(若已存在 .bak 则追加日期)
10
+ */
11
+ export function backupDirectory(dirPath) {
12
+ if (!fs.existsSync(dirPath)) {
13
+ return null;
14
+ }
15
+ let backupPath = dirPath + '.bak';
16
+ // 若 .bak 已存在,追加日期
17
+ if (fs.existsSync(backupPath)) {
18
+ const date = new Date().toISOString().slice(0, 10).replace(/-/g, '');
19
+ backupPath = `${dirPath}.bak.${date}`;
20
+ // 若日期备份也存在,追加时间戳
21
+ if (fs.existsSync(backupPath)) {
22
+ backupPath = `${dirPath}.bak.${Date.now()}`;
23
+ }
24
+ }
25
+ const { isWindows } = getPlatform();
26
+ const cmd = isWindows
27
+ ? `xcopy "${dirPath}" "${backupPath}" /E /I /H /Y /Q`
28
+ : `cp -r "${dirPath}" "${backupPath}"`;
29
+ const result = execCommand(cmd);
30
+ if (result.success) {
31
+ return backupPath;
32
+ }
33
+ // fallback: 使用 Node.js fs
34
+ try {
35
+ copyDirRecursive(dirPath, backupPath);
36
+ return backupPath;
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ }
42
+ /**
43
+ * 删除目录
44
+ */
45
+ export function removeDirectory(dirPath) {
46
+ if (!fs.existsSync(dirPath)) {
47
+ return true;
48
+ }
49
+ try {
50
+ fs.rmSync(dirPath, { recursive: true, force: true });
51
+ return true;
52
+ }
53
+ catch {
54
+ // fallback: 使用 shell 命令
55
+ const { isWindows } = getPlatform();
56
+ const cmd = isWindows
57
+ ? `rmdir /S /Q "${dirPath}"`
58
+ : `rm -rf "${dirPath}"`;
59
+ return execCommand(cmd).success;
60
+ }
61
+ }
62
+ /**
63
+ * 递归复制目录(纯 Node.js)
64
+ */
65
+ function copyDirRecursive(src, dest) {
66
+ fs.mkdirSync(dest, { recursive: true });
67
+ const entries = fs.readdirSync(src, { withFileTypes: true });
68
+ for (const entry of entries) {
69
+ const srcPath = path.join(src, entry.name);
70
+ const destPath = path.join(dest, entry.name);
71
+ if (entry.isDirectory()) {
72
+ copyDirRecursive(srcPath, destPath);
73
+ }
74
+ else {
75
+ fs.copyFileSync(srcPath, destPath);
76
+ }
77
+ }
78
+ }
79
+ //# sourceMappingURL=backup.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 生成 TicketPro ASCII banner
3
+ */
4
+ export declare function generateBanner(): string;
5
+ /**
6
+ * 生成完成时的 banner
7
+ */
8
+ export declare function generateCompleteBanner(): string;
9
+ //# sourceMappingURL=banner.d.ts.map
@@ -0,0 +1,41 @@
1
+ /**
2
+ * ASCII Art 生成 — figlet 封装
3
+ */
4
+ import figlet from 'figlet';
5
+ import chalk from 'chalk';
6
+ /**
7
+ * 生成 TicketPro ASCII banner
8
+ */
9
+ export function generateBanner() {
10
+ try {
11
+ const art = figlet.textSync('TicketPro', {
12
+ font: 'Standard',
13
+ horizontalLayout: 'default',
14
+ verticalLayout: 'default',
15
+ });
16
+ return chalk.cyan(art);
17
+ }
18
+ catch {
19
+ // fallback 如果 figlet 失败
20
+ return chalk.cyan(`
21
+ _____ _ _ _ ____
22
+ |_ _(_) ___| | _____| |_| _ \\ _ __ ___
23
+ | | | |/ __| |/ / _ \\ __| |_) | '__/ _ \\
24
+ | | | | (__| < __/ |_| __/| | | (_) |
25
+ |_| |_|\\___|_|\\_\\___|\\__|_| |_| \\___/
26
+ `);
27
+ }
28
+ }
29
+ /**
30
+ * 生成完成时的 banner
31
+ */
32
+ export function generateCompleteBanner() {
33
+ return chalk.green(`
34
+ ╔═══════════════════════════════════════════╗
35
+ ║ ║
36
+ ║ ✅ Setup Complete! ║
37
+ ║ ║
38
+ ╚═══════════════════════════════════════════╝
39
+ `);
40
+ }
41
+ //# sourceMappingURL=banner.js.map
@@ -0,0 +1,16 @@
1
+ export declare const log: {
2
+ info: (msg: string) => void;
3
+ success: (msg: string) => void;
4
+ warn: (msg: string) => void;
5
+ error: (msg: string) => void;
6
+ step: (msg: string) => void;
7
+ dim: (msg: string) => void;
8
+ blank: () => void;
9
+ /** 带标题的分割线 */
10
+ section: (title: string) => void;
11
+ /** 带框的消息 */
12
+ box: (lines: string[]) => void;
13
+ /** 键值对显示 */
14
+ kv: (key: string, value: string) => void;
15
+ };
16
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1,40 @@
1
+ /**
2
+ * 日志 + chalk 封装
3
+ */
4
+ import chalk from 'chalk';
5
+ export const log = {
6
+ info: (msg) => console.log(chalk.cyan(' ℹ ') + msg),
7
+ success: (msg) => console.log(chalk.green(' ✓ ') + msg),
8
+ warn: (msg) => console.log(chalk.yellow(' ⚠ ') + msg),
9
+ error: (msg) => console.log(chalk.red(' ✗ ') + msg),
10
+ step: (msg) => console.log(chalk.blue(' → ') + msg),
11
+ dim: (msg) => console.log(chalk.dim(' ' + msg)),
12
+ blank: () => console.log(),
13
+ /** 带标题的分割线 */
14
+ section: (title) => {
15
+ console.log();
16
+ console.log(chalk.bold.white(` ── ${title} ${'─'.repeat(Math.max(0, 50 - title.length))}`));
17
+ console.log();
18
+ },
19
+ /** 带框的消息 */
20
+ box: (lines) => {
21
+ const maxLen = Math.max(...lines.map(l => stripAnsi(l).length));
22
+ const border = '─'.repeat(maxLen + 4);
23
+ console.log(chalk.dim(` ┌${border}┐`));
24
+ for (const line of lines) {
25
+ const pad = ' '.repeat(Math.max(0, maxLen - stripAnsi(line).length));
26
+ console.log(chalk.dim(' │') + ` ${line}${pad} ` + chalk.dim('│'));
27
+ }
28
+ console.log(chalk.dim(` └${border}┘`));
29
+ },
30
+ /** 键值对显示 */
31
+ kv: (key, value) => {
32
+ console.log(chalk.dim(' ') + chalk.gray(key + ': ') + chalk.white(value));
33
+ },
34
+ };
35
+ /** 简易去除 ANSI 转义码(用于计算显示宽度) */
36
+ function stripAnsi(str) {
37
+ // eslint-disable-next-line no-control-regex
38
+ return str.replace(/\x1B\[[0-9;]*m/g, '');
39
+ }
40
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1,9 @@
1
+ import type { PlatformInfo } from '../types/index.js';
2
+ export declare function getPlatform(): PlatformInfo;
3
+ /** 获取 ~/.claude 路径 */
4
+ export declare function getClaudeDir(): string;
5
+ /** 获取 ~/.codex 路径 */
6
+ export declare function getCodexDir(): string;
7
+ /** 获取 shell profile 文件路径 */
8
+ export declare function getShellProfile(): string;
9
+ //# sourceMappingURL=platform.d.ts.map
@@ -0,0 +1,55 @@
1
+ /**
2
+ * 跨平台工具 — 路径、shell、权限检测
3
+ */
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ let _platform;
7
+ export function getPlatform() {
8
+ if (_platform)
9
+ return _platform;
10
+ const isWindows = process.platform === 'win32';
11
+ const isMac = process.platform === 'darwin';
12
+ const isLinux = process.platform === 'linux';
13
+ const homeDir = os.homedir();
14
+ // 检测默认 shell
15
+ let shell = 'bash';
16
+ if (isWindows) {
17
+ shell = 'powershell';
18
+ }
19
+ else {
20
+ const envShell = process.env.SHELL ?? '';
21
+ if (envShell.includes('zsh'))
22
+ shell = 'zsh';
23
+ else if (envShell.includes('bash'))
24
+ shell = 'bash';
25
+ else
26
+ shell = 'sh';
27
+ }
28
+ // Windows 下 npm/npx 需要 .cmd 后缀
29
+ const npmCmd = isWindows ? 'npm.cmd' : 'npm';
30
+ const npxCmd = isWindows ? 'npx.cmd' : 'npx';
31
+ const gitCmd = isWindows ? 'git.exe' : 'git';
32
+ _platform = { isWindows, isMac, isLinux, homeDir, shell, npmCmd, npxCmd, gitCmd };
33
+ return _platform;
34
+ }
35
+ /** 获取 ~/.claude 路径 */
36
+ export function getClaudeDir() {
37
+ return path.join(getPlatform().homeDir, '.claude');
38
+ }
39
+ /** 获取 ~/.codex 路径 */
40
+ export function getCodexDir() {
41
+ return path.join(getPlatform().homeDir, '.codex');
42
+ }
43
+ /** 获取 shell profile 文件路径 */
44
+ export function getShellProfile() {
45
+ const { homeDir, shell, isWindows } = getPlatform();
46
+ if (isWindows) {
47
+ return path.join(homeDir, 'Documents', 'WindowsPowerShell', 'Microsoft.PowerShell_profile.ps1');
48
+ }
49
+ switch (shell) {
50
+ case 'zsh': return path.join(homeDir, '.zshrc');
51
+ case 'bash': return path.join(homeDir, '.bashrc');
52
+ default: return path.join(homeDir, '.profile');
53
+ }
54
+ }
55
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1,27 @@
1
+ export interface ExecResult {
2
+ success: boolean;
3
+ stdout: string;
4
+ stderr: string;
5
+ code: number | null;
6
+ }
7
+ /**
8
+ * 同步执行命令,返回结构化结果
9
+ */
10
+ export declare function execCommand(command: string, options?: {
11
+ cwd?: string;
12
+ timeout?: number;
13
+ env?: Record<string, string>;
14
+ maxBuffer?: number;
15
+ }): ExecResult;
16
+ /**
17
+ * 检查命令是否可用
18
+ */
19
+ export declare function commandExists(cmd: string): boolean;
20
+ /**
21
+ * 异步执行命令(用于长耗时操作)
22
+ */
23
+ export declare function execAsync(command: string, options?: {
24
+ cwd?: string;
25
+ env?: Record<string, string>;
26
+ }): Promise<ExecResult>;
27
+ //# sourceMappingURL=shell.d.ts.map
@@ -0,0 +1,77 @@
1
+ /**
2
+ * 命令执行封装 — child_process 包装
3
+ */
4
+ import { execSync, spawn } from 'node:child_process';
5
+ import { getPlatform } from './platform.js';
6
+ /**
7
+ * 同步执行命令,返回结构化结果
8
+ */
9
+ export function execCommand(command, options) {
10
+ const { isWindows } = getPlatform();
11
+ const shellCmd = isWindows ? 'cmd.exe' : '/bin/bash';
12
+ const shellArg = isWindows ? '/c' : '-c';
13
+ try {
14
+ const stdout = execSync(command, {
15
+ cwd: options?.cwd,
16
+ timeout: options?.timeout ?? 120_000,
17
+ encoding: 'utf-8',
18
+ shell: isWindows ? 'cmd.exe' : '/bin/bash',
19
+ env: { ...process.env, ...options?.env },
20
+ stdio: ['pipe', 'pipe', 'pipe'],
21
+ maxBuffer: options?.maxBuffer ?? 10 * 1024 * 1024, // 10MB default
22
+ });
23
+ return { success: true, stdout: stdout.trim(), stderr: '', code: 0 };
24
+ }
25
+ catch (err) {
26
+ return {
27
+ success: false,
28
+ stdout: (err.stdout ?? '').toString().trim(),
29
+ stderr: (err.stderr ?? '').toString().trim(),
30
+ code: err.status ?? 1,
31
+ };
32
+ }
33
+ }
34
+ /**
35
+ * 检查命令是否可用
36
+ */
37
+ export function commandExists(cmd) {
38
+ const { isWindows } = getPlatform();
39
+ const checkCmd = isWindows ? `where ${cmd}` : `command -v ${cmd}`;
40
+ return execCommand(checkCmd).success;
41
+ }
42
+ /**
43
+ * 异步执行命令(用于长耗时操作)
44
+ */
45
+ export function execAsync(command, options) {
46
+ return new Promise((resolve) => {
47
+ const { isWindows } = getPlatform();
48
+ const shell = isWindows ? 'cmd.exe' : '/bin/bash';
49
+ const shellArg = isWindows ? '/c' : '-c';
50
+ const child = spawn(shell, [shellArg, command], {
51
+ cwd: options?.cwd,
52
+ env: { ...process.env, ...options?.env },
53
+ stdio: ['pipe', 'pipe', 'pipe'],
54
+ });
55
+ let stdout = '';
56
+ let stderr = '';
57
+ child.stdout.on('data', (data) => { stdout += data.toString(); });
58
+ child.stderr.on('data', (data) => { stderr += data.toString(); });
59
+ child.on('close', (code) => {
60
+ resolve({
61
+ success: code === 0,
62
+ stdout: stdout.trim(),
63
+ stderr: stderr.trim(),
64
+ code,
65
+ });
66
+ });
67
+ child.on('error', (err) => {
68
+ resolve({
69
+ success: false,
70
+ stdout: '',
71
+ stderr: err.message,
72
+ code: 1,
73
+ });
74
+ });
75
+ });
76
+ }
77
+ //# sourceMappingURL=shell.js.map
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "ticketpro-auto-setup",
3
+ "version": "1.0.0",
4
+ "description": "TicketPro Auto Setup Wizard — 一键配置 Claude Code CLI / Codex CLI",
5
+ "type": "module",
6
+ "bin": {
7
+ "ticketpro-auto-setup": "./dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist/**/*.js",
11
+ "dist/**/*.d.ts"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "start": "node dist/index.js",
16
+ "dev": "tsc --watch",
17
+ "prepublishOnly": "tsc"
18
+ },
19
+ "engines": {
20
+ "node": ">=18.0.0"
21
+ },
22
+ "keywords": [
23
+ "claude-code",
24
+ "codex-cli",
25
+ "auto-setup",
26
+ "ticketpro",
27
+ "anthropic",
28
+ "openai",
29
+ "mcp",
30
+ "code-abyss"
31
+ ],
32
+ "author": "TicketPro",
33
+ "license": "MIT",
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "https://github.com/ticketpro/ticketpro-auto-setup"
37
+ },
38
+ "dependencies": {
39
+ "@inquirer/prompts": "^7.0.0",
40
+ "chalk": "^5.3.0",
41
+ "figlet": "^1.8.0",
42
+ "ora": "^8.1.0"
43
+ },
44
+ "devDependencies": {
45
+ "@types/figlet": "^1.7.0",
46
+ "@types/node": "^22.0.0",
47
+ "typescript": "^5.7.0"
48
+ }
49
+ }