@claudetools/tools 0.7.0 → 0.7.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.
@@ -3,6 +3,7 @@
3
3
  // =============================================================================
4
4
  import { mcpLogger } from '../logger.js';
5
5
  import * as fs from 'fs';
6
+ import * as path from 'path';
6
7
  import { getConfig, getConfigDir, getProjectsPath, } from './config-manager.js';
7
8
  import { getOrRegisterProject } from './project-registration.js';
8
9
  // Configuration - now loaded from config manager
@@ -10,6 +11,28 @@ const config = getConfig();
10
11
  export const API_BASE_URL = config.apiUrl;
11
12
  export const CLAUDETOOLS_DIR = getConfigDir();
12
13
  export const PROJECTS_FILE = getProjectsPath();
14
+ const SESSION_CONTEXT_FILE = path.join(CLAUDETOOLS_DIR, 'session-context.md');
15
+ /**
16
+ * Read project ID from session-context.md (written by session-start hook)
17
+ * This is the most reliable source since it's set by Claude Code's hook system
18
+ */
19
+ function getProjectIdFromSessionContext() {
20
+ try {
21
+ if (!fs.existsSync(SESSION_CONTEXT_FILE)) {
22
+ return null;
23
+ }
24
+ const content = fs.readFileSync(SESSION_CONTEXT_FILE, 'utf-8');
25
+ // Parse: **Project ID:** proj_xxxxx
26
+ const match = content.match(/\*\*Project ID:\*\*\s*(proj_[a-f0-9]{20})/);
27
+ if (match) {
28
+ return match[1];
29
+ }
30
+ return null;
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ }
13
36
  // Cache for resolved project ID
14
37
  let resolvedProjectId = null;
15
38
  /**
@@ -93,6 +116,14 @@ export async function resolveProjectIdAsync() {
93
116
  mcpLogger.debug('MEMORY', `Using project ID from env: ${resolvedProjectId}`);
94
117
  return resolvedProjectId;
95
118
  }
119
+ // Check session-context.md (written by Claude Code's session-start hook)
120
+ // This is the most reliable source since MCP server's cwd isn't the project dir
121
+ const sessionProjectId = getProjectIdFromSessionContext();
122
+ if (sessionProjectId) {
123
+ resolvedProjectId = sessionProjectId;
124
+ mcpLogger.info('MEMORY', `Project resolved from session context: ${resolvedProjectId}`);
125
+ return resolvedProjectId;
126
+ }
96
127
  const cwd = process.cwd();
97
128
  // Check projects.json cache
98
129
  const binding = findProjectBinding(cwd);
@@ -134,13 +165,19 @@ export async function resolveProjectIdAsync() {
134
165
  let _defaultProjectId = null;
135
166
  /**
136
167
  * Gets the default project ID (synchronous version)
137
- * Throws if not already resolved - call resolveProjectIdAsync() first
168
+ * Checks session-context.md first, then config, then falls back to cwd resolution
138
169
  */
139
170
  export function getDefaultProjectId() {
140
171
  if (_defaultProjectId) {
141
172
  return _defaultProjectId;
142
173
  }
143
- // Try config first
174
+ // Check session-context.md first (most reliable for MCP server)
175
+ const sessionProjectId = getProjectIdFromSessionContext();
176
+ if (sessionProjectId) {
177
+ _defaultProjectId = sessionProjectId;
178
+ return _defaultProjectId;
179
+ }
180
+ // Try config second
144
181
  if (config.defaultProjectId) {
145
182
  if (!isValidProjectId(config.defaultProjectId)) {
146
183
  // Legacy format - convert to local_ format instead of throwing
@@ -37,11 +37,17 @@ When complete, provide a concise summary of changes made.`,
37
37
  - Response formatting
38
38
  - Error handling for endpoints
39
39
 
40
- CODEDNA PRIORITY: Before writing CRUD code manually, check if CodeDNA can generate it:
41
- - Look for Entity DSL in task (e.g., "User(email:string:unique, password:string:hashed)")
42
- - Call codedna_generate_api(spec, framework="express", options={...})
43
- - This generates models, controllers, routes, validation in seconds
44
- - Only write manually for complex business logic that can't be generated
40
+ PATTERN DETECTION (for existing projects):
41
+ 1. Call codedna_detect_patterns(package_json) to find existing patterns
42
+ 2. MATCH detected patterns - don't introduce conflicting libraries
43
+ 3. Check for: zod vs yup validation, tanstack-query vs swr, etc.
44
+
45
+ CODEDNA PRIORITY: Before writing CRUD code manually:
46
+ 1. Call codedna_list_generators() to discover available generators
47
+ 2. Look for Entity DSL in task (e.g., "User(email:string:unique, password:string:hashed)")
48
+ 3. Detect framework from project (check package.json, existing patterns)
49
+ 4. Call codedna_generate_api(spec, framework="<detected>", options={...})
50
+ 5. Only write manually for complex business logic that can't be generated
45
51
 
46
52
  Focus only on API-related changes. Do not modify schema or extraction code.
47
53
  When complete, provide a concise summary of endpoints created or modified.`,
@@ -99,6 +105,40 @@ TOOLS: Use codebase_context to see file dependencies.
99
105
 
100
106
  Focus on integration without modifying core implementation logic.
101
107
  When complete, provide a concise summary of integrations configured.`,
108
+ },
109
+ 'frontend-expert': {
110
+ id: 'frontend-expert',
111
+ name: 'Frontend Expert',
112
+ description: 'Specialises in React, Vue, and frontend component development',
113
+ domains: ['**/components/**', '**/pages/**', '**/app/**', '**/*.tsx', '**/*.vue'],
114
+ capabilities: ['react', 'vue', 'components', 'forms', 'tables', 'styling'],
115
+ promptTemplate: `You are a frontend development expert. Your domain is limited to:
116
+ - React/Vue components and pages
117
+ - Form and table components
118
+ - UI component libraries
119
+ - Client-side state management
120
+
121
+ PATTERN DETECTION (CRITICAL for existing projects):
122
+ 1. Call codedna_detect_patterns(package_json) to detect existing patterns
123
+ 2. RESPECT detected patterns - consistency > "better":
124
+ - Compound components? Use compound pattern
125
+ - React Hook Form? Don't introduce Formik
126
+ - Zustand? Don't add Redux
127
+ - Tailwind? Match styling approach
128
+ 3. Check codedna_list_patterns(category="anti-patterns") for code smells to avoid
129
+
130
+ CODEDNA PRIORITY: Before writing UI components manually:
131
+ 1. Call codedna_list_generators() to discover available generators
132
+ 2. Detect UI framework from project (check package.json for react, vue, etc.)
133
+ 3. Check for UI library (package.json: @shadcn/ui, @mui/material, @chakra-ui, etc.)
134
+ 4. Call codedna_generate_frontend or codedna_generate_component with detected settings
135
+ 5. DO NOT assume any specific framework/library - discover via list_generators, detect from project
136
+
137
+ TOOLS: Use codebase_find to discover existing component patterns.
138
+ TOOLS: Use memory_search for past UI decisions.
139
+
140
+ Focus on components and pages. Do not modify API or schema code.
141
+ When complete, provide a concise summary of components created.`,
102
142
  },
103
143
  'general-expert': {
104
144
  id: 'general-expert',
@@ -108,7 +148,13 @@ When complete, provide a concise summary of integrations configured.`,
108
148
  capabilities: ['general-development', 'refactoring', 'documentation', 'testing'],
109
149
  promptTemplate: `You are a general purpose development expert.
110
150
 
111
- CODEDNA: For CRUD/API tasks, use codedna_generate_api before writing code manually.
151
+ CODEDNA - DISCOVER THEN DETECT:
152
+ 1. Call codedna_list_generators() to see what's available
153
+ 2. Detect project framework from package.json/pyproject.toml
154
+ 3. Match detected framework to generator capabilities
155
+ 4. If no match, ASK the user which framework to use
156
+ 5. DO NOT assume any specific framework exists - always discover first
157
+
112
158
  TOOLS: Use memory_search and codebase_find before implementing from scratch.
113
159
 
114
160
  Handle this task with care:
@@ -267,7 +313,6 @@ export function matchTaskToWorker(task) {
267
313
  'database': 'schema-expert',
268
314
  'sql': 'schema-expert',
269
315
  'migration': 'schema-expert',
270
- 'table': 'schema-expert',
271
316
  'api': 'api-expert',
272
317
  'route': 'api-expert',
273
318
  'endpoint': 'api-expert',
@@ -282,6 +327,14 @@ export function matchTaskToWorker(task) {
282
327
  'integration': 'integration-expert',
283
328
  'config': 'integration-expert',
284
329
  'wiring': 'integration-expert',
330
+ 'component': 'frontend-expert',
331
+ 'frontend': 'frontend-expert',
332
+ 'react': 'frontend-expert',
333
+ 'vue': 'frontend-expert',
334
+ 'form': 'frontend-expert',
335
+ 'table': 'frontend-expert',
336
+ 'page': 'frontend-expert',
337
+ 'ui': 'frontend-expert',
285
338
  };
286
339
  for (const [keyword, workerId] of Object.entries(keywordMap)) {
287
340
  if (searchText.includes(keyword)) {
@@ -187,15 +187,23 @@ export function buildOrchestratorPrompt(params) {
187
187
  - general-expert: Tasks that don't fit other domains`}
188
188
  </available_workers>
189
189
 
190
- <codedna_generators>
191
- Workers have access to CodeDNA generators that create production code from Entity DSL:
190
+ <codedna_generators priority="CRITICAL">
191
+ CodeDNA generates production code from Entity DSL - workers MUST check availability first.
192
192
 
193
- - codedna_generate_api: Creates CRUD API (Express, FastAPI, NestJS)
194
- Generates: models, controllers, routes, validation, auth middleware, tests
195
- Token savings: 95-99% vs manual coding
193
+ BEFORE creating any task involving APIs, CRUD, or UI components:
194
+ 1. Workers should call codedna_list_generators() to see available generators
195
+ 2. If a generator exists, use it instead of writing code manually
196
196
 
197
- When your tasks involve CRUD operations, define entities using DSL format.
198
- Workers will use CodeDNA automatically.
197
+ AVAILABLE DOMAINS:
198
+ - api: Express, FastAPI, NestJS (full CRUD with auth, validation, tests)
199
+ - frontend: React/Next.js, Vue 3 (pages, forms, tables)
200
+ - component: Forms, tables, cards, modals (React, Vue, Svelte)
201
+
202
+ INCLUDE IN TASK DESCRIPTIONS:
203
+ When tasks involve entities, include the DSL spec so workers know to use CodeDNA:
204
+ "Create user registration. Entity: User(email:string:unique, password:string:hashed)"
205
+
206
+ Token savings: 95-99% vs manual coding
199
207
  </codedna_generators>
200
208
 
201
209
  ${epicTitle ? `<epic_context>
@@ -71,16 +71,18 @@ function buildBehavioralSection(taskId) {
71
71
  <behavior id="codedna_first" priority="MANDATORY">
72
72
  BEFORE writing code manually, check if CodeDNA can generate it:
73
73
 
74
- FOR CRUD/API operations:
75
- Use codedna_generate_api(spec, framework, options)
74
+ DISCOVERY WORKFLOW:
75
+ 1. Call codedna_list_generators() to see available generators
76
+ 2. Check if task includes Entity DSL format
77
+ Example: "User(email:string:unique, password:string:hashed)"
78
+ 3. Detect framework from project (package.json, existing code)
79
+ 4. Match detected framework to generator capabilities
80
+ 5. Call appropriate generator with detected settings
81
+
82
+ BENEFITS:
76
83
  → Saves 95-99% tokens vs manual coding
77
84
  → Generates production-ready code with validation, auth, tests
78
85
 
79
- FOR Entity definitions:
80
- → Check if task includes Entity DSL format
81
- → Example: "User(email:string:unique, password:string:hashed)"
82
- → Call codedna_generate_api with the spec
83
-
84
86
  ONLY write code manually when:
85
87
  - Logic is too complex for generation
86
88
  - Modifying existing code (not creating new)
@@ -177,16 +179,12 @@ function buildDomainSection(worker) {
177
179
  return `<!-- Layer 4: Domain Knowledge -->
178
180
  <domain_knowledge>
179
181
  <codedna_capabilities>
180
- AVAILABLE GENERATORS:
181
-
182
- 1. codedna_generate_api(spec, framework, options)
183
- - Frameworks: "express", "fastapi", "nestjs"
184
- - Options: { auth: true, validation: true, tests: true }
185
- - Generates: model, controller, routes, validation, auth, tests
186
-
187
- 2. codedna_validate_spec(spec)
188
- - Validates Entity DSL syntax before generation
189
- - Returns parsed structure or errors
182
+ CODEDNA DISCOVERY PATTERN:
183
+ 1. Call codedna_list_generators() to see available generators
184
+ 2. Each generator lists supported frameworks and options
185
+ 3. Detect project framework from package.json/pyproject.toml
186
+ 4. Match detected framework to generator capabilities
187
+ 5. If no match, ASK the user which framework to use
190
188
 
191
189
  ENTITY DSL FORMAT:
192
190
  EntityName(field:type:constraint, field:type:constraint, ...)
@@ -197,20 +195,15 @@ function buildDomainSection(worker) {
197
195
  - enum(val1|val2|val3) - enumeration
198
196
 
199
197
  CONSTRAINTS:
200
- - unique - unique constraint
201
- - required - not null
202
- - min(n), max(n) - numeric bounds
203
- - hashed - for passwords (auto bcrypt)
204
- - default(value) - default value
205
-
206
- EXAMPLE:
207
- codedna_generate_api({
208
- spec: "User(email:string:unique:required, password:string:hashed, role:enum(admin|user|guest), created_at:datetime:default(now))",
209
- framework: "express",
210
- options: { auth: true, validation: true }
211
- })
212
- → Generates 6 production files in ~5 seconds
213
- → Saves ~30,000 tokens vs manual implementation
198
+ - unique, required, min(n), max(n), hashed, default(value)
199
+ - UI hints: textarea, switch, radio (for form rendering)
200
+
201
+ WORKFLOW:
202
+ 1. codedna_list_generators() discover capabilities
203
+ 2. codedna_validate_spec(spec) → validate DSL syntax
204
+ 3. codedna_generate_*(spec, framework, options) → generate code
205
+
206
+ DO NOT assume frameworks exist - always discover via codedna_list_generators
214
207
  </codedna_capabilities>
215
208
 
216
209
  <worker_expertise>
package/dist/tools.js CHANGED
@@ -952,6 +952,10 @@ export function registerToolDefinitions(server) {
952
952
  },
953
953
  },
954
954
  },
955
+ package_json: {
956
+ type: 'object',
957
+ description: 'Optional: package.json content for pattern detection. If provided, generator will detect patterns (zod, yup, etc.) and use matching template variants.',
958
+ },
955
959
  },
956
960
  required: ['spec', 'framework'],
957
961
  },
@@ -993,6 +997,10 @@ export function registerToolDefinitions(server) {
993
997
  },
994
998
  },
