Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
941bcd1
Add runtime enablement config plumbing
ibetitsmike Feb 12, 2026
9005cdb
Add runtime enablement settings
ibetitsmike Feb 12, 2026
5709e52
Respect runtime enablement in creation UI
ibetitsmike Feb 12, 2026
478bac0
fix: seed runtime enablement in UI
ibetitsmike Feb 12, 2026
a143b1c
feat: adjust workspace creation controls
ibetitsmike Feb 12, 2026
846ed92
Add runtime defaults and per-project overrides
ibetitsmike Feb 12, 2026
3368a26
Rewrite runtime settings UI for project overrides
ibetitsmike Feb 12, 2026
564ef96
Fix runtime override persistence and guard last runtime
ibetitsmike Feb 12, 2026
78b359a
🤖 fix: hide disabled runtimes in creation UI
ibetitsmike Feb 12, 2026
afe6590
Fix runtime override persistence
ibetitsmike Feb 12, 2026
f4aec2a
fix: restore branch selector styling
ibetitsmike Feb 12, 2026
cb9526d
fix creation runtime settings fallbacks
ibetitsmike Feb 12, 2026
f6e93a7
fix: project overrides use independent enablement (not merged with gl…
ibetitsmike Feb 12, 2026
f47a60e
fix: filter fallback runtime by availability to prevent render oscill…
ibetitsmike Feb 12, 2026
4f35edd
fix: filter fallback runtime against policy constraints
ibetitsmike Feb 12, 2026
dff5aa1
fix: non-git fallback respects enablement + track coder/ssh distincti…
ibetitsmike Feb 12, 2026
030f412
test: wrap useCreationWorkspace harness with ProjectProvider
ibetitsmike Feb 12, 2026
302606f
test: add ProjectProvider to useDraftWorkspaceSettings tests
ibetitsmike Feb 12, 2026
44ea508
fix: keep active runtime visible even if settings-disabled (prevent t…
ibetitsmike Feb 12, 2026
8c5ffdd
fix: stabilize enablement ref + unify non-git fallback with general s…
ibetitsmike Feb 12, 2026
bf42039
fix: don't reattach coder config when settings default is plain SSH
ibetitsmike Feb 12, 2026
b365d3a
fix: treat all non-local modes as unavailable in non-git repos
ibetitsmike Feb 12, 2026
7eb724b
fix: restore data-tutorial=trunk-branch anchor on branch selector
ibetitsmike Feb 12, 2026
0794540
fix: check availability map in fallback + fall through cached default…
ibetitsmike Feb 12, 2026
598c5fe
fix: align runtime defaults and enablement
ibetitsmike Feb 13, 2026
a2f7dca
fix: skip unavailable coder fallback
ibetitsmike Feb 13, 2026
d7e7345
fix: refresh runtime overrides after sync
ibetitsmike Feb 13, 2026
5217188
fix: preserve runtime default config
ibetitsmike Feb 13, 2026
25c3d44
fix: honor project runtime overrides
ibetitsmike Feb 13, 2026
ed4877b
fix: prefer worktree in runtime fallback
ibetitsmike Feb 13, 2026
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
304 changes: 232 additions & 72 deletions src/browser/components/ChatInput/CreationControls.tsx

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions src/browser/components/ChatInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
getInputAttachmentsKey,
AGENT_AI_DEFAULTS_KEY,
VIM_ENABLED_KEY,
RUNTIME_ENABLEMENT_KEY,
getProjectScopeId,
getPendingScopeId,
getDraftScopeId,
Expand Down Expand Up @@ -95,6 +96,7 @@ import type { PendingUserMessage } from "@/browser/utils/chatEditing";
import type { AgentSkillDescriptor } from "@/common/types/agentSkill";
import type { AgentAiDefaults } from "@/common/types/agentAiDefaults";
import { coerceThinkingLevel, type ThinkingLevel } from "@/common/types/thinking";
import { DEFAULT_RUNTIME_ENABLEMENT, normalizeRuntimeEnablement } from "@/common/types/runtime";
import { resolveThinkingInput } from "@/common/utils/thinking/policy";
import {
type MuxFrontendMetadata,
Expand Down Expand Up @@ -208,6 +210,14 @@ const ChatInputInner: React.FC<ChatInputProps> = (props) => {
};
})();

// User request: keep creation runtime controls synced with Settings enablement toggles.
const [rawRuntimeEnablement] = usePersistedState(
RUNTIME_ENABLEMENT_KEY,
DEFAULT_RUNTIME_ENABLEMENT,
{ listener: true }
);
const runtimeEnablement = normalizeRuntimeEnablement(rawRuntimeEnablement);

const [input, setInput] = usePersistedState(storageKeys.inputKey, "", { listener: true });

// Keep a stable reference to the latest input value so event handlers don't need to rebind
Expand Down Expand Up @@ -627,6 +637,15 @@ const ChatInputInner: React.FC<ChatInputProps> = (props) => {
const { projects } = useProjectContext();
const pendingSectionId = variant === "creation" ? (props.pendingSectionId ?? null) : null;
const creationProject = variant === "creation" ? projects.get(props.projectPath) : undefined;
const hasCreationRuntimeOverrides =
creationProject?.runtimeOverridesEnabled === true ||
Boolean(creationProject?.runtimeEnablement) ||
creationProject?.defaultRuntime !== undefined;
// Keep workspace creation in sync with Settings → Runtimes project overrides.
const creationRuntimeEnablement =
variant === "creation" && hasCreationRuntimeOverrides
? normalizeRuntimeEnablement(creationProject?.runtimeEnablement)
: runtimeEnablement;
const creationSections = creationProject?.sections ?? [];

const [selectedSectionId, setSelectedSectionId] = useState<string | null>(() => pendingSectionId);
Expand Down Expand Up @@ -769,6 +788,7 @@ const ChatInputInner: React.FC<ChatInputProps> = (props) => {
projectName: props.projectName,
nameState: creationState.nameState,
runtimeAvailabilityState: creationState.runtimeAvailabilityState,
runtimeEnablement: creationRuntimeEnablement,
sections: creationSections,
selectedSectionId,
onSectionChange: handleCreationSectionChange,
Expand Down
13 changes: 11 additions & 2 deletions src/browser/components/ChatInput/useCreationWorkspace.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { APIClient } from "@/browser/contexts/API";
import { ProjectProvider } from "@/browser/contexts/ProjectContext";
import type { DraftWorkspaceSettings } from "@/browser/hooks/useDraftWorkspaceSettings";
import {
getAgentIdKey,
Expand Down Expand Up @@ -161,7 +162,10 @@ type WorkspaceUpdateAgentAISettingsResult = Awaited<
type WorkspaceCreateResult = Awaited<ReturnType<APIClient["workspace"]["create"]>>;
type NameGenerationArgs = Parameters<APIClient["nameGeneration"]["generate"]>[0];
type NameGenerationResult = Awaited<ReturnType<APIClient["nameGeneration"]["generate"]>>;
type MockOrpcProjectsClient = Pick<APIClient["projects"], "listBranches" | "runtimeAvailability">;
type MockOrpcProjectsClient = Pick<
APIClient["projects"],
"list" | "listBranches" | "runtimeAvailability"
>;
type MockOrpcWorkspaceClient = Pick<
APIClient["workspace"],
"sendMessage" | "create" | "updateAgentAISettings"
Expand Down Expand Up @@ -266,6 +270,7 @@ const setupWindow = ({

currentORPCClient = {
projects: {
list: () => Promise.resolve([]),
listBranches: (input: ListBranchesArgs) => listBranchesMock(input),
runtimeAvailability: () =>
Promise.resolve({
Expand Down Expand Up @@ -881,7 +886,11 @@ function renderUseCreationWorkspace(options: HookOptions) {
return null;
}

render(<Harness {...options} />);
render(
<ProjectProvider>
<Harness {...options} />
</ProjectProvider>
);

return () => {
if (!resultRef.current) {
Expand Down
8 changes: 8 additions & 0 deletions src/browser/components/Settings/SettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
Bot,
Keyboard,
Layout,
Container,
BrainCircuit,
ShieldCheck,
Server,
Expand All @@ -28,6 +29,7 @@ import { Button } from "@/browser/components/ui/button";
import { MCPSettingsSection } from "./sections/MCPSettingsSection";
import { SecretsSection } from "./sections/SecretsSection";
import { LayoutsSection } from "./sections/LayoutsSection";
import { RuntimesSection } from "./sections/RuntimesSection";
import { ExperimentsSection } from "./sections/ExperimentsSection";
import { KeybindsSection } from "./sections/KeybindsSection";
import type { SettingsSection } from "./types";
Expand Down Expand Up @@ -75,6 +77,12 @@ const BASE_SECTIONS: SettingsSection[] = [
icon: <Layout className="h-4 w-4" />,
component: LayoutsSection,
},
{
id: "runtimes",
label: "Runtimes",
icon: <Container className="h-4 w-4" />,
component: RuntimesSection,
},
{
id: "experiments",
label: "Experiments",
Expand Down
Loading
Loading