@wrongstack/requirement-intake 1.0.24 → 1.0.26
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/dist/index.d.ts +1 -1
- package/dist/index.js +58 -16
- package/dist/validation.d.ts +52 -2
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,6 @@ export { type IntakeCreateResult, type IntakeListFilter, type IntakeSubmitResult
|
|
|
17
17
|
export { type IntakeIndexEntry, newIntakeId, RequirementIntakeStore, type RequirementIntakeStoreOptions, type StoreCreateResult, type StoreUpdateOptions, } from './store.js';
|
|
18
18
|
export { assertSuggestionString, type LlmSuggestionGenerator, type LlmSuggestionOutput, type LlmSuggestionRequest, llmSuggestionOutputSchema, type NormalizedLlmSuggestion, toProposals, validateLlmSuggestionOutput, } from './suggestions.js';
|
|
19
19
|
export { type AddAnswerInput, type AttachResourceInput, type ChangeHistoryEntry, type CreateIntakeInput, INTAKE_EVENT_NAMES, type IntakeActor, type IntakeAnswer, type IntakeAttachment, type IntakeAttachmentInput, type IntakeContext, type IntakeEvent, type IntakeEventName, type IntakeQuestion, type IntakeQuestionTemplateInput, type LlmSuggestionProposal, type RelatedResource, type RelatedResourceInput, type RequirementIntakeRecord, type UpdateIntakeInput, } from './types.js';
|
|
20
|
-
export { answerInputSchema, attachmentInputSchema, attachResourceInputSchema, createIntakeSchema, deterministicSummary, deterministicTitle, isBlank, metadataSchema, normalizeRequestType, parseWithIssues, prioritySchema, questionTemplateInputSchema, relatedResourceInputSchema, requestTypeSchema, updateIntakeSchema, validateAnswerInput, validateAttachmentInput, validateAttachResourceInput, validateCreateInput, validateFieldSource, validateQuestionTemplateInput, validateRelatedResourceInput, validateUpdateInput, } from './validation.js';
|
|
20
|
+
export { answerInputSchema, attachmentInputSchema, attachResourceInputSchema, createIntakeSchema, deterministicSummary, deterministicTitle, isBlank, metadataSchema, normalizeRequestType, parseWithIssues, prioritySchema, questionTemplateInputSchema, relatedResourceInputSchema, requestTypeSchema, updateIntakeSchema, validateAnswerInput, validateAttachmentInput, validateAttachResourceInput, validateCreateInput, validateFieldSource, validateQuestionTemplateInput, validateRelatedResourceInput, validateUpdateInput, vibeProtocolStateSchema, } from './validation.js';
|
|
21
21
|
export { deriveVibeState, hasVibeTag, stripVibeTag, VIBE_TAG_REGEX, type VibeProtocolStage, type VibeProtocolState, } from './vibe.js';
|
|
22
22
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -413,6 +413,19 @@ var IDEMPOTENCY_PATH = "_idempotency.json";
|
|
|
413
413
|
function hashIdempotencyKey(key) {
|
|
414
414
|
return createHash("sha256").update(key, "utf8").digest("hex");
|
|
415
415
|
}
|
|
416
|
+
function indexEntryFor(record) {
|
|
417
|
+
return {
|
|
418
|
+
id: record.id,
|
|
419
|
+
projectId: record.projectId,
|
|
420
|
+
title: record.title,
|
|
421
|
+
status: record.status,
|
|
422
|
+
requestType: record.requestType,
|
|
423
|
+
priority: record.priority,
|
|
424
|
+
requestedBy: record.requestedBy,
|
|
425
|
+
updatedAt: record.updatedAt,
|
|
426
|
+
createdAt: record.createdAt
|
|
427
|
+
};
|
|
428
|
+
}
|
|
416
429
|
var RequirementIntakeStore = class {
|
|
417
430
|
baseDir;
|
|
418
431
|
indexPath;
|
|
@@ -566,26 +579,37 @@ var RequirementIntakeStore = class {
|
|
|
566
579
|
const raw = await fsp.readFile(this.indexPath, "utf8");
|
|
567
580
|
const parsed = JSON.parse(raw);
|
|
568
581
|
if (parsed?.version === 1 && Array.isArray(parsed.entries)) return parsed;
|
|
569
|
-
} catch {
|
|
582
|
+
} catch (error) {
|
|
583
|
+
if (error.code !== "ENOENT" && !(error instanceof SyntaxError)) {
|
|
584
|
+
throw error;
|
|
585
|
+
}
|
|
570
586
|
}
|
|
571
|
-
|
|
587
|
+
let files;
|
|
588
|
+
try {
|
|
589
|
+
files = await fsp.readdir(this.baseDir);
|
|
590
|
+
} catch (error) {
|
|
591
|
+
if (error.code === "ENOENT") return { version: 1, entries: [] };
|
|
592
|
+
throw error;
|
|
593
|
+
}
|
|
594
|
+
const entries = [];
|
|
595
|
+
for (const file of files) {
|
|
596
|
+
if (file === INDEX_PATH || file === IDEMPOTENCY_PATH || !file.endsWith(".json")) continue;
|
|
597
|
+
const id = file.slice(0, -".json".length);
|
|
598
|
+
if (!/^[A-Za-z0-9_-]{1,128}$/.test(id)) continue;
|
|
599
|
+
const record = JSON.parse(
|
|
600
|
+
await fsp.readFile(path.join(this.baseDir, file), "utf8")
|
|
601
|
+
);
|
|
602
|
+
if (record?.id !== id) throw new Error(`Invalid requirement intake record: ${file}`);
|
|
603
|
+
entries.push(indexEntryFor(record));
|
|
604
|
+
}
|
|
605
|
+
return { version: 1, entries };
|
|
572
606
|
}
|
|
573
607
|
async updateIndexFor(record) {
|
|
574
608
|
return withFileLock(
|
|
575
609
|
this.indexPath,
|
|
576
610
|
async () => {
|
|
577
611
|
const index = await this.readIndex();
|
|
578
|
-
const entry =
|
|
579
|
-
id: record.id,
|
|
580
|
-
projectId: record.projectId,
|
|
581
|
-
title: record.title,
|
|
582
|
-
status: record.status,
|
|
583
|
-
requestType: record.requestType,
|
|
584
|
-
priority: record.priority,
|
|
585
|
-
requestedBy: record.requestedBy,
|
|
586
|
-
updatedAt: record.updatedAt,
|
|
587
|
-
createdAt: record.createdAt
|
|
588
|
-
};
|
|
612
|
+
const entry = indexEntryFor(record);
|
|
589
613
|
const position = index.entries.findIndex((candidate) => candidate.id === record.id);
|
|
590
614
|
if (position >= 0) {
|
|
591
615
|
index.entries[position] = entry;
|
|
@@ -691,6 +715,15 @@ var optionalString = (max) => z.string().max(max).optional();
|
|
|
691
715
|
var optionalStringArray = z.array(z.string().trim().min(1).max(MAX_STRING_FIELD_LENGTH)).max(MAX_ARRAY_ITEMS).optional();
|
|
692
716
|
var optionalAttachmentArray = z.array(attachmentInputSchema).max(MAX_ATTACHMENTS).optional();
|
|
693
717
|
var optionalRelatedResourceArray = z.array(relatedResourceInputSchema).max(MAX_RELATED_RESOURCES).optional();
|
|
718
|
+
var vibeProtocolStateSchema = z.object({
|
|
719
|
+
isVibeMode: z.literal(true),
|
|
720
|
+
detectedAt: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
|
|
721
|
+
stage: z.enum(["synthesizer", "coder", "auditor", "passed"]),
|
|
722
|
+
synthesizedSpec: z.string().max(MAX_ANSWER_LENGTH).optional(),
|
|
723
|
+
coderContract: z.string().max(MAX_ANSWER_LENGTH).optional(),
|
|
724
|
+
auditVerdict: z.enum(["PASS", "REJECT"]).optional(),
|
|
725
|
+
auditNotes: z.array(z.string().max(MAX_STRING_FIELD_LENGTH)).max(MAX_ARRAY_ITEMS).optional()
|
|
726
|
+
}).strict();
|
|
694
727
|
var createIntakeSchema = z.object({
|
|
695
728
|
projectId: idSchema,
|
|
696
729
|
originalRequest: nonBlankString(MAX_REQUEST_LENGTH, "originalRequest"),
|
|
@@ -711,7 +744,7 @@ var createIntakeSchema = z.object({
|
|
|
711
744
|
knownFields: z.array(z.string().trim().min(1).max(64)).max(MAX_ARRAY_ITEMS).optional(),
|
|
712
745
|
questions: z.array(questionTemplateInputSchema).max(50).optional(),
|
|
713
746
|
isVibeMode: z.boolean().optional(),
|
|
714
|
-
vibeProtocol:
|
|
747
|
+
vibeProtocol: vibeProtocolStateSchema.optional()
|
|
715
748
|
}).strict();
|
|
716
749
|
var updateIntakeSchema = z.object({
|
|
717
750
|
title: optionalString(MAX_TITLE_LENGTH),
|
|
@@ -725,7 +758,7 @@ var updateIntakeSchema = z.object({
|
|
|
725
758
|
providedContext: optionalStringArray,
|
|
726
759
|
metadata: metadataSchema.optional(),
|
|
727
760
|
isVibeMode: z.boolean().optional(),
|
|
728
|
-
vibeProtocol:
|
|
761
|
+
vibeProtocol: vibeProtocolStateSchema.optional()
|
|
729
762
|
}).strict();
|
|
730
763
|
var answerInputSchema = z.object({
|
|
731
764
|
field: nonBlankString(64, "answer field"),
|
|
@@ -1384,6 +1417,7 @@ var RequirementIntakeService = class {
|
|
|
1384
1417
|
throw new IntakeValidationError([{ field: "title", message: "title must not be blank" }]);
|
|
1385
1418
|
}
|
|
1386
1419
|
return this.store.update(id, this.updateMeta(ctx, "updated", changedKeys, expectedVersion), (next) => {
|
|
1420
|
+
this.assertMutable(next, "updateIntake");
|
|
1387
1421
|
if (validated.title !== void 0) {
|
|
1388
1422
|
next.title = validated.title.trim();
|
|
1389
1423
|
next.fieldSources.title = "user";
|
|
@@ -1421,6 +1455,7 @@ var RequirementIntakeService = class {
|
|
|
1421
1455
|
id,
|
|
1422
1456
|
this.updateMeta(ctx, "answer_added", [validated.field], expectedVersion),
|
|
1423
1457
|
(next) => {
|
|
1458
|
+
this.assertMutable(next, "addAnswer");
|
|
1424
1459
|
applyAnswerToRecord(next, validated, ctx.id, Date.now());
|
|
1425
1460
|
}
|
|
1426
1461
|
).then((updated) => {
|
|
@@ -1438,6 +1473,7 @@ var RequirementIntakeService = class {
|
|
|
1438
1473
|
})
|
|
1439
1474
|
);
|
|
1440
1475
|
return this.store.update(id, this.updateMeta(ctx, "answer_updated", [answerId], expectedVersion), (next) => {
|
|
1476
|
+
this.assertMutable(next, "updateAnswer");
|
|
1441
1477
|
applyAnswerUpdateToRecord(next, answerId, validated.answer);
|
|
1442
1478
|
}).then((updated) => {
|
|
1443
1479
|
this.afterMutation(updated, ctx, "RequirementIntakeUpdated");
|
|
@@ -1454,6 +1490,7 @@ var RequirementIntakeService = class {
|
|
|
1454
1490
|
id,
|
|
1455
1491
|
this.updateMeta(ctx, "attachment_added", ["attachments"], expectedVersion),
|
|
1456
1492
|
(next) => {
|
|
1493
|
+
this.assertMutable(next, "attachResource");
|
|
1457
1494
|
applyAttachmentToRecord(next, validated, ctx.id, now);
|
|
1458
1495
|
}
|
|
1459
1496
|
).then((updated) => {
|
|
@@ -1465,6 +1502,7 @@ var RequirementIntakeService = class {
|
|
|
1465
1502
|
id,
|
|
1466
1503
|
this.updateMeta(ctx, "related_resource_added", ["related_resources"], expectedVersion),
|
|
1467
1504
|
(next) => {
|
|
1505
|
+
this.assertMutable(next, "attachResource");
|
|
1468
1506
|
applyRelatedResourceToRecord(next, validated, ctx.id, now);
|
|
1469
1507
|
}
|
|
1470
1508
|
).then((updated) => {
|
|
@@ -1520,6 +1558,7 @@ var RequirementIntakeService = class {
|
|
|
1520
1558
|
to: previousStatus === nextStatus ? void 0 : nextStatus
|
|
1521
1559
|
},
|
|
1522
1560
|
(next) => {
|
|
1561
|
+
this.assertMutable(next, "generateSuggestions");
|
|
1523
1562
|
next.llmSuggestions.push(...proposals);
|
|
1524
1563
|
if (next.llmSuggestions.length > MAX_SUGGESTIONS) {
|
|
1525
1564
|
next.llmSuggestions = next.llmSuggestions.slice(
|
|
@@ -1561,6 +1600,7 @@ var RequirementIntakeService = class {
|
|
|
1561
1600
|
id,
|
|
1562
1601
|
this.updateMeta(ctx, "suggestion_accepted", [proposal2.kind], expectedVersion),
|
|
1563
1602
|
(next) => {
|
|
1603
|
+
this.assertMutable(next, "acceptSuggestion");
|
|
1564
1604
|
const target = next.llmSuggestions.find((candidate) => candidate.id === proposalId);
|
|
1565
1605
|
if (!target) {
|
|
1566
1606
|
throw new IntakeValidationError([
|
|
@@ -1584,6 +1624,7 @@ var RequirementIntakeService = class {
|
|
|
1584
1624
|
id,
|
|
1585
1625
|
this.updateMeta(ctx, "suggestion_rejected", [proposalId], expectedVersion),
|
|
1586
1626
|
(next) => {
|
|
1627
|
+
this.assertMutable(next, "rejectSuggestion");
|
|
1587
1628
|
const target = next.llmSuggestions.find((candidate) => candidate.id === proposalId);
|
|
1588
1629
|
if (!target) {
|
|
1589
1630
|
throw new IntakeValidationError([
|
|
@@ -1915,6 +1956,7 @@ export {
|
|
|
1915
1956
|
validateLlmSuggestionOutput,
|
|
1916
1957
|
validateQuestionTemplateInput,
|
|
1917
1958
|
validateRelatedResourceInput,
|
|
1918
|
-
validateUpdateInput
|
|
1959
|
+
validateUpdateInput,
|
|
1960
|
+
vibeProtocolStateSchema
|
|
1919
1961
|
};
|
|
1920
1962
|
//# sourceMappingURL=index.js.map
|
package/dist/validation.d.ts
CHANGED
|
@@ -75,6 +75,24 @@ export declare const questionTemplateInputSchema: z.ZodObject<{
|
|
|
75
75
|
required: z.ZodOptional<z.ZodBoolean>;
|
|
76
76
|
}, z.core.$strip>;
|
|
77
77
|
export declare const metadataSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
78
|
+
/** Strict, bounded representation of resumable VIBE protocol state. */
|
|
79
|
+
export declare const vibeProtocolStateSchema: z.ZodObject<{
|
|
80
|
+
isVibeMode: z.ZodLiteral<true>;
|
|
81
|
+
detectedAt: z.ZodNumber;
|
|
82
|
+
stage: z.ZodEnum<{
|
|
83
|
+
auditor: "auditor";
|
|
84
|
+
coder: "coder";
|
|
85
|
+
passed: "passed";
|
|
86
|
+
synthesizer: "synthesizer";
|
|
87
|
+
}>;
|
|
88
|
+
synthesizedSpec: z.ZodOptional<z.ZodString>;
|
|
89
|
+
coderContract: z.ZodOptional<z.ZodString>;
|
|
90
|
+
auditVerdict: z.ZodOptional<z.ZodEnum<{
|
|
91
|
+
PASS: "PASS";
|
|
92
|
+
REJECT: "REJECT";
|
|
93
|
+
}>>;
|
|
94
|
+
auditNotes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
95
|
+
}, z.core.$strict>;
|
|
78
96
|
export declare const createIntakeSchema: z.ZodObject<{
|
|
79
97
|
projectId: z.ZodString;
|
|
80
98
|
originalRequest: z.ZodString;
|
|
@@ -129,7 +147,23 @@ export declare const createIntakeSchema: z.ZodObject<{
|
|
|
129
147
|
required: z.ZodOptional<z.ZodBoolean>;
|
|
130
148
|
}, z.core.$strip>>>;
|
|
131
149
|
isVibeMode: z.ZodOptional<z.ZodBoolean>;
|
|
132
|
-
vibeProtocol: z.ZodOptional<z.
|
|
150
|
+
vibeProtocol: z.ZodOptional<z.ZodObject<{
|
|
151
|
+
isVibeMode: z.ZodLiteral<true>;
|
|
152
|
+
detectedAt: z.ZodNumber;
|
|
153
|
+
stage: z.ZodEnum<{
|
|
154
|
+
auditor: "auditor";
|
|
155
|
+
coder: "coder";
|
|
156
|
+
passed: "passed";
|
|
157
|
+
synthesizer: "synthesizer";
|
|
158
|
+
}>;
|
|
159
|
+
synthesizedSpec: z.ZodOptional<z.ZodString>;
|
|
160
|
+
coderContract: z.ZodOptional<z.ZodString>;
|
|
161
|
+
auditVerdict: z.ZodOptional<z.ZodEnum<{
|
|
162
|
+
PASS: "PASS";
|
|
163
|
+
REJECT: "REJECT";
|
|
164
|
+
}>>;
|
|
165
|
+
auditNotes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
166
|
+
}, z.core.$strict>>;
|
|
133
167
|
}, z.core.$strict>;
|
|
134
168
|
export declare const updateIntakeSchema: z.ZodObject<{
|
|
135
169
|
title: z.ZodOptional<z.ZodString>;
|
|
@@ -149,7 +183,23 @@ export declare const updateIntakeSchema: z.ZodObject<{
|
|
|
149
183
|
providedContext: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
150
184
|
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
151
185
|
isVibeMode: z.ZodOptional<z.ZodBoolean>;
|
|
152
|
-
vibeProtocol: z.ZodOptional<z.
|
|
186
|
+
vibeProtocol: z.ZodOptional<z.ZodObject<{
|
|
187
|
+
isVibeMode: z.ZodLiteral<true>;
|
|
188
|
+
detectedAt: z.ZodNumber;
|
|
189
|
+
stage: z.ZodEnum<{
|
|
190
|
+
auditor: "auditor";
|
|
191
|
+
coder: "coder";
|
|
192
|
+
passed: "passed";
|
|
193
|
+
synthesizer: "synthesizer";
|
|
194
|
+
}>;
|
|
195
|
+
synthesizedSpec: z.ZodOptional<z.ZodString>;
|
|
196
|
+
coderContract: z.ZodOptional<z.ZodString>;
|
|
197
|
+
auditVerdict: z.ZodOptional<z.ZodEnum<{
|
|
198
|
+
PASS: "PASS";
|
|
199
|
+
REJECT: "REJECT";
|
|
200
|
+
}>>;
|
|
201
|
+
auditNotes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
202
|
+
}, z.core.$strict>>;
|
|
153
203
|
}, z.core.$strict>;
|
|
154
204
|
export declare const answerInputSchema: z.ZodObject<{
|
|
155
205
|
field: z.ZodString;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/requirement-intake",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.26",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack Requirements Intake — collect, preserve, validate, normalize, and submit unstructured software development requests as structured intake records. Upstream of spec-driven development: it never plans, specifies, or implements.",
|
|
6
6
|
"repository": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"!dist/**/*.map"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@wrongstack/core": "1.0.
|
|
30
|
+
"@wrongstack/core": "1.0.26",
|
|
31
31
|
"zod": "4.6.2"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|