feat(landing-visual): add landing-design-interpretation skill, landing-visual-debugging rule, extract-contrast script, and frontend-developer measurement-first protocol

Evolution to solve human-language design tasks (e.g., 'text blends into background').

New:
- .kilo/skills/landing-design-interpretation/SKILL.md — translation dictionary + contrast protocol
- .kilo/rules/landing-visual-debugging.md — mandatory 3-phase pipeline (Interpret→Measure→Fix)
- tests/scripts/extract-contrast.js — Playwright-based contrast extraction
- HOW_TO_SYNC_KILO.md — sync instructions for target projects

Updated:
- .kilo/agents/frontend-developer.md — mandatory measurement-first behavior for landing visual tasks
- kilo-meta.json — description updated for frontend-developer
- AGENTS.md, KILO_SPEC.md — auto-synced by script

Refs: landing visual debugging evolution
This commit is contained in:
NW
2026-05-22 18:27:44 +01:00
parent ded8e3022d
commit 9eb0a0ba34
8 changed files with 743 additions and 22 deletions

View File

@@ -435,32 +435,37 @@ Provider availability depends on configuration. Common providers include:
|-------|------|-------|
| `@RequirementRefiner` | Converts vague ideas and bug reports into strict User Stories with acceptance criteria checklists. | ollama-cloud/kimi-k2-thinking |
| `@HistoryMiner` | Analyzes git history to find duplicates and past solutions, preventing regression and duplicate work. | ollama-cloud/nemotron-3-super |
| `@SystemAnalyst` | Designs technical specifications, data schemas, and API contracts before implementation. | ollama-cloud/nemotron-3-super |
| `@SystemAnalyst` | Designs technical specifications, data schemas, and API contracts before implementation. | ollama-cloud/glm-5.1 |
| `@SdetEngineer` | Writes tests following TDD methodology. | ollama-cloud/qwen3-coder:480b |
| `@LeadDeveloper` | Primary code writer for backend and core logic. | ollama-cloud/nemotron-3-super |
| `@FrontendDeveloper` | Handles UI implementation with multimodal capabilities. | ollama-cloud/kimi-k2.5 |
| `@BackendDeveloper` | Backend specialist for Node. | ollama-cloud/deepseek-v3.2 |
| `@GoDeveloper` | Go backend specialist for Gin, Echo, APIs, and database integration. | ollama-cloud/qwen3-coder:480b |
| `@LeadDeveloper` | Primary code writer for backend and core logic. | ollama-cloud/qwen3-coder:480b |
| `@FrontendDeveloper` | Handles UI implementation with multimodal capabilities. | ollama-cloud/minimax-m2.5 |
| `@BackendDeveloper` | Backend specialist for Node. | ollama-cloud/qwen3-coder:480b |
| `@GoDeveloper` | Go backend specialist for Gin, Echo, APIs, and database integration. | ollama-cloud/deepseek-v4-pro-max |
| `@DevopsEngineer` | DevOps specialist for Docker, Kubernetes, CI/CD pipeline automation, and infrastructure management. | ollama-cloud/kimi-k2.6 |
| `@CodeSkeptic` | Adversarial code reviewer. | ollama-cloud/minimax-m2.5 |
| `@TheFixer` | Iteratively fixes bugs based on specific error reports and test failures. | ollama-cloud/minimax-m2.5 |
| `@PerformanceEngineer` | Reviews code for performance issues. | ollama-cloud/nemotron-3-super |
| `@SecurityAuditor` | Scans for security vulnerabilities, OWASP Top 10, dependency CVEs, and hardcoded secrets. | ollama-cloud/nemotron-3-super |
| `@TheFixer` | Iteratively fixes bugs based on specific error reports and test failures. | ollama-cloud/kimi-k2.6 |
| `@PerformanceEngineer` | Reviews code for performance issues. | ollama-cloud/deepseek-v4-pro-max |
| `@SecurityAuditor` | Scans for security vulnerabilities, OWASP Top 10, dependency CVEs, and hardcoded secrets. | ollama-cloud/deepseek-v4-pro-max |
| `@VisualTester` | Visual regression testing agent that compares screenshots and detects UI differences using pixelmatch and image diff. | ollama-cloud/qwen3-coder:480b |
| `@Orchestrator` | Main dispatcher. | ollama-cloud/kimi-k2.6 |
| `@ReleaseManager` | Manages git operations, semantic versioning, branching, and deployments. | ollama-cloud/devstral-2:123b |
| `@Evaluator` | Scores agent effectiveness after task completion for continuous improvement. | ollama-cloud/nemotron-3-super |
| `@PromptOptimizer` | Improves agent system prompts based on performance failures. | ollama-cloud/glm-5.1 |
| `@ReleaseManager` | Manages git operations, semantic versioning, branching, and deployments. | ollama-cloud/glm-5.1 |
| `@Evaluator` | Scores agent effectiveness after task completion for continuous improvement. | ollama-cloud/glm-5.1 |
| `@PromptOptimizer` | Improves agent system prompts based on performance failures. | ollama-cloud/qwen3.6-plus |
| `@ProductOwner` | Manages issue checklists, status labels, tracks progress and coordinates with human users. | ollama-cloud/glm-5.1 |
| `@AgentArchitect` | Creates, modifies, and reviews new agents, workflows, and skills based on capability gap analysis. | ollama-cloud/kimi-k2.6 |
| `@CapabilityAnalyst` | Analyzes task requirements against available agents, workflows, and skills. | ollama-cloud/nemotron-3-super |
| `@WorkflowArchitect` | Creates and maintains workflow definitions with complete architecture, Gitea integration, and quality gates. | ollama-cloud/gpt-oss:120b |
| `@MarkdownValidator` | Validates and corrects Markdown descriptions for Gitea issues. | ollama-cloud/nemotron-3-nano:30b |
| `@BrowserAutomation` | Browser automation agent using Playwright MCP for E2E testing, form filling, navigation, and web interaction. | ollama-cloud/kimi-k2.6 |
| `@Planner` | Advanced task planner using Chain of Thought, Tree of Thoughts, and Plan-Execute-Reflect. | ollama-cloud/nemotron-3-super |
| `@Reflector` | Self-reflection agent using Reflexion pattern - learns from mistakes. | ollama-cloud/nemotron-3-super |
| `@MemoryManager` | Manages agent memory systems - short-term (context), long-term (vector store), and episodic (experiences). | ollama-cloud/nemotron-3-super |
| `@IncidentResponder` | Server incident response, live forensics, malware removal, hardening, and SSH-based cleanup. | ollama-cloud/kimi-k2.6 |
| `@CapabilityAnalyst` | Analyzes task requirements against available agents, workflows, and skills. | ollama-cloud/glm-5.1 |
| `@WorkflowArchitect` | Creates and maintains workflow definitions with complete architecture, Gitea integration, and quality gates. | ollama-cloud/glm-5.1 |
| `@MarkdownValidator` | Validates and corrects Markdown descriptions for Gitea issues. | ollama-cloud/deepseek-v4-pro-max |
| `@BrowserAutomation` | Browser automation agent using Playwright MCP for E2E testing, form filling, navigation, and web interaction. | ollama-cloud/qwen3-coder:480b |
| `@Planner` | Advanced task planner using Chain of Thought, Tree of Thoughts, and Plan-Execute-Reflect. | ollama-cloud/deepseek-v4-pro-max |
| `@Reflector` | Self-reflection agent using Reflexion pattern - learns from mistakes. | ollama-cloud/deepseek-v4-pro-max |
| `@MemoryManager` | Manages agent memory systems - short-term (context), long-term (vector store), and episodic (experiences). | ollama-cloud/qwen3.6-plus |
| `@ArchitectIndexer` | Indexes and maps project codebase architecture into . | ollama-cloud/glm-5.1 |
| `@FlutterDeveloper` | Flutter mobile specialist for cross-platform apps, state management, and UI components. | ollama-cloud/qwen3-coder:480b |
| `@PhpDeveloper` | PHP specialist for Laravel, Symfony, WordPress, and modular architecture. | ollama-cloud/qwen3-coder:480b |
| `@PipelineJudge` | Automated pipeline judge. | ollama-cloud/glm-5.1 |
| `@PythonDeveloper` | Python specialist for Django, FastAPI, data processing, and ML pipelines. | ollama-cloud/qwen3-coder:480b |
| `@IncidentResponder` | Server incident response and system hardening specialist. | ollama-cloud/kimi-k2.6 |

