Skip to main content

Juick

@magistr/juickv2026.08.19.1· 23d agoMODELSWORKFLOWS
01README

Juick.com microblogging API - fetch posts, comments, threads, and import to Obsidian

02Models1
@magistr/juickv2026.08.19.1extensions/models/juick.ts

Global Arguments

ArgumentTypeDescription
apiUrlstringJuick API base URL
allowedHostsarrayDefault-deny hostname allowlist applied to the Juick API request and to
timeoutnumberPer-request timeout (ms) applied to every Juick API fetch via
maxPagesnumberMaximum number of pages getUserPosts will paginate through before
fn getMessages(uname?: string, tag?: string, search?: string, popular?: boolean)
Get messages from feed, optionally filtered by user or tag
ArgumentTypeDescription
uname?stringFilter by username
tag?stringFilter by tag
search?stringFull-text search
popular?booleanShow popular messages
fn getThread(mid: number)
Get a full thread (post + comments) by message ID
ArgumentTypeDescription
midnumberMessage ID
fn getUser(uname: string)
Get user profile
ArgumentTypeDescription
unamestringUsername
fn getUserPosts(uname: string, folder: string, withComments: boolean)
Get ALL posts by a user with pagination, fetch comments for each, format for Obsidian
ArgumentTypeDescription
unamestringUsername
folderstringObsidian folder for notes
withCommentsbooleanFetch comments for each post

Resources

messages(1h)— Messages from Juick feed
thread(1h)— Full thread with comments
userProfile(1h)— User profile
userPosts(1h)— All posts by a user with comments
03Workflows1
@magistr/juick-to-obsidian

Fetch Juick user posts with comments and import into Obsidian vault

fetchFetch all user posts from Juick with comments and format for Obsidian
1.get-postsjuick.getUserPosts— Fetch all posts with pagination, comments, and Obsidian formatting
importCreate notes in Obsidian vault
1.create-note-${{ self.post.mid }}my-vault.create— Create Obsidian note for Juick post
04Previous Versions4
2026.08.02.1

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) plus PROVENANCE.md. No live call was made against https://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 stubbed globalThis.fetch (cast as 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 in juick_adversarial_test.ts), tracked locally as juick-latent-bugs (triaged medium/security, never the Lab):
    • LB1 — SSRF (HIGH) — FIXED. juickApi now runs assertPublicHttpUrl before every request AND before following any redirect Location: 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 in allowedHosts — and everything else is checked against a new default-deny allowedHosts global argument (default ["api.juick.com"]). Fetches use redirect: "manual" with a bounded hop loop, re-validating the host on every hop.
    • LB2 — YAML-frontmatter injection (MED) — FIXED. A hostile uname can no longer break out of the source:/author: double-quoted YAML scalars (new yamlDq escapes 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 standalone tags: list item.
    • LB3 — Unbounded while(true) pagination (MED) — FIXED. getUserPosts now stops when the cursor (before_mid) fails to advance (a missing mid on the last message, or a server that echoes the same page back), and is additionally hard-capped by a new maxPages global argument (default 1000).
    • LB4 — Unguarded JSON.parse (LOW) — FIXED. A non-JSON 200 body now throws a domain Error (Juick <path>: invalid JSON response...) instead of an unmapped SyntaxError. An empty body still parses to null, unchanged.
    • LB5 — Three DISTINCT non-array/malformed-response failure shapes (MED) — FIXED. getMessages now coerces a non-array response to [] (matching the existing falsy-case behavior, and now passing its own resource schema);

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

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.

Added 1, removed 1 models. Added 1, removed 1 workflows

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
15.6 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