ai-global 2.6.0 → 2.8.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.
- package/README.md +40 -36
- package/ai-global +98 -94
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
# AI Global
|
|
2
2
|
|
|
3
|
-
English
|
|
3
|
+
English · [简体中文](README_CN.md) · [繁體中文](README_TW.md) · [日本語](README_JP.md)· [한국어](README_KR.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
6
|
|
|
7
|
-
|
|
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/
|
|
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
|
|
123
|
-
- **Project Mode**: Manages AI
|
|
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 |
|
|
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.
|
|
7
|
+
VERSION="2.8.0"
|
|
8
8
|
|
|
9
9
|
# Known AI tool patterns
|
|
10
|
-
# Format: nodes|key|name|agents_md|rules|commands|skills|
|
|
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
|
|
13
|
-
".augment|augment|Augment|AGENTS.md|rules|commands
|
|
14
|
-
".blackbox|blackbox|Blackbox AI|.|.|.|skills
|
|
15
|
-
".claude|claude|Claude Code|CLAUDE.md|.|commands|skills
|
|
16
|
-
".cline|cline|Cline|AGENTS.md|rules|.|skills
|
|
17
|
-
".clawdbot|clawdbot|Clawdbot Code|AGENTS.md|.|.|skills
|
|
18
|
-
".codex|codex|OpenAI Codex|AGENTS.md|rules|.|skills
|
|
19
|
-
".commandcode|commandcode|Command Code|AGENTS.md|.|.|skills
|
|
20
|
-
".continue|continue|Continue|AGENTS.md|rules
|
|
21
|
-
".copilot|copilot|GitHub Copilot|AGENTS.md|.|.|skills
|
|
22
|
-
".cursor|cursor|Cursor|AGENTS.md|rules|commands|skills
|
|
23
|
-
".factory|droid|Factory Droid|AGENTS.md|rules|commands|skills
|
|
24
|
-
".gemini|antigravity|Antigravity|GEMINI.md|.|.|antigravity/skills
|
|
25
|
-
".gemini|gemini|Gemini CLI|GEMINI.md|.|.|skills
|
|
26
|
-
".goose|goose|Goose AI|AGENTS.md|.|.|skills
|
|
27
|
-
".kiro|kiro|Kiro CLI|AGENTS.md|steering|.|skills
|
|
28
|
-
".kilocode|kilocode|Kilo Code|AGENTS.md|rules|commands|skills
|
|
29
|
-
".neovate|neovate|Neovate|AGENTS.md|.|commands|skills
|
|
30
|
-
".opencode, .config/opencode|opencode|OpenCode|AGENTS.md|.|commands|skills
|
|
31
|
-
".openhands|openhands|OpenHands|AGENTS.md|.|.|skills
|
|
32
|
-
".qodo|qodo|Qodo|AGENTS.md
|
|
33
|
-
".qoder|qoder|Qoder|AGENTS.md|rules|commands|skills
|
|
34
|
-
".roo|roo|Roo Code|AGENTS.md|rules|commands|skills
|
|
35
|
-
".trae|trae|TRAE|AGENTS.md|rules|.|skills
|
|
36
|
-
".windsurf, .codeium/windsurf|windsurf|Windsurf|AGENTS.md|rules|.|skills
|
|
37
|
-
".zencoder|zencoder|Zencoder|AGENTS.md|rules|.|skills
|
|
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" "$
|
|
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
|
|
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"
|
|
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"
|
|
@@ -160,7 +159,8 @@ update_links() {
|
|
|
160
159
|
else
|
|
161
160
|
# Copy all files (overwrite if exists)
|
|
162
161
|
find "$type_dir" -type f -print0 2> /dev/null | while IFS= read -r -d '' file_dir; do
|
|
163
|
-
local
|
|
162
|
+
local rel_path="${file_dir#$type_dir/}"
|
|
163
|
+
local target_file="$target_dir/$rel_path"
|
|
164
164
|
mkdir -p "$(dirname "$target_file")" 2> /dev/null
|
|
165
165
|
cp "$file_dir" "$target_file" 2> /dev/null || true
|
|
166
166
|
done
|
|
@@ -192,7 +192,7 @@ update_links() {
|
|
|
192
192
|
|
|
193
193
|
# Check if any tools were found
|
|
194
194
|
if [[ $total_tools -eq 0 ]]; then
|
|
195
|
-
log_info "No AI tool
|
|
195
|
+
log_info "No AI tool configs found"
|
|
196
196
|
# Remove empty .ai-global directory
|
|
197
197
|
rm -rf "$base_dir/.ai-global" 2> /dev/null
|
|
198
198
|
echo ""
|
|
@@ -247,17 +247,16 @@ show_status() {
|
|
|
247
247
|
local rules_output=""
|
|
248
248
|
local commands_output=""
|
|
249
249
|
local skills_output=""
|
|
250
|
-
local subagents_output=""
|
|
251
250
|
|
|
252
251
|
for pattern in "${KNOWN_PATTERNS[@]}"; do
|
|
253
|
-
IFS='|' read -r nodes key name agents_md rules commands skills
|
|
252
|
+
IFS='|' read -r nodes key name agents_md rules commands skills color <<< "$pattern"
|
|
254
253
|
IFS=', ' read -ra node_array <<< "$nodes"
|
|
255
254
|
|
|
256
255
|
for tool_node in "${node_array[@]}"; do
|
|
257
256
|
local tool_dir="$base_dir/$tool_node"
|
|
258
257
|
|
|
259
258
|
if [[ -d "$tool_dir" ]]; then
|
|
260
|
-
local types=("$agents_md:agents_md_output" "$rules:rules_output" "$commands:commands_output" "$skills:skills_output"
|
|
259
|
+
local types=("$agents_md:agents_md_output" "$rules:rules_output" "$commands:commands_output" "$skills:skills_output")
|
|
261
260
|
|
|
262
261
|
for type_info in "${types[@]}"; do
|
|
263
262
|
IFS=':' read -r type_node output_var <<< "$type_info"
|
|
@@ -273,7 +272,7 @@ show_status() {
|
|
|
273
272
|
return
|
|
274
273
|
fi
|
|
275
274
|
|
|
276
|
-
local types=("AGENTS.md:$agents_md_output" "rules:$rules_output" "commands:$commands_output" "skills:$skills_output"
|
|
275
|
+
local types=("AGENTS.md:$agents_md_output" "rules:$rules_output" "commands:$commands_output" "skills:$skills_output")
|
|
277
276
|
|
|
278
277
|
for type_info in "${types[@]}"; do
|
|
279
278
|
IFS=':' read -r title content <<< "$type_info"
|
|
@@ -289,11 +288,11 @@ list_tools() {
|
|
|
289
288
|
local base_dir=$(pwd)
|
|
290
289
|
log_context_info "$base_dir"
|
|
291
290
|
|
|
292
|
-
echo -e " ${BLUE}Tool Key Directory AGENTS.md Rules Commands Skills
|
|
293
|
-
echo -e " ${BLUE}
|
|
291
|
+
echo -e " ${BLUE}Tool Key Directory AGENTS.md Rules Commands Skills Status${NC}"
|
|
292
|
+
echo -e " ${BLUE}-------------------------------------------------------------------------------------------------------${NC}"
|
|
294
293
|
|
|
295
294
|
for pattern in "${KNOWN_PATTERNS[@]}"; do
|
|
296
|
-
IFS='|' read -r nodes key name agents_md rules commands skills
|
|
295
|
+
IFS='|' read -r nodes key name agents_md rules commands skills color <<< "$pattern"
|
|
297
296
|
IFS=', ' read -ra node_array <<< "$nodes"
|
|
298
297
|
|
|
299
298
|
local row_color="${GRAY}"
|
|
@@ -324,7 +323,7 @@ list_tools() {
|
|
|
324
323
|
local nodes_pad=" "
|
|
325
324
|
nodes_pad="${nodes_pad:0:$nodes_spaces}"
|
|
326
325
|
|
|
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 "○")
|
|
326
|
+
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
327
|
done
|
|
329
328
|
echo ""
|
|
330
329
|
}
|
|
@@ -362,12 +361,11 @@ unlink_one_tool() {
|
|
|
362
361
|
local rules="$4"
|
|
363
362
|
local commands="$5"
|
|
364
363
|
local skills="$6"
|
|
365
|
-
local
|
|
366
|
-
local color="$8"
|
|
364
|
+
local color="$7"
|
|
367
365
|
|
|
368
366
|
local unlinked_count=0
|
|
369
367
|
|
|
370
|
-
for type_node in "$agents_md" "$rules" "$commands" "$skills"
|
|
368
|
+
for type_node in "$agents_md" "$rules" "$commands" "$skills"; do
|
|
371
369
|
if [[ "$type_node" != "." ]]; then
|
|
372
370
|
local type_dir="$base_dir/$tool_node/$type_node"
|
|
373
371
|
if [[ -L "$type_dir" ]]; then
|
|
@@ -401,14 +399,14 @@ unlink_all_tools() {
|
|
|
401
399
|
local total_unlinked=0
|
|
402
400
|
|
|
403
401
|
for pattern in "${KNOWN_PATTERNS[@]}"; do
|
|
404
|
-
IFS='|' read -r nodes key name agents_md rules commands skills
|
|
402
|
+
IFS='|' read -r nodes key name agents_md rules commands skills color <<< "$pattern"
|
|
405
403
|
IFS=', ' read -ra node_array <<< "$nodes"
|
|
406
404
|
|
|
407
405
|
for tool_node in "${node_array[@]}"; do
|
|
408
406
|
local tool_dir="$base_dir/$tool_node"
|
|
409
407
|
|
|
410
408
|
if [[ -d "$tool_dir" ]]; then
|
|
411
|
-
unlink_one_tool "$base_dir" "$tool_node" "$agents_md" "$rules" "$commands" "$skills" "$
|
|
409
|
+
unlink_one_tool "$base_dir" "$tool_node" "$agents_md" "$rules" "$commands" "$skills" "$color"
|
|
412
410
|
total_unlinked=$((total_unlinked + $?))
|
|
413
411
|
fi
|
|
414
412
|
done
|
|
@@ -442,7 +440,7 @@ unlink_tool() {
|
|
|
442
440
|
# Find pattern by searching KNOWN_PATTERNS
|
|
443
441
|
local match=""
|
|
444
442
|
for pattern in "${KNOWN_PATTERNS[@]}"; do
|
|
445
|
-
IFS='|' read -r nodes key name agents_md rules commands skills
|
|
443
|
+
IFS='|' read -r nodes key name agents_md rules commands skills color <<< "$pattern"
|
|
446
444
|
if [[ "$key" == "$query_key" ]]; then
|
|
447
445
|
match="$pattern"
|
|
448
446
|
break
|
|
@@ -462,7 +460,7 @@ unlink_tool() {
|
|
|
462
460
|
local has_found=false
|
|
463
461
|
|
|
464
462
|
# Parse pattern and unlink tool
|
|
465
|
-
IFS='|' read -r nodes key name agents_md rules commands skills
|
|
463
|
+
IFS='|' read -r nodes key name agents_md rules commands skills color <<< "$match"
|
|
466
464
|
IFS=', ' read -ra node_array <<< "$nodes"
|
|
467
465
|
|
|
468
466
|
for tool_node in "${node_array[@]}"; do
|
|
@@ -470,7 +468,7 @@ unlink_tool() {
|
|
|
470
468
|
|
|
471
469
|
if [[ -d "$tool_dir" ]]; then
|
|
472
470
|
has_found=true
|
|
473
|
-
unlink_one_tool "$base_dir" "$tool_node" "$agents_md" "$rules" "$commands" "$skills" "$
|
|
471
|
+
unlink_one_tool "$base_dir" "$tool_node" "$agents_md" "$rules" "$commands" "$skills" "$color"
|
|
474
472
|
local unlinked_count=$?
|
|
475
473
|
if [[ $unlinked_count -gt 0 ]]; then
|
|
476
474
|
log_ok "Unlinked $unlinked_count symlinks from ${color}$(beautify_dir "$tool_dir")${NC}"
|
|
@@ -549,49 +547,55 @@ download_from_github() {
|
|
|
549
547
|
|
|
550
548
|
if [[ -d "$source_node" ]]; then
|
|
551
549
|
local meta_file="SKILL.md"
|
|
550
|
+
local processed_dirs=()
|
|
551
|
+
local has_root_skill=false
|
|
552
552
|
|
|
553
|
-
#
|
|
553
|
+
# First check if root has SKILL.md
|
|
554
554
|
if [[ -f "$source_node/$meta_file" ]]; then
|
|
555
|
+
has_root_skill=true
|
|
555
556
|
local name=$(extract_meta_name "$source_node/$meta_file" "$(basename "$source_node")")
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
557
|
+
mkdir -p "$skills_dir/$name"
|
|
558
|
+
# Copy files excluding: hidden (.), README.md*, LICENSE*
|
|
559
|
+
for item in "$source_node"/*; do
|
|
560
|
+
[[ ! -e "$item" ]] && continue
|
|
561
|
+
local item_name=$(basename "$item")
|
|
562
|
+
# Skip hidden files, README.md, LICENSE
|
|
563
|
+
[[ "$item_name" == .* ]] && continue
|
|
564
|
+
[[ "$item_name" == README.md* ]] && continue
|
|
565
|
+
[[ "$item_name" == LICENSE* ]] && continue
|
|
566
|
+
cp -R "$item" "$skills_dir/$name/" 2> /dev/null || true
|
|
567
|
+
done
|
|
568
|
+
echo " - $name"
|
|
559
569
|
skills_count=1
|
|
560
570
|
fi
|
|
561
571
|
|
|
562
|
-
#
|
|
563
|
-
if [[ $
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
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
|
|
572
|
+
# Only check subdirectories if root doesn't have SKILL.md
|
|
573
|
+
if [[ "$has_root_skill" == false ]]; then
|
|
574
|
+
while IFS= read -r -d '' skill_file; do
|
|
575
|
+
local skill_parent=$(dirname "$skill_file")
|
|
576
|
+
local dir_name=$(basename "$skill_parent")
|
|
578
577
|
|
|
579
|
-
#
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
578
|
+
# Skip hidden directories
|
|
579
|
+
[[ "$dir_name" == .* ]] && continue
|
|
580
|
+
|
|
581
|
+
# Skip if already processed
|
|
582
|
+
local already_processed=false
|
|
583
|
+
for processed in "${processed_dirs[@]}"; do
|
|
584
|
+
[[ "$processed" == "$skill_parent" ]] && already_processed=true && break
|
|
585
|
+
done
|
|
586
|
+
[[ "$already_processed" == true ]] && continue
|
|
586
587
|
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
local name=$(extract_meta_name "$source_node/src/$meta_file" "$(basename "$source_node")")
|
|
588
|
+
processed_dirs+=("$skill_parent")
|
|
589
|
+
|
|
590
|
+
local name=$(extract_meta_name "$skill_file" "$dir_name")
|
|
591
591
|
mkdir -p "$skills_dir/$name"
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
592
|
+
# Copy files excluding hidden files
|
|
593
|
+
for skill_item in "$skill_parent"/[^.]*; do
|
|
594
|
+
[[ -e "$skill_item" ]] && cp -R "$skill_item" "$skills_dir/$name/" 2> /dev/null || true
|
|
595
|
+
done
|
|
596
|
+
echo " - $name"
|
|
597
|
+
((skills_count++))
|
|
598
|
+
done < <(find "$source_node" -mindepth 2 -name "$meta_file" -type f -print0 2> /dev/null | grep -zZv '/\.' || true)
|
|
595
599
|
fi
|
|
596
600
|
|
|
597
601
|
if [[ $skills_count -gt 0 ]]; then
|
|
@@ -697,8 +701,8 @@ upgrade() {
|
|
|
697
701
|
fi
|
|
698
702
|
}
|
|
699
703
|
|
|
700
|
-
# Backup all ai-global
|
|
701
|
-
|
|
704
|
+
# Backup all ai-global configs to .agents directory
|
|
705
|
+
backup_to_dot_agents_dir() {
|
|
702
706
|
local base_dir="$1"
|
|
703
707
|
local config_dir="$base_dir/.ai-global"
|
|
704
708
|
|
|
@@ -711,7 +715,7 @@ backup_to_agents_dir() {
|
|
|
711
715
|
mkdir -p "$config_backup_dir"
|
|
712
716
|
|
|
713
717
|
# Backup all
|
|
714
|
-
local types=("AGENTS.md" "skills" "rules" "
|
|
718
|
+
local types=("AGENTS.md" "skills" "rules" "commands")
|
|
715
719
|
|
|
716
720
|
for type_node in "${types[@]}"; do
|
|
717
721
|
if [[ -e "$config_dir/$type_node" ]]; then
|
|
@@ -727,19 +731,19 @@ backup_to_agents_dir() {
|
|
|
727
731
|
|
|
728
732
|
# Uninstall
|
|
729
733
|
uninstall() {
|
|
730
|
-
# Backup all
|
|
734
|
+
# Backup all configs to .agents directory
|
|
731
735
|
echo ""
|
|
732
|
-
|
|
736
|
+
backup_to_dot_agents_dir "$HOME"
|
|
733
737
|
unlink_all_tools "$HOME"
|
|
734
738
|
echo ""
|
|
735
739
|
|
|
736
|
-
# Find and clean up all project
|
|
740
|
+
# Find and clean up all project configs
|
|
737
741
|
local projects_file="$HOME/.ai-global/projects"
|
|
738
742
|
if [[ ! -f "$projects_file" ]]; then
|
|
739
|
-
log_info "No project
|
|
743
|
+
log_info "No project configs found"
|
|
740
744
|
echo ""
|
|
741
745
|
else
|
|
742
|
-
log_info "Checking for project
|
|
746
|
+
log_info "Checking for project configs..."
|
|
743
747
|
echo ""
|
|
744
748
|
|
|
745
749
|
local project_count=0
|
|
@@ -750,7 +754,7 @@ uninstall() {
|
|
|
750
754
|
if [[ -d "$project_dir" ]]; then
|
|
751
755
|
if [[ -d "$project_dir/.ai-global" ]]; then
|
|
752
756
|
log_info "Found project: $(beautify_dir "$project_dir")"
|
|
753
|
-
|
|
757
|
+
backup_to_dot_agents_dir "$project_dir"
|
|
754
758
|
|
|
755
759
|
(cd "$project_dir" && unlink_all_tools "$project_dir" 2> /dev/null || true)
|
|
756
760
|
|
|
@@ -764,7 +768,7 @@ uninstall() {
|
|
|
764
768
|
done < "$projects_file"
|
|
765
769
|
|
|
766
770
|
if [[ $project_count -eq 0 ]]; then
|
|
767
|
-
log_info "No project
|
|
771
|
+
log_info "No project configs found"
|
|
768
772
|
echo ""
|
|
769
773
|
fi
|
|
770
774
|
fi
|