diff --git a/ui/src/App.tsx b/ui/src/App.tsx index e5c7346f86..4a9e971f7c 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -8,7 +8,6 @@ import { OnboardingWizardVariant } from "./components/OnboardingWizardVariant"; import { CloudAccessGate } from "./components/CloudAccessGate"; import { Dashboard } from "./pages/Dashboard"; import { DashboardLive } from "./pages/DashboardLive"; -import { Timeline } from "./pages/Timeline"; import { Companies } from "./pages/Companies"; import { Agents } from "./pages/Agents"; import { AgentDetail } from "./pages/AgentDetail"; @@ -80,7 +79,6 @@ function boardRoutes() { } /> } /> } /> - } /> } /> } /> } /> diff --git a/ui/src/api/workTimeline.ts b/ui/src/api/workTimeline.ts deleted file mode 100644 index 42a22b8ebf..0000000000 --- a/ui/src/api/workTimeline.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { WorkTimelineResult } from "@paperclipai/shared"; -import { api } from "./client"; - -export interface WorkTimelineParams { - from?: string; - to?: string; - /** lens: work kicked off / touched by this user. */ - userId?: string; - goalId?: string; - projectId?: string; - issueId?: string; - limit?: number; -} - -function query(params: WorkTimelineParams): string { - const search = new URLSearchParams(); - if (params.from) search.set("from", params.from); - if (params.to) search.set("to", params.to); - if (params.userId) search.set("userId", params.userId); - if (params.goalId) search.set("goalId", params.goalId); - if (params.projectId) search.set("projectId", params.projectId); - if (params.issueId) search.set("issueId", params.issueId); - if (params.limit) search.set("limit", String(params.limit)); - const qs = search.toString(); - return qs ? `?${qs}` : ""; -} - -export const workTimelineApi = { - get: (companyId: string, params: WorkTimelineParams = {}) => - api.get(`/companies/${companyId}/timeline${query(params)}`), -}; diff --git a/ui/src/components/Sidebar.tsx b/ui/src/components/Sidebar.tsx index ade1f437bc..78cd9b882f 100644 --- a/ui/src/components/Sidebar.tsx +++ b/ui/src/components/Sidebar.tsx @@ -18,7 +18,6 @@ import { PanelLeftOpen, Pin, MessagesSquare, - GanttChartSquare, } from "lucide-react"; import { useQuery } from "@tanstack/react-query"; import { NavLink } from "@/lib/router"; @@ -181,7 +180,6 @@ export function Sidebar() { ) : null} - {showWorkspacesLink ? ( diff --git a/ui/src/components/timeline/WorkTimelineChart.test.tsx b/ui/src/components/timeline/WorkTimelineChart.test.tsx deleted file mode 100644 index 1d42452ca2..0000000000 --- a/ui/src/components/timeline/WorkTimelineChart.test.tsx +++ /dev/null @@ -1,128 +0,0 @@ -// @vitest-environment jsdom - -import { flushSync } from "react-dom"; -import { createRoot, type Root } from "react-dom/client"; -import type { WorkTimelineResult } from "@paperclipai/shared"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { WorkTimelineChart } from "./WorkTimelineChart"; - -vi.mock("@/lib/router", () => ({ - useNavigate: () => vi.fn(), -})); - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -(globalThis as any).IS_REACT_ACT_ENVIRONMENT = true; - -let container: HTMLDivElement; -let root: Root; - -beforeEach(() => { - container = document.createElement("div"); - document.body.appendChild(container); - root = createRoot(container); -}); - -afterEach(() => { - flushSync(() => root.unmount()); - container.remove(); -}); - -function renderChart(data: WorkTimelineResult) { - flushSync(() => { - root.render( - , - ); - }); -} - -function timelineSample(): WorkTimelineResult { - return { - actors: [ - { id: "agent:codex", type: "agent", name: "CodexCoder" }, - { id: "agent:qa", type: "agent", name: "QA" }, - ], - spans: [ - { - actorId: "agent:codex", - laneHint: null, - runId: "run-1", - issueId: "issue-1", - issueIdentifier: "PAP-12443", - issueTitle: "Work Timeline sticky gutter", - start: "2026-07-02T09:00:00.000Z", - end: "2026-07-02T10:00:00.000Z", - status: "completed", - retryOfRunId: null, - }, - { - actorId: "agent:qa", - laneHint: null, - runId: "run-2", - issueId: "issue-2", - issueIdentifier: "PAP-12426", - issueTitle: "QA validation", - start: "2026-07-02T11:00:00.000Z", - end: "2026-07-02T11:30:00.000Z", - status: "completed", - retryOfRunId: null, - }, - ], - events: [], - edges: [], - pagination: { limit: 200, offset: 0, totalIssues: 2, hasMore: false }, - window: { - from: "2026-07-02T00:00:00.000Z", - to: "2026-07-03T00:00:00.000Z", - capped: false, - }, - }; -} - -describe("WorkTimelineChart", () => { - it("renders actor labels in a sticky gutter outside the horizontally scrolling SVG", () => { - renderChart(timelineSample()); - - const scroller = container.querySelector("[data-testid='work-timeline-scroll']"); - const gutter = container.querySelector("[data-testid='work-timeline-actor-gutter']"); - const chartSvg = container.querySelector("svg.absolute"); - - expect(scroller).not.toBeNull(); - expect(gutter).not.toBeNull(); - expect(chartSvg).not.toBeNull(); - expect(gutter?.getAttribute("class")).toContain("sticky"); - expect(gutter?.getAttribute("class")).toContain("left-0"); - expect(gutter?.getAttribute("width")).toBe("176"); - expect(chartSvg?.getAttribute("width")).not.toBe(gutter?.getAttribute("width")); - expect(gutter?.textContent).toContain("CodexCoder"); - - flushSync(() => { - scroller!.scrollLeft = 10_000; - scroller!.dispatchEvent(new Event("scroll", { bubbles: true })); - }); - - expect(container.querySelector("[data-testid='work-timeline-actor-gutter']")?.textContent).toContain("CodexCoder"); - }); - - it("renders a human row with diamond event markers when the payload carries events", () => { - const data = timelineSample(); - data.actors.push({ id: "user:dotta", type: "user", name: "Dotta" }); - data.events = [ - { actorId: "user:dotta", kind: "created", issueId: "issue-1", at: "2026-07-02T08:30:00.000Z" }, - { actorId: "user:dotta", kind: "commented", issueId: "issue-2", at: "2026-07-02T09:15:00.000Z" }, - { actorId: "user:dotta", kind: "approved", issueId: "issue-1", at: "2026-07-02T10:05:00.000Z" }, - ]; - renderChart(data); - - // Dotta gets a row in the gutter… - const gutter = container.querySelector("[data-testid='work-timeline-actor-gutter']"); - expect(gutter?.textContent).toContain("Dotta"); - // …and her three instant events render as clickable diamond marker paths. - const markers = container.querySelectorAll("svg.absolute path.cursor-pointer"); - expect(markers).toHaveLength(3); - }); -}); diff --git a/ui/src/components/timeline/WorkTimelineChart.tsx b/ui/src/components/timeline/WorkTimelineChart.tsx deleted file mode 100644 index 7b56b68107..0000000000 --- a/ui/src/components/timeline/WorkTimelineChart.tsx +++ /dev/null @@ -1,576 +0,0 @@ -/** - * Work Timeline — custom-SVG Gantt (board-locked Direction C, PAP-12422). - * - * Renders actor rows with concurrency sub-lanes, run bars (no issue IDs on the - * bar — identity is the thin left colour tab; truncated title shows on hover), - * kickoff avatar chips at each bar's leading edge (incl. humans), straight - * agent→agent delegation connectors (dashed for retries), an in-progress fade to - * "now", a hover tooltip, and a full-window mini-map with a draggable brush. - */ -import { useMemo, useRef, useState } from "react"; -import { useNavigate } from "@/lib/router"; -import type { - TimelineEventKind, - WorkTimelineActor, - WorkTimelineResult, -} from "@paperclipai/shared"; -import { - AXIS_H, - actorType, - chooseTickStepMs, - computeLayout, - formatDuration, - issueColor, - shortLabel, - type ColorMode, - type LayoutOptions, - type PositionedBar, - type PositionedMarker, -} from "@/lib/timeline/layout"; - -export type ZoomLevel = "hour" | "day" | "week"; - -const ZOOM_PX_PER_MIN: Record = { - hour: 8, - day: 1.6, - week: 0.32, -}; - -/** Pick an initial zoom whose plotted width comfortably fills a typical viewport. */ -export function defaultZoomForWindow(fromMs: number, toMs: number): ZoomLevel { - const hours = (toMs - fromMs) / 3_600_000; - if (hours <= 4) return "hour"; - if (hours <= 48) return "day"; - return "week"; -} - -const GEOM: Omit = { - gutter: 176, - rowH: 34, - barH: 15, - laneGap: 4, -}; -const AVATAR_R = 11; -const CHIP_R = 9; -const MARKER_R = 5.5; - -/** - * Per-kind styling for instant event markers (diamonds). Each kind gets a - * distinct fill + verb so created / commented / approved / delegated / assigned - * read apart at a glance; the hues sit mid-lightness so they hold on light+dark. - */ -const EVENT_STYLE: Record = { - created: { fill: "hsl(145 55% 42%)", verb: "created" }, - commented: { fill: "hsl(212 62% 54%)", verb: "commented on" }, - approved: { fill: "hsl(265 52% 60%)", verb: "approved" }, - delegated: { fill: "hsl(28 78% 52%)", verb: "delegated" }, - assigned: { fill: "hsl(190 58% 44%)", verb: "assigned" }, -}; - -interface TooltipState { - x: number; - y: number; - bar: PositionedBar; -} - -interface MarkerTooltipState { - x: number; - y: number; - marker: PositionedMarker; - /** resolved issue label (identifier/title) or the raw id as a fallback. */ - issueLabel: string; -} - -function fmtClock(ms: number): string { - const d = new Date(ms); - return `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`; -} - -function fmtTick(ms: number, stepMs: number): string { - const d = new Date(ms); - if (stepMs >= 24 * 60 * 60 * 1000) { - return `${d.getMonth() + 1}/${d.getDate()}`; - } - return fmtClock(ms); -} - -function truncate(text: string, n = 42): string { - return text.length > n ? `${text.slice(0, n - 1)}…` : text; -} - -/** An SVG avatar glyph: square for humans, dashed circle for system, circle for agents. */ -function AvatarGlyph({ - cx, - cy, - r, - label, - type, -}: { - cx: number; - cy: number; - r: number; - label: string; - type: string; -}) { - const stroke = "var(--color-foreground)"; - const fill = type === "system" ? "var(--color-muted)" : "var(--color-card)"; - return ( - - {type === "user" ? ( - - ) : ( - - )} - 10 ? 9 : 8} textAnchor="middle" fill={stroke}> - {label} - - - ); -} - -export interface WorkTimelineChartProps { - data: WorkTimelineResult; - zoom: ZoomLevel; - colorMode: ColorMode; - /** override "now" (tests / stories); defaults to Date.now(). */ - nowMs?: number; -} - -export function WorkTimelineChart({ data, zoom, colorMode, nowMs }: WorkTimelineChartProps) { - const navigate = useNavigate(); - const scrollRef = useRef(null); - const [tooltip, setTooltip] = useState(null); - const [markerTooltip, setMarkerTooltip] = useState(null); - const [scrollLeft, setScrollLeft] = useState(0); - const [viewportW, setViewportW] = useState(0); - - const now = nowMs ?? Date.now(); - const layout = useMemo( - () => computeLayout(data, { ...GEOM, pxPerMinute: ZOOM_PX_PER_MIN[zoom], nowMs: now }), - [data, zoom, now], - ); - - // Resolve an event's issue to its human label (identifier/title) via the legend - // hue map, falling back to the raw id for issues that have no run in-window. - const issueLabelById = useMemo( - () => new Map(layout.issues.map((i) => [i.key, i.label])), - [layout.issues], - ); - - const stepMs = chooseTickStepMs(layout.pxPerMinute); - const ticks: number[] = []; - const startTick = Math.ceil(layout.fromMs / stepMs) * stepMs; - for (let ms = startTick; ms <= layout.toMs; ms += stepMs) ticks.push(ms); - - const barFill = (bar: PositionedBar): string => { - if (colorMode === "status") { - if (bar.running) return "url(#tl-hatchV)"; - if (bar.span.status.includes("change") || bar.span.status.includes("fail") || bar.span.status === "blocked") - return "url(#tl-hatchD)"; - return "var(--color-card)"; - } - return "var(--color-card)"; - }; - - const openIssue = (issueId: string) => navigate(`/issues/${issueId}`); - - const showTooltip = (evt: React.MouseEvent, bar: PositionedBar) => { - setTooltip({ x: evt.clientX, y: evt.clientY, bar }); - }; - - const showMarkerTooltip = (evt: React.MouseEvent, marker: PositionedMarker) => { - const issueLabel = issueLabelById.get(marker.event.issueId) ?? marker.event.issueId; - setMarkerTooltip({ x: evt.clientX, y: evt.clientY, marker, issueLabel }); - }; - - return ( -
-
setScrollLeft(e.currentTarget.scrollLeft)} - > -
- - - { - if (el && viewportW === 0 && scrollRef.current) setViewportW(scrollRef.current.clientWidth); - }} - > - - - - - - - - - - - - - - - - {/* row backgrounds */} - {layout.rows.map((row, i) => ( - - ))} - - {/* gridlines + time labels */} - {ticks.map((ms) => { - const gx = layout.gutter + ((ms - layout.fromMs) / 60000) * layout.pxPerMinute; - return ( - - - - {fmtTick(ms, stepMs)} - - - ); - })} - - {/* now line */} - {now >= layout.fromMs && now <= layout.toMs && ( - - )} - - {/* gutter divider + axis baseline */} - - - - {/* connectors (behind bars) */} - {layout.connectors.map((c, i) => { - const ang = (Math.atan2(c.y2 - c.y1, c.x2 - c.x1) * 180) / Math.PI; - return ( - - - - - - ); - })} - - {/* rows: gutter avatar/label, lane baselines, bars, chips */} - {layout.rows.map((row) => { - const cy = row.y + AXIS_H + row.h / 2; - return ( - - - - {truncate(row.actor.name, 18)} - - - {row.actor.type} - - - {Array.from({ length: row.laneCount }).map((_, ln) => { - const ly = row.y + AXIS_H + 6 + ln * (GEOM.barH + GEOM.laneGap) + GEOM.barH / 2; - return ( - - ); - })} - - {row.bars.map((bar) => { - const yTop = bar.yTop + AXIS_H; - const w = bar.x2 - bar.x1; - const hue = issueColor(bar.span.issueId); - return ( - - showTooltip(e, bar)} - onMouseLeave={() => setTooltip(null)} - onClick={() => openIssue(bar.span.issueId)} - > - - {/* left colour tab = issue identity (no textual ID on the bar) */} - - {/* in-progress fade to "now" */} - {bar.running && w > 8 && ( - - )} - - {bar.kickoff && ( - - - - )} - - ); - })} - - {/* instant event markers — diamonds at x(event.at) on this row */} - {row.markers.map((marker) => { - const style = EVENT_STYLE[marker.event.kind]; - const mx = marker.x; - const my = marker.yc + AXIS_H; - return ( - showMarkerTooltip(e, marker)} - onMouseLeave={() => setMarkerTooltip(null)} - /> - ); - })} - - ); - })} - -
-
- - - - {tooltip && } - {markerTooltip && } -
- ); -} - -function MarkerTooltip({ tooltip }: { tooltip: MarkerTooltipState }) { - const { marker, issueLabel } = tooltip; - const style = EVENT_STYLE[marker.event.kind]; - const atMs = new Date(marker.event.at).getTime(); - const left = Math.min(tooltip.x + 14, (typeof window !== "undefined" ? window.innerWidth : 1200) - 300); - return ( -
-
- - {style?.verb ?? marker.event.kind} - {truncate(issueLabel, 28)} -
-
{fmtClock(atMs)}
-
- ); -} - -function ActorGutter({ rows, height }: { rows: ReturnType["rows"]; height: number }) { - return ( - - ); -} - -function Tooltip({ tooltip, now }: { tooltip: TooltipState; now: number }) { - const { bar } = tooltip; - const startMs = new Date(bar.span.start).getTime(); - const endMs = bar.span.end ? new Date(bar.span.end).getTime() : now; - const title = bar.span.issueTitle ?? bar.span.issueIdentifier ?? "run"; - const left = Math.min(tooltip.x + 14, (typeof window !== "undefined" ? window.innerWidth : 1200) - 300); - return ( -
-
{truncate(title)}
-
- {fmtClock(startMs)}–{bar.span.end ? fmtClock(endMs) : "now"} · {formatDuration(startMs, endMs)} ·{" "} - {bar.span.status} -
- {bar.kickoff && ( -
- kicked off by: {(bar.kickoff as WorkTimelineActor).name} - {bar.span.retryOfRunId ? " · retry" : ""} -
- )} -
click → open task
-
- ); -} - -function MiniMap({ - layout, - scrollRef, - viewportW, - scrollLeft, -}: { - layout: ReturnType; - scrollRef: React.RefObject; - viewportW: number; - scrollLeft: number; -}) { - const W = Math.max(320, viewportW || 900); - const H = 54; - const pad = 8; - const spanMs = layout.toMs - layout.fromMs || 1; - const mx = (ms: number) => pad + ((ms - layout.fromMs) / spanMs) * (W - 2 * pad); - - // one thin tick per run, stacked by row order - const rowIndex = new Map(layout.rows.map((r, i) => [r.actor.id, i])); - const laneH = (H - 2 * pad) / Math.max(1, layout.rows.length); - - const frac = layout.width > 0 ? (viewportW || W) / layout.width : 1; - const brushW = Math.max(24, Math.min(1, frac) * (W - 2 * pad)); - const brushX = pad + (layout.width > 0 ? scrollLeft / layout.width : 0) * (W - 2 * pad); - - const seek = (clientX: number, el: SVGSVGElement) => { - const rect = el.getBoundingClientRect(); - const f = Math.min(1, Math.max(0, (clientX - rect.left - pad) / (W - 2 * pad))); - if (scrollRef.current) { - scrollRef.current.scrollLeft = f * layout.width - scrollRef.current.clientWidth / 2; - } - }; - - return ( -
- { - const el = e.currentTarget; - seek(e.clientX, el); - const move = (ev: MouseEvent) => seek(ev.clientX, el); - const up = () => { - document.removeEventListener("mousemove", move); - document.removeEventListener("mouseup", up); - }; - document.addEventListener("mousemove", move); - document.addEventListener("mouseup", up); - }} - > - - {layout.rows.flatMap((row) => - row.bars.map((bar) => { - const startMs = new Date(bar.span.start).getTime(); - const endMs = bar.span.end ? new Date(bar.span.end).getTime() : layout.toMs; - const yy = pad + (rowIndex.get(row.actor.id) ?? 0) * laneH; - return ( - - ); - }), - )} - - -
- ); -} diff --git a/ui/src/lib/queryKeys.ts b/ui/src/lib/queryKeys.ts index 011e3c5cd6..2fbc9a9224 100644 --- a/ui/src/lib/queryKeys.ts +++ b/ui/src/lib/queryKeys.ts @@ -251,7 +251,6 @@ export const queryKeys = { ["company-search", companyId, q, scope, limit, offset] as const, }, dashboard: (companyId: string) => ["dashboard", companyId] as const, - workTimeline: (companyId: string, lens?: string) => ["work-timeline", companyId, lens ?? "all"] as const, userProfile: (companyId: string, userSlug: string) => ["user-profile", companyId, userSlug] as const, sidebarBadges: (companyId: string) => ["sidebar-badges", companyId] as const, diff --git a/ui/src/lib/timeline/layout.test.ts b/ui/src/lib/timeline/layout.test.ts deleted file mode 100644 index 4bb95d3169..0000000000 --- a/ui/src/lib/timeline/layout.test.ts +++ /dev/null @@ -1,197 +0,0 @@ -import { describe, expect, it } from "vitest"; -import type { WorkTimelineResult } from "@paperclipai/shared"; -import { chooseTickStepMs, computeLayout, issueColor, shortLabel, type LayoutOptions } from "./layout"; - -const DAY = "2026-07-02"; -const t = (hhmm: string) => `${DAY}T${hhmm}:00.000Z`; - -// A trimmed version of the board's locked-design sample (PAP-12422), expressed -// in the real endpoint contract: actor→actor edges rather than run→run. -function sample(): WorkTimelineResult { - const actors = [ - { id: "user:dotta", type: "user" as const, name: "dotta" }, - { id: "agent:ceo", type: "agent" as const, name: "CEO" }, - { id: "agent:cto", type: "agent" as const, name: "CTO Architect" }, - { id: "agent:ux", type: "agent" as const, name: "UXDesigner" }, - { id: "agent:senior", type: "agent" as const, name: "SeniorEngineer" }, - { id: "agent:codex", type: "agent" as const, name: "CodexCoder" }, - { id: "agent:qa", type: "agent" as const, name: "QA" }, - { id: "system:routine", type: "system" as const, name: "Circleback" }, - ]; - const span = ( - runId: string, - actorId: string, - issueId: string, - identifier: string, - start: string, - end: string | null, - status: string, - retryOfRunId: string | null = null, - ): WorkTimelineResult["spans"][number] => ({ - actorId, - laneHint: null, - runId, - issueId, - issueIdentifier: identifier, - issueTitle: `${identifier} title`, - start: t(start), - end: end ? t(end) : null, - status, - retryOfRunId, - }); - const spans = [ - span("r1", "agent:ceo", "i-405", "PAP-12405", "09:02", "09:10", "completed"), - span("r2", "agent:cto", "i-405", "PAP-12405", "09:14", "09:52", "completed"), - span("r3", "agent:senior", "i-075", "PAP-12075", "09:58", "10:20", "completed"), - span("r4", "agent:ux", "i-422", "PAP-12422", "10:10", "11:34", "running"), - span("r5", "agent:codex", "i-423", "PAP-12423", "10:10", "10:56", "completed"), - span("r6", "agent:codex", "i-075", "PAP-12075", "10:22", "11:08", "completed"), // overlaps r5 → sub-lane - span("r7", "agent:qa", "i-423", "PAP-12423", "11:40", "12:12", "completed"), - span("r8", "agent:codex", "i-423", "PAP-12423", "12:20", "12:38", "completed", "r5"), // retry - span("r9", "system:routine", "i-286", "PAP-12286", "20:00", "20:04", "completed"), - ]; - const edge = (from: string, to: string, issueId: string, at: string): WorkTimelineResult["edges"][number] => ({ - fromActorId: from, - toActorId: to, - issueId, - at: t(at), - kind: "delegation", - }); - const edges = [ - edge("user:dotta", "agent:ceo", "i-405", "09:01"), // human kickoff → chip only, no line - edge("agent:ceo", "agent:cto", "i-405", "09:13"), - edge("agent:cto", "agent:ux", "i-422", "10:09"), - edge("agent:cto", "agent:codex", "i-423", "10:09"), - edge("agent:senior", "agent:codex", "i-075", "10:21"), - edge("agent:codex", "agent:qa", "i-423", "11:39"), - edge("agent:qa", "agent:codex", "i-423", "12:19"), // → retry r8 (dashed) - ]; - return { - actors, - spans, - events: [], - edges, - pagination: { limit: 200, offset: 0, totalIssues: 6, hasMore: false }, - window: { from: t("09:00"), to: t("20:15"), capped: false }, - }; -} - -const OPTS: LayoutOptions = { - pxPerMinute: 1.7, - gutter: 172, - rowH: 34, - barH: 15, - laneGap: 4, - nowMs: new Date(t("13:00")).getTime(), -}; - -describe("computeLayout", () => { - it("excludes humans from rows but keeps agents and system actors", () => { - const layout = computeLayout(sample(), OPTS); - const rowActorTypes = layout.rows.map((r) => r.actor.type); - expect(rowActorTypes).not.toContain("user"); - expect(layout.rows.map((r) => r.actor.id)).toContain("system:routine"); - expect(layout.rows).toHaveLength(7); // 6 agents + 1 system - }); - - it("orders rows by first activity", () => { - const layout = computeLayout(sample(), OPTS); - expect(layout.rows[0].actor.id).toBe("agent:ceo"); - expect(layout.rows[layout.rows.length - 1].actor.id).toBe("system:routine"); - }); - - it("packs overlapping runs into concurrency sub-lanes", () => { - const layout = computeLayout(sample(), OPTS); - const codex = layout.rows.find((r) => r.actor.id === "agent:codex")!; - expect(codex.laneCount).toBe(2); // r5 and r6 overlap - const lanesTop = new Set(codex.bars.map((b) => b.yTop)); - expect(lanesTop.size).toBeGreaterThan(1); - }); - - it("derives the kickoff actor for a run (incl. human) from edges", () => { - const layout = computeLayout(sample(), OPTS); - const codexApi = layout.rows - .find((r) => r.actor.id === "agent:codex")! - .bars.find((b) => b.span.runId === "r5")!; - expect(codexApi.kickoff?.id).toBe("agent:cto"); - - const ceoRun = layout.rows.find((r) => r.actor.id === "agent:ceo")!.bars[0]; - expect(ceoRun.kickoff?.id).toBe("user:dotta"); // human kickoff shown as chip - }); - - it("draws agent→agent connectors only, dashing retries, never from a human", () => { - const layout = computeLayout(sample(), OPTS); - // 6 agent→agent edges resolve to bars; the dotta→ceo human edge draws no line. - expect(layout.connectors.length).toBe(6); - const dashed = layout.connectors.filter((c) => c.dashed); - expect(dashed).toHaveLength(1); // only the QA→codex retry hop - // every connector is left-to-right (source trailing edge → target leading edge) - for (const c of layout.connectors) expect(c.x2).toBeGreaterThanOrEqual(c.x1 - 1); - }); - - it("extends in-progress runs to now and clamps sub-minute bars", () => { - const layout = computeLayout(sample(), OPTS); - const running = layout.rows - .find((r) => r.actor.id === "agent:ux")! - .bars.find((b) => b.span.runId === "r4")!; - expect(running.running).toBe(true); - expect(running.x2).toBeGreaterThan(running.x1 + 3); - }); - - it("produces a deterministic issue hue + legend", () => { - const layout = computeLayout(sample(), OPTS); - expect(layout.issues.length).toBe(5); // i-405, i-075, i-422, i-423, i-286 - expect(issueColor("i-405")).toBe(issueColor("i-405")); - }); -}); - -describe("human activity markers", () => { - const withUserEvents = (): WorkTimelineResult => ({ - ...sample(), - events: [ - { actorId: "user:dotta", kind: "created", issueId: "i-405", at: t("09:00") }, - { actorId: "user:dotta", kind: "commented", issueId: "i-422", at: t("11:00") }, - { actorId: "user:dotta", kind: "approved", issueId: "i-423", at: t("12:15") }, - ], - }); - - it("gives a human actor a row driven purely by their in-window events", () => { - const layout = computeLayout(withUserEvents(), OPTS); - const dotta = layout.rows.find((r) => r.actor.id === "user:dotta"); - expect(dotta).toBeDefined(); - expect(dotta!.actor.type).toBe("user"); - expect(dotta!.bars).toHaveLength(0); // humans have no runs - }); - - it("positions instant markers at x(event.at) on the owning row, time-ordered", () => { - const layout = computeLayout(withUserEvents(), OPTS); - const dotta = layout.rows.find((r) => r.actor.id === "user:dotta")!; - expect(dotta.markers).toHaveLength(3); - expect(dotta.markers.map((m) => m.event.kind)).toEqual(["created", "commented", "approved"]); - const xs = dotta.markers.map((m) => m.x); - expect(xs).toEqual([...xs].sort((a, b) => a - b)); // monotonic in time - for (const m of dotta.markers) expect(m.yc).toBeCloseTo(dotta.y + dotta.h / 2); - }); - - it("keeps humans marker-only: no run bars, no connectors target them", () => { - const layout = computeLayout(withUserEvents(), OPTS); - // dotta→ceo human kickoff still draws no line; agent→agent count unchanged. - expect(layout.connectors.length).toBe(6); - }); - - it("still excludes a human with no in-window events", () => { - const layout = computeLayout(sample(), OPTS); // events: [] - expect(layout.rows.map((r) => r.actor.type)).not.toContain("user"); - }); -}); - -describe("helpers", () => { - it("shortLabel builds 2-char initials", () => { - expect(shortLabel("CodexCoder")).toBe("CO"); - expect(shortLabel("CTO Architect")).toBe("CA"); - }); - - it("chooseTickStepMs grows the step as the view zooms out", () => { - expect(chooseTickStepMs(6)).toBeLessThan(chooseTickStepMs(0.4)); - }); -}); diff --git a/ui/src/lib/timeline/layout.ts b/ui/src/lib/timeline/layout.ts deleted file mode 100644 index ca99dd1fec..0000000000 --- a/ui/src/lib/timeline/layout.ts +++ /dev/null @@ -1,342 +0,0 @@ -/** - * Work Timeline layout — pure transform from the Phase B endpoint contract - * (`WorkTimelineResult`) into a renderable view model for the custom-SVG Gantt. - * - * Ports the board-locked "Direction C" logic (PAP-12422): agent/system rows only - * (humans never get a row), overlapping runs packed into concurrency sub-lanes, - * a kickoff actor derived per run (shown as an avatar chip — may be a human), - * and straight agent→agent delegation connectors from a source bar's trailing - * edge to a target bar's leading edge (dashed for retries / changes-requested). - * - * Everything here is deterministic given (result, options) so it can be unit - * tested without a DOM. - */ -import type { - WorkTimelineActor, - WorkTimelineEdge, - WorkTimelineEvent, - WorkTimelineResult, - WorkTimelineSpan, -} from "@paperclipai/shared"; - -export type ColorMode = "issue" | "status"; - -export interface LayoutOptions { - /** px per minute along the x axis (set by the zoom level). */ - pxPerMinute: number; - /** width of the left actor gutter in px. */ - gutter: number; - /** row height in px. */ - rowH: number; - /** bar height in px. */ - barH: number; - /** vertical gap between concurrency sub-lanes in px. */ - laneGap: number; - /** wall-clock "now" in ms, used to close in-progress runs. */ - nowMs: number; -} - -export interface PositionedBar { - span: WorkTimelineSpan; - /** leading (start) x in px. */ - x1: number; - /** trailing (end) x in px. */ - x2: number; - /** vertical center of the bar in px. */ - yc: number; - /** top of the bar in px. */ - yTop: number; - height: number; - running: boolean; - /** the actor who kicked this run off, if resolvable (may be a human/user). */ - kickoff: WorkTimelineActor | null; -} - -/** - * An instant human/actor action (issue created, comment, approval, delegation, - * assignment) — plotted as a diamond marker at its timestamp on the actor's row. - * Humans have no "runs", so these markers are their only presence on the chart. - */ -export interface PositionedMarker { - event: WorkTimelineEvent; - /** x position (px) of the marker centre = x(event.at). */ - x: number; - /** vertical centre of the marker in px (row-relative, excludes axis offset). */ - yc: number; -} - -export interface ActorRow { - actor: WorkTimelineActor; - /** top of the row (excluding axis offset) in px. */ - y: number; - /** row height in px. */ - h: number; - laneCount: number; - bars: PositionedBar[]; - /** instant event markers (issue created / comment / approval / …) on this row. */ - markers: PositionedMarker[]; -} - -export interface Connector { - x1: number; - y1: number; - x2: number; - y2: number; - /** dashed = a return / retry (changes-requested) hop. */ - dashed: boolean; -} - -export interface TimelineLayout { - rows: ActorRow[]; - connectors: Connector[]; - /** full inner width of the chart (gutter + plotted time + pad). */ - width: number; - /** full height of the chart including the axis strip. */ - height: number; - /** domain start (ms). */ - fromMs: number; - /** domain end (ms). */ - toMs: number; - gutter: number; - pxPerMinute: number; - /** ordered list of distinct issue keys present, for the legend + hue map. */ - issues: { key: string; label: string; color: string }[]; -} - -export const AXIS_H = 22; -const RUNNING_STATUSES = new Set(["running", "in_progress", "queued", "pending"]); - -export function isRunningStatus(status: string): boolean { - return RUNNING_STATUSES.has(status); -} - -export function actorType(actor: WorkTimelineActor | undefined): string { - return actor?.type ?? "system"; -} - -/** Deterministic, stable hue per issue that reads on both light and dark. */ -export function issueColor(key: string): string { - let hash = 0; - for (let i = 0; i < key.length; i++) { - hash = (hash * 31 + key.charCodeAt(i)) & 0xffffffff; - } - const hue = Math.abs(hash) % 360; - return `hsl(${hue} 62% 52%)`; -} - -/** 2-char initials for an SVG avatar chip. */ -export function shortLabel(name: string): string { - const parts = name.trim().split(/\s+/).filter(Boolean); - if (parts.length >= 2) return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase(); - return (name.slice(0, 2) || "?").toUpperCase(); -} - -function spanStartMs(s: WorkTimelineSpan): number { - return new Date(s.start).getTime(); -} - -function spanEndMs(s: WorkTimelineSpan, nowMs: number): number { - const raw = s.end ? new Date(s.end).getTime() : nowMs; - return raw; -} - -/** - * Resolve the kickoff actor for a run: the source of the delegation/assignment - * edge that points at this run's actor on this run's issue, closest at-or-before - * the run start (falling back to the nearest such edge). Mirrors the design's - * "avatar chip at the leading edge = who kicked it off". - */ -function resolveKickoff( - span: WorkTimelineSpan, - edges: WorkTimelineEdge[], - actorById: Map, -): WorkTimelineActor | null { - const start = spanStartMs(span); - let best: { edge: WorkTimelineEdge; delta: number } | null = null; - for (const e of edges) { - if (e.toActorId !== span.actorId || e.issueId !== span.issueId) continue; - if (e.fromActorId === span.actorId) continue; // self-kickoff is not a delegation - const at = new Date(e.at).getTime(); - // Prefer edges at-or-before the run start; otherwise smallest absolute gap. - const delta = at <= start ? start - at : (start - at) + 1e12; - if (!best || delta < best.delta) best = { edge: e, delta }; - } - if (!best) return null; - return actorById.get(best.edge.fromActorId) ?? null; -} - -export function computeLayout(result: WorkTimelineResult, opts: LayoutOptions): TimelineLayout { - const { pxPerMinute, gutter, rowH, barH, laneGap, nowMs } = opts; - const fromMs = new Date(result.window.from).getTime(); - const toMs = new Date(result.window.to).getTime(); - const actorById = new Map(result.actors.map((a) => [a.id, a])); - - const x = (ms: number) => gutter + ((ms - fromMs) / 60000) * pxPerMinute; - - // Rows: any actor with in-window activity gets a row — agents/system via their - // runs (spans), and humans (type "user") via their instant events, since humans - // have no "runs" and would otherwise never appear. Order by first activity so the - // eye follows the delegation chain top-to-bottom. - const firstActivity = new Map(); - const noteActivity = (actorId: string, t: number) => { - const cur = firstActivity.get(actorId); - if (cur === undefined || t < cur) firstActivity.set(actorId, t); - }; - for (const s of result.spans) noteActivity(s.actorId, spanStartMs(s)); - for (const e of result.events) noteActivity(e.actorId, new Date(e.at).getTime()); - - // Instant events grouped by the actor who performed them. - const eventsByActor = new Map(); - for (const e of result.events) { - const arr = eventsByActor.get(e.actorId); - if (arr) arr.push(e); - else eventsByActor.set(e.actorId, [e]); - } - - const rowActors = result.actors - .filter((a) => firstActivity.has(a.id)) // drop idle actors with no run/event in-window - .sort((a, b) => (firstActivity.get(a.id)! - firstActivity.get(b.id)!)); - - // Issue hue map (ordered by first appearance) for the "by issue" color mode + legend. - const issueOrder: string[] = []; - const issueLabel = new Map(); - for (const s of result.spans) { - const key = s.issueId; - if (!issueLabel.has(key)) { - issueOrder.push(key); - issueLabel.set(key, s.issueIdentifier ?? s.issueTitle ?? "issue"); - } - } - const issues = issueOrder.map((key) => ({ key, label: issueLabel.get(key)!, color: issueColor(key) })); - - const barIndex = new Map(); // runId -> bar - const rows: ActorRow[] = []; - let y = 0; - for (const actor of rowActors) { - const runs = result.spans - .filter((s) => s.actorId === actor.id) - .sort((p, q) => spanStartMs(p) - spanStartMs(q)); - - // Greedy pack overlapping runs into sub-lanes. - const laneEnds: number[] = []; - const laneOf = new Map(); - for (const r of runs) { - const rs = spanStartMs(r); - const re = spanEndMs(r, nowMs); - let placed = -1; - for (let ln = 0; ln < laneEnds.length; ln++) { - if (laneEnds[ln] <= rs) { - placed = ln; - break; - } - } - if (placed === -1) { - placed = laneEnds.length; - laneEnds.push(re); - } else { - laneEnds[placed] = re; - } - laneOf.set(r.runId, placed); - } - const laneCount = Math.max(1, laneEnds.length); - const h = Math.max(rowH, laneCount * (barH + laneGap) + 8); - - const bars: PositionedBar[] = runs.map((r) => { - const lane = laneOf.get(r.runId) ?? 0; - const laneTop = y + 6 + lane * (barH + laneGap); - const x1 = x(spanStartMs(r)); - const x2raw = x(spanEndMs(r, nowMs)); - const x2 = Math.max(x1 + 3, x2raw); // clamp sub-minute runs to a visible min width - const bar: PositionedBar = { - span: r, - x1, - x2, - yTop: laneTop, - yc: laneTop + barH / 2, - height: barH, - running: isRunningStatus(r.status), - kickoff: resolveKickoff(r, result.edges, actorById), - }; - barIndex.set(r.runId, bar); - return bar; - }); - - // Instant markers for this actor, positioned at their timestamp on this row. - const markers: PositionedMarker[] = (eventsByActor.get(actor.id) ?? []) - .slice() - .sort((p, q) => new Date(p.at).getTime() - new Date(q.at).getTime()) - .map((event) => ({ - event, - x: x(new Date(event.at).getTime()), - yc: y + h / 2, - })); - - rows.push({ actor, y, h, laneCount, bars, markers }); - y += h; - } - - // Connectors: straight agent→agent lines, connected at both ends. For each bar - // with an agent/system kickoff, connect from the kickoff actor's nearest - // preceding bar (same issue preferred) to this bar's leading edge. - const connectors: Connector[] = []; - for (const row of rows) { - for (const bar of row.bars) { - const k = bar.kickoff; - if (!k || k.type === "user") continue; // agent→agent only; humans stay as chips - const source = nearestSourceBar(k.id, bar, barIndex, nowMs); - if (!source) continue; - connectors.push({ - x1: source.x2, - y1: source.yc, - x2: bar.x1, - y2: bar.yc, - dashed: Boolean(bar.span.retryOfRunId), - }); - } - } - - const width = gutter + ((toMs - fromMs) / 60000) * pxPerMinute + 40; - const height = y + AXIS_H; - return { rows, connectors, width, height, fromMs, toMs, gutter, pxPerMinute, issues }; -} - -/** The kickoff actor's bar that best precedes `target` (same issue preferred). */ -function nearestSourceBar( - kickoffActorId: string, - target: PositionedBar, - barIndex: Map, - nowMs: number, -): PositionedBar | null { - const targetStart = spanStartMs(target.span); - let sameIssue: PositionedBar | null = null; - let anyIssue: PositionedBar | null = null; - for (const bar of barIndex.values()) { - if (bar.span.actorId !== kickoffActorId) continue; - if (bar === target) continue; - const end = spanEndMs(bar.span, nowMs); - if (end > targetStart + 1) continue; // must precede (small tolerance) - if (bar.span.issueId === target.span.issueId) { - if (!sameIssue || spanEndMs(sameIssue.span, nowMs) < end) sameIssue = bar; - } - if (!anyIssue || spanEndMs(anyIssue.span, nowMs) < end) anyIssue = bar; - } - return sameIssue ?? anyIssue; -} - -/** Choose a "nice" gridline step (ms) targeting ~120px between labels. */ -export function chooseTickStepMs(pxPerMinute: number): number { - const targetPx = 120; - const minutesPerTarget = targetPx / pxPerMinute; - const steps = [15, 30, 60, 120, 180, 360, 720, 1440, 2880, 10080]; // minutes - for (const m of steps) { - if (m >= minutesPerTarget) return m * 60000; - } - return steps[steps.length - 1] * 60000; -} - -export function formatDuration(startMs: number, endMs: number): string { - const mins = Math.max(0, Math.round((endMs - startMs) / 60000)); - if (mins >= 1440) return `${Math.floor(mins / 1440)}d ${Math.floor((mins % 1440) / 60)}h`; - if (mins >= 60) return `${Math.floor(mins / 60)}h ${mins % 60}m`; - return `${mins}m`; -} diff --git a/ui/src/pages/Timeline.tsx b/ui/src/pages/Timeline.tsx deleted file mode 100644 index a8efad0828..0000000000 --- a/ui/src/pages/Timeline.tsx +++ /dev/null @@ -1,242 +0,0 @@ -/** - * Work Timeline page (PAP-12424 / Phase C of PAP-12405). - * - * A Gantt-style view of company actor activity built on the Phase B endpoint - * (`GET /companies/:companyId/timeline`). Rendering is the board-locked - * Direction C (PAP-12422): dense rows, mini-map brush, custom inline SVG. - */ -import { useEffect, useMemo, useRef, useState } from "react"; -import { useQuery } from "@tanstack/react-query"; -import { GanttChartSquare } from "lucide-react"; -import type { WorkTimelineActor, WorkTimelineResult } from "@paperclipai/shared"; -import { workTimelineApi, type WorkTimelineParams } from "@/api/workTimeline"; -import { queryKeys } from "@/lib/queryKeys"; -import { useCompany } from "@/context/CompanyContext"; -import { useBreadcrumbs } from "@/context/BreadcrumbContext"; -import { EmptyState } from "@/components/EmptyState"; -import { PageSkeleton } from "@/components/PageSkeleton"; -import { Button } from "@/components/ui/button"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select"; -import { WorkTimelineChart, defaultZoomForWindow, type ZoomLevel } from "@/components/timeline/WorkTimelineChart"; -import { issueColor, type ColorMode } from "@/lib/timeline/layout"; -import { cn } from "@/lib/utils"; - -const EVERYONE = "__everyone__"; - -function Segmented({ - value, - options, - onChange, -}: { - value: T; - options: { value: T; label: string }[]; - onChange: (v: T) => void; -}) { - return ( -
- {options.map((opt, i) => ( - - ))} -
- ); -} - -export function Timeline() { - const { selectedCompanyId } = useCompany(); - const { setBreadcrumbs } = useBreadcrumbs(); - const [zoom, setZoom] = useState("day"); - const zoomTouched = useRef(false); - const setZoomManual = (z: ZoomLevel) => { - zoomTouched.current = true; - setZoom(z); - }; - const [colorMode, setColorMode] = useState("issue"); - const [lensUserId, setLensUserId] = useState(EVERYONE); - // Union of users discovered across fetches so the lens list stays stable. - const [knownUsers, setKnownUsers] = useState([]); - - useEffect(() => { - setBreadcrumbs([{ label: "Timeline" }]); - }, [setBreadcrumbs]); - - const params: WorkTimelineParams = useMemo( - () => (lensUserId === EVERYONE ? {} : { userId: lensUserId.replace(/^user:/, "") }), - [lensUserId], - ); - - const { data, isLoading, error } = useQuery({ - queryKey: queryKeys.workTimeline(selectedCompanyId ?? "", lensUserId), - queryFn: () => workTimelineApi.get(selectedCompanyId!, params), - enabled: !!selectedCompanyId, - }); - - useEffect(() => { - if (!data || zoomTouched.current) return; - setZoom(defaultZoomForWindow(new Date(data.window.from).getTime(), new Date(data.window.to).getTime())); - }, [data]); - - useEffect(() => { - if (!data) return; - setKnownUsers((prev) => { - const byId = new Map(prev.map((u) => [u.id, u])); - for (const a of data.actors) if (a.type === "user") byId.set(a.id, a); - return Array.from(byId.values()); - }); - }, [data]); - - if (!selectedCompanyId) { - return ; - } - - const header = ( -
-
- -

Work Timeline

-
-

- A Gantt view of who did what, when. Rows are actors; bars are heartbeat runs colored by task; - the avatar chip at a bar's leading edge is who kicked it off; straight lines are agent→agent - delegation. Hover a bar for its task & timing; click to open the task. -

-
- ); - - const toolbar = ( -
- - - -
- ); - - return ( -
- {header} - {toolbar} - - {isLoading && } - - {error && ( - - )} - - {data && !isLoading && ( - data.spans.length === 0 ? ( - - ) : ( -
- -
- -
-

- {data.spans.length} run{data.spans.length === 1 ? "" : "s"} ·{" "} - {new Date(data.window.from).toLocaleString()} → {new Date(data.window.to).toLocaleString()} - {data.window.capped ? " · window capped" : ""} -

-
- ) - )} -
- ); -} - -function Legend({ data, colorMode }: { data: WorkTimelineResult; colorMode: ColorMode }) { - if (colorMode === "status") { - return ( -
- - done - - - {" "} - in progress - - - {" "} - changes/blocked - -
- ); - } - const issues = Array.from( - new Map(data.spans.map((s) => [s.issueId, s.issueIdentifier ?? s.issueTitle ?? "task"])).entries(), - ); - return ( -
- {issues.slice(0, 12).map(([id, label]) => ( - - - {label} - - ))} - {issues.length > 12 && +{issues.length - 12} more} -
- ); -} diff --git a/ui/storybook/fixtures/workTimeline.human.sample.json b/ui/storybook/fixtures/workTimeline.human.sample.json deleted file mode 100644 index abbedf4227..0000000000 --- a/ui/storybook/fixtures/workTimeline.human.sample.json +++ /dev/null @@ -1,1824 +0,0 @@ -{ - "actors": [ - { - "id": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "type": "agent", - "name": "QA", - "avatar": "bug" - }, - { - "id": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", - "type": "agent", - "name": "CTO", - "avatar": "file-code" - }, - { - "id": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "type": "agent", - "name": "Senior Engineer Fable", - "avatar": "code" - }, - { - "id": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "type": "agent", - "name": "UXDesigner", - "avatar": "gem" - }, - { - "id": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "type": "user", - "name": "Dotta", - "avatar": "/api/assets/3b1e4f9b-6136-4315-8484-fd9f441aae54/content" - }, - { - "id": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "type": "agent", - "name": "CodexCoder", - "avatar": "code" - }, - { - "id": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "type": "agent", - "name": "CloudOpsEngineer", - "avatar": "cog" - }, - { - "id": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "type": "agent", - "name": "CEO", - "avatar": "crown" - }, - { - "id": "agent:ef2d1ee5-5c42-42fc-8197-5e2386ac34ed", - "type": "agent", - "name": "Strategic Ops", - "avatar": "target" - }, - { - "id": "agent:b8bc4df6-599c-4228-9969-6b041e7c88f8", - "type": "agent", - "name": "Senior Planning Engineer Pro", - "avatar": "code" - }, - { - "id": "system:system", - "type": "system", - "name": "System", - "avatar": null - }, - { - "id": "agent:c9dcefd1-b052-489a-a1f3-4cd1783bcb5f", - "type": "agent", - "name": "DevRel", - "avatar": "globe" - }, - { - "id": "agent:ece64c0e-767e-4d37-a15e-193694daa1d8", - "type": "agent", - "name": "SecurityEngineer", - "avatar": "shield" - }, - { - "id": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "type": "agent", - "name": "ClaudeCoder", - "avatar": "code" - }, - { - "id": "agent:db1c09f1-422c-48c8-9711-4054d3657aac", - "type": "agent", - "name": "ConnectionCoder", - "avatar": "code" - } - ], - "spans": [ - { - "actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "laneHint": "automation", - "runId": "571d1495-fe7e-4cf8-a79f-e4d8d779cecf", - "issueId": "1ae0d728-2f4e-4ec9-ac95-d006a7f19741", - "issueIdentifier": "PAP-12298", - "issueTitle": "blog page redesign", - "start": "2026-07-02T14:42:05.689Z", - "end": "2026-07-02T14:45:37.694Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "laneHint": "assignment", - "runId": "c7a242bb-adf1-46e2-a322-474ed791c7ff", - "issueId": "b5a59535-38f5-4f0d-a0bf-2bf755a4be15", - "issueIdentifier": "PAP-12420", - "issueTitle": "Attach S3 policy to paperclip-page-uploader IAM user for pages.paperclip.ing", - "start": "2026-07-02T14:44:59.649Z", - "end": "2026-07-02T14:48:23.151Z", - "status": "cancelled", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "laneHint": "automation", - "runId": "c214c9f0-b46b-47de-ba86-2520e1a8aa75", - "issueId": "b5a59535-38f5-4f0d-a0bf-2bf755a4be15", - "issueIdentifier": "PAP-12420", - "issueTitle": "Attach S3 policy to paperclip-page-uploader IAM user for pages.paperclip.ing", - "start": "2026-07-02T14:48:23.194Z", - "end": "2026-07-02T14:52:29.939Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "laneHint": "automation", - "runId": "6b0a55a9-7c1a-4d48-bdfb-159370e9c03d", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "issueIdentifier": "PAP-12405", - "issueTitle": "design a ‘gantt chart’ representation of my paperclip work", - "start": "2026-07-02T14:50:35.277Z", - "end": "2026-07-02T14:55:43.520Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", - "laneHint": "assignment", - "runId": "e573c5dc-94b9-4b63-bdb3-c48327a85cea", - "issueId": "9c5003e8-104d-46ae-9389-c62cb6fc8889", - "issueIdentifier": "PAP-12421", - "issueTitle": "CTO/admin: attach corrected pages.paperclip.ing S3 policy to paperclip-page-uploader", - "start": "2026-07-02T14:52:04.426Z", - "end": "2026-07-02T14:56:08.638Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "laneHint": "assignment", - "runId": "8a716a87-61e2-4667-9cc4-3641fe42c6f0", - "issueId": "b868097a-4b8a-447d-a667-a96ebd24e385", - "issueIdentifier": "PAP-12422", - "issueTitle": "Work Timeline — Phase A: wireframe exploration (2–3 directions, board picks one)", - "start": "2026-07-02T14:52:21.788Z", - "end": "2026-07-02T15:07:44.596Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "laneHint": "assignment", - "runId": "4b085459-77b0-41e4-a62f-a76e1ba9b521", - "issueId": "e64a9b35-54e8-430c-9244-18f60c70f87a", - "issueIdentifier": "PAP-12423", - "issueTitle": "Work Timeline — Phase B: timeline aggregation endpoint (GET /companies/:id/timeline)", - "start": "2026-07-02T14:52:21.929Z", - "end": "2026-07-02T15:03:54.376Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "laneHint": "assignment", - "runId": "972b6b5b-5fdd-419d-aea0-5641b4634448", - "issueId": "5a3cf258-ae30-44ba-9b57-494eaf6c0238", - "issueIdentifier": "PAP-12427", - "issueTitle": "CEO/admin: unblock IAM mutation for paperclip-page-uploader pages policy", - "start": "2026-07-02T14:54:41.918Z", - "end": "2026-07-02T14:57:27.722Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "laneHint": "assignment", - "runId": "d14a8901-4569-4f05-b8c2-5e49d4216a6d", - "issueId": "6d12933d-1393-484c-aeb8-17d98e61b8c0", - "issueIdentifier": "PAP-12428", - "issueTitle": "just change the terminology to “Responsible”", - "start": "2026-07-02T14:55:00.330Z", - "end": "2026-07-02T15:01:10.197Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "laneHint": "automation", - "runId": "77ffd755-a755-41e6-b2cb-ee0817f11152", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "issueIdentifier": "PAP-12405", - "issueTitle": "design a ‘gantt chart’ representation of my paperclip work", - "start": "2026-07-02T14:55:43.595Z", - "end": "2026-07-02T14:57:12.235Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "laneHint": "automation", - "runId": "960639c7-f6cc-45ad-b746-22ca507c237d", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "issueIdentifier": "PAP-12405", - "issueTitle": "design a ‘gantt chart’ representation of my paperclip work", - "start": "2026-07-02T14:57:12.287Z", - "end": "2026-07-02T15:12:26.352Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "laneHint": "assignment", - "runId": "a61b657c-d297-43b7-948c-2be7bd161e3b", - "issueId": "5a3cf258-ae30-44ba-9b57-494eaf6c0238", - "issueIdentifier": "PAP-12427", - "issueTitle": "CEO/admin: unblock IAM mutation for paperclip-page-uploader pages policy", - "start": "2026-07-02T14:57:27.831Z", - "end": "2026-07-02T15:01:08.081Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "laneHint": "assignment", - "runId": "67f65027-b802-4e88-91a6-bebb5c94f16b", - "issueId": "0dc1021f-2326-4977-a5b2-7eb4ab66e6df", - "issueIdentifier": "PAP-12429", - "issueTitle": "give the AWS_ keys that ClaudeCoder has to CodexCoder and CloudOpsEngineer and UXDesigner", - "start": "2026-07-02T14:57:50.711Z", - "end": "2026-07-02T15:01:18.973Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "laneHint": "assignment", - "runId": "e9ff0a09-6607-4793-90f3-1b3ab1741ef0", - "issueId": "16901797-89cc-4b85-8213-7a27d70f9d16", - "issueIdentifier": "PAP-12430", - "issueTitle": "merged Create a single PR from this branch PAP-12404-inbox-blocked-but-descendent-live-icon", - "start": "2026-07-02T14:59:42.783Z", - "end": "2026-07-02T15:17:12.936Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:c9dcefd1-b052-489a-a1f3-4cd1783bcb5f", - "laneHint": "assignment", - "runId": "91f67e3b-18ae-4230-8fae-18b414ffcd14", - "issueId": "1533f78d-d677-449f-afd9-4cf653168438", - "issueIdentifier": "PAP-12431", - "issueTitle": "2026-07-02 create a standup message i can copy to slack about everything i've been working on for the last 36 hours", - "start": "2026-07-02T15:00:19.704Z", - "end": "2026-07-02T15:05:16.672Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "laneHint": "assignment", - "runId": "e08e32ae-9106-46e0-9c2b-97ab74520fc4", - "issueId": "0facd02e-425f-4822-875c-2f97988de98a", - "issueIdentifier": "PAP-12432", - "issueTitle": "CEO/admin: apply paperclip-page-uploader pages.paperclip.ing inline policy", - "start": "2026-07-02T15:00:46.697Z", - "end": "2026-07-02T15:06:05.586Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:ece64c0e-767e-4d37-a15e-193694daa1d8", - "laneHint": "automation", - "runId": "12223c0b-0bad-4b95-be56-ceb1ce955b0f", - "issueId": "d6327ba4-5bed-4bad-b860-213256cf127a", - "issueIdentifier": "PAP-12425", - "issueTitle": "Work Timeline — security review: timeline endpoint ACLs and data exposure", - "start": "2026-07-02T15:01:28.563Z", - "end": "2026-07-02T15:05:43.985Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:b8bc4df6-599c-4228-9969-6b041e7c88f8", - "laneHint": "assignment", - "runId": "33181a90-d2af-4081-9deb-253d996d81f1", - "issueId": "09b1e135-e25c-4fb5-a812-48dfd15edd55", - "issueIdentifier": "PAP-12433", - "issueTitle": "project star’ing", - "start": "2026-07-02T15:03:27.392Z", - "end": "2026-07-02T15:52:11.373Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:ef2d1ee5-5c42-42fc-8197-5e2386ac34ed", - "laneHint": "assignment", - "runId": "0961f6e8-a1cd-4493-9979-99775285c748", - "issueId": "7751d27f-c016-4be5-a332-b29b888e8b48", - "issueIdentifier": "PAP-12434", - "issueTitle": "Strategic Ops: get AWS admin to attach pages.paperclip.ing uploader policy", - "start": "2026-07-02T15:05:38.870Z", - "end": "2026-07-02T15:08:15.576Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "laneHint": "assignment", - "runId": "0ecdb797-e6b4-4f12-a5f0-b7bce348138f", - "issueId": "804fff38-a46b-4391-9c44-cd76fd889753", - "issueIdentifier": "PAP-12435", - "issueTitle": "CloudOps: attach pages.paperclip.ing uploader IAM policy", - "start": "2026-07-02T15:07:45.699Z", - "end": "2026-07-02T15:11:13.138Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "laneHint": "assignment", - "runId": "bcfaef62-ca9a-4a96-b279-bf2314108dbf", - "issueId": "40490e19-4e4a-4fa3-8300-719a82d3633a", - "issueIdentifier": "PAP-12403", - "issueTitle": "github and environment variables", - "start": "2026-07-02T15:09:15.958Z", - "end": "2026-07-02T15:20:22.053Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "laneHint": "automation", - "runId": "e4e854bc-9cce-4c5f-bfb9-a2f3c0094075", - "issueId": "b5a59535-38f5-4f0d-a0bf-2bf755a4be15", - "issueIdentifier": "PAP-12420", - "issueTitle": "Attach S3 policy to paperclip-page-uploader IAM user for pages.paperclip.ing", - "start": "2026-07-02T15:10:25.014Z", - "end": "2026-07-02T15:15:34.966Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", - "laneHint": "assignment", - "runId": "b83d9b78-f63c-465c-808c-c1e1175a18c5", - "issueId": "91292c04-bbfe-4a94-9779-baceb3941857", - "issueIdentifier": "PAP-12436", - "issueTitle": "CTO/admin: grant IAM write path for paperclip-page-uploader pages policy", - "start": "2026-07-02T15:10:51.773Z", - "end": "2026-07-02T15:14:59.703Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:ece64c0e-767e-4d37-a15e-193694daa1d8", - "laneHint": "automation", - "runId": "90cd6835-be7c-4dd8-bdf7-017d40df9c38", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "issueIdentifier": "PAP-12405", - "issueTitle": "design a ‘gantt chart’ representation of my paperclip work", - "start": "2026-07-02T15:12:26.440Z", - "end": "2026-07-02T15:14:56.976Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "laneHint": "assignment", - "runId": "f4d1d8a6-c74d-4d59-b831-b788eeaf93f2", - "issueId": "57a438c1-876a-40ce-9b2b-5c8a8b47ec5b", - "issueIdentifier": "PAP-12437", - "issueTitle": "for parent task, cleanup the effecitvely merged ones", - "start": "2026-07-02T15:14:30.602Z", - "end": "2026-07-02T15:20:22.033Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "laneHint": "automation", - "runId": "cd8cf33f-5a1c-4b3a-905e-aabc0341edd1", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "issueIdentifier": "PAP-12405", - "issueTitle": "design a ‘gantt chart’ representation of my paperclip work", - "start": "2026-07-02T15:14:57.094Z", - "end": "2026-07-02T15:16:53.870Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "laneHint": "assignment", - "runId": "a9ba6322-e0e3-43bb-bc0b-2af53bec9610", - "issueId": "91292c04-bbfe-4a94-9779-baceb3941857", - "issueIdentifier": "PAP-12436", - "issueTitle": "CTO/admin: grant IAM write path for paperclip-page-uploader pages policy", - "start": "2026-07-02T15:14:59.782Z", - "end": "2026-07-02T15:20:10.000Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "laneHint": "automation", - "runId": "df0d6959-ef5f-4a75-b710-492cfd6de658", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "issueIdentifier": "PAP-12405", - "issueTitle": "design a ‘gantt chart’ representation of my paperclip work", - "start": "2026-07-02T15:16:53.952Z", - "end": "2026-07-02T15:19:28.111Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "laneHint": "assignment", - "runId": "4cec085d-bf1f-48a2-aef1-62cce353a09f", - "issueId": "e0189c44-1245-4526-9423-1128862d7c95", - "issueIdentifier": "PAP-12438", - "issueTitle": "environment variables editor re-design", - "start": "2026-07-02T15:18:55.386Z", - "end": "2026-07-02T15:26:14.263Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "laneHint": "automation", - "runId": "17e168c3-c2f4-4cef-9492-c4e680bebcf5", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "issueIdentifier": "PAP-12405", - "issueTitle": "design a ‘gantt chart’ representation of my paperclip work", - "start": "2026-07-02T15:19:28.163Z", - "end": "2026-07-02T15:21:38.254Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "laneHint": "automation", - "runId": "8e58708e-88df-4681-84c5-f6a676d1dd6a", - "issueId": "e3afbdcf-98b8-4971-a094-9a92d78736d1", - "issueIdentifier": "PAP-10273", - "issueTitle": "Defect (Minor): preview emits noisy \"skill not present in package\" warnings for catalog-skill references", - "start": "2026-07-02T15:20:20.734Z", - "end": "2026-07-02T15:25:39.352Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "laneHint": "automation", - "runId": "accd3b96-89a2-47f4-a3db-65f94ec6be3a", - "issueId": "6f7ac707-363a-4e77-b3d0-7479165352db", - "issueIdentifier": "PAP-10274", - "issueTitle": "Defect (Minor UX): \"Partial state is not rolled back\" message is incorrect — install transaction rolled back cleanly", - "start": "2026-07-02T15:20:20.784Z", - "end": "2026-07-02T15:28:39.720Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "laneHint": "automation", - "runId": "ebc8e142-c416-4b85-86ff-be0fed98f41f", - "issueId": "153322a9-301d-4868-b15e-a24063ceeca2", - "issueIdentifier": "PAP-10275", - "issueTitle": "Defect (Minor): CLI install lacks --adapter-override and --secret-value flags", - "start": "2026-07-02T15:20:20.854Z", - "end": "2026-07-02T15:22:56.590Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "laneHint": "automation", - "runId": "85339e14-6ac3-459c-99a2-811e0e6adbba", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "issueIdentifier": "PAP-12405", - "issueTitle": "design a ‘gantt chart’ representation of my paperclip work", - "start": "2026-07-02T15:21:38.307Z", - "end": "2026-07-02T15:22:48.667Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "laneHint": "automation", - "runId": "671705a1-718d-4be6-86b4-390295a17a74", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "issueIdentifier": "PAP-12405", - "issueTitle": "design a ‘gantt chart’ representation of my paperclip work", - "start": "2026-07-02T15:22:48.720Z", - "end": "2026-07-02T15:24:16.925Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "laneHint": "automation", - "runId": "cbce714c-a056-477d-971b-3ceb02a4441b", - "issueId": "804fff38-a46b-4391-9c44-cd76fd889753", - "issueIdentifier": "PAP-12435", - "issueTitle": "CloudOps: attach pages.paperclip.ing uploader IAM policy", - "start": "2026-07-02T15:23:13.966Z", - "end": "2026-07-02T15:23:32.715Z", - "status": "cancelled", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "laneHint": "automation", - "runId": "88e7b7a9-4ea6-40bc-b402-ffd731a3dfe2", - "issueId": "1ae0d728-2f4e-4ec9-ac95-d006a7f19741", - "issueIdentifier": "PAP-12298", - "issueTitle": "blog page redesign", - "start": "2026-07-02T15:23:28.308Z", - "end": "2026-07-02T15:29:09.108Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "laneHint": "assignment", - "runId": "1b734867-943b-4ef3-a10e-3f2c1edcad93", - "issueId": "f5b13e28-cbe4-40e5-bd29-d88eb8ea0ee3", - "issueIdentifier": "PAP-12439", - "issueTitle": "Wireframes: Environment Variables Editor redesign", - "start": "2026-07-02T15:25:07.982Z", - "end": "2026-07-02T15:32:24.457Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "laneHint": "automation", - "runId": "2bd1ec14-ecbb-42d8-8412-106a251780b8", - "issueId": "e0189c44-1245-4526-9423-1128862d7c95", - "issueIdentifier": "PAP-12438", - "issueTitle": "environment variables editor re-design", - "start": "2026-07-02T15:26:14.310Z", - "end": "2026-07-02T15:34:59.661Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", - "laneHint": "assignment", - "runId": "9eb8e7ba-53b5-4d22-8f8d-cbba6a5c5bb5", - "issueId": "9ae0377a-8040-4221-9376-4ae64270e3b4", - "issueIdentifier": "PAP-12440", - "issueTitle": "Defect (Minor): teams-catalog install is not atomic — mid-import failure can orphan skills/agents", - "start": "2026-07-02T15:27:39.339Z", - "end": "2026-07-02T15:37:04.236Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "assignment" - }, - { - "actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "laneHint": "automation", - "runId": "339694a1-6a7d-4de0-8466-43574a7c6b4d", - "issueId": "b868097a-4b8a-447d-a667-a96ebd24e385", - "issueIdentifier": "PAP-12422", - "issueTitle": "Work Timeline — Phase A: wireframe exploration (2–3 directions, board picks one)", - "start": "2026-07-02T15:28:13.886Z", - "end": "2026-07-02T15:42:27.258Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "laneHint": "automation", - "runId": "040ce2ef-acd4-47f2-bcf1-5a1194f5a450", - "issueId": "e0189c44-1245-4526-9423-1128862d7c95", - "issueIdentifier": "PAP-12438", - "issueTitle": "environment variables editor re-design", - "start": "2026-07-02T15:34:59.718Z", - "end": "2026-07-02T15:38:04.415Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "laneHint": "automation", - "runId": "20f1e461-b4b6-4d5f-b897-6f60656429fb", - "issueId": "1ae0d728-2f4e-4ec9-ac95-d006a7f19741", - "issueIdentifier": "PAP-12298", - "issueTitle": "blog page redesign", - "start": "2026-07-02T15:35:56.578Z", - "end": "2026-07-02T15:38:40.543Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - }, - { - "actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "laneHint": "automation", - "runId": "063a9727-b191-49e2-9802-b6b63ec65b97", - "issueId": "3c1b19ae-9064-4d78-8bf4-c3983a7730d6", - "issueIdentifier": "PAP-12424", - "issueTitle": "Work Timeline — Phase C: frontend Gantt component + Timeline page", - "start": "2026-07-02T15:41:30.586Z", - "end": "2026-07-02T16:06:58.629Z", - "status": "succeeded", - "retryOfRunId": null, - "continuationAttempt": 0, - "invocationSource": "automation" - } - ], - "events": [ - { - "actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "kind": "created", - "issueId": "e3afbdcf-98b8-4971-a094-9a92d78736d1", - "at": "2026-06-03T19:39:46.628Z" - }, - { - "actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "kind": "created", - "issueId": "6f7ac707-363a-4e77-b3d0-7479165352db", - "at": "2026-06-03T19:40:14.945Z" - }, - { - "actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "kind": "created", - "issueId": "153322a9-301d-4868-b15e-a24063ceeca2", - "at": "2026-06-03T19:40:14.974Z" - }, - { - "actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "kind": "created", - "issueId": "5e955520-f5ea-4ad4-aef6-860c95b1797e", - "at": "2026-06-03T20:23:11.278Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "created", - "issueId": "bc7a42bb-91bb-40b3-b3a8-6f9ebf98bc94", - "at": "2026-06-30T22:22:13.060Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "created", - "issueId": "6ff91230-ab9d-4b95-9590-1471ae37297e", - "at": "2026-07-01T16:31:55.423Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "created", - "issueId": "1ae0d728-2f4e-4ec9-ac95-d006a7f19741", - "at": "2026-07-01T18:23:43.255Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "created", - "issueId": "48264b4d-0004-4015-9ca0-08c867eed064", - "at": "2026-07-02T00:13:22.977Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "created", - "issueId": "2e375459-115c-4f0c-a1c8-59e359b5c3f6", - "at": "2026-07-02T02:21:56.069Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "created", - "issueId": "df84e69c-35e1-4323-a95f-e10d27b3227c", - "at": "2026-07-02T02:39:19.891Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "created", - "issueId": "ad7f2c54-6e50-421f-a805-4c743948421a", - "at": "2026-07-02T03:29:27.493Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "created", - "issueId": "44c2c3d2-7dc0-44df-beb6-ad2417b81503", - "at": "2026-07-02T04:45:14.251Z" - }, - { - "actorId": "agent:b8bc4df6-599c-4228-9969-6b041e7c88f8", - "kind": "delegated", - "issueId": "44c2c3d2-7dc0-44df-beb6-ad2417b81503", - "at": "2026-07-02T04:45:14.251Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "created", - "issueId": "40490e19-4e4a-4fa3-8300-719a82d3633a", - "at": "2026-07-02T04:52:34.737Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "created", - "issueId": "db6e4af1-0669-42d0-a6ef-e12dcfd7112d", - "at": "2026-07-02T04:56:04.034Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "created", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "at": "2026-07-02T05:07:46.810Z" - }, - { - "actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "kind": "created", - "issueId": "abe00e5c-bbcd-4782-ba9e-13532a09184f", - "at": "2026-07-02T05:08:53.619Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "approved", - "issueId": "1ae0d728-2f4e-4ec9-ac95-d006a7f19741", - "at": "2026-07-02T14:42:05.663Z" - }, - { - "actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "kind": "created", - "issueId": "b5a59535-38f5-4f0d-a0bf-2bf755a4be15", - "at": "2026-07-02T14:44:59.609Z" - }, - { - "actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "kind": "delegated", - "issueId": "b5a59535-38f5-4f0d-a0bf-2bf755a4be15", - "at": "2026-07-02T14:44:59.609Z" - }, - { - "actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "kind": "commented", - "issueId": "1ae0d728-2f4e-4ec9-ac95-d006a7f19741", - "at": "2026-07-02T14:45:19.329Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "commented", - "issueId": "b5a59535-38f5-4f0d-a0bf-2bf755a4be15", - "at": "2026-07-02T14:48:06.921Z" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "kind": "commented", - "issueId": "b5a59535-38f5-4f0d-a0bf-2bf755a4be15", - "at": "2026-07-02T14:48:23.164Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "approved", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "at": "2026-07-02T14:50:35.254Z" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "kind": "created", - "issueId": "9c5003e8-104d-46ae-9389-c62cb6fc8889", - "at": "2026-07-02T14:52:04.388Z" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "kind": "delegated", - "issueId": "9c5003e8-104d-46ae-9389-c62cb6fc8889", - "at": "2026-07-02T14:52:04.388Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "created", - "issueId": "b868097a-4b8a-447d-a667-a96ebd24e385", - "at": "2026-07-02T14:52:21.683Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "delegated", - "issueId": "b868097a-4b8a-447d-a667-a96ebd24e385", - "at": "2026-07-02T14:52:21.683Z" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "kind": "commented", - "issueId": "b5a59535-38f5-4f0d-a0bf-2bf755a4be15", - "at": "2026-07-02T14:52:21.751Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "created", - "issueId": "e64a9b35-54e8-430c-9244-18f60c70f87a", - "at": "2026-07-02T14:52:21.778Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "delegated", - "issueId": "e64a9b35-54e8-430c-9244-18f60c70f87a", - "at": "2026-07-02T14:52:21.778Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "created", - "issueId": "3c1b19ae-9064-4d78-8bf4-c3983a7730d6", - "at": "2026-07-02T14:52:53.705Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "delegated", - "issueId": "3c1b19ae-9064-4d78-8bf4-c3983a7730d6", - "at": "2026-07-02T14:52:53.705Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "created", - "issueId": "d6327ba4-5bed-4bad-b860-213256cf127a", - "at": "2026-07-02T14:53:41.388Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "delegated", - "issueId": "d6327ba4-5bed-4bad-b860-213256cf127a", - "at": "2026-07-02T14:53:41.388Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "created", - "issueId": "a466f1d9-cfb3-4fa1-a354-57d8bee78ce1", - "at": "2026-07-02T14:53:55.809Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "delegated", - "issueId": "a466f1d9-cfb3-4fa1-a354-57d8bee78ce1", - "at": "2026-07-02T14:53:55.809Z" - }, - { - "actorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", - "kind": "created", - "issueId": "5a3cf258-ae30-44ba-9b57-494eaf6c0238", - "at": "2026-07-02T14:54:41.875Z" - }, - { - "actorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", - "kind": "delegated", - "issueId": "5a3cf258-ae30-44ba-9b57-494eaf6c0238", - "at": "2026-07-02T14:54:41.875Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "commented", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "at": "2026-07-02T14:54:44.297Z" - }, - { - "actorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", - "kind": "commented", - "issueId": "9c5003e8-104d-46ae-9389-c62cb6fc8889", - "at": "2026-07-02T14:54:55.966Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "created", - "issueId": "6d12933d-1393-484c-aeb8-17d98e61b8c0", - "at": "2026-07-02T14:55:00.287Z" - }, - { - "actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "kind": "delegated", - "issueId": "6d12933d-1393-484c-aeb8-17d98e61b8c0", - "at": "2026-07-02T14:55:00.287Z" - }, - { - "actorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", - "kind": "commented", - "issueId": "9c5003e8-104d-46ae-9389-c62cb6fc8889", - "at": "2026-07-02T14:55:40.913Z" - }, - { - "actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "kind": "commented", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "at": "2026-07-02T14:57:12.257Z" - }, - { - "actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "kind": "commented", - "issueId": "5a3cf258-ae30-44ba-9b57-494eaf6c0238", - "at": "2026-07-02T14:57:14.910Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "created", - "issueId": "0dc1021f-2326-4977-a5b2-7eb4ab66e6df", - "at": "2026-07-02T14:57:50.676Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "created", - "issueId": "16901797-89cc-4b85-8213-7a27d70f9d16", - "at": "2026-07-02T14:59:42.755Z" - }, - { - "actorId": "system:system", - "kind": "created", - "issueId": "1533f78d-d677-449f-afd9-4cf653168438", - "at": "2026-07-02T15:00:19.659Z" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "kind": "created", - "issueId": "0facd02e-425f-4822-875c-2f97988de98a", - "at": "2026-07-02T15:00:46.643Z" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "kind": "delegated", - "issueId": "0facd02e-425f-4822-875c-2f97988de98a", - "at": "2026-07-02T15:00:46.643Z" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "kind": "commented", - "issueId": "5a3cf258-ae30-44ba-9b57-494eaf6c0238", - "at": "2026-07-02T15:01:00.247Z" - }, - { - "actorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "kind": "commented", - "issueId": "6d12933d-1393-484c-aeb8-17d98e61b8c0", - "at": "2026-07-02T15:01:05.759Z" - }, - { - "actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "kind": "commented", - "issueId": "0dc1021f-2326-4977-a5b2-7eb4ab66e6df", - "at": "2026-07-02T15:01:14.833Z" - }, - { - "actorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "kind": "commented", - "issueId": "e64a9b35-54e8-430c-9244-18f60c70f87a", - "at": "2026-07-02T15:01:28.524Z" - }, - { - "actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "kind": "commented", - "issueId": "0facd02e-425f-4822-875c-2f97988de98a", - "at": "2026-07-02T15:02:00.701Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "created", - "issueId": "09b1e135-e25c-4fb5-a812-48dfd15edd55", - "at": "2026-07-02T15:03:27.354Z" - }, - { - "actorId": "agent:b8bc4df6-599c-4228-9969-6b041e7c88f8", - "kind": "commented", - "issueId": "09b1e135-e25c-4fb5-a812-48dfd15edd55", - "at": "2026-07-02T15:04:40.445Z" - }, - { - "actorId": "agent:c9dcefd1-b052-489a-a1f3-4cd1783bcb5f", - "kind": "commented", - "issueId": "1533f78d-d677-449f-afd9-4cf653168438", - "at": "2026-07-02T15:05:03.153Z" - }, - { - "actorId": "agent:ece64c0e-767e-4d37-a15e-193694daa1d8", - "kind": "commented", - "issueId": "d6327ba4-5bed-4bad-b860-213256cf127a", - "at": "2026-07-02T15:05:38.298Z" - }, - { - "actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "kind": "created", - "issueId": "7751d27f-c016-4be5-a332-b29b888e8b48", - "at": "2026-07-02T15:05:38.834Z" - }, - { - "actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "kind": "delegated", - "issueId": "7751d27f-c016-4be5-a332-b29b888e8b48", - "at": "2026-07-02T15:05:38.834Z" - }, - { - "actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "kind": "commented", - "issueId": "0facd02e-425f-4822-875c-2f97988de98a", - "at": "2026-07-02T15:05:52.785Z" - }, - { - "actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "kind": "approved", - "issueId": "b868097a-4b8a-447d-a667-a96ebd24e385", - "at": "2026-07-02T15:06:51.894Z" - }, - { - "actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "kind": "commented", - "issueId": "b868097a-4b8a-447d-a667-a96ebd24e385", - "at": "2026-07-02T15:07:21.753Z" - }, - { - "actorId": "agent:ef2d1ee5-5c42-42fc-8197-5e2386ac34ed", - "kind": "created", - "issueId": "804fff38-a46b-4391-9c44-cd76fd889753", - "at": "2026-07-02T15:07:45.644Z" - }, - { - "actorId": "agent:ef2d1ee5-5c42-42fc-8197-5e2386ac34ed", - "kind": "delegated", - "issueId": "804fff38-a46b-4391-9c44-cd76fd889753", - "at": "2026-07-02T15:07:45.644Z" - }, - { - "actorId": "agent:ef2d1ee5-5c42-42fc-8197-5e2386ac34ed", - "kind": "commented", - "issueId": "7751d27f-c016-4be5-a332-b29b888e8b48", - "at": "2026-07-02T15:07:56.186Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "commented", - "issueId": "40490e19-4e4a-4fa3-8300-719a82d3633a", - "at": "2026-07-02T15:09:15.910Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "commented", - "issueId": "b5a59535-38f5-4f0d-a0bf-2bf755a4be15", - "at": "2026-07-02T15:10:24.986Z" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "kind": "created", - "issueId": "91292c04-bbfe-4a94-9779-baceb3941857", - "at": "2026-07-02T15:10:51.721Z" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "kind": "delegated", - "issueId": "91292c04-bbfe-4a94-9779-baceb3941857", - "at": "2026-07-02T15:10:51.721Z" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "kind": "commented", - "issueId": "804fff38-a46b-4391-9c44-cd76fd889753", - "at": "2026-07-02T15:11:04.865Z" - }, - { - "actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "kind": "commented", - "issueId": "b868097a-4b8a-447d-a667-a96ebd24e385", - "at": "2026-07-02T15:11:14.738Z" - }, - { - "actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "kind": "commented", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "at": "2026-07-02T15:12:26.380Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "created", - "issueId": "57a438c1-876a-40ce-9b2b-5c8a8b47ec5b", - "at": "2026-07-02T15:14:30.565Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "delegated", - "issueId": "57a438c1-876a-40ce-9b2b-5c8a8b47ec5b", - "at": "2026-07-02T15:14:30.565Z" - }, - { - "actorId": "agent:ece64c0e-767e-4d37-a15e-193694daa1d8", - "kind": "commented", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "at": "2026-07-02T15:14:43.831Z" - }, - { - "actorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", - "kind": "commented", - "issueId": "91292c04-bbfe-4a94-9779-baceb3941857", - "at": "2026-07-02T15:14:44.435Z" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "kind": "commented", - "issueId": "b5a59535-38f5-4f0d-a0bf-2bf755a4be15", - "at": "2026-07-02T15:15:02.505Z" - }, - { - "actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "kind": "commented", - "issueId": "91292c04-bbfe-4a94-9779-baceb3941857", - "at": "2026-07-02T15:15:56.982Z" - }, - { - "actorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "kind": "commented", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "at": "2026-07-02T15:16:35.238Z" - }, - { - "actorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "kind": "commented", - "issueId": "16901797-89cc-4b85-8213-7a27d70f9d16", - "at": "2026-07-02T15:17:07.032Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "created", - "issueId": "e0189c44-1245-4526-9423-1128862d7c95", - "at": "2026-07-02T15:18:55.353Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "approved", - "issueId": "40490e19-4e4a-4fa3-8300-719a82d3633a", - "at": "2026-07-02T15:19:05.154Z" - }, - { - "actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "kind": "commented", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "at": "2026-07-02T15:19:11.188Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "commented", - "issueId": "40490e19-4e4a-4fa3-8300-719a82d3633a", - "at": "2026-07-02T15:19:25.678Z" - }, - { - "actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "kind": "approved", - "issueId": "91292c04-bbfe-4a94-9779-baceb3941857", - "at": "2026-07-02T15:19:39.277Z" - }, - { - "actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "kind": "commented", - "issueId": "91292c04-bbfe-4a94-9779-baceb3941857", - "at": "2026-07-02T15:19:55.477Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "commented", - "issueId": "e0189c44-1245-4526-9423-1128862d7c95", - "at": "2026-07-02T15:20:10.329Z" - }, - { - "actorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "kind": "commented", - "issueId": "57a438c1-876a-40ce-9b2b-5c8a8b47ec5b", - "at": "2026-07-02T15:20:17.139Z" - }, - { - "actorId": "system:system", - "kind": "commented", - "issueId": "e3afbdcf-98b8-4971-a094-9a92d78736d1", - "at": "2026-07-02T15:20:20.709Z" - }, - { - "actorId": "system:system", - "kind": "commented", - "issueId": "6f7ac707-363a-4e77-b3d0-7479165352db", - "at": "2026-07-02T15:20:20.751Z" - }, - { - "actorId": "system:system", - "kind": "commented", - "issueId": "153322a9-301d-4868-b15e-a24063ceeca2", - "at": "2026-07-02T15:20:20.803Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "commented", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "at": "2026-07-02T15:21:26.500Z" - }, - { - "actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "kind": "commented", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "at": "2026-07-02T15:22:40.012Z" - }, - { - "actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "kind": "commented", - "issueId": "153322a9-301d-4868-b15e-a24063ceeca2", - "at": "2026-07-02T15:22:40.511Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "commented", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "at": "2026-07-02T15:24:07.505Z" - }, - { - "actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "kind": "commented", - "issueId": "e3afbdcf-98b8-4971-a094-9a92d78736d1", - "at": "2026-07-02T15:24:36.094Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "created", - "issueId": "f5b13e28-cbe4-40e5-bd29-d88eb8ea0ee3", - "at": "2026-07-02T15:25:07.938Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "delegated", - "issueId": "f5b13e28-cbe4-40e5-bd29-d88eb8ea0ee3", - "at": "2026-07-02T15:25:07.938Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "commented", - "issueId": "e0189c44-1245-4526-9423-1128862d7c95", - "at": "2026-07-02T15:25:26.349Z" - }, - { - "actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "kind": "commented", - "issueId": "e3afbdcf-98b8-4971-a094-9a92d78736d1", - "at": "2026-07-02T15:25:28.318Z" - }, - { - "actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "kind": "commented", - "issueId": "804fff38-a46b-4391-9c44-cd76fd889753", - "at": "2026-07-02T15:25:56.773Z" - }, - { - "actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "kind": "created", - "issueId": "9ae0377a-8040-4221-9376-4ae64270e3b4", - "at": "2026-07-02T15:27:39.300Z" - }, - { - "actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "kind": "commented", - "issueId": "1ae0d728-2f4e-4ec9-ac95-d006a7f19741", - "at": "2026-07-02T15:28:01.540Z" - }, - { - "actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "kind": "commented", - "issueId": "6f7ac707-363a-4e77-b3d0-7479165352db", - "at": "2026-07-02T15:28:02.346Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "commented", - "issueId": "b868097a-4b8a-447d-a667-a96ebd24e385", - "at": "2026-07-02T15:28:13.852Z" - }, - { - "actorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", - "kind": "commented", - "issueId": "9ae0377a-8040-4221-9376-4ae64270e3b4", - "at": "2026-07-02T15:28:52.824Z" - }, - { - "actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "kind": "commented", - "issueId": "f5b13e28-cbe4-40e5-bd29-d88eb8ea0ee3", - "at": "2026-07-02T15:30:55.654Z" - }, - { - "actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "kind": "commented", - "issueId": "e0189c44-1245-4526-9423-1128862d7c95", - "at": "2026-07-02T15:34:59.686Z" - }, - { - "actorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "kind": "approved", - "issueId": "1ae0d728-2f4e-4ec9-ac95-d006a7f19741", - "at": "2026-07-02T15:35:56.554Z" - }, - { - "actorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", - "kind": "commented", - "issueId": "9ae0377a-8040-4221-9376-4ae64270e3b4", - "at": "2026-07-02T15:36:48.753Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "approved", - "issueId": "e0189c44-1245-4526-9423-1128862d7c95", - "at": "2026-07-02T15:37:11.074Z" - }, - { - "actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "kind": "commented", - "issueId": "e0189c44-1245-4526-9423-1128862d7c95", - "at": "2026-07-02T15:37:24.105Z" - }, - { - "actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "kind": "approved", - "issueId": "1ae0d728-2f4e-4ec9-ac95-d006a7f19741", - "at": "2026-07-02T15:38:21.704Z" - }, - { - "actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "kind": "commented", - "issueId": "1ae0d728-2f4e-4ec9-ac95-d006a7f19741", - "at": "2026-07-02T15:38:31.695Z" - }, - { - "actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "kind": "commented", - "issueId": "b868097a-4b8a-447d-a667-a96ebd24e385", - "at": "2026-07-02T15:41:22.766Z" - }, - { - "actorId": "agent:b8bc4df6-599c-4228-9969-6b041e7c88f8", - "kind": "approved", - "issueId": "09b1e135-e25c-4fb5-a812-48dfd15edd55", - "at": "2026-07-02T15:43:04.428Z" - }, - { - "actorId": "agent:b8bc4df6-599c-4228-9969-6b041e7c88f8", - "kind": "commented", - "issueId": "09b1e135-e25c-4fb5-a812-48dfd15edd55", - "at": "2026-07-02T15:47:28.798Z" - }, - { - "actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "kind": "commented", - "issueId": "3c1b19ae-9064-4d78-8bf4-c3983a7730d6", - "at": "2026-07-02T15:48:25.833Z" - } - ], - "edges": [ - { - "fromActorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "toActorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "issueId": "e3afbdcf-98b8-4971-a094-9a92d78736d1", - "at": "2026-06-03T19:39:46.628Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "toActorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "issueId": "6f7ac707-363a-4e77-b3d0-7479165352db", - "at": "2026-06-03T19:40:14.945Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "toActorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "issueId": "153322a9-301d-4868-b15e-a24063ceeca2", - "at": "2026-06-03T19:40:14.974Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "toActorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "issueId": "5e955520-f5ea-4ad4-aef6-860c95b1797e", - "at": "2026-06-03T20:23:11.278Z", - "kind": "assignment" - }, - { - "fromActorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "toActorId": "agent:b8bc4df6-599c-4228-9969-6b041e7c88f8", - "issueId": "bc7a42bb-91bb-40b3-b3a8-6f9ebf98bc94", - "at": "2026-06-30T22:22:13.060Z", - "kind": "assignment" - }, - { - "fromActorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "toActorId": "agent:db1c09f1-422c-48c8-9711-4054d3657aac", - "issueId": "6ff91230-ab9d-4b95-9590-1471ae37297e", - "at": "2026-07-01T16:31:55.423Z", - "kind": "assignment" - }, - { - "fromActorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "toActorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "issueId": "1ae0d728-2f4e-4ec9-ac95-d006a7f19741", - "at": "2026-07-01T18:23:43.255Z", - "kind": "assignment" - }, - { - "fromActorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "toActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "issueId": "48264b4d-0004-4015-9ca0-08c867eed064", - "at": "2026-07-02T00:13:22.977Z", - "kind": "assignment" - }, - { - "fromActorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "toActorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "issueId": "2e375459-115c-4f0c-a1c8-59e359b5c3f6", - "at": "2026-07-02T02:21:56.069Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "toActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "issueId": "df84e69c-35e1-4323-a95f-e10d27b3227c", - "at": "2026-07-02T02:39:19.891Z", - "kind": "assignment" - }, - { - "fromActorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "toActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "issueId": "ad7f2c54-6e50-421f-a805-4c743948421a", - "at": "2026-07-02T03:29:27.493Z", - "kind": "assignment" - }, - { - "fromActorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "toActorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "issueId": "44c2c3d2-7dc0-44df-beb6-ad2417b81503", - "at": "2026-07-02T04:45:14.251Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:b8bc4df6-599c-4228-9969-6b041e7c88f8", - "toActorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "issueId": "44c2c3d2-7dc0-44df-beb6-ad2417b81503", - "at": "2026-07-02T04:45:14.251Z", - "kind": "delegation" - }, - { - "fromActorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "toActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "issueId": "40490e19-4e4a-4fa3-8300-719a82d3633a", - "at": "2026-07-02T04:52:34.737Z", - "kind": "assignment" - }, - { - "fromActorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "toActorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "issueId": "db6e4af1-0669-42d0-a6ef-e12dcfd7112d", - "at": "2026-07-02T04:56:04.034Z", - "kind": "assignment" - }, - { - "fromActorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "toActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "issueId": "828497e6-087d-4336-b627-331e51380ad4", - "at": "2026-07-02T05:07:46.810Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "toActorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "issueId": "abe00e5c-bbcd-4782-ba9e-13532a09184f", - "at": "2026-07-02T05:08:53.619Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "toActorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "issueId": "b5a59535-38f5-4f0d-a0bf-2bf755a4be15", - "at": "2026-07-02T14:44:59.609Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "toActorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "issueId": "b5a59535-38f5-4f0d-a0bf-2bf755a4be15", - "at": "2026-07-02T14:44:59.609Z", - "kind": "delegation" - }, - { - "fromActorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "toActorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", - "issueId": "9c5003e8-104d-46ae-9389-c62cb6fc8889", - "at": "2026-07-02T14:52:04.388Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "toActorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", - "issueId": "9c5003e8-104d-46ae-9389-c62cb6fc8889", - "at": "2026-07-02T14:52:04.388Z", - "kind": "delegation" - }, - { - "fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "toActorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "issueId": "b868097a-4b8a-447d-a667-a96ebd24e385", - "at": "2026-07-02T14:52:21.683Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "toActorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "issueId": "b868097a-4b8a-447d-a667-a96ebd24e385", - "at": "2026-07-02T14:52:21.683Z", - "kind": "delegation" - }, - { - "fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "toActorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "issueId": "e64a9b35-54e8-430c-9244-18f60c70f87a", - "at": "2026-07-02T14:52:21.778Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "toActorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "issueId": "e64a9b35-54e8-430c-9244-18f60c70f87a", - "at": "2026-07-02T14:52:21.778Z", - "kind": "delegation" - }, - { - "fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "toActorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "issueId": "3c1b19ae-9064-4d78-8bf4-c3983a7730d6", - "at": "2026-07-02T14:52:53.705Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "toActorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", - "issueId": "3c1b19ae-9064-4d78-8bf4-c3983a7730d6", - "at": "2026-07-02T14:52:53.705Z", - "kind": "delegation" - }, - { - "fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "toActorId": "agent:ece64c0e-767e-4d37-a15e-193694daa1d8", - "issueId": "d6327ba4-5bed-4bad-b860-213256cf127a", - "at": "2026-07-02T14:53:41.388Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "toActorId": "agent:ece64c0e-767e-4d37-a15e-193694daa1d8", - "issueId": "d6327ba4-5bed-4bad-b860-213256cf127a", - "at": "2026-07-02T14:53:41.388Z", - "kind": "delegation" - }, - { - "fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "toActorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "issueId": "a466f1d9-cfb3-4fa1-a354-57d8bee78ce1", - "at": "2026-07-02T14:53:55.809Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "toActorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "issueId": "a466f1d9-cfb3-4fa1-a354-57d8bee78ce1", - "at": "2026-07-02T14:53:55.809Z", - "kind": "delegation" - }, - { - "fromActorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", - "toActorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "issueId": "5a3cf258-ae30-44ba-9b57-494eaf6c0238", - "at": "2026-07-02T14:54:41.875Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", - "toActorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "issueId": "5a3cf258-ae30-44ba-9b57-494eaf6c0238", - "at": "2026-07-02T14:54:41.875Z", - "kind": "delegation" - }, - { - "fromActorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "toActorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "issueId": "6d12933d-1393-484c-aeb8-17d98e61b8c0", - "at": "2026-07-02T14:55:00.287Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "toActorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "issueId": "6d12933d-1393-484c-aeb8-17d98e61b8c0", - "at": "2026-07-02T14:55:00.287Z", - "kind": "delegation" - }, - { - "fromActorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "toActorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "issueId": "0dc1021f-2326-4977-a5b2-7eb4ab66e6df", - "at": "2026-07-02T14:57:50.676Z", - "kind": "assignment" - }, - { - "fromActorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "toActorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "issueId": "16901797-89cc-4b85-8213-7a27d70f9d16", - "at": "2026-07-02T14:59:42.755Z", - "kind": "assignment" - }, - { - "fromActorId": "system:system", - "toActorId": "agent:c9dcefd1-b052-489a-a1f3-4cd1783bcb5f", - "issueId": "1533f78d-d677-449f-afd9-4cf653168438", - "at": "2026-07-02T15:00:19.659Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "toActorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "issueId": "0facd02e-425f-4822-875c-2f97988de98a", - "at": "2026-07-02T15:00:46.643Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "toActorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "issueId": "0facd02e-425f-4822-875c-2f97988de98a", - "at": "2026-07-02T15:00:46.643Z", - "kind": "delegation" - }, - { - "fromActorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "toActorId": "agent:b8bc4df6-599c-4228-9969-6b041e7c88f8", - "issueId": "09b1e135-e25c-4fb5-a812-48dfd15edd55", - "at": "2026-07-02T15:03:27.354Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "toActorId": "agent:ef2d1ee5-5c42-42fc-8197-5e2386ac34ed", - "issueId": "7751d27f-c016-4be5-a332-b29b888e8b48", - "at": "2026-07-02T15:05:38.834Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "toActorId": "agent:ef2d1ee5-5c42-42fc-8197-5e2386ac34ed", - "issueId": "7751d27f-c016-4be5-a332-b29b888e8b48", - "at": "2026-07-02T15:05:38.834Z", - "kind": "delegation" - }, - { - "fromActorId": "agent:ef2d1ee5-5c42-42fc-8197-5e2386ac34ed", - "toActorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "issueId": "804fff38-a46b-4391-9c44-cd76fd889753", - "at": "2026-07-02T15:07:45.644Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:ef2d1ee5-5c42-42fc-8197-5e2386ac34ed", - "toActorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "issueId": "804fff38-a46b-4391-9c44-cd76fd889753", - "at": "2026-07-02T15:07:45.644Z", - "kind": "delegation" - }, - { - "fromActorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "toActorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "issueId": "91292c04-bbfe-4a94-9779-baceb3941857", - "at": "2026-07-02T15:10:51.721Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", - "toActorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", - "issueId": "91292c04-bbfe-4a94-9779-baceb3941857", - "at": "2026-07-02T15:10:51.721Z", - "kind": "delegation" - }, - { - "fromActorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "toActorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "issueId": "57a438c1-876a-40ce-9b2b-5c8a8b47ec5b", - "at": "2026-07-02T15:14:30.565Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "toActorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", - "issueId": "57a438c1-876a-40ce-9b2b-5c8a8b47ec5b", - "at": "2026-07-02T15:14:30.565Z", - "kind": "delegation" - }, - { - "fromActorId": "user:1gQsX9Jbj5jk1Wu51YU1G0atxCRwj1Om", - "toActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "issueId": "e0189c44-1245-4526-9423-1128862d7c95", - "at": "2026-07-02T15:18:55.353Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "toActorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "issueId": "f5b13e28-cbe4-40e5-bd29-d88eb8ea0ee3", - "at": "2026-07-02T15:25:07.938Z", - "kind": "assignment" - }, - { - "fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", - "toActorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", - "issueId": "f5b13e28-cbe4-40e5-bd29-d88eb8ea0ee3", - "at": "2026-07-02T15:25:07.938Z", - "kind": "delegation" - }, - { - "fromActorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", - "toActorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", - "issueId": "9ae0377a-8040-4221-9376-4ae64270e3b4", - "at": "2026-07-02T15:27:39.300Z", - "kind": "assignment" - } - ], - "pagination": { - "limit": 500, - "offset": 0, - "totalIssues": 37, - "hasMore": false - }, - "window": { - "from": "2026-07-02T14:00:00.000Z", - "to": "2026-07-02T16:00:00.000Z", - "capped": false - } -} \ No newline at end of file diff --git a/ui/storybook/fixtures/workTimeline.sample.json b/ui/storybook/fixtures/workTimeline.sample.json deleted file mode 100644 index 29a8ada09d..0000000000 --- a/ui/storybook/fixtures/workTimeline.sample.json +++ /dev/null @@ -1 +0,0 @@ -{"actors": [{"id": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", "type": "agent", "name": "CEO", "avatar": "crown"}, {"id": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", "type": "agent", "name": "ClaudeCoder", "avatar": "code"}, {"id": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", "type": "agent", "name": "CloudOpsEngineer", "avatar": "cog"}, {"id": "agent:6670e11b-91d3-4429-82e0-436b88b51808", "type": "agent", "name": "UXDesigner", "avatar": "gem"}, {"id": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", "type": "agent", "name": "CTO", "avatar": "file-code"}, {"id": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", "type": "agent", "name": "Senior Engineer Fable", "avatar": "code"}, {"id": "agent:b8bc4df6-599c-4228-9969-6b041e7c88f8", "type": "agent", "name": "Senior Planning Engineer Pro", "avatar": "code"}, {"id": "agent:c9dcefd1-b052-489a-a1f3-4cd1783bcb5f", "type": "agent", "name": "DevRel", "avatar": "globe"}, {"id": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", "type": "agent", "name": "CodexCoder", "avatar": "code"}, {"id": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", "type": "agent", "name": "QA", "avatar": "bug"}, {"id": "agent:ece64c0e-767e-4d37-a15e-193694daa1d8", "type": "agent", "name": "SecurityEngineer", "avatar": "shield"}, {"id": "agent:ef2d1ee5-5c42-42fc-8197-5e2386ac34ed", "type": "agent", "name": "Strategic Ops", "avatar": "target"}], "spans": [{"actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", "laneHint": "automation", "runId": "063a9727-b191-49e2-9802-b6b63ec65b97", "issueId": "3c1b19ae-9064-4d78-8bf4-c3983a7730d6", "issueIdentifier": "PAP-12424", "issueTitle": "Work Timeline \u2014 Phase C: frontend Gantt component + Timeline page", "start": "2026-07-02T15:41:30.586Z", "end": null, "status": "running", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", "laneHint": "automation", "runId": "20f1e461-b4b6-4d5f-b897-6f60656429fb", "issueId": "1ae0d728-2f4e-4ec9-ac95-d006a7f19741", "issueIdentifier": "PAP-12298", "issueTitle": "blog page redesign", "start": "2026-07-02T15:35:56.578Z", "end": "2026-07-02T15:38:40.543Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", "laneHint": "automation", "runId": "040ce2ef-acd4-47f2-bcf1-5a1194f5a450", "issueId": "e0189c44-1245-4526-9423-1128862d7c95", "issueIdentifier": "PAP-12438", "issueTitle": "environment variables editor re-design", "start": "2026-07-02T15:34:59.718Z", "end": "2026-07-02T15:38:04.415Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", "laneHint": "automation", "runId": "339694a1-6a7d-4de0-8466-43574a7c6b4d", "issueId": "b868097a-4b8a-447d-a667-a96ebd24e385", "issueIdentifier": "PAP-12422", "issueTitle": "Work Timeline \u2014 Phase A: wireframe exploration (2\u20133 directions, board picks one)", "start": "2026-07-02T15:28:13.886Z", "end": "2026-07-02T15:42:27.258Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", "laneHint": "assignment", "runId": "9eb8e7ba-53b5-4d22-8f8d-cbba6a5c5bb5", "issueId": "9ae0377a-8040-4221-9376-4ae64270e3b4", "issueIdentifier": "PAP-12440", "issueTitle": "Defect (Minor): teams-catalog install is not atomic \u2014 mid-import failure can orphan skills/agents", "start": "2026-07-02T15:27:39.339Z", "end": "2026-07-02T15:37:04.236Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", "laneHint": "automation", "runId": "2bd1ec14-ecbb-42d8-8412-106a251780b8", "issueId": "e0189c44-1245-4526-9423-1128862d7c95", "issueIdentifier": "PAP-12438", "issueTitle": "environment variables editor re-design", "start": "2026-07-02T15:26:14.310Z", "end": "2026-07-02T15:34:59.661Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", "laneHint": "assignment", "runId": "1b734867-943b-4ef3-a10e-3f2c1edcad93", "issueId": "f5b13e28-cbe4-40e5-bd29-d88eb8ea0ee3", "issueIdentifier": "PAP-12439", "issueTitle": "Wireframes: Environment Variables Editor redesign", "start": "2026-07-02T15:25:07.982Z", "end": "2026-07-02T15:32:24.457Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", "laneHint": "automation", "runId": "88e7b7a9-4ea6-40bc-b402-ffd731a3dfe2", "issueId": "1ae0d728-2f4e-4ec9-ac95-d006a7f19741", "issueIdentifier": "PAP-12298", "issueTitle": "blog page redesign", "start": "2026-07-02T15:23:28.308Z", "end": "2026-07-02T15:29:09.108Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", "laneHint": "automation", "runId": "cbce714c-a056-477d-971b-3ceb02a4441b", "issueId": "804fff38-a46b-4391-9c44-cd76fd889753", "issueIdentifier": "PAP-12435", "issueTitle": "CloudOps: attach pages.paperclip.ing uploader IAM policy", "start": "2026-07-02T15:23:13.966Z", "end": "2026-07-02T15:23:32.715Z", "status": "cancelled", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", "laneHint": "automation", "runId": "671705a1-718d-4be6-86b4-390295a17a74", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "issueIdentifier": "PAP-12405", "issueTitle": "design a \u2018gantt chart\u2019 representation of my paperclip work", "start": "2026-07-02T15:22:48.720Z", "end": "2026-07-02T15:24:16.925Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", "laneHint": "automation", "runId": "85339e14-6ac3-459c-99a2-811e0e6adbba", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "issueIdentifier": "PAP-12405", "issueTitle": "design a \u2018gantt chart\u2019 representation of my paperclip work", "start": "2026-07-02T15:21:38.307Z", "end": "2026-07-02T15:22:48.667Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", "laneHint": "automation", "runId": "ebc8e142-c416-4b85-86ff-be0fed98f41f", "issueId": "153322a9-301d-4868-b15e-a24063ceeca2", "issueIdentifier": "PAP-10275", "issueTitle": "Defect (Minor): CLI install lacks --adapter-override and --secret-value flags", "start": "2026-07-02T15:20:20.854Z", "end": "2026-07-02T15:22:56.590Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", "laneHint": "automation", "runId": "accd3b96-89a2-47f4-a3db-65f94ec6be3a", "issueId": "6f7ac707-363a-4e77-b3d0-7479165352db", "issueIdentifier": "PAP-10274", "issueTitle": "Defect (Minor UX): \"Partial state is not rolled back\" message is incorrect \u2014 install transaction rolled back cleanly", "start": "2026-07-02T15:20:20.784Z", "end": "2026-07-02T15:28:39.720Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", "laneHint": "automation", "runId": "8e58708e-88df-4681-84c5-f6a676d1dd6a", "issueId": "e3afbdcf-98b8-4971-a094-9a92d78736d1", "issueIdentifier": "PAP-10273", "issueTitle": "Defect (Minor): preview emits noisy \"skill not present in package\" warnings for catalog-skill references", "start": "2026-07-02T15:20:20.734Z", "end": "2026-07-02T15:25:39.352Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", "laneHint": "automation", "runId": "17e168c3-c2f4-4cef-9492-c4e680bebcf5", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "issueIdentifier": "PAP-12405", "issueTitle": "design a \u2018gantt chart\u2019 representation of my paperclip work", "start": "2026-07-02T15:19:28.163Z", "end": "2026-07-02T15:21:38.254Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", "laneHint": "assignment", "runId": "4cec085d-bf1f-48a2-aef1-62cce353a09f", "issueId": "e0189c44-1245-4526-9423-1128862d7c95", "issueIdentifier": "PAP-12438", "issueTitle": "environment variables editor re-design", "start": "2026-07-02T15:18:55.386Z", "end": "2026-07-02T15:26:14.263Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", "laneHint": "automation", "runId": "df0d6959-ef5f-4a75-b710-492cfd6de658", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "issueIdentifier": "PAP-12405", "issueTitle": "design a \u2018gantt chart\u2019 representation of my paperclip work", "start": "2026-07-02T15:16:53.952Z", "end": "2026-07-02T15:19:28.111Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", "laneHint": "assignment", "runId": "a9ba6322-e0e3-43bb-bc0b-2af53bec9610", "issueId": "91292c04-bbfe-4a94-9779-baceb3941857", "issueIdentifier": "PAP-12436", "issueTitle": "CTO/admin: grant IAM write path for paperclip-page-uploader pages policy", "start": "2026-07-02T15:14:59.782Z", "end": "2026-07-02T15:20:10.000Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", "laneHint": "automation", "runId": "cd8cf33f-5a1c-4b3a-905e-aabc0341edd1", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "issueIdentifier": "PAP-12405", "issueTitle": "design a \u2018gantt chart\u2019 representation of my paperclip work", "start": "2026-07-02T15:14:57.094Z", "end": "2026-07-02T15:16:53.870Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", "laneHint": "assignment", "runId": "f4d1d8a6-c74d-4d59-b831-b788eeaf93f2", "issueId": "57a438c1-876a-40ce-9b2b-5c8a8b47ec5b", "issueIdentifier": "PAP-12437", "issueTitle": "for parent task, cleanup the effecitvely merged ones", "start": "2026-07-02T15:14:30.602Z", "end": "2026-07-02T15:20:22.033Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:ece64c0e-767e-4d37-a15e-193694daa1d8", "laneHint": "automation", "runId": "90cd6835-be7c-4dd8-bdf7-017d40df9c38", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "issueIdentifier": "PAP-12405", "issueTitle": "design a \u2018gantt chart\u2019 representation of my paperclip work", "start": "2026-07-02T15:12:26.440Z", "end": "2026-07-02T15:14:56.976Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", "laneHint": "assignment", "runId": "b83d9b78-f63c-465c-808c-c1e1175a18c5", "issueId": "91292c04-bbfe-4a94-9779-baceb3941857", "issueIdentifier": "PAP-12436", "issueTitle": "CTO/admin: grant IAM write path for paperclip-page-uploader pages policy", "start": "2026-07-02T15:10:51.773Z", "end": "2026-07-02T15:14:59.703Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", "laneHint": "automation", "runId": "e4e854bc-9cce-4c5f-bfb9-a2f3c0094075", "issueId": "b5a59535-38f5-4f0d-a0bf-2bf755a4be15", "issueIdentifier": "PAP-12420", "issueTitle": "Attach S3 policy to paperclip-page-uploader IAM user for pages.paperclip.ing", "start": "2026-07-02T15:10:25.014Z", "end": "2026-07-02T15:15:34.966Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", "laneHint": "assignment", "runId": "bcfaef62-ca9a-4a96-b279-bf2314108dbf", "issueId": "40490e19-4e4a-4fa3-8300-719a82d3633a", "issueIdentifier": "PAP-12403", "issueTitle": "github and environment variables", "start": "2026-07-02T15:09:15.958Z", "end": "2026-07-02T15:20:22.053Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", "laneHint": "assignment", "runId": "0ecdb797-e6b4-4f12-a5f0-b7bce348138f", "issueId": "804fff38-a46b-4391-9c44-cd76fd889753", "issueIdentifier": "PAP-12435", "issueTitle": "CloudOps: attach pages.paperclip.ing uploader IAM policy", "start": "2026-07-02T15:07:45.699Z", "end": "2026-07-02T15:11:13.138Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:ef2d1ee5-5c42-42fc-8197-5e2386ac34ed", "laneHint": "assignment", "runId": "0961f6e8-a1cd-4493-9979-99775285c748", "issueId": "7751d27f-c016-4be5-a332-b29b888e8b48", "issueIdentifier": "PAP-12434", "issueTitle": "Strategic Ops: get AWS admin to attach pages.paperclip.ing uploader policy", "start": "2026-07-02T15:05:38.870Z", "end": "2026-07-02T15:08:15.576Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:b8bc4df6-599c-4228-9969-6b041e7c88f8", "laneHint": "assignment", "runId": "33181a90-d2af-4081-9deb-253d996d81f1", "issueId": "09b1e135-e25c-4fb5-a812-48dfd15edd55", "issueIdentifier": "PAP-12433", "issueTitle": "project star\u2019ing", "start": "2026-07-02T15:03:27.392Z", "end": "2026-07-02T15:52:11.373Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:ece64c0e-767e-4d37-a15e-193694daa1d8", "laneHint": "automation", "runId": "12223c0b-0bad-4b95-be56-ceb1ce955b0f", "issueId": "d6327ba4-5bed-4bad-b860-213256cf127a", "issueIdentifier": "PAP-12425", "issueTitle": "Work Timeline \u2014 security review: timeline endpoint ACLs and data exposure", "start": "2026-07-02T15:01:28.563Z", "end": "2026-07-02T15:05:43.985Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", "laneHint": "assignment", "runId": "e08e32ae-9106-46e0-9c2b-97ab74520fc4", "issueId": "0facd02e-425f-4822-875c-2f97988de98a", "issueIdentifier": "PAP-12432", "issueTitle": "CEO/admin: apply paperclip-page-uploader pages.paperclip.ing inline policy", "start": "2026-07-02T15:00:46.697Z", "end": "2026-07-02T15:06:05.586Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:c9dcefd1-b052-489a-a1f3-4cd1783bcb5f", "laneHint": "assignment", "runId": "91f67e3b-18ae-4230-8fae-18b414ffcd14", "issueId": "1533f78d-d677-449f-afd9-4cf653168438", "issueIdentifier": "PAP-12431", "issueTitle": "2026-07-02 create a standup message i can copy to slack about everything i've been working on for the last 36 hours", "start": "2026-07-02T15:00:19.704Z", "end": "2026-07-02T15:05:16.672Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", "laneHint": "assignment", "runId": "e9ff0a09-6607-4793-90f3-1b3ab1741ef0", "issueId": "16901797-89cc-4b85-8213-7a27d70f9d16", "issueIdentifier": "PAP-12430", "issueTitle": "merged Create a single PR from this branch PAP-12404-inbox-blocked-but-descendent-live-icon", "start": "2026-07-02T14:59:42.783Z", "end": "2026-07-02T15:17:12.936Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", "laneHint": "assignment", "runId": "67f65027-b802-4e88-91a6-bebb5c94f16b", "issueId": "0dc1021f-2326-4977-a5b2-7eb4ab66e6df", "issueIdentifier": "PAP-12429", "issueTitle": "give the AWS_ keys that ClaudeCoder has to CodexCoder and CloudOpsEngineer and UXDesigner", "start": "2026-07-02T14:57:50.711Z", "end": "2026-07-02T15:01:18.973Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", "laneHint": "assignment", "runId": "a61b657c-d297-43b7-948c-2be7bd161e3b", "issueId": "5a3cf258-ae30-44ba-9b57-494eaf6c0238", "issueIdentifier": "PAP-12427", "issueTitle": "CEO/admin: unblock IAM mutation for paperclip-page-uploader pages policy", "start": "2026-07-02T14:57:27.831Z", "end": "2026-07-02T15:01:08.081Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", "laneHint": "automation", "runId": "960639c7-f6cc-45ad-b746-22ca507c237d", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "issueIdentifier": "PAP-12405", "issueTitle": "design a \u2018gantt chart\u2019 representation of my paperclip work", "start": "2026-07-02T14:57:12.287Z", "end": "2026-07-02T15:12:26.352Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", "laneHint": "automation", "runId": "77ffd755-a755-41e6-b2cb-ee0817f11152", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "issueIdentifier": "PAP-12405", "issueTitle": "design a \u2018gantt chart\u2019 representation of my paperclip work", "start": "2026-07-02T14:55:43.595Z", "end": "2026-07-02T14:57:12.235Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", "laneHint": "assignment", "runId": "d14a8901-4569-4f05-b8c2-5e49d4216a6d", "issueId": "6d12933d-1393-484c-aeb8-17d98e61b8c0", "issueIdentifier": "PAP-12428", "issueTitle": "just change the terminology to \u201cResponsible\u201d", "start": "2026-07-02T14:55:00.330Z", "end": "2026-07-02T15:01:10.197Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", "laneHint": "assignment", "runId": "972b6b5b-5fdd-419d-aea0-5641b4634448", "issueId": "5a3cf258-ae30-44ba-9b57-494eaf6c0238", "issueIdentifier": "PAP-12427", "issueTitle": "CEO/admin: unblock IAM mutation for paperclip-page-uploader pages policy", "start": "2026-07-02T14:54:41.918Z", "end": "2026-07-02T14:57:27.722Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", "laneHint": "assignment", "runId": "4b085459-77b0-41e4-a62f-a76e1ba9b521", "issueId": "e64a9b35-54e8-430c-9244-18f60c70f87a", "issueIdentifier": "PAP-12423", "issueTitle": "Work Timeline \u2014 Phase B: timeline aggregation endpoint (GET /companies/:id/timeline)", "start": "2026-07-02T14:52:21.929Z", "end": "2026-07-02T15:03:54.376Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", "laneHint": "assignment", "runId": "8a716a87-61e2-4667-9cc4-3641fe42c6f0", "issueId": "b868097a-4b8a-447d-a667-a96ebd24e385", "issueIdentifier": "PAP-12422", "issueTitle": "Work Timeline \u2014 Phase A: wireframe exploration (2\u20133 directions, board picks one)", "start": "2026-07-02T14:52:21.788Z", "end": "2026-07-02T15:07:44.596Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", "laneHint": "assignment", "runId": "e573c5dc-94b9-4b63-bdb3-c48327a85cea", "issueId": "9c5003e8-104d-46ae-9389-c62cb6fc8889", "issueIdentifier": "PAP-12421", "issueTitle": "CTO/admin: attach corrected pages.paperclip.ing S3 policy to paperclip-page-uploader", "start": "2026-07-02T14:52:04.426Z", "end": "2026-07-02T14:56:08.638Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", "laneHint": "automation", "runId": "6b0a55a9-7c1a-4d48-bdfb-159370e9c03d", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "issueIdentifier": "PAP-12405", "issueTitle": "design a \u2018gantt chart\u2019 representation of my paperclip work", "start": "2026-07-02T14:50:35.277Z", "end": "2026-07-02T14:55:43.520Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", "laneHint": "automation", "runId": "c214c9f0-b46b-47de-ba86-2520e1a8aa75", "issueId": "b5a59535-38f5-4f0d-a0bf-2bf755a4be15", "issueIdentifier": "PAP-12420", "issueTitle": "Attach S3 policy to paperclip-page-uploader IAM user for pages.paperclip.ing", "start": "2026-07-02T14:48:23.194Z", "end": "2026-07-02T14:52:29.939Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}, {"actorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", "laneHint": "assignment", "runId": "c7a242bb-adf1-46e2-a322-474ed791c7ff", "issueId": "b5a59535-38f5-4f0d-a0bf-2bf755a4be15", "issueIdentifier": "PAP-12420", "issueTitle": "Attach S3 policy to paperclip-page-uploader IAM user for pages.paperclip.ing", "start": "2026-07-02T14:44:59.649Z", "end": "2026-07-02T14:48:23.151Z", "status": "cancelled", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "assignment"}, {"actorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", "laneHint": "automation", "runId": "571d1495-fe7e-4cf8-a79f-e4d8d779cecf", "issueId": "1ae0d728-2f4e-4ec9-ac95-d006a7f19741", "issueIdentifier": "PAP-12298", "issueTitle": "blog page redesign", "start": "2026-07-02T14:42:05.689Z", "end": "2026-07-02T14:45:37.694Z", "status": "succeeded", "retryOfRunId": null, "continuationAttempt": 0, "invocationSource": "automation"}], "events": [], "edges": [{"fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", "toActorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", "issueId": "e0189c44-1245-4526-9423-1128862d7c95", "at": "2026-07-02T15:26:14.310Z", "kind": "delegation"}, {"fromActorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", "toActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", "issueId": "e0189c44-1245-4526-9423-1128862d7c95", "at": "2026-07-02T15:34:59.718Z", "kind": "delegation"}, {"fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", "toActorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "at": "2026-07-02T14:55:43.595Z", "kind": "delegation"}, {"fromActorId": "agent:eae27ade-c807-4723-97e8-23808ad4fa14", "toActorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "at": "2026-07-02T14:57:12.287Z", "kind": "delegation"}, {"fromActorId": "agent:6670e11b-91d3-4429-82e0-436b88b51808", "toActorId": "agent:ece64c0e-767e-4d37-a15e-193694daa1d8", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "at": "2026-07-02T15:12:26.440Z", "kind": "delegation"}, {"fromActorId": "agent:ece64c0e-767e-4d37-a15e-193694daa1d8", "toActorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "at": "2026-07-02T15:14:57.094Z", "kind": "delegation"}, {"fromActorId": "agent:eab6f1c7-5950-410e-8eed-7d074426165d", "toActorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "at": "2026-07-02T15:16:53.952Z", "kind": "delegation"}, {"fromActorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", "toActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "at": "2026-07-02T15:19:28.163Z", "kind": "delegation"}, {"fromActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", "toActorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "at": "2026-07-02T15:21:38.307Z", "kind": "delegation"}, {"fromActorId": "agent:3108ef8e-5ed0-41d9-b561-6b41c41b8545", "toActorId": "agent:a9f9a532-690a-45c2-8da7-64789e7cbb06", "issueId": "828497e6-087d-4336-b627-331e51380ad4", "at": "2026-07-02T15:22:48.720Z", "kind": "delegation"}, {"fromActorId": "agent:66b3c071-6cb8-4424-b833-9d9b6318de0b", "toActorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", "issueId": "91292c04-bbfe-4a94-9779-baceb3941857", "at": "2026-07-02T15:14:59.782Z", "kind": "delegation"}, {"fromActorId": "agent:244c0c2c-8416-43b6-84c9-ec183c074cc1", "toActorId": "agent:352aa64b-2a22-4d00-928f-71f5fb884f66", "issueId": "5a3cf258-ae30-44ba-9b57-494eaf6c0238", "at": "2026-07-02T14:57:27.831Z", "kind": "delegation"}], "pagination": {"limit": 200, "offset": 0, "totalIssues": 26, "hasMore": false}, "window": {"from": "2026-07-02T14:00:00.000Z", "to": "2026-07-02T15:50:00.000Z", "capped": false}} \ No newline at end of file diff --git a/ui/storybook/stories/work-timeline.stories.tsx b/ui/storybook/stories/work-timeline.stories.tsx deleted file mode 100644 index 169541f8f1..0000000000 --- a/ui/storybook/stories/work-timeline.stories.tsx +++ /dev/null @@ -1,164 +0,0 @@ -import { useState } from "react"; -import type { Meta, StoryObj } from "@storybook/react-vite"; -import type { WorkTimelineResult } from "@paperclipai/shared"; -import { WorkTimelineChart, type ZoomLevel } from "@/components/timeline/WorkTimelineChart"; -import { issueColor, type ColorMode } from "@/lib/timeline/layout"; -import { cn } from "@/lib/utils"; -import sampleJson from "../fixtures/workTimeline.sample.json"; -import humanSampleJson from "../fixtures/workTimeline.human.sample.json"; - -const sample = sampleJson as unknown as WorkTimelineResult; -// A second real slice (2026-07-02 14:00–16:00Z) captured straight from the live -// `/timeline` endpoint that DOES carry human events — Dotta's created / commented / -// approved / delegated actions render as instant diamond markers on her own row. -const humanSample = humanSampleJson as unknown as WorkTimelineResult; -// The fixture is a real slice of PAP company activity (2026-07-02 14:00–15:50Z); -// pin "now" to the window end so in-progress runs fade correctly. -const NOW = new Date("2026-07-02T15:45:00.000Z").getTime(); - -function Segmented({ - value, - options, - onChange, -}: { - value: T; - options: { value: T; label: string }[]; - onChange: (v: T) => void; -}) { - return ( -
- {options.map((opt, i) => ( - - ))} -
- ); -} - -function TimelineHarness({ - initialZoom = "day" as ZoomLevel, - initialColor = "issue" as ColorMode, - data = sample, - now = NOW, -}: { - initialZoom?: ZoomLevel; - initialColor?: ColorMode; - data?: WorkTimelineResult; - now?: number; -}) { - const [zoom, setZoom] = useState(initialZoom); - const [colorMode, setColorMode] = useState(initialColor); - const issues = Array.from( - new Map(data.spans.map((s) => [s.issueId, s.issueIdentifier ?? s.issueTitle ?? "task"])).entries(), - ); - return ( -
-
-
-

Work Timeline

-

- A Gantt view of who did what, when — real PAP activity (2026-07-02, 14:00–15:50Z). Rows are actors; bars are - heartbeat runs colored by task; the avatar chip at a bar's leading edge is who kicked it off; straight lines - are agent→agent delegation. Hover a bar for its task & timing; click to open the task. -

-
- -
- - -
- -
-
- {colorMode === "issue" - ? issues.slice(0, 10).map(([id, label]) => ( - - - {label} - - )) - : ( - <> - - done - - - {" "} - in progress - - - )} -
-
- -
-

- {data.spans.length} runs · {data.actors.length} actors · {data.events.length} human/instant events · real - company data -

-
-
-
- ); -} - -const meta: Meta = { - title: "Pages/Work Timeline", - component: TimelineHarness, - parameters: { layout: "fullscreen" }, -}; -export default meta; - -type Story = StoryObj; - -export const HourByTask: Story = { args: { initialZoom: "hour", initialColor: "issue" } }; -export const DayZoom: Story = { args: { initialZoom: "day", initialColor: "issue" } }; -export const ByStatus: Story = { args: { initialZoom: "hour", initialColor: "status" } }; -// Live slice that carries human events — Dotta gets a row with diamond markers -// for her created / commented / approved / delegated actions (PAP-12444). -export const WithHumanMarkers: Story = { - args: { - initialZoom: "hour", - initialColor: "issue", - data: humanSample, - now: new Date("2026-07-02T16:00:00.000Z").getTime(), - }, -};