repo-nexus 0.7.24 → 0.7.26

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 (38) hide show
  1. package/docs/examples/monorepo-coexistence.md +0 -1
  2. package/docs/examples/multi-repo-workspace.md +0 -2
  3. package/docs/guide/configuration.md +2 -3
  4. package/docs/plugins/claude.md +5 -5
  5. package/docs/plugins/copilot.md +1 -2
  6. package/docs/plugins/cursor.md +2 -4
  7. package/docs/plugins/gemini.md +4 -4
  8. package/docs/plugins/index.md +2 -2
  9. package/docs/plugins/windsurf.md +2 -4
  10. package/docs/rnex.example.yaml +7 -9
  11. package/lib/ai.sh +90 -0
  12. package/lib/commands/status.sh +14 -4
  13. package/lib/yaml.sh +20 -5
  14. package/package.json +1 -1
  15. package/templates/rnex-env.sh +169 -8
  16. package/templates/rnex.example.yaml +7 -9
  17. package/toolkit/plugins/claude/README.md +2 -2
  18. package/toolkit/plugins/claude/hooks/after_sync.sh +32 -32
  19. package/toolkit/plugins/claude/hooks/before_plugin_disable.sh +1 -0
  20. package/toolkit/plugins/claude/instructions/rnex-claude-integration.md +1 -1
  21. package/toolkit/plugins/claude/plugin.yaml +2 -2
  22. package/toolkit/plugins/copilot/README.md +0 -2
  23. package/toolkit/plugins/copilot/hooks/after_sync.sh +3 -10
  24. package/toolkit/plugins/copilot/instructions/rnex-copilot-integration.md +0 -1
  25. package/toolkit/plugins/copilot/plugin.yaml +0 -2
  26. package/toolkit/plugins/cursor/README.md +0 -2
  27. package/toolkit/plugins/cursor/hooks/after_sync.sh +12 -17
  28. package/toolkit/plugins/cursor/instructions/rnex-cursor-integration.md +0 -1
  29. package/toolkit/plugins/cursor/plugin.yaml +0 -2
  30. package/toolkit/plugins/gemini/README.md +2 -2
  31. package/toolkit/plugins/gemini/hooks/after_sync.sh +43 -6
  32. package/toolkit/plugins/gemini/hooks/before_plugin_disable.sh +1 -0
  33. package/toolkit/plugins/gemini/instructions/rnex-gemini-integration.md +1 -1
  34. package/toolkit/plugins/gemini/plugin.yaml +2 -2
  35. package/toolkit/plugins/windsurf/README.md +0 -2
  36. package/toolkit/plugins/windsurf/hooks/after_sync.sh +2 -6
  37. package/toolkit/plugins/windsurf/instructions/rnex-windsurf-integration.md +0 -1
  38. package/toolkit/plugins/windsurf/plugin.yaml +0 -2
@@ -52,7 +52,6 @@ repos:
52
52
 
53
53
  plugins:
54
54
  claude:
55
- instructions: true
56
55
  skills: true
57
56
  ```
58
57
 
@@ -50,10 +50,8 @@ repos:
50
50
 
51
51
  plugins:
52
52
  claude:
53
- instructions: true
54
53
  skills: true
55
54
  cursor:
56
- instructions: true
57
55
  skills: true
58
56
  ```
59
57
 
@@ -64,11 +64,10 @@ repos:
64
64
  plugins:
65
65
  # AI Provider Plugins
66
66
  claude:
67
- instructions: true
68
67
  skills: true
68
+ auto_sync_on: SessionStart
69
69
 
70
70
  cursor:
71
- instructions: true
72
71
  skills: true
73
72
 
74
73
  # Knowledge & Agent Protocol Plugins
@@ -116,7 +115,7 @@ repos:
116
115
 
117
116
  plugins:
118
117
  gemini:
119
- instructions: true
118
+ skills: true
120
119
  ```
121
120
 
122
121
  After modifying configuration files directly, reconcile the workspace state:
@@ -21,8 +21,8 @@ Operational skills, rules, and subagents remain cleanly encapsulated within `.rn
21
21
 
22
22
  2. **Native Instruction Support via `CLAUDE.md` & `AGENTS.md`**:
23
23
  - Claude Code natively reads `CLAUDE.md` as its primary instructions file; it only falls back to `AGENTS.md` when no `CLAUDE.md` exists in the project.
24
- - When enabled (`instructions: true`), the Claude plugin synchronizes Repo Nexus routing instructions to `CLAUDE.md` (or merges them cleanly if you already have custom instructions).
25
- - If `CLAUDE.md` is absent and `instructions: false`, Claude Code falls back to reading `AGENTS.md` directly.
24
+ - When enabled, the Claude plugin automatically synchronizes Repo Nexus routing instructions to `CLAUDE.md` (or merges them cleanly if you already have custom instructions).
25
+ - If the plugin is disabled, the routing block is removed, allowing Claude Code to read `AGENTS.md` directly.
26
26
 
27
27
  3. **Subagent & Skill Execution**:
28
28
  - Core skills reside under `.rnex/skills/`.
@@ -58,15 +58,15 @@ Configure options under `plugins.claude` in `rnex.yaml` or `.local.rnex.yaml`:
58
58
  ```yaml
59
59
  plugins:
60
60
  claude:
61
- instructions: true # Sync routing instructions to CLAUDE.md (default: true)
62
61
  skills: true # Generate user skills in .claude/skills/ (default: true)
62
+ auto_sync_on: SessionStart # Trigger auto-sync on lifecycle event (default: SessionStart, or false)
63
63
  enabled: true # Set to false to disable
64
64
  ```
65
65
 
66
66
  | Option | Type | Default | Description |
67
67
  |:---|:---|:---|:---|
68
- | `instructions` | boolean | `true` | Merge routing instructions into `CLAUDE.md`. |
69
68
  | `skills` | boolean | `true` | Generate user skill pointers in `.claude/skills/rnex-*.md`. |
69
+ | `auto_sync_on` | string/boolean | `SessionStart` | Lifecycle event triggering auto-sync in `.claude/settings.json` (or `false` to disable). |
70
70
  | `enabled` | boolean | `true` | Enable or disable the plugin. Overridable in `.local.rnex.yaml`. |
71
71
 
72
72
  ---
@@ -78,7 +78,7 @@ When `claude` is enabled with functional plugins like `karpathy-llm`, it generat
78
78
  ```text
79
79
  my-workspace/
80
80
  ├── AGENTS.md # Universal workspace instructions & routing
81
- ├── CLAUDE.md # Claude-specific instructions (if instructions: true)
81
+ ├── CLAUDE.md # Claude-specific instructions
82
82
  ├── .claude/
83
83
  │ └── skills/ # Zero-logic User Skill pointers
84
84
  │ ├── rnex-clone-sync.md
@@ -11,7 +11,7 @@ The `copilot` plugin integrates GitHub Copilot with Repo Nexus by projecting wor
11
11
 
12
12
  GitHub Copilot operates natively within VS Code, Visual Studio, JetBrains, and GitHub.com:
13
13
  - **Universal Routing (`AGENTS.md`)**: GitHub Copilot natively reads `AGENTS.md` at the workspace root.
14
- - **Custom Instructions (`.github/copilot-instructions.md`)**: When `instructions: true`, Repo Nexus injects its non-destructive routing block inside `<!-- REPO-NEXUS:START -->` and `<!-- REPO-NEXUS:END -->`. Custom developer rules outside these markers are strictly preserved.
14
+ - **Custom Instructions (`.github/copilot-instructions.md`)**: When enabled, Repo Nexus injects its non-destructive routing block inside `<!-- REPO-NEXUS:START -->` and `<!-- REPO-NEXUS:END -->`. Custom developer rules outside these markers are strictly preserved.
15
15
  - **User Skills (`.github/skills/`)**: When `skills: true`, Repo Nexus generates native `SKILL.md` directory bundles (`.github/skills/rnex-<name>/SKILL.md`) with YAML frontmatter, making them automatically discoverable in VS Code and Copilot Chat skill-pickers while redirecting to the underlying agentic skills under `.rnex/skills/` and active plugins.
16
16
 
17
17
  ## Configuration
@@ -21,7 +21,6 @@ Enable in `rnex.yaml`:
21
21
  ```yaml
