@samrahimi/smol-js 0.7.0 → 0.7.1

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/cli.js CHANGED
@@ -25,7 +25,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
25
25
 
26
26
  // src/cli.ts
27
27
  var fs8 = __toESM(require("fs"));
28
- var path8 = __toESM(require("path"));
28
+ var path9 = __toESM(require("path"));
29
29
  var readline = __toESM(require("readline"));
30
30
  var import_chalk3 = __toESM(require("chalk"));
31
31
  var import_dotenv = __toESM(require("dotenv"));
@@ -755,7 +755,7 @@ Total time: ${(duration / 1e3).toFixed(2)}s`);
755
755
  }
756
756
  /** Sleep for a specified duration */
757
757
  sleep(ms) {
758
- return new Promise((resolve7) => setTimeout(resolve7, ms));
758
+ return new Promise((resolve8) => setTimeout(resolve8, ms));
759
759
  }
760
760
  };
761
761
 
@@ -2707,7 +2707,7 @@ var ExaResearchTool = class extends Tool {
2707
2707
  while (Date.now() - startTime < this.maxPollTime) {
2708
2708
  attempts++;
2709
2709
  if (attempts > 1) {
2710
- await new Promise((resolve7) => setTimeout(resolve7, this.pollInterval));
2710
+ await new Promise((resolve8) => setTimeout(resolve8, this.pollInterval));
2711
2711
  }
2712
2712
  const statusResponse = await fetch(`https://api.exa.ai/research/v1/${researchId}`, {
2713
2713
  method: "GET",
