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
54 changes: 27 additions & 27 deletions internal/tool/project_verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,41 @@ import (
// to guess a build or test command.
type ProjectVerifyTool struct{}

// ProjectVerifyInput is the typed input for ProjectVerifyTool.
type ProjectVerifyInput struct {
Action string `json:"action"`
Path string `json:"path"`
TimeoutSeconds int `json:"timeout_seconds"`
}

func (ProjectVerifyTool) Name() string { return "ProjectVerify" }
func (ProjectVerifyTool) RiskLevel() string { return "medium" }
func (ProjectVerifyTool) Aliases() []string { return []string{"project-verify", "verify_project"} }
func (ProjectVerifyTool) Description() string {
return "Detect the project stack and run bounded build, test, lint, or format checks using fixed argument lists (no shell interpolation). Returns structured results with exit codes and durations."
}

func (ProjectVerifyTool) Parameters() map[string]interface{} {
return map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"action": map[string]interface{}{
"type": "string",
"enum": []string{"detect", "build", "test", "lint", "format", "all"},
"description": "Verification action. detect only inspects files; all runs build, test, lint, and format checks that are available.",
},
"path": map[string]interface{}{
"type": "string",
"description": "Project directory (default: session working directory).",
},
"timeout_seconds": map[string]interface{}{
"type": "integer",
"minimum": 1,
"maximum": 600,
"description": "Per-command timeout (default 120 seconds, max 600).",
},
// Schema returns the typed input schema. Parameters() delegates to it so the
// two cannot diverge.
func (ProjectVerifyTool) Schema() ToolSchema {
return ToolSchema{
Type: "object",
Properties: map[string]SchemaProperty{
"action": {Type: "string", Enum: []interface{}{"detect", "build", "test", "lint", "format", "all"}, Description: "Verification action. detect only inspects files; all runs build, test, lint, and format checks that are available."},
"path": {Type: "string", Description: "Project directory (default: session working directory)."},
"timeout_seconds": {Type: "integer", Minimum: 1, Maximum: 600, Description: "Per-command timeout (default 120 seconds, max 600)."},
},
"required": []string{"action"},
Required: []string{"action"},
}
}

func (ProjectVerifyTool) Parameters() map[string]interface{} {
return projectVerifySchema.ToJSONSchema()
}

// projectVerifySchema is the single source of truth for ProjectVerify's input schema.
var projectVerifySchema = ProjectVerifyTool{}.Schema()

type projectStack struct {
Root string `json:"root"`
Markers []string `json:"markers"`
Expand All @@ -67,13 +71,9 @@ type verificationResult struct {
}

func (ProjectVerifyTool) Execute(ctx context.Context, input json.RawMessage) (string, error) {
var params struct {
Action string `json:"action"`
Path string `json:"path"`
TimeoutSeconds int `json:"timeout_seconds"`
}
if err := json.Unmarshal(input, &params); err != nil {
return "", fmt.Errorf("invalid input: %w", err)
params, err := DecodeInput[ProjectVerifyInput]("ProjectVerify", input)
if err != nil {
return "", err
}
params.Action = strings.ToLower(strings.TrimSpace(params.Action))
if params.Action == "" {
Expand Down
127 changes: 46 additions & 81 deletions internal/tool/refactor.go
Original file line number Diff line number Diff line change
Expand Up @@ -772,95 +772,61 @@ func NewRefactorTool() *RefactorTool {
}

func (RefactorTool) Name() string { return "Refactor" }

// RefactorInput is the typed input for RefactorTool.
type RefactorInput struct {
Action string `json:"action"`
File string `json:"file"`
StartLine int `json:"start_line"`
EndLine int `json:"end_line"`
NewName string `json:"new_name"`
OldName string `json:"old_name"`
Line int `json:"line"`
Expr string `json:"expr"`
VarName string `json:"var_name"`
Context string `json:"context"`
TestFunc string `json:"test_func"`
FuncName string `json:"func_name"`
}

func (RefactorTool) Description() string {
return "Apply common refactoring patterns (extract function, rename symbol, inline variable, extract variable, add error check, wrap with context, convert to table test, sort imports, remove unused params) without LLM calls."
}

func (RefactorTool) Parameters() map[string]interface{} {
return map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"action": map[string]interface{}{
"type": "string",
"description": "Refactoring action: extract_function, rename_symbol, inline_variable, extract_variable, add_error_check, wrap_with_context, convert_table_test, sort_imports, remove_unused_params",
"enum": []string{
"extract_function",
"rename_symbol",
"inline_variable",
"extract_variable",
"add_error_check",
"wrap_with_context",
"convert_table_test",
"sort_imports",
"remove_unused_params",
},
},
"file": map[string]interface{}{
"type": "string",
"description": "Absolute path to the file to refactor",
},
"start_line": map[string]interface{}{
"type": "integer",
"description": "Start line (1-based) for extract_function",
},
"end_line": map[string]interface{}{
"type": "integer",
"description": "End line (1-based) for extract_function",
},
"new_name": map[string]interface{}{
"type": "string",
"description": "New name for extract_function or rename_symbol",
},
"old_name": map[string]interface{}{
"type": "string",
"description": "Old symbol name for rename_symbol",
},
"line": map[string]interface{}{
"type": "integer",
"description": "Line number for inline_variable, extract_variable, add_error_check, or wrap_with_context",
},
"expr": map[string]interface{}{
"type": "string",
"description": "Expression to extract for extract_variable",
},
"var_name": map[string]interface{}{
"type": "string",
"description": "Variable name for extract_variable",
},
"context": map[string]interface{}{
"type": "string",
"description": "Context message for wrap_with_context",
},
"test_func": map[string]interface{}{
"type": "string",
"description": "Test function name for convert_table_test",
},
"func_name": map[string]interface{}{
"type": "string",
"description": "Function name for remove_unused_params",
},
// Schema returns the typed input schema. Parameters() delegates to it so the
// two cannot diverge.
func (RefactorTool) Schema() ToolSchema {
return ToolSchema{
Type: "object",
Properties: map[string]SchemaProperty{
"action": {Type: "string", Enum: []interface{}{"extract_function", "rename_symbol", "inline_variable", "extract_variable", "add_error_check", "wrap_with_context", "convert_table_test", "sort_imports", "remove_unused_params"}, Description: "Refactoring action: extract_function, rename_symbol, inline_variable, extract_variable, add_error_check, wrap_with_context, convert_table_test, sort_imports, remove_unused_params"},
"file": {Type: "string", Description: "Absolute path to the file to refactor"},
"start_line": {Type: "integer", Description: "Start line (1-based) for extract_function"},
"end_line": {Type: "integer", Description: "End line (1-based) for extract_function"},
"new_name": {Type: "string", Description: "New name for extract_function or rename_symbol"},
"old_name": {Type: "string", Description: "Old symbol name for rename_symbol"},
"line": {Type: "integer", Description: "Line number for inline_variable, extract_variable, add_error_check, or wrap_with_context"},
"expr": {Type: "string", Description: "Expression to extract for extract_variable"},
"var_name": {Type: "string", Description: "Variable name for extract_variable"},
"context": {Type: "string", Description: "Context message for wrap_with_context"},
"test_func": {Type: "string", Description: "Test function name for convert_table_test"},
"func_name": {Type: "string", Description: "Function name for remove_unused_params"},
},
"required": []string{"action", "file"},
Required: []string{"action", "file"},
}
}

func (RefactorTool) Parameters() map[string]interface{} {
return refactorSchema.ToJSONSchema()
}

// refactorSchema is the single source of truth for Refactor's input schema.
var refactorSchema = RefactorTool{}.Schema()

func (rt RefactorTool) Execute(ctx context.Context, input json.RawMessage) (string, error) {
var p struct {
Action string `json:"action"`
File string `json:"file"`
StartLine int `json:"start_line"`
EndLine int `json:"end_line"`
NewName string `json:"new_name"`
OldName string `json:"old_name"`
Line int `json:"line"`
Expr string `json:"expr"`
VarName string `json:"var_name"`
Context string `json:"context"`
TestFunc string `json:"test_func"`
FuncName string `json:"func_name"`
}
if err := json.Unmarshal(input, &p); err != nil {
return "", fmt.Errorf("invalid input: %w", err)
p, err := DecodeInput[RefactorInput]("Refactor", input)
if err != nil {
return "", err
}
if p.Action == "" {
return "", fmt.Errorf("action is required")
Expand All @@ -874,7 +840,6 @@ func (rt RefactorTool) Execute(ctx context.Context, input json.RawMessage) (stri

ref := rt.refactorer
var result *RefactoringResult
var err error

switch p.Action {
case "extract_function":
Expand Down
Loading
Loading