22
22
  plugins:
23
23
  copilot:
24
- instructions: true # Maintain routing in .github/copilot-instructions.md
25
24
  skills: true # Generate user skills in .github/skills/
26
25
  ```
27
26
 
@@ -20,7 +20,7 @@ Operational skills, rules, and subagents remain cleanly encapsulated within `.rn
20
20
  - Contains zero inline heuristics—redirects Cursor directly to the underlying agentic skill protocols inside `.rnex/`.
21
21
 
22
22
  2. **Native Instructions & Rules Support**:
23
- - Synchronizes Repo Nexus routing instructions to `.cursorrules` when `instructions: true` (default).
23
+ - Automatically synchronizes Repo Nexus routing instructions to `.cursorrules` and `.cursor/rules/rnex-context.mdc`.
24
24
  - Preserves user custom rules and custom sections in `.cursorrules`.
25
25
 
26
26
  3. **Subagent & Skill Execution**:
@@ -57,14 +57,12 @@ Configure options under `plugins.cursor` in `rnex.yaml` or `.local.rnex.yaml`:
57
57
  ```yaml
58
58
  plugins:
59
59
  cursor:
60
- instructions: true # Sync routing instructions to .cursorrules (default: true)
61
60
  skills: true # Generate user skills in .cursor/rules/ (default: true)
62
61
  enabled: true # Set to false to disable
63
62
  ```
64
63
 
65
64
  | Option | Type | Default | Description |
66
65
  |:---|:---|:---|:---|
67
- | `instructions` | boolean | `true` | Merge routing instructions into `.cursorrules`. |
68
66
  | `skills` | boolean | `true` | Generate user skill pointers in `.cursor/rules/rnex-*.md`. |
69
67
  | `enabled` | boolean | `true` | Enable or disable the plugin. Overridable in `.local.rnex.yaml`. |
70
68
 
@@ -77,7 +75,7 @@ When `cursor` is enabled with functional plugins like `karpathy-llm`, it generat
77
75
  ```text
78
76
  my-workspace/
79
77
  ├── AGENTS.md # Universal workspace instructions & routing
80
- ├── .cursorrules # Cursor root instructions (if instructions: true)
78
+ ├── .cursorrules # Cursor root instructions
81
79
  ├── .cursor/
82
80
  │ └── rules/ # Zero-logic User Skill pointers
83
81
  │ ├── rnex-clone-sync.md
@@ -20,7 +20,7 @@ Operational skills, rules, and subagents remain cleanly encapsulated within `.rn
20
20
  - Contains zero inline heuristics—redirects Gemini/Antigravity directly to the underlying agentic skill protocols inside `.rnex/`.
21
21
 
22
22
  2. **Native Instructions Support via `GEMINI.md`**:
23
- - Synchronizes Repo Nexus routing instructions to `GEMINI.md` (when `instructions: true`, default) for native support by the Google Gemini CLI.
23
+ - Automatically synchronizes Repo Nexus routing instructions to `GEMINI.md` for native support by the Google Gemini CLI and Antigravity.
24
24
  - Preserves user-defined custom sections in `GEMINI.md` across updates.
25
25
 
26
26
  3. **Subagent & Skill Execution**:
@@ -57,15 +57,15 @@ Configure options under `plugins.gemini` in `rnex.yaml` or `.local.rnex.yaml`:
57
57
  ```yaml
58
58
  plugins:
59
59
  gemini:
60
- instructions: true # Sync routing instructions to GEMINI.md (default: true)
61
60
  skills: true # Generate user skills in .agents/skills/ (default: true)
61
+ auto_sync_on: SessionStart # Trigger auto-sync on lifecycle event (default: SessionStart, or false)
62
62
  enabled: true # Set to false to disable
63
63
  ```
64
64
 
65
65
  | Option | Type | Default | Description |
66
66
  |:---|:---|:---|:---|
67
- | `instructions` | boolean | `true` | Merge routing instructions into `GEMINI.md`. |
68
67
  | `skills` | boolean | `true` | Generate user skill pointers in `.agents/skills/rnex-*/SKILL.md`. |
68
+ | `auto_sync_on` | string/boolean | `SessionStart` | Lifecycle event triggering auto-sync in `.agents/hooks.json` (or `false` to disable). |
69
69
  | `enabled` | boolean | `true` | Enable or disable the plugin. Overridable in `.local.rnex.yaml`. |
70
70
 
71
71
  ---
@@ -76,7 +76,7 @@ When `gemini` is enabled with functional plugins like `karpathy-llm`, it generat
76
76
 
77
77
  ```text
78
78
  my-workspace/
79
- ├── GEMINI.md # Gemini-specific instructions (if instructions: true)
79
+ ├── GEMINI.md # Gemini-specific instructions
80
80
  ├── .agents/
81
81
  │ └── skills/ # Zero-logic User Skill pointers
82
82
  │ ├── rnex-clone-sync/
@@ -97,12 +97,12 @@ repos_dir: ./repos
97
97
  plugins:
98
98
  # AI Provider Plugins
99
99
  claude:
100
- instructions: true
101
100
  skills: true
101
+ auto_sync_on: SessionStart
102
102
 
103
103
  gemini:
104
- instructions: true
105
104
  skills: true
105
+ auto_sync_on: SessionStart
106
106
 
107
107
  # Functional / Knowledge Plugins
108
108
  karpathy-llm:
@@ -20,7 +20,7 @@ Operational skills, rules, and subagents remain cleanly encapsulated within `.rn
20
20
  - Contains zero inline heuristics—redirects Cascade directly to the underlying agentic skill protocols inside `.rnex/`.
21
21
 
22
22
  2. **Native Instructions Support via `.windsurfrules`**:
23
- - Synchronizes Repo Nexus routing instructions to `.windsurfrules` when `instructions: true` (default).
23
+ - Automatically synchronizes Repo Nexus routing instructions to `.windsurfrules`.
24
24
  - Preserves user custom rules and custom sections in `.windsurfrules`.
25
25
 
26
26
  3. **Subagent & Skill Execution**:
@@ -57,14 +57,12 @@ Configure options under `plugins.windsurf` in `rnex.yaml` or `.local.rnex.yaml`:
57
57
  ```yaml
58
58
  plugins:
59
59
  windsurf:
60
- instructions: true # Sync routing instructions to .windsurfrules (default: true)
61
60
  skills: true # Generate user skills in .windsurf/rules/ (default: true)
62
61
  enabled: true # Set to false to disable
63
62
  ```
64
63
 
65
64
  | Option | Type | Default | Description |
66
65
  |:---|:---|:---|:---|
67
- | `instructions` | boolean | `true` | Merge routing instructions into `.windsurfrules`. |
68
66
  | `skills` | boolean | `true` | Generate user skill pointers in `.windsurf/rules/rnex-*.md`. |
69
67
  | `enabled` | boolean | `true` | Enable or disable the plugin. Overridable in `.local.rnex.yaml`. |
70
68
 
