repo-nexus 0.7.7 → 0.7.8

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/CHANGELOG.md CHANGED
@@ -5,6 +5,19 @@ All notable changes to Repo Nexus (`rnex`) will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.7.7] - 2026-10-15
9
+
10
+ ### Added
11
+ - **Native `SKILL.md` Bundle Support for User Skills**:
12
+ - Upgraded User Skill generator (`rnex_register_user_skill`) to emit dual formats tailored to each AI provider's discovery engine:
13
+ - **Skill-Based Providers (`.github/skills/`, `.claude/skills/`, `.gemini/skills/`)**: Generates native `rnex-<name>/SKILL.md` directory bundles containing YAML frontmatter (`name: rnex-<name>`, `description: "..."`) for automatic discoverability in VS Code, Copilot Chat, Antigravity, and Claude Code skill-pickers.
14
+ - **Rule-Based Providers (`.cursor/rules/`, `.windsurf/rules/`)**: Generates flat `rnex-<name>.md` pointer files aligning with Cursor and Windsurf rule conventions.
15
+ - Automatically extracts skill descriptions from target markdown headers to populate YAML frontmatter cleanly.
16
+ - **GitHub Copilot Integration Plugin (`copilot`)**:
17
+ - Restored `copilot` as a first-class AI provider plugin in `toolkit/plugins/copilot/`.
18
+ - Supports `instructions: true` (managing `.github/copilot-instructions.md` within non-destructive delimiters) and `skills: true` (generating native User Skill bundles in `.github/skills/`).
19
+ - Added CLI flags `--copilot` and `--no-copilot` to `rnex init`.
20
+
8
21
  ## [0.7.5] - 2026-10-15
9
22
 
10
23
  ### Added
package/docs/CLI.md CHANGED
@@ -87,8 +87,8 @@ Every lifecycle hook receives the following environment variables:
87
87
  | `RNEX_QUIET` | Set to `1` when `--quiet` was passed, `0` otherwise. |
88
88
 
89
89
  Hooks have access to POSIX helper functions for managing User Skill pointers:
90
- - `rnex_register_user_skill <skill_name> <target_path_in_rnex>`: Generates a zero-logic user skill pointer (`rnex-<skill_name>.md`) in active provider directories linking to the target skill protocol.
91
- - `rnex_unregister_user_skill <skill_name>`: Removes the `rnex-<skill_name>.md` user skill pointer from all active provider directories.
90
+ - `rnex_register_user_skill <skill_name> <target_path_in_rnex>`: Generates a zero-logic user skill pointer (either a native `rnex-<name>/SKILL.md` bundle with YAML frontmatter for skill-based providers, or a flat `rnex-<name>.md` file for rule-based providers) linking to the target skill protocol.
91
+ - `rnex_unregister_user_skill <skill_name>`: Removes the `rnex-<skill_name>` user skill pointer (bundle or flat file) from all active provider directories.
92
92
 
93
93
  ### Karpathy LLM Wiki Plugin
94
94
  The `karpathy-llm` plugin uses lifecycle hooks to manage its domain directories:
@@ -15,8 +15,8 @@ Operational skills, rules, and subagents remain cleanly encapsulated within `.rn
15
15
 
16
16
  ## Capabilities
17
17
 
18
- 1. **Zero-Logic User Skills (`.claude/skills/rnex-*.md`)**:
19
- - Generates lightweight user skill pointers prefixed with `rnex-` in `.claude/skills/`.
18
+ 1. **Zero-Logic User Skills (`.claude/skills/rnex-*/SKILL.md`)**:
19
+ - Generates native `SKILL.md` bundles prefixed with `rnex-` in `.claude/skills/` with YAML frontmatter for Claude Code skill discovery.
20
20
  - Contains zero inline heuristics—redirects Claude directly to the underlying agentic skill protocols inside `.rnex/`.
21
21
 
22
22
  2. **Native Instruction Support via `CLAUDE.md` & `AGENTS.md`**:
@@ -12,7 +12,7 @@ The `copilot` plugin integrates GitHub Copilot with Repo Nexus by projecting wor
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
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.
15
- - **User Skills (`.github/skills/`)**: When `skills: true`, zero-logic User Skill pointers (`rnex-<name>.md`) redirect Copilot Chat to the underlying agentic skills under `.rnex/skills/` and active plugins.
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
18
18
 
@@ -15,8 +15,8 @@ Operational skills, rules, and subagents remain cleanly encapsulated within `.rn
15
15
 
