Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/desktop/src/backend/DesktopBackendConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ export const make = Effect.gen(function* () {
const backendExposure = yield* serverExposure.backendConfig;
const persistedSettings = yield* settings.get;
const shared = yield* sharedInputs;
yield* wslEnvironment.preWarm(persistedSettings.wslDistro);
return yield* resolveWslStartConfig({
...shared,
port: backendExposure.port,
Expand Down
37 changes: 36 additions & 1 deletion apps/server/src/provider/Layers/ClaudeProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,36 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [
],
}),
},
{
slug: "claude-sonnet-5",
name: "Claude Sonnet 5",
isCustom: false,
capabilities: createModelCapabilities({
optionDescriptors: [
buildSelectOptionDescriptor({
id: "effort",
label: "Reasoning",
options: [
{ value: "low", label: "Low" },
{ value: "medium", label: "Medium" },
{ value: "high", label: "High", isDefault: true },
{ value: "xhigh", label: "Extra High" },
{ value: "max", label: "Max" },
{ value: "ultrathink", label: "Ultrathink" },
],
promptInjectedValues: ["ultrathink"],
}),
buildSelectOptionDescriptor({
id: "contextWindow",
label: "Context Window",
options: [
{ value: "200k", label: "200k", isDefault: true },
{ value: "1m", label: "1M" },
],
}),
],
}),
},
{
slug: "claude-sonnet-4-6",
name: "Claude Sonnet 4.6",
Expand Down Expand Up @@ -322,7 +352,12 @@ export function normalizeClaudeCliEffort(
if (effort === "ultracode") {
return "xhigh";
}
if (effort === "xhigh" && model !== "claude-fable-5" && model !== "claude-opus-4-8") {
if (
effort === "xhigh" &&
model !== "claude-fable-5" &&
model !== "claude-opus-4-8" &&
model !== "claude-sonnet-5"
) {
return "max";
}
if (effort === "max" && model === "claude-sonnet-4-6") {
Expand Down
15 changes: 15 additions & 0 deletions apps/web/src/components/RightPanelTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,19 @@ export function RightPanelTabs(props: RightPanelTabsProps) {
},
[props],
);
const handleTabMouseDown = useCallback((event: ReactMouseEvent) => {
if (event.button !== 1) return;
event.preventDefault();
}, []);
const handleTabAuxClick = useCallback(
(event: ReactMouseEvent, surface: RightPanelSurface) => {
if (event.button !== 1) return;
event.preventDefault();
event.stopPropagation();
props.onCloseSurface(surface);
},
[props],
);

useEffect(() => {
const activeTab = tabListRef.current?.querySelector<HTMLElement>("[data-active-tab='true']");
Expand Down Expand Up @@ -411,6 +424,8 @@ export function RightPanelTabs(props: RightPanelTabsProps) {
<div
key={surface.id}
data-active-tab={active}
onMouseDown={handleTabMouseDown}
onAuxClick={(event) => handleTabAuxClick(event, surface)}
onContextMenu={(event) => void handleTabContextMenu(event, surface)}
className={cn(
"group flex h-7 min-w-25 max-w-44 shrink-0 items-center gap-1.5 rounded-md px-2 text-sm",
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/settings/ProviderModelsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
*/
const CUSTOM_MODEL_PLACEHOLDER_BY_KIND: Partial<Record<ProviderDriverKind, string>> = {
[ProviderDriverKind.make("codex")]: "gpt-6.7-codex-ultra-preview",
[ProviderDriverKind.make("claudeAgent")]: "claude-sonnet-5-0",
[ProviderDriverKind.make("claudeAgent")]: "claude-sonnet-5",
[ProviderDriverKind.make("cursor")]: "claude-sonnet-4-6",
[ProviderDriverKind.make("opencode")]: "openai/gpt-5",
};
Expand Down
49 changes: 49 additions & 0 deletions docs/upstream-sync/16-cadence-pull-v0.0.29-nightly.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# 16 — Cadence pull: v0.0.28 → v0.0.29-nightly.20260630.695

First steady-state pull after the Phase 1–2 migration. Australian English.

## Headline

- **Window:** `2448212367` (v0.0.28, the Phase-2 merge-base) → `upstream/main`
`9d66b104f` (v0.0.29-nightly.20260630.695). **Only 3 upstream commits, 6 files.**
- **Zero conflicts.** `git merge upstream/main` produced a clean recursive merge;
the two files our fork also touched auto-merged on disjoint lines.
- All gates green; live boot smoke test against a DB copy passed. Merge commit
`01521c01d`.

## The 3 upstream commits

| Commit | Change | Overlap with fork? |
| ----------- | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `0615fd7df` | Add middle-click close for right panel tabs (#3161) | `RightPanelTabs.tsx` — our fork added Tasks/Workstream tabs + props at the top of the file; upstream added `onMouseDown`/`onAuxClick` handlers in the function body. Disjoint regions, auto-merged. |
| `51ea084c8` | Warm WSL before preflight in WSL-only backend mode (#3588) | None. `DesktopBackendConfiguration.ts` (+1 line). WSL-only; inert on Linux. |
| `9d66b104f` | Add Claude Sonnet 5 as default Claude model (#3620) | `contracts/src/model.ts` — upstream flipped `CLAUDE_DRIVER_KIND` default `claude-sonnet-4-6 → claude-sonnet-5` and added sonnet-5 aliases; our fork's `PI_DRIVER_KIND`/`PI_DEFAULT_MODEL` additions are on separate lines. Both present in the merged result. Also touches `ClaudeProvider.ts`, `ProviderModelsSection.tsx`, `model.test.ts` (no fork overlap). |

## What I re-applied / verified

Nothing to re-home — no fork capability was displaced. Verified the two
auto-merges semantically: the merged `model.ts` keeps upstream's new
`claude-sonnet-5` Claude default **and** our `[PI_DRIVER_KIND]: PI_DEFAULT_MODEL`
entries; `RightPanelTabs.tsx` keeps upstream's middle-click handlers **and** our
Tasks/Workstream tab surface.

## Gates

- `vp run typecheck`: pass (0/15; two non-blocking `suggestion` advisories in
upstream's own `apps/desktop` code, pre-existing).
- `pnpm build`: exit 0 (all 5 build targets).
- `vp check`: 0 errors, 15 warnings (pre-existing `react/no-unstable-nested-components`
in `apps/mobile`, unrelated to this pull).
- **Live smoke test:** built `apps/server/dist/bin.mjs` launched on a spare port
(13955) against a _copy_ of `~/.t3/cockpit/userdata/state.sqlite`. Booted clean,
`migrations: []` (no new migrations — consistent with zero DB/schema files in the
window), `GET /` → HTTP 200, workstream-liveness + session-reaper started. The
live cockpit on the default port was never touched.

## Why this pull was cheap (cadence confirmation)

This validates the Phase-2 enabling fact in practice: `merge-base` is the real
upstream commit `2448212367`, so `git merge upstream/main` Just Works with a
normal three-way merge — no grafts, no replace-refs. Conflict cost scaled with
_overlap_ (2 fork-touched files of 6), not commit count, exactly as doc 05 §4
predicts. Frequent small pulls keep this trivial.
7 changes: 5 additions & 2 deletions packages/contracts/src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export type PiThinkingLevel = (typeof PI_THINKING_LEVEL_OPTIONS)[number];

export const DEFAULT_MODEL_BY_PROVIDER: Partial<Record<ProviderDriverKind, string>> = {
[CODEX_DRIVER_KIND]: DEFAULT_MODEL,
[CLAUDE_DRIVER_KIND]: "claude-sonnet-4-6",
[CLAUDE_DRIVER_KIND]: "claude-sonnet-5",
[CURSOR_DRIVER_KIND]: "auto",
[GROK_DRIVER_KIND]: "grok-build",
[PI_DRIVER_KIND]: PI_DEFAULT_MODEL,
Expand Down Expand Up @@ -187,7 +187,10 @@ export const MODEL_SLUG_ALIASES_BY_PROVIDER: Partial<
"opus-4.6": "claude-opus-4-6",
"claude-opus-4.6": "claude-opus-4-6",
"claude-opus-4-6-20251117": "claude-opus-4-6",
sonnet: "claude-sonnet-4-6",
sonnet: "claude-sonnet-5",
"sonnet-5": "claude-sonnet-5",
"claude-sonnet-5.0": "claude-sonnet-5",
"claude-sonnet-5-0": "claude-sonnet-5",
"sonnet-4.6": "claude-sonnet-4-6",
"claude-sonnet-4.6": "claude-sonnet-4-6",
"claude-sonnet-4-6-20251117": "claude-sonnet-4-6",
Expand Down
89 changes: 1 addition & 88 deletions packages/shared/src/model.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
import { describe, expect, it } from "vite-plus/test";
import {
DEFAULT_MODEL,
ProviderDriverKind,
ProviderInstanceId,
type ModelCapabilities,
} from "@t3tools/contracts";
import { ProviderInstanceId, type ModelCapabilities } from "@t3tools/contracts";

import {
applyClaudePromptEffortPrefix,
buildProviderOptionSelectionsFromDescriptors,
createModelCapabilities,
createModelSelection,
Expand All @@ -16,11 +10,6 @@ import {
getProviderOptionDescriptors,
getProviderOptionBooleanSelectionValue,
getProviderOptionStringSelectionValue,
isClaudeUltrathinkPrompt,
normalizeModelSlug,
resolveModelSlugForProvider,
resolveSelectableModel,
trimOrNull,
} from "./model.ts";

const codexCaps: ModelCapabilities = createModelCapabilities({
Expand Down Expand Up @@ -70,82 +59,6 @@ const claudeCaps: ModelCapabilities = createModelCapabilities({
],
});

describe("normalizeModelSlug", () => {
it("maps known aliases to canonical slugs", () => {
const claude = ProviderDriverKind.make("claudeAgent");
expect(normalizeModelSlug("gpt-5-codex")).toBe("gpt-5.4");
expect(normalizeModelSlug("5.3")).toBe("gpt-5.3-codex");
expect(normalizeModelSlug("sonnet", claude)).toBe("claude-sonnet-4-6");
});

it("returns null for empty or missing values", () => {
expect(normalizeModelSlug("")).toBeNull();
expect(normalizeModelSlug(" ")).toBeNull();
expect(normalizeModelSlug(null)).toBeNull();
expect(normalizeModelSlug(undefined)).toBeNull();
});
});

describe("resolveModelSlugForProvider", () => {
it("returns defaults when the model is missing", () => {
expect(resolveModelSlugForProvider(ProviderDriverKind.make("codex"), undefined)).toBe(
DEFAULT_MODEL,
);
expect(resolveModelSlugForProvider(ProviderDriverKind.make("ollama"), undefined)).toBe(
DEFAULT_MODEL,
);
expect(resolveModelSlugForProvider(ProviderDriverKind.make("grok"), undefined)).toBe(
"grok-build",
);
});

it("preserves normalized unknown models", () => {
expect(
resolveModelSlugForProvider(ProviderDriverKind.make("codex"), "custom/internal-model"),
).toBe("custom/internal-model");
});
});

describe("resolveSelectableModel", () => {
it("resolves exact slugs, labels, and aliases", () => {
const options = [
{ slug: "gpt-5.3-codex", name: "GPT-5.3 Codex" },
{ slug: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" },
];
expect(resolveSelectableModel(ProviderDriverKind.make("codex"), "gpt-5.3-codex", options)).toBe(
"gpt-5.3-codex",
);
expect(resolveSelectableModel(ProviderDriverKind.make("codex"), "gpt-5.3 codex", options)).toBe(
"gpt-5.3-codex",
);
expect(resolveSelectableModel(ProviderDriverKind.make("claudeAgent"), "sonnet", options)).toBe(
"claude-sonnet-4-6",
);
});
});

describe("misc helpers", () => {
it("detects ultrathink prompts", () => {
expect(isClaudeUltrathinkPrompt("Please ultrathink about this")).toBe(true);
expect(isClaudeUltrathinkPrompt("Ultrathink:\nInvestigate")).toBe(true);
expect(isClaudeUltrathinkPrompt("Investigate")).toBe(false);
});

it("prefixes ultrathink prompts once", () => {
expect(applyClaudePromptEffortPrefix("Investigate", "ultrathink")).toBe(
"Ultrathink:\nInvestigate",
);
expect(applyClaudePromptEffortPrefix("Ultrathink:\nInvestigate", "ultrathink")).toBe(
"Ultrathink:\nInvestigate",
);
});

it("trims strings to null", () => {
expect(trimOrNull(" hi ")).toBe("hi");
expect(trimOrNull(" ")).toBeNull();
});
});

describe("descriptor helpers", () => {
it("applies selection values to capability descriptors", () => {
expect(
Expand Down
Loading