@@ -22,7 +22,9 @@ import (
2222 "fmt"
2323 "io/fs"
2424 "os"
25+ "os/exec"
2526 "path/filepath"
27+ "runtime"
2628 "strings"
2729
2830 "github.com/cloudwego/abcoder/llm/log"
@@ -43,6 +45,11 @@ type mcpServerConfig struct {
4345
4446// runInitSpec implements the init-spec command
4547func RunInitSpec (targetDir string ) error {
48+ // Check and install jq dependency required by hook scripts
49+ if err := ensureJqInstalled (); err != nil {
50+ return fmt .Errorf ("failed to ensure jq is installed: %w" , err )
51+ }
52+
4653 if targetDir == "" {
4754 // Default to current directory if not specified
4855 cwd , err := os .Getwd ()
@@ -264,3 +271,61 @@ For more information, see:
264271 - https://github.com/cloudwego/abcoder
265272` , targetDir , configPath , astsDir )
266273}
274+
275+ // ensureJqInstalled checks if jq is installed and attempts to install it if not found
276+ func ensureJqInstalled () error {
277+ if _ , err := exec .LookPath ("jq" ); err == nil {
278+ log .Info ("jq is already installed" )
279+ return nil
280+ }
281+
282+ log .Info ("jq not found, attempting to install..." )
283+
284+ var cmd * exec.Cmd
285+ switch runtime .GOOS {
286+ case "linux" :
287+ // Detect available package manager
288+ if _ , err := exec .LookPath ("apt-get" ); err == nil {
289+ cmd = exec .Command ("sudo" , "apt-get" , "install" , "-y" , "jq" )
290+ } else if _ , err := exec .LookPath ("yum" ); err == nil {
291+ cmd = exec .Command ("sudo" , "yum" , "install" , "-y" , "jq" )
292+ } else if _ , err := exec .LookPath ("dnf" ); err == nil {
293+ cmd = exec .Command ("sudo" , "dnf" , "install" , "-y" , "jq" )
294+ } else if _ , err := exec .LookPath ("apk" ); err == nil {
295+ cmd = exec .Command ("apk" , "add" , "jq" )
296+ } else {
297+ return fmt .Errorf ("jq is required but not found, and no supported package manager (apt-get/yum/dnf/apk) was detected.\n " +
298+ "Please install jq manually:\n " +
299+ " - Ubuntu/Debian: sudo apt-get install -y jq\n " +
300+ " - CentOS/RHEL: sudo yum install -y jq\n " +
301+ " - Fedora: sudo dnf install -y jq\n " +
302+ " - Alpine: apk add jq" )
303+ }
304+ case "darwin" :
305+ if _ , err := exec .LookPath ("brew" ); err == nil {
306+ cmd = exec .Command ("brew" , "install" , "jq" )
307+ } else {
308+ return fmt .Errorf ("jq is required but not found, and Homebrew is not available.\n " +
309+ "Please install jq manually:\n " +
310+ " - Install Homebrew first: /bin/bash -c \" $(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\" \n " +
311+ " - Then run: brew install jq" )
312+ }
313+ default :
314+ return fmt .Errorf ("jq is required but not found. Automatic installation is not supported on %s.\n " +
315+ "Please install jq manually: https://jqlang.github.io/jq/download/" , runtime .GOOS )
316+ }
317+
318+ cmd .Stdout = os .Stdout
319+ cmd .Stderr = os .Stderr
320+ if err := cmd .Run (); err != nil {
321+ return fmt .Errorf ("failed to install jq: %w" , err )
322+ }
323+
324+ // Verify jq is available after installation
325+ if _ , err := exec .LookPath ("jq" ); err != nil {
326+ return fmt .Errorf ("jq was installed but still not found in PATH. Please check your PATH configuration" )
327+ }
328+
329+ log .Info ("jq installed successfully" )
330+ return nil
331+ }
0 commit comments