16
16
  ## Capabilities
17
17
 
18
- 1. **Zero-Logic User Skills (`.gemini/skills/rnex-*.md`)**:
19
- - Generates lightweight user skill pointers prefixed with `rnex-` in `.gemini/skills/`.
18
+ 1. **Zero-Logic User Skills (`.gemini/skills/rnex-*/SKILL.md`)**:
19
+ - Generates native `SKILL.md` bundles prefixed with `rnex-` in `.gemini/skills/` with YAML frontmatter for Gemini and Antigravity skill discovery.
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,7 +23,7 @@ Active plugins are mirrored into each active member repository under `repos/<nam
23
23
  Repo Nexus decouples functional plugins from AI provider plugins:
24
24
  - **Core Skills (`toolkit/skills/` $\rightarrow$ `.rnex/skills/`)**: Workspace-level capabilities owned by Repo Nexus core.
25
25
  - **Plugin Skills (`toolkit/plugins/<plugin>/skills/` $\rightarrow$ `.rnex/plugins/<plugin>/skills/`)**: Scoped domain skills owned exclusively by individual plugins.
26
- - **User Skills (`rnex-<name>.md`)**: Provider plugins (`claude`, `gemini`, `cursor`, and `windsurf`) generate zero-logic user skill pointers in active provider directories (`.cursor/rules/`, `.claude/skills/`, `.gemini/skills/`, `.windsurf/rules/`) that redirect AI assistants directly to the underlying agentic skills in `.rnex/`.
26
+ - **User Skills**: Provider plugins (`copilot`, `claude`, `gemini`, `cursor`, and `windsurf`) project zero-logic user skill pointers into active provider directories using native `SKILL.md` bundles with YAML frontmatter in skill directories (`.github/skills/`, `.claude/skills/`, `.gemini/skills/`) and flat files in rule directories (`.cursor/rules/`, `.windsurf/rules/`), redirecting AI assistants directly to the underlying agentic skills in `.rnex/`.
27
27
 
28
28
  ### 4. Non-Destructive Delimited Merging
29
29
  When plugins update root instruction files (`AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `.cursorrules`, `.windsurfrules`), Repo Nexus isolates auto-managed routing between explicit delimiters:
package/lib/ai.sh CHANGED
@@ -370,21 +370,63 @@ fi
370
370
  rnex_register_user_skill() {
371
371
  skill_name="$1"
372
372
  target_path="$2"
373
- for provider_dir in $RNEX_PROVIDER_SKILL_DIRS; do
374
- mkdir -p "$RNEX_ROOT/$provider_dir"
375
- cat << EOF > "$RNEX_ROOT/$provider_dir/rnex-${skill_name}.md"
373
+ _dirs="${RNEX_PROVIDER_SKILL_DIRS:-}"
374
+ _r="${RNEX_ROOT:-.}"
375
+
376
+ _target_file=""
377
+ if [ -f "$_r/$target_path" ]; then
378
+ _target_file="$_r/$target_path"
379
+ elif [ -f "$target_path" ]; then
380
+ _target_file="$target_path"
381
+ fi
382
+
383
+ _skill_desc=""
384
+ if [ -n "$_target_file" ]; then
385
+ _skill_desc="$(awk 'NF && !/^#/ { print; exit }' "$_target_file" 2>/dev/null)"
386
+ fi
387
+ if [ -z "$_skill_desc" ]; then
388
+ _skill_desc="Repo Nexus agentic skill protocol for ${skill_name}."
389
+ fi
390
+ _skill_desc="$(printf '%s' "$_skill_desc" | tr '\n\r' ' ' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/"/\\"/g')"
391
+
392
+ for provider_dir in $_dirs; do
393
+ case "$provider_dir" in
394
+ *rules*)
395
+ mkdir -p "$_r/$provider_dir"
396
+ rm -rf "$_r/$provider_dir/rnex-${skill_name}" 2>/dev/null || true
397
+ cat << EOF > "$_r/$provider_dir/rnex-${skill_name}.md"
376
398
  # User Skill: rnex-${skill_name}
