Help us shape the future of Go! Take the 2026 Go Developer Survey

nativehost

package
v0.57.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 1, 2026 License: AGPL-3.0 Imports: 19 Imported by: 0

Documentation

Overview

Package nativehost implements the Chrome Native Messaging host the companion browser extension pairs through: Chrome launches `ogcode native-host` with the port's stdin/stdout bound, and everything the extension needs to find this machine's running ogcode servers — an origin, a websocket URL and a pair token per server — is one "pair" request away.

The wire protocol is the one Chrome defines for native messaging: every message, request and reply alike, is a 4-byte length followed by that many bytes of UTF-8 JSON. Chrome's spec says the length is written in the machine's native byte order, and every platform Chrome ships on is little-endian (x86, ARM64, WebAssembly), so binary.LittleEndian matches native order everywhere while keeping the framing platform-independent.

Only framed messages may ever reach the host's stdout — Chrome reads that pipe as a stream of frames, and one stray line breaks every reply after it — so diagnostics go to stderr through slog and never touch out.

Index

Constants

View Source
const ExtensionIDsEnv = "OGCODE_EXTENSION_IDS"

ExtensionIDsEnv is the process-wide env var of extra extension ids to allowlist, comma-separated.

View Source
const NativeHostName = "com.ogcode"

NativeHostName is the native-messaging host's name: it names both the manifest file Chrome looks up ({Name}.json) and the chrome.runtime.connectNative call the extension makes.

View Source
const UnpackedExtensionDir = "browser-extension"

UnpackedExtensionDir names the project folder the companion extension lives in while it is built, before the store publishes an id for it.

View Source
const WebStoreExtensionID = "kacnfgnhmmnhdpokflkiemdehhjhkidp"

WebStoreExtensionID is the companion extension's published Chrome Web Store id. Store installs run under this id, so every native-messaging manifest written at boot allowlists it and a store install pairs itself without a flag. (Unpacked repo installs keep their path-derived id alongside it.)

Variables

This section is empty.

Functions

func CandidatesFor

func CandidatesFor(projectDir string) []string

CandidatesFor lists the extension ids projectDir is entitled to allowlist: the unpacked browser-extension/ directory when the project ships one, ids named in OGCODE_EXTENSION_IDS, and the published web store id once the extension ships. Deduplicated in order, empty ids dropped.

func DedupeExtensionIDs

func DedupeExtensionIDs(ids []string) []string

DedupeExtensionIDs keeps each id's first occurrence, in order, dropping empty strings — the shape CandidatesFor returns and Register accepts.

func DisabledByEnv

func DisabledByEnv() bool

DisabledByEnv reports whether OGCODE_NATIVE_HOST_INSTALL is set to a falsey value (0/false/no/off). It gates only the server's boot-time auto-install: an explicit `ogcode native-host install` runs regardless, and the way to refuse manifests for good is `native-host uninstall`.

func EnsureRegistered

func EnsureRegistered(projectDir string) error

EnsureRegistered is the server's boot-time install: when this project entitles any extension id, keep every installed browser's manifest pointing at this ogcode executable, so a fresh extension install pairs itself without a manual paste. Idempotent — repeated boots rewrite the same bytes — and a no-op when there is nothing to allowlist. OGCODE_NATIVE_HOST_INSTALL falsey turns the whole thing off for a deployment that wants the manifests untouched.

func ExtensionIDForPath

func ExtensionIDForPath(path string) string

ExtensionIDForPath computes the extension id Chrome assigns to an unpacked extension loaded from path: SHA-256 over the absolute path's UTF-8 bytes, the first 16 digest bytes, each rendered in the a–p alphabet (high nibble, then low) as one 32-character id. It mirrors Chromium's GenerateIdForPath, which hashes the path AS SPELLED — verified against Chrome 156.0.8078.48 on macOS 15.5, which recorded the sha256 of the mixed-case path verbatim. The lowercased spelling this file hashed until 2026-10-25 produced an id Chrome never assigned, so the boot-written manifest allowlisted an origin no installed extension could launch the host from.

func ManifestPaths

func ManifestPaths() []string

ManifestPaths lists the manifest file paths registration would write right now — the supported browsers whose profile folder exists — so the CLI can report exactly what an install touches (and an uninstall clean up).

func Register

func Register(executablePath string, extensionIDs []string) error

Register writes the native-messaging manifest naming executablePath into every supported browser's NativeMessagingHosts directory whose browser profile folder exists — a browser the machine has never run installs nothing. It is idempotent: the same inputs rewrite the same file. Existing manifests of this host are overwritten; another host's file is left alone.

func Run

func Run(in io.Reader, out io.Writer) error

Run serves the native-messaging protocol over in/out with the production prober: every recorded port is probed over loopback HTTP at pair time.

func Uninstall

func Uninstall() error

Uninstall removes every manifest this host wrote, wherever it found one. It is idempotent — running it with nothing installed succeeds.

func UnpackedIDFor

func UnpackedIDFor(projectDir string) (string, bool)

UnpackedIDFor returns the id Chrome would assign to projectDir's unpacked companion, and whether such an extension (a manifest.json) is present there at all — the two facts the CLI's install hint names.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL