Skip to content

Commit 340e0e3

Browse files
committed
refactor: improve CLI perf with lazy loading
Signed-off-by: Jiaxiao Zhou <duibao55328@gmail.com>
1 parent 2215694 commit 340e0e3

File tree

10 files changed

+396
-35
lines changed

10 files changed

+396
-35
lines changed

.claude/agents/rust-pro.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
name: rust-pro
3+
description: Use this agent to write rust code
4+
model: sonnet
5+
color: orange
6+
---
7+
8+
You are a Rust expert specializing in safe, performant systems programming.
9+
10+
## Focus Areas
11+
12+
- Ownership, borrowing, and lifetime annotations
13+
- Trait design and generic programming
14+
- Async/await with Tokio/async-std
15+
- Safe concurrency with Arc, Mutex, channels
16+
- Error handling with Result and custom errors
17+
- FFI and unsafe code when necessary
18+
19+
## Approach
20+
21+
1. Leverage the type system for correctness
22+
2. Zero-cost abstractions over runtime checks
23+
3. Explicit error handling - no panics in libraries
24+
4. Use iterators over manual loops
25+
5. Minimize unsafe blocks with clear invariants
26+
27+
## Output
28+
29+
- Idiomatic Rust with proper error handling
30+
- Trait implementations with derive macros
31+
- Async code with proper cancellation
32+
- Unit tests and documentation tests
33+
- Benchmarks with criterion.rs
34+
- Cargo.toml with feature flags
35+
36+
Follow clippy lints. Include examples in doc comments.

.claude/settings.local.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(git fetch:*)",
5+
"Bash(git rebase:*)",
6+
"Bash(git add:*)",
7+
"Bash(cargo check:*)",
8+
"Bash(cargo build:*)",
9+
"mcp__wassette__list-components",
10+
"Bash(cargo test:*)",
11+
"Bash(just build)",
12+
"Bash(just test:*)",
13+
"Bash(find:*)",
14+
"Bash(cargo doc:*)"
15+
],
16+
"deny": [],
17+
"ask": [],
18+
"defaultMode": "acceptEdits"
19+
}
20+
}

config.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
binds:
2+
- port: 3000
3+
listeners:
4+
- routes:
5+
- policies:
6+
cors:
7+
allowOrigins:
8+
- "*"
9+
allowHeaders:
10+
- mcp-protocol-version
11+
- content-type
12+
- cache-control
13+
backends:
14+
- mcp:
15+
targets:
16+
- name: wassette
17+
stdio:
18+
cmd: wassette
19+
args: ["serve", "--stdio",]
20+
env:
21+
RUST_LOG: "off"

