@vibgrate/cli 1.0.77 → 1.0.79

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.
Files changed (3) hide show
  1. package/dist/cli.js +158 -19
  2. package/dist/hcs-worker.js +394205 -0
  3. package/package.json +6 -5
package/dist/cli.js CHANGED
@@ -554,19 +554,23 @@ function validateFactLine(line) {
554
554
  return { valid: true, fact: envelope };
555
555
  }
556
556
  function resolveHcsWorkerBin() {
557
+ const base = import.meta.dirname ?? path6.dirname(new URL(import.meta.url).pathname);
558
+ const bundledPath = path6.resolve(base, "..", "dist", "hcs-worker.js");
559
+ if (existsSync(bundledPath)) return bundledPath;
560
+ const siblingPath = path6.resolve(base, "hcs-worker.js");
561
+ if (existsSync(siblingPath)) return siblingPath;
557
562
  try {
558
563
  const resolved = import.meta.resolve("@vibgrate/hcs-node-worker");
559
564
  const resolvedPath = resolved.startsWith("file://") ? new URL(resolved).pathname : resolved;
560
565
  if (existsSync(resolvedPath)) return resolvedPath;
561
566
  } catch {
562
567
  }
563
- const base = import.meta.dirname ?? path6.dirname(new URL(import.meta.url).pathname);
564
568
  const monorepoPath = path6.resolve(base, "..", "..", "..", "vibgrate-hcs", "node", "dist", "main.js");
565
569
  if (existsSync(monorepoPath)) return monorepoPath;
566
570
  const devPath = path6.resolve(base, "..", "..", "..", "vibgrate-hcs", "node", "src", "main.ts");
567
571
  if (existsSync(devPath)) return devPath;
568
572
  throw new Error(
569
- 'Cannot locate @vibgrate/hcs-node-worker. Run "pnpm build" in packages/vibgrate-hcs/node or install @vibgrate/hcs-node-worker.'
573
+ 'Cannot locate HCS worker. Run "pnpm build" in the CLI package to bundle the worker into dist/.'
570
574
  );
571
575
  }
572
576
  var NODE_WORKER_AST_LANGS = /* @__PURE__ */ new Set(["typescript", "javascript"]);
@@ -584,7 +588,8 @@ var NODE_WORKER_ALL_LANGS = /* @__PURE__ */ new Set([
584
588
  ...NODE_WORKER_AST_LANGS,
585
589
  ...NODE_WORKER_TEXT_LANGS
586
590
  ]);
587
- var EXTERNAL_WORKER_LANGS = /* @__PURE__ */ new Set(["go", "python", "java", "csharp"]);
591
+ var NATIVE_AST_LANGS = /* @__PURE__ */ new Set(["go", "python", "java", "csharp"]);
592
+ var ALL_WORKER_LANGS = /* @__PURE__ */ new Set([...NODE_WORKER_ALL_LANGS, ...NATIVE_AST_LANGS]);
588
593
  async function runNodeWorker(rootDir, language, opts) {
589
594
  const workerBin = resolveHcsWorkerBin();
590
595
  const args = [];
@@ -661,6 +666,145 @@ async function runNodeWorker(rootDir, language, opts) {
661
666
  });
662
667
  });
663
668
  }
