ai-global 2.6.0 → 2.7.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 (3) hide show
  1. package/README.md +40 -36
  2. package/ai-global +104 -96
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,13 +1,19 @@
1
1
  # AI Global
2
2
 
3
- English | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [日本語](README_JP.md) | [한국어](README_KR.md)
3
+ English · [简体中文](README_CN.md) · [繁體中文](README_TW.md) · [日本語](README_JP.md)· [한국어](README_KR.md)
4
4
 
5
- Unified configuration manager for AI coding assistants. Edit one file, sync to all your AI tools.
5
+ ---
6
6
 
7
- Works both **System Mode** and **Project Mode**!
7
+ **Unified Configuration Manager for AI Coding Tools.**
8
+
9
+ Edit one file, sync to all your AI tools.
10
+
11
+ Works both **System Mode** & **Project Mode**.
8
12
 
9
13
  ## Installation
10
14
 
15
+ Install with `curl` or `npm`:
16
+
11
17
  ### curl
12
18
 
13
19
  ```bash
@@ -46,7 +52,7 @@ This will:
46
52
  1. Detect current directory (system or project)
47
53
  2. Scan for installed AI tools
48
54
  3. Backup original configs to `.ai-global/backups/`
49
- 4. Merge AGENTS.md/skills/agents/rules/commands from detected tools
55
+ 4. Merge AGENTS.md/skills/rules/commands from detected tools
50
56
  5. Create symlinks from each tool's config to shared directories
51
57
 
52
58
  ## Commands
@@ -84,7 +90,6 @@ Skills will be downloaded and added to your `.ai-global/skills/` directory.
84
90
  ~/.ai-global/
85
91
  ├── AGENTS.md <- Shared AGENTS.md (edit this)
86
92
  ├── skills/ <- Shared skills (merged from all tools)
87
- ├── agents/ <- Shared agents
88
93
  ├── rules/ <- Shared rules
89
94
  ├── commands/ <- Shared slash commands
90
95
  └── backups/ <- Original configs (backups)
@@ -108,7 +113,6 @@ my-project/
108
113
  ├── .ai-global/ <- Project-specific configs
109
114
  │ ├── AGENTS.md <- Project AGENTS.md
110
115
  │ ├── skills/ <- Project skills
111
- │ ├── agents/ <- Project agents
112
116
  │ ├── rules/ <- Project rules
113
117
  │ ├── commands/ <- Project commands
114
118
  │ └── backups/ <- Project backups
@@ -119,8 +123,8 @@ my-project/
119
123
 
120
124
  ### Mode Behavior
121
125
 
122
- - **System Mode**: Manages AI configurations across your entire system
123
- - **Project Mode**: Manages AI configurations for a specific project only
126
+ - **System Mode**: Manages AI configs across your entire system
127
+ - **Project Mode**: Manages AI configs for a specific project only
124
128
  - **Automatic Detection**: No commands needed to switch between modes
125
129
  - **Context-Aware**: Commands will show which context they're operating in
126
130
 
@@ -136,34 +140,34 @@ When you run `ai-global`, it merges items from all tools by filename:
136
140
 
137
141
  ## Supported Tools
138
142
 
139
- | Tool | Key | AGENTS.md | Rules | Commands | Skills | Agents |
140
- | -------------- | ------------- | :-------: | :---: | :------: | :----: | :----: |
141
- | Claude Code | `claude` | ✓ | | ✓ | ✓ | ✓ |
142
- | OpenAI Codex | `codex` | ✓ | ✓ | | ✓ | ✓ |
143
- | Cursor | `cursor` | ✓ | ✓ | ✓ | ✓ | ✓ |
144
- | Factory Droid | `droid` | ✓ | ✓ | ✓ | ✓ | ✓ |
145
- | Amp | `amp` | ✓ | ✓ | ✓ | ✓ | |
146
- | Antigravity | `antigravity` | ✓ | | | ✓ | |
147
- | Gemini CLI | `gemini` | ✓ | | | ✓ | |
148
- | Kiro CLI | `kiro` | ✓ | ✓ | | ✓ | ✓ |
149
- | OpenCode | `opencode` | ✓ | | ✓ | ✓ | ✓ |
150
- | Qoder | `qoder` | ✓ | ✓ | ✓ | ✓ | ✓ |
151
- | Qodo | `qodo` | ✓ | | | | ✓ |
152
- | GitHub Copilot | `copilot` | ✓ | | | ✓ | ✓ |
153
- | Continue | `continue` | ✓ | ✓ | | | |
154
- | Windsurf | `windsurf` | ✓ | ✓ | | ✓ | |
155
- | Roo Code | `roo` | ✓ | ✓ | ✓ | ✓ | |
156
- | Cline | `cline` | ✓ | ✓ | | ✓ | |
157
- | Blackbox AI | `blackbox` | | | | ✓ | |
158
- | Goose AI | `goose` | ✓ | | | ✓ | |
159
- | Augment | `augment` | ✓ | ✓ | ✓ | | ✓ |
160
- | Clawdbot Code | `clawdbot` | ✓ | | | ✓ | ✓ |
161
- | Command Code | `commandcode` | ✓ | | ✓ | ✓ | |
162
- | Kilo Code | `kilocode` | ✓ | ✓ | ✓ | ✓ | |
163
- | Neovate | `neovate` | ✓ | | ✓ | ✓ | ✓ |
164
- | OpenHands | `openhands` | ✓ | | | ✓ | |
165
- | TRAE | `trae` | ✓ | ✓ | | ✓ | |
166
- | Zencoder | `zencoder` | ✓ | ✓ | | ✓ | |
143
+ | Tool | Key | AGENTS.md | Rules | Commands | Skills |
144
+ | -------------- | ------------- | :-------: | :---: | :------: | :----: |
145
+ | Claude Code | `claude` | ✓ | | ✓ | ✓ |
146
+ | OpenAI Codex | `codex` | ✓ | ✓ | | ✓ |
147
+ | Cursor | `cursor` | ✓ | ✓ | ✓ | ✓ |
148
+ | Factory Droid | `droid` | ✓ | ✓ | ✓ | ✓ |
149
+ | Amp | `amp` | ✓ | ✓ | ✓ | ✓ |
150
+ | Antigravity | `antigravity` | ✓ | | | ✓ |
151
+ | Gemini CLI | `gemini` | ✓ | | | ✓ |
152
+ | Kiro CLI | `kiro` | ✓ | ✓ | | ✓ |
153
+ | OpenCode | `opencode` | ✓ | | ✓ | ✓ |
154
+ | Qoder | `qoder` | ✓ | ✓ | ✓ | ✓ |
155
+ | Qodo | `qodo` | ✓ | | | |
156
+ | GitHub Copilot | `copilot` | ✓ | | | ✓ |
157
+ | Continue | `continue` | ✓ | ✓ | | |
158
+ | Windsurf | `windsurf` | ✓ | ✓ | | ✓ |
159
+ | Roo Code | `roo` | ✓ | ✓ | ✓ | ✓ |
160
+ | Cline | `cline` | ✓ | ✓ | | ✓ |
161
+ | Blackbox AI | `blackbox` | | | | ✓ |
162
+ | Goose AI | `goose` | ✓ | | | ✓ |
163
+ | Augment | `augment` | ✓ | ✓ | ✓ | |
164
+ | Clawdbot Code | `clawdbot` | ✓ | | | ✓ |
165
+ | Command Code | `commandcode` | ✓ | | ✓ | ✓ |
166
+ | Kilo Code | `kilocode` | ✓ | ✓ | ✓ | ✓ |
167
+ | Neovate | `neovate` | ✓ | | ✓ | ✓ |
168
+ | OpenHands | `openhands` | ✓ | | | ✓ |
169
+ | TRAE | `trae` | ✓ | ✓ | | ✓ |
170
+ | Zencoder | `zencoder` | ✓ | ✓ | | ✓ |
167
171
 
168
172
  ## Uninstall
169
173
 
package/ai-global CHANGED
@@ -4,37 +4,37 @@
4
4
  # https://github.com/nanxiaobei/ai-global
5
5
 
6
6
  # Version
7
- VERSION="2.6.0"
7
+ VERSION="2.7.0"
8
8
 
9
9
  # Known AI tool patterns
10
- # Format: nodes|key|name|agents_md|rules|commands|skills|subagents|color
10
+ # Format: nodes|key|name|agents_md|rules|commands|skills|color
11
11
  declare -a KNOWN_PATTERNS=(
12
- ".amp|amp|Amp|AGENTS.md|rules|commands|skills|.|\\033[38;5;226m"
13
- ".augment|augment|Augment|AGENTS.md|rules|commands|.|agents|\\033[38;5;46m"
14
- ".blackbox|blackbox|Blackbox AI|.|.|.|skills|.|\\033[38;5;51m"
15
- ".claude|claude|Claude Code|CLAUDE.md|.|commands|skills|agents|\\033[38;5;180m"
16
- ".cline|cline|Cline|AGENTS.md|rules|.|skills|.|\\033[38;5;201m"
17
- ".clawdbot|clawdbot|Clawdbot Code|AGENTS.md|.|.|skills|subagents|\\033[38;5;208m"
18
- ".codex|codex|OpenAI Codex|AGENTS.md|rules|.|skills|agents|\\033[38;5;9m"
19
- ".commandcode|commandcode|Command Code|AGENTS.md|.|.|skills|.|\\033[38;5;11m"
20
- ".continue|continue|Continue|AGENTS.md|rules|.|.|.|\\033[38;5;10m"
21
- ".copilot|copilot|GitHub Copilot|AGENTS.md|.|.|skills|agents|\\033[38;5;14m"
22
- ".cursor|cursor|Cursor|AGENTS.md|rules|commands|skills|agents|\\033[38;5;12m"
23
- ".factory|droid|Factory Droid|AGENTS.md|rules|commands|skills|droids|\\033[38;5;13m"
24
- ".gemini|antigravity|Antigravity|GEMINI.md|.|.|antigravity/skills|.|\\033[38;5;214m"
25
- ".gemini|gemini|Gemini CLI|GEMINI.md|.|.|skills|.|\\033[38;5;220m"
26
- ".goose|goose|Goose AI|AGENTS.md|.|.|skills|.|\\033[38;5;82m"
27
- ".kiro|kiro|Kiro CLI|AGENTS.md|steering|.|skills|agents|\\033[38;5;117m"
28
- ".kilocode|kilocode|Kilo Code|AGENTS.md|rules|commands|skills|.|\\033[38;5;165m"
29
- ".neovate|neovate|Neovate|AGENTS.md|.|commands|skills|agents|\\033[38;5;118m"
30
- ".opencode, .config/opencode|opencode|OpenCode|AGENTS.md|.|commands|skills|agents|\\033[38;5;225m"
31
- ".openhands|openhands|OpenHands|AGENTS.md|.|.|skills|.|\\033[38;5;39m"
32
- ".qodo|qodo|Qodo|AGENTS.md|.|.|.|agents|\\033[38;5;129m"
33
- ".qoder|qoder|Qoder|AGENTS.md|rules|commands|skills|agents|\\033[38;5;203m"
34
- ".roo|roo|Roo Code|AGENTS.md|rules|commands|skills|.|\\033[38;5;77m"
35
- ".trae|trae|TRAE|AGENTS.md|rules|.|skills|.|\\033[38;5;215m"
36
- ".windsurf, .codeium/windsurf|windsurf|Windsurf|AGENTS.md|rules|.|skills|.|\\033[38;5;159m"
37
- ".zencoder|zencoder|Zencoder|AGENTS.md|rules|.|skills|.|\\033[38;5;147m"
12
+ ".amp|amp|Amp|AGENTS.md|rules|commands|skills|\\033[38;5;226m"
13
+ ".augment|augment|Augment|AGENTS.md|rules|commands|.|\\033[38;5;46m"
14
+ ".blackbox|blackbox|Blackbox AI|.|.|.|skills|\\033[38;5;51m"
15
+ ".claude|claude|Claude Code|CLAUDE.md|.|commands|skills|\\033[38;5;180m"
16
+ ".cline|cline|Cline|AGENTS.md|rules|.|skills|\\033[38;5;201m"
17
+ ".clawdbot|clawdbot|Clawdbot Code|AGENTS.md|.|.|skills|\\033[38;5;208m"
18
+ ".codex|codex|OpenAI Codex|AGENTS.md|rules|.|skills|\\033[38;5;9m"
19
+ ".commandcode|commandcode|Command Code|AGENTS.md|.|.|skills|\\033[38;5;11m"
20
+ ".continue|continue|Continue|AGENTS.md|rules|.|.|\\033[38;5;10m"
21
+ ".copilot|copilot|GitHub Copilot|AGENTS.md|.|.|skills|\\033[38;5;14m"
22
+ ".cursor|cursor|Cursor|AGENTS.md|rules|commands|skills|\\033[38;5;12m"
23
+ ".factory|droid|Factory Droid|AGENTS.md|rules|commands|skills|\\033[38;5;13m"
24
+ ".gemini|antigravity|Antigravity|GEMINI.md|.|.|antigravity/skills|\\033[38;5;214m"
25
+ ".gemini|gemini|Gemini CLI|GEMINI.md|.|.|skills|\\033[38;5;220m"
26
+ ".goose|goose|Goose AI|AGENTS.md|.|.|skills|\\033[38;5;82m"
27
+ ".kiro|kiro|Kiro CLI|AGENTS.md|steering|.|skills|\\033[38;5;117m"
28
+ ".kilocode|kilocode|Kilo Code|AGENTS.md|rules|commands|skills|\\033[38;5;165m"
29
+ ".neovate|neovate|Neovate|AGENTS.md|.|commands|skills|\\033[38;5;118m"
30
+ ".opencode, .config/opencode|opencode|OpenCode|AGENTS.md|.|commands|skills|\\033[38;5;225m"
31
+ ".openhands|openhands|OpenHands|AGENTS.md|.|.|skills|\\033[38;5;39m"
32
+ ".qodo|qodo|Qodo|AGENTS.md|.|.|.|\\033[38;5;129m"
33
+ ".qoder|qoder|Qoder|AGENTS.md|rules|commands|skills|\\033[38;5;203m"
34
+ ".roo|roo|Roo Code|AGENTS.md|rules|commands|skills|\\033[38;5;77m"
35
+ ".trae|trae|TRAE|AGENTS.md|rules|.|skills|\\033[38;5;215m"
36
+ ".windsurf, .codeium/windsurf|windsurf|Windsurf|AGENTS.md|rules|.|skills|\\033[38;5;159m"
37
+ ".zencoder|zencoder|Zencoder|AGENTS.md|rules|.|skills|\\033[38;5;147m"
38
38
  )
39
39
 
40
40
  # Colors
@@ -88,7 +88,6 @@ update_links() {
88
88
  local rules_dir="$base_dir/.ai-global/rules"
89
89
  local commands_dir="$base_dir/.ai-global/commands"
90
90
  local skills_dir="$base_dir/.ai-global/skills"
91
- local subagents_dir="$base_dir/.ai-global/agents"
92
91
  local backups_dir="$base_dir/.ai-global/backups"
93
92
 
94
93
  local total_tools=0
@@ -117,10 +116,10 @@ update_links() {
117
116
  fi
118
117
 
119
118
  # Create directories
120
- mkdir -p "$rules_dir" "$commands_dir" "$skills_dir" "$subagents_dir" "$backups_dir"
119
+ mkdir -p "$rules_dir" "$commands_dir" "$skills_dir" "$backups_dir"
121
120
 
122
121
  for pattern in "${KNOWN_PATTERNS[@]}"; do
123
- IFS='|' read -r nodes key name agents_md rules commands skills subagents color <<< "$pattern"
122
+ IFS='|' read -r nodes key name agents_md rules commands skills color <<< "$pattern"
124
123
  IFS=', ' read -ra node_array <<< "$nodes"
125
124
 
126
125
  for tool_node in "${node_array[@]}"; do
@@ -132,7 +131,7 @@ update_links() {
132
131
  echo ""
133
132
  echo -e "${GREEN}[OK]${NC} ${color}Found: $name${NC}"
134
133
 
135
- local types=("file:$agents_md:$agents_md_dir" "dir:$rules:$rules_dir" "dir:$commands:$commands_dir" "dir:$skills:$skills_dir" "dir:$subagents:$subagents_dir")
134
+ local types=("file:$agents_md:$agents_md_dir" "dir:$rules:$rules_dir" "dir:$commands:$commands_dir" "dir:$skills:$skills_dir")
136
135
 
137
136
  for type_info in "${types[@]}"; do
138
137
  IFS=':' read -r type_key type_node target_dir <<< "$type_info"
@@ -158,9 +157,14 @@ update_links() {
158
157
  echo "" >> "$target_dir"
159
158
  fi
160
159
  else
161
- # Copy all files (overwrite if exists)
162
- find "$type_dir" -type f -print0 2> /dev/null | while IFS= read -r -d '' file_dir; do
163
- local target_file="$target_dir/${file_dir#$type_dir/}"
160
+ # Copy all files (overwrite if exists), excluding hidden files and files in hidden dirs
161
+ find "$type_dir" -type f -not -name '.*' -print0 2> /dev/null | while IFS= read -r -d '' file_dir; do
162
+ local rel_path="${file_dir#$type_dir/}"
163
+ # Skip if path contains any hidden directory component (at start or after /)
164
+ if [[ "$rel_path" =~ (^|/)\.[^/]+(/|$) ]]; then
165
+ continue
166
+ fi
167
+ local target_file="$target_dir/$rel_path"
164
168
  mkdir -p "$(dirname "$target_file")" 2> /dev/null
165
169
  cp "$file_dir" "$target_file" 2> /dev/null || true
166
170
  done
@@ -192,7 +196,7 @@ update_links() {
192
196
 
193
197
  # Check if any tools were found
194
198
  if [[ $total_tools -eq 0 ]]; then
195
- log_info "No AI tool configurations found"
199
+ log_info "No AI tool configs found"
196
200
  # Remove empty .ai-global directory
197
201
  rm -rf "$base_dir/.ai-global" 2> /dev/null
198
202
  echo ""
@@ -247,17 +251,16 @@ show_status() {
247
251
  local rules_output=""
248
252
  local commands_output=""
249
253
  local skills_output=""
250
- local subagents_output=""
251
254
 
252
255
  for pattern in "${KNOWN_PATTERNS[@]}"; do
253
- IFS='|' read -r nodes key name agents_md rules commands skills subagents color <<< "$pattern"
256
+ IFS='|' read -r nodes key name agents_md rules commands skills color <<< "$pattern"
254
257
  IFS=', ' read -ra node_array <<< "$nodes"
255
258
 
256
259
  for tool_node in "${node_array[@]}"; do
257
260
  local tool_dir="$base_dir/$tool_node"
258
261
 
259
262
  if [[ -d "$tool_dir" ]]; then
260
- local types=("$agents_md:agents_md_output" "$rules:rules_output" "$commands:commands_output" "$skills:skills_output" "$subagents:subagents_output")
263
+ local types=("$agents_md:agents_md_output" "$rules:rules_output" "$commands:commands_output" "$skills:skills_output")
261
264
 
262
265
  for type_info in "${types[@]}"; do
263
266
  IFS=':' read -r type_node output_var <<< "$type_info"
@@ -273,7 +276,7 @@ show_status() {
273
276
  return
274
277
  fi
275
278
 
276
- local types=("AGENTS.md:$agents_md_output" "rules:$rules_output" "commands:$commands_output" "skills:$skills_output" "agents:$subagents_output")
279
+ local types=("AGENTS.md:$agents_md_output" "rules:$rules_output" "commands:$commands_output" "skills:$skills_output")
277
280
 
278
281
  for type_info in "${types[@]}"; do
279
282
  IFS=':' read -r title content <<< "$type_info"
@@ -289,11 +292,11 @@ list_tools() {
289
292
  local base_dir=$(pwd)
290
293
  log_context_info "$base_dir"
291
294
 
292
- echo -e " ${BLUE}Tool Key Directory AGENTS.md Rules Commands Skills Agents Status${NC}"
293
- echo -e " ${BLUE}-----------------------------------------------------------------------------------------------------------${NC}"
295
+ echo -e " ${BLUE}Tool Key Directory AGENTS.md Rules Commands Skills Status${NC}"
296
+ echo -e " ${BLUE}-------------------------------------------------------------------------------------------------------${NC}"
294
297
 
295
298
  for pattern in "${KNOWN_PATTERNS[@]}"; do
296
- IFS='|' read -r nodes key name agents_md rules commands skills subagents color <<< "$pattern"
299
+ IFS='|' read -r nodes key name agents_md rules commands skills color <<< "$pattern"
297
300
  IFS=', ' read -ra node_array <<< "$nodes"
298
301
 
299
302
  local row_color="${GRAY}"
@@ -324,7 +327,7 @@ list_tools() {
324
327
  local nodes_pad=" "
325
328
  nodes_pad="${nodes_pad:0:$nodes_spaces}"
326
329
 
327
- echo -e " ${row_color}${name}${name_pad}${key}${key_spacing}${nodes}${nodes_pad} $([[ "$agents_md" == "." ]] && echo "." || echo "○") $([[ "$rules" == "." ]] && echo "." || echo "○") $([[ "$commands" == "." ]] && echo "." || echo "○") $([[ "$skills" == "." ]] && echo "." || echo "○") $([[ "$subagents" == "." ]] && echo "." || echo "○") ${status}${NC}"
330
+ echo -e " ${row_color}${name}${name_pad}${key}${key_spacing}${nodes}${nodes_pad} $([[ "$agents_md" == "." ]] && echo "." || echo "○") $([[ "$rules" == "." ]] && echo "." || echo "○") $([[ "$commands" == "." ]] && echo "." || echo "○") $([[ "$skills" == "." ]] && echo "." || echo "○") ${status}${NC}"
328
331
  done
329
332
  echo ""
330
333
  }
@@ -362,12 +365,11 @@ unlink_one_tool() {
362
365
  local rules="$4"
363
366
  local commands="$5"
364
367
  local skills="$6"
365
- local subagents="$7"
366
- local color="$8"
368
+ local color="$7"
367
369
 
368
370
  local unlinked_count=0
369
371
 
370
- for type_node in "$agents_md" "$rules" "$commands" "$skills" "$subagents"; do
372
+ for type_node in "$agents_md" "$rules" "$commands" "$skills"; do
371
373
  if [[ "$type_node" != "." ]]; then
372
374
  local type_dir="$base_dir/$tool_node/$type_node"
373
375
  if [[ -L "$type_dir" ]]; then
@@ -401,14 +403,14 @@ unlink_all_tools() {
401
403
  local total_unlinked=0
402
404
 
403
405
  for pattern in "${KNOWN_PATTERNS[@]}"; do
404
- IFS='|' read -r nodes key name agents_md rules commands skills subagents color <<< "$pattern"
406
+ IFS='|' read -r nodes key name agents_md rules commands skills color <<< "$pattern"
405
407
  IFS=', ' read -ra node_array <<< "$nodes"
406
408
 
407
409
  for tool_node in "${node_array[@]}"; do
408
410
  local tool_dir="$base_dir/$tool_node"
409
411
 
410
412
  if [[ -d "$tool_dir" ]]; then
411
- unlink_one_tool "$base_dir" "$tool_node" "$agents_md" "$rules" "$commands" "$skills" "$subagents" "$color"
413
+ unlink_one_tool "$base_dir" "$tool_node" "$agents_md" "$rules" "$commands" "$skills" "$color"
412
414
  total_unlinked=$((total_unlinked + $?))
413
415
  fi
414
416
  done
@@ -442,7 +444,7 @@ unlink_tool() {
442
444
  # Find pattern by searching KNOWN_PATTERNS
443
445
  local match=""
444
446
  for pattern in "${KNOWN_PATTERNS[@]}"; do
445
- IFS='|' read -r nodes key name agents_md rules commands skills subagents color <<< "$pattern"
447
+ IFS='|' read -r nodes key name agents_md rules commands skills color <<< "$pattern"
446
448
  if [[ "$key" == "$query_key" ]]; then
447
449
  match="$pattern"
448
450
  break
@@ -462,7 +464,7 @@ unlink_tool() {
462
464
  local has_found=false
463
465
 
464
466
  # Parse pattern and unlink tool
465
- IFS='|' read -r nodes key name agents_md rules commands skills subagents color <<< "$match"
467
+ IFS='|' read -r nodes key name agents_md rules commands skills color <<< "$match"
466
468
  IFS=', ' read -ra node_array <<< "$nodes"
467
469
 
468
470
  for tool_node in "${node_array[@]}"; do
@@ -470,7 +472,7 @@ unlink_tool() {
470
472
 
471
473
  if [[ -d "$tool_dir" ]]; then
472
474
  has_found=true
473
- unlink_one_tool "$base_dir" "$tool_node" "$agents_md" "$rules" "$commands" "$skills" "$subagents" "$color"
475
+ unlink_one_tool "$base_dir" "$tool_node" "$agents_md" "$rules" "$commands" "$skills" "$color"
474
476
  local unlinked_count=$?
475
477
  if [[ $unlinked_count -gt 0 ]]; then
476
478
  log_ok "Unlinked $unlinked_count symlinks from ${color}$(beautify_dir "$tool_dir")${NC}"
@@ -549,49 +551,55 @@ download_from_github() {
549
551
 
550
552
  if [[ -d "$source_node" ]]; then
551
553
  local meta_file="SKILL.md"
554
+ local processed_dirs=()
555
+ local has_root_skill=false
552
556
 
553
- # 1. Check if root contains metadata file
557
+ # First check if root has SKILL.md
554
558
  if [[ -f "$source_node/$meta_file" ]]; then
559
+ has_root_skill=true
555
560
  local name=$(extract_meta_name "$source_node/$meta_file" "$(basename "$source_node")")
556
- local file_dir="$skills_dir/$name"
557
- mkdir -p "$file_dir"
558
- cp -R "$source_node"/* "$file_dir/"
561
+ mkdir -p "$skills_dir/$name"
562
+ # Copy files excluding: hidden (.), README.md*, LICENSE*
563
+ for item in "$source_node"/*; do
564
+ [[ ! -e "$item" ]] && continue
565
+ local item_name=$(basename "$item")
566
+ # Skip hidden files, README.md, LICENSE
567
+ [[ "$item_name" == .* ]] && continue
568
+ [[ "$item_name" == README.md* ]] && continue
569
+ [[ "$item_name" == LICENSE* ]] && continue
570
+ cp -R "$item" "$skills_dir/$name/" 2> /dev/null || true
571
+ done
572
+ echo " - $name"
559
573
  skills_count=1
560
574
  fi
561
575
 
562
- # 2. Check skills/ subdirectories
563
- if [[ $skills_count -eq 0 ]] && [[ -z "$path" ]]; then
564
- for dir in skills skill; do
565
- if [[ -d "$source_node/$dir" ]]; then
566
- # Search subdirectories containing SKILL.md
567
- for d in "$source_node/$dir"/*; do
568
- [[ ! -d "$d" ]] && continue
569
- if [[ -f "$d/$meta_file" ]]; then
570
- local name=$(extract_meta_name "$d/$meta_file" "$(basename "$d")")
571
- mkdir -p "$skills_dir/$name"
572
- cp -R "$d"/* "$skills_dir/$name/"
573
- echo " - $name"
574
- ((skills_count++))
575
- fi
576
- done
577
- fi
576
+ # Only check subdirectories if root doesn't have SKILL.md
577
+ if [[ "$has_root_skill" == false ]]; then
578
+ while IFS= read -r -d '' skill_file; do
579
+ local skill_parent=$(dirname "$skill_file")
580
+ local dir_name=$(basename "$skill_parent")
578
581
 
579
- # If we found items, we are done with this dir
580
- if [[ $skills_count -gt 0 ]]; then
581
- source_node="$source_node/$dir"
582
- break
583
- fi
584
- done
585
- fi
582
+ # Skip hidden directories
583
+ [[ "$dir_name" == .* ]] && continue
584
+
585
+ # Skip if already processed
586
+ local already_processed=false
587
+ for processed in "${processed_dirs[@]}"; do
588
+ [[ "$processed" == "$skill_parent" ]] && already_processed=true && break
589
+ done
590
+ [[ "$already_processed" == true ]] && continue
586
591
 
587
- # 3. Check src/ directory if still nothing
588
- if [[ $skills_count -eq 0 ]] && [[ -d "$source_node/src" ]]; then
589
- if [[ -f "$source_node/src/$meta_file" ]]; then
590
- local name=$(extract_meta_name "$source_node/src/$meta_file" "$(basename "$source_node")")
592
+ processed_dirs+=("$skill_parent")
593
+
594
+ local name=$(extract_meta_name "$skill_file" "$dir_name")
591
595
  mkdir -p "$skills_dir/$name"
592
- cp -R "$source_node/src"/* "$skills_dir/$name/"
593
- skills_count=1
594
- fi
596
+ # Copy files excluding hidden files
597
+ for skill_item in "$skill_parent"/[^.]*; do
598
+ [[ -e "$skill_item" ]] && cp -R "$skill_item" "$skills_dir/$name/" 2> /dev/null || true
599
+ done
600
+ echo " - $name"
601
+ ((skills_count++))
602
+ done < <(find "$source_node" -mindepth 2 -name "$meta_file" -type f -print0 2> /dev/null | grep -zZv '/\.' || true)
595
603
  fi
596
604
 
597
605
  if [[ $skills_count -gt 0 ]]; then
@@ -697,8 +705,8 @@ upgrade() {
697
705
  fi
698
706
  }
699
707
 
700
- # Backup all ai-global configurations to .agents directory
701
- backup_to_agents_dir() {
708
+ # Backup all ai-global configs to .agents directory
709
+ backup_to_dot_agents_dir() {
702
710
  local base_dir="$1"
703
711
  local config_dir="$base_dir/.ai-global"
704
712
 
@@ -711,7 +719,7 @@ backup_to_agents_dir() {
711
719
  mkdir -p "$config_backup_dir"
712
720
 
713
721
  # Backup all
714
- local types=("AGENTS.md" "skills" "rules" "agents" "commands")
722
+ local types=("AGENTS.md" "skills" "rules" "commands")
715
723
 
716
724
  for type_node in "${types[@]}"; do
717
725
  if [[ -e "$config_dir/$type_node" ]]; then
@@ -727,19 +735,19 @@ backup_to_agents_dir() {
727
735
 
728
736
  # Uninstall
729
737
  uninstall() {
730
- # Backup all configurations to .agents directory
738
+ # Backup all configs to .agents directory
731
739
  echo ""
732
- backup_to_agents_dir "$HOME"
740
+ backup_to_dot_agents_dir "$HOME"
733
741
  unlink_all_tools "$HOME"
734
742
  echo ""
735
743
 
736
- # Find and clean up all project configurations
744
+ # Find and clean up all project configs
737
745
  local projects_file="$HOME/.ai-global/projects"
738
746
  if [[ ! -f "$projects_file" ]]; then
739
- log_info "No project configurations found"
747
+ log_info "No project configs found"
740
748
  echo ""
741
749
  else
742
- log_info "Checking for project configurations..."
750
+ log_info "Checking for project configs..."
743
751
  echo ""
744
752
 
745
753
  local project_count=0
@@ -750,7 +758,7 @@ uninstall() {
750
758
  if [[ -d "$project_dir" ]]; then
751
759
  if [[ -d "$project_dir/.ai-global" ]]; then
752
760
  log_info "Found project: $(beautify_dir "$project_dir")"
753
- backup_to_agents_dir "$project_dir"
761
+ backup_to_dot_agents_dir "$project_dir"
754
762
 
755
763
  (cd "$project_dir" && unlink_all_tools "$project_dir" 2> /dev/null || true)
756
764
 
@@ -764,7 +772,7 @@ uninstall() {
764
772
  done < "$projects_file"
765
773
 
766
774
  if [[ $project_count -eq 0 ]]; then
767
- log_info "No project configurations found"
775
+ log_info "No project configs found"
768
776
  echo ""
769
777
  fi
770
778
  fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-global",
3
- "version": "2.6.0",
3
+ "version": "2.7.0",
4
4
  "description": "Unified configuration manager for AI coding assistants",
5
5
  "author": "nanxiaobei",
6
6
  "homepage": "https://github.com/nanxiaobei/ai-global#readme",