@zeliper/zscode-mcp-server 1.0.1 → 1.0.2

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 (50) hide show
  1. package/dist/errors/index.d.ts +28 -0
  2. package/dist/errors/index.d.ts.map +1 -1
  3. package/dist/errors/index.js +50 -0
  4. package/dist/errors/index.js.map +1 -1
  5. package/dist/state/manager.d.ts +33 -2
  6. package/dist/state/manager.d.ts.map +1 -1
  7. package/dist/state/manager.js +341 -138
  8. package/dist/state/manager.js.map +1 -1
  9. package/dist/state/manager.test.d.ts +2 -0
  10. package/dist/state/manager.test.d.ts.map +1 -0
  11. package/dist/state/manager.test.js +310 -0
  12. package/dist/state/manager.test.js.map +1 -0
  13. package/dist/state/schema.d.ts +190 -9
  14. package/dist/state/schema.d.ts.map +1 -1
  15. package/dist/state/schema.js +33 -1
  16. package/dist/state/schema.js.map +1 -1
  17. package/dist/state/schema.test.d.ts +2 -0
  18. package/dist/state/schema.test.d.ts.map +1 -0
  19. package/dist/state/schema.test.js +300 -0
  20. package/dist/state/schema.test.js.map +1 -0
  21. package/dist/state/types.d.ts +5 -1
  22. package/dist/state/types.d.ts.map +1 -1
  23. package/dist/state/types.js +3 -1
  24. package/dist/state/types.js.map +1 -1
  25. package/dist/tools/archive.d.ts.map +1 -1
  26. package/dist/tools/archive.js +57 -0
  27. package/dist/tools/archive.js.map +1 -1
  28. package/dist/tools/context.d.ts.map +1 -1
  29. package/dist/tools/context.js +14 -0
  30. package/dist/tools/context.js.map +1 -1
  31. package/dist/tools/index.d.ts.map +1 -1
  32. package/dist/tools/index.js +3 -0
  33. package/dist/tools/index.js.map +1 -1
  34. package/dist/tools/memory.d.ts +7 -0
  35. package/dist/tools/memory.d.ts.map +1 -0
  36. package/dist/tools/memory.js +243 -0
  37. package/dist/tools/memory.js.map +1 -0
  38. package/dist/tools/modify.d.ts.map +1 -1
  39. package/dist/tools/modify.js +9 -6
  40. package/dist/tools/modify.js.map +1 -1
  41. package/dist/tools/plan.js +3 -3
  42. package/dist/tools/plan.js.map +1 -1
  43. package/dist/tools/staging.d.ts.map +1 -1
  44. package/dist/tools/staging.js +3 -3
  45. package/dist/tools/staging.js.map +1 -1
  46. package/dist/utils/paths.d.ts +34 -0
  47. package/dist/utils/paths.d.ts.map +1 -1
  48. package/dist/utils/paths.js +94 -2
  49. package/dist/utils/paths.js.map +1 -1
  50. package/package.json +10 -3