@@ -77,7 +75,7 @@ When `windsurf` is enabled with functional plugins like `karpathy-llm`, it gener
77
75
  ```text
78
76
  my-workspace/
79
77
  ├── AGENTS.md # Universal workspace instructions & routing
80
- ├── .windsurfrules # Windsurf instructions (if instructions: true)
78
+ ├── .windsurfrules # Windsurf instructions
81
79
  ├── .windsurf/
82
80
  │ └── rules/ # Zero-logic User Skill pointers
83
81
  │ ├── rnex-clone-sync.md
@@ -84,24 +84,22 @@ git_hooks: true
84
84
  # AGENTS.md at workspace root is the universal cross-tool standard. Assistants that read AGENTS.md
85
85
  # all the time need no separate top-level instructions file. Assistants with native
86
86
  # formats (Claude with CLAUDE.md, Gemini with GEMINI.md, Cursor with .cursorrules, Windsurf with .windsurfrules)
87
- # have their instruction files maintained when their plugin is enabled (instructions: true).
87
+ # have their instruction files maintained automatically when their plugin is enabled.
88
88
  # Agentic skills live self-contained inside .rnex/skills/ (core) and .rnex/plugins/<plugin>/skills/ (plugins).
89
89
  # Provider plugins generate zero-logic User Skills (prefixed with rnex-) into IDE-specific skill directories
90
90
  # linking directly to the agentic skill protocols inside .rnex/.
91
91
 
92
92
  plugins:
93
93
  # claude:
94
- # instructions: true # sync routing instructions to CLAUDE.md (default: true)
95
- # skills: true # generate user skills in .claude/skills/ (default: true)
94
+ # skills: true # generate user skills in .claude/skills/ (default: true)
95
+ # auto_sync_on: SessionStart # trigger auto-sync on lifecycle event (default: SessionStart, or false)
96
96
  # gemini:
97
- # instructions: true # sync routing instructions to GEMINI.md (default: true)
98
- # skills: true # generate user skills in .agents/skills/ (default: true)
97
+ # skills: true # generate user skills in .agents/skills/ (default: true)
98
+ # auto_sync_on: SessionStart # trigger auto-sync on lifecycle event (default: SessionStart, or false)
99
99
  # cursor:
100
- # instructions: true # sync routing instructions to .cursorrules (default: true)
101
- # skills: true # generate user skills in .cursor/rules/ (default: true)
100
+ # skills: true # generate user skills in .cursor/rules/ (default: true)
102
101
  # windsurf:
103
- # instructions: true # sync routing instructions to .windsurfrules (default: true)
104
- # skills: true # generate user skills in .windsurf/rules/ (default: true)
102
+ # skills: true # generate user skills in .windsurf/rules/ (default: true)
105
103
  # karpathy-llm:
106
104
  # raw_dir: "./docs" # Append-only directory for unmodified intake documents (default: ./docs)
107
105
  # wiki_dir: ".rnex/wiki" # Directory for curated atomic markdown pages (default: .rnex/wiki)
package/lib/ai.sh CHANGED
@@ -495,6 +495,96 @@ clean_provider_agents() {
495
495
  rmdir "$_ag_dir" 2>/dev/null || true
496
496
  }
497
497
 
498
+ clean_claude_auto_sync_hook() {
499
+ _settings="$1"
500
+ [ -f "$_settings" ] || return 0
501
+ if grep -q "auto-sync.sh" "$_settings" 2>/dev/null; then
502
+ _tmp="$(mktemp)"
503
+ awk '
504
+ /\{[ \t]*"command"[ \t]*:[ \t]*"\.rnex\/bin\/auto-sync\.sh"[ \t]*\}/ { next }
505
+ /"command"[ \t]*:[ \t]*"\.rnex\/bin\/auto-sync\.sh"/ { next }
506
+ { print }
507
+ ' "$_settings" > "$_tmp"
508
+ _clean="$(sed -e 's/"hooks"//g' -e 's/"SessionStart"//g' < "$_tmp" | tr -d ' \t\r\n[]{}:,"')"
509
+ if [ -z "$_clean" ]; then
510
+ rm -f "$_tmp" "$_settings"
511
+ else
512
+ awk '
513
+ { lines[NR] = $0 }
514
+ END {
515
+ for (i = 1; i <= NR; i++) {
516
+ if (i < NR && lines[i] ~ /,[ \t]*$/) {
517
+ next_is_bracket = 0
518
+ for (j = i + 1; j <= NR; j++) {
519
+ if (lines[j] ~ /^[ \t]*$/) continue
520
+ if (lines[j] ~ /^[ \t]*[\]\}]/) next_is_bracket = 1
521
+ break
522
+ }
523
+ if (next_is_bracket) {
524
+ sub(/,[ \t]*$/, "", lines[i])
525
+ }
526
+ }
527
+ print lines[i]
528
+ }
529
+ }
530
+ ' "$_tmp" > "$_settings"
531
+ rm -f "$_tmp"
532
+ fi
533
+ fi
534
+ }
535
+
536
+ clean_agents_auto_sync_hook() {
537
+ _hooks="$1"
538
+ [ -f "$_hooks" ] || return 0
539
+ if grep -q '"rnex-auto-sync"' "$_hooks" 2>/dev/null; then
540
+ _tmp="$(mktemp)"
541
+ awk '
542
+ BEGIN { skip=0; depth=0 }
543
+ /"rnex-auto-sync"[ \t]*:[ \t]*\{/ { skip=1; depth=1; next }
544
+ skip {
545
+ for (i=1; i<=length($0); i++) {
546
+ c = substr($0, i, 1)
547
+ if (c == "{") depth++
548
+ if (c == "}") {
549
+ depth--
550
+ if (depth == 0) {
551
+ skip = 0
552
+ next
553
+ }
554
+ }
555
+ }
556
+ next
557
+ }
558
+ { print }
559
+ ' "$_hooks" > "$_tmp"
560
+ _clean="$(tr -d " \t\r\n{}" < "$_tmp")"
561
+ if [ -z "$_clean" ]; then
562
+ rm -f "$_tmp" "$_hooks"
563
+ else
564
+ awk '
565
+ { lines[NR] = $0 }
566
+ END {
567
+ for (i = 1; i <= NR; i++) {
568
+ if (i < NR && lines[i] ~ /,[ \t]*$/) {
569
+ next_is_brace = 0
570
+ for (j = i + 1; j <= NR; j++) {
571
+ if (lines[j] ~ /^[ \t]*$/) continue
572
+ if (lines[j] ~ /^[ \t]*\}/) next_is_brace = 1
573
+ break
574
+ }
575
+ if (next_is_brace) {
576
+ sub(/,[ \t]*$/, "", lines[i])
577
+ }
578
+ }
579
+ print lines[i]
580
+ }
581
+ }
582
+ ' "$_tmp" > "$_hooks"
583
+ rm -f "$_tmp"
584
+ fi
585
+ fi
586
+ }
587
+
498
588
  sync_rnex_base_assets() {
499
589
  _src_toolkit=""
500
590
  if [ -d "$SCRIPT_LOCATION/toolkit" ]; then
@@ -213,10 +213,20 @@ cmd_status() {
213
213
  else
214
214
  printf ' %b●%b %-18s %b(v%s)%b %s\n' "$_G" "$_NC" "$_pname" "$_DIM" "${_ver:-0.1.0}" "$_NC" "${_desc:+- $_desc}"
215
215
  printf ' %bScoped directory: .rnex/plugins/%s%b\n' "$_DIM" "$_pname" "$_NC"
216
- if [ -n "$_pdir" ] && { grep -q "instructions:" "$_pdir/plugin.yaml" 2>/dev/null || [ -n "$(yaml_plugin_get "$_pname" "instructions" 2>/dev/null)" ]; }; then
217
- printf ' %b↳ Options: instructions=%s, skills=%s%b\n' "$_DIM" \
218
- "$(provider_option_enabled "$_pname" "instructions" && echo "true" || echo "false")" \
219
- "$(provider_option_enabled "$_pname" "skills" && echo "true" || echo "false")" "$_NC"
216
+ if [ -n "$_pdir" ] && [ -f "$_pdir/plugin.yaml" ]; then
217
+ _opts=""
218
+ if grep -q "skills:" "$_pdir/plugin.yaml" 2>/dev/null || [ -n "$(yaml_plugin_get "$_pname" "skills" 2>/dev/null)" ]; then
219
+ _opts="${_opts:+$_opts, }skills=$(provider_option_enabled "$_pname" "skills" && echo "true" || echo "false")"
220
+ fi
221
+ if grep -q "auto_sync_on:" "$_pdir/plugin.yaml" 2>/dev/null || grep -q "autoSyncOn:" "$_pdir/plugin.yaml" 2>/dev/null || [ -n "$(yaml_plugin_get "$_pname" "auto_sync_on" 2>/dev/null)" ] || [ -n "$(yaml_plugin_get "$_pname" "autoSyncOn" 2>/dev/null)" ]; then
222
+ _aso="$(yaml_plugin_get "$_pname" "auto_sync_on" 2>/dev/null || true)"
223
+ [ -z "$_aso" ] && _aso="$(yaml_plugin_get "$_pname" "autoSyncOn" 2>/dev/null || true)"
224
+ [ -z "$_aso" ] && _aso="SessionStart"
225
+ _opts="${_opts:+$_opts, }auto_sync_on=$_aso"
226
+ fi
227
+ if [ -n "$_opts" ]; then
228
+ printf ' %b↳ Options: %s%b\n' "$_DIM" "$_opts" "$_NC"
229
+ fi
220
230
  fi
221
231
  fi
222
232
  else
package/lib/yaml.sh CHANGED
@@ -157,24 +157,39 @@ provider_option_enabled() {
157
157
  esac
158
158
  }
159
159
 
160
+ provider_auto_sync_enabled() {
161
+ _p="$1"
162
+ provider_plugin_enabled "$_p" || return 1
163
+ _val="$(yaml_plugin_get "$_p" "auto_sync_on")"
164
+ [ -z "$_val" ] && _val="$(yaml_plugin_get "$_p" "autoSyncOn")"
165
+ [ -z "$_val" ] && _val="SessionStart"
166
+ _val="$(printf '%s' "$_val" | tr '[:upper:]' '[:lower:]')"
167
+ case "$_val" in
168
+ false|no|0|disabled|off|none) return 1 ;;
169
+ *) return 0 ;;
170
+ esac
171
+ }
172
+
160
173
  copilot_plugin_enabled() { provider_plugin_enabled "copilot"; }
161
- copilot_instructions_enabled() { provider_option_enabled "copilot" "instructions"; }
174
+ copilot_instructions_enabled() { provider_plugin_enabled "copilot"; }
162
175
  copilot_skills_enabled() { provider_option_enabled "copilot" "skills"; }
163
176
 
164
177
  claude_plugin_enabled() { provider_plugin_enabled "claude"; }
165
- claude_instructions_enabled() { provider_option_enabled "claude" "instructions"; }
178
+ claude_instructions_enabled() { provider_plugin_enabled "claude"; }
166
179
  claude_skills_enabled() { provider_option_enabled "claude" "skills"; }
180
+ claude_auto_sync_enabled() { provider_auto_sync_enabled "claude"; }
167
181
 
168
182
  gemini_plugin_enabled() { provider_plugin_enabled "gemini"; }
169
- gemini_instructions_enabled() { provider_option_enabled "gemini" "instructions"; }
183
+ gemini_instructions_enabled() { provider_plugin_enabled "gemini"; }
170
184
  gemini_skills_enabled() { provider_option_enabled "gemini" "skills"; }
185
+ gemini_auto_sync_enabled() { provider_auto_sync_enabled "gemini"; }
171
186
 
172
187
  cursor_plugin_enabled() { provider_plugin_enabled "cursor"; }
173
- cursor_instructions_enabled() { provider_option_enabled "cursor" "instructions"; }
188
+ cursor_instructions_enabled() { provider_plugin_enabled "cursor"; }
174
189
  cursor_skills_enabled() { provider_option_enabled "cursor" "skills"; }
175
190
 
176
191
  windsurf_plugin_enabled() { provider_plugin_enabled "windsurf"; }
177
- windsurf_instructions_enabled() { provider_option_enabled "windsurf" "instructions"; }
192
+ windsurf_instructions_enabled() { provider_plugin_enabled "windsurf"; }
178
193
  windsurf_skills_enabled() { provider_option_enabled "windsurf" "skills"; }
179
194
 
180
195
  has_active_provider_instructions() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "repo-nexus",
3
- "version": "0.7.24",
3
+ "version": "0.7.26",
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",
@@ -9,7 +9,6 @@ if [ -z "$RNEX_PROVIDER_SKILL_DIRS" ]; then
9
9
  [ -d "$RNEX_ROOT/.claude" ] && _dirs="${_dirs:+$_dirs }.claude/skills"
10
10
  [ -d "$RNEX_ROOT/.windsurf" ] && _dirs="${_dirs:+$_dirs }.windsurf/rules"
11
11
  [ -d "$RNEX_ROOT/.agents" ] && _dirs="${_dirs:+$_dirs }.agents/skills"
12
- [ -d "$RNEX_ROOT/.gemini" ] && _dirs="${_dirs:+$_dirs }.agents/skills"
13
12
  export RNEX_PROVIDER_SKILL_DIRS="$_dirs"
14
13
  fi
15
14
 
@@ -106,8 +105,54 @@ rnex_unregister_user_skill() {
106
105
  }
107
106
 
108
107
  # Provider configuration check helper
109
- if ! command -v provider_option_enabled >/dev/null 2>&1; then
110
- provider_option_enabled() {
108
+ if ! command -v provider_plugin_enabled >/dev/null 2>&1; then
109
+ provider_plugin_enabled() {
110
+ _p="$1"
111
+ _r="${NEXUS_DIR:-${RNEX_ROOT:-.}}"
112
+ _val=""
113
+ if [ -f "$_r/.local.rnex.yaml" ]; then
114
+ _val="$(awk -v p="$_p" '
115
+ /^plugins:/ { in_p=1; next }
116
+ in_p && /^[^ #]/ { in_p=0; in_target=0 }
117
+ in_p && match($0, "^[ ]*" p ":[ ]*(#.*)?$") { in_target=1; next }
118
+ in_p && match($0, "^[ ]*-[ ]*" p "[ ]*(#.*)?$") { print "true"; exit }
119
+ in_target && (/^[ ]{1,2}[^ #]/ || /^[^ #]/) { in_target=0 }
120
+ in_target && $0 ~ "^[ ]*enabled:[ ]*" {
121
+ sub("^[ ]*enabled:[ ]*", "")
122
+ sub(/[ ]*#.*/, "")
123
+ gsub(/["\047]/, "")
124
+ print
125
+ exit
126
+ }
127
+ ' "$_r/.local.rnex.yaml")"
128
+ fi
129
+ if [ -z "$_val" ] && [ -f "$_r/rnex.yaml" ]; then
130
+ _val="$(awk -v p="$_p" '
131
+ /^plugins:/ { in_p=1; next }
132
+ in_p && /^[^ #]/ { in_p=0; in_target=0 }
133
+ in_p && match($0, "^[ ]*" p ":[ ]*(#.*)?$") { in_target=1; next }
134
+ in_p && match($0, "^[ ]*-[ ]*" p "[ ]*(#.*)?$") { print "true"; exit }
135
+ in_target && (/^[ ]{1,2}[^ #]/ || /^[^ #]/) { in_target=0 }
136
+ in_target && $0 ~ "^[ ]*enabled:[ ]*" {
137
+ sub("^[ ]*enabled:[ ]*", "")
138
+ sub(/[ ]*#.*/, "")
139
+ gsub(/["\047]/, "")
140
+ print
141
+ exit
142
+ }
143
+ ' "$_r/rnex.yaml")"
144
+ fi
145
+ [ -n "$_val" ] || return 1
146
+ _val="$(printf '%s' "$_val" | tr '[:upper:]' '[:lower:]')"
147
+ case "$_val" in
148
+ false|no|0|disabled|off) return 1 ;;
149
+ *) return 0 ;;
150
+ esac
151
+ }
152
+ fi
153
+
154
+ if ! command -v provider_option_get >/dev/null 2>&1; then
155
+ provider_option_get() {
111
156
  _p="$1"; _opt="$2"
112
157
  _r="${NEXUS_DIR:-${RNEX_ROOT:-.}}"
113
158
  _val=""
@@ -141,6 +186,14 @@ if ! command -v provider_option_enabled >/dev/null 2>&1; then
141
186
  }
142
187
  ' "$_r/rnex.yaml")"
143
188
  fi
189
+ printf '%s' "$_val"
190
+ }
191
+ fi
192
+
193
+ if ! command -v provider_option_enabled >/dev/null 2>&1; then
194
+ provider_option_enabled() {
195
+ _p="$1"; _opt="$2"
196
+ _val="$(provider_option_get "$_p" "$_opt")"
144
197
  _val="$(printf '%s' "$_val" | tr '[:upper:]' '[:lower:]')"
145
198
  case "$_val" in
146
199
  false|no|0|disabled|off) return 1 ;;
@@ -149,17 +202,125 @@ if ! command -v provider_option_enabled >/dev/null 2>&1; then
149
202
  }
150
203
  fi
151
204
 
205
+ if ! command -v provider_auto_sync_enabled >/dev/null 2>&1; then
206
+ provider_auto_sync_enabled() {
207
+ _p="$1"
208
+ _val="$(provider_option_get "$_p" "auto_sync_on")"
209
+ [ -z "$_val" ] && _val="$(provider_option_get "$_p" "autoSyncOn")"
210
+ [ -z "$_val" ] && _val="SessionStart"
211
+ _val="$(printf '%s' "$_val" | tr '[:upper:]' '[:lower:]')"
212
+ case "$_val" in
213
+ false|no|0|disabled|off|none) return 1 ;;
214
+ *) return 0 ;;
215
+ esac
216
+ }
217
+ fi
218
+
152
219
  if ! command -v has_active_provider_instructions >/dev/null 2>&1; then
153
220
  has_active_provider_instructions() {
154
- provider_option_enabled "copilot" "instructions" 2>/dev/null && return 0
155
- provider_option_enabled "claude" "instructions" 2>/dev/null && return 0
156
- provider_option_enabled "gemini" "instructions" 2>/dev/null && return 0
157
- provider_option_enabled "cursor" "instructions" 2>/dev/null && return 0
158
- provider_option_enabled "windsurf" "instructions" 2>/dev/null && return 0
221
+ provider_plugin_enabled "copilot" 2>/dev/null && return 0
222
+ provider_plugin_enabled "claude" 2>/dev/null && return 0
223
+ provider_plugin_enabled "gemini" 2>/dev/null && return 0
224
+ provider_plugin_enabled "cursor" 2>/dev/null && return 0
225
+ provider_plugin_enabled "windsurf" 2>/dev/null && return 0
159
226
  return 1
160
227
  }
161
228
  fi
162
229
 
230
+ if ! command -v clean_claude_auto_sync_hook >/dev/null 2>&1; then
231
+ clean_claude_auto_sync_hook() {
232
+ _settings="$1"
233
+ [ -f "$_settings" ] || return 0
234
+ if grep -q "auto-sync.sh" "$_settings" 2>/dev/null; then
235
+ _tmp="$(mktemp)"
236
+ awk '
237
+ /\{[ \t]*"command"[ \t]*:[ \t]*"\.rnex\/bin\/auto-sync\.sh"[ \t]*\}/ { next }
238
+ /"command"[ \t]*:[ \t]*"\.rnex\/bin\/auto-sync\.sh"/ { next }
239
+ { print }
240
+ ' "$_settings" > "$_tmp"
241
+ _clean="$(sed -e 's/"hooks"//g' -e 's/"SessionStart"//g' < "$_tmp" | tr -d ' \t\r\n[]{}:,"')"
242
+ if [ -z "$_clean" ]; then
243
+ rm -f "$_tmp" "$_settings"
244
+ else
245
+ awk '
246
+ { lines[NR] = $0 }
247
+ END {
248
+ for (i = 1; i <= NR; i++) {
249
+ if (i < NR && lines[i] ~ /,[ \t]*$/) {
250
+ next_is_bracket = 0
251
+ for (j = i + 1; j <= NR; j++) {
252
+ if (lines[j] ~ /^[ \t]*$/) continue
253
+ if (lines[j] ~ /^[ \t]*[\]\}]/) next_is_bracket = 1
254
+ break
255
+ }
256
+ if (next_is_bracket) {
257
+ sub(/,[ \t]*$/, "", lines[i])
258
+ }
259
+ }
260
+ print lines[i]
261
+ }
262
+ }
263
+ ' "$_tmp" > "$_settings"
264
+ rm -f "$_tmp"
265
+ fi
266
+ fi
267
+ }
268
+ fi
269
+
270
+ if ! command -v clean_agents_auto_sync_hook >/dev/null 2>&1; then
271
+ clean_agents_auto_sync_hook() {
272
+ _hooks="$1"
273
+ [ -f "$_hooks" ] || return 0
274
+ if grep -q '"rnex-auto-sync"' "$_hooks" 2>/dev/null; then
275
+ _tmp="$(mktemp)"
276
+ awk '
277
+ BEGIN { skip=0; depth=0 }
278
+ /"rnex-auto-sync"[ \t]*:[ \t]*\{/ { skip=1; depth=1; next }
279
+ skip {
280
+ for (i=1; i<=length($0); i++) {
281
+ c = substr($0, i, 1)
282
+ if (c == "{") depth++
283
+ if (c == "}") {
284
+ depth--
285
+ if (depth == 0) {
286
+ skip = 0
287
+ next
288
+ }
289
+ }
290
+ }
291
+ next
292
+ }
293
+ { print }
294
+ ' "$_hooks" > "$_tmp"
295
+ _clean="$(tr -d " \t\r\n{}" < "$_tmp")"
296
+ if [ -z "$_clean" ]; then
297
+ rm -f "$_tmp" "$_hooks"
298
+ else
299
+ awk '
300
+ { lines[NR] = $0 }
301
+ END {
302
+ for (i = 1; i <= NR; i++) {
303
+ if (i < NR && lines[i] ~ /,[ \t]*$/) {
304
+ next_is_brace = 0
305
+ for (j = i + 1; j <= NR; j++) {
306
+ if (lines[j] ~ /^[ \t]*$/) continue
307
+ if (lines[j] ~ /^[ \t]*\}/) next_is_brace = 1
308
+ break
309
+ }
310
+ if (next_is_brace) {
311
+ sub(/,[ \t]*$/, "", lines[i])
312
+ }
313
+ }
314
+ print lines[i]
315
+ }
316
+ }
317
+ ' "$_tmp" > "$_hooks"
318
+ rm -f "$_tmp"
319
+ fi
320
+ fi
321
+ }
322
+ fi
323
+
163
324
  # Instructions routing helpers
164
325
  if ! command -v merge_rnex_instructions >/dev/null 2>&1; then
165
326
  merge_rnex_instructions() {
@@ -84,24 +84,22 @@ git_hooks: true
84
84
  # AGENTS.md at workspace root is the universal cross-tool standard. Assistants that read AGENTS.md
85
85
  # all the time need no separate top-level instructions file. Assistants with native
86
86
  # formats (Claude with CLAUDE.md, Gemini with GEMINI.md, Cursor with .cursorrules, Windsurf with .windsurfrules)
87
- # have their instruction files maintained when their plugin is enabled (instructions: true).
87
+ # have their instruction files maintained automatically when their plugin is enabled.
88
88
  # Agentic skills live self-contained inside .rnex/skills/ (core) and .rnex/plugins/<plugin>/skills/ (plugins).
89
89
  # Provider plugins generate zero-logic User Skills (prefixed with rnex-) into IDE-specific skill directories
90
90
  # linking directly to the agentic skill protocols inside .rnex/.
91
91
 
92
92
  plugins:
93
93
  # claude:
94
- # instructions: true # sync routing instructions to CLAUDE.md (default: true)
95
- # skills: true # generate user skills in .claude/skills/ (default: true)
94
+ # skills: true # generate user skills in .claude/skills/ (default: true)
95
+ # auto_sync_on: SessionStart # trigger auto-sync on lifecycle event (default: SessionStart, or false)
96
96
  # gemini:
97
- # instructions: true # sync routing instructions to GEMINI.md (default: true)
98
- # skills: true # generate user skills in .agents/skills/ (default: true)
97
+ # skills: true # generate user skills in .agents/skills/ (default: true)
98
+ # auto_sync_on: SessionStart # trigger auto-sync on lifecycle event (default: SessionStart, or false)
99
99
  # cursor:
100
- # instructions: true # sync routing instructions to .cursorrules (default: true)
101
- # skills: true # generate user skills in .cursor/rules/ (default: true)
100
+ # skills: true # generate user skills in .cursor/rules/ (default: true)
102
101
  # windsurf:
103
- # instructions: true # sync routing instructions to .windsurfrules (default: true)
104
- # skills: true # generate user skills in .windsurf/rules/ (default: true)
102
+ # skills: true # generate user skills in .windsurf/rules/ (default: true)
105
103
  # karpathy-llm:
106
104
  # raw_dir: "./docs" # Append-only directory for unmodified intake documents (default: ./docs)
107
105
  # wiki_dir: ".rnex/wiki" # Directory for curated atomic markdown pages (default: .rnex/wiki)
@@ -18,14 +18,14 @@ Or configure options in `rnex.yaml` or `.local.rnex.yaml`:
18
18
  ```yaml
