debug-that 0.4.0 → 0.5.0

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/main.js CHANGED
@@ -1,6 +1,21 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
+ var __create = Object.create;
4
+ var __getProtoOf = Object.getPrototypeOf;
3
5
  var __defProp = Object.defineProperty;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __toESM = (mod, isNodeMode, target) => {
9
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
10
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
11
+ for (let key of __getOwnPropNames(mod))
12
+ if (!__hasOwnProp.call(to, key))
13
+ __defProp(to, key, {
14
+ get: () => mod[key],
15
+ enumerable: true
16
+ });
17
+ return to;
18
+ };
4
19
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
5
20
  var __export = (target, all) => {
6
21
  for (var name in all)
@@ -16827,6 +16842,196 @@ var init_session = __esm(() => {
16827
16842
  };
16828
16843
  });
16829
16844
 
16845
+ // src/dap/adapters/java/adapter-sources.tar.gz
16846
+ var require_adapter_sources_tar = __commonJS((exports, module) => {
16847
+ module.exports = "./adapter-sources.tar-cnge9g7b.gz";
16848
+ });
16849
+
16850
+ // src/dap/adapters/java.ts
16851
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
16852
+ import { delimiter, join as join2 } from "path";
16853
+ var {$ } = globalThis.Bun;
16854
+ function getJavaAdapterDir() {
16855
+ return join2(getManagedAdaptersDir(), "java");
16856
+ }
16857
+ function isJavaAdapterInstalled() {
16858
+ const dir = getJavaAdapterDir();
16859
+ const depsDir = join2(dir, "deps");
16860
+ if (!existsSync2(join2(dir, "classes", "com", "debugthat", "adapter", "Main.class"))) {
16861
+ return false;
16862
+ }
16863
+ return JAVA_DEP_NAMES.every((jar) => existsSync2(join2(depsDir, jar)));
16864
+ }
16865
+ function getJavaAdapterClasspath() {
16866
+ const dir = getJavaAdapterDir();
16867
+ const depsDir = join2(dir, "deps");
16868
+ const classesDir = join2(dir, "classes");
16869
+ const jars = JAVA_DEP_NAMES.map((jar) => join2(depsDir, jar));
16870
+ return [classesDir, ...jars].join(delimiter);
16871
+ }
16872
+ async function extractAdapterSources(installDir) {
16873
+ const devPackageDir = join2(import.meta.dir, "java", "com", "debugthat", "adapter");
16874
+ if (existsSync2(devPackageDir)) {
16875
+ return Array.from(new Bun.Glob("*.java").scanSync(devPackageDir)).map((f) => join2(devPackageDir, f));
16876
+ }
16877
+ const { default: tarballPath } = await Promise.resolve().then(() => __toESM(require_adapter_sources_tar(), 1));
16878
+ const resolved = tarballPath.startsWith("/") ? tarballPath : join2(import.meta.dir, tarballPath);
16879
+ const srcDir = join2(installDir, "src");
16880
+ mkdirSync2(srcDir, { recursive: true });
16881
+ await $`tar xzf ${resolved} -C ${srcDir}`;
16882
+ const packageDir = join2(srcDir, "com", "debugthat", "adapter");
16883
+ return Array.from(new Bun.Glob("*.java").scanSync(packageDir)).map((f) => join2(packageDir, f));
16884
+ }
16885
+ var MAVEN_CENTRAL = "https://repo1.maven.org/maven2", JAVA_DEPS, JAVA_DEP_NAMES, javaInstaller;
16886
+ var init_java = __esm(() => {
16887
+ init_session2();
16888
+ JAVA_DEPS = {
16889
+ "com.microsoft.java.debug.core-0.53.0.jar": "com/microsoft/java/com.microsoft.java.debug.core/0.53.0/com.microsoft.java.debug.core-0.53.0.jar",
16890
+ "commons-lang3-3.14.0.jar": "org/apache/commons/commons-lang3/3.14.0/commons-lang3-3.14.0.jar",
16891
+ "gson-2.10.1.jar": "com/google/code/gson/gson/2.10.1/gson-2.10.1.jar",
16892
+ "rxjava-2.2.21.jar": "io/reactivex/rxjava2/rxjava/2.2.21/rxjava-2.2.21.jar",
16893
+ "reactive-streams-1.0.4.jar": "org/reactivestreams/reactive-streams/1.0.4/reactive-streams-1.0.4.jar",
16894
+ "commons-io-2.15.1.jar": "commons-io/commons-io/2.15.1/commons-io-2.15.1.jar"
16895
+ };
16896
+ JAVA_DEP_NAMES = Object.keys(JAVA_DEPS);
16897
+ javaInstaller = {
16898
+ name: "java (java-debug.core)",
16899
+ isInstalled: isJavaAdapterInstalled,
16900
+ async install(log) {
16901
+ const javaVersionResult = await $`java -version`.quiet().nothrow();
16902
+ const stderr = javaVersionResult.stderr.toString().trim();
16903
+ const versionMatch = stderr.match(/version "(\d+)/);
16904
+ const version2 = versionMatch?.[1] ? parseInt(versionMatch[1], 10) : 0;
16905
+ if (version2 < 11) {
16906
+ throw new Error(`Java 11+ required (found: ${stderr.split(`
16907
+ `)[0]?.trim() ?? "none"})`);
16908
+ }
16909
+ const dir = getJavaAdapterDir();
16910
+ const depsDir = join2(dir, "deps");
16911
+ mkdirSync2(depsDir, { recursive: true });
16912
+ for (const [jarName, mavenPath] of Object.entries(JAVA_DEPS)) {
16913
+ const jarPath = join2(depsDir, jarName);
16914
+ if (!existsSync2(jarPath)) {
16915
+ log(` Downloading ${jarName}...`);
16916
+ const response = await fetch(`${MAVEN_CENTRAL}/${mavenPath}`, {
16917
+ redirect: "follow"
16918
+ });
16919
+ if (!response.ok) {
16920
+ throw new Error(`Failed to download ${jarName}: HTTP ${response.status}`);
16921
+ }
16922
+ await Bun.write(jarPath, response);
16923
+ }
16924
+ }
16925
+ log(" Compiling adapter...");
16926
+ const cp = JAVA_DEP_NAMES.map((jar) => join2(depsDir, jar)).join(delimiter);
16927
+ const classesDir = join2(dir, "classes");
16928
+ mkdirSync2(classesDir, { recursive: true });
16929
+ const sourceFiles = await extractAdapterSources(dir);
16930
+ await $`javac -d ${classesDir} -cp ${cp} -source 11 -target 11 ${sourceFiles}`;
16931
+ log(" Adapter compiled.");
16932
+ }
16933
+ };
16934
+ });
16935
+
16936
+ // src/dap/adapters/lldb.ts
16937
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3 } from "fs";
16938
+ import { join as join3 } from "path";
16939
+ var {$: $2 } = globalThis.Bun;
16940
+ function getLlvmDownloadUrl(version2, os, arch) {
16941
+ const platforms = {
16942
+ darwin: {
16943
+ arm64: `LLVM-${version2}-macOS-ARM64.tar.xz`,
16944
+ x64: `LLVM-${version2}-macOS-X64.tar.xz`
16945
+ },
16946
+ linux: {
16947
+ x64: `LLVM-${version2}-Linux-X64.tar.xz`,
16948
+ arm64: `LLVM-${version2}-Linux-AArch64.tar.xz`
16949
+ }
16950
+ };
16951
+ const filename = platforms[os]?.[arch];
16952
+ if (!filename)
16953
+ return null;
16954
+ return `https://github.com/llvm/llvm-project/releases/download/llvmorg-${version2}/${filename}`;
16955
+ }
16956
+ function getTargetPath() {
16957
+ return join3(getManagedAdaptersDir(), "lldb-dap");
16958
+ }
16959
+ var LLVM_VERSION = "19.1.7", lldbInstaller;
16960
+ var init_lldb = __esm(() => {
16961
+ init_session2();
16962
+ lldbInstaller = {
16963
+ name: "lldb-dap",
16964
+ isInstalled() {
16965
+ return existsSync3(getTargetPath());
16966
+ },
16967
+ async install(log) {
16968
+ const os = process.platform;
16969
+ const arch = process.arch;
16970
+ const url2 = getLlvmDownloadUrl(LLVM_VERSION, os, arch);
16971
+ if (!url2) {
16972
+ throw new Error(`Unsupported platform: ${os}-${arch}
16973
+ Supported: darwin-arm64, darwin-x64, linux-x64, linux-arm64`);
16974
+ }
16975
+ const adaptersDir = getManagedAdaptersDir();
16976
+ const targetPath = getTargetPath();
16977
+ log(`Downloading LLVM ${LLVM_VERSION} for ${os}-${arch}...`);
16978
+ const response = await fetch(url2, { redirect: "follow" });
16979
+ if (!response.ok) {
16980
+ throw new Error(`Download failed: HTTP ${response.status}
16981
+ -> Check your internet connection or try again later`);
16982
+ }
16983
+ const tarball = await response.arrayBuffer();
16984
+ log(`Downloaded ${(tarball.byteLength / 1024 / 1024).toFixed(1)} MB`);
16985
+ mkdirSync3(adaptersDir, { recursive: true });
16986
+ const tmpTar = join3(adaptersDir, "llvm-download.tar.xz");
16987
+ await Bun.write(tmpTar, tarball);
16988
+ try {
16989
+ log("Extracting lldb-dap...");
16990
+ const files = (await $2`tar -tf ${tmpTar}`.text()).split(`
16991
+ `);
16992
+ const lldbDapEntry = files.find((f) => f.endsWith("/bin/lldb-dap") || f === "bin/lldb-dap");
16993
+ if (!lldbDapEntry) {
16994
+ throw new Error(`Could not find lldb-dap in the LLVM archive (${files.length} entries)
16995
+ -> Try installing manually: brew install llvm`);
16996
+ }
16997
+ const stripComponents = String(lldbDapEntry.split("/").length - 1);
16998
+ await $2`tar -xf ${tmpTar} -C ${adaptersDir} --strip-components ${stripComponents} ${lldbDapEntry}`;
16999
+ const liblldbEntries = files.filter((f) => f.includes("liblldb") && (f.endsWith(".so") || f.endsWith(".dylib")));
17000
+ for (const libEntry of liblldbEntries) {
17001
+ const libStrip = String(libEntry.split("/").length - 1);
17002
+ await $2`tar -xf ${tmpTar} -C ${adaptersDir} --strip-components ${libStrip} ${libEntry}`.quiet();
17003
+ }
17004
+ } finally {
17005
+ await $2`rm -f ${tmpTar}`.quiet();
17006
+ }
17007
+ await $2`chmod +x ${targetPath}`;
17008
+ if (!existsSync3(targetPath)) {
17009
+ throw new Error(`lldb-dap not found after extraction
17010
+ -> Try installing manually: brew install llvm`);
17011
+ }
17012
+ log(`Installed lldb-dap to ${targetPath}`);
17013
+ }
17014
+ };
17015
+ });
17016
+
17017
+ // src/dap/adapters/index.ts
17018
+ function getAdapterInstaller(name) {
17019
+ return ADAPTERS[name];
17020
+ }
17021
+ function listAdapterNames() {
17022
+ return Object.keys(ADAPTERS);
17023
+ }
17024
+ var ADAPTERS;
17025
+ var init_adapters2 = __esm(() => {
17026
+ init_java();
17027
+ init_lldb();
17028
+ init_java();
17029
+ ADAPTERS = {
17030
+ lldb: lldbInstaller,
17031
+ java: javaInstaller
17032
+ };
17033
+ });
17034
+
16830
17035
  // src/dap/client.ts
