nitrogen_cli 0.5.4
nitrogen_cli: ^0.5.4 copied to clipboard
CLI for Nitrogen Modules. Scaffold new Flutter FFI plugins and generate native bridge code.
0.5.4 #
- Fixed: Multi-spec C++ plugin —
NitroOptInt64typedef conflict in generated C++ bridge headers —cpp_record_generator.dartnow excludes the built-in library record types (NitroOptInt64,NitroOptFloat64,NitroOptBool,NitroNullableInt,NitroNullableDouble,NitrNullableBool) from C++ forward declarations and struct definitions. These types are already defined as anonymous C typedefs in the generatedbridge.g.h; emitting a namedstruct NitroOptInt64;in the same compilation unit caused a hard compiler error (definition of type 'NitroOptInt64' conflicts with typedef of the same name). - Fixed: Multi-spec Swift plugin —
NitroRecordWriternot found in scope forNativeImpl.cppbridges —swift_record_generator.dartnow skips library record type struct definitions whenemitBoilerplate: false(theNativeImpl.cppbridge path). Previously,NitroNullableIntand friends were emitted in the cpp bridge file even without the preamble, causing'NitroNullableInt' is ambiguous for type lookuperrors when multiple bridge files compiled into the same Swift module. - Fixed: Multi-spec macOS — Static initialization order fiasco (SIOF) crash on startup —
cpp_direct_emitter.dartnow generates Meyers' Singleton wrapper functions (_g_instances(),_g_instances_mtx(),_g_next_instance_id(),_g_factory()) for all C++ registry globals. The previous static global variables could be accessed by__attribute__((constructor))callbacks before the globals were initialized, manifesting as astd::__next_primeoverflow/abort on macOS. - Fixed: Multi-spec SPM — C++ bridge files copied before preamble-defining Swift bridge —
_syncSwiftBridgesToSpmSourcesinlink_command.dartnow sorts bridge files so that those containingpublic protocol NitroEncodable(the shared preamble) are placed first. The first file is copied verbatim; subsequent files have the preamble stripped. This ensuresNitroRecordWriterand related types are always defined before they are referenced in the same Swift module. - Tests: 55 new per-spec integration tests in
integration_test.dartverifying generator output for all three native-spec combinations:testing_project(Swift/Kotlin),testing_cpp(NativeImpl.cpp all platforms), andtesting_mixed(Swift iOS / Kotlin Android / C++ macOS). Covers Dart binding symbols, C bridge signatures, Swift protocol declarations, Kotlin interface signatures,native.g.habstract class,impl.g.cppeditable starter, and SPM file placement. - Integration: 25/25 device integration tests pass on macOS across all 3 specs —
add,getGreeting,multiply,pi,isEven,tryDivide(nullable int return),platform,optionalFlag(nullable bool),optionalValue(nullable double).
0.5.3 #
- Fixed: Multi-spec plugin —
symbol not found: nitro_<spec>_init_dart_api_dlcrash (root cause) — The stale-forwarder cleanup loop in_syncCppModuleSourcesToSpmwas deleting${lib}.bridge.g.mmfor every module whereisAppleCpp=false, including modules that useios: NativeImpl.swiftalongsidewindows: WindowsNativeImpl.cpp. Because the bridge mm is required for ALL modules on Apple to compile${lib}_init_dart_api_dlinto the SPM binary (even for Swift-backed modules), this deletion caused a runtime symbol-not-found crash. The stale cleanup now only removes theHybridXxx.cppimpl forwarder, never the bridge forwarder. - Tests: 4 new regression tests in
link_command_test.dartverifying that (1)bridge.g.mmis created for a Swift-on-iOS/C++-on-Windows module, (2) it is not deleted by the stale cleanup, (3) theHybridXxx.cppimpl forwarder is correctly removed for Swift-on-Apple modules, and (4) all three bridge mm forwarders are present for a full 3-spec plugin (the nitro_view scenario). - Integration tests: 35 tests added to
nitro_view/example/integration_test/multi_spec_bridge_test.dartexercising real FFI calls across all 3 specs (NitroSystem,NitroUI,NitroView) on iOS, Android, and macOS. Includes a cross-spec group as a definitive regression guard for the symbol-not-found crash. AddedACCESS_NETWORK_STATEandVIBRATEpermissions to the Android example manifest.
0.5.2 #
- Fixed: Multi-spec Swift plugin —
invalid redeclarationpersists after everynitrogen generate/nitrogen link—_copySwiftBridgesToClassesand_syncSwiftBridgesToSpmSourcesin the link step always copied bridge files without preamble-stripping, overwriting any correctly-stripped copies. The fix moves preamble-stripping into these two functions (sorted alphabetically; first file keeps the full preamble, subsequent files have it removed) and relocatesstripSharedSwiftPreambletoutils.dartso it is shared by both the generate and link code paths. Standalonenitrogen linknow also produces correctly-stripped bridge files. - Fixed: Multi-spec plugin —
symbol not found: nitro_<spec>_init_dart_api_dlcrash when 2nd/3rd spec uses Swift on iOS/macOS but C++ on Windows/Linux —_syncCppModuleSourcesToSpmcreated per-module${lib}.bridge.g.mmSPM forwarders only for modules whereisCpp=true AND isAppleCpp=true. Modules withios: NativeImpl.swift, windows: WindowsNativeImpl.cpphadisCpp=true(triggering the stale-cleanup loop) butisAppleCpp=false(triggering deletion of the bridge mm). The bridge mm is required for ALL modules on Apple to compile${lib}_init_dart_api_dlinto the SPM binary; the stale cleanup now only removes the impl forwarder (HybridXxx.cpp), never the bridge forwarder (${lib}.bridge.g.mm).
0.5.1 #
- Fixed: Multi-spec Swift plugin — runtime
symbol not foundcrash —_syncCppModuleSourcesToSpmnow creates a${lib}.bridge.g.mmforwarder in the SPM<PluginName>Cpptarget for every non-plugin Swift module. Previously only C++ modules got per-module wrappers; theallCppModules.isEmptyguard skipped all per-module work for pure-Swift plugins, so 2nd and 3rd specs (e.g.nitro_ui,nitro_system) were never compiled into the binary. Result:dlsym('nitro_ui_init_dart_api_dl'): symbol not foundcrash on first use. Applies to both iOS and macOS SPM targets. - Fixed: Multi-spec Swift plugin —
invalid redeclarationcompile error —_syncSwiftBridgesToClassesnow strips the shared public-type preamble (NitroEncodable,NitroNullableInt,NitroRecordWriter, etc.) from the 2nd and subsequent bridge.swiftfiles before writing them toios/Classes/,macos/Classes/, and SPMSources/<ClassName>/directories. All bridge files compile into the same Swift module; duplicatepublicdeclarations cause a Swift compilerinvalid redeclarationerror. The first file (alphabetically) retains the full preamble; later files keep only their file-private string helpers and spec-specific protocol/registry/stubs. - New:
stripSharedSwiftPreamble(String content)— Exported top-level function implementing the preamble-stripping logic, enabling direct unit testing without filesystem scaffolding.
0.5.0 #
- Ecosystem sync — Aligned with
nitro,nitro_annotations, andnitro_generator0.5.0.
0.4.6 #
- Ecosystem sync — Aligned with
nitro,nitro_annotations, andnitro_generator0.4.6.
0.4.5 #
- Ecosystem sync — Aligned with
nitro,nitro_annotations, andnitro_generator0.4.5.
0.4.4 #
- Ecosystem sync — Aligned with
nitro,nitro_annotations, andnitro_generator0.4.4.
0.4.3 #
- New:
nitrogen generate --no-ui— Headless plain-text output mode with no ANSI colours, auto-enabled when stdout is not a TTY (great for CI pipelines and scripts). - New:
nitrogen generate --fail-on-warn— Exits with code 2 ifbuild_runneremits any[WARNING]lines, so CI catches generation warnings as failures. - New:
nitrogen generate --verbose/-v— Prints a per-phase timing breakdown (e.g. "resolve: 120ms, codegen: 340ms") at the end of generation. - New:
nitrogen cleancommand — Deletes all Nitrogen-generated files (*.g.dart,*.bridge.g.*,*.native.g.h, etc.) and thebuild_runnercache in one command. - New:
--no-uiheadless mode for all commands — Every command (init,generate,clean,link,doctor,migrate,update,watch,open) now supports--no-ui. Output is plain text prefixed with[nitro],[nitro:warn], or[nitro:error]; auto-enabled when stdout is not a TTY. - TUI: Animated NITRO logo — The dashboard now displays a large block-art "NITRO" logo with rocket animation at the top of the main content area, pulsing between cyan and magenta in sync with the header.
- TUI: Improved credits — Credits updated to "Inspired by Nitro — @mrousavy" with clickable links; added a row for Shreeman Arjun with X and GitHub links.
- CLI: Nitro credit in
--versionand--help—nitrogen --versionnow prints the Nitro inspiration line;nitrogen --helpdescription includes the @mrousavy attribution. - Fixed: Doctor false positives on
FlutterFramework/Package.swift—detectSpmStatuswas picking upios/FlutterFramework/Package.swift(the Flutter SDK's SPM manifest, symlinked by CocoaPods) before the plugin's ownios/<name>/Package.swift. The scanner now skips directories whose name is not a valid Dart package identifier (lowercase snake_case), eliminating false-positive SPM errors on real-world plugins. - Fixed: SPM
Package.swiftmissing FlutterFramework dependency —nitrogen linknow patches older pluginPackage.swiftfiles to add theFlutterFrameworktarget dependency if it is missing, preventing SPM build failures after upgrading Flutter. - Fixed: ANSI escape codes in headless
build_runneroutput —runStreamingInspectedstrips ANSI sequences from subprocess output when running in--no-uimode, so log files stay clean.
0.4.2 #
- Fixed: Apple C++ forwarder incorrectly deleted —
link_command.dartnow uses a safe default: forwarders are kept when no spec file exists for a library. Previously any lib not inplatformCppLibswas deleted, removing valid Apple forwarders from plugins without a local spec. - Fixed: Pure-Swift plugin files not copied to SPM target —
_syncSwiftPluginToSpmis now called for plugins with no C/C++ content before the earlycontinue, ensuring Swift plugin files reachSources/<className>/when building with SPM. - Fixed: SPM sync crash for macOS-only plugins —
_syncSwiftPluginToSpmnow returns early when the target directory doesn't exist, preventing aPathNotFoundExceptionfor platforms that have no SPM layout. - Fixed: Scaffold generated double "Plugin" suffix —
scaffold_templates.dartwas generatingSwift${pascal}Plugin.swift; corrected toSwift${pascal}.swiftto match the expected filename. - Ecosystem sync — Aligned with
nitro,nitro_annotations, andnitro_generator0.4.2.
0.4.1 #
- Fixed: SPM Package.swift invalid header search paths — Removed external paths (
../../lib/src/generated/cpp,../../.symlinks/plugins/nitro/src/native) from SPM Swift target configuration. The Swift target accesses types through its${className}Cppdependency viapublicHeadersPath: "include". - Fixed: Swift plugin not found under SPM — Added
_syncSwiftPluginToSpm()which copies*Plugin.swiftand*Impl.swiftfromClasses/toSources/<className>/, ensuringGeneratedPluginRegistrant.mcan find the Swift plugin class when building with SPM. - Fixed: Mixed Apple platform linking —
nitrogen linknow correctly handles modules with different implementations per Apple platform (e.g.ios: NativeImpl.swift+macos: NativeImpl.cpp). iOS and macOSPlugin.swiftregistration andHybridXxx.cppforwarders are managed independently per platform. - Fixed: Portable
dart_api_dlheader —dart_api_dl.his now written from the resolved pub-cache path rather than a relative.symlinkspath, making it stable across both CocoaPods and SPM build trees and on CI machines. - Fixed: Release-mode
nitro.hexport macros —createSharedHeadersandnitrogen doctornow validate thatNITRO_EXPORTis present innitro.h, fixing linker errors in archive/release builds. - Fixed: Android multi-module stabilization —
nitrogen initandnitrogen linkCMake templates no longer produce duplicate library targets in multi-module projects;build.gradlesource-set configuration avoids AGP 8.x routing issues. - Refactored: Template extraction — All inline string templates moved from command files into
lib/templates/(forwarder_templates.dart,podspec_templates.dart,cpp_stubs.dart,swift_templates.dart,cmake_templates.dart,native_headers.dart,scaffold_templates.dart). Command files now contain only logic. - Fixed: Lint warnings in generated and test code — Removed underscore-prefixed local identifiers (
_scaffoldSpm,_scaffoldMacosSpm) and unused variables from test files;no_leading_underscores_for_local_identifierswarnings eliminated.
0.4.0 #
- New: Mixed Apple platform support —
nitrogen linknow correctly handles modules with different implementation languages per Apple platform (e.g.ios: NativeImpl.swift+macos: NativeImpl.cpp). iOSPlugin.swiftregistration and macOSPlugin.swiftregistration are managed independently, andHybridXxx.cppforwarders are only written for the platform that actually uses C++. - SPM and CocoaPods — Both build systems are fully supported. SPM targets (
Sources/<PluginCpp>/) and CocoaPods targets (ios/Classes/,macos/Classes/) are wired automatically bynitrogen link.nitrogen doctorvalidates both layouts. - Fixed:
bridge.g.mmalways written —bridge.g.mmis now written unconditionally (relative#includepath), so plugins build correctly even whennitrogen linkis run beforenitrogen generate. - Fixed:
nitrogen linkno longer deletes the main plugin bridge when the module lib name matches the plugin name. - Fixed:
nitrogen generate/nitrogen watchno longer hang whenbuild_runneris already running.
0.3.4 #
- Fixed:
createSharedHeadersnow populates SPM Cpp target include dirs — Previously,createSharedHeadersonly wrotenitro.hand Dart API headers tosrc/,ios/Classes/, andmacos/Classes/. Plugins using the nested Flutter 3.41+ SPM layout ({platform}/<plugin>/Sources/<ClassName>Cpp/include/) were left without those headers untillinkPodspecran.createSharedHeadersnow scans for any existing*Cpp/include/directories underios/<plugin>/Sources/andmacos/<plugin>/Sources/and writesnitro.hplus copies alldart_api*.hheaders into them.
0.3.3 #
- Fixed:
linkPodspecoperation order causing re-added stale Swift bridges —_cleanStaleSwiftBridgeswas called beforesyncBridgeFiles, so any stale.bridge.g.swiftcopies deleted fromios/Classes/were immediately re-added by the subsequentsyncBridgeFilescall. The order is nowsyncBridgeFilesfirst, then_cleanStaleSwiftBridges, ensuring stale copies are permanently removed. - Fixed:
syncBridgeFilesmissing stale Swift bridge deletion for C++ modules — Previously,syncBridgeFilesskipped Swift bridges forNativeImpl.cpp/AppleNativeImpl.cppmodules but never deleted any stale copies that already existed inClasses/orSources/<ClassName>/. It now explicitly deletes those stale files, preventing "Invalid redeclaration" compile errors in projects upgrading from earlier layouts. - Fixed:
syncBridgeFilesSPM layout support — The function previously returned early whenios/Classes/was missing, so theios/Sources/<ClassName>/target (used by SPM-enabled plugins) never received Swift bridge copies. It now checks both layouts independently and copies to whichever target directories exist. - Fixed:
_syncCppModuleSourcesToSpmspurious files when no C++ modules present — WhenmoduleInfoscontained noisCppmodules, the function still wrotedart_api_dl.cand the main plugin forwarder intoios/Sources/<PluginCpp>/because the guard was placed after those writes. It now returns early ifallCppModulesis empty, leaving the SPM directory untouched. - Improved: Test coverage — All 339 tests pass. Added and corrected assertions in
utils_test.dartandlink_command_test.dartcovering: stale Swift bridge deletion for C++ modules in bothios/Classes/andmacos/Classes/, SPM-layout Swift bridge copying,linkPodspecoperation order, and_syncCppModuleSourcesToSpmno-op behaviour.
0.3.2 #
- Fixed: Swift bridge duplicate compilation ("Invalid redeclaration") — Generated
.bridge.g.swiftfiles are now compiled directly fromlib/src/generated/swift/via the podspecsource_filespattern.nitrogen generateandnitrogen linkno longer copy these files intoios/Classes/ormacos/Classes/; instead, they delete any stale copies that were left from earlier versions. This eliminates the "Invalid redeclaration" Swift compiler error that occurred when both locations were compiled. - Fixed: Android "Unresolved reference: XxxJniBridge" in AGP 8.x — The generated
build.gradletemplate innitrogen initand the benchmark project no longer includejava.srcDirs += "...lib/src/generated/kotlin". In AGP 8.x that line routes.ktfiles through the Java compiler path, making Kotlin-only constructs unresolvable.kotlin.srcDirsalone is sufficient and correct. - Improved:
nitrogen doctorAGP 8.x diagnostic — The Android section now detectsjava.srcDirspointing atgenerated/kotlinand reports an actionable error:java.srcDirs includes generated/kotlin — causes "Unresolved reference: XxxJniBridge" in AGP 8.x, with a hint to remove the line and usekotlin.srcDirsonly. - Improved:
nitrogen doctormixed-platform module detection — Generated-files checks now use platform-specific helpers (_isAndroidKotlinModule/_isAppleSwiftModule) instead of the broadisCppModuleguard. This correctly handles mixed modules such aswindows: WindowsNativeImpl.cpp, android: NativeImpl.kotlin: the.bridge.g.ktcheck is no longer skipped just because another platform uses C++. - Improved:
nitrogen linkpodspecsource_files—linkPodspec()andlinkMacosPodspec()now append'../lib/src/generated/swift/**/*.swift'to the podspecsource_filespattern so Swift bridges are compiled without manual copying. - Improved: Test coverage — 14 new tests across
doctor_command_test.dart,link_command_test.dart, andutils_test.dartcovering:java.srcDirserror detection,sourceSetsmissing error, android:cpp.bridge.g.ktskip, mixed-module.bridge.g.ktcheck, apple:cpp.bridge.g.swiftskip, partial-Swift.bridge.g.swiftcheck, podspecsource_filesinjection, stale Swift bridge cleanup, and AGP 8.x regression guard.
0.3.1 #
- Improved: Ecosystem Sync — Synchronized to version 0.3.1.
- New: macOS
nitrogen linkstep —linkMacosPodspec()now wiresmacos/$plugin.podspecwith the corrects.platform = :osx, '10.15',HEADER_SEARCH_PATHS,swift_version,DEFINES_MODULE,dart_api_dl.cforwarder, and per-module C++ impl forwarders inmacos/Classes/. The new step appears in the link progress view at index 3. - Improved: macOS
nitrogen linkauto-fixes —linkMacosSwiftPlugin()now automatically creates a default${ClassName}Plugin.swiftif missing and injects the requiredRegistry.register()calls. It also handles implementation naming fallbacks (e.g.BenchmarkImpl). - Improved:
nitrogen linkpodspec auto-dependency —linkPodspec()andlinkMacosPodspec()now automatically injects.dependency 'nitro'if it's missing, ensuring the 1.5 µs FFI bridge headers are always visible to the compiler. - Fixed:
nitrogen linksymlink corruption — HardenedlinkMacosSwiftPlugin()andlinkSwiftPlugin()to usefollowLinks: falseand filter out.symlinks/directories, preventing recursive modification of external packages in thepub_cache. - New: macOS Swift plugin wiring —
linkMacosSwiftPlugin()injectsNitroModulesbridge registration calls intomacos/*Plugin.swift, mirroring the existing iOSlinkSwiftPlugin(). Both iOS and macOS Swift wiring now run in a single link step that marks done if either platform directory is present. - New: macOS
nitrogen doctorsection — A dedicatedmacOSdoctor section checks podspecHEADER_SEARCH_PATHS, C++17 flag,dart_api_dl.c,nitro.h,NITRO_EXPORTmacro, stale.bridge.g.cpppresence,.bridge.g.mmbridges,.native.g.hheader sync, and Swift plugin registration — parallel to the existing iOS section. - Improved:
nitrogen doctorplatform diagnostics — Added explicit checks fors.dependency 'nitro'in both iOS and macOS podspecs, providing better DX for troubleshooting native linkage issues. - New: macOS pubspec check —
nitrogen doctornow validates themacos:platform block inpubspec.yaml, checking forpluginClassorffiPlugin: true. - Fixed:
isCppModule()detection for macOS-only and mixed-platform specs — The old implementation required two occurrences ofNativeImpl.cppin the annotation string, somacos: NativeImpl.cppalone (orios: NativeImpl.cpp, macos: NativeImpl.cppwith no Android) was falsely classified as non-cpp. Now uses a platform-arg regex\b(?:ios|android|macos)\s*:\s*NativeImpl\.cpp\b— any platform being cpp marks the module as cpp. - Fixed:
_discoverCppLibs()same two-occurrence bug — The internal bridge-sync utility had identical broken logic; stale.bridge.g.swiftfiles were not cleaned fromios/Classes/ormacos/Classes/for macOS-only cpp specs. Fixed with the same platform-arg regex. - New:
syncBridgeFiles(platform:)parameter —syncBridgeFilesnow accepts an optionalplatformparameter ('ios' or 'macos', default 'ios') so macOS bridge files are correctly synced tomacos/Classes/with the same Swift-exclusion and.cpp→.mmrename logic. - New:
nitro.hcopied tomacos/Classes/—createSharedHeaders()now writesnitro.hintomacos/Classes/when that directory exists, in addition toios/Classes/. - Fixed:
dashboard_testWatch description assertion — the TUI right-panel column truncates long strings; test now checks the visible prefix'Run the Nitro gen'instead of the full description. - Improved: Test coverage — 30+ new edge-case tests across
link_command_test.dart,doctor_command_test.dart, andutils_test.dart: multi-line/comment-above annotation parsing, macOS-onlydiscoverModuleInfos, tri-platform specs,linkMacosPodspecno-op/insertion/idempotency,linkMacosSwiftPlugininjection/deduplication/no-op,syncBridgeFiles(platform: 'macos')variants, macOS doctor section states, and macOS pubspec check variants.
0.3.0 #
- Fixed: PascalCase derivation for filenames with underscores —
discoverModuleInfosnow uses a robust_toPascalCasehelper with empty-segment guards. This preventsRangeErrorexceptions when processing filenames with consecutive underscores (e.g.,my__module.native.dart). - Improved: Ecosystem Sync: Synchronized the Nitro ecosystem to version 0.3.0.
0.2.4 #
- Fixed: iOS build failure for NativeImpl.cpp modules — Three issues that blocked
NativeImpl.cppmodules from linking on iOS have been resolved:linkPodspecnow createsios/Classes/Hybrid<Lib>.cppforwarders for C++ module impl files. On Android each module is its own.so; on iOS everything is one binary — the impl must be compiled inios/Classes/.syncBridgeFilesnow auto-discovers NativeImpl.cpp modules by reading.native.dartspecs and skips copying their.bridge.g.swifttoios/Classes/. The C++ bridge callsg_impldirectly; the@_cdecl("_call_*")stubs in the Swift file are never called and their names clash with the non-cpp Swift bridge, causing a duplicate-symbol linker error.ensureIosPackageSwift+ new_syncCppModuleSourcesToSpmsyncs the.bridge.g.mmandHybrid<Lib>.cppforwarders into the SPMSources/<Main>Cpp/target, and copies only the C-compatible.bridge.g.hintoinclude/(never.native.g.h, which uses C++ types that break the CocoaPods umbrella header).
- New: NativeImpl.cpp Direct C++ Support — All CLI commands now fully support
@NitroModule(ios: NativeImpl.cpp, android: NativeImpl.cpp)modules:nitrogen generate: syncs.native.g.hheaders toios/Classes/; skips "Not applicable" Swift placeholder files; shows a tailored next-steps hint for cpp modules.nitrogen link: skips Swift bridge registration and KotlinJniBridge.registersteps for all-cpp plugins; addsgenerated/cpp/test/to.clangdfor GoogleMock IDE support.nitrogen doctor: new NativeImpl.cpp Direct Implementation section checks whether${lib}_register_impl()is wired up insrc/and whether.clangdincludes the test directory; Android/iOS sections showℹ info(not errors) for checks irrelevant to cpp modules.
- Improved:
nitrogen doctor— cpp-aware Android/iOS sections:- Android: when all specs use
NativeImpl.cpp, Kotlin JNI bridge checks are shown as info. - iOS: Registry.register check skipped for all-cpp plugins; checks for
.native.g.hheaders inios/Classes/instead;.bridge.g.mmwarning suppressed. - Generated files:
.bridge.g.kt/.bridge.g.swiftshown asℹ info(placeholder) for cpp modules;.native.g.h,.mock.g.h,.test.g.cppchecked as required outputs.
- Android: when all specs use
- New:
isCppModule()+ModuleInfo—link_command.dartexportsisCppModule(File)(detects twoNativeImpl.cppoccurrences in annotation) andModuleInfo(carriesisCppflag). LegacydiscoverModules()preserved for compatibility. - Improved: Test Coverage — 28 new tests covering
isCppModuleedge cases,discoverModuleInfoswith mixed cpp/kotlin projects, doctor Android/iOS cpp sections, NativeImpl.cpp doctor section (register_impl check, clangd check).
0.2.3 #
- Automated Native Healing: Commands now proactively fix common native build errors.
nitrogen linkandnitrogen generateautomatically scan your C++ source files and strip redundant#include "*.bridge.g.cpp"directives that previously caused duplicate symbol errors in Xcode.- Added a dedicated
cleanRedundantIncludesutility to the CLI core for robust source cleanup.
- Native Visibility Synchronization:
- The CLI now maintains a canonical
nitro.hwithNITRO_EXPORTvisibility macros for cross-platform FFI compatibility. nitrogen link,nitrogen generate, andnitrogen initall strictly enforce that your project'snitro.his up to date, automatically repairing it if it's outdated or corrupted.
- The CLI now maintains a canonical
- Enhanced
nitrogen doctorDiagnostics:- New check for redundant bridge includes in
src/. - New check for
NITRO_EXPORTvisibility macros innitro.h. - Improved
HEADER_SEARCH_PATHSvalidation in iOS podspecs to ensure all generated code is discoverable.
- New check for redundant bridge includes in
- Improved Code Generation: Fixed an issue in
nitro_generatorwhere largeUint8Listbuffers were incorrectly passed asArray<UInt8>instead ofDatain some Swift bridge signatures. - Dependency Sync: Synchronized the Nitro ecosystem to version 0.2.3.
0.2.2 #
- Standardized on Nitrogen 0.2.2 ecosystem versions.
0.2.1 #
- New Watch Mode: Added the
nitrogen watchcommand to handle continuous code generation. This feature includes an automatic iOS Bridge Sync that copies and renames generated C++/Swift bridges toios/Classeson every successful build. This ensures that your iOS project always has the latest generated bridge files without manual intervention. - Better TUI Experience: Overhauled the Nitro Dashboard with a new multi-project sidebar, improved focus management (using [Tab]), and consistent ESC-based navigation.
- New: Multi-Project Discovery: Automatically detects and switches between multiple Nitrogen modules in a monorepo.
- Improved: Enhanced Doctor: Expanded
nitrogen doctorto verify system compiler toolchains (Clang, Xcode, NDK, Java) and validate plugin registration. - Performance: Optimized Android and JNI bridge performance with static caching and persistent thread pools.
- Improved: TUI Navigation & Error Handling — Standardized "ESC back" and "ESC exit" navigation logic across all views. Implemented a centered, high-visibility error UI for all command failures (e.g., missing
pubspec.yaml, network/process errors). - Improved: JNI Performance — All
FindClass,GetStaticMethodID,GetFieldID, andGetMethodIDcalls are now cached as static globals and initialized once inJNI_OnLoad, eliminating per-call classloader traversal. - Improved: Android Async Throughput — Kotlin bridge async methods now delegate to a
newCachedThreadPoolexecutor instead of callingrunBlockingdirectly. - Improved: Generator O(1) Type Lookups —
KotlinGeneratorandCppBridgeGeneratornow pre-build type name tables once per generation, reducing lookup complexity from O(n) to O(1). - Improved: Process Feedback —
ProcessViewnow uses visual cues (red borders) and explicit status text when a long-running process fails. - Fixed: Arena Use-After-Free in Async FFI Bridges — Generated code now uses
Arena()directly withtry/finallyto ensure the arena lives until after the async native call completes. - Fixed: Typed
callAsync<T>Removes Raw Pointer Casts — Generated Dart now uses the typed formcallAsync<T>(...), eliminating unsafeascasts. - Fixed: Null Safety for JNI Pack — Added null guards for zero-copy
ByteBufferfields inpack_*_from_jnihelpers. - Fixed:
nitrogen doctorUnmodifiable List Error — Resolved a runtime exception by ensuring diagnostic lists are growable. - Fixed:
nitrogen exitcommand — Properly terminates the application from the menu. - Refactored Link Logic: Decoupled core linking logic (CMake, Podspec, Swift/Kotlin plugins,
.clangd) from the TUI-specificLinkView. All linking tasks are now top-level, testable functions that support abaseDirparameter for programmatic execution in monorepos or test environments. - Improved: iOS Podspec Wiring: Updated
linkPodspecto automatically enforce Swift 5.9 and iOS 13.0 as minimums, ensuring compatibility with the latest Nitrogen generated code. - Fixed: PathNotFoundException in Tests: Updated
getAllProjectsto accept an optionalbaseDir, eliminating reliance on the process-globalDirectory.currentand fixing parallel test execution failures. - Improved Test Coverage: Added a comprehensive test suite for CLI command registration, module discovery, and path resolution.
0.2.0 #
- New: High-Performance Binary Codec Integration — All generated bridges now default to the compact binary protocol for
@HybridRecordtypes, matching the updates inpackage:nitro0.2.0. - Improved:
nitrogen doctorReliability — Fixed a runtime exception ("Unsupported operation: Cannot add to an unmodifiable list") when running checks onpubspec.yaml, generated files, and build system wiring. - Improved:
nitrogen generateStability — Updated the generator backbone to remove unreferenced helper methods and redundant type lookups in Swift bridges. - Improved: Linter Integration — Updated analysis options to prefer wider page widths (220) and cleaner formatting for generated code across all packages.
- Dependency Sync: Synchronized core ecosystem versions to 0.2.0 across
nitro,nitro_generator, andnitrogen_cli.
0.1.13 #
- Full Zero-Copy TypedData Support:
- Fixed JNI bridging for
@HybridStruct(descriptors, casts, and byte counts). - Added
ZeroCopyBuffervariants for ALL TypedData types with GC finalizers. Int64ListandUint64Listare now correctly handled in all generators.
- Fixed JNI bridging for
- iOS & Swift Safety:
- Renamed bridge files to
.bridge.g.mmto enable Objective-C++ exception handling. - Fixed memory corruption when passing typed lists (
Float32List, etc.) by using ABI-safe pointers and companion length parameters. - Replaced
fatalErrorwith catchableNSException.raisefor bridge validation errors.
- Renamed bridge files to
- CLI Workflow & Tooling:
nitrogen generatenow automatically syncs Swift bridges toios/Classes/and runspod install.- Added new
nitrogen doctorchecks for iOS project health and FFI plugin configuration. - Stale bridge files are now automatically cleaned up during
link.
- Generator Enhancements: Added cyclic dependency detection in structs and support for
@HybridEnumas struct fields. - Testing & Quality: Added 150+ new tests covering zero-copy TypedData, cyclic dependencies, and bridge safety. Fixed minor TUI lints and improved CLI feedback.
0.1.12 #
- Fix static version in
lib/version.dart nitrogen init:src/dart_api_dl.candsrc/CMakeLists.txtnow resolve the correct pub-cachenitropath at scaffold time instead of writing a monorepo placeholder. After pubspec dependencies are installed,nitrogen initreads.dart_tool/package_config.json(using the sameresolveNitroNativePathlogic asnitrogen link) and overwrites both files with the absolute path — so the generated plugin builds immediately without needing a separatenitrogen linkrun.
0.1.11 #
nitrogen init: generatedexample/lib/main.dartnow showcases the plugin API with a proper Flutter app —WidgetsFlutterBinding.ensureInitialized(), aStatelessWidgetMyApp, try-catch error screen, asyncFutureBuilder, and a reusable_FeatureCardwidget. Fixes broken template syntax (const .all(10),.center) from the previous scaffold.- Added
docs/swift-type-mapping.md: comprehensive reference covering the two-layer Swift type system, full Dart → C →@_cdecl→ protocol type mapping table, memory ownership for String returns, async bridging pattern, Bool conversion, struct returns, and a crash diagnosis guide forEXC_BAD_ACCESS. - Updated
docs/getting-started.md: added@_cdeclbridge type callout in the Supported Types section, Step 6 note reminding plugin authors to use native Swift types in*Impl.swift, and anEXC_BAD_ACCESStroubleshooting entry.
0.1.10 #
- Editor Quick Links: Instantly open your active Nitro project in VS Code or Antigravity via clickable links in the dashboard header or the
nitrogen opencommand. - Smart Project Discovery:
generate,link, anddoctorcommands now automatically search for a Nitro project in the current directory and its direct subdirectories. This allows running Nitrogen commands from a parent folder (e.g., right afterinit) without needing to manuallycd.- Dashboard now reflects the active project found in subdirectories.
- Improved Navigation: Added visible
‹ Backbuttons to all menu views (Init, Doctor, Link, and Generate) for easier dashboard navigation. - UI Stability Fix:
- Fixed flickering and layout jumps in the "✨ SUCCESS ✨" pulse animation during generation and initialization.
- The success status now maintains a stable height, preventing the log view from shifting.
- TUI Menu Refinement: Rearranged core commands with Exit consistently at the bottom and editor options moved to a cleaner header position.
0.1.9 #
- TUI Visual Overhaul (Neon Premium Theme):
- New pulsing header logo (cycles between ⚡ Cyan and 🔥 Magenta).
- Added "by Shreeman Arjun" author attribution to the dashboard.
- Improved readability with high-contrast color palettes for menus and logs.
- Mouse & Interactive Features:
- Full mouse support: Hover over menu items to highlight them.
- Click anywhere on a command row to execute it instantly.
- Clickable footer links for Documentation, Shreeman.dev, and Marc Rousavy.
- Context-Aware Dashboard:
- Project Bar: Displays the name and version of the currently active Nitrogen project in the header.
- Status Bar: Added a fixed bottom bar showing Dart version and current Git branch.
- Enhanced Process Feedback:
- Added a pulsing "✨ SUCCESS ✨" animation and green color shift when a generation or initialization completes successfully.
- Usability Fixes:
- Added an explicit Exit command to the TUI menu for easy quitting.
- Standardized menu alignment (labels and descriptions now align vertically in the center).
- Automatic TUI versioning: the dashboard always displays the actual package version from
pubspec.yaml.
0.1.8 #
nitrogen link: fix Android/iOS build failure wheredart_api_dl.canddart_api_dl.hwere not found whennitrois installed from pub.dev (e.g. via puro's pub cache) rather than a local monorepo path.linknow reads.dart_tool/package_config.jsonto resolve the actual installednitropackage path (absolutefile://URI or relative URI).- Creates a local
src/dart_api_dl.cforwarder (#include "<resolved path>") so the Android CMake build never references a path outside the project directory. ios/Classes/dart_api_dl.cnow chains through../../src/dart_api_dl.c, giving both Android CMake and iOS CocoaPods/SPM a single resolution point.- Migrates legacy
"${NITRO_NATIVE}/dart_api_dl.c"entries in existingCMakeLists.txtto the new local"dart_api_dl.c"form automatically. - Updates a stale
NITRO_NATIVEcmake variable if the path it currently points to no longer containsdart_api_dl.h.
nitrogen init: generatedCMakeLists.txtandios/Classes/dart_api_dl.cnow use the same local-forwarder pattern from day one.- Extracted
resolveNitroNativePath,nitroNativePathExists, anddartApiDlForwarderContentas package-level functions for testability; private_LinkViewStatehelpers now delegate to them. - Added tests covering
resolveNitroNativePath(file:// URI, relative URI, absent config, fallback),nitroNativePathExists, anddartApiDlForwarderContent.
0.1.7 #
nitrogen init:nitroandnitro_generatordependency versions are now resolved automatically from pub.dev at scaffold time instead of being hardcoded.- Fallback: if pub.dev is unreachable,
flutter pub add nitroandflutter pub add --dev nitro_generatorare run in the generated plugin directory so pub resolves the latest compatible versions itself.
0.1.6 #
- Fix
nitrogen doctoralways reportingios/Classes/dart_api_dl.cpp missing: the check now correctly looks fordart_api_dl.c, matching whatnitrogen linkactually creates (.cppis deleted bylinkbecause C++ rejects thevoid*/function-pointer cast inside it).
0.1.5 #
nitrogen initnow generates starter${ClassName}Impl.swiftand${ClassName}Impl.ktfiles so the plugin compiles immediately without any manual steps.- iOS: switched from
@objc/NSObjectto@_cdeclC-bridge stubs — Swift structs and Swift-only protocols can now cross the native boundary correctly. - iOS:
HEADER_SEARCH_PATHSin podspec now uses${PODS_ROOT}/../.symlinks/plugins/nitro/src/nativeso the path resolves correctly whethernitrois a local path dependency or installed from pub.dev. - iOS:
dart_api_dlis created as.c(not.cpp) so the Dart DL API compiles as C; C++ rejects thevoid*/function-pointer cast inside it. - iOS:
nitrogen initnow creates aPackage.swiftalongside the podspec, enabling Swift Package Manager distribution in addition to CocoaPods. - iOS: SPM
Sources/layout uses symlinks intoClasses/so a single file exists at one location and is shared between both build systems. nitrogen link: extracteddiscoverModuleLibsandextractLibNameFromSpecas package-level functions for testability.- Added comprehensive
link_command_test.dartcovering lib-name extraction, module discovery, podspec path correctness, and template content validation.
0.1.4 #
nitrogen initalways prompts for plugin name via an interactivePluginNameFormTUI; the name can no longer be passed as a positional argument.- Added
NitrogenInitApp(public) to handle the form → scaffold flow, reusable in both CLI and TUI dashboard. - TUI dashboard
/initroute updated to useNitrogenInitAppinstead of a hardcodedInitView. ESCon the plugin name form navigates back to the dashboard (TUI) or is a no-op (CLI).- Added
pluginNamefield toInitResultfor post-run reporting. - Added comprehensive tests for
InitResult,InitStep,InitStepRow,PluginNameForm, and plugin name validation.
0.1.3 #
- Implement String type conversion in the struct generator and add braces to the CLI's plugin name extraction.
0.1.2 #
- Rename generator package folder to
nitro_generator. - Update
doctorandinitcommands with new path references.
0.1.1 #
- Update
nitrogenpackage reference tonitro_generator.
0.1.0 #
- Initial release with
noctermdashboard. - Integrated
nitrogen init,generate,link,doctor, andupdate.