cmp-standards 2.0.1 → 2.4.0

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 (110) hide show
  1. package/README.md +171 -101
  2. package/dist/cli/index.js +239 -7
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/dashboard/server.d.ts.map +1 -1
  5. package/dist/dashboard/server.js +203 -39
  6. package/dist/dashboard/server.js.map +1 -1
  7. package/dist/db/cloud.d.ts +174 -0
  8. package/dist/db/cloud.d.ts.map +1 -0
  9. package/dist/db/cloud.js +241 -0
  10. package/dist/db/cloud.js.map +1 -0
  11. package/dist/db/errors.d.ts +76 -0
  12. package/dist/db/errors.d.ts.map +1 -0
  13. package/dist/db/errors.js +135 -0
  14. package/dist/db/errors.js.map +1 -0
  15. package/dist/db/turso-client.d.ts +178 -0
  16. package/dist/db/turso-client.d.ts.map +1 -0
  17. package/dist/db/turso-client.js +455 -0
  18. package/dist/db/turso-client.js.map +1 -0
  19. package/dist/db/upstash-client.d.ts +161 -0
  20. package/dist/db/upstash-client.d.ts.map +1 -0
  21. package/dist/db/upstash-client.js +325 -0
  22. package/dist/db/upstash-client.js.map +1 -0
  23. package/dist/hooks/cloud-post-tool-use.d.ts +30 -0
  24. package/dist/hooks/cloud-post-tool-use.d.ts.map +1 -0
  25. package/dist/hooks/cloud-post-tool-use.js +116 -0
  26. package/dist/hooks/cloud-post-tool-use.js.map +1 -0
  27. package/dist/hooks/cloud-pre-tool-use.d.ts +19 -0
  28. package/dist/hooks/cloud-pre-tool-use.d.ts.map +1 -0
  29. package/dist/hooks/cloud-pre-tool-use.js +149 -0
  30. package/dist/hooks/cloud-pre-tool-use.js.map +1 -0
  31. package/dist/hooks/cloud-session-start.d.ts +20 -0
  32. package/dist/hooks/cloud-session-start.d.ts.map +1 -0
  33. package/dist/hooks/cloud-session-start.js +130 -0
  34. package/dist/hooks/cloud-session-start.js.map +1 -0
  35. package/dist/hooks/index.d.ts +3 -0
  36. package/dist/hooks/index.d.ts.map +1 -1
  37. package/dist/hooks/index.js +5 -0
  38. package/dist/hooks/index.js.map +1 -1
  39. package/dist/hooks/memory-checkpoint.d.ts.map +1 -1
  40. package/dist/hooks/memory-checkpoint.js +12 -20
  41. package/dist/hooks/memory-checkpoint.js.map +1 -1
  42. package/dist/hooks/pre-tool-use.d.ts +2 -8
  43. package/dist/hooks/pre-tool-use.d.ts.map +1 -1
  44. package/dist/hooks/pre-tool-use.js +7 -106
  45. package/dist/hooks/pre-tool-use.js.map +1 -1
  46. package/dist/hooks/session-start.d.ts.map +1 -1
  47. package/dist/hooks/session-start.js +15 -6
  48. package/dist/hooks/session-start.js.map +1 -1
  49. package/dist/index.d.ts +10 -0
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +14 -1
  52. package/dist/index.js.map +1 -1
  53. package/dist/mcp/server.d.ts.map +1 -1
  54. package/dist/mcp/server.js +223 -0
  55. package/dist/mcp/server.js.map +1 -1
  56. package/dist/schema/tracking.d.ts +644 -0
  57. package/dist/schema/tracking.d.ts.map +1 -0
  58. package/dist/schema/tracking.js +204 -0
  59. package/dist/schema/tracking.js.map +1 -0
  60. package/dist/services/ProjectScaffold.d.ts.map +1 -1
  61. package/dist/services/ProjectScaffold.js +33 -5
  62. package/dist/services/ProjectScaffold.js.map +1 -1
  63. package/dist/services/TaskTracker.d.ts +1 -1
  64. package/dist/services/TaskTracker.d.ts.map +1 -1
  65. package/dist/services/TaskTracker.js +4 -8
  66. package/dist/services/TaskTracker.js.map +1 -1
  67. package/dist/services/WorkPlanManager.d.ts +1 -1
  68. package/dist/services/WorkPlanManager.d.ts.map +1 -1
  69. package/dist/services/WorkPlanManager.js +8 -14
  70. package/dist/services/WorkPlanManager.js.map +1 -1
  71. package/dist/services/auto-inject.d.ts +1 -0
  72. package/dist/services/auto-inject.d.ts.map +1 -1
  73. package/dist/services/auto-inject.js +12 -17
  74. package/dist/services/auto-inject.js.map +1 -1
  75. package/dist/services/cross-project-sync.d.ts +2 -0
  76. package/dist/services/cross-project-sync.d.ts.map +1 -1
  77. package/dist/services/cross-project-sync.js +26 -21
  78. package/dist/services/cross-project-sync.js.map +1 -1
  79. package/dist/services/memory-consolidation.d.ts.map +1 -1
  80. package/dist/services/memory-consolidation.js +30 -27
  81. package/dist/services/memory-consolidation.js.map +1 -1
  82. package/dist/utils/env-loader.d.ts +41 -0
  83. package/dist/utils/env-loader.d.ts.map +1 -0
  84. package/dist/utils/env-loader.js +78 -0
  85. package/dist/utils/env-loader.js.map +1 -0
  86. package/dist/utils/git.d.ts +52 -0
  87. package/dist/utils/git.d.ts.map +1 -0
  88. package/dist/utils/git.js +267 -0
  89. package/dist/utils/git.js.map +1 -0
  90. package/dist/utils/paths.d.ts +39 -5
  91. package/dist/utils/paths.d.ts.map +1 -1
  92. package/dist/utils/paths.js +88 -7
  93. package/dist/utils/paths.js.map +1 -1
  94. package/package.json +8 -2
  95. package/standards/README.md +50 -0
  96. package/standards/experts/expert-routing.md +215 -0
  97. package/standards/general/code-quality.md +86 -0
  98. package/standards/general/memory-usage.md +205 -0
  99. package/standards/general/sync-workflow.md +235 -0
  100. package/standards/general/workflow.md +82 -0
  101. package/standards/hooks/mandatory-tracking.md +446 -0
  102. package/standards/infrastructure/cloud-database.md +287 -0
  103. package/standards/mcp/server-design.md +243 -0
  104. package/standards/mcp/tool-patterns.md +354 -0
  105. package/standards/skills/skill-structure.md +286 -0
  106. package/standards/skills/workflow-design.md +323 -0
  107. package/standards/tools/tool-design.md +297 -0
  108. package/templates/claude-settings.json +72 -0
  109. package/templates/memory-config.json +2 -28
  110. package/templates/skills/continue.md +205 -0