@@ -3337,10 +3337,11 @@ var Orchestrator = class {
3337
3337
 
3338
3338
  // src/tools/CustomToolScanner.ts
3339
3339
  var fs7 = __toESM(require("fs"));
3340
- var path7 = __toESM(require("path"));
3340
+ var path8 = __toESM(require("path"));
3341
3341
 
3342
3342
  // src/tools/ProxyTool.ts
3343
3343
  var import_child_process2 = require("child_process");
3344
+ var path7 = __toESM(require("path"));
3344
3345
 
3345
3346
  // src/utils/bunInstaller.ts
3346
3347
  var import_child_process = require("child_process");
@@ -3399,10 +3400,12 @@ function whichBun() {
3399
3400
  }
3400
3401
 
3401
3402
  // src/tools/ProxyTool.ts
3402
- var TOOL_OUTPUT_PREFIX = "[TOOL_OUTPUT]";
3403
3403
  var TOOL_RESULT_PREFIX = "[TOOL_RESULT]";
3404
3404
  var TOOL_ERROR_PREFIX = "[TOOL_ERROR]";
3405
3405
  var DEFAULT_TOOL_TIMEOUT_MS = 6e4;
3406
+ function resolveHarnessPath() {
3407
+ return path7.resolve(__dirname, "..", "toolHarness.ts");
3408
+ }
3406
3409
  var ProxyTool = class extends Tool {
3407
3410
  name;
3408
3411
  description;
@@ -3411,6 +3414,7 @@ var ProxyTool = class extends Tool {
3411
3414
  toolPath;
3412
3415
  timeout;
3413
3416
  bunPath = null;
3417
+ harnessPath = null;
3414
3418
  constructor(config) {
3415
3419
  super();
3416
3420
  this.name = config.name;
@@ -3421,23 +3425,25 @@ var ProxyTool = class extends Tool {
3421
3425
  this.timeout = config.timeout ?? DEFAULT_TOOL_TIMEOUT_MS;
3422
3426
  }
3423
3427
  /**
3424
- * Ensure Bun is available before first invocation.
3428
+ * Ensure Bun is available and locate the harness before first invocation.
3425
3429
  */
3426
3430
  async setup() {
3427
3431
  this.bunPath = await ensureBunAvailable();
3432
+ this.harnessPath = resolveHarnessPath();
3428
3433
  this.isSetup = true;
3429
3434
  }
3430
3435
  /**
3431
- * Spawn the tool in a Bun child process, pass serialized args via CLI,
3432
- * stream stdout back as log lines, and parse the final result.
3436
+ * Spawn the harness in a Bun child process. The harness imports the tool,
3437
+ * calls execute(args), and writes the protocol lines. Any console.log from
3438
+ * the tool flows through stdout as plain lines.
3433
3439
  */
3434
3440
  async execute(args) {
3435
- if (!this.bunPath) {
3441
+ if (!this.bunPath || !this.harnessPath) {
3436
3442
  await this.setup();
3437
3443
  }
3438
3444
  const serializedArgs = JSON.stringify(args);
3439
- return new Promise((resolve7, reject) => {
3440
- const child = (0, import_child_process2.spawn)(this.bunPath, ["run", this.toolPath, serializedArgs], {
3445
+ return new Promise((resolve8, reject) => {
3446
+ const child = (0, import_child_process2.spawn)(this.bunPath, ["run", this.harnessPath, this.toolPath, serializedArgs], {
3441
3447
  stdio: ["pipe", "pipe", "pipe"],
3442
3448
  env: { ...process.env }
3443
3449
  });
@@ -3502,12 +3508,12 @@ ${logBuffer.join("\n")}
3502
3508
  [Tool result]
3503
3509
  `;
3504
3510
  if (typeof result === "string") {
3505
- resolve7(logPrefix + result);
3511
+ resolve8(logPrefix + result);
3506
3512
  } else {
3507
- resolve7({ logs: logBuffer.join("\n"), result });
3513
+ resolve8({ logs: logBuffer.join("\n"), result });
3508
3514
  }
3509
3515
  } else {
3510
- resolve7(result);
3516
+ resolve8(result);
3511
3517
  }
3512
3518
  return;
3513
3519
  }
@@ -3517,7 +3523,7 @@ ${logBuffer.join("\n")}
3517
3523
  `Custom tool "${this.name}" exited with code ${code}. Output: ${combined || "(none)"}`
3518
3524
  ));
3519
3525
  } else {
3520
- resolve7(combined || `Tool "${this.name}" produced no output.`);
3526
+ resolve8(combined || `Tool "${this.name}" produced no output.`);
3521
3527
  }
3522
3528
  });
3523
3529
  child.on("error", (err) => {
@@ -3528,7 +3534,7 @@ ${logBuffer.join("\n")}
3528
3534
  });
3529
3535
  });
3530
3536
  }
3531
- // --- internal line parser ---
3537
+ // --- line parser: protocol is spoken by harness, interpreted here ---
3532
3538
  processLine(line, handlers) {
3533
3539
  const trimmed = line.trimEnd();
3534
3540
  if (!trimmed) return;
@@ -3541,8 +3547,6 @@ ${logBuffer.join("\n")}
3541
3547
  }
3542
3548
  } else if (trimmed.startsWith(TOOL_ERROR_PREFIX)) {
3543
3549
  handlers.onError(trimmed.slice(TOOL_ERROR_PREFIX.length).trim());
3544
- } else if (trimmed.startsWith(TOOL_OUTPUT_PREFIX)) {
3545
- handlers.onOutput(trimmed.slice(TOOL_OUTPUT_PREFIX.length).trim());
3546
3550
  } else {
3547
3551
  handlers.onOutput(trimmed);
3548
3552
  }
@@ -3561,10 +3565,10 @@ function scanCustomTools(folderPath) {
3561
3565
  const discovered = [];
3562
3566
  for (const entry of entries) {
3563
3567
  if (entry.isDirectory()) continue;
3564
- const ext = path7.extname(entry.name).toLowerCase();
3568
+ const ext = path8.extname(entry.name).toLowerCase();
3565
3569
  if (ext !== ".ts" && ext !== ".js") continue;
3566
- const filePath = path7.resolve(folderPath, entry.name);
3567
- const baseName = path7.basename(entry.name, ext);
3570
+ const filePath = path8.resolve(folderPath, entry.name);
3571
+ const baseName = path8.basename(entry.name, ext);
3568
3572
  let metadata;
3569
3573
  try {
3570
3574
  metadata = extractMetadata(filePath);
@@ -3718,7 +3722,7 @@ async function runCommand(args) {
3718
3722
  if (outputFormat === "json" && !runId) {
3719
3723
  runId = `run-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`;
3720
3724
  }
3721
- const resolvedPath = path8.isAbsolute(filePath) ? filePath : path8.resolve(process.cwd(), filePath);
3725
+ const resolvedPath = path9.isAbsolute(filePath) ? filePath : path9.resolve(process.cwd(), filePath);
3722
3726
  if (!fs8.existsSync(resolvedPath)) {
3723
3727
  if (outputFormat === "json") {
3724
3728
  console.log(JSON.stringify({
@@ -3749,7 +3753,7 @@ async function runCommand(args) {
3749
3753
  }
3750
3754
  }
3751
3755
  if (cwd) {
3752
- const resolvedCwd = path8.isAbsolute(cwd) ? cwd : path8.resolve(process.cwd(), cwd);
3756
+ const resolvedCwd = path9.isAbsolute(cwd) ? cwd : path9.resolve(process.cwd(), cwd);
3753
3757
  if (!fs8.existsSync(resolvedCwd)) {
3754
3758
  fs8.mkdirSync(resolvedCwd, { recursive: true });
3755
3759
  }
@@ -3762,7 +3766,7 @@ async function runCommand(args) {
3762
3766
  cwd: cwd || void 0
3763
3767
  });
3764
3768
  if (customToolsFolder) {
3765
- const resolvedToolsFolder = path8.isAbsolute(customToolsFolder) ? customToolsFolder : path8.resolve(process.cwd(), customToolsFolder);
3769
+ const resolvedToolsFolder = path9.isAbsolute(customToolsFolder) ? customToolsFolder : path9.resolve(process.cwd(), customToolsFolder);
3766
3770
  if (outputFormat !== "json") {
3767
3771
  console.log(import_chalk3.default.gray(`
3768
3772
  Scanning custom tools in: ${resolvedToolsFolder}
@@ -3816,7 +3820,7 @@ async function validateCommand(args) {
3816
3820
  process.exit(1);
3817
3821
  }
3818
3822
  const filePath = args[0];
3819
- const resolvedPath = path8.isAbsolute(filePath) ? filePath : path8.resolve(process.cwd(), filePath);
3823
+ const resolvedPath = path9.isAbsolute(filePath) ? filePath : path9.resolve(process.cwd(), filePath);
3820
3824
  if (!fs8.existsSync(resolvedPath)) {
3821
3825
  console.error(import_chalk3.default.red(`Error: file not found: ${resolvedPath}`));
3822
3826
  process.exit(1);
@@ -3840,10 +3844,10 @@ function promptUser(question) {
3840
3844
  input: process.stdin,
3841
3845
  output: process.stdout
3842
3846
  });
3843
- return new Promise((resolve7) => {
3847
+ return new Promise((resolve8) => {
3844
3848
  rl.question(import_chalk3.default.cyan(question), (answer) => {
3845
3849
  rl.close();
3846
- resolve7(answer);
3850
+ resolve8(answer);
3847
3851
  });
3848
3852
  });
3849
3853
  }