@prmichaelsen/remember-mcp 3.15.4 → 3.15.6

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 (132) hide show
  1. package/AGENT.md +363 -5
  2. package/CHANGELOG.md +7 -0
  3. package/agent/commands/acp.clarification-capture.md +386 -0
  4. package/agent/commands/acp.clarification-create.md +50 -0
  5. package/agent/commands/acp.command-create.md +60 -0
  6. package/agent/commands/acp.design-create.md +62 -0
  7. package/agent/commands/acp.design-reference.md +355 -0
  8. package/agent/commands/acp.index.md +423 -0
  9. package/agent/commands/acp.init.md +48 -0
  10. package/agent/commands/acp.package-create.md +1 -0
  11. package/agent/commands/acp.package-info.md +1 -0
  12. package/agent/commands/acp.package-install.md +19 -0
  13. package/agent/commands/acp.package-list.md +1 -0
  14. package/agent/commands/acp.package-publish.md +1 -0
  15. package/agent/commands/acp.package-remove.md +1 -0
  16. package/agent/commands/acp.package-search.md +1 -0
  17. package/agent/commands/acp.package-update.md +1 -0
  18. package/agent/commands/acp.package-validate.md +1 -0
  19. package/agent/commands/acp.pattern-create.md +60 -0
  20. package/agent/commands/acp.plan.md +25 -0
  21. package/agent/commands/acp.proceed.md +621 -75
  22. package/agent/commands/acp.project-create.md +3 -0
  23. package/agent/commands/acp.project-info.md +3 -0
  24. package/agent/commands/acp.project-list.md +3 -1
  25. package/agent/commands/acp.project-set.md +1 -0
  26. package/agent/commands/acp.project-update.md +14 -3
  27. package/agent/commands/acp.projects-restore.md +228 -0
  28. package/agent/commands/acp.projects-sync.md +347 -0
  29. package/agent/commands/acp.report.md +13 -0
  30. package/agent/commands/acp.resume.md +3 -1
  31. package/agent/commands/acp.sessions.md +301 -0
  32. package/agent/commands/acp.status.md +13 -0
  33. package/agent/commands/acp.sync.md +1 -0
  34. package/agent/commands/acp.task-create.md +105 -3
  35. package/agent/commands/acp.update.md +1 -0
  36. package/agent/commands/acp.validate.md +32 -2
  37. package/agent/commands/acp.version-check-for-updates.md +1 -0
  38. package/agent/commands/acp.version-check.md +1 -0
  39. package/agent/commands/acp.version-update.md +1 -0
  40. package/agent/commands/command.template.md +23 -0
  41. package/agent/commands/git.commit.md +1 -0
  42. package/agent/commands/git.init.md +1 -0
  43. package/agent/design/complete-tool-set.md +157 -233
  44. package/agent/design/design.template.md +18 -0
  45. package/agent/design/user-preferences.md +11 -7
  46. package/agent/milestones/milestone-19-new-search-ghost-tools.md +46 -0
  47. package/agent/package.template.yaml +50 -0
  48. package/agent/patterns/pattern.template.md +18 -0
  49. package/agent/progress.yaml +162 -6
  50. package/agent/scripts/acp.common.sh +258 -15
  51. package/agent/scripts/acp.install.sh +91 -4
  52. package/agent/scripts/acp.package-create.sh +0 -1
  53. package/agent/scripts/acp.package-info.sh +19 -1
  54. package/agent/scripts/acp.package-install-optimized.sh +1 -1
  55. package/agent/scripts/acp.package-install.sh +388 -38
  56. package/agent/scripts/acp.package-list.sh +52 -4
  57. package/agent/scripts/acp.package-remove.sh +77 -1
  58. package/agent/scripts/acp.package-search.sh +2 -2
  59. package/agent/scripts/acp.package-update.sh +91 -12
  60. package/agent/scripts/acp.package-validate.sh +136 -1
  61. package/agent/scripts/acp.project-info.sh +34 -11
  62. package/agent/scripts/acp.project-list.sh +4 -0
  63. package/agent/scripts/acp.project-update.sh +66 -19
  64. package/agent/scripts/acp.projects-restore.sh +170 -0
  65. package/agent/scripts/acp.projects-sync.sh +155 -0
  66. package/agent/scripts/acp.sessions.sh +725 -0
  67. package/agent/scripts/acp.version-update.sh +21 -3
  68. package/agent/scripts/acp.yaml-parser.sh +20 -6
  69. package/agent/tasks/milestone-19-new-search-ghost-tools/task-203-create-search-by-tool.md +143 -0
  70. package/agent/tasks/milestone-19-new-search-ghost-tools/task-204-add-new-filters-existing-tools.md +77 -0
  71. package/agent/tasks/milestone-19-new-search-ghost-tools/task-205-add-feel-fields-create-update.md +137 -0
  72. package/agent/tasks/milestone-19-new-search-ghost-tools/task-206-add-byproperty-bysignificance-modes.md +135 -0
  73. package/agent/tasks/milestone-19-new-search-ghost-tools/task-207-add-emotional-composites-search-results.md +88 -0
  74. package/agent/tasks/milestone-19-new-search-ghost-tools/task-208-add-bybroad-byrandom-modes.md +115 -0
  75. package/agent/tasks/milestone-19-new-search-ghost-tools/task-209-create-ghost-memory-tools.md +192 -0
  76. package/agent/tasks/milestone-19-new-search-ghost-tools/task-210-create-get-core-tool.md +203 -0
  77. package/agent/tasks/milestone-19-new-search-ghost-tools/task-211-create-search-space-by-tool.md +182 -0
  78. package/agent/tasks/task-1-{title}.template.md +19 -0
  79. package/agent/tasks/unassigned/bug-report-remember-core-e2e-findings.md +99 -0
  80. package/dist/e2e-helpers.d.ts +26 -0
  81. package/dist/ghost-persona.e2e.d.ts +8 -0
  82. package/dist/memory-crud.e2e.d.ts +8 -0
  83. package/dist/preferences.e2e.d.ts +8 -0
  84. package/dist/relationships.e2e.d.ts +8 -0
  85. package/dist/search-modes.e2e.d.ts +8 -0
  86. package/dist/server-factory.js +1977 -100
  87. package/dist/server.js +1174 -51
  88. package/dist/shared-spaces.e2e.d.ts +8 -0
  89. package/dist/tools/create-ghost-memory.d.ts +70 -0
  90. package/dist/tools/create-memory.d.ts +175 -0
  91. package/dist/tools/get-core.d.ts +28 -0
  92. package/dist/tools/get-core.spec.d.ts +2 -0
  93. package/dist/tools/ghost-tools.spec.d.ts +2 -0
  94. package/dist/tools/query-ghost-memory.d.ts +34 -0
  95. package/dist/tools/query-memory.d.ts +4 -0
  96. package/dist/tools/search-by.d.ts +147 -0
  97. package/dist/tools/search-by.spec.d.ts +2 -0
  98. package/dist/tools/search-ghost-memory-by.d.ts +54 -0
  99. package/dist/tools/search-ghost-memory.d.ts +53 -0
  100. package/dist/tools/search-memory.d.ts +19 -0
  101. package/dist/tools/search-space-by.d.ts +78 -0
  102. package/dist/tools/search-space-by.spec.d.ts +2 -0
  103. package/dist/tools/search-space.d.ts +2 -0
  104. package/dist/tools/update-ghost-memory.d.ts +51 -0
  105. package/dist/tools/update-memory.d.ts +175 -0
  106. package/jest.e2e.config.js +11 -0
  107. package/package.json +2 -2
  108. package/src/e2e-helpers.ts +86 -0
  109. package/src/ghost-persona.e2e.ts +215 -0
  110. package/src/memory-crud.e2e.ts +203 -0
  111. package/src/preferences.e2e.ts +88 -0
  112. package/src/relationships.e2e.ts +156 -0
  113. package/src/search-modes.e2e.ts +184 -0
  114. package/src/server-factory.ts +56 -0
  115. package/src/shared-spaces.e2e.ts +204 -0
  116. package/src/tools/create-ghost-memory.ts +103 -0
  117. package/src/tools/create-memory.ts +45 -1
  118. package/src/tools/get-core.spec.ts +223 -0
  119. package/src/tools/get-core.ts +109 -0
  120. package/src/tools/ghost-tools.spec.ts +361 -0
  121. package/src/tools/query-ghost-memory.ts +63 -0
  122. package/src/tools/query-memory.ts +4 -0
  123. package/src/tools/search-by.spec.ts +325 -0
  124. package/src/tools/search-by.ts +298 -0
  125. package/src/tools/search-ghost-memory-by.ts +80 -0
  126. package/src/tools/search-ghost-memory.ts +73 -0
  127. package/src/tools/search-memory.ts +23 -0
  128. package/src/tools/search-space-by.spec.ts +289 -0
  129. package/src/tools/search-space-by.ts +173 -0
  130. package/src/tools/search-space.ts +20 -1
  131. package/src/tools/update-ghost-memory.ts +86 -0
  132. package/src/tools/update-memory.ts +45 -1
