pixelcrew 0.2.2 → 0.2.6
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/README.md +389 -315
- package/bin/pixel-agents.js +306 -149
- package/package.json +3 -1
- package/skill/SKILL.md +185 -0
- package/skill/references/anti-ai-rubric.md +30 -0
- package/skill/references/anti-ai-slop-encyclopedia.md +181 -0
- package/skill/references/commands-reference.md +135 -0
- package/skill/references/testing-and-qa-strategy.md +25 -0
- package/skill/references/token-efficiency.md +20 -0
- package/src/adapters/adapter.interface.js +77 -0
- package/src/adapters/antigravity.js +138 -0
- package/src/adapters/claude-code.js +149 -0
- package/src/adapters/codex.js +131 -0
- package/src/adapters/cursor.js +133 -0
- package/src/adapters/generic.js +63 -0
- package/src/adapters/index.js +15 -0
- package/src/adapters/kiro.js +134 -0
- package/src/adapters/registry.js +150 -0
- package/src/backend/analyzer/complexity-analyzer.js +104 -0
- package/src/backend/analyzer/requirement-analyzer.js +213 -0
- package/src/backend/analyzer/threat-analyzer.js +122 -0
- package/src/backend/api/api-designer.js +90 -0
- package/src/backend/api/error-contract.js +132 -0
- package/src/backend/api/route-generator.js +92 -0
- package/src/backend/api/schema-generator.js +64 -0
- package/src/backend/architecture/adr-generator.js +62 -0
- package/src/backend/architecture/architecture-reasoner.js +119 -0
- package/src/backend/architecture/architecture-selector.js +57 -0
- package/src/backend/architecture/tradeoff-analyzer.js +92 -0
- package/src/backend/data/data-modeler.js +114 -0
- package/src/backend/data/index-analyzer.js +93 -0
- package/src/backend/data/query-analyzer.js +41 -0
- package/src/backend/data/schema-generator.js +92 -0
- package/src/backend/data/transaction-analyzer.js +49 -0
- package/src/backend/index.js +67 -0
- package/src/backend/observability/logging-engine.js +80 -0
- package/src/backend/observability/metrics-engine.js +31 -0
- package/src/backend/observability/tracing-engine.js +16 -0
- package/src/backend/patterns/pattern-registry.js +74 -0
- package/src/backend/patterns/pattern-selector.js +39 -0
- package/src/backend/patterns/tradeoff-engine.js +17 -0
- package/src/backend/performance/cache-analyzer.js +31 -0
- package/src/backend/performance/concurrency-analyzer.js +34 -0
- package/src/backend/performance/performance-engine.js +98 -0
- package/src/backend/performance/query-optimizer.js +16 -0
- package/src/backend/reliability/failure-analyzer.js +22 -0
- package/src/backend/reliability/idempotency-engine.js +56 -0
- package/src/backend/reliability/resilience-engine.js +141 -0
- package/src/backend/reliability/retry-analyzer.js +15 -0
- package/src/backend/security/auth-selector.js +33 -0
- package/src/backend/security/authorization-engine.js +90 -0
- package/src/backend/security/policy-engine.js +49 -0
- package/src/backend/security/secret-analyzer.js +39 -0
- package/src/backend/security/security-engine.js +122 -0
- package/src/backend/security/threat-model.js +59 -0
- package/src/backend/synthesis/backend-synthesizer.js +98 -0
- package/src/backend/synthesis/infrastructure-synthesizer.js +108 -0
- package/src/backend/synthesis/module-synthesizer.js +262 -0
- package/src/backend/validation/architecture-validator.js +70 -0
- package/src/backend/validation/backend-quality-validator.js +71 -0
- package/src/backend/validation/dependency-validator.js +20 -0
- package/src/backend/validation/performance-validator.js +38 -0
- package/src/backend/validation/security-validator.js +73 -0
- package/src/commands/adapt.js +105 -0
- package/src/commands/add.js +78 -0
- package/src/commands/animate.js +48 -0
- package/src/commands/assemble.js +57 -0
- package/src/commands/audit.js +93 -0
- package/src/commands/backend.js +125 -0
- package/src/commands/bento.js +25 -0
- package/src/commands/blueprint.js +65 -0
- package/src/commands/bolder.js +48 -0
- package/src/commands/boss-fight.js +60 -0
- package/src/commands/build.js +39 -0
- package/src/commands/calibrate.js +25 -0
- package/src/commands/chromatic.js +25 -0
- package/src/commands/clarify.js +52 -0
- package/src/commands/colorize.js +57 -0
- package/src/commands/command.interface.js +28 -0
- package/src/commands/commands.js +84 -0
- package/src/commands/craft.js +57 -0
- package/src/commands/crew.js +66 -0
- package/src/commands/critique.js +25 -0
- package/src/commands/de-slop.js +25 -0
- package/src/commands/delight.js +46 -0
- package/src/commands/deploy.js +42 -0
- package/src/commands/distill.js +48 -0
- package/src/commands/doctor.js +89 -0
- package/src/commands/document.js +83 -0
- package/src/commands/eight-bit.js +25 -0
- package/src/commands/extract.js +75 -0
- package/src/commands/fix.js +46 -0
- package/src/commands/harden.js +85 -0
- package/src/commands/index.js +67 -0
- package/src/commands/install.js +75 -0
- package/src/commands/layout.js +48 -0
- package/src/commands/live.js +44 -0
- package/src/commands/manifest.js +25 -0
- package/src/commands/office.js +25 -0
- package/src/commands/onboard.js +46 -0
- package/src/commands/oneshot.js +60 -0
- package/src/commands/optimize.js +46 -0
- package/src/commands/overdrive.js +46 -0
- package/src/commands/parser.js +143 -0
- package/src/commands/pixelcrew.js +96 -0
- package/src/commands/plan.js +66 -0
- package/src/commands/polish.js +45 -0
- package/src/commands/quieter.js +48 -0
- package/src/commands/recap.js +358 -0
- package/src/commands/registry.js +353 -0
- package/src/commands/render.js +26 -0
- package/src/commands/retrofit.js +25 -0
- package/src/commands/review.js +118 -0
- package/src/commands/roster.js +25 -0
- package/src/commands/sentinel.js +25 -0
- package/src/commands/shape.js +66 -0
- package/src/commands/skills.js +57 -0
- package/src/commands/status.js +48 -0
- package/src/commands/stop.js +50 -0
- package/src/commands/sync.js +58 -0
- package/src/commands/typeset.js +58 -0
- package/src/commands/warp.js +25 -0
- package/src/core/agent-runtime.js +94 -0
- package/src/core/event-bus.js +98 -0
- package/src/core/index.js +9 -0
- package/src/core/orchestrator.js +234 -0
- package/src/core/scheduler.js +124 -0
- package/src/core/task-graph.js +185 -0
- package/src/dashboard/app.js +1172 -30
- package/src/dashboard/index.html +223 -23
- package/src/dashboard/styles.css +870 -0
- package/src/index.js +16 -0
- package/src/orchestrator/artifact-graph.js +104 -0
- package/src/orchestrator/ast-normalizer.js +147 -0
- package/src/orchestrator/code-generator.js +846 -0
- package/src/orchestrator/design-engine.js +203 -0
- package/src/orchestrator/engine.js +318 -39
- package/src/orchestrator/oneshot.js +351 -1561
- package/src/orchestrator/ontology.js +394 -0
- package/src/orchestrator/planner.js +302 -0
- package/src/orchestrator/repair-planner.js +67 -0
- package/src/orchestrator/requirement-contract.js +177 -0
- package/src/orchestrator/requirement-validator.js +39 -0
- package/src/orchestrator/semantic-engine.js +582 -0
- package/src/orchestrator/semantic-reviewer.js +179 -0
- package/src/orchestrator/skills-registry.js +194 -0
- package/src/orchestrator/task-planner.js +111 -0
- package/src/orchestrator/task-queue.js +128 -0
- package/src/orchestrator/telemetry.js +209 -0
- package/src/orchestrator/ui-synthesizer.js +245 -0
- package/src/orchestrator/visual-critic.js +106 -0
- package/src/policies/architecture/layering.policy.js +14 -0
- package/src/policies/performance/indexing.policy.js +13 -0
- package/src/policies/reliability/resilience.policy.js +13 -0
- package/src/policies/security/auth.policy.js +31 -0
- package/src/protocol/agent.js +124 -0
- package/src/protocol/event.js +78 -0
- package/src/protocol/index.js +8 -0
- package/src/protocol/skill.js +54 -0
- package/src/protocol/task.js +100 -0
- package/src/scaffold/claude-generator.js +60 -0
- package/src/scaffold/commands-catalog.js +321 -0
- package/src/scaffold/cursor-generator.js +74 -0
- package/src/scaffold/ide-rules.js +133 -0
- package/src/scaffold/init.js +415 -91
- package/src/scaffold/installer.js +571 -0
- package/src/scaffold/kiro-generator.js +86 -0
- package/src/scaffold/skills-bundle.js +520 -0
- package/src/scaffold/templates.js +57 -4
- package/src/scaffold/workstations.js +364 -0
- package/src/server/server.js +292 -42
- package/src/utils/fs-safe.js +168 -0
- package/src/utils/markdown-report.js +175 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Semantic Reviewer
|
|
3
|
+
*
|
|
4
|
+
* Performs deterministic structural and semantic coherence audits on Project ASTs:
|
|
5
|
+
* - Missing / orphaned entities
|
|
6
|
+
* - Invalid entity relationships
|
|
7
|
+
* - Workflows lacking UI views or backend operations
|
|
8
|
+
* - Critical requirements lacking verifiable acceptance criteria
|
|
9
|
+
* - Automatically synthesizes missing links to guarantee 100% coherence.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { UniversalSoftwareOntology, OPERATION_METHODS, LAYOUT_PRIMITIVES, REQUIREMENT_CATEGORIES } from './ontology.js';
|
|
13
|
+
|
|
14
|
+
export class SemanticReviewer {
|
|
15
|
+
/**
|
|
16
|
+
* Audit and repair an AST for semantic completeness.
|
|
17
|
+
*/
|
|
18
|
+
static reviewAndRepair(ast) {
|
|
19
|
+
if (!ast || typeof ast !== 'object') {
|
|
20
|
+
throw new Error('SemanticReviewer: ast must be a valid object.');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const issues = [];
|
|
24
|
+
const suggestions = [];
|
|
25
|
+
const repaired = JSON.parse(JSON.stringify(ast));
|
|
26
|
+
|
|
27
|
+
const entityNames = new Set((repaired.entities || []).map(e => e.name));
|
|
28
|
+
|
|
29
|
+
// 1. Audit Entities & Seed Data
|
|
30
|
+
if (!repaired.entities || repaired.entities.length === 0) {
|
|
31
|
+
issues.push({ code: 'EMPTY_ENTITIES', severity: 'error', message: 'AST contains zero domain entities.' });
|
|
32
|
+
repaired.entities = [UniversalSoftwareOntology.validateEntity({ name: 'SystemRecord' })];
|
|
33
|
+
entityNames.add('SystemRecord');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
repaired.entities.forEach(entity => {
|
|
37
|
+
// Ensure seed data exists
|
|
38
|
+
if (!entity.seedData || entity.seedData.length === 0) {
|
|
39
|
+
entity.seedData = this.synthesizeSeedData(entity);
|
|
40
|
+
suggestions.push({ type: 'SYNTHESIZED_SEED_DATA', entity: entity.name });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Check relationships
|
|
44
|
+
if (Array.isArray(entity.relationships)) {
|
|
45
|
+
entity.relationships.forEach(rel => {
|
|
46
|
+
if (!entityNames.has(rel.targetEntity)) {
|
|
47
|
+
issues.push({
|
|
48
|
+
code: 'ORPHANED_RELATIONSHIP',
|
|
49
|
+
severity: 'warning',
|
|
50
|
+
message: `Entity '${entity.name}' references non-existent target '${rel.targetEntity}'.`
|
|
51
|
+
});
|
|
52
|
+
// Re-target to available entity
|
|
53
|
+
rel.targetEntity = Array.from(entityNames)[0];
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// 2. Audit Views (Ensure every primary entity has an interactive view)
|
|
60
|
+
if (!repaired.views || repaired.views.length === 0) {
|
|
61
|
+
issues.push({ code: 'NO_VIEWS', severity: 'error', message: 'AST has no UI views defined.' });
|
|
62
|
+
repaired.views = [];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const coveredEntitiesInViews = new Set();
|
|
66
|
+
repaired.views.forEach(v => {
|
|
67
|
+
(v.targetEntities || []).forEach(te => coveredEntitiesInViews.add(te));
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
repaired.entities.forEach((entity, idx) => {
|
|
71
|
+
if (!coveredEntitiesInViews.has(entity.name)) {
|
|
72
|
+
// Synthesize an interactive view for uncovered entity
|
|
73
|
+
const newView = {
|
|
74
|
+
id: `view-${entity.name.toLowerCase()}-management`,
|
|
75
|
+
componentName: `${entity.name}Explorer`,
|
|
76
|
+
title: `${entity.title || entity.name} Explorer`,
|
|
77
|
+
purpose: `Browse, inspect and manage ${entity.plural || entity.name} records`,
|
|
78
|
+
targetEntities: [entity.name],
|
|
79
|
+
layout: { type: idx === 0 ? LAYOUT_PRIMITIVES.SPLIT : LAYOUT_PRIMITIVES.GRID, density: 'comfortable' },
|
|
80
|
+
regions: [
|
|
81
|
+
{ role: 'navigation', components: ['search', 'filter'] },
|
|
82
|
+
{ role: 'content', components: ['collection', 'table'] },
|
|
83
|
+
{ role: 'inspector', components: ['inspector', 'form'] }
|
|
84
|
+
],
|
|
85
|
+
capabilities: ['search', 'filter', 'view', 'create', 'edit', 'delete']
|
|
86
|
+
};
|
|
87
|
+
repaired.views.push(UniversalSoftwareOntology.validateView(newView, repaired.entities));
|
|
88
|
+
suggestions.push({ type: 'SYNTHESIZED_VIEW', entity: entity.name, view: newView.componentName });
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// 3. Audit Operations (Ensure backend REST operations exist for all entities)
|
|
93
|
+
if (!repaired.operations || repaired.operations.length === 0) {
|
|
94
|
+
repaired.operations = [];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const operatedEntities = new Set(repaired.operations.map(o => o.targetEntity));
|
|
98
|
+
repaired.entities.forEach(entity => {
|
|
99
|
+
if (!operatedEntities.has(entity.name)) {
|
|
100
|
+
// Add GET and POST operations
|
|
101
|
+
repaired.operations.push(UniversalSoftwareOntology.validateOperation({
|
|
102
|
+
id: `op-get-${entity.name.toLowerCase()}s`,
|
|
103
|
+
path: `/api/${entity.name.toLowerCase()}s`,
|
|
104
|
+
method: OPERATION_METHODS.GET,
|
|
105
|
+
description: `Retrieve all ${entity.plural || entity.name} records`,
|
|
106
|
+
targetEntity: entity.name
|
|
107
|
+
}, repaired.entities));
|
|
108
|
+
|
|
109
|
+
repaired.operations.push(UniversalSoftwareOntology.validateOperation({
|
|
110
|
+
id: `op-post-${entity.name.toLowerCase()}`,
|
|
111
|
+
path: `/api/${entity.name.toLowerCase()}s`,
|
|
112
|
+
method: OPERATION_METHODS.POST,
|
|
113
|
+
description: `Create a new ${entity.name} record`,
|
|
114
|
+
targetEntity: entity.name,
|
|
115
|
+
requestFields: entity.fields.map(f => f.name)
|
|
116
|
+
}, repaired.entities));
|
|
117
|
+
|
|
118
|
+
suggestions.push({ type: 'SYNTHESIZED_OPERATIONS', entity: entity.name });
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// 4. Audit Requirements & Acceptance Criteria
|
|
123
|
+
if (!repaired.requirements || repaired.requirements.length === 0) {
|
|
124
|
+
repaired.requirements = [];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Ensure at least 1 requirement per View and 1 per Operation
|
|
128
|
+
repaired.views.forEach((v, idx) => {
|
|
129
|
+
const hasReq = repaired.requirements.some(r => r.target === v.componentName || r.description.includes(v.componentName));
|
|
130
|
+
if (!hasReq) {
|
|
131
|
+
repaired.requirements.push({
|
|
132
|
+
id: `REQ-${String(repaired.requirements.length + 1).padStart(3, '0')}`,
|
|
133
|
+
category: REQUIREMENT_CATEGORIES.UI_COMPONENT,
|
|
134
|
+
target: v.componentName,
|
|
135
|
+
description: `Synthesize interactive ${v.title} component with search, filter, and inspector capabilities.`,
|
|
136
|
+
acceptanceCriteria: [
|
|
137
|
+
`${v.componentName} renders without runtime errors`,
|
|
138
|
+
`Displays active ${v.targetEntities.join(', ')} records`,
|
|
139
|
+
`Supports interactive filtering and state updates`
|
|
140
|
+
],
|
|
141
|
+
priority: idx === 0 ? 'critical' : 'high'
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
isValid: issues.filter(i => i.severity === 'error').length === 0,
|
|
148
|
+
issues,
|
|
149
|
+
suggestions,
|
|
150
|
+
ast: repaired
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Synthesize realistic domain seed data for an entity
|
|
156
|
+
*/
|
|
157
|
+
static synthesizeSeedData(entity) {
|
|
158
|
+
const records = [];
|
|
159
|
+
const count = 4;
|
|
160
|
+
for (let i = 1; i <= count; i++) {
|
|
161
|
+
const rec = {};
|
|
162
|
+
entity.fields.forEach(f => {
|
|
163
|
+
if (f.name === 'id') {
|
|
164
|
+
rec.id = `${entity.id || entity.name.toLowerCase()}-${String(i).padStart(3, '0')}`;
|
|
165
|
+
} else if (f.type === 'number') {
|
|
166
|
+
rec[f.name] = (i * 12.5) + (f.name.includes('depth') ? 45 : (f.name.includes('count') ? 8 : 100));
|
|
167
|
+
} else if (f.type === 'boolean') {
|
|
168
|
+
rec[f.name] = i % 2 === 0;
|
|
169
|
+
} else if (f.type === 'datetime') {
|
|
170
|
+
rec[f.name] = new Date(Date.now() - (i * 86400000)).toISOString();
|
|
171
|
+
} else {
|
|
172
|
+
rec[f.name] = `${entity.name} ${f.label || f.name} ${i}`;
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
records.push(rec);
|
|
176
|
+
}
|
|
177
|
+
return records;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Modular Skill Registry
|
|
3
|
+
*
|
|
4
|
+
* Reusable capability definitions across Frontend, Design, Motion, Quality, Backend, and Content.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export const SKILL_DEFINITIONS = {
|
|
8
|
+
// Frontend Skills
|
|
9
|
+
'frontend/nextjs': {
|
|
10
|
+
id: 'frontend/nextjs',
|
|
11
|
+
name: 'Next.js 14/15 App Router',
|
|
12
|
+
category: 'frontend',
|
|
13
|
+
description: 'Server Components, Streaming SSR, Layout hierarchy, and Metadata APIs',
|
|
14
|
+
targetAgents: ['frontend']
|
|
15
|
+
},
|
|
16
|
+
'frontend/react': {
|
|
17
|
+
id: 'frontend/react',
|
|
18
|
+
name: 'React 18/19 Primitives',
|
|
19
|
+
category: 'frontend',
|
|
20
|
+
description: 'Custom React hooks, client-side state management, and component islands',
|
|
21
|
+
targetAgents: ['frontend']
|
|
22
|
+
},
|
|
23
|
+
'frontend/tailwind': {
|
|
24
|
+
id: 'frontend/tailwind',
|
|
25
|
+
name: 'Tailwind CSS & Token System',
|
|
26
|
+
category: 'frontend',
|
|
27
|
+
description: 'Utility-first styling, design token mapping, fluid clamp scales, and dark mode',
|
|
28
|
+
targetAgents: ['frontend', 'designSystem']
|
|
29
|
+
},
|
|
30
|
+
'frontend/accessibility': {
|
|
31
|
+
id: 'frontend/accessibility',
|
|
32
|
+
name: 'WCAG 2.1 AA/AAA Accessibility',
|
|
33
|
+
category: 'frontend',
|
|
34
|
+
description: 'ARIA landmarks, keyboard focus management, and color contrast compliance',
|
|
35
|
+
targetAgents: ['frontend', 'qa']
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
// Design Skills
|
|
39
|
+
'design/ui-design': {
|
|
40
|
+
id: 'design/ui-design',
|
|
41
|
+
name: 'Bespoke UI & Asymmetric Layouts',
|
|
42
|
+
category: 'design',
|
|
43
|
+
description: 'High-contrast visual hierarchy, intentional whitespace, and Bento grid topologies',
|
|
44
|
+
targetAgents: ['creativeDirector', 'uxPlanner']
|
|
45
|
+
},
|
|
46
|
+
'design/typography': {
|
|
47
|
+
id: 'design/typography',
|
|
48
|
+
name: 'Expressive Typography Scales',
|
|
49
|
+
category: 'design',
|
|
50
|
+
description: 'Mathematical fluid clamp() type scales, display serif and geometric sans pairings',
|
|
51
|
+
targetAgents: ['creativeDirector', 'designSystem']
|
|
52
|
+
},
|
|
53
|
+
'design/design-system': {
|
|
54
|
+
id: 'design/design-system',
|
|
55
|
+
name: 'Design System Architecture',
|
|
56
|
+
category: 'design',
|
|
57
|
+
description: 'CSS Custom Properties, HSL color tokens, surface elevation tiers, and borders',
|
|
58
|
+
targetAgents: ['designSystem']
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
// Motion & Animation Skills
|
|
62
|
+
'motion/framer-motion': {
|
|
63
|
+
id: 'motion/framer-motion',
|
|
64
|
+
name: 'Framer Motion & View Transitions',
|
|
65
|
+
category: 'motion',
|
|
66
|
+
description: 'Smooth scroll-driven reveals, staggered entrance choreography, and gesture physics',
|
|
67
|
+
targetAgents: ['animationSpecialist', 'frontend']
|
|
68
|
+
},
|
|
69
|
+
'motion/micro-interactions': {
|
|
70
|
+
id: 'motion/micro-interactions',
|
|
71
|
+
name: 'Interactive Micro-Interactions',
|
|
72
|
+
category: 'motion',
|
|
73
|
+
description: 'Hover states, magnetic buttons, live filter transitions, and interactive terminal state',
|
|
74
|
+
targetAgents: ['animationSpecialist', 'frontend']
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
// Quality & Review Skills
|
|
78
|
+
'quality/responsive-design': {
|
|
79
|
+
id: 'quality/responsive-design',
|
|
80
|
+
name: 'Adaptive Responsive Design',
|
|
81
|
+
category: 'quality',
|
|
82
|
+
description: 'Fluid viewports from 360px mobile to 4K desktop with zero horizontal overflow',
|
|
83
|
+
targetAgents: ['responsiveSpecialist', 'frontend']
|
|
84
|
+
},
|
|
85
|
+
'quality/visual-review': {
|
|
86
|
+
id: 'quality/visual-review',
|
|
87
|
+
name: '6-Dimension Anti-AI Rubric Review',
|
|
88
|
+
category: 'quality',
|
|
89
|
+
description: 'Originality, Typography, Layout, Hierarchy, Brand Consistency, and AI Slop Penalty audit',
|
|
90
|
+
targetAgents: ['visualCritic', 'qa']
|
|
91
|
+
},
|
|
92
|
+
'quality/browser-testing': {
|
|
93
|
+
id: 'quality/browser-testing',
|
|
94
|
+
name: 'Build Verification & Smoke Testing',
|
|
95
|
+
category: 'quality',
|
|
96
|
+
description: 'Syntax validation, TypeScript type-checking, and layout integrity checks',
|
|
97
|
+
targetAgents: ['qa']
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
// Backend & Data Skills
|
|
101
|
+
'backend/route-handlers': {
|
|
102
|
+
id: 'backend/route-handlers',
|
|
103
|
+
name: 'TypeScript Route Handlers',
|
|
104
|
+
category: 'backend',
|
|
105
|
+
description: 'Next.js App Router API routes, JSON schema validation, and RFC 7807 error envelopes',
|
|
106
|
+
targetAgents: ['backend']
|
|
107
|
+
},
|
|
108
|
+
'backend/data-models': {
|
|
109
|
+
id: 'backend/data-models',
|
|
110
|
+
name: 'Structured Data Modeling',
|
|
111
|
+
category: 'backend',
|
|
112
|
+
description: 'Domain entities, TypeScript interfaces, and static fixtures',
|
|
113
|
+
targetAgents: ['backend', 'database']
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
// Content & Anti-AI Skills
|
|
117
|
+
'content/copywriting': {
|
|
118
|
+
id: 'content/copywriting',
|
|
119
|
+
name: 'Grounded Technical Copywriting',
|
|
120
|
+
category: 'content',
|
|
121
|
+
description: 'Zero AI cliché copy, authentic product propositions, and real technical metrics',
|
|
122
|
+
targetAgents: ['contentStrategist', 'uxPlanner']
|
|
123
|
+
},
|
|
124
|
+
'anti-ai/slop-guardian': {
|
|
125
|
+
id: 'anti-ai/slop-guardian',
|
|
126
|
+
name: 'Anti-AI Pattern Detection Guardian',
|
|
127
|
+
category: 'quality',
|
|
128
|
+
description: 'Bans purple/blue mesh gradient blobs, repeating 3-card grids, and fake AI sparkles',
|
|
129
|
+
targetAgents: ['creativeDirector', 'visualCritic']
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export class SkillRegistry {
|
|
134
|
+
constructor() {
|
|
135
|
+
this.skills = new Map(Object.entries(SKILL_DEFINITIONS));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
getSkill(skillId) {
|
|
139
|
+
return this.skills.get(skillId) || null;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
getAllSkills() {
|
|
143
|
+
return Array.from(this.skills.values());
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
getSkillsByCategory(category) {
|
|
147
|
+
return Array.from(this.skills.values()).filter(s => s.category === category);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Matches task requirements to skill IDs
|
|
152
|
+
*/
|
|
153
|
+
matchSkills(taskRequirement) {
|
|
154
|
+
const text = (taskRequirement || '').toLowerCase();
|
|
155
|
+
const matched = new Set();
|
|
156
|
+
|
|
157
|
+
if (text.includes('next') || text.includes('component') || text.includes('page')) {
|
|
158
|
+
matched.add('frontend/nextjs');
|
|
159
|
+
matched.add('frontend/react');
|
|
160
|
+
matched.add('frontend/tailwind');
|
|
161
|
+
}
|
|
162
|
+
if (text.includes('design') || text.includes('visual') || text.includes('artistic')) {
|
|
163
|
+
matched.add('design/ui-design');
|
|
164
|
+
matched.add('design/typography');
|
|
165
|
+
matched.add('design/design-system');
|
|
166
|
+
matched.add('anti-ai/slop-guardian');
|
|
167
|
+
}
|
|
168
|
+
if (text.includes('animation') || text.includes('motion') || text.includes('interaction')) {
|
|
169
|
+
matched.add('motion/framer-motion');
|
|
170
|
+
matched.add('motion/micro-interactions');
|
|
171
|
+
}
|
|
172
|
+
if (text.includes('responsive') || text.includes('mobile') || text.includes('tablet')) {
|
|
173
|
+
matched.add('quality/responsive-design');
|
|
174
|
+
}
|
|
175
|
+
if (text.includes('api') || text.includes('backend') || text.includes('route')) {
|
|
176
|
+
matched.add('backend/route-handlers');
|
|
177
|
+
matched.add('backend/data-models');
|
|
178
|
+
}
|
|
179
|
+
if (text.includes('qa') || text.includes('test') || text.includes('review') || text.includes('rubric')) {
|
|
180
|
+
matched.add('quality/visual-review');
|
|
181
|
+
matched.add('quality/browser-testing');
|
|
182
|
+
}
|
|
183
|
+
if (text.includes('copy') || text.includes('content') || text.includes('text')) {
|
|
184
|
+
matched.add('content/copywriting');
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (matched.size === 0) {
|
|
188
|
+
matched.add('frontend/nextjs');
|
|
189
|
+
matched.add('frontend/tailwind');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return Array.from(matched);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Dynamic Task Planner
|
|
3
|
+
*
|
|
4
|
+
* Compiles a Directed Acyclic Graph (DAG) of specialized agent tasks from
|
|
5
|
+
* Project AST, RequirementContract, and DesignSpec.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export class TaskPlanner {
|
|
9
|
+
/**
|
|
10
|
+
* Compile DAG task graph
|
|
11
|
+
*/
|
|
12
|
+
static planTaskGraph({ ast, requirementContract, designSpec }) {
|
|
13
|
+
const tasks = [];
|
|
14
|
+
const views = ast.views || [];
|
|
15
|
+
const operations = ast.operations || [];
|
|
16
|
+
const entities = ast.entities || [];
|
|
17
|
+
|
|
18
|
+
// Phase 1: Semantic Review & Design Direction
|
|
19
|
+
tasks.push({
|
|
20
|
+
id: 'task-semantic-review',
|
|
21
|
+
title: 'Review Project AST & Semantic Coherence',
|
|
22
|
+
role: 'orchestrator',
|
|
23
|
+
phase: 'analysis',
|
|
24
|
+
dependencies: [],
|
|
25
|
+
inputs: ['Project AST'],
|
|
26
|
+
outputs: ['Normalized AST', 'Requirement Contract']
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
tasks.push({
|
|
30
|
+
id: 'task-design-spec',
|
|
31
|
+
title: 'Synthesize Bespoke Visual Design Specification',
|
|
32
|
+
role: 'creativeDirector',
|
|
33
|
+
phase: 'design',
|
|
34
|
+
dependencies: ['task-semantic-review'],
|
|
35
|
+
inputs: ['Normalized AST'],
|
|
36
|
+
outputs: ['DesignSpec']
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Phase 2: Domain Modeling & Database Fixtures
|
|
40
|
+
tasks.push({
|
|
41
|
+
id: 'task-data-modeling',
|
|
42
|
+
title: `Synthesize TypeScript Models & Seed Data for ${entities.length} Entities`,
|
|
43
|
+
role: 'database',
|
|
44
|
+
phase: 'foundation',
|
|
45
|
+
dependencies: ['task-semantic-review'],
|
|
46
|
+
inputs: entities.map(e => e.name),
|
|
47
|
+
outputs: ['src/types/index.ts', 'src/lib/data.ts']
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Phase 3: Global Design Tokens & App Layout
|
|
51
|
+
tasks.push({
|
|
52
|
+
id: 'task-design-tokens',
|
|
53
|
+
title: 'Compile Tailwind Tokens & Global CSS',
|
|
54
|
+
role: 'designSystem',
|
|
55
|
+
phase: 'foundation',
|
|
56
|
+
dependencies: ['task-design-spec'],
|
|
57
|
+
inputs: ['DesignSpec'],
|
|
58
|
+
outputs: ['src/app/globals.css', 'tailwind.config.ts']
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Phase 4: Parallel View & Backend API Construction
|
|
62
|
+
views.forEach((v, idx) => {
|
|
63
|
+
tasks.push({
|
|
64
|
+
id: `task-view-${v.componentName.toLowerCase()}`,
|
|
65
|
+
title: `Implement ${v.componentName} (${v.title})`,
|
|
66
|
+
role: 'frontend',
|
|
67
|
+
phase: 'implementation',
|
|
68
|
+
dependencies: ['task-data-modeling', 'task-design-tokens'],
|
|
69
|
+
inputs: [v.componentName, ...v.targetEntities],
|
|
70
|
+
outputs: [`src/components/sections/${v.componentName}.tsx`]
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
tasks.push({
|
|
75
|
+
id: 'task-backend-routes',
|
|
76
|
+
title: `Synthesize ${operations.length} REST Route Handlers (RFC 7807)`,
|
|
77
|
+
role: 'backend',
|
|
78
|
+
phase: 'implementation',
|
|
79
|
+
dependencies: ['task-data-modeling'],
|
|
80
|
+
inputs: operations.map(o => o.path),
|
|
81
|
+
outputs: operations.map(o => `src/app${o.path}/route.ts`)
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Phase 5: Root Page Assembly
|
|
85
|
+
tasks.push({
|
|
86
|
+
id: 'task-page-assembly',
|
|
87
|
+
title: 'Assemble Dynamic Root Page & Navigation',
|
|
88
|
+
role: 'frontend',
|
|
89
|
+
phase: 'assembly',
|
|
90
|
+
dependencies: views.map(v => `task-view-${v.componentName.toLowerCase()}`),
|
|
91
|
+
inputs: views.map(v => v.componentName),
|
|
92
|
+
outputs: ['src/app/page.tsx', 'src/components/sections/PortalHeader.tsx']
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Phase 6: Requirement & Visual Quality Validation
|
|
96
|
+
tasks.push({
|
|
97
|
+
id: 'task-validation-gate',
|
|
98
|
+
title: 'Run Requirement Contract & Visual Critic Quality Gate',
|
|
99
|
+
role: 'qa',
|
|
100
|
+
phase: 'validation',
|
|
101
|
+
dependencies: ['task-page-assembly', 'task-backend-routes'],
|
|
102
|
+
inputs: ['RequirementContract', 'All Generated Files'],
|
|
103
|
+
outputs: ['QualityGateReport']
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
totalTasks: tasks.length,
|
|
108
|
+
tasks
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Autonomous Agent Runtime & DAG Task Queue
|
|
3
|
+
*
|
|
4
|
+
* Manages dynamic DAG task scheduling, parallel execution, and granular event streaming.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { EventEmitter } from 'node:events';
|
|
8
|
+
|
|
9
|
+
export class TaskQueue extends EventEmitter {
|
|
10
|
+
constructor(tasks = []) {
|
|
11
|
+
super();
|
|
12
|
+
this.tasks = new Map(tasks.map(t => [t.id, { ...t }]));
|
|
13
|
+
this.completedTasks = new Set();
|
|
14
|
+
this.runningTasks = new Set();
|
|
15
|
+
this.failedTasks = new Set();
|
|
16
|
+
this.history = [];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Retrieves all tasks currently ready for execution
|
|
21
|
+
* (all dependencies completed and task is currently queued)
|
|
22
|
+
*/
|
|
23
|
+
getReadyTasks() {
|
|
24
|
+
const ready = [];
|
|
25
|
+
for (const [id, task] of this.tasks.entries()) {
|
|
26
|
+
if (task.status === 'queued') {
|
|
27
|
+
const depsMet = task.dependsOn.every(depId => this.completedTasks.has(depId));
|
|
28
|
+
if (depsMet) {
|
|
29
|
+
ready.push(task);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return ready;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
isCompleted() {
|
|
37
|
+
return this.tasks.size === this.completedTasks.size;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
hasFailed() {
|
|
41
|
+
return this.failedTasks.size > 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Executes the entire DAG with autonomous agent dispatching
|
|
46
|
+
*/
|
|
47
|
+
async execute(runtimeContext = {}, onEvent = () => {}) {
|
|
48
|
+
const emit = (event) => {
|
|
49
|
+
this.history.push(event);
|
|
50
|
+
this.emit('event', event);
|
|
51
|
+
onEvent(event);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
while (!this.isCompleted() && !this.hasFailed()) {
|
|
55
|
+
const readyTasks = this.getReadyTasks();
|
|
56
|
+
|
|
57
|
+
if (readyTasks.length === 0 && this.runningTasks.size === 0) {
|
|
58
|
+
throw new Error('Deadlock detected in Task Graph: cyclic dependency or unmet prerequisite');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Execute all ready tasks in parallel batch
|
|
62
|
+
const promises = readyTasks.map(async (task) => {
|
|
63
|
+
task.status = 'running';
|
|
64
|
+
this.runningTasks.add(task.id);
|
|
65
|
+
|
|
66
|
+
emit({
|
|
67
|
+
type: 'agent.started',
|
|
68
|
+
agent: task.agentId,
|
|
69
|
+
taskId: task.id,
|
|
70
|
+
taskName: task.name,
|
|
71
|
+
message: `Workstation activated for: ${task.name}`
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Activate required skills
|
|
75
|
+
for (const skill of task.skills) {
|
|
76
|
+
emit({
|
|
77
|
+
type: 'skill.activated',
|
|
78
|
+
agent: task.agentId,
|
|
79
|
+
taskId: task.id,
|
|
80
|
+
skill,
|
|
81
|
+
message: `Applying skill: ${skill}`
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Execute actual agent task payload if handler exists
|
|
86
|
+
if (runtimeContext.executeTaskHandler) {
|
|
87
|
+
try {
|
|
88
|
+
await runtimeContext.executeTaskHandler(task, emit);
|
|
89
|
+
} catch (err) {
|
|
90
|
+
task.status = 'failed';
|
|
91
|
+
this.failedTasks.add(task.id);
|
|
92
|
+
this.runningTasks.delete(task.id);
|
|
93
|
+
emit({
|
|
94
|
+
type: 'task.failed',
|
|
95
|
+
agent: task.agentId,
|
|
96
|
+
taskId: task.id,
|
|
97
|
+
error: err.message
|
|
98
|
+
});
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
await new Promise(r => setTimeout(r, 400));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
task.status = 'completed';
|
|
106
|
+
this.runningTasks.delete(task.id);
|
|
107
|
+
this.completedTasks.add(task.id);
|
|
108
|
+
|
|
109
|
+
emit({
|
|
110
|
+
type: 'task.completed',
|
|
111
|
+
agent: task.agentId,
|
|
112
|
+
taskId: task.id,
|
|
113
|
+
taskName: task.name,
|
|
114
|
+
message: `Completed: ${task.name}`
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
await Promise.all(promises);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
success: !this.hasFailed(),
|
|
123
|
+
completedCount: this.completedTasks.size,
|
|
124
|
+
totalTasks: this.tasks.size,
|
|
125
|
+
history: this.history
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
}
|