@prmichaelsen/acp-visualizer 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/README.md +68 -0
- package/agent/commands/acp.clarification-address.md +417 -0
- package/agent/commands/acp.clarification-capture.md +386 -0
- package/agent/commands/acp.clarification-create.md +437 -0
- package/agent/commands/acp.clarifications-research.md +326 -0
- package/agent/commands/acp.command-create.md +432 -0
- package/agent/commands/acp.design-create.md +286 -0
- package/agent/commands/acp.design-reference.md +355 -0
- package/agent/commands/acp.handoff.md +270 -0
- package/agent/commands/acp.index.md +423 -0
- package/agent/commands/acp.init.md +546 -0
- package/agent/commands/acp.package-create.md +895 -0
- package/agent/commands/acp.package-info.md +212 -0
- package/agent/commands/acp.package-install.md +539 -0
- package/agent/commands/acp.package-list.md +280 -0
- package/agent/commands/acp.package-publish.md +541 -0
- package/agent/commands/acp.package-remove.md +293 -0
- package/agent/commands/acp.package-search.md +307 -0
- package/agent/commands/acp.package-update.md +361 -0
- package/agent/commands/acp.package-validate.md +540 -0
- package/agent/commands/acp.pattern-create.md +386 -0
- package/agent/commands/acp.plan.md +587 -0
- package/agent/commands/acp.proceed.md +882 -0
- package/agent/commands/acp.project-create.md +675 -0
- package/agent/commands/acp.project-info.md +312 -0
- package/agent/commands/acp.project-list.md +226 -0
- package/agent/commands/acp.project-remove.md +379 -0
- package/agent/commands/acp.project-set.md +227 -0
- package/agent/commands/acp.project-update.md +307 -0
- package/agent/commands/acp.projects-restore.md +228 -0
- package/agent/commands/acp.projects-sync.md +347 -0
- package/agent/commands/acp.report.md +407 -0
- package/agent/commands/acp.resume.md +239 -0
- package/agent/commands/acp.sessions.md +301 -0
- package/agent/commands/acp.status.md +293 -0
- package/agent/commands/acp.sync.md +364 -0
- package/agent/commands/acp.task-create.md +500 -0
- package/agent/commands/acp.update.md +302 -0
- package/agent/commands/acp.validate.md +466 -0
- package/agent/commands/acp.version-check-for-updates.md +276 -0
- package/agent/commands/acp.version-check.md +191 -0
- package/agent/commands/acp.version-update.md +289 -0
- package/agent/commands/command.template.md +339 -0
- package/agent/commands/git.commit.md +526 -0
- package/agent/commands/git.init.md +514 -0
- package/agent/commands/tanstack-cloudflare.deploy.md +272 -0
- package/agent/commands/tanstack-cloudflare.tail.md +275 -0
- package/agent/design/.gitkeep +0 -0
- package/agent/design/design.template.md +154 -0
- package/agent/design/local.dashboard-layout-routing.md +288 -0
- package/agent/design/local.data-model-yaml-parsing.md +310 -0
- package/agent/design/local.search-filtering.md +331 -0
- package/agent/design/local.server-api-auto-refresh.md +235 -0
- package/agent/design/local.table-tree-views.md +299 -0
- package/agent/design/local.visualizer-requirements.md +349 -0
- package/agent/design/requirements.template.md +387 -0
- package/agent/index/.gitkeep +0 -0
- package/agent/index/acp.core.yaml +137 -0
- package/agent/index/local.main.template.yaml +37 -0
- package/agent/manifest.template.yaml +13 -0
- package/agent/manifest.yaml +302 -0
- package/agent/milestones/.gitkeep +0 -0
- package/agent/milestones/milestone-1-project-scaffold-data-pipeline.md +67 -0
- package/agent/milestones/milestone-1-{title}.template.md +206 -0
- package/agent/milestones/milestone-2-dashboard-views-interaction.md +79 -0
- package/agent/package.template.yaml +86 -0
- package/agent/patterns/.gitkeep +0 -0
- package/agent/patterns/bootstrap.template.md +1237 -0
- package/agent/patterns/pattern.template.md +382 -0
- package/agent/patterns/tanstack-cloudflare.acl-permissions.md +332 -0
- package/agent/patterns/tanstack-cloudflare.action-bar-item.md +416 -0
- package/agent/patterns/tanstack-cloudflare.api-route-handlers.md +401 -0
- package/agent/patterns/tanstack-cloudflare.auth-session-management.md +387 -0
- package/agent/patterns/tanstack-cloudflare.card-and-list.md +271 -0
- package/agent/patterns/tanstack-cloudflare.chat-engine.md +353 -0
- package/agent/patterns/tanstack-cloudflare.confirmation-tokens.md +346 -0
- package/agent/patterns/tanstack-cloudflare.durable-objects-websocket.md +516 -0
- package/agent/patterns/tanstack-cloudflare.email-service.md +431 -0
- package/agent/patterns/tanstack-cloudflare.expander.md +98 -0
- package/agent/patterns/tanstack-cloudflare.fcm-push.md +115 -0
- package/agent/patterns/tanstack-cloudflare.firebase-anonymous-sessions.md +441 -0
- package/agent/patterns/tanstack-cloudflare.firebase-auth.md +348 -0
- package/agent/patterns/tanstack-cloudflare.firebase-firestore.md +550 -0
- package/agent/patterns/tanstack-cloudflare.firebase-storage.md +369 -0
- package/agent/patterns/tanstack-cloudflare.form-controls.md +145 -0
- package/agent/patterns/tanstack-cloudflare.global-search-context.md +93 -0
- package/agent/patterns/tanstack-cloudflare.image-carousel.md +126 -0
- package/agent/patterns/tanstack-cloudflare.library-services.md +553 -0
- package/agent/patterns/tanstack-cloudflare.lightbox.md +169 -0
- package/agent/patterns/tanstack-cloudflare.markdown-content.md +115 -0
- package/agent/patterns/tanstack-cloudflare.mention-suggestions.md +98 -0
- package/agent/patterns/tanstack-cloudflare.modal.md +156 -0
- package/agent/patterns/tanstack-cloudflare.nextjs-to-tanstack-routing.md +461 -0
- package/agent/patterns/tanstack-cloudflare.notifications-engine.md +151 -0
- package/agent/patterns/tanstack-cloudflare.oauth-token-refresh.md +90 -0
- package/agent/patterns/tanstack-cloudflare.og-metadata.md +296 -0
- package/agent/patterns/tanstack-cloudflare.pagination.md +442 -0
- package/agent/patterns/tanstack-cloudflare.pill-input.md +220 -0
- package/agent/patterns/tanstack-cloudflare.provider-adapter.md +401 -0
- package/agent/patterns/tanstack-cloudflare.rate-limiting.md +323 -0
- package/agent/patterns/tanstack-cloudflare.scheduled-tasks.md +338 -0
- package/agent/patterns/tanstack-cloudflare.searchable-settings.md +375 -0
- package/agent/patterns/tanstack-cloudflare.slide-over.md +129 -0
- package/agent/patterns/tanstack-cloudflare.ssr-preload.md +571 -0
- package/agent/patterns/tanstack-cloudflare.third-party-api-integration.md +508 -0
- package/agent/patterns/tanstack-cloudflare.toast-system.md +142 -0
- package/agent/patterns/tanstack-cloudflare.unified-header.md +280 -0
- package/agent/patterns/tanstack-cloudflare.user-scoped-collections.md +628 -0
- package/agent/patterns/tanstack-cloudflare.websocket-manager.md +237 -0
- package/agent/patterns/tanstack-cloudflare.wrangler-configuration.md +358 -0
- package/agent/patterns/tanstack-cloudflare.zod-schema-validation.md +336 -0
- package/agent/progress.template.yaml +161 -0
- package/agent/progress.yaml +145 -0
- package/agent/schemas/package.schema.yaml +276 -0
- package/agent/scripts/acp.common.sh +1781 -0
- package/agent/scripts/acp.install.sh +333 -0
- package/agent/scripts/acp.package-create.sh +924 -0
- package/agent/scripts/acp.package-info.sh +288 -0
- package/agent/scripts/acp.package-install.sh +893 -0
- package/agent/scripts/acp.package-list.sh +311 -0
- package/agent/scripts/acp.package-publish.sh +420 -0
- package/agent/scripts/acp.package-remove.sh +348 -0
- package/agent/scripts/acp.package-search.sh +156 -0
- package/agent/scripts/acp.package-update.sh +517 -0
- package/agent/scripts/acp.package-validate.sh +1018 -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 +176 -0
- package/agent/scripts/acp.yaml-parser.sh +985 -0
- package/agent/scripts/acp.yaml-validate.sh +205 -0
- package/agent/tasks/.gitkeep +0 -0
- package/agent/tasks/milestone-1-project-scaffold-data-pipeline/task-1-initialize-tanstack-start-project.md +210 -0
- package/agent/tasks/milestone-1-project-scaffold-data-pipeline/task-2-implement-data-model-yaml-parser.md +294 -0
- package/agent/tasks/milestone-1-project-scaffold-data-pipeline/task-3-build-server-api-data-loading.md +193 -0
- package/agent/tasks/milestone-1-project-scaffold-data-pipeline/task-4-add-auto-refresh-sse.md +262 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-10-polish-integration-testing.md +156 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-5-build-dashboard-layout-routing.md +178 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-6-build-overview-page.md +141 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-7-implement-milestone-table-view.md +153 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-8-implement-milestone-tree-view.md +174 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-9-implement-search-filtering.md +233 -0
- package/agent/tasks/task-1-{title}.template.md +244 -0
- package/bin/visualize.mjs +84 -0
- package/package.json +48 -0
- package/src/components/ExtraFieldsBadge.tsx +15 -0
- package/src/components/FilterBar.tsx +33 -0
- package/src/components/Header.tsx +23 -0
- package/src/components/MilestoneTable.tsx +167 -0
- package/src/components/MilestoneTree.tsx +84 -0
- package/src/components/ProgressBar.tsx +20 -0
- package/src/components/SearchInput.tsx +22 -0
- package/src/components/Sidebar.tsx +54 -0
- package/src/components/StatusBadge.tsx +23 -0
- package/src/components/StatusDot.tsx +12 -0
- package/src/components/TaskList.tsx +36 -0
- package/src/components/ViewToggle.tsx +31 -0
- package/src/lib/config.ts +8 -0
- package/src/lib/file-watcher.ts +43 -0
- package/src/lib/search.ts +48 -0
- package/src/lib/types.ts +73 -0
- package/src/lib/useAutoRefresh.ts +31 -0
- package/src/lib/useCollapse.ts +31 -0
- package/src/lib/useFilteredData.ts +55 -0
- package/src/lib/yaml-loader-real.spec.ts +47 -0
- package/src/lib/yaml-loader.spec.ts +201 -0
- package/src/lib/yaml-loader.ts +265 -0
- package/src/routeTree.gen.ts +140 -0
- package/src/router.tsx +10 -0
- package/src/routes/__root.tsx +75 -0
- package/src/routes/api/watch.ts +29 -0
- package/src/routes/index.tsx +115 -0
- package/src/routes/milestones.tsx +50 -0
- package/src/routes/search.tsx +84 -0
- package/src/routes/tasks.tsx +63 -0
- package/src/services/progress-database.service.ts +46 -0
- package/src/styles.css +25 -0
- package/tsconfig.json +24 -0
- package/vite.config.ts +16 -0
- package/vitest.config.ts +27 -0
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Agent Context Protocol (ACP) Package Update Script
|
|
4
|
+
# Updates installed ACP packages to their latest versions
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# Source common utilities
|
|
9
|
+
SCRIPT_DIR="$(dirname "$0")"
|
|
10
|
+
. "${SCRIPT_DIR}/acp.common.sh"
|
|
11
|
+
|
|
12
|
+
# Initialize colors
|
|
13
|
+
init_colors
|
|
14
|
+
|
|
15
|
+
# Parse arguments
|
|
16
|
+
PACKAGE_NAME=""
|
|
17
|
+
CHECK_ONLY=false
|
|
18
|
+
SKIP_MODIFIED=false
|
|
19
|
+
FORCE=false
|
|
20
|
+
AUTO_CONFIRM=false
|
|
21
|
+
GLOBAL_MODE=false
|
|
22
|
+
|
|
23
|
+
while [[ $# -gt 0 ]]; do
|
|
24
|
+
case $1 in
|
|
25
|
+
--global|-g)
|
|
26
|
+
GLOBAL_MODE=true
|
|
27
|
+
shift
|
|
28
|
+
;;
|
|
29
|
+
--check)
|
|
30
|
+
CHECK_ONLY=true
|
|
31
|
+
shift
|
|
32
|
+
;;
|
|
33
|
+
--skip-modified)
|
|
34
|
+
SKIP_MODIFIED=true
|
|
35
|
+
shift
|
|
36
|
+
;;
|
|
37
|
+
--force)
|
|
38
|
+
FORCE=true
|
|
39
|
+
shift
|
|
40
|
+
;;
|
|
41
|
+
-y|--yes)
|
|
42
|
+
AUTO_CONFIRM=true
|
|
43
|
+
shift
|
|
44
|
+
;;
|
|
45
|
+
*)
|
|
46
|
+
PACKAGE_NAME="$1"
|
|
47
|
+
shift
|
|
48
|
+
;;
|
|
49
|
+
esac
|
|
50
|
+
done
|
|
51
|
+
|
|
52
|
+
# Check if experimental feature is already installed
|
|
53
|
+
is_experimental_installed() {
|
|
54
|
+
local file_name="$1"
|
|
55
|
+
local file_type="$2"
|
|
56
|
+
local package_name="$3"
|
|
57
|
+
|
|
58
|
+
# Check manifest to see if this file is already installed
|
|
59
|
+
local installed=$(awk -v pkg="$package_name" -v type="$file_type" -v fname="$file_name" '
|
|
60
|
+
BEGIN { in_pkg=0; in_type=0 }
|
|
61
|
+
$0 ~ "^ " pkg ":" { in_pkg=1; next }
|
|
62
|
+
in_pkg && /^ [a-z]/ { in_pkg=0 }
|
|
63
|
+
in_pkg && $0 ~ "^ " type ":" { in_type=1; next }
|
|
64
|
+
in_type && /^ [a-z]/ { in_type=0 }
|
|
65
|
+
in_type && /^ - name:/ && $3 == fname { print "found"; exit }
|
|
66
|
+
' "$MANIFEST_FILE")
|
|
67
|
+
|
|
68
|
+
if [ -n "$installed" ]; then
|
|
69
|
+
return 0 # Already installed
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
return 1 # Not installed
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
# Check if feature graduated from experimental to stable
|
|
76
|
+
check_graduation() {
|
|
77
|
+
local file_name="$1"
|
|
78
|
+
local file_type="$2"
|
|
79
|
+
local package_name="$3"
|
|
80
|
+
local package_yaml_path="$4"
|
|
81
|
+
|
|
82
|
+
# Check if was experimental in manifest
|
|
83
|
+
local was_experimental=$(awk -v pkg="$package_name" -v type="$file_type" -v fname="$file_name" '
|
|
84
|
+
BEGIN { in_pkg=0; in_type=0; in_file=0 }
|
|
85
|
+
$0 ~ "^ " pkg ":" { in_pkg=1; next }
|
|
86
|
+
in_pkg && /^ [a-z]/ { in_pkg=0 }
|
|
87
|
+
in_pkg && $0 ~ "^ " type ":" { in_type=1; next }
|
|
88
|
+
in_type && /^ [a-z]/ { in_type=0 }
|
|
89
|
+
in_type && /^ - name:/ && $3 == fname { in_file=1; next }
|
|
90
|
+
in_file && /^ - name:/ { in_file=0 }
|
|
91
|
+
in_file && /^ experimental:/ { print $2; exit }
|
|
92
|
+
' "$MANIFEST_FILE")
|
|
93
|
+
|
|
94
|
+
# Check if is experimental in new package.yaml
|
|
95
|
+
local is_experimental=$(grep -A 1000 "^ ${file_type}:" "$package_yaml_path" 2>/dev/null | grep -A 2 "name: ${file_name}" | grep "^ *experimental: true" | grep -v "^[[:space:]]*#" | head -1)
|
|
96
|
+
|
|
97
|
+
if [ "$was_experimental" = "true" ] && [ -z "$is_experimental" ]; then
|
|
98
|
+
return 0 # Graduated
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
return 1 # Not graduated
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
# Check for updates for a package
|
|
105
|
+
# Usage: check_package_for_updates "package_name"
|
|
106
|
+
# Returns: 0 if updates available, 1 if up to date
|
|
107
|
+
check_package_for_updates() {
|
|
108
|
+
local package_name="$1"
|
|
109
|
+
|
|
110
|
+
# Get current version and source from manifest
|
|
111
|
+
local current_version
|
|
112
|
+
current_version=$(awk -v pkg="$package_name" '
|
|
113
|
+
$0 ~ "^ " pkg ":" { in_pkg=1; next }
|
|
114
|
+
in_pkg && /^ [a-z]/ { in_pkg=0 }
|
|
115
|
+
in_pkg && /^ package_version:/ { print $2; exit }
|
|
116
|
+
' "$MANIFEST_FILE")
|
|
117
|
+
|
|
118
|
+
local source_url
|
|
119
|
+
source_url=$(awk -v pkg="$package_name" '
|
|
120
|
+
$0 ~ "^ " pkg ":" { in_pkg=1; next }
|
|
121
|
+
in_pkg && /^ [a-z]/ { in_pkg=0 }
|
|
122
|
+
in_pkg && /^ source:/ { print $2; exit }
|
|
123
|
+
' "$MANIFEST_FILE")
|
|
124
|
+
|
|
125
|
+
if [ -z "$current_version" ] || [ -z "$source_url" ]; then
|
|
126
|
+
warn "Could not read package metadata for $package_name"
|
|
127
|
+
return 1
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
info "Checking $package_name ($current_version)..."
|
|
131
|
+
|
|
132
|
+
# Clone repository to temp location
|
|
133
|
+
local temp_dir
|
|
134
|
+
temp_dir=$(mktemp -d)
|
|
135
|
+
trap "rm -rf $temp_dir" RETURN
|
|
136
|
+
|
|
137
|
+
if ! git clone --depth 1 "$source_url" "$temp_dir" &>/dev/null; then
|
|
138
|
+
warn "Failed to clone repository for $package_name"
|
|
139
|
+
return 1
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
# Get remote version
|
|
143
|
+
local remote_version
|
|
144
|
+
if [ -f "$temp_dir/package.yaml" ]; then
|
|
145
|
+
remote_version=$(awk '/^version:/ {print $2; exit}' "$temp_dir/package.yaml")
|
|
146
|
+
else
|
|
147
|
+
warn "No package.yaml found in repository"
|
|
148
|
+
return 1
|
|
149
|
+
fi
|
|
150
|
+
|
|
151
|
+
# Compare versions
|
|
152
|
+
local comparison
|
|
153
|
+
comparison=$(compare_versions "$current_version" "$remote_version")
|
|
154
|
+
|
|
155
|
+
if [ "$comparison" = "newer" ]; then
|
|
156
|
+
echo " ${GREEN}✓${NC} Update available: $current_version → $remote_version"
|
|
157
|
+
return 0
|
|
158
|
+
else
|
|
159
|
+
echo " ${GREEN}✓${NC} Up to date: $current_version"
|
|
160
|
+
return 1
|
|
161
|
+
fi
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
# Update a package
|
|
165
|
+
# Usage: update_package "package_name"
|
|
166
|
+
update_package() {
|
|
167
|
+
local package_name="$1"
|
|
168
|
+
|
|
169
|
+
echo "${BLUE}Updating $package_name...${NC}"
|
|
170
|
+
|
|
171
|
+
# Get package info from manifest
|
|
172
|
+
local source_url
|
|
173
|
+
source_url=$(awk -v pkg="$package_name" '
|
|
174
|
+
$0 ~ "^ " pkg ":" { in_pkg=1; next }
|
|
175
|
+
in_pkg && /^ [a-z]/ { in_pkg=0 }
|
|
176
|
+
in_pkg && /^ source:/ { print $2; exit }
|
|
177
|
+
' "$MANIFEST_FILE")
|
|
178
|
+
|
|
179
|
+
# Clone latest version
|
|
180
|
+
local temp_dir
|
|
181
|
+
temp_dir=$(mktemp -d)
|
|
182
|
+
trap "rm -rf $temp_dir" RETURN
|
|
183
|
+
|
|
184
|
+
if ! git clone --depth 1 "$source_url" "$temp_dir" &>/dev/null; then
|
|
185
|
+
die "Failed to clone repository"
|
|
186
|
+
fi
|
|
187
|
+
|
|
188
|
+
# Parse new package metadata
|
|
189
|
+
parse_package_metadata "$temp_dir"
|
|
190
|
+
local new_commit
|
|
191
|
+
new_commit=$(get_commit_hash "$temp_dir")
|
|
192
|
+
|
|
193
|
+
# Get list of installed files from manifest
|
|
194
|
+
local updated_count=0
|
|
195
|
+
local skipped_count=0
|
|
196
|
+
local modified_files=()
|
|
197
|
+
|
|
198
|
+
# Check for modified files first
|
|
199
|
+
for file_type in patterns commands design indices; do
|
|
200
|
+
local files
|
|
201
|
+
files=$(awk -v pkg="$package_name" -v type="$file_type" '
|
|
202
|
+
BEGIN { in_pkg=0; in_type=0 }
|
|
203
|
+
$0 ~ "^ " pkg ":" { in_pkg=1; next }
|
|
204
|
+
in_pkg && /^ [a-z]/ { in_pkg=0 }
|
|
205
|
+
in_pkg && $0 ~ "^ " type ":" { in_type=1; next }
|
|
206
|
+
in_type && /^ [a-z]/ { in_type=0 }
|
|
207
|
+
in_type && /^ - name:/ { print $3 }
|
|
208
|
+
' "$MANIFEST_FILE")
|
|
209
|
+
|
|
210
|
+
for file_name in $files; do
|
|
211
|
+
if is_file_modified "$package_name" "$file_type" "$file_name"; then
|
|
212
|
+
modified_files+=("$file_type/$file_name")
|
|
213
|
+
fi
|
|
214
|
+
done
|
|
215
|
+
done
|
|
216
|
+
|
|
217
|
+
# Check template files for modifications
|
|
218
|
+
local _tmpl_entries
|
|
219
|
+
_tmpl_entries=$(awk -v pkg="$package_name" '
|
|
220
|
+
BEGIN { in_pkg=0; in_files=0; name="" }
|
|
221
|
+
$0 ~ "^ " pkg ":" { in_pkg=1; next }
|
|
222
|
+
in_pkg && /^ [a-z]/ { in_pkg=0 }
|
|
223
|
+
in_pkg && /^ files:$/ { in_files=1; next }
|
|
224
|
+
in_files && /^ [a-z]/ { in_files=0 }
|
|
225
|
+
in_files && /^ - name:/ { name=$3 }
|
|
226
|
+
in_files && /^ target:/ { $1=""; gsub(/^ +/, ""); print name "|" $0 }
|
|
227
|
+
' "$MANIFEST_FILE")
|
|
228
|
+
while IFS='|' read -r _fname _ftarget; do
|
|
229
|
+
[ -z "$_fname" ] && continue
|
|
230
|
+
if [ -n "$_ftarget" ] && is_template_file_modified "$package_name" "$_fname" "$_ftarget"; then
|
|
231
|
+
modified_files+=("files/$_fname → $_ftarget")
|
|
232
|
+
fi
|
|
233
|
+
done <<< "$_tmpl_entries"
|
|
234
|
+
|
|
235
|
+
# Handle modified files
|
|
236
|
+
if [ ${#modified_files[@]} -gt 0 ] && [ "$FORCE" = false ]; then
|
|
237
|
+
echo ""
|
|
238
|
+
echo "${YELLOW}⚠️ Modified files detected:${NC}"
|
|
239
|
+
for file in "${modified_files[@]}"; do
|
|
240
|
+
echo " - $file"
|
|
241
|
+
done
|
|
242
|
+
echo ""
|
|
243
|
+
|
|
244
|
+
if [ "$SKIP_MODIFIED" = true ]; then
|
|
245
|
+
echo "Will skip modified files (--skip-modified)"
|
|
246
|
+
elif [ "$AUTO_CONFIRM" = false ]; then
|
|
247
|
+
read -p "Overwrite modified files? (y/N) " -n 1 -r
|
|
248
|
+
echo
|
|
249
|
+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
250
|
+
SKIP_MODIFIED=true
|
|
251
|
+
echo "Skipping modified files"
|
|
252
|
+
fi
|
|
253
|
+
fi
|
|
254
|
+
echo ""
|
|
255
|
+
fi
|
|
256
|
+
|
|
257
|
+
# Mapping from manifest type to directory name
|
|
258
|
+
local _dir_for_type
|
|
259
|
+
_type_to_dir() {
|
|
260
|
+
case "$1" in
|
|
261
|
+
indices) echo "index" ;;
|
|
262
|
+
*) echo "$1" ;;
|
|
263
|
+
esac
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
# Update files
|
|
267
|
+
for file_type in patterns commands design indices; do
|
|
268
|
+
local files
|
|
269
|
+
files=$(awk -v pkg="$package_name" -v type="$file_type" '
|
|
270
|
+
BEGIN { in_pkg=0; in_type=0 }
|
|
271
|
+
$0 ~ "^ " pkg ":" { in_pkg=1; next }
|
|
272
|
+
in_pkg && /^ [a-z]/ { in_pkg=0 }
|
|
273
|
+
in_pkg && $0 ~ "^ " type ":" { in_type=1; next }
|
|
274
|
+
in_type && /^ [a-z]/ { in_type=0 }
|
|
275
|
+
in_type && /^ - name:/ { print $3 }
|
|
276
|
+
' "$MANIFEST_FILE")
|
|
277
|
+
|
|
278
|
+
for file_name in $files; do
|
|
279
|
+
# Check if file should be skipped due to local modifications
|
|
280
|
+
if [ "$SKIP_MODIFIED" = true ]; then
|
|
281
|
+
if printf '%s\n' "${modified_files[@]}" | grep -q "^${file_type}/${file_name}$"; then
|
|
282
|
+
echo " ${YELLOW}⊘${NC} Skipped $file_type/$file_name (modified locally)"
|
|
283
|
+
((skipped_count++))
|
|
284
|
+
continue
|
|
285
|
+
fi
|
|
286
|
+
fi
|
|
287
|
+
|
|
288
|
+
# Map manifest type to directory name
|
|
289
|
+
local _file_dir=$(_type_to_dir "$file_type")
|
|
290
|
+
|
|
291
|
+
# Check if file exists in new version
|
|
292
|
+
if [ ! -f "$temp_dir/agent/$_file_dir/$file_name" ]; then
|
|
293
|
+
warn "File no longer exists in package: $_file_dir/$file_name"
|
|
294
|
+
((skipped_count++))
|
|
295
|
+
continue
|
|
296
|
+
fi
|
|
297
|
+
|
|
298
|
+
# Check if this is a new experimental feature
|
|
299
|
+
local is_experimental=$(grep -A 1000 "^ ${file_type}:" "$temp_dir/package.yaml" 2>/dev/null | grep -A 2 "name: ${file_name}" | grep "^ *experimental: true" | grep -v "^[[:space:]]*#" | head -1)
|
|
300
|
+
|
|
301
|
+
if [ -n "$is_experimental" ]; then
|
|
302
|
+
# This is an experimental feature
|
|
303
|
+
if ! is_experimental_installed "$file_name" "$file_type" "$package_name"; then
|
|
304
|
+
# Not installed, skip it
|
|
305
|
+
echo " ${DIM}⊘${NC} Skipping new experimental: $file_type/$file_name (use --experimental with install to add)"
|
|
306
|
+
((skipped_count++))
|
|
307
|
+
continue
|
|
308
|
+
fi
|
|
309
|
+
# Already installed, update it
|
|
310
|
+
echo " ${YELLOW}↻${NC} Updating experimental: $file_type/$file_name"
|
|
311
|
+
else
|
|
312
|
+
# Check if graduated from experimental to stable
|
|
313
|
+
if check_graduation "$file_name" "$file_type" "$package_name" "$temp_dir/package.yaml"; then
|
|
314
|
+
echo " ${GREEN}🎓${NC} Graduated to stable: $file_type/$file_name"
|
|
315
|
+
fi
|
|
316
|
+
echo " ${BLUE}↻${NC} Updating: $file_type/$file_name"
|
|
317
|
+
fi
|
|
318
|
+
|
|
319
|
+
# Copy file
|
|
320
|
+
mkdir -p "agent/$_file_dir"
|
|
321
|
+
cp "$temp_dir/agent/$_file_dir/$file_name" "agent/$_file_dir/"
|
|
322
|
+
|
|
323
|
+
# Get new version and checksum
|
|
324
|
+
local new_version
|
|
325
|
+
new_version=$(get_file_version "$temp_dir/package.yaml" "$file_type" "$file_name")
|
|
326
|
+
local new_checksum
|
|
327
|
+
new_checksum=$(calculate_checksum "agent/$_file_dir/$file_name")
|
|
328
|
+
|
|
329
|
+
# Update manifest (including experimental status)
|
|
330
|
+
update_file_in_manifest "$package_name" "$file_type" "$file_name" "$new_version" "$new_checksum"
|
|
331
|
+
|
|
332
|
+
# Update experimental flag in manifest if needed
|
|
333
|
+
if [ -n "$is_experimental" ]; then
|
|
334
|
+
# Still experimental, ensure flag is set
|
|
335
|
+
_sed_i "/packages:/{:a;N;/name: ${file_name}/!ba;s/\(name: ${file_name}\)/\1\n experimental: true/;}" "$MANIFEST_FILE" 2>/dev/null || true
|
|
336
|
+
elif check_graduation "$file_name" "$file_type" "$package_name" "$temp_dir/package.yaml"; then
|
|
337
|
+
# Graduated, remove experimental flag
|
|
338
|
+
_sed_i "/name: ${file_name}/{N;s/\n *experimental: true//;}" "$MANIFEST_FILE" 2>/dev/null || true
|
|
339
|
+
fi
|
|
340
|
+
|
|
341
|
+
echo " ${GREEN}✓${NC} Updated $file_type/$file_name (v$new_version)"
|
|
342
|
+
((updated_count++))
|
|
343
|
+
done
|
|
344
|
+
done
|
|
345
|
+
|
|
346
|
+
# Update template files (installed at target paths)
|
|
347
|
+
while IFS='|' read -r _fname _ftarget; do
|
|
348
|
+
[ -z "$_fname" ] && continue
|
|
349
|
+
|
|
350
|
+
# Check if modified and should skip
|
|
351
|
+
if [ "$SKIP_MODIFIED" = true ]; then
|
|
352
|
+
if printf '%s\n' "${modified_files[@]}" | grep -q "^files/$_fname"; then
|
|
353
|
+
echo " ${YELLOW}⊘${NC} Skipped files/$_fname (modified locally)"
|
|
354
|
+
((skipped_count++))
|
|
355
|
+
continue
|
|
356
|
+
fi
|
|
357
|
+
fi
|
|
358
|
+
|
|
359
|
+
# Check if source file exists in new version
|
|
360
|
+
local _src_file="$temp_dir/agent/files/$_fname"
|
|
361
|
+
if [ ! -f "$_src_file" ]; then
|
|
362
|
+
warn "File no longer exists in package: files/$_fname"
|
|
363
|
+
((skipped_count++))
|
|
364
|
+
continue
|
|
365
|
+
fi
|
|
366
|
+
|
|
367
|
+
# Copy to target path
|
|
368
|
+
mkdir -p "$(dirname "$_ftarget")"
|
|
369
|
+
cp "$_src_file" "$_ftarget"
|
|
370
|
+
|
|
371
|
+
# Re-apply variable substitution if stored
|
|
372
|
+
local _stored_vars
|
|
373
|
+
_stored_vars=$(get_template_file_variables "$package_name" "$_fname")
|
|
374
|
+
if [ -n "$_stored_vars" ]; then
|
|
375
|
+
while IFS='=' read -r _vname _vval; do
|
|
376
|
+
[ -z "$_vname" ] && continue
|
|
377
|
+
local _escaped
|
|
378
|
+
_escaped=$(printf '%s\n' "$_vval" | sed 's/[&/\]/\\&/g')
|
|
379
|
+
_sed_i "s|{{${_vname}}}|${_escaped}|g" "$_ftarget"
|
|
380
|
+
done <<< "$_stored_vars"
|
|
381
|
+
fi
|
|
382
|
+
|
|
383
|
+
# Update manifest
|
|
384
|
+
local _new_checksum
|
|
385
|
+
_new_checksum=$(calculate_checksum "$_ftarget")
|
|
386
|
+
local _new_version
|
|
387
|
+
_new_version=$(get_file_version "$temp_dir/package.yaml" "files" "$_fname")
|
|
388
|
+
update_template_file_in_manifest "$package_name" "$_fname" "$_new_version" "$_new_checksum"
|
|
389
|
+
|
|
390
|
+
echo " ${GREEN}✓${NC} Updated files/$_fname → $_ftarget"
|
|
391
|
+
((updated_count++))
|
|
392
|
+
done <<< "$_tmpl_entries"
|
|
393
|
+
|
|
394
|
+
# Update package metadata in manifest
|
|
395
|
+
local timestamp
|
|
396
|
+
timestamp=$(get_timestamp)
|
|
397
|
+
|
|
398
|
+
# Update using awk
|
|
399
|
+
local temp_file
|
|
400
|
+
temp_file=$(mktemp)
|
|
401
|
+
|
|
402
|
+
awk -v pkg="$package_name" -v ver="$PACKAGE_VERSION" -v commit="$new_commit" -v ts="$timestamp" '
|
|
403
|
+
BEGIN { in_pkg=0 }
|
|
404
|
+
$0 ~ "^ " pkg ":" { in_pkg=1; print; next }
|
|
405
|
+
in_pkg && /^ [a-z]/ { in_pkg=0; print; next }
|
|
406
|
+
in_pkg && /^ package_version:/ { print " package_version: " ver; next }
|
|
407
|
+
in_pkg && /^ commit:/ { print " commit: " commit; next }
|
|
408
|
+
in_pkg && /^ updated_at:/ { print " updated_at: " ts; next }
|
|
409
|
+
{ print }
|
|
410
|
+
' "$MANIFEST_FILE" > "$temp_file"
|
|
411
|
+
|
|
412
|
+
mv "$temp_file" "$MANIFEST_FILE"
|
|
413
|
+
|
|
414
|
+
# Update manifest timestamp
|
|
415
|
+
update_manifest_timestamp
|
|
416
|
+
|
|
417
|
+
echo ""
|
|
418
|
+
success "Updated $package_name: $updated_count file(s)"
|
|
419
|
+
if [ $skipped_count -gt 0 ]; then
|
|
420
|
+
echo " Skipped: $skipped_count file(s)"
|
|
421
|
+
fi
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
# Main script execution
|
|
425
|
+
echo "${BLUE}📦 ACP Package Updater${NC}"
|
|
426
|
+
echo "========================================"
|
|
427
|
+
echo ""
|
|
428
|
+
|
|
429
|
+
# Determine manifest file based on mode
|
|
430
|
+
if [ "$GLOBAL_MODE" = true ]; then
|
|
431
|
+
MANIFEST_FILE="$HOME/.acp/manifest.yaml"
|
|
432
|
+
echo "${BLUE}Updating global packages...${NC}"
|
|
433
|
+
echo ""
|
|
434
|
+
else
|
|
435
|
+
MANIFEST_FILE="./agent/manifest.yaml"
|
|
436
|
+
echo "${BLUE}Updating packages...${NC}"
|
|
437
|
+
echo ""
|
|
438
|
+
fi
|
|
439
|
+
|
|
440
|
+
# Check if manifest exists
|
|
441
|
+
if [ ! -f "$MANIFEST_FILE" ]; then
|
|
442
|
+
if [ "$GLOBAL_MODE" = true ]; then
|
|
443
|
+
die "No global manifest found. No global packages installed."
|
|
444
|
+
else
|
|
445
|
+
die "No manifest found. No packages installed."
|
|
446
|
+
fi
|
|
447
|
+
fi
|
|
448
|
+
|
|
449
|
+
# Source YAML parser
|
|
450
|
+
source_yaml_parser
|
|
451
|
+
|
|
452
|
+
# Get list of installed packages
|
|
453
|
+
INSTALLED_PACKAGES=$(awk '/^ [a-z]/ && !/^ / && /:$/ {gsub(/:/, ""); print $1}' "$MANIFEST_FILE")
|
|
454
|
+
|
|
455
|
+
if [ -z "$INSTALLED_PACKAGES" ]; then
|
|
456
|
+
echo "${YELLOW}No packages installed${NC}"
|
|
457
|
+
exit 0
|
|
458
|
+
fi
|
|
459
|
+
|
|
460
|
+
# If no package specified, update all
|
|
461
|
+
if [ -z "$PACKAGE_NAME" ]; then
|
|
462
|
+
echo "Checking all packages for updates..."
|
|
463
|
+
echo ""
|
|
464
|
+
|
|
465
|
+
UPDATES_AVAILABLE=false
|
|
466
|
+
for pkg in $INSTALLED_PACKAGES; do
|
|
467
|
+
if check_package_for_updates "$pkg"; then
|
|
468
|
+
UPDATES_AVAILABLE=true
|
|
469
|
+
fi
|
|
470
|
+
done
|
|
471
|
+
|
|
472
|
+
if [ "$UPDATES_AVAILABLE" = false ]; then
|
|
473
|
+
echo "${GREEN}✓${NC} All packages are up to date"
|
|
474
|
+
exit 0
|
|
475
|
+
fi
|
|
476
|
+
|
|
477
|
+
if [ "$CHECK_ONLY" = true ]; then
|
|
478
|
+
echo ""
|
|
479
|
+
echo "To update all packages: $0"
|
|
480
|
+
echo "To update specific package: $0 <package-name>"
|
|
481
|
+
exit 0
|
|
482
|
+
fi
|
|
483
|
+
|
|
484
|
+
# Update all packages
|
|
485
|
+
echo ""
|
|
486
|
+
if [ "$AUTO_CONFIRM" = false ]; then
|
|
487
|
+
read -p "Update all packages? (y/N) " -n 1 -r
|
|
488
|
+
echo
|
|
489
|
+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
490
|
+
echo "Update cancelled"
|
|
491
|
+
exit 0
|
|
492
|
+
fi
|
|
493
|
+
fi
|
|
494
|
+
|
|
495
|
+
echo ""
|
|
496
|
+
for pkg in $INSTALLED_PACKAGES; do
|
|
497
|
+
update_package "$pkg"
|
|
498
|
+
echo ""
|
|
499
|
+
done
|
|
500
|
+
else
|
|
501
|
+
# Update specific package
|
|
502
|
+
if ! echo "$INSTALLED_PACKAGES" | grep -q "^${PACKAGE_NAME}$"; then
|
|
503
|
+
die "Package not installed: $PACKAGE_NAME"
|
|
504
|
+
fi
|
|
505
|
+
|
|
506
|
+
if check_package_for_updates "$PACKAGE_NAME"; then
|
|
507
|
+
if [ "$CHECK_ONLY" = false ]; then
|
|
508
|
+
echo ""
|
|
509
|
+
update_package "$PACKAGE_NAME"
|
|
510
|
+
fi
|
|
511
|
+
else
|
|
512
|
+
echo "${GREEN}✓${NC} Package is up to date"
|
|
513
|
+
fi
|
|
514
|
+
fi
|
|
515
|
+
|
|
516
|
+
echo ""
|
|
517
|
+
echo "${GREEN}✅ Update complete!${NC}"
|