19
19
  plugins:
20
20
  claude:
21
- instructions: true
22
21
  skills: true
22
+ auto_sync_on: SessionStart
23
23
  ```
24
24
 
25
25
  ## Options
26
26
 
27
27
  | Option | Type | Default | Description |
28
28
  |--------|------|---------|-------------|
29
- | `instructions` | boolean | `true` | Maintain routing in `CLAUDE.md` |
30
29
  | `skills` | boolean | `true` | Generate user skills in `.claude/skills/` |
30
+ | `auto_sync_on` | string/boolean | `SessionStart` | Lifecycle event triggering auto-sync in `.claude/settings.json` (or `false` to disable) |
31
31
  | `enabled` | boolean | `true` | Set to `false` in `.local.rnex.yaml` to override team config |
@@ -8,13 +8,8 @@ if ! command -v merge_rnex_instructions >/dev/null 2>&1; then
8
8
  fi
9
9
  fi
10
10
 
11
- # Instructions management
12
- _inst="$(provider_option_enabled "claude" "instructions" 2>/dev/null && echo "true" || echo "false")"
13
- if [ "$_inst" = "true" ]; then
14
- merge_rnex_instructions "$_root/CLAUDE.md"
15
- else
16
- clean_rnex_instructions "$_root/CLAUDE.md"
17
- fi
11
+ # Instructions management (always maintained when claude plugin is enabled)
12
+ merge_rnex_instructions "$_root/CLAUDE.md"
18
13
 
19
14
  # Skills management
20
15
  _sk="$(provider_option_enabled "claude" "skills" 2>/dev/null && echo "true" || echo "false")"
@@ -22,11 +17,12 @@ if [ "$_sk" != "true" ]; then
22
17
  clean_provider_user_skills "$_root/.claude/skills"
23
18
  fi
24
19
 
25
- # SessionStart auto-sync hook configuration
26
- mkdir -p "$_root/.claude"
20
+ # Auto-sync hook configuration (SessionStart)
27
21
  _settings="$_root/.claude/settings.json"
28
- if [ ! -f "$_settings" ]; then
29
- cat > "$_settings" <<'EOF'
22
+ if provider_auto_sync_enabled "claude"; then
23
+ mkdir -p "$_root/.claude"
24
+ if [ ! -f "$_settings" ]; then
25
+ cat > "$_settings" <<'EOF'
30
26
  {
31
27
  "hooks": {
32
28
  "SessionStart": [
@@ -37,26 +33,30 @@ if [ ! -f "$_settings" ]; then
37
33
  }
38
34
  }
39
35
  EOF
40
- elif ! grep -q "auto-sync.sh" "$_settings" 2>/dev/null; then
41
- if grep -q '"SessionStart"' "$_settings" 2>/dev/null; then
42
- _tmp="$(mktemp)"
43
- awk '
44
- /"SessionStart"[ ]*:[ ]*\[/ {
45
- print
46
- print " { \"command\": \".rnex/bin/auto-sync.sh\" },"
47
- next
48
- }
49
- { print }
50
- ' "$_settings" > "$_tmp" && mv "$_tmp" "$_settings"
51
- elif grep -q '"hooks"' "$_settings" 2>/dev/null; then
52
- _tmp="$(mktemp)"
53
- awk '
54
- /"hooks"[ ]*:[ ]*\{/ {
55
- print
56
- print " \"SessionStart\": [ { \"command\": \".rnex/bin/auto-sync.sh\" } ],"
57
- next
58
- }
59
- { print }
60
- ' "$_settings" > "$_tmp" && mv "$_tmp" "$_settings"
36
+ elif ! grep -q "auto-sync.sh" "$_settings" 2>/dev/null; then
37
+ if grep -q '"SessionStart"' "$_settings" 2>/dev/null; then
38
+ _tmp="$(mktemp)"
39
+ awk '
40
+ /"SessionStart"[ ]*:[ ]*\[/ {
41
+ print
42
+ print " { \"command\": \".rnex/bin/auto-sync.sh\" },"
43
+ next
44
+ }
45
+ { print }
46
+ ' "$_settings" > "$_tmp" && mv "$_tmp" "$_settings"
47
+ elif grep -q '"hooks"' "$_settings" 2>/dev/null; then
48
+ _tmp="$(mktemp)"
49
+ awk '
50
+ /"hooks"[ ]*:[ ]*\{/ {
51
+ print
52
+ print " \"SessionStart\": [ { \"command\": \".rnex/bin/auto-sync.sh\" } ],"
53
+ next
54
+ }
55
+ { print }
56
+ ' "$_settings" > "$_tmp" && mv "$_tmp" "$_settings"
57
+ fi
61
58
  fi
59
+ else
60
+ clean_claude_auto_sync_hook "$_settings"
61
+ rmdir "$_root/.claude" 2>/dev/null || true
62
62
  fi
@@ -10,5 +10,6 @@ fi
10
10
 
11
11
  clean_rnex_instructions "$_root/CLAUDE.md"
12
12
  clean_provider_user_skills "$_root/.claude/skills"
13
+ clean_claude_auto_sync_hook "$_root/.claude/settings.json"
13
14
  rm -rf "$_root/.claude/commands" "$_root/.claude/prompts" 2>/dev/null || true
14
15
  rmdir "$_root/.claude" 2>/dev/null || true
@@ -13,8 +13,8 @@ Configure plugin options in `rnex.yaml` or override them per developer in `.loca
13
13
  ```yaml
14
14
  plugins:
15
15
  claude:
16
- instructions: true # Maintain routing in CLAUDE.md (default: true)
17
16
  skills: true # Generate user skills in .claude/skills/ (default: true)
17
+ auto_sync_on: SessionStart # Trigger auto-sync on lifecycle event (default: SessionStart, or false)
18
18
  ```
