中文版本: README.zh-CN.md
First-party extension repository for Navop.
This repository builds and publishes official extension packages independently
from the main Navop application. The host app owns the extension runtime,
marketplace client, update client, and SDK/runtime contracts. This repository
owns concrete official extensions, release artifacts, the repository-maintained
marketplace manifest, and Cloudflare R2 upload automation.
extensions/
ipc/
duckdb/ Rust DuckDB IPC database driver
redis/ Rust Redis native IPC sidecar driver
mongodb-modern/ Rust MongoDB 4.2+ native IPC sidecar manifest
mongodb-legacy/ Rust MongoDB 3.6 native IPC sidecar manifest
mongodb-legacy-3-2/ Rust MongoDB 3.2–3.4 EOL native IPC sidecar manifest
iotdb/ Go Apache IoTDB IPC database driver
dm/ Go Dameng DM IPC database driver
kingbase/ Go KingbaseES IPC database driver
gbase8s/ Java GBase 8s IPC database driver
oceanbase/ Go OceanBase IPC database driver
opengauss/ Rust openGauss IPC database driver
oracle-go/ Go Oracle IPC database driver (pure Go, godror)
remote-desktop/
rdp/ Rust RDP remote desktop provider
rdp-helper/ Rust RDP helper binary (Cargo workspace)
vnc/ Rust VNC remote desktop provider
vnc-helper/ Rust VNC helper binary (Cargo workspace)
cmd/
dm-ipc-driver/
iotdb-ipc-driver/
kingbase-ipc-driver/
oceanbase-ipc-driver/
oracle-go-ipc-driver/
java/
gbase8s-ipc-driver/
internal/
dbipc/ shared Go IPC database server runtime
drivers/ driver-specific Go implementations (dm, iotdb, kingbase, oceanbase, oracle)
ipc/ Go IPC framing and socket utilities
runner/ Go IPC process runner
manifest.json lightweight marketplace index
scripts/
build-go-driver.sh
build-java-driver.sh
changed-extensions.mjs
generate-marketplace-manifest.mjs
install-local-drivers.sh
install-local-remote-desktop-providers.sh
install-local-composite-extensions.sh
package-driver.sh
package-remote-desktop-provider.sh
release-driver.mjs
verify-package.sh
verify-remote-desktop-provider-package.sh
tests/
scripts.test.mjs
docs/
superpowers/plans/ implementation plans used by agentic development workflows
.codex/
skills/ipc-driver-development/
The duplicated root-level ipc-driver-development/ skill directory is not used.
Keep driver-development guidance under
.codex/skills/ipc-driver-development/.
Implementation plans under docs/superpowers/plans/ capture approved,
task-oriented work plans for extension changes. Treat them as development
records: they may describe local findings, verification steps, and follow-up
implementation tasks, but they are not extension runtime inputs.
| Driver | Runtime | Package metadata | Manifest | Notes |
|---|---|---|---|---|
| DuckDB | Rust | extensions/ipc/duckdb/extension.build.json |
extensions/ipc/duckdb/driver.json |
Embedded single-file analytical database driver. Cargo workspace member. |
| Apache IoTDB | Go | extensions/ipc/iotdb/extension.build.json |
extensions/ipc/iotdb/driver.json |
Time-series database driver. Uses cmd/iotdb-ipc-driver and internal/drivers/iotdb. |
| Dameng DM | Go | extensions/ipc/dm/extension.build.json |
extensions/ipc/dm/driver.json |
Uses shared internal/dbipc runtime and dm_driver build tag. |
| KingbaseES | Go | extensions/ipc/kingbase/extension.build.json |
extensions/ipc/kingbase/driver.json |
Uses shared internal/dbipc runtime and kingbase_driver build tag. |
| GBase 8s | Java | extensions/ipc/gbase8s/extension.build.json |
extensions/ipc/gbase8s/driver.json |
Uses java/gbase8s-ipc-driver. Preserve java/gbase8s-ipc-driver/bin/lib/gbase8s-ipc-driver.jar when present. Universal (cross-platform) target only. |
| OceanBase | Go | extensions/ipc/oceanbase/extension.build.json |
extensions/ipc/oceanbase/driver.json |
Uses shared internal/dbipc runtime and oceanbase_driver build tag. |
| openGauss | Rust | extensions/ipc/opengauss/extension.build.json |
extensions/ipc/opengauss/driver.json |
Cargo workspace member. Uses tokio-opengauss async driver. |
| Oracle Go | Go | extensions/ipc/oracle-go/extension.build.json |
extensions/ipc/oracle-go/driver.json |
Pure Go Oracle driver using oracle_go_driver build tag. |
| Redis | Rust | extensions/ipc/redis/extension.build.json |
extensions/ipc/redis/driver.json |
Native API sidecar with binary-safe command/pipeline, blob, and bounded Pub/Sub support. |
| MongoDB Modern | Rust | extensions/ipc/mongodb-modern/extension.build.json |
extensions/ipc/mongodb-modern/driver.json |
Shares the IPC implementation package with the legacy variant, uses MongoDB Rust Driver 3.8, and targets MongoDB 4.2+. |
| MongoDB Legacy | Rust | extensions/ipc/mongodb-legacy/extension.build.json |
extensions/ipc/mongodb-legacy/driver.json |
Shares the IPC implementation package with the modern variant, uses MongoDB Rust Driver 2.8, and targets MongoDB 3.6. |
| MongoDB Legacy 3.2 | Rust | extensions/ipc/mongodb-legacy-3-2/extension.build.json |
extensions/ipc/mongodb-legacy-3-2/driver.json |
Uses the MongoDB Rust Driver 0.3 wire implementation for EOL MongoDB 3.2–3.4 servers; SRV and TLS are intentionally unsupported. |
Domestic database drivers declare "category": "domestic_database" in
driver.json; the host should use manifest metadata instead of hardcoded ids
for UI grouping.
| Provider | Runtime | Package metadata | Manifest | Notes |
|---|---|---|---|---|
| RDP | Rust | extensions/remote-desktop/rdp/extension.build.json |
extensions/remote-desktop/rdp/remote_desktop_provider.json |
RDP remote desktop provider. Binary built from extensions/remote-desktop/rdp-helper. |
| VNC | Rust | extensions/remote-desktop/vnc/extension.build.json |
extensions/remote-desktop/vnc/remote_desktop_provider.json |
VNC remote desktop provider. Binary built from extensions/remote-desktop/vnc-helper. |
Each driver declares its callable methods in driver.json.methods and should
return the same method list from init. Treat this list as a runtime contract:
if a method is declared, the binary must route it or intentionally return a
typed unsupported error.
The current IPC drivers expose schema metadata through the legacy fixed methods such as:
schema/databasesschema/schemasschema/objectsschema/columnsschema/indexesschema/viewsschema/functions
Drivers that customize object-list table headers also declare
schema/object_view. That method is connection-bound and returns the complete
render table shape:
{
"title": "Columns",
"columns": [
{ "key": "name", "name": "Field", "width_px": 220 },
{ "key": "type", "name": "Type", "width_px": 160 },
{ "key": "nullable", "name": "Null?", "width_px": 72, "align": "right" }
],
"rows": [
["id", "INTEGER", "false"],
["payload", "JSON", "true"]
]
}If schema/object_view is absent or returns typed not-supported or
method-not-found for a view, the host falls back to the legacy schema methods.
Keep the first column as the object name when rows represent clickable database
objects.
Rust drivers depend on these SDK crates from feigeCode/navop:
extension-protocolextension-driverextension-host
At the moment, Cargo.toml points to the dev branch because the existing
v0.4.8 tag does not contain those crates. After Navop publishes a release
tag that includes the SDK crates, replace the branch dependencies with that
fixed tag.
The Cargo workspace currently includes extensions/ipc/duckdb,
extensions/ipc/opengauss, extensions/ipc/redis, and the shared
drivers/mongodb-driver crate. The RDP and VNC helpers are independent Cargo
projects under extensions/remote-desktop/rdp-helper and
extensions/remote-desktop/vnc-helper respectively.
Run script and packaging tests:
node --test tests/scripts.test.mjsRun Rust driver tests:
cargo test -p duckdb_driver -- --nocapture
cargo test -p opengauss_driver -- --nocaptureRun Go runtime tests:
GOCACHE=/private/tmp/navop-go-cache go test ./internal/dbipcRun Java driver tests:
mvn -f java/gbase8s-ipc-driver/pom.xml testCheck Rust formatting:
cargo fmt --all --checkValidate GitHub Actions YAML:
ruby -e 'require "yaml"; YAML.load_file(".github/workflows/ci.yml"); YAML.load_file(".github/workflows/release.yml"); YAML.load_file(".github/workflows/upload-r2.yml"); YAML.load_file(".github/workflows/backfill-windows-x86.yml"); YAML.load_file(".github/workflows/sync-cnb-release-assets.yml"); YAML.load_file(".github/workflows/sync-cnb-latest.yml"); puts "workflow yaml ok"'All extension packages are described by
extensions/ipc/<driver-id>/extension.build.json. The build metadata defines
the extension id, runtime language, package or binary name, target triples,
release tag prefix, and R2 prefix.
Build and package DuckDB for the local host target:
HOST_TRIPLE="$(rustc -vV | sed -n 's/^host: //p')"
cargo build --release -p duckdb_driver --target "$HOST_TRIPLE"
mkdir -p artifacts
bash scripts/package-driver.sh duckdb "$HOST_TRIPLE" artifacts 1.0.0
bash scripts/verify-package.sh "artifacts/duckdb-driver-${HOST_TRIPLE}.tar.gz"Build and package a Go driver:
HOST_TRIPLE="$(rustc -vV | sed -n 's/^host: //p')"
bash scripts/build-go-driver.sh dm "$HOST_TRIPLE"
mkdir -p artifacts
bash scripts/package-driver.sh dm "$HOST_TRIPLE" artifacts 0.1.0Build and package the Java GBase 8s driver:
HOST_TRIPLE="$(rustc -vV | sed -n 's/^host: //p')"
bash scripts/build-java-driver.sh gbase8s "$HOST_TRIPLE"
mkdir -p artifacts
bash scripts/package-driver.sh gbase8s "$HOST_TRIPLE" artifacts 0.1.0Build and package a Rust remote desktop provider:
HOST_TRIPLE="$(rustc -vV | sed -n 's/^host: //p')"
bash scripts/package-remote-desktop-provider.sh rdp "$HOST_TRIPLE" artifacts 0.1.0
bash scripts/verify-remote-desktop-provider-package.sh "artifacts/rdp-remote-desktop-provider-${HOST_TRIPLE}.tar.gz"Package archives contain the extension directory with driver.json, the entry
binary or launcher, and packaged resources such as locales, icons, and runtime
libraries.
Build, package, verify, and replace installed local drivers:
bash scripts/install-local-drivers.sh
bash scripts/install-local-drivers.sh dmBy default this installs into
$XDG_CONFIG_HOME/one-hub/extensions/database_drivers or
$HOME/.config/one-hub/extensions/database_drivers. Override the target with
NAVOP_DATABASE_DRIVER_DIR=/path/to/database_drivers. The legacy
ONETCLI_DATABASE_DRIVER_DIR variable remains supported for compatibility.
Install remote desktop providers locally:
bash scripts/install-local-remote-desktop-providers.sh
bash scripts/install-local-remote-desktop-providers.sh rdpBuild, package, verify, and install a native or universal composite extension:
bash scripts/install-local-composite-extensions.sh elasticsearchNative composites publish one archive per target. Their root extension.json
may combine runtime.ipc with contributes.shellViews; packages contain the
platform provider under bin/ and gpui-shell sources under ui/.
By default this follows Navop's config-directory migration state. On Unix it
uses $HOME/.config; on Windows it uses %APPDATA%. Within that config root it
installs below
navop/extensions/remote_desktop_providers, while continuing to use the legacy
one-hub directory if it still exists and Navop has not written the
.one-hub-migration-complete marker. Override the target with
NAVOP_REMOTE_DESKTOP_PROVIDER_DIR=/path/to/remote_desktop_providers; the legacy
ONETCLI_REMOTE_DESKTOP_PROVIDER_DIR variable remains supported.
Prepare release artifacts for one driver locally:
node scripts/release-driver.mjs duckdb 1.0.0
node scripts/release-driver.mjs dm 0.4.0 --target x86_64-unknown-linux-gnu
node scripts/release-driver.mjs gbase8s 0.7.0 --artifact-dir artifacts/gbase8s-0.7.0The release script reads extensions/ipc/<driver-id>/extension.build.json,
builds each selected target with the runtime-specific build command, packages
and verifies each archive, then writes:
artifacts/<driver-id>-driver-<target>.tar.gzartifacts/sha256sums.txtartifacts/extension-manifest.jsonartifacts/release-metadata.json
Use --skip-build when binaries have already been staged under
target/<target>/release.
The repository root manifest.json is the global marketplace index. It is
maintained and committed directly in this repository, then uploaded unchanged to
R2 as extensions/manifest.json.
Release jobs generate one plugin manifest:
artifacts/extension-manifest.json: the current extension manifest published to that extension's GitHub Release. It contains target artifact file names and checksums.
The plugin manifest is generated from:
- package filenames
artifacts/sha256sums.txt- release environment variables
Required environment variables:
ARTIFACT_DIR=artifacts
EXTENSION_VERSION=1.0.0
EXTENSION_ID=duckdb
RELEASE_TAG=duckdb-v1.0.0
The extension-scoped GitHub Release keeps extension-manifest.json as the
current extension's plugin manifest. After the Release workflow succeeds, the
upload workflow serializes marketplace publication, uploads that plugin manifest
to R2 at extensions/<id>/manifest.json, and uploads the committed root
manifest.json to R2 at extensions/manifest.json with no-cache.
The global marketplace entry is schema v2 and contains metadata plus a manifest path, not artifact files or download URLs:
{
"id": "duckdb",
"kind": "database_driver",
"name": "DuckDB",
"version": "1.0.0",
"release_tag": "duckdb-v1.0.0",
"description": "DuckDB embedded analytical database IPC driver",
"file_extensions": [],
"manifest": "duckdb/manifest.json"
}The plugin manifest is also schema v2 and contains artifact file names plus checksums, not full download URLs:
{
"schema_version": 2,
"release_version": "duckdb-v1.0.0",
"extensions": [{
"id": "duckdb",
"kind": "database_driver",
"name": "DuckDB",
"version": "1.0.0",
"release_tag": "duckdb-v1.0.0",
"artifacts": {
"x86_64-unknown-linux-gnu": {
"file": "duckdb-driver-x86_64-unknown-linux-gnu.tar.gz",
"sha256": "<sha256>"
}
}
}]
}The Navop client owns download source policy. It first loads the global
marketplace index, then loads the selected extension's plugin manifest. For R2,
package URLs are resolved from the plugin manifest directory using
<version>/<file>. If the R2 plugin manifest or package is unavailable, the
client derives GitHub Release fallback URLs from its configured GitHub manifest
base, the entry's release_tag, and the plugin manifest or artifact file name.
.github/workflows/ci.yml detects changed extensions and builds only affected
release units.
Current selection rules:
- Changes under
extensions/ipc/<driver-id>/**build that driver. - Changes under shared runtime, scripts, workflow, or packaging paths build all known extensions.
- Each target triple is one matrix entry.
Extension releases are extension-scoped:
git tag duckdb-v1.0.0
git push origin duckdb-v1.0.0The Release workflow:
- Resolves the extension id and version from the tag.
- Builds every target listed in
extension.build.json. - Packages and verifies each archive.
- Generates checksums.
- Generates the current extension plugin manifest.
- Publishes a GitHub Release with packages, checksums, and the current
extension
extension-manifest.json.
Manual release is also available through workflow_dispatch with:
extension, for exampleduckdbversion, for example1.0.0
.github/workflows/upload-r2.yml runs after a successful Release workflow or
can be triggered manually with a release tag.
Repository secrets:
CLOUDFLARE_ACCOUNT_ID
CLOUDFLARE_R2_ACCESS_KEY_ID
CLOUDFLARE_R2_SECRET_ACCESS_KEY
CLOUDFLARE_R2_BUCKET
The upload workflow is serialized with the extension-marketplace-publish
concurrency group. For DuckDB 1.0.0, R2 receives:
extensions/duckdb/1.0.0/<package>.tar.gz
extensions/duckdb/manifest.json
extensions/manifest.json
Versioned packages are uploaded with immutable caching. Plugin manifests and the
global marketplace index are uploaded with no-cache. The global manifest is
the repository-maintained root manifest.json, uploaded unchanged to
extensions/manifest.json.
.github/workflows/sync-cnb-release-assets.yml mirrors a release's Git tags and
assets to the CNB mirror navop-dev/navop-extensions. The Release workflow
dispatches it for every new release, and .github/workflows/sync-cnb-latest.yml
reconciles the latest stable release of every extension on a daily schedule
(plus workflow_dispatch) so the Navop website can serve extension downloads
from CNB:
https://cnb.cool/navop-dev/navop-extensions/-/releases/download/<release-tag>/<asset>
The latest-version workflow:
- Runs
scripts/discover-latest-extension-releases.mjs, which reads everyextension.build.jsonreleaseTagPrefixand resolves the newest stable GitHub release per extension into a build matrix. - Calls
sync-cnb-release-assets.ymlonce per extension withtag: <extension>-v<version>andsecrets: inherit.
CNB synchronization requires the CNB_TOKEN repository secret.
Add a new directory under extensions/ipc/<driver-id> with:
driver.json
extension.build.json
locales/
icons/
Runtime-specific code lives in the appropriate local package:
- Rust drivers usually live under
extensions/ipc/<driver-id>/srcand are root Cargo workspace members. - Go drivers can reuse
internal/dbipcand add a command undercmd/. - Java drivers can use a package under
java/.
Create metadata similar to:
{
"id": "postgres",
"kind": "database_driver",
"language": "go",
"package": "./cmd/postgres-ipc-driver",
"binary": "postgres-ipc-driver",
"path": "extensions/ipc/postgres",
"targets": [
"aarch64-apple-darwin",
"x86_64-apple-darwin",
"x86_64-unknown-linux-gnu",
"aarch64-unknown-linux-gnu",
"x86_64-pc-windows-msvc",
"i686-pc-windows-msvc"
],
"releaseTagPrefix": "postgres-v",
"r2Prefix": "extensions/postgres"
}No workflow changes should be needed for another IPC database driver if it uses the existing metadata and package shape.
Add a new directory under extensions/remote-desktop/<provider-id> with:
remote_desktop_provider.json
extension.build.json
The helper binary is a Rust Cargo project under
extensions/remote-desktop/<provider-id>-helper. The extension.build.json
references the helper's Cargo.toml via manifest_path and lists the helper
source directory in source_paths so that CI change detection works correctly.
The main Navop repository should consume the published global marketplace
manifest from R2 first. Each global entry points to an extension plugin manifest
such as duckdb/manifest.json; the host loads that file before selecting a
platform artifact. GitHub fallback is extension-scoped: the host derives
https://github.com/feigeCode/navop-extensions/releases/download/<release_tag>/extension-manifest.json
for the plugin manifest, then derives package fallback URLs from the same
release tag and artifact file name.
Do not make the main application release depend on this repository's extension builds. The main app owns runtime consumption; this repository owns extension production and publication.