@alipay/alipay-aipay 1.0.0 → 1.0.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 (117) hide show
  1. package/bin/alipay-aipay.js +6 -0
  2. package/dist/commands/install.d.ts +11 -0
  3. package/dist/commands/install.d.ts.map +1 -0
  4. package/dist/commands/install.js +182 -0
  5. package/dist/commands/install.js.map +1 -0
  6. package/dist/commands/prepare-tools.d.ts +5 -0
  7. package/dist/commands/prepare-tools.d.ts.map +1 -0
  8. package/dist/commands/prepare-tools.js +29 -0
  9. package/dist/commands/prepare-tools.js.map +1 -0
  10. package/dist/commands/uninstall.d.ts +10 -0
  11. package/dist/commands/uninstall.d.ts.map +1 -0
  12. package/dist/commands/uninstall.js +82 -0
  13. package/dist/commands/uninstall.js.map +1 -0
  14. package/dist/commands/update.d.ts +10 -0
  15. package/dist/commands/update.d.ts.map +1 -0
  16. package/dist/commands/update.js +155 -0
  17. package/dist/commands/update.js.map +1 -0
  18. package/dist/index.d.ts +2 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +65 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/types.d.ts +43 -0
  23. package/dist/types.d.ts.map +1 -0
  24. package/dist/types.js +2 -0
  25. package/dist/types.js.map +1 -0
  26. package/dist/utils/alipay-cli.d.ts +15 -0
  27. package/dist/utils/alipay-cli.d.ts.map +1 -0
  28. package/dist/utils/alipay-cli.js +221 -0
  29. package/dist/utils/alipay-cli.js.map +1 -0
  30. package/dist/utils/config.d.ts +48 -0
  31. package/dist/utils/config.d.ts.map +1 -0
  32. package/dist/utils/config.js +207 -0
  33. package/dist/utils/config.js.map +1 -0
  34. package/dist/utils/file.d.ts +55 -0
  35. package/dist/utils/file.d.ts.map +1 -0
  36. package/dist/utils/file.js +154 -0
  37. package/dist/utils/file.js.map +1 -0
  38. package/dist/utils/gpg.d.ts +14 -0
  39. package/dist/utils/gpg.d.ts.map +1 -0
  40. package/dist/utils/gpg.js +247 -0
  41. package/dist/utils/gpg.js.map +1 -0
  42. package/dist/utils/jq.d.ts +14 -0
  43. package/dist/utils/jq.d.ts.map +1 -0
  44. package/dist/utils/jq.js +221 -0
  45. package/dist/utils/jq.js.map +1 -0
  46. package/dist/utils/npm.d.ts +17 -0
  47. package/dist/utils/npm.d.ts.map +1 -0
  48. package/dist/utils/npm.js +42 -0
  49. package/dist/utils/npm.js.map +1 -0
  50. package/dist/utils/shell.d.ts +11 -0
  51. package/dist/utils/shell.d.ts.map +1 -0
  52. package/dist/utils/shell.js +54 -0
  53. package/dist/utils/shell.js.map +1 -0
  54. package/package.json +48 -7
  55. package/skill/SKILL.md +118 -0
  56. package/skill/references/integration/flow.md +487 -0
  57. package/skill/references/integration/modules/alipay-sdk-reminder.md +256 -0
  58. package/skill/references/integration/modules/checklist.md +122 -0
  59. package/skill/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +68 -0
  60. package/skill/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +77 -0
  61. package/skill/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +74 -0
  62. package/skill/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +73 -0
  63. package/skill/references/integration/modules/code-examples/csharp/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +58 -0
  64. package/skill/references/integration/modules/code-examples/csharp/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +128 -0
  65. package/skill/references/integration/modules/code-examples/csharp/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.cs +500 -0
  66. package/skill/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +72 -0
  67. package/skill/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +80 -0
  68. package/skill/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +78 -0
  69. package/skill/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +77 -0
  70. package/skill/references/integration/modules/code-examples/java/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +66 -0
  71. package/skill/references/integration/modules/code-examples/java/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +135 -0
  72. package/skill/references/integration/modules/code-examples/java/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemoController.java +610 -0
  73. package/skill/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +51 -0
  74. package/skill/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +57 -0
  75. package/skill/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +55 -0
  76. package/skill/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +54 -0
  77. package/skill/references/integration/modules/code-examples/nodejs/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +77 -0
  78. package/skill/references/integration/modules/code-examples/nodejs/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +65 -0
  79. package/skill/references/integration/modules/code-examples/nodejs/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.js +461 -0
  80. package/skill/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +59 -0
  81. package/skill/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +67 -0
  82. package/skill/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +66 -0
  83. package/skill/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +65 -0
  84. package/skill/references/integration/modules/code-examples/php/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +56 -0
  85. package/skill/references/integration/modules/code-examples/php/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +107 -0
  86. package/skill/references/integration/modules/code-examples/php/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.php +444 -0
  87. package/skill/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +57 -0
  88. package/skill/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +65 -0
  89. package/skill/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +63 -0
  90. package/skill/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +62 -0
  91. package/skill/references/integration/modules/code-examples/python/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +48 -0
  92. package/skill/references/integration/modules/code-examples/python/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +43 -0
  93. package/skill/references/integration/modules/code-examples/python/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.py +465 -0
  94. package/skill/references/integration/modules/interface-guide.md +90 -0
  95. package/skill/references/integration/modules/product-decision.md +90 -0
  96. package/skill/references/integration/modules/sandbox/a2m-sandbox-test.md +270 -0
  97. package/skill/references/integration/modules/sandbox/alipay-sandbox-tool.md +133 -0
  98. package/skill/references/integration/modules/sandbox/sandbox-setup-guide.md +218 -0
  99. package/skill/references/integration/modules/scripts/local_402_sandbox_pay.py +659 -0
  100. package/skill/references/normal/alipay-cli-env.md +214 -0
  101. package/skill/references/normal/rejection-guide.md +37 -0
  102. package/skill/references/normal/scripts/common.sh +32 -0
  103. package/skill/references/normal/scripts/detect_dev_tool.sh +46 -0
  104. package/skill/references/onboarding/flow.md +573 -0
  105. package/skill/references/onboarding/modules/app-release.md +415 -0
  106. package/skill/references/onboarding/modules/authorization.md +269 -0
  107. package/skill/references/onboarding/modules/error-handling.md +251 -0
  108. package/skill/references/onboarding/modules/mcc-reference.md +209 -0
  109. package/skill/references/onboarding/modules/product-sign.md +304 -0
  110. package/skill/references/onboarding/modules/scripts/app.sh +705 -0
  111. package/skill/references/onboarding/modules/scripts/ar_sign_apply.sh +248 -0
  112. package/skill/references/onboarding/modules/scripts/auth.sh +505 -0
  113. package/skill/references/onboarding/modules/scripts/error_handler.sh +452 -0
  114. package/skill/references/onboarding/modules/scripts/query_sign_status.sh +146 -0
  115. package/skill/references/onboarding/modules/scripts/service.sh +267 -0
  116. package/skill/references/onboarding/modules/scripts/upload_screenshots.sh +152 -0
  117. package/skill/references/onboarding/modules/service-registration.md +294 -0
