From d0e9cc76f2eb114ed63d398ee0a0185d64bff852 Mon Sep 17 00:00:00 2001 From: Dotta <34892728+cryppadotta@users.noreply.github.com> Date: Wed, 6 May 2026 09:00:54 -0500 Subject: [PATCH] Show workspace changes and stale notices in issue threads (#5356) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - The issue thread is the operator's durable audit trail for what changed and why > - Workspace changes and stale disposition notices need to be visible in that same timeline without noisy or misleading rendering > - The local branch already contained backend activity details, timeline conversion, and UI rendering work for those events > - This pull request isolates the issue-thread activity work into a standalone branch against `origin/master` > - The benefit is a focused audit-trail PR that can merge independently of the sidebar/operator UI polish branch ## What Changed - Adds readable workspace-change activity details to issue update activity events. - Surfaces workspace-change events in issue chat/timeline rendering. - Makes the existing issue comment migration idempotent. - Folds and renders stale disposition notices inline so they match activity-log styling and spacing. - Adds focused route, timeline, and issue-thread system notice coverage. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/issue-activity-events-routes.test.ts ui/src/lib/issue-timeline-events.test.ts ui/src/components/IssueChatThreadSystemNotice.test.tsx` — 3 files passed, 22 tests passed. - Confirmed the PR changes 9 files and does not include `pnpm-lock.yaml` or `.github/workflows/*`. - `pnpm exec vitest run server/src/__tests__/issue-closed-workspace-routes.test.ts` — 1 file passed, 4 tests passed. - `pnpm exec vitest run server/src/__tests__/issue-activity-events-routes.test.ts ui/src/lib/issue-timeline-events.test.ts ui/src/components/IssueChatThreadSystemNotice.test.tsx server/src/services/recovery/successful-run-handoff.test.ts packages/shared/src/validators/issue.test.ts` — 5 files passed, 54 tests passed. - `pnpm --filter @paperclipai/shared typecheck && pnpm --filter @paperclipai/server typecheck && pnpm --filter @paperclipai/ui typecheck`. - `pnpm --filter @paperclipai/ui typecheck` after adding the Storybook screenshot fixture. - Captured Storybook screenshots for the new UI rendering paths: - Collapsed stale notice + workspace-change row: `docs/pr-screenshots/pr-5356/issue-thread-notices-collapsed.png` - Expanded stale notice details: `docs/pr-screenshots/pr-5356/issue-thread-notices-expanded.png` ### Screenshots Collapsed stale notice with workspace-change row: ![Collapsed stale notice with workspace-change row](docs/pr-screenshots/pr-5356/issue-thread-notices-collapsed.png) Expanded stale notice details: ![Expanded stale notice details](docs/pr-screenshots/pr-5356/issue-thread-notices-expanded.png) ## Risks - Moderate risk: this touches issue activity serialization and issue-thread rendering, both of which are central operator surfaces. - Migration risk is low: the only migration change makes an existing migration idempotent. - No new migrations are introduced, so there is no cross-PR migration ordering requirement. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - OpenAI Codex, GPT-5 coding agent, shell/tool-use enabled, used to split the existing branch, verify the isolated PR branch, and create this PR. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip --- .../issue-thread-notices-collapsed.png | Bin 0 -> 43721 bytes .../pr-5356/issue-thread-notices-expanded.png | Bin 0 -> 62949 bytes .../db/src/migrations/0078_white_darwin.sql | 6 +- packages/shared/src/types/issue.ts | 1 + packages/shared/src/validators/issue.test.ts | 2 + packages/shared/src/validators/issue.ts | 1 + .../issue-activity-events-routes.test.ts | 71 +++++ server/src/routes/issues.ts | 176 +++++++++-- .../recovery/successful-run-handoff.test.ts | 2 + .../recovery/successful-run-handoff.ts | 2 + ui/src/components/CommentThread.tsx | 17 +- ui/src/components/IssueChatThread.tsx | 284 +++++++++++++++++- .../IssueChatThreadSystemNotice.test.tsx | 93 +++++- ui/src/lib/issue-chat-messages.ts | 6 + ui/src/lib/issue-timeline-events.test.ts | 63 +++- ui/src/lib/issue-timeline-events.ts | 55 +++- .../stories/chat-comments.stories.tsx | 109 +++++++ 17 files changed, 852 insertions(+), 36 deletions(-) create mode 100644 docs/pr-screenshots/pr-5356/issue-thread-notices-collapsed.png create mode 100644 docs/pr-screenshots/pr-5356/issue-thread-notices-expanded.png diff --git a/docs/pr-screenshots/pr-5356/issue-thread-notices-collapsed.png b/docs/pr-screenshots/pr-5356/issue-thread-notices-collapsed.png new file mode 100644 index 0000000000000000000000000000000000000000..0dcefcc32a36280c27f9211a559d0b7a7fa95b36 GIT binary patch literal 43721 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 statement-breakpoint -ALTER TABLE "issue_comments" ADD COLUMN "presentation" jsonb;--> statement-breakpoint -ALTER TABLE "issue_comments" ADD COLUMN "metadata" jsonb; \ No newline at end of file +ALTER TABLE "issue_comments" ADD COLUMN IF NOT EXISTS "author_type" text;--> statement-breakpoint +ALTER TABLE "issue_comments" ADD COLUMN IF NOT EXISTS "presentation" jsonb;--> statement-breakpoint +ALTER TABLE "issue_comments" ADD COLUMN IF NOT EXISTS "metadata" jsonb; diff --git a/packages/shared/src/types/issue.ts b/packages/shared/src/types/issue.ts index 59d9f169..2f09515a 100644 --- a/packages/shared/src/types/issue.ts +++ b/packages/shared/src/types/issue.ts @@ -434,6 +434,7 @@ export interface IssueCommentMetadataSection { export interface IssueCommentMetadata { version: 1; + sourceRunId?: string | null; sections: IssueCommentMetadataSection[]; } diff --git a/packages/shared/src/validators/issue.test.ts b/packages/shared/src/validators/issue.test.ts index ad5fbc53..a8d26845 100644 --- a/packages/shared/src/validators/issue.test.ts +++ b/packages/shared/src/validators/issue.test.ts @@ -65,6 +65,7 @@ describe("issue validators", () => { }, metadata: { version: 1, + sourceRunId: "11111111-1111-4111-8111-111111111111", sections: [ { title: "Evidence", @@ -79,6 +80,7 @@ describe("issue validators", () => { }); expect(parsed.presentation?.detailsDefaultOpen).toBe(false); + expect(parsed.metadata?.sourceRunId).toBe("11111111-1111-4111-8111-111111111111"); expect(parsed.metadata?.sections[0]?.rows).toHaveLength(3); }); diff --git a/packages/shared/src/validators/issue.ts b/packages/shared/src/validators/issue.ts index d1f9af21..d7e26e76 100644 --- a/packages/shared/src/validators/issue.ts +++ b/packages/shared/src/validators/issue.ts @@ -318,6 +318,7 @@ export const issueCommentMetadataSectionSchema = z.object({ export const issueCommentMetadataSchema = z.object({ version: z.literal(1), + sourceRunId: z.string().uuid().nullable().optional(), sections: z.array(issueCommentMetadataSectionSchema).min(1).max(20), }).strict(); diff --git a/server/src/__tests__/issue-activity-events-routes.test.ts b/server/src/__tests__/issue-activity-events-routes.test.ts index dbd15303..14349614 100644 --- a/server/src/__tests__/issue-activity-events-routes.test.ts +++ b/server/src/__tests__/issue-activity-events-routes.test.ts @@ -1,5 +1,6 @@ import express from "express"; import request from "supertest"; +import { getTableName } from "drizzle-orm"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { normalizeIssueExecutionPolicy } from "../services/issue-execution-policy.ts"; @@ -266,6 +267,76 @@ describe("issue activity event routes", () => { }); }, 15_000); + it("logs readable workspace change activity details for issue updates", async () => { + const previousProjectWorkspaceId = "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa"; + const nextExecutionWorkspaceId = "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb"; + const issue = { + ...makeIssue(), + projectId: "cccccccc-cccc-4ccc-8ccc-cccccccccccc", + projectWorkspaceId: previousProjectWorkspaceId, + executionWorkspaceId: null, + executionWorkspacePreference: "shared_workspace", + executionWorkspaceSettings: { mode: "shared_workspace" }, + }; + mockIssueService.getById.mockResolvedValue(issue); + mockIssueService.update.mockImplementation(async (_id: string, patch: Record) => ({ + ...issue, + ...patch, + updatedAt: new Date(), + })); + + const dbMock = { + select: vi.fn(() => ({ + from: (table: unknown) => ({ + where: async () => { + const tableName = getTableName(table as Parameters[0]); + if (tableName === "project_workspaces") { + return [{ id: previousProjectWorkspaceId, name: "Main workspace" }]; + } + if (tableName === "execution_workspaces") { + return [{ id: nextExecutionWorkspaceId, name: "Feature workspace" }]; + } + return []; + }, + }), + })), + }; + + const res = await request(await createApp(dbMock)) + .patch(`/api/issues/${issue.id}`) + .send({ executionWorkspaceId: nextExecutionWorkspaceId }); + + expect(res.status).toBe(200); + await vi.waitFor(() => { + expect(mockLogActivity).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + action: "issue.updated", + details: expect.objectContaining({ + executionWorkspaceId: nextExecutionWorkspaceId, + workspaceChange: { + from: { + label: "Main workspace", + projectWorkspaceId: previousProjectWorkspaceId, + executionWorkspaceId: null, + mode: "shared_workspace", + }, + to: { + label: "Feature workspace", + projectWorkspaceId: previousProjectWorkspaceId, + executionWorkspaceId: nextExecutionWorkspaceId, + mode: "shared_workspace", + }, + }, + _previous: expect.objectContaining({ + executionWorkspaceId: null, + }), + }), + }), + ); + }); + }); + it("logs successful_run_handoff_resolved when an in_progress issue transitions to done with a pending required handoff", async () => { const issue = { ...makeIssue(), status: "in_progress" }; mockIssueService.getById.mockResolvedValue(issue); diff --git a/server/src/routes/issues.ts b/server/src/routes/issues.ts index 69d206d9..4e568c15 100644 --- a/server/src/routes/issues.ts +++ b/server/src/routes/issues.ts @@ -4,7 +4,7 @@ import multer from "multer"; import { z } from "zod"; import { and, desc, eq, inArray } from "drizzle-orm"; import type { Db } from "@paperclipai/db"; -import { activityLog, issueExecutionDecisions } from "@paperclipai/db"; +import { activityLog, executionWorkspaces, issueExecutionDecisions, projectWorkspaces } from "@paperclipai/db"; import { addIssueCommentSchema, acceptIssueThreadInteractionSchema, @@ -96,6 +96,7 @@ import { redactIssueMonitorExternalRef, setIssueExecutionPolicyMonitorScheduledBy, } from "../services/issue-execution-policy.js"; +import { parseIssueExecutionWorkspaceSettings } from "../services/execution-workspace-policy.js"; import type { PluginWorkerManager } from "../services/plugin-worker-manager.js"; const MAX_ISSUE_COMMENT_LIMIT = 500; @@ -142,10 +143,148 @@ const SUCCESSFUL_RUN_HANDOFF_ACTIONS = [ "issue.successful_run_handoff_escalated", ] as const; +const ISSUE_WORKSPACE_AUDIT_FIELDS = new Set([ + "projectWorkspaceId", + "executionWorkspaceId", + "executionWorkspacePreference", + "executionWorkspaceSettings", +]); + function readNonEmptyString(value: unknown): string | null { return typeof value === "string" && value.trim().length > 0 ? value.trim() : null; } +function hasIssueWorkspaceAuditChange(previous: Record) { + return Object.keys(previous).some((key) => ISSUE_WORKSPACE_AUDIT_FIELDS.has(key)); +} + +function labelIssueWorkspaceMode(mode: string | null) { + switch (mode) { + case "shared_workspace": + return "Project default"; + case "isolated_workspace": + return "New isolated workspace"; + case "operator_branch": + return "Operator branch"; + case "reuse_existing": + return "Reuse existing workspace"; + case "agent_default": + return "Agent default"; + case "inherit": + return "Inherited workspace"; + default: + return "No workspace"; + } +} + +type IssueWorkspaceAuditInput = { + projectWorkspaceId?: string | null; + executionWorkspaceId?: string | null; + executionWorkspacePreference?: string | null; + executionWorkspaceSettings?: unknown; +}; + +type WorkspaceNameMaps = { + projectWorkspaceNames: Map; + executionWorkspaceNames: Map; +}; + +function emptyWorkspaceNameMaps(): WorkspaceNameMaps { + return { + projectWorkspaceNames: new Map(), + executionWorkspaceNames: new Map(), + }; +} + +function summarizeIssueWorkspaceForActivity( + issue: IssueWorkspaceAuditInput, + names: WorkspaceNameMaps, +) { + const settings = parseIssueExecutionWorkspaceSettings(issue.executionWorkspaceSettings); + const mode = settings?.mode ?? issue.executionWorkspacePreference ?? null; + const executionWorkspaceId = issue.executionWorkspaceId ?? null; + const projectWorkspaceId = issue.projectWorkspaceId ?? null; + + const label = (() => { + if (executionWorkspaceId) { + return names.executionWorkspaceNames.get(executionWorkspaceId) ?? `Workspace ${executionWorkspaceId.slice(0, 8)}`; + } + if (projectWorkspaceId) { + return names.projectWorkspaceNames.get(projectWorkspaceId) ?? `Workspace ${projectWorkspaceId.slice(0, 8)}`; + } + return labelIssueWorkspaceMode(mode); + })(); + + return { + label, + projectWorkspaceId, + executionWorkspaceId, + mode, + }; +} + +async function buildIssueWorkspaceChangeActivityDetails( + db: Db, + companyId: string, + previousIssue: IssueWorkspaceAuditInput, + nextIssue: IssueWorkspaceAuditInput, +) { + const projectWorkspaceIds = [ + previousIssue.projectWorkspaceId, + nextIssue.projectWorkspaceId, + ].filter((value): value is string => typeof value === "string" && value.length > 0); + const executionWorkspaceIds = [ + previousIssue.executionWorkspaceId, + nextIssue.executionWorkspaceId, + ].filter((value): value is string => typeof value === "string" && value.length > 0); + + const [projectRows, executionRows] = await Promise.all([ + projectWorkspaceIds.length > 0 + ? db + .select({ id: projectWorkspaces.id, name: projectWorkspaces.name }) + .from(projectWorkspaces) + .where(and(eq(projectWorkspaces.companyId, companyId), inArray(projectWorkspaces.id, projectWorkspaceIds))) + : Promise.resolve([]), + executionWorkspaceIds.length > 0 + ? db + .select({ id: executionWorkspaces.id, name: executionWorkspaces.name }) + .from(executionWorkspaces) + .where(and(eq(executionWorkspaces.companyId, companyId), inArray(executionWorkspaces.id, executionWorkspaceIds))) + : Promise.resolve([]), + ]); + + const names: WorkspaceNameMaps = { + projectWorkspaceNames: new Map(projectRows.map((row) => [row.id, row.name])), + executionWorkspaceNames: new Map(executionRows.map((row) => [row.id, row.name])), + }; + + return { + from: summarizeIssueWorkspaceForActivity(previousIssue, names), + to: summarizeIssueWorkspaceForActivity(nextIssue, names), + }; +} + +function hasExecutionParticipant(value: unknown) { + const state = parseIssueExecutionState(value); + if (!state || state.status !== "pending") return false; + const participant = state.currentParticipant; + if (!participant) return false; + if (participant.type === "agent") return Boolean(participant.agentId); + if (participant.type === "user") return Boolean(participant.userId); + return false; +} + +function hasScheduledMonitor(input: { + existingMonitorNextCheckAt?: Date | null; + patchMonitorNextCheckAt?: unknown; + executionPolicy?: unknown; +}) { + if (input.patchMonitorNextCheckAt instanceof Date && !Number.isNaN(input.patchMonitorNextCheckAt.getTime())) return true; + if (input.patchMonitorNextCheckAt === undefined && input.existingMonitorNextCheckAt) return true; + const policy = normalizeIssueExecutionPolicy(input.executionPolicy ?? null); + return Boolean(policy?.monitor?.nextCheckAt); +} + function successfulRunHandoffStateFromActivity(row: { action: string; agentId: string | null; @@ -236,27 +375,6 @@ const INVALID_AGENT_IN_REVIEW_DISPOSITION_MESSAGE = "link or request a pending approval, assign a human reviewer with assigneeUserId, set a typed executionState.currentParticipant through an execution policy, " + "or schedule an issue monitor for an external review/check. After creating one of those review paths, retry the status update."; -function hasExecutionParticipant(value: unknown) { - const state = parseIssueExecutionState(value); - if (!state || state.status !== "pending") return false; - const participant = state.currentParticipant; - if (!participant) return false; - if (participant.type === "agent") return Boolean(participant.agentId); - if (participant.type === "user") return Boolean(participant.userId); - return false; -} - -function hasScheduledMonitor(input: { - existingMonitorNextCheckAt?: Date | null; - patchMonitorNextCheckAt?: unknown; - executionPolicy?: unknown; -}) { - if (input.patchMonitorNextCheckAt instanceof Date && !Number.isNaN(input.patchMonitorNextCheckAt.getTime())) return true; - if (input.patchMonitorNextCheckAt === undefined && input.existingMonitorNextCheckAt) return true; - const policy = normalizeIssueExecutionPolicy(input.executionPolicy ?? null); - return Boolean(policy?.monitor?.nextCheckAt); -} - function executionPrincipalsEqual( left: ParsedExecutionState["currentParticipant"] | null, right: ParsedExecutionState["currentParticipant"] | null, @@ -2673,6 +2791,19 @@ export function issueRoutes( } const hasFieldChanges = Object.keys(previous).length > 0; + let workspaceChange = null; + if (hasIssueWorkspaceAuditChange(previous)) { + try { + workspaceChange = await buildIssueWorkspaceChangeActivityDetails(db, issue.companyId, existing, issue); + } catch (err) { + logger.warn({ err, issueId: issue.id }, "failed to enrich issue workspace change activity details"); + const fallbackNames = emptyWorkspaceNameMaps(); + workspaceChange = { + from: summarizeIssueWorkspaceForActivity(existing, fallbackNames), + to: summarizeIssueWorkspaceForActivity(issue, fallbackNames), + }; + } + } const reopened = commentBody && effectiveMoveToTodoRequested && @@ -2697,6 +2828,7 @@ export function issueRoutes( ...(reopened ? { reopened: true, reopenedFrom: reopenFromStatus } : {}), ...(interruptedRunId ? { interruptedRunId } : {}), ...(cancelledStatusRunId ? { cancelledStatusRunId } : {}), + ...(workspaceChange ? { workspaceChange } : {}), _previous: hasFieldChanges ? previous : undefined, ...summarizeIssueReferenceActivityDetails( updateReferenceDiff diff --git a/server/src/services/recovery/successful-run-handoff.test.ts b/server/src/services/recovery/successful-run-handoff.test.ts index b5e25b74..727512f4 100644 --- a/server/src/services/recovery/successful-run-handoff.test.ts +++ b/server/src/services/recovery/successful-run-handoff.test.ts @@ -218,6 +218,7 @@ describe("successful run handoff decision", () => { title: "Missing issue disposition", detailsDefaultOpen: false, }); + expect(notice.metadata.sourceRunId).toBe("22222222-2222-4222-8222-222222222222"); expect(notice.metadata.sections).toEqual(expect.arrayContaining([ expect.objectContaining({ title: "Required action", @@ -267,6 +268,7 @@ describe("successful run handoff decision", () => { tone: "danger", detailsDefaultOpen: false, }); + expect(notice.metadata.sourceRunId).toBe("22222222-2222-4222-8222-222222222222"); expect(notice.metadata.sections).toEqual(expect.arrayContaining([ expect.objectContaining({ title: "Recovery owner", diff --git a/server/src/services/recovery/successful-run-handoff.ts b/server/src/services/recovery/successful-run-handoff.ts index 2d5b79ff..1b9bbe18 100644 --- a/server/src/services/recovery/successful-run-handoff.ts +++ b/server/src/services/recovery/successful-run-handoff.ts @@ -146,6 +146,7 @@ export function buildSuccessfulRunHandoffRequiredNotice(input: { }), metadata: { version: 1, + sourceRunId: input.run.id, sections: [ { title: "Required action", @@ -193,6 +194,7 @@ export function buildSuccessfulRunHandoffExhaustedNotice(input: { }), metadata: { version: 1, + sourceRunId: input.sourceRun?.id ?? null, sections: [ { title: "Recovery owner", diff --git a/ui/src/components/CommentThread.tsx b/ui/src/components/CommentThread.tsx index 080b3e97..e80abea7 100644 --- a/ui/src/components/CommentThread.tsx +++ b/ui/src/components/CommentThread.tsx @@ -20,7 +20,7 @@ import { OutputFeedbackButtons } from "./OutputFeedbackButtons"; import { ApprovalCard } from "./ApprovalCard"; import { AgentIcon } from "./AgentIconPicker"; import { formatAssigneeUserLabel } from "../lib/assignees"; -import type { IssueTimelineAssignee, IssueTimelineEvent } from "../lib/issue-timeline-events"; +import { formatTimelineWorkspaceLabel, type IssueTimelineAssignee, type IssueTimelineEvent } from "../lib/issue-timeline-events"; import { timeAgo } from "../lib/timeAgo"; import { cn, formatDateTime } from "../lib/utils"; import { restoreSubmittedCommentDraft } from "../lib/comment-submit-draft"; @@ -535,6 +535,21 @@ function TimelineEventCard({ ) : null} + + {event.workspaceChange ? ( +

+ + Workspace + + + {formatTimelineWorkspaceLabel(event.workspaceChange.from)} + + + + {formatTimelineWorkspaceLabel(event.workspaceChange.to)} + +
+ ) : null} ); diff --git a/ui/src/components/IssueChatThread.tsx b/ui/src/components/IssueChatThread.tsx index 792b129f..9ac472f5 100644 --- a/ui/src/components/IssueChatThread.tsx +++ b/ui/src/components/IssueChatThread.tsx @@ -16,6 +16,7 @@ import { useCallback, useContext, useEffect, + useId, useImperativeHandle, useLayoutEffect, useMemo, @@ -61,7 +62,12 @@ import type { } from "../lib/issue-thread-interactions"; import { buildIssueThreadInteractionSummary, isIssueThreadInteraction } from "../lib/issue-thread-interactions"; import { resolveIssueChatTranscriptRuns } from "../lib/issueChatTranscriptRuns"; -import type { IssueTimelineAssignee, IssueTimelineEvent } from "../lib/issue-timeline-events"; +import { + formatTimelineWorkspaceLabel, + type IssueTimelineAssignee, + type IssueTimelineEvent, + type IssueTimelineWorkspace, +} from "../lib/issue-timeline-events"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; @@ -99,8 +105,15 @@ import { isSuccessfulRunHandoffComment, isSuccessfulRunHandoffEscalationComment, } from "../lib/successful-run-handoff"; -import { SystemNotice } from "./SystemNotice"; -import { buildSystemNoticeProps } from "../lib/system-notice-comment"; +import { + SystemNotice, + type SystemNoticeMetadataRow, + type SystemNoticeMetadataSection, +} from "./SystemNotice"; +import { + buildSystemNoticeProps, + mapCommentMetadataToSystemNoticeSections, +} from "../lib/system-notice-comment"; import type { IssueCommentMetadata, IssueCommentPresentation, @@ -155,11 +168,15 @@ interface IssueChatMessageContext { onCancelInteraction?: ( interaction: AskUserQuestionsInteraction, ) => Promise | void; + issueStatus?: string; + successfulRunHandoff?: SuccessfulRunHandoffState | null; } const IssueChatCtx = createContext({ feedbackDataSharingPreference: "prompt", feedbackTermsUrl: null, + issueStatus: undefined, + successfulRunHandoff: null, }); export function resolveAssistantMessageFoldedState(args: { @@ -1968,6 +1985,227 @@ function isIssueCommentMetadata(value: unknown): value is IssueCommentMetadata { return v.version === 1 && Array.isArray(v.sections); } +function issueStatusIsTerminalDisposition(issueStatus: string | undefined) { + return issueStatus === "done" || issueStatus === "cancelled"; +} + +function sourceRunIdFromSuccessfulRunHandoffMetadata(metadata: IssueCommentMetadata | null) { + if (metadata?.sourceRunId) return metadata.sourceRunId; + const runLinks = []; + for (const section of metadata?.sections ?? []) { + for (const row of section.rows) { + if (row.type === "run_link") runLinks.push(row.runId); + } + } + return runLinks.length === 1 ? runLinks[0] : null; +} + +function isStaleSuccessfulRunHandoffNotice(input: { + bodyText: string; + issueStatus?: string; + successfulRunHandoff?: SuccessfulRunHandoffState | null; + runId?: string | null; + metadata: IssueCommentMetadata | null; +}) { + if (!isSuccessfulRunHandoffComment(input.bodyText)) return false; + + const currentHandoff = input.successfulRunHandoff ?? null; + if (currentHandoff?.state === "resolved") return true; + if (issueStatusIsTerminalDisposition(input.issueStatus)) return true; + + const noticeSourceRunId = sourceRunIdFromSuccessfulRunHandoffMetadata(input.metadata) ?? input.runId ?? null; + if ( + noticeSourceRunId + && currentHandoff?.sourceRunId + && noticeSourceRunId !== currentHandoff.sourceRunId + ) { + return true; + } + + return false; +} + +function StaleDispositionWarningMetadataRow({ row }: { row: SystemNoticeMetadataRow }) { + const label = ( + + {row.label} + + ); + const value = (() => { + switch (row.kind) { + case "text": + return {row.value}; + case "code": + return ( + + {row.value} + + ); + case "issue": { + const content = ( + <> + {row.identifier} + {row.title ? - {row.title} : null} + + ); + return row.href ? ( + + {content} + + ) : ( + {content} + ); + } + case "agent": + return row.href ? ( + + {row.name} + + ) : ( + {row.name} + ); + case "run": { + const runShort = row.runId.length > 12 ? `${row.runId.slice(0, 8)}...` : row.runId; + const content = ( + <> + + {runShort} + + {row.status ? {row.status} : null} + + ); + return row.href ? ( + + {content} + + ) : ( + {content} + ); + } + } + })(); + + return ( +
+ {label} +
{value}
+
+ ); +} + +function metadataRowKey(row: SystemNoticeMetadataRow) { + switch (row.kind) { + case "issue": + return `issue:${row.label}:${row.identifier}:${row.href ?? ""}:${row.title ?? ""}`; + case "agent": + return `agent:${row.label}:${row.name}:${row.href ?? ""}`; + case "run": + return `run:${row.label}:${row.runId}:${row.href ?? ""}:${row.status ?? ""}`; + default: + return `${row.kind}:${row.label}:${row.value}`; + } +} + +function metadataSectionKey(section: SystemNoticeMetadataSection) { + return `${section.title ?? "details"}:${section.rows.map(metadataRowKey).join("|")}`; +} + +function isNullableString(value: unknown): value is string | null { + return value === null || typeof value === "string"; +} + +function isTimelineWorkspace(value: unknown): value is IssueTimelineWorkspace { + if (!value || typeof value !== "object" || Array.isArray(value)) return false; + const workspace = value as Record; + return isNullableString(workspace.label) + && isNullableString(workspace.projectWorkspaceId) + && isNullableString(workspace.executionWorkspaceId) + && isNullableString(workspace.mode); +} + +function isTimelineWorkspaceChange(value: unknown): value is NonNullable { + if (!value || typeof value !== "object" || Array.isArray(value)) return false; + const change = value as Record; + return isTimelineWorkspace(change.from) && isTimelineWorkspace(change.to); +} + +function StaleDispositionWarningDetails({ + sections, +}: { + sections: SystemNoticeMetadataSection[]; +}) { + if (sections.length === 0) { + return
No additional details.
; + } + + return ( +
+ {sections.map((section) => ( +
+ {section.title ? ( +
+ {section.title} +
+ ) : null} +
+ {section.rows.map((row) => ( + + ))} +
+
+ ))} +
+ ); +} + +function StaleDispositionWarningRow({ + anchorId, + message, + metadata, + runAgentId, +}: { + anchorId?: string; + message: ThreadMessage; + metadata: IssueCommentMetadata | null; + runAgentId?: string | null; +}) { + const [open, setOpen] = useState(false); + const detailsId = useId(); + const sections = mapCommentMetadataToSystemNoticeSections(metadata, { runAgentId }); + + return ( +
+
+ +
+ + +
+
+
+ ); +} + function SystemNoticeCommentRow({ message, anchorId, @@ -1975,7 +2213,7 @@ function SystemNoticeCommentRow({ message: ThreadMessage; anchorId?: string; }) { - const { onImageClick, agentMap } = useContext(IssueChatCtx); + const { onImageClick, agentMap, issueStatus, successfulRunHandoff } = useContext(IssueChatCtx); const custom = message.metadata.custom as Record; const presentation = isIssueCommentPresentation(custom.presentation) ? custom.presentation : null; const commentMetadata = isIssueCommentMetadata(custom.commentMetadata) ? custom.commentMetadata : null; @@ -1987,6 +2225,13 @@ function SystemNoticeCommentRow({ .filter((p): p is { type: "text"; text: string } => p.type === "text") .map((p) => p.text) .join("\n\n"); + const staleSuccessfulRunHandoffNotice = isStaleSuccessfulRunHandoffNotice({ + bodyText, + issueStatus, + successfulRunHandoff, + runId, + metadata: commentMetadata, + }); const [copied, setCopied] = useState(false); const [copiedLink, setCopiedLink] = useState(false); @@ -2033,6 +2278,17 @@ function SystemNoticeCommentRow({ }); }; + if (staleSuccessfulRunHandoffNotice) { + return ( + + ); + } + return (
@@ -2105,6 +2361,7 @@ function IssueChatSystemMessage({ message }: { message: ThreadMessage }) { to: IssueTimelineAssignee; } : null; + const workspaceChange = isTimelineWorkspaceChange(custom.workspaceChange) ? custom.workspaceChange : null; const interaction = isIssueThreadInteraction(custom.interaction) ? custom.interaction : null; @@ -2192,6 +2449,21 @@ function IssueChatSystemMessage({ message }: { message: ThreadMessage }) {
) : null} + + {workspaceChange ? ( +
+ + Workspace + + + {formatTimelineWorkspaceLabel(workspaceChange.from)} + + + + {formatTimelineWorkspaceLabel(workspaceChange.to)} + +
+ ) : null}
); @@ -3855,6 +4127,8 @@ export function IssueChatThread({ onRejectInteraction: stableOnRejectInteraction, onSubmitInteractionAnswers: stableOnSubmitInteractionAnswers, onCancelInteraction: stableOnCancelInteraction, + issueStatus, + successfulRunHandoff, }), [ feedbackDataSharingPreference, @@ -3875,6 +4149,8 @@ export function IssueChatThread({ stableOnRejectInteraction, stableOnSubmitInteractionAnswers, stableOnCancelInteraction, + issueStatus, + successfulRunHandoff, ], ); diff --git a/ui/src/components/IssueChatThreadSystemNotice.test.tsx b/ui/src/components/IssueChatThreadSystemNotice.test.tsx index 01453d38..a1173df4 100644 --- a/ui/src/components/IssueChatThreadSystemNotice.test.tsx +++ b/ui/src/components/IssueChatThreadSystemNotice.test.tsx @@ -7,7 +7,7 @@ import { MemoryRouter } from "react-router-dom"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { IssueChatThread } from "./IssueChatThread"; import type { IssueChatComment } from "../lib/issue-chat-messages"; -import type { Agent } from "@paperclipai/shared"; +import type { Agent, SuccessfulRunHandoffState } from "@paperclipai/shared"; vi.mock("@assistant-ui/react", () => ({ AssistantRuntimeProvider: ({ children }: { children: ReactNode }) =>
{children}
, @@ -70,7 +70,14 @@ afterEach(() => { container.remove(); }); -function renderThread(comments: IssueChatComment[], agentMap?: Map) { +function renderThread( + comments: IssueChatComment[], + options: { + agentMap?: Map; + issueStatus?: string; + successfulRunHandoff?: SuccessfulRunHandoffState | null; + } = {}, +) { act(() => { root.render( @@ -82,7 +89,9 @@ function renderThread(comments: IssueChatComment[], agentMap?: Map {}} showComposer={false} enableLiveTranscriptPolling={false} - agentMap={agentMap} + agentMap={options.agentMap} + issueStatus={options.issueStatus} + successfulRunHandoff={options.successfulRunHandoff} /> , ); @@ -265,7 +274,7 @@ describe("IssueChatThread system notice routing", () => { ...baseTimestamps, }; - renderThread([comment], agentMap); + renderThread([comment], { agentMap }); const status = container.querySelector('[role="status"]'); expect(status).not.toBeNull(); @@ -395,4 +404,80 @@ describe("IssueChatThread system notice routing", () => { expect(container.querySelector('[role="status"]')).toBeNull(); expect(container.querySelector('[data-message-role="assistant"]')).not.toBeNull(); }); + + it("folds stale successful-run disposition warnings into the activity log disclosure style", () => { + const comment: IssueChatComment = { + id: "comment-stale-disposition-warning", + companyId: "company-1", + issueId: "issue-1", + authorType: "system", + authorAgentId: null, + authorUserId: null, + runId: "run-stale", + runAgentId: "agent-codex", + body: "Paperclip needs a disposition before this issue can continue.", + presentation: { + kind: "system_notice", + tone: "warning", + title: "Missing issue disposition", + detailsDefaultOpen: false, + }, + metadata: { + version: 1, + sourceRunId: "run-stale", + sections: [ + { + title: "Run evidence", + rows: [ + { type: "run_link", label: "Completed run", runId: "run-stale", title: "succeeded" }, + { type: "key_value", label: "Normalized cause", value: "successful_run_missing_state" }, + ], + }, + ], + }, + ...baseTimestamps, + }; + + renderThread([comment], { + issueStatus: "done", + successfulRunHandoff: { + state: "resolved", + required: false, + sourceRunId: "run-stale", + correctiveRunId: "run-corrective", + assigneeAgentId: "agent-codex", + detectedProgressSummary: null, + createdAt: new Date("2026-05-04T17:00:00.000Z"), + }, + }); + + const row = container.querySelector('[data-testid="stale-disposition-warning"]'); + expect(row).not.toBeNull(); + expect(row?.querySelector('span[aria-hidden="true"]')?.className).toContain("size-6"); + const toggle = row?.querySelector("button[aria-expanded]") as HTMLButtonElement; + expect(toggle.className).toContain("w-full"); + expect(toggle.className).toContain("py-0.5"); + expect(row?.querySelector('[role="status"]')).toBeNull(); + expect(row?.querySelector(".lucide-triangle-alert")).toBeNull(); + expect(row?.querySelector(".lucide-chevron-down")).not.toBeNull(); + expect(row?.querySelector('[data-testid="stale-disposition-warning-time"]')?.parentElement?.className).toContain("ml-auto"); + expect(row?.textContent).toContain("Stale disposition warning"); + expect(row?.textContent).not.toContain("This disposition warning is stale because the issue now has a newer disposition."); + expect(row?.textContent).not.toContain("Paperclip needs a disposition before this issue can continue."); + + expect(toggle.getAttribute("aria-expanded")).toBe("false"); + const detailsId = toggle.getAttribute("aria-controls"); + expect(detailsId).toBeTruthy(); + const details = detailsId ? container.ownerDocument.getElementById(detailsId) : null; + expect(details).not.toBeNull(); + expect(details?.textContent).toContain("run-stale"); + expect(details).toHaveProperty("hidden", true); + act(() => { + toggle.click(); + }); + + expect(toggle.getAttribute("aria-expanded")).toBe("true"); + expect(details).toHaveProperty("hidden", false); + expect(container.textContent).toContain("run-stale"); + }); }); diff --git a/ui/src/lib/issue-chat-messages.ts b/ui/src/lib/issue-chat-messages.ts index ef50a4e6..59d0ac90 100644 --- a/ui/src/lib/issue-chat-messages.ts +++ b/ui/src/lib/issue-chat-messages.ts @@ -455,6 +455,11 @@ function createTimelineEventMessage(args: { : (formatAssigneeUserLabel(event.assigneeChange.to.userId, currentUserId, userLabelMap) ?? "Unassigned"); lines.push(`Assignee: ${from} -> ${to}`); } + if (event.workspaceChange) { + lines.push( + `Workspace: ${event.workspaceChange.from.label ?? "none"} -> ${event.workspaceChange.to.label ?? "none"}`, + ); + } const message: ThreadSystemMessage = { id: `activity:${event.id}`, @@ -471,6 +476,7 @@ function createTimelineEventMessage(args: { actorId: event.actorId, statusChange: event.statusChange ?? null, assigneeChange: event.assigneeChange ?? null, + workspaceChange: event.workspaceChange ?? null, followUpRequested: event.followUpRequested === true, }, }, diff --git a/ui/src/lib/issue-timeline-events.test.ts b/ui/src/lib/issue-timeline-events.test.ts index 3b073954..4458be79 100644 --- a/ui/src/lib/issue-timeline-events.test.ts +++ b/ui/src/lib/issue-timeline-events.test.ts @@ -171,6 +171,67 @@ describe("extractIssueTimelineEvents", () => { ]); }); + it("extracts workspace changes from issue update activity", () => { + const events = extractIssueTimelineEvents([ + { + id: "evt-workspace", + companyId: "company-1", + actorType: "user", + actorId: "local-board", + action: "issue.updated", + entityType: "issue", + entityId: "issue-1", + agentId: null, + runId: null, + createdAt: new Date("2026-03-31T12:01:00.000Z"), + details: { + projectWorkspaceId: "workspace-2", + workspaceChange: { + from: { + label: "Main workspace", + projectWorkspaceId: "workspace-1", + executionWorkspaceId: null, + mode: "shared_workspace", + }, + to: { + label: "Feature branch", + projectWorkspaceId: "workspace-2", + executionWorkspaceId: null, + mode: "shared_workspace", + }, + }, + _previous: { + projectWorkspaceId: "workspace-1", + }, + }, + }, + ] satisfies ActivityEvent[]); + + expect(events).toEqual([ + { + id: "evt-workspace", + createdAt: new Date("2026-03-31T12:01:00.000Z"), + actorType: "user", + actorId: "local-board", + runId: null, + workspaceChange: { + from: { + label: "Main workspace", + projectWorkspaceId: "workspace-1", + executionWorkspaceId: null, + mode: "shared_workspace", + }, + to: { + label: "Feature branch", + projectWorkspaceId: "workspace-2", + executionWorkspaceId: null, + mode: "shared_workspace", + }, + }, + }, + ]); + }); + it("synthesizes non-status follow-up rows from comment activity", () => { const events = extractIssueTimelineEvents([ { @@ -205,7 +266,7 @@ describe("extractIssueTimelineEvents", () => { ]); }); - it("ignores issue updates without visible status or assignee transitions", () => { + it("ignores issue updates without visible status, assignee, or workspace transitions", () => { const events = extractIssueTimelineEvents([ { id: "evt-title", diff --git a/ui/src/lib/issue-timeline-events.ts b/ui/src/lib/issue-timeline-events.ts index d1d12b11..4ade3db4 100644 --- a/ui/src/lib/issue-timeline-events.ts +++ b/ui/src/lib/issue-timeline-events.ts @@ -19,10 +19,26 @@ export interface IssueTimelineEvent { from: IssueTimelineAssignee; to: IssueTimelineAssignee; }; + workspaceChange?: { + from: IssueTimelineWorkspace; + to: IssueTimelineWorkspace; + }; commentId?: string | null; followUpRequested?: boolean; } +export interface IssueTimelineWorkspace { + label: string | null; + projectWorkspaceId: string | null; + executionWorkspaceId: string | null; + mode: string | null; +} + +export function formatTimelineWorkspaceLabel(workspace: IssueTimelineWorkspace) { + const fallbackId = workspace.executionWorkspaceId ?? workspace.projectWorkspaceId; + return workspace.label ?? (fallbackId ? fallbackId.slice(0, 8) : "None"); +} + function asRecord(value: unknown): Record | null { if (typeof value !== "object" || value === null || Array.isArray(value)) return null; return value as Record; @@ -44,6 +60,33 @@ function sameAssignee(left: IssueTimelineAssignee, right: IssueTimelineAssignee) return left.agentId === right.agentId && left.userId === right.userId; } +function sameWorkspace(left: IssueTimelineWorkspace, right: IssueTimelineWorkspace) { + return left.projectWorkspaceId === right.projectWorkspaceId + && left.executionWorkspaceId === right.executionWorkspaceId + && left.mode === right.mode + && left.label === right.label; +} + +function workspaceFromRecord(value: unknown): IssueTimelineWorkspace | null { + const record = asRecord(value); + if (!record) return null; + return { + label: nullableString(record.label), + projectWorkspaceId: nullableString(record.projectWorkspaceId), + executionWorkspaceId: nullableString(record.executionWorkspaceId), + mode: nullableString(record.mode), + }; +} + +function workspaceChangeFromDetails(details: Record) { + const change = asRecord(details.workspaceChange); + if (!change) return null; + const from = workspaceFromRecord(change.from); + const to = workspaceFromRecord(change.to); + if (!from || !to || sameWorkspace(from, to)) return null; + return { from, to }; +} + function sortTimelineEvents(events: T[]) { return [...events].sort((a, b) => { const createdAtDiff = toTimestamp(a.createdAt) - toTimestamp(b.createdAt); @@ -120,7 +163,17 @@ export function extractIssueTimelineEvents(activity: ActivityEvent[] | null | un } } - if (timelineEvent.statusChange || timelineEvent.assigneeChange || timelineEvent.followUpRequested) { + const workspaceChange = workspaceChangeFromDetails(details); + if (workspaceChange) { + timelineEvent.workspaceChange = workspaceChange; + } + + if ( + timelineEvent.statusChange + || timelineEvent.assigneeChange + || timelineEvent.workspaceChange + || timelineEvent.followUpRequested + ) { events.push(timelineEvent); } } diff --git a/ui/storybook/stories/chat-comments.stories.tsx b/ui/storybook/stories/chat-comments.stories.tsx index cb5431da..041293f9 100644 --- a/ui/storybook/stories/chat-comments.stories.tsx +++ b/ui/storybook/stories/chat-comments.stories.tsx @@ -404,6 +404,7 @@ const issueChatComments: IssueChatComment[] = [ }, metadata: { version: 1, + sourceRunId: "run-issue-chat-01", sections: [ { title: "Required action", @@ -459,6 +460,73 @@ const issueTimelineEvents: IssueTimelineEvent[] = [ }), ]; +const issueThreadNoticeReviewComments: IssueChatComment[] = [ + createComment({ + id: "comment-notice-board", + body: "The issue thread needs to show workspace routing changes and make old missing-disposition warnings feel resolved.", + createdAt: new Date("2026-04-20T13:44:00.000Z"), + }), + createComment({ + id: "comment-notice-system-warning", + authorType: "system", + authorAgentId: null, + authorUserId: null, + runId: "run-notice-source", + runAgentId: codexAgent.id, + body: "Paperclip needs a disposition before this issue can continue.", + presentation: { + kind: "system_notice", + tone: "warning", + title: "Missing issue disposition", + detailsDefaultOpen: false, + }, + metadata: { + version: 1, + sourceRunId: "run-notice-source", + sections: [ + { + title: "Required action", + rows: [ + { type: "issue_link", label: "Source issue", issueId, identifier: "PAP-3660", title: "Show issue-thread notices" }, + { type: "agent_link", label: "Assignee", agentId: codexAgent.id, name: codexAgent.name }, + { type: "key_value", label: "Missing disposition", value: "clear_next_step" }, + ], + }, + { + title: "Run evidence", + rows: [ + { type: "run_link", label: "Completed run", runId: "run-notice-source", title: "succeeded" }, + { type: "key_value", label: "Normalized cause", value: "successful_run_missing_state" }, + ], + }, + ], + }, + createdAt: new Date("2026-04-20T13:48:00.000Z"), + }), +]; + +const issueThreadNoticeReviewTimelineEvents: IssueTimelineEvent[] = [ + createSystemEvent({ + id: "event-notice-workspace-change", + createdAt: new Date("2026-04-20T13:46:00.000Z"), + statusChange: undefined, + workspaceChange: { + from: { + label: "Project primary workspace", + projectWorkspaceId: "workspace-primary", + executionWorkspaceId: null, + mode: "shared_workspace", + }, + to: { + label: "PAP-3660 issue-thread-notices", + projectWorkspaceId: null, + executionWorkspaceId: "execution-workspace-notices", + mode: "isolated_workspace", + }, + }, + }), +]; + const issueLinkedRuns: IssueChatLinkedRun[] = [ { runId: "run-issue-chat-01", @@ -701,6 +769,43 @@ function IssueChatMatrix() { ); } +function IssueThreadNoticeReview() { + return ( +
+
+
+
+ {}} + enableLiveTranscriptPolling={false} + showJumpToLatest={false} + /> +
+
+
+
+ ); +} + function ChatCommentsStories() { return (
@@ -771,3 +876,7 @@ export const IssueChatWithTimeline: Story = {
), }; + +export const IssueThreadNotices: Story = { + render: () => , +};