View File

@@ -1,5 +1,5 @@
---
description: Handles UI implementation with multimodal capabilities. Accepts visual references like screenshots and mockups (GNS-2 Tier 1)
description: Handles UI implementation with multimodal capabilities. Accepts visual references like screenshots and mockups. Follows landing-design-interpretation skill for visual/contrast/color tasks on landing pages (MANDATORY measurement-first protocol)
mode: all
model: ollama-cloud/minimax-m2.5
color: "#0EA5E9"
@@ -46,6 +46,11 @@ Use the Task tool with `subagent_type` to delegate to other agents:
4. **Responsive by default** — mobile-first approach
5. **Component composition** — build small, reusable parts
6. **Tool-First Enforcement** — Read existing component files with Read/Grep before modifying. Search for existing patterns before introducing new ones.
7. **Landing Visual Protocol (MANDATORY)** — When task involves landing pages, colors, contrast, or readability:
- **STEP 1: Interpret** — Load `.kilo/skills/landing-design-interpretation/SKILL.md`. Translate human description to technical selectors.
- **STEP 2: Measure** — Use Docker-based measurement tools (Playwright contrast extraction, screenshot diff, or axe-core) to get exact color values and contrast ratios. **NEVER guess colors without measurement.**
- **STEP 3: Fix + Verify** — Apply minimal targeted CSS changes, then re-run measurement to confirm contrast >= 4.5:1.
- Reference: `.kilo/rules/landing-visual-debugging.md`
## Visual Quality Rules (Learned from Past Mistakes)
@@ -60,6 +65,7 @@ Use the Task tool with `subagent_type` to delegate to other agents:
1. **Always check selector specificity** when styling reused components. If a global `.nav-link { color: white !important }` exists from navbar, scoped tab `.nav-link` MUST use higher specificity or `!important` override.
2. **Verify contrast BEFORE shipping** — light gray text (`#6c757d`) on white (`#fff`) is only 4.6:1, which is borderline. For small text under 14px, use darker text (`#495057` or `#333`).
3. **Don't assume Bootstrap defaults are safe** — its `.nav-tabs` may bring unwanted borders, margins, or radius. Always inspect computed styles.
4. **Human Description Translation** — When human says "blends in", "disappears", "hard to read": immediately compute contrast ratio with `getComputedStyle` + Docker Playwright script. Do NOT trust visual intuition alone.
### Border & Shadow Hygiene
1. **One visual hierarchy per component** — border OR shadow, not both simultaneously on the same element.
@@ -73,6 +79,7 @@ Use the Task tool with `subagent_type` to delegate to other agents:
- [ ] Hover states are distinguishable from active states
- [ ] Mobile: tabs don't overflow or wrap weirdly
- [ ] Component looks intentional, not accidental
- [ ] Contrast measurement run and documented for landing/visual tasks
## Output Format
@@ -119,6 +126,9 @@ This model can:
- DO NOT make API design decisions
- DO NOT skip accessibility
- DO NOT ignore responsive design
- DO NOT change landing page colors without running automated contrast measurement
- DO NOT rely on visual intuition for color decisions on landing pages
- DO NOT skip `.kilo/rules/landing-visual-debugging.md` protocol for visual tasks
## Handoff Protocol

