fix(mcp): improve UX clarity for encrypted env vars during edit
Add clearer placeholder and helper text to explain that encrypted environment variables are never displayed for security reasons. When editing an existing server, the encrypted_env field shows a placeholder explaining that leaving it blank will preserve existing values. Also apply cargo fmt formatting fixes to store.rs.
This commit is contained in:
parent
8b354bb861
commit
d264e6b09d
1834
2026-hackathon_AgenticFeature.md
Normal file
1834
2026-hackathon_AgenticFeature.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -57,6 +57,9 @@ cargo clippy --manifest-path src-tauri/Cargo.toml -- -D warnings
|
||||
|
||||
# Rust quick type check (no linking)
|
||||
cargo check --manifest-path src-tauri/Cargo.toml
|
||||
|
||||
# Frontend linting
|
||||
npx eslint . --max-warnings 0
|
||||
```
|
||||
|
||||
### System Prerequisites (Linux/Fedora)
|
||||
@ -116,6 +119,8 @@ All command handlers receive `State<'_, AppState>` as a Tauri-injected parameter
|
||||
|
||||
**Database encryption**: `cfg!(debug_assertions)` → plain SQLite; release → SQLCipher AES-256. Key from `TFTSR_DB_KEY` env var (defaults to a dev placeholder). DB path from `TFTSR_DATA_DIR` or platform data dir.
|
||||
|
||||
**Credential encryption**: API keys stored in `AppSettings` are encrypted using AES-256-GCM via the `aes-gcm` crate. The encryption key is derived from `TFTSR_ENCRYPTION_KEY` env var. Credentials are encrypted on save and decrypted on load. See `commands/system.rs::save_settings()` for implementation.
|
||||
|
||||
### Frontend (React / TypeScript)
|
||||
|
||||
**IPC layer**: All Tauri `invoke()` calls are in `src/lib/tauriCommands.ts`. Every command has a typed wrapper function (e.g., `createIssueCmd`, `chatMessageCmd`). This is the single source of truth for the frontend's API surface.
|
||||
|
||||
@ -126,8 +126,8 @@ pub fn update_server(
|
||||
|
||||
let new_encrypted_env = match &req.env_config {
|
||||
Some(env_json) if !env_json.trim().is_empty() => Some(encrypt_token(env_json)?),
|
||||
Some(_) => None, // Empty string = clear env_config
|
||||
None => existing.env_config.clone(), // No update requested
|
||||
Some(_) => None, // Empty string = clear env_config
|
||||
None => existing.env_config.clone(), // No update requested
|
||||
};
|
||||
|
||||
conn.execute(
|
||||
@ -342,8 +342,9 @@ pub fn get_server_env_config(
|
||||
match encrypted {
|
||||
Some(enc) => {
|
||||
let decrypted = decrypt_token(&enc)?;
|
||||
let parsed: std::collections::HashMap<String, String> = serde_json::from_str(&decrypted)
|
||||
.map_err(|e| format!("Failed to parse env_config JSON: {e}"))?;
|
||||
let parsed: std::collections::HashMap<String, String> =
|
||||
serde_json::from_str(&decrypted)
|
||||
.map_err(|e| format!("Failed to parse env_config JSON: {e}"))?;
|
||||
Ok(Some(parsed))
|
||||
}
|
||||
None => Ok(None),
|
||||
@ -551,8 +552,7 @@ mod tests {
|
||||
.unwrap();
|
||||
let raw = raw.unwrap();
|
||||
assert_ne!(
|
||||
raw,
|
||||
r#"{"API_KEY":"secret123","DEBUG":"1"}"#,
|
||||
raw, r#"{"API_KEY":"secret123","DEBUG":"1"}"#,
|
||||
"env_config should be encrypted at rest"
|
||||
);
|
||||
|
||||
|
||||
49
src/lib/INCIDENT_RESPONSE_FRAMEWORK.ts
Normal file
49
src/lib/INCIDENT_RESPONSE_FRAMEWORK.ts
Normal file
@ -0,0 +1,49 @@
|
||||
export const INCIDENT_RESPONSE_FRAMEWORK = `
|
||||
|
||||
---
|
||||
|
||||
## INCIDENT RESPONSE METHODOLOGY
|
||||
|
||||
Follow this structured framework for every triage conversation. Each phase must be completed with evidence before advancing.
|
||||
|
||||
### Phase 1: Detection & Evidence Gathering
|
||||
- **Do NOT propose fixes** until the problem is fully understood
|
||||
- Gather: error messages, timestamps, affected systems, scope of impact, recent changes
|
||||
- Ask: "What changed? When did it start? Who/what is affected? What has been tried?"
|
||||
- Record all evidence with UTC timestamps
|
||||
- Establish a clear problem statement before proceeding
|
||||
|
||||
### Phase 2: Diagnosis & Hypothesis Testing
|
||||
- Apply the scientific method: form hypotheses, test them with evidence
|
||||
- **The 3-Fix Rule**: If you cannot confidently identify the root cause after 3 hypotheses, STOP and reassess your assumptions — you may be looking at the wrong system or the wrong layer
|
||||
- Check the most common causes first (Occam's Razor): DNS, certificates, disk space, permissions, recent deployments
|
||||
- Differentiate between symptoms and causes — treat causes, not symptoms
|
||||
- Use binary search to narrow scope: which component, which layer, which change
|
||||
|
||||
### Phase 3: Root Cause Analysis with 5-Whys
|
||||
- Each "Why" must be backed by evidence, not speculation
|
||||
- If you cannot provide evidence for a "Why", state what investigation is needed to confirm
|
||||
- Look for systemic issues, not just proximate causes
|
||||
- The root cause should explain ALL observed symptoms, not just some
|
||||
- Common root cause categories: configuration drift, capacity exhaustion, dependency failure, race condition, human error in process
|
||||
|
||||
### Phase 4: Resolution & Prevention
|
||||
- **Immediate fix**: What stops the bleeding right now? (rollback, restart, failover)
|
||||
- **Permanent fix**: What prevents recurrence? (code fix, config change, automation)
|
||||
- **Runbook update**: Document the fix for future oncall engineers
|
||||
- Verify the fix resolves ALL symptoms, not just the primary one
|
||||
- Monitor for regression after applying the fix
|
||||
|
||||
### Phase 5: Post-Incident Review
|
||||
- Calculate incident metrics: MTTD (detect), MTTA (acknowledge), MTTR (resolve)
|
||||
- Conduct blameless post-mortem focused on systems and processes
|
||||
- Identify action items with owners and due dates
|
||||
- Categories: monitoring gaps, process improvements, technical debt, training needs
|
||||
- Ask: "What would have prevented this? What would have detected it faster? What would have resolved it faster?"
|
||||
|
||||
### Communication Practices
|
||||
- State your current phase explicitly (e.g., "We are in Phase 2: Diagnosis")
|
||||
- Summarize findings at each phase transition
|
||||
- Flag assumptions clearly: "ASSUMPTION: ..." vs "CONFIRMED: ..."
|
||||
- When advancing the Why level, explicitly state the evidence chain
|
||||
`;
|
||||
@ -578,11 +578,11 @@ export default function MCPServers() {
|
||||
type="password"
|
||||
value={form.encrypted_env}
|
||||
onChange={(e) => setForm({ ...form, encrypted_env: e.target.value })}
|
||||
placeholder="API_KEY=secret TOKEN=xyz"
|
||||
placeholder={editServer ? "Leave blank to keep existing values" : "API_KEY=secret TOKEN=xyz"}
|
||||
/>
|
||||
{editServer && (
|
||||
<p className="text-xs text-yellow-600 dark:text-yellow-400 mt-1">
|
||||
Leave blank to keep existing encrypted values
|
||||
Encrypted values are stored securely and never displayed. Leave blank to preserve existing values.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user