repo-nexus 0.7.19 → 0.7.22

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.
@@ -55,8 +55,11 @@ complete -F _rnex_completions repo-nexus
55
55
  # Prompt hook for zero-fork auto-synchronization
56
56
  _rnex_auto_sync() {
57
57
  [ -f rnex.yaml ] || return 0
58
- if [ ! -f .rnex/.sync_stamp ] || [ rnex.yaml -nt .rnex/.sync_stamp ] || \
59
- { [ -f .local.rnex.yaml ] && [ .local.rnex.yaml -nt .rnex/.sync_stamp ]; }; then
58
+ _stamp=""
59
+ [ -f .rnex/sync_stamp ] && _stamp=".rnex/sync_stamp"
60
+ [ -z "$_stamp" ] && [ -f .rnex/.sync_stamp ] && _stamp=".rnex/.sync_stamp"
61
+ if [ -z "$_stamp" ] || [ rnex.yaml -nt "$_stamp" ] || \
62
+ { [ -f .local.rnex.yaml ] && [ .local.rnex.yaml -nt "$_stamp" ]; }; then
60
63
  rnex sync -y --quiet
61
64
  fi
62
65
  }
@@ -143,8 +146,11 @@ _rnex "$@"
143
146
  # Prompt hook for zero-fork auto-synchronization
144
147
  _rnex_auto_sync() {
145
148
  [ -f rnex.yaml ] || return 0
146
- if [ ! -f .rnex/.sync_stamp ] || [ rnex.yaml -nt .rnex/.sync_stamp ] || \
147
- { [ -f .local.rnex.yaml ] && [ .local.rnex.yaml -nt .rnex/.sync_stamp ]; }; then
149
+ _stamp=""
150
+ [ -f .rnex/sync_stamp ] && _stamp=".rnex/sync_stamp"
151
+ [ -z "$_stamp" ] && [ -f .rnex/.sync_stamp ] && _stamp=".rnex/.sync_stamp"
152
+ if [ -z "$_stamp" ] || [ rnex.yaml -nt "$_stamp" ] || \
153
+ { [ -f .local.rnex.yaml ] && [ .local.rnex.yaml -nt "$_stamp" ]; }; then
148
154
  rnex sync -y --quiet
149
155
  fi
150
156
  }
@@ -179,7 +185,13 @@ complete -c rnex -n "__fish_use_subcommand" -a version -d "Show version"
179
185
 
180
186
  function _rnex_auto_sync --on-event fish_prompt
181
187
  test -f rnex.yaml; or return 0
182
- if not test -f .rnex/.sync_stamp; or test rnex.yaml -nt .rnex/.sync_stamp; or test -f .local.rnex.yaml -a .local.rnex.yaml -nt .rnex/.sync_stamp
188
+ set -l _stamp ""
189
+ if test -f .rnex/sync_stamp
190
+ set _stamp .rnex/sync_stamp
191
+ else if test -f .rnex/.sync_stamp
192
+ set _stamp .rnex/.sync_stamp
193
+ end
194
+ if test -z "$_stamp"; or test rnex.yaml -nt "$_stamp"; or test -f .local.rnex.yaml -a .local.rnex.yaml -nt "$_stamp"
183
195
  rnex sync -y --quiet
184
196
  end
185
197
  end
@@ -131,8 +131,8 @@ cmd_plugin_info() {
131
131
  [ -n "$_item" ] || continue
132
132
  _s="${_item%%:*}"
133
133
  _d="${_item#*:}"
134
- _s="$(printf '%s' "$_s" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's/^["\047]//' -e 's/["\047]$//')"
135
- _d="$(printf '%s' "$_d" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's/^["\047]//' -e 's/["\047]$//')"
134
+ _s="$(printf '%s' "$_s" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr -d "'\"")"
135
+ _d="$(printf '%s' "$_d" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr -d "'\"")"
136
136
  _d="$(plugin_resolve_placeholders "$_name" "$_pdir" "$_d")"
137
137
  printf ' - %s → %s\n' "$_s" "$_d"
138
138
  done