995
999
  },
1000
+ package_json: {
1001
+ type: 'object',
1002
+ description: 'Optional: package.json content for pattern detection. Detects React Hook Form, Zod, TanStack Query, etc. and uses matching template variants.',
1003
+ },
996
1004
  },
997
1005
  required: ['spec', 'framework'],
998
1006
  },
@@ -1031,16 +1039,26 @@ export function registerToolDefinitions(server) {
1031
1039
  },
1032
1040
  },
1033
1041
  },
1042
+ package_json: {
1043
+ type: 'object',
1044
+ description: 'Optional: package.json content for pattern detection. Detects form libraries, validation tools, etc. and uses matching template variants.',
1045
+ },
1034
1046
  },
1035
1047
  required: ['spec', 'type', 'framework'],
1036
1048
  },
1037
1049
  },
1038
1050
  {
1039
1051
  name: 'codedna_list_generators',
1040
- description: 'List all available code generators and their capabilities.',
1052
+ description: 'CALL THIS BEFORE writing any API, CRUD, or UI component code. Lists available code generators that save 95-99% tokens vs manual coding. Returns generators grouped by domain (api/frontend/component) with their capabilities. If a generator exists for your task, use codedna_generate_* instead of writing code manually.',
1041
1053
  inputSchema: {
1042
1054
  type: 'object',
1043
- properties: {},
1055
+ properties: {
1056
+ domain: {
1057
+ type: 'string',
1058
+ enum: ['api', 'frontend', 'component'],
1059
+ description: 'Filter by domain: "api" for backend APIs, "frontend" for full frontend apps, "component" for individual UI components',
1060
+ },
1061
+ },
1044
1062
  },
1045
1063
  },