@@ -0,0 +1,267 @@
1
+ /**
2
+ * Safe Git Utilities
3
+ *
4
+ * Uses simple-git library instead of exec() to prevent command injection.
5
+ * All paths are validated to prevent directory traversal attacks.
6
+ */
7
+ import { simpleGit } from 'simple-git';
8
+ import path from 'path';
9
+ import fs from 'fs/promises';
10
+ // =============================================================================
11
+ // PATH VALIDATION
12
+ // =============================================================================
13
+ /**
14
+ * Validate that a path is safe and within project bounds
15
+ */
16
+ export async function validateGitPath(projectRoot) {
17
+ // 1. Resolve to absolute path
18
+ const absolutePath = path.resolve(projectRoot);
19
+ // 2. Check if path exists
20
+ try {
21
+ await fs.access(absolutePath);
22
+ }
23
+ catch {
24
+ return false;
25
+ }
26
+ // 3. Prevent path traversal - ensure no .. in resolved path
27
+ const normalizedPath = path.normalize(absolutePath);
28
+ if (normalizedPath.includes('..')) {
29
+ return false;
30
+ }
31
+ // 4. Check if it's a git repository
32
+ try {
33
+ await fs.access(path.join(absolutePath, '.git'));
34
+ return true;
35
+ }
36
+ catch {
37
+ // Could be a subdirectory of a git repo
38
+ return true;
39
+ }
40
+ }
41
+ /**
42
+ * Create a safe git instance for a project
43
+ * Returns null on failure instead of error result for simpler handling
44
+ */
45
+ async function createSafeGit(projectRoot) {
46
+ const isValid = await validateGitPath(projectRoot);
47
+ if (!isValid) {
48
+ return null;
49
+ }
50
+ try {
51
+ const git = simpleGit(projectRoot);
52
+ // Verify it's a git repo
53
+ await git.status();
54
+ return git;
55
+ }
56
+ catch {
57
+ return null;
58
+ }
59
+ }
60
+ /**
61
+ * Get current git branch name
62
+ */
63
+ export async function getCurrentBranch(projectRoot) {
64
+ const git = await createSafeGit(projectRoot);
65
+ if (!git) {
66
+ return { success: false, error: 'Not a valid git repository' };
67
+ }
68
+ try {
69
+ const result = await git.branch();
70
+ return {
71
+ success: true,
72
+ data: result.current,
73
+ };
74
+ }
75
+ catch (error) {
76
+ return {
77
+ success: false,
78
+ error: `Failed to get branch: ${error}`,
79
+ };
80
+ }
81
+ }
82
+ /**
83
+ * Get recently changed files (by comparing commits)
84
+ */
85
+ export async function getRecentChanges(projectRoot, options = {}) {
86
+ const git = await createSafeGit(projectRoot);
87
+ if (!git) {
88
+ return { success: false, error: 'Not a valid git repository' };
89
+ }
90
+ const commits = options.commits ?? 10;
91
+ try {
92
+ // Try to get diff from HEAD~N to HEAD
93
+ try {
94
+ const diff = await git.diff([`HEAD~${commits}`, 'HEAD', '--name-only']);
95
+ const files = diff.trim().split('\n').filter(Boolean);
96
+ return { success: true, data: files };
97
+ }
98
+ catch {
99
+ // Fallback: get unstaged changes
100
+ try {
101
+ const diff = await git.diff(['--name-only']);
102
+ const files = diff.trim().split('\n').filter(Boolean);
103
+ return { success: true, data: files };
104
+ }
105
+ catch {
106
+ return { success: true, data: [] };
107
+ }
108
+ }
109
+ }
110
+ catch (error) {
111
+ return {
112
+ success: false,
113
+ error: `Failed to get recent changes: ${error}`,
114
+ };
115
+ }
116
+ }
117
+ /**
118
+ * Get files changed in the last N time period
119
+ */
120
+ export async function getChangesInPeriod(projectRoot, period = '1.day.ago') {
121
+ const git = await createSafeGit(projectRoot);
122
+ if (!git) {
123
+ return { success: false, error: 'Not a valid git repository' };
124
+ }
125
+ try {
126
+ // First try with time-based ref
127
+ try {
128
+ const log = await git.log([`--since="${period}"`, '--name-only', '--pretty=format:']);
129
+ const files = new Set();
130
+ // Parse log output for file names
131
+ for (const commit of log.all) {
132
+ if (commit.diff) {
133
+ for (const file of commit.diff.files) {
134
+ files.add(file.file);
135
+ }
136
+ }
137
+ }
138
+ if (files.size > 0) {
139
+ return { success: true, data: Array.from(files) };
140
+ }
141
+ }
142
+ catch {
143
+ // Time-based ref not supported, fallback
144
+ }
145
+ // Fallback to last 10 commits
146
+ return getRecentChanges(projectRoot, { commits: 10 });
147
+ }
148
+ catch (error) {
149
+ return {
150
+ success: false,
151
+ error: `Failed to get changes in period: ${error}`,
152
+ };
153
+ }
154
+ }
155
+ /**
156
+ * Helper to safely get insertions/deletions from diff file
157
+ */
158
+ function getFileStats(file) {
159
+ // Binary files don't have insertions/deletions
160
+ if (file.binary) {
161
+ return { insertions: 0, deletions: 0 };
162
+ }
163
+ return {
164
+ insertions: file.insertions ?? 0,
165
+ deletions: file.deletions ?? 0,
166
+ };
167
+ }
168
+ /**
169
+ * Get staged (cached) file changes with stats
170
+ */
171
+ export async function getStagedChanges(projectRoot) {
172
+ const git = await createSafeGit(projectRoot);
173
+ if (!git) {
174
+ return { success: false, error: 'Not a valid git repository' };
175
+ }
176
+ try {
177
+ const diff = await git.diffSummary(['--cached']);
178
+ const changes = diff.files.map(file => {
179
+ const stats = getFileStats(file);
180
+ return {
181
+ path: file.file,
182
+ type: stats.insertions === 0 && stats.deletions > 0
183
+ ? 'delete'
184
+ : stats.deletions === 0 && stats.insertions > 0
185
+ ? 'add'
186
+ : 'modify',
187
+ linesAdded: stats.insertions,
188
+ linesRemoved: stats.deletions,
189
+ };
190
+ });
191
+ return { success: true, data: changes };
192
+ }
193
+ catch (error) {
194
+ return {
195
+ success: false,
196
+ error: `Failed to get staged changes: ${error}`,
197
+ };
198
+ }
199
+ }
200
+ /**
201
+ * Get unstaged file changes with stats
202
+ */
203
+ export async function getUnstagedChanges(projectRoot) {
204
+ const git = await createSafeGit(projectRoot);
205
+ if (!git) {
206
+ return { success: false, error: 'Not a valid git repository' };
207
+ }
208
+ try {
209
+ const diff = await git.diffSummary();
210
+ const changes = diff.files.map(file => {
211
+ const stats = getFileStats(file);
212
+ return {
213
+ path: file.file,
214
+ type: stats.insertions === 0 && stats.deletions > 0
215
+ ? 'delete'
216
+ : stats.deletions === 0 && stats.insertions > 0
217
+ ? 'add'
218
+ : 'modify',
219
+ linesAdded: stats.insertions,
220
+ linesRemoved: stats.deletions,
221
+ };
222
+ });
223
+ return { success: true, data: changes };
224
+ }
225
+ catch (error) {
226
+ return {
227
+ success: false,
228
+ error: `Failed to get unstaged changes: ${error}`,
229
+ };
230
+ }
231
+ }
232
+ /**
233
+ * Get diff between two refs
234
+ */
235
+ export async function getDiffBetweenRefs(projectRoot, fromRef, toRef) {
236
+ const git = await createSafeGit(projectRoot);
237
+ if (!git) {
238
+ return { success: false, error: 'Not a valid git repository' };
239
+ }
240
+ // Validate refs - only allow safe characters
241
+ const safeRefPattern = /^[a-zA-Z0-9_.~^/-]+$/;
242
+ if (!safeRefPattern.test(fromRef) || !safeRefPattern.test(toRef)) {
243
+ return {
244
+ success: false,
245
+ error: 'Invalid ref format',
246
+ };
247
+ }
248
+ try {
249
+ const diff = await git.diff([fromRef, toRef, '--name-only']);
250
+ const files = diff.trim().split('\n').filter(Boolean);
251
+ return { success: true, data: files };
252
+ }
253
+ catch (error) {
254
+ return {
255
+ success: false,
256
+ error: `Failed to get diff: ${error}`,
257
+ };
258
+ }
259
+ }
260
+ /**
261
+ * Check if directory is a git repository
262
+ */
263
+ export async function isGitRepository(projectRoot) {
264
+ const git = await createSafeGit(projectRoot);
265
+ return git !== null;
266
+ }
267
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"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"}
@@ -1,24 +1,58 @@
1
1
  /**
2
- * Path utilities
2
+ * Path Utilities
3
+ *
4
+ * Provides safe path operations with traversal protection.
3
5
  */
