@wrongstack/requirement-intake 0.303.0 → 0.305.1

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 (2) hide show
  1. package/README.md +110 -0
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -201,6 +201,116 @@ optional and falls back to this when omitted).
201
201
  interview from a submitted intake record, using the original request as the
202
202
  interview intent and the collected facts as project context.
203
203
 
204
+ ## WebUI scope: minimal-by-design
205
+
206
+ The WebUI activity-bar panel (`packages/webui/src/components/RequirementIntakeView.tsx`,
207
+ icon: `ClipboardList`, label: "Requirements") is intentionally **minimal**:
208
+ list project intake records + file a new one. Its i18n keys
209
+ (`activity.reqIntake.*`) cover only the create form and the list — there are
210
+ no keys for answers, attachments, suggestions, accept/reject, or cancel.
211
+ This is the deliberate boundary.
212
+
213
+ **What the panel does today**
214
+
215
+ - Lists records for the resolved project via `GET /api/requirement-intakes`
216
+ (server returns `{ projectId, intakes }`).
217
+ - Files a new record with `POST /api/projects/:projectId/requirement-intakes`
218
+ then submits it with `POST /api/requirement-intakes/:id/submit`. The body
219
+ carries `projectId` (server-resolved) and `requestedBy: 'webui'` (matching
220
+ the `techstack-handlers` sentinel; swap to a real user id when WebUI
221
+ exposes one).
222
+ - Surfaces success (`Intake recorded and submitted (<id>).`) and server
223
+ errors (HTTP status + parsed `error.message`).
224
+ - Refreshes the list after a successful submit.
225
+
226
+ **What the panel does not do (by design)**
227
+
228
+ - **Inline answer / question editor.** Adding a `DEFAULT_INTAKE_QUESTIONS`
229
+ flow with `addAnswer` / `updateAnswer` / `pendingQuestions` is a full
230
+ questionnaire UI — comparable to `SddInterviewView`. Belongs in a
231
+ dedicated intake-detail view or in SDD itself, not in the activity-bar
232
+ panel.
233
+ - **LLM suggestion UI.** `generateSuggestions` requires a real
234
+ `LlmSuggestionGenerator` adapter to be wired into the webui-server; the
235
+ server runs without one. Adding UI for a non-existent path is misleading,
236
+ and exposing `acceptSuggestion` / `rejectSuggestion` would commit the view
237
+ to a generator contract that is currently pluggable.
238
+ - **Attachment upload.** The `attachResource` schema requires exactly one of
239
+ `path` or `url` plus a `kind` enum and a non-blank name. File-picker,
240
+ size limits, MIME detection, and storage strategy are out of scope for a
241
+ single-purpose panel.
242
+ - **Field editing after draft.** `PATCH /api/requirement-intakes/:id` exists
243
+ and is used by programmatic callers; the panel's job is filing, not
244
+ editing.
245
+
246
+ **Three small exceptions the panel will add next**
247
+
248
+ Even while staying minimal, three additions pay for themselves quickly.
249
+ All three are gated on lifecycle (`MUTABLE_STATUSES = ['draft',
250
+ 'collecting_information']`) so the panel never mutates a submitted,
251
+ cancelled, or archived record.
252
+
253
+ 1. **Read-only detail panel.** Clicking a record opens a side panel showing
254
+ the full record body: `originalRequest` (verbatim, monospace),
255
+ `normalizedSummary`, `businessGoal`, `expectedOutcome`, `scopeNotes`,
256
+ `targetUsers`, `constraints`, `providedContext`, `attachments`,
257
+ `relatedResources`, `answers`, `questions`, and `llmSuggestions`
258
+ (read-only, source-tagged). Makes the list clickable without adding any
259
+ mutation surface. One new component, no service changes.
260
+ 2. **Cancel button on draft records.** Single button, single endpoint
261
+ (`POST /api/requirement-intakes/:id/cancel`). Visible only when the
262
+ record's `status` is in `MUTABLE_STATUSES`; cancel transitions
263
+ `draft → cancelled` or `collecting_information → cancelled`
264
+ (`lifecycle.ALLOWED_TRANSITIONS`). Submitted/cancelled/archived records
265
+ surface an **Archive** action instead, gated behind a confirm dialog
266
+ because archive is irreversible.
267
+ 3. **Status-locked error surfacing.** When the panel POSTs an action
268
+ against a record that is no longer mutable (e.g. another tab
269
+ `submitIntake`ed a draft the moment the user clicked Cancel), the
270
+ server returns 409 with `INTAKE_STATUS_LOCKED`. The view should detect
271
+ that code, refresh the list, and surface a non-alarming "this record
272
+ was finalized elsewhere — reloaded" notice rather than a generic error.
273
+
274
+ **Power-user path:** Everything the panel omits is reachable via the
275
+ REST API, the `/intake` slash command, the `@wrongstack/requirement-intake-mcp`
276
+ server, and the `@wrongstack/sdd` interview bridge. The panel exposes the
277
+ `id` and status so a user can copy the id and run CLI/REST against it.
278
+
279
+ **Rationale.** The activity bar's panels are *varied* in surface area —
280
+ each is sized to its domain's natural complexity, not to a single shared
281
+ shape. Concretely (line counts from `packages/webui/src/components`):
282
+
283
+ | Activity-bar panel | Backing component(s) | Surface |
284
+ |---|---|---|
285
+ | `intake` (Requirements) | `RequirementIntakeView.tsx` | 366 lines — single form + list |
286
+ | `sddhub` (SDD) | `SddHub.tsx` | 117 lines — thin entry, defers to other views |
287
+ | `goal` (Goal) | `GoalView.tsx` | 526 lines — focused |
288
+ | `roster` (Agent Roster) | `AgentRosterView.tsx` | 569 lines — focused |
289
+ | `kanban` (Kanban) | `KanbanView.tsx` | 646 lines — focused |
290
+ | `techstack` (TechStack) | `TechStackView/index.tsx` + 5 sub-components | 757 lines + 1,034 lines of sub-panels (1,791 total) |
291
+ | `codemap` (CodeMap) | `CodeMap.tsx` | 889 lines — full explorer |
292
+ | `memory` (Memory) | `MemoryManager/index.tsx` + 14 sub-components | 1,096 lines + 3,508 lines of sub-components (4,604 total) |
293
+
294
+ (Line counts measured with `(Get-Content -Path | Measure-Object -Line).Lines` on `*.tsx`/`*.ts` files under `packages/webui/src/components/`, excluding `node_modules` and `dist`. Re-measure any time; the source files keep moving.)
295
+
296
+ The right question for the Requirements panel is not "match the smallest
297
+ panel" — it's *does the panel reflect the domain's natural surface, without
298
+ bloat?* The intake domain has a wide surface (answers, attachments,
299
+ suggestions, lifecycle transitions) but a narrow *entry point*: the
300
+ verbatim original request. The minimal panel correctly captures that entry
301
+ point; the full surface is reachable via REST/CLI/MCP/SDD.
302
+
303
+ A full feature-CRUD view would (a) obscure the module's core invariants —
304
+ original request sacred, source-tagging, LLM output is proposal,
305
+ deterministic validation, fail-closed auth — by spreading them across
306
+ mutation paths; (b) couple WebUI to the LLM-suggestion generator contract
307
+ before a real adapter exists; (c) force a multi-pane questionnaire layout
308
+ that breaks on mobile; and (d) leave the LLM-suggestion path shipped-but-
309
+ broken at the UI level. The minimal surface keeps the entry point obvious,
310
+ leaves the LLM path unimplemented at the UI level until a real generator
311
+ is wired in, and pushes the structured-questioning UX to `SddInterviewView`
312
+ where it already lives.
313
+
204
314
  ## Observability
205
315
 
206
316
  - **Events** — `RequirementIntakeCreated`, `RequirementIntakeUpdated`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrongstack/requirement-intake",
3
- "version": "0.303.0",
3
+ "version": "0.305.1",
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": {
@@ -28,7 +28,7 @@
28
28
  ],
29
29
  "dependencies": {
30
30
  "zod": "4.4.3",
31
- "@wrongstack/core": "0.303.0"
31
+ "@wrongstack/core": "0.305.1"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/node": "^26.1.2",