@liangjie559567/ultrapower 5.2.4 → 5.2.7

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 (104) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/dist/__tests__/auto-update.test.js +196 -4
  3. package/dist/__tests__/auto-update.test.js.map +1 -1
  4. package/dist/__tests__/release-local.test.d.ts +2 -0
  5. package/dist/__tests__/release-local.test.d.ts.map +1 -0
  6. package/dist/__tests__/release-local.test.js +19 -0
  7. package/dist/__tests__/release-local.test.js.map +1 -0
  8. package/dist/__tests__/release-steps.test.d.ts +2 -0
  9. package/dist/__tests__/release-steps.test.d.ts.map +1 -0
  10. package/dist/__tests__/release-steps.test.js +82 -0
  11. package/dist/__tests__/release-steps.test.js.map +1 -0
  12. package/dist/features/auto-update.d.ts.map +1 -1
  13. package/dist/features/auto-update.js +23 -3
  14. package/dist/features/auto-update.js.map +1 -1
  15. package/dist/installer/hooks.d.ts.map +1 -1
  16. package/dist/installer/hooks.js +11 -9
  17. package/dist/installer/hooks.js.map +1 -1
  18. package/dist/lib/__tests__/plugin-registry.test.d.ts +2 -0
  19. package/dist/lib/__tests__/plugin-registry.test.d.ts.map +1 -0
  20. package/dist/lib/__tests__/plugin-registry.test.js +241 -0
  21. package/dist/lib/__tests__/plugin-registry.test.js.map +1 -0
  22. package/docs/CLAUDE.md +1 -1
  23. package/docs/plans/2026-02-27-release-cicd-pipeline-design.md +265 -0
  24. package/docs/plans/2026-02-27-release-cicd-pipeline-impl.md +519 -0
  25. package/docs/reviews/ultrapower-standards/AGENTS.md +30 -30
  26. package/docs/standards/templates/AGENTS.md +28 -28
  27. package/docs/superpowers/plans/AGENTS.md +26 -26
  28. package/docs/superpowers/specs/AGENTS.md +26 -26
  29. package/docs/tasks/ultrapower-standards/AGENTS.md +27 -27
  30. package/package.json +4 -2
  31. package/scripts/plugin-setup.mjs +25 -4
  32. package/scripts/release-local.mjs +27 -0
  33. package/scripts/release-steps.mjs +121 -0
  34. package/skills/analyze/AGENTS.md +28 -28
  35. package/skills/autopilot/AGENTS.md +28 -28
  36. package/skills/ax-analyze-error/AGENTS.md +28 -28
  37. package/skills/ax-context/AGENTS.md +28 -28
  38. package/skills/ax-decompose/AGENTS.md +28 -28
  39. package/skills/ax-draft/AGENTS.md +28 -28
  40. package/skills/ax-evolution/AGENTS.md +28 -28
  41. package/skills/ax-evolve/AGENTS.md +28 -28
  42. package/skills/ax-export/AGENTS.md +28 -28
  43. package/skills/ax-implement/AGENTS.md +28 -28
  44. package/skills/ax-knowledge/AGENTS.md +28 -28
  45. package/skills/ax-reflect/AGENTS.md +28 -28
  46. package/skills/ax-review/AGENTS.md +28 -28
  47. package/skills/ax-rollback/AGENTS.md +28 -28
  48. package/skills/ax-status/AGENTS.md +28 -28
  49. package/skills/ax-suspend/AGENTS.md +28 -28
  50. package/skills/brainstorming/AGENTS.md +28 -28
  51. package/skills/build-fix/AGENTS.md +28 -28
  52. package/skills/cancel/AGENTS.md +28 -28
  53. package/skills/ccg/AGENTS.md +28 -28
  54. package/skills/code-review/AGENTS.md +28 -28
  55. package/skills/configure-discord/AGENTS.md +28 -28
  56. package/skills/configure-telegram/AGENTS.md +28 -28
  57. package/skills/deepinit/AGENTS.md +28 -28
  58. package/skills/deepsearch/AGENTS.md +28 -28
  59. package/skills/dispatching-parallel-agents/AGENTS.md +28 -28
  60. package/skills/executing-plans/AGENTS.md +28 -28
  61. package/skills/external-context/AGENTS.md +28 -28
  62. package/skills/finishing-a-development-branch/AGENTS.md +28 -28
  63. package/skills/frontend-ui-ux/AGENTS.md +28 -28
  64. package/skills/git-master/AGENTS.md +28 -28
  65. package/skills/hud/AGENTS.md +28 -28
  66. package/skills/learn-about-omc/AGENTS.md +28 -28
  67. package/skills/learner/AGENTS.md +28 -28
  68. package/skills/mcp-setup/AGENTS.md +28 -28
  69. package/skills/next-step-router/AGENTS.md +28 -28
  70. package/skills/note/AGENTS.md +28 -28
  71. package/skills/omc-doctor/AGENTS.md +28 -28
  72. package/skills/omc-help/AGENTS.md +28 -28
  73. package/skills/omc-setup/AGENTS.md +28 -28
  74. package/skills/pipeline/AGENTS.md +28 -28
  75. package/skills/plan/AGENTS.md +28 -28
  76. package/skills/project-session-manager/AGENTS.md +28 -28
  77. package/skills/psm/AGENTS.md +28 -28
  78. package/skills/ralph/AGENTS.md +28 -28
  79. package/skills/ralph-init/AGENTS.md +28 -28
  80. package/skills/ralplan/AGENTS.md +28 -28
  81. package/skills/receiving-code-review/AGENTS.md +28 -28
  82. package/skills/release/AGENTS.md +28 -28
  83. package/skills/release/SKILL.md +19 -3
  84. package/skills/requesting-code-review/AGENTS.md +28 -28
  85. package/skills/review/AGENTS.md +28 -28
  86. package/skills/sciomc/AGENTS.md +28 -28
  87. package/skills/security-review/AGENTS.md +28 -28
  88. package/skills/skill/AGENTS.md +28 -28
  89. package/skills/subagent-driven-development/AGENTS.md +28 -28
  90. package/skills/swarm/AGENTS.md +28 -28
  91. package/skills/systematic-debugging/AGENTS.md +28 -28
  92. package/skills/team/AGENTS.md +28 -28
  93. package/skills/test-driven-development/AGENTS.md +28 -28
  94. package/skills/trace/AGENTS.md +28 -28
  95. package/skills/ultrapilot/AGENTS.md +28 -28
  96. package/skills/ultraqa/AGENTS.md +28 -28
  97. package/skills/ultrawork/AGENTS.md +28 -28
  98. package/skills/using-git-worktrees/AGENTS.md +28 -28
  99. package/skills/using-superpowers/AGENTS.md +28 -28
  100. package/skills/verification-before-completion/AGENTS.md +28 -28
  101. package/skills/wizard/AGENTS.md +28 -28
  102. package/skills/writer-memory/AGENTS.md +28 -28
  103. package/skills/writing-plans/AGENTS.md +28 -28
  104. package/skills/writing-skills/AGENTS.md +28 -28
