repo-nexus 0.7.36 → 0.7.39
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/lib/ai.sh +15 -2
- package/lib/commands/completion.sh +11 -3
- package/lib/commands/init.sh +7 -2
- package/lib/commands/plugin.sh +8 -0
- package/lib/commands/repo.sh +98 -20
- package/lib/commands/status.sh +15 -11
- package/lib/commands/sync.sh +8 -0
- package/lib/commands/system.sh +42 -9
- package/lib/core.sh +32 -6
- package/lib/hooks.sh +5 -0
- package/lib/plugins.sh +6 -0
- package/lib/repos.sh +61 -28
- package/lib/sdk.sh +6 -1
- package/lib/workspace.sh +5 -0
- package/lib/yaml.sh +32 -4
- package/package.json +3 -8
- package/rnex +8 -2
- package/templates/ai-instructions.sample.md +4 -2
- package/templates/rnex.example.yaml +25 -13
- package/toolkit/plugins/codex/README.md +29 -0
- package/toolkit/plugins/codex/hooks/after_sync.sh +14 -0
- package/toolkit/plugins/codex/hooks/before_plugin_disable.sh +13 -0
- package/toolkit/plugins/codex/instructions/rnex-codex-integration.md +24 -0
- package/toolkit/plugins/codex/plugin.yaml +15 -0
- package/CHANGELOG.md +0 -363
- package/docs/.gitkeep +0 -0
- package/docs/CLI.md +0 -99
- package/docs/FAQ.md +0 -180
- package/docs/cli/execution.md +0 -81
- package/docs/cli/index.md +0 -81
- package/docs/cli/repos.md +0 -129
- package/docs/cli/tooling.md +0 -92
- package/docs/cli/workspace.md +0 -169
- package/docs/examples/ai-workflows.md +0 -54
- package/docs/examples/local-overrides.md +0 -70
- package/docs/examples/monorepo-coexistence.md +0 -80
- package/docs/examples/multi-repo-workspace.md +0 -100
- package/docs/faq/index.md +0 -180
- package/docs/guide/architecture.md +0 -86
- package/docs/guide/configuration.md +0 -129
- package/docs/guide/getting-started.md +0 -117
- package/docs/guide/why-repo-nexus.md +0 -48
- package/docs/guide/workflows.md +0 -123
- package/docs/index.md +0 -83
- package/docs/plugins/authoring.md +0 -69
- package/docs/plugins/claude.md +0 -109
- package/docs/plugins/copilot.md +0 -46
- package/docs/plugins/cursor.md +0 -106
- package/docs/plugins/gemini.md +0 -112
- package/docs/plugins/index.md +0 -120
- package/docs/plugins/karpathy-llm.md +0 -203
- package/docs/plugins/windsurf.md +0 -106
- package/docs/public/dark_logo.svg +0 -15
- package/docs/public/home.png +0 -0
- package/docs/public/light_logo.svg +0 -15
- package/docs/public/logo.legacy.png +0 -0
- package/docs/public/robots.txt +0 -3
- package/docs/rnex.example.yaml +0 -152
- package/toolkit/scripts/.gitkeep +0 -0
package/lib/ai.sh
CHANGED
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
# ---- Gitignore & Search Tool Ignore Reconciliation -------------------------
|
|
8
8
|
|
|
9
|
+
# Reconcile workspace root .gitignore and .ignore:
|
|
10
|
+
# - Ensures repos/ is ignored in git to prevent accidental commits of member repos
|
|
11
|
+
# - Ensures .local.rnex.yaml is ignored
|
|
12
|
+
# - Ensures .ignore un-ignores repos/* so ripgrep and AI tools can index member files
|
|
9
13
|
reconcile_gitignore() {
|
|
10
14
|
_dir="${1:-$NEXUS_DIR}"
|
|
11
15
|
_gi="$_dir/.gitignore"
|
|
@@ -60,6 +64,8 @@ GI_EOF
|
|
|
60
64
|
|
|
61
65
|
# ---- AI Instructions Compilation (.rnex/ai-instructions.md) ----------------
|
|
62
66
|
|
|
67
|
+
# Compile the unified .rnex/ai-instructions.md file consumed by AI coding agents.
|
|
68
|
+
# Aggregates sample template instructions and active plugin instruction sections.
|
|
63
69
|
build_ai_instructions() {
|
|
64
70
|
_dir="${1:-$NEXUS_DIR}"
|
|
65
71
|
_ai_file="$_dir/.rnex/ai-instructions.md"
|
|
@@ -97,7 +103,9 @@ Execute in sequence before task execution:
|
|
|
97
103
|
Autonomous subagents are defined under `.rnex/agents/` and active plugin agents under `.rnex/plugins/<plugin-name>/agents/`.
|
|
98
104
|
|
|
99
105
|
## Member Repositories (`repos/<name>/`)
|
|
100
|
-
Each member repository is an autonomous Git repository.
|
|
106
|
+
Each member repository is an autonomous Git repository. Inspect only targeted files required for the task.
|
|
107
|
+
If repository-specific context exists, it is stored under `repos/<name>/.rnex/`.
|
|
108
|
+
Repositories marked `readonly: true` in configuration are reference-only: DO NOT modify, write to, or commit changes in read-only repositories; use them strictly for information, code exploration, and schema references.
|
|
101
109
|
|
|
102
110
|
## Workspace Maintenance
|
|
103
111
|
When workspace configuration, routing blocks, plugin assets, or member repository structures require reconciliation or schema upgrades:
|
|
@@ -105,7 +113,7 @@ When workspace configuration, routing blocks, plugin assets, or member repositor
|
|
|
105
113
|
- Use `rnex sync -y` to non-destructively apply configuration version upgrades automatically.
|
|
106
114
|
|
|
107
115
|
## Git Operations
|
|
108
|
-
Commit and push changes directly within the respective member repository root (`repos/<name>/`).
|
|
116
|
+
Commit and push changes directly within the respective member repository root (`repos/<name>/`). For read-only repositories (`readonly: true`), never commit, edit, or push changes.
|
|
109
117
|
BASE_AI_EOF
|
|
110
118
|
fi
|
|
111
119
|
|
|
@@ -150,6 +158,8 @@ BASE_AI_EOF
|
|
|
150
158
|
|
|
151
159
|
# ---- Multi-Root IDE Workspace (.code-workspace) ----------------------------
|
|
152
160
|
|
|
161
|
+
# Generate and maintain a multi-root VS Code / Cursor workspace file (.code-workspace).
|
|
162
|
+
# Adds workspace root and each active member repository as first-class workspace folders.
|
|
153
163
|
sync_code_workspace() {
|
|
154
164
|
[ -n "$CODE_WORKSPACE_FILE" ] || return 0
|
|
155
165
|
_ws_path="$NEXUS_DIR/$CODE_WORKSPACE_FILE"
|
|
@@ -260,6 +270,7 @@ get_active_provider_skill_dirs() {
|
|
|
260
270
|
claude) _sdir=".claude/skills" ;;
|
|
261
271
|
windsurf) _sdir=".windsurf/rules" ;;
|
|
262
272
|
gemini) _sdir=".agents/skills" ;;
|
|
273
|
+
codex) _sdir=".codex/skills" ;;
|
|
263
274
|
esac
|
|
264
275
|
fi
|
|
265
276
|
if [ -n "$_sdir" ]; then
|
|
@@ -273,6 +284,8 @@ get_active_provider_skill_dirs() {
|
|
|
273
284
|
printf '%s' "$_dirs"
|
|
274
285
|
}
|
|
275
286
|
|
|
287
|
+
# Synchronize built-in core agentic skills into .rnex/skills/ and register
|
|
288
|
+
# zero-logic user skill pointers across all active AI assistant directories.
|
|
276
289
|
sync_rnex_base_assets() {
|
|
277
290
|
_src_toolkit=""
|
|
278
291
|
if [ -d "$SCRIPT_LOCATION/toolkit" ]; then
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
# lib/commands/completion.sh — Shell completion generators (bash, zsh, fish)
|
|
5
5
|
# ============================================================================
|
|
6
6
|
|
|
7
|
+
# Generate tab-completion script for the requested shell (bash, zsh, or fish).
|
|
8
|
+
# Usage:
|
|
9
|
+
# source <(rnex completion bash)
|
|
10
|
+
# source <(rnex completion zsh)
|
|
7
11
|
cmd_completion() {
|
|
8
12
|
_shell="${1:-bash}"
|
|
9
13
|
case "$_shell" in
|
|
@@ -14,7 +18,7 @@ _rnex_completions() {
|
|
|
14
18
|
COMPREPLY=()
|
|
15
19
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
|
16
20
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
|
17
|
-
commands="init install add clone exec remove enable disable list sync status rnex-dir update upgrade hooks plugin completion version help"
|
|
21
|
+
commands="init install add clone exec remove enable disable readonly list sync status rnex-dir update upgrade hooks plugin completion version help"
|
|
18
22
|
|
|
19
23
|
case "$prev" in
|
|
20
24
|
rnex)
|
|
@@ -37,7 +41,7 @@ _rnex_completions() {
|
|
|
37
41
|
COMPREPLY=( $(compgen -W "install uninstall status" -- "$cur") )
|
|
38
42
|
return 0
|
|
39
43
|
;;
|
|
40
|
-
enable|disable|remove|show|hide|rnex-dir)
|
|
44
|
+
enable|disable|readonly|remove|show|hide|rnex-dir)
|
|
41
45
|
local repos
|
|
42
46
|
repos=$(rnex list 2>/dev/null | awk 'NR>2 {print $1}')
|
|
43
47
|
COMPREPLY=( $(compgen -W "$repos" -- "$cur") )
|
|
@@ -81,6 +85,7 @@ _rnex() {
|
|
|
81
85
|
'remove:Unregister and delete a repository'
|
|
82
86
|
'enable:Enable a repository in active workspace'
|
|
83
87
|
'disable:Disable a repository in workspace'
|
|
88
|
+
'readonly:Toggle read-only (information-only) status for a repo'
|
|
84
89
|
'list:List member repositories'
|
|
85
90
|
'sync:Reconcile workspace, plugins, skills, and member .rnex directories'
|
|
86
91
|
'status:Inspect workspace health and status (read-only)'
|
|
@@ -124,7 +129,7 @@ _rnex() {
|
|
|
124
129
|
hook_cmds=('install:Install Git hooks' 'uninstall:Uninstall Git hooks' 'status:Show Git hooks status')
|
|
125
130
|
_describe -t hook_cmds 'hooks command' hook_cmds
|
|
126
131
|
;;
|
|
127
|
-
enable|disable|remove|show|hide|rnex-dir)
|
|
132
|
+
enable|disable|readonly|remove|show|hide|rnex-dir)
|
|
128
133
|
local -a repos
|
|
129
134
|
repos=($(rnex list 2>/dev/null | awk 'NR>2 {print $1}'))
|
|
130
135
|
_describe -t repos 'repository' repos
|
|
@@ -163,6 +168,9 @@ complete -c rnex -n "__fish_use_subcommand" -a exec -d "Execute command across m
|
|
|
163
168
|
complete -c rnex -n "__fish_use_subcommand" -a remove -d "Remove a repository"
|
|
164
169
|
complete -c rnex -n "__fish_use_subcommand" -a enable -d "Enable a repository"
|
|
165
170
|
complete -c rnex -n "__fish_use_subcommand" -a disable -d "Disable a repository"
|
|
171
|
+
complete -c rnex -n "__fish_use_subcommand" -a readonly -d "Toggle read-only status for a repo"
|
|
172
|
+
complete -c rnex -n "__fish_seen_subcommand_from readonly" -a "enable disable"
|
|
173
|
+
complete -c rnex -n "__fish_seen_subcommand_from readonly" -l local -d "Apply locally"
|
|
166
174
|
complete -c rnex -n "__fish_use_subcommand" -a list -d "List repositories"
|
|
167
175
|
complete -c rnex -n "__fish_use_subcommand" -a rnex-dir -d "Toggle .rnex directory integration for a repo"
|
|
168
176
|
complete -c rnex -n "__fish_seen_subcommand_from rnex-dir" -a "enable disable"
|
package/lib/commands/init.sh
CHANGED
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
# lib/commands/init.sh — Workspace initialization command
|
|
5
5
|
# ============================================================================
|
|
6
6
|
|
|
7
|
+
# Initialize a new Repo Nexus workspace in the specified directory (or current directory):
|
|
8
|
+
# Sets up rnex.yaml, .rnex/ harness, gitignore rules, routing instructions in AGENTS.md,
|
|
9
|
+
# enabled plugins (e.g. --claude, --gemini, --karpathy), and optional VS Code / Cursor workspace.
|
|
10
|
+
# Usage:
|
|
11
|
+
# rnex init [-y|--yes] [--hooks|--no-hooks] [--<plugin>] [<directory>]
|
|
7
12
|
cmd_init() {
|
|
8
13
|
_non_interactive=0
|
|
9
14
|
_init_dir=""
|
|
@@ -165,7 +170,7 @@ YAML_EOF
|
|
|
165
170
|
if ! has_active_provider_instructions "$_init_dir"; then
|
|
166
171
|
merge_rnex_instructions "$_init_dir/AGENTS.md"
|
|
167
172
|
fi
|
|
168
|
-
for _if in CLAUDE.md GEMINI.md .cursorrules .windsurfrules .github/copilot-instructions.md; do
|
|
173
|
+
for _if in CLAUDE.md GEMINI.md CODEX.md .cursorrules .windsurfrules .github/copilot-instructions.md; do
|
|
169
174
|
[ -f "$_init_dir/$_if" ] && merge_rnex_instructions "$_init_dir/$_if"
|
|
170
175
|
done
|
|
171
176
|
|
|
@@ -216,7 +221,7 @@ YAML_EOF
|
|
|
216
221
|
log_dim "Created $_created_items"
|
|
217
222
|
printf '\n'
|
|
218
223
|
log_info "Next steps:"
|
|
219
|
-
log_dim "1. Add repositories with: rnex add <name> <git-url>"
|
|
224
|
+
log_dim "1. Add repositories with: rnex add [<name>] <git-url>"
|
|
220
225
|
log_dim "2. Clone team repositories: rnex clone"
|
|
221
226
|
log_dim "3. Run commands across all repos: rnex exec <command>"
|
|
222
227
|
fi
|
package/lib/commands/plugin.sh
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# lib/commands/plugin.sh — Plugin management commands
|
|
5
5
|
# ============================================================================
|
|
6
6
|
|
|
7
|
+
# List all available, enabled, and disabled plugins found in the workspace toolkit.
|
|
7
8
|
cmd_plugin_list() {
|
|
8
9
|
require_workspace
|
|
9
10
|
printf '\n%b%s%b\n' "$_B" "Repo Nexus Plugins" "$_NC"
|
|
@@ -35,6 +36,7 @@ cmd_plugin_list() {
|
|
|
35
36
|
printf '\n'
|
|
36
37
|
}
|
|
37
38
|
|
|
39
|
+
# Display detailed metadata, configurable options, and template paths for a specific plugin.
|
|
38
40
|
cmd_plugin_info() {
|
|
39
41
|
require_workspace
|
|
40
42
|
_pname="$1"
|
|
@@ -73,6 +75,7 @@ cmd_plugin_info() {
|
|
|
73
75
|
gemini) _skill_target=".agents/skills/" ;;
|
|
74
76
|
cursor) _skill_target=".cursor/rules/" ;;
|
|
75
77
|
windsurf) _skill_target=".windsurf/rules/" ;;
|
|
78
|
+
codex) _skill_target=".codex/skills/" ;;
|
|
76
79
|
esac
|
|
77
80
|
case "$_skill_target" in
|
|
78
81
|
*/|"") ;;
|
|
@@ -144,6 +147,7 @@ cmd_plugin_info() {
|
|
|
144
147
|
printf '\n'
|
|
145
148
|
}
|
|
146
149
|
|
|
150
|
+
# Enable a plugin in workspace configuration (team or local) and sync assets.
|
|
147
151
|
cmd_plugin_enable() {
|
|
148
152
|
require_workspace
|
|
149
153
|
_is_local=0
|
|
@@ -176,6 +180,7 @@ cmd_plugin_enable() {
|
|
|
176
180
|
log_ok "Plugin '$_name' active in workspace (.rnex/plugins/$_name)"
|
|
177
181
|
}
|
|
178
182
|
|
|
183
|
+
# Disable a plugin, dispatch before_plugin_disable hook, and prune its assets.
|
|
179
184
|
cmd_plugin_disable() {
|
|
180
185
|
require_workspace
|
|
181
186
|
_is_local=0
|
|
@@ -215,6 +220,9 @@ cmd_plugin_disable() {
|
|
|
215
220
|
cmd_sync -q
|
|
216
221
|
}
|
|
217
222
|
|
|
223
|
+
# Toggle the member repository .rnex harness (enable or disable) for a specific repo.
|
|
224
|
+
# Usage:
|
|
225
|
+
# rnex rnex-dir <enable|disable> <name> [--local]
|
|
218
226
|
cmd_rnex_dir() {
|
|
219
227
|
require_workspace
|
|
220
228
|
_action=""
|
package/lib/commands/repo.sh
CHANGED
|
@@ -4,25 +4,31 @@
|
|
|
4
4
|
# lib/commands/repo.sh — Member repository management commands
|
|
5
5
|
# ============================================================================
|
|
6
6
|
|
|
7
|
+
# Register a new repository in workspace configuration and clone it into ./repos/<name>.
|
|
8
|
+
# Usage:
|
|
9
|
+
# rnex add [--local] [--disabled] [--readonly] [<name>] <git-url>
|
|
10
|
+
# If <name> is omitted, it is inferred from the last component of <git-url>.
|
|
7
11
|
cmd_add() {
|
|
8
12
|
require_workspace
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
_rnex_dir="true"
|
|
13
|
+
_arg1=""
|
|
14
|
+
_arg2=""
|
|
12
15
|
_enabled="true"
|
|
16
|
+
_readonly="false"
|
|
13
17
|
_is_local=0
|
|
14
18
|
|
|
15
19
|
while [ $# -gt 0 ]; do
|
|
16
20
|
case "$1" in
|
|
17
21
|
--local) _is_local=1 ;;
|
|
18
22
|
--disabled) _enabled="false" ;;
|
|
19
|
-
--
|
|
20
|
-
--rnex-dir|--rnex-dir=true)
|
|
23
|
+
--readonly) _readonly="true" ;;
|
|
24
|
+
--no-rnex-dir|--rnex-dir=false|--rnex-dir|--rnex-dir=true)
|
|
25
|
+
# Obsolete flag ignored after transition to on-demand member .rnex
|
|
26
|
+
;;
|
|
21
27
|
*)
|
|
22
|
-
if [ -z "$
|
|
23
|
-
|
|
24
|
-
elif [ -z "$
|
|
25
|
-
|
|
28
|
+
if [ -z "$_arg1" ]; then
|
|
29
|
+
_arg1="$1"
|
|
30
|
+
elif [ -z "$_arg2" ]; then
|
|
31
|
+
_arg2="$1"
|
|
26
32
|
else
|
|
27
33
|
die "Unexpected argument: $1"
|
|
28
34
|
fi
|
|
@@ -31,8 +37,21 @@ cmd_add() {
|
|
|
31
37
|
shift
|
|
32
38
|
done
|
|
33
39
|
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
# Derive repo name and URL:
|
|
41
|
+
# - If 2 positional args: <name> <git-url>
|
|
42
|
+
# - If 1 positional arg: <git-url> (name inferred from the last component of the path/URL)
|
|
43
|
+
if [ -n "$_arg2" ]; then
|
|
44
|
+
_name="$_arg1"
|
|
45
|
+
_url="$_arg2"
|
|
46
|
+
elif [ -n "$_arg1" ]; then
|
|
47
|
+
_url="$_arg1"
|
|
48
|
+
_name="$(repo_name_from_path "$_url")"
|
|
49
|
+
else
|
|
50
|
+
die "Usage: rnex add [--local] [--disabled] [--readonly] [<name>] <git-url>"
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
[ -n "$_name" ] || die "Could not determine repository name from '$_url'"
|
|
54
|
+
[ -n "$_url" ] || die "Usage: rnex add [--local] [--disabled] [--readonly] [<name>] <git-url>"
|
|
36
55
|
|
|
37
56
|
ensure_repos_dir
|
|
38
57
|
_target_dir="$(resolve_repo_path "$_name")"
|
|
@@ -47,7 +66,7 @@ cmd_add() {
|
|
|
47
66
|
|
|
48
67
|
if [ "$_is_local" -eq 1 ]; then
|
|
49
68
|
yaml_set_local "$_name" "url" "$_url"
|
|
50
|
-
[ "$
|
|
69
|
+
[ "$_readonly" = "true" ] && yaml_set_local "$_name" "readonly" "true"
|
|
51
70
|
[ "$_enabled" = "false" ] && yaml_set_local "$_name" "enabled" "false"
|
|
52
71
|
sync_repo_rnex "$_name"
|
|
53
72
|
sync_code_workspace
|
|
@@ -64,7 +83,7 @@ cmd_add() {
|
|
|
64
83
|
die "Repo '$_name' is already registered in $(basename "$WORKSPACE_YAML")"
|
|
65
84
|
else
|
|
66
85
|
yaml_set "$_name" "url" "$_url"
|
|
67
|
-
[ "$
|
|
86
|
+
[ "$_readonly" = "true" ] && yaml_set "$_name" "readonly" "true"
|
|
68
87
|
[ "$_enabled" = "false" ] && yaml_set "$_name" "enabled" "false"
|
|
69
88
|
sync_repo_rnex "$_name"
|
|
70
89
|
sync_code_workspace
|
|
@@ -75,7 +94,7 @@ cmd_add() {
|
|
|
75
94
|
fi
|
|
76
95
|
fi
|
|
77
96
|
|
|
78
|
-
yaml_add_repo "$_name" "$_url" "$
|
|
97
|
+
yaml_add_repo "$_name" "$_url" "$_enabled" "$_readonly"
|
|
79
98
|
sync_repo_rnex "$_name"
|
|
80
99
|
sync_code_workspace
|
|
81
100
|
run_hook "after_sync" "$@"
|
|
@@ -83,6 +102,8 @@ cmd_add() {
|
|
|
83
102
|
log_ok "Registered and added repo '${_name}'"
|
|
84
103
|
}
|
|
85
104
|
|
|
105
|
+
# Clone all enabled repositories declared in configuration that are not yet cloned.
|
|
106
|
+
# Skips disabled repositories and already existing clones.
|
|
86
107
|
cmd_clone() {
|
|
87
108
|
require_workspace
|
|
88
109
|
ensure_repos_dir
|
|
@@ -127,6 +148,8 @@ cmd_clone() {
|
|
|
127
148
|
printf '\n'
|
|
128
149
|
}
|
|
129
150
|
|
|
151
|
+
# Execute a shell command across all enabled member repositories in ./repos/<name>.
|
|
152
|
+
# Propagates non-zero exit codes if any repository command fails.
|
|
130
153
|
cmd_exec() {
|
|
131
154
|
require_workspace
|
|
132
155
|
[ $# -gt 0 ] || die "Usage: rnex exec <command...>"
|
|
@@ -198,6 +221,7 @@ _repo_toggle_state() {
|
|
|
198
221
|
_repo_set_config_and_log "$_name" "enabled" "$_target_val" "$_is_local" "$_verb"
|
|
199
222
|
}
|
|
200
223
|
|
|
224
|
+
# Enable a member repository in configuration and reconcile its workspace state.
|
|
201
225
|
cmd_enable() {
|
|
202
226
|
_repo_toggle_state "true" "Enabled repo" "$@"
|
|
203
227
|
sync_repo_rnex "$_name"
|
|
@@ -205,6 +229,7 @@ cmd_enable() {
|
|
|
205
229
|
run_hook "after_sync" "$@"
|
|
206
230
|
}
|
|
207
231
|
|
|
232
|
+
# Disable a member repository in configuration (skips execution and hides from IDE).
|
|
208
233
|
cmd_disable() {
|
|
209
234
|
_repo_toggle_state "false" "Disabled repo" "$@"
|
|
210
235
|
sync_code_workspace
|
|
@@ -218,6 +243,57 @@ cmd_hide() {
|
|
|
218
243
|
cmd_disable "$@"
|
|
219
244
|
}
|
|
220
245
|
|
|
246
|
+
# Toggle the member repository read-only setting (enable or disable) for a specific repo.
|
|
247
|
+
# When a repository is read-only, it is strictly used for information / reference.
|
|
248
|
+
# Usage:
|
|
249
|
+
# rnex readonly <enable|disable> <name> [--local]
|
|
250
|
+
cmd_readonly() {
|
|
251
|
+
require_workspace
|
|
252
|
+
_action=""
|
|
253
|
+
_name=""
|
|
254
|
+
_is_local=0
|
|
255
|
+
|
|
256
|
+
while [ $# -gt 0 ]; do
|
|
257
|
+
case "$1" in
|
|
258
|
+
--local) _is_local=1 ;;
|
|
259
|
+
enable|true|yes|1)
|
|
260
|
+
if [ -z "$_action" ]; then _action="true"; else _name="$1"; fi
|
|
261
|
+
;;
|
|
262
|
+
disable|false|no|0)
|
|
263
|
+
if [ -z "$_action" ]; then _action="false"; else _name="$1"; fi
|
|
264
|
+
;;
|
|
265
|
+
*)
|
|
266
|
+
if [ -z "$_action" ] && [ "$1" = "enable" ] || [ "$1" = "disable" ]; then
|
|
267
|
+
_action="$1"
|
|
268
|
+
elif [ -z "$_name" ]; then
|
|
269
|
+
_name="$1"
|
|
270
|
+
elif [ -z "$_action" ]; then
|
|
271
|
+
_action="$1"
|
|
272
|
+
fi
|
|
273
|
+
;;
|
|
274
|
+
esac
|
|
275
|
+
shift
|
|
276
|
+
done
|
|
277
|
+
|
|
278
|
+
case "$_action" in
|
|
279
|
+
enable|true|yes|1) _action="true" ;;
|
|
280
|
+
disable|false|no|0) _action="false" ;;
|
|
281
|
+
"") _action="true" ;;
|
|
282
|
+
esac
|
|
283
|
+
|
|
284
|
+
[ -n "$_name" ] || die "Usage: rnex readonly <enable|disable> <name> [--local]"
|
|
285
|
+
yaml_has_repo "$_name" || die "Repo '$_name' is not registered"
|
|
286
|
+
|
|
287
|
+
if [ "$_action" = "true" ]; then
|
|
288
|
+
_repo_set_config_and_log "$_name" "readonly" "true" "$_is_local" "Marked repo as read-only"
|
|
289
|
+
else
|
|
290
|
+
_repo_set_config_and_log "$_name" "readonly" "false" "$_is_local" "Disabled read-only mode for"
|
|
291
|
+
fi
|
|
292
|
+
sync_code_workspace
|
|
293
|
+
run_hook "after_sync" "$@"
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
# Remove a member repository from configuration and delete its local directory in ./repos/<name>.
|
|
221
297
|
cmd_remove() {
|
|
222
298
|
require_workspace
|
|
223
299
|
_name=""
|
|
@@ -251,9 +327,11 @@ cmd_remove() {
|
|
|
251
327
|
run_hook "after_sync" "$@"
|
|
252
328
|
}
|
|
253
329
|
|
|
330
|
+
# Print a tabular status list of all registered member repositories, showing
|
|
331
|
+
# state (enabled/disabled), clone status, active git branch, readonly status, and URL.
|
|
254
332
|
cmd_list() {
|
|
255
333
|
require_workspace
|
|
256
|
-
printf '\n%b%-18s %-10s %-8s %-14s %-10s %s%b\n' "$_B" "NAME" "STATE" "CLONED" "BRANCH" "
|
|
334
|
+
printf '\n%b%-18s %-10s %-8s %-14s %-10s %s%b\n' "$_B" "NAME" "STATE" "CLONED" "BRANCH" "READONLY" "URL" "$_NC"
|
|
257
335
|
printf '%-18s %-10s %-8s %-14s %-10s %s\n' "----" "-----" "------" "------" "--------" "---"
|
|
258
336
|
yaml_list_repos | while read -r _name; do
|
|
259
337
|
[ -n "$_name" ] || continue
|
|
@@ -275,13 +353,13 @@ cmd_list() {
|
|
|
275
353
|
[ -n "$_b" ] && _branch="$_b"
|
|
276
354
|
fi
|
|
277
355
|
|
|
278
|
-
|
|
279
|
-
if
|
|
280
|
-
|
|
356
|
+
_ro="false"
|
|
357
|
+
if yaml_repo_readonly "$_name"; then
|
|
358
|
+
_ro="${_Y}true${_NC}"
|
|
281
359
|
fi
|
|
282
360
|
|
|
283
|
-
printf '%-18s %-19b %-17b %-14s %-
|
|
284
|
-
"$_name" "$_state" "$_cloned" "$_branch" "$
|
|
361
|
+
printf '%-18s %-19b %-17b %-14s %-19b %s\n' \
|
|
362
|
+
"$_name" "$_state" "$_cloned" "$_branch" "$_ro" "${_url:-(none)}"
|
|
285
363
|
done
|
|
286
364
|
printf '\n'
|
|
287
365
|
}
|
package/lib/commands/status.sh
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# lib/commands/status.sh — Workspace health and status diagnostics
|
|
5
5
|
# ============================================================================
|
|
6
6
|
|
|
7
|
+
# Query active plugins for any non-manual lint triggers (e.g. git hook triggers).
|
|
7
8
|
_status_active_plugin_trigger() {
|
|
8
9
|
for _p in $(yaml_list_plugins 2>/dev/null || true); do
|
|
9
10
|
yaml_plugin_enabled "$_p" 2>/dev/null || continue
|
|
@@ -17,10 +18,14 @@ _status_active_plugin_trigger() {
|
|
|
17
18
|
return 0
|
|
18
19
|
}
|
|
19
20
|
|
|
21
|
+
# Check if a directory contains any rnex-* user skills or skill symlinks.
|
|
20
22
|
_status_has_rnex_skills() {
|
|
21
23
|
[ -d "$1" ] && { ls "$1"/rnex-*.md >/dev/null 2>&1 || ls -d "$1"/rnex-* >/dev/null 2>&1; }
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
# Print comprehensive read-only workspace diagnostic report:
|
|
27
|
+
# Shows config versions, gitignore rules, AI context routing, registered plugins,
|
|
28
|
+
# git hooks status, and member repository status.
|
|
24
29
|
cmd_status() {
|
|
25
30
|
require_workspace
|
|
26
31
|
ensure_repos_dir
|
|
@@ -146,6 +151,7 @@ cmd_status() {
|
|
|
146
151
|
for _pair in \
|
|
147
152
|
"CLAUDE.md:Claude" \
|
|
148
153
|
"GEMINI.md:Gemini" \
|
|
154
|
+
"CODEX.md:Codex" \
|
|
149
155
|
".cursorrules:Cursor" \
|
|
150
156
|
".windsurfrules:Windsurf" \
|
|
151
157
|
".github/copilot-instructions.md:Copilot"; do
|
|
@@ -179,6 +185,7 @@ cmd_status() {
|
|
|
179
185
|
".windsurf/rules/:Windsurf" \
|
|
180
186
|
".agents/skills/:Gemini" \
|
|
181
187
|
".gemini/skills/:Gemini" \
|
|
188
|
+
".codex/skills/:Codex" \
|
|
182
189
|
".github/skills/:Copilot"; do
|
|
183
190
|
_sdir="${_spair%%:*}"
|
|
184
191
|
_slbl="${_spair#*:}"
|
|
@@ -235,7 +242,7 @@ cmd_status() {
|
|
|
235
242
|
printf '%b%s%b\n' "$_BOLD" "Member Repositories:" "$_NC"
|
|
236
243
|
_all_repos="$(yaml_list_repos)"
|
|
237
244
|
if [ -z "$_all_repos" ]; then
|
|
238
|
-
printf ' %b%s%b\n' "$_DIM" "(No repositories registered yet. Use 'rnex add <name> <git-url>')" "$_NC"
|
|
245
|
+
printf ' %b%s%b\n' "$_DIM" "(No repositories registered yet. Use 'rnex add [<name>] <git-url>')" "$_NC"
|
|
239
246
|
else
|
|
240
247
|
echo "$_all_repos" | while read -r _name; do
|
|
241
248
|
[ -n "$_name" ] || continue
|
|
@@ -247,17 +254,14 @@ cmd_status() {
|
|
|
247
254
|
printf ' %b○%b %-18s %b[disabled]%b %s\n' "$_DIM" "$_NC" "$_name" "$_DIM" "$_NC" "${_url:+- $_url}"
|
|
248
255
|
elif [ -d "$_rdir/.git" ]; then
|
|
249
256
|
_b="$(git -C "$_rdir" symbolic-ref --short HEAD 2>/dev/null || git -C "$_rdir" rev-parse --short HEAD 2>/dev/null || echo "head")"
|
|
250
|
-
|
|
251
|
-
if
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
fi
|
|
257
|
-
else
|
|
258
|
-
_rnex_tag=" ${_DIM}[.rnex off]${_NC}"
|
|
257
|
+
_tags=""
|
|
258
|
+
if yaml_repo_readonly "$_name"; then
|
|
259
|
+
_tags=" ${_Y}[readonly]${_NC}"
|
|
260
|
+
fi
|
|
261
|
+
if [ -d "$_rdir/.rnex" ]; then
|
|
262
|
+
_tags="${_tags} ${_DIM}[.rnex]${_NC}"
|
|
259
263
|
fi
|
|
260
|
-
printf ' %b●%b %-18s %b[%s]%b%b %s\n' "$_G" "$_NC" "$_name" "$_C" "$_b" "$_NC" "$
|
|
264
|
+
printf ' %b●%b %-18s %b[%s]%b%b %s\n' "$_G" "$_NC" "$_name" "$_C" "$_b" "$_NC" "$_tags" "${_url:+- $_url}"
|
|
261
265
|
else
|
|
262
266
|
printf ' %b✗%b %-18s %b[missing — run "rnex clone"]%b %s\n' "$_R" "$_NC" "$_name" "$_R" "$_NC" "${_url:+- $_url}"
|
|
263
267
|
fi
|
package/lib/commands/sync.sh
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
# lib/commands/sync.sh — Workspace reconciliation and compilation
|
|
5
5
|
# ============================================================================
|
|
6
6
|
|
|
7
|
+
# Write the standalone .rnex/bin/auto-sync.sh helper used by hooks and subshells
|
|
8
|
+
# to rapidly verify workspace stamp checksum and trigger rnex sync on config changes.
|
|
7
9
|
_write_auto_sync_script() {
|
|
8
10
|
_dir="${1:-$NEXUS_DIR}"
|
|
9
11
|
_bin_dir="$_dir/.rnex/bin"
|
|
@@ -31,6 +33,12 @@ EOF
|
|
|
31
33
|
chmod +x "$_script"
|
|
32
34
|
}
|
|
33
35
|
|
|
36
|
+
# Primary workspace reconciliation command:
|
|
37
|
+
# Reconciles workspace configuration version, .gitignore / .ignore routing, AGENTS.md,
|
|
38
|
+
# core skills, AI instruction compilation, active plugins, Git hooks, member .rnex
|
|
39
|
+
# harnesses, and VS Code / Cursor workspace files.
|
|
40
|
+
# Usage:
|
|
41
|
+
# rnex sync [-y|--yes] [-q|--quiet] [--upgrade]
|
|
34
42
|
cmd_sync() {
|
|
35
43
|
require_workspace
|
|
36
44
|
ensure_repos_dir
|
package/lib/commands/system.sh
CHANGED
|
@@ -4,18 +4,47 @@
|
|
|
4
4
|
# lib/commands/system.sh — System commands: install, version, help
|
|
5
5
|
# ============================================================================
|
|
6
6
|
|
|
7
|
+
# Install rnex and repo-nexus executables and asset libraries into user bin and share directories.
|
|
7
8
|
cmd_install() {
|
|
8
|
-
_target_bin="${1:-$HOME/.local/bin}"
|
|
9
|
+
_target_bin="${1:-${RNEX_BIN_DIR:-$HOME/.local/bin}}"
|
|
9
10
|
_target_bin="$(resolve_path "$_target_bin")"
|
|
10
11
|
mkdir -p "$_target_bin"
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
[ -f "$
|
|
13
|
+
_src_root="$SCRIPT_LOCATION"
|
|
14
|
+
[ -f "$_src_root/rnex" ] || _src_root="$(dirname "$SCRIPT_LOCATION")"
|
|
15
|
+
_source_cli="$_src_root/rnex"
|
|
14
16
|
[ -f "$_source_cli" ] || die "Could not locate source CLI executable to install"
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
if [ -n "${RNEX_INSTALL_DIR:-}" ]; then
|
|
19
|
+
_install_dir="$(resolve_path "$RNEX_INSTALL_DIR")"
|
|
20
|
+
elif [ -n "${1:-}" ]; then
|
|
21
|
+
case "$(basename "$_target_bin")" in
|
|
22
|
+
bin) _install_dir="$(dirname "$_target_bin")/share/repo-nexus" ;;
|
|
23
|
+
*) _install_dir="$_target_bin" ;;
|
|
24
|
+
esac
|
|
25
|
+
else
|
|
26
|
+
_install_dir="$HOME/.local/share/repo-nexus"
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
mkdir -p "$_install_dir"
|
|
30
|
+
if [ "$_src_root" != "$_install_dir" ]; then
|
|
31
|
+
rm -rf "$_install_dir/docs"
|
|
32
|
+
cp "$_source_cli" "$_install_dir/rnex"
|
|
33
|
+
[ -f "$_src_root/package.json" ] && cp "$_src_root/package.json" "$_install_dir/package.json"
|
|
34
|
+
for _asset in lib templates toolkit; do
|
|
35
|
+
if [ -d "$_src_root/$_asset" ]; then
|
|
36
|
+
rm -rf "${_install_dir:?}/$_asset"
|
|
37
|
+
cp -R "$_src_root/$_asset" "$_install_dir/$_asset"
|
|
38
|
+
fi
|
|
39
|
+
done
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
_installed_cli="$_install_dir/rnex"
|
|
43
|
+
chmod +x "$_installed_cli"
|
|
44
|
+
if [ "$_target_bin" != "$_install_dir" ]; then
|
|
45
|
+
ln -sf "$_installed_cli" "$_target_bin/rnex"
|
|
46
|
+
fi
|
|
47
|
+
ln -sf "$_installed_cli" "$_target_bin/repo-nexus"
|
|
19
48
|
|
|
20
49
|
log_ok "Installed 'rnex' and 'repo-nexus' into $_target_bin"
|
|
21
50
|
case ":$PATH:" in
|
|
@@ -28,10 +57,12 @@ cmd_install() {
|
|
|
28
57
|
esac
|
|
29
58
|
}
|
|
30
59
|
|
|
60
|
+
# Output current Repo Nexus version from package.json.
|
|
31
61
|
cmd_version() {
|
|
32
62
|
printf 'rnex %s\n' "$RNEX_VERSION"
|
|
33
63
|
}
|
|
34
64
|
|
|
65
|
+
# Check workspace configuration version against current CLI and run sync to upgrade if needed.
|
|
35
66
|
cmd_update() {
|
|
36
67
|
require_workspace
|
|
37
68
|
_cmp=0
|
|
@@ -48,6 +79,7 @@ cmd_upgrade() {
|
|
|
48
79
|
cmd_update "$@"
|
|
49
80
|
}
|
|
50
81
|
|
|
82
|
+
# Display complete CLI usage, command catalog, options, and practical examples.
|
|
51
83
|
cmd_help() {
|
|
52
84
|
cat <<EOF
|
|
53
85
|
|
|
@@ -63,7 +95,7 @@ cmd_help() {
|
|
|
63
95
|
-v, --version Show version
|
|
64
96
|
|
|
65
97
|
WORKSPACE & SYSTEM SETUP
|
|
66
|
-
init [-y] [--code-workspace [file]] [--hooks|--no-hooks] [--copilot] [--claude] [--gemini] [--cursor] [--windsurf] [--karpathy] [dir]
|
|
98
|
+
init [-y] [--code-workspace [file]] [--hooks|--no-hooks] [--copilot] [--claude] [--gemini] [--codex] [--cursor] [--windsurf] [--karpathy] [dir]
|
|
67
99
|
Initialize a new Repo Nexus workspace (default: AGENTS.md)
|
|
68
100
|
install [dir] Install rnex & repo-nexus globally into ~/.local/bin (or custom dir)
|
|
69
101
|
sync [-y] [--quiet] Reconcile workspace, plugins, skills, member .rnex directories, and compile AI instructions
|
|
@@ -75,15 +107,16 @@ cmd_help() {
|
|
|
75
107
|
completion <shell> Generate shell completion script (bash, zsh, fish)
|
|
76
108
|
|
|
77
109
|
REPO MANAGEMENT
|
|
78
|
-
add [--local] [--disabled] [--
|
|
110
|
+
add [--local] [--disabled] [--readonly] [<name>] <git-url>
|
|
79
111
|
Register and clone repo (--local writes to .local.rnex.yaml)
|
|
80
112
|
clone Clone all missing enabled repositories declared in rnex.yaml
|
|
81
113
|
exec <command...> Execute a shell command across all active member repositories
|
|
82
114
|
remove <name> Unregister and delete member repository
|
|
83
115
|
enable [--local] <name> Enable a member repository in active workspace
|
|
84
116
|
disable [--local] <name> Disable a member repository in workspace
|
|
117
|
+
readonly [--local] <enable|disable> <name>
|
|
118
|
+
Toggle read-only (information-only) status for a member repo
|
|
85
119
|
list List all member repositories with clone state & active branch
|
|
86
|
-
rnex-dir <enable|disable> <name> Toggle .rnex directory integration for a member repo
|
|
87
120
|
|
|
88
121
|
PLUGIN MANAGEMENT
|
|
89
122
|
plugin [list] List available and enabled plugins
|