@prmichaelsen/remember-mcp 3.15.4 → 3.15.5
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/AGENT.md +363 -5
- package/CHANGELOG.md +7 -0
- package/agent/commands/acp.clarification-capture.md +386 -0
- package/agent/commands/acp.clarification-create.md +50 -0
- package/agent/commands/acp.command-create.md +60 -0
- package/agent/commands/acp.design-create.md +62 -0
- package/agent/commands/acp.design-reference.md +355 -0
- package/agent/commands/acp.index.md +423 -0
- package/agent/commands/acp.init.md +48 -0
- package/agent/commands/acp.package-create.md +1 -0
- package/agent/commands/acp.package-info.md +1 -0
- package/agent/commands/acp.package-install.md +19 -0
- package/agent/commands/acp.package-list.md +1 -0
- package/agent/commands/acp.package-publish.md +1 -0
- package/agent/commands/acp.package-remove.md +1 -0
- package/agent/commands/acp.package-search.md +1 -0
- package/agent/commands/acp.package-update.md +1 -0
- package/agent/commands/acp.package-validate.md +1 -0
- package/agent/commands/acp.pattern-create.md +60 -0
- package/agent/commands/acp.plan.md +25 -0
- package/agent/commands/acp.proceed.md +621 -75
- package/agent/commands/acp.project-create.md +3 -0
- package/agent/commands/acp.project-info.md +3 -0
- package/agent/commands/acp.project-list.md +3 -1
- package/agent/commands/acp.project-set.md +1 -0
- package/agent/commands/acp.project-update.md +14 -3
- package/agent/commands/acp.projects-restore.md +228 -0
- package/agent/commands/acp.projects-sync.md +347 -0
- package/agent/commands/acp.report.md +13 -0
- package/agent/commands/acp.resume.md +3 -1
- package/agent/commands/acp.sessions.md +301 -0
- package/agent/commands/acp.status.md +13 -0
- package/agent/commands/acp.sync.md +1 -0
- package/agent/commands/acp.task-create.md +105 -3
- package/agent/commands/acp.update.md +1 -0
- package/agent/commands/acp.validate.md +32 -2
- package/agent/commands/acp.version-check-for-updates.md +1 -0
- package/agent/commands/acp.version-check.md +1 -0
- package/agent/commands/acp.version-update.md +1 -0
- package/agent/commands/command.template.md +23 -0
- package/agent/commands/git.commit.md +1 -0
- package/agent/commands/git.init.md +1 -0
- package/agent/design/complete-tool-set.md +157 -233
- package/agent/design/design.template.md +18 -0
- package/agent/design/user-preferences.md +11 -7
- package/agent/milestones/milestone-19-new-search-ghost-tools.md +46 -0
- package/agent/package.template.yaml +50 -0
- package/agent/patterns/pattern.template.md +18 -0
- package/agent/progress.yaml +162 -6
- package/agent/scripts/acp.common.sh +258 -15
- package/agent/scripts/acp.install.sh +91 -4
- package/agent/scripts/acp.package-create.sh +0 -1
- package/agent/scripts/acp.package-info.sh +19 -1
- package/agent/scripts/acp.package-install-optimized.sh +1 -1
- package/agent/scripts/acp.package-install.sh +388 -38
- package/agent/scripts/acp.package-list.sh +52 -4
- package/agent/scripts/acp.package-remove.sh +77 -1
- package/agent/scripts/acp.package-search.sh +2 -2
- package/agent/scripts/acp.package-update.sh +91 -12
- package/agent/scripts/acp.package-validate.sh +136 -1
- package/agent/scripts/acp.project-info.sh +34 -11
- package/agent/scripts/acp.project-list.sh +4 -0
- package/agent/scripts/acp.project-update.sh +66 -19
- package/agent/scripts/acp.projects-restore.sh +170 -0
- package/agent/scripts/acp.projects-sync.sh +155 -0
- package/agent/scripts/acp.sessions.sh +725 -0
- package/agent/scripts/acp.version-update.sh +21 -3
- package/agent/scripts/acp.yaml-parser.sh +20 -6
- package/agent/tasks/milestone-19-new-search-ghost-tools/task-203-create-search-by-tool.md +143 -0
- package/agent/tasks/milestone-19-new-search-ghost-tools/task-204-add-new-filters-existing-tools.md +77 -0
- package/agent/tasks/milestone-19-new-search-ghost-tools/task-205-add-feel-fields-create-update.md +137 -0
- package/agent/tasks/milestone-19-new-search-ghost-tools/task-206-add-byproperty-bysignificance-modes.md +135 -0
- package/agent/tasks/milestone-19-new-search-ghost-tools/task-207-add-emotional-composites-search-results.md +88 -0
- package/agent/tasks/milestone-19-new-search-ghost-tools/task-208-add-bybroad-byrandom-modes.md +115 -0
- package/agent/tasks/milestone-19-new-search-ghost-tools/task-209-create-ghost-memory-tools.md +192 -0
- package/agent/tasks/milestone-19-new-search-ghost-tools/task-210-create-get-core-tool.md +203 -0
- package/agent/tasks/milestone-19-new-search-ghost-tools/task-211-create-search-space-by-tool.md +182 -0
- package/agent/tasks/task-1-{title}.template.md +19 -0
- package/agent/tasks/unassigned/bug-report-remember-core-e2e-findings.md +99 -0
- package/dist/e2e-helpers.d.ts +26 -0
- package/dist/ghost-persona.e2e.d.ts +8 -0
- package/dist/memory-crud.e2e.d.ts +8 -0
- package/dist/preferences.e2e.d.ts +8 -0
- package/dist/relationships.e2e.d.ts +8 -0
- package/dist/search-modes.e2e.d.ts +8 -0
- package/dist/server-factory.js +1971 -94
- package/dist/server.js +1168 -45
- package/dist/shared-spaces.e2e.d.ts +8 -0
- package/dist/tools/create-ghost-memory.d.ts +70 -0
- package/dist/tools/create-memory.d.ts +175 -0
- package/dist/tools/get-core.d.ts +28 -0
- package/dist/tools/get-core.spec.d.ts +2 -0
- package/dist/tools/ghost-tools.spec.d.ts +2 -0
- package/dist/tools/query-ghost-memory.d.ts +34 -0
- package/dist/tools/query-memory.d.ts +4 -0
- package/dist/tools/search-by.d.ts +147 -0
- package/dist/tools/search-by.spec.d.ts +2 -0
- package/dist/tools/search-ghost-memory-by.d.ts +54 -0
- package/dist/tools/search-ghost-memory.d.ts +53 -0
- package/dist/tools/search-memory.d.ts +19 -0
- package/dist/tools/search-space-by.d.ts +78 -0
- package/dist/tools/search-space-by.spec.d.ts +2 -0
- package/dist/tools/search-space.d.ts +2 -0
- package/dist/tools/update-ghost-memory.d.ts +51 -0
- package/dist/tools/update-memory.d.ts +175 -0
- package/jest.e2e.config.js +11 -0
- package/package.json +2 -2
- package/src/e2e-helpers.ts +86 -0
- package/src/ghost-persona.e2e.ts +215 -0
- package/src/memory-crud.e2e.ts +203 -0
- package/src/preferences.e2e.ts +88 -0
- package/src/relationships.e2e.ts +156 -0
- package/src/search-modes.e2e.ts +184 -0
- package/src/server-factory.ts +56 -0
- package/src/shared-spaces.e2e.ts +204 -0
- package/src/tools/create-ghost-memory.ts +103 -0
- package/src/tools/create-memory.ts +45 -1
- package/src/tools/get-core.spec.ts +223 -0
- package/src/tools/get-core.ts +109 -0
- package/src/tools/ghost-tools.spec.ts +361 -0
- package/src/tools/query-ghost-memory.ts +63 -0
- package/src/tools/query-memory.ts +4 -0
- package/src/tools/search-by.spec.ts +325 -0
- package/src/tools/search-by.ts +298 -0
- package/src/tools/search-ghost-memory-by.ts +80 -0
- package/src/tools/search-ghost-memory.ts +73 -0
- package/src/tools/search-memory.ts +23 -0
- package/src/tools/search-space-by.spec.ts +289 -0
- package/src/tools/search-space-by.ts +173 -0
- package/src/tools/search-space.ts +20 -1
- package/src/tools/update-ghost-memory.ts +86 -0
- package/src/tools/update-memory.ts +45 -1
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
# Common utilities for ACP scripts
|
|
3
3
|
# POSIX-compliant for maximum portability
|
|
4
4
|
|
|
5
|
+
# Portable in-place sed (works on both GNU and BSD/macOS sed)
|
|
6
|
+
# Usage: _sed_i "expression" "file"
|
|
7
|
+
_sed_i() {
|
|
8
|
+
if [ "$(uname)" = "Darwin" ]; then
|
|
9
|
+
sed -i '' "$@"
|
|
10
|
+
else
|
|
11
|
+
sed -i "$@"
|
|
12
|
+
fi
|
|
13
|
+
}
|
|
14
|
+
|
|
5
15
|
# Initialize colors using tput (more reliable than ANSI codes)
|
|
6
16
|
init_colors() {
|
|
7
17
|
if command -v tput >/dev/null 2>&1 && [ -t 1 ]; then
|
|
@@ -30,7 +40,13 @@ calculate_checksum() {
|
|
|
30
40
|
echo "Error: File not found: $file" >&2
|
|
31
41
|
return 1
|
|
32
42
|
fi
|
|
33
|
-
sha256sum
|
|
43
|
+
if command -v sha256sum >/dev/null 2>&1; then
|
|
44
|
+
sha256sum "$file" 2>/dev/null | cut -d' ' -f1
|
|
45
|
+
elif command -v shasum >/dev/null 2>&1; then
|
|
46
|
+
shasum -a 256 "$file" 2>/dev/null | cut -d' ' -f1
|
|
47
|
+
else
|
|
48
|
+
echo "unknown"
|
|
49
|
+
fi
|
|
34
50
|
}
|
|
35
51
|
|
|
36
52
|
# Get current timestamp in ISO 8601 format (UTC)
|
|
@@ -143,7 +159,7 @@ update_manifest_timestamp() {
|
|
|
143
159
|
timestamp=$(get_timestamp)
|
|
144
160
|
|
|
145
161
|
# Update timestamp using sed
|
|
146
|
-
|
|
162
|
+
_sed_i "s/^last_updated: .*/last_updated: $timestamp/" "$manifest"
|
|
147
163
|
}
|
|
148
164
|
|
|
149
165
|
# Check if package exists in manifest
|
|
@@ -192,7 +208,6 @@ init_global_manifest() {
|
|
|
192
208
|
fi
|
|
193
209
|
|
|
194
210
|
# Create ~/.acp directory if needed
|
|
195
|
-
mkdir -p "$HOME/.acp/packages"
|
|
196
211
|
mkdir -p "$HOME/.acp/projects"
|
|
197
212
|
|
|
198
213
|
# Create manifest
|
|
@@ -240,7 +255,7 @@ update_global_manifest_timestamp() {
|
|
|
240
255
|
# Update timestamp using sed
|
|
241
256
|
local timestamp
|
|
242
257
|
timestamp=$(get_timestamp)
|
|
243
|
-
|
|
258
|
+
_sed_i "s/^updated: .*/updated: $timestamp/" "$manifest_path"
|
|
244
259
|
}
|
|
245
260
|
|
|
246
261
|
# Check if package exists in global manifest
|
|
@@ -296,7 +311,22 @@ init_global_acp() {
|
|
|
296
311
|
|
|
297
312
|
# Create ~/.acp directory
|
|
298
313
|
mkdir -p "$global_dir"
|
|
299
|
-
|
|
314
|
+
|
|
315
|
+
# Create .gitignore for global ACP directory
|
|
316
|
+
if [ ! -f "$global_dir/.gitignore" ]; then
|
|
317
|
+
cat > "$global_dir/.gitignore" << 'GITIGNORE'
|
|
318
|
+
# Project repos have their own git
|
|
319
|
+
projects/
|
|
320
|
+
|
|
321
|
+
# Claude Code session data
|
|
322
|
+
.claude/
|
|
323
|
+
|
|
324
|
+
# Common noise
|
|
325
|
+
*.log
|
|
326
|
+
node_modules/
|
|
327
|
+
GITIGNORE
|
|
328
|
+
fi
|
|
329
|
+
|
|
300
330
|
# Get the directory where this script is located
|
|
301
331
|
local script_dir
|
|
302
332
|
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
@@ -483,7 +513,7 @@ get_file_version() {
|
|
|
483
513
|
|
|
484
514
|
if [ ! -f "$package_yaml" ]; then
|
|
485
515
|
echo "0.0.0"
|
|
486
|
-
return
|
|
516
|
+
return 0
|
|
487
517
|
fi
|
|
488
518
|
|
|
489
519
|
# Use awk to parse YAML array (acp.yaml.sh doesn't support array queries)
|
|
@@ -508,6 +538,8 @@ get_file_version() {
|
|
|
508
538
|
else
|
|
509
539
|
echo "$version"
|
|
510
540
|
fi
|
|
541
|
+
|
|
542
|
+
return 0
|
|
511
543
|
}
|
|
512
544
|
|
|
513
545
|
# Add package to manifest
|
|
@@ -526,7 +558,7 @@ add_package_to_manifest() {
|
|
|
526
558
|
# Check if package already exists
|
|
527
559
|
if grep -q "^ ${package_name}:" "$manifest" 2>/dev/null; then
|
|
528
560
|
# Update existing package
|
|
529
|
-
|
|
561
|
+
_sed_i "/^ ${package_name}:/,/^ [a-z]/ {
|
|
530
562
|
s|source: .*|source: $source_url|
|
|
531
563
|
s|package_version: .*|package_version: $package_version|
|
|
532
564
|
s|commit: .*|commit: $commit_hash|
|
|
@@ -537,10 +569,11 @@ add_package_to_manifest() {
|
|
|
537
569
|
# Find the packages: line and append after it
|
|
538
570
|
awk -v pkg="$package_name" -v src="$source_url" -v ver="$package_version" -v commit="$commit_hash" -v ts="$timestamp" '
|
|
539
571
|
/^packages:/ {
|
|
540
|
-
print
|
|
541
572
|
if ($2 == "{}") {
|
|
542
|
-
# Empty packages
|
|
543
|
-
|
|
573
|
+
# Empty packages - replace {} with just "packages:"
|
|
574
|
+
print "packages:"
|
|
575
|
+
} else {
|
|
576
|
+
print
|
|
544
577
|
}
|
|
545
578
|
print " " pkg ":"
|
|
546
579
|
print " source: " src
|
|
@@ -554,6 +587,7 @@ add_package_to_manifest() {
|
|
|
554
587
|
print " designs: []"
|
|
555
588
|
print " scripts: []"
|
|
556
589
|
print " files: []"
|
|
590
|
+
print " indices: []"
|
|
557
591
|
next
|
|
558
592
|
}
|
|
559
593
|
{ print }
|
|
@@ -602,7 +636,7 @@ add_file_to_manifest() {
|
|
|
602
636
|
fi
|
|
603
637
|
|
|
604
638
|
# Convert empty arrays [] to proper format first (workaround for parser limitation)
|
|
605
|
-
|
|
639
|
+
_sed_i "s/^ ${file_type}: \\[\\]$/ ${file_type}:/" "$manifest"
|
|
606
640
|
|
|
607
641
|
# Parse manifest
|
|
608
642
|
yaml_parse "$manifest"
|
|
@@ -637,7 +671,7 @@ get_commit_hash() {
|
|
|
637
671
|
|
|
638
672
|
if [ ! -d "$repo_dir/.git" ]; then
|
|
639
673
|
echo "unknown"
|
|
640
|
-
return
|
|
674
|
+
return 0
|
|
641
675
|
fi
|
|
642
676
|
|
|
643
677
|
(cd "$repo_dir" && git rev-parse HEAD 2>/dev/null) || echo "unknown"
|
|
@@ -701,8 +735,13 @@ is_file_modified() {
|
|
|
701
735
|
fi
|
|
702
736
|
|
|
703
737
|
# Calculate current checksum
|
|
738
|
+
# Map manifest key to filesystem directory (they differ for some types)
|
|
739
|
+
local file_dir="$file_type"
|
|
740
|
+
case "$file_type" in
|
|
741
|
+
indices) file_dir="index" ;;
|
|
742
|
+
esac
|
|
704
743
|
local current_checksum
|
|
705
|
-
current_checksum=$(calculate_checksum "agent/${
|
|
744
|
+
current_checksum=$(calculate_checksum "agent/${file_dir}/${file_name}")
|
|
706
745
|
|
|
707
746
|
if [ "$stored_checksum" != "$current_checksum" ]; then
|
|
708
747
|
return 0 # Modified
|
|
@@ -760,6 +799,166 @@ update_file_in_manifest() {
|
|
|
760
799
|
mv "$temp_file" "$manifest"
|
|
761
800
|
}
|
|
762
801
|
|
|
802
|
+
# ============================================================================
|
|
803
|
+
# Template File Manifest Functions
|
|
804
|
+
# ============================================================================
|
|
805
|
+
|
|
806
|
+
# Check if a template file was modified locally (uses target path, not agent/ path)
|
|
807
|
+
# Usage: is_template_file_modified "package_name" "filename" "target_path"
|
|
808
|
+
# Returns: 0 if modified, 1 if not modified
|
|
809
|
+
is_template_file_modified() {
|
|
810
|
+
local package_name="$1"
|
|
811
|
+
local file_name="$2"
|
|
812
|
+
local target_path="$3"
|
|
813
|
+
local manifest="agent/manifest.yaml"
|
|
814
|
+
|
|
815
|
+
# Get stored checksum from manifest
|
|
816
|
+
local stored_checksum
|
|
817
|
+
stored_checksum=$(awk -v pkg="$package_name" -v name="$file_name" '
|
|
818
|
+
BEGIN { in_pkg=0; in_files=0; in_file=0 }
|
|
819
|
+
$0 ~ "^ " pkg ":" { in_pkg=1; next }
|
|
820
|
+
in_pkg && /^ [a-z]/ && !/^ / { in_pkg=0 }
|
|
821
|
+
in_pkg && /^ files:/ { in_files=1; next }
|
|
822
|
+
in_files && /^ [a-z]/ && !/^ / { in_files=0 }
|
|
823
|
+
in_files && /^ - name:/ {
|
|
824
|
+
if ($3 == name) { in_file=1 }
|
|
825
|
+
else { in_file=0 }
|
|
826
|
+
next
|
|
827
|
+
}
|
|
828
|
+
in_file && /^ checksum:/ {
|
|
829
|
+
gsub(/sha256:/, "", $2)
|
|
830
|
+
print $2
|
|
831
|
+
exit
|
|
832
|
+
}
|
|
833
|
+
' "$manifest")
|
|
834
|
+
|
|
835
|
+
if [ -z "$stored_checksum" ]; then
|
|
836
|
+
warn "No checksum found in manifest for files/$file_name"
|
|
837
|
+
return 1
|
|
838
|
+
fi
|
|
839
|
+
|
|
840
|
+
# Calculate current checksum from target path
|
|
841
|
+
if [ ! -f "$target_path" ]; then
|
|
842
|
+
warn "Target file not found: $target_path"
|
|
843
|
+
return 0 # Missing = modified (deleted)
|
|
844
|
+
fi
|
|
845
|
+
|
|
846
|
+
local current_checksum
|
|
847
|
+
current_checksum=$(calculate_checksum "$target_path")
|
|
848
|
+
|
|
849
|
+
if [ "$stored_checksum" != "$current_checksum" ]; then
|
|
850
|
+
return 0 # Modified
|
|
851
|
+
else
|
|
852
|
+
return 1 # Not modified
|
|
853
|
+
fi
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
# Get target path for a template file from manifest
|
|
857
|
+
# Usage: target=$(get_template_file_target "package_name" "filename")
|
|
858
|
+
get_template_file_target() {
|
|
859
|
+
local package_name="$1"
|
|
860
|
+
local file_name="$2"
|
|
861
|
+
local manifest="agent/manifest.yaml"
|
|
862
|
+
|
|
863
|
+
awk -v pkg="$package_name" -v name="$file_name" '
|
|
864
|
+
BEGIN { in_pkg=0; in_files=0; in_file=0 }
|
|
865
|
+
$0 ~ "^ " pkg ":" { in_pkg=1; next }
|
|
866
|
+
in_pkg && /^ [a-z]/ && !/^ / { in_pkg=0 }
|
|
867
|
+
in_pkg && /^ files:/ { in_files=1; next }
|
|
868
|
+
in_files && /^ [a-z]/ && !/^ / { in_files=0 }
|
|
869
|
+
in_files && /^ - name:/ {
|
|
870
|
+
if ($3 == name) { in_file=1 }
|
|
871
|
+
else { in_file=0 }
|
|
872
|
+
next
|
|
873
|
+
}
|
|
874
|
+
in_file && /^ target:/ {
|
|
875
|
+
$1=""
|
|
876
|
+
gsub(/^ +/, "")
|
|
877
|
+
print
|
|
878
|
+
exit
|
|
879
|
+
}
|
|
880
|
+
' "$manifest"
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
# Get stored variable values for a template file from manifest
|
|
884
|
+
# Usage: vars=$(get_template_file_variables "package_name" "filename")
|
|
885
|
+
# Returns: KEY=VALUE lines (one per line)
|
|
886
|
+
get_template_file_variables() {
|
|
887
|
+
local package_name="$1"
|
|
888
|
+
local file_name="$2"
|
|
889
|
+
local manifest="agent/manifest.yaml"
|
|
890
|
+
|
|
891
|
+
awk -v pkg="$package_name" -v name="$file_name" '
|
|
892
|
+
BEGIN { in_pkg=0; in_files=0; in_file=0; in_vars=0 }
|
|
893
|
+
$0 ~ "^ " pkg ":" { in_pkg=1; next }
|
|
894
|
+
in_pkg && /^ [a-z]/ && !/^ / { in_pkg=0 }
|
|
895
|
+
in_pkg && /^ files:/ { in_files=1; next }
|
|
896
|
+
in_files && /^ [a-z]/ && !/^ / { in_files=0 }
|
|
897
|
+
in_files && /^ - name:/ {
|
|
898
|
+
if ($3 == name) { in_file=1 }
|
|
899
|
+
else { in_file=0; in_vars=0 }
|
|
900
|
+
next
|
|
901
|
+
}
|
|
902
|
+
in_file && /^ variables:/ { in_vars=1; next }
|
|
903
|
+
in_vars && /^ [A-Z]/ {
|
|
904
|
+
key=$1
|
|
905
|
+
gsub(/:$/, "", key)
|
|
906
|
+
$1=""
|
|
907
|
+
gsub(/^ +/, "")
|
|
908
|
+
print key "=" $0
|
|
909
|
+
next
|
|
910
|
+
}
|
|
911
|
+
in_vars && /^ [a-z]/ { in_vars=0 }
|
|
912
|
+
in_vars && /^ -/ { in_vars=0; in_file=0 }
|
|
913
|
+
' "$manifest"
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
# Update template file entry in manifest
|
|
917
|
+
# Usage: update_template_file_in_manifest "package_name" "filename" "new_version" "new_checksum"
|
|
918
|
+
update_template_file_in_manifest() {
|
|
919
|
+
local package_name="$1"
|
|
920
|
+
local file_name="$2"
|
|
921
|
+
local new_version="$3"
|
|
922
|
+
local new_checksum="$4"
|
|
923
|
+
local timestamp
|
|
924
|
+
timestamp=$(get_timestamp)
|
|
925
|
+
|
|
926
|
+
local manifest="agent/manifest.yaml"
|
|
927
|
+
|
|
928
|
+
local temp_file
|
|
929
|
+
temp_file=$(mktemp)
|
|
930
|
+
|
|
931
|
+
awk -v pkg="$package_name" -v name="$file_name" \
|
|
932
|
+
-v ver="$new_version" -v chk="sha256:$new_checksum" -v ts="$timestamp" '
|
|
933
|
+
BEGIN { in_pkg=0; in_files=0; in_file=0 }
|
|
934
|
+
$0 ~ "^ " pkg ":" { in_pkg=1; print; next }
|
|
935
|
+
in_pkg && /^ [a-z]/ && !/^ / { in_pkg=0; print; next }
|
|
936
|
+
in_pkg && /^ files:/ { in_files=1; print; next }
|
|
937
|
+
in_files && /^ [a-z]/ && !/^ / { in_files=0; print; next }
|
|
938
|
+
in_files && /^ - name:/ {
|
|
939
|
+
if ($3 == name) { in_file=1 }
|
|
940
|
+
else { in_file=0 }
|
|
941
|
+
print
|
|
942
|
+
next
|
|
943
|
+
}
|
|
944
|
+
in_file && /^ version:/ {
|
|
945
|
+
print " version: " ver
|
|
946
|
+
next
|
|
947
|
+
}
|
|
948
|
+
in_file && /^ checksum:/ {
|
|
949
|
+
print " checksum: " chk
|
|
950
|
+
next
|
|
951
|
+
}
|
|
952
|
+
in_file && /^ modified:/ {
|
|
953
|
+
print " modified: false"
|
|
954
|
+
next
|
|
955
|
+
}
|
|
956
|
+
{ print }
|
|
957
|
+
' "$manifest" > "$temp_file"
|
|
958
|
+
|
|
959
|
+
mv "$temp_file" "$manifest"
|
|
960
|
+
}
|
|
961
|
+
|
|
763
962
|
# ============================================================================
|
|
764
963
|
# Dependency Checking Functions
|
|
765
964
|
# ============================================================================
|
|
@@ -1437,14 +1636,41 @@ last_updated: ${timestamp}
|
|
|
1437
1636
|
EOF
|
|
1438
1637
|
}
|
|
1439
1638
|
|
|
1639
|
+
# Get git remote origin URL for a directory
|
|
1640
|
+
# Usage: origin=$(get_git_origin "/path/to/repo")
|
|
1641
|
+
# Returns: Git remote origin URL, or empty string if not a git repo or no origin
|
|
1642
|
+
get_git_origin() {
|
|
1643
|
+
local dir="${1:-.}"
|
|
1644
|
+
if [ -d "$dir/.git" ] || git -C "$dir" rev-parse --git-dir >/dev/null 2>&1; then
|
|
1645
|
+
git -C "$dir" remote get-url origin 2>/dev/null || echo ""
|
|
1646
|
+
else
|
|
1647
|
+
echo ""
|
|
1648
|
+
fi
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
# Get current git branch for a directory
|
|
1652
|
+
# Usage: branch=$(get_git_branch "/path/to/repo")
|
|
1653
|
+
# Returns: Current branch name, or empty string if not a git repo
|
|
1654
|
+
get_git_branch() {
|
|
1655
|
+
local dir="${1:-.}"
|
|
1656
|
+
if [ -d "$dir/.git" ] || git -C "$dir" rev-parse --git-dir >/dev/null 2>&1; then
|
|
1657
|
+
git -C "$dir" branch --show-current 2>/dev/null || echo ""
|
|
1658
|
+
else
|
|
1659
|
+
echo ""
|
|
1660
|
+
fi
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1440
1663
|
# Register project in registry
|
|
1441
|
-
# Usage: register_project "project-name" "/path/to/project" "project-type" "description"
|
|
1664
|
+
# Usage: register_project "project-name" "/path/to/project" "project-type" "description" ["git_origin"] ["git_branch"]
|
|
1442
1665
|
# NOTE: Caller must source acp.yaml-parser.sh before calling this function
|
|
1666
|
+
# git_origin and git_branch are optional; if omitted, auto-detected from project path
|
|
1443
1667
|
register_project() {
|
|
1444
1668
|
local project_name="$1"
|
|
1445
1669
|
local project_path="$2"
|
|
1446
1670
|
local project_type="$3"
|
|
1447
1671
|
local project_description="$4"
|
|
1672
|
+
local git_origin="${5:-}"
|
|
1673
|
+
local git_branch="${6:-}"
|
|
1448
1674
|
local registry_path
|
|
1449
1675
|
registry_path=$(get_projects_registry_path)
|
|
1450
1676
|
|
|
@@ -1471,7 +1697,24 @@ register_project() {
|
|
|
1471
1697
|
yaml_set "projects.${project_name}.last_modified" "$timestamp"
|
|
1472
1698
|
yaml_set "projects.${project_name}.last_accessed" "$timestamp"
|
|
1473
1699
|
yaml_set "projects.${project_name}.status" "active"
|
|
1474
|
-
|
|
1700
|
+
|
|
1701
|
+
# Auto-detect git origin/branch if not provided
|
|
1702
|
+
local expanded_path="${project_path/#\~/$HOME}"
|
|
1703
|
+
if [ -z "$git_origin" ] && [ -d "$expanded_path" ]; then
|
|
1704
|
+
git_origin=$(get_git_origin "$expanded_path")
|
|
1705
|
+
fi
|
|
1706
|
+
if [ -z "$git_branch" ] && [ -d "$expanded_path" ]; then
|
|
1707
|
+
git_branch=$(get_git_branch "$expanded_path")
|
|
1708
|
+
fi
|
|
1709
|
+
|
|
1710
|
+
# Set git fields if available
|
|
1711
|
+
if [ -n "$git_origin" ]; then
|
|
1712
|
+
yaml_set "projects.${project_name}.git_origin" "$git_origin"
|
|
1713
|
+
fi
|
|
1714
|
+
if [ -n "$git_branch" ]; then
|
|
1715
|
+
yaml_set "projects.${project_name}.git_branch" "$git_branch"
|
|
1716
|
+
fi
|
|
1717
|
+
|
|
1475
1718
|
# Set as current project if first project
|
|
1476
1719
|
local current
|
|
1477
1720
|
current=$(yaml_get "$registry_path" "current_project" 2>/dev/null || echo "")
|
|
@@ -71,6 +71,7 @@ mkdir -p "$TARGET_DIR/agent/drafts"
|
|
|
71
71
|
mkdir -p "$TARGET_DIR/agent/clarifications"
|
|
72
72
|
mkdir -p "$TARGET_DIR/agent/feedback"
|
|
73
73
|
mkdir -p "$TARGET_DIR/agent/preferences"
|
|
74
|
+
mkdir -p "$TARGET_DIR/agent/index"
|
|
74
75
|
|
|
75
76
|
# Create .gitkeep files
|
|
76
77
|
touch "$TARGET_DIR/agent/design/.gitkeep"
|
|
@@ -78,6 +79,7 @@ touch "$TARGET_DIR/agent/milestones/.gitkeep"
|
|
|
78
79
|
touch "$TARGET_DIR/agent/patterns/.gitkeep"
|
|
79
80
|
touch "$TARGET_DIR/agent/tasks/.gitkeep"
|
|
80
81
|
touch "$TARGET_DIR/agent/clarifications/.gitkeep"
|
|
82
|
+
touch "$TARGET_DIR/agent/index/.gitkeep"
|
|
81
83
|
|
|
82
84
|
# Create agent/.gitignore to exclude local-only directories from version control
|
|
83
85
|
cat > "$TARGET_DIR/agent/.gitignore" << 'EOF'
|
|
@@ -105,6 +107,11 @@ find "$TEMP_DIR/agent/patterns" -maxdepth 1 -name "*.template.md" -exec cp {} "$
|
|
|
105
107
|
find "$TEMP_DIR/agent/tasks" -maxdepth 1 -name "*.template.md" -exec cp {} "$TARGET_DIR/agent/tasks/" \;
|
|
106
108
|
find "$TEMP_DIR/agent/clarifications" -maxdepth 1 -name "*.template.md" -exec cp {} "$TARGET_DIR/agent/clarifications/" \;
|
|
107
109
|
|
|
110
|
+
# Copy index template files
|
|
111
|
+
if [ -d "$TEMP_DIR/agent/index" ]; then
|
|
112
|
+
find "$TEMP_DIR/agent/index" -maxdepth 1 -name "*.template.yaml" -exec cp {} "$TARGET_DIR/agent/index/" \;
|
|
113
|
+
fi
|
|
114
|
+
|
|
108
115
|
# Copy command template
|
|
109
116
|
cp "$TEMP_DIR/agent/commands/command.template.md" "$TARGET_DIR/agent/commands/"
|
|
110
117
|
|
|
@@ -150,11 +157,91 @@ fi
|
|
|
150
157
|
# Copy AGENT.md
|
|
151
158
|
cp "$TEMP_DIR/AGENT.md" "$TARGET_DIR/"
|
|
152
159
|
|
|
153
|
-
# Copy
|
|
154
|
-
# This ensures all current and future scripts are copied
|
|
160
|
+
# Copy scripts - selective installation based on command dependencies
|
|
155
161
|
if [ -d "$TEMP_DIR/agent/scripts" ]; then
|
|
156
|
-
|
|
157
|
-
|
|
162
|
+
# Check if this is ACP core (has package.yaml) or direct install
|
|
163
|
+
if [ -f "$TEMP_DIR/package.yaml" ]; then
|
|
164
|
+
# ACP core with package.yaml - selective script installation
|
|
165
|
+
echo "Resolving script dependencies from package.yaml..."
|
|
166
|
+
|
|
167
|
+
# Copy YAML parser first (needed for parsing)
|
|
168
|
+
if [ -f "$TEMP_DIR/agent/scripts/acp.yaml-parser.sh" ]; then
|
|
169
|
+
cp "$TEMP_DIR/agent/scripts/acp.yaml-parser.sh" "$TARGET_DIR/agent/scripts/"
|
|
170
|
+
chmod +x "$TARGET_DIR/agent/scripts/acp.yaml-parser.sh"
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
# Copy common utilities first (needed for parsing)
|
|
174
|
+
if [ -f "$TEMP_DIR/agent/scripts/acp.common.sh" ]; then
|
|
175
|
+
cp "$TEMP_DIR/agent/scripts/acp.common.sh" "$TARGET_DIR/agent/scripts/"
|
|
176
|
+
chmod +x "$TARGET_DIR/agent/scripts/acp.common.sh"
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
# Source YAML parser for querying
|
|
180
|
+
if [ -f "$TARGET_DIR/agent/scripts/acp.yaml-parser.sh" ]; then
|
|
181
|
+
. "$TARGET_DIR/agent/scripts/acp.yaml-parser.sh"
|
|
182
|
+
yaml_parse "$TEMP_DIR/package.yaml"
|
|
183
|
+
fi
|
|
184
|
+
|
|
185
|
+
# Find all NON-experimental commands in package (or all if no experimental filtering)
|
|
186
|
+
PACKAGE_COMMANDS=()
|
|
187
|
+
while IFS= read -r cmd; do
|
|
188
|
+
if [ -n "$cmd" ] && [ "$cmd" != "null" ]; then
|
|
189
|
+
# Check if command is experimental
|
|
190
|
+
is_exp=$(yaml_query ".contents.commands[] | select(.name == \"$cmd\") | .experimental?" 2>/dev/null || echo "false")
|
|
191
|
+
if [ "$is_exp" != "true" ]; then
|
|
192
|
+
PACKAGE_COMMANDS+=("$cmd")
|
|
193
|
+
fi
|
|
194
|
+
fi
|
|
195
|
+
done < <(yaml_query ".contents.commands[].name" 2>/dev/null || echo "")
|
|
196
|
+
|
|
197
|
+
# Collect required scripts from non-experimental commands
|
|
198
|
+
REQUIRED_SCRIPTS=()
|
|
199
|
+
for cmd in "${PACKAGE_COMMANDS[@]}"; do
|
|
200
|
+
# Read scripts array from package.yaml for this command
|
|
201
|
+
cmd_scripts=$(yaml_query ".contents.commands[] | select(.name == \"$cmd\") | .scripts[]?" 2>/dev/null || echo "")
|
|
202
|
+
|
|
203
|
+
# Add each script to required list (with deduplication)
|
|
204
|
+
while IFS= read -r script; do
|
|
205
|
+
if [ -n "$script" ] && [ "$script" != "null" ]; then
|
|
206
|
+
# Check if already in list
|
|
207
|
+
already_added=false
|
|
208
|
+
for existing in "${REQUIRED_SCRIPTS[@]}"; do
|
|
209
|
+
if [ "$existing" = "$script" ]; then
|
|
210
|
+
already_added=true
|
|
211
|
+
break
|
|
212
|
+
fi
|
|
213
|
+
done
|
|
214
|
+
|
|
215
|
+
if [ "$already_added" = false ]; then
|
|
216
|
+
REQUIRED_SCRIPTS+=("$script")
|
|
217
|
+
fi
|
|
218
|
+
fi
|
|
219
|
+
done <<< "$cmd_scripts"
|
|
220
|
+
done
|
|
221
|
+
|
|
222
|
+
# Install required scripts (excluding common.sh and yaml-parser.sh already copied)
|
|
223
|
+
for script in "${REQUIRED_SCRIPTS[@]}"; do
|
|
224
|
+
if [ "$script" = "acp.common.sh" ] || [ "$script" = "acp.yaml-parser.sh" ]; then
|
|
225
|
+
continue # Already copied
|
|
226
|
+
fi
|
|
227
|
+
|
|
228
|
+
if [ -f "$TEMP_DIR/agent/scripts/$script" ]; then
|
|
229
|
+
# Check if script is experimental
|
|
230
|
+
is_exp=$(yaml_query ".contents.scripts[] | select(.name == \"$script\") | .experimental?" 2>/dev/null || echo "false")
|
|
231
|
+
if [ "$is_exp" != "true" ]; then
|
|
232
|
+
cp "$TEMP_DIR/agent/scripts/$script" "$TARGET_DIR/agent/scripts/"
|
|
233
|
+
chmod +x "$TARGET_DIR/agent/scripts/$script"
|
|
234
|
+
fi
|
|
235
|
+
fi
|
|
236
|
+
done
|
|
237
|
+
|
|
238
|
+
echo "${GREEN}✓${NC} Installed ${#REQUIRED_SCRIPTS[@]} required script(s)"
|
|
239
|
+
else
|
|
240
|
+
# Direct install mode (no package.yaml) - copy all scripts
|
|
241
|
+
find "$TEMP_DIR/agent/scripts" -maxdepth 1 -name "*.sh" -exec cp {} "$TARGET_DIR/agent/scripts/" \;
|
|
242
|
+
chmod +x "$TARGET_DIR/agent/scripts"/*.sh 2>/dev/null || true
|
|
243
|
+
echo "${GREEN}✓${NC} Installed all scripts"
|
|
244
|
+
fi
|
|
158
245
|
fi
|
|
159
246
|
|
|
160
247
|
# Clean up deprecated scripts (from versions < 2.0.0)
|
|
@@ -214,7 +214,6 @@ fi
|
|
|
214
214
|
|
|
215
215
|
# Target directory (optional)
|
|
216
216
|
# Default: ~/.acp/projects/acp-{package-name}
|
|
217
|
-
# Note: ~/.acp/projects/ is for development, ~/.acp/packages/ is for installed packages
|
|
218
217
|
DEFAULT_TARGET_DIR="$HOME/.acp/projects/acp-${PACKAGE_NAME}"
|
|
219
218
|
if [ "$NON_INTERACTIVE" = false ] && [ -z "$TARGET_DIR" ]; then
|
|
220
219
|
read -p "Target directory [${DEFAULT_TARGET_DIR}]: " TARGET_DIR
|
|
@@ -150,11 +150,21 @@ designs_files=$(awk -v pkg="$PACKAGE_NAME" '
|
|
|
150
150
|
in_designs && /^ - name:/ { print $3 }
|
|
151
151
|
' "$MANIFEST_FILE")
|
|
152
152
|
|
|
153
|
+
indices_files=$(awk -v pkg="$PACKAGE_NAME" '
|
|
154
|
+
BEGIN { in_pkg=0; in_indices=0 }
|
|
155
|
+
$0 ~ "^ " pkg ":" { in_pkg=1; next }
|
|
156
|
+
in_pkg && /^ [a-z]/ { in_pkg=0 }
|
|
157
|
+
in_pkg && /^ indices:/ { in_indices=1; next }
|
|
158
|
+
in_indices && /^ [a-z]/ { in_indices=0 }
|
|
159
|
+
in_indices && /^ - name:/ { print $3 }
|
|
160
|
+
' "$MANIFEST_FILE")
|
|
161
|
+
|
|
153
162
|
# Count files
|
|
154
163
|
patterns_count=$(echo "$patterns_files" | grep -c . || echo 0)
|
|
155
164
|
commands_count=$(echo "$commands_files" | grep -c . || echo 0)
|
|
156
165
|
designs_count=$(echo "$designs_files" | grep -c . || echo 0)
|
|
157
|
-
|
|
166
|
+
indices_count=$(echo "$indices_files" | grep -c . || echo 0)
|
|
167
|
+
total_files=$((patterns_count + commands_count + designs_count + indices_count))
|
|
158
168
|
|
|
159
169
|
echo "${BLUE}Contents:${NC}"
|
|
160
170
|
echo ""
|
|
@@ -243,6 +253,14 @@ if [ "$designs_count" -gt 0 ]; then
|
|
|
243
253
|
echo ""
|
|
244
254
|
fi
|
|
245
255
|
|
|
256
|
+
if [ "$indices_count" -gt 0 ]; then
|
|
257
|
+
echo " ${GREEN}Indices ($indices_count):${NC}"
|
|
258
|
+
for file in $indices_files; do
|
|
259
|
+
echo " - $file (agent/index/$file)"
|
|
260
|
+
done
|
|
261
|
+
echo ""
|
|
262
|
+
fi
|
|
263
|
+
|
|
246
264
|
# Count modified files
|
|
247
265
|
modified_count=0
|
|
248
266
|
for file in $patterns_files; do
|
|
@@ -382,7 +382,7 @@ if [ ${#ALL_INSTALLED_FILES[@]} -gt 0 ]; then
|
|
|
382
382
|
checksum=$(echo "$line" | awk '{print $1}')
|
|
383
383
|
filepath=$(echo "$line" | awk '{$1=""; print substr($0,2)}')
|
|
384
384
|
CHECKSUMS["$filepath"]="$checksum"
|
|
385
|
-
done < <(sha256sum "${ALL_INSTALLED_FILES[@]}" 2>/dev/null)
|
|
385
|
+
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)
|
|
386
386
|
fi
|
|
387
387
|
|
|
388
388
|
# ============================================================================
|