Edition Log · One Sentence Per Fix
Changelog
v0.16.0 – v0.16.3 May 13, 2026
Extension transport: WebSocket → Native Messaging. The extension no longer reaches the CLI via
ws://127.0.0.1:9333; it speaks to a Chrome-managed native-messaging host over OS-supervised stdio. No localhost port is opened; the host is launched on demand and dies when the extension disconnects. PoC validated for 19m30s sustained port, 2.1ms graceful EOF, and clean shutdown across three failure modes. First-run flow gains a one-time tap bridge setup --extension-id <id> step that writes the native-host manifest into Chrome's profile directory; the popup walks new users through it.
Changes
- New permission:
nativeMessaging. Replaces the previous reliance on a localhost WebSocket. No data leaves your machine — see the updated Privacy Policy. - Popup gains failure-mode CTAs. Distinct messaging for "manifest missing" (run setup), "host crashed" (check
host.log), and "Chrome blocklist active" (restart Chrome) — instead of one generic "bridge down". - Service-worker keepalive consolidated. 25-second alarm plus four wake hooks (
onStartup,onInstalled,tabs.onActivated,windows.onFocusChanged) — Chrome MV3's 30s idle sleep is no longer user-visible.
v0.15.8 May 9, 2026
Release pipeline is fully hands-off. First end-to-end run with zero human intervention:
git push v0.15.8 → 12 CI jobs → npm + PyPI + GitHub binaries + Homebrew formula + MCP Registry all auto-update. The MCP Registry leg uses GitHub Actions OIDC (no shared secret) with a direct curl POST to bypass a confirmed CLI false-negative bug.
Fixes
release.yml mcp-registry-publishuses curl directly instead ofmcp-publisher publish. The CLI v1.7.8 returns HTTP 400 "duplicate version" even when the underlying POST returns 200 — verified against live Registry on 0.15.6 and 0.15.7. Workaround extracts the OIDC-issued JWT from~/.config/mcp-publisher/token.jsonand posts to/v0/publishwith curl.mcp-publisherinstall URL fix. Theinstall.shpath on the registry repo doesn't exist; replaced with direct release-tarball download (mcp-publisher_linux_amd64.tar.gz, pinned to v1.7.8).
v0.15.7 May 9, 2026
Features
- MCP Registry auto-publish lands in
release.yml. A newmcp-registry-publishjob authenticates via GitHub OIDC and pushes the canonicalserver.jsonon every tag push. No more 13-day stalenesses where the Registry pinned@taprun/cli@0.14.0while npm shipped 0.15.4. Bumps version pins from canonicalnpm/cli/package.jsonviajq; no generator script, no diff gate, no SHIPPED_* table — just one ~30-line CI job.
v0.15.6 May 9, 2026
Userspace via standards. ADR-driven: bare
tap defaults to stdio MCP when stdin is a pipe — MCP host config simplifies to {"command":"tap"}, no Tap-specific argv string required. Plan files now self-declare $schema URL; loader supports every URL ever shipped, returning typed kind:"unknown_schema" for forward-incompatible plans.
Features
- E1 — argv dissolution.
tapwith empty argv routes by stdin TTY: pipe/redirect → stdio MCP server; TTY → help. All previously-published argv forms (mcp start,mcp stdio,serve,serve stdio) continue to work via alias dispatch (Tier 0 userspace loyalty). - INV-2 — plan
$schemafield. Optional URL on every Plan;persistence.ts:loadPlandispatches by URL, supports every shipped schema. Adding a new schema = appending one reader function. Drift class structurally impossible. tap daemon <sub>forwards totap bridge <sub>. Previously,tap daemon statussilently started a daemon (sub-verb argv was dropped). Now grammar and behavior align: baretap daemonstill starts (preserves systemd convention);tap daemon <anything>mirrorstap bridge <anything>.tap --versionworks in compiled binary. OldreadVersion()tried to readCHANGELOG.mdviaimport.meta.url— the file isn't on disk insidedeno compile'd binaries. Now JSON-imports fromnpm/cli/package.jsonat bundle time so the version literal is welded into the binary.
Fixes
- Homebrew orphan formula deleted.
Formula/tap.rbat v0.4.0 was stuck since thetap → taprunrename in 2026-05-03; auto-bump only touchedtaprun.rb. Anyone runningbrew install LeonTing1010/tap/tapgot a years-old binary. Fixed viaoldname "tap"alias on the canonicaltaprun.rb; existing install commands keep working.
v0.15.5 May 5, 2026
Fixes
- Extension cross-origin tab routing. Cross-origin navigations now update the daemon's
lastActiveTabcache so subsequent ops route to the new tab. Previously the cache lagged behind the SW's view, causing routes to a closed/wrong tab. - Origin-mismatch nav opens new background tab. When a saved tap navigates to a host different from the active tab, the extension now spawns a background tab instead of clobbering the user's foreground tab.
- Extension self-heal — MV3 SW keep-alive. Service worker stays alive while a long-running op is in flight (chrome.alarms heartbeat); prevents the 30s idle-kill mid-op.
v0.15.4 May 3, 2026
v2 launch — substrate dissolved, surface vocabulary converged. Engine source contains no type representing substrate state. The 11 ops in
core/types.ts ARE the protocol. Tool surface collapses 12→4 meta verbs (capture / verify / mark / run); saved taps appear as MCP Resources at tap://{site}/{name}.
Features
- Substrate-dissolved engine. No
Substratetype or interface anywhere incore/.core/dispatch.tsroutes each op to either an inline handler or to a registered peer function; substrate state lives on the other side of a function-call boundary, structurally inaccessible to the engine. Per ADR2026-05-04-substrate-dissolved.md. - 4 meta verbs + N saved-tap Resources. Tool table is constant; per-plan capability is exposed as MCP Resources, not per-plan Tools. Discovery flow:
resources/list→resources/read({uri})→run({ref, args}). Per ADR2026-05-04-saved-taps-as-resources.md. - Plan format simplified to bare JSON. No W3C envelope, no
@context, nomotivation. Pure data, schema-validated againstcore/types.ts.op:execdeleted;op:evalis the only escape hatch with mandatoryreturns.type. - Daemon model. Single-process daemon hosts the in-process queue plus two listeners (
:9333extension long-poll,:9334MCP HTTP). Auto-forks on first call from CLI/stdio; idle-times out at 30 min. - K(Δ) accounting via Run transitions. Every Run captures a transition log; healing/recovery cost is computed by projecting over
transitions[kind=="heal"].
v0.15.3 May 3, 2026
Fixes
- Release pipeline 5-bug sweep. v0.15.0 → 0.15.4 retried the binary-release flow until every latent CI bug was caught: bundle entry path, transitive-npm-import externalization, deno.json imports-map propagation, GH cross-repo PAT scope, and a stale
npm_publish_test.tsreference. v0.15.4 was the first all-green run; v0.15.0–3 are CI-fix patches with no behavior changes.
v0.14.5–v0.14.7 May 1, 2026
Fixes
- Capability-strict runtime API. Plans declare
requires; lint hard-rejectspage-sessionwithoutrequires.runtime:"extension".tap.runpre-flightsmatchCapabilitybefore any op. No silent ephemeral-fallback or string-warning machinery. - Op-grain plan fingerprint Phase 1.
PlanFingerprint.op_hashes+diffPlanFingerprintshelper. Heal/doctor consumer wiring deferred to Phase 2. - No-new-legacy on save.
lintPlan({isNewSave:true})rejects plans withlegacy:true;handleSavePlancomputes the flag from filesystem instead of trusting payload. Drainage terminal state codified.
v0.14.0–v0.14.4 April 26 – May 1, 2026
MCP Registry submission. Tap goes live in the official Anthropic MCP Registry at
io.github.LeonTing1010/tap; PulseMCP auto-syncs within 2 days. op:fetch gains credentials: "deno-host" | "page-session" field for cross-origin auth via the user's logged-in Chrome.
Features
- MCP Registry listing live.
mcp-publisher publishfrom the canonicalserver.json. Empirical test confirmed Registry search is name-only —nameis the discovery key,description/title/websiteUrlare render-only. v0.14.2/0.14.3 refresh metadata visible in client UIs. op:fetch credentials: "page-session". Enables cross-origin requests authenticated by the user's Chrome session, replacing theop:execescape hatch for 4 reddit taps blocked on free-tier auth.
v0.13.0–v0.13.1 April 20–22, 2026
Features
- Plan-lint — static author-time checks. Catches schema errors, dangling references, unsafe ops at save time instead of run time. CLI reads
.tap.jsonviafindTap+doctor. tap.runenvelope: annotation. Run records carry W3C Annotation envelope for cross-tool interop.
Fixes
- Sandbox fully retired. The sandbox layer that isolated tap code from the host's Deno APIs is removed; security boundary is now purely the runtime+extension trust model.
- Linux UPX fix. v0.13.0
tap-linux-x64was UPX-packed and broke at startup ("Could not find standalone binary section"). v0.13.1 removes UPX from the build pipeline. - Runtime vision op removed. Violated the zero-AI-at-runtime invariant; vision-related compilation now happens at authoring time only.
v0.11.3 April 11, 2026
Chrome MV3 "many empty tabs" root fix. Four related bugs, one root cause: MV3 service workers wipe in-memory state every ~30s of idle, but Chrome tabs persist. The sessions Map in the extension was losing track of its own tabs across SW restarts, and every follow-on symptom traced back to that one mismatch. Full post-mortem: Debugging Chrome MV3's "Many Empty Tabs" Bug.
Fixes
- Session persistence across service-worker restarts. Extension's sessions Map is now written through to
chrome.storage.sessionand rehydrated on SW wake. Previously, any session created before an SW idle became an orphan:session.destroysilently no-op'd on lookup miss, and the tab leaked forever. - nav no longer leaks
chrome://newtab/placeholder tabs. The daemon-path nav handler used to create a replacement tab whenever the current URL waschrome://, updating session.tabId but never closing the original. Now useschrome.tabs.updatein place. - MCP main session is lazy.
mcp-stdio.ts/mcp-http.tsused to eagerlysessionCreateon the first non-local tool call, wasting a browser tab for puretap.runworkflows (which create their own temp session). Main session now materializes only on first use of the interactive API. - Compiled-binary detection uses
Deno.execPath(). The priorDeno.mainModule.startsWith("file://")check silently regressed in recent Deno — both source and compiled contexts now returnfile://-prefixed main modules, so the Playwright→extension fallback never fired and every compiled binary errored with "Playwright is not available" on the first MCP call.
v0.11.2 April 11, 2026
Fixes
npm-publish --sync-onlyruns sync step only instead of triggering the full build+publish pipeline. Used byrelease.shstep 1 to keep npm package.json versions aligned withsrc/cli.tsVERSION without rebuilding dist/.
v0.11.1 April 10, 2026
Fixes
- Daemon pollWaiters drops dead waiters on timeout. Stale waiters accumulated on every client timeout and caused subsequent
notifyPollcalls to shift resolved no-ops instead of the live extension waiter — every client command was paying the full poll timeout (~20s) before dispatch. Unblocked typical RPC latency back to single-digit milliseconds.
v0.11.0 April 10, 2026
MCP goes Playwright-first. Zero-friction onboarding:
tap mcp now defaults to Playwright runtime (no extension, no daemon needed). Users can switch to Chrome mid-session via the new tap.connect(runtime:'chrome') tool when they hit an auth wall.
Features
tap.connect— switch runtime mid-session in MCP. Hit a login wall on a headless run? Calltap.connect(runtime:'chrome')and the next tool call operates on your real Chrome browser with login cookies. No server restart.tap doctor --env— environment health check. One command surfaces daemon status, extension connectivity, Playwright availability, Chrome profile state, and MCP auth — the first place to look when something misbehaves.- SessionManager refactor — extension owns all tab lifecycle. Sessions are created, routed, and destroyed inside the extension process; Deno side just holds sessionIds. Cleaner boundary, fewer cross-process races.
Fixes
- MCP detects Playwright availability at startup and falls back to extension runtime if the npm package isn't loadable. Hint messages guide users to either install Playwright or call
tap.connect(runtime:'chrome'). tap.runreuses caller's runtime context. Previously, a tap run from a Playwright MCP session would spawn a fresh extension runtime, losing cookies/session. Nowtap.runhonors the caller's runtime when they match.- Stable daemon token + forge captures page-load API traffic. Daemon restarts no longer invalidate MCP auth; forge.inspect now captures network requests that happen during the initial page load (previously missed the first batch).
- Sandbox allows all
tap.*RPC methods, blocks Deno APIs. Clarified the sandbox's threat model: it isolates untrusted tap code from the host's filesystem/network/env, not from the browser runtime (which has its own security layer). codesign --deepfor macOS binaries. Nested frameworks in the compiled binary were not being signed, causing Gatekeeper to kill the process on launch.
For releases older than v0.11.0, see the full GitHub releases archive.