@liangjie559567/ultrapower 5.0.19 → 5.0.21

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ultrapower",
3
3
  "description": "Disciplined multi-agent orchestration: workflow enforcement + parallel execution. Combines superpowers' TDD/debugging discipline with OMC's multi-agent execution capabilities.",
4
- "version": "5.0.19",
4
+ "version": "5.0.21",
5
5
  "author": {
6
6
  "name": "Jesse Vincent & oh-my-claudecode contributors"
7
7
  },
package/docs/CLAUDE.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <!-- OMC:START -->
2
- <!-- OMC:VERSION:5.0.19 -->
2
+ <!-- OMC:VERSION:5.0.21 -->
3
3
  # ultrapower - Multi-Agent Orchestration 智能多 Agent 编排
4
4
 
5
5
  你正在使用 ultrapower(OMC),这是 Claude Code 的多 agent 编排层。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liangjie559567/ultrapower",
3
- "version": "5.0.19",
3
+ "version": "5.0.21",
4
4
  "description": "Disciplined multi-agent orchestration: workflow enforcement + parallel execution",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -19,9 +19,12 @@ const SETTINGS_FILE = join(CLAUDE_DIR, 'settings.json');
19
19
 
20
20
  console.log('[OMC] Running post-install setup...');
21
21
 
