feat(03-02): replace display strings in OnboardingWizard, LiveUpdatesProvider, and assignees lib

- OnboardingWizard.tsx: DEFAULT_TASK_DESCRIPTION uses VOCAB.ceo/company/hire; useState uses VOCAB.ceo; task title updated to Nexus vocabulary; step tab label uses VOCAB.company; placeholder uses VOCAB.ceo; launch summary uses VOCAB.company
- LiveUpdatesProvider.tsx: resolveActorLabel returns VOCAB.board instead of hardcoded 'Board'
- assignees.ts: formatAssigneeUserLabel returns VOCAB.board for local-board user
- assignees.test.ts: updated expectation to 'Owner' (VOCAB.board value)
This commit is contained in:
Mikkel Georgsen 2026-03-30 23:51:59 +02:00 committed by Nexus Dev
parent a260882540
commit 6dddf038eb
4 changed files with 18 additions and 14 deletions

View file

@ -1,4 +1,5 @@
import { useEffect, useState, useRef, useCallback, useMemo } from "react";
import { VOCAB } from "@paperclipai/branding";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import type { AdapterEnvironmentTestResult } from "@paperclipai/shared";
import { useLocation, useNavigate, useParams } from "@/lib/router";
@ -70,9 +71,9 @@ type AdapterType =
| "http"
| "openclaw_gateway";
const DEFAULT_TASK_DESCRIPTION = `You are the CEO. You set the direction for the company.
const DEFAULT_TASK_DESCRIPTION = `You are the ${VOCAB.ceo}. You set the direction for the ${VOCAB.company.toLowerCase()}.
- hire a founding engineer
- ${VOCAB.hire.toLowerCase()} a founding engineer
- write a hiring plan
- break the roadmap into concrete tasks and start delegating work`;
@ -113,7 +114,7 @@ export function OnboardingWizard() {
const [companyGoal, setCompanyGoal] = useState("");
// Step 2
const [agentName, setAgentName] = useState("CEO");
const [agentName, setAgentName] = useState(VOCAB.ceo);
const [adapterType, setAdapterType] = useState<AdapterType>("claude_local");
const [model, setModel] = useState("");
const [command, setCommand] = useState("");
@ -130,7 +131,7 @@ export function OnboardingWizard() {
// Step 3
const [taskTitle, setTaskTitle] = useState(
"Hire your first engineer and create a hiring plan"
"Add your first engineer and create a staffing plan"
);
const [taskDescription, setTaskDescription] = useState(
DEFAULT_TASK_DESCRIPTION
@ -288,7 +289,7 @@ export function OnboardingWizard() {
setError(null);
setCompanyName("");
setCompanyGoal("");
setAgentName("CEO");
setAgentName(VOCAB.ceo);
setAdapterType("claude_local");
setModel("");
setCommand("");
@ -299,7 +300,7 @@ export function OnboardingWizard() {
setAdapterEnvLoading(false);
setForceUnsetAnthropicApiKey(false);
setUnsetAnthropicLoading(false);
setTaskTitle("Hire your first engineer and create a hiring plan");
setTaskTitle("Add your first engineer and create a staffing plan");
setTaskDescription(DEFAULT_TASK_DESCRIPTION);
setCreatedCompanyId(null);
setCreatedCompanyPrefix(null);
@ -650,11 +651,11 @@ export function OnboardingWizard() {
<div className="flex items-center gap-0 mb-8 border-b border-border">
{(
[
{ step: 1 as Step, label: "Company", icon: Building2 },
{ step: 1 as Step, label: VOCAB.company, icon: Building2 },
{ step: 2 as Step, label: "Agent", icon: Bot },
{ step: 3 as Step, label: "Task", icon: ListTodo },
{ step: 4 as Step, label: "Launch", icon: Rocket }
] as const
]
).map(({ step: s, label, icon: Icon }) => (
<button
key={s}
@ -681,7 +682,7 @@ export function OnboardingWizard() {
<Building2 className="h-5 w-5 text-muted-foreground" />
</div>
<div>
<h3 className="font-medium">Name your company</h3>
<h3 className="font-medium">{`Name your ${VOCAB.company.toLowerCase()}`}</h3>
<p className="text-xs text-muted-foreground">
This is the organization your agents will work for.
</p>
@ -746,7 +747,7 @@ export function OnboardingWizard() {
</label>
<input
className="w-full rounded-md border border-border bg-transparent px-3 py-2 text-sm outline-none focus:ring-1 focus:ring-ring placeholder:text-muted-foreground/50"
placeholder="CEO"
placeholder={VOCAB.ceo}
value={agentName}
onChange={(e) => setAgentName(e.target.value)}
autoFocus
@ -1221,7 +1222,7 @@ export function OnboardingWizard() {
<p className="text-sm font-medium truncate">
{companyName}
</p>
<p className="text-xs text-muted-foreground">Company</p>
<p className="text-xs text-muted-foreground">{VOCAB.company}</p>
</div>
<Check className="h-4 w-4 text-green-500 shrink-0" />
</div>

View file

@ -1,4 +1,5 @@
import { useEffect, useRef, type ReactNode } from "react";
import { VOCAB } from "@paperclipai/branding";
import { useQuery, useQueryClient, type QueryClient } from "@tanstack/react-query";
import type { Agent, Issue, LiveEvent } from "@paperclipai/shared";
import type { RunForIssue } from "../api/activity";
@ -66,7 +67,7 @@ function resolveActorLabel(
}
if (actorType === "system") return "System";
if (actorType === "user" && actorId) {
return "Board";
return VOCAB.board;
}
return "Someone";
}

View file

@ -48,7 +48,7 @@ describe("assignee selection helpers", () => {
it("formats current and board user labels consistently", () => {
expect(formatAssigneeUserLabel("user-1", "user-1")).toBe("Me");
expect(formatAssigneeUserLabel("local-board", "someone-else")).toBe("Board");
expect(formatAssigneeUserLabel("local-board", "someone-else")).toBe("Owner");
expect(formatAssigneeUserLabel("user-abcdef", "someone-else")).toBe("user-");
});

View file

@ -1,3 +1,5 @@
import { VOCAB } from "@paperclipai/branding";
export interface AssigneeSelection {
assigneeAgentId: string | null;
assigneeUserId: string | null;
@ -77,6 +79,6 @@ export function formatAssigneeUserLabel(
): string | null {
if (!userId) return null;
if (currentUserId && userId === currentUserId) return "Me";
if (userId === "local-board") return "Board";
if (userId === "local-board") return VOCAB.board;
return userId.slice(0, 5);
}