Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions crates/perry-api-manifest/src/entries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2087,6 +2087,11 @@ pub static API_MANIFEST: &[ApiEntry] = &[
method("perry/system", "isDarkMode", false, None),
method("perry/system", "getDeviceIdiom", false, None),
method("perry/system", "getDeviceModel", false, None),
// Bug-report-flow utility: stable OS-version string per
// platform (e.g. `"15.2"`, `"macOS 14.5"`, `"Android 14"`).
// Common need for crash reports and telemetry; pairs with
// getDeviceModel / getAppVersion.
method("perry/system", "getOSVersion", false, None),
method("perry/system", "getLocale", false, None),
method("perry/system", "getAppVersion", false, None),
method("perry/system", "getAppBuildNumber", false, None),
Expand Down
10 changes: 10 additions & 0 deletions crates/perry-dispatch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2204,6 +2204,16 @@ pub static PERRY_SYSTEM_TABLE: &[MethodRow] = &[
args: &[],
ret: ReturnKind::F64,
},
// Bug-report-flow utility: stable OS-version string per
// platform. Returns a NaN-boxed JS string the user can splice
// into crash reports / telemetry. Same dispatch shape as
// getDeviceModel.
MethodRow {
method: "getOSVersion",
runtime: "perry_system_get_os_version",
args: &[],
ret: ReturnKind::F64,
},
MethodRow {
method: "audioSetOutputFilename",
runtime: "perry_system_audio_set_output_filename",
Expand Down
14 changes: 14 additions & 0 deletions crates/perry-ui-android/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2169,6 +2169,20 @@ pub extern "C" fn perry_system_audio_get_waveform(count: f64) -> f64 {
pub extern "C" fn perry_system_get_device_model() -> i64 {
audio::get_device_model()
}
/// Bug-report-flow utility: stable OS-version string. Android stub —
/// native impl will read `Build.VERSION.RELEASE` via JNI.
#[no_mangle]
pub extern "C" fn perry_system_get_os_version() -> i64 {
perry_runtime::stub_diag::perry_stub_warn(
"perry_system_get_os_version",
"Android getOSVersion (Build.VERSION.RELEASE) not yet implemented",
None,
);
extern "C" {
fn js_string_from_bytes(ptr: *const u8, len: i32) -> i64;
}
unsafe { js_string_from_bytes(std::ptr::null(), 0) }
}
#[no_mangle]
pub extern "C" fn perry_system_audio_set_output_filename(filename_ptr: i64) {
fn str_from_header(ptr: *const u8) -> &'static str {
Expand Down
15 changes: 15 additions & 0 deletions crates/perry-ui-gtk4/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1949,6 +1949,21 @@ pub extern "C" fn perry_system_audio_get_waveform(count: f64) -> f64 {
pub extern "C" fn perry_system_get_device_model() -> i64 {
audio::get_device_model()
}
/// Bug-report-flow utility: stable OS-version string. GTK4/Linux
/// stub — native impl would read `/etc/os-release` or
/// `uname -r`.
#[no_mangle]
pub extern "C" fn perry_system_get_os_version() -> i64 {
perry_runtime::stub_diag::perry_stub_warn(
"perry_system_get_os_version",
"Linux getOSVersion (/etc/os-release) not yet implemented",
None,
);
extern "C" {
fn js_string_from_bytes(ptr: *const u8, len: i32) -> i64;
}
unsafe { js_string_from_bytes(std::ptr::null(), 0) }
}
#[no_mangle]
pub extern "C" fn perry_system_audio_set_output_filename(filename_ptr: i64) {
fn str_from_header(ptr: *const u8) -> &'static str {
Expand Down
14 changes: 14 additions & 0 deletions crates/perry-ui-ios/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1541,6 +1541,20 @@ pub extern "C" fn perry_system_audio_get_waveform(count: f64) -> f64 {
pub extern "C" fn perry_system_get_device_model() -> i64 {
audio::get_device_model()
}
/// Bug-report-flow utility: stable OS-version string. MVP stub on
/// iOS; native impl will use `[[UIDevice currentDevice] systemVersion]`.
#[no_mangle]
pub extern "C" fn perry_system_get_os_version() -> i64 {
perry_runtime::stub_diag::perry_stub_warn(
"perry_system_get_os_version",
"iOS getOSVersion not yet implemented (UIDevice.systemVersion follow-up)",
Some("#918"),
);
extern "C" {
fn js_string_from_bytes(ptr: *const u8, len: i32) -> i64;
}
unsafe { js_string_from_bytes(std::ptr::null(), 0) }
}
#[no_mangle]
pub extern "C" fn perry_system_audio_set_output_filename(filename_ptr: i64) {
fn str_from_header(ptr: *const u8) -> &'static str {
Expand Down
33 changes: 33 additions & 0 deletions crates/perry-ui-macos/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2157,6 +2157,39 @@ pub extern "C" fn perry_system_get_device_model() -> i64 {
audio::get_device_model()
}

/// Bug-report-flow utility: stable OS-version string. Uses
/// `[[NSProcessInfo processInfo] operatingSystemVersionString]`
/// which returns a human-readable form like `"Version 14.5
/// (Build 23F79)"` — preserved as-is so triage can grep the build
/// number too. Returned as a Perry-managed string.
#[no_mangle]
pub extern "C" fn perry_system_get_os_version() -> i64 {
extern "C" {
fn js_string_from_bytes(ptr: *const u8, len: i32) -> i64;
}
unsafe {
let cls = objc2::runtime::AnyClass::get(c"NSProcessInfo").unwrap();
let info: *mut objc2::runtime::AnyObject = objc2::msg_send![cls, processInfo];
if info.is_null() {
return js_string_from_bytes(std::ptr::null(), 0);
}
let s: *mut objc2::runtime::AnyObject =
objc2::msg_send![info, operatingSystemVersionString];
if s.is_null() {
return js_string_from_bytes(std::ptr::null(), 0);
}
let utf8_ptr: *const u8 = objc2::msg_send![s, UTF8String];
if utf8_ptr.is_null() {
return js_string_from_bytes(std::ptr::null(), 0);
}
let utf8_len: usize = objc2::msg_send![s, lengthOfBytesUsingEncoding: 4u64];
if utf8_len == 0 {
return js_string_from_bytes(std::ptr::null(), 0);
}
js_string_from_bytes(utf8_ptr, utf8_len as i32)
}
}

/// Set output filename for audio recording.
#[no_mangle]
pub extern "C" fn perry_system_audio_set_output_filename(filename_ptr: i64) {
Expand Down
14 changes: 14 additions & 0 deletions crates/perry-ui-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1463,6 +1463,20 @@ pub const FEATURES: &[Feature] = &[
web: S,
web_name: None,
},
// Bug-report-flow utility: stable OS-version string. macOS has
// the real impl via NSProcessInfo; every other platform is a
// first-call-warning stub awaiting its native implementation.
Feature {
name: "perry_system_get_os_version",
category: SystemApi,
macos: S,
ios: S,
android: S,
gtk4: S,
windows: S,
web: S,
web_name: None,
},
Feature {
name: "perry_system_preferences_set",
category: SystemApi,
Expand Down
15 changes: 15 additions & 0 deletions crates/perry-ui-tvos/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1327,6 +1327,21 @@ pub extern "C" fn perry_system_audio_get_waveform(count: f64) -> f64 {
pub extern "C" fn perry_system_get_device_model() -> i64 {
audio::get_device_model()
}
/// Bug-report-flow utility: stable OS-version string. tvOS stub —
/// native impl can mirror iOS's `[[UIDevice currentDevice] systemVersion]`
/// (UIDevice is available on tvOS).
#[no_mangle]
pub extern "C" fn perry_system_get_os_version() -> i64 {
perry_runtime::stub_diag::perry_stub_warn(
"perry_system_get_os_version",
"tvOS getOSVersion not yet implemented",
None,
);
extern "C" {
fn js_string_from_bytes(ptr: *const u8, len: i32) -> i64;
}
unsafe { js_string_from_bytes(std::ptr::null(), 0) }
}
#[no_mangle]
pub extern "C" fn perry_system_audio_set_output_filename(filename_ptr: i64) {
fn str_from_header(ptr: *const u8) -> &'static str {
Expand Down
13 changes: 13 additions & 0 deletions crates/perry-ui-visionos/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1448,6 +1448,19 @@ pub extern "C" fn perry_system_audio_get_waveform(count: f64) -> f64 {
pub extern "C" fn perry_system_get_device_model() -> i64 {
audio::get_device_model()
}
/// Bug-report-flow utility: stable OS-version string. visionOS stub.
#[no_mangle]
pub extern "C" fn perry_system_get_os_version() -> i64 {
perry_runtime::stub_diag::perry_stub_warn(
"perry_system_get_os_version",
"visionOS getOSVersion not yet implemented",
None,
);
extern "C" {
fn js_string_from_bytes(ptr: *const u8, len: i32) -> i64;
}
unsafe { js_string_from_bytes(std::ptr::null(), 0) }
}
#[no_mangle]
pub extern "C" fn perry_system_audio_set_output_filename(filename_ptr: i64) {
fn str_from_header(ptr: *const u8) -> &'static str {
Expand Down
13 changes: 13 additions & 0 deletions crates/perry-ui-watchos/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1200,6 +1200,19 @@ pub extern "C" fn perry_system_audio_get_waveform(_count: f64) -> f64 {
pub extern "C" fn perry_system_get_device_model() -> i64 {
0
}
/// Bug-report-flow utility: stable OS-version string. watchOS stub.
#[no_mangle]
pub extern "C" fn perry_system_get_os_version() -> i64 {
perry_runtime::stub_diag::perry_stub_warn(
"perry_system_get_os_version",
"watchOS getOSVersion not yet implemented",
None,
);
extern "C" {
fn js_string_from_bytes(ptr: *const u8, len: i32) -> i64;
}
unsafe { js_string_from_bytes(std::ptr::null(), 0) }
}
#[no_mangle]
pub extern "C" fn perry_system_audio_set_output_filename(filename_ptr: i64) {
let filename = str_from_header(filename_ptr as *const u8);
Expand Down
14 changes: 14 additions & 0 deletions crates/perry-ui-windows/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1994,6 +1994,20 @@ pub extern "C" fn perry_system_audio_get_waveform(count: f64) -> f64 {
pub extern "C" fn perry_system_get_device_model() -> i64 {
audio::get_device_model()
}
/// Bug-report-flow utility: stable OS-version string. Windows stub —
/// native impl will use `GetVersionEx` / `RtlGetVersion`.
#[no_mangle]
pub extern "C" fn perry_system_get_os_version() -> i64 {
perry_runtime::stub_diag::perry_stub_warn(
"perry_system_get_os_version",
"Windows getOSVersion (RtlGetVersion) not yet implemented",
None,
);
extern "C" {
fn js_string_from_bytes(ptr: *const u8, len: i32) -> i64;
}
unsafe { js_string_from_bytes(std::ptr::null(), 0) }
}
#[no_mangle]
pub extern "C" fn perry_system_audio_set_output_filename(filename_ptr: i64) {
fn str_from_header(ptr: *const u8) -> &'static str {
Expand Down
4 changes: 3 additions & 1 deletion docs/api/perry.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Auto-generated from Perry's API manifest (#465). Do not edit by hand.
// Source: perry-api-manifest::API_MANIFEST
// Coverage: 900 entries across 71 modules
// Coverage: 901 entries across 71 modules

declare module "argon2" {
/** stdlib */
Expand Down Expand Up @@ -736,6 +736,8 @@ declare module "perry/system" {
/** stdlib */
export function getLocale(...args: any[]): any;
/** stdlib */
export function getOSVersion(...args: any[]): any;
/** stdlib */
export function imagePickerPick(...args: any[]): any;
/** stdlib */
export function isDarkMode(...args: any[]): any;
Expand Down
3 changes: 2 additions & 1 deletion docs/src/api/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This page is auto-generated from Perry's compile-time API manifest (`perry-api-manifest::API_MANIFEST`). It is the source of truth for what `perry compile` accepts; references to symbols not listed here produce `R005 UnimplementedApi` (issue #463). Stubs (#464) are flagged ⚠ — they link cleanly but no-op at runtime on the chosen target.

Total: 900 entries across 71 modules.
Total: 901 entries across 71 modules.

## Modules

Expand Down Expand Up @@ -922,6 +922,7 @@ Total: 900 entries across 71 modules.
- `getDeviceIdiom` — module
- `getDeviceModel` — module
- `getLocale` — module
- `getOSVersion` — module
- `imagePickerPick` — module
- `isDarkMode` — module
- `keychainDelete` — module
Expand Down
Loading