View File

@@ -0,0 +1,135 @@
# Landing Visual Debugging Rules
Mandatory rules for handling visual/contrast/color tasks on landing pages. All agents working with landing pages MUST follow this pipeline.
## The Core Problem
Human descriptions like "text blends into background" are semantically precise for humans but computationally ambiguous for LLMs. Pure prompt engineering cannot reliably teach an LLM to "see" low contrast. The solution is a **structured protocol + automated tooling** that converts human language into measurable visual metrics.
## Rule: The 3-Phase Landing Visual Fix Protocol
### Phase 1: Interpret (Do NOT write code yet)
Before touching any CSS file:
1. **LOAD SKILL**: Read `.kilo/skills/landing-design-interpretation/SKILL.md`
2. **TRANSLATE**: Map human description to technical meaning using the Translation Dictionary
3. **IDENTIFY**: List specific CSS selectors likely affected (min 3, max 10)
4. **DO NOT IMPLEMENT** until Phase 3
### Phase 2: Measure (Automated detection)
ALWAYS run measurement before fixing. Choose ONE method:
#### Method A: Playwright Contrast Extraction (Preferred)
```bash
# Inside Docker
docker compose -f docker/docker-compose.web-testing.yml run --rm browser-automation \
node -e "
const { chromium } = require('playwright');
// Script that extracts all color pairs with contrast < 4.5
// Output: JSON array of {selector, color, background, ratio, text}
"
```
#### Method B: Screenshot + Visual Diff
```bash
docker compose -f docker/docker-compose.web-testing.yml run --rm screenshot-current
# Take screenshot, then analyze with landing-design-interpretation skill
```
#### Method C: Axe-Core Automated Check
```bash
# If project has axe-core installed
npx axe {url} --tags wcag2aa --reporter json
# Extract contrast violations from output
```
### Phase 3: Fix (With verification)
1. **Read SKILL**: Re-read `.kilo/skills/landing-design-interpretation/SKILL.md` § Fix Direction
2. **Apply minimal fix**: Change ONLY the specific color values identified in Phase 2
3. **Verify immediately**:
```bash
# Re-run the same measurement tool
# Confirm contrast ratio now >= 4.5:1
```
4. **Screenshot comparison**: Run visual-tester to ensure fix didn't break other elements
## Rule: Contrast-First Verification
For EVERY landing visual task, the agent MUST verify contrast BEFORE marking complete:
```markdown
### Contrast Verification
- [ ] All text elements checked
- [ ] Contrast ratio >= 4.5:1 (or >= 3:1 for large text)
- [ ] No invisible text (color == background)
- [ ] Hover states maintain minimum contrast
- [ ] Screenshot taken after fix for visual confirmation
```
## Rule: No Pure LLM Guessing
PROHIBITED:
- Changing colors based only on "looks better" intuition
- Applying `!important` without measuring root cause
- Darkening/lightening by arbitrary amounts (e.g., "make it a bit darker")
- Skipping verification after fixes
REQUIRED:
- Every color change must reference a computed contrast ratio
- Every fix must be verifiable by re-running measurement
- Every invisible-text bug must include the exact hex values that caused collision
## Rule: Landing-Specific Context
When ANY task mentions these keywords, automatically load this rule + landing-design-interpretation skill:
- `landing`, `лендинг`, `landing page`
- `цвет`, `цветовая`, `фон`, `background`, `contrast`, `контраст`
- `не видно`, `сливается`, `disappears`, `blends`, `invisible`
- `почище`, `профессионально`, `professional`, `clean`
## Example: Complete Workflow
### Task
> "Исправь цветовую схему лендинга так как где то цвет текста сливается с цветом фона и блока"
### Phase 1: Interpret
- LOAD: landing-design-interpretation skill
- TRANSLATE: "сливается" = contrast < 4.5:1 or color ≈ background-color
- IDENTIFY: likely `.hero-text`, `.feature-description`, `.cta-subtitle`, `.card-body p`
### Phase 2: Measure
```bash
docker compose -f docker/docker-compose.web-testing.yml run --rm browser-automation
# Output:
# {
# "issues": [
# {"selector": ".hero p", "color": "#888888", "background": "#f0f0f0", "ratio": 2.8},
# {"selector": ".card-body", "color": "#666666", "background": "#e8e8e8", "ratio": 3.2}
# ]
# }
```
### Phase 3: Fix
- `.hero p`: change `#888` → `#555` (ratio becomes 5.1:1)
- `.card-body`: change `#666` → `#444` (ratio becomes 4.8:1)
- Re-run measurement: ✅ PASSED
- Screenshot diff: ✅ No regressions
## Integration with Existing Rules
| Existing Rule | How This Extends It |
|---------------|---------------------|
| `frontend-developer.md` | Adds mandatory contrast-measurement step before CSS changes |
| `visual-tester.md` | Adds structured issue detection (contrast ratios) to screenshot comparison |
| `docker.md` | Requires Docker-based measurement tools, not host installation |
| `token-optimization.md` | Prevents 7-iteration loops by enforcing measurement-first approach |
## Violation Consequences
If an agent skips phases or guesses colors:
1. Result MUST be rejected by orchestrator
2. Issue labeled `quality::visual-fix-failed`
3. Re-assigned with explicit instruction: "Follow landing-visual-debugging protocol"

