nexus-dev-toolkit 3.1.3__tar.gz → 3.1.5__tar.gz
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.
- {nexus_dev_toolkit-3.1.3/nexus_dev_toolkit.egg-info → nexus_dev_toolkit-3.1.5}/PKG-INFO +22 -10
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/README.md +21 -9
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/nexus_cli.py +176 -43
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5/nexus_dev_toolkit.egg-info}/PKG-INFO +22 -10
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/nexus_dev_toolkit.egg-info/SOURCES.txt +3 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/pyproject.toml +1 -1
- nexus_dev_toolkit-3.1.5/tests/test_cli.py +489 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/agents/code-reviewer.md +37 -44
- nexus_dev_toolkit-3.1.5/tools/epav/graph_backend.py +88 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/epav/skills/apply.md +5 -2
- nexus_dev_toolkit-3.1.5/tools/epav/skills/code-review.md +24 -0
- nexus_dev_toolkit-3.1.5/tools/epav/skills/commit.md +48 -0
- nexus_dev_toolkit-3.1.5/tools/epav/skills/create-pr.md +64 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/epav/skills/epav.md +1 -1
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/epav/skills/evaluate.md +9 -6
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/epav/skills/plan.md +4 -4
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/epav/skills/validate.md +5 -5
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/epav/task_loader.py +7 -20
- nexus_dev_toolkit-3.1.3/tests/test_cli.py +0 -225
- nexus_dev_toolkit-3.1.3/tools/epav/skills/code-review.md +0 -91
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/LICENSE +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/nexus_dev_toolkit.egg-info/dependency_links.txt +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/nexus_dev_toolkit.egg-info/entry_points.txt +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/nexus_dev_toolkit.egg-info/requires.txt +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/nexus_dev_toolkit.egg-info/top_level.txt +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/nexus_server.py +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/setup.cfg +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tests/test_server.py +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/__init__.py +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/agents/__init__.py +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/agents/database-reviewer.md +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/agents/deployment-reviewer.md +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/agents/monitoring-reviewer.md +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/agents/performance-reviewer.md +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/epav/__init__.py +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/epav/arch_ingest.py +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/epav/package_resolver.py +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/epav/project_rules.py +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/epav/skills/__init__.py +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/epav/skills/database-review.md +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/epav/skills/deployment-review.md +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/epav/skills/monitoring-review.md +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/epav/skills/performance-review.md +0 -0
- {nexus_dev_toolkit-3.1.3 → nexus_dev_toolkit-3.1.5}/tools/epav/skills/scaffold.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nexus-dev-toolkit
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.5
|
|
4
4
|
Summary: Developer workflow toolkit for Claude Code — Day 0 scaffold + Day 1 EPAV
|
|
5
5
|
Author-email: Ronald dela Cruz <rcdelacruz@users.noreply.github.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -22,7 +22,7 @@ Dynamic: license-file
|
|
|
22
22
|
# nexus-dev-toolkit
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
Developer workflow toolkit for Claude Code. Gives any team a structured Day 0 scaffold and repeatable Day 1 feature cycle via the EPAV methodology.
|
|
25
|
+
Developer workflow toolkit for Claude Code and OpenCode. Gives any team a structured Day 0 scaffold and repeatable Day 1 feature cycle via the EPAV methodology.
|
|
26
26
|
|
|
27
27
|
**[Documentation](https://nexus.coderstudio.co/docs)**
|
|
28
28
|
|
|
@@ -70,6 +70,13 @@ uv tool install graphifyy # PyPI package name has double y; command is "graphi
|
|
|
70
70
|
graphify install # registers /graphify skill into Claude Code
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
**codegraph** _(alternative to graphify)_ — a different knowledge-graph tool EPAV skills can use instead. Pick one, not both; `nexus doctor` warns if it finds graphs from both built in the same project.
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npm i -g @colbymchenry/codegraph
|
|
77
|
+
codegraph install # wires codegraph into Claude Code / OpenCode / etc.
|
|
78
|
+
```
|
|
79
|
+
|
|
73
80
|
### 2. Install nexus-dev-toolkit
|
|
74
81
|
|
|
75
82
|
```bash
|
|
@@ -80,8 +87,9 @@ uv tool install nexus-dev-toolkit
|
|
|
80
87
|
|
|
81
88
|
```bash
|
|
82
89
|
cd my-project
|
|
83
|
-
nexus init .
|
|
84
|
-
nexus init . --tool opencode
|
|
90
|
+
nexus init . # Claude Code (default), prompts for graphify/codegraph/none
|
|
91
|
+
nexus init . --tool opencode # OpenCode
|
|
92
|
+
nexus init . --graph-backend codegraph # skip the prompt, use codegraph
|
|
85
93
|
```
|
|
86
94
|
|
|
87
95
|
### 4. Place your reference docs
|
|
@@ -111,12 +119,13 @@ Open the project in Claude Code and run:
|
|
|
111
119
|
|
|
112
120
|
### 6. Build the knowledge graph
|
|
113
121
|
|
|
114
|
-
After `/scaffold` completes,
|
|
122
|
+
After `/scaffold` completes, build whichever backend you chose at init:
|
|
115
123
|
```
|
|
116
|
-
/graphify .
|
|
124
|
+
/graphify . # if you chose graphify
|
|
125
|
+
codegraph install && codegraph init # if you chose codegraph, run in your terminal
|
|
117
126
|
```
|
|
118
127
|
|
|
119
|
-
This generates `graphify-out/graph.json`
|
|
128
|
+
This generates `graphify-out/graph.json` or `.codegraph/codegraph.db` — EPAV skills use whichever is present, or fall back to full file reads if neither is built yet. Run `nexus doctor` any time to check which backend is active.
|
|
120
129
|
|
|
121
130
|
---
|
|
122
131
|
|
|
@@ -138,12 +147,14 @@ Each step is a built-in skill in `.claude/commands/`. Every task starts from the
|
|
|
138
147
|
|
|
139
148
|
## What `nexus init` Creates
|
|
140
149
|
|
|
150
|
+
`settings.json`/`graphify.js` below are only created if you pick graphify (the default) at the `--graph-backend` prompt. Pick codegraph instead and neither is scaffolded — codegraph wires and syncs itself via `codegraph install && codegraph init`.
|
|
151
|
+
|
|
141
152
|
**Claude Code** (`nexus init .`):
|
|
142
153
|
```
|
|
143
154
|
.claude/
|
|
144
155
|
├── commands/ ← EPAV skills + 5 reviewer skills (/code-review, etc.)
|
|
145
156
|
├── agents/ ← 5 reviewer subagents (code-reviewer, database-reviewer, etc.)
|
|
146
|
-
└── settings.json ← PostToolUse: graphify auto-updates after every file edit
|
|
157
|
+
└── settings.json ← PostToolUse: graphify auto-updates after every file edit (graphify backend only)
|
|
147
158
|
knowledge/
|
|
148
159
|
├── rules/ ← coding standards, arch decisions
|
|
149
160
|
├── patterns/ ← reusable implementation patterns
|
|
@@ -158,7 +169,7 @@ knowledge/
|
|
|
158
169
|
├── commands/ ← same EPAV skills + reviewer skills
|
|
159
170
|
├── agents/ ← same reviewer subagents (adapted for OpenCode)
|
|
160
171
|
└── plugins/
|
|
161
|
-
└── graphify.js ← tool.execute.after: graphify auto-update
|
|
172
|
+
└── graphify.js ← tool.execute.after: graphify auto-update (graphify backend only)
|
|
162
173
|
knowledge/ ← same structure
|
|
163
174
|
opencode.json ← MCP server config
|
|
164
175
|
```
|
|
@@ -171,7 +182,8 @@ opencode.json ← MCP server config
|
|
|
171
182
|
nexus init . # Claude Code — set up .claude/ + knowledge/ + .mcp.json
|
|
172
183
|
nexus init . --tool opencode # OpenCode — set up .opencode/ + knowledge/ + opencode.json
|
|
173
184
|
nexus --version # show installed version
|
|
174
|
-
nexus update # update to
|
|
185
|
+
nexus update # update the CLI itself; asks whether to also sync in a real terminal
|
|
186
|
+
nexus update --sync # skip the prompt, always sync the current project's skills/agents too
|
|
175
187
|
nexus sync # sync built-in skills & agents to latest (custom files untouched)
|
|
176
188
|
nexus doctor # validate project setup
|
|
177
189
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# nexus-dev-toolkit
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
Developer workflow toolkit for Claude Code. Gives any team a structured Day 0 scaffold and repeatable Day 1 feature cycle via the EPAV methodology.
|
|
4
|
+
Developer workflow toolkit for Claude Code and OpenCode. Gives any team a structured Day 0 scaffold and repeatable Day 1 feature cycle via the EPAV methodology.
|
|
5
5
|
|
|
6
6
|
**[Documentation](https://nexus.coderstudio.co/docs)**
|
|
7
7
|
|
|
@@ -49,6 +49,13 @@ uv tool install graphifyy # PyPI package name has double y; command is "graphi
|
|
|
49
49
|
graphify install # registers /graphify skill into Claude Code
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
**codegraph** _(alternative to graphify)_ — a different knowledge-graph tool EPAV skills can use instead. Pick one, not both; `nexus doctor` warns if it finds graphs from both built in the same project.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm i -g @colbymchenry/codegraph
|
|
56
|
+
codegraph install # wires codegraph into Claude Code / OpenCode / etc.
|
|
57
|
+
```
|
|
58
|
+
|
|
52
59
|
### 2. Install nexus-dev-toolkit
|
|
53
60
|
|
|
54
61
|
```bash
|
|
@@ -59,8 +66,9 @@ uv tool install nexus-dev-toolkit
|
|
|
59
66
|
|
|
60
67
|
```bash
|
|
61
68
|
cd my-project
|
|
62
|
-
nexus init .
|
|
63
|
-
nexus init . --tool opencode
|
|
69
|
+
nexus init . # Claude Code (default), prompts for graphify/codegraph/none
|
|
70
|
+
nexus init . --tool opencode # OpenCode
|
|
71
|
+
nexus init . --graph-backend codegraph # skip the prompt, use codegraph
|
|
64
72
|
```
|
|
65
73
|
|
|
66
74
|
### 4. Place your reference docs
|
|
@@ -90,12 +98,13 @@ Open the project in Claude Code and run:
|
|
|
90
98
|
|
|
91
99
|
### 6. Build the knowledge graph
|
|
92
100
|
|
|
93
|
-
After `/scaffold` completes,
|
|
101
|
+
After `/scaffold` completes, build whichever backend you chose at init:
|
|
94
102
|
```
|
|
95
|
-
/graphify .
|
|
103
|
+
/graphify . # if you chose graphify
|
|
104
|
+
codegraph install && codegraph init # if you chose codegraph, run in your terminal
|
|
96
105
|
```
|
|
97
106
|
|
|
98
|
-
This generates `graphify-out/graph.json`
|
|
107
|
+
This generates `graphify-out/graph.json` or `.codegraph/codegraph.db` — EPAV skills use whichever is present, or fall back to full file reads if neither is built yet. Run `nexus doctor` any time to check which backend is active.
|
|
99
108
|
|
|
100
109
|
---
|
|
101
110
|
|
|
@@ -117,12 +126,14 @@ Each step is a built-in skill in `.claude/commands/`. Every task starts from the
|
|
|
117
126
|
|
|
118
127
|
## What `nexus init` Creates
|
|
119
128
|
|
|
129
|
+
`settings.json`/`graphify.js` below are only created if you pick graphify (the default) at the `--graph-backend` prompt. Pick codegraph instead and neither is scaffolded — codegraph wires and syncs itself via `codegraph install && codegraph init`.
|
|
130
|
+
|
|
120
131
|
**Claude Code** (`nexus init .`):
|
|
121
132
|
```
|
|
122
133
|
.claude/
|
|
123
134
|
├── commands/ ← EPAV skills + 5 reviewer skills (/code-review, etc.)
|
|
124
135
|
├── agents/ ← 5 reviewer subagents (code-reviewer, database-reviewer, etc.)
|
|
125
|
-
└── settings.json ← PostToolUse: graphify auto-updates after every file edit
|
|
136
|
+
└── settings.json ← PostToolUse: graphify auto-updates after every file edit (graphify backend only)
|
|
126
137
|
knowledge/
|
|
127
138
|
├── rules/ ← coding standards, arch decisions
|
|
128
139
|
├── patterns/ ← reusable implementation patterns
|
|
@@ -137,7 +148,7 @@ knowledge/
|
|
|
137
148
|
├── commands/ ← same EPAV skills + reviewer skills
|
|
138
149
|
├── agents/ ← same reviewer subagents (adapted for OpenCode)
|
|
139
150
|
└── plugins/
|
|
140
|
-
└── graphify.js ← tool.execute.after: graphify auto-update
|
|
151
|
+
└── graphify.js ← tool.execute.after: graphify auto-update (graphify backend only)
|
|
141
152
|
knowledge/ ← same structure
|
|
142
153
|
opencode.json ← MCP server config
|
|
143
154
|
```
|
|
@@ -150,7 +161,8 @@ opencode.json ← MCP server config
|
|
|
150
161
|
nexus init . # Claude Code — set up .claude/ + knowledge/ + .mcp.json
|
|
151
162
|
nexus init . --tool opencode # OpenCode — set up .opencode/ + knowledge/ + opencode.json
|
|
152
163
|
nexus --version # show installed version
|
|
153
|
-
nexus update # update to
|
|
164
|
+
nexus update # update the CLI itself; asks whether to also sync in a real terminal
|
|
165
|
+
nexus update --sync # skip the prompt, always sync the current project's skills/agents too
|
|
154
166
|
nexus sync # sync built-in skills & agents to latest (custom files untouched)
|
|
155
167
|
nexus doctor # validate project setup
|
|
156
168
|
|
|
@@ -2,13 +2,17 @@ import json
|
|
|
2
2
|
import shutil
|
|
3
3
|
import subprocess
|
|
4
4
|
import sys
|
|
5
|
+
import urllib.request
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
|
|
7
8
|
import typer
|
|
8
9
|
from rich.console import Console
|
|
10
|
+
from rich.markup import escape
|
|
9
11
|
from rich.table import Table
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
from tools.epav import graph_backend
|
|
14
|
+
|
|
15
|
+
app = typer.Typer(name="nexus", no_args_is_help=False, help="nexus-dev-toolkit — Day 0 scaffold + Day 1 EPAV workflow for Claude Code and OpenCode")
|
|
12
16
|
skill_app = typer.Typer(name="skill", no_args_is_help=True, help="Manage skills in .claude/commands/")
|
|
13
17
|
rule_app = typer.Typer(name="rule", no_args_is_help=True, help="Manage rules in knowledge/rules/")
|
|
14
18
|
agent_app = typer.Typer(name="agent", no_args_is_help=True, help="Manage subagents in .claude/agents/")
|
|
@@ -18,7 +22,31 @@ app.add_typer(agent_app, name="agent")
|
|
|
18
22
|
|
|
19
23
|
console = Console()
|
|
20
24
|
|
|
21
|
-
_VERSION = "3.1.
|
|
25
|
+
_VERSION = "3.1.5"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _fetch_latest_pypi_version() -> str | None:
|
|
29
|
+
"""Fetch the latest published version from PyPI. None on any failure — offline, timeout,
|
|
30
|
+
bad response — never raises."""
|
|
31
|
+
try:
|
|
32
|
+
with urllib.request.urlopen(
|
|
33
|
+
"https://pypi.org/pypi/nexus-dev-toolkit/json", timeout=3
|
|
34
|
+
) as resp:
|
|
35
|
+
return json.loads(resp.read())["info"]["version"]
|
|
36
|
+
except Exception:
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _version_tuple(v: str) -> tuple[int, ...]:
|
|
41
|
+
return tuple(int(part) for part in v.split("."))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _is_outdated(installed: str, latest: str) -> bool:
|
|
45
|
+
try:
|
|
46
|
+
return _version_tuple(latest) > _version_tuple(installed)
|
|
47
|
+
except Exception:
|
|
48
|
+
return False # malformed version string from PyPI — don't false-alarm
|
|
49
|
+
|
|
22
50
|
|
|
23
51
|
_LOGO = """\
|
|
24
52
|
[cyan]███╗ ██╗███████╗██╗ ██╗██╗ ██╗███████╗[/cyan]
|
|
@@ -141,12 +169,12 @@ export const GraphifyPlugin = async ({ directory }) => {
|
|
|
141
169
|
"""
|
|
142
170
|
|
|
143
171
|
|
|
144
|
-
def _init_project(project_dir: Path) -> list[str]:
|
|
172
|
+
def _init_project(project_dir: Path, backend: str = "graphify") -> list[str]:
|
|
145
173
|
"""
|
|
146
174
|
nexus init — sets up:
|
|
147
175
|
.claude/commands/ ← built-in skills
|
|
148
176
|
.claude/agents/ ← built-in subagents
|
|
149
|
-
.claude/settings.json ← PostToolUse graphify hook
|
|
177
|
+
.claude/settings.json ← PostToolUse graphify hook (only when backend == "graphify")
|
|
150
178
|
knowledge/ ← empty scaffold
|
|
151
179
|
"""
|
|
152
180
|
created = []
|
|
@@ -173,11 +201,12 @@ def _init_project(project_dir: Path) -> list[str]:
|
|
|
173
201
|
shutil.copy2(src, dest)
|
|
174
202
|
created.append(f".claude/agents/{agent_name}")
|
|
175
203
|
|
|
176
|
-
# .claude/settings.json — PostToolUse graphify hook
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
settings_path.
|
|
180
|
-
|
|
204
|
+
# .claude/settings.json — PostToolUse graphify hook (codegraph syncs itself, no hook needed)
|
|
205
|
+
if backend == "graphify":
|
|
206
|
+
settings_path = project_dir / ".claude" / "settings.json"
|
|
207
|
+
if not settings_path.exists():
|
|
208
|
+
settings_path.write_text(json.dumps(_CLAUDE_SETTINGS, indent=2))
|
|
209
|
+
created.append(".claude/settings.json")
|
|
181
210
|
|
|
182
211
|
# knowledge/ scaffold
|
|
183
212
|
for d in _KNOWLEDGE_DIRS:
|
|
@@ -201,12 +230,12 @@ def _strip_claude_frontmatter(content: str) -> str:
|
|
|
201
230
|
return "---" + "\n".join(lines) + "---" + parts[2]
|
|
202
231
|
|
|
203
232
|
|
|
204
|
-
def _init_opencode(project_dir: Path) -> list[str]:
|
|
233
|
+
def _init_opencode(project_dir: Path, backend: str = "graphify") -> list[str]:
|
|
205
234
|
"""
|
|
206
235
|
nexus init --tool opencode — sets up:
|
|
207
236
|
.opencode/commands/ ← built-in skills
|
|
208
237
|
.opencode/agents/ ← built-in subagents
|
|
209
|
-
.opencode/plugins/ ← graphify PostToolUse hook
|
|
238
|
+
.opencode/plugins/ ← graphify PostToolUse hook (only when backend == "graphify")
|
|
210
239
|
opencode.json ← MCP server config
|
|
211
240
|
knowledge/ ← empty scaffold
|
|
212
241
|
"""
|
|
@@ -232,13 +261,14 @@ def _init_opencode(project_dir: Path) -> list[str]:
|
|
|
232
261
|
dest.write_text(_strip_claude_frontmatter(src.read_text()), encoding="utf-8")
|
|
233
262
|
created.append(f".opencode/agents/{agent_name}")
|
|
234
263
|
|
|
235
|
-
# .opencode/plugins/graphify.js — PostToolUse hook
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
plugin_path.
|
|
241
|
-
|
|
264
|
+
# .opencode/plugins/graphify.js — PostToolUse hook (codegraph syncs itself, no hook needed)
|
|
265
|
+
if backend == "graphify":
|
|
266
|
+
plugins_dir = project_dir / ".opencode" / "plugins"
|
|
267
|
+
plugins_dir.mkdir(parents=True, exist_ok=True)
|
|
268
|
+
plugin_path = plugins_dir / "graphify.js"
|
|
269
|
+
if not plugin_path.exists():
|
|
270
|
+
plugin_path.write_text(_OPENCODE_GRAPHIFY_PLUGIN, encoding="utf-8")
|
|
271
|
+
created.append(".opencode/plugins/graphify.js")
|
|
242
272
|
|
|
243
273
|
# opencode.json — MCP server config
|
|
244
274
|
opencode_json = project_dir / "opencode.json"
|
|
@@ -306,7 +336,7 @@ def _check_and_offer_install(tool: str) -> None:
|
|
|
306
336
|
console.print(f" [dim]Install manually: {info['install']}[/dim]\n")
|
|
307
337
|
return
|
|
308
338
|
|
|
309
|
-
answer = console.input(f" Install {info['name']} now? [y/N] ").strip().lower()
|
|
339
|
+
answer = console.input(f" Install {info['name']} now? {escape('[y/N]')} ").strip().lower()
|
|
310
340
|
if answer != "y":
|
|
311
341
|
console.print(f" [dim]Skipping. Install manually: {info['install']}[/dim]\n")
|
|
312
342
|
return
|
|
@@ -323,10 +353,36 @@ def _check_and_offer_install(tool: str) -> None:
|
|
|
323
353
|
console.print(f" [red]✗[/red] Install failed. Run manually: {info['install']}\n")
|
|
324
354
|
|
|
325
355
|
|
|
356
|
+
_GRAPH_BACKENDS = {
|
|
357
|
+
"graphify": "existing default — this scaffolds the PostToolUse hook that auto-updates it",
|
|
358
|
+
"codegraph": "you run `codegraph install && codegraph init` yourself — it syncs itself, no hook needed",
|
|
359
|
+
"none": "skip for now — set either up later, `nexus doctor` will detect it",
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
def _resolve_graph_backend(explicit: str | None) -> str:
|
|
364
|
+
if explicit:
|
|
365
|
+
if explicit not in _GRAPH_BACKENDS:
|
|
366
|
+
console.print(f" [red]✗[/red] Unknown --graph-backend '{explicit}'. Choose from: {', '.join(_GRAPH_BACKENDS)}")
|
|
367
|
+
raise typer.Exit(1)
|
|
368
|
+
return explicit
|
|
369
|
+
|
|
370
|
+
if not sys.stdin.isatty():
|
|
371
|
+
return "graphify" # unchanged behavior for CI/scripted `nexus init`
|
|
372
|
+
|
|
373
|
+
console.print(" Which knowledge graph do you want nexus to wire up?")
|
|
374
|
+
console.print(" [cyan]1[/cyan] graphify (default)")
|
|
375
|
+
console.print(" [cyan]2[/cyan] codegraph")
|
|
376
|
+
console.print(" [cyan]3[/cyan] skip for now")
|
|
377
|
+
answer = console.input(f" Choice {escape('[1]')}: ").strip()
|
|
378
|
+
return {"2": "codegraph", "3": "none"}.get(answer, "graphify")
|
|
379
|
+
|
|
380
|
+
|
|
326
381
|
@app.command()
|
|
327
382
|
def init(
|
|
328
383
|
project_dir: str = typer.Argument(".", help="Project directory to initialize"),
|
|
329
384
|
tool: str = typer.Option("claude", "--tool", "-t", help=f"AI coding tool to set up for ({', '.join(_SUPPORTED_TOOLS)})"),
|
|
385
|
+
graph_backend: str = typer.Option(None, "--graph-backend", "-g", help=f"Knowledge graph tool to wire up ({', '.join(_GRAPH_BACKENDS)}). Prompts interactively if omitted."),
|
|
330
386
|
) -> None:
|
|
331
387
|
"""Initialize nexus in a project directory. Defaults to Claude Code."""
|
|
332
388
|
if tool not in _SUPPORTED_TOOLS:
|
|
@@ -335,11 +391,13 @@ def init(
|
|
|
335
391
|
|
|
336
392
|
_check_and_offer_install(tool)
|
|
337
393
|
|
|
394
|
+
backend = _resolve_graph_backend(graph_backend)
|
|
395
|
+
|
|
338
396
|
root = Path(project_dir).resolve()
|
|
339
397
|
console.print(f" [cyan]▶[/cyan] Initializing nexus for [bold]{tool}[/bold] in [bold]{root}[/bold]\n")
|
|
340
398
|
|
|
341
399
|
if tool == "opencode":
|
|
342
|
-
created = _init_opencode(root)
|
|
400
|
+
created = _init_opencode(root, backend)
|
|
343
401
|
for f in created:
|
|
344
402
|
console.print(f" [green]✓[/green] {f}")
|
|
345
403
|
if not created:
|
|
@@ -347,7 +405,7 @@ def init(
|
|
|
347
405
|
return
|
|
348
406
|
console.print(f"\n [bold green]Done.[/bold green] Open [bold]{root}[/bold] in OpenCode and type [cyan]/scaffold[/cyan]\n")
|
|
349
407
|
else:
|
|
350
|
-
created = _init_project(root)
|
|
408
|
+
created = _init_project(root, backend)
|
|
351
409
|
for f in created:
|
|
352
410
|
console.print(f" [green]✓[/green] {f}")
|
|
353
411
|
if not created:
|
|
@@ -357,32 +415,58 @@ def init(
|
|
|
357
415
|
console.print(f" [green]✓[/green] {mcp}")
|
|
358
416
|
console.print(f"\n [bold green]Done.[/bold green] Open [bold]{root}[/bold] in Claude Code and type [cyan]/scaffold[/cyan]\n")
|
|
359
417
|
|
|
418
|
+
if backend == "codegraph":
|
|
419
|
+
console.print(" [cyan]→[/cyan] Next: run [bold]codegraph install && codegraph init[/bold] to wire codegraph into this project (it manages its own auto-sync — no hook needed).\n")
|
|
420
|
+
|
|
360
421
|
|
|
361
422
|
@app.command()
|
|
362
|
-
def update(
|
|
423
|
+
def update(
|
|
424
|
+
also_sync: bool = typer.Option(False, "--sync", "-s", help="Also sync built-in skills/agents in the current directory after upgrading."),
|
|
425
|
+
) -> None:
|
|
363
426
|
"""Update nexus-dev-toolkit to the latest version."""
|
|
364
|
-
|
|
365
|
-
if
|
|
366
|
-
|
|
427
|
+
latest_version = _fetch_latest_pypi_version()
|
|
428
|
+
if latest_version and not _is_outdated(_VERSION, latest_version):
|
|
429
|
+
console.print(f"\n [green]✓[/green] Already up to date (v{_VERSION}).\n")
|
|
367
430
|
else:
|
|
368
|
-
|
|
369
|
-
|
|
431
|
+
console.print("\n [cyan]▶[/cyan] Updating nexus-dev-toolkit…\n")
|
|
432
|
+
if shutil.which("uv"):
|
|
433
|
+
subprocess.run(["uv", "tool", "upgrade", "nexus-dev-toolkit"])
|
|
434
|
+
else:
|
|
435
|
+
subprocess.run([sys.executable, "-m", "pip", "install", "--upgrade", "nexus-dev-toolkit"])
|
|
436
|
+
console.print("\n [green]✓[/green] Done.\n")
|
|
437
|
+
|
|
438
|
+
if not also_sync:
|
|
439
|
+
if sys.stdin.isatty():
|
|
440
|
+
answer = console.input(f" Also sync built-in skills/agents in the current directory? {escape('[y/N]')} ").strip().lower()
|
|
441
|
+
also_sync = answer == "y"
|
|
442
|
+
|
|
443
|
+
if not also_sync:
|
|
444
|
+
console.print(
|
|
445
|
+
" [dim]This only updated the nexus CLI itself. Run [/dim][cyan]nexus sync[/cyan][dim] in each "
|
|
446
|
+
"project to pull the updated skills/agents into .claude/ or .opencode/ — or pass "
|
|
447
|
+
"[/dim][cyan]--sync[/cyan][dim] next time to do both at once.[/dim]\n"
|
|
448
|
+
)
|
|
449
|
+
return
|
|
370
450
|
|
|
451
|
+
root = Path(".").resolve()
|
|
452
|
+
table = _sync_project(root)
|
|
453
|
+
if table is None:
|
|
454
|
+
console.print(" [yellow]⚠[/yellow] Current directory isn't a nexus project — skipping sync.\n")
|
|
455
|
+
return
|
|
371
456
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
457
|
+
console.print(f" [cyan]▶[/cyan] Syncing built-ins in [bold]{root}[/bold]\n")
|
|
458
|
+
console.print(table)
|
|
459
|
+
console.print()
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
def _sync_project(root: Path) -> Table | None:
|
|
463
|
+
"""Sync built-in skills/agents into root. None if root isn't a nexus project (neither
|
|
464
|
+
.claude/ nor .opencode/ present) — callers decide how to handle that case."""
|
|
378
465
|
has_claude = (root / ".claude").is_dir()
|
|
379
466
|
has_opencode = (root / ".opencode").is_dir()
|
|
380
467
|
|
|
381
468
|
if not has_claude and not has_opencode:
|
|
382
|
-
|
|
383
|
-
raise typer.Exit(1)
|
|
384
|
-
|
|
385
|
-
console.print(f"\n [cyan]▶[/cyan] Syncing built-ins in [bold]{root}[/bold]\n")
|
|
469
|
+
return None
|
|
386
470
|
|
|
387
471
|
table = Table(show_header=True, header_style="dim")
|
|
388
472
|
table.add_column("File")
|
|
@@ -452,6 +536,21 @@ def sync(
|
|
|
452
536
|
plugin_dst.write_text(_OPENCODE_GRAPHIFY_PLUGIN, encoding="utf-8")
|
|
453
537
|
table.add_row(".opencode/plugins/graphify.js", "[cyan]updated[/cyan]")
|
|
454
538
|
|
|
539
|
+
return table
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
@app.command()
|
|
543
|
+
def sync(
|
|
544
|
+
project_dir: str = typer.Argument(".", help="Project directory to sync"),
|
|
545
|
+
) -> None:
|
|
546
|
+
"""Sync built-in skills and agents to their latest versions (custom files untouched)."""
|
|
547
|
+
root = Path(project_dir).resolve()
|
|
548
|
+
table = _sync_project(root)
|
|
549
|
+
if table is None:
|
|
550
|
+
console.print(" [red]✗[/red] Not a nexus project. Run [cyan]nexus init[/cyan] first.\n")
|
|
551
|
+
raise typer.Exit(1)
|
|
552
|
+
|
|
553
|
+
console.print(f"\n [cyan]▶[/cyan] Syncing built-ins in [bold]{root}[/bold]\n")
|
|
455
554
|
console.print(table)
|
|
456
555
|
console.print()
|
|
457
556
|
|
|
@@ -480,6 +579,14 @@ def doctor(
|
|
|
480
579
|
has_failure = True
|
|
481
580
|
return f"[red]✗[/red] {msg}"
|
|
482
581
|
|
|
582
|
+
# ── nexus ────────────────────────────────────────────────────────────────
|
|
583
|
+
latest_version = _fetch_latest_pypi_version()
|
|
584
|
+
if latest_version:
|
|
585
|
+
if _is_outdated(_VERSION, latest_version):
|
|
586
|
+
table.add_row("nexus-dev-toolkit", warn(f"update available: v{_VERSION} → v{latest_version} (run: nexus update)"))
|
|
587
|
+
else:
|
|
588
|
+
table.add_row("nexus-dev-toolkit", ok(f"up to date (v{_VERSION})"))
|
|
589
|
+
|
|
483
590
|
# ── Tool ─────────────────────────────────────────────────────────────────
|
|
484
591
|
has_claude_bin = bool(shutil.which("claude"))
|
|
485
592
|
has_opencode_bin = bool(shutil.which("opencode"))
|
|
@@ -568,16 +675,42 @@ def doctor(
|
|
|
568
675
|
else:
|
|
569
676
|
table.add_row("Knowledge dirs", warn(f"missing: {', '.join(missing_dirs)}"))
|
|
570
677
|
|
|
571
|
-
# ──
|
|
572
|
-
has_graphify =
|
|
678
|
+
# ── Knowledge graph backends ────────────────────────────────────────────
|
|
679
|
+
has_graphify = graph_backend.backend_installed("graphify")
|
|
573
680
|
table.add_row("graphify", ok("installed") if has_graphify else warn("not installed — uv tool install graphifyy"))
|
|
574
681
|
|
|
575
|
-
|
|
576
|
-
if
|
|
577
|
-
|
|
682
|
+
has_codegraph = graph_backend.backend_installed("codegraph")
|
|
683
|
+
table.add_row("codegraph", ok("installed") if has_codegraph else warn("not installed — npm i -g @colbymchenry/codegraph"))
|
|
684
|
+
|
|
685
|
+
graphify_built = graph_backend.graph_exists("graphify", root)
|
|
686
|
+
codegraph_built = graph_backend.graph_exists("codegraph", root)
|
|
687
|
+
override = graph_backend.get_override()
|
|
688
|
+
active = graph_backend.detect_backend(root)
|
|
689
|
+
|
|
690
|
+
if graphify_built and codegraph_built:
|
|
691
|
+
if override in graph_backend.BACKEND_NAMES and graph_backend.graph_exists(override, root):
|
|
692
|
+
reason = f"forced via {graph_backend.ENV_VAR}={override}"
|
|
693
|
+
else:
|
|
694
|
+
reason = "graphify wins ties by default"
|
|
695
|
+
table.add_row("Knowledge graph", warn(f"both graphify and codegraph graphs present — using {active} ({reason})"))
|
|
696
|
+
elif graphify_built or codegraph_built:
|
|
697
|
+
built = "graphify" if graphify_built else "codegraph"
|
|
698
|
+
output = "graphify-out/graph.json" if built == "graphify" else ".codegraph/codegraph.db"
|
|
699
|
+
table.add_row("Knowledge graph", ok(f"{output} exists ({built})"))
|
|
578
700
|
else:
|
|
579
|
-
table.add_row("Knowledge graph", warn("not built — run: graphify ."))
|
|
701
|
+
table.add_row("Knowledge graph", warn("not built — run: graphify . (or codegraph init)"))
|
|
580
702
|
|
|
703
|
+
if override and (override not in graph_backend.BACKEND_NAMES or not graph_backend.graph_exists(override, root)):
|
|
704
|
+
table.add_row(
|
|
705
|
+
graph_backend.ENV_VAR,
|
|
706
|
+
warn(f"set to '{override}' but its graph isn't built — ignoring override, run the matching init/build command"),
|
|
707
|
+
)
|
|
708
|
+
|
|
709
|
+
if graph_backend.has_graphify_hook(root) and codegraph_built and active == "codegraph":
|
|
710
|
+
table.add_row("Stale hook", warn("graphify PostToolUse hook present but codegraph is the active backend — harmless no-op, remove manually if unwanted"))
|
|
711
|
+
|
|
712
|
+
console.print()
|
|
713
|
+
console.print(" [dim]Some tools below are alternatives, not companions (e.g. graphify vs codegraph) — nexus flags conflicts here when both are present.[/dim]")
|
|
581
714
|
console.print()
|
|
582
715
|
console.print(table)
|
|
583
716
|
console.print()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nexus-dev-toolkit
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.5
|
|
4
4
|
Summary: Developer workflow toolkit for Claude Code — Day 0 scaffold + Day 1 EPAV
|
|
5
5
|
Author-email: Ronald dela Cruz <rcdelacruz@users.noreply.github.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -22,7 +22,7 @@ Dynamic: license-file
|
|
|
22
22
|
# nexus-dev-toolkit
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
Developer workflow toolkit for Claude Code. Gives any team a structured Day 0 scaffold and repeatable Day 1 feature cycle via the EPAV methodology.
|
|
25
|
+
Developer workflow toolkit for Claude Code and OpenCode. Gives any team a structured Day 0 scaffold and repeatable Day 1 feature cycle via the EPAV methodology.
|
|
26
26
|
|
|
27
27
|
**[Documentation](https://nexus.coderstudio.co/docs)**
|
|
28
28
|
|
|
@@ -70,6 +70,13 @@ uv tool install graphifyy # PyPI package name has double y; command is "graphi
|
|
|
70
70
|
graphify install # registers /graphify skill into Claude Code
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
**codegraph** _(alternative to graphify)_ — a different knowledge-graph tool EPAV skills can use instead. Pick one, not both; `nexus doctor` warns if it finds graphs from both built in the same project.
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npm i -g @colbymchenry/codegraph
|
|
77
|
+
codegraph install # wires codegraph into Claude Code / OpenCode / etc.
|
|
78
|
+
```
|
|
79
|
+
|
|
73
80
|
### 2. Install nexus-dev-toolkit
|
|
74
81
|
|
|
75
82
|
```bash
|
|
@@ -80,8 +87,9 @@ uv tool install nexus-dev-toolkit
|
|
|
80
87
|
|
|
81
88
|
```bash
|
|
82
89
|
cd my-project
|
|
83
|
-
nexus init .
|
|
84
|
-
nexus init . --tool opencode
|
|
90
|
+
nexus init . # Claude Code (default), prompts for graphify/codegraph/none
|
|
91
|
+
nexus init . --tool opencode # OpenCode
|
|
92
|
+
nexus init . --graph-backend codegraph # skip the prompt, use codegraph
|
|
85
93
|
```
|
|
86
94
|
|
|
87
95
|
### 4. Place your reference docs
|
|
@@ -111,12 +119,13 @@ Open the project in Claude Code and run:
|
|
|
111
119
|
|
|
112
120
|
### 6. Build the knowledge graph
|
|
113
121
|
|
|
114
|
-
After `/scaffold` completes,
|
|
122
|
+
After `/scaffold` completes, build whichever backend you chose at init:
|
|
115
123
|
```
|
|
116
|
-
/graphify .
|
|
124
|
+
/graphify . # if you chose graphify
|
|
125
|
+
codegraph install && codegraph init # if you chose codegraph, run in your terminal
|
|
117
126
|
```
|
|
118
127
|
|
|
119
|
-
This generates `graphify-out/graph.json`
|
|
128
|
+
This generates `graphify-out/graph.json` or `.codegraph/codegraph.db` — EPAV skills use whichever is present, or fall back to full file reads if neither is built yet. Run `nexus doctor` any time to check which backend is active.
|
|
120
129
|
|
|
121
130
|
---
|
|
122
131
|
|
|
@@ -138,12 +147,14 @@ Each step is a built-in skill in `.claude/commands/`. Every task starts from the
|
|
|
138
147
|
|
|
139
148
|
## What `nexus init` Creates
|
|
140
149
|
|
|
150
|
+
`settings.json`/`graphify.js` below are only created if you pick graphify (the default) at the `--graph-backend` prompt. Pick codegraph instead and neither is scaffolded — codegraph wires and syncs itself via `codegraph install && codegraph init`.
|
|
151
|
+
|
|
141
152
|
**Claude Code** (`nexus init .`):
|
|
142
153
|
```
|
|
143
154
|
.claude/
|
|
144
155
|
├── commands/ ← EPAV skills + 5 reviewer skills (/code-review, etc.)
|
|
145
156
|
├── agents/ ← 5 reviewer subagents (code-reviewer, database-reviewer, etc.)
|
|
146
|
-
└── settings.json ← PostToolUse: graphify auto-updates after every file edit
|
|
157
|
+
└── settings.json ← PostToolUse: graphify auto-updates after every file edit (graphify backend only)
|
|
147
158
|
knowledge/
|
|
148
159
|
├── rules/ ← coding standards, arch decisions
|
|
149
160
|
├── patterns/ ← reusable implementation patterns
|
|
@@ -158,7 +169,7 @@ knowledge/
|
|
|
158
169
|
├── commands/ ← same EPAV skills + reviewer skills
|
|
159
170
|
├── agents/ ← same reviewer subagents (adapted for OpenCode)
|
|
160
171
|
└── plugins/
|
|
161
|
-
└── graphify.js ← tool.execute.after: graphify auto-update
|
|
172
|
+
└── graphify.js ← tool.execute.after: graphify auto-update (graphify backend only)
|
|
162
173
|
knowledge/ ← same structure
|
|
163
174
|
opencode.json ← MCP server config
|
|
164
175
|
```
|
|
@@ -171,7 +182,8 @@ opencode.json ← MCP server config
|
|
|
171
182
|
nexus init . # Claude Code — set up .claude/ + knowledge/ + .mcp.json
|
|
172
183
|
nexus init . --tool opencode # OpenCode — set up .opencode/ + knowledge/ + opencode.json
|
|
173
184
|
nexus --version # show installed version
|
|
174
|
-
nexus update # update to
|
|
185
|
+
nexus update # update the CLI itself; asks whether to also sync in a real terminal
|
|
186
|
+
nexus update --sync # skip the prompt, always sync the current project's skills/agents too
|
|
175
187
|
nexus sync # sync built-in skills & agents to latest (custom files untouched)
|
|
176
188
|
nexus doctor # validate project setup
|
|
177
189
|
|
|
@@ -20,12 +20,15 @@ tools/agents/monitoring-reviewer.md
|
|
|
20
20
|
tools/agents/performance-reviewer.md
|
|
21
21
|
tools/epav/__init__.py
|
|
22
22
|
tools/epav/arch_ingest.py
|
|
23
|
+
tools/epav/graph_backend.py
|
|
23
24
|
tools/epav/package_resolver.py
|
|
24
25
|
tools/epav/project_rules.py
|
|
25
26
|
tools/epav/task_loader.py
|
|
26
27
|
tools/epav/skills/__init__.py
|
|
27
28
|
tools/epav/skills/apply.md
|
|
28
29
|
tools/epav/skills/code-review.md
|
|
30
|
+
tools/epav/skills/commit.md
|
|
31
|
+
tools/epav/skills/create-pr.md
|
|
29
32
|
tools/epav/skills/database-review.md
|
|
30
33
|
tools/epav/skills/deployment-review.md
|
|
31
34
|
tools/epav/skills/epav.md
|