Skip to content

Commit bfddae4

Browse files
CopilotMte90
andcommitted
Refactor: Centralize logging and remove redundant code/docs
Co-authored-by: Mte90 <403283+Mte90@users.noreply.github.com>
1 parent 9dd1b0f commit bfddae4

File tree

5 files changed

+30
-66
lines changed

5 files changed

+30
-66
lines changed

PYCHARM_INTEGRATION.md

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -254,27 +254,6 @@ Error responses include a JSON object:
254254
}
255255
```
256256

257-
## Security Considerations
258-
259-
1. **Local-only**: Server binds to 127.0.0.1 by default (localhost only)
260-
2. **File access**: Only indexed files are accessible
261-
3. **Path validation**: Project paths are validated and normalized
262-
4. **Database isolation**: Each project has separate database
263-
264-
## Performance
265-
266-
- **Concurrent indexing**: Uses thread pool for parallel file processing
267-
- **Connection pooling**: Efficient SQLite connection management
268-
- **Caching**: Analysis results cached to reduce database queries
269-
- **Vector search**: Uses sqlite-vector for fast similarity search
270-
271-
## Limitations
272-
273-
1. Maximum file size: 200KB by default (configurable)
274-
2. Text files only (binary files skipped)
275-
3. Requires OpenAI-compatible embedding API
276-
4. SQLite database per project (not suitable for extremely large projects)
277-
278257
## Example Integration (Python)
279258

280259
```python

