chore(runtime): harden worktree and heartbeat flows

This commit is contained in:
dotta authored and Dotta committed 2026-04-10 10:11:31 -05:00
1 parent 0e87fdbe35
commit dcb807cb2f
48 files changed
+15603 -670

No files matched your search

+10 -7
View File
@@ -1,15 +1,18 @@
import type {
HeartbeatRun,
HeartbeatRunEvent,
InstanceSchedulerHeartbeatAgent,
WorkspaceOperation,
} from "@paperclipai/shared";
import type { HeartbeatRun, HeartbeatRunEvent, InstanceSchedulerHeartbeatAgent, WorkspaceOperation } from "@paperclipai/shared";
import { api } from "./client";
export interface ActiveRunForIssue extends HeartbeatRun {
export interface ActiveRunForIssue {
id: string;
status: string;
invocationSource: string;
triggerDetail: string | null;
startedAt: string | Date | null;
finishedAt: string | Date | null;
createdAt: string | Date;
agentId: string;
agentName: string;
adapterType: string;
issueId?: string | null;
}
export interface LiveRunForIssue {
+12 -13
View File
@@ -1,6 +1,6 @@
import { startTransition, useEffect, useMemo, useRef, useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useNavigate, useSearchParams } from "@/lib/router";
import { Link, useNavigate, useSearchParams } from "@/lib/router";
import { Check, ChevronDown, ChevronRight, Layers, MoreHorizontal, Plus, Repeat } from "lucide-react";
import { routinesApi } from "../api/routines";
import { agentsApi } from "../api/agents";
@@ -182,7 +182,7 @@ function RoutineListRow({
agentById,
runningRoutineId,
statusMutationRoutineId,
onNavigate,
href,
onRunNow,
onToggleEnabled,
onToggleArchived,
@@ -192,7 +192,7 @@ function RoutineListRow({
agentById: Map<string, { name: string; icon?: string | null }>;
runningRoutineId: string | null;
statusMutationRoutineId: string | null;
onNavigate: (routineId: string) => void;
href: string;
onRunNow: (routine: RoutineListItem) => void;
onToggleEnabled: (routine: RoutineListItem, enabled: boolean) => void;
onToggleArchived: (routine: RoutineListItem) => void;
@@ -205,9 +205,9 @@ function RoutineListRow({
const isDraft = !isArchived && !routine.assigneeAgentId;
return (
<div
className="group flex cursor-pointer flex-col gap-3 border-b border-border px-3 py-3 transition-colors hover:bg-accent/50 last:border-b-0 sm:flex-row sm:items-center"
onClick={() => onNavigate(routine.id)}
<Link
to={href}
className="group flex flex-col gap-3 border-b border-border px-3 py-3 transition-colors hover:bg-accent/50 last:border-b-0 sm:flex-row sm:items-center no-underline text-inherit"
>
<div className="min-w-0 flex-1 space-y-1.5">
<div className="flex flex-wrap items-center gap-2">
@@ -237,7 +237,7 @@ function RoutineListRow({
</div>
</div>
<div className="flex items-center gap-3" onClick={(event) => event.stopPropagation()}>
<div className="flex items-center gap-3" onClick={(event) => { event.preventDefault(); event.stopPropagation(); }}>
<div className="flex items-center gap-3">
<ToggleSwitch
size="lg"
@@ -258,8 +258,8 @@ function RoutineListRow({
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => onNavigate(routine.id)}>
Edit
<DropdownMenuItem asChild>
<Link to={href}>Edit</Link>
</DropdownMenuItem>
<DropdownMenuItem
disabled={runningRoutineId === routine.id || isArchived}
@@ -283,7 +283,7 @@ function RoutineListRow({
</DropdownMenuContent>
</DropdownMenu>
</div>
</div>
</Link>
);
}
@@ -566,9 +566,8 @@ export function Routines() {
<div className="space-y-6">
<div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
<div className="space-y-1">
<h1 className="text-2xl font-semibold tracking-tight flex items-center gap-2">
<h1 className="text-2xl font-semibold tracking-tight">
Routines
<span className="rounded-full bg-amber-100 px-2 py-0.5 text-xs font-medium text-amber-800 dark:bg-amber-900/30 dark:text-amber-400">Beta</span>
</h1>
<p className="text-sm text-muted-foreground">
Recurring work definitions that materialize into auditable execution issues.
@@ -953,7 +952,7 @@ export function Routines() {
agentById={agentById}
runningRoutineId={runningRoutineId}
statusMutationRoutineId={statusMutationRoutineId}
onNavigate={(routineId) => navigate(`/routines/${routineId}`)}
href={`/routines/${routine.id}`}
onRunNow={handleRunNow}
onToggleEnabled={handleToggleEnabled}
onToggleArchived={handleToggleArchived}