@ryuenn3123/agentic-senior-core 3.0.11 → 3.0.13
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 +7 -1
- package/.agent-context/rules/architecture.md +7 -0
- package/.agent-context/state/memory-continuity-benchmark.json +1 -1
- package/.cursorrules +1 -1
- package/.windsurfrules +1 -1
- package/lib/cli/commands/init.mjs +215 -154
- package/lib/cli/commands/upgrade.mjs +5 -0
- package/lib/cli/compiler.mjs +20 -0
- package/lib/cli/constants.mjs +1 -0
- package/lib/cli/detector.mjs +444 -90
- package/lib/cli/project-scaffolder.mjs +161 -35
- package/package.json +1 -1
- package/scripts/frontend-usability-audit.mjs +2 -0
- package/scripts/mcp-server.mjs +200 -118
- package/scripts/ui-design-judge.mjs +3 -2
- package/scripts/validate.mjs +4 -0
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import fs from 'node:fs/promises';
|
|
7
7
|
import path from 'node:path';
|
|
8
8
|
|
|
9
|
-
import { ensureDirectory, askChoice, toTitleCase, pathExists } from './utils.mjs';
|
|
9
|
+
import { ensureDirectory, askChoice, askYesNo, toTitleCase, pathExists } from './utils.mjs';
|
|
10
10
|
|
|
11
11
|
const SUPPORTED_DOC_LANGUAGES = new Set(['en', 'id']);
|
|
12
12
|
const PROJECT_DOC_FILE_NAMES = [
|
|
@@ -137,14 +137,18 @@ export function normalizeDocsLanguage(rawDocsLanguage = 'en') {
|
|
|
137
137
|
* Returns a structured object with all user responses.
|
|
138
138
|
*/
|
|
139
139
|
export async function runProjectDiscovery(userInterface, options = {}) {
|
|
140
|
-
console.log('\n--- Project
|
|
141
|
-
console.log('I will ask
|
|
140
|
+
console.log('\n--- Project Setup ---');
|
|
141
|
+
console.log('I will ask one focused set of questions to bootstrap project context and documentation.');
|
|
142
142
|
console.log('This helps AI agents understand your project before writing code.\n');
|
|
143
143
|
console.log('You can answer in your own language.');
|
|
144
144
|
console.log('CLI prompts stay in English, but non-English answers are fully supported.\n');
|
|
145
145
|
|
|
146
146
|
const defaultProjectName = (options.defaultProjectName || '').trim();
|
|
147
147
|
const defaultProjectDescription = String(options.defaultProjectDescription || '').trim();
|
|
148
|
+
const defaultIncludeCiGuardrails = typeof options.defaultIncludeCiGuardrails === 'boolean'
|
|
149
|
+
? options.defaultIncludeCiGuardrails
|
|
150
|
+
: true;
|
|
151
|
+
const shouldAskForCiGuardrails = options.askForCiGuardrails !== false;
|
|
148
152
|
let projectName = '';
|
|
149
153
|
|
|
150
154
|
const projectNamePrompt = defaultProjectName
|
|
@@ -171,6 +175,14 @@ export async function runProjectDiscovery(userInterface, options = {}) {
|
|
|
171
175
|
projectDescription = defaultProjectDescription || `A ${projectName} project.`;
|
|
172
176
|
}
|
|
173
177
|
|
|
178
|
+
const includeCiGuardrails = shouldAskForCiGuardrails
|
|
179
|
+
? await askYesNo(
|
|
180
|
+
'Enable CI/CD quality checks (guardrails) and the LLM Judge policy?',
|
|
181
|
+
userInterface,
|
|
182
|
+
defaultIncludeCiGuardrails
|
|
183
|
+
)
|
|
184
|
+
: defaultIncludeCiGuardrails;
|
|
185
|
+
|
|
174
186
|
const domainSelection = await askChoice(
|
|
175
187
|
'Primary domain:',
|
|
176
188
|
DOMAIN_CHOICES,
|
|
@@ -210,24 +222,18 @@ export async function runProjectDiscovery(userInterface, options = {}) {
|
|
|
210
222
|
userInterface
|
|
211
223
|
);
|
|
212
224
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
if (features.length === 0) {
|
|
216
|
-
features.push('Core functionality (define during development)');
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const additionalContext = (await userInterface.question('\nAdditional context (optional, press Enter to skip): ')).trim()
|
|
220
|
-
|| 'No additional context provided.';
|
|
225
|
+
const features = await askFeatureList(userInterface);
|
|
221
226
|
|
|
222
227
|
return {
|
|
223
228
|
projectName,
|
|
224
229
|
projectDescription,
|
|
230
|
+
includeCiGuardrails,
|
|
225
231
|
primaryDomain,
|
|
226
232
|
databaseChoice,
|
|
227
233
|
authStrategy,
|
|
228
234
|
dockerStrategy,
|
|
229
235
|
features,
|
|
230
|
-
additionalContext,
|
|
236
|
+
additionalContext: 'No additional context provided.',
|
|
231
237
|
};
|
|
232
238
|
}
|
|
233
239
|
|
|
@@ -315,7 +321,7 @@ const DESIGN_REQUIRED_SECTIONS = [
|
|
|
315
321
|
'Spacing, Layout Rhythm, and Density Strategy',
|
|
316
322
|
'Responsive Strategy and Cross-Viewport Adaptation Matrix',
|
|
317
323
|
'Interaction, Motion, and Feedback Rules',
|
|
318
|
-
'Component Language and Shared Patterns',
|
|
324
|
+
'Component Language, Morphology, and Shared Patterns',
|
|
319
325
|
'Accessibility Non-Negotiables',
|
|
320
326
|
'Anti-Patterns to Avoid',
|
|
321
327
|
'Implementation Notes for Future UI Tasks',
|
|
@@ -343,6 +349,17 @@ function inferDesignKeywords(discoveryAnswers) {
|
|
|
343
349
|
'Keep decision-critical information prominent while secondary merchandising stays quiet.',
|
|
344
350
|
'Let imagery and spacing create premium perception before decorative effects do.',
|
|
345
351
|
],
|
|
352
|
+
motionPurpose: 'Use restrained motion to reinforce buying confidence, product continuity, and feedback. Motion should feel premium, not promotional.',
|
|
353
|
+
motionChoreography: 'Favor short hover/focus transitions, sheet choreography, and product-media continuity. Avoid looping hero motion, autoplay spectacle, and parallax-heavy scenes.',
|
|
354
|
+
motionDurations: {
|
|
355
|
+
desktop: 180,
|
|
356
|
+
mobile: 240,
|
|
357
|
+
},
|
|
358
|
+
componentMorphology: {
|
|
359
|
+
mobile: 'Product cards should compress supporting metadata, pin purchase actions closer to the thumb zone, and move comparison into progressive disclosure or bottom sheets.',
|
|
360
|
+
tablet: 'Cards and merch modules should preserve comparison affordances while reducing tertiary chrome and keeping visual hierarchy stable.',
|
|
361
|
+
desktop: 'Cards can expand media, comparison, and reassurance copy while keeping buying cues dominant and visually disciplined.',
|
|
362
|
+
},
|
|
346
363
|
mutationRules: {
|
|
347
364
|
mobile: 'Convert browsing into vertically stacked product cards, move cart and filter actions into sticky or bottom-sheet patterns, and keep thumb-reach actions persistent.',
|
|
348
365
|
tablet: 'Preserve browsing flow with a two-column rhythm, collapse tertiary filters, and keep comparison moments visible without forcing desktop density.',
|
|
@@ -365,6 +382,17 @@ function inferDesignKeywords(discoveryAnswers) {
|
|
|
365
382
|
'Use visual weight to separate signal from operational noise.',
|
|
366
383
|
'Reserve strong accents for alerts, decisions, and state transitions only.',
|
|
367
384
|
],
|
|
385
|
+
motionPurpose: 'Use motion as operational feedback and state continuity, never as ambient decoration that competes with dense information.',
|
|
386
|
+
motionChoreography: 'Prefer fast transitions for filters, drawers, status reveals, and row expansion. Avoid floaty choreography and ornamental motion that slows scanning.',
|
|
387
|
+
motionDurations: {
|
|
388
|
+
desktop: 160,
|
|
389
|
+
mobile: 220,
|
|
390
|
+
},
|
|
391
|
+
componentMorphology: {
|
|
392
|
+
mobile: 'Data rows should become prioritized cards or grouped summaries, with filters and secondary tools moving into sheets or drawers.',
|
|
393
|
+
tablet: 'Operational panels should retain split-view logic where possible, while tertiary panels collapse behind explicit toggles.',
|
|
394
|
+
desktop: 'Dense tables, side panels, and comparison surfaces can remain visible simultaneously, with state treatments optimized for rapid scanning.',
|
|
395
|
+
},
|
|
368
396
|
mutationRules: {
|
|
369
397
|
mobile: 'Collapse dense tables into prioritized cards or row groups, move filters into drawers or sheets, and pin the most critical actions to the bottom reach zone.',
|
|
370
398
|
tablet: 'Keep two-column or split-pane workflows, collapse tertiary panels, and maintain fast scan paths for operators using touch or keyboard.',
|
|
@@ -387,6 +415,17 @@ function inferDesignKeywords(discoveryAnswers) {
|
|
|
387
415
|
'Use code-adjacent rhythm and hierarchy to build trust with technical users.',
|
|
388
416
|
'Keep complexity legible through spacing, grouping, and explicit interaction states.',
|
|
389
417
|
],
|
|
418
|
+
motionPurpose: 'Use motion to clarify causality, reveal system state, and preserve context during multi-pane technical workflows.',
|
|
419
|
+
motionChoreography: 'Prefer subtle panel transitions, command feedback, and disclosure motion. Avoid ornamental sweeps that make technical work feel imprecise.',
|
|
420
|
+
motionDurations: {
|
|
421
|
+
desktop: 170,
|
|
422
|
+
mobile: 230,
|
|
423
|
+
},
|
|
424
|
+
componentMorphology: {
|
|
425
|
+
mobile: 'Technical panes should flatten into sequential sections, with commands and diagnostics colocated near the content they affect.',
|
|
426
|
+
tablet: 'Split views should survive where useful, with explicit panel toggles and condensed chrome for code-adjacent tasks.',
|
|
427
|
+
desktop: 'Navigation, documentation, diagnostics, and active work surfaces can remain concurrently visible when it improves expert comprehension.',
|
|
428
|
+
},
|
|
390
429
|
mutationRules: {
|
|
391
430
|
mobile: 'Switch multi-pane technical layouts into stacked sections, turn secondary navigation into segmented or sheet-based controls, and keep commands near the content they affect.',
|
|
392
431
|
tablet: 'Retain split-view comprehension where possible, compress chrome, and keep documentation or diagnostics adjacent to the active task.',
|
|
@@ -409,6 +448,17 @@ function inferDesignKeywords(discoveryAnswers) {
|
|
|
409
448
|
'Use contrast and spacing to guide attention between creation, moderation, and discovery.',
|
|
410
449
|
'Give key interaction moments personality without sacrificing clarity.',
|
|
411
450
|
],
|
|
451
|
+
motionPurpose: 'Use motion to support reading rhythm, reveal structure, and reward contribution moments without overwhelming long-form consumption.',
|
|
452
|
+
motionChoreography: 'Favor reveal choreography for section transitions, lightweight feedback on participation, and measured media behavior. Avoid constant background motion.',
|
|
453
|
+
motionDurations: {
|
|
454
|
+
desktop: 190,
|
|
455
|
+
mobile: 250,
|
|
456
|
+
},
|
|
457
|
+
componentMorphology: {
|
|
458
|
+
mobile: 'Reading surfaces should dominate while secondary discovery and community tools collapse behind sheets, tabs, or segmented controls.',
|
|
459
|
+
tablet: 'Editorial modules can balance reading and discovery, provided the primary narrative flow remains obvious.',
|
|
460
|
+
desktop: 'Long-form content, secondary navigation, and related discovery modules can coexist without fragmenting the reading rhythm.',
|
|
461
|
+
},
|
|
412
462
|
mutationRules: {
|
|
413
463
|
mobile: 'Prioritize reading and contribution flows in a single-column narrative stack, tuck secondary discovery tools behind sheets, and keep primary creation actions within reach.',
|
|
414
464
|
tablet: 'Balance narrative reading with supporting discovery modules, using two-column compositions only where hierarchy stays obvious.',
|
|
@@ -430,6 +480,17 @@ function inferDesignKeywords(discoveryAnswers) {
|
|
|
430
480
|
'Use rhythm, hierarchy, and motion intentionally so the interface feels authored.',
|
|
431
481
|
'Keep the system flexible enough to evolve with product scope without losing identity.',
|
|
432
482
|
],
|
|
483
|
+
motionPurpose: 'Allow motion when it improves continuity, feedback, or perceived craft. Avoid banning motion outright, but reject decorative movement with no product value.',
|
|
484
|
+
motionChoreography: 'Use short, purposeful transitions and keep heavier choreography rare, opt-in, and explainable in product terms.',
|
|
485
|
+
motionDurations: {
|
|
486
|
+
desktop: 180,
|
|
487
|
+
mobile: 240,
|
|
488
|
+
},
|
|
489
|
+
componentMorphology: {
|
|
490
|
+
mobile: 'Primary components should simplify structure, prioritize direct tasks, and collapse supporting detail into explicit disclosure.',
|
|
491
|
+
tablet: 'Components should preserve hierarchy and task continuity while reducing density and compressing tertiary chrome.',
|
|
492
|
+
desktop: 'Components can expose richer states, denser supporting information, and broader navigation affordances without losing clarity.',
|
|
493
|
+
},
|
|
433
494
|
mutationRules: {
|
|
434
495
|
mobile: 'Stack primary tasks vertically, convert secondary navigation into thumb-friendly overlays or sheets, and simplify dense comparison layouts into progressive disclosure.',
|
|
435
496
|
tablet: 'Preserve hierarchy with fewer columns, condensed chrome, and adaptive navigation that maintains task continuity.',
|
|
@@ -453,7 +514,14 @@ function buildDesignIntentContractObject({
|
|
|
453
514
|
primaryDomain,
|
|
454
515
|
features,
|
|
455
516
|
});
|
|
456
|
-
const
|
|
517
|
+
const normalizedPrimaryDomain = String(primaryDomain || '').trim().toLowerCase();
|
|
518
|
+
const resolvedSpacingPattern = inferredKeywords.densityMode === 'dense'
|
|
519
|
+
? 'compact-grid'
|
|
520
|
+
: normalizedPrimaryDomain.includes('mobile')
|
|
521
|
+
? 'mobile-first-single-axis'
|
|
522
|
+
: inferredKeywords.densityMode === 'focused'
|
|
523
|
+
? 'high-contrast-rhythm'
|
|
524
|
+
: 'balanced-grid';
|
|
457
525
|
|
|
458
526
|
return {
|
|
459
527
|
mode: 'dynamic',
|
|
@@ -476,14 +544,14 @@ function buildDesignIntentContractObject({
|
|
|
476
544
|
mathSystems: {
|
|
477
545
|
typographyScaleRatio: inferredKeywords.typographyScaleRatio,
|
|
478
546
|
baseGridUnit: inferredKeywords.baseGridUnit,
|
|
479
|
-
spacingPattern:
|
|
547
|
+
spacingPattern: resolvedSpacingPattern,
|
|
480
548
|
densityMode: inferredKeywords.densityMode,
|
|
481
549
|
},
|
|
482
550
|
colorTruth: {
|
|
483
551
|
format: 'OKLCH',
|
|
484
552
|
allowHexDerivatives: true,
|
|
485
553
|
requirePerceptualLightnessCurve: true,
|
|
486
|
-
paletteRoles:
|
|
554
|
+
paletteRoles: ['base', 'surface', 'accent'],
|
|
487
555
|
intent: inferredKeywords.colorIntent,
|
|
488
556
|
},
|
|
489
557
|
crossViewportAdaptation: {
|
|
@@ -491,11 +559,28 @@ function buildDesignIntentContractObject({
|
|
|
491
559
|
touchTargetMinPx: 44,
|
|
492
560
|
mutationRules: inferredKeywords.mutationRules,
|
|
493
561
|
},
|
|
562
|
+
motionSystem: {
|
|
563
|
+
allowMeaningfulMotion: true,
|
|
564
|
+
purpose: inferredKeywords.motionPurpose,
|
|
565
|
+
choreography: inferredKeywords.motionChoreography,
|
|
566
|
+
desktopDurationMs: inferredKeywords.motionDurations.desktop,
|
|
567
|
+
mobileDurationMs: inferredKeywords.motionDurations.mobile,
|
|
568
|
+
respectReducedMotion: true,
|
|
569
|
+
preferTransformAndOpacity: true,
|
|
570
|
+
avoidDecorativeMotionForItsOwnSake: true,
|
|
571
|
+
},
|
|
572
|
+
componentMorphology: {
|
|
573
|
+
requireStateBehaviorMatrix: true,
|
|
574
|
+
preserveIdentityAcrossViewports: true,
|
|
575
|
+
stateKeys: ['default', 'hover', 'focus', 'active', 'disabled', 'loading', 'error'],
|
|
576
|
+
viewportBehavior: inferredKeywords.componentMorphology,
|
|
577
|
+
},
|
|
494
578
|
experiencePrinciples: [
|
|
495
579
|
'Design must feel project-specific, not interchangeable with generic SaaS templates.',
|
|
496
580
|
'Major interface decisions must be explainable in product and user terms.',
|
|
497
581
|
'Accessibility, responsiveness, and implementation realism are non-negotiable.',
|
|
498
582
|
'Cross-viewport behavior must reorganize tasks and navigation, not just scale the desktop layout down.',
|
|
583
|
+
'Motion may add character and continuity when it improves the product experience, but it must stay purposeful, performant, and optional for reduced-motion users.',
|
|
499
584
|
],
|
|
500
585
|
forbiddenPatterns: [
|
|
501
586
|
'generic-saas-hero',
|
|
@@ -509,6 +594,8 @@ function buildDesignIntentContractObject({
|
|
|
509
594
|
requireViewportMutationRules: true,
|
|
510
595
|
requirePerceptualColorRationale: true,
|
|
511
596
|
allowHexDerivatives: true,
|
|
597
|
+
requireMotionRationale: true,
|
|
598
|
+
requireStateMorphology: true,
|
|
512
599
|
},
|
|
513
600
|
requiredDesignSections: DESIGN_REQUIRED_SECTIONS,
|
|
514
601
|
implementation: {
|
|
@@ -517,6 +604,7 @@ function buildDesignIntentContractObject({
|
|
|
517
604
|
requireDistinctVisualDirection: true,
|
|
518
605
|
requireMachineReadableContract: true,
|
|
519
606
|
requireViewportMutationRules: true,
|
|
607
|
+
requirePurposefulMotionGuidelines: true,
|
|
520
608
|
bootstrapPrompt: '.agent-context/prompts/bootstrap-design.md',
|
|
521
609
|
autoLoadedRuleFiles: [
|
|
522
610
|
'.agent-context/prompts/bootstrap-design.md',
|
|
@@ -528,7 +616,6 @@ function buildDesignIntentContractObject({
|
|
|
528
616
|
'.agent-context/rules/microservices.md',
|
|
529
617
|
],
|
|
530
618
|
},
|
|
531
|
-
architectSignals: designSignals,
|
|
532
619
|
...supplementalFields,
|
|
533
620
|
};
|
|
534
621
|
}
|
|
@@ -589,6 +676,41 @@ export function validateDesignIntentContract(designIntentContract) {
|
|
|
589
676
|
}
|
|
590
677
|
}
|
|
591
678
|
|
|
679
|
+
if (!designIntentContract.motionSystem || typeof designIntentContract.motionSystem !== 'object') {
|
|
680
|
+
validationErrors.push('designIntent.motionSystem must exist.');
|
|
681
|
+
} else {
|
|
682
|
+
if (designIntentContract.motionSystem.allowMeaningfulMotion !== true) {
|
|
683
|
+
validationErrors.push('designIntent.motionSystem.allowMeaningfulMotion must equal true.');
|
|
684
|
+
}
|
|
685
|
+
if (!String(designIntentContract.motionSystem.purpose || '').trim()) {
|
|
686
|
+
validationErrors.push('designIntent.motionSystem.purpose must be a non-empty string.');
|
|
687
|
+
}
|
|
688
|
+
if (designIntentContract.motionSystem.respectReducedMotion !== true) {
|
|
689
|
+
validationErrors.push('designIntent.motionSystem.respectReducedMotion must equal true.');
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
if (!designIntentContract.componentMorphology || typeof designIntentContract.componentMorphology !== 'object') {
|
|
694
|
+
validationErrors.push('designIntent.componentMorphology must exist.');
|
|
695
|
+
} else {
|
|
696
|
+
if (designIntentContract.componentMorphology.requireStateBehaviorMatrix !== true) {
|
|
697
|
+
validationErrors.push('designIntent.componentMorphology.requireStateBehaviorMatrix must equal true.');
|
|
698
|
+
}
|
|
699
|
+
if (!Array.isArray(designIntentContract.componentMorphology.stateKeys) || designIntentContract.componentMorphology.stateKeys.length < 4) {
|
|
700
|
+
validationErrors.push('designIntent.componentMorphology.stateKeys must contain multiple interaction states.');
|
|
701
|
+
}
|
|
702
|
+
const viewportBehavior = designIntentContract.componentMorphology.viewportBehavior;
|
|
703
|
+
if (!viewportBehavior || typeof viewportBehavior !== 'object') {
|
|
704
|
+
validationErrors.push('designIntent.componentMorphology.viewportBehavior must exist.');
|
|
705
|
+
} else {
|
|
706
|
+
for (const viewportKey of ['mobile', 'tablet', 'desktop']) {
|
|
707
|
+
if (!String(viewportBehavior[viewportKey] || '').trim()) {
|
|
708
|
+
validationErrors.push(`designIntent.componentMorphology.viewportBehavior.${viewportKey} must be a non-empty string.`);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
|
|
592
714
|
if (!Array.isArray(designIntentContract.requiredDesignSections) || designIntentContract.requiredDesignSections.length !== DESIGN_REQUIRED_SECTIONS.length) {
|
|
593
715
|
validationErrors.push('designIntent.requiredDesignSections must match the required design contract sections.');
|
|
594
716
|
} else {
|
|
@@ -656,7 +778,7 @@ function buildProjectContextBootstrapPrompt({
|
|
|
656
778
|
}) {
|
|
657
779
|
const featuresList = Array.isArray(discoveryAnswers.features) && discoveryAnswers.features.length > 0
|
|
658
780
|
? discoveryAnswers.features.map((feature, featureIndex) => `${featureIndex + 1}. ${feature}`).join('\n')
|
|
659
|
-
: '
|
|
781
|
+
: 'Derive the first concrete feature set from the project name, description, and domain. Do not invent arbitrary modules just to fill space.';
|
|
660
782
|
|
|
661
783
|
const expectedDocsList = expectedDocFileNames
|
|
662
784
|
.map((fileName, fileIndex) => `${fileIndex + 1}. docs/${fileName}`)
|
|
@@ -692,6 +814,11 @@ function buildProjectContextBootstrapPrompt({
|
|
|
692
814
|
'3. Keep stack, database, and auth aligned with the project constraints below unless user explicitly requests migration.',
|
|
693
815
|
'4. Output must be implementation-ready for engineers, not generic textbook explanation.',
|
|
694
816
|
'5. For any research-backed claim, include citation metadata (source + fetchedAt timestamp) from the Architect Engine Snapshot.',
|
|
817
|
+
'6. Write for native English speakers at an 8th-grade reading level. Use clear, direct, plain language.',
|
|
818
|
+
'7. Avoid emoji, AI cliches, buzzwords, academic phrasing, padding, and generic filler.',
|
|
819
|
+
'8. Separate confirmed facts from assumptions explicitly. When context is incomplete, add an `Assumptions to Validate` section and a `Next Validation Action` line.',
|
|
820
|
+
'9. If user inputs conflict with repo evidence, call out the conflict and choose the safer interpretation instead of silently forcing a generic answer.',
|
|
821
|
+
'10. Do not invent modules or architecture layers only to make the docs look complete.',
|
|
695
822
|
'',
|
|
696
823
|
'## Project Inputs',
|
|
697
824
|
`- Project name: ${discoveryAnswers.projectName}`,
|
|
@@ -719,8 +846,10 @@ function buildProjectContextBootstrapPrompt({
|
|
|
719
846
|
'',
|
|
720
847
|
'## Required Execution',
|
|
721
848
|
'1. Create all required docs files listed above with complete Markdown content.',
|
|
722
|
-
'2.
|
|
723
|
-
'3.
|
|
849
|
+
'2. Make the docs adaptive to the real repo and prompt context. These are living references, not frozen templates.',
|
|
850
|
+
'3. In docs/project-brief.md and docs/architecture-decision-record.md, include explicit sections for confirmed facts, assumptions to validate, and next validation actions whenever context is incomplete.',
|
|
851
|
+
'4. Keep content original, specific to this project, and actionable for implementation.',
|
|
852
|
+
'5. After writing docs, continue coding tasks using these docs as living project context.',
|
|
724
853
|
'',
|
|
725
854
|
].join('\n');
|
|
726
855
|
}
|
|
@@ -731,8 +860,6 @@ function buildDesignBootstrapPrompt({
|
|
|
731
860
|
docsLanguage,
|
|
732
861
|
architectureRecommendation,
|
|
733
862
|
}) {
|
|
734
|
-
const designSignals = architectureRecommendation?.designGuidance?.normalizedSignals || null;
|
|
735
|
-
const designSignalsJson = JSON.stringify(designSignals, null, 2);
|
|
736
863
|
const designIntentSeed = buildDesignIntentSeed({
|
|
737
864
|
discoveryAnswers,
|
|
738
865
|
initContext,
|
|
@@ -764,7 +891,7 @@ function buildDesignBootstrapPrompt({
|
|
|
764
891
|
'6. Spacing, Layout Rhythm, and Density Strategy',
|
|
765
892
|
'7. Responsive Strategy and Cross-Viewport Adaptation Matrix',
|
|
766
893
|
'8. Motion and Interaction Principles',
|
|
767
|
-
'9. Component Language (cards, forms, nav, states)',
|
|
894
|
+
'9. Component Language and Morphology (cards, forms, nav, states)',
|
|
768
895
|
'10. Accessibility Non-Negotiables',
|
|
769
896
|
'11. Anti-Patterns to Avoid',
|
|
770
897
|
'12. Implementation Notes for Future UI Tasks',
|
|
@@ -780,11 +907,13 @@ function buildDesignBootstrapPrompt({
|
|
|
780
907
|
'8. mathSystems',
|
|
781
908
|
'9. colorTruth',
|
|
782
909
|
'10. crossViewportAdaptation',
|
|
783
|
-
'11.
|
|
784
|
-
'12.
|
|
785
|
-
'13.
|
|
786
|
-
'14.
|
|
787
|
-
'15.
|
|
910
|
+
'11. motionSystem',
|
|
911
|
+
'12. componentMorphology',
|
|
912
|
+
'13. experiencePrinciples',
|
|
913
|
+
'14. forbiddenPatterns',
|
|
914
|
+
'15. validationHints',
|
|
915
|
+
'16. requiredDesignSections',
|
|
916
|
+
'17. implementation',
|
|
788
917
|
'',
|
|
789
918
|
'## Hard Rules',
|
|
790
919
|
'1. No copy-paste from external style guides.',
|
|
@@ -795,7 +924,9 @@ function buildDesignBootstrapPrompt({
|
|
|
795
924
|
'6. Reject interchangeable hero layouts, generic SaaS gradients, and trend-chasing decoration unless the project context explicitly justifies them.',
|
|
796
925
|
'7. Encode color intent in perceptual terms first. Hex values may exist only as implementation derivatives.',
|
|
797
926
|
'8. Responsive guidance must include layout mutation rules for mobile, tablet, and desktop. Shrinking the desktop layout is not enough.',
|
|
798
|
-
'9.
|
|
927
|
+
'9. Motion is allowed when it reinforces feedback, continuity, or hierarchy. Do not remove motion entirely, but reject decorative motion that harms clarity or performance.',
|
|
928
|
+
'10. Define component morphology across interaction states and viewports so cards, forms, nav, and feedback surfaces adapt coherently instead of only resizing.',
|
|
929
|
+
'11. Keep UI-only requests context-isolated. Load frontend design rules first and do not eagerly load backend-only rules unless the task explicitly crosses those boundaries.',
|
|
799
930
|
'',
|
|
800
931
|
'## Project Inputs',
|
|
801
932
|
`- Project name: ${discoveryAnswers.projectName}`,
|
|
@@ -804,12 +935,6 @@ function buildDesignBootstrapPrompt({
|
|
|
804
935
|
`- Stack: ${toTitleCase(initContext.stackFileName)}`,
|
|
805
936
|
`- Blueprint: ${toTitleCase(initContext.blueprintFileName)}`,
|
|
806
937
|
'',
|
|
807
|
-
'## Architect Design Signals (raw control vector)',
|
|
808
|
-
'Use this only as baseline fuel, then expand into full design direction with original reasoning:',
|
|
809
|
-
'```json',
|
|
810
|
-
designSignalsJson || 'null',
|
|
811
|
-
'```',
|
|
812
|
-
'',
|
|
813
938
|
'## Seed Machine Contract',
|
|
814
939
|
'Refine this seed instead of discarding it. Keep the final JSON aligned with the markdown design system.',
|
|
815
940
|
'```json',
|
|
@@ -1019,6 +1144,7 @@ export async function loadProjectConfig(configFilePath) {
|
|
|
1019
1144
|
return {
|
|
1020
1145
|
projectName: configEntries.projectName || configEntries.name || '',
|
|
1021
1146
|
projectDescription: configEntries.projectDescription || configEntries.description || '',
|
|
1147
|
+
includeCiGuardrails: parseBooleanLikeValue(configEntries.includeCiGuardrails) ?? parseBooleanLikeValue(configEntries.ci) ?? true,
|
|
1022
1148
|
primaryDomain: configEntries.primaryDomain || configEntries.domain || 'API service',
|
|
1023
1149
|
databaseChoice: configEntries.databaseChoice || configEntries.database || 'None (stateless service)',
|
|
1024
1150
|
authStrategy: configEntries.authStrategy || configEntries.auth || 'None (public service)',
|
package/package.json
CHANGED
|
@@ -64,6 +64,8 @@ const REQUIRED_BOOTSTRAP_DESIGN_SNIPPETS = [
|
|
|
64
64
|
'Responsive Strategy and Cross-Viewport Adaptation Matrix',
|
|
65
65
|
'colorTruth.format',
|
|
66
66
|
'crossViewportAdaptation.mutationRules.mobile/tablet/desktop',
|
|
67
|
+
'motionSystem',
|
|
68
|
+
'componentMorphology',
|
|
67
69
|
];
|
|
68
70
|
|
|
69
71
|
const REQUIRED_UI_DESIGN_JUDGE_SNIPPETS = [
|