Initial implementation of vault-os
Complete implementation across all 13 phases: - vault-core: types, YAML frontmatter parsing, entity classification, filesystem ops, config, prompt composition, validation, search - vault-watch: filesystem watcher with daemon write filtering, event classification - vault-scheduler: cron engine, process executor, task runner with retry logic and concurrency limiting - vault-api: Axum REST API (15 route modules), WebSocket with broadcast, AI assistant proxy, validation, templates - Dashboard: React + TypeScript + Tailwind v4 with kanban, CodeMirror editor, dynamic view system, AI chat sidebar - Nix flake with dev shell and NixOS module - Graceful shutdown, inotify overflow recovery, tracing instrumentation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
commit
f820a72b04
123 changed files with 18288 additions and 0 deletions
70
dashboard/src/pages/AgentQueuePage.tsx
Normal file
70
dashboard/src/pages/AgentQueuePage.tsx
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
import { useAgentTasks } from '../hooks/useApi';
|
||||
import { StatusBadge } from '../components/StatusBadge';
|
||||
import type { AgentTask, AgentTaskStatus } from '../api/types';
|
||||
|
||||
const COLUMNS: { id: AgentTaskStatus; label: string }[] = [
|
||||
{ id: 'queued', label: 'Queued' },
|
||||
{ id: 'running', label: 'Running' },
|
||||
{ id: 'done', label: 'Done' },
|
||||
{ id: 'failed', label: 'Failed' },
|
||||
];
|
||||
|
||||
export function AgentQueuePage() {
|
||||
const { data: tasks, isLoading } = useAgentTasks();
|
||||
|
||||
const byStatus = (s: AgentTaskStatus) => (tasks || []).filter((t) => t.status === s);
|
||||
|
||||
return (
|
||||
<div className="p-6">
|
||||
<h1 className="mb-4 text-lg font-semibold">Agent Queue</h1>
|
||||
|
||||
{isLoading ? (
|
||||
<div className="text-text-muted">Loading...</div>
|
||||
) : (
|
||||
<div className="flex gap-4">
|
||||
{COLUMNS.map((col) => {
|
||||
const items = byStatus(col.id);
|
||||
return (
|
||||
<div key={col.id} className="w-72 shrink-0">
|
||||
<div className="mb-2 flex items-center justify-between px-1">
|
||||
<h3 className="text-sm font-semibold text-text-secondary">{col.label}</h3>
|
||||
<span className="text-xs text-text-muted">{items.length}</span>
|
||||
</div>
|
||||
<div className="space-y-2 rounded-lg border border-border bg-surface p-2">
|
||||
{items.length === 0 ? (
|
||||
<div className="py-4 text-center text-xs text-text-muted">Empty</div>
|
||||
) : (
|
||||
items.map((task) => <AgentTaskCard key={task.id} task={task} />)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function AgentTaskCard({ task }: { task: AgentTask }) {
|
||||
return (
|
||||
<div className="rounded-lg border border-border bg-surface-raised p-3">
|
||||
<div className="mb-1 text-sm font-medium text-text-primary">{task.title}</div>
|
||||
<div className="flex items-center gap-2 text-xs text-text-secondary">
|
||||
<span>{task.agent}</span>
|
||||
<StatusBadge value={task.priority} />
|
||||
{task.type && <span className="text-text-muted">{task.type}</span>}
|
||||
</div>
|
||||
{task.error && (
|
||||
<div className="mt-2 truncate rounded bg-danger/10 px-2 py-1 text-xs text-danger">
|
||||
{task.error}
|
||||
</div>
|
||||
)}
|
||||
{task.started && (
|
||||
<div className="mt-1 text-xs text-text-muted">
|
||||
started: {new Date(task.started).toLocaleTimeString()}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue