Repository navigation
v0.3.0
A hardening release: a correctness fix to the answers contract, a documentation gap that
made an implemented feature unreachable, the project's first CI, and a set of robustness,
security, and UX fixes. See
docs/plan/refactor-quizzing-hardening-1.md
for the plan this release implements.
Changed — answers JSON
A response marked skipped or deferred no longer carries an answer value. The form
pre-seeds each question with the agent's recommended answer, and skipping previously left
that value in place, so {"skipped": true, "rangeValue": 3} could be read back as the user
accepting the recommendation. Skipped and deferred responses now emit only questionId,
skipped, and deferred.
This changes the shape of emitted answers JSON. Artifacts produced by 0.2.0 will not
round-trip identically, though both old and new output remain valid against
answers.schema.json, which never required the value fields. Consumers that read a value
without first checking skipped were reading the agent's own recommendation, not an answer.
Added
decision-matrixis now documented inSKILL.md— the type was fully implemented,
schema-backed, and shown in the README screenshots, but absent from the agent's authoring
surface, so no agent would ever produce one.- Continuous integration (
.github/workflows/ci.yml): the test suite on Node 18, 20 and 22,
JSON-schema validation of the example fixtures, and a manifest version-sync check. tests/docs.test.jsasserts every questiontypeanddiagram.formatthe schema accepts
is named inSKILL.md, so this documentation gap cannot recur silently.tools/check-version-sync.js(make check-version) checks the tenversionfields spread
across the six distribution manifests and the lockfile.- The form now resumes after a reload. Progress is saved to
localStorage, keyed by
questionnaire id and version, announced once with a "Start over" affordance, and cleared on
submit. Access is best-effort, so afile://origin or disabled storage degrades to the
previous behaviour. The review screen discloses where answers are kept.
Fixed
- Author-supplied SVG is sanitised at build time. Diagram content is rendered through
innerHTML, so a hand-authoredformat: "svg"diagram carrying<script>or anon*
attribute would execute in the user's browser.<script>and<foreignObject>elements,
event-handler attributes, comments, and any URL that is not a#fragmentordata:image/…
are now stripped. Generatedflowandlayeredoutput is unaffected. serve.jscreates missing parent directories of--outinstead of failing withENOENT
after the user has already completed the form.serve.jsvalidates a submission before writing it: it must be an object with an array of
responsesand aquestionnaire.idmatching the questionnaire being served. Previously any
parseable JSON was written over the answers file and acknowledged as success.serve.jsreports write failures on stderr; they were previously visible only to the browser.--portand--timeoutare validated as integers rather than passed through
parseInt(...) || default, which read--timeout soonas 1800 and discarded an explicit
--timeout 0.--timeout 0now means "wait indefinitely".- Pressing Enter while typing in a single-line custom-input field no longer jumps to the next
question. Radios, checkboxes and buttons still advance. tests/form.test.jsfails instead of silently passing when jsdom is missing under CI.
Removed
- Unused
osrequire inserve.js.