@ryuenn3123/agentic-senior-core 3.0.5 → 3.0.7
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/prompts/bootstrap-design.md +38 -12
- package/.agent-context/prompts/init-project.md +3 -3
- package/.agent-context/prompts/refactor.md +1 -1
- package/.agent-context/prompts/review-code.md +1 -1
- package/.agent-context/review-checklists/pr-checklist.md +1 -1
- package/.agent-context/rules/architecture.md +1 -1
- package/.agent-context/state/memory-continuity-benchmark.json +1 -1
- package/.cursorrules +2 -2
- package/.gemini/instructions.md +1 -1
- package/.github/copilot-instructions.md +1 -1
- package/.windsurfrules +2 -2
- package/AGENTS.md +1 -1
- package/README.md +5 -5
- package/lib/cli/commands/init.mjs +14 -1
- package/lib/cli/commands/upgrade.mjs +139 -3
- package/lib/cli/compiler.mjs +6 -2
- package/lib/cli/init-architecture-flow.mjs +2 -0
- package/lib/cli/project-scaffolder.mjs +214 -223
- package/lib/cli/utils.mjs +108 -43
- package/package.json +1 -1
- package/scripts/validate.mjs +39 -4
|
@@ -1,22 +1,48 @@
|
|
|
1
1
|
|
|
2
|
-
# Bootstrap
|
|
2
|
+
# Bootstrap Dynamic Design Contract
|
|
3
3
|
|
|
4
|
-
When a user requests frontend design or redesign, the agent should automatically synthesize a
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- User journey and interaction flows
|
|
10
|
-
- Design tokens and handoff notes for developers
|
|
4
|
+
When a user requests frontend design or redesign, the agent should automatically synthesize a dynamic design contract made of:
|
|
5
|
+
- `docs/DESIGN.md` for human-readable design direction and implementation rationale
|
|
6
|
+
- `docs/design-intent.json` for machine-readable intent, anti-generic constraints, and validation hints
|
|
7
|
+
|
|
8
|
+
This contract is a structure and reasoning system, not a fixed visual template. It must adapt to product context, user needs, platform constraints, and current design signals.
|
|
11
9
|
|
|
12
10
|
The agent must:
|
|
13
11
|
1. Read [AGENTS.md](../../AGENTS.md) for project context and team roles.
|
|
14
12
|
2. Scan all files in [.agent-context/rules/](../rules/) for UI/UX and accessibility standards.
|
|
15
13
|
3. Reference [docs/deep-dive.md](../../docs/deep-dive.md) and [docs/faq.md](../../docs/faq.md) for architecture and product background.
|
|
16
|
-
4. If [docs/DESIGN.md](../../docs/DESIGN.md) exists, check for drift and
|
|
17
|
-
5.
|
|
14
|
+
4. If [docs/DESIGN.md](../../docs/DESIGN.md) or `docs/design-intent.json` already exists, check for drift and improve them instead of rewriting blindly.
|
|
15
|
+
5. Treat any example structure or stylistic inspiration as non-normative. Use it only to judge depth and clarity, never to copy a visual language directly.
|
|
16
|
+
6. All references to docs or rules must be clickable markdown links.
|
|
17
|
+
|
|
18
|
+
Required `docs/DESIGN.md` sections:
|
|
19
|
+
1. Design Intent and Product Personality
|
|
20
|
+
2. Audience and Use-Context Signals
|
|
21
|
+
3. Visual Direction and Distinctive Moves
|
|
22
|
+
4. Color System and Semantic Roles
|
|
23
|
+
5. Typography System and Hierarchy
|
|
24
|
+
6. Spacing, Layout Rhythm, and Density Strategy
|
|
25
|
+
7. Interaction, Motion, and Feedback Rules
|
|
26
|
+
8. Component Language and Shared Patterns
|
|
27
|
+
9. Accessibility Non-Negotiables
|
|
28
|
+
10. Responsive Strategy
|
|
29
|
+
11. Anti-Patterns to Avoid
|
|
30
|
+
12. Implementation Notes for Future UI Tasks
|
|
31
|
+
|
|
32
|
+
Required `docs/design-intent.json` fields:
|
|
33
|
+
- `mode`
|
|
34
|
+
- `status`
|
|
35
|
+
- `project`
|
|
36
|
+
- `brandAdjectives`
|
|
37
|
+
- `antiAdjectives`
|
|
38
|
+
- `visualDirection`
|
|
39
|
+
- `experiencePrinciples`
|
|
40
|
+
- `forbiddenPatterns`
|
|
41
|
+
- `requiredDesignSections`
|
|
42
|
+
- `implementation`
|
|
18
43
|
|
|
19
44
|
Output:
|
|
20
|
-
-
|
|
21
|
-
-
|
|
45
|
+
- Create or update both `docs/DESIGN.md` and `docs/design-intent.json`.
|
|
46
|
+
- Keep both files synchronized: the markdown explains the why, the JSON captures the contract in machine-readable form.
|
|
47
|
+
- Use practical, modern, accessible language grounded in the project, not generic SaaS defaults.
|
|
22
48
|
- Wait for user approval before generating Figma or code assets.
|
|
@@ -35,7 +35,7 @@ If the user specifies a framework/blueprint, the agent should:
|
|
|
35
35
|
See [docs/roadmap.md](../../docs/roadmap.md) and [docs/deep-dive.md](../../docs/deep-dive.md) for the latest stack and blueprint list.
|
|
36
36
|
|
|
37
37
|
## UI/UX Bootstrap
|
|
38
|
-
When a user requests frontend or UI/UX design, the agent should automatically execute the [bootstrap-design.md](./bootstrap-design.md) prompt to synthesize DESIGN.md.
|
|
38
|
+
When a user requests frontend or UI/UX design, the agent should automatically execute the [bootstrap-design.md](./bootstrap-design.md) prompt to synthesize a dynamic design contract (`docs/DESIGN.md` + `docs/design-intent.json`).
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
@@ -97,6 +97,6 @@ See [docs/roadmap.md](../../docs/roadmap.md) and [docs/deep-dive.md](../../docs/
|
|
|
97
97
|
|
|
98
98
|
---
|
|
99
99
|
|
|
100
|
-
## Bootstrap UI/UX (
|
|
100
|
+
## Bootstrap UI/UX (Dynamic Design Contract)
|
|
101
101
|
|
|
102
|
-
To start UI/UX design from scratch, use the [bootstrap-design.md](./bootstrap-design.md) prompt to synthesize `docs/DESIGN.md`.
|
|
102
|
+
To start UI/UX design from scratch, use the [bootstrap-design.md](./bootstrap-design.md) prompt to synthesize `docs/DESIGN.md` and `docs/design-intent.json`.
|
|
@@ -15,7 +15,7 @@ Before making changes:
|
|
|
15
15
|
3. Read .agent-context/rules/error-handling.md — fix error handling patterns.
|
|
16
16
|
4. Resolve active language guidance from dynamic stack signals (TypeScript in this repository).
|
|
17
17
|
5. Enforce backend universal principles: no clever hacks, no premature abstraction, readability over brevity.
|
|
18
|
-
6. Enforce Universal SOP hard gate: stop implementation if `docs/architecture-decision-record.md` is missing, and for UI scope stop if `docs/DESIGN.md` is missing.
|
|
18
|
+
6. Enforce Universal SOP hard gate: stop implementation if `docs/architecture-decision-record.md` is missing, and for UI scope stop if `docs/DESIGN.md` or `docs/design-intent.json` is missing.
|
|
19
19
|
|
|
20
20
|
For every change you make, provide a Reasoning Chain:
|
|
21
21
|
- What was wrong (rule reference)
|
|
@@ -20,7 +20,7 @@ Use these checklists:
|
|
|
20
20
|
7. Enforce cross-session consistency guardian: session handoff must include active architecture contract summary, drift detection must warn before direction changes, and direction changes require explicit user confirmation.
|
|
21
21
|
8. Enforce explain-on-demand state visibility: default responses must avoid unnecessary state-file internals, state internals are exposed only on explicit request, and diagnostic mode must explain relevant state decisions when needed.
|
|
22
22
|
9. Enforce single-source and lazy-loading policy: canonical rule source must be explicitly enforced, language-specific guidance must load lazily based on detected scope, and conflicting duplicate rule instructions must not appear during normal flow.
|
|
23
|
-
10. Enforce Universal SOP hard gate: block coding flow when required project docs are missing (`docs/architecture-decision-record.md`, and for UI scope `docs/DESIGN.md`).
|
|
23
|
+
10. Enforce Universal SOP hard gate: block coding flow when required project docs are missing (`docs/architecture-decision-record.md`, and for UI scope `docs/DESIGN.md` plus `docs/design-intent.json`).
|
|
24
24
|
|
|
25
25
|
For EVERY violation found:
|
|
26
26
|
- State the exact file and line
|
|
@@ -135,4 +135,4 @@ VERDICT: PASS / FAIL (X/Y items passed)
|
|
|
135
135
|
- [ ] Backend and frontend mindset checks are both applied when scope spans API and UI boundaries
|
|
136
136
|
- [ ] Security and testing requirements remain mandatory after static template purge
|
|
137
137
|
- [ ] Coding flow is blocked if `docs/architecture-decision-record.md` (or `docs/Architecture-Decision-Record.md`) is missing
|
|
138
|
-
- [ ] UI implementation flow is blocked if `docs/DESIGN.md` is missing
|
|
138
|
+
- [ ] UI implementation flow is blocked if `docs/DESIGN.md` or `docs/design-intent.json` is missing
|
|
@@ -21,7 +21,7 @@ The `.agent-context/rules/` directory is the default guidance source for impleme
|
|
|
21
21
|
- Security and testing are non-negotiable baseline requirements.
|
|
22
22
|
- Hard block before coding:
|
|
23
23
|
- `docs/architecture-decision-record.md` (alias: `docs/Architecture-Decision-Record.md`) must exist.
|
|
24
|
-
- For UI scope, `docs/DESIGN.md` must exist.
|
|
24
|
+
- For UI scope, `docs/DESIGN.md` and `docs/design-intent.json` must exist.
|
|
25
25
|
- If required project context docs are missing, stop implementation and bootstrap docs before writing application code.
|
|
26
26
|
|
|
27
27
|
## Rules as Guardian (Cross-Session Consistency)
|
package/.cursorrules
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AGENTIC-SENIOR-CORE DYNAMIC GOVERNANCE RULESET
|
|
2
2
|
|
|
3
|
-
Generated by Agentic-Senior-Core CLI v3.0.
|
|
3
|
+
Generated by Agentic-Senior-Core CLI v3.0.7
|
|
4
4
|
Timestamp: 2026-04-18T00:00:00.000Z
|
|
5
5
|
Selected profile: beginner
|
|
6
6
|
Selected policy file: .agent-context/policies/llm-judge-threshold.json
|
|
@@ -46,4 +46,4 @@ Do not claim done before checklist pass.
|
|
|
46
46
|
|
|
47
47
|
## UNIVERSAL SOP HARD GATES
|
|
48
48
|
- Stop coding if docs/architecture-decision-record.md (or docs/Architecture-Decision-Record.md) is missing.
|
|
49
|
-
- For UI scope, stop coding if docs/DESIGN.md is missing.
|
|
49
|
+
- For UI scope, stop coding if docs/DESIGN.md or docs/design-intent.json is missing.
|
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: 08c326d79f2c0f4bd7ef106da3542ab0f78f4d02bc205d63598db34cf3f40731
|
|
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: 08c326d79f2c0f4bd7ef106da3542ab0f78f4d02bc205d63598db34cf3f40731
|
|
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 v3.0.
|
|
3
|
+
Generated by Agentic-Senior-Core CLI v3.0.7
|
|
4
4
|
Timestamp: 2026-04-18T00:00:00.000Z
|
|
5
5
|
Selected profile: beginner
|
|
6
6
|
Selected policy file: .agent-context/policies/llm-judge-threshold.json
|
|
@@ -46,4 +46,4 @@ Do not claim done before checklist pass.
|
|
|
46
46
|
|
|
47
47
|
## UNIVERSAL SOP HARD GATES
|
|
48
48
|
- Stop coding if docs/architecture-decision-record.md (or docs/Architecture-Decision-Record.md) is missing.
|
|
49
|
-
- For UI scope, stop coding if docs/DESIGN.md is missing.
|
|
49
|
+
- For UI scope, stop coding if docs/DESIGN.md or docs/design-intent.json is missing.
|
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: 08c326d79f2c0f4bd7ef106da3542ab0f78f4d02bc205d63598db34cf3f40731
|
|
6
6
|
|
|
7
7
|
This file is an adapter entrypoint for agent discovery.
|
|
8
8
|
The canonical policy source is [.instructions.md](.instructions.md).
|
package/README.md
CHANGED
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
**Production-grade Rules Engine (Governance Engine) for AI coding agents.**
|
|
11
11
|
Works with Cursor, Windsurf, GitHub Copilot, Claude Code, Gemini, and other LLM-powered IDE workflows.
|
|
12
12
|
|
|
13
|
-
Latest release: 3.0.
|
|
13
|
+
Latest release: 3.0.7 (2026-04-20).
|
|
14
14
|
|
|
15
|
-
Highlights in 3.0.
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
- Init
|
|
15
|
+
Highlights in 3.0.7:
|
|
16
|
+
- Dynamic UI design contract bootstrap now ships paired markdown and machine-readable intent.
|
|
17
|
+
- Upgrade warns when existing UI repositories are missing required design contract files.
|
|
18
|
+
- Init discovery stays slimmer by reusing architecture context and removing redundant wizard branches.
|
|
19
19
|
|
|
20
20
|
</div>
|
|
21
21
|
|
|
@@ -399,6 +399,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
399
399
|
)?.label || 'Both (frontend + backend)';
|
|
400
400
|
|
|
401
401
|
let architectureRecommendation = null;
|
|
402
|
+
let architectureProjectDescription = '';
|
|
402
403
|
let architectPreferenceState = await readArchitectPreferenceState();
|
|
403
404
|
let architectPreferenceUpdated = false;
|
|
404
405
|
|
|
@@ -457,6 +458,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
457
458
|
selectedProjectScopeLabel = architectureSelection.selectedProjectScopeLabel;
|
|
458
459
|
selectedManualStackFileName = architectureSelection.selectedManualStackFileName;
|
|
459
460
|
selectedManualBlueprintFileName = architectureSelection.selectedManualBlueprintFileName;
|
|
461
|
+
architectureProjectDescription = architectureSelection.architectureProjectDescription;
|
|
460
462
|
architectureRecommendation = architectureSelection.architectureRecommendation;
|
|
461
463
|
architectPreferenceState = architectureSelection.architectPreferenceState;
|
|
462
464
|
architectPreferenceUpdated = architectureSelection.architectPreferenceUpdated;
|
|
@@ -607,6 +609,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
607
609
|
} else {
|
|
608
610
|
discoveryAnswers = await runProjectDiscovery(userInterface, {
|
|
609
611
|
defaultProjectName: path.basename(resolvedTargetDirectoryPath),
|
|
612
|
+
defaultProjectDescription: architectureProjectDescription,
|
|
610
613
|
});
|
|
611
614
|
}
|
|
612
615
|
|
|
@@ -645,6 +648,9 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
645
648
|
for (const generatedPromptFileName of scaffoldingResult.generatedPromptFileNames || []) {
|
|
646
649
|
console.log(` - .agent-context/prompts/${generatedPromptFileName}`);
|
|
647
650
|
}
|
|
651
|
+
for (const materializedFileName of scaffoldingResult.materializedFileNames || []) {
|
|
652
|
+
console.log(` - docs/${materializedFileName}`);
|
|
653
|
+
}
|
|
648
654
|
console.log('Project docs will be authored dynamically by your IDE assistant from these prompts.');
|
|
649
655
|
} else {
|
|
650
656
|
console.log(`\nProject documentation generated in docs/:`);
|
|
@@ -674,6 +680,10 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
674
680
|
selectedProfileName,
|
|
675
681
|
selectedProfilePack,
|
|
676
682
|
selectedPreset: initOptions.preset || null,
|
|
683
|
+
projectScope: {
|
|
684
|
+
key: selectedProjectScopeKey,
|
|
685
|
+
label: selectedProjectScopeLabel,
|
|
686
|
+
},
|
|
677
687
|
selectedStackFileName: selectedResolvedStackFileName,
|
|
678
688
|
selectedAdditionalStackFileNames,
|
|
679
689
|
selectedBlueprintFileName: selectedResolvedBlueprintFileName,
|
|
@@ -746,6 +756,9 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
746
756
|
console.log('- Generated files: .agent-instructions.md, .cursorrules, .windsurfrules, .clauderc, and .agent-context/state/onboarding-report.json');
|
|
747
757
|
if (scaffoldingResult?.bootstrapMode === 'ai-synthesis') {
|
|
748
758
|
console.log(`- Bootstrap prompts: ${(scaffoldingResult.generatedPromptFileNames || []).length} files generated in .agent-context/prompts/`);
|
|
759
|
+
if ((scaffoldingResult.materializedFileNames || []).length > 0) {
|
|
760
|
+
console.log(`- Seed docs: ${(scaffoldingResult.materializedFileNames || []).length} files generated in docs/`);
|
|
761
|
+
}
|
|
749
762
|
console.log(`- Bootstrap docs language: ${scaffoldingResult.docsLanguage}`);
|
|
750
763
|
console.log(`- Expected project docs after synthesis: ${scaffoldingResult.generatedFileNames.length} files in docs/`);
|
|
751
764
|
} else if (scaffoldingResult) {
|
|
@@ -779,7 +792,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
779
792
|
console.log('\nPrompt starter examples (copy and adapt in your IDE):');
|
|
780
793
|
console.log('- If docs/project-brief.md is missing, execute .agent-context/prompts/bootstrap-project-context.md now and create all required docs files.');
|
|
781
794
|
if ((scaffoldingResult.generatedPromptFileNames || []).includes('bootstrap-design.md')) {
|
|
782
|
-
console.log('- If docs/DESIGN.md is missing, execute .agent-context/prompts/bootstrap-design.md now before building UI components.');
|
|
795
|
+
console.log('- If docs/DESIGN.md or docs/design-intent.json is missing, execute .agent-context/prompts/bootstrap-design.md now before building UI components.');
|
|
783
796
|
}
|
|
784
797
|
console.log(`- Build an MVP for ${promptProjectName} using the newly synthesized docs as strict project context.`);
|
|
785
798
|
console.log('- When scope changes, update docs/* in the same change so future prompts stay aligned.');
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
detectProjectContext,
|
|
30
30
|
buildDetectionSummary,
|
|
31
31
|
formatDetectionCandidates,
|
|
32
|
+
collectProjectMarkers,
|
|
32
33
|
} from '../detector.mjs';
|
|
33
34
|
import {
|
|
34
35
|
buildCompiledRulesContent,
|
|
@@ -103,6 +104,102 @@ function buildExistingProjectMajorConstraints() {
|
|
|
103
104
|
];
|
|
104
105
|
}
|
|
105
106
|
|
|
107
|
+
async function readPackageJsonIfExists(targetDirectoryPath) {
|
|
108
|
+
const packageJsonPath = path.join(targetDirectoryPath, 'package.json');
|
|
109
|
+
if (!(await pathExists(packageJsonPath))) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
return JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
|
|
115
|
+
} catch {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async function detectUiScopeSignals({
|
|
121
|
+
targetDirectoryPath,
|
|
122
|
+
existingOnboardingReport,
|
|
123
|
+
selectedStackFileName,
|
|
124
|
+
selectedBlueprintFileName,
|
|
125
|
+
}) {
|
|
126
|
+
const signalReasons = [];
|
|
127
|
+
const markerNames = await collectProjectMarkers(targetDirectoryPath);
|
|
128
|
+
const packageManifest = await readPackageJsonIfExists(targetDirectoryPath);
|
|
129
|
+
|
|
130
|
+
const persistedProjectScopeKey = String(existingOnboardingReport?.projectScope?.key || '').trim().toLowerCase();
|
|
131
|
+
if (persistedProjectScopeKey === 'frontend-only' || persistedProjectScopeKey === 'both') {
|
|
132
|
+
signalReasons.push(`onboarding project scope: ${persistedProjectScopeKey}`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const selectedStackKey = String(selectedStackFileName || '').trim().toLowerCase();
|
|
136
|
+
if (selectedStackKey === 'react-native.md' || selectedStackKey === 'flutter.md') {
|
|
137
|
+
signalReasons.push(`selected stack implies UI runtime: ${selectedStackKey}`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const selectedBlueprintKey = String(selectedBlueprintFileName || '').trim().toLowerCase();
|
|
141
|
+
if (selectedBlueprintKey.includes('frontend') || selectedBlueprintKey.includes('landing') || selectedBlueprintKey.includes('mobile-app')) {
|
|
142
|
+
signalReasons.push(`selected blueprint implies UI scope: ${selectedBlueprintKey}`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const directUiMarkerNames = [
|
|
146
|
+
'next.config.js',
|
|
147
|
+
'next.config.mjs',
|
|
148
|
+
'next.config.ts',
|
|
149
|
+
'tailwind.config.js',
|
|
150
|
+
'tailwind.config.mjs',
|
|
151
|
+
'tailwind.config.ts',
|
|
152
|
+
'vite.config.js',
|
|
153
|
+
'vite.config.mjs',
|
|
154
|
+
'vite.config.ts',
|
|
155
|
+
'react-native.config.js',
|
|
156
|
+
'app',
|
|
157
|
+
'pages',
|
|
158
|
+
'components',
|
|
159
|
+
'public',
|
|
160
|
+
'styles',
|
|
161
|
+
'android',
|
|
162
|
+
'ios',
|
|
163
|
+
'index.html',
|
|
164
|
+
];
|
|
165
|
+
|
|
166
|
+
const detectedUiMarkers = directUiMarkerNames.filter((markerName) => markerNames.has(markerName));
|
|
167
|
+
if (detectedUiMarkers.length > 0) {
|
|
168
|
+
signalReasons.push(`ui markers: ${detectedUiMarkers.join(', ')}`);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const dependencyMap = {
|
|
172
|
+
next: 'next',
|
|
173
|
+
react: 'react',
|
|
174
|
+
reactDom: 'react-dom',
|
|
175
|
+
reactNative: 'react-native',
|
|
176
|
+
expo: 'expo',
|
|
177
|
+
tailwindcss: 'tailwindcss',
|
|
178
|
+
};
|
|
179
|
+
const dependencySource = {
|
|
180
|
+
...(packageManifest?.dependencies || {}),
|
|
181
|
+
...(packageManifest?.devDependencies || {}),
|
|
182
|
+
};
|
|
183
|
+
const detectedUiDependencies = Object.values(dependencyMap).filter((dependencyName) => dependencySource[dependencyName]);
|
|
184
|
+
if (detectedUiDependencies.length > 0) {
|
|
185
|
+
signalReasons.push(`ui dependencies: ${detectedUiDependencies.join(', ')}`);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const hasStrongUiMarker = detectedUiMarkers.some((markerName) => (
|
|
189
|
+
markerName.startsWith('next.config')
|
|
190
|
+
|| markerName === 'react-native.config.js'
|
|
191
|
+
|| markerName === 'android'
|
|
192
|
+
|| markerName === 'ios'
|
|
193
|
+
));
|
|
194
|
+
const hasUiDependencies = detectedUiDependencies.length > 0;
|
|
195
|
+
const hasStructuralUiMarkers = detectedUiMarkers.length >= 2;
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
isUiScopeLikely: signalReasons.length > 0 && (hasStrongUiMarker || hasUiDependencies || hasStructuralUiMarkers || persistedProjectScopeKey.length > 0),
|
|
199
|
+
signalReasons,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
106
203
|
export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions = {}) {
|
|
107
204
|
const resolvedTargetDirectoryPath = path.resolve(targetDirectoryArgument || '.');
|
|
108
205
|
|
|
@@ -167,6 +264,21 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
167
264
|
const includeCiGuardrails = typeof existingOnboardingReport?.ciGuardrailsEnabled === 'boolean'
|
|
168
265
|
? existingOnboardingReport.ciGuardrailsEnabled
|
|
169
266
|
: true;
|
|
267
|
+
const uiScopeSignals = await detectUiScopeSignals({
|
|
268
|
+
targetDirectoryPath: resolvedTargetDirectoryPath,
|
|
269
|
+
existingOnboardingReport,
|
|
270
|
+
selectedStackFileName,
|
|
271
|
+
selectedBlueprintFileName,
|
|
272
|
+
});
|
|
273
|
+
const designContractPaths = ['docs/DESIGN.md', 'docs/design-intent.json'];
|
|
274
|
+
const missingDesignContractPaths = [];
|
|
275
|
+
|
|
276
|
+
for (const designContractPath of designContractPaths) {
|
|
277
|
+
const absoluteDesignContractPath = path.join(resolvedTargetDirectoryPath, ...designContractPath.split('/'));
|
|
278
|
+
if (!(await pathExists(absoluteDesignContractPath))) {
|
|
279
|
+
missingDesignContractPaths.push(designContractPath);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
170
282
|
|
|
171
283
|
const detectionMajorConstraints = buildExistingProjectMajorConstraints();
|
|
172
284
|
const detectionTransparency = {
|
|
@@ -256,6 +368,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
256
368
|
console.log(`- Rules changed: ${isRulesContentChanged ? 'yes' : 'no'}`);
|
|
257
369
|
console.log(`- Managed surface stale files: ${managedSurfacePlan.staleFiles.length}`);
|
|
258
370
|
console.log(`- Managed surface stale directories: ${managedSurfacePlan.staleDirectories.length}`);
|
|
371
|
+
console.log(`- Managed surface sync mode: 1:1 (prune enabled)`);
|
|
259
372
|
console.log(`- Managed surface prune mode: ${upgradeOptions.pruneManagedSurface === true ? 'enabled (default)' : 'disabled (--no-prune)'}`);
|
|
260
373
|
console.log(`- MCP config write mode: ${upgradeOptions.includeMcpTemplate === true ? 'enabled (default)' : 'disabled (--no-mcp-template)'}`);
|
|
261
374
|
if (projectDocStalenessReport.hasProjectDocs) {
|
|
@@ -287,6 +400,18 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
287
400
|
console.log('Recommendation: regenerate docs with init --scaffold-docs or update the files manually to match the latest template version.');
|
|
288
401
|
}
|
|
289
402
|
|
|
403
|
+
if (uiScopeSignals.isUiScopeLikely && missingDesignContractPaths.length > 0) {
|
|
404
|
+
console.log('\n[WARN] UI/frontend scope was detected, but the dynamic design contract is incomplete:');
|
|
405
|
+
for (const missingDesignContractPath of missingDesignContractPaths) {
|
|
406
|
+
console.log(`- Missing ${missingDesignContractPath}`);
|
|
407
|
+
}
|
|
408
|
+
if (uiScopeSignals.signalReasons.length > 0) {
|
|
409
|
+
console.log(`- Detection signals: ${uiScopeSignals.signalReasons.join('; ')}`);
|
|
410
|
+
}
|
|
411
|
+
console.log('Recommendation: create or refresh docs/DESIGN.md and docs/design-intent.json before allowing UI implementation work.');
|
|
412
|
+
console.log('Upgrade synchronizes governance assets, but it does not author project-specific design docs automatically.');
|
|
413
|
+
}
|
|
414
|
+
|
|
290
415
|
if (upgradeOptions.dryRun) {
|
|
291
416
|
console.log('\nDry run enabled. No files were modified.');
|
|
292
417
|
return;
|
|
@@ -319,6 +444,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
319
444
|
targetDirectoryPath: resolvedTargetDirectoryPath,
|
|
320
445
|
selectedProfileName,
|
|
321
446
|
selectedProfilePack: existingOnboardingReport?.selectedProfilePack || null,
|
|
447
|
+
projectScope: existingOnboardingReport?.projectScope || null,
|
|
322
448
|
selectedStackFileName,
|
|
323
449
|
selectedAdditionalStackFileNames,
|
|
324
450
|
selectedBlueprintFileName,
|
|
@@ -332,11 +458,21 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
332
458
|
});
|
|
333
459
|
|
|
334
460
|
console.log('\nUpgrade complete.');
|
|
461
|
+
console.log(`- Governance surface sync: 1:1 (${governanceSyncResult.updatedFiles.length} updated, ${governanceSyncResult.createdFiles.length} new, ${governanceSyncResult.deletedManagedFiles.length} deleted, ${governanceSyncResult.unchangedFiles.length} unchanged)`);
|
|
335
462
|
console.log(`- Rules rewritten: ${isRulesContentChanged ? 'yes' : 'no (metadata refreshed)'}`);
|
|
336
|
-
|
|
337
|
-
|
|
463
|
+
if (governanceSyncResult.deletedManagedDirectories.length > 0) {
|
|
464
|
+
console.log(`- Managed stale directories removed: ${governanceSyncResult.deletedManagedDirectories.length}`);
|
|
465
|
+
}
|
|
338
466
|
console.log(`- Setup time: ${formatDuration(setupDurationMs)}`);
|
|
339
|
-
|
|
467
|
+
|
|
468
|
+
if (governanceSyncResult.updatedFiles.length > 0 || governanceSyncResult.createdFiles.length > 0 || governanceSyncResult.deletedManagedFiles.length > 0) {
|
|
469
|
+
console.log('\nDetailed changes:');
|
|
470
|
+
governanceSyncResult.createdFiles.forEach((fileName) => console.log(` [NEW] ${fileName}`));
|
|
471
|
+
governanceSyncResult.updatedFiles.forEach((fileName) => console.log(` [UPDATED] ${fileName}`));
|
|
472
|
+
governanceSyncResult.deletedManagedFiles.forEach((fileName) => console.log(` [DELETED] ${fileName}`));
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
console.log('\nRefreshed files: .cursorrules, .windsurfrules, .agent-context/state/onboarding-report.json');
|
|
340
476
|
} catch (error) {
|
|
341
477
|
console.error('\n[FATAL] An error occurred during upgrade. Attempting automatic rollback...');
|
|
342
478
|
try {
|
package/lib/cli/compiler.mjs
CHANGED
|
@@ -37,6 +37,7 @@ export async function writeOnboardingReport({
|
|
|
37
37
|
selectedProfileName,
|
|
38
38
|
selectedProfilePack,
|
|
39
39
|
selectedPreset,
|
|
40
|
+
projectScope = null,
|
|
40
41
|
selectedStackFileName,
|
|
41
42
|
selectedAdditionalStackFileNames = [],
|
|
42
43
|
selectedBlueprintFileName,
|
|
@@ -70,6 +71,7 @@ export async function writeOnboardingReport({
|
|
|
70
71
|
}
|
|
71
72
|
: null,
|
|
72
73
|
selectedPreset,
|
|
74
|
+
projectScope,
|
|
73
75
|
selectedStack: selectedStackFileName,
|
|
74
76
|
selectedAdditionalStacks: selectedAdditionalStackFileNames,
|
|
75
77
|
selectedBlueprint: selectedBlueprintFileName,
|
|
@@ -351,6 +353,8 @@ export async function buildCompiledRulesContent({
|
|
|
351
353
|
'database-schema.md',
|
|
352
354
|
'api-contract.md',
|
|
353
355
|
'flow-overview.md',
|
|
356
|
+
'DESIGN.md',
|
|
357
|
+
'design-intent.json',
|
|
354
358
|
];
|
|
355
359
|
|
|
356
360
|
for (const candidateFileName of candidateDocFileNames) {
|
|
@@ -369,7 +373,7 @@ export async function buildCompiledRulesContent({
|
|
|
369
373
|
'',
|
|
370
374
|
'Universal SOP hard block policy:',
|
|
371
375
|
'- Stop implementation if docs/architecture-decision-record.md (alias: docs/Architecture-Decision-Record.md) is missing.',
|
|
372
|
-
'- For UI scope, stop implementation if docs/DESIGN.md is missing.',
|
|
376
|
+
'- For UI scope, stop implementation if docs/DESIGN.md or docs/design-intent.json is missing.',
|
|
373
377
|
'- Materialize missing docs first, then continue coding.',
|
|
374
378
|
'',
|
|
375
379
|
'These docs were generated during project initialization and reflect the architecture,',
|
|
@@ -402,7 +406,7 @@ export async function buildCompiledRulesContent({
|
|
|
402
406
|
'- Hard block: do not write application code until docs/project-brief.md and docs/architecture-decision-record.md exist.',
|
|
403
407
|
'- If docs/project-brief.md is missing, execute bootstrap-project-context prompt immediately.',
|
|
404
408
|
hasBootstrapDesignPrompt
|
|
405
|
-
? '- For UI scope: if docs/DESIGN.md is missing, execute bootstrap-design prompt before implementing UI surfaces.'
|
|
409
|
+
? '- For UI scope: if docs/DESIGN.md or docs/design-intent.json is missing, execute bootstrap-design prompt before implementing UI surfaces.'
|
|
406
410
|
: '- For UI scope: add a design bootstrap prompt before implementing UI surfaces.',
|
|
407
411
|
'- Save generated docs under docs/ and keep them updated when feature scope changes.',
|
|
408
412
|
'Latest user prompt defines current feature scope and product direction.',
|
|
@@ -62,6 +62,7 @@ export async function resolveArchitectureSelection({
|
|
|
62
62
|
selectedProjectScopeLabel,
|
|
63
63
|
selectedManualStackFileName,
|
|
64
64
|
selectedManualBlueprintFileName,
|
|
65
|
+
architectureProjectDescription: '',
|
|
65
66
|
architectureRecommendation,
|
|
66
67
|
architectPreferenceState: nextArchitectPreferenceState,
|
|
67
68
|
architectPreferenceUpdated,
|
|
@@ -224,6 +225,7 @@ export async function resolveArchitectureSelection({
|
|
|
224
225
|
selectedProjectScopeLabel,
|
|
225
226
|
selectedManualStackFileName,
|
|
226
227
|
selectedManualBlueprintFileName,
|
|
228
|
+
architectureProjectDescription,
|
|
227
229
|
architectureRecommendation,
|
|
228
230
|
architectPreferenceState: nextArchitectPreferenceState,
|
|
229
231
|
architectPreferenceUpdated,
|