6
+ /**
7
+ * Error thrown when path traversal is detected
8
+ */
9
+ export declare class PathTraversalError extends Error {
10
+ constructor(message: string);
11
+ }
12
+ /**
13
+ * Validate a path is safe and doesn't escape the base directory
14
+ *
15
+ * @throws PathTraversalError if path attempts to escape base directory
16
+ */
17
+ export declare function validateSafePath(basePath: string, targetPath: string): string;
18
+ /**
19
+ * Safely join paths with traversal protection
20
+ *
21
+ * @throws PathTraversalError if resulting path escapes base directory
22
+ */
23
+ export declare function safeJoin(basePath: string, ...paths: string[]): string;
24
+ /**
25
+ * Check if a path is safe (doesn't escape base directory)
26
+ */
27
+ export declare function isPathSafe(basePath: string, targetPath: string): boolean;
28
+ /**
29
+ * Sanitize a filename by removing dangerous characters
30
+ */
31
+ export declare function sanitizeFilename(filename: string): string;
32
+ /**
33
+ * Sanitize a path segment (not a full path)
34
+ */
35
+ export declare function sanitizePathSegment(segment: string): string;
4
36
  /**
5
37
  * Find project root by looking for package.json or .git
6
38
  */
7
39
  export declare function getProjectRoot(startDir?: string): Promise<string>;