377
399
 
378
400
  CRITICAL: Do not execute inline heuristics. Read and strictly follow the agentic skill protocol at:
379
401
  \`${target_path}\`
380
402
  EOF
403
+ ;;
404
+ *)
405
+ mkdir -p "$_r/$provider_dir/rnex-${skill_name}"
406
+ rm -f "$_r/$provider_dir/rnex-${skill_name}.md" 2>/dev/null || true
407
+ cat << EOF > "$_r/$provider_dir/rnex-${skill_name}/SKILL.md"
408
+ ---
409
+ name: rnex-${skill_name}
410
+ description: "${_skill_desc}"
411
+ ---
412
+
413
+ # User Skill: rnex-${skill_name}
414
+
415
+ CRITICAL: Do not execute inline heuristics. Read and strictly follow the agentic skill protocol at:
416
+ \`${target_path}\`
417
+ EOF
418
+ ;;
419
+ esac
381
420
  done
382
421
  }
383
422
 
384
423
  rnex_unregister_user_skill() {
385
424
  skill_name="$1"
386
- for provider_dir in $RNEX_PROVIDER_SKILL_DIRS; do
387
- rm -f "$RNEX_ROOT/$provider_dir/rnex-${skill_name}.md"
425
+ _dirs="${RNEX_PROVIDER_SKILL_DIRS:-}"
426
+ _r="${RNEX_ROOT:-.}"
427
+ for provider_dir in $_dirs; do
428
+ rm -f "$_r/$provider_dir/rnex-${skill_name}.md"
429
+ rm -rf "$_r/$provider_dir/rnex-${skill_name}"
388
430
  done
389
431
  }
390
432
  ENV_EOF
@@ -417,14 +459,51 @@ rnex_register_user_skill() {
417
459
  target_path="$2"
418
460
  _dirs="${RNEX_PROVIDER_SKILL_DIRS:-$(get_active_provider_skill_dirs)}"
419
461
  _r="${NEXUS_DIR:-${RNEX_ROOT:-.}}"
462
+
463
+ _target_file=""
464
+ if [ -f "$_r/$target_path" ]; then
465
+ _target_file="$_r/$target_path"
466
+ elif [ -f "$target_path" ]; then
467
+ _target_file="$target_path"
468
+ fi
469
+
470
+ _skill_desc=""
471
+ if [ -n "$_target_file" ]; then
472
+ _skill_desc="$(awk 'NF && !/^#/ { print; exit }' "$_target_file" 2>/dev/null)"
473
+ fi
474
+ if [ -z "$_skill_desc" ]; then
475
+ _skill_desc="Repo Nexus agentic skill protocol for ${skill_name}."
476
+ fi
477
+ _skill_desc="$(printf '%s' "$_skill_desc" | tr '\n\r' ' ' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/"/\\"/g')"
478
+
420
479
  for provider_dir in $_dirs; do
421
- mkdir -p "$_r/$provider_dir"
422
- cat << EOF > "$_r/$provider_dir/rnex-${skill_name}.md"
480
+ case "$provider_dir" in
481
+ *rules*)
482
+ mkdir -p "$_r/$provider_dir"
483
+ rm -rf "$_r/$provider_dir/rnex-${skill_name}" 2>/dev/null || true
484
+ cat << EOF > "$_r/$provider_dir/rnex-${skill_name}.md"
485
+ # User Skill: rnex-${skill_name}
486
+
487
+ CRITICAL: Do not execute inline heuristics. Read and strictly follow the agentic skill protocol at:
488
+ \`${target_path}\`
489
+ EOF
490
+ ;;
491
+ *)
492
+ mkdir -p "$_r/$provider_dir/rnex-${skill_name}"
493
+ rm -f "$_r/$provider_dir/rnex-${skill_name}.md" 2>/dev/null || true
494
+ cat << EOF > "$_r/$provider_dir/rnex-${skill_name}/SKILL.md"
495
+ ---
496
+ name: rnex-${skill_name}
497
+ description: "${_skill_desc}"
498
+ ---
499
+
423
500
  # User Skill: rnex-${skill_name}
424
501
 
425
502
  CRITICAL: Do not execute inline heuristics. Read and strictly follow the agentic skill protocol at:
426
503
  \`${target_path}\`
427
504
  EOF
505
+ ;;
506
+ esac
428
507
  done
429
508
  }
430
509
 
@@ -435,6 +514,7 @@ rnex_unregister_user_skill() {
435
514
  _r="${NEXUS_DIR:-${RNEX_ROOT:-.}}"
436
515
  for provider_dir in $_dirs; do
437
516
  rm -f "$_r/$provider_dir/rnex-${skill_name}.md"
517
+ rm -rf "$_r/$provider_dir/rnex-${skill_name}"
438
518
  done
439
519
  }
440
520
 
@@ -444,8 +524,7 @@ clean_provider_user_skills() {
444
524
  rm -f "$_sk_dir"/rnex-*.md 2>/dev/null || true
445
525
  for _d in "$_sk_dir"/rnex-*; do
446
526
  [ -d "$_d" ] || continue
447
- rm -f "$_d/SKILL.md" 2>/dev/null || true
448
- rmdir "$_d" 2>/dev/null || true
527
+ rm -rf "$_d" 2>/dev/null || true
449
528
  done
450
529
  rmdir "$_sk_dir" 2>/dev/null || true
451
530
  }
@@ -165,15 +165,18 @@ cmd_status() {
165
165
  if [ -d "$NEXUS_DIR/.cursor/rules" ] && ls "$NEXUS_DIR/.cursor/rules"/rnex-*.md >/dev/null 2>&1; then
166
166
  printf ' %b✓%b %s %b(Cursor user skills)%b\n' "$_G" "$_NC" ".cursor/rules/" "$_DIM" "$_NC"
167
167
  fi
168
- if [ -d "$NEXUS_DIR/.claude/skills" ] && ls "$NEXUS_DIR/.claude/skills"/rnex-*.md >/dev/null 2>&1; then
168
+ if [ -d "$NEXUS_DIR/.claude/skills" ] && { ls "$NEXUS_DIR/.claude/skills"/rnex-*.md >/dev/null 2>&1 || ls -d "$NEXUS_DIR/.claude/skills"/rnex-* >/dev/null 2>&1; }; then
169
169
  printf ' %b✓%b %s %b(Claude user skills)%b\n' "$_G" "$_NC" ".claude/skills/" "$_DIM" "$_NC"
170
170
  fi
171
171
  if [ -d "$NEXUS_DIR/.windsurf/rules" ] && ls "$NEXUS_DIR/.windsurf/rules"/rnex-*.md >/dev/null 2>&1; then
172
172
  printf ' %b✓%b %s %b(Windsurf user skills)%b\n' "$_G" "$_NC" ".windsurf/rules/" "$_DIM" "$_NC"
173
173
  fi
174
- if [ -d "$NEXUS_DIR/.gemini/skills" ] && ls "$NEXUS_DIR/.gemini/skills"/rnex-*.md >/dev/null 2>&1; then
174
+ if [ -d "$NEXUS_DIR/.gemini/skills" ] && { ls "$NEXUS_DIR/.gemini/skills"/rnex-*.md >/dev/null 2>&1 || ls -d "$NEXUS_DIR/.gemini/skills"/rnex-* >/dev/null 2>&1; }; then
175
175
  printf ' %b✓%b %s %b(Gemini user skills)%b\n' "$_G" "$_NC" ".gemini/skills/" "$_DIM" "$_NC"
176
176
  fi
177
+ if [ -d "$NEXUS_DIR/.github/skills" ] && { ls "$NEXUS_DIR/.github/skills"/rnex-*.md >/dev/null 2>&1 || ls -d "$NEXUS_DIR/.github/skills"/rnex-* >/dev/null 2>&1; }; then
178
+ printf ' %b✓%b %s %b(Copilot user skills)%b\n' "$_G" "$_NC" ".github/skills/" "$_DIM" "$_NC"
179
+ fi
177
180
  printf '\n'
178
181
 
179
182
  printf '%bActive Plugins:%b\n' "$_BOLD" "$_NC"
package/lib/hooks.sh CHANGED
@@ -62,14 +62,49 @@ run_hook() {
62
62
  rnex_register_user_skill() {
63
63
  skill_name="$1"
64
64
  target_path="$2"
65
+ _target_file=""
66
+ if [ -f "$RNEX_ROOT/$target_path" ]; then
67
+ _target_file="$RNEX_ROOT/$target_path"
68
+ elif [ -f "$target_path" ]; then
69
+ _target_file="$target_path"
70
+ fi
71
+ _skill_desc=""
72
+ if [ -n "$_target_file" ]; then
73
+ _skill_desc="$(awk 'NF && !/^#/ { print; exit }' "$_target_file" 2>/dev/null)"
74
+ fi
75
+ if [ -z "$_skill_desc" ]; then
76
+ _skill_desc="Repo Nexus agentic skill protocol for ${skill_name}."
77
+ fi
78
+ _skill_desc="$(printf '%s' "$_skill_desc" | tr '\n\r' ' ' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/"/\\"/g')"
79
+
65
80
  for provider_dir in $RNEX_PROVIDER_SKILL_DIRS; do
66
- mkdir -p "$RNEX_ROOT/$provider_dir"
67
- cat << EOF > "$RNEX_ROOT/$provider_dir/rnex-${skill_name}.md"
81
+ case "$provider_dir" in
82
+ *rules*)
83
+ mkdir -p "$RNEX_ROOT/$provider_dir"
84
+ rm -rf "$RNEX_ROOT/$provider_dir/rnex-${skill_name}" 2>/dev/null || true
85
+ cat << EOF > "$RNEX_ROOT/$provider_dir/rnex-${skill_name}.md"
86
+ # User Skill: rnex-${skill_name}
87
+
88
+ CRITICAL: Do not execute inline heuristics. Read and strictly follow the agentic skill protocol at:
89
+ \`${target_path}\`
90
+ EOF
91
+ ;;
92
+ *)
93
+ mkdir -p "$RNEX_ROOT/$provider_dir/rnex-${skill_name}"
94
+ rm -f "$RNEX_ROOT/$provider_dir/rnex-${skill_name}.md" 2>/dev/null || true
95
+ cat << EOF > "$RNEX_ROOT/$provider_dir/rnex-${skill_name}/SKILL.md"
96
+ ---
97
+ name: rnex-${skill_name}
98
+ description: "${_skill_desc}"
99
+ ---
100
+
68
101
  # User Skill: rnex-${skill_name}
69
102
 
70
103
  CRITICAL: Do not execute inline heuristics. Read and strictly follow the agentic skill protocol at:
71
104
  \`${target_path}\`
72
105
  EOF
106
+ ;;
107
+ esac
73
108
  done
74
109
  }
75
110
 
@@ -78,6 +113,7 @@ EOF
78
113
  skill_name="$1"
79
114
  for provider_dir in $RNEX_PROVIDER_SKILL_DIRS; do
80
115
  rm -f "$RNEX_ROOT/$provider_dir/rnex-${skill_name}.md"
116
+ rm -rf "$RNEX_ROOT/$provider_dir/rnex-${skill_name}"
81
117
  done
82
118
  }
83
119
  set -- "$@"
@@ -141,14 +177,49 @@ run_plugin_hook() {
141
177
  rnex_register_user_skill() {
142
178
  skill_name="$1"
143
179
  target_path="$2"
180
+ _target_file=""
181
+ if [ -f "$RNEX_ROOT/$target_path" ]; then
182
+ _target_file="$RNEX_ROOT/$target_path"
183
+ elif [ -f "$target_path" ]; then
184
+ _target_file="$target_path"
185
+ fi
186
+ _skill_desc=""
187
+ if [ -n "$_target_file" ]; then
188
+ _skill_desc="$(awk 'NF && !/^#/ { print; exit }' "$_target_file" 2>/dev/null)"
189
+ fi
190
+ if [ -z "$_skill_desc" ]; then
191
+ _skill_desc="Repo Nexus agentic skill protocol for ${skill_name}."
192
+ fi
193
+ _skill_desc="$(printf '%s' "$_skill_desc" | tr '\n\r' ' ' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/"/\\"/g')"
194
+
144
195
  for provider_dir in $RNEX_PROVIDER_SKILL_DIRS; do
145
- mkdir -p "$RNEX_ROOT/$provider_dir"
146
- cat << EOF > "$RNEX_ROOT/$provider_dir/rnex-${skill_name}.md"
196
+ case "$provider_dir" in
197
+ *rules*)
198
+ mkdir -p "$RNEX_ROOT/$provider_dir"
199
+ rm -rf "$RNEX_ROOT/$provider_dir/rnex-${skill_name}" 2>/dev/null || true
200
+ cat << EOF > "$RNEX_ROOT/$provider_dir/rnex-${skill_name}.md"
201
+ # User Skill: rnex-${skill_name}
202
+
203
+ CRITICAL: Do not execute inline heuristics. Read and strictly follow the agentic skill protocol at:
204
+ \`${target_path}\`
205
+ EOF
206
+ ;;
207
+ *)
208
+ mkdir -p "$RNEX_ROOT/$provider_dir/rnex-${skill_name}"
209
+ rm -f "$RNEX_ROOT/$provider_dir/rnex-${skill_name}.md" 2>/dev/null || true
210
+ cat << EOF > "$RNEX_ROOT/$provider_dir/rnex-${skill_name}/SKILL.md"
211
+ ---
212
+ name: rnex-${skill_name}
213
+ description: "${_skill_desc}"
214
+ ---
215
+
147
216
  # User Skill: rnex-${skill_name}
148
217
 
149
218
  CRITICAL: Do not execute inline heuristics. Read and strictly follow the agentic skill protocol at:
150
219
  \`${target_path}\`
151
220
  EOF
221
+ ;;
222
+ esac
152
223
  done
153
224
  }
154
225
 
@@ -157,6 +228,7 @@ EOF
157
228
  skill_name="$1"
158
229
  for provider_dir in $RNEX_PROVIDER_SKILL_DIRS; do
159
230
  rm -f "$RNEX_ROOT/$provider_dir/rnex-${skill_name}.md"
231
+ rm -rf "$RNEX_ROOT/$provider_dir/rnex-${skill_name}"
160
232
  done
161
233
  }
162
234
  set -- "$@"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "repo-nexus",
3
- "version": "0.7.7",
3
+ "version": "0.7.8",
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",