19
19
 
20
20
  To disable locally without altering team configuration, add to `.local.rnex.yaml`:
@@ -6,12 +6,12 @@ homepage: https://github.com/unoxen/repo-nexus
6
6
  skill_dir: .claude/skills
7
7
 
8
8
  config_defaults:
9
- instructions: true
10
9
  skills: true
10
+ auto_sync_on: SessionStart
11
11
 
12
12
  config_descriptions:
13
- instructions: "true|false (maintain provider instructions)"
14
13
  skills: "true|false (generate user skills in {skill_dir})"
14
+ auto_sync_on: "SessionStart|false (trigger auto-sync on lifecycle event, e.g. SessionStart)"
15
15
 
16
16
  instructions:
17
17
  - instructions/rnex-claude-integration.md: .rnex/plugins/claude/instructions/rnex-claude-integration.md
@@ -18,7 +18,6 @@ Or configure options in `rnex.yaml` or `.local.rnex.yaml`:
18
18
  ```yaml
19
19
  plugins:
20
20
  copilot:
21
- instructions: true
22
21
  skills: true
23
22
  ```
24
23
 
@@ -26,6 +25,5 @@ plugins:
26
25
 
27
26
  | Option | Type | Default | Description |
28
27
  |--------|------|---------|-------------|
29
- | `instructions` | boolean | `true` | Maintain routing in `.github/copilot-instructions.md` |
30
28
  | `skills` | boolean | `true` | Generate user skills in `.github/skills/` |
