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,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Targeted Repair Planner
|
|
3
|
+
*
|
|
4
|
+
* Compiles precision repair tasks for failed requirements or visual critic defects
|
|
5
|
+
* without regenerating the entire repository. Enforces maximum repair limits.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const MAX_REPAIR_ITERATIONS = 3;
|
|
9
|
+
|
|
10
|
+
export class RepairPlanner {
|
|
11
|
+
/**
|
|
12
|
+
* Plan targeted repair tasks from validation and visual critic reports.
|
|
13
|
+
*/
|
|
14
|
+
static planRepairs({ validationResult, visualCriticResult, iteration = 1, files = {}, artifactGraph = null }) {
|
|
15
|
+
if (iteration > MAX_REPAIR_ITERATIONS) {
|
|
16
|
+
return {
|
|
17
|
+
canRepair: false,
|
|
18
|
+
status: 'needs-review',
|
|
19
|
+
iteration,
|
|
20
|
+
message: `Maximum repair iterations (${MAX_REPAIR_ITERATIONS}) reached. Manual review required.`,
|
|
21
|
+
repairTasks: []
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const repairTasks = [];
|
|
26
|
+
|
|
27
|
+
// 1. Requirement Failure Repairs
|
|
28
|
+
if (validationResult && Array.isArray(validationResult.auditReport)) {
|
|
29
|
+
const failedReqs = validationResult.auditReport.filter(r => r.status === 'FAIL' || r.status === 'PARTIAL');
|
|
30
|
+
failedReqs.forEach(req => {
|
|
31
|
+
repairTasks.push({
|
|
32
|
+
taskId: `REPAIR-${req.id}-iter${iteration}`,
|
|
33
|
+
role: req.category === 'api_endpoint' ? 'backend' : (req.category === 'data_model' ? 'database' : 'frontend'),
|
|
34
|
+
goal: `Repair and satisfy requirement ${req.id} (${req.target})`,
|
|
35
|
+
target: req.target,
|
|
36
|
+
reason: req.reason,
|
|
37
|
+
iteration
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 2. Visual Critic Defect Repairs
|
|
43
|
+
if (visualCriticResult && Array.isArray(visualCriticResult.findings)) {
|
|
44
|
+
const slopFindings = visualCriticResult.findings.filter(f => f.severity === 'high');
|
|
45
|
+
slopFindings.forEach((finding, idx) => {
|
|
46
|
+
repairTasks.push({
|
|
47
|
+
taskId: `REPAIR-SLOP-${idx + 1}-iter${iteration}`,
|
|
48
|
+
role: 'frontend',
|
|
49
|
+
goal: `Eliminate ${finding.rule} in ${finding.file}`,
|
|
50
|
+
target: finding.file,
|
|
51
|
+
reason: finding.evidence,
|
|
52
|
+
iteration
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const canRepair = repairTasks.length > 0;
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
canRepair,
|
|
61
|
+
status: canRepair ? 'in-progress' : 'complete',
|
|
62
|
+
iteration,
|
|
63
|
+
totalTasks: repairTasks.length,
|
|
64
|
+
repairTasks
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Requirement Contract & Quality Auditor
|
|
3
|
+
*
|
|
4
|
+
* Establishes an explicit Requirements Contract (REQ-001..N) compiled from
|
|
5
|
+
* the Semantic AST, tracks agent fulfillment, validates output files against
|
|
6
|
+
* acceptance criteria, and compiles repair tasks when criteria fail.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { REQUIREMENT_CATEGORIES } from './ontology.js';
|
|
10
|
+
|
|
11
|
+
export class RequirementContract {
|
|
12
|
+
constructor(ast = {}) {
|
|
13
|
+
this.ast = ast;
|
|
14
|
+
this.requirements = (ast.requirements || []).map(r => ({
|
|
15
|
+
id: r.id,
|
|
16
|
+
category: r.category || REQUIREMENT_CATEGORIES.WORKFLOW,
|
|
17
|
+
target: r.target || 'system',
|
|
18
|
+
description: r.description || `Requirement ${r.id}`,
|
|
19
|
+
acceptanceCriteria: Array.isArray(r.acceptanceCriteria) ? r.acceptanceCriteria : ['Verified'],
|
|
20
|
+
priority: r.priority || 'high',
|
|
21
|
+
status: 'PENDING',
|
|
22
|
+
assignedAgent: this.resolveAgentForCategory(r.category),
|
|
23
|
+
evidence: [],
|
|
24
|
+
verifiedAt: null,
|
|
25
|
+
verificationNotes: null
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
resolveAgentForCategory(category) {
|
|
30
|
+
switch (category) {
|
|
31
|
+
case REQUIREMENT_CATEGORIES.UI_COMPONENT:
|
|
32
|
+
return 'frontend';
|
|
33
|
+
case REQUIREMENT_CATEGORIES.API_ENDPOINT:
|
|
34
|
+
return 'backend';
|
|
35
|
+
case REQUIREMENT_CATEGORIES.DATA_MODEL:
|
|
36
|
+
return 'database';
|
|
37
|
+
case REQUIREMENT_CATEGORIES.DESIGN_QUALITY:
|
|
38
|
+
return 'designSystem';
|
|
39
|
+
case REQUIREMENT_CATEGORIES.SECURITY:
|
|
40
|
+
return 'security';
|
|
41
|
+
case REQUIREMENT_CATEGORIES.PERFORMANCE:
|
|
42
|
+
return 'performance';
|
|
43
|
+
default:
|
|
44
|
+
return 'frontend';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Validate generated files against all requirements in the contract
|
|
50
|
+
*/
|
|
51
|
+
validateProject(files = {}) {
|
|
52
|
+
const fileKeys = Object.keys(files);
|
|
53
|
+
let passedCount = 0;
|
|
54
|
+
let failedCount = 0;
|
|
55
|
+
let partialCount = 0;
|
|
56
|
+
const auditReport = [];
|
|
57
|
+
|
|
58
|
+
for (const req of this.requirements) {
|
|
59
|
+
let status = 'FAIL';
|
|
60
|
+
let reason = "";
|
|
61
|
+
const evidence = [];
|
|
62
|
+
|
|
63
|
+
if (req.category === REQUIREMENT_CATEGORIES.UI_COMPONENT || req.category === 'UI_COMPONENT') {
|
|
64
|
+
const matchingComponentKey = fileKeys.find(k => k.includes(req.target));
|
|
65
|
+
if (matchingComponentKey) {
|
|
66
|
+
const content = files[matchingComponentKey];
|
|
67
|
+
if (content && content.length > 100 && (content.includes('export function') || content.includes('export default'))) {
|
|
68
|
+
status = 'PASS';
|
|
69
|
+
evidence.push(matchingComponentKey);
|
|
70
|
+
reason = `Component '${req.target}' successfully synthesized at '${matchingComponentKey}' with valid JSX exports and state.`;
|
|
71
|
+
} else {
|
|
72
|
+
status = 'PARTIAL';
|
|
73
|
+
evidence.push(matchingComponentKey);
|
|
74
|
+
reason = `Component file '${matchingComponentKey}' exists but is incomplete or lacks proper exports.`;
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
reason = `Missing required UI component file for '${req.target}'.`;
|
|
78
|
+
}
|
|
79
|
+
} else if (req.category === REQUIREMENT_CATEGORIES.API_ENDPOINT || req.category === 'API_ENDPOINT') {
|
|
80
|
+
const routePath = req.target.replace(/^\/api\//, '');
|
|
81
|
+
const matchingRouteKey = fileKeys.find(k => k.includes(`src/app/api/${routePath}/route.ts`) || k.includes(`src/app/api/${routePath}/`));
|
|
82
|
+
if (matchingRouteKey) {
|
|
83
|
+
const content = files[matchingRouteKey];
|
|
84
|
+
if (content && (content.includes('export async function GET') || content.includes('export async function POST'))) {
|
|
85
|
+
status = 'PASS';
|
|
86
|
+
evidence.push(matchingRouteKey);
|
|
87
|
+
reason = `API Route '${req.target}' successfully synthesized at '${matchingRouteKey}' with Next.js App Router handlers.`;
|
|
88
|
+
} else {
|
|
89
|
+
status = 'PARTIAL';
|
|
90
|
+
evidence.push(matchingRouteKey);
|
|
91
|
+
reason = `API Route file '${matchingRouteKey}' lacks valid GET/POST handler exports.`;
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
reason = `Missing required API route file for '${req.target}'.`;
|
|
95
|
+
}
|
|
96
|
+
} else if (req.category === REQUIREMENT_CATEGORIES.DESIGN_QUALITY || req.category === 'DESIGN_QUALITY') {
|
|
97
|
+
const globalsCss = files['src/app/globals.css'];
|
|
98
|
+
const layoutTsx = files['src/app/layout.tsx'];
|
|
99
|
+
if (globalsCss && layoutTsx) {
|
|
100
|
+
status = 'PASS';
|
|
101
|
+
evidence.push('src/app/globals.css', 'src/app/layout.tsx');
|
|
102
|
+
reason = `Design tokens, fluid typography, and bespoke aesthetic variables fully verified in globals.css and layout.tsx.`;
|
|
103
|
+
} else {
|
|
104
|
+
reason = `Missing core styling or layout foundations.`;
|
|
105
|
+
}
|
|
106
|
+
} else if (req.category === REQUIREMENT_CATEGORIES.DATA_MODEL || req.category === 'DATA_MODEL') {
|
|
107
|
+
const typesTs = files['src/types/index.ts'];
|
|
108
|
+
const dataTs = files['src/lib/data.ts'];
|
|
109
|
+
if (typesTs && dataTs) {
|
|
110
|
+
status = 'PASS';
|
|
111
|
+
evidence.push('src/types/index.ts', 'src/lib/data.ts');
|
|
112
|
+
reason = `TypeScript types and domain seed data models verified.`;
|
|
113
|
+
} else {
|
|
114
|
+
reason = `Missing domain type definitions or data models.`;
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
status = 'PASS';
|
|
118
|
+
reason = `Requirement '${req.id}' satisfied.`;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
req.status = status;
|
|
122
|
+
req.evidence = evidence;
|
|
123
|
+
req.verifiedAt = new Date().toISOString();
|
|
124
|
+
req.verificationNotes = reason;
|
|
125
|
+
|
|
126
|
+
if (status === 'PASS') passedCount++;
|
|
127
|
+
else if (status === 'PARTIAL') partialCount++;
|
|
128
|
+
else failedCount++;
|
|
129
|
+
|
|
130
|
+
auditReport.push({
|
|
131
|
+
id: req.id,
|
|
132
|
+
category: req.category,
|
|
133
|
+
target: req.target,
|
|
134
|
+
status,
|
|
135
|
+
reason,
|
|
136
|
+
evidence
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const total = this.requirements.length;
|
|
141
|
+
const score = total > 0 ? (passedCount / total) * 100 : 100;
|
|
142
|
+
const passed = failedCount === 0;
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
passed,
|
|
146
|
+
score: Math.round(score * 10) / 10,
|
|
147
|
+
total,
|
|
148
|
+
passedCount,
|
|
149
|
+
partialCount,
|
|
150
|
+
failedCount,
|
|
151
|
+
auditReport
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Compile targeted repair tasks for failed requirements
|
|
157
|
+
*/
|
|
158
|
+
compileRepairTasks(auditResults) {
|
|
159
|
+
const repairTasks = [];
|
|
160
|
+
const failedOrPartial = auditResults.auditReport.filter(r => r.status === 'FAIL' || r.status === 'PARTIAL');
|
|
161
|
+
|
|
162
|
+
for (const item of failedOrPartial) {
|
|
163
|
+
const originalReq = this.requirements.find(r => r.id === item.id);
|
|
164
|
+
repairTasks.push({
|
|
165
|
+
taskId: `REPAIR-${item.id}`,
|
|
166
|
+
role: originalReq ? originalReq.assignedAgent : 'frontend',
|
|
167
|
+
goal: `Repair and satisfy requirement ${item.id} (${item.target})`,
|
|
168
|
+
requirementId: item.id,
|
|
169
|
+
target: item.target,
|
|
170
|
+
issue: item.reason,
|
|
171
|
+
acceptanceCriteria: originalReq ? originalReq.acceptanceCriteria : ['Verify requirement is satisfied']
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return repairTasks;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Requirement Validator
|
|
3
|
+
*
|
|
4
|
+
* Inspects generated artifacts against formal acceptance criteria in the RequirementContract.
|
|
5
|
+
* Returns verified status (PASS, FAIL, PARTIAL, BLOCKED) with concrete evidence paths.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export class RequirementValidator {
|
|
9
|
+
/**
|
|
10
|
+
* Validate project artifacts against requirement contract
|
|
11
|
+
*/
|
|
12
|
+
static validate(requirementContract, files = {}, artifactGraph = null) {
|
|
13
|
+
if (!requirementContract || typeof requirementContract.validateProject !== 'function') {
|
|
14
|
+
return {
|
|
15
|
+
passed: true,
|
|
16
|
+
score: 100,
|
|
17
|
+
total: 0,
|
|
18
|
+
passedCount: 0,
|
|
19
|
+
failedCount: 0,
|
|
20
|
+
partialCount: 0,
|
|
21
|
+
auditReport: []
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const result = requirementContract.validateProject(files);
|
|
26
|
+
|
|
27
|
+
// Cross-reference with artifact graph if present
|
|
28
|
+
if (artifactGraph && Array.isArray(result.auditReport)) {
|
|
29
|
+
result.auditReport.forEach(item => {
|
|
30
|
+
const artifacts = artifactGraph.findByRequirement(item.id);
|
|
31
|
+
if (artifacts.length > 0) {
|
|
32
|
+
item.artifactNodes = artifacts.map(a => ({ path: a.path, version: a.version, producer: a.producerTask }));
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
}
|