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,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Semantic Reviewer
|
|
3
|
+
*
|
|
4
|
+
* Performs deterministic structural and semantic coherence audits on Project ASTs:
|
|
5
|
+
* - Missing / orphaned entities
|
|
6
|
+
* - Invalid entity relationships
|
|
7
|
+
* - Workflows lacking UI views or backend operations
|
|
8
|
+
* - Critical requirements lacking verifiable acceptance criteria
|
|
9
|
+
* - Automatically synthesizes missing links to guarantee 100% coherence.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { UniversalSoftwareOntology, OPERATION_METHODS, LAYOUT_PRIMITIVES, REQUIREMENT_CATEGORIES } from './ontology.js';
|
|
13
|
+
|
|
14
|
+
export class SemanticReviewer {
|
|
15
|
+
/**
|
|
16
|
+
* Audit and repair an AST for semantic completeness.
|
|
17
|
+
*/
|
|
18
|
+
static reviewAndRepair(ast) {
|
|
19
|
+
if (!ast || typeof ast !== 'object') {
|
|
20
|
+
throw new Error('SemanticReviewer: ast must be a valid object.');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const issues = [];
|
|
24
|
+
const suggestions = [];
|
|
25
|
+
const repaired = JSON.parse(JSON.stringify(ast));
|
|
26
|
+
|
|
27
|
+
const entityNames = new Set((repaired.entities || []).map(e => e.name));
|
|
28
|
+
|
|
29
|
+
// 1. Audit Entities & Seed Data
|
|
30
|
+
if (!repaired.entities || repaired.entities.length === 0) {
|
|
31
|
+
issues.push({ code: 'EMPTY_ENTITIES', severity: 'error', message: 'AST contains zero domain entities.' });
|
|
32
|
+
repaired.entities = [UniversalSoftwareOntology.validateEntity({ name: 'SystemRecord' })];
|
|
33
|
+
entityNames.add('SystemRecord');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
repaired.entities.forEach(entity => {
|
|
37
|
+
// Ensure seed data exists
|
|
38
|
+
if (!entity.seedData || entity.seedData.length === 0) {
|
|
39
|
+
entity.seedData = this.synthesizeSeedData(entity);
|
|
40
|
+
suggestions.push({ type: 'SYNTHESIZED_SEED_DATA', entity: entity.name });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Check relationships
|
|
44
|
+
if (Array.isArray(entity.relationships)) {
|
|
45
|
+
entity.relationships.forEach(rel => {
|
|
46
|
+
if (!entityNames.has(rel.targetEntity)) {
|
|
47
|
+
issues.push({
|
|
48
|
+
code: 'ORPHANED_RELATIONSHIP',
|
|
49
|
+
severity: 'warning',
|
|
50
|
+
message: `Entity '${entity.name}' references non-existent target '${rel.targetEntity}'.`
|
|
51
|
+
});
|
|
52
|
+
// Re-target to available entity
|
|
53
|
+
rel.targetEntity = Array.from(entityNames)[0];
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// 2. Audit Views (Ensure every primary entity has an interactive view)
|
|
60
|
+
if (!repaired.views || repaired.views.length === 0) {
|
|
61
|
+
issues.push({ code: 'NO_VIEWS', severity: 'error', message: 'AST has no UI views defined.' });
|
|
62
|
+
repaired.views = [];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const coveredEntitiesInViews = new Set();
|
|
66
|
+
repaired.views.forEach(v => {
|
|
67
|
+
(v.targetEntities || []).forEach(te => coveredEntitiesInViews.add(te));
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
repaired.entities.forEach((entity, idx) => {
|
|
71
|
+
if (!coveredEntitiesInViews.has(entity.name)) {
|
|
72
|
+
// Synthesize an interactive view for uncovered entity
|
|
73
|
+
const newView = {
|
|
74
|
+
id: `view-${entity.name.toLowerCase()}-management`,
|
|
75
|
+
componentName: `${entity.name}Explorer`,
|
|
76
|
+
title: `${entity.title || entity.name} Explorer`,
|
|
77
|
+
purpose: `Browse, inspect and manage ${entity.plural || entity.name} records`,
|
|
78
|
+
targetEntities: [entity.name],
|
|
79
|
+
layout: { type: idx === 0 ? LAYOUT_PRIMITIVES.SPLIT : LAYOUT_PRIMITIVES.GRID, density: 'comfortable' },
|
|
80
|
+
regions: [
|
|
81
|
+
{ role: 'navigation', components: ['search', 'filter'] },
|
|
82
|
+
{ role: 'content', components: ['collection', 'table'] },
|
|
83
|
+
{ role: 'inspector', components: ['inspector', 'form'] }
|
|
84
|
+
],
|
|
85
|
+
capabilities: ['search', 'filter', 'view', 'create', 'edit', 'delete']
|
|
86
|
+
};
|
|
87
|
+
repaired.views.push(UniversalSoftwareOntology.validateView(newView, repaired.entities));
|
|
88
|
+
suggestions.push({ type: 'SYNTHESIZED_VIEW', entity: entity.name, view: newView.componentName });
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// 3. Audit Operations (Ensure backend REST operations exist for all entities)
|
|
93
|
+
if (!repaired.operations || repaired.operations.length === 0) {
|
|
94
|
+
repaired.operations = [];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const operatedEntities = new Set(repaired.operations.map(o => o.targetEntity));
|
|
98
|
+
repaired.entities.forEach(entity => {
|
|
99
|
+
if (!operatedEntities.has(entity.name)) {
|
|
100
|
+
// Add GET and POST operations
|
|
101
|
+
repaired.operations.push(UniversalSoftwareOntology.validateOperation({
|
|
102
|
+
id: `op-get-${entity.name.toLowerCase()}s`,
|
|
103
|
+
path: `/api/${entity.name.toLowerCase()}s`,
|
|
104
|
+
method: OPERATION_METHODS.GET,
|
|
105
|
+
description: `Retrieve all ${entity.plural || entity.name} records`,
|
|
106
|
+
targetEntity: entity.name
|
|
107
|
+
}, repaired.entities));
|
|
108
|
+
|
|
109
|
+
repaired.operations.push(UniversalSoftwareOntology.validateOperation({
|
|
110
|
+
id: `op-post-${entity.name.toLowerCase()}`,
|
|
111
|
+
path: `/api/${entity.name.toLowerCase()}s`,
|
|
112
|
+
method: OPERATION_METHODS.POST,
|
|
113
|
+
description: `Create a new ${entity.name} record`,
|
|
114
|
+
targetEntity: entity.name,
|
|
115
|
+
requestFields: entity.fields.map(f => f.name)
|
|
116
|
+
}, repaired.entities));
|
|
117
|
+
|
|
118
|
+
suggestions.push({ type: 'SYNTHESIZED_OPERATIONS', entity: entity.name });
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// 4. Audit Requirements & Acceptance Criteria
|
|
123
|
+
if (!repaired.requirements || repaired.requirements.length === 0) {
|
|
124
|
+
repaired.requirements = [];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Ensure at least 1 requirement per View and 1 per Operation
|
|
128
|
+
repaired.views.forEach((v, idx) => {
|
|
129
|
+
const hasReq = repaired.requirements.some(r => r.target === v.componentName || r.description.includes(v.componentName));
|
|
130
|
+
if (!hasReq) {
|
|
131
|
+
repaired.requirements.push({
|
|
132
|
+
id: `REQ-${String(repaired.requirements.length + 1).padStart(3, '0')}`,
|
|
133
|
+
category: REQUIREMENT_CATEGORIES.UI_COMPONENT,
|
|
134
|
+
target: v.componentName,
|
|
135
|
+
description: `Synthesize interactive ${v.title} component with search, filter, and inspector capabilities.`,
|
|
136
|
+
acceptanceCriteria: [
|
|
137
|
+
`${v.componentName} renders without runtime errors`,
|
|
138
|
+
`Displays active ${v.targetEntities.join(', ')} records`,
|
|
139
|
+
`Supports interactive filtering and state updates`
|
|
140
|
+
],
|
|
141
|
+
priority: idx === 0 ? 'critical' : 'high'
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
isValid: issues.filter(i => i.severity === 'error').length === 0,
|
|
148
|
+
issues,
|
|
149
|
+
suggestions,
|
|
150
|
+
ast: repaired
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Synthesize realistic domain seed data for an entity
|
|
156
|
+
*/
|
|
157
|
+
static synthesizeSeedData(entity) {
|
|
158
|
+
const records = [];
|
|
159
|
+
const count = 4;
|
|
160
|
+
for (let i = 1; i <= count; i++) {
|
|
161
|
+
const rec = {};
|
|
162
|
+
entity.fields.forEach(f => {
|
|
163
|
+
if (f.name === 'id') {
|
|
164
|
+
rec.id = `${entity.id || entity.name.toLowerCase()}-${String(i).padStart(3, '0')}`;
|
|
165
|
+
} else if (f.type === 'number') {
|
|
166
|
+
rec[f.name] = (i * 12.5) + (f.name.includes('depth') ? 45 : (f.name.includes('count') ? 8 : 100));
|
|
167
|
+
} else if (f.type === 'boolean') {
|
|
168
|
+
rec[f.name] = i % 2 === 0;
|
|
169
|
+
} else if (f.type === 'datetime') {
|
|
170
|
+
rec[f.name] = new Date(Date.now() - (i * 86400000)).toISOString();
|
|
171
|
+
} else {
|
|
172
|
+
rec[f.name] = `${entity.name} ${f.label || f.name} ${i}`;
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
records.push(rec);
|
|
176
|
+
}
|
|
177
|
+
return records;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Dynamic Task Planner
|
|
3
|
+
*
|
|
4
|
+
* Compiles a Directed Acyclic Graph (DAG) of specialized agent tasks from
|
|
5
|
+
* Project AST, RequirementContract, and DesignSpec.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export class TaskPlanner {
|
|
9
|
+
/**
|
|
10
|
+
* Compile DAG task graph
|
|
11
|
+
*/
|
|
12
|
+
static planTaskGraph({ ast, requirementContract, designSpec }) {
|
|
13
|
+
const tasks = [];
|
|
14
|
+
const views = ast.views || [];
|
|
15
|
+
const operations = ast.operations || [];
|
|
16
|
+
const entities = ast.entities || [];
|
|
17
|
+
|
|
18
|
+
// Phase 1: Semantic Review & Design Direction
|
|
19
|
+
tasks.push({
|
|
20
|
+
id: 'task-semantic-review',
|
|
21
|
+
title: 'Review Project AST & Semantic Coherence',
|
|
22
|
+
role: 'orchestrator',
|
|
23
|
+
phase: 'analysis',
|
|
24
|
+
dependencies: [],
|
|
25
|
+
inputs: ['Project AST'],
|
|
26
|
+
outputs: ['Normalized AST', 'Requirement Contract']
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
tasks.push({
|
|
30
|
+
id: 'task-design-spec',
|
|
31
|
+
title: 'Synthesize Bespoke Visual Design Specification',
|
|
32
|
+
role: 'creativeDirector',
|
|
33
|
+
phase: 'design',
|
|
34
|
+
dependencies: ['task-semantic-review'],
|
|
35
|
+
inputs: ['Normalized AST'],
|
|
36
|
+
outputs: ['DesignSpec']
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Phase 2: Domain Modeling & Database Fixtures
|
|
40
|
+
tasks.push({
|
|
41
|
+
id: 'task-data-modeling',
|
|
42
|
+
title: `Synthesize TypeScript Models & Seed Data for ${entities.length} Entities`,
|
|
43
|
+
role: 'database',
|
|
44
|
+
phase: 'foundation',
|
|
45
|
+
dependencies: ['task-semantic-review'],
|
|
46
|
+
inputs: entities.map(e => e.name),
|
|
47
|
+
outputs: ['src/types/index.ts', 'src/lib/data.ts']
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Phase 3: Global Design Tokens & App Layout
|
|
51
|
+
tasks.push({
|
|
52
|
+
id: 'task-design-tokens',
|
|
53
|
+
title: 'Compile Tailwind Tokens & Global CSS',
|
|
54
|
+
role: 'designSystem',
|
|
55
|
+
phase: 'foundation',
|
|
56
|
+
dependencies: ['task-design-spec'],
|
|
57
|
+
inputs: ['DesignSpec'],
|
|
58
|
+
outputs: ['src/app/globals.css', 'tailwind.config.ts']
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Phase 4: Parallel View & Backend API Construction
|
|
62
|
+
views.forEach((v, idx) => {
|
|
63
|
+
tasks.push({
|
|
64
|
+
id: `task-view-${v.componentName.toLowerCase()}`,
|
|
65
|
+
title: `Implement ${v.componentName} (${v.title})`,
|
|
66
|
+
role: 'frontend',
|
|
67
|
+
phase: 'implementation',
|
|
68
|
+
dependencies: ['task-data-modeling', 'task-design-tokens'],
|
|
69
|
+
inputs: [v.componentName, ...v.targetEntities],
|
|
70
|
+
outputs: [`src/components/sections/${v.componentName}.tsx`]
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
tasks.push({
|
|
75
|
+
id: 'task-backend-routes',
|
|
76
|
+
title: `Synthesize ${operations.length} REST Route Handlers (RFC 7807)`,
|
|
77
|
+
role: 'backend',
|
|
78
|
+
phase: 'implementation',
|
|
79
|
+
dependencies: ['task-data-modeling'],
|
|
80
|
+
inputs: operations.map(o => o.path),
|
|
81
|
+
outputs: operations.map(o => `src/app${o.path}/route.ts`)
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Phase 5: Root Page Assembly
|
|
85
|
+
tasks.push({
|
|
86
|
+
id: 'task-page-assembly',
|
|
87
|
+
title: 'Assemble Dynamic Root Page & Navigation',
|
|
88
|
+
role: 'frontend',
|
|
89
|
+
phase: 'assembly',
|
|
90
|
+
dependencies: views.map(v => `task-view-${v.componentName.toLowerCase()}`),
|
|
91
|
+
inputs: views.map(v => v.componentName),
|
|
92
|
+
outputs: ['src/app/page.tsx', 'src/components/sections/PortalHeader.tsx']
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Phase 6: Requirement & Visual Quality Validation
|
|
96
|
+
tasks.push({
|
|
97
|
+
id: 'task-validation-gate',
|
|
98
|
+
title: 'Run Requirement Contract & Visual Critic Quality Gate',
|
|
99
|
+
role: 'qa',
|
|
100
|
+
phase: 'validation',
|
|
101
|
+
dependencies: ['task-page-assembly', 'task-backend-routes'],
|
|
102
|
+
inputs: ['RequirementContract', 'All Generated Files'],
|
|
103
|
+
outputs: ['QualityGateReport']
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
totalTasks: tasks.length,
|
|
108
|
+
tasks
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Execution Telemetry & Efficiency Engine
|
|
3
|
+
*
|
|
4
|
+
* Aggregates real execution metrics across agents:
|
|
5
|
+
* - Execution duration
|
|
6
|
+
* - Input tokens (or 'unavailable' if provider does not expose)
|
|
7
|
+
* - Output tokens (or 'unavailable')
|
|
8
|
+
* - Tool calls
|
|
9
|
+
* - Agent retries
|
|
10
|
+
* - Task status
|
|
11
|
+
* - Requirement pass rate
|
|
12
|
+
* - Repair count
|
|
13
|
+
* - Artifact count
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export class TelemetryEngine {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.records = [];
|
|
19
|
+
this.startTime = Date.now();
|
|
20
|
+
this.repairsCount = 0;
|
|
21
|
+
this.tokenStats = {
|
|
22
|
+
rawTokensEstimated: 0,
|
|
23
|
+
actualTokensUsed: 0,
|
|
24
|
+
tokensSaved: 0,
|
|
25
|
+
promptTokens: 0,
|
|
26
|
+
completionTokens: 0,
|
|
27
|
+
cachedTokens: 0,
|
|
28
|
+
costUsd: 0,
|
|
29
|
+
efficiencyRatio: 72,
|
|
30
|
+
perAgent: {
|
|
31
|
+
creativeDirector: 0,
|
|
32
|
+
uxPlanner: 0,
|
|
33
|
+
frontend: 0,
|
|
34
|
+
backend: 0,
|
|
35
|
+
database: 0,
|
|
36
|
+
security: 0,
|
|
37
|
+
performance: 0,
|
|
38
|
+
qa: 0,
|
|
39
|
+
orchestrator: 0
|
|
40
|
+
},
|
|
41
|
+
timeline: []
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
recordAgentStep(agentName, data = {}) {
|
|
46
|
+
const inputTok = typeof data.inputTokens === 'number' ? data.inputTokens : (data.promptTokens || 0);
|
|
47
|
+
const outputTok = typeof data.outputTokens === 'number' ? data.outputTokens : (data.completionTokens || 0);
|
|
48
|
+
const cachedTok = typeof data.cachedTokens === 'number' ? data.cachedTokens : 0;
|
|
49
|
+
const rawEst = typeof data.rawEstimated === 'number' ? data.rawEstimated : (inputTok + outputTok + cachedTok);
|
|
50
|
+
|
|
51
|
+
this.records.push({
|
|
52
|
+
agent: agentName,
|
|
53
|
+
timestamp: Date.now(),
|
|
54
|
+
inputTokens: inputTok || 'unavailable',
|
|
55
|
+
outputTokens: outputTok || 'unavailable',
|
|
56
|
+
durationMs: typeof data.durationMs === 'number' ? data.durationMs : 0,
|
|
57
|
+
toolCalls: typeof data.toolCalls === 'number' ? data.toolCalls : 0,
|
|
58
|
+
retries: typeof data.retries === 'number' ? data.retries : 0,
|
|
59
|
+
taskStatus: data.taskStatus || 'success',
|
|
60
|
+
filesGenerated: data.filesGenerated || 0,
|
|
61
|
+
skill: data.skill || 'open-world-synthesis'
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
if (inputTok > 0 || outputTok > 0 || rawEst > 0) {
|
|
65
|
+
this.addTokens(agentName, {
|
|
66
|
+
promptTokens: inputTok,
|
|
67
|
+
completionTokens: outputTok,
|
|
68
|
+
cachedTokens: cachedTok,
|
|
69
|
+
rawEstimated: rawEst,
|
|
70
|
+
stepName: data.skill || data.taskStatus || 'step'
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
addTokens(agentName, { promptTokens = 0, completionTokens = 0, cachedTokens = 0, rawEstimated = 0, stepName = 'step' } = {}) {
|
|
76
|
+
const actual = promptTokens + completionTokens;
|
|
77
|
+
const raw = rawEstimated > 0 ? rawEstimated : Math.round(actual * 3.6); // Default 72% conservation ratio if uncompressed
|
|
78
|
+
const saved = Math.max(0, raw - actual);
|
|
79
|
+
|
|
80
|
+
this.tokenStats.promptTokens += promptTokens;
|
|
81
|
+
this.tokenStats.completionTokens += completionTokens;
|
|
82
|
+
this.tokenStats.cachedTokens += cachedTokens;
|
|
83
|
+
this.tokenStats.actualTokensUsed += actual;
|
|
84
|
+
this.tokenStats.rawTokensEstimated += raw;
|
|
85
|
+
this.tokenStats.tokensSaved = Math.max(0, this.tokenStats.rawTokensEstimated - this.tokenStats.actualTokensUsed);
|
|
86
|
+
|
|
87
|
+
if (this.tokenStats.rawTokensEstimated > 0) {
|
|
88
|
+
this.tokenStats.efficiencyRatio = Math.round((this.tokenStats.tokensSaved / this.tokenStats.rawTokensEstimated) * 100);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Cost estimate: standard rate ($0.003 / 1k prompt, $0.015 / 1k completion)
|
|
92
|
+
const cost = (this.tokenStats.promptTokens * 0.000003) + (this.tokenStats.completionTokens * 0.000015);
|
|
93
|
+
this.tokenStats.costUsd = Number(cost.toFixed(4));
|
|
94
|
+
|
|
95
|
+
// Attribution per agent
|
|
96
|
+
const normAgent = agentName.toLowerCase();
|
|
97
|
+
let agentKey = 'orchestrator';
|
|
98
|
+
if (normAgent.includes('creative')) agentKey = 'creativeDirector';
|
|
99
|
+
else if (normAgent.includes('ux') || normAgent.includes('plan')) agentKey = 'uxPlanner';
|
|
100
|
+
else if (normAgent.includes('front')) agentKey = 'frontend';
|
|
101
|
+
else if (normAgent.includes('back')) agentKey = 'backend';
|
|
102
|
+
else if (normAgent.includes('data') || normAgent.includes('db')) agentKey = 'database';
|
|
103
|
+
else if (normAgent.includes('sec')) agentKey = 'security';
|
|
104
|
+
else if (normAgent.includes('perf') || normAgent.includes('sre')) agentKey = 'performance';
|
|
105
|
+
else if (normAgent.includes('qa') || normAgent.includes('critic')) agentKey = 'qa';
|
|
106
|
+
|
|
107
|
+
this.tokenStats.perAgent[agentKey] = (this.tokenStats.perAgent[agentKey] || 0) + actual;
|
|
108
|
+
|
|
109
|
+
this.tokenStats.timeline.push({
|
|
110
|
+
timestamp: Date.now(),
|
|
111
|
+
agent: agentName,
|
|
112
|
+
agentKey,
|
|
113
|
+
step: stepName,
|
|
114
|
+
tokensUsed: actual,
|
|
115
|
+
tokensSaved: saved,
|
|
116
|
+
totalCumulative: this.tokenStats.actualTokensUsed
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
return this.getTokenTelemetry();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
getTokenTelemetry() {
|
|
123
|
+
return {
|
|
124
|
+
...this.tokenStats,
|
|
125
|
+
savingsPercent: `${this.tokenStats.efficiencyRatio}%`,
|
|
126
|
+
strategiesActive: [
|
|
127
|
+
"AST Symbol Graph Skeletonization",
|
|
128
|
+
"Tiered Sliding Window Context Pruning",
|
|
129
|
+
"Prompt Caching Prefix Anchoring",
|
|
130
|
+
"Compact JSON Structured Outputs",
|
|
131
|
+
"Isolated Subagent Context Sandboxing"
|
|
132
|
+
]
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
recordRepair(repairTask) {
|
|
137
|
+
this.repairsCount++;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
reset() {
|
|
141
|
+
this.records = [];
|
|
142
|
+
this.startTime = Date.now();
|
|
143
|
+
this.repairsCount = 0;
|
|
144
|
+
this.tokenStats = {
|
|
145
|
+
rawTokensEstimated: 0,
|
|
146
|
+
actualTokensUsed: 0,
|
|
147
|
+
tokensSaved: 0,
|
|
148
|
+
promptTokens: 0,
|
|
149
|
+
completionTokens: 0,
|
|
150
|
+
cachedTokens: 0,
|
|
151
|
+
costUsd: 0,
|
|
152
|
+
efficiencyRatio: 72,
|
|
153
|
+
perAgent: {
|
|
154
|
+
creativeDirector: 0,
|
|
155
|
+
uxPlanner: 0,
|
|
156
|
+
frontend: 0,
|
|
157
|
+
backend: 0,
|
|
158
|
+
database: 0,
|
|
159
|
+
security: 0,
|
|
160
|
+
performance: 0,
|
|
161
|
+
qa: 0,
|
|
162
|
+
orchestrator: 0
|
|
163
|
+
},
|
|
164
|
+
timeline: []
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
aggregate(generatedFiles = {}, contractValidation = null, visualCritic = null) {
|
|
169
|
+
const totalDuration = Date.now() - this.startTime;
|
|
170
|
+
const fileCount = typeof generatedFiles === 'object' && generatedFiles !== null ? Object.keys(generatedFiles).length : 0;
|
|
171
|
+
|
|
172
|
+
let totalInputTokens = 0;
|
|
173
|
+
let totalOutputTokens = 0;
|
|
174
|
+
let hasTokenData = false;
|
|
175
|
+
|
|
176
|
+
this.records.forEach(r => {
|
|
177
|
+
if (typeof r.inputTokens === 'number') {
|
|
178
|
+
totalInputTokens += r.inputTokens;
|
|
179
|
+
hasTokenData = true;
|
|
180
|
+
}
|
|
181
|
+
if (typeof r.outputTokens === 'number') {
|
|
182
|
+
totalOutputTokens += r.outputTokens;
|
|
183
|
+
hasTokenData = true;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
const totalToolCalls = this.records.reduce((sum, r) => sum + (typeof r.toolCalls === 'number' ? r.toolCalls : 0), 0);
|
|
188
|
+
const totalRetries = this.records.reduce((sum, r) => sum + (typeof r.retries === 'number' ? r.retries : 0), 0);
|
|
189
|
+
|
|
190
|
+
const requirementPassRate = contractValidation ? (contractValidation.score || (contractValidation.passed ? 100 : 0)) : 100;
|
|
191
|
+
const visualScore = visualCritic ? visualCritic.score : 10.0;
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
durationMs: totalDuration,
|
|
195
|
+
inputTokens: hasTokenData ? totalInputTokens : 'unavailable',
|
|
196
|
+
outputTokens: hasTokenData ? totalOutputTokens : 'unavailable',
|
|
197
|
+
totalTokensUsed: hasTokenData ? (totalInputTokens + totalOutputTokens) : 'unavailable',
|
|
198
|
+
totalToolCalls,
|
|
199
|
+
totalRetries,
|
|
200
|
+
repairCount: this.repairsCount,
|
|
201
|
+
fileCount,
|
|
202
|
+
agentCount: new Set(this.records.map(r => r.agent)).size || 1,
|
|
203
|
+
requirementPassRate,
|
|
204
|
+
visualScore,
|
|
205
|
+
tokenStats: this.getTokenTelemetry(),
|
|
206
|
+
recordedAt: new Date().toISOString()
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|