@@ -1,5 +1,6 @@
1
- import { mkdir } from "fs/promises";
2
- import { sep, normalize, join, dirname, isAbsolute } from "path";
1
+ import { mkdir, writeFile, rename, unlink } from "fs/promises";
2
+ import { sep, normalize, join, dirname, isAbsolute, resolve } from "path";
3
+ import { randomBytes } from "crypto";
3
4
  /**
4
5
  * Normalize path for current OS
5
6
  * Windows: uses backslashes
@@ -119,4 +120,95 @@ export function escapeForShell(filePath) {
119
120
  return filePath.replace(/(["\s'$`\\])/g, "\\$1");
120
121
  }
121
122
  }
123
+ // ============ Security Functions ============
124
+ /**
125
+ * Check if a target path is safely within the base directory
126
+ * Prevents path traversal attacks (e.g., ../../../etc/passwd)
127
+ * @param basePath - The allowed base directory
128
+ * @param targetPath - The path to validate
129
+ * @returns true if targetPath is within basePath
130
+ */
131
+ export function isPathSafe(basePath, targetPath) {
132
+ const resolvedBase = resolve(normalize(basePath));
133
+ const resolvedTarget = resolve(normalize(targetPath));
134
+ // Ensure the target starts with the base path
135
+ // Add separator to prevent partial matches (e.g., /base123 matching /base)
136
+ return resolvedTarget === resolvedBase ||
137
+ resolvedTarget.startsWith(resolvedBase + sep);
138
+ }
139
+ /**
140
+ * Validate that a path component doesn't contain traversal sequences
141
+ * @param component - A single path component (e.g., filename or directory name)
142
+ * @returns true if the component is safe
143
+ */
144
+ export function isSafePathComponent(component) {
145
+ // Check for path traversal patterns
146
+ if (component === "." || component === "..") {
147
+ return false;
148
+ }
149
+ // Check for traversal sequences
150
+ if (component.includes("..") || component.includes("/") || component.includes("\\")) {
151
+ return false;
152
+ }
153
+ // Check for null bytes (can be used to truncate paths)
154
+ if (component.includes("\0")) {
155
+ return false;
156
+ }
157
+ return true;
158
+ }
159
+ /**
160
+ * Validate an ID to ensure it doesn't contain malicious characters
161
+ * @param id - The ID to validate
162
+ * @returns true if the ID is safe to use in file paths
163
+ */
164
+ export function isValidId(id) {
165
+ // IDs should only contain alphanumeric characters and hyphens
166
+ return /^[a-zA-Z0-9-]+$/.test(id);
167
+ }
168
+ // ============ Atomic File Operations ============
169
+ /**
170
+ * Write file atomically by writing to a temp file first, then renaming
171
+ * This prevents data corruption if the write is interrupted
172
+ * @param filePath - Target file path
173
+ * @param content - Content to write
174
+ * @param encoding - File encoding (default: utf-8)
175
+ */
176
+ export async function atomicWriteFile(filePath, content, encoding = "utf-8") {
177
+ const normalizedPath = normalizePath(filePath);
178
+ const dirPath = dirname(normalizedPath);
179
+ const tempPath = normalizedPath + `.tmp.${randomBytes(8).toString("hex")}`;
180
+ await ensureDir(dirPath);
181
+ try {
182
+ // Write to temp file
183
+ await writeFile(tempPath, content, encoding);
184
+ // Atomic rename
185
+ await rename(tempPath, normalizedPath);
186
+ }
187
+ catch (error) {
188
+ // Clean up temp file if it exists
189
+ try {
190
+ await unlink(tempPath);
191
+ }
192
+ catch {
193
+ // Ignore cleanup errors
194
+ }
195
+ throw error;
196
+ }
197
+ }
198
+ // ============ Secure ID Generation ============
199
+ /**
200
+ * Generate a cryptographically secure random ID
201
+ * @param length - Length of the random part
202
+ * @returns Random alphanumeric string
203
+ */
204
+ export function generateSecureId(length) {
205
+ const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
206
+ const bytes = randomBytes(length);
207
+ let result = "";
208
+ for (let i = 0; i < length; i++) {
209
+ // Use modulo to map byte value to character set
210
+ result += chars[bytes[i] % chars.length];
211
+ }
212
+ return result;
213
+ }
122
214
  //# sourceMappingURL=paths.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeliper/zscode-mcp-server",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "ZSCode MCP Server for Claude Code - Project planning and task management",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -15,8 +15,12 @@
15
15
  "build": "tsc",
16
16
  "clean": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"",
17
17
  "dev": "tsc --watch",
18
+ "dev:server": "tsx src/index.ts",
19
+ "dev:watch": "tsx --watch src/index.ts",
18
20
  "start": "node dist/index.js",
19
- "test": "echo \"No tests yet\" && exit 0"
21
+ "test": "vitest run",
22
+ "test:watch": "vitest",
23
+ "test:coverage": "vitest run --coverage"
20
24
  },
21
25
  "dependencies": {
22
26
  "@modelcontextprotocol/sdk": "^1.0.0",
@@ -24,7 +28,10 @@
24
28
  },
25
29
  "devDependencies": {
26
30
  "@types/node": "^20.10.0",
27
- "typescript": "^5.3.0"
31
+ "@vitest/coverage-v8": "^4.0.16",
32
+ "tsx": "^4.7.0",
33
+ "typescript": "^5.3.0",
34
+ "vitest": "^4.0.16"
28
35
  },
29
36
  "peerDependencies": {
30
37
  "zod": "^3.22.0"