8
40
  /**
9
- * Resolve a path relative to project root
41
+ * Resolve a path relative to project root with traversal protection
42
+ *
43
+ * @throws PathTraversalError if path escapes project root
10
44
  */
11
45
  export declare function resolveProjectPath(projectRoot: string, relativePath: string): string;
12
46
  /**
13
- * Get .claude directory path
47
+ * Get .claude directory path (safe - fixed subpath)
14
48
  */
15
49
  export declare function getClaudeDir(projectRoot: string): string;
16
50
  /**
17
- * Get hooks directory path
51
+ * Get hooks directory path (safe - fixed subpath)
18
52
  */
19
53
  export declare function getHooksDir(projectRoot: string): string;
20
54
  /**
21
- * Get knowledge directory path
55
+ * Get knowledge directory path (safe - fixed subpath)
22
56
  */
23
57
  export declare function getKnowledgeDir(projectRoot: string): string;
24
58
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;GAEG;AACH,wBAAsB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBvE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAS5E"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAa7E;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAGrE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAOxE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOzD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAM3D;AAMD;;GAEG;AACH,wBAAsB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BvE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAS5E"}
@@ -1,13 +1,92 @@
1
1
  /**
2
- * Path utilities
2
+ * Path Utilities
3
+ *
4
+ * Provides safe path operations with traversal protection.
3
5
  */
