nexus-dev-toolkit 3.0.1__tar.gz → 3.1.1__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.0.1/nexus_dev_toolkit.egg-info → nexus_dev_toolkit-3.1.1}/PKG-INFO +32 -13
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/README.md +28 -10
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/nexus_cli.py +119 -2
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1/nexus_dev_toolkit.egg-info}/PKG-INFO +32 -13
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/nexus_dev_toolkit.egg-info/SOURCES.txt +13 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/nexus_dev_toolkit.egg-info/requires.txt +1 -1
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/pyproject.toml +5 -3
- nexus_dev_toolkit-3.1.1/tests/test_cli.py +105 -0
- nexus_dev_toolkit-3.1.1/tests/test_server.py +21 -0
- nexus_dev_toolkit-3.1.1/tools/agents/code-reviewer.md +93 -0
- nexus_dev_toolkit-3.1.1/tools/agents/database-reviewer.md +95 -0
- nexus_dev_toolkit-3.1.1/tools/agents/deployment-reviewer.md +97 -0
- nexus_dev_toolkit-3.1.1/tools/agents/monitoring-reviewer.md +95 -0
- nexus_dev_toolkit-3.1.1/tools/agents/performance-reviewer.md +98 -0
- nexus_dev_toolkit-3.1.1/tools/epav/skills/__init__.py +0 -0
- nexus_dev_toolkit-3.1.1/tools/epav/skills/code-review.md +91 -0
- nexus_dev_toolkit-3.1.1/tools/epav/skills/database-review.md +91 -0
- nexus_dev_toolkit-3.1.1/tools/epav/skills/deployment-review.md +94 -0
- nexus_dev_toolkit-3.1.1/tools/epav/skills/monitoring-review.md +91 -0
- nexus_dev_toolkit-3.1.1/tools/epav/skills/performance-review.md +93 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/LICENSE +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/nexus_dev_toolkit.egg-info/dependency_links.txt +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/nexus_dev_toolkit.egg-info/entry_points.txt +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/nexus_dev_toolkit.egg-info/top_level.txt +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/nexus_server.py +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/setup.cfg +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/tools/__init__.py +0 -0
- {nexus_dev_toolkit-3.0.1/tools/epav/skills → nexus_dev_toolkit-3.1.1/tools/agents}/__init__.py +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/tools/epav/__init__.py +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/tools/epav/arch_ingest.py +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/tools/epav/package_resolver.py +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/tools/epav/project_rules.py +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/tools/epav/skills/apply.md +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/tools/epav/skills/epav.md +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/tools/epav/skills/evaluate.md +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/tools/epav/skills/plan.md +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/tools/epav/skills/scaffold.md +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/tools/epav/skills/validate.md +0 -0
- {nexus_dev_toolkit-3.0.1 → nexus_dev_toolkit-3.1.1}/tools/epav/task_loader.py +0 -0
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nexus-dev-toolkit
|
|
3
|
-
Version: 3.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 3.1.1
|
|
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
|
|
7
7
|
Project-URL: Homepage, https://nexus.coderstudio.co
|
|
8
|
+
Project-URL: Documentation, https://nexus.coderstudio.co/docs
|
|
8
9
|
Project-URL: Repository, https://github.com/rcdelacruz/nexus-dev-toolkit
|
|
9
10
|
Project-URL: Issues, https://github.com/rcdelacruz/nexus-dev-toolkit/issues
|
|
10
11
|
Requires-Python: >=3.10
|
|
11
12
|
Description-Content-Type: text/markdown
|
|
12
13
|
License-File: LICENSE
|
|
13
|
-
Requires-Dist: mcp[cli]>=1.
|
|
14
|
+
Requires-Dist: mcp[cli]>=1.27.1
|
|
14
15
|
Requires-Dist: typer>=0.12.0
|
|
15
16
|
Requires-Dist: rich>=13.0.0
|
|
16
17
|
Provides-Extra: dev
|
|
@@ -20,12 +21,11 @@ Dynamic: license-file
|
|
|
20
21
|
|
|
21
22
|
# nexus-dev-toolkit
|
|
22
23
|
|
|
23
|
-
[](https://pypi.org/project/nexus-dev-toolkit/)
|
|
24
|
-
[](https://pypi.org/project/nexus-dev-toolkit/)
|
|
25
|
-
[](LICENSE)
|
|
26
24
|
|
|
27
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.
|
|
28
26
|
|
|
27
|
+
**[Documentation](https://nexus.coderstudio.co/docs)**
|
|
28
|
+
|
|
29
29
|
---
|
|
30
30
|
|
|
31
31
|
## Why
|
|
@@ -83,33 +83,52 @@ cd my-project
|
|
|
83
83
|
nexus init .
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
-
### 4.
|
|
86
|
+
### 4. Place your reference docs
|
|
87
|
+
|
|
88
|
+
Before running `/scaffold`, put everything Claude needs in `docs/`:
|
|
87
89
|
|
|
88
|
-
Open the project in Claude Code and run:
|
|
89
90
|
```
|
|
90
|
-
/
|
|
91
|
+
docs/
|
|
92
|
+
├── arch-docs/ ← architecture doc, ADRs
|
|
93
|
+
├── figma/ ← Figma export ZIP
|
|
94
|
+
├── brd/ ← Business Requirements Document
|
|
95
|
+
└── prd/ ← Product Requirements Document
|
|
91
96
|
```
|
|
92
97
|
|
|
93
|
-
This generates `graphify-out/graph.json` — required by all EPAV skills.
|
|
94
|
-
|
|
95
98
|
### 5. Start Day 0
|
|
96
99
|
|
|
100
|
+
Open the project in Claude Code and run:
|
|
97
101
|
```
|
|
98
102
|
/scaffold
|
|
99
103
|
```
|
|
100
104
|
|
|
105
|
+
`/scaffold` runs EVALUATE first then stops. You drive each phase by typing the next command:
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
/scaffold → (review) → /plan → (review) → /apply → (review) → /validate
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 6. Build the knowledge graph
|
|
112
|
+
|
|
113
|
+
After `/scaffold` completes, run in Claude Code:
|
|
114
|
+
```
|
|
115
|
+
/graphify .
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
This generates `graphify-out/graph.json` — required by all EPAV skills before starting Day 1.
|
|
119
|
+
|
|
101
120
|
---
|
|
102
121
|
|
|
103
122
|
## The Workflow
|
|
104
123
|
|
|
105
124
|
### Day 0 — `/scaffold` (once per project)
|
|
106
125
|
|
|
107
|
-
|
|
126
|
+
Produces a production-grade project from your architecture document and Figma design: correct stack, mock auth, mock data, design system, AGENTS.md — zero external dependencies. Runs `npm install && npm run dev` (or equivalent) from commit one.
|
|
108
127
|
|
|
109
128
|
### Day 1 — EPAV (every feature, every sprint)
|
|
110
129
|
|
|
111
130
|
```
|
|
112
|
-
/evaluate
|
|
131
|
+
/evaluate <task> → /plan → /apply → /validate
|
|
113
132
|
```
|
|
114
133
|
|
|
115
134
|
Each step is a built-in skill in `.claude/commands/`. Every task starts from the dev tasks CSV. Every task ends with acceptance criteria verified.
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
# nexus-dev-toolkit
|
|
2
2
|
|
|
3
|
-
[](https://pypi.org/project/nexus-dev-toolkit/)
|
|
4
|
-
[](https://pypi.org/project/nexus-dev-toolkit/)
|
|
5
|
-
[](LICENSE)
|
|
6
3
|
|
|
7
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.
|
|
8
5
|
|
|
6
|
+
**[Documentation](https://nexus.coderstudio.co/docs)**
|
|
7
|
+
|
|
9
8
|
---
|
|
10
9
|
|
|
11
10
|
## Why
|
|
@@ -63,33 +62,52 @@ cd my-project
|
|
|
63
62
|
nexus init .
|
|
64
63
|
```
|
|
65
64
|
|
|
66
|
-
### 4.
|
|
65
|
+
### 4. Place your reference docs
|
|
66
|
+
|
|
67
|
+
Before running `/scaffold`, put everything Claude needs in `docs/`:
|
|
67
68
|
|
|
68
|
-
Open the project in Claude Code and run:
|
|
69
69
|
```
|
|
70
|
-
/
|
|
70
|
+
docs/
|
|
71
|
+
├── arch-docs/ ← architecture doc, ADRs
|
|
72
|
+
├── figma/ ← Figma export ZIP
|
|
73
|
+
├── brd/ ← Business Requirements Document
|
|
74
|
+
└── prd/ ← Product Requirements Document
|
|
71
75
|
```
|
|
72
76
|
|
|
73
|
-
This generates `graphify-out/graph.json` — required by all EPAV skills.
|
|
74
|
-
|
|
75
77
|
### 5. Start Day 0
|
|
76
78
|
|
|
79
|
+
Open the project in Claude Code and run:
|
|
77
80
|
```
|
|
78
81
|
/scaffold
|
|
79
82
|
```
|
|
80
83
|
|
|
84
|
+
`/scaffold` runs EVALUATE first then stops. You drive each phase by typing the next command:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
/scaffold → (review) → /plan → (review) → /apply → (review) → /validate
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 6. Build the knowledge graph
|
|
91
|
+
|
|
92
|
+
After `/scaffold` completes, run in Claude Code:
|
|
93
|
+
```
|
|
94
|
+
/graphify .
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
This generates `graphify-out/graph.json` — required by all EPAV skills before starting Day 1.
|
|
98
|
+
|
|
81
99
|
---
|
|
82
100
|
|
|
83
101
|
## The Workflow
|
|
84
102
|
|
|
85
103
|
### Day 0 — `/scaffold` (once per project)
|
|
86
104
|
|
|
87
|
-
|
|
105
|
+
Produces a production-grade project from your architecture document and Figma design: correct stack, mock auth, mock data, design system, AGENTS.md — zero external dependencies. Runs `npm install && npm run dev` (or equivalent) from commit one.
|
|
88
106
|
|
|
89
107
|
### Day 1 — EPAV (every feature, every sprint)
|
|
90
108
|
|
|
91
109
|
```
|
|
92
|
-
/evaluate
|
|
110
|
+
/evaluate <task> → /plan → /apply → /validate
|
|
93
111
|
```
|
|
94
112
|
|
|
95
113
|
Each step is a built-in skill in `.claude/commands/`. Every task starts from the dev tasks CSV. Every task ends with acceptance criteria verified.
|
|
@@ -11,12 +11,14 @@ from rich.table import Table
|
|
|
11
11
|
app = typer.Typer(name="nexus", no_args_is_help=False, help="nexus-dev-toolkit — Day 0 scaffold + Day 1 EPAV workflow for Claude Code")
|
|
12
12
|
skill_app = typer.Typer(name="skill", no_args_is_help=True, help="Manage skills in .claude/commands/")
|
|
13
13
|
rule_app = typer.Typer(name="rule", no_args_is_help=True, help="Manage rules in knowledge/rules/")
|
|
14
|
+
agent_app = typer.Typer(name="agent", no_args_is_help=True, help="Manage subagents in .claude/agents/")
|
|
14
15
|
app.add_typer(skill_app, name="skill")
|
|
15
16
|
app.add_typer(rule_app, name="rule")
|
|
17
|
+
app.add_typer(agent_app, name="agent")
|
|
16
18
|
|
|
17
19
|
console = Console()
|
|
18
20
|
|
|
19
|
-
_VERSION = "3.
|
|
21
|
+
_VERSION = "3.1.1"
|
|
20
22
|
|
|
21
23
|
_LOGO = """\
|
|
22
24
|
[cyan]███╗ ██╗███████╗██╗ ██╗██╗ ██╗███████╗[/cyan]
|
|
@@ -35,8 +37,17 @@ def _print_logo() -> None:
|
|
|
35
37
|
console.print()
|
|
36
38
|
|
|
37
39
|
|
|
40
|
+
def _version_callback(value: bool) -> None:
|
|
41
|
+
if value:
|
|
42
|
+
console.print(f"nexus-dev-toolkit v{_VERSION}")
|
|
43
|
+
raise typer.Exit()
|
|
44
|
+
|
|
45
|
+
|
|
38
46
|
@app.callback(invoke_without_command=True)
|
|
39
|
-
def _callback(
|
|
47
|
+
def _callback(
|
|
48
|
+
ctx: typer.Context,
|
|
49
|
+
version: bool = typer.Option(None, "--version", "-V", callback=_version_callback, is_eager=True, help="Show version and exit."),
|
|
50
|
+
) -> None:
|
|
40
51
|
if ctx.invoked_subcommand is None:
|
|
41
52
|
_print_logo()
|
|
42
53
|
console.print(ctx.get_help())
|
|
@@ -52,8 +63,24 @@ _BUILTIN_SKILLS = [
|
|
|
52
63
|
"apply.md",
|
|
53
64
|
"validate.md",
|
|
54
65
|
"epav.md",
|
|
66
|
+
"code-review.md",
|
|
67
|
+
"database-review.md",
|
|
68
|
+
"deployment-review.md",
|
|
69
|
+
"performance-review.md",
|
|
70
|
+
"monitoring-review.md",
|
|
55
71
|
]
|
|
56
72
|
|
|
73
|
+
_AGENTS_SRC = Path(__file__).parent / "tools" / "agents"
|
|
74
|
+
|
|
75
|
+
_BUILTIN_AGENTS = [
|
|
76
|
+
"deployment-reviewer.md",
|
|
77
|
+
"code-reviewer.md",
|
|
78
|
+
"performance-reviewer.md",
|
|
79
|
+
"monitoring-reviewer.md",
|
|
80
|
+
"database-reviewer.md",
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
|
|
57
84
|
# ── .claude/settings.json ────────────────────────────────────────────────────
|
|
58
85
|
|
|
59
86
|
_CLAUDE_SETTINGS = {
|
|
@@ -95,6 +122,7 @@ def _init_project(project_dir: Path) -> list[str]:
|
|
|
95
122
|
"""
|
|
96
123
|
nexus init — sets up:
|
|
97
124
|
.claude/commands/ ← built-in skills
|
|
125
|
+
.claude/agents/ ← built-in subagents
|
|
98
126
|
.claude/settings.json ← PostToolUse graphify hook
|
|
99
127
|
knowledge/ ← empty scaffold
|
|
100
128
|
"""
|
|
@@ -111,6 +139,17 @@ def _init_project(project_dir: Path) -> list[str]:
|
|
|
111
139
|
shutil.copy2(src, dest)
|
|
112
140
|
created.append(f".claude/commands/{skill_name}")
|
|
113
141
|
|
|
142
|
+
# .claude/agents/ — copy built-in subagents
|
|
143
|
+
agents_dir = project_dir / ".claude" / "agents"
|
|
144
|
+
agents_dir.mkdir(parents=True, exist_ok=True)
|
|
145
|
+
|
|
146
|
+
for agent_name in _BUILTIN_AGENTS:
|
|
147
|
+
src = _AGENTS_SRC / agent_name
|
|
148
|
+
dest = agents_dir / agent_name
|
|
149
|
+
if src.exists() and not dest.exists():
|
|
150
|
+
shutil.copy2(src, dest)
|
|
151
|
+
created.append(f".claude/agents/{agent_name}")
|
|
152
|
+
|
|
114
153
|
# .claude/settings.json — PostToolUse graphify hook
|
|
115
154
|
settings_path = project_dir / ".claude" / "settings.json"
|
|
116
155
|
if not settings_path.exists():
|
|
@@ -309,6 +348,84 @@ def rule_list(
|
|
|
309
348
|
console.print(table)
|
|
310
349
|
|
|
311
350
|
|
|
351
|
+
# ── agent subcommands ─────────────────────────────────────────────────────────
|
|
352
|
+
|
|
353
|
+
_AGENT_TEMPLATE = """\
|
|
354
|
+
---
|
|
355
|
+
name: {name}
|
|
356
|
+
description: Describe when Claude should spawn this agent (role, not action — e.g. "reviews X for Y")
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
# {name}
|
|
360
|
+
|
|
361
|
+
## Role
|
|
362
|
+
|
|
363
|
+
Describe what this agent does.
|
|
364
|
+
|
|
365
|
+
## Steps
|
|
366
|
+
|
|
367
|
+
### 1 — Discover context
|
|
368
|
+
|
|
369
|
+
Read CLAUDE.md, project manifest, and relevant source files.
|
|
370
|
+
|
|
371
|
+
### 2 — Perform task
|
|
372
|
+
|
|
373
|
+
What the agent should do.
|
|
374
|
+
|
|
375
|
+
### 3 — Output
|
|
376
|
+
|
|
377
|
+
What the agent should return when done.
|
|
378
|
+
"""
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
@agent_app.command("add")
|
|
382
|
+
def agent_add(
|
|
383
|
+
name: str = typer.Argument(..., help="Agent name (e.g. 'security-reviewer')"),
|
|
384
|
+
project_dir: str = typer.Option(".", "--dir", "-d"),
|
|
385
|
+
) -> None:
|
|
386
|
+
"""Create a new subagent in .claude/agents/."""
|
|
387
|
+
root = Path(project_dir).resolve()
|
|
388
|
+
dest = root / ".claude" / "agents" / f"{name}.md"
|
|
389
|
+
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
390
|
+
|
|
391
|
+
if dest.exists():
|
|
392
|
+
console.print(f" [yellow]·[/yellow] .claude/agents/{name}.md already exists")
|
|
393
|
+
return
|
|
394
|
+
|
|
395
|
+
dest.write_text(_AGENT_TEMPLATE.format(name=name), encoding="utf-8")
|
|
396
|
+
console.print(f" [green]✓[/green] Created .claude/agents/{name}.md")
|
|
397
|
+
console.print(f" [dim]Edit the description so Claude knows when to spawn it.[/dim]")
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
@agent_app.command("list")
|
|
401
|
+
def agent_list(
|
|
402
|
+
project_dir: str = typer.Option(".", "--dir", "-d"),
|
|
403
|
+
) -> None:
|
|
404
|
+
"""List all subagents in .claude/agents/."""
|
|
405
|
+
root = Path(project_dir).resolve()
|
|
406
|
+
agents_dir = root / ".claude" / "agents"
|
|
407
|
+
|
|
408
|
+
if not agents_dir.exists():
|
|
409
|
+
console.print(" [yellow]·[/yellow] No .claude/agents/ found. Run [cyan]nexus init[/cyan] first.")
|
|
410
|
+
return
|
|
411
|
+
|
|
412
|
+
agents = sorted(agents_dir.glob("*.md"))
|
|
413
|
+
if not agents:
|
|
414
|
+
console.print(" [yellow]·[/yellow] No agents yet. Run [cyan]nexus agent add <name>[/cyan]")
|
|
415
|
+
return
|
|
416
|
+
|
|
417
|
+
table = Table(show_header=True, header_style="dim")
|
|
418
|
+
table.add_column("Agent", style="cyan")
|
|
419
|
+
table.add_column("Source")
|
|
420
|
+
|
|
421
|
+
builtins = set(_BUILTIN_AGENTS)
|
|
422
|
+
for a in agents:
|
|
423
|
+
source = "built-in" if a.name in builtins else "custom"
|
|
424
|
+
table.add_row(a.stem, source)
|
|
425
|
+
|
|
426
|
+
console.print(table)
|
|
427
|
+
|
|
428
|
+
|
|
312
429
|
def main() -> None:
|
|
313
430
|
app()
|
|
314
431
|
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nexus-dev-toolkit
|
|
3
|
-
Version: 3.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 3.1.1
|
|
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
|
|
7
7
|
Project-URL: Homepage, https://nexus.coderstudio.co
|
|
8
|
+
Project-URL: Documentation, https://nexus.coderstudio.co/docs
|
|
8
9
|
Project-URL: Repository, https://github.com/rcdelacruz/nexus-dev-toolkit
|
|
9
10
|
Project-URL: Issues, https://github.com/rcdelacruz/nexus-dev-toolkit/issues
|
|
10
11
|
Requires-Python: >=3.10
|
|
11
12
|
Description-Content-Type: text/markdown
|
|
12
13
|
License-File: LICENSE
|
|
13
|
-
Requires-Dist: mcp[cli]>=1.
|
|
14
|
+
Requires-Dist: mcp[cli]>=1.27.1
|
|
14
15
|
Requires-Dist: typer>=0.12.0
|
|
15
16
|
Requires-Dist: rich>=13.0.0
|
|
16
17
|
Provides-Extra: dev
|
|
@@ -20,12 +21,11 @@ Dynamic: license-file
|
|
|
20
21
|
|
|
21
22
|
# nexus-dev-toolkit
|
|
22
23
|
|
|
23
|
-
[](https://pypi.org/project/nexus-dev-toolkit/)
|
|
24
|
-
[](https://pypi.org/project/nexus-dev-toolkit/)
|
|
25
|
-
[](LICENSE)
|
|
26
24
|
|
|
27
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.
|
|
28
26
|
|
|
27
|
+
**[Documentation](https://nexus.coderstudio.co/docs)**
|
|
28
|
+
|
|
29
29
|
---
|
|
30
30
|
|
|
31
31
|
## Why
|
|
@@ -83,33 +83,52 @@ cd my-project
|
|
|
83
83
|
nexus init .
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
-
### 4.
|
|
86
|
+
### 4. Place your reference docs
|
|
87
|
+
|
|
88
|
+
Before running `/scaffold`, put everything Claude needs in `docs/`:
|
|
87
89
|
|
|
88
|
-
Open the project in Claude Code and run:
|
|
89
90
|
```
|
|
90
|
-
/
|
|
91
|
+
docs/
|
|
92
|
+
├── arch-docs/ ← architecture doc, ADRs
|
|
93
|
+
├── figma/ ← Figma export ZIP
|
|
94
|
+
├── brd/ ← Business Requirements Document
|
|
95
|
+
└── prd/ ← Product Requirements Document
|
|
91
96
|
```
|
|
92
97
|
|
|
93
|
-
This generates `graphify-out/graph.json` — required by all EPAV skills.
|
|
94
|
-
|
|
95
98
|
### 5. Start Day 0
|
|
96
99
|
|
|
100
|
+
Open the project in Claude Code and run:
|
|
97
101
|
```
|
|
98
102
|
/scaffold
|
|
99
103
|
```
|
|
100
104
|
|
|
105
|
+
`/scaffold` runs EVALUATE first then stops. You drive each phase by typing the next command:
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
/scaffold → (review) → /plan → (review) → /apply → (review) → /validate
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 6. Build the knowledge graph
|
|
112
|
+
|
|
113
|
+
After `/scaffold` completes, run in Claude Code:
|
|
114
|
+
```
|
|
115
|
+
/graphify .
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
This generates `graphify-out/graph.json` — required by all EPAV skills before starting Day 1.
|
|
119
|
+
|
|
101
120
|
---
|
|
102
121
|
|
|
103
122
|
## The Workflow
|
|
104
123
|
|
|
105
124
|
### Day 0 — `/scaffold` (once per project)
|
|
106
125
|
|
|
107
|
-
|
|
126
|
+
Produces a production-grade project from your architecture document and Figma design: correct stack, mock auth, mock data, design system, AGENTS.md — zero external dependencies. Runs `npm install && npm run dev` (or equivalent) from commit one.
|
|
108
127
|
|
|
109
128
|
### Day 1 — EPAV (every feature, every sprint)
|
|
110
129
|
|
|
111
130
|
```
|
|
112
|
-
/evaluate
|
|
131
|
+
/evaluate <task> → /plan → /apply → /validate
|
|
113
132
|
```
|
|
114
133
|
|
|
115
134
|
Each step is a built-in skill in `.claude/commands/`. Every task starts from the dev tasks CSV. Every task ends with acceptance criteria verified.
|
|
@@ -9,7 +9,15 @@ nexus_dev_toolkit.egg-info/dependency_links.txt
|
|
|
9
9
|
nexus_dev_toolkit.egg-info/entry_points.txt
|
|
10
10
|
nexus_dev_toolkit.egg-info/requires.txt
|
|
11
11
|
nexus_dev_toolkit.egg-info/top_level.txt
|
|
12
|
+
tests/test_cli.py
|
|
13
|
+
tests/test_server.py
|
|
12
14
|
tools/__init__.py
|
|
15
|
+
tools/agents/__init__.py
|
|
16
|
+
tools/agents/code-reviewer.md
|
|
17
|
+
tools/agents/database-reviewer.md
|
|
18
|
+
tools/agents/deployment-reviewer.md
|
|
19
|
+
tools/agents/monitoring-reviewer.md
|
|
20
|
+
tools/agents/performance-reviewer.md
|
|
13
21
|
tools/epav/__init__.py
|
|
14
22
|
tools/epav/arch_ingest.py
|
|
15
23
|
tools/epav/package_resolver.py
|
|
@@ -17,8 +25,13 @@ tools/epav/project_rules.py
|
|
|
17
25
|
tools/epav/task_loader.py
|
|
18
26
|
tools/epav/skills/__init__.py
|
|
19
27
|
tools/epav/skills/apply.md
|
|
28
|
+
tools/epav/skills/code-review.md
|
|
29
|
+
tools/epav/skills/database-review.md
|
|
30
|
+
tools/epav/skills/deployment-review.md
|
|
20
31
|
tools/epav/skills/epav.md
|
|
21
32
|
tools/epav/skills/evaluate.md
|
|
33
|
+
tools/epav/skills/monitoring-review.md
|
|
34
|
+
tools/epav/skills/performance-review.md
|
|
22
35
|
tools/epav/skills/plan.md
|
|
23
36
|
tools/epav/skills/scaffold.md
|
|
24
37
|
tools/epav/skills/validate.md
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nexus-dev-toolkit"
|
|
3
|
-
version = "3.
|
|
4
|
-
description = "
|
|
3
|
+
version = "3.1.1"
|
|
4
|
+
description = "Developer workflow toolkit for Claude Code — Day 0 scaffold + Day 1 EPAV"
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Ronald dela Cruz", email = "rcdelacruz@users.noreply.github.com"}
|
|
7
7
|
]
|
|
@@ -9,7 +9,7 @@ readme = "README.md"
|
|
|
9
9
|
license = "MIT"
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
11
|
dependencies = [
|
|
12
|
-
"mcp[cli]>=1.
|
|
12
|
+
"mcp[cli]>=1.27.1",
|
|
13
13
|
"typer>=0.12.0",
|
|
14
14
|
"rich>=13.0.0",
|
|
15
15
|
]
|
|
@@ -20,6 +20,7 @@ nexus-mcp = "nexus_server:main"
|
|
|
20
20
|
|
|
21
21
|
[project.urls]
|
|
22
22
|
Homepage = "https://nexus.coderstudio.co"
|
|
23
|
+
Documentation = "https://nexus.coderstudio.co/docs"
|
|
23
24
|
Repository = "https://github.com/rcdelacruz/nexus-dev-toolkit"
|
|
24
25
|
Issues = "https://github.com/rcdelacruz/nexus-dev-toolkit/issues"
|
|
25
26
|
|
|
@@ -42,6 +43,7 @@ include = ["tools*"]
|
|
|
42
43
|
|
|
43
44
|
[tool.setuptools.package-data]
|
|
44
45
|
"tools.epav" = ["skills/*.md"]
|
|
46
|
+
"tools.agents" = ["*.md"]
|
|
45
47
|
|
|
46
48
|
[tool.pytest.ini_options]
|
|
47
49
|
asyncio_mode = "auto"
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
from typer.testing import CliRunner
|
|
6
|
+
|
|
7
|
+
from nexus_cli import app, _BUILTIN_SKILLS, _BUILTIN_AGENTS, _KNOWLEDGE_DIRS
|
|
8
|
+
|
|
9
|
+
runner = CliRunner()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.fixture()
|
|
13
|
+
def tmp_project(tmp_path):
|
|
14
|
+
return tmp_path
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_init_creates_commands(tmp_project):
|
|
18
|
+
result = runner.invoke(app, ["init", str(tmp_project)])
|
|
19
|
+
assert result.exit_code == 0
|
|
20
|
+
commands_dir = tmp_project / ".claude" / "commands"
|
|
21
|
+
assert commands_dir.exists()
|
|
22
|
+
for skill in _BUILTIN_SKILLS:
|
|
23
|
+
assert (commands_dir / skill).exists(), f"Missing skill: {skill}"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_init_creates_agents(tmp_project):
|
|
27
|
+
result = runner.invoke(app, ["init", str(tmp_project)])
|
|
28
|
+
assert result.exit_code == 0
|
|
29
|
+
agents_dir = tmp_project / ".claude" / "agents"
|
|
30
|
+
assert agents_dir.exists()
|
|
31
|
+
for agent in _BUILTIN_AGENTS:
|
|
32
|
+
assert (agents_dir / agent).exists(), f"Missing agent: {agent}"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_init_creates_knowledge_dirs(tmp_project):
|
|
37
|
+
runner.invoke(app, ["init", str(tmp_project)])
|
|
38
|
+
for d in _KNOWLEDGE_DIRS:
|
|
39
|
+
assert (tmp_project / d).exists(), f"Missing dir: {d}"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_init_creates_settings_json(tmp_project):
|
|
43
|
+
runner.invoke(app, ["init", str(tmp_project)])
|
|
44
|
+
settings = tmp_project / ".claude" / "settings.json"
|
|
45
|
+
assert settings.exists()
|
|
46
|
+
data = json.loads(settings.read_text())
|
|
47
|
+
assert "hooks" in data
|
|
48
|
+
assert "PostToolUse" in data["hooks"]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_init_creates_mcp_json(tmp_project):
|
|
52
|
+
runner.invoke(app, ["init", str(tmp_project)])
|
|
53
|
+
mcp = tmp_project / ".mcp.json"
|
|
54
|
+
assert mcp.exists()
|
|
55
|
+
data = json.loads(mcp.read_text())
|
|
56
|
+
assert "nexus" in data["mcpServers"]
|
|
57
|
+
assert data["mcpServers"]["nexus"]["command"] == "uvx"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def test_init_idempotent(tmp_project):
|
|
61
|
+
runner.invoke(app, ["init", str(tmp_project)])
|
|
62
|
+
result = runner.invoke(app, ["init", str(tmp_project)])
|
|
63
|
+
assert result.exit_code == 0
|
|
64
|
+
assert "Already initialized" in result.output
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_skill_add(tmp_project):
|
|
68
|
+
runner.invoke(app, ["init", str(tmp_project)])
|
|
69
|
+
result = runner.invoke(app, ["skill", "add", "my-custom-skill", "--dir", str(tmp_project)])
|
|
70
|
+
assert result.exit_code == 0
|
|
71
|
+
skill_file = tmp_project / ".claude" / "commands" / "my-custom-skill.md"
|
|
72
|
+
assert skill_file.exists()
|
|
73
|
+
assert "/my-custom-skill" in skill_file.read_text()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def test_skill_add_idempotent(tmp_project):
|
|
77
|
+
runner.invoke(app, ["init", str(tmp_project)])
|
|
78
|
+
runner.invoke(app, ["skill", "add", "my-custom-skill", "--dir", str(tmp_project)])
|
|
79
|
+
result = runner.invoke(app, ["skill", "add", "my-custom-skill", "--dir", str(tmp_project)])
|
|
80
|
+
assert result.exit_code == 0
|
|
81
|
+
assert "already exists" in result.output
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_skill_list(tmp_project):
|
|
85
|
+
runner.invoke(app, ["init", str(tmp_project)])
|
|
86
|
+
result = runner.invoke(app, ["skill", "list", "--dir", str(tmp_project)])
|
|
87
|
+
assert result.exit_code == 0
|
|
88
|
+
assert "/scaffold" in result.output
|
|
89
|
+
assert "/evaluate" in result.output
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def test_rule_add(tmp_project):
|
|
93
|
+
runner.invoke(app, ["init", str(tmp_project)])
|
|
94
|
+
result = runner.invoke(app, ["rule", "add", "api-standards", "--dir", str(tmp_project)])
|
|
95
|
+
assert result.exit_code == 0
|
|
96
|
+
rule_file = tmp_project / "knowledge" / "rules" / "api-standards.md"
|
|
97
|
+
assert rule_file.exists()
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def test_rule_list(tmp_project):
|
|
101
|
+
runner.invoke(app, ["init", str(tmp_project)])
|
|
102
|
+
runner.invoke(app, ["rule", "add", "api-standards", "--dir", str(tmp_project)])
|
|
103
|
+
result = runner.invoke(app, ["rule", "list", "--dir", str(tmp_project)])
|
|
104
|
+
assert result.exit_code == 0
|
|
105
|
+
assert "api-standards" in result.output
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from mcp.server.fastmcp import FastMCP
|
|
2
|
+
|
|
3
|
+
from tools.epav import register_epav_tools
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_epav_tools_register():
|
|
7
|
+
mcp = FastMCP("test")
|
|
8
|
+
register_epav_tools(mcp)
|
|
9
|
+
tool_names = {t.name for t in mcp._tool_manager.list_tools()}
|
|
10
|
+
assert "ingest_architecture_doc" in tool_names
|
|
11
|
+
assert "load_task" in tool_names
|
|
12
|
+
assert "generate_project_rules" in tool_names
|
|
13
|
+
assert "resolve_package_versions" in tool_names
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_epav_tools_register_idempotent():
|
|
17
|
+
mcp = FastMCP("test")
|
|
18
|
+
register_epav_tools(mcp)
|
|
19
|
+
register_epav_tools(mcp)
|
|
20
|
+
tool_names = [t.name for t in mcp._tool_manager.list_tools()]
|
|
21
|
+
assert tool_names.count("load_task") == 1
|