View File

@@ -0,0 +1,197 @@
# Skill: Landing Design Interpretation
Translate human designer language into precise CSS/visual requirements. Bridge the gap between fuzzy descriptions like "text blends into background" and concrete technical fixes.
## Core Problem
LLM agents (even multimodal) cannot reliably detect subtle visual issues like low contrast, color collisions, or invisible text from screenshots. This skill provides a structured translation layer and automated validation pipeline.
## Translation Dictionary
| Human Description | Technical Meaning | Automated Check | CSS Properties to Inspect |
|-------------------|-------------------|-------------------|---------------------------|
| "Text blends into background" | Contrast ratio < 4.5:1 (WCAG AA) | `axe-core` or custom contrast script | `color`, `background-color`, `opacity` |
| "Text disappears" | `color` matches or is too close to `background-color` | Compute relative luminance | `color`, `background-color` |
| "Colors clash" | Color combination violates WCAG or brand palette | Check against design tokens | `color`, `background-color`, `border-color` |
| "Looks washed out" | Low saturation OR low contrast overall | HSL analysis + contrast check | `filter`, `opacity`, `background-color` |
| "Hard to read" | Font size too small OR contrast too low OR line-height too tight | Combined metric check | `font-size`, `color`, `background-color`, `line-height` |
| "Not enough pop" | Insufficient contrast between element and surroundings | Surrounding pixel sampling | `box-shadow`, `border`, `background` |
| "Looks muddy" | Similar luminance values competing | Luminance delta check | All color properties |
| "Feels heavy" | Too many dark elements OR too much contrast | Visual weight analysis | `background`, `border`, `box-shadow` |
## Contrast Analysis Protocol
### Step 1: Extract Color Pairs
For any element reported as problematic:
```
1. Get computed `color` (text)
2. Get computed `background-color` (direct or inherited)
3. If background is transparent, sample parent background
4. If background is image/gradient, sample dominant color
```
### Step 2: Compute Contrast Ratio
```
relativeLuminance = (component <= 0.03928) ? component/12.92 : ((component + 0.055)/1.055)^2.4
contrastRatio = (L1 + 0.05) / (L2 + 0.05) # L1 = lighter, L2 = darker
```
### Step 3: Decision Matrix
| Ratio | Verdict | Action |
|-------|---------|--------|
| < 3:1 | Critical fail | Immediate fix required |
| 3:1 4.5:1 | Fail (AA for normal text) | Darken text or lighten background |
| 4.5:1 7:1 | Pass (AA) | Acceptable, monitor |
| >= 7:1 | Pass (AAA) | Excellent |
### Step 4: Fix Direction
If text is too light on light background:
- Option A: Darken text (`#333``#000`)
- Option B: Lighten background (`#f5f5f5``#fff`)
- Option C: Add text-shadow for readability boost
If text is too dark on dark background:
- Option A: Lighten text (`#333``#ccc` or `#fff`)
- Option B: Darken background
- Option C: Add semi-transparent overlay behind text
## Automated Validation Tools
### Tool 1: Playwright Contrast Extractor
```javascript
// Extract all color pairs from page
const elements = await page.$$('body *');
const issues = [];
for (const el of elements) {
const style = await el.evaluate(e => window.getComputedStyle(e));
const text = await el.evaluate(e => e.textContent?.trim());
if (text && style.color && style.backgroundColor) {
const ratio = computeContrast(style.color, style.backgroundColor);
if (ratio < 4.5) {
issues.push({selector: await el.evaluate(e => cssPath(e)), ratio, text: text.slice(0, 50)});
}
}
}
```
### Tool 2: Screenshot + OCR Fallback
If automated extraction fails:
1. Take full-page screenshot
2. Run OCR (tesseract.js) on regions with reported text
3. Compare text bounding boxes to surrounding pixels
4. Flag regions where text color ≈ background color
## Skill Invocation
When an agent receives a landing-page visual task:
```
1. READ this skill first
2. TRANSLATE human description using Translation Dictionary
3. IDENTIFY affected elements via CSS selectors or DOM paths
4. RUN contrast analysis protocol
5. GENERATE structured report with:
- original_description
- technical_diagnosis
- affected_selectors[]
- contrast_ratios{}
- recommended_fixes[]
6. PASS report to frontend-developer or the-fixer for implementation
```
## Output Format
```markdown
## Landing Design Interpretation Report
### Original Request
{human description}
### Translation
| Human Term | Technical Meaning |
|------------|-------------------|
| ... | ... |
### Detected Issues
1. **{selector}**: contrast {ratio}:1 → {verdict}
- Current: `color: {val}; background: {val}`
- Fix: {specific CSS change}
### Recommended Fixes
1. `{selector}` → change `color` from `{old}` to `{new}`
2. `{selector}` → add `text-shadow: 0 1px 2px rgba(0,0,0,0.5)`
### Verification Checklist
- [ ] Contrast ratio >= 4.5:1 for all text
- [ ] No invisible text (color == background)
- [ ] Hover states distinguishable from active states
```
## Integration with Agents
| Agent | Uses This Skill When |
|-------|---------------------|
| `frontend-developer` | Receives landing visual bug report |
| `visual-tester` | Screenshot shows potential contrast issues |
| `the-fixer` | Bug report contains human visual description |
| `orchestrator` | Task keywords: landing + color/contrast/visual/readability |
## Examples
### Example 1: "Text blends into background"
```
Input: "Исправь цветовую схему лендинга так как где то цвет текста сливается с цветом фона и блока"
Translation:
- "сливается" = contrast ratio < 4.5:1 or color ≈ background-color
- "цвет текста" = `color` property
- "цвет фона и блока" = `background-color` of element and its container
Action:
1. Query all text elements with computed color
2. Compare to their effective background-color
3. Flag elements where ratio < 4.5
4. Report specific selectors and current values
5. Recommend darkening/lightening based on background luminance
```
### Example 2: "Looks unprofessional"
```
Input: "Сделай лендинг почище, сейчас выглядит непрофессионально"
Translation:
- "почище" = reduce visual noise, consistent spacing, remove competing shadows/borders
- "непрофессионально" = likely: inconsistent spacing, color chaos, poor hierarchy
Action:
1. Audit for >3 different fonts
2. Audit for >5 different colors in palette
3. Audit for competing shadows + borders on same element
4. Check vertical rhythm consistency (margin/padding multiples)
5. Report as structured list of design system violations
```
## GNS-2 Protocol
### Tier
Tier 0 (Skill / No Cascade)
- Used as reference material by agents
- Does NOT spawn subagents
- Provides structured data for agent decision-making
### On Entry
When an agent loads this skill:
1. Read the Translation Dictionary
2. Identify the human description pattern in the task
3. Follow the Contrast Analysis Protocol
4. Produce structured report
### On Exit
Agent MUST include in its result comment:
```markdown
### Design Interpretation Applied
- Original: "{human text}"
- Translated to: {technical terms}
- Contrast issues found: {count}
- Fixes applied: {count}
```