4
6
  import fs from 'fs/promises';
5
7
  import path from 'path';
8
+ // =============================================================================
9
+ // PATH VALIDATION & SECURITY
10
+ // =============================================================================
11
+ /**
12
+ * Error thrown when path traversal is detected
13
+ */
14
+ export class PathTraversalError extends Error {
15
+ constructor(message) {
16
+ super(message);
17
+ this.name = 'PathTraversalError';
18
+ }
19
+ }
20
+ /**
21
+ * Validate a path is safe and doesn't escape the base directory
22
+ *
23
+ * @throws PathTraversalError if path attempts to escape base directory
24
+ */
25
+ export function validateSafePath(basePath, targetPath) {
26
+ // Resolve both paths to absolute
27
+ const resolvedBase = path.resolve(basePath);
28
+ const resolvedTarget = path.resolve(basePath, targetPath);
29
+ // Ensure target is within base (prevents ../ attacks)
30
+ if (!resolvedTarget.startsWith(resolvedBase + path.sep) && resolvedTarget !== resolvedBase) {
31
+ throw new PathTraversalError(`Path traversal detected: "${targetPath}" escapes base directory "${basePath}"`);
32
+ }
33
+ return resolvedTarget;
34
+ }
35
+ /**
36
+ * Safely join paths with traversal protection
37
+ *
38
+ * @throws PathTraversalError if resulting path escapes base directory
39
+ */
40
+ export function safeJoin(basePath, ...paths) {
41
+ const joined = path.join(...paths);
42
+ return validateSafePath(basePath, joined);
43
+ }
44
+ /**
45
+ * Check if a path is safe (doesn't escape base directory)
46
+ */
47
+ export function isPathSafe(basePath, targetPath) {
48
+ try {
49
+ validateSafePath(basePath, targetPath);
50
+ return true;
51
+ }
52
+ catch {
53
+ return false;
54
+ }
55
+ }
56
+ /**
57
+ * Sanitize a filename by removing dangerous characters
58
+ */
59
+ export function sanitizeFilename(filename) {
60
+ // Remove path separators and null bytes
61
+ return filename
62
+ .replace(/[/\\]/g, '_')
63
+ .replace(/\0/g, '')
64
+ .replace(/\.\./g, '__')
65
+ .trim();
66
+ }
67
+ /**
68
+ * Sanitize a path segment (not a full path)
69
+ */
70
+ export function sanitizePathSegment(segment) {
71
+ return segment
72
+ .replace(/\.\./g, '')
73
+ .replace(/[<>:"|?*]/g, '_')
74
+ .replace(/\0/g, '')
75
+ .trim();
76
+ }
77
+ // =============================================================================
78
+ // PROJECT ROOT DETECTION
79
+ // =============================================================================
6
80
  /**
7
81
  * Find project root by looking for package.json or .git
8
82
  */
9
83
  export async function getProjectRoot(startDir) {
10
- let currentDir = startDir || process.cwd();
84
+ // Validate startDir if provided
85
+ let currentDir = startDir ? path.resolve(startDir) : process.cwd();
86
+ // Prevent null byte injection
87
+ if (currentDir.includes('\0')) {
88
+ throw new PathTraversalError('Null byte detected in path');
89
+ }
11
90
  while (currentDir !== path.parse(currentDir).root) {
12
91
  // Check for package.json
13
92
  try {
@@ -30,25 +109,27 @@ export async function getProjectRoot(startDir) {
30
109
  return process.cwd();
31
110
  }
32
111
  /**
33
- * Resolve a path relative to project root
112
+ * Resolve a path relative to project root with traversal protection
113
+ *
114
+ * @throws PathTraversalError if path escapes project root
34
115
  */
35
116
  export function resolveProjectPath(projectRoot, relativePath) {
36
- return path.resolve(projectRoot, relativePath);
117
+ return validateSafePath(projectRoot, relativePath);
37
118
  }
38
119
  /**
39
- * Get .claude directory path
120
+ * Get .claude directory path (safe - fixed subpath)
40
121
  */
41
122
  export function getClaudeDir(projectRoot) {
42
123
  return path.join(projectRoot, '.claude');
43
124
  }
44
125
  /**
45
- * Get hooks directory path
126
+ * Get hooks directory path (safe - fixed subpath)
46
127
  */
47
128
  export function getHooksDir(projectRoot) {
48
129
  return path.join(projectRoot, '.claude', 'hooks');
49
130
  }
50
131
  /**
51
- * Get knowledge directory path
132
+ * Get knowledge directory path (safe - fixed subpath)
52
133
  */
53
134
  export function getKnowledgeDir(projectRoot) {
54
135
  return path.join(projectRoot, '.claude', 'knowledge');
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,aAAa,CAAA;AAC5B,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAiB;IACpD,IAAI,UAAU,GAAG,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IAE1C,OAAO,UAAU,KAAK,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,yBAAyB;QACzB,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAA;YACtD,OAAO,UAAU,CAAA;QACnB,CAAC;QAAC,MAAM,CAAC;YACP,iBAAiB;YACjB,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAA;gBAC9C,OAAO,UAAU,CAAA;YACnB,CAAC;YAAC,MAAM,CAAC;gBACP,qBAAqB;YACvB,CAAC;QACH,CAAC;QAED,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IACvC,CAAC;IAED,gCAAgC;IAChC,OAAO,OAAO,CAAC,GAAG,EAAE,CAAA;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB,EAAE,YAAoB;IAC1E,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,YAAY,CAAC,CAAA;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,WAAmB;IAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;AAC1C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,WAAmB;IAC7C,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,CAAA;AACnD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,QAAkB;IACjE,2CAA2C;IAC3C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;QAClC,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,IAAY;IAC/B,MAAM,OAAO,GAAG,IAAI;SACjB,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC;SACpC,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC;SAChC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;SACvB,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC,CAAA;IAEjC,OAAO,IAAI,MAAM,CAAC,IAAI,OAAO,GAAG,CAAC,CAAA;AACnC,CAAC"}
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": "cmp-standards",
3
- "version": "2.0.1",
3
+ "version": "2.4.0",
4
4
  "type": "module",
5
5
  "description": "Unified standards, memory, ESLint rules & workflow system for Claude Code projects",
6
6
  "main": "dist/index.js",
@@ -41,7 +41,10 @@
41
41
  "node": ">=18.0.0"
42
42
  },
43
43
  "dependencies": {
44
+ "@libsql/client": "^0.14.0",
44
45
  "@modelcontextprotocol/sdk": "^0.5.0",
46
+ "@upstash/redis": "^1.34.0",
47
+ "@upstash/vector": "^1.1.0",
45
48
  "chalk": "^5.3.0",
46
49
  "commander": "^12.0.0",
47
50
  "cors": "^2.8.5",
@@ -52,7 +55,9 @@
52
55
  "gray-matter": "^4.0.3",
53
56
  "mysql2": ">=3.0.0",
54
57
  "open": "^10.0.0",
55
- "ulid": "^2.3.0"
58
+ "simple-git": "^3.30.0",
59
+ "ulid": "^2.3.0",
60
+ "zod": "^3.23.0"
56
61
  },
57
62
  "peerDependencies": {
58
63
  "drizzle-orm": ">=0.30.0",
@@ -72,6 +77,7 @@
72
77
  "files": [
73
78
  "dist",
74
79
  "templates",
80
+ "standards",
75
81
  "README.md"
76
82
  ],
77
83
  "exports": {
@@ -0,0 +1,50 @@
1
+ # CMP Standards
2
+
3
+ Estándares globales para proyectos con Claude Code. Estos estándares son **adaptados inteligentemente** por la IA a cada proyecto local.
4
+
5
+ ## Estructura
6
+
7
+ ```
8
+ standards/
9
+ ├── general/ # Cómo trabajar en general
10
+ │ ├── workflow.md # Flujo de trabajo con Claude
11
+ │ ├── code-quality.md # Estándares de código
12
+ │ ├── memory-usage.md # Uso del sistema de memoria
13
+ │ └── sync-workflow.md # Cómo funciona el sync inteligente
14
+
15
+ ├── mcp/ # Model Context Protocol
16
+ │ ├── server-design.md
17
+ │ └── tool-patterns.md
18
+
19
+ ├── tools/ # Diseño de herramientas
20
+ │ └── tool-design.md
21
+
22
+ ├── skills/ # Sistema de skills
23
+ │ ├── skill-structure.md
24
+ │ └── workflow-design.md
25
+
26
+ ├── experts/ # Sistema de expertos
27
+ │ └── expert-routing.md
28
+
29
+ ├── hooks/ # Hooks obligatorios
30
+ │ └── mandatory-tracking.md # Sistema de tracking continuo
31
+
32
+ └── infrastructure/ # Infraestructura cloud
33
+ └── cloud-database.md # Turso + Upstash (gratis)
34
+ ```
35
+
36
+ ## Cómo funciona el Sync
37
+
38
+ 1. **AI lee** estos estándares globales
39
+ 2. **AI analiza** el proyecto local (estructura, tech stack, CLAUDE.md existente)
40
+ 3. **AI adapta** los estándares al contexto local
41
+ 4. **AI actualiza** el CLAUDE.md local con lo relevante
42
+
43
+ ## Uso
44
+
45
+ ```bash
46
+ # El sync se invoca como skill
47
+ /sync
48
+ ```
49
+
50
+ La IA ejecuta el sync de forma inteligente, no es un script.