@ryuenn3123/agentic-senior-core 2.0.19 → 2.0.21
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/.agent-context/state/benchmark-comparison-schema.json +181 -0
- package/.cursorrules +1 -1
- package/.gemini/instructions.md +1 -1
- package/.github/copilot-instructions.md +1 -1
- package/.windsurfrules +1 -1
- package/AGENTS.md +1 -1
- package/lib/cli/commands/init.mjs +123 -0
- package/lib/cli/commands/upgrade.mjs +16 -0
- package/lib/cli/compiler.mjs +31 -0
- package/lib/cli/project-scaffolder.mjs +465 -0
- package/lib/cli/templates/api-contract.md.id.tmpl +143 -0
- package/lib/cli/templates/api-contract.md.tmpl +143 -0
- package/lib/cli/templates/architecture-decision-record.md.id.tmpl +106 -0
- package/lib/cli/templates/architecture-decision-record.md.tmpl +106 -0
- package/lib/cli/templates/database-schema.md.id.tmpl +74 -0
- package/lib/cli/templates/database-schema.md.tmpl +74 -0
- package/lib/cli/templates/flow-overview.md.id.tmpl +118 -0
- package/lib/cli/templates/flow-overview.md.tmpl +119 -0
- package/lib/cli/templates/project-brief.md.id.tmpl +53 -0
- package/lib/cli/templates/project-brief.md.tmpl +53 -0
- package/lib/cli/utils.mjs +5 -1
- package/package.json +2 -2
- package/scripts/bump-version.mjs +101 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "Benchmark Before-vs-After Comparison",
|
|
4
|
+
"description": "Schema for comparing benchmark results across releases or configuration changes. Each entry captures quality, bug signal, runtime, and token metrics for a before and after snapshot.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["schemaVersion", "comparisonId", "generatedAt", "before", "after", "delta"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"schemaVersion": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"const": "1.0.0"
|
|
11
|
+
},
|
|
12
|
+
"comparisonId": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "Unique identifier for this comparison run."
|
|
15
|
+
},
|
|
16
|
+
"generatedAt": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"format": "date-time"
|
|
19
|
+
},
|
|
20
|
+
"baselineVersion": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"description": "Package version of the before snapshot."
|
|
23
|
+
},
|
|
24
|
+
"candidateVersion": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"description": "Package version of the after snapshot."
|
|
27
|
+
},
|
|
28
|
+
"comparisonType": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"enum": ["release-to-release", "config-change", "model-swap", "manual"],
|
|
31
|
+
"description": "What triggered this comparison."
|
|
32
|
+
},
|
|
33
|
+
"before": { "$ref": "#/$defs/snapshot" },
|
|
34
|
+
"after": { "$ref": "#/$defs/snapshot" },
|
|
35
|
+
"delta": { "$ref": "#/$defs/deltaReport" },
|
|
36
|
+
"verdict": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"enum": ["pass", "warn", "fail"],
|
|
39
|
+
"description": "Overall comparison verdict based on threshold policy."
|
|
40
|
+
},
|
|
41
|
+
"verdictReason": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"description": "Human-readable explanation of the verdict."
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"$defs": {
|
|
47
|
+
"snapshot": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"required": ["capturedAt", "quality", "runtime"],
|
|
50
|
+
"properties": {
|
|
51
|
+
"capturedAt": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"format": "date-time"
|
|
54
|
+
},
|
|
55
|
+
"packageVersion": {
|
|
56
|
+
"type": "string"
|
|
57
|
+
},
|
|
58
|
+
"quality": {
|
|
59
|
+
"type": "object",
|
|
60
|
+
"properties": {
|
|
61
|
+
"top1Accuracy": {
|
|
62
|
+
"type": "number",
|
|
63
|
+
"minimum": 0,
|
|
64
|
+
"maximum": 1,
|
|
65
|
+
"description": "Fraction of scenarios where the top-ranked output was correct."
|
|
66
|
+
},
|
|
67
|
+
"manualCorrectionRate": {
|
|
68
|
+
"type": "number",
|
|
69
|
+
"minimum": 0,
|
|
70
|
+
"maximum": 1,
|
|
71
|
+
"description": "Fraction of outputs requiring human correction."
|
|
72
|
+
},
|
|
73
|
+
"averageJudgeScore": {
|
|
74
|
+
"type": "number",
|
|
75
|
+
"minimum": 0,
|
|
76
|
+
"maximum": 10,
|
|
77
|
+
"description": "Mean score across all judge dimensions."
|
|
78
|
+
},
|
|
79
|
+
"scenarioCount": {
|
|
80
|
+
"type": "integer",
|
|
81
|
+
"minimum": 1
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"bugSignal": {
|
|
86
|
+
"type": "object",
|
|
87
|
+
"properties": {
|
|
88
|
+
"validationFailures": {
|
|
89
|
+
"type": "integer",
|
|
90
|
+
"minimum": 0,
|
|
91
|
+
"description": "Number of validation check failures."
|
|
92
|
+
},
|
|
93
|
+
"securityWarnings": {
|
|
94
|
+
"type": "integer",
|
|
95
|
+
"minimum": 0
|
|
96
|
+
},
|
|
97
|
+
"deprecationWarnings": {
|
|
98
|
+
"type": "integer",
|
|
99
|
+
"minimum": 0
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"runtime": {
|
|
104
|
+
"type": "object",
|
|
105
|
+
"properties": {
|
|
106
|
+
"totalDurationMs": {
|
|
107
|
+
"type": "number",
|
|
108
|
+
"description": "Total benchmark suite execution time in milliseconds."
|
|
109
|
+
},
|
|
110
|
+
"averageScenarioDurationMs": {
|
|
111
|
+
"type": "number"
|
|
112
|
+
},
|
|
113
|
+
"peakMemoryMb": {
|
|
114
|
+
"type": "number"
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"token": {
|
|
119
|
+
"type": "object",
|
|
120
|
+
"properties": {
|
|
121
|
+
"nativeSavingsPercent": {
|
|
122
|
+
"type": "number",
|
|
123
|
+
"description": "Token savings from native optimization."
|
|
124
|
+
},
|
|
125
|
+
"proxySavingsPercent": {
|
|
126
|
+
"type": "number",
|
|
127
|
+
"description": "Token savings from external proxy optimization."
|
|
128
|
+
},
|
|
129
|
+
"totalInputTokens": {
|
|
130
|
+
"type": "integer"
|
|
131
|
+
},
|
|
132
|
+
"totalOutputTokens": {
|
|
133
|
+
"type": "integer"
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
"deltaReport": {
|
|
140
|
+
"type": "object",
|
|
141
|
+
"properties": {
|
|
142
|
+
"top1AccuracyChange": {
|
|
143
|
+
"type": "number",
|
|
144
|
+
"description": "After minus before. Positive means improvement."
|
|
145
|
+
},
|
|
146
|
+
"manualCorrectionRateChange": {
|
|
147
|
+
"type": "number",
|
|
148
|
+
"description": "After minus before. Negative means improvement."
|
|
149
|
+
},
|
|
150
|
+
"averageJudgeScoreChange": {
|
|
151
|
+
"type": "number"
|
|
152
|
+
},
|
|
153
|
+
"validationFailureChange": {
|
|
154
|
+
"type": "integer"
|
|
155
|
+
},
|
|
156
|
+
"totalDurationMsChange": {
|
|
157
|
+
"type": "number"
|
|
158
|
+
},
|
|
159
|
+
"nativeSavingsChange": {
|
|
160
|
+
"type": "number"
|
|
161
|
+
},
|
|
162
|
+
"regressionDetected": {
|
|
163
|
+
"type": "boolean",
|
|
164
|
+
"description": "True if any metric crossed a threshold in the wrong direction."
|
|
165
|
+
},
|
|
166
|
+
"regressionDetails": {
|
|
167
|
+
"type": "array",
|
|
168
|
+
"items": {
|
|
169
|
+
"type": "object",
|
|
170
|
+
"properties": {
|
|
171
|
+
"metric": { "type": "string" },
|
|
172
|
+
"threshold": { "type": "number" },
|
|
173
|
+
"actual": { "type": "number" },
|
|
174
|
+
"direction": { "type": "string", "enum": ["increase", "decrease"] }
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
package/.cursorrules
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AGENTIC-SENIOR-CORE DYNAMIC GOVERNANCE RULESET
|
|
2
2
|
|
|
3
|
-
Generated by Agentic-Senior-Core CLI v2.0.
|
|
3
|
+
Generated by Agentic-Senior-Core CLI v2.0.21
|
|
4
4
|
Timestamp: 2026-04-15T00:14:51.184Z
|
|
5
5
|
Selected profile: beginner
|
|
6
6
|
Selected policy file: .agent-context/policies/llm-judge-threshold.json
|
package/.gemini/instructions.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Adapter Mode: thin
|
|
4
4
|
Adapter Source: .instructions.md
|
|
5
|
-
Canonical Snapshot SHA256:
|
|
5
|
+
Canonical Snapshot SHA256: 2a2a036b4fb90f9e668163b83614f2339044c0d021a6eaf2f380e626dfe72de0
|
|
6
6
|
|
|
7
7
|
Canonical policy source: [.instructions.md](../.instructions.md).
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Adapter Mode: thin
|
|
4
4
|
Adapter Source: .instructions.md
|
|
5
|
-
Canonical Snapshot SHA256:
|
|
5
|
+
Canonical Snapshot SHA256: 2a2a036b4fb90f9e668163b83614f2339044c0d021a6eaf2f380e626dfe72de0
|
|
6
6
|
|
|
7
7
|
The canonical policy source for this repository is [.instructions.md](../.instructions.md).
|
|
8
8
|
|
package/.windsurfrules
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AGENTIC-SENIOR-CORE DYNAMIC GOVERNANCE RULESET
|
|
2
2
|
|
|
3
|
-
Generated by Agentic-Senior-Core CLI v2.0.
|
|
3
|
+
Generated by Agentic-Senior-Core CLI v2.0.21
|
|
4
4
|
Timestamp: 2026-04-15T00:14:51.184Z
|
|
5
5
|
Selected profile: beginner
|
|
6
6
|
Selected policy file: .agent-context/policies/llm-judge-threshold.json
|
package/AGENTS.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Adapter Mode: thin
|
|
4
4
|
Adapter Source: .instructions.md
|
|
5
|
-
Canonical Snapshot SHA256:
|
|
5
|
+
Canonical Snapshot SHA256: 2a2a036b4fb90f9e668163b83614f2339044c0d021a6eaf2f380e626dfe72de0
|
|
6
6
|
|
|
7
7
|
This file is an adapter entrypoint for agent discovery.
|
|
8
8
|
The canonical policy source is [.instructions.md](.instructions.md).
|
|
@@ -34,6 +34,14 @@ import { detectProjectContext, buildDetectionSummary, formatDetectionCandidates
|
|
|
34
34
|
import { compileDynamicContext, writeSelectedPolicy, writeOnboardingReport } from '../compiler.mjs';
|
|
35
35
|
import { runPreflightChecks } from '../preflight.mjs';
|
|
36
36
|
import { createBackup } from '../backup.mjs';
|
|
37
|
+
import {
|
|
38
|
+
runProjectDiscovery,
|
|
39
|
+
generateProjectDocumentation,
|
|
40
|
+
isDirectoryEffectivelyEmpty,
|
|
41
|
+
hasExistingProjectDocs,
|
|
42
|
+
loadProjectConfig,
|
|
43
|
+
normalizeDocsLanguage,
|
|
44
|
+
} from '../project-scaffolder.mjs';
|
|
37
45
|
import { performRollback } from '../rollback.mjs';
|
|
38
46
|
import {
|
|
39
47
|
createTokenOptimizationState,
|
|
@@ -58,6 +66,10 @@ export function parseInitArguments(commandArguments) {
|
|
|
58
66
|
tokenOptimize: true,
|
|
59
67
|
tokenAgent: 'copilot',
|
|
60
68
|
includeMcpTemplate: false,
|
|
69
|
+
scaffoldDocs: undefined,
|
|
70
|
+
docsLang: 'en',
|
|
71
|
+
docsLangProvided: false,
|
|
72
|
+
projectConfig: undefined,
|
|
61
73
|
};
|
|
62
74
|
|
|
63
75
|
for (let argumentIndex = 0; argumentIndex < commandArguments.length; argumentIndex++) {
|
|
@@ -166,6 +178,40 @@ export function parseInitArguments(commandArguments) {
|
|
|
166
178
|
continue;
|
|
167
179
|
}
|
|
168
180
|
|
|
181
|
+
if (currentArgument === '--scaffold-docs') {
|
|
182
|
+
parsedInitOptions.scaffoldDocs = true;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (currentArgument === '--no-scaffold-docs') {
|
|
187
|
+
parsedInitOptions.scaffoldDocs = false;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (currentArgument === '--docs-lang') {
|
|
192
|
+
parsedInitOptions.docsLang = commandArguments[argumentIndex + 1] || 'en';
|
|
193
|
+
parsedInitOptions.docsLangProvided = true;
|
|
194
|
+
argumentIndex += 1;
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (currentArgument.startsWith('--docs-lang=')) {
|
|
199
|
+
parsedInitOptions.docsLang = currentArgument.split('=')[1] || 'en';
|
|
200
|
+
parsedInitOptions.docsLangProvided = true;
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (currentArgument === '--project-config') {
|
|
205
|
+
parsedInitOptions.projectConfig = commandArguments[argumentIndex + 1];
|
|
206
|
+
argumentIndex += 1;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (currentArgument.startsWith('--project-config=')) {
|
|
211
|
+
parsedInitOptions.projectConfig = currentArgument.split('=')[1];
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
|
|
169
215
|
throw new Error(`Unknown option: ${currentArgument}`);
|
|
170
216
|
}
|
|
171
217
|
|
|
@@ -173,6 +219,12 @@ export function parseInitArguments(commandArguments) {
|
|
|
173
219
|
throw new Error('--newbie can only be combined with --profile beginner');
|
|
174
220
|
}
|
|
175
221
|
|
|
222
|
+
const normalizedDocsLanguage = normalizeDocsLanguage(parsedInitOptions.docsLang || 'en');
|
|
223
|
+
if (!normalizedDocsLanguage) {
|
|
224
|
+
throw new Error('--docs-lang must be one of: en, id');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
parsedInitOptions.docsLang = normalizedDocsLanguage;
|
|
176
228
|
parsedInitOptions.tokenAgent = normalizeAgentName(parsedInitOptions.tokenAgent);
|
|
177
229
|
|
|
178
230
|
return parsedInitOptions;
|
|
@@ -185,6 +237,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
185
237
|
: true;
|
|
186
238
|
const shouldIncludeMcpTemplate = initOptions.includeMcpTemplate === true;
|
|
187
239
|
const selectedTokenAgentName = normalizeAgentName(initOptions.tokenAgent || 'copilot');
|
|
240
|
+
const isInteractiveSession = Boolean(stdin.isTTY && stdout.isTTY);
|
|
188
241
|
|
|
189
242
|
if (resolvedTargetDirectoryPath.toLowerCase() === 'c:\\windows' || resolvedTargetDirectoryPath.toLowerCase() === 'c:\\windows\\system32') {
|
|
190
243
|
console.error('\n[FATAL] Target directory resolved to a Windows system folder (C:\\Windows).');
|
|
@@ -203,6 +256,9 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
203
256
|
throw new Error('Preflight checks failed.');
|
|
204
257
|
}
|
|
205
258
|
|
|
259
|
+
const wasDirectoryEffectivelyEmpty = await isDirectoryEffectivelyEmpty(resolvedTargetDirectoryPath);
|
|
260
|
+
const hadExistingProjectDocsBeforeInit = await hasExistingProjectDocs(resolvedTargetDirectoryPath);
|
|
261
|
+
|
|
206
262
|
const backup = await createBackup(resolvedTargetDirectoryPath);
|
|
207
263
|
|
|
208
264
|
const userInterface = createInterface({ input: stdin, output: stdout });
|
|
@@ -386,6 +442,66 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
386
442
|
console.log('Installation will continue, but review these warnings before production use.');
|
|
387
443
|
}
|
|
388
444
|
|
|
445
|
+
// --- Project Documentation Scaffolding ---
|
|
446
|
+
let scaffoldingResult = null;
|
|
447
|
+
const isFreshProjectTarget = wasDirectoryEffectivelyEmpty && !hadExistingProjectDocsBeforeInit;
|
|
448
|
+
const shouldOfferScaffolding = initOptions.scaffoldDocs === true
|
|
449
|
+
|| Boolean(initOptions.projectConfig)
|
|
450
|
+
|| (initOptions.scaffoldDocs !== false && isFreshProjectTarget);
|
|
451
|
+
|
|
452
|
+
if (shouldOfferScaffolding) {
|
|
453
|
+
if (initOptions.scaffoldDocs === true && !initOptions.projectConfig && !isInteractiveSession) {
|
|
454
|
+
throw new Error('Non-interactive scaffolding requires --project-config when --scaffold-docs is enabled.');
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
const userWantsScaffolding = initOptions.scaffoldDocs === true
|
|
458
|
+
|| initOptions.projectConfig
|
|
459
|
+
|| (!isInteractiveSession
|
|
460
|
+
? false
|
|
461
|
+
: await askYesNo(
|
|
462
|
+
'This is a fresh project. Want me to scaffold project documentation (architecture, database, API contract, flow)?',
|
|
463
|
+
userInterface,
|
|
464
|
+
true
|
|
465
|
+
));
|
|
466
|
+
|
|
467
|
+
if (userWantsScaffolding) {
|
|
468
|
+
let discoveryAnswers;
|
|
469
|
+
|
|
470
|
+
if (initOptions.projectConfig) {
|
|
471
|
+
discoveryAnswers = await loadProjectConfig(initOptions.projectConfig);
|
|
472
|
+
console.log(`\nLoaded project configuration from: ${initOptions.projectConfig}`);
|
|
473
|
+
} else {
|
|
474
|
+
discoveryAnswers = await runProjectDiscovery(userInterface);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
const normalizedConfigDocsLanguage = normalizeDocsLanguage(discoveryAnswers.docsLang || '');
|
|
478
|
+
if (discoveryAnswers.docsLang && !normalizedConfigDocsLanguage) {
|
|
479
|
+
throw new Error(`Unsupported docs language in project config: ${discoveryAnswers.docsLang}. Supported values: en, id`);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
const selectedDocsLanguage = (!initOptions.docsLangProvided && normalizedConfigDocsLanguage)
|
|
483
|
+
? normalizedConfigDocsLanguage
|
|
484
|
+
: initOptions.docsLang;
|
|
485
|
+
|
|
486
|
+
scaffoldingResult = await generateProjectDocumentation(
|
|
487
|
+
resolvedTargetDirectoryPath,
|
|
488
|
+
discoveryAnswers,
|
|
489
|
+
{
|
|
490
|
+
stackFileName: selectedResolvedStackFileName,
|
|
491
|
+
blueprintFileName: selectedResolvedBlueprintFileName,
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
docsLanguage: selectedDocsLanguage,
|
|
495
|
+
}
|
|
496
|
+
);
|
|
497
|
+
|
|
498
|
+
console.log(`\nProject documentation generated in docs/:`);
|
|
499
|
+
for (const generatedFileName of scaffoldingResult.generatedFileNames) {
|
|
500
|
+
console.log(` - docs/${generatedFileName}`);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
389
505
|
await compileDynamicContext({
|
|
390
506
|
targetDirectoryPath: resolvedTargetDirectoryPath,
|
|
391
507
|
selectedProfileName,
|
|
@@ -428,6 +544,10 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
428
544
|
console.log(`- Blocking severities: ${formatBlockingSeverities(selectedProfile.blockingSeverities)}`);
|
|
429
545
|
console.log(`- Setup time: ${formatDuration(setupDurationMs)}`);
|
|
430
546
|
console.log('- Generated files: .cursorrules, .windsurfrules, and .agent-context/state/onboarding-report.json');
|
|
547
|
+
if (scaffoldingResult) {
|
|
548
|
+
console.log(`- Project docs: ${scaffoldingResult.generatedFileNames.length} files generated in docs/`);
|
|
549
|
+
console.log(`- Project docs language: ${scaffoldingResult.docsLanguage}`);
|
|
550
|
+
}
|
|
431
551
|
console.log(`- Repository workflows copied: no (workflows remain source-repo assets)`);
|
|
432
552
|
console.log(`- MCP template file: ${shouldIncludeMcpTemplate ? 'created (.vscode/mcp.json)' : 'not created by default (use --mcp-template)'}`);
|
|
433
553
|
if (isTokenOptimizationEnabled) {
|
|
@@ -437,6 +557,9 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
437
557
|
}
|
|
438
558
|
console.log('\nPlain-language summary:');
|
|
439
559
|
console.log(`I prepared a ${selectedProfile.displayName.toLowerCase()} governance pack for a ${toTitleCase(selectedResolvedStackFileName)} project using the ${toTitleCase(selectedResolvedBlueprintFileName)} blueprint.`);
|
|
560
|
+
if (scaffoldingResult) {
|
|
561
|
+
console.log(`I also generated project documentation (${scaffoldingResult.docsLanguage}) based on your project description. AI agents will use docs/ as project context.`);
|
|
562
|
+
}
|
|
440
563
|
console.log('Your AI tools will now receive one compiled rulebook plus the original source rules, and your review threshold is stored in .agent-context/policies/llm-judge-threshold.json.');
|
|
441
564
|
console.log('MCP server registration is manual inside your IDE settings, even when mcp.json exists.');
|
|
442
565
|
} catch (error) {
|
|
@@ -37,6 +37,7 @@ import { createBackup } from '../backup.mjs';
|
|
|
37
37
|
import { performRollback } from '../rollback.mjs';
|
|
38
38
|
import { inferSkillDomainNamesFromSelection } from '../skill-selector.mjs';
|
|
39
39
|
import { evaluateSkillDomainCompatibility } from '../compatibility.mjs';
|
|
40
|
+
import { detectProjectDocTemplateStaleness } from '../project-scaffolder.mjs';
|
|
40
41
|
|
|
41
42
|
export function parseUpgradeArguments(commandArguments) {
|
|
42
43
|
const parsedUpgradeOptions = {
|
|
@@ -134,6 +135,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
134
135
|
resolvedTargetDirectoryPath,
|
|
135
136
|
selectedSkillDomainNames
|
|
136
137
|
);
|
|
138
|
+
const projectDocStalenessReport = await detectProjectDocTemplateStaleness(resolvedTargetDirectoryPath);
|
|
137
139
|
|
|
138
140
|
if (compatibilityWarnings.length > 0) {
|
|
139
141
|
console.log('\n[WARN] Compatibility checks reported potential issues for this environment:');
|
|
@@ -169,6 +171,20 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
169
171
|
console.log(`- Existing rules lines: ${currentRuleLineCount}`);
|
|
170
172
|
console.log(`- Planned rules lines: ${plannedRuleLineCount}`);
|
|
171
173
|
console.log(`- Rules changed: ${isRulesContentChanged ? 'yes' : 'no'}`);
|
|
174
|
+
if (projectDocStalenessReport.hasProjectDocs) {
|
|
175
|
+
console.log(`- Project docs detected: ${projectDocStalenessReport.checkedFileNames.length}`);
|
|
176
|
+
console.log(`- Project docs expected template version: ${projectDocStalenessReport.expectedTemplateVersion}`);
|
|
177
|
+
console.log(`- Project docs stale files: ${projectDocStalenessReport.staleFiles.length}`);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (projectDocStalenessReport.staleFiles.length > 0) {
|
|
181
|
+
console.log('\n[WARN] Some project docs were generated from older template versions:');
|
|
182
|
+
for (const staleDoc of projectDocStalenessReport.staleFiles) {
|
|
183
|
+
const detectedVersionLabel = staleDoc.detectedTemplateVersion || 'missing';
|
|
184
|
+
console.log(`- docs/${staleDoc.fileName} (detected: ${detectedVersionLabel}, expected: ${projectDocStalenessReport.expectedTemplateVersion})`);
|
|
185
|
+
}
|
|
186
|
+
console.log('Recommendation: regenerate docs with init --scaffold-docs or update the files manually to match the latest template version.');
|
|
187
|
+
}
|
|
172
188
|
|
|
173
189
|
if (upgradeOptions.dryRun) {
|
|
174
190
|
console.log('\nDry run enabled. No files were modified.');
|
package/lib/cli/compiler.mjs
CHANGED
|
@@ -236,6 +236,37 @@ export async function buildCompiledRulesContent({
|
|
|
236
236
|
].join('\n')
|
|
237
237
|
);
|
|
238
238
|
|
|
239
|
+
const projectBriefPath = path.join(resolvedTargetDirectoryPath, 'docs', 'project-brief.md');
|
|
240
|
+
if (await pathExists(projectBriefPath)) {
|
|
241
|
+
const projectDocsEntries = ['project-brief.md'];
|
|
242
|
+
const candidateDocFileNames = [
|
|
243
|
+
'architecture-decision-record.md',
|
|
244
|
+
'database-schema.md',
|
|
245
|
+
'api-contract.md',
|
|
246
|
+
'flow-overview.md',
|
|
247
|
+
];
|
|
248
|
+
|
|
249
|
+
for (const candidateFileName of candidateDocFileNames) {
|
|
250
|
+
const candidateFilePath = path.join(resolvedTargetDirectoryPath, 'docs', candidateFileName);
|
|
251
|
+
if (await pathExists(candidateFilePath)) {
|
|
252
|
+
projectDocsEntries.push(candidateFileName);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
contextBlocks.push(
|
|
257
|
+
[
|
|
258
|
+
'## LAYER 9: PROJECT CONTEXT (MANDATORY)',
|
|
259
|
+
'These documents describe the specific project being built.',
|
|
260
|
+
'Read them before writing any application code:',
|
|
261
|
+
...projectDocsEntries.map((docFileName, docIndex) => `${docIndex + 1}. docs/${docFileName}`),
|
|
262
|
+
'',
|
|
263
|
+
'These docs were generated during project initialization and reflect the architecture,',
|
|
264
|
+
'database design, API contracts, and application flows chosen for this project.',
|
|
265
|
+
'Update them as the project evolves. They are living references, not frozen specs.',
|
|
266
|
+
].join('\n')
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
|
|
239
270
|
return [
|
|
240
271
|
'# AGENTIC-SENIOR-CORE DYNAMIC GOVERNANCE RULESET',
|
|
241
272
|
'',
|