22
- // Fix: flatten nested cache directories caused by installer wrapping content in plugin-name subdir.
23
- // The installer places npm package contents under cache/.../VERSION/ultrapower/ instead of cache/.../VERSION/
24
- // This function detects and fixes that by moving contents up one level.
22
+ // Fix: flatten nested cache directories caused by Claude Code installer bug.
23
+ // Root cause: xF6(src, dest) copies src contents to dest, but dest is a subdirectory of src.
24
+ // After mkdir -p dest, readdir(src) includes the newly created dest subdir, causing recursive copy.
25
+ // Result: cache/.../VERSION/ultrapower/VERSION/ultrapower/VERSION/... infinite nesting.
26
+ // This function detects and fixes arbitrary-depth nesting by finding the real plugin content
27
+ // and moving it up to the version directory, then removing all nested dirs.
25
28
  function fixNestedCacheDir() {
26
29
  try {
27
30
  const pluginCacheBase = join(CLAUDE_DIR, 'plugins/cache/ultrapower/ultrapower');
@@ -31,25 +34,51 @@ function fixNestedCacheDir() {
31
34
  const versionDir = join(pluginCacheBase, version);
32
35
  const nestedDir = join(versionDir, 'ultrapower');
33
36
  if (!existsSync(nestedDir)) continue;
34
- // Check if the nested dir itself has the actual plugin content (skills/, dist/, etc.)
35
- const nestedContents = readdirSync(nestedDir);
36
- // If nested dir is empty (leftover from previous fix), just remove it
37
- if (nestedContents.length === 0) {
38
- rmSync(nestedDir, { recursive: true, force: true });
39
- console.log(`[OMC] Removed empty nested dir for version ${version}`);
40
- continue;
37
+
38
+ // Walk down the nesting to find the real plugin content (arbitrary depth)
39
+ // Real content has skills/, dist/, agents/, or hooks/ directly inside
40
+ const PLUGIN_MARKERS = ['skills', 'dist', 'agents', 'hooks'];
41
+ let realContentDir = null;
42
+ let searchDir = nestedDir;
43
+ let depth = 0;
44
+ while (depth < 20) {
45
+ const contents = readdirSync(searchDir);
46
+ if (contents.length === 0) {
47
+ // Empty dir - just remove it
48
+ rmSync(nestedDir, { recursive: true, force: true });
49
+ console.log(`[OMC] Removed empty nested dir for version ${version}`);
50
+ break;
51
+ }
52
+ if (contents.some(f => PLUGIN_MARKERS.includes(f))) {
53
+ realContentDir = searchDir;
54
+ break;
55
+ }
56
+ // Go deeper: look for ultrapower/ or version/ subdir
57
+ const nextDir = join(searchDir, 'ultrapower');
58
+ const nextVerDir = join(searchDir, version);
59
+ if (existsSync(nextDir)) {
60
+ searchDir = nextDir;
61
+ } else if (existsSync(nextVerDir)) {
62
+ searchDir = nextVerDir;
63
+ } else {
64
+ break;
65
+ }
66
+ depth++;
41
67
  }
42
- const hasPluginContent = nestedContents.some(f => ['skills', 'dist', 'agents', 'hooks'].includes(f));
43
- if (!hasPluginContent) continue;
44
- console.log(`[OMC] Fixing nested cache dir for version ${version}...`);
45
- // Move contents of nestedDir up to versionDir, then remove nestedDir
46
- for (const item of nestedContents) {
47
- const src = join(nestedDir, item);
68
+
69
+ if (!realContentDir) continue;
70
+
71
+ console.log(`[OMC] Fixing nested cache dir for version ${version} (depth ${depth})...`);
72
+ // Move contents of realContentDir up to versionDir
73
+ const realContents = readdirSync(realContentDir);
74
+ for (const item of realContents) {
75
+ const src = join(realContentDir, item);
48
76
  const dest = join(versionDir, item);
49
77
  if (!existsSync(dest)) {
50
78
  renameSync(src, dest);
51
79
  }
52
80
  }
81
+ // Remove the entire nested ultrapower/ subtree
53
82
  rmSync(nestedDir, { recursive: true, force: true });
54
83
  console.log(`[OMC] Fixed nested cache dir for version ${version}`);
55
84
  }
@@ -71,6 +71,36 @@ if(f.existsSync(npmCachePkg)){
71
71
  - `MISMATCH: dir=X pkg.version=Y`:严重错误——npm-cache 复用导致旧内容被安装到新版本目录
72
72
  - npm-cache range 显示旧版本范围(如 `^5.0.11`):警告——下次安装仍会复用旧缓存
73
73
 
74
+ ### 第一步 ter:检查无限嵌套缓存目录
75
+
76
+ 检查插件缓存目录是否存在无限嵌套(Claude Code 安装器 `xF6` bug 导致):
77
+
78
+ ```bash
79
+ node -e "
80
+ const p=require('path'),f=require('fs'),h=require('os').homedir();
81
+ const d=process.env.CLAUDE_CONFIG_DIR||p.join(h,'.claude');
82
+ const b=p.join(d,'plugins','cache','ultrapower','ultrapower');
83
+ try {
84
+ const vs=f.readdirSync(b).filter(x=>/^\d/.test(x));
85
+ let found=false;
86
+ for(const v of vs){
87
+ const nested=p.join(b,v,'ultrapower');
88
+ if(f.existsSync(nested)){
89
+ console.log('CRITICAL: nested dir found: '+nested);
90
+ found=true;
91
+ }
92
+ }
93
+ if(!found) console.log('OK: no nested ultrapower/ dirs found');
94
+ } catch(e){console.log('Cache not found (normal if not installed)');}
95
+ "
96
+ ```
97
+
98
+ **诊断**:
99
+ - `CRITICAL: nested dir found`:严重错误——安装器 `xF6` bug 导致无限嵌套,插件内容可能损坏
100
+ - 根本原因:`xF6(src, dest)` 先 `mkdir -p dest`,再 `readdir(src)`;因 `dest` 是 `src` 子目录,readdir 包含刚创建的子目录,递归复制时把自身复制进去
101
+ - 加剧因素:`PM1()` 检测目标非空则跳过复制,嵌套一旦产生安装器永远不会自动修复
102
+ - 自动修复:5.0.20+ 的 `postinstall` 脚本会自动检测并修复任意深度嵌套
103
+
74
104
  ### 第二步:检查 settings.json 中的旧版 hook
75
105
 
76
106
  读取 `~/.claude/settings.json`(用户级)和 `./.claude/settings.json`(项目级),检查是否存在包含以下条目的 `"hooks"` 键:
@@ -157,6 +187,7 @@ ls -la ~/.claude/skills/ 2>/dev/null
157
187
  |-------|--------|---------|
158
188
  | 插件版本 | OK/WARN/CRITICAL | ... |
159
189
  | npm-cache 复用 | OK/WARN/CRITICAL | ... |
190
+ | 无限嵌套缓存 | OK/CRITICAL | ... |
160
191
  | 旧版 Hook (settings.json) | OK/CRITICAL | ... |
161
192
  | 旧版脚本 (~/.claude/hooks/) | OK/WARN | ... |
162
193
  | CLAUDE.md | OK/WARN/CRITICAL | ... |
@@ -198,6 +229,21 @@ rm -f ~/.claude/hooks/stop-continuation.sh
198
229
  node -e "const p=require('path'),f=require('fs'),d=process.env.CLAUDE_CONFIG_DIR||p.join(require('os').homedir(),'.claude'),b=p.join(d,'plugins','cache','omc','ultrapower');try{f.rmSync(b,{recursive:true,force:true});console.log('Plugin cache cleared. Restart Claude Code to fetch latest version.')}catch{console.log('No plugin cache found')}"
199
230
  ```
200
231
 
232
+ ### 修复:无限嵌套缓存目录
233
+
234
+ 症状:`versionDir/ultrapower/` 子目录存在,插件内容可能损坏。
235
+
236
+ ```bash
237
+ # 完整清洁重装(5.0.20+ postinstall 会自动修复残留嵌套)
238
+ claude plugin uninstall ultrapower
239
+ rm -rf ~/.claude/plugins/npm-cache
240
+ rm -rf ~/.claude/plugins/cache/ultrapower
241
+ claude plugin marketplace update ultrapower
242
+ claude plugin install ultrapower
243
+ ```
244
+
245
+ > ✅ 安装 5.0.20+ 后,`postinstall` 脚本会自动检测并修复任意深度嵌套,无需手动干预。
246
+
201
247
  ### 修复:npm-cache 复用(插件内容是旧版本)
202
248
 
203
249
  症状:插件缓存目录版本号与 `package.json` 内 `version` 字段不一致。
@@ -128,26 +128,33 @@ ls ~/.claude/plugins/cache/ultrapower/ultrapower/<version>/skills/
128
128
 
129
129
  症状:`cache/ultrapower/ultrapower/5.x.x/ultrapower/5.x.x/ultrapower/...`
130
130
 
131
- 原因:npm 包中包含了 `ultrapower/` 子目录(通常是缓存目录被打包进去)。
131
+ **根本原因(已确认)**:Claude Code 安装器的 `xF6(src, dest)` 函数存在 bug:
132
+ 1. 先执行 `mkdir -p dest`(`dest = cache/ultrapower/ultrapower/5.x.x`)
133
+ 2. 再执行 `readdir(src)`(`src = cache/ultrapower`)
134
+ 3. 由于 `dest` 是 `src` 的子目录,`readdir` 结果包含刚创建的 `ultrapower/` 子目录
135
+ 4. 递归复制时把自身也复制进去,产生无限嵌套
132
136
 
133
- 修复步骤:
134
- ```bash
135
- # 1. 卸载插件
136
- claude plugin uninstall ultrapower
137
+ **加剧因素**:`PM1()` 检查目标目录是否非空,非空则跳过复制(认为已缓存)。一旦嵌套产生,安装器永远不会自动修复。
137
138
 
138
- # 2. 清除缓存
139
+ **自动修复**:5.0.20+ 的 `postinstall` 脚本(`fixNestedCacheDir()`)会自动检测并修复任意深度嵌套。
140
+
141
+ 手动修复步骤:
142
+ ```bash
143
+ # 1. 清除嵌套的缓存目录
139
144
  rm -rf ~/.claude/plugins/cache/ultrapower
140
- rm -rf ~/.claude/plugins/marketplaces/ultrapower
141
145
 
142
- # 3. 确认 .npmignore 已排除 ultrapower/ 目录
146
+ # 2. 清除 npm-cache(防止复用旧内容)
147
+ rm -rf ~/.claude/plugins/npm-cache
143
148
 
144
- # 4. 重新发布(需升级版本号)
145
- npm publish --access public
149
+ # 3. 刷新 marketplace 缓存
150
+ claude plugin marketplace update ultrapower
146
151
 
147
- # 5. 重新安装
152
+ # 4. 重新安装(postinstall 会自动修复任何残留嵌套)
148
153
  claude plugin install ultrapower
149
154
  ```
150
155
 
156
+ > ⚠️ `.npmignore` 中的 `ultrapower/` 排除项仍然必要,防止开发目录被打包进 npm 包。
157
+
151
158
  ### 安装后仍是旧版本
152
159
 
153
160
  原因:本地 marketplace 缓存未更新,安装器读取的是旧版 `marketplace.json`。