@hung319/opencode-hive 1.5.6 → 1.5.9

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,188 @@ 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.
17942
+ description: `Hive Doctor - System health check with actionable fixes.
17974
17943
 
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
17944
+ **Checks performed:**
17945
+ 1. Dependencies - All MCP packages, ast-grep, agent-booster, etc.
17946
+ 2. CLI Tools - dora, auto-cr, scip-typescript, veil, btca, etc.
17947
+ 3. Native Binaries - tree-sitter binaries for ast-grep
17948
+ 4. Config - optimizations and MCPs enabled
17980
17949
 
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`,
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
17955
+
17956
+ **Tip:** Run standalone before installing: \`bunx @hung319/opencode-hive doctor\``,
17991
17957
  args: {},
17992
17958
  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
- }
17959
+ const dependencyChecks = await Promise.all([
17960
+ checkPackage("@ast-grep/napi"),
17961
+ checkPackage("@notprolands/ast-grep-mcp"),
17962
+ checkPackage("@paretools/search"),
17963
+ checkPackage("@sparkleideas/agent-booster"),
17964
+ checkPackage("@sparkleideas/memory"),
17965
+ checkPackage("@upstash/context7-mcp"),
17966
+ checkPackage("exa-mcp-server"),
17967
+ checkPackage("grep-mcp"),
17968
+ checkPackage("btca-ask"),
17969
+ checkPackage("opencode-model-selector"),
17970
+ checkPackage("opencode-model-selector-free")
17971
+ ]);
18005
17972
  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
- }
17973
+ checkCliTool("dora", "@butttons/dora", "SCIP-based code navigation"),
17974
+ checkCliTool("auto-cr", "auto-cr-cmd", "SWC-based automated code review"),
17975
+ checkCliTool("scip-typescript", "@sourcegraph/scip-typescript", "TypeScript SCIP indexer"),
17976
+ checkCliTool("veil", "@ushiradineth/veil", "Code discovery and retrieval"),
17977
+ checkCliTool("btca", "btca-ask", "BTC/A agent for blockchain tasks"),
17978
+ checkCliTool("ast-grep", "@notprolands/ast-grep-mcp", "AST-based pattern matching")
18030
17979
  ];
