@itz4blitz/agentful 1.2.0 → 1.3.0
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 +28 -1
- package/bin/cli.js +11 -1055
- package/bin/hooks/block-file-creation.js +271 -0
- package/bin/hooks/product-spec-watcher.js +151 -0
- package/lib/index.js +0 -11
- package/lib/init.js +2 -21
- package/lib/parallel-execution.js +235 -0
- package/lib/presets.js +26 -4
- package/package.json +4 -7
- package/template/.claude/agents/architect.md +2 -2
- package/template/.claude/agents/backend.md +17 -30
- package/template/.claude/agents/frontend.md +17 -39
- package/template/.claude/agents/orchestrator.md +63 -4
- package/template/.claude/agents/product-analyzer.md +1 -1
- package/template/.claude/agents/tester.md +16 -29
- package/template/.claude/commands/agentful-generate.md +221 -14
- package/template/.claude/commands/agentful-init.md +621 -0
- package/template/.claude/commands/agentful-product.md +1 -1
- package/template/.claude/commands/agentful-start.md +99 -1
- package/template/.claude/product/EXAMPLES.md +2 -2
- package/template/.claude/product/index.md +1 -1
- package/template/.claude/settings.json +22 -0
- package/template/.claude/skills/research/SKILL.md +432 -0
- package/template/CLAUDE.md +5 -6
- package/template/bin/hooks/architect-drift-detector.js +242 -0
- package/template/bin/hooks/product-spec-watcher.js +151 -0
- package/version.json +1 -1
- package/bin/hooks/post-agent.js +0 -101
- package/bin/hooks/post-feature.js +0 -227
- package/bin/hooks/pre-agent.js +0 -118
- package/bin/hooks/pre-feature.js +0 -138
- package/lib/VALIDATION_README.md +0 -455
- package/lib/ci/claude-action-integration.js +0 -641
- package/lib/ci/index.js +0 -10
- package/lib/core/analyzer.js +0 -497
- package/lib/core/cli.js +0 -141
- package/lib/core/detectors/conventions.js +0 -342
- package/lib/core/detectors/framework.js +0 -276
- package/lib/core/detectors/index.js +0 -15
- package/lib/core/detectors/language.js +0 -199
- package/lib/core/detectors/patterns.js +0 -356
- package/lib/core/generator.js +0 -626
- package/lib/core/index.js +0 -9
- package/lib/core/output-parser.js +0 -458
- package/lib/core/storage.js +0 -515
- package/lib/core/templates.js +0 -556
- package/lib/pipeline/cli.js +0 -423
- package/lib/pipeline/engine.js +0 -928
- package/lib/pipeline/executor.js +0 -440
- package/lib/pipeline/index.js +0 -33
- package/lib/pipeline/integrations.js +0 -559
- package/lib/pipeline/schemas.js +0 -288
- package/lib/remote/client.js +0 -361
- package/lib/server/auth.js +0 -270
- package/lib/server/client-example.js +0 -190
- package/lib/server/executor.js +0 -477
- package/lib/server/index.js +0 -494
- package/lib/update-helpers.js +0 -505
- package/lib/validation.js +0 -460
package/lib/validation.js
DELETED
|
@@ -1,460 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import Ajv from 'ajv';
|
|
3
|
-
import addFormats from 'ajv-formats';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Centralized Validation Library
|
|
7
|
-
*
|
|
8
|
-
* Provides unified validation functions for state files with:
|
|
9
|
-
* - File existence checks
|
|
10
|
-
* - JSON parsing validation
|
|
11
|
-
* - Schema validation using AJV
|
|
12
|
-
* - Required field validation
|
|
13
|
-
*
|
|
14
|
-
* Standardized action codes:
|
|
15
|
-
* - "missing": File does not exist
|
|
16
|
-
* - "corrupted": File exists but is not valid JSON
|
|
17
|
-
* - "invalid": JSON is valid but doesn't match schema
|
|
18
|
-
* - "incomplete": Schema is valid but required fields are missing
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
// Initialize AJV with formats support
|
|
22
|
-
const ajv = new Ajv({ allErrors: true });
|
|
23
|
-
addFormats(ajv);
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* JSON Schemas for state files
|
|
27
|
-
*/
|
|
28
|
-
export const schemas = {
|
|
29
|
-
state: {
|
|
30
|
-
type: 'object',
|
|
31
|
-
required: ['initialized', 'version', 'agents', 'skills'],
|
|
32
|
-
properties: {
|
|
33
|
-
initialized: {
|
|
34
|
-
type: 'string',
|
|
35
|
-
format: 'date-time'
|
|
36
|
-
},
|
|
37
|
-
version: {
|
|
38
|
-
type: 'string',
|
|
39
|
-
pattern: '^\\d+\\.\\d+\\.\\d+$'
|
|
40
|
-
},
|
|
41
|
-
agents: {
|
|
42
|
-
type: 'array',
|
|
43
|
-
items: {
|
|
44
|
-
type: 'string'
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
skills: {
|
|
48
|
-
type: 'array',
|
|
49
|
-
items: {
|
|
50
|
-
type: 'string'
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
additionalProperties: true
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
completion: {
|
|
58
|
-
type: 'object',
|
|
59
|
-
required: ['agents', 'skills', 'lastUpdated'],
|
|
60
|
-
properties: {
|
|
61
|
-
agents: {
|
|
62
|
-
type: 'object',
|
|
63
|
-
additionalProperties: {
|
|
64
|
-
type: 'object',
|
|
65
|
-
properties: {
|
|
66
|
-
completed: { type: 'boolean' },
|
|
67
|
-
progress: { type: 'number', minimum: 0, maximum: 100 }
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
skills: {
|
|
72
|
-
type: 'object',
|
|
73
|
-
additionalProperties: {
|
|
74
|
-
type: 'object',
|
|
75
|
-
properties: {
|
|
76
|
-
completed: { type: 'boolean' },
|
|
77
|
-
progress: { type: 'number', minimum: 0, maximum: 100 }
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
lastUpdated: {
|
|
82
|
-
type: 'string',
|
|
83
|
-
format: 'date-time'
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
additionalProperties: true
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
decisions: {
|
|
90
|
-
type: 'object',
|
|
91
|
-
required: ['decisions', 'lastUpdated'],
|
|
92
|
-
properties: {
|
|
93
|
-
decisions: {
|
|
94
|
-
type: 'array',
|
|
95
|
-
items: {
|
|
96
|
-
type: 'object',
|
|
97
|
-
required: ['id', 'question', 'status'],
|
|
98
|
-
properties: {
|
|
99
|
-
id: { type: 'string' },
|
|
100
|
-
question: { type: 'string' },
|
|
101
|
-
status: {
|
|
102
|
-
type: 'string',
|
|
103
|
-
enum: ['pending', 'answered', 'cancelled']
|
|
104
|
-
},
|
|
105
|
-
answer: { type: 'string' },
|
|
106
|
-
context: { type: 'string' },
|
|
107
|
-
created: { type: 'string', format: 'date-time' },
|
|
108
|
-
updated: { type: 'string', format: 'date-time' }
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
},
|
|
112
|
-
lastUpdated: {
|
|
113
|
-
type: 'string',
|
|
114
|
-
format: 'date-time'
|
|
115
|
-
}
|
|
116
|
-
},
|
|
117
|
-
additionalProperties: false
|
|
118
|
-
},
|
|
119
|
-
|
|
120
|
-
architecture: {
|
|
121
|
-
type: 'object',
|
|
122
|
-
required: ['version', 'analyzedAt', 'projectRoot', 'fileCount', 'confidence', 'languages', 'frameworks', 'patterns', 'conventions', 'recommendations'],
|
|
123
|
-
properties: {
|
|
124
|
-
version: { type: 'string' },
|
|
125
|
-
analyzedAt: {
|
|
126
|
-
type: 'string',
|
|
127
|
-
format: 'date-time'
|
|
128
|
-
},
|
|
129
|
-
duration: { type: 'number' },
|
|
130
|
-
projectRoot: { type: 'string' },
|
|
131
|
-
fileCount: { type: 'number', minimum: 0 },
|
|
132
|
-
isNewProject: { type: 'boolean' },
|
|
133
|
-
confidence: { type: 'number', minimum: 0, maximum: 100 },
|
|
134
|
-
languages: {
|
|
135
|
-
type: 'array',
|
|
136
|
-
items: {
|
|
137
|
-
type: 'object',
|
|
138
|
-
required: ['name', 'confidence', 'files'],
|
|
139
|
-
properties: {
|
|
140
|
-
name: { type: 'string' },
|
|
141
|
-
confidence: { type: 'number' },
|
|
142
|
-
files: { type: 'number' },
|
|
143
|
-
percentage: { type: 'number' },
|
|
144
|
-
extensions: { type: 'array', items: { type: 'string' } }
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
},
|
|
148
|
-
primaryLanguage: { type: ['string', 'null'] },
|
|
149
|
-
frameworks: {
|
|
150
|
-
type: 'array',
|
|
151
|
-
items: {
|
|
152
|
-
type: 'object',
|
|
153
|
-
required: ['name', 'confidence'],
|
|
154
|
-
properties: {
|
|
155
|
-
name: { type: 'string' },
|
|
156
|
-
version: { type: 'string' },
|
|
157
|
-
type: { type: 'string' },
|
|
158
|
-
category: { type: 'string' },
|
|
159
|
-
confidence: { type: 'number' },
|
|
160
|
-
source: { type: 'string' }
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
},
|
|
164
|
-
patterns: {
|
|
165
|
-
type: 'object',
|
|
166
|
-
properties: {
|
|
167
|
-
components: { type: 'object' },
|
|
168
|
-
api: { type: 'object' },
|
|
169
|
-
database: { type: 'object' },
|
|
170
|
-
tests: { type: 'object' },
|
|
171
|
-
auth: { type: 'object' }
|
|
172
|
-
}
|
|
173
|
-
},
|
|
174
|
-
conventions: {
|
|
175
|
-
type: 'object'
|
|
176
|
-
},
|
|
177
|
-
recommendations: {
|
|
178
|
-
type: 'array',
|
|
179
|
-
items: {
|
|
180
|
-
type: 'object',
|
|
181
|
-
required: ['type', 'priority', 'message', 'action'],
|
|
182
|
-
properties: {
|
|
183
|
-
type: { type: 'string' },
|
|
184
|
-
priority: { type: 'string' },
|
|
185
|
-
message: { type: 'string' },
|
|
186
|
-
action: { type: 'string' }
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
},
|
|
191
|
-
additionalProperties: true
|
|
192
|
-
},
|
|
193
|
-
|
|
194
|
-
product: {
|
|
195
|
-
type: 'object',
|
|
196
|
-
required: ['name', 'description', 'features', 'lastUpdated'],
|
|
197
|
-
properties: {
|
|
198
|
-
name: { type: 'string' },
|
|
199
|
-
description: { type: 'string' },
|
|
200
|
-
features: {
|
|
201
|
-
type: 'array',
|
|
202
|
-
items: {
|
|
203
|
-
type: 'object',
|
|
204
|
-
required: ['id', 'name'],
|
|
205
|
-
properties: {
|
|
206
|
-
id: { type: 'string' },
|
|
207
|
-
name: { type: 'string' },
|
|
208
|
-
description: { type: 'string' },
|
|
209
|
-
priority: {
|
|
210
|
-
type: 'string',
|
|
211
|
-
enum: ['high', 'medium', 'low']
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
},
|
|
216
|
-
lastUpdated: {
|
|
217
|
-
type: 'string',
|
|
218
|
-
format: 'date-time'
|
|
219
|
-
}
|
|
220
|
-
},
|
|
221
|
-
additionalProperties: true
|
|
222
|
-
}
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
// Compile all schemas
|
|
226
|
-
const compiledSchemas = {
|
|
227
|
-
state: ajv.compile(schemas.state),
|
|
228
|
-
completion: ajv.compile(schemas.completion),
|
|
229
|
-
decisions: ajv.compile(schemas.decisions),
|
|
230
|
-
architecture: ajv.compile(schemas.architecture),
|
|
231
|
-
product: ajv.compile(schemas.product)
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Unified validation function for state files
|
|
236
|
-
*
|
|
237
|
-
* @param {string} filePath - Absolute path to the file to validate
|
|
238
|
-
* @param {string} schemaName - Name of schema to use ('state', 'completion', 'decisions', 'architecture', 'product')
|
|
239
|
-
* @param {string[]} requiredFields - Additional required fields to check beyond schema
|
|
240
|
-
* @returns {Object} Validation result with standardized structure
|
|
241
|
-
*
|
|
242
|
-
* Return format for invalid:
|
|
243
|
-
* { valid: false, action: "missing" | "corrupted" | "invalid" | "incomplete", errors?: array, missing_field?: string }
|
|
244
|
-
*
|
|
245
|
-
* Return format for valid:
|
|
246
|
-
* { valid: true, content: object }
|
|
247
|
-
*/
|
|
248
|
-
export function validateStateFile(filePath, schemaName, requiredFields = []) {
|
|
249
|
-
// 1. Check file exists
|
|
250
|
-
if (!fs.existsSync(filePath)) {
|
|
251
|
-
return {
|
|
252
|
-
valid: false,
|
|
253
|
-
action: 'missing',
|
|
254
|
-
error: `File not found: ${filePath}`
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// 2. Parse JSON
|
|
259
|
-
let content;
|
|
260
|
-
try {
|
|
261
|
-
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
|
262
|
-
content = JSON.parse(fileContent);
|
|
263
|
-
} catch (error) {
|
|
264
|
-
return {
|
|
265
|
-
valid: false,
|
|
266
|
-
action: 'corrupted',
|
|
267
|
-
error: `Invalid JSON in ${filePath}: ${error.message}`
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// 3. Validate against schema using AJV
|
|
272
|
-
const validator = compiledSchemas[schemaName];
|
|
273
|
-
if (!validator) {
|
|
274
|
-
throw new Error(`Unknown schema name: ${schemaName}. Valid schemas: ${Object.keys(compiledSchemas).join(', ')}`);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
const schemaValid = validator(content);
|
|
278
|
-
if (!schemaValid) {
|
|
279
|
-
return {
|
|
280
|
-
valid: false,
|
|
281
|
-
action: 'invalid',
|
|
282
|
-
errors: validator.errors,
|
|
283
|
-
error: `Schema validation failed for ${filePath}`
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// 4. Check additional required fields
|
|
288
|
-
for (const field of requiredFields) {
|
|
289
|
-
if (!(field in content)) {
|
|
290
|
-
return {
|
|
291
|
-
valid: false,
|
|
292
|
-
action: 'incomplete',
|
|
293
|
-
missing_field: field,
|
|
294
|
-
error: `Missing required field '${field}' in ${filePath}`
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// 5. Success
|
|
300
|
-
return {
|
|
301
|
-
valid: true,
|
|
302
|
-
content
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Validate state.json file
|
|
308
|
-
*
|
|
309
|
-
* @param {string} filePath - Path to state.json (defaults to .agentful/state.json)
|
|
310
|
-
* @param {string[]} additionalFields - Additional required fields beyond schema
|
|
311
|
-
* @returns {Object} Validation result
|
|
312
|
-
*/
|
|
313
|
-
export function validateState(filePath = '.agentful/state.json', additionalFields = []) {
|
|
314
|
-
return validateStateFile(filePath, 'state', additionalFields);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
/**
|
|
318
|
-
* Validate completion.json file
|
|
319
|
-
*
|
|
320
|
-
* @param {string} filePath - Path to completion.json (defaults to .agentful/completion.json)
|
|
321
|
-
* @param {string[]} additionalFields - Additional required fields beyond schema
|
|
322
|
-
* @returns {Object} Validation result
|
|
323
|
-
*/
|
|
324
|
-
export function validateCompletion(filePath = '.agentful/completion.json', additionalFields = []) {
|
|
325
|
-
return validateStateFile(filePath, 'completion', additionalFields);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* Validate decisions.json file
|
|
330
|
-
*
|
|
331
|
-
* @param {string} filePath - Path to decisions.json (defaults to .agentful/decisions.json)
|
|
332
|
-
* @param {string[]} additionalFields - Additional required fields beyond schema
|
|
333
|
-
* @returns {Object} Validation result
|
|
334
|
-
*/
|
|
335
|
-
export function validateDecisions(filePath = '.agentful/decisions.json', additionalFields = []) {
|
|
336
|
-
return validateStateFile(filePath, 'decisions', additionalFields);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
/**
|
|
340
|
-
* Validate architecture.json file
|
|
341
|
-
*
|
|
342
|
-
* @param {string} filePath - Path to architecture.json (defaults to .agentful/architecture.json)
|
|
343
|
-
* @param {string[]} additionalFields - Additional required fields beyond schema
|
|
344
|
-
* @returns {Object} Validation result
|
|
345
|
-
*/
|
|
346
|
-
export function validateArchitecture(filePath = '.agentful/architecture.json', additionalFields = []) {
|
|
347
|
-
return validateStateFile(filePath, 'architecture', additionalFields);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* Validate product.json file
|
|
352
|
-
*
|
|
353
|
-
* @param {string} filePath - Path to product.json (defaults to .agentful/product.json)
|
|
354
|
-
* @param {string[]} additionalFields - Additional required fields beyond schema
|
|
355
|
-
* @returns {Object} Validation result
|
|
356
|
-
*/
|
|
357
|
-
export function validateProduct(filePath = '.agentful/product.json', additionalFields = []) {
|
|
358
|
-
return validateStateFile(filePath, 'product', additionalFields);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* Batch validate multiple state files
|
|
363
|
-
*
|
|
364
|
-
* @param {Object[]} files - Array of {filePath, schemaName, requiredFields?}
|
|
365
|
-
* @returns {Object} Map of filePath to validation result
|
|
366
|
-
*
|
|
367
|
-
* Example:
|
|
368
|
-
* const results = validateBatch([
|
|
369
|
-
* { filePath: '.agentful/state.json', schemaName: 'state' },
|
|
370
|
-
* { filePath: '.agentful/completion.json', schemaName: 'completion', requiredFields: ['gates'] }
|
|
371
|
-
* ]);
|
|
372
|
-
*/
|
|
373
|
-
export function validateBatch(files) {
|
|
374
|
-
const results = {};
|
|
375
|
-
|
|
376
|
-
for (const { filePath, schemaName, requiredFields = [] } of files) {
|
|
377
|
-
results[filePath] = validateStateFile(filePath, schemaName, requiredFields);
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
return results;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
/**
|
|
384
|
-
* Get human-readable error message for validation result
|
|
385
|
-
*
|
|
386
|
-
* @param {Object} validationResult - Result from validateStateFile
|
|
387
|
-
* @returns {string} Human-readable error message
|
|
388
|
-
*/
|
|
389
|
-
export function getErrorMessage(validationResult) {
|
|
390
|
-
if (validationResult.valid) {
|
|
391
|
-
return 'Validation passed';
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
switch (validationResult.action) {
|
|
395
|
-
case 'missing':
|
|
396
|
-
return `File not found. Initialize it first.`;
|
|
397
|
-
|
|
398
|
-
case 'corrupted':
|
|
399
|
-
return `File is corrupted (invalid JSON). Backup and reset recommended.`;
|
|
400
|
-
|
|
401
|
-
case 'invalid':
|
|
402
|
-
if (validationResult.errors && validationResult.errors.length > 0) {
|
|
403
|
-
const errorDetails = validationResult.errors
|
|
404
|
-
.map(err => ` - ${err.instancePath || 'root'}: ${err.message}`)
|
|
405
|
-
.join('\n');
|
|
406
|
-
return `Schema validation failed:\n${errorDetails}`;
|
|
407
|
-
}
|
|
408
|
-
return `Schema validation failed.`;
|
|
409
|
-
|
|
410
|
-
case 'incomplete':
|
|
411
|
-
return `Missing required field: '${validationResult.missing_field}'`;
|
|
412
|
-
|
|
413
|
-
default:
|
|
414
|
-
return validationResult.error || 'Unknown validation error';
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
/**
|
|
419
|
-
* Suggested action for validation result
|
|
420
|
-
*
|
|
421
|
-
* @param {Object} validationResult - Result from validateStateFile
|
|
422
|
-
* @returns {string} Suggested action to fix the issue
|
|
423
|
-
*/
|
|
424
|
-
export function getSuggestedAction(validationResult) {
|
|
425
|
-
if (validationResult.valid) {
|
|
426
|
-
return 'No action needed';
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
switch (validationResult.action) {
|
|
430
|
-
case 'missing':
|
|
431
|
-
return 'Run initialization command to create the file';
|
|
432
|
-
|
|
433
|
-
case 'corrupted':
|
|
434
|
-
return 'Backup the file and create a new one with valid JSON';
|
|
435
|
-
|
|
436
|
-
case 'invalid':
|
|
437
|
-
return 'Fix schema validation errors in the file';
|
|
438
|
-
|
|
439
|
-
case 'incomplete':
|
|
440
|
-
return `Add the missing field: '${validationResult.missing_field}'`;
|
|
441
|
-
|
|
442
|
-
default:
|
|
443
|
-
return 'Check the file and fix any issues';
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* Export AJV instance for custom schemas
|
|
449
|
-
*/
|
|
450
|
-
export { ajv };
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Export action constants for easy reference
|
|
454
|
-
*/
|
|
455
|
-
export const ValidationActions = {
|
|
456
|
-
MISSING: 'missing',
|
|
457
|
-
CORRUPTED: 'corrupted',
|
|
458
|
-
INVALID: 'invalid',
|
|
459
|
-
INCOMPLETE: 'incomplete'
|
|
460
|
-
};
|