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.
Files changed (171) hide show
  1. package/README.md +389 -315
  2. package/bin/pixel-agents.js +306 -149
  3. package/package.json +3 -1
  4. package/skill/SKILL.md +185 -0
  5. package/skill/references/anti-ai-rubric.md +30 -0
  6. package/skill/references/anti-ai-slop-encyclopedia.md +181 -0
  7. package/skill/references/commands-reference.md +135 -0
  8. package/skill/references/testing-and-qa-strategy.md +25 -0
  9. package/skill/references/token-efficiency.md +20 -0
  10. package/src/adapters/adapter.interface.js +77 -0
  11. package/src/adapters/antigravity.js +138 -0
  12. package/src/adapters/claude-code.js +149 -0
  13. package/src/adapters/codex.js +131 -0
  14. package/src/adapters/cursor.js +133 -0
  15. package/src/adapters/generic.js +63 -0
  16. package/src/adapters/index.js +15 -0
  17. package/src/adapters/kiro.js +134 -0
  18. package/src/adapters/registry.js +150 -0
  19. package/src/backend/analyzer/complexity-analyzer.js +104 -0
  20. package/src/backend/analyzer/requirement-analyzer.js +213 -0
  21. package/src/backend/analyzer/threat-analyzer.js +122 -0
  22. package/src/backend/api/api-designer.js +90 -0
  23. package/src/backend/api/error-contract.js +132 -0
  24. package/src/backend/api/route-generator.js +92 -0
  25. package/src/backend/api/schema-generator.js +64 -0
  26. package/src/backend/architecture/adr-generator.js +62 -0
  27. package/src/backend/architecture/architecture-reasoner.js +119 -0
  28. package/src/backend/architecture/architecture-selector.js +57 -0
  29. package/src/backend/architecture/tradeoff-analyzer.js +92 -0
  30. package/src/backend/data/data-modeler.js +114 -0
  31. package/src/backend/data/index-analyzer.js +93 -0
  32. package/src/backend/data/query-analyzer.js +41 -0
  33. package/src/backend/data/schema-generator.js +92 -0
  34. package/src/backend/data/transaction-analyzer.js +49 -0
  35. package/src/backend/index.js +67 -0
  36. package/src/backend/observability/logging-engine.js +80 -0
  37. package/src/backend/observability/metrics-engine.js +31 -0
  38. package/src/backend/observability/tracing-engine.js +16 -0
  39. package/src/backend/patterns/pattern-registry.js +74 -0
  40. package/src/backend/patterns/pattern-selector.js +39 -0
  41. package/src/backend/patterns/tradeoff-engine.js +17 -0
  42. package/src/backend/performance/cache-analyzer.js +31 -0
  43. package/src/backend/performance/concurrency-analyzer.js +34 -0
  44. package/src/backend/performance/performance-engine.js +98 -0
  45. package/src/backend/performance/query-optimizer.js +16 -0
  46. package/src/backend/reliability/failure-analyzer.js +22 -0
  47. package/src/backend/reliability/idempotency-engine.js +56 -0
  48. package/src/backend/reliability/resilience-engine.js +141 -0
  49. package/src/backend/reliability/retry-analyzer.js +15 -0
  50. package/src/backend/security/auth-selector.js +33 -0
  51. package/src/backend/security/authorization-engine.js +90 -0
  52. package/src/backend/security/policy-engine.js +49 -0
  53. package/src/backend/security/secret-analyzer.js +39 -0
  54. package/src/backend/security/security-engine.js +122 -0
  55. package/src/backend/security/threat-model.js +59 -0
  56. package/src/backend/synthesis/backend-synthesizer.js +98 -0
  57. package/src/backend/synthesis/infrastructure-synthesizer.js +108 -0
  58. package/src/backend/synthesis/module-synthesizer.js +262 -0
  59. package/src/backend/validation/architecture-validator.js +70 -0
  60. package/src/backend/validation/backend-quality-validator.js +71 -0
  61. package/src/backend/validation/dependency-validator.js +20 -0
  62. package/src/backend/validation/performance-validator.js +38 -0
  63. package/src/backend/validation/security-validator.js +73 -0
  64. package/src/commands/adapt.js +105 -0
  65. package/src/commands/add.js +78 -0
  66. package/src/commands/animate.js +48 -0
  67. package/src/commands/assemble.js +57 -0
  68. package/src/commands/audit.js +93 -0
  69. package/src/commands/backend.js +125 -0
  70. package/src/commands/bento.js +25 -0
  71. package/src/commands/blueprint.js +65 -0
  72. package/src/commands/bolder.js +48 -0
  73. package/src/commands/boss-fight.js +60 -0
  74. package/src/commands/build.js +39 -0
  75. package/src/commands/calibrate.js +25 -0
  76. package/src/commands/chromatic.js +25 -0
  77. package/src/commands/clarify.js +52 -0
  78. package/src/commands/colorize.js +57 -0
  79. package/src/commands/command.interface.js +28 -0
  80. package/src/commands/commands.js +84 -0
  81. package/src/commands/craft.js +57 -0
  82. package/src/commands/crew.js +66 -0
  83. package/src/commands/critique.js +25 -0
  84. package/src/commands/de-slop.js +25 -0
  85. package/src/commands/delight.js +46 -0
  86. package/src/commands/deploy.js +42 -0
  87. package/src/commands/distill.js +48 -0
  88. package/src/commands/doctor.js +89 -0
  89. package/src/commands/document.js +83 -0
  90. package/src/commands/eight-bit.js +25 -0
  91. package/src/commands/extract.js +75 -0
  92. package/src/commands/fix.js +46 -0
  93. package/src/commands/harden.js +85 -0
  94. package/src/commands/index.js +67 -0
  95. package/src/commands/install.js +75 -0
  96. package/src/commands/layout.js +48 -0
  97. package/src/commands/live.js +44 -0
  98. package/src/commands/manifest.js +25 -0
  99. package/src/commands/office.js +25 -0
  100. package/src/commands/onboard.js +46 -0
  101. package/src/commands/oneshot.js +60 -0
  102. package/src/commands/optimize.js +46 -0
  103. package/src/commands/overdrive.js +46 -0
  104. package/src/commands/parser.js +143 -0
  105. package/src/commands/pixelcrew.js +96 -0
  106. package/src/commands/plan.js +66 -0
  107. package/src/commands/polish.js +45 -0
  108. package/src/commands/quieter.js +48 -0
  109. package/src/commands/recap.js +358 -0
  110. package/src/commands/registry.js +353 -0
  111. package/src/commands/render.js +26 -0
  112. package/src/commands/retrofit.js +25 -0
  113. package/src/commands/review.js +118 -0
  114. package/src/commands/roster.js +25 -0
  115. package/src/commands/sentinel.js +25 -0
  116. package/src/commands/shape.js +66 -0
  117. package/src/commands/skills.js +57 -0
  118. package/src/commands/status.js +48 -0
  119. package/src/commands/stop.js +50 -0
  120. package/src/commands/sync.js +58 -0
  121. package/src/commands/typeset.js +58 -0
  122. package/src/commands/warp.js +25 -0
  123. package/src/core/agent-runtime.js +94 -0
  124. package/src/core/event-bus.js +98 -0
  125. package/src/core/index.js +9 -0
  126. package/src/core/orchestrator.js +234 -0
  127. package/src/core/scheduler.js +124 -0
  128. package/src/core/task-graph.js +185 -0
  129. package/src/dashboard/app.js +1172 -30
  130. package/src/dashboard/index.html +223 -23
  131. package/src/dashboard/styles.css +870 -0
  132. package/src/index.js +16 -0
  133. package/src/orchestrator/artifact-graph.js +104 -0
  134. package/src/orchestrator/ast-normalizer.js +147 -0
  135. package/src/orchestrator/code-generator.js +632 -780
  136. package/src/orchestrator/design-engine.js +203 -0
  137. package/src/orchestrator/engine.js +307 -38
  138. package/src/orchestrator/oneshot.js +367 -380
  139. package/src/orchestrator/ontology.js +394 -0
  140. package/src/orchestrator/planner.js +231 -258
  141. package/src/orchestrator/repair-planner.js +67 -0
  142. package/src/orchestrator/requirement-contract.js +177 -0
  143. package/src/orchestrator/requirement-validator.js +39 -0
  144. package/src/orchestrator/semantic-engine.js +582 -0
  145. package/src/orchestrator/semantic-reviewer.js +179 -0
  146. package/src/orchestrator/task-planner.js +111 -0
  147. package/src/orchestrator/telemetry.js +209 -0
  148. package/src/orchestrator/ui-synthesizer.js +245 -0
  149. package/src/orchestrator/visual-critic.js +106 -0
  150. package/src/policies/architecture/layering.policy.js +14 -0
  151. package/src/policies/performance/indexing.policy.js +13 -0
  152. package/src/policies/reliability/resilience.policy.js +13 -0
  153. package/src/policies/security/auth.policy.js +31 -0
  154. package/src/protocol/agent.js +124 -0
  155. package/src/protocol/event.js +78 -0
  156. package/src/protocol/index.js +8 -0
  157. package/src/protocol/skill.js +54 -0
  158. package/src/protocol/task.js +100 -0
  159. package/src/scaffold/claude-generator.js +60 -0
  160. package/src/scaffold/commands-catalog.js +321 -0
  161. package/src/scaffold/cursor-generator.js +74 -0
  162. package/src/scaffold/ide-rules.js +133 -0
  163. package/src/scaffold/init.js +415 -91
  164. package/src/scaffold/installer.js +571 -0
  165. package/src/scaffold/kiro-generator.js +86 -0
  166. package/src/scaffold/skills-bundle.js +520 -0
  167. package/src/scaffold/templates.js +57 -4
  168. package/src/scaffold/workstations.js +364 -0
  169. package/src/server/server.js +283 -40
  170. package/src/utils/fs-safe.js +168 -0
  171. package/src/utils/markdown-report.js +175 -0
