pixelcrew 0.1.0

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,398 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+
4
+ /**
5
+ * Deep static codebase analyzer that detects frameworks, database/ORMs,
6
+ * architectures, languages, and directory layouts to tailor agent skills and permissions.
7
+ */
8
+ export async function analyzeCodebase(targetDir = process.cwd()) {
9
+ const profile = {
10
+ projectName: path.basename(targetDir),
11
+ languages: [],
12
+ frameworks: [],
13
+ backend: [],
14
+ database: [],
15
+ testing: [],
16
+ auth: [],
17
+ styling: [],
18
+ packageManager: 'npm',
19
+ directories: [],
20
+ files: [],
21
+ recommendedSkills: [],
22
+ agentSpecializations: {}
23
+ };
24
+
25
+ // Helper to safely check if file or dir exists
26
+ const exists = async (relPath) => {
27
+ try {
28
+ await fs.access(path.join(targetDir, relPath));
29
+ return true;
30
+ } catch {
31
+ return false;
32
+ }
33
+ };
34
+
35
+ // Helper to read and parse JSON
36
+ const readJson = async (relPath) => {
37
+ try {
38
+ const data = await fs.readFile(path.join(targetDir, relPath), 'utf-8');
39
+ return JSON.parse(data);
40
+ } catch {
41
+ return null;
42
+ }
43
+ };
44
+
45
+ // Helper to read file text
46
+ const readText = async (relPath) => {
47
+ try {
48
+ return await fs.readFile(path.join(targetDir, relPath), 'utf-8');
49
+ } catch {
50
+ return null;
51
+ }
52
+ };
53
+
54
+ // 1. Scan Top-Level Directories
55
+ try {
56
+ const entries = await fs.readdir(targetDir, { withFileTypes: true });
57
+ for (const entry of entries) {
58
+ if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {
59
+ profile.directories.push(entry.name);
60
+ } else if (entry.isFile()) {
61
+ profile.files.push(entry.name);
62
+ }
63
+ }
64
+ } catch {
65
+ // ignore
66
+ }
67
+
68
+ // 2. Node.js & JavaScript/TypeScript Ecosystem Detection
69
+ const dirName = path.basename(targetDir);
70
+ const GENERIC_NAMES = new Set([
71
+ 'next_temp', 'next-temp', 'nextjs-temp', 'my-app', 'next-app', 'react-app',
72
+ 'app', 'template', 'starter', 'boilerplate', 'untitled', 'temp', 'tmp', 'project',
73
+ 'create-next-app', 'vite-project', 'frontend', 'backend', 'demo', 'sample'
74
+ ]);
75
+
76
+ const pkg = await readJson('package.json');
77
+ if (pkg && pkg.name && !GENERIC_NAMES.has(pkg.name.toLowerCase())) {
78
+ profile.projectName = pkg.name;
79
+ } else {
80
+ profile.projectName = dirName;
81
+ }
82
+
83
+ if (pkg) {
84
+ const allDeps = {
85
+ ...(pkg.dependencies || {}),
86
+ ...(pkg.devDependencies || {})
87
+ };
88
+
89
+ // Languages
90
+ if (allDeps.typescript || await exists('tsconfig.json')) {
91
+ profile.languages.push('TypeScript');
92
+ }
93
+ profile.languages.push('JavaScript');
94
+
95
+ // Frontend Frameworks
96
+ if (allDeps.next) {
97
+ const isAppRouter = (await exists('app')) || (await exists('src/app'));
98
+ profile.frameworks.push(`Next.js (${isAppRouter ? 'App Router' : 'Pages Router'})`);
99
+ profile.recommendedSkills.push('nextjs');
100
+ }
101
+ if (allDeps.react) {
102
+ profile.frameworks.push('React');
103
+ profile.recommendedSkills.push('react');
104
+ }
105
+ if (allDeps.vue) {
106
+ profile.frameworks.push('Vue');
107
+ profile.recommendedSkills.push('vue');
108
+ }
109
+ if (allDeps.svelte) {
110
+ profile.frameworks.push('Svelte');
111
+ profile.recommendedSkills.push('svelte');
112
+ }
113
+ if (allDeps.astro) {
114
+ profile.frameworks.push('Astro');
115
+ profile.recommendedSkills.push('astro');
116
+ }
117
+
118
+ // Styling
119
+ if (allDeps.tailwindcss || await exists('tailwind.config.js') || await exists('tailwind.config.ts')) {
120
+ profile.styling.push('TailwindCSS');
121
+ profile.recommendedSkills.push('tailwind');
122
+ }
123
+
124
+ // Backend
125
+ if (allDeps.express) {
126
+ profile.backend.push('Express.js');
127
+ profile.recommendedSkills.push('express');
128
+ profile.recommendedSkills.push('api-architecture');
129
+ }
130
+ if (allDeps['@nestjs/core']) {
131
+ profile.backend.push('NestJS');
132
+ profile.recommendedSkills.push('nestjs');
133
+ }
134
+ if (allDeps.fastify) {
135
+ profile.backend.push('Fastify');
136
+ profile.recommendedSkills.push('fastify');
137
+ }
138
+ if (allDeps.hono) {
139
+ profile.backend.push('Hono');
140
+ }
141
+ if (allDeps['@trpc/server']) {
142
+ profile.backend.push('tRPC');
143
+ profile.recommendedSkills.push('trpc');
144
+ }
145
+ if (allDeps.graphql) {
146
+ profile.backend.push('GraphQL');
147
+ profile.recommendedSkills.push('graphql');
148
+ }
149
+
150
+ // Database & ORMs
151
+ if (allDeps['@prisma/client'] || await exists('prisma/schema.prisma')) {
152
+ profile.database.push('Prisma ORM');
153
+ profile.recommendedSkills.push('prisma');
154
+ profile.recommendedSkills.push('query-optimization');
155
+
156
+ // Check DB provider in prisma schema
157
+ const schemaText = await readText('prisma/schema.prisma');
158
+ if (schemaText) {
159
+ if (schemaText.includes('provider = "postgresql"') || schemaText.includes('provider = "postgres"')) {
160
+ profile.database.push('PostgreSQL');
161
+ profile.recommendedSkills.push('postgresql');
162
+ } else if (schemaText.includes('provider = "mysql"')) {
163
+ profile.database.push('MySQL');
164
+ profile.recommendedSkills.push('mysql');
165
+ } else if (schemaText.includes('provider = "sqlite"')) {
166
+ profile.database.push('SQLite');
167
+ profile.recommendedSkills.push('sqlite');
168
+ } else if (schemaText.includes('provider = "mongodb"')) {
169
+ profile.database.push('MongoDB');
170
+ profile.recommendedSkills.push('mongodb');
171
+ }
172
+ }
173
+ }
174
+
175
+ if (allDeps['drizzle-orm'] || await exists('drizzle.config.ts') || await exists('drizzle.config.js')) {
176
+ profile.database.push('Drizzle ORM');
177
+ profile.recommendedSkills.push('drizzle');
178
+ }
179
+ if (allDeps.typeorm) {
180
+ profile.database.push('TypeORM');
181
+ profile.recommendedSkills.push('typeorm');
182
+ }
183
+ if (allDeps.mongoose) {
184
+ profile.database.push('Mongoose (MongoDB)');
185
+ profile.recommendedSkills.push('mongodb');
186
+ }
187
+ if (allDeps.pg) {
188
+ if (!profile.database.includes('PostgreSQL')) profile.database.push('PostgreSQL');
189
+ profile.recommendedSkills.push('postgresql');
190
+ }
191
+ if (allDeps.redis || allDeps.ioredis || allDeps['@upstash/redis']) {
192
+ profile.database.push('Redis');
193
+ profile.recommendedSkills.push('redis-caching');
194
+ }
195
+
196
+ // Testing
197
+ if (allDeps.vitest) {
198
+ profile.testing.push('Vitest');
199
+ profile.recommendedSkills.push('vitest');
200
+ }
201
+ if (allDeps.jest) {
202
+ profile.testing.push('Jest');
203
+ profile.recommendedSkills.push('jest');
204
+ }
205
+ if (allDeps['@playwright/test']) {
206
+ profile.testing.push('Playwright');
207
+ profile.recommendedSkills.push('playwright-e2e');
208
+ }
209
+ if (allDeps.cypress) {
210
+ profile.testing.push('Cypress');
211
+ profile.recommendedSkills.push('cypress-e2e');
212
+ }
213
+
214
+ // Auth
215
+ if (allDeps['next-auth'] || allDeps['@auth/core']) {
216
+ profile.auth.push('NextAuth / Auth.js');
217
+ profile.recommendedSkills.push('auth-security');
218
+ }
219
+ if (allDeps['@clerk/nextjs'] || allDeps['@clerk/clerk-react']) {
220
+ profile.auth.push('Clerk Auth');
221
+ }
222
+ if (allDeps['@supabase/supabase-js'] || allDeps['@supabase/ssr']) {
223
+ profile.auth.push('Supabase Auth & DB');
224
+ profile.recommendedSkills.push('supabase');
225
+ }
226
+ }
227
+
228
+ // 3. Python Ecosystem Detection
229
+ if (await exists('requirements.txt') || await exists('pyproject.toml') || await exists('Pipfile')) {
230
+ profile.languages.push('Python');
231
+ const reqText = (await readText('requirements.txt')) || (await readText('pyproject.toml')) || '';
232
+ if (reqText.includes('django')) {
233
+ profile.backend.push('Django');
234
+ profile.recommendedSkills.push('django');
235
+ }
236
+ if (reqText.includes('fastapi')) {
237
+ profile.backend.push('FastAPI');
238
+ profile.recommendedSkills.push('fastapi');
239
+ profile.recommendedSkills.push('api-architecture');
240
+ }
241
+ if (reqText.includes('sqlalchemy')) {
242
+ profile.database.push('SQLAlchemy');
243
+ profile.recommendedSkills.push('sqlalchemy');
244
+ }
245
+ if (reqText.includes('pytest')) {
246
+ profile.testing.push('Pytest');
247
+ profile.recommendedSkills.push('pytest');
248
+ }
249
+ }
250
+
251
+ // 4. Go Ecosystem Detection
252
+ if (await exists('go.mod')) {
253
+ profile.languages.push('Go');
254
+ const goMod = await readText('go.mod');
255
+ if (goMod && goMod.includes('gin-gonic/gin')) profile.backend.push('Gin');
256
+ if (goMod && goMod.includes('gorm.io/gorm')) profile.database.push('GORM');
257
+ profile.recommendedSkills.push('go-architecture');
258
+ }
259
+
260
+ // 5. Rust Ecosystem Detection
261
+ if (await exists('Cargo.toml')) {
262
+ profile.languages.push('Rust');
263
+ profile.recommendedSkills.push('rust-architecture');
264
+ }
265
+
266
+ // Fallbacks if empty
267
+ if (profile.languages.length === 0) profile.languages.push('JavaScript');
268
+ if (profile.frameworks.length === 0) profile.frameworks.push('Standard Web / DOM');
269
+ if (profile.backend.length === 0) profile.backend.push('Node.js API');
270
+ if (profile.database.length === 0) profile.database.push('SQL / Relational DB');
271
+ if (profile.testing.length === 0) profile.testing.push('Unit & E2E Testing');
272
+
273
+ // Always include core skills
274
+ profile.recommendedSkills.push('codebase-intelligence', 'security-audit', 'performance-profiling', 'testing');
275
+ profile.recommendedSkills = [...new Set(profile.recommendedSkills)];
276
+
277
+ return profile;
278
+ }
279
+
280
+ /**
281
+ * Generates tailored agent configurations and skills mapped to the analyzed codebase
282
+ */
283
+ export function buildAdaptedConfig(profile, options = {}) {
284
+ const isTypeScript = profile.languages.includes('TypeScript');
285
+ const hasPrisma = profile.database.includes('Prisma ORM');
286
+ const hasNext = profile.frameworks.some(f => f.includes('Next.js'));
287
+
288
+ // Detect directories present in project for permissions
289
+ const srcPrefix = profile.directories.includes('src') ? 'src/' : '';
290
+
291
+ return {
292
+ version: "0.1.0",
293
+ project: profile.projectName,
294
+ codebaseProfile: {
295
+ languages: profile.languages,
296
+ frameworks: profile.frameworks,
297
+ backend: profile.backend,
298
+ database: profile.database,
299
+ testing: profile.testing,
300
+ auth: profile.auth,
301
+ styling: profile.styling
302
+ },
303
+ orchestrator: {
304
+ enabled: true,
305
+ maxConcurrentAgents: 4,
306
+ autoDecompose: true,
307
+ logEvents: true
308
+ },
309
+ agents: {
310
+ frontend: {
311
+ name: "Frontend Agent",
312
+ role: `${profile.frameworks[0] || 'UI/UX'} & Component Engineering`,
313
+ sprite: "frontend",
314
+ color: "#00f0ff",
315
+ enabled: true,
316
+ maxTasks: 2,
317
+ skills: profile.recommendedSkills.filter(s => ['react', 'nextjs', 'vue', 'svelte', 'astro', 'tailwind', 'ui-optimization'].includes(s)),
318
+ permissions: {
319
+ read: [`${srcPrefix}components/**`, `${srcPrefix}pages/**`, `${srcPrefix}app/**`, `${srcPrefix}styles/**`, "public/**"],
320
+ write: [`${srcPrefix}components/**`, `${srcPrefix}pages/**`, `${srcPrefix}app/**`, `${srcPrefix}styles/**`]
321
+ }
322
+ },
323
+ backend: {
324
+ name: "Backend Agent",
325
+ role: `${profile.backend[0] || 'API'} Architecture & Business Logic`,
326
+ sprite: "backend",
327
+ color: "#ff007f",
328
+ enabled: true,
329
+ maxTasks: 2,
330
+ skills: profile.recommendedSkills.filter(s => ['api-architecture', 'node', 'express', 'nestjs', 'fastify', 'trpc', 'graphql', 'fastapi', 'django', 'go-architecture', 'auth-security'].includes(s)),
331
+ permissions: {
332
+ read: [`${srcPrefix}api/**`, `${srcPrefix}server/**`, `${srcPrefix}routes/**`, `${srcPrefix}controllers/**`, `${srcPrefix}lib/**`],
333
+ write: [`${srcPrefix}api/**`, `${srcPrefix}server/**`, `${srcPrefix}routes/**`, `${srcPrefix}controllers/**`]
334
+ }
335
+ },
336
+ database: {
337
+ name: "Database Agent",
338
+ role: `${profile.database[0] || 'Database'} & Data Modeling Architect`,
339
+ sprite: "database",
340
+ color: "#ffd700",
341
+ enabled: true,
342
+ maxTasks: 1,
343
+ skills: profile.recommendedSkills.filter(s => ['postgresql', 'prisma', 'drizzle', 'typeorm', 'mongodb', 'mysql', 'sqlite', 'query-optimization', 'indexing', 'redis-caching'].includes(s)),
344
+ permissions: {
345
+ read: ["prisma/**", "db/**", "migrations/**", "models/**", "drizzle/**"],
346
+ write: ["prisma/**", "db/**", "migrations/**", "drizzle/**"]
347
+ }
348
+ },
349
+ security: {
350
+ name: "Security Agent",
351
+ role: "OWASP & Vulnerability Hardening",
352
+ sprite: "security",
353
+ color: "#ff3344",
354
+ enabled: true,
355
+ maxTasks: 1,
356
+ skills: ["security-audit", "codebase-intelligence", "auth-security"],
357
+ permissions: {
358
+ read: ["**/*"],
359
+ write: ["security/**", ".env.example"]
360
+ }
361
+ },
362
+ performance: {
363
+ name: "Performance Agent",
364
+ role: "Core Web Vitals & Runtime Profiling",
365
+ sprite: "performance",
366
+ color: "#39ff14",
367
+ enabled: true,
368
+ maxTasks: 1,
369
+ skills: ["performance-profiling", "lcp-optimization", "memory-profiling"],
370
+ permissions: {
371
+ read: ["**/*"],
372
+ write: [`${srcPrefix}**/*`]
373
+ }
374
+ },
375
+ qa: {
376
+ name: "QA Agent",
377
+ role: `${profile.testing[0] || 'Testing'} Automation Lead`,
378
+ sprite: "qa",
379
+ color: "#b026ff",
380
+ enabled: true,
381
+ maxTasks: 1,
382
+ dependsOn: ["frontend", "backend", "database"],
383
+ skills: profile.recommendedSkills.filter(s => ['testing', 'vitest', 'jest', 'playwright-e2e', 'cypress-e2e', 'pytest'].includes(s)),
384
+ permissions: {
385
+ read: ["**/*"],
386
+ write: ["tests/**", "__tests__/**", "cypress/**", "playwright/**", "e2e/**"]
387
+ }
388
+ }
389
+ },
390
+ dashboard: {
391
+ enabled: true,
392
+ port: 4747,
393
+ theme: "pixel",
394
+ crtEffect: true,
395
+ soundEffects: true
396
+ }
397
+ };
398
+ }
@@ -0,0 +1,155 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import readline from 'node:readline/promises';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { DEFAULT_CONFIG, INITIAL_STATE, AGENT_MARKDOWNS, SKILL_MARKDOWNS } from './templates.js';
6
+ import { analyzeCodebase, buildAdaptedConfig } from './analyzer.js';
7
+
8
+ /**
9
+ * Initializes a new .pixel-agents workspace adapted to the target directory
10
+ */
11
+ export async function initializeProject(targetDir = process.cwd(), options = {}) {
12
+ const isInteractive = !options.yes && process.stdin.isTTY;
13
+ let projectName = options.name || path.basename(targetDir);
14
+ let enableDashboard = true;
15
+
16
+ if (isInteractive) {
17
+ const rl = readline.createInterface({
18
+ input: process.stdin,
19
+ output: process.stdout
20
+ });
21
+
22
+ console.log('\n\x1b[36m' + `
23
+ ╔═══════════════════════════════════════════════════════════╗
24
+ ║ PIXEL AGENTS - Multi-Agent Orchestration Framework ║
25
+ ║ [ ◉ _ ◉ ] ║
26
+ ╚═══════════════════════════════════════════════════════════╝
27
+ ` + '\x1b[0m');
28
+
29
+ const nameAns = await rl.question(`? Project name (${projectName}): `);
30
+ if (nameAns.trim()) {
31
+ projectName = nameAns.trim();
32
+ }
33
+
34
+ const dashAns = await rl.question(`? Enable visual pixel dashboard? (Y/n): `);
35
+ if (dashAns.trim().toLowerCase() === 'n') {
36
+ enableDashboard = false;
37
+ }
38
+
39
+ rl.close();
40
+ }
41
+
42
+ console.log('\n\x1b[33mInitializing Pixel Agents in:\x1b[0m', targetDir);
43
+
44
+ // 1. Deep Codebase Analysis & Context Extraction
45
+ console.log('\x1b[36m🔍 Scanning and analyzing codebase architecture...\x1b[0m');
46
+ const profile = await analyzeCodebase(targetDir);
47
+ if (options.name) {
48
+ profile.projectName = options.name;
49
+ projectName = options.name;
50
+ } else if (profile.projectName) {
51
+ projectName = profile.projectName;
52
+ }
53
+
54
+ console.log(` \x1b[90m• Languages:\x1b[0m ${profile.languages.join(', ') || 'JavaScript'}`);
55
+ console.log(` \x1b[90m• Frameworks:\x1b[0m ${profile.frameworks.join(', ') || 'Standard Web'}`);
56
+ console.log(` \x1b[90m• Backend:\x1b[0m ${profile.backend.join(', ') || 'Node.js'}`);
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
+ const pixelAgentsDir = path.join(targetDir, '.pixel-agents');
61
+ const agentsDir = path.join(pixelAgentsDir, 'agents');
62
+ const skillsDir = path.join(pixelAgentsDir, 'skills');
63
+ const dashboardDir = path.join(targetDir, '.pixel-dashboard');
64
+
65
+ // Create directories
66
+ await fs.mkdir(pixelAgentsDir, { recursive: true });
67
+ await fs.mkdir(agentsDir, { recursive: true });
68
+ await fs.mkdir(skillsDir, { recursive: true });
69
+ if (enableDashboard) {
70
+ await fs.mkdir(dashboardDir, { recursive: true });
71
+ }
72
+
73
+ // 2. Build Context-Adapted Config
74
+ const adaptedConfig = buildAdaptedConfig(profile, options);
75
+ adaptedConfig.project = projectName;
76
+ adaptedConfig.dashboard.enabled = enableDashboard;
77
+
78
+ await fs.writeFile(
79
+ path.join(pixelAgentsDir, 'config.json'),
80
+ JSON.stringify(adaptedConfig, null, 2),
81
+ 'utf-8'
82
+ );
83
+ console.log(' \x1b[32m✓\x1b[0m Created .pixel-agents/config.json (tailored agent roles & permissions)');
84
+
85
+ // 3. Write Codebase Context Cache
86
+ await fs.writeFile(
87
+ path.join(pixelAgentsDir, 'context.json'),
88
+ JSON.stringify(profile, null, 2),
89
+ 'utf-8'
90
+ );
91
+ console.log(' \x1b[32m✓\x1b[0m Created .pixel-agents/context.json (grounded codebase context)');
92
+
93
+ // 4. Write state.json
94
+ const state = JSON.parse(JSON.stringify(INITIAL_STATE));
95
+ state.startedAt = new Date().toISOString();
96
+ await fs.writeFile(
97
+ path.join(pixelAgentsDir, 'state.json'),
98
+ JSON.stringify(state, null, 2),
99
+ 'utf-8'
100
+ );
101
+ console.log(' \x1b[32m✓\x1b[0m Created .pixel-agents/state.json');
102
+
103
+ // 5. Write initial events.jsonl
104
+ const initialEvent = {
105
+ id: 'evt-0',
106
+ timestamp: Date.now(),
107
+ agent: 'orchestrator',
108
+ type: 'spawn',
109
+ message: `Pixel Agents swarm initialized & adapted to ${profile.frameworks.join(', ') || 'codebase'}`,
110
+ metadata: { version: '0.1.0', profile }
111
+ };
112
+ await fs.writeFile(
113
+ path.join(pixelAgentsDir, 'events.jsonl'),
114
+ JSON.stringify(initialEvent) + '\n',
115
+ 'utf-8'
116
+ );
117
+ console.log(' \x1b[32m✓\x1b[0m Created .pixel-agents/events.jsonl');
118
+
119
+ // 6. Write agents/*.md
120
+ for (const [filename, content] of Object.entries(AGENT_MARKDOWNS)) {
121
+ await fs.writeFile(path.join(agentsDir, filename), content.trim() + '\n', 'utf-8');
122
+ }
123
+ console.log(` \x1b[32m✓\x1b[0m Created ${Object.keys(AGENT_MARKDOWNS).length} agent definitions in .pixel-agents/agents/`);
124
+
125
+ // 7. Write skills/*.md
126
+ for (const [filename, content] of Object.entries(SKILL_MARKDOWNS)) {
127
+ await fs.writeFile(path.join(skillsDir, filename), content.trim() + '\n', 'utf-8');
128
+ }
129
+ console.log(` \x1b[32m✓\x1b[0m Created ${Object.keys(SKILL_MARKDOWNS).length} skill definitions in .pixel-agents/skills/`);
130
+
131
+ // 8. Copy dashboard static files if enabled
132
+ if (enableDashboard) {
133
+ const srcDashboardDir = fileURLToPath(new URL('../dashboard', import.meta.url));
134
+ try {
135
+ const html = await fs.readFile(path.join(srcDashboardDir, 'index.html'), 'utf-8');
136
+ const css = await fs.readFile(path.join(srcDashboardDir, 'styles.css'), 'utf-8');
137
+ const js = await fs.readFile(path.join(srcDashboardDir, 'app.js'), 'utf-8');
138
+
139
+ await fs.writeFile(path.join(dashboardDir, 'index.html'), html, 'utf-8');
140
+ await fs.writeFile(path.join(dashboardDir, 'styles.css'), css, 'utf-8');
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)');
143
+ } catch (err) {
144
+ // ignore
145
+ }
146
+ }
147
+
148
+ console.log('\n\x1b[32m\x1b[1mPixel Agents initialized & adapted successfully!\x1b[0m\n');
149
+ console.log('Next steps:');
150
+ console.log(' \x1b[36mnpx pixel-agents start\x1b[0m Launch orchestration server & dashboard');
151
+ console.log(' \x1b[36mnpx pixel-agents demo\x1b[0m Run an interactive multi-agent demo');
152
+ console.log(' \x1b[36mnpx pixel-agents task "..."\x1b[0m Dispatch a task to the agent swarm\n');
153
+
154
+ return { pixelAgentsDir, dashboardDir, profile };
155
+ }