16831
17036
  class DapClient {
16832
17037
  proc;
@@ -17024,49 +17229,102 @@ class DapClient {
17024
17229
  var init_client2 = () => {};
17025
17230
 
17026
17231
  // src/dap/session.ts
17027
- import { existsSync as existsSync2 } from "fs";
17028
- import { join as join2 } from "path";
17232
+ import { existsSync as existsSync4 } from "fs";
17233
+ import { join as join4 } from "path";
17029
17234
  function getManagedAdaptersDir() {
17030
17235
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "/tmp";
17031
- return join2(home, ".debug-that", "adapters");
17032
- }
17033
- function resolveAdapterCommand(runtime) {
17034
- switch (runtime) {
17035
- case "lldb":
17036
- case "lldb-dap": {
17037
- const managedPath = join2(getManagedAdaptersDir(), "lldb-dap");
17038
- if (existsSync2(managedPath)) {
17236
+ return join4(home, ".debug-that", "adapters");
17237
+ }
17238
+ function getRuntimeConfig(runtime) {
17239
+ return RUNTIME_CONFIGS[runtime] ?? {
17240
+ resolveCommand: () => [runtime],
17241
+ buildLaunchArgs: DEFAULT_LAUNCH
17242
+ };
17243
+ }
17244
+ var DEFAULT_LAUNCH = (program, programArgs, cwd) => ({
17245
+ program,
17246
+ args: programArgs,
17247
+ cwd
17248
+ }), lldbConfig, debugpyConfig, javaConfig, RUNTIME_CONFIGS, DapSession;
17249
+ var init_session2 = __esm(() => {
17250
+ init_base_session();
17251
+ init_adapters2();
17252
+ init_client2();
17253
+ lldbConfig = {
17254
+ resolveCommand() {
17255
+ const managedPath = join4(getManagedAdaptersDir(), "lldb-dap");
17256
+ if (existsSync4(managedPath))
17039
17257
  return [managedPath];
17040
- }
17041
- const whichResult = Bun.spawnSync(["which", "lldb-dap"]);
17042
- if (whichResult.exitCode === 0) {
17258
+ if (Bun.which("lldb-dap"))
17043
17259
  return ["lldb-dap"];
17044
- }
17045
17260
  const brewPath = "/opt/homebrew/opt/llvm/bin/lldb-dap";
17046
- if (existsSync2(brewPath)) {
17261
+ if (existsSync4(brewPath))
17047
17262
  return [brewPath];
17048
- }
17049
17263
  return ["lldb-dap"];
17050
- }
17051
- case "codelldb":
17052
- return ["codelldb", "--port", "0"];
17053
- case "python":
17054
- case "debugpy": {
17055
- const py3 = Bun.spawnSync(["which", "python3"]);
17056
- const pyBin = py3.exitCode === 0 ? "python3" : "python";
17264
+ },
17265
+ buildLaunchArgs: DEFAULT_LAUNCH
17266
+ };
17267
+ debugpyConfig = {
17268
+ resolveCommand() {
17269
+ const pyBin = Bun.which("python3") ? "python3" : "python";
17057
17270
  return [pyBin, "-m", "debugpy.adapter"];
17271
+ },
17272
+ buildLaunchArgs: (program, programArgs, cwd) => ({
17273
+ program,
17274
+ args: programArgs,
17275
+ cwd,
17276
+ console: "internalConsole",
17277
+ justMyCode: false
17278
+ })
17279
+ };
17280
+ javaConfig = {
17281
+ resolveCommand() {
17282
+ if (!isJavaAdapterInstalled()) {
17283
+ throw new Error("Java debug adapter not installed. Run `dbg install java` first.");
17284
+ }
17285
+ const cp = getJavaAdapterClasspath();
17286
+ return ["java", "-cp", cp, "com.debugthat.adapter.Main"];
17287
+ },
17288
+ buildLaunchArgs(program, programArgs, _cwd) {
17289
+ const basename = program.split("/").pop() ?? program;
17290
+ const mainClass = basename.replace(/\.(java|class)$/, "");
17291
+ const programDir = program.includes("/") ? program.substring(0, program.lastIndexOf("/")) : _cwd;
17292
+ return {
17293
+ mainClass,
17294
+ classPaths: [programDir],
17295
+ cwd: programDir,
17296
+ sourcePaths: [programDir],
17297
+ stopOnEntry: true,
17298
+ ...programArgs.length > 0 ? { args: programArgs.join(" ") } : {}
17299
+ };
17300
+ },
17301
+ parseAttachTarget(target) {
17302
+ const colonIdx = target.lastIndexOf(":");
17303
+ if (colonIdx > 0) {
17304
+ return {
17305
+ hostName: target.substring(0, colonIdx),
17306
+ port: parseInt(target.substring(colonIdx + 1), 10)
17307
+ };
17308
+ }
17309
+ const port = parseInt(target, 10);
17310
+ return { hostName: "localhost", port: Number.isNaN(port) ? 5005 : port };
17058
17311
  }
17059
- default:
17060
- return [runtime];
17061
- }
17062
- }
17063
- var DapSession;
17064
- var init_session2 = __esm(() => {
17065
- init_base_session();
17066
- init_client2();
17312
+ };
17313
+ RUNTIME_CONFIGS = {
17314
+ lldb: lldbConfig,
17315
+ "lldb-dap": lldbConfig,
17316
+ codelldb: {
17317
+ resolveCommand: () => ["codelldb", "--port", "0"],
17318
+ buildLaunchArgs: DEFAULT_LAUNCH
17319
+ },
17320
+ python: debugpyConfig,
17321
+ debugpy: debugpyConfig,
17322
+ java: javaConfig
17323
+ };
17067
17324
  DapSession = class DapSession extends BaseSession {
17068
17325
  dap = null;
17069
17326
  _runtime;
17327
+ _isAttached = false;
17070
17328
  _threadId = 1;
17071
17329
  _stackFrames = [];
17072
17330
  adapterCapabilities = {};
@@ -17109,17 +17367,16 @@ var init_session2 = __esm(() => {
17109
17367
  if (this.state !== "idle") {
17110
17368
  throw new Error("Session already has an active debug target");
17111
17369
  }
17112
- const adapterCmd = resolveAdapterCommand(this._runtime);
17370
+ const config2 = getRuntimeConfig(this._runtime);
17371
+ const adapterCmd = config2.resolveCommand();
17113
17372
  this.dap = DapClient.spawn(adapterCmd);
17114
17373
  this.setupEventHandlers();
17115
17374
  await this.initializeAdapter();
17116
- const program = options.program ?? command[0];
17375
+ const program = options.program ?? command[0] ?? "";
17117
17376
  const programArgs = options.args ?? command.slice(1);
17118
17377
  const launchArgs = {
17119
- program,
17120
- args: programArgs,
17121
17378
  stopOnEntry: options.brk ?? true,
17122
- cwd: process.cwd()
17379
+ ...config2.buildLaunchArgs(program, programArgs, process.cwd())
17123
17380
  };
17124
17381
  if (this._remaps.length > 0) {
17125
17382
  launchArgs.sourceMap = this._remaps.map(([from, to]) => [from, to]);
@@ -17127,10 +17384,6 @@ var init_session2 = __esm(() => {
17127
17384
  if (this._symbolPaths.length > 0) {
17128
17385
  launchArgs.preRunCommands = this._symbolPaths.map((p) => `add-dsym ${p}`);
17129
17386
  }
17130
- if (this._runtime === "python" || this._runtime === "debugpy") {
17131
- launchArgs.console = "internalConsole";
17132
- launchArgs.justMyCode = false;
17133
- }
17134
17387
  const launchPromise = this.dap.send("launch", launchArgs);
17135
17388
  await this.waitForInitialized();
17136
17389
  await this.dap.send("configurationDone");
@@ -17160,12 +17413,19 @@ ${detail}` : "Target exited without stopping (stopOnEntry had no effect)";
17160
17413
  if (this.state !== "idle") {
17161
17414
  throw new Error("Session already has an active debug target");
17162
17415
  }
17163
- const adapterCmd = resolveAdapterCommand(this._runtime);
17416
+ this._isAttached = true;
17417
+ const config2 = getRuntimeConfig(this._runtime);
17418
+ const adapterCmd = config2.resolveCommand();
17164
17419
  this.dap = DapClient.spawn(adapterCmd);
17165
17420
  this.setupEventHandlers();
17166
17421
  await this.initializeAdapter();
17167
- const pid = parseInt(target, 10);
17168
- const attachArgs = Number.isNaN(pid) ? { program: target, waitFor: true } : { pid };
17422
+ let attachArgs;
17423
+ if (config2.parseAttachTarget) {
17424
+ attachArgs = config2.parseAttachTarget(target);
17425
+ } else {
17426
+ const pid = parseInt(target, 10);
17427
+ attachArgs = Number.isNaN(pid) ? { program: target, waitFor: true } : { pid };
17428
+ }
17169
17429
  const attachPromise = this.dap.send("attach", attachArgs);
17170
17430
  await this.waitForInitialized();
17171
17431
  await this.dap.send("configurationDone");
@@ -17190,13 +17450,14 @@ ${detail}` : "Target exited without stopping (stopOnEntry had no effect)";
17190
17450
  async stop() {
17191
17451
  if (this.dap) {
17192
17452
  try {
17193
- await this.dap.send("disconnect", { terminateDebuggee: true });
17453
+ await this.dap.send("disconnect", { terminateDebuggee: !this._isAttached });
17194
17454
  } catch {}
17195
17455
  this.dap.disconnect();
17196
17456
  this.dap = null;
17197
17457
  }
17198
17458
  this.resetState();
17199
17459
  this._stackFrames = [];
17460
+ this._isAttached = false;
17200
17461
  this.breakpoints.clear();
17201
17462
  this.allBreakpoints = [];
17202
17463
  this.functionBreakpoints = [];
@@ -17930,7 +18191,7 @@ var DAP_RUNTIMES;
17930
18191
  var init_factory = __esm(() => {
17931
18192
  init_session();
17932
18193
  init_session2();
17933
- DAP_RUNTIMES = new Set(["lldb", "lldb-dap", "codelldb", "python", "debugpy"]);
18194
+ DAP_RUNTIMES = new Set(["lldb", "lldb-dap", "codelldb", "python", "debugpy", "java"]);
17934
18195
  });
17935
18196
 
17936
18197
  // src/daemon/eval-suggestions.ts
@@ -17979,7 +18240,7 @@ function extractLines(buffer) {
17979
18240
  }
17980
18241
 
17981
18242
  // src/daemon/server.ts
17982
- import { existsSync as existsSync3, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
18243
+ import { existsSync as existsSync5, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
17983
18244
 
17984
18245
  class DaemonServer {
17985
18246
  session;
@@ -18002,14 +18263,14 @@ class DaemonServer {
18002
18263
  }
18003
18264
  async start() {
18004
18265
  ensureSocketDir();
18005
- if (existsSync3(this.lockPath)) {
18266
+ if (existsSync5(this.lockPath)) {
18006
18267
  const existingPid = parseInt(await Bun.file(this.lockPath).text(), 10);
18007
18268
  if (!Number.isNaN(existingPid) && isProcessRunning(existingPid)) {
18008
18269
  throw new Error(`Daemon already running for session "${this.session}" (pid ${existingPid})`);
18009
18270
  }
18010
18271
  unlinkSync(this.lockPath);
18011
18272
  }
18012
- if (existsSync3(this.socketPath)) {
18273
+ if (existsSync5(this.socketPath)) {
18013
18274
  unlinkSync(this.socketPath);
18014
18275
  }
18015
18276
  writeFileSync3(this.lockPath, String(process.pid));
@@ -18135,10 +18396,10 @@ class DaemonServer {
18135
18396
  this.listener.stop(true);
18136
18397
  this.listener = null;
18137
18398
  }
18138
- if (existsSync3(this.socketPath)) {
18399
+ if (existsSync5(this.socketPath)) {
18139
18400
  unlinkSync(this.socketPath);
18140
18401
  }
18141
- if (existsSync3(this.lockPath)) {
18402
+ if (existsSync5(this.lockPath)) {
18142
18403
  unlinkSync(this.lockPath);
18143
18404
  }
18144
18405
  }
@@ -20883,7 +21144,7 @@ var init_command = __esm(() => {
20883
21144
  });
20884
21145
 
20885
21146
  // src/daemon/client.ts
20886
- import { existsSync as existsSync4, readdirSync, readFileSync, unlinkSync as unlinkSync2 } from "fs";
21147
+ import { existsSync as existsSync6, readdirSync, readFileSync, unlinkSync as unlinkSync2 } from "fs";
20887
21148
 
20888
21149
  class DaemonClient {
20889
21150
  session;
@@ -20963,11 +21224,11 @@ class DaemonClient {
20963
21224
  }
20964
21225
  static isRunning(session2) {
20965
21226
  const socketPath = getSocketPath(session2);
20966
- if (!existsSync4(socketPath)) {
21227
+ if (!existsSync6(socketPath)) {
20967
21228
  return false;
20968
21229
  }
20969
21230
  const lockPath = getLockPath(session2);
20970
- if (!existsSync4(lockPath)) {
21231
+ if (!existsSync6(lockPath)) {
20971
21232
  return false;
20972
21233
  }
20973
21234
  try {
@@ -20983,14 +21244,14 @@ class DaemonClient {
20983
21244
  static cleanStaleFiles(session2) {
20984
21245
  const socketPath = getSocketPath(session2);
20985
21246
  const lockPath = getLockPath(session2);
20986
- if (existsSync4(socketPath))
21247
+ if (existsSync6(socketPath))
20987
21248
  unlinkSync2(socketPath);
20988
- if (existsSync4(lockPath))
21249
+ if (existsSync6(lockPath))
20989
21250
  unlinkSync2(lockPath);
20990
21251
  }
20991
21252
  static async isAlive(session2) {
20992
21253
  const socketPath = getSocketPath(session2);
20993
- if (!existsSync4(socketPath)) {
21254
+ if (!existsSync6(socketPath)) {
20994
21255
  return false;
20995
21256
  }
20996
21257
  try {
@@ -21003,7 +21264,7 @@ class DaemonClient {
21003
21264
  }
21004
21265
  static listSessions() {
21005
21266
  const dir = getSocketDir();
21006
- if (!existsSync4(dir)) {
21267
+ if (!existsSync6(dir)) {
21007
21268
  return [];
21008
21269
  }
21009
21270
  const files = readdirSync(dir);
@@ -21032,7 +21293,7 @@ var init_client3 = __esm(() => {
21032
21293
  });
21033
21294
 
21034
21295
  // src/daemon/spawn.ts
21035
- import { closeSync, existsSync as existsSync5, openSync, readFileSync as readFileSync2 } from "fs";
21296
+ import { closeSync, existsSync as existsSync7, openSync, readFileSync as readFileSync2 } from "fs";
21036
21297
  async function spawnDaemon(session2, options = {}) {
21037
21298
  const socketPath = getSocketPath(session2);
21038
21299
  const spawnArgs = [];
@@ -21059,7 +21320,7 @@ async function spawnDaemon(session2, options = {}) {
21059
21320
  proc.unref();
21060
21321
  const deadline = Date.now() + SPAWN_TIMEOUT_MS;
21061
21322
  while (Date.now() < deadline) {
21062
- if (existsSync5(socketPath)) {
21323
+ if (existsSync7(socketPath)) {
21063
21324
  return;
21064
21325
  }
21065
21326
  await Bun.sleep(SPAWN_POLL_INTERVAL_MS);
@@ -21171,6 +21432,10 @@ var init_detect_runtime = __esm(() => {
21171
21432
  pattern: /^(uvicorn|gunicorn|flask|django-admin|pytest|mypy)$/,
21172
21433
  entry: { runtime: "debugpy", stripInterpreter: false }
21173
21434
  },
21435
+ {
21436
+ pattern: /^(mvn|mvnw|gradle|gradlew|mvnDebug)$/,
21437
+ entry: { runtime: "java", stripInterpreter: false }
21438
+ },
21174
21439
  { pattern: /^(rails|rake|rspec|irb)$/, entry: { runtime: "ruby", stripInterpreter: false } },
21175
21440
  { pattern: /^(iex|mix)$/, entry: { runtime: "elixir", stripInterpreter: false } }
21176
21441
  ];
@@ -23473,36 +23738,11 @@ var init_symbols = __esm(() => {
23473
23738
  });
23474
23739
 
23475
23740
  // src/commands/install.ts
23476
- import { existsSync as existsSync6, mkdirSync as mkdirSync2 } from "fs";
23477
- import { join as join3 } from "path";
23478
- function getPlatformArch() {
23479
- const os = process.platform;
23480
- const arch = process.arch;
23481
- return { os, arch };
23482
- }
23483
- function getLlvmDownloadUrl(version2, os, arch) {
23484
- if (os === "darwin") {
23485
- if (arch === "arm64") {
23486
- return `https://github.com/llvm/llvm-project/releases/download/llvmorg-${version2}/LLVM-${version2}-macOS-ARM64.tar.xz`;
23487
- }
23488
- if (arch === "x64") {
23489
- return `https://github.com/llvm/llvm-project/releases/download/llvmorg-${version2}/LLVM-${version2}-macOS-X64.tar.xz`;
23490
- }
23491
- }
23492
- if (os === "linux") {
23493
- if (arch === "x64") {
23494
- return `https://github.com/llvm/llvm-project/releases/download/llvmorg-${version2}/LLVM-${version2}-Linux-X64.tar.xz`;
23495
- }
23496
- if (arch === "arm64") {
23497
- return `https://github.com/llvm/llvm-project/releases/download/llvmorg-${version2}/LLVM-${version2}-Linux-AArch64.tar.xz`;
23498
- }
23499
- }
23500
- return null;
23501
- }
23502
- var LLVM_VERSION = "19.1.7";
23741
+ import { existsSync as existsSync8 } from "fs";
23503
23742
  var init_install = __esm(() => {
23504
23743
  init_zod();
23505
23744
  init_command();
23745
+ init_adapters2();
23506
23746
  init_session2();
23507
23747
  defineCommand({
23508
23748
  name: "install",
@@ -23516,10 +23756,11 @@ var init_install = __esm(() => {
23516
23756
  }),
23517
23757
  handler: async (ctx) => {
23518
23758
  const adapter = ctx.positional || undefined;
23759
+ const supported = listAdapterNames();
23519
23760
  if (ctx.flags.list) {
23520
23761
  const dir = getManagedAdaptersDir();
23521
23762
  console.log(`Managed adapters directory: ${dir}`);
23522
- if (!existsSync6(dir)) {
23763
+ if (!existsSync8(dir)) {
23523
23764
  console.log(" (empty \u2014 no adapters installed)");
23524
23765
  return 0;
23525
23766
  }
@@ -23535,92 +23776,30 @@ var init_install = __esm(() => {
23535
23776
  }
23536
23777
  if (!adapter) {
23537
23778
  console.error("Usage: dbg install <adapter>");
23538
- console.error(" Supported adapters: lldb");
23779
+ console.error(` Supported adapters: ${supported.join(", ")}`);
23539
23780
  console.error(" Options: --list (show installed adapters)");
23540
23781
  return 1;
23541
23782
  }
23542
- if (adapter !== "lldb") {
23783
+ const installer = getAdapterInstaller(adapter);
23784
+ if (!installer) {
23543
23785
  console.error(`Unknown adapter: ${adapter}`);
23544
- console.error(" Supported adapters: lldb");
23545
- return 1;
23546
- }
23547
- const { os, arch } = getPlatformArch();
23548
- const url3 = getLlvmDownloadUrl(LLVM_VERSION, os, arch);
23549
- if (!url3) {
23550
- console.error(`Unsupported platform: ${os}-${arch}`);
23551
- console.error(" Supported: darwin-arm64, darwin-x64, linux-x64, linux-arm64");
23786
+ console.error(` Supported adapters: ${supported.join(", ")}`);
23552
23787
  return 1;
23553
23788
  }
23554
- const adaptersDir = getManagedAdaptersDir();
23555
- const targetPath = join3(adaptersDir, "lldb-dap");
23556
- if (existsSync6(targetPath)) {
23557
- console.log(`lldb-dap already installed at ${targetPath}`);
23558
- console.log(` To reinstall, remove it first: rm ${targetPath}`);
23789
+ if (installer.isInstalled()) {
23790
+ console.log(`${installer.name} is already installed.`);
23791
+ console.log(" To reinstall, remove ~/.debug-that/adapters/ entry first.");
23559
23792
  return 0;
23560
23793
  }
23561
- console.log(`Downloading LLVM ${LLVM_VERSION} for ${os}-${arch}...`);
23562
- console.log(` From: ${url3}`);
23563
- const response = await fetch(url3, { redirect: "follow" });
23564
- if (!response.ok) {
23565
- console.error(`Download failed: HTTP ${response.status}`);
23566
- console.error(" -> Check your internet connection or try again later");
23567
- return 1;
23568
- }
23569
- const tarball = await response.arrayBuffer();
23570
- console.log(`Downloaded ${(tarball.byteLength / 1024 / 1024).toFixed(1)} MB`);
23571
- mkdirSync2(adaptersDir, { recursive: true });
23572
- const tmpTar = join3(adaptersDir, "llvm-download.tar.xz");
23573
- await Bun.write(tmpTar, tarball);
23574
- console.log("Extracting lldb-dap...");
23575
- const listResult = Bun.spawnSync(["tar", "-tf", tmpTar], {
23576
- stdout: "pipe"
23577
- });
23578
- const files = listResult.stdout.toString().split(`
23579
- `);
23580
- const lldbDapEntry = files.find((f) => f.endsWith("/bin/lldb-dap") || f === "bin/lldb-dap");
23581
- if (!lldbDapEntry) {
23582
- Bun.spawnSync(["rm", tmpTar]);
23583
- console.error("Could not find lldb-dap in the LLVM archive");
23584
- console.error(` Archive entries searched: ${files.length}`);
23585
- console.error(" -> Try installing manually: brew install llvm");
23586
- return 1;
23587
- }
23588
- const extractResult = Bun.spawnSync([
23589
- "tar",
23590
- "-xf",
23591
- tmpTar,
23592
- "-C",
23593
- adaptersDir,
23594
- "--strip-components",
23595
- String(lldbDapEntry.split("/").length - 1),
23596
- lldbDapEntry
23597
- ], { stdout: "pipe", stderr: "pipe" });
23598
- Bun.spawnSync(["rm", tmpTar]);
23599
- if (extractResult.exitCode !== 0) {
23600
- console.error(`Extraction failed: ${extractResult.stderr.toString()}`);
23601
- return 1;
23602
- }
23603
- const liblldbEntries = files.filter((f) => f.includes("liblldb") && (f.endsWith(".so") || f.endsWith(".dylib")));
23604
- for (const libEntry of liblldbEntries) {
23605
- Bun.spawnSync([
23606
- "tar",
23607
- "-xf",
23608
- tmpTar,
23609
- "-C",
23610
- adaptersDir,
23611
- "--strip-components",
23612
- String(libEntry.split("/").length - 1),
23613
- libEntry
23614
- ], { stdout: "pipe", stderr: "pipe" });
23615
- }
23616
- Bun.spawnSync(["chmod", "+x", targetPath]);
23617
- if (existsSync6(targetPath)) {
23618
- console.log(`Installed lldb-dap to ${targetPath}`);
23794
+ try {
23795
+ console.log(`Installing ${installer.name}...`);
23796
+ await installer.install((msg) => console.log(msg));
23797
+ console.log(`${installer.name} installed successfully.`);
23619
23798
  return 0;
23799
+ } catch (e) {
23800
+ console.error(`Installation failed: ${e.message}`);
23801
+ return 1;
23620
23802
  }
23621
- console.error("Installation failed \u2014 lldb-dap not found after extraction");
23622
- console.error(" -> Try installing manually: brew install llvm");
23623
- return 1;
23624
23803
  }
23625
23804
  });
23626
23805
  });
@@ -23742,7 +23921,7 @@ var init_logs = __esm(() => {
23742
23921
  // src/commands/logs.ts
23743
23922
  import {
23744
23923
  closeSync as closeSync2,
23745
- existsSync as existsSync7,
23924
+ existsSync as existsSync9,
23746
23925
  openSync as openSync2,
23747
23926
  readFileSync as readFileSync3,
23748
23927
  readSync,
@@ -23822,7 +24001,7 @@ var init_logs2 = __esm(() => {
23822
24001
  const isDaemon = ctx.flags.daemon || false;
23823
24002
  const logPath = isDaemon ? getDaemonLogPath(session2) : getLogPath(session2);
23824
24003
  if (ctx.flags.clear) {
23825
- if (existsSync7(logPath)) {
24004
+ if (existsSync9(logPath)) {
23826
24005
  writeFileSync4(logPath, "");
23827
24006
  console.log(`${isDaemon ? "Daemon log" : "Log"} cleared`);
23828
24007
  } else {
@@ -23830,7 +24009,7 @@ var init_logs2 = __esm(() => {
23830
24009
  }
23831
24010
  return 0;
23832
24011
  }
23833
- if (!existsSync7(logPath)) {
24012
+ if (!existsSync9(logPath)) {
23834
24013
  console.error(`No ${isDaemon ? "daemon " : ""}log file for session "${session2}"`);
23835
24014
  console.error(" -> Try: dbg launch --brk node app.js");
23836
24015
  return 1;
@@ -24168,7 +24347,7 @@ var init_help = __esm(() => {
24168
24347
  var require_package = __commonJS((exports, module) => {
24169
24348
  module.exports = {
24170
24349
  name: "debug-that",
24171
- version: "0.4.0",
24350
+ version: "0.5.0",
24172
24351
  description: "Universal Debugger CLI for AI Agents",
24173
24352
  license: "MIT",
24174
24353
  author: "Theodo Group",
@@ -24200,7 +24379,7 @@ var require_package = __commonJS((exports, module) => {
24200
24379
  ],
24201
24380
  scripts: {
24202
24381
  dev: "bun run src/main.ts",
24203
- build: "bun build src/main.ts --outdir dist --target=bun",
24382
+ build: "bun run build.ts",
24204
24383
  test: "bun test tests/unit/ && bun test --concurrent tests/integration/",
24205
24384
  lint: "biome check .",
24206
24385
  format: "biome check --write .",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "debug-that",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Universal Debugger CLI for AI Agents",
5
5
  "license": "MIT",
6
6
  "author": "Theodo Group",
@@ -32,7 +32,7 @@
32
32
  ],
33
33
  "scripts": {
34
34
  "dev": "bun run src/main.ts",
35
- "build": "bun build src/main.ts --outdir dist --target=bun",
35
+ "build": "bun run build.ts",
36
36
  "test": "bun test tests/unit/ && bun test --concurrent tests/integration/",
37
37
  "lint": "biome check .",
38
38
  "format": "biome check --write .",
@@ -54,4 +54,4 @@
54
54
  "zod": "^4.0.0"
55
55
  },
56
56
  "module": "index.ts"
57
- }
57
+ }