|
|
a7dec7fdee
|
feat(ds): add voyage scope tokens + badge--scope-voyage (B-DS-4); resync vendor
|
2026-05-10 10:17:50 +02:00 |
|
|
|
97b6f5406e
|
feat(voyage): add export flow + A11Y baseline — v4.2 Step 11 [skip-docs]
Closes Wave 2 (Steps 6-11) of v4.2 implementation. Playground now
delivers the complete annotation pipeline: render -> create gestures
-> sidebar -> export.
Export flow:
- 'Eksporter batch' button in sidebar export-bar
- Export modal with role="dialog" aria-modal="true"
- Generated /trekrevise command-string ready to copy
- Two paths:
navigator.clipboard.writeText (modern) with execCommand('copy')
legacy fallback for cross-browser support
Blob + URL.createObjectURL download as annotated-{brief|plan|review}.md
- buildAnnotatedMarkdown injects voyage:anchor comments above target
lines (mirrors lib/parsers/anchor-parser.mjs addAnchors() behaviour)
Resolve-til-arkiv (Google Docs pattern, per research-06):
- Post-export marks pending drafts as exported (NOT delete)
- Tab 2 ('Alle revisjoner') surfaces history with revision-stamp
- aria-live='polite' toast announces export status
A11Y baseline (per research-06 + llm-security A11Y-RAPPORT.md):
- aria-live='polite' toast region (Step 1)
- Skip-to-main link (.visually-hidden + #main target)
- role='dialog' + aria-modal='true' on form modal (Step 9)
on export modal (Step 11)
- role='tablist' / role='tab' / aria-selected / tabindex roving (Step 10)
- aria-controls + aria-labelledby on tabpanels
- aria-pressed on intent buttons (radiogroup-like)
- aria-expanded + aria-controls on sidebar FAB
- aria-hidden='true' on decorative SVG paths
- aria-label on icon-only buttons
- .visually-hidden labels for textarea + clipboard helper
Test coverage: tests/playground/voyage-playground.test.mjs +4 cases —
aria-live='polite', Skip to main, Blob, clipboard.writeText.
Verify: node --test tests/playground/voyage-playground.test.mjs ->
22 pass / 0 fail.
Full npm test: 596 pass / 0 fail / 2 skipped (Docker).
Refs plan.md Step 11 + research-06 + llm-security A11Y baseline.
|
2026-05-09 15:27:01 +02:00 |
|
|
|
125bfb02b2
|
feat(voyage): add playground sidebar with tabs + critique-card-list — v4.2 Step 10 [skip-docs]
Right-collapsible sidebar (320px) with 40px icon-rail when collapsed
(per critical decision #4 + research-06):
- 2-state FAB toggle (aria-expanded toggles aria-hidden on aside)
- Visible draft-count badge on FAB (mitigates 'forgot to export' friction)
- Two tabs:
'Denne planen (N drafts)' — pending annotations
'Alle revisjoner (M historiske)' — exported (Step 11 wires this)
- role="tablist" + role="tab" + aria-selected + tabindex roving
- ArrowLeft/ArrowRight keyboard nav between tabs
- .findings list of .critique-card per annotation
- Click on critique-card scrolls to anchor + .lint-annotation-glow
1s pulse animation
- Sort-by-location (Hypothes.is pattern; line ASC)
Card visual: intent-badge (color-coded fix=green/change=blue/question=yellow/block=red),
ANN-NNNN ID, snippet preview, comment, exported-status.
Layout: main shifts margin-right: 320px above 1024px viewport so the
sidebar doesn't overlap the rendered artifact.
saveModalAsAnnotation + mountRender hooks now refresh the sidebar so
new drafts appear immediately and re-render preserves visibility.
Test coverage: tests/playground/voyage-playground.test.mjs +2 cases —
role="tablist", tabindex.
Verify: node --test tests/playground/voyage-playground.test.mjs ->
18 pass / 0 fail.
Full npm test: 592 pass / 0 fail / 2 skipped (Docker).
Refs plan.md Step 10 + critical decision #4 + research-06.
|
2026-05-09 15:25:01 +02:00 |
|
|
|
a7a6a53686
|
feat(voyage): add three annotation creation gestures + form modal — v4.2 Step 9 [skip-docs]
Three creation gestures + shared form modal for the v4.2 annotation
playground (per critical decisions #2-#4 + research-06):
Gesture 1 — text-anchored adder-popup:
- mouseup-debounce 200ms (settles selection)
- 300ms grace before hide (Hypothes.is friction-mitigation)
- floating .voyage-adder-popup positioned at selection-bound corner
- click -> opens form modal with derived heading-path + line + snippet
Gesture 2 — paragraph-anchored hover-icon:
- 24px pencil SVG injected per <p>/<li> after each render
- opacity 0 default, opacity 1 on hover/focus-visible
- click -> opens form modal with no snippet
Gesture 3 — page-level note:
- .voyage-page-note-btn injected in viewport
- click -> opens form modal with target=page
Form modal (shared):
- role="dialog" aria-modal="true" + aria-labelledby
- 400px right-anchored on backdrop (per critical decision #3)
- 4 intent buttons (Fiks / Endre / Spørsmål / Block) as aria-pressed group
- <textarea> required for comment
- ESC + backdrop-click + Avbryt close
- Lagre persists via saveModalAsAnnotation
Anchor-ID generation (per critical decision #2 + risk-assessor H7):
- sequential ANN-NNNN per project+file scope
- persisted in localStorage under voyage_ann_<project>__<file>.drafts
Test coverage: tests/playground/voyage-playground.test.mjs +3 cases —
aria-modal, ANN-, 300ms grace.
Verify: node --test tests/playground/voyage-playground.test.mjs ->
16 pass / 0 fail.
Full npm test: 590 pass / 0 fail / 2 skipped (Docker).
Refs plan.md Step 9 + critical decisions #2/#3/#4 + research-06.
|
2026-05-09 15:22:52 +02:00 |
|
|
|
249142df2f
|
feat(voyage): vendor markdown-it/highlight.js + playground render-pipeline + scripts/render-artifact.mjs CLI — v4.2 Step 8 [skip-docs]
Vendored libs (locked headless via scripts/vendor-playground-libs.mjs;
plan-critic B3 — never use highlightjs.org website builder):
- playground/lib/markdown-it.min.js — markdown-it@14.1.0 UMD bundle
- playground/lib/markdown-it-front-matter.min.js — markdown-it-front-matter@0.2.4 IIFE-wrapped
- playground/lib/highlight.min.js — highlight.js@11.11.1 (5-lang bundle:
yaml/json/javascript/bash/markdown/diff)
- playground/lib/VENDOR-MANIFEST.json — pin record + audit trail
scripts/vendor-playground-libs.mjs implements the reproducible
CommonJS-to-IIFE wrapping. Re-vendoring requires only:
node scripts/vendor-playground-libs.mjs
Render pipeline in playground/voyage-playground.html (~330 LoC total):
- inline <script src=lib/...> for the three vendored bundles
- markdown-it init with html: true (preserves voyage:anchor comments)
- front-matter plugin with pre-render-then-wrap pattern (research/03)
- paste-import-row textarea + Render/Sample/Clear buttons
- voyage-viewport region with role + aria-live for A11Y
- localStorage key pattern: voyage_ann_<project>__<slug> (risk-assessor H7)
- inline sample plan (mirrors annotation-plan.md fixture)
scripts/render-artifact.mjs CLI (~200 LoC) — brief SC1 + SC11:
- reads input.md, runs same vendored pipeline server-side
- inlines DS CSS + (URL-stripped) highlight.js into output
- zero http://https:// URLs in output (verified by test)
- deterministic: two invocations -> byte-identical sha256
- default output: <input>.html next to input
Test coverage:
- tests/scripts/render-artifact.test.mjs — 5 cases (SC1/SC11)
- tests/playground/voyage-playground.test.mjs — +5 cases (Step 8 extension)
Verify: node --test tests/playground/voyage-playground.test.mjs
tests/scripts/render-artifact.test.mjs -> 18 pass / 0 fail.
Full npm test: 587 pass / 0 fail / 2 skipped (Docker).
Refs plan.md Step 8 + plan-critic B3 + scope-guardian B1.
|
2026-05-09 15:20:17 +02:00 |
|
|
|
2f4330265c
|
feat(voyage): scaffold playground/ with DS vendor sync — v4.2 Step 5
- playground/voyage-playground.html: minimal skeleton (DOCTYPE, app-header, guide-panel, aria-live region, skip-to-main link). Steps 8-11 will extend with render-pipeline + creation gestures + sidebar + export.
- playground/vendor/playground-design-system/: synced via 'node scripts/sync-design-system.mjs voyage' (27 files + MANIFEST.json with source_commit + sync_date + SHA-256 per file).
- tests/playground/voyage-playground.test.mjs: 8 tests pinning HTML existence, DOCTYPE, no-external-URLs, no-marked, A11Y skip-to-main + aria-live, MANIFEST.json structure, vendored DS files present.
- shared/PLAYGROUND-MAINTENANCE.md: consumer list updated 5 -> 6 (added voyage).
|
2026-05-09 12:55:02 +02:00 |
|