@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.
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 +1971 -94
  87. package/dist/server.js +1168 -45
  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
@@ -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 "$file" 2>/dev/null | cut -d' ' -f1
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
- sed -i "s/^last_updated: .*/last_updated: $timestamp/" "$manifest"
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
- sed -i "s/^updated: .*/updated: $timestamp/" "$manifest_path"
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 1
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
- sed -i "/^ ${package_name}:/,/^ [a-z]/ {
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, replace line
543
- next
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
- sed -i "s/^ ${file_type}: \\[\\]$/ ${file_type}:/" "$manifest"
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 1
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/${file_type}/${file_name}")
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 all scripts (*.sh files)
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
- find "$TEMP_DIR/agent/scripts" -maxdepth 1 -name "*.sh" -exec cp {} "$TARGET_DIR/agent/scripts/" \;
157
- chmod +x "$TARGET_DIR/agent/scripts"/*.sh
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
- total_files=$((patterns_count + commands_count + designs_count))
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
  # ============================================================================