View File

@@ -52,6 +52,11 @@ These agents are invoked automatically by `/pipeline` or manually via `@mention`
| `@BackendDeveloper` | Backend specialist for Node | When backend needed |
| `@GoDeveloper` | Go backend specialist for Gin, Echo, APIs, and database integration | When Go backend needed |
| `@DevopsEngineer` | DevOps specialist for Docker, Kubernetes, CI/CD pipeline automation, and infrastructure management | When deployment/infra needed |
| `@ArchitectIndexer` | Indexes and maps project codebase architecture into | Manual invocation |
| `@FlutterDeveloper` | Flutter mobile specialist for cross-platform apps, state management, and UI components | Manual invocation |
| `@PhpDeveloper` | PHP specialist for Laravel, Symfony, WordPress, and modular architecture | Manual invocation |
| `@PythonDeveloper` | Python specialist for Django, FastAPI, data processing, and ML pipelines | Manual invocation |
| `@IncidentResponder` | Server incident response and system hardening specialist | Manual invocation |
### Quality Assurance
| Agent | Role | When Invoked |
@@ -87,6 +92,7 @@ These agents are invoked automatically by `/pipeline` or manually via `@mention`
| `@CapabilityAnalyst` | Analyzes task requirements against available agents, workflows, and skills | When starting new task |
| `@WorkflowArchitect` | Creates and maintains workflow definitions with complete architecture, Gitea integration, and quality gates | New workflow needed |
| `@MarkdownValidator` | Validates and corrects Markdown descriptions for Gitea issues | Before issue creation |
| `@PipelineJudge` | Automated pipeline judge | Manual invocation |
### Security & Incident Response
| Agent | Role | When Invoked |