crates/mcp-server/src/components.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ use wassette::LifecycleManager;
1515
#[instrument(skip(lifecycle_manager))]
1616
pub(crate) async fn get_component_tools(lifecycle_manager: &LifecycleManager) -> Result<Vec<Tool>> {
1717
debug!("Listing components");
18-
let component_ids = lifecycle_manager.list_components().await;
18+
// Use known components (loaded or present on disk) for fast listing
19+
let component_ids = lifecycle_manager.list_components_known().await;
1920

2021
info!(count = component_ids.len(), "Found components");
2122
let mut tools = Vec::new();
@@ -139,7 +140,8 @@ pub async fn handle_list_components(
139140
) -> Result<CallToolResult> {
140141
info!("Listing loaded components");
141142

142-
let component_ids = lifecycle_manager.list_components().await;
143+
// Use known components (loaded or present on disk) for fast listing
144+
let component_ids = lifecycle_manager.list_components_known().await;
143145

144146
let components_info = stream::iter(component_ids)
145147
.map(|id| async move {

crates/mcp-server/src/tools.rs

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -463,14 +463,11 @@ pub async fn handle_get_policy(
463463

464464
info!("Getting policy for component {}", component_id);
465465

466-
// First check if the component exists
467-
let component_exists = lifecycle_manager
468-
.get_component(component_id)
466+
// Ensure the component is available (compile lazily if needed)
467+
lifecycle_manager
468+
.ensure_component_loaded(component_id)
469469
.await
470-
.is_some();
471-
if !component_exists {
472-
return Err(anyhow::anyhow!("Component not found: {}", component_id));
473-
}
470+
.map_err(|e| anyhow::anyhow!("Component not found: {} ({})", component_id, e))?;
474471

475472
let policy_info = lifecycle_manager.get_policy_info(component_id).await;
476473

@@ -520,6 +517,12 @@ pub async fn handle_grant_storage_permission(
520517

521518
info!("Granting storage permission to component {}", component_id);
522519

520+
// Ensure component is loaded (lazy compile)
521+
lifecycle_manager
522+
.ensure_component_loaded(component_id)
523+
.await
524+
.map_err(|e| anyhow::anyhow!("Component not found: {} ({})", component_id, e))?;
525+
523526
let result = lifecycle_manager
524527
.grant_permission(component_id, "storage", details)
525528
.await;
@@ -570,6 +573,11 @@ pub async fn handle_grant_network_permission(
570573

571574
info!("Granting network permission to component {}", component_id);
572575

576+
lifecycle_manager
577+
.ensure_component_loaded(component_id)
578+
.await
579+
.map_err(|e| anyhow::anyhow!("Component not found: {} ({})", component_id, e))?;
580+
573581
let result = lifecycle_manager
574582
.grant_permission(component_id, "network", details)
575583
.await;
@@ -623,6 +631,11 @@ pub async fn handle_grant_environment_variable_permission(
623631
component_id
624632
);
625633

634+
lifecycle_manager
635+
.ensure_component_loaded(component_id)
636+
.await
637+
.map_err(|e| anyhow::anyhow!("Component not found: {} ({})", component_id, e))?;
638+
626639
let result = lifecycle_manager
627640
.grant_permission(component_id, "environment", details)
628641
.await;
@@ -673,6 +686,11 @@ pub async fn handle_grant_memory_permission(
673686

674687
info!("Granting memory permission to component {}", component_id);
675688

689+
lifecycle_manager
690+
.ensure_component_loaded(component_id)
691+
.await
692+
.map_err(|e| anyhow::anyhow!("Component not found: {} ({})", component_id, e))?;
693+
676694
let result = lifecycle_manager
677695
.grant_permission(component_id, "resource", details)
678696
.await;
@@ -731,6 +749,11 @@ pub async fn handle_revoke_storage_permission(
731749
uri, component_id
732750
);
733751

752+
lifecycle_manager
753+
.ensure_component_loaded(component_id)
754+
.await
755+
.map_err(|e| anyhow::anyhow!("Component not found: {} ({})", component_id, e))?;
756+
734757
let result = lifecycle_manager
735758
.revoke_storage_permission_by_uri(component_id, uri)
736759
.await;
@@ -784,6 +807,11 @@ pub async fn handle_revoke_network_permission(
784807
component_id
785808
);
786809

810+
lifecycle_manager
811+
.ensure_component_loaded(component_id)
812+
.await
813+
.map_err(|e| anyhow::anyhow!("Component not found: {} ({})", component_id, e))?;
814+
787815
let result = lifecycle_manager
788816
.revoke_permission(component_id, "network", details)
789817
.await;
@@ -837,6 +865,11 @@ pub async fn handle_revoke_environment_variable_permission(
837865
component_id
838866
);
839867

868+
lifecycle_manager
869+
.ensure_component_loaded(component_id)
870+
.await
871+
.map_err(|e| anyhow::anyhow!("Component not found: {} ({})", component_id, e))?;
872+
840873
let result = lifecycle_manager
841874
.revoke_permission(component_id, "environment", details)
842875
.await;
@@ -883,6 +916,11 @@ pub async fn handle_reset_permission(
883916

884917
info!("Resetting all permissions for component {}", component_id);
885918

919+
lifecycle_manager
920+
.ensure_component_loaded(component_id)
921+
.await
922+
.map_err(|e| anyhow::anyhow!("Component not found: {} ({})", component_id, e))?;
923+
886924
let result = lifecycle_manager.reset_permission(component_id).await;
887925

888926
match result {

0 commit comments

Comments
 (0)