pixelcrew 0.2.1 → 0.2.3

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.
@@ -0,0 +1,329 @@
1
+ /**
2
+ * PIXEL CREW — Dynamic Project Planner & Task Graph Engine
3
+ *
4
+ * Analyzes user prompts from first principles and creates:
5
+ * 1. Deep Project Specification (Domain, Components, Features, Data Models)
6
+ * 2. Dynamic Task Graph (DAG) with explicit dependency resolution
7
+ */
8
+
9
+ import { SkillRegistry } from './skills-registry.js';
10
+
11
+ export class DynamicPlanner {
12
+ constructor() {
13
+ this.skillRegistry = new SkillRegistry();
14
+ }
15
+
16
+ /**
17
+ * Step 1: Analyze Requirements from User Prompt
18
+ */
19
+ analyzeRequirements(prompt, options = {}) {
20
+ const p = (prompt || '').toLowerCase();
21
+
22
+ // 1. Target Framework & Stack
23
+ let framework = options.targetFramework || 'nextjs';
24
+ if (p.includes('react') && !p.includes('next')) framework = 'react';
25
+ else if (p.includes('vue')) framework = 'vue';
26
+ else if (p.includes('vanilla')) framework = 'vanilla';
27
+
28
+ // 2. Domain Classification
29
+ let domain = 'custom';
30
+ if (p.includes('portfolio') || p.includes('resume') || p.includes('showcase my project') || p.includes('developer portfolio') || p.includes('personal site')) {
31
+ domain = 'portfolio';
32
+ } else if (p.includes('restaurant') || p.includes('culinary') || p.includes('dining') || p.includes('cafe') || p.includes('bistro') || p.includes('menu')) {
33
+ domain = 'restaurant';
34
+ } else if (p.includes('ecommerce') || p.includes('shop') || p.includes('store') || p.includes('product store') || p.includes('clothing')) {
35
+ domain = 'ecommerce';
36
+ } else if (p.includes('saas') || p.includes('platform') || p.includes('subscription') || p.includes('analytics') || p.includes('pricing calculator')) {
37
+ domain = 'saas';
38
+ } else if (p.includes('agency') || p.includes('studio') || p.includes('creative lab') || p.includes('design agency')) {
39
+ domain = 'agency';
40
+ } else if (p.includes('database') || p.includes('infra') || p.includes('developer tool') || p.includes('query') || p.includes('api engine')) {
41
+ domain = 'devtool';
42
+ }
43
+
44
+ // 3. Motion & Animation Intent
45
+ const hasAnimations = p.includes('animation') || p.includes('motion') || p.includes('interactive') || p.includes('kinetic') || true;
46
+
47
+ // 4. Extract Entity / Project Name
48
+ let projectName = "Bespoke System";
49
+ let companyName = "Studio Artisan";
50
+ let roleOrSubtitle = "Modern Digital Platform";
51
+ let summary = "Engineered with intentional restraint and zero generic AI slop.";
52
+
53
+ if (domain === 'portfolio') {
54
+ projectName = "Modern Developer Portfolio";
55
+ companyName = "Alex Rivera";
56
+ roleOrSubtitle = "Staff Systems Architect & Creative Technologist";
57
+ summary = "Designing high-order distributed architectures, sub-millisecond query engines, and kinetic human-grade web interfaces.";
58
+ } else if (domain === 'restaurant') {
59
+ projectName = "Artisan Culinary Studio";
60
+ companyName = "AURELIA";
61
+ roleOrSubtitle = "Modern Botanical Gastronomy & Tasting Lab";
62
+ summary = "Hyper-seasonal tasting menus driven by foraging, fermentation, and architectural plating.";
63
+ } else if (domain === 'ecommerce') {
64
+ projectName = "Minimalist Object Store";
65
+ companyName = "MONOLITH GOODS";
66
+ roleOrSubtitle = "Precision-Crafted Hardware & Studio Tools";
67
+ summary = "Industrial-grade design artifacts engineered for creators, architects, and minimalists.";
68
+ } else if (domain === 'saas' || domain === 'devtool') {
69
+ projectName = "High-Performance Data Infrastructure";
70
+ companyName = "VectorScale";
71
+ roleOrSubtitle = "Real-Time Telemetry & Vector Query Engine";
72
+ summary = "Sub-millisecond latency query routing and deterministic state coordination for autonomous AI swarms.";
73
+ } else if (domain === 'agency') {
74
+ projectName = "Kinetic Creative Studio";
75
+ companyName = "KITE CREATIVE";
76
+ roleOrSubtitle = "Design Engineering & Spatial Digital Systems";
77
+ summary = "We partner with visionary founders to build category-defining digital flagships and interactive products.";
78
+ }
79
+
80
+ return {
81
+ prompt,
82
+ domain,
83
+ framework,
84
+ hasAnimations,
85
+ projectName,
86
+ companyName,
87
+ roleOrSubtitle,
88
+ summary,
89
+ requestedFeatures: this.extractRequestedFeatures(p, domain)
90
+ };
91
+ }
92
+
93
+ /**
94
+ * Helper: Extracts requested interactive feature modules
95
+ */
96
+ extractRequestedFeatures(promptLower, domain) {
97
+ const features = [];
98
+
99
+ if (domain === 'portfolio') {
100
+ features.push('project-filter-matrix', 'interactive-terminal-shell', 'career-timeline', 'contact-modal');
101
+ } else if (domain === 'restaurant') {
102
+ features.push('interactive-tasting-menu', 'table-reservation-modal', 'chef-curation-slider', 'hours-location-card');
103
+ } else if (domain === 'ecommerce') {
104
+ features.push('product-bento-grid', 'interactive-cart-drawer', 'currency-toggle', 'live-spec-sheet');
105
+ } else if (domain === 'saas' || domain === 'devtool') {
106
+ features.push('interactive-latency-calculator', 'code-sandbox-tabs', 'benchmark-comparison-matrix', 'pricing-tier-switcher');
107
+ } else {
108
+ features.push('asymmetric-showcase', 'interactive-feature-tabs', 'dynamic-contact-drawer');
109
+ }
110
+
111
+ if (promptLower.includes('dark') || promptLower.includes('theme') || promptLower.includes('toggle')) {
112
+ features.push('theme-toggle');
113
+ }
114
+
115
+ return features;
116
+ }
117
+
118
+ /**
119
+ * Step 2: Create Unique Project Specification
120
+ */
121
+ createProjectSpecification(analysis) {
122
+ const { domain, framework, companyName, roleOrSubtitle, summary, requestedFeatures, hasAnimations } = analysis;
123
+
124
+ // 1. Design Tokens & Palette (High-contrast, zero generic AI purple blobs)
125
+ let palette = {
126
+ bg: "#090a0f",
127
+ surface: "#10121a",
128
+ surfaceRaised: "#181b26",
129
+ border: "rgba(255, 255, 255, 0.08)",
130
+ borderHover: "rgba(255, 255, 255, 0.25)",
131
+ textPrimary: "#f8fafc",
132
+ textSecondary: "#94a3b8",
133
+ accent: "#38bdf8",
134
+ accentGlow: "rgba(56, 189, 248, 0.15)"
135
+ };
136
+
137
+ let fonts = {
138
+ display: "'Space Grotesk', -apple-system, sans-serif",
139
+ body: "'Plus Jakarta Sans', -apple-system, sans-serif",
140
+ mono: "'JetBrains Mono', monospace",
141
+ googleFontsUrl: "https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&family=Plus+Jakarta+Sans:wght@300;400;500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap"
142
+ };
143
+
144
+ if (domain === 'restaurant') {
145
+ palette = {
146
+ bg: "#0c0b0a",
147
+ surface: "#141311",
148
+ surfaceRaised: "#1c1b18",
149
+ border: "rgba(217, 196, 163, 0.12)",
150
+ borderHover: "rgba(217, 196, 163, 0.35)",
151
+ textPrimary: "#f5f2eb",
152
+ textSecondary: "#a8a29e",
153
+ accent: "#d4af37",
154
+ accentGlow: "rgba(212, 175, 55, 0.15)"
155
+ };
156
+ fonts = {
157
+ display: "'Cormorant Garamond', Georgia, serif",
158
+ body: "'Plus Jakarta Sans', sans-serif",
159
+ mono: "'JetBrains Mono', monospace",
160
+ googleFontsUrl: "https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,600;1,400&family=Plus+Jakarta+Sans:wght@300;400;500;600&display=swap"
161
+ };
162
+ } else if (domain === 'agency' || domain === 'portfolio') {
163
+ palette = {
164
+ bg: "#08090c",
165
+ surface: "#0f1117",
166
+ surfaceRaised: "#161922",
167
+ border: "rgba(255, 255, 255, 0.08)",
168
+ borderHover: "rgba(255, 255, 255, 0.3)",
169
+ textPrimary: "#ffffff",
170
+ textSecondary: "#9ca3af",
171
+ accent: "#10b981",
172
+ accentGlow: "rgba(16, 185, 129, 0.15)"
173
+ };
174
+ fonts = {
175
+ display: "'Instrument Serif', Georgia, serif",
176
+ body: "'Inter', -apple-system, sans-serif",
177
+ mono: "'JetBrains Mono', monospace",
178
+ googleFontsUrl: "https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap"
179
+ };
180
+ }
181
+
182
+ // 2. Dynamic Section Topology
183
+ const sections = this.buildSectionTopology(domain, companyName, roleOrSubtitle, summary, requestedFeatures);
184
+
185
+ return {
186
+ projectName: analysis.projectName,
187
+ domain,
188
+ framework,
189
+ companyName,
190
+ headline: roleOrSubtitle,
191
+ summary,
192
+ hasAnimations,
193
+ palette,
194
+ fonts,
195
+ requestedFeatures,
196
+ sections,
197
+ apiRoutes: [
198
+ { path: 'src/app/api/contact/route.ts', purpose: 'Handles inquiries with RFC 7807 validation' },
199
+ { path: 'src/app/api/data/route.ts', purpose: 'Serves dynamic domain entities & filtering' }
200
+ ]
201
+ };
202
+ }
203
+
204
+ /**
205
+ * Helper: Builds domain-specific section hierarchy
206
+ */
207
+ buildSectionTopology(domain, name, headline, summary, features) {
208
+ if (domain === 'portfolio') {
209
+ return [
210
+ { id: 'navbar', component: 'Navbar', title: name, navLinks: ['Projects', 'Console', 'Timeline', 'Contact'] },
211
+ { id: 'hero', component: 'Hero', headline: "Architecting high-order distributed systems & kinetic web platforms.", subheadline: summary, primaryCta: "Explore Selected Works", secondaryCta: "Launch Interactive Shell" },
212
+ { id: 'projects', component: 'ProjectsGrid', title: "Selected Works & Architectures", categories: ["All", "Distributed Systems", "AI & RAG", "Frontend Islands", "Open Source"] },
213
+ { id: 'terminal', component: 'TerminalBio', title: "Interactive Developer Shell", subtitle: "Type `skills`, `architecture`, `experience`, or `contact`" },
214
+ { id: 'experience', component: 'ExperienceTimeline', title: "Career & Technical Milestones" },
215
+ { id: 'contact', component: 'ContactSection', title: "Let's build something exceptional together.", email: "alex@example.com" }
216
+ ];
217
+ } else if (domain === 'restaurant') {
218
+ return [
219
+ { id: 'navbar', component: 'Navbar', title: name, navLinks: ['Tasting Menu', 'Philosophy', 'Private Dining', 'Reservations'] },
220
+ { id: 'hero', component: 'Hero', headline: "Hyper-seasonal gastronomy rooted in botanical exploration.", subheadline: summary, primaryCta: "Reserve a Table", secondaryCta: "View Seasonal Menu" },
221
+ { id: 'tasting-menu', component: 'TastingMenu', title: "Autumn Tasting Course", categories: ["All", "First Course", "Main Course", "Dessert", "Wine Pairings"] },
222
+ { id: 'philosophy', component: 'ChefPhilosophy', title: "From Soil to Plate", quote: "We cook not to impress, but to connect guests with the untamed landscape." },
223
+ { id: 'reservation', component: 'ReservationSection', title: "Join Us at the Table", cta: "Book Reservation" }
224
+ ];
225
+ } else {
226
+ return [
227
+ { id: 'navbar', component: 'Navbar', title: name, navLinks: ['Capabilities', 'Architecture', 'Throughput', 'Contact'] },
228
+ { id: 'hero', component: 'Hero', headline: headline, subheadline: summary, primaryCta: "Launch Interactive Sandbox", secondaryCta: "Explore Specs" },
229
+ { id: 'showcase', component: 'BentoShowcase', title: "Engineered from First Principles", cards: 4 },
230
+ { id: 'interactive', component: 'InteractiveCalculator', title: "Performance ROI Calculator" },
231
+ { id: 'contact', component: 'ContactSection', title: "Deploy Modern Architecture", email: "team@example.com" }
232
+ ];
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Step 3: Create Dynamic Task Graph (DAG)
238
+ */
239
+ createTaskGraph(spec) {
240
+ const tasks = [
241
+ {
242
+ id: 'task-plan',
243
+ agentId: 'orchestrator',
244
+ name: 'Project Requirement Analysis & DAG Compilation',
245
+ task: `Deconstruct brief for ${spec.domain.toUpperCase()} project into modular task DAG`,
246
+ skills: ['frontend/nextjs'],
247
+ dependsOn: [],
248
+ status: 'queued'
249
+ },
250
+ {
251
+ id: 'task-design-director',
252
+ agentId: 'creativeDirector',
253
+ name: 'Visual Direction & Anti-AI Guardian Strategy',
254
+ task: `Formulate authentic visual personality, fluid clamp typography, and ban purple gradients & repetitive cards`,
255
+ skills: ['design/ui-design', 'design/typography', 'anti-ai/slop-guardian'],
256
+ dependsOn: ['task-plan'],
257
+ status: 'queued'
258
+ },
259
+ {
260
+ id: 'task-content-strategist',
261
+ agentId: 'contentStrategist',
262
+ name: 'Grounded Technical Copywriting & Domain Data',
263
+ task: `Author bespoke domain fixtures and technical value props with zero placeholder cliché copy`,
264
+ skills: ['content/copywriting', 'backend/data-models'],
265
+ dependsOn: ['task-plan'],
266
+ status: 'queued'
267
+ },
268
+ {
269
+ id: 'task-frontend-scaffold',
270
+ agentId: 'frontend',
271
+ name: 'Next.js 14/15 App Router Scaffolding & Root Layout',
272
+ task: `Synthesize package.json, tsconfig.json, tailwind.config.ts, src/app/layout.tsx, and globals.css`,
273
+ skills: ['frontend/nextjs', 'frontend/react', 'frontend/tailwind'],
274
+ dependsOn: ['task-design-director'],
275
+ status: 'queued'
276
+ },
277
+ {
278
+ id: 'task-frontend-components',
279
+ agentId: 'frontend',
280
+ name: 'Bespoke Asymmetric Section Components & Pages',
281
+ task: `Build src/app/page.tsx and all section components (${spec.sections.map(s => s.component).join(', ')})`,
282
+ skills: ['frontend/nextjs', 'frontend/react', 'design/ui-design'],
283
+ dependsOn: ['task-frontend-scaffold', 'task-content-strategist'],
284
+ status: 'queued'
285
+ },
286
+ {
287
+ id: 'task-backend-routes',
288
+ agentId: 'backend',
289
+ name: 'TypeScript API Route Handlers & Data Contract',
290
+ task: `Synthesize src/app/api/contact/route.ts and src/app/api/data/route.ts with RFC 7807 validation`,
291
+ skills: ['backend/route-handlers', 'backend/data-models'],
292
+ dependsOn: ['task-frontend-scaffold'],
293
+ status: 'queued'
294
+ },
295
+ {
296
+ id: 'task-animation-motion',
297
+ agentId: 'animationSpecialist',
298
+ name: 'Framer Motion Transitions & Interactive Micro-Interactions',
299
+ task: `Add smooth reveal choreography, interactive category filtering, and terminal emulator logic`,
300
+ skills: ['motion/framer-motion', 'motion/micro-interactions'],
301
+ dependsOn: ['task-frontend-components'],
302
+ status: 'queued'
303
+ },
304
+ {
305
+ id: 'task-responsive-specialist',
306
+ agentId: 'responsiveSpecialist',
307
+ name: 'Responsive Viewport Optimization & Layout Integrity',
308
+ task: `Ensure zero horizontal scroll, fluid clamp() font scaling, and touch target sizing`,
309
+ skills: ['quality/responsive-design', 'frontend/accessibility'],
310
+ dependsOn: ['task-frontend-components'],
311
+ status: 'queued'
312
+ },
313
+ {
314
+ id: 'task-qa-visual-critic',
315
+ agentId: 'visualCritic',
316
+ name: 'Anti-AI Rubric Review & Build Verification',
317
+ task: `Audit generated codebase against 6-dimension Anti-AI rubric and verify final threshold >= 8.5/10`,
318
+ skills: ['quality/visual-review', 'quality/browser-testing'],
319
+ dependsOn: ['task-animation-motion', 'task-responsive-specialist', 'task-backend-routes'],
320
+ status: 'queued'
321
+ }
322
+ ];
323
+
324
+ return {
325
+ spec,
326
+ tasks
327
+ };
328
+ }
329
+ }
@@ -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,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
+ }
@@ -55,17 +55,17 @@ export async function initializeProject(targetDir = process.cwd(), options = {})
55
55
  console.log(` \x1b[90m• Frameworks:\x1b[0m ${profile.frameworks.join(', ') || 'Standard Web'}`);
56
56
  console.log(` \x1b[90m• Backend:\x1b[0m ${profile.backend.join(', ') || 'Node.js'}`);
57
57
  console.log(` \x1b[90m• Database:\x1b[0m ${profile.database.join(', ') || 'SQL / Relational'}`);
58
- console.log(` \x1b[90m• Testing:\x1b[0m ${profile.testing.join(', ') || 'Standard Testing'}`);
59
-
60
58
  const pixelAgentsDir = path.join(targetDir, '.pixel-agents');
61
59
  const agentsDir = path.join(pixelAgentsDir, 'agents');
62
60
  const skillsDir = path.join(pixelAgentsDir, 'skills');
63
- const dashboardDir = path.join(targetDir, '.pixel-dashboard');
61
+ const reportsDir = path.join(pixelAgentsDir, 'reports');
62
+ const dashboardDir = path.join(pixelAgentsDir, 'dashboard');
64
63
 
65
- // Create directories
64
+ // Create directories inside .pixel-agents
66
65
  await fs.mkdir(pixelAgentsDir, { recursive: true });
67
66
  await fs.mkdir(agentsDir, { recursive: true });
68
67
  await fs.mkdir(skillsDir, { recursive: true });
68
+ await fs.mkdir(reportsDir, { recursive: true });
69
69
  if (enableDashboard) {
70
70
  await fs.mkdir(dashboardDir, { recursive: true });
71
71
  }
@@ -139,7 +139,7 @@ export async function initializeProject(targetDir = process.cwd(), options = {})
139
139
  await fs.writeFile(path.join(dashboardDir, 'index.html'), html, 'utf-8');
140
140
  await fs.writeFile(path.join(dashboardDir, 'styles.css'), css, 'utf-8');
141
141
  await fs.writeFile(path.join(dashboardDir, 'app.js'), js, 'utf-8');
142
- console.log(' \x1b[32m✓\x1b[0m Created .pixel-dashboard/ (index.html, styles.css, app.js)');
142
+ console.log(' \x1b[32m✓\x1b[0m Created .pixel-agents/dashboard/ (index.html, styles.css, app.js)');
143
143
  } catch (err) {
144
144
  // ignore
145
145
  }