191
HOW_TO_SYNC_KILO.md Normal file
View File

@@ -0,0 +1,191 @@
# How to Sync `.kilo/` from APAW to Your Project
## The Problem
APAW is the **framework repository** — it contains the master definitions for all agents, skills, rules, and workflows. Your project is the **target repository** — it needs these definitions to work with the agent system.
Agents DO NOT read from Gitea. They read from `.kilo/` in the **current working directory**. If you want your project's agents to use the new landing visual debugging capabilities, you MUST copy the updated files into your project's `.kilo/` directory.
## Sync Pattern
### Option 1: Copy `.kilo/` from APAW (Recommended for now)
When you want agents in your project to use the new landing visual debugging skill/rule/agent updates:
```bash
# 1. In APAW repo — verify you have the latest
cd /home/swp/Projects/APAW
git pull origin dev
# 2. Copy new/modified files to YOUR project
cp -r .kilo/skills/landing-design-interpretation /path/to/your/project/.kilo/skills/
cp .kilo/rules/landing-visual-debugging.md /path/to/your/project/.kilo/rules/
cp .kilo/agents/frontend-developer.md /path/to/your/project/.kilo/agents/
# Also copy any updated skills/rules/agents you need
cp .kilo/skills/web-testing/SKILL.md /path/to/your/project/.kilo/skills/web-testing/
cp .kilo/skills/visual-testing/SKILL.md /path/to/your/project/.kilo/skills/visual-testing/
# 3. Copy scripts if you want the contrast extractor
cp tests/scripts/extract-contrast.js /path/to/your/project/tests/scripts/
# 4. Commit in YOUR project
cd /path/to/your/project
git add .kilo/skills/landing-design-interpretation .kilo/rules/landing-visual-debugging.md .kilo/agents/frontend-developer.md
git commit -m "chore: sync .kilo/ from APAW — landing visual debugging pipeline"
```
### Option 2: Submodule (Future / CI-friendly)
If your project uses Git submodules, you can link APAW as `.kilo/` source. However, this requires CI to copy files at build time because agents read from the local filesystem, not from submodule path directly.
### Option 3: Release Manager Sync (Automated)
In the release pipeline (`.kilo/rules/branch-strategy.md` § Release Process):
```bash
# Step 6 of release: sync .kilo/ to target projects
# This is done BY THE RELEASE MANAGER agent when creating a release from dev → main
git -C /path/to/your/project pull origin dev --ff-only
rsync -av --exclude='*.tmp' /home/swp/Projects/APAW/.kilo/ /path/to/your/project/.kilo/
```
## What Changed (2026-05-22)
### New Files (MUST be copied to project)
- `.kilo/skills/landing-design-interpretation/SKILL.md` — translation dictionary + contrast protocol
- `.kilo/rules/landing-visual-debugging.md` — mandatory 3-phase pipeline
- `tests/scripts/extract-contrast.js` — Playwright-based contrast extraction script
### Updated Files (SHOULD be copied to project)
- `.kilo/agents/frontend-developer.md` — added mandatory measurement-first protocol for landing tasks
- `.kilo/agents/orchestrator.md` — no changes needed for this evolution
### Sync Script
Save this as `scripts/sync-from-apaw.sh` in your project:
```bash
#!/usr/bin/env bash
set -euo pipefail
APAW_DIR="${APAW_DIR:-/home/swp/Projects/APAW}"
TARGET_DIR="${TARGET_DIR:-$(pwd)}"
echo "=== Syncing .kilo/ from APAW ==="
echo "Source: $APAW_DIR"
echo "Target: $TARGET_DIR"
# New skill
if [ -d "$APAW_DIR/.kilo/skills/landing-design-interpretation" ]; then
mkdir -p "$TARGET_DIR/.kilo/skills"
rsync -av "$APAW_DIR/.kilo/skills/landing-design-interpretation/" "$TARGET_DIR/.kilo/skills/landing-design-interpretation/"
echo "✅ landing-design-interpretation skill synced"
fi
# New rule
if [ -f "$APAW_DIR/.kilo/rules/landing-visual-debugging.md" ]; then
cp "$APAW_DIR/.kilo/rules/landing-visual-debugging.md" "$TARGET_DIR/.kilo/rules/"
echo "✅ landing-visual-debugging rule synced"
fi
# Updated agent
if [ -f "$APAW_DIR/.kilo/agents/frontend-developer.md" ]; then
cp "$APAW_DIR/.kilo/agents/frontend-developer.md" "$TARGET_DIR/.kilo/agents/"
echo "✅ frontend-developer agent synced"
fi
# Script
if [ -f "$APAW_DIR/tests/scripts/extract-contrast.js" ]; then
mkdir -p "$TARGET_DIR/tests/scripts"
cp "$APAW_DIR/tests/scripts/extract-contrast.js" "$TARGET_DIR/tests/scripts/"
echo "✅ extract-contrast.js synced"
fi
echo "=== Sync complete ==="
```
## Usage After Sync
### 1. Landing Visual Task Comes In
User says: "Исправь цветовую схему лендинга, текст сливается с фоном"
### 2. Orchestrator Routes to frontend-developer
Agent prompt MUST include:
```
Task: Fix landing page contrast issue
Context:
- Follow .kilo/rules/landing-visual-debugging.md (MANDATORY)
- Load skill .kilo/skills/landing-design-interpretation/SKILL.md on entry
- Use measurement-first protocol — never change colors without running extract-contrast.js
- URL: http://localhost:8080 (or project landing URL)
```
### 3. Agent Executes Pipeline
1. **Reads landing-design-interpretation skill** → translates "сливается" → `contrast ratio < 4.5`
2. **Runs measurement**:
```bash
docker compose -f docker/docker-compose.web-testing.yml run --rm browser-automation \
node tests/scripts/extract-contrast.js http://localhost:8080 --threshold 4.5 --output contrast-report.json
```
3. **Reads report** → gets exact selectors + current colors + ratios
4. **Applies minimal CSS fixes** → changes only the specific hex values
5. **Re-runs measurement** → confirms all ratios >= 4.5
6. **Takes screenshot** → verifies no regressions
### 4. Expected Output
```markdown
## Frontend Developer: Contrast Fix Complete
### Measurement
- Tool: extract-contrast.js (Playwright)
- URL: http://localhost:8080
- Threshold: 4.5:1
- Violations found: 3
### Fixes Applied
1. `.hero p` — color: #888 → #555 (ratio: 2.8 → 5.1)
2. `.card-body` — color: #666 → #444 (ratio: 3.2 → 4.8)
3. `.cta-subtitle` — color: #999 → #555 (ratio: 2.1 → 5.1)
### Verification
- [x] Re-run extract-contrast.js — all ratios >= 4.5
- [x] Screenshot comparison — no regressions
- [x] Hover states maintain contrast
```
## Common Mistakes
### ❌ Wrong: Agent works without reading the skill
```
# Bad prompt — no skill reference
"Fix the landing page colors"
# Result: agent guesses, 7 iterations, no result
```
### ✅ Right: Skill is loaded into agent context
```
# Good prompt — skill loaded
"Fix landing page colors. Load .kilo/skills/landing-design-interpretation/SKILL.md on entry. Follow Phase 1→2→3 protocol."
# Result: 1 iteration with measurement + verification
```
### ❌ Wrong: Project has outdated frontend-developer.md
```
# Old agent ignores measurement protocol
# Result: agent changes colors based on visual intuition
```
### ✅ Right: frontend-developer.md synced from APAW
```
# Updated agent has mandatory Landing Visual Protocol in behavior guidelines
# Result: agent automatically follows measure-first approach
```
## One-Line Summary
> **Agents read `.kilo/` from disk, not from Gitea. Copy new files from APAW to your project before using them.**

