Skip to main content
Yanked

This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Reason given by maintainers: Pre-public development package; replaced by sn-module-gen

Supernote Module Generator

Supernote Module Generator adds typed C/C++ and Kotlin/Java capabilities to an existing Supernote plugin. It generates the JSI, JNI, Kotlin Symbol Processing, TypeScript, build, and lifecycle code that connects those implementations to JavaScript.

V2 models one user-facing feature, regardless of where its implementation lives. One feature may contain C++, C helper files, Kotlin, and Java together. JSI is the only JavaScript frontend, and the plugin compiles one generated V2 runtime/build component shared by all features.

V2 is the current stable architecture. Version 2.0.2 keeps ordinary static feature imports runtime-safe and improves transactional recovery, concurrent CLI operation handling, source/metadata diagnostics, and Kotlin/Java failure messages. Actual feature calls still require the plugin runtime to be ready. The initial V2 release series deliberately keeps advanced value/object features and caller-controlled cancellation out of scope; the supported foundation is described below.

Install

Python 3.9 or newer is required:

python3 -m pip install supernote-module-generator

The public identities remain:

Python distribution: supernote-module-generator
CLI command:         supernote-module

Run the CLI from an existing Supernote plugin root.

Add a feature

Choose which starter source families to scaffold:

supernote-module add document --starter cpp --yes
supernote-module add document --starter kotlin --yes
supernote-module add document --starter cpp --starter kotlin --yes

The guided command presents the same choices as C/C++ (native) and Kotlin/Java (JVM). This choice creates initial example files only. It does not make the feature a native or JVM feature, and either source family can be added later without conversion or metadata changes.

The native root compiles C23 and C++23 implementation source. Initial first-class marked declarations are C++23 only; C23 code remains fully supported behind normal C-compatible interfaces and a canonical marked C++ boundary.

Useful lifecycle commands are:

supernote-module update document --yes
supernote-module validate document
supernote-module validate --all --build
supernote-module doctor
supernote-module remove document --yes

Removal preserves plugin build output by default. To remove the three known generated build directories as part of an explicit removal:

supernote-module remove document --delete-build-files --yes

That option targets only build/, android/build/, and android/app/build/. --yes by itself never enables build-output deletion or widens a single-feature target to all features.

Explicit source intent

Normal public source is ignored by the generator. A declaration participates only when it has a deliberate Supernote marker.

For C++ the initial marker form is an exact source comment:

// @SupernotePluginExport
std::int32_t pageCount();

// @SupernotePluginInternal
void rebuildIndex();

// @SupernotePluginExport
// @SupernotePluginAsync
std::vector<std::byte> loadPage(std::int32_t page);

void ordinaryHelper(); // ignored

For Kotlin and Java, use the generated annotations with the same names:

@SupernotePluginExport
fun pageCount(): Int = 42

@SupernotePluginInternal
fun rebuildIndex() = Unit

@SupernotePluginExport
@SupernotePluginAsync
suspend fun loadPage(page: Int): ByteArray = TODO()

SupernotePluginInternal generates typed cross-language routing without adding the declaration to JavaScript or TypeScript. SupernotePluginAsync is always explicit; Kotlin suspend, C++ future-like types, or blocking implementation code never silently change the public API.

An exported class publishes the object type. Its single eligible public constructor becomes the normal create(...) factory, while every other method still needs its own marker:

// @SupernotePluginExport
class Document {
public:
  explicit Document(std::string path);

  // @SupernotePluginExport
  std::int32_t pageCount() const;

  void resetInternalCache(); // ignored
};

Initial V2 also supports the same narrow per-JavaScript-object model for deliberately marked Kotlin/Java classes. Object parameters/results, returned-only objects, inheritance, properties, custom factories, and general object graphs are deferred.

Initial value types

The initial semantic types and JavaScript/TypeScript mappings are:

Supernote value JavaScript/TypeScript
void void
bool boolean
int32 number
int64 bigint
float32, float64 number
string string
bytes Uint8Array

Strings use UTF-8 when crossing native/JNI boundaries. Byte values use copy-based snapshot semantics and pass only the visible Uint8Array view. Nullability, generic collections, maps, value structs, enums, unsigned values, and zero-copy buffers are not part of the initial foundation.

Async, errors, and lifetime

An accepted async call immediately returns a normal Promise<T>. Ordinary blocking implementations use the plugin's shared bounded worker executor; supported Kotlin suspend implementations use the generated coroutine adapter. Both routes share the same cancellation, teardown, error, and completion rules.

Argument count/type/integer/range misuse throws TypeError or RangeError before an operation is accepted. Later failures reject with the exported SupernoteError, whose stable string code includes RESOURCE_EXHAUSTED, CANCELLED, FEATURE_CLOSED, IMPLEMENTATION_ERROR, and INTERNAL.

Accepted async object methods retain their implementation receiver until physical work can no longer access it. Generated code prevents use-after-free but does not add a mutex or serial queue around user object state; plugin implementations remain responsible for their own thread safety.

Final generated C++ receiver/resource destruction is deferred to a managed non-JS context. There is no promise of a particular cleanup thread, exact timing, or JSI access. Resources requiring a specific thread must be managed by the plugin implementation. JNI global references are released safely by the generated runtime, while later JVM object collection remains controlled by the JVM.

Validation boundary

supernote-module validate checks generated structure by default; --build also invokes the Android build. A successful local build proves generation and compilation for that environment, not that a particular Supernote firmware, PluginHost, linker namespace, or SELinux policy will load and execute the code. Target-device behavior must be validated on the intended device.

The generator does not create the surrounding Supernote plugin. Plugin creation, installation, and device debugging are covered by the official Supernote plugin documentation.

Contributing

See CONTRIBUTING.md for development and validation rules and V1 to V2 architecture for contributor-facing architectural history. That history is not a project migration guide or a compatibility promise.

License

MIT. See LICENSE.

Release files for supernote-module-generator 2.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for supernote-module-generator 2.0.2
File Size Uploaded
supernote_module_generator-2.0.2.tar.gz 257.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for supernote-module-generator 2.0.2
File Interpreter ABI Platform
supernote_module_generator-2.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 479.5 kB

Release files / supernote_module_generator-2.0.2.tar.gz

Download URL supernote_module_generator-2.0.2.tar.gz
Size 257.7 kB
Tags Source
SHA-256 checksum
How to use checksums
f88c311e1758e61728527d8474c9659dcbff309399dc60cf9ffbfc5ab6ccb6b9
BLAKE2b-256 checksum
How to use checksums
e91ce1a7e33449336df17fc0f63a701d9585c169dfb0b2e0eeab4f883f3f4a66
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 15, 2026.

Transparency log

Release files / supernote_module_generator-2.0.2-py3-none-any.whl

Download URL supernote_module_generator-2.0.2-py3-none-any.whl
Size 221.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c8936e77cc12dc784c0ce8fade5e38d1031ede58a83f69abcd366af130ccd125
BLAKE2b-256 checksum
How to use checksums
818ba72e4e5d0f31fe75bab83ad70aecd07d9a8a5049695536534bf7a0dfffe1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 15, 2026.

Transparency log

Release history Release notifications | RSS feed

3.0.3

2 release files

3.0.2

2 release files

3.0.1

2 release files

3.0.0

2 release files

2.0.4

2 release files

2.0.3

2 release files

This release

2.0.2 This release

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page