@ryuenn3123/agentic-senior-core 3.0.12 → 3.0.14
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/rules/architecture.md +7 -0
- package/.agent-context/state/memory-continuity-benchmark.json +1 -1
- package/.cursorrules +1 -1
- package/.gemini/instructions.md +8 -7
- package/.github/copilot-instructions.md +8 -7
- package/.instructions.md +338 -0
- package/.windsurfrules +1 -1
- package/AGENTS.md +9 -8
- package/lib/cli/commands/init.mjs +214 -155
- package/lib/cli/commands/upgrade.mjs +11 -3
- package/lib/cli/compiler.mjs +13 -2
- package/lib/cli/detector.mjs +22 -0
- package/lib/cli/project-scaffolder.mjs +39 -27
- package/package.json +2 -1
- package/scripts/sync-thin-adapters.mjs +22 -19
- package/scripts/validate.mjs +6 -0
|
@@ -8,13 +8,13 @@ import fs from 'node:fs/promises';
|
|
|
8
8
|
import path from 'node:path';
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
|
+
PROJECT_SCOPE_CHOICES,
|
|
11
12
|
CLI_VERSION,
|
|
12
13
|
AGENT_CONTEXT_DIR,
|
|
13
14
|
INIT_PRESETS,
|
|
14
15
|
PROFILE_PRESETS,
|
|
15
16
|
GOLDEN_STANDARD_PROFILE_NAME,
|
|
16
17
|
BLUEPRINT_RECOMMENDATIONS,
|
|
17
|
-
PROJECT_SCOPE_CHOICES,
|
|
18
18
|
FALLBACK_STACK_FILE_NAMES,
|
|
19
19
|
FALLBACK_BLUEPRINT_FILE_NAMES,
|
|
20
20
|
RUNTIME_ENVIRONMENT_CHOICES,
|
|
@@ -42,10 +42,13 @@ import {
|
|
|
42
42
|
} from '../detector.mjs';
|
|
43
43
|
import { compileDynamicContext, writeSelectedPolicy, writeOnboardingReport } from '../compiler.mjs';
|
|
44
44
|
import {
|
|
45
|
+
filterStackFileNamesByCandidates,
|
|
45
46
|
filterBlueprintFileNamesByCandidates,
|
|
46
47
|
normalizeAdditionalStackSelection,
|
|
47
48
|
normalizeAdditionalBlueprintSelection,
|
|
48
49
|
deriveAdditionalBlueprintFileNamesFromStacks,
|
|
50
|
+
resolveScopeStackCandidates,
|
|
51
|
+
resolveScopeBlueprintCandidates,
|
|
49
52
|
} from '../init-selection.mjs';
|
|
50
53
|
import {
|
|
51
54
|
buildExistingProjectMajorConstraints,
|
|
@@ -75,11 +78,7 @@ import {
|
|
|
75
78
|
createMemoryContinuityState,
|
|
76
79
|
writeMemoryContinuityState,
|
|
77
80
|
} from '../memory-continuity.mjs';
|
|
78
|
-
import {
|
|
79
|
-
readArchitectPreferenceState,
|
|
80
|
-
writeArchitectPreferenceState,
|
|
81
|
-
} from '../architect.mjs';
|
|
82
|
-
import { resolveArchitectureSelection } from '../init-architecture-flow.mjs';
|
|
81
|
+
import { recommendArchitecture } from '../architect.mjs';
|
|
83
82
|
|
|
84
83
|
export { REPO_ROOT } from '../constants.mjs';
|
|
85
84
|
// Keep these architect option flags visible in the init command surface for validator coverage:
|
|
@@ -156,6 +155,82 @@ export function detectRuntimeEnvironment() {
|
|
|
156
155
|
};
|
|
157
156
|
}
|
|
158
157
|
|
|
158
|
+
function resolveProjectScopeLabelFromKey(projectScopeKey) {
|
|
159
|
+
return PROJECT_SCOPE_CHOICES.find((scopeChoice) => scopeChoice.key === projectScopeKey)?.label
|
|
160
|
+
|| PROJECT_SCOPE_CHOICES.find((scopeChoice) => scopeChoice.key === 'both')?.label
|
|
161
|
+
|| 'Both (frontend + backend)';
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function inferProjectScopeFromDiscoveryAnswers(discoveryAnswers) {
|
|
165
|
+
const normalizedDomain = String(discoveryAnswers?.primaryDomain || '').trim().toLowerCase();
|
|
166
|
+
const normalizedDescription = [
|
|
167
|
+
discoveryAnswers?.projectDescription,
|
|
168
|
+
...(Array.isArray(discoveryAnswers?.features) ? discoveryAnswers.features : []),
|
|
169
|
+
].join(' ').toLowerCase();
|
|
170
|
+
|
|
171
|
+
if (
|
|
172
|
+
normalizedDomain.includes('api service')
|
|
173
|
+
|| normalizedDomain.includes('cli tool')
|
|
174
|
+
|| normalizedDomain.includes('library')
|
|
175
|
+
) {
|
|
176
|
+
return 'backend-only';
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (normalizedDomain.includes('mobile app')) {
|
|
180
|
+
return 'frontend-only';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (normalizedDomain.includes('web application')) {
|
|
184
|
+
if (/(landing page|marketing site|showcase|portfolio|brochure|company profile)/.test(normalizedDescription)) {
|
|
185
|
+
return 'frontend-only';
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return 'both';
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return 'both';
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function resolveSilentCiGuardrailsDefault({
|
|
195
|
+
initOptions,
|
|
196
|
+
selectedPreset,
|
|
197
|
+
selectedProfilePack,
|
|
198
|
+
selectedProfile,
|
|
199
|
+
}) {
|
|
200
|
+
if (typeof initOptions.ci === 'boolean') {
|
|
201
|
+
return {
|
|
202
|
+
value: initOptions.ci,
|
|
203
|
+
shouldAsk: false,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (typeof selectedPreset?.ci === 'boolean') {
|
|
208
|
+
return {
|
|
209
|
+
value: selectedPreset.ci,
|
|
210
|
+
shouldAsk: false,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (typeof selectedProfilePack?.defaultCi === 'boolean') {
|
|
215
|
+
return {
|
|
216
|
+
value: selectedProfilePack.defaultCi,
|
|
217
|
+
shouldAsk: Boolean(!selectedProfilePack.lockCi),
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (selectedProfile.lockCi) {
|
|
222
|
+
return {
|
|
223
|
+
value: selectedProfile.defaultCi,
|
|
224
|
+
shouldAsk: false,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
value: selectedProfile.defaultCi,
|
|
230
|
+
shouldAsk: true,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
159
234
|
async function askStackSelection(promptMessage, selectableStackFileNames, userInterface) {
|
|
160
235
|
const stackDisplayChoices = selectableStackFileNames.map((stackFileName) => toTitleCase(stackFileName));
|
|
161
236
|
const selectedDisplayChoice = await askChoice(promptMessage, stackDisplayChoices, userInterface);
|
|
@@ -242,8 +317,6 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
242
317
|
const wasDirectoryEffectivelyEmpty = await isDirectoryEffectivelyEmpty(resolvedTargetDirectoryPath);
|
|
243
318
|
const hadExistingProjectDocsBeforeInit = await hasExistingProjectDocs(resolvedTargetDirectoryPath);
|
|
244
319
|
|
|
245
|
-
await createBackup(resolvedTargetDirectoryPath);
|
|
246
|
-
|
|
247
320
|
const userInterface = createInterface({ input: stdin, output: stdout });
|
|
248
321
|
|
|
249
322
|
try {
|
|
@@ -442,20 +515,21 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
442
515
|
let selectedAdditionalBlueprintFileNames = [];
|
|
443
516
|
let detectedSetupWasApplied = false;
|
|
444
517
|
let selectedProjectScopeKey = 'both';
|
|
445
|
-
let selectedProjectScopeLabel =
|
|
446
|
-
(scopeChoice) => scopeChoice.key === 'both'
|
|
447
|
-
)?.label || 'Both (frontend + backend)';
|
|
448
|
-
|
|
518
|
+
let selectedProjectScopeLabel = resolveProjectScopeLabelFromKey('both');
|
|
449
519
|
let architectureRecommendation = null;
|
|
450
|
-
let architectureProjectDescription = '';
|
|
451
|
-
let
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
520
|
+
let architectureProjectDescription = String(initOptions.projectDescription || '').trim();
|
|
521
|
+
let discoveryAnswers = null;
|
|
522
|
+
const ciGuardrailsSelection = resolveSilentCiGuardrailsDefault({
|
|
523
|
+
initOptions,
|
|
524
|
+
selectedPreset,
|
|
525
|
+
selectedProfilePack,
|
|
526
|
+
selectedProfile,
|
|
527
|
+
});
|
|
528
|
+
const isFreshProjectTarget = !projectDetection.hasExistingProjectFiles
|
|
529
|
+
&& wasDirectoryEffectivelyEmpty
|
|
530
|
+
&& !hadExistingProjectDocsBeforeInit;
|
|
531
|
+
const shouldRunInteractiveScaffolding = isInteractiveSession
|
|
532
|
+
&& (initOptions.scaffoldDocs === true || (initOptions.scaffoldDocs !== false && isFreshProjectTarget));
|
|
459
533
|
|
|
460
534
|
const detectedSetupDecision = await resolveDetectedSetupDecision({
|
|
461
535
|
shouldAutoApplyDetectedStack,
|
|
@@ -479,37 +553,76 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
479
553
|
selectedAdditionalStackFileNames = detectedSetupDecision.selectedAdditionalStackFileNames;
|
|
480
554
|
detectedBlueprintFileName = detectedSetupDecision.detectedBlueprintFileName;
|
|
481
555
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
556
|
+
if (initOptions.projectConfig) {
|
|
557
|
+
discoveryAnswers = await loadProjectConfig(initOptions.projectConfig);
|
|
558
|
+
console.log(`\nLoaded project configuration from: ${initOptions.projectConfig}`);
|
|
559
|
+
} else if (shouldRunInteractiveScaffolding) {
|
|
560
|
+
discoveryAnswers = await runProjectDiscovery(userInterface, {
|
|
561
|
+
defaultProjectName: path.basename(resolvedTargetDirectoryPath),
|
|
562
|
+
defaultProjectDescription: architectureProjectDescription,
|
|
563
|
+
defaultIncludeCiGuardrails: ciGuardrailsSelection.value,
|
|
564
|
+
askForCiGuardrails: ciGuardrailsSelection.shouldAsk,
|
|
565
|
+
});
|
|
566
|
+
} else if (initOptions.scaffoldDocs === true && !isInteractiveSession) {
|
|
567
|
+
throw new Error('Non-interactive scaffolding requires --project-config when --scaffold-docs is enabled.');
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
if (discoveryAnswers?.projectDescription) {
|
|
571
|
+
architectureProjectDescription = discoveryAnswers.projectDescription;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
if (discoveryAnswers) {
|
|
575
|
+
selectedProjectScopeKey = inferProjectScopeFromDiscoveryAnswers(discoveryAnswers);
|
|
576
|
+
selectedProjectScopeLabel = resolveProjectScopeLabelFromKey(selectedProjectScopeKey);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
const shouldUseSilentArchitectureSelection = !selectedStackFileNameFromOption
|
|
580
|
+
&& !selectedPreset?.stack
|
|
581
|
+
&& !shouldAutoApplyDetectedStack
|
|
582
|
+
&& !selectedProfilePack?.defaultStackFileName
|
|
583
|
+
&& !selectedProfile.defaultStackFileName;
|
|
584
|
+
|
|
585
|
+
if (shouldUseSilentArchitectureSelection) {
|
|
586
|
+
const architectureScopeStackCandidates = filterStackFileNamesByCandidates(
|
|
587
|
+
stackFileNames,
|
|
588
|
+
resolveScopeStackCandidates(selectedProjectScopeKey)
|
|
589
|
+
);
|
|
590
|
+
const architectureScopeBlueprintCandidates = filterBlueprintFileNamesByCandidates(
|
|
591
|
+
blueprintFileNames,
|
|
592
|
+
resolveScopeBlueprintCandidates(selectedProjectScopeKey)
|
|
593
|
+
);
|
|
594
|
+
|
|
595
|
+
architectureRecommendation = recommendArchitecture({
|
|
596
|
+
projectDescription: architectureProjectDescription || `A software project named ${path.basename(resolvedTargetDirectoryPath)}.`,
|
|
597
|
+
projectDetection,
|
|
598
|
+
stackFileNames: architectureScopeStackCandidates,
|
|
599
|
+
blueprintFileNames: architectureScopeBlueprintCandidates,
|
|
600
|
+
tokenBudget: initOptions.architectTokenBudget,
|
|
601
|
+
timeoutMs: initOptions.architectTimeoutMs,
|
|
487
602
|
researchMode: initOptions.architectResearchMode,
|
|
488
603
|
enableRealtimeResearch: initOptions.enableRealtimeResearch,
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
stackFileNames,
|
|
492
|
-
blueprintFileNames,
|
|
493
|
-
userInterface,
|
|
494
|
-
isInteractiveSession,
|
|
495
|
-
initialSelectedProjectScopeKey: selectedProjectScopeKey,
|
|
496
|
-
initialSelectedProjectScopeLabel: selectedProjectScopeLabel,
|
|
497
|
-
initialSelectedManualStackFileName: selectedManualStackFileName,
|
|
498
|
-
initialSelectedManualBlueprintFileName: selectedManualBlueprintFileName,
|
|
499
|
-
architectPreferenceState,
|
|
500
|
-
askStackSelection,
|
|
501
|
-
askBlueprintSelection,
|
|
502
|
-
detectionTransparency,
|
|
503
|
-
});
|
|
604
|
+
realtimeSignalFilePath: initOptions.architectRealtimeSignalFile,
|
|
605
|
+
});
|
|
504
606
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
607
|
+
architectureRecommendation.projectDomain = {
|
|
608
|
+
key: selectedProjectScopeKey,
|
|
609
|
+
label: selectedProjectScopeLabel,
|
|
610
|
+
};
|
|
611
|
+
architectureRecommendation.userVeto = {
|
|
612
|
+
applied: false,
|
|
613
|
+
selectedStackFileName: architectureRecommendation.recommendedStackFileName,
|
|
614
|
+
selectedBlueprintFileName: architectureRecommendation.recommendedBlueprintFileName,
|
|
615
|
+
source: projectDetection.hasExistingProjectFiles ? 'silent-existing-bootstrap' : 'silent-fresh-bootstrap',
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
selectedManualStackFileName = architectureRecommendation.recommendedStackFileName;
|
|
619
|
+
selectedManualBlueprintFileName = architectureRecommendation.recommendedBlueprintFileName;
|
|
620
|
+
|
|
621
|
+
if (!projectDetection.hasExistingProjectFiles) {
|
|
622
|
+
detectionTransparency.quickConfirmation.response = 'fresh-project-streamlined';
|
|
623
|
+
detectionTransparency.decision.mode = 'fresh-project-streamlined';
|
|
624
|
+
}
|
|
625
|
+
}
|
|
513
626
|
|
|
514
627
|
const blueprintDisplayChoices = blueprintFileNames.map((blueprintFileName) => toTitleCase(blueprintFileName));
|
|
515
628
|
|
|
@@ -550,15 +663,6 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
550
663
|
if (architectureRecommendation) {
|
|
551
664
|
architectureRecommendation.appliedStackFileName = selectedResolvedStackFileName;
|
|
552
665
|
architectureRecommendation.appliedBlueprintFileName = selectedResolvedBlueprintFileName;
|
|
553
|
-
|
|
554
|
-
if (!architectureRecommendation.userVeto) {
|
|
555
|
-
architectureRecommendation.userVeto = {
|
|
556
|
-
applied: false,
|
|
557
|
-
selectedStackFileName: selectedResolvedStackFileName,
|
|
558
|
-
selectedBlueprintFileName: selectedResolvedBlueprintFileName,
|
|
559
|
-
source: 'recommendation',
|
|
560
|
-
};
|
|
561
|
-
}
|
|
562
666
|
}
|
|
563
667
|
|
|
564
668
|
const derivedAdditionalBlueprintFileNames = deriveAdditionalBlueprintFileNamesFromStacks(
|
|
@@ -580,23 +684,25 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
580
684
|
detectionTransparency.decision.selectedAdditionalBlueprintFileNames = selectedAdditionalBlueprintFileNames;
|
|
581
685
|
detectionTransparency.decision.usedDetectedSetup = detectedSetupWasApplied;
|
|
582
686
|
|
|
583
|
-
const includeCiGuardrails = typeof
|
|
584
|
-
?
|
|
585
|
-
:
|
|
586
|
-
?
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
:
|
|
687
|
+
const includeCiGuardrails = typeof discoveryAnswers?.includeCiGuardrails === 'boolean'
|
|
688
|
+
? discoveryAnswers.includeCiGuardrails
|
|
689
|
+
: ciGuardrailsSelection.shouldAsk
|
|
690
|
+
? (!isInteractiveSession
|
|
691
|
+
? ciGuardrailsSelection.value
|
|
692
|
+
: await askYesNo(
|
|
693
|
+
'Enable CI/CD quality checks (guardrails) and the LLM Judge policy?',
|
|
694
|
+
userInterface,
|
|
695
|
+
ciGuardrailsSelection.value
|
|
696
|
+
))
|
|
697
|
+
: ciGuardrailsSelection.value;
|
|
594
698
|
|
|
595
699
|
detectionTransparency.activeRulesSummary.ciGuardrailsEnabled = includeCiGuardrails;
|
|
596
700
|
|
|
597
701
|
detectionTransparency.decision.selectedProjectScopeKey = selectedProjectScopeKey;
|
|
598
702
|
detectionTransparency.decision.selectedProjectScopeLabel = selectedProjectScopeLabel;
|
|
599
703
|
|
|
704
|
+
await createBackup(resolvedTargetDirectoryPath);
|
|
705
|
+
|
|
600
706
|
await copyGovernanceAssetsToTarget(resolvedTargetDirectoryPath, {
|
|
601
707
|
includeMcpTemplate: shouldIncludeMcpTemplate,
|
|
602
708
|
});
|
|
@@ -629,83 +735,50 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
629
735
|
// --- Project Documentation Scaffolding ---
|
|
630
736
|
let scaffoldingResult = null;
|
|
631
737
|
const supplementalMaterializedDocFileNames = [];
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
if (shouldOfferScaffolding) {
|
|
638
|
-
if (initOptions.scaffoldDocs === true && !initOptions.projectConfig && !isInteractiveSession) {
|
|
639
|
-
throw new Error('Non-interactive scaffolding requires --project-config when --scaffold-docs is enabled.');
|
|
738
|
+
if (discoveryAnswers) {
|
|
739
|
+
const normalizedConfigDocsLanguage = normalizeDocsLanguage(discoveryAnswers.docsLang || '');
|
|
740
|
+
if (discoveryAnswers.docsLang && !normalizedConfigDocsLanguage) {
|
|
741
|
+
throw new Error(`Unsupported docs language in project config: ${discoveryAnswers.docsLang}. Supported values: en, id`);
|
|
640
742
|
}
|
|
641
743
|
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
? false
|
|
646
|
-
: await askYesNo(
|
|
647
|
-
'This is a fresh project. Want me to scaffold project documentation (architecture, database, API contract, flow)?',
|
|
648
|
-
userInterface,
|
|
649
|
-
true
|
|
650
|
-
));
|
|
744
|
+
// Keep generated docs in English by default to align with the writing scope.
|
|
745
|
+
// A different output language is only used when explicitly requested via --docs-lang.
|
|
746
|
+
const selectedDocsLanguage = initOptions.docsLang;
|
|
651
747
|
|
|
652
|
-
if (
|
|
653
|
-
|
|
748
|
+
if (!initOptions.docsLangProvided && normalizedConfigDocsLanguage && normalizedConfigDocsLanguage !== 'en') {
|
|
749
|
+
console.log('[INFO] Project config docsLang is set, but output defaults to English. Use --docs-lang to override.');
|
|
750
|
+
}
|
|
654
751
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
752
|
+
scaffoldingResult = await generateProjectDocumentation(
|
|
753
|
+
resolvedTargetDirectoryPath,
|
|
754
|
+
discoveryAnswers,
|
|
755
|
+
{
|
|
756
|
+
stackFileName: selectedResolvedStackFileName,
|
|
757
|
+
additionalStackFileNames: selectedAdditionalStackFileNames,
|
|
758
|
+
blueprintFileName: selectedResolvedBlueprintFileName,
|
|
759
|
+
additionalBlueprintFileNames: selectedAdditionalBlueprintFileNames,
|
|
760
|
+
runtimeEnvironmentKey: selectedRuntimeEnvironmentKey,
|
|
761
|
+
runtimeEnvironmentLabel: resolveRuntimeEnvironmentLabelFromKey(selectedRuntimeEnvironmentKey),
|
|
762
|
+
architectureRecommendation,
|
|
763
|
+
},
|
|
764
|
+
{
|
|
765
|
+
docsLanguage: selectedDocsLanguage,
|
|
663
766
|
}
|
|
767
|
+
);
|
|
664
768
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
769
|
+
if (scaffoldingResult.bootstrapMode === 'ai-synthesis') {
|
|
770
|
+
console.log(`\nAI synthesis bootstrap prompts generated in .agent-context/prompts/:`);
|
|
771
|
+
for (const generatedPromptFileName of scaffoldingResult.generatedPromptFileNames || []) {
|
|
772
|
+
console.log(` - .agent-context/prompts/${generatedPromptFileName}`);
|
|
668
773
|
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
// A different output language is only used when explicitly requested via --docs-lang.
|
|
672
|
-
const selectedDocsLanguage = initOptions.docsLang;
|
|
673
|
-
|
|
674
|
-
if (!initOptions.docsLangProvided && normalizedConfigDocsLanguage && normalizedConfigDocsLanguage !== 'en') {
|
|
675
|
-
console.log('[INFO] Project config docsLang is set, but output defaults to English. Use --docs-lang to override.');
|
|
774
|
+
for (const materializedFileName of scaffoldingResult.materializedFileNames || []) {
|
|
775
|
+
console.log(` - docs/${materializedFileName}`);
|
|
676
776
|
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
{
|
|
682
|
-
stackFileName: selectedResolvedStackFileName,
|
|
683
|
-
additionalStackFileNames: selectedAdditionalStackFileNames,
|
|
684
|
-
blueprintFileName: selectedResolvedBlueprintFileName,
|
|
685
|
-
additionalBlueprintFileNames: selectedAdditionalBlueprintFileNames,
|
|
686
|
-
runtimeEnvironmentKey: selectedRuntimeEnvironmentKey,
|
|
687
|
-
runtimeEnvironmentLabel: resolveRuntimeEnvironmentLabelFromKey(selectedRuntimeEnvironmentKey),
|
|
688
|
-
architectureRecommendation,
|
|
689
|
-
},
|
|
690
|
-
{
|
|
691
|
-
docsLanguage: selectedDocsLanguage,
|
|
692
|
-
}
|
|
693
|
-
);
|
|
694
|
-
|
|
695
|
-
if (scaffoldingResult.bootstrapMode === 'ai-synthesis') {
|
|
696
|
-
console.log(`\nAI synthesis bootstrap prompts generated in .agent-context/prompts/:`);
|
|
697
|
-
for (const generatedPromptFileName of scaffoldingResult.generatedPromptFileNames || []) {
|
|
698
|
-
console.log(` - .agent-context/prompts/${generatedPromptFileName}`);
|
|
699
|
-
}
|
|
700
|
-
for (const materializedFileName of scaffoldingResult.materializedFileNames || []) {
|
|
701
|
-
console.log(` - docs/${materializedFileName}`);
|
|
702
|
-
}
|
|
703
|
-
console.log('Project docs will be authored dynamically by your IDE assistant from these prompts.');
|
|
704
|
-
} else {
|
|
705
|
-
console.log(`\nProject documentation generated in docs/:`);
|
|
706
|
-
for (const generatedFileName of scaffoldingResult.generatedFileNames) {
|
|
707
|
-
console.log(` - docs/${generatedFileName}`);
|
|
708
|
-
}
|
|
777
|
+
console.log('Project docs will be authored dynamically by your IDE assistant from these prompts.');
|
|
778
|
+
} else {
|
|
779
|
+
console.log(`\nProject documentation generated in docs/:`);
|
|
780
|
+
for (const generatedFileName of scaffoldingResult.generatedFileNames) {
|
|
781
|
+
console.log(` - docs/${generatedFileName}`);
|
|
709
782
|
}
|
|
710
783
|
}
|
|
711
784
|
}
|
|
@@ -795,10 +868,6 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
795
868
|
uiScopeSignals: existingProjectUiScopeSignals,
|
|
796
869
|
});
|
|
797
870
|
|
|
798
|
-
if (architectPreferenceUpdated && architectPreferenceState) {
|
|
799
|
-
await writeArchitectPreferenceState(architectPreferenceState);
|
|
800
|
-
}
|
|
801
|
-
|
|
802
871
|
console.log('\nInitialization complete.');
|
|
803
872
|
console.log(`- Target directory: ${resolvedTargetDirectoryPath}`);
|
|
804
873
|
console.log(`- Profile: ${selectedProfile.displayName}`);
|
|
@@ -808,18 +877,8 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
808
877
|
if (selectedProfilePack) {
|
|
809
878
|
console.log(`- Team profile pack: ${selectedProfilePack.displayName}`);
|
|
810
879
|
}
|
|
811
|
-
if (
|
|
812
|
-
console.log(
|
|
813
|
-
`- Architect recommendation: ${toTitleCase(architectureRecommendation.recommendedStackFileName)} + ${toTitleCase(architectureRecommendation.recommendedBlueprintFileName)} (${architectureRecommendation.confidenceLabel})`
|
|
814
|
-
);
|
|
815
|
-
if (!projectDetection.hasExistingProjectFiles) {
|
|
816
|
-
console.log(`- Project domain: ${selectedProjectScopeLabel}`);
|
|
817
|
-
}
|
|
818
|
-
if (architectureRecommendation.userVeto?.applied) {
|
|
819
|
-
console.log(
|
|
820
|
-
`- User veto path: applied (${toTitleCase(architectureRecommendation.userVeto.selectedStackFileName)} + ${toTitleCase(architectureRecommendation.userVeto.selectedBlueprintFileName)})`
|
|
821
|
-
);
|
|
822
|
-
}
|
|
880
|
+
if (!projectDetection.hasExistingProjectFiles) {
|
|
881
|
+
console.log(`- Project domain: ${selectedProjectScopeLabel}`);
|
|
823
882
|
}
|
|
824
883
|
console.log(`- Stack: ${toTitleCase(selectedResolvedStackFileName)}`);
|
|
825
884
|
if (selectedAdditionalStackFileNames.length > 0) {
|
|
@@ -833,7 +892,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
833
892
|
console.log(`- CI/CD quality checks (guardrails): ${includeCiGuardrails ? 'enabled' : 'disabled'}`);
|
|
834
893
|
console.log(`- Blocking severities: ${formatBlockingSeverities(selectedProfile.blockingSeverities)}`);
|
|
835
894
|
console.log(`- Setup time: ${formatDuration(setupDurationMs)}`);
|
|
836
|
-
console.log('- Generated files: .
|
|
895
|
+
console.log('- Generated files: .instructions.md, .agent-instructions.md, compiled adapters, and .agent-context/state/onboarding-report.json');
|
|
837
896
|
if (scaffoldingResult?.bootstrapMode === 'ai-synthesis') {
|
|
838
897
|
console.log(`- Bootstrap prompts: ${(scaffoldingResult.generatedPromptFileNames || []).length} files generated in .agent-context/prompts/`);
|
|
839
898
|
if ((scaffoldingResult.materializedFileNames || []).length > 0) {
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
} from '../detector.mjs';
|
|
34
34
|
import {
|
|
35
35
|
buildCompiledRulesContent,
|
|
36
|
+
compileDynamicContext,
|
|
36
37
|
writeSelectedPolicy,
|
|
37
38
|
writeOnboardingReport,
|
|
38
39
|
loadOnboardingReportIfExists,
|
|
@@ -408,8 +409,15 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
408
409
|
supplementalCreatedFileNames.push('docs/design-intent.json');
|
|
409
410
|
}
|
|
410
411
|
|
|
411
|
-
await
|
|
412
|
-
|
|
412
|
+
await compileDynamicContext({
|
|
413
|
+
targetDirectoryPath: resolvedTargetDirectoryPath,
|
|
414
|
+
selectedProfileName,
|
|
415
|
+
selectedStackFileName,
|
|
416
|
+
selectedAdditionalStackFileNames,
|
|
417
|
+
selectedBlueprintFileName,
|
|
418
|
+
selectedAdditionalBlueprintFileNames,
|
|
419
|
+
includeCiGuardrails,
|
|
420
|
+
});
|
|
413
421
|
await writeSelectedPolicy(resolvedTargetDirectoryPath, selectedProfileName);
|
|
414
422
|
|
|
415
423
|
const setupDurationMs = Date.now() - setupStartedAt;
|
|
@@ -452,7 +460,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
452
460
|
supplementalCreatedFileNames.forEach((fileName) => console.log(` [NEW] ${fileName} (seed)`));
|
|
453
461
|
}
|
|
454
462
|
|
|
455
|
-
console.log('\nRefreshed files: .
|
|
463
|
+
console.log('\nRefreshed files: .instructions.md, .agent-instructions.md, compiled adapters, and .agent-context/state/onboarding-report.json');
|
|
456
464
|
} catch (error) {
|
|
457
465
|
console.error('\n[FATAL] An error occurred during upgrade. Attempting automatic rollback...');
|
|
458
466
|
try {
|
package/lib/cli/compiler.mjs
CHANGED
|
@@ -188,8 +188,8 @@ export async function buildCompiledRulesContent({
|
|
|
188
188
|
`6. .agent-context/policies/${POLICY_FILE_NAME}`,
|
|
189
189
|
'7. docs/ project context (or bootstrap prompts when docs are not materialized)',
|
|
190
190
|
'',
|
|
191
|
-
'
|
|
192
|
-
'
|
|
191
|
+
'Project-specific compiled snapshot: .agent-instructions.md',
|
|
192
|
+
'Compiled adapter entrypoints: .cursorrules, .windsurfrules, .clauderc, .gemini/instructions.md, .github/copilot-instructions.md',
|
|
193
193
|
'Canonical baseline: .instructions.md',
|
|
194
194
|
].join('\n')
|
|
195
195
|
);
|
|
@@ -396,9 +396,15 @@ export async function buildCompiledRulesContent({
|
|
|
396
396
|
...projectDocsEntries.map((docFileName, docIndex) => `${docIndex + 1}. docs/${docFileName}`),
|
|
397
397
|
'',
|
|
398
398
|
'Universal SOP hard block policy:',
|
|
399
|
+
'- Stop implementation if docs/project-brief.md is missing.',
|
|
399
400
|
'- Stop implementation if docs/architecture-decision-record.md (alias: docs/Architecture-Decision-Record.md) is missing.',
|
|
401
|
+
'- Stop implementation if docs/flow-overview.md is missing.',
|
|
402
|
+
'- If the product uses persistent data, docs/database-schema.md must exist before coding continues.',
|
|
403
|
+
'- If the product exposes API or web application flows, docs/api-contract.md must exist before coding continues.',
|
|
400
404
|
'- For UI scope, stop implementation if docs/DESIGN.md or docs/design-intent.json is missing.',
|
|
401
405
|
'- Materialize missing docs first, then continue coding.',
|
|
406
|
+
'- Bootstrap missing docs from real repo evidence and the latest user request. Do not write generic placeholder templates.',
|
|
407
|
+
'- Separate confirmed facts from assumptions and end each major explanation with the next validation action.',
|
|
402
408
|
'',
|
|
403
409
|
'These docs were generated during project initialization and reflect the architecture,',
|
|
404
410
|
'database design, API contracts, and application flows chosen for this project.',
|
|
@@ -428,10 +434,15 @@ export async function buildCompiledRulesContent({
|
|
|
428
434
|
'',
|
|
429
435
|
'Bootstrap policy:',
|
|
430
436
|
'- Hard block: do not write application code until docs/project-brief.md and docs/architecture-decision-record.md exist.',
|
|
437
|
+
'- docs/flow-overview.md must also exist before coding continues.',
|
|
438
|
+
'- Add docs/database-schema.md when persistent data is involved.',
|
|
439
|
+
'- Add docs/api-contract.md when API or web application flows are involved.',
|
|
431
440
|
'- If docs/project-brief.md is missing, execute bootstrap-project-context prompt immediately.',
|
|
432
441
|
hasBootstrapDesignPrompt
|
|
433
442
|
? '- For UI scope: if docs/DESIGN.md or docs/design-intent.json is missing, execute bootstrap-design prompt before implementing UI surfaces.'
|
|
434
443
|
: '- For UI scope: add a design bootstrap prompt before implementing UI surfaces.',
|
|
444
|
+
'- Bootstrap docs from repo evidence and the latest user request. Do not use generic placeholder templates.',
|
|
445
|
+
'- Separate confirmed facts from assumptions, include an Assumptions to Validate section when context is incomplete, and end with the next validation action.',
|
|
435
446
|
'- Save generated docs under docs/ and keep them updated when feature scope changes.',
|
|
436
447
|
'Latest user prompt defines current feature scope and product direction.',
|
|
437
448
|
'Treat synthesized docs as living references, then continue implementation with those docs as source of truth.',
|
package/lib/cli/detector.mjs
CHANGED
|
@@ -100,6 +100,24 @@ const PROJECT_MARKER_FILE_NAMES = new Set([
|
|
|
100
100
|
'tsconfig.json',
|
|
101
101
|
...DIRECT_UI_MARKER_NAMES,
|
|
102
102
|
]);
|
|
103
|
+
const INTERNAL_GOVERNANCE_SURFACE_NAMES = new Set([
|
|
104
|
+
'.agent-context',
|
|
105
|
+
'.agent-instructions.md',
|
|
106
|
+
'.agent-override.md',
|
|
107
|
+
'.agentic-backup',
|
|
108
|
+
'.agents',
|
|
109
|
+
'.clauderc',
|
|
110
|
+
'.cursorrules',
|
|
111
|
+
'.cursor',
|
|
112
|
+
'.gemini',
|
|
113
|
+
'.github',
|
|
114
|
+
'.instructions.md',
|
|
115
|
+
'.vscode',
|
|
116
|
+
'.windsurfrules',
|
|
117
|
+
'.zed',
|
|
118
|
+
'AGENTS.md',
|
|
119
|
+
'mcp.json',
|
|
120
|
+
]);
|
|
103
121
|
|
|
104
122
|
function looksLikeWorkspaceSearchCandidate(directoryName) {
|
|
105
123
|
const normalizedDirectoryName = String(directoryName || '').trim().toLowerCase();
|
|
@@ -148,6 +166,10 @@ export async function collectProjectMarkers(targetDirectoryPath) {
|
|
|
148
166
|
continue;
|
|
149
167
|
}
|
|
150
168
|
|
|
169
|
+
if (INTERNAL_GOVERNANCE_SURFACE_NAMES.has(directoryEntry.name)) {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
|
|
151
173
|
markerNames.add(directoryEntry.name);
|
|
152
174
|
}
|
|
153
175
|
|