View File

@@ -1,7 +1,7 @@
{
"$schema": "https://app.kilo.ai/config.json",
"metaVersion": "1.0.0",
"lastSync": "2026-04-27T11:07:02.592Z",
"lastSync": "2026-05-21T11:08:50.773Z",
"agents": {
"requirement-refiner": {
"file": ".kilo/agents/requirement-refiner.md",
@@ -43,7 +43,7 @@
},
"frontend-developer": {
"file": ".kilo/agents/frontend-developer.md",
"description": "Handles UI implementation with multimodal capabilities. Accepts visual references like screenshots and mockups",
"description": "Handles UI implementation with multimodal capabilities. Accepts visual references like screenshots and mockups. Follows landing-design-interpretation skill for visual/contrast/color tasks on landing pages (MANDATORY measurement-first protocol)",
"model": "ollama-cloud/minimax-m2.5",
"mode": "all",
"color": "#0EA5E9",

View File

@@ -0,0 +1,177 @@
const { chromium } = require('playwright');
const fs = require('fs');
/**
* Extract contrast ratios for all visible text elements on a page.
* Writes JSON report with violations where contrast < threshold.
*
* Usage:
* node extract-contrast.js https://example.com [--threshold 4.5] [--output contrast-report.json]
*/
function luminance(r, g, b) {
const a = [r, g, b].map(v => {
v /= 255;
return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
});
return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
}
function hexToRgb(hex) {
const m = hex.replace('#', '').match(/^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);
if (!m) return null;
return { r: parseInt(m[1], 16), g: parseInt(m[2], 16), b: parseInt(m[3], 16) };
}
function parseRgb(rgb) {
const m = rgb.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+)\s*)?\)/);
if (!m) return null;
return { r: +m[1], g: +m[2], b: +m[3], a: m[4] !== undefined ? parseFloat(m[4]) : 1 };
}
function colorToRgb(str) {
if (!str || str === 'transparent' || str === 'rgba(0, 0, 0, 0)') return null;
if (str.startsWith('#')) return hexToRgb(str);
return parseRgb(str);
}
function contrastRatio(c1, c2) {
if (!c1 || !c2) return null;
const l1 = luminance(c1.r, c1.g, c1.b) + 0.05;
const l2 = luminance(c2.r, c2.g, c2.b) + 0.05;
return l1 > l2 ? l1 / l2 : l2 / l1;
}
function getEffectiveBackground(el) {
while (el && el !== document.documentElement) {
const style = window.getComputedStyle(el);
const bg = style.backgroundColor;
if (bg && bg !== 'rgba(0, 0, 0, 0)' && bg !== 'transparent') {
return bg;
}
el = el.parentElement;
}
return 'rgb(255, 255, 255)';
}
async function extractContrast(url, threshold = 4.5) {
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
await page.goto(url, { waitUntil: 'networkidle' });
const issues = await page.evaluate(({ threshold }) => {
function luminance(r, g, b) {
const a = [r, g, b].map(v => {
v /= 255;
return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
});
return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
}
function parseColor(str) {
if (!str || str === 'transparent') return null;
if (str.startsWith('#')) {
const m = str.replace('#', '').match(/^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);
return m ? { r: parseInt(m[1], 16), g: parseInt(m[2], 16), b: parseInt(m[3], 16) } : null;
}
const m = str.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+)\s*)?\)/);
return m ? { r: +m[1], g: +m[2], b: +m[3] } : null;
}
function contrast(c1, c2) {
if (!c1 || !c2) return 0;
const l1 = luminance(c1.r, c1.g, c1.b) + 0.05;
const l2 = luminance(c2.r, c2.g, c2.b) + 0.05;
return l1 > l2 ? l1 / l2 : l2 / l1;
}
const results = [];
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
let node;
const seen = new Set();
while ((node = walker.nextNode())) {
const el = node.parentElement;
if (!el || !el.getBoundingClientRect) continue;
const rect = el.getBoundingClientRect();
if (rect.width === 0 || rect.height === 0) continue;
const text = node.textContent.trim();
if (!text || text.length < 2) continue;
let bg = window.getComputedStyle(el).backgroundColor;
if (!bg || bg === 'rgba(0, 0, 0, 0)' || bg === 'transparent') {
let p = el.parentElement;
while (p) {
const s = window.getComputedStyle(p);
if (s.backgroundColor && s.backgroundColor !== 'rgba(0, 0, 0, 0)' && s.backgroundColor !== 'transparent') {
bg = s.backgroundColor;
break;
}
p = p.parentElement;
}
if (!bg) bg = 'rgb(255, 255, 255)';
}
const style = window.getComputedStyle(el);
const color = style.color;
const colorRgb = parseColor(color);
const bgRgb = parseColor(bg);
const ratio = contrast(colorRgb, bgRgb);
if (ratio < threshold) {
const key = el.tagName + (el.className ? '.' + el.className.split(/\s+/).join('.') : '') + '::' + color + '::' + bg;
if (seen.has(key)) continue;
seen.add(key);
results.push({
tagName: el.tagName,
className: el.className || '',
id: el.id || '',
selector: el.tagName.toLowerCase() + (el.id ? '#' + el.id : '') + (el.className ? '.' + el.className.split(/\s+/).join('.') : ''),
color,
backgroundColor: bg,
ratio: Math.round(ratio * 100) / 100,
textLength: text.length,
textPreview: text.slice(0, 80).replace(/\s+/g, ' '),
fontSize: style.fontSize,
fontWeight: style.fontWeight,
isInvisible: ratio <= 1.2,
});
}
}
return results;
}, { threshold });
await browser.close();
const report = {
url,
threshold,
totalViolations: issues.length,
invisibleCount: issues.filter(i => i.isInvisible).length,
issues: issues.sort((a, b) => a.ratio - b.ratio),
};
return report;
}
async function main() {
const url = process.argv[2];
if (!url) {
console.error('Usage: node extract-contrast.js <url> [--threshold 4.5] [--output report.json]');
process.exit(1);
}
const threshold = (process.argv.indexOf('--threshold') >= 0 ? parseFloat(process.argv[process.argv.indexOf('--threshold') + 1]) : null) || 4.5;
const outputIdx = process.argv.indexOf('--output');
const output = outputIdx >= 0 ? process.argv[outputIdx + 1] : null;
const report = await extractContrast(url, threshold);
const json = JSON.stringify(report, null, 2);
if (output) {
fs.writeFileSync(output, json);
console.log(`Report written to ${output}`);
} else {
console.log(json);
}
}
main().catch(e => {
console.error(e);
process.exit(1);
});