1046
1064
  {
@@ -1057,6 +1075,87 @@ export function registerToolDefinitions(server) {
1057
1075
  required: ['spec'],
1058
1076
  },
1059
1077
  },
1078
+ // =========================================================================
1079
+ // CodeDNA Pattern Library Tools
1080
+ // =========================================================================
1081
+ {
1082
+ name: 'codedna_list_patterns',
1083
+ description: 'List coding patterns from the library. Returns best practices (compound components, TanStack Query, Zod) and anti-patterns to avoid (prop drilling, useEffect fetch). Use to understand what patterns are available for a project.',
1084
+ inputSchema: {
1085
+ type: 'object',
1086
+ properties: {
1087
+ category: {
1088
+ type: 'string',
1089
+ enum: ['components', 'hooks', 'forms', 'state', 'validation', 'styling', 'anti-patterns'],
1090
+ description: 'Filter by category',
1091
+ },
1092
+ recommended_only: {
1093
+ type: 'boolean',
1094
+ description: 'Only return recommended best-practice patterns',
1095
+ },
1096
+ include_anti_patterns: {
1097
+ type: 'boolean',
1098
+ description: 'Include anti-patterns in results (default: true)',
1099
+ },
1100
+ },
1101
+ },
1102
+ },
1103
+ {
1104
+ name: 'codedna_get_pattern',
1105
+ description: 'Get detailed documentation for a specific pattern including code examples, when to use/avoid, and migration guides. Use after codedna_list_patterns to get full details.',
1106
+ inputSchema: {
1107
+ type: 'object',
1108
+ properties: {
1109
+ pattern_id: {
1110
+ type: 'string',
1111
+ description: 'Pattern ID (e.g., "compound-components", "tanstack-query", "prop-drilling")',
1112
+ },
1113
+ },
1114
+ required: ['pattern_id'],
1115
+ },
1116
+ },
1117
+ {
1118
+ name: 'codedna_detect_patterns',
1119
+ description: 'Detect which patterns are used in an existing codebase. Analyzes package.json dependencies and code samples to identify patterns and anti-patterns. Use before making changes to understand project conventions.',
1120
+ inputSchema: {
1121
+ type: 'object',
1122
+ properties: {
1123
+ package_json: {
1124
+ type: 'object',
1125
+ description: 'The project package.json object (with dependencies/devDependencies)',
1126
+ },
1127
+ code_samples: {
1128
+ type: 'array',
1129
+ items: { type: 'string' },
1130
+ description: 'Code snippets to analyze for pattern signals',
1131
+ },
1132
+ },
1133
+ },
1134
+ },
1135
+ {
1136
+ name: 'codedna_init_project',
1137
+ description: 'Initialize a project with recommended patterns. For NEW projects, applies best-practice defaults. For EXISTING projects, use with auto_detect to match existing conventions.',
1138
+ inputSchema: {
1139
+ type: 'object',
1140
+ properties: {
1141
+ project_id: {
1142
+ type: 'string',
1143
+ description: 'Project ID from claudetools',
1144
+ },
1145
+ patterns: {
1146
+ type: 'array',
1147
+ items: { type: 'string' },
1148
+ description: 'Specific pattern IDs to apply (optional - uses recommended if not specified)',
1149
+ },
1150
+ project_type: {
1151
+ type: 'string',
1152
+ enum: ['new', 'existing'],
1153
+ description: '"new" for greenfield (uses recommended), "existing" for updating (detects patterns)',
1154
+ },
1155
+ },
1156
+ required: ['project_id'],
1157
+ },
1158
+ },
1060
1159
  ],
