@liangjie559567/ultrapower 5.5.25 → 5.5.26

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.
@@ -8,11 +8,11 @@
8
8
  {
9
9
  "name": "ultrapower",
10
10
  "description": "Disciplined multi-agent orchestration: workflow enforcement + parallel execution",
11
- "version": "5.5.25",
11
+ "version": "5.5.26",
12
12
  "source": {
13
13
  "source": "npm",
14
14
  "package": "@liangjie559567/ultrapower",
15
- "version": "5.5.25"
15
+ "version": "5.5.26"
16
16
  },
17
17
  "author": {
18
18
  "name": "liangjie559567"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ultrapower",
3
3
  "description": "Disciplined multi-agent orchestration: workflow enforcement + parallel execution",
4
- "version": "5.5.25",
4
+ "version": "5.5.26",
5
5
  "author": {
6
6
  "name": "liangjie559567"
7
7
  },
@@ -0,0 +1,85 @@
1
+ # Release Process
2
+
3
+ ## 版本同步检查清单
4
+
5
+ 发布前必须确保以下文件版本一致:
6
+
7
+ 1. `package.json` - npm 包版本
8
+ 2. `.claude-plugin/plugin.json` - 用户看到的插件版本
9
+ 3. `.claude-plugin/marketplace.json` - 插件市场版本
10
+
11
+ ## 自动化验证
12
+
13
+ ### 本地验证
14
+
15
+ ```bash
16
+ npm run validate:versions
17
+ ```
18
+
19
+ ### CI 验证
20
+
21
+ 版本验证已集成到 GitHub Actions release 工作流的 preflight 步骤中。
22
+
23
+ ## 发布流程
24
+
25
+ ### 标准发布(推荐)
26
+
27
+ 1. 更新版本号:
28
+ ```bash
29
+ npm run bump -- 5.5.26
30
+ ```
31
+
32
+ 2. 验证版本同步:
33
+ ```bash
34
+ npm run validate:versions
35
+ ```
36
+
37
+ 3. 提交并打标签:
38
+ ```bash
39
+ git add -A
40
+ git commit -m "chore: bump version to 5.5.26"
41
+ git tag v5.5.26
42
+ git push origin main
43
+ git push origin v5.5.26
44
+ ```
45
+
46
+ 4. GitHub Actions 自动执行:
47
+ - 构建和测试
48
+ - 发布到 npm
49
+ - 创建 GitHub Release
50
+ - 同步 marketplace.json 和 plugin.json
51
+
52
+ ### 手动发布(仅用于调试)
53
+
54
+ ```bash
55
+ npm run release:dry-run # 预览
56
+ npm run release:local # 执行
57
+ ```
58
+
59
+ ## 故障排查
60
+
61
+ ### 版本不一致
62
+
63
+ 如果 `validate:versions` 失败:
64
+
65
+ ```bash
66
+ # 查看差异
67
+ git diff package.json .claude-plugin/plugin.json .claude-plugin/marketplace.json
68
+
69
+ # 手动修复后重新验证
70
+ npm run validate:versions
71
+ ```
72
+
73
+ ### CI 失败
74
+
75
+ 1. 检查 GitHub Actions 日志
76
+ 2. 本地重现问题:
77
+ ```bash
78
+ npm run test:run
79
+ npm run build
80
+ ```
81
+
82
+ ## 相关知识
83
+
84
+ - [k-077: Multi-File Version Sync in Release Pipeline](../../.omc/axiom/evolution/knowledge_base.md#k-077)
85
+ - [k-074: Version Number Sync Checklist](../../.omc/axiom/evolution/knowledge_base.md#k-074)
@@ -0,0 +1,94 @@
1
+ # Testing Guide
2
+
3
+ ## 测试环境隔离模式
4
+
5
+ ### 标准模式(推荐)
6
+
7
+ 所有需要文件系统操作或 git 环境的测试必须使用隔离的测试目录:
8
+
9
+ ```typescript
10
+ import { join } from 'path';
11
+ import { homedir } from 'os';
12
+ import { mkdirSync, rmSync, existsSync } from 'fs';
13
+
14
+ describe('test suite', () => {
15
+ const testDir = join(homedir(), '.omc', 'test-unique-name');
16
+
17
+ beforeEach(() => {
18
+ mkdirSync(testDir, { recursive: true });
19
+ try {
20
+ require('child_process').execSync('git init', { cwd: testDir, stdio: 'ignore' });
21
+ } catch (e) {
22
+ // Ignore if git init fails
23
+ }
24
+ });
25
+
26
+ afterEach(() => {
27
+ if (existsSync(testDir)) {
28
+ rmSync(testDir, { recursive: true, force: true });
29
+ }
30
+ });
31
+
32
+ it('should use testDir instead of process.cwd()', () => {
33
+ const config = {
34
+ workingDirectory: testDir // ✅ 正确
35
+ // workingDirectory: process.cwd() // ❌ 错误
36
+ };
37
+ });
38
+ });
39
+ ```
40
+
41
+ ### 关键要素
42
+
43
+ 1. **使用 `homedir()`**:确保路径在用户目录下
44
+ 2. **唯一测试目录名**:避免并发测试冲突
45
+ 3. **`beforeEach` 中初始化 git**:满足 worktree 检查
46
+ 4. **`afterEach` 中清理**:避免测试污染
47
+ 5. **使用 `testDir` 而非 `process.cwd()`**:CI 环境兼容
48
+
49
+ ### 反模式
50
+
51
+ ❌ **错误**:使用 `process.cwd()`
52
+ ```typescript
53
+ const config = {
54
+ workingDirectory: process.cwd() // CI 中路径不可控
55
+ };
56
+ ```
57
+
58
+ ✅ **正确**:使用隔离的 `testDir`
59
+ ```typescript
60
+ const testDir = join(homedir(), '.omc', 'test-my-feature');
61
+ const config = {
62
+ workingDirectory: testDir
63
+ };
64
+ ```
65
+
66
+ ## 跨平台注意事项
67
+
68
+ ### Windows vs Linux
69
+
70
+ - **路径分隔符**:使用 `path.join()` 而非手动拼接
71
+ - **`process.cwd()` 行为**:
72
+ - Linux CI: `/home/runner/work/repo/repo`
73
+ - Windows CI: `D:/a/repo/repo`
74
+ - 两者都可能在 home 目录外部
75
+
76
+ ### Git 环境
77
+
78
+ 测试目录默认不是 git 仓库,需要显式初始化:
79
+
80
+ ```typescript
81
+ beforeEach(() => {
82
+ mkdirSync(testDir, { recursive: true });
83
+ try {
84
+ execSync('git init', { cwd: testDir, stdio: 'ignore' });
85
+ } catch (e) {
86
+ // Ignore if git not available
87
+ }
88
+ });
89
+ ```
90
+
91
+ ## 相关知识
92
+
93
+ - [k-078: CI Test Environment Isolation Pattern](../../.omc/axiom/evolution/knowledge_base.md#k-078)
94
+ - [k-079: Batch Fix Same-Pattern Issues](../../.omc/axiom/evolution/knowledge_base.md#k-079)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liangjie559567/ultrapower",
3
- "version": "5.5.25",
3
+ "version": "5.5.26",
4
4
  "description": "Disciplined multi-agent orchestration: workflow enforcement + parallel execution",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -61,7 +61,8 @@
61
61
  "postinstall": "node scripts/plugin-setup.mjs",
62
62
  "release:local": "node scripts/release-local.mjs",
63
63
  "release:dry-run": "node scripts/release-local.mjs --dry-run",
64
- "bump": "node scripts/bump-version.mjs"
64
+ "bump": "node scripts/bump-version.mjs",
65
+ "validate:versions": "node scripts/validate-versions.mjs"
65
66
  },
66
67
  "dependencies": {
67
68
  "@anthropic-ai/claude-agent-sdk": "^0.1.0",
@@ -280,6 +280,57 @@ function fixNpmCache() {
280
280
 
281
281
  fixNpmCache();
282
282
 
283
+ // Fix: npm-cache marketplace.json also needs repair
284
+ function fixNpmCacheMarketplace() {
285
+ try {
286
+ const npmCacheDir = join(CLAUDE_DIR, 'plugins', 'cache', 'npm-cache', 'node_modules', '@liangjie559567', 'ultrapower');
287
+ if (!existsSync(npmCacheDir)) return;
288
+
289
+ const npmMarketplaceDir = join(npmCacheDir, '.claude-plugin');
290
+ const npmMarketplacePath = join(npmMarketplaceDir, 'marketplace.json');
291
+
292
+ let cacheVersion = '0.0.0';
293
+ try {
294
+ const cachePkg = JSON.parse(readFileSync(join(npmCacheDir, 'package.json'), 'utf-8'));
295
+ cacheVersion = cachePkg.version || cacheVersion;
296
+ } catch { /* use default */ }
297
+
298
+ function marketplaceNeedsRepair() {
299
+ try {
300
+ const content = JSON.parse(readFileSync(npmMarketplacePath, 'utf-8'));
301
+ if (content.name !== 'omc') return true;
302
+ if (!Array.isArray(content.plugins) || content.plugins.length === 0) return true;
303
+ return false;
304
+ } catch (e) {
305
+ if (e.code === 'ENOENT') return true;
306
+ return false;
307
+ }
308
+ }
309
+
310
+ if (!marketplaceNeedsRepair()) return;
311
+
312
+ const cleanMarketplaceJson = {
313
+ name: 'omc',
314
+ description: 'Disciplined multi-agent orchestration for Claude Code: workflow enforcement + parallel execution',
315
+ owner: { name: 'liangjie559567' },
316
+ plugins: [{
317
+ name: 'ultrapower',
318
+ description: 'Disciplined multi-agent orchestration: workflow enforcement + parallel execution',
319
+ version: cacheVersion,
320
+ source: { source: 'npm', package: '@liangjie559567/ultrapower', version: cacheVersion },
321
+ author: { name: 'liangjie559567' }
322
+ }]
323
+ };
324
+ mkdirSync(npmMarketplaceDir, { recursive: true });
325
+ writeFileSync(npmMarketplacePath, JSON.stringify(cleanMarketplaceJson, null, 2));
326
+ console.log(`[OMC] Repaired npm-cache marketplace.json (v${cacheVersion})`);
327
+ } catch (e) {
328
+ console.log('[OMC] Warning: Could not repair npm-cache marketplace.json:', e.message);
329
+ }
330
+ }
331
+
332
+ fixNpmCacheMarketplace();
333
+
283
334
  // Fix: Claude Code's npm-cache/package.json stores a semver range (e.g. "^5.2.3") after first install.
284
335
  // On subsequent "Update now" clicks, the installer sees the range is satisfied by the cached version
285
336
  // and skips re-downloading — so users stay on the old version forever.
@@ -390,6 +441,54 @@ function fixMissingPluginJson() {
390
441
 
391
442
  fixMissingPluginJson();
392
443
 
444
+ // Fix: npm install strips .claude-plugin/marketplace.json, recreate it in plugin cache
445
+ function fixMissingMarketplaceJson() {
446
+ try {
447
+ const pluginRoot = dirname(__dirname);
448
+ const pkgPath = join(pluginRoot, 'package.json');
449
+ if (!existsSync(pkgPath)) return;
450
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
451
+ const version = pkg.version || '0.0.0';
452
+
453
+ const marketplaceJson = {
454
+ name: 'omc',
455
+ description: 'Disciplined multi-agent orchestration for Claude Code: workflow enforcement + parallel execution',
456
+ owner: { name: 'liangjie559567' },
457
+ plugins: [{
458
+ name: 'ultrapower',
459
+ description: pkg.description || '',
460
+ version,
461
+ source: { source: 'npm', package: '@liangjie559567/ultrapower', version },
462
+ author: { name: 'liangjie559567' }
463
+ }]
464
+ };
465
+ const marketplaceJsonStr = JSON.stringify(marketplaceJson, null, 2);
466
+
467
+ // 1. Write to install dir
468
+ const localDir = join(pluginRoot, '.claude-plugin');
469
+ mkdirSync(localDir, { recursive: true });
470
+ writeFileSync(join(localDir, 'marketplace.json'), marketplaceJsonStr);
471
+ console.log('[OMC] Wrote .claude-plugin/marketplace.json in install dir');
472
+
473
+ // 2. Write to plugin cache
474
+ const pluginCacheBase = join(CLAUDE_DIR, 'plugins/cache/omc/ultrapower');
475
+ if (existsSync(pluginCacheBase)) {
476
+ const versions = readdirSync(pluginCacheBase);
477
+ for (const v of versions) {
478
+ const cacheDir = join(pluginCacheBase, v, '.claude-plugin');
479
+ mkdirSync(cacheDir, { recursive: true });
480
+ const versionedMkt = { ...marketplaceJson, plugins: [{ ...marketplaceJson.plugins[0], version: v, source: { ...marketplaceJson.plugins[0].source, version: v } }] };
481
+ writeFileSync(join(cacheDir, 'marketplace.json'), JSON.stringify(versionedMkt, null, 2));
482
+ console.log(`[OMC] Wrote .claude-plugin/marketplace.json in plugin cache v${v}`);
483
+ }
484
+ }
485
+ } catch (e) {
486
+ console.log('[OMC] Warning: Could not create .claude-plugin/marketplace.json:', e.message);
487
+ }
488
+ }
489
+
490
+ fixMissingMarketplaceJson();
491
+
393
492
  // 1. Create HUD directory
394
493
  if (!existsSync(HUD_DIR)) {
395
494
  mkdirSync(HUD_DIR, { recursive: true });
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+ // scripts/validate-versions.mjs
3
+ // Validates version consistency across all version-bearing files
4
+
5
+ import { readFileSync } from 'node:fs';
6
+ import { resolve } from 'node:path';
7
+
8
+ const files = [
9
+ { path: 'package.json', extract: (c) => JSON.parse(c).version },
10
+ { path: '.claude-plugin/plugin.json', extract: (c) => JSON.parse(c).version },
11
+ { path: '.claude-plugin/marketplace.json', extract: (c) => JSON.parse(c).plugins?.[0]?.version },
12
+ ];
13
+
14
+ function validateVersions() {
15
+ const versions = new Map();
16
+ const errors = [];
17
+
18
+ for (const { path, extract } of files) {
19
+ try {
20
+ const content = readFileSync(resolve(path), 'utf-8');
21
+ const version = extract(content);
22
+ if (!version) {
23
+ errors.push(`${path}: version not found`);
24
+ continue;
25
+ }
26
+ versions.set(path, version);
27
+ } catch (err) {
28
+ errors.push(`${path}: ${err.message}`);
29
+ }
30
+ }
31
+
32
+ if (errors.length > 0) {
33
+ console.error('Version validation failed:');
34
+ errors.forEach(e => console.error(` - ${e}`));
35
+ process.exit(1);
36
+ }
37
+
38
+ const uniqueVersions = new Set(versions.values());
39
+ if (uniqueVersions.size > 1) {
40
+ console.error('Version mismatch detected:');
41
+ versions.forEach((v, p) => console.error(` ${p}: ${v}`));
42
+ process.exit(1);
43
+ }
44
+
45
+ const version = Array.from(uniqueVersions)[0];
46
+ console.log(`✓ All versions in sync: ${version}`);
47
+ return version;
48
+ }
49
+
50
+ if (import.meta.url.startsWith('file:') && process.argv[1]) {
51
+ validateVersions();
52
+ }
53
+
54
+ export { validateVersions };