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
package/src/scaffold/init.js
CHANGED
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
3
4
|
import readline from 'node:readline/promises';
|
|
4
|
-
import
|
|
5
|
+
import fsSync from 'node:fs';
|
|
5
6
|
import { DEFAULT_CONFIG, INITIAL_STATE, AGENT_MARKDOWNS, SKILL_MARKDOWNS } from './templates.js';
|
|
6
7
|
import { analyzeCodebase, buildAdaptedConfig } from './analyzer.js';
|
|
8
|
+
import { detectActiveIDE, GLOBAL_PROVIDER_PATHS, PROVIDER_PATHS } from './installer.js';
|
|
9
|
+
import { getSkillBundle, getAllCanonicalSkillIds } from './skills-bundle.js';
|
|
10
|
+
import { generateKiroFiles } from './kiro-generator.js';
|
|
11
|
+
import { generateCursorFiles, generateAntigravityFiles, generateClaudeFiles, generateAllIDERules } from './ide-rules.js';
|
|
12
|
+
import { FLOOR42_COMMANDS } from './commands-catalog.js';
|
|
13
|
+
import { safeWriteFile, safeMkdir, DryRunReporter } from '../utils/fs-safe.js';
|
|
7
14
|
|
|
8
15
|
/**
|
|
9
|
-
* Initializes a new .pixel-
|
|
16
|
+
* Initializes a new .pixel-crew workspace adapted to the target directory
|
|
10
17
|
*/
|
|
11
18
|
export async function initializeProject(targetDir = process.cwd(), options = {}) {
|
|
12
|
-
const isInteractive = !options.yes && process.stdin.isTTY;
|
|
19
|
+
const isInteractive = !options.yes && !options.dryRun && process.stdin.isTTY;
|
|
13
20
|
let projectName = options.name || path.basename(targetDir);
|
|
14
|
-
|
|
21
|
+
const activeIDE = detectActiveIDE(targetDir);
|
|
22
|
+
let installScope = options.scope || (options.global ? 'global' : 'project');
|
|
23
|
+
let chosenProvider = options.provider || null;
|
|
24
|
+
const dryRun = Boolean(options.dryRun);
|
|
25
|
+
const reporter = options.reporter || new DryRunReporter(targetDir);
|
|
15
26
|
|
|
16
27
|
if (isInteractive) {
|
|
17
28
|
const rl = readline.createInterface({
|
|
@@ -21,7 +32,7 @@ export async function initializeProject(targetDir = process.cwd(), options = {})
|
|
|
21
32
|
|
|
22
33
|
console.log('\n\x1b[36m' + `
|
|
23
34
|
╔═══════════════════════════════════════════════════════════╗
|
|
24
|
-
║ PIXEL
|
|
35
|
+
║ PIXEL CREW - Multi-Agent Orchestration Framework ║
|
|
25
36
|
║ [ ◉ _ ◉ ] ║
|
|
26
37
|
╚═══════════════════════════════════════════════════════════╝
|
|
27
38
|
` + '\x1b[0m');
|
|
@@ -31,18 +42,88 @@ export async function initializeProject(targetDir = process.cwd(), options = {})
|
|
|
31
42
|
projectName = nameAns.trim();
|
|
32
43
|
}
|
|
33
44
|
|
|
34
|
-
|
|
35
|
-
if (
|
|
36
|
-
|
|
45
|
+
|
|
46
|
+
if (!chosenProvider) {
|
|
47
|
+
const isDetected = activeIDE.id !== 'pixel-crew';
|
|
48
|
+
console.log(`\n\x1b[36mTarget AI IDE Selection:\x1b[0m`);
|
|
49
|
+
console.log(` 1) ${isDetected ? `${activeIDE.name} (Auto-detected)` : 'Kiro AI (.kiro/ & .kirorules)'} [Default]`);
|
|
50
|
+
console.log(` 2) Cursor IDE (.cursor/ & .cursorrules)`);
|
|
51
|
+
console.log(` 3) Google Antigravity (.agents/ & AGENTS.md)`);
|
|
52
|
+
console.log(` 4) Claude Code (.claude/ & CLAUDE.md)`);
|
|
53
|
+
console.log(` 5) Clean CLI only (.pixel-crew/ only — zero extra folders)`);
|
|
54
|
+
console.log(` 6) Multi-IDE (Configure all IDEs)`);
|
|
55
|
+
|
|
56
|
+
const ideAns = await rl.question(`Choice [1-6] (1): `);
|
|
57
|
+
const trimmedIde = ideAns.trim();
|
|
58
|
+
if (trimmedIde === '1' || trimmedIde === '') {
|
|
59
|
+
chosenProvider = isDetected ? activeIDE.id : 'kiro';
|
|
60
|
+
} else if (trimmedIde === '2' || trimmedIde.toLowerCase() === 'cursor') {
|
|
61
|
+
chosenProvider = 'cursor';
|
|
62
|
+
} else if (trimmedIde === '3' || trimmedIde.toLowerCase() === 'antigravity' || trimmedIde.toLowerCase() === 'agents') {
|
|
63
|
+
chosenProvider = 'antigravity';
|
|
64
|
+
} else if (trimmedIde === '4' || trimmedIde.toLowerCase() === 'claude') {
|
|
65
|
+
chosenProvider = 'claude-code';
|
|
66
|
+
} else if (trimmedIde === '5' || trimmedIde.toLowerCase() === 'none' || trimmedIde.toLowerCase() === 'cli') {
|
|
67
|
+
chosenProvider = 'none';
|
|
68
|
+
} else if (trimmedIde === '6' || trimmedIde.toLowerCase() === 'all' || trimmedIde.toLowerCase() === 'multi') {
|
|
69
|
+
chosenProvider = 'all';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!options.scope && !options.global) {
|
|
74
|
+
console.log(`\nSelect skill installation scope:`);
|
|
75
|
+
console.log(` 1) Project Workspace (.pixel-crew/ and active IDE) [Default]`);
|
|
76
|
+
console.log(` 2) Global (${activeIDE.name}: ${activeIDE.globalPath} — available in ANY folder)`);
|
|
77
|
+
console.log(` 3) Both (Project Workspace + Global config)`);
|
|
78
|
+
|
|
79
|
+
const scopeAns = await rl.question(`Choice [1-3] (1): `);
|
|
80
|
+
const trimmed = scopeAns.trim();
|
|
81
|
+
if (trimmed === '2' || trimmed.toLowerCase() === 'global') installScope = 'global';
|
|
82
|
+
else if (trimmed === '3' || trimmed.toLowerCase() === 'both') installScope = 'both';
|
|
83
|
+
else installScope = 'project';
|
|
37
84
|
}
|
|
38
85
|
|
|
39
86
|
rl.close();
|
|
40
87
|
}
|
|
41
88
|
|
|
42
|
-
|
|
89
|
+
if (!chosenProvider) {
|
|
90
|
+
if (options.yes) {
|
|
91
|
+
chosenProvider = 'all';
|
|
92
|
+
} else if (activeIDE.id !== 'pixel-crew') {
|
|
93
|
+
chosenProvider = activeIDE.id;
|
|
94
|
+
} else {
|
|
95
|
+
// Check if project workspace already contains specific IDE markers
|
|
96
|
+
const workspaceMarkers = [
|
|
97
|
+
{ id: 'kiro', paths: ['.kiro', '.kirorules', 'kiro.json'] },
|
|
98
|
+
{ id: 'cursor', paths: ['.cursor', '.cursorrules'] },
|
|
99
|
+
{ id: 'antigravity', paths: ['.agents', 'AGENTS.md', '.gemini'] },
|
|
100
|
+
{ id: 'claude-code', paths: ['.claude', 'CLAUDE.md'] }
|
|
101
|
+
];
|
|
102
|
+
const matchedWorkspace = workspaceMarkers.find(m => m.paths.some(p => fsSync.existsSync(path.join(targetDir, p))));
|
|
103
|
+
|
|
104
|
+
if (matchedWorkspace) {
|
|
105
|
+
chosenProvider = matchedWorkspace.id;
|
|
106
|
+
} else {
|
|
107
|
+
// Check if user has global IDEs in home directory
|
|
108
|
+
const home = options.homeDir || process.env.PIXELCREW_HOME || os.homedir();
|
|
109
|
+
const homeMarkers = [
|
|
110
|
+
{ id: 'claude-code', path: path.join(home, '.claude') },
|
|
111
|
+
{ id: 'cursor', path: path.join(home, '.cursor') },
|
|
112
|
+
{ id: 'kiro', path: path.join(home, '.kiro') },
|
|
113
|
+
{ id: 'antigravity', path: path.join(home, '.gemini', 'config') }
|
|
114
|
+
];
|
|
115
|
+
const hasHomeIde = homeMarkers.some(m => fsSync.existsSync(m.path));
|
|
116
|
+
// Default to 'all' so that when opened in ANY AI IDE on this device,
|
|
117
|
+
// slash commands and workflows appear immediately!
|
|
118
|
+
chosenProvider = hasHomeIde ? 'all' : (options.yes ? 'all' : 'none');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
console.log('\n\x1b[33mInitializing Pixel Crew in:\x1b[0m', targetDir);
|
|
43
124
|
|
|
44
125
|
// 1. Deep Codebase Analysis & Context Extraction
|
|
45
|
-
console.log('\x1b[
|
|
126
|
+
console.log('\x1b[36mScanning and analyzing codebase architecture...\x1b[0m');
|
|
46
127
|
const profile = await analyzeCodebase(targetDir);
|
|
47
128
|
if (options.name) {
|
|
48
129
|
profile.projectName = options.name;
|
|
@@ -51,105 +132,348 @@ export async function initializeProject(targetDir = process.cwd(), options = {})
|
|
|
51
132
|
projectName = profile.projectName;
|
|
52
133
|
}
|
|
53
134
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
await fs.mkdir(pixelAgentsDir, { recursive: true });
|
|
66
|
-
await fs.mkdir(agentsDir, { recursive: true });
|
|
67
|
-
await fs.mkdir(skillsDir, { recursive: true });
|
|
68
|
-
await fs.mkdir(reportsDir, { recursive: true });
|
|
69
|
-
if (enableDashboard) {
|
|
70
|
-
await fs.mkdir(dashboardDir, { recursive: true });
|
|
135
|
+
const isEmptyDir = profile.files.length === 0 && profile.directories.length === 0;
|
|
136
|
+
|
|
137
|
+
if (isEmptyDir) {
|
|
138
|
+
console.log(` \x1b[90m• Workspace:\x1b[0m Greenfield (Empty Directory)`);
|
|
139
|
+
console.log(` \x1b[90m• Default Stack:\x1b[0m Next.js 14/15 (TypeScript) + Tailwind CSS`);
|
|
140
|
+
console.log(` \x1b[90m• Backend:\x1b[0m TypeScript Route Handlers`);
|
|
141
|
+
} else {
|
|
142
|
+
console.log(` \x1b[90m• Languages:\x1b[0m ${profile.languages.join(', ') || 'JavaScript'}`);
|
|
143
|
+
console.log(` \x1b[90m• Frameworks:\x1b[0m ${profile.frameworks.join(', ') || 'Standard Web'}`);
|
|
144
|
+
console.log(` \x1b[90m• Backend:\x1b[0m ${profile.backend.join(', ') || 'Node.js'}`);
|
|
145
|
+
console.log(` \x1b[90m• Database:\x1b[0m ${profile.database.join(', ') || 'SQL / Relational'}`);
|
|
71
146
|
}
|
|
147
|
+
const pixelCrewDir = path.join(targetDir, '.pixel-crew');
|
|
148
|
+
const targets = [pixelCrewDir];
|
|
72
149
|
|
|
73
150
|
// 2. Build Context-Adapted Config
|
|
74
151
|
const adaptedConfig = buildAdaptedConfig(profile, options);
|
|
75
152
|
adaptedConfig.project = projectName;
|
|
76
|
-
adaptedConfig.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
|
153
|
+
if (!adaptedConfig.orchestrator) adaptedConfig.orchestrator = {};
|
|
154
|
+
adaptedConfig.orchestrator.runtimeStrategy = options.provider || 'auto';
|
|
155
|
+
|
|
156
|
+
// 4. State & Initial Event
|
|
94
157
|
const state = JSON.parse(JSON.stringify(INITIAL_STATE));
|
|
95
158
|
state.startedAt = new Date().toISOString();
|
|
96
|
-
|
|
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
|
|
159
|
+
|
|
104
160
|
const initialEvent = {
|
|
105
161
|
id: 'evt-0',
|
|
106
162
|
timestamp: Date.now(),
|
|
107
163
|
agent: 'orchestrator',
|
|
108
164
|
type: 'spawn',
|
|
109
|
-
message: `Pixel
|
|
110
|
-
metadata: { version: '0.
|
|
165
|
+
message: `Pixel Crew swarm initialized & adapted to ${profile.frameworks.join(', ') || 'codebase'}`,
|
|
166
|
+
metadata: { version: '0.2.5', profile }
|
|
111
167
|
};
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
'
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
168
|
+
|
|
169
|
+
const manifest = {
|
|
170
|
+
name: projectName,
|
|
171
|
+
version: '0.2.5',
|
|
172
|
+
frameworks: profile.frameworks,
|
|
173
|
+
languages: profile.languages,
|
|
174
|
+
installedAt: new Date().toISOString(),
|
|
175
|
+
skills: Object.keys(SKILL_MARKDOWNS).reduce((acc, k) => {
|
|
176
|
+
const sId = k.replace('.md', '');
|
|
177
|
+
acc[sId] = {
|
|
178
|
+
name: sId,
|
|
179
|
+
category: 'core',
|
|
180
|
+
providers: ['pixel-crew'],
|
|
181
|
+
installedAt: new Date().toISOString()
|
|
182
|
+
};
|
|
183
|
+
return acc;
|
|
184
|
+
}, {})
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
for (const baseDir of targets) {
|
|
189
|
+
const agentsDir = path.join(baseDir, 'agents');
|
|
190
|
+
const skillsDir = path.join(baseDir, 'skills');
|
|
191
|
+
const commandsDir = path.join(baseDir, 'commands');
|
|
192
|
+
const reportsDir = path.join(baseDir, 'reports');
|
|
193
|
+
const tasksDir = path.join(baseDir, 'tasks');
|
|
194
|
+
|
|
195
|
+
await safeMkdir(baseDir, { dryRun, reporter });
|
|
196
|
+
await safeMkdir(agentsDir, { dryRun, reporter });
|
|
197
|
+
await safeMkdir(skillsDir, { dryRun, reporter });
|
|
198
|
+
await safeMkdir(commandsDir, { dryRun, reporter });
|
|
199
|
+
await safeMkdir(reportsDir, { dryRun, reporter });
|
|
200
|
+
await safeMkdir(tasksDir, { dryRun, reporter });
|
|
201
|
+
|
|
202
|
+
await safeWriteFile(path.join(baseDir, 'config.json'), JSON.stringify(adaptedConfig, null, 2), { dryRun, reporter, targetDir });
|
|
203
|
+
await safeWriteFile(path.join(baseDir, 'context.json'), JSON.stringify(profile, null, 2), { dryRun, reporter, targetDir });
|
|
204
|
+
await safeWriteFile(path.join(baseDir, 'state.json'), JSON.stringify(state, null, 2), { dryRun, reporter, targetDir });
|
|
205
|
+
await safeWriteFile(path.join(baseDir, 'events.jsonl'), JSON.stringify(initialEvent) + '\n', { dryRun, reporter, targetDir });
|
|
206
|
+
await safeWriteFile(path.join(baseDir, 'pixel.json'), JSON.stringify(manifest, null, 2) + '\n', { dryRun, reporter, targetDir });
|
|
207
|
+
|
|
208
|
+
for (const [filename, content] of Object.entries(AGENT_MARKDOWNS)) {
|
|
209
|
+
await safeWriteFile(path.join(agentsDir, filename), content.trim() + '\n', { dryRun, reporter, targetDir });
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
for (const [filename, content] of Object.entries(SKILL_MARKDOWNS)) {
|
|
213
|
+
await safeWriteFile(path.join(skillsDir, filename), content.trim() + '\n', { dryRun, reporter, targetDir });
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Write all Floor 42 command markdown files
|
|
217
|
+
for (const cmd of FLOOR42_COMMANDS) {
|
|
218
|
+
const cmdContent = `---
|
|
219
|
+
description: ${cmd.description}
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
# /${cmd.name}
|
|
223
|
+
|
|
224
|
+
${cmd.prompt}
|
|
225
|
+
`;
|
|
226
|
+
await safeWriteFile(path.join(commandsDir, `${cmd.name}.md`), cmdContent, { dryRun, reporter, targetDir });
|
|
227
|
+
}
|
|
228
|
+
|
|
122
229
|
}
|
|
123
|
-
console.log(` \x1b[32m✓\x1b[0m Created ${Object.keys(AGENT_MARKDOWNS).length} agent definitions in .pixel-agents/agents/`);
|
|
124
230
|
|
|
125
|
-
//
|
|
126
|
-
|
|
127
|
-
|
|
231
|
+
// 1. Install skills to IDE project directories (.kiro, .cursor, .agents, .claude)
|
|
232
|
+
let targetIdes = [];
|
|
233
|
+
if (installScope !== 'global') {
|
|
234
|
+
if (chosenProvider === 'all' || chosenProvider === 'multi') {
|
|
235
|
+
targetIdes = ['kiro', 'cursor', 'antigravity', 'claude-code'];
|
|
236
|
+
} else if (chosenProvider && chosenProvider !== 'none' && chosenProvider !== 'pixel-crew' && chosenProvider !== 'cli') {
|
|
237
|
+
const p = chosenProvider.toLowerCase();
|
|
238
|
+
if (p === 'claude') targetIdes = ['claude-code'];
|
|
239
|
+
else if (p === 'agents') targetIdes = ['antigravity'];
|
|
240
|
+
else if (PROVIDER_PATHS[p]) targetIdes = [p];
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const canonicalSkills = getAllCanonicalSkillIds();
|
|
244
|
+
for (const ideId of targetIdes) {
|
|
245
|
+
const idePathFn = PROVIDER_PATHS[ideId];
|
|
246
|
+
if (!idePathFn) continue;
|
|
247
|
+
|
|
248
|
+
for (const sName of canonicalSkills) {
|
|
249
|
+
const bundle = await getSkillBundle(sName);
|
|
250
|
+
if (!bundle) continue;
|
|
251
|
+
const ideSkillFile = idePathFn(targetDir, sName);
|
|
252
|
+
await safeWriteFile(ideSkillFile, bundle.content.trim() + '\n', { dryRun, reporter, targetDir });
|
|
253
|
+
|
|
254
|
+
if (bundle.references && Object.keys(bundle.references).length > 0) {
|
|
255
|
+
const skillDir = path.dirname(ideSkillFile);
|
|
256
|
+
for (const [refName, refContent] of Object.entries(bundle.references)) {
|
|
257
|
+
const refFullPath = path.join(skillDir, 'references', refName);
|
|
258
|
+
await safeWriteFile(refFullPath, refContent, { dryRun, reporter, targetDir });
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Generate Kiro workflows, prompts, and rules
|
|
265
|
+
if (targetIdes.includes('kiro')) {
|
|
266
|
+
const kiroFiles = generateKiroFiles(targetDir, false);
|
|
267
|
+
for (const kf of kiroFiles) {
|
|
268
|
+
await safeWriteFile(kf.path, kf.content, { dryRun, reporter, targetDir });
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Generate Cursor rules & Cursor 2.0 rules
|
|
273
|
+
if (targetIdes.includes('cursor')) {
|
|
274
|
+
const cursorFiles = generateCursorFiles(targetDir);
|
|
275
|
+
for (const cf of cursorFiles) {
|
|
276
|
+
await safeWriteFile(cf.path, cf.content, { dryRun, reporter, targetDir });
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Generate Antigravity agent instructions & workspace rules
|
|
281
|
+
if (targetIdes.includes('antigravity')) {
|
|
282
|
+
const antigravityFiles = generateAntigravityFiles(targetDir);
|
|
283
|
+
for (const af of antigravityFiles) {
|
|
284
|
+
await safeWriteFile(af.path, af.content, { dryRun, reporter, targetDir });
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Generate Claude Code instructions & plugin manifest
|
|
289
|
+
if (targetIdes.includes('claude-code')) {
|
|
290
|
+
const claudeFiles = generateClaudeFiles(targetDir);
|
|
291
|
+
for (const clf of claudeFiles) {
|
|
292
|
+
await safeWriteFile(clf.path, clf.content, { dryRun, reporter, targetDir });
|
|
293
|
+
}
|
|
294
|
+
}
|
|
128
295
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
296
|
+
|
|
297
|
+
// 2. Install skills to Global IDE directory if scope is global, both, or all
|
|
298
|
+
if (installScope === 'global' || installScope === 'both' || installScope === 'all') {
|
|
299
|
+
const userHome = options.homeDir || process.env.PIXELCREW_HOME || os.homedir();
|
|
300
|
+
const globalProviders = installScope === 'all'
|
|
301
|
+
? Object.keys(GLOBAL_PROVIDER_PATHS)
|
|
302
|
+
: (options.provider && options.provider !== 'auto'
|
|
303
|
+
? (options.provider === 'all' ? Object.keys(GLOBAL_PROVIDER_PATHS) : [options.provider.toLowerCase() === 'claude' ? 'claude-code' : (options.provider.toLowerCase() === 'agents' ? 'antigravity' : options.provider.toLowerCase())])
|
|
304
|
+
: [activeIDE.id]);
|
|
305
|
+
|
|
306
|
+
for (const gp of globalProviders) {
|
|
307
|
+
const globalPathFn = GLOBAL_PROVIDER_PATHS[gp];
|
|
308
|
+
if (!globalPathFn) continue;
|
|
309
|
+
|
|
310
|
+
const canonicalSkills = getAllCanonicalSkillIds();
|
|
311
|
+
for (const sName of canonicalSkills) {
|
|
312
|
+
const bundle = await getSkillBundle(sName);
|
|
313
|
+
if (!bundle) continue;
|
|
314
|
+
const fullGlobalPath = globalPathFn(sName, userHome);
|
|
315
|
+
await safeWriteFile(fullGlobalPath, bundle.content.trim() + '\n', { dryRun, reporter, targetDir: userHome });
|
|
316
|
+
|
|
317
|
+
if (bundle.references && Object.keys(bundle.references).length > 0) {
|
|
318
|
+
const skillDir = path.dirname(fullGlobalPath);
|
|
319
|
+
for (const [refName, refContent] of Object.entries(bundle.references)) {
|
|
320
|
+
const refFullPath = path.join(skillDir, 'references', refName);
|
|
321
|
+
await safeWriteFile(refFullPath, refContent, { dryRun, reporter, targetDir: userHome });
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (globalProviders.includes('kiro')) {
|
|
328
|
+
const kiroGlobalFiles = generateKiroFiles(path.join(userHome, '.kiro'), true);
|
|
329
|
+
for (const kf of kiroGlobalFiles) {
|
|
330
|
+
await safeWriteFile(kf.path, kf.content, { dryRun, reporter, targetDir: userHome });
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (globalProviders.includes('claude-code')) {
|
|
335
|
+
const claudeGlobalFiles = generateClaudeFiles(path.join(userHome, '.claude'), true);
|
|
336
|
+
for (const clf of claudeGlobalFiles) {
|
|
337
|
+
await safeWriteFile(clf.path, clf.content, { dryRun, reporter, targetDir: userHome });
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (globalProviders.includes('cursor')) {
|
|
342
|
+
const cursorGlobalFiles = generateCursorFiles(path.join(userHome, '.cursor'), true);
|
|
343
|
+
for (const cf of cursorGlobalFiles) {
|
|
344
|
+
await safeWriteFile(cf.path, cf.content, { dryRun, reporter, targetDir: userHome });
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if (globalProviders.includes('antigravity')) {
|
|
349
|
+
const antigravityGlobalFiles = generateAntigravityFiles(path.join(userHome, '.gemini', 'config'), true);
|
|
350
|
+
for (const af of antigravityGlobalFiles) {
|
|
351
|
+
await safeWriteFile(af.path, af.content, { dryRun, reporter, targetDir: userHome });
|
|
352
|
+
}
|
|
145
353
|
}
|
|
146
354
|
}
|
|
147
355
|
|
|
148
|
-
|
|
149
|
-
|
|
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');
|
|
356
|
+
// Ensure workspace has clean .gitignore rules (ignoring .vite, .next, .turbo, logs, temp)
|
|
357
|
+
const gitignoreResult = await ensureGitignore(targetDir, { dryRun, reporter });
|
|
153
358
|
|
|
154
|
-
|
|
359
|
+
if (dryRun) {
|
|
360
|
+
reporter.print();
|
|
361
|
+
return {
|
|
362
|
+
dryRun: true,
|
|
363
|
+
reporter,
|
|
364
|
+
profile,
|
|
365
|
+
pixelCrewDir,
|
|
366
|
+
activeIDE,
|
|
367
|
+
installScope,
|
|
368
|
+
gitignore: gitignoreResult
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
console.log(' \x1b[32m✓\x1b[0m Created .pixel-crew/ (config.json, context.json, state.json, events.jsonl, pixel.json)');
|
|
373
|
+
console.log(` \x1b[32m✓\x1b[0m Created ${Object.keys(AGENT_MARKDOWNS).length} agent definitions in .pixel-crew/agents/`);
|
|
374
|
+
console.log(` \x1b[32m✓\x1b[0m Created ${Object.keys(SKILL_MARKDOWNS).length} skill definitions in .pixel-crew/skills/`);
|
|
375
|
+
if (installScope !== 'global' && targetIdes.length > 0) {
|
|
376
|
+
if (targetIdes.includes('kiro')) {
|
|
377
|
+
console.log(` \x1b[32m✓\x1b[0m Generated Kiro workflows & prompts (.kiro/workflows/, .kiro/prompts/, .kirorules)`);
|
|
378
|
+
}
|
|
379
|
+
if (targetIdes.includes('cursor')) {
|
|
380
|
+
console.log(` \x1b[32m✓\x1b[0m Generated Cursor rules (.cursorrules, .cursor/rules/pixelcrew.mdc)`);
|
|
381
|
+
}
|
|
382
|
+
if (targetIdes.includes('antigravity')) {
|
|
383
|
+
console.log(` \x1b[32m✓\x1b[0m Generated Antigravity agent instructions (AGENTS.md, GEMINI.md, .agents/rules/)`);
|
|
384
|
+
}
|
|
385
|
+
if (targetIdes.includes('claude-code')) {
|
|
386
|
+
console.log(` \x1b[32m✓\x1b[0m Generated Claude Code instructions (CLAUDE.md, .claude-plugin/)`);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
if (installScope === 'global' || installScope === 'both' || installScope === 'all') {
|
|
390
|
+
console.log(` \x1b[32m✓\x1b[0m Installed skills globally for \x1b[36m${activeIDE.name}\x1b[0m (\x1b[90m${activeIDE.globalPath}\x1b[0m)`);
|
|
391
|
+
}
|
|
392
|
+
if (gitignoreResult.created || gitignoreResult.updated) {
|
|
393
|
+
console.log(' \x1b[32m✓\x1b[0m Clean workspace configured in .gitignore (ignoring .vite/, .next/, build/ & cache directories)');
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const ideLabel = targetIdes.length === 1
|
|
397
|
+
? (targetIdes[0] === 'kiro' ? 'Kiro AI' : targetIdes[0] === 'cursor' ? 'Cursor IDE' : targetIdes[0] === 'antigravity' ? 'Antigravity' : 'Claude Code')
|
|
398
|
+
: (targetIdes.length > 1 ? 'AI IDE' : 'Pixel Crew');
|
|
399
|
+
|
|
400
|
+
console.log('\n\x1b[32m\x1b[1mPixel Crew initialized & adapted successfully!\x1b[0m\n');
|
|
401
|
+
console.log(`Ready in ${ideLabel} Chatbox:`);
|
|
402
|
+
console.log(' • Type \x1b[36minit\x1b[0m or \x1b[36m/pixelcrew init\x1b[0m in chat to adapt current workspace');
|
|
403
|
+
console.log(' • Type \x1b[36m/recap\x1b[0m in chat to get a token-optimized session changelog');
|
|
404
|
+
console.log(' • Type \x1b[36m/pixelcrew assemble "..."\x1b[0m to run full-stack multi-agent sprint');
|
|
405
|
+
console.log('\nCLI Commands:');
|
|
406
|
+
console.log(' \x1b[36mnpx pixelcrew start\x1b[0m Launch orchestration server');
|
|
407
|
+
console.log(' \x1b[36mnpx pixelcrew task "..."\x1b[0m Dispatch goal or full-stack task to agents');
|
|
408
|
+
console.log(' \x1b[36mnpx pixelcrew recap\x1b[0m Generate git activity and session recap');
|
|
409
|
+
console.log(' \x1b[36mnpx pixelcrew doctor\x1b[0m Check available coding agent providers');
|
|
410
|
+
console.log(' \x1b[36mnpx pixelcrew demo\x1b[0m Run interactive multi-agent visual demo\n');
|
|
411
|
+
|
|
412
|
+
return { pixelCrewDir, profile, gitignore: gitignoreResult };
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Ensures target workspace has clean ignore rules for .vite, .next, and build/cache folders
|
|
417
|
+
*/
|
|
418
|
+
export async function ensureGitignore(targetDir, { dryRun = false, reporter } = {}) {
|
|
419
|
+
const gitignorePath = path.join(targetDir, '.gitignore');
|
|
420
|
+
const requiredPatterns = [
|
|
421
|
+
'node_modules/',
|
|
422
|
+
'.vite/',
|
|
423
|
+
'.next/',
|
|
424
|
+
'.turbo/',
|
|
425
|
+
'dist/',
|
|
426
|
+
'build/',
|
|
427
|
+
'*.log',
|
|
428
|
+
'.DS_Store',
|
|
429
|
+
'.pixel-temp/',
|
|
430
|
+
'scratch/',
|
|
431
|
+
'tmp/'
|
|
432
|
+
];
|
|
433
|
+
|
|
434
|
+
let existingContent = '';
|
|
435
|
+
let exists = false;
|
|
436
|
+
try {
|
|
437
|
+
existingContent = await fs.readFile(gitignorePath, 'utf-8');
|
|
438
|
+
exists = true;
|
|
439
|
+
} catch {}
|
|
440
|
+
|
|
441
|
+
const lines = existingContent.split('\n').map(l => l.trim());
|
|
442
|
+
const missing = requiredPatterns.filter(p => !lines.includes(p));
|
|
443
|
+
|
|
444
|
+
if (!exists) {
|
|
445
|
+
const newContent = [
|
|
446
|
+
'# Dependencies',
|
|
447
|
+
'node_modules/',
|
|
448
|
+
'package-lock.json',
|
|
449
|
+
'',
|
|
450
|
+
'# Build and Cache Artifacts',
|
|
451
|
+
'.vite/',
|
|
452
|
+
'.next/',
|
|
453
|
+
'.turbo/',
|
|
454
|
+
'dist/',
|
|
455
|
+
'build/',
|
|
456
|
+
'',
|
|
457
|
+
'# Runtime & Workspace Temp',
|
|
458
|
+
'.pixel-temp/',
|
|
459
|
+
'scratch/',
|
|
460
|
+
'tmp/',
|
|
461
|
+
'',
|
|
462
|
+
'# Logs & OS',
|
|
463
|
+
'*.log',
|
|
464
|
+
'.DS_Store',
|
|
465
|
+
''
|
|
466
|
+
].join('\n');
|
|
467
|
+
|
|
468
|
+
await safeWriteFile(gitignorePath, newContent, { dryRun, reporter, targetDir });
|
|
469
|
+
return { created: true, updated: false, missing: requiredPatterns };
|
|
470
|
+
} else if (missing.length > 0) {
|
|
471
|
+
const addition = `\n# Build Caches & Workspace Temp\n${missing.join('\n')}\n`;
|
|
472
|
+
const updatedContent = existingContent.endsWith('\n') ? existingContent + addition : existingContent + '\n' + addition;
|
|
473
|
+
await safeWriteFile(gitignorePath, updatedContent, { dryRun, reporter, targetDir });
|
|
474
|
+
return { created: false, updated: true, missing };
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
return { created: false, updated: false, missing: [] };
|
|
155
478
|
}
|
|
479
|
+
|