1061
1160
  }));
1062
1161
  }
package/dist/watcher.js CHANGED
@@ -4,7 +4,9 @@
4
4
  // Monitors project directories for changes and syncs with the API
5
5
  import { homedir } from 'os';
6
6
  import { join } from 'path';
7
- import { existsSync, readFileSync, writeFileSync, unlinkSync, watch, readdirSync, statSync } from 'fs';
7
+ import { existsSync, readFileSync, writeFileSync, unlinkSync, watch, readdirSync, statSync, mkdirSync } from 'fs';
8
+ import { getProjectTemplate, SECTION_START } from './templates/claude-md.js';
9
+ import { generateCodebaseMap } from './helpers/codebase-mapper.js';
8
10
  // -----------------------------------------------------------------------------
9
11
  // Constants
10
12
  // -----------------------------------------------------------------------------
@@ -136,6 +138,94 @@ function discoverProjects(directories) {
136
138
  }
137
139
  return projects;
138
140
  }
141
+ /**
142
+ * Ensures .claude/CLAUDE.md exists for a project
143
+ * Creates it if missing, using the project template
144
+ */
145
+ function ensureProjectClaudeMd(projectPath, projectId, projectName) {
146
+ const claudeDir = join(projectPath, '.claude');
147
+ const claudeMdPath = join(claudeDir, 'CLAUDE.md');
148
+ // Skip if CLAUDE.md already exists with claudetools section
149
+ if (existsSync(claudeMdPath)) {
150
+ try {
151
+ const content = readFileSync(claudeMdPath, 'utf-8');
152
+ if (content.includes(SECTION_START)) {
153
+ return false; // Already has claudetools section
154
+ }
155
+ // Has CLAUDE.md but no claudetools section - append it
156
+ const template = getProjectTemplate(projectId, projectName);
157
+ writeFileSync(claudeMdPath, content.trimEnd() + '\n' + template);
158
+ log('info', `Added ClaudeTools section to existing CLAUDE.md: ${projectPath}`);
159
+ return true;
160
+ }
161
+ catch {
162
+ return false;
163
+ }
164
+ }
165
+ // Create .claude directory if needed
166
+ if (!existsSync(claudeDir)) {
167
+ try {
168
+ mkdirSync(claudeDir, { recursive: true });
169
+ }
170
+ catch (err) {
171
+ log('warn', `Could not create .claude directory for ${projectPath}: ${err}`);
172
+ return false;
173
+ }
174
+ }
175
+ // Create CLAUDE.md with template
176
+ try {
177
+ const template = getProjectTemplate(projectId, projectName);
178
+ writeFileSync(claudeMdPath, template);
179
+ log('info', `Created CLAUDE.md for project: ${projectPath}`);
180
+ return true;
181
+ }
182
+ catch (err) {
183
+ log('warn', `Could not create CLAUDE.md for ${projectPath}: ${err}`);
184
+ return false;
185
+ }
186
+ }
187
+ /**
188
+ * Ensures all synced projects have CLAUDE.md files
189
+ */
190
+ function ensureAllProjectsHaveClaudeMd(bindings) {
191
+ let created = 0;
192
+ for (const binding of bindings) {
193
+ if (binding.local_path && binding.project_id) {
194
+ if (ensureProjectClaudeMd(binding.local_path, binding.project_id, binding.project_name || 'Unknown')) {
195
+ created++;
196
+ }
197
+ }
198
+ }
199
+ if (created > 0) {
200
+ log('info', `Created CLAUDE.md for ${created} projects`);
201
+ }
202
+ }
203
+ /**
204
+ * Generate codebase maps for all synced projects
205
+ */
206
+ async function generateMapsForProjects(bindings, apiKey) {
207
+ let generated = 0;
208
+ for (const binding of bindings) {
209
+ if (binding.local_path && binding.project_id) {
210
+ try {
211
+ log('info', `Generating codebase map for ${binding.project_name || binding.local_path}...`);
212
+ const result = await generateCodebaseMap(binding.local_path, binding.project_id, apiKey);
213
+ if (result.success) {
214
+ generated++;
215
+ }
216
+ else {
217
+ log('warn', `Map generation failed for ${binding.project_name}: ${result.error}`);
218
+ }
219
+ }
220
+ catch (err) {
221
+ log('warn', `Map generation error for ${binding.project_name}: ${err}`);
222
+ }
223
+ }
224
+ }
225
+ if (generated > 0) {
226
+ log('info', `Generated codebase maps for ${generated} projects`);
227
+ }
228
+ }
139
229
  // -----------------------------------------------------------------------------