669
+ function resolveNativeWorker(language, projectDir) {
670
+ const base = import.meta.dirname ?? path6.dirname(new URL(import.meta.url).pathname);
671
+ const hcsFromBundle = path6.resolve(base, "..", "..", "vibgrate-hcs");
672
+ const hcsFromSrc = path6.resolve(base, "..", "..", "..", "vibgrate-hcs");
673
+ const hcsRoot = existsSync(hcsFromBundle) ? hcsFromBundle : hcsFromSrc;
674
+ const workersDir = path6.resolve(base, "workers");
675
+ switch (language) {
676
+ case "go": {
677
+ const bin = path6.join(workersDir, process.platform === "win32" ? "vibgrate-hcs-go.exe" : "vibgrate-hcs-go");
678
+ if (existsSync(bin)) {
679
+ return { cmd: bin, args: ["--project", projectDir, "--output", "ndjson"] };
680
+ }
681
+ const src = path6.join(hcsRoot, "go");
682
+ if (existsSync(path6.join(src, "main.go"))) {
683
+ return { cmd: "go", args: ["run", ".", "--project", projectDir, "--output", "ndjson"], cwd: src };
684
+ }
685
+ return null;
686
+ }
687
+ case "python": {
688
+ const bin = path6.join(workersDir, "vibgrate-hcs-python");
689
+ if (existsSync(bin)) {
690
+ return { cmd: bin, args: ["--project", projectDir, "--output", "ndjson"] };
691
+ }
692
+ const src = path6.join(hcsRoot, "python");
693
+ if (existsSync(path6.join(src, "pyproject.toml"))) {
694
+ return {
695
+ cmd: "python3",
696
+ args: ["-m", "vibgrate_hcs_python.main", "--project", projectDir, "--output", "ndjson"],
697
+ cwd: src
698
+ };
699
+ }
700
+ return null;
701
+ }
702
+ case "java": {
703
+ const jar = path6.join(workersDir, "vibgrate-hcs-jvm.jar");
704
+ if (existsSync(jar)) {
705
+ return { cmd: "java", args: ["-jar", jar, "--project", projectDir, "--output", "ndjson"] };
706
+ }
707
+ const src = path6.join(hcsRoot, "jvm");
708
+ if (existsSync(path6.join(src, "build.gradle.kts"))) {
709
+ const gradlew = path6.join(src, process.platform === "win32" ? "gradlew.bat" : "gradlew");
710
+ const launcher = existsSync(gradlew) ? gradlew : "gradle";
711
+ return {
712
+ cmd: launcher,
713
+ args: ["-q", "--console=plain", "run", `--args=--project ${projectDir} --output ndjson`],
714
+ cwd: src
715
+ };
716
+ }
717
+ return null;
718
+ }
719
+ case "csharp": {
720
+ const dll = path6.join(workersDir, "VibgrateHcsWorker.dll");
721
+ if (existsSync(dll)) {
722
+ return { cmd: "dotnet", args: [dll, "--project", projectDir, "--output", "ndjson"] };
723
+ }
724
+ const csproj = path6.join(hcsRoot, "dotnet", "src", "VibgrateHcsWorker", "VibgrateHcsWorker.csproj");
725
+ if (existsSync(csproj)) {
726
+ return {
727
+ cmd: "dotnet",
728
+ args: ["run", "--project", csproj, "--", "--project", projectDir, "--output", "ndjson"]
729
+ };
730
+ }
731
+ return null;
732
+ }
733
+ default:
734
+ return null;
735
+ }
736
+ }
737
+ async function runNativeWorker(rootDir, language, opts) {
738
+ const spec = resolveNativeWorker(language, rootDir);
739
+ if (!spec) {
740
+ return {
741
+ language,
742
+ facts: [],
743
+ errors: [
744
+ `[error] No native worker found for '${language}'. Install the toolchain (${language === "go" ? "Go" : language === "python" ? "Python 3" : language === "java" ? "Java 17+" : "dotnet SDK"}) or build the worker binary.`
745
+ ],
746
+ exitCode: EXIT_PARSE_FAILURE
747
+ };
748
+ }
749
+ return new Promise((resolve6) => {
750
+ const facts = [];
751
+ const errors = [];
752
+ let stdoutBuf = "";
753
+ let killed = false;
754
+ if (opts.verbose) {
755
+ process.stderr.write(chalk5.dim(`[${language}] Spawning: ${spec.cmd} ${spec.args.join(" ")}
756
+ `));
757
+ }
758
+ const child = spawn(spec.cmd, spec.args, {
759
+ cwd: spec.cwd ?? rootDir,
760
+ stdio: ["ignore", "pipe", "pipe"]
761
+ });
762
+ const timer = setTimeout(() => {
763
+ killed = true;
764
+ child.kill("SIGKILL");
765
+ }, opts.timeoutMs);
766
+ child.stdout.on("data", (chunk) => {
767
+ stdoutBuf += chunk.toString();
768
+ const lines = stdoutBuf.split("\n");
769
+ stdoutBuf = lines.pop();
770
+ for (const line of lines) {
771
+ const trimmed = line.trim();
772
+ if (trimmed) facts.push(trimmed);
773
+ }
774
+ });
775
+ child.stderr.on("data", (chunk) => {
776
+ const text = chunk.toString();
777
+ for (const line of text.split("\n")) {
778
+ const trimmed = line.trim();
779
+ if (!trimmed) continue;
780
+ if (opts.verbose) {
781
+ process.stderr.write(chalk5.dim(`[${language}] ${trimmed}
782
+ `));
783
+ }
784
+ if (trimmed.startsWith("[error]")) {
785
+ errors.push(trimmed);
786
+ }
787
+ }
788
+ });
789
+ child.on("close", (code) => {
790
+ clearTimeout(timer);
791
+ if (stdoutBuf.trim()) facts.push(stdoutBuf.trim());
792
+ if (killed) {
793
+ resolve6({ language, facts, errors: ["Worker killed: timeout exceeded"], exitCode: EXIT_TIMEOUT });
794
+ } else {
795
+ resolve6({ language, facts, errors, exitCode: code ?? 0 });
796
+ }
797
+ });
798
+ child.on("error", (err) => {
799
+ clearTimeout(timer);
800
+ const isNotFound = err.code === "ENOENT";
801
+ errors.push(
802
+ isNotFound ? `[error] '${spec.cmd}' not found. Is the required toolchain installed and on PATH?` : `[error] Failed to spawn native worker: ${err.message}`
803
+ );
804
+ resolve6({ language, facts, errors, exitCode: EXIT_PARSE_FAILURE });
805
+ });
806
+ });
807
+ }
664
808
  async function pushFacts(facts, dsn, verbose) {
665
809
  const parsed = parseDsn(dsn);
666
810
  if (!parsed) {
@@ -893,25 +1037,16 @@ var extractCommand = new Command5("extract").description("Analyze source code an
893
1037
  }
894
1038
  }
895
1039
  }
