@prmichaelsen/acp-mcp 0.1.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/.env.example +5 -0
- package/AGENT.md +1279 -0
- package/README.md +78 -0
- package/agent/commands/acp.command-create.md +372 -0
- package/agent/commands/acp.design-create.md +224 -0
- package/agent/commands/acp.init.md +410 -0
- package/agent/commands/acp.package-create.md +894 -0
- package/agent/commands/acp.package-info.md +211 -0
- package/agent/commands/acp.package-install.md +461 -0
- package/agent/commands/acp.package-list.md +279 -0
- package/agent/commands/acp.package-publish.md +540 -0
- package/agent/commands/acp.package-remove.md +292 -0
- package/agent/commands/acp.package-search.md +306 -0
- package/agent/commands/acp.package-update.md +310 -0
- package/agent/commands/acp.package-validate.md +535 -0
- package/agent/commands/acp.pattern-create.md +326 -0
- package/agent/commands/acp.plan.md +552 -0
- package/agent/commands/acp.proceed.md +336 -0
- package/agent/commands/acp.project-create.md +672 -0
- package/agent/commands/acp.report.md +394 -0
- package/agent/commands/acp.resume.md +237 -0
- package/agent/commands/acp.status.md +280 -0
- package/agent/commands/acp.sync.md +363 -0
- package/agent/commands/acp.task-create.md +390 -0
- package/agent/commands/acp.update.md +301 -0
- package/agent/commands/acp.validate.md +436 -0
- package/agent/commands/acp.version-check-for-updates.md +275 -0
- package/agent/commands/acp.version-check.md +190 -0
- package/agent/commands/acp.version-update.md +288 -0
- package/agent/commands/command.template.md +316 -0
- package/agent/commands/git.commit.md +513 -0
- package/agent/commands/git.init.md +513 -0
- package/agent/commands/mcp-server-starter.add-tool.md +677 -0
- package/agent/commands/mcp-server-starter.init.md +894 -0
- package/agent/design/.gitkeep +0 -0
- package/agent/design/design.template.md +136 -0
- package/agent/design/remember-mcp-analysis.md +987 -0
- package/agent/design/requirements.template.md +387 -0
- package/agent/manifest.template.yaml +13 -0
- package/agent/manifest.yaml +109 -0
- package/agent/milestones/.gitkeep +0 -0
- package/agent/milestones/milestone-1-{title}.template.md +206 -0
- package/agent/package.template.yaml +36 -0
- package/agent/patterns/.gitkeep +0 -0
- package/agent/patterns/bootstrap.template.md +1237 -0
- package/agent/patterns/mcp-server-starter.bootstrap.md +597 -0
- package/agent/patterns/mcp-server-starter.build-config.md +554 -0
- package/agent/patterns/mcp-server-starter.config-management.md +525 -0
- package/agent/patterns/mcp-server-starter.server-factory.md +616 -0
- package/agent/patterns/mcp-server-starter.server-standalone.md +642 -0
- package/agent/patterns/mcp-server-starter.test-config.md +558 -0
- package/agent/patterns/mcp-server-starter.tool-creation.md +653 -0
- package/agent/patterns/pattern.template.md +364 -0
- package/agent/progress.template.yaml +161 -0
- package/agent/progress.yaml +33 -0
- package/agent/schemas/package.schema.yaml +161 -0
- package/agent/scripts/acp.common.sh +1362 -0
- package/agent/scripts/acp.install.sh +213 -0
- package/agent/scripts/acp.package-create.sh +925 -0
- package/agent/scripts/acp.package-info.sh +270 -0
- package/agent/scripts/acp.package-install.sh +550 -0
- package/agent/scripts/acp.package-list.sh +263 -0
- package/agent/scripts/acp.package-publish.sh +420 -0
- package/agent/scripts/acp.package-remove.sh +272 -0
- package/agent/scripts/acp.package-search.sh +156 -0
- package/agent/scripts/acp.package-update.sh +356 -0
- package/agent/scripts/acp.package-validate.sh +766 -0
- package/agent/scripts/acp.uninstall.sh +85 -0
- package/agent/scripts/acp.version-check-for-updates.sh +98 -0
- package/agent/scripts/acp.version-check.sh +47 -0
- package/agent/scripts/acp.version-update.sh +158 -0
- package/agent/scripts/acp.yaml-parser.sh +736 -0
- package/agent/scripts/acp.yaml-validate.sh +205 -0
- package/agent/tasks/.gitkeep +0 -0
- package/agent/tasks/task-1-{title}.template.md +225 -0
- package/dist/config.d.ts +4 -0
- package/dist/server-factory.d.ts +9 -0
- package/dist/server-factory.js +99 -0
- package/dist/server-factory.js.map +7 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +106 -0
- package/dist/server.js.map +7 -0
- package/dist/tools/acp-remote-list-files.d.ts +15 -0
- package/dist/types/ssh-config.d.ts +16 -0
- package/esbuild.build.js +34 -0
- package/esbuild.watch.js +31 -0
- package/jest.config.js +31 -0
- package/package.json +54 -0
- package/src/config.ts +16 -0
- package/src/server-factory.ts +43 -0
- package/src/server.ts +46 -0
- package/src/tools/acp-remote-list-files.ts +89 -0
- package/src/types/ssh-config.ts +17 -0
- package/tsconfig.json +22 -0
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Agent Context Protocol (ACP) Package Install Script
|
|
4
|
+
# Installs third-party ACP packages (commands, patterns, designs, etc.) from git repositories
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# Source common utilities
|
|
9
|
+
SCRIPT_DIR="$(dirname "$0")"
|
|
10
|
+
. "${SCRIPT_DIR}/acp.common.sh"
|
|
11
|
+
. "${SCRIPT_DIR}/acp.yaml-parser.sh"
|
|
12
|
+
|
|
13
|
+
# Initialize colors
|
|
14
|
+
init_colors
|
|
15
|
+
|
|
16
|
+
# Parse arguments
|
|
17
|
+
REPO_URL=""
|
|
18
|
+
INSTALL_PATTERNS=false
|
|
19
|
+
INSTALL_COMMANDS=false
|
|
20
|
+
INSTALL_DESIGNS=false
|
|
21
|
+
PATTERN_FILES=()
|
|
22
|
+
COMMAND_FILES=()
|
|
23
|
+
DESIGN_FILES=()
|
|
24
|
+
LIST_ONLY=false
|
|
25
|
+
GLOBAL_INSTALL=false
|
|
26
|
+
|
|
27
|
+
while [[ $# -gt 0 ]]; do
|
|
28
|
+
case $1 in
|
|
29
|
+
--repo)
|
|
30
|
+
REPO_URL="$2"
|
|
31
|
+
shift 2
|
|
32
|
+
;;
|
|
33
|
+
--global)
|
|
34
|
+
GLOBAL_INSTALL=true
|
|
35
|
+
shift
|
|
36
|
+
;;
|
|
37
|
+
--patterns)
|
|
38
|
+
INSTALL_PATTERNS=true
|
|
39
|
+
shift
|
|
40
|
+
# Collect pattern file names until next flag
|
|
41
|
+
while [[ $# -gt 0 && ! $1 =~ ^-- ]]; do
|
|
42
|
+
PATTERN_FILES+=("$1")
|
|
43
|
+
shift
|
|
44
|
+
done
|
|
45
|
+
;;
|
|
46
|
+
--commands)
|
|
47
|
+
INSTALL_COMMANDS=true
|
|
48
|
+
shift
|
|
49
|
+
# Collect command file names until next flag
|
|
50
|
+
while [[ $# -gt 0 && ! $1 =~ ^-- ]]; do
|
|
51
|
+
COMMAND_FILES+=("$1")
|
|
52
|
+
shift
|
|
53
|
+
done
|
|
54
|
+
;;
|
|
55
|
+
--designs)
|
|
56
|
+
INSTALL_DESIGNS=true
|
|
57
|
+
shift
|
|
58
|
+
# Collect design file names until next flag
|
|
59
|
+
while [[ $# -gt 0 && ! $1 =~ ^-- ]]; do
|
|
60
|
+
DESIGN_FILES+=("$1")
|
|
61
|
+
shift
|
|
62
|
+
done
|
|
63
|
+
;;
|
|
64
|
+
--list)
|
|
65
|
+
LIST_ONLY=true
|
|
66
|
+
shift
|
|
67
|
+
;;
|
|
68
|
+
*)
|
|
69
|
+
echo "${RED}Error: Unknown option: $1${NC}"
|
|
70
|
+
echo "Use --repo to specify repository URL"
|
|
71
|
+
exit 1
|
|
72
|
+
;;
|
|
73
|
+
esac
|
|
74
|
+
done
|
|
75
|
+
|
|
76
|
+
# Check if repository URL provided
|
|
77
|
+
if [ -z "$REPO_URL" ]; then
|
|
78
|
+
echo "${RED}Error: Repository URL required${NC}"
|
|
79
|
+
echo "Usage: $0 --repo <repository-url> [options]"
|
|
80
|
+
echo ""
|
|
81
|
+
echo "Required:"
|
|
82
|
+
echo " --repo <url> Repository URL to install from"
|
|
83
|
+
echo ""
|
|
84
|
+
echo "Options:"
|
|
85
|
+
echo " --global Install to ~/.acp/packages/ instead of ./agent/"
|
|
86
|
+
echo " --patterns [files...] Install patterns (all if no files specified)"
|
|
87
|
+
echo " --commands [files...] Install commands (all if no files specified)"
|
|
88
|
+
echo " --designs [files...] Install designs (all if no files specified)"
|
|
89
|
+
echo " --list List available files without installing"
|
|
90
|
+
echo ""
|
|
91
|
+
echo "Examples:"
|
|
92
|
+
echo " $0 https://github.com/example/acp-package.git"
|
|
93
|
+
echo " $0 --patterns https://github.com/example/acp-package.git"
|
|
94
|
+
echo " $0 --patterns file1 file2 https://github.com/example/acp-package.git"
|
|
95
|
+
echo " $0 --list https://github.com/example/acp-package.git"
|
|
96
|
+
exit 1
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
# Default: install everything if no selective flags specified
|
|
100
|
+
if [[ "$INSTALL_PATTERNS" == false && "$INSTALL_COMMANDS" == false && "$INSTALL_DESIGNS" == false ]]; then
|
|
101
|
+
INSTALL_PATTERNS=true
|
|
102
|
+
INSTALL_COMMANDS=true
|
|
103
|
+
INSTALL_DESIGNS=true
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
echo "${BLUE}📦 ACP Package Installer${NC}"
|
|
107
|
+
echo "========================================"
|
|
108
|
+
echo ""
|
|
109
|
+
echo "Repository: $REPO_URL"
|
|
110
|
+
echo ""
|
|
111
|
+
|
|
112
|
+
# Validate URL format
|
|
113
|
+
if [[ ! "$REPO_URL" =~ ^https?:// ]]; then
|
|
114
|
+
echo "${RED}Error: Invalid repository URL${NC}"
|
|
115
|
+
echo "URL must start with http:// or https://"
|
|
116
|
+
exit 1
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
# Create temporary directory
|
|
120
|
+
TEMP_DIR=$(mktemp -d)
|
|
121
|
+
trap "rm -rf $TEMP_DIR" EXIT
|
|
122
|
+
|
|
123
|
+
echo "Cloning repository..."
|
|
124
|
+
if ! git clone --depth 1 "$REPO_URL" "$TEMP_DIR" &>/dev/null; then
|
|
125
|
+
echo "${RED}Error: Failed to clone repository${NC}"
|
|
126
|
+
echo "Please check the URL and your internet connection."
|
|
127
|
+
exit 1
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
echo "${GREEN}✓${NC} Repository cloned"
|
|
131
|
+
echo ""
|
|
132
|
+
|
|
133
|
+
# Check if repository has agent/ directory
|
|
134
|
+
if [ ! -d "$TEMP_DIR/agent" ]; then
|
|
135
|
+
echo "${RED}Error: No agent/ directory found${NC}"
|
|
136
|
+
echo "Repository must contain an 'agent/' directory with ACP files"
|
|
137
|
+
exit 1
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
# Determine installation directory and manifest based on --global flag
|
|
141
|
+
if [ "$GLOBAL_INSTALL" = true ]; then
|
|
142
|
+
# Global installation - install directly into ~/.acp/agent/
|
|
143
|
+
INSTALL_BASE_DIR="$HOME/.acp/agent"
|
|
144
|
+
MANIFEST_FILE="$HOME/.acp/agent/manifest.yaml"
|
|
145
|
+
|
|
146
|
+
echo "${BLUE}Installing globally to ~/.acp/agent/${NC}"
|
|
147
|
+
echo ""
|
|
148
|
+
|
|
149
|
+
# Initialize global ACP infrastructure (auto-initialization)
|
|
150
|
+
init_global_acp || {
|
|
151
|
+
echo "${RED}Error: Failed to initialize global infrastructure${NC}" >&2
|
|
152
|
+
exit 1
|
|
153
|
+
}
|
|
154
|
+
else
|
|
155
|
+
# Local installation (existing behavior)
|
|
156
|
+
INSTALL_BASE_DIR="./agent"
|
|
157
|
+
MANIFEST_FILE="./agent/manifest.yaml"
|
|
158
|
+
|
|
159
|
+
echo "${BLUE}Installing locally to ./agent/${NC}"
|
|
160
|
+
echo ""
|
|
161
|
+
|
|
162
|
+
# Initialize local manifest
|
|
163
|
+
init_manifest
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
# Parse package metadata
|
|
167
|
+
parse_package_metadata "$TEMP_DIR"
|
|
168
|
+
|
|
169
|
+
# Get commit hash
|
|
170
|
+
COMMIT_HASH=$(get_commit_hash "$TEMP_DIR")
|
|
171
|
+
info "Commit: $COMMIT_HASH"
|
|
172
|
+
echo ""
|
|
173
|
+
|
|
174
|
+
# List mode - show available files and exit
|
|
175
|
+
if [ "$LIST_ONLY" = true ]; then
|
|
176
|
+
echo "${BLUE}📁 Available files in package:${NC}"
|
|
177
|
+
echo ""
|
|
178
|
+
|
|
179
|
+
# List patterns
|
|
180
|
+
if [ -d "$TEMP_DIR/agent/patterns" ]; then
|
|
181
|
+
PATTERN_COUNT=$(find "$TEMP_DIR/agent/patterns" -maxdepth 1 -name "*.md" ! -name "*.template.md" -type f 2>/dev/null | wc -l)
|
|
182
|
+
if [ "$PATTERN_COUNT" -gt 0 ]; then
|
|
183
|
+
echo "${GREEN}Patterns ($PATTERN_COUNT):${NC}"
|
|
184
|
+
find "$TEMP_DIR/agent/patterns" -maxdepth 1 -name "*.md" ! -name "*.template.md" -type f 2>/dev/null | xargs -n1 basename | sed 's/^/ - /'
|
|
185
|
+
echo ""
|
|
186
|
+
fi
|
|
187
|
+
fi
|
|
188
|
+
|
|
189
|
+
# List commands
|
|
190
|
+
if [ -d "$TEMP_DIR/agent/commands" ]; then
|
|
191
|
+
COMMAND_COUNT=$(find "$TEMP_DIR/agent/commands" -maxdepth 1 -name "*.*.md" ! -name "*.template.md" -type f 2>/dev/null | wc -l)
|
|
192
|
+
if [ "$COMMAND_COUNT" -gt 0 ]; then
|
|
193
|
+
echo "${GREEN}Commands ($COMMAND_COUNT):${NC}"
|
|
194
|
+
find "$TEMP_DIR/agent/commands" -maxdepth 1 -name "*.*.md" ! -name "*.template.md" -type f 2>/dev/null | xargs -n1 basename | sed 's/^/ - /'
|
|
195
|
+
echo ""
|
|
196
|
+
fi
|
|
197
|
+
fi
|
|
198
|
+
|
|
199
|
+
# List designs
|
|
200
|
+
if [ -d "$TEMP_DIR/agent/design" ]; then
|
|
201
|
+
DESIGN_COUNT=$(find "$TEMP_DIR/agent/design" -maxdepth 1 -name "*.md" ! -name "*.template.md" -type f 2>/dev/null | wc -l)
|
|
202
|
+
if [ "$DESIGN_COUNT" -gt 0 ]; then
|
|
203
|
+
echo "${GREEN}Designs ($DESIGN_COUNT):${NC}"
|
|
204
|
+
find "$TEMP_DIR/agent/design" -maxdepth 1 -name "*.md" ! -name "*.template.md" -type f 2>/dev/null | xargs -n1 basename | sed 's/^/ - /'
|
|
205
|
+
echo ""
|
|
206
|
+
fi
|
|
207
|
+
fi
|
|
208
|
+
|
|
209
|
+
TOTAL_COUNT=$((PATTERN_COUNT + COMMAND_COUNT + DESIGN_COUNT))
|
|
210
|
+
echo "Total: $TOTAL_COUNT file(s) available"
|
|
211
|
+
echo ""
|
|
212
|
+
echo "To install all files:"
|
|
213
|
+
echo " $0 $REPO_URL"
|
|
214
|
+
echo ""
|
|
215
|
+
echo "To install specific types:"
|
|
216
|
+
echo " $0 --patterns $REPO_URL"
|
|
217
|
+
echo " $0 --commands $REPO_URL"
|
|
218
|
+
echo " $0 --patterns --commands $REPO_URL"
|
|
219
|
+
echo ""
|
|
220
|
+
echo "To install specific files:"
|
|
221
|
+
echo " $0 --patterns file1 file2 $REPO_URL"
|
|
222
|
+
|
|
223
|
+
exit 0
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
# Validate project dependencies
|
|
227
|
+
if [ -f "$TEMP_DIR/package.yaml" ]; then
|
|
228
|
+
if ! validate_project_dependencies "$TEMP_DIR/package.yaml"; then
|
|
229
|
+
echo "${RED}Installation cancelled due to dependency issues${NC}"
|
|
230
|
+
exit 1
|
|
231
|
+
fi
|
|
232
|
+
fi
|
|
233
|
+
|
|
234
|
+
# Directories to install from (based on flags)
|
|
235
|
+
INSTALL_DIRS=()
|
|
236
|
+
[ "$INSTALL_PATTERNS" = true ] && INSTALL_DIRS+=("patterns")
|
|
237
|
+
[ "$INSTALL_COMMANDS" = true ] && INSTALL_DIRS+=("commands")
|
|
238
|
+
[ "$INSTALL_DESIGNS" = true ] && INSTALL_DIRS+=("design")
|
|
239
|
+
[ "$INSTALL_COMMANDS" = true ] && INSTALL_DIRS+=("scripts") # Scripts installed with commands
|
|
240
|
+
|
|
241
|
+
INSTALLED_COUNT=0
|
|
242
|
+
SKIPPED_COUNT=0
|
|
243
|
+
|
|
244
|
+
echo "Scanning for installable files..."
|
|
245
|
+
echo ""
|
|
246
|
+
|
|
247
|
+
# Process each directory
|
|
248
|
+
for dir in "${INSTALL_DIRS[@]}"; do
|
|
249
|
+
SOURCE_DIR="$TEMP_DIR/agent/$dir"
|
|
250
|
+
|
|
251
|
+
if [ ! -d "$SOURCE_DIR" ]; then
|
|
252
|
+
continue
|
|
253
|
+
fi
|
|
254
|
+
|
|
255
|
+
# Determine which files to process based on selective flags
|
|
256
|
+
declare -n FILE_LIST
|
|
257
|
+
case "$dir" in
|
|
258
|
+
patterns)
|
|
259
|
+
FILE_LIST=PATTERN_FILES
|
|
260
|
+
;;
|
|
261
|
+
commands)
|
|
262
|
+
FILE_LIST=COMMAND_FILES
|
|
263
|
+
;;
|
|
264
|
+
design)
|
|
265
|
+
FILE_LIST=DESIGN_FILES
|
|
266
|
+
;;
|
|
267
|
+
scripts)
|
|
268
|
+
FILE_LIST=COMMAND_FILES # Scripts use command files list (empty array if no specific files)
|
|
269
|
+
;;
|
|
270
|
+
esac
|
|
271
|
+
|
|
272
|
+
# If specific files requested, use those; otherwise find all
|
|
273
|
+
if [ ${#FILE_LIST[@]} -gt 0 ]; then
|
|
274
|
+
# Selective file installation
|
|
275
|
+
FILES_TO_PROCESS=()
|
|
276
|
+
for file_name in "${FILE_LIST[@]}"; do
|
|
277
|
+
# Add appropriate extension if not present
|
|
278
|
+
if [ "$dir" = "scripts" ]; then
|
|
279
|
+
[[ "$file_name" != *.sh ]] && file_name="${file_name}.sh"
|
|
280
|
+
else
|
|
281
|
+
[[ "$file_name" != *.md ]] && file_name="${file_name}.md"
|
|
282
|
+
fi
|
|
283
|
+
|
|
284
|
+
file_path="$SOURCE_DIR/$file_name"
|
|
285
|
+
if [ -f "$file_path" ]; then
|
|
286
|
+
FILES_TO_PROCESS+=("$file_path")
|
|
287
|
+
else
|
|
288
|
+
echo "${YELLOW}⚠${NC} File not found in $dir/: $file_name"
|
|
289
|
+
SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
|
|
290
|
+
fi
|
|
291
|
+
done
|
|
292
|
+
else
|
|
293
|
+
# Install all files from directory
|
|
294
|
+
FILES_TO_PROCESS=()
|
|
295
|
+
if [ "$dir" = "scripts" ]; then
|
|
296
|
+
# For scripts, find .sh files
|
|
297
|
+
while IFS= read -r file; do
|
|
298
|
+
[ -n "$file" ] && FILES_TO_PROCESS+=("$file")
|
|
299
|
+
done < <(find "$SOURCE_DIR" -maxdepth 1 -name "*.sh" ! -name "*.template.sh" -type f)
|
|
300
|
+
else
|
|
301
|
+
# For other types, find .md files
|
|
302
|
+
while IFS= read -r file; do
|
|
303
|
+
[ -n "$file" ] && FILES_TO_PROCESS+=("$file")
|
|
304
|
+
done < <(find "$SOURCE_DIR" -maxdepth 1 -name "*.md" ! -name "*.template.md" -type f)
|
|
305
|
+
fi
|
|
306
|
+
fi
|
|
307
|
+
|
|
308
|
+
if [ ${#FILES_TO_PROCESS[@]} -eq 0 ]; then
|
|
309
|
+
continue
|
|
310
|
+
fi
|
|
311
|
+
|
|
312
|
+
echo "${BLUE}📁 $dir/${NC} (${#FILES_TO_PROCESS[@]} file(s))"
|
|
313
|
+
|
|
314
|
+
# Validate and list files
|
|
315
|
+
for file in "${FILES_TO_PROCESS[@]}"; do
|
|
316
|
+
filename=$(basename "$file")
|
|
317
|
+
|
|
318
|
+
# Special validation for commands
|
|
319
|
+
if [ "$dir" = "commands" ]; then
|
|
320
|
+
# Check for reserved 'acp' namespace
|
|
321
|
+
if [[ "$filename" =~ ^acp\. ]]; then
|
|
322
|
+
echo " ${RED}✗${NC} $filename (reserved namespace 'acp')"
|
|
323
|
+
SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
|
|
324
|
+
continue
|
|
325
|
+
fi
|
|
326
|
+
|
|
327
|
+
# Check for agent directive
|
|
328
|
+
if ! grep -q "🤖 Agent Directive" "$file"; then
|
|
329
|
+
echo " ${YELLOW}⚠${NC} $filename (missing agent directive - skipping)"
|
|
330
|
+
SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
|
|
331
|
+
continue
|
|
332
|
+
fi
|
|
333
|
+
fi
|
|
334
|
+
|
|
335
|
+
# Special validation for scripts
|
|
336
|
+
if [ "$dir" = "scripts" ]; then
|
|
337
|
+
# Check for reserved 'acp' namespace
|
|
338
|
+
if [[ "$filename" =~ ^acp\. ]]; then
|
|
339
|
+
echo " ${RED}✗${NC} $filename (reserved namespace 'acp')"
|
|
340
|
+
SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
|
|
341
|
+
continue
|
|
342
|
+
fi
|
|
343
|
+
|
|
344
|
+
# Check for shebang
|
|
345
|
+
if ! head -n1 "$file" | grep -q "^#!/"; then
|
|
346
|
+
echo " ${YELLOW}⚠${NC} $filename (missing shebang)"
|
|
347
|
+
fi
|
|
348
|
+
fi
|
|
349
|
+
|
|
350
|
+
# Check for conflicts
|
|
351
|
+
if [ -f "$INSTALL_BASE_DIR/$dir/$filename" ]; then
|
|
352
|
+
echo " ${YELLOW}⚠${NC} $filename (will overwrite existing)"
|
|
353
|
+
else
|
|
354
|
+
echo " ${GREEN}✓${NC} $filename"
|
|
355
|
+
fi
|
|
356
|
+
|
|
357
|
+
INSTALLED_COUNT=$((INSTALLED_COUNT + 1))
|
|
358
|
+
done
|
|
359
|
+
|
|
360
|
+
unset -n FILE_LIST
|
|
361
|
+
echo ""
|
|
362
|
+
done
|
|
363
|
+
|
|
364
|
+
# Exit if nothing to install
|
|
365
|
+
if [ $INSTALLED_COUNT -eq 0 ]; then
|
|
366
|
+
echo "${RED}Error: No valid files to install${NC}"
|
|
367
|
+
if [ $SKIPPED_COUNT -gt 0 ]; then
|
|
368
|
+
echo "Skipped $SKIPPED_COUNT file(s) due to validation failures"
|
|
369
|
+
fi
|
|
370
|
+
exit 1
|
|
371
|
+
fi
|
|
372
|
+
|
|
373
|
+
# Confirm installation
|
|
374
|
+
echo "Ready to install $INSTALLED_COUNT file(s)"
|
|
375
|
+
if [ $SKIPPED_COUNT -gt 0 ]; then
|
|
376
|
+
echo "($SKIPPED_COUNT file(s) will be skipped)"
|
|
377
|
+
fi
|
|
378
|
+
echo ""
|
|
379
|
+
|
|
380
|
+
if [ "$SKIP_CONFIRM" = false ]; then
|
|
381
|
+
read -p "Proceed with installation? (y/N) " -n 1 -r
|
|
382
|
+
echo
|
|
383
|
+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
384
|
+
echo "Installation cancelled."
|
|
385
|
+
exit 0
|
|
386
|
+
fi
|
|
387
|
+
else
|
|
388
|
+
echo "Auto-confirming installation (-y flag)"
|
|
389
|
+
fi
|
|
390
|
+
|
|
391
|
+
echo ""
|
|
392
|
+
echo "Installing files..."
|
|
393
|
+
|
|
394
|
+
# Add package to manifest
|
|
395
|
+
add_package_to_manifest "$PACKAGE_NAME" "$REPO_URL" "$PACKAGE_VERSION" "$COMMIT_HASH"
|
|
396
|
+
|
|
397
|
+
# Install files (same logic for both global and local)
|
|
398
|
+
for dir in "${INSTALL_DIRS[@]}"; do
|
|
399
|
+
SOURCE_DIR="$TEMP_DIR/agent/$dir"
|
|
400
|
+
|
|
401
|
+
if [ ! -d "$SOURCE_DIR" ]; then
|
|
402
|
+
continue
|
|
403
|
+
fi
|
|
404
|
+
|
|
405
|
+
# Create target directory
|
|
406
|
+
mkdir -p "$INSTALL_BASE_DIR/$dir"
|
|
407
|
+
|
|
408
|
+
# Determine which files to install based on selective flags
|
|
409
|
+
declare -n FILE_LIST
|
|
410
|
+
case "$dir" in
|
|
411
|
+
patterns)
|
|
412
|
+
FILE_LIST=PATTERN_FILES
|
|
413
|
+
;;
|
|
414
|
+
commands)
|
|
415
|
+
FILE_LIST=COMMAND_FILES
|
|
416
|
+
;;
|
|
417
|
+
design)
|
|
418
|
+
FILE_LIST=DESIGN_FILES
|
|
419
|
+
;;
|
|
420
|
+
scripts)
|
|
421
|
+
FILE_LIST=COMMAND_FILES # Scripts use command files list
|
|
422
|
+
;;
|
|
423
|
+
esac
|
|
424
|
+
|
|
425
|
+
# If specific files requested, use those; otherwise find all
|
|
426
|
+
if [ ${#FILE_LIST[@]} -gt 0 ]; then
|
|
427
|
+
# Selective file installation
|
|
428
|
+
FILES_TO_INSTALL=()
|
|
429
|
+
for file_name in "${FILE_LIST[@]}"; do
|
|
430
|
+
# Add appropriate extension if not present
|
|
431
|
+
if [ "$dir" = "scripts" ]; then
|
|
432
|
+
[[ "$file_name" != *.sh ]] && file_name="${file_name}.sh"
|
|
433
|
+
else
|
|
434
|
+
[[ "$file_name" != *.md ]] && file_name="${file_name}.md"
|
|
435
|
+
fi
|
|
436
|
+
|
|
437
|
+
file_path="$SOURCE_DIR/$file_name"
|
|
438
|
+
if [ -f "$file_path" ]; then
|
|
439
|
+
FILES_TO_INSTALL+=("$file_path")
|
|
440
|
+
fi
|
|
441
|
+
done
|
|
442
|
+
else
|
|
443
|
+
# Install all files from directory
|
|
444
|
+
FILES_TO_INSTALL=()
|
|
445
|
+
if [ "$dir" = "scripts" ]; then
|
|
446
|
+
while IFS= read -r file; do
|
|
447
|
+
[ -n "$file" ] && FILES_TO_INSTALL+=("$file")
|
|
448
|
+
done < <(find "$SOURCE_DIR" -maxdepth 1 -name "*.sh" ! -name "*.template.sh" -type f)
|
|
449
|
+
else
|
|
450
|
+
while IFS= read -r file; do
|
|
451
|
+
[ -n "$file" ] && FILES_TO_INSTALL+=("$file")
|
|
452
|
+
done < <(find "$SOURCE_DIR" -maxdepth 1 -name "*.md" ! -name "*.template.md" -type f)
|
|
453
|
+
fi
|
|
454
|
+
fi
|
|
455
|
+
|
|
456
|
+
for file in "${FILES_TO_INSTALL[@]}"; do
|
|
457
|
+
filename=$(basename "$file")
|
|
458
|
+
|
|
459
|
+
# Skip invalid files
|
|
460
|
+
if [ "$dir" = "commands" ]; then
|
|
461
|
+
if [[ "$filename" =~ ^acp\. ]] || ! grep -q "🤖 Agent Directive" "$file"; then
|
|
462
|
+
continue
|
|
463
|
+
fi
|
|
464
|
+
fi
|
|
465
|
+
|
|
466
|
+
# Skip invalid scripts
|
|
467
|
+
if [ "$dir" = "scripts" ]; then
|
|
468
|
+
if [[ "$filename" =~ ^acp\. ]]; then
|
|
469
|
+
continue
|
|
470
|
+
fi
|
|
471
|
+
fi
|
|
472
|
+
|
|
473
|
+
# Copy file
|
|
474
|
+
cp "$file" "$INSTALL_BASE_DIR/$dir/$filename"
|
|
475
|
+
|
|
476
|
+
# Make scripts executable
|
|
477
|
+
if [ "$dir" = "scripts" ]; then
|
|
478
|
+
chmod +x "$INSTALL_BASE_DIR/$dir/$filename"
|
|
479
|
+
fi
|
|
480
|
+
|
|
481
|
+
# Get file version from package.yaml
|
|
482
|
+
FILE_VERSION=$(get_file_version "$TEMP_DIR/package.yaml" "$dir" "$filename")
|
|
483
|
+
|
|
484
|
+
# Add file to manifest
|
|
485
|
+
add_file_to_manifest "$PACKAGE_NAME" "$dir" "$filename" "$FILE_VERSION" "$INSTALL_BASE_DIR/$dir/$filename"
|
|
486
|
+
|
|
487
|
+
if [ "$dir" = "scripts" ]; then
|
|
488
|
+
echo " ${GREEN}✓${NC} Installed $dir/$filename (v$FILE_VERSION) [executable]"
|
|
489
|
+
else
|
|
490
|
+
echo " ${GREEN}✓${NC} Installed $dir/$filename (v$FILE_VERSION)"
|
|
491
|
+
fi
|
|
492
|
+
done
|
|
493
|
+
|
|
494
|
+
unset -n FILE_LIST
|
|
495
|
+
echo ""
|
|
496
|
+
done
|
|
497
|
+
|
|
498
|
+
echo ""
|
|
499
|
+
|
|
500
|
+
# Success message based on installation mode
|
|
501
|
+
if [ "$GLOBAL_INSTALL" = true ]; then
|
|
502
|
+
echo "${GREEN}✅ Package installed globally!${NC}"
|
|
503
|
+
echo ""
|
|
504
|
+
echo "Location: $INSTALL_BASE_DIR"
|
|
505
|
+
echo "Manifest: $MANIFEST_FILE"
|
|
506
|
+
echo ""
|
|
507
|
+
echo "Agents can now discover this package by reading ~/.acp/agent/manifest.yaml"
|
|
508
|
+
echo ""
|
|
509
|
+
echo "To use in any project:"
|
|
510
|
+
echo " 1. Run @acp.init to discover global packages"
|
|
511
|
+
echo " 2. Reference commands via @namespace.command"
|
|
512
|
+
echo ""
|
|
513
|
+
echo "To list global packages: @acp.package-list --global"
|
|
514
|
+
echo ""
|
|
515
|
+
else
|
|
516
|
+
echo "${GREEN}✅ Installation complete!${NC}"
|
|
517
|
+
echo ""
|
|
518
|
+
echo "Installed $INSTALLED_COUNT file(s) from:"
|
|
519
|
+
echo " $REPO_URL"
|
|
520
|
+
echo ""
|
|
521
|
+
echo "Package: $PACKAGE_NAME ($PACKAGE_VERSION)"
|
|
522
|
+
echo "Manifest: agent/manifest.yaml updated"
|
|
523
|
+
echo ""
|
|
524
|
+
fi
|
|
525
|
+
|
|
526
|
+
# List installed commands
|
|
527
|
+
if [ -d "$TEMP_DIR/agent/commands" ]; then
|
|
528
|
+
COMMANDS=$(find "$TEMP_DIR/agent/commands" -maxdepth 1 -name "*.*.md" ! -name "*.template.md" -type f)
|
|
529
|
+
if [ -n "$COMMANDS" ]; then
|
|
530
|
+
echo "Installed commands:"
|
|
531
|
+
while IFS= read -r cmd_file; do
|
|
532
|
+
cmd_name=$(basename "$cmd_file" .md)
|
|
533
|
+
if [[ ! "$cmd_name" =~ ^acp\. ]]; then
|
|
534
|
+
invocation="@${cmd_name}"
|
|
535
|
+
echo " - $invocation"
|
|
536
|
+
fi
|
|
537
|
+
done <<< "$COMMANDS"
|
|
538
|
+
echo ""
|
|
539
|
+
fi
|
|
540
|
+
fi
|
|
541
|
+
|
|
542
|
+
echo "${YELLOW}⚠️ Security Reminder:${NC}"
|
|
543
|
+
echo "Review installed files before using them."
|
|
544
|
+
echo "Third-party files can instruct agents to modify files and execute scripts."
|
|
545
|
+
echo ""
|
|
546
|
+
echo "Next steps:"
|
|
547
|
+
echo " 1. Review installed files in agent/ directories"
|
|
548
|
+
echo " 2. Test installed commands"
|
|
549
|
+
echo " 3. Update progress.yaml with installation notes"
|
|
550
|
+
echo ""
|