pixelcrew 0.2.3 → 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 +632 -780
- package/src/orchestrator/design-engine.js +203 -0
- package/src/orchestrator/engine.js +307 -38
- package/src/orchestrator/oneshot.js +367 -380
- package/src/orchestrator/ontology.js +394 -0
- package/src/orchestrator/planner.js +231 -258
- 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/task-planner.js +111 -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 +283 -40
- package/src/utils/fs-safe.js +168 -0
- package/src/utils/markdown-report.js +175 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — /skills Command
|
|
3
|
+
*
|
|
4
|
+
* Lists all available skills in the registry, their categories, and targeted agents.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { PixelCommand } from './command.interface.js';
|
|
8
|
+
import { SKILL_DEFINITIONS } from '../orchestrator/skills-registry.js';
|
|
9
|
+
|
|
10
|
+
export class SkillsCommand extends PixelCommand {
|
|
11
|
+
constructor() {
|
|
12
|
+
super({
|
|
13
|
+
name: 'skills',
|
|
14
|
+
aliases: ['skillset'],
|
|
15
|
+
description: 'Show available skills, categories, and targeted agent capabilities',
|
|
16
|
+
usage: '/skills [category]',
|
|
17
|
+
category: 'inspection'
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async execute(context, args) {
|
|
22
|
+
const filterCategory = args[0]?.toLowerCase();
|
|
23
|
+
|
|
24
|
+
const outputLines = [
|
|
25
|
+
'╔══════════════════════════════════════════════════════════════════╗',
|
|
26
|
+
'║ PIXEL CREW — MODULAR SKILL REGISTRY ║',
|
|
27
|
+
'╚══════════════════════════════════════════════════════════════════╝',
|
|
28
|
+
''
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
const filtered = Object.values(SKILL_DEFINITIONS).filter(s => {
|
|
32
|
+
if (!filterCategory) return true;
|
|
33
|
+
return s.category === filterCategory;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const categories = {};
|
|
37
|
+
for (const skill of filtered) {
|
|
38
|
+
if (!categories[skill.category]) categories[skill.category] = [];
|
|
39
|
+
categories[skill.category].push(skill);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for (const [cat, list] of Object.entries(categories)) {
|
|
43
|
+
outputLines.push(`[${cat.toUpperCase()} SKILLS]`);
|
|
44
|
+
for (const s of list) {
|
|
45
|
+
outputLines.push(` • ${s.id.padEnd(28)} → ${s.name} (${s.description})`);
|
|
46
|
+
}
|
|
47
|
+
outputLines.push('');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
success: true,
|
|
52
|
+
message: `Found ${filtered.length} registered skills`,
|
|
53
|
+
data: { skills: filtered },
|
|
54
|
+
output: outputLines.join('\n')
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — /status Command
|
|
3
|
+
*
|
|
4
|
+
* Displays orchestration progress, active sprint metrics, and swarm state.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { PixelCommand } from './command.interface.js';
|
|
8
|
+
|
|
9
|
+
export class StatusCommand extends PixelCommand {
|
|
10
|
+
constructor() {
|
|
11
|
+
super({
|
|
12
|
+
name: 'status',
|
|
13
|
+
aliases: ['progress', 'info'],
|
|
14
|
+
description: 'Show orchestration sprint progress and active state',
|
|
15
|
+
usage: '/status',
|
|
16
|
+
category: 'inspection'
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async execute(context, args) {
|
|
21
|
+
const state = context.engine?.getState ? context.engine.getState() : {};
|
|
22
|
+
const config = context.engine?.getConfig ? context.engine.getConfig() : {};
|
|
23
|
+
|
|
24
|
+
const isRunning = state?.status === 'RUNNING';
|
|
25
|
+
const statusTag = isRunning ? '● RUNNING' : 'STANDBY';
|
|
26
|
+
|
|
27
|
+
const output = [
|
|
28
|
+
`╔══════════════════════════════════════════════════════════════════╗`,
|
|
29
|
+
`║ PIXEL CREW — SWARM ORCHESTRATION STATUS ║`,
|
|
30
|
+
`╚══════════════════════════════════════════════════════════════════╝`,
|
|
31
|
+
``,
|
|
32
|
+
`PROJECT: ${config?.project || 'my-app'}`,
|
|
33
|
+
`STATUS: ${statusTag}`,
|
|
34
|
+
`ACTIVE TASK: ${state?.activeTask || 'None'}`,
|
|
35
|
+
`STARTED: ${state?.startedAt ? new Date(state.startedAt).toLocaleTimeString() : 'N/A'}`,
|
|
36
|
+
`PROGRESS: ${state?.orchestrator?.progress || 0}%`,
|
|
37
|
+
``,
|
|
38
|
+
`ORCHESTRATOR EXPRESSION: ${state?.orchestrator?.expression || '◉_◉'}`
|
|
39
|
+
].join('\n');
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
success: true,
|
|
43
|
+
message: `Swarm is currently in ${state?.status || 'READY'} state`,
|
|
44
|
+
data: { state, config },
|
|
45
|
+
output
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — /stop & /resume Command
|
|
3
|
+
*
|
|
4
|
+
* Controls active swarm execution lifecycle (aborting or resuming sprints).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { PixelCommand } from './command.interface.js';
|
|
8
|
+
|
|
9
|
+
export class StopCommand extends PixelCommand {
|
|
10
|
+
constructor() {
|
|
11
|
+
super({
|
|
12
|
+
name: 'stop',
|
|
13
|
+
aliases: ['abort', 'cancel', 'halt'],
|
|
14
|
+
description: 'Stop or cancel active multi-agent orchestration sprint',
|
|
15
|
+
usage: '/stop',
|
|
16
|
+
category: 'lifecycle'
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async execute(context, args) {
|
|
21
|
+
if (context.engine?.cancelActiveExecution) {
|
|
22
|
+
context.engine.cancelActiveExecution();
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
success: true,
|
|
26
|
+
message: 'Active orchestration sprint aborted.',
|
|
27
|
+
output: 'Swarm stopped and returned to standby.'
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class ResumeCommand extends PixelCommand {
|
|
33
|
+
constructor() {
|
|
34
|
+
super({
|
|
35
|
+
name: 'resume',
|
|
36
|
+
aliases: ['unpause', 'continue'],
|
|
37
|
+
description: 'Resume paused orchestration sprint',
|
|
38
|
+
usage: '/resume',
|
|
39
|
+
category: 'lifecycle'
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async execute(context, args) {
|
|
44
|
+
return {
|
|
45
|
+
success: true,
|
|
46
|
+
message: 'Swarm ready to resume tasks.',
|
|
47
|
+
output: 'Standing by for new sprint tasks.'
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — /sync Command
|
|
3
|
+
*
|
|
4
|
+
* Synchronizes all workspace skills across detected agent environments (.claude, .cursor, .kiro, .agents).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { PixelCommand } from './command.interface.js';
|
|
8
|
+
import { syncSkills } from '../scaffold/installer.js';
|
|
9
|
+
import { DryRunReporter } from '../utils/fs-safe.js';
|
|
10
|
+
|
|
11
|
+
export class SyncCommand extends PixelCommand {
|
|
12
|
+
constructor() {
|
|
13
|
+
super({
|
|
14
|
+
name: 'sync',
|
|
15
|
+
aliases: ['sync-skills', 're-sync'],
|
|
16
|
+
description: 'Synchronize skills across all detected IDE agent folders',
|
|
17
|
+
usage: '/sync [--dry-run] [--provider <name>]',
|
|
18
|
+
category: 'scaffold'
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async execute(context = {}, args = []) {
|
|
23
|
+
const options = context.options || {};
|
|
24
|
+
const dryRun = args.includes('--dry-run') || Boolean(options.dryRun);
|
|
25
|
+
const providerArgIdx = args.findIndex(a => a === '--provider' || a === '-p');
|
|
26
|
+
const provider = providerArgIdx !== -1 && args[providerArgIdx + 1] ? args[providerArgIdx + 1] : (options.provider || null);
|
|
27
|
+
|
|
28
|
+
const targetDir = context.targetDir || process.cwd();
|
|
29
|
+
const reporter = new DryRunReporter(targetDir);
|
|
30
|
+
|
|
31
|
+
const result = await syncSkills(targetDir, {
|
|
32
|
+
dryRun,
|
|
33
|
+
provider,
|
|
34
|
+
reporter
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
if (dryRun) {
|
|
38
|
+
return {
|
|
39
|
+
success: true,
|
|
40
|
+
message: 'Dry-run preview for skill synchronization',
|
|
41
|
+
data: result,
|
|
42
|
+
output: reporter.formatOutput()
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const lines = [
|
|
47
|
+
`\x1b[32m\x1b[1m✓ Synchronized ${result.skillsSynced.length} skills across workspace:\x1b[0m`,
|
|
48
|
+
` \x1b[90mSkills:\x1b[0m ${result.skillsSynced.join(', ')}`
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
success: true,
|
|
53
|
+
message: `Successfully synchronized ${result.skillsSynced.length} skills`,
|
|
54
|
+
data: result,
|
|
55
|
+
output: lines.join('\n')
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — /typeset Command
|
|
3
|
+
*
|
|
4
|
+
* Fixes font choices, font pairings, and applies mathematical fluid clamp() typography scales.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { PixelCommand } from './command.interface.js';
|
|
8
|
+
|
|
9
|
+
export class TypesetCommand extends PixelCommand {
|
|
10
|
+
constructor() {
|
|
11
|
+
super({
|
|
12
|
+
name: 'typeset',
|
|
13
|
+
aliases: ['typography', 'fonts'],
|
|
14
|
+
description: 'Fix font pairings, hierarchy, and apply mathematical fluid clamp() scales',
|
|
15
|
+
usage: '/typeset [font-preset]',
|
|
16
|
+
category: 'design'
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async execute(context, args = []) {
|
|
21
|
+
const preset = args[0] || 'editorial-tech';
|
|
22
|
+
|
|
23
|
+
const scales = {
|
|
24
|
+
hero: 'clamp(2.5rem, 5vw + 1rem, 4.5rem)',
|
|
25
|
+
h1: 'clamp(2rem, 3.5vw + 1rem, 3rem)',
|
|
26
|
+
h2: 'clamp(1.5rem, 2.5vw + 0.5rem, 2.25rem)',
|
|
27
|
+
h3: 'clamp(1.25rem, 1.5vw + 0.5rem, 1.75rem)',
|
|
28
|
+
body: 'clamp(1rem, 0.5vw + 0.75rem, 1.125rem)',
|
|
29
|
+
small: '0.875rem'
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const lines = [
|
|
33
|
+
'╔══════════════════════════════════════════════════════════════════╗',
|
|
34
|
+
'║ PIXEL CREW — MATHEMATICAL FLUID TYPOGRAPHY ENGINE ║',
|
|
35
|
+
'╚══════════════════════════════════════════════════════════════════╝',
|
|
36
|
+
'',
|
|
37
|
+
`\x1b[32m[DESIGN SYSTEM ARCHITECT]\x1b[0m Applied Font Preset: \x1b[36m${preset}\x1b[0m`,
|
|
38
|
+
' • Display Serif/Geometric: "Outfit", sans-serif (Tight letter-spacing: -0.025em)',
|
|
39
|
+
' • Technical Body: "Inter", -apple-system, sans-serif',
|
|
40
|
+
' • Telemetry Mono: "JetBrains Mono", monospace',
|
|
41
|
+
'',
|
|
42
|
+
'\x1b[1mCALCULATED FLUID CLAMP SCALES:\x1b[0m',
|
|
43
|
+
` • Hero Display: ${scales.hero}`,
|
|
44
|
+
` • Primary (H1): ${scales.h1}`,
|
|
45
|
+
` • Section (H2): ${scales.h2}`,
|
|
46
|
+
` • Body Text: ${scales.body}`,
|
|
47
|
+
'',
|
|
48
|
+
'\x1b[32m✓ Expressive typography scales and pairings compiled.\x1b[0m'
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
success: true,
|
|
53
|
+
message: `Applied typography preset: ${preset}`,
|
|
54
|
+
data: { preset, scales },
|
|
55
|
+
output: lines.join('\n')
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — /warp Command
|
|
3
|
+
*
|
|
4
|
+
* Full-stack performance speedrun: streaming SSR, bundle minification, and AST prompt caching.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { PixelCommand } from './command.interface.js';
|
|
8
|
+
import { OptimizeCommand } from './optimize.js';
|
|
9
|
+
|
|
10
|
+
export class WarpCommand extends PixelCommand {
|
|
11
|
+
constructor() {
|
|
12
|
+
super({
|
|
13
|
+
name: 'warp',
|
|
14
|
+
aliases: ['optimize', 'perf', 'speed', 'turbo'],
|
|
15
|
+
description: 'Floor 42 Warp Speed: Streaming SSR, bundle minification, and AST token caching',
|
|
16
|
+
usage: '/warp',
|
|
17
|
+
category: 'performance'
|
|
18
|
+
});
|
|
19
|
+
this.optimizeCmd = new OptimizeCommand();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async execute(context, args = []) {
|
|
23
|
+
return await this.optimizeCmd.execute(context, args);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Agent Runtime Execution Engine
|
|
3
|
+
*
|
|
4
|
+
* Manages the lifecycle of task execution on assigned Agent Adapters.
|
|
5
|
+
* Handles timeouts, cancellation signals, skill injection, and progress telemetry.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { EVENT_TYPES } from '../protocol/event.js';
|
|
9
|
+
import { TASK_STATUS } from '../protocol/task.js';
|
|
10
|
+
|
|
11
|
+
export class AgentRuntime {
|
|
12
|
+
constructor(options = {}) {
|
|
13
|
+
this.eventBus = options.eventBus || null;
|
|
14
|
+
this.defaultTimeoutMs = options.defaultTimeoutMs || 120000;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
setEventBus(eventBus) {
|
|
18
|
+
this.eventBus = eventBus;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Executes a single AgentTask on the provided adapter
|
|
23
|
+
*/
|
|
24
|
+
async executeTask(task, adapter, runtimeContext = {}) {
|
|
25
|
+
const startTime = Date.now();
|
|
26
|
+
const abortController = runtimeContext.abortController || new AbortController();
|
|
27
|
+
|
|
28
|
+
const emit = async (eventType, message, data = {}) => {
|
|
29
|
+
if (!this.eventBus) return;
|
|
30
|
+
await this.eventBus.emitEvent({
|
|
31
|
+
agent: task.agent,
|
|
32
|
+
type: eventType,
|
|
33
|
+
taskId: task.id,
|
|
34
|
+
taskName: task.title,
|
|
35
|
+
provider: adapter?.id || 'generic',
|
|
36
|
+
message,
|
|
37
|
+
data
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
task.status = TASK_STATUS.RUNNING;
|
|
43
|
+
task.assignedProvider = adapter?.id || 'generic';
|
|
44
|
+
|
|
45
|
+
await emit(EVENT_TYPES.AGENT_STARTED, `Activated agent for task: ${task.title}`, {
|
|
46
|
+
skills: task.skills,
|
|
47
|
+
provider: adapter?.name || adapter?.id
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Announce activated skills
|
|
51
|
+
for (const skill of task.skills) {
|
|
52
|
+
await emit(EVENT_TYPES.SKILL_ACTIVATED, `Applying skill: ${skill}`, { skill });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Execute on adapter
|
|
56
|
+
let result;
|
|
57
|
+
if (adapter && typeof adapter.execute === 'function') {
|
|
58
|
+
result = await adapter.execute(task, {
|
|
59
|
+
...runtimeContext,
|
|
60
|
+
emit,
|
|
61
|
+
signal: abortController.signal
|
|
62
|
+
});
|
|
63
|
+
} else if (runtimeContext.executeTaskHandler) {
|
|
64
|
+
result = await runtimeContext.executeTaskHandler(task, emit);
|
|
65
|
+
} else {
|
|
66
|
+
// Fallback simulation delay
|
|
67
|
+
await new Promise(r => setTimeout(r, 300));
|
|
68
|
+
result = { success: true, message: `Completed task ${task.id} via generic runner` };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
task.status = TASK_STATUS.COMPLETED;
|
|
72
|
+
task.result = result;
|
|
73
|
+
task.updatedAt = Date.now();
|
|
74
|
+
|
|
75
|
+
await emit(EVENT_TYPES.TASK_COMPLETED, `Completed: ${task.title} (${Date.now() - startTime}ms)`, {
|
|
76
|
+
durationMs: Date.now() - startTime,
|
|
77
|
+
result
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
return result;
|
|
81
|
+
} catch (err) {
|
|
82
|
+
task.status = TASK_STATUS.FAILED;
|
|
83
|
+
task.error = err.message;
|
|
84
|
+
task.updatedAt = Date.now();
|
|
85
|
+
|
|
86
|
+
await emit(EVENT_TYPES.TASK_FAILED, `Failed: ${task.title} — ${err.message}`, {
|
|
87
|
+
durationMs: Date.now() - startTime,
|
|
88
|
+
error: err.message
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
throw err;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Core Event Bus & Telemetry Stream
|
|
3
|
+
*
|
|
4
|
+
* Provides unified pub/sub, append-only disk logging, and live SSE multiplexing.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { EventEmitter } from 'node:events';
|
|
8
|
+
import fs from 'node:fs/promises';
|
|
9
|
+
import fsSync from 'node:fs';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
import { createEvent, serializeEvent, EVENT_TYPES } from '../protocol/event.js';
|
|
12
|
+
|
|
13
|
+
export class EventBus extends EventEmitter {
|
|
14
|
+
constructor(options = {}) {
|
|
15
|
+
super();
|
|
16
|
+
this.maxHistory = options.maxHistory || 300;
|
|
17
|
+
this.history = [];
|
|
18
|
+
this.logFilePaths = options.logFilePaths || [];
|
|
19
|
+
this.isPersisting = false;
|
|
20
|
+
this.pendingWrites = [];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
addLogFilePath(filePath) {
|
|
24
|
+
if (filePath && !this.logFilePaths.includes(filePath)) {
|
|
25
|
+
this.logFilePaths.push(filePath);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Publishes an event to memory, emits to listeners, and asynchronously writes to disk
|
|
31
|
+
*/
|
|
32
|
+
async emitEvent(eventInput) {
|
|
33
|
+
const event = eventInput?.id && eventInput?.timestamp ? eventInput : createEvent(eventInput);
|
|
34
|
+
|
|
35
|
+
this.history.push(event);
|
|
36
|
+
if (this.history.length > this.maxHistory) {
|
|
37
|
+
this.history.shift();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Emit typed and generic events
|
|
41
|
+
this.emit('event', event);
|
|
42
|
+
this.emit(event.type || 'progress', event);
|
|
43
|
+
|
|
44
|
+
// Queue for disk persistence
|
|
45
|
+
if (this.logFilePaths.length > 0) {
|
|
46
|
+
this.pendingWrites.push(serializeEvent(event) + '\n');
|
|
47
|
+
this.flushLogs().catch(() => {});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return event;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
getHistory(limit = 100) {
|
|
54
|
+
return this.history.slice(-limit);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
clearHistory() {
|
|
58
|
+
this.history = [];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async flushLogs() {
|
|
62
|
+
if (this.isPersisting || this.pendingWrites.length === 0) return;
|
|
63
|
+
this.isPersisting = true;
|
|
64
|
+
|
|
65
|
+
const chunk = this.pendingWrites.join('');
|
|
66
|
+
this.pendingWrites = [];
|
|
67
|
+
|
|
68
|
+
for (const logPath of this.logFilePaths) {
|
|
69
|
+
try {
|
|
70
|
+
await fs.mkdir(path.dirname(logPath), { recursive: true });
|
|
71
|
+
await fs.appendFile(logPath, chunk, 'utf-8');
|
|
72
|
+
} catch (err) {
|
|
73
|
+
// Disk write fallback or ignore
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
this.isPersisting = false;
|
|
78
|
+
if (this.pendingWrites.length > 0) {
|
|
79
|
+
setImmediate(() => this.flushLogs());
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async loadFromDisk(filePath) {
|
|
84
|
+
try {
|
|
85
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
86
|
+
const lines = content.split('\n').filter(Boolean);
|
|
87
|
+
for (const line of lines) {
|
|
88
|
+
try {
|
|
89
|
+
const evt = JSON.parse(line);
|
|
90
|
+
this.history.push(evt);
|
|
91
|
+
} catch {}
|
|
92
|
+
}
|
|
93
|
+
if (this.history.length > this.maxHistory) {
|
|
94
|
+
this.history = this.history.slice(-this.maxHistory);
|
|
95
|
+
}
|
|
96
|
+
} catch {}
|
|
97
|
+
}
|
|
98
|
+
}
|