31
29
  | `enabled` | boolean | `true` | Set to `false` in `.local.rnex.yaml` to override team config |
@@ -142,16 +142,9 @@ if ! command -v clean_provider_user_skills >/dev/null 2>&1; then
142
142
  }
143
143
  fi
144
144
 
145
- _inst="$(provider_option_enabled "copilot" "instructions" 2>/dev/null && echo "true" || echo "false")"
146
- if [ "$_inst" = "true" ]; then
147
- mkdir -p "$_root/.github"
148
- if command -v merge_rnex_instructions >/dev/null 2>&1; then
149
- merge_rnex_instructions "$_root/.github/copilot-instructions.md"
150
- fi
151
- else
152
- if command -v clean_rnex_instructions >/dev/null 2>&1; then
153
- clean_rnex_instructions "$_root/.github/copilot-instructions.md"
154
- fi
145
+ mkdir -p "$_root/.github"
146
+ if command -v merge_rnex_instructions >/dev/null 2>&1; then
147
+ merge_rnex_instructions "$_root/.github/copilot-instructions.md"
155
148
  fi
156
149
 
157
150
  _sk="$(provider_option_enabled "copilot" "skills" 2>/dev/null && echo "true" || echo "false")"
@@ -12,7 +12,6 @@ Configure plugin options in `rnex.yaml` or override them per developer in `.loca
12
12
  ```yaml
