Show HN: Pyscn – Python code quality analyzer for vibe coders (github.com)
Hi HN! I built pyscn for Python developers in the vibe coding era.
If you're using Cursor, Claude, or ChatGPT to ship Python code fast, you know the feeling: features work, tests pass, but the codebase feels... messy.
Common vibe coding artifacts:
• Code duplication (from copy-pasted snippets)
• Dead code from quick iterations
• Over-engineered solutions for simple problems
• Inconsistent patterns across modules
pyscn performs structural analysis:
• APTED tree edit distance + LSH
• Control-Flow Graph (CFG) analysis
• Coupling Between Objects (CBO)
• Cyclomatic Complexity
Try it without installation:
uvx pyscn analyze . # Using uv (fastest)
pipx run pyscn analyze . # Using pipx
(Or install: pip install pyscn)
Built with Go + tree-sitter. Happy to dive into the implementation details!
24 comments
[ 3.5 ms ] story [ 17.5 ms ] threadSince you mentioned the implementation details, a couple questions come to mind:
1. Are there any research papers you found helpful or influential when building this? For example, I need to read up on using tree edit distance for code duplication.
2. How hard do you think this would be to generalize to support other programming languages?
I see you are using tree-sitter which supports many languages, but I imagine a challenge might be CFGs and dependencies.
I’ll add a Qlty plugin for this (https://github.com/qltysh/qlty) so it can be run with other code quality tools and reported back to GitHub as pass/fail commit statuses and comments. That way, the AI coding agents can take action based on the issues that pyscn finds directly in a cloud dev env.
Vibe coders don't care about quality and wouldn't understand why any of these things are a problem in the first place.
I have a MCP server that wraps developer tool CLIs (linting, tests, etc), but this would need a textual report instead of HTML.
https://github.com/scosman/hooks_mcp
1) unfamiliar framework 2) just need to build a throwaway utility to help with a main task (and I don't want to split my attention) 3) for fun: I think of it as "code sculpting" rather than writing
So this is absolutely a utility I would use. (Kudos to the OP.)
Remember the second-best advice for internet interactions (after Wheaton's Law): "Ssssshh. Let people enjoy things."
I'll try hooking it into my refactor/cleanup workflow with copilot and see how it works as grounding.
Prescriptive comment: Comment describes exactly what the following code does without adding useful context. (Usually this is for the LLM to direct itself and should be removed).
Inconsistent style: You have this across modules, but this would be in the same file.
Inconsistent calling style: A function or method should return one kind of thing.
(In the worst case, the LLM has generated a load of special cases in the caller to handle the different styles it made).
Unneeded "Service" class: I saw a few instances where something that should have been simple function calls resulted in a class with Service in the name being added, I'm not sure why, but it did happen adding extra complications.
Those are the ones off the top of my head.
As a senior dev, I think use of these tools can be fine, as long as people are happy to go and fix the issues and learn, anyone can go from vibe coder to coder if you accept the need to learn and improve.
The output of the LLM is a starting point, however much we engineer prompts, we can't know what else we need to say until we see the (somewhat) wrong output and iterate it.
I'd love to look into incorporating checks for these into pyscn. This is exactly the kind of stuff I want it to catch.
But when i try to run analyze or check.
Running quality check...
Complexity analysis failed: [INVALID_INPUT] no Python files found in the specified paths
Dead code analysis failed: [INVALID_INPUT] no Python files found in the specified paths
Error: analysis failed with errorsI'm certainly in a folder with python files.
Thanks a lot for the bug report and for providing the details. I have a hunch—it's possible that you need to explicitly specify the path depending on your directory structure. For example, if your Python files are under a src directory, could you try running it like [your_tool_name] analyze src/?
If that still doesn't solve the problem, it would be a huge help if you could open a quick issue on GitHub for this.
Thanks again for your feedback!