pub struct ContextApi { /* private fields */ }Implementations§
Source§impl ContextApi
impl ContextApi
Sourcepub fn new() -> Result<Self, Error>
pub fn new() -> Result<Self, Error>
Examples found in repository?
examples/runtime_capabilities.rs (line 4)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let api = ContextApi::new()?;
5
6 println!(
7 "device={} platform={:?}",
8 api.device_context().device_id,
9 api.device_context().platform
10 );
11
12 for signal_type in [
13 SignalType::Clipboard,
14 SignalType::Selection,
15 SignalType::Focus,
16 ] {
17 println!("{signal_type:?}: {:?}", api.signal_support(signal_type));
18 }
19
20 println!("supported={:?}", api.supported_signals());
21 Ok(())
22}More examples
examples/context_live_view.rs (line 12)
11fn main() -> Result<(), Box<dyn std::error::Error>> {
12 let mut api = ContextApi::new()?;
13 let events = Arc::new(Mutex::new(VecDeque::<String>::new()));
14
15 for signal_type in [
16 SignalType::Clipboard,
17 SignalType::Selection,
18 SignalType::Focus,
19 ] {
20 if !matches!(api.signal_support(signal_type), SignalSupport::Supported) {
21 continue;
22 }
23
24 let events = Arc::clone(&events);
25 api.subscribe_enveloped(signal_type, move |envelope| {
26 let line = summarize_envelope(&envelope);
27 let mut queue = events.lock().expect("event queue mutex poisoned");
28 queue.push_front(line);
29 while queue.len() > MAX_EVENTS {
30 let _ = queue.pop_back();
31 }
32 })?;
33 }
34
35 loop {
36 draw_dashboard(&api, &events)?;
37 thread::sleep(Duration::from_millis(350));
38 }
39}examples/clipboard_monitor.rs (line 6)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let mut api = ContextApi::new()?;
7
8 api.subscribe(SignalType::Clipboard, |signal| {
9 println!(
10 "clipboard changed: type={:?}, bytes={}, source={}, sensitive={}, command={}",
11 signal.content_type,
12 signal.size_bytes,
13 signal.source_app,
14 signal.likely_sensitive,
15 signal.likely_command
16 );
17 })?;
18
19 api.request_permission(
20 PermissionRequest::new(
21 Capability::ReadClipboardContent,
22 Scope::Session,
23 "Show how explicit content access works in the example",
24 )
25 .with_ttl(Duration::from_secs(300)),
26 )?;
27
28 if let Ok(content) = api.read_clipboard_content() {
29 println!("initial clipboard preview: {}", content.redacted_preview());
30 }
31
32 println!("Monitoring clipboard changes. Press Ctrl+C to exit.");
33 api.run_with_signals()?;
34 Ok(())
35}examples/assistant_context_adapter.rs (line 23)
22fn main() -> Result<(), Box<dyn std::error::Error>> {
23 let mut api = ContextApi::new()?;
24 let state = Arc::new(Mutex::new(AdapterState::default()));
25
26 println!("LCSA Assistant Adapter Demo");
27 println!("Type a developer task and press Enter.");
28 println!("Commands: :help :context :grant-content :revoke-content :quit");
29 println!();
30
31 attach_signal_subscriptions(&mut api, Arc::clone(&state))?;
32
33 let stdin = io::stdin();
34 loop {
35 print!("ask> ");
36 io::stdout().flush()?;
37
38 let mut input = String::new();
39 stdin.read_line(&mut input)?;
40 let input = input.trim();
41 if input.is_empty() {
42 continue;
43 }
44
45 match input {
46 ":help" => print_help(),
47 ":context" => print_context_snapshot(&api, &state),
48 ":grant-content" => grant_clipboard_content(&mut api)?,
49 ":revoke-content" => {
50 let revoked = api.revoke_permission(Capability::ReadClipboardContent);
51 println!("clipboard content access revoked={revoked}");
52 }
53 ":quit" | ":exit" => break,
54 task => print_augmented_packet(&api, &state, task),
55 }
56 }
57
58 Ok(())
59}Sourcepub fn builder() -> ContextApiBuilder
pub fn builder() -> ContextApiBuilder
Examples found in repository?
examples/enveloped_clipboard_monitor.rs (line 9)
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9 let mut api = ContextApi::builder()
10 .device_context(DeviceContext {
11 device_id: "desktop:devbox".to_string(),
12 device_name: "devbox".to_string(),
13 platform: Platform::Linux,
14 device_class: DeviceClass::Desktop,
15 os_version: None,
16 })
17 .application_context(ApplicationContext {
18 app_id: "lcsa-demo".to_string(),
19 app_name: "lcsa-demo".to_string(),
20 app_version: Some("0.1.0".to_string()),
21 })
22 .build()?;
23
24 api.request_permission(
25 PermissionRequest::new(
26 Capability::ReadClipboardContent,
27 Scope::Session,
28 "Demonstrate cross-device envelopes plus gated content access",
29 )
30 .with_ttl(Duration::from_secs(300)),
31 )?;
32
33 api.subscribe_enveloped(SignalType::Clipboard, |envelope| {
34 println!(
35 "envelope={} device={} app={} source={:?}",
36 envelope.signal_id,
37 envelope.device.device_id,
38 envelope.application.app_id,
39 envelope.source
40 );
41 })?;
42
43 println!("Monitoring enveloped clipboard signals. Press Ctrl+C to exit.");
44 api.run_with_signals()?;
45 Ok(())
46}Sourcepub fn device_context(&self) -> &DeviceContext
pub fn device_context(&self) -> &DeviceContext
Examples found in repository?
examples/runtime_capabilities.rs (line 8)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let api = ContextApi::new()?;
5
6 println!(
7 "device={} platform={:?}",
8 api.device_context().device_id,
9 api.device_context().platform
10 );
11
12 for signal_type in [
13 SignalType::Clipboard,
14 SignalType::Selection,
15 SignalType::Focus,
16 ] {
17 println!("{signal_type:?}: {:?}", api.signal_support(signal_type));
18 }
19
20 println!("supported={:?}", api.supported_signals());
21 Ok(())
22}More examples
examples/context_live_view.rs (line 49)
41fn draw_dashboard(
42 api: &ContextApi,
43 events: &Arc<Mutex<VecDeque<String>>>,
44) -> Result<(), Box<dyn std::error::Error>> {
45 print!("\x1B[2J\x1B[H");
46 println!("LCSA Live View");
47 println!(
48 "device={} platform={:?}",
49 api.device_context().device_name,
50 api.device_context().platform
51 );
52 println!();
53 println!("Signal Capabilities");
54 for signal_type in [
55 SignalType::Clipboard,
56 SignalType::Selection,
57 SignalType::Focus,
58 ] {
59 println!(
60 " {:<10} {:?}",
61 format!("{signal_type:?}"),
62 api.signal_support(signal_type)
63 );
64 }
65 println!();
66 println!("Recent Context Events");
67 println!(" (copy text, select text, or switch windows to see updates)");
68
69 let queue = events.lock().expect("event queue mutex poisoned");
70 if queue.is_empty() {
71 println!(" - waiting for signals...");
72 } else {
73 for line in queue.iter() {
74 println!(" - {line}");
75 }
76 }
77
78 io::stdout().flush()?;
79 Ok(())
80}examples/assistant_context_adapter.rs (line 192)
183fn build_context_packet(
184 api: &ContextApi,
185 snapshot: &AdapterState,
186 task: &str,
187 clipboard_preview: Option<String>,
188) -> serde_json::Value {
189 json!({
190 "task": task,
191 "device": {
192 "id": api.device_context().device_id,
193 "platform": format!("{:?}", api.device_context().platform),
194 },
195 "capabilities": {
196 "clipboard": format!("{:?}", api.signal_support(SignalType::Clipboard)),
197 "selection": format!("{:?}", api.signal_support(SignalType::Selection)),
198 "focus": format!("{:?}", api.signal_support(SignalType::Focus)),
199 "clipboard_content_access": api.can_access(Capability::ReadClipboardContent),
200 },
201 "context": {
202 "recent_focus": snapshot.recent_focus,
203 "recent_selection": snapshot.recent_selection,
204 "recent_clipboard_signal": snapshot.recent_clipboard,
205 "clipboard_content_preview": clipboard_preview,
206 "recent_events": snapshot.recent_events.iter().take(8).cloned().collect::<Vec<_>>(),
207 },
208 "hints": derive_hints(snapshot),
209 })
210}pub fn application_context(&self) -> &ApplicationContext
Sourcepub fn subscribe_enveloped<F>(
&mut self,
signal_type: SignalType,
handler: F,
) -> Result<SubscriptionHandle, Error>
pub fn subscribe_enveloped<F>( &mut self, signal_type: SignalType, handler: F, ) -> Result<SubscriptionHandle, Error>
Subscribe to signals with envelope wrapping (includes device/app context). The handler is called on the event bus dispatcher thread.
Examples found in repository?
examples/assistant_context_adapter.rs (lines 73-75)
61fn attach_signal_subscriptions(
62 api: &mut ContextApi,
63 state: Arc<Mutex<AdapterState>>,
64) -> Result<(), Box<dyn std::error::Error>> {
65 for signal_type in [
66 SignalType::Clipboard,
67 SignalType::Selection,
68 SignalType::Focus,
69 ] {
70 match api.signal_support(signal_type) {
71 SignalSupport::Supported => {
72 let state = Arc::clone(&state);
73 api.subscribe_enveloped(signal_type, move |envelope| {
74 ingest_envelope(&state, envelope);
75 })?;
76 println!("{signal_type:?}: subscribed");
77 }
78 unsupported => {
79 println!("{signal_type:?}: {unsupported:?}");
80 }
81 }
82 }
83
84 println!();
85 Ok(())
86}More examples
examples/context_live_view.rs (lines 25-32)
11fn main() -> Result<(), Box<dyn std::error::Error>> {
12 let mut api = ContextApi::new()?;
13 let events = Arc::new(Mutex::new(VecDeque::<String>::new()));
14
15 for signal_type in [
16 SignalType::Clipboard,
17 SignalType::Selection,
18 SignalType::Focus,
19 ] {
20 if !matches!(api.signal_support(signal_type), SignalSupport::Supported) {
21 continue;
22 }
23
24 let events = Arc::clone(&events);
25 api.subscribe_enveloped(signal_type, move |envelope| {
26 let line = summarize_envelope(&envelope);
27 let mut queue = events.lock().expect("event queue mutex poisoned");
28 queue.push_front(line);
29 while queue.len() > MAX_EVENTS {
30 let _ = queue.pop_back();
31 }
32 })?;
33 }
34
35 loop {
36 draw_dashboard(&api, &events)?;
37 thread::sleep(Duration::from_millis(350));
38 }
39}examples/enveloped_clipboard_monitor.rs (lines 33-41)
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9 let mut api = ContextApi::builder()
10 .device_context(DeviceContext {
11 device_id: "desktop:devbox".to_string(),
12 device_name: "devbox".to_string(),
13 platform: Platform::Linux,
14 device_class: DeviceClass::Desktop,
15 os_version: None,
16 })
17 .application_context(ApplicationContext {
18 app_id: "lcsa-demo".to_string(),
19 app_name: "lcsa-demo".to_string(),
20 app_version: Some("0.1.0".to_string()),
21 })
22 .build()?;
23
24 api.request_permission(
25 PermissionRequest::new(
26 Capability::ReadClipboardContent,
27 Scope::Session,
28 "Demonstrate cross-device envelopes plus gated content access",
29 )
30 .with_ttl(Duration::from_secs(300)),
31 )?;
32
33 api.subscribe_enveloped(SignalType::Clipboard, |envelope| {
34 println!(
35 "envelope={} device={} app={} source={:?}",
36 envelope.signal_id,
37 envelope.device.device_id,
38 envelope.application.app_id,
39 envelope.source
40 );
41 })?;
42
43 println!("Monitoring enveloped clipboard signals. Press Ctrl+C to exit.");
44 api.run_with_signals()?;
45 Ok(())
46}Sourcepub fn read_clipboard_content(&self) -> Result<ClipboardContent, Error>
pub fn read_clipboard_content(&self) -> Result<ClipboardContent, Error>
Examples found in repository?
examples/assistant_context_adapter.rs (line 162)
160fn print_augmented_packet(api: &ContextApi, state: &Arc<Mutex<AdapterState>>, task: &str) {
161 let snapshot = state.lock().expect("adapter state mutex poisoned").clone();
162 let clipboard_preview = api.read_clipboard_content().ok().map(|content| {
163 // The preview intentionally keeps sensitive content redacted when needed.
164 content.redacted_preview()
165 });
166
167 let packet = build_context_packet(api, &snapshot, task, clipboard_preview.clone());
168 println!();
169 println!("=== Augmented Context Packet ===");
170 println!(
171 "{}",
172 serde_json::to_string_pretty(&packet).unwrap_or_default()
173 );
174 println!();
175 println!("=== Prompt Preview ===");
176 println!(
177 "{}",
178 build_prompt_preview(task, &snapshot, clipboard_preview)
179 );
180 println!();
181}More examples
examples/clipboard_monitor.rs (line 28)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let mut api = ContextApi::new()?;
7
8 api.subscribe(SignalType::Clipboard, |signal| {
9 println!(
10 "clipboard changed: type={:?}, bytes={}, source={}, sensitive={}, command={}",
11 signal.content_type,
12 signal.size_bytes,
13 signal.source_app,
14 signal.likely_sensitive,
15 signal.likely_command
16 );
17 })?;
18
19 api.request_permission(
20 PermissionRequest::new(
21 Capability::ReadClipboardContent,
22 Scope::Session,
23 "Show how explicit content access works in the example",
24 )
25 .with_ttl(Duration::from_secs(300)),
26 )?;
27
28 if let Ok(content) = api.read_clipboard_content() {
29 println!("initial clipboard preview: {}", content.redacted_preview());
30 }
31
32 println!("Monitoring clipboard changes. Press Ctrl+C to exit.");
33 api.run_with_signals()?;
34 Ok(())
35}pub fn is_signal_supported(&self, signal_type: SignalType) -> bool
Sourcepub fn signal_support(&self, signal_type: SignalType) -> SignalSupport
pub fn signal_support(&self, signal_type: SignalType) -> SignalSupport
Examples found in repository?
examples/runtime_capabilities.rs (line 17)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let api = ContextApi::new()?;
5
6 println!(
7 "device={} platform={:?}",
8 api.device_context().device_id,
9 api.device_context().platform
10 );
11
12 for signal_type in [
13 SignalType::Clipboard,
14 SignalType::Selection,
15 SignalType::Focus,
16 ] {
17 println!("{signal_type:?}: {:?}", api.signal_support(signal_type));
18 }
19
20 println!("supported={:?}", api.supported_signals());
21 Ok(())
22}More examples
examples/assistant_context_adapter.rs (line 70)
61fn attach_signal_subscriptions(
62 api: &mut ContextApi,
63 state: Arc<Mutex<AdapterState>>,
64) -> Result<(), Box<dyn std::error::Error>> {
65 for signal_type in [
66 SignalType::Clipboard,
67 SignalType::Selection,
68 SignalType::Focus,
69 ] {
70 match api.signal_support(signal_type) {
71 SignalSupport::Supported => {
72 let state = Arc::clone(&state);
73 api.subscribe_enveloped(signal_type, move |envelope| {
74 ingest_envelope(&state, envelope);
75 })?;
76 println!("{signal_type:?}: subscribed");
77 }
78 unsupported => {
79 println!("{signal_type:?}: {unsupported:?}");
80 }
81 }
82 }
83
84 println!();
85 Ok(())
86}
87
88fn ingest_envelope(state: &Arc<Mutex<AdapterState>>, envelope: SignalEnvelope) {
89 let mut state = state.lock().expect("adapter state mutex poisoned");
90 let ts = unix_secs(envelope.emitted_at);
91
92 match envelope.payload {
93 StructuralSignal::Clipboard(signal) => {
94 let summary = format!(
95 "clipboard type={:?} bytes={} sensitive={} command={} source={}",
96 signal.content_type,
97 signal.size_bytes,
98 signal.likely_sensitive,
99 signal.likely_command,
100 signal.source_app
101 );
102 state.recent_clipboard = Some(summary.clone());
103 push_event(&mut state.recent_events, format!("{ts} {summary}"));
104 }
105 StructuralSignal::Selection(signal) => {
106 let preview = format!(
107 "selection type={:?} bytes={} editable={} source={}",
108 signal.content_type, signal.size_bytes, signal.is_editable, signal.source_app
109 );
110 state.recent_selection = Some(preview.clone());
111 push_event(&mut state.recent_events, format!("{ts} {preview}"));
112 }
113 StructuralSignal::Focus(signal) => {
114 let summary = format!(
115 "focus target={:?} editable={} source={}",
116 signal.target, signal.is_editable, signal.source_app
117 );
118 state.recent_focus = Some(summary.clone());
119 push_event(&mut state.recent_events, format!("{ts} {summary}"));
120 }
121 StructuralSignal::Filesystem(signal) => {
122 push_event(
123 &mut state.recent_events,
124 format!(
125 "{ts} filesystem {} {:?}",
126 signal.event_name(),
127 signal.action
128 ),
129 );
130 }
131 }
132}
133
134fn print_help() {
135 println!(":context show current signal snapshot");
136 println!(":grant-content grant clipboard content access for this session");
137 println!(":revoke-content revoke clipboard content access");
138 println!(":quit exit");
139}
140
141fn print_context_snapshot(api: &ContextApi, state: &Arc<Mutex<AdapterState>>) {
142 let snapshot = state.lock().expect("adapter state mutex poisoned").clone();
143 let packet = build_context_packet(api, &snapshot, "(snapshot)", None);
144 println!(
145 "{}",
146 serde_json::to_string_pretty(&packet).unwrap_or_default()
147 );
148}
149
150fn grant_clipboard_content(api: &mut ContextApi) -> Result<(), Box<dyn std::error::Error>> {
151 api.request_permission(PermissionRequest::new(
152 Capability::ReadClipboardContent,
153 Scope::Session,
154 "Enable content-level context in assistant adapter demo",
155 ))?;
156 println!("clipboard content access granted for current session");
157 Ok(())
158}
159
160fn print_augmented_packet(api: &ContextApi, state: &Arc<Mutex<AdapterState>>, task: &str) {
161 let snapshot = state.lock().expect("adapter state mutex poisoned").clone();
162 let clipboard_preview = api.read_clipboard_content().ok().map(|content| {
163 // The preview intentionally keeps sensitive content redacted when needed.
164 content.redacted_preview()
165 });
166
167 let packet = build_context_packet(api, &snapshot, task, clipboard_preview.clone());
168 println!();
169 println!("=== Augmented Context Packet ===");
170 println!(
171 "{}",
172 serde_json::to_string_pretty(&packet).unwrap_or_default()
173 );
174 println!();
175 println!("=== Prompt Preview ===");
176 println!(
177 "{}",
178 build_prompt_preview(task, &snapshot, clipboard_preview)
179 );
180 println!();
181}
182
183fn build_context_packet(
184 api: &ContextApi,
185 snapshot: &AdapterState,
186 task: &str,
187 clipboard_preview: Option<String>,
188) -> serde_json::Value {
189 json!({
190 "task": task,
191 "device": {
192 "id": api.device_context().device_id,
193 "platform": format!("{:?}", api.device_context().platform),
194 },
195 "capabilities": {
196 "clipboard": format!("{:?}", api.signal_support(SignalType::Clipboard)),
197 "selection": format!("{:?}", api.signal_support(SignalType::Selection)),
198 "focus": format!("{:?}", api.signal_support(SignalType::Focus)),
199 "clipboard_content_access": api.can_access(Capability::ReadClipboardContent),
200 },
201 "context": {
202 "recent_focus": snapshot.recent_focus,
203 "recent_selection": snapshot.recent_selection,
204 "recent_clipboard_signal": snapshot.recent_clipboard,
205 "clipboard_content_preview": clipboard_preview,
206 "recent_events": snapshot.recent_events.iter().take(8).cloned().collect::<Vec<_>>(),
207 },
208 "hints": derive_hints(snapshot),
209 })
210}examples/context_live_view.rs (line 20)
11fn main() -> Result<(), Box<dyn std::error::Error>> {
12 let mut api = ContextApi::new()?;
13 let events = Arc::new(Mutex::new(VecDeque::<String>::new()));
14
15 for signal_type in [
16 SignalType::Clipboard,
17 SignalType::Selection,
18 SignalType::Focus,
19 ] {
20 if !matches!(api.signal_support(signal_type), SignalSupport::Supported) {
21 continue;
22 }
23
24 let events = Arc::clone(&events);
25 api.subscribe_enveloped(signal_type, move |envelope| {
26 let line = summarize_envelope(&envelope);
27 let mut queue = events.lock().expect("event queue mutex poisoned");
28 queue.push_front(line);
29 while queue.len() > MAX_EVENTS {
30 let _ = queue.pop_back();
31 }
32 })?;
33 }
34
35 loop {
36 draw_dashboard(&api, &events)?;
37 thread::sleep(Duration::from_millis(350));
38 }
39}
40
41fn draw_dashboard(
42 api: &ContextApi,
43 events: &Arc<Mutex<VecDeque<String>>>,
44) -> Result<(), Box<dyn std::error::Error>> {
45 print!("\x1B[2J\x1B[H");
46 println!("LCSA Live View");
47 println!(
48 "device={} platform={:?}",
49 api.device_context().device_name,
50 api.device_context().platform
51 );
52 println!();
53 println!("Signal Capabilities");
54 for signal_type in [
55 SignalType::Clipboard,
56 SignalType::Selection,
57 SignalType::Focus,
58 ] {
59 println!(
60 " {:<10} {:?}",
61 format!("{signal_type:?}"),
62 api.signal_support(signal_type)
63 );
64 }
65 println!();
66 println!("Recent Context Events");
67 println!(" (copy text, select text, or switch windows to see updates)");
68
69 let queue = events.lock().expect("event queue mutex poisoned");
70 if queue.is_empty() {
71 println!(" - waiting for signals...");
72 } else {
73 for line in queue.iter() {
74 println!(" - {line}");
75 }
76 }
77
78 io::stdout().flush()?;
79 Ok(())
80}Sourcepub fn supported_signals(&self) -> Vec<SignalType>
pub fn supported_signals(&self) -> Vec<SignalType>
Examples found in repository?
examples/runtime_capabilities.rs (line 20)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let api = ContextApi::new()?;
5
6 println!(
7 "device={} platform={:?}",
8 api.device_context().device_id,
9 api.device_context().platform
10 );
11
12 for signal_type in [
13 SignalType::Clipboard,
14 SignalType::Selection,
15 SignalType::Focus,
16 ] {
17 println!("{signal_type:?}: {:?}", api.signal_support(signal_type));
18 }
19
20 println!("supported={:?}", api.supported_signals());
21 Ok(())
22}Sourcepub fn subscribe<F>(
&mut self,
signal_type: SignalType,
handler: F,
) -> Result<SubscriptionHandle, Error>
pub fn subscribe<F>( &mut self, signal_type: SignalType, handler: F, ) -> Result<SubscriptionHandle, Error>
Subscribe to clipboard signals only. The handler is called on the event bus dispatcher thread.
Examples found in repository?
examples/clipboard_monitor.rs (lines 8-17)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let mut api = ContextApi::new()?;
7
8 api.subscribe(SignalType::Clipboard, |signal| {
9 println!(
10 "clipboard changed: type={:?}, bytes={}, source={}, sensitive={}, command={}",
11 signal.content_type,
12 signal.size_bytes,
13 signal.source_app,
14 signal.likely_sensitive,
15 signal.likely_command
16 );
17 })?;
18
19 api.request_permission(
20 PermissionRequest::new(
21 Capability::ReadClipboardContent,
22 Scope::Session,
23 "Show how explicit content access works in the example",
24 )
25 .with_ttl(Duration::from_secs(300)),
26 )?;
27
28 if let Ok(content) = api.read_clipboard_content() {
29 println!("initial clipboard preview: {}", content.redacted_preview());
30 }
31
32 println!("Monitoring clipboard changes. Press Ctrl+C to exit.");
33 api.run_with_signals()?;
34 Ok(())
35}pub fn unsubscribe(&mut self, handle: SubscriptionHandle)
Sourcepub fn request_permission(
&mut self,
request: PermissionRequest,
) -> Result<Grant, Error>
pub fn request_permission( &mut self, request: PermissionRequest, ) -> Result<Grant, Error>
Examples found in repository?
More examples
examples/clipboard_monitor.rs (lines 19-26)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let mut api = ContextApi::new()?;
7
8 api.subscribe(SignalType::Clipboard, |signal| {
9 println!(
10 "clipboard changed: type={:?}, bytes={}, source={}, sensitive={}, command={}",
11 signal.content_type,
12 signal.size_bytes,
13 signal.source_app,
14 signal.likely_sensitive,
15 signal.likely_command
16 );
17 })?;
18
19 api.request_permission(
20 PermissionRequest::new(
21 Capability::ReadClipboardContent,
22 Scope::Session,
23 "Show how explicit content access works in the example",
24 )
25 .with_ttl(Duration::from_secs(300)),
26 )?;
27
28 if let Ok(content) = api.read_clipboard_content() {
29 println!("initial clipboard preview: {}", content.redacted_preview());
30 }
31
32 println!("Monitoring clipboard changes. Press Ctrl+C to exit.");
33 api.run_with_signals()?;
34 Ok(())
35}examples/enveloped_clipboard_monitor.rs (lines 24-31)
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9 let mut api = ContextApi::builder()
10 .device_context(DeviceContext {
11 device_id: "desktop:devbox".to_string(),
12 device_name: "devbox".to_string(),
13 platform: Platform::Linux,
14 device_class: DeviceClass::Desktop,
15 os_version: None,
16 })
17 .application_context(ApplicationContext {
18 app_id: "lcsa-demo".to_string(),
19 app_name: "lcsa-demo".to_string(),
20 app_version: Some("0.1.0".to_string()),
21 })
22 .build()?;
23
24 api.request_permission(
25 PermissionRequest::new(
26 Capability::ReadClipboardContent,
27 Scope::Session,
28 "Demonstrate cross-device envelopes plus gated content access",
29 )
30 .with_ttl(Duration::from_secs(300)),
31 )?;
32
33 api.subscribe_enveloped(SignalType::Clipboard, |envelope| {
34 println!(
35 "envelope={} device={} app={} source={:?}",
36 envelope.signal_id,
37 envelope.device.device_id,
38 envelope.application.app_id,
39 envelope.source
40 );
41 })?;
42
43 println!("Monitoring enveloped clipboard signals. Press Ctrl+C to exit.");
44 api.run_with_signals()?;
45 Ok(())
46}Sourcepub fn revoke_permission(&mut self, capability: Capability) -> bool
pub fn revoke_permission(&mut self, capability: Capability) -> bool
Examples found in repository?
examples/assistant_context_adapter.rs (line 50)
22fn main() -> Result<(), Box<dyn std::error::Error>> {
23 let mut api = ContextApi::new()?;
24 let state = Arc::new(Mutex::new(AdapterState::default()));
25
26 println!("LCSA Assistant Adapter Demo");
27 println!("Type a developer task and press Enter.");
28 println!("Commands: :help :context :grant-content :revoke-content :quit");
29 println!();
30
31 attach_signal_subscriptions(&mut api, Arc::clone(&state))?;
32
33 let stdin = io::stdin();
34 loop {
35 print!("ask> ");
36 io::stdout().flush()?;
37
38 let mut input = String::new();
39 stdin.read_line(&mut input)?;
40 let input = input.trim();
41 if input.is_empty() {
42 continue;
43 }
44
45 match input {
46 ":help" => print_help(),
47 ":context" => print_context_snapshot(&api, &state),
48 ":grant-content" => grant_clipboard_content(&mut api)?,
49 ":revoke-content" => {
50 let revoked = api.revoke_permission(Capability::ReadClipboardContent);
51 println!("clipboard content access revoked={revoked}");
52 }
53 ":quit" | ":exit" => break,
54 task => print_augmented_packet(&api, &state, task),
55 }
56 }
57
58 Ok(())
59}Sourcepub fn can_access(&self, capability: Capability) -> bool
pub fn can_access(&self, capability: Capability) -> bool
Examples found in repository?
examples/assistant_context_adapter.rs (line 199)
183fn build_context_packet(
184 api: &ContextApi,
185 snapshot: &AdapterState,
186 task: &str,
187 clipboard_preview: Option<String>,
188) -> serde_json::Value {
189 json!({
190 "task": task,
191 "device": {
192 "id": api.device_context().device_id,
193 "platform": format!("{:?}", api.device_context().platform),
194 },
195 "capabilities": {
196 "clipboard": format!("{:?}", api.signal_support(SignalType::Clipboard)),
197 "selection": format!("{:?}", api.signal_support(SignalType::Selection)),
198 "focus": format!("{:?}", api.signal_support(SignalType::Focus)),
199 "clipboard_content_access": api.can_access(Capability::ReadClipboardContent),
200 },
201 "context": {
202 "recent_focus": snapshot.recent_focus,
203 "recent_selection": snapshot.recent_selection,
204 "recent_clipboard_signal": snapshot.recent_clipboard,
205 "clipboard_content_preview": clipboard_preview,
206 "recent_events": snapshot.recent_events.iter().take(8).cloned().collect::<Vec<_>>(),
207 },
208 "hints": derive_hints(snapshot),
209 })
210}Sourcepub fn is_shutdown(&self) -> bool
pub fn is_shutdown(&self) -> bool
Check if shutdown has been requested.
Sourcepub fn run_with_signals(&self) -> Result<(), Error>
pub fn run_with_signals(&self) -> Result<(), Error>
Run with Unix signal handling (SIGINT, SIGTERM). This method blocks until a signal is received or shutdown() is called.
Examples found in repository?
examples/clipboard_monitor.rs (line 33)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let mut api = ContextApi::new()?;
7
8 api.subscribe(SignalType::Clipboard, |signal| {
9 println!(
10 "clipboard changed: type={:?}, bytes={}, source={}, sensitive={}, command={}",
11 signal.content_type,
12 signal.size_bytes,
13 signal.source_app,
14 signal.likely_sensitive,
15 signal.likely_command
16 );
17 })?;
18
19 api.request_permission(
20 PermissionRequest::new(
21 Capability::ReadClipboardContent,
22 Scope::Session,
23 "Show how explicit content access works in the example",
24 )
25 .with_ttl(Duration::from_secs(300)),
26 )?;
27
28 if let Ok(content) = api.read_clipboard_content() {
29 println!("initial clipboard preview: {}", content.redacted_preview());
30 }
31
32 println!("Monitoring clipboard changes. Press Ctrl+C to exit.");
33 api.run_with_signals()?;
34 Ok(())
35}More examples
examples/enveloped_clipboard_monitor.rs (line 44)
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9 let mut api = ContextApi::builder()
10 .device_context(DeviceContext {
11 device_id: "desktop:devbox".to_string(),
12 device_name: "devbox".to_string(),
13 platform: Platform::Linux,
14 device_class: DeviceClass::Desktop,
15 os_version: None,
16 })
17 .application_context(ApplicationContext {
18 app_id: "lcsa-demo".to_string(),
19 app_name: "lcsa-demo".to_string(),
20 app_version: Some("0.1.0".to_string()),
21 })
22 .build()?;
23
24 api.request_permission(
25 PermissionRequest::new(
26 Capability::ReadClipboardContent,
27 Scope::Session,
28 "Demonstrate cross-device envelopes plus gated content access",
29 )
30 .with_ttl(Duration::from_secs(300)),
31 )?;
32
33 api.subscribe_enveloped(SignalType::Clipboard, |envelope| {
34 println!(
35 "envelope={} device={} app={} source={:?}",
36 envelope.signal_id,
37 envelope.device.device_id,
38 envelope.application.app_id,
39 envelope.source
40 );
41 })?;
42
43 println!("Monitoring enveloped clipboard signals. Press Ctrl+C to exit.");
44 api.run_with_signals()?;
45 Ok(())
46}Auto Trait Implementations§
impl Freeze for ContextApi
impl RefUnwindSafe for ContextApi
impl Send for ContextApi
impl Sync for ContextApi
impl Unpin for ContextApi
impl UnsafeUnpin for ContextApi
impl UnwindSafe for ContextApi
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more