repowise 0.1.0__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.
Files changed (136) hide show
  1. repowise-0.1.0/MANIFEST.in +2 -0
  2. repowise-0.1.0/PKG-INFO +150 -0
  3. repowise-0.1.0/README.md +74 -0
  4. repowise-0.1.0/packages/cli/src/repowise/cli/__init__.py +9 -0
  5. repowise-0.1.0/packages/cli/src/repowise/cli/commands/__init__.py +1 -0
  6. repowise-0.1.0/packages/cli/src/repowise/cli/commands/claude_md_cmd.py +103 -0
  7. repowise-0.1.0/packages/cli/src/repowise/cli/commands/dead_code_cmd.py +143 -0
  8. repowise-0.1.0/packages/cli/src/repowise/cli/commands/decision_cmd.py +489 -0
  9. repowise-0.1.0/packages/cli/src/repowise/cli/commands/doctor_cmd.py +145 -0
  10. repowise-0.1.0/packages/cli/src/repowise/cli/commands/export_cmd.py +158 -0
  11. repowise-0.1.0/packages/cli/src/repowise/cli/commands/init_cmd.py +1012 -0
  12. repowise-0.1.0/packages/cli/src/repowise/cli/commands/mcp_cmd.py +59 -0
  13. repowise-0.1.0/packages/cli/src/repowise/cli/commands/reindex_cmd.py +183 -0
  14. repowise-0.1.0/packages/cli/src/repowise/cli/commands/search_cmd.py +167 -0
  15. repowise-0.1.0/packages/cli/src/repowise/cli/commands/serve_cmd.py +33 -0
  16. repowise-0.1.0/packages/cli/src/repowise/cli/commands/status_cmd.py +88 -0
  17. repowise-0.1.0/packages/cli/src/repowise/cli/commands/update_cmd.py +306 -0
  18. repowise-0.1.0/packages/cli/src/repowise/cli/commands/watch_cmd.py +99 -0
  19. repowise-0.1.0/packages/cli/src/repowise/cli/cost_estimator.py +282 -0
  20. repowise-0.1.0/packages/cli/src/repowise/cli/helpers.py +258 -0
  21. repowise-0.1.0/packages/cli/src/repowise/cli/main.py +41 -0
  22. repowise-0.1.0/packages/cli/src/repowise/cli/mcp_config.py +66 -0
  23. repowise-0.1.0/packages/cli/src/repowise/cli/ui.py +540 -0
  24. repowise-0.1.0/packages/core/src/repowise/core/__init__.py +9 -0
  25. repowise-0.1.0/packages/core/src/repowise/core/analysis/__init__.py +1 -0
  26. repowise-0.1.0/packages/core/src/repowise/core/analysis/dead_code.py +554 -0
  27. repowise-0.1.0/packages/core/src/repowise/core/analysis/decision_extractor.py +783 -0
  28. repowise-0.1.0/packages/core/src/repowise/core/generation/__init__.py +90 -0
  29. repowise-0.1.0/packages/core/src/repowise/core/generation/context_assembler.py +823 -0
  30. repowise-0.1.0/packages/core/src/repowise/core/generation/editor_files/__init__.py +30 -0
  31. repowise-0.1.0/packages/core/src/repowise/core/generation/editor_files/base.py +130 -0
  32. repowise-0.1.0/packages/core/src/repowise/core/generation/editor_files/claude_md.py +25 -0
  33. repowise-0.1.0/packages/core/src/repowise/core/generation/editor_files/data.py +54 -0
  34. repowise-0.1.0/packages/core/src/repowise/core/generation/editor_files/fetcher.py +235 -0
  35. repowise-0.1.0/packages/core/src/repowise/core/generation/editor_files/tech_stack.py +203 -0
  36. repowise-0.1.0/packages/core/src/repowise/core/generation/job_system.py +253 -0
  37. repowise-0.1.0/packages/core/src/repowise/core/generation/models.py +357 -0
  38. repowise-0.1.0/packages/core/src/repowise/core/generation/page_generator.py +913 -0
  39. repowise-0.1.0/packages/core/src/repowise/core/generation/templates/api_contract.j2 +30 -0
  40. repowise-0.1.0/packages/core/src/repowise/core/generation/templates/architecture_diagram.j2 +31 -0
  41. repowise-0.1.0/packages/core/src/repowise/core/generation/templates/claude_md.j2 +87 -0
  42. repowise-0.1.0/packages/core/src/repowise/core/generation/templates/cross_package.j2 +18 -0
  43. repowise-0.1.0/packages/core/src/repowise/core/generation/templates/diff_summary.j2 +46 -0
  44. repowise-0.1.0/packages/core/src/repowise/core/generation/templates/file_page.j2 +129 -0
  45. repowise-0.1.0/packages/core/src/repowise/core/generation/templates/infra_page.j2 +21 -0
  46. repowise-0.1.0/packages/core/src/repowise/core/generation/templates/module_page.j2 +39 -0
  47. repowise-0.1.0/packages/core/src/repowise/core/generation/templates/repo_overview.j2 +38 -0
  48. repowise-0.1.0/packages/core/src/repowise/core/generation/templates/scc_page.j2 +30 -0
  49. repowise-0.1.0/packages/core/src/repowise/core/generation/templates/symbol_spotlight.j2 +41 -0
  50. repowise-0.1.0/packages/core/src/repowise/core/ingestion/__init__.py +55 -0
  51. repowise-0.1.0/packages/core/src/repowise/core/ingestion/change_detector.py +418 -0
  52. repowise-0.1.0/packages/core/src/repowise/core/ingestion/git_indexer.py +897 -0
  53. repowise-0.1.0/packages/core/src/repowise/core/ingestion/graph.py +420 -0
  54. repowise-0.1.0/packages/core/src/repowise/core/ingestion/models.py +214 -0
  55. repowise-0.1.0/packages/core/src/repowise/core/ingestion/parser.py +988 -0
  56. repowise-0.1.0/packages/core/src/repowise/core/ingestion/parsers/__init__.py +4 -0
  57. repowise-0.1.0/packages/core/src/repowise/core/ingestion/parsers/base.py +3 -0
  58. repowise-0.1.0/packages/core/src/repowise/core/ingestion/parsers/go.py +2 -0
  59. repowise-0.1.0/packages/core/src/repowise/core/ingestion/parsers/python.py +2 -0
  60. repowise-0.1.0/packages/core/src/repowise/core/ingestion/parsers/typescript.py +2 -0
  61. repowise-0.1.0/packages/core/src/repowise/core/ingestion/queries/c.scm +35 -0
  62. repowise-0.1.0/packages/core/src/repowise/core/ingestion/queries/cpp.scm +62 -0
  63. repowise-0.1.0/packages/core/src/repowise/core/ingestion/queries/go.scm +36 -0
  64. repowise-0.1.0/packages/core/src/repowise/core/ingestion/queries/java.scm +44 -0
  65. repowise-0.1.0/packages/core/src/repowise/core/ingestion/queries/javascript.scm +45 -0
  66. repowise-0.1.0/packages/core/src/repowise/core/ingestion/queries/kotlin.scm +25 -0
  67. repowise-0.1.0/packages/core/src/repowise/core/ingestion/queries/python.scm +59 -0
  68. repowise-0.1.0/packages/core/src/repowise/core/ingestion/queries/ruby.scm +30 -0
  69. repowise-0.1.0/packages/core/src/repowise/core/ingestion/queries/rust.scm +56 -0
  70. repowise-0.1.0/packages/core/src/repowise/core/ingestion/queries/typescript.scm +78 -0
  71. repowise-0.1.0/packages/core/src/repowise/core/ingestion/special_handlers.py +290 -0
  72. repowise-0.1.0/packages/core/src/repowise/core/ingestion/traverser.py +525 -0
  73. repowise-0.1.0/packages/core/src/repowise/core/persistence/__init__.py +183 -0
  74. repowise-0.1.0/packages/core/src/repowise/core/persistence/crud.py +1299 -0
  75. repowise-0.1.0/packages/core/src/repowise/core/persistence/database.py +140 -0
  76. repowise-0.1.0/packages/core/src/repowise/core/persistence/models.py +458 -0
  77. repowise-0.1.0/packages/core/src/repowise/core/persistence/search.py +247 -0
  78. repowise-0.1.0/packages/core/src/repowise/core/persistence/vector_store.py +373 -0
  79. repowise-0.1.0/packages/core/src/repowise/core/providers/__init__.py +50 -0
  80. repowise-0.1.0/packages/core/src/repowise/core/providers/embedding/__init__.py +26 -0
  81. repowise-0.1.0/packages/core/src/repowise/core/providers/embedding/base.py +74 -0
  82. repowise-0.1.0/packages/core/src/repowise/core/providers/embedding/gemini.py +129 -0
  83. repowise-0.1.0/packages/core/src/repowise/core/providers/embedding/openai.py +107 -0
  84. repowise-0.1.0/packages/core/src/repowise/core/providers/embedding/registry.py +99 -0
  85. repowise-0.1.0/packages/core/src/repowise/core/providers/llm/__init__.py +42 -0
  86. repowise-0.1.0/packages/core/src/repowise/core/providers/llm/anthropic.py +306 -0
  87. repowise-0.1.0/packages/core/src/repowise/core/providers/llm/base.py +227 -0
  88. repowise-0.1.0/packages/core/src/repowise/core/providers/llm/gemini.py +383 -0
  89. repowise-0.1.0/packages/core/src/repowise/core/providers/llm/litellm.py +253 -0
  90. repowise-0.1.0/packages/core/src/repowise/core/providers/llm/mock.py +158 -0
  91. repowise-0.1.0/packages/core/src/repowise/core/providers/llm/ollama.py +240 -0
  92. repowise-0.1.0/packages/core/src/repowise/core/providers/llm/openai.py +254 -0
  93. repowise-0.1.0/packages/core/src/repowise/core/providers/llm/registry.py +154 -0
  94. repowise-0.1.0/packages/core/src/repowise/core/rate_limiter.py +132 -0
  95. repowise-0.1.0/packages/server/src/repowise/server/__init__.py +10 -0
  96. repowise-0.1.0/packages/server/src/repowise/server/app.py +166 -0
  97. repowise-0.1.0/packages/server/src/repowise/server/chat_tools.py +289 -0
  98. repowise-0.1.0/packages/server/src/repowise/server/deps.py +55 -0
  99. repowise-0.1.0/packages/server/src/repowise/server/mcp_server/__init__.py +96 -0
  100. repowise-0.1.0/packages/server/src/repowise/server/mcp_server/_helpers.py +275 -0
  101. repowise-0.1.0/packages/server/src/repowise/server/mcp_server/_server.py +231 -0
  102. repowise-0.1.0/packages/server/src/repowise/server/mcp_server/_state.py +17 -0
  103. repowise-0.1.0/packages/server/src/repowise/server/mcp_server/tool_context.py +384 -0
  104. repowise-0.1.0/packages/server/src/repowise/server/mcp_server/tool_dead_code.py +261 -0
  105. repowise-0.1.0/packages/server/src/repowise/server/mcp_server/tool_dependency.py +253 -0
  106. repowise-0.1.0/packages/server/src/repowise/server/mcp_server/tool_diagram.py +202 -0
  107. repowise-0.1.0/packages/server/src/repowise/server/mcp_server/tool_overview.py +135 -0
  108. repowise-0.1.0/packages/server/src/repowise/server/mcp_server/tool_risk.py +342 -0
  109. repowise-0.1.0/packages/server/src/repowise/server/mcp_server/tool_search.py +138 -0
  110. repowise-0.1.0/packages/server/src/repowise/server/mcp_server/tool_why.py +481 -0
  111. repowise-0.1.0/packages/server/src/repowise/server/provider_config.py +199 -0
  112. repowise-0.1.0/packages/server/src/repowise/server/routers/__init__.py +1 -0
  113. repowise-0.1.0/packages/server/src/repowise/server/routers/chat.py +500 -0
  114. repowise-0.1.0/packages/server/src/repowise/server/routers/claude_md.py +84 -0
  115. repowise-0.1.0/packages/server/src/repowise/server/routers/dead_code.py +95 -0
  116. repowise-0.1.0/packages/server/src/repowise/server/routers/decisions.py +144 -0
  117. repowise-0.1.0/packages/server/src/repowise/server/routers/git.py +184 -0
  118. repowise-0.1.0/packages/server/src/repowise/server/routers/graph.py +692 -0
  119. repowise-0.1.0/packages/server/src/repowise/server/routers/health.py +82 -0
  120. repowise-0.1.0/packages/server/src/repowise/server/routers/jobs.py +103 -0
  121. repowise-0.1.0/packages/server/src/repowise/server/routers/pages.py +107 -0
  122. repowise-0.1.0/packages/server/src/repowise/server/routers/providers.py +53 -0
  123. repowise-0.1.0/packages/server/src/repowise/server/routers/repos.py +181 -0
  124. repowise-0.1.0/packages/server/src/repowise/server/routers/search.py +42 -0
  125. repowise-0.1.0/packages/server/src/repowise/server/routers/symbols.py +90 -0
  126. repowise-0.1.0/packages/server/src/repowise/server/routers/webhooks.py +169 -0
  127. repowise-0.1.0/packages/server/src/repowise/server/scheduler.py +117 -0
  128. repowise-0.1.0/packages/server/src/repowise/server/schemas.py +666 -0
  129. repowise-0.1.0/pyproject.toml +236 -0
  130. repowise-0.1.0/repowise.egg-info/PKG-INFO +150 -0
  131. repowise-0.1.0/repowise.egg-info/SOURCES.txt +134 -0
  132. repowise-0.1.0/repowise.egg-info/dependency_links.txt +1 -0
  133. repowise-0.1.0/repowise.egg-info/entry_points.txt +2 -0
  134. repowise-0.1.0/repowise.egg-info/requires.txt +60 -0
  135. repowise-0.1.0/repowise.egg-info/top_level.txt +1 -0
  136. repowise-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,2 @@
