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,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Structured Logging Engine
|
|
3
|
+
*
|
|
4
|
+
* Synthesizes structured JSON logger with correlation IDs (requestId, traceId),
|
|
5
|
+
* log levels, and automatic PII redaction.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export class LoggingEngine {
|
|
9
|
+
/**
|
|
10
|
+
* Synthesize structured logger module
|
|
11
|
+
* @returns {string} TypeScript logger code
|
|
12
|
+
*/
|
|
13
|
+
static generateLogger() {
|
|
14
|
+
return `/**
|
|
15
|
+
* Enterprise Structured JSON Logger with PII Redaction
|
|
16
|
+
* Auto-generated by Pixel Crew Observability Engine
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export type LogLevel = "debug" | "info" | "warn" | "error";
|
|
20
|
+
|
|
21
|
+
const SENSITIVE_KEYS = new Set([
|
|
22
|
+
"password", "secret", "token", "authorization", "apiKey", "creditCard", "ssn"
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
function redactPII(obj: any): any {
|
|
26
|
+
if (!obj || typeof obj !== "object") return obj;
|
|
27
|
+
if (Array.isArray(obj)) return obj.map(redactPII);
|
|
28
|
+
|
|
29
|
+
const cleaned: Record<string, any> = {};
|
|
30
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
31
|
+
if (SENSITIVE_KEYS.has(key.toLowerCase())) {
|
|
32
|
+
cleaned[key] = "[REDACTED]";
|
|
33
|
+
} else if (typeof value === "object") {
|
|
34
|
+
cleaned[key] = redactPII(value);
|
|
35
|
+
} else {
|
|
36
|
+
cleaned[key] = value;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return cleaned;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export class Logger {
|
|
43
|
+
constructor(private readonly context: string = "Application") {}
|
|
44
|
+
|
|
45
|
+
private log(level: LogLevel, event: string, data?: Record<string, any>, error?: Error) {
|
|
46
|
+
const payload = {
|
|
47
|
+
timestamp: new Date().toISOString(),
|
|
48
|
+
level,
|
|
49
|
+
context: this.context,
|
|
50
|
+
event,
|
|
51
|
+
...(data ? { data: redactPII(data) } : {}),
|
|
52
|
+
...(error ? {
|
|
53
|
+
error: {
|
|
54
|
+
name: error.name,
|
|
55
|
+
message: error.message,
|
|
56
|
+
stack: process.env.NODE_ENV !== "production" ? error.stack : undefined
|
|
57
|
+
}
|
|
58
|
+
} : {})
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const formatted = JSON.stringify(payload);
|
|
62
|
+
if (level === "error") {
|
|
63
|
+
console.error(formatted);
|
|
64
|
+
} else if (level === "warn") {
|
|
65
|
+
console.warn(formatted);
|
|
66
|
+
} else {
|
|
67
|
+
console.log(formatted);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
debug(event: string, data?: Record<string, any>) { this.log("debug", event, data); }
|
|
72
|
+
info(event: string, data?: Record<string, any>) { this.log("info", event, data); }
|
|
73
|
+
warn(event: string, data?: Record<string, any>) { this.log("warn", event, data); }
|
|
74
|
+
error(event: string, error?: Error, data?: Record<string, any>) { this.log("error", event, data, error); }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export const logger = new Logger("Root");
|
|
78
|
+
`;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Health & Metrics Engine
|
|
3
|
+
*
|
|
4
|
+
* Synthesizes /health/live, /health/ready endpoints and metrics counters.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export class MetricsEngine {
|
|
8
|
+
/**
|
|
9
|
+
* Synthesize Health Check routes
|
|
10
|
+
* @returns {string} TypeScript health check route
|
|
11
|
+
*/
|
|
12
|
+
static generateHealthRoutes() {
|
|
13
|
+
return `import { NextResponse } from "next/server";
|
|
14
|
+
import { formatErrorResponse } from "@/shared/errors";
|
|
15
|
+
|
|
16
|
+
export async function GET() {
|
|
17
|
+
try {
|
|
18
|
+
return NextResponse.json({
|
|
19
|
+
status: "ok",
|
|
20
|
+
timestamp: new Date().toISOString(),
|
|
21
|
+
uptimeSeconds: process.uptime(),
|
|
22
|
+
memoryUsageMB: Math.round(process.memoryUsage().heapUsed / 1024 / 1024)
|
|
23
|
+
}, { status: 200 });
|
|
24
|
+
} catch (error) {
|
|
25
|
+
const { status, body } = formatErrorResponse(error, "/api/health");
|
|
26
|
+
return NextResponse.json(body, { status });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
`;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Distributed Tracing Engine
|
|
3
|
+
*
|
|
4
|
+
* Synthesizes request correlation middleware (x-request-id, traceparent propagation).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export class TracingEngine {
|
|
8
|
+
static generateMiddleware() {
|
|
9
|
+
return `import { NextRequest } from "next/server";
|
|
10
|
+
|
|
11
|
+
export function getCorrelationId(request: NextRequest): string {
|
|
12
|
+
return request.headers.get("x-request-id") || request.headers.get("x-correlation-id") || \`req_\${Math.random().toString(36).slice(2, 10)}\`;
|
|
13
|
+
}
|
|
14
|
+
`;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Backend Pattern Registry
|
|
3
|
+
*
|
|
4
|
+
* Defines standard architectural patterns with explicit preconditions, triggers,
|
|
5
|
+
* trade-offs, and implementation strategies.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const BACKEND_PATTERNS = [
|
|
9
|
+
{
|
|
10
|
+
id: 'pat-cursor-pagination',
|
|
11
|
+
name: 'Cursor-Based Pagination',
|
|
12
|
+
category: 'api',
|
|
13
|
+
when: ['large dataset', 'high growth', 'frequent pagination', 'real-time feeds'],
|
|
14
|
+
avoidWhen: ['small dataset', 'simple administrative table with page jumps'],
|
|
15
|
+
benefits: ['Stable pagination under concurrent inserts', 'Constant O(1) database index seek time'],
|
|
16
|
+
tradeoffs: ['Cannot jump directly to arbitrary page N'],
|
|
17
|
+
risk: 'Cursor corruption on malformed input',
|
|
18
|
+
mitigation: 'Base64URL encoding with signature or strict schema decode'
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: 'pat-cache-aside',
|
|
22
|
+
name: 'Cache-Aside with Mutation Invalidation',
|
|
23
|
+
category: 'caching',
|
|
24
|
+
when: ['read-heavy access', 'expensive relational joins', 'hot entity reads'],
|
|
25
|
+
avoidWhen: ['write-heavy stream', 'highly volatile transactional state'],
|
|
26
|
+
benefits: ['Sub-millisecond query response', 'Protects database from query spikes'],
|
|
27
|
+
tradeoffs: ['Cache invalidation complexity', 'Potential stale read window'],
|
|
28
|
+
risk: 'Serving stale data after updates',
|
|
29
|
+
mitigation: 'Short TTL (300s) + immediate key invalidation on write mutations'
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: 'pat-idempotent-receiver',
|
|
33
|
+
name: 'Idempotent Consumer / Receiver',
|
|
34
|
+
category: 'resilience',
|
|
35
|
+
when: ['payment operations', 'webhook processing', 'mutating POST/PATCH retries'],
|
|
36
|
+
avoidWhen: ['pure idempotent GET/DELETE operations'],
|
|
37
|
+
benefits: ['Guarantees exactly-once execution semantics under network retries'],
|
|
38
|
+
tradeoffs: ['Requires caching or storage of Idempotency-Key responses'],
|
|
39
|
+
risk: 'Storage memory growth from unused keys',
|
|
40
|
+
mitigation: '24-hour TTL on idempotency storage records'
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 'pat-modular-monolith',
|
|
44
|
+
name: 'Modular Monolith Domain Separation',
|
|
45
|
+
category: 'architecture',
|
|
46
|
+
when: ['small to large business applications', 'teams needing fast velocity with clean domain boundaries'],
|
|
47
|
+
avoidWhen: ['independent polyglot teams requiring distinct deployment cadences across hundreds of engineers'],
|
|
48
|
+
benefits: ['Simple deployment', 'Compile-time type safety', 'Zero network hop overhead between modules'],
|
|
49
|
+
tradeoffs: ['Shared runtime deployment container'],
|
|
50
|
+
risk: 'Accidental coupling between domain services and internal repositories',
|
|
51
|
+
mitigation: 'Automated architectural policy engine enforcing layer purity'
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 'pat-transactional-outbox',
|
|
55
|
+
name: 'Transactional Outbox & Worker Queue',
|
|
56
|
+
category: 'queues',
|
|
57
|
+
when: ['long-running background jobs', 'reliable email dispatch', 'batch report generation'],
|
|
58
|
+
avoidWhen: ['synchronous request/response endpoints with low compute'],
|
|
59
|
+
benefits: ['Prevents blocking user HTTP requests', 'Automatic retry on background failure'],
|
|
60
|
+
tradeoffs: ['Eventual consistency between request and job completion'],
|
|
61
|
+
risk: 'Worker queue starvation or message loss on crash',
|
|
62
|
+
mitigation: 'Dead-letter queues and atomic database enqueue step'
|
|
63
|
+
}
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
export class PatternRegistry {
|
|
67
|
+
static getPatterns() {
|
|
68
|
+
return BACKEND_PATTERNS;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static findPattern(id) {
|
|
72
|
+
return BACKEND_PATTERNS.find(p => p.id === id);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Pattern Selector
|
|
3
|
+
*
|
|
4
|
+
* Selects applicable architectural patterns from the registry based on application requirements.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { BACKEND_PATTERNS } from './pattern-registry.js';
|
|
8
|
+
|
|
9
|
+
export class PatternSelector {
|
|
10
|
+
/**
|
|
11
|
+
* Select patterns for a given requirement model
|
|
12
|
+
* @param {object} requirements
|
|
13
|
+
* @returns {Array<object>} Selected Patterns
|
|
14
|
+
*/
|
|
15
|
+
static selectPatterns(requirements = {}) {
|
|
16
|
+
const selected = [];
|
|
17
|
+
|
|
18
|
+
// Always select modular monolith
|
|
19
|
+
selected.push(BACKEND_PATTERNS.find(p => p.id === 'pat-modular-monolith'));
|
|
20
|
+
|
|
21
|
+
if (requirements.performance?.paginationStrategy === 'cursor') {
|
|
22
|
+
selected.push(BACKEND_PATTERNS.find(p => p.id === 'pat-cursor-pagination'));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (requirements.performance?.caching) {
|
|
26
|
+
selected.push(BACKEND_PATTERNS.find(p => p.id === 'pat-cache-aside'));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (requirements.data?.transactions) {
|
|
30
|
+
selected.push(BACKEND_PATTERNS.find(p => p.id === 'pat-idempotent-receiver'));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (requirements.backgroundJobs?.required) {
|
|
34
|
+
selected.push(BACKEND_PATTERNS.find(p => p.id === 'pat-transactional-outbox'));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return selected.filter(Boolean);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Pattern Tradeoff Engine
|
|
3
|
+
*
|
|
4
|
+
* Formulates structured decision matrices for all selected patterns.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export class TradeoffEngine {
|
|
8
|
+
static formatTradeoffMatrix(patterns = []) {
|
|
9
|
+
return patterns.map(p => ({
|
|
10
|
+
pattern: p.name,
|
|
11
|
+
category: p.category,
|
|
12
|
+
benefit: p.benefits[0] || 'Optimized performance',
|
|
13
|
+
cost: p.tradeoffs[0] || 'Additional abstraction',
|
|
14
|
+
mitigation: p.mitigation || 'Automated policy validation'
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Cache Strategy Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Determines when caching is justified and generates key schemas and TTL policies.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export class CacheAnalyzer {
|
|
8
|
+
/**
|
|
9
|
+
* Derive caching strategy and keys
|
|
10
|
+
* @param {Array<object>} entities
|
|
11
|
+
* @param {object} architecture
|
|
12
|
+
* @returns {Array<object>} Cache Policies
|
|
13
|
+
*/
|
|
14
|
+
static analyzeCachePolicies(entities = [], architecture = {}) {
|
|
15
|
+
const policies = [];
|
|
16
|
+
|
|
17
|
+
entities.forEach(ent => {
|
|
18
|
+
const lower = ent.name.toLowerCase();
|
|
19
|
+
policies.push({
|
|
20
|
+
entity: ent.name,
|
|
21
|
+
itemKeyPattern: `${lower}:item:\${id}`,
|
|
22
|
+
listKeyPattern: `${lower}:list:\${tenantId || 'global'}:\${queryHash}`,
|
|
23
|
+
ttlSeconds: 300,
|
|
24
|
+
invalidationTriggers: ['create', 'update', 'delete'],
|
|
25
|
+
strategy: 'Cache-Aside with Explicit Invalidation'
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
return policies;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Concurrency & Race Condition Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Detects race conditions in stateful entities (inventory, balance, slots)
|
|
5
|
+
* and enforces optimistic locking or atomic database operations.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export class ConcurrencyAnalyzer {
|
|
9
|
+
/**
|
|
10
|
+
* Analyze entities for race condition vulnerabilities
|
|
11
|
+
* @param {Array<object>} entities
|
|
12
|
+
* @returns {Array<object>} Concurrency Controls
|
|
13
|
+
*/
|
|
14
|
+
static analyze(entities = []) {
|
|
15
|
+
const controls = [];
|
|
16
|
+
|
|
17
|
+
entities.forEach(ent => {
|
|
18
|
+
const fieldNames = (ent.fields || []).map(f => f.name.toLowerCase());
|
|
19
|
+
const isSensitiveToRace = fieldNames.some(f =>
|
|
20
|
+
f.includes('stock') || f.includes('inventory') || f.includes('balance') || f.includes('capacity') || f.includes('slot') || f.includes('status')
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
if (isSensitiveToRace) {
|
|
24
|
+
controls.push({
|
|
25
|
+
entity: ent.name,
|
|
26
|
+
mechanism: 'Optimistic Locking with version field or Atomic Increment/Decrement',
|
|
27
|
+
rationale: `Concurrent updates to ${ent.name} state must prevent lost updates or double-spend.`
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
return controls;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Performance Engine
|
|
3
|
+
*
|
|
4
|
+
* Synthesizes performance utilities: in-memory / Redis cache adapters,
|
|
5
|
+
* cursor pagination helpers, and payload optimization.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export class PerformanceEngine {
|
|
9
|
+
/**
|
|
10
|
+
* Generate performance infrastructure files
|
|
11
|
+
* @param {object} architecture
|
|
12
|
+
* @returns {object} Map of filename -> content
|
|
13
|
+
*/
|
|
14
|
+
static generatePerformanceSuite(architecture = {}) {
|
|
15
|
+
const files = {};
|
|
16
|
+
const useRedis = architecture.cache?.technology === 'redis';
|
|
17
|
+
|
|
18
|
+
// 1. Unified Cache Adapter
|
|
19
|
+
files['src/infrastructure/cache.ts'] = `/**
|
|
20
|
+
* High-Performance Multi-Tier Cache Adapter
|
|
21
|
+
* Auto-generated by Pixel Crew Performance Engine
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
class InMemoryCache {
|
|
25
|
+
private store = new Map<string, { value: any; expiresAt: number }>();
|
|
26
|
+
|
|
27
|
+
async get<T>(key: string): Promise<T | null> {
|
|
28
|
+
const entry = this.store.get(key);
|
|
29
|
+
if (!entry) return null;
|
|
30
|
+
if (Date.now() > entry.expiresAt) {
|
|
31
|
+
this.store.delete(key);
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return entry.value as T;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async set(key: string, value: any, ttlSeconds: number = 300): Promise<void> {
|
|
38
|
+
this.store.set(key, {
|
|
39
|
+
value,
|
|
40
|
+
expiresAt: Date.now() + ttlSeconds * 1000
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async delete(key: string): Promise<void> {
|
|
45
|
+
this.store.delete(key);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async invalidatePrefix(prefix: string): Promise<void> {
|
|
49
|
+
for (const key of this.store.keys()) {
|
|
50
|
+
if (key.startsWith(prefix)) {
|
|
51
|
+
this.store.delete(key);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const cache = new InMemoryCache();
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
// 2. Cursor Pagination Helper
|
|
61
|
+
files['src/shared/pagination.ts'] = `/**
|
|
62
|
+
* High-Performance Cursor & Offset Pagination Utility
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
export interface CursorPaginationParams {
|
|
66
|
+
cursor?: string;
|
|
67
|
+
limit?: number;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface PaginatedResult<T> {
|
|
71
|
+
data: T[];
|
|
72
|
+
pagination: {
|
|
73
|
+
nextCursor: string | null;
|
|
74
|
+
hasMore: boolean;
|
|
75
|
+
totalCount?: number;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function encodeCursor(id: string, timestamp: Date | string): string {
|
|
80
|
+
const ts = timestamp instanceof Date ? timestamp.toISOString() : timestamp;
|
|
81
|
+
return Buffer.from(\`\${id}_\${ts}\`).toString("base64url");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function decodeCursor(cursor: string): { id: string; timestamp: string } | null {
|
|
85
|
+
try {
|
|
86
|
+
const raw = Buffer.from(cursor, "base64url").toString("utf-8");
|
|
87
|
+
const [id, timestamp] = raw.split("_");
|
|
88
|
+
if (!id || !timestamp) return null;
|
|
89
|
+
return { id, timestamp };
|
|
90
|
+
} catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
`;
|
|
95
|
+
|
|
96
|
+
return files;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Query Optimizer
|
|
3
|
+
*
|
|
4
|
+
* Analyzes query structures and recommends batching, cursor slicing, and column projection.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export class QueryOptimizer {
|
|
8
|
+
static optimize(queryPlan = {}) {
|
|
9
|
+
return {
|
|
10
|
+
useProjection: true,
|
|
11
|
+
maxLimit: 100,
|
|
12
|
+
defaultLimit: 20,
|
|
13
|
+
enableCursorPagination: true
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Failure Mode Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Analyzes potential subsystem failures and outlines fallback behaviors.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export class FailureAnalyzer {
|
|
8
|
+
static analyzeFailures(architecture = {}) {
|
|
9
|
+
return [
|
|
10
|
+
{
|
|
11
|
+
subsystem: 'Database Connection Pool',
|
|
12
|
+
failureMode: 'Connection Exhaustion / Timeout',
|
|
13
|
+
fallback: 'Return RFC 7807 503 Service Unavailable with Retry-After header'
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
subsystem: 'Background Worker Queue',
|
|
17
|
+
failureMode: 'Worker crash during batch processing',
|
|
18
|
+
fallback: 'Dead-letter queue isolation with exponential retry and alert emission'
|
|
19
|
+
}
|
|
20
|
+
];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Idempotency Engine
|
|
3
|
+
*
|
|
4
|
+
* Synthesizes Idempotency-Key validation middleware and storage guards
|
|
5
|
+
* to prevent duplicate side effects on retried mutating requests.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export class IdempotencyEngine {
|
|
9
|
+
/**
|
|
10
|
+
* Synthesize idempotency middleware file
|
|
11
|
+
* @returns {string} TypeScript middleware code
|
|
12
|
+
*/
|
|
13
|
+
static generateMiddleware() {
|
|
14
|
+
return `import { NextRequest, NextResponse } from "next/server";
|
|
15
|
+
import { ConflictError } from "@/shared/errors";
|
|
16
|
+
|
|
17
|
+
const idempotencyStore = new Map<string, { status: number; body: any; timestamp: number }>();
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Validates Idempotency-Key header on mutating endpoints
|
|
21
|
+
*/
|
|
22
|
+
export async function withIdempotency(
|
|
23
|
+
request: NextRequest,
|
|
24
|
+
handler: () => Promise<NextResponse>
|
|
25
|
+
): Promise<NextResponse> {
|
|
26
|
+
const idempotencyKey = request.headers.get("idempotency-key");
|
|
27
|
+
if (!idempotencyKey) {
|
|
28
|
+
return await handler();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const cached = idempotencyStore.get(idempotencyKey);
|
|
32
|
+
if (cached) {
|
|
33
|
+
return NextResponse.json(cached.body, { status: cached.status });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const response = await handler();
|
|
37
|
+
|
|
38
|
+
if (response.status >= 200 && response.status < 300) {
|
|
39
|
+
try {
|
|
40
|
+
const cloned = response.clone();
|
|
41
|
+
const body = await cloned.json();
|
|
42
|
+
idempotencyStore.set(idempotencyKey, {
|
|
43
|
+
status: response.status,
|
|
44
|
+
body,
|
|
45
|
+
timestamp: Date.now()
|
|
46
|
+
});
|
|
47
|
+
} catch {
|
|
48
|
+
// Non-json response
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return response;
|
|
53
|
+
}
|
|
54
|
+
`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Resilience & Reliability Engine
|
|
3
|
+
*
|
|
4
|
+
* Synthesizes retry policies with exponential backoff & full jitter,
|
|
5
|
+
* circuit breakers, and graceful shutdown signal handlers.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export class ResilienceEngine {
|
|
9
|
+
/**
|
|
10
|
+
* Synthesize resilience utilities
|
|
11
|
+
* @param {object} architecture
|
|
12
|
+
* @returns {object} Map of filename -> content
|
|
13
|
+
*/
|
|
14
|
+
static generateResilienceSuite(architecture = {}) {
|
|
15
|
+
const files = {};
|
|
16
|
+
|
|
17
|
+
// 1. Retry with Exponential Backoff & Jitter
|
|
18
|
+
files['src/infrastructure/resilience.ts'] = `/**
|
|
19
|
+
* Enterprise Resilience Utilities: Retries, Backoff & Circuit Breakers
|
|
20
|
+
* Auto-generated by Pixel Crew Resilience Engine
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
export interface RetryOptions {
|
|
24
|
+
maxRetries?: number;
|
|
25
|
+
baseDelayMs?: number;
|
|
26
|
+
maxDelayMs?: number;
|
|
27
|
+
retryOnStatus?: number[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Executes an async operation with exponential backoff and full jitter
|
|
32
|
+
*/
|
|
33
|
+
export async function withRetry<T>(
|
|
34
|
+
operation: () => Promise<T>,
|
|
35
|
+
options: RetryOptions = {}
|
|
36
|
+
): Promise<T> {
|
|
37
|
+
const {
|
|
38
|
+
maxRetries = 3,
|
|
39
|
+
baseDelayMs = 200,
|
|
40
|
+
maxDelayMs = 3000
|
|
41
|
+
} = options;
|
|
42
|
+
|
|
43
|
+
let attempt = 0;
|
|
44
|
+
while (true) {
|
|
45
|
+
try {
|
|
46
|
+
return await operation();
|
|
47
|
+
} catch (error) {
|
|
48
|
+
attempt++;
|
|
49
|
+
if (attempt > maxRetries) {
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Full Jitter Formula: sleep = rand(0, min(maxDelay, baseDelay * 2^attempt))
|
|
54
|
+
const expDelay = Math.min(maxDelayMs, baseDelayMs * Math.pow(2, attempt));
|
|
55
|
+
const jitterDelay = Math.floor(Math.random() * expDelay);
|
|
56
|
+
|
|
57
|
+
await new Promise(resolve => setTimeout(resolve, jitterDelay));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Tri-State Circuit Breaker
|
|
64
|
+
*/
|
|
65
|
+
export class CircuitBreaker {
|
|
66
|
+
private failureCount = 0;
|
|
67
|
+
private state: "CLOSED" | "OPEN" | "HALF_OPEN" = "CLOSED";
|
|
68
|
+
private nextAttempt = Date.now();
|
|
69
|
+
|
|
70
|
+
constructor(
|
|
71
|
+
private readonly threshold: number = 5,
|
|
72
|
+
private readonly resetTimeoutMs: number = 30000
|
|
73
|
+
) {}
|
|
74
|
+
|
|
75
|
+
async execute<T>(action: () => Promise<T>): Promise<T> {
|
|
76
|
+
if (this.state === "OPEN") {
|
|
77
|
+
if (Date.now() > this.nextAttempt) {
|
|
78
|
+
this.state = "HALF_OPEN";
|
|
79
|
+
} else {
|
|
80
|
+
throw new Error("Circuit breaker is OPEN: service temporarily unavailable");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
const result = await action();
|
|
86
|
+
this.onSuccess();
|
|
87
|
+
return result;
|
|
88
|
+
} catch (error) {
|
|
89
|
+
this.onFailure();
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private onSuccess() {
|
|
95
|
+
this.failureCount = 0;
|
|
96
|
+
this.state = "CLOSED";
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private onFailure() {
|
|
100
|
+
this.failureCount++;
|
|
101
|
+
if (this.failureCount >= this.threshold) {
|
|
102
|
+
this.state = "OPEN";
|
|
103
|
+
this.nextAttempt = Date.now() + this.resetTimeoutMs;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
`;
|
|
108
|
+
|
|
109
|
+
// 2. Graceful Shutdown Coordinator
|
|
110
|
+
files['src/infrastructure/shutdown.ts'] = `/**
|
|
111
|
+
* Graceful Process Shutdown Handler (SIGTERM, SIGINT)
|
|
112
|
+
*/
|
|
113
|
+
|
|
114
|
+
type CleanupFunction = () => Promise<void> | void;
|
|
115
|
+
const cleanupHandlers: CleanupFunction[] = [];
|
|
116
|
+
|
|
117
|
+
export function registerCleanupHandler(fn: CleanupFunction): void {
|
|
118
|
+
cleanupHandlers.push(fn);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function setupGracefulShutdown(): void {
|
|
122
|
+
const shutdown = async (signal: string) => {
|
|
123
|
+
console.info(\`Received \${signal}. Initiating graceful shutdown sequence...\`);
|
|
124
|
+
for (const handler of cleanupHandlers) {
|
|
125
|
+
try {
|
|
126
|
+
await handler();
|
|
127
|
+
} catch (err) {
|
|
128
|
+
console.error("Error during cleanup handler execution:", err);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
process.exit(0);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
135
|
+
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
136
|
+
}
|
|
137
|
+
`;
|
|
138
|
+
|
|
139
|
+
return files;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PIXEL CREW — Retry Strategy Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Classifies HTTP status codes and errors into retryable vs non-retryable categories.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export class RetryAnalyzer {
|
|
8
|
+
static isRetryableStatus(statusCode) {
|
|
9
|
+
const nonRetryable = [400, 401, 403, 404, 409, 422];
|
|
10
|
+
if (nonRetryable.includes(statusCode)) return false;
|
|
11
|
+
|
|
12
|
+
const retryable = [408, 429, 502, 503, 504];
|
|
13
|
+
return retryable.includes(statusCode);
|
|
14
|
+
}
|
|
15
|
+
}
|