Enable chat agents to queue and monitor executor-owned verification runs. - Persist task verification requests through a new PostgreSQL migration. - Expose action-gated chat request and status tools with executor processing. - Show verification status in task and Command Center views. - Advance the schema baseline to migration 0024 and keep chat mocks complete. Files changed: .changeset/fn-8296-feature.md | 7 ++ docs/agent-tool-surface-full-loop.md | 10 +-- docs/dashboard-guide.md | 4 + packages/core/src/index.ts | 2 + .../core/src/postgres/migrations/0000_initial.sql | 20 +++++ .../migrations/0024_task_verification_request.sql | 20 +++++ packages/core/src/postgres/schema-applier.ts | 13 ++- packages/core/src/postgres/schema/project.ts | 25 ++++++ packages/core/src/store.ts | 16 +++- packages/core/src/task-store/reads.ts | 14 +++- packages/core/src/task-store/remaining-ops-6.ts | 49 ++++++++++- packages/core/src/types.ts | 30 +++++++ packages/dashboard/app/api/legacy.ts | 1 + packages/dashboard/app/api/task-content.ts | 10 +++ .../dashboard/app/components/TaskDetailModal.tsx | 17 +++- .../app/components/TaskVerificationStatus.css | 94 ++++++++++++++++++++++ .../app/components/TaskVerificationStatus.tsx | 39 +++++++++ .../__tests__/TaskVerificationStatus.test.tsx | 28 +++++++ .../components/command-center/CommandCenter.css | 33 ++++++++ .../components/command-center/CommandCenter.tsx | 37 ++++++++- packages/dashboard/src/__tests__/chat.test.ts | 1 + packages/dashboard/src/chat.ts | 55 +++++++++++++ .../src/routes/register-command-center-routes.ts | 20 +++++ .../src/routes/register-task-workflow-routes.ts | 17 ++++ packages/engine/src/executor.ts | 51 +++++++++++- packages/engine/src/gating-classifications.ts | 5 ++ packages/engine/src/index.ts | 2 +- 27 files changed, 605 insertions(+), 15 deletions(-) Fusion-Task-Id: FN-8296 Fusion-Task-Lineage: f94647cf-c89f-4f0e-b25f-cbf5b56683bc Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
40 lines
2.2 KiB
TypeScript
40 lines
2.2 KiB
TypeScript
import type { TaskVerificationRequest } from "@fusion/core";
|
|
import { AlertCircle, CheckCircle2, Loader2 } from "lucide-react";
|
|
import "./TaskVerificationStatus.css";
|
|
|
|
function formatDuration(durationMs: number | undefined): string | null {
|
|
if (typeof durationMs !== "number") return null;
|
|
return `${(durationMs / 1000).toFixed(1)}s`;
|
|
}
|
|
|
|
/**
|
|
* FNXC:TaskVerificationStatus 2026-07-30-00:00:
|
|
* FN-8296 exposes executor-owned verification as persisted state in every human
|
|
* surface. This component deliberately renders a record only; it never offers a
|
|
* command control or reimplements the chat/executor permission boundary.
|
|
*/
|
|
export function TaskVerificationStatus({ request, compact = false }: { request: TaskVerificationRequest | null; compact?: boolean }) {
|
|
if (!request) return compact ? null : <p className="task-verification-status task-verification-status--empty">No chat verification requested.</p>;
|
|
|
|
const running = request.status === "requested" || request.status === "running";
|
|
const failed = request.status === "failed" || request.status === "rejected";
|
|
const Icon = running ? Loader2 : failed ? AlertCircle : CheckCircle2;
|
|
const summary = request.status === "rejected"
|
|
? request.rejectionReason ?? "Request rejected"
|
|
: request.result
|
|
? `${request.result.success ? "Passed" : "Failed"}${formatDuration(request.result.durationMs) ? ` · ${formatDuration(request.result.durationMs)}` : ""}`
|
|
: request.status === "requested" ? "Queued for the task executor" : "Running in the task worktree";
|
|
|
|
return (
|
|
<section className={`task-verification-status task-verification-status--${request.status}${compact ? " task-verification-status--compact" : ""}`} aria-live="polite" data-testid="task-verification-status">
|
|
<div className="task-verification-status__heading">
|
|
<Icon aria-hidden="true" className={running ? "task-verification-status__spinner" : undefined} />
|
|
<strong>Verification · {request.profile}</strong>
|
|
<span className="task-verification-status__state">{request.status}</span>
|
|
</div>
|
|
<p>{summary}</p>
|
|
{!compact && request.result?.stderrTail ? <pre className="task-verification-status__output">{request.result.stderrTail}</pre> : null}
|
|
</section>
|
|
);
|
|
}
|