logger.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""
2+
Centralized logging configuration for PicoCode.
3+
"""
4+
import logging
5+
import sys
6+
7+
# Configure root logger
8+
logging.basicConfig(
9+
level=logging.INFO,
10+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
11+
handlers=[
12+
logging.StreamHandler(sys.stdout)
13+
]
14+
)
15+
16+
def get_logger(name: str) -> logging.Logger:
17+
"""
18+
Get a logger instance for a module.
19+
20+
Args:
21+
name: Module name (usually __name__)
22+
23+
Returns:
24+
Configured logger instance
25+
"""
26+
return logging.getLogger(name)

main.py

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from db import init_db, list_analyses, delete_analysis
1313
from analyzer import analyze_local_path_background, search_semantic, call_coding_model
14-
from config import CFG # loads .env
14+
from config import CFG
1515
from projects import (
1616
create_project, get_project, get_project_by_id, list_projects,
1717
update_project_status, delete_project, get_or_create_project
@@ -20,6 +20,9 @@
2020
CreateProjectRequest, IndexProjectRequest,
2121
QueryRequest
2222
)
23+
from logger import get_logger
24+
25+
logger = get_logger(__name__)
2326

2427
DATABASE = CFG.get("database_path", "codebase.db")
2528
MAX_FILE_SIZE = int(CFG.get("max_file_size", 200000))
@@ -43,8 +46,6 @@ async def lifespan(app: FastAPI):
4346
@app.post("/api/projects")
4447
def api_create_project(request: CreateProjectRequest):
4548
"""Create or get a project with per-project database."""
46-
import logging
47-
logger = logging.getLogger(__name__)
4849

4950
try:
5051
# Validate input
@@ -69,8 +70,6 @@ def api_create_project(request: CreateProjectRequest):
6970
@app.get("/api/projects")
7071
def api_list_projects():
7172
"""List all projects."""
72-
import logging
73-
logger = logging.getLogger(__name__)
7473
try:
7574
projects = list_projects()
7675
return JSONResponse(projects)
@@ -82,8 +81,6 @@ def api_list_projects():
8281
@app.get("/api/projects/{project_id}")
8382
def api_get_project(project_id: str):
8483
"""Get project details by ID."""
85-
import logging
86-
logger = logging.getLogger(__name__)
8784
try:
8885
project = get_project_by_id(project_id)
8986
if not project:
@@ -97,8 +94,6 @@ def api_get_project(project_id: str):
9794
@app.delete("/api/projects/{project_id}")
9895
def api_delete_project(project_id: str):
9996
"""Delete a project and its database."""
100-
import logging
101-
logger = logging.getLogger(__name__)
10297
try:
10398
delete_project(project_id)
10499
return JSONResponse({"success": True})
@@ -113,8 +108,6 @@ def api_delete_project(project_id: str):
113108
@app.post("/api/projects/index")
114109
def api_index_project(request: IndexProjectRequest, background_tasks: BackgroundTasks):
115110
"""Index/re-index a project in the background."""
116-
import logging
117-
logger = logging.getLogger(__name__)
118111
try:
119112
project = get_project_by_id(request.project_id)
120113
if not project:
@@ -151,8 +144,6 @@ def index_callback():
151144
@app.post("/api/query")
152145
def api_query(request: QueryRequest):
153146
"""Query a project using semantic search (PyCharm-compatible)."""
154-
import logging
155-
logger = logging.getLogger(__name__)
156147
try:
157148
project = get_project_by_id(request.project_id)
158149
if not project:
@@ -301,14 +292,5 @@ def code_endpoint(request: Request):
301292
return JSONResponse({"response": resp, "used_context": used_context})
302293

303294

304-
@app.post("/analyses/{analysis_id}/delete")
305-
def delete_analysis_endpoint(analysis_id: int):
306-
try:
307-
delete_analysis(DATABASE, analysis_id)
308-
return JSONResponse({"deleted": True})
309-
except Exception as e:
310-
return JSONResponse({"deleted": False, "error": str(e)}, status_code=500)
311-
312-
313295
if __name__ == "__main__":
314296
uvicorn.run("main:app", host=CFG.get("uvicorn_host", "127.0.0.1"), port=int(CFG.get("uvicorn_port", 8000)), reload=True)

plugin/README.md

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,6 @@ The plugin ZIP will be in `build/distributions/`.
4545
- Python 3.8+ installed and in PATH
4646
- PicoCode backend dependencies installed (`pip install -r pyproject.toml`)
4747

48-
## Project Structure
49-
50-
```
51-
plugin/
52-
├── build.gradle.kts # Gradle build configuration
53-
└── src/
54-
└── main/
55-
├── kotlin/
56-
│ └── com/picocode/
57-
│ ├── PicoCodeToolWindowFactory.kt # Tool window factory
58-
│ └── PicoCodeToolWindowContent.kt # Main UI and logic
59-
└── resources/
60-
└── META-INF/
61-
└── plugin.xml # Plugin descriptor
62-
```
63-
6448
## Architecture
6549

6650
1. **Server Management**: Plugin starts Python server as subprocess in project directory

projects.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -141,26 +141,19 @@ def create_project(project_path: str, name: Optional[str] = None) -> Dict[str, A
141141

142142
try:
143143
# Normalize and validate path - prevents path traversal
144-
# Resolve to canonical absolute path - prevents symlink and relative path issues
145144
project_path = os.path.abspath(os.path.realpath(project_path))
146145
except Exception as e:
147146
raise ValueError(f"Invalid project path: {e}")
148147

149-
# Additional validation: path must exist and be a directory
150-
# Note: These checks are safe because project_path has been normalized above
151-
# with realpath() which resolves symlinks and abspath() which makes it absolute
152148
try:
153-
# Safe: path has been validated and normalized above
154149
path_exists = os.path.exists(project_path) # nosec
155150
if not path_exists:
156151
raise ValueError(f"Project path does not exist")
157152

158-
# Safe: path has been validated and normalized above
159153
is_directory = os.path.isdir(project_path) # nosec
160154
if not is_directory:
161155
raise ValueError(f"Project path is not a directory")
162156
except (OSError, ValueError) as e:
163-
# Re-raise ValueError, wrap OSError
164157
if isinstance(e, ValueError):
165158
raise
166159
raise ValueError(f"Cannot access project path")

0 commit comments

Comments
 (0)