@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/README.md +0 -23
- package/dist/cli.js +71 -9
- package/dist/cli.js.map +1 -1
- package/dist/index.js +71 -9
- package/dist/index.js.map +1 -1
- package/package.json +7 -27
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:
|
|
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} ${
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
}
|