aiknowsys 0.4.1 â 0.5.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/commands/audit.js +85 -48
- package/lib/commands/check.js +1 -1
- package/lib/commands/init.js +24 -4
- package/lib/commands/install-agents.js +2 -2
- package/lib/commands/install-skills.js +0 -1
- package/lib/commands/scan.js +1 -1
- package/lib/commands/sync.js +54 -39
- package/lib/commands/update.js +146 -121
- package/package.json +1 -1
- package/templates/AGENTS.template.md +2 -0
- package/templates/CODEBASE_CHANGELOG.template.md +3 -0
- package/templates/agents/architect.agent.template.md +7 -1
- package/templates/stacks/express-api/CODEBASE_ESSENTIALS.md +991 -0
- package/templates/stacks/fastapi/CODEBASE_ESSENTIALS.md +1540 -0
- package/templates/stacks/nextjs/CODEBASE_ESSENTIALS.md +361 -5
- package/templates/stacks/nextjs-api/CODEBASE_ESSENTIALS.md +2065 -0
- package/templates/stacks/vue-express/CODEBASE_ESSENTIALS.md +497 -5
- package/templates/stacks/vue-vite/CODEBASE_ESSENTIALS.md +1037 -0
package/lib/commands/audit.js
CHANGED
|
@@ -8,10 +8,13 @@ import chalk from 'chalk';
|
|
|
8
8
|
*/
|
|
9
9
|
export async function audit(options) {
|
|
10
10
|
const targetDir = path.resolve(options.dir);
|
|
11
|
+
const silent = options._silent || false;
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
if (!silent) {
|
|
14
|
+
console.log('');
|
|
15
|
+
console.log(chalk.cyan.bold('đ Knowledge System Audit'));
|
|
16
|
+
console.log('');
|
|
17
|
+
}
|
|
15
18
|
|
|
16
19
|
const issues = [];
|
|
17
20
|
let warnings = 0;
|
|
@@ -21,8 +24,18 @@ export async function audit(options) {
|
|
|
21
24
|
const agentsPath = path.join(targetDir, 'AGENTS.md');
|
|
22
25
|
const changelogPath = path.join(targetDir, 'CODEBASE_CHANGELOG.md');
|
|
23
26
|
|
|
27
|
+
// Check if knowledge system exists
|
|
28
|
+
if (!fs.existsSync(essentialsPath) && !fs.existsSync(agentsPath)) {
|
|
29
|
+
if (!silent) {
|
|
30
|
+
console.log(chalk.yellow('â No knowledge system found in this directory'));
|
|
31
|
+
console.log(chalk.gray(' Run: npx aiknowsys init'));
|
|
32
|
+
console.log('');
|
|
33
|
+
}
|
|
34
|
+
throw new Error('No knowledge system found');
|
|
35
|
+
}
|
|
36
|
+
|
|
24
37
|
// Audit 1: Check for duplicated validation matrix
|
|
25
|
-
console.log(chalk.white('đ Checking for duplication issues...'));
|
|
38
|
+
if (!silent) console.log(chalk.white('đ Checking for duplication issues...'));
|
|
26
39
|
|
|
27
40
|
if (fs.existsSync(essentialsPath) && fs.existsSync(agentsPath)) {
|
|
28
41
|
const essentialsContent = fs.readFileSync(essentialsPath, 'utf-8');
|
|
@@ -34,7 +47,7 @@ export async function audit(options) {
|
|
|
34
47
|
const hasAgentsMatrix = matrixTablePattern.test(agentsContent);
|
|
35
48
|
|
|
36
49
|
if (hasEssentialsMatrix && hasAgentsMatrix) {
|
|
37
|
-
console.log(chalk.yellow(' â ī¸ Validation matrix duplicated in both files'));
|
|
50
|
+
if (!silent) console.log(chalk.yellow(' â ī¸ Validation matrix duplicated in both files'));
|
|
38
51
|
issues.push({
|
|
39
52
|
type: 'warning',
|
|
40
53
|
category: 'DRY Violation',
|
|
@@ -43,14 +56,14 @@ export async function audit(options) {
|
|
|
43
56
|
});
|
|
44
57
|
warnings++;
|
|
45
58
|
} else if (hasEssentialsMatrix) {
|
|
46
|
-
console.log(chalk.green(' â Validation matrix in ESSENTIALS only (correct)'));
|
|
59
|
+
if (!silent) console.log(chalk.green(' â Validation matrix in ESSENTIALS only (correct)'));
|
|
47
60
|
}
|
|
48
61
|
}
|
|
49
62
|
|
|
50
|
-
console.log('');
|
|
63
|
+
if (!silent) console.log('');
|
|
51
64
|
|
|
52
65
|
// Audit 2: Check for generic placeholder values
|
|
53
|
-
console.log(chalk.white('đ Checking for placeholder quality...'));
|
|
66
|
+
if (!silent) console.log(chalk.white('đ Checking for placeholder quality...'));
|
|
54
67
|
|
|
55
68
|
if (fs.existsSync(essentialsPath)) {
|
|
56
69
|
const content = fs.readFileSync(essentialsPath, 'utf-8');
|
|
@@ -67,7 +80,7 @@ export async function audit(options) {
|
|
|
67
80
|
const matches = content.match(check.pattern);
|
|
68
81
|
if (matches && matches.length > 3) { // Allow a few TBDs
|
|
69
82
|
if (check.severity === 'warning') {
|
|
70
|
-
console.log(chalk.yellow(` â ī¸ ${matches.length} instances of ${check.name}`));
|
|
83
|
+
if (!silent) console.log(chalk.yellow(` â ī¸ ${matches.length} instances of ${check.name}`));
|
|
71
84
|
issues.push({
|
|
72
85
|
type: 'warning',
|
|
73
86
|
category: 'Incomplete Setup',
|
|
@@ -76,7 +89,13 @@ export async function audit(options) {
|
|
|
76
89
|
});
|
|
77
90
|
warnings++;
|
|
78
91
|
} else {
|
|
79
|
-
console.log(chalk.cyan(` âšī¸ ${matches.length} instances of ${check.name}`));
|
|
92
|
+
if (!silent) console.log(chalk.cyan(` âšī¸ ${matches.length} instances of ${check.name}`));
|
|
93
|
+
issues.push({
|
|
94
|
+
type: 'info',
|
|
95
|
+
category: 'Incomplete Setup',
|
|
96
|
+
message: `${matches.length} ${check.name} found`,
|
|
97
|
+
fix: 'Complete TODO sections with actual project details'
|
|
98
|
+
});
|
|
80
99
|
info++;
|
|
81
100
|
}
|
|
82
101
|
}
|
|
@@ -86,7 +105,7 @@ export async function audit(options) {
|
|
|
86
105
|
const placeholderMatches = [...content.matchAll(/{{([A-Z_]+)}}/g)];
|
|
87
106
|
if (placeholderMatches.length > 0) {
|
|
88
107
|
const unique = [...new Set(placeholderMatches.map(m => m[1]))];
|
|
89
|
-
console.log(chalk.yellow(` â ī¸ ${unique.length} unfilled placeholders`));
|
|
108
|
+
if (!silent) console.log(chalk.yellow(` â ī¸ ${unique.length} unfilled placeholders`));
|
|
90
109
|
issues.push({
|
|
91
110
|
type: 'warning',
|
|
92
111
|
category: 'Incomplete Setup',
|
|
@@ -95,27 +114,37 @@ export async function audit(options) {
|
|
|
95
114
|
});
|
|
96
115
|
warnings++;
|
|
97
116
|
} else {
|
|
98
|
-
console.log(chalk.green(' â All placeholders filled'));
|
|
117
|
+
if (!silent) console.log(chalk.green(' â All placeholders filled'));
|
|
99
118
|
}
|
|
100
119
|
}
|
|
101
120
|
|
|
102
|
-
console.log('');
|
|
121
|
+
if (!silent) console.log('');
|
|
103
122
|
|
|
104
123
|
// Audit 3: Check validation matrix quality
|
|
105
|
-
console.log(chalk.white('â
Checking validation matrix quality...'));
|
|
124
|
+
if (!silent) console.log(chalk.white('â
Checking validation matrix quality...'));
|
|
106
125
|
|
|
107
126
|
if (fs.existsSync(essentialsPath)) {
|
|
108
127
|
const content = fs.readFileSync(essentialsPath, 'utf-8');
|
|
109
128
|
const matrixSection = content.split(/## \d*\.?\s*Validation Matrix/i)[1]?.split(/##/)[0] || '';
|
|
110
129
|
|
|
111
|
-
if (matrixSection.length
|
|
130
|
+
if (matrixSection.length === 0) {
|
|
131
|
+
// Validation Matrix section is missing
|
|
132
|
+
if (!silent) console.log(chalk.yellow(' â ī¸ Validation Matrix section missing'));
|
|
133
|
+
issues.push({
|
|
134
|
+
type: 'warning',
|
|
135
|
+
category: 'Missing Section',
|
|
136
|
+
message: 'Validation Matrix section missing from ESSENTIALS',
|
|
137
|
+
fix: 'Add Validation Matrix section with test commands'
|
|
138
|
+
});
|
|
139
|
+
warnings++;
|
|
140
|
+
} else if (matrixSection.length > 0) {
|
|
112
141
|
// Check for specific commands
|
|
113
142
|
const hasTestCmd = /test|pytest|jest|vitest/i.test(matrixSection);
|
|
114
143
|
const hasLintCmd = /lint|eslint|flake8|ruff/i.test(matrixSection);
|
|
115
144
|
const hasTypeCmd = /type-check|mypy|tsc/i.test(matrixSection);
|
|
116
145
|
|
|
117
146
|
if (!hasTestCmd) {
|
|
118
|
-
console.log(chalk.yellow(' â ī¸ No test command in validation matrix'));
|
|
147
|
+
if (!silent) console.log(chalk.yellow(' â ī¸ No test command in validation matrix'));
|
|
119
148
|
issues.push({
|
|
120
149
|
type: 'warning',
|
|
121
150
|
category: 'Missing Validation',
|
|
@@ -124,22 +153,22 @@ export async function audit(options) {
|
|
|
124
153
|
});
|
|
125
154
|
warnings++;
|
|
126
155
|
} else {
|
|
127
|
-
console.log(chalk.green(' â Test command configured'));
|
|
156
|
+
if (!silent) console.log(chalk.green(' â Test command configured'));
|
|
128
157
|
}
|
|
129
158
|
|
|
130
159
|
if (!hasLintCmd) {
|
|
131
|
-
console.log(chalk.cyan(' âšī¸ No linter configured (optional)'));
|
|
160
|
+
if (!silent) console.log(chalk.cyan(' âšī¸ No linter configured (optional)'));
|
|
132
161
|
info++;
|
|
133
162
|
} else {
|
|
134
|
-
console.log(chalk.green(' â Linter configured'));
|
|
163
|
+
if (!silent) console.log(chalk.green(' â Linter configured'));
|
|
135
164
|
}
|
|
136
165
|
}
|
|
137
166
|
}
|
|
138
167
|
|
|
139
|
-
console.log('');
|
|
168
|
+
if (!silent) console.log('');
|
|
140
169
|
|
|
141
170
|
// Audit 4: Check changelog usage
|
|
142
|
-
console.log(chalk.white('đ Checking changelog...'));
|
|
171
|
+
if (!silent) console.log(chalk.white('đ Checking changelog...'));
|
|
143
172
|
|
|
144
173
|
if (fs.existsSync(changelogPath)) {
|
|
145
174
|
const content = fs.readFileSync(changelogPath, 'utf-8');
|
|
@@ -156,70 +185,78 @@ export async function audit(options) {
|
|
|
156
185
|
}
|
|
157
186
|
}
|
|
158
187
|
|
|
159
|
-
console.log('');
|
|
188
|
+
if (!silent) console.log('');
|
|
160
189
|
|
|
161
190
|
// Audit 5: Check file sizes (detect bloat)
|
|
162
|
-
console.log(chalk.white('đ Checking file sizes...'));
|
|
191
|
+
if (!silent) console.log(chalk.white('đ Checking file sizes...'));
|
|
163
192
|
|
|
164
193
|
if (fs.existsSync(essentialsPath)) {
|
|
165
|
-
const
|
|
166
|
-
const
|
|
194
|
+
const content = fs.readFileSync(essentialsPath, 'utf-8');
|
|
195
|
+
const lineCount = content.split('\n').length;
|
|
167
196
|
|
|
168
|
-
if (
|
|
169
|
-
console.log(chalk.yellow(` â ī¸ CODEBASE_ESSENTIALS.md is large (${
|
|
197
|
+
if (lineCount > 300) {
|
|
198
|
+
if (!silent) console.log(chalk.yellow(` â ī¸ CODEBASE_ESSENTIALS.md is large (${lineCount} lines)`));
|
|
170
199
|
issues.push({
|
|
171
200
|
type: 'warning',
|
|
172
201
|
category: 'File Size',
|
|
173
|
-
message: `ESSENTIALS.md is ${
|
|
202
|
+
message: `ESSENTIALS.md is ${lineCount} lines (consider splitting)`,
|
|
174
203
|
fix: 'Consider using minimal template or archiving old patterns'
|
|
175
204
|
});
|
|
176
205
|
warnings++;
|
|
177
206
|
} else {
|
|
178
|
-
console.log(chalk.green(` â CODEBASE_ESSENTIALS.md size OK (${
|
|
207
|
+
if (!silent) console.log(chalk.green(` â CODEBASE_ESSENTIALS.md size OK (${lineCount} lines)`));
|
|
179
208
|
}
|
|
180
209
|
}
|
|
181
210
|
|
|
182
|
-
console.log('');
|
|
211
|
+
if (!silent) console.log('');
|
|
183
212
|
|
|
184
213
|
// Summary
|
|
185
|
-
console.log(chalk.cyan.bold('đ Audit Summary:'));
|
|
214
|
+
if (!silent) console.log(chalk.cyan.bold('đ Audit Summary:'));
|
|
186
215
|
|
|
187
216
|
if (issues.length === 0 && info === 0) {
|
|
188
|
-
console.log(chalk.green(' â No issues found'));
|
|
217
|
+
if (!silent) console.log(chalk.green(' â No issues found'));
|
|
189
218
|
} else {
|
|
190
219
|
if (warnings > 0) {
|
|
191
|
-
console.log(chalk.yellow(` â ī¸ Warnings: ${warnings}`));
|
|
220
|
+
if (!silent) console.log(chalk.yellow(` â ī¸ Warnings: ${warnings}`));
|
|
192
221
|
}
|
|
193
222
|
if (info > 0) {
|
|
194
|
-
console.log(chalk.cyan(` âšī¸ Info: ${info}`));
|
|
223
|
+
if (!silent) console.log(chalk.cyan(` âšī¸ Info: ${info}`));
|
|
195
224
|
}
|
|
196
225
|
}
|
|
197
226
|
|
|
198
|
-
console.log('');
|
|
227
|
+
if (!silent) console.log('');
|
|
199
228
|
|
|
200
229
|
// Detailed issues
|
|
201
230
|
if (issues.length > 0) {
|
|
202
|
-
console.log(chalk.cyan.bold('đ§ Issues Found:'));
|
|
203
|
-
console.log('');
|
|
231
|
+
if (!silent) console.log(chalk.cyan.bold('đ§ Issues Found:'));
|
|
232
|
+
if (!silent) console.log('');
|
|
204
233
|
|
|
205
234
|
issues.forEach((issue, idx) => {
|
|
206
235
|
const icon = issue.type === 'warning' ? 'â ī¸ ' : 'âšī¸ ';
|
|
207
|
-
console.log(chalk.white(`${idx + 1}. ${icon}${chalk.bold(issue.category)}`));
|
|
208
|
-
console.log(chalk.gray(` ${issue.message}`));
|
|
209
|
-
console.log(chalk.cyan(` Fix: ${issue.fix}`));
|
|
210
|
-
console.log('');
|
|
236
|
+
if (!silent) console.log(chalk.white(`${idx + 1}. ${icon}${chalk.bold(issue.category)}`));
|
|
237
|
+
if (!silent) console.log(chalk.gray(` ${issue.message}`));
|
|
238
|
+
if (!silent) console.log(chalk.cyan(` Fix: ${issue.fix}`));
|
|
239
|
+
if (!silent) console.log('');
|
|
211
240
|
});
|
|
212
241
|
}
|
|
213
242
|
|
|
214
243
|
// Recommendations
|
|
215
244
|
if (warnings > 0) {
|
|
216
|
-
console.log(chalk.cyan('đĄ Next Steps:'));
|
|
217
|
-
console.log(chalk.white(' 1. Run: npx aiknowsys sync (fix duplication)'));
|
|
218
|
-
console.log(chalk.white(' 2. Complete placeholder sections'));
|
|
219
|
-
console.log(chalk.white(' 3. Run: npx aiknowsys check (verify fixes)'));
|
|
220
|
-
console.log('');
|
|
245
|
+
if (!silent) console.log(chalk.cyan('đĄ Next Steps:'));
|
|
246
|
+
if (!silent) console.log(chalk.white(' 1. Run: npx aiknowsys sync (fix duplication)'));
|
|
247
|
+
if (!silent) console.log(chalk.white(' 2. Complete placeholder sections'));
|
|
248
|
+
if (!silent) console.log(chalk.white(' 3. Run: npx aiknowsys check (verify fixes)'));
|
|
249
|
+
if (!silent) console.log('');
|
|
221
250
|
} else {
|
|
222
|
-
console.log(chalk.green('â
Knowledge system is in good shape!'));
|
|
223
|
-
console.log('');
|
|
251
|
+
if (!silent) console.log(chalk.green('â
Knowledge system is in good shape!'));
|
|
252
|
+
if (!silent) console.log('');
|
|
224
253
|
}
|
|
254
|
+
|
|
255
|
+
// Return audit results for programmatic use
|
|
256
|
+
return {
|
|
257
|
+
issues,
|
|
258
|
+
warnings,
|
|
259
|
+
info,
|
|
260
|
+
clean: warnings === 0 && issues.length === 0
|
|
261
|
+
};
|
|
225
262
|
}
|
package/lib/commands/check.js
CHANGED
|
@@ -207,7 +207,7 @@ export async function check(options) {
|
|
|
207
207
|
// Exit with appropriate code
|
|
208
208
|
if (failed > 0) {
|
|
209
209
|
console.log(chalk.red('â Health check failed'));
|
|
210
|
-
|
|
210
|
+
throw new Error(`Health check failed: ${failed} check(s) failed`);
|
|
211
211
|
} else if (warnings > 0) {
|
|
212
212
|
console.log(chalk.yellow('â ī¸ Health check passed with warnings'));
|
|
213
213
|
} else {
|
package/lib/commands/init.js
CHANGED
|
@@ -16,6 +16,26 @@ const AVAILABLE_STACKS = {
|
|
|
16
16
|
name: 'vue-express',
|
|
17
17
|
display: 'Vue 3 + Express (Full-stack monorepo with shared types)',
|
|
18
18
|
description: 'Frontend + Backend + Shared packages'
|
|
19
|
+
},
|
|
20
|
+
'vue-vite': {
|
|
21
|
+
name: 'vue-vite',
|
|
22
|
+
display: 'Vue 3 + Vite (TypeScript + Vue Router + Pinia)',
|
|
23
|
+
description: 'Frontend SPA with modern tooling'
|
|
24
|
+
},
|
|
25
|
+
'express-api': {
|
|
26
|
+
name: 'express-api',
|
|
27
|
+
display: 'Express.js API (TypeScript + Prisma + PostgreSQL)',
|
|
28
|
+
description: 'Backend REST API with Node.js'
|
|
29
|
+
},
|
|
30
|
+
fastapi: {
|
|
31
|
+
name: 'fastapi',
|
|
32
|
+
display: 'FastAPI (Python + SQLAlchemy + PostgreSQL)',
|
|
33
|
+
description: 'Modern Python API framework with async support'
|
|
34
|
+
},
|
|
35
|
+
'nextjs-api': {
|
|
36
|
+
name: 'nextjs-api',
|
|
37
|
+
display: 'Next.js API (App Router + API routes + Server Actions)',
|
|
38
|
+
description: 'Next.js as a backend API framework'
|
|
19
39
|
}
|
|
20
40
|
};
|
|
21
41
|
|
|
@@ -588,7 +608,7 @@ export async function init(options) {
|
|
|
588
608
|
console.log('');
|
|
589
609
|
console.log(chalk.gray(' Use --list-stacks for detailed descriptions'));
|
|
590
610
|
console.log('');
|
|
591
|
-
|
|
611
|
+
throw new Error(`Invalid stack: ${options.stack}`);
|
|
592
612
|
}
|
|
593
613
|
|
|
594
614
|
// Check if project already exists
|
|
@@ -597,7 +617,7 @@ export async function init(options) {
|
|
|
597
617
|
console.log(chalk.yellow('â ī¸ Knowledge system files already exist in this directory.'));
|
|
598
618
|
console.log(chalk.gray(' Run "aiknowsys migrate" to update existing files.'));
|
|
599
619
|
console.log('');
|
|
600
|
-
|
|
620
|
+
throw new Error('Project already exists');
|
|
601
621
|
}
|
|
602
622
|
|
|
603
623
|
const stackInfo = AVAILABLE_STACKS[options.stack];
|
|
@@ -676,7 +696,7 @@ export async function init(options) {
|
|
|
676
696
|
} catch (error) {
|
|
677
697
|
spinner.fail('Failed to copy stack template');
|
|
678
698
|
console.error(chalk.red(`\nâ Error: ${error.message}\n`));
|
|
679
|
-
|
|
699
|
+
throw error;
|
|
680
700
|
}
|
|
681
701
|
}
|
|
682
702
|
|
|
@@ -1035,7 +1055,7 @@ export async function init(options) {
|
|
|
1035
1055
|
} catch (error) {
|
|
1036
1056
|
spinner.fail('Failed to initialize');
|
|
1037
1057
|
console.error(chalk.red(error.message));
|
|
1038
|
-
|
|
1058
|
+
throw error;
|
|
1039
1059
|
}
|
|
1040
1060
|
}
|
|
1041
1061
|
|
|
@@ -9,6 +9,7 @@ export async function installAgents(options) {
|
|
|
9
9
|
const targetDir = path.resolve(options.dir);
|
|
10
10
|
const essentialsFile = options.essentials || 'CODEBASE_ESSENTIALS.md';
|
|
11
11
|
const silent = options._silent || false;
|
|
12
|
+
const skipPrompts = options.yes || false;
|
|
12
13
|
|
|
13
14
|
if (!silent) {
|
|
14
15
|
console.log('');
|
|
@@ -54,7 +55,7 @@ export async function installAgents(options) {
|
|
|
54
55
|
if (spinner) spinner.succeed('Agent templates installed');
|
|
55
56
|
|
|
56
57
|
// Ask for project-specific guidelines (only in interactive mode)
|
|
57
|
-
if (!silent) {
|
|
58
|
+
if (!silent && !skipPrompts) {
|
|
58
59
|
const { addGuidelines } = await inquirer.prompt([{
|
|
59
60
|
type: 'confirm',
|
|
60
61
|
name: 'addGuidelines',
|
|
@@ -97,7 +98,6 @@ export async function installAgents(options) {
|
|
|
97
98
|
} catch (error) {
|
|
98
99
|
if (spinner) spinner.fail('Failed to install agents');
|
|
99
100
|
console.error(chalk.red(error.message));
|
|
100
|
-
if (!silent) process.exit(1);
|
|
101
101
|
throw error;
|
|
102
102
|
}
|
|
103
103
|
}
|
package/lib/commands/scan.js
CHANGED
package/lib/commands/sync.js
CHANGED
|
@@ -9,28 +9,35 @@ import ora from 'ora';
|
|
|
9
9
|
*/
|
|
10
10
|
export async function sync(options) {
|
|
11
11
|
const targetDir = path.resolve(options.dir);
|
|
12
|
+
const silent = options._silent || false;
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
if (!silent) {
|
|
15
|
+
console.log('');
|
|
16
|
+
console.log(chalk.cyan.bold('đ Sync Validation Matrix Reference'));
|
|
17
|
+
console.log('');
|
|
18
|
+
}
|
|
16
19
|
|
|
17
20
|
const essentialsPath = path.join(targetDir, 'CODEBASE_ESSENTIALS.md');
|
|
18
21
|
const agentsPath = path.join(targetDir, 'AGENTS.md');
|
|
19
22
|
|
|
20
23
|
// Check files exist
|
|
21
24
|
if (!fs.existsSync(essentialsPath)) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
if (!silent) {
|
|
26
|
+
console.log(chalk.red('â CODEBASE_ESSENTIALS.md not found'));
|
|
27
|
+
console.log(chalk.gray(' Run: npx aiknowsys init'));
|
|
28
|
+
}
|
|
29
|
+
throw new Error('CODEBASE_ESSENTIALS.md not found');
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
if (!fs.existsSync(agentsPath)) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
if (!silent) {
|
|
34
|
+
console.log(chalk.red('â AGENTS.md not found'));
|
|
35
|
+
console.log(chalk.gray(' Run: npx aiknowsys init'));
|
|
36
|
+
}
|
|
37
|
+
throw new Error('AGENTS.md not found');
|
|
31
38
|
}
|
|
32
39
|
|
|
33
|
-
const spinner = ora('Checking validation matrix...').start();
|
|
40
|
+
const spinner = silent ? null : ora('Checking validation matrix...').start();
|
|
34
41
|
|
|
35
42
|
// Read ESSENTIALS to verify validation matrix exists
|
|
36
43
|
const essentialsContent = fs.readFileSync(essentialsPath, 'utf-8');
|
|
@@ -38,13 +45,15 @@ export async function sync(options) {
|
|
|
38
45
|
essentialsContent.includes('## Validation Matrix');
|
|
39
46
|
|
|
40
47
|
if (!hasValidationMatrix) {
|
|
41
|
-
spinner.fail('Validation matrix not found in CODEBASE_ESSENTIALS.md');
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
if (spinner) spinner.fail('Validation matrix not found in CODEBASE_ESSENTIALS.md');
|
|
49
|
+
if (!silent) {
|
|
50
|
+
console.log('');
|
|
51
|
+
console.log(chalk.yellow('đĄ Add a Validation Matrix section to CODEBASE_ESSENTIALS.md'));
|
|
52
|
+
}
|
|
53
|
+
throw new Error('Validation matrix not found in CODEBASE_ESSENTIALS.md');
|
|
45
54
|
}
|
|
46
55
|
|
|
47
|
-
spinner.text = 'Reading AGENTS.md...';
|
|
56
|
+
if (spinner) spinner.text = 'Reading AGENTS.md...';
|
|
48
57
|
|
|
49
58
|
// Read AGENTS.md
|
|
50
59
|
let agentsContent = fs.readFileSync(agentsPath, 'utf-8');
|
|
@@ -54,14 +63,16 @@ export async function sync(options) {
|
|
|
54
63
|
agentsContent.includes('CODEBASE_ESSENTIALS.md#validation-matrix');
|
|
55
64
|
|
|
56
65
|
if (hasReference) {
|
|
57
|
-
spinner.succeed('Validation matrix reference already up to date');
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
66
|
+
if (spinner) spinner.succeed('Validation matrix reference already up to date');
|
|
67
|
+
if (!silent) {
|
|
68
|
+
console.log('');
|
|
69
|
+
console.log(chalk.green('â
AGENTS.md correctly references CODEBASE_ESSENTIALS.md'));
|
|
70
|
+
console.log('');
|
|
71
|
+
}
|
|
61
72
|
return;
|
|
62
73
|
}
|
|
63
74
|
|
|
64
|
-
spinner.text = 'Updating AGENTS.md...';
|
|
75
|
+
if (spinner) spinner.text = 'Updating AGENTS.md...';
|
|
65
76
|
|
|
66
77
|
// Find the validation matrix section in AGENTS.md
|
|
67
78
|
// Look for the pattern that might have a duplicated matrix
|
|
@@ -69,17 +80,19 @@ export async function sync(options) {
|
|
|
69
80
|
const match = agentsContent.match(validationSectionRegex);
|
|
70
81
|
|
|
71
82
|
if (!match) {
|
|
72
|
-
spinner.warn('Could not find validation matrix section in AGENTS.md');
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
if (spinner) spinner.warn('Could not find validation matrix section in AGENTS.md');
|
|
84
|
+
if (!silent) {
|
|
85
|
+
console.log('');
|
|
86
|
+
console.log(chalk.yellow('â ī¸ Manual update required'));
|
|
87
|
+
console.log(chalk.white('Add this to your AGENTS.md validation section:'));
|
|
88
|
+
console.log('');
|
|
89
|
+
console.log(chalk.gray('**Validation Matrix:**'));
|
|
90
|
+
console.log(chalk.gray(''));
|
|
91
|
+
console.log(chalk.gray('đ **See [CODEBASE_ESSENTIALS.md - Validation Matrix](CODEBASE_ESSENTIALS.md#validation-matrix)**'));
|
|
92
|
+
console.log(chalk.gray(''));
|
|
93
|
+
console.log(chalk.gray('The validation matrix lives in CODEBASE_ESSENTIALS.md as the single source of truth.'));
|
|
94
|
+
console.log('');
|
|
95
|
+
}
|
|
83
96
|
return;
|
|
84
97
|
}
|
|
85
98
|
|
|
@@ -96,12 +109,14 @@ The validation matrix lives in CODEBASE_ESSENTIALS.md as the single source of tr
|
|
|
96
109
|
// Write updated AGENTS.md
|
|
97
110
|
fs.writeFileSync(agentsPath, agentsContent);
|
|
98
111
|
|
|
99
|
-
spinner.succeed('AGENTS.md updated');
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
112
|
+
if (spinner) spinner.succeed('AGENTS.md updated');
|
|
113
|
+
if (!silent) {
|
|
114
|
+
console.log('');
|
|
115
|
+
console.log(chalk.green('â
Validation matrix reference synced'));
|
|
116
|
+
console.log('');
|
|
117
|
+
console.log(chalk.cyan('đĄ What changed:'));
|
|
118
|
+
console.log(chalk.white(' âĸ AGENTS.md now references CODEBASE_ESSENTIALS.md'));
|
|
119
|
+
console.log(chalk.white(' âĸ Update validation matrix in ESSENTIALS.md only (single source of truth)'));
|
|
120
|
+
console.log('');
|
|
121
|
+
}
|
|
107
122
|
}
|