@@ -51,6 +51,7 @@ cmd_status() {
51
51
  fi
52
52
 
53
53
  _stamp_file="$NEXUS_DIR/.rnex/.sync_stamp"
54
+ [ -f "$_stamp_file" ] || _stamp_file="$NEXUS_DIR/.rnex/sync_stamp"
54
55
  _cur_sum="$(get_config_sum "$NEXUS_DIR")"
55
56
  if [ ! -f "$_stamp_file" ] || [ "$_cur_sum" != "$(cat "$_stamp_file" 2>/dev/null)" ]; then
56
57
  printf ' %b!%b Sync Stamp: workspace out of sync with configuration (run "rnex sync")\n' "$_Y" "$_NC"
@@ -16,6 +16,7 @@ _ws="$(cd "$(dirname "$0")/../.." 2>/dev/null && pwd -P)"
16
16
  [ -f "$_ws/rnex.yaml" ] || exit 0
17
17
 
18
18
  _stamp="$_ws/.rnex/.sync_stamp"
19
+ [ -f "$_stamp" ] || _stamp="$_ws/.rnex/sync_stamp"
19
20
  _cur_sum="$(cd "$_ws" 2>/dev/null && cksum rnex.yaml .local.rnex.yaml 2>/dev/null | cksum | awk '{print $1, $2}')"
20
21
  _saved_sum=""
21
22
  [ -f "$_stamp" ] && _saved_sum="$(cat "$_stamp" 2>/dev/null)"
@@ -70,22 +71,38 @@ cmd_sync() {
70
71
  [ "$_sync_quiet" -eq 0 ] && log_ok "Upgraded workspace configuration and routing instructions to v$RNEX_VERSION"
71
72
  fi
72
73
 
73
- # 1. Ensure .gitignore ignores repos/, local configs; ensure .ignore has !repos/*
74
+ # --------------------------------------------------------------------------
75
+ # Step 1: Sync hardcoded files & invoke commands that do not depend on config
76
+ # --------------------------------------------------------------------------
77
+ # 1.1. Ensure .gitignore ignores repos/, local configs; ensure .ignore has !repos/*
74
78
  reconcile_gitignore "$NEXUS_DIR"
75
79
 
76
- # 2. Reconcile plugins (scopes, deterministic sync, lifecycle hooks copy)
77
- sync_plugins
80
+ # 1.2. Reconcile universal workspace instructions in AGENTS.md
81
+ merge_rnex_instructions "$NEXUS_DIR/AGENTS.md"
82
+
83
+ # 1.3. Generate auto-sync script and AI session-start hooks (hardcoded harness)
84
+ _write_auto_sync_script "$NEXUS_DIR"
85
+ _sync_ai_session_start_hooks "$NEXUS_DIR"
86
+
87
+ # 1.4. Sync core agentic skills into .rnex/skills/ and write rnex-env.sh
88
+ sync_skills
78
89
 
79
- # 3. Compile .rnex/ai-instructions.md
90
+ # --------------------------------------------------------------------------
91
+ # Step 2: Generate .rnex/ai-instructions.md and .rnex/sync_stamp
92
+ # --------------------------------------------------------------------------
93
+ # 2.1. Compile .rnex/ai-instructions.md
80
94
  build_ai_instructions "$NEXUS_DIR"
81
95
 
82
- # 4. Reconcile universal workspace instructions in AGENTS.md
83
- merge_rnex_instructions "$NEXUS_DIR/AGENTS.md"
96
+ # 2.2. Update sync stamp (.rnex/.sync_stamp and .rnex/sync_stamp)
97
+ update_sync_stamp "$NEXUS_DIR"
84
98
 
85
- # 5. Sync core agentic skills and active provider user skills
86
- sync_skills
99
+ # --------------------------------------------------------------------------
100
+ # Step 3: The rest of synchronization
101
+ # --------------------------------------------------------------------------
102
+ # 3.1. Reconcile plugins (scopes, deterministic sync, lifecycle hooks copy, templates, leaked dir cleanup)
103
+ sync_plugins
87
104
 
88
- # 6. Reconcile Git hooks according to configuration
105
+ # 3.2. Reconcile Git hooks according to configuration
89
106
  case "$GIT_HOOKS_CONFIG" in
90
107
  false|no|0)
91
108
  _cur_hp="$(git -C "$NEXUS_DIR" config --get core.hooksPath 2>/dev/null || true)"
@@ -123,7 +140,7 @@ cmd_sync() {
123
140
  ;;
124
141
  esac
125
142
 
126
- # 7. Reconcile member repos (.rnex/ harness sync)
143
+ # 3.3. Reconcile member repos (.rnex/ harness sync)
127
144
  yaml_list_repos | while read -r _name; do
128
145
  [ -n "$_name" ] || continue
129
146
  if yaml_repo_enabled "$_name"; then
@@ -136,16 +153,9 @@ cmd_sync() {
136
153
  fi
137
154
  done
138
155
 
139
- # 8. Reconcile VS Code / Cursor multi-root workspace if configured
156
+ # 3.4. Reconcile VS Code / Cursor multi-root workspace if configured
140
157
  sync_code_workspace
141
158
 
142
- # 9. Generate auto-sync script and AI session-start hooks
143
- _write_auto_sync_script "$NEXUS_DIR"
144
- _sync_ai_session_start_hooks "$NEXUS_DIR"
145
-
146
- # 10. Update sync stamp
147
- update_sync_stamp "$NEXUS_DIR"
148
-
149
159
  if [ "$_sync_quiet" -eq 0 ]; then
150
160
  log_ok "Sync complete — workspace, plugins, skills, and member .rnex directories reconciled"
151
161
  fi
package/lib/hooks.sh CHANGED
@@ -324,7 +324,13 @@ cmd_hooks() {
324
324
  case "$_hook_name" in
325
325
  post-merge)
326
326
  _cfg_changed=0
327
- if [ ! -f "$NEXUS_DIR/.rnex/.sync_stamp" ] || [ "$(get_config_sum "$NEXUS_DIR")" != "$(cat "$NEXUS_DIR/.rnex/.sync_stamp" 2>/dev/null)" ]; then
327
+ _stamp_file=""
328
+ if [ -f "$NEXUS_DIR/.rnex/sync_stamp" ]; then
329
+ _stamp_file="$NEXUS_DIR/.rnex/sync_stamp"
330
+ elif [ -f "$NEXUS_DIR/.rnex/.sync_stamp" ]; then
331
+ _stamp_file="$NEXUS_DIR/.rnex/.sync_stamp"
332
+ fi
333
+ if [ -z "$_stamp_file" ] || [ "$(get_config_sum "$NEXUS_DIR")" != "$(cat "$_stamp_file" 2>/dev/null)" ]; then
328
334
  _cfg_changed=1
329
335
  elif git -C "$NEXUS_DIR" diff-tree -r --name-only ORIG_HEAD HEAD 2>/dev/null | grep -qE "(^rnex\.yaml$|^\.local\.rnex\.yaml$)"; then
330
336
  _cfg_changed=1
@@ -342,7 +348,13 @@ cmd_hooks() {
342
348
  ;;
343
349
  post-checkout)
344
350
  _cfg_changed=0
345
- if [ ! -f "$NEXUS_DIR/.rnex/.sync_stamp" ] || [ "$(get_config_sum "$NEXUS_DIR")" != "$(cat "$NEXUS_DIR/.rnex/.sync_stamp" 2>/dev/null)" ]; then
351
+ _stamp_file=""
352
+ if [ -f "$NEXUS_DIR/.rnex/sync_stamp" ]; then
353
+ _stamp_file="$NEXUS_DIR/.rnex/sync_stamp"
354
+ elif [ -f "$NEXUS_DIR/.rnex/.sync_stamp" ]; then
355
+ _stamp_file="$NEXUS_DIR/.rnex/.sync_stamp"
356
+ fi
357
+ if [ -z "$_stamp_file" ] || [ "$(get_config_sum "$NEXUS_DIR")" != "$(cat "$_stamp_file" 2>/dev/null)" ]; then
346
358
  _cfg_changed=1
347
359
  elif [ -n "$1" ] && [ -n "$2" ] && git -C "$NEXUS_DIR" diff-tree -r --name-only "$1" "$2" 2>/dev/null | grep -qE "(^rnex\.yaml$|^\.local\.rnex\.yaml$)"; then
348
360
  _cfg_changed=1
@@ -369,7 +381,13 @@ cmd_hooks() {
369
381
  ;;
370
382
  pre-commit)
371
383
  _cfg_changed=0
372
- if [ ! -f "$NEXUS_DIR/.rnex/.sync_stamp" ] || [ "$(get_config_sum "$NEXUS_DIR")" != "$(cat "$NEXUS_DIR/.rnex/.sync_stamp" 2>/dev/null)" ]; then
384
+ _stamp_file=""
385
+ if [ -f "$NEXUS_DIR/.rnex/sync_stamp" ]; then
386
+ _stamp_file="$NEXUS_DIR/.rnex/sync_stamp"
387
+ elif [ -f "$NEXUS_DIR/.rnex/.sync_stamp" ]; then
388
+ _stamp_file="$NEXUS_DIR/.rnex/.sync_stamp"
389
+ fi
390
+ if [ -z "$_stamp_file" ] || [ "$(get_config_sum "$NEXUS_DIR")" != "$(cat "$_stamp_file" 2>/dev/null)" ]; then
373
391
  _cfg_changed=1
374
392
  elif git -C "$NEXUS_DIR" diff --cached --name-only 2>/dev/null | grep -qE "(^rnex\.yaml$|^\.local\.rnex\.yaml$)"; then
375
393
  _cfg_changed=1
package/lib/plugins.sh CHANGED
@@ -8,12 +8,16 @@ find_plugin_dir() {
8
8
  _query="$1"
9
9
  _sdir="$(dirname "$SCRIPT_LOCATION")"
10
10
  for _cand in \
11
+ "${RNEX_ROOT:-}/toolkit/plugins/$_query" \
12
+ "${RNEX_TOOLKIT_DIR:-}/plugins/$_query" \
13
+ "${RNEX_PLUGINS_DIR:-}/$_query" \
11
14
  "$NEXUS_DIR/toolkit/plugins/$_query" \
12
15
  "$SCRIPT_LOCATION/toolkit/plugins/$_query" \
13
16
  "$_sdir/toolkit/plugins/$_query" \
14
17
  "$NEXUS_DIR/plugins/$_query" \
15
18
  "$NEXUS_DIR/.rnex/plugins/$_query" \
16
19
  "$NEXUS_DIR/.nexus/plugins/$_query"; do
20
+ [ -n "$_cand" ] || continue
17
21
  if [ -f "$_cand/plugin.yaml" ]; then
18
22
  printf '%s' "$_cand"
19
23
  return 0
@@ -26,12 +30,16 @@ list_all_available_plugin_dirs() {
26
30
  _sdir="$(dirname "$SCRIPT_LOCATION")"
27
31
  _dirs=""
28
32
  for _parent in \
33
+ "${RNEX_ROOT:-}/toolkit/plugins" \
34
+ "${RNEX_TOOLKIT_DIR:-}/plugins" \
35
+ "${RNEX_PLUGINS_DIR:-}" \
29
36
  "$NEXUS_DIR/toolkit/plugins" \
30
37
  "$SCRIPT_LOCATION/toolkit/plugins" \
31
38
  "$_sdir/toolkit/plugins" \
32
39
  "$NEXUS_DIR/plugins" \
33
40
  "$NEXUS_DIR/.rnex/plugins" \
34
41
  "$NEXUS_DIR/.nexus/plugins"; do
42
+ [ -n "$_parent" ] || continue
35
43
  if [ -d "$_parent" ]; then
36
44
  for _sub in "$_parent"/*; do
37
45
  if [ -d "$_sub" ] && [ -f "$_sub/plugin.yaml" ]; then
@@ -70,6 +78,7 @@ plugin_list_templates() {
70
78
  t && /^[ ]*-[ ]*/ {
71
79
  sub(/^[ ]*-[ ]*/, "");
72
80
  sub(/[ ]*#.*/, "");
81
+ gsub(/["\047]/, "");
73
82
  if (length($0) > 0) print $0
74
83
  }
75
84
  ' "$_pdir/plugin.yaml"
@@ -91,7 +100,7 @@ plugin_list_instructions() {
91
100
 
92
101
  plugin_resolve_placeholders() {
93
102
  _p="$1"; _pd="$2"; _str="$3"
94
- _res="$(printf '%s' "$_str" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's/^["\047]//' -e 's/["\047]$//')"
103
+ _res="$(printf '%s' "$_str" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr -d "'\"")"
95
104
 
96
105
  if [ -f "$_pd/plugin.yaml" ]; then
97
106
  _keys="$(awk '
@@ -114,7 +123,7 @@ plugin_resolve_placeholders() {
114
123
  in_c && $0 ~ ("^[ ]*" k ":") {
115
124
  sub("^[ ]*" k ":[ ]*", "")
116
125
  sub(/[ ]*#.*/, "")
117
- gsub(/^["\047]|["\047]$/, "")
126
+ gsub(/["\047]/, "")
118
127
  print
119
128
  exit
120
129
  }
@@ -122,27 +131,29 @@ plugin_resolve_placeholders() {
122
131
  fi
123
132
  case "$_k" in
124
133
  *_dir|dir)
125
- _v="$(printf '%s' "$_v" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's#^\./##' -e 's#^/##' -e 's#/$##')"
134
+ _v="$(printf '%s' "$_v" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr -d "'\"" | sed -e 's#^\./##' -e 's#^/##' -e 's#/$##')"
126
135
  ;;
127
136
  esac
128
137
  _res="$(printf '%s' "$_res" | sed -e "s|{$_k}|$_v|g")"
129
138
  done
130
139
  fi
131
140
 
132
- # Backward compatibility for legacy template destination paths
141
+ # Fallback resolution for core wiki/raw placeholders and legacy prefixes
133
142
  _w_val="$(yaml_plugin_get "$_p" "wiki_dir" 2>/dev/null || true)"
134
143
  [ -z "$_w_val" ] && _w_val=".rnex/wiki"
135
- _w_val="$(printf '%s' "$_w_val" | sed -e 's#^/##' -e 's#/$##')"
144
+ _w_val="$(printf '%s' "$_w_val" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr -d "'\"" | sed -e 's#^\./##' -e 's#^/##' -e 's#/$##')"
136
145
 
137
146
  _r_val="$(yaml_plugin_get "$_p" "raw_dir" 2>/dev/null || true)"
138
147
  [ -z "$_r_val" ] && _r_val="docs"
139
- _r_val="$(printf '%s' "$_r_val" | sed -e 's#^\./##' -e 's#^/##' -e 's#/$##')"
148
+ _r_val="$(printf '%s' "$_r_val" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr -d "'\"" | sed -e 's#^\./##' -e 's#^/##' -e 's#/$##')"
140
149
 
141
150
  _res="$(printf '%s' "$_res" | sed \
142
- -e "s|^wiki/|${_w_val}/|" \
143
- -e "s|^raw/|${_r_val}/|")"
151
+ -e "s|{wiki_dir}|${_w_val}|g" \
152
+ -e "s|{raw_dir}|${_r_val}|g" \
153
+ -e "s|^\.\{0,1\}\/\{0,1\}wiki/|${_w_val}/|" \
154
+ -e "s|^\.\{0,1\}\/\{0,1\}raw/|${_r_val}/|")"
144
155
 
145
- _res="$(printf '%s' "$_res" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's/^["\047]//' -e 's/["\047]$//')"
156
+ _res="$(printf '%s' "$_res" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr -d "'\"" | sed -e 's#^\./##')"
146
157
 
147
158
  printf '%s' "$_res"
148
159
  }
@@ -152,11 +163,11 @@ plugin_instantiate_template() {
152
163
 
153
164
  _w_val="$(yaml_plugin_get "$_p" "wiki_dir" 2>/dev/null || true)"
154
165
  [ -z "$_w_val" ] && _w_val=".rnex/wiki"
155
- _w_val="$(printf '%s' "$_w_val" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's#^/##' -e 's#/$##')"
166
+ _w_val="$(printf '%s' "$_w_val" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr -d "'\"" | sed -e 's#^/##' -e 's#/$##')"
156
167
 
157
168
  _r_val="$(yaml_plugin_get "$_p" "raw_dir" 2>/dev/null || true)"
158
169
  [ -z "$_r_val" ] && _r_val="docs"
159
- _r_val="$(printf '%s' "$_r_val" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's#^\./##' -e 's#^/##' -e 's#/$##')"
170
+ _r_val="$(printf '%s' "$_r_val" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr -d "'\"" | sed -e 's#^\./##' -e 's#^/##' -e 's#/$##')"
160
171
 
161
172
  sed -e "s|{wiki_dir}|$_w_val|g" \
162
173
  -e "s|{raw_dir}|$_r_val|g" \
@@ -165,6 +176,79 @@ plugin_instantiate_template() {
165
176
 
166
177
  # Sync plugins into scoped directories: .rnex/plugins/<plugin-name>/
167
178
  sync_plugins() {
179
+ # Clean up any bogus placeholder directories accidentally created in workspace root
180
+ for _bogus in \
181
+ "$NEXUS_DIR/\"{wiki_dir}" \
182
+ "$NEXUS_DIR/\"{raw_dir}" \
183
+ "$NEXUS_DIR/{wiki_dir}" \
184
+ "$NEXUS_DIR/{raw_dir}"; do
185
+ if [ -d "$_bogus" ]; then
186
+ rm -rf "$_bogus"
187
+ log_dim "Cleaned up leaked placeholder directory: $(basename "$_bogus")"
188
+ fi
189
+ done
190
+
191
+ # Clean up obsolete leaked root ./raw and ./wiki directories if non-default paths are configured
192
+ _raw_cfg="$(yaml_plugin_get "karpathy-llm" "raw_dir" 2>/dev/null || true)"
193
+ [ -z "$_raw_cfg" ] && _raw_cfg="docs"
194
+ _raw_cfg="$(printf '%s' "$_raw_cfg" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr -d "'\"" | sed -e 's#^\./##' -e 's#^/##' -e 's#/$##')"
195
+
196
+ _wiki_cfg="$(yaml_plugin_get "karpathy-llm" "wiki_dir" 2>/dev/null || true)"
197
+ [ -z "$_wiki_cfg" ] && _wiki_cfg=".rnex/wiki"
198
+ _wiki_cfg="$(printf '%s' "$_wiki_cfg" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr -d "'\"" | sed -e 's#^\./##' -e 's#^/##' -e 's#/$##')"
199
+
200
+ if [ "$_raw_cfg" != "raw" ] && [ -d "$NEXUS_DIR/raw" ]; then
201
+ if ! rmdir "$NEXUS_DIR/raw" 2>/dev/null; then
202
+ _can_clean=1
203
+ for _f in "$NEXUS_DIR/raw"/* "$NEXUS_DIR/raw"/.[!.]* "$NEXUS_DIR/raw"/..?*; do
204
+ [ -e "$_f" ] || continue
205
+ _b="$(basename "$_f")"
206
+ if [ "$_b" = ".gitkeep" ]; then
207
+ continue
208
+ fi
209
+ if [ -f "$NEXUS_DIR/$_raw_cfg/$_b" ] && cmp -s "$_f" "$NEXUS_DIR/$_raw_cfg/$_b"; then
210
+ continue
211
+ fi
212
+ _can_clean=0
213
+ break
214
+ done
215
+ if [ "$_can_clean" -eq 1 ]; then
216
+ rm -rf "$NEXUS_DIR/raw"
217
+ log_dim "Cleaned up obsolete root raw/ directory"
218
+ fi
219
+ else
220
+ log_dim "Removed empty obsolete root raw/ directory"
221
+ fi
222
+ fi
223
+
224
+ if [ "$_wiki_cfg" != "wiki" ] && [ -d "$NEXUS_DIR/wiki" ]; then
225
+ if ! rmdir "$NEXUS_DIR/wiki" 2>/dev/null; then
226
+ _can_clean=1
227
+ for _f in "$NEXUS_DIR/wiki"/* "$NEXUS_DIR/wiki"/.[!.]* "$NEXUS_DIR/wiki"/..?*; do
228
+ [ -e "$_f" ] || continue
229
+ _b="$(basename "$_f")"
230
+ case "$_b" in
231
+ index.md|_log.md|hot.md|.gitkeep)
232
+ continue
233
+ ;;
234
+ *)
235
+ if [ -f "$NEXUS_DIR/$_wiki_cfg/$_b" ] && cmp -s "$_f" "$NEXUS_DIR/$_wiki_cfg/$_b"; then
236
+ continue
237
+ fi
238
+ _can_clean=0
239
+ break
240
+ ;;
241
+ esac
242
+ done
243
+ if [ "$_can_clean" -eq 1 ]; then
244
+ rm -rf "$NEXUS_DIR/wiki"
245
+ log_dim "Cleaned up obsolete root wiki/ directory"
246
+ fi
247
+ else
248
+ log_dim "Removed empty obsolete root wiki/ directory"
249
+ fi
250
+ fi
251
+
168
252
  # 1. Prune plugins that are disabled or no longer enabled in config
169
253
  if [ -d "$NEXUS_DIR/.rnex/plugins" ]; then
170
254
  for _existing in "$NEXUS_DIR/.rnex/plugins"/*; do
@@ -232,11 +316,19 @@ sync_plugins() {
232
316
  [ -n "$_item" ] || continue
233
317
  _s="${_item%%:*}"
234
318
  _d="${_item#*:}"
235
- _s="$(printf '%s' "$_s" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's/^["\047]//' -e 's/["\047]$//')"
236
- _d="$(printf '%s' "$_d" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's/^["\047]//' -e 's/["\047]$//')"
319
+ _s="$(printf '%s' "$_s" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr -d "'\"")"
320
+ _d="$(printf '%s' "$_d" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr -d "'\"")"
237
321
 
238
322
  _d="$(plugin_resolve_placeholders "$_pname" "$_pdir" "$_d")"
239
323
 
324
+ # Defensive guard: never create directories or files if placeholder expansion failed or quotes leaked
325
+ case "$_d" in
326
+ *"{"*"}"*|*\"*|*\'*)
327
+ log_warn "Skipping invalid template destination with unresolved placeholders: $_d"
328
+ continue
329
+ ;;
330
+ esac
331
+
240
332
  _src_path="$_pdir/$_s"
241
333
  _dest_path="$NEXUS_DIR/$_d"
242
334
 
package/lib/workspace.sh CHANGED
@@ -42,11 +42,18 @@ update_sync_stamp() {
42
42
  _dir="${1:-${NEXUS_DIR:-.}}"
43
43
  mkdir -p "$_dir/.rnex"
44
44
  if [ ! -f "$_dir/.rnex/.gitignore" ]; then
45
- printf ".sync_stamp\n" > "$_dir/.rnex/.gitignore"
46
- elif ! grep -q "^\.sync_stamp" "$_dir/.rnex/.gitignore" 2>/dev/null; then
47
- printf ".sync_stamp\n" >> "$_dir/.rnex/.gitignore"
45
+ printf ".sync_stamp\nsync_stamp\n" > "$_dir/.rnex/.gitignore"
46
+ else
47
+ if ! grep -q "^\.sync_stamp" "$_dir/.rnex/.gitignore" 2>/dev/null; then
48
+ printf ".sync_stamp\n" >> "$_dir/.rnex/.gitignore"
49
+ fi
50
+ if ! grep -q "^sync_stamp" "$_dir/.rnex/.gitignore" 2>/dev/null; then
51
+ printf "sync_stamp\n" >> "$_dir/.rnex/.gitignore"
52
+ fi
48
53
  fi
49
- get_config_sum "$_dir" > "$_dir/.rnex/.sync_stamp"
54
+ _csum="$(get_config_sum "$_dir")"
55
+ printf '%s\n' "$_csum" > "$_dir/.rnex/.sync_stamp"
56
+ printf '%s\n' "$_csum" > "$_dir/.rnex/sync_stamp"
50
57
  }
51
58
 
52
59
  check_auto_sync() {
@@ -70,6 +77,7 @@ check_auto_sync() {
70
77
  fi
71
78
  [ -f "$_cfg_file" ] || return 0
72
79
  _stamp="$_ws/.rnex/.sync_stamp"
80
+ [ -f "$_stamp" ] || _stamp="$_ws/.rnex/sync_stamp"
73
81
  if [ ! -f "$_stamp" ] || [ "$(get_config_sum "$_ws")" != "$(cat "$_stamp" 2>/dev/null)" ]; then
74
82
  cmd_sync -y --quiet
75
83
  fi
package/lib/yaml.sh CHANGED
@@ -8,30 +8,48 @@ _yaml_list_plugins_from_file() {
8
8
  _f="$1"
9
9
  [ -f "$_f" ] || return 0
10
10
  awk '
11
- /^plugins:[ ]*$/ || /^plugins:[ ]*#/ { p=1; next }
12
- p && /^[^ #]/ { p=0 }
13
- p && /^ [a-zA-Z0-9_.-]+:/ {
14
- line = $0
15
- sub(/^[ ]*/, "", line)
16
- sub(/:.*/, "", line)
17
- gsub(/[[:space:]]/, "", line)
18
- if (length(line) > 0) print line
11
+ /^[ \t]*plugins:[ \t]*(#.*)?$/ { in_plugins=1; plugin_indent=-1; next }
12
+ in_plugins && /^[^ \t#]/ { in_plugins=0 }
13
+ !in_plugins { next }
14
+ {
15
+ match($0, /^[ \t]*/)
16
+ indent = RLENGTH
17
+ trimmed = substr($0, indent + 1)
19
18
  }
20
- p && /^ -[ ]+[a-zA-Z0-9_.-]+/ {
21
- line = $0
22
- sub(/^[ ]*-[ ]*/, "", line)
23
- sub(/[ ]*#.*/, "", line)
24
- sub(/:.*/, "", line)
25
- gsub(/[[:space:]]/, "", line)
26
- if (length(line) > 0) print line
19
+ trimmed ~ /^([#]|$)/ { next }
20
+
21
+ in_plugins && (plugin_indent == -1) && (indent > 0) {
22
+ plugin_indent = indent
23
+ }
24
+
25
+ in_plugins && (indent == plugin_indent) {
26
+ if (trimmed ~ /^["\047]?[a-zA-Z0-9_.-]+["\047]?:/) {
27
+ line = trimmed
28
+ sub(/:.*/, "", line)
29
+ gsub(/^["\047]|["\047]$/, "", line)
30
+ gsub(/[[:space:]]/, "", line)
31
+ if (length(line) > 0) print line
32
+ } else if (trimmed ~ /^-[ \t]+["\047]?[a-zA-Z0-9_.-]+/) {
33
+ line = trimmed
34
+ sub(/^-[ \t]+/, "", line)
35
+ sub(/[ \t]*#.*/, "", line)
36
+ sub(/:.*/, "", line)
37
+ gsub(/^["\047]|["\047]$/, "", line)
38
+ gsub(/[[:space:]]/, "", line)
39
+ if (length(line) > 0) print line
40
+ }
27
41
  }
28
42
  ' "$_f"
29
43
  }
30
44
 
31
45
  yaml_list_plugins() {
46
+ _wy="${WORKSPACE_YAML:-}"
47
+ [ -z "$_wy" ] && _wy="${NEXUS_DIR:-.}/$RNEX_CONFIG_FILE"
48
+ _wly="${WORKSPACE_LOCAL_YAML:-}"
49
+ [ -z "$_wly" ] && _wly="${NEXUS_DIR:-.}/$RNEX_LOCAL_CONFIG_FILE"
32
50
  {
33
- _yaml_list_plugins_from_file "$WORKSPACE_YAML"
34
- _yaml_list_plugins_from_file "$WORKSPACE_LOCAL_YAML"
51
+ _yaml_list_plugins_from_file "$_wy"
52
+ _yaml_list_plugins_from_file "$_wly"
35
53
  } | awk '!seen[$0]++'
36
54
  }
37
55
 
@@ -39,29 +57,69 @@ _yaml_plugin_get_from_file() {
39
57
  _f="$1"; _pname="$2"; _key="$3"
40
58
  [ -f "$_f" ] || return 0
41
59
  awk -v plugin="$_pname" -v key="$_key" '
42
- /^plugins:[ ]*$/ || /^plugins:[ ]*#/ { in_plugins=1; next }
43
- in_plugins && /^[^ #]/ { in_plugins=0 }
44
- in_plugins && match($0, "^ " plugin ":[ ]*(#.*)?$") { in_target=1; next }
45
- in_target && /^ [^ #]/ { in_target=0 }
46
- in_target && match($0, "^ " key ":[ ]*") {
47
- line = $0
48
- sub("^ " key ":[ ]*", "", line)
49
- sub(/[ ]*#.*$/, "", line)
50
- gsub(/^["\x27]|["\x27]$/, "", line)
51
- print line
52
- exit
60
+ /^[ \t]*plugins:[ \t]*(#.*)?$/ { in_plugins=1; in_target=0; plugin_indent=-1; next }
61
+ in_plugins && /^[^ \t#]/ { in_plugins=0; in_target=0 }
62
+ !in_plugins { next }
63
+ {
64
+ match($0, /^[ \t]*/)
65
+ indent = RLENGTH
66
+ trimmed = substr($0, indent + 1)
67
+ }
68
+ trimmed ~ /^([#]|$)/ { next }
69
+
70
+ in_target && (indent <= plugin_indent) {
71
+ in_target=0
72
+ }
73
+
74
+ !in_target {
75
+ k = trimmed
76
+ sub(/:.*/, "", k)
77
+ gsub(/^["\047]|["\047]$/, "", k)
78
+ gsub(/[[:space:]]/, "", k)
79
+ if (k == plugin && trimmed ~ /:[ \t]*(#.*)?$/) {
80
+ in_target=1
81
+ plugin_indent=indent
82
+ next
83
+ }
84
+ }
85
+
86
+ in_target && (indent > plugin_indent) {
87
+ k = trimmed
88
+ sub(/:.*/, "", k)
89
+ gsub(/^["\047]|["\047]$/, "", k)
90
+ gsub(/[[:space:]]/, "", k)
91
+ if (k == key && trimmed ~ /:[ \t]*/) {
92
+ val = trimmed
93
+ sub(/^[^:]*:[ \t]*/, "", val)
94
+ if (val ~ /^"[^"]*"/) {
95
+ match(val, /^"[^"]*"/)
96
+ val = substr(val, 2, RLENGTH - 2)
97
+ } else if (val ~ /^\047[^\047]*\047/) {
98
+ match(val, /^\047[^\047]*\047/)
99
+ val = substr(val, 2, RLENGTH - 2)
100
+ } else {
101
+ sub(/[ \t]*#.*$/, "", val)
102
+ sub(/[ \t]+$/, "", val)
103
+ }
104
+ print val
105
+ exit
106
+ }
53
107
  }
54
108
  ' "$_f"
55
109
  }
56
110
 
57
111
  yaml_plugin_get() {
58
112
  _pname="$1"; _key="$2"
59
- _val="$(_yaml_plugin_get_from_file "$WORKSPACE_LOCAL_YAML" "$_pname" "$_key")"
113
+ _wy="${WORKSPACE_YAML:-}"
114
+ [ -z "$_wy" ] && _wy="${NEXUS_DIR:-.}/$RNEX_CONFIG_FILE"
115
+ _wly="${WORKSPACE_LOCAL_YAML:-}"
116
+ [ -z "$_wly" ] && _wly="${NEXUS_DIR:-.}/$RNEX_LOCAL_CONFIG_FILE"
117
+ _val="$(_yaml_plugin_get_from_file "$_wly" "$_pname" "$_key")"
60
118
  if [ -n "$_val" ]; then
61
119
  printf '%s' "$_val"
62
120
  return 0
63
121
  fi
64
- _yaml_plugin_get_from_file "$WORKSPACE_YAML" "$_pname" "$_key"
122
+ _yaml_plugin_get_from_file "$_wy" "$_pname" "$_key"
65
123
  }
66
124
 
67
125
  yaml_has_plugin() {
@@ -346,7 +404,7 @@ _yaml_get_from_file() {
346
404
  line = $0
347
405
  sub("^ " field ":[ ]*", "", line)
348
406
  sub(/[ ]*#.*$/, "", line)
349
- gsub(/^["\x27]|["\x27]$/, "", line)
407
+ gsub(/^["\047]|["\047]$/, "", line)
350
408
  print line
351
409
  exit
352
410
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "repo-nexus",
3
- "version": "0.7.19",
3
+ "version": "0.7.22",
4
4
  "description": "Lightweight, zero-dependency Virtual Meta-Repo companion for multi-repo workspaces and shared AI context (no git submodules)",
5
5
  "bin": {
6
6
  "repo-nexus": "rnex",
@@ -12,36 +12,60 @@ _root="$RNEX_ROOT"
12
12
  get_cfg() {
13
13
  _key="$1"; _def="$2"
14
14
  _val=""
15
- if [ -f "$_root/.local.rnex.yaml" ]; then
16
- _val="$(awk -v k="$_key" '
17
- /^plugins:/ { in_p=1; in_k=0; next }
18
- in_p && /^[^ #]/ { in_p=0; in_k=0 }
19
- in_p && match($0, "^[ ]*karpathy-llm:[ ]*(#.*)?$") { in_k=1; next }
20
- in_k && (/^[ ]{1,2}[^ #]/ || /^[^ #]/) { in_k=0 }
21
- in_k && $0 ~ ("^[ ]*" k ":") {
22
- sub("^[ ]*" k ":[ ]*", "")
23
- sub(/[ ]*#.*/, "")
24
- gsub(/["\047]/, "")
25
- print
26
- exit
15
+ for _cfg in "$_root/.local.rnex.yaml" "$_root/rnex.yaml"; do
16
+ [ -f "$_cfg" ] || continue
17
+ _val="$(awk -v plugin="karpathy-llm" -v key="$_key" '
18
+ /^[ \t]*plugins:[ \t]*(#.*)?$/ { in_plugins=1; in_target=0; plugin_indent=-1; next }
19
+ in_plugins && /^[^ \t#]/ { in_plugins=0; in_target=0 }
20
+ !in_plugins { next }
21
+ {
22
+ match($0, /^[ \t]*/)
23
+ indent = RLENGTH
24
+ trimmed = substr($0, indent + 1)
27
25
  }
28
- ' "$_root/.local.rnex.yaml")"
29
- fi
30
- if [ -z "$_val" ] && [ -f "$_root/rnex.yaml" ]; then
31
- _val="$(awk -v k="$_key" '
32
- /^plugins:/ { in_p=1; in_k=0; next }
33
- in_p && /^[^ #]/ { in_p=0; in_k=0 }
34
- in_p && match($0, "^[ ]*karpathy-llm:[ ]*(#.*)?$") { in_k=1; next }
35
- in_k && (/^[ ]{1,2}[^ #]/ || /^[^ #]/) { in_k=0 }
36
- in_k && $0 ~ ("^[ ]*" k ":") {
37
- sub("^[ ]*" k ":[ ]*", "")
38
- sub(/[ ]*#.*/, "")
39
- gsub(/["\047]/, "")
40
- print
41
- exit
26
+ trimmed ~ /^([#]|$)/ { next }
27
+
28
+ in_target && (indent <= plugin_indent) {
29
+ in_target=0
42
30
  }
43
- ' "$_root/rnex.yaml")"
44
- fi
31
+
32
+ !in_target {
33
+ k = trimmed
34
+ sub(/:.*/, "", k)
35
+ gsub(/^["\047]|["\047]$/, "", k)
36
+ gsub(/[[:space:]]/, "", k)
37
+ if (k == plugin && trimmed ~ /:[ \t]*(#.*)?$/) {
38
+ in_target=1
39
+ plugin_indent=indent
40
+ next
41
+ }
42
+ }
43
+
44
+ in_target && (indent > plugin_indent) {
45
+ k = trimmed
46
+ sub(/:.*/, "", k)
47
+ gsub(/^["\047]|["\047]$/, "", k)
48
+ gsub(/[[:space:]]/, "", k)
49
+ if (k == key && trimmed ~ /:[ \t]*/) {
50
+ val = trimmed
51
+ sub(/^[^:]*:[ \t]*/, "", val)
52
+ if (val ~ /^"[^"]*"/) {
53
+ match(val, /^"[^"]*"/)
54
+ val = substr(val, 2, RLENGTH - 2)
55
+ } else if (val ~ /^\047[^\047]*\047/) {
56
+ match(val, /^\047[^\047]*\047/)
57
+ val = substr(val, 2, RLENGTH - 2)
58
+ } else {
59
+ sub(/[ \t]*#.*$/, "", val)
60
+ sub(/[ \t]+$/, "", val)
61
+ }
62
+ print val
63
+ exit
64
+ }
65
+ }
66
+ ' "$_cfg")"
67
+ [ -n "$_val" ] && break
68
+ done
45
69
  [ -n "$_val" ] && printf '%s' "$_val" || printf '%s' "$_def"
46
70
  }
47
71
 
@@ -59,6 +83,53 @@ _raw_path="$_root/$_raw"
59
83
  mkdir -p "$_wiki_path" "$_raw_path"
60
84
  [ -f "$_raw_path/.gitkeep" ] || touch "$_raw_path/.gitkeep"
61
85
 
86
+ # Clean up obsolete leaked root ./raw and ./wiki directories if non-default paths are configured
87
+ if [ "$_raw" != "raw" ] && [ -d "$_root/raw" ]; then
88
+ if ! rmdir "$_root/raw" 2>/dev/null; then
89
+ _clean_raw_leak=1
90
+ for _rf in "$_root/raw"/* "$_root/raw"/.[!.]* "$_root/raw"/..?*; do
91
+ [ -e "$_rf" ] || continue
92
+ _rf_base="$(basename "$_rf")"
93
+ if [ "$_rf_base" = ".gitkeep" ]; then
94
+ continue
95
+ fi
96
+ if [ -f "$_raw_path/$_rf_base" ] && cmp -s "$_rf" "$_raw_path/$_rf_base"; then
97
+ continue
98
+ fi
99
+ _clean_raw_leak=0
100
+ break
101
+ done
102
+ if [ "$_clean_raw_leak" -eq 1 ]; then
103
+ rm -rf "$_root/raw" 2>/dev/null || true
104
+ fi
105
+ fi
106
+ fi
107
+
108
+ if [ "$_wiki" != "wiki" ] && [ -d "$_root/wiki" ]; then
109
+ if ! rmdir "$_root/wiki" 2>/dev/null; then
110
+ _clean_wiki_leak=1
111
+ for _wf in "$_root/wiki"/* "$_root/wiki"/.[!.]* "$_root/wiki"/..?*; do
112
+ [ -e "$_wf" ] || continue
113
+ _wf_base="$(basename "$_wf")"
114
+ case "$_wf_base" in
115
+ index.md|_log.md|hot.md|.gitkeep)
116
+ continue
117
+ ;;
118
+ *)
119
+ if [ -f "$_wiki_path/$_wf_base" ] && cmp -s "$_wf" "$_wiki_path/$_wf_base"; then
120
+ continue
121
+ fi
122
+ _clean_wiki_leak=0
123
+ break
124
+ ;;
125
+ esac
126
+ done
127
+ if [ "$_clean_wiki_leak" -eq 1 ]; then
128
+ rm -rf "$_root/wiki" 2>/dev/null || true
129
+ fi
130
+ fi
131
+ fi
132
+
62
133
  # Clean up legacy staging directory only if empty or positively verified as managed duplicate copies
63
134
  if [ -d "$_wiki_path/raw" ]; then
64
135
  if ! rmdir "$_wiki_path/raw" 2>/dev/null; then
@@ -369,7 +440,7 @@ if [ "$_skip_all_readmes" -ne 1 ]; then
369
440
  line = $0
370
441
  sub("^ enabled:[ ]*", "", line)
371
442
  sub(/[ ]*#.*$/, "", line)
372
- gsub(/^["\x27]|["\x27]$/, "", line)
443
+ gsub(/^["\047]|["\047]$/, "", line)
373
444
  print line
374
445
  exit
375
446
  }
@@ -390,7 +461,7 @@ if [ "$_skip_all_readmes" -ne 1 ]; then
390
461
  line = $0
391
462
  sub("^ ingest_member_readmes:[ ]*", "", line)
392
463
  sub(/[ ]*#.*$/, "", line)
393
- gsub(/^["\x27]|["\x27]$/, "", line)
464
+ gsub(/^["\047]|["\047]$/, "", line)
394
465
  print line
395
466
  exit
396
467
  }
@@ -412,7 +483,7 @@ if [ "$_skip_all_readmes" -ne 1 ]; then
412
483
  line = $0
413
484
  sub("^ path:[ ]*", "", line)
414
485
  sub(/[ ]*#.*$/, "", line)
415
- gsub(/^["\x27]|["\x27]$/, "")
486
+ gsub(/^["\047]|["\047]$/, "", line)
416
487
  print line
417
488
  exit
418
489
  }
@@ -4,36 +4,60 @@ _root="${RNEX_ROOT:-$PWD}"
4
4
  get_cfg() {
5
5
  _key="$1"; _def="$2"
6
6
  _val=""
7
- if [ -f "$_root/.local.rnex.yaml" ]; then
8
- _val="$(awk -v k="$_key" '
9
- /^plugins:/ { in_p=1; in_k=0; next }
10
- in_p && /^[^ #]/ { in_p=0; in_k=0 }
11
- in_p && match($0, "^[ ]*karpathy-llm:[ ]*(#.*)?$") { in_k=1; next }
12
- in_k && (/^[ ]{1,2}[^ #]/ || /^[^ #]/) { in_k=0 }
13
- in_k && $0 ~ ("^[ ]*" k ":") {
14
- sub("^[ ]*" k ":[ ]*", "")
15
- sub(/[ ]*#.*/, "")
16
- gsub(/["\047]/, "")
17
- print
18
- exit
7
+ for _cfg in "$_root/.local.rnex.yaml" "$_root/rnex.yaml"; do
8
+ [ -f "$_cfg" ] || continue
9
+ _val="$(awk -v plugin="karpathy-llm" -v key="$_key" '
10
+ /^[ \t]*plugins:[ \t]*(#.*)?$/ { in_plugins=1; in_target=0; plugin_indent=-1; next }
11
+ in_plugins && /^[^ \t#]/ { in_plugins=0; in_target=0 }
12
+ !in_plugins { next }
13
+ {
14
+ match($0, /^[ \t]*/)
15
+ indent = RLENGTH
16
+ trimmed = substr($0, indent + 1)
19
17
  }
20
- ' "$_root/.local.rnex.yaml")"
21
- fi
22
- if [ -z "$_val" ] && [ -f "$_root/rnex.yaml" ]; then
23
- _val="$(awk -v k="$_key" '
24
- /^plugins:/ { in_p=1; in_k=0; next }
25
- in_p && /^[^ #]/ { in_p=0; in_k=0 }
26
- in_p && match($0, "^[ ]*karpathy-llm:[ ]*(#.*)?$") { in_k=1; next }
27
- in_k && (/^[ ]{1,2}[^ #]/ || /^[^ #]/) { in_k=0 }
28
- in_k && $0 ~ ("^[ ]*" k ":") {
29
- sub("^[ ]*" k ":[ ]*", "")
30
- sub(/[ ]*#.*/, "")
31
- gsub(/["\047]/, "")
32
- print
33
- exit
18
+ trimmed ~ /^([#]|$)/ { next }
19
+
20
+ in_target && (indent <= plugin_indent) {
21
+ in_target=0
34
22
  }
35
- ' "$_root/rnex.yaml")"
36
- fi
23
+
24
+ !in_target {
25
+ k = trimmed
26
+ sub(/:.*/, "", k)
27
+ gsub(/^["\047]|["\047]$/, "", k)
28
+ gsub(/[[:space:]]/, "", k)
29
+ if (k == plugin && trimmed ~ /:[ \t]*(#.*)?$/) {
30
+ in_target=1
31
+ plugin_indent=indent
32
+ next
33
+ }
34
+ }
35
+
36
+ in_target && (indent > plugin_indent) {
37
+ k = trimmed
38
+ sub(/:.*/, "", k)
39
+ gsub(/^["\047]|["\047]$/, "", k)
40
+ gsub(/[[:space:]]/, "", k)
41
+ if (k == key && trimmed ~ /:[ \t]*/) {
42
+ val = trimmed
43
+ sub(/^[^:]*:[ \t]*/, "", val)
44
+ if (val ~ /^"[^"]*"/) {
45
+ match(val, /^"[^"]*"/)
46
+ val = substr(val, 2, RLENGTH - 2)
47
+ } else if (val ~ /^\047[^\047]*\047/) {
48
+ match(val, /^\047[^\047]*\047/)
49
+ val = substr(val, 2, RLENGTH - 2)
50
+ } else {
51
+ sub(/[ \t]*#.*$/, "", val)
52
+ sub(/[ \t]+$/, "", val)
53
+ }
54
+ print val
55
+ exit
56
+ }
57
+ }
58
+ ' "$_cfg")"
59
+ [ -n "$_val" ] && break
60
+ done
37
61
  [ -n "$_val" ] && printf '%s' "$_val" || printf '%s' "$_def"
38
62
  }
39
63
 
@@ -4,36 +4,60 @@ _root="${RNEX_ROOT:-$PWD}"
4
4
  get_cfg() {
5
5
  _key="$1"; _def="$2"
6
6
  _val=""
7
- if [ -f "$_root/.local.rnex.yaml" ]; then
8
- _val="$(awk -v k="$_key" '
9
- /^plugins:/ { in_p=1; in_k=0; next }
10
- in_p && /^[^ #]/ { in_p=0; in_k=0 }
11
- in_p && match($0, "^[ ]*karpathy-llm:[ ]*(#.*)?$") { in_k=1; next }
12
- in_k && (/^[ ]{1,2}[^ #]/ || /^[^ #]/) { in_k=0 }
13
- in_k && $0 ~ ("^[ ]*" k ":") {
14
- sub("^[ ]*" k ":[ ]*", "")
15
- sub(/[ ]*#.*/, "")
16
- gsub(/["\047]/, "")
17
- print
18
- exit
7
+ for _cfg in "$_root/.local.rnex.yaml" "$_root/rnex.yaml"; do
8
+ [ -f "$_cfg" ] || continue
9
+ _val="$(awk -v plugin="karpathy-llm" -v key="$_key" '
10
+ /^[ \t]*plugins:[ \t]*(#.*)?$/ { in_plugins=1; in_target=0; plugin_indent=-1; next }
11
+ in_plugins && /^[^ \t#]/ { in_plugins=0; in_target=0 }
12
+ !in_plugins { next }
13
+ {
14
+ match($0, /^[ \t]*/)
15
+ indent = RLENGTH
16
+ trimmed = substr($0, indent + 1)
19
17
  }
20
- ' "$_root/.local.rnex.yaml")"
21
- fi
22
- if [ -z "$_val" ] && [ -f "$_root/rnex.yaml" ]; then
23
- _val="$(awk -v k="$_key" '
24
- /^plugins:/ { in_p=1; in_k=0; next }
25
- in_p && /^[^ #]/ { in_p=0; in_k=0 }
26
- in_p && match($0, "^[ ]*karpathy-llm:[ ]*(#.*)?$") { in_k=1; next }
27
- in_k && (/^[ ]{1,2}[^ #]/ || /^[^ #]/) { in_k=0 }
28
- in_k && $0 ~ ("^[ ]*" k ":") {
29
- sub("^[ ]*" k ":[ ]*", "")
30
- sub(/[ ]*#.*/, "")
31
- gsub(/["\047]/, "")
32
- print
33
- exit
18
+ trimmed ~ /^([#]|$)/ { next }
19
+
20
+ in_target && (indent <= plugin_indent) {
21
+ in_target=0
34
22
  }
35
- ' "$_root/rnex.yaml")"
36
- fi
23
+
24
+ !in_target {
25
+ k = trimmed
26
+ sub(/:.*/, "", k)
27
+ gsub(/^["\047]|["\047]$/, "", k)
28
+ gsub(/[[:space:]]/, "", k)
29
+ if (k == plugin && trimmed ~ /:[ \t]*(#.*)?$/) {
30
+ in_target=1
31
+ plugin_indent=indent
32
+ next
33
+ }
34
+ }
35
+
36
+ in_target && (indent > plugin_indent) {
37
+ k = trimmed
38
+ sub(/:.*/, "", k)
39
+ gsub(/^["\047]|["\047]$/, "", k)
40
+ gsub(/[[:space:]]/, "", k)
41
+ if (k == key && trimmed ~ /:[ \t]*/) {
42
+ val = trimmed
43
+ sub(/^[^:]*:[ \t]*/, "", val)
44
+ if (val ~ /^"[^"]*"/) {
45
+ match(val, /^"[^"]*"/)
46
+ val = substr(val, 2, RLENGTH - 2)
47
+ } else if (val ~ /^\047[^\047]*\047/) {
48
+ match(val, /^\047[^\047]*\047/)
49
+ val = substr(val, 2, RLENGTH - 2)
50
+ } else {
51
+ sub(/[ \t]*#.*$/, "", val)
52
+ sub(/[ \t]+$/, "", val)
53
+ }
54
+ print val
55
+ exit
56
+ }
57
+ }
58
+ ' "$_cfg")"
59
+ [ -n "$_val" ] && break
60
+ done
37
61
  [ -n "$_val" ] && printf '%s' "$_val" || printf '%s' "$_def"
38
62
  }
39
63
 
@@ -4,36 +4,60 @@ _root="${RNEX_ROOT:-$PWD}"
4
4
  get_cfg() {
5
5
  _key="$1"; _def="$2"
6
6
  _val=""
7
- if [ -f "$_root/.local.rnex.yaml" ]; then
8
- _val="$(awk -v k="$_key" '
9
- /^plugins:/ { in_p=1; in_k=0; next }
10
- in_p && /^[^ #]/ { in_p=0; in_k=0 }
11
- in_p && match($0, "^[ ]*karpathy-llm:[ ]*(#.*)?$") { in_k=1; next }
12
- in_k && (/^[ ]{1,2}[^ #]/ || /^[^ #]/) { in_k=0 }
13
- in_k && $0 ~ ("^[ ]*" k ":") {
14
- sub("^[ ]*" k ":[ ]*", "")
15
- sub(/[ ]*#.*/, "")
16
- gsub(/["\047]/, "")
17
- print
18
- exit
7
+ for _cfg in "$_root/.local.rnex.yaml" "$_root/rnex.yaml"; do
8
+ [ -f "$_cfg" ] || continue
9
+ _val="$(awk -v plugin="karpathy-llm" -v key="$_key" '
10
+ /^[ \t]*plugins:[ \t]*(#.*)?$/ { in_plugins=1; in_target=0; plugin_indent=-1; next }
11
+ in_plugins && /^[^ \t#]/ { in_plugins=0; in_target=0 }
12
+ !in_plugins { next }
13
+ {
14
+ match($0, /^[ \t]*/)
15
+ indent = RLENGTH
16
+ trimmed = substr($0, indent + 1)
19
17
  }
20
- ' "$_root/.local.rnex.yaml")"
21
- fi
22
- if [ -z "$_val" ] && [ -f "$_root/rnex.yaml" ]; then
23
- _val="$(awk -v k="$_key" '
24
- /^plugins:/ { in_p=1; in_k=0; next }
25
- in_p && /^[^ #]/ { in_p=0; in_k=0 }
26
- in_p && match($0, "^[ ]*karpathy-llm:[ ]*(#.*)?$") { in_k=1; next }
27
- in_k && (/^[ ]{1,2}[^ #]/ || /^[^ #]/) { in_k=0 }
28
- in_k && $0 ~ ("^[ ]*" k ":") {
29
- sub("^[ ]*" k ":[ ]*", "")
30
- sub(/[ ]*#.*/, "")
31
- gsub(/["\047]/, "")
32
- print
33
- exit
18
+ trimmed ~ /^([#]|$)/ { next }
19
+
20
+ in_target && (indent <= plugin_indent) {
21
+ in_target=0
34
22
  }
35
- ' "$_root/rnex.yaml")"
36
- fi
23
+
24
+ !in_target {
25
+ k = trimmed
26
+ sub(/:.*/, "", k)
27
+ gsub(/^["\047]|["\047]$/, "", k)
28
+ gsub(/[[:space:]]/, "", k)
29
+ if (k == plugin && trimmed ~ /:[ \t]*(#.*)?$/) {
30
+ in_target=1
31
+ plugin_indent=indent
32
+ next
33
+ }
34
+ }
35
+
36
+ in_target && (indent > plugin_indent) {
37
+ k = trimmed
38
+ sub(/:.*/, "", k)
39
+ gsub(/^["\047]|["\047]$/, "", k)
40
+ gsub(/[[:space:]]/, "", k)
41
+ if (k == key && trimmed ~ /:[ \t]*/) {
42
+ val = trimmed
43
+ sub(/^[^:]*:[ \t]*/, "", val)
44
+ if (val ~ /^"[^"]*"/) {
45
+ match(val, /^"[^"]*"/)
46
+ val = substr(val, 2, RLENGTH - 2)
47
+ } else if (val ~ /^\047[^\047]*\047/) {
48
+ match(val, /^\047[^\047]*\047/)
49
+ val = substr(val, 2, RLENGTH - 2)
50
+ } else {
51
+ sub(/[ \t]*#.*$/, "", val)
52
+ sub(/[ \t]+$/, "", val)
53
+ }
54
+ print val
55
+ exit
56
+ }
57
+ }
58
+ ' "$_cfg")"
59
+ [ -n "$_val" ] && break
60
+ done
37
61
  [ -n "$_val" ] && printf '%s' "$_val" || printf '%s' "$_def"
38
62
  }
39
63
 
@@ -4,36 +4,60 @@ _root="${RNEX_ROOT:-$PWD}"
4
4
  get_cfg() {
5
5
  _key="$1"; _def="$2"
6
6
  _val=""
7
- if [ -f "$_root/.local.rnex.yaml" ]; then
8
- _val="$(awk -v k="$_key" '
9
- /^plugins:/ { in_p=1; in_k=0; next }
10
- in_p && /^[^ #]/ { in_p=0; in_k=0 }
11
- in_p && match($0, "^[ ]*karpathy-llm:[ ]*(#.*)?$") { in_k=1; next }
12
- in_k && (/^[ ]{1,2}[^ #]/ || /^[^ #]/) { in_k=0 }
13
- in_k && $0 ~ ("^[ ]*" k ":") {
14
- sub("^[ ]*" k ":[ ]*", "")
15
- sub(/[ ]*#.*/, "")
16
- gsub(/["\047]/, "")
17
- print
18
- exit
7
+ for _cfg in "$_root/.local.rnex.yaml" "$_root/rnex.yaml"; do
8
+ [ -f "$_cfg" ] || continue
9
+ _val="$(awk -v plugin="karpathy-llm" -v key="$_key" '
10
+ /^[ \t]*plugins:[ \t]*(#.*)?$/ { in_plugins=1; in_target=0; plugin_indent=-1; next }
11
+ in_plugins && /^[^ \t#]/ { in_plugins=0; in_target=0 }
12
+ !in_plugins { next }
13
+ {
14
+ match($0, /^[ \t]*/)
15
+ indent = RLENGTH
16
+ trimmed = substr($0, indent + 1)
19
17
  }
20
- ' "$_root/.local.rnex.yaml")"
21
- fi
22
- if [ -z "$_val" ] && [ -f "$_root/rnex.yaml" ]; then
23
- _val="$(awk -v k="$_key" '
24
- /^plugins:/ { in_p=1; in_k=0; next }
25
- in_p && /^[^ #]/ { in_p=0; in_k=0 }
26
- in_p && match($0, "^[ ]*karpathy-llm:[ ]*(#.*)?$") { in_k=1; next }
27
- in_k && (/^[ ]{1,2}[^ #]/ || /^[^ #]/) { in_k=0 }
28
- in_k && $0 ~ ("^[ ]*" k ":") {
29
- sub("^[ ]*" k ":[ ]*", "")
30
- sub(/[ ]*#.*/, "")
31
- gsub(/["\047]/, "")
32
- print
33
- exit
18
+ trimmed ~ /^([#]|$)/ { next }
19
+
20
+ in_target && (indent <= plugin_indent) {
21
+ in_target=0
34
22
  }
35
- ' "$_root/rnex.yaml")"
36
- fi
23
+
24
+ !in_target {
25
+ k = trimmed
26
+ sub(/:.*/, "", k)
27
+ gsub(/^["\047]|["\047]$/, "", k)
28
+ gsub(/[[:space:]]/, "", k)
29
+ if (k == plugin && trimmed ~ /:[ \t]*(#.*)?$/) {
30
+ in_target=1
31
+ plugin_indent=indent
32
+ next
33
+ }
34
+ }
35
+
36
+ in_target && (indent > plugin_indent) {
37
+ k = trimmed
38
+ sub(/:.*/, "", k)
39
+ gsub(/^["\047]|["\047]$/, "", k)
40
+ gsub(/[[:space:]]/, "", k)
41
+ if (k == key && trimmed ~ /:[ \t]*/) {
42
+ val = trimmed
43
+ sub(/^[^:]*:[ \t]*/, "", val)
44
+ if (val ~ /^"[^"]*"/) {
45
+ match(val, /^"[^"]*"/)
46
+ val = substr(val, 2, RLENGTH - 2)
47
+ } else if (val ~ /^\047[^\047]*\047/) {
48
+ match(val, /^\047[^\047]*\047/)
49
+ val = substr(val, 2, RLENGTH - 2)
50
+ } else {
51
+ sub(/[ \t]*#.*$/, "", val)
52
+ sub(/[ \t]+$/, "", val)
53
+ }
54
+ print val
55
+ exit
56
+ }
57
+ }
58
+ ' "$_cfg")"
59
+ [ -n "$_val" ] && break
60
+ done
37
61
  [ -n "$_val" ] && printf '%s' "$_val" || printf '%s' "$_def"
38
62
  }
39
63