Jsk Studio F95zone May 2026
| Use‑case | How the Bridge helps | |----------|----------------------| | on F95Zone when a build is published from JSK Studio. | Generates a markdown‑ready post with title, description, version, changelog, cover‑art and download link. | | Sync changelog & screenshots whenever a new commit is pushed to the project repo. | Updates the existing thread (or creates a new “Update” post) with the latest screenshots and release notes. | | Two‑way notification – get forum replies or private messages inside the JSK Studio UI. | Shows a badge in the IDE with the count of unread forum replies; clicking opens a small chat‑like panel. | | User‑based access control – only allow verified developers to post on behalf of the game. | OAuth2 login via F95Zone’s API (or a custom token flow) stores a short‑lived access token per developer. | | Analytics dashboard – view page‑views, download clicks, and “likes” directly in the studio. | Pulls public statistics from F95Zone (or parses the thread HTML) and visualises them in a tab. | 2️⃣ High‑Level Architecture +-------------------+ +----------------------+ +-------------------+ | JSK Studio IDE | HTTP | JSK‑F95Connector | HTTP | F95Zone API / | | (plugin UI) +--------->| (Node/TS backend) +--------->| Webhooks / HTML | +-------------------+ +----------------------+ +-------------------+
export interface F95Post title: string; body: string; // markdown category: string; // e.g., "Adult Game" tags?: string[]; jsk studio f95zone
For developers who prefer a no‑code approach, the plugin can expose a “Generate markdown” button that copies the output to the clipboard, allowing manual posting if the API is unavailable. 7️⃣ UI Mock‑up (Textual Description) +--------------------------------------------------------------+ | JSK Studio – Bottom Panel | |--------------------------------------------------------------| | [F95Zone] Connect | Status: Connected as <username> | |--------------------------------------------------------------| | Game Title: <input> | Category: <dropdown> | | Version: <input> | Cover image: <preview + upload> | |--------------------------------------------------------------| | [Publish Build] [Sync Changelog] [View Thread] [Analytics]| |--------------------------------------------------------------| | Unread Replies: 3 (badge) | Views: 1,254 Likes: 87 | +--------------------------------------------------------------+ All controls are optional – the developer can enable only the parts they need. 8️⃣ Testing & QA Checklist | Test | Description | |------|-------------| | OAuth flow | Verify token retrieval, expiration handling, and revocation. | | Thread creation | Mock API response; ensure markdown is correctly escaped. | | Update comment | Confirm that only the new part of the changelog is added. | | Badge count | Simulate a new reply and confirm badge increments. | | Analytics | Use a fake stats endpoint and verify chart rendering. | | Error handling | Force 429/500 responses and verify exponential back‑off. | | Security | Run static analysis to ensure no token leaks in logs. | | Cross‑platform | Test on Windows/macOS/Linux installations of JSK Studio. | 9️⃣ Release Plan | Milestone | Scope | Approx. Effort | |-----------|-------|----------------| | MVP | OAuth, thread creation, markdown | Use‑case | How the Bridge helps |
/** * Create a new thread (first release). */ export async function createThread( post: F95Post, token: string ): Promise< threadId: string; url: string > const payload = title: post.title, body: post.body, category: post.category, tags: post.tags ?? [], ; const data = await authFetch( "https://api.f95zone.to/v1/threads", token, method: "POST", body: JSON.stringify(payload) ); return threadId: data.id, url: data.url ; | Updates the existing thread (or creates a
/** * Pull unread replies (used for badge count). */ export async function getUnreadCount( threadId: string, token: string ): Promise<number> const data = await authFetch( `https://api.f95zone.to/v1/threads/$threadId/replies?unread=true`, token ); return data.unreadCount ?? 0;
$coverImgUrl ? `\n` : ""