tarsk 0.3.28 → 0.3.29

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 (2) hide show
  1. package/dist/index.js +16 -4
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2433,7 +2433,7 @@ function generateDiffString(oldContent, newContent, contextLines = 4) {
2433
2433
  // src/tools/path-utils.ts
2434
2434
  import { accessSync, constants } from "node:fs";
2435
2435
  import * as os from "node:os";
2436
- import { isAbsolute, resolve as resolvePath } from "node:path";
2436
+ import { isAbsolute, resolve as resolvePath, relative as relative2 } from "node:path";
2437
2437
  var UNICODE_SPACES = /[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g;
2438
2438
  var NARROW_NO_BREAK_SPACE = " ";
2439
2439
  function normalizeUnicodeSpaces(str) {
@@ -2476,6 +2476,12 @@ function resolveToCwd(filePath, cwd) {
2476
2476
  }
2477
2477
  return resolvePath(cwd, expanded);
2478
2478
  }
2479
+ function validatePathWithinCwd(resolvedPath, cwd) {
2480
+ const relativePath = relative2(cwd, resolvedPath);
2481
+ if (relativePath.startsWith("..") || isAbsolute(relativePath)) {
2482
+ throw new Error(`Access denied: Path is outside the allowed directory. ` + `Requested: ${resolvedPath}, Allowed root: ${cwd}`);
2483
+ }
2484
+ }
2479
2485
  function resolveReadPath(filePath, cwd) {
2480
2486
  const resolved = resolveToCwd(filePath, cwd);
2481
2487
  if (fileExists(resolved)) {
@@ -2520,6 +2526,7 @@ function createEditTool(cwd, options) {
2520
2526
  parameters: editSchema,
2521
2527
  execute: async (_toolCallId, { path, oldText, newText }, signal) => {
2522
2528
  const absolutePath = resolveToCwd(path, cwd);
2529
+ validatePathWithinCwd(absolutePath, cwd);
2523
2530
  return new Promise((resolve, reject) => {
2524
2531
  if (signal?.aborted) {
2525
2532
  reject(new Error("Operation aborted"));
@@ -2652,6 +2659,7 @@ function createFindTool(cwd, options) {
2652
2659
  (async () => {
2653
2660
  try {
2654
2661
  const searchPath = resolveToCwd(searchDir || ".", cwd);
2662
+ validatePathWithinCwd(searchPath, cwd);
2655
2663
  const effectiveLimit = limit ?? DEFAULT_LIMIT;
2656
2664
  const ops = customOps ?? defaultFindOperations;
2657
2665
  if (!await ops.exists(searchPath)) {
@@ -2780,6 +2788,7 @@ function createGrepTool(cwd, options) {
2780
2788
  return;
2781
2789
  }
2782
2790
  const searchPath = resolveToCwd(searchDir || ".", cwd);
2791
+ validatePathWithinCwd(searchPath, cwd);
2783
2792
  const ops = customOps ?? defaultGrepOperations;
2784
2793
  let isDirectory;
2785
2794
  try {
@@ -2792,9 +2801,9 @@ function createGrepTool(cwd, options) {
2792
2801
  const effectiveLimit = Math.max(1, limit ?? DEFAULT_LIMIT2);
2793
2802
  const formatPath = (filePath) => {
2794
2803
  if (isDirectory) {
2795
- const relative2 = path2.relative(searchPath, filePath);
2796
- if (relative2 && !relative2.startsWith("..")) {
2797
- return relative2.replace(/\\/g, "/");
2804
+ const relative3 = path2.relative(searchPath, filePath);
2805
+ if (relative3 && !relative3.startsWith("..")) {
2806
+ return relative3.replace(/\\/g, "/");
2798
2807
  }
2799
2808
  }
2800
2809
  return path2.basename(filePath);
@@ -2986,6 +2995,7 @@ function createLsTool(cwd, options) {
2986
2995
  (async () => {
2987
2996
  try {
2988
2997
  const dirPath = resolveToCwd(dirPathArg || ".", cwd);
2998
+ validatePathWithinCwd(dirPath, cwd);
2989
2999
  const effectiveLimit = limit ?? DEFAULT_LIMIT3;
2990
3000
  if (!await ops.exists(dirPath)) {
2991
3001
  reject(new Error(`Path not found: ${dirPath}`));
@@ -3079,6 +3089,7 @@ function createReadTool(cwd, options) {
3079
3089
  parameters: readSchema,
3080
3090
  execute: async (_toolCallId, { path: path3, offset, limit }, signal) => {
3081
3091
  const absolutePath = resolveReadPath(path3, cwd);
3092
+ validatePathWithinCwd(absolutePath, cwd);
3082
3093
  return new Promise((resolve, reject) => {
3083
3094
  if (signal?.aborted) {
3084
3095
  reject(new Error("Operation aborted"));
@@ -3187,6 +3198,7 @@ function createWriteTool(cwd, options) {
3187
3198
  parameters: writeSchema,
3188
3199
  execute: async (_toolCallId, { path: path3, content }, signal) => {
3189
3200
  const absolutePath = resolveToCwd(path3, cwd);
3201
+ validatePathWithinCwd(absolutePath, cwd);
3190
3202
  const dir = dirname4(absolutePath);
3191
3203
  return new Promise((resolve, reject) => {
3192
3204
  if (signal?.aborted) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tarsk",
3
- "version": "0.3.28",
3
+ "version": "0.3.29",
4
4
  "description": "CLI for Tarsk - Project Threads Manager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",