Skip to main content

Fidonet Msgbase

@magistr/fidonet-msgbasev2026.08.19.1· 5d agoMODELSREPORTS
01README

FidoNet JAM/Squish/FTS-0001 message base reader — browse areas, read messages, search by sender/address/text

02Models1
@magistr/fidonet-msgbasev2026.08.19.1extensions/models/fidonet_msgbase.ts

Global Arguments

ArgumentTypeDescription
basePathstringPath to directory containing message base files
fn listAreas()
List all message areas with message counts
fn readArea(area: string, limit: number, offset: number)
Read all messages from a specific area
ArgumentTypeDescription
areastringArea name (e.g. fido.general)
limitnumberMax messages to return
offsetnumberSkip first N messages
fn readNetmail(limit: number, offset: number)
Read netmail messages (FTS-0001 .msg files)
ArgumentTypeDescription
limitnumberMax messages to return
offsetnumberSkip first N messages
fn searchBySender(sender: string, limit: number)
Search all areas for messages from a specific sender (case-insensitive partial match)
ArgumentTypeDescription
senderstringSender name to search for
limitnumberMax results
fn searchByAddress(address: string, limit: number)
Search all areas by FidoNet address — full node (2:5020/1) or point (2:5020/1.28)
ArgumentTypeDescription
addressstringFidoNet address to match (e.g. 2:5020/1 or 2:5020/1.28)
limitnumberMax results
fn formatForObsidian(source: string, folder: string)
Format stored search/read results as Obsidian markdown notes
ArgumentTypeDescription
sourcestringData instance name from a previous search (e.g. sender_John_Doe_a1b2c3, netmail, address_2_5020_1_28_4d5e6f — search instance names carry a trailing 6-hex-digit hash; check the search method's own output for the exact name)
folderstringObsidian folder for notes
fn searchByText(text: string, limit: number)
Search all areas for messages containing text (case-insensitive)
ArgumentTypeDescription
textstringText to search for in message bodies
limitnumberMax results

Resources

areas(infinite)— List of message areas
messages(1h)— Messages from an area or search results
03Reports2
@magistr/fidonet-messagesmethod
extensions/reports/fidonet_messages.ts

Display FidoNet messages from search or area read results

fidonetmessages
@magistr/fidonet-summarymethod
extensions/reports/fidonet_summary.ts

Summarize FidoNet message base results — top senders, areas, date distribution

fidonetsummary
04Previous Versions5
2026.08.02.1

2026.08.02.1

Real fix for all 9 latent bugs found and pinned by the prior test backfill (below) -- source edits in extensions/models/fidonet_msgbase.ts, not just characterization. Valid-message parsing stays byte-identical; the only schema change is an additive, optional warnings field on the messages resource.

  • LB1 (HIGH) -- readArea path traversal via the area arg: added resolveAreaFile(basePath, area, ext), adapted from livejournal-import's normalizeSegments confinement check, used for all three .jhr/.jdt/ .sqd path builds in readArea. Rejects any /, \, .., absolute, ., or empty area segment with Area '<x>': path traversal rejected, and double-checks the resolved path still lands under basePath. Only readArea was a vector -- the fan-out search methods enumerate area files via Deno.readDir, never from a caller-supplied name.
  • LB2 (MED) -- Squish frame-chain cycle: parseSquishMessages now tracks visited frame offsets in a Set (plus an iteration cap) and breaks on a revisit instead of looping forever on a crafted A -> B -> A chain.
  • LB3 (MED) -- silent-skip empty catch blocks: searchBySender/ searchByAddress/searchByText's per-area catches, and a too-short (< 1024-byte) .jhr fixed header, now push a message onto a new warnings: string[] array on the written resource instead of failing completely silently; a good sibling area is still fully searched.
  • LB4 (MED) -- searchByText excluded all Squish areas: added a .sqd branch mirroring searchBySender's, so text that exists only in a Squish area is now found.
  • LB5 (LOW) -- searchByText dropped JAM areas missing .jdt: a missing .jdt now sets an empty body and keeps scanning subject/from, matching readArea/searchBySender's tolerance, instead of continue-ing past the whole area.
  • LB6 (LOW) -- Squish truncated-frame OOB reads: parseSquishMessages now checks xmsgOfs + 238 <= sqd.length before reading the XMSG region and skips (breaks on) a frame that doesn't have the full fixed region present, instead of decoding out-of-bounds undefined reads as a garbage "0:0/0" address.
  • LB7 (LOW) -- resource-name slug collision: searchBySender/ searchByAddress/searchByText now append a 6-hex-digit FNV-1a hash of the RAW (pre-slugification) query to their writeResource instance name, so distinct queries that previously collapsed to the identical slug (e.g. "John.Doe" vs "John_Doe") no longer overwrite each other's stored results, while the same raw query still produces a deterministic name. readArea/readNetmail/formatForObsidian instance names are unchanged.
  • LB8 (LOW) -- JAM subfields carried raw untrimmed bytes: subfield text is now NUL-trimmed (.replace(/\0.*/s, "")) to match Squish's XMSG fixed fields and FTS-0001's header fields. Also collapsed decodeText's dead-code high-byte guard (if (slice.some(b=>b>=0x80)) return text; return text;) to a single return text; -- byte-identical, since both branches always returned the same value.
  • LB9 (LOW) -- unbounded Deno.readFile into RAM: added readFileCapped(path), which Deno.stats a file and rejects it before reading if it exceeds a cap (default 256 MiB, overridable via the FIDONET_MSGBASE_MAX_BYTES env var); used at every Deno.readFile call site. readArea throws exceeds size cap; the fan-out search methods surface it as a warnings entry instead of dropping the area silently.
  • Added the model's first upgrades[] entry (2026.07.16.2 -> 2026.08.02.1, identity upgradeAttributes) -- no breaking schema change.
  • deno.json: both test and test:soak tasks' --allow-env extended from FC_NUM_RUNS to FC_NUM_RUNS,FIDONET_MSGBASE_MAX_BYTES.
  • quality.yaml: re-stamped ratchet from a fresh swamp extension quality manifest.yaml --json run; header comment updated from "byte-frozen backfill" to "real-fix".
  • Test suites gained 9 new tests (pin-flips plus new adversarial/contract/ property coverage for the fixes above) -- 59 tests before this change, 68 after; see the test-backfill bullets below for the suites themselves.

Also folded into this release, the STANDARD.md five-suite quality-bar test backfill that found and pinned the 9 bugs above (wave-4 batch-4a extension-quality backfill, ext-quality-test-backfill):

  • Added extensions/models/fidonet_msgbase_methods_test.ts (methods, 9 tests), fidonet_msgbase_contract_test.ts (contract-fixture, 15 tests), fidonet_msgbase_adversarial_test.ts (adversarial, 14 tests),

Notes trimmed at a line boundary to fit the registry's 4900-byte per-version cap. Full section: https://github.com/umag/swamp-workspace/blob/d850d8e8372d4c0008c9245959a090b37095de7a/fidonet-msgbase/CHANGELOG.md

2026.07.16.2

Release 2026.07.16.2 — align model versions with manifests

Maintenance release across the @magistr extensions. For most packages this carries no functional change: the only edit is the model's version: field, brought back in line with its manifest version so the published model type version and the package version no longer drift.

Functional changes in this release are limited to:

  • anime-cron: normalizeTitle now strips a ": subtitle" suffix and a trailing parenthesized year before comparison, fixing dedup false-misses where the torrent title carries a subtitle or year that the AniList romaji does not.

  • arckit: first publish. Standalone ArcKit port — a 12-phase architecture governance state machine with 65 bundled templates, driven by a bundled skill.

Also tracks three extensions (kaiten, observability-agent, music-library) that previously existed only as untracked working-tree directories, recovered from stashes.

2026.07.16.1

Maintenance version bump. No functional changes.

Added 2, removed 2 reports

2026.05.25.1

Merge pull request #4 from umag/extensions/magistr-grade-a-workspace

extensions: stage 15 @magistr extensions as Grade A workspace dirs + wire CI

2026.03.29.1
05Stats
A
100 / 100
Downloads
2
Archive size
28.3 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types (deprecated)1/1earned
  • Dependencies pass trust audit2/2earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License declared1/1earned
  • Verified public repository2/2earned
06Platforms
07Labels