JS Cpp Protocol
notepadqq/notepadqq
Reference for the communication protocol between the JavaScript editor (CodeMirror or Monaco) and the C++/Qt UI layer via QWebChannel.
Build and modify tinyjs desktop apps — tiny macOS (and beta Windows/Linux) apps with a txiki.js JavaScript backend and a native webview window.
$ npx skills add tarwin/tinyjsapp --skill tinyjs -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install tarwin/tinyjsapp tinyjs --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/tarwin/tinyjsapp.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skill .claude/skills/tinyjs && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "tinyjs" agent skill from https://github.com/tarwin/tinyjsapp/tree/main/skill into .claude/skills/tinyjs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "tinyjs", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/tarwin/tinyjsapp/tree/main/skillType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add tarwin/tinyjsapp --skill tinyjs -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install tarwin/tinyjsapp tinyjs --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/tarwin/tinyjsapp.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skill .agents/skills/tinyjs && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "tinyjs" agent skill from https://github.com/tarwin/tinyjsapp/tree/main/skill into .agents/skills/tinyjs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "tinyjs", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add tarwin/tinyjsapp --skill tinyjs -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install tarwin/tinyjsapp tinyjs --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/tarwin/tinyjsapp.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skill .cursor/skills/tinyjs && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "tinyjs" agent skill from https://github.com/tarwin/tinyjsapp/tree/main/skill into .cursor/skills/tinyjs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "tinyjs", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/tarwin/tinyjsapp.git --path skill--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add tarwin/tinyjsapp --skill tinyjs -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install tarwin/tinyjsapp tinyjs --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/tarwin/tinyjsapp.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skill .gemini/skills/tinyjs && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "tinyjs" agent skill from https://github.com/tarwin/tinyjsapp/tree/main/skill into .gemini/skills/tinyjs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "tinyjs", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install tarwin/tinyjsapp tinyjsInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add tarwin/tinyjsapp --skill tinyjs -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/tarwin/tinyjsapp.git skills-src && mkdir -p .github/skills && cp -r skills-src/skill .github/skills/tinyjs && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "tinyjs" agent skill from https://github.com/tarwin/tinyjsapp/tree/main/skill into .github/skills/tinyjs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "tinyjs", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add tarwin/tinyjsapp --skill tinyjs -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install tarwin/tinyjsapp tinyjs --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/tarwin/tinyjsapp.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skill .opencode/skills/tinyjs && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "tinyjs" agent skill from https://github.com/tarwin/tinyjsapp/tree/main/skill into .opencode/skills/tinyjs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "tinyjs", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
tinyjsBuild and modify tinyjs desktop apps — tiny macOS (and beta Windows/Linux) apps with a txiki.js JavaScript backend and a native webview window.
Tinyjs is an agent skill from tarwin/tinyjsapp. Build and modify tinyjs desktop apps — tiny macOS (and beta Windows/Linux) apps with a txiki.js JavaScript backend and a native webview window. Use when working in a project with a tinyjs.json, when the user mentions tinyjs, tiny.api, or tinyjs dev/build, or when porting an Electron app to tinyjs.
Its SKILL.md is about 2.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 7 other files, including reference files (for example `references/api.md`, `references/electron-migration.md` and `references/performance.md`).
It works with Linux, macOS, Electron and JavaScript. The repository describes itself as: Build native apps in JS. Backend, frontend. ~5Mb. The licence is MIT.
Read from SKILL.md and the folder at commit 24d21a2. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are javascript and bash).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Tinyjs loads about 2.9k tokens when it runs, and up to ~20k if it reads all its reference files. Until then it costs about 76 tokens; SKILL.md has 650 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from tarwin/tinyjsapp at commit 24d21a2, republished under its MIT licence (© tarwin). 650 words, ~2,928 tokens.
.claude/skills/tinyjs/SKILL.md (or your agent's skills folder). This skill also uses 6 other files; get the full folder from GitHub.tinyjs (https://tinyjs.app, repo tarwin/tinyjsapp) makes ~6 MB desktop apps: a txiki.js backend (full system access: files, sockets, processes, FFI)
tiny.api (which the tinyjs.json "api" gate can
narrow), which is why anything interpolated into innerHTML must be
escaped. Two launcher-side paths skip that crossing, both limited to the
app's own pages and the origins "api" trusts: tiny.proxyURL's
tiny-media:// proxy (cross-origin http(s) reads, macOS + Linux;
media.proxy) and mic/camera (media.microphone / media.camera).Current release: 0.50.0. App floors: macOS 15+ — a default build opens only
on the build Mac's CPU (build --arch arm64|x86_64 or --universal for the
other); Windows 10/11 (WebView2); Linux glibc 2.35+ (Ubuntu 22.04 / Debian 12
/ Mint 21 and up).
| doing | read |
|---|---|
| any API beyond the basics below (windows, menus, tray, clipboard, audio, permissions, system…) | references/api.md |
| per-OS support, Windows/Linux quirks, capability gating | references/platforms.md |
| starting a tray app, desktop pet/overlay, media app, document app, site wrapper, agent app | references/recipes.md |
| shipping: build/sign/notarize, per-OS packaging, auto-update manifests | references/release.md |
| porting from Electron (API map, what won't work) | references/electron-migration.md |
| deciding where code runs, wire/binary payloads, throttling, memory | references/performance.md |
tinyjs new <dir> # scaffold (zero dependencies)
tinyjs new <dir> --template react-ts|vue-ts|svelte-ts|solid-ts|preact-ts|lit-ts|alpine-ts|vanilla-ts|…
# create-vite + tinyjs overlay: HMR dev server in the
# native window, esbuild-bundled TS backend (npm pkgs ok).
# No name = asks framework + language. --pm npm|pnpm|
# yarn|bun|vp[:pnpm] (else asks; npm off a terminal),
# --no-install. Agents: pass both flags — no prompts.
# vp needs Vite+ ≥ 1.0. alpine = vanilla + Alpine.js.
tinyjs wrap <url> # site wrapper: the site IS the app, origin-gated API
# (--origins subdomains, --menubar [--panel], --top,
# --external a.com, --ua, --force re-wraps in place)
tinyjs dev # run with hot reload (frontend edits swap in place;
# backend edits restart the process)
tinyjs build # dist/<name> binary + dist/<Name>.app (codesigned)
# --dmg installer image; --cli [name] terminal shim
# --arch arm64|x86_64: macOS .app for that CPU (any Mac;
# 0.42+); --universal: one .app for both (needs the
# Command Line Tools' lipo). Bare dist/<name> = host CPU
tinyjs publish # build + dist/publish/<name>-<ver>.zip|tarball + manifest
tinyjs notarize # macOS: notarytool submit + staple (--dmg re-makes dmg)
# publish/notarize take --arch too — repeat the build's
tinyjs update # update tinyjs itself (--check); also: uninstall, version
TINYJS_DEBUG=1 tinyjs dev # trace every bridge messagetinyjs.json { name, title, size, id, version, icon?,
minTinyjsVersion?, // refuse older tinyjs with a
// real message; `tinyjs new`
// stamps its own version — raise
// it for newer APIs you adopt
update?: { url: "https://…/manifest.json", auto? },
urlScheme?: "myapp", fileExtensions?: ["md"],
openFolders?: true, readAccess?: true | "/path",
userAgent?: "…", activation?: "accessory",
offscreenRescue?: false, windowPlacement?: true,
contextMenu?: false, audioTap?: "app" | "system",
audioTapReason?: "why", about?: "menu",
attribution?: "…", // About panel credit line (macOS);
// a project-root Credits.html wins
debug?: true | "open", browserAccelerators?: true,
permissions?: { microphone?: "why", camera?: "why",
speechRecognition?: "why" },
chrome?: { frame, windowControls, windowControlsPos,
transparent, vibrancy, squareCorners,
acceptsFirstMouse, menu },
signIdentity?, notarize?: { profile },
backend?: "backend/main.ts", // .ts → esbuild bundle;
// default src/main.{js,ts} or backend/main.{js,ts}
frontend?: { dir?, build, dist, dev, devUrl },
// dir: plain page folder (default src/frontend);
// build/dev need the packages installed first
// wrapping a hosted site (recipes.md) — "url" replaces
// the local frontend, "api" gates what that origin may
// call. NEVER wrap a site you don't control without it.
url?: "https://app.example.com",
inject?: "src/shim.js", // document-start, every page
downloads?: "auto" | "ask" | "deny",
popups?: "external" | "window" | "deny",
api?: "wrapper" | { disable?, enable?, origins? },
macos?/windows?/linux?: { …merged on top per OS } }
icon.png 1024×1024 app icon
src/main.js backend
src/frontend/ index.html + assets — served as real files (file://),
so relative paths just workexport const api = {
// page calls tiny.api.call('readNotes', { dir }) — return resolves the
// page's promise, throwing rejects it; meta.window = calling window id
readNotes: async ({ dir }, app, meta) => { ... },
};
export function init(app) {
app.push('event-name', data); // page: tiny.api.on('event-name')
// app mostly mirrors the page: app.window(id).*, app.openWindow,
// app.tray.*, app.audio.sampler.*, app.clipboard.*, app.store.*,
// app.paths (plain object), notify, quit, … — but some names differ
// (app.setMenu, app.setChrome, …): name map in references/api.md
}
// other exports the scaffold wires, each (info, app): onMenu, onTray (id
// null = bare icon click), onContextMenu, onHotkey, onWindowState,
// onWindowClosed, onOpenUrl, onOpenFiles, onMediaKey, onNotificationClick,
// onNotificationAction, onUpdateAvailable, onClipboardChange, onLocale,
// onAudioTap, onNavigate, onDownload, onWindowOpen — except
// onSystem(kind, value, app)Runtime is txiki.js (tjs global): tjs.readFile/writeFile/readDir/stat,
tjs.spawn, tjs.watch, fetch, WebSocket, tjs:sqlite, FFI. It is
NOT Node (no require, no Node builtins, no native npm modules) and it has
no JIT — compute-heavy work belongs in the page
(references/performance.md). Streams need getReader() (no for await);
tjs.cwd is a property; no Intl (format in the page). Every tjs.* fs
call is async — await it — while tjs:sqlite is fully sync (never await;
statements have run/all/finalize only, no get(), run() returns void).
await tiny.api.call('method', { params }); // -> backend api.<method>
const off = tiny.api.on('event', fn); // <- app.push; returns unsubscribe
audio.src = tiny.fileURL(path); // ALWAYS this, never 'file://' + path
// (breaks on Windows drive letters)
const r = await tiny.fetch(url, opts); // backend-proxied, no CORS/CSP
tiny.win.open('settings', { page: 'settings.html', size: '420x300',
chrome: { frame: false } });
// chrome/x/y/minSize in open() (or tinyjs.json "chrome" for main) apply
// BEFORE first paint — a late setChrome flashes the default window.Everything else — windows/chrome/state events, menus (in every window),
dialogs, tray, notifications, clipboard, hotkeys, audio (sampler / filters /
audioTap / proxyURL), store/secrets, permissions, deep links, auto-update,
tiny.macos.* — is in references/api.md with signatures and gotchas.
capabilities() lists only the
EXCEPTIONS: test caps.x !== false, never if (caps.x) (the truthy form
reports "unsupported" on the OS that has it). Query calls resolve null
where unsupported, capability calls reject with the reason,
fire-and-forget ones no-op — but tiny.macos.* off macOS REJECTS.
caps.sampler is a string ('native'|'page') — informational, don't
branch.app.paths / tiny.app.paths() — never hardcode ~/Library or
%APPDATA%; join with '/' (works everywhere).tiny.system.os()/isMacOS()/isWindows()/isLinux() are synchronous;
architecture() must be awaited (navigator lies on Apple Silicon).tiny.system.promptMissing([ids]) puts the fix in front of the user.{ title: 'Edit' } — macOS already has one, so
the bar shows two. Use { role: 'edit', items: [...] }; for the SAME
menu on all three OSes, place the stock items yourself:
items: [{ role: 'standard' }, { separator: true }, ...yours]
(details in references/api.md → Menus).api methods; keep the frontend thin — but
keep COMPUTE in the page and bytes off the wire (pass paths, not
ArrayBuffers; references/performance.md).innerHTML — the page holds an RPC
channel to full system access.chrome identifier in frontend code:
window.chrome is a non-configurable global on WebView2, so a top-level
const chrome is a PARSE-time SyntaxError that kills the whole script.ctx.destination (it crackles —
measured, unfixable page-side). SFX → tiny.audio.sampler; EQ →
tiny.audio.filters; details in references/platforms.md.TINYJS_HTML=/abs/page.html tinyjs dev. The bundled test/smoke.html
only fits an UNMODIFIED zero-dependency scaffold (it calls the template's
sysinfo/listDir and waits for its tick push).tinyjs: explanation and exits 3 ("launcher exited before connecting") —
the environment, not your code; there is no headless mode.dist/<Name>.app is the distributable; bare dist/<name> is local-only.© tarwin, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 6 other files (references) in skill of tarwin/tinyjsapp.
Open the folder on GitHubat commit 24d21a2
Tinyjs next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Tinyjs this skilltarwin/tinyjsapp | 671 | — | ~2.9k | Automated safety check: Pass | MIT | |
| JS Cpp Protocolnotepadqq/notepadqq | 2.3k | — | ~3.2k | Automated safety check: Pass | GPL-3.0 | |
| Releasing Blancbnfy/blanc | 105 | — | ~2.9k | Automated safety check: Notes | MIT | |
| Debug CIweb-infra-dev/rslint | 460 | — | ~2.8k | Automated safety check: Pass | MIT | |
| Import Open Tabsbnfy/blanc | 105 | — | ~510 | Automated safety check: Pass | MIT | |
| Windows macOS Test Packageswjybky/deepwrite | 559 | — | ~574 | Automated safety check: Pass | Apache-2.0 |
notepadqq/notepadqq
Reference for the communication protocol between the JavaScript editor (CodeMirror or Monaco) and the C++/Qt UI layer via QWebChannel.
bnfy/blanc
Full runbook for cutting a Blanc desktop release — scripts/release.sh mechanics and its required BLANCRELEASE env vars, macOS notarization via 1Password, the Touch ID provisioning profile and…
web-infra-dev/rslint
Reproduce Linux CI failures locally using Docker when the same tests pass on the host, especially Go platform differences and VS Code extension tests requiring xvfb.
bnfy/blanc
Copy the current Chrome, Edge, Brave, Opera, or Vivaldi window into the current Blanc window through a private one-time handoff, with a new window available as an explicit choice in Blanc.
swjybky/deepwrite
构建并验证 DeepWrite Windows、macOS 测试安装包,排查打包错误、修复后继续。用于打包、测试包、Win/Mac 包及相关流程修改;版本递增和发布另用 package-patch-release。
pedronauck/skills
Comprehensive guide for electron-builder (v26.x) packaging, code signing, auto-updates, and release workflows.
Works with
Build and modify tinyjs desktop apps — tiny macOS (and beta Windows/Linux) apps with a txiki.js JavaScript backend and a native webview window. Tinyjs is an agent skill from tarwin/tinyjsapp.js JavaScript backend and a native webview window.
Tinyjs fits situations like: working in a project with a tinyjs.json; the user mentions tinyjs; tinyjs dev/build; porting an Electron app to tinyjs.
Run `npx skills add tarwin/tinyjsapp --skill tinyjs -a claude-code`. Or copy the skill folder (skill in tarwin/tinyjsapp) into .claude/skills/tinyjs in your project. Claude Code loads it when a task matches its description.
Run `npx skills add tarwin/tinyjsapp --skill tinyjs -a codex`. Or copy the skill folder (skill in tarwin/tinyjsapp) into .agents/skills/tinyjs in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add tarwin/tinyjsapp --skill tinyjs -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/tinyjs, .gemini/skills/tinyjs, .github/skills/tinyjs and .opencode/skills/tinyjs in your project.
SKILL.md names no scripts, command-line tools or credentials: Tinyjs is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Tinyjs is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 2.9k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 17k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Tinyjs: JS Cpp Protocol (notepadqq/notepadqq, 2.3k stars), Releasing Blanc (bnfy/blanc, 105 stars), Debug CI (web-infra-dev/rslint, 460 stars) and Import Open Tabs (bnfy/blanc, 105 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
tarwin (a GitHub user) maintains it in tarwin/tinyjsapp, which has 671 GitHub stars. The repository was last updated on October 6, 2026.
Source: tarwin/tinyjsapp on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.