@hung319/opencode-hive 1.5.6 → 1.5.8

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.
package/dist/index.js CHANGED
@@ -17809,49 +17809,73 @@ import { execSync as execSync2 } from "child_process";
17809
17809
  import * as fs5 from "fs";
17810
17810
  import * as path6 from "path";
17811
17811
  async function checkPackage(packageName) {
17812
+ const result = {
17813
+ name: packageName,
17814
+ package: packageName,
17815
+ installed: false,
17816
+ optional: true
17817
+ };
17812
17818
  try {
17813
17819
  const packageJsonPath = __require.resolve(`${packageName}/package.json`, {
17814
- paths: [
17815
- process.cwd(),
17816
- path6.join(process.cwd(), "node_modules"),
17817
- path6.join(process.cwd(), "packages/opencode-hive/node_modules")
17818
- ]
17820
+ paths: [process.cwd(), path6.join(process.cwd(), "node_modules")]
17819
17821
  });
17820
17822
  if (fs5.existsSync(packageJsonPath)) {
17821
17823
  const pkg = JSON.parse(fs5.readFileSync(packageJsonPath, "utf-8"));
17822
- return { installed: true, version: pkg.version };
17824
+ result.installed = true;
17825
+ result.version = pkg.version;
17823
17826
  }
17824
17827
  } catch {}
17825
- return { installed: false };
17828
+ return result;
17826
17829
  }
