@wrongstack/requirement-intake 1.0.35 → 1.0.36

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.js CHANGED
@@ -1027,9 +1027,11 @@ function deriveVibeState(rawText, existingState, now = Date.now()) {
1027
1027
  }
1028
1028
 
1029
1029
  // src/service-helpers.ts
1030
+ function splitItems(raw) {
1031
+ return raw.split(/[\n,;]+/).map((item) => item.trim()).filter((item) => item.length > 0);
1032
+ }
1030
1033
  function appendItems(target, raw) {
1031
- const items = raw.split(/[\n,;]+/).map((item) => item.trim()).filter((item) => item.length > 0);
1032
- for (const item of items) {
1034
+ for (const item of splitItems(raw)) {
1033
1035
  if (!target.includes(item) && target.length < MAX_ARRAY_ITEMS) {
1034
1036
  target.push(item);
1035
1037
  }
@@ -1059,22 +1061,26 @@ var ANSWER_FIELD_MAPPING = {
1059
1061
  target_users: {
1060
1062
  set: (record, value) => {
1061
1063
  appendItems(record.targetUsers, value);
1062
- }
1064
+ },
1065
+ list: (record) => record.targetUsers
1063
1066
  },
1064
1067
  constraints: {
1065
1068
  set: (record, value) => {
1066
1069
  appendItems(record.constraints, value);
1067
- }
1070
+ },
1071
+ list: (record) => record.constraints
1068
1072
  },
1069
1073
  provided_context: {
1070
1074
  set: (record, value) => {
1071
1075
  appendItems(record.providedContext, value);
1072
- }
1076
+ },
1077
+ list: (record) => record.providedContext
1073
1078
  },
1074
1079
  project_component: {
1075
1080
  set: (record, value) => {
1076
1081
  appendItems(record.providedContext, value);
1077
- }
1082
+ },
1083
+ list: (record) => record.providedContext
1078
1084
  },
1079
1085
  priority: {
1080
1086
  set: (record, value) => {
@@ -1319,6 +1325,7 @@ function applyAnswerUpdateToRecord(record, answerId, newAnswer) {
1319
1325
  { field: "answerId", message: `answer not found: ${answerId}` }
1320
1326
  ]);
1321
1327
  }
1328
+ const previous = answer.answer;
1322
1329
  answer.answer = newAnswer;
1323
1330
  answer.answeredAt = Date.now();
1324
1331
  const question = record.questions.find((candidate) => candidate.field === answer.field);
@@ -1327,6 +1334,18 @@ function applyAnswerUpdateToRecord(record, answerId, newAnswer) {
1327
1334
  question.status = "answered";
1328
1335
  }
1329
1336
  const mapping = ANSWER_FIELD_MAPPING[answer.field];
1337
+ const list = mapping?.list?.(record);
1338
+ if (list) {
1339
+ const stillGiven = new Set(
1340
+ record.answers.filter(
1341
+ (other) => other !== answer && ANSWER_FIELD_MAPPING[other.field]?.list?.(record) === list
1342
+ ).flatMap((other) => splitItems(other.answer))
1343
+ );
1344
+ for (const item of splitItems(previous)) {
1345
+ const at = list.indexOf(item);
1346
+ if (at >= 0 && !stillGiven.has(item)) list.splice(at, 1);
1347
+ }
1348
+ }
1330
1349
  if (mapping) {
1331
1350
  mapping.set(record, newAnswer);
1332
1351
  const sourceKey = answer.field;
@@ -4,6 +4,8 @@ export declare function appendItems(target: string[], raw: string): void;
4
4
  /** Answer fields that also update a record property. */
5
5
  export declare const ANSWER_FIELD_MAPPING: Readonly<Record<string, {
6
6
  set: (record: RequirementIntakeRecord, value: string) => void;
7
+ /** The list an append-only answer feeds; an update takes its old items back out. */
8
+ list?: (record: RequirementIntakeRecord) => string[];
7
9
  }>>;
8
10
  export declare function buildNewIntakeRecord(input: CreateIntakeInput, ctx: IntakeContext, now: number, catalog: readonly IntakeQuestionTemplate[]): RequirementIntakeRecord;
9
11
  export declare function assertIntakeSubmitReady(record: RequirementIntakeRecord): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrongstack/requirement-intake",
3
- "version": "1.0.35",
3
+ "version": "1.0.36",
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.35",
30
+ "@wrongstack/core": "1.0.36",
31
31
  "zod": "4.6.2"
32
32
  },
33
33
  "devDependencies": {
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "scripts": {
41
41
  "build": "node ../../scripts/build-package.mjs",
42
- "typecheck": "tsc --noEmit",
42
+ "typecheck": "node ../../scripts/bun-typecheck.mjs --noEmit",
43
43
  "test": "vitest run",
44
44
  "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\""
45
45
  }