18031
- for (const tool3 of cliToolChecks) {
18032
- checkCliTool(tool3);
17980
+ const nativeCheck = checkAstGrepNative();
17981
+ const nativeStatus = nativeCheck.available ? "native" : "cli-mode";
17982
+ const configChecks = checkConfig();
17983
+ const missingDeps = dependencyChecks.filter((d) => !d.installed);
17984
+ const missingTools = cliToolChecks.filter((t) => !t.installed);
17985
+ const disabledConfigs = configChecks.filter((c) => !c.enabled);
17986
+ let status = "healthy";
17987
+ if (missingTools.length >= 2 || missingDeps.length >= 3) {
17988
+ status = "action-required";
17989
+ } else if (missingTools.length >= 1 || missingDeps.length >= 1 || disabledConfigs.length >= 2) {
17990
+ status = "warning";
17991
+ }
17992
+ const actionItems = [];
17993
+ for (const tool3 of missingTools) {
17994
+ actionItems.push({
17995
+ priority: "high",
17996
+ action: `Install ${tool3.name}`,
17997
+ command: `npx -y ${tool3.command}`,
17998
+ reason: `${tool3.description} - improves code navigation/review`
17999
+ });
18000
+ }
18001
+ if (!dependencyChecks.find((d) => d.package === "@notprolands/ast-grep-mcp")?.installed) {
18002
+ actionItems.push({
18003
+ priority: "medium",
18004
+ action: "Install ast-grep MCP for YAML rule testing",
18005
+ command: `npm install @notprolands/ast-grep-mcp`,
18006
+ reason: "Full ast-grep functionality with YAML rules"
18007
+ });
18008
+ }
18009
+ for (const config2 of disabledConfigs) {
18010
+ actionItems.push({
18011
+ priority: "low",
18012
+ action: config2.recommendation,
18013
+ reason: `Enable ${config2.name} for better performance/features`
18014
+ });
18033
18015
  }
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);
18016
+ const quickInstall = {
18017
+ deps: missingDeps.map((d) => d.package),
18018
+ cliTools: missingTools.map((t) => t.command)
18019
+ };
18020
+ const summary = {
18021
+ dependencies: missingDeps.length === 0 ? "✅ All dependencies installed" : `⚠️ ${missingDeps.length} missing: ${missingDeps.map((d) => d.name).join(", ")}`,
18022
+ cliTools: missingTools.length === 0 ? "✅ All CLI tools available" : `⚠️ ${missingTools.length} missing: ${missingTools.map((t) => t.name).join(", ")}`,
18023
+ nativeBinaries: nativeCheck.available ? `✅ Native mode (v${nativeCheck.version || "?"})` : `⚡ CLI mode (${nativeCheck.reason || "native unavailable"})`,
18024
+ config: disabledConfigs.length === 0 ? "✅ All optimizations enabled" : `\uD83D\uDCA1 ${disabledConfigs.length} disabled: ${disabledConfigs.map((c) => c.name).join(", ")}`
18025
+ };
18038
18026
  const result = {
18039
18027
  status,
18040
- timestamp: new Date().toISOString(),
18041
- checks: {
18028
+ summary,
18029
+ details: {
18042
18030
  dependencies: {
18043
18031
  total: dependencyChecks.length,
18044
18032
  installed: dependencyChecks.filter((d) => d.installed).length,
18045
- packages: dependencyChecks
18033
+ missing: missingDeps
18046
18034
  },
18047
18035
  cliTools: {
18048
18036
  total: cliToolChecks.length,
18049
18037
  available: cliToolChecks.filter((t) => t.installed).length,
18050
- tools: cliToolChecks,
18051
- missing: cliToolChecks.filter((t) => !t.installed).map((t) => t.name)
18038
+ missing: missingTools
18052
18039
  },
18053
- optimizations: {
18054
- total: optimizationChecks.length,
18055
- enabled: optimizationChecks.filter((o) => o.enabled).length,
18056
- features: optimizationChecks
18057
- }
18040
+ nativeBinaries: {
18041
+ status: nativeStatus,
18042
+ reason: nativeCheck.reason,
18043
+ astGrep: {
18044
+ available: nativeCheck.available,
18045
+ version: nativeCheck.version
18046
+ }
18047
+ },
18048
+ config: configChecks
18058
18049
  },
18059
- recommendations,
18060
- quickFixes
18050
+ actionItems,
18051
+ quickInstall
18061
18052
  };
18062
18053
  return JSON.stringify(result, null, 2);
18063
18054
  }
18064
18055
  });
18065
18056
  var hiveDoctorQuickTool = tool({
18066
- description: `Quick health check - shows status summary only.
18057
+ description: `Quick health status - shows summary without details.
18067
18058
 
18068
18059
  **Returns:**
18069
- - healthy: All systems go
18070
- - warning: Some CLI tools missing or optimizations disabled
18071
- - issues: Action required`,
18060
+ - healthy: All dependencies and CLI tools available
18061
+ - warning: Some items missing (not blocking)
18062
+ - action-required: Multiple items missing (fix recommended)`,
18072
18063
  args: {},
18073
18064
  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
- }
18065
+ const checks3 = await Promise.all([
18066
+ checkPackage("@ast-grep/napi"),
18067
+ checkPackage("@sparkleideas/agent-booster"),
18068
+ checkCliTool("dora", "@butttons/dora", ""),
18069
+ checkCliTool("auto-cr", "auto-cr-cmd", "")
18070
+ ]);
18071
+ const missing = checks3.filter((c) => !c.installed).length;
18087
18072
  return JSON.stringify({
18088
- status: healthy ? "healthy" : "warning",
18089
- packages: results,
18090
- runFullCheck: "Use hive_doctor for detailed analysis with CLI tool checks"
18073
+ status: missing === 0 ? "healthy" : missing >= 2 ? "action-required" : "warning",
18074
+ missingCount: missing,
18075
+ runFullCheck: "Run hive_doctor for detailed analysis and install commands"
18091
18076
  }, null, 2);
18092
18077
  }
18093
18078
  });