@@ -0,0 +1,394 @@
1
+ /**
2
+ * PIXEL CREW — Universal Software Ontology
3
+ *
4
+ * Defines the domain-agnostic primitives, grammatical contracts, and schemas of software architecture.
5
+ * The orchestrator owns the software synthesis process, NOT a catalog of application domains.
6
+ * The domain is runtime data.
7
+ */
8
+
9
+ export const UNIVERSAL_CAPABILITIES = [
10
+ 'search',
11
+ 'filter',
12
+ 'sort',
13
+ 'create',
14
+ 'edit',
15
+ 'delete',
16
+ 'view',
17
+ 'schedule',
18
+ 'calculate',
19
+ 'simulate',
20
+ 'compare',
21
+ 'upload',
22
+ 'download',
23
+ 'export',
24
+ 'authenticate',
25
+ 'authorize',
26
+ 'approve',
27
+ 'reject',
28
+ 'assign',
29
+ 'track',
30
+ 'visualize',
31
+ 'collaborate',
32
+ 'notify',
33
+ 'archive',
34
+ 'restore'
35
+ ];
36
+
37
+ export const LAYOUT_PRIMITIVES = {
38
+ STACK: 'stack',
39
+ SPLIT: 'split',
40
+ GRID: 'grid',
41
+ OVERLAY: 'overlay',
42
+ WORKSPACE: 'workspace',
43
+ SIDEBAR: 'sidebar',
44
+ INSPECTOR: 'inspector',
45
+ CANVAS: 'canvas',
46
+ TIMELINE: 'timeline',
47
+ SEQUENCE: 'sequence',
48
+ NESTED: 'nested',
49
+ FREEFORM: 'freeform'
50
+ };
51
+
52
+ export const UI_PRIMITIVES = {
53
+ COLLECTION: 'collection',
54
+ TABLE: 'table',
55
+ FORM: 'form',
56
+ TIMELINE: 'timeline',
57
+ CALENDAR: 'calendar',
58
+ BOARD: 'board',
59
+ CANVAS: 'canvas',
60
+ INSPECTOR: 'inspector',
61
+ WORKSPACE: 'workspace',
62
+ MODAL: 'modal',
63
+ DRAWER: 'drawer',
64
+ SEARCH: 'search',
65
+ FILTER: 'filter',
66
+ PAGINATION: 'pagination',
67
+ VISUALIZATION: 'visualization'
68
+ };
69
+
70
+ export const OPERATION_METHODS = {
71
+ GET: 'GET',
72
+ POST: 'POST',
73
+ PUT: 'PUT',
74
+ PATCH: 'PATCH',
75
+ DELETE: 'DELETE'
76
+ };
77
+
78
+ export const REQUIREMENT_CATEGORIES = {
79
+ WORKFLOW: 'workflow',
80
+ UI_COMPONENT: 'ui_component',
81
+ API_ENDPOINT: 'api_endpoint',
82
+ DATA_MODEL: 'data_model',
83
+ SECURITY: 'security',
84
+ PERFORMANCE: 'performance',
85
+ DESIGN_QUALITY: 'design_quality'
86
+ };
87
+
88
+ export class UniversalSoftwareOntology {
89
+ /**
90
+ * Validate & Normalize Project Definition
91
+ */
92
+ static validateProject(project) {
93
+ if (!project || typeof project !== 'object') {
94
+ throw new Error('Project definition must be a valid object.');
95
+ }
96
+ return {
97
+ name: String(project.name || 'Universal Application').trim(),
98
+ description: String(project.description || 'Open-world synthesized software application').trim(),
99
+ domain: String(project.domain || 'general-software').toLowerCase().replace(/[^a-z0-9]+/g, '-'),
100
+ goals: Array.isArray(project.goals) ? project.goals.map(String) : []
101
+ };
102
+ }
103
+
104
+ /**
105
+ * Validate & Normalize Actor Definition
106
+ */
107
+ static validateActor(actor, index = 0) {
108
+ if (!actor || typeof actor !== 'object') {
109
+ return {
110
+ id: `actor-${index + 1}`,
111
+ name: 'User',
112
+ role: 'Primary Operator',
113
+ capabilities: ['view', 'create', 'search'],
114
+ permissions: ['read', 'write']
115
+ };
116
+ }
117
+ const name = String(actor.name || `Actor ${index + 1}`).trim();
118
+ const id = actor.id || `actor-${name.toLowerCase().replace(/[^a-z0-9]+/g, '-') || (index + 1)}`;
119
+ return {
120
+ id,
121
+ name,
122
+ role: String(actor.role || name).trim(),
123
+ capabilities: Array.isArray(actor.capabilities) ? actor.capabilities.map(String) : ['view', 'search'],
124
+ permissions: Array.isArray(actor.permissions) ? actor.permissions.map(String) : ['read']
125
+ };
126
+ }
127
+
128
+ /**
129
+ * Validate & Normalize Entity Definition
130
+ */
131
+ static validateEntity(entity, index = 0) {
132
+ if (!entity || typeof entity !== 'object' || !entity.name) {
133
+ throw new Error(`Entity at index ${index} must have a valid string name.`);
134
+ }
135
+ const cleanName = String(entity.name).replace(/[^a-zA-Z0-9]/g, '');
136
+ if (!cleanName) {
137
+ throw new Error(`Entity name '${entity.name}' contains no alphanumeric characters.`);
138
+ }
139
+ const id = entity.id || `entity-${cleanName.toLowerCase()}`;
140
+ const title = entity.title || cleanName;
141
+ const plural = String(entity.plural || `${cleanName}s`).trim();
142
+ const description = String(entity.description || `Domain entity representing ${cleanName}`).trim();
143
+
144
+ const fields = Array.isArray(entity.fields) && entity.fields.length > 0
145
+ ? entity.fields.map((f, fi) => this.normalizeField(f, fi))
146
+ : [
147
+ { name: 'id', type: 'string', required: true, label: 'ID', sampleValue: `${id}-001` },
148
+ { name: 'name', type: 'string', required: true, label: 'Name', sampleValue: `Sample ${cleanName}` },
149
+ { name: 'status', type: 'string', required: false, label: 'Status', sampleValue: 'Active' },
150
+ { name: 'createdAt', type: 'datetime', required: true, label: 'Created At', sampleValue: '2026-08-31T00:00:00.000Z' }
151
+ ];
152
+
153
+ const relationships = Array.isArray(entity.relationships)
154
+ ? entity.relationships.map(r => this.normalizeRelationship(r, cleanName))
155
+ : [];
156
+
157
+ const constraints = Array.isArray(entity.constraints) ? entity.constraints.map(String) : [];
158
+ const seedData = Array.isArray(entity.seedData) ? entity.seedData : [];
159
+
160
+ return {
161
+ id,
162
+ name: cleanName,
163
+ title,
164
+ plural,
165
+ description,
166
+ fields,
167
+ relationships,
168
+ constraints,
169
+ seedData
170
+ };
171
+ }
172
+
173
+ /**
174
+ * Normalize an individual Field definition
175
+ */
176
+ static normalizeField(field, index = 0) {
177
+ if (typeof field === 'string') {
178
+ const isNum = /(count|price|depth|size|age|rating|score|amount|total|latitude|longitude|index|duration|tokens|ms|speed)/i.test(field);
179
+ const isDate = /(date|time|at|created|updated|scheduled|timestamp)/i.test(field);
180
+ const isBool = /(is|has|enabled|active|completed|verified)/i.test(field);
181
+ const type = field === 'id' ? 'string' : (isNum ? 'number' : (isDate ? 'datetime' : (isBool ? 'boolean' : 'string')));
182
+ return {
183
+ name: field,
184
+ type,
185
+ required: field === 'id' || field === 'name',
186
+ label: field.charAt(0).toUpperCase() + field.slice(1).replace(/([A-Z])/g, ' $1'),
187
+ sampleValue: isNum ? 100 : (isDate ? '2026-08-31T12:00:00.000Z' : (isBool ? true : `Sample ${field}`))
188
+ };
189
+ }
190
+ const name = String(field.name || `field_${index + 1}`).trim();
191
+ const type = String(field.type || 'string').toLowerCase();
192
+ const required = Boolean(field.required ?? (name === 'id' || name === 'name'));
193
+ const label = String(field.label || name.charAt(0).toUpperCase() + name.slice(1)).trim();
194
+ let sampleValue = field.sampleValue;
195
+ if (sampleValue === undefined) {
196
+ if (type === 'number') sampleValue = 42;
197
+ else if (type === 'boolean') sampleValue = true;
198
+ else if (type === 'datetime') sampleValue = '2026-08-31T12:00:00.000Z';
199
+ else sampleValue = `Sample ${label}`;
200
+ }
201
+ return {
202
+ name,
203
+ type,
204
+ required,
205
+ label,
206
+ sampleValue
207
+ };
208
+ }
209
+
210
+ /**
211
+ * Normalize an Entity Relationship
212
+ */
213
+ static normalizeRelationship(rel, sourceEntity) {
214
+ if (typeof rel === 'string') {
215
+ return {
216
+ type: 'belongsTo',
217
+ targetEntity: rel.replace(/[^a-zA-Z0-9]/g, ''),
218
+ foreignKey: `${rel.toLowerCase()}Id`
219
+ };
220
+ }
221
+ return {
222
+ type: rel.type || 'hasMany',
223
+ targetEntity: String(rel.targetEntity || rel.target || 'Entity').replace(/[^a-zA-Z0-9]/g, ''),
224
+ foreignKey: rel.foreignKey || (rel.type === 'belongsTo' ? `${(rel.targetEntity || 'entity').toLowerCase()}Id` : undefined),
225
+ cardinality: rel.cardinality || (rel.type === 'hasMany' ? '1:N' : 'N:1')
226
+ };
227
+ }
228
+
229
+ /**
230
+ * Validate & Normalize Workflow Definition
231
+ */
232
+ static validateWorkflow(wf, index = 0) {
233
+ if (!wf || typeof wf !== 'object') {
234
+ return {
235
+ id: `workflow-${index + 1}`,
236
+ name: `Workflow ${index + 1}`,
237
+ actor: 'User',
238
+ trigger: 'Manual Action',
239
+ steps: ['Initiate', 'Process', 'Complete'],
240
+ outcome: 'Completed'
241
+ };
242
+ }
243
+ const name = String(wf.name || `Workflow ${index + 1}`).trim();
244
+ const id = wf.id || `workflow-${name.toLowerCase().replace(/[^a-z0-9]+/g, '-') || (index + 1)}`;
245
+ return {
246
+ id,
247
+ name,
248
+ actor: String(wf.actor || 'User').trim(),
249
+ trigger: String(wf.trigger || 'Action Triggered').trim(),
250
+ steps: Array.isArray(wf.steps) ? wf.steps.map(String) : ['Execute action', 'Record state'],
251
+ outcome: String(wf.outcome || 'Workflow completed').trim()
252
+ };
253
+ }
254
+
255
+ /**
256
+ * Validate & Normalize View Definition
257
+ */
258
+ static validateView(view, entities = [], index = 0) {
259
+ if (!view || typeof view !== 'object') {
260
+ const fallbackEntity = entities[0] ? entities[0].name : 'Item';
261
+ return {
262
+ id: `view-${index + 1}`,
263
+ componentName: `${fallbackEntity}Overview`,
264
+ title: `${fallbackEntity} Overview`,
265
+ purpose: `Browse and manage ${fallbackEntity} records`,
266
+ targetEntities: [fallbackEntity],
267
+ layout: { type: LAYOUT_PRIMITIVES.GRID, density: 'comfortable' },
268
+ regions: [
269
+ { role: 'navigation', components: ['search', 'filter'] },
270
+ { role: 'content', components: ['collection'] }
271
+ ],
272
+ capabilities: ['search', 'filter', 'view']
273
+ };
274
+ }
275
+ const rawTitle = String(view.title || view.name || `View ${index + 1}`).trim();
276
+ const cleanComp = (view.componentName || rawTitle).replace(/[^a-zA-Z0-9]/g, '');
277
+ const componentName = cleanComp.charAt(0).toUpperCase() + cleanComp.slice(1) || `DynamicView${index + 1}`;
278
+ const id = view.id || `view-${componentName.toLowerCase()}`;
279
+ const targetEntities = Array.isArray(view.targetEntities) && view.targetEntities.length > 0
280
+ ? view.targetEntities.map(e => String(e).replace(/[^a-zA-Z0-9]/g, ''))
281
+ : (view.targetEntity ? [String(view.targetEntity).replace(/[^a-zA-Z0-9]/g, '')] : (entities[0] ? [entities[0].name] : ['System']));
282
+
283
+ const layout = typeof view.layout === 'object' && view.layout !== null
284
+ ? view.layout
285
+ : { type: LAYOUT_PRIMITIVES.GRID, density: 'comfortable' };
286
+
287
+ const regions = Array.isArray(view.regions) ? view.regions : [
288
+ { role: 'navigation', components: ['search', 'filter'] },
289
+ { role: 'content', components: ['collection'] }
290
+ ];
291
+
292
+ const capabilities = Array.isArray(view.capabilities) ? view.capabilities.map(String) : ['view', 'search', 'filter'];
293
+
294
+ return {
295
+ id,
296
+ componentName,
297
+ title: rawTitle,
298
+ purpose: String(view.purpose || `Interactive interface for ${rawTitle}`).trim(),
299
+ targetEntities,
300
+ layout,
301
+ regions,
302
+ capabilities
303
+ };
304
+ }
305
+
306
+ /**
307
+ * Validate & Normalize Operation Definition
308
+ */
309
+ static validateOperation(op, entities = [], index = 0) {
310
+ if (!op || typeof op !== 'object') {
311
+ const ent = entities[0] ? entities[0].name : 'Resource';
312
+ return {
313
+ id: `operation-${index + 1}`,
314
+ path: `/api/${ent.toLowerCase()}s`,
315
+ method: OPERATION_METHODS.GET,
316
+ description: `List ${ent} records`,
317
+ targetEntity: ent,
318
+ requestFields: [],
319
+ responseFields: [],
320
+ authorization: 'none'
321
+ };
322
+ }
323
+ const path = String(op.path || '/api/resource').startsWith('/') ? String(op.path || '/api/resource') : `/${op.path}`;
324
+ const method = Object.values(OPERATION_METHODS).includes(String(op.method).toUpperCase())
325
+ ? String(op.method).toUpperCase()
326
+ : OPERATION_METHODS.GET;
327
+ const targetEntity = String(op.targetEntity || (entities[0] ? entities[0].name : 'Entity')).replace(/[^a-zA-Z0-9]/g, '');
328
+ const id = op.id || `op-${method.toLowerCase()}-${path.replace(/[^a-zA-Z0-9]/g, '-')}`;
329
+
330
+ return {
331
+ id,
332
+ path,
333
+ method,
334
+ description: String(op.description || `Execute ${method} on ${path}`).trim(),
335
+ targetEntity,
336
+ requestFields: Array.isArray(op.requestFields) ? op.requestFields.map(String) : [],
337
+ responseFields: Array.isArray(op.responseFields) ? op.responseFields.map(String) : [],
338
+ authorization: String(op.authorization || 'none')
339
+ };
340
+ }
341
+
342
+ /**
343
+ * Validate & Normalize Event Definition
344
+ */
345
+ static validateEvent(evt, index = 0) {
346
+ if (!evt || typeof evt !== 'object') {
347
+ return {
348
+ id: `event-${index + 1}`,
349
+ name: `Event${index + 1}`,
350
+ source: 'System',
351
+ payload: { timestamp: 'datetime' },
352
+ consumers: ['AuditLogger']
353
+ };
354
+ }
355
+ const name = String(evt.name || `Event${index + 1}`).replace(/[^a-zA-Z0-9]/g, '');
356
+ return {
357
+ id: evt.id || `event-${name.toLowerCase()}`,
358
+ name,
359
+ source: String(evt.source || 'System').trim(),
360
+ payload: typeof evt.payload === 'object' && evt.payload !== null ? evt.payload : {},
361
+ consumers: Array.isArray(evt.consumers) ? evt.consumers.map(String) : []
362
+ };
363
+ }
364
+
365
+ /**
366
+ * Validate & Normalize Requirement Definition
367
+ */
368
+ static validateRequirement(req, index = 0) {
369
+ if (!req || typeof req !== 'object') {
370
+ return {
371
+ id: `REQ-${String(index + 1).padStart(3, '0')}`,
372
+ category: REQUIREMENT_CATEGORIES.WORKFLOW,
373
+ target: 'system',
374
+ description: 'System requirement',
375
+ acceptanceCriteria: ['Requirement fulfilled'],
376
+ priority: 'high'
377
+ };
378
+ }
379
+ const id = req.id || `REQ-${String(index + 1).padStart(3, '0')}`;
380
+ const category = Object.values(REQUIREMENT_CATEGORIES).includes(req.category)
381
+ ? req.category
382
+ : REQUIREMENT_CATEGORIES.WORKFLOW;
383
+ return {
384
+ id,
385
+ category,
386
+ target: String(req.target || 'system').trim(),
387
+ description: String(req.description || `Requirement ${id}`).trim(),
388
+ acceptanceCriteria: Array.isArray(req.acceptanceCriteria) && req.acceptanceCriteria.length > 0
389
+ ? req.acceptanceCriteria.map(String)
390
+ : ['Functionality implemented and verified'],
391
+ priority: ['critical', 'high', 'medium', 'low'].includes(req.priority) ? req.priority : 'high'
392
+ };
393
+ }
394
+ }