@ryuenn3123/agentic-senior-core 3.0.6 → 3.0.8

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.
@@ -1,22 +1,48 @@
1
1
 
2
- # Bootstrap DESIGN.md (UI/UX Art Direction)
2
+ # Bootstrap Dynamic Design Contract
3
3
 
4
- When a user requests frontend design or redesign, the agent should automatically synthesize a complete DESIGN.md covering:
5
- - Visual identity (color palette, typography, spacing, iconography)
6
- - Layout and navigation principles
7
- - Component library and atomic design system
8
- - Accessibility and responsive guidelines
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 propose improvements instead of rewriting from scratch.
17
- 5. All references to docs or rules must be clickable markdown links.
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
- - Write a full DESIGN.md in markdown, with clear sections and clickable links to referenced docs/rules.
21
- - Use practical, modern, and accessible design language.
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 (DESIGN.md)
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)
@@ -1,5 +1,5 @@
1
1
  {
2
- "generatedAt": "2026-04-19T03:52:25.678Z",
2
+ "generatedAt": "2026-04-20T01:05:14.547Z",
3
3
  "reportName": "memory-continuity-benchmark",
4
4
  "schemaVersion": "1.0.0",
5
5
  "passed": true,
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.6
3
+ Generated by Agentic-Senior-Core CLI v3.0.8
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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Adapter Mode: thin
4
4
  Adapter Source: .instructions.md
5
- Canonical Snapshot SHA256: 354edbbfaedec284ddcc6d4a5bb5393a7f5385650d1a6ae84a2d9633b5a6d10d
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: 354edbbfaedec284ddcc6d4a5bb5393a7f5385650d1a6ae84a2d9633b5a6d10d
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.6
3
+ Generated by Agentic-Senior-Core CLI v3.0.8
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: 354edbbfaedec284ddcc6d4a5bb5393a7f5385650d1a6ae84a2d9633b5a6d10d
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.6 (2026-04-19).
13
+ Latest release: 3.0.8 (2026-04-20).
14
14
 
15
- Highlights in 3.0.0:
16
- - Universal IDE adapter surface is completed and synchronized through thin adapters.
17
- - Scoped auto-docs sync rollout is active with explicit phase-1 boundaries and precision/recall evidence.
18
- - Init and scaffolding flow is slimmer, template-free on active path, and validated by deterministic release gates.
15
+ Highlights in 3.0.8:
16
+ - Existing UI repositories now get `docs/design-intent.json` seeded during both `init` and `upgrade`.
17
+ - Upgrade preview explicitly shows when a machine-readable design seed will be created on apply.
18
+ - UI scope detection is now shared between `init` and `upgrade` so design-contract enforcement stays consistent.
19
19
 
20
20
  </div>
21
21
 
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import { createInterface } from 'node:readline/promises';
6
6
  import { stdin, stdout } from 'node:process';
7
+ import fs from 'node:fs/promises';
7
8
  import path from 'node:path';
8
9
 
9
10
  import {
@@ -29,10 +30,16 @@ import {
29
30
  formatBlockingSeverities,
30
31
  formatDuration,
31
32
  copyGovernanceAssetsToTarget,
33
+ pathExists,
32
34
  } from '../utils.mjs';
33
35
 
34
36
  import { collectProfilePacks, findProfilePackByInput } from '../profile-packs.mjs';
35
- import { detectProjectContext, buildDetectionSummary, formatDetectionCandidates } from '../detector.mjs';
37
+ import {
38
+ detectProjectContext,
39
+ buildDetectionSummary,
40
+ formatDetectionCandidates,
41
+ detectUiScopeSignals,
42
+ } from '../detector.mjs';
36
43
  import { compileDynamicContext, writeSelectedPolicy, writeOnboardingReport } from '../compiler.mjs';
37
44
  import {
38
45
  filterBlueprintFileNamesByCandidates,
@@ -55,6 +62,7 @@ import {
55
62
  hasExistingProjectDocs,
56
63
  loadProjectConfig,
57
64
  normalizeDocsLanguage,
65
+ buildDesignIntentSeedFromSignals,
58
66
  } from '../project-scaffolder.mjs';
59
67
  import { performRollback } from '../rollback.mjs';
60
68
  import {
@@ -162,6 +170,41 @@ async function askBlueprintSelection(promptMessage, selectableBlueprintFileNames
162
170
  return selectableBlueprintFileNames[selectedIndex] || selectableBlueprintFileNames[0] || null;
163
171
  }
164
172
 
173
+ function buildInitExistingProjectDesignIntentSeed({
174
+ targetDirectoryPath,
175
+ packageManifest,
176
+ selectedStackFileName,
177
+ selectedBlueprintFileName,
178
+ uiScopeSignals,
179
+ architectureProjectDescription,
180
+ }) {
181
+ const projectName = String(packageManifest?.name || path.basename(targetDirectoryPath)).trim() || 'existing-ui-project';
182
+ const isMobileUiProject = String(selectedStackFileName || '').toLowerCase().includes('react-native')
183
+ || String(selectedStackFileName || '').toLowerCase().includes('flutter')
184
+ || uiScopeSignals.signalReasons.some((signalReason) => signalReason.includes('android') || signalReason.includes('ios'));
185
+ const resolvedDomain = isMobileUiProject ? 'Mobile app' : 'Web application';
186
+ const projectDescription = String(packageManifest?.description || architectureProjectDescription || '').trim()
187
+ || `Existing ${resolvedDomain.toLowerCase()} detected during init. Create a project-specific dynamic design contract before shipping new UI work.`;
188
+
189
+ return buildDesignIntentSeedFromSignals({
190
+ projectName,
191
+ projectDescription,
192
+ primaryDomain: resolvedDomain,
193
+ features: [],
194
+ initContext: {
195
+ stackFileName: selectedStackFileName,
196
+ blueprintFileName: selectedBlueprintFileName,
197
+ },
198
+ status: 'seed-generated-during-init',
199
+ supplementalFields: {
200
+ initSignals: {
201
+ detectedFrom: uiScopeSignals.signalReasons,
202
+ generatedBy: 'init-existing-project-seed',
203
+ },
204
+ },
205
+ });
206
+ }
207
+
165
208
  export async function runInitCommand(targetDirectoryArgument, initOptions = {}) {
166
209
  const resolvedTargetDirectoryPath = path.resolve(targetDirectoryArgument || '.');
167
210
  const isTokenOptimizationEnabled = typeof initOptions.tokenOptimize === 'boolean'
@@ -399,6 +442,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
399
442
  )?.label || 'Both (frontend + backend)';
400
443
 
401
444
  let architectureRecommendation = null;
445
+ let architectureProjectDescription = '';
402
446
  let architectPreferenceState = await readArchitectPreferenceState();
403
447
  let architectPreferenceUpdated = false;
404
448
 
@@ -457,6 +501,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
457
501
  selectedProjectScopeLabel = architectureSelection.selectedProjectScopeLabel;
458
502
  selectedManualStackFileName = architectureSelection.selectedManualStackFileName;
459
503
  selectedManualBlueprintFileName = architectureSelection.selectedManualBlueprintFileName;
504
+ architectureProjectDescription = architectureSelection.architectureProjectDescription;
460
505
  architectureRecommendation = architectureSelection.architectureRecommendation;
461
506
  architectPreferenceState = architectureSelection.architectPreferenceState;
462
507
  architectPreferenceUpdated = architectureSelection.architectPreferenceUpdated;
@@ -578,6 +623,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
578
623
 
579
624
  // --- Project Documentation Scaffolding ---
580
625
  let scaffoldingResult = null;
626
+ const supplementalMaterializedDocFileNames = [];
581
627
  const isFreshProjectTarget = wasDirectoryEffectivelyEmpty && !hadExistingProjectDocsBeforeInit;
582
628
  const shouldOfferScaffolding = initOptions.scaffoldDocs === true
583
629
  || Boolean(initOptions.projectConfig)
@@ -607,6 +653,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
607
653
  } else {
608
654
  discoveryAnswers = await runProjectDiscovery(userInterface, {
609
655
  defaultProjectName: path.basename(resolvedTargetDirectoryPath),
656
+ defaultProjectDescription: architectureProjectDescription,
610
657
  });
611
658
  }
612
659
 
@@ -645,6 +692,9 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
645
692
  for (const generatedPromptFileName of scaffoldingResult.generatedPromptFileNames || []) {
646
693
  console.log(` - .agent-context/prompts/${generatedPromptFileName}`);
647
694
  }
695
+ for (const materializedFileName of scaffoldingResult.materializedFileNames || []) {
696
+ console.log(` - docs/${materializedFileName}`);
697
+ }
648
698
  console.log('Project docs will be authored dynamically by your IDE assistant from these prompts.');
649
699
  } else {
650
700
  console.log(`\nProject documentation generated in docs/:`);
@@ -655,6 +705,36 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
655
705
  }
656
706
  }
657
707
 
708
+ const existingProjectUiScopeSignals = projectDetection.hasExistingProjectFiles
709
+ ? await detectUiScopeSignals({
710
+ targetDirectoryPath: resolvedTargetDirectoryPath,
711
+ selectedStackFileName: selectedResolvedStackFileName,
712
+ selectedBlueprintFileName: selectedResolvedBlueprintFileName,
713
+ })
714
+ : null;
715
+ const designIntentTargetPath = path.join(resolvedTargetDirectoryPath, 'docs', 'design-intent.json');
716
+ const shouldSeedExistingUiDesignIntent = projectDetection.hasExistingProjectFiles
717
+ && existingProjectUiScopeSignals?.isUiScopeLikely === true
718
+ && !(await pathExists(designIntentTargetPath));
719
+
720
+ if (shouldSeedExistingUiDesignIntent) {
721
+ const docsDirectoryPath = path.join(resolvedTargetDirectoryPath, 'docs');
722
+ const designIntentSeedContent = buildInitExistingProjectDesignIntentSeed({
723
+ targetDirectoryPath: resolvedTargetDirectoryPath,
724
+ packageManifest: existingProjectUiScopeSignals.packageManifest,
725
+ selectedStackFileName: selectedResolvedStackFileName,
726
+ selectedBlueprintFileName: selectedResolvedBlueprintFileName,
727
+ uiScopeSignals: existingProjectUiScopeSignals,
728
+ architectureProjectDescription,
729
+ });
730
+
731
+ await ensureDirectory(docsDirectoryPath);
732
+ await fs.writeFile(designIntentTargetPath, designIntentSeedContent, 'utf8');
733
+ supplementalMaterializedDocFileNames.push('design-intent.json');
734
+
735
+ console.log('\nExisting UI/frontend scope detected. Seeded docs/design-intent.json so the machine-readable design contract exists before UI implementation work continues.');
736
+ }
737
+
658
738
  await compileDynamicContext({
659
739
  targetDirectoryPath: resolvedTargetDirectoryPath,
660
740
  selectedProfileName,
@@ -674,6 +754,10 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
674
754
  selectedProfileName,
675
755
  selectedProfilePack,
676
756
  selectedPreset: initOptions.preset || null,
757
+ projectScope: {
758
+ key: selectedProjectScopeKey,
759
+ label: selectedProjectScopeLabel,
760
+ },
677
761
  selectedStackFileName: selectedResolvedStackFileName,
678
762
  selectedAdditionalStackFileNames,
679
763
  selectedBlueprintFileName: selectedResolvedBlueprintFileName,
@@ -746,12 +830,18 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
746
830
  console.log('- Generated files: .agent-instructions.md, .cursorrules, .windsurfrules, .clauderc, and .agent-context/state/onboarding-report.json');
747
831
  if (scaffoldingResult?.bootstrapMode === 'ai-synthesis') {
748
832
  console.log(`- Bootstrap prompts: ${(scaffoldingResult.generatedPromptFileNames || []).length} files generated in .agent-context/prompts/`);
833
+ if ((scaffoldingResult.materializedFileNames || []).length > 0) {
834
+ console.log(`- Seed docs: ${(scaffoldingResult.materializedFileNames || []).length} files generated in docs/`);
835
+ }
749
836
  console.log(`- Bootstrap docs language: ${scaffoldingResult.docsLanguage}`);
750
837
  console.log(`- Expected project docs after synthesis: ${scaffoldingResult.generatedFileNames.length} files in docs/`);
751
838
  } else if (scaffoldingResult) {
752
839
  console.log(`- Project docs: ${scaffoldingResult.generatedFileNames.length} files generated in docs/`);
753
840
  console.log(`- Project docs language: ${scaffoldingResult.docsLanguage}`);
754
841
  }
842
+ if (supplementalMaterializedDocFileNames.length > 0) {
843
+ console.log(`- Design seed docs: ${supplementalMaterializedDocFileNames.length} files generated in docs/`);
844
+ }
755
845
  console.log(`- Repository workflows copied: no (workflows remain source-repo assets)`);
756
846
  console.log(`- MCP configuration: ${shouldIncludeMcpTemplate ? 'auto-configured for your IDEs (VS Code, Cursor, Zed, Gemini)' : 'disabled (--no-mcp-template)'}`);
757
847
  if (isMemoryContinuityEnabled) {
@@ -779,7 +869,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
779
869
  console.log('\nPrompt starter examples (copy and adapt in your IDE):');
780
870
  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
871
  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.');
872
+ 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
873
  }
784
874
  console.log(`- Build an MVP for ${promptProjectName} using the newly synthesized docs as strict project context.`);
785
875
  console.log('- When scope changes, update docs/* in the same change so future prompts stay aligned.');
@@ -791,6 +881,11 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
791
881
  console.log(`- Build an MVP for ${promptProjectName}. Follow Layer 9 docs and keep the current stack, database, and auth constraints.`);
792
882
  console.log('- Add [new feature] and update docs/project-brief.md plus docs/flow-overview.md in the same change.');
793
883
  console.log('- If this change needs architecture migration, propose a migration plan first, then implement after approval.');
884
+ } else if (supplementalMaterializedDocFileNames.includes('design-intent.json')) {
885
+ console.log('I also seeded docs/design-intent.json for this existing UI repository so future UI work starts from a machine-readable design contract without forcing a canned visual concept.');
886
+ console.log('\nPrompt starter examples (copy and adapt in your IDE):');
887
+ console.log('- If docs/DESIGN.md is missing, execute .agent-context/prompts/bootstrap-design.md now and refine docs/design-intent.json into a complete design contract before building UI components.');
888
+ console.log('- Keep docs/design-intent.json and docs/DESIGN.md synchronized whenever the UI direction changes.');
794
889
  }
795
890
  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.');
796
891
  console.log('MCP server registration is manual inside your IDE settings, even when mcp.json exists.');
@@ -29,6 +29,7 @@ import {
29
29
  detectProjectContext,
30
30
  buildDetectionSummary,
31
31
  formatDetectionCandidates,
32
+ detectUiScopeSignals,
32
33
  } from '../detector.mjs';
33
34
  import {
34
35
  buildCompiledRulesContent,
@@ -40,7 +41,10 @@ import {
40
41
  import { runPreflightChecks } from '../preflight.mjs';
41
42
  import { createBackup } from '../backup.mjs';
42
43
  import { performRollback } from '../rollback.mjs';
43
- import { detectProjectDocTemplateStaleness } from '../project-scaffolder.mjs';
44
+ import {
45
+ detectProjectDocTemplateStaleness,
46
+ buildDesignIntentSeedFromSignals,
47
+ } from '../project-scaffolder.mjs';
44
48
 
45
49
  export function parseUpgradeArguments(commandArguments) {
46
50
  const parsedUpgradeOptions = {
@@ -103,6 +107,40 @@ function buildExistingProjectMajorConstraints() {
103
107
  ];
104
108
  }
105
109
 
110
+ function buildUpgradeDesignIntentSeed({
111
+ targetDirectoryPath,
112
+ packageManifest,
113
+ selectedStackFileName,
114
+ selectedBlueprintFileName,
115
+ uiScopeSignals,
116
+ }) {
117
+ const projectName = String(packageManifest?.name || path.basename(targetDirectoryPath)).trim() || 'existing-ui-project';
118
+ const isMobileUiProject = String(selectedStackFileName || '').toLowerCase().includes('react-native')
119
+ || String(selectedStackFileName || '').toLowerCase().includes('flutter')
120
+ || uiScopeSignals.signalReasons.some((signalReason) => signalReason.includes('android') || signalReason.includes('ios'));
121
+ const resolvedDomain = isMobileUiProject ? 'Mobile app' : 'Web application';
122
+ const projectDescription = String(packageManifest?.description || '').trim()
123
+ || `Existing ${resolvedDomain.toLowerCase()} detected during upgrade. Create a project-specific dynamic design contract before shipping new UI work.`;
124
+
125
+ return buildDesignIntentSeedFromSignals({
126
+ projectName,
127
+ projectDescription,
128
+ primaryDomain: resolvedDomain,
129
+ features: [],
130
+ initContext: {
131
+ stackFileName: selectedStackFileName,
132
+ blueprintFileName: selectedBlueprintFileName,
133
+ },
134
+ status: 'seed-generated-during-upgrade',
135
+ supplementalFields: {
136
+ upgradeSignals: {
137
+ detectedFrom: uiScopeSignals.signalReasons,
138
+ generatedBy: 'upgrade-seed',
139
+ },
140
+ },
141
+ });
142
+ }
143
+
106
144
  export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions = {}) {
107
145
  const resolvedTargetDirectoryPath = path.resolve(targetDirectoryArgument || '.');
108
146
 
@@ -135,7 +173,6 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
135
173
  const blueprintFileNames = await collectFileNames(path.join(AGENT_CONTEXT_DIR, 'blueprints'));
136
174
  const existingOnboardingReport = await loadOnboardingReportIfExists(resolvedTargetDirectoryPath);
137
175
  const projectDetection = await detectProjectContext(resolvedTargetDirectoryPath);
138
-
139
176
  const selectedProfileName = PROFILE_PRESETS[existingOnboardingReport?.selectedProfile]
140
177
  ? existingOnboardingReport.selectedProfile
141
178
  : 'balanced';
@@ -167,6 +204,34 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
167
204
  const includeCiGuardrails = typeof existingOnboardingReport?.ciGuardrailsEnabled === 'boolean'
168
205
  ? existingOnboardingReport.ciGuardrailsEnabled
169
206
  : true;
207
+ const uiScopeSignals = await detectUiScopeSignals({
208
+ targetDirectoryPath: resolvedTargetDirectoryPath,
209
+ selectedStackFileName,
210
+ selectedBlueprintFileName,
211
+ projectScopeKey: existingOnboardingReport?.projectScope?.key || null,
212
+ projectScopeSourceLabel: 'onboarding project scope',
213
+ });
214
+ const packageManifest = uiScopeSignals.packageManifest;
215
+ const designContractPaths = ['docs/DESIGN.md', 'docs/design-intent.json'];
216
+ const missingDesignContractPaths = [];
217
+
218
+ for (const designContractPath of designContractPaths) {
219
+ const absoluteDesignContractPath = path.join(resolvedTargetDirectoryPath, ...designContractPath.split('/'));
220
+ if (!(await pathExists(absoluteDesignContractPath))) {
221
+ missingDesignContractPaths.push(designContractPath);
222
+ }
223
+ }
224
+ const shouldSeedDesignIntentOnApply = uiScopeSignals.isUiScopeLikely
225
+ && missingDesignContractPaths.includes('docs/design-intent.json');
226
+ const designIntentSeedContent = shouldSeedDesignIntentOnApply
227
+ ? buildUpgradeDesignIntentSeed({
228
+ targetDirectoryPath: resolvedTargetDirectoryPath,
229
+ packageManifest,
230
+ selectedStackFileName,
231
+ selectedBlueprintFileName,
232
+ uiScopeSignals,
233
+ })
234
+ : null;
170
235
 
171
236
  const detectionMajorConstraints = buildExistingProjectMajorConstraints();
172
237
  const detectionTransparency = {
@@ -288,6 +353,21 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
288
353
  console.log('Recommendation: regenerate docs with init --scaffold-docs or update the files manually to match the latest template version.');
289
354
  }
290
355
 
356
+ if (uiScopeSignals.isUiScopeLikely && missingDesignContractPaths.length > 0) {
357
+ console.log('\n[WARN] UI/frontend scope was detected, but the dynamic design contract is incomplete:');
358
+ for (const missingDesignContractPath of missingDesignContractPaths) {
359
+ console.log(`- Missing ${missingDesignContractPath}`);
360
+ }
361
+ if (uiScopeSignals.signalReasons.length > 0) {
362
+ console.log(`- Detection signals: ${uiScopeSignals.signalReasons.join('; ')}`);
363
+ }
364
+ if (shouldSeedDesignIntentOnApply) {
365
+ console.log('- Planned seed on apply: docs/design-intent.json');
366
+ }
367
+ console.log('Recommendation: create or refresh docs/DESIGN.md and docs/design-intent.json before allowing UI implementation work.');
368
+ console.log('Upgrade synchronizes governance assets and can seed docs/design-intent.json, but it does not author project-specific docs/DESIGN.md automatically.');
369
+ }
370
+
291
371
  if (upgradeOptions.dryRun) {
292
372
  console.log('\nDry run enabled. No files were modified.');
293
373
  return;
@@ -310,6 +390,15 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
310
390
  pruneManagedSurface: upgradeOptions.pruneManagedSurface === true,
311
391
  managedSurfacePlan,
312
392
  });
393
+ const supplementalCreatedFileNames = [];
394
+
395
+ if (shouldSeedDesignIntentOnApply && designIntentSeedContent) {
396
+ const docsDirectoryPath = path.join(resolvedTargetDirectoryPath, 'docs');
397
+ const designIntentTargetPath = path.join(docsDirectoryPath, 'design-intent.json');
398
+ await ensureDirectory(docsDirectoryPath);
399
+ await fs.writeFile(designIntentTargetPath, designIntentSeedContent, 'utf8');
400
+ supplementalCreatedFileNames.push('docs/design-intent.json');
401
+ }
313
402
 
314
403
  await fs.writeFile(currentRulesPath, plannedRulesContent, 'utf8');
315
404
  await fs.writeFile(path.join(resolvedTargetDirectoryPath, '.windsurfrules'), plannedRulesContent, 'utf8');
@@ -320,6 +409,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
320
409
  targetDirectoryPath: resolvedTargetDirectoryPath,
321
410
  selectedProfileName,
322
411
  selectedProfilePack: existingOnboardingReport?.selectedProfilePack || null,
412
+ projectScope: existingOnboardingReport?.projectScope || null,
323
413
  selectedStackFileName,
324
414
  selectedAdditionalStackFileNames,
325
415
  selectedBlueprintFileName,
@@ -346,6 +436,12 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
346
436
  governanceSyncResult.updatedFiles.forEach((fileName) => console.log(` [UPDATED] ${fileName}`));
347
437
  governanceSyncResult.deletedManagedFiles.forEach((fileName) => console.log(` [DELETED] ${fileName}`));
348
438
  }
439
+ if (supplementalCreatedFileNames.length > 0) {
440
+ if (!(governanceSyncResult.updatedFiles.length > 0 || governanceSyncResult.createdFiles.length > 0 || governanceSyncResult.deletedManagedFiles.length > 0)) {
441
+ console.log('\nDetailed changes:');
442
+ }
443
+ supplementalCreatedFileNames.forEach((fileName) => console.log(` [NEW] ${fileName} (seed)`));
444
+ }
349
445
 
350
446
  console.log('\nRefreshed files: .cursorrules, .windsurfrules, .agent-context/state/onboarding-report.json');
351
447
  } catch (error) {
@@ -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.',