13
13
  plugins:
14
14
  copilot:
15
- instructions: true # Maintain routing in .github/copilot-instructions.md (default: true)
16
15
  skills: true # Generate user skills in .github/skills/ (default: true)
17
16
  ```
18
17
 
@@ -6,11 +6,9 @@ homepage: https://github.com/unoxen/repo-nexus
6
6
  skill_dir: .github/skills
7
7
 
8
8
  config_defaults:
9
- instructions: true
10
9
  skills: true
11
10
 
12
11
  config_descriptions:
13
- instructions: "true|false (maintain provider instructions)"
14
12
  skills: "true|false (generate user skills in {skill_dir})"
15
13
 
16
14
  instructions:
@@ -19,7 +19,6 @@ Or configure options in `rnex.yaml` or `.local.rnex.yaml`:
19
19
  ```yaml
20
20
  plugins:
21
21
  cursor:
22
- instructions: true
23
22
  skills: true
24
23
  ```
25
24
 
@@ -27,6 +26,5 @@ plugins:
27
26
 
28
27
  | Option | Type | Default | Description |
29
28
  |--------|------|---------|-------------|
30
- | `instructions` | boolean | `true` | Maintain routing in `.cursorrules` & `.cursor/rules/` |
31
29
  | `skills` | boolean | `true` | Generate user skills in `.cursor/rules/` |
32
30
  | `enabled` | boolean | `true` | Set to `false` in `.local.rnex.yaml` to override team config |
@@ -20,23 +20,18 @@ elif ! grep -q '!repos/\*' "$_ci" 2>/dev/null; then
20
20
  [ "${RNEX_QUIET:-0}" -eq 0 ] && log_dim "Added !repos/* to .cursorignore"
21
21
  fi
22
22
 
23
- _inst="$(provider_option_enabled "cursor" "instructions" 2>/dev/null && echo "true" || echo "false")"
24
- if [ "$_inst" = "true" ]; then
25
- merge_rnex_instructions "$_root/.cursorrules"
26
- mkdir -p "$_root/.cursor/rules"
27
- _c_body="$(mktemp)"
28
- get_rnex_instructions > "$_c_body"
29
- {
30
- printf -- '---\ndescription: Repo Nexus Virtual Meta-Repo routing protocol\nglobs: *\nalwaysApply: true\n---\n\n%s\n' "${AI_MARKER_START:-<!-- REPO-NEXUS:START -->}"
31
- cat "$_c_body"
32
- printf '\n%s\n' "${AI_MARKER_END:-<!-- REPO-NEXUS:END -->}"
33
- } > "$_root/.cursor/rules/rnex-context.mdc"
34
- rm -f "$_c_body"
35
- rm -f "$_root/.cursor/rules/repo-nexus.mdc" 2>/dev/null || true
36
- else
37
- clean_rnex_instructions "$_root/.cursorrules"
38
- rm -f "$_root/.cursor/rules/rnex-context.mdc" "$_root/.cursor/rules/repo-nexus.mdc" 2>/dev/null || true
39
- fi
23
+ # Instructions management (always maintained when cursor plugin is enabled)
24
+ merge_rnex_instructions "$_root/.cursorrules"
25
+ mkdir -p "$_root/.cursor/rules"
26
+ _c_body="$(mktemp)"
27
+ get_rnex_instructions > "$_c_body"
28
+ {
29
+ printf -- '---\ndescription: Repo Nexus Virtual Meta-Repo routing protocol\nglobs: *\nalwaysApply: true\n---\n\n%s\n' "${AI_MARKER_START:-<!-- REPO-NEXUS:START -->}"
30
+ cat "$_c_body"
31
+ printf '\n%s\n' "${AI_MARKER_END:-<!-- REPO-NEXUS:END -->}"
32
+ } > "$_root/.cursor/rules/rnex-context.mdc"
33
+ rm -f "$_c_body"
34
+ rm -f "$_root/.cursor/rules/repo-nexus.mdc" 2>/dev/null || true
40
35
 
41
36
  _sk="$(provider_option_enabled "cursor" "skills" 2>/dev/null && echo "true" || echo "false")"
42
37
  if [ "$_sk" != "true" ]; then
@@ -14,7 +14,6 @@ Configure plugin options in `rnex.yaml` or override them per developer in `.loca
14
14
  ```yaml
15
15
  plugins:
16
16
  cursor:
17
- instructions: true # Maintain routing in .cursorrules & .cursor/rules/ (default: true)
18
17
  skills: true # Generate user skills in .cursor/rules/ (default: true)
19
18
  ```
20
19
 
@@ -6,11 +6,9 @@ homepage: https://github.com/unoxen/repo-nexus
6
6
  skill_dir: .cursor/rules
7
7
 
8
8
  config_defaults:
9
- instructions: true
10
9
  skills: true
11
10
 
12
11
  config_descriptions:
13
- instructions: "true|false (maintain provider instructions)"
14
12
  skills: "true|false (generate user skills in {skill_dir})"
15
13
 
16
14
  instructions:
@@ -19,14 +19,14 @@ Or configure options in `rnex.yaml` or `.local.rnex.yaml`:
19
19
  ```yaml
20
20
  plugins:
21
21
  gemini:
22
- instructions: true
23
22
  skills: true
23
+ auto_sync_on: SessionStart
24
24
  ```