@@ -82,7 +82,9 @@ export function getHooksDir() {
82
82
  * Returns the appropriate syntax for the current platform.
83
83
  */
84
84
  export function getHomeEnvVar() {
85
- return isWindows() ? "%USERPROFILE%" : "$HOME";
85
+ // On Windows, Claude Code runs hooks via bash (Git Bash / WSL).
86
+ // bash does NOT expand cmd.exe-style %USERPROFILE%, but DOES expand $USERPROFILE.
87
+ return isWindows() ? "$USERPROFILE" : "$HOME";
86
88
  }
87
89
  /**
88
90
  * Ultrawork message - injected when ultrawork/ulw keyword detected
@@ -295,10 +297,10 @@ export const HOOKS_SETTINGS_CONFIG_NODE = {
295
297
  hooks: [
296
298
  {
297
299
  type: "command",
298
- // Note: On Windows, %USERPROFILE% is expanded by cmd.exe
299
- // On Unix with node hooks, $HOME is expanded by the shell
300
+ // On Windows, Claude Code runs hooks via bash (Git Bash / WSL).
301
+ // bash expands $USERPROFILE but NOT cmd.exe-style %USERPROFILE%.
300
302
  command: isWindows()
301
- ? 'node "%USERPROFILE%\\.claude\\hooks\\keyword-detector.mjs"'
303
+ ? 'node "$USERPROFILE/.claude/hooks/keyword-detector.mjs"'
302
304
  : 'node "$HOME/.claude/hooks/keyword-detector.mjs"',
303
305
  },
304
306
  ],
@@ -310,7 +312,7 @@ export const HOOKS_SETTINGS_CONFIG_NODE = {
310
312
  {
311
313
  type: "command",
312
314
  command: isWindows()
313
- ? 'node "%USERPROFILE%\\.claude\\hooks\\session-start.mjs"'
315
+ ? 'node "$USERPROFILE/.claude/hooks/session-start.mjs"'
314
316
  : 'node "$HOME/.claude/hooks/session-start.mjs"',
315
317
  },
316
318
  ],
@@ -322,7 +324,7 @@ export const HOOKS_SETTINGS_CONFIG_NODE = {
322
324
  {
323
325
  type: "command",
324
326
  command: isWindows()
325
- ? 'node "%USERPROFILE%\\.claude\\hooks\\pre-tool-use.mjs"'
327
+ ? 'node "$USERPROFILE/.claude/hooks/pre-tool-use.mjs"'
326
328
  : 'node "$HOME/.claude/hooks/pre-tool-use.mjs"',
327
329
  },
328
330
  ],
@@ -334,7 +336,7 @@ export const HOOKS_SETTINGS_CONFIG_NODE = {
334
336
  {
335
337
  type: "command",
336
338
  command: isWindows()
337
- ? 'node "%USERPROFILE%\\.claude\\hooks\\post-tool-use.mjs"'
339
+ ? 'node "$USERPROFILE/.claude/hooks/post-tool-use.mjs"'
338
340
  : 'node "$HOME/.claude/hooks/post-tool-use.mjs"',
339
341
  },
340
342
  ],
@@ -346,7 +348,7 @@ export const HOOKS_SETTINGS_CONFIG_NODE = {
346
348
  {
347
349
  type: "command",
348
350
  command: isWindows()
349
- ? 'node "%USERPROFILE%\\.claude\\hooks\\post-tool-use-failure.mjs"'
351
+ ? 'node "$USERPROFILE/.claude/hooks/post-tool-use-failure.mjs"'
350
352
  : 'node "$HOME/.claude/hooks/post-tool-use-failure.mjs"',
351
353
  },
352
354
  ],
@@ -358,7 +360,7 @@ export const HOOKS_SETTINGS_CONFIG_NODE = {
358
360
  {
359
361
  type: "command",
360
362
  command: isWindows()
361
- ? 'node "%USERPROFILE%\\.claude\\hooks\\persistent-mode.mjs"'
363
+ ? 'node "$USERPROFILE/.claude/hooks/persistent-mode.mjs"'
362
364
  : 'node "$HOME/.claude/hooks/persistent-mode.mjs"',
363
365
  },
364
366
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/installer/hooks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/installer/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=plugin-registry.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-registry.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/plugin-registry.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,241 @@
1
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
2
+ import { existsSync, readFileSync } from 'fs';
3
+ // Mock fs module
4
+ vi.mock('fs', async (importOriginal) => {
5
+ const actual = await importOriginal();
6
+ return {
7
+ ...actual,
8
+ existsSync: vi.fn(),
9
+ readFileSync: vi.fn(),
10
+ };
11
+ });
12
+ // Mock atomic-write
13
+ vi.mock('../atomic-write.js', () => ({
14
+ atomicWriteJsonSync: vi.fn(),
15
+ safeReadJson: vi.fn(),
16
+ }));
17
+ // Mock url module for import.meta.url
18
+ vi.mock('url', async (importOriginal) => {
19
+ const actual = await importOriginal();
20
+ return {
21
+ ...actual,
22
+ fileURLToPath: vi.fn(() => '/mock/src/lib/plugin-registry.ts'),
23
+ };
24
+ });
25
+ import { syncPluginRegistry, checkVersionConsistency } from '../plugin-registry.js';
26
+ import { atomicWriteJsonSync } from '../atomic-write.js';
27
+ const mockExistsSync = vi.mocked(existsSync);
28
+ const mockReadFileSync = vi.mocked(readFileSync);
29
+ const mockAtomicWriteJsonSync = vi.mocked(atomicWriteJsonSync);
30
+ const REGISTRY_PATH_SUFFIX = join('.claude', 'plugins', 'installed_plugins.json');
31
+ import { join } from 'path';
32
+ import { homedir } from 'os';
33
+ const REGISTRY_PATH = join(homedir(), '.claude', 'plugins', 'installed_plugins.json');
34
+ function makeRegistry(version, installPath = '/mock/install/path') {
35
+ return {
36
+ version: 2,
37
+ plugins: {
38
+ 'ultrapower@ultrapower': [
39
+ {
40
+ scope: 'user',
41
+ installPath,
42
+ version,
43
+ installedAt: '2026-01-01T00:00:00.000Z',
44
+ lastUpdated: '2026-01-01T00:00:00.000Z',
45
+ },
46
+ ],
47
+ },
48
+ };
49
+ }
50
+ describe('syncPluginRegistry', () => {
51
+ beforeEach(() => {
52
+ vi.clearAllMocks();
53
+ });
54
+ it('1. 正常更新:精确匹配 ultrapower@ultrapower,更新 version 和 lastUpdated,不修改 installPath', () => {
55
+ const registry = makeRegistry('5.0.0');
56
+ mockExistsSync.mockReturnValue(true);
57
+ mockReadFileSync.mockReturnValue(JSON.stringify(registry));
58
+ const result = syncPluginRegistry({ newVersion: '5.1.0' });
59
+ expect(result.success).toBe(true);
60
+ expect(result.previousVersion).toBe('5.0.0');
61
+ expect(result.newVersion).toBe('5.1.0');
62
+ expect(mockAtomicWriteJsonSync).toHaveBeenCalledTimes(1);
63
+ const written = mockAtomicWriteJsonSync.mock.calls[0][1];
64
+ const entry = written.plugins['ultrapower@ultrapower'][0];
65
+ expect(entry.version).toBe('5.1.0');
66
+ expect(entry.installPath).toBe('/mock/install/path'); // installPath 未被修改
67
+ expect(entry.lastUpdated).not.toBe('2026-01-01T00:00:00.000Z'); // lastUpdated 已更新
68
+ });
69
+ it('2. 文件不存在:返回 { success: true, skipped: true },不调用 atomicWriteJsonSync', () => {
70
+ mockExistsSync.mockReturnValue(false);
71
+ const result = syncPluginRegistry({ newVersion: '5.1.0' });
72
+ expect(result.success).toBe(true);
73
+ expect(result.skipped).toBe(true);
74
+ expect(mockAtomicWriteJsonSync).not.toHaveBeenCalled();
75
+ });
76
+ it('3. key 不存在:返回 { success: false, errors },不调用 atomicWriteJsonSync', () => {
77
+ const registry = {
78
+ version: 2,
79
+ plugins: {
80
+ 'other-plugin@other': [{ scope: 'user', installPath: '/x', version: '1.0.0', installedAt: '', lastUpdated: '' }],
81
+ },
82
+ };
83
+ mockExistsSync.mockReturnValue(true);
84
+ mockReadFileSync.mockReturnValue(JSON.stringify(registry));
85
+ const result = syncPluginRegistry({ newVersion: '5.1.0' });
86
+ expect(result.success).toBe(false);
87
+ expect(result.errors).toBeDefined();
88
+ expect(result.errors[0]).toContain('not found');
89
+ expect(mockAtomicWriteJsonSync).not.toHaveBeenCalled();
90
+ });
91
+ it('4. 幂等性:连续调用两次,第二次 previousVersion === newVersion,lastUpdated 更新', () => {
92
+ const registry = makeRegistry('5.1.0');
93
+ mockExistsSync.mockReturnValue(true);
94
+ mockReadFileSync.mockReturnValue(JSON.stringify(registry));
95
+ const result1 = syncPluginRegistry({ newVersion: '5.1.0' });
96
+ const result2 = syncPluginRegistry({ newVersion: '5.1.0' });
97
+ expect(result1.previousVersion).toBe('5.1.0');
98
+ expect(result2.previousVersion).toBe('5.1.0');
99
+ expect(mockAtomicWriteJsonSync).toHaveBeenCalledTimes(2);
100
+ });
101
+ it('5. skipIfProjectScoped=true:返回 { success: true, skipped: true },不读取文件', () => {
102
+ const result = syncPluginRegistry({ newVersion: '5.1.0', skipIfProjectScoped: true });
103
+ expect(result.success).toBe(true);
104
+ expect(result.skipped).toBe(true);
105
+ expect(mockReadFileSync).not.toHaveBeenCalled();
106
+ expect(mockAtomicWriteJsonSync).not.toHaveBeenCalled();
107
+ });
108
+ it('6. 不匹配 fork key:不更新,返回 { success: false }', () => {
109
+ const registry = {
110
+ version: 2,
111
+ plugins: {
112
+ 'ultrapower-fork@someuser': [
113
+ { scope: 'user', installPath: '/x', version: '5.0.0', installedAt: '', lastUpdated: '' },
114
+ ],
115
+ },
116
+ };
117
+ mockExistsSync.mockReturnValue(true);
118
+ mockReadFileSync.mockReturnValue(JSON.stringify(registry));
119
+ const result = syncPluginRegistry({ newVersion: '5.1.0' });
120
+ expect(result.success).toBe(false);
121
+ expect(mockAtomicWriteJsonSync).not.toHaveBeenCalled();
122
+ });
123
+ it('7. atomicWriteJsonSync 抛出异常:返回 { success: false, errors }', () => {
124
+ const registry = makeRegistry('5.0.0');
125
+ mockExistsSync.mockReturnValue(true);
126
+ mockReadFileSync.mockReturnValue(JSON.stringify(registry));
127
+ mockAtomicWriteJsonSync.mockImplementation(() => { throw new Error('disk full'); });
128
+ const result = syncPluginRegistry({ newVersion: '5.1.0' });
129
+ expect(result.success).toBe(false);
130
+ expect(result.errors).toBeDefined();
131
+ expect(result.errors[0]).toContain('disk full');
132
+ });
133
+ });
134
+ describe('checkVersionConsistency', () => {
135
+ beforeEach(() => {
136
+ vi.clearAllMocks();
137
+ });
138
+ function setupMocks(opts) {
139
+ const { registryVersion = '5.1.0', versionMetadataVersion = '5.1.0', packageJsonVersion = '5.1.0' } = opts;
140
+ mockExistsSync.mockImplementation((p) => {
141
+ const path = String(p);
142
+ if (path.endsWith('installed_plugins.json'))
143
+ return registryVersion !== null;
144
+ if (path.includes('version.json'))
145
+ return versionMetadataVersion !== null;
146
+ if (path.endsWith('package.json'))
147
+ return true;
148
+ return false;
149
+ });
150
+ mockReadFileSync.mockImplementation((p) => {
151
+ const path = String(p);
152
+ if (path.endsWith('installed_plugins.json') && registryVersion !== null) {
153
+ return JSON.stringify(makeRegistry(registryVersion));
154
+ }
155
+ if (path.includes('version.json') && versionMetadataVersion !== null) {
156
+ return JSON.stringify({ version: versionMetadataVersion });
157
+ }
158
+ if (path.endsWith('package.json')) {
159
+ return JSON.stringify({ name: 'ultrapower', version: packageJsonVersion });
160
+ }
161
+ throw new Error(`ENOENT: ${path}`);
162
+ });
163
+ }
164
+ it('8. 三源一致:返回 { consistent: true, discrepancies: [] }', () => {
165
+ setupMocks({ registryVersion: '5.1.0', versionMetadataVersion: '5.1.0', packageJsonVersion: '5.1.0' });
166
+ const report = checkVersionConsistency();
167
+ expect(report.consistent).toBe(true);
168
+ expect(report.discrepancies).toHaveLength(0);
169
+ expect(report.fixCommand).toBeUndefined();
170
+ });
171
+ it('9. registryVersion 落后:discrepancies 非空,fixCommand 非空', () => {
172
+ setupMocks({ registryVersion: '5.0.0', versionMetadataVersion: '5.1.0', packageJsonVersion: '5.1.0' });
173
+ const report = checkVersionConsistency();
174
+ expect(report.consistent).toBe(false);
175
+ expect(report.discrepancies.length).toBeGreaterThan(0);
176
+ expect(report.fixCommand).toBeDefined();
177
+ expect(report.registryVersion).toBe('5.0.0');
178
+ });
179
+ it('10. versionMetadataVersion 为 null(文件不存在):consistent: false', () => {
180
+ setupMocks({ registryVersion: '5.1.0', versionMetadataVersion: null, packageJsonVersion: '5.1.0' });
181
+ const report = checkVersionConsistency();
182
+ expect(report.consistent).toBe(false);
183
+ expect(report.versionMetadataVersion).toBeNull();
184
+ });
185
+ it('11. isUpdating: registryVersion 与 packageJsonVersion 不同时为 true', () => {
186
+ setupMocks({ registryVersion: '5.0.0', versionMetadataVersion: '5.1.0', packageJsonVersion: '5.1.0' });
187
+ const report = checkVersionConsistency();
188
+ expect(report.isUpdating).toBe(true);
189
+ });
190
+ it('12. 多条目数组:使用第 0 项', () => {
191
+ const multiEntryRegistry = {
192
+ version: 2,
193
+ plugins: {
194
+ 'ultrapower@ultrapower': [
195
+ { scope: 'user', installPath: '/a', version: '5.1.0', installedAt: '', lastUpdated: '' },
196
+ { scope: 'user', installPath: '/b', version: '4.0.0', installedAt: '', lastUpdated: '' },
197
+ ],
198
+ },
199
+ };
200
+ mockExistsSync.mockImplementation((p) => {
201
+ const path = String(p);
202
+ if (path.endsWith('installed_plugins.json'))
203
+ return true;
204
+ if (path.endsWith('package.json'))
205
+ return true;
206
+ return false;
207
+ });
208
+ mockReadFileSync.mockImplementation((p) => {
209
+ const path = String(p);
210
+ if (path.endsWith('installed_plugins.json'))
211
+ return JSON.stringify(multiEntryRegistry);
212
+ if (path.endsWith('package.json'))
213
+ return JSON.stringify({ name: 'ultrapower', version: '5.1.0' });
214
+ throw new Error(`ENOENT: ${path}`);
215
+ });
216
+ const report = checkVersionConsistency();
217
+ expect(report.registryVersion).toBe('5.1.0');
218
+ });
219
+ it('13. 空数组:registryVersion 为 null', () => {
220
+ const emptyRegistry = { version: 2, plugins: { 'ultrapower@ultrapower': [] } };
221
+ mockExistsSync.mockImplementation((p) => {
222
+ const path = String(p);
223
+ if (path.endsWith('installed_plugins.json'))
224
+ return true;
225
+ if (path.endsWith('package.json'))
226
+ return true;
227
+ return false;
228
+ });
229
+ mockReadFileSync.mockImplementation((p) => {
230
+ const path = String(p);
231
+ if (path.endsWith('installed_plugins.json'))
232
+ return JSON.stringify(emptyRegistry);
233
+ if (path.endsWith('package.json'))
234
+ return JSON.stringify({ name: 'ultrapower', version: '5.1.0' });
235
+ throw new Error(`ENOENT: ${path}`);
236
+ });
237
+ const report = checkVersionConsistency();
238
+ expect(report.registryVersion).toBeNull();
239
+ });
240
+ });
241
+ //# sourceMappingURL=plugin-registry.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-registry.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/plugin-registry.test.ts"],"names":[],"mappings":"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"}
package/docs/CLAUDE.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <!-- OMC:START -->
2
- <!-- OMC:VERSION:5.2.4 -->
2
+ <!-- OMC:VERSION:5.2.7 -->
3
3
  # ultrapower - Multi-Agent Orchestration 智能多 Agent 编排
4
4
 
5
5
  你正在使用 ultrapower(OMC),这是 Claude Code 的多 agent 编排层。
@@ -0,0 +1,265 @@
1
+ # 插件发布 CI/CD 流水线设计
2
+
3
+ **日期**:2026-02-27
4
+ **状态**:已批准
5
+ **方案**:C(GitHub Actions 主导 + 本地脚本备用,共享核心逻辑)
6
+
7
+ ---
8
+
9
+ ## 1. 背景与目标
10
+
11
+ ### 问题陈述
12
+
13
+ 当前 ultrapower 发布流程依赖手动执行 `skills/release/SKILL.md` 中的步骤:
14
+ - 手动更新版本号(多个文件)
15
+ - 手动运行 `npm publish`
16
+ - 手动创建 GitHub Release
17
+ - 手动更新 `marketplace.json`
18
+
19
+ 这导致:
20
+ - 发布步骤容易遗漏(如 REFERENCE.md 双重数量声明 — k-047)
21
+ - 发布者机器环境依赖(NPM_TOKEN 本地配置)
22
+ - 无法并行执行独立步骤
23
+
24
+ ### 目标
25
+
26
+ 从 `git tag v*` 推送到完整发布,全自动化,同时保留本地执行能力用于调试和紧急发布。
27
+
28
+ ---
29
+
30
+ ## 2. 架构概览
31
+
32
+ ```
33
+ 发布触发
34
+ └── git tag v5.3.0 && git push --tags
35
+
36
+ ├── GitHub Actions(主路径)
37
+ │ .github/workflows/release.yml
38
+ │ └── 调用 scripts/release-steps.mjs
39
+
40
+ └── 本地脚本(备用路径)
41
+ scripts/release-local.mjs
42
+ └── 调用 scripts/release-steps.mjs
43
+
44
+ 共享核心
45
+ scripts/release-steps.mjs
46
+ ├── validateBuild()
47
+ ├── publishNpm()
48
+ ├── createGithubRelease()
49
+ └── syncMarketplace()
50
+ ```
51
+
52
+ ### 文件变更清单
53
+
54
+ | 操作 | 文件 | 说明 |
55
+ |------|------|------|
56
+ | 新增 | `.github/workflows/release.yml` | GitHub Actions 主流程 |
57
+ | 新增 | `scripts/release-steps.mjs` | 共享核心逻辑 |
58
+ | 新增 | `scripts/release-local.mjs` | 本地执行入口 |
59
+ | 修改 | `skills/release/SKILL.md` | 更新:说明 CI 接管后续步骤 |
60
+ | 修改 | `package.json` | 新增 `release:local` / `release:dry-run` scripts |
61
+
62
+ ---
63
+
64
+ ## 3. 共享核心:`scripts/release-steps.mjs`
65
+
66
+ ### 接口设计
67
+
68
+ ```javascript
69
+ /**
70
+ * 步骤 1:构建验证
71
+ * 执行 tsc --noEmit && npm run build && npm test
72
+ */
73
+ export async function validateBuild(opts = {})
74
+ // opts: { skipTests?: boolean }
75
+ // 返回: { success: boolean, output: string }
76
+
77
+ /**
78
+ * 步骤 2:npm 发布
79
+ * 执行 npm publish --access public
80
+ */
81
+ export async function publishNpm(opts = {})
82
+ // opts: { dryRun?: boolean, tag?: string }
83
+ // 返回: { success: boolean, version: string }
84
+
85
+ /**
86
+ * 步骤 3:GitHub Release 创建
87
+ * 执行 gh release create v{version} --generate-notes
88
+ */
89
+ export async function createGithubRelease(opts = {})
90
+ // opts: { version: string, notes?: string, dryRun?: boolean }
91
+ // 返回: { success: boolean, url: string }
92
+
93
+ /**
94
+ * 步骤 4:市场版本同步
95
+ * 更新 .claude-plugin/marketplace.json version 字段 + git commit + push
96
+ */
97
+ export async function syncMarketplace(opts = {})
98
+ // opts: { version: string, dryRun?: boolean }
99
+ // 返回: { success: boolean }
100
+
101
+ /**
102
+ * 完整流水线(顺序执行全部 4 步)
103
+ */
104
+ export async function runReleasePipeline(opts = {})
105
+ // opts: {
106
+ // dryRun?: boolean,
107
+ // skipTests?: boolean,
108
+ // startFrom?: 'validate' | 'publish' | 'release' | 'sync'
109
+ // }
110
+ // 任一步骤失败则停止并以非零退出码退出
111
+ ```
112
+
113
+ ### 错误处理原则
114
+
115
+ - 每步失败输出明确错误信息(步骤名 + 错误内容 + 建议操作)
116
+ - 支持 `--start-from` 从失败步骤重试(跳过已完成步骤)
117
+ - dry-run 模式:打印将执行的命令,不实际执行
118
+
119
+ ---
120
+
121
+ ## 4. GitHub Actions Workflow
122
+
123
+ ### 触发条件
124
+
125
+ ```yaml
126
+ on:
127
+ push:
128
+ tags:
129
+ - 'v*'
130
+ ```
131
+
132
+ ### Job 依赖图
133
+
134
+ ```
135
+ build-test
136
+
137
+ └── publish
138
+
139
+ ├── github-release
140
+ └── marketplace-sync
141
+ ```
142
+
143
+ - `build-test` → `publish`:串行(确保验证通过才发布)
144
+ - `publish` → `github-release`:串行(确保 npm 包存在才创建 Release)
145
+ - `publish` → `marketplace-sync`:并行(与 github-release 独立)
146
+
147
+ ### Secrets 需求
148
+
149
+ | Secret | 用途 | 配置位置 |
150
+ |--------|------|---------|
151
+ | `NPM_TOKEN` | npm publish 权限 | GitHub repo Settings → Secrets |
152
+ | `GITHUB_TOKEN` | GitHub Release 创建 | Actions 内置,无需手动配置 |
153
+
154
+ ### 关键配置
155
+
156
+ ```yaml
157
+ jobs:
158
+ build-test:
159
+ runs-on: ubuntu-latest
160
+ steps:
161
+ - uses: actions/checkout@v4
162
+ - uses: actions/setup-node@v4
163
+ with:
164
+ node-version: '20'
165
+ cache: 'npm'
166
+ - run: npm ci
167
+ - run: node scripts/release-steps.mjs validate
168
+
169
+ publish:
170
+ needs: build-test
171
+ runs-on: ubuntu-latest
172
+ steps:
173
+ - uses: actions/checkout@v4
174
+ - uses: actions/setup-node@v4
175
+ with:
176
+ node-version: '20'
177
+ registry-url: 'https://registry.npmjs.org'
178
+ - run: npm ci
179
+ - run: node scripts/release-steps.mjs publish
180
+ env:
181
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
182
+
183
+ github-release:
184
+ needs: publish
185
+ runs-on: ubuntu-latest
186
+ steps:
187
+ - uses: actions/checkout@v4
188
+ - run: node scripts/release-steps.mjs release
189
+ env:
190
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
191
+
192
+ marketplace-sync:
193
+ needs: publish
194
+ runs-on: ubuntu-latest
195
+ steps:
196
+ - uses: actions/checkout@v4
197
+ with:
198
+ token: ${{ secrets.GITHUB_TOKEN }}
199
+ - run: node scripts/release-steps.mjs sync
200
+ env:
201
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
202
+ ```
203
+
204
+ ---
205
+
206
+ ## 5. 本地脚本
207
+
208
+ ### `scripts/release-local.mjs`
209
+
210
+ ```javascript
211
+ // 用法:
212
+ // node scripts/release-local.mjs
213
+ // node scripts/release-local.mjs --dry-run
214
+ // node scripts/release-local.mjs --start-from=publish
215
+ // npm run release:local
216
+ // npm run release:dry-run
217
+ ```
218
+
219
+ ### `package.json` 新增 scripts
220
+
221
+ ```json
222
+ {
223
+ "scripts": {
224
+ "release:local": "node scripts/release-local.mjs",
225
+ "release:dry-run": "node scripts/release-local.mjs --dry-run"
226
+ }
227
+ }
228
+ ```
229
+
230
+ ---
231
+
232
+ ## 6. 与现有 Release Skill 的分工
233
+
234
+ | 步骤 | 负责方 | 工具 |
235
+ |------|--------|------|
236
+ | 版本号更新(package.json、CHANGELOG、文档) | release skill(手动) | 编辑文件 |
237
+ | git commit + tag + push | release skill(手动) | git |
238
+ | npm publish | **GitHub Actions(自动)** | release-steps.mjs |
239
+ | GitHub Release 创建 | **GitHub Actions(自动)** | release-steps.mjs |
240
+ | marketplace.json 版本同步 | **GitHub Actions(自动)** | release-steps.mjs |
241
+
242
+ **`skills/release/SKILL.md` 更新说明**:在"发布步骤"末尾添加:
243
+ > 执行 `git push --tags` 后,GitHub Actions 自动接管后续步骤(npm 发布、GitHub Release、市场同步)。如需手动执行,运行 `npm run release:local`。
244
+
245
+ ---
246
+
247
+ ## 7. 测试策略
248
+
249
+ | 测试类型 | 覆盖内容 |
250
+ |---------|---------|
251
+ | 单元测试 | `release-steps.mjs` 各函数(mock exec) |
252
+ | dry-run 测试 | 验证 dry-run 模式不执行实际命令 |
253
+ | 集成测试 | GitHub Actions workflow 语法验证(`actionlint`) |
254
+ | 手动验证 | 首次发布时使用 `--dry-run` 预检 |
255
+
256
+ ---
257
+
258
+ ## 8. 风险与缓解
259
+
260
+ | 风险 | 缓解措施 |
261
+ |------|---------|
262
+ | NPM_TOKEN 过期 | CI 失败时发邮件通知,本地脚本作为备用 |
263
+ | marketplace-sync 提交冲突 | 使用 `git pull --rebase` 后再 push |
264
+ | 版本号不一致 | validateBuild 步骤检查 package.json vs git tag 一致性 |
265
+ | 网络超时 | 每步设置 timeout,失败后支持 `--start-from` 重试 |