@@ -151,7 +151,17 @@ for package in $INSTALLED_PACKAGES; do
151
151
  END { print count }
152
152
  ' "$MANIFEST_FILE")
153
153
 
154
- total_files=$((patterns_count + commands_count + designs_count))
154
+ files_count=$(awk -v pkg="$package" '
155
+ BEGIN { in_pkg=0; in_files=0; count=0 }
156
+ $0 ~ "^ " pkg ":" { in_pkg=1; next }
157
+ in_pkg && /^ [a-z]/ { in_pkg=0 }
158
+ in_pkg && /^ files:$/ { in_files=1; next }
159
+ in_files && /^ [a-z]/ { in_files=0 }
160
+ in_files && /^ - name:/ { count++ }
161
+ END { print count }
162
+ ' "$MANIFEST_FILE")
163
+
164
+ total_files=$((patterns_count + commands_count + designs_count + files_count))
155
165
 
156
166
  # Check if package has updates (for --outdated filter)
157
167
  has_updates=false
@@ -190,7 +200,7 @@ for package in $INSTALLED_PACKAGES; do
190
200
  in_type && /^ [a-z]/ { in_type=0 }
191
201
  in_type && /^ - name:/ { print $3 }
192
202
  ' "$MANIFEST_FILE")
193
-
203
+
194
204
  for file_name in $files; do
195
205
  if is_file_modified "$package" "$file_type" "$file_name"; then
196
206
  has_modified=true
@@ -198,6 +208,27 @@ for package in $INSTALLED_PACKAGES; do
198
208
  fi
199
209
  done
200
210
  done
211
+
212
+ # Also check template files for modifications
213
+ if [ "$has_modified" = false ]; then
214
+ _file_entries=$(awk -v pkg="$package" '
215
+ BEGIN { in_pkg=0; in_files=0; in_entry=0; name="" }
216
+ $0 ~ "^ " pkg ":" { in_pkg=1; next }
217
+ in_pkg && /^ [a-z]/ { in_pkg=0 }
218
+ in_pkg && /^ files:$/ { in_files=1; next }
219
+ in_files && /^ [a-z]/ { in_files=0 }
220
+ in_files && /^ - name:/ { name=$3 }
221
+ in_files && /^ target:/ { $1=""; gsub(/^ +/, ""); print name "|" $0 }
222
+ ' "$MANIFEST_FILE")
223
+
224
+ while IFS='|' read -r _fname _ftarget; do
225
+ [ -z "$_fname" ] && continue
226
+ if [ -n "$_ftarget" ] && is_template_file_modified "$package" "$_fname" "$_ftarget"; then
227
+ has_modified=true
228
+ break
229
+ fi
230
+ done <<< "$_file_entries"
231
+ fi
201
232
 
202
233
  # Skip if no modifications and filtering for modified
203
234
  if [ "$has_modified" = false ]; then
@@ -220,7 +251,8 @@ for package in $INSTALLED_PACKAGES; do
220
251
  [ "$patterns_count" -gt 0 ] && echo " - $patterns_count pattern(s)"
221
252
  [ "$commands_count" -gt 0 ] && echo " - $commands_count command(s)"
222
253
  [ "$designs_count" -gt 0 ] && echo " - $designs_count design(s)"
223
-
254
+ [ "$files_count" -gt 0 ] && echo " - $files_count file(s)"
255
+
224
256
  # Show modified files if any
225
257
  if [ "$has_modified" = true ]; then
226
258
  echo " ${YELLOW}Modified files:${NC}"
@@ -233,13 +265,29 @@ for package in $INSTALLED_PACKAGES; do
233
265
  in_type && /^ [a-z]/ { in_type=0 }
234
266
  in_type && /^ - name:/ { print $3 }
235
267
  ' "$MANIFEST_FILE")
236
-
268
+
237
269
  for file_name in $files; do
238
270
  if is_file_modified "$package" "$file_type" "$file_name"; then
239
271
  echo " - $file_type/$file_name"
240
272
  fi
241
273
  done
242
274
  done
275
+ # Check template files too
276
+ _file_entries=$(awk -v pkg="$package" '
277
+ BEGIN { in_pkg=0; in_files=0; name="" }
278
+ $0 ~ "^ " pkg ":" { in_pkg=1; next }
279
+ in_pkg && /^ [a-z]/ { in_pkg=0 }
280
+ in_pkg && /^ files:$/ { in_files=1; next }
281
+ in_files && /^ [a-z]/ { in_files=0 }
282
+ in_files && /^ - name:/ { name=$3 }
283
+ in_files && /^ target:/ { $1=""; gsub(/^ +/, ""); print name "|" $0 }
284
+ ' "$MANIFEST_FILE")
285
+ while IFS='|' read -r _fname _ftarget; do
286
+ [ -z "$_fname" ] && continue
287
+ if [ -n "$_ftarget" ] && is_template_file_modified "$package" "$_fname" "$_ftarget"; then
288
+ echo " - files/$_fname → $_ftarget"
289
+ fi
290
+ done <<< "$_file_entries"
243
291
  fi
244
292
 
245
293
  # Show update status if checking outdated
@@ -125,6 +125,26 @@ designs_files=$(awk -v pkg="$PACKAGE_NAME" '
125
125
  in_designs && /^ - name:/ { print $3 }
126
126
  ' "$MANIFEST_FILE")
127
127
 
128
+ indices_files=$(awk -v pkg="$PACKAGE_NAME" '
129
+ BEGIN { in_pkg=0; in_indices=0 }
130
+ $0 ~ "^ " pkg ":" { in_pkg=1; next }
131
+ in_pkg && /^ [a-z]/ { in_pkg=0 }
132
+ in_pkg && /^ indices:/ { in_indices=1; next }
133
+ in_indices && /^ [a-z]/ { in_indices=0 }
134
+ in_indices && /^ - name:/ { print $3 }
135
+ ' "$MANIFEST_FILE")
136
+
137
+ # Get template files with their target paths (name|target)
138
+ template_file_entries=$(awk -v pkg="$PACKAGE_NAME" '
139
+ BEGIN { in_pkg=0; in_files=0; name="" }
140
+ $0 ~ "^ " pkg ":" { in_pkg=1; next }
141
+ in_pkg && /^ [a-z]/ { in_pkg=0 }
142
+ in_pkg && /^ files:$/ { in_files=1; next }
143
+ in_files && /^ [a-z]/ { in_files=0 }
144
+ in_files && /^ - name:/ { name=$3 }
145
+ in_files && /^ target:/ { $1=""; gsub(/^ +/, ""); print name "|" $0 }
146
+ ' "$MANIFEST_FILE")
147
+
128
148
  # Count files (handle empty strings properly)
129
149
  if [ -n "$patterns_files" ]; then
130
150
  patterns_count=$(echo "$patterns_files" | wc -l)
@@ -144,12 +164,26 @@ else
144
164
  designs_count=0
145
165
  fi
146
166
 
147
- total_files=$((patterns_count + commands_count + designs_count))
167
+ if [ -n "$indices_files" ]; then
168
+ indices_count=$(echo "$indices_files" | wc -l)
169
+ else
170
+ indices_count=0
171
+ fi
172
+
173
+ if [ -n "$template_file_entries" ]; then
174
+ template_files_count=$(echo "$template_file_entries" | wc -l)
175
+ else
176
+ template_files_count=0
177
+ fi
178
+
179
+ total_files=$((patterns_count + commands_count + designs_count + indices_count + template_files_count))
148
180
 
149
181
  echo "${YELLOW}⚠️ This will remove:${NC}"
150
182
  [ "$patterns_count" -gt 0 ] && echo " - $patterns_count pattern(s)"
151
183
  [ "$commands_count" -gt 0 ] && echo " - $commands_count command(s)"
152
184
  [ "$designs_count" -gt 0 ] && echo " - $designs_count design(s)"
185
+ [ "$indices_count" -gt 0 ] && echo " - $indices_count index file(s)"
186
+ [ "$template_files_count" -gt 0 ] && echo " - $template_files_count file(s) (installed to project)"
153
187
  echo ""
154
188
  echo "Total: $total_files file(s)"
155
189
  echo ""
@@ -174,6 +208,20 @@ for file in $designs_files; do
174
208
  fi
175
209
  done
176
210
 
211
+ for file in $indices_files; do
212
+ if is_file_modified "$PACKAGE_NAME" "indices" "$file"; then
213
+ modified_files+=("index/$file")
214
+ fi
215
+ done
216
+
217
+ # Check template files for modifications
218
+ while IFS='|' read -r _fname _ftarget; do
219
+ [ -z "$_fname" ] && continue
220
+ if [ -n "$_ftarget" ] && is_template_file_modified "$PACKAGE_NAME" "$_fname" "$_ftarget"; then
221
+ modified_files+=("files/$_fname → $_ftarget")
222
+ fi
223
+ done <<< "$template_file_entries"
224
+
177
225
  if [ ${#modified_files[@]} -gt 0 ]; then
178
226
  echo "${YELLOW}⚠️ Modified files detected:${NC}"
179
227
  for file in "${modified_files[@]}"; do
@@ -243,6 +291,34 @@ for file in $designs_files; do
243
291
  fi
244
292
  done
245
293
 
294
+ for file in $indices_files; do
295
+ if printf '%s\n' "${modified_files[@]}" | grep -q "^index/$file$" && [ "$KEEP_MODIFIED" = true ]; then
296
+ echo " ${YELLOW}⊙${NC} Kept index/$file (modified)"
297
+ kept_count=$((kept_count + 1))
298
+ else
299
+ if [ -f "agent/index/$file" ]; then
300
+ rm "agent/index/$file"
301
+ echo " ${GREEN}✓${NC} Removed index/$file"
302
+ removed_count=$((removed_count + 1))
303
+ fi
304
+ fi
305
+ done
306
+
307
+ # Remove template files (installed at target paths)
308
+ while IFS='|' read -r _fname _ftarget; do
309
+ [ -z "$_fname" ] && continue
310
+ if printf '%s\n' "${modified_files[@]}" | grep -q "^files/$_fname" && [ "$KEEP_MODIFIED" = true ]; then
311
+ echo " ${YELLOW}⊙${NC} Kept $_ftarget (modified)"
312
+ kept_count=$((kept_count + 1))
313
+ else
314
+ if [ -f "$_ftarget" ]; then
315
+ rm "$_ftarget"
316
+ echo " ${GREEN}✓${NC} Removed $_ftarget (from files/$_fname)"
317
+ removed_count=$((removed_count + 1))
318
+ fi
319
+ fi
320
+ done <<< "$template_file_entries"
321
+
246
322
  # Remove package from manifest
247
323
  echo ""
248
324
  echo "Updating manifest..."
@@ -145,12 +145,12 @@ echo "$RESPONSE" | grep -o '"full_name": "[^"]*"' | cut -d'"' -f4 | while read -
145
145
  if [ -n "$TAGS" ]; then
146
146
  echo " Tags: $TAGS"
147
147
  fi
148
- echo " Install: ./agent/scripts/acp.package-install.sh $URL.git"
148
+ echo " Install: ./agent/scripts/acp.package-install.sh --repo $URL.git"
149
149
  echo ""
150
150
  done
151
151
 
152
152
  echo "Showing $REPO_COUNT of $TOTAL_COUNT result(s)"
153
153
  echo ""
154
154
  echo "To install a package:"
155
- echo " ./agent/scripts/acp.package-install.sh <repository-url>"
155
+ echo " ./agent/scripts/acp.package-install.sh --repo <repository-url>"
156
156
  echo ""
@@ -196,7 +196,7 @@ update_package() {
196
196
  local modified_files=()
197
197
 
198
198
  # Check for modified files first
199
- for file_type in patterns commands design; do
199
+ for file_type in patterns commands design indices; do
200
200
  local files
201
201
  files=$(awk -v pkg="$package_name" -v type="$file_type" '
202
202
  BEGIN { in_pkg=0; in_type=0 }
@@ -206,13 +206,31 @@ update_package() {
206
206
  in_type && /^ [a-z]/ { in_type=0 }
207
207
  in_type && /^ - name:/ { print $3 }
208
208
  ' "$MANIFEST_FILE")
209
-
209
+
210
210
  for file_name in $files; do
211
211
  if is_file_modified "$package_name" "$file_type" "$file_name"; then
212
212
  modified_files+=("$file_type/$file_name")
213
213
  fi
214
214
  done
215
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"
216
234
 
217
235
  # Handle modified files
218
236
  if [ ${#modified_files[@]} -gt 0 ] && [ "$FORCE" = false ]; then
@@ -236,8 +254,17 @@ update_package() {
236
254
  echo ""
237
255
  fi
238
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
+
239
266
  # Update files
240
- for file_type in patterns commands design; do
267
+ for file_type in patterns commands design indices; do
241
268
  local files
242
269
  files=$(awk -v pkg="$package_name" -v type="$file_type" '
243
270
  BEGIN { in_pkg=0; in_type=0 }
@@ -258,13 +285,16 @@ update_package() {
258
285
  fi
259
286
  fi
260
287
 
288
+ # Map manifest type to directory name
289
+ local _file_dir=$(_type_to_dir "$file_type")
290
+
261
291
  # Check if file exists in new version
262
- if [ ! -f "$temp_dir/agent/$file_type/$file_name" ]; then
263
- warn "File no longer exists in package: $file_type/$file_name"
292
+ if [ ! -f "$temp_dir/agent/$_file_dir/$file_name" ]; then
293
+ warn "File no longer exists in package: $_file_dir/$file_name"
264
294
  ((skipped_count++))
265
295
  continue
266
296
  fi
267
-
297
+
268
298
  # Check if this is a new experimental feature
269
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)
270
300
 
@@ -287,13 +317,14 @@ update_package() {
287
317
  fi
288
318
 
289
319
  # Copy file
290
- cp "$temp_dir/agent/$file_type/$file_name" "agent/$file_type/"
291
-
320
+ mkdir -p "agent/$_file_dir"
321
+ cp "$temp_dir/agent/$_file_dir/$file_name" "agent/$_file_dir/"
322
+
292
323
  # Get new version and checksum
293
324
  local new_version
294
325
  new_version=$(get_file_version "$temp_dir/package.yaml" "$file_type" "$file_name")
295
326
  local new_checksum
296
- new_checksum=$(calculate_checksum "agent/$file_type/$file_name")
327
+ new_checksum=$(calculate_checksum "agent/$_file_dir/$file_name")
297
328
 
298
329
  # Update manifest (including experimental status)
299
330
  update_file_in_manifest "$package_name" "$file_type" "$file_name" "$new_version" "$new_checksum"
@@ -301,17 +332,65 @@ update_package() {
301
332
  # Update experimental flag in manifest if needed
302
333
  if [ -n "$is_experimental" ]; then
303
334
  # Still experimental, ensure flag is set
304
- sed -i "/packages:/{:a;N;/name: ${file_name}/!ba;s/\(name: ${file_name}\)/\1\n experimental: true/;}" "$MANIFEST_FILE" 2>/dev/null || true
335
+ _sed_i "/packages:/{:a;N;/name: ${file_name}/!ba;s/\(name: ${file_name}\)/\1\n experimental: true/;}" "$MANIFEST_FILE" 2>/dev/null || true
305
336
  elif check_graduation "$file_name" "$file_type" "$package_name" "$temp_dir/package.yaml"; then
306
337
  # Graduated, remove experimental flag
307
- sed -i "/name: ${file_name}/{N;s/\n *experimental: true//;}" "$MANIFEST_FILE" 2>/dev/null || true
338
+ _sed_i "/name: ${file_name}/{N;s/\n *experimental: true//;}" "$MANIFEST_FILE" 2>/dev/null || true
308
339
  fi
309
340
 
310
341
  echo " ${GREEN}✓${NC} Updated $file_type/$file_name (v$new_version)"
311
342
  ((updated_count++))
312
343
  done
313
344
  done
314
-
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
+
315
394
  # Update package metadata in manifest
316
395
  local timestamp
317
396
  timestamp=$(get_timestamp)
@@ -172,13 +172,49 @@ validate_file_existence() {
172
172
  done
173
173
  fi
174
174
 
175
+ # Check indices (key file index files in agent/index/)
176
+ if yaml_has_key "package.yaml" "contents.indices"; then
177
+ local indices_count=$(yaml_get_array "package.yaml" "contents.indices")
178
+ for i in $(seq 0 $((indices_count - 1))); do
179
+ local index_name=$(yaml_get_nested "package.yaml" "contents.indices[$i].name")
180
+ if [ -n "$index_name" ]; then
181
+ total_files=$((total_files + 1))
182
+ check
183
+ if [ -f "agent/index/$index_name" ]; then
184
+ pass "agent/index/$index_name ✓"
185
+ else
186
+ error "Missing file: agent/index/$index_name"
187
+ missing_files=$((missing_files + 1))
188
+ fi
189
+ fi
190
+ done
191
+ fi
192
+
193
+ # Check files (template source files in agent/files/)
194
+ if yaml_has_key "package.yaml" "contents.files"; then
195
+ local files_count=$(yaml_get_array "package.yaml" "contents.files")
196
+ for i in $(seq 0 $((files_count - 1))); do
197
+ local file_name=$(yaml_get_nested "package.yaml" "contents.files[$i].name")
198
+ if [ -n "$file_name" ]; then
199
+ total_files=$((total_files + 1))
200
+ check
201
+ if [ -f "agent/files/$file_name" ]; then
202
+ pass "agent/files/$file_name ✓"
203
+ else
204
+ error "Missing file: agent/files/$file_name"
205
+ missing_files=$((missing_files + 1))
206
+ fi
207
+ fi
208
+ done
209
+ fi
210
+
175
211
  if [ "$missing_files" -eq 0 ]; then
176
212
  pass "All $total_files files in contents exist"
177
213
  else
178
214
  error "$missing_files of $total_files files missing"
179
215
  fixable "Remove missing files from package.yaml"
180
216
  fi
181
-
217
+
182
218
  echo ""
183
219
  }
184
220
 
@@ -794,6 +830,104 @@ validate_experimental_consistency() {
794
830
  return $errors
795
831
  }
796
832
 
833
+ # Validate script-command bindings
834
+ validate_script_dependencies() {
835
+ echo ""
836
+ echo "${BOLD}Script-Command Bindings${NC}"
837
+
838
+ local validation_errors=0
839
+
840
+ # Get all commands from package.yaml
841
+ local commands=$(yaml_query ".contents.commands[]?.name" 2>/dev/null || echo "")
842
+
843
+ if [ -z "$commands" ]; then
844
+ pass "No commands to validate"
845
+ return 0
846
+ fi
847
+
848
+ local cmd_count=0
849
+ while IFS= read -r cmd; do
850
+ if [ -z "$cmd" ] || [ "$cmd" = "null" ]; then
851
+ continue
852
+ fi
853
+
854
+ cmd_count=$((cmd_count + 1))
855
+ local cmd_file="agent/commands/$cmd"
856
+
857
+ if [ ! -f "$cmd_file" ]; then
858
+ continue # File existence checked elsewhere
859
+ fi
860
+
861
+ # Get scripts from frontmatter
862
+ local frontmatter_line=$(grep "^\*\*Scripts\*\*:" "$cmd_file" 2>/dev/null || echo "")
863
+
864
+ if [ -z "$frontmatter_line" ]; then
865
+ check
866
+ error "$cmd: Missing **Scripts**: field in frontmatter"
867
+ fixable "Add **Scripts**: field to $cmd_file frontmatter"
868
+ validation_errors=$((validation_errors + 1))
869
+ continue
870
+ fi
871
+
872
+ local frontmatter_scripts=$(echo "$frontmatter_line" | awk -F': ' '{print $2}' | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | grep -v "^$" | sort)
873
+
874
+ # Handle "None" case
875
+ if echo "$frontmatter_scripts" | grep -qi "^None$"; then
876
+ frontmatter_scripts=""
877
+ fi
878
+
879
+ # Get scripts from package.yaml
880
+ local yaml_scripts=$(yaml_query ".contents.commands[] | select(.name == \"$cmd\") | .scripts[]?" 2>/dev/null | grep -v "^null$" | sort || echo "")
881
+
882
+ # Compare (both should be empty or both should match)
883
+ if [ "$frontmatter_scripts" != "$yaml_scripts" ]; then
884
+ check
885
+ error "$cmd: Scripts mismatch between frontmatter and package.yaml"
886
+ echo " ${DIM}Frontmatter: $(echo "$frontmatter_scripts" | tr '\n' ', ' | sed 's/, $//')${NC}"
887
+ echo " ${DIM}package.yaml: $(echo "$yaml_scripts" | tr '\n' ', ' | sed 's/, $//')${NC}"
888
+ fixable "Update $cmd to have matching scripts in both locations"
889
+ validation_errors=$((validation_errors + 1))
890
+ continue
891
+ fi
892
+
893
+ # Verify all scripts exist in scripts section
894
+ local script_errors=0
895
+ while IFS= read -r script; do
896
+ if [ -n "$script" ]; then
897
+ local script_exists=$(yaml_query ".contents.scripts[]? | select(.name == \"$script\") | .name" 2>/dev/null || echo "")
898
+
899
+ if [ -z "$script_exists" ] || [ "$script_exists" = "null" ]; then
900
+ if [ $script_errors -eq 0 ]; then
901
+ check
902
+ error "$cmd: Declares scripts not in scripts section"
903
+ fi
904
+ echo " ${DIM}Missing: $script${NC}"
905
+ fixable "Add $script to contents.scripts section in package.yaml"
906
+ script_errors=$((script_errors + 1))
907
+ fi
908
+ fi
909
+ done <<< "$frontmatter_scripts"
910
+
911
+ if [ $script_errors -gt 0 ]; then
912
+ validation_errors=$((validation_errors + 1))
913
+ else
914
+ check
915
+ local script_count=$(echo "$frontmatter_scripts" | grep -v "^$" | wc -l)
916
+ if [ "$script_count" -eq 0 ]; then
917
+ pass "$cmd: No script dependencies"
918
+ else
919
+ pass "$cmd: Scripts consistent ($script_count script(s))"
920
+ fi
921
+ fi
922
+ done <<< "$commands"
923
+
924
+ if [ $cmd_count -eq 0 ]; then
925
+ pass "No commands to validate"
926
+ fi
927
+
928
+ return $validation_errors
929
+ }
930
+
797
931
  # Main validation function
798
932
  main() {
799
933
  echo "${BLUE}🔍 ACP Package Validation${NC}"
@@ -808,6 +942,7 @@ main() {
808
942
  validate_file_existence
809
943
  check_unlisted_files
810
944
  validate_namespace_consistency
945
+ validate_script_dependencies
811
946
  validate_experimental_consistency
812
947
  validate_git_repository
813
948
  validate_readme
@@ -1,9 +1,9 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  # acp.project-info.sh - Display detailed project information from registry
3
3
  # Part of Agent Context Protocol (ACP)
4
4
  # Usage: ./acp.project-info.sh <project-name>
5
5
 
6
- set -euo pipefail
6
+ set -e
7
7
 
8
8
  # Get script directory
9
9
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@@ -45,17 +45,23 @@ main() {
45
45
  fi
46
46
 
47
47
  # Parse registry
48
- yaml_parse "$registry_path"
48
+ if ! yaml_parse "$registry_path"; then
49
+ echo "Error: Failed to parse registry at: $registry_path" >&2
50
+ return 1
51
+ fi
52
+
53
+ # Check if project exists by trying to query it
54
+ local project_type
55
+ project_type=$(yaml_query ".projects.${project_name}.type" 2>&1 || echo "")
49
56
 
50
- # Check if project exists
51
- if ! yaml_query ".projects.${project_name}" >/dev/null 2>&1 || [ "$(yaml_query ".projects.${project_name}")" = "null" ]; then
57
+ if [ -z "$project_type" ] || [ "$project_type" = "null" ] || echo "$project_type" | grep -q "Error:"; then
52
58
  echo "Error: Project '${project_name}' not found in registry"
53
59
  echo ""
54
60
  echo "Available projects:"
55
61
 
56
62
  # List available projects
57
63
  local projects
58
- projects=$(yaml_query ".projects")
64
+ projects=$(yaml_query ".projects" 2>/dev/null || echo "")
59
65
 
60
66
  if [ -z "$projects" ] || [ "$projects" = "null" ]; then
61
67
  echo " (none)"
@@ -78,15 +84,20 @@ main() {
78
84
  last_modified=$(yaml_query ".projects.${project_name}.last_modified")
79
85
  last_accessed=$(yaml_query ".projects.${project_name}.last_accessed")
80
86
 
87
+ # Get git fields
88
+ local git_origin git_branch
89
+ git_origin=$(yaml_query ".projects.${project_name}.git_origin" 2>/dev/null || echo "")
90
+ git_branch=$(yaml_query ".projects.${project_name}.git_branch" 2>/dev/null || echo "")
91
+
81
92
  # Get optional fields
82
93
  local tags related_projects dependencies
83
- tags=$(yaml_query ".projects.${project_name}.tags")
84
- related_projects=$(yaml_query ".projects.${project_name}.related_projects")
85
- dependencies=$(yaml_query ".projects.${project_name}.dependencies")
94
+ tags=$(yaml_query ".projects.${project_name}.tags" 2>/dev/null || echo "")
95
+ related_projects=$(yaml_query ".projects.${project_name}.related_projects" 2>/dev/null || echo "")
96
+ dependencies=$(yaml_query ".projects.${project_name}.dependencies" 2>/dev/null || echo "")
86
97
 
87
98
  # Check if this is the current project
88
99
  local current_project
89
- current_project=$(yaml_query ".current_project")
100
+ current_project=$(yaml_query ".current_project" 2>/dev/null || echo "")
90
101
  local is_current=""
91
102
  if [ "$current_project" = "$project_name" ]; then
92
103
  is_current=" ⭐ Current"
@@ -118,7 +129,19 @@ main() {
118
129
  echo " Last Modified: ${last_modified}"
119
130
  echo " Last Accessed: ${last_accessed}"
120
131
  echo ""
121
-
132
+
133
+ # Git info (if present)
134
+ if [ -n "$git_origin" ] && [ "$git_origin" != "null" ]; then
135
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
136
+ echo ""
137
+ echo "Git:"
138
+ echo " Origin: ${git_origin}"
139
+ if [ -n "$git_branch" ] && [ "$git_branch" != "null" ]; then
140
+ echo " Branch: ${git_branch}"
141
+ fi
142
+ echo ""
143
+ fi
144
+
122
145
  # Tags (if present)
123
146
  if [ -n "$tags" ] && [ "$tags" != "null" ]; then
124
147
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@@ -108,6 +108,10 @@ for project_name in $PROJECT_NAMES; do
108
108
  fi
109
109
 
110
110
  echo " ${project_desc}"
111
+ project_origin=$(yaml_query ".projects.${project_name}.git_origin" 2>/dev/null || echo "")
112
+ if [ -n "$project_origin" ] && [ "$project_origin" != "null" ]; then
113
+ echo " Git: ${project_origin}"
114
+ fi
111
115
  echo " Last accessed: ${project_accessed}"
112
116
  echo ""
113
117
  done