@probelabs/probe 0.6.0-rc117 → 0.6.0-rc119

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.
@@ -223,9 +223,22 @@ export const listFilesTool = {
223
223
 
224
224
  // Security: Validate path to prevent traversal attacks
225
225
  const secureBaseDir = path.resolve(baseCwd);
226
- const targetDir = path.resolve(secureBaseDir, directory);
227
- if (!targetDir.startsWith(secureBaseDir + path.sep) && targetDir !== secureBaseDir) {
228
- throw new Error('Path traversal attempt detected. Access denied.');
226
+
227
+ // If directory is absolute, check if it's within the secure base directory
228
+ // If it's relative, resolve it against the secure base directory
229
+ let targetDir;
230
+ if (path.isAbsolute(directory)) {
231
+ targetDir = path.resolve(directory);
232
+ // Check if the absolute path is within the secure base directory
233
+ if (!targetDir.startsWith(secureBaseDir + path.sep) && targetDir !== secureBaseDir) {
234
+ throw new Error(`Path traversal attempt detected. Cannot access directory outside workspace: ${directory}`);
235
+ }
236
+ } else {
237
+ targetDir = path.resolve(secureBaseDir, directory);
238
+ // Double-check the resolved path is still within the secure base directory
239
+ if (!targetDir.startsWith(secureBaseDir + path.sep) && targetDir !== secureBaseDir) {
240
+ throw new Error(`Path traversal attempt detected. Access denied: ${directory}`);
241
+ }
229
242
  }
230
243
 
231
244
  const debug = process.env.DEBUG === '1';
@@ -309,9 +322,22 @@ export const searchFilesTool = {
309
322
  // Security: Validate path to prevent traversal attacks
310
323
  const baseCwd = workingDirectory || process.cwd();
311
324
  const secureBaseDir = path.resolve(baseCwd);
312
- const targetDir = path.resolve(secureBaseDir, directory);
313
- if (!targetDir.startsWith(secureBaseDir + path.sep) && targetDir !== secureBaseDir) {
314
- throw new Error('Path traversal attempt detected. Access denied.');
325
+
326
+ // If directory is absolute, check if it's within the secure base directory
327
+ // If it's relative, resolve it against the secure base directory
328
+ let targetDir;
329
+ if (path.isAbsolute(directory)) {
330
+ targetDir = path.resolve(directory);
331
+ // Check if the absolute path is within the secure base directory
332
+ if (!targetDir.startsWith(secureBaseDir + path.sep) && targetDir !== secureBaseDir) {
333
+ throw new Error(`Path traversal attempt detected. Cannot access directory outside workspace: ${directory}`);
334
+ }
335
+ } else {
336
+ targetDir = path.resolve(secureBaseDir, directory);
337
+ // Double-check the resolved path is still within the secure base directory
338
+ if (!targetDir.startsWith(secureBaseDir + path.sep) && targetDir !== secureBaseDir) {
339
+ throw new Error(`Path traversal attempt detected. Access denied: ${directory}`);
340
+ }
315
341
  }
316
342
 
317
343
  // Validate pattern complexity to prevent DoS
@@ -1,14 +1,14 @@
1
- import { get_encoding } from 'tiktoken';
1
+ import { encode } from 'gpt-tokenizer';
2
2
 
3
3
  /**
4
4
  * TokenCounter class to track token usage in the agent
5
5
  */
6
6
  export class TokenCounter {
7
7
  constructor() {
8
- // Initialize the tokenizer with cl100k_base encoding (works for both Claude and GPT models)
8
+ // Initialize the tokenizer with gpt-tokenizer (works for both Claude and GPT models)
9
9
  try {
10
- // Initialize tokenizer
11
- this.tokenizer = get_encoding('cl100k_base');
10
+ // gpt-tokenizer uses encode directly, no need to initialize
11
+ this.tokenizer = encode;
12
12
 
13
13
  // Context window tracking
14
14
  this.contextSize = 0; // Current size based on history
@@ -30,7 +30,7 @@ export class TokenCounter {
30
30
 
31
31
  } catch (error) {
32
32
  console.error('Error initializing tokenizer:', error);
33
- // Fallback to a simple token counting method if tiktoken fails
33
+ // Fallback to a simple token counting method if gpt-tokenizer fails
34
34
  this.tokenizer = null;
35
35
  this.contextSize = 0;
36
36
  this.requestTokens = 0;
@@ -49,7 +49,7 @@ export class TokenCounter {
49
49
  }
50
50
 
51
51
  /**
52
- * Count tokens in a string using tiktoken or fallback method
52
+ * Count tokens in a string using gpt-tokenizer or fallback method
53
53
  * @param {string} text - The text to count tokens for
54
54
  * @returns {number} - The number of tokens
55
55
  */
@@ -60,7 +60,7 @@ export class TokenCounter {
60
60
 
61
61
  if (this.tokenizer) {
62
62
  try {
63
- const tokens = this.tokenizer.encode(text);
63
+ const tokens = this.tokenizer(text);
64
64
  return tokens.length;
65
65
  } catch (error) {
66
66
  // Fallback to a simple approximation (1 token ≈ 4 characters)