Juick
Juick.com microblogging API - fetch posts, comments, threads, and import to Obsidian
Global Arguments
| Argument | Type | Description |
|---|---|---|
| apiUrl | string | Juick API base URL |
| allowedHosts | array | Default-deny hostname allowlist applied to the Juick API request and to |
| timeout | number | Per-request timeout (ms) applied to every Juick API fetch via |
| maxPages | number | Maximum number of pages getUserPosts will paginate through before |
| Argument | Type | Description |
|---|---|---|
| uname? | string | Filter by username |
| tag? | string | Filter by tag |
| search? | string | Full-text search |
| popular? | boolean | Show popular messages |
| Argument | Type | Description |
|---|---|---|
| mid | number | Message ID |
| Argument | Type | Description |
|---|---|---|
| uname | string | Username |
| Argument | Type | Description |
|---|---|---|
| uname | string | Username |
| folder | string | Obsidian folder for notes |
| withComments | boolean | Fetch comments for each post |
Resources
Fetch Juick user posts with comments and import into Obsidian vault
2026.08.02.1
Real fix for all 8 latent bugs below (LB1–LB8, tracked locally under
juick-latent-bugs), headlined by an SSRF fix (LB1, HIGH). juick.ts model
version moves from 2026.07.16.2 to 2026.08.02.1; the upgrade bootstraps
the upgrades[] chain (juick had none before) with a single backward-compatible
entry (upgradeAttributes: (old) => old, no resource schema change). Three new
backward-compatible (all .default()) global arguments were added:
allowedHosts, timeout, maxPages.
Test backfill to the STANDARD.md five-suite quality bar (wave 2c, full build of
the extension-quality backfill program, ext-quality-test-backfill) landed
first with no behavior change; this release is the follow-up fix pass over that
same test suite.
Scope correction during planning: juick was originally triaged as an HTML
scraper (plan v1, modeled on the musicbrainz/Bandcamp recipe). Plan v1 was
rejected on adversarial review — juick has no crawlFeed method and no HTML
parsing at all; it is a JSON API client over api.juick.com (getMessages,
getThread, getUser, getUserPosts). Plan v2 re-scoped the entire suite set
to the porkbun JSON-wire recipe (synthetic .json fixtures + stubbed fetch),
which is what the wave-2c backfill implemented.
- Added
extensions/models/juick_test.ts(contract-fixture),juick_methods_test.ts(methods),juick_adversarial_test.ts(adversarial),juick_coverage_test.ts(coverage),juick_property_test.ts(property-invariant-flow) — 0 tests before the wave-2c backfill, 78 after, 82 after this fix pass (pin-flips plus new SSRF-control/private-IP-backstop/ redirect-hop/abort-timeout/maxPages-cap tests). - Added
fixtures/— pure doc-derived, synthetic api.juick.com JSON wire-shape fixtures (messages,thread,user,userposts-page1,userposts-page2,error-500) plusPROVENANCE.md. No live call was made againsthttps://api.juick.com; every username, message id, and body is synthetic. juick has no vault/credentials (unauthenticated public read API), so the fixtures-secret-scan is reframed to real-email/high-entropy/ bearer patterns rather than a vendor-key-shape scan. - Every suite drives
model.methods.<m>.execute()against a stubbedglobalThis.fetch(castas unknown as typeof globalThis.fetch— the deno 2.8.3 toolchain pin) and a fake context. The wave-2c backfill pinned already-shipped behavior — including 8 latent bugs, characterized rather than fixed at the time. All 8 are FIXED in this release (pins flipped injuick_adversarial_test.ts), tracked locally asjuick-latent-bugs(triaged medium/security, never the Lab):- LB1 — SSRF (HIGH) — FIXED.
juickApinow runsassertPublicHttpUrlbefore every request AND before following any redirectLocation: non-http(s) schemes are rejected, loopback/link-local/private-range IP literals (127/8,::1, 169.254/16,fe80::/10, 10/8, 172.16/12, 192.168/16,0.0.0.0,::) are rejected UNCONDITIONALLY — even if present inallowedHosts— and everything else is checked against a new default-denyallowedHostsglobal argument (default["api.juick.com"]). Fetches useredirect: "manual"with a bounded hop loop, re-validating the host on every hop. - LB2 — YAML-frontmatter injection (MED) — FIXED. A hostile
unamecan no longer break out of thesource:/author:double-quoted YAML scalars (newyamlDqescapes backslash, quote, and control characters including CR/LF) or inject a new frontmatter key. Tags keep the existing colon-to-hyphen replacement and additionally collapse embedded newlines to spaces and strip other control characters, so a hostile tag can no longer inject a standalonetags:list item. - LB3 — Unbounded
while(true)pagination (MED) — FIXED.getUserPostsnow stops when the cursor (before_mid) fails to advance (a missingmidon the last message, or a server that echoes the same page back), and is additionally hard-capped by a newmaxPagesglobal argument (default1000). - LB4 — Unguarded
JSON.parse(LOW) — FIXED. A non-JSON 200 body now throws a domainError(Juick <path>: invalid JSON response...) instead of an unmappedSyntaxError. An empty body still parses tonull, unchanged. - LB5 — Three DISTINCT non-array/malformed-response failure shapes (MED) —
FIXED.
getMessagesnow coerces a non-array response to[](matching the existing falsy-case behavior, and now passing its own resource schema);
- LB1 — SSRF (HIGH) — FIXED.
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/juick/CHANGELOG.md
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. Added 1, removed 1 workflows
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