Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ coverage.out
# IDE
.idea/
.vscode/
.cursor/
*.swp
*.swo

Expand Down
49 changes: 48 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

All notable changes to CKB will be documented in this file.

## [8.1.0] - Unreleased
## [8.1.0] - 2026-01-31

### Added

Expand Down Expand Up @@ -61,6 +61,53 @@ The `--include-tests` flag now works end-to-end in `ckb impact diff`:
- Properly sets `IsTest` flag on references based on file path
- Filters test files from changed symbols when `--include-tests=false`

#### Dependency Cycle Detection (`findCycles`)
Detect circular dependencies in module, directory, or file dependency graphs using Tarjan's SCC algorithm:

```bash
# Via MCP
findCycles { "granularity": "directory", "targetPath": "internal/" }
```

- Uses Tarjan's strongly connected components to find real cycles
- Recommends which edge to break (lowest coupling cost)
- Severity classification: size ≥5 = high, ≥3 = medium, 2 = low
- Available in `refactor` preset

#### Move/Relocate Change Type
`prepareChange` and `planRefactor` now support `changeType: "move"` with a `targetPath` parameter:

```bash
prepareChange { "target": "internal/old/handler.go", "changeType": "move", "targetPath": "pkg/handler.go" }
```

- Scans all source files for import path references that need updating
- Detects target directory conflicts (existing files with same name)
- Generates move-specific refactoring steps in `planRefactor`

#### Extract Variable Flow Analysis
`prepareChange` with `changeType: "extract"` now provides tree-sitter-based variable flow analysis when CGO is available:

- Identifies parameters (variables defined outside selection, used inside)
- Identifies return values (variables defined inside, used after selection)
- Classifies local variables (defined and consumed within selection)
- Generates language-appropriate function signatures (Go, Python, JS/TS)
- Graceful degradation: falls back to line-count heuristics without CGO

#### Suggested Refactoring Detection (`suggestRefactorings`)
Proactive detection of refactoring opportunities by combining existing analyzers in parallel:

```bash
suggestRefactorings { "scope": "internal/query", "minSeverity": "medium" }
```

- **Complexity**: High cyclomatic/cognitive functions → `extract_function`, `simplify_function`
- **Coupling**: Highly correlated file pairs → `reduce_coupling`, `split_file`
- **Dead code**: Unused symbols → `remove_dead_code`
- **Test gaps**: High-risk untested code → `add_tests`
- Each suggestion includes severity, effort estimate, and priority score
- Available in `refactor` preset

## [8.0.2] - 2026-01-22

### Added
Expand Down
29 changes: 13 additions & 16 deletions cmd/ckb/mcp.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package main

import (
Expand All @@ -15,6 +15,7 @@
"github.com/SimplyLiz/CodeMCP/internal/index"
"github.com/SimplyLiz/CodeMCP/internal/mcp"
"github.com/SimplyLiz/CodeMCP/internal/project"
"github.com/SimplyLiz/CodeMCP/internal/query"
"github.com/SimplyLiz/CodeMCP/internal/repos"
"github.com/SimplyLiz/CodeMCP/internal/repostate"
"github.com/SimplyLiz/CodeMCP/internal/slogutil"
Expand Down Expand Up @@ -118,10 +119,9 @@
repoName = mcpRepo
fmt.Fprintf(os.Stderr, "Repository: %s (%s) [%s]\n", repoName, repoRoot, state)

// Use multi-repo mode
server = mcp.NewMCPServerWithRegistry(version.Version, registry, logger)
engine := mustGetEngine(repoRoot, logger)
server.SetActiveRepo(repoName, repoRoot, engine)
// Skip multi-repo mode - use lazy loading path instead
// TODO: Add lazy loading support to multi-repo mode
_ = registry // silence unused warning
}
} else {
// No --repo flag - use smart resolution
Expand Down Expand Up @@ -160,13 +160,9 @@
}
}

// Use multi-repo mode if registry is available
registry, err := repos.LoadRegistry()
if err == nil && resolved.Source != repos.ResolvedFromCWDGit {
server = mcp.NewMCPServerWithRegistry(version.Version, registry, logger)
engine := mustGetEngine(repoRoot, logger)
server.SetActiveRepo(repoName, repoRoot, engine)
}
// Skip multi-repo mode for now - use lazy loading path instead
// TODO: Add lazy loading support to multi-repo mode
_ = repos.LoadRegistry // silence unused warning
} else {
// No repo found - fall back to current directory
repoRoot = mustGetRepoRoot()
Expand Down Expand Up @@ -199,11 +195,12 @@
logger = slogutil.NewTeeLogger(fileLogger.Handler(), stderrHandler)
}

// Create server if not already created (legacy single-engine mode)
if server == nil {
engine := mustGetEngine(repoRoot, logger)
server = mcp.NewMCPServer(version.Version, engine, logger)
}
// Use lazy loading for fast MCP handshake
// Capture repoRoot and logger for the closure
root, log := repoRoot, logger
server = mcp.NewMCPServerLazy(version.Version, func() (*query.Engine, error) {
return getEngine(root, log)
}, logger)

// Apply preset configuration
if err := server.SetPreset(mcpPreset); err != nil {
Expand Down
Loading
Loading