repo-nexus 0.4.4 → 0.4.7
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/docs/rnex.example.yaml +28 -0
- package/package.json +1 -1
- package/rnex +245 -48
package/docs/rnex.example.yaml
CHANGED
|
@@ -23,6 +23,34 @@
|
|
|
23
23
|
|
|
24
24
|
repos_dir: ./repos
|
|
25
25
|
|
|
26
|
+
# ------------------------------------------------------------------------------
|
|
27
|
+
# ai_instructions — Main AI instructions routing file
|
|
28
|
+
# ------------------------------------------------------------------------------
|
|
29
|
+
# Main instructions file created and managed by Repo Nexus.
|
|
30
|
+
# Default: AGENTS.md (recognized by modern AI coding assistants)
|
|
31
|
+
#
|
|
32
|
+
# Examples:
|
|
33
|
+
# ai_instructions: AGENTS.md # default standard
|
|
34
|
+
# ai_instructions: CLAUDE.md # for Anthropic Claude Code CLI
|
|
35
|
+
# ai_instructions: GEMINI.md # for Google Gemini / Antigravity CLI
|
|
36
|
+
#
|
|
37
|
+
ai_instructions: AGENTS.md
|
|
38
|
+
|
|
39
|
+
# ------------------------------------------------------------------------------
|
|
40
|
+
# code_workspace — VS Code / Cursor multi-root workspace file
|
|
41
|
+
# ------------------------------------------------------------------------------
|
|
42
|
+
# Automatically generates and maintains a multi-root .code-workspace file mapping
|
|
43
|
+
# the workspace root and all active member repository clones.
|
|
44
|
+
#
|
|
45
|
+
# Default: false
|
|
46
|
+
#
|
|
47
|
+
# Examples:
|
|
48
|
+
# code_workspace: false # disabled (default)
|
|
49
|
+
# code_workspace: true # generates <workspace-name>.code-workspace
|
|
50
|
+
# code_workspace: workspace.code-workspace # custom filename
|
|
51
|
+
#
|
|
52
|
+
code_workspace: false
|
|
53
|
+
|
|
26
54
|
# ------------------------------------------------------------------------------
|
|
27
55
|
# plugins — Workspace plugins and AI instruction packs
|
|
28
56
|
# ------------------------------------------------------------------------------
|
package/package.json
CHANGED
package/rnex
CHANGED
|
@@ -118,6 +118,8 @@ require_workspace() {
|
|
|
118
118
|
WORKSPACE_YAML="$_cfg_path"
|
|
119
119
|
_init_local_yaml
|
|
120
120
|
_load_repos_dir
|
|
121
|
+
_load_ai_instructions_file
|
|
122
|
+
_load_code_workspace
|
|
121
123
|
log_info "Using workspace at ${_BOLD}$NEXUS_DIR${_NC} ${_DIM}(via config: $WORKSPACE_YAML)${_NC}"
|
|
122
124
|
return 0
|
|
123
125
|
fi
|
|
@@ -144,6 +146,8 @@ require_workspace() {
|
|
|
144
146
|
fi
|
|
145
147
|
_init_local_yaml
|
|
146
148
|
_load_repos_dir
|
|
149
|
+
_load_ai_instructions_file
|
|
150
|
+
_load_code_workspace
|
|
147
151
|
|
|
148
152
|
log_info "Using workspace at ${_BOLD}$NEXUS_DIR${_NC} ${_DIM}($(basename "$WORKSPACE_YAML") found)${_NC}"
|
|
149
153
|
}
|
|
@@ -161,10 +165,10 @@ _init_local_yaml() {
|
|
|
161
165
|
_load_repos_dir() {
|
|
162
166
|
_rd=""
|
|
163
167
|
if [ -f "$WORKSPACE_LOCAL_YAML" ]; then
|
|
164
|
-
_rd="$(awk '/^repos_dir:/ { sub(/^repos_dir:[ ]*/, ""); sub(/[ ]*#.*/, ""); print }' "$WORKSPACE_LOCAL_YAML")"
|
|
168
|
+
_rd="$(awk '/^repos_dir:/ { sub(/^repos_dir:[ ]*/, ""); sub(/[ ]*#.*/, ""); val=$0 } END { if (val) print val }' "$WORKSPACE_LOCAL_YAML")"
|
|
165
169
|
fi
|
|
166
170
|
if [ -z "$_rd" ] && [ -f "$WORKSPACE_YAML" ]; then
|
|
167
|
-
_rd="$(awk '/^repos_dir:/ { sub(/^repos_dir:[ ]*/, ""); sub(/[ ]*#.*/, ""); print }' "$WORKSPACE_YAML")"
|
|
171
|
+
_rd="$(awk '/^repos_dir:/ { sub(/^repos_dir:[ ]*/, ""); sub(/[ ]*#.*/, ""); val=$0 } END { if (val) print val }' "$WORKSPACE_YAML")"
|
|
168
172
|
fi
|
|
169
173
|
_rd="${_rd:-./repos}"
|
|
170
174
|
case "$_rd" in
|
|
@@ -173,6 +177,44 @@ _load_repos_dir() {
|
|
|
173
177
|
esac
|
|
174
178
|
}
|
|
175
179
|
|
|
180
|
+
_load_ai_instructions_file() {
|
|
181
|
+
_aif=""
|
|
182
|
+
if [ -f "$WORKSPACE_LOCAL_YAML" ]; then
|
|
183
|
+
_aif="$(awk '/^(ai_instructions|ai_instructions_file):/ { sub(/^[a-zA-Z0-9_]+:[ ]*/, ""); sub(/[ ]*#.*/, ""); val=$0 } END { if (val) print val }' "$WORKSPACE_LOCAL_YAML")"
|
|
184
|
+
fi
|
|
185
|
+
if [ -z "$_aif" ] && [ -f "$WORKSPACE_YAML" ]; then
|
|
186
|
+
_aif="$(awk '/^(ai_instructions|ai_instructions_file):/ { sub(/^[a-zA-Z0-9_]+:[ ]*/, ""); sub(/[ ]*#.*/, ""); val=$0 } END { if (val) print val }' "$WORKSPACE_YAML")"
|
|
187
|
+
fi
|
|
188
|
+
_aif="$(echo "$_aif" | tr -d " \t\r\n'\"")"
|
|
189
|
+
AI_INSTRUCTIONS_FILE="${_aif:-AGENTS.md}"
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
_load_code_workspace() {
|
|
193
|
+
_cw=""
|
|
194
|
+
if [ -f "$WORKSPACE_LOCAL_YAML" ]; then
|
|
195
|
+
_cw="$(awk '/^(code_workspace|vscode_workspace):/ { sub(/^[a-zA-Z0-9_]+:[ ]*/, ""); sub(/[ ]*#.*/, ""); val=$0 } END { if (val) print val }' "$WORKSPACE_LOCAL_YAML")"
|
|
196
|
+
fi
|
|
197
|
+
if [ -z "$_cw" ] && [ -f "$WORKSPACE_YAML" ]; then
|
|
198
|
+
_cw="$(awk '/^(code_workspace|vscode_workspace):/ { sub(/^[a-zA-Z0-9_]+:[ ]*/, ""); sub(/[ ]*#.*/, ""); val=$0 } END { if (val) print val }' "$WORKSPACE_YAML")"
|
|
199
|
+
fi
|
|
200
|
+
_cw="$(echo "$_cw" | tr -d " \t\r\n'\"")"
|
|
201
|
+
case "$_cw" in
|
|
202
|
+
true|yes|1)
|
|
203
|
+
_ws_basename="$(basename "$NEXUS_DIR")"
|
|
204
|
+
CODE_WORKSPACE_FILE="$_ws_basename.code-workspace"
|
|
205
|
+
;;
|
|
206
|
+
false|no|0|none|"")
|
|
207
|
+
CODE_WORKSPACE_FILE=""
|
|
208
|
+
;;
|
|
209
|
+
*)
|
|
210
|
+
case "$_cw" in
|
|
211
|
+
*.code-workspace) CODE_WORKSPACE_FILE="$_cw" ;;
|
|
212
|
+
*) CODE_WORKSPACE_FILE="$_cw.code-workspace" ;;
|
|
213
|
+
esac
|
|
214
|
+
;;
|
|
215
|
+
esac
|
|
216
|
+
}
|
|
217
|
+
|
|
176
218
|
# ---- YAML Parser / Manipulator (for rnex.yaml & .local.rnex.yaml) ----------
|
|
177
219
|
|
|
178
220
|
_yaml_list_plugins_from_file() {
|
|
@@ -509,7 +551,10 @@ resolve_repo_path() {
|
|
|
509
551
|
fi
|
|
510
552
|
}
|
|
511
553
|
|
|
512
|
-
ensure_repos_dir() {
|
|
554
|
+
ensure_repos_dir() {
|
|
555
|
+
mkdir -p "$REPOS_DIR"
|
|
556
|
+
[ -f "$REPOS_DIR/.gitkeep" ] || touch "$REPOS_DIR/.gitkeep"
|
|
557
|
+
}
|
|
513
558
|
|
|
514
559
|
# ---- Member Repo .rnex Isolation ------------------------------------------
|
|
515
560
|
|
|
@@ -899,6 +944,74 @@ merge_rnex_instructions() {
|
|
|
899
944
|
log_ok "Merged Repo Nexus routing instructions with existing $(basename "$_dst")"
|
|
900
945
|
}
|
|
901
946
|
|
|
947
|
+
sync_code_workspace() {
|
|
948
|
+
[ -n "$CODE_WORKSPACE_FILE" ] || return 0
|
|
949
|
+
_ws_path="$NEXUS_DIR/$CODE_WORKSPACE_FILE"
|
|
950
|
+
_root_name="$(basename "$NEXUS_DIR")"
|
|
951
|
+
|
|
952
|
+
_f_tmp="$(mktemp)"
|
|
953
|
+
|
|
954
|
+
printf ' {\n "name": "%s (Workspace Root)",\n "path": "."\n }' "$_root_name" > "$_f_tmp"
|
|
955
|
+
|
|
956
|
+
_repos_rel="${REPOS_DIR#"$NEXUS_DIR"/}"
|
|
957
|
+
_repos_rel="${_repos_rel#./}"
|
|
958
|
+
[ -n "$_repos_rel" ] || _repos_rel="repos"
|
|
959
|
+
|
|
960
|
+
yaml_list_repos | while read -r _rname; do
|
|
961
|
+
[ -n "$_rname" ] || continue
|
|
962
|
+
if yaml_repo_enabled "$_rname"; then
|
|
963
|
+
_rdir="$(resolve_repo_path "$_rname")"
|
|
964
|
+
if [ -d "$_rdir" ]; then
|
|
965
|
+
printf ',\n {\n "name": "%s",\n "path": "%s/%s"\n }' "$_rname" "$_repos_rel" "$_rname" >> "$_f_tmp"
|
|
966
|
+
fi
|
|
967
|
+
fi
|
|
968
|
+
done
|
|
969
|
+
|
|
970
|
+
if [ ! -f "$_ws_path" ]; then
|
|
971
|
+
{
|
|
972
|
+
printf '{\n "folders": [\n'
|
|
973
|
+
cat "$_f_tmp"
|
|
974
|
+
printf '\n ],\n "settings": {\n "search.exclude": {\n "**/node_modules": true,\n "**/.git": true\n }\n }\n}\n'
|
|
975
|
+
} > "$_ws_path"
|
|
976
|
+
rm -f "$_f_tmp"
|
|
977
|
+
log_ok "Created $CODE_WORKSPACE_FILE (VS Code / Cursor multi-root workspace)"
|
|
978
|
+
return 0
|
|
979
|
+
fi
|
|
980
|
+
|
|
981
|
+
if grep -q '"folders"[ ]*:' "$_ws_path" 2>/dev/null; then
|
|
982
|
+
_tmp_out="$(mktemp)"
|
|
983
|
+
awk -v f_src="$_f_tmp" '
|
|
984
|
+
BEGIN { in_f = 0 }
|
|
985
|
+
/"folders"[ ]*:[ ]*\[/ {
|
|
986
|
+
in_f = 1
|
|
987
|
+
print " \"folders\": ["
|
|
988
|
+
while ((getline line < f_src) > 0) print line
|
|
989
|
+
close(f_src)
|
|
990
|
+
next
|
|
991
|
+
}
|
|
992
|
+
in_f {
|
|
993
|
+
if (/\]/) {
|
|
994
|
+
in_f = 0
|
|
995
|
+
has_comma = ($0 ~ /,[ ]*$/) ? "," : ""
|
|
996
|
+
print " ]" has_comma
|
|
997
|
+
}
|
|
998
|
+
next
|
|
999
|
+
}
|
|
1000
|
+
{ print }
|
|
1001
|
+
' "$_ws_path" > "$_tmp_out" && mv "$_tmp_out" "$_ws_path"
|
|
1002
|
+
rm -f "$_f_tmp"
|
|
1003
|
+
log_ok "Updated folders in $CODE_WORKSPACE_FILE"
|
|
1004
|
+
else
|
|
1005
|
+
{
|
|
1006
|
+
printf '{\n "folders": [\n'
|
|
1007
|
+
cat "$_f_tmp"
|
|
1008
|
+
printf '\n ],\n "settings": {\n "search.exclude": {\n "**/node_modules": true,\n "**/.git": true\n }\n }\n}\n'
|
|
1009
|
+
} > "$_ws_path"
|
|
1010
|
+
rm -f "$_f_tmp"
|
|
1011
|
+
log_ok "Updated $CODE_WORKSPACE_FILE"
|
|
1012
|
+
fi
|
|
1013
|
+
}
|
|
1014
|
+
|
|
902
1015
|
# ============================================================================
|
|
903
1016
|
# Commands
|
|
904
1017
|
# ============================================================================
|
|
@@ -906,10 +1019,32 @@ merge_rnex_instructions() {
|
|
|
906
1019
|
cmd_init() {
|
|
907
1020
|
_non_interactive=0
|
|
908
1021
|
_target_dir=""
|
|
1022
|
+
_cli_ai_instructions=""
|
|
1023
|
+
_cli_code_workspace=""
|
|
909
1024
|
|
|
910
1025
|
while [ $# -gt 0 ]; do
|
|
911
1026
|
case "$1" in
|
|
912
1027
|
-y|--yes) _non_interactive=1 ;;
|
|
1028
|
+
--ai|--instructions|--ai-instructions)
|
|
1029
|
+
shift
|
|
1030
|
+
_cli_ai_instructions="$1"
|
|
1031
|
+
;;
|
|
1032
|
+
--code-workspace|--vscode)
|
|
1033
|
+
_cli_code_workspace="true"
|
|
1034
|
+
if [ $# -ge 2 ]; then
|
|
1035
|
+
case "$2" in
|
|
1036
|
+
-*) ;;
|
|
1037
|
+
*)
|
|
1038
|
+
case "$2" in
|
|
1039
|
+
true|false|*.code-workspace)
|
|
1040
|
+
shift
|
|
1041
|
+
_cli_code_workspace="$1"
|
|
1042
|
+
;;
|
|
1043
|
+
esac
|
|
1044
|
+
;;
|
|
1045
|
+
esac
|
|
1046
|
+
fi
|
|
1047
|
+
;;
|
|
913
1048
|
*)
|
|
914
1049
|
if [ -z "$_target_dir" ]; then
|
|
915
1050
|
_target_dir="$1"
|
|
@@ -943,6 +1078,12 @@ cmd_init() {
|
|
|
943
1078
|
# Directory for member repository clones
|
|
944
1079
|
repos_dir: ./repos
|
|
945
1080
|
|
|
1081
|
+
# Main AI instructions routing file (default: AGENTS.md; e.g. CLAUDE.md, GEMINI.md)
|
|
1082
|
+
ai_instructions: ${_cli_ai_instructions:-AGENTS.md}
|
|
1083
|
+
|
|
1084
|
+
# VS Code / Cursor multi-root workspace file (default: false; e.g. true or workspace.code-workspace)
|
|
1085
|
+
code_workspace: ${_cli_code_workspace:-false}
|
|
1086
|
+
|
|
946
1087
|
# Workspace plugins
|
|
947
1088
|
plugins:
|
|
948
1089
|
|
|
@@ -953,51 +1094,79 @@ YAML_EOF
|
|
|
953
1094
|
log_ok "Created $RNEX_CONFIG_FILE"
|
|
954
1095
|
fi
|
|
955
1096
|
|
|
956
|
-
# ---- 2. Merge routing instructions into
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
if [ "$
|
|
962
|
-
|
|
963
|
-
printf 'Would you like to generate routing files for other assistants?\n'
|
|
964
|
-
printf ' [1] Claude Code (CLAUDE.md)\n'
|
|
965
|
-
printf ' [2] Cursor (.cursorrules)\n'
|
|
966
|
-
printf ' [3] Both (CLAUDE.md & .cursorrules)\n'
|
|
967
|
-
printf ' [Enter to skip]\n'
|
|
968
|
-
printf 'Choice [1/2/3/skip]: '
|
|
969
|
-
read -r _choice || _choice=""
|
|
970
|
-
case "$_choice" in
|
|
971
|
-
1)
|
|
972
|
-
merge_rnex_instructions "$_target_dir/CLAUDE.md"
|
|
973
|
-
;;
|
|
974
|
-
2)
|
|
975
|
-
merge_rnex_instructions "$_target_dir/.cursorrules"
|
|
976
|
-
;;
|
|
977
|
-
3)
|
|
978
|
-
merge_rnex_instructions "$_target_dir/CLAUDE.md"
|
|
979
|
-
merge_rnex_instructions "$_target_dir/.cursorrules"
|
|
980
|
-
;;
|
|
981
|
-
*)
|
|
982
|
-
;;
|
|
983
|
-
esac
|
|
1097
|
+
# ---- 2. Merge routing instructions into main AI instructions file ---------
|
|
1098
|
+
_target_aif="$_cli_ai_instructions"
|
|
1099
|
+
if [ -z "$_target_aif" ] && [ -f "$_target_dir/$RNEX_LOCAL_CONFIG_FILE" ]; then
|
|
1100
|
+
_target_aif="$(awk '/^(ai_instructions|ai_instructions_file):/ { sub(/^[a-zA-Z0-9_]+:[ ]*/, ""); sub(/[ ]*#.*/, ""); val=$0 } END { if (val) print val }' "$_target_dir/$RNEX_LOCAL_CONFIG_FILE")"
|
|
1101
|
+
fi
|
|
1102
|
+
if [ -z "$_target_aif" ] && [ -f "$_target_yaml" ]; then
|
|
1103
|
+
_target_aif="$(awk '/^(ai_instructions|ai_instructions_file):/ { sub(/^[a-zA-Z0-9_]+:[ ]*/, ""); sub(/[ ]*#.*/, ""); val=$0 } END { if (val) print val }' "$_target_yaml")"
|
|
984
1104
|
fi
|
|
1105
|
+
_target_aif="$(echo "$_target_aif" | tr -d " \t\r\n'\"")"
|
|
1106
|
+
_target_aif="${_target_aif:-AGENTS.md}"
|
|
1107
|
+
|
|
1108
|
+
_target_agents="$_target_dir/$_target_aif"
|
|
1109
|
+
merge_rnex_instructions "$_target_agents"
|
|
1110
|
+
[ -f "$_target_dir/AGENTS.md" ] && [ "$_target_aif" != "AGENTS.md" ] && merge_rnex_instructions "$_target_dir/AGENTS.md"
|
|
1111
|
+
[ -f "$_target_dir/CLAUDE.md" ] && [ "$_target_aif" != "CLAUDE.md" ] && merge_rnex_instructions "$_target_dir/CLAUDE.md"
|
|
1112
|
+
[ -f "$_target_dir/.cursorrules" ] && [ "$_target_aif" != ".cursorrules" ] && merge_rnex_instructions "$_target_dir/.cursorrules"
|
|
985
1113
|
|
|
986
|
-
# ----
|
|
1114
|
+
# ---- 3. Create repos directory with .gitkeep -----------------------------
|
|
987
1115
|
_repos_dir="$_target_dir/repos"
|
|
988
1116
|
mkdir -p "$_repos_dir"
|
|
1117
|
+
[ -f "$_repos_dir/.gitkeep" ] || touch "$_repos_dir/.gitkeep"
|
|
989
1118
|
|
|
990
|
-
# ----
|
|
1119
|
+
# ---- 4. Create internal .rnex directory ----------------------------------
|
|
991
1120
|
mkdir -p "$_target_dir/.rnex"
|
|
992
1121
|
mkdir -p "$_target_dir/.rnex/plugins"
|
|
993
1122
|
|
|
994
|
-
# ----
|
|
1123
|
+
# ---- 5. Ensure repos/, .rnex/, and local configs are gitignored ---------
|
|
995
1124
|
reconcile_gitignore "$_target_dir"
|
|
996
1125
|
|
|
1126
|
+
# ---- 6. Generate VS Code / Cursor workspace if configured ----------------
|
|
1127
|
+
_target_cw="$_cli_code_workspace"
|
|
1128
|
+
if [ -z "$_target_cw" ] && [ -f "$_target_dir/$RNEX_LOCAL_CONFIG_FILE" ]; then
|
|
1129
|
+
_target_cw="$(awk '/^(code_workspace|vscode_workspace):/ { sub(/^[a-zA-Z0-9_]+:[ ]*/, ""); sub(/[ ]*#.*/, ""); val=$0 } END { if (val) print val }' "$_target_dir/$RNEX_LOCAL_CONFIG_FILE")"
|
|
1130
|
+
fi
|
|
1131
|
+
if [ -z "$_target_cw" ] && [ -f "$_target_yaml" ]; then
|
|
1132
|
+
_target_cw="$(awk '/^(code_workspace|vscode_workspace):/ { sub(/^[a-zA-Z0-9_]+:[ ]*/, ""); sub(/[ ]*#.*/, ""); val=$0 } END { if (val) print val }' "$_target_yaml")"
|
|
1133
|
+
fi
|
|
1134
|
+
_target_cw="$(echo "$_target_cw" | tr -d " \t\r\n'\"")"
|
|
1135
|
+
case "$_target_cw" in
|
|
1136
|
+
true|yes|1)
|
|
1137
|
+
_cw_name="$(basename "$_target_dir").code-workspace"
|
|
1138
|
+
;;
|
|
1139
|
+
false|no|0|none|"")
|
|
1140
|
+
_cw_name=""
|
|
1141
|
+
;;
|
|
1142
|
+
*)
|
|
1143
|
+
case "$_target_cw" in
|
|
1144
|
+
*.code-workspace) _cw_name="$_target_cw" ;;
|
|
1145
|
+
*) _cw_name="$_target_cw.code-workspace" ;;
|
|
1146
|
+
esac
|
|
1147
|
+
;;
|
|
1148
|
+
esac
|
|
1149
|
+
|
|
1150
|
+
if [ -n "$_cw_name" ]; then
|
|
1151
|
+
_orig_nexus="$NEXUS_DIR"
|
|
1152
|
+
_orig_repos="$REPOS_DIR"
|
|
1153
|
+
_orig_cw="$CODE_WORKSPACE_FILE"
|
|
1154
|
+
CODE_WORKSPACE_FILE="$_cw_name"
|
|
1155
|
+
NEXUS_DIR="$_target_dir"
|
|
1156
|
+
_repos_rel="repos"
|
|
1157
|
+
REPOS_DIR="$_target_dir/$_repos_rel"
|
|
1158
|
+
sync_code_workspace
|
|
1159
|
+
NEXUS_DIR="$_orig_nexus"
|
|
1160
|
+
REPOS_DIR="$_orig_repos"
|
|
1161
|
+
CODE_WORKSPACE_FILE="$_orig_cw"
|
|
1162
|
+
fi
|
|
1163
|
+
|
|
997
1164
|
if [ "$_config_created" -eq 1 ]; then
|
|
998
1165
|
printf '\n'
|
|
999
1166
|
log_ok "Initialized Repo Nexus workspace at ${_BOLD}$_target_dir${_NC}"
|
|
1000
|
-
|
|
1167
|
+
_created_items="$RNEX_CONFIG_FILE, $_target_aif, .rnex/, and repos/"
|
|
1168
|
+
[ -n "$_cw_name" ] && _created_items="$_created_items (and $_cw_name)"
|
|
1169
|
+
log_dim "Created $_created_items"
|
|
1001
1170
|
printf '\n'
|
|
1002
1171
|
log_info "Next steps:"
|
|
1003
1172
|
log_dim "1. Add repositories with: rnex add <name> <git-url>"
|
|
@@ -1055,6 +1224,7 @@ cmd_add() {
|
|
|
1055
1224
|
[ "$_rnex_dir" = "false" ] && yaml_set_local "$_name" "rnex_dir" "false"
|
|
1056
1225
|
[ "$_enabled" = "false" ] && yaml_set_local "$_name" "enabled" "false"
|
|
1057
1226
|
sync_repo_rnex "$_name"
|
|
1227
|
+
sync_code_workspace
|
|
1058
1228
|
printf '\n'
|
|
1059
1229
|
log_ok "Registered repo '${_name}' in $(basename "$WORKSPACE_LOCAL_YAML")"
|
|
1060
1230
|
return 0
|
|
@@ -1070,6 +1240,7 @@ cmd_add() {
|
|
|
1070
1240
|
[ "$_rnex_dir" = "false" ] && yaml_set "$_name" "rnex_dir" "false"
|
|
1071
1241
|
[ "$_enabled" = "false" ] && yaml_set "$_name" "enabled" "false"
|
|
1072
1242
|
sync_repo_rnex "$_name"
|
|
1243
|
+
sync_code_workspace
|
|
1073
1244
|
printf '\n'
|
|
1074
1245
|
log_ok "Updated repo '${_name}' in $(basename "$WORKSPACE_YAML")"
|
|
1075
1246
|
return 0
|
|
@@ -1078,6 +1249,7 @@ cmd_add() {
|
|
|
1078
1249
|
|
|
1079
1250
|
yaml_add_repo "$_name" "$_url" "$_rnex_dir" "$_enabled"
|
|
1080
1251
|
sync_repo_rnex "$_name"
|
|
1252
|
+
sync_code_workspace
|
|
1081
1253
|
printf '\n'
|
|
1082
1254
|
log_ok "Registered and added repo '${_name}'"
|
|
1083
1255
|
}
|
|
@@ -1121,6 +1293,7 @@ cmd_clone() {
|
|
|
1121
1293
|
fi
|
|
1122
1294
|
fi
|
|
1123
1295
|
done
|
|
1296
|
+
sync_code_workspace
|
|
1124
1297
|
printf '\n'
|
|
1125
1298
|
}
|
|
1126
1299
|
|
|
@@ -1178,6 +1351,7 @@ cmd_enable() {
|
|
|
1178
1351
|
log_ok "Enabled repo '$_name' in $(basename "$WORKSPACE_YAML")"
|
|
1179
1352
|
fi
|
|
1180
1353
|
sync_repo_rnex "$_name"
|
|
1354
|
+
sync_code_workspace
|
|
1181
1355
|
}
|
|
1182
1356
|
|
|
1183
1357
|
cmd_disable() {
|
|
@@ -1201,6 +1375,7 @@ cmd_disable() {
|
|
|
1201
1375
|
yaml_set "$_name" "enabled" "false"
|
|
1202
1376
|
log_ok "Disabled repo '$_name' in $(basename "$WORKSPACE_YAML")"
|
|
1203
1377
|
fi
|
|
1378
|
+
sync_code_workspace
|
|
1204
1379
|
}
|
|
1205
1380
|
|
|
1206
1381
|
cmd_show() {
|
|
@@ -1225,6 +1400,7 @@ cmd_remove() {
|
|
|
1225
1400
|
else
|
|
1226
1401
|
log_ok "Unregistered repo '$_name'"
|
|
1227
1402
|
fi
|
|
1403
|
+
sync_code_workspace
|
|
1228
1404
|
}
|
|
1229
1405
|
|
|
1230
1406
|
cmd_list() {
|
|
@@ -1282,6 +1458,10 @@ cmd_status() {
|
|
|
1282
1458
|
printf ' %b○%b Local Config: %s %b(not found — using repo defaults)%b\n' "$_DIM" "$_NC" "$WORKSPACE_LOCAL_YAML" "$_DIM" "$_NC"
|
|
1283
1459
|
fi
|
|
1284
1460
|
printf ' %b●%b Repos Dir: %s\n' "$_DIM" "$_NC" "$REPOS_DIR"
|
|
1461
|
+
printf ' %b●%b AI File: %s\n' "$_DIM" "$_NC" "$AI_INSTRUCTIONS_FILE"
|
|
1462
|
+
if [ -n "$CODE_WORKSPACE_FILE" ]; then
|
|
1463
|
+
printf ' %b●%b Workspace: %s\n' "$_DIM" "$_NC" "$CODE_WORKSPACE_FILE"
|
|
1464
|
+
fi
|
|
1285
1465
|
|
|
1286
1466
|
_gi="$NEXUS_DIR/.gitignore"
|
|
1287
1467
|
_gi_repos=0; _gi_rnex=0; _gi_local=0; _gi_has_counter=0
|
|
@@ -1300,17 +1480,29 @@ cmd_status() {
|
|
|
1300
1480
|
printf '\n'
|
|
1301
1481
|
|
|
1302
1482
|
printf '%bWorkspace AI Context (Routing):%b\n' "$_BOLD" "$_NC"
|
|
1303
|
-
|
|
1304
|
-
|
|
1483
|
+
_main_ai="${AI_INSTRUCTIONS_FILE:-AGENTS.md}"
|
|
1484
|
+
if [ -e "$NEXUS_DIR/$_main_ai" ]; then
|
|
1485
|
+
printf ' %b✓%b %s %b(main instructions)%b\n' "$_G" "$_NC" "$_main_ai" "$_DIM" "$_NC"
|
|
1305
1486
|
else
|
|
1306
|
-
printf ' %b✗%b %s (
|
|
1307
|
-
fi
|
|
1308
|
-
if [ -f "$NEXUS_DIR/CLAUDE.md" ]; then
|
|
1309
|
-
printf ' %b✓%b %s\n' "$_G" "$_NC" "CLAUDE.md"
|
|
1487
|
+
printf ' %b✗%b %s %b(main instructions — MISSING; run "rnex fix" to create)%b\n' "$_R" "$_NC" "$_main_ai" "$_R" "$_NC"
|
|
1310
1488
|
fi
|
|
1311
|
-
|
|
1312
|
-
|
|
1489
|
+
for _aux_ai in "AGENTS.md" "CLAUDE.md" "GEMINI.md" ".cursorrules"; do
|
|
1490
|
+
if [ "$_aux_ai" != "$_main_ai" ] && [ -f "$NEXUS_DIR/$_aux_ai" ]; then
|
|
1491
|
+
printf ' %b✓%b %s\n' "$_G" "$_NC" "$_aux_ai"
|
|
1492
|
+
fi
|
|
1493
|
+
done
|
|
1494
|
+
if [ -n "$CODE_WORKSPACE_FILE" ]; then
|
|
1495
|
+
if [ -f "$NEXUS_DIR/$CODE_WORKSPACE_FILE" ]; then
|
|
1496
|
+
printf ' %b✓%b %s %b(VS Code / Cursor workspace)%b\n' "$_G" "$_NC" "$CODE_WORKSPACE_FILE" "$_DIM" "$_NC"
|
|
1497
|
+
else
|
|
1498
|
+
printf ' %b✗%b %s %b(VS Code / Cursor workspace — MISSING; run "rnex fix" to create)%b\n' "$_R" "$_NC" "$CODE_WORKSPACE_FILE" "$_R" "$_NC"
|
|
1499
|
+
fi
|
|
1313
1500
|
fi
|
|
1501
|
+
for _found_cw in "$NEXUS_DIR"/*.code-workspace; do
|
|
1502
|
+
if [ -f "$_found_cw" ] && [ "$(basename "$_found_cw")" != "$CODE_WORKSPACE_FILE" ]; then
|
|
1503
|
+
printf ' %b✓%b %s %b(VS Code / Cursor workspace)%b\n' "$_G" "$_NC" "$(basename "$_found_cw")" "$_DIM" "$_NC"
|
|
1504
|
+
fi
|
|
1505
|
+
done
|
|
1314
1506
|
if [ -d "$NEXUS_DIR/.rnex" ]; then
|
|
1315
1507
|
printf ' %b✓%b %s\n' "$_G" "$_NC" ".rnex/"
|
|
1316
1508
|
fi
|
|
@@ -1380,10 +1572,11 @@ cmd_fix() {
|
|
|
1380
1572
|
# 1. Ensure .gitignore ignores repos/, .rnex/, and local configs, and strips legacy counters
|
|
1381
1573
|
reconcile_gitignore "$NEXUS_DIR"
|
|
1382
1574
|
|
|
1383
|
-
# 2. Reconcile instructions in
|
|
1384
|
-
merge_rnex_instructions "$NEXUS_DIR
|
|
1385
|
-
[ -f "$NEXUS_DIR/
|
|
1386
|
-
[ -f "$NEXUS_DIR
|
|
1575
|
+
# 2. Reconcile instructions in main AI instructions file (and optional AI assistant files if present)
|
|
1576
|
+
merge_rnex_instructions "$NEXUS_DIR/$AI_INSTRUCTIONS_FILE"
|
|
1577
|
+
[ -f "$NEXUS_DIR/AGENTS.md" ] && [ "$AI_INSTRUCTIONS_FILE" != "AGENTS.md" ] && merge_rnex_instructions "$NEXUS_DIR/AGENTS.md"
|
|
1578
|
+
[ -f "$NEXUS_DIR/CLAUDE.md" ] && [ "$AI_INSTRUCTIONS_FILE" != "CLAUDE.md" ] && merge_rnex_instructions "$NEXUS_DIR/CLAUDE.md"
|
|
1579
|
+
[ -f "$NEXUS_DIR/.cursorrules" ] && [ "$AI_INSTRUCTIONS_FILE" != ".cursorrules" ] && merge_rnex_instructions "$NEXUS_DIR/.cursorrules"
|
|
1387
1580
|
|
|
1388
1581
|
# 3. Reconcile plugins
|
|
1389
1582
|
sync_plugins
|
|
@@ -1401,6 +1594,9 @@ cmd_fix() {
|
|
|
1401
1594
|
fi
|
|
1402
1595
|
done
|
|
1403
1596
|
|
|
1597
|
+
# 5. Reconcile VS Code / Cursor multi-root workspace if configured
|
|
1598
|
+
sync_code_workspace
|
|
1599
|
+
|
|
1404
1600
|
log_ok "Fix complete — workspace, plugins, and member .rnex directories reconciled"
|
|
1405
1601
|
}
|
|
1406
1602
|
|
|
@@ -1736,7 +1932,8 @@ cmd_help() {
|
|
|
1736
1932
|
-v, --version Show version
|
|
1737
1933
|
|
|
1738
1934
|
WORKSPACE & SYSTEM SETUP
|
|
1739
|
-
init [-y] [
|
|
1935
|
+
init [-y] [--ai <file>] [--code-workspace [file]] [dir]
|
|
1936
|
+
Initialize a new Repo Nexus workspace (default AI file: AGENTS.md)
|
|
1740
1937
|
install [dir] Install rnex & repo-nexus globally into ~/.local/bin (or custom dir)
|
|
1741
1938
|
fix Reconcile workspace, plugins & member .rnex/ directories (alias: sync)
|
|
1742
1939
|
completion <shell> Generate shell completion script (bash, zsh, fish)
|