896
- const runnableLanguages = targetLanguages.filter((l) => NODE_WORKER_ALL_LANGS.has(l));
897
- const skippedLanguages = targetLanguages.filter((l) => EXTERNAL_WORKER_LANGS.has(l));
898
- const unknownWorkerLangs = targetLanguages.filter(
899
- (l) => !NODE_WORKER_ALL_LANGS.has(l) && !EXTERNAL_WORKER_LANGS.has(l)
900
- );
901
- if (skippedLanguages.length > 0 && opts.verbose) {
902
- process.stderr.write(chalk5.yellow(
903
- `Skipping languages without built-in HCS worker: ${skippedLanguages.join(", ")}
904
- ` + chalk5.dim("These require dedicated external workers.\n")
1040
+ const runnableLanguages = targetLanguages.filter((l) => ALL_WORKER_LANGS.has(l));
1041
+ const unknownWorkerLangs = targetLanguages.filter((l) => !ALL_WORKER_LANGS.has(l));
1042
+ if (unknownWorkerLangs.length > 0 && opts.verbose) {
1043
+ process.stderr.write(chalk5.dim(
1044
+ `No worker registered for: ${unknownWorkerLangs.join(", ")} \u2014 skipping.
1045
+ `
905
1046
  ));
906
1047
  }
907
1048
  if (runnableLanguages.length === 0) {
908
1049
  process.stderr.write(chalk5.yellow("No languages with available HCS workers found.\n"));
909
- if (skippedLanguages.length > 0) {
910
- process.stderr.write(chalk5.dim(
911
- `Detected: ${skippedLanguages.join(", ")} \u2014 these require external workers not yet integrated.
912
- `
913
- ));
914
- }
915
1050
  process.exit(EXIT_SUCCESS);
916
1051
  }
917
1052
  const startTime = Date.now();
@@ -935,11 +1070,15 @@ var extractCommand = new Command5("extract").description("Analyze source code an
935
1070
  hasTimeout = true;
936
1071
  return;
937
1072
  }
938
- const result = await runNodeWorker(rootDir, language, {
1073
+ const result = NODE_WORKER_ALL_LANGS.has(language) ? await runNodeWorker(rootDir, language, {
939
1074
  includeTests: opts.includeTests ?? false,
940
1075
  verbose: opts.verbose ?? false,
941
1076
  timeoutMs: remaining,
942
1077
  onProgress: (event) => progress.onProgress(language, event)
1078
+ }) : await runNativeWorker(rootDir, language, {
1079
+ verbose: opts.verbose ?? false,
1080
+ timeoutMs: remaining,
1081
+ onProgress: (event) => progress.onProgress(language, event)
943
1082
  });
944
1083
  if (result.exitCode === EXIT_TIMEOUT) {
945
1084
  hasTimeout = true;