create-universal-ai-context 2.2.2 → 2.3.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.
@@ -73,7 +73,9 @@ async function generate(analysis, config, projectRoot) {
73
73
  result.files.push(...claudeDirResult);
74
74
  }
75
75
 
76
- result.success = result.errors.length === 0 || result.errors.some(e => e.code === 'EXISTS');
76
+ // Success if no actual errors (warnings and info are OK)
77
+ result.success = result.errors.length === 0 ||
78
+ result.errors.every(e => e.code === 'EXISTS' || e.severity === 'info' || e.severity === 'warning');
77
79
  } catch (error) {
78
80
  result.errors.push({
79
81
  message: error.message,
@@ -85,7 +87,7 @@ async function generate(analysis, config, projectRoot) {
85
87
  }
86
88
 
87
89
  /**
88
- * Generate .claude/ directory with full structure
90
+ * Generate .claude/ directory with symlinks to .ai-context/
89
91
  * @param {string} projectRoot - Project root directory
90
92
  * @param {object} context - Template context
91
93
  * @param {object} result - Result object to track files/errors
@@ -94,6 +96,7 @@ async function generate(analysis, config, projectRoot) {
94
96
  async function generateClaudeDirectory(projectRoot, context, result) {
95
97
  const { copyDirectory } = require('../installer');
96
98
  const templatesDir = path.join(__dirname, '..', '..', 'templates', 'base');
99
+ const aiContextDir = path.join(projectRoot, '.ai-context');
97
100
  const claudeDir = path.join(projectRoot, '.claude');
98
101
 
99
102
  // Don't overwrite existing .claude/ directory
@@ -115,29 +118,52 @@ async function generateClaudeDirectory(projectRoot, context, result) {
115
118
  // Create .claude/ directory
116
119
  fs.mkdirSync(claudeDir, { recursive: true });
117
120
 
118
- // Copy relevant subdirectories from templates/base to .claude/
119
- const subdirsToCopy = [
121
+ // Subdirectories to symlink from .ai-context/
122
+ const subdirsToLink = [
120
123
  'agents',
121
124
  'commands',
122
125
  'indexes',
123
126
  'context',
124
127
  'schemas',
125
- 'standards'
128
+ 'standards',
129
+ 'tools'
126
130
  ];
127
131
 
128
- // Only copy tools if explicitly enabled
129
- if (context.features?.tools !== false) {
130
- subdirsToCopy.push('tools');
131
- }
132
-
132
+ let linksCreated = 0;
133
133
  let filesCopied = 0;
134
- for (const subdir of subdirsToCopy) {
135
- const srcPath = path.join(templatesDir, subdir);
136
- if (fs.existsSync(srcPath)) {
137
- const destPath = path.join(claudeDir, subdir);
138
- fs.mkdirSync(destPath, { recursive: true });
139
- const count = await copyDirectory(srcPath, destPath);
140
- filesCopied += count;
134
+
135
+ for (const subdir of subdirsToLink) {
136
+ const srcPath = path.join(aiContextDir, subdir);
137
+ const destPath = path.join(claudeDir, subdir);
138
+
139
+ // Skip if source doesn't exist
140
+ if (!fs.existsSync(srcPath)) {
141
+ continue;
142
+ }
143
+
144
+ // Try to create symlink, fallback to copy
145
+ try {
146
+ // Remove dest if it exists (shouldn't, but safety)
147
+ if (fs.existsSync(destPath)) {
148
+ if (fs.lstatSync(destPath).isSymbolicLink()) {
149
+ fs.unlinkSync(destPath);
150
+ } else {
151
+ // Existing directory, skip
152
+ continue;
153
+ }
154
+ }
155
+
156
+ // Create symlink
157
+ fs.symlinkSync(srcPath, destPath, 'junction');
158
+ linksCreated++;
159
+ } catch (symlinkError) {
160
+ // Symlink failed (likely Windows permissions or filesystem limitation)
161
+ // Fallback: copy directory contents
162
+ if (!fs.existsSync(destPath)) {
163
+ fs.mkdirSync(destPath, { recursive: true });
164
+ const count = await copyDirectory(srcPath, destPath);
165
+ filesCopied += count;
166
+ }
141
167
  }
142
168
  }
143
169
 
@@ -145,7 +171,7 @@ async function generateClaudeDirectory(projectRoot, context, result) {
145
171
  const settingsPath = path.join(claudeDir, 'settings.json');
146
172
  const settings = {
147
173
  '$schema': './schemas/settings.schema.json',
148
- version: '2.1.0',
174
+ version: '2.2.2',
149
175
  project: {
150
176
  name: context.project?.name || 'Project',
151
177
  tech_stack: context.project?.tech_stack || 'Not detected'
@@ -170,7 +196,26 @@ async function generateClaudeDirectory(projectRoot, context, result) {
170
196
  const readmePath = path.join(claudeDir, 'README.md');
171
197
  const readme = `# .claude Configuration - ${context.project?.name || 'Project'}
172
198
 
173
- This directory contains Claude Code-specific context engineering files.
199
+ This directory provides Claude Code with auto-discovered commands, agents, and configuration.
200
+
201
+ ## Architecture
202
+
203
+ This directory uses **symlinks** to \`../.ai-context/\` for all shared content:
204
+
205
+ \`\`\`
206
+ .claude/
207
+ ├── agents → ../.ai-context/agents/
208
+ ├── commands → ../.ai-context/commands/
209
+ ├── indexes → ../.ai-context/indexes/
210
+ ├── context → ../.ai-context/context/
211
+ ├── schemas → ../.ai-context/schemas/
212
+ ├── standards → ../.ai-context/standards/
213
+ ├── tools → ../.ai-context/tools/
214
+ ├── settings.json (this file - Claude-specific)
215
+ └── README.md (this file)
216
+ \`\`\`
217
+
218
+ **Single source of truth:** All content lives in \`.ai-context/\`. Edit there, not here.
174
219
 
175
220
  ## Quick Start
176
221
 
@@ -182,22 +227,26 @@ This directory contains Claude Code-specific context engineering files.
182
227
 
183
228
  See \`AI_CONTEXT.md\` at project root for universal AI context (works with all tools).
184
229
 
185
- ## Claude-Specific Files
186
-
187
- - **agents/** - Specialized agents for different tasks
188
- - **commands/** - Custom slash commands
189
- - **indexes/** - 3-level navigation system
190
- - **context/** - Workflow documentation
191
-
192
- *Generated by create-universal-ai-context v${context.version || '2.1.0'}*
230
+ *Generated by create-universal-ai-context v${context.version || '2.3.0'}*
193
231
  `;
194
232
  fs.writeFileSync(readmePath, readme);
195
233
  filesCopied++;
196
234
 
235
+ // Add info message about symlink approach
236
+ if (linksCreated > 0) {
237
+ result.errors.push({
238
+ message: `Created ${linksCreated} symlinks from .claude/ to .ai-context/ (single source of truth)`,
239
+ code: 'SYMLINKS_CREATED',
240
+ severity: 'info'
241
+ });
242
+ }
243
+
197
244
  return [{
198
245
  path: claudeDir,
199
246
  relativePath: '.claude/',
200
- size: filesCopied
247
+ size: filesCopied,
248
+ symlinks: linksCreated,
249
+ details: `${linksCreated} symlinks, ${filesCopied} files`
201
250
  }];
202
251
 
203
252
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-universal-ai-context",
3
- "version": "2.2.2",
3
+ "version": "2.3.0",
4
4
  "description": "Universal AI Context Engineering - Set up context for Claude, Copilot, Cline, Antigravity, and more",
5
5
  "main": "lib/index.js",
6
6
  "bin": {