pixelcrew 0.2.2 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +389 -315
- package/bin/pixel-agents.js +306 -149
- package/package.json +3 -1
- package/skill/SKILL.md +185 -0
- package/skill/references/anti-ai-rubric.md +30 -0
- package/skill/references/anti-ai-slop-encyclopedia.md +181 -0
- package/skill/references/commands-reference.md +135 -0
- package/skill/references/testing-and-qa-strategy.md +25 -0
- package/skill/references/token-efficiency.md +20 -0
- package/src/adapters/adapter.interface.js +77 -0
- package/src/adapters/antigravity.js +138 -0
- package/src/adapters/claude-code.js +149 -0
- package/src/adapters/codex.js +131 -0
- package/src/adapters/cursor.js +133 -0
- package/src/adapters/generic.js +63 -0
- package/src/adapters/index.js +15 -0
- package/src/adapters/kiro.js +134 -0
- package/src/adapters/registry.js +150 -0
- package/src/backend/analyzer/complexity-analyzer.js +104 -0
- package/src/backend/analyzer/requirement-analyzer.js +213 -0
- package/src/backend/analyzer/threat-analyzer.js +122 -0
- package/src/backend/api/api-designer.js +90 -0
- package/src/backend/api/error-contract.js +132 -0
- package/src/backend/api/route-generator.js +92 -0
- package/src/backend/api/schema-generator.js +64 -0
- package/src/backend/architecture/adr-generator.js +62 -0
- package/src/backend/architecture/architecture-reasoner.js +119 -0
- package/src/backend/architecture/architecture-selector.js +57 -0
- package/src/backend/architecture/tradeoff-analyzer.js +92 -0
- package/src/backend/data/data-modeler.js +114 -0
- package/src/backend/data/index-analyzer.js +93 -0
- package/src/backend/data/query-analyzer.js +41 -0
- package/src/backend/data/schema-generator.js +92 -0
- package/src/backend/data/transaction-analyzer.js +49 -0
- package/src/backend/index.js +67 -0
- package/src/backend/observability/logging-engine.js +80 -0
- package/src/backend/observability/metrics-engine.js +31 -0
- package/src/backend/observability/tracing-engine.js +16 -0
- package/src/backend/patterns/pattern-registry.js +74 -0
- package/src/backend/patterns/pattern-selector.js +39 -0
- package/src/backend/patterns/tradeoff-engine.js +17 -0
- package/src/backend/performance/cache-analyzer.js +31 -0
- package/src/backend/performance/concurrency-analyzer.js +34 -0
- package/src/backend/performance/performance-engine.js +98 -0
- package/src/backend/performance/query-optimizer.js +16 -0
- package/src/backend/reliability/failure-analyzer.js +22 -0
- package/src/backend/reliability/idempotency-engine.js +56 -0
- package/src/backend/reliability/resilience-engine.js +141 -0
- package/src/backend/reliability/retry-analyzer.js +15 -0
- package/src/backend/security/auth-selector.js +33 -0
- package/src/backend/security/authorization-engine.js +90 -0
- package/src/backend/security/policy-engine.js +49 -0
- package/src/backend/security/secret-analyzer.js +39 -0
- package/src/backend/security/security-engine.js +122 -0
- package/src/backend/security/threat-model.js +59 -0
- package/src/backend/synthesis/backend-synthesizer.js +98 -0
- package/src/backend/synthesis/infrastructure-synthesizer.js +108 -0
- package/src/backend/synthesis/module-synthesizer.js +262 -0
- package/src/backend/validation/architecture-validator.js +70 -0
- package/src/backend/validation/backend-quality-validator.js +71 -0
- package/src/backend/validation/dependency-validator.js +20 -0
- package/src/backend/validation/performance-validator.js +38 -0
- package/src/backend/validation/security-validator.js +73 -0
- package/src/commands/adapt.js +105 -0
- package/src/commands/add.js +78 -0
- package/src/commands/animate.js +48 -0
- package/src/commands/assemble.js +57 -0
- package/src/commands/audit.js +93 -0
- package/src/commands/backend.js +125 -0
- package/src/commands/bento.js +25 -0
- package/src/commands/blueprint.js +65 -0
- package/src/commands/bolder.js +48 -0
- package/src/commands/boss-fight.js +60 -0
- package/src/commands/build.js +39 -0
- package/src/commands/calibrate.js +25 -0
- package/src/commands/chromatic.js +25 -0
- package/src/commands/clarify.js +52 -0
- package/src/commands/colorize.js +57 -0
- package/src/commands/command.interface.js +28 -0
- package/src/commands/commands.js +84 -0
- package/src/commands/craft.js +57 -0
- package/src/commands/crew.js +66 -0
- package/src/commands/critique.js +25 -0
- package/src/commands/de-slop.js +25 -0
- package/src/commands/delight.js +46 -0
- package/src/commands/deploy.js +42 -0
- package/src/commands/distill.js +48 -0
- package/src/commands/doctor.js +89 -0
- package/src/commands/document.js +83 -0
- package/src/commands/eight-bit.js +25 -0
- package/src/commands/extract.js +75 -0
- package/src/commands/fix.js +46 -0
- package/src/commands/harden.js +85 -0
- package/src/commands/index.js +67 -0
- package/src/commands/install.js +75 -0
- package/src/commands/layout.js +48 -0
- package/src/commands/live.js +44 -0
- package/src/commands/manifest.js +25 -0
- package/src/commands/office.js +25 -0
- package/src/commands/onboard.js +46 -0
- package/src/commands/oneshot.js +60 -0
- package/src/commands/optimize.js +46 -0
- package/src/commands/overdrive.js +46 -0
- package/src/commands/parser.js +143 -0
- package/src/commands/pixelcrew.js +96 -0
- package/src/commands/plan.js +66 -0
- package/src/commands/polish.js +45 -0
- package/src/commands/quieter.js +48 -0
- package/src/commands/recap.js +358 -0
- package/src/commands/registry.js +353 -0
- package/src/commands/render.js +26 -0
- package/src/commands/retrofit.js +25 -0
- package/src/commands/review.js +118 -0
- package/src/commands/roster.js +25 -0
- package/src/commands/sentinel.js +25 -0
- package/src/commands/shape.js +66 -0
- package/src/commands/skills.js +57 -0
- package/src/commands/status.js +48 -0
- package/src/commands/stop.js +50 -0
- package/src/commands/sync.js +58 -0
- package/src/commands/typeset.js +58 -0
- package/src/commands/warp.js +25 -0
- package/src/core/agent-runtime.js +94 -0
- package/src/core/event-bus.js +98 -0
- package/src/core/index.js +9 -0
- package/src/core/orchestrator.js +234 -0
- package/src/core/scheduler.js +124 -0
- package/src/core/task-graph.js +185 -0
- package/src/dashboard/app.js +1172 -30
- package/src/dashboard/index.html +223 -23
- package/src/dashboard/styles.css +870 -0
- package/src/index.js +16 -0
- package/src/orchestrator/artifact-graph.js +104 -0
- package/src/orchestrator/ast-normalizer.js +147 -0
- package/src/orchestrator/code-generator.js +846 -0
- package/src/orchestrator/design-engine.js +203 -0
- package/src/orchestrator/engine.js +318 -39
- package/src/orchestrator/oneshot.js +351 -1561
- package/src/orchestrator/ontology.js +394 -0
- package/src/orchestrator/planner.js +302 -0
- package/src/orchestrator/repair-planner.js +67 -0
- package/src/orchestrator/requirement-contract.js +177 -0
- package/src/orchestrator/requirement-validator.js +39 -0
- package/src/orchestrator/semantic-engine.js +582 -0
- package/src/orchestrator/semantic-reviewer.js +179 -0
- package/src/orchestrator/skills-registry.js +194 -0
- package/src/orchestrator/task-planner.js +111 -0
- package/src/orchestrator/task-queue.js +128 -0
- package/src/orchestrator/telemetry.js +209 -0
- package/src/orchestrator/ui-synthesizer.js +245 -0
- package/src/orchestrator/visual-critic.js +106 -0
- package/src/policies/architecture/layering.policy.js +14 -0
- package/src/policies/performance/indexing.policy.js +13 -0
- package/src/policies/reliability/resilience.policy.js +13 -0
- package/src/policies/security/auth.policy.js +31 -0
- package/src/protocol/agent.js +124 -0
- package/src/protocol/event.js +78 -0
- package/src/protocol/index.js +8 -0
- package/src/protocol/skill.js +54 -0
- package/src/protocol/task.js +100 -0
- package/src/scaffold/claude-generator.js +60 -0
- package/src/scaffold/commands-catalog.js +321 -0
- package/src/scaffold/cursor-generator.js +74 -0
- package/src/scaffold/ide-rules.js +133 -0
- package/src/scaffold/init.js +415 -91
- package/src/scaffold/installer.js +571 -0
- package/src/scaffold/kiro-generator.js +86 -0
- package/src/scaffold/skills-bundle.js +520 -0
- package/src/scaffold/templates.js +57 -4
- package/src/scaffold/workstations.js +364 -0
- package/src/server/server.js +292 -42
- package/src/utils/fs-safe.js +168 -0
- package/src/utils/markdown-report.js +175 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Universal Agent Adapter Interface
|
|
3
|
+
*
|
|
4
|
+
* Abstract contract implemented by every coding agent execution environment
|
|
5
|
+
* (Claude Code, Codex, Cursor, Kiro, Antigravity, and Generic CLI).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { normalizeCapabilities } from '../protocol/agent.js';
|
|
9
|
+
|
|
10
|
+
export class AgentAdapter {
|
|
11
|
+
constructor(id, name, options = {}) {
|
|
12
|
+
if (!id || !name) {
|
|
13
|
+
throw new Error('AgentAdapter must have an id and name');
|
|
14
|
+
}
|
|
15
|
+
this.id = id;
|
|
16
|
+
this.name = name;
|
|
17
|
+
this.icon = options.icon || '🤖';
|
|
18
|
+
this.description = options.description || '';
|
|
19
|
+
this.capabilities = normalizeCapabilities(options.capabilities || {});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Returns a confidence score for whether this provider is currently active
|
|
24
|
+
* (>= 1000: active runtime session, >= 200: workspace config, >= 50: installed app/cli, 0: not detected)
|
|
25
|
+
* @param {string} targetDir
|
|
26
|
+
* @returns {Promise<number>}
|
|
27
|
+
*/
|
|
28
|
+
async detectScore(targetDir = process.cwd()) {
|
|
29
|
+
const isDetected = await this.detect(targetDir);
|
|
30
|
+
return isDetected ? 100 : 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Detects if this provider/IDE is available in the current environment
|
|
35
|
+
* @param {string} targetDir
|
|
36
|
+
* @returns {Promise<boolean>}
|
|
37
|
+
*/
|
|
38
|
+
async detect(targetDir = process.cwd()) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Returns normalized capabilities of this agent provider
|
|
44
|
+
* @returns {Promise<import('../protocol/agent.js').AgentCapabilities>}
|
|
45
|
+
*/
|
|
46
|
+
async getCapabilities() {
|
|
47
|
+
return this.capabilities;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Executes a standard AgentTask on this provider
|
|
52
|
+
* @param {import('../protocol/task.js').AgentTask} task
|
|
53
|
+
* @param {object} context
|
|
54
|
+
* @returns {Promise<any>}
|
|
55
|
+
*/
|
|
56
|
+
async execute(task, context = {}) {
|
|
57
|
+
throw new Error(`execute() not implemented for adapter: ${this.name}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Cancels a running task on this provider
|
|
62
|
+
* @param {string} taskId
|
|
63
|
+
* @returns {Promise<void>}
|
|
64
|
+
*/
|
|
65
|
+
async cancel(taskId) {
|
|
66
|
+
// Optional cancel override
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Returns current status of a running task on this provider
|
|
71
|
+
* @param {string} taskId
|
|
72
|
+
* @returns {Promise<{ status: string, progress?: number }>}
|
|
73
|
+
*/
|
|
74
|
+
async getStatus(taskId) {
|
|
75
|
+
return { status: 'unknown' };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Antigravity Adapter
|
|
3
|
+
*
|
|
4
|
+
* Execution adapter for Google Antigravity (AGY) SDK, IDE, and subagent sidecars.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fs from 'node:fs/promises';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import os from 'node:os';
|
|
10
|
+
import { spawn } from 'node:child_process';
|
|
11
|
+
import { AgentAdapter } from './adapter.interface.js';
|
|
12
|
+
|
|
13
|
+
export class AntigravityAdapter extends AgentAdapter {
|
|
14
|
+
constructor(options = {}) {
|
|
15
|
+
super('antigravity', 'Google Antigravity', {
|
|
16
|
+
icon: '🪐',
|
|
17
|
+
description: 'Google Antigravity SDK & Advanced Agentic Coding environment',
|
|
18
|
+
capabilities: {
|
|
19
|
+
fileAccess: true,
|
|
20
|
+
terminalAccess: true,
|
|
21
|
+
subagents: true,
|
|
22
|
+
backgroundTasks: true,
|
|
23
|
+
streaming: true,
|
|
24
|
+
toolCalls: true
|
|
25
|
+
},
|
|
26
|
+
...options
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async detectScore(targetDir = process.cwd()) {
|
|
31
|
+
let score = 0;
|
|
32
|
+
|
|
33
|
+
// 1. Active Antigravity session / IDE environment variables (+1000 points)
|
|
34
|
+
if (
|
|
35
|
+
process.env.ANTIGRAVITY_AGENT ||
|
|
36
|
+
process.env.ANTIGRAVITY_CONVERSATION_ID ||
|
|
37
|
+
process.env.ANTIGRAVITY_EDITOR_APP_ROOT ||
|
|
38
|
+
process.env.ANTIGRAVITY_APP_DIR ||
|
|
39
|
+
process.env.ANTIGRAVITY_TRAJECTORY_ID ||
|
|
40
|
+
process.env.ANTIGRAVITY_LS_ADDRESS ||
|
|
41
|
+
process.env.AGY_SESSION ||
|
|
42
|
+
process.env.ANTIGRAVITY ||
|
|
43
|
+
process.env.AGY ||
|
|
44
|
+
process.env.AGY_WORKSPACE ||
|
|
45
|
+
process.env.GEMINI_CLI
|
|
46
|
+
) {
|
|
47
|
+
score += 1000;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 2. Workspace indicators (.agents/, .agent/, .gemini/, GEMINI.md, AGENTS.md) (+200 points)
|
|
51
|
+
const indicators = ['.agents', '.agent', '.gemini', 'GEMINI.md', 'AGENTS.md'];
|
|
52
|
+
for (const item of indicators) {
|
|
53
|
+
try {
|
|
54
|
+
await fs.access(path.join(targetDir, item));
|
|
55
|
+
score += 200;
|
|
56
|
+
break;
|
|
57
|
+
} catch {}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 3. User home directory (~/.gemini, ~/.agents, ~/.config/antigravity) (+50 points)
|
|
61
|
+
try {
|
|
62
|
+
const home = os.homedir();
|
|
63
|
+
if (home) {
|
|
64
|
+
try {
|
|
65
|
+
await fs.access(path.join(home, '.gemini'));
|
|
66
|
+
score += 50;
|
|
67
|
+
} catch {}
|
|
68
|
+
try {
|
|
69
|
+
await fs.access(path.join(home, '.agents'));
|
|
70
|
+
score += 50;
|
|
71
|
+
} catch {}
|
|
72
|
+
}
|
|
73
|
+
} catch {}
|
|
74
|
+
|
|
75
|
+
// 4. macOS Application bundle (+30 points)
|
|
76
|
+
if (process.platform === 'darwin') {
|
|
77
|
+
const macApps = [
|
|
78
|
+
'/Applications/Antigravity.app',
|
|
79
|
+
path.join(os.homedir() || '', 'Applications', 'Antigravity.app'),
|
|
80
|
+
'/Applications/Google Antigravity.app'
|
|
81
|
+
];
|
|
82
|
+
for (const appPath of macApps) {
|
|
83
|
+
try {
|
|
84
|
+
await fs.access(appPath);
|
|
85
|
+
score += 30;
|
|
86
|
+
break;
|
|
87
|
+
} catch {}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// 5. Binary CLI in PATH (+30 points)
|
|
92
|
+
const binaries = ['agy', 'antigravity', 'gemini', 'google-antigravity'];
|
|
93
|
+
for (const bin of binaries) {
|
|
94
|
+
const isFound = await new Promise((resolve) => {
|
|
95
|
+
try {
|
|
96
|
+
const cmd = process.platform === 'win32' ? 'where' : 'which';
|
|
97
|
+
const proc = spawn(cmd, [bin], { stdio: 'ignore' });
|
|
98
|
+
proc.on('close', (code) => resolve(code === 0));
|
|
99
|
+
proc.on('error', () => resolve(false));
|
|
100
|
+
} catch {
|
|
101
|
+
resolve(false);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
if (isFound) {
|
|
105
|
+
score += 30;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return score;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async detect(targetDir = process.cwd()) {
|
|
114
|
+
const score = await this.detectScore(targetDir);
|
|
115
|
+
return score > 0;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async execute(task, context = {}) {
|
|
119
|
+
const { emit = () => {}, signal } = context;
|
|
120
|
+
|
|
121
|
+
if (signal?.aborted) {
|
|
122
|
+
throw new Error(`Task ${task.id} cancelled before start`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
await emit('tool.invoked', `Antigravity agent executing task: ${task.title}`);
|
|
126
|
+
|
|
127
|
+
if (context.executeTaskHandler) {
|
|
128
|
+
return await context.executeTaskHandler(task, emit);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
await new Promise(r => setTimeout(r, 200));
|
|
132
|
+
return {
|
|
133
|
+
success: true,
|
|
134
|
+
provider: this.id,
|
|
135
|
+
taskId: task.id
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Claude Code Adapter
|
|
3
|
+
*
|
|
4
|
+
* Execution adapter for Anthropic Claude Code CLI.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fs from 'node:fs/promises';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import os from 'node:os';
|
|
10
|
+
import { spawn } from 'node:child_process';
|
|
11
|
+
import { AgentAdapter } from './adapter.interface.js';
|
|
12
|
+
|
|
13
|
+
export class ClaudeCodeAdapter extends AgentAdapter {
|
|
14
|
+
constructor(options = {}) {
|
|
15
|
+
super('claude-code', 'Claude Code', {
|
|
16
|
+
icon: '🤖',
|
|
17
|
+
description: 'Anthropic Claude Code CLI & autonomous agent runtime',
|
|
18
|
+
capabilities: {
|
|
19
|
+
fileAccess: true,
|
|
20
|
+
terminalAccess: true,
|
|
21
|
+
subagents: true,
|
|
22
|
+
backgroundTasks: true,
|
|
23
|
+
streaming: true,
|
|
24
|
+
toolCalls: true
|
|
25
|
+
},
|
|
26
|
+
...options
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async detectScore(targetDir = process.cwd()) {
|
|
31
|
+
let score = 0;
|
|
32
|
+
|
|
33
|
+
// 1. Environment variables (Active Claude Code session) (+1000 points)
|
|
34
|
+
if (
|
|
35
|
+
process.env.CLAUDE_CODE ||
|
|
36
|
+
process.env.CLAUDE_AGENT ||
|
|
37
|
+
process.env.CLAUDE_SESSION ||
|
|
38
|
+
process.env.CLAUDE_WORKSPACE ||
|
|
39
|
+
process.env.CLAUDE_APP_DIR
|
|
40
|
+
) {
|
|
41
|
+
score += 1000;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 2. Workspace indicators (.claude/, .claude-plugin/, CLAUDE.md, claude.json, .claude.json) (+200 points)
|
|
45
|
+
const indicators = ['.claude', '.claude-plugin', 'CLAUDE.md', 'claude.json', '.claude.json'];
|
|
46
|
+
for (const item of indicators) {
|
|
47
|
+
try {
|
|
48
|
+
await fs.access(path.join(targetDir, item));
|
|
49
|
+
score += 200;
|
|
50
|
+
break;
|
|
51
|
+
} catch {}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 3. User home directory (~/.claude, ~/.claude.json) (+50 points)
|
|
55
|
+
try {
|
|
56
|
+
const home = os.homedir();
|
|
57
|
+
if (home) {
|
|
58
|
+
try {
|
|
59
|
+
await fs.access(path.join(home, '.claude'));
|
|
60
|
+
score += 50;
|
|
61
|
+
} catch {}
|
|
62
|
+
try {
|
|
63
|
+
await fs.access(path.join(home, '.claude.json'));
|
|
64
|
+
score += 50;
|
|
65
|
+
} catch {}
|
|
66
|
+
}
|
|
67
|
+
} catch {}
|
|
68
|
+
|
|
69
|
+
// 4. macOS Application bundle detection (+30 points)
|
|
70
|
+
if (process.platform === 'darwin') {
|
|
71
|
+
const macApps = [
|
|
72
|
+
'/Applications/Claude.app',
|
|
73
|
+
path.join(os.homedir() || '', 'Applications', 'Claude.app'),
|
|
74
|
+
'/Applications/Claude Code.app'
|
|
75
|
+
];
|
|
76
|
+
for (const appPath of macApps) {
|
|
77
|
+
try {
|
|
78
|
+
await fs.access(appPath);
|
|
79
|
+
score += 30;
|
|
80
|
+
break;
|
|
81
|
+
} catch {}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 5. Binary CLI in PATH (claude, claude-code, claude-cli) (+30 points)
|
|
86
|
+
const binaries = ['claude', 'claude-code', 'claude-cli'];
|
|
87
|
+
for (const bin of binaries) {
|
|
88
|
+
const isFound = await new Promise((resolve) => {
|
|
89
|
+
try {
|
|
90
|
+
const cmd = process.platform === 'win32' ? 'where' : 'which';
|
|
91
|
+
const proc = spawn(cmd, [bin], { stdio: 'ignore' });
|
|
92
|
+
proc.on('close', (code) => resolve(code === 0));
|
|
93
|
+
proc.on('error', () => resolve(false));
|
|
94
|
+
} catch {
|
|
95
|
+
resolve(false);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
if (isFound) {
|
|
99
|
+
score += 30;
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return score;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async detect(targetDir = process.cwd()) {
|
|
108
|
+
const score = await this.detectScore(targetDir);
|
|
109
|
+
return score > 0;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Translates universal AgentTask to Claude Code prompt format
|
|
114
|
+
*/
|
|
115
|
+
formatTaskForClaude(task) {
|
|
116
|
+
return [
|
|
117
|
+
`[PIXEL CREW SPRINT TASK: ${task.id}]`,
|
|
118
|
+
`TITLE: ${task.title}`,
|
|
119
|
+
`ROLE: ${task.agent}`,
|
|
120
|
+
`SKILLS: ${task.skills.join(', ')}`,
|
|
121
|
+
`READ FILES: ${task.files.read.join(', ') || 'All'}`,
|
|
122
|
+
`WRITE FILES: ${task.files.write.join(', ') || 'All'}`,
|
|
123
|
+
`DESCRIPTION:\n${task.description}`
|
|
124
|
+
].join('\n\n');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async execute(task, context = {}) {
|
|
128
|
+
const { emit = () => {}, signal } = context;
|
|
129
|
+
|
|
130
|
+
if (signal?.aborted) {
|
|
131
|
+
throw new Error(`Task ${task.id} cancelled before start`);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
await emit('tool.invoked', `Claude Code dispatching subagent for task: ${task.title}`);
|
|
135
|
+
|
|
136
|
+
if (context.executeTaskHandler) {
|
|
137
|
+
return await context.executeTaskHandler(task, emit);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Standard task execution
|
|
141
|
+
await new Promise(r => setTimeout(r, 200));
|
|
142
|
+
return {
|
|
143
|
+
success: true,
|
|
144
|
+
provider: this.id,
|
|
145
|
+
taskId: task.id,
|
|
146
|
+
prompt: this.formatTaskForClaude(task)
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Codex Adapter
|
|
3
|
+
*
|
|
4
|
+
* Execution adapter for OpenAI Codex / CLI environments.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fs from 'node:fs/promises';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import os from 'node:os';
|
|
10
|
+
import { spawn } from 'node:child_process';
|
|
11
|
+
import { AgentAdapter } from './adapter.interface.js';
|
|
12
|
+
|
|
13
|
+
export class CodexAdapter extends AgentAdapter {
|
|
14
|
+
constructor(options = {}) {
|
|
15
|
+
super('codex', 'Codex', {
|
|
16
|
+
icon: '🧠',
|
|
17
|
+
description: 'OpenAI Codex & Assistant code execution environment',
|
|
18
|
+
capabilities: {
|
|
19
|
+
fileAccess: true,
|
|
20
|
+
terminalAccess: true,
|
|
21
|
+
subagents: false,
|
|
22
|
+
backgroundTasks: false,
|
|
23
|
+
streaming: true,
|
|
24
|
+
toolCalls: true
|
|
25
|
+
},
|
|
26
|
+
...options
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async detectScore(targetDir = process.cwd()) {
|
|
31
|
+
let score = 0;
|
|
32
|
+
|
|
33
|
+
// 1. Environment variables (Active Codex session) (+1000 points)
|
|
34
|
+
if (
|
|
35
|
+
process.env.CODEX_AGENT ||
|
|
36
|
+
process.env.CODEX_SESSION ||
|
|
37
|
+
process.env.CODEX_WORKSPACE ||
|
|
38
|
+
process.env.CODEX_APP_DIR ||
|
|
39
|
+
process.env.OPENAI_CODEX
|
|
40
|
+
) {
|
|
41
|
+
score += 1000;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 2. Workspace indicators (.codex/, .codexrules, codex.json, .codex.json) (+200 points)
|
|
45
|
+
const indicators = ['.codex', '.codexrules', 'codex.json', '.codex.json'];
|
|
46
|
+
for (const item of indicators) {
|
|
47
|
+
try {
|
|
48
|
+
await fs.access(path.join(targetDir, item));
|
|
49
|
+
score += 200;
|
|
50
|
+
break;
|
|
51
|
+
} catch {}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 3. User home directory (~/.codex, ~/.openai) (+50 points)
|
|
55
|
+
try {
|
|
56
|
+
const home = os.homedir();
|
|
57
|
+
if (home) {
|
|
58
|
+
try {
|
|
59
|
+
await fs.access(path.join(home, '.codex'));
|
|
60
|
+
score += 50;
|
|
61
|
+
} catch {}
|
|
62
|
+
try {
|
|
63
|
+
await fs.access(path.join(home, '.openai'));
|
|
64
|
+
score += 50;
|
|
65
|
+
} catch {}
|
|
66
|
+
}
|
|
67
|
+
} catch {}
|
|
68
|
+
|
|
69
|
+
// 4. macOS Application bundle detection (+30 points)
|
|
70
|
+
if (process.platform === 'darwin') {
|
|
71
|
+
const macApps = [
|
|
72
|
+
'/Applications/Codex.app',
|
|
73
|
+
path.join(os.homedir() || '', 'Applications', 'Codex.app')
|
|
74
|
+
];
|
|
75
|
+
for (const appPath of macApps) {
|
|
76
|
+
try {
|
|
77
|
+
await fs.access(appPath);
|
|
78
|
+
score += 30;
|
|
79
|
+
break;
|
|
80
|
+
} catch {}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 5. Binary CLI in PATH (codex, codex-cli, codex-agent, openai) (+30 points)
|
|
85
|
+
const binaries = ['codex', 'codex-cli', 'codex-agent', 'openai'];
|
|
86
|
+
for (const bin of binaries) {
|
|
87
|
+
const isFound = await new Promise((resolve) => {
|
|
88
|
+
try {
|
|
89
|
+
const cmd = process.platform === 'win32' ? 'where' : 'which';
|
|
90
|
+
const proc = spawn(cmd, [bin], { stdio: 'ignore' });
|
|
91
|
+
proc.on('close', (code) => resolve(code === 0));
|
|
92
|
+
proc.on('error', () => resolve(false));
|
|
93
|
+
} catch {
|
|
94
|
+
resolve(false);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
if (isFound) {
|
|
98
|
+
score += 30;
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return score;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async detect(targetDir = process.cwd()) {
|
|
107
|
+
const score = await this.detectScore(targetDir);
|
|
108
|
+
return score > 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async execute(task, context = {}) {
|
|
112
|
+
const { emit = () => {}, signal } = context;
|
|
113
|
+
|
|
114
|
+
if (signal?.aborted) {
|
|
115
|
+
throw new Error(`Task ${task.id} cancelled before start`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
await emit('tool.invoked', `Codex engine executing task: ${task.title}`);
|
|
119
|
+
|
|
120
|
+
if (context.executeTaskHandler) {
|
|
121
|
+
return await context.executeTaskHandler(task, emit);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
await new Promise(r => setTimeout(r, 200));
|
|
125
|
+
return {
|
|
126
|
+
success: true,
|
|
127
|
+
provider: this.id,
|
|
128
|
+
taskId: task.id
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Cursor Adapter
|
|
3
|
+
*
|
|
4
|
+
* Execution adapter for Cursor IDE, Composer, and .cursorrules rulesets.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fs from 'node:fs/promises';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import os from 'node:os';
|
|
10
|
+
import { spawn } from 'node:child_process';
|
|
11
|
+
import { AgentAdapter } from './adapter.interface.js';
|
|
12
|
+
|
|
13
|
+
export class CursorAdapter extends AgentAdapter {
|
|
14
|
+
constructor(options = {}) {
|
|
15
|
+
super('cursor', 'Cursor IDE', {
|
|
16
|
+
icon: '⚡',
|
|
17
|
+
description: 'Cursor AI editor environment & Composer agent integration',
|
|
18
|
+
capabilities: {
|
|
19
|
+
fileAccess: true,
|
|
20
|
+
terminalAccess: true,
|
|
21
|
+
subagents: false,
|
|
22
|
+
backgroundTasks: true,
|
|
23
|
+
streaming: true,
|
|
24
|
+
toolCalls: true
|
|
25
|
+
},
|
|
26
|
+
...options
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async detectScore(targetDir = process.cwd()) {
|
|
31
|
+
let score = 0;
|
|
32
|
+
|
|
33
|
+
// 1. Environment variables (Active Cursor session) (+1000 points)
|
|
34
|
+
if (
|
|
35
|
+
process.env.CURSOR ||
|
|
36
|
+
process.env.CURSOR_AGENT ||
|
|
37
|
+
process.env.CURSOR_SESSION ||
|
|
38
|
+
process.env.CURSOR_WORKSPACE ||
|
|
39
|
+
process.env.CURSOR_APP_DIR ||
|
|
40
|
+
process.env.CURSOR_CONFIG_DIR ||
|
|
41
|
+
process.env.CURSOR_PATH
|
|
42
|
+
) {
|
|
43
|
+
score += 1000;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 2. Workspace indicators (.cursorrules, .cursor/, .cursor/rules, cursor.json) (+200 points)
|
|
47
|
+
const indicators = ['.cursorrules', '.cursor', 'cursor.json', '.cursor.json'];
|
|
48
|
+
for (const item of indicators) {
|
|
49
|
+
try {
|
|
50
|
+
await fs.access(path.join(targetDir, item));
|
|
51
|
+
score += 200;
|
|
52
|
+
break;
|
|
53
|
+
} catch {}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// 3. User home directory (~/.cursor, ~/.cursorrules) (+50 points)
|
|
57
|
+
try {
|
|
58
|
+
const home = os.homedir();
|
|
59
|
+
if (home) {
|
|
60
|
+
try {
|
|
61
|
+
await fs.access(path.join(home, '.cursor'));
|
|
62
|
+
score += 50;
|
|
63
|
+
} catch {}
|
|
64
|
+
try {
|
|
65
|
+
await fs.access(path.join(home, '.cursorrules'));
|
|
66
|
+
score += 50;
|
|
67
|
+
} catch {}
|
|
68
|
+
}
|
|
69
|
+
} catch {}
|
|
70
|
+
|
|
71
|
+
// 4. macOS Application bundle detection (+30 points)
|
|
72
|
+
if (process.platform === 'darwin') {
|
|
73
|
+
const macApps = [
|
|
74
|
+
'/Applications/Cursor.app',
|
|
75
|
+
path.join(os.homedir() || '', 'Applications', 'Cursor.app')
|
|
76
|
+
];
|
|
77
|
+
for (const appPath of macApps) {
|
|
78
|
+
try {
|
|
79
|
+
await fs.access(appPath);
|
|
80
|
+
score += 30;
|
|
81
|
+
break;
|
|
82
|
+
} catch {}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// 5. Binary CLI in PATH (cursor, cursor-cli, cursor-agent) (+30 points)
|
|
87
|
+
const binaries = ['cursor', 'cursor-cli', 'cursor-agent'];
|
|
88
|
+
for (const bin of binaries) {
|
|
89
|
+
const isFound = await new Promise((resolve) => {
|
|
90
|
+
try {
|
|
91
|
+
const cmd = process.platform === 'win32' ? 'where' : 'which';
|
|
92
|
+
const proc = spawn(cmd, [bin], { stdio: 'ignore' });
|
|
93
|
+
proc.on('close', (code) => resolve(code === 0));
|
|
94
|
+
proc.on('error', () => resolve(false));
|
|
95
|
+
} catch {
|
|
96
|
+
resolve(false);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
if (isFound) {
|
|
100
|
+
score += 30;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return score;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async detect(targetDir = process.cwd()) {
|
|
109
|
+
const score = await this.detectScore(targetDir);
|
|
110
|
+
return score > 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async execute(task, context = {}) {
|
|
114
|
+
const { emit = () => {}, signal } = context;
|
|
115
|
+
|
|
116
|
+
if (signal?.aborted) {
|
|
117
|
+
throw new Error(`Task ${task.id} cancelled before start`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
await emit('tool.invoked', `Cursor agent applying task context to workspace: ${task.title}`);
|
|
121
|
+
|
|
122
|
+
if (context.executeTaskHandler) {
|
|
123
|
+
return await context.executeTaskHandler(task, emit);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
await new Promise(r => setTimeout(r, 200));
|
|
127
|
+
return {
|
|
128
|
+
success: true,
|
|
129
|
+
provider: this.id,
|
|
130
|
+
taskId: task.id
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Generic Local CLI & Process Adapter
|
|
3
|
+
*
|
|
4
|
+
* Baseline fallback execution adapter. Runs tasks locally through Node.js,
|
|
5
|
+
* subprocesses, and built-in code synthesis engines without requiring third-party agent CLIs.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { AgentAdapter } from './adapter.interface.js';
|
|
9
|
+
|
|
10
|
+
export class GenericAdapter extends AgentAdapter {
|
|
11
|
+
constructor(options = {}) {
|
|
12
|
+
super('generic', 'Generic CLI Runner', {
|
|
13
|
+
icon: '💻',
|
|
14
|
+
description: 'Local portable Node.js and subshell execution runner (Zero external dependencies required)',
|
|
15
|
+
capabilities: {
|
|
16
|
+
fileAccess: true,
|
|
17
|
+
terminalAccess: true,
|
|
18
|
+
subagents: false,
|
|
19
|
+
backgroundTasks: true,
|
|
20
|
+
streaming: true,
|
|
21
|
+
toolCalls: true
|
|
22
|
+
},
|
|
23
|
+
...options
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async detectScore() {
|
|
28
|
+
return 10;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async detect() {
|
|
32
|
+
// Always available as baseline runtime
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async execute(task, context = {}) {
|
|
37
|
+
const { emit = () => {}, signal } = context;
|
|
38
|
+
|
|
39
|
+
if (signal?.aborted) {
|
|
40
|
+
throw new Error(`Task ${task.id} aborted prior to execution`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (context.executeTaskHandler) {
|
|
44
|
+
return await context.executeTaskHandler(task, emit);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Default local synthesis / execution handler
|
|
48
|
+
await emit('tool.invoked', `Local runner reading files: ${task.files.read.join(', ') || 'workspace'}`);
|
|
49
|
+
await new Promise(r => setTimeout(r, 150));
|
|
50
|
+
|
|
51
|
+
if (signal?.aborted) throw new Error('Task aborted');
|
|
52
|
+
|
|
53
|
+
await emit('tool.invoked', `Local runner writing targets: ${task.files.write.join(', ') || 'output'}`);
|
|
54
|
+
await new Promise(r => setTimeout(r, 150));
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
success: true,
|
|
58
|
+
provider: this.id,
|
|
59
|
+
taskId: task.id,
|
|
60
|
+
executedAt: Date.now()
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Adapters Index
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export * from './adapter.interface.js';
|
|
6
|
+
export * from './generic.js';
|
|
7
|
+
export * from './claude-code.js';
|
|
8
|
+
export * from './codex.js';
|
|
9
|
+
export * from './cursor.js';
|
|
10
|
+
export * from './kiro.js';
|
|
11
|
+
export * from './antigravity.js';
|
|
12
|
+
export * from './registry.js';
|
|
13
|
+
|
|
14
|
+
import { ProviderRegistry } from './registry.js';
|
|
15
|
+
export const defaultProviderRegistry = new ProviderRegistry();
|