feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
import { invoke } from "@tauri-apps/api/core";
|
|
|
|
|
|
|
|
|
|
// ─── Types matching Rust backend models ───────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface ProviderConfig {
|
|
|
|
|
provider_type?: string;
|
|
|
|
|
max_tokens?: number;
|
|
|
|
|
temperature?: number;
|
|
|
|
|
name: string;
|
|
|
|
|
api_url: string;
|
|
|
|
|
api_key: string;
|
|
|
|
|
model: string;
|
2026-04-03 20:45:42 +00:00
|
|
|
custom_endpoint_path?: string;
|
|
|
|
|
custom_auth_header?: string;
|
|
|
|
|
custom_auth_prefix?: string;
|
|
|
|
|
api_format?: string;
|
|
|
|
|
session_id?: string;
|
2026-04-03 21:34:00 +00:00
|
|
|
user_id?: string;
|
2026-04-09 23:05:44 +00:00
|
|
|
use_datastore_upload?: boolean;
|
2026-06-05 13:14:03 +00:00
|
|
|
supports_tool_calling?: boolean;
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface Message {
|
|
|
|
|
role: string;
|
|
|
|
|
content: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface TokenUsage {
|
|
|
|
|
prompt_tokens: number;
|
|
|
|
|
completion_tokens: number;
|
|
|
|
|
total_tokens: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ChatResponse {
|
|
|
|
|
content: string;
|
|
|
|
|
model: string;
|
|
|
|
|
usage?: TokenUsage;
|
2026-06-01 00:36:44 +00:00
|
|
|
/** What was stored in the DB — may be auto-redacted. Use this for display and history. */
|
|
|
|
|
user_message?: string;
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface AnalysisResult {
|
|
|
|
|
summary: string;
|
|
|
|
|
key_findings: string[];
|
|
|
|
|
suggested_why1: string;
|
|
|
|
|
severity_assessment: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ProviderInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
supports_streaming: boolean;
|
|
|
|
|
models: string[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface Issue {
|
|
|
|
|
id: string;
|
|
|
|
|
title: string;
|
|
|
|
|
description: string;
|
|
|
|
|
severity: string;
|
|
|
|
|
status: string;
|
|
|
|
|
category: string;
|
|
|
|
|
source: string;
|
|
|
|
|
created_at: string;
|
|
|
|
|
updated_at: string;
|
|
|
|
|
resolved_at?: string;
|
|
|
|
|
assigned_to: string;
|
|
|
|
|
tags: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface FiveWhyEntry {
|
|
|
|
|
id: string;
|
|
|
|
|
why_number: number;
|
|
|
|
|
question: string;
|
|
|
|
|
answer?: string;
|
|
|
|
|
created_at: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface TimelineEvent {
|
|
|
|
|
id: string;
|
2026-04-19 23:25:53 +00:00
|
|
|
issue_id: string;
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
event_type: string;
|
|
|
|
|
description: string;
|
2026-04-19 23:25:53 +00:00
|
|
|
metadata: string;
|
|
|
|
|
created_at: string;
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface AiConversation {
|
|
|
|
|
id: string;
|
|
|
|
|
issue_id: string;
|
|
|
|
|
provider: string;
|
|
|
|
|
model: string;
|
|
|
|
|
created_at: string;
|
|
|
|
|
title: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ResolutionStep {
|
|
|
|
|
id: string;
|
|
|
|
|
issue_id: string;
|
|
|
|
|
step_order: number;
|
|
|
|
|
why_question: string;
|
|
|
|
|
answer: string;
|
|
|
|
|
evidence: string;
|
|
|
|
|
created_at: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface IssueDetail {
|
|
|
|
|
issue: Issue;
|
|
|
|
|
log_files: LogFile[];
|
2026-04-09 01:03:34 +00:00
|
|
|
image_attachments: ImageAttachment[];
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
resolution_steps: ResolutionStep[];
|
|
|
|
|
conversations: AiConversation[];
|
2026-04-19 23:25:53 +00:00
|
|
|
timeline_events: TimelineEvent[];
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface IssueSummary {
|
|
|
|
|
id: string;
|
|
|
|
|
title: string;
|
|
|
|
|
severity: string;
|
|
|
|
|
status: string;
|
|
|
|
|
category: string;
|
|
|
|
|
created_at: string;
|
|
|
|
|
updated_at: string;
|
|
|
|
|
domain?: string;
|
|
|
|
|
log_count: number;
|
|
|
|
|
step_count: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface IssueListQuery {
|
|
|
|
|
status?: string;
|
|
|
|
|
domain?: string;
|
|
|
|
|
severity?: string;
|
|
|
|
|
search?: string;
|
|
|
|
|
limit?: number;
|
|
|
|
|
offset?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface NewIssue {
|
|
|
|
|
title: string;
|
|
|
|
|
domain: string;
|
|
|
|
|
description?: string;
|
|
|
|
|
severity?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface LogFile {
|
|
|
|
|
id: string;
|
|
|
|
|
issue_id: string;
|
|
|
|
|
file_name: string;
|
|
|
|
|
file_path: string;
|
|
|
|
|
file_size: number;
|
|
|
|
|
mime_type: string;
|
|
|
|
|
content_hash: string;
|
|
|
|
|
uploaded_at: string;
|
|
|
|
|
redacted: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-09 01:03:34 +00:00
|
|
|
export interface ImageAttachment {
|
|
|
|
|
id: string;
|
|
|
|
|
issue_id: string;
|
|
|
|
|
file_name: string;
|
|
|
|
|
file_path: string;
|
|
|
|
|
file_size: number;
|
|
|
|
|
mime_type: string;
|
|
|
|
|
upload_hash: string;
|
|
|
|
|
uploaded_at: string;
|
|
|
|
|
pii_warning_acknowledged: boolean;
|
|
|
|
|
is_paste: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
export interface PiiSpan {
|
|
|
|
|
id: string;
|
|
|
|
|
pii_type: string;
|
|
|
|
|
start: number;
|
|
|
|
|
end: number;
|
|
|
|
|
original: string;
|
|
|
|
|
replacement: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface PiiDetectionResult {
|
|
|
|
|
log_file_id: string;
|
|
|
|
|
detections: PiiSpan[];
|
|
|
|
|
total_pii_found: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface RedactedLogFile {
|
|
|
|
|
id: string;
|
|
|
|
|
original_file_id: string;
|
|
|
|
|
file_name: string;
|
|
|
|
|
file_hash: string;
|
|
|
|
|
redaction_count: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface Document_ {
|
|
|
|
|
id: string;
|
|
|
|
|
issue_id: string;
|
|
|
|
|
doc_type: string;
|
|
|
|
|
title: string;
|
|
|
|
|
content_md: string;
|
|
|
|
|
created_at: number;
|
|
|
|
|
updated_at: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface HardwareInfo {
|
|
|
|
|
total_ram_gb: number;
|
|
|
|
|
cpu_arch: string;
|
|
|
|
|
gpu_vendor?: string;
|
|
|
|
|
gpu_vram_gb?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ModelRecommendation {
|
|
|
|
|
name: string;
|
|
|
|
|
size: string;
|
|
|
|
|
min_ram_gb: number;
|
|
|
|
|
description: string;
|
|
|
|
|
recommended: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface OllamaModel {
|
|
|
|
|
name: string;
|
|
|
|
|
size: number;
|
|
|
|
|
modified: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface OllamaStatus {
|
|
|
|
|
installed: boolean;
|
|
|
|
|
version?: string;
|
|
|
|
|
running: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface InstallGuide {
|
|
|
|
|
platform: string;
|
|
|
|
|
steps: string[];
|
|
|
|
|
url: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface AuditEntry {
|
|
|
|
|
id: string;
|
|
|
|
|
timestamp: string;
|
|
|
|
|
action: string;
|
|
|
|
|
entity_type: string;
|
|
|
|
|
entity_id: string;
|
|
|
|
|
user_id: string;
|
|
|
|
|
details: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface AuditFilter {
|
|
|
|
|
action?: string;
|
|
|
|
|
entity_type?: string;
|
|
|
|
|
entity_id?: string;
|
|
|
|
|
limit?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface AppSettings {
|
|
|
|
|
theme: string;
|
|
|
|
|
ai_providers: ProviderConfig[];
|
|
|
|
|
active_provider?: string;
|
|
|
|
|
default_provider: string;
|
|
|
|
|
default_model: string;
|
|
|
|
|
ollama_url: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── TriageMessage (for UI store, not a DB type) ──────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface TriageMessage {
|
|
|
|
|
id: string;
|
|
|
|
|
issue_id: string;
|
|
|
|
|
role: string;
|
|
|
|
|
content: string;
|
|
|
|
|
why_level?: number;
|
|
|
|
|
created_at: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── AI commands ──────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const analyzeLogsCmd = (issueId: string, logFileIds: string[], providerConfig: ProviderConfig) =>
|
|
|
|
|
invoke<AnalysisResult>("analyze_logs", { issueId, logFileIds, providerConfig });
|
|
|
|
|
|
2026-06-01 00:20:46 +00:00
|
|
|
export const chatMessageCmd = (
|
|
|
|
|
issueId: string,
|
|
|
|
|
message: string,
|
|
|
|
|
logFileIds: string[],
|
|
|
|
|
providerConfig: ProviderConfig,
|
|
|
|
|
systemPrompt?: string
|
|
|
|
|
) =>
|
|
|
|
|
invoke<ChatResponse>("chat_message", {
|
|
|
|
|
issueId,
|
|
|
|
|
message,
|
2026-06-01 01:01:07 +00:00
|
|
|
logFileIds: logFileIds.length > 0 ? logFileIds : undefined,
|
2026-06-01 00:20:46 +00:00
|
|
|
providerConfig,
|
|
|
|
|
systemPrompt: systemPrompt ?? null,
|
|
|
|
|
});
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
|
|
|
|
|
export const listProvidersCmd = () => invoke<ProviderInfo[]>("list_providers");
|
|
|
|
|
|
|
|
|
|
// ─── Analysis / PII commands ──────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const uploadLogFileCmd = (issueId: string, filePath: string) =>
|
|
|
|
|
invoke<LogFile>("upload_log_file", { issueId, filePath });
|
|
|
|
|
|
2026-04-09 23:05:44 +00:00
|
|
|
export const uploadLogFileByContentCmd = (issueId: string, fileName: string, content: string) =>
|
|
|
|
|
invoke<LogFile>("upload_log_file_by_content", { issueId, fileName, content });
|
|
|
|
|
|
2026-04-09 01:03:34 +00:00
|
|
|
export const uploadImageAttachmentCmd = (issueId: string, filePath: string) =>
|
|
|
|
|
invoke<ImageAttachment>("upload_image_attachment", { issueId, filePath });
|
|
|
|
|
|
2026-04-09 23:05:44 +00:00
|
|
|
export const uploadImageAttachmentByContentCmd = (issueId: string, fileName: string, base64Content: string) =>
|
|
|
|
|
invoke<ImageAttachment>("upload_image_attachment_by_content", { issueId, fileName, base64Content });
|
|
|
|
|
|
|
|
|
|
export const uploadFileToDatastoreCmd = (providerConfig: ProviderConfig, filePath: string) =>
|
|
|
|
|
invoke<string>("upload_file_to_datastore", { providerConfig, filePath });
|
|
|
|
|
|
|
|
|
|
export const uploadFileToDatastoreAnyCmd = (providerConfig: ProviderConfig, filePath: string) =>
|
|
|
|
|
invoke<string>("upload_file_to_datastore_any", { providerConfig, filePath });
|
|
|
|
|
|
2026-04-09 01:03:34 +00:00
|
|
|
export const uploadPasteImageCmd = (issueId: string, base64Image: string, mimeType: string) =>
|
|
|
|
|
invoke<ImageAttachment>("upload_paste_image", { issueId, base64Image, mimeType });
|
|
|
|
|
|
|
|
|
|
export const listImageAttachmentsCmd = (issueId: string) =>
|
|
|
|
|
invoke<ImageAttachment[]>("list_image_attachments", { issueId });
|
|
|
|
|
|
|
|
|
|
export const deleteImageAttachmentCmd = (attachmentId: string) =>
|
|
|
|
|
invoke<void>("delete_image_attachment", { attachmentId });
|
|
|
|
|
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
export const detectPiiCmd = (logFileId: string) =>
|
|
|
|
|
invoke<PiiDetectionResult>("detect_pii", { logFileId });
|
|
|
|
|
|
2026-06-01 00:05:51 +00:00
|
|
|
export const scanTextForPiiCmd = (text: string) =>
|
|
|
|
|
invoke<PiiDetectionResult>("scan_text_for_pii", { text });
|
|
|
|
|
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
export const applyRedactionsCmd = (logFileId: string, approvedSpanIds: string[]) =>
|
|
|
|
|
invoke<RedactedLogFile>("apply_redactions", { logFileId, approvedSpanIds });
|
|
|
|
|
|
|
|
|
|
// ─── Issue CRUD ───────────────────────────────────────────────────────────────
|
|
|
|
|
|
2026-03-31 12:46:36 +00:00
|
|
|
export const testProviderConnectionCmd = (providerConfig: ProviderConfig) =>
|
|
|
|
|
invoke<ChatResponse>("test_provider_connection", { providerConfig });
|
|
|
|
|
|
2026-06-05 13:14:03 +00:00
|
|
|
export const detectToolCallingSupportCmd = (providerConfig: ProviderConfig) =>
|
|
|
|
|
invoke<boolean>("detect_tool_calling_support", { providerConfig });
|
|
|
|
|
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
export const createIssueCmd = (newIssue: NewIssue) =>
|
2026-03-30 20:52:43 +00:00
|
|
|
invoke<Issue>("create_issue", {
|
|
|
|
|
title: newIssue.title,
|
|
|
|
|
description: newIssue.description ?? "",
|
|
|
|
|
severity: newIssue.severity ?? "P3",
|
|
|
|
|
category: newIssue.domain,
|
|
|
|
|
});
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
|
|
|
|
|
export const getIssueCmd = (issueId: string) =>
|
|
|
|
|
invoke<IssueDetail>("get_issue", { issueId });
|
|
|
|
|
|
|
|
|
|
export const listIssuesCmd = (query: IssueListQuery) =>
|
2026-03-31 14:09:57 +00:00
|
|
|
invoke<IssueSummary[]>("list_issues", { filter: query });
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
|
|
|
|
|
export const updateIssueCmd = (
|
|
|
|
|
issueId: string,
|
|
|
|
|
updates: { title?: string; status?: string; severity?: string; description?: string; domain?: string }
|
2026-03-31 17:50:39 +00:00
|
|
|
) => invoke<Issue>("update_issue", { issueId, updates });
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
|
|
|
|
|
export const deleteIssueCmd = (issueId: string) =>
|
|
|
|
|
invoke<void>("delete_issue", { issueId });
|
|
|
|
|
|
|
|
|
|
export const searchIssuesCmd = (query: string) =>
|
|
|
|
|
invoke<IssueSummary[]>("search_issues", { query });
|
|
|
|
|
|
2026-03-31 17:50:39 +00:00
|
|
|
export interface IssueMessage {
|
|
|
|
|
id: string;
|
|
|
|
|
conversation_id: string;
|
|
|
|
|
role: string;
|
|
|
|
|
content: string;
|
|
|
|
|
token_count: number;
|
|
|
|
|
created_at: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const getIssueMessagesCmd = (issueId: string) =>
|
|
|
|
|
invoke<IssueMessage[]>("get_issue_messages", { issueId });
|
|
|
|
|
|
|
|
|
|
export const addFiveWhyCmd = (
|
|
|
|
|
issueId: string,
|
|
|
|
|
stepOrder: number,
|
|
|
|
|
whyQuestion: string,
|
|
|
|
|
answer: string,
|
|
|
|
|
evidence: string
|
|
|
|
|
) => invoke<ResolutionStep>("add_five_why", { issueId, stepOrder, whyQuestion, answer, evidence });
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
|
|
|
|
|
export const updateFiveWhyCmd = (entryId: string, answer: string) =>
|
|
|
|
|
invoke<void>("update_five_why", { entryId, answer });
|
|
|
|
|
|
2026-04-19 23:13:47 +00:00
|
|
|
export const addTimelineEventCmd = (issueId: string, eventType: string, description: string, metadata?: string) =>
|
|
|
|
|
invoke<TimelineEvent>("add_timeline_event", { issueId, eventType, description, metadata: metadata ?? null });
|
|
|
|
|
|
|
|
|
|
export const getTimelineEventsCmd = (issueId: string) =>
|
|
|
|
|
invoke<TimelineEvent[]>("get_timeline_events", { issueId });
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
|
|
|
|
|
// ─── Document commands ────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const generateRcaCmd = (issueId: string) => invoke<Document_>("generate_rca", { issueId });
|
|
|
|
|
|
|
|
|
|
export const generatePostmortemCmd = (issueId: string) =>
|
|
|
|
|
invoke<Document_>("generate_postmortem", { issueId });
|
|
|
|
|
|
|
|
|
|
export const updateDocumentCmd = (docId: string, contentMd: string) =>
|
|
|
|
|
invoke<Document_>("update_document", { docId, contentMd });
|
|
|
|
|
|
2026-04-03 13:05:58 +00:00
|
|
|
export const exportDocumentCmd = (docId: string, title: string, contentMd: string, format: string, outputDir: string) =>
|
|
|
|
|
invoke<string>("export_document", { title, contentMd, format, outputDir });
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
|
|
|
|
|
// ─── Ollama & System ──────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const checkOllamaInstalledCmd = () => invoke<OllamaStatus>("check_ollama_installed");
|
|
|
|
|
|
|
|
|
|
export const getOllamaInstallGuideCmd = (platform: string) =>
|
|
|
|
|
invoke<InstallGuide>("get_ollama_install_guide", { platform });
|
|
|
|
|
|
|
|
|
|
export const listOllamaModelsCmd = () => invoke<OllamaModel[]>("list_ollama_models");
|
|
|
|
|
|
|
|
|
|
export const pullOllamaModelCmd = (modelName: string) =>
|
|
|
|
|
invoke<void>("pull_ollama_model", { modelName });
|
|
|
|
|
|
|
|
|
|
export const deleteOllamaModelCmd = (modelName: string) =>
|
|
|
|
|
invoke<void>("delete_ollama_model", { modelName });
|
|
|
|
|
|
|
|
|
|
export const detectHardwareCmd = () => invoke<HardwareInfo>("detect_hardware");
|
|
|
|
|
|
|
|
|
|
export const recommendModelsCmd = () => invoke<ModelRecommendation[]>("recommend_models");
|
|
|
|
|
|
|
|
|
|
// ─── Settings & Audit ─────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const getSettingsCmd = () => invoke<AppSettings>("get_settings");
|
|
|
|
|
|
|
|
|
|
export const updateSettingsCmd = (partialSettings: Partial<AppSettings>) =>
|
|
|
|
|
invoke<AppSettings>("update_settings", { partialSettings });
|
|
|
|
|
|
|
|
|
|
export const getAuditLogCmd = (filter: AuditFilter) =>
|
|
|
|
|
invoke<AuditEntry[]>("get_audit_log", { filter });
|
feat: add OAuth2 frontend UI and complete integration flow
Phase 2.2: OAuth2 flow - FRONTEND COMPLETE ✅
Implemented:
- TypeScript command wrappers in tauriCommands.ts
* initiateOauthCmd(service) -> OAuthInitResponse
* handleOauthCallbackCmd(service, code, stateKey)
* test*ConnectionCmd() for all services
* OAuthInitResponse and ConnectionResult types
- Complete Settings/Integrations UI
* Three integration cards: Confluence, ServiceNow, ADO
* Connect with OAuth2 buttons (Confluence, ADO)
* Basic auth note for ServiceNow
* Configuration inputs: baseUrl, username, projectName, spaceKey
* Test connection buttons with loading states
* Success/error feedback with color-coded messages
* OAuth2 flow instructions for users
- OAuth2 flow in browser
* Opens auth URL in default browser via shell plugin
* User authenticates with service
* Redirected to localhost:8765/callback
* Callback server handles token exchange automatically
* Success message shown to user
- CSP updates in tauri.conf.json
* Added http://localhost:8765 (callback server)
* Added https://auth.atlassian.com (Confluence OAuth)
* Added https://*.atlassian.net (Confluence API)
* Added https://login.microsoftonline.com (ADO OAuth)
* Added https://dev.azure.com (ADO API)
- UI improvements
* Fixed Cancel button variant (ghost instead of secondary)
* Loading spinners with Loader2 icon
* Check/X icons for success/error states
* Disabled states when not configured
* Optimistic UI updates on connect
Frontend + Backend = COMPLETE END-TO-END OAUTH2 FLOW:
1. User goes to Settings → Integrations
2. Enters base URL and config
3. Clicks 'Connect with OAuth2'
4. Browser opens with service auth page
5. User logs in and authorizes
6. Redirected to localhost:8765/callback
7. Token exchanged and encrypted automatically
8. Stored in SQLite credentials table
9. Ready for API calls to external services ✅
TypeScript: All types checked, no errors
Frontend build: ✅ Built in 2.26s
Total lines: ~400 lines of new UI code
Next: Phase 2.3 - Integration API clients (Confluence REST, ServiceNow REST, ADO REST)
2026-04-03 20:04:12 +00:00
|
|
|
|
|
|
|
|
// ─── OAuth & Integrations ─────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface OAuthInitResponse {
|
|
|
|
|
auth_url: string;
|
|
|
|
|
state: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ConnectionResult {
|
|
|
|
|
success: boolean;
|
|
|
|
|
message: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const initiateOauthCmd = (service: string) =>
|
|
|
|
|
invoke<OAuthInitResponse>("initiate_oauth", { service });
|
|
|
|
|
|
|
|
|
|
export const handleOauthCallbackCmd = (service: string, code: string, stateKey: string) =>
|
|
|
|
|
invoke<void>("handle_oauth_callback", { service, code, stateKey });
|
|
|
|
|
|
|
|
|
|
export const testConfluenceConnectionCmd = (baseUrl: string, credentials: Record<string, unknown>) =>
|
|
|
|
|
invoke<ConnectionResult>("test_confluence_connection", { baseUrl, credentials });
|
|
|
|
|
|
|
|
|
|
export const testServiceNowConnectionCmd = (instanceUrl: string, credentials: Record<string, unknown>) =>
|
|
|
|
|
invoke<ConnectionResult>("test_servicenow_connection", { instanceUrl, credentials });
|
|
|
|
|
|
|
|
|
|
export const testAzureDevOpsConnectionCmd = (orgUrl: string, credentials: Record<string, unknown>) =>
|
|
|
|
|
invoke<ConnectionResult>("test_azuredevops_connection", { orgUrl, credentials });
|
2026-04-03 22:26:09 +00:00
|
|
|
|
|
|
|
|
// ─── Webview & Token Authentication ──────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface WebviewAuthResponse {
|
|
|
|
|
success: boolean;
|
|
|
|
|
message: string;
|
|
|
|
|
webview_id: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface TokenAuthRequest {
|
|
|
|
|
service: string;
|
|
|
|
|
token: string;
|
|
|
|
|
token_type: string;
|
|
|
|
|
base_url: string;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-04 14:57:22 +00:00
|
|
|
export interface IntegrationConfig {
|
|
|
|
|
service: string;
|
|
|
|
|
base_url: string;
|
|
|
|
|
username?: string;
|
|
|
|
|
project_name?: string;
|
|
|
|
|
space_key?: string;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-09 01:44:51 +00:00
|
|
|
export const authenticateWithWebviewCmd = (service: string, baseUrl: string, projectName?: string) =>
|
|
|
|
|
invoke<WebviewAuthResponse>("authenticate_with_webview", { service, baseUrl, projectName });
|
2026-04-03 22:26:09 +00:00
|
|
|
|
|
|
|
|
export const extractCookiesFromWebviewCmd = (service: string, webviewId: string) =>
|
|
|
|
|
invoke<ConnectionResult>("extract_cookies_from_webview", { service, webviewId });
|
|
|
|
|
|
|
|
|
|
export const saveManualTokenCmd = (request: TokenAuthRequest) =>
|
|
|
|
|
invoke<ConnectionResult>("save_manual_token", { request });
|
2026-04-04 14:57:22 +00:00
|
|
|
|
|
|
|
|
// ─── Integration Configuration Persistence ────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const saveIntegrationConfigCmd = (config: IntegrationConfig) =>
|
|
|
|
|
invoke<void>("save_integration_config", { config });
|
|
|
|
|
|
|
|
|
|
export const getIntegrationConfigCmd = (service: string) =>
|
|
|
|
|
invoke<IntegrationConfig | null>("get_integration_config", { service });
|
|
|
|
|
|
|
|
|
|
export const getAllIntegrationConfigsCmd = () =>
|
|
|
|
|
invoke<IntegrationConfig[]>("get_all_integration_configs");
|
2026-04-09 01:44:51 +00:00
|
|
|
|
|
|
|
|
// ─── AI Provider Configuration ────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const saveAiProviderCmd = (config: ProviderConfig) =>
|
2026-04-09 19:15:01 +00:00
|
|
|
invoke<void>("save_ai_provider", { provider: config });
|
2026-04-09 01:44:51 +00:00
|
|
|
|
|
|
|
|
export const loadAiProvidersCmd = () =>
|
|
|
|
|
invoke<ProviderConfig[]>("load_ai_providers");
|
|
|
|
|
|
|
|
|
|
export const deleteAiProviderCmd = (name: string) =>
|
|
|
|
|
invoke<void>("delete_ai_provider", { name });
|
2026-04-13 21:08:34 +00:00
|
|
|
|
feat(mcp): add MCP Server Support with TDD implementation
Adds full Model Context Protocol (MCP) server management, enabling the
AI assistant to discover and call tools from external MCP servers during
triage conversations.
Backend (Rust):
- rmcp 1.7.0 dependency (client + stdio + Streamable HTTP transports)
- Migration 018: mcp_servers, mcp_tools, mcp_resources tables with
CHECK constraints for transport_type, auth_type, discovery_status
- src/mcp/ module: models, store, client, adapter, discovery, commands,
transport/{stdio,http}
- AppState gains mcp_connections: Arc<TokioMutex<HashMap<...>>>
- .setup() hook auto-discovers enabled servers at startup
- 8 new Tauri commands wired into invoke_handler
- execute_mcp_tool_call: PII scan + mandatory audit_log before execution
- Auth values encrypted at rest via integrations::auth::encrypt_token();
scrubbed before any frontend response
Frontend:
- MCPServers.tsx settings page (/settings/mcp) with server list,
status badges, Discover Now, Add/Edit modal, enable/disable toggle
- tauriCommands.ts: McpServer, McpTool, McpServerStatus types + 8 cmds
- App.tsx: Plug icon, /settings/mcp route, sidebar nav entry
Tests (TDD): 15 new tests, all green
- 5 migration tests (written before migration, red → green)
- 5 store CRUD + encryption tests
- 5 adapter sanitization + conversion tests
Verification: 185/185 Rust, 94/94 Vitest, clippy -D warnings: 0
2026-05-23 21:23:48 +00:00
|
|
|
// ─── MCP Server types ────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface McpServer {
|
|
|
|
|
id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
url: string;
|
|
|
|
|
transport_type: "stdio" | "http";
|
|
|
|
|
transport_config: string;
|
|
|
|
|
auth_type: "none" | "api_key" | "bearer" | "oauth2";
|
|
|
|
|
auth_value?: string;
|
|
|
|
|
enabled: boolean;
|
|
|
|
|
last_discovered_at?: string;
|
|
|
|
|
discovery_status: "pending" | "connected" | "unreachable" | "error";
|
|
|
|
|
discovery_error?: string;
|
|
|
|
|
created_at: string;
|
|
|
|
|
updated_at: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface McpTool {
|
|
|
|
|
id: string;
|
|
|
|
|
server_id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
tool_key: string;
|
|
|
|
|
description?: string;
|
|
|
|
|
parameters: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface McpResource {
|
|
|
|
|
id: string;
|
|
|
|
|
server_id: string;
|
|
|
|
|
uri: string;
|
|
|
|
|
name?: string;
|
|
|
|
|
description?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface McpServerStatus {
|
|
|
|
|
server_id: string;
|
|
|
|
|
status: "pending" | "connected" | "unreachable" | "error";
|
|
|
|
|
error?: string;
|
|
|
|
|
tool_count: number;
|
|
|
|
|
resource_count: number;
|
|
|
|
|
last_discovered_at?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface CreateMcpServerRequest {
|
|
|
|
|
name: string;
|
|
|
|
|
url: string;
|
|
|
|
|
transport_type: "stdio" | "http";
|
|
|
|
|
transport_config: string;
|
|
|
|
|
auth_type: "none" | "api_key" | "bearer" | "oauth2";
|
|
|
|
|
auth_value?: string;
|
|
|
|
|
enabled: boolean;
|
fix(mcp): add environment variable and HTTP header support for MCP servers
Add dual-mode environment variable support for stdio MCP servers and custom
HTTP headers for HTTP-based MCP servers to enable proper authentication and
configuration.
Backend changes (Rust):
- Add migration 023 for env_config column in mcp_servers table
- Add env_config field to McpServer, CreateMcpServerRequest, UpdateMcpServerRequest
- Encrypt env_config using AES-256-GCM on create/update in store.rs
- Add get_server_env_config() helper to decrypt and parse env vars
- Parse plaintext env from transport_config.env (stdio only)
- Parse custom headers from transport_config.headers (HTTP only)
- Merge plaintext and encrypted env vars (encrypted takes precedence)
- Update connect_stdio() to accept HashMap<String, String> for env vars
- Update connect_http() to accept HashMap<String, String> for headers
- Apply env vars to tokio::process::Command via .env() method
- Add warning for HTTP headers (rmcp v1.7.0 limitation - no .header() method)
- Add comprehensive tests for encryption, merging, and clearing
Frontend changes (TypeScript/React):
- Add env_config field to CreateMcpServerRequest and UpdateMcpServerRequest
- Add plaintext_env, encrypted_env, http_headers to ServerForm interface
- Add parsing helpers: parseEnvVars(), formatEnvVars(), parseHeaders(), formatHeaders()
- Update startEdit() to extract and format env vars/headers from transport_config
- Update handleSave() to build transport_config with env/headers and env_config JSON
- Add conditional UI fields: stdio (plaintext + encrypted env), HTTP (custom headers)
- Use password input type for all sensitive fields
Security:
- Encrypted env vars stored using AES-256-GCM (matching auth_value pattern)
- Plaintext env vars in transport_config for non-sensitive values
- UI masks all env/header fields with password input type
- Never display decrypted values when editing
Fixes inability to configure MCP servers that require environment variables
(e.g., GitHub MCP server with GITHUB_PERSONAL_ACCESS_TOKEN).
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-06-01 13:32:51 +00:00
|
|
|
env_config?: string;
|
feat(mcp): add MCP Server Support with TDD implementation
Adds full Model Context Protocol (MCP) server management, enabling the
AI assistant to discover and call tools from external MCP servers during
triage conversations.
Backend (Rust):
- rmcp 1.7.0 dependency (client + stdio + Streamable HTTP transports)
- Migration 018: mcp_servers, mcp_tools, mcp_resources tables with
CHECK constraints for transport_type, auth_type, discovery_status
- src/mcp/ module: models, store, client, adapter, discovery, commands,
transport/{stdio,http}
- AppState gains mcp_connections: Arc<TokioMutex<HashMap<...>>>
- .setup() hook auto-discovers enabled servers at startup
- 8 new Tauri commands wired into invoke_handler
- execute_mcp_tool_call: PII scan + mandatory audit_log before execution
- Auth values encrypted at rest via integrations::auth::encrypt_token();
scrubbed before any frontend response
Frontend:
- MCPServers.tsx settings page (/settings/mcp) with server list,
status badges, Discover Now, Add/Edit modal, enable/disable toggle
- tauriCommands.ts: McpServer, McpTool, McpServerStatus types + 8 cmds
- App.tsx: Plug icon, /settings/mcp route, sidebar nav entry
Tests (TDD): 15 new tests, all green
- 5 migration tests (written before migration, red → green)
- 5 store CRUD + encryption tests
- 5 adapter sanitization + conversion tests
Verification: 185/185 Rust, 94/94 Vitest, clippy -D warnings: 0
2026-05-23 21:23:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface UpdateMcpServerRequest {
|
|
|
|
|
name?: string;
|
|
|
|
|
url?: string;
|
|
|
|
|
transport_type?: "stdio" | "http";
|
|
|
|
|
transport_config?: string;
|
|
|
|
|
auth_type?: "none" | "api_key" | "bearer" | "oauth2";
|
|
|
|
|
auth_value?: string;
|
|
|
|
|
enabled?: boolean;
|
fix(mcp): add environment variable and HTTP header support for MCP servers
Add dual-mode environment variable support for stdio MCP servers and custom
HTTP headers for HTTP-based MCP servers to enable proper authentication and
configuration.
Backend changes (Rust):
- Add migration 023 for env_config column in mcp_servers table
- Add env_config field to McpServer, CreateMcpServerRequest, UpdateMcpServerRequest
- Encrypt env_config using AES-256-GCM on create/update in store.rs
- Add get_server_env_config() helper to decrypt and parse env vars
- Parse plaintext env from transport_config.env (stdio only)
- Parse custom headers from transport_config.headers (HTTP only)
- Merge plaintext and encrypted env vars (encrypted takes precedence)
- Update connect_stdio() to accept HashMap<String, String> for env vars
- Update connect_http() to accept HashMap<String, String> for headers
- Apply env vars to tokio::process::Command via .env() method
- Add warning for HTTP headers (rmcp v1.7.0 limitation - no .header() method)
- Add comprehensive tests for encryption, merging, and clearing
Frontend changes (TypeScript/React):
- Add env_config field to CreateMcpServerRequest and UpdateMcpServerRequest
- Add plaintext_env, encrypted_env, http_headers to ServerForm interface
- Add parsing helpers: parseEnvVars(), formatEnvVars(), parseHeaders(), formatHeaders()
- Update startEdit() to extract and format env vars/headers from transport_config
- Update handleSave() to build transport_config with env/headers and env_config JSON
- Add conditional UI fields: stdio (plaintext + encrypted env), HTTP (custom headers)
- Use password input type for all sensitive fields
Security:
- Encrypted env vars stored using AES-256-GCM (matching auth_value pattern)
- Plaintext env vars in transport_config for non-sensitive values
- UI masks all env/header fields with password input type
- Never display decrypted values when editing
Fixes inability to configure MCP servers that require environment variables
(e.g., GitHub MCP server with GITHUB_PERSONAL_ACCESS_TOKEN).
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-06-01 13:32:51 +00:00
|
|
|
env_config?: string;
|
feat(mcp): add MCP Server Support with TDD implementation
Adds full Model Context Protocol (MCP) server management, enabling the
AI assistant to discover and call tools from external MCP servers during
triage conversations.
Backend (Rust):
- rmcp 1.7.0 dependency (client + stdio + Streamable HTTP transports)
- Migration 018: mcp_servers, mcp_tools, mcp_resources tables with
CHECK constraints for transport_type, auth_type, discovery_status
- src/mcp/ module: models, store, client, adapter, discovery, commands,
transport/{stdio,http}
- AppState gains mcp_connections: Arc<TokioMutex<HashMap<...>>>
- .setup() hook auto-discovers enabled servers at startup
- 8 new Tauri commands wired into invoke_handler
- execute_mcp_tool_call: PII scan + mandatory audit_log before execution
- Auth values encrypted at rest via integrations::auth::encrypt_token();
scrubbed before any frontend response
Frontend:
- MCPServers.tsx settings page (/settings/mcp) with server list,
status badges, Discover Now, Add/Edit modal, enable/disable toggle
- tauriCommands.ts: McpServer, McpTool, McpServerStatus types + 8 cmds
- App.tsx: Plug icon, /settings/mcp route, sidebar nav entry
Tests (TDD): 15 new tests, all green
- 5 migration tests (written before migration, red → green)
- 5 store CRUD + encryption tests
- 5 adapter sanitization + conversion tests
Verification: 185/185 Rust, 94/94 Vitest, clippy -D warnings: 0
2026-05-23 21:23:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── MCP Commands ─────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export function listMcpServersCmd(): Promise<McpServer[]> {
|
|
|
|
|
return invoke<McpServer[]>("list_mcp_servers");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function createMcpServerCmd(request: CreateMcpServerRequest): Promise<McpServer> {
|
|
|
|
|
return invoke<McpServer>("create_mcp_server", { request });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function updateMcpServerCmd(id: string, request: UpdateMcpServerRequest): Promise<McpServer> {
|
|
|
|
|
return invoke<McpServer>("update_mcp_server", { id, request });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function deleteMcpServerCmd(id: string): Promise<void> {
|
|
|
|
|
return invoke<void>("delete_mcp_server", { id });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function toggleMcpServerCmd(id: string, enabled: boolean): Promise<void> {
|
|
|
|
|
return invoke<void>("toggle_mcp_server", { id, enabled });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function discoverMcpServerCmd(id: string): Promise<McpServerStatus> {
|
|
|
|
|
return invoke<McpServerStatus>("discover_mcp_server", { id });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getMcpServerStatusCmd(id: string): Promise<McpServerStatus> {
|
|
|
|
|
return invoke<McpServerStatus>("get_mcp_server_status", { id });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function initiateMcpOauthCmd(id: string): Promise<void> {
|
|
|
|
|
return invoke<void>("initiate_mcp_oauth", { id });
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-31 18:51:08 +00:00
|
|
|
// ─── Sudo credential commands ─────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface SudoConfigStatus {
|
|
|
|
|
configured: boolean;
|
|
|
|
|
username: string;
|
|
|
|
|
updated_at: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const setSudoPasswordCmd = (password: string, username?: string) =>
|
|
|
|
|
invoke<void>("set_sudo_password", { password, username: username ?? null });
|
|
|
|
|
|
|
|
|
|
export const getSudoConfigStatusCmd = () =>
|
|
|
|
|
invoke<SudoConfigStatus>("get_sudo_config_status");
|
|
|
|
|
|
|
|
|
|
export const testSudoPasswordCmd = () =>
|
|
|
|
|
invoke<boolean>("test_sudo_password");
|
|
|
|
|
|
|
|
|
|
export const clearSudoPasswordCmd = () =>
|
|
|
|
|
invoke<void>("clear_sudo_password");
|
|
|
|
|
|
2026-04-13 21:08:34 +00:00
|
|
|
// ─── System / Version ─────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const getAppVersionCmd = () =>
|
|
|
|
|
invoke<string>("get_app_version");
|
feat: attachment DB storage and cross-incident recall
Store compressed log content and raw image bytes in SQLite so attachments
are self-contained regardless of source file availability on disk.
DB (migrations 020-022):
- log_files.content_compressed BLOB — gzip-compressed extracted text
- image_attachments.image_data BLOB — raw image bytes
- Views v_log_files_with_issue and v_image_attachments_with_issue for
cross-incident queries with joined issue title
Rust backend:
- compress_text / decompress_text helpers (flate2 rust_backend / miniz_oxide)
with 100 MB decompression-bomb guard
- upload_log_file*, upload_log_file_by_content store content_compressed
- upload_image_attachment*, upload_paste_image store image_data
- New commands: get_log_file_content, list_all_log_files (analysis.rs)
- New commands: get_image_attachment_data, list_all_image_attachments (image.rs)
- All commands fall back to file_path for pre-migration records
Frontend:
- LogFileSummary, ImageAttachmentSummary types in tauriCommands.ts
- attachmentStore (Zustand) — loadAttachments, searchAttachments
- History page: Issues tab (existing) + Attachments tab (new)
with log/image tables, search bar, View modals, lazy thumbnails
Tests: 227 Rust (+16 new), 103 frontend (+9 new), tsc clean, clippy clean
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-31 22:55:47 +00:00
|
|
|
|
|
|
|
|
// ─── Attachment cross-incident types ─────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface LogFileSummary {
|
|
|
|
|
id: string;
|
|
|
|
|
issue_id: string;
|
|
|
|
|
issue_title: string;
|
|
|
|
|
file_name: string;
|
|
|
|
|
file_path: string;
|
|
|
|
|
file_size: number;
|
|
|
|
|
mime_type: string;
|
|
|
|
|
content_hash: string;
|
|
|
|
|
uploaded_at: string;
|
|
|
|
|
redacted: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ImageAttachmentSummary {
|
|
|
|
|
id: string;
|
|
|
|
|
issue_id: string;
|
|
|
|
|
issue_title: string;
|
|
|
|
|
file_name: string;
|
|
|
|
|
file_path: string;
|
|
|
|
|
file_size: number;
|
|
|
|
|
mime_type: string;
|
|
|
|
|
upload_hash: string;
|
|
|
|
|
uploaded_at: string;
|
|
|
|
|
pii_warning_acknowledged: boolean;
|
|
|
|
|
is_paste: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Attachment cross-incident commands ───────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const getLogFileContentCmd = (logFileId: string) =>
|
|
|
|
|
invoke<string>("get_log_file_content", { logFileId });
|
|
|
|
|
|
|
|
|
|
export const listAllLogFilesCmd = (search?: string, issueId?: string) =>
|
|
|
|
|
invoke<LogFileSummary[]>("list_all_log_files", {
|
|
|
|
|
search: search ?? null,
|
|
|
|
|
issueId: issueId ?? null,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export const getImageAttachmentDataCmd = (attachmentId: string) =>
|
|
|
|
|
invoke<string>("get_image_attachment_data", { attachmentId });
|
|
|
|
|
|
|
|
|
|
export const listAllImageAttachmentsCmd = (search?: string, issueId?: string) =>
|
|
|
|
|
invoke<ImageAttachmentSummary[]>("list_all_image_attachments", {
|
|
|
|
|
search: search ?? null,
|
|
|
|
|
issueId: issueId ?? null,
|
|
|
|
|
});
|
2026-06-05 13:14:03 +00:00
|
|
|
|
|
|
|
|
// ─── Shell Execution Commands ────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface KubeconfigInfo {
|
|
|
|
|
id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
context: string;
|
|
|
|
|
cluster_url?: string;
|
|
|
|
|
is_active: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface CommandExecution {
|
|
|
|
|
id: string;
|
|
|
|
|
command: string;
|
|
|
|
|
tier: number;
|
|
|
|
|
approval_status: string;
|
|
|
|
|
exit_code: number | null;
|
|
|
|
|
stdout: string | null;
|
|
|
|
|
stderr: string | null;
|
|
|
|
|
execution_time_ms: number | null;
|
|
|
|
|
executed_at: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface KubectlStatus {
|
|
|
|
|
installed: boolean;
|
|
|
|
|
path?: string;
|
|
|
|
|
version?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const uploadKubeconfigCmd = (name: string, content: string) =>
|
|
|
|
|
invoke<string>("upload_kubeconfig", { name, content });
|
|
|
|
|
|
|
|
|
|
export const listKubeconfigsCmd = () =>
|
|
|
|
|
invoke<KubeconfigInfo[]>("list_kubeconfigs");
|
|
|
|
|
|
|
|
|
|
export const activateKubeconfigCmd = (id: string) =>
|
|
|
|
|
invoke<void>("activate_kubeconfig", { id });
|
|
|
|
|
|
|
|
|
|
export const deleteKubeconfigCmd = (id: string) =>
|
|
|
|
|
invoke<void>("delete_kubeconfig", { id });
|
|
|
|
|
|
|
|
|
|
export const respondToShellApprovalCmd = (approvalId: string, decision: string) =>
|
|
|
|
|
invoke<void>("respond_to_shell_approval", { approvalId, decision });
|
|
|
|
|
|
|
|
|
|
export const listCommandExecutionsCmd = (issueId?: string) =>
|
|
|
|
|
invoke<CommandExecution[]>("list_command_executions", {
|
|
|
|
|
issueId: issueId ?? null,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export const checkKubectlInstalledCmd = () =>
|
|
|
|
|
invoke<KubectlStatus>("check_kubectl_installed");
|
2026-06-06 17:46:33 +00:00
|
|
|
|
fix(classifier): fix 3 safety bugs, extract const arrays, make tier UI dynamic
Bug 1 — Dead multi-word tier3 entries / missing single-token commands
parse_single_command() extracts only the first token as `command`, so
multi-word entries like "kill -9", "init 0", "service stop" in the tier3
array never matched. Adding the single-token forms "kill", "pkill",
"killall", "init" to TIER3_COMMANDS ensures these commands are always
denied. Removed all dead multi-word entries.
Bug 2 — systemctl Tier 1 special case was dead code
systemctl was not in tier1_general, so the block that was supposed to
auto-execute `systemctl status` never ran. Moved systemctl handling into
its own block (TIER1_SYSTEMCTL_SUBCOMMANDS / TIER2_SYSTEMCTL_SUBCOMMANDS)
evaluated before the general tier checks. status, is-active, is-enabled,
list-units, list-unit-files → Tier 1; all others → Tier 2.
Bug 3 — ldapmodify / ldapdelete / ldapadd misclassified as Tier 1
Both appeared in the old tier1_general and tier2_general arrays; the tier1
check ran first, so LDAP write operations auto-executed. Removed them from
tier1. ldapsearch (read-only) remains Tier 1.
Dynamic Safety Architecture UI
Extracted all tier classification arrays to module-level pub const slices
(TIER3_COMMANDS, TIER1_KUBECTL_SUBCOMMANDS, etc.) so both the classifier
logic and a new get_classifier_rules() Tauri command share a single source
of truth. ShellExecution.tsx now calls getClassifierRulesCmd() on mount and
renders the actual command lists in collapsible per-tier cards — any change
to the const arrays is automatically reflected in the UI with no manual
documentation update needed.
Also fixes the cargo fmt CI failure introduced in the previous commit
(ClusterClient::new call reformatted to a single line).
2026-06-07 23:15:42 +00:00
|
|
|
export interface ClassifierRules {
|
|
|
|
|
tier1_kubectl: string[];
|
|
|
|
|
tier1_systemctl: string[];
|
|
|
|
|
tier1_proxmox: string[];
|
|
|
|
|
tier1_general: string[];
|
|
|
|
|
tier2_kubectl: string[];
|
|
|
|
|
tier2_systemctl: string[];
|
|
|
|
|
tier2_proxmox: string[];
|
|
|
|
|
tier2_general: string[];
|
|
|
|
|
tier3: string[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const getClassifierRulesCmd = () =>
|
|
|
|
|
invoke<ClassifierRules>("get_classifier_rules");
|
|
|
|
|
|
2026-06-06 17:46:33 +00:00
|
|
|
// ─── Kubernetes Management Types ──────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface ClusterInfo {
|
|
|
|
|
id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
context: string;
|
|
|
|
|
cluster_url: string;
|
|
|
|
|
}
|
|
|
|
|
|
feat(kubernetes): implement Phase 1 & 2: resource discovery UIs and advanced features
- Add kubernetesStore.ts with Zustand state management (clusters, namespaces, resources, terminals, search, bulk selection)
- Create 15 resource list components (Secret, ReplicaSet, Job, CronJob, Ingress, PVC, PV, ServiceAccount, Role, ClusterRole, RoleBinding, ClusterRoleBinding, HPA, Node, Event, ConfigMap)
- Add advanced components (Terminal, YamlEditor, MetricsChart, SearchBar, ContextSwitcher, ApplicationView, PodDetail)
- Update KubernetesPage.tsx to integrate kubernetesStore and add cluster management
- Add ContextInfo and ResourceInfo types to tauriCommands.ts
- All components pass ESLint, TypeScript, and pass 114 tests
- Build successful
2026-06-07 15:24:26 +00:00
|
|
|
export interface ContextInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
cluster: string;
|
|
|
|
|
user: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ResourceInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
[key: string]: unknown;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-06 17:46:33 +00:00
|
|
|
export interface PortForwardRequest {
|
|
|
|
|
cluster_id: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
pod: string;
|
|
|
|
|
container_port: number;
|
2026-06-06 21:23:00 +00:00
|
|
|
local_port?: number;
|
2026-06-06 17:46:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface PortForwardResponse {
|
|
|
|
|
id: string;
|
|
|
|
|
cluster_id: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
pod: string;
|
2026-06-06 21:23:00 +00:00
|
|
|
container_ports: number[];
|
|
|
|
|
local_ports: number[];
|
2026-06-06 17:46:33 +00:00
|
|
|
status: string;
|
|
|
|
|
}
|
|
|
|
|
|
feat(k8s): implement clean-room Kubernetes management GUI
- Backend: kube module with ClusterClient, PortForwardSession, RefreshRegistry
- 7 Tauri IPC commands: add_cluster, remove_cluster, list_clusters, start_port_forward, stop_port_forward, list_port_forwards, delete_port_forward, shutdown_port_forwards
- AppState extended with clusters, port_forwards, refresh_registry fields
- Version bumped to 1.1.0 in Cargo.toml and package.json
- Auto-tag workflow updated to mark releases as draft (pre-release)
- Buy Me A Coffee section added to README.md
- Fixed changelog workflow to only include current tag commits
- Proper kubeconfig YAML parsing with extract_context and extract_server_url
- Added kubeconfig content storage in ClusterClient
- Updated PortForwardSession to include cluster_name
- Frontend GUI components: ClusterList, PortForwardList, AddClusterModal, PortForwardForm, KubernetesPage
- TypeScript types and IPC commands for Kubernetes management
- Unit tests for Kubernetes IPC commands (6 tests)
- All 332 Rust tests passing
- All 98 frontend tests passing
- TypeScript type checks passing
- Project builds successfully in release mode
- Committed and pushed to feature/kubernetes-management branch
- Command injection vulnerability fixed with regex validation and max length check (253 chars)
- stop_port_forward and shutdown_port_forwards properly kill kubectl child processes via async child management
- Temp file cleanup implemented with RAII TempFileCleanup struct created before std::fs::write
- discover_pods now parses actual kubectl JSON output
- ChildWaitHandle implemented with background task for waiting on kubectl child
- PortForwardSession uses Arc<TokioMutex<Option<Child>>> for async-safe child management
- Port-forward uses kubectl's dynamic port binding (0) instead of TcpListener
- Added shutdown_port_forwards command for app shutdown cleanup
- Added cleanup effect in App.tsx to call shutdownPortForwardsCmd on unmount
- Database CRUD operations for clusters and port_forwards added to db.rs
- validate_resource_name uses lazy_static! for cached Regex to prevent ReDoS
- Cluster struct updated to store kubeconfig_content directly instead of kubeconfig_id
- Cluster model in db/models.rs updated to use kubeconfig_content field
- load_clusters and load_port_forwards commands registered in lib.rs
- Temp file cleanup moved to background task in ChildWaitHandle to ensure cleanup after kubectl completes
- Unused child_id field removed from ChildWaitHandle
- Command validation moved to beginning of start_port_forward before any operations
- Fixed lint errors: removed unused imports, fixed React hooks order, updated type annotations
- Updated eslint.config.js to properly configure file patterns
2026-06-07 01:27:39 +00:00
|
|
|
export interface PodInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
status: string;
|
|
|
|
|
ready: string;
|
|
|
|
|
age: string;
|
fix(kube): resolve automated PR review blockers and warnings
Blockers:
- Replace serde_yaml::from_str with serde_json::from_str in all 6
parse_*_json functions (parse_namespaces, parse_pods, parse_services,
parse_deployments, parse_statefulsets, parse_daemonsets). Update
.as_sequence() → .as_array(), .as_mapping() → .as_object(), and
mapping iterator patterns throughout. Explicitly type serde_yaml::Value
in extract_context/extract_server_url which legitimately parse YAML.
Warnings:
- Add containers: Vec<String> to PodInfo struct; parse from
spec.containers[].name in parse_pods_json
- Fix PodList.tsx to use selectedPod.containers instead of [selectedPod.name]
- Fix exec_pod: add optional shell param with allowlist validation
(sh/bash/ash/dash); correct arg ordering — -c container now placed
before -- separator
- Handle empty namespace with --all-namespaces in all 5 list commands
- Fix dialog overflow: overflow-hidden → overflow-y-auto on inner div
- Memoize namespace options with useMemo in ResourceBrowser
Lint cleanup (all pre-existing, surfaced by eslint config fix):
- Deduplicate eslint.config.js (was doubled to 272 lines); move ignores
to standalone global object; allow console.log in cli section
- Remove stale .eslintignore (migrated to eslint.config.js)
- Remove unused Card/CardTitle imports from Kubernetes list components
- Rename unused props to _clusterId/_namespace in DaemonSetList,
ServiceList, StatefulSetList
- Fix useEffect/useCallback missing deps in Triage and LogUpload
- Remove debug console.log from App.tsx provider auto-test
- Rename unused hover prop to _hover in TableRow (ui/index.tsx)
- Add #[allow(unused_variables)] to Phase 3 stub Tauri commands
- Restore get_pod_logs, scale_deployment, restart_deployment,
delete_resource, exec_pod to lib.rs handler registration (were
accidentally dropped in Phase 3 expansion)
All checks pass: cargo clippy -D warnings, tsc --noEmit,
eslint --max-warnings 0, 331 Rust tests, 98 frontend tests.
2026-06-07 04:55:44 +00:00
|
|
|
containers: string[];
|
feat(k8s): implement clean-room Kubernetes management GUI
- Backend: kube module with ClusterClient, PortForwardSession, RefreshRegistry
- 7 Tauri IPC commands: add_cluster, remove_cluster, list_clusters, start_port_forward, stop_port_forward, list_port_forwards, delete_port_forward, shutdown_port_forwards
- AppState extended with clusters, port_forwards, refresh_registry fields
- Version bumped to 1.1.0 in Cargo.toml and package.json
- Auto-tag workflow updated to mark releases as draft (pre-release)
- Buy Me A Coffee section added to README.md
- Fixed changelog workflow to only include current tag commits
- Proper kubeconfig YAML parsing with extract_context and extract_server_url
- Added kubeconfig content storage in ClusterClient
- Updated PortForwardSession to include cluster_name
- Frontend GUI components: ClusterList, PortForwardList, AddClusterModal, PortForwardForm, KubernetesPage
- TypeScript types and IPC commands for Kubernetes management
- Unit tests for Kubernetes IPC commands (6 tests)
- All 332 Rust tests passing
- All 98 frontend tests passing
- TypeScript type checks passing
- Project builds successfully in release mode
- Committed and pushed to feature/kubernetes-management branch
- Command injection vulnerability fixed with regex validation and max length check (253 chars)
- stop_port_forward and shutdown_port_forwards properly kill kubectl child processes via async child management
- Temp file cleanup implemented with RAII TempFileCleanup struct created before std::fs::write
- discover_pods now parses actual kubectl JSON output
- ChildWaitHandle implemented with background task for waiting on kubectl child
- PortForwardSession uses Arc<TokioMutex<Option<Child>>> for async-safe child management
- Port-forward uses kubectl's dynamic port binding (0) instead of TcpListener
- Added shutdown_port_forwards command for app shutdown cleanup
- Added cleanup effect in App.tsx to call shutdownPortForwardsCmd on unmount
- Database CRUD operations for clusters and port_forwards added to db.rs
- validate_resource_name uses lazy_static! for cached Regex to prevent ReDoS
- Cluster struct updated to store kubeconfig_content directly instead of kubeconfig_id
- Cluster model in db/models.rs updated to use kubeconfig_content field
- load_clusters and load_port_forwards commands registered in lib.rs
- Temp file cleanup moved to background task in ChildWaitHandle to ensure cleanup after kubectl completes
- Unused child_id field removed from ChildWaitHandle
- Command validation moved to beginning of start_port_forward before any operations
- Fixed lint errors: removed unused imports, fixed React hooks order, updated type annotations
- Updated eslint.config.js to properly configure file patterns
2026-06-07 01:27:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ClusterConnectionState {
|
|
|
|
|
type: "Connected" | "Disconnected";
|
|
|
|
|
error?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ClusterConnectionStatus {
|
|
|
|
|
status: ClusterConnectionState;
|
|
|
|
|
context: string;
|
|
|
|
|
}
|
|
|
|
|
|
feat: implement full Lens-like Kubernetes UI with resource discovery and management
- Add ResourceBrowser with namespace/resource type tabs for pods, services, deployments, statefulsets, daemonsets
- Implement PodList with logs viewer and container selection
- Implement ServiceList with cluster IP, type, ports display
- Implement DeploymentList with scale and restart operations
- Add backend commands: list_namespaces, list_pods, list_services, list_deployments, list_statefulsets, list_daemonsets
- Add resource management commands: get_pod_logs, scale_deployment, restart_deployment, delete_resource, exec_pod
- Add UI components: Table, Tabs, Dialog, Alert to shared UI library
- Update KubernetesPage to use new ResourceBrowser component
- All tests passing (331 Rust + 98 frontend)
- Build successful in release mode
2026-06-07 04:08:01 +00:00
|
|
|
// ─── Kubernetes Resource Discovery Types ──────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface NamespaceInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
status: string;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ServicePort {
|
|
|
|
|
name?: string;
|
|
|
|
|
port: number;
|
|
|
|
|
target_port?: string;
|
|
|
|
|
protocol: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ServiceInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
type: string;
|
|
|
|
|
cluster_ip: string;
|
|
|
|
|
external_ip?: string;
|
|
|
|
|
ports: ServicePort[];
|
|
|
|
|
age: string;
|
|
|
|
|
selector: Record<string, string>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface DeploymentInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
ready: string;
|
|
|
|
|
up_to_date: string;
|
|
|
|
|
available: string;
|
|
|
|
|
age: string;
|
|
|
|
|
replicas: number;
|
|
|
|
|
labels: Record<string, string>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface StatefulSetInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
ready: string;
|
|
|
|
|
age: string;
|
|
|
|
|
replicas: number;
|
|
|
|
|
labels: Record<string, string>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface DaemonSetInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
desired: number;
|
|
|
|
|
current: number;
|
|
|
|
|
ready: number;
|
|
|
|
|
up_to_date: number;
|
|
|
|
|
available: number;
|
|
|
|
|
age: string;
|
|
|
|
|
labels: Record<string, string>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface NodeMetrics {
|
|
|
|
|
name: string;
|
|
|
|
|
cpu_usage: string;
|
|
|
|
|
memory_usage: string;
|
|
|
|
|
cpu_percentage: number;
|
|
|
|
|
memory_percentage: number;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface PodMetrics {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
cpu_usage: string;
|
|
|
|
|
memory_usage: string;
|
|
|
|
|
cpu_percentage: number;
|
|
|
|
|
memory_percentage: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface LogResponse {
|
|
|
|
|
logs: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ExecResponse {
|
|
|
|
|
stdout: string;
|
|
|
|
|
stderr: string;
|
|
|
|
|
exit_code: number | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ExecSessionResponse {
|
|
|
|
|
session_id: string;
|
|
|
|
|
cluster_id: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
pod: string;
|
|
|
|
|
container?: string;
|
|
|
|
|
status: string;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-06 17:46:33 +00:00
|
|
|
// ─── Kubernetes Management Commands ───────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const addClusterCmd = (id: string, name: string, kubeconfigContent: string) =>
|
|
|
|
|
invoke<ClusterInfo>("add_cluster", { id, name, kubeconfig_content: kubeconfigContent });
|
|
|
|
|
|
|
|
|
|
export const removeClusterCmd = (id: string) =>
|
|
|
|
|
invoke<void>("remove_cluster", { id });
|
|
|
|
|
|
2026-06-07 22:39:07 +00:00
|
|
|
export const connectClusterFromKubeconfigCmd = (id: string) =>
|
|
|
|
|
invoke<void>("connect_cluster_from_kubeconfig", { id });
|
|
|
|
|
|
2026-06-08 01:31:50 +00:00
|
|
|
/** Diagnostic: runs kubectl cluster-info and returns a human-readable summary. */
|
|
|
|
|
export const testKubectlConnectionCmd = (clusterId: string) =>
|
|
|
|
|
invoke<string>("test_kubectl_connection", { clusterId });
|
|
|
|
|
|
2026-06-06 17:46:33 +00:00
|
|
|
export const listClustersCmd = () =>
|
|
|
|
|
invoke<ClusterInfo[]>("list_clusters");
|
|
|
|
|
|
|
|
|
|
export const startPortForwardCmd = (request: PortForwardRequest) =>
|
|
|
|
|
invoke<PortForwardResponse>("start_port_forward", { request });
|
|
|
|
|
|
|
|
|
|
export const stopPortForwardCmd = (id: string) =>
|
|
|
|
|
invoke<void>("stop_port_forward", { id });
|
|
|
|
|
|
2026-06-06 18:01:35 +00:00
|
|
|
export const deletePortForwardCmd = (id: string) =>
|
2026-06-06 18:09:14 +00:00
|
|
|
invoke<void>("delete_port_forward", { id });
|
2026-06-06 18:01:35 +00:00
|
|
|
|
2026-06-06 17:46:33 +00:00
|
|
|
export const listPortForwardsCmd = () =>
|
|
|
|
|
invoke<PortForwardResponse[]>("list_port_forwards");
|
2026-06-06 23:48:52 +00:00
|
|
|
|
|
|
|
|
export const shutdownPortForwardsCmd = () =>
|
|
|
|
|
invoke<void>("shutdown_port_forwards");
|
feat(k8s): implement clean-room Kubernetes management GUI
- Backend: kube module with ClusterClient, PortForwardSession, RefreshRegistry
- 7 Tauri IPC commands: add_cluster, remove_cluster, list_clusters, start_port_forward, stop_port_forward, list_port_forwards, delete_port_forward, shutdown_port_forwards
- AppState extended with clusters, port_forwards, refresh_registry fields
- Version bumped to 1.1.0 in Cargo.toml and package.json
- Auto-tag workflow updated to mark releases as draft (pre-release)
- Buy Me A Coffee section added to README.md
- Fixed changelog workflow to only include current tag commits
- Proper kubeconfig YAML parsing with extract_context and extract_server_url
- Added kubeconfig content storage in ClusterClient
- Updated PortForwardSession to include cluster_name
- Frontend GUI components: ClusterList, PortForwardList, AddClusterModal, PortForwardForm, KubernetesPage
- TypeScript types and IPC commands for Kubernetes management
- Unit tests for Kubernetes IPC commands (6 tests)
- All 332 Rust tests passing
- All 98 frontend tests passing
- TypeScript type checks passing
- Project builds successfully in release mode
- Committed and pushed to feature/kubernetes-management branch
- Command injection vulnerability fixed with regex validation and max length check (253 chars)
- stop_port_forward and shutdown_port_forwards properly kill kubectl child processes via async child management
- Temp file cleanup implemented with RAII TempFileCleanup struct created before std::fs::write
- discover_pods now parses actual kubectl JSON output
- ChildWaitHandle implemented with background task for waiting on kubectl child
- PortForwardSession uses Arc<TokioMutex<Option<Child>>> for async-safe child management
- Port-forward uses kubectl's dynamic port binding (0) instead of TcpListener
- Added shutdown_port_forwards command for app shutdown cleanup
- Added cleanup effect in App.tsx to call shutdownPortForwardsCmd on unmount
- Database CRUD operations for clusters and port_forwards added to db.rs
- validate_resource_name uses lazy_static! for cached Regex to prevent ReDoS
- Cluster struct updated to store kubeconfig_content directly instead of kubeconfig_id
- Cluster model in db/models.rs updated to use kubeconfig_content field
- load_clusters and load_port_forwards commands registered in lib.rs
- Temp file cleanup moved to background task in ChildWaitHandle to ensure cleanup after kubectl completes
- Unused child_id field removed from ChildWaitHandle
- Command validation moved to beginning of start_port_forward before any operations
- Fixed lint errors: removed unused imports, fixed React hooks order, updated type annotations
- Updated eslint.config.js to properly configure file patterns
2026-06-07 01:27:39 +00:00
|
|
|
|
|
|
|
|
export const testClusterConnectionCmd = (clusterId: string) =>
|
|
|
|
|
invoke<ClusterConnectionStatus>("test_cluster_connection", { clusterId });
|
|
|
|
|
|
|
|
|
|
export const discoverPodsCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<PodInfo[]>("discover_pods", { clusterId, namespace });
|
feat: implement full Lens-like Kubernetes UI with resource discovery and management
- Add ResourceBrowser with namespace/resource type tabs for pods, services, deployments, statefulsets, daemonsets
- Implement PodList with logs viewer and container selection
- Implement ServiceList with cluster IP, type, ports display
- Implement DeploymentList with scale and restart operations
- Add backend commands: list_namespaces, list_pods, list_services, list_deployments, list_statefulsets, list_daemonsets
- Add resource management commands: get_pod_logs, scale_deployment, restart_deployment, delete_resource, exec_pod
- Add UI components: Table, Tabs, Dialog, Alert to shared UI library
- Update KubernetesPage to use new ResourceBrowser component
- All tests passing (331 Rust + 98 frontend)
- Build successful in release mode
2026-06-07 04:08:01 +00:00
|
|
|
|
|
|
|
|
// ─── Kubernetes Resource Discovery Commands ───────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const listNamespacesCmd = (clusterId: string) =>
|
|
|
|
|
invoke<NamespaceInfo[]>("list_namespaces", { clusterId });
|
|
|
|
|
|
|
|
|
|
export const listPodsCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<PodInfo[]>("list_pods", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listServicesCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<ServiceInfo[]>("list_services", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listDeploymentsCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<DeploymentInfo[]>("list_deployments", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listStatefulsetsCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<StatefulSetInfo[]>("list_statefulsets", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listDaemonsetsCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<DaemonSetInfo[]>("list_daemonsets", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
// ─── Kubernetes Resource Management Commands ──────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const getPodLogsCmd = (clusterId: string, namespace: string, podName: string, containerName: string) =>
|
|
|
|
|
invoke<LogResponse>("get_pod_logs", { clusterId, namespace, podName, containerName });
|
|
|
|
|
|
|
|
|
|
export const scaleDeploymentCmd = (clusterId: string, namespace: string, deploymentName: string, replicas: number) =>
|
|
|
|
|
invoke<void>("scale_deployment", { clusterId, namespace, deploymentName, replicas });
|
|
|
|
|
|
|
|
|
|
export const restartDeploymentCmd = (clusterId: string, namespace: string, deploymentName: string) =>
|
|
|
|
|
invoke<void>("restart_deployment", { clusterId, namespace, deploymentName });
|
|
|
|
|
|
|
|
|
|
export const deleteResourceCmd = (clusterId: string, resourceType: string, namespace: string, resourceName: string) =>
|
|
|
|
|
invoke<void>("delete_resource", { clusterId, resourceType, namespace, resourceName });
|
|
|
|
|
|
fix(kube): resolve automated PR review blockers and warnings
Blockers:
- Replace serde_yaml::from_str with serde_json::from_str in all 6
parse_*_json functions (parse_namespaces, parse_pods, parse_services,
parse_deployments, parse_statefulsets, parse_daemonsets). Update
.as_sequence() → .as_array(), .as_mapping() → .as_object(), and
mapping iterator patterns throughout. Explicitly type serde_yaml::Value
in extract_context/extract_server_url which legitimately parse YAML.
Warnings:
- Add containers: Vec<String> to PodInfo struct; parse from
spec.containers[].name in parse_pods_json
- Fix PodList.tsx to use selectedPod.containers instead of [selectedPod.name]
- Fix exec_pod: add optional shell param with allowlist validation
(sh/bash/ash/dash); correct arg ordering — -c container now placed
before -- separator
- Handle empty namespace with --all-namespaces in all 5 list commands
- Fix dialog overflow: overflow-hidden → overflow-y-auto on inner div
- Memoize namespace options with useMemo in ResourceBrowser
Lint cleanup (all pre-existing, surfaced by eslint config fix):
- Deduplicate eslint.config.js (was doubled to 272 lines); move ignores
to standalone global object; allow console.log in cli section
- Remove stale .eslintignore (migrated to eslint.config.js)
- Remove unused Card/CardTitle imports from Kubernetes list components
- Rename unused props to _clusterId/_namespace in DaemonSetList,
ServiceList, StatefulSetList
- Fix useEffect/useCallback missing deps in Triage and LogUpload
- Remove debug console.log from App.tsx provider auto-test
- Rename unused hover prop to _hover in TableRow (ui/index.tsx)
- Add #[allow(unused_variables)] to Phase 3 stub Tauri commands
- Restore get_pod_logs, scale_deployment, restart_deployment,
delete_resource, exec_pod to lib.rs handler registration (were
accidentally dropped in Phase 3 expansion)
All checks pass: cargo clippy -D warnings, tsc --noEmit,
eslint --max-warnings 0, 331 Rust tests, 98 frontend tests.
2026-06-07 04:55:44 +00:00
|
|
|
export const execPodCmd = (clusterId: string, namespace: string, podName: string, containerName: string, command: string, shell?: string) =>
|
|
|
|
|
invoke<ExecResponse>("exec_pod", { clusterId, namespace, podName, containerName, shell, command });
|
feat: implement additional Kubernetes resource discovery and management commands
- Add 16 new resource discovery commands: replicasets, jobs, cronjobs, configmaps, secrets, nodes, events, ingresses, pvcs, pvs, serviceaccounts, roles, clusterroles, rolebindings, clusterrolebindings, hpas
- Add 6 new management commands: cordon_node, uncordon_node, drain_node, rollback_deployment, create_resource, edit_resource
- All commands follow existing patterns with proper temp file cleanup and error handling
- All tests passing (331 Rust + 98 frontend)
- TypeScript type checks passing
- Build successful in release mode
2026-06-07 05:10:19 +00:00
|
|
|
|
|
|
|
|
// ─── Additional Kubernetes Resource Discovery Types ───────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface ReplicaSetInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
replicas: number;
|
|
|
|
|
ready: string;
|
|
|
|
|
age: string;
|
|
|
|
|
labels: Record<string, string>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface JobInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
completions: string;
|
|
|
|
|
duration: string;
|
|
|
|
|
age: string;
|
|
|
|
|
labels: Record<string, string>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface CronJobInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
schedule: string;
|
|
|
|
|
active: number;
|
|
|
|
|
last_schedule: string;
|
|
|
|
|
age: string;
|
|
|
|
|
labels: Record<string, string>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ConfigMapInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
data_keys: number;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface SecretInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
type: string;
|
|
|
|
|
data_keys: number;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface NodeInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
status: string;
|
|
|
|
|
roles: string;
|
|
|
|
|
version: string;
|
|
|
|
|
internal_ip: string;
|
|
|
|
|
external_ip?: string;
|
|
|
|
|
os_image: string;
|
|
|
|
|
kernel_version: string;
|
|
|
|
|
kubelet_version: string;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface EventInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
event_type: string;
|
|
|
|
|
reason: string;
|
|
|
|
|
object: string;
|
|
|
|
|
count: number;
|
|
|
|
|
first_seen: string;
|
|
|
|
|
last_seen: string;
|
|
|
|
|
message: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface IngressInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
class?: string;
|
|
|
|
|
host: string;
|
|
|
|
|
addresses: string[];
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface PersistentVolumeClaimInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
status: string;
|
|
|
|
|
volume: string;
|
|
|
|
|
capacity: string;
|
|
|
|
|
access_modes: string[];
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface PersistentVolumeInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
status: string;
|
|
|
|
|
capacity: string;
|
|
|
|
|
access_modes: string[];
|
|
|
|
|
reclaim_policy: string;
|
|
|
|
|
storage_class: string;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ServiceAccountInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
secrets: number;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface RoleInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ClusterRoleInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface RoleBindingInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
role: string;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ClusterRoleBindingInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
cluster_role: string;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface HorizontalPodAutoscalerInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
min_replicas: number;
|
|
|
|
|
max_replicas: number;
|
|
|
|
|
current_replicas: number;
|
|
|
|
|
desired_replicas: number;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Additional Kubernetes Resource Discovery Commands ────────────────────────
|
|
|
|
|
|
|
|
|
|
export const listReplicasetsCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<ReplicaSetInfo[]>("list_replicasets", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listJobsCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<JobInfo[]>("list_jobs", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listCronjobsCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<CronJobInfo[]>("list_cronjobs", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listConfigmapsCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<ConfigMapInfo[]>("list_configmaps", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listSecretsCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<SecretInfo[]>("list_secrets", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listNodesCmd = (clusterId: string) =>
|
|
|
|
|
invoke<NodeInfo[]>("list_nodes", { clusterId });
|
|
|
|
|
|
|
|
|
|
export const listEventsCmd = (clusterId: string, namespace?: string) =>
|
|
|
|
|
invoke<EventInfo[]>("list_events", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listIngressesCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<IngressInfo[]>("list_ingresses", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listPersistentvolumeclaimsCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<PersistentVolumeClaimInfo[]>("list_persistentvolumeclaims", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listPersistentvolumesCmd = (clusterId: string) =>
|
|
|
|
|
invoke<PersistentVolumeInfo[]>("list_persistentvolumes", { clusterId });
|
|
|
|
|
|
|
|
|
|
export const listServiceaccountsCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<ServiceAccountInfo[]>("list_serviceaccounts", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listRolesCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<RoleInfo[]>("list_roles", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listClusterrolesCmd = (clusterId: string) =>
|
|
|
|
|
invoke<ClusterRoleInfo[]>("list_clusterroles", { clusterId });
|
|
|
|
|
|
|
|
|
|
export const listRolebindingsCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<RoleBindingInfo[]>("list_rolebindings", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listClusterrolebindingsCmd = (clusterId: string) =>
|
|
|
|
|
invoke<ClusterRoleBindingInfo[]>("list_clusterrolebindings", { clusterId });
|
|
|
|
|
|
|
|
|
|
export const listHorizontalpodautoscalersCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<HorizontalPodAutoscalerInfo[]>("list_horizontalpodautoscalers", { clusterId, namespace });
|
|
|
|
|
|
feat(kubernetes): implement Lens Desktop v5 feature-parity UI
Complete overhaul of the Kubernetes management page from a basic config
panel into a full Lens-style IDE shell with 26 resource types, real-time
data, and a comprehensive test suite.
Layout & navigation:
- Rewrite KubernetesPage as a Lens v5-style shell: collapsible sidebar
(Workloads / Services & Networking / Config & Storage / Access Control /
Cluster), top hotbar with cluster+namespace selectors, Ctrl+K command
palette
- All 26 resource types now accessible via sidebar navigation (previously 5)
New resource types (Rust + TypeScript + React):
- StorageClasses, NetworkPolicies, ResourceQuotas, LimitRanges
- 4 new Tauri commands registered in generate_handler![]
Component implementations (replacing stubs with real IPC):
- Terminal: full xterm.js with multi-tab sessions and exec_pod IPC
- YamlEditor: Monaco editor with YAML syntax highlighting
- MetricsChart: recharts LineChart/BarChart
- ClusterOverview: live node/pod/deployment/namespace counts
- ClusterDetails: real kubeconfig + node data
- PodDetail, DeploymentDetail, ServiceDetail, ConfigMapDetail, SecretDetail:
all connected to real IPC data, zero hardcoded values
- CreateResourceModal, EditResourceModal: wired to createResourceCmd /
editResourceCmd
- RbacViewer: live data from 4 RBAC IPC commands
- RbacEditor: create roles/cluster-roles via YAML editor
- CommandPalette: 12 real navigation commands, keyboard nav
Dependencies added: xterm@5, xterm-addon-fit, xterm-addon-web-links,
@monaco-editor/react@4, recharts@2
Tooling:
- Replace eslint-plugin-react (incompatible with ESLint 10) with
@eslint-react/eslint-plugin; fix eslint.config.js for flat config
- Fix pre-existing hoisting lint errors in Security.tsx, PortForwardForm.tsx
- Fix eventBus.ts: replace all `any` generics with `unknown`
Tests: 251 passing across 35 test files (was 94/19)
- 16 new test files covering all new and fixed components (TDD)
- npx tsc --noEmit: 0 errors
- cargo clippy -- -D warnings: 0 warnings
- cargo fmt --check: passes
- eslint src/ --max-warnings 0: 0 issues
2026-06-07 21:41:28 +00:00
|
|
|
// ─── Additional Lens Resource Types ───────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface StorageClassInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
provisioner: string;
|
|
|
|
|
reclaim_policy: string;
|
|
|
|
|
volume_binding_mode: string;
|
|
|
|
|
allow_volume_expansion: boolean;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface NetworkPolicyInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
pod_selector: string;
|
|
|
|
|
policy_types: string[];
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ResourceQuotaInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
request_cpu: string;
|
|
|
|
|
request_memory: string;
|
|
|
|
|
limit_cpu: string;
|
|
|
|
|
limit_memory: string;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface LimitRangeInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
limit_count: number;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const listStorageclassesCmd = (clusterId: string) =>
|
|
|
|
|
invoke<StorageClassInfo[]>("list_storageclasses", { clusterId });
|
|
|
|
|
|
|
|
|
|
export const listNetworkpoliciesCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<NetworkPolicyInfo[]>("list_networkpolicies", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listResourcequotasCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<ResourceQuotaInfo[]>("list_resourcequotas", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listLimitrangesCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<LimitRangeInfo[]>("list_limitranges", { clusterId, namespace });
|
|
|
|
|
|
feat: implement additional Kubernetes resource discovery and management commands
- Add 16 new resource discovery commands: replicasets, jobs, cronjobs, configmaps, secrets, nodes, events, ingresses, pvcs, pvs, serviceaccounts, roles, clusterroles, rolebindings, clusterrolebindings, hpas
- Add 6 new management commands: cordon_node, uncordon_node, drain_node, rollback_deployment, create_resource, edit_resource
- All commands follow existing patterns with proper temp file cleanup and error handling
- All tests passing (331 Rust + 98 frontend)
- TypeScript type checks passing
- Build successful in release mode
2026-06-07 05:10:19 +00:00
|
|
|
// ─── Additional Kubernetes Resource Management Commands ───────────────────────
|
|
|
|
|
|
|
|
|
|
export const cordonNodeCmd = (clusterId: string, nodeName: string) =>
|
|
|
|
|
invoke<void>("cordon_node", { clusterId, nodeName });
|
|
|
|
|
|
|
|
|
|
export const uncordonNodeCmd = (clusterId: string, nodeName: string) =>
|
|
|
|
|
invoke<void>("uncordon_node", { clusterId, nodeName });
|
|
|
|
|
|
|
|
|
|
export const drainNodeCmd = (clusterId: string, nodeName: string) =>
|
|
|
|
|
invoke<void>("drain_node", { clusterId, nodeName });
|
|
|
|
|
|
|
|
|
|
export const rollbackDeploymentCmd = (clusterId: string, namespace: string, deploymentName: string) =>
|
|
|
|
|
invoke<void>("rollback_deployment", { clusterId, namespace, deploymentName });
|
|
|
|
|
|
|
|
|
|
export const createResourceCmd = (clusterId: string, namespace: string, resourceType: string, yamlContent: string) =>
|
|
|
|
|
invoke<void>("create_resource", { clusterId, namespace, resourceType, yamlContent });
|
|
|
|
|
|
|
|
|
|
export const editResourceCmd = (clusterId: string, namespace: string, resourceType: string, resourceName: string, yamlContent: string) =>
|
|
|
|
|
invoke<void>("edit_resource", { clusterId, namespace, resourceType, resourceName, yamlContent });
|
2026-06-09 01:16:55 +00:00
|
|
|
|
|
|
|
|
// ─── Missing Resource Types ───────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface ReplicationControllerInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
desired: number;
|
|
|
|
|
ready: number;
|
|
|
|
|
current: number;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface PodDisruptionBudgetInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
min_available: string;
|
|
|
|
|
max_unavailable: string;
|
|
|
|
|
disruptions_allowed: number;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface PriorityClassInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
value: number;
|
|
|
|
|
global_default: boolean;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface RuntimeClassInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
handler: string;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface LeaseInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
holder: string;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface WebhookConfigInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
webhooks: number;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface EndpointInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
addresses: string[];
|
|
|
|
|
ports: string[];
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface EndpointSliceInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
address_type: string;
|
|
|
|
|
endpoints: number;
|
|
|
|
|
ports: string[];
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface IngressClassInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
controller: string;
|
|
|
|
|
is_default: boolean;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface NamespaceResourceInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
status: string;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Helm Types ───────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface HelmRepository {
|
|
|
|
|
name: string;
|
|
|
|
|
url: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface HelmChart {
|
|
|
|
|
name: string;
|
|
|
|
|
chart_version: string;
|
|
|
|
|
app_version: string;
|
|
|
|
|
description: string;
|
|
|
|
|
repository: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface HelmRelease {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
chart: string;
|
|
|
|
|
chart_version: string;
|
|
|
|
|
app_version: string;
|
|
|
|
|
status: string;
|
|
|
|
|
updated: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Custom Resource / CRD Types ─────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface CrdInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
group: string;
|
|
|
|
|
version: string;
|
|
|
|
|
kind: string;
|
|
|
|
|
scope: string;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface CustomResourceInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
age: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Resource Actions ─────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface DescribeResponse {
|
|
|
|
|
output: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface LogStreamConfig {
|
|
|
|
|
cluster_id: string;
|
|
|
|
|
namespace: string;
|
|
|
|
|
pod_name: string;
|
|
|
|
|
container_name: string;
|
|
|
|
|
follow: boolean;
|
|
|
|
|
timestamps: boolean;
|
|
|
|
|
tail_lines?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── New Resource List Commands ───────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const listReplicationcontrollersCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<ReplicationControllerInfo[]>("list_replicationcontrollers", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listPoddisruptionbudgetsCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<PodDisruptionBudgetInfo[]>("list_poddisruptionbudgets", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listPriorityclassesCmd = (clusterId: string) =>
|
|
|
|
|
invoke<PriorityClassInfo[]>("list_priorityclasses", { clusterId });
|
|
|
|
|
|
|
|
|
|
export const listRuntimeclassesCmd = (clusterId: string) =>
|
|
|
|
|
invoke<RuntimeClassInfo[]>("list_runtimeclasses", { clusterId });
|
|
|
|
|
|
|
|
|
|
export const listLeasesCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<LeaseInfo[]>("list_leases", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listMutatingwebhookconfigurationsCmd = (clusterId: string) =>
|
|
|
|
|
invoke<WebhookConfigInfo[]>("list_mutatingwebhookconfigurations", { clusterId });
|
|
|
|
|
|
|
|
|
|
export const listValidatingwebhookconfigurationsCmd = (clusterId: string) =>
|
|
|
|
|
invoke<WebhookConfigInfo[]>("list_validatingwebhookconfigurations", { clusterId });
|
|
|
|
|
|
|
|
|
|
export const listEndpointsCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<EndpointInfo[]>("list_endpoints", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listEndpointslicesCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<EndpointSliceInfo[]>("list_endpointslices", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const listIngressclassesCmd = (clusterId: string) =>
|
|
|
|
|
invoke<IngressClassInfo[]>("list_ingressclasses", { clusterId });
|
|
|
|
|
|
|
|
|
|
export const listNamespacesResourceCmd = (clusterId: string) =>
|
|
|
|
|
invoke<NamespaceResourceInfo[]>("list_namespaces_resource", { clusterId });
|
|
|
|
|
|
|
|
|
|
export const createNamespaceCmd = (clusterId: string, name: string) =>
|
|
|
|
|
invoke<void>("create_namespace", { clusterId, name });
|
|
|
|
|
|
|
|
|
|
export const deleteNamespaceCmd = (clusterId: string, name: string) =>
|
|
|
|
|
invoke<void>("delete_namespace", { clusterId, name });
|
|
|
|
|
|
|
|
|
|
// ─── Resource Action Commands ─────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const attachPodCmd = (clusterId: string, namespace: string, podName: string, containerName: string) =>
|
|
|
|
|
invoke<ExecSessionResponse>("attach_pod", { clusterId, namespace, podName, containerName });
|
|
|
|
|
|
|
|
|
|
export const forceDeleteResourceCmd = (clusterId: string, resourceType: string, namespace: string, resourceName: string) =>
|
|
|
|
|
invoke<void>("force_delete_resource", { clusterId, resourceType, namespace, resourceName });
|
|
|
|
|
|
|
|
|
|
export const describeResourceCmd = (clusterId: string, resourceType: string, namespace: string, resourceName: string) =>
|
|
|
|
|
invoke<DescribeResponse>("describe_resource", { clusterId, resourceType, namespace, resourceName });
|
|
|
|
|
|
|
|
|
|
export const getResourceYamlCmd = (clusterId: string, resourceType: string, namespace: string, resourceName: string) =>
|
|
|
|
|
invoke<string>("get_resource_yaml", { clusterId, resourceType, namespace, resourceName });
|
|
|
|
|
|
|
|
|
|
export const restartStatefulsetCmd = (clusterId: string, namespace: string, name: string) =>
|
|
|
|
|
invoke<void>("restart_statefulset", { clusterId, namespace, name });
|
|
|
|
|
|
|
|
|
|
export const restartDaemonsetCmd = (clusterId: string, namespace: string, name: string) =>
|
|
|
|
|
invoke<void>("restart_daemonset", { clusterId, namespace, name });
|
|
|
|
|
|
|
|
|
|
export const scaleStatefulsetCmd = (clusterId: string, namespace: string, name: string, replicas: number) =>
|
|
|
|
|
invoke<void>("scale_statefulset", { clusterId, namespace, name, replicas });
|
|
|
|
|
|
|
|
|
|
export const scaleReplicasetCmd = (clusterId: string, namespace: string, name: string, replicas: number) =>
|
|
|
|
|
invoke<void>("scale_replicaset", { clusterId, namespace, name, replicas });
|
|
|
|
|
|
|
|
|
|
export const scaleReplicationcontrollerCmd = (clusterId: string, namespace: string, name: string, replicas: number) =>
|
|
|
|
|
invoke<void>("scale_replicationcontroller", { clusterId, namespace, name, replicas });
|
|
|
|
|
|
|
|
|
|
export const suspendCronjobCmd = (clusterId: string, namespace: string, name: string) =>
|
|
|
|
|
invoke<void>("suspend_cronjob", { clusterId, namespace, name });
|
|
|
|
|
|
|
|
|
|
export const resumeCronjobCmd = (clusterId: string, namespace: string, name: string) =>
|
|
|
|
|
invoke<void>("resume_cronjob", { clusterId, namespace, name });
|
|
|
|
|
|
|
|
|
|
export const triggerCronjobCmd = (clusterId: string, namespace: string, name: string) =>
|
|
|
|
|
invoke<void>("trigger_cronjob", { clusterId, namespace, name });
|
|
|
|
|
|
|
|
|
|
// ─── Log Streaming Commands ───────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const streamPodLogsCmd = (config: LogStreamConfig) =>
|
|
|
|
|
invoke<string>("stream_pod_logs", { config });
|
|
|
|
|
|
|
|
|
|
export const stopLogStreamCmd = (streamId: string) =>
|
|
|
|
|
invoke<void>("stop_log_stream", { streamId });
|
|
|
|
|
|
|
|
|
|
// ─── Helm Commands ────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const helmListReposCmd = (clusterId: string) =>
|
|
|
|
|
invoke<HelmRepository[]>("helm_list_repos", { clusterId });
|
|
|
|
|
|
|
|
|
|
export const helmAddRepoCmd = (clusterId: string, name: string, url: string) =>
|
|
|
|
|
invoke<void>("helm_add_repo", { clusterId, name, url });
|
|
|
|
|
|
|
|
|
|
export const helmUpdateReposCmd = (clusterId: string) =>
|
|
|
|
|
invoke<void>("helm_update_repos", { clusterId });
|
|
|
|
|
|
|
|
|
|
export const helmSearchRepoCmd = (clusterId: string, query: string) =>
|
|
|
|
|
invoke<HelmChart[]>("helm_search_repo", { clusterId, query });
|
|
|
|
|
|
|
|
|
|
export const helmListReleasesCmd = (clusterId: string, namespace: string) =>
|
|
|
|
|
invoke<HelmRelease[]>("helm_list_releases", { clusterId, namespace });
|
|
|
|
|
|
|
|
|
|
export const helmUninstallCmd = (clusterId: string, namespace: string, releaseName: string) =>
|
|
|
|
|
invoke<void>("helm_uninstall", { clusterId, namespace, releaseName });
|
|
|
|
|
|
|
|
|
|
export const helmRollbackCmd = (clusterId: string, namespace: string, releaseName: string, revision?: number) =>
|
|
|
|
|
invoke<void>("helm_rollback", { clusterId, namespace, releaseName, revision });
|
|
|
|
|
|
|
|
|
|
// ─── CRD / Custom Resource Commands ──────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export const listCrdsCmd = (clusterId: string) =>
|
|
|
|
|
invoke<CrdInfo[]>("list_crds", { clusterId });
|
|
|
|
|
|
|
|
|
|
export const listCustomResourcesCmd = (clusterId: string, group: string, version: string, resource: string, namespace: string) =>
|
|
|
|
|
invoke<CustomResourceInfo[]>("list_custom_resources", { clusterId, group, version, resource, namespace });
|