Skype
Skype SQLite database reader — conversations, contacts, messages, search, Obsidian export
Global Arguments
| Argument | Type | Description |
|---|---|---|
| basePath | string | Path to Skype data directory (contains profile subdirectories) |
| profile | string | Profile directory name (e.g. your-skype-name) |
| queryTimeoutMs | number | Max milliseconds to wait for a single sqlite3 subprocess query before aborting it |
| Argument | Type | Description |
|---|---|---|
| minMessages | number | Minimum messages to include |
| Argument | Type | Description |
|---|---|---|
| conversation | string | Conversation identity or display name |
| limit | number | Max messages |
| offset | number | Skip first N messages |
| Argument | Type | Description |
|---|---|---|
| sender | string | Sender skypename or display name (partial match) |
| limit | number | Max results |
| Argument | Type | Description |
|---|---|---|
| folder | string | Obsidian base folder |
| minMessages | number | Skip conversations with fewer messages |
| maxNotesPerResource | number | Flush accumulated notes to a new data resource after this many conversations, bounding both in-memory growth and per-resource size for large profiles |
| Argument | Type | Description |
|---|---|---|
| folder | string | Obsidian base folder |
| vaultPath | string | Absolute path to Obsidian vault directory |
| minMessages | number | Skip conversations with fewer messages |
| Argument | Type | Description |
|---|---|---|
| text | string | Text to search for |
| limit | number | Max results |
Resources
2026.08.02.1
The remaining seven of the nine latent bugs pinned in 2026.07.16.2's test
backfill (all MEDIUM/LOW) are now real-fixed. Tracked end-to-end in the LOCAL
skype-latent-bugs issue-lifecycle model (never a Lab issue). Every adversarial
pin proving each bug now asserts the FIXED behavior instead of the bug; no
benign/frozen contract, methods, or coverage assertion changed byte for byte,
and both 2026.08.01.1 fixes (LB1/LB2) stay green and untouched.
- Resource-name/note-filename collision (MEDIUM), FIXED —
readConversation'sconv_<safeKey>(50-char truncation) andexportToObsidian/importToObsidian's 80-char-truncated filename both collided for two distinct conversations sharing a long common prefix, silently clobbering one's data with the other's. Fixed with a newtruncKey(s, n)helper: a string that already fits withinnCODE POINTS is returned completely unchanged (so every existing short name stays byte-identical); once truncation actually removes something, a short deterministic hash (shortHash, FNV-1a 32-bit, base36-encoded) of the FULL original string is appended, so two names sharing the same truncated prefix no longer collide. exportToObsidianunbounded memory + single-blob resource (MEDIUM), FIXED — every conversation's full chat log used to accumulate into one in-memory array and write as exactly onewriteResourcecall, regardless of profile size. A newmaxNotesPerResourcemethod argument (default500, backward-compatible) now flushes the accumulated notes to their own data resource every N conversations: page 0 keeps the originalobsidian_<profile>name, overflow pages areobsidian_<profile>_p<N>, and the method now returns onedataHandlesentry per page. An empty export still writes exactly one (empty) page 0, never zero resources. Any profile within the default 500-conversation budget — every fixture in this test suite — still writes exactly one byte-identical resource.- No subprocess timeout (MEDIUM), FIXED —
queryDb'sDeno.Commandcarried nosignal/timeout option; a wedgedsqlite3process (e.g. a locked/corruptmain.db) would hold the caller, and the swamp model lock, forever. Fixed with a newqueryTimeoutMsglobal argument (default30000ms, backward-compatible) threaded through everyqueryDbcall site;queryDbnow wraps itsDeno.Commandin anAbortController+setTimeout(() => ac.abort(), timeoutMs), clearing the timer in afinallyblock on every path (success or failure). Deliberately NOTAbortSignal.timeout(ms): that built-in's internal timer has no handle the caller can clear, so a query finishing well within budget would still leave a live timer running — under Deno's test resource sanitizer that shows up as a leaked timer. - Lone-surrogate slice truncation (MEDIUM), FIXED —
importToObsidian's (andexportToObsidian's) 80-char filename slice could cut an astral-emoji surrogate pair in half;Deno.writeTextFilesilently tolerated this, replacing the lone surrogate with U+FFFD on disk rather than erroring or skipping the write. Folded into the sametruncKeyfix as #1 above: truncation now happens by CODE POINT viaArray.from, so a surrogate pair landing at the cut boundary is kept whole rather than split.searchByText'stextKeyslicing was fixed the same way for consistency, though it was never observed to corrupt an on-disk file (it only feeds a resource name). - YAML frontmatter injection via a raw line-break in the display name
(MEDIUM), FIXED — the frontmatter
title:/identity:/profile:template only ever escaped", never a line-break; a display name (or identity, or profile) carrying a raw\r(a real newline character that, unlike\n, survivesqueryDb's row split intact) could inject arbitrary additional YAML-shaped lines into the frontmatter block. Fixed with a newyamlDq(s)helper — backslash and double-quote are backslash-escaped, and every C0 control character (including a raw CR/LF) is replaced with its escape sequence — applied totitle/identity/profilein bothexportToObsidianandimportToObsidian. Byte-identical for every benign (control-character-free) value. - Emoji numeric-entity mis-decode (LOW), FIXED —
stripXml's&#(\d+);decoder usedString.fromCharCode, correct for BMP code points but silently wrong for any astral (>0xFFFF) code point — e.g.😀(grinning face) decoded to an unrelated BMP character instead of the intended emoji. Fixed by switching toString.fromCodePoint, guarded so an out-of-range code point (impossible for\d+to produce negative, butfromCodePointthrows above0x10FFFF) leaves the original entity text
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.
Added 1, removed 1 models
Merge pull request #4 from umag/extensions/magistr-grade-a-workspace
extensions: stage 15 @magistr extensions as Grade A workspace dirs + wire CI
- 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