25
25
 
26
26
  ## Options
27
27
 
28
28
  | Option | Type | Default | Description |
29
29
  |--------|------|---------|-------------|
30
- | `instructions` | boolean | `true` | Maintain routing in `GEMINI.md` |
31
30
  | `skills` | boolean | `true` | Generate user skills in `.agents/skills/` |
31
+ | `auto_sync_on` | string/boolean | `SessionStart` | Lifecycle event triggering auto-sync in `.agents/hooks.json` (or `false` to disable) |
32
32
  | `enabled` | boolean | `true` | Set to `false` in `.local.rnex.yaml` to override team config |
@@ -20,18 +20,55 @@ elif ! grep -q '!repos/\*' "$_gi" 2>/dev/null; then
20
20
  [ "${RNEX_QUIET:-0}" -eq 0 ] && log_dim "Added !repos/* to .geminiignore"
21
21
  fi
22
22
 
23
- _inst="$(provider_option_enabled "gemini" "instructions" 2>/dev/null && echo "true" || echo "false")"
24
- if [ "$_inst" = "true" ]; then
25
- merge_rnex_instructions "$_root/GEMINI.md"
26
- else
27
- clean_rnex_instructions "$_root/GEMINI.md"
28
- fi
23
+ # Instructions management (always maintained when gemini plugin is enabled)
24
+ merge_rnex_instructions "$_root/GEMINI.md"
29
25
 
26
+ # Skills management
30
27
  _sk="$(provider_option_enabled "gemini" "skills" 2>/dev/null && echo "true" || echo "false")"
31
28
  if [ "$_sk" != "true" ]; then
32
29
  clean_provider_user_skills "$_root/.agents/skills"
33
30
  fi
34
31
 
32
+ # Auto-sync hook configuration (SessionStart)
33
+ _hooks_file="$_root/.agents/hooks.json"
34
+ if provider_auto_sync_enabled "gemini"; then
35
+ if [ ! -f "$_hooks_file" ]; then
36
+ mkdir -p "$_root/.agents"
37
+ cat > "$_hooks_file" <<'EOF'
38
+ {
39
+ "rnex-auto-sync": {
40
+ "SessionStart": [
41
+ {
42
+ "type": "command",
43
+ "command": ".rnex/bin/auto-sync.sh"
44
+ }
45
+ ]
46
+ }
47
+ }
48
+ EOF
49
+ elif ! grep -q '"rnex-auto-sync"' "$_hooks_file" 2>/dev/null; then
50
+ _tmp="$(mktemp)"
51
+ awk '
52
+ /^[ \t]*\{/ && !done {
53
+ print
54
+ print " \"rnex-auto-sync\": {"
55
+ print " \"SessionStart\": ["
56
+ print " {"
57
+ print " \"type\": \"command\","
58
+ print " \"command\": \".rnex/bin/auto-sync.sh\""
59
+ print " }"
60
+ print " ]"
61
+ print " },"
62
+ done = 1
63
+ next
64
+ }
65
+ { print }
66
+ ' "$_hooks_file" > "$_tmp" && mv "$_tmp" "$_hooks_file"
67
+ fi
68
+ else
69
+ clean_agents_auto_sync_hook "$_hooks_file"
70
+ fi
71
+
35
72
  # Clean legacy .gemini/skills if it exists
36
73
  if [ -d "$_root/.gemini/skills" ]; then
37
74
  clean_provider_user_skills "$_root/.gemini/skills"
@@ -12,6 +12,7 @@ clean_provider_ignore "$_root/.geminiignore"
12
12
  clean_rnex_instructions "$_root/GEMINI.md"
13
13
  clean_provider_user_skills "$_root/.agents/skills"
14
14
  clean_provider_user_skills "$_root/.gemini/skills"
15
+ clean_agents_auto_sync_hook "$_root/.agents/hooks.json"
15
16
  rm -rf "$_root/.gemini/prompts" 2>/dev/null || true
16
17
  rmdir "$_root/.gemini" 2>/dev/null || true
17
18
  rmdir "$_root/.agents" 2>/dev/null || true
@@ -14,8 +14,8 @@ Configure plugin options in `rnex.yaml` or override them per developer in `.loca
14
14
  ```yaml
15
15
  plugins:
16
16
  gemini:
17
- instructions: true # Maintain routing in GEMINI.md (default: true)
18
17
  skills: true # Generate user skills in .agents/skills/ (default: true)
18
+ auto_sync_on: SessionStart # Trigger auto-sync on lifecycle event (default: SessionStart, or false)
19
19
  ```
20
20
 
21
21
  To disable locally without altering team configuration, add to `.local.rnex.yaml`:
@@ -6,12 +6,12 @@ homepage: https://github.com/unoxen/repo-nexus
6
6
  skill_dir: .agents/skills
7
7
 
8
8
  config_defaults:
9
- instructions: true
10
9
  skills: true
10
+ auto_sync_on: SessionStart
11
11
 
12
12
  config_descriptions:
13
- instructions: "true|false (maintain provider instructions)"
14
13
  skills: "true|false (generate user skills in {skill_dir})"
14
+ auto_sync_on: "SessionStart|false (trigger auto-sync on lifecycle event, e.g. SessionStart)"
15
15
 
16
16
  instructions:
17
17
  - instructions/rnex-gemini-integration.md: .rnex/plugins/gemini/instructions/rnex-gemini-integration.md
@@ -18,7 +18,6 @@ Or configure options in `rnex.yaml` or `.local.rnex.yaml`:
18
18
  ```yaml
19
19
  plugins:
20
20
  windsurf:
21
- instructions: true
22
21
  skills: true
23
22
  ```
24
23
 
@@ -26,6 +25,5 @@ plugins:
26
25
 
27
26
  | Option | Type | Default | Description |
28
27
  |--------|------|---------|-------------|
29
- | `instructions` | boolean | `true` | Maintain routing in `.windsurfrules` |
30
28
  | `skills` | boolean | `true` | Generate user skills in `.windsurf/rules/` |
31
29
  | `enabled` | boolean | `true` | Set to `false` in `.local.rnex.yaml` to override team config |
@@ -8,12 +8,8 @@ if ! command -v merge_rnex_instructions >/dev/null 2>&1; then
8
8
  fi
9
9
  fi
10
10
 
11
- _inst="$(provider_option_enabled "windsurf" "instructions" 2>/dev/null && echo "true" || echo "false")"
12
- if [ "$_inst" = "true" ]; then
13
- merge_rnex_instructions "$_root/.windsurfrules"
14
- else
15
- clean_rnex_instructions "$_root/.windsurfrules"
16
- fi
11
+ # Instructions management (always maintained when windsurf plugin is enabled)
12
+ merge_rnex_instructions "$_root/.windsurfrules"
17
13
 
18
14
  _sk="$(provider_option_enabled "windsurf" "skills" 2>/dev/null && echo "true" || echo "false")"
19
15
  if [ "$_sk" != "true" ]; then
@@ -13,7 +13,6 @@ Configure plugin options in `rnex.yaml` or override them per developer in `.loca
13
13
  ```yaml
14
14
  plugins:
15
15
  windsurf:
16
- instructions: true # Maintain routing in .windsurfrules (default: true)
17
16
  skills: true # Generate user skills in .windsurf/rules/ (default: true)
18
17
  ```
19
18
 
@@ -6,11 +6,9 @@ homepage: https://github.com/unoxen/repo-nexus
6
6
  skill_dir: .windsurf/rules
7
7
 
8
8
  config_defaults:
9
- instructions: true
10
9
  skills: true
11
10
 
12
11
  config_descriptions:
13
- instructions: "true|false (maintain provider instructions)"
14
12
  skills: "true|false (generate user skills in {skill_dir})"
15
13
 
16
14
  instructions: