Files
PaperClipAI/ui/src/lib/work-mode-meta.ts
T
scotttongandClaude Fable 5 a7e689b3c3 feat(ui): rename "Agent mode" to "Auto mode" and show full work-mode labels (#11866)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The task composer and the New Task dialog show a work-mode chip (how
the agent will run a task)
> - The default mode was labeled "Agent mode", and the New Task dialog
chip abbreviated every mode to one word ("Auto", "Plan", "Ask")
> - "Agent mode" is confusing because every mode runs an agent, and the
abbreviated chip hid what the label means
> - This pull request renames the mode to "Auto mode" and makes every
mode chip show the full label
> - The benefit is a clearer, consistent mode name in every place the
user selects a work mode

## Linked Issues or Issue Description

No public GitHub issue exists for this change. Description follows the
enhancement template:

**What existing behavior does this improve?**

The work-mode selector chips in the task composer and in the New Task
dialog.

**Subsystem affected**

UI (`ui/src/lib/work-mode-meta.ts`,
`ui/src/components/NewIssueDialog.tsx`).

**Current behavior**

The default work mode is labeled "Agent mode". The New Task dialog chip
shows a shortened label ("Auto", "Plan", "Ask") from a separate
`shortLabel` field.

**Proposed behavior**

The default work mode is labeled "Auto mode". Every chip shows the full
label ("Auto mode", "Plan mode", "Ask mode"). The `shortLabel` field is
removed so no surface can fall back to the short form.

**Reason and benefit**

"Agent mode" does not describe the behavior — all modes use an agent.
"Auto mode" states what the mode does. One label field keeps every
surface consistent.

**Breaking changes**

None. This is a display-string change only. No API, storage, or mode-key
changes.

## What Changed

- Renamed the `standard` work-mode label from "Agent mode" to "Auto
mode" in `ui/src/lib/work-mode-meta.ts`, the single source for all mode
chips.
- Changed the New Task dialog mode chip to render the full `label`
instead of `shortLabel`.
- Deleted the `shortLabel` field from `WorkModeMeta` so nothing can
silently regress to the short form.
- Updated unit tests and fixtures to pin the full labels.

## Verification

- Run `pnpm --filter @paperclipai/ui test --
src/lib/work-mode-meta.test.ts src/components/NewIssueDialog.test.tsx
src/components/IssueChatThread.test.tsx
src/components/task-chat/TaskChatComposer.test.tsx`. All tests pass. The
tests assert the labels are exactly "Auto mode", "Plan mode", and "Ask
mode".
- Manual: start the dev server, open the board, press `c` to open the
New Task dialog, and press Cmd+Period to cycle modes. The chip reads
"Auto mode", "Plan mode", then "Ask mode". The composer chip on an open
task shows the same labels.

## Risks

- Low risk. Display strings only. The chip is a few pixels wider in the
New Task dialog; no layout overflow was observed in any of the three
modes.

## Model Used

- Claude Fable 5 (Anthropic, model ID `claude-fable-5`), extended
thinking with tool use, run inside a Claude Code agent session.

## 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 searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 10:28:55 -07:00

90 lines
3.1 KiB
TypeScript

import type { IssueWorkMode } from "@paperclipai/shared";
import { ClipboardList, Hammer, MessageCircleQuestion, type LucideIcon } from "lucide-react";
export type WorkModeTone = "neutral" | "ask" | "planning";
export interface WorkModeMeta {
value: IssueWorkMode;
label: string;
icon: LucideIcon;
tone: WorkModeTone;
classes: {
chip: string;
container: string;
menuItem: string;
badge: string;
};
}
const STANDARD_CLASSES = {
chip: "border-border bg-muted/40 text-muted-foreground hover:bg-accent hover:text-foreground",
container: "",
menuItem: "text-foreground",
badge: "",
};
const ASK_CLASSES = {
chip: "border-sky-500/60 bg-sky-500/15 text-sky-800 hover:bg-sky-500/25 dark:border-sky-500/50 dark:bg-sky-500/15 dark:text-sky-200 dark:hover:bg-sky-500/25",
container: "border-sky-500/60 bg-sky-50/60 supports-[backdrop-filter]:bg-sky-50/40 dark:border-sky-500/50 dark:bg-sky-500/[0.07] dark:supports-[backdrop-filter]:bg-sky-500/[0.07]",
menuItem: "text-sky-700 dark:text-sky-300",
badge: "border-sky-500/40 bg-sky-50 text-sky-700 dark:border-sky-500/40 dark:bg-sky-500/10 dark:text-sky-200",
};
const PLANNING_CLASSES = {
chip: "border-amber-500/60 bg-amber-500/15 text-amber-800 hover:bg-amber-500/25 dark:border-amber-500/50 dark:bg-amber-500/15 dark:text-amber-200 dark:hover:bg-amber-500/25",
container: "border-amber-500/60 bg-amber-50/60 supports-[backdrop-filter]:bg-amber-50/40 dark:border-amber-500/50 dark:bg-amber-500/[0.07] dark:supports-[backdrop-filter]:bg-amber-500/[0.07]",
menuItem: "text-amber-700 dark:text-amber-300",
badge: "border-amber-500/40 bg-amber-500/10 text-amber-700 dark:text-amber-300",
};
export function isIssueWorkMode(value: unknown): value is IssueWorkMode {
return value === "standard" || value === "ask" || value === "planning";
}
export function workModeMetaList(): WorkModeMeta[] {
return [
{
value: "standard",
label: "Auto mode",
icon: Hammer,
tone: "neutral",
classes: STANDARD_CLASSES,
},
{
value: "planning",
label: "Plan mode",
icon: ClipboardList,
tone: "planning",
classes: PLANNING_CLASSES,
},
{
value: "ask",
label: "Ask mode",
icon: MessageCircleQuestion,
tone: "ask",
classes: ASK_CLASSES,
},
];
}
export function workModeMetaFor(mode: IssueWorkMode): WorkModeMeta {
const modes = workModeMetaList();
return modes.find((meta) => meta.value === mode) ?? modes[0]!;
}
export function nextWorkMode(mode: IssueWorkMode): IssueWorkMode {
const modes = workModeMetaList();
const index = modes.findIndex((meta) => meta.value === mode);
return modes[(index + 1) % modes.length]?.value ?? "standard";
}
export function titleForPendingWorkMode(mode: IssueWorkMode): string {
if (mode === "ask") {
return "Ask mode for this submission. Click to change. The responsible will answer in this thread; no implementation work.";
}
if (mode === "planning") {
return "Plan mode is on for this submission. Click to change.";
}
return "Auto mode for this submission. Click to change.";
}