repo-nexus 0.5.4 → 0.5.6
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 +17 -0
- package/README.md +25 -2
- package/docs/CLI.md +9 -6
- package/docs/rnex.example.yaml +13 -5
- package/package.json +1 -1
- package/rnex +651 -57
- package/toolkit/plugins/copilot/README.md +37 -0
- package/toolkit/plugins/copilot/instructions/copilot-integration.md +29 -0
- package/toolkit/plugins/copilot/plugin.yaml +7 -0
- package/toolkit/plugins/karpathy-llm/agents/wiki-curator.agent.md +8 -0
- package/toolkit/plugins/karpathy-llm/prompts/wiki-ingest.md +10 -0
- package/toolkit/plugins/karpathy-llm/prompts/wiki-lint.md +10 -0
- package/toolkit/plugins/karpathy-llm/skills/wiki-ingest/SKILL.md +14 -0
- package/toolkit/plugins/karpathy-llm/skills/wiki-lint/SKILL.md +14 -0
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
16
16
|
- Interactive `rnex init` determines and records `git_hooks` preference upfront in new workspaces.
|
|
17
17
|
- Workspace schema migration in `rnex update` and `rnex fix -y` non-destructively inserts `git_hooks` into older configurations.
|
|
18
18
|
- `rnex status` and `rnex hooks status` display configuration state alongside runtime Git hooks status.
|
|
19
|
+
- **Modular GitHub Copilot Plugin & Extensible Provider Sync (`plugins: copilot: ...`)**:
|
|
20
|
+
- Encapsulated GitHub Copilot integration as a built-in Repo Nexus plugin (`copilot`) located in `toolkit/plugins/copilot/`.
|
|
21
|
+
- Extensible configuration options per provider under `plugins:` in `rnex.yaml` and `.local.rnex.yaml`:
|
|
22
|
+
- `prompts: true|false`: Syncs operational prompts into `.github/prompts/*.prompt.md` with YAML frontmatter for VS Code Copilot Chat prompt picker & slash commands.
|
|
23
|
+
- `skills: true|false`: Syncs agent skills into `.github/skills/<name>/SKILL.md` for Copilot Agent mode & `gh skill`.
|
|
24
|
+
- `instructions: true|false`: Synthesizes workspace routing and active plugin guidelines into `.github/copilot-instructions.md`, preserving manual user instructions outside `<!-- REPO-NEXUS -->` markers.
|
|
25
|
+
- `agents: true|false`: Syncs active plugin custom agents into `.github/agents/*.agent.md` and Copilot skills.
|
|
26
|
+
- `enabled: false`: Allows local machine overrides in `.local.rnex.yaml` without altering team configuration.
|
|
27
|
+
- Decoupled cross-plugin asset discovery: `copilot` provider inspects all active plugins (e.g. `karpathy-llm`) and mirrors their prompts, workflows, skills, agents, and guidelines without introducing plugin dependencies.
|
|
28
|
+
- CLI management via `rnex plugin enable [--local] copilot`, `rnex plugin disable [--local] copilot`, and `rnex plugin info copilot`.
|
|
29
|
+
- Added `--copilot` initialization flag to `rnex init` enabling the plugin in newly generated workspaces.
|
|
30
|
+
- Clean reconciliation in `rnex fix`: safely removes `.github/prompts/`, `.github/skills/`, `.github/agents/`, and `.github/copilot-instructions.md` when disabled or when specific target options are toggled off.
|
|
31
|
+
- Diagnostics and configurable options reporting integrated into `rnex status`.
|
|
19
32
|
|
|
20
33
|
### Fixed
|
|
21
34
|
- **Git Hooks Self-Rewrite & Wrapper Preservation**:
|
|
@@ -24,6 +37,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
24
37
|
- Preserved custom / repository-owned wrappers in `.rnex/hooks/` that are not auto-managed by `rnex`.
|
|
25
38
|
- Added `cmp -s` check before writing hook files to eliminate unnecessary file churn and in-place overwrites.
|
|
26
39
|
- Automatically chain to existing repository-owned `.githooks/` scripts if present.
|
|
40
|
+
- **Track Workspace `.rnex/` in Version Control**:
|
|
41
|
+
- Removed `.rnex/` from `.gitignore` templates and generation.
|
|
42
|
+
- `reconcile_gitignore` and `rnex fix` actively strip legacy `.rnex/` ignore rules from `.gitignore` so that team prompts (`.rnex/prompts/`), plugins (`.rnex/plugins/`), and hooks (`.rnex/hooks/`) are tracked in git.
|
|
43
|
+
- Updated `rnex status` to expect `.rnex/` to remain tracked by git.
|
|
27
44
|
|
|
28
45
|
## [0.5.1] - 2026-10-08
|
|
29
46
|
|
package/README.md
CHANGED
|
@@ -215,7 +215,25 @@ rnex plugin enable karpathy-llm
|
|
|
215
215
|
rnex plugin disable karpathy-llm
|
|
216
216
|
```
|
|
217
217
|
|
|
218
|
-
### Built-in
|
|
218
|
+
### Built-in Plugins
|
|
219
|
+
|
|
220
|
+
#### 1. `copilot`
|
|
221
|
+
The `copilot` plugin provides GitHub Copilot integration, automatically mirroring workspace and active plugin assets:
|
|
222
|
+
* **Prompts (`.github/prompts/*.prompt.md`)**: Formatted with YAML frontmatter (`name`, `description`) for the VS Code Copilot Chat prompt picker and slash commands.
|
|
223
|
+
* **Agent Skills (`.github/skills/<name>/SKILL.md`)**: Configured for GitHub Copilot Agent mode and `gh skill`.
|
|
224
|
+
* **Custom Agents (`.github/agents/*.agent.md`)**: Active plugins' agent definitions mirrored for Copilot workspace custom agents.
|
|
225
|
+
* **Instructions (`.github/copilot-instructions.md`)**: Synthesized workspace routing and active plugin guidelines, preserving manual user instructions.
|
|
226
|
+
* **Configurable Options**:
|
|
227
|
+
```yaml
|
|
228
|
+
plugins:
|
|
229
|
+
copilot:
|
|
230
|
+
prompts: true # mirror prompts to .github/prompts/*.prompt.md (default: true)
|
|
231
|
+
skills: true # mirror skills to .github/skills/<name>/SKILL.md (default: true)
|
|
232
|
+
instructions: true # mirror guidelines to .github/copilot-instructions.md (default: true)
|
|
233
|
+
agents: true # mirror custom agents to .github/agents/*.agent.md (default: true)
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
#### 2. `karpathy-llm`
|
|
219
237
|
The `karpathy-llm` plugin packages Andrej Karpathy's verified LLM agent design patterns, context engineering principles, and the autonomous **Karpathy LLM Wiki** architecture:
|
|
220
238
|
* **The 4 Cardinal Agent Rules** (`.rnex/plugins/karpathy-llm/rules/behavioral.md`):
|
|
221
239
|
1. *Think Before Coding:* Formulate explicit assumptions, boundary checks, and trade-offs before writing code.
|
|
@@ -248,8 +266,13 @@ repos_dir: ./repos
|
|
|
248
266
|
# Automated workspace Git hooks (default: true)
|
|
249
267
|
git_hooks: true
|
|
250
268
|
|
|
251
|
-
# Workspace plugins
|
|
269
|
+
# Workspace plugins and tool integrations
|
|
252
270
|
plugins:
|
|
271
|
+
copilot:
|
|
272
|
+
prompts: true
|
|
273
|
+
skills: true
|
|
274
|
+
instructions: true
|
|
275
|
+
agents: true
|
|
253
276
|
karpathy-llm: {}
|
|
254
277
|
|
|
255
278
|
# Member repositories (enabled by default)
|
package/docs/CLI.md
CHANGED
|
@@ -72,15 +72,18 @@ rnex init [options] [directory]
|
|
|
72
72
|
- `--code-workspace [filename]`: Enable VS Code / Cursor multi-root workspace file generation. Defaults to `<directory-name>.code-workspace` if omitted.
|
|
73
73
|
- `--hooks`: Force-enable automated Git hooks setup during initialization.
|
|
74
74
|
- `--no-hooks`: Skip Git hooks configuration during initialization.
|
|
75
|
+
- `--copilot`: Enable GitHub Copilot integration plugin (mirrors prompts, skills, agents, and instructions to `.github/`).
|
|
76
|
+
- `--no-copilot`: Skip GitHub Copilot plugin (default).
|
|
75
77
|
|
|
76
78
|
#### What it does:
|
|
77
79
|
1. Creates `rnex.yaml` with schema versioning (`version: <version>`), `repos_dir: ./repos`, and configured defaults.
|
|
78
80
|
2. Merges Repo Nexus routing instructions (`<!-- REPO-NEXUS:START -->` ... `<!-- REPO-NEXUS:END -->`) into the target AI instructions file.
|
|
79
81
|
3. Creates `./repos/` directory with a tracked `.gitkeep`.
|
|
80
82
|
4. Creates `.rnex/`, `.rnex/plugins/`, and copies standardized prompts to `.rnex/prompts/`.
|
|
81
|
-
5. Reconciles `.gitignore` to ensure `repos
|
|
83
|
+
5. Reconciles `.gitignore` to ensure `repos/` and `.local.rnex.yaml` are never tracked by the meta-repo (while keeping `.rnex/` tracked).
|
|
82
84
|
6. Generates a multi-root `.code-workspace` file if configured.
|
|
83
85
|
7. Prompts to configure automated workspace Git hooks (`core.hooksPath = .rnex/hooks`) if inside a Git repository.
|
|
86
|
+
8. Configures enabled plugins (including `copilot` if requested).
|
|
84
87
|
|
|
85
88
|
#### Examples:
|
|
86
89
|
```sh
|
|
@@ -110,7 +113,7 @@ rnex status
|
|
|
110
113
|
#### What it reports:
|
|
111
114
|
- **Configuration & Versions**: Path, version tag, and load status of `rnex.yaml` and `.local.rnex.yaml`.
|
|
112
115
|
- **Paths**: Clones directory (`repos_dir`) and primary AI instructions file.
|
|
113
|
-
- **Git Integration**: Validation that `.gitignore` ignores `repos
|
|
116
|
+
- **Git Integration**: Validation that `.gitignore` ignores `repos/` and local files (while keeping `.rnex/` tracked), and whether `core.hooksPath` points to `.rnex/hooks`.
|
|
114
117
|
- **AI Routing Context**: Existence and routing block markers in `AGENTS.md`, `CLAUDE.md`, `.code-workspace`, and prompts catalog (`.rnex/prompts/index.md`).
|
|
115
118
|
- **Active Plugins**: List of enabled plugins, scoped versions, and asset directories.
|
|
116
119
|
- **Member Repositories**: Every registered repository, enabled/disabled state, clone health, and active Git branch.
|
|
@@ -353,14 +356,14 @@ Unsets `core.hooksPath` in Git configuration, removes `.rnex/hooks/`, and record
|
|
|
353
356
|
Repo Nexus features a modular plugin architecture where plugin rules, instructions, and templates are scoped strictly under `.rnex/plugins/<plugin-name>/`.
|
|
354
357
|
|
|
355
358
|
```sh
|
|
356
|
-
rnex plugin <list|info|enable|disable> [name]
|
|
359
|
+
rnex plugin <list|info|enable|disable> [options] [name]
|
|
357
360
|
```
|
|
358
361
|
|
|
359
362
|
### Subcommands
|
|
360
363
|
- **`rnex plugin list`**: Displays all available plugins distributed with `rnex` and highlights enabled plugins.
|
|
361
|
-
- **`rnex plugin info <name>`**: Shows description, version, scoped directory, and external template paths for a plugin.
|
|
362
|
-
- **`rnex plugin enable <name>`**: Enables a plugin in `rnex.yaml
|
|
363
|
-
- **`rnex plugin disable <name>`**: Removes plugin assets from `.rnex/plugins/<name>/` and disables the plugin in `rnex.yaml`.
|
|
364
|
+
- **`rnex plugin info <name>`**: Shows description, version, configurable options, scoped directory, and external template paths for a plugin.
|
|
365
|
+
- **`rnex plugin enable [--local] <name>`**: Enables a plugin in `rnex.yaml` (or `.local.rnex.yaml` with `--local`), copies assets to `.rnex/plugins/<name>/`, and reconciles workspace files.
|
|
366
|
+
- **`rnex plugin disable [--local] <name>`**: Removes plugin assets from `.rnex/plugins/<name>/` and disables the plugin in `rnex.yaml` (or overrides with `enabled: false` in `.local.rnex.yaml` with `--local`).
|
|
364
367
|
|
|
365
368
|
---
|
|
366
369
|
|
package/docs/rnex.example.yaml
CHANGED
|
@@ -74,21 +74,29 @@ code_workspace: false
|
|
|
74
74
|
git_hooks: true
|
|
75
75
|
|
|
76
76
|
# ------------------------------------------------------------------------------
|
|
77
|
-
# plugins — Workspace plugins and AI instruction packs
|
|
77
|
+
# plugins — Workspace plugins, tool integrations, and AI instruction packs
|
|
78
78
|
# ------------------------------------------------------------------------------
|
|
79
79
|
# Plugins extend your workspace with curated AI guidelines, context rules,
|
|
80
|
-
#
|
|
80
|
+
# tool provider integrations (e.g. GitHub Copilot), and templates.
|
|
81
81
|
#
|
|
82
82
|
# Manage plugins with:
|
|
83
|
-
# rnex plugin list
|
|
84
|
-
# rnex plugin enable <name>
|
|
85
|
-
# rnex plugin disable <name>
|
|
83
|
+
# rnex plugin list # View available and active plugins
|
|
84
|
+
# rnex plugin enable [--local] <name> # Enable plugin (global or local override)
|
|
85
|
+
# rnex plugin disable [--local] <name> # Disable plugin from workspace
|
|
86
|
+
# rnex plugin info <name> # View plugin details & configurable options
|
|
86
87
|
#
|
|
87
88
|
# Built-in plugins:
|
|
89
|
+
# copilot — GitHub Copilot integration: mirrors operational prompts, skills,
|
|
90
|
+
# agents, and synthesized instructions into .github/
|
|
88
91
|
# karpathy-llm — Andrej Karpathy's agent behavioral principles,
|
|
89
92
|
# context engineering guidelines, and LLM Wiki architecture
|
|
90
93
|
|
|
91
94
|
plugins:
|
|
95
|
+
# copilot:
|
|
96
|
+
# prompts: true # mirror prompts to .github/prompts/*.prompt.md (default: true)
|
|
97
|
+
# skills: true # mirror skills to .github/skills/<name>/SKILL.md (default: true)
|
|
98
|
+
# instructions: true # mirror instructions to .github/copilot-instructions.md (default: true)
|
|
99
|
+
# agents: true # mirror custom agents to .github/agents/*.agent.md (default: true)
|
|
92
100
|
# karpathy-llm: {}
|
|
93
101
|
|
|
94
102
|
# ------------------------------------------------------------------------------
|
package/package.json
CHANGED
package/rnex
CHANGED
|
@@ -147,6 +147,7 @@ require_workspace() {
|
|
|
147
147
|
_load_ai_instructions_file
|
|
148
148
|
_load_code_workspace
|
|
149
149
|
_load_git_hooks
|
|
150
|
+
_load_copilot
|
|
150
151
|
log_info "Using workspace at ${_BOLD}$NEXUS_DIR${_NC} ${_DIM}(via config: $WORKSPACE_YAML)${_NC}"
|
|
151
152
|
return 0
|
|
152
153
|
fi
|
|
@@ -177,6 +178,7 @@ require_workspace() {
|
|
|
177
178
|
_load_ai_instructions_file
|
|
178
179
|
_load_code_workspace
|
|
179
180
|
_load_git_hooks
|
|
181
|
+
_load_copilot
|
|
180
182
|
|
|
181
183
|
log_info "Using workspace at ${_BOLD}$NEXUS_DIR${_NC} ${_DIM}($(basename "$WORKSPACE_YAML") found)${_NC}"
|
|
182
184
|
}
|
|
@@ -268,6 +270,18 @@ _load_git_hooks() {
|
|
|
268
270
|
GIT_HOOKS_CONFIG="$_gh"
|
|
269
271
|
}
|
|
270
272
|
|
|
273
|
+
_load_copilot() {
|
|
274
|
+
_cp=""
|
|
275
|
+
if [ -f "$WORKSPACE_LOCAL_YAML" ]; then
|
|
276
|
+
_cp="$(awk '/^(copilot|copilot_sync):/ { sub(/^[a-zA-Z0-9_]+:[ ]*/, ""); sub(/[ ]*#.*/, ""); val=$0 } END { if (val) print val }' "$WORKSPACE_LOCAL_YAML")"
|
|
277
|
+
fi
|
|
278
|
+
if [ -z "$_cp" ] && [ -f "$WORKSPACE_YAML" ]; then
|
|
279
|
+
_cp="$(awk '/^(copilot|copilot_sync):/ { sub(/^[a-zA-Z0-9_]+:[ ]*/, ""); sub(/[ ]*#.*/, ""); val=$0 } END { if (val) print val }' "$WORKSPACE_YAML")"
|
|
280
|
+
fi
|
|
281
|
+
_cp="$(echo "$_cp" | tr -d " \t\r\n'\"")"
|
|
282
|
+
COPILOT_CONFIG="$_cp"
|
|
283
|
+
}
|
|
284
|
+
|
|
271
285
|
# ---- YAML Parser / Manipulator (for rnex.yaml & .local.rnex.yaml) ----------
|
|
272
286
|
|
|
273
287
|
_yaml_list_plugins_from_file() {
|
|
@@ -352,22 +366,211 @@ yaml_has_plugin() {
|
|
|
352
366
|
yaml_list_plugins | grep -qx "$1" 2>/dev/null
|
|
353
367
|
}
|
|
354
368
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
369
|
+
yaml_plugin_enabled() {
|
|
370
|
+
_plugin="$1"
|
|
371
|
+
yaml_has_plugin "$_plugin" || return 1
|
|
372
|
+
_val="$(yaml_plugin_get "$_plugin" "enabled")"
|
|
373
|
+
_val="$(printf '%s' "$_val" | tr '[:upper:]' '[:lower:]')"
|
|
374
|
+
case "$_val" in
|
|
375
|
+
false|no|0|disabled|off) return 1 ;;
|
|
376
|
+
*) return 0 ;;
|
|
377
|
+
esac
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
copilot_plugin_enabled() {
|
|
381
|
+
if yaml_plugin_enabled "copilot"; then
|
|
382
|
+
return 0
|
|
383
|
+
fi
|
|
384
|
+
case "$COPILOT_CONFIG" in
|
|
385
|
+
true|yes|1) return 0 ;;
|
|
386
|
+
*) return 1 ;;
|
|
387
|
+
esac
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
copilot_prompts_enabled() {
|
|
391
|
+
copilot_plugin_enabled || return 1
|
|
392
|
+
_val="$(yaml_plugin_get "copilot" "prompts")"
|
|
393
|
+
_val="$(printf '%s' "$_val" | tr '[:upper:]' '[:lower:]')"
|
|
394
|
+
case "$_val" in
|
|
395
|
+
false|no|0|disabled|off) return 1 ;;
|
|
396
|
+
*) return 0 ;;
|
|
397
|
+
esac
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
copilot_skills_enabled() {
|
|
401
|
+
copilot_plugin_enabled || return 1
|
|
402
|
+
_val="$(yaml_plugin_get "copilot" "skills")"
|
|
403
|
+
_val="$(printf '%s' "$_val" | tr '[:upper:]' '[:lower:]')"
|
|
404
|
+
case "$_val" in
|
|
405
|
+
false|no|0|disabled|off) return 1 ;;
|
|
406
|
+
*) return 0 ;;
|
|
407
|
+
esac
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
copilot_instructions_enabled() {
|
|
411
|
+
copilot_plugin_enabled || return 1
|
|
412
|
+
_val="$(yaml_plugin_get "copilot" "instructions")"
|
|
413
|
+
_val="$(printf '%s' "$_val" | tr '[:upper:]' '[:lower:]')"
|
|
414
|
+
case "$_val" in
|
|
415
|
+
false|no|0|disabled|off) return 1 ;;
|
|
416
|
+
*) return 0 ;;
|
|
417
|
+
esac
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
copilot_agents_enabled() {
|
|
421
|
+
copilot_plugin_enabled || return 1
|
|
422
|
+
_val="$(yaml_plugin_get "copilot" "agents")"
|
|
423
|
+
_val="$(printf '%s' "$_val" | tr '[:upper:]' '[:lower:]')"
|
|
424
|
+
case "$_val" in
|
|
425
|
+
false|no|0|disabled|off) return 1 ;;
|
|
426
|
+
*) return 0 ;;
|
|
427
|
+
esac
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
_yaml_plugin_set_in_file() {
|
|
431
|
+
_file="$1"; _plugin="$2"; _field="$3"; _value="$4"
|
|
432
|
+
if [ ! -f "$_file" ]; then
|
|
433
|
+
mkdir -p "$(dirname "$_file")"
|
|
434
|
+
printf 'plugins:\n' > "$_file"
|
|
435
|
+
elif ! grep -q '^plugins:' "$_file" 2>/dev/null; then
|
|
436
|
+
printf '\nplugins:\n' >> "$_file"
|
|
359
437
|
fi
|
|
360
|
-
|
|
438
|
+
|
|
439
|
+
if ! awk -v plugin="$_plugin" '
|
|
440
|
+
/^plugins:[ ]*$/ || /^plugins:[ ]*#/ { in_p=1; next }
|
|
441
|
+
in_p && /^[^ #]/ { in_p=0 }
|
|
442
|
+
in_p && match($0, "^ " plugin ":[ ]*(#.*)?$") { found=1; exit }
|
|
443
|
+
END { exit !found }
|
|
444
|
+
' "$_file" 2>/dev/null; then
|
|
445
|
+
if grep -qE "^ $_plugin:[ ]*(\{\}|\[\])?$" "$_file" 2>/dev/null; then
|
|
446
|
+
_tmp="$(mktemp)"
|
|
447
|
+
awk -v plugin="$_plugin" -v field="$_field" -v value="$_value" '
|
|
448
|
+
match($0, "^ " plugin ":[ ]*(\\{\\}|\\[\\])?$") {
|
|
449
|
+
printf " %s:\n %s: %s\n", plugin, field, value
|
|
450
|
+
next
|
|
451
|
+
}
|
|
452
|
+
{ print }
|
|
453
|
+
' "$_file" > "$_tmp" && mv "$_tmp" "$_file"
|
|
454
|
+
return 0
|
|
455
|
+
fi
|
|
361
456
|
_tmp="$(mktemp)"
|
|
362
|
-
awk -v
|
|
363
|
-
/^plugins
|
|
457
|
+
awk -v plugin="$_plugin" -v field="$_field" -v value="$_value" '
|
|
458
|
+
/^plugins:[ ]*$/ || /^plugins:[ ]*#/ {
|
|
364
459
|
print
|
|
365
|
-
printf " %s:
|
|
460
|
+
printf " %s:\n %s: %s\n", plugin, field, value
|
|
366
461
|
added=1
|
|
367
462
|
next
|
|
368
463
|
}
|
|
369
464
|
{ print }
|
|
370
|
-
|
|
465
|
+
END {
|
|
466
|
+
if (!added) {
|
|
467
|
+
printf "plugins:\n %s:\n %s: %s\n", plugin, field, value
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
' "$_file" > "$_tmp" && mv "$_tmp" "$_file"
|
|
471
|
+
return 0
|
|
472
|
+
fi
|
|
473
|
+
|
|
474
|
+
_tmp="$(mktemp)"
|
|
475
|
+
awk -v plugin="$_plugin" -v field="$_field" -v value="$_value" '
|
|
476
|
+
/^plugins:/ { in_plugins=1; print; next }
|
|
477
|
+
in_plugins && /^[^ #]/ {
|
|
478
|
+
if (in_target && !field_set) {
|
|
479
|
+
printf " %s: %s\n", field, value
|
|
480
|
+
field_set=1
|
|
481
|
+
}
|
|
482
|
+
in_plugins=0; in_target=0
|
|
483
|
+
}
|
|
484
|
+
in_plugins && match($0, "^ " plugin ":[ ]*(#.*)?$") {
|
|
485
|
+
in_target=1; print; next
|
|
486
|
+
}
|
|
487
|
+
in_target && /^ [^ #]/ {
|
|
488
|
+
if (!field_set) {
|
|
489
|
+
printf " %s: %s\n", field, value
|
|
490
|
+
field_set=1
|
|
491
|
+
}
|
|
492
|
+
in_target=0
|
|
493
|
+
}
|
|
494
|
+
in_target && match($0, "^ " field ":") {
|
|
495
|
+
printf " %s: %s\n", field, value
|
|
496
|
+
field_set=1
|
|
497
|
+
next
|
|
498
|
+
}
|
|
499
|
+
{ print }
|
|
500
|
+
END {
|
|
501
|
+
if (in_target && !field_set) {
|
|
502
|
+
printf " %s: %s\n", field, value
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
' "$_file" > "$_tmp" && mv "$_tmp" "$_file"
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
yaml_plugin_set() {
|
|
509
|
+
_plugin="$1"; _field="$2"; _value="$3"
|
|
510
|
+
_yaml_plugin_set_in_file "$WORKSPACE_YAML" "$_plugin" "$_field" "$_value"
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
yaml_plugin_set_local() {
|
|
514
|
+
_plugin="$1"; _field="$2"; _value="$3"
|
|
515
|
+
if [ ! -f "$WORKSPACE_LOCAL_YAML" ]; then
|
|
516
|
+
cat <<'EOF' > "$WORKSPACE_LOCAL_YAML"
|
|
517
|
+
# ==============================================================================
|
|
518
|
+
# .local.rnex.yaml — Repo Nexus Local Configuration (Machine-Specific)
|
|
519
|
+
# ==============================================================================
|
|
520
|
+
# This file is gitignored. Use it to specify local repository paths, overrides,
|
|
521
|
+
# and enable/disable states for this workstation.
|
|
522
|
+
|
|
523
|
+
plugins:
|
|
524
|
+
EOF
|
|
525
|
+
fi
|
|
526
|
+
_yaml_plugin_set_in_file "$WORKSPACE_LOCAL_YAML" "$_plugin" "$_field" "$_value"
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
yaml_enable_plugin() {
|
|
530
|
+
_name="$1"
|
|
531
|
+
_target_file="${2:-$WORKSPACE_YAML}"
|
|
532
|
+
if [ ! -f "$_target_file" ]; then
|
|
533
|
+
printf 'plugins:\n' > "$_target_file"
|
|
534
|
+
elif ! grep -q '^plugins:' "$_target_file" 2>/dev/null; then
|
|
535
|
+
printf '\nplugins:\n' >> "$_target_file"
|
|
536
|
+
fi
|
|
537
|
+
if ! _yaml_list_plugins_from_file "$_target_file" | grep -qx "$_name" 2>/dev/null; then
|
|
538
|
+
_tmp="$(mktemp)"
|
|
539
|
+
if [ "$_name" = "copilot" ]; then
|
|
540
|
+
awk -v name="$_name" '
|
|
541
|
+
/^plugins:[ ]*$/ || /^plugins:[ ]*#/ {
|
|
542
|
+
print
|
|
543
|
+
printf " %s:\n prompts: true\n skills: true\n instructions: true\n agents: true\n", name
|
|
544
|
+
added=1
|
|
545
|
+
next
|
|
546
|
+
}
|
|
547
|
+
{ print }
|
|
548
|
+
END {
|
|
549
|
+
if (!added) {
|
|
550
|
+
printf "plugins:\n %s:\n prompts: true\n skills: true\n instructions: true\n agents: true\n", name
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
' "$_target_file" > "$_tmp" && mv "$_tmp" "$_target_file"
|
|
554
|
+
else
|
|
555
|
+
awk -v name="$_name" '
|
|
556
|
+
/^plugins:[ ]*$/ || /^plugins:[ ]*#/ {
|
|
557
|
+
print
|
|
558
|
+
printf " %s: {}\n", name
|
|
559
|
+
added=1
|
|
560
|
+
next
|
|
561
|
+
}
|
|
562
|
+
{ print }
|
|
563
|
+
END {
|
|
564
|
+
if (!added) {
|
|
565
|
+
printf "plugins:\n %s: {}\n", name
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
' "$_target_file" > "$_tmp" && mv "$_tmp" "$_target_file"
|
|
569
|
+
fi
|
|
570
|
+
else
|
|
571
|
+
if [ -f "$WORKSPACE_LOCAL_YAML" ] && [ "$_target_file" = "$WORKSPACE_LOCAL_YAML" ]; then
|
|
572
|
+
_yaml_plugin_set_in_file "$_target_file" "$_name" "enabled" "true"
|
|
573
|
+
fi
|
|
371
574
|
fi
|
|
372
575
|
}
|
|
373
576
|
|
|
@@ -734,8 +937,8 @@ EOF
|
|
|
734
937
|
_dest_pdir="$_r_rnex/plugins/$_pname"
|
|
735
938
|
mkdir -p "$_dest_pdir"
|
|
736
939
|
|
|
737
|
-
# Copy rules/workflows/instructions into member plugin dir
|
|
738
|
-
for _sub in rules workflows instructions; do
|
|
940
|
+
# Copy rules/workflows/instructions/prompts/skills/agents into member plugin dir
|
|
941
|
+
for _sub in rules workflows instructions prompts skills agents; do
|
|
739
942
|
if [ -d "$_pdir/$_sub" ]; then
|
|
740
943
|
mkdir -p "$_dest_pdir/$_sub"
|
|
741
944
|
cp -r "$_pdir/$_sub"/* "$_dest_pdir/$_sub"/ 2>/dev/null || true
|
|
@@ -846,8 +1049,8 @@ sync_plugins() {
|
|
|
846
1049
|
if [ "$_pdir" != "$_scoped_dest" ]; then
|
|
847
1050
|
mkdir -p "$_scoped_dest"
|
|
848
1051
|
|
|
849
|
-
# Copy rules, workflows, instructions into scoped plugin directory
|
|
850
|
-
for _sub in rules workflows instructions; do
|
|
1052
|
+
# Copy rules, workflows, instructions, prompts, skills, agents into scoped plugin directory
|
|
1053
|
+
for _sub in rules workflows instructions prompts skills agents; do
|
|
851
1054
|
if [ -d "$_pdir/$_sub" ]; then
|
|
852
1055
|
mkdir -p "$_scoped_dest/$_sub"
|
|
853
1056
|
cp -r "$_pdir/$_sub"/* "$_scoped_dest/$_sub"/ 2>/dev/null || true
|
|
@@ -890,14 +1093,11 @@ reconcile_gitignore() {
|
|
|
890
1093
|
repos/*
|
|
891
1094
|
!repos/.gitkeep
|
|
892
1095
|
|
|
893
|
-
# Repo Nexus internal state & cache
|
|
894
|
-
.rnex/
|
|
895
|
-
|
|
896
1096
|
# Local machine-specific configuration
|
|
897
1097
|
$RNEX_LOCAL_CONFIG_FILE
|
|
898
1098
|
.rnex.local.yaml
|
|
899
1099
|
GI_EOF
|
|
900
|
-
log_ok "Created .gitignore (ignoring repos
|
|
1100
|
+
log_ok "Created .gitignore (ignoring repos/ and $RNEX_LOCAL_CONFIG_FILE)"
|
|
901
1101
|
return 0
|
|
902
1102
|
fi
|
|
903
1103
|
|
|
@@ -908,18 +1108,19 @@ GI_EOF
|
|
|
908
1108
|
log_ok "Removed legacy lint trigger counter entries from .gitignore"
|
|
909
1109
|
fi
|
|
910
1110
|
|
|
911
|
-
# 2.
|
|
1111
|
+
# 2. Strip legacy .rnex/ entries if present (.rnex/ contains tracked prompts, plugins, and hooks)
|
|
1112
|
+
if grep -qE '^[ ]*#?[ ]*Repo Nexus internal state' "$_gi" 2>/dev/null || grep -qE '^\.rnex/?$' "$_gi" 2>/dev/null; then
|
|
1113
|
+
_tmp="$(mktemp)"
|
|
1114
|
+
grep -vE '(^[ ]*#?[ ]*Repo Nexus internal state|^\.rnex/?$)' "$_gi" > "$_tmp" && mv "$_tmp" "$_gi"
|
|
1115
|
+
log_ok "Removed .rnex/ from .gitignore (.rnex should be tracked in git)"
|
|
1116
|
+
fi
|
|
1117
|
+
|
|
1118
|
+
# 3. Ensure repos/* is ignored
|
|
912
1119
|
if ! grep -q "^repos" "$_gi" 2>/dev/null; then
|
|
913
1120
|
printf '\n# Member repos (managed by rnex)\nrepos/*\n!repos/.gitkeep\n' >> "$_gi"
|
|
914
1121
|
log_dim "Added repos/* to .gitignore"
|
|
915
1122
|
fi
|
|
916
1123
|
|
|
917
|
-
# 3. Ensure .rnex/ is ignored
|
|
918
|
-
if ! grep -q '^\.rnex/' "$_gi" 2>/dev/null && ! grep -q '^\.rnex$' "$_gi" 2>/dev/null; then
|
|
919
|
-
printf '\n# Repo Nexus internal state & cache\n.rnex/\n' >> "$_gi"
|
|
920
|
-
log_dim "Added .rnex/ to .gitignore"
|
|
921
|
-
fi
|
|
922
|
-
|
|
923
1124
|
# 4. Ensure local config files are ignored
|
|
924
1125
|
if ! grep -qF "$RNEX_LOCAL_CONFIG_FILE" "$_gi" 2>/dev/null; then
|
|
925
1126
|
printf '\n# Local machine-specific configuration\n%s\n' "$RNEX_LOCAL_CONFIG_FILE" >> "$_gi"
|
|
@@ -1132,6 +1333,115 @@ sync_code_workspace() {
|
|
|
1132
1333
|
fi
|
|
1133
1334
|
}
|
|
1134
1335
|
|
|
1336
|
+
sync_copilot_instructions() {
|
|
1337
|
+
_dst_ci="$NEXUS_DIR/.github/copilot-instructions.md"
|
|
1338
|
+
if ! copilot_instructions_enabled; then
|
|
1339
|
+
if [ -f "$_dst_ci" ]; then
|
|
1340
|
+
if grep -q "$AI_MARKER_START" "$_dst_ci" 2>/dev/null; then
|
|
1341
|
+
_non_rnex="$(awk -v s="$AI_MARKER_START" -v e="$AI_MARKER_END" '
|
|
1342
|
+
$0 ~ s { skip=1; next }
|
|
1343
|
+
$0 ~ e { skip=0; next }
|
|
1344
|
+
!skip { print }
|
|
1345
|
+
' "$_dst_ci" | tr -d " \t\r\n")"
|
|
1346
|
+
if [ -z "$_non_rnex" ]; then
|
|
1347
|
+
rm -f "$_dst_ci"
|
|
1348
|
+
else
|
|
1349
|
+
_tmp="$(mktemp)"
|
|
1350
|
+
awk -v s="$AI_MARKER_START" -v e="$AI_MARKER_END" '
|
|
1351
|
+
$0 ~ s { skip=1; next }
|
|
1352
|
+
$0 ~ e { skip=0; next }
|
|
1353
|
+
!skip { print }
|
|
1354
|
+
' "$_dst_ci" > "$_tmp" && mv "$_tmp" "$_dst_ci"
|
|
1355
|
+
fi
|
|
1356
|
+
fi
|
|
1357
|
+
fi
|
|
1358
|
+
return 0
|
|
1359
|
+
fi
|
|
1360
|
+
|
|
1361
|
+
mkdir -p "$NEXUS_DIR/.github"
|
|
1362
|
+
_body_tmp="$(mktemp)"
|
|
1363
|
+
|
|
1364
|
+
{
|
|
1365
|
+
cat <<'EOF'
|
|
1366
|
+
# GitHub Copilot Instructions (Repo Nexus Virtual Meta-Repo)
|
|
1367
|
+
|
|
1368
|
+
This workspace operates as a **Repo Nexus Virtual Meta-Repo** uniting independent repositories.
|
|
1369
|
+
|
|
1370
|
+
## Routing & Operating Protocol
|
|
1371
|
+
1. Inspect `.local.rnex.yaml` when present, then `rnex.yaml`.
|
|
1372
|
+
2. Master operational prompts are indexed at `.rnex/prompts/index.md` (and mirrored in `.github/prompts/`).
|
|
1373
|
+
3. Member repositories reside in `repos/<name>/`. Inspect `repos/<name>/.rnex/` for repository-specific context.
|
|
1374
|
+
4. Perform Git commits directly inside member repository roots (`repos/<name>/`).
|
|
1375
|
+
EOF
|
|
1376
|
+
|
|
1377
|
+
# Append active plugins instructions & rules
|
|
1378
|
+
_active_p="$(yaml_list_plugins)"
|
|
1379
|
+
if [ -n "$_active_p" ]; then
|
|
1380
|
+
printf '\n## Active Plugins & Guidelines\n'
|
|
1381
|
+
echo "$_active_p" | while read -r _pname; do
|
|
1382
|
+
[ -n "$_pname" ] || continue
|
|
1383
|
+
yaml_plugin_enabled "$_pname" || continue
|
|
1384
|
+
[ "$_pname" != "copilot" ] || continue
|
|
1385
|
+
_pdir="$(find_plugin_dir "$_pname" 2>/dev/null || true)"
|
|
1386
|
+
[ -n "$_pdir" ] || continue
|
|
1387
|
+
_pdesc="$(plugin_get_field "$_pdir" "description")"
|
|
1388
|
+
printf '\n### Plugin: %s\n' "$_pname"
|
|
1389
|
+
[ -n "$_pdesc" ] && printf '%s\n\n' "$_pdesc"
|
|
1390
|
+
|
|
1391
|
+
for _rfile in "$_pdir"/rules/*.md "$NEXUS_DIR/.rnex/plugins/$_pname"/rules/*.md; do
|
|
1392
|
+
if [ -f "$_rfile" ]; then
|
|
1393
|
+
printf '#### Rules (%s)\n' "$(basename "$_rfile")"
|
|
1394
|
+
cat "$_rfile"
|
|
1395
|
+
printf '\n'
|
|
1396
|
+
break
|
|
1397
|
+
fi
|
|
1398
|
+
done
|
|
1399
|
+
|
|
1400
|
+
for _ifile in "$_pdir"/instructions/*.md "$NEXUS_DIR/.rnex/plugins/$_pname"/instructions/*.md; do
|
|
1401
|
+
if [ -f "$_ifile" ]; then
|
|
1402
|
+
printf '#### Instructions (%s)\n' "$(basename "$_ifile")"
|
|
1403
|
+
cat "$_ifile"
|
|
1404
|
+
printf '\n'
|
|
1405
|
+
break
|
|
1406
|
+
fi
|
|
1407
|
+
done
|
|
1408
|
+
done
|
|
1409
|
+
fi
|
|
1410
|
+
} > "$_body_tmp"
|
|
1411
|
+
|
|
1412
|
+
if [ ! -f "$_dst_ci" ]; then
|
|
1413
|
+
{
|
|
1414
|
+
printf '%s\n' "$AI_MARKER_START"
|
|
1415
|
+
cat "$_body_tmp"
|
|
1416
|
+
printf '\n%s\n' "$AI_MARKER_END"
|
|
1417
|
+
} > "$_dst_ci"
|
|
1418
|
+
elif grep -q "$AI_MARKER_START" "$_dst_ci" 2>/dev/null; then
|
|
1419
|
+
_tmp="$(mktemp)"
|
|
1420
|
+
awk -v s="$AI_MARKER_START" -v e="$AI_MARKER_END" -v src="$_body_tmp" '
|
|
1421
|
+
$0 ~ s {
|
|
1422
|
+
print s
|
|
1423
|
+
while ((getline line < src) > 0) print line
|
|
1424
|
+
close(src)
|
|
1425
|
+
print e
|
|
1426
|
+
skip=1
|
|
1427
|
+
next
|
|
1428
|
+
}
|
|
1429
|
+
$0 ~ e { skip=0; next }
|
|
1430
|
+
!skip { print }
|
|
1431
|
+
' "$_dst_ci" > "$_tmp" && mv "$_tmp" "$_dst_ci"
|
|
1432
|
+
else
|
|
1433
|
+
_tmp="$(mktemp)"
|
|
1434
|
+
cat "$_dst_ci" > "$_tmp"
|
|
1435
|
+
{
|
|
1436
|
+
printf '\n\n%s\n' "$AI_MARKER_START"
|
|
1437
|
+
cat "$_body_tmp"
|
|
1438
|
+
printf '\n%s\n' "$AI_MARKER_END"
|
|
1439
|
+
} >> "$_tmp"
|
|
1440
|
+
mv "$_tmp" "$_dst_ci"
|
|
1441
|
+
fi
|
|
1442
|
+
rm -f "$_body_tmp"
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1135
1445
|
sync_prompts() {
|
|
1136
1446
|
_src_prompts=""
|
|
1137
1447
|
if [ -d "$SCRIPT_LOCATION/toolkit/prompts" ]; then
|
|
@@ -1152,6 +1462,208 @@ sync_prompts() {
|
|
|
1152
1462
|
_b="$(basename "$_pfile")"
|
|
1153
1463
|
cp -f "$_pfile" "$_dst_prompts/$_b"
|
|
1154
1464
|
done
|
|
1465
|
+
|
|
1466
|
+
# Copilot prompts sync (.github/prompts/*.prompt.md)
|
|
1467
|
+
if copilot_prompts_enabled; then
|
|
1468
|
+
_copilot_prompts="$NEXUS_DIR/.github/prompts"
|
|
1469
|
+
mkdir -p "$_copilot_prompts"
|
|
1470
|
+
|
|
1471
|
+
# Base toolkit prompts
|
|
1472
|
+
for _pfile in "$_src_prompts"/rnex-*.md; do
|
|
1473
|
+
[ -f "$_pfile" ] || continue
|
|
1474
|
+
_pname="$(basename "$_pfile" .md)"
|
|
1475
|
+
_desc="$(awk '
|
|
1476
|
+
/^#/ { in_title=1; next }
|
|
1477
|
+
in_title && /^[A-Za-z]/ { print; exit }
|
|
1478
|
+
' "$_pfile" 2>/dev/null)"
|
|
1479
|
+
[ -n "$_desc" ] || _desc="Repo Nexus prompt for $_pname"
|
|
1480
|
+
|
|
1481
|
+
_dst_cp="$_copilot_prompts/$_pname.prompt.md"
|
|
1482
|
+
{
|
|
1483
|
+
printf -- '---\nname: %s\ndescription: %s\n---\n\n' "$_pname" "$_desc"
|
|
1484
|
+
cat "$_pfile"
|
|
1485
|
+
} > "$_dst_cp"
|
|
1486
|
+
done
|
|
1487
|
+
|
|
1488
|
+
# Active plugins prompts & workflows
|
|
1489
|
+
yaml_list_plugins | while read -r _pname; do
|
|
1490
|
+
[ -n "$_pname" ] || continue
|
|
1491
|
+
yaml_plugin_enabled "$_pname" || continue
|
|
1492
|
+
[ "$_pname" != "copilot" ] || continue
|
|
1493
|
+
_pdir="$(find_plugin_dir "$_pname" 2>/dev/null || true)"
|
|
1494
|
+
[ -n "$_pdir" ] || continue
|
|
1495
|
+
|
|
1496
|
+
for _sub in prompts workflows; do
|
|
1497
|
+
for _s_dir in "$_pdir/$_sub" "$NEXUS_DIR/.rnex/plugins/$_pname/$_sub"; do
|
|
1498
|
+
[ -d "$_s_dir" ] || continue
|
|
1499
|
+
for _pfile in "$_s_dir"/*.md; do
|
|
1500
|
+
[ -f "$_pfile" ] || continue
|
|
1501
|
+
_base="$(basename "$_pfile" .md)"
|
|
1502
|
+
case "$_base" in
|
|
1503
|
+
index|README) continue ;;
|
|
1504
|
+
esac
|
|
1505
|
+
_desc="$(awk '
|
|
1506
|
+
/^#/ { in_title=1; next }
|
|
1507
|
+
in_title && /^[A-Za-z]/ { print; exit }
|
|
1508
|
+
' "$_pfile" 2>/dev/null)"
|
|
1509
|
+
[ -n "$_desc" ] || _desc="Prompt $_base from plugin $_pname"
|
|
1510
|
+
|
|
1511
|
+
_dst_cp="$_copilot_prompts/$_base.prompt.md"
|
|
1512
|
+
{
|
|
1513
|
+
printf -- '---\nname: %s\ndescription: %s\n---\n\n' "$_base" "$_desc"
|
|
1514
|
+
cat "$_pfile"
|
|
1515
|
+
} > "$_dst_cp"
|
|
1516
|
+
done
|
|
1517
|
+
done
|
|
1518
|
+
done
|
|
1519
|
+
done
|
|
1520
|
+
else
|
|
1521
|
+
if [ -d "$NEXUS_DIR/.github/prompts" ]; then
|
|
1522
|
+
rm -f "$NEXUS_DIR/.github/prompts"/*.prompt.md 2>/dev/null || true
|
|
1523
|
+
rmdir "$NEXUS_DIR/.github/prompts" 2>/dev/null || true
|
|
1524
|
+
fi
|
|
1525
|
+
fi
|
|
1526
|
+
|
|
1527
|
+
# Copilot skills sync (.github/skills/<name>/SKILL.md)
|
|
1528
|
+
if copilot_skills_enabled; then
|
|
1529
|
+
_copilot_skills="$NEXUS_DIR/.github/skills"
|
|
1530
|
+
mkdir -p "$_copilot_skills"
|
|
1531
|
+
|
|
1532
|
+
# Base toolkit skills
|
|
1533
|
+
for _pfile in "$_src_prompts"/rnex-*.md; do
|
|
1534
|
+
[ -f "$_pfile" ] || continue
|
|
1535
|
+
_pname="$(basename "$_pfile" .md)"
|
|
1536
|
+
_desc="$(awk '
|
|
1537
|
+
/^#/ { in_title=1; next }
|
|
1538
|
+
in_title && /^[A-Za-z]/ { print; exit }
|
|
1539
|
+
' "$_pfile" 2>/dev/null)"
|
|
1540
|
+
[ -n "$_desc" ] || _desc="Repo Nexus prompt for $_pname"
|
|
1541
|
+
|
|
1542
|
+
_dst_sk_dir="$_copilot_skills/$_pname"
|
|
1543
|
+
mkdir -p "$_dst_sk_dir"
|
|
1544
|
+
_dst_sk="$_dst_sk_dir/SKILL.md"
|
|
1545
|
+
{
|
|
1546
|
+
printf -- '---\nname: %s\ndescription: %s\n---\n\n' "$_pname" "$_desc"
|
|
1547
|
+
cat "$_pfile"
|
|
1548
|
+
} > "$_dst_sk"
|
|
1549
|
+
done
|
|
1550
|
+
|
|
1551
|
+
# Active plugins skills, prompts, & workflows
|
|
1552
|
+
yaml_list_plugins | while read -r _pname; do
|
|
1553
|
+
[ -n "$_pname" ] || continue
|
|
1554
|
+
yaml_plugin_enabled "$_pname" || continue
|
|
1555
|
+
[ "$_pname" != "copilot" ] || continue
|
|
1556
|
+
_pdir="$(find_plugin_dir "$_pname" 2>/dev/null || true)"
|
|
1557
|
+
[ -n "$_pdir" ] || continue
|
|
1558
|
+
|
|
1559
|
+
# A. Dedicated skills in plugin
|
|
1560
|
+
for _s_dir in "$_pdir/skills" "$NEXUS_DIR/.rnex/plugins/$_pname/skills"; do
|
|
1561
|
+
[ -d "$_s_dir" ] || continue
|
|
1562
|
+
for _s_entry in "$_s_dir"/*; do
|
|
1563
|
+
if [ -d "$_s_entry" ] && [ -f "$_s_entry/SKILL.md" ]; then
|
|
1564
|
+
_sname="$(basename "$_s_entry")"
|
|
1565
|
+
mkdir -p "$_copilot_skills/$_sname"
|
|
1566
|
+
cp -f "$_s_entry/SKILL.md" "$_copilot_skills/$_sname/SKILL.md"
|
|
1567
|
+
elif [ -f "$_s_entry" ]; then
|
|
1568
|
+
_sname="$(basename "$_s_entry" .md)"
|
|
1569
|
+
mkdir -p "$_copilot_skills/$_sname"
|
|
1570
|
+
if grep -q '^---' "$_s_entry" 2>/dev/null; then
|
|
1571
|
+
cp -f "$_s_entry" "$_copilot_skills/$_sname/SKILL.md"
|
|
1572
|
+
else
|
|
1573
|
+
_desc="$(awk '
|
|
1574
|
+
/^#/ { in_title=1; next }
|
|
1575
|
+
in_title && /^[A-Za-z]/ { print; exit }
|
|
1576
|
+
' "$_s_entry" 2>/dev/null)"
|
|
1577
|
+
[ -n "$_desc" ] || _desc="Skill $_sname from plugin $_pname"
|
|
1578
|
+
{
|
|
1579
|
+
printf -- '---\nname: %s\ndescription: %s\n---\n\n' "$_sname" "$_desc"
|
|
1580
|
+
cat "$_s_entry"
|
|
1581
|
+
} > "$_copilot_skills/$_sname/SKILL.md"
|
|
1582
|
+
fi
|
|
1583
|
+
fi
|
|
1584
|
+
done
|
|
1585
|
+
done
|
|
1586
|
+
|
|
1587
|
+
# B. Plugin prompts & workflows as skills if not already provided
|
|
1588
|
+
for _sub in prompts workflows; do
|
|
1589
|
+
for _s_dir in "$_pdir/$_sub" "$NEXUS_DIR/.rnex/plugins/$_pname/$_sub"; do
|
|
1590
|
+
[ -d "$_s_dir" ] || continue
|
|
1591
|
+
for _pfile in "$_s_dir"/*.md; do
|
|
1592
|
+
[ -f "$_pfile" ] || continue
|
|
1593
|
+
_base="$(basename "$_pfile" .md)"
|
|
1594
|
+
case "$_base" in
|
|
1595
|
+
index|README) continue ;;
|
|
1596
|
+
esac
|
|
1597
|
+
_dst_sk_dir="$_copilot_skills/$_base"
|
|
1598
|
+
if [ ! -f "$_dst_sk_dir/SKILL.md" ]; then
|
|
1599
|
+
mkdir -p "$_dst_sk_dir"
|
|
1600
|
+
_desc="$(awk '
|
|
1601
|
+
/^#/ { in_title=1; next }
|
|
1602
|
+
in_title && /^[A-Za-z]/ { print; exit }
|
|
1603
|
+
' "$_pfile" 2>/dev/null)"
|
|
1604
|
+
[ -n "$_desc" ] || _desc="Skill $_base from plugin $_pname"
|
|
1605
|
+
{
|
|
1606
|
+
printf -- '---\nname: %s\ndescription: %s\n---\n\n' "$_base" "$_desc"
|
|
1607
|
+
cat "$_pfile"
|
|
1608
|
+
} > "$_dst_sk_dir/SKILL.md"
|
|
1609
|
+
fi
|
|
1610
|
+
done
|
|
1611
|
+
done
|
|
1612
|
+
done
|
|
1613
|
+
done
|
|
1614
|
+
else
|
|
1615
|
+
if [ -d "$NEXUS_DIR/.github/skills" ]; then
|
|
1616
|
+
rm -rf "$NEXUS_DIR/.github/skills" 2>/dev/null || true
|
|
1617
|
+
fi
|
|
1618
|
+
fi
|
|
1619
|
+
|
|
1620
|
+
# Copilot agents sync (.github/agents/*.agent.md)
|
|
1621
|
+
if copilot_agents_enabled; then
|
|
1622
|
+
_copilot_agents="$NEXUS_DIR/.github/agents"
|
|
1623
|
+
|
|
1624
|
+
yaml_list_plugins | while read -r _pname; do
|
|
1625
|
+
[ -n "$_pname" ] || continue
|
|
1626
|
+
yaml_plugin_enabled "$_pname" || continue
|
|
1627
|
+
[ "$_pname" != "copilot" ] || continue
|
|
1628
|
+
_pdir="$(find_plugin_dir "$_pname" 2>/dev/null || true)"
|
|
1629
|
+
[ -n "$_pdir" ] || continue
|
|
1630
|
+
|
|
1631
|
+
for _s_dir in "$_pdir/agents" "$NEXUS_DIR/.rnex/plugins/$_pname/agents"; do
|
|
1632
|
+
[ -d "$_s_dir" ] || continue
|
|
1633
|
+
for _afile in "$_s_dir"/*.md; do
|
|
1634
|
+
[ -f "$_afile" ] || continue
|
|
1635
|
+
_aname="$(basename "$_afile" .agent.md)"
|
|
1636
|
+
_aname="$(basename "$_aname" .md)"
|
|
1637
|
+
mkdir -p "$_copilot_agents"
|
|
1638
|
+
if grep -q '^---' "$_afile" 2>/dev/null; then
|
|
1639
|
+
cp -f "$_afile" "$_copilot_agents/$_aname.agent.md"
|
|
1640
|
+
else
|
|
1641
|
+
_desc="$(awk '
|
|
1642
|
+
/^#/ { in_title=1; next }
|
|
1643
|
+
in_title && /^[A-Za-z]/ { print; exit }
|
|
1644
|
+
' "$_afile" 2>/dev/null)"
|
|
1645
|
+
[ -n "$_desc" ] || _desc="Agent $_aname from plugin $_pname"
|
|
1646
|
+
{
|
|
1647
|
+
printf -- '---\nname: %s\ndescription: %s\n---\n\n' "$_aname" "$_desc"
|
|
1648
|
+
cat "$_afile"
|
|
1649
|
+
} > "$_copilot_agents/$_aname.agent.md"
|
|
1650
|
+
fi
|
|
1651
|
+
# Also mirror to skills if skills enabled
|
|
1652
|
+
if copilot_skills_enabled; then
|
|
1653
|
+
mkdir -p "$_copilot_skills/$_aname"
|
|
1654
|
+
cp -f "$_copilot_agents/$_aname.agent.md" "$_copilot_skills/$_aname/SKILL.md"
|
|
1655
|
+
fi
|
|
1656
|
+
done
|
|
1657
|
+
done
|
|
1658
|
+
done
|
|
1659
|
+
else
|
|
1660
|
+
if [ -d "$NEXUS_DIR/.github/agents" ]; then
|
|
1661
|
+
rm -rf "$NEXUS_DIR/.github/agents" 2>/dev/null || true
|
|
1662
|
+
fi
|
|
1663
|
+
fi
|
|
1664
|
+
|
|
1665
|
+
# Copilot instructions sync (.github/copilot-instructions.md)
|
|
1666
|
+
sync_copilot_instructions
|
|
1155
1667
|
}
|
|
1156
1668
|
|
|
1157
1669
|
upgrade_workspace_config() {
|
|
@@ -1486,12 +1998,15 @@ cmd_init() {
|
|
|
1486
1998
|
_cli_code_workspace=""
|
|
1487
1999
|
_cli_hooks=""
|
|
1488
2000
|
_cli_no_hooks=0
|
|
2001
|
+
_cli_copilot=""
|
|
1489
2002
|
|
|
1490
2003
|
while [ $# -gt 0 ]; do
|
|
1491
2004
|
case "$1" in
|
|
1492
2005
|
-y|--yes) _non_interactive=1 ;;
|
|
1493
2006
|
--hooks) _cli_hooks="true" ;;
|
|
1494
2007
|
--no-hooks) _cli_no_hooks=1; _cli_hooks="false" ;;
|
|
2008
|
+
--copilot) _cli_copilot="true" ;;
|
|
2009
|
+
--no-copilot) _cli_copilot="false" ;;
|
|
1495
2010
|
--ai|--instructions|--ai-instructions)
|
|
1496
2011
|
shift
|
|
1497
2012
|
_cli_ai_instructions="$1"
|
|
@@ -1561,11 +2076,15 @@ cmd_init() {
|
|
|
1561
2076
|
log_dim "To reconcile repos and plugins, run:"
|
|
1562
2077
|
log_dim " rnex fix"
|
|
1563
2078
|
else
|
|
2079
|
+
_init_plugins=""
|
|
2080
|
+
if [ "$_cli_copilot" = "true" ]; then
|
|
2081
|
+
_init_plugins=" copilot:\n prompts: true\n skills: true\n instructions: true\n agents: true\n"
|
|
2082
|
+
fi
|
|
2083
|
+
|
|
1564
2084
|
cat > "$_target_yaml" <<YAML_EOF
|
|
1565
|
-
# Repo Nexus workspace configuration
|
|
2085
|
+
# Repo Nexus workspace configuration
|
|
1566
2086
|
# See docs/rnex.example.yaml for a comprehensive example with all options.
|
|
1567
2087
|
|
|
1568
|
-
# Workspace configuration version
|
|
1569
2088
|
version: $RNEX_VERSION
|
|
1570
2089
|
|
|
1571
2090
|
# Directory for member repository clones
|
|
@@ -1582,7 +2101,7 @@ git_hooks: $_init_git_hooks
|
|
|
1582
2101
|
|
|
1583
2102
|
# Workspace plugins
|
|
1584
2103
|
plugins:
|
|
1585
|
-
|
|
2104
|
+
$(printf '%b' "$_init_plugins")
|
|
1586
2105
|
# Member repositories managed by Repo Nexus
|
|
1587
2106
|
repos:
|
|
1588
2107
|
YAML_EOF
|
|
@@ -1617,11 +2136,18 @@ YAML_EOF
|
|
|
1617
2136
|
mkdir -p "$_target_dir/.rnex/plugins"
|
|
1618
2137
|
mkdir -p "$_target_dir/.rnex/prompts"
|
|
1619
2138
|
_orig_nexus="$NEXUS_DIR"
|
|
2139
|
+
_orig_yaml="$WORKSPACE_YAML"
|
|
2140
|
+
_orig_local_yaml="$WORKSPACE_LOCAL_YAML"
|
|
1620
2141
|
NEXUS_DIR="$_target_dir"
|
|
2142
|
+
WORKSPACE_YAML="$_target_yaml"
|
|
2143
|
+
WORKSPACE_LOCAL_YAML="$_target_dir/$RNEX_LOCAL_CONFIG_FILE"
|
|
2144
|
+
sync_plugins
|
|
1621
2145
|
sync_prompts
|
|
2146
|
+
WORKSPACE_LOCAL_YAML="$_orig_local_yaml"
|
|
2147
|
+
WORKSPACE_YAML="$_orig_yaml"
|
|
1622
2148
|
NEXUS_DIR="$_orig_nexus"
|
|
1623
2149
|
|
|
1624
|
-
# ---- 5. Ensure repos
|
|
2150
|
+
# ---- 5. Ensure repos/ and local configs are gitignored ---------
|
|
1625
2151
|
reconcile_gitignore "$_target_dir"
|
|
1626
2152
|
|
|
1627
2153
|
# ---- 6. Generate VS Code / Cursor workspace if configured ----------------
|
|
@@ -1978,18 +2504,18 @@ cmd_status() {
|
|
|
1978
2504
|
fi
|
|
1979
2505
|
|
|
1980
2506
|
_gi="$NEXUS_DIR/.gitignore"
|
|
1981
|
-
_gi_repos=0;
|
|
2507
|
+
_gi_repos=0; _gi_local=0; _gi_has_counter=0; _gi_has_rnex=0
|
|
1982
2508
|
if [ -f "$_gi" ]; then
|
|
1983
2509
|
grep -q '^repos' "$_gi" 2>/dev/null && _gi_repos=1
|
|
1984
|
-
(grep -q '^\.rnex/' "$_gi" 2>/dev/null || grep -q '^\.rnex$' "$_gi" 2>/dev/null) && _gi_rnex=1
|
|
1985
2510
|
grep -qF "$RNEX_LOCAL_CONFIG_FILE" "$_gi" 2>/dev/null && _gi_local=1
|
|
1986
2511
|
grep -q "lint_trigger_counter" "$_gi" 2>/dev/null && _gi_has_counter=1
|
|
2512
|
+
(grep -q '^\.rnex/' "$_gi" 2>/dev/null || grep -q '^\.rnex$' "$_gi" 2>/dev/null) && _gi_has_rnex=1
|
|
1987
2513
|
fi
|
|
1988
2514
|
|
|
1989
|
-
if [ "$_gi_repos" -eq 1 ] && [ "$
|
|
1990
|
-
printf ' %b✓%b Git Ignore: repos
|
|
2515
|
+
if [ "$_gi_repos" -eq 1 ] && [ "$_gi_local" -eq 1 ] && [ "$_gi_has_counter" -eq 0 ] && [ "$_gi_has_rnex" -eq 0 ]; then
|
|
2516
|
+
printf ' %b✓%b Git Ignore: repos/ and %s ignored in .gitignore\n' "$_G" "$_NC" "$RNEX_LOCAL_CONFIG_FILE"
|
|
1991
2517
|
else
|
|
1992
|
-
printf ' %b!%b Git Ignore: recommend running "rnex fix" to update .gitignore (repos/,
|
|
2518
|
+
printf ' %b!%b Git Ignore: recommend running "rnex fix" to update .gitignore (repos/, local configs)\n' "$_Y" "$_NC"
|
|
1993
2519
|
fi
|
|
1994
2520
|
|
|
1995
2521
|
_hooks_path="$(git -C "$NEXUS_DIR" config --get core.hooksPath 2>/dev/null || true)"
|
|
@@ -2037,6 +2563,7 @@ cmd_status() {
|
|
|
2037
2563
|
fi
|
|
2038
2564
|
;;
|
|
2039
2565
|
esac
|
|
2566
|
+
|
|
2040
2567
|
printf '\n'
|
|
2041
2568
|
|
|
2042
2569
|
printf '%bWorkspace AI Context (Routing):%b\n' "$_BOLD" "$_NC"
|
|
@@ -2069,6 +2596,18 @@ cmd_status() {
|
|
|
2069
2596
|
if [ -f "$NEXUS_DIR/.rnex/prompts/index.md" ]; then
|
|
2070
2597
|
printf ' %b✓%b %s %b(prompts catalog)%b\n' "$_G" "$_NC" ".rnex/prompts/index.md" "$_DIM" "$_NC"
|
|
2071
2598
|
fi
|
|
2599
|
+
if [ -d "$NEXUS_DIR/.github/prompts" ]; then
|
|
2600
|
+
printf ' %b✓%b %s %b(Copilot prompts)%b\n' "$_G" "$_NC" ".github/prompts/" "$_DIM" "$_NC"
|
|
2601
|
+
fi
|
|
2602
|
+
if [ -d "$NEXUS_DIR/.github/skills" ]; then
|
|
2603
|
+
printf ' %b✓%b %s %b(Copilot skills)%b\n' "$_G" "$_NC" ".github/skills/" "$_DIM" "$_NC"
|
|
2604
|
+
fi
|
|
2605
|
+
if [ -d "$NEXUS_DIR/.github/agents" ]; then
|
|
2606
|
+
printf ' %b✓%b %s %b(Copilot agents)%b\n' "$_G" "$_NC" ".github/agents/" "$_DIM" "$_NC"
|
|
2607
|
+
fi
|
|
2608
|
+
if [ -f "$NEXUS_DIR/.github/copilot-instructions.md" ]; then
|
|
2609
|
+
printf ' %b✓%b %s %b(Copilot instructions)%b\n' "$_G" "$_NC" ".github/copilot-instructions.md" "$_DIM" "$_NC"
|
|
2610
|
+
fi
|
|
2072
2611
|
printf '\n'
|
|
2073
2612
|
|
|
2074
2613
|
printf '%bActive Plugins:%b\n' "$_BOLD" "$_NC"
|
|
@@ -2082,8 +2621,19 @@ cmd_status() {
|
|
|
2082
2621
|
if [ -n "$_pdir" ]; then
|
|
2083
2622
|
_ver="$(plugin_get_field "$_pdir" "version")"
|
|
2084
2623
|
_desc="$(plugin_get_field "$_pdir" "description")"
|
|
2085
|
-
|
|
2086
|
-
|
|
2624
|
+
if ! yaml_plugin_enabled "$_pname"; then
|
|
2625
|
+
printf ' %b○%b %-18s %b[disabled locally]%b\n' "$_DIM" "$_NC" "$_pname" "$_DIM" "$_NC"
|
|
2626
|
+
else
|
|
2627
|
+
printf ' %b●%b %-18s %b(v%s)%b %s\n' "$_G" "$_NC" "$_pname" "$_DIM" "${_ver:-0.1.0}" "$_NC" "${_desc:+- $_desc}"
|
|
2628
|
+
printf ' %bScoped directory: .rnex/plugins/%s%b\n' "$_DIM" "$_pname" "$_NC"
|
|
2629
|
+
if [ "$_pname" = "copilot" ]; then
|
|
2630
|
+
printf ' %b↳ Options: prompts=%s, skills=%s, instructions=%s, agents=%s%b\n' "$_DIM" \
|
|
2631
|
+
"$(copilot_prompts_enabled && echo "true" || echo "false")" \
|
|
2632
|
+
"$(copilot_skills_enabled && echo "true" || echo "false")" \
|
|
2633
|
+
"$(copilot_instructions_enabled && echo "true" || echo "false")" \
|
|
2634
|
+
"$(copilot_agents_enabled && echo "true" || echo "false")" "$_NC"
|
|
2635
|
+
fi
|
|
2636
|
+
fi
|
|
2087
2637
|
else
|
|
2088
2638
|
printf ' %b✗%b %-18s %bMISSING%b\n' "$_R" "$_NC" "$_pname" "$_R" "$_NC"
|
|
2089
2639
|
printf ' %b↳ [!] Issue: plugin declared in config but directory not found on disk%b\n' "$_R" "$_NC"
|
|
@@ -2174,6 +2724,7 @@ cmd_fix() {
|
|
|
2174
2724
|
_load_ai_instructions_file
|
|
2175
2725
|
_load_code_workspace
|
|
2176
2726
|
_load_git_hooks
|
|
2727
|
+
_load_copilot
|
|
2177
2728
|
[ "$_fix_quiet" -eq 0 ] && log_ok "Upgraded workspace configuration and routing instructions to v$RNEX_VERSION"
|
|
2178
2729
|
fi
|
|
2179
2730
|
fi
|
|
@@ -2330,8 +2881,10 @@ cmd_plugin_info() {
|
|
|
2330
2881
|
_author="$(plugin_get_field "$_pdir" "author")"
|
|
2331
2882
|
_home="$(plugin_get_field "$_pdir" "homepage")"
|
|
2332
2883
|
|
|
2333
|
-
if
|
|
2884
|
+
if yaml_plugin_enabled "$_name"; then
|
|
2334
2885
|
_status="${_G}enabled${_NC}"
|
|
2886
|
+
elif yaml_has_plugin "$_name"; then
|
|
2887
|
+
_status="${_DIM}disabled locally (${WORKSPACE_LOCAL_YAML})${_NC}"
|
|
2335
2888
|
else
|
|
2336
2889
|
_status="${_DIM}available (not enabled)${_NC}"
|
|
2337
2890
|
fi
|
|
@@ -2344,6 +2897,14 @@ cmd_plugin_info() {
|
|
|
2344
2897
|
[ -n "$_home" ] && printf '%bHomepage:%b %s\n' "$_BOLD" "$_NC" "$_home"
|
|
2345
2898
|
printf '%bLocation:%b %s\n' "$_BOLD" "$_NC" "$_pdir"
|
|
2346
2899
|
|
|
2900
|
+
if [ "$_name" = "copilot" ]; then
|
|
2901
|
+
printf '\n%bConfigurable Options (in rnex.yaml or .local.rnex.yaml):%b\n' "$_BOLD" "$_NC"
|
|
2902
|
+
printf ' - prompts: true|false (mirror prompts to .github/prompts/*.prompt.md; current: %s)\n' "$(copilot_prompts_enabled && echo "true" || echo "false")"
|
|
2903
|
+
printf ' - skills: true|false (mirror skills to .github/skills/<name>/SKILL.md; current: %s)\n' "$(copilot_skills_enabled && echo "true" || echo "false")"
|
|
2904
|
+
printf ' - instructions: true|false (mirror instructions to .github/copilot-instructions.md; current: %s)\n' "$(copilot_instructions_enabled && echo "true" || echo "false")"
|
|
2905
|
+
printf ' - agents: true|false (mirror agents to .github/agents/*.agent.md; current: %s)\n' "$(copilot_agents_enabled && echo "true" || echo "false")"
|
|
2906
|
+
fi
|
|
2907
|
+
|
|
2347
2908
|
printf '\n%bScoped Directory:%b .rnex/plugins/%s\n' "$_BOLD" "$_NC" "$_name"
|
|
2348
2909
|
|
|
2349
2910
|
_tmpl="$(plugin_list_templates "$_pdir")"
|
|
@@ -2363,8 +2924,16 @@ cmd_plugin_info() {
|
|
|
2363
2924
|
|
|
2364
2925
|
cmd_plugin_enable() {
|
|
2365
2926
|
require_workspace
|
|
2366
|
-
|
|
2367
|
-
|
|
2927
|
+
_is_local=0
|
|
2928
|
+
_pname=""
|
|
2929
|
+
while [ $# -gt 0 ]; do
|
|
2930
|
+
case "$1" in
|
|
2931
|
+
--local) _is_local=1 ;;
|
|
2932
|
+
*) _pname="$1" ;;
|
|
2933
|
+
esac
|
|
2934
|
+
shift
|
|
2935
|
+
done
|
|
2936
|
+
[ -n "$_pname" ] || die "Usage: rnex plugin enable [--local] <name>"
|
|
2368
2937
|
|
|
2369
2938
|
_pdir="$(find_plugin_dir "$_pname" 2>/dev/null || true)"
|
|
2370
2939
|
[ -n "$_pdir" ] || die "Plugin '$_pname' not found."
|
|
@@ -2372,8 +2941,13 @@ cmd_plugin_enable() {
|
|
|
2372
2941
|
_name="$(plugin_get_field "$_pdir" "name")"
|
|
2373
2942
|
[ -n "$_name" ] || _name="$_pname"
|
|
2374
2943
|
|
|
2375
|
-
|
|
2376
|
-
|
|
2944
|
+
if [ "$_is_local" -eq 1 ]; then
|
|
2945
|
+
yaml_enable_plugin "$_name" "$WORKSPACE_LOCAL_YAML"
|
|
2946
|
+
log_ok "Plugin '$_name' enabled locally in $(basename "$WORKSPACE_LOCAL_YAML")"
|
|
2947
|
+
else
|
|
2948
|
+
yaml_enable_plugin "$_name" "$WORKSPACE_YAML"
|
|
2949
|
+
log_ok "Plugin '$_name' enabled in $(basename "$WORKSPACE_YAML")"
|
|
2950
|
+
fi
|
|
2377
2951
|
|
|
2378
2952
|
sync_plugins
|
|
2379
2953
|
cmd_fix
|
|
@@ -2382,8 +2956,16 @@ cmd_plugin_enable() {
|
|
|
2382
2956
|
|
|
2383
2957
|
cmd_plugin_disable() {
|
|
2384
2958
|
require_workspace
|
|
2385
|
-
|
|
2386
|
-
|
|
2959
|
+
_is_local=0
|
|
2960
|
+
_pname=""
|
|
2961
|
+
while [ $# -gt 0 ]; do
|
|
2962
|
+
case "$1" in
|
|
2963
|
+
--local) _is_local=1 ;;
|
|
2964
|
+
*) _pname="$1" ;;
|
|
2965
|
+
esac
|
|
2966
|
+
shift
|
|
2967
|
+
done
|
|
2968
|
+
[ -n "$_pname" ] || die "Usage: rnex plugin disable [--local] <name>"
|
|
2387
2969
|
|
|
2388
2970
|
_pdir="$(find_plugin_dir "$_pname" 2>/dev/null || true)"
|
|
2389
2971
|
_name="$_pname"
|
|
@@ -2392,22 +2974,34 @@ cmd_plugin_disable() {
|
|
|
2392
2974
|
[ -n "$_n" ] && _name="$_n"
|
|
2393
2975
|
fi
|
|
2394
2976
|
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2977
|
+
if [ "$_is_local" -eq 1 ]; then
|
|
2978
|
+
if _yaml_list_plugins_from_file "$WORKSPACE_YAML" | grep -qx "$_name" 2>/dev/null; then
|
|
2979
|
+
yaml_plugin_set_local "$_name" "enabled" "false"
|
|
2980
|
+
log_ok "Plugin '$_name' disabled locally in $(basename "$WORKSPACE_LOCAL_YAML")"
|
|
2981
|
+
else
|
|
2982
|
+
_yaml_disable_plugin_in_file "$WORKSPACE_LOCAL_YAML" "$_name"
|
|
2983
|
+
log_ok "Plugin '$_name' removed from $(basename "$WORKSPACE_LOCAL_YAML")"
|
|
2984
|
+
fi
|
|
2985
|
+
else
|
|
2986
|
+
yaml_disable_plugin "$_name"
|
|
2987
|
+
log_ok "Plugin '$_name' disabled from workspace"
|
|
2401
2988
|
fi
|
|
2402
2989
|
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
rm -rf "$_rpath/.rnex/plugins/$_name"
|
|
2990
|
+
if ! yaml_plugin_enabled "$_name"; then
|
|
2991
|
+
if [ -d "$NEXUS_DIR/.rnex/plugins/$_name" ]; then
|
|
2992
|
+
rm -rf "$NEXUS_DIR/.rnex/plugins/$_name"
|
|
2993
|
+
log_ok "Removed workspace plugin scope: .rnex/plugins/$_name"
|
|
2408
2994
|
fi
|
|
2409
|
-
done
|
|
2410
2995
|
|
|
2996
|
+
yaml_list_repos | while read -r _rname; do
|
|
2997
|
+
_rpath="$(resolve_repo_path "$_rname")"
|
|
2998
|
+
if [ -d "$_rpath/.rnex/plugins/$_name" ]; then
|
|
2999
|
+
rm -rf "$_rpath/.rnex/plugins/$_name"
|
|
3000
|
+
fi
|
|
3001
|
+
done
|
|
3002
|
+
fi
|
|
3003
|
+
|
|
3004
|
+
sync_prompts
|
|
2411
3005
|
log_ok "Plugin '$_name' disabled from workspace"
|
|
2412
3006
|
}
|
|
2413
3007
|
|
|
@@ -2630,7 +3224,7 @@ cmd_help() {
|
|
|
2630
3224
|
-v, --version Show version
|
|
2631
3225
|
|
|
2632
3226
|
WORKSPACE & SYSTEM SETUP
|
|
2633
|
-
init [-y] [--ai <file>] [--code-workspace [file]] [--hooks|--no-hooks] [dir]
|
|
3227
|
+
init [-y] [--ai <file>] [--code-workspace [file]] [--hooks|--no-hooks] [--copilot|--no-copilot] [dir]
|
|
2634
3228
|
Initialize a new Repo Nexus workspace (default AI file: AGENTS.md)
|
|
2635
3229
|
install [dir] Install rnex & repo-nexus globally into ~/.local/bin (or custom dir)
|
|
2636
3230
|
fix [-y] [--quiet] Reconcile workspace, plugins, prompts & member .rnex/ (alias: sync)
|
|
@@ -2654,8 +3248,8 @@ cmd_help() {
|
|
|
2654
3248
|
PLUGIN MANAGEMENT
|
|
2655
3249
|
plugin [list] List available and enabled plugins
|
|
2656
3250
|
plugin info <name> Show details of a plugin
|
|
2657
|
-
plugin enable <name>
|
|
2658
|
-
plugin disable <name>
|
|
3251
|
+
plugin enable [--local] <name> Enable plugin in workspace (scoped to .rnex/plugins/<name>/)
|
|
3252
|
+
plugin disable [--local] <name> Disable plugin from workspace
|
|
2659
3253
|
|
|
2660
3254
|
EXAMPLES
|
|
2661
3255
|
rnex init # Initialize workspace in current folder
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# GitHub Copilot Plugin for Repo Nexus
|
|
2
|
+
|
|
3
|
+
A built-in Repo Nexus plugin providing bidirectional alignment and operational prompt/skill mirroring for GitHub Copilot.
|
|
4
|
+
|
|
5
|
+
## Capabilities
|
|
6
|
+
|
|
7
|
+
1. **Prompts Mirroring**: Standardized Repo Nexus prompts (`rnex-feature`, `rnex-audit`, etc.) and active plugins' prompts/workflows are synchronized into `.github/prompts/*.prompt.md` with YAML frontmatter.
|
|
8
|
+
2. **Agent Skills**: Prompts, active plugin skills, and agent bundles are mirrored into `.github/skills/<name>/SKILL.md` for GitHub Copilot Agent mode.
|
|
9
|
+
3. **Custom Agents**: Active plugins' agents are mirrored into `.github/agents/*.agent.md`.
|
|
10
|
+
4. **Instructions Integration**: Active plugins' rules/instructions and Repo Nexus routing instructions are synthesized into `.github/copilot-instructions.md`.
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
Enable the plugin across the workspace:
|
|
15
|
+
```bash
|
|
16
|
+
rnex plugin enable copilot
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or configure options in `rnex.yaml` or `.local.rnex.yaml`:
|
|
20
|
+
```yaml
|
|
21
|
+
plugins:
|
|
22
|
+
copilot:
|
|
23
|
+
prompts: true
|
|
24
|
+
skills: true
|
|
25
|
+
instructions: true
|
|
26
|
+
agents: true
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Options
|
|
30
|
+
|
|
31
|
+
| Option | Type | Default | Description |
|
|
32
|
+
|--------|------|---------|-------------|
|
|
33
|
+
| `prompts` | boolean | `true` | Mirror prompts to `.github/prompts/*.prompt.md` |
|
|
34
|
+
| `skills` | boolean | `true` | Mirror skills to `.github/skills/<name>/SKILL.md` |
|
|
35
|
+
| `instructions` | boolean | `true` | Mirror guidelines to `.github/copilot-instructions.md` |
|
|
36
|
+
| `agents` | boolean | `true` | Mirror custom agents to `.github/agents/*.agent.md` |
|
|
37
|
+
| `enabled` | boolean | `true` | Set to `false` in `.local.rnex.yaml` to override team config |
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# GitHub Copilot Integration for Repo Nexus
|
|
2
|
+
|
|
3
|
+
This workspace has the Repo Nexus `copilot` plugin enabled.
|
|
4
|
+
|
|
5
|
+
## Operating Principles
|
|
6
|
+
- **Prompts (`.github/prompts/*.prompt.md`)**: Operational Repo Nexus prompts and active plugins' prompts/workflows are mirrored here with YAML frontmatter (`name`, `description`) for use in the VS Code Copilot Chat prompt picker and slash commands.
|
|
7
|
+
- **Agent Skills (`.github/skills/<name>/SKILL.md`)**: Standard prompts, active plugin skills, and agent bundles are mirrored as individual skill bundles with frontmatter for GitHub Copilot Agent mode and `gh skill`.
|
|
8
|
+
- **Custom Agents (`.github/agents/*.agent.md`)**: Active plugins' agent definitions (such as `wiki-curator`) are mirrored here for Copilot workspace custom agents.
|
|
9
|
+
- **Copilot Instructions (`.github/copilot-instructions.md`)**: Synthesizes workspace routing and active plugin guidelines between `<!-- REPO-NEXUS:START -->` and `<!-- REPO-NEXUS:END -->`, preserving any manual user instructions outside those markers.
|
|
10
|
+
- **Decoupled Cross-Plugin Discovery**: Plugins remain independent and decoupled; the `copilot` provider discovers and mirrors assets from whatever plugins are currently active.
|
|
11
|
+
|
|
12
|
+
## Configuration
|
|
13
|
+
Configure plugin options in `rnex.yaml` or override them per developer in `.local.rnex.yaml`:
|
|
14
|
+
|
|
15
|
+
```yaml
|
|
16
|
+
plugins:
|
|
17
|
+
copilot:
|
|
18
|
+
prompts: true # Mirror prompts to .github/prompts/ (default: true)
|
|
19
|
+
skills: true # Mirror skills to .github/skills/ (default: true)
|
|
20
|
+
instructions: true # Mirror routing & plugin guidelines to .github/copilot-instructions.md (default: true)
|
|
21
|
+
agents: true # Mirror custom agents to .github/agents/ (default: true)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
To disable locally without altering team configuration, add to `.local.rnex.yaml`:
|
|
25
|
+
```yaml
|
|
26
|
+
plugins:
|
|
27
|
+
copilot:
|
|
28
|
+
enabled: false
|
|
29
|
+
```
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
name: copilot
|
|
2
|
+
version: 0.5.1
|
|
3
|
+
description: GitHub Copilot integration (mirrors workspace prompts to .github/prompts and skills to .github/skills)
|
|
4
|
+
author: nu-nenoi
|
|
5
|
+
homepage: https://github.com/nu-nenoi/repo-nexus
|
|
6
|
+
instructions:
|
|
7
|
+
- instructions/copilot-integration.md: .rnex/plugins/copilot/instructions/copilot-integration.md
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wiki-curator
|
|
3
|
+
description: Autonomous knowledge librarian for the Karpathy LLM Wiki architecture.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Wiki Curator Agent
|
|
7
|
+
|
|
8
|
+
Autonomous knowledge librarian specialized in synthesizing unstructured source documents into the atomic Karpathy LLM Wiki graph.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Karpathy LLM Wiki Ingestion Workflow (`wiki-ingest`)
|
|
2
|
+
|
|
3
|
+
Autonomous workflow for decomposing and ingesting raw source documents from `raw/` into atomic Karpathy LLM Wiki pages.
|
|
4
|
+
|
|
5
|
+
## Protocol
|
|
6
|
+
1. Scan `raw/` for uningested documents not yet recorded in `wiki/_log.md`.
|
|
7
|
+
2. Read source materials completely; preserve original files in `raw/` unmodified.
|
|
8
|
+
3. Decompose each source document into atomic wiki pages in `wiki/` (5–25 pages per source).
|
|
9
|
+
4. For every page, write required YAML frontmatter with typed relations (`sources`, `related`, `extends`, `contradicts`, `mentioned_in`).
|
|
10
|
+
5. Update `wiki/index.md` and append an entry to `wiki/_log.md`.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Karpathy LLM Wiki Lint & Graph Maintenance (`wiki-lint`)
|
|
2
|
+
|
|
3
|
+
Periodic maintenance workflow to preserve wiki graph integrity, validate typed relations, and recompute bidirectional links.
|
|
4
|
+
|
|
5
|
+
## Protocol
|
|
6
|
+
1. Verify all frontmatter relation paths (`sources`, `related`, `extends`, `contradicts`) resolve to existing files.
|
|
7
|
+
2. Recompute `mentioned_in` backlinks for every page across the entire wiki graph.
|
|
8
|
+
3. Find orphaned pages not reachable from `wiki/index.md` or any `mentioned_in` link, and index them.
|
|
9
|
+
4. Detect duplicate/overlapping pages and check for factual contradictions.
|
|
10
|
+
5. Identify knowledge gaps and append audit results to `wiki/_log.md`.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wiki-ingest
|
|
3
|
+
description: Autonomous ingestion and atomic decomposition of raw sources into Karpathy LLM Wiki pages.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Karpathy LLM Wiki Ingestion Skill
|
|
7
|
+
|
|
8
|
+
Use this skill when decomposing raw documents, research notes, meeting logs, or external articles from `raw/` into atomic wiki pages under `wiki/`.
|
|
9
|
+
|
|
10
|
+
## Key Rules
|
|
11
|
+
- Source documents stay untouched in `raw/`.
|
|
12
|
+
- Produce 5–25 atomic pages per document (never lump into one large file).
|
|
13
|
+
- Include YAML frontmatter with typed relations (`sources`, `related`, `extends`, `contradicts`, `mentioned_in`).
|
|
14
|
+
- Record completed ingestion in `wiki/_log.md`.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wiki-lint
|
|
3
|
+
description: Autonomous link validation, backlink recalculation, and graph repair for Karpathy LLM Wiki.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Karpathy LLM Wiki Lint Skill
|
|
7
|
+
|
|
8
|
+
Use this skill when auditing and maintaining knowledge graph integrity across `/wiki/`.
|
|
9
|
+
|
|
10
|
+
## Key Steps
|
|
11
|
+
- Validate all relation filepaths exist.
|
|
12
|
+
- Recalculate and update `mentioned_in` backlinks.
|
|
13
|
+
- Check for orphan pages and update `wiki/index.md`.
|
|
14
|
+
- Flag contradictions and record maintenance in `wiki/_log.md`.
|