140
230
  // API Sync
141
231
  // -----------------------------------------------------------------------------
@@ -166,6 +256,12 @@ async function syncProjectsWithAPI(config, system, projects) {
166
256
  projectsData.bindings = data.bindings;
167
257
  projectsData.last_sync = new Date().toISOString();
168
258
  writeFileSync(PROJECTS_FILE, JSON.stringify(projectsData, null, 2));
259
+ // Auto-create CLAUDE.md for all synced projects
260
+ ensureAllProjectsHaveClaudeMd(data.bindings);
261
+ // Generate codebase maps for all projects (async, don't block)
262
+ generateMapsForProjects(data.bindings, config.apiKey).catch((err) => {
263
+ log('warn', `Map generation failed: ${err}`);
264
+ });
169
265
  }
170
266
  log('info', `Synced ${projects.length} projects with API`);
171
267
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claudetools/tools",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Persistent AI memory, task management, and codebase intelligence for Claude Code",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -59,7 +59,8 @@
59
59
  "chalk": "^5.6.2",
60
60
  "nunjucks": "^3.2.4",
61
61
  "ora": "^9.0.0",
62
- "prompts": "^2.4.2"
62
+ "prompts": "^2.4.2",
63
+ "typescript": "^5.3.0"
63
64
  },
64
65
  "devDependencies": {
65
66
  "@types/node": "^20.10.0",