@prmichaelsen/acp-visualizer 0.1.0 → 0.1.2

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 (159) hide show
  1. package/package.json +8 -10
  2. package/src/components/ExtraFieldsBadge.tsx +1 -1
  3. package/src/components/FilterBar.tsx +1 -1
  4. package/src/components/Header.tsx +1 -1
  5. package/src/components/MilestoneTable.tsx +1 -1
  6. package/src/components/MilestoneTree.tsx +2 -2
  7. package/src/components/StatusBadge.tsx +1 -1
  8. package/src/components/StatusDot.tsx +1 -1
  9. package/src/components/TaskList.tsx +1 -1
  10. package/src/routes/__root.tsx +5 -5
  11. package/src/routes/api/watch.ts +1 -1
  12. package/src/routes/index.tsx +2 -2
  13. package/src/routes/milestones.tsx +7 -7
  14. package/src/routes/search.tsx +4 -4
  15. package/src/routes/tasks.tsx +3 -3
  16. package/src/services/progress-database.service.ts +3 -3
  17. package/agent/commands/acp.clarification-address.md +0 -417
  18. package/agent/commands/acp.clarification-capture.md +0 -386
  19. package/agent/commands/acp.clarification-create.md +0 -437
  20. package/agent/commands/acp.clarifications-research.md +0 -326
  21. package/agent/commands/acp.command-create.md +0 -432
  22. package/agent/commands/acp.design-create.md +0 -286
  23. package/agent/commands/acp.design-reference.md +0 -355
  24. package/agent/commands/acp.handoff.md +0 -270
  25. package/agent/commands/acp.index.md +0 -423
  26. package/agent/commands/acp.init.md +0 -546
  27. package/agent/commands/acp.package-create.md +0 -895
  28. package/agent/commands/acp.package-info.md +0 -212
  29. package/agent/commands/acp.package-install.md +0 -539
  30. package/agent/commands/acp.package-list.md +0 -280
  31. package/agent/commands/acp.package-publish.md +0 -541
  32. package/agent/commands/acp.package-remove.md +0 -293
  33. package/agent/commands/acp.package-search.md +0 -307
  34. package/agent/commands/acp.package-update.md +0 -361
  35. package/agent/commands/acp.package-validate.md +0 -540
  36. package/agent/commands/acp.pattern-create.md +0 -386
  37. package/agent/commands/acp.plan.md +0 -587
  38. package/agent/commands/acp.proceed.md +0 -882
  39. package/agent/commands/acp.project-create.md +0 -675
  40. package/agent/commands/acp.project-info.md +0 -312
  41. package/agent/commands/acp.project-list.md +0 -226
  42. package/agent/commands/acp.project-remove.md +0 -379
  43. package/agent/commands/acp.project-set.md +0 -227
  44. package/agent/commands/acp.project-update.md +0 -307
  45. package/agent/commands/acp.projects-restore.md +0 -228
  46. package/agent/commands/acp.projects-sync.md +0 -347
  47. package/agent/commands/acp.report.md +0 -407
  48. package/agent/commands/acp.resume.md +0 -239
  49. package/agent/commands/acp.sessions.md +0 -301
  50. package/agent/commands/acp.status.md +0 -293
  51. package/agent/commands/acp.sync.md +0 -364
  52. package/agent/commands/acp.task-create.md +0 -500
  53. package/agent/commands/acp.update.md +0 -302
  54. package/agent/commands/acp.validate.md +0 -466
  55. package/agent/commands/acp.version-check-for-updates.md +0 -276
  56. package/agent/commands/acp.version-check.md +0 -191
  57. package/agent/commands/acp.version-update.md +0 -289
  58. package/agent/commands/command.template.md +0 -339
  59. package/agent/commands/git.commit.md +0 -526
  60. package/agent/commands/git.init.md +0 -514
  61. package/agent/commands/tanstack-cloudflare.deploy.md +0 -272
  62. package/agent/commands/tanstack-cloudflare.tail.md +0 -275
  63. package/agent/design/.gitkeep +0 -0
  64. package/agent/design/design.template.md +0 -154
  65. package/agent/design/local.dashboard-layout-routing.md +0 -288
  66. package/agent/design/local.data-model-yaml-parsing.md +0 -310
  67. package/agent/design/local.search-filtering.md +0 -331
  68. package/agent/design/local.server-api-auto-refresh.md +0 -235
  69. package/agent/design/local.table-tree-views.md +0 -299
  70. package/agent/design/local.visualizer-requirements.md +0 -349
  71. package/agent/design/requirements.template.md +0 -387
  72. package/agent/index/.gitkeep +0 -0
  73. package/agent/index/acp.core.yaml +0 -137
  74. package/agent/index/local.main.template.yaml +0 -37
  75. package/agent/manifest.template.yaml +0 -13
  76. package/agent/manifest.yaml +0 -302
  77. package/agent/milestones/.gitkeep +0 -0
  78. package/agent/milestones/milestone-1-project-scaffold-data-pipeline.md +0 -67
  79. package/agent/milestones/milestone-1-{title}.template.md +0 -206
  80. package/agent/milestones/milestone-2-dashboard-views-interaction.md +0 -79
  81. package/agent/package.template.yaml +0 -86
  82. package/agent/patterns/.gitkeep +0 -0
  83. package/agent/patterns/bootstrap.template.md +0 -1237
  84. package/agent/patterns/pattern.template.md +0 -382
  85. package/agent/patterns/tanstack-cloudflare.acl-permissions.md +0 -332
  86. package/agent/patterns/tanstack-cloudflare.action-bar-item.md +0 -416
  87. package/agent/patterns/tanstack-cloudflare.api-route-handlers.md +0 -401
  88. package/agent/patterns/tanstack-cloudflare.auth-session-management.md +0 -387
  89. package/agent/patterns/tanstack-cloudflare.card-and-list.md +0 -271
  90. package/agent/patterns/tanstack-cloudflare.chat-engine.md +0 -353
  91. package/agent/patterns/tanstack-cloudflare.confirmation-tokens.md +0 -346
  92. package/agent/patterns/tanstack-cloudflare.durable-objects-websocket.md +0 -516
  93. package/agent/patterns/tanstack-cloudflare.email-service.md +0 -431
  94. package/agent/patterns/tanstack-cloudflare.expander.md +0 -98
  95. package/agent/patterns/tanstack-cloudflare.fcm-push.md +0 -115
  96. package/agent/patterns/tanstack-cloudflare.firebase-anonymous-sessions.md +0 -441
  97. package/agent/patterns/tanstack-cloudflare.firebase-auth.md +0 -348
  98. package/agent/patterns/tanstack-cloudflare.firebase-firestore.md +0 -550
  99. package/agent/patterns/tanstack-cloudflare.firebase-storage.md +0 -369
  100. package/agent/patterns/tanstack-cloudflare.form-controls.md +0 -145
  101. package/agent/patterns/tanstack-cloudflare.global-search-context.md +0 -93
  102. package/agent/patterns/tanstack-cloudflare.image-carousel.md +0 -126
  103. package/agent/patterns/tanstack-cloudflare.library-services.md +0 -553
  104. package/agent/patterns/tanstack-cloudflare.lightbox.md +0 -169
  105. package/agent/patterns/tanstack-cloudflare.markdown-content.md +0 -115
  106. package/agent/patterns/tanstack-cloudflare.mention-suggestions.md +0 -98
  107. package/agent/patterns/tanstack-cloudflare.modal.md +0 -156
  108. package/agent/patterns/tanstack-cloudflare.nextjs-to-tanstack-routing.md +0 -461
  109. package/agent/patterns/tanstack-cloudflare.notifications-engine.md +0 -151
  110. package/agent/patterns/tanstack-cloudflare.oauth-token-refresh.md +0 -90
  111. package/agent/patterns/tanstack-cloudflare.og-metadata.md +0 -296
  112. package/agent/patterns/tanstack-cloudflare.pagination.md +0 -442
  113. package/agent/patterns/tanstack-cloudflare.pill-input.md +0 -220
  114. package/agent/patterns/tanstack-cloudflare.provider-adapter.md +0 -401
  115. package/agent/patterns/tanstack-cloudflare.rate-limiting.md +0 -323
  116. package/agent/patterns/tanstack-cloudflare.scheduled-tasks.md +0 -338
  117. package/agent/patterns/tanstack-cloudflare.searchable-settings.md +0 -375
  118. package/agent/patterns/tanstack-cloudflare.slide-over.md +0 -129
  119. package/agent/patterns/tanstack-cloudflare.ssr-preload.md +0 -571
  120. package/agent/patterns/tanstack-cloudflare.third-party-api-integration.md +0 -508
  121. package/agent/patterns/tanstack-cloudflare.toast-system.md +0 -142
  122. package/agent/patterns/tanstack-cloudflare.unified-header.md +0 -280
  123. package/agent/patterns/tanstack-cloudflare.user-scoped-collections.md +0 -628
  124. package/agent/patterns/tanstack-cloudflare.websocket-manager.md +0 -237
  125. package/agent/patterns/tanstack-cloudflare.wrangler-configuration.md +0 -358
  126. package/agent/patterns/tanstack-cloudflare.zod-schema-validation.md +0 -336
  127. package/agent/progress.template.yaml +0 -161
  128. package/agent/progress.yaml +0 -145
  129. package/agent/schemas/package.schema.yaml +0 -276
  130. package/agent/scripts/acp.common.sh +0 -1781
  131. package/agent/scripts/acp.install.sh +0 -333
  132. package/agent/scripts/acp.package-create.sh +0 -924
  133. package/agent/scripts/acp.package-info.sh +0 -288
  134. package/agent/scripts/acp.package-install.sh +0 -893
  135. package/agent/scripts/acp.package-list.sh +0 -311
  136. package/agent/scripts/acp.package-publish.sh +0 -420
  137. package/agent/scripts/acp.package-remove.sh +0 -348
  138. package/agent/scripts/acp.package-search.sh +0 -156
  139. package/agent/scripts/acp.package-update.sh +0 -517
  140. package/agent/scripts/acp.package-validate.sh +0 -1018
  141. package/agent/scripts/acp.uninstall.sh +0 -85
  142. package/agent/scripts/acp.version-check-for-updates.sh +0 -98
  143. package/agent/scripts/acp.version-check.sh +0 -47
  144. package/agent/scripts/acp.version-update.sh +0 -176
  145. package/agent/scripts/acp.yaml-parser.sh +0 -985
  146. package/agent/scripts/acp.yaml-validate.sh +0 -205
  147. package/agent/tasks/.gitkeep +0 -0
  148. package/agent/tasks/milestone-1-project-scaffold-data-pipeline/task-1-initialize-tanstack-start-project.md +0 -210
  149. package/agent/tasks/milestone-1-project-scaffold-data-pipeline/task-2-implement-data-model-yaml-parser.md +0 -294
  150. package/agent/tasks/milestone-1-project-scaffold-data-pipeline/task-3-build-server-api-data-loading.md +0 -193
  151. package/agent/tasks/milestone-1-project-scaffold-data-pipeline/task-4-add-auto-refresh-sse.md +0 -262
  152. package/agent/tasks/milestone-2-dashboard-views-interaction/task-10-polish-integration-testing.md +0 -156
  153. package/agent/tasks/milestone-2-dashboard-views-interaction/task-5-build-dashboard-layout-routing.md +0 -178
  154. package/agent/tasks/milestone-2-dashboard-views-interaction/task-6-build-overview-page.md +0 -141
  155. package/agent/tasks/milestone-2-dashboard-views-interaction/task-7-implement-milestone-table-view.md +0 -153
  156. package/agent/tasks/milestone-2-dashboard-views-interaction/task-8-implement-milestone-tree-view.md +0 -174
  157. package/agent/tasks/milestone-2-dashboard-views-interaction/task-9-implement-search-filtering.md +0 -233
  158. package/agent/tasks/task-1-{title}.template.md +0 -244
  159. package/vitest.config.ts +0 -27
