feat: make chat-style tasks the default experience - #11101
Open
scotttong wants to merge 36 commits into
Open
Conversation
…onfirm→act)
Rewrite the auto-created first-run onboarding task so it welcomes the user,
asks clarifying questions, proposes a plan + team, confirms, then acts — and
drops the "CEO" framing (PAP-396, implements approved PAP-395 rev 2 plan).
- OnboardingWizard.tsx: new DEFAULT_TASK_TITLE / DEFAULT_TASK_DESCRIPTION
("You are the Paperclip agent") with the 5-step ask→propose→confirm→act flow.
- ceo-instructions.ts: seeded lead-agent instructions no longer call the role
"CEO"; team/org-neutral wording.
- e2e title literals updated to match the new task title so the specs compile.
Scope A: internal role enum stays role:"ceo"; OnboardingChat.tsx untouched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ents Board feedback on PAP-396: - After the onboarding wizard, drop the user into the first task's detail page (not the dashboard) so they land on the conversation the agent starts in. - Stop auto-provisioning the Reflection Coach and Summarizer for new users. autoProvisionBundledAgents now creates nothing by default (gated by an empty AUTO_PROVISION_ON_COMPANY_CREATE_KEYS) but still reconciles any bundled agent an operator already enabled. Both remain available to enable on demand. Tests updated to reflect the new default: fresh companies have no bundled built-in agents; the enable-on-demand + reconcile-of-existing paths keep their coverage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The redirect fix in 52b2675aa navigates to the first task's detail page
after onboarding, but the two e2e specs still asserted a /dashboard URL
(Change 3 updated only the title literal). Verified via Playwright that
the wizard now lands on /{prefix}/issues/{ref}; update both assertions
and the now-stale conference-room docstring/test names to match.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…on bubble
Round 2 · Ask 1 (PAP-400, from approved plan PAP-396). Under the task-chat
redesign the seeded first-task description rendered as a right-aligned "user"
bubble, as if the user had typed the agent's own instructions. Instead:
- Mark the single onboarding first task with a new `onboarding_first_task`
origin kind. The wizard sends a narrow `onboardingFirstTask` flag; the server
owns the resulting origin kind so clients can't set arbitrary ones.
- Suppress the seeded-description bubble in the task-detail chat for that origin
kind (IssueDetail passes `issueBrief={undefined}`).
- Seed a deterministic, template-driven agent greeting (team name + reflected
goals + propose-not-decide + questions-coming) as an agent-authored comment at
issue-create time, best-effort so a greeting failure never fails create.
- Drop step 1 ("Welcome the user…") from DEFAULT_TASK_DESCRIPTION and note a
greeting is already posted, so the first auto-run goes straight to
ask_user_questions.
UI + server typecheck green; greeting-builder and onboarding-launch unit tests
green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Round 2 · board feedback on PAP-396. The seeded first-task greeting identified the agent generically as "your Paperclip agent". Instead introduce it by the name the user picked for the agent in the onboarding wizard (e.g. "Welcome — I'm Chief of staff for Acme."), falling back to the generic phrasing only when no name is available. buildOnboardingGreeting now takes an agentName; the issue-create handler resolves the assignee agent's name and passes it through. Greeting unit tests cover the named (with/without team) paths; server typecheck green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rame greeting Per user feedback on PAP-396: - First-task title → "Paperclip onboarding" (with matching e2e literals). - Greeting reframes the agent as "your first agent teammate on Paperclip", drops the "propose, not decide" line, and closes on gathering context to propose a team of agents. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Select the newly created company as a route sync, not a manual switch, so useCompanyPageMemory does not restore the company's remembered page (falling back to /dashboard) and clobber the explicit first-task navigate. The bounce only reproduces on instances that already have >=1 company, where Layout's route-sync effect transiently resets selection while the companies list is stale, making the wizard's setSelectedCompanyId a real change that triggers the page-memory restore. Strengthen the two onboarding e2e specs to catch a reintroduced bounce: a History-API tap records every client-side path so a /dashboard visit is provably detected (react-router uses pushState, so framenavigated never fires), plus a settle-window assertion. Add a variant that seeds a pre-existing company first — the exact failing condition. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…413) Prepend a copy · thumbs-up · thumbs-down cluster to the "✓ Worked · …" summary line below agent bubbles in the redesigned task thread, leading the always-visible timestamp. Runless agent replies get the same cluster with the timestamp trailing; human/system bubbles are unchanged. Reuses the shared IssueChatFeedbackButtons so the thread speaks the same feedback language as the conference room's AgentBubbleActionRow, and wires the redesign to the feedback-vote API props it already received but ignored (feedbackVotes / onVote). Dev harness gets a demo binding. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…awn confirmations (PAP-416) Interaction cards were pinned to createdAt, so a card you just answered could sit above a message written before you answered — reading backwards. Anchor a resolved card at its resolvedAt so it settles next to the answer; pending cards keep the request-time slot. Suppress withdrawn/superseded confirmation cards from the thread so a dead card never stacks above the one that replaced it. New pure helper interaction-thread-order.ts (+8 tests). Phase A of PAP-412. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…(PAP-417) Phase B of PAP-412. Rewrite the seeded first-task flow so the onboarding agent proposes ONE plan-approval card instead of a separate suggested-tasks card plus a plan confirmation. - DEFAULT_TASK_DESCRIPTION steps 2-4: the agent writes the approach plan to the `plan` document, lists proposed hires + follow-up tasks at the bottom, and presents a SINGLE request_checkbox_confirmation targeting the plan doc with each hire/task as a checkable option (checked by default). On approval it creates ONLY the checked options; unchecking drops an item. - Explicitly drops suggest_tasks + request_confirmation for the first task. No new engine: request_checkbox_confirmation (schema, MCP producer tool, server accept storing selectedOptionIds, wake payload checkboxSelection, and the plan-document target rendering in IssueThreadInteractionCard) already exist — this is the prompt wiring that switches onboarding onto the primitive. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…s (PAP-419) Add an optional freeText flag to ask_user_questions options. Selecting a free-text option now reveals an inline text field (submitted as otherText) instead of acting as a dead radio, and suppresses the built-in "Other" link so a question never shows two free-text affordances. Validator allows at most one free-text option per question and the schema description steers agents away from authoring dead "describe it" options. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…one approval surface (PAP-418) Phase C of PAP-412. Every plan/task-approval card now shares one grammar: Approve · Revise… · Reject. "Revise…" reveals an attached note field for the changes you want (the former "decline with a reason" path); bare "Reject" sends work back with no note. Extracted a single ConfirmationActionRow used by both RequestConfirmationCard and RequestCheckboxConfirmationCard, so the two cards can't drift apart again. Producer flags still tune which affordances appear (allowDeclineReason=false drops Revise…; rejectRequiresReason=true drops bare Reject so every rejection carries a note). Collapsed the two plan-approval surfaces into one: removed the sticky Plan-pane IssuePlanConfirmationActionBar so the in-thread plan card — always visible in the conversation — is the single place to approve a plan. The Plans tab now just shows the plan document and its accepted-revision history. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…copy (PAP-417) Auto-switch the task-chat pane to the Plan tab as soon as a plan document exists, so the plan write-up is exposed alongside the plan-approval card instead of leaving the user on Properties. Manual tab selection still wins. Update the onboarding prompt so the plan card points to the full write-up 'in the plan on the right sidebar' rather than 'in the plan doc above'. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nore legacy payload label (PAP-423)
The unified ConfirmationActionRow grammar (Approve · Revise… · Reject) was
leaking a legacy payload label: both RequestConfirmationCard and
RequestCheckboxConfirmationCard passed
`rejectLabel={interaction.payload.rejectLabel ?? CONFIRMATION_REJECT_LABEL}`,
so onboarding/plan-approval interactions seeded with the legacy
`rejectLabel: "Request changes"` rendered a redundant CTA next to "Revise…".
Both call sites now pin the bare-reject button to CONFIRMATION_REJECT_LABEL
("Reject"); the reject word no longer drifts per-payload. "Revise…" already
carries the send-back-with-notes path.
- Fixtures: the four confirmation/checkbox fixtures seeding
`rejectLabel: "Request changes"` now use "Reject" to match production grammar.
- Tests: added a regression test asserting a payload `rejectLabel: "Request
changes"` still renders the bare-reject button as "Reject" (and no card shows
both "Revise…" and "Request changes"); updated the disabled-decline-reason
test to expect the canonical "Reject".
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ists (PAP-425) Gate the right-hand Properties panel *mount* for the first onboarding task only: withhold the panel content while the task has no plan document, then reveal it once a plan lands (IssueProperties auto-switches to the Plan tab). The global panelVisible preference is never touched, so no "hidden" state leaks into other tasks and the reveal is instant. Non-first / manual / watchdog issues are unaffected (originKind !== onboarding_first_task). Adds focused IssueDetail panel-effect tests: first-task + no plan keeps the panel closed; a plan doc reveals it; a non-first task mounts it immediately. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… guard) (PAP-424) Implements the approved plan from PAP-420: never draw a degenerate `ask_user_questions` card in the task chat (e.g. the onboarding `Test / A` placeholder the model produces while obeying the intentional prompt mandate). UI-only — no prompt, greeting, server, schema, or API change; the interaction is still created and stored (audit intact), we simply never render it. - Shared structural predicate `isDegenerateAskUserQuestions(interaction)` in `issue-thread-interactions.ts`: degenerate when there are zero questions, or every question is degenerate — blank/whitespace prompt, or no real choice (fewer than two fixed options AND no first-class free-text option, the PAP-419 `freeText` flag). Catches `Test / A` and empty-prompt; leaves yes/no, multi-select, and free-text cards untouched. - Composition filters so a suppressed card leaves no empty slot or gap: `TaskChatThread` ordered backbone and `buildIssueChatMessages` (the source for both IssueChatThread render sites) skip degenerate interactions. - Unit tests for the predicate (zero-Q / blank / `Test / A` / no-options → true; yes-no / multi-select / free-text / mixed → false; non-ask kinds ignored), a render test (card returns nothing for degenerate, renders a normal one), and a thread-composition test (no empty message slot). The single card entry-point guard — `if (isDegenerateAskUserQuestions(...)) return null;` at the top of `IssueThreadInteractionCard`, covering all three render sites at once — already landed in b4d566b53; this commit adds the shared predicate it depends on plus the composition-site filters and tests, restoring a consistent build. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nt-door) - "Create new company" dropdown skips the front-door choice and lands directly on step 1 (initialStep: 1). - Step 1: "Name your organization" / "What should we call your team or company?". - Step 2: extra space above the mission-path selector; removed the "Change company name" text link. - Step 3: "Create your first agent" + reworded subtitle; removed the "an empty slot for an agent" caption. - Step 4: CTA "Give it a heartbeat" → "Connect". - Step 5: subtitle "Everything's set up. Your first agent is online and ready to work."; more space below subtitle and above the agent name; capsule caption shows the agent name only; "Company name" → "Organization name"; removed the mission quote and the "We'll create the first task…" helper text. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tle (PAP-431) Board follow-up: the final onboarding step subtitle now reads just "Your first agent is online and ready to work." — the leading "Everything's set up." sentence is removed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…new organization..." (PAP-431) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…e (PAP-431) - Add ~30px more space below the subtitle (space-y-6 → space-y-[54px], step 5) - Match agent name text size to the 'Organization name' checklist (text-sm, step 5) - Set 10px between the capsule and the agent name (gap-3 → gap-2.5, step 5) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…p (PAP-431) Board follow-up on the final review screen: the whitespace above the animated capsule should equal the whitespace between the agent name and "Organization name". The prior `space-y-[54px]` was a silent no-op — this project's Tailwind v4 setup does not emit arbitrary `[value]` spacing utilities (verified: the class rendered marginTop:0). Replace it with a standard-scale `mt-8` on the capsule block. Measured in the running app: above-capsule gap ≈35px now matches the name→"Organization name" gap ≈34px (both ≈37px baseline-to-top). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Only honor the onboarding first-task marker when the request comes from a human board/user session. Prevents an agent from using the client-supplied marker to seed a comment attributed to another agent and hide an ordinary issue's description. The onboarding wizard always runs under the user's own session, so legitimate onboarding UX is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…estions resolvable Two review fixes: - Onboarding first-task marker now requires both a human (board) session AND a genuinely empty company (no existing issues) before it stamps the onboarding origin or seeds an agent-authored greeting. Fails closed, so a client marker alone can no longer make a normal issue impersonate an assigned agent. - Degenerate ask_user_questions guard now hides only truly unanswerable cards (zero questions, blank prompt, or no option and no free-text). A single fixed option is answerable, so it renders — a hidden-but-pending card would strand the assignee. Tests updated to use genuinely unanswerable cards. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-437) Agents schema-probe the interactions API with throwaway ask_user_questions they never withdraw, so garbage cards sit pending in the thread forever (PAP-436 root cause; same pattern as PAP-428). Implements the approved PAP-436 plan, all structural — no content heuristics. - Server: when an agent creates a new ask_user_questions on an issue while its own earlier ones are still pending, expire them with new expirationReason "superseded_by_newer_interaction" (reuses the create-time supersede machinery that already covers request_confirmation). Scoped to same agent + same issue + same kind. - UI: hide expired cards carrying that reason via a single shouldHideInteractionCard predicate wired into the card + both thread backbones; superseded_by_comment keeps its stale notice; a pending card is never hidden (PAP-424/00b136f45). - Prompt: new anti-probe bullet in DEFAULT_PAPERCLIP_AGENT_PROMPT_TEMPLATE covering issue-thread interactions; placed to merge cleanly with PAP-429. - Tests: service (probe→real auto-expired; other agent/kind/issue untouched; onboarding first-task path leaves exactly one pending question), UI predicate, and prompt bullet. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…action cards (PAP-440) The indigo policy badge next to the interaction status pill carried no actionable information and had no interaction beyond a tooltip. Drop it and keep the addressee chip. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ask (PAP-441) The first-task panel suppression (PAP-425) withheld the Properties pane mount entirely, which also made the 'Show properties' header button an invisible no-op. Keep the pane hidden by default, but keep the button visible while suppressed; clicking it sets a per-issue override that mounts the pane on demand before a plan exists. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Paperclip <noreply@paperclip.ing>
…le tail keys (PAP-460) PAP-458 wave 1: the two primary causes of streamed messages appearing then vanishing midstream. B1 — chunk-cap trimming. mergeRunLogChunks permanently spliced off the oldest chunks past a 200-chunk cap; delta-streaming runs hit 200 in seconds so just-rendered messages fell off the top irreversibly. Trimming is now byte-budget-based (applyRetentionBudget); task views get a ~2MB budget and, when genuinely exceeded, collapse the oldest output behind a single visible marker instead of silently discarding it. Dashboard tickers and the summary draft keep their compact silent count cap. B2 — streaming tail remounts every delta. The tail block's React key embedded a mutating ts, so the block unmounted/remounted and its 300ms fade-in restarted each chunk (text blinked out and back). Blocks now carry a stable startTs and key off a position-independent identity so the streaming tail stays mounted. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ve tail (PAP-461) Wave 2 of the PAP-458 plan: give the experimental chat-style view's live tail (RunTranscriptView appended by TaskChatThread) the default view's liked streaming look. A1 — status pill parity: new TaskChatLiveRunPill mounts above the live tail with the default view's CoT-header grammar (spinner + shimmering "Working" + elapsed words + "· ran/called N tools"), settling to a static emerald-dot "Worked" summary once terminal. Reuses formatDurationWords + useSecondTick; toolCountSummaryFromEntries mirrors IssueChatThread.toolCountSummary off the streamed transcript entries (deduped by toolUseId). A2 — text-style parity: RunTranscriptView message body now uses `text-sm leading-6` and thinking uses `text-(length:--text-compact) leading-5 text-muted-foreground/70`, matching the default view's chat/CoT text. A3 — streaming motion: raw `animate-in … duration-300` / `animate-ping` classes replaced with token-driven `.tc-stream-block-enter` / `.tc-live-ping` (--motion-tool-enter / --motion-approval-pulse) so the redesign's reduced-motion overrides apply consistently. Verified live on :3125 (flag ON): pill streamed "Working · for 1 minute · called 11 tools" with shimmer, elapsed ticking; 18 unit tests + tsc -b + check-task-chat-motion green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ugh settle (PAP-462) Wave 3 of PAP-458. Two resilience fixes on the live-transcript pipeline; no change to deliberate compaction (the board-confirmed line: collapsing is fine, silent midstream vanishing is the defect). B3 — transcript wiped on transient poll gaps. useLiveRunTranscripts pruned every accumulated chunk for any run momentarily absent from the runs list, so a single empty/errored parent poll wiped the buffer and forced a rehydration that skipped to the last 256KB. Add a 20s grace: an absent run keeps its buffer (and log offset / seen-chunk / trimmed-seq state) until it stays gone past the window, with a deferred prune tick so a genuinely-gone run is still cleaned up. Shared pipeline, so the default view benefits too. B4 — whole transcript unmounts when the run settles. The experimental tail was `liveRun ? <tail/> : null`, so everything vanished the frame liveRun flipped null — seconds before the settled comment renders. Snapshot the just-settled run in a layout effect (pre-paint, no blank frame) and keep its now-static transcript mounted until its settled turn or reply comment lands in the thread (backstop timeout for stopped runs with neither). The pill settles to its "Worked" state during the gap. Tests: both fixes have regression tests proven to fail without the change — grace-retention + after-grace prune for B3, settle-gap mount for B4. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… (PAP-463) The chat-style view's live tail rendered through RunTranscriptView (the verbatim debug viewer) since e4f3d77, so a streaming run showed raw plumbing the settled thread never does: the INIT row, "N LOG LINES" / "N SYSTEM MESSAGES" banners, a "Streaming" chip, uppercase "USED TERMINAL" cards, and raw stdout/JSON dumps. Replace the RunTranscriptView tail body with the clean converter the settled turns already use: transcriptToTaskChatItems(tailEntries, { running }) rendered through a new TaskChatLiveTail — tool cards (with diffs) via TaskChatToolCard plus the streamed reply markdown. The converter already drops init/stdout/stderr/system/user/result, so none of that noise can reach the thread. The TaskChatLiveRunPill header and all rev-2 no-vanishing protections (byte-budget trimming, poll-gap grace, keep-through-settle) are untouched — none depend on which component renders the tail. Live and settle-gap feed the same converter (running: true vs false), so the tail never restyles when a run finishes. RunTranscriptView stays the debug viewer for AgentDetail. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…efault (PAP-468) The chat-style task experience is now the only task detail view. The flag is deleted end to end rather than default-flipped so no install can strand itself on the legacy view with no UI to escape; stale persisted keys are silently dropped by the server's .strip() storage schema, so no migration is needed. - shared: drop the feature-catalog entry, the InstanceExperimentalSettings field, and its zod validator field. - server: drop the field from both branches of normalizeExperimentalSettings. - ui: delete useTaskChatRedesignEnabled and TaskChatRedesignGate; collapse every flag conditional to the redesign path (IssueDetail thread is always TaskChatThread with the thread-owned center column, PropertiesPanel is always the resizable pane, IssueProperties always renders the tab shell); remove the Chat-Style Tasks card from Settings → Experimental; keep the /dev/task-chat-lab route dev-only without the flag gate; sweep stale flag comments. IssueChatThread stays — BoardChat, Pipelines, RunChatSurface and the UX labs still use it. - tests: legacy flag-off cases removed; flag-on cases are now the defaults. Deeper dead-code sweep of legacy-only IssueDetail helpers is a follow-up. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The onboarding wizard copy changed (step-1 heading is now 'Name your organization', the step-4 CTA is 'Connect') and the task detail page now renders the chat-style composer by default, whose work-mode control lives on the 'task-chat-composer-mode' chip instead of the old 'issue-chat-composer' test ids. Update the four e2e specs that still drove the old copy and locators; all five previously-failing tests pass locally against the throwaway e2e instance. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…flake The sandbox process-session bridge writes event files asynchronously; on slow CI shards a final write races the afterEach recursive fs.rm and the events dir rmdir fails with ENOTEMPTY (seen twice on workspaces-b). Enable fs.rm's built-in retry so cleanup waits out the writer. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
scotttong
marked this pull request as ready for review
August 9, 2026 02:22
Contributor
Author
|
@greptileai review |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Thinking Path
Linked Issues or Issue Description
No public GitHub issue exists for this change. Description follows the feature request template.
Problem or motivation
The chat-style task experience is complete, but it is hidden behind the
enableTaskChatRedesignexperimental flag. A user who installs Paperclip gets the legacy task detail view by default. They must discover the experimental features card and turn the flag on to get the intended experience. Maintaining two task detail render paths also slows development and invites drift between them.Proposed solution
Make the chat-style task experience the default for all users. Remove the
enableTaskChatRedesignflag from the shared types, the server instance settings, and the UI. Remove the chat-style tasks card from the experimental features list. Port the streaming presentation work so the live tail is stable in the default path.Alternatives considered
Keep the flag and default it to on. This was rejected because it keeps the dual render path alive and keeps a dead card in the experimental list.
Roadmap alignment
This completes the "make tasks feel like chat" track. It does not duplicate planned core work in
ROADMAP.md.What Changed
enableTaskChatRedesignflag frompackages/shared,server/src/services/instance-settings.ts, and the UI.transcriptToTaskChatItems.Verification
pnpm dev, open any task, and confirm the chat-style detail view renders with no flag set.Risks
Model Used
claude-fable-5(Fable 5), with extended thinking and agentic tool use via the Claude Agent SDK.Checklist
Fixes: #/Closes #/Refs #OR (b) described the issue in-PR following the relevant issue template#NNN/github.com/paperclipai/paperclipURLs)docs/...,fix/...) and contains no internal Paperclip ticket id or instance-derived details