1
+ recursive-include packages/core/src/repowise/core/ingestion/queries *.scm
2
+ recursive-include packages/core/src/repowise/core/generation/templates *.j2
@@ -0,0 +1,150 @@
1
+ Metadata-Version: 2.4
2
+ Name: repowise
3
+ Version: 0.1.0
4
+ Summary: Codebase intelligence for developers and AI — generates and maintains a structured wiki for any codebase
5
+ License-Expression: AGPL-3.0-only
6
+ Project-URL: Homepage, https://repowise.dev
7
+ Project-URL: Repository, https://github.com/repowise-ai/repowise
8
+ Project-URL: Issues, https://github.com/repowise-ai/repowise/issues
9
+ Project-URL: Documentation, https://docs.repowise.dev
10
+ Keywords: documentation,codebase,wiki,llm,ai,mcp
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Environment :: Console
18
+ Classifier: Framework :: FastAPI
19
+ Classifier: Topic :: Software Development :: Documentation
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.11
22
+ Description-Content-Type: text/markdown
23
+ Requires-Dist: httpx<1,>=0.27
24
+ Requires-Dist: tree-sitter<1,>=0.23
25
+ Requires-Dist: tree-sitter-python<1,>=0.23
26
+ Requires-Dist: tree-sitter-typescript<1,>=0.23
27
+ Requires-Dist: tree-sitter-javascript<1,>=0.23
28
+ Requires-Dist: tree-sitter-go<1,>=0.23
29
+ Requires-Dist: tree-sitter-rust<1,>=0.23
30
+ Requires-Dist: tree-sitter-java<1,>=0.23
31
+ Requires-Dist: tree-sitter-cpp<1,>=0.23
32
+ Requires-Dist: networkx<4,>=3.3
33
+ Requires-Dist: scipy<2,>=1.11
34
+ Requires-Dist: jinja2<4,>=3.1
35
+ Requires-Dist: pathspec<1,>=0.12
36
+ Requires-Dist: structlog<25,>=24
37
+ Requires-Dist: sqlalchemy[asyncio]<3,>=2.0
38
+ Requires-Dist: aiosqlite<1,>=0.20
39
+ Requires-Dist: alembic<2,>=1.13
40
+ Requires-Dist: pydantic<3,>=2.8
41
+ Requires-Dist: tenacity<10,>=9
42
+ Requires-Dist: gitpython<4,>=3.1
43
+ Requires-Dist: pyyaml<7,>=6.0
44
+ Requires-Dist: lancedb<1,>=0.12
45
+ Requires-Dist: click<9,>=8.1
46
+ Requires-Dist: rich<14,>=13
47
+ Requires-Dist: watchdog<5,>=4
48
+ Requires-Dist: fastapi<1,>=0.115
49
+ Requires-Dist: uvicorn[standard]<1,>=0.32
50
+ Requires-Dist: mcp<2,>=1.0
51
+ Requires-Dist: apscheduler<4,>=3.10
52
+ Requires-Dist: cryptography<44,>=43
53
+ Provides-Extra: anthropic
54
+ Requires-Dist: anthropic<1,>=0.40; extra == "anthropic"
55
+ Provides-Extra: openai
56
+ Requires-Dist: openai<2,>=1.50; extra == "openai"
57
+ Provides-Extra: gemini
58
+ Requires-Dist: google-genai<2,>=1.0; extra == "gemini"
59
+ Provides-Extra: litellm
60
+ Requires-Dist: litellm<2,>=1.50; extra == "litellm"
61
+ Provides-Extra: postgres
62
+ Requires-Dist: pgvector<1,>=0.3; extra == "postgres"
63
+ Requires-Dist: asyncpg<1,>=0.29; extra == "postgres"
64
+ Provides-Extra: all
65
+ Requires-Dist: repowise[anthropic,gemini,litellm,openai,postgres]; extra == "all"
66
+ Provides-Extra: dev
67
+ Requires-Dist: pytest<9,>=8; extra == "dev"
68
+ Requires-Dist: pytest-asyncio<1,>=0.23; extra == "dev"
69
+ Requires-Dist: pytest-snapshot<1,>=0.9; extra == "dev"
70
+ Requires-Dist: respx<1,>=0.21; extra == "dev"
71
+ Requires-Dist: time-machine<3,>=2.14; extra == "dev"
72
+ Requires-Dist: ruff<1,>=0.6; extra == "dev"
73
+ Requires-Dist: mypy<2,>=1.11; extra == "dev"
74
+ Requires-Dist: types-networkx<4,>=3.3; extra == "dev"
75
+ Requires-Dist: build>=1.0; extra == "dev"
76
+
77
+ # repowise
78
+
79
+ **Codebase intelligence for developers and AI.**
80
+
81
+ repowise generates and maintains a structured, hierarchical wiki for any codebase.
82
+ It keeps documentation accurate as code changes and exposes everything through an
83
+ MCP server so AI coding assistants can query it in real time.
84
+
85
+ ## Features
86
+
87
+ - **Automatic documentation** — generates module, file, and symbol-level docs from source code
88
+ - **Git intelligence** — tracks churn hotspots, ownership, and change patterns
89
+ - **Dead code detection** — finds confirmed unused exports, functions, and types
90
+ - **Decision intelligence** — captures *why* code is structured the way it is
91
+ - **MCP server** — 8 tools for AI assistants (Claude Code, Cursor, Windsurf, etc.)
92
+ - **REST API + Web UI** — browse the wiki, search, and explore architecture diagrams
93
+ - **Multi-language** — Python, TypeScript, JavaScript, Go, Rust, Java, C/C++, Kotlin, Ruby
94
+
95
+ ## Install
96
+
97
+ ```bash
98
+ pip install repowise
99
+ ```
100
+
101
+ LLM providers are optional — install only the one you need:
102
+
103
+ ```bash
104
+ pip install "repowise[anthropic]" # Claude models
105
+ pip install "repowise[openai]" # GPT models
106
+ pip install "repowise[gemini]" # Gemini models
107
+ pip install "repowise[litellm]" # 100+ providers via LiteLLM
108
+ pip install "repowise[all]" # Everything
109
+ ```
110
+
111
+ ## Quick Start
112
+
113
+ ```bash
114
+ # Generate documentation for your codebase
115
+ repowise init --provider anthropic --model claude-sonnet-4-6
116
+
117
+ # Keep docs in sync after code changes
118
+ repowise update
119
+
120
+ # Start the MCP server for AI assistants
121
+ repowise mcp
122
+
123
+ # Launch the web UI
124
+ repowise serve
125
+ ```
126
+
127
+ ## How It Works
128
+
129
+ 1. **Ingestion** — parses every file using tree-sitter, extracts symbols, imports, and builds a dependency graph
130
+ 2. **Analysis** — computes git signals (churn, ownership, recency), detects dead code, identifies architectural decisions
131
+ 3. **Generation** — sends structured prompts to an LLM to produce wiki pages at every level of the hierarchy
132
+ 4. **Persistence** — stores everything in SQLite (or PostgreSQL) with full-text and vector search
133
+ 5. **Serving** — exposes the wiki through REST API, MCP server, and web UI
134
+
135
+ ## Requirements
136
+
137
+ - Python 3.11+
138
+ - Git (for repository analysis)
139
+ - An LLM API key (for documentation generation — not needed for analysis-only mode)
140
+
141
+ ## Documentation
142
+
143
+ - [Architecture Guide](docs/ARCHITECTURE.md)
144
+ - [CLI Reference](packages/cli/README.md)
145
+ - [Server & MCP Tools](packages/server/README.md)
146
+ - [Core Library](packages/core/README.md)
147
+
148
+ ## License
149
+
150
+ AGPL-3.0 — see [LICENSE](LICENSE) for details.
@@ -0,0 +1,74 @@
1
+ # repowise
2
+
3
+ **Codebase intelligence for developers and AI.**
4
+
5
+ repowise generates and maintains a structured, hierarchical wiki for any codebase.
6
+ It keeps documentation accurate as code changes and exposes everything through an
7
+ MCP server so AI coding assistants can query it in real time.
8
+
9
+ ## Features
10
+
11
+ - **Automatic documentation** — generates module, file, and symbol-level docs from source code
12
+ - **Git intelligence** — tracks churn hotspots, ownership, and change patterns
13
+ - **Dead code detection** — finds confirmed unused exports, functions, and types
14
+ - **Decision intelligence** — captures *why* code is structured the way it is
15
+ - **MCP server** — 8 tools for AI assistants (Claude Code, Cursor, Windsurf, etc.)
16
+ - **REST API + Web UI** — browse the wiki, search, and explore architecture diagrams
17
+ - **Multi-language** — Python, TypeScript, JavaScript, Go, Rust, Java, C/C++, Kotlin, Ruby
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pip install repowise
23
+ ```
24
+
25
+ LLM providers are optional — install only the one you need:
26
+
27
+ ```bash
28
+ pip install "repowise[anthropic]" # Claude models
29
+ pip install "repowise[openai]" # GPT models
30
+ pip install "repowise[gemini]" # Gemini models
31
+ pip install "repowise[litellm]" # 100+ providers via LiteLLM
32
+ pip install "repowise[all]" # Everything
33
+ ```
34
+
35
+ ## Quick Start
36
+
37
+ ```bash
38
+ # Generate documentation for your codebase
39
+ repowise init --provider anthropic --model claude-sonnet-4-6
40
+
41
+ # Keep docs in sync after code changes
42
+ repowise update
43
+
44
+ # Start the MCP server for AI assistants
45
+ repowise mcp
46
+
47
+ # Launch the web UI
48
+ repowise serve
49
+ ```
50
+
51
+ ## How It Works
52
+
53
+ 1. **Ingestion** — parses every file using tree-sitter, extracts symbols, imports, and builds a dependency graph
54
+ 2. **Analysis** — computes git signals (churn, ownership, recency), detects dead code, identifies architectural decisions
55
+ 3. **Generation** — sends structured prompts to an LLM to produce wiki pages at every level of the hierarchy
56
+ 4. **Persistence** — stores everything in SQLite (or PostgreSQL) with full-text and vector search
57
+ 5. **Serving** — exposes the wiki through REST API, MCP server, and web UI
58
+
59
+ ## Requirements
60
+
61
+ - Python 3.11+
62
+ - Git (for repository analysis)
63
+ - An LLM API key (for documentation generation — not needed for analysis-only mode)
64
+
65
+ ## Documentation
66
+
67
+ - [Architecture Guide](docs/ARCHITECTURE.md)
68
+ - [CLI Reference](packages/cli/README.md)
69
+ - [Server & MCP Tools](packages/server/README.md)
70
+ - [Core Library](packages/core/README.md)
71
+
72
+ ## License
73
+
74
+ AGPL-3.0 — see [LICENSE](LICENSE) for details.
@@ -0,0 +1,9 @@
1
+ """repowise CLI package.
2
+
3
+ Entry point: ``repowise`` command (defined in repowise.cli.main).
4
+ Codebase intelligence for developers and AI — dependency graphs,
5
+ git signals, dead code detection, architectural decisions, and
6
+ AI-generated documentation.
7
+ """
8
+
9
+ __version__ = "0.1.0"
@@ -0,0 +1 @@
1
+ """CLI command modules."""
@@ -0,0 +1,103 @@
1
+ """repowise generate-claude-md — generate/update CLAUDE.md for a repository."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ import click
8
+
9
+ from repowise.cli.helpers import (
10
+ ensure_repowise_dir,
11
+ get_db_url_for_repo,
12
+ run_async,
13
+ )
14
+
15
+
16
+ @click.command("generate-claude-md")
17
+ @click.argument("path", required=False, default=None)
18
+ @click.option(
19
+ "--output",
20
+ "output_path",
21
+ default=None,
22
+ metavar="FILE",
23
+ help="Write to a custom path (default: CLAUDE.md in the repo root).",
24
+ )
25
+ @click.option(
26
+ "--stdout",
27
+ "to_stdout",
28
+ is_flag=True,
29
+ default=False,
30
+ help="Print generated content to stdout instead of writing a file.",
31
+ )
32
+ def claude_md_command(
33
+ path: str | None,
34
+ output_path: str | None,
35
+ to_stdout: bool,
36
+ ) -> None:
37
+ """Generate or update CLAUDE.md with codebase intelligence context.
38
+
39
+ PATH defaults to the current directory.
40
+
41
+ The file is split into two sections:
42
+ - Your custom instructions (above the REPOWISE markers) — never modified.
43
+ - Repowise-managed section (between markers) — auto-updated from the index.
44
+
45
+ Run 'repowise init' or 'repowise update' to keep it current automatically.
46
+ """
47
+ repo_path = Path(path).resolve() if path else Path.cwd()
48
+ ensure_repowise_dir(repo_path)
49
+
50
+ try:
51
+ content = run_async(_generate(repo_path, output_path, to_stdout))
52
+ except Exception as exc: # noqa: BLE001
53
+ raise click.ClickException(str(exc)) from exc
54
+
55
+ if to_stdout:
56
+ click.echo(content, nl=False)
57
+
58
+
59
+ async def _generate(
60
+ repo_path: Path,
61
+ output_path: str | None,
62
+ to_stdout: bool,
63
+ ) -> str | None:
64
+ from repowise.core.generation.editor_files import ClaudeMdGenerator, EditorFileDataFetcher
65
+ from repowise.core.persistence import (
66
+ create_engine,
67
+ create_session_factory,
68
+ get_session,
69
+ init_db,
70
+ )
71
+ from repowise.core.persistence.crud import get_repository_by_path
72
+
73
+ url = get_db_url_for_repo(repo_path)
74
+ engine = create_engine(url)
75
+ await init_db(engine)
76
+ sf = create_session_factory(engine)
77
+
78
+ try:
79
+ async with get_session(sf) as session:
80
+ repo = await get_repository_by_path(session, str(repo_path))
81
+ if repo is None:
82
+ raise click.ClickException(
83
+ f"Repository not found in index. Run 'repowise init' first."
84
+ )
85
+ fetcher = EditorFileDataFetcher(session, repo.id, repo_path)
86
+ data = await fetcher.fetch()
87
+ finally:
88
+ await engine.dispose()
89
+
90
+ gen = ClaudeMdGenerator()
91
+
92
+ if to_stdout:
93
+ return gen.render_full(repo_path, data)
94
+
95
+ dest = Path(output_path).resolve() if output_path else None
96
+ written = gen.write(dest.parent if dest else repo_path, data)
97
+ if dest and dest != written:
98
+ # Custom output path differs from default filename in same dir
99
+ written.rename(dest)
100
+ written = dest
101
+
102
+ click.echo(f"CLAUDE.md updated: {written}")
103
+ return None
@@ -0,0 +1,143 @@
1
+ """``repowise dead-code`` — detect dead and unused code."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+
7
+ import click
8
+ from rich.table import Table
9
+
10
+ from repowise.cli.helpers import (
11
+ console,
12
+ resolve_repo_path,
13
+ run_async,
14
+ )
15
+
16
+
17
+ @click.command("dead-code")
18
+ @click.argument("path", required=False, type=click.Path(exists=True))
19
+ @click.option("--min-confidence", default=0.4, type=float, help="Minimum confidence threshold.")
20
+ @click.option("--safe-only", is_flag=True, help="Only show safe_to_delete=True findings.")
21
+ @click.option(
22
+ "--kind",
23
+ type=click.Choice(["unreachable_file", "unused_export", "unused_internal", "zombie_package"]),
24
+ help="Filter by finding kind.",
25
+ )
26
+ @click.option(
27
+ "--format",
28
+ "fmt",
29
+ default="table",
30
+ type=click.Choice(["table", "json", "md"]),
31
+ help="Output format.",
32
+ )
33
+ def dead_code_command(
34
+ path: str | None,
35
+ min_confidence: float,
36
+ safe_only: bool,
37
+ kind: str | None,
38
+ fmt: str,
39
+ ) -> None:
40
+ """Detect dead and unused code."""
41
+ from pathlib import Path as PathlibPath
42
+
43
+ from repowise.core.analysis.dead_code import DeadCodeAnalyzer
44
+ from repowise.core.ingestion import ASTParser, FileTraverser, GraphBuilder
45
+
46
+ repo_path = resolve_repo_path(path)
47
+
48
+ console.print(f"[bold]repowise dead-code[/bold] — {repo_path}")
49
+
50
+ # Ingest
51
+ traverser = FileTraverser(repo_path)
52
+ file_infos = list(traverser.traverse())
53
+ parser = ASTParser()
54
+ graph_builder = GraphBuilder()
55
+
56
+ for fi in file_infos:
57
+ try:
58
+ source = PathlibPath(fi.abs_path).read_bytes()
59
+ parsed = parser.parse_file(fi, source)
60
+ graph_builder.add_file(parsed)
61
+ except Exception:
62
+ pass
63
+ graph_builder.build()
64
+
65
+ # Git metadata (best effort)
66
+ git_meta_map: dict = {}
67
+ try:
68
+ from repowise.core.ingestion.git_indexer import GitIndexer
69
+
70
+ git_indexer = GitIndexer(repo_path)
71
+ _, metadata_list = run_async(git_indexer.index_repo(""))
72
+ git_meta_map = {m["file_path"]: m for m in metadata_list}
73
+ except Exception:
74
+ pass
75
+
76
+ # Analyze
77
+ config = {"min_confidence": min_confidence}
78
+ if kind:
79
+ # Enable only the requested kind
80
+ config["detect_unreachable_files"] = kind == "unreachable_file"
81
+ config["detect_unused_exports"] = kind == "unused_export"
82
+ config["detect_unused_internals"] = kind == "unused_internal"
83
+ config["detect_zombie_packages"] = kind == "zombie_package"
84
+
85
+ analyzer = DeadCodeAnalyzer(graph_builder.graph(), git_meta_map)
86
+ report = analyzer.analyze(config)
87
+
88
+ findings = report.findings
89
+ if safe_only:
90
+ findings = [f for f in findings if f.safe_to_delete]
91
+
92
+ if fmt == "json":
93
+ output = []
94
+ for f in findings:
95
+ output.append({
96
+ "kind": f.kind.value,
97
+ "file_path": f.file_path,
98
+ "symbol_name": f.symbol_name,
99
+ "confidence": f.confidence,
100
+ "reason": f.reason,
101
+ "safe_to_delete": f.safe_to_delete,
102
+ "lines": f.lines,
103
+ "primary_owner": f.primary_owner,
104
+ })
105
+ click.echo(json.dumps(output, indent=2))
106
+ return
107
+
108
+ if fmt == "md":
109
+ click.echo(f"# Dead Code Report\n")
110
+ click.echo(f"**Total findings:** {len(findings)}")
111
+ click.echo(f"**Deletable lines:** {report.deletable_lines}\n")
112
+ for f in findings:
113
+ safe = " (safe to remove)" if f.safe_to_delete else ""
114
+ name = f"`{f.symbol_name}`" if f.symbol_name else f"`{f.file_path}`"
115
+ click.echo(f"- [{f.kind.value}] {name} — {f.reason} ({f.confidence:.0%}){safe}")
116
+ return
117
+
118
+ # Table format (default)
119
+ table = Table(title=f"Dead Code ({len(findings)} findings)")
120
+ table.add_column("Kind", style="cyan")
121
+ table.add_column("File / Symbol")
122
+ table.add_column("Confidence", justify="right")
123
+ table.add_column("Safe?", justify="center")
124
+ table.add_column("Lines", justify="right")
125
+ table.add_column("Reason")
126
+
127
+ for f in findings:
128
+ name = f.symbol_name or f.file_path
129
+ safe = "[green]✓[/green]" if f.safe_to_delete else "[red]✗[/red]"
130
+ table.add_row(
131
+ f.kind.value,
132
+ name,
133
+ f"{f.confidence:.0%}",
134
+ safe,
135
+ str(f.lines),
136
+ f.reason[:60],
137
+ )
138
+
139
+ console.print(table)
140
+ console.print(
141
+ f"\nDeletable lines: [bold]{report.deletable_lines:,}[/bold] "
142
+ f"(confidence: {report.confidence_summary})"
143
+ )