@@ -1,893 +0,0 @@
1
- #!/bin/bash
2
-
3
- # Agent Context Protocol (ACP) Package Install Script - OPTIMIZED VERSION
4
- # Installs third-party ACP packages with batched operations for 10x+ performance improvement
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 (same as original)
17
- REPO_URL=""
18
- INSTALL_PATTERNS=false
19
- INSTALL_COMMANDS=false
20
- INSTALL_DESIGNS=false
21
- INSTALL_FILES=false
22
- INSTALL_INDICES=false
23
- PATTERN_FILES=()
24
- COMMAND_FILES=()
25
- DESIGN_FILES=()
26
- FILE_FILES=()
27
- INDEX_FILES=()
28
- LIST_ONLY=false
29
- GLOBAL_INSTALL=false
30
- INSTALL_EXPERIMENTAL=false
31
- SKIP_CONFIRM=false
32
-
33
- while [[ $# -gt 0 ]]; do
34
- case $1 in
35
- --repo)
36
- REPO_URL="$2"
37
- shift 2
38
- ;;
39
- --global)
40
- GLOBAL_INSTALL=true
41
- shift
42
- ;;
43
- --experimental)
44
- INSTALL_EXPERIMENTAL=true
45
- shift
46
- ;;
47
- -y|--yes)
48
- SKIP_CONFIRM=true
49
- shift
50
- ;;
51
- --patterns)
52
- INSTALL_PATTERNS=true
53
- shift
54
- while [[ $# -gt 0 && ! $1 =~ ^- ]]; do
55
- PATTERN_FILES+=("$1")
56
- shift
57
- done
58
- ;;
59
- --commands)
60
- INSTALL_COMMANDS=true
61
- shift
62
- while [[ $# -gt 0 && ! $1 =~ ^- ]]; do
63
- COMMAND_FILES+=("$1")
64
- shift
65
- done
66
- ;;
67
- --designs)
68
- INSTALL_DESIGNS=true
69
- shift
70
- while [[ $# -gt 0 && ! $1 =~ ^- ]]; do
71
- DESIGN_FILES+=("$1")
72
- shift
73
- done
74
- ;;
75
- --files)
76
- INSTALL_FILES=true
77
- shift
78
- while [[ $# -gt 0 && ! $1 =~ ^- ]]; do
79
- FILE_FILES+=("$1")
80
- shift
81
- done
82
- ;;
83
- --indices)
84
- INSTALL_INDICES=true
85
- shift
86
- while [[ $# -gt 0 && ! $1 =~ ^- ]]; do
87
- INDEX_FILES+=("$1")
88
- shift
89
- done
90
- ;;
91
- --list)
92
- LIST_ONLY=true
93
- shift
94
- ;;
95
- *)
96
- echo "${RED}Error: Unknown option: $1${NC}"
97
- echo "Use --repo to specify repository URL"
98
- exit 1
99
- ;;
100
- esac
101
- done
102
-
103
- # Check if repository URL provided
104
- if [ -z "$REPO_URL" ]; then
105
- echo "${RED}Error: Repository URL required${NC}"
106
- echo "Usage: $0 --repo <repository-url> [options]"
107
- exit 1
108
- fi
109
-
110
- # Default: install everything if no selective flags specified
111
- if [[ "$INSTALL_PATTERNS" == false && "$INSTALL_COMMANDS" == false && "$INSTALL_DESIGNS" == false && "$INSTALL_FILES" == false && "$INSTALL_INDICES" == false ]]; then
112
- INSTALL_PATTERNS=true
113
- INSTALL_COMMANDS=true
114
- INSTALL_DESIGNS=true
115
- INSTALL_FILES=true
116
- INSTALL_INDICES=true
117
- fi
118
-
119
- echo "${BLUE}📦 ACP Package Installer (Optimized)${NC}"
120
- echo "========================================"
121
- echo ""
122
- echo "Repository: $REPO_URL"
123
- echo ""
124
-
125
- # Validate URL format
126
- if [[ ! "$REPO_URL" =~ ^https?:// ]] && [[ ! "$REPO_URL" =~ ^file:// ]] && [[ ! -d "$REPO_URL" ]]; then
127
- echo "${RED}Error: Invalid repository URL${NC}"
128
- exit 1
129
- fi
130
-
131
- # Create temporary directory
132
- TEMP_DIR=$(mktemp -d)
133
- trap "rm -rf $TEMP_DIR" EXIT
134
-
135
- echo "Cloning repository..."
136
- if [ -d "$REPO_URL" ]; then
137
- # Local directory - copy contents instead of clone
138
- cp -r "$REPO_URL"/* "$TEMP_DIR/" 2>/dev/null || cp -r "$REPO_URL"/.[!.]* "$TEMP_DIR/" 2>/dev/null || true
139
- echo "${GREEN}✓${NC} Local directory copied"
140
- elif ! git clone --depth 1 "$REPO_URL" "$TEMP_DIR" &>/dev/null; then
141
- echo "${RED}Error: Failed to clone repository${NC}"
142
- exit 1
143
- else
144
- echo "${GREEN}✓${NC} Repository cloned"
145
- fi
146
-
147
- echo "${GREEN}✓${NC} Repository cloned"
148
- echo ""
149
-
150
- # Check for agent/ directory
151
- if [ ! -d "$TEMP_DIR/agent" ]; then
152
- echo "${RED}Error: No agent/ directory found${NC}"
153
- exit 1
154
- fi
155
-
156
- # Determine installation directory and manifest
157
- if [ "$GLOBAL_INSTALL" = true ]; then
158
- INSTALL_BASE_DIR="$HOME/.acp/agent"
159
- MANIFEST_FILE="$HOME/.acp/agent/manifest.yaml"
160
- echo "${BLUE}Installing globally to ~/.acp/agent/${NC}"
161
- echo ""
162
- init_global_acp || {
163
- echo "${RED}Error: Failed to initialize global infrastructure${NC}" >&2
164
- exit 1
165
- }
166
- else
167
- INSTALL_BASE_DIR="./agent"
168
- MANIFEST_FILE="./agent/manifest.yaml"
169
- echo "${BLUE}Installing locally to ./agent/${NC}"
170
- echo ""
171
- init_manifest
172
- fi
173
-
174
- # Parse package metadata
175
- parse_package_metadata "$TEMP_DIR"
176
- COMMIT_HASH=$(get_commit_hash "$TEMP_DIR")
177
- info "Commit: $COMMIT_HASH"
178
- echo ""
179
-
180
- # Validate dependencies
181
- if [ -f "$TEMP_DIR/package.yaml" ]; then
182
- if ! validate_project_dependencies "$TEMP_DIR/package.yaml"; then
183
- echo "${RED}Installation cancelled due to dependency issues${NC}"
184
- exit 1
185
- fi
186
- fi
187
-
188
- # Directories to install from
189
- INSTALL_DIRS=()
190
- [ "$INSTALL_PATTERNS" = true ] && INSTALL_DIRS+=("patterns")
191
- [ "$INSTALL_COMMANDS" = true ] && INSTALL_DIRS+=("commands")
192
- [ "$INSTALL_DESIGNS" = true ] && INSTALL_DIRS+=("design")
193
- [ "$INSTALL_COMMANDS" = true ] && INSTALL_DIRS+=("scripts")
194
- [ "$INSTALL_FILES" = true ] && INSTALL_DIRS+=("files")
195
- [ "$INSTALL_INDICES" = true ] && INSTALL_DIRS+=("index")
196
-
197
- # Mapping from dir names to manifest keys (dir → manifest key)
198
- declare -A MANIFEST_KEYS=(
199
- ["patterns"]="patterns"
200
- ["commands"]="commands"
201
- ["design"]="designs"
202
- ["scripts"]="scripts"
203
- ["files"]="files"
204
- ["index"]="indices"
205
- )
206
-
207
- # ============================================================================
208
- # OPTIMIZATION: Collect all files first, then batch process
209
- # ============================================================================
210
-
211
- # Arrays to hold all files to install
212
- declare -A ALL_FILES_TO_INSTALL # Key: dir, Value: space-separated file paths
213
- declare -A FILE_METADATA # Key: "dir/filename", Value: "version|experimental"
214
-
215
- # Track installed commands for script-command binding resolution
216
- INSTALLED_COMMANDS=()
217
-
218
- INSTALLED_COUNT=0
219
- SKIPPED_COUNT=0
220
-
221
- # Template file metadata (populated during scanning when contents.files exists)
222
- declare -A FILE_TARGETS # Key: "files/relpath", Value: target directory path
223
- declare -A FILE_VARS # Key: "files/relpath", Value: "VAR1,VAR2,..."
224
- declare -A COLLECTED_VARS # Key: "VARNAME", Value: user-provided value
225
- HAS_FILE_METADATA=false
226
-
227
- echo "Scanning for installable files..."
228
- echo ""
229
-
230
- # Parse package.yaml once for experimental checking
231
- if [ -f "$TEMP_DIR/package.yaml" ]; then
232
- yaml_parse "$TEMP_DIR/package.yaml"
233
- fi
234
-
235
- # Collect all files to install
236
- for dir in "${INSTALL_DIRS[@]}"; do
237
- SOURCE_DIR="$TEMP_DIR/agent/$dir"
238
-
239
- if [ ! -d "$SOURCE_DIR" ]; then
240
- continue
241
- fi
242
-
243
- # Determine which files to process
244
- declare -n FILE_LIST
245
- case "$dir" in
246
- patterns) FILE_LIST=PATTERN_FILES ;;
247
- commands) FILE_LIST=COMMAND_FILES ;;
248
- design) FILE_LIST=DESIGN_FILES ;;
249
- scripts) FILE_LIST=COMMAND_FILES ;;
250
- files) FILE_LIST=FILE_FILES ;;
251
- index) FILE_LIST=INDEX_FILES ;;
252
- esac
253
-
254
- # Collect files
255
- FILES_TO_PROCESS=()
256
- if [ ${#FILE_LIST[@]} -gt 0 ]; then
257
- # Selective installation
258
- for file_name in "${FILE_LIST[@]}"; do
259
- if [ "$dir" = "scripts" ]; then
260
- [[ "$file_name" != *.sh ]] && file_name="${file_name}.sh"
261
- elif [ "$dir" != "files" ]; then
262
- [[ "$file_name" != *.md ]] && file_name="${file_name}.md"
263
- fi
264
-
265
- file_path="$SOURCE_DIR/$file_name"
266
- if [ -f "$file_path" ]; then
267
- FILES_TO_PROCESS+=("$file_path")
268
-
269
- # For selective files, also collect metadata from package.yaml
270
- if [ "$dir" = "files" ] && [ -f "$TEMP_DIR/package.yaml" ]; then
271
- _sel_idx=0
272
- while true; do
273
- _sel_name=$(yaml_query ".contents.files[$_sel_idx].name" 2>/dev/null || echo "")
274
- [ -z "$_sel_name" ] || [ "$_sel_name" = "null" ] && break
275
- if [ "$_sel_name" = "$file_name" ]; then
276
- HAS_FILE_METADATA=true
277
- _sel_target=$(yaml_query ".contents.files[$_sel_idx].target" 2>/dev/null || echo "")
278
- [ -n "$_sel_target" ] && [ "$_sel_target" != "null" ] && FILE_TARGETS["files/$file_name"]="$_sel_target"
279
- _sel_var_idx=0
280
- _sel_vars=""
281
- while true; do
282
- _sel_var=$(yaml_query ".contents.files[$_sel_idx].variables[$_sel_var_idx]" 2>/dev/null || echo "")
283
- [ -z "$_sel_var" ] || [ "$_sel_var" = "null" ] && break
284
- [ -n "$_sel_vars" ] && _sel_vars="$_sel_vars,$_sel_var" || _sel_vars="$_sel_var"
285
- _sel_var_idx=$((_sel_var_idx + 1))
286
- done
287
- [ -n "$_sel_vars" ] && FILE_VARS["files/$file_name"]="$_sel_vars"
288
- break
289
- fi
290
- _sel_idx=$((_sel_idx + 1))
291
- done
292
- fi
293
- else
294
- echo "${YELLOW}⚠${NC} File not found in $dir/: $file_name"
295
- SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
296
- fi
297
- done
298
- else
299
- # Install all files
300
- if [ "$dir" = "files" ]; then
301
- # Check if package.yaml has contents.files metadata
302
- _first_file=$(yaml_query ".contents.files[0].name" 2>/dev/null || echo "")
303
- if [ -f "$TEMP_DIR/package.yaml" ] && [ -n "$_first_file" ] && [ "$_first_file" != "null" ]; then
304
- # Use package.yaml contents.files as source of truth
305
- HAS_FILE_METADATA=true
306
- _file_idx=0
307
- while true; do
308
- _fname=$(yaml_query ".contents.files[$_file_idx].name" 2>/dev/null || echo "")
309
- [ -z "$_fname" ] || [ "$_fname" = "null" ] && break
310
-
311
- if [ -f "$SOURCE_DIR/$_fname" ]; then
312
- FILES_TO_PROCESS+=("$SOURCE_DIR/$_fname")
313
-
314
- # Store target metadata
315
- _target=$(yaml_query ".contents.files[$_file_idx].target" 2>/dev/null || echo "")
316
- [ -n "$_target" ] && [ "$_target" != "null" ] && FILE_TARGETS["files/$_fname"]="$_target"
317
-
318
- # Collect variable names
319
- _var_idx=0
320
- _vars=""
321
- while true; do
322
- _var=$(yaml_query ".contents.files[$_file_idx].variables[$_var_idx]" 2>/dev/null || echo "")
323
- [ -z "$_var" ] || [ "$_var" = "null" ] && break
324
- [ -n "$_vars" ] && _vars="$_vars,$_var" || _vars="$_var"
325
- _var_idx=$((_var_idx + 1))
326
- done
327
- [ -n "$_vars" ] && FILE_VARS["files/$_fname"]="$_vars"
328
- else
329
- echo " ${YELLOW}⚠${NC} Declared in package.yaml but not found: agent/files/$_fname"
330
- SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
331
- fi
332
-
333
- _file_idx=$((_file_idx + 1))
334
- done
335
- else
336
- # Fallback: recursive scan (backward compat for packages without contents.files)
337
- while IFS= read -r file; do
338
- [ -n "$file" ] && FILES_TO_PROCESS+=("$file")
339
- done < <(find "$SOURCE_DIR" -type f)
340
- fi
341
- elif [ "$dir" = "scripts" ]; then
342
- while IFS= read -r file; do
343
- [ -n "$file" ] && FILES_TO_PROCESS+=("$file")
344
- done < <(find "$SOURCE_DIR" -maxdepth 1 -name "*.sh" ! -name "*.template.sh" -type f)
345
- elif [ "$dir" = "index" ]; then
346
- while IFS= read -r file; do
347
- [ -n "$file" ] && FILES_TO_PROCESS+=("$file")
348
- done < <(find "$SOURCE_DIR" -maxdepth 1 -name "*.yaml" ! -name "*.template.yaml" -type f)
349
- else
350
- while IFS= read -r file; do
351
- [ -n "$file" ] && FILES_TO_PROCESS+=("$file")
352
- done < <(find "$SOURCE_DIR" -maxdepth 1 -name "*.md" ! -name "*.template.md" -type f)
353
- fi
354
- fi
355
-
356
- if [ ${#FILES_TO_PROCESS[@]} -eq 0 ]; then
357
- unset -n FILE_LIST
358
- continue
359
- fi
360
-
361
- if [ "$dir" = "files" ] && [ "$HAS_FILE_METADATA" = false ]; then
362
- echo "${BLUE}📁 $dir/${NC} (${#FILES_TO_PROCESS[@]} file(s)) → installs to ./"
363
- else
364
- echo "${BLUE}📁 $dir/${NC} (${#FILES_TO_PROCESS[@]} file(s))"
365
- fi
366
-
367
- # Validate files
368
- VALID_FILES=()
369
- for file in "${FILES_TO_PROCESS[@]}"; do
370
- # For files/ dir, use relative path from SOURCE_DIR; otherwise basename
371
- if [ "$dir" = "files" ]; then
372
- filename="${file#$SOURCE_DIR/}"
373
- else
374
- filename=$(basename "$file")
375
- fi
376
-
377
- # Validation (not applied to files/ directory)
378
- if [ "$dir" = "commands" ]; then
379
- if [[ "$filename" =~ ^acp\. ]]; then
380
- echo " ${RED}✗${NC} $filename (reserved namespace 'acp')"
381
- SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
382
- continue
383
- fi
384
- if ! grep -q "🤖 Agent Directive" "$file"; then
385
- echo " ${YELLOW}⚠${NC} $filename (missing agent directive - skipping)"
386
- SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
387
- continue
388
- fi
389
- fi
390
-
391
- if [ "$dir" = "scripts" ]; then
392
- if [[ "$filename" =~ ^acp\. ]]; then
393
- echo " ${RED}✗${NC} $filename (reserved namespace 'acp')"
394
- SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
395
- continue
396
- fi
397
- fi
398
-
399
- # Check experimental status
400
- is_experimental=""
401
- if [ -f "$TEMP_DIR/package.yaml" ]; then
402
- if [ "$dir" = "files" ] && [ "$HAS_FILE_METADATA" = false ]; then
403
- : # No per-file experimental marking without metadata
404
- elif [ "$dir" = "files" ]; then
405
- # Files entries have more fields (name, description, target, required, experimental)
406
- # so need a wider context window (-A 6) to catch experimental: true
407
- is_experimental=$(grep -A 1000 "^ ${dir}:" "$TEMP_DIR/package.yaml" 2>/dev/null | grep -A 6 "name: ${filename}" | grep "^ *experimental: true" | grep -v "^[[:space:]]*#" | head -1)
408
- else
409
- is_experimental=$(grep -A 1000 "^ ${dir}:" "$TEMP_DIR/package.yaml" 2>/dev/null | grep -A 2 "name: ${filename}" | grep "^ *experimental: true" | grep -v "^[[:space:]]*#" | head -1)
410
- fi
411
- fi
412
-
413
- if [ -n "$is_experimental" ] && [ "$INSTALL_EXPERIMENTAL" = false ]; then
414
- echo " ${DIM}⊘${NC} $filename (experimental - use --experimental)"
415
- SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
416
- continue
417
- fi
418
-
419
- # Get file version
420
- FILE_VERSION=$(get_file_version "$TEMP_DIR/package.yaml" "$dir" "$filename")
421
-
422
- # Store metadata
423
- FILE_METADATA["$dir/$filename"]="$FILE_VERSION|$is_experimental"
424
-
425
- # Add to valid files
426
- VALID_FILES+=("$file")
427
-
428
- # Determine target path for overwrite check
429
- if [ "$dir" = "files" ] && [ "$HAS_FILE_METADATA" = true ]; then
430
- _file_target="${FILE_TARGETS[files/$filename]:-./}"
431
- _bname=$(basename "$filename")
432
- _bname="${_bname%.template}"
433
- target_path="${_file_target}${_bname}"
434
- elif [ "$dir" = "files" ]; then
435
- target_path="./$filename"
436
- else
437
- target_path="$INSTALL_BASE_DIR/$dir/$filename"
438
- fi
439
-
440
- # Build display info for files with metadata
441
- _display_extra=""
442
- if [ "$dir" = "files" ] && [ "$HAS_FILE_METADATA" = true ]; then
443
- _file_vars="${FILE_VARS[files/$filename]:-}"
444
- _display_extra=" → $target_path"
445
- [ -n "$_file_vars" ] && _display_extra="$_display_extra (variables: $_file_vars)"
446
- fi
447
-
448
- if [ -f "$target_path" ]; then
449
- echo " ${YELLOW}⚠${NC} $filename${_display_extra} (will overwrite)"
450
- else
451
- echo " ${GREEN}✓${NC} $filename${_display_extra}"
452
- fi
453
-
454
- INSTALLED_COUNT=$((INSTALLED_COUNT + 1))
455
- done
456
-
457
- # Store valid files for this directory
458
- if [ ${#VALID_FILES[@]} -gt 0 ]; then
459
- ALL_FILES_TO_INSTALL["$dir"]="${VALID_FILES[*]}"
460
- fi
461
-
462
- unset -n FILE_LIST
463
- echo ""
464
- done
465
-
466
- # Warn about unrecognized directories in the package
467
- KNOWN_DIRS="patterns commands design scripts files index"
468
- if [ -d "$TEMP_DIR/agent" ]; then
469
- UNRECOGNIZED=()
470
- while IFS= read -r pkg_dir; do
471
- dir_name=$(basename "$pkg_dir")
472
- if ! echo " $KNOWN_DIRS " | grep -q " $dir_name "; then
473
- UNRECOGNIZED+=("$dir_name")
474
- fi
475
- done < <(find "$TEMP_DIR/agent" -mindepth 1 -maxdepth 1 -type d)
476
-
477
- if [ ${#UNRECOGNIZED[@]} -gt 0 ]; then
478
- echo "${YELLOW}⚠ Unrecognized directories in package (not installed):${NC}"
479
- for udir in "${UNRECOGNIZED[@]}"; do
480
- echo " $udir/"
481
- done
482
- echo ""
483
- fi
484
- fi
485
-
486
- # Exit if nothing to install
487
- if [ $INSTALLED_COUNT -eq 0 ]; then
488
- echo "${RED}Error: No valid files to install${NC}"
489
- [ $SKIPPED_COUNT -gt 0 ] && echo "Skipped $SKIPPED_COUNT file(s)"
490
- exit 1
491
- fi
492
-
493
- # Confirm installation
494
- echo "Ready to install $INSTALLED_COUNT file(s)"
495
- [ $SKIPPED_COUNT -gt 0 ] && echo "($SKIPPED_COUNT file(s) will be skipped)"
496
- echo ""
497
-
498
- if [ "$LIST_ONLY" = true ]; then
499
- echo "${BLUE}(dry run — no files were installed)${NC}"
500
- exit 0
501
- fi
502
-
503
- if [ "$SKIP_CONFIRM" = false ]; then
504
- read -p "Proceed with installation? (y/N) " -n 1 -r
505
- echo
506
- if [[ ! $REPLY =~ ^[Yy]$ ]]; then
507
- echo "Installation cancelled."
508
- exit 0
509
- fi
510
- else
511
- echo "Auto-confirming installation (-y flag)"
512
- fi
513
-
514
- echo ""
515
-
516
- # Collect template variables from user (if any files have variables declared)
517
- if [ ${#FILE_VARS[@]} -gt 0 ]; then
518
- echo "${BLUE}Collecting template variables...${NC}"
519
-
520
- # Build list of unique variables across all templates
521
- _all_vars=""
522
- for _key in "${!FILE_VARS[@]}"; do
523
- IFS=',' read -ra _var_arr <<< "${FILE_VARS[$_key]}"
524
- for _var in "${_var_arr[@]}"; do
525
- if [[ ! ",$_all_vars," =~ ",$_var," ]]; then
526
- [ -n "$_all_vars" ] && _all_vars="$_all_vars,$_var" || _all_vars="$_var"
527
- fi
528
- done
529
- done
530
-
531
- # Prompt for each unique variable
532
- IFS=',' read -ra _unique_vars <<< "$_all_vars"
533
- for _var in "${_unique_vars[@]}"; do
534
- read -p " Enter $_var: " _value
535
- COLLECTED_VARS["$_var"]="$_value"
536
- done
537
-
538
- echo "${GREEN}✓${NC} Variables collected"
539
- echo ""
540
- fi
541
-
542
- echo "Installing files..."
543
-
544
- # ============================================================================
545
- # OPTIMIZATION: Batch file operations
546
- # ============================================================================
547
-
548
- # Check if file should be installed based on experimental status
549
- should_install_file() {
550
- local filename="$1"
551
- local file_type="$2" # commands, patterns, designs, scripts
552
-
553
- # If no package.yaml, install everything
554
- if [ ! -f "$TEMP_DIR/package.yaml" ]; then
555
- return 0
556
- fi
557
-
558
- # Check if file is marked experimental in package.yaml
559
- # Extract only the relevant section, then find the specific entry
560
- local section=$(grep -A 1000 "^ ${file_type}:" "$TEMP_DIR/package.yaml" 2>/dev/null | grep -B 1000 "^ [a-z]" 2>/dev/null | head -n -1 || true)
561
- local is_experimental=$(echo "$section" | grep -A 3 "^ - name: ${filename}$" 2>/dev/null | grep "^ *experimental: true" 2>/dev/null | grep -v "^[[:space:]]*#" | head -1 || true)
562
-
563
- if [ -n "$is_experimental" ]; then
564
- if [ "$INSTALL_EXPERIMENTAL" = true ]; then
565
- echo " ${YELLOW}⚠${NC} Installing experimental: ${filename}"
566
- return 0 # Install it
567
- else
568
- echo " ${DIM}⊘${NC} Skipping experimental: ${filename} (use --experimental to install)"
569
- return 1 # Skip it
570
- fi
571
- fi
572
-
573
- return 0 # Install non-experimental files
574
- }
575
-
576
- # Add package to manifest once
577
- add_package_to_manifest "$PACKAGE_NAME" "$REPO_URL" "$PACKAGE_VERSION" "$COMMIT_HASH"
578
-
579
- # Batch copy all files (skip scripts — handled via script-command binding below)
580
- for dir in "${!ALL_FILES_TO_INSTALL[@]}"; do
581
- SOURCE_DIR="$TEMP_DIR/agent/$dir"
582
-
583
- # Skip scripts in first pass — install selectively after commands via script-command binding
584
- if [ "$dir" = "scripts" ]; then
585
- continue
586
- fi
587
-
588
- # Copy all files
589
- for file in ${ALL_FILES_TO_INSTALL[$dir]}; do
590
- if [ "$dir" = "files" ]; then
591
- rel_path="${file#$SOURCE_DIR/}"
592
-
593
- if [ "$HAS_FILE_METADATA" = true ]; then
594
- # Metadata-aware installation: use target path and variable substitution
595
- _file_target="${FILE_TARGETS[files/$rel_path]:-./}"
596
- _bname=$(basename "$rel_path")
597
- _bname="${_bname%.template}"
598
- _dest="${_file_target}${_bname}"
599
-
600
- # Safety validation: reject paths that escape project root
601
- if [[ "$_dest" =~ \.\. ]] || [[ "$_dest" =~ ^/ ]]; then
602
- echo " ${RED}✗${NC} Skipping $rel_path (unsafe target: $_dest)"
603
- continue
604
- fi
605
-
606
- mkdir -p "$(dirname "$_dest")"
607
-
608
- # Apply variable substitution if template has variables
609
- _file_vars="${FILE_VARS[files/$rel_path]:-}"
610
- if [ -n "$_file_vars" ] && [ ${#COLLECTED_VARS[@]} -gt 0 ]; then
611
- cp "$file" "$_dest"
612
- IFS=',' read -ra _var_arr <<< "$_file_vars"
613
- for _var in "${_var_arr[@]}"; do
614
- _value="${COLLECTED_VARS[$_var]:-}"
615
- if [ -n "$_value" ]; then
616
- _escaped=$(printf '%s\n' "$_value" | sed 's/[&/\]/\\&/g')
617
- _sed_i "s|{{${_var}}}|${_escaped}|g" "$_dest"
618
- fi
619
- done
620
- else
621
- cp "$file" "$_dest"
622
- fi
623
- else
624
- # Backward compat: install to project root preserving subdirectory structure
625
- target_dir="$(dirname "./$rel_path")"
626
- mkdir -p "$target_dir"
627
- cp "$file" "./$rel_path"
628
- fi
629
- else
630
- mkdir -p "$INSTALL_BASE_DIR/$dir"
631
- filename=$(basename "$file")
632
- cp "$file" "$INSTALL_BASE_DIR/$dir/$filename"
633
- fi
634
-
635
- # Track installed commands for script dependency resolution
636
- if [ "$dir" = "commands" ]; then
637
- filename=$(basename "$file")
638
- INSTALLED_COMMANDS+=("$filename")
639
- fi
640
- done
641
- done
642
-
643
- # ============================================================================
644
- # Script-Command Binding: Install scripts based on command dependencies
645
- # ============================================================================
646
-
647
- if [ -f "$TEMP_DIR/package.yaml" ] && [ ${#INSTALLED_COMMANDS[@]} -gt 0 ]; then
648
- echo "Resolving script dependencies..."
649
- echo " Installed commands: ${INSTALLED_COMMANDS[@]}"
650
-
651
- # Collect required scripts from installed commands using YAML parser
652
- REQUIRED_SCRIPTS=()
653
- for cmd in "${INSTALLED_COMMANDS[@]}"; do
654
- # Find the command index in the array
655
- cmd_index=0
656
- while true; do
657
- cmd_name=$(yaml_get_nested "$TEMP_DIR/package.yaml" "contents.commands[$cmd_index].name" 2>/dev/null || echo "")
658
- if [ -z "$cmd_name" ] || [ "$cmd_name" = "null" ]; then
659
- break
660
- fi
661
-
662
- if [ "$cmd_name" = "$cmd" ]; then
663
- # Found the command, now get its scripts
664
- script_index=0
665
- while true; do
666
- script=$(yaml_get_nested "$TEMP_DIR/package.yaml" "contents.commands[$cmd_index].scripts[$script_index]" 2>/dev/null || echo "")
667
- if [ -z "$script" ] || [ "$script" = "null" ]; then
668
- break
669
- fi
670
-
671
- # Add to required scripts (with deduplication)
672
- already_added=false
673
- for existing in "${REQUIRED_SCRIPTS[@]}"; do
674
- if [ "$existing" = "$script" ]; then
675
- already_added=true
676
- break
677
- fi
678
- done
679
-
680
- if [ "$already_added" = false ]; then
681
- REQUIRED_SCRIPTS+=("$script")
682
- fi
683
-
684
- script_index=$((script_index + 1))
685
- done
686
- break
687
- fi
688
-
689
- cmd_index=$((cmd_index + 1))
690
- done
691
- done
692
-
693
- echo " Found ${#REQUIRED_SCRIPTS[@]} required script(s): ${REQUIRED_SCRIPTS[@]}"
694
-
695
- # Install required scripts and add to ALL_FILES_TO_INSTALL for batch manifest update
696
- SCRIPT_FILES_LIST=""
697
- if [ ${#REQUIRED_SCRIPTS[@]} -gt 0 ]; then
698
- mkdir -p "$INSTALL_BASE_DIR/scripts"
699
- for script in "${REQUIRED_SCRIPTS[@]}"; do
700
- script_path="$TEMP_DIR/agent/scripts/$script"
701
-
702
- # Check if script exists
703
- if [ ! -f "$script_path" ]; then
704
- echo " ${RED}✗${NC} Script not found: $script (declared in package.yaml)"
705
- continue
706
- fi
707
-
708
- # Check if should install based on experimental status
709
- if ! should_install_file "$script" "scripts"; then
710
- continue
711
- fi
712
-
713
- # Copy script and make executable
714
- cp "$script_path" "$INSTALL_BASE_DIR/scripts/$script"
715
- chmod +x "$INSTALL_BASE_DIR/scripts/$script"
716
-
717
- # Get file version and store metadata
718
- FILE_VERSION=$(get_file_version "$TEMP_DIR/package.yaml" "scripts" "$script")
719
-
720
- # Check experimental status
721
- is_experimental=""
722
- if [ -f "$TEMP_DIR/package.yaml" ]; then
723
- is_experimental=$(grep -A 1000 "^ scripts:" "$TEMP_DIR/package.yaml" 2>/dev/null | grep -A 2 "name: ${script}" | grep "^ *experimental: true" | grep -v "^[[:space:]]*#" | head -1)
724
- fi
725
- FILE_METADATA["scripts/$script"]="$FILE_VERSION|$is_experimental"
726
-
727
- # Track for batch processing
728
- if [ -n "$SCRIPT_FILES_LIST" ]; then
729
- SCRIPT_FILES_LIST="$SCRIPT_FILES_LIST $script_path"
730
- else
731
- SCRIPT_FILES_LIST="$script_path"
732
- fi
733
- done
734
- fi
735
-
736
- # Update ALL_FILES_TO_INSTALL with resolved scripts
737
- if [ -n "$SCRIPT_FILES_LIST" ]; then
738
- ALL_FILES_TO_INSTALL["scripts"]="$SCRIPT_FILES_LIST"
739
- fi
740
- echo ""
741
- elif [ -d "$TEMP_DIR/agent/scripts" ] && [ -n "${ALL_FILES_TO_INSTALL[scripts]+x}" ]; then
742
- # Scripts were collected during scan but no package.yaml script-command binding
743
- # Install all scripts that passed validation (backward compatibility)
744
- for file in ${ALL_FILES_TO_INSTALL[scripts]}; do
745
- filename=$(basename "$file")
746
- mkdir -p "$INSTALL_BASE_DIR/scripts"
747
- cp "$file" "$INSTALL_BASE_DIR/scripts/$filename"
748
- chmod +x "$INSTALL_BASE_DIR/scripts/$filename"
749
- done
750
- fi
751
-
752
- # ============================================================================
753
- # OPTIMIZATION: Batch checksum calculation
754
- # ============================================================================
755
-
756
- echo " ${BLUE}Calculating checksums...${NC}"
757
-
758
- # Collect all installed files for batch checksum
759
- ALL_INSTALLED_FILES=()
760
- for dir in "${!ALL_FILES_TO_INSTALL[@]}"; do
761
- SOURCE_DIR="$TEMP_DIR/agent/$dir"
762
- for file in ${ALL_FILES_TO_INSTALL[$dir]}; do
763
- if [ "$dir" = "files" ]; then
764
- rel_path="${file#$SOURCE_DIR/}"
765
- if [ "$HAS_FILE_METADATA" = true ]; then
766
- _file_target="${FILE_TARGETS[files/$rel_path]:-./}"
767
- _bname=$(basename "$rel_path")
768
- _bname="${_bname%.template}"
769
- ALL_INSTALLED_FILES+=("${_file_target}${_bname}")
770
- else
771
- ALL_INSTALLED_FILES+=("./$rel_path")
772
- fi
773
- else
774
- filename=$(basename "$file")
775
- ALL_INSTALLED_FILES+=("$INSTALL_BASE_DIR/$dir/$filename")
776
- fi
777
- done
778
- done
779
-
780
- # Calculate all checksums in one pass
781
- declare -A CHECKSUMS
782
- if [ ${#ALL_INSTALLED_FILES[@]} -gt 0 ]; then
783
- while IFS= read -r line; do
784
- checksum=$(echo "$line" | awk '{print $1}')
785
- filepath=$(echo "$line" | awk '{$1=""; print substr($0,2)}')
786
- CHECKSUMS["$filepath"]="$checksum"
787
- done < <(if command -v sha256sum >/dev/null 2>&1; then sha256sum "${ALL_INSTALLED_FILES[@]}" 2>/dev/null; elif command -v shasum >/dev/null 2>&1; then shasum -a 256 "${ALL_INSTALLED_FILES[@]}" 2>/dev/null; fi)
788
- fi
789
-
790
- # ============================================================================
791
- # OPTIMIZATION: Batch manifest update
792
- # ============================================================================
793
-
794
- echo " ${BLUE}Updating manifest...${NC}"
795
-
796
- # Parse manifest once
797
- yaml_parse "$MANIFEST_FILE"
798
-
799
- # Add all files to manifest in memory
800
- timestamp=$(get_timestamp)
801
- for dir in "${!ALL_FILES_TO_INSTALL[@]}"; do
802
- SOURCE_DIR="$TEMP_DIR/agent/$dir"
803
- manifest_key="${MANIFEST_KEYS[$dir]:-$dir}"
804
-
805
- for file in ${ALL_FILES_TO_INSTALL[$dir]}; do
806
- # Determine filename and installed filepath based on dir type
807
- if [ "$dir" = "files" ]; then
808
- filename="${file#$SOURCE_DIR/}"
809
- if [ "$HAS_FILE_METADATA" = true ]; then
810
- _file_target="${FILE_TARGETS[files/$filename]:-./}"
811
- _bname=$(basename "$filename")
812
- _bname="${_bname%.template}"
813
- filepath="${_file_target}${_bname}"
814
- else
815
- filepath="./$filename"
816
- fi
817
- else
818
- filename=$(basename "$file")
819
- filepath="$INSTALL_BASE_DIR/$dir/$filename"
820
- fi
821
-
822
- # Get metadata
823
- IFS='|' read -r file_version is_experimental <<< "${FILE_METADATA[$dir/$filename]}"
824
-
825
- # Get checksum
826
- checksum="${CHECKSUMS[$filepath]:-unknown}"
827
-
828
- # Append to manifest using mapped key
829
- obj_node=$(yaml_array_append_object ".packages.${PACKAGE_NAME}.files.${manifest_key}")
830
- yaml_object_set "$obj_node" "name" "$filename" >/dev/null
831
- yaml_object_set "$obj_node" "version" "$file_version" >/dev/null
832
- yaml_object_set "$obj_node" "installed_at" "$timestamp" >/dev/null
833
- yaml_object_set "$obj_node" "modified" "false" >/dev/null
834
- yaml_object_set "$obj_node" "checksum" "sha256:$checksum" >/dev/null
835
-
836
- if [ -n "$is_experimental" ]; then
837
- yaml_object_set "$obj_node" "experimental" "true" >/dev/null
838
- fi
839
-
840
- # For files with metadata: store target path and variables
841
- if [ "$dir" = "files" ] && [ "$HAS_FILE_METADATA" = true ]; then
842
- yaml_object_set "$obj_node" "target" "$filepath" >/dev/null
843
- # Store variable values if this file had variables
844
- _file_vars_manifest="${FILE_VARS[files/$filename]:-}"
845
- if [ -n "$_file_vars_manifest" ]; then
846
- # Create nested map node for variables
847
- _vars_node=$(create_node "map" "variables" "" "$obj_node")
848
- add_child "$obj_node" "$_vars_node"
849
- IFS=',' read -ra _var_names <<< "$_file_vars_manifest"
850
- for _vname in "${_var_names[@]}"; do
851
- _vval="${COLLECTED_VARS[$_vname]:-}"
852
- if [ -n "$_vval" ]; then
853
- yaml_object_set "$_vars_node" "$_vname" "$_vval" >/dev/null
854
- fi
855
- done
856
- fi
857
- fi
858
-
859
- if [ "$dir" = "scripts" ]; then
860
- echo " ${GREEN}✓${NC} Installed $dir/$filename (v$file_version) [executable]"
861
- elif [ "$dir" = "files" ]; then
862
- echo " ${GREEN}✓${NC} Installed $filename → $filepath"
863
- else
864
- echo " ${GREEN}✓${NC} Installed $dir/$filename (v$file_version)"
865
- fi
866
- done
867
- done
868
-
869
- # Write manifest once at the end
870
- yaml_write "$MANIFEST_FILE"
871
-
872
- echo ""
873
-
874
- # Success message
875
- if [ "$GLOBAL_INSTALL" = true ]; then
876
- echo "${GREEN}✅ Package installed globally!${NC}"
877
- echo ""
878
- echo "Location: $INSTALL_BASE_DIR"
879
- echo "Manifest: $MANIFEST_FILE"
880
- else
881
- echo "${GREEN}✅ Installation complete!${NC}"
882
- echo ""
883
- echo "Installed $INSTALLED_COUNT file(s) from:"
884
- echo " $REPO_URL"
885
- echo ""
886
- echo "Package: $PACKAGE_NAME ($PACKAGE_VERSION)"
887
- echo "Manifest: agent/manifest.yaml updated"
888
- fi
889
-
890
- echo ""
891
- echo "${YELLOW}⚠️ Security Reminder:${NC}"
892
- echo "Review installed files before using them."
893
- echo ""