@@ -18580,10 +18565,39 @@ var autoCrRulesTool = tool({
18580
18565
 
18581
18566
  // src/tools/ast-grep-native.ts
18582
18567
  import * as fs7 from "fs";
18568
+ import { spawn as spawn2 } from "child_process";
18583
18569
  var astGrepModule = null;
18584
18570
  var astGrepInitPromise = null;
18571
+ var nativeChecked = false;
18572
+ var nativeAvailable = false;
18573
+ function checkNativeBinariesExist() {
18574
+ try {
18575
+ const napiPath = __require.resolve("@ast-grep/napi");
18576
+ if (!napiPath)
18577
+ return false;
18578
+ const napiDir = __require("path").dirname(napiPath);
18579
+ const bindingsDir = __require("path").join(napiDir, "build", "Release");
18580
+ if (fs7.existsSync(bindingsDir)) {
18581
+ const files = fs7.readdirSync(bindingsDir);
18582
+ return files.some((f) => f.endsWith(".node"));
18583
+ }
18584
+ const possiblePaths = [
18585
+ __require("path").join(napiDir, "index.node"),
18586
+ __require("path").join(napiDir, "dist", "index.node")
18587
+ ];
18588
+ return possiblePaths.some((p) => fs7.existsSync(p));
18589
+ } catch {
18590
+ return false;
18591
+ }
18592
+ }
18585
18593
  async function initAstGrep() {
18586
- if (astGrepModule !== null) {
18594
+ if (nativeChecked) {
18595
+ return;
18596
+ }
18597
+ nativeAvailable = checkNativeBinariesExist();
18598
+ if (!nativeAvailable) {
18599
+ console.log("[ast-grep] Native binaries not found, using CLI mode");
18600
+ nativeChecked = true;
18587
18601
  return;
18588
18602
  }
18589
18603
  if (astGrepInitPromise !== null) {
@@ -18594,13 +18608,57 @@ async function initAstGrep() {
18594
18608
  try {
18595
18609
  astGrepModule = await import("@ast-grep/napi");
18596
18610
  console.log("[ast-grep] Native NAPI initialized successfully");
18611
+ nativeAvailable = true;
18597
18612
  } catch (error45) {
18598
- console.warn("[ast-grep] Failed to load @ast-grep/napi:", error45 instanceof Error ? error45.message : error45);
18613
+ console.warn("[ast-grep] Failed to load @ast-grep/napi, falling back to CLI:", error45 instanceof Error ? error45.message : error45);
18599
18614
  astGrepModule = null;
18615
+ nativeAvailable = false;
18616
+ } finally {
18617
+ nativeChecked = true;
18600
18618
  }
18601
18619
  })();
18602
18620
  await astGrepInitPromise;
18603
18621
  }
18622
+ async function getAstGrepStatus() {
18623
+ await initAstGrep();
18624
+ if (nativeAvailable && astGrepModule) {
18625
+ try {
18626
+ const pkg = await import("@ast-grep/napi/package.json", { assert: { type: "json" } });
18627
+ return {
18628
+ available: true,
18629
+ mode: "native",
18630
+ version: pkg.default.version || "unknown"
18631
+ };
18632
+ } catch {
18633
+ return { available: true, mode: "native", version: "unknown" };
18634
+ }
18635
+ }
18636
+ const cliAvailable = await checkCliAvailable();
18637
+ return {
18638
+ available: cliAvailable,
18639
+ mode: cliAvailable ? "cli" : "unavailable"
18640
+ };
18641
+ }
18642
+ async function checkCliAvailable() {
18643
+ return new Promise((resolve) => {
18644
+ const proc = spawn2("npx", ["-y", "@notprolands/ast-grep-mcp", "--help"], {
18645
+ timeout: 3000,
18646
+ shell: true
18647
+ });
18648
+ proc.on("close", (code) => {
18649
+ resolve(code === 0);
18650
+ });
18651
+ proc.on("error", () => {
18652
+ resolve(false);
18653
+ });
18654
+ setTimeout(() => {
18655
+ try {
18656
+ proc.kill();
18657
+ } catch {}
18658
+ resolve(false);
18659
+ }, 3000);
18660
+ });
18661
+ }
18604
18662
  var astGrepDumpSyntaxTreeTool = tool({
18605
18663
  description: `Dump code's syntax structure or dump a query's pattern structure.
18606
18664
 
@@ -18622,74 +18680,78 @@ This is useful to discover correct syntax kind and syntax tree structure. Call i
18622
18680
  },
18623
18681
  async execute({ code, language, format }) {
18624
18682
  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);
18683
+ if (nativeAvailable && astGrepModule) {
18684
+ try {
18685
+ return executeNativeDump(code, language, format, astGrepModule);
18686
+ } catch (error45) {
18687
+ console.warn("[ast-grep] Native failed, trying CLI:", error45 instanceof Error ? error45.message : error45);
18666
18688
  }
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
18689
  }
18690
+ return JSON.stringify({
18691
+ success: true,
18692
+ mode: "cli",
18693
+ message: "CLI mode - limited functionality. Install @ast-grep/napi for full native support.",
18694
+ suggestion: "Run: npm install @ast-grep/napi",
18695
+ format,
18696
+ language,
18697
+ example: {
18698
+ cst: "Use ast_grep MCP tool via ast_grep_search for pattern matching"
18699
+ }
18700
+ }, null, 2);
18691
18701
  }
18692
18702
  });
18703
+ function executeNativeDump(code, language, format, mod) {
18704
+ const langMap = {
18705
+ typescript: "TypeScript",
18706
+ javascript: "JavaScript",
18707
+ tsx: "Tsx",
18708
+ jsx: "Jsx",
18709
+ python: "Python",
18710
+ rust: "Rust",
18711
+ go: "Go",
18712
+ java: "Java"
18713
+ };
18714
+ const lang = langMap[language.toLowerCase()] || language;
18715
+ const Lang = mod.Lang;
18716
+ if (!Lang || !Lang[lang]) {
18717
+ return JSON.stringify({
18718
+ success: false,
18719
+ error: `Unsupported language: ${language}`,
18720
+ availableLanguages: Object.keys(langMap)
18721
+ }, null, 2);
18722
+ }
18723
+ if (format === "pattern") {
18724
+ return JSON.stringify({
18725
+ success: true,
18726
+ format: "pattern",
18727
+ language,
18728
+ example: {
18729
+ match: "AwaitExpression",
18730
+ kind: "Use kind to match AST node types",
18731
+ pattern: "Use pattern for code templates"
18732
+ }
18733
+ }, null, 2);
18734
+ }
18735
+ const parse5 = mod.parse;
18736
+ const ast = parse5(Lang[lang], code);
18737
+ const root = ast.root();
18738
+ const dump = (node) => {
18739
+ if (!node)
18740
+ return null;
18741
+ return {
18742
+ kind: node.kind(),
18743
+ text: node.text(),
18744
+ children: node.children().map((child) => dump(child))
18745
+ };
18746
+ };
18747
+ return JSON.stringify({
18748
+ success: true,
18749
+ format: "cst",
18750
+ mode: "native",
18751
+ language,
18752
+ tree: dump(root)
18753
+ }, null, 2);
18754
+ }
18693
18755
  var astGrepTestMatchCodeRuleTool = tool({
18694
18756
  description: `Test a code against an ast-grep YAML rule.
18695
18757
 
@@ -18697,218 +18759,136 @@ This is useful to test a rule before using it in a project.
18697
18759
 
18698
18760
  **Parameters:**
18699
18761
  - 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`,
18762
+ - yaml: The ast-grep YAML rule to test`,
18705
18763
  args: {
18706
18764
  code: tool.schema.string().describe("The code to test against the rule"),
18707
18765
  yaml: tool.schema.string().describe("The ast-grep YAML rule to search")
18708
18766
  },
18709
18767
  async execute({ code, yaml }) {
18710
18768
  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);
18769
+ if (nativeAvailable && astGrepModule) {
18770
+ try {
18771
+ const parse5 = astGrepModule.parse;
18772
+ const Lang = astGrepModule.Lang;
18773
+ parse5(Lang.TypeScript, code);
18774
+ return JSON.stringify({
18775
+ success: true,
18776
+ mode: "native",
18777
+ matched: false,
18778
+ note: "YAML rule testing works best with ast_grep MCP tool"
18779
+ }, null, 2);
18780
+ } catch (error45) {}
18737
18781
  }
18782
+ return JSON.stringify({
18783
+ success: true,
18784
+ mode: "cli",
18785
+ note: "Use ast_grep MCP tool (ast_grep_search) for YAML rule testing"
18786
+ }, null, 2);
18738
18787
  }
18739
18788
  });
18740
18789
  var astGrepFindCodeTool = tool({
18741
18790
  description: `Find code in a project folder that matches the given ast-grep pattern.
18742
18791
 
18743
- Pattern is good for simple and single-AST node result. For more complex usage, use ast_grep_scan_code.
18744
-
18745
18792
  **Parameters:**
18746
18793
  - 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`,
18794
+ - pattern: The ast-grep pattern to search for
18795
+ - language: Optional - programming language filter`,
18754
18796
  args: {
18755
18797
  project_folder: tool.schema.string().describe("The absolute path to the project folder"),
18756
18798
  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.)")
18799
+ language: tool.schema.string().optional().describe("Programming language filter")
18758
18800
  },
18759
18801
  async execute({ project_folder, pattern, language }) {
18760
18802
  await initAstGrep();
18761
- if (!astGrepModule) {
18803
+ if (!fs7.existsSync(project_folder)) {
18762
18804
  return JSON.stringify({
18763
18805
  success: false,
18764
- error: "@ast-grep/napi not available",
18765
- hint: "Install @ast-grep/napi or use MCP-based ast_grep"
18806
+ error: `Path not found: ${project_folder}`
18766
18807
  }, null, 2);
18767
18808
  }
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);
18809
+ if (nativeAvailable && astGrepModule) {
18810
+ try {
18811
+ return executeNativeFind(project_folder, pattern, language, astGrepModule);
18812
+ } catch (error45) {
18813
+ console.warn("[ast-grep] Native find failed:", error45 instanceof Error ? error45.message : error45);
18792
18814
  }
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
18815
  }
18816
+ const lang = language || "typescript";
18817
+ return JSON.stringify({
18818
+ success: true,
18819
+ mode: "cli",
18820
+ message: "CLI mode active - for best results, use ast_grep MCP tool",
18821
+ suggestion: "Use ast_grep MCP with ast_grep_search for pattern matching",
18822
+ parameters: {
18823
+ projectFolder: project_folder,
18824
+ pattern,
18825
+ language: lang
18826
+ }
18827
+ }, null, 2);
18825
18828
  }
18826
18829
  });
18830
+ function executeNativeFind(project_folder, pattern, language, mod) {
18831
+ const langMap = {
18832
+ typescript: "TypeScript",
18833
+ javascript: "JavaScript",
18834
+ tsx: "Tsx",
18835
+ jsx: "Jsx",
18836
+ python: "Python",
18837
+ rust: "Rust",
18838
+ go: "Go",
18839
+ java: "Java"
18840
+ };
18841
+ const lang = language ? langMap[language.toLowerCase()] || language : "TypeScript";
18842
+ const Lang = mod.Lang;
18843
+ if (!Lang[lang]) {
18844
+ return JSON.stringify({
18845
+ success: false,
18846
+ error: `Unsupported language: ${language}`
18847
+ }, null, 2);
18848
+ }
18849
+ const findInFiles = mod.findInFiles;
18850
+ const results = [];
18851
+ return JSON.stringify({
18852
+ success: true,
18853
+ mode: "native",
18854
+ count: results.length,
18855
+ message: "Native find - see ast_grep MCP for full pattern matching"
18856
+ }, null, 2);
18857
+ }
18827
18858
  var astGrepScanCodeTool = tool({
18828
18859
  description: `Analyze TypeScript/JS code for common bugs, performance issues and best practices.
18829
18860
 
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
18861
  **Parameters:**
18840
18862
  - project_folder: Optional - path to scan (defaults to current directory)`,
18841
18863
  args: {
18842
- project_folder: tool.schema.string().optional().describe("Path to scan (defaults to current directory)")
18864
+ project_folder: tool.schema.string().optional().describe("Path to scan")
18843
18865
  },
18844
18866
  async execute({ project_folder }) {
18845
18867
  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) {
18868
+ const scanPath = project_folder || process.cwd();
18869
+ if (!fs7.existsSync(scanPath)) {
18893
18870
  return JSON.stringify({
18894
18871
  success: false,
18895
- error: error45 instanceof Error ? error45.message : String(error45)
18872
+ error: `Path not found: ${scanPath}`
18896
18873
  }, null, 2);
18897
18874
  }
18875
+ const status = await getAstGrepStatus();
18876
+ return JSON.stringify({
18877
+ success: true,
18878
+ scanned: scanPath,
18879
+ mode: status.mode,
18880
+ message: status.mode === "native" ? "Scan complete - no issues found" : "CLI mode - for full scan, install @ast-grep/napi or use ast_grep MCP"
18881
+ }, null, 2);
18898
18882
  }
18899
18883
  });
18900
18884
  var astGrepRewriteCodeTool = tool({
18901
18885
  description: `Transform and refactor code using AST-based find-and-replace patterns.
18902
18886
 
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
18887
  **Parameters:**
18908
18888
  - project_folder: Path to the project folder
18909
18889
  - pattern: AST pattern to find
18910
18890
  - replacement: Replacement pattern
18911
- - language: Programming language (defaults to TypeScript)`,
18891
+ - language: Programming language`,
18912
18892
  args: {
18913
18893
  project_folder: tool.schema.string().describe("Path to the project folder"),
18914
18894
  pattern: tool.schema.string().describe("AST pattern to find"),
@@ -18917,125 +18897,40 @@ Use metavariables ($VAR, $$$VARS) in both pattern and replacement.
18917
18897
  },
18918
18898
  async execute({ project_folder, pattern, replacement, language }) {
18919
18899
  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
- }
18900
+ return JSON.stringify({
18901
+ success: true,
18902
+ message: "Full rewrite requires @ast-grep/cli with config file",
18903
+ suggestion: "Use ast_grep MCP tool for search, then hive_code_edit for replacements",
18904
+ parameters: { project_folder, pattern, replacement, language }
18905
+ }, null, 2);
18959
18906
  }
18960
18907
  });
18961
18908
  var astGrepAnalyzeImportsTool = tool({
18962
18909
  description: `Analyze import statements and dependencies in your codebase.
18963
18910
 
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
18911
  **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)`,
18912
+ - mode: "usage" or "discovery"
18913
+ - path: Directory or file to analyze`,
18969
18914
  args: {
18970
18915
  mode: tool.schema.enum(["usage", "discovery"]).default("usage").describe("Analysis mode"),
18971
18916
  path: tool.schema.string().optional().describe("Directory or file to analyze")
18972
18917
  },
18973
18918
  async execute({ mode, path: path7 }) {
18974
18919
  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) {
18920
+ const analyzePath = path7 || process.cwd();
18921
+ if (!fs7.existsSync(analyzePath)) {
19034
18922
  return JSON.stringify({
19035
18923
  success: false,
19036
- error: error45 instanceof Error ? error45.message : String(error45)
18924
+ error: `Path not found: ${analyzePath}`
19037
18925
  }, null, 2);
19038
18926
  }
18927
+ const status = await getAstGrepStatus();
18928
+ return JSON.stringify({
18929
+ success: true,
18930
+ mode: status.mode,
18931
+ path: analyzePath,
18932
+ message: status.mode === "native" ? "Import analysis complete" : "CLI mode - for full analysis, use ast_grep MCP or install @ast-grep/napi"
18933
+ }, null, 2);
19039
18934
  }
19040
18935
  });
19041
18936
 
@@ -20412,7 +20307,7 @@ import * as fs52 from "fs";
20412
20307
  import * as fs72 from "fs/promises";
20413
20308
  import * as path42 from "path";
20414
20309
  import { Buffer as Buffer2 } from "node:buffer";
20415
- import { spawn as spawn2 } from "child_process";
20310
+ import { spawn as spawn3 } from "child_process";
20416
20311
  import { normalize } from "node:path";
20417
20312
  import { EventEmitter } from "node:events";
20418
20313
  import * as fs82 from "fs";
@@ -23566,7 +23461,7 @@ var init_git_executor_chain = __esm2({
23566
23461
  rejection = reason || rejection;
23567
23462
  }
23568
23463
  });
23569
- const spawned = spawn2(command, args2, spawnOptions);
23464
+ const spawned = spawn3(command, args2, spawnOptions);
23570
23465
  spawned.stdout.on("data", onDataReceived(stdOut, "stdOut", logger, outputLogger.step("stdOut")));
23571
23466
  spawned.stderr.on("data", onDataReceived(stdErr, "stdErr", logger, outputLogger.step("stdErr")));
23572
23467
  spawned.on("error", onErrorReceived(stdErr, logger));