diff --git a/apps/web/src/components/chat/ProviderHealthBanner.tsx b/apps/web/src/components/chat/ProviderHealthBanner.tsx
index 12c7f6054..38a6a5e4a 100644
--- a/apps/web/src/components/chat/ProviderHealthBanner.tsx
+++ b/apps/web/src/components/chat/ProviderHealthBanner.tsx
@@ -2,6 +2,8 @@ import { type ServerProviderStatus } from "@t3tools/contracts";
import { memo } from "react";
import { Alert, AlertDescription, AlertTitle } from "../ui/alert";
import { CircleAlertIcon } from "lucide-react";
+import { PROVIDER_OPTIONS } from "~/session-logic";
+import { ensureSentenceEnds } from "~/lib/utils";
export const ProviderHealthBanner = memo(function ProviderHealthBanner({
status,
@@ -17,6 +19,8 @@ export const ProviderHealthBanner = memo(function ProviderHealthBanner({
? `${status.provider} provider is unavailable.`
: `${status.provider} provider has limited availability.`;
+ const opts = PROVIDER_OPTIONS.find((opt) => opt.value === status.provider);
+
return (
@@ -25,7 +29,20 @@ export const ProviderHealthBanner = memo(function ProviderHealthBanner({
{status.provider === "codex" ? "Codex provider status" : `${status.provider} status`}
- {status.message ?? defaultMessage}
+ {ensureSentenceEnds(status.message ?? defaultMessage)}
+ {opts?.docsUrl ? (
+ <>
+ {" "}
+
+ Installation Guide
+
+ >
+ ) : null}
diff --git a/apps/web/src/lib/utils.ts b/apps/web/src/lib/utils.ts
index 08a5de91e..13c781059 100644
--- a/apps/web/src/lib/utils.ts
+++ b/apps/web/src/lib/utils.ts
@@ -30,3 +30,11 @@ export const newProjectId = (): ProjectId => ProjectId.makeUnsafe(randomUUID());
export const newThreadId = (): ThreadId => ThreadId.makeUnsafe(randomUUID());
export const newMessageId = (): MessageId => MessageId.makeUnsafe(randomUUID());
+
+export const ensureSentenceEnds = (value: string): string => {
+ const trimmed = value.trim();
+ if ([".", "!", "?"].includes(trimmed.at(-1) ?? "")) {
+ return trimmed;
+ }
+ return `${trimmed}.`;
+};
diff --git a/apps/web/src/session-logic.ts b/apps/web/src/session-logic.ts
index e389f10e2..31555cecf 100644
--- a/apps/web/src/session-logic.ts
+++ b/apps/web/src/session-logic.ts
@@ -24,10 +24,26 @@ export const PROVIDER_OPTIONS: Array<{
value: ProviderPickerKind;
label: string;
available: boolean;
+ docsUrl: string | null;
}> = [
- { value: "codex", label: "Codex", available: true },
- { value: "claudeCode", label: "Claude Code", available: false },
- { value: "cursor", label: "Cursor", available: false },
+ {
+ value: "codex",
+ label: "Codex",
+ available: true,
+ docsUrl: "https://developers.openai.com/codex/cli/#cli-setup",
+ },
+ {
+ value: "claudeCode",
+ label: "Claude Code",
+ available: false,
+ docsUrl: "https://code.claude.com/docs/en/quickstart#step-1-install-claude-code",
+ },
+ {
+ value: "cursor",
+ label: "Cursor",
+ available: false,
+ docsUrl: "https://cursor.com/docs/cli/installation#installation",
+ },
];
export interface WorkLogEntry {