@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.
- package/README.md +110 -0
- 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.
|
|
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.
|
|
31
|
+
"@wrongstack/core": "0.305.1"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/node": "^26.1.2",
|