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.
- package/lib/adapters/claude.js +77 -28
- package/package.json +1 -1
package/lib/adapters/claude.js
CHANGED
|
@@ -73,7 +73,9 @@ async function generate(analysis, config, projectRoot) {
|
|
|
73
73
|
result.files.push(...claudeDirResult);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
|
|
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
|
|
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
|
-
//
|
|
119
|
-
const
|
|
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
|
-
|
|
129
|
-
if (context.features?.tools !== false) {
|
|
130
|
-
subdirsToCopy.push('tools');
|
|
131
|
-
}
|
|
132
|
-
|
|
132
|
+
let linksCreated = 0;
|
|
133
133
|
let filesCopied = 0;
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
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