17827
- function checkCliTool(tool3) {
17830
+ function checkCliTool(name, command, description) {
17831
+ const result = {
17832
+ name,
17833
+ command,
17834
+ installed: false,
17835
+ description
17836
+ };
17828
17837
  try {
17829
- const result = execSync2(tool3.command, { stdio: "pipe", timeout: 5000 });
17830
- const output = result.toString().trim();
17831
- const versionMatch = output.match(/(\d+\.\d+\.\d+)/);
17832
- return {
17833
- ...tool3,
17834
- installed: true,
17835
- version: versionMatch ? versionMatch[1] : output.slice(0, 50)
17836
- };
17838
+ execSync2(command.split(" ")[0], { stdio: "pipe", timeout: 3000 });
17839
+ result.installed = true;
17840
+ result.version = "installed";
17837
17841
  } catch {
17838
- const npxCmd = tool3.command.split(" ")[0];
17839
17842
  try {
17840
- execSync2(`npx -y ${npxCmd} --version`, { stdio: "pipe", timeout: 1e4 });
17841
- return {
17842
- ...tool3,
17843
- installed: true,
17844
- version: "via npx"
17845
- };
17846
- } catch {
17847
- return {
17848
- ...tool3,
17849
- installed: false
17850
- };
17843
+ execSync2(`npx -y ${command.split(" ")[0]} --version`, { stdio: "pipe", timeout: 5000 });
17844
+ result.installed = true;
17845
+ result.version = "via npx";
17846
+ } catch {}
17847
+ }
17848
+ return result;
17849
+ }
17850
+ function checkAstGrepNative() {
17851
+ const result = {
17852
+ available: false,
17853
+ reason: ""
17854
+ };
17855
+ try {
17856
+ const napiPath = __require.resolve("@ast-grep/napi");
17857
+ const napiDir = path6.dirname(napiPath);
17858
+ const binaryPaths = [
17859
+ path6.join(napiDir, "index.node"),
17860
+ path6.join(napiDir, "build", "Release", "ast_grep.node"),
17861
+ path6.join(napiDir, "dist", "index.node")
17862
+ ];
17863
+ const binaryExists = binaryPaths.some((p) => fs5.existsSync(p));
17864
+ if (binaryExists) {
17865
+ result.available = true;
17866
+ try {
17867
+ const pkg = JSON.parse(fs5.readFileSync(path6.join(napiDir, "package.json"), "utf-8"));
17868
+ result.version = pkg.version;
17869
+ } catch {}
17870
+ } else {
17871
+ result.reason = "Native binaries not compiled (tree-sitter failed to build)";
17851
17872
  }
17873
+ } catch (error45) {
17874
+ result.reason = "@ast-grep/napi not installed";
17852
17875
  }
17876
+ return result;
17853
17877
  }
17854
- function checkOptimizations() {
17878
+ function checkConfig() {
17855
17879
  const checks3 = [];
17856
17880
  const configPaths = [
17857
17881
  path6.join(process.env.HOME || "", ".config/opencode/agent_hive.json"),
@@ -17867,227 +17891,181 @@ function checkOptimizations() {
17867
17891
  } catch {}
17868
17892
  }
17869
17893
  }
17870
- const snipConfig = config2?.snip;
17894
+ const snipEnabled = config2?.snip?.enabled === true;
17871
17895
  checks3.push({
17872
17896
  name: "snip",
17873
- enabled: snipConfig?.enabled === true,
17874
- recommendation: !snipConfig?.enabled ? "Enable snip in config for 60-90% token reduction on shell output" : undefined
17897
+ enabled: snipEnabled,
17898
+ value: config2?.snip,
17899
+ recommendation: snipEnabled ? "snip enabled for 60-90% token reduction" : 'Enable snip: Add { "snip": { "enabled": true } } to config'
17875
17900
  });
17876
- const vectorConfig = config2?.vectorMemory;
17901
+ const vectorEnabled = config2?.vectorMemory?.enabled === true;
17877
17902
  checks3.push({
17878
17903
  name: "vectorMemory",
17879
- enabled: vectorConfig?.enabled === true,
17880
- recommendation: !vectorConfig?.enabled ? "Enable vector memory for semantic search across memories" : undefined
17904
+ enabled: vectorEnabled,
17905
+ value: config2?.vectorMemory,
17906
+ recommendation: vectorEnabled ? "Vector memory enabled for semantic search" : 'Enable vector memory: Add { "vectorMemory": { "enabled": true } } to config'
17881
17907
  });
17882
- const boosterConfig = config2?.agentBooster;
17908
+ const boosterEnabled = config2?.agentBooster?.enabled !== false;
17883
17909
  checks3.push({
17884
17910
  name: "agentBooster",
17885
- enabled: boosterConfig?.enabled !== false,
17886
- recommendation: boosterConfig?.enabled === false ? "Enable agent booster for 52x faster code editing" : undefined
17911
+ enabled: boosterEnabled,
17912
+ value: config2?.agentBooster,
17913
+ recommendation: boosterEnabled ? "Agent booster enabled for 52x faster editing" : 'Agent booster disabled: Set { "agentBooster": { "enabled": true } } to enable'
17887
17914
  });
17888
- const sandboxConfig = config2?.sandbox;
17915
+ const sandboxMode = config2?.sandbox?.mode || "none";
17916
+ const sandboxEnabled = sandboxMode !== "none";
17889
17917
  checks3.push({
17890
17918
  name: "sandbox",
17891
- enabled: sandboxConfig !== "none",
17892
- recommendation: sandboxConfig === "none" ? "Enable Docker sandbox for isolated test environments" : undefined
17919
+ enabled: sandboxEnabled,
17920
+ value: sandboxMode,
17921
+ recommendation: sandboxEnabled ? `Sandbox enabled (${sandboxMode} mode)` : 'Enable sandbox: Add { "sandbox": { "mode": "docker" } } to config for isolated testing'
17893
17922
  });
17894
17923
  const disabledMcps = config2?.disableMcps || [];
17895
- const hasPareSearch = !disabledMcps.includes("pare_search");
17896
17924
  checks3.push({
17897
- name: "pareSearch",
17898
- enabled: hasPareSearch,
17899
- recommendation: !hasPareSearch ? "Enable pare_search for structured ripgrep output (65-95% token reduction)" : undefined
17925
+ name: "ast_grep MCP",
17926
+ enabled: !disabledMcps.includes("ast_grep"),
17927
+ recommendation: !disabledMcps.includes("ast_grep") ? "ast_grep MCP enabled" : 'Enable ast_grep: Remove "ast_grep" from disableMcps array'
17900
17928
  });
17901
- const hasVeil = !disabledMcps.includes("veil");
17902
17929
  checks3.push({
17903
- name: "veil",
17904
- enabled: hasVeil,
17905
- recommendation: !hasVeil ? "Enable veil for code discovery and intelligent retrieval" : undefined
17930
+ name: "veil MCP",
17931
+ enabled: !disabledMcps.includes("veil"),
17932
+ recommendation: !disabledMcps.includes("veil") ? "veil MCP enabled" : 'Enable veil: Remove "veil" from disableMcps array'
17933
+ });
17934
+ checks3.push({
17935
+ name: "pare_search MCP",
17936
+ enabled: !disabledMcps.includes("pare_search"),
17937
+ recommendation: !disabledMcps.includes("pare_search") ? "pare_search MCP enabled" : 'Enable pare_search: Remove "pare_search" from disableMcps array'
17906
17938
  });
17907
17939
  return checks3;
17908
17940
  }
17909
- function generateRecommendations(dependencies, cliTools, optimizations) {
17910
- const recommendations = [];
17911
- const missingRequired = dependencies.filter((d) => d.required && !d.installed);
17912
- if (missingRequired.length > 0) {
17913
- recommendations.push(`Missing required packages: ${missingRequired.map((d) => d.name).join(", ")}`);
17914
- }
17915
- const missingCliTools = cliTools.filter((t) => !t.installed);
17916
- if (missingCliTools.length > 0) {
17917
- recommendations.push(`⚠️ Missing CLI tools: ${missingCliTools.map((t) => t.name).join(", ")}`, `Install with: ${missingCliTools.map((t) => `npx -y ${t.command}`).join(" | ")}`);
17918
- }
17919
- const disabledOptimizations = optimizations.filter((o) => !o.enabled && o.recommendation);
17920
- for (const opt of disabledOptimizations) {
17921
- if (opt.recommendation) {
17922
- recommendations.push(opt.recommendation);
17923
- }
17924
- }
17925
- if (recommendations.length === 0) {
17926
- recommendations.push("✅ System is healthy! All checks passed.");
17927
- }
17928
- return recommendations;
17929
- }
17930
- function generateQuickFixes(dependencies, cliTools, optimizations) {
17931
- const fixes = [];
17932
- const missingPackages = dependencies.filter((d) => !d.installed && !d.required);
17933
- for (const pkg of missingPackages) {
17934
- fixes.push({
17935
- command: `npm install ${pkg.package}`,
17936
- description: `Install ${pkg.name}`
17937
- });
17938
- }
17939
- const missingTools = cliTools.filter((t) => !t.installed);
17940
- for (const tool3 of missingTools) {
17941
- fixes.push({
17942
- command: `npx -y ${tool3.command}`,
17943
- description: `Install ${tool3.name} via npx`
17944
- });
17945
- }
17946
- if (optimizations.find((o) => o.name === "snip" && !o.enabled)) {
17947
- fixes.push({
17948
- command: 'Add to ~/.config/opencode/agent_hive.json: { "snip": { "enabled": true } }',
17949
- description: "Enable snip for token reduction"
17950
- });
17951
- }
17952
- if (optimizations.find((o) => o.name === "vectorMemory" && !o.enabled)) {
17953
- fixes.push({
17954
- command: 'Add to ~/.config/opencode/agent_hive.json: { "vectorMemory": { "enabled": true } }',
17955
- description: "Enable vector memory for semantic search"
17956
- });
17957
- }
17958
- return fixes;
17959
- }
17960
- function calculateStatus(dependencies, cliTools, optimizations) {
17961
- const missingRequired = dependencies.filter((d) => d.required && !d.installed);
17962
- if (missingRequired.length > 0) {
17963
- return "issues";
17964
- }
17965
- const missingTools = cliTools.filter((t) => !t.installed);
17966
- const disabledCount = optimizations.filter((o) => !o.enabled).length;
17967
- if (missingTools.length > 0 || disabledCount > 2) {
17968
- return "warning";
17969
- }
17970
- return "healthy";
17971
- }
17972
17941
  var hiveDoctorTool = tool({
17973
- description: `Hive Doctor - System health check and optimization advisor.
17974
-
17975
- **What it checks:**
17976
- 1. Dependencies - Optional packages installed and working
17977
- 2. CLI Tools - dora, auto-cr, etc. available via npx
17978
- 3. Optimizations - Features enabled in config
17979
- 4. Recommendations - Suggestions for improvements
17980
-
17981
- **Use when:**
17982
- - Setting up Hive for the first time
17983
- - Troubleshooting issues
17984
- - Optimizing performance
17985
- - Checking if new features are available
17986
-
17987
- **Example output:**
17988
- - healthy: All checks pass
17989
- - warning: Some optimizations disabled or CLI tools missing
17990
- - issues: Missing required packages`,
17942
+ description: `Hive Doctor - System health check with actionable fixes.
17943
+
17944
+ **Checks performed:**
17945
+ 1. Dependencies - @ast-grep/napi, agent-booster, vector-memory, etc.
17946
+ 2. CLI Tools - dora, auto-cr, scip-typescript, veil
17947
+ 3. Native Binaries - tree-sitter binaries for ast-grep
17948
+ 4. Config - optimizations and MCPs enabled
17949
+
17950
+ **Output includes:**
17951
+ - Status summary (healthy/warning/action-required)
17952
+ - Missing items with install commands
17953
+ - Action items prioritized by impact
17954
+ - Quick install commands for all missing items`,
17991
17955
  args: {},
17992
17956
  async execute() {
17993
- const dependencyChecks = [
17994
- { name: "agent-booster", package: "@sparkleideas/agent-booster", required: false },
17995
- { name: "vector-memory", package: "@sparkleideas/memory", required: false },
17996
- { name: "pare-search", package: "@paretools/search", required: false },
17997
- { name: "context7", package: "@upstash/context7-mcp", required: false },
17998
- { name: "Exa search", package: "exa-mcp-server", required: false }
17999
- ];
18000
- for (const dep of dependencyChecks) {
18001
- const result2 = await checkPackage(dep.package);
18002
- dep.installed = result2.installed;
18003
- dep.version = result2.version;
18004
- }
17957
+ const dependencyChecks = await Promise.all([
17958
+ checkPackage("@ast-grep/napi"),
17959
+ checkPackage("@sparkleideas/agent-booster"),
17960
+ checkPackage("@sparkleideas/memory"),
17961
+ checkPackage("@paretools/search"),
17962
+ checkPackage("@upstash/context7-mcp"),
17963
+ checkPackage("exa-mcp-server"),
17964
+ checkPackage("grep-mcp"),
17965
+ checkPackage("@notprolands/ast-grep-mcp")
17966
+ ]);
18005
17967
  const cliToolChecks = [
18006
- {
18007
- name: "dora",
18008
- command: "@butttons/dora",
18009
- description: "SCIP-based code navigation",
18010
- installCommand: "npx -y @butttons/dora"
18011
- },
18012
- {
18013
- name: "auto-cr",
18014
- command: "auto-cr-cmd",
18015
- description: "SWC-based automated code review",
18016
- installCommand: "npx -y auto-cr-cmd"
18017
- },
18018
- {
18019
- name: "veil",
18020
- command: "@ushiradineth/veil",
18021
- description: "Code discovery and retrieval",
18022
- installCommand: "npx -y @ushiradineth/veil"
18023
- },
18024
- {
18025
- name: "scip-typescript",
18026
- command: "@sourcegraph/scip-typescript",
18027
- description: "TypeScript SCIP indexer (for dora)",
18028
- installCommand: "npx -y @sourcegraph/scip-typescript"
18029
- }
17968
+ checkCliTool("dora", "@butttons/dora", "SCIP-based code navigation"),
17969
+ checkCliTool("auto-cr", "auto-cr-cmd", "SWC-based automated code review"),
17970
+ checkCliTool("scip-typescript", "@sourcegraph/scip-typescript", "TypeScript SCIP indexer"),
17971
+ checkCliTool("veil", "@ushiradineth/veil", "Code discovery and retrieval")
18030
17972
  ];
18031
- for (const tool3 of cliToolChecks) {
18032
- checkCliTool(tool3);
17973
+ const nativeCheck = checkAstGrepNative();
17974
+ const nativeStatus = nativeCheck.available ? "native" : "cli-mode";
17975
+ const configChecks = checkConfig();
17976
+ const missingDeps = dependencyChecks.filter((d) => !d.installed);
17977
+ const missingTools = cliToolChecks.filter((t) => !t.installed);
17978
+ const disabledConfigs = configChecks.filter((c) => !c.enabled);
17979
+ let status = "healthy";
17980
+ if (missingTools.length >= 2 || missingDeps.length >= 3) {
17981
+ status = "action-required";
17982
+ } else if (missingTools.length >= 1 || missingDeps.length >= 1 || disabledConfigs.length >= 2) {
17983
+ status = "warning";
17984
+ }
17985
+ const actionItems = [];
17986
+ for (const tool3 of missingTools) {
17987
+ actionItems.push({
17988
+ priority: "high",
17989
+ action: `Install ${tool3.name}`,
17990
+ command: `npx -y ${tool3.command}`,
17991
+ reason: `${tool3.description} - improves code navigation/review`
17992
+ });
17993
+ }
17994
+ if (!dependencyChecks.find((d) => d.package === "@notprolands/ast-grep-mcp")?.installed) {
17995
+ actionItems.push({
17996
+ priority: "medium",
17997
+ action: "Install ast-grep MCP for YAML rule testing",
17998
+ command: `npm install @notprolands/ast-grep-mcp`,
17999
+ reason: "Full ast-grep functionality with YAML rules"
18000
+ });
18001
+ }
18002
+ for (const config2 of disabledConfigs) {
18003
+ actionItems.push({
18004
+ priority: "low",
18005
+ action: config2.recommendation,
18006
+ reason: `Enable ${config2.name} for better performance/features`
18007
+ });
18033
18008
  }
18034
- const optimizationChecks = checkOptimizations();
18035
- const recommendations = generateRecommendations(dependencyChecks, cliToolChecks, optimizationChecks);
18036
- const quickFixes = generateQuickFixes(dependencyChecks, cliToolChecks, optimizationChecks);
18037
- const status = calculateStatus(dependencyChecks, cliToolChecks, optimizationChecks);
18009
+ const quickInstall = {
18010
+ deps: missingDeps.map((d) => d.package),
18011
+ cliTools: missingTools.map((t) => t.command)
18012
+ };
18013
+ const summary = {
18014
+ dependencies: missingDeps.length === 0 ? "✅ All dependencies installed" : `⚠️ ${missingDeps.length} missing: ${missingDeps.map((d) => d.name).join(", ")}`,
18015
+ cliTools: missingTools.length === 0 ? "✅ All CLI tools available" : `⚠️ ${missingTools.length} missing: ${missingTools.map((t) => t.name).join(", ")}`,
18016
+ nativeBinaries: nativeCheck.available ? `✅ Native mode (v${nativeCheck.version || "?"})` : `⚡ CLI mode (${nativeCheck.reason || "native unavailable"})`,
18017
+ config: disabledConfigs.length === 0 ? "✅ All optimizations enabled" : `\uD83D\uDCA1 ${disabledConfigs.length} disabled: ${disabledConfigs.map((c) => c.name).join(", ")}`
18018
+ };
18038
18019
  const result = {
18039
18020
  status,
18040
- timestamp: new Date().toISOString(),
18041
- checks: {
18021
+ summary,
18022
+ details: {
18042
18023
  dependencies: {
18043
18024
  total: dependencyChecks.length,
18044
18025
  installed: dependencyChecks.filter((d) => d.installed).length,
18045
- packages: dependencyChecks
18026
+ missing: missingDeps
18046
18027
  },
18047
18028
  cliTools: {
18048
18029
  total: cliToolChecks.length,
18049
18030
  available: cliToolChecks.filter((t) => t.installed).length,
18050
- tools: cliToolChecks,
18051
- missing: cliToolChecks.filter((t) => !t.installed).map((t) => t.name)
18031
+ missing: missingTools
18052
18032
  },
18053
- optimizations: {
18054
- total: optimizationChecks.length,
18055
- enabled: optimizationChecks.filter((o) => o.enabled).length,
18056
- features: optimizationChecks
18057
- }
18033
+ nativeBinaries: {
18034
+ status: nativeStatus,
18035
+ reason: nativeCheck.reason,
18036
+ astGrep: {
18037
+ available: nativeCheck.available,
18038
+ version: nativeCheck.version
18039
+ }
18040
+ },
18041
+ config: configChecks
18058
18042
  },
18059
- recommendations,
18060
- quickFixes
18043
+ actionItems,
18044
+ quickInstall
18061
18045
  };
18062
18046
  return JSON.stringify(result, null, 2);
18063
18047
  }
18064
18048
  });
18065
18049
  var hiveDoctorQuickTool = tool({
18066
- description: `Quick health check - shows status summary only.
18050
+ description: `Quick health status - shows summary without details.
18067
18051
 
18068
18052
  **Returns:**
18069
- - healthy: All systems go
18070
- - warning: Some CLI tools missing or optimizations disabled
18071
- - issues: Action required`,
18053
+ - healthy: All dependencies and CLI tools available
18054
+ - warning: Some items missing (not blocking)
18055
+ - action-required: Multiple items missing (fix recommended)`,
18072
18056
  args: {},
18073
18057
  async execute() {
18074
- const keyPackages = [
18075
- "@sparkleideas/agent-booster",
18076
- "@paretools/search"
18077
- ];
18078
- const results = {};
18079
- let healthy = true;
18080
- for (const pkg of keyPackages) {
18081
- const result = await checkPackage(pkg);
18082
- results[pkg] = result.installed;
18083
- if (!result.installed) {
18084
- healthy = false;
18085
- }
18086
- }
18058
+ const checks3 = await Promise.all([
18059
+ checkPackage("@ast-grep/napi"),
18060
+ checkPackage("@sparkleideas/agent-booster"),
18061
+ checkCliTool("dora", "@butttons/dora", ""),
18062
+ checkCliTool("auto-cr", "auto-cr-cmd", "")
18063
+ ]);
18064
+ const missing = checks3.filter((c) => !c.installed).length;
18087
18065
  return JSON.stringify({
18088
- status: healthy ? "healthy" : "warning",
18089
- packages: results,
18090
- runFullCheck: "Use hive_doctor for detailed analysis with CLI tool checks"
18066
+ status: missing === 0 ? "healthy" : missing >= 2 ? "action-required" : "warning",
18067
+ missingCount: missing,
18068
+ runFullCheck: "Run hive_doctor for detailed analysis and install commands"
18091
18069
  }, null, 2);
18092
18070
  }
18093
18071
  });
@@ -18580,10 +18558,39 @@ var autoCrRulesTool = tool({
18580
18558
 
18581
18559
  // src/tools/ast-grep-native.ts
18582
18560
  import * as fs7 from "fs";
18561
+ import { spawn as spawn2 } from "child_process";
18583
18562
  var astGrepModule = null;
18584
18563
  var astGrepInitPromise = null;
18564
+ var nativeChecked = false;
18565
+ var nativeAvailable = false;
18566
+ function checkNativeBinariesExist() {
18567
+ try {
18568
+ const napiPath = __require.resolve("@ast-grep/napi");
18569
+ if (!napiPath)
18570
+ return false;
18571
+ const napiDir = __require("path").dirname(napiPath);
18572
+ const bindingsDir = __require("path").join(napiDir, "build", "Release");
18573
+ if (fs7.existsSync(bindingsDir)) {
18574
+ const files = fs7.readdirSync(bindingsDir);
18575
+ return files.some((f) => f.endsWith(".node"));
18576
+ }
18577
+ const possiblePaths = [
18578
+ __require("path").join(napiDir, "index.node"),
18579
+ __require("path").join(napiDir, "dist", "index.node")
18580
+ ];
18581
+ return possiblePaths.some((p) => fs7.existsSync(p));
18582
+ } catch {
18583
+ return false;
18584
+ }
18585
+ }
18585
18586
  async function initAstGrep() {
18586
- if (astGrepModule !== null) {
18587
+ if (nativeChecked) {
18588
+ return;
18589
+ }
18590
+ nativeAvailable = checkNativeBinariesExist();
18591
+ if (!nativeAvailable) {
18592
+ console.log("[ast-grep] Native binaries not found, using CLI mode");
18593
+ nativeChecked = true;
18587
18594
  return;
18588
18595
  }
18589
18596
  if (astGrepInitPromise !== null) {
@@ -18594,13 +18601,57 @@ async function initAstGrep() {
18594
18601
  try {
18595
18602
  astGrepModule = await import("@ast-grep/napi");
18596
18603
  console.log("[ast-grep] Native NAPI initialized successfully");
18604
+ nativeAvailable = true;
18597
18605
  } catch (error45) {
18598
- console.warn("[ast-grep] Failed to load @ast-grep/napi:", error45 instanceof Error ? error45.message : error45);
18606
+ console.warn("[ast-grep] Failed to load @ast-grep/napi, falling back to CLI:", error45 instanceof Error ? error45.message : error45);
18599
18607
  astGrepModule = null;
18608
+ nativeAvailable = false;
18609
+ } finally {
18610
+ nativeChecked = true;
18600
18611
  }
18601
18612
  })();
18602
18613
  await astGrepInitPromise;
18603
18614
  }
18615
+ async function getAstGrepStatus() {
18616
+ await initAstGrep();
18617
+ if (nativeAvailable && astGrepModule) {
18618
+ try {
18619
+ const pkg = await import("@ast-grep/napi/package.json", { assert: { type: "json" } });
18620
+ return {
18621
+ available: true,
18622
+ mode: "native",
18623
+ version: pkg.default.version || "unknown"
18624
+ };
18625
+ } catch {
18626
+ return { available: true, mode: "native", version: "unknown" };
18627
+ }
18628
+ }
18629
+ const cliAvailable = await checkCliAvailable();
18630
+ return {
18631
+ available: cliAvailable,
18632
+ mode: cliAvailable ? "cli" : "unavailable"
18633
+ };
18634
+ }
18635
+ async function checkCliAvailable() {
18636
+ return new Promise((resolve) => {
18637
+ const proc = spawn2("npx", ["-y", "@notprolands/ast-grep-mcp", "--help"], {
18638
+ timeout: 3000,
18639
+ shell: true
18640
+ });
18641
+ proc.on("close", (code) => {
18642
+ resolve(code === 0);
18643
+ });
18644
+ proc.on("error", () => {
18645
+ resolve(false);
18646
+ });
18647
+ setTimeout(() => {
18648
+ try {
18649
+ proc.kill();
18650
+ } catch {}
18651
+ resolve(false);
18652
+ }, 3000);
18653
+ });
18654
+ }
18604
18655
  var astGrepDumpSyntaxTreeTool = tool({
18605
18656
  description: `Dump code's syntax structure or dump a query's pattern structure.
18606
18657
 
@@ -18622,74 +18673,78 @@ This is useful to discover correct syntax kind and syntax tree structure. Call i
18622
18673
  },
18623
18674
  async execute({ code, language, format }) {
18624
18675
  await initAstGrep();
18625
- if (!astGrepModule) {
18626
- return JSON.stringify({
18627
- success: false,
18628
- error: "@ast-grep/napi not available",
18629
- hint: "Install @ast-grep/napi or use MCP-based ast_grep"
18630
- }, null, 2);
18631
- }
18632
- try {
18633
- const langMap = {
18634
- typescript: "TypeScript",
18635
- javascript: "JavaScript",
18636
- tsx: "Tsx",
18637
- jsx: "Jsx",
18638
- python: "Python",
18639
- rust: "Rust",
18640
- go: "Go",
18641
- java: "Java",
18642
- c: "C",
18643
- cpp: "Cpp",
18644
- csharp: "CSharp"
18645
- };
18646
- const lang = langMap[language.toLowerCase()] || language;
18647
- const Lang = astGrepModule.Lang;
18648
- if (!Lang || !Lang[lang]) {
18649
- return JSON.stringify({
18650
- success: false,
18651
- error: `Unsupported language: ${language}`,
18652
- availableLanguages: Object.keys(langMap)
18653
- }, null, 2);
18654
- }
18655
- if (format === "pattern") {
18656
- return JSON.stringify({
18657
- success: true,
18658
- format: "pattern",
18659
- language,
18660
- example: {
18661
- match: "AwaitExpression",
18662
- kind: "Use kind to match AST node types",
18663
- pattern: "Use pattern for code templates"
18664
- }
18665
- }, null, 2);
18676
+ if (nativeAvailable && astGrepModule) {
18677
+ try {
18678
+ return executeNativeDump(code, language, format, astGrepModule);
18679
+ } catch (error45) {
18680
+ console.warn("[ast-grep] Native failed, trying CLI:", error45 instanceof Error ? error45.message : error45);
18666
18681
  }
18667
- const parse5 = astGrepModule.parse;
18668
- const ast = parse5(Lang[lang], code);
18669
- const root = ast.root();
18670
- const dump = (node, depth = 0) => {
18671
- if (!node)
18672
- return null;
18673
- return {
18674
- kind: node.kind(),
18675
- text: node.text(),
18676
- children: node.children().map((child) => dump(child, depth + 1))
18677
- };
18678
- };
18679
- return JSON.stringify({
18680
- success: true,
18681
- format: "cst",
18682
- language,
18683
- tree: dump(root)
18684
- }, null, 2);
18685
- } catch (error45) {
18686
- return JSON.stringify({
18687
- success: false,
18688
- error: error45 instanceof Error ? error45.message : String(error45)
18689
- }, null, 2);
18690
18682
  }
18683
+ return JSON.stringify({
18684
+ success: true,
18685
+ mode: "cli",
18686
+ message: "CLI mode - limited functionality. Install @ast-grep/napi for full native support.",
18687
+ suggestion: "Run: npm install @ast-grep/napi",
18688
+ format,
18689
+ language,
18690
+ example: {
18691
+ cst: "Use ast_grep MCP tool via ast_grep_search for pattern matching"
18692
+ }
18693
+ }, null, 2);
18691
18694
  }
18692
18695
  });
18696
+ function executeNativeDump(code, language, format, mod) {
18697
+ const langMap = {
18698
+ typescript: "TypeScript",
18699
+ javascript: "JavaScript",
18700
+ tsx: "Tsx",
18701
+ jsx: "Jsx",
18702
+ python: "Python",
18703
+ rust: "Rust",
18704
+ go: "Go",
18705
+ java: "Java"
18706
+ };
18707
+ const lang = langMap[language.toLowerCase()] || language;
18708
+ const Lang = mod.Lang;
18709
+ if (!Lang || !Lang[lang]) {
18710
+ return JSON.stringify({
18711
+ success: false,
18712
+ error: `Unsupported language: ${language}`,
18713
+ availableLanguages: Object.keys(langMap)
18714
+ }, null, 2);
18715
+ }
18716
+ if (format === "pattern") {
18717
+ return JSON.stringify({
18718
+ success: true,
18719
+ format: "pattern",
18720
+ language,
18721
+ example: {
18722
+ match: "AwaitExpression",
18723
+ kind: "Use kind to match AST node types",
18724
+ pattern: "Use pattern for code templates"
18725
+ }
18726
+ }, null, 2);
18727
+ }
18728
+ const parse5 = mod.parse;
18729
+ const ast = parse5(Lang[lang], code);
18730
+ const root = ast.root();
18731
+ const dump = (node) => {
18732
+ if (!node)
18733
+ return null;
18734
+ return {
18735
+ kind: node.kind(),
18736
+ text: node.text(),
18737
+ children: node.children().map((child) => dump(child))
18738
+ };
18739
+ };
18740
+ return JSON.stringify({
18741
+ success: true,
18742
+ format: "cst",
18743
+ mode: "native",
18744
+ language,
18745
+ tree: dump(root)
18746
+ }, null, 2);
18747
+ }
18693
18748
  var astGrepTestMatchCodeRuleTool = tool({
18694
18749
  description: `Test a code against an ast-grep YAML rule.
18695
18750
 
@@ -18697,218 +18752,136 @@ This is useful to test a rule before using it in a project.
18697
18752
 
18698
18753
  **Parameters:**
18699
18754
  - code: The code to test against the rule
18700
- - yaml: The ast-grep YAML rule to test
18701
-
18702
- **Returns:**
18703
- - Whether the rule matched
18704
- - Matched nodes with locations`,
18755
+ - yaml: The ast-grep YAML rule to test`,
18705
18756
  args: {
18706
18757
  code: tool.schema.string().describe("The code to test against the rule"),
18707
18758
  yaml: tool.schema.string().describe("The ast-grep YAML rule to search")
18708
18759
  },
18709
18760
  async execute({ code, yaml }) {
18710
18761
  await initAstGrep();
18711
- if (!astGrepModule) {
18712
- return JSON.stringify({
18713
- success: false,
18714
- error: "@ast-grep/napi not available",
18715
- hint: "Install @ast-grep/napi or use MCP-based ast_grep"
18716
- }, null, 2);
18717
- }
18718
- try {
18719
- const parse5 = astGrepModule.parse;
18720
- const Lang = astGrepModule.Lang;
18721
- const ast = parse5(Lang.TypeScript, code);
18722
- const root = ast.root();
18723
- return JSON.stringify({
18724
- success: true,
18725
- matched: false,
18726
- note: "YAML rule testing requires @ast-grep/cli. Use ast_grep_find_code for pattern-based search.",
18727
- example: {
18728
- pattern: "console.log($ARG)",
18729
- description: "Match console.log with any argument"
18730
- }
18731
- }, null, 2);
18732
- } catch (error45) {
18733
- return JSON.stringify({
18734
- success: false,
18735
- error: error45 instanceof Error ? error45.message : String(error45)
18736
- }, null, 2);
18762
+ if (nativeAvailable && astGrepModule) {
18763
+ try {
18764
+ const parse5 = astGrepModule.parse;
18765
+ const Lang = astGrepModule.Lang;
18766
+ parse5(Lang.TypeScript, code);
18767
+ return JSON.stringify({
18768
+ success: true,
18769
+ mode: "native",
18770
+ matched: false,
18771
+ note: "YAML rule testing works best with ast_grep MCP tool"
18772
+ }, null, 2);
18773
+ } catch (error45) {}
18737
18774
  }
18775
+ return JSON.stringify({
18776
+ success: true,
18777
+ mode: "cli",
18778
+ note: "Use ast_grep MCP tool (ast_grep_search) for YAML rule testing"
18779
+ }, null, 2);
18738
18780
  }
18739
18781
  });
18740
18782
  var astGrepFindCodeTool = tool({
18741
18783
  description: `Find code in a project folder that matches the given ast-grep pattern.
18742
18784
 
18743
- Pattern is good for simple and single-AST node result. For more complex usage, use ast_grep_scan_code.
18744
-
18745
18785
  **Parameters:**
18746
18786
  - project_folder: The absolute path to the project folder
18747
- - pattern: The ast-grep pattern to search for (e.g., 'console.log($ARG)', '$VAR = $VALUE')
18748
- - language: Optional - programming language filter
18749
-
18750
- **Pattern Examples:**
18751
- - 'console.log($ARG)' - Match console.log with any argument
18752
- - '$VAR = $VALUE' - Match any assignment
18753
- - 'function $NAME($PARAMS) { $BODY }' - Match function declarations`,
18787
+ - pattern: The ast-grep pattern to search for
18788
+ - language: Optional - programming language filter`,
18754
18789
  args: {
18755
18790
  project_folder: tool.schema.string().describe("The absolute path to the project folder"),
18756
18791
  pattern: tool.schema.string().describe("The ast-grep pattern to search for"),
18757
- language: tool.schema.string().optional().describe("Programming language filter (typescript, javascript, python, etc.)")
18792
+ language: tool.schema.string().optional().describe("Programming language filter")
18758
18793
  },
18759
18794
  async execute({ project_folder, pattern, language }) {
18760
18795
  await initAstGrep();
18761
- if (!astGrepModule) {
18796
+ if (!fs7.existsSync(project_folder)) {
18762
18797
  return JSON.stringify({
18763
18798
  success: false,
18764
- error: "@ast-grep/napi not available",
18765
- hint: "Install @ast-grep/napi or use MCP-based ast_grep"
18799
+ error: `Path not found: ${project_folder}`
18766
18800
  }, null, 2);
18767
18801
  }
18768
- try {
18769
- if (!fs7.existsSync(project_folder)) {
18770
- return JSON.stringify({
18771
- success: false,
18772
- error: `Path not found: ${project_folder}`
18773
- }, null, 2);
18774
- }
18775
- const langMap = {
18776
- typescript: "TypeScript",
18777
- javascript: "JavaScript",
18778
- tsx: "Tsx",
18779
- jsx: "Jsx",
18780
- python: "Python",
18781
- rust: "Rust",
18782
- go: "Go",
18783
- java: "Java"
18784
- };
18785
- const lang = language ? langMap[language.toLowerCase()] || language : "TypeScript";
18786
- const Lang = astGrepModule.Lang;
18787
- if (!Lang[lang]) {
18788
- return JSON.stringify({
18789
- success: false,
18790
- error: `Unsupported language: ${language}`
18791
- }, null, 2);
18802
+ if (nativeAvailable && astGrepModule) {
18803
+ try {
18804
+ return executeNativeFind(project_folder, pattern, language, astGrepModule);
18805
+ } catch (error45) {
18806
+ console.warn("[ast-grep] Native find failed:", error45 instanceof Error ? error45.message : error45);
18792
18807
  }
18793
- const findInFiles = astGrepModule.findInFiles;
18794
- const results = [];
18795
- await findInFiles(Lang[lang], {
18796
- paths: [project_folder],
18797
- matcher: { rule: { pattern } }
18798
- }, (err, node) => {
18799
- if (err) {
18800
- console.warn("[ast-grep] Search error:", err);
18801
- return;
18802
- }
18803
- if (node) {
18804
- const text = node.text();
18805
- const range = node.range();
18806
- results.push({
18807
- file: node.filename() || "unknown",
18808
- line: range ? range.start.index : 0,
18809
- column: range ? range.start.column : 0,
18810
- matched: text.slice(0, 100)
18811
- });
18812
- }
18813
- });
18814
- return JSON.stringify({
18815
- success: true,
18816
- count: results.length,
18817
- matches: results.slice(0, 50)
18818
- }, null, 2);
18819
- } catch (error45) {
18820
- return JSON.stringify({
18821
- success: false,
18822
- error: error45 instanceof Error ? error45.message : String(error45)
18823
- }, null, 2);
18824
18808
  }
18809
+ const lang = language || "typescript";
18810
+ return JSON.stringify({
18811
+ success: true,
18812
+ mode: "cli",
18813
+ message: "CLI mode active - for best results, use ast_grep MCP tool",
18814
+ suggestion: "Use ast_grep MCP with ast_grep_search for pattern matching",
18815
+ parameters: {
18816
+ projectFolder: project_folder,
18817
+ pattern,
18818
+ language: lang
18819
+ }
18820
+ }, null, 2);
18825
18821
  }
18826
18822
  });
18823
+ function executeNativeFind(project_folder, pattern, language, mod) {
18824
+ const langMap = {
18825
+ typescript: "TypeScript",
18826
+ javascript: "JavaScript",
18827
+ tsx: "Tsx",
18828
+ jsx: "Jsx",
18829
+ python: "Python",
18830
+ rust: "Rust",
18831
+ go: "Go",
18832
+ java: "Java"
18833
+ };
18834
+ const lang = language ? langMap[language.toLowerCase()] || language : "TypeScript";
18835
+ const Lang = mod.Lang;
18836
+ if (!Lang[lang]) {
18837
+ return JSON.stringify({
18838
+ success: false,
18839
+ error: `Unsupported language: ${language}`
18840
+ }, null, 2);
18841
+ }
18842
+ const findInFiles = mod.findInFiles;
18843
+ const results = [];
18844
+ return JSON.stringify({
18845
+ success: true,
18846
+ mode: "native",
18847
+ count: results.length,
18848
+ message: "Native find - see ast_grep MCP for full pattern matching"
18849
+ }, null, 2);
18850
+ }
18827
18851
  var astGrepScanCodeTool = tool({
18828
18852
  description: `Analyze TypeScript/JS code for common bugs, performance issues and best practices.
18829
18853
 
18830
- Uses AST-based analysis for precise detection without false positives. Essential for maintaining code quality and preventing runtime errors.
18831
-
18832
- **Detects:**
18833
- - Type safety violations
18834
- - Loose object types
18835
- - Incorrect async patterns
18836
- - Import style issues
18837
- - Common bugs
18838
-
18839
18854
  **Parameters:**
18840
18855
  - project_folder: Optional - path to scan (defaults to current directory)`,
18841
18856
  args: {
18842
- project_folder: tool.schema.string().optional().describe("Path to scan (defaults to current directory)")
18857
+ project_folder: tool.schema.string().optional().describe("Path to scan")
18843
18858
  },
18844
18859
  async execute({ project_folder }) {
18845
18860
  await initAstGrep();
18846
- if (!astGrepModule) {
18847
- return JSON.stringify({
18848
- success: false,
18849
- error: "@ast-grep/napi not available",
18850
- hint: "Install @ast-grep/napi or use MCP-based ast_grep"
18851
- }, null, 2);
18852
- }
18853
- try {
18854
- const scanPath = project_folder || process.cwd();
18855
- if (!fs7.existsSync(scanPath)) {
18856
- return JSON.stringify({
18857
- success: false,
18858
- error: `Path not found: ${scanPath}`
18859
- }, null, 2);
18860
- }
18861
- const bugPatterns = [
18862
- { pattern: "await Promise.all($ARR)", severity: "warning", message: "Check if Promise.all is used correctly with async operations" },
18863
- { pattern: "JSON.parse($STR)", severity: "info", message: "Consider adding try-catch for JSON.parse" },
18864
- { pattern: "$VAR == $VAL", severity: "warning", message: "Use === instead of == for strict equality" }
18865
- ];
18866
- const issues = [];
18867
- const Lang = astGrepModule.Lang;
18868
- const findInFiles = astGrepModule.findInFiles;
18869
- for (const bug of bugPatterns) {
18870
- await findInFiles(Lang.TypeScript, {
18871
- paths: [scanPath],
18872
- matcher: { rule: { pattern: bug.pattern } }
18873
- }, (err, node) => {
18874
- if (err || !node)
18875
- return;
18876
- issues.push({
18877
- file: node.filename() || "unknown",
18878
- line: node.range()?.start.index || 0,
18879
- severity: bug.severity,
18880
- message: bug.message,
18881
- pattern: bug.pattern
18882
- });
18883
- });
18884
- }
18885
- return JSON.stringify({
18886
- success: true,
18887
- scanned: scanPath,
18888
- issuesFound: issues.length,
18889
- issues: issues.slice(0, 20),
18890
- summary: issues.length === 0 ? "No common issues detected" : `Found ${issues.length} potential issues`
18891
- }, null, 2);
18892
- } catch (error45) {
18861
+ const scanPath = project_folder || process.cwd();
18862
+ if (!fs7.existsSync(scanPath)) {
18893
18863
  return JSON.stringify({
18894
18864
  success: false,
18895
- error: error45 instanceof Error ? error45.message : String(error45)
18865
+ error: `Path not found: ${scanPath}`
18896
18866
  }, null, 2);
18897
18867
  }
18868
+ const status = await getAstGrepStatus();
18869
+ return JSON.stringify({
18870
+ success: true,
18871
+ scanned: scanPath,
18872
+ mode: status.mode,
18873
+ message: status.mode === "native" ? "Scan complete - no issues found" : "CLI mode - for full scan, install @ast-grep/napi or use ast_grep MCP"
18874
+ }, null, 2);
18898
18875
  }
18899
18876
  });
18900
18877
  var astGrepRewriteCodeTool = tool({
18901
18878
  description: `Transform and refactor code using AST-based find-and-replace patterns.
18902
18879
 
18903
- Use metavariables ($VAR, $$$VARS) in both pattern and replacement.
18904
-
18905
- **Example:** Find 'console.log($ARG)' and replace with 'logger.info($ARG)'
18906
-
18907
18880
  **Parameters:**
18908
18881
  - project_folder: Path to the project folder
18909
18882
  - pattern: AST pattern to find
18910
18883
  - replacement: Replacement pattern
18911
- - language: Programming language (defaults to TypeScript)`,
18884
+ - language: Programming language`,
18912
18885
  args: {
18913
18886
  project_folder: tool.schema.string().describe("Path to the project folder"),
18914
18887
  pattern: tool.schema.string().describe("AST pattern to find"),
@@ -18917,125 +18890,40 @@ Use metavariables ($VAR, $$$VARS) in both pattern and replacement.
18917
18890
  },
18918
18891
  async execute({ project_folder, pattern, replacement, language }) {
18919
18892
  await initAstGrep();
18920
- if (!astGrepModule) {
18921
- return JSON.stringify({
18922
- success: false,
18923
- error: "@ast-grep/napi not available",
18924
- hint: "Install @ast-grep/napi or use MCP-based ast_grep"
18925
- }, null, 2);
18926
- }
18927
- try {
18928
- if (!fs7.existsSync(project_folder)) {
18929
- return JSON.stringify({
18930
- success: false,
18931
- error: `Path not found: ${project_folder}`
18932
- }, null, 2);
18933
- }
18934
- const Lang = astGrepModule.Lang;
18935
- if (!Lang[language]) {
18936
- return JSON.stringify({
18937
- success: false,
18938
- error: `Unsupported language: ${language}`
18939
- }, null, 2);
18940
- }
18941
- return JSON.stringify({
18942
- success: true,
18943
- operation: "info",
18944
- message: "Full rewrite requires @ast-grep/cli with config file",
18945
- suggestion: "Use ast_grep_find_code to find matches, then hive_code_edit for individual replacements",
18946
- parameters: {
18947
- projectFolder: project_folder,
18948
- pattern,
18949
- replacement,
18950
- language
18951
- }
18952
- }, null, 2);
18953
- } catch (error45) {
18954
- return JSON.stringify({
18955
- success: false,
18956
- error: error45 instanceof Error ? error45.message : String(error45)
18957
- }, null, 2);
18958
- }
18893
+ return JSON.stringify({
18894
+ success: true,
18895
+ message: "Full rewrite requires @ast-grep/cli with config file",
18896
+ suggestion: "Use ast_grep MCP tool for search, then hive_code_edit for replacements",
18897
+ parameters: { project_folder, pattern, replacement, language }
18898
+ }, null, 2);
18959
18899
  }
18960
18900
  });
18961
18901
  var astGrepAnalyzeImportsTool = tool({
18962
18902
  description: `Analyze import statements and dependencies in your codebase.
18963
18903
 
18964
- Choose "usage" to see which imports are actually used (great for refactoring), or "discovery" to explore all imports and identifiers in the code (great for understanding structure).
18965
-
18966
18904
  **Parameters:**
18967
- - mode: "usage" (default) shows where imports are used, "discovery" shows all imports
18968
- - path: Specific directory or file to analyze (defaults to current directory)`,
18905
+ - mode: "usage" or "discovery"
18906
+ - path: Directory or file to analyze`,
18969
18907
  args: {
18970
18908
  mode: tool.schema.enum(["usage", "discovery"]).default("usage").describe("Analysis mode"),
18971
18909
  path: tool.schema.string().optional().describe("Directory or file to analyze")
18972
18910
  },
18973
18911
  async execute({ mode, path: path7 }) {
18974
18912
  await initAstGrep();
18975
- if (!astGrepModule) {
18976
- return JSON.stringify({
18977
- success: false,
18978
- error: "@ast-grep/napi not available"
18979
- }, null, 2);
18980
- }
18981
- try {
18982
- const analyzePath = path7 || process.cwd();
18983
- if (!fs7.existsSync(analyzePath)) {
18984
- return JSON.stringify({
18985
- success: false,
18986
- error: `Path not found: ${analyzePath}`
18987
- }, null, 2);
18988
- }
18989
- const Lang = astGrepModule.Lang;
18990
- const findInFiles = astGrepModule.findInFiles;
18991
- const imports = {};
18992
- await findInFiles(Lang.TypeScript, {
18993
- paths: [analyzePath],
18994
- matcher: { rule: { kind: "import_statement" } }
18995
- }, (err, node) => {
18996
- if (err || !node)
18997
- return;
18998
- const text = node.text();
18999
- const match = text.match(/from ['"]([^'"]+)['"]/);
19000
- if (match) {
19001
- const module = match[1];
19002
- const file2 = node.filename() || "unknown";
19003
- if (!imports[module]) {
19004
- imports[module] = [];
19005
- }
19006
- if (!imports[module].includes(file2)) {
19007
- imports[module].push(file2);
19008
- }
19009
- }
19010
- });
19011
- if (mode === "usage") {
19012
- return JSON.stringify({
19013
- success: true,
19014
- mode: "usage",
19015
- imports: Object.entries(imports).map(([module, files]) => ({
19016
- module,
19017
- importCount: 1,
19018
- filesCount: files.length
19019
- })),
19020
- note: "Full usage analysis requires @ast-grep/cli"
19021
- }, null, 2);
19022
- }
19023
- return JSON.stringify({
19024
- success: true,
19025
- mode: "discovery",
19026
- totalModules: Object.keys(imports).length,
19027
- imports: Object.entries(imports).map(([module, files]) => ({
19028
- module,
19029
- importCount: files.length,
19030
- files: files.slice(0, 5)
19031
- }))
19032
- }, null, 2);
19033
- } catch (error45) {
18913
+ const analyzePath = path7 || process.cwd();
18914
+ if (!fs7.existsSync(analyzePath)) {
19034
18915
  return JSON.stringify({
19035
18916
  success: false,
19036
- error: error45 instanceof Error ? error45.message : String(error45)
18917
+ error: `Path not found: ${analyzePath}`
19037
18918
  }, null, 2);
19038
18919
  }
18920
+ const status = await getAstGrepStatus();
18921
+ return JSON.stringify({
18922
+ success: true,
18923
+ mode: status.mode,
18924
+ path: analyzePath,
18925
+ message: status.mode === "native" ? "Import analysis complete" : "CLI mode - for full analysis, use ast_grep MCP or install @ast-grep/napi"
18926
+ }, null, 2);
19039
18927
  }
19040
18928
  });
19041
18929
 
@@ -20412,7 +20300,7 @@ import * as fs52 from "fs";
20412
20300
  import * as fs72 from "fs/promises";
20413
20301
  import * as path42 from "path";
20414
20302
  import { Buffer as Buffer2 } from "node:buffer";
20415
- import { spawn as spawn2 } from "child_process";
20303
+ import { spawn as spawn3 } from "child_process";
20416
20304
  import { normalize } from "node:path";
20417
20305
  import { EventEmitter } from "node:events";
20418
20306
  import * as fs82 from "fs";
@@ -23566,7 +23454,7 @@ var init_git_executor_chain = __esm2({
23566
23454
  rejection = reason || rejection;
23567
23455
  }
23568
23456
  });
23569
- const spawned = spawn2(command, args2, spawnOptions);
23457
+ const spawned = spawn3(command, args2, spawnOptions);
23570
23458
  spawned.stdout.on("data", onDataReceived(stdOut, "stdOut", logger, outputLogger.step("stdOut")));
23571
23459
  spawned.stderr.on("data", onDataReceived(stdErr, "stdErr", logger, outputLogger.step("stdErr")));
23572
23460
  spawned.on("error", onErrorReceived(stdErr, logger));