@@ -0,0 +1,154 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import { SKILL_NAME, SKILL_DIR } from './config.js';
4
+ /**
5
+ * 检查目录是否存在
6
+ */
7
+ export async function dirExists(dir) {
8
+ try {
9
+ const stat = await fs.stat(dir);
10
+ return stat.isDirectory();
11
+ }
12
+ catch {
13
+ return false;
14
+ }
15
+ }
16
+ /**
17
+ * 确保目录存在
18
+ */
19
+ export async function ensureDir(dir) {
20
+ if (!(await dirExists(dir))) {
21
+ await fs.mkdir(dir, { recursive: true });
22
+ }
23
+ }
24
+ /**
25
+ * 递归复制目录(保留 .sh 文件执行权限)
26
+ */
27
+ export async function copyDirWithPerms(src, dest) {
28
+ await ensureDir(dest);
29
+ const entries = await fs.readdir(src, { withFileTypes: true });
30
+ for (const entry of entries) {
31
+ const srcPath = path.join(src, entry.name);
32
+ const destPath = path.join(dest, entry.name);
33
+ if (entry.isDirectory()) {
34
+ await copyDirWithPerms(srcPath, destPath);
35
+ }
36
+ else {
37
+ await fs.copyFile(srcPath, destPath);
38
+ // 保留 .sh 文件的执行权限
39
+ if (entry.name.endsWith('.sh')) {
40
+ await fs.chmod(destPath, 0o755);
41
+ }
42
+ }
43
+ }
44
+ }
45
+ /**
46
+ * 递归复制目录(通用,不处理权限)
47
+ */
48
+ export async function copyDir(src, dest) {
49
+ await ensureDir(dest);
50
+ const entries = await fs.readdir(src, { withFileTypes: true });
51
+ for (const entry of entries) {
52
+ const srcPath = path.join(src, entry.name);
53
+ const destPath = path.join(dest, entry.name);
54
+ if (entry.isDirectory()) {
55
+ await copyDir(srcPath, destPath);
56
+ }
57
+ else {
58
+ await fs.copyFile(srcPath, destPath);
59
+ }
60
+ }
61
+ }
62
+ /**
63
+ * 递归删除目录
64
+ */
65
+ export async function removeDir(dir) {
66
+ try {
67
+ await fs.rm(dir, { recursive: true, force: true });
68
+ }
69
+ catch (error) {
70
+ // 忽略不存在的目录
71
+ if (error.code !== 'ENOENT') {
72
+ throw error;
73
+ }
74
+ }
75
+ }
76
+ /**
77
+ * 删除文件
78
+ */
79
+ export async function removeFile(filePath) {
80
+ try {
81
+ await fs.unlink(filePath);
82
+ }
83
+ catch (error) {
84
+ if (error.code !== 'ENOENT') {
85
+ throw error;
86
+ }
87
+ }
88
+ }
89
+ /**
90
+ * 读取版本记录文件
91
+ */
92
+ export async function readVersionFile(versionFilePath) {
93
+ try {
94
+ const content = await fs.readFile(versionFilePath, 'utf-8');
95
+ return JSON.parse(content);
96
+ }
97
+ catch {
98
+ return null;
99
+ }
100
+ }
101
+ /**
102
+ * 读取安装记录。兼容旧版本曾写入 skill 目录内的隐藏记录文件。
103
+ */
104
+ export async function readVersionRecord(ctx) {
105
+ return (await readVersionFile(ctx.versionFile)) ?? (await readVersionFile(ctx.legacyVersionFile));
106
+ }
107
+ /**
108
+ * 将旧版 skill 目录内的隐藏安装记录迁移到用户配置目录。
109
+ */
110
+ export async function migrateVersionRecord(ctx, record) {
111
+ await writeVersionFile(ctx.versionFile, record);
112
+ await removeFile(ctx.legacyVersionFile);
113
+ }
114
+ /**
115
+ * 写入版本记录文件
116
+ */
117
+ export async function writeVersionFile(versionFilePath, record) {
118
+ await ensureDir(path.dirname(versionFilePath));
119
+ await fs.writeFile(versionFilePath, JSON.stringify(record, null, 2), 'utf-8');
120
+ }
121
+ /**
122
+ * 安装 Skill 文件到目标目录
123
+ * 从包内 skill/ 目录复制 SKILL.md + references/ 到目标 skills 目录
124
+ */
125
+ export async function installSkillFiles(packageRoot, targetDir) {
126
+ const skillTargetDir = path.join(targetDir, SKILL_NAME);
127
+ const skillSourceDir = path.join(packageRoot, SKILL_DIR);
128
+ await removeDir(skillTargetDir);
129
+ await ensureDir(skillTargetDir);
130
+ // 复制 SKILL.md
131
+ await fs.copyFile(path.join(skillSourceDir, 'SKILL.md'), path.join(skillTargetDir, 'SKILL.md'));
132
+ // 复制 references/ 并保留 .sh 执行权限
133
+ await copyDirWithPerms(path.join(skillSourceDir, 'references'), path.join(skillTargetDir, 'references'));
134
+ }
135
+ /**
136
+ * 检查 skill 是否已安装
137
+ */
138
+ export async function isSkillInstalled(targetDir, skillName) {
139
+ const skillDir = path.join(targetDir, skillName);
140
+ return dirExists(skillDir);
141
+ }
142
+ /**
143
+ * 获取目标目录中已存在的 skills
144
+ */
145
+ export async function getExistingSkills(targetDir, skillNames) {
146
+ const existing = [];
147
+ for (const name of skillNames) {
148
+ if (await isSkillInstalled(targetDir, name)) {
149
+ existing.push(name);
150
+ }
151
+ }
152
+ return existing;
153
+ }
154
+ //# sourceMappingURL=file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/utils/file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { ToolCheckResult } from '../types.js';
2
+ /**
3
+ * 检查 GPG (gnupg) 是否已安装
4
+ */
5
+ export declare function checkGpg(): Promise<ToolCheckResult>;
6
+ /**
7
+ * 安装 GPG
8
+ */
9
+ export declare function installGpg(): Promise<boolean>;
10
+ /**
11
+ * 确保 GPG 已安装,未安装则自动安装
12
+ */
13
+ export declare function ensureGpg(): Promise<boolean>;
14
+ //# sourceMappingURL=gpg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gpg.d.ts","sourceRoot":"","sources":["../../src/utils/gpg.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAwBnD;;GAEG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,eAAe,CAAC,CAqBzD;AAoLD;;GAEG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAYnD;AAED;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAQlD"}
@@ -0,0 +1,247 @@
1
+ import { exec } from 'child_process';
2
+ import { promisify } from 'util';
3
+ import chalk from 'chalk';
4
+ import { execInteractive, isInteractive } from './shell.js';
5
+ const execAsync = promisify(exec);
6
+ /**
7
+ * 检测 Linux 包管理器
8
+ */
9
+ async function detectLinuxPackageManager() {
10
+ try {
11
+ await execAsync('which apt-get 2>/dev/null', { timeout: 3000 });
12
+ return 'apt';
13
+ }
14
+ catch {
15
+ // ignore
16
+ }
17
+ try {
18
+ await execAsync('which yum 2>/dev/null', { timeout: 3000 });
19
+ return 'yum';
20
+ }
21
+ catch {
22
+ // ignore
23
+ }
24
+ return 'unknown';
25
+ }
26
+ /**
27
+ * 检查 GPG (gnupg) 是否已安装
28
+ */
29
+ export async function checkGpg() {
30
+ try {
31
+ const { stdout } = await execAsync('gpg --version', { timeout: 5000 });
32
+ const versionLine = stdout.split('\n')[0];
33
+ const match = versionLine.match(/(\d+\.\d+\.\d+)/);
34
+ let gpgPath = '';
35
+ try {
36
+ const { stdout: whichOut } = await execAsync('which gpg', { timeout: 3000 });
37
+ gpgPath = whichOut.trim();
38
+ }
39
+ catch {
40
+ // ignore
41
+ }
42
+ return {
43
+ name: 'GPG',
44
+ installed: true,
45
+ version: match ? match[1] : 'unknown',
46
+ path: gpgPath || undefined,
47
+ };
48
+ }
49
+ catch {
50
+ return { name: 'GPG', installed: false };
51
+ }
52
+ }
53
+ // ============================================================
54
+ // 国内 Bottle 镜像源(只用于加速二进制包下载)
55
+ // formula 索引走 brew 默认的 formulae.brew.sh,不设 API_DOMAIN
56
+ // ============================================================
57
+ const BREW_BOTTLE_MIRRORS = [
58
+ { name: '清华', domain: 'https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles' },
59
+ { name: '阿里云', domain: 'https://mirrors.aliyun.com/homebrew-bottles' },
60
+ { name: '中科大', domain: 'https://mirrors.ustc.edu.cn/homebrew-bottles' },
61
+ ];
62
+ function formatErrorTail(error) {
63
+ const message = error instanceof Error ? error.message : String(error);
64
+ return message
65
+ .split('\n')
66
+ .map((line) => line.trimEnd())
67
+ .filter((line) => line.length > 0)
68
+ .slice(-6)
69
+ .join('\n');
70
+ }
71
+ /**
72
+ * 生成 brew install gnupg 命令
73
+ *
74
+ * 关键环境变量说明:
75
+ * - HOMEBREW_BOTTLE_DOMAIN: bottle(二进制包)下载走国内镜像,这是真正慢的部分
76
+ * - HOMEBREW_NO_AUTO_UPDATE=1: 跳过 brew update(慢,且 gnupg 是常用包不需要更新索引)
77
+ * - HOMEBREW_NO_INSTALL_CLEANUP=1: 安装后不自动清理旧版本
78
+ * - 不设 HOMEBREW_API_DOMAIN: 让 formula 索引走 brew 默认的 formulae.brew.sh
79
+ * (这个通常很快,且设国内镜像反而可能索引不完整)
80
+ * - 不设 HOMEBREW_NO_INSTALL_FROM_API: 必须允许从 API 读取 formula 信息
81
+ * (否则 brew 不知道 gnupg 怎么装)
82
+ */
83
+ function buildBrewInstallCommand(bottleDomain) {
84
+ return [
85
+ `export HOMEBREW_BOTTLE_DOMAIN="${bottleDomain}"`,
86
+ 'export HOMEBREW_NO_AUTO_UPDATE=1',
87
+ 'export HOMEBREW_NO_INSTALL_CLEANUP=1',
88
+ 'yes | brew install gnupg',
89
+ ].join(' && ');
90
+ }
91
+ // ============================================================
92
+ // macOS 安装 GPG
93
+ // ============================================================
94
+ /**
95
+ * macOS 安装 GPG:遍历镜像源自动重试
96
+ *
97
+ * 逻辑很简单:只换 bottle 下载源,其他 brew 行为保持默认。
98
+ * formula 索引下载(formulae.brew.sh)通常很快,不需要镜像。
99
+ * 真正慢的是 bottle 下载,用国内镜像加速即可。
100
+ */
101
+ async function installGpgMacos() {
102
+ // 检查 brew 是否可用
103
+ try {
104
+ await execAsync('which brew', { timeout: 3000 });
105
+ }
106
+ catch {
107
+ console.log(chalk.red(' ✗ 未检测到 Homebrew,无法自动安装 GPG'));
108
+ console.log(chalk.gray(' 请先安装 Homebrew:'));
109
+ console.log(chalk.cyan(' /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"'));
110
+ console.log(chalk.gray(' 或手动安装 GPG: brew install gnupg'));
111
+ return false;
112
+ }
113
+ console.log(chalk.cyan(' ⏳ 使用 Homebrew 安装 GPG...\n'));
114
+ // 依次尝试每个镜像源
115
+ for (let i = 0; i < BREW_BOTTLE_MIRRORS.length; i++) {
116
+ const mirror = BREW_BOTTLE_MIRRORS[i];
117
+ const command = buildBrewInstallCommand(mirror.domain);
118
+ if (isInteractive()) {
119
+ // TTY 环境,让用户看到 brew 的实时输出
120
+ }
121
+ else {
122
+ console.log(chalk.gray(` [${i + 1}/${BREW_BOTTLE_MIRRORS.length}] 使用${mirror.name}镜像源...`));
123
+ }
124
+ try {
125
+ await execInteractive(command, 120000); // 2 分钟超时:下不完说明源不通,立刻换下一个
126
+ // 验证安装
127
+ const verify = await checkGpg();
128
+ if (verify.installed) {
129
+ console.log(chalk.green(` ✓ GPG 安装成功 (${verify.version})`));
130
+ return true;
131
+ }
132
+ }
133
+ catch (error) {
134
+ if (!isInteractive()) {
135
+ const detail = formatErrorTail(error);
136
+ if (detail)
137
+ console.log(chalk.gray(` 失败原因: ${detail}\n`));
138
+ }
139
+ }
140
+ // 失败了,提示继续
141
+ if (i < BREW_BOTTLE_MIRRORS.length - 1) {
142
+ console.log(chalk.yellow(` ⚠ ${mirror.name}镜像源失败,尝试下一个...\n`));
143
+ }
144
+ }
145
+ // 所有镜像源都失败,最后一次尝试:不用任何镜像,裸装
146
+ console.log(chalk.gray(' [兜底] 不使用镜像源,直连安装...'));
147
+ try {
148
+ await execInteractive('export HOMEBREW_NO_AUTO_UPDATE=1 && export HOMEBREW_NO_INSTALL_CLEANUP=1 && yes | brew install gnupg', 180000);
149
+ const verify = await checkGpg();
150
+ if (verify.installed) {
151
+ console.log(chalk.green(` ✓ GPG 安装成功 (${verify.version})`));
152
+ return true;
153
+ }
154
+ }
155
+ catch (error) {
156
+ if (!isInteractive()) {
157
+ const detail = formatErrorTail(error);
158
+ if (detail)
159
+ console.log(chalk.gray(` 失败原因: ${detail}\n`));
160
+ }
161
+ }
162
+ console.log(chalk.red(' ✗ GPG 自动安装失败'));
163
+ console.log(chalk.gray(' 请手动在终端执行:'));
164
+ console.log(chalk.cyan(' brew install gnupg'));
165
+ console.log(chalk.gray(' 如果下载慢,设置 bottle 镜像后重试:'));
166
+ console.log(chalk.cyan(' export HOMEBREW_BOTTLE_DOMAIN="https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles"'));
167
+ console.log(chalk.cyan(' export HOMEBREW_NO_AUTO_UPDATE=1'));
168
+ console.log(chalk.cyan(' brew install gnupg'));
169
+ return false;
170
+ }
171
+ // ============================================================
172
+ // Linux 安装
173
+ // ============================================================
174
+ /**
175
+ * Linux 安装 GPG
176
+ */
177
+ async function installGpgLinux() {
178
+ const pkgManager = await detectLinuxPackageManager();
179
+ let command;
180
+ if (pkgManager === 'apt') {
181
+ command = 'sudo apt-get update -qq && sudo apt-get install -y gnupg';
182
+ }
183
+ else if (pkgManager === 'yum') {
184
+ command = 'sudo yum install -y gnupg2';
185
+ }
186
+ else {
187
+ console.log(chalk.red(' ✗ 无法识别的 Linux 包管理器'));
188
+ console.log(chalk.gray(' 请手动安装 GPG:'));
189
+ console.log(chalk.gray(' apt: sudo apt install -y gnupg'));
190
+ console.log(chalk.gray(' yum: sudo yum install -y gnupg2'));
191
+ return false;
192
+ }
193
+ console.log(chalk.cyan(' ⏳ 安装 GPG(可能需要输入 sudo 密码)...\n'));
194
+ try {
195
+ await execInteractive(command, 300000);
196
+ const verify = await checkGpg();
197
+ if (verify.installed) {
198
+ console.log(chalk.green(` ✓ GPG 安装成功 (${verify.version})`));
199
+ return true;
200
+ }
201
+ console.log(chalk.yellow(' ⚠ GPG 安装命令已执行,但验证失败'));
202
+ console.log(chalk.gray(' 请手动安装: sudo apt install -y gnupg'));
203
+ return false;
204
+ }
205
+ catch (error) {
206
+ console.log(chalk.red(' ✗ GPG 安装失败'));
207
+ const detail = formatErrorTail(error);
208
+ if (detail)
209
+ console.log(chalk.gray(` 失败原因: ${detail}`));
210
+ console.log(chalk.gray(' 请手动安装:'));
211
+ console.log(chalk.cyan(` ${pkgManager === 'apt' ? 'sudo apt install -y gnupg' : 'sudo yum install -y gnupg2'}`));
212
+ return false;
213
+ }
214
+ }
215
+ // ============================================================
216
+ // 主入口
217
+ // ============================================================
218
+ /**
219
+ * 安装 GPG
220
+ */
221
+ export async function installGpg() {
222
+ const platform = process.platform;
223
+ if (platform === 'darwin') {
224
+ return await installGpgMacos();
225
+ }
226
+ else if (platform === 'linux') {
227
+ return await installGpgLinux();
228
+ }
229
+ else {
230
+ console.log(chalk.red(` ✗ 不支持的操作系统: ${platform}`));
231
+ console.log(chalk.gray(' 请手动安装 GPG (gnupg)'));
232
+ return false;
233
+ }
234
+ }
235
+ /**
236
+ * 确保 GPG 已安装,未安装则自动安装
237
+ */
238
+ export async function ensureGpg() {
239
+ const check = await checkGpg();
240
+ if (check.installed) {
241
+ console.log(chalk.green(` ✓ GPG 已安装 (${check.version})`));
242
+ return true;
243
+ }
244
+ console.log(chalk.yellow(' ⚠ GPG 未安装,正在自动安装...'));
245
+ return await installGpg();
246
+ }
247
+ //# sourceMappingURL=gpg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gpg.js","sourceRoot":"","sources":["../../src/utils/gpg.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { ToolCheckResult } from '../types.js';
2
+ /**
3
+ * 检查 jq 是否已安装
4
+ */
5
+ export declare function checkJq(): Promise<ToolCheckResult>;
6
+ /**
7
+ * 安装 jq
8
+ */
9
+ export declare function installJq(): Promise<boolean>;
10
+ /**
11
+ * 确保 jq 已安装,未安装则自动安装
12
+ */
13
+ export declare function ensureJq(): Promise<boolean>;
14
+ //# sourceMappingURL=jq.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jq.d.ts","sourceRoot":"","sources":["../../src/utils/jq.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA+DnD;;GAEG;AACH,wBAAsB,OAAO,IAAI,OAAO,CAAC,eAAe,CAAC,CAoBxD;AAiHD;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAYlD;AAED;;GAEG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,CAQjD"}
@@ -0,0 +1,221 @@
1
+ import { exec } from 'child_process';
2
+ import { promisify } from 'util';
3
+ import chalk from 'chalk';
4
+ import { execInteractive } from './shell.js';
5
+ const execAsync = promisify(exec);
6
+ // ============================================================
7
+ // 国内 Bottle 镜像源(只用于加速二进制包下载)
8
+ // formula 索引走 brew 默认的 formulae.brew.sh,不设 API_DOMAIN
9
+ // ============================================================
10
+ const BREW_BOTTLE_MIRRORS = [
11
+ { name: '清华', domain: 'https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles' },
12
+ { name: '阿里云', domain: 'https://mirrors.aliyun.com/homebrew-bottles' },
13
+ { name: '中科大', domain: 'https://mirrors.ustc.edu.cn/homebrew-bottles' },
14
+ ];
15
+ function formatErrorTail(error) {
16
+ const message = error instanceof Error ? error.message : String(error);
17
+ return message
18
+ .split('\n')
19
+ .map((line) => line.trimEnd())
20
+ .filter((line) => line.length > 0)
21
+ .slice(-6)
22
+ .join('\n');
23
+ }
24
+ /**
25
+ * 生成 brew install jq 命令
26
+ *
27
+ * 关键环境变量说明:
28
+ * - HOMEBREW_BOTTLE_DOMAIN: bottle(二进制包)下载走国内镜像
29
+ * - HOMEBREW_NO_AUTO_UPDATE=1: 跳过 brew update
30
+ * - HOMEBREW_NO_INSTALL_CLEANUP=1: 安装后不自动清理旧版本
31
+ * - 不设 HOMEBREW_API_DOMAIN: 让 formula 索引走 brew 默认 API,避免镜像索引不完整
32
+ */
33
+ function buildBrewInstallCommand(bottleDomain) {
34
+ return [
35
+ `export HOMEBREW_BOTTLE_DOMAIN="${bottleDomain}"`,
36
+ 'export HOMEBREW_NO_AUTO_UPDATE=1',
37
+ 'export HOMEBREW_NO_INSTALL_CLEANUP=1',
38
+ 'yes | brew install jq',
39
+ ].join(' && ');
40
+ }
41
+ /**
42
+ * 检测 Linux 包管理器
43
+ */
44
+ async function detectLinuxPackageManager() {
45
+ try {
46
+ await execAsync('which apt-get 2>/dev/null', { timeout: 3000 });
47
+ return 'apt';
48
+ }
49
+ catch {
50
+ // ignore
51
+ }
52
+ try {
53
+ await execAsync('which yum 2>/dev/null', { timeout: 3000 });
54
+ return 'yum';
55
+ }
56
+ catch {
57
+ // ignore
58
+ }
59
+ return 'unknown';
60
+ }
61
+ /**
62
+ * 检查 jq 是否已安装
63
+ */
64
+ export async function checkJq() {
65
+ try {
66
+ const { stdout } = await execAsync('jq --version', { timeout: 5000 });
67
+ const version = stdout.trim().replace(/^jq-/, '');
68
+ let jqPath = '';
69
+ try {
70
+ const { stdout: whichOut } = await execAsync('which jq', { timeout: 3000 });
71
+ jqPath = whichOut.trim();
72
+ }
73
+ catch {
74
+ // ignore
75
+ }
76
+ return {
77
+ name: 'jq',
78
+ installed: true,
79
+ version: version || 'unknown',
80
+ path: jqPath || undefined,
81
+ };
82
+ }
83
+ catch {
84
+ return { name: 'jq', installed: false };
85
+ }
86
+ }
87
+ /**
88
+ * macOS 安装 jq:遍历镜像源自动重试
89
+ */
90
+ async function installJqMacos() {
91
+ try {
92
+ await execAsync('which brew', { timeout: 3000 });
93
+ }
94
+ catch {
95
+ console.log(chalk.red(' ✗ 未检测到 Homebrew,无法自动安装 jq'));
96
+ console.log(chalk.gray(' 请先安装 Homebrew,或手动安装 jq: brew install jq'));
97
+ return false;
98
+ }
99
+ console.log(chalk.cyan(' ⏳ 使用 Homebrew 安装 jq...\n'));
100
+ // 依次尝试每个镜像源
101
+ for (let i = 0; i < BREW_BOTTLE_MIRRORS.length; i++) {
102
+ const mirror = BREW_BOTTLE_MIRRORS[i];
103
+ const command = buildBrewInstallCommand(mirror.domain);
104
+ if (!process.stdin.isTTY) {
105
+ console.log(chalk.gray(` [${i + 1}/${BREW_BOTTLE_MIRRORS.length}] 使用${mirror.name}镜像源...`));
106
+ }
107
+ try {
108
+ await execInteractive(command, 120000);
109
+ const verify = await checkJq();
110
+ if (verify.installed) {
111
+ console.log(chalk.green(` ✓ jq 安装成功 (${verify.version})`));
112
+ return true;
113
+ }
114
+ }
115
+ catch (error) {
116
+ if (!process.stdin.isTTY) {
117
+ const detail = formatErrorTail(error);
118
+ if (detail)
119
+ console.log(chalk.gray(` 失败原因: ${detail}\n`));
120
+ }
121
+ }
122
+ if (i < BREW_BOTTLE_MIRRORS.length - 1) {
123
+ console.log(chalk.yellow(` ⚠ ${mirror.name}镜像源失败,尝试下一个...\n`));
124
+ }
125
+ }
126
+ // 所有镜像源都失败,最后一次尝试:不用任何镜像,裸装
127
+ console.log(chalk.gray(' [兜底] 不使用镜像源,直连安装...'));
128
+ try {
129
+ await execInteractive('export HOMEBREW_NO_AUTO_UPDATE=1 && export HOMEBREW_NO_INSTALL_CLEANUP=1 && yes | brew install jq', 180000);
130
+ const verify = await checkJq();
131
+ if (verify.installed) {
132
+ console.log(chalk.green(` ✓ jq 安装成功 (${verify.version})`));
133
+ return true;
134
+ }
135
+ }
136
+ catch (error) {
137
+ if (!process.stdin.isTTY) {
138
+ const detail = formatErrorTail(error);
139
+ if (detail)
140
+ console.log(chalk.gray(` 失败原因: ${detail}\n`));
141
+ }
142
+ }
143
+ console.log(chalk.red(' ✗ jq 自动安装失败'));
144
+ console.log(chalk.gray(' 请手动在终端执行:'));
145
+ console.log(chalk.cyan(' brew install jq'));
146
+ console.log(chalk.gray(' 如果下载慢,设置 bottle 镜像后重试:'));
147
+ console.log(chalk.cyan(' export HOMEBREW_BOTTLE_DOMAIN="https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles"'));
148
+ console.log(chalk.cyan(' export HOMEBREW_NO_AUTO_UPDATE=1'));
149
+ console.log(chalk.cyan(' brew install jq'));
150
+ return false;
151
+ }
152
+ /**
153
+ * Linux 安装 jq
154
+ */
155
+ async function installJqLinux() {
156
+ const pkgManager = await detectLinuxPackageManager();
157
+ let command;
158
+ if (pkgManager === 'apt') {
159
+ command = 'sudo apt-get update -qq && sudo apt-get install -y jq';
160
+ }
161
+ else if (pkgManager === 'yum') {
162
+ command = 'sudo yum install -y jq';
163
+ }
164
+ else {
165
+ console.log(chalk.red(' ✗ 无法识别的 Linux 包管理器'));
166
+ console.log(chalk.gray(' 请手动安装 jq:'));
167
+ console.log(chalk.gray(' apt: sudo apt install -y jq'));
168
+ console.log(chalk.gray(' yum: sudo yum install -y jq'));
169
+ return false;
170
+ }
171
+ console.log(chalk.cyan(' ⏳ 安装 jq(可能需要输入 sudo 密码)...\n'));
172
+ try {
173
+ await execInteractive(command, 300000);
174
+ const verify = await checkJq();
175
+ if (verify.installed) {
176
+ console.log(chalk.green(` ✓ jq 安装成功 (${verify.version})`));
177
+ return true;
178
+ }
179
+ console.log(chalk.yellow(' ⚠ jq 安装命令已执行,但验证失败'));
180
+ return false;
181
+ }
182
+ catch (error) {
183
+ console.log(chalk.red(' ✗ jq 安装失败'));
184
+ const detail = formatErrorTail(error);
185
+ if (detail)
186
+ console.log(chalk.gray(` 失败原因: ${detail}`));
187
+ console.log(chalk.gray(' 请手动安装:'));
188
+ console.log(chalk.cyan(` ${pkgManager === 'apt' ? 'sudo apt install -y jq' : 'sudo yum install -y jq'}`));
189
+ return false;
190
+ }
191
+ }
192
+ /**
193
+ * 安装 jq
194
+ */
195
+ export async function installJq() {
196
+ const platform = process.platform;
197
+ if (platform === 'darwin') {
198
+ return await installJqMacos();
199
+ }
200
+ else if (platform === 'linux') {
201
+ return await installJqLinux();
202
+ }
203
+ else {
204
+ console.log(chalk.red(` ✗ 不支持的操作系统: ${platform}`));
205
+ console.log(chalk.gray(' 请手动安装 jq'));
206
+ return false;
207
+ }
208
+ }
209
+ /**
210
+ * 确保 jq 已安装,未安装则自动安装
211
+ */
212
+ export async function ensureJq() {
213
+ const check = await checkJq();
214
+ if (check.installed) {
215
+ console.log(chalk.green(` ✓ jq 已安装 (${check.version})`));
216
+ return true;
217
+ }
218
+ console.log(chalk.yellow(' ⚠ jq 未安装,正在自动安装...'));
219
+ return await installJq();
220
+ }
221
+ //# sourceMappingURL=jq.js.map