feat: Add new tools and configurations for Castle platform

- Introduced `uv.lock` for dependency management with various packages including `pytest`, `colorama`, and `pluggy`.
- Added `pyrightconfig.json` for Python type checking configuration.
- Expanded `recommendations.md` with detailed scaling recommendations and project management strategies.
- Created shared `ruff.toml` for consistent linting across projects.
- Developed `Castle Tools` with various utilities including Android backup, browser automation, document conversion, and search tools.
- Implemented `backup-collect` and `schedule` tools for system administration tasks.
- Enhanced `search` functionality with indexing and querying capabilities using Tantivy.
- Added comprehensive documentation for each tool, including usage examples and installation instructions.
This commit is contained in:
2026-02-20 16:41:19 -08:00
parent 0d35ac9ffd
commit f39a551aad
152 changed files with 21197 additions and 83 deletions

View File

@@ -0,0 +1,76 @@
import { useEffect } from "react"
import { useQuery, useQueryClient, useMutation } from "@tanstack/react-query"
import { apiClient } from "./client"
import type {
ComponentSummary,
ComponentDetail,
StatusResponse,
GatewayInfo,
ServiceActionResponse,
SSEHealthEvent,
} from "@/types"
export function useComponents() {
return useQuery({
queryKey: ["components"],
queryFn: () => apiClient.get<ComponentSummary[]>("/components"),
})
}
export function useComponent(name: string) {
return useQuery({
queryKey: ["components", name],
queryFn: () => apiClient.get<ComponentDetail>(`/components/${name}`),
enabled: !!name,
})
}
export function useStatus() {
return useQuery({
queryKey: ["status"],
queryFn: () => apiClient.get<StatusResponse>("/status"),
// SSE provides live updates; this is the fallback poll
refetchInterval: 30_000,
})
}
export function useGateway() {
return useQuery({
queryKey: ["gateway"],
queryFn: () => apiClient.get<GatewayInfo>("/gateway"),
})
}
export function useServiceAction() {
return useMutation({
mutationFn: ({ name, action }: { name: string; action: string }) =>
apiClient.post<ServiceActionResponse>(`/services/${name}/${action}`),
// SSE health event handles the UI update; no need to refetch here
})
}
export function useEventStream() {
const qc = useQueryClient()
useEffect(() => {
const url = apiClient.streamUrl("/stream")
const es = new EventSource(url)
es.addEventListener("health", (e) => {
const data: SSEHealthEvent = JSON.parse(e.data)
qc.setQueryData<StatusResponse>(["status"], { statuses: data.statuses })
})
es.addEventListener("service-action", () => {
// Health event already pushes correct status; just refetch components
// in case the action changed what's available
qc.invalidateQueries({ queryKey: ["components"] })
})
es.onerror = () => {
// EventSource auto-reconnects; nothing to do
}
return () => es.close()
}, [qc])
}