Skip to content
Vocino edited this page Aug 20, 2026 · 6 revisions

Import on warband.pro

Where

  • Left rail $ import field (not a route, not overlay anymore)
  • Also Top-right sink [ ↻ sync / ↥ import ▼]↥ Import addon (wb1!)
  • Settings → Import (same decoder)
  • Hotkey i from anywhere — opens rail tab if collapsed

How it works

  1. Click Import or hit i (user gesture required for navigator.clipboard.readText())

  2. If clipboard startsWith wb1! or wb0! length>10: auto-fill preview immediately — 0 paste needed!

  3. Else: big <textarea> auto-focused placeholder "Paste wb1! string here — Ctrl+V", paste → debounce 150ms → preview

  4. Preview sentence (rail is 280px, cannot hold 8 columns):

    "6 chars, 1 over 3d — Enter to import" + rows with dots

    Row: name · realm · 🟢<6h 🟡<3d 🔴>3d ⚪never · gold · freshness Hover: "Bags 2h ago, Bank 5d ago (open bank to refresh), Warbank 14d" Warn if half stale >3d: "half stale — you may want to log alts later"

  5. Enter confirms → POST /api/addon/import { bundle:"wb1!..." } → D1 character_addon_cache / warband_bank_cache upsert per char, per user_id

  6. Receipt: one line per char with dot + gold, printed in waves like $ output (terminal aesthetic), held 6s, decayed 4 steps, removed — block returns to original height

  7. Nothing reloads — only that one line stamped in place. Reload would discard receipt (what overlay version did).

Validation UX

Client-side before D1 write:

  • Not wb1! — if wb0! "That's Camp DNA share, not inventory — use Share import tab", else "Doesn't look like Warband string — run /warband copy again"
  • 20 chars or >1MB decoded (1MB, not 25KB — measured full-inventory 6 is 154KB JSON, 26KB wire, 20 cap ~474KB/73KB) → "too large, try single-char"

  • Missing chars NOT deleted — keeps old snapshot aging red (staleness lowers confidence, never deletes)

Implementation

src/lib/warband-import.ts — pure decoder, testable with vitest (no DOM/D1):

  • WIRE_PREFIX='wb1!' DNA_PREFIX='wb0!' MAX_CHARACTERS=20 MAX_DECODED_BYTES=1_048_576
  • base64url → bytes → DecompressionStream('deflate-raw') (not 'deflate', expects zlib header addon doesn't emit, use 'deflate-raw' or pako.inflateRaw)
  • Throws on anything bad — route mirrors checks

This file is the law on web side, tests in src/__tests__/warband-import.test.ts. Vectors in addon repo docs/contract/vectors/v1-min.wb1.

Astro parser hazard

Any element whose raw text begins // inside JSX expression is silently deleted from output (compiler reads as line comment, no warning). Correct fix: not to write it — // mark is .cmt::before in base.css.

Clipboard nuance

  • Requires HTTPS user gesture — warband.pro is HTTPS so fine on Chrome/Edge
  • Never polling readText(), only inside click
  • Don't auto-submit — user must Confirm after preview seeing staleness
  • Firefox/Safari stricter → fallback textarea Ctrl+V

Tonight Plan hook

After Confirm, scorer re-reads consumables rollup (src/lib/tonight.ts, warband-import.ts types). Freshness influences block vs grey.

See Also

  • App wiki Article: warband-pro/app .wiki/wiki/topics/addon-import.md
  • warband-pro/addon docs/UI.md, docs/APP-IMPORT.md, docs/FLOW.md

Warband.pro Companion

Home

Start

Integration

Internals

Clone this wiki locally