diff --git a/crates/bashkit-capi/include/bashkit.def b/crates/bashkit-capi/include/bashkit.def index fb7b37f46..ecd02533d 100644 --- a/crates/bashkit-capi/include/bashkit.def +++ b/crates/bashkit-capi/include/bashkit.def @@ -3,16 +3,17 @@ EXPORTS bashkit_abi_version bashkit_buffer_bytes bashkit_buffer_free + bashkit_cancel bashkit_capabilities_json + bashkit_clear_cancel bashkit_create_default bashkit_create_json + bashkit_create_with_runtime_handler_v1 bashkit_error_code bashkit_error_free bashkit_error_message bashkit_execute bashkit_execute_streaming - bashkit_cancel - bashkit_clear_cancel bashkit_free bashkit_mkdir bashkit_mount @@ -24,6 +25,11 @@ EXPORTS bashkit_result_free bashkit_result_stderr bashkit_result_stdout + bashkit_runtime_call_cancelled + bashkit_runtime_call_fail + bashkit_runtime_call_free + bashkit_runtime_call_request + bashkit_runtime_call_respond_json bashkit_unmount bashkit_version bashkit_write_file diff --git a/knowledge/log.md b/knowledge/log.md index dbd76a7e5..7fd461da1 100644 --- a/knowledge/log.md +++ b/knowledge/log.md @@ -4,7 +4,7 @@ * **C streaming callbacks**: Integrated C ABI runtime host functions with live output. Buffered and streaming entry points share admission guards, and output callbacks reject blocking reentry on any handle before a nested runtime can start. Combined tests cover immediate/cross-thread replies, capture and discard, caller affinity, and recursive streaming calls. See [C API](runtimes/c-api.md). -* **C runtime parity**: Added optional Python/TypeScript runtime flags and an additive ABI v1 host dispatcher. Owned, revocable runtime calls accept immediate or cross-thread replies; blocking callback reentry fails with BUSY. Added parallel-instance, caller-thread, cancellation/deadline/reuse and real C header/library tests. Corrected parity evidence for existing C cancellation and mounts. See [C API](runtimes/c-api.md). +* **C runtime parity**: Added optional Python/TypeScript runtime flags and an additive ABI v1 host dispatcher. Owned, revocable runtime calls accept immediate or cross-thread replies; blocking callback reentry fails with BUSY. Added parallel-instance, caller-thread, cancellation/deadline/reuse and real C header/library tests. Corrected parity evidence for existing C cancellation and mounts. Windows import libraries include every runtime symbol; header/Rust/definition inventory checks prevent missing exports. See [C API](runtimes/c-api.md). * **Live runtime callbacks**: Integrated JavaScript Python/TypeScript host functions with byte sinks and explicit capture after the runtime-function API landed. Buffered and live execution share the request-local dispatcher lease and async/sync admission guard. Regression suites cover queued caller contexts, output delivery and signal revocation across Node, Bun and Deno. See [Node Package](runtimes/node-package.md). diff --git a/knowledge/runtimes/c-api.md b/knowledge/runtimes/c-api.md index ef003f153..7251b0ddb 100644 --- a/knowledge/runtimes/c-api.md +++ b/knowledge/runtimes/c-api.md @@ -73,6 +73,7 @@ and defaults to deny on credential paths. incompatibly. - Opaque layouts may change at any time. - Additive functions and status values are allowed. +- Windows import libraries are generated from `include/bashkit.def`. Every public header function and Rust C entry point must be listed there; `scripts/tests/test_capi_exports.py` enforces the complete inventory, including runtime callback APIs. - Breaking changes require a parallel ABI major. ## Embedded runtime host functions diff --git a/scripts/tests/test_capi_exports.py b/scripts/tests/test_capi_exports.py new file mode 100644 index 000000000..2ca92725f --- /dev/null +++ b/scripts/tests/test_capi_exports.py @@ -0,0 +1,23 @@ +"""The shipped Windows import library must expose the complete public C ABI.""" +from pathlib import Path +import re +import unittest + +ROOT = Path(__file__).resolve().parents[2] / "crates/bashkit-capi" + + +class CApiExportsTests(unittest.TestCase): + def test_header_rust_and_windows_exports_match(self): + header = re.sub(r"/\*.*?\*/|//[^\n]*", "", (ROOT / "include/bashkit.h").read_text(), flags=re.S) + declared = set(re.findall(r"\b(bashkit_\w+)\s*\(", header)) + windows = set(re.findall(r"^\s+(bashkit_\w+)\s*$", (ROOT / "include/bashkit.def").read_text(), re.M)) + rust = set() + for source in (ROOT / "src").rglob("*.rs"): + rust.update(re.findall(r'#\[unsafe\(no_mangle\)\]\s+pub\s+(?:unsafe\s+)?extern\s+"C"\s+fn\s+(bashkit_\w+)', source.read_text())) + self.assertTrue(declared) + self.assertEqual(declared, rust, "public header and Rust entry points differ") + self.assertEqual(declared, windows, "Windows SDK import-library exports differ from the public header") + + +if __name__ == "__main__": + unittest.main()