@mtaap/mcp 0.2.7 → 0.2.8

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/index.js CHANGED
@@ -429,6 +429,7 @@ var ListTasksInputSchema = import_zod2.z.object({
429
429
  includeArchived: import_zod2.z.boolean().optional()
430
430
  });
431
431
  var cuidOrPrefixedId = import_zod2.z.string().regex(/^([a-z0-9]+|[a-z]+_[a-zA-Z0-9]+)$/);
432
+ var gitBranchName = import_zod2.z.string().min(1).max(100).regex(/^[a-zA-Z0-9][-a-zA-Z0-9._/]*[a-zA-Z0-9]$|^[a-zA-Z0-9]$/, "Branch name must start and end with alphanumeric character").refine((val) => !val.includes("..") && !val.includes("@{") && !val.includes("//") && !val.endsWith(".lock") && !val.includes("~") && !val.includes("^") && !val.includes(":") && !val.includes("?") && !val.includes("*") && !val.includes("[") && !val.includes("\\") && !val.includes(" ") && !val.includes(";") && !val.includes("&") && !val.includes("|") && !val.includes("$") && !val.includes("`") && !val.includes("'") && !val.includes('"') && !val.includes("<") && !val.includes(">") && !val.includes("(") && !val.includes(")"), "Invalid branch name: contains forbidden characters or sequences");
432
433
  var GetTaskInputSchema = import_zod2.z.object({
433
434
  taskId: cuidOrPrefixedId
434
435
  });
@@ -643,7 +644,7 @@ var UpdateTaskMCPInputSchema = import_zod2.z.object({
643
644
  var ReportBranchInputSchema = import_zod2.z.object({
644
645
  projectId: cuidOrPrefixedId,
645
646
  taskId: cuidOrPrefixedId,
646
- branchName: import_zod2.z.string().min(1).max(100)
647
+ branchName: gitBranchName
647
648
  });
648
649
  var ReportPRInputSchema = import_zod2.z.object({
649
650
  projectId: cuidOrPrefixedId,
@@ -950,6 +951,12 @@ var errorTrackerInstance = new NoOpErrorTracker();
950
951
 
951
952
  // src/api-client.ts
952
953
  var DEFAULT_TIMEOUT = 3e4;
954
+ function sanitizeForLogging(str) {
955
+ let sanitized = str.replace(/\bcollab_[a-zA-Z0-9_-]+\b/gi, "[REDACTED_API_KEY]");
956
+ sanitized = sanitized.replace(/\bBearer\s+[a-zA-Z0-9._-]+\b/gi, "Bearer [REDACTED]");
957
+ sanitized = sanitized.replace(/([?&](api_?key|token|auth|key|secret)=)[^&\s]+/gi, "$1[REDACTED]");
958
+ return sanitized;
959
+ }
953
960
  var ApiError = class extends Error {
954
961
  constructor(message, code, status, details) {
955
962
  super(message);
@@ -979,7 +986,7 @@ var MCPApiClient = class {
979
986
  const controller = new AbortController();
980
987
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
981
988
  if (this.debug) {
982
- console.error(`[mcp-api] ${method} ${url}`);
989
+ console.error(`[mcp-api] ${method} ${sanitizeForLogging(path)}`);
983
990
  }
984
991
  try {
985
992
  const response = await fetch(url, {
@@ -1014,8 +1021,9 @@ var MCPApiClient = class {
1014
1021
  408
1015
1022
  );
1016
1023
  }
1024
+ const rawMessage = error instanceof Error ? error.message : "Unknown error";
1017
1025
  throw new ApiError(
1018
- error instanceof Error ? error.message : "Unknown error",
1026
+ sanitizeForLogging(rawMessage),
1019
1027
  "NETWORK_ERROR",
1020
1028
  0
1021
1029
  );
@@ -2201,22 +2209,76 @@ function handleApiError(error) {
2201
2209
  isError: true
2202
2210
  };
2203
2211
  }
2212
+ var ActiveTaskSchema = import_zod3.z.object({
2213
+ taskId: import_zod3.z.string().min(1),
2214
+ projectId: import_zod3.z.string().min(1),
2215
+ branchName: import_zod3.z.string().optional(),
2216
+ startedAt: import_zod3.z.string().optional()
2217
+ });
2204
2218
  async function checkActiveTask() {
2205
2219
  const fs = await import("fs");
2206
2220
  const path = await import("path");
2207
- const activeTaskPath = path.join(process.cwd(), ".collab", "active-task.json");
2221
+ const cwd = process.cwd();
2222
+ const collabDir = path.join(cwd, ".collab");
2223
+ const activeTaskPath = path.join(collabDir, "active-task.json");
2208
2224
  try {
2209
- await fs.promises.access(activeTaskPath);
2225
+ const resolvedPath = path.resolve(activeTaskPath);
2226
+ const resolvedCollabDir = path.resolve(collabDir);
2227
+ if (!resolvedPath.startsWith(resolvedCollabDir + path.sep) && resolvedPath !== resolvedCollabDir) {
2228
+ return {
2229
+ hasActiveTask: false,
2230
+ task: null,
2231
+ error: "Invalid active task path"
2232
+ };
2233
+ }
2234
+ const stats = await fs.promises.lstat(activeTaskPath);
2235
+ if (stats.isSymbolicLink()) {
2236
+ return {
2237
+ hasActiveTask: false,
2238
+ task: null,
2239
+ error: "Symlinks not allowed for active task file"
2240
+ };
2241
+ }
2242
+ if (!stats.isFile()) {
2243
+ return {
2244
+ hasActiveTask: false,
2245
+ task: null
2246
+ };
2247
+ }
2210
2248
  const content = await fs.promises.readFile(activeTaskPath, "utf-8");
2211
- const activeTask = JSON.parse(content);
2249
+ let parsed;
2250
+ try {
2251
+ parsed = JSON.parse(content);
2252
+ } catch {
2253
+ return {
2254
+ hasActiveTask: false,
2255
+ task: null,
2256
+ error: "Invalid JSON in active task file"
2257
+ };
2258
+ }
2259
+ const validationResult = ActiveTaskSchema.safeParse(parsed);
2260
+ if (!validationResult.success) {
2261
+ return {
2262
+ hasActiveTask: false,
2263
+ task: null,
2264
+ error: "Active task file has invalid structure"
2265
+ };
2266
+ }
2212
2267
  return {
2213
2268
  hasActiveTask: true,
2214
- task: activeTask
2269
+ task: validationResult.data
2215
2270
  };
2216
- } catch {
2271
+ } catch (err) {
2272
+ if (err instanceof Error && "code" in err && err.code === "ENOENT") {
2273
+ return {
2274
+ hasActiveTask: false,
2275
+ task: null
2276
+ };
2277
+ }
2217
2278
  return {
2218
2279
  hasActiveTask: false,
2219
- task: null
2280
+ task: null,
2281
+ error: "Failed to read active task file"
2220
2282
  };
2221
2283
  }
2222
2284
  }