feat(core): import progress & perf (#15197)

#### PR Dependency Tree


* **PR #15197** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a new import pipeline with “plan then commit” batch handling for
Markdown, Notion HTML, Obsidian, and Bear backups.
* Enabled native import sessions with progress, cancellation, and
batch-by-batch committing (including assets, folders, icons, and tags).
  * Added web preflight limits for ZIP and multi-file imports.
* **Bug Fixes**
* Improved import error/warning reporting and continued processing when
some items fail.
* Strengthened snapshot-based file/directory picking to preserve paths.
* **Chores**
  * Updated project packaging/configuration for the new import workflow.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
DarkSky
2026-07-06 01:29:24 +08:00
committed by GitHub
parent 477015f064
commit 8d72e4dc29
106 changed files with 3329 additions and 11690 deletions
@@ -682,14 +682,6 @@ impl ShareableContent {
}
}
#[napi]
pub fn tap_audio(
process_id: u32,
audio_stream_callback: ThreadsafeFunction<napi::bindgen_prelude::Float32Array, ()>,
) -> Result<AudioCaptureSession> {
ShareableContent::tap_audio_with_callback(process_id, AudioCallback::Js(Arc::new(audio_stream_callback)))
}
pub(crate) fn tap_global_audio_with_callback(
excluded_processes: Option<Vec<&ApplicationInfo>>,
audio_stream_callback: AudioCallback,
@@ -706,15 +698,4 @@ impl ShareableContent {
let boxed_manager = Box::new(device_manager);
Ok(AudioCaptureSession::new(boxed_manager))
}
#[napi]
pub fn tap_global_audio(
excluded_processes: Option<Vec<&ApplicationInfo>>,
audio_stream_callback: ThreadsafeFunction<napi::bindgen_prelude::Float32Array, ()>,
) -> Result<AudioCaptureSession> {
ShareableContent::tap_global_audio_with_callback(
excluded_processes,
AudioCallback::Js(Arc::new(audio_stream_callback)),
)
}
}
@@ -21,7 +21,6 @@ use coreaudio::sys::{
kAudioSubTapUIDKey,
};
use napi::bindgen_prelude::Result;
use napi_derive::napi;
use objc2::runtime::AnyObject;
use crate::{
@@ -887,8 +886,6 @@ impl Drop for AggregateDeviceManager {
}
}
// NEW NAPI Struct: AudioCaptureSession
#[napi]
pub struct AudioCaptureSession {
// Use Option<Box<...>> to allow taking ownership in stop()
manager: Option<Box<AggregateDeviceManager>>,
@@ -896,9 +893,7 @@ pub struct AudioCaptureSession {
channels: Option<u32>,
}
#[napi]
impl AudioCaptureSession {
// Constructor called internally, not directly via NAPI
pub(crate) fn new(manager: Box<AggregateDeviceManager>) -> Self {
Self {
manager: Some(manager),
@@ -907,7 +902,6 @@ impl AudioCaptureSession {
}
}
#[napi]
pub fn stop(&mut self) -> Result<()> {
if let Some(manager) = self.manager.take() {
// Cache the stats before dropping
@@ -926,7 +920,6 @@ impl AudioCaptureSession {
}
}
#[napi(getter)]
pub fn get_sample_rate(&self) -> Result<f64> {
if let Some(manager) = &self.manager {
manager
@@ -943,7 +936,6 @@ impl AudioCaptureSession {
}
}
#[napi(getter)]
pub fn get_channels(&self) -> Result<u32> {
if let Some(manager) = &self.manager {
manager
@@ -960,7 +952,6 @@ impl AudioCaptureSession {
}
}
#[napi(getter)]
pub fn get_actual_sample_rate(&self) -> Result<f64> {
if let Some(manager) = &self.manager {
manager
@@ -200,7 +200,6 @@ fn emit_mixed_frames(
}
}
#[napi]
pub struct AudioCaptureSession {
mic_stream: Option<cpal::Stream>,
lb_stream: Option<cpal::Stream>,
@@ -258,25 +257,20 @@ where
}
}
#[napi]
impl AudioCaptureSession {
#[napi(getter)]
pub fn get_sample_rate(&self) -> f64 {
self.sample_rate.0 as f64
}
#[napi(getter)]
pub fn get_channels(&self) -> u32 {
self.channels
}
#[napi(getter)]
pub fn get_actual_sample_rate(&self) -> f64 {
// For CPAL we always operate at the target rate which is sample_rate
self.sample_rate.0 as f64
}
#[napi]
pub fn stop(&mut self) -> Result<()> {
teardown_audio_capture_resources(
&mut self.mic_stream,
@@ -225,16 +225,6 @@ impl ShareableContent {
crate::windows::audio_capture::start_recording(audio_stream_callback, target)
}
#[napi]
pub fn tap_audio(
_process_id: u32, // Currently unused - Windows captures global audio
audio_stream_callback: ThreadsafeFunction<napi::bindgen_prelude::Float32Array, ()>,
) -> Result<AudioCaptureSession> {
// On Windows with CPAL, we capture global audio (mic + loopback)
// since per-application audio tapping isn't supported the same way as macOS
ShareableContent::tap_audio_with_callback(_process_id, AudioCallback::Js(Arc::new(audio_stream_callback)), None)
}
pub(crate) fn tap_global_audio_with_callback(
_excluded_processes: Option<Vec<&ApplicationInfo>>,
audio_stream_callback: AudioCallback,
@@ -246,18 +236,6 @@ impl ShareableContent {
crate::windows::audio_capture::start_recording(audio_stream_callback, target)
}
#[napi]
pub fn tap_global_audio(
_excluded_processes: Option<Vec<&ApplicationInfo>>,
audio_stream_callback: ThreadsafeFunction<napi::bindgen_prelude::Float32Array, ()>,
) -> Result<AudioCaptureSession> {
ShareableContent::tap_global_audio_with_callback(
_excluded_processes,
AudioCallback::Js(Arc::new(audio_stream_callback)),
None,
)
}
#[napi]
pub fn is_using_microphone(process_id